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