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
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
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
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
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.EditableRepositoryGroup;
44 import org.apache.archiva.repository.RepositoryException;
45 import org.apache.archiva.repository.RepositoryRegistry;
46 import org.apache.archiva.repository.base.ConfigurationHandler;
47 import org.apache.archiva.repository.validation.ValidationResponse;
48 import org.apache.archiva.rest.api.model.v2.RepositoryGroup;
49 import org.apache.archiva.rest.api.services.v2.ArchivaRestServiceException;
50 import org.apache.archiva.rest.api.services.v2.ErrorKeys;
51 import org.apache.archiva.rest.api.services.v2.ErrorMessage;
52 import org.apache.archiva.rest.api.services.v2.RepositoryGroupService;
53 import org.apache.archiva.rest.api.services.v2.ValidationException;
54 import org.apache.commons.lang3.StringUtils;
55 import org.slf4j.Logger;
56 import org.slf4j.LoggerFactory;
57 import org.springframework.stereotype.Service;
59 import javax.servlet.http.HttpServletResponse;
60 import javax.ws.rs.core.Context;
61 import javax.ws.rs.core.Response;
62 import javax.ws.rs.core.UriInfo;
63 import java.util.Comparator;
64 import java.util.List;
65 import java.util.function.Predicate;
66 import java.util.stream.Collectors;
69 * REST V2 Implementation for repository groups.
71 * @author Martin Stockhammer <martin_s@apache.org>
72 * @see RepositoryGroupService
75 @Service("v2.repositoryGroupService#rest")
76 public class DefaultRepositoryGroupService implements RepositoryGroupService
78 private final ConfigurationHandler configurationHandler;
81 HttpServletResponse httpServletResponse;
86 final private RepositoryRegistry repositoryRegistry;
90 private static final Logger log = LoggerFactory.getLogger( DefaultRepositoryGroupService.class );
91 private static final QueryHelper<org.apache.archiva.repository.RepositoryGroup> QUERY_HELPER = new QueryHelper<>( new String[]{"id"} );
94 QUERY_HELPER.addStringFilter( "id", org.apache.archiva.repository.RepositoryGroup::getId );
95 QUERY_HELPER.addNullsafeFieldComparator( "id", org.apache.archiva.repository.RepositoryGroup::getId );
99 public DefaultRepositoryGroupService( RepositoryRegistry repositoryRegistry, ConfigurationHandler configurationHandler ) {
100 this.repositoryRegistry = repositoryRegistry;
101 this.configurationHandler = configurationHandler;
105 public PagedResult<RepositoryGroup> getRepositoriesGroups( String searchTerm, Integer offset, Integer limit, List<String> orderBy, String order ) throws ArchivaRestServiceException
109 Predicate<org.apache.archiva.repository.RepositoryGroup> filter = QUERY_HELPER.getQueryFilter( searchTerm );
110 Comparator<org.apache.archiva.repository.RepositoryGroup> ordering = QUERY_HELPER.getComparator( orderBy, QUERY_HELPER.isAscending( order ) );
111 int totalCount = Math.toIntExact( repositoryRegistry.getRepositoryGroups( ).stream( ).filter( filter ).count( ) );
112 List<RepositoryGroup> result = repositoryRegistry.getRepositoryGroups( ).stream( ).filter( filter ).sorted( ordering ).skip( offset ).limit( limit ).map(
114 ).collect( Collectors.toList( ) );
115 return new PagedResult<>( totalCount, offset, limit, result );
117 catch ( ArithmeticException e )
119 log.error( "Could not convert total count: {}", e.getMessage( ) );
120 throw new ArchivaRestServiceException( ErrorMessage.of( ErrorKeys.INVALID_RESULT_SET_ERROR ) );
126 public RepositoryGroup getRepositoryGroup( String repositoryGroupId ) throws ArchivaRestServiceException
128 if ( StringUtils.isEmpty( repositoryGroupId ) )
130 throw new ArchivaRestServiceException( ErrorMessage.of( ErrorKeys.REPOSITORY_GROUP_NOT_FOUND, "" ), 404 );
132 org.apache.archiva.repository.RepositoryGroup group = repositoryRegistry.getRepositoryGroup( repositoryGroupId );
133 return RepositoryGroup.of( group );
136 private RepositoryGroupConfiguration toConfig( RepositoryGroup group )
138 RepositoryGroupConfiguration result = new RepositoryGroupConfiguration( );
139 result.setId( group.getId( ) );
140 result.setLocation( group.getLocation( ) );
141 result.setRepositories( group.getRepositories( ) );
142 result.setMergedIndexPath( group.getMergeConfiguration( ).getMergedIndexPath( ) );
143 result.setMergedIndexTtl( group.getMergeConfiguration( ).getMergedIndexTtlMinutes( ) );
144 result.setCronExpression( group.getMergeConfiguration( ).getIndexMergeSchedule( ) );
149 public RepositoryGroup addRepositoryGroup( RepositoryGroup repositoryGroup ) throws ArchivaRestServiceException
151 final String groupId = repositoryGroup.getId( );
152 if ( StringUtils.isEmpty( groupId ) ) {
153 throw new ArchivaRestServiceException( ErrorMessage.of( ErrorKeys.REPOSITORY_INVALID_ID, groupId ), 422 );
155 if (repositoryRegistry.hasRepositoryGroup( groupId )) {
156 httpServletResponse.setHeader( "Location", uriInfo.getAbsolutePathBuilder( ).path( groupId ).build( ).toString( ) );
157 throw new ArchivaRestServiceException( ErrorMessage.of( ErrorKeys.REPOSITORY_ID_EXISTS, groupId ), 303 );
161 RepositoryGroupConfiguration configuration = toConfig( repositoryGroup );
162 Configuration config = configurationHandler.getBaseConfiguration( );
163 org.apache.archiva.repository.RepositoryGroup repo = repositoryRegistry.putRepositoryGroup( configuration, config);
166 ValidationResponse<org.apache.archiva.repository.RepositoryGroup> validationResult = repositoryRegistry.validateRepository( repo );
167 if ( validationResult.isValid( ) )
169 httpServletResponse.setStatus( 201 );
170 configurationHandler.save( config );
171 return RepositoryGroup.of( repo );
173 throw ValidationException.of( validationResult );
178 throw new ArchivaRestServiceException( ErrorMessage.of( ErrorKeys.REPOSITORY_GROUP_ADD_FAILED ) );
181 catch ( RepositoryException | IndeterminateConfigurationException | RegistryException e )
183 throw new ArchivaRestServiceException( ErrorMessage.of( ErrorKeys.REPOSITORY_GROUP_ADD_FAILED ) );
188 public RepositoryGroup updateRepositoryGroup( final String repositoryGroupId, final RepositoryGroup repositoryGroup ) throws ArchivaRestServiceException
190 if ( StringUtils.isEmpty( repositoryGroupId ) )
192 throw new ArchivaRestServiceException( ErrorMessage.of( ErrorKeys.REPOSITORY_GROUP_NOT_FOUND, "" ), 404 );
194 if ( !repositoryRegistry.hasRepositoryGroup( repositoryGroupId ) )
196 throw new ArchivaRestServiceException( ErrorMessage.of( ErrorKeys.REPOSITORY_GROUP_NOT_FOUND ), 404 );
198 repositoryGroup.setId( repositoryGroupId );
202 RepositoryGroupConfiguration configuration = toConfig( repositoryGroup );
203 Configuration config = configurationHandler.getBaseConfiguration( );
204 org.apache.archiva.repository.RepositoryGroup repo = repositoryRegistry.putRepositoryGroup( configuration, config);
207 ValidationResponse<org.apache.archiva.repository.RepositoryGroup> validationResult = repositoryRegistry.validateRepository( repo );
208 if ( validationResult.isValid( ) )
210 httpServletResponse.setStatus( 201 );
211 configurationHandler.save( config );
212 return RepositoryGroup.of( repo );
214 throw ValidationException.of( validationResult );
219 log.error( "Returned repository group was null {}", repositoryGroupId );
220 throw new ArchivaRestServiceException( ErrorMessage.of( ErrorKeys.REPOSITORY_GROUP_UPDATE_FAILED ) );
224 catch ( RepositoryException | IndeterminateConfigurationException | RegistryException e )
226 log.error( "Exception during repository group update: {}", e.getMessage( ), e );
227 throw new ArchivaRestServiceException( ErrorMessage.of( ErrorKeys.REPOSITORY_GROUP_UPDATE_FAILED, e.getMessage() ) );
233 public Response deleteRepositoryGroup( String repositoryGroupId ) throws ArchivaRestServiceException
235 if ( StringUtils.isEmpty( repositoryGroupId ) )
237 throw new ArchivaRestServiceException( ErrorMessage.of( ErrorKeys.REPOSITORY_GROUP_NOT_FOUND, "" ), 404 );
241 org.apache.archiva.repository.RepositoryGroup group = repositoryRegistry.getRepositoryGroup( repositoryGroupId );
243 throw new ArchivaRestServiceException( ErrorMessage.of( ErrorKeys.REPOSITORY_GROUP_NOT_FOUND, "" ), 404 );
245 repositoryRegistry.removeRepositoryGroup( group );
246 return Response.ok( ).build( );
248 catch ( RepositoryException e )
250 throw new ArchivaRestServiceException( ErrorMessage.of( ErrorKeys.REPOSITORY_GROUP_DELETE_FAILED ) );
255 public RepositoryGroup addRepositoryToGroup( String repositoryGroupId, String repositoryId ) throws ArchivaRestServiceException
257 if ( StringUtils.isEmpty( repositoryGroupId ) )
259 throw new ArchivaRestServiceException( ErrorMessage.of( ErrorKeys.REPOSITORY_GROUP_NOT_FOUND, "" ), 404 );
261 if ( StringUtils.isEmpty( repositoryId ) )
263 throw new ArchivaRestServiceException( ErrorMessage.of( ErrorKeys.REPOSITORY_NOT_FOUND, "" ), 404 );
267 org.apache.archiva.repository.RepositoryGroup repositoryGroup = repositoryRegistry.getRepositoryGroup( repositoryGroupId );
268 if (repositoryGroup==null) {
269 throw new ArchivaRestServiceException( ErrorMessage.of( ErrorKeys.REPOSITORY_GROUP_NOT_FOUND, "" ), 404 );
271 if (!(repositoryGroup instanceof EditableRepositoryGroup )) {
272 log.error( "This group instance is not editable: {}", repositoryGroupId );
273 throw new ArchivaRestServiceException( ErrorMessage.of( ErrorKeys.REPOSITORY_GROUP_UPDATE_FAILED, "" ), 500 );
275 EditableRepositoryGroup editableRepositoryGroup = (EditableRepositoryGroup) repositoryGroup;
276 if ( editableRepositoryGroup.getRepositories().stream().anyMatch( repo -> repositoryId.equals(repo.getId())) )
278 log.info( "Repository {} is already member of group {}", repositoryId, repositoryGroupId );
279 return RepositoryGroup.of( editableRepositoryGroup );
281 org.apache.archiva.repository.ManagedRepository managedRepo = repositoryRegistry.getManagedRepository(repositoryId);
282 if (managedRepo==null) {
283 throw new ArchivaRestServiceException( ErrorMessage.of( ErrorKeys.REPOSITORY_NOT_FOUND, "" ), 404 );
285 editableRepositoryGroup.addRepository( managedRepo );
286 org.apache.archiva.repository.RepositoryGroup newGroup = repositoryRegistry.putRepositoryGroup( editableRepositoryGroup );
287 return RepositoryGroup.of( newGroup );
289 catch ( RepositoryException e )
291 throw new ArchivaRestServiceException( ErrorMessage.of( ErrorKeys.REPOSITORY_GROUP_UPDATE_FAILED, e.getMessage() ), 500 );
296 public RepositoryGroup deleteRepositoryFromGroup( String repositoryGroupId, String repositoryId ) throws org.apache.archiva.rest.api.services.v2.ArchivaRestServiceException
298 if ( StringUtils.isEmpty( repositoryGroupId ) )
300 throw new ArchivaRestServiceException( ErrorMessage.of( ErrorKeys.REPOSITORY_GROUP_NOT_FOUND, "" ), 404 );
302 if ( StringUtils.isEmpty( repositoryId ) )
304 throw new ArchivaRestServiceException( ErrorMessage.of( ErrorKeys.REPOSITORY_NOT_FOUND, "" ), 404 );
308 org.apache.archiva.repository.RepositoryGroup repositoryGroup = repositoryRegistry.getRepositoryGroup( repositoryGroupId );
309 if (repositoryGroup==null) {
310 throw new ArchivaRestServiceException( ErrorMessage.of( ErrorKeys.REPOSITORY_GROUP_NOT_FOUND, "" ), 404 );
312 if (!(repositoryGroup instanceof EditableRepositoryGroup)) {
313 log.error( "This group instance is not editable: {}", repositoryGroupId );
314 throw new ArchivaRestServiceException( ErrorMessage.of( ErrorKeys.REPOSITORY_GROUP_UPDATE_FAILED, "" ), 500 );
316 EditableRepositoryGroup editableRepositoryGroup = (EditableRepositoryGroup) repositoryGroup;
318 editableRepositoryGroup.removeRepository( repositoryId );
319 org.apache.archiva.repository.RepositoryGroup newGroup = repositoryRegistry.putRepositoryGroup( editableRepositoryGroup );
320 return RepositoryGroup.of( newGroup );
322 catch ( RepositoryException e )
324 throw new ArchivaRestServiceException( ErrorMessage.of( ErrorKeys.REPOSITORY_GROUP_UPDATE_FAILED, e.getMessage() ), 500 );