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

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