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.

AbstractRepositoryHandler.java 13KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384
  1. package org.apache.archiva.repository.base;
  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.components.registry.RegistryException;
  20. import org.apache.archiva.configuration.AbstractRepositoryConfiguration;
  21. import org.apache.archiva.configuration.Configuration;
  22. import org.apache.archiva.configuration.IndeterminateConfigurationException;
  23. import org.apache.archiva.event.Event;
  24. import org.apache.archiva.event.EventManager;
  25. import org.apache.archiva.event.EventType;
  26. import org.apache.archiva.repository.EditableRepository;
  27. import org.apache.archiva.repository.Repository;
  28. import org.apache.archiva.repository.RepositoryException;
  29. import org.apache.archiva.repository.RepositoryHandler;
  30. import org.apache.archiva.repository.RepositoryProvider;
  31. import org.apache.archiva.repository.RepositoryState;
  32. import org.apache.archiva.repository.RepositoryType;
  33. import org.apache.archiva.repository.event.LifecycleEvent;
  34. import org.apache.archiva.repository.validation.CheckedResult;
  35. import org.apache.archiva.repository.validation.CombinedValidator;
  36. import org.apache.archiva.repository.validation.RepositoryChecker;
  37. import org.apache.archiva.repository.validation.RepositoryValidator;
  38. import org.apache.archiva.repository.validation.ValidationError;
  39. import org.slf4j.Logger;
  40. import org.slf4j.LoggerFactory;
  41. import java.util.Collection;
  42. import java.util.Collections;
  43. import java.util.HashMap;
  44. import java.util.List;
  45. import java.util.Map;
  46. import java.util.stream.Collectors;
  47. /**
  48. * Base abstract class for repository handlers.
  49. *
  50. * @author Martin Stockhammer <martin_s@apache.org>
  51. */
  52. public abstract class AbstractRepositoryHandler<R extends Repository, C extends AbstractRepositoryConfiguration> implements RepositoryHandler<R, C>
  53. {
  54. private static final Logger log = LoggerFactory.getLogger( AbstractRepositoryHandler.class );
  55. protected final Map<RepositoryType, RepositoryProvider> providerMap = new HashMap<>( );
  56. private CombinedValidator<R> combinedValidator;
  57. private final Class<R> repositoryClazz;
  58. private final Class<C> configurationClazz;
  59. private final EventManager eventManager;
  60. private final Map<String, R> repositoryMap = new HashMap<>( );
  61. private final ConfigurationHandler configurationHandler;
  62. public AbstractRepositoryHandler(Class<R> repositoryClazz, Class<C> configurationClazz, ConfigurationHandler configurationHandler) {
  63. this.repositoryClazz = repositoryClazz;
  64. this.configurationClazz = configurationClazz;
  65. this.eventManager = new EventManager( this );
  66. this.configurationHandler = configurationHandler;
  67. }
  68. protected List<RepositoryValidator<R>> initValidators( Class<R> clazz, List<RepositoryValidator<? extends Repository>> repositoryGroupValidatorList )
  69. {
  70. if ( repositoryGroupValidatorList != null && repositoryGroupValidatorList.size( ) > 0 )
  71. {
  72. return repositoryGroupValidatorList.stream( ).filter(
  73. v -> v.isFlavour( clazz )
  74. ).map( v -> v.narrowTo( clazz ) ).collect( Collectors.toList( ) );
  75. }
  76. else
  77. {
  78. return Collections.emptyList( );
  79. }
  80. }
  81. protected CombinedValidator<R> getCombinedValidator( Class<R> clazz, List<RepositoryValidator<? extends Repository>> repositoryGroupValidatorList )
  82. {
  83. return new CombinedValidator<>( clazz, initValidators( clazz, repositoryGroupValidatorList ) );
  84. }
  85. protected void setLastState( R repo, RepositoryState state )
  86. {
  87. RepositoryState currentState = repo.getLastState( );
  88. if ( repo instanceof EditableRepository )
  89. {
  90. if ( state.getOrderNumber( ) > repo.getLastState( ).getOrderNumber( ) )
  91. {
  92. ( (EditableRepository) repo ).setLastState( state );
  93. }
  94. }
  95. else
  96. {
  97. log.error( "Found a not editable repository instance: {}, {}", repo.getId( ), repo.getClass( ).getName( ) );
  98. }
  99. if (state == RepositoryState.REGISTERED && state != currentState ) {
  100. pushEvent( LifecycleEvent.REGISTERED, repo );
  101. } else if (state == RepositoryState.UNREGISTERED && state != currentState) {
  102. pushEvent( LifecycleEvent.UNREGISTERED, repo );
  103. }
  104. }
  105. @Override
  106. public void setRepositoryProviders( List<RepositoryProvider> providers )
  107. {
  108. if ( providers != null )
  109. {
  110. for ( RepositoryProvider provider : providers )
  111. {
  112. for ( RepositoryType type : provider.provides( ) )
  113. {
  114. providerMap.put( type, provider );
  115. }
  116. }
  117. }
  118. }
  119. protected RepositoryProvider getProvider(RepositoryType type) {
  120. return providerMap.get( type );
  121. }
  122. @Override
  123. public void setRepositoryValidator( List<RepositoryValidator<? extends Repository>> repositoryValidatorList )
  124. {
  125. this.combinedValidator = getCombinedValidator( repositoryClazz, repositoryValidatorList );
  126. }
  127. protected CombinedValidator<R> getCombinedValidator() {
  128. return this.combinedValidator;
  129. }
  130. @Override
  131. public Class<R> getVariant( )
  132. {
  133. return this.repositoryClazz;
  134. }
  135. @Override
  136. public Class<C> getConfigurationVariant( )
  137. {
  138. return this.configurationClazz;
  139. }
  140. @Override
  141. public void processOtherVariantRemoval( Repository repository )
  142. {
  143. // Default: do nothing
  144. }
  145. protected void pushEvent( Event event )
  146. {
  147. eventManager.fireEvent( event );
  148. }
  149. protected void pushEvent(EventType<? extends LifecycleEvent> event, R repo) {
  150. pushEvent( new LifecycleEvent( event, this, repo ) );
  151. }
  152. protected Map<String, R> getRepositories() {
  153. return repositoryMap;
  154. }
  155. protected ConfigurationHandler getConfigurationHandler() {
  156. return configurationHandler;
  157. }
  158. @Override
  159. public void activateRepository( R repository )
  160. {
  161. //
  162. }
  163. @Override
  164. public void deactivateRepository( R repository )
  165. {
  166. repository.close();
  167. }
  168. @Override
  169. public abstract R newInstance( C repositoryConfiguration ) throws RepositoryException;
  170. @Override
  171. public <D> CheckedResult<R, D> putWithCheck( C repositoryConfiguration, RepositoryChecker<R, D> checker ) throws RepositoryException
  172. {
  173. final String id = repositoryConfiguration.getId( );
  174. R currentRepository = getRepositories().get( id );
  175. R managedRepository = newInstance( repositoryConfiguration );
  176. CheckedResult<R, D> result;
  177. if ( currentRepository == null )
  178. {
  179. result = checker.apply( managedRepository );
  180. }
  181. else
  182. {
  183. result = checker.applyForUpdate( managedRepository );
  184. }
  185. if ( result.isValid( ) )
  186. {
  187. put( result.getRepository() );
  188. }
  189. return result;
  190. }
  191. protected abstract C findRepositoryConfiguration(Configuration configuration, String id);
  192. protected abstract void removeRepositoryConfiguration(Configuration configuration, C repoConfiguration );
  193. protected abstract void addRepositoryConfiguration( Configuration configuration, C repoConfiguration );
  194. /**
  195. * Removes a repository group from the registry and configuration, if it exists.
  196. * The change is saved to the configuration immediately.
  197. *
  198. * @param id the id of the repository group to remove
  199. * @throws RepositoryException if an error occurs during configuration save
  200. */
  201. @Override
  202. public void remove( String id ) throws RepositoryException
  203. {
  204. R repo = get( id );
  205. if ( repo != null )
  206. {
  207. try
  208. {
  209. repo = getRepositories().remove( id );
  210. if ( repo != null )
  211. {
  212. deactivateRepository( repo );
  213. Configuration configuration = this.configurationHandler.getBaseConfiguration( );
  214. C cfg = findRepositoryConfiguration( configuration, id );
  215. if ( cfg != null )
  216. {
  217. removeRepositoryConfiguration( configuration, cfg );
  218. }
  219. this.configurationHandler.save( configuration, ConfigurationHandler.REGISTRY_EVENT_TAG );
  220. setLastState( repo, RepositoryState.UNREGISTERED );
  221. }
  222. }
  223. catch ( RegistryException | IndeterminateConfigurationException e )
  224. {
  225. // Rollback
  226. log.error( "Could not save config after repository removal: {}", e.getMessage( ), e );
  227. getRepositories().put( repo.getId( ), repo );
  228. throw new RepositoryException( "Could not save configuration after repository removal: " + e.getMessage( ) );
  229. }
  230. }
  231. }
  232. @Override
  233. public void remove( String id, Configuration configuration ) throws RepositoryException
  234. {
  235. R repo = getRepositories().get( id );
  236. if ( repo != null )
  237. {
  238. repo = getRepositories().remove( id );
  239. if ( repo != null )
  240. {
  241. deactivateRepository( repo );
  242. }
  243. setLastState( repo, RepositoryState.UNREGISTERED );
  244. }
  245. C cfg = findRepositoryConfiguration(configuration, id );
  246. if ( cfg != null )
  247. {
  248. removeRepositoryConfiguration(configuration, cfg );
  249. }
  250. }
  251. @Override
  252. public R get( String groupId )
  253. {
  254. return getRepositories().get( groupId );
  255. }
  256. @Override
  257. public Collection<R> getAll( )
  258. {
  259. return Collections.unmodifiableCollection( getRepositories( ).values( ) );
  260. }
  261. @Override
  262. public RepositoryValidator<R> getValidator( )
  263. {
  264. return getCombinedValidator();
  265. }
  266. @Override
  267. public CheckedResult<R, Map<String, List<ValidationError>>> validateRepository( R repository )
  268. {
  269. return getCombinedValidator( ).apply( repository );
  270. }
  271. @Override
  272. public CheckedResult<R,Map<String, List<ValidationError>>> validateRepositoryForUpdate( R repository )
  273. {
  274. return getCombinedValidator().applyForUpdate( repository );
  275. }
  276. @Override
  277. public boolean hasRepository( String id )
  278. {
  279. return getRepositories().containsKey( id );
  280. }
  281. @Override
  282. public void close( )
  283. {
  284. for ( R repository : getRepositories().values( ) )
  285. {
  286. try
  287. {
  288. deactivateRepository( repository );
  289. }
  290. catch ( Throwable e )
  291. {
  292. log.error( "Could not close repository {}: {}", repository.getId( ), e.getMessage( ) );
  293. }
  294. }
  295. getRepositories().clear( );
  296. }
  297. protected void registerNewRepository( C repositoryGroupConfiguration, R currentRepository, Configuration configuration, boolean updated ) throws IndeterminateConfigurationException, RegistryException, RepositoryException
  298. {
  299. final String id = repositoryGroupConfiguration.getId( );
  300. getConfigurationHandler().save( configuration, ConfigurationHandler.REGISTRY_EVENT_TAG );
  301. updateReferences( currentRepository, repositoryGroupConfiguration );
  302. if (!updated )
  303. {
  304. setLastState( currentRepository, RepositoryState.REFERENCES_SET );
  305. }
  306. activateRepository( currentRepository );
  307. getRepositories().put( id, currentRepository );
  308. setLastState( currentRepository, RepositoryState.REGISTERED );
  309. }
  310. protected void rollback( Configuration configuration, R oldRepository, Exception e, C oldCfg ) throws RepositoryException
  311. {
  312. final String id = oldRepository.getId( );
  313. replaceOrAddRepositoryConfig( oldCfg, configuration );
  314. try
  315. {
  316. getConfigurationHandler().save( configuration, ConfigurationHandler.REGISTRY_EVENT_TAG );
  317. }
  318. catch ( IndeterminateConfigurationException | RegistryException indeterminateConfigurationException )
  319. {
  320. log.error( "Fatal error, config save during rollback failed: {}", e.getMessage( ), e );
  321. }
  322. updateReferences( oldRepository, oldCfg );
  323. setLastState( oldRepository, RepositoryState.REFERENCES_SET );
  324. activateRepository( oldRepository );
  325. getRepositories().put( id, oldRepository );
  326. setLastState( oldRepository, RepositoryState.REGISTERED );
  327. }
  328. protected void replaceOrAddRepositoryConfig( C repositoryGroupConfiguration, Configuration configuration )
  329. {
  330. C oldCfg = findRepositoryConfiguration( configuration, repositoryGroupConfiguration.getId( ) );
  331. if ( oldCfg != null )
  332. {
  333. removeRepositoryConfiguration(configuration, oldCfg );
  334. }
  335. addRepositoryConfiguration( configuration, repositoryGroupConfiguration );
  336. }
  337. }