]> source.dussan.org Git - archiva.git/blob
146632011456d954aa91e3ba203c0bab59f34a91
[archiva.git] /
1 package org.apache.archiva.rest.services.v2;/*
2  * Licensed to the Apache Software Foundation (ASF) under one
3  * or more contributor license agreements.  See the NOTICE file
4  * distributed with this work for additional information
5  * regarding copyright ownership.  The ASF licenses this file
6  * to you under the Apache License, Version 2.0 (the
7  * "License"); you may not use this file except in compliance
8  * with the License.  You may obtain a copy of the License at
9  *
10  * http://www.apache.org/licenses/LICENSE-2.0
11  * Unless required by applicable law or agreed to in writing,
12  * software distributed under the License is distributed on an
13  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14  * KIND, either express or implied.  See the License for the
15  * specific language governing permissions and limitations
16  * under the License.
17  */
18
19 /*
20  * Licensed to the Apache Software Foundation (ASF) under one
21  * or more contributor license agreements.  See the NOTICE file
22  * distributed with this work for additional information
23  * regarding copyright ownership.  The ASF licenses this file
24  * to you under the Apache License, Version 2.0 (the
25  * "License"); you may not use this file except in compliance
26  * with the License.  You may obtain a copy of the License at
27  *
28  * http://www.apache.org/licenses/LICENSE-2.0
29  * Unless required by applicable law or agreed to in writing,
30  * software distributed under the License is distributed on an
31  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
32  * KIND, either express or implied.  See the License for the
33  * specific language governing permissions and limitations
34  * under the License.
35  */
36
37 import org.apache.archiva.components.registry.RegistryException;
38 import org.apache.archiva.components.rest.model.PagedResult;
39 import org.apache.archiva.components.rest.util.QueryHelper;
40 import org.apache.archiva.configuration.Configuration;
41 import org.apache.archiva.configuration.IndeterminateConfigurationException;
42 import org.apache.archiva.configuration.RepositoryGroupConfiguration;
43 import org.apache.archiva.repository.CheckedResult;
44 import org.apache.archiva.repository.EditableRepositoryGroup;
45 import org.apache.archiva.repository.RepositoryException;
46 import org.apache.archiva.repository.RepositoryRegistry;
47 import org.apache.archiva.repository.base.ConfigurationHandler;
48 import org.apache.archiva.repository.validation.ValidationError;
49 import org.apache.archiva.repository.validation.ValidationResponse;
50 import org.apache.archiva.rest.api.model.v2.MergeConfiguration;
51 import org.apache.archiva.rest.api.model.v2.RepositoryGroup;
52 import org.apache.archiva.rest.api.services.v2.ArchivaRestServiceException;
53 import org.apache.archiva.rest.api.services.v2.ErrorKeys;
54 import org.apache.archiva.rest.api.services.v2.ErrorMessage;
55 import org.apache.archiva.rest.api.services.v2.RepositoryGroupService;
56 import org.apache.archiva.rest.api.services.v2.ValidationException;
57 import org.apache.commons.lang3.StringUtils;
58 import org.slf4j.Logger;
59 import org.slf4j.LoggerFactory;
60 import org.springframework.stereotype.Service;
61
62 import javax.servlet.http.HttpServletResponse;
63 import javax.ws.rs.core.Context;
64 import javax.ws.rs.core.Response;
65 import javax.ws.rs.core.UriInfo;
66 import java.util.Comparator;
67 import java.util.List;
68 import java.util.Map;
69 import java.util.function.Predicate;
70 import java.util.stream.Collectors;
71
72 /**
73  * REST V2 Implementation for repository groups.
74  *
75  * @author Martin Stockhammer <martin_s@apache.org>
76  * @see RepositoryGroupService
77  * @since 3.0
78  */
79 @Service("v2.repositoryGroupService#rest")
80 public class DefaultRepositoryGroupService implements RepositoryGroupService
81 {
82     private final ConfigurationHandler configurationHandler;
83
84     @Context
85     HttpServletResponse httpServletResponse;
86
87     @Context
88     UriInfo uriInfo;
89
90     final private RepositoryRegistry repositoryRegistry;
91
92
93
94     private static final Logger log = LoggerFactory.getLogger( DefaultRepositoryGroupService.class );
95     private static final QueryHelper<org.apache.archiva.repository.RepositoryGroup> QUERY_HELPER = new QueryHelper<>( new String[]{"id"} );
96     static
97     {
98         QUERY_HELPER.addStringFilter( "id", org.apache.archiva.repository.RepositoryGroup::getId );
99         QUERY_HELPER.addNullsafeFieldComparator( "id", org.apache.archiva.repository.RepositoryGroup::getId );
100     }
101
102
103     public DefaultRepositoryGroupService( RepositoryRegistry repositoryRegistry, ConfigurationHandler configurationHandler ) {
104         this.repositoryRegistry = repositoryRegistry;
105         this.configurationHandler = configurationHandler;
106     }
107
108     @Override
109     public PagedResult<RepositoryGroup> getRepositoriesGroups( String searchTerm, Integer offset, Integer limit, List<String> orderBy, String order ) throws ArchivaRestServiceException
110     {
111         try
112         {
113             Predicate<org.apache.archiva.repository.RepositoryGroup> filter = QUERY_HELPER.getQueryFilter( searchTerm );
114             Comparator<org.apache.archiva.repository.RepositoryGroup> ordering = QUERY_HELPER.getComparator( orderBy, QUERY_HELPER.isAscending( order ) );
115             int totalCount = Math.toIntExact( repositoryRegistry.getRepositoryGroups( ).stream( ).filter( filter ).count( ) );
116             List<RepositoryGroup> result = repositoryRegistry.getRepositoryGroups( ).stream( ).filter( filter ).sorted( ordering ).skip( offset ).limit( limit ).map(
117                 RepositoryGroup::of
118             ).collect( Collectors.toList( ) );
119             return new PagedResult<>( totalCount, offset, limit, result );
120         }
121         catch ( ArithmeticException e )
122         {
123             log.error( "Could not convert total count: {}", e.getMessage( ) );
124             throw new ArchivaRestServiceException( ErrorMessage.of( ErrorKeys.INVALID_RESULT_SET_ERROR ) );
125         }
126
127     }
128
129     @Override
130     public RepositoryGroup getRepositoryGroup( String repositoryGroupId ) throws ArchivaRestServiceException
131     {
132         if ( StringUtils.isEmpty( repositoryGroupId ) )
133         {
134             throw new ArchivaRestServiceException( ErrorMessage.of( ErrorKeys.REPOSITORY_GROUP_NOT_FOUND, "" ), 404 );
135         }
136         org.apache.archiva.repository.RepositoryGroup group = repositoryRegistry.getRepositoryGroup( repositoryGroupId );
137         return RepositoryGroup.of( group );
138     }
139
140     private RepositoryGroupConfiguration toConfig( RepositoryGroup group )
141     {
142         RepositoryGroupConfiguration result = new RepositoryGroupConfiguration( );
143         result.setId( group.getId( ) );
144         result.setLocation( group.getLocation( ) );
145         result.setRepositories( group.getRepositories( ) );
146         MergeConfiguration mergeConfig = group.getMergeConfiguration( );
147         if (mergeConfig!=null)
148         {
149             result.setMergedIndexPath( mergeConfig.getMergedIndexPath( ) );
150             result.setMergedIndexTtl( mergeConfig.getMergedIndexTtlMinutes( ) );
151             result.setCronExpression( mergeConfig.getIndexMergeSchedule( ) );
152         }
153         return result;
154     }
155
156     @Override
157     public RepositoryGroup addRepositoryGroup( RepositoryGroup repositoryGroup ) throws ArchivaRestServiceException
158     {
159         final String groupId = repositoryGroup.getId( );
160         if ( StringUtils.isEmpty( groupId ) ) {
161             throw new ArchivaRestServiceException( ErrorMessage.of( ErrorKeys.REPOSITORY_INVALID_ID, groupId ), 422 );
162         }
163         if (repositoryRegistry.hasRepositoryGroup( groupId )) {
164             httpServletResponse.setHeader( "Location", uriInfo.getAbsolutePathBuilder( ).path( groupId ).build( ).toString( ) );
165             throw new ArchivaRestServiceException( ErrorMessage.of( ErrorKeys.REPOSITORY_ID_EXISTS, groupId ), 303 );
166         }
167         try
168         {
169
170             RepositoryGroupConfiguration configuration = toConfig( repositoryGroup );
171             CheckedResult<org.apache.archiva.repository.RepositoryGroup, Map<String, List<ValidationError>>> validationResult = repositoryRegistry.putRepositoryGroupAndValidate( configuration );
172                 if ( validationResult.isValid( ) )
173                 {
174                     httpServletResponse.setStatus( 201 );
175                     return RepositoryGroup.of( validationResult.getRepository() );
176                 } else {
177                     throw ValidationException.of( validationResult.getResult() );
178                 }
179         }
180         catch ( RepositoryException e )
181         {
182             throw new ArchivaRestServiceException( ErrorMessage.of( ErrorKeys.REPOSITORY_GROUP_ADD_FAILED ) );
183         }
184     }
185
186     @Override
187     public RepositoryGroup updateRepositoryGroup( final String repositoryGroupId, final RepositoryGroup repositoryGroup ) throws ArchivaRestServiceException
188     {
189         if ( StringUtils.isEmpty( repositoryGroupId ) )
190         {
191             throw new ArchivaRestServiceException( ErrorMessage.of( ErrorKeys.REPOSITORY_GROUP_NOT_FOUND, "" ), 404 );
192         }
193         if ( !repositoryRegistry.hasRepositoryGroup( repositoryGroupId ) )
194         {
195             throw new ArchivaRestServiceException( ErrorMessage.of( ErrorKeys.REPOSITORY_GROUP_NOT_FOUND ), 404 );
196         }
197         repositoryGroup.setId( repositoryGroupId );
198         try
199         {
200             RepositoryGroupConfiguration configuration = toConfig( repositoryGroup );
201                 CheckedResult<org.apache.archiva.repository.RepositoryGroup, Map<String, List<ValidationError>>> validationResult = repositoryRegistry.putRepositoryGroupAndValidate( configuration );
202                 if ( validationResult.isValid( ) )
203                 {
204                     httpServletResponse.setStatus( 201 );
205                     return RepositoryGroup.of( validationResult.getRepository() );
206                 } else {
207                     throw ValidationException.of( validationResult.getResult() );
208                 }
209         }
210         catch ( RepositoryException e )
211         {
212             log.error( "Exception during repository group update: {}", e.getMessage( ), e );
213             throw new ArchivaRestServiceException( ErrorMessage.of( ErrorKeys.REPOSITORY_GROUP_UPDATE_FAILED, e.getMessage() ) );
214
215         }
216     }
217
218     @Override
219     public Response deleteRepositoryGroup( String repositoryGroupId ) throws ArchivaRestServiceException
220     {
221         if ( StringUtils.isEmpty( repositoryGroupId ) )
222         {
223             throw new ArchivaRestServiceException( ErrorMessage.of( ErrorKeys.REPOSITORY_GROUP_NOT_FOUND, "" ), 404 );
224         }
225         try
226         {
227             org.apache.archiva.repository.RepositoryGroup group = repositoryRegistry.getRepositoryGroup( repositoryGroupId );
228             if (group==null) {
229                 throw new ArchivaRestServiceException( ErrorMessage.of( ErrorKeys.REPOSITORY_GROUP_NOT_FOUND, "" ), 404 );
230             }
231             repositoryRegistry.removeRepositoryGroup( group );
232             return Response.ok( ).build( );
233         }
234         catch ( RepositoryException e )
235         {
236             throw new ArchivaRestServiceException( ErrorMessage.of( ErrorKeys.REPOSITORY_GROUP_DELETE_FAILED ) );
237         }
238     }
239
240     @Override
241     public RepositoryGroup addRepositoryToGroup( String repositoryGroupId, String repositoryId ) throws ArchivaRestServiceException
242     {
243         if ( StringUtils.isEmpty( repositoryGroupId ) )
244         {
245             throw new ArchivaRestServiceException( ErrorMessage.of( ErrorKeys.REPOSITORY_GROUP_NOT_FOUND, "" ), 404 );
246         }
247         if ( StringUtils.isEmpty( repositoryId ) )
248         {
249             throw new ArchivaRestServiceException( ErrorMessage.of( ErrorKeys.REPOSITORY_NOT_FOUND, "" ), 404 );
250         }
251         try
252         {
253             org.apache.archiva.repository.RepositoryGroup repositoryGroup = repositoryRegistry.getRepositoryGroup( repositoryGroupId );
254             if (repositoryGroup==null) {
255                 throw new ArchivaRestServiceException( ErrorMessage.of( ErrorKeys.REPOSITORY_GROUP_NOT_FOUND, "" ), 404 );
256             }
257             if (!(repositoryGroup instanceof EditableRepositoryGroup )) {
258                 log.error( "This group instance is not editable: {}", repositoryGroupId );
259                 throw new ArchivaRestServiceException( ErrorMessage.of( ErrorKeys.REPOSITORY_GROUP_UPDATE_FAILED, "" ), 500 );
260             }
261             EditableRepositoryGroup editableRepositoryGroup = (EditableRepositoryGroup) repositoryGroup;
262             if ( editableRepositoryGroup.getRepositories().stream().anyMatch( repo -> repositoryId.equals(repo.getId())) )
263             {
264                 log.info( "Repository {} is already member of group {}", repositoryId, repositoryGroupId );
265                 return RepositoryGroup.of( editableRepositoryGroup );
266             }
267             org.apache.archiva.repository.ManagedRepository managedRepo = repositoryRegistry.getManagedRepository(repositoryId);
268             if (managedRepo==null) {
269                 throw new ArchivaRestServiceException( ErrorMessage.of( ErrorKeys.REPOSITORY_NOT_FOUND, "" ), 404 );
270             }
271             editableRepositoryGroup.addRepository( managedRepo );
272             org.apache.archiva.repository.RepositoryGroup newGroup = repositoryRegistry.putRepositoryGroup( editableRepositoryGroup );
273             return RepositoryGroup.of( newGroup );
274         }
275         catch ( RepositoryException e )
276         {
277             throw new ArchivaRestServiceException( ErrorMessage.of( ErrorKeys.REPOSITORY_GROUP_UPDATE_FAILED, e.getMessage() ), 500 );
278         }
279     }
280
281     @Override
282     public RepositoryGroup deleteRepositoryFromGroup( String repositoryGroupId, String repositoryId ) throws org.apache.archiva.rest.api.services.v2.ArchivaRestServiceException
283     {
284         if ( StringUtils.isEmpty( repositoryGroupId ) )
285         {
286             throw new ArchivaRestServiceException( ErrorMessage.of( ErrorKeys.REPOSITORY_GROUP_NOT_FOUND, "" ), 404 );
287         }
288         if ( StringUtils.isEmpty( repositoryId ) )
289         {
290             throw new ArchivaRestServiceException( ErrorMessage.of( ErrorKeys.REPOSITORY_NOT_FOUND, "" ), 404 );
291         }
292         try
293         {
294             org.apache.archiva.repository.RepositoryGroup repositoryGroup = repositoryRegistry.getRepositoryGroup( repositoryGroupId );
295             if (repositoryGroup==null) {
296                 throw new ArchivaRestServiceException( ErrorMessage.of( ErrorKeys.REPOSITORY_GROUP_NOT_FOUND, "" ), 404 );
297             }
298             if (!(repositoryGroup instanceof EditableRepositoryGroup)) {
299                 log.error( "This group instance is not editable: {}", repositoryGroupId );
300                 throw new ArchivaRestServiceException( ErrorMessage.of( ErrorKeys.REPOSITORY_GROUP_UPDATE_FAILED, "" ), 500 );
301             }
302             EditableRepositoryGroup editableRepositoryGroup = (EditableRepositoryGroup) repositoryGroup;
303
304             editableRepositoryGroup.removeRepository( repositoryId );
305             org.apache.archiva.repository.RepositoryGroup newGroup = repositoryRegistry.putRepositoryGroup( editableRepositoryGroup );
306             return RepositoryGroup.of( newGroup );
307         }
308         catch ( RepositoryException e )
309         {
310             throw new ArchivaRestServiceException( ErrorMessage.of( ErrorKeys.REPOSITORY_GROUP_UPDATE_FAILED, e.getMessage() ), 500 );
311         }
312     }
313
314
315 }