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.

DefaultRepositoryTaskAdministration.java 17KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360
  1. package org.apache.archiva.admin.repository.admin;
  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. * Unless required by applicable law or agreed to in writing,
  13. * software distributed under the License is distributed on an
  14. * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
  15. * KIND, either express or implied. See the License for the
  16. * specific language governing permissions and limitations
  17. * under the License.
  18. */
  19. import org.apache.archiva.admin.model.RepositoryAdminException;
  20. import org.apache.archiva.admin.model.admin.RepositoryTaskAdministration;
  21. import org.apache.archiva.admin.model.beans.IndexingTask;
  22. import org.apache.archiva.admin.model.beans.MetadataScanTask;
  23. import org.apache.archiva.admin.model.beans.RepositoryTaskInfo;
  24. import org.apache.archiva.admin.model.beans.ScanStatus;
  25. import org.apache.archiva.components.taskqueue.TaskQueueException;
  26. import org.apache.archiva.components.taskqueue.execution.TaskQueueExecutor;
  27. import org.apache.archiva.metadata.repository.stats.model.RepositoryStatisticsManager;
  28. import org.apache.archiva.repository.RepositoryRegistry;
  29. import org.apache.archiva.repository.storage.StorageAsset;
  30. import org.apache.archiva.scheduler.indexing.ArtifactIndexingTask;
  31. import org.apache.archiva.scheduler.indexing.IndexingArchivaTaskScheduler;
  32. import org.apache.archiva.scheduler.repository.model.RepositoryArchivaTaskScheduler;
  33. import org.apache.archiva.scheduler.repository.model.RepositoryTask;
  34. import org.apache.commons.lang3.StringUtils;
  35. import org.slf4j.Logger;
  36. import org.slf4j.LoggerFactory;
  37. import org.springframework.stereotype.Service;
  38. import javax.inject.Named;
  39. import java.util.ArrayList;
  40. import java.util.List;
  41. import java.util.stream.Collectors;
  42. /**
  43. * @author Martin Stockhammer <martin_s@apache.org>
  44. */
  45. @Service( "repositoryTaskAdministration#default" )
  46. public class DefaultRepositoryTaskAdministration implements RepositoryTaskAdministration
  47. {
  48. private static final Logger log = LoggerFactory.getLogger( DefaultRepositoryTaskAdministration.class );
  49. final RepositoryRegistry repositoryRegistry;
  50. final
  51. TaskQueueExecutor<ArtifactIndexingTask> indexingTaskExecutor;
  52. final
  53. TaskQueueExecutor<RepositoryTask> scanningTaskExecutor;
  54. private final RepositoryArchivaTaskScheduler repositoryArchivaTaskScheduler;
  55. private final IndexingArchivaTaskScheduler indexingArchivaTaskScheduler;
  56. public DefaultRepositoryTaskAdministration( RepositoryRegistry repositoryRegistry,
  57. @Named( value = "taskQueueExecutor#indexing" ) TaskQueueExecutor<ArtifactIndexingTask> indexingTaskExecutor,
  58. @Named( value = "taskQueueExecutor#repository-scanning" ) TaskQueueExecutor<RepositoryTask> scanningTaskExecutor,
  59. @Named( value = "archivaTaskScheduler#repository" ) RepositoryArchivaTaskScheduler repositoryArchivaTaskScheduler,
  60. @Named( value = "archivaTaskScheduler#indexing" ) IndexingArchivaTaskScheduler indexingArchivaTaskScheduler)
  61. {
  62. this.repositoryRegistry = repositoryRegistry;
  63. this.indexingTaskExecutor = indexingTaskExecutor;
  64. this.scanningTaskExecutor = scanningTaskExecutor;
  65. this.repositoryArchivaTaskScheduler = repositoryArchivaTaskScheduler;
  66. this.indexingArchivaTaskScheduler = indexingArchivaTaskScheduler;
  67. }
  68. @Override
  69. public void scheduleFullScan( String repositoryId ) throws RepositoryAdminException
  70. {
  71. if ( StringUtils.isEmpty( repositoryId ) ) {
  72. throw RepositoryAdminException.ofKey( "repository.id.invalid", "" );
  73. }
  74. try
  75. {
  76. org.apache.archiva.repository.ManagedRepository repository = repositoryRegistry.getManagedRepository( repositoryId );
  77. if (repository==null) {
  78. throw RepositoryAdminException.ofKey( "repository.not_found", repositoryId );
  79. }
  80. ArtifactIndexingTask task =
  81. new ArtifactIndexingTask( repository, null, ArtifactIndexingTask.Action.FINISH, repository.getIndexingContext( ) );
  82. task.setExecuteOnEntireRepo( true );
  83. task.setOnlyUpdate( false );
  84. indexingArchivaTaskScheduler.queueTask( task );
  85. repositoryArchivaTaskScheduler.queueTask( new RepositoryTask( repositoryId, true ) );
  86. }
  87. catch ( TaskQueueException e )
  88. {
  89. log.error( "Could not queue the task: {}", e.getMessage( ), e );
  90. throw RepositoryAdminException.ofKey( "repository.scan.task_queue_error", e, e.getMessage( ) );
  91. }
  92. }
  93. @Override
  94. public void scheduleIndexFullScan( String repositoryId ) throws RepositoryAdminException
  95. {
  96. if ( StringUtils.isEmpty( repositoryId ) ) {
  97. throw RepositoryAdminException.ofKey( "repository.id.invalid", "" );
  98. }
  99. try
  100. {
  101. org.apache.archiva.repository.ManagedRepository repository = repositoryRegistry.getManagedRepository( repositoryId );
  102. if (repository==null) {
  103. throw RepositoryAdminException.ofKey( "repository.not_found", repositoryId );
  104. }
  105. ArtifactIndexingTask task =
  106. new ArtifactIndexingTask( repository, null, ArtifactIndexingTask.Action.FINISH, repository.getIndexingContext( ) );
  107. task.setExecuteOnEntireRepo( true );
  108. task.setOnlyUpdate( false );
  109. indexingArchivaTaskScheduler.queueTask( task );
  110. }
  111. catch ( TaskQueueException e )
  112. {
  113. log.error( "Could not queue the task: {}", e.getMessage( ), e );
  114. throw RepositoryAdminException.ofKey( "repository.scan.task_queue_error", e, e.getMessage( ) );
  115. }
  116. }
  117. @Override
  118. public void scheduleIndexScan( String repositoryId, String relativePath ) throws RepositoryAdminException
  119. {
  120. if ( StringUtils.isEmpty( repositoryId ) ) {
  121. throw RepositoryAdminException.ofKey( "repository.id.invalid", "" );
  122. }
  123. try
  124. {
  125. org.apache.archiva.repository.ManagedRepository repository = repositoryRegistry.getManagedRepository( repositoryId );
  126. if (repository==null) {
  127. throw RepositoryAdminException.ofKey( "repository.not_found", repositoryId );
  128. }
  129. StorageAsset asset = repository.getAsset( relativePath );
  130. if (!asset.exists()) {
  131. throw RepositoryAdminException.ofKey( "repository.file.not_found", repositoryId, relativePath );
  132. }
  133. ArtifactIndexingTask task =
  134. new ArtifactIndexingTask( repository, asset.getFilePath( ), ArtifactIndexingTask.Action.FINISH, repository.getIndexingContext( ) );
  135. task.setExecuteOnEntireRepo( false );
  136. task.setOnlyUpdate( true );
  137. indexingArchivaTaskScheduler.queueTask( task );
  138. }
  139. catch ( TaskQueueException e )
  140. {
  141. log.error( "Could not queue the task: {}", e.getMessage( ), e );
  142. throw RepositoryAdminException.ofKey( "repository.scan.task_queue_error", e, e.getMessage( ) );
  143. }
  144. }
  145. @Override
  146. public void scheduleMetadataFullScan( String repositoryId ) throws RepositoryAdminException
  147. {
  148. if ( StringUtils.isEmpty( repositoryId ) ) {
  149. throw RepositoryAdminException.ofKey( "repository.id.invalid", "" );
  150. }
  151. try
  152. {
  153. org.apache.archiva.repository.ManagedRepository repository = repositoryRegistry.getManagedRepository( repositoryId );
  154. if (repository==null) {
  155. throw RepositoryAdminException.ofKey( "repository.not_found", repositoryId );
  156. }
  157. repositoryArchivaTaskScheduler.queueTask( new RepositoryTask( repositoryId, true ) );
  158. }
  159. catch ( TaskQueueException e )
  160. {
  161. log.error( "Could not queue the task: {}", e.getMessage( ), e );
  162. throw RepositoryAdminException.ofKey( "repository.scan.task_queue_error", e, e.getMessage( ) );
  163. }
  164. }
  165. @Override
  166. public void scheduleMetadataUpdateScan( String repositoryId ) throws RepositoryAdminException
  167. {
  168. if ( StringUtils.isEmpty( repositoryId ) ) {
  169. throw RepositoryAdminException.ofKey( "repository.id.invalid", "" );
  170. }
  171. try
  172. {
  173. org.apache.archiva.repository.ManagedRepository repository = repositoryRegistry.getManagedRepository( repositoryId );
  174. if (repository==null) {
  175. throw RepositoryAdminException.ofKey( "repository.not_found", repositoryId );
  176. }
  177. repositoryArchivaTaskScheduler.queueTask( new RepositoryTask( repositoryId, false ) );
  178. }
  179. catch ( TaskQueueException e )
  180. {
  181. log.error( "Could not queue the task: {}", e.getMessage( ), e );
  182. throw RepositoryAdminException.ofKey( "repository.scan.task_queue_error", e, e.getMessage( ) );
  183. }
  184. }
  185. public static MetadataScanTask getMetadataScanTaskInfo(RepositoryTask repositoryTask) {
  186. MetadataScanTask scanTask = new MetadataScanTask( );
  187. scanTask.setFullScan( repositoryTask.isScanAll());
  188. scanTask.setUpdateRelatedArtifacts( repositoryTask.isUpdateRelatedArtifacts() );
  189. StorageAsset file = repositoryTask.getResourceFile( );
  190. scanTask.setResource( repositoryTask.getResourceFile( )==null?"":repositoryTask.getResourceFile().toString( ) );
  191. scanTask.setMaxExecutionTimeMs( repositoryTask.getMaxExecutionTime() );
  192. scanTask.setRepositoryId( repositoryTask.getRepositoryId( ) );
  193. return scanTask;
  194. }
  195. public static IndexingTask getIndexingTaskInfo(ArtifactIndexingTask repositoryTask) {
  196. IndexingTask indexingTask = new IndexingTask( );
  197. indexingTask.setFullScan( repositoryTask.isExecuteOnEntireRepo());
  198. indexingTask.setUpdateOnly( repositoryTask.isOnlyUpdate() );
  199. indexingTask.setResource( repositoryTask.getResourceFile( )==null?"":repositoryTask.getResourceFile().toString( ) );
  200. indexingTask.setMaxExecutionTimeMs( repositoryTask.getMaxExecutionTime() );
  201. indexingTask.setRepositoryId( repositoryTask.getRepository().getId() );
  202. return indexingTask;
  203. }
  204. public void updateScanInfo( ScanStatus scanStatus, RepositoryTask runningRepositoryTask, List<RepositoryTask> taskQueue) {
  205. List<MetadataScanTask> newScanQueue = new ArrayList<>( );
  206. if (runningRepositoryTask!=null) {
  207. MetadataScanTask taskInfo = getMetadataScanTaskInfo( runningRepositoryTask );
  208. taskInfo.setRunning( true );
  209. newScanQueue.add( 0, taskInfo);
  210. }
  211. newScanQueue.addAll( taskQueue.stream( ).map( task -> getMetadataScanTaskInfo( task ) ).collect( Collectors.toList( ) ) );
  212. scanStatus.setScanQueue( newScanQueue );
  213. }
  214. public void updateIndexInfo( ScanStatus scanStatus, ArtifactIndexingTask runningIndexingTask, List<ArtifactIndexingTask> taskQueue) {
  215. List<IndexingTask> newIndexQueue = new ArrayList<>( );
  216. if (runningIndexingTask!=null) {
  217. IndexingTask taskInfo = getIndexingTaskInfo( runningIndexingTask );
  218. taskInfo.setRunning( true );
  219. newIndexQueue.add(taskInfo );
  220. }
  221. newIndexQueue.addAll( taskQueue.stream( ).map( task -> getIndexingTaskInfo( task ) ).collect( Collectors.toList( ) ) );
  222. scanStatus.setIndexingQueue( newIndexQueue );
  223. }
  224. @Override
  225. public ScanStatus getCurrentScanStatus( String repositoryId ) throws RepositoryAdminException
  226. {
  227. if ( StringUtils.isEmpty( repositoryId ) ) {
  228. throw RepositoryAdminException.ofKey( "repository.id.invalid", "" );
  229. }
  230. org.apache.archiva.repository.ManagedRepository repository = repositoryRegistry.getManagedRepository( repositoryId );
  231. if (repository==null) {
  232. throw RepositoryAdminException.ofKey( "repository.not_found", repositoryId );
  233. }
  234. ScanStatus status = new ScanStatus( );
  235. try
  236. {
  237. RepositoryTask scanTask = scanningTaskExecutor.getCurrentTask( );
  238. if ( scanTask!=null && !repositoryId.equals( scanTask.getRepositoryId( ) ) )
  239. {
  240. scanTask = null;
  241. }
  242. ArtifactIndexingTask indexTask = indexingTaskExecutor.getCurrentTask( );
  243. if ( indexTask!=null && !repositoryId.equals( indexTask.getRepository( ).getId( ) ) )
  244. {
  245. indexTask = null;
  246. }
  247. updateScanInfo( status, scanTask, scanningTaskExecutor.getQueue( ).getQueueSnapshot( ).stream( ).filter( task -> repositoryId.equals( task.getRepositoryId( ) ) ).collect( Collectors.toList( ) ) );
  248. updateIndexInfo( status, indexTask, indexingTaskExecutor.getQueue( ).getQueueSnapshot( ).stream( ).filter( task -> repositoryId.equals( task.getRepository( ).getId( ) ) ).collect( Collectors.toList( ) ) );
  249. return status;
  250. }
  251. catch ( TaskQueueException e )
  252. {
  253. log.error( "Could not get task information: {}", e.getMessage( ), e );
  254. throw RepositoryAdminException.ofKey( "repository.scan.task_retrieval_failed", e.getMessage( ) );
  255. }
  256. }
  257. @Override
  258. public ScanStatus getCurrentScanStatus( ) throws RepositoryAdminException
  259. {
  260. ScanStatus status = new ScanStatus( );
  261. try
  262. {
  263. RepositoryTask scanTask = scanningTaskExecutor.getCurrentTask( );
  264. ArtifactIndexingTask indexTask = indexingTaskExecutor.getCurrentTask( );
  265. updateScanInfo( status, scanTask, scanningTaskExecutor.getQueue( ).getQueueSnapshot() );
  266. updateIndexInfo( status, indexTask, indexingTaskExecutor.getQueue( ).getQueueSnapshot( ) );
  267. return status;
  268. }
  269. catch ( TaskQueueException e )
  270. {
  271. log.error( "Could not get task information: {}", e.getMessage( ), e );
  272. throw RepositoryAdminException.ofKey( "repository.scan.task_retrieval_failed", e.getMessage( ) );
  273. }
  274. }
  275. @Override
  276. public List<RepositoryTaskInfo> cancelTasks( String repositoryId ) throws RepositoryAdminException
  277. {
  278. ArrayList<RepositoryTaskInfo> resultList = new ArrayList<>( );
  279. resultList.addAll( cancelScanTasks( repositoryId ) );
  280. resultList.addAll( cancelIndexTasks( repositoryId ) );
  281. return resultList;
  282. }
  283. @Override
  284. public List<RepositoryTaskInfo> cancelScanTasks( String repositoryId ) throws RepositoryAdminException
  285. {
  286. try
  287. {
  288. ArrayList<RepositoryTaskInfo> resultList = new ArrayList<>( );
  289. List<RepositoryTask> removeTasks = scanningTaskExecutor.getQueue( ).getQueueSnapshot( ).stream( ).filter( task -> repositoryId.equals( task.getRepositoryId() ) ).collect( Collectors.toList( ) );
  290. scanningTaskExecutor.getQueue( ).removeAll( removeTasks );
  291. RepositoryTask currentTask = scanningTaskExecutor.getCurrentTask( );
  292. if ( currentTask != null && repositoryId.equals( currentTask.getRepositoryId()) )
  293. {
  294. scanningTaskExecutor.cancelTask( currentTask );
  295. resultList.add( getMetadataScanTaskInfo( currentTask ) );
  296. }
  297. resultList.addAll( removeTasks.stream( ).map( task -> getMetadataScanTaskInfo( task ) ).collect( Collectors.toList( ) ) );
  298. return resultList;
  299. }
  300. catch ( TaskQueueException e )
  301. {
  302. throw RepositoryAdminException.ofKey( "repository.task.dequeue_failed", repositoryId );
  303. }
  304. }
  305. @Override
  306. public List<RepositoryTaskInfo> cancelIndexTasks( String repositoryId ) throws RepositoryAdminException
  307. {
  308. try
  309. {
  310. ArrayList<RepositoryTaskInfo> resultList = new ArrayList<>( );
  311. List<ArtifactIndexingTask> removeTasks = indexingTaskExecutor.getQueue( ).getQueueSnapshot( ).stream( ).filter( task -> repositoryId.equals( task.getRepository( ).getId( ) ) ).collect( Collectors.toList( ) );
  312. indexingTaskExecutor.getQueue( ).removeAll( removeTasks );
  313. ArtifactIndexingTask currentTask = indexingTaskExecutor.getCurrentTask( );
  314. if ( currentTask != null && repositoryId.equals( currentTask.getRepository( ).getId( ) ) )
  315. {
  316. indexingTaskExecutor.cancelTask( currentTask );
  317. resultList.add( getIndexingTaskInfo( currentTask ) );
  318. }
  319. resultList.addAll( removeTasks.stream( ).map( task -> getIndexingTaskInfo( task ) ).collect( Collectors.toList( ) ) );
  320. return resultList;
  321. }
  322. catch ( TaskQueueException e )
  323. {
  324. throw RepositoryAdminException.ofKey( "repository.task.dequeue_failed", repositoryId );
  325. }
  326. }
  327. }