001package org.apache.archiva.consumers.core.repository; 002 003/* 004 * Licensed to the Apache Software Foundation (ASF) under one 005 * or more contributor license agreements. See the NOTICE file 006 * distributed with this work for additional information 007 * regarding copyright ownership. The ASF licenses this file 008 * to you under the Apache License, Version 2.0 (the 009 * "License"); you may not use this file except in compliance 010 * with the License. You may obtain a copy of the License at 011 * 012 * http://www.apache.org/licenses/LICENSE-2.0 013 * 014 * Unless required by applicable law or agreed to in writing, 015 * software distributed under the License is distributed on an 016 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 017 * KIND, either express or implied. See the License for the 018 * specific language governing permissions and limitations 019 * under the License. 020 */ 021 022import org.apache.archiva.configuration.ArchivaConfiguration; 023import org.apache.archiva.configuration.ConfigurationNames; 024import org.apache.archiva.configuration.FileTypes; 025import org.apache.archiva.consumers.AbstractMonitoredConsumer; 026import org.apache.archiva.consumers.ConsumerException; 027import org.apache.archiva.consumers.KnownRepositoryContentConsumer; 028import org.apache.archiva.metadata.repository.RepositorySession; 029import org.apache.archiva.metadata.repository.RepositorySessionFactory; 030import org.apache.archiva.components.registry.Registry; 031import org.apache.archiva.components.registry.RegistryListener; 032import org.apache.archiva.repository.ManagedRepository; 033import org.apache.archiva.repository.ManagedRepositoryContent; 034import org.apache.archiva.repository.RepositoryContentFactory; 035import org.apache.archiva.repository.RepositoryRegistry; 036import org.apache.archiva.metadata.audit.RepositoryListener; 037import org.apache.archiva.repository.features.ArtifactCleanupFeature; 038import org.apache.archiva.repository.metadata.base.MetadataTools; 039import org.springframework.beans.factory.annotation.Autowired; 040import org.springframework.context.annotation.Scope; 041import org.springframework.stereotype.Service; 042 043import javax.annotation.PostConstruct; 044import javax.inject.Inject; 045import javax.inject.Named; 046import java.util.ArrayList; 047import java.util.Collections; 048import java.util.Date; 049import java.util.List; 050 051/** 052 * Consumer for removing old snapshots in the repository based on the criteria 053 * specified by the user. 054 */ 055@Service( "knownRepositoryContentConsumer#repository-purge" ) 056@Scope( "prototype" ) 057public class RepositoryPurgeConsumer 058 extends AbstractMonitoredConsumer 059 implements KnownRepositoryContentConsumer, RegistryListener 060{ 061 /** 062 * default-value="repository-purge" 063 */ 064 private String id = "repository-purge"; 065 066 /** 067 * default-value="Purge repository of old snapshots" 068 */ 069 private String description = "Purge repository of old snapshots"; 070 071 @Inject 072 @Named( value = "archivaConfiguration#default" ) 073 private ArchivaConfiguration configuration; 074 075 @Inject 076 private RepositoryRegistry repositoryRegistry; 077 078 @Inject 079 @Named( value = "repositoryContentFactory#default" ) 080 private RepositoryContentFactory repositoryContentFactory; 081 082 @Inject 083 private MetadataTools metadataTools; 084 085 @Inject 086 @Named( value = "fileTypes" ) 087 private FileTypes filetypes; 088 089 private List<String> includes = new ArrayList<>( ); 090 091 private RepositoryPurge repoPurge; 092 093 private RepositoryPurge cleanUp; 094 095 private boolean deleteReleasedSnapshots; 096 097 /** 098 * 099 */ 100 @Inject 101 @Autowired( required = false ) 102 private List<RepositoryListener> listeners = Collections.emptyList( ); 103 104 @Inject 105 private RepositorySessionFactory repositorySessionFactory; 106 107 private RepositorySession repositorySession; 108 109 @Override 110 public String getId( ) 111 { 112 return this.id; 113 } 114 115 @Override 116 public String getDescription( ) 117 { 118 return this.description; 119 } 120 121 @Override 122 public List<String> getExcludes( ) 123 { 124 return getDefaultArtifactExclusions( ); 125 } 126 127 @Override 128 public List<String> getIncludes( ) 129 { 130 return this.includes; 131 } 132 133 @Override 134 public void beginScan( ManagedRepository repository, Date whenGathered ) 135 throws ConsumerException 136 { 137 ManagedRepositoryContent repositoryContent; 138 repositoryContent = repository.getContent(); 139 140 try 141 { 142 repositorySession = repositorySessionFactory.createSession( ); 143 } 144 catch ( org.apache.archiva.metadata.repository.MetadataRepositoryException e ) 145 { 146 throw new ConsumerException( "Could not create session: " + e.getMessage( ), e ); 147 } 148 149 if (repository.supportsFeature( ArtifactCleanupFeature.class )) 150 { 151 ArtifactCleanupFeature acf = repository.getFeature( ArtifactCleanupFeature.class ).get(); 152 int retentionPeriodInDays = acf.getRetentionPeriod( ).getDays( ); 153 int retentionCount = acf.getRetentionCount(); 154 if ( retentionPeriodInDays != 0 ) 155 { 156 repoPurge = new DaysOldRepositoryPurge( repositoryContent, retentionPeriodInDays, 157 retentionCount, repositorySession, listeners ); 158 } 159 else 160 { 161 repoPurge = 162 new RetentionCountRepositoryPurge( repositoryContent, retentionCount, repositorySession, 163 listeners ); 164 } 165 deleteReleasedSnapshots = acf.isDeleteReleasedSnapshots( ); 166 } else { 167 throw new ConsumerException( "The repository does not support the ArtifactCleanup feature "+repository.getId() ); 168 } 169 170 171 cleanUp = new CleanupReleasedSnapshotsRepositoryPurge( repositoryContent, metadataTools, repositoryRegistry, 172 repositorySession, listeners ); 173 174 } 175 176 @Override 177 public void beginScan( ManagedRepository repository, Date whenGathered, boolean executeOnEntireRepo ) 178 throws ConsumerException 179 { 180 beginScan( repository, whenGathered ); 181 } 182 183 @Override 184 public void processFile( String path ) 185 throws ConsumerException 186 { 187 try 188 { 189 if ( deleteReleasedSnapshots ) 190 { 191 cleanUp.process( path ); 192 } 193 repoPurge.process( path ); 194 } 195 catch ( RepositoryPurgeException rpe ) 196 { 197 throw new ConsumerException( rpe.getMessage( ), rpe ); 198 } 199 } 200 201 @Override 202 public void processFile( String path, boolean executeOnEntireRepo ) 203 throws Exception 204 { 205 processFile( path ); 206 } 207 208 @Override 209 public void completeScan( ) 210 { 211 repositorySession.close( ); 212 } 213 214 @Override 215 public void completeScan( boolean executeOnEntireRepo ) 216 { 217 completeScan( ); 218 } 219 220 @Override 221 public void afterConfigurationChange( Registry registry, String propertyName, Object propertyValue ) 222 { 223 if ( ConfigurationNames.isRepositoryScanning( propertyName ) ) 224 { 225 initIncludes( ); 226 } 227 } 228 229 @Override 230 public void beforeConfigurationChange( Registry registry, String propertyName, Object propertyValue ) 231 { 232 /* do nothing */ 233 } 234 235 private void initIncludes( ) 236 { 237 includes = new ArrayList<>( filetypes.getFileTypePatterns( FileTypes.ARTIFACTS ) ); 238 } 239 240 @PostConstruct 241 public void initialize( ) 242 { 243 configuration.addChangeListener( this ); 244 245 initIncludes( ); 246 } 247 248 @Override 249 public boolean isProcessUnmodified( ) 250 { 251 // we need to check all files for deletion, especially if not modified 252 return true; 253 } 254 255 public ArchivaConfiguration getConfiguration( ) 256 { 257 return configuration; 258 } 259 260 public void setConfiguration( ArchivaConfiguration configuration ) 261 { 262 this.configuration = configuration; 263 } 264 265 public RepositoryContentFactory getRepositoryContentFactory( ) 266 { 267 return repositoryContentFactory; 268 } 269 270 public void setRepositoryContentFactory( RepositoryContentFactory repositoryContentFactory ) 271 { 272 this.repositoryContentFactory = repositoryContentFactory; 273 } 274 275 public MetadataTools getMetadataTools( ) 276 { 277 return metadataTools; 278 } 279 280 public void setMetadataTools( MetadataTools metadataTools ) 281 { 282 this.metadataTools = metadataTools; 283 } 284 285 public FileTypes getFiletypes( ) 286 { 287 return filetypes; 288 } 289 290 public void setFiletypes( FileTypes filetypes ) 291 { 292 this.filetypes = filetypes; 293 } 294 295 public RepositoryPurge getRepoPurge( ) 296 { 297 return repoPurge; 298 } 299 300 public void setRepoPurge( RepositoryPurge repoPurge ) 301 { 302 this.repoPurge = repoPurge; 303 } 304 305 public RepositoryPurge getCleanUp( ) 306 { 307 return cleanUp; 308 } 309 310 public void setCleanUp( RepositoryPurge cleanUp ) 311 { 312 this.cleanUp = cleanUp; 313 } 314 315 public boolean isDeleteReleasedSnapshots( ) 316 { 317 return deleteReleasedSnapshots; 318 } 319 320 public void setDeleteReleasedSnapshots( boolean deleteReleasedSnapshots ) 321 { 322 this.deleteReleasedSnapshots = deleteReleasedSnapshots; 323 } 324 325 public RepositorySessionFactory getRepositorySessionFactory( ) 326 { 327 return repositorySessionFactory; 328 } 329 330 public void setRepositorySessionFactory( RepositorySessionFactory repositorySessionFactory ) 331 { 332 this.repositorySessionFactory = repositorySessionFactory; 333 } 334 335}