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 org.apache.archiva.metadata.model.facets.AuditEvent; import org.apache.archiva.common.utils.VersionUtil; import org.apache.archiva.metadata.model.ArtifactMetadata; import org.apache.archiva.metadata.model.maven2.MavenArtifactFacet; import org.apache.archiva.metadata.repository.MetadataRepository; import org.apache.archiva.metadata.repository.MetadataRepositoryException; import org.apache.archiva.metadata.repository.MetadataResolutionException; import org.apache.archiva.metadata.repository.RepositorySession; import org.apache.archiva.model.ArtifactReference; import org.apache.archiva.repository.ContentNotFoundException; import org.apache.archiva.repository.ManagedRepositoryContent; import org.apache.archiva.repository.events.RepositoryListener; import org.apache.commons.lang.StringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.io.File; import java.io.FilenameFilter; import java.util.Collection; import java.util.List; import java.util.Set; /** * Base class for all repository purge tasks. */ public abstract class AbstractRepositoryPurge implements RepositoryPurge { protected Logger log = LoggerFactory.getLogger( getClass() ); protected final ManagedRepositoryContent repository; protected final RepositorySession repositorySession; protected final List<RepositoryListener> listeners; private Logger logger = LoggerFactory.getLogger( "org.apache.archiva.AuditLog" ); private static final char DELIM = ' '; public AbstractRepositoryPurge( ManagedRepositoryContent repository, RepositorySession repositorySession, List<RepositoryListener> listeners ) { this.repository = repository; this.repositorySession = repositorySession; this.listeners = listeners; } /** * Purge the repo. Update db and index of removed artifacts. * * @param references */ protected void purge( Set<ArtifactReference> references ) { if ( references != null && !references.isEmpty() ) { MetadataRepository metadataRepository = repositorySession.getRepository(); for ( ArtifactReference reference : references ) { File artifactFile = repository.toFile( reference ); for ( RepositoryListener listener : listeners ) { listener.deleteArtifact( metadataRepository, repository.getId(), reference.getGroupId(), reference.getArtifactId(), reference.getVersion(), artifactFile.getName() ); } // TODO: this needs to be logged artifactFile.delete(); try { repository.deleteArtifact( reference ); } catch ( ContentNotFoundException e ) { 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() ); try { if ( snapshotVersion ) { String baseVersion = VersionUtil.getBaseVersion( reference.getVersion() ); Collection<ArtifactMetadata> artifacts = metadataRepository.getArtifacts( repository.getId(), reference.getGroupId(), reference.getArtifactId(), baseVersion ); if ( artifacts != null ) { // cleanup snapshots metadata for ( ArtifactMetadata artifactMetadata : artifacts ) { // TODO: mismatch between artifact (snapshot) version and project (base) version here if ( artifactMetadata.getVersion().equals( reference.getVersion() ) ) { if ( StringUtils.isNotBlank( reference.getClassifier() ) ) { // cleanup facet which contains classifier information MavenArtifactFacet mavenArtifactFacet = (MavenArtifactFacet) artifactMetadata.getFacet( MavenArtifactFacet.FACET_ID ); if ( StringUtils.equals( reference.getClassifier(), mavenArtifactFacet.getClassifier() ) ) { artifactMetadata.removeFacet( MavenArtifactFacet.FACET_ID ); String groupId = reference.getGroupId(), artifactId = reference.getArtifactId(), version = reference.getVersion(); MavenArtifactFacet mavenArtifactFacetToCompare = new MavenArtifactFacet(); mavenArtifactFacetToCompare.setClassifier( reference.getClassifier() ); metadataRepository.removeArtifact( repository.getId(), groupId, artifactId, version, mavenArtifactFacetToCompare ); metadataRepository.save(); } } else { metadataRepository.removeArtifact( artifactMetadata, VersionUtil.getBaseVersion( reference.getVersion() ) ); } } } } } } catch ( MetadataResolutionException e ) { log.warn( "skip error deleting metadata {}: {}", reference, e.getMessage() ); } catch ( MetadataRepositoryException e ) { log.warn( "skip error deleting metadata {}: {}", reference, e.getMessage() ); } repositorySession.save(); triggerAuditEvent( repository.getRepository().getId(), ArtifactReference.toKey( reference ), AuditEvent.PURGE_ARTIFACT ); purgeSupportFiles( artifactFile ); } } } /** * <p> * This find support files for the artifactFile and deletes them. * </p> * <p> * Support Files are things like ".sha1", ".md5", ".asc", etc. * </p> * * @param artifactFile the file to base off of. */ private void purgeSupportFiles( File artifactFile ) { File parentDir = artifactFile.getParentFile(); if ( !parentDir.exists() ) { return; } FilenameFilter filter = new ArtifactFilenameFilter( artifactFile.getName() ); File[] files = parentDir.listFiles( filter ); 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 ) { String msg = repoId + DELIM + "<system-purge>" + DELIM + "<system>" + DELIM + '\"' + resource + '\"' + DELIM + '\"' + action + '\"'; logger.info( msg ); } }