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.

DefaultRepositoryService.java 11KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244
  1. package org.apache.archiva.rest.services.v2;
  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.components.rest.model.PagedResult;
  22. import org.apache.archiva.components.rest.util.QueryHelper;
  23. import org.apache.archiva.components.rest.util.RestUtil;
  24. import org.apache.archiva.metadata.repository.MetadataRepositoryException;
  25. import org.apache.archiva.metadata.repository.stats.model.RepositoryStatisticsManager;
  26. import org.apache.archiva.repository.RemoteRepository;
  27. import org.apache.archiva.repository.RepositoryRegistry;
  28. import org.apache.archiva.repository.scanner.RepositoryScanner;
  29. import org.apache.archiva.repository.scanner.RepositoryScannerException;
  30. import org.apache.archiva.rest.api.model.v2.Repository;
  31. import org.apache.archiva.rest.api.model.v2.RepositoryStatistics;
  32. import org.apache.archiva.rest.api.model.v2.ScanStatus;
  33. import org.apache.archiva.rest.api.services.v2.ArchivaRestServiceException;
  34. import org.apache.archiva.rest.api.services.v2.ErrorKeys;
  35. import org.apache.archiva.rest.api.services.v2.ErrorMessage;
  36. import org.apache.archiva.rest.api.services.v2.RepositoryService;
  37. import org.apache.archiva.scheduler.indexing.DownloadRemoteIndexException;
  38. import org.apache.archiva.scheduler.indexing.DownloadRemoteIndexScheduler;
  39. import org.apache.commons.lang3.StringUtils;
  40. import org.slf4j.Logger;
  41. import org.slf4j.LoggerFactory;
  42. import org.springframework.stereotype.Service;
  43. import javax.inject.Named;
  44. import javax.ws.rs.core.Response;
  45. import javax.ws.rs.core.UriInfo;
  46. import java.util.Comparator;
  47. import java.util.List;
  48. import java.util.Locale;
  49. import java.util.function.Predicate;
  50. import java.util.stream.Collectors;
  51. /**
  52. * @author Martin Stockhammer <martin_s@apache.org>
  53. * @since 3.0
  54. */
  55. @Service( "v2.repositoryService#rest" )
  56. public class DefaultRepositoryService implements RepositoryService
  57. {
  58. final
  59. RepositoryRegistry repositoryRegistry;
  60. final
  61. RepositoryStatisticsManager repositoryStatisticsManager;
  62. private final RepositoryTaskAdministration repositoryTaskAdministration;
  63. private final RepositoryScanner repoScanner;
  64. private final DownloadRemoteIndexScheduler downloadRemoteIndexScheduler;
  65. private static final Logger log = LoggerFactory.getLogger( DefaultRepositoryService.class );
  66. private static final QueryHelper<org.apache.archiva.repository.Repository> QUERY_HELPER = new QueryHelper<>( new String[]{"id", "name"} );
  67. static
  68. {
  69. QUERY_HELPER.addStringFilter( "id", org.apache.archiva.repository.Repository::getId );
  70. QUERY_HELPER.addStringFilter( "name", org.apache.archiva.repository.Repository::getName );
  71. QUERY_HELPER.addStringFilter( "description", org.apache.archiva.repository.Repository::getDescription );
  72. QUERY_HELPER.addStringFilter( "type", repo -> repo.getType( ).name( ) );
  73. QUERY_HELPER.addBooleanFilter( "scanned", org.apache.archiva.repository.Repository::isScanned );
  74. QUERY_HELPER.addNullsafeFieldComparator( "id", org.apache.archiva.repository.Repository::getId );
  75. QUERY_HELPER.addNullsafeFieldComparator( "name", org.apache.archiva.repository.Repository::getName );
  76. QUERY_HELPER.addNullsafeFieldComparator( "type", repo -> repo.getType( ).name( ) );
  77. QUERY_HELPER.addNullsafeFieldComparator( "boolean", org.apache.archiva.repository.Repository::isScanned );
  78. }
  79. public DefaultRepositoryService( RepositoryRegistry repositoryRegistry, RepositoryStatisticsManager repositoryStatisticsManager,
  80. @Named( value = "repositoryTaskAdministration#default") RepositoryTaskAdministration repositoryTaskAdministration,
  81. RepositoryScanner repoScanner, DownloadRemoteIndexScheduler downloadRemoteIndexScheduler )
  82. {
  83. this.repositoryRegistry = repositoryRegistry;
  84. this.repositoryStatisticsManager = repositoryStatisticsManager;
  85. this.repoScanner = repoScanner;
  86. this.repositoryTaskAdministration = repositoryTaskAdministration;
  87. this.downloadRemoteIndexScheduler = downloadRemoteIndexScheduler;
  88. }
  89. private void handleAdminException( RepositoryAdminException e ) throws ArchivaRestServiceException
  90. {
  91. log.error( "Repository admin error: {}", e.getMessage( ), e );
  92. if ( e.keyExists( ) )
  93. {
  94. throw new ArchivaRestServiceException( ErrorMessage.of( ErrorKeys.PREFIX + e.getKey( ), e.getParameters( ) ) );
  95. }
  96. else
  97. {
  98. throw new ArchivaRestServiceException( ErrorMessage.of( ErrorKeys.REPOSITORY_ADMIN_ERROR, e.getMessage( ) ) );
  99. }
  100. }
  101. @Override
  102. public PagedResult<Repository> getRepositories( String searchTerm, Integer offset, Integer limit, List<String> orderBy, String order,
  103. String localeString ) throws ArchivaRestServiceException
  104. {
  105. final Locale locale = StringUtils.isNotEmpty( localeString ) ? Locale.forLanguageTag( localeString ) : Locale.getDefault( );
  106. boolean isAscending = QUERY_HELPER.isAscending( order );
  107. Predicate<org.apache.archiva.repository.Repository> filter = QUERY_HELPER.getQueryFilter( searchTerm );
  108. Comparator<org.apache.archiva.repository.Repository> comparator = QUERY_HELPER.getComparator( orderBy, isAscending );
  109. try
  110. {
  111. int totalCount = Math.toIntExact( repositoryRegistry.getRepositories( ).stream( ).filter( filter ).count( ) );
  112. return new PagedResult<>( totalCount, offset, limit, repositoryRegistry.getRepositories( ).stream( )
  113. .filter( filter ).skip( offset ).limit( limit ).sorted( comparator ).map( repo -> Repository.of( repo, locale ) )
  114. .collect( Collectors.toList( ) ) );
  115. }
  116. catch ( ArithmeticException e )
  117. {
  118. log.error( "Invalid integer conversion for totalCount" );
  119. throw new ArchivaRestServiceException( ErrorMessage.of( ErrorKeys.INVALID_RESULT_SET_ERROR ) );
  120. }
  121. }
  122. @Override
  123. public RepositoryStatistics getManagedRepositoryStatistics( String repositoryId ) throws ArchivaRestServiceException
  124. {
  125. if ( repositoryRegistry.getManagedRepository( repositoryId ) == null )
  126. {
  127. throw new ArchivaRestServiceException( ErrorMessage.of( ErrorKeys.REPOSITORY_MANAGED_NOT_FOUND, repositoryId ), 404 );
  128. }
  129. try
  130. {
  131. return RepositoryStatistics.of( repositoryStatisticsManager.getLastStatistics( repositoryId ) );
  132. }
  133. catch ( MetadataRepositoryException e )
  134. {
  135. log.error( "Metadata error: {} ", e.getMessage( ), e );
  136. throw new ArchivaRestServiceException( ErrorMessage.of( ErrorKeys.REPOSITORY_METADATA_ERROR, e.getMessage( ) ) );
  137. }
  138. }
  139. @Override
  140. public Response scheduleRepositoryScan( String repositoryId, boolean fullScan ) throws ArchivaRestServiceException
  141. {
  142. try
  143. {
  144. repositoryTaskAdministration.scheduleFullScan( repositoryId );
  145. return Response.ok( ).build( );
  146. }
  147. catch ( RepositoryAdminException e )
  148. {
  149. handleAdminException( e );
  150. return Response.serverError( ).build( );
  151. }
  152. }
  153. @Override
  154. public RepositoryStatistics scanRepositoryImmediately( String repositoryId ) throws ArchivaRestServiceException
  155. {
  156. long sinceWhen = RepositoryScanner.FRESH_SCAN;
  157. try
  158. {
  159. return RepositoryStatistics.of( repoScanner.scan( repositoryRegistry.getManagedRepository( repositoryId ), sinceWhen ) );
  160. }
  161. catch ( RepositoryScannerException e )
  162. {
  163. log.error( e.getMessage( ), e );
  164. throw new ArchivaRestServiceException( ErrorMessage.of( ErrorKeys.REPOSITORY_SCAN_FAILED, e.getMessage( ) ) );
  165. }
  166. }
  167. @Override
  168. public ScanStatus getScanStatus( String repositoryId ) throws ArchivaRestServiceException
  169. {
  170. try
  171. {
  172. return ScanStatus.of( repositoryTaskAdministration.getCurrentScanStatus( ) );
  173. }
  174. catch ( RepositoryAdminException e )
  175. {
  176. handleAdminException( e );
  177. return new ScanStatus();
  178. }
  179. }
  180. @Override
  181. public Response removeScanningTaskFromQueue( String repositoryId ) throws ArchivaRestServiceException
  182. {
  183. try
  184. {
  185. repositoryTaskAdministration.cancelTasks( repositoryId );
  186. return Response.ok( ).build( );
  187. }
  188. catch ( RepositoryAdminException e )
  189. {
  190. handleAdminException( e );
  191. return Response.serverError( ).build( );
  192. }
  193. }
  194. @Override
  195. public Response scheduleDownloadRemoteIndex( String repositoryId, boolean immediately, boolean full,
  196. UriInfo uriInfo ) throws ArchivaRestServiceException
  197. {
  198. boolean immediateSet = RestUtil.isFlagSet( uriInfo, "immediate" );
  199. boolean fullSet = RestUtil.isFlagSet( uriInfo, "full" );
  200. RemoteRepository repo = repositoryRegistry.getRemoteRepository( repositoryId );
  201. if (repo==null) {
  202. throw new ArchivaRestServiceException( ErrorMessage.of( ErrorKeys.REPOSITORY_REMOTE_NOT_FOUND, repositoryId ), 404 );
  203. }
  204. try
  205. {
  206. downloadRemoteIndexScheduler.scheduleDownloadRemote( repositoryId, immediateSet, fullSet );
  207. return Response.ok( ).build( );
  208. }
  209. catch ( DownloadRemoteIndexException e )
  210. {
  211. log.error( "Could not schedule index download for repository {}: {}", repositoryId, e.getMessage(), e );
  212. throw new ArchivaRestServiceException( ErrorMessage.of( ErrorKeys.REPOSITORY_REMOTE_INDEX_DOWNLOAD_FAILED, e.getMessage( ) ) );
  213. }
  214. }
  215. @Override
  216. public List<String> getRunningRemoteDownloads( )
  217. {
  218. return downloadRemoteIndexScheduler.getRunningRemoteDownloadIds( );
  219. }
  220. }