1 package org.apache.archiva.proxy;
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
12 * http://www.apache.org/licenses/LICENSE-2.0
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
22 import org.apache.archiva.configuration.ArchivaConfiguration;
23 import org.apache.archiva.configuration.NetworkProxyConfiguration;
24 import org.apache.archiva.configuration.ProxyConnectorConfiguration;
25 import org.apache.archiva.configuration.RemoteRepositoryConfiguration;
26 import org.apache.archiva.model.ArtifactReference;
27 import org.apache.archiva.policies.CachedFailuresPolicy;
28 import org.apache.archiva.policies.ChecksumPolicy;
29 import org.apache.archiva.policies.PropagateErrorsDownloadPolicy;
30 import org.apache.archiva.policies.PropagateErrorsOnUpdateDownloadPolicy;
31 import org.apache.archiva.policies.ReleasesPolicy;
32 import org.apache.archiva.policies.SnapshotsPolicy;
33 import org.apache.archiva.proxy.model.RepositoryProxyHandler;
34 import org.apache.archiva.repository.*;
35 import org.apache.archiva.test.utils.ArchivaSpringJUnit4ClassRunner;
36 import org.apache.commons.io.FileUtils;
37 import org.assertj.core.api.Assertions;
38 import org.eclipse.jetty.server.Handler;
39 import org.eclipse.jetty.server.HttpConnectionFactory;
40 import org.eclipse.jetty.server.Request;
41 import org.eclipse.jetty.server.Server;
42 import org.eclipse.jetty.server.ServerConnector;
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;
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.IOException;
56 import java.nio.charset.Charset;
57 import java.nio.file.Files;
58 import java.nio.file.Path;
59 import java.nio.file.Paths;
61 import static org.junit.Assert.*;
64 * Integration test for connecting over a HTTP proxy.
68 @RunWith( ArchivaSpringJUnit4ClassRunner.class )
69 @ContextConfiguration( locations = { "classpath*:/META-INF/spring-context.xml", "classpath:/spring-context.xml" } )
70 public class HttpProxyTransferTest
72 private static final String PROXY_ID = "proxy";
74 private static final String MANAGED_ID = "default-managed-repository";
76 private static final String PROXIED_ID = "proxied1";
78 private static final String PROXIED_BASEDIR = "src/test/repositories/proxied1";
80 private RepositoryProxyHandler proxyHandler;
82 private ArchivaConfiguration config;
84 private ManagedRepositoryContent managedDefaultRepository;
87 private ApplicationContext applicationContext;
90 private RepositoryRegistry repositoryRegistry;
92 private Server server;
94 protected ManagedRepositoryContent createRepository( String id, String name, String path, String layout )
97 ManagedRepository repo = BasicManagedRepository.newFilesystemInstance(id, name, Paths.get(path));
98 repositoryRegistry.putRepository(repo);
99 return repositoryRegistry.getManagedRepository(id).getContent();
106 proxyHandler = applicationContext.getBean( "repositoryProxyConnectors#test", RepositoryProxyHandler.class );
108 config = applicationContext.getBean( "archivaConfiguration#mock", ArchivaConfiguration.class );
110 // clear from previous tests - TODO the spring context should be initialised per test instead, or the config
111 // made a complete mock
112 config.getConfiguration().getProxyConnectors().clear();
114 // Setup source repository (using default layout)
115 String repoPath = "target/test-repository/managed/" + getClass().getSimpleName();
117 Path destRepoDir = Paths.get( repoPath );
119 // Cleanout destination dirs.
120 if ( Files.exists(destRepoDir))
122 FileUtils.deleteDirectory( destRepoDir.toFile() );
125 // Make the destination dir.
126 Files.createDirectories(destRepoDir);
129 Handler handler = new AbstractHandler()
132 public void handle( String s, Request request, HttpServletRequest httpServletRequest,
133 HttpServletResponse response )
134 throws IOException, ServletException
136 response.setContentType( "text/plain" );
137 response.setStatus( HttpServletResponse.SC_OK );
138 response.getWriter().print( "get-default-layout-1.0.jar\n\n" );
139 assertNotNull( request.getHeader( "Proxy-Connection" ) );
141 ( (Request) request ).setHandled( true );
144 public void handle( String target, HttpServletRequest request, HttpServletResponse response, int dispatch )
145 throws IOException, ServletException
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" ) );
152 ( (Request) request ).setHandled( true );
156 server = new Server( );
157 ServerConnector serverConnector = new ServerConnector( server, new HttpConnectionFactory());
158 server.addConnector( serverConnector );
159 server.setHandler( handler );
162 int port = serverConnector.getLocalPort();
164 NetworkProxyConfiguration proxyConfig = new NetworkProxyConfiguration();
165 proxyConfig.setHost( "localhost" );
166 proxyConfig.setPort( port );
167 proxyConfig.setProtocol( "http" );
168 proxyConfig.setId( PROXY_ID );
169 config.getConfiguration().addNetworkProxy( proxyConfig );
170 ( (MockConfiguration) config ).triggerChange("networkProxies.networkProxy(0).host", "localhost");
172 // Setup target (proxied to) repository.
173 RemoteRepositoryConfiguration repoConfig = new RemoteRepositoryConfiguration();
175 repoConfig.setId( PROXIED_ID );
176 repoConfig.setName( "Proxied Repository 1" );
177 repoConfig.setLayout( "default" );
178 repoConfig.setUrl( "http://www.example.com/" );
180 config.getConfiguration().addRemoteRepository( repoConfig );
182 repositoryRegistry.reload();
184 managedDefaultRepository = createRepository(MANAGED_ID, "Default Managed Repository", repoPath, "default");
189 public void tearDown()
196 public void testGetOverHttpProxy()
199 Assertions.assertThat( System.getProperty( "http.proxyHost", "" ) ).isEmpty();
200 Assertions.assertThat( System.getProperty( "http.proxyPort", "" ) ).isEmpty();
202 String path = "org/apache/maven/test/get-default-layout/1.0/get-default-layout-1.0.jar";
204 // Configure Connector (usually done within archiva.xml configuration)
207 Path expectedFile = Paths.get( managedDefaultRepository.getRepoRoot() ).resolve( path );
208 ArtifactReference artifact = managedDefaultRepository.toArtifactReference( path );
210 // Attempt the proxy fetch.
211 Path downloadedFile = proxyHandler.fetchFromProxies( managedDefaultRepository, artifact );
213 Path sourceFile = Paths.get( PROXIED_BASEDIR, path );
214 assertNotNull( "Expected File should not be null.", expectedFile );
215 assertNotNull( "Actual File should not be null.", downloadedFile );
217 assertTrue( "Check actual file exists.", Files.exists(downloadedFile));
218 assertTrue( "Check filename path is appropriate.", Files.isSameFile( expectedFile, downloadedFile));
219 assertTrue( "Check file path matches.", Files.isSameFile( expectedFile, downloadedFile));
221 String expectedContents = FileUtils.readFileToString( sourceFile.toFile(), Charset.defaultCharset() );
222 String actualContents = FileUtils.readFileToString( downloadedFile.toFile(), Charset.defaultCharset() );
223 assertEquals( "Check file contents.", expectedContents, actualContents );
225 Assertions.assertThat( System.getProperty( "http.proxyHost" , "") ).isEmpty();
226 Assertions.assertThat( System.getProperty( "http.proxyPort" , "") ).isEmpty();
229 private void addConnector()
231 ProxyConnectorConfiguration connectorConfig = new ProxyConnectorConfiguration();
232 connectorConfig.setProxyId( PROXY_ID );
233 connectorConfig.setSourceRepoId( MANAGED_ID );
234 connectorConfig.setTargetRepoId( PROXIED_ID );
235 connectorConfig.addPolicy( ProxyConnectorConfiguration.POLICY_CHECKSUM, ChecksumPolicy.FIX );
236 connectorConfig.addPolicy( ProxyConnectorConfiguration.POLICY_RELEASES, ReleasesPolicy.ONCE );
237 connectorConfig.addPolicy( ProxyConnectorConfiguration.POLICY_SNAPSHOTS, SnapshotsPolicy.ONCE );
238 connectorConfig.addPolicy( ProxyConnectorConfiguration.POLICY_CACHE_FAILURES, CachedFailuresPolicy.NO );
239 connectorConfig.addPolicy( ProxyConnectorConfiguration.POLICY_PROPAGATE_ERRORS,
240 PropagateErrorsDownloadPolicy.QUEUE );
241 connectorConfig.addPolicy( ProxyConnectorConfiguration.POLICY_PROPAGATE_ERRORS_ON_UPDATE,
242 PropagateErrorsOnUpdateDownloadPolicy.NOT_PRESENT );
244 int count = config.getConfiguration().getProxyConnectors().size();
245 config.getConfiguration().addProxyConnector( connectorConfig );
247 // Proper Triggering ...
248 String prefix = "proxyConnectors.proxyConnector(" + count + ")";
249 ( (MockConfiguration) config ).triggerChange( prefix + ".sourceRepoId", connectorConfig.getSourceRepoId() );