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.

MetadataUpdaterConsumer.java 11KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324
  1. package org.apache.archiva.consumers.core;
  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.admin.model.beans.ManagedRepository;
  21. import org.apache.archiva.configuration.ArchivaConfiguration;
  22. import org.apache.archiva.configuration.ConfigurationNames;
  23. import org.apache.archiva.configuration.FileTypes;
  24. import org.apache.archiva.consumers.AbstractMonitoredConsumer;
  25. import org.apache.archiva.consumers.ConsumerException;
  26. import org.apache.archiva.consumers.KnownRepositoryContentConsumer;
  27. import org.apache.archiva.model.ArtifactReference;
  28. import org.apache.archiva.model.ProjectReference;
  29. import org.apache.archiva.model.VersionedReference;
  30. import org.apache.archiva.repository.ContentNotFoundException;
  31. import org.apache.archiva.repository.ManagedRepositoryContent;
  32. import org.apache.archiva.repository.RepositoryContentFactory;
  33. import org.apache.archiva.repository.RepositoryException;
  34. import org.apache.archiva.repository.RepositoryNotFoundException;
  35. import org.apache.archiva.repository.layout.LayoutException;
  36. import org.apache.archiva.repository.metadata.MetadataTools;
  37. import org.apache.archiva.repository.metadata.RepositoryMetadataException;
  38. import org.apache.archiva.redback.components.registry.Registry;
  39. import org.apache.archiva.redback.components.registry.RegistryListener;
  40. import org.slf4j.Logger;
  41. import org.slf4j.LoggerFactory;
  42. import org.springframework.context.annotation.Scope;
  43. import org.springframework.stereotype.Service;
  44. import javax.annotation.PostConstruct;
  45. import javax.inject.Inject;
  46. import java.io.File;
  47. import java.io.IOException;
  48. import java.util.ArrayList;
  49. import java.util.Date;
  50. import java.util.List;
  51. /**
  52. * MetadataUpdaterConsumer will create and update the metadata present within the repository.
  53. *
  54. *
  55. */
  56. @Service( "knownRepositoryContentConsumer#metadata-updater" )
  57. @Scope( "prototype" )
  58. public class MetadataUpdaterConsumer
  59. extends AbstractMonitoredConsumer
  60. implements KnownRepositoryContentConsumer, RegistryListener
  61. {
  62. private Logger log = LoggerFactory.getLogger( MetadataUpdaterConsumer.class );
  63. /**
  64. * default-value="metadata-updater"
  65. */
  66. private String id = "metadata-updater";
  67. /**
  68. * default-value="Update / Create maven-metadata.xml files"
  69. */
  70. private String description = "Update / Create maven-metadata.xml files";
  71. /**
  72. *
  73. */
  74. @Inject
  75. private RepositoryContentFactory repositoryFactory;
  76. /**
  77. *
  78. */
  79. @Inject
  80. private MetadataTools metadataTools;
  81. /**
  82. *
  83. */
  84. @Inject
  85. private ArchivaConfiguration configuration;
  86. /**
  87. *
  88. */
  89. @Inject
  90. private FileTypes filetypes;
  91. private static final String TYPE_METADATA_BAD_INTERNAL_REF = "metadata-bad-internal-ref";
  92. private static final String TYPE_METADATA_WRITE_FAILURE = "metadata-write-failure";
  93. private static final String TYPE_METADATA_IO = "metadata-io-warning";
  94. private ManagedRepositoryContent repository;
  95. private File repositoryDir;
  96. private List<String> includes = new ArrayList<>( 0 );
  97. private long scanStartTimestamp = 0;
  98. public String getDescription()
  99. {
  100. return description;
  101. }
  102. public String getId()
  103. {
  104. return id;
  105. }
  106. public void setIncludes( List<String> includes )
  107. {
  108. this.includes = includes;
  109. }
  110. public void beginScan( ManagedRepository repoConfig, Date whenGathered )
  111. throws ConsumerException
  112. {
  113. try
  114. {
  115. this.repository = repositoryFactory.getManagedRepositoryContent( repoConfig.getId() );
  116. this.repositoryDir = new File( repository.getRepoRoot() );
  117. this.scanStartTimestamp = System.currentTimeMillis();
  118. }
  119. catch ( RepositoryNotFoundException e )
  120. {
  121. throw new ConsumerException( e.getMessage(), e );
  122. }
  123. catch ( RepositoryException e )
  124. {
  125. throw new ConsumerException( e.getMessage(), e );
  126. }
  127. }
  128. public void beginScan( ManagedRepository repository, Date whenGathered, boolean executeOnEntireRepo )
  129. throws ConsumerException
  130. {
  131. beginScan( repository, whenGathered );
  132. }
  133. public void completeScan()
  134. {
  135. /* do nothing here */
  136. }
  137. public void completeScan( boolean executeOnEntireRepo )
  138. {
  139. completeScan();
  140. }
  141. public List<String> getExcludes()
  142. {
  143. return getDefaultArtifactExclusions();
  144. }
  145. public List<String> getIncludes()
  146. {
  147. return this.includes;
  148. }
  149. public void processFile( String path )
  150. throws ConsumerException
  151. {
  152. // Ignore paths like .index etc
  153. if ( !path.startsWith( "." ) )
  154. {
  155. try
  156. {
  157. ArtifactReference artifact = repository.toArtifactReference( path );
  158. updateVersionMetadata( artifact, path );
  159. updateProjectMetadata( artifact, path );
  160. }
  161. catch ( LayoutException e )
  162. {
  163. log.info( "Not processing path that is not an artifact: {} ({})", path, e.getMessage() );
  164. }
  165. }
  166. }
  167. public void processFile( String path, boolean executeOnEntireRepo )
  168. throws Exception
  169. {
  170. processFile( path );
  171. }
  172. private void updateProjectMetadata( ArtifactReference artifact, String path )
  173. {
  174. ProjectReference projectRef = new ProjectReference();
  175. projectRef.setGroupId( artifact.getGroupId() );
  176. projectRef.setArtifactId( artifact.getArtifactId() );
  177. try
  178. {
  179. String metadataPath = this.metadataTools.toPath( projectRef );
  180. File projectMetadata = new File( this.repositoryDir, metadataPath );
  181. if ( projectMetadata.exists() && ( projectMetadata.lastModified() >= this.scanStartTimestamp ) )
  182. {
  183. // This metadata is up to date. skip it.
  184. log.debug( "Skipping uptodate metadata: {}", this.metadataTools.toPath( projectRef ) );
  185. return;
  186. }
  187. metadataTools.updateMetadata( this.repository, projectRef );
  188. log.debug( "Updated metadata: {}", this.metadataTools.toPath( projectRef ) );
  189. }
  190. catch ( LayoutException e )
  191. {
  192. triggerConsumerWarning( TYPE_METADATA_BAD_INTERNAL_REF,
  193. "Unable to convert path [" + path + "] to an internal project reference: "
  194. + e.getMessage() );
  195. }
  196. catch ( RepositoryMetadataException e )
  197. {
  198. triggerConsumerError( TYPE_METADATA_WRITE_FAILURE,
  199. "Unable to write project metadata for artifact [" + path + "]: " + e.getMessage() );
  200. }
  201. catch ( IOException e )
  202. {
  203. triggerConsumerWarning( TYPE_METADATA_IO,
  204. "Project metadata not written due to IO warning: " + e.getMessage() );
  205. }
  206. catch ( ContentNotFoundException e )
  207. {
  208. triggerConsumerWarning( TYPE_METADATA_IO,
  209. "Project metadata not written because no versions were found to update: "
  210. + e.getMessage() );
  211. }
  212. }
  213. private void updateVersionMetadata( ArtifactReference artifact, String path )
  214. {
  215. VersionedReference versionRef = new VersionedReference();
  216. versionRef.setGroupId( artifact.getGroupId() );
  217. versionRef.setArtifactId( artifact.getArtifactId() );
  218. versionRef.setVersion( artifact.getVersion() );
  219. try
  220. {
  221. String metadataPath = this.metadataTools.toPath( versionRef );
  222. File projectMetadata = new File( this.repositoryDir, metadataPath );
  223. if ( projectMetadata.exists() && ( projectMetadata.lastModified() >= this.scanStartTimestamp ) )
  224. {
  225. // This metadata is up to date. skip it.
  226. log.debug( "Skipping uptodate metadata: {}", this.metadataTools.toPath( versionRef ) );
  227. return;
  228. }
  229. metadataTools.updateMetadata( this.repository, versionRef );
  230. log.debug( "Updated metadata: {}", this.metadataTools.toPath( versionRef ) );
  231. }
  232. catch ( LayoutException e )
  233. {
  234. triggerConsumerWarning( TYPE_METADATA_BAD_INTERNAL_REF,
  235. "Unable to convert path [" + path + "] to an internal version reference: "
  236. + e.getMessage() );
  237. }
  238. catch ( RepositoryMetadataException e )
  239. {
  240. triggerConsumerError( TYPE_METADATA_WRITE_FAILURE,
  241. "Unable to write version metadata for artifact [" + path + "]: " + e.getMessage() );
  242. }
  243. catch ( IOException e )
  244. {
  245. triggerConsumerWarning( TYPE_METADATA_IO,
  246. "Version metadata not written due to IO warning: " + e.getMessage() );
  247. }
  248. catch ( ContentNotFoundException e )
  249. {
  250. triggerConsumerWarning( TYPE_METADATA_IO,
  251. "Version metadata not written because no versions were found to update: "
  252. + e.getMessage() );
  253. }
  254. }
  255. public boolean isPermanent()
  256. {
  257. return false;
  258. }
  259. public void afterConfigurationChange( Registry registry, String propertyName, Object propertyValue )
  260. {
  261. if ( ConfigurationNames.isRepositoryScanning( propertyName ) )
  262. {
  263. initIncludes();
  264. }
  265. }
  266. public void beforeConfigurationChange( Registry registry, String propertyName, Object propertyValue )
  267. {
  268. /* do nothing here */
  269. }
  270. private void initIncludes()
  271. {
  272. includes = new ArrayList<String>( filetypes.getFileTypePatterns( FileTypes.ARTIFACTS ) );
  273. }
  274. @PostConstruct
  275. public void initialize()
  276. {
  277. configuration.addChangeListener( this );
  278. initIncludes();
  279. }
  280. }