git-svn-id: https://svn.apache.org/repos/asf/maven/repository-manager/trunk@431135 13f79535-47bb-0310-9956-ffa450edef68tags/archiva-0.9-alpha-1
@@ -26,6 +26,7 @@ import java.util.Properties; | |||
* Test the configuration store. | |||
* | |||
* @author <a href="mailto:brett@apache.org">Brett Porter</a> | |||
* @noinspection JavaDoc | |||
*/ | |||
public class ConfigurationStoreTest | |||
extends PlexusTestCase | |||
@@ -130,6 +131,9 @@ public class ConfigurationStoreTest | |||
assertEquals( "check value", "index-path", configuration.getIndexPath() ); | |||
} | |||
/** | |||
* @noinspection JUnitTestMethodWithNoAssertions | |||
*/ | |||
public void testChangeListeners() | |||
throws Exception | |||
{ |
@@ -42,6 +42,12 @@ | |||
<groupId>org.apache.maven.wagon</groupId> | |||
<artifactId>wagon-provider-api</artifactId> | |||
</dependency> | |||
<dependency> | |||
<groupId>easymock</groupId> | |||
<artifactId>easymock</artifactId> | |||
<version>1.2_Java1.3</version> | |||
<scope>test</scope> | |||
</dependency> | |||
</dependencies> | |||
<build> | |||
<plugins> |
@@ -17,7 +17,6 @@ package org.apache.maven.repository.proxy; | |||
*/ | |||
import org.apache.maven.artifact.Artifact; | |||
import org.apache.maven.artifact.manager.ChecksumFailedException; | |||
import org.apache.maven.artifact.repository.ArtifactRepository; | |||
import org.apache.maven.artifact.repository.ArtifactRepositoryPolicy; | |||
import org.apache.maven.repository.discovery.ArtifactDiscoverer; | |||
@@ -38,8 +37,8 @@ import java.io.File; | |||
import java.io.IOException; | |||
import java.security.NoSuchAlgorithmException; | |||
import java.util.Date; | |||
import java.util.HashMap; | |||
import java.util.Iterator; | |||
import java.util.LinkedHashMap; | |||
import java.util.List; | |||
import java.util.Map; | |||
@@ -49,6 +48,7 @@ import java.util.Map; | |||
* @author <a href="mailto:brett@apache.org">Brett Porter</a> | |||
* @plexus.component | |||
* @todo this currently duplicates a lot of the wagon manager, and doesn't do things like snapshot resolution, etc. | |||
* The checksum handling is inconsistent with that of the wagon manager. | |||
* Should we have a more artifact based one? This will merge metadata so should behave correctly, and it is able to | |||
* correct some limitations of the wagon manager (eg, it can retrieve newer SNAPSHOT files without metadata) | |||
*/ | |||
@@ -100,7 +100,7 @@ public class DefaultProxyRequestHandler | |||
public File getAlways( String path, List proxiedRepositories, ArtifactRepository managedRepository, | |||
ProxyInfo wagonProxy ) | |||
throws ProxyException, ResourceDoesNotExistException | |||
throws ResourceDoesNotExistException, ProxyException | |||
{ | |||
File target = new File( managedRepository.getBasedir(), path ); | |||
@@ -114,68 +114,24 @@ public class DefaultProxyRequestHandler | |||
} | |||
else | |||
{ | |||
if ( path.endsWith( ".md5" ) || path.endsWith( ".sha1" ) ) | |||
{ | |||
// always read from the managed repository, no need to make remote request | |||
} | |||
else if ( path.endsWith( "maven-metadata.xml" ) ) | |||
{ | |||
// TODO: this is not always! | |||
if ( !target.exists() || isOutOfDate( repository.getRepository().getReleases(), target ) ) | |||
{ | |||
getFileFromRepository( path, repository, managedRepository.getBasedir(), wagonProxy, target ); | |||
} | |||
} | |||
else | |||
try | |||
{ | |||
Artifact artifact = null; | |||
try | |||
{ | |||
artifact = defaultArtifactDiscoverer.buildArtifact( path ); | |||
} | |||
catch ( DiscovererException e ) | |||
{ | |||
getLogger().debug( | |||
"Failed to build artifact using default layout with message: " + e.getMessage() ); | |||
} | |||
if ( artifact == null ) | |||
{ | |||
try | |||
{ | |||
artifact = legacyArtifactDiscoverer.buildArtifact( path ); | |||
} | |||
catch ( DiscovererException e ) | |||
{ | |||
getLogger().debug( | |||
"Failed to build artifact using legacy layout with message: " + e.getMessage() ); | |||
} | |||
} | |||
get( path, target, repository, managedRepository, wagonProxy ); | |||
if ( artifact != null ) | |||
if ( !target.exists() ) | |||
{ | |||
getArtifactFromRepository( artifact, repository, managedRepository, wagonProxy, target ); | |||
repository.addFailure( path ); | |||
} | |||
else | |||
{ | |||
// Some other unknown file in the repository, proxy as is | |||
// TODO: this is not always! | |||
if ( !target.exists() ) | |||
{ | |||
getFileFromRepository( path, repository, managedRepository.getBasedir(), wagonProxy, | |||
target ); | |||
} | |||
// in case it previously failed and we've since found it | |||
repository.clearFailure( path ); | |||
} | |||
} | |||
if ( !target.exists() ) | |||
catch ( ProxyException e ) | |||
{ | |||
repository.addFailure( path ); | |||
} | |||
else | |||
{ | |||
// in case it previously failed and we've since found it | |||
repository.clearFailure( path ); | |||
throw e; | |||
} | |||
} | |||
} | |||
@@ -188,9 +144,65 @@ public class DefaultProxyRequestHandler | |||
return target; | |||
} | |||
private void get( String path, File target, ProxiedArtifactRepository repository, | |||
ArtifactRepository managedRepository, ProxyInfo wagonProxy ) | |||
throws ProxyException | |||
{ | |||
if ( path.endsWith( ".md5" ) || path.endsWith( ".sha1" ) ) | |||
{ | |||
// always read from the managed repository, no need to make remote request | |||
} | |||
else if ( path.endsWith( "maven-metadata.xml" ) ) | |||
{ | |||
// TODO: this is not always! | |||
if ( !target.exists() || isOutOfDate( repository.getRepository().getReleases(), target ) ) | |||
{ | |||
getFileFromRepository( path, repository, managedRepository.getBasedir(), wagonProxy, target ); | |||
} | |||
} | |||
else | |||
{ | |||
Artifact artifact = null; | |||
try | |||
{ | |||
artifact = defaultArtifactDiscoverer.buildArtifact( path ); | |||
} | |||
catch ( DiscovererException e ) | |||
{ | |||
getLogger().debug( "Failed to build artifact using default layout with message: " + e.getMessage() ); | |||
} | |||
if ( artifact == null ) | |||
{ | |||
try | |||
{ | |||
artifact = legacyArtifactDiscoverer.buildArtifact( path ); | |||
} | |||
catch ( DiscovererException e ) | |||
{ | |||
getLogger().debug( "Failed to build artifact using legacy layout with message: " + e.getMessage() ); | |||
} | |||
} | |||
if ( artifact != null ) | |||
{ | |||
getArtifactFromRepository( artifact, repository, managedRepository, wagonProxy, target ); | |||
} | |||
else | |||
{ | |||
// Some other unknown file in the repository, proxy as is | |||
// TODO: this is not always! | |||
if ( !target.exists() ) | |||
{ | |||
getFileFromRepository( path, repository, managedRepository.getBasedir(), wagonProxy, target ); | |||
} | |||
} | |||
} | |||
} | |||
private void getFileFromRepository( String path, ProxiedArtifactRepository repository, String repositoryCachePath, | |||
ProxyInfo httpProxy, File target ) | |||
throws ProxyException, ResourceDoesNotExistException | |||
throws ProxyException | |||
{ | |||
boolean connected = false; | |||
Map checksums = null; | |||
@@ -222,7 +234,7 @@ public class DefaultProxyRequestHandler | |||
{ | |||
tries++; | |||
getLogger().info( "Trying " + path + " from " + repository.getName() + "..." ); | |||
getLogger().debug( "Trying " + path + " from " + repository.getName() + "..." ); | |||
if ( !target.exists() ) | |||
{ | |||
@@ -233,21 +245,21 @@ public class DefaultProxyRequestHandler | |||
wagon.getIfNewer( path, temp, target.lastModified() ); | |||
} | |||
success = doChecksumCheck( checksums, path, wagon, repositoryCachePath ); | |||
success = checkChecksum( checksums, path, wagon, repositoryCachePath ); | |||
if ( tries > 1 && !success ) | |||
{ | |||
throw new ProxyException( "Checksum failures occurred while downloading " + path ); | |||
//noinspection ThrowCaughtLocally | |||
throw new TransferFailedException( "Checksum failures occurred while downloading " + path ); | |||
} | |||
} | |||
while ( !success ); | |||
disconnectWagon( wagon ); | |||
if ( temp.exists() ) | |||
{ | |||
moveTempToTarget( temp, target ); | |||
// temp won't exist if we called getIfNewer and it was older, but its still a successful return | |||
if ( temp.exists() ) | |||
{ | |||
moveTempToTarget( temp, target ); | |||
} | |||
} | |||
while ( !success ); | |||
} | |||
//try next repository | |||
} | |||
@@ -261,6 +273,11 @@ public class DefaultProxyRequestHandler | |||
String message = "Skipping repository " + repository.getName() + ": " + e.getMessage(); | |||
processRepositoryFailure( repository, message, e ); | |||
} | |||
catch ( ResourceDoesNotExistException e ) | |||
{ | |||
// hard failure setting doesn't affect "not found". | |||
getLogger().debug( "Artifact not found in repository: " + repository.getName() + ": " + e.getMessage() ); | |||
} | |||
finally | |||
{ | |||
if ( wagon != null && checksums != null ) | |||
@@ -288,7 +305,7 @@ public class DefaultProxyRequestHandler | |||
*/ | |||
private Map prepareChecksumListeners( Wagon wagon ) | |||
{ | |||
Map checksums = new HashMap(); | |||
Map checksums = new LinkedHashMap(); | |||
try | |||
{ | |||
ChecksumObserver checksum = new ChecksumObserver( "SHA-1" ); | |||
@@ -344,7 +361,7 @@ public class DefaultProxyRequestHandler | |||
return connected; | |||
} | |||
private boolean doChecksumCheck( Map checksumMap, String path, Wagon wagon, String repositoryCachePath ) | |||
private boolean checkChecksum( Map checksumMap, String path, Wagon wagon, String repositoryCachePath ) | |||
throws ProxyException | |||
{ | |||
releaseChecksumListeners( wagon, checksumMap ); | |||
@@ -367,45 +384,49 @@ public class DefaultProxyRequestHandler | |||
remoteChecksum = remoteChecksum.substring( 0, remoteChecksum.indexOf( ' ' ) ); | |||
} | |||
boolean checksumCheck = false; | |||
if ( remoteChecksum.toUpperCase().equals( checksum.getActualChecksum().toUpperCase() ) ) | |||
String actualChecksum = checksum.getActualChecksum().toUpperCase(); | |||
remoteChecksum = remoteChecksum.toUpperCase(); | |||
boolean checksumCheck; | |||
if ( remoteChecksum.equals( actualChecksum ) ) | |||
{ | |||
moveTempToTarget( tempChecksumFile, checksumFile ); | |||
checksumCheck = true; | |||
} | |||
else | |||
{ | |||
getLogger().warn( | |||
"The checksum '" + actualChecksum + "' did not match the remote value: " + remoteChecksum ); | |||
checksumCheck = false; | |||
} | |||
return checksumCheck; | |||
} | |||
catch ( ChecksumFailedException e ) | |||
{ | |||
return false; | |||
} | |||
catch ( TransferFailedException e ) | |||
{ | |||
getLogger().debug( "An error occurred during the download of " + checksumPath + ": " + e.getMessage(), | |||
e ); | |||
getLogger().warn( "An error occurred during the download of " + checksumPath + ": " + e.getMessage(), | |||
e ); | |||
// do nothing try the next checksum | |||
} | |||
catch ( ResourceDoesNotExistException e ) | |||
{ | |||
getLogger().debug( "An error occurred during the download of " + checksumPath + ": " + e.getMessage(), | |||
e ); | |||
getLogger().debug( "The checksum did not exist: " + checksumPath, e ); | |||
// do nothing try the next checksum | |||
} | |||
catch ( AuthorizationException e ) | |||
{ | |||
getLogger().debug( "An error occurred during the download of " + checksumPath + ": " + e.getMessage(), | |||
e ); | |||
getLogger().warn( "An error occurred during the download of " + checksumPath + ": " + e.getMessage(), | |||
e ); | |||
// do nothing try the next checksum | |||
} | |||
catch ( IOException e ) | |||
{ | |||
getLogger().debug( "An error occurred while reading the temporary checksum file.", e ); | |||
getLogger().warn( "An error occurred while reading the temporary checksum file.", e ); | |||
return false; | |||
} | |||
} | |||
getLogger().debug( "Skipping checksum validation for " + path + ": No remote checksums available." ); | |||
getLogger().debug( "No remote checksums available." ); | |||
return true; | |||
} | |||
@@ -480,13 +501,14 @@ public class DefaultProxyRequestHandler | |||
} | |||
else | |||
{ | |||
getLogger().error( message, t ); | |||
getLogger().warn( message ); | |||
getLogger().debug( message, t ); | |||
} | |||
} | |||
private void getArtifactFromRepository( Artifact artifact, ProxiedArtifactRepository repository, | |||
ArtifactRepository managedRepository, ProxyInfo httpProxy, File remoteFile ) | |||
throws ProxyException, ResourceDoesNotExistException | |||
throws ProxyException | |||
{ | |||
ArtifactRepository artifactRepository = repository.getRepository(); | |||
ArtifactRepositoryPolicy policy = |
@@ -20,21 +20,24 @@ import org.apache.maven.artifact.repository.ArtifactRepository; | |||
import org.apache.maven.artifact.repository.ArtifactRepositoryFactory; | |||
import org.apache.maven.artifact.repository.layout.ArtifactRepositoryLayout; | |||
import org.apache.maven.wagon.ResourceDoesNotExistException; | |||
import org.apache.maven.wagon.TransferFailedException; | |||
import org.apache.maven.wagon.Wagon; | |||
import org.apache.maven.wagon.authorization.AuthorizationException; | |||
import org.codehaus.plexus.PlexusTestCase; | |||
import org.codehaus.plexus.util.FileUtils; | |||
import org.easymock.MockControl; | |||
import java.io.File; | |||
import java.io.IOException; | |||
import java.net.MalformedURLException; | |||
import java.util.ArrayList; | |||
import java.util.List; | |||
/** | |||
* @author Brett Porter | |||
* @todo! tests to do vvv | |||
* @todo test when >1 repo has the artifact | |||
* @todo test when >1 repo has the artifact but one fails | |||
* @todo test hard failure on repo1 | |||
* @todo test when failure is cached | |||
* @todo test when failure is cached and repo is hard fail | |||
* @todo test when failure should be cached but caching is disabled | |||
* @todo test snapshots - general | |||
* @todo test snapshots - newer version on repo2 is pulled down | |||
@@ -43,10 +46,18 @@ import java.util.List; | |||
* @todo test metadata - general | |||
* @todo test metadata - multiple repos are merged | |||
* @todo test metadata - update interval | |||
* @todo test metadata - looking for an update and file has been removed remotely | |||
* @todo test when managed repo is m1 layout (proxy is m2), including metadata | |||
* @todo test when one proxied repo is m1 layout (managed is m2), including metadata | |||
* @todo test when one proxied repo is m1 layout (managed is m1), including metadata | |||
* @todo test get always | |||
* @todo test get always when resource is present locally but not in any proxied repos (should fail) | |||
* @todo test remote checksum only md5 | |||
* @todo test remote checksum only sha1 | |||
* @todo test remote checksum missing | |||
* @todo test remote checksum present and correct | |||
* @todo test remote checksum present and incorrect | |||
* @todo test remote checksum transfer failed | |||
*/ | |||
public class ProxyRequestHandlerTest | |||
extends PlexusTestCase | |||
@@ -61,6 +72,14 @@ public class ProxyRequestHandlerTest | |||
private ArtifactRepository proxiedRepository2; | |||
private ArtifactRepositoryLayout defaultLayout; | |||
private ArtifactRepositoryFactory factory; | |||
private MockControl wagonMockControl; | |||
private Wagon wagonMock; | |||
protected void setUp() | |||
throws Exception | |||
{ | |||
@@ -72,24 +91,25 @@ public class ProxyRequestHandlerTest | |||
FileUtils.deleteDirectory( repoLocation ); | |||
copyDirectoryStructure( getTestFile( "src/test/repositories/managed" ), repoLocation ); | |||
ArtifactRepositoryFactory factory = (ArtifactRepositoryFactory) lookup( ArtifactRepositoryFactory.ROLE ); | |||
ArtifactRepositoryLayout defaultLayout = | |||
(ArtifactRepositoryLayout) lookup( ArtifactRepositoryLayout.ROLE, "default" ); | |||
defaultManagedRepository = factory.createArtifactRepository( "managed-repository", | |||
repoLocation.toURI().toURL().toExternalForm(), | |||
defaultLayout, null, null ); | |||
defaultLayout = (ArtifactRepositoryLayout) lookup( ArtifactRepositoryLayout.ROLE, "default" ); | |||
factory = (ArtifactRepositoryFactory) lookup( ArtifactRepositoryFactory.ROLE ); | |||
defaultManagedRepository = createRepository( "managed-repository", repoLocation ); | |||
File location = getTestFile( "src/test/repositories/proxied1" ); | |||
proxiedRepository1 = factory.createArtifactRepository( "proxied1", location.toURI().toURL().toExternalForm(), | |||
defaultLayout, null, null ); | |||
proxiedRepository1 = createRepository( "proxied1", location ); | |||
location = getTestFile( "src/test/repositories/proxied2" ); | |||
proxiedRepository2 = factory.createArtifactRepository( "proxied2", location.toURI().toURL().toExternalForm(), | |||
defaultLayout, null, null ); | |||
proxiedRepository2 = createRepository( "proxied2", location ); | |||
proxiedRepositories = new ArrayList( 2 ); | |||
proxiedRepositories.add( createProxiedRepository( proxiedRepository1 ) ); | |||
proxiedRepositories.add( createProxiedRepository( proxiedRepository2 ) ); | |||
wagonMockControl = MockControl.createNiceControl( Wagon.class ); | |||
wagonMock = (Wagon) wagonMockControl.getMock(); | |||
WagonDelegate delegate = (WagonDelegate) lookup( Wagon.ROLE, "test" ); | |||
delegate.setDelegate( wagonMock ); | |||
} | |||
public void testGetDefaultLayoutNotPresent() | |||
@@ -134,12 +154,183 @@ public class ProxyRequestHandlerTest | |||
file.lastModified() ); | |||
} | |||
public void testGetWhenInBothProxiedRepos() | |||
throws ResourceDoesNotExistException, ProxyException, IOException | |||
{ | |||
String path = "org/apache/maven/test/get-in-both-proxies/1.0/get-in-both-proxies-1.0.jar"; | |||
File expectedFile = new File( defaultManagedRepository.getBasedir(), path ); | |||
assertFalse( expectedFile.exists() ); | |||
File file = requestHandler.get( path, proxiedRepositories, defaultManagedRepository ); | |||
assertEquals( "Check file matches", expectedFile, file ); | |||
assertTrue( "Check file created", file.exists() ); | |||
File proxiedFile = new File( proxiedRepository1.getBasedir(), path ); | |||
String expectedContents = FileUtils.fileRead( proxiedFile ); | |||
assertEquals( "Check file contents", expectedContents, FileUtils.fileRead( file ) ); | |||
proxiedFile = new File( proxiedRepository2.getBasedir(), path ); | |||
String unexpectedContents = FileUtils.fileRead( proxiedFile ); | |||
assertFalse( "Check file contents", unexpectedContents.equals( FileUtils.fileRead( file ) ) ); | |||
} | |||
public void testGetInSecondProxiedRepo() | |||
throws ResourceDoesNotExistException, ProxyException, IOException | |||
{ | |||
String path = "org/apache/maven/test/get-in-second-proxy/1.0/get-in-second-proxy-1.0.jar"; | |||
File expectedFile = new File( defaultManagedRepository.getBasedir(), path ); | |||
assertFalse( expectedFile.exists() ); | |||
File file = requestHandler.get( path, proxiedRepositories, defaultManagedRepository ); | |||
assertEquals( "Check file matches", expectedFile, file ); | |||
assertTrue( "Check file created", file.exists() ); | |||
File proxiedFile = new File( proxiedRepository2.getBasedir(), path ); | |||
String expectedContents = FileUtils.fileRead( proxiedFile ); | |||
assertEquals( "Check file contents", expectedContents, FileUtils.fileRead( file ) ); | |||
} | |||
public void testNotFoundInAnyProxies() | |||
throws ResourceDoesNotExistException, ProxyException, IOException | |||
{ | |||
String path = "org/apache/maven/test/does-not-exist/1.0/does-not-exist-1.0.jar"; | |||
File expectedFile = new File( defaultManagedRepository.getBasedir(), path ); | |||
assertFalse( expectedFile.exists() ); | |||
try | |||
{ | |||
File file = requestHandler.get( path, proxiedRepositories, defaultManagedRepository ); | |||
fail( "File returned was: " + file + "; should have got a not found exception" ); | |||
} | |||
catch ( ResourceDoesNotExistException e ) | |||
{ | |||
// expected, but check file was not created | |||
assertFalse( expectedFile.exists() ); | |||
} | |||
} | |||
public void testGetInSecondProxiedRepoFirstFails() | |||
throws ResourceDoesNotExistException, ProxyException, IOException, TransferFailedException, | |||
AuthorizationException | |||
{ | |||
String path = "org/apache/maven/test/get-in-second-proxy/1.0/get-in-second-proxy-1.0.jar"; | |||
File expectedFile = new File( defaultManagedRepository.getBasedir(), path ).getAbsoluteFile(); | |||
assertFalse( expectedFile.exists() ); | |||
proxiedRepository1 = createRepository( "proxied1", "test://..." ); | |||
proxiedRepositories.clear(); | |||
ProxiedArtifactRepository proxiedArtifactRepository = createProxiedRepository( proxiedRepository1 ); | |||
proxiedRepositories.add( proxiedArtifactRepository ); | |||
proxiedRepositories.add( createProxiedRepository( proxiedRepository2 ) ); | |||
wagonMock.get( path, new File( expectedFile.getParentFile(), expectedFile.getName() + ".tmp" ) ); | |||
wagonMockControl.setThrowable( new TransferFailedException( "transfer failed" ) ); | |||
wagonMockControl.replay(); | |||
File file = requestHandler.get( path, proxiedRepositories, defaultManagedRepository ); | |||
wagonMockControl.verify(); | |||
assertEquals( "Check file matches", expectedFile, file ); | |||
assertTrue( "Check file created", file.exists() ); | |||
File proxiedFile = new File( proxiedRepository2.getBasedir(), path ); | |||
String expectedContents = FileUtils.fileRead( proxiedFile ); | |||
assertEquals( "Check file contents", expectedContents, FileUtils.fileRead( file ) ); | |||
assertTrue( "Check failure", proxiedArtifactRepository.isCachedFailure( path ) ); | |||
} | |||
public void testGetButAllRepositoriesFail() | |||
throws ResourceDoesNotExistException, ProxyException, IOException, TransferFailedException, | |||
AuthorizationException | |||
{ | |||
String path = "org/apache/maven/test/get-in-second-proxy/1.0/get-in-second-proxy-1.0.jar"; | |||
File expectedFile = new File( defaultManagedRepository.getBasedir(), path ).getAbsoluteFile(); | |||
assertFalse( expectedFile.exists() ); | |||
proxiedRepository1 = createRepository( "proxied1", "test://..." ); | |||
proxiedRepository2 = createRepository( "proxied2", "test://..." ); | |||
proxiedRepositories.clear(); | |||
ProxiedArtifactRepository proxiedArtifactRepository1 = createProxiedRepository( proxiedRepository1 ); | |||
proxiedRepositories.add( proxiedArtifactRepository1 ); | |||
ProxiedArtifactRepository proxiedArtifactRepository2 = createProxiedRepository( proxiedRepository2 ); | |||
proxiedRepositories.add( proxiedArtifactRepository2 ); | |||
wagonMock.get( path, new File( expectedFile.getParentFile(), expectedFile.getName() + ".tmp" ) ); | |||
wagonMockControl.setThrowable( new TransferFailedException( "transfer failed" ) ); | |||
wagonMock.get( path, new File( expectedFile.getParentFile(), expectedFile.getName() + ".tmp" ) ); | |||
wagonMockControl.setThrowable( new TransferFailedException( "transfer failed" ) ); | |||
wagonMockControl.replay(); | |||
try | |||
{ | |||
File file = requestHandler.get( path, proxiedRepositories, defaultManagedRepository ); | |||
fail( "Found file: " + file + "; but was expecting a failure" ); | |||
} | |||
catch ( ResourceDoesNotExistException e ) | |||
{ | |||
// as expected | |||
wagonMockControl.verify(); | |||
assertTrue( "Check failure", proxiedArtifactRepository1.isCachedFailure( path ) ); | |||
assertTrue( "Check failure", proxiedArtifactRepository2.isCachedFailure( path ) ); | |||
// TODO: do we really want failures to present as a not found? | |||
// TODO: How much information on each failure should we pass back to the user vs. logging in the proxy? | |||
} | |||
} | |||
public void testGetInSecondProxiedRepoFirstHardFails() | |||
throws ResourceDoesNotExistException, ProxyException, IOException, TransferFailedException, | |||
AuthorizationException | |||
{ | |||
String path = "org/apache/maven/test/get-in-second-proxy/1.0/get-in-second-proxy-1.0.jar"; | |||
File expectedFile = new File( defaultManagedRepository.getBasedir(), path ).getAbsoluteFile(); | |||
assertFalse( expectedFile.exists() ); | |||
proxiedRepository1 = createRepository( "proxied1", "test://..." ); | |||
proxiedRepositories.clear(); | |||
ProxiedArtifactRepository proxiedArtifactRepository = createHardFailProxiedRepository( proxiedRepository1 ); | |||
proxiedRepositories.add( proxiedArtifactRepository ); | |||
proxiedRepositories.add( createProxiedRepository( proxiedRepository2 ) ); | |||
wagonMock.get( path, new File( expectedFile.getParentFile(), expectedFile.getName() + ".tmp" ) ); | |||
TransferFailedException failedException = new TransferFailedException( "transfer failed" ); | |||
wagonMockControl.setThrowable( failedException ); | |||
wagonMockControl.replay(); | |||
try | |||
{ | |||
File file = requestHandler.get( path, proxiedRepositories, defaultManagedRepository ); | |||
fail( "Found file: " + file + "; but was expecting a failure" ); | |||
} | |||
catch ( ProxyException e ) | |||
{ | |||
// expect a failure | |||
wagonMockControl.verify(); | |||
assertEquals( "Check cause", failedException, e.getCause() ); | |||
assertTrue( "Check failure", proxiedArtifactRepository.isCachedFailure( path ) ); | |||
} | |||
} | |||
/** | |||
* A faster recursive copy that omits .svn directories. | |||
* | |||
* @param sourceDirectory the source directory to copy | |||
* @param destDirectory the target location | |||
* @throws java.io.IOException if there is a copying problemt | |||
* @throws java.io.IOException if there is a copying problem | |||
* @todo get back into plexus-utils, share with indexing module | |||
*/ | |||
private static void copyDirectoryStructure( File sourceDirectory, File destDirectory ) | |||
throws IOException | |||
@@ -193,6 +384,30 @@ public class ProxyRequestHandlerTest | |||
{ | |||
ProxiedArtifactRepository proxiedArtifactRepository = new ProxiedArtifactRepository( repository ); | |||
proxiedArtifactRepository.setName( repository.getId() ); | |||
proxiedArtifactRepository.setCacheFailures( true ); | |||
return proxiedArtifactRepository; | |||
} | |||
private static ProxiedArtifactRepository createHardFailProxiedRepository( ArtifactRepository repository ) | |||
{ | |||
ProxiedArtifactRepository proxiedArtifactRepository = createProxiedRepository( repository ); | |||
proxiedArtifactRepository.setHardFail( true ); | |||
return proxiedArtifactRepository; | |||
} | |||
private ArtifactRepository createRepository( String id, File repoLocation ) | |||
throws MalformedURLException | |||
{ | |||
return createRepository( id, repoLocation.toURI().toURL().toExternalForm() ); | |||
} | |||
private ArtifactRepository createRepository( String id, String url ) | |||
{ | |||
return createRepository( id, url, defaultLayout ); | |||
} | |||
private ArtifactRepository createRepository( String id, String url, ArtifactRepositoryLayout repositoryLayout ) | |||
{ | |||
return factory.createArtifactRepository( id, url, repositoryLayout, null, null ); | |||
} | |||
} |
@@ -0,0 +1,157 @@ | |||
package org.apache.maven.repository.proxy; | |||
/* | |||
* Copyright 2005-2006 The Apache Software Foundation. | |||
* | |||
* Licensed under the Apache License, Version 2.0 (the "License"); | |||
* you may not use this file except in compliance with the License. | |||
* You may obtain a copy of the License at | |||
* | |||
* http://www.apache.org/licenses/LICENSE-2.0 | |||
* | |||
* Unless required by applicable law or agreed to in writing, software | |||
* distributed under the License is distributed on an "AS IS" BASIS, | |||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |||
* See the License for the specific language governing permissions and | |||
* limitations under the License. | |||
*/ | |||
import org.apache.maven.wagon.Wagon; | |||
import org.apache.maven.wagon.TransferFailedException; | |||
import org.apache.maven.wagon.ResourceDoesNotExistException; | |||
import org.apache.maven.wagon.ConnectionException; | |||
import org.apache.maven.wagon.events.SessionListener; | |||
import org.apache.maven.wagon.events.TransferListener; | |||
import org.apache.maven.wagon.proxy.ProxyInfo; | |||
import org.apache.maven.wagon.authentication.AuthenticationException; | |||
import org.apache.maven.wagon.authentication.AuthenticationInfo; | |||
import org.apache.maven.wagon.repository.Repository; | |||
import org.apache.maven.wagon.authorization.AuthorizationException; | |||
import java.io.File; | |||
/** | |||
* A dummy wagon implementation | |||
* | |||
* @author <a href="mailto:brett@apache.org">Brett Porter</a> | |||
*/ | |||
public class WagonDelegate | |||
implements Wagon | |||
{ | |||
private Wagon delegate; | |||
public void get( String resourceName, File destination ) | |||
throws TransferFailedException, ResourceDoesNotExistException, AuthorizationException | |||
{ | |||
delegate.get( resourceName, destination ); | |||
} | |||
public boolean getIfNewer( String resourceName, File destination, long timestamp ) | |||
throws TransferFailedException, ResourceDoesNotExistException, AuthorizationException | |||
{ | |||
return delegate.getIfNewer( resourceName, destination, timestamp ); | |||
} | |||
public void put( File source, String destination ) | |||
throws TransferFailedException, ResourceDoesNotExistException, AuthorizationException | |||
{ | |||
delegate.put( source, destination ); | |||
} | |||
public void putDirectory( File sourceDirectory, String destinationDirectory ) | |||
throws TransferFailedException, ResourceDoesNotExistException, AuthorizationException | |||
{ | |||
delegate.putDirectory( sourceDirectory, destinationDirectory ); | |||
} | |||
public boolean supportsDirectoryCopy() | |||
{ | |||
return delegate.supportsDirectoryCopy(); | |||
} | |||
public Repository getRepository() | |||
{ | |||
return delegate.getRepository(); | |||
} | |||
public void connect( Repository source ) | |||
throws ConnectionException, AuthenticationException | |||
{ | |||
delegate.connect( source ); | |||
} | |||
public void connect( Repository source, ProxyInfo proxyInfo ) | |||
throws ConnectionException, AuthenticationException | |||
{ | |||
delegate.connect( source, proxyInfo ); | |||
} | |||
public void connect( Repository source, AuthenticationInfo authenticationInfo ) | |||
throws ConnectionException, AuthenticationException | |||
{ | |||
delegate.connect( source, authenticationInfo ); | |||
} | |||
public void connect( Repository source, AuthenticationInfo authenticationInfo, ProxyInfo proxyInfo ) | |||
throws ConnectionException, AuthenticationException | |||
{ | |||
delegate.connect( source, authenticationInfo, proxyInfo ); | |||
} | |||
public void openConnection() | |||
throws ConnectionException, AuthenticationException | |||
{ | |||
delegate.openConnection(); | |||
} | |||
public void disconnect() | |||
throws ConnectionException | |||
{ | |||
delegate.disconnect(); | |||
} | |||
public void addSessionListener( SessionListener listener ) | |||
{ | |||
delegate.addSessionListener( listener ); | |||
} | |||
public void removeSessionListener( SessionListener listener ) | |||
{ | |||
delegate.removeSessionListener( listener ); | |||
} | |||
public boolean hasSessionListener( SessionListener listener ) | |||
{ | |||
return delegate.hasSessionListener( listener ); | |||
} | |||
public void addTransferListener( TransferListener listener ) | |||
{ | |||
delegate.addTransferListener( listener ); | |||
} | |||
public void removeTransferListener( TransferListener listener ) | |||
{ | |||
delegate.removeTransferListener( listener ); | |||
} | |||
public boolean hasTransferListener( TransferListener listener ) | |||
{ | |||
return delegate.hasTransferListener( listener ); | |||
} | |||
public boolean isInteractive() | |||
{ | |||
return delegate.isInteractive(); | |||
} | |||
public void setInteractive( boolean interactive ) | |||
{ | |||
delegate.setInteractive( interactive ); | |||
} | |||
public void setDelegate( Wagon delegate ) | |||
{ | |||
this.delegate = delegate; | |||
} | |||
} |
@@ -0,0 +1,3 @@ | |||
get-in-both-proxies-1.0.jar | |||
(proxied 1) | |||
@@ -0,0 +1,3 @@ | |||
get-in-both-proxies-1.0.jar | |||
(proxied 2) | |||
@@ -0,0 +1,2 @@ | |||
get-in-second-proxy-1.0.jar | |||
@@ -0,0 +1,25 @@ | |||
<!-- | |||
~ Copyright 2005-2006 The Apache Software Foundation. | |||
~ | |||
~ Licensed under the Apache License, Version 2.0 (the "License"); | |||
~ you may not use this file except in compliance with the License. | |||
~ You may obtain a copy of the License at | |||
~ | |||
~ http://www.apache.org/licenses/LICENSE-2.0 | |||
~ | |||
~ Unless required by applicable law or agreed to in writing, software | |||
~ distributed under the License is distributed on an "AS IS" BASIS, | |||
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |||
~ See the License for the specific language governing permissions and | |||
~ limitations under the License. | |||
--> | |||
<component-set> | |||
<components> | |||
<component> | |||
<role>org.apache.maven.wagon.Wagon</role> | |||
<role-hint>test</role-hint> | |||
<implementation>org.apache.maven.repository.proxy.WagonDelegate</implementation> | |||
</component> | |||
</components> | |||
</component-set> |