aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMartin Stockhammer <martin_s@apache.org>2020-06-11 14:33:00 +0200
committerMartin Stockhammer <martin_s@apache.org>2020-06-11 14:33:00 +0200
commit46fd585f40f0264b8889154e1924eb8df991b0f3 (patch)
tree09408c7375f7e57d0760ef48b0ddae7be768e4ca
parentb942314aa27330a179acf17300fea6849bf89d4d (diff)
downloadarchiva-46fd585f40f0264b8889154e1924eb8df991b0f3.tar.gz
archiva-46fd585f40f0264b8889154e1924eb8df991b0f3.zip
Improving repository API
-rw-r--r--archiva-modules/archiva-base/archiva-common/src/main/java/org/apache/archiva/common/utils/VersionUtil.java2
-rw-r--r--archiva-modules/archiva-base/archiva-consumers/archiva-core-consumers/src/main/java/org/apache/archiva/consumers/core/repository/DaysOldRepositoryPurge.java140
-rw-r--r--archiva-modules/archiva-base/archiva-consumers/archiva-core-consumers/src/main/java/org/apache/archiva/consumers/core/repository/RetentionCountRepositoryPurge.java104
-rw-r--r--archiva-modules/archiva-base/archiva-proxy-api/src/main/java/org/apache/archiva/proxy/model/RepositoryProxyHandler.java16
-rw-r--r--archiva-modules/archiva-base/archiva-proxy/src/main/java/org/apache/archiva/proxy/DefaultRepositoryProxyHandler.java72
-rw-r--r--archiva-modules/archiva-base/archiva-repository-api/src/main/java/org/apache/archiva/repository/RepositoryRequestInfo.java10
-rw-r--r--archiva-modules/archiva-maven/archiva-maven-repository/src/main/java/org/apache/archiva/repository/maven/content/ManagedDefaultRepositoryContent.java112
-rw-r--r--archiva-modules/archiva-maven/archiva-maven-repository/src/main/java/org/apache/archiva/repository/maven/content/MavenRepositoryRequestInfo.java19
-rw-r--r--archiva-modules/archiva-maven/archiva-maven-repository/src/main/java/org/apache/archiva/repository/maven/metadata/storage/Maven2RepositoryStorage.java92
-rw-r--r--archiva-modules/archiva-maven/archiva-maven-repository/src/test/java/org/apache/archiva/repository/maven/content/ManagedDefaultRepositoryContentTest.java2
-rw-r--r--archiva-modules/archiva-maven/archiva-maven-repository/src/test/java/org/apache/archiva/repository/maven/content/MavenRepositoryRequestInfoTest.java9
-rw-r--r--archiva-modules/archiva-web/archiva-security/src/test/java/org/apache/archiva/security/mock/MockBeanServices.java7
-rw-r--r--archiva-modules/archiva-web/archiva-webdav/src/main/java/org/apache/archiva/webdav/ArchivaDavResourceFactory.java16
-rw-r--r--archiva-modules/metadata/metadata-repository-api/src/main/java/org/apache/archiva/metadata/repository/storage/RepositoryStorage.java16
-rw-r--r--archiva-modules/plugins/metadata-store-cassandra/src/test/java/org/apache/archiva/metadata/repository/cassandra/MockRepositoryStorage.java7
15 files changed, 458 insertions, 166 deletions
diff --git a/archiva-modules/archiva-base/archiva-common/src/main/java/org/apache/archiva/common/utils/VersionUtil.java b/archiva-modules/archiva-base/archiva-common/src/main/java/org/apache/archiva/common/utils/VersionUtil.java
index c1a3ac694..408d7b4e1 100644
--- a/archiva-modules/archiva-base/archiva-common/src/main/java/org/apache/archiva/common/utils/VersionUtil.java
+++ b/archiva-modules/archiva-base/archiva-common/src/main/java/org/apache/archiva/common/utils/VersionUtil.java
@@ -194,4 +194,6 @@ public class VersionUtil
}
return version;
}
+
+
}
diff --git a/archiva-modules/archiva-base/archiva-consumers/archiva-core-consumers/src/main/java/org/apache/archiva/consumers/core/repository/DaysOldRepositoryPurge.java b/archiva-modules/archiva-base/archiva-consumers/archiva-core-consumers/src/main/java/org/apache/archiva/consumers/core/repository/DaysOldRepositoryPurge.java
index fb42390bb..282f45c41 100644
--- a/archiva-modules/archiva-base/archiva-consumers/archiva-core-consumers/src/main/java/org/apache/archiva/consumers/core/repository/DaysOldRepositoryPurge.java
+++ b/archiva-modules/archiva-base/archiva-consumers/archiva-core-consumers/src/main/java/org/apache/archiva/consumers/core/repository/DaysOldRepositoryPurge.java
@@ -23,9 +23,9 @@ import org.apache.archiva.common.utils.VersionComparator;
import org.apache.archiva.common.utils.VersionUtil;
import org.apache.archiva.metadata.audit.RepositoryListener;
import org.apache.archiva.metadata.repository.RepositorySession;
-import org.apache.archiva.repository.ManagedRepositoryContent;
-import org.apache.archiva.repository.LayoutException;
import org.apache.archiva.repository.BaseRepositoryContentLayout;
+import org.apache.archiva.repository.LayoutException;
+import org.apache.archiva.repository.ManagedRepositoryContent;
import org.apache.archiva.repository.content.Artifact;
import org.apache.archiva.repository.content.ContentItem;
import org.apache.archiva.repository.content.base.ArchivaItemSelector;
@@ -74,94 +74,94 @@ public class DaysOldRepositoryPurge
{
ContentItem item = repository.toItem( path );
- if ( item instanceof Artifact )
+ Artifact artifactItem = repository.getLayout( BaseRepositoryContentLayout.class ).adaptItem( Artifact.class, item );
+
+ if ( !artifactItem.exists( ) )
{
- Artifact artifactItem = (Artifact) item;
+ return;
+ }
- if ( !artifactItem.exists( ) )
- {
- return;
- }
+ // ArtifactReference artifact = repository.toArtifactReference( path );
- // ArtifactReference artifact = repository.toArtifactReference( path );
-
- Calendar olderThanThisDate = Calendar.getInstance( TimeZone.getTimeZone( "UTC" ) );
- olderThanThisDate.add( Calendar.DATE, -retentionPeriod );
-
- ArchivaItemSelector selector = ArchivaItemSelector.builder( )
- .withNamespace( artifactItem.getVersion( ).getProject( ).getNamespace( ).getId( ) )
- .withProjectId( artifactItem.getVersion( ).getProject( ).getId( ) )
- .withVersion( artifactItem.getVersion( ).getId( ) )
- .withClassifier( "*" )
- .includeRelatedArtifacts( )
- .build( );
-
- List<String> artifactVersions;
- try( Stream<? extends Artifact> stream = repository.getLayout( BaseRepositoryContentLayout.class ).newArtifactStream( selector )){
- artifactVersions = stream.map( a -> a.getArtifactVersion( ) )
- .filter( StringUtils::isNotEmpty )
- .distinct()
- .collect( Collectors.toList( ) );
- }
+ Calendar olderThanThisDate = Calendar.getInstance( TimeZone.getTimeZone( "UTC" ) );
+ olderThanThisDate.add( Calendar.DATE, -retentionPeriod );
- Collections.sort( artifactVersions, VersionComparator.getInstance( ) );
+ ArchivaItemSelector selector = ArchivaItemSelector.builder( )
+ .withNamespace( artifactItem.getVersion( ).getProject( ).getNamespace( ).getId( ) )
+ .withProjectId( artifactItem.getVersion( ).getProject( ).getId( ) )
+ .withVersion( artifactItem.getVersion( ).getId( ) )
+ .withClassifier( "*" )
+ .includeRelatedArtifacts( )
+ .build( );
- if ( retentionCount > artifactVersions.size( ) )
- {
- // Done. nothing to do here. skip it.
- return;
- }
+ List<String> artifactVersions;
+ try ( Stream<? extends Artifact> stream = repository.getLayout( BaseRepositoryContentLayout.class ).newArtifactStream( selector ) )
+ {
+ artifactVersions = stream.map( a -> a.getArtifactVersion( ) )
+ .filter( StringUtils::isNotEmpty )
+ .distinct( )
+ .collect( Collectors.toList( ) );
+ }
+
+ Collections.sort( artifactVersions, VersionComparator.getInstance( ) );
- int countToPurge = artifactVersions.size( ) - retentionCount;
+ if ( retentionCount > artifactVersions.size( ) )
+ {
+ // Done. nothing to do here. skip it.
+ return;
+ }
+ int countToPurge = artifactVersions.size( ) - retentionCount;
- ArchivaItemSelector.Builder artifactSelectorBuilder = ArchivaItemSelector.builder( )
- .withNamespace( artifactItem.getVersion( ).getProject( ).getNamespace( ).getId( ) )
- .withProjectId( artifactItem.getVersion( ).getProject( ).getId( ) )
- .withVersion( artifactItem.getVersion( ).getId( ) )
- .withArtifactId( artifactItem.getId() )
- .withClassifier( "*" )
- .includeRelatedArtifacts( );
- Set<Artifact> artifactsToDelete = new HashSet<>( );
- for ( String version : artifactVersions )
+ ArchivaItemSelector.Builder artifactSelectorBuilder = ArchivaItemSelector.builder( )
+ .withNamespace( artifactItem.getVersion( ).getProject( ).getNamespace( ).getId( ) )
+ .withProjectId( artifactItem.getVersion( ).getProject( ).getId( ) )
+ .withVersion( artifactItem.getVersion( ).getId( ) )
+ .withArtifactId( artifactItem.getId( ) )
+ .withClassifier( "*" )
+ .includeRelatedArtifacts( );
+
+ Set<Artifact> artifactsToDelete = new HashSet<>( );
+ for ( String version : artifactVersions )
+ {
+ if ( countToPurge-- <= 0 )
{
- if ( countToPurge-- <= 0 )
- {
- break;
- }
+ break;
+ }
- ArchivaItemSelector artifactSelector = artifactSelectorBuilder.withArtifactVersion( version ).build( );
- try
- {
+ ArchivaItemSelector artifactSelector = artifactSelectorBuilder.withArtifactVersion( version ).build( );
+ try
+ {
- // Is this a generic snapshot "1.0-SNAPSHOT" ?
- if ( VersionUtil.isGenericSnapshot( version ) )
+ // Is this a generic snapshot "1.0-SNAPSHOT" ?
+ if ( VersionUtil.isGenericSnapshot( version ) )
+ {
+ List<? extends Artifact> artifactList = repository.getLayout( BaseRepositoryContentLayout.class ).getArtifacts( artifactSelector );
+ if ( artifactList.size( ) > 0 && artifactList.get( 0 ).getAsset( ).getModificationTime( ).toEpochMilli( ) < olderThanThisDate.getTimeInMillis( ) )
{
- List<? extends Artifact> artifactList = repository.getLayout( BaseRepositoryContentLayout.class ).getArtifacts( artifactSelector );
- if ( artifactList.size()>0 && artifactList.get(0).getAsset().getModificationTime( ).toEpochMilli( ) < olderThanThisDate.getTimeInMillis( ) )
- {
- artifactsToDelete.addAll( artifactList );
- }
+ artifactsToDelete.addAll( artifactList );
}
- // Is this a timestamp snapshot "1.0-20070822.123456-42" ?
- else if ( VersionUtil.isUniqueSnapshot( version ) )
- {
- Calendar timestampCal = uniqueSnapshotToCalendar( version );
+ }
+ // Is this a timestamp snapshot "1.0-20070822.123456-42" ?
+ else if ( VersionUtil.isUniqueSnapshot( version ) )
+ {
+ Calendar timestampCal = uniqueSnapshotToCalendar( version );
- if ( timestampCal.getTimeInMillis( ) < olderThanThisDate.getTimeInMillis( ) )
- {
- artifactsToDelete.addAll( repository.getLayout( BaseRepositoryContentLayout.class ).getArtifacts( artifactSelector ) );
- }
+ if ( timestampCal.getTimeInMillis( ) < olderThanThisDate.getTimeInMillis( ) )
+ {
+ artifactsToDelete.addAll( repository.getLayout( BaseRepositoryContentLayout.class ).getArtifacts( artifactSelector ) );
}
- } catch ( IllegalArgumentException e ) {
- log.error( "Bad selector for artifact: {}", e.getMessage( ), e );
- // continue
}
}
- purge( artifactsToDelete );
+ catch ( IllegalArgumentException e )
+ {
+ log.error( "Bad selector for artifact: {}", e.getMessage( ), e );
+ // continue
+ }
}
+ purge( artifactsToDelete );
}
catch ( LayoutException e )
{
diff --git a/archiva-modules/archiva-base/archiva-consumers/archiva-core-consumers/src/main/java/org/apache/archiva/consumers/core/repository/RetentionCountRepositoryPurge.java b/archiva-modules/archiva-base/archiva-consumers/archiva-core-consumers/src/main/java/org/apache/archiva/consumers/core/repository/RetentionCountRepositoryPurge.java
index ec3a242f4..74df6a679 100644
--- a/archiva-modules/archiva-base/archiva-consumers/archiva-core-consumers/src/main/java/org/apache/archiva/consumers/core/repository/RetentionCountRepositoryPurge.java
+++ b/archiva-modules/archiva-base/archiva-consumers/archiva-core-consumers/src/main/java/org/apache/archiva/consumers/core/repository/RetentionCountRepositoryPurge.java
@@ -21,12 +21,12 @@ package org.apache.archiva.consumers.core.repository;
import org.apache.archiva.common.utils.VersionComparator;
import org.apache.archiva.common.utils.VersionUtil;
+import org.apache.archiva.metadata.audit.RepositoryListener;
import org.apache.archiva.metadata.repository.RepositorySession;
import org.apache.archiva.model.ArtifactReference;
-import org.apache.archiva.repository.ManagedRepositoryContent;
-import org.apache.archiva.repository.LayoutException;
import org.apache.archiva.repository.BaseRepositoryContentLayout;
-import org.apache.archiva.metadata.audit.RepositoryListener;
+import org.apache.archiva.repository.LayoutException;
+import org.apache.archiva.repository.ManagedRepositoryContent;
import org.apache.archiva.repository.content.Artifact;
import org.apache.archiva.repository.content.ContentItem;
import org.apache.archiva.repository.content.base.ArchivaItemSelector;
@@ -61,67 +61,65 @@ public class RetentionCountRepositoryPurge
try
{
ContentItem item = repository.toItem( path );
- if (item instanceof Artifact )
+ BaseRepositoryContentLayout layout = repository.getLayout( BaseRepositoryContentLayout.class );
+ Artifact artifact = layout.adaptItem( Artifact.class, item );
+ if ( !artifact.exists( ) )
{
- Artifact artifact = (Artifact) item;
- if (!artifact.exists()) {
- return;
- }
+ return;
+ }
- if ( VersionUtil.isSnapshot( artifact.getVersion( ).getId() ) )
- {
- ArchivaItemSelector selector = ArchivaItemSelector.builder( )
- .withNamespace( artifact.getVersion( ).getProject( ).getNamespace( ).getId( ) )
- .withProjectId( artifact.getVersion( ).getProject( ).getId( ) )
- .withArtifactId( artifact.getId( ) )
- .withVersion( artifact.getVersion( ).getId( ) )
- .withClassifier( "*" )
- .includeRelatedArtifacts()
- .build( );
+ if ( VersionUtil.isSnapshot( artifact.getVersion( ).getId( ) ) )
+ {
+ ArchivaItemSelector selector = ArchivaItemSelector.builder( )
+ .withNamespace( artifact.getVersion( ).getProject( ).getNamespace( ).getId( ) )
+ .withProjectId( artifact.getVersion( ).getProject( ).getId( ) )
+ .withArtifactId( artifact.getId( ) )
+ .withVersion( artifact.getVersion( ).getId( ) )
+ .withClassifier( "*" )
+ .includeRelatedArtifacts( )
+ .build( );
- List<String> versions;
- try( Stream<? extends Artifact> stream = repository.getLayout( BaseRepositoryContentLayout.class ).newArtifactStream( selector) ){
- versions = stream.map( a -> a.getArtifactVersion( ) )
- .filter( StringUtils::isNotEmpty )
- .distinct()
- .collect( Collectors.toList( ) );
- }
+ List<String> versions;
+ try ( Stream<? extends Artifact> stream = repository.getLayout( BaseRepositoryContentLayout.class ).newArtifactStream( selector ) )
+ {
+ versions = stream.map( a -> a.getArtifactVersion( ) )
+ .filter( StringUtils::isNotEmpty )
+ .distinct( )
+ .collect( Collectors.toList( ) );
+ }
+
+ Collections.sort( versions, VersionComparator.getInstance( ) );
- Collections.sort( versions, VersionComparator.getInstance( ) );
+ if ( retentionCount > versions.size( ) )
+ {
+ log.trace( "No deletion, because retention count is higher than actual number of artifacts." );
+ // Done. nothing to do here. skip it.
+ return;
+ }
- if ( retentionCount > versions.size( ) )
+ ArchivaItemSelector.Builder selectorBuilder = ArchivaItemSelector.builder( )
+ .withNamespace( artifact.getVersion( ).getProject( ).getNamespace( ).getId( ) )
+ .withProjectId( artifact.getVersion( ).getProject( ).getId( ) )
+ .withArtifactId( artifact.getId( ) )
+ .withClassifier( "*" )
+ .includeRelatedArtifacts( )
+ .withVersion( artifact.getVersion( ).getId( ) );
+ int countToPurge = versions.size( ) - retentionCount;
+ Set<Artifact> artifactsToDelete = new HashSet<>( );
+ for ( String version : versions )
+ {
+ if ( countToPurge-- <= 0 )
{
- log.trace( "No deletion, because retention count is higher than actual number of artifacts." );
- // Done. nothing to do here. skip it.
- return;
+ break;
}
-
- ArchivaItemSelector.Builder selectorBuilder = ArchivaItemSelector.builder( )
- .withNamespace( artifact.getVersion( ).getProject( ).getNamespace( ).getId( ) )
- .withProjectId( artifact.getVersion( ).getProject( ).getId( ) )
- .withArtifactId( artifact.getId( ) )
- .withClassifier( "*" )
- .includeRelatedArtifacts()
- .withVersion( artifact.getVersion( ).getId( ) );
- int countToPurge = versions.size( ) - retentionCount;
- Set<Artifact> artifactsToDelete = new HashSet<>( );
- for ( String version : versions )
+ List<? extends Artifact> delArtifacts = repository.getLayout( BaseRepositoryContentLayout.class ).getArtifacts( selectorBuilder.withArtifactVersion( version ).build( ) );
+ if ( delArtifacts != null && delArtifacts.size( ) > 0 )
{
- if ( countToPurge-- <= 0 )
- {
- break;
- }
- List<? extends Artifact> delArtifacts = repository.getLayout( BaseRepositoryContentLayout.class ).getArtifacts( selectorBuilder.withArtifactVersion( version ).build( ) );
- if (delArtifacts!=null && delArtifacts.size()>0)
- {
- artifactsToDelete.addAll( delArtifacts );
- }
+ artifactsToDelete.addAll( delArtifacts );
}
- purge( artifactsToDelete );
}
- } else {
- throw new RepositoryPurgeException( "Bad artifact path " + path );
+ purge( artifactsToDelete );
}
}
catch ( LayoutException le )
diff --git a/archiva-modules/archiva-base/archiva-proxy-api/src/main/java/org/apache/archiva/proxy/model/RepositoryProxyHandler.java b/archiva-modules/archiva-base/archiva-proxy-api/src/main/java/org/apache/archiva/proxy/model/RepositoryProxyHandler.java
index f775c3924..f6c9259a3 100644
--- a/archiva-modules/archiva-base/archiva-proxy-api/src/main/java/org/apache/archiva/proxy/model/RepositoryProxyHandler.java
+++ b/archiva-modules/archiva-base/archiva-proxy-api/src/main/java/org/apache/archiva/proxy/model/RepositoryProxyHandler.java
@@ -25,6 +25,7 @@ import org.apache.archiva.policies.ProxyDownloadException;
import org.apache.archiva.repository.ManagedRepository;
import org.apache.archiva.repository.RepositoryType;
import org.apache.archiva.repository.content.Artifact;
+import org.apache.archiva.repository.content.ItemSelector;
import org.apache.archiva.repository.storage.StorageAsset;
import java.util.List;
@@ -90,6 +91,21 @@ public interface RepositoryProxyHandler
throws ProxyDownloadException;
/**
+ * Performs the artifact fetch operation against the target repositories
+ * of the provided source repository.
+ * <p>
+ * If the artifact is found, it is downloaded and placed into the source repository
+ * filesystem.
+ *
+ * @param repository the source repository to use. (must be a managed repository)
+ * @param artifactSelector the artifact to fetch.
+ * @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.
+ */
+ StorageAsset fetchFromProxies( ManagedRepository repository, ItemSelector artifactSelector )
+ throws ProxyDownloadException;
+
+ /**
* Performs the metadata fetch operation against the target repositories
* of the provided source repository.
* <p>
diff --git a/archiva-modules/archiva-base/archiva-proxy/src/main/java/org/apache/archiva/proxy/DefaultRepositoryProxyHandler.java b/archiva-modules/archiva-base/archiva-proxy/src/main/java/org/apache/archiva/proxy/DefaultRepositoryProxyHandler.java
index 8cf2e97d2..2373fb938 100644
--- a/archiva-modules/archiva-base/archiva-proxy/src/main/java/org/apache/archiva/proxy/DefaultRepositoryProxyHandler.java
+++ b/archiva-modules/archiva-base/archiva-proxy/src/main/java/org/apache/archiva/proxy/DefaultRepositoryProxyHandler.java
@@ -50,6 +50,7 @@ import org.apache.archiva.repository.RemoteRepository;
import org.apache.archiva.repository.RemoteRepositoryContent;
import org.apache.archiva.repository.RepositoryType;
import org.apache.archiva.repository.content.Artifact;
+import org.apache.archiva.repository.content.ContentItem;
import org.apache.archiva.repository.content.ItemSelector;
import org.apache.archiva.repository.content.base.ArchivaItemSelector;
import org.apache.archiva.repository.metadata.base.MetadataTools;
@@ -207,6 +208,73 @@ public abstract class DefaultRepositoryProxyHandler implements RepositoryProxyHa
}
@Override
+ public StorageAsset fetchFromProxies( ManagedRepository repository, ItemSelector artifactSelector )
+ throws ProxyDownloadException
+ {
+ Map<String, Exception> previousExceptions = new LinkedHashMap<>();
+ ContentItem item = repository.getContent( ).getItem( artifactSelector );
+ StorageAsset localFile = item.getAsset( );
+
+ Properties requestProperties = new Properties();
+ requestProperties.setProperty( "filetype", "artifact" );
+ requestProperties.setProperty( "version", artifactSelector.getVersion() );
+ requestProperties.setProperty( "managedRepositoryId", repository.getId() );
+
+ List<ProxyConnector> connectors = getProxyConnectors( repository );
+ for ( ProxyConnector connector : connectors )
+ {
+ if ( !connector.isEnabled() )
+ {
+ continue;
+ }
+
+ RemoteRepository targetRepository = connector.getTargetRepository();
+ requestProperties.setProperty( "remoteRepositoryId", targetRepository.getId() );
+
+ StorageAsset targetFile = targetRepository.getAsset( localFile.getPath( ) );
+ // Removing the leading '/' from the path
+ String targetPath = targetFile.getPath( ).substring( 1 );
+ try
+ {
+ StorageAsset downloadedFile =
+ transferFile( connector, targetRepository, targetPath, repository, localFile, requestProperties,
+ true );
+
+ if ( fileExists(downloadedFile) )
+ {
+ log.debug( "Successfully transferred: {}", downloadedFile.getPath() );
+ return downloadedFile;
+ }
+ }
+ catch ( NotFoundException e )
+ {
+ log.debug( "Artifact {} not found on repository \"{}\".", item,
+ targetRepository.getId() );
+ }
+ catch ( NotModifiedException e )
+ {
+ log.debug( "Artifact {} not updated on repository \"{}\".", item,
+ targetRepository.getId() );
+ }
+ catch ( ProxyException e )
+ {
+ validatePolicies( this.downloadErrorPolicies, connector.getPolicies(), requestProperties, item,
+ targetRepository.getContent(), localFile, e, previousExceptions );
+ }
+ }
+
+ if ( !previousExceptions.isEmpty() )
+ {
+ throw new ProxyDownloadException( "Failures occurred downloading from some remote repositories",
+ previousExceptions );
+ }
+
+ log.debug( "Exhausted all target repositories, artifact {} not found.", item );
+
+ return null;
+ }
+
+ @Override
public StorageAsset fetchFromProxies( ManagedRepository repository, ArtifactReference artifact )
throws ProxyDownloadException
{
@@ -736,7 +804,7 @@ public abstract class DefaultRepositoryProxyHandler implements RepositoryProxyHa
}
private void validatePolicies( Map<String, DownloadErrorPolicy> policies, Map<Policy, PolicyOption> settings,
- Properties request, Artifact artifact, RemoteRepositoryContent content,
+ Properties request, ContentItem artifact, RemoteRepositoryContent content,
StorageAsset localFile, Exception exception, Map<String, Exception> previousExceptions )
throws ProxyDownloadException
{
@@ -784,7 +852,7 @@ public abstract class DefaultRepositoryProxyHandler implements RepositoryProxyHa
log.warn(
"Transfer error from repository {} for artifact {} , continuing to next repository. Error message: {}",
- content.getRepository().getId(), artifact.getId(), exception.getMessage() );
+ content.getRepository().getId(), artifact, exception.getMessage() );
log.debug( "Full stack trace", exception );
}
diff --git a/archiva-modules/archiva-base/archiva-repository-api/src/main/java/org/apache/archiva/repository/RepositoryRequestInfo.java b/archiva-modules/archiva-base/archiva-repository-api/src/main/java/org/apache/archiva/repository/RepositoryRequestInfo.java
index 04700e76b..52cfb2c22 100644
--- a/archiva-modules/archiva-base/archiva-repository-api/src/main/java/org/apache/archiva/repository/RepositoryRequestInfo.java
+++ b/archiva-modules/archiva-base/archiva-repository-api/src/main/java/org/apache/archiva/repository/RepositoryRequestInfo.java
@@ -20,6 +20,7 @@ package org.apache.archiva.repository;
*/
import org.apache.archiva.model.ArtifactReference;
+import org.apache.archiva.repository.content.ItemSelector;
import org.apache.archiva.repository.features.RepositoryFeature;
/**
@@ -42,6 +43,15 @@ public interface RepositoryRequestInfo
*/
ArtifactReference toArtifactReference( String requestPath ) throws LayoutException;
+
+ /**
+ * Returns the item selector that matches the given path.
+ * @param requestPath the request path which may be different from the filesystem structure
+ * @return the item selector
+ * @throws LayoutException if the path is not valid for the given repository layout
+ */
+ ItemSelector toItemSelector( String requestPath ) throws LayoutException;
+
/**
* <p>
* Tests the path to see if it conforms to the expectations of a metadata request.
diff --git a/archiva-modules/archiva-maven/archiva-maven-repository/src/main/java/org/apache/archiva/repository/maven/content/ManagedDefaultRepositoryContent.java b/archiva-modules/archiva-maven/archiva-maven-repository/src/main/java/org/apache/archiva/repository/maven/content/ManagedDefaultRepositoryContent.java
index 734174732..b66207dd8 100644
--- a/archiva-modules/archiva-maven/archiva-maven-repository/src/main/java/org/apache/archiva/repository/maven/content/ManagedDefaultRepositoryContent.java
+++ b/archiva-modules/archiva-maven/archiva-maven-repository/src/main/java/org/apache/archiva/repository/maven/content/ManagedDefaultRepositoryContent.java
@@ -20,6 +20,7 @@ package org.apache.archiva.repository.maven.content;
import org.apache.archiva.common.filelock.FileLockManager;
import org.apache.archiva.common.utils.FileUtils;
+import org.apache.archiva.common.utils.VersionUtil;
import org.apache.archiva.configuration.FileTypes;
import org.apache.archiva.metadata.maven.MavenMetadataReader;
import org.apache.archiva.metadata.repository.storage.RepositoryPathTranslator;
@@ -186,30 +187,42 @@ public class ManagedDefaultRepositoryContent
@Override
public <T extends ContentItem> T adaptItem( Class<T> clazz, ContentItem item ) throws LayoutException
{
- if (clazz.isAssignableFrom( Version.class ))
+ try
{
- if ( !item.hasCharacteristic( Version.class ) )
+ if ( clazz.isAssignableFrom( Version.class ) )
{
- item.setCharacteristic( Version.class, createVersionFromPath( item.getAsset() ) );
+ if ( !item.hasCharacteristic( Version.class ) )
+ {
+ item.setCharacteristic( Version.class, createVersionFromPath( item.getAsset( ) ) );
+ }
+ return (T) item.adapt( Version.class );
}
- return (T) item.adapt( Version.class );
- } else if ( clazz.isAssignableFrom( Project.class )) {
- if ( !item.hasCharacteristic( Project.class ) )
+ else if ( clazz.isAssignableFrom( Project.class ) )
{
- item.setCharacteristic( Project.class, createProjectFromPath( item.getAsset() ) );
+ if ( !item.hasCharacteristic( Project.class ) )
+ {
+ item.setCharacteristic( Project.class, createProjectFromPath( item.getAsset( ) ) );
+ }
+ return (T) item.adapt( Project.class );
}
- return (T) item.adapt( Project.class );
- } else if ( clazz.isAssignableFrom( Namespace.class )) {
- if ( !item.hasCharacteristic( Namespace.class ) )
+ else if ( clazz.isAssignableFrom( Namespace.class ) )
{
- item.setCharacteristic( Namespace.class, createNamespaceFromPath( item.getAsset() ) );
+ if ( !item.hasCharacteristic( Namespace.class ) )
+ {
+ item.setCharacteristic( Namespace.class, createNamespaceFromPath( item.getAsset( ) ) );
+ }
+ return (T) item.adapt( Namespace.class );
}
- return (T) item.adapt( Namespace.class );
- } else if ( clazz.isAssignableFrom( Artifact.class )) {
- if (!item.hasCharacteristic( Artifact.class )) {
- item.setCharacteristic( Artifact.class, createArtifactFromPath( item.getAsset( ) ) );
+ else if ( clazz.isAssignableFrom( Artifact.class ) )
+ {
+ if ( !item.hasCharacteristic( Artifact.class ) )
+ {
+ item.setCharacteristic( Artifact.class, createArtifactFromPath( item.getAsset( ) ) );
+ }
+ return (T) item.adapt( Artifact.class );
}
- return (T) item.adapt( Artifact.class );
+ } catch (LayoutRuntimeException e) {
+ throw new LayoutException( e.getMessage( ), e );
}
throw new LayoutException( "Could not convert item to class " + clazz);
}
@@ -593,6 +606,7 @@ public class ManagedDefaultRepositoryContent
}
}
+
private DataItem getDataItemFromPath( final StorageAsset artifactPath )
{
final String contentType = getContentType( artifactPath );
@@ -644,13 +658,13 @@ public class ManagedDefaultRepositoryContent
private ArtifactType artifactType = BaseArtifactTypes.MAIN;
}
- private ArtifactInfo getArtifactInfoFromPath( String genericVersion, StorageAsset path )
+ private ArtifactInfo getArtifactInfoFromPath( final String genericVersion, final StorageAsset path )
{
final ArtifactInfo info = new ArtifactInfo( );
info.asset = path;
info.id = path.getParent( ).getParent( ).getName( );
final String fileName = path.getName( );
- if ( genericVersion.endsWith( "-" + SNAPSHOT ) )
+ if ( VersionUtil.isGenericSnapshot( genericVersion ) )
{
String baseVersion = StringUtils.substringBeforeLast( genericVersion, "-" + SNAPSHOT );
String prefix = info.id + "-" + baseVersion + "-";
@@ -722,7 +736,7 @@ public class ManagedDefaultRepositoryContent
else
{
String prefix = info.id + "-" + genericVersion;
- if ( fileName.startsWith( prefix ) )
+ if ( fileName.startsWith( prefix + "-") )
{
info.version = genericVersion;
String classPostfix = StringUtils.removeStart( fileName, prefix );
@@ -737,6 +751,24 @@ public class ManagedDefaultRepositoryContent
info.classifier = "";
info.remainder = classPostfix;
}
+ } else if (fileName.startsWith(prefix + ".")) {
+ info.version = genericVersion;
+ info.remainder = StringUtils.removeStart( fileName, prefix );
+ info.classifier = "";
+ } else if (fileName.startsWith(info.id+"-")) {
+ String postFix = StringUtils.removeStart( fileName, info.id + "-" );
+ String versionPart = StringUtils.substringBefore( postFix, "." );
+ if (VersionUtil.isVersion(versionPart)) {
+ info.version = versionPart;
+ info.remainder = StringUtils.removeStart( postFix, versionPart );
+ info.classifier = "";
+ } else {
+ info.version = "";
+ info.classifier = "";
+ int dotPos = fileName.indexOf( "." );
+ info.remainder = fileName.substring( dotPos );
+ }
+
}
else
{
@@ -747,10 +779,10 @@ public class ManagedDefaultRepositoryContent
else
{
info.id = fileName;
+ info.version = "";
}
log.debug( "Artifact does not match the version pattern {}", path );
info.artifactType = BaseArtifactTypes.UNKNOWN;
- info.version = "";
info.classifier = "";
info.remainder = StringUtils.substringAfterLast( fileName, "." );
}
@@ -1454,16 +1486,40 @@ public class ManagedDefaultRepositoryContent
@Override
public ContentItem toItem( String path ) throws LayoutException
{
+
StorageAsset asset = getRepository( ).getAsset( path );
- if ( asset.isLeaf( ) )
- {
- ItemSelector selector = getPathParser( ).toItemSelector( path );
- return getItem( selector );
- }
- else
- {
- return getItemFromPath( asset );
+ ContentItem item = getItemFromPath( asset );
+ if (item instanceof DataItem) {
+ Artifact artifact = adaptItem( Artifact.class, item );
+ if (asset.getParent()==null) {
+ throw new LayoutException( "Path too short for maven artifact "+path );
+ }
+ String version = asset.getParent( ).getName( );
+ if (asset.getParent().getParent()==null) {
+ throw new LayoutException( "Path too short for maven artifact " + path );
+ }
+ String project = item.getAsset( ).getParent( ).getParent( ).getName( );
+ DataItem dataItem = (DataItem) item;
+ if (StringUtils.isEmpty( dataItem.getExtension())) {
+ throw new LayoutException( "Missing type on maven artifact" );
+ }
+ if (!project.equals(artifact.getId())) {
+ throw new LayoutException( "The maven artifact id "+artifact.getId() +" does not match the project id: " + project);
+ }
+ boolean versionIsGenericSnapshot = VersionUtil.isGenericSnapshot( version );
+ boolean artifactVersionIsSnapshot = VersionUtil.isSnapshot( artifact.getArtifactVersion() );
+ if ( versionIsGenericSnapshot && !artifactVersionIsSnapshot ) {
+ throw new LayoutException( "The maven artifact has no snapshot version in snapshot directory " + dataItem );
+ }
+ if ( !versionIsGenericSnapshot && artifactVersionIsSnapshot) {
+ throw new LayoutException( "The maven artifact version " + artifact.getArtifactVersion() + " is a snapshot version but inside a non snapshot directory " + version );
+ }
+ if ( !versionIsGenericSnapshot && !version.equals( artifact.getArtifactVersion() ) )
+ {
+ throw new LayoutException( "The maven artifact version " + artifact.getArtifactVersion() + " does not match the version directory " + version );
+ }
}
+ return item;
}
@Override
diff --git a/archiva-modules/archiva-maven/archiva-maven-repository/src/main/java/org/apache/archiva/repository/maven/content/MavenRepositoryRequestInfo.java b/archiva-modules/archiva-maven/archiva-maven-repository/src/main/java/org/apache/archiva/repository/maven/content/MavenRepositoryRequestInfo.java
index 08afdcfbe..3a6145567 100644
--- a/archiva-modules/archiva-maven/archiva-maven-repository/src/main/java/org/apache/archiva/repository/maven/content/MavenRepositoryRequestInfo.java
+++ b/archiva-modules/archiva-maven/archiva-maven-repository/src/main/java/org/apache/archiva/repository/maven/content/MavenRepositoryRequestInfo.java
@@ -20,6 +20,7 @@ package org.apache.archiva.repository.maven.content;
import org.apache.archiva.model.ArtifactReference;
import org.apache.archiva.repository.*;
+import org.apache.archiva.repository.content.ItemSelector;
import org.apache.archiva.repository.content.PathParser;
import org.apache.archiva.repository.features.RepositoryFeature;
import org.apache.archiva.repository.metadata.base.MetadataTools;
@@ -82,6 +83,12 @@ public class MavenRepositoryRequestInfo implements RepositoryRequestInfo
}
}
+ @Override
+ public ItemSelector toItemSelector( String requestPath ) throws LayoutException
+ {
+ return repository.getContent( ).toItemSelector( requestPath );
+ }
+
/**
* <p>
* Tests the path to see if it conforms to the expectations of a metadata request.
@@ -275,12 +282,18 @@ public class MavenRepositoryRequestInfo implements RepositoryRequestInfo
* Default layout is the only layout that can contain maven-metadata.xml files, and
* if the managedRepository is layout legacy, this request would never occur.
*/
- return requestedPath;
+ if (requestedPath.startsWith( "/" )) {
+ return requestedPath;
+ } else
+ {
+ return "/"+requestedPath;
+ }
}
+
+
// Treat as an artifact reference.
- ArtifactReference ref = toArtifactReference( referencedResource );
- String adjustedPath = repository.getContent().toPath( ref );
+ String adjustedPath = repository.getContent( ).toPath( repository.getContent( ).toItem( requestedPath ) );
return adjustedPath + supportfile;
}
diff --git a/archiva-modules/archiva-maven/archiva-maven-repository/src/main/java/org/apache/archiva/repository/maven/metadata/storage/Maven2RepositoryStorage.java b/archiva-modules/archiva-maven/archiva-maven-repository/src/main/java/org/apache/archiva/repository/maven/metadata/storage/Maven2RepositoryStorage.java
index 51dec603f..e1c61aad2 100644
--- a/archiva-modules/archiva-maven/archiva-maven-repository/src/main/java/org/apache/archiva/repository/maven/metadata/storage/Maven2RepositoryStorage.java
+++ b/archiva-modules/archiva-maven/archiva-maven-repository/src/main/java/org/apache/archiva/repository/maven/metadata/storage/Maven2RepositoryStorage.java
@@ -644,6 +644,98 @@ public class Maven2RepositoryStorage
}
}
+ @Override
+ public ItemSelector applyServerSideRelocation(ManagedRepository managedRepository, ItemSelector artifactSelector)
+ throws ProxyDownloadException {
+ if ("pom".equals(artifactSelector.getType())) {
+ return artifactSelector;
+ }
+
+ // Build the artifact POM reference
+ BaseRepositoryContentLayout layout;
+ try
+ {
+ layout = managedRepository.getContent( ).getLayout( BaseRepositoryContentLayout.class );
+ }
+ catch ( LayoutException e )
+ {
+ throw new ProxyDownloadException( "Could not set layout " + e.getMessage( ), new HashMap<>( ) );
+ }
+
+ RepositoryType repositoryType = managedRepository.getType();
+ if (!proxyRegistry.hasHandler(repositoryType)) {
+ throw new ProxyDownloadException("No proxy handler found for repository type " + repositoryType, new HashMap<>());
+ }
+
+
+
+ ItemSelector selector = ArchivaItemSelector.builder( )
+ .withNamespace( artifactSelector.getNamespace( ) )
+ .withProjectId( artifactSelector.getArtifactId( ) )
+ .withArtifactId( artifactSelector.getArtifactId( ) )
+ .withVersion( artifactSelector.getVersion( ) )
+ .withArtifactVersion( artifactSelector.getVersion( ) )
+ .withType( "pom" ).build( );
+
+ Artifact pom = layout.getArtifact( selector );
+
+ RepositoryProxyHandler proxyHandler = proxyRegistry.getHandler(repositoryType).get(0);
+
+ // Get the artifact POM from proxied repositories if needed
+ proxyHandler.fetchFromProxies(managedRepository, pom);
+
+ // Open and read the POM from the managed repo
+
+ if (!pom.exists()) {
+ return artifactSelector;
+ }
+
+ try {
+ // MavenXpp3Reader leaves the file open, so we need to close it ourselves.
+
+ Model model;
+ try (Reader reader = Channels.newReader(pom.getAsset().getReadChannel(), Charset.defaultCharset().name())) {
+ model = MAVEN_XPP_3_READER.read(reader);
+ }
+
+ DistributionManagement dist = model.getDistributionManagement();
+ if (dist != null) {
+ Relocation relocation = dist.getRelocation();
+ if (relocation != null) {
+ ArchivaItemSelector.Builder relocatedBuilder = ArchivaItemSelector.builder( );
+ // artifact is relocated : update the repositoryPath
+ if (relocation.getGroupId() != null) {
+ relocatedBuilder.withNamespace( relocation.getGroupId( ) );
+ } else {
+ relocatedBuilder.withNamespace( artifactSelector.getNamespace( ) );
+ }
+ if (relocation.getArtifactId() != null) {
+ relocatedBuilder.withArtifactId( relocation.getArtifactId( ) );
+ } else {
+ relocatedBuilder.withArtifactId( artifactSelector.getArtifactId( ) );
+ }
+ if (relocation.getVersion() != null)
+ {
+ relocatedBuilder.withVersion( relocation.getVersion( ) );
+ } else {
+ relocatedBuilder.withVersion( artifactSelector.getVersion( ) );
+ }
+ return relocatedBuilder.withArtifactVersion( artifactSelector.getArtifactVersion( ) )
+ .withClassifier( artifactSelector.getClassifier( ) )
+ .withType( artifactSelector.getType( ) )
+ .withProjectId( artifactSelector.getProjectId( ) )
+ .withExtension( artifactSelector.getExtension( ) )
+ .build( );
+ }
+ }
+ } catch (IOException e) {
+ // Unable to read POM : ignore.
+ } catch (XmlPullParserException e) {
+ // Invalid POM : ignore
+ }
+ return artifactSelector;
+ }
+
@Override
public String getFilePath(String requestPath, org.apache.archiva.repository.ManagedRepository managedRepository) {
diff --git a/archiva-modules/archiva-maven/archiva-maven-repository/src/test/java/org/apache/archiva/repository/maven/content/ManagedDefaultRepositoryContentTest.java b/archiva-modules/archiva-maven/archiva-maven-repository/src/test/java/org/apache/archiva/repository/maven/content/ManagedDefaultRepositoryContentTest.java
index 532997b46..d86e75930 100644
--- a/archiva-modules/archiva-maven/archiva-maven-repository/src/test/java/org/apache/archiva/repository/maven/content/ManagedDefaultRepositoryContentTest.java
+++ b/archiva-modules/archiva-maven/archiva-maven-repository/src/test/java/org/apache/archiva/repository/maven/content/ManagedDefaultRepositoryContentTest.java
@@ -1014,7 +1014,7 @@ public class ManagedDefaultRepositoryContentTest
path = "/org/apache/maven/shared/maven-downloader/1.1/maven-downloader-1.1.jar";
item = repoContent.toItem( path );
assertNotNull( item );
- assertTrue( item instanceof Artifact );
+ assertTrue( item instanceof DataItem );
}
diff --git a/archiva-modules/archiva-maven/archiva-maven-repository/src/test/java/org/apache/archiva/repository/maven/content/MavenRepositoryRequestInfoTest.java b/archiva-modules/archiva-maven/archiva-maven-repository/src/test/java/org/apache/archiva/repository/maven/content/MavenRepositoryRequestInfoTest.java
index 6e8fe08b5..7317e57f3 100644
--- a/archiva-modules/archiva-maven/archiva-maven-repository/src/test/java/org/apache/archiva/repository/maven/content/MavenRepositoryRequestInfoTest.java
+++ b/archiva-modules/archiva-maven/archiva-maven-repository/src/test/java/org/apache/archiva/repository/maven/content/MavenRepositoryRequestInfoTest.java
@@ -72,6 +72,9 @@ public class MavenRepositoryRequestInfoTest
@Inject
FileLockManager fileLockManager;
+ @Inject
+ MavenContentHelper mavenContentHelper;
+
private MavenRepositoryRequestInfo repoRequest;
@@ -109,6 +112,8 @@ public class MavenRepositoryRequestInfoTest
ManagedDefaultRepositoryContent repoContent = new ManagedDefaultRepositoryContent(repository, artifactMappingProviders, fileTypes, fileLockManager);
//repoContent = (ManagedRepositoryContent) lookup( ManagedRepositoryContent.class, "default" );
repository.setContent(repoContent);
+ repoContent.setMavenContentHelper( mavenContentHelper );
+
repoRequest = new MavenRepositoryRequestInfo(repository);
}
@@ -430,7 +435,7 @@ public class MavenRepositoryRequestInfoTest
ManagedRepositoryContent repository = createManagedRepo( "default" );
// Test (artifact) default to default - dual extension
- assertEquals( "org/project/example-presentation/3.2/example-presentation-3.2.xml.zip",
+ assertEquals( "/org/project/example-presentation/3.2/example-presentation-3.2.xml.zip",
repoRequest.toNativePath( "org/project/example-presentation/3.2/example-presentation-3.2.xml.zip") );
}
@@ -442,7 +447,7 @@ public class MavenRepositoryRequestInfoTest
ManagedRepositoryContent repository = createManagedRepo( "default" );
// Test (metadata) default to default
- assertEquals( "org/apache/derby/derby/10.2.2.0/maven-metadata.xml.sha1",
+ assertEquals( "/org/apache/derby/derby/10.2.2.0/maven-metadata.xml.sha1",
repoRequest.toNativePath( "org/apache/derby/derby/10.2.2.0/maven-metadata.xml.sha1") );
}
diff --git a/archiva-modules/archiva-web/archiva-security/src/test/java/org/apache/archiva/security/mock/MockBeanServices.java b/archiva-modules/archiva-web/archiva-security/src/test/java/org/apache/archiva/security/mock/MockBeanServices.java
index 9fb1184c6..edb686bff 100644
--- a/archiva-modules/archiva-web/archiva-security/src/test/java/org/apache/archiva/security/mock/MockBeanServices.java
+++ b/archiva-modules/archiva-web/archiva-security/src/test/java/org/apache/archiva/security/mock/MockBeanServices.java
@@ -31,6 +31,7 @@ import org.apache.archiva.components.taskqueue.TaskQueueException;
import org.apache.archiva.repository.ManagedRepositoryContent;
import org.apache.archiva.repository.ManagedRepository;
import org.apache.archiva.metadata.audit.RepositoryListener;
+import org.apache.archiva.repository.content.ItemSelector;
import org.apache.archiva.scheduler.repository.model.RepositoryArchivaTaskScheduler;
import org.apache.archiva.scheduler.repository.model.RepositoryTask;
import org.apache.archiva.xml.XMLException;
@@ -108,6 +109,12 @@ public class MockBeanServices
}
+ @Override
+ public ItemSelector applyServerSideRelocation( ManagedRepository managedRepository, ItemSelector selector ) throws ProxyDownloadException
+ {
+ return null;
+ }
+
@Override
public void deleteArtifact( MetadataRepository metadataRepository, String repositoryId, String namespace,
diff --git a/archiva-modules/archiva-web/archiva-webdav/src/main/java/org/apache/archiva/webdav/ArchivaDavResourceFactory.java b/archiva-modules/archiva-web/archiva-webdav/src/main/java/org/apache/archiva/webdav/ArchivaDavResourceFactory.java
index 8528b658c..b83dcdb61 100644
--- a/archiva-modules/archiva-web/archiva-webdav/src/main/java/org/apache/archiva/webdav/ArchivaDavResourceFactory.java
+++ b/archiva-modules/archiva-web/archiva-webdav/src/main/java/org/apache/archiva/webdav/ArchivaDavResourceFactory.java
@@ -68,6 +68,7 @@ import org.apache.archiva.repository.RepositoryRegistry;
import org.apache.archiva.repository.RepositoryRequestInfo;
import org.apache.archiva.repository.content.Artifact;
import org.apache.archiva.repository.content.ContentItem;
+import org.apache.archiva.repository.content.ItemSelector;
import org.apache.archiva.repository.storage.fs.FilesystemStorage;
import org.apache.archiva.repository.storage.StorageAsset;
import org.apache.archiva.metadata.audit.AuditListener;
@@ -791,22 +792,23 @@ public class ArchivaDavResourceFactory
try
{
// Get the artifact reference in a layout neutral way.
- ArtifactReference artifact = repositoryRequestInfo.toArtifactReference( path );
+// ArtifactReference artifact = repositoryRequestInfo.toArtifactReference( path );
+ ItemSelector selector = repositoryRequestInfo.toItemSelector( path );
- if ( artifact != null )
+ if ( selector != null )
{
String repositoryLayout = managedRepository.getLayout();
RepositoryStorage repositoryStorage =
this.applicationContext.getBean( "repositoryStorage#" + repositoryLayout, RepositoryStorage.class );
- repositoryStorage.applyServerSideRelocation( managedRepository, artifact );
+ selector = repositoryStorage.applyServerSideRelocation( managedRepository, selector );
- StorageAsset proxiedFile = proxyHandler.fetchFromProxies( managedRepository, artifact );
+ StorageAsset proxiedFile = proxyHandler.fetchFromProxies( managedRepository, selector );
- resource.setPath( managedRepository.getContent().toPath( artifact ) );
+ resource.setPath( managedRepository.getContent().toPath( selector ) );
- log.debug( "Proxied artifact '{}:{}:{}'", artifact.getGroupId(), artifact.getArtifactId(),
- artifact.getVersion() );
+ log.debug( "Proxied artifact '{}:{}:{}:{}'", selector.getNamespace(), selector.getArtifactId(),
+ selector.getVersion(), selector.getArtifactVersion() );
return ( proxiedFile != null );
}
diff --git a/archiva-modules/metadata/metadata-repository-api/src/main/java/org/apache/archiva/metadata/repository/storage/RepositoryStorage.java b/archiva-modules/metadata/metadata-repository-api/src/main/java/org/apache/archiva/metadata/repository/storage/RepositoryStorage.java
index 6559be1c6..e56311506 100644
--- a/archiva-modules/metadata/metadata-repository-api/src/main/java/org/apache/archiva/metadata/repository/storage/RepositoryStorage.java
+++ b/archiva-modules/metadata/metadata-repository-api/src/main/java/org/apache/archiva/metadata/repository/storage/RepositoryStorage.java
@@ -27,6 +27,7 @@ import org.apache.archiva.model.ArtifactReference;
import org.apache.archiva.policies.ProxyDownloadException;
import org.apache.archiva.repository.ManagedRepositoryContent;
import org.apache.archiva.repository.ManagedRepository;
+import org.apache.archiva.repository.content.ItemSelector;
import org.apache.archiva.xml.XMLException;
import java.io.IOException;
@@ -75,6 +76,21 @@ public interface RepositoryStorage
throws ProxyDownloadException;
/**
+ * A relocation capable client will request the POM prior to the artifact, and will then read meta-data and do
+ * client side relocation. A simplier client (like maven 1) will only request the artifact and not use the
+ * metadatas.
+ * <p>
+ * For such clients, archiva does server-side relocation by reading itself the &lt;relocation&gt; element in
+ * metadatas and serving the expected artifact.
+ * @param managedRepository the used managed repository
+ * @param artifact the artifact reference
+ * @throws org.apache.archiva.policies.ProxyDownloadException
+ */
+ ItemSelector applyServerSideRelocation( ManagedRepository managedRepository, ItemSelector selector )
+ throws ProxyDownloadException;
+
+
+ /**
* add an other method to evaluate real path as when receiving -SNAPSHOT (for maven storage)
* request redirect to the last build
* @param requestPath the web uri request
diff --git a/archiva-modules/plugins/metadata-store-cassandra/src/test/java/org/apache/archiva/metadata/repository/cassandra/MockRepositoryStorage.java b/archiva-modules/plugins/metadata-store-cassandra/src/test/java/org/apache/archiva/metadata/repository/cassandra/MockRepositoryStorage.java
index ab520236f..d320ecbb4 100644
--- a/archiva-modules/plugins/metadata-store-cassandra/src/test/java/org/apache/archiva/metadata/repository/cassandra/MockRepositoryStorage.java
+++ b/archiva-modules/plugins/metadata-store-cassandra/src/test/java/org/apache/archiva/metadata/repository/cassandra/MockRepositoryStorage.java
@@ -37,6 +37,7 @@ import org.apache.archiva.policies.ProxyDownloadException;
import org.apache.archiva.repository.ManagedRepositoryContent;
import org.apache.archiva.repository.ManagedRepository;
import org.apache.archiva.metadata.audit.RepositoryListener;
+import org.apache.archiva.repository.content.ItemSelector;
import org.apache.archiva.xml.XMLException;
import java.io.IOException;
@@ -113,6 +114,12 @@ public class MockRepositoryStorage
}
@Override
+ public ItemSelector applyServerSideRelocation( ManagedRepository managedRepository, ItemSelector selector ) throws ProxyDownloadException
+ {
+ return null;
+ }
+
+ @Override
public String getFilePath( String requestPath, org.apache.archiva.repository.ManagedRepository managedRepository )
{
return null;