From 28e545b65a3079ca6b09d691c2ebb0d64d23254f Mon Sep 17 00:00:00 2001 From: Brett Porter Date: Fri, 18 Jul 2008 05:47:04 +0000 Subject: [PATCH] [MRM-876] let Archiva proxy arbitrary paths, particularly allowing it for pre-emptive proxying of support files when requested before the artifact git-svn-id: https://svn.apache.org/repos/asf/archiva/trunk@677828 13f79535-47bb-0310-9956-ffa450edef68 --- .../DefaultRepositoryProxyConnectors.java | 83 ++++++---- .../proxy/RepositoryProxyConnectors.java | 16 +- .../proxy/ManagedDefaultTransferTest.java | 23 +++ .../1.0/get-default-layout-1.0.jar.asc | 7 + .../webdav/ArchivaDavResourceFactory.java | 5 +- .../archiva/webdav/RepositoryServlet.java | 2 - ...positoryServletProxiedPassthroughTest.java | 156 ++++++++++++++++++ 7 files changed, 253 insertions(+), 39 deletions(-) create mode 100644 archiva-modules/archiva-base/archiva-proxy/src/test/repositories/proxied1/org/apache/maven/test/get-default-layout/1.0/get-default-layout-1.0.jar.asc create mode 100644 archiva-modules/archiva-web/archiva-webdav/src/test/java/org/apache/maven/archiva/webdav/RepositoryServletProxiedPassthroughTest.java diff --git a/archiva-modules/archiva-base/archiva-proxy/src/main/java/org/apache/maven/archiva/proxy/DefaultRepositoryProxyConnectors.java b/archiva-modules/archiva-base/archiva-proxy/src/main/java/org/apache/maven/archiva/proxy/DefaultRepositoryProxyConnectors.java index c2937fe3e..7f5a1e1d2 100644 --- a/archiva-modules/archiva-base/archiva-proxy/src/main/java/org/apache/maven/archiva/proxy/DefaultRepositoryProxyConnectors.java +++ b/archiva-modules/archiva-base/archiva-proxy/src/main/java/org/apache/maven/archiva/proxy/DefaultRepositoryProxyConnectors.java @@ -138,15 +138,6 @@ public class DefaultRepositoryProxyConnectors */ private RepositoryContentConsumers consumers; - /** - * Fetch an artifact from a remote repository. - * - * @param repository the managed repository to utilize for the request. - * @param artifact the artifact reference to fetch. - * @return the local file in the managed repository that was fetched, or null if the artifact was not (or - * could not be) fetched. - * @throws PolicyViolationException if there was a problem fetching the artifact. - */ public File fetchFromProxies( ManagedRepositoryContent repository, ArtifactReference artifact ) throws ProxyDownloadException { @@ -205,11 +196,56 @@ public class DefaultRepositoryProxyConnectors return null; } - /** - * Fetch, from the proxies, a metadata.xml file for the groupId:artifactId:version metadata contents. - * - * @return the (local) metadata file that was fetched/merged/updated, or null if no metadata file exists. - */ + public File fetchFromProxies( ManagedRepositoryContent repository, String path ) + { + File localFile = new File( repository.getRepoRoot(), path ); + + Properties requestProperties = new Properties(); + requestProperties.setProperty( "filetype", "resource" ); + requestProperties.setProperty( "managedRepositoryId", repository.getId() ); + + List connectors = getProxyConnectors( repository ); + for ( ProxyConnector connector : connectors ) + { + RemoteRepositoryContent targetRepository = connector.getTargetRepository(); + requestProperties.setProperty( "remoteRepositoryId", targetRepository.getId() ); + + String targetPath = path; + + try + { + File downloadedFile = + transferFile( connector, targetRepository, targetPath, repository, localFile, requestProperties ); + + if ( fileExists( downloadedFile ) ) + { + log.debug( "Successfully transferred: " + downloadedFile.getAbsolutePath() ); + return downloadedFile; + } + } + catch ( NotFoundException e ) + { + log.debug( "Resource " + path + " not found on repository \"" + + targetRepository.getRepository().getId() + "\"." ); + } + catch ( NotModifiedException e ) + { + log.debug( "Resource " + path + " not updated on repository \"" + + targetRepository.getRepository().getId() + "\"." ); + } + catch ( ProxyException e ) + { + log.warn( "Transfer error from repository \"" + targetRepository.getRepository().getId() + + "\" for resource " + path + ", continuing to next repository. Error message: " + e.getMessage() ); + log.debug( "Full stack trace", e ); + } + } + + log.debug( "Exhausted all target repositories, resource " + path + " not found." ); + + return null; + } + public File fetchFromProxies( ManagedRepositoryContent repository, VersionedReference metadata ) { File localFile = toLocalFile( repository, metadata ); @@ -323,12 +359,6 @@ public class DefaultRepositoryProxyConnectors return ( currentLastModified > originalLastModified ); } - /** - * Fetch from the proxies a metadata.xml file for the groupId:artifactId metadata contents. - * - * @return the (local) metadata file that was fetched/merged/updated, or null if no metadata file exists. - * @throws ProxyException if there was a problem fetching the metadata file. - */ public File fetchFromProxies( ManagedRepositoryContent repository, ProjectReference metadata ) { File localFile = toLocalFile( repository, metadata ); @@ -984,7 +1014,7 @@ public class DefaultRepositoryProxyConnectors List ret = (List) this.proxyConnectorMap.get( repository.getId() ); if ( ret == null ) { - return Collections.EMPTY_LIST; + return Collections.emptyList(); } Collections.sort( ret, ProxyConnectorOrderComparator.getInstance() ); @@ -1008,16 +1038,7 @@ public class DefaultRepositoryProxyConnectors /* do nothing */ } - private void logProcess( String managedRepoId, String resource, String event ) - { - - } - - private void logRejection( String managedRepoId, String remoteRepoId, String resource, String reason ) - { - - } - + @SuppressWarnings("unchecked") private void initConnectorsAndNetworkProxies() { synchronized ( this.proxyConnectorMap ) diff --git a/archiva-modules/archiva-base/archiva-proxy/src/main/java/org/apache/maven/archiva/proxy/RepositoryProxyConnectors.java b/archiva-modules/archiva-base/archiva-proxy/src/main/java/org/apache/maven/archiva/proxy/RepositoryProxyConnectors.java index c27c5b8ab..cf68c9509 100644 --- a/archiva-modules/archiva-base/archiva-proxy/src/main/java/org/apache/maven/archiva/proxy/RepositoryProxyConnectors.java +++ b/archiva-modules/archiva-base/archiva-proxy/src/main/java/org/apache/maven/archiva/proxy/RepositoryProxyConnectors.java @@ -45,7 +45,7 @@ public interface RepositoryProxyConnectors * * @param repository the source repository to use. (must be a managed repository) * @param artifact the artifact to fetch. - * @return true if the fetch operation succeeded in obtaining content, false if no content was obtained. + * @return the file that was obtained, or null if no content was obtained * @throws ProxyDownloadException if there was a problem fetching the content from the target repositories. */ public File fetchFromProxies( ManagedRepositoryContent repository, ArtifactReference artifact ) @@ -60,7 +60,7 @@ public interface RepositoryProxyConnectors * * @param repository the source repository to use. (must be a managed repository) * @param metadata the metadata to fetch. - * @return true if the fetch operation succeeded in obtaining content, false if no content was obtained. + * @return the file that was obtained, or null if no content was obtained */ public File fetchFromProxies( ManagedRepositoryContent repository, VersionedReference metadata ); @@ -73,10 +73,20 @@ public interface RepositoryProxyConnectors * * @param repository the source repository to use. (must be a managed repository) * @param metadata the metadata to fetch. - * @return true if the fetch operation succeeded in obtaining content, false if no content was obtained. + * @return the file that was obtained, or null if no content was obtained */ public File fetchFromProxies( ManagedRepositoryContent repository, ProjectReference metadata ); + /** + * Performs the fetch operation against the target repositories + * of the provided source repository. + * + * @param repository the source repository to use. (must be a managed repository) + * @param path the path of the resource to fetch + * @return the file that was obtained, or null if no content was obtained + */ + public File fetchFromProxies( ManagedRepositoryContent managedRepository, String path ); + /** * Get the List of {@link ProxyConnector} objects of the source repository. * diff --git a/archiva-modules/archiva-base/archiva-proxy/src/test/java/org/apache/maven/archiva/proxy/ManagedDefaultTransferTest.java b/archiva-modules/archiva-base/archiva-proxy/src/test/java/org/apache/maven/archiva/proxy/ManagedDefaultTransferTest.java index 9819f7cc0..32f6db1a5 100644 --- a/archiva-modules/archiva-base/archiva-proxy/src/test/java/org/apache/maven/archiva/proxy/ManagedDefaultTransferTest.java +++ b/archiva-modules/archiva-base/archiva-proxy/src/test/java/org/apache/maven/archiva/proxy/ManagedDefaultTransferTest.java @@ -64,6 +64,29 @@ public class ManagedDefaultTransferTest assertNoTempFiles( expectedFile ); } + public void testGetDefaultLayoutNotPresentPassthrough() + throws Exception + { + String path = "org/apache/maven/test/get-default-layout/1.0/get-default-layout-1.0.jar.asc"; + setupTestableManagedRepository( path ); + + File expectedFile = new File( managedDefaultDir, path ); + + // Ensure file isn't present first. + assertNotExistsInManagedDefaultRepo( expectedFile ); + + // Configure Connector (usually done within archiva.xml configuration) + saveConnector( ID_DEFAULT_MANAGED, ID_PROXIED1, ChecksumPolicy.FIX, ReleasesPolicy.ONCE, SnapshotsPolicy.ONCE, + CachedFailuresPolicy.NO ); + + // Attempt the proxy fetch. + File downloadedFile = proxyHandler.fetchFromProxies( managedDefaultRepository, path ); + + File sourceFile = new File( REPOPATH_PROXIED1, path ); + assertFileEquals( expectedFile, downloadedFile, sourceFile ); + assertNoTempFiles( expectedFile ); + } + /** * The attempt here should result in no file being transferred. *

diff --git a/archiva-modules/archiva-base/archiva-proxy/src/test/repositories/proxied1/org/apache/maven/test/get-default-layout/1.0/get-default-layout-1.0.jar.asc b/archiva-modules/archiva-base/archiva-proxy/src/test/repositories/proxied1/org/apache/maven/test/get-default-layout/1.0/get-default-layout-1.0.jar.asc new file mode 100644 index 000000000..bf07c716d --- /dev/null +++ b/archiva-modules/archiva-base/archiva-proxy/src/test/repositories/proxied1/org/apache/maven/test/get-default-layout/1.0/get-default-layout-1.0.jar.asc @@ -0,0 +1,7 @@ +-----BEGIN PGP SIGNATURE----- +Version: GnuPG v1.4.8 (Darwin) + +iEUEABECAAYFAkiAKPMACgkQTusOMqfRa9RpcQCfUsvdYGZ7P97TYXzQ0MclsV2r +ASkAmJNCpmKjersaTXmsCupNGAJu38c= +=/yRo +-----END PGP SIGNATURE----- diff --git a/archiva-modules/archiva-web/archiva-webdav/src/main/java/org/apache/maven/archiva/webdav/ArchivaDavResourceFactory.java b/archiva-modules/archiva-web/archiva-webdav/src/main/java/org/apache/maven/archiva/webdav/ArchivaDavResourceFactory.java index 39e21c38f..861df090f 100644 --- a/archiva-modules/archiva-web/archiva-webdav/src/main/java/org/apache/maven/archiva/webdav/ArchivaDavResourceFactory.java +++ b/archiva-modules/archiva-web/archiva-webdav/src/main/java/org/apache/maven/archiva/webdav/ArchivaDavResourceFactory.java @@ -495,10 +495,9 @@ public class ArchivaDavResourceFactory { if ( repositoryRequest.isSupportFile( resource.getPath() ) ) { - // Checksums are fetched with artifact / metadata. + File proxiedFile = connectors.fetchFromProxies( managedRepository, resource.getPath() ); - // Need to adjust the path for the checksum resource. - return false; + return ( proxiedFile != null ); } // Is it a Metadata resource? diff --git a/archiva-modules/archiva-web/archiva-webdav/src/main/java/org/apache/maven/archiva/webdav/RepositoryServlet.java b/archiva-modules/archiva-web/archiva-webdav/src/main/java/org/apache/maven/archiva/webdav/RepositoryServlet.java index 5fa2d3bd7..ca9aa5aed 100644 --- a/archiva-modules/archiva-web/archiva-webdav/src/main/java/org/apache/maven/archiva/webdav/RepositoryServlet.java +++ b/archiva-modules/archiva-web/archiva-webdav/src/main/java/org/apache/maven/archiva/webdav/RepositoryServlet.java @@ -28,8 +28,6 @@ import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; -import org.apache.commons.io.FileUtils; -import org.apache.commons.lang.StringUtils; import org.apache.jackrabbit.webdav.DavException; import org.apache.jackrabbit.webdav.DavLocatorFactory; import org.apache.jackrabbit.webdav.DavMethods; diff --git a/archiva-modules/archiva-web/archiva-webdav/src/test/java/org/apache/maven/archiva/webdav/RepositoryServletProxiedPassthroughTest.java b/archiva-modules/archiva-web/archiva-webdav/src/test/java/org/apache/maven/archiva/webdav/RepositoryServletProxiedPassthroughTest.java new file mode 100644 index 000000000..2de368b6b --- /dev/null +++ b/archiva-modules/archiva-web/archiva-webdav/src/test/java/org/apache/maven/archiva/webdav/RepositoryServletProxiedPassthroughTest.java @@ -0,0 +1,156 @@ +package org.apache.maven.archiva.webdav; + +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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 java.io.File; + +import com.meterware.httpunit.GetMethodWebRequest; +import com.meterware.httpunit.HttpUnitOptions; +import com.meterware.httpunit.WebRequest; +import com.meterware.httpunit.WebResponse; + +/** + * RepositoryServlet Tests, Proxied, Get of resources that are not artifacts or metadata, with varying policy settings. + * + * @author Joakim Erdfelt + * @version $Id: RepositoryServletProxiedReleasePolicyTest.java 661174 2008-05-29 01:49:41Z jdumay $ + */ +public class RepositoryServletProxiedPassthroughTest + extends AbstractRepositoryServletProxiedTestCase +{ + private static final String CONTENT_SHA1 = "2aab0a51c04c9023636852f3e63a68034ba10142"; + + private static final String PATH_SHA1 = "org/apache/archiva/test/1.0/test-1.0.jar.sha1"; + + private static final String CONTENT_ASC = + "-----BEGIN PGP SIGNATURE-----\n" + "Version: GnuPG v1.4.8 (Darwin)\n" + "\n" + + "iEYEABECAAYFAkiAIVgACgkQxbsDNW2stZZjyACeK3LW+ZDeawCyJj4XgvUaJkNh\n" + + "qIEAoIUiijY4Iw82RWOT75Rt3yZuY6ZI\n" + "=WLkm\n" + "-----END PGP SIGNATURE-----\n"; + + private static final String PATH_ASC = "org/apache/archiva/test/1.0/test-1.0.jar.asc"; + + public void testGetProxiedManagedNewerSha1() + throws Exception + { + assertGetProxiedResource( EXPECT_MANAGED_CONTENTS, HAS_MANAGED_COPY, ( NEWER * OVER_ONE_DAY ), PATH_SHA1, + CONTENT_SHA1 ); + } + + public void testGetProxiedManagedOlderSha1() + throws Exception + { + assertGetProxiedResource( EXPECT_REMOTE_CONTENTS, HAS_MANAGED_COPY, ( OLDER * OVER_ONE_DAY ), PATH_SHA1, + CONTENT_SHA1 ); + } + + public void testGetProxiedNoManagedContentSha1() + throws Exception + { + assertGetProxiedResource( EXPECT_REMOTE_CONTENTS, NO_MANAGED_COPY, PATH_SHA1, CONTENT_SHA1 ); + } + + public void testGetProxiedEqualSha1() + throws Exception + { + assertGetProxiedResource( EXPECT_MANAGED_CONTENTS, HAS_MANAGED_COPY, PATH_SHA1, CONTENT_SHA1 ); + } + + public void testGetProxiedManagedNewerAsc() + throws Exception + { + assertGetProxiedResource( EXPECT_MANAGED_CONTENTS, HAS_MANAGED_COPY, ( NEWER * OVER_ONE_DAY ), PATH_ASC, + CONTENT_ASC ); + } + + public void testGetProxiedManagedOlderAsc() + throws Exception + { + assertGetProxiedResource( EXPECT_REMOTE_CONTENTS, HAS_MANAGED_COPY, ( OLDER * OVER_ONE_DAY ), PATH_ASC, + CONTENT_ASC ); + } + + public void testGetProxiedNoManagedContentAsc() + throws Exception + { + assertGetProxiedResource( EXPECT_REMOTE_CONTENTS, NO_MANAGED_COPY, PATH_ASC, CONTENT_ASC ); + } + + public void testGetProxiedEqualAsc() + throws Exception + { + assertGetProxiedResource( EXPECT_MANAGED_CONTENTS, HAS_MANAGED_COPY, PATH_ASC, CONTENT_ASC ); + } + + private void assertGetProxiedResource( int expectation, boolean hasManagedCopy, String path, String content ) + throws Exception + { + assertGetProxiedResource( expectation, hasManagedCopy, 0, path, content ); + } + + private void assertGetProxiedResource( int expectation, boolean hasManagedCopy, long deltaManagedToRemoteTimestamp, + String path, String contents ) + throws Exception + { + // --- Setup + setupCentralRemoteRepo(); + setupCleanInternalRepo(); + + String expectedRemoteContents = contents; + String expectedManagedContents = null; + File remoteFile = populateRepo( remoteCentral, path, expectedRemoteContents ); + + if ( hasManagedCopy ) + { + expectedManagedContents = contents; + File managedFile = populateRepo( repoRootInternal, path, expectedManagedContents ); + managedFile.setLastModified( remoteFile.lastModified() + deltaManagedToRemoteTimestamp ); + } + + setupConnector( REPOID_INTERNAL, remoteCentral ); + saveConfiguration(); + + // --- Execution + // process the response code later, not via an exception. + HttpUnitOptions.setExceptionsThrownOnErrorStatus( false ); + + WebRequest request = new GetMethodWebRequest( "http://machine.com/repository/internal/" + path ); + WebResponse response = sc.getResponse( request ); + + // --- Verification + + switch ( expectation ) + { + case EXPECT_MANAGED_CONTENTS: + assertResponseOK( response ); + assertTrue( "Invalid Test Case: Can't expect managed contents with " + + "test that doesn't have a managed copy in the first place.", hasManagedCopy ); + assertEquals( "Expected managed file contents", expectedManagedContents, response.getText() ); + break; + case EXPECT_REMOTE_CONTENTS: + assertResponseOK( response ); + assertEquals( "Expected remote file contents", expectedRemoteContents, response.getText() ); + break; + case EXPECT_NOT_FOUND: + assertResponseNotFound( response ); + assertManagedFileNotExists( repoRootInternal, path ); + break; + } + } +} -- 2.39.5