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.

DefaultRepositoryGroupService.java 15KB

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