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.

RepositoryContentConsumers.java 14KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357
  1. package org.apache.archiva.repository.scanner;
  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.RepositoryAdminException;
  21. import org.apache.archiva.admin.model.admin.ArchivaAdministration;
  22. import org.apache.archiva.common.utils.BaseFile;
  23. import org.apache.archiva.common.utils.PathUtil;
  24. import org.apache.archiva.configuration.ArchivaConfiguration;
  25. import org.apache.archiva.consumers.InvalidRepositoryContentConsumer;
  26. import org.apache.archiva.consumers.KnownRepositoryContentConsumer;
  27. import org.apache.archiva.consumers.functors.ConsumerWantsFilePredicate;
  28. import org.apache.archiva.redback.components.registry.RegistryListener;
  29. import org.apache.archiva.repository.ManagedRepository;
  30. import org.apache.archiva.repository.scanner.functors.ConsumerProcessFileClosure;
  31. import org.apache.archiva.repository.scanner.functors.TriggerBeginScanClosure;
  32. import org.apache.archiva.repository.scanner.functors.TriggerScanCompletedClosure;
  33. import org.apache.commons.collections.Closure;
  34. import org.apache.commons.collections.CollectionUtils;
  35. import org.apache.commons.collections.functors.IfClosure;
  36. import org.springframework.beans.BeansException;
  37. import org.springframework.context.ApplicationContext;
  38. import org.springframework.context.ApplicationContextAware;
  39. import org.springframework.stereotype.Service;
  40. import javax.inject.Inject;
  41. import java.nio.file.Path;
  42. import java.util.ArrayList;
  43. import java.util.Date;
  44. import java.util.HashMap;
  45. import java.util.List;
  46. import java.util.Map;
  47. /**
  48. * RepositoryContentConsumerUtil
  49. */
  50. @Service("repositoryContentConsumers")
  51. public class RepositoryContentConsumers
  52. implements ApplicationContextAware
  53. {
  54. @Inject
  55. private ApplicationContext applicationContext;
  56. private ArchivaAdministration archivaAdministration;
  57. private List<KnownRepositoryContentConsumer> selectedKnownConsumers;
  58. private List<InvalidRepositoryContentConsumer> selectedInvalidConsumers;
  59. @Inject
  60. private ArchivaConfiguration archivaConfiguration;
  61. @Inject
  62. public RepositoryContentConsumers( ArchivaAdministration archivaAdministration )
  63. {
  64. this.archivaAdministration = archivaAdministration;
  65. }
  66. @Override
  67. public void setApplicationContext( ApplicationContext applicationContext )
  68. throws BeansException
  69. {
  70. this.applicationContext = applicationContext;
  71. }
  72. /**
  73. * <p>
  74. * Get the list of Ids associated with those {@link KnownRepositoryContentConsumer} that have
  75. * been selected in the configuration to execute.
  76. * </p>
  77. * <p>
  78. * NOTE: This list can be larger and contain entries that might not exist or be available
  79. * in the classpath, or as a component.
  80. * </p>
  81. *
  82. * @return the list of consumer ids that have been selected by the configuration.
  83. */
  84. public List<String> getSelectedKnownConsumerIds()
  85. throws RepositoryAdminException
  86. {
  87. return archivaAdministration.getKnownContentConsumers();
  88. }
  89. /**
  90. * <p>
  91. * Get the list of Ids associated with those {@link InvalidRepositoryContentConsumer} that have
  92. * been selected in the configuration to execute.
  93. * </p>
  94. * <p>
  95. * NOTE: This list can be larger and contain entries that might not exist or be available
  96. * in the classpath, or as a component.
  97. * </p>
  98. *
  99. * @return the list of consumer ids that have been selected by the configuration.
  100. */
  101. public List<String> getSelectedInvalidConsumerIds()
  102. throws RepositoryAdminException
  103. {
  104. return archivaAdministration.getInvalidContentConsumers();
  105. }
  106. /**
  107. * Get the map of {@link String} ids to {@link KnownRepositoryContentConsumer} implementations,
  108. * for those consumers that have been selected according to the active configuration.
  109. *
  110. * @return the map of String ids to {@link KnownRepositoryContentConsumer} objects.
  111. */
  112. public Map<String, KnownRepositoryContentConsumer> getSelectedKnownConsumersMap()
  113. throws RepositoryAdminException
  114. {
  115. Map<String, KnownRepositoryContentConsumer> consumerMap = new HashMap<>();
  116. for ( KnownRepositoryContentConsumer consumer : getSelectedKnownConsumers() )
  117. {
  118. consumerMap.put( consumer.getId(), consumer );
  119. }
  120. return consumerMap;
  121. }
  122. /**
  123. * Get the map of {@link String} ids to {@link InvalidRepositoryContentConsumer} implementations,
  124. * for those consumers that have been selected according to the active configuration.
  125. *
  126. * @return the map of String ids to {@link InvalidRepositoryContentConsumer} objects.
  127. */
  128. public Map<String, InvalidRepositoryContentConsumer> getSelectedInvalidConsumersMap()
  129. throws RepositoryAdminException
  130. {
  131. Map<String, InvalidRepositoryContentConsumer> consumerMap = new HashMap<>();
  132. for ( InvalidRepositoryContentConsumer consumer : getSelectedInvalidConsumers() )
  133. {
  134. consumerMap.put( consumer.getId(), consumer );
  135. }
  136. return consumerMap;
  137. }
  138. /**
  139. * Get the list of {@link KnownRepositoryContentConsumer} objects that are
  140. * selected according to the active configuration.
  141. *
  142. * @return the list of {@link KnownRepositoryContentConsumer} that have been selected
  143. * by the active configuration.
  144. */
  145. public List<KnownRepositoryContentConsumer> getSelectedKnownConsumers()
  146. throws RepositoryAdminException
  147. {
  148. // FIXME only for testing
  149. if ( selectedKnownConsumers != null )
  150. {
  151. return selectedKnownConsumers;
  152. }
  153. List<KnownRepositoryContentConsumer> ret = new ArrayList<>();
  154. List<String> knownSelected = getSelectedKnownConsumerIds();
  155. for ( KnownRepositoryContentConsumer consumer : getAvailableKnownConsumers() )
  156. {
  157. if ( knownSelected.contains( consumer.getId() ) )
  158. {
  159. ret.add( consumer );
  160. }
  161. }
  162. return ret;
  163. }
  164. public void releaseSelectedKnownConsumers( List<KnownRepositoryContentConsumer> repositoryContentConsumers )
  165. {
  166. if ( repositoryContentConsumers == null )
  167. {
  168. return;
  169. }
  170. for ( KnownRepositoryContentConsumer knownRepositoryContentConsumer : repositoryContentConsumers )
  171. {
  172. if ( RegistryListener.class.isAssignableFrom( knownRepositoryContentConsumer.getClass() ) )
  173. {
  174. archivaConfiguration.removeChangeListener(
  175. RegistryListener.class.cast( knownRepositoryContentConsumer ) );
  176. }
  177. }
  178. }
  179. /**
  180. * Get the list of {@link InvalidRepositoryContentConsumer} objects that are
  181. * selected according to the active configuration.
  182. *
  183. * @return the list of {@link InvalidRepositoryContentConsumer} that have been selected
  184. * by the active configuration.
  185. */
  186. public synchronized List<InvalidRepositoryContentConsumer> getSelectedInvalidConsumers()
  187. throws RepositoryAdminException
  188. {
  189. // FIXME only for testing
  190. if ( selectedInvalidConsumers != null )
  191. {
  192. return selectedInvalidConsumers;
  193. }
  194. List<InvalidRepositoryContentConsumer> ret = new ArrayList<>();
  195. List<String> invalidSelected = getSelectedInvalidConsumerIds();
  196. for ( InvalidRepositoryContentConsumer consumer : getAvailableInvalidConsumers() )
  197. {
  198. if ( invalidSelected.contains( consumer.getId() ) )
  199. {
  200. ret.add( consumer );
  201. }
  202. }
  203. return ret;
  204. }
  205. /**
  206. * Get the list of {@link KnownRepositoryContentConsumer} objects that are
  207. * available and present in the classpath and as components in the IoC.
  208. *
  209. * @return the list of all available {@link KnownRepositoryContentConsumer} present in the classpath
  210. * and as a component in the IoC.
  211. */
  212. public List<KnownRepositoryContentConsumer> getAvailableKnownConsumers()
  213. {
  214. return new ArrayList<>( applicationContext.getBeansOfType( KnownRepositoryContentConsumer.class ).values() );
  215. }
  216. /**
  217. * Get the list of {@link InvalidRepositoryContentConsumer} objects that are
  218. * available and present in the classpath and as components in the IoC.
  219. *
  220. * @return the list of all available {@link InvalidRepositoryContentConsumer} present in the classpath
  221. * and as a component in the IoC.
  222. */
  223. public List<InvalidRepositoryContentConsumer> getAvailableInvalidConsumers()
  224. {
  225. return new ArrayList<>( applicationContext.getBeansOfType( InvalidRepositoryContentConsumer.class ).values() );
  226. }
  227. /**
  228. * A convienence method to execute all of the active selected consumers for a
  229. * particular arbitrary file.
  230. * NOTE: Make sure that there is no repository scanning task executing before invoking this so as to prevent
  231. * the index writer/reader of the current index-content consumer executing from getting closed. For an example,
  232. * see ArchivaDavResource#executeConsumers( File ).
  233. *
  234. * @param repository the repository configuration to use.
  235. * @param localFile the local file to execute the consumers against.
  236. * @param updateRelatedArtifacts TODO
  237. */
  238. public void executeConsumers( ManagedRepository repository, Path localFile, boolean updateRelatedArtifacts )
  239. throws RepositoryAdminException
  240. {
  241. List<KnownRepositoryContentConsumer> selectedKnownConsumers = null;
  242. // Run the repository consumers
  243. try
  244. {
  245. Closure triggerBeginScan = new TriggerBeginScanClosure( repository, getStartTime(), false );
  246. selectedKnownConsumers = getSelectedKnownConsumers();
  247. // MRM-1212/MRM-1197
  248. // - do not create missing/fix invalid checksums and update metadata when deploying from webdav since these are uploaded by maven
  249. if ( !updateRelatedArtifacts )
  250. {
  251. List<KnownRepositoryContentConsumer> clone = new ArrayList<>();
  252. clone.addAll( selectedKnownConsumers );
  253. for ( KnownRepositoryContentConsumer consumer : clone )
  254. {
  255. if ( consumer.getId().equals( "create-missing-checksums" ) || consumer.getId().equals(
  256. "metadata-updater" ) )
  257. {
  258. selectedKnownConsumers.remove( consumer );
  259. }
  260. }
  261. }
  262. List<InvalidRepositoryContentConsumer> selectedInvalidConsumers = getSelectedInvalidConsumers();
  263. CollectionUtils.forAllDo( selectedKnownConsumers, triggerBeginScan );
  264. CollectionUtils.forAllDo( selectedInvalidConsumers, triggerBeginScan );
  265. // yuck. In case you can't read this, it says
  266. // "process the file if the consumer has it in the includes list, and not in the excludes list"
  267. Path repoPath = PathUtil.getPathFromUri( repository.getLocation() );
  268. BaseFile baseFile = new BaseFile( repoPath.toString(), localFile.toFile() );
  269. ConsumerWantsFilePredicate predicate = new ConsumerWantsFilePredicate( repository );
  270. predicate.setBasefile( baseFile );
  271. predicate.setCaseSensitive( false );
  272. ConsumerProcessFileClosure closure = new ConsumerProcessFileClosure();
  273. closure.setBasefile( baseFile );
  274. closure.setExecuteOnEntireRepo( false );
  275. Closure processIfWanted = IfClosure.getInstance( predicate, closure );
  276. CollectionUtils.forAllDo( selectedKnownConsumers, processIfWanted );
  277. if ( predicate.getWantedFileCount() <= 0 )
  278. {
  279. // Nothing known processed this file. It is invalid!
  280. CollectionUtils.forAllDo( selectedInvalidConsumers, closure );
  281. }
  282. TriggerScanCompletedClosure scanCompletedClosure = new TriggerScanCompletedClosure( repository, false );
  283. CollectionUtils.forAllDo( selectedKnownConsumers, scanCompletedClosure );
  284. }
  285. finally
  286. {
  287. /* TODO: This is never called by the repository scanner instance, so not calling here either - but it probably should be?
  288. CollectionUtils.forAllDo( availableKnownConsumers, triggerCompleteScan );
  289. CollectionUtils.forAllDo( availableInvalidConsumers, triggerCompleteScan );
  290. */
  291. releaseSelectedKnownConsumers( selectedKnownConsumers );
  292. }
  293. }
  294. public void setSelectedKnownConsumers( List<KnownRepositoryContentConsumer> selectedKnownConsumers )
  295. {
  296. this.selectedKnownConsumers = selectedKnownConsumers;
  297. }
  298. public void setSelectedInvalidConsumers( List<InvalidRepositoryContentConsumer> selectedInvalidConsumers )
  299. {
  300. this.selectedInvalidConsumers = selectedInvalidConsumers;
  301. }
  302. protected Date getStartTime()
  303. {
  304. return new Date( System.currentTimeMillis() );
  305. }
  306. public void setArchivaAdministration( ArchivaAdministration archivaAdministration )
  307. {
  308. this.archivaAdministration = archivaAdministration;
  309. }
  310. }