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.

RepositoryRegistry.java 55KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380
  1. package org.apache.archiva.repository;
  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. *
  13. * Unless required by applicable law or agreed to in writing,
  14. * software distributed under the License is distributed on an
  15. * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
  16. * KIND, either express or implied. See the License for the
  17. * specific language governing permissions and limitations
  18. * under the License.
  19. */
  20. import org.apache.archiva.configuration.*;
  21. import org.apache.archiva.indexer.ArchivaIndexManager;
  22. import org.apache.archiva.indexer.ArchivaIndexingContext;
  23. import org.apache.archiva.indexer.IndexCreationFailedException;
  24. import org.apache.archiva.indexer.IndexManagerFactory;
  25. import org.apache.archiva.indexer.IndexUpdateFailedException;
  26. import org.apache.archiva.redback.components.registry.RegistryException;
  27. import org.apache.archiva.repository.features.IndexCreationEvent;
  28. import org.apache.archiva.repository.features.IndexCreationFeature;
  29. import org.apache.archiva.repository.features.StagingRepositoryFeature;
  30. import org.apache.commons.lang.StringUtils;
  31. import org.slf4j.Logger;
  32. import org.slf4j.LoggerFactory;
  33. import org.springframework.stereotype.Service;
  34. import javax.annotation.PostConstruct;
  35. import javax.annotation.PreDestroy;
  36. import javax.inject.Inject;
  37. import javax.inject.Named;
  38. import java.util.ArrayList;
  39. import java.util.Collection;
  40. import java.util.Collections;
  41. import java.util.HashMap;
  42. import java.util.LinkedHashMap;
  43. import java.util.List;
  44. import java.util.Map;
  45. import java.util.concurrent.locks.ReentrantReadWriteLock;
  46. import java.util.stream.Collectors;
  47. import java.util.stream.Stream;
  48. import static org.apache.archiva.indexer.ArchivaIndexManager.DEFAULT_INDEX_PATH;
  49. /**
  50. * Registry for repositories. This is the central entry point for repositories. It provides methods for
  51. * retrieving, adding and removing repositories.
  52. *
  53. * The modification methods addXX and removeXX persist the changes immediately to the configuration. If the
  54. * configuration save fails the changes are rolled back.
  55. *
  56. * TODO: Audit events
  57. */
  58. @Service( "repositoryRegistry" )
  59. public class RepositoryRegistry implements ConfigurationListener, RepositoryEventHandler, RepositoryEventListener {
  60. private static final Logger log = LoggerFactory.getLogger( RepositoryRegistry.class );
  61. /**
  62. * We inject all repository providers
  63. */
  64. @Inject
  65. List<RepositoryProvider> repositoryProviders;
  66. @Inject
  67. IndexManagerFactory indexManagerFactory;
  68. @Inject
  69. ArchivaConfiguration archivaConfiguration;
  70. @Inject
  71. @Named("repositoryContentFactory#default")
  72. RepositoryContentFactory repositoryContentFactory;
  73. private List<RepositoryEventListener> listeners = new ArrayList<>();
  74. private Map<String, ManagedRepository> managedRepositories = new HashMap<>( );
  75. private Map<String, ManagedRepository> uManagedRepository = Collections.unmodifiableMap( managedRepositories );
  76. private Map<String, RemoteRepository> remoteRepositories = new HashMap<>( );
  77. private Map<String, RemoteRepository> uRemoteRepositories = Collections.unmodifiableMap( remoteRepositories );
  78. private Map<String, RepositoryGroup> repositoryGroups = new HashMap<>();
  79. private Map<String, RepositoryGroup> uRepositoryGroups = Collections.unmodifiableMap(repositoryGroups);
  80. private ReentrantReadWriteLock rwLock = new ReentrantReadWriteLock( );
  81. public void setArchivaConfiguration( ArchivaConfiguration archivaConfiguration) {
  82. this.archivaConfiguration = archivaConfiguration;
  83. }
  84. @PostConstruct
  85. private void initialize( )
  86. {
  87. rwLock.writeLock( ).lock( );
  88. try
  89. {
  90. log.debug("Initializing repository registry");
  91. for(ManagedRepository rep : managedRepositories.values()) {
  92. rep.close();
  93. }
  94. managedRepositories.clear( );
  95. managedRepositories.putAll( getManagedRepositoriesFromConfig( ) );
  96. for (RemoteRepository repo : remoteRepositories.values()) {
  97. repo.close();
  98. }
  99. remoteRepositories.clear( );
  100. remoteRepositories.putAll( getRemoteRepositoriesFromConfig( ) );
  101. repositoryGroups.clear();
  102. repositoryGroups.putAll(getRepositorGroupsFromConfig());
  103. // archivaConfiguration.addChangeListener(this);
  104. archivaConfiguration.addListener(this);
  105. }
  106. finally
  107. {
  108. rwLock.writeLock( ).unlock( );
  109. }
  110. }
  111. @PreDestroy
  112. public void destroy() {
  113. for(ManagedRepository rep : managedRepositories.values()) {
  114. rep.close();
  115. }
  116. for (RemoteRepository repo : remoteRepositories.values()) {
  117. repo.close();
  118. }
  119. }
  120. private Map<RepositoryType, RepositoryProvider> createProviderMap( )
  121. {
  122. Map<RepositoryType, RepositoryProvider> map = new HashMap<>( );
  123. if ( repositoryProviders != null )
  124. {
  125. for ( RepositoryProvider provider : repositoryProviders )
  126. {
  127. for ( RepositoryType type : provider.provides( ) )
  128. {
  129. map.put( type, provider );
  130. }
  131. }
  132. }
  133. return map;
  134. }
  135. private RepositoryProvider getProvider( RepositoryType type ) throws RepositoryException
  136. {
  137. return repositoryProviders.stream( ).filter( repositoryProvider -> repositoryProvider.provides( ).contains( type ) ).findFirst( ).orElseThrow( ( ) -> new RepositoryException( "Repository type cannot be handled: " + type ) );
  138. }
  139. private Map<String, ManagedRepository> getManagedRepositoriesFromConfig( )
  140. {
  141. try
  142. {
  143. List<ManagedRepositoryConfiguration> managedRepoConfigs =
  144. getArchivaConfiguration( ).getConfiguration( ).getManagedRepositories( );
  145. if ( managedRepoConfigs == null )
  146. {
  147. return Collections.emptyMap();
  148. }
  149. Map<String, ManagedRepository> managedRepos = new LinkedHashMap<>( managedRepoConfigs.size( ) );
  150. Map<RepositoryType, RepositoryProvider> providerMap = createProviderMap( );
  151. for ( ManagedRepositoryConfiguration repoConfig : managedRepoConfigs )
  152. {
  153. if (managedRepos.containsKey(repoConfig.getId())) {
  154. log.warn( "Duplicate repository definitions for {} in config found.", repoConfig.getId( ) );
  155. continue;
  156. }
  157. RepositoryType repositoryType = RepositoryType.valueOf( repoConfig.getType( ) );
  158. if ( providerMap.containsKey( repositoryType ) )
  159. {
  160. try
  161. {
  162. ManagedRepository repo = createNewManagedRepository( providerMap.get( repositoryType ), repoConfig );
  163. managedRepos.put( repo.getId( ), repo );
  164. }
  165. catch ( Exception e )
  166. {
  167. log.error( "Could not create managed repository {}: {}", repoConfig.getId( ), e.getMessage( ), e );
  168. }
  169. }
  170. }
  171. return managedRepos;
  172. } catch (Throwable e) {
  173. log.error("Could not initialize repositories from config: {}",e.getMessage(), e );
  174. //noinspection unchecked
  175. return Collections.emptyMap();
  176. }
  177. }
  178. private ManagedRepository createNewManagedRepository( RepositoryProvider provider, ManagedRepositoryConfiguration cfg ) throws RepositoryException
  179. {
  180. log.debug("Creating repo {}", cfg.getId());
  181. ManagedRepository repo = provider.createManagedInstance( cfg );
  182. repo.addListener(this);
  183. updateRepositoryReferences( provider, repo, cfg , null);
  184. return repo;
  185. }
  186. @SuppressWarnings( "unchecked" )
  187. private void updateRepositoryReferences(RepositoryProvider provider, ManagedRepository repo, ManagedRepositoryConfiguration cfg, Configuration configuration) throws RepositoryException
  188. {
  189. log.debug("Updating references of repo {}",repo.getId());
  190. if ( repo.supportsFeature( StagingRepositoryFeature.class ) )
  191. {
  192. StagingRepositoryFeature feature = repo.getFeature( StagingRepositoryFeature.class ).get( );
  193. if ( feature.isStageRepoNeeded( ) && feature.getStagingRepository() == null)
  194. {
  195. ManagedRepository stageRepo = getStagingRepository( provider, cfg, configuration);
  196. managedRepositories.put(stageRepo.getId(), stageRepo);
  197. feature.setStagingRepository( stageRepo );
  198. if (configuration!=null) {
  199. replaceOrAddRepositoryConfig( provider.getManagedConfiguration( stageRepo ), configuration );
  200. }
  201. }
  202. }
  203. if ( repo instanceof EditableManagedRepository)
  204. {
  205. EditableManagedRepository editableRepo = (EditableManagedRepository) repo;
  206. if (repo.getContent()==null) {
  207. editableRepo.setContent(repositoryContentFactory.getManagedRepositoryContent(repo));
  208. }
  209. log.debug("Index repo: "+repo.hasIndex());
  210. if (repo.hasIndex() && repo.getIndexingContext()==null) {
  211. log.debug("Creating indexing context for {}", repo.getId());
  212. createIndexingContext(editableRepo);
  213. }
  214. }
  215. }
  216. public ArchivaIndexManager getIndexManager(RepositoryType type) {
  217. return indexManagerFactory.getIndexManager(type);
  218. }
  219. private void createIndexingContext(EditableRepository editableRepo) throws RepositoryException {
  220. if (editableRepo.supportsFeature(IndexCreationFeature.class)) {
  221. ArchivaIndexManager idxManager = getIndexManager(editableRepo.getType());
  222. try {
  223. editableRepo.setIndexingContext(idxManager.createContext(editableRepo));
  224. idxManager.updateLocalIndexPath(editableRepo);
  225. } catch (IndexCreationFailedException e) {
  226. throw new RepositoryException("Could not create index for repository "+editableRepo.getId()+": "+e.getMessage(),e);
  227. }
  228. }
  229. }
  230. private ManagedRepository getStagingRepository(RepositoryProvider provider, ManagedRepositoryConfiguration baseRepoCfg, Configuration configuration) throws RepositoryException
  231. {
  232. ManagedRepository stageRepo = getManagedRepository( baseRepoCfg.getId( ) + StagingRepositoryFeature.STAGING_REPO_POSTFIX );
  233. if ( stageRepo == null )
  234. {
  235. stageRepo = provider.createStagingInstance( baseRepoCfg );
  236. if (stageRepo.supportsFeature(StagingRepositoryFeature.class)) {
  237. stageRepo.getFeature(StagingRepositoryFeature.class).get().setStageRepoNeeded(false);
  238. }
  239. ManagedRepositoryConfiguration stageCfg = provider.getManagedConfiguration( stageRepo );
  240. updateRepositoryReferences( provider, stageRepo, stageCfg, configuration);
  241. }
  242. return stageRepo;
  243. }
  244. private Map<String, RemoteRepository> getRemoteRepositoriesFromConfig( )
  245. {
  246. try
  247. {
  248. List<RemoteRepositoryConfiguration> remoteRepoConfigs =
  249. getArchivaConfiguration( ).getConfiguration( ).getRemoteRepositories( );
  250. if ( remoteRepoConfigs == null )
  251. {
  252. //noinspection unchecked
  253. return Collections.emptyMap();
  254. }
  255. Map<String, RemoteRepository> remoteRepos = new LinkedHashMap<>( remoteRepoConfigs.size( ) );
  256. Map<RepositoryType, RepositoryProvider> providerMap = createProviderMap( );
  257. for ( RemoteRepositoryConfiguration repoConfig : remoteRepoConfigs )
  258. {
  259. RepositoryType repositoryType = RepositoryType.valueOf( repoConfig.getType( ) );
  260. if ( providerMap.containsKey( repositoryType ) )
  261. {
  262. RepositoryProvider provider = getProvider( repositoryType );
  263. try
  264. {
  265. RemoteRepository remoteRepository = createNewRemoteRepository( provider, repoConfig );
  266. remoteRepos.put( repoConfig.getId( ), remoteRepository);
  267. }
  268. catch ( Exception e )
  269. {
  270. log.error( "Could not create repository {} from config: {}", repoConfig.getId( ), e.getMessage( ), e );
  271. }
  272. }
  273. }
  274. return remoteRepos;
  275. } catch (Throwable e) {
  276. log.error("Could not initialize remote repositories from config: {}", e.getMessage(), e);
  277. //noinspection unchecked
  278. return Collections.emptyMap();
  279. }
  280. }
  281. private RemoteRepository createNewRemoteRepository( RepositoryProvider provider, RemoteRepositoryConfiguration cfg ) throws RepositoryException
  282. {
  283. log.debug("Creating remote repo {}", cfg.getId());
  284. RemoteRepository repo = provider.createRemoteInstance( cfg );
  285. repo.addListener(this);
  286. updateRepositoryReferences( provider, repo, cfg , null);
  287. return repo;
  288. }
  289. @SuppressWarnings( "unchecked" )
  290. private void updateRepositoryReferences( RepositoryProvider provider, RemoteRepository repo, RemoteRepositoryConfiguration cfg, Configuration configuration) throws RepositoryException
  291. {
  292. if ( repo instanceof EditableRemoteRepository && repo.getContent() == null)
  293. {
  294. EditableRemoteRepository editableRepo = (EditableRemoteRepository) repo;
  295. editableRepo.setContent( repositoryContentFactory.getRemoteRepositoryContent( repo ) );
  296. if (repo.supportsFeature(IndexCreationFeature.class) && repo.getIndexingContext()==null ) {
  297. createIndexingContext(editableRepo);
  298. }
  299. }
  300. }
  301. private Map<String, RepositoryGroup> getRepositorGroupsFromConfig( )
  302. {
  303. try
  304. {
  305. List<RepositoryGroupConfiguration> repositoryGroupConfigurations =
  306. getArchivaConfiguration( ).getConfiguration( ).getRepositoryGroups();
  307. if ( repositoryGroupConfigurations == null )
  308. {
  309. return Collections.emptyMap();
  310. }
  311. Map<String, RepositoryGroup> repositoryGroupMap = new LinkedHashMap<>( repositoryGroupConfigurations.size( ) );
  312. Map<RepositoryType, RepositoryProvider> providerMap = createProviderMap( );
  313. for ( RepositoryGroupConfiguration repoConfig : repositoryGroupConfigurations )
  314. {
  315. RepositoryType repositoryType = RepositoryType.valueOf( repoConfig.getType( ) );
  316. if ( providerMap.containsKey( repositoryType ) )
  317. {
  318. try
  319. {
  320. RepositoryGroup repo = createNewRepositoryGroup( providerMap.get( repositoryType ), repoConfig );
  321. repositoryGroupMap.put( repo.getId( ), repo );
  322. }
  323. catch ( Exception e )
  324. {
  325. log.error( "Could not create repository group {}: {}", repoConfig.getId( ), e.getMessage( ), e );
  326. }
  327. }
  328. }
  329. return repositoryGroupMap;
  330. } catch (Throwable e) {
  331. log.error("Could not initialize repositories from config: {}",e.getMessage(), e );
  332. //noinspection unchecked
  333. return Collections.emptyMap();
  334. }
  335. }
  336. RepositoryGroup createNewRepositoryGroup(RepositoryProvider provider, RepositoryGroupConfiguration config) throws RepositoryException {
  337. RepositoryGroup repositoryGroup = provider.createRepositoryGroup(config);
  338. repositoryGroup.addListener(this);
  339. updateRepositoryReferences(provider, repositoryGroup, config);
  340. return repositoryGroup;
  341. }
  342. private void updateRepositoryReferences(RepositoryProvider provider, RepositoryGroup group, RepositoryGroupConfiguration configuration) {
  343. if (group instanceof EditableRepositoryGroup) {
  344. EditableRepositoryGroup eGroup = (EditableRepositoryGroup) group;
  345. eGroup.setRepositories(configuration.getRepositories().stream().map(r -> getManagedRepository(r)).collect(Collectors.toList()));
  346. }
  347. }
  348. private ArchivaConfiguration getArchivaConfiguration( )
  349. {
  350. return this.archivaConfiguration;
  351. }
  352. /**
  353. * Returns all repositories that are registered. There is no defined order of the returned repositories.
  354. *
  355. * @return a list of managed and remote repositories
  356. */
  357. public Collection<Repository> getRepositories( )
  358. {
  359. rwLock.readLock( ).lock( );
  360. try
  361. {
  362. return Stream.concat( managedRepositories.values( ).stream( ), remoteRepositories.values( ).stream( )).collect( Collectors.toList( ) );
  363. }
  364. finally
  365. {
  366. rwLock.readLock( ).unlock( );
  367. }
  368. }
  369. /**
  370. * Returns only the managed repositories. There is no defined order of the returned repositories.
  371. *
  372. * @return a list of managed repositories
  373. */
  374. public Collection<ManagedRepository> getManagedRepositories( )
  375. {
  376. rwLock.readLock().lock();
  377. try
  378. {
  379. return uManagedRepository.values( );
  380. } finally
  381. {
  382. rwLock.readLock().unlock();
  383. }
  384. }
  385. /**
  386. * Returns only the remote repositories. There is no defined order of the returned repositories.
  387. *
  388. * @return a list of remote repositories
  389. */
  390. public Collection<RemoteRepository> getRemoteRepositories( )
  391. {
  392. rwLock.readLock().lock();
  393. try
  394. {
  395. return uRemoteRepositories.values( );
  396. } finally
  397. {
  398. rwLock.readLock().unlock();
  399. }
  400. }
  401. public Collection<RepositoryGroup> getRepositoryGroups() {
  402. rwLock.readLock().lock();
  403. try {
  404. return uRepositoryGroups.values();
  405. } finally {
  406. rwLock.readLock().unlock();
  407. }
  408. }
  409. /**
  410. * Returns the repository with the given id. The returned repository may be a managed or remote repository.
  411. * It returns null, if no repository is registered with the given id.
  412. *
  413. * @param repoId the repository id
  414. * @return the repository if found, otherwise null
  415. */
  416. public Repository getRepository( String repoId )
  417. {
  418. rwLock.readLock( ).lock( );
  419. try
  420. {
  421. log.debug("getRepository {}", repoId);
  422. if ( managedRepositories.containsKey( repoId ) )
  423. {
  424. log.debug("Managed repo");
  425. return managedRepositories.get( repoId );
  426. }
  427. else if (remoteRepositories.containsKey(repoId))
  428. {
  429. log.debug("Remote repo");
  430. return remoteRepositories.get( repoId );
  431. } else if (repositoryGroups.containsKey(repoId)) {
  432. return repositoryGroups.get(repoId);
  433. } else {
  434. return null;
  435. }
  436. }
  437. finally
  438. {
  439. rwLock.readLock( ).unlock( );
  440. }
  441. }
  442. /**
  443. * Convenience method, that returns the managed repository with the given id.
  444. * It returns null, if no managed repository is registered with this id.
  445. *
  446. * @param repoId the repository id
  447. * @return the managed repository if found, otherwise null
  448. */
  449. public ManagedRepository getManagedRepository( String repoId )
  450. {
  451. rwLock.readLock( ).lock( );
  452. try
  453. {
  454. return managedRepositories.get( repoId );
  455. }
  456. finally
  457. {
  458. rwLock.readLock( ).unlock( );
  459. }
  460. }
  461. /**
  462. * Convenience method, that returns the remote repository with the given id.
  463. * It returns null, if no remote repository is registered with this id.
  464. *
  465. * @param repoId the repository id
  466. * @return the remote repository if found, otherwise null
  467. */
  468. public RemoteRepository getRemoteRepository( String repoId )
  469. {
  470. rwLock.readLock( ).lock( );
  471. try
  472. {
  473. return remoteRepositories.get( repoId );
  474. }
  475. finally
  476. {
  477. rwLock.readLock( ).unlock( );
  478. }
  479. }
  480. public RepositoryGroup getRepositoryGroup( String groupId ) {
  481. rwLock.readLock().lock();
  482. try {
  483. return repositoryGroups.get(groupId);
  484. } finally {
  485. rwLock.readLock().unlock();
  486. }
  487. }
  488. /**
  489. * Adds a new repository to the current list, or replaces the repository definition with
  490. * the same id, if it exists already.
  491. * The change is saved to the configuration immediately.
  492. *
  493. * @param managedRepository the new repository.
  494. * @throws RepositoryException if the new repository could not be saved to the configuration.
  495. */
  496. public ManagedRepository putRepository( ManagedRepository managedRepository ) throws RepositoryException
  497. {
  498. rwLock.writeLock( ).lock( );
  499. try
  500. {
  501. final String id = managedRepository.getId();
  502. if (remoteRepositories.containsKey( id )) {
  503. throw new RepositoryException( "There exists a remote repository with id "+id+". Could not update with managed repository." );
  504. }
  505. ManagedRepository originRepo = managedRepositories.put( id, managedRepository );
  506. try
  507. {
  508. if (originRepo!=null) {
  509. originRepo.close();
  510. }
  511. RepositoryProvider provider = getProvider( managedRepository.getType() );
  512. ManagedRepositoryConfiguration newCfg = provider.getManagedConfiguration( managedRepository );
  513. Configuration configuration = getArchivaConfiguration( ).getConfiguration( );
  514. updateRepositoryReferences( provider, managedRepository, newCfg, configuration );
  515. ManagedRepositoryConfiguration oldCfg = configuration.findManagedRepositoryById( id );
  516. if (oldCfg!=null) {
  517. configuration.removeManagedRepository( oldCfg );
  518. }
  519. configuration.addManagedRepository( newCfg );
  520. getArchivaConfiguration( ).save( configuration );
  521. return managedRepository;
  522. }
  523. catch ( Exception e )
  524. {
  525. // Rollback
  526. if ( originRepo != null )
  527. {
  528. managedRepositories.put( id, originRepo );
  529. } else {
  530. managedRepositories.remove(id);
  531. }
  532. log.error("Exception during configuration update {}", e.getMessage(), e);
  533. throw new RepositoryException( "Could not save the configuration" + (e.getMessage( )==null?"":": "+e.getMessage()) );
  534. }
  535. }
  536. finally
  537. {
  538. rwLock.writeLock( ).unlock( );
  539. }
  540. }
  541. /**
  542. * Adds a new repository or updates the repository with the same id, if it exists already.
  543. * The configuration is saved immediately.
  544. *
  545. * @param managedRepositoryConfiguration the repository configuration
  546. * @return the updated or created repository
  547. * @throws RepositoryException if an error occurs, or the configuration is not valid.
  548. */
  549. public ManagedRepository putRepository( ManagedRepositoryConfiguration managedRepositoryConfiguration) throws RepositoryException
  550. {
  551. rwLock.writeLock( ).lock( );
  552. try
  553. {
  554. final String id = managedRepositoryConfiguration.getId();
  555. final RepositoryType repositoryType = RepositoryType.valueOf( managedRepositoryConfiguration.getType() );
  556. Configuration configuration = getArchivaConfiguration().getConfiguration();
  557. ManagedRepository repo = managedRepositories.get(id);
  558. ManagedRepositoryConfiguration oldCfg = repo!=null ? getProvider( repositoryType ).getManagedConfiguration( repo ) : null;
  559. repo = putRepository( managedRepositoryConfiguration, configuration );
  560. try
  561. {
  562. getArchivaConfiguration().save(configuration);
  563. }
  564. catch ( IndeterminateConfigurationException | RegistryException e )
  565. {
  566. if (oldCfg!=null) {
  567. getProvider( repositoryType ).updateManagedInstance( (EditableManagedRepository)repo, oldCfg );
  568. }
  569. log.error("Could not save the configuration for repository {}: {}", id, e.getMessage(),e );
  570. throw new RepositoryException( "Could not save the configuration for repository "+id+": "+e.getMessage() );
  571. }
  572. return repo;
  573. }
  574. finally
  575. {
  576. rwLock.writeLock( ).unlock( );
  577. }
  578. }
  579. /**
  580. * Adds a new repository or updates the repository with the same id. The given configuration object is updated, but
  581. * the configuration is not saved.
  582. *
  583. * @param managedRepositoryConfiguration the new or changed repository configuration
  584. * @param configuration the configuration object
  585. * @return the new or updated repository
  586. * @throws RepositoryException if the configuration cannot be saved or updated
  587. */
  588. @SuppressWarnings( "unchecked" )
  589. public ManagedRepository putRepository( ManagedRepositoryConfiguration managedRepositoryConfiguration, Configuration configuration) throws RepositoryException
  590. {
  591. rwLock.writeLock( ).lock( );
  592. try
  593. {
  594. final String id = managedRepositoryConfiguration.getId();
  595. final RepositoryType repoType = RepositoryType.valueOf( managedRepositoryConfiguration.getType() );
  596. ManagedRepository repo;
  597. if (managedRepositories.containsKey( id )) {
  598. repo = managedRepositories.get(id);
  599. if (repo instanceof EditableManagedRepository)
  600. {
  601. getProvider( repoType ).updateManagedInstance( (EditableManagedRepository) repo, managedRepositoryConfiguration );
  602. } else {
  603. throw new RepositoryException( "The repository is not editable "+id );
  604. }
  605. } else
  606. {
  607. repo = getProvider( repoType ).createManagedInstance( managedRepositoryConfiguration );
  608. repo.addListener(this);
  609. managedRepositories.put(id, repo);
  610. }
  611. updateRepositoryReferences( getProvider( repoType ), repo, managedRepositoryConfiguration, configuration );
  612. replaceOrAddRepositoryConfig( managedRepositoryConfiguration, configuration );
  613. return repo;
  614. }
  615. finally
  616. {
  617. rwLock.writeLock( ).unlock( );
  618. }
  619. }
  620. /**
  621. * Adds a new repository group to the current list, or replaces the repository group definition with
  622. * the same id, if it exists already.
  623. * The change is saved to the configuration immediately.
  624. *
  625. * @param repositoryGroup the new repository group.
  626. * @throws RepositoryException if the new repository group could not be saved to the configuration.
  627. */
  628. public RepositoryGroup putRepositoryGroup( RepositoryGroup repositoryGroup ) throws RepositoryException
  629. {
  630. rwLock.writeLock( ).lock( );
  631. try
  632. {
  633. final String id = repositoryGroup.getId();
  634. RepositoryGroup originRepo = repositoryGroups.put( id, repositoryGroup );
  635. try
  636. {
  637. if (originRepo!=null) {
  638. originRepo.close();
  639. }
  640. RepositoryProvider provider = getProvider( repositoryGroup.getType() );
  641. RepositoryGroupConfiguration newCfg = provider.getRepositoryGroupConfiguration( repositoryGroup );
  642. Configuration configuration = getArchivaConfiguration( ).getConfiguration( );
  643. updateRepositoryReferences( provider, repositoryGroup, newCfg );
  644. RepositoryGroupConfiguration oldCfg = configuration.findRepositoryGroupById( id );
  645. if (oldCfg!=null) {
  646. configuration.removeRepositoryGroup( oldCfg );
  647. }
  648. configuration.addRepositoryGroup( newCfg );
  649. getArchivaConfiguration( ).save( configuration );
  650. return repositoryGroup;
  651. }
  652. catch ( Exception e )
  653. {
  654. // Rollback
  655. if ( originRepo != null )
  656. {
  657. repositoryGroups.put( id, originRepo );
  658. } else {
  659. repositoryGroups.remove(id);
  660. }
  661. log.error("Exception during configuration update {}", e.getMessage(), e);
  662. throw new RepositoryException( "Could not save the configuration" + (e.getMessage( )==null?"":": "+e.getMessage()) );
  663. }
  664. }
  665. finally
  666. {
  667. rwLock.writeLock( ).unlock( );
  668. }
  669. }
  670. /**
  671. * Adds a new repository group or updates the repository with the same id, if it exists already.
  672. * The configuration is saved immediately.
  673. *
  674. * @param repositoryGroupConfiguration the repository configuration
  675. * @return the updated or created repository
  676. * @throws RepositoryException if an error occurs, or the configuration is not valid.
  677. */
  678. public RepositoryGroup putRepositoryGroup( RepositoryGroupConfiguration repositoryGroupConfiguration) throws RepositoryException
  679. {
  680. rwLock.writeLock( ).lock( );
  681. try
  682. {
  683. final String id = repositoryGroupConfiguration.getId();
  684. final RepositoryType repositoryType = RepositoryType.valueOf( repositoryGroupConfiguration.getType() );
  685. Configuration configuration = getArchivaConfiguration().getConfiguration();
  686. RepositoryGroup repo = repositoryGroups.get(id);
  687. RepositoryGroupConfiguration oldCfg = repo!=null ? getProvider( repositoryType ).getRepositoryGroupConfiguration( repo ) : null;
  688. repo = putRepositoryGroup( repositoryGroupConfiguration, configuration );
  689. try
  690. {
  691. getArchivaConfiguration().save(configuration);
  692. }
  693. catch ( IndeterminateConfigurationException | RegistryException e )
  694. {
  695. if (oldCfg!=null) {
  696. getProvider( repositoryType ).updateRepositoryGroupInstance( (EditableRepositoryGroup) repo, oldCfg );
  697. }
  698. log.error("Could not save the configuration for repository group {}: {}", id, e.getMessage(),e );
  699. throw new RepositoryException( "Could not save the configuration for repository group "+id+": "+e.getMessage() );
  700. }
  701. return repo;
  702. }
  703. finally
  704. {
  705. rwLock.writeLock( ).unlock( );
  706. }
  707. }
  708. /**
  709. * Adds a new repository group or updates the repository group with the same id. The given configuration object is updated, but
  710. * the configuration is not saved.
  711. *
  712. * @param repositoryGroupConfiguration the new or changed repository configuration
  713. * @param configuration the configuration object
  714. * @return the new or updated repository
  715. * @throws RepositoryException if the configuration cannot be saved or updated
  716. */
  717. @SuppressWarnings( "unchecked" )
  718. public RepositoryGroup putRepositoryGroup( RepositoryGroupConfiguration repositoryGroupConfiguration, Configuration configuration) throws RepositoryException
  719. {
  720. rwLock.writeLock( ).lock( );
  721. try
  722. {
  723. final String id = repositoryGroupConfiguration.getId();
  724. final RepositoryType repoType = RepositoryType.valueOf( repositoryGroupConfiguration.getType() );
  725. RepositoryGroup repo;
  726. setRepositoryGroupDefaults(repositoryGroupConfiguration);
  727. if (repositoryGroups.containsKey( id )) {
  728. repo = repositoryGroups.get(id);
  729. if (repo instanceof EditableRepositoryGroup)
  730. {
  731. getProvider( repoType ).updateRepositoryGroupInstance( (EditableRepositoryGroup) repo, repositoryGroupConfiguration );
  732. } else {
  733. throw new RepositoryException( "The repository is not editable "+id );
  734. }
  735. } else
  736. {
  737. repo = getProvider( repoType ).createRepositoryGroup( repositoryGroupConfiguration );
  738. repo.addListener(this);
  739. repositoryGroups.put(id, repo);
  740. }
  741. updateRepositoryReferences( getProvider( repoType ), repo, repositoryGroupConfiguration );
  742. replaceOrAddRepositoryConfig( repositoryGroupConfiguration, configuration );
  743. return repo;
  744. }
  745. finally
  746. {
  747. rwLock.writeLock( ).unlock( );
  748. }
  749. }
  750. private void setRepositoryGroupDefaults(RepositoryGroupConfiguration repositoryGroupConfiguration) {
  751. if (StringUtils.isEmpty(repositoryGroupConfiguration.getMergedIndexPath())) {
  752. repositoryGroupConfiguration.setMergedIndexPath(DEFAULT_INDEX_PATH);
  753. }
  754. if (repositoryGroupConfiguration.getMergedIndexTtl()<=0) {
  755. repositoryGroupConfiguration.setMergedIndexTtl(300);
  756. }
  757. if (StringUtils.isEmpty(repositoryGroupConfiguration.getCronExpression())) {
  758. repositoryGroupConfiguration.setCronExpression("0 0 03 ? * MON");
  759. }
  760. }
  761. private void replaceOrAddRepositoryConfig(ManagedRepositoryConfiguration managedRepositoryConfiguration, Configuration configuration) {
  762. ManagedRepositoryConfiguration oldCfg = configuration.findManagedRepositoryById( managedRepositoryConfiguration.getId() );
  763. if ( oldCfg !=null) {
  764. configuration.removeManagedRepository( oldCfg );
  765. }
  766. configuration.addManagedRepository( managedRepositoryConfiguration );
  767. }
  768. private void replaceOrAddRepositoryConfig(RemoteRepositoryConfiguration remoteRepositoryConfiguration, Configuration configuration) {
  769. RemoteRepositoryConfiguration oldCfg = configuration.findRemoteRepositoryById( remoteRepositoryConfiguration.getId() );
  770. if ( oldCfg !=null) {
  771. configuration.removeRemoteRepository( oldCfg );
  772. }
  773. configuration.addRemoteRepository( remoteRepositoryConfiguration );
  774. }
  775. private void replaceOrAddRepositoryConfig(RepositoryGroupConfiguration repositoryGroupConfiguration, Configuration configuration) {
  776. RepositoryGroupConfiguration oldCfg = configuration.findRepositoryGroupById( repositoryGroupConfiguration.getId() );
  777. if ( oldCfg !=null) {
  778. configuration.removeRepositoryGroup( oldCfg );
  779. }
  780. configuration.addRepositoryGroup( repositoryGroupConfiguration);
  781. }
  782. public RemoteRepository putRepository( RemoteRepository remoteRepository, Configuration configuration) throws RepositoryException
  783. {
  784. rwLock.writeLock( ).lock( );
  785. try
  786. {
  787. final String id = remoteRepository.getId();
  788. if (managedRepositories.containsKey( id )) {
  789. throw new RepositoryException( "There exists a managed repository with id "+id+". Could not update with remote repository." );
  790. }
  791. RemoteRepository originRepo = remoteRepositories.put( id, remoteRepository );
  792. RemoteRepositoryConfiguration oldCfg=null;
  793. RemoteRepositoryConfiguration newCfg;
  794. try
  795. {
  796. if (originRepo!=null) {
  797. originRepo.close();
  798. }
  799. final RepositoryProvider provider = getProvider( remoteRepository.getType() );
  800. newCfg = provider.getRemoteConfiguration( remoteRepository );
  801. updateRepositoryReferences( provider, remoteRepository, newCfg, configuration );
  802. oldCfg = configuration.findRemoteRepositoryById( id );
  803. if (oldCfg!=null) {
  804. configuration.removeRemoteRepository( oldCfg );
  805. }
  806. configuration.addRemoteRepository( newCfg );
  807. return remoteRepository;
  808. }
  809. catch ( Exception e )
  810. {
  811. // Rollback
  812. if ( originRepo != null )
  813. {
  814. remoteRepositories.put( id, originRepo );
  815. } else {
  816. remoteRepositories.remove( id);
  817. }
  818. if (oldCfg!=null) {
  819. RemoteRepositoryConfiguration cfg = configuration.findRemoteRepositoryById( id );
  820. if (cfg!=null) {
  821. configuration.removeRemoteRepository( cfg );
  822. configuration.addRemoteRepository( oldCfg );
  823. }
  824. }
  825. log.error("Error while adding remote repository {}", e.getMessage(), e);
  826. throw new RepositoryException( "Could not save the configuration" + (e.getMessage( )==null?"":": "+e.getMessage()) );
  827. }
  828. }
  829. finally
  830. {
  831. rwLock.writeLock( ).unlock( );
  832. }
  833. }
  834. /**
  835. * Adds a remote repository, or overwrites the repository definition with the same id, if it exists already.
  836. * The modification is saved to the configuration immediately.
  837. *
  838. * @param remoteRepository the remote repository to add
  839. * @throws RepositoryException if an error occurs during configuration save
  840. */
  841. public RemoteRepository putRepository( RemoteRepository remoteRepository ) throws RepositoryException
  842. {
  843. rwLock.writeLock( ).lock( );
  844. try
  845. {
  846. Configuration configuration = getArchivaConfiguration().getConfiguration();
  847. try
  848. {
  849. RemoteRepository repo = putRepository( remoteRepository, configuration );
  850. getArchivaConfiguration().save(configuration);
  851. return repo;
  852. }
  853. catch ( RegistryException | IndeterminateConfigurationException e )
  854. {
  855. log.error("Error while saving remote repository {}", e.getMessage(), e);
  856. throw new RepositoryException( "Could not save the configuration" + (e.getMessage( )==null?"":": "+e.getMessage()) );
  857. }
  858. }
  859. finally
  860. {
  861. rwLock.writeLock( ).unlock( );
  862. }
  863. }
  864. /**
  865. * Adds a new repository or updates the repository with the same id, if it exists already.
  866. * The configuration is saved immediately.
  867. *
  868. * @param remoteRepositoryConfiguration the repository configuration
  869. * @return the updated or created repository
  870. * @throws RepositoryException if an error occurs, or the configuration is not valid.
  871. */
  872. public RemoteRepository putRepository( RemoteRepositoryConfiguration remoteRepositoryConfiguration) throws RepositoryException
  873. {
  874. rwLock.writeLock( ).lock( );
  875. try
  876. {
  877. final String id = remoteRepositoryConfiguration.getId();
  878. final RepositoryType repositoryType = RepositoryType.valueOf( remoteRepositoryConfiguration.getType() );
  879. Configuration configuration = getArchivaConfiguration().getConfiguration();
  880. RemoteRepository repo = remoteRepositories.get(id);
  881. RemoteRepositoryConfiguration oldCfg = repo!=null ? getProvider( repositoryType ).getRemoteConfiguration( repo ) : null;
  882. repo = putRepository( remoteRepositoryConfiguration, configuration );
  883. try
  884. {
  885. getArchivaConfiguration().save(configuration);
  886. }
  887. catch ( IndeterminateConfigurationException | RegistryException e )
  888. {
  889. if (oldCfg!=null) {
  890. getProvider( repositoryType ).updateRemoteInstance( (EditableRemoteRepository)repo, oldCfg );
  891. }
  892. log.error("Could not save the configuration for repository {}: {}", id, e.getMessage(),e );
  893. throw new RepositoryException( "Could not save the configuration for repository "+id+": "+e.getMessage() );
  894. }
  895. return repo;
  896. }
  897. finally
  898. {
  899. rwLock.writeLock( ).unlock( );
  900. }
  901. }
  902. /**
  903. * Adds a new repository or updates the repository with the same id. The given configuration object is updated, but
  904. * the configuration is not saved.
  905. *
  906. * @param remoteRepositoryConfiguration the new or changed repository configuration
  907. * @param configuration the configuration object
  908. * @return the new or updated repository
  909. * @throws RepositoryException if the configuration cannot be saved or updated
  910. */
  911. @SuppressWarnings( "unchecked" )
  912. public RemoteRepository putRepository( RemoteRepositoryConfiguration remoteRepositoryConfiguration, Configuration configuration) throws RepositoryException
  913. {
  914. rwLock.writeLock( ).lock( );
  915. try
  916. {
  917. final String id = remoteRepositoryConfiguration.getId();
  918. final RepositoryType repoType = RepositoryType.valueOf( remoteRepositoryConfiguration.getType() );
  919. RemoteRepository repo;
  920. if (remoteRepositories.containsKey( id )) {
  921. repo = remoteRepositories.get(id);
  922. if (repo instanceof EditableRemoteRepository)
  923. {
  924. getProvider( repoType ).updateRemoteInstance( (EditableRemoteRepository) repo, remoteRepositoryConfiguration );
  925. } else {
  926. throw new RepositoryException( "The repository is not editable "+id );
  927. }
  928. } else
  929. {
  930. repo = getProvider( repoType ).createRemoteInstance( remoteRepositoryConfiguration );
  931. repo.addListener(this);
  932. remoteRepositories.put(id, repo);
  933. }
  934. updateRepositoryReferences( getProvider( repoType ), repo, remoteRepositoryConfiguration, configuration );
  935. replaceOrAddRepositoryConfig( remoteRepositoryConfiguration, configuration );
  936. return repo;
  937. }
  938. finally
  939. {
  940. rwLock.writeLock( ).unlock( );
  941. }
  942. }
  943. public void removeRepository(String repoId) throws RepositoryException {
  944. Repository repo = getRepository(repoId);
  945. if (repo!=null) {
  946. removeRepository(repo);
  947. }
  948. }
  949. @SuppressWarnings( "unchecked" )
  950. public void removeRepository(Repository repo) throws RepositoryException
  951. {
  952. if (repo==null) {
  953. log.warn("Trying to remove null repository");
  954. return;
  955. }
  956. if (repo instanceof RemoteRepository ) {
  957. removeRepository( (RemoteRepository)repo );
  958. } else if (repo instanceof ManagedRepository) {
  959. removeRepository( (ManagedRepository)repo);
  960. } else if (repo instanceof RepositoryGroup ) {
  961. removeRepositoryGroup((RepositoryGroup) repo);
  962. }else {
  963. throw new RepositoryException( "Repository type not known: "+repo.getClass() );
  964. }
  965. }
  966. /**
  967. * Removes a managed repository from the registry and configuration, if it exists.
  968. * The change is saved to the configuration immediately.
  969. *
  970. * @param managedRepository the managed repository to remove
  971. * @throws RepositoryException if a error occurs during configuration save
  972. */
  973. public void removeRepository( ManagedRepository managedRepository ) throws RepositoryException
  974. {
  975. final String id = managedRepository.getId();
  976. ManagedRepository repo = getManagedRepository( id );
  977. if (repo!=null) {
  978. rwLock.writeLock().lock();
  979. try {
  980. repo = managedRepositories.remove( id );
  981. if (repo!=null) {
  982. repo.close();
  983. removeRepositoryFromGroups(repo);
  984. Configuration configuration = getArchivaConfiguration().getConfiguration();
  985. ManagedRepositoryConfiguration cfg = configuration.findManagedRepositoryById( id );
  986. if (cfg!=null) {
  987. configuration.removeManagedRepository( cfg );
  988. }
  989. getArchivaConfiguration().save( configuration );
  990. }
  991. }
  992. catch ( RegistryException | IndeterminateConfigurationException e )
  993. {
  994. // Rollback
  995. log.error("Could not save config after repository removal: {}", e.getMessage(), e);
  996. managedRepositories.put(repo.getId(), repo);
  997. throw new RepositoryException( "Could not save configuration after repository removal: "+e.getMessage() );
  998. } finally
  999. {
  1000. rwLock.writeLock().unlock();
  1001. }
  1002. }
  1003. }
  1004. private void removeRepositoryFromGroups(ManagedRepository repo) {
  1005. if (repo!=null) {
  1006. repositoryGroups.values().stream().filter(repoGroup -> repoGroup instanceof EditableRepository).
  1007. map(repoGroup -> (EditableRepositoryGroup) repoGroup).forEach(repoGroup -> repoGroup.removeRepository(repo));
  1008. }
  1009. }
  1010. public void removeRepository(ManagedRepository managedRepository, Configuration configuration) throws RepositoryException
  1011. {
  1012. final String id = managedRepository.getId();
  1013. ManagedRepository repo = getManagedRepository( id );
  1014. if (repo!=null) {
  1015. rwLock.writeLock().lock();
  1016. try {
  1017. repo = managedRepositories.remove( id );
  1018. if (repo!=null) {
  1019. repo.close();
  1020. removeRepositoryFromGroups(repo);
  1021. ManagedRepositoryConfiguration cfg = configuration.findManagedRepositoryById( id );
  1022. if (cfg!=null) {
  1023. configuration.removeManagedRepository( cfg );
  1024. }
  1025. }
  1026. } finally
  1027. {
  1028. rwLock.writeLock().unlock();
  1029. }
  1030. }
  1031. }
  1032. /**
  1033. * Removes a repository group from the registry and configuration, if it exists.
  1034. * The change is saved to the configuration immediately.
  1035. *
  1036. * @param repositoryGroup the repository group to remove
  1037. * @throws RepositoryException if a error occurs during configuration save
  1038. */
  1039. public void removeRepositoryGroup( RepositoryGroup repositoryGroup ) throws RepositoryException
  1040. {
  1041. final String id = repositoryGroup.getId();
  1042. RepositoryGroup repo = getRepositoryGroup( id );
  1043. if (repo!=null) {
  1044. rwLock.writeLock().lock();
  1045. try {
  1046. repo = repositoryGroups.remove( id );
  1047. if (repo!=null) {
  1048. repo.close();
  1049. Configuration configuration = getArchivaConfiguration().getConfiguration();
  1050. RepositoryGroupConfiguration cfg = configuration.findRepositoryGroupById( id );
  1051. if (cfg!=null) {
  1052. configuration.removeRepositoryGroup( cfg );
  1053. }
  1054. getArchivaConfiguration().save( configuration );
  1055. }
  1056. }
  1057. catch ( RegistryException | IndeterminateConfigurationException e )
  1058. {
  1059. // Rollback
  1060. log.error("Could not save config after repository removal: {}", e.getMessage(), e);
  1061. repositoryGroups.put(repo.getId(), repo);
  1062. throw new RepositoryException( "Could not save configuration after repository removal: "+e.getMessage() );
  1063. } finally
  1064. {
  1065. rwLock.writeLock().unlock();
  1066. }
  1067. }
  1068. }
  1069. public void removeRepositoryGroup(RepositoryGroup repositoryGroup, Configuration configuration) throws RepositoryException
  1070. {
  1071. final String id = repositoryGroup.getId();
  1072. RepositoryGroup repo = getRepositoryGroup( id );
  1073. if (repo!=null) {
  1074. rwLock.writeLock().lock();
  1075. try {
  1076. repo = repositoryGroups.remove( id );
  1077. if (repo!=null) {
  1078. repo.close();
  1079. RepositoryGroupConfiguration cfg = configuration.findRepositoryGroupById( id );
  1080. if (cfg!=null) {
  1081. configuration.removeRepositoryGroup( cfg );
  1082. }
  1083. }
  1084. } finally
  1085. {
  1086. rwLock.writeLock().unlock();
  1087. }
  1088. }
  1089. }
  1090. private void doRemoveRepo(RemoteRepository repo, Configuration configuration) {
  1091. repo.close();
  1092. RemoteRepositoryConfiguration cfg = configuration.findRemoteRepositoryById(repo.getId());
  1093. if (cfg != null) {
  1094. configuration.removeRemoteRepository(cfg);
  1095. }
  1096. List<ProxyConnectorConfiguration> proxyConnectors = new ArrayList<>(configuration.getProxyConnectors());
  1097. for (ProxyConnectorConfiguration proxyConnector : proxyConnectors) {
  1098. if (StringUtils.equals(proxyConnector.getTargetRepoId(), repo.getId())) {
  1099. configuration.removeProxyConnector(proxyConnector);
  1100. }
  1101. }
  1102. }
  1103. /**
  1104. * Removes the remote repository from the registry and configuration.
  1105. * The change is saved to the configuration immediately.
  1106. *
  1107. * @param remoteRepository the remote repository to remove
  1108. * @throws RepositoryException if a error occurs during configuration save
  1109. */
  1110. public void removeRepository( RemoteRepository remoteRepository ) throws RepositoryException
  1111. {
  1112. final String id = remoteRepository.getId();
  1113. RemoteRepository repo = getRemoteRepository( id );
  1114. if (repo!=null) {
  1115. rwLock.writeLock().lock();
  1116. try {
  1117. repo = remoteRepositories.remove( id );
  1118. if (repo!=null) {
  1119. Configuration configuration = getArchivaConfiguration().getConfiguration();
  1120. doRemoveRepo(repo, configuration);
  1121. getArchivaConfiguration().save( configuration );
  1122. }
  1123. }
  1124. catch ( RegistryException | IndeterminateConfigurationException e )
  1125. {
  1126. // Rollback
  1127. log.error("Could not save config after repository removal: {}", e.getMessage(), e);
  1128. remoteRepositories.put(repo.getId(), repo);
  1129. throw new RepositoryException( "Could not save configuration after repository removal: "+e.getMessage() );
  1130. } finally
  1131. {
  1132. rwLock.writeLock().unlock();
  1133. }
  1134. }
  1135. }
  1136. public void removeRepository( RemoteRepository remoteRepository, Configuration configuration) throws RepositoryException
  1137. {
  1138. final String id = remoteRepository.getId();
  1139. RemoteRepository repo = getRemoteRepository( id );
  1140. if (repo!=null) {
  1141. rwLock.writeLock().lock();
  1142. try {
  1143. repo = remoteRepositories.remove( id );
  1144. if (repo!=null) {
  1145. doRemoveRepo(repo, configuration);
  1146. }
  1147. } finally
  1148. {
  1149. rwLock.writeLock().unlock();
  1150. }
  1151. }
  1152. }
  1153. /**
  1154. * Reloads the registry from the configuration.
  1155. */
  1156. public void reload() {
  1157. initialize();
  1158. }
  1159. /**
  1160. * Resets the indexing context of a given repository.
  1161. *
  1162. * @param repo
  1163. * @throws IndexUpdateFailedException
  1164. */
  1165. @SuppressWarnings( "unchecked" )
  1166. public void resetIndexingContext(Repository repo) throws IndexUpdateFailedException {
  1167. if (repo.hasIndex() && repo instanceof EditableRepository) {
  1168. EditableRepository eRepo = (EditableRepository) repo;
  1169. ArchivaIndexingContext newCtx = getIndexManager(repo.getType()).reset(repo.getIndexingContext());
  1170. eRepo.setIndexingContext(newCtx);
  1171. }
  1172. }
  1173. /**
  1174. * Creates a new repository instance with the same settings as this one. The cloned repository is not
  1175. * registered or saved to the configuration.
  1176. *
  1177. * @param repo The origin repository
  1178. * @return The cloned repository.
  1179. */
  1180. public ManagedRepository clone(ManagedRepository repo, String newId) throws RepositoryException
  1181. {
  1182. if (managedRepositories.containsKey(newId) || remoteRepositories.containsKey(newId)) {
  1183. throw new RepositoryException("The given id exists already "+newId);
  1184. }
  1185. RepositoryProvider provider = getProvider(repo.getType());
  1186. ManagedRepositoryConfiguration cfg = provider.getManagedConfiguration(repo);
  1187. cfg.setId(newId);
  1188. ManagedRepository cloned = provider.createManagedInstance(cfg);
  1189. cloned.addListener(this);
  1190. return cloned;
  1191. }
  1192. @SuppressWarnings( "unchecked" )
  1193. public <T extends Repository> Repository clone(T repo, String newId) throws RepositoryException {
  1194. if (repo instanceof RemoteRepository ) {
  1195. return this.clone((RemoteRepository)repo, newId);
  1196. } else if (repo instanceof ManagedRepository) {
  1197. return this.clone((ManagedRepository)repo, newId);
  1198. } else {
  1199. throw new RepositoryException("This repository class is not supported "+ repo.getClass().getName());
  1200. }
  1201. }
  1202. /**
  1203. * Creates a new repository instance with the same settings as this one. The cloned repository is not
  1204. * registered or saved to the configuration.
  1205. *
  1206. * @param repo The origin repository
  1207. * @return The cloned repository.
  1208. */
  1209. public RemoteRepository clone( RemoteRepository repo, String newId) throws RepositoryException
  1210. {
  1211. if (managedRepositories.containsKey(newId) || remoteRepositories.containsKey(newId)) {
  1212. throw new RepositoryException("The given id exists already "+newId);
  1213. }
  1214. RepositoryProvider provider = getProvider(repo.getType());
  1215. RemoteRepositoryConfiguration cfg = provider.getRemoteConfiguration(repo);
  1216. cfg.setId(newId);
  1217. RemoteRepository cloned = provider.createRemoteInstance(cfg);
  1218. cloned.addListener(this);
  1219. return cloned;
  1220. }
  1221. @Override
  1222. public void configurationEvent(ConfigurationEvent event) {
  1223. }
  1224. @Override
  1225. public void addListener(RepositoryEventListener listener) {
  1226. if (!this.listeners.contains(listener)) {
  1227. this.listeners.add(listener);
  1228. }
  1229. }
  1230. @Override
  1231. public void removeListener(RepositoryEventListener listener) {
  1232. this.listeners.remove(listener);
  1233. }
  1234. @Override
  1235. public void clearListeners() {
  1236. this.listeners.clear();
  1237. }
  1238. @SuppressWarnings( "unchecked" )
  1239. @Override
  1240. public <T> void raise(RepositoryEvent<T> event) {
  1241. if (event instanceof IndexCreationEvent ) {
  1242. if (managedRepositories.containsKey(event.getRepository().getId()) ||
  1243. remoteRepositories.containsKey(event.getRepository().getId())) {
  1244. EditableRepository repo = (EditableRepository) event.getRepository();
  1245. if (repo != null && repo.getIndexingContext()!=null) {
  1246. try {
  1247. ArchivaIndexManager idxmgr = getIndexManager(repo.getType());
  1248. if (idxmgr != null) {
  1249. ArchivaIndexingContext newCtx = idxmgr.move(repo.getIndexingContext(), repo);
  1250. repo.setIndexingContext(newCtx);
  1251. idxmgr.updateLocalIndexPath(repo);
  1252. }
  1253. } catch (IndexCreationFailedException e) {
  1254. log.error("Could not move index to new directory {}", e.getMessage(), e);
  1255. }
  1256. }
  1257. }
  1258. }
  1259. for(RepositoryEventListener listener : listeners) {
  1260. listener.raise(event);
  1261. }
  1262. }
  1263. }