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.7KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181
  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.common.utils.VersionComparator;
  21. import org.apache.archiva.common.utils.VersionUtil;
  22. import org.apache.archiva.metadata.repository.RepositorySession;
  23. import org.apache.archiva.model.ArtifactReference;
  24. import org.apache.archiva.model.VersionedReference;
  25. import org.apache.archiva.repository.ContentNotFoundException;
  26. import org.apache.archiva.repository.ManagedRepositoryContent;
  27. import org.apache.archiva.repository.events.RepositoryListener;
  28. import org.apache.archiva.repository.layout.LayoutException;
  29. import org.apache.commons.lang.time.DateUtils;
  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.HashSet;
  38. import java.util.List;
  39. import java.util.Set;
  40. import java.util.regex.Matcher;
  41. /**
  42. * Purge from repository all snapshots older than the specified days in the repository configuration.
  43. */
  44. public class DaysOldRepositoryPurge
  45. extends AbstractRepositoryPurge
  46. {
  47. private SimpleDateFormat timestampParser;
  48. private int daysOlder;
  49. private int retentionCount;
  50. public DaysOldRepositoryPurge( ManagedRepositoryContent repository, int daysOlder, int retentionCount,
  51. RepositorySession repositorySession, List<RepositoryListener> listeners )
  52. {
  53. super( repository, repositorySession, listeners );
  54. this.daysOlder = daysOlder;
  55. this.retentionCount = retentionCount;
  56. timestampParser = new SimpleDateFormat( "yyyyMMdd.HHmmss" );
  57. timestampParser.setTimeZone( DateUtils.UTC_TIME_ZONE );
  58. }
  59. @Override
  60. public void process( String path )
  61. throws RepositoryPurgeException
  62. {
  63. try
  64. {
  65. File artifactFile = new File( repository.getRepoRoot( ), path );
  66. if ( !artifactFile.exists( ) )
  67. {
  68. return;
  69. }
  70. ArtifactReference artifact = repository.toArtifactReference( path );
  71. Calendar olderThanThisDate = Calendar.getInstance( DateUtils.UTC_TIME_ZONE );
  72. olderThanThisDate.add( Calendar.DATE, -daysOlder );
  73. // respect retention count
  74. VersionedReference reference = new VersionedReference( );
  75. reference.setGroupId( artifact.getGroupId( ) );
  76. reference.setArtifactId( artifact.getArtifactId( ) );
  77. reference.setVersion( artifact.getVersion( ) );
  78. List<String> versions = new ArrayList<>( repository.getVersions( reference ) );
  79. Collections.sort( versions, VersionComparator.getInstance( ) );
  80. if ( retentionCount > versions.size( ) )
  81. {
  82. // Done. nothing to do here. skip it.
  83. return;
  84. }
  85. int countToPurge = versions.size( ) - retentionCount;
  86. Set<ArtifactReference> artifactsToDelete = new HashSet<>( );
  87. for ( String version : versions )
  88. {
  89. if ( countToPurge-- <= 0 )
  90. {
  91. break;
  92. }
  93. ArtifactReference newArtifactReference = repository.toArtifactReference(
  94. artifactFile.getAbsolutePath( ) );
  95. newArtifactReference.setVersion( version );
  96. File newArtifactFile = repository.toFile( newArtifactReference );
  97. // Is this a generic snapshot "1.0-SNAPSHOT" ?
  98. if ( VersionUtil.isGenericSnapshot( newArtifactReference.getVersion( ) ) )
  99. {
  100. if ( newArtifactFile.lastModified( ) < olderThanThisDate.getTimeInMillis( ) )
  101. {
  102. artifactsToDelete.addAll( repository.getRelatedArtifacts( newArtifactReference ) );
  103. }
  104. }
  105. // Is this a timestamp snapshot "1.0-20070822.123456-42" ?
  106. else if ( VersionUtil.isUniqueSnapshot( newArtifactReference.getVersion( ) ) )
  107. {
  108. Calendar timestampCal = uniqueSnapshotToCalendar( newArtifactReference.getVersion( ) );
  109. if ( timestampCal.getTimeInMillis( ) < olderThanThisDate.getTimeInMillis( ) )
  110. {
  111. artifactsToDelete.addAll( repository.getRelatedArtifacts( newArtifactReference ) );
  112. }
  113. }
  114. }
  115. purge( artifactsToDelete );
  116. }
  117. catch ( ContentNotFoundException e )
  118. {
  119. throw new RepositoryPurgeException( e.getMessage( ), e );
  120. }
  121. catch ( LayoutException e )
  122. {
  123. log.debug( "Not processing file that is not an artifact: {}", e.getMessage( ) );
  124. }
  125. }
  126. private Calendar uniqueSnapshotToCalendar( String version )
  127. {
  128. // The latestVersion will contain the full version string "1.0-alpha-5-20070821.213044-8"
  129. // This needs to be broken down into ${base}-${timestamp}-${build_number}
  130. Matcher m = VersionUtil.UNIQUE_SNAPSHOT_PATTERN.matcher( version );
  131. if ( m.matches( ) )
  132. {
  133. Matcher mtimestamp = VersionUtil.TIMESTAMP_PATTERN.matcher( m.group( 2 ) );
  134. if ( mtimestamp.matches( ) )
  135. {
  136. String tsDate = mtimestamp.group( 1 );
  137. String tsTime = mtimestamp.group( 2 );
  138. Date versionDate;
  139. try
  140. {
  141. versionDate = timestampParser.parse( tsDate + "." + tsTime );
  142. Calendar cal = Calendar.getInstance( DateUtils.UTC_TIME_ZONE );
  143. cal.setTime( versionDate );
  144. return cal;
  145. }
  146. catch ( ParseException e )
  147. {
  148. // Invalid Date/Time
  149. return null;
  150. }
  151. }
  152. }
  153. return null;
  154. }
  155. }