You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

DaysOldRepositoryPurge.java 6.8KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190
  1. package org.apache.archiva.consumers.core.repository;
  2. /*
  3. * Licensed to the Apache Software Foundation (ASF) under one
  4. * or more contributor license agreements. See the NOTICE file
  5. * distributed with this work for additional information
  6. * regarding copyright ownership. The ASF licenses this file
  7. * to you under the Apache License, Version 2.0 (the
  8. * "License"); you may not use this file except in compliance
  9. * with the License. You may obtain a copy of the License at
  10. *
  11. * http://www.apache.org/licenses/LICENSE-2.0
  12. *
  13. * Unless required by applicable law or agreed to in writing,
  14. * software distributed under the License is distributed on an
  15. * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
  16. * KIND, either express or implied. See the License for the
  17. * specific language governing permissions and limitations
  18. * under the License.
  19. */
  20. import org.apache.archiva.metadata.repository.RepositorySession;
  21. import org.apache.archiva.repository.events.RepositoryListener;
  22. import org.apache.commons.lang.time.DateUtils;
  23. import org.apache.archiva.common.utils.VersionComparator;
  24. import org.apache.archiva.common.utils.VersionUtil;
  25. import org.apache.archiva.model.ArtifactReference;
  26. import org.apache.archiva.model.VersionedReference;
  27. import org.apache.archiva.repository.ContentNotFoundException;
  28. import org.apache.archiva.repository.ManagedRepositoryContent;
  29. import org.apache.archiva.repository.layout.LayoutException;
  30. import java.io.File;
  31. import java.text.ParseException;
  32. import java.text.SimpleDateFormat;
  33. import java.util.ArrayList;
  34. import java.util.Calendar;
  35. import java.util.Collections;
  36. import java.util.Date;
  37. import java.util.List;
  38. import java.util.Set;
  39. import java.util.regex.Matcher;
  40. /**
  41. * Purge from repository all snapshots older than the specified days in the repository configuration.
  42. */
  43. public class DaysOldRepositoryPurge
  44. extends AbstractRepositoryPurge
  45. {
  46. private SimpleDateFormat timestampParser;
  47. private int daysOlder;
  48. private int retentionCount;
  49. public DaysOldRepositoryPurge( ManagedRepositoryContent repository, int daysOlder, int retentionCount,
  50. RepositorySession repositorySession, List<RepositoryListener> listeners )
  51. {
  52. super( repository, repositorySession, listeners );
  53. this.daysOlder = daysOlder;
  54. this.retentionCount = retentionCount;
  55. timestampParser = new SimpleDateFormat( "yyyyMMdd.HHmmss" );
  56. timestampParser.setTimeZone( DateUtils.UTC_TIME_ZONE );
  57. }
  58. public void process( String path )
  59. throws RepositoryPurgeException
  60. {
  61. try
  62. {
  63. File artifactFile = new File( repository.getRepoRoot(), path );
  64. if ( !artifactFile.exists() )
  65. {
  66. return;
  67. }
  68. ArtifactReference artifact = repository.toArtifactReference( path );
  69. Calendar olderThanThisDate = Calendar.getInstance( DateUtils.UTC_TIME_ZONE );
  70. olderThanThisDate.add( Calendar.DATE, -daysOlder );
  71. // respect retention count
  72. VersionedReference reference = new VersionedReference();
  73. reference.setGroupId( artifact.getGroupId() );
  74. reference.setArtifactId( artifact.getArtifactId() );
  75. reference.setVersion( artifact.getVersion() );
  76. List<String> versions = new ArrayList<>( repository.getVersions( reference ) );
  77. Collections.sort( versions, VersionComparator.getInstance() );
  78. if ( retentionCount > versions.size() )
  79. {
  80. // Done. nothing to do here. skip it.
  81. return;
  82. }
  83. int countToPurge = versions.size() - retentionCount;
  84. for ( String version : versions )
  85. {
  86. if ( countToPurge-- <= 0 )
  87. {
  88. break;
  89. }
  90. ArtifactReference newArtifactReference = repository.toArtifactReference(
  91. artifactFile.getAbsolutePath() );
  92. newArtifactReference.setVersion( version );
  93. File newArtifactFile = repository.toFile( newArtifactReference );
  94. // Is this a generic snapshot "1.0-SNAPSHOT" ?
  95. if ( VersionUtil.isGenericSnapshot( newArtifactReference.getVersion() ) )
  96. {
  97. if ( newArtifactFile.lastModified() < olderThanThisDate.getTimeInMillis() )
  98. {
  99. doPurgeAllRelated( newArtifactReference );
  100. }
  101. }
  102. // Is this a timestamp snapshot "1.0-20070822.123456-42" ?
  103. else if ( VersionUtil.isUniqueSnapshot( newArtifactReference.getVersion() ) )
  104. {
  105. Calendar timestampCal = uniqueSnapshotToCalendar( newArtifactReference.getVersion() );
  106. if ( timestampCal.getTimeInMillis() < olderThanThisDate.getTimeInMillis() )
  107. {
  108. doPurgeAllRelated( newArtifactReference );
  109. }
  110. }
  111. }
  112. }
  113. catch ( ContentNotFoundException e )
  114. {
  115. throw new RepositoryPurgeException( e.getMessage(), e );
  116. }
  117. catch ( LayoutException e )
  118. {
  119. log.debug( "Not processing file that is not an artifact: {}", e.getMessage() );
  120. }
  121. }
  122. private Calendar uniqueSnapshotToCalendar( String version )
  123. {
  124. // The latestVersion will contain the full version string "1.0-alpha-5-20070821.213044-8"
  125. // This needs to be broken down into ${base}-${timestamp}-${build_number}
  126. Matcher m = VersionUtil.UNIQUE_SNAPSHOT_PATTERN.matcher( version );
  127. if ( m.matches() )
  128. {
  129. Matcher mtimestamp = VersionUtil.TIMESTAMP_PATTERN.matcher( m.group( 2 ) );
  130. if ( mtimestamp.matches() )
  131. {
  132. String tsDate = mtimestamp.group( 1 );
  133. String tsTime = mtimestamp.group( 2 );
  134. Date versionDate;
  135. try
  136. {
  137. versionDate = timestampParser.parse( tsDate + "." + tsTime );
  138. Calendar cal = Calendar.getInstance( DateUtils.UTC_TIME_ZONE );
  139. cal.setTime( versionDate );
  140. return cal;
  141. }
  142. catch ( ParseException e )
  143. {
  144. // Invalid Date/Time
  145. return null;
  146. }
  147. }
  148. }
  149. return null;
  150. }
  151. private void doPurgeAllRelated( ArtifactReference reference )
  152. {
  153. try
  154. {
  155. Set<ArtifactReference> related = repository.getRelatedArtifacts( reference );
  156. purge( related );
  157. }
  158. catch ( ContentNotFoundException e )
  159. {
  160. // Nothing to do here - it means the repository would have been constructed incorrectly
  161. log.debug( e.getMessage(), e );
  162. }
  163. }
  164. }