mirror of
https://github.com/apache/archiva.git
synced 2025-02-08 02:59:43 +00:00
Fixing metadata removal. Adding mocks for verification.
- Prevent redundant removals for same artifacts - Adding metadata removal for each file removal - Adding mock verifications for metadata removal in unit tests
This commit is contained in:
parent
9964f9d5ea
commit
1601657702
@ -37,9 +37,11 @@
|
|||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.FilenameFilter;
|
import java.io.FilenameFilter;
|
||||||
import java.util.Collection;
|
import java.io.IOException;
|
||||||
import java.util.List;
|
import java.nio.file.Files;
|
||||||
import java.util.Set;
|
import java.nio.file.Path;
|
||||||
|
import java.util.*;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Base class for all repository purge tasks.
|
* Base class for all repository purge tasks.
|
||||||
@ -67,6 +69,116 @@ public AbstractRepositoryPurge( ManagedRepositoryContent repository, RepositoryS
|
|||||||
this.listeners = listeners;
|
this.listeners = listeners;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* We have to track namespace, project, project version, artifact version and classifier
|
||||||
|
* There is no metadata class that contains all these properties.
|
||||||
|
*/
|
||||||
|
class ArtifactInfo
|
||||||
|
{
|
||||||
|
final String namespace;
|
||||||
|
final String name;
|
||||||
|
final String projectVersion;
|
||||||
|
String version;
|
||||||
|
String classifier;
|
||||||
|
|
||||||
|
ArtifactInfo( String namespace, String name, String projectVersion, String version )
|
||||||
|
{
|
||||||
|
this.namespace = namespace;
|
||||||
|
this.name = name;
|
||||||
|
this.projectVersion = projectVersion;
|
||||||
|
this.version = version;
|
||||||
|
}
|
||||||
|
|
||||||
|
ArtifactInfo( String namespace, String name, String projectVersion )
|
||||||
|
{
|
||||||
|
this.namespace = namespace;
|
||||||
|
this.name = name;
|
||||||
|
this.projectVersion = projectVersion;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Creates a info object without version and classifier
|
||||||
|
*/
|
||||||
|
ArtifactInfo projectVersionLevel( )
|
||||||
|
{
|
||||||
|
return new ArtifactInfo( this.namespace, this.name, this.projectVersion );
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setClassifier( String classifier )
|
||||||
|
{
|
||||||
|
this.classifier = classifier;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getNamespace( )
|
||||||
|
{
|
||||||
|
return namespace;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getName( )
|
||||||
|
{
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getProjectVersion( )
|
||||||
|
{
|
||||||
|
return projectVersion;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getVersion( )
|
||||||
|
{
|
||||||
|
return version;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getClassifier( )
|
||||||
|
{
|
||||||
|
return classifier;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean hasClassifier( )
|
||||||
|
{
|
||||||
|
return classifier != null && !"".equals( classifier );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals( Object o )
|
||||||
|
{
|
||||||
|
if ( this == o ) return true;
|
||||||
|
if ( o == null || getClass( ) != o.getClass( ) ) return false;
|
||||||
|
|
||||||
|
ArtifactInfo that = (ArtifactInfo) o;
|
||||||
|
|
||||||
|
if ( !namespace.equals( that.namespace ) ) return false;
|
||||||
|
if ( !name.equals( that.name ) ) return false;
|
||||||
|
if ( !projectVersion.equals( that.projectVersion ) ) return false;
|
||||||
|
if ( !( version != null ? version.equals( that.version ) : that.version == null ) ) return false;
|
||||||
|
return classifier != null ? classifier.equals( that.classifier ) : that.classifier == null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode( )
|
||||||
|
{
|
||||||
|
int result = namespace.hashCode( );
|
||||||
|
result = 31 * result + name.hashCode( );
|
||||||
|
result = 31 * result + projectVersion.hashCode( );
|
||||||
|
result = 31 * result + ( version != null ? version.hashCode( ) : 0 );
|
||||||
|
result = 31 * result + ( classifier != null ? classifier.hashCode( ) : 0 );
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString( )
|
||||||
|
{
|
||||||
|
final StringBuilder sb = new StringBuilder( "ArtifactInfo{" );
|
||||||
|
sb.append( "namespace='" ).append( namespace ).append( '\'' );
|
||||||
|
sb.append( ", name='" ).append( name ).append( '\'' );
|
||||||
|
sb.append( ", projectVersion='" ).append( projectVersion ).append( '\'' );
|
||||||
|
sb.append( ", version='" ).append( version ).append( '\'' );
|
||||||
|
sb.append( ", classifier='" ).append( classifier ).append( '\'' );
|
||||||
|
sb.append( '}' );
|
||||||
|
return sb.toString( );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Purge the repo. Update db and index of removed artifacts.
|
* Purge the repo. Update db and index of removed artifacts.
|
||||||
*
|
*
|
||||||
@ -77,19 +189,44 @@ protected void purge( Set<ArtifactReference> references )
|
|||||||
if ( references != null && !references.isEmpty( ) )
|
if ( references != null && !references.isEmpty( ) )
|
||||||
{
|
{
|
||||||
MetadataRepository metadataRepository = repositorySession.getRepository( );
|
MetadataRepository metadataRepository = repositorySession.getRepository( );
|
||||||
|
Map<ArtifactInfo, ArtifactMetadata> metaRemovalList = new HashMap<>( );
|
||||||
|
Map<String, Collection<ArtifactMetadata>> metaResolved = new HashMap<>( );
|
||||||
for ( ArtifactReference reference : references )
|
for ( ArtifactReference reference : references )
|
||||||
{
|
{
|
||||||
File artifactFile = repository.toFile( reference );
|
String baseVersion = VersionUtil.getBaseVersion( reference.getVersion( ) );
|
||||||
|
// Needed for tracking in the hashmap
|
||||||
|
String metaBaseId = reference.getGroupId( ) + "/" + reference.getArtifactId( ) + "/" + baseVersion;
|
||||||
|
|
||||||
|
if ( !metaResolved.containsKey( metaBaseId ) )
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
metaResolved.put( metaBaseId, metadataRepository.getArtifacts( repository.getId( ), reference.getGroupId( ),
|
||||||
|
reference.getArtifactId( ), baseVersion ) );
|
||||||
|
}
|
||||||
|
catch ( MetadataResolutionException e )
|
||||||
|
{
|
||||||
|
log.error( "Error during metadata retrieval {}: {}", metaBaseId, e.getMessage( ) );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Path artifactFile = repository.toFile( reference ).toPath( );
|
||||||
|
|
||||||
for ( RepositoryListener listener : listeners )
|
for ( RepositoryListener listener : listeners )
|
||||||
{
|
{
|
||||||
listener.deleteArtifact( metadataRepository, repository.getId( ), reference.getGroupId( ),
|
listener.deleteArtifact( metadataRepository, repository.getId( ), reference.getGroupId( ),
|
||||||
reference.getArtifactId( ), reference.getVersion( ),
|
reference.getArtifactId( ), reference.getVersion( ),
|
||||||
artifactFile.getName() );
|
artifactFile.getFileName( ).toString( ) );
|
||||||
|
}
|
||||||
|
try
|
||||||
|
{
|
||||||
|
Files.delete( artifactFile );
|
||||||
|
log.debug( "File deleted: {}", artifactFile.toAbsolutePath( ) );
|
||||||
|
}
|
||||||
|
catch ( IOException e )
|
||||||
|
{
|
||||||
|
log.error( "Could not delete file {}: {}", artifactFile.toAbsolutePath( ), e.getMessage( ), e );
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: this needs to be logged
|
|
||||||
artifactFile.delete();
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
repository.deleteArtifact( reference );
|
repository.deleteArtifact( reference );
|
||||||
@ -99,84 +236,141 @@ protected void purge( Set<ArtifactReference> references )
|
|||||||
log.warn( "skip error deleting artifact {}: {}", reference, e.getMessage( ) );
|
log.warn( "skip error deleting artifact {}: {}", reference, e.getMessage( ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
metadataRepository.removeProjectVersion( repository.getId(), reference.getGroupId(),
|
|
||||||
reference.getArtifactId(), reference.getVersion() );
|
|
||||||
}
|
|
||||||
catch ( MetadataRepositoryException e )
|
|
||||||
{
|
|
||||||
log.warn( "skip error removeProjectVersion artifact {}: {}", reference, e.getMessage() );
|
|
||||||
}
|
|
||||||
|
|
||||||
boolean snapshotVersion = VersionUtil.isSnapshot( reference.getVersion( ) );
|
boolean snapshotVersion = VersionUtil.isSnapshot( reference.getVersion( ) );
|
||||||
|
|
||||||
try
|
|
||||||
{
|
// If this is a snapshot we have to search for artifacts with the same version. And remove all of them.
|
||||||
if ( snapshotVersion )
|
if ( snapshotVersion )
|
||||||
{
|
{
|
||||||
String baseVersion = VersionUtil.getBaseVersion( reference.getVersion() );
|
|
||||||
Collection<ArtifactMetadata> artifacts =
|
Collection<ArtifactMetadata> artifacts =
|
||||||
metadataRepository.getArtifacts( repository.getId(), reference.getGroupId(),
|
metaResolved.get( metaBaseId );
|
||||||
reference.getArtifactId(), baseVersion );
|
|
||||||
if ( artifacts != null )
|
if ( artifacts != null )
|
||||||
{
|
{
|
||||||
// cleanup snapshots metadata
|
// cleanup snapshots metadata
|
||||||
for ( ArtifactMetadata artifactMetadata : artifacts )
|
for ( ArtifactMetadata artifactMetadata : artifacts )
|
||||||
{
|
{
|
||||||
|
// Artifact metadata and reference version should match.
|
||||||
// TODO: mismatch between artifact (snapshot) version and project (base) version here
|
|
||||||
if ( artifactMetadata.getVersion( ).equals( reference.getVersion( ) ) )
|
if ( artifactMetadata.getVersion( ).equals( reference.getVersion( ) ) )
|
||||||
{
|
{
|
||||||
|
ArtifactInfo info = new ArtifactInfo( artifactMetadata.getNamespace( ), artifactMetadata.getProject( ), artifactMetadata.getProjectVersion( ), artifactMetadata.getVersion( ) );
|
||||||
if ( StringUtils.isNotBlank( reference.getClassifier( ) ) )
|
if ( StringUtils.isNotBlank( reference.getClassifier( ) ) )
|
||||||
{
|
{
|
||||||
|
info.setClassifier( reference.getClassifier( ) );
|
||||||
|
metaRemovalList.put( info, artifactMetadata );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// metadataRepository.removeArtifact( artifactMetadata, baseVersion );
|
||||||
|
metaRemovalList.put( info, artifactMetadata );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else // otherwise we delete the artifact version
|
||||||
|
{
|
||||||
|
ArtifactInfo info = new ArtifactInfo( reference.getGroupId( ), reference.getArtifactId( ), baseVersion, reference.getVersion( ) );
|
||||||
|
for ( ArtifactMetadata metadata : metaResolved.get( metaBaseId ) )
|
||||||
|
{
|
||||||
|
metaRemovalList.put( info, metadata );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
triggerAuditEvent( repository.getRepository( ).getId( ), ArtifactReference.toKey( reference ),
|
||||||
|
AuditEvent.PURGE_ARTIFACT );
|
||||||
|
purgeSupportFiles( artifactFile );
|
||||||
|
}
|
||||||
|
purgeMetadata( metadataRepository, metaRemovalList );
|
||||||
|
repositorySession.save( );
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Purges the metadata. First removes the artifacts. After that empty versions will be removed.
|
||||||
|
*/
|
||||||
|
private void purgeMetadata( MetadataRepository metadataRepository, Map<ArtifactInfo, ArtifactMetadata> dataList )
|
||||||
|
{
|
||||||
|
Set<ArtifactInfo> projectLevelMetadata = new HashSet<>( );
|
||||||
|
for ( Map.Entry<ArtifactInfo, ArtifactMetadata> infoEntry : dataList.entrySet( ) )
|
||||||
|
{
|
||||||
|
ArtifactInfo info = infoEntry.getKey( );
|
||||||
|
try
|
||||||
|
{
|
||||||
|
removeArtifact( metadataRepository, info, infoEntry.getValue( ) );
|
||||||
|
log.debug( "Removed artifact from MetadataRepository {}", info );
|
||||||
|
}
|
||||||
|
catch ( MetadataRepositoryException e )
|
||||||
|
{
|
||||||
|
log.error( "Could not remove artifact from MetadataRepository {}: {}", info, e.getMessage( ), e );
|
||||||
|
}
|
||||||
|
projectLevelMetadata.add( info.projectVersionLevel( ) );
|
||||||
|
}
|
||||||
|
metadataRepository.save( );
|
||||||
|
Collection<ArtifactMetadata> artifacts = null;
|
||||||
|
// Get remaining artifacts and remove project if empty
|
||||||
|
for ( ArtifactInfo info : projectLevelMetadata )
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
artifacts = metadataRepository.getArtifacts( repository.getId( ), info.getNamespace( ), info.getName( ),
|
||||||
|
info.getProjectVersion( ) );
|
||||||
|
if ( artifacts.size( ) == 0 )
|
||||||
|
{
|
||||||
|
metadataRepository.removeProjectVersion( repository.getId( ), info.getNamespace( ),
|
||||||
|
info.getName( ), info.getProjectVersion( ) );
|
||||||
|
log.debug( "Removed project version from MetadataRepository {}", info );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch ( MetadataResolutionException | MetadataRepositoryException e )
|
||||||
|
{
|
||||||
|
log.error( "Could not remove project version from MetadataRepository {}: {}", info, e.getMessage( ), e );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
metadataRepository.save( );
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Removes the artifact from the metadataRepository. If a classifier is set, the facet will be removed.
|
||||||
|
*/
|
||||||
|
private void removeArtifact( MetadataRepository metadataRepository, ArtifactInfo artifactInfo, ArtifactMetadata artifactMetadata ) throws MetadataRepositoryException
|
||||||
|
{
|
||||||
|
if ( artifactInfo.hasClassifier( ) )
|
||||||
|
{
|
||||||
// cleanup facet which contains classifier information
|
// cleanup facet which contains classifier information
|
||||||
MavenArtifactFacet mavenArtifactFacet =
|
MavenArtifactFacet mavenArtifactFacet =
|
||||||
(MavenArtifactFacet) artifactMetadata.getFacet(
|
(MavenArtifactFacet) artifactMetadata.getFacet(
|
||||||
MavenArtifactFacet.FACET_ID );
|
MavenArtifactFacet.FACET_ID );
|
||||||
|
|
||||||
if ( StringUtils.equals( reference.getClassifier(),
|
if ( StringUtils.equals( artifactInfo.classifier,
|
||||||
mavenArtifactFacet.getClassifier( ) ) )
|
mavenArtifactFacet.getClassifier( ) ) )
|
||||||
{
|
{
|
||||||
artifactMetadata.removeFacet( MavenArtifactFacet.FACET_ID );
|
artifactMetadata.removeFacet( MavenArtifactFacet.FACET_ID );
|
||||||
String groupId = reference.getGroupId(), artifactId =
|
String groupId = artifactInfo.getNamespace( ), artifactId =
|
||||||
reference.getArtifactId(),
|
artifactInfo.getName( ),
|
||||||
version = reference.getVersion();
|
version = artifactInfo.getProjectVersion( );
|
||||||
MavenArtifactFacet mavenArtifactFacetToCompare = new MavenArtifactFacet( );
|
MavenArtifactFacet mavenArtifactFacetToCompare = new MavenArtifactFacet( );
|
||||||
mavenArtifactFacetToCompare.setClassifier( reference.getClassifier() );
|
mavenArtifactFacetToCompare.setClassifier( artifactInfo.getClassifier( ) );
|
||||||
metadataRepository.removeArtifact( repository.getId( ), groupId, artifactId,
|
metadataRepository.removeArtifact( repository.getId( ), groupId, artifactId,
|
||||||
version, mavenArtifactFacetToCompare );
|
version, mavenArtifactFacetToCompare );
|
||||||
metadataRepository.save( );
|
metadataRepository.save( );
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
metadataRepository.removeArtifact( artifactMetadata, VersionUtil.getBaseVersion(
|
metadataRepository.removeArtifact( artifactMetadata, artifactInfo.getProjectVersion( ) );
|
||||||
reference.getVersion() ) );
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
private void deleteSilently(Path path) {
|
||||||
}
|
try
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch ( MetadataResolutionException e )
|
|
||||||
{
|
{
|
||||||
log.warn( "skip error deleting metadata {}: {}", reference, e.getMessage() );
|
Files.deleteIfExists( path );
|
||||||
|
triggerAuditEvent( repository.getRepository( ).getId( ), path.toString(), AuditEvent.PURGE_FILE );
|
||||||
}
|
}
|
||||||
catch ( MetadataRepositoryException e )
|
catch ( IOException e )
|
||||||
{
|
{
|
||||||
log.warn( "skip error deleting metadata {}: {}", reference, e.getMessage() );
|
log.error("Error occured during file deletion {}: {} ",path,e.getMessage(), e);
|
||||||
}
|
|
||||||
|
|
||||||
repositorySession.save();
|
|
||||||
|
|
||||||
triggerAuditEvent( repository.getRepository().getId(), ArtifactReference.toKey( reference ),
|
|
||||||
AuditEvent.PURGE_ARTIFACT );
|
|
||||||
purgeSupportFiles( artifactFile );
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -190,29 +384,28 @@ protected void purge( Set<ArtifactReference> references )
|
|||||||
*
|
*
|
||||||
* @param artifactFile the file to base off of.
|
* @param artifactFile the file to base off of.
|
||||||
*/
|
*/
|
||||||
private void purgeSupportFiles( File artifactFile )
|
private void purgeSupportFiles( Path artifactFile )
|
||||||
{
|
{
|
||||||
File parentDir = artifactFile.getParentFile();
|
Path parentDir = artifactFile.getParent();
|
||||||
|
|
||||||
if ( !parentDir.exists() )
|
if ( !Files.exists(parentDir) )
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
FilenameFilter filter = new ArtifactFilenameFilter( artifactFile.getName() );
|
final String artifactName = artifactFile.getFileName().toString();
|
||||||
|
|
||||||
File[] files = parentDir.listFiles( filter );
|
try
|
||||||
|
{
|
||||||
|
Files.find(parentDir, 3,
|
||||||
|
( path, basicFileAttributes ) -> path.getFileName().toString().startsWith(artifactName)
|
||||||
|
&& Files.isRegularFile( path ) ).forEach( this::deleteSilently );
|
||||||
|
}
|
||||||
|
catch ( IOException e )
|
||||||
|
{
|
||||||
|
log.error("Purge of support files failed {}: {}", artifactFile, e.getMessage(), e);
|
||||||
|
}
|
||||||
|
|
||||||
for ( File file : files )
|
|
||||||
{
|
|
||||||
if ( file.exists() && file.isFile() )
|
|
||||||
{
|
|
||||||
String fileName = file.getName();
|
|
||||||
file.delete();
|
|
||||||
// TODO: log that it was deleted
|
|
||||||
triggerAuditEvent( repository.getRepository().getId(), fileName, AuditEvent.PURGE_FILE );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void triggerAuditEvent( String repoId, String resource, String action )
|
private void triggerAuditEvent( String repoId, String resource, String action )
|
||||||
|
@ -1,49 +0,0 @@
|
|||||||
package org.apache.archiva.consumers.core.repository;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* 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.FilenameFilter;
|
|
||||||
import java.io.File;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Filename filter for getting all the files related to a specific artifact.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
public class ArtifactFilenameFilter
|
|
||||||
implements FilenameFilter
|
|
||||||
{
|
|
||||||
private String filename;
|
|
||||||
|
|
||||||
public ArtifactFilenameFilter()
|
|
||||||
{
|
|
||||||
// no op
|
|
||||||
}
|
|
||||||
|
|
||||||
public ArtifactFilenameFilter( String filename )
|
|
||||||
{
|
|
||||||
this.filename = filename;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean accept( File dir, String name )
|
|
||||||
{
|
|
||||||
return ( name.startsWith( filename ) );
|
|
||||||
}
|
|
||||||
}
|
|
@ -23,6 +23,7 @@
|
|||||||
import org.apache.archiva.admin.model.beans.ManagedRepository;
|
import org.apache.archiva.admin.model.beans.ManagedRepository;
|
||||||
import org.apache.archiva.admin.model.managed.ManagedRepositoryAdmin;
|
import org.apache.archiva.admin.model.managed.ManagedRepositoryAdmin;
|
||||||
import org.apache.archiva.metadata.repository.MetadataRepository;
|
import org.apache.archiva.metadata.repository.MetadataRepository;
|
||||||
|
import org.apache.archiva.metadata.repository.MetadataRepositoryException;
|
||||||
import org.apache.archiva.metadata.repository.RepositorySession;
|
import org.apache.archiva.metadata.repository.RepositorySession;
|
||||||
import org.apache.archiva.repository.events.RepositoryListener;
|
import org.apache.archiva.repository.events.RepositoryListener;
|
||||||
import org.apache.archiva.common.utils.VersionComparator;
|
import org.apache.archiva.common.utils.VersionComparator;
|
||||||
@ -159,13 +160,14 @@ public void process( String path )
|
|||||||
versionRef.setVersion( artifactRef.getVersion() );
|
versionRef.setVersion( artifactRef.getVersion() );
|
||||||
repository.deleteVersion( versionRef );
|
repository.deleteVersion( versionRef );
|
||||||
|
|
||||||
// FIXME: looks incomplete, might not delete related metadata?
|
|
||||||
for ( RepositoryListener listener : listeners )
|
for ( RepositoryListener listener : listeners )
|
||||||
{
|
{
|
||||||
listener.deleteArtifact( metadataRepository, repository.getId(), artifactRef.getGroupId(),
|
listener.deleteArtifact( metadataRepository, repository.getId(), artifactRef.getGroupId(),
|
||||||
artifactRef.getArtifactId(), artifactRef.getVersion(),
|
artifactRef.getArtifactId(), artifactRef.getVersion(),
|
||||||
artifactFile.getName() );
|
artifactFile.getName() );
|
||||||
}
|
}
|
||||||
|
metadataRepository.removeProjectVersion( repository.getId(), artifactRef.getGroupId(),
|
||||||
|
artifactRef.getArtifactId(), artifactRef.getVersion());
|
||||||
|
|
||||||
needsMetadataUpdate = true;
|
needsMetadataUpdate = true;
|
||||||
}
|
}
|
||||||
@ -186,6 +188,10 @@ public void process( String path )
|
|||||||
{
|
{
|
||||||
throw new RepositoryPurgeException( e.getMessage(), e );
|
throw new RepositoryPurgeException( e.getMessage(), e );
|
||||||
}
|
}
|
||||||
|
catch ( MetadataRepositoryException e )
|
||||||
|
{
|
||||||
|
log.error("Could not remove metadata during cleanup of released snapshots of {}", path, e);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void updateMetadata( ArtifactReference artifact )
|
private void updateMetadata( ArtifactReference artifact )
|
||||||
|
@ -33,12 +33,7 @@
|
|||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.text.ParseException;
|
import java.text.ParseException;
|
||||||
import java.text.SimpleDateFormat;
|
import java.text.SimpleDateFormat;
|
||||||
import java.util.ArrayList;
|
import java.util.*;
|
||||||
import java.util.Calendar;
|
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.Date;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Set;
|
|
||||||
import java.util.regex.Matcher;
|
import java.util.regex.Matcher;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -99,6 +94,7 @@ public void process( String path )
|
|||||||
|
|
||||||
int countToPurge = versions.size() - retentionCount;
|
int countToPurge = versions.size() - retentionCount;
|
||||||
|
|
||||||
|
Set<ArtifactReference> artifactsToDelete = new HashSet<>();
|
||||||
for ( String version : versions )
|
for ( String version : versions )
|
||||||
{
|
{
|
||||||
if ( countToPurge-- <= 0 )
|
if ( countToPurge-- <= 0 )
|
||||||
@ -117,7 +113,7 @@ public void process( String path )
|
|||||||
{
|
{
|
||||||
if ( newArtifactFile.lastModified() < olderThanThisDate.getTimeInMillis() )
|
if ( newArtifactFile.lastModified() < olderThanThisDate.getTimeInMillis() )
|
||||||
{
|
{
|
||||||
doPurgeAllRelated( newArtifactReference );
|
artifactsToDelete.addAll(repository.getRelatedArtifacts(newArtifactReference) );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Is this a timestamp snapshot "1.0-20070822.123456-42" ?
|
// Is this a timestamp snapshot "1.0-20070822.123456-42" ?
|
||||||
@ -127,10 +123,11 @@ else if ( VersionUtil.isUniqueSnapshot( newArtifactReference.getVersion() ) )
|
|||||||
|
|
||||||
if ( timestampCal.getTimeInMillis() < olderThanThisDate.getTimeInMillis() )
|
if ( timestampCal.getTimeInMillis() < olderThanThisDate.getTimeInMillis() )
|
||||||
{
|
{
|
||||||
doPurgeAllRelated( newArtifactReference );
|
artifactsToDelete.addAll( repository.getRelatedArtifacts(newArtifactReference));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
purge(artifactsToDelete);
|
||||||
}
|
}
|
||||||
catch ( ContentNotFoundException e )
|
catch ( ContentNotFoundException e )
|
||||||
{
|
{
|
||||||
@ -175,17 +172,4 @@ private Calendar uniqueSnapshotToCalendar( String version )
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void doPurgeAllRelated( ArtifactReference reference )
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
Set<ArtifactReference> related = repository.getRelatedArtifacts( reference );
|
|
||||||
purge( related );
|
|
||||||
}
|
|
||||||
catch ( ContentNotFoundException e )
|
|
||||||
{
|
|
||||||
// Nothing to do here - it means the repository would have been constructed incorrectly
|
|
||||||
log.debug( e.getMessage(), e );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -102,9 +102,6 @@ public class RepositoryPurgeConsumer
|
|||||||
@Autowired(required = false)
|
@Autowired(required = false)
|
||||||
private List<RepositoryListener> listeners = Collections.emptyList();
|
private List<RepositoryListener> listeners = Collections.emptyList();
|
||||||
|
|
||||||
/**
|
|
||||||
* FIXME: this could be multiple implementations and needs to be configured.
|
|
||||||
*/
|
|
||||||
@Inject
|
@Inject
|
||||||
private RepositorySessionFactory repositorySessionFactory;
|
private RepositorySessionFactory repositorySessionFactory;
|
||||||
|
|
||||||
@ -189,7 +186,6 @@ public void processFile( String path )
|
|||||||
{
|
{
|
||||||
cleanUp.process( path );
|
cleanUp.process( path );
|
||||||
}
|
}
|
||||||
|
|
||||||
repoPurge.process( path );
|
repoPurge.process( path );
|
||||||
}
|
}
|
||||||
catch ( RepositoryPurgeException rpe )
|
catch ( RepositoryPurgeException rpe )
|
||||||
|
@ -32,6 +32,7 @@
|
|||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
|
import java.util.HashSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
@ -78,21 +79,22 @@ public void process( String path )
|
|||||||
|
|
||||||
if ( retentionCount > versions.size() )
|
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.
|
// Done. nothing to do here. skip it.
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
int countToPurge = versions.size() - retentionCount;
|
int countToPurge = versions.size() - retentionCount;
|
||||||
|
Set<ArtifactReference> artifactsToDelete = new HashSet<>();
|
||||||
for ( String version : versions )
|
for ( String version : versions )
|
||||||
{
|
{
|
||||||
if ( countToPurge-- <= 0 )
|
if ( countToPurge-- <= 0 )
|
||||||
{
|
{
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
artifactsToDelete.addAll(repository.getRelatedArtifacts( getNewArtifactReference( artifact, version) ));
|
||||||
doPurgeAllRelated( artifact, version );
|
|
||||||
}
|
}
|
||||||
|
purge(artifactsToDelete);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch ( LayoutException le )
|
catch ( LayoutException le )
|
||||||
@ -101,12 +103,14 @@ public void process( String path )
|
|||||||
}
|
}
|
||||||
catch ( ContentNotFoundException e )
|
catch ( ContentNotFoundException e )
|
||||||
{
|
{
|
||||||
// Nothing to do here.
|
log.error("Repostory artifact not found {}", path);
|
||||||
// TODO: Log this condition?
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void doPurgeAllRelated( ArtifactReference reference, String version )
|
/*
|
||||||
|
* Returns a new artifact reference with different version
|
||||||
|
*/
|
||||||
|
private ArtifactReference getNewArtifactReference( ArtifactReference reference, String version )
|
||||||
throws LayoutException
|
throws LayoutException
|
||||||
{
|
{
|
||||||
ArtifactReference artifact = new ArtifactReference();
|
ArtifactReference artifact = new ArtifactReference();
|
||||||
@ -115,16 +119,7 @@ private void doPurgeAllRelated( ArtifactReference reference, String version )
|
|||||||
artifact.setVersion( version );
|
artifact.setVersion( version );
|
||||||
artifact.setClassifier( reference.getClassifier() );
|
artifact.setClassifier( reference.getClassifier() );
|
||||||
artifact.setType( reference.getType() );
|
artifact.setType( reference.getType() );
|
||||||
|
return artifact;
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
Set<ArtifactReference> related = repository.getRelatedArtifacts( artifact );
|
|
||||||
purge( related );
|
|
||||||
}
|
|
||||||
catch ( ContentNotFoundException e )
|
|
||||||
{
|
|
||||||
// Nothing to do here.
|
|
||||||
// TODO: Log this?
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -21,8 +21,11 @@
|
|||||||
|
|
||||||
import org.apache.archiva.admin.model.beans.ManagedRepository;
|
import org.apache.archiva.admin.model.beans.ManagedRepository;
|
||||||
import org.apache.archiva.common.plexusbridge.PlexusSisuBridge;
|
import org.apache.archiva.common.plexusbridge.PlexusSisuBridge;
|
||||||
|
import org.apache.archiva.common.utils.VersionUtil;
|
||||||
|
import org.apache.archiva.metadata.model.ArtifactMetadata;
|
||||||
import org.apache.archiva.metadata.repository.MetadataRepository;
|
import org.apache.archiva.metadata.repository.MetadataRepository;
|
||||||
import org.apache.archiva.metadata.repository.RepositorySession;
|
import org.apache.archiva.metadata.repository.RepositorySession;
|
||||||
|
import org.apache.archiva.metadata.repository.storage.maven2.Maven2RepositoryPathTranslator;
|
||||||
import org.apache.archiva.repository.ManagedRepositoryContent;
|
import org.apache.archiva.repository.ManagedRepositoryContent;
|
||||||
import org.apache.archiva.repository.events.RepositoryListener;
|
import org.apache.archiva.repository.events.RepositoryListener;
|
||||||
import org.apache.archiva.test.utils.ArchivaSpringJUnit4ClassRunner;
|
import org.apache.archiva.test.utils.ArchivaSpringJUnit4ClassRunner;
|
||||||
@ -41,6 +44,14 @@
|
|||||||
|
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.nio.file.Files;
|
||||||
|
import java.nio.file.LinkOption;
|
||||||
|
import java.nio.file.Path;
|
||||||
|
import java.nio.file.Paths;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
import static org.junit.Assert.assertFalse;
|
import static org.junit.Assert.assertFalse;
|
||||||
import static org.junit.Assert.assertTrue;
|
import static org.junit.Assert.assertTrue;
|
||||||
@ -193,6 +204,10 @@ protected File getTestRepoRoot()
|
|||||||
return new File( "target/test-" + getName() + "/" + TEST_REPO_ID );
|
return new File( "target/test-" + getName() + "/" + TEST_REPO_ID );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected Path getTestRepoRootPath() {
|
||||||
|
return Paths.get("target/test-"+getName()+"/"+TEST_REPO_ID);
|
||||||
|
}
|
||||||
|
|
||||||
protected String prepareTestRepos()
|
protected String prepareTestRepos()
|
||||||
throws Exception
|
throws Exception
|
||||||
{
|
{
|
||||||
@ -217,4 +232,14 @@ public String getName()
|
|||||||
{
|
{
|
||||||
return StringUtils.substringAfterLast( getClass().getName(), "." );
|
return StringUtils.substringAfterLast( getClass().getName(), "." );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected List<ArtifactMetadata> getArtifactMetadataFromDir( String repoId, String projectName, Path repoDir, Path vDir ) throws IOException
|
||||||
|
{
|
||||||
|
Maven2RepositoryPathTranslator translator = new Maven2RepositoryPathTranslator( new ArrayList<>( ) );
|
||||||
|
return Files.find(vDir, 1,
|
||||||
|
(path, basicFileAttributes) -> basicFileAttributes.isRegularFile() && path.getFileName().toString().startsWith(projectName))
|
||||||
|
.map( path ->
|
||||||
|
translator.getArtifactForPath( repoId, repoDir.relativize( path ).toString() )
|
||||||
|
).collect( Collectors.toList());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -22,6 +22,8 @@
|
|||||||
import org.apache.archiva.admin.model.managed.ManagedRepositoryAdmin;
|
import org.apache.archiva.admin.model.managed.ManagedRepositoryAdmin;
|
||||||
import org.apache.archiva.admin.repository.managed.DefaultManagedRepositoryAdmin;
|
import org.apache.archiva.admin.repository.managed.DefaultManagedRepositoryAdmin;
|
||||||
import org.apache.archiva.configuration.ArchivaConfiguration;
|
import org.apache.archiva.configuration.ArchivaConfiguration;
|
||||||
|
import org.apache.archiva.metadata.model.ArtifactMetadata;
|
||||||
|
import org.apache.archiva.metadata.model.MetadataFacet;
|
||||||
import org.apache.archiva.repository.RepositoryContentFactory;
|
import org.apache.archiva.repository.RepositoryContentFactory;
|
||||||
import org.apache.archiva.repository.events.RepositoryListener;
|
import org.apache.archiva.repository.events.RepositoryListener;
|
||||||
import org.apache.archiva.repository.metadata.MetadataTools;
|
import org.apache.archiva.repository.metadata.MetadataTools;
|
||||||
@ -30,15 +32,21 @@
|
|||||||
import org.easymock.EasyMock;
|
import org.easymock.EasyMock;
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
import org.mockito.ArgumentCaptor;
|
||||||
import org.springframework.test.context.ContextConfiguration;
|
import org.springframework.test.context.ContextConfiguration;
|
||||||
|
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.nio.charset.Charset;
|
import java.nio.charset.Charset;
|
||||||
|
import java.nio.file.Path;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
|
import java.util.HashSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
import static org.junit.Assert.assertTrue;
|
import static org.junit.Assert.assertTrue;
|
||||||
|
import static org.mockito.Matchers.eq;
|
||||||
|
import static org.mockito.Mockito.*;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -92,7 +100,7 @@ public void setUp()
|
|||||||
removeMavenIndexes();
|
removeMavenIndexes();
|
||||||
}
|
}
|
||||||
|
|
||||||
//@Test
|
@Test
|
||||||
public void testReleasedSnapshotsExistsInSameRepo()
|
public void testReleasedSnapshotsExistsInSameRepo()
|
||||||
throws Exception
|
throws Exception
|
||||||
{
|
{
|
||||||
@ -101,17 +109,35 @@ public void testReleasedSnapshotsExistsInSameRepo()
|
|||||||
getRepoConfiguration( TEST_REPO_ID, TEST_REPO_NAME ), false, null );
|
getRepoConfiguration( TEST_REPO_ID, TEST_REPO_NAME ), false, null );
|
||||||
|
|
||||||
String repoRoot = prepareTestRepos();
|
String repoRoot = prepareTestRepos();
|
||||||
|
String projectNs = "org.apache.maven.plugins";
|
||||||
|
String projectPath = projectNs.replaceAll("\\.","/");
|
||||||
|
String projectName = "maven-plugin-plugin";
|
||||||
|
String projectVersion = "2.3-SNAPSHOT";
|
||||||
|
String projectRoot = repoRoot + "/" + projectPath+"/"+projectName;
|
||||||
|
Path repo = getTestRepoRootPath();
|
||||||
|
Path vDir = repo.resolve(projectPath).resolve(projectName).resolve(projectVersion);
|
||||||
|
Set<String> deletedVersions = new HashSet<>();
|
||||||
|
deletedVersions.add("2.3-SNAPSHOT");
|
||||||
|
|
||||||
// test listeners for the correct artifacts
|
// test listeners for the correct artifacts
|
||||||
listener.deleteArtifact( metadataRepository, getRepository().getId(), "org.apache.maven.plugins",
|
listener.deleteArtifact( metadataRepository, getRepository().getId(), "org.apache.maven.plugins",
|
||||||
"maven-plugin-plugin", "2.3-SNAPSHOT", "maven-plugin-plugin-2.3-SNAPSHOT.jar" );
|
"maven-plugin-plugin", "2.3-SNAPSHOT", "maven-plugin-plugin-2.3-SNAPSHOT.jar" );
|
||||||
listenerControl.replay();
|
listenerControl.replay();
|
||||||
|
|
||||||
|
// Provide the metadata list
|
||||||
|
List<ArtifactMetadata> ml = getArtifactMetadataFromDir(TEST_REPO_ID , projectName, repo.getParent(), vDir );
|
||||||
|
when(metadataRepository.getArtifacts(TEST_REPO_ID, projectNs,
|
||||||
|
projectName, projectVersion)).thenReturn(ml);
|
||||||
|
|
||||||
|
|
||||||
repoPurge.process( PATH_TO_RELEASED_SNAPSHOT_IN_SAME_REPO );
|
repoPurge.process( PATH_TO_RELEASED_SNAPSHOT_IN_SAME_REPO );
|
||||||
|
|
||||||
listenerControl.verify();
|
listenerControl.verify();
|
||||||
|
|
||||||
String projectRoot = repoRoot + "/org/apache/maven/plugins/maven-plugin-plugin";
|
// Verify the metadataRepository invocations
|
||||||
|
// complete snapshot version removal for released
|
||||||
|
verify(metadataRepository, times(1)).removeProjectVersion(eq(TEST_REPO_ID), eq(projectNs), eq(projectName), eq(projectVersion));
|
||||||
|
verify(metadataRepository, never()).removeProjectVersion(eq(TEST_REPO_ID), eq(projectNs), eq(projectName), eq("2.3"));
|
||||||
|
|
||||||
// check if the snapshot was removed
|
// check if the snapshot was removed
|
||||||
assertDeleted( projectRoot + "/2.3-SNAPSHOT" );
|
assertDeleted( projectRoot + "/2.3-SNAPSHOT" );
|
||||||
@ -149,7 +175,7 @@ public void testReleasedSnapshotsExistsInSameRepo()
|
|||||||
XMLAssert.assertXpathEvaluatesTo( "20070315032817", "//metadata/versioning/lastUpdated", metadataXml );
|
XMLAssert.assertXpathEvaluatesTo( "20070315032817", "//metadata/versioning/lastUpdated", metadataXml );
|
||||||
}
|
}
|
||||||
|
|
||||||
//@Test
|
@Test
|
||||||
public void testNonArtifactFile()
|
public void testNonArtifactFile()
|
||||||
throws Exception
|
throws Exception
|
||||||
{
|
{
|
||||||
@ -179,7 +205,7 @@ public void testNonArtifactFile()
|
|||||||
assertTrue( file.exists() );
|
assertTrue( file.exists() );
|
||||||
}
|
}
|
||||||
|
|
||||||
//@Test
|
@Test
|
||||||
public void testReleasedSnapshotsExistsInDifferentRepo()
|
public void testReleasedSnapshotsExistsInDifferentRepo()
|
||||||
throws Exception
|
throws Exception
|
||||||
{
|
{
|
||||||
@ -192,6 +218,18 @@ public void testReleasedSnapshotsExistsInDifferentRepo()
|
|||||||
getRepoConfiguration( RELEASES_TEST_REPO_ID, RELEASES_TEST_REPO_NAME ), false, null );
|
getRepoConfiguration( RELEASES_TEST_REPO_ID, RELEASES_TEST_REPO_NAME ), false, null );
|
||||||
|
|
||||||
String repoRoot = prepareTestRepos();
|
String repoRoot = prepareTestRepos();
|
||||||
|
String projectNs = "org.apache.archiva";
|
||||||
|
String projectPath = projectNs.replaceAll("\\.","/");
|
||||||
|
String projectName = "released-artifact-in-diff-repo";
|
||||||
|
String projectVersion = "1.0-SNAPSHOT";
|
||||||
|
String releaseVersion = "1.0";
|
||||||
|
String projectRoot = repoRoot + "/" + projectPath+"/"+projectName;
|
||||||
|
Path repo = getTestRepoRootPath();
|
||||||
|
Path vDir = repo.resolve(projectPath).resolve(projectName).resolve(projectVersion);
|
||||||
|
Path releaseDir = repo.getParent().resolve(RELEASES_TEST_REPO_ID).resolve(projectPath).resolve(projectName).resolve(releaseVersion);
|
||||||
|
Set<String> deletedVersions = new HashSet<>();
|
||||||
|
deletedVersions.add("1.0-SNAPSHOT");
|
||||||
|
|
||||||
|
|
||||||
// test listeners for the correct artifacts
|
// test listeners for the correct artifacts
|
||||||
listener.deleteArtifact( metadataRepository, getRepository().getId(), "org.apache.archiva",
|
listener.deleteArtifact( metadataRepository, getRepository().getId(), "org.apache.archiva",
|
||||||
@ -199,11 +237,25 @@ public void testReleasedSnapshotsExistsInDifferentRepo()
|
|||||||
"released-artifact-in-diff-repo-1.0-SNAPSHOT.jar" );
|
"released-artifact-in-diff-repo-1.0-SNAPSHOT.jar" );
|
||||||
listenerControl.replay();
|
listenerControl.replay();
|
||||||
|
|
||||||
|
// Provide the metadata list
|
||||||
|
List<ArtifactMetadata> ml = getArtifactMetadataFromDir(TEST_REPO_ID , projectName, repo.getParent(), vDir );
|
||||||
|
when(metadataRepository.getArtifacts(TEST_REPO_ID, projectNs,
|
||||||
|
projectName, projectVersion)).thenReturn(ml);
|
||||||
|
|
||||||
|
List<ArtifactMetadata> ml2 = getArtifactMetadataFromDir(RELEASES_TEST_REPO_ID , projectName, repo.getParent(), releaseDir );
|
||||||
|
when(metadataRepository.getArtifacts(RELEASES_TEST_REPO_ID, projectNs,
|
||||||
|
projectName, releaseVersion)).thenReturn(ml2);
|
||||||
|
|
||||||
|
|
||||||
repoPurge.process( PATH_TO_RELEASED_SNAPSHOT_IN_DIFF_REPO );
|
repoPurge.process( PATH_TO_RELEASED_SNAPSHOT_IN_DIFF_REPO );
|
||||||
|
|
||||||
listenerControl.verify();
|
listenerControl.verify();
|
||||||
|
|
||||||
String projectRoot = repoRoot + "/org/apache/archiva/released-artifact-in-diff-repo";
|
// Verify the metadataRepository invocations
|
||||||
|
// Complete version removal for cleanup
|
||||||
|
verify(metadataRepository, times(1)).removeProjectVersion(eq(TEST_REPO_ID), eq(projectNs), eq(projectName), eq(projectVersion));
|
||||||
|
verify(metadataRepository, never()).removeProjectVersion(eq(RELEASES_TEST_REPO_ID), eq(projectNs), eq(projectName), eq(releaseVersion));
|
||||||
|
|
||||||
|
|
||||||
// check if the snapshot was removed
|
// check if the snapshot was removed
|
||||||
assertDeleted( projectRoot + "/1.0-SNAPSHOT" );
|
assertDeleted( projectRoot + "/1.0-SNAPSHOT" );
|
||||||
@ -241,15 +293,44 @@ public void testHigherSnapshotExistsInSameRepo()
|
|||||||
getRepoConfiguration( TEST_REPO_ID, TEST_REPO_NAME ), false, null );
|
getRepoConfiguration( TEST_REPO_ID, TEST_REPO_NAME ), false, null );
|
||||||
|
|
||||||
String repoRoot = prepareTestRepos();
|
String repoRoot = prepareTestRepos();
|
||||||
|
String projectNs = "org.apache.maven.plugins";
|
||||||
|
String projectPath = projectNs.replaceAll("\\.","/");
|
||||||
|
String projectName = "maven-source-plugin";
|
||||||
|
String projectVersion = "2.0.2";
|
||||||
|
String projectRoot = repoRoot + "/" + projectPath+"/"+projectName;
|
||||||
|
Path repo = getTestRepoRootPath();
|
||||||
|
Path vDir = repo.resolve(projectPath).resolve(projectName).resolve(projectVersion);
|
||||||
|
Path vDir2 = repo.resolve(projectPath).resolve(projectName).resolve("2.0.3-SNAPSHOT");
|
||||||
|
Path vDir3 = repo.resolve(projectPath).resolve(projectName).resolve("2.0.4-SNAPSHOT");
|
||||||
|
|
||||||
// test listeners for the correct artifacts - no deletions
|
// test listeners for the correct artifacts - no deletions
|
||||||
listenerControl.replay();
|
listenerControl.replay();
|
||||||
|
|
||||||
|
// Provide the metadata list
|
||||||
|
List<ArtifactMetadata> ml = getArtifactMetadataFromDir(TEST_REPO_ID , projectName, repo.getParent(), vDir );
|
||||||
|
when(metadataRepository.getArtifacts(TEST_REPO_ID, projectNs,
|
||||||
|
projectName, projectVersion)).thenReturn(ml);
|
||||||
|
List<ArtifactMetadata> m2 = getArtifactMetadataFromDir(TEST_REPO_ID , projectName, repo.getParent(), vDir2 );
|
||||||
|
when(metadataRepository.getArtifacts(TEST_REPO_ID, projectNs,
|
||||||
|
projectName, "2.0.3-SNAPSHOT")).thenReturn(ml);
|
||||||
|
List<ArtifactMetadata> m3 = getArtifactMetadataFromDir(TEST_REPO_ID , projectName, repo.getParent(), vDir3 );
|
||||||
|
when(metadataRepository.getArtifacts(TEST_REPO_ID, projectNs,
|
||||||
|
projectName, "2.0.4-SNAPSHOT")).thenReturn(ml);
|
||||||
|
|
||||||
|
|
||||||
repoPurge.process( CleanupReleasedSnapshotsRepositoryPurgeTest.PATH_TO_HIGHER_SNAPSHOT_EXISTS_IN_SAME_REPO );
|
repoPurge.process( CleanupReleasedSnapshotsRepositoryPurgeTest.PATH_TO_HIGHER_SNAPSHOT_EXISTS_IN_SAME_REPO );
|
||||||
|
|
||||||
listenerControl.verify();
|
listenerControl.verify();
|
||||||
|
|
||||||
String projectRoot = repoRoot + "/org/apache/maven/plugins/maven-source-plugin";
|
// Verify the metadataRepository invocations
|
||||||
|
// No removal
|
||||||
|
verify(metadataRepository, never()).removeProjectVersion(eq(TEST_REPO_ID), eq(projectNs), eq(projectName), eq(projectVersion));
|
||||||
|
verify(metadataRepository, never()).removeProjectVersion(eq(TEST_REPO_ID), eq(projectNs), eq(projectName), eq("2.0.3-SNAPSHOT"));
|
||||||
|
verify(metadataRepository, never()).removeProjectVersion(eq(TEST_REPO_ID), eq(projectNs), eq(projectName), eq("2.0.4-SNAPSHOT"));
|
||||||
|
verify(metadataRepository, never()).removeArtifact(any(ArtifactMetadata.class), any(String.class));
|
||||||
|
verify(metadataRepository, never()).removeArtifact(any(String.class), any(String.class), any(String.class), any(String.class), any( MetadataFacet.class));
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// check if the snapshot was not removed
|
// check if the snapshot was not removed
|
||||||
assertExists( projectRoot + "/2.0.3-SNAPSHOT" );
|
assertExists( projectRoot + "/2.0.3-SNAPSHOT" );
|
||||||
|
@ -20,15 +20,25 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
|
import java.nio.file.Path;
|
||||||
import java.text.SimpleDateFormat;
|
import java.text.SimpleDateFormat;
|
||||||
import java.util.Calendar;
|
import java.util.Calendar;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
|
import java.util.HashSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
import org.apache.archiva.admin.model.beans.ManagedRepository;
|
import org.apache.archiva.admin.model.beans.ManagedRepository;
|
||||||
|
import org.apache.archiva.metadata.model.ArtifactMetadata;
|
||||||
import org.apache.archiva.repository.events.RepositoryListener;
|
import org.apache.archiva.repository.events.RepositoryListener;
|
||||||
import org.apache.commons.lang.time.DateUtils;
|
import org.apache.commons.lang.time.DateUtils;
|
||||||
import org.junit.After;
|
import org.junit.After;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
import org.mockito.ArgumentCaptor;
|
||||||
|
|
||||||
|
import static org.junit.Assert.assertTrue;
|
||||||
|
import static org.mockito.Matchers.eq;
|
||||||
|
import static org.mockito.Mockito.*;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*/
|
*/
|
||||||
@ -66,10 +76,18 @@ public void testByLastModified()
|
|||||||
Collections.singletonList( listener ) );
|
Collections.singletonList( listener ) );
|
||||||
|
|
||||||
String repoRoot = prepareTestRepos();
|
String repoRoot = prepareTestRepos();
|
||||||
|
String projectNs = "org.apache.maven.plugins";
|
||||||
|
String projectPath = projectNs.replaceAll("\\.","/");
|
||||||
|
String projectName = "maven-install-plugin";
|
||||||
|
String projectVersion = "2.2-SNAPSHOT";
|
||||||
|
String projectRoot = repoRoot + "/" + projectPath+"/"+projectName;
|
||||||
|
Path repo = getTestRepoRootPath();
|
||||||
|
Path vDir = repo.resolve(projectPath).resolve(projectName).resolve(projectVersion);
|
||||||
|
Set<String> deletedVersions = new HashSet<>();
|
||||||
|
deletedVersions.add("2.2-SNAPSHOT");
|
||||||
|
deletedVersions.add("2.2-20061118.060401-2");
|
||||||
|
|
||||||
String projectRoot = repoRoot + "/org/apache/maven/plugins/maven-install-plugin";
|
setLastModified( projectRoot + "/" + projectVersion + "/", OLD_TIMESTAMP );
|
||||||
|
|
||||||
setLastModified( projectRoot + "/2.2-SNAPSHOT/", OLD_TIMESTAMP );
|
|
||||||
|
|
||||||
// test listeners for the correct artifacts
|
// test listeners for the correct artifacts
|
||||||
listener.deleteArtifact( metadataRepository, getRepository().getId(), "org.apache.maven.plugins",
|
listener.deleteArtifact( metadataRepository, getRepository().getId(), "org.apache.maven.plugins",
|
||||||
@ -84,10 +102,26 @@ public void testByLastModified()
|
|||||||
"maven-install-plugin-2.2-20061118.060401-2.pom" );
|
"maven-install-plugin-2.2-20061118.060401-2.pom" );
|
||||||
listenerControl.replay();
|
listenerControl.replay();
|
||||||
|
|
||||||
|
// Provide the metadata list
|
||||||
|
List<ArtifactMetadata> ml = getArtifactMetadataFromDir(TEST_REPO_ID , projectName, repo.getParent(), vDir );
|
||||||
|
when(metadataRepository.getArtifacts(TEST_REPO_ID, projectNs,
|
||||||
|
projectName, projectVersion)).thenReturn(ml);
|
||||||
|
|
||||||
repoPurge.process( PATH_TO_BY_DAYS_OLD_ARTIFACT );
|
repoPurge.process( PATH_TO_BY_DAYS_OLD_ARTIFACT );
|
||||||
|
|
||||||
listenerControl.verify();
|
listenerControl.verify();
|
||||||
|
|
||||||
|
// Verify the metadataRepository invocations
|
||||||
|
verify(metadataRepository, never()).removeProjectVersion(eq(TEST_REPO_ID), eq(projectNs), eq(projectName), eq(projectVersion));
|
||||||
|
ArgumentCaptor<ArtifactMetadata> metadataArg = ArgumentCaptor.forClass(ArtifactMetadata.class);
|
||||||
|
verify(metadataRepository, times(2)).removeArtifact(metadataArg.capture(), eq(projectVersion));
|
||||||
|
List<ArtifactMetadata> metaL = metadataArg.getAllValues();
|
||||||
|
for (ArtifactMetadata meta : metaL) {
|
||||||
|
assertTrue(meta.getId().startsWith(projectName));
|
||||||
|
assertTrue(deletedVersions.contains(meta.getVersion()));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
assertDeleted( projectRoot + "/2.2-SNAPSHOT/maven-install-plugin-2.2-SNAPSHOT.jar" );
|
assertDeleted( projectRoot + "/2.2-SNAPSHOT/maven-install-plugin-2.2-SNAPSHOT.jar" );
|
||||||
assertDeleted( projectRoot + "/2.2-SNAPSHOT/maven-install-plugin-2.2-SNAPSHOT.jar.md5" );
|
assertDeleted( projectRoot + "/2.2-SNAPSHOT/maven-install-plugin-2.2-SNAPSHOT.jar.md5" );
|
||||||
assertDeleted( projectRoot + "/2.2-SNAPSHOT/maven-install-plugin-2.2-SNAPSHOT.jar.sha1" );
|
assertDeleted( projectRoot + "/2.2-SNAPSHOT/maven-install-plugin-2.2-SNAPSHOT.jar.sha1" );
|
||||||
@ -128,10 +162,17 @@ public void testOrderOfDeletion()
|
|||||||
repoConfiguration.getRetentionCount(), repositorySession, listeners );
|
repoConfiguration.getRetentionCount(), repositorySession, listeners );
|
||||||
|
|
||||||
String repoRoot = prepareTestRepos();
|
String repoRoot = prepareTestRepos();
|
||||||
|
String projectNs = "org.apache.maven.plugins";
|
||||||
|
String projectPath = projectNs.replaceAll("\\.","/");
|
||||||
|
String projectName = "maven-assembly-plugin";
|
||||||
|
String projectVersion = "1.1.2-SNAPSHOT";
|
||||||
|
String projectRoot = repoRoot + "/" + projectPath+"/"+projectName;
|
||||||
|
Path repo = getTestRepoRootPath();
|
||||||
|
Path vDir = repo.resolve(projectPath).resolve(projectName).resolve(projectVersion);
|
||||||
|
Set<String> deletedVersions = new HashSet<>();
|
||||||
|
deletedVersions.add("1.1.2-20070427.065136-1");
|
||||||
|
|
||||||
String projectRoot = repoRoot + "/org/apache/maven/plugins/maven-assembly-plugin";
|
setLastModified( projectRoot + "/" + projectVersion + "/", OLD_TIMESTAMP );
|
||||||
|
|
||||||
setLastModified( projectRoot + "/1.1.2-SNAPSHOT/", OLD_TIMESTAMP );
|
|
||||||
|
|
||||||
// test listeners for the correct artifacts
|
// test listeners for the correct artifacts
|
||||||
listener.deleteArtifact( metadataRepository, getRepository().getId(), "org.apache.maven.plugins",
|
listener.deleteArtifact( metadataRepository, getRepository().getId(), "org.apache.maven.plugins",
|
||||||
@ -142,10 +183,27 @@ public void testOrderOfDeletion()
|
|||||||
"maven-assembly-plugin-1.1.2-20070427.065136-1.pom" );
|
"maven-assembly-plugin-1.1.2-20070427.065136-1.pom" );
|
||||||
listenerControl.replay();
|
listenerControl.replay();
|
||||||
|
|
||||||
|
// Provide the metadata list
|
||||||
|
List<ArtifactMetadata> ml = getArtifactMetadataFromDir(TEST_REPO_ID , projectName, repo.getParent(), vDir );
|
||||||
|
when(metadataRepository.getArtifacts(TEST_REPO_ID, projectNs,
|
||||||
|
projectName, projectVersion)).thenReturn(ml);
|
||||||
|
|
||||||
|
|
||||||
repoPurge.process( PATH_TO_TEST_ORDER_OF_DELETION );
|
repoPurge.process( PATH_TO_TEST_ORDER_OF_DELETION );
|
||||||
|
|
||||||
listenerControl.verify();
|
listenerControl.verify();
|
||||||
|
|
||||||
|
// Verify the metadataRepository invocations
|
||||||
|
verify(metadataRepository, never()).removeProjectVersion(eq(TEST_REPO_ID), eq(projectNs), eq(projectName), eq(projectVersion));
|
||||||
|
ArgumentCaptor<ArtifactMetadata> metadataArg = ArgumentCaptor.forClass(ArtifactMetadata.class);
|
||||||
|
verify(metadataRepository, times(deletedVersions.size())).removeArtifact(metadataArg.capture(), eq(projectVersion));
|
||||||
|
List<ArtifactMetadata> metaL = metadataArg.getAllValues();
|
||||||
|
for (ArtifactMetadata meta : metaL) {
|
||||||
|
assertTrue(meta.getId().startsWith(projectName));
|
||||||
|
assertTrue(deletedVersions.contains(meta.getVersion()));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
assertDeleted( projectRoot + "/1.1.2-SNAPSHOT/maven-assembly-plugin-1.1.2-20070427.065136-1.jar" );
|
assertDeleted( projectRoot + "/1.1.2-SNAPSHOT/maven-assembly-plugin-1.1.2-20070427.065136-1.jar" );
|
||||||
assertDeleted( projectRoot + "/1.1.2-SNAPSHOT/maven-assembly-plugin-1.1.2-20070427.065136-1.jar.sha1" );
|
assertDeleted( projectRoot + "/1.1.2-SNAPSHOT/maven-assembly-plugin-1.1.2-20070427.065136-1.jar.sha1" );
|
||||||
assertDeleted( projectRoot + "/1.1.2-SNAPSHOT/maven-assembly-plugin-1.1.2-20070427.065136-1.jar.md5" );
|
assertDeleted( projectRoot + "/1.1.2-SNAPSHOT/maven-assembly-plugin-1.1.2-20070427.065136-1.jar.md5" );
|
||||||
@ -179,8 +237,18 @@ public void testMetadataDrivenSnapshots()
|
|||||||
repoConfiguration.getRetentionCount(), repositorySession, listeners );
|
repoConfiguration.getRetentionCount(), repositorySession, listeners );
|
||||||
|
|
||||||
String repoRoot = prepareTestRepos();
|
String repoRoot = prepareTestRepos();
|
||||||
|
String projectNs = "org.codehaus.plexus";
|
||||||
|
String projectPath = projectNs.replaceAll("\\.","/");
|
||||||
|
String projectName = "plexus-utils";
|
||||||
|
String projectVersion = "1.4.3-SNAPSHOT";
|
||||||
|
String projectRoot = repoRoot + "/" + projectPath+"/"+projectName;
|
||||||
|
Path repo = getTestRepoRootPath();
|
||||||
|
Path vDir = repo.resolve(projectPath).resolve(projectName).resolve(projectVersion);
|
||||||
|
Set<String> deletedVersions = new HashSet<>();
|
||||||
|
deletedVersions.add("1.4.3-20070113.163208-4");
|
||||||
|
|
||||||
String versionRoot = repoRoot + "/org/codehaus/plexus/plexus-utils/1.4.3-SNAPSHOT";
|
|
||||||
|
String versionRoot = projectRoot + "/"+ projectVersion;
|
||||||
|
|
||||||
Calendar currentDate = Calendar.getInstance( DateUtils.UTC_TIME_ZONE );
|
Calendar currentDate = Calendar.getInstance( DateUtils.UTC_TIME_ZONE );
|
||||||
setLastModified( versionRoot, currentDate.getTimeInMillis() );
|
setLastModified( versionRoot, currentDate.getTimeInMillis() );
|
||||||
@ -209,10 +277,27 @@ public void testMetadataDrivenSnapshots()
|
|||||||
"1.4.3-20070113.163208-4", "plexus-utils-1.4.3-20070113.163208-4.pom" );
|
"1.4.3-20070113.163208-4", "plexus-utils-1.4.3-20070113.163208-4.pom" );
|
||||||
listenerControl.replay();
|
listenerControl.replay();
|
||||||
|
|
||||||
|
// Provide the metadata list
|
||||||
|
List<ArtifactMetadata> ml = getArtifactMetadataFromDir(TEST_REPO_ID , projectName, repo.getParent(), vDir );
|
||||||
|
when(metadataRepository.getArtifacts(TEST_REPO_ID, projectNs,
|
||||||
|
projectName, projectVersion)).thenReturn(ml);
|
||||||
|
|
||||||
|
|
||||||
repoPurge.process( PATH_TO_BY_DAYS_OLD_METADATA_DRIVEN_ARTIFACT );
|
repoPurge.process( PATH_TO_BY_DAYS_OLD_METADATA_DRIVEN_ARTIFACT );
|
||||||
|
|
||||||
listenerControl.verify();
|
listenerControl.verify();
|
||||||
|
|
||||||
|
// Verify the metadataRepository invocations
|
||||||
|
verify(metadataRepository, never()).removeProjectVersion(eq(TEST_REPO_ID), eq(projectNs), eq(projectName), eq(projectVersion));
|
||||||
|
ArgumentCaptor<ArtifactMetadata> metadataArg = ArgumentCaptor.forClass(ArtifactMetadata.class);
|
||||||
|
verify(metadataRepository, times(deletedVersions.size())).removeArtifact(metadataArg.capture(), eq(projectVersion));
|
||||||
|
List<ArtifactMetadata> metaL = metadataArg.getAllValues();
|
||||||
|
for (ArtifactMetadata meta : metaL) {
|
||||||
|
assertTrue(meta.getId().startsWith(projectName));
|
||||||
|
assertTrue(deletedVersions.contains(meta.getVersion()));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// this should be deleted since the filename version (timestamp) is older than
|
// this should be deleted since the filename version (timestamp) is older than
|
||||||
// 100 days even if the last modified date was <100 days ago
|
// 100 days even if the last modified date was <100 days ago
|
||||||
assertDeleted( versionRoot + "/plexus-utils-1.4.3-20070113.163208-4.jar" );
|
assertDeleted( versionRoot + "/plexus-utils-1.4.3-20070113.163208-4.jar" );
|
||||||
|
@ -30,19 +30,38 @@
|
|||||||
import org.apache.archiva.configuration.FileTypes;
|
import org.apache.archiva.configuration.FileTypes;
|
||||||
import org.apache.archiva.consumers.KnownRepositoryContentConsumer;
|
import org.apache.archiva.consumers.KnownRepositoryContentConsumer;
|
||||||
import org.apache.archiva.consumers.functors.ConsumerWantsFilePredicate;
|
import org.apache.archiva.consumers.functors.ConsumerWantsFilePredicate;
|
||||||
|
import org.apache.archiva.metadata.model.ArtifactMetadata;
|
||||||
|
import org.apache.archiva.metadata.model.MetadataFacet;
|
||||||
|
import org.apache.archiva.metadata.model.facets.RepositoryProblemFacet;
|
||||||
import org.apache.archiva.mock.MockRepositorySessionFactory;
|
import org.apache.archiva.mock.MockRepositorySessionFactory;
|
||||||
import org.apache.commons.io.FileUtils;
|
import org.apache.commons.io.FileUtils;
|
||||||
import org.custommonkey.xmlunit.XMLAssert;
|
import org.custommonkey.xmlunit.XMLAssert;
|
||||||
import org.junit.After;
|
import org.junit.After;
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
import org.mockito.ArgumentCaptor;
|
||||||
import org.springframework.test.context.ContextConfiguration;
|
import org.springframework.test.context.ContextConfiguration;
|
||||||
|
import sun.awt.image.ImageWatched;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
|
import java.io.IOException;
|
||||||
import java.nio.charset.Charset;
|
import java.nio.charset.Charset;
|
||||||
|
import java.nio.file.Files;
|
||||||
|
import java.nio.file.LinkOption;
|
||||||
|
import java.nio.file.Path;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
import static com.sun.imageio.plugins.jpeg.JPEG.version;
|
||||||
import static org.junit.Assert.assertEquals;
|
import static org.junit.Assert.assertEquals;
|
||||||
import static org.junit.Assert.assertFalse;
|
import static org.junit.Assert.assertFalse;
|
||||||
|
import static org.junit.Assert.assertTrue;
|
||||||
|
import static org.mockito.Matchers.any;
|
||||||
|
import static org.mockito.Matchers.eq;
|
||||||
|
import static org.mockito.Mockito.*;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*/
|
*/
|
||||||
@ -152,10 +171,37 @@ public void testConsumerByRetentionCount()
|
|||||||
repoPurgeConsumer.beginScan( repoConfiguration, null );
|
repoPurgeConsumer.beginScan( repoConfiguration, null );
|
||||||
|
|
||||||
String repoRoot = prepareTestRepos();
|
String repoRoot = prepareTestRepos();
|
||||||
|
String projectNs = "org.jruby.plugins";
|
||||||
|
String projectPath = projectNs.replaceAll("\\.","/");
|
||||||
|
String projectName = "jruby-rake-plugin";
|
||||||
|
String projectVersion = "1.0RC1-SNAPSHOT";
|
||||||
|
String projectRoot = repoRoot + "/" + projectPath+"/"+projectName;
|
||||||
|
String versionRoot = projectRoot + "/" + projectVersion;
|
||||||
|
|
||||||
|
Path repo = getTestRepoRootPath();
|
||||||
|
Path vDir = repo.resolve(projectPath).resolve(projectName).resolve(projectVersion);
|
||||||
|
|
||||||
|
// Provide the metadata list
|
||||||
|
List<ArtifactMetadata> ml = getArtifactMetadataFromDir( TEST_REPO_ID, projectName, repo, vDir );
|
||||||
|
when(metadataRepository.getArtifacts(TEST_REPO_ID, projectNs,
|
||||||
|
projectName, projectVersion)).thenReturn(ml);
|
||||||
|
Set<String> deletedVersions = new HashSet<>();
|
||||||
|
deletedVersions.add("1.0RC1-20070504.153317-1");
|
||||||
|
deletedVersions.add("1.0RC1-20070504.160758-2");
|
||||||
|
|
||||||
repoPurgeConsumer.processFile( PATH_TO_BY_RETENTION_COUNT_ARTIFACT );
|
repoPurgeConsumer.processFile( PATH_TO_BY_RETENTION_COUNT_ARTIFACT );
|
||||||
|
|
||||||
String versionRoot = repoRoot + "/org/jruby/plugins/jruby-rake-plugin/1.0RC1-SNAPSHOT";
|
// Verify the metadataRepository invocations
|
||||||
|
verify(metadataRepository, never()).removeProjectVersion(eq(TEST_REPO_ID), eq(projectNs), eq(projectName), eq(projectVersion));
|
||||||
|
ArgumentCaptor<ArtifactMetadata> metadataArg = ArgumentCaptor.forClass(ArtifactMetadata.class);
|
||||||
|
verify(metadataRepository, times(2)).removeArtifact(metadataArg.capture(), eq(projectVersion));
|
||||||
|
List<ArtifactMetadata> metaL = metadataArg.getAllValues();
|
||||||
|
for (ArtifactMetadata meta : metaL) {
|
||||||
|
assertTrue(meta.getId().startsWith(projectName));
|
||||||
|
assertTrue(deletedVersions.contains(meta.getVersion()));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// assert if removed from repo
|
// assert if removed from repo
|
||||||
assertDeleted( versionRoot + "/jruby-rake-plugin-1.0RC1-20070504.153317-1.jar" );
|
assertDeleted( versionRoot + "/jruby-rake-plugin-1.0RC1-20070504.153317-1.jar" );
|
||||||
@ -247,12 +293,38 @@ public void testConsumerByDaysOld()
|
|||||||
repoPurgeConsumer.beginScan( repoConfiguration, null );
|
repoPurgeConsumer.beginScan( repoConfiguration, null );
|
||||||
|
|
||||||
String repoRoot = prepareTestRepos();
|
String repoRoot = prepareTestRepos();
|
||||||
String projectRoot = repoRoot + "/org/apache/maven/plugins/maven-install-plugin";
|
String projectNs = "org.apache.maven.plugins";
|
||||||
|
String projectPath = projectNs.replaceAll("\\.","/");
|
||||||
|
String projectName = "maven-install-plugin";
|
||||||
|
String projectVersion = "2.2-SNAPSHOT";
|
||||||
|
String projectRoot = repoRoot + "/" + projectPath+"/"+projectName;
|
||||||
|
|
||||||
setLastModified( projectRoot + "/2.2-SNAPSHOT" );
|
setLastModified( projectRoot + "/"+projectVersion);
|
||||||
|
|
||||||
|
|
||||||
|
Path repo = getTestRepoRootPath();
|
||||||
|
Path vDir = repo.resolve(projectPath).resolve(projectName).resolve(projectVersion);
|
||||||
|
|
||||||
|
// Provide the metadata list
|
||||||
|
List<ArtifactMetadata> ml = getArtifactMetadataFromDir( TEST_REPO_ID, projectName, repo, vDir );
|
||||||
|
when(metadataRepository.getArtifacts(TEST_REPO_ID, projectNs,
|
||||||
|
projectName, projectVersion)).thenReturn(ml);
|
||||||
|
Set<String> deletedVersions = new HashSet<>();
|
||||||
|
deletedVersions.add("2.2-SNAPSHOT");
|
||||||
|
deletedVersions.add("2.2-20061118.060401-2");
|
||||||
|
|
||||||
repoPurgeConsumer.processFile( PATH_TO_BY_DAYS_OLD_ARTIFACT );
|
repoPurgeConsumer.processFile( PATH_TO_BY_DAYS_OLD_ARTIFACT );
|
||||||
|
|
||||||
|
// Verify the metadataRepository invocations
|
||||||
|
verify(metadataRepository, never()).removeProjectVersion(eq(TEST_REPO_ID), eq(projectNs), eq(projectName), eq(projectVersion));
|
||||||
|
ArgumentCaptor<ArtifactMetadata> metadataArg = ArgumentCaptor.forClass(ArtifactMetadata.class);
|
||||||
|
verify(metadataRepository, times(2)).removeArtifact(metadataArg.capture(), eq(projectVersion));
|
||||||
|
List<ArtifactMetadata> metaL = metadataArg.getAllValues();
|
||||||
|
for (ArtifactMetadata meta : metaL) {
|
||||||
|
assertTrue(meta.getId().startsWith(projectName));
|
||||||
|
assertTrue(deletedVersions.contains(meta.getVersion()));
|
||||||
|
}
|
||||||
|
|
||||||
assertDeleted( projectRoot + "/2.2-SNAPSHOT/maven-install-plugin-2.2-SNAPSHOT.jar" );
|
assertDeleted( projectRoot + "/2.2-SNAPSHOT/maven-install-plugin-2.2-SNAPSHOT.jar" );
|
||||||
assertDeleted( projectRoot + "/2.2-SNAPSHOT/maven-install-plugin-2.2-SNAPSHOT.jar.md5" );
|
assertDeleted( projectRoot + "/2.2-SNAPSHOT/maven-install-plugin-2.2-SNAPSHOT.jar.md5" );
|
||||||
assertDeleted( projectRoot + "/2.2-SNAPSHOT/maven-install-plugin-2.2-SNAPSHOT.jar.sha1" );
|
assertDeleted( projectRoot + "/2.2-SNAPSHOT/maven-install-plugin-2.2-SNAPSHOT.jar.sha1" );
|
||||||
@ -305,12 +377,29 @@ public void testReleasedSnapshotsWereNotCleaned()
|
|||||||
repoPurgeConsumer.beginScan( repoConfiguration, null );
|
repoPurgeConsumer.beginScan( repoConfiguration, null );
|
||||||
|
|
||||||
String repoRoot = prepareTestRepos();
|
String repoRoot = prepareTestRepos();
|
||||||
|
String projectNs = "org.apache.maven.plugins";
|
||||||
|
String projectPath = projectNs.replaceAll("\\.","/");
|
||||||
|
String projectName = "maven-plugin-plugin";
|
||||||
|
String projectVersion = "2.3-SNAPSHOT";
|
||||||
|
String projectRoot = repoRoot + "/" + projectPath+"/"+projectName;
|
||||||
|
|
||||||
|
Path repo = getTestRepoRootPath();
|
||||||
|
Path vDir = repo.resolve(projectPath).resolve(projectName).resolve(projectVersion);
|
||||||
|
|
||||||
|
// Provide the metadata list
|
||||||
|
List<ArtifactMetadata> ml = getArtifactMetadataFromDir( TEST_REPO_ID, projectName, repo, vDir );
|
||||||
|
when(metadataRepository.getArtifacts(TEST_REPO_ID, projectNs,
|
||||||
|
projectName, projectVersion)).thenReturn(ml);
|
||||||
|
|
||||||
repoPurgeConsumer.processFile(
|
repoPurgeConsumer.processFile(
|
||||||
CleanupReleasedSnapshotsRepositoryPurgeTest.PATH_TO_RELEASED_SNAPSHOT_IN_SAME_REPO );
|
CleanupReleasedSnapshotsRepositoryPurgeTest.PATH_TO_RELEASED_SNAPSHOT_IN_SAME_REPO );
|
||||||
|
|
||||||
|
verify(metadataRepository, never()).removeProjectVersion(eq(TEST_REPO_ID), eq(projectNs), eq(projectName), eq(projectVersion));
|
||||||
|
ArgumentCaptor<ArtifactMetadata> metadataArg = ArgumentCaptor.forClass(ArtifactMetadata.class);
|
||||||
|
verify(metadataRepository, never()).removeArtifact(any(), any());
|
||||||
|
verify(metadataRepository, never()).removeArtifact( any(), any(), any(), any(), any(MetadataFacet.class) );
|
||||||
|
|
||||||
// check if the snapshot wasn't removed
|
// check if the snapshot wasn't removed
|
||||||
String projectRoot = repoRoot + "/org/apache/maven/plugins/maven-plugin-plugin";
|
|
||||||
|
|
||||||
assertExists( projectRoot + "/2.3-SNAPSHOT" );
|
assertExists( projectRoot + "/2.3-SNAPSHOT" );
|
||||||
assertExists( projectRoot + "/2.3-SNAPSHOT/maven-plugin-plugin-2.3-SNAPSHOT.jar" );
|
assertExists( projectRoot + "/2.3-SNAPSHOT/maven-plugin-plugin-2.3-SNAPSHOT.jar" );
|
||||||
@ -350,11 +439,25 @@ public void testReleasedSnapshotsWereCleaned()
|
|||||||
repoPurgeConsumer.beginScan( repoConfiguration, null );
|
repoPurgeConsumer.beginScan( repoConfiguration, null );
|
||||||
|
|
||||||
String repoRoot = prepareTestRepos();
|
String repoRoot = prepareTestRepos();
|
||||||
|
String projectNs = "org.apache.maven.plugins";
|
||||||
|
String projectPath = projectNs.replaceAll("\\.","/");
|
||||||
|
String projectName = "maven-plugin-plugin";
|
||||||
|
String projectVersion = "2.3-SNAPSHOT";
|
||||||
|
String projectRoot = repoRoot + "/" + projectPath+"/"+projectName;
|
||||||
|
Path repo = getTestRepoRootPath();
|
||||||
|
Path vDir = repo.resolve(projectPath).resolve(projectName).resolve(projectVersion);
|
||||||
|
|
||||||
|
// Provide the metadata list
|
||||||
|
List<ArtifactMetadata> ml = getArtifactMetadataFromDir(TEST_REPO_ID , projectName, repo.getParent(), vDir );
|
||||||
|
when(metadataRepository.getArtifacts(TEST_REPO_ID, projectNs,
|
||||||
|
projectName, projectVersion)).thenReturn(ml);
|
||||||
|
|
||||||
repoPurgeConsumer.processFile(
|
repoPurgeConsumer.processFile(
|
||||||
CleanupReleasedSnapshotsRepositoryPurgeTest.PATH_TO_RELEASED_SNAPSHOT_IN_SAME_REPO );
|
CleanupReleasedSnapshotsRepositoryPurgeTest.PATH_TO_RELEASED_SNAPSHOT_IN_SAME_REPO );
|
||||||
|
|
||||||
String projectRoot = repoRoot + "/org/apache/maven/plugins/maven-plugin-plugin";
|
verify(metadataRepository, times(1)).removeProjectVersion(eq(TEST_REPO_ID), eq(projectNs), eq(projectName), eq(projectVersion));
|
||||||
|
ArgumentCaptor<ArtifactMetadata> metadataArg = ArgumentCaptor.forClass(ArtifactMetadata.class);
|
||||||
|
verify(metadataRepository, never()).removeArtifact(any(), any());
|
||||||
|
|
||||||
// check if the snapshot was removed
|
// check if the snapshot was removed
|
||||||
assertDeleted( projectRoot + "/2.3-SNAPSHOT" );
|
assertDeleted( projectRoot + "/2.3-SNAPSHOT" );
|
||||||
|
@ -19,13 +19,23 @@
|
|||||||
* under the License.
|
* under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
import java.nio.file.Path;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
|
import java.util.HashSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
import org.apache.archiva.admin.model.beans.ManagedRepository;
|
import org.apache.archiva.admin.model.beans.ManagedRepository;
|
||||||
|
import org.apache.archiva.metadata.model.ArtifactMetadata;
|
||||||
import org.apache.archiva.repository.events.RepositoryListener;
|
import org.apache.archiva.repository.events.RepositoryListener;
|
||||||
import org.junit.After;
|
import org.junit.After;
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
import org.mockito.ArgumentCaptor;
|
||||||
|
|
||||||
|
import static org.junit.Assert.assertTrue;
|
||||||
|
import static org.mockito.Matchers.eq;
|
||||||
|
import static org.mockito.Mockito.*;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Test RetentionsCountRepositoryPurgeTest
|
* Test RetentionsCountRepositoryPurgeTest
|
||||||
@ -62,6 +72,17 @@ public void testIfAJarWasFound()
|
|||||||
throws Exception
|
throws Exception
|
||||||
{
|
{
|
||||||
String repoRoot = prepareTestRepos();
|
String repoRoot = prepareTestRepos();
|
||||||
|
String projectNs = "org.jruby.plugins";
|
||||||
|
String projectPath = projectNs.replaceAll("\\.","/");
|
||||||
|
String projectName = "jruby-rake-plugin";
|
||||||
|
String projectVersion = "1.0RC1-SNAPSHOT";
|
||||||
|
String projectRoot = repoRoot + "/" + projectPath+"/"+projectName;
|
||||||
|
Path repo = getTestRepoRootPath();
|
||||||
|
Path vDir = repo.resolve(projectPath).resolve(projectName).resolve(projectVersion);
|
||||||
|
Set<String> deletedVersions = new HashSet<>();
|
||||||
|
deletedVersions.add("1.0RC1-20070504.153317-1");
|
||||||
|
deletedVersions.add("1.0RC1-20070504.160758-2");
|
||||||
|
String versionRoot = projectRoot + "/" + projectVersion;
|
||||||
|
|
||||||
// test listeners for the correct artifacts
|
// test listeners for the correct artifacts
|
||||||
listener.deleteArtifact( metadataRepository, getRepository().getId(), "org.jruby.plugins", "jruby-rake-plugin",
|
listener.deleteArtifact( metadataRepository, getRepository().getId(), "org.jruby.plugins", "jruby-rake-plugin",
|
||||||
@ -87,11 +108,26 @@ public void testIfAJarWasFound()
|
|||||||
"1.0RC1-20070504.160758-2", "jruby-rake-plugin-1.0RC1-20070504.160758-2.pom" );
|
"1.0RC1-20070504.160758-2", "jruby-rake-plugin-1.0RC1-20070504.160758-2.pom" );
|
||||||
listenerControl.replay();
|
listenerControl.replay();
|
||||||
|
|
||||||
|
// Provide the metadata list
|
||||||
|
List<ArtifactMetadata> ml = getArtifactMetadataFromDir(TEST_REPO_ID , projectName, repo.getParent(), vDir );
|
||||||
|
when(metadataRepository.getArtifacts(TEST_REPO_ID, projectNs,
|
||||||
|
projectName, projectVersion)).thenReturn(ml);
|
||||||
|
|
||||||
|
|
||||||
repoPurge.process( PATH_TO_BY_RETENTION_COUNT_ARTIFACT );
|
repoPurge.process( PATH_TO_BY_RETENTION_COUNT_ARTIFACT );
|
||||||
|
|
||||||
listenerControl.verify();
|
listenerControl.verify();
|
||||||
|
|
||||||
String versionRoot = repoRoot + "/org/jruby/plugins/jruby-rake-plugin/1.0RC1-SNAPSHOT";
|
// Verify the metadataRepository invocations
|
||||||
|
verify(metadataRepository, never()).removeProjectVersion(eq(TEST_REPO_ID), eq(projectNs), eq(projectName), eq(projectVersion));
|
||||||
|
ArgumentCaptor<ArtifactMetadata> metadataArg = ArgumentCaptor.forClass(ArtifactMetadata.class);
|
||||||
|
verify(metadataRepository, times(deletedVersions.size())).removeArtifact(metadataArg.capture(), eq(projectVersion));
|
||||||
|
List<ArtifactMetadata> metaL = metadataArg.getAllValues();
|
||||||
|
for (ArtifactMetadata meta : metaL) {
|
||||||
|
assertTrue(meta.getId().startsWith(projectName));
|
||||||
|
assertTrue(deletedVersions.contains(meta.getVersion()));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// assert if removed from repo
|
// assert if removed from repo
|
||||||
assertDeleted( versionRoot + "/jruby-rake-plugin-1.0RC1-20070504.153317-1.jar" );
|
assertDeleted( versionRoot + "/jruby-rake-plugin-1.0RC1-20070504.153317-1.jar" );
|
||||||
@ -132,6 +168,17 @@ public void testIfAPomWasFound()
|
|||||||
throws Exception
|
throws Exception
|
||||||
{
|
{
|
||||||
String repoRoot = prepareTestRepos();
|
String repoRoot = prepareTestRepos();
|
||||||
|
String projectNs = "org.codehaus.castor";
|
||||||
|
String projectPath = projectNs.replaceAll("\\.","/");
|
||||||
|
String projectName = "castor-anttasks";
|
||||||
|
String projectVersion = "1.1.2-SNAPSHOT";
|
||||||
|
String projectRoot = repoRoot + "/" + projectPath+"/"+projectName;
|
||||||
|
Path repo = getTestRepoRootPath();
|
||||||
|
Path vDir = repo.resolve(projectPath).resolve(projectName).resolve(projectVersion);
|
||||||
|
Set<String> deletedVersions = new HashSet<>();
|
||||||
|
deletedVersions.add("1.1.2-20070427.065136-1");
|
||||||
|
String versionRoot = projectRoot + "/" + projectVersion;
|
||||||
|
|
||||||
|
|
||||||
// test listeners for the correct artifacts
|
// test listeners for the correct artifacts
|
||||||
listener.deleteArtifact( metadataRepository, getRepository().getId(), "org.codehaus.castor", "castor-anttasks",
|
listener.deleteArtifact( metadataRepository, getRepository().getId(), "org.codehaus.castor", "castor-anttasks",
|
||||||
@ -140,11 +187,25 @@ public void testIfAPomWasFound()
|
|||||||
"1.1.2-20070427.065136-1", "castor-anttasks-1.1.2-20070427.065136-1.pom" );
|
"1.1.2-20070427.065136-1", "castor-anttasks-1.1.2-20070427.065136-1.pom" );
|
||||||
listenerControl.replay();
|
listenerControl.replay();
|
||||||
|
|
||||||
|
// Provide the metadata list
|
||||||
|
List<ArtifactMetadata> ml = getArtifactMetadataFromDir(TEST_REPO_ID , projectName, repo.getParent(), vDir );
|
||||||
|
when(metadataRepository.getArtifacts(TEST_REPO_ID, projectNs,
|
||||||
|
projectName, projectVersion)).thenReturn(ml);
|
||||||
|
|
||||||
repoPurge.process( PATH_TO_BY_RETENTION_COUNT_POM );
|
repoPurge.process( PATH_TO_BY_RETENTION_COUNT_POM );
|
||||||
|
|
||||||
listenerControl.verify();
|
listenerControl.verify();
|
||||||
|
|
||||||
String versionRoot = repoRoot + "/org/codehaus/castor/castor-anttasks/1.1.2-SNAPSHOT";
|
// Verify the metadataRepository invocations
|
||||||
|
verify(metadataRepository, never()).removeProjectVersion(eq(TEST_REPO_ID), eq(projectNs), eq(projectName), eq(projectVersion));
|
||||||
|
ArgumentCaptor<ArtifactMetadata> metadataArg = ArgumentCaptor.forClass(ArtifactMetadata.class);
|
||||||
|
verify(metadataRepository, times(deletedVersions.size())).removeArtifact(metadataArg.capture(), eq(projectVersion));
|
||||||
|
List<ArtifactMetadata> metaL = metadataArg.getAllValues();
|
||||||
|
for (ArtifactMetadata meta : metaL) {
|
||||||
|
assertTrue(meta.getId().startsWith(projectName));
|
||||||
|
assertTrue(deletedVersions.contains(meta.getVersion()));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// assert if removed from repo
|
// assert if removed from repo
|
||||||
assertDeleted( versionRoot + "/castor-anttasks-1.1.2-20070427.065136-1.jar" );
|
assertDeleted( versionRoot + "/castor-anttasks-1.1.2-20070427.065136-1.jar" );
|
||||||
@ -181,6 +242,17 @@ public void testOrderOfDeletion()
|
|||||||
throws Exception
|
throws Exception
|
||||||
{
|
{
|
||||||
String repoRoot = prepareTestRepos();
|
String repoRoot = prepareTestRepos();
|
||||||
|
String projectNs = "org.apache.maven.plugins";
|
||||||
|
String projectPath = projectNs.replaceAll("\\.","/");
|
||||||
|
String projectName = "maven-assembly-plugin";
|
||||||
|
String projectVersion = "1.1.2-SNAPSHOT";
|
||||||
|
String projectRoot = repoRoot + "/" + projectPath+"/"+projectName;
|
||||||
|
Path repo = getTestRepoRootPath();
|
||||||
|
Path vDir = repo.resolve(projectPath).resolve(projectName).resolve(projectVersion);
|
||||||
|
Set<String> deletedVersions = new HashSet<>();
|
||||||
|
deletedVersions.add("1.1.2-20070427.065136-1");
|
||||||
|
String versionRoot = projectRoot + "/" + projectVersion;
|
||||||
|
|
||||||
|
|
||||||
// test listeners for the correct artifacts
|
// test listeners for the correct artifacts
|
||||||
listener.deleteArtifact( metadataRepository, getRepository().getId(), "org.apache.maven.plugins",
|
listener.deleteArtifact( metadataRepository, getRepository().getId(), "org.apache.maven.plugins",
|
||||||
@ -191,11 +263,25 @@ public void testOrderOfDeletion()
|
|||||||
"maven-assembly-plugin-1.1.2-20070427.065136-1.pom" );
|
"maven-assembly-plugin-1.1.2-20070427.065136-1.pom" );
|
||||||
listenerControl.replay();
|
listenerControl.replay();
|
||||||
|
|
||||||
|
// Provide the metadata list
|
||||||
|
List<ArtifactMetadata> ml = getArtifactMetadataFromDir(TEST_REPO_ID , projectName, repo.getParent(), vDir );
|
||||||
|
when(metadataRepository.getArtifacts(TEST_REPO_ID, projectNs,
|
||||||
|
projectName, projectVersion)).thenReturn(ml);
|
||||||
|
|
||||||
repoPurge.process( PATH_TO_TEST_ORDER_OF_DELETION );
|
repoPurge.process( PATH_TO_TEST_ORDER_OF_DELETION );
|
||||||
|
|
||||||
listenerControl.verify();
|
listenerControl.verify();
|
||||||
|
|
||||||
String versionRoot = repoRoot + "/org/apache/maven/plugins/maven-assembly-plugin/1.1.2-SNAPSHOT";
|
// Verify the metadataRepository invocations
|
||||||
|
verify(metadataRepository, never()).removeProjectVersion(eq(TEST_REPO_ID), eq(projectNs), eq(projectName), eq(projectVersion));
|
||||||
|
ArgumentCaptor<ArtifactMetadata> metadataArg = ArgumentCaptor.forClass(ArtifactMetadata.class);
|
||||||
|
verify(metadataRepository, times(deletedVersions.size())).removeArtifact(metadataArg.capture(), eq(projectVersion));
|
||||||
|
List<ArtifactMetadata> metaL = metadataArg.getAllValues();
|
||||||
|
for (ArtifactMetadata meta : metaL) {
|
||||||
|
assertTrue(meta.getId().startsWith(projectName));
|
||||||
|
assertTrue(deletedVersions.contains(meta.getVersion()));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
assertDeleted( versionRoot + "/maven-assembly-plugin-1.1.2-20070427.065136-1.jar" );
|
assertDeleted( versionRoot + "/maven-assembly-plugin-1.1.2-20070427.065136-1.jar" );
|
||||||
assertDeleted( versionRoot + "/maven-assembly-plugin-1.1.2-20070427.065136-1.jar.sha1" );
|
assertDeleted( versionRoot + "/maven-assembly-plugin-1.1.2-20070427.065136-1.jar.sha1" );
|
||||||
|
Loading…
x
Reference in New Issue
Block a user