]> source.dussan.org Git - archiva.git/commitdiff
[MRM-876] let Archiva proxy arbitrary paths, particularly allowing it for pre-emptive...
authorBrett Porter <brett@apache.org>
Fri, 18 Jul 2008 05:47:04 +0000 (05:47 +0000)
committerBrett Porter <brett@apache.org>
Fri, 18 Jul 2008 05:47:04 +0000 (05:47 +0000)
git-svn-id: https://svn.apache.org/repos/asf/archiva/trunk@677828 13f79535-47bb-0310-9956-ffa450edef68

archiva-modules/archiva-base/archiva-proxy/src/main/java/org/apache/maven/archiva/proxy/DefaultRepositoryProxyConnectors.java
archiva-modules/archiva-base/archiva-proxy/src/main/java/org/apache/maven/archiva/proxy/RepositoryProxyConnectors.java
archiva-modules/archiva-base/archiva-proxy/src/test/java/org/apache/maven/archiva/proxy/ManagedDefaultTransferTest.java
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 with mode: 0644]
archiva-modules/archiva-web/archiva-webdav/src/main/java/org/apache/maven/archiva/webdav/ArchivaDavResourceFactory.java
archiva-modules/archiva-web/archiva-webdav/src/main/java/org/apache/maven/archiva/webdav/RepositoryServlet.java
archiva-modules/archiva-web/archiva-webdav/src/test/java/org/apache/maven/archiva/webdav/RepositoryServletProxiedPassthroughTest.java [new file with mode: 0644]

index c2937fe3eeb1a8c79507942d346b111fe3e91f6c..7f5a1e1d26098e16236aa5210d335975acbddf19 100644 (file)
@@ -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<ProxyConnector> 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<ProxyConnector> ret = (List<ProxyConnector>) 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 )
index c27c5b8ab01b1a3f943c2cea8f967c967b72a46c..cf68c9509486a5a2e90fac8ce0bf364720e4e444 100644 (file)
@@ -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.
      * 
index 9819f7cc0e3288f755a94af835642c6b497983f9..32f6db1a52a61f4bccbbb37ae6e5056dbff890ba 100644 (file)
@@ -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.
      * <p/>
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 (file)
index 0000000..bf07c71
--- /dev/null
@@ -0,0 +1,7 @@
+-----BEGIN PGP SIGNATURE-----
+Version: GnuPG v1.4.8 (Darwin)
+
+iEUEABECAAYFAkiAKPMACgkQTusOMqfRa9RpcQCfUsvdYGZ7P97TYXzQ0MclsV2r
+ASkAmJNCpmKjersaTXmsCupNGAJu38c=
+=/yRo
+-----END PGP SIGNATURE-----
index 39e21c38f6e051bbe5136398cf06c2236ff435ff..861df090fa198ef6e1232586381fd0aebfd5c398 100644 (file)
@@ -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?
index 5fa2d3bd7d61bb9ad7d7c9bc3073f4c46177aa77..ca9aa5aedb5805301afacd5c189c90c0684b0c32 100644 (file)
@@ -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 (file)
index 0000000..2de368b
--- /dev/null
@@ -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 <a href="mailto:joakime@apache.org">Joakim Erdfelt</a>
+ * @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;
+        }
+    }
+}