public File get( String path, List proxiedRepositories, ArtifactRepository managedRepository, ProxyInfo wagonProxy )
throws ProxyException, ResourceDoesNotExistException
{
+ // TODO! this will prove wrong for metadata and snapshots, let tests bring it out
//@todo use wagonManager for cache use file:// as URL
File cachedFile = new File( managedRepository.getBasedir(), path );
if ( !cachedFile.exists() )
ProxyInfo wagonProxy )
throws ProxyException, ResourceDoesNotExistException
{
- File remoteFile = null;
+ File target = new File( managedRepository.getBasedir(), path );
for ( Iterator i = proxiedRepositories.iterator(); i.hasNext(); )
{
{
if ( path.endsWith( ".md5" ) || path.endsWith( ".sha1" ) )
{
- // always read from the managed repository
- remoteFile = new File( managedRepository.getBasedir(), path );
+ // always read from the managed repository, no need to make remote request
}
else if ( path.endsWith( "maven-metadata.xml" ) )
{
- remoteFile = getFromRepository( path, repository, managedRepository.getBasedir(), wagonProxy,
- repository.getRepository().getReleases() );
+ // TODO: this is not always!
+ if ( !target.exists() || isOutOfDate( repository.getRepository().getReleases(), target ) )
+ {
+ getFileFromRepository( path, repository, managedRepository.getBasedir(), wagonProxy, target );
+ }
}
else
{
if ( artifact != null )
{
- getArtifact( artifact, repository, managedRepository, wagonProxy );
-
- remoteFile = artifact.getFile();
+ getArtifactFromRepository( artifact, repository, managedRepository, wagonProxy, target );
}
else
{
// Some other unknown file in the repository, proxy as is
- getFromRepository( path, repository, managedRepository.getBasedir(), wagonProxy, null );
+ // TODO: this is not always!
+ if ( !target.exists() )
+ {
+ getFileFromRepository( path, repository, managedRepository.getBasedir(), wagonProxy,
+ target );
+ }
}
}
- if ( remoteFile != null && !remoteFile.exists() )
+ if ( !target.exists() )
{
repository.addFailure( path );
- throw new ResourceDoesNotExistException(
- "Could not find " + path + " in any of the repositories." );
}
else
{
}
}
- return remoteFile;
+ if ( !target.exists() )
+ {
+ throw new ResourceDoesNotExistException( "Could not find " + path + " in any of the repositories." );
+ }
+
+ return target;
}
- private File getFromRepository( String path, ProxiedArtifactRepository repository, String repositoryCachePath,
- ProxyInfo httpProxy, ArtifactRepositoryPolicy policy )
+ private void getFileFromRepository( String path, ProxiedArtifactRepository repository, String repositoryCachePath,
+ ProxyInfo httpProxy, File target )
throws ProxyException, ResourceDoesNotExistException
{
- File target = new File( repositoryCachePath, path );
- if ( !target.exists() || isOutOfDate( policy, target ) )
- {
- boolean connected = false;
- Map checksums = null;
- Wagon wagon = null;
+ boolean connected = false;
+ Map checksums = null;
+ Wagon wagon = null;
- try
+ try
+ {
+ String protocol = repository.getRepository().getProtocol();
+ wagon = (Wagon) wagons.get( protocol );
+ if ( wagon == null )
{
- String protocol = repository.getRepository().getProtocol();
- wagon = (Wagon) wagons.get( protocol );
- if ( wagon == null )
- {
- throw new ProxyException( "Unsupported remote protocol: " + protocol );
- }
-
- //@todo configure wagon (ssh settings, etc)
-
- checksums = prepareChecksumListeners( wagon );
+ throw new ProxyException( "Unsupported remote protocol: " + protocol );
+ }
- connected = connectToRepository( wagon, repository, httpProxy );
- if ( connected )
- {
- File temp = new File( target.getAbsolutePath() + ".tmp" );
- temp.deleteOnExit();
+ //@todo configure wagon (ssh settings, etc)
- int tries = 0;
- boolean success;
+ checksums = prepareChecksumListeners( wagon );
- do
- {
- tries++;
+ connected = connectToRepository( wagon, repository, httpProxy );
+ if ( connected )
+ {
+ File temp = new File( target.getAbsolutePath() + ".tmp" );
+ temp.deleteOnExit();
- getLogger().info( "Trying " + path + " from " + repository.getName() + "..." );
+ int tries = 0;
+ boolean success;
- if ( !target.exists() )
- {
- wagon.get( path, temp );
- }
- else
- {
- wagon.getIfNewer( path, temp, target.lastModified() );
- }
+ do
+ {
+ tries++;
- success = doChecksumCheck( checksums, path, wagon, repositoryCachePath );
+ getLogger().info( "Trying " + path + " from " + repository.getName() + "..." );
- if ( tries > 1 && !success )
- {
- throw new ProxyException( "Checksum failures occurred while downloading " + path );
- }
+ if ( !target.exists() )
+ {
+ wagon.get( path, temp );
+ }
+ else
+ {
+ wagon.getIfNewer( path, temp, target.lastModified() );
}
- while ( !success );
- disconnectWagon( wagon );
+ success = doChecksumCheck( checksums, path, wagon, repositoryCachePath );
- if ( temp.exists() )
+ if ( tries > 1 && !success )
{
- moveTempToTarget( temp, target );
+ throw new ProxyException( "Checksum failures occurred while downloading " + path );
}
}
- //try next repository
- }
- catch ( TransferFailedException e )
- {
- String message = "Skipping repository " + repository.getName() + ": " + e.getMessage();
- processRepositoryFailure( repository, message, e );
+ while ( !success );
+
+ disconnectWagon( wagon );
+
+ if ( temp.exists() )
+ {
+ moveTempToTarget( temp, target );
+ }
}
- catch ( AuthorizationException e )
+ //try next repository
+ }
+ catch ( TransferFailedException e )
+ {
+ String message = "Skipping repository " + repository.getName() + ": " + e.getMessage();
+ processRepositoryFailure( repository, message, e );
+ }
+ catch ( AuthorizationException e )
+ {
+ String message = "Skipping repository " + repository.getName() + ": " + e.getMessage();
+ processRepositoryFailure( repository, message, e );
+ }
+ finally
+ {
+ if ( wagon != null && checksums != null )
{
- String message = "Skipping repository " + repository.getName() + ": " + e.getMessage();
- processRepositoryFailure( repository, message, e );
+ releaseChecksumListeners( wagon, checksums );
}
- finally
- {
- if ( wagon != null && checksums != null )
- {
- releaseChecksumListeners( wagon, checksums );
- }
- if ( connected )
- {
- disconnectWagon( wagon );
- }
+ if ( connected )
+ {
+ disconnectWagon( wagon );
}
}
- return target;
}
private static boolean isOutOfDate( ArtifactRepositoryPolicy policy, File target )
}
}
- private void getArtifact( Artifact artifact, ProxiedArtifactRepository repository, ArtifactRepository repoCache,
- ProxyInfo httpProxy )
+ private void getArtifactFromRepository( Artifact artifact, ProxiedArtifactRepository repository,
+ ArtifactRepository managedRepository, ProxyInfo httpProxy, File remoteFile )
throws ProxyException, ResourceDoesNotExistException
{
ArtifactRepository artifactRepository = repository.getRepository();
else
{
getLogger().debug( "Trying repository " + repository.getName() );
- // Don't use releases policy, we don't want to perform updates on them (only metadata, as used above)
- getFromRepository( artifactRepository.pathOf( artifact ), repository, repoCache.getBasedir(), httpProxy,
- artifact.isSnapshot() ? artifactRepository.getSnapshots() : null );
+ // Don't use releases policy, we don't want to perform updates on them (only metadata, as used earlier)
+ // TODO: this is not always!
+ if ( !remoteFile.exists() || isOutOfDate( policy, remoteFile ) )
+ {
+ getFileFromRepository( artifactRepository.pathOf( artifact ), repository,
+ managedRepository.getBasedir(), httpProxy, remoteFile );
+ }
getLogger().debug( " Artifact resolved" );
artifact.setResolved( true );
* limitations under the License.
*/
+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.codehaus.plexus.PlexusTestCase;
+import org.codehaus.plexus.util.FileUtils;
import java.io.File;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
/**
- * @author Edwin Punzalan
+ * @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 should be cached but caching is disabled
+ * @todo test snapshots - general
+ * @todo test snapshots - newer version on repo2 is pulled down
+ * @todo test snapshots - older version on repo2 is skipped
+ * @todo test snapshots - update interval
+ * @todo test metadata - general
+ * @todo test metadata - multiple repos are merged
+ * @todo test metadata - update interval
+ * @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
*/
public class ProxyRequestHandlerTest
extends PlexusTestCase
{
private ProxyRequestHandler requestHandler;
- public void testdummy(){}
+ private List proxiedRepositories;
+
+ private ArtifactRepository defaultManagedRepository;
+
+ private ArtifactRepository proxiedRepository1;
+
+ private ArtifactRepository proxiedRepository2;
-/* TODO!
protected void setUp()
throws Exception
{
super.setUp();
- requestHandler = (ProxyRequestHandler) container.lookup( ProxyRequestHandler.ROLE );
- }
+ requestHandler = (ProxyRequestHandler) lookup( ProxyRequestHandler.ROLE );
- public void testArtifactDownload()
- throws Exception
- {
- //test download
- String s = "/commons-logging/commons-logging/1.0/commons-logging-1.0.jar";
- File file = get( s );
- assertTrue( "File must be downloaded.", file.exists() );
- assertTrue( "Downloaded file should be present in the cache.",
- file.getAbsolutePath().startsWith( managedRepository.getBasedir() ) );
+ File repoLocation = getTestFile( "target/test-repository/managed" );
+ FileUtils.deleteDirectory( repoLocation );
+ copyDirectoryStructure( getTestFile( "src/test/repositories/managed" ), repoLocation );
- //test cache
- get( "/commons-logging/commons-logging/1.0/commons-logging-1.0.jar" );
+ 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 );
- try
- {
- get( "/commons-logging/commons-logging/2.0/commons-logging-2.0.jar" );
- fail( "Expected ResourceDoesNotExistException exception not thrown" );
- }
- catch ( ResourceDoesNotExistException e )
- {
- assertTrue( true );
- }
- }
+ File location = getTestFile( "src/test/repositories/proxied1" );
+ proxiedRepository1 = factory.createArtifactRepository( "proxied1", location.toURI().toURL().toExternalForm(),
+ defaultLayout, null, null );
- private File get( String s )
- throws ProxyException, ResourceDoesNotExistException
- {
- return requestHandler.get( s, proxiedRepositories, managedRepository );
- }
+ location = getTestFile( "src/test/repositories/proxied2" );
+ proxiedRepository2 = factory.createArtifactRepository( "proxied2", location.toURI().toURL().toExternalForm(),
+ defaultLayout, null, null );
- public void testArtifactChecksum()
- throws Exception
- {
- //force the downlod from the remote repository, use getAlways()
- File file = requestHandler.getAlways( "/commons-logging/commons-logging/1.0/commons-logging-1.0.jar.md5" );
- assertTrue( "File must be downloaded.", file.exists() );
- assertTrue( "Downloaded file should be present in the cache.",
- file.getAbsolutePath().startsWith( managedRepository.getBasedir() ) );
+ proxiedRepositories = new ArrayList( 2 );
+ proxiedRepositories.add( createProxiedRepository( proxiedRepository1 ) );
+ proxiedRepositories.add( createProxiedRepository( proxiedRepository2 ) );
}
- public void testNonArtifactWithNoChecksum()
- throws Exception
+ public void testGetDefaultLayoutNotPresent()
+ throws ResourceDoesNotExistException, ProxyException, IOException
{
- File file = get( "/not-standard/repository/file.txt" );
- assertTrue( "File must be downloaded.", file.exists() );
- assertTrue( "Downloaded file should be present in the cache.",
- file.getAbsolutePath().startsWith( managedRepository.getBasedir() ) );
- }
+ String path = "org/apache/maven/test/get-default-layout/1.0/get-default-layout-1.0.jar";
+ File expectedFile = new File( defaultManagedRepository.getBasedir(), path );
- public void testNonArtifactWithMD5Checksum()
- throws Exception
- {
- File file = get( "/checksumed-md5/repository/file.txt" );
- assertTrue( "File must be downloaded.", file.exists() );
- assertTrue( "Downloaded file should be present in the cache.",
- file.getAbsolutePath().startsWith( managedRepository.getBasedir() ) );
+ 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 ) );
+ // TODO: timestamp preservation requires support for that in wagon
+// assertEquals( "Check file timestamp", proxiedFile.lastModified(), file.lastModified() );
}
- public void testNonArtifactWithSHA1Checksum()
- throws Exception
+ public void testGetDefaultLayoutAlreadyPresent()
+ throws ResourceDoesNotExistException, ProxyException, IOException
{
- File file = get( "/checksumed-sha1/repository/file.txt" );
- assertTrue( "File must be downloaded.", file.exists() );
- assertTrue( "Downloaded file should be present in the cache.",
- file.getAbsolutePath().startsWith( managedRepository.getBasedir() ) );
+ String path = "org/apache/maven/test/get-default-layout-present/1.0/get-default-layout-present-1.0.jar";
+ File expectedFile = new File( defaultManagedRepository.getBasedir(), path );
+ String expectedContents = FileUtils.fileRead( expectedFile );
+ long originalModificationTime = expectedFile.lastModified();
+
+ assertTrue( expectedFile.exists() );
+
+ File file = requestHandler.get( path, proxiedRepositories, defaultManagedRepository );
+
+ assertEquals( "Check file matches", expectedFile, file );
+ assertTrue( "Check file created", file.exists() );
+ assertEquals( "Check file contents", expectedContents, FileUtils.fileRead( file ) );
+ File proxiedFile = new File( proxiedRepository1.getBasedir(), path );
+ String unexpectedContents = FileUtils.fileRead( proxiedFile );
+ assertFalse( "Check file contents", unexpectedContents.equals( FileUtils.fileRead( file ) ) );
+ assertFalse( "Check file timestamp is not that of proxy", proxiedFile.lastModified() == file.lastModified() );
+ assertEquals( "Check file timestamp is that of original managed file", originalModificationTime,
+ file.lastModified() );
}
- private ProxyConfiguration getProxyConfiguration()
- throws ComponentLookupException
+ /**
+ * 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
+ */
+ private static void copyDirectoryStructure( File sourceDirectory, File destDirectory )
+ throws IOException
{
- ProxyConfiguration config = new ProxyConfiguration();
-
- config.setRepositoryCachePath( "target/requestHandler-cache" );
-
- ArtifactRepositoryLayout defLayout = new DefaultRepositoryLayout();
+ if ( !sourceDirectory.exists() )
+ {
+ throw new IOException( "Source directory doesn't exists (" + sourceDirectory.getAbsolutePath() + ")." );
+ }
- File repo1File = getTestFile( "src/test/remote-repo1" );
+ File[] files = sourceDirectory.listFiles();
- ProxyRepository repo1 = new ProxyRepository( "test-repo", "file://" + repo1File.getAbsolutePath(), defLayout );
+ String sourcePath = sourceDirectory.getAbsolutePath();
- config.addRepository( repo1 );
+ for ( int i = 0; i < files.length; i++ )
+ {
+ File file = files[i];
+
+ String dest = file.getAbsolutePath();
+
+ dest = dest.substring( sourcePath.length() + 1 );
+
+ File destination = new File( destDirectory, dest );
+
+ if ( file.isFile() )
+ {
+ destination = destination.getParentFile();
+
+ FileUtils.copyFileToDirectory( file, destination );
+ }
+ else if ( file.isDirectory() )
+ {
+ if ( !".svn".equals( file.getName() ) )
+ {
+ if ( !destination.exists() && !destination.mkdirs() )
+ {
+ throw new IOException(
+ "Could not create destination directory '" + destination.getAbsolutePath() + "'." );
+ }
+
+ copyDirectoryStructure( file, destination );
+ }
+ }
+ else
+ {
+ throw new IOException( "Unknown file type: " + file.getAbsolutePath() );
+ }
+ }
+ }
- return config;
+ private static ProxiedArtifactRepository createProxiedRepository( ArtifactRepository repository )
+ {
+ ProxiedArtifactRepository proxiedArtifactRepository = new ProxiedArtifactRepository( repository );
+ proxiedArtifactRepository.setName( repository.getId() );
+ return proxiedArtifactRepository;
}
-*/
}