View Javadoc
1   package org.apache.archiva.proxy;
2   
3   /*
4    * Licensed to the Apache Software Foundation (ASF) under one
5    * or more contributor license agreements.  See the NOTICE file
6    * distributed with this work for additional information
7    * regarding copyright ownership.  The ASF licenses this file
8    * to you under the Apache License, Version 2.0 (the
9    * "License"); you may not use this file except in compliance
10   * with the License.  You may obtain a copy of the License at
11   *
12   *  http://www.apache.org/licenses/LICENSE-2.0
13   *
14   * Unless required by applicable law or agreed to in writing,
15   * software distributed under the License is distributed on an
16   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
17   * KIND, either express or implied.  See the License for the
18   * specific language governing permissions and limitations
19   * under the License.
20   */
21  
22  import org.apache.archiva.admin.model.beans.ManagedRepository;
23  import org.apache.archiva.admin.model.managed.ManagedRepositoryAdmin;
24  import org.apache.archiva.admin.repository.managed.DefaultManagedRepositoryAdmin;
25  import org.apache.archiva.proxy.model.RepositoryProxyConnectors;
26  import org.apache.commons.io.FileUtils;
27  import org.apache.archiva.configuration.ArchivaConfiguration;
28  import org.apache.archiva.configuration.NetworkProxyConfiguration;
29  import org.apache.archiva.configuration.ProxyConnectorConfiguration;
30  import org.apache.archiva.configuration.RemoteRepositoryConfiguration;
31  import org.apache.archiva.model.ArtifactReference;
32  import org.apache.archiva.policies.CachedFailuresPolicy;
33  import org.apache.archiva.policies.ChecksumPolicy;
34  import org.apache.archiva.policies.PropagateErrorsDownloadPolicy;
35  import org.apache.archiva.policies.PropagateErrorsOnUpdateDownloadPolicy;
36  import org.apache.archiva.policies.ReleasesPolicy;
37  import org.apache.archiva.policies.SnapshotsPolicy;
38  import org.apache.archiva.repository.ManagedRepositoryContent;
39  import org.assertj.core.api.Assertions;
40  import org.eclipse.jetty.server.Handler;
41  import org.eclipse.jetty.server.Request;
42  import org.eclipse.jetty.server.Server;
43  import org.eclipse.jetty.server.handler.AbstractHandler;
44  import org.junit.After;
45  import org.junit.Before;
46  import org.junit.Test;
47  import org.junit.runner.RunWith;
48  import org.springframework.context.ApplicationContext;
49  import org.springframework.test.context.ContextConfiguration;
50  
51  import javax.inject.Inject;
52  import javax.servlet.ServletException;
53  import javax.servlet.http.HttpServletRequest;
54  import javax.servlet.http.HttpServletResponse;
55  import java.io.File;
56  import java.io.IOException;
57  import java.nio.charset.Charset;
58  
59  import org.apache.archiva.test.utils.ArchivaSpringJUnit4ClassRunner;
60  
61  import static org.junit.Assert.*;
62  
63  /**
64   * Integration test for connecting over a HTTP proxy.
65   *
66   *
67   */
68  @RunWith( ArchivaSpringJUnit4ClassRunner.class )
69  @ContextConfiguration( locations = { "classpath*:/META-INF/spring-context.xml", "classpath:/spring-context.xml" } )
70  public class HttpProxyTransferTest
71  {
72      private static final String PROXY_ID = "proxy";
73  
74      private static final String MANAGED_ID = "default-managed-repository";
75  
76      private static final String PROXIED_ID = "proxied1";
77  
78      private static final String PROXIED_BASEDIR = "src/test/repositories/proxied1";
79  
80      private RepositoryProxyConnectors proxyHandler;
81  
82      private ArchivaConfiguration config;
83  
84      private ManagedRepositoryContent managedDefaultRepository;
85  
86      @Inject
87      private ApplicationContext applicationContext;
88  
89      private Server server;
90  
91      @Before
92      public void setUp()
93          throws Exception
94      {
95          proxyHandler = applicationContext.getBean( "repositoryProxyConnectors#test", RepositoryProxyConnectors.class );
96  
97          config = applicationContext.getBean( "archivaConfiguration#mock", ArchivaConfiguration.class );
98  
99          // clear from previous tests - TODO the spring context should be initialised per test instead, or the config
100         // made a complete mock
101         config.getConfiguration().getProxyConnectors().clear();
102 
103         // Setup source repository (using default layout)
104         String repoPath = "target/test-repository/managed/" + getClass().getSimpleName();
105 
106         File destRepoDir = new File( repoPath );
107 
108         // Cleanout destination dirs.
109         if ( destRepoDir.exists() )
110         {
111             FileUtils.deleteDirectory( destRepoDir );
112         }
113 
114         // Make the destination dir.
115         destRepoDir.mkdirs();
116 
117         ManagedRepository repo = new ManagedRepository();
118         repo.setId( MANAGED_ID );
119         repo.setName( "Default Managed Repository" );
120         repo.setLocation( repoPath );
121         repo.setLayout( "default" );
122 
123         ManagedRepositoryContent repoContent =
124             applicationContext.getBean( "managedRepositoryContent#default", ManagedRepositoryContent.class );
125 
126         repoContent.setRepository( repo );
127         managedDefaultRepository = repoContent;
128 
129         ( (DefaultManagedRepositoryAdmin) applicationContext.getBean(
130             ManagedRepositoryAdmin.class ) ).setArchivaConfiguration( config );
131 
132         ManagedRepositoryAdmin managedRepositoryAdmin = applicationContext.getBean( ManagedRepositoryAdmin.class );
133         if ( managedRepositoryAdmin.getManagedRepository( repo.getId() ) == null )
134         {
135             managedRepositoryAdmin.addManagedRepository( repo, false, null );
136         }
137 
138         //config.getConfiguration().addManagedRepository( repo );
139 
140         Handler handler = new AbstractHandler()
141         {
142             @Override
143             public void handle( String s, Request request, HttpServletRequest httpServletRequest,
144                                 HttpServletResponse response )
145                 throws IOException, ServletException
146             {
147                 response.setContentType( "text/plain" );
148                 response.setStatus( HttpServletResponse.SC_OK );
149                 response.getWriter().print( "get-default-layout-1.0.jar\n\n" );
150                 assertNotNull( request.getHeader( "Proxy-Connection" ) );
151 
152                 ( (Request) request ).setHandled( true );
153             }
154 
155             public void handle( String target, HttpServletRequest request, HttpServletResponse response, int dispatch )
156                 throws IOException, ServletException
157             {
158                 response.setContentType( "text/plain" );
159                 response.setStatus( HttpServletResponse.SC_OK );
160                 response.getWriter().print( "get-default-layout-1.0.jar\n\n" );
161                 assertNotNull( request.getHeader( "Proxy-Connection" ) );
162 
163                 ( (Request) request ).setHandled( true );
164             }
165         };
166 
167         server = new Server( 0 );
168         server.setHandler( handler );
169         server.start();
170 
171         int port = server.getConnectors()[0].getLocalPort();
172 
173         NetworkProxyConfiguration proxyConfig = new NetworkProxyConfiguration();
174         proxyConfig.setHost( "localhost" );
175         proxyConfig.setPort( port );
176         proxyConfig.setProtocol( "http" );
177         proxyConfig.setId( PROXY_ID );
178         config.getConfiguration().addNetworkProxy( proxyConfig );
179 
180         // Setup target (proxied to) repository.
181         RemoteRepositoryConfiguration repoConfig = new RemoteRepositoryConfiguration();
182 
183         repoConfig.setId( PROXIED_ID );
184         repoConfig.setName( "Proxied Repository 1" );
185         repoConfig.setLayout( "default" );
186         repoConfig.setUrl( "http://www.example.com/" );
187 
188         config.getConfiguration().addRemoteRepository( repoConfig );
189 
190     }
191 
192     @After
193     public void tearDown()
194         throws Exception
195     {
196         server.stop();
197     }
198 
199     @Test
200     public void testGetOverHttpProxy()
201         throws Exception
202     {
203         Assertions.assertThat( System.getProperty( "http.proxyHost" ) ).isEmpty();
204         Assertions.assertThat( System.getProperty( "http.proxyPort" ) ).isEmpty();
205 
206         String path = "org/apache/maven/test/get-default-layout/1.0/get-default-layout-1.0.jar";
207 
208         // Configure Connector (usually done within archiva.xml configuration)
209         addConnector();
210 
211         File expectedFile = new File( new File( managedDefaultRepository.getRepoRoot() ), path );
212         ArtifactReference artifact = managedDefaultRepository.toArtifactReference( path );
213 
214         // Attempt the proxy fetch.
215         File downloadedFile = proxyHandler.fetchFromProxies( managedDefaultRepository, artifact );
216 
217         File sourceFile = new File( PROXIED_BASEDIR, path );
218         assertNotNull( "Expected File should not be null.", expectedFile );
219         assertNotNull( "Actual File should not be null.", downloadedFile );
220 
221         assertTrue( "Check actual file exists.", downloadedFile.exists() );
222         assertEquals( "Check filename path is appropriate.", expectedFile.getCanonicalPath(),
223                       downloadedFile.getCanonicalPath() );
224         assertEquals( "Check file path matches.", expectedFile.getAbsolutePath(), downloadedFile.getAbsolutePath() );
225 
226         String expectedContents = FileUtils.readFileToString( sourceFile, Charset.defaultCharset() );
227         String actualContents = FileUtils.readFileToString( downloadedFile, Charset.defaultCharset() );
228         assertEquals( "Check file contents.", expectedContents, actualContents );
229 
230         Assertions.assertThat( System.getProperty( "http.proxyHost" ) ).isEmpty();
231         Assertions.assertThat( System.getProperty( "http.proxyPort" ) ).isEmpty();
232     }
233 
234     private void addConnector()
235     {
236         ProxyConnectorConfiguration connectorConfig = new ProxyConnectorConfiguration();
237         connectorConfig.setProxyId( PROXY_ID );
238         connectorConfig.setSourceRepoId( MANAGED_ID );
239         connectorConfig.setTargetRepoId( PROXIED_ID );
240         connectorConfig.addPolicy( ProxyConnectorConfiguration.POLICY_CHECKSUM, ChecksumPolicy.FIX );
241         connectorConfig.addPolicy( ProxyConnectorConfiguration.POLICY_RELEASES, ReleasesPolicy.ONCE );
242         connectorConfig.addPolicy( ProxyConnectorConfiguration.POLICY_SNAPSHOTS, SnapshotsPolicy.ONCE );
243         connectorConfig.addPolicy( ProxyConnectorConfiguration.POLICY_CACHE_FAILURES, CachedFailuresPolicy.NO );
244         connectorConfig.addPolicy( ProxyConnectorConfiguration.POLICY_PROPAGATE_ERRORS,
245                                    PropagateErrorsDownloadPolicy.QUEUE );
246         connectorConfig.addPolicy( ProxyConnectorConfiguration.POLICY_PROPAGATE_ERRORS_ON_UPDATE,
247                                    PropagateErrorsOnUpdateDownloadPolicy.NOT_PRESENT );
248 
249         int count = config.getConfiguration().getProxyConnectors().size();
250         config.getConfiguration().addProxyConnector( connectorConfig );
251 
252         // Proper Triggering ...
253         String prefix = "proxyConnectors.proxyConnector(" + count + ")";
254         ( (MockConfiguration) config ).triggerChange( prefix + ".sourceRepoId", connectorConfig.getSourceRepoId() );
255     }
256 }