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.admin.model.beans.ManagedRepository; 023import org.apache.archiva.admin.model.managed.ManagedRepositoryAdmin; 024import org.apache.archiva.configuration.ArchivaConfiguration; 025import org.apache.archiva.configuration.ConfigurationNames; 026import org.apache.archiva.configuration.FileTypes; 027import org.apache.archiva.consumers.AbstractMonitoredConsumer; 028import org.apache.archiva.consumers.ConsumerException; 029import org.apache.archiva.consumers.KnownRepositoryContentConsumer; 030import org.apache.archiva.metadata.repository.RepositorySession; 031import org.apache.archiva.metadata.repository.RepositorySessionFactory; 032import org.apache.archiva.redback.components.registry.Registry; 033import org.apache.archiva.redback.components.registry.RegistryListener; 034import org.apache.archiva.repository.ManagedRepositoryContent; 035import org.apache.archiva.repository.RepositoryContentFactory; 036import org.apache.archiva.repository.RepositoryException; 037import org.apache.archiva.repository.RepositoryNotFoundException; 038import org.apache.archiva.repository.events.RepositoryListener; 039import org.apache.archiva.repository.metadata.MetadataTools; 040import org.springframework.beans.factory.annotation.Autowired; 041import org.springframework.context.annotation.Scope; 042import org.springframework.stereotype.Service; 043 044import javax.annotation.PostConstruct; 045import javax.inject.Inject; 046import javax.inject.Named; 047import java.util.ArrayList; 048import java.util.Collections; 049import java.util.Date; 050import java.util.List; 051 052/** 053 * Consumer for removing old snapshots in the repository based on the criteria 054 * specified by the user. 055 */ 056@Service( "knownRepositoryContentConsumer#repository-purge" ) 057@Scope( "prototype" ) 058public class RepositoryPurgeConsumer 059 extends AbstractMonitoredConsumer 060 implements KnownRepositoryContentConsumer, RegistryListener 061{ 062 /** 063 * default-value="repository-purge" 064 */ 065 private String id = "repository-purge"; 066 067 /** 068 * default-value="Purge repository of old snapshots" 069 */ 070 private String description = "Purge repository of old snapshots"; 071 072 @Inject 073 @Named( value = "archivaConfiguration#default" ) 074 private ArchivaConfiguration configuration; 075 076 @Inject 077 private ManagedRepositoryAdmin managedRepositoryAdmin; 078 079 @Inject 080 @Named( value = "repositoryContentFactory#default" ) 081 private RepositoryContentFactory repositoryContentFactory; 082 083 @Inject 084 private MetadataTools metadataTools; 085 086 @Inject 087 @Named( value = "fileTypes" ) 088 private FileTypes filetypes; 089 090 private List<String> includes = new ArrayList<>( ); 091 092 private RepositoryPurge repoPurge; 093 094 private RepositoryPurge cleanUp; 095 096 private boolean deleteReleasedSnapshots; 097 098 /** 099 * 100 */ 101 @Inject 102 @Autowired( required = false ) 103 private List<RepositoryListener> listeners = Collections.emptyList( ); 104 105 @Inject 106 private RepositorySessionFactory repositorySessionFactory; 107 108 private RepositorySession repositorySession; 109 110 @Override 111 public String getId( ) 112 { 113 return this.id; 114 } 115 116 @Override 117 public String getDescription( ) 118 { 119 return this.description; 120 } 121 122 @Override 123 public List<String> getExcludes( ) 124 { 125 return getDefaultArtifactExclusions( ); 126 } 127 128 @Override 129 public List<String> getIncludes( ) 130 { 131 return this.includes; 132 } 133 134 @Override 135 public void beginScan( ManagedRepository repository, Date whenGathered ) 136 throws ConsumerException 137 { 138 ManagedRepositoryContent repositoryContent; 139 try 140 { 141 repositoryContent = repositoryContentFactory.getManagedRepositoryContent( repository.getId( ) ); 142 } 143 catch ( RepositoryNotFoundException e ) 144 { 145 throw new ConsumerException( "Can't run repository purge: " + e.getMessage( ), e ); 146 } 147 catch ( RepositoryException e ) 148 { 149 throw new ConsumerException( "Can't run repository purge: " + e.getMessage( ), e ); 150 } 151 152 repositorySession = repositorySessionFactory.createSession( ); 153 154 if ( repository.getDaysOlder( ) != 0 ) 155 { 156 repoPurge = new DaysOldRepositoryPurge( repositoryContent, repository.getDaysOlder( ), 157 repository.getRetentionCount( ), repositorySession, listeners ); 158 } 159 else 160 { 161 repoPurge = 162 new RetentionCountRepositoryPurge( repositoryContent, repository.getRetentionCount( ), repositorySession, 163 listeners ); 164 } 165 166 cleanUp = new CleanupReleasedSnapshotsRepositoryPurge( repositoryContent, metadataTools, managedRepositoryAdmin, 167 repositoryContentFactory, repositorySession, listeners ); 168 169 deleteReleasedSnapshots = repository.isDeleteReleasedSnapshots( ); 170 } 171 172 @Override 173 public void beginScan( ManagedRepository repository, Date whenGathered, boolean executeOnEntireRepo ) 174 throws ConsumerException 175 { 176 beginScan( repository, whenGathered ); 177 } 178 179 @Override 180 public void processFile( String path ) 181 throws ConsumerException 182 { 183 try 184 { 185 if ( deleteReleasedSnapshots ) 186 { 187 cleanUp.process( path ); 188 } 189 repoPurge.process( path ); 190 } 191 catch ( RepositoryPurgeException rpe ) 192 { 193 throw new ConsumerException( rpe.getMessage( ), rpe ); 194 } 195 } 196 197 @Override 198 public void processFile( String path, boolean executeOnEntireRepo ) 199 throws Exception 200 { 201 processFile( path ); 202 } 203 204 @Override 205 public void completeScan( ) 206 { 207 repositorySession.close( ); 208 } 209 210 @Override 211 public void completeScan( boolean executeOnEntireRepo ) 212 { 213 completeScan( ); 214 } 215 216 @Override 217 public void afterConfigurationChange( Registry registry, String propertyName, Object propertyValue ) 218 { 219 if ( ConfigurationNames.isRepositoryScanning( propertyName ) ) 220 { 221 initIncludes( ); 222 } 223 } 224 225 @Override 226 public void beforeConfigurationChange( Registry registry, String propertyName, Object propertyValue ) 227 { 228 /* do nothing */ 229 } 230 231 private void initIncludes( ) 232 { 233 includes = new ArrayList<>( filetypes.getFileTypePatterns( FileTypes.ARTIFACTS ) ); 234 } 235 236 @PostConstruct 237 public void initialize( ) 238 { 239 configuration.addChangeListener( this ); 240 241 initIncludes( ); 242 } 243 244 @Override 245 public boolean isProcessUnmodified( ) 246 { 247 // we need to check all files for deletion, especially if not modified 248 return true; 249 } 250 251 public ArchivaConfiguration getConfiguration( ) 252 { 253 return configuration; 254 } 255 256 public void setConfiguration( ArchivaConfiguration configuration ) 257 { 258 this.configuration = configuration; 259 } 260 261 public RepositoryContentFactory getRepositoryContentFactory( ) 262 { 263 return repositoryContentFactory; 264 } 265 266 public void setRepositoryContentFactory( RepositoryContentFactory repositoryContentFactory ) 267 { 268 this.repositoryContentFactory = repositoryContentFactory; 269 } 270 271 public MetadataTools getMetadataTools( ) 272 { 273 return metadataTools; 274 } 275 276 public void setMetadataTools( MetadataTools metadataTools ) 277 { 278 this.metadataTools = metadataTools; 279 } 280 281 public FileTypes getFiletypes( ) 282 { 283 return filetypes; 284 } 285 286 public void setFiletypes( FileTypes filetypes ) 287 { 288 this.filetypes = filetypes; 289 } 290 291 public RepositoryPurge getRepoPurge( ) 292 { 293 return repoPurge; 294 } 295 296 public void setRepoPurge( RepositoryPurge repoPurge ) 297 { 298 this.repoPurge = repoPurge; 299 } 300 301 public RepositoryPurge getCleanUp( ) 302 { 303 return cleanUp; 304 } 305 306 public void setCleanUp( RepositoryPurge cleanUp ) 307 { 308 this.cleanUp = cleanUp; 309 } 310 311 public boolean isDeleteReleasedSnapshots( ) 312 { 313 return deleteReleasedSnapshots; 314 } 315 316 public void setDeleteReleasedSnapshots( boolean deleteReleasedSnapshots ) 317 { 318 this.deleteReleasedSnapshots = deleteReleasedSnapshots; 319 } 320 321 public RepositorySessionFactory getRepositorySessionFactory( ) 322 { 323 return repositorySessionFactory; 324 } 325 326 public void setRepositorySessionFactory( RepositorySessionFactory repositorySessionFactory ) 327 { 328 this.repositorySessionFactory = repositorySessionFactory; 329 } 330 331 public RepositorySession getRepositorySession( ) 332 { 333 return repositorySession; 334 } 335 336 public void setRepositorySession( RepositorySession repositorySession ) 337 { 338 this.repositorySession = repositorySession; 339 } 340}