void save( Configuration configuration )
throws RegistryException, IndeterminateConfigurationException;
+ /**
+ * Save any updated configuration. This method allows to add a tag to the thrown event.
+ * This allows to verify the origin if the caller is the same as the listener.
+ *
+ * @param configuration the configuration to save
+ * @param eventTag the tag to add to the thrown event
+ * @throws org.apache.archiva.components.registry.RegistryException
+ * if there is a problem saving the registry data
+ * @throws IndeterminateConfigurationException
+ * if the configuration cannot be saved because it was read from two sources
+ */
+ void save( Configuration configuration, String eventTag )
+ throws RegistryException, IndeterminateConfigurationException;
+
/**
* Determines if the configuration in use was as a result of a defaulted configuration.
*
private int type;
+ private String tag;
+
public ConfigurationEvent( int type )
{
this.type = type;
+ tag = "";
+ }
+
+ public ConfigurationEvent(int type, String tag) {
+ this.type = type;
+ this.tag = tag;
}
public int getType()
return type;
}
+ public String getTag( )
+ {
+ return tag;
+ }
+
+ public void setTag( String tag )
+ {
+ this.tag = tag;
+ }
+
@Override
- public int hashCode()
+ public boolean equals( Object o )
{
- final int prime = 31;
- int result = 1;
- result = prime * result + type;
- return result;
+ if ( this == o ) return true;
+ if ( o == null || getClass( ) != o.getClass( ) ) return false;
+
+ ConfigurationEvent that = (ConfigurationEvent) o;
+
+ if ( type != that.type ) return false;
+ return tag.equals( that.tag );
}
@Override
- public boolean equals( Object obj )
+ public int hashCode( )
{
- if ( this == obj )
- {
- return true;
- }
- if ( obj == null )
- {
- return false;
- }
- if ( getClass() != obj.getClass() )
- {
- return false;
- }
- final ConfigurationEvent other = (ConfigurationEvent) obj;
- if ( type != other.type )
- {
- return false;
- }
- return true;
+ int result = type;
+ result = 31 * result + tag.hashCode( );
+ return result;
}
}
@SuppressWarnings("unchecked")
@Override
- public synchronized void save(Configuration configuration)
+ public synchronized void save(Configuration configuration) throws IndeterminateConfigurationException, RegistryException
+ {
+ save( configuration, "" );
+ }
+
+ /**
+ * Saves the configuration and adds the given tag to the event.
+ * @param configuration the configuration to save
+ * @param eventTag the tag to add to the configuration saved event
+ * @throws IndeterminateConfigurationException if the
+ * @throws RegistryException
+ */
+ @Override
+ public synchronized void save(Configuration configuration, String eventTag)
throws IndeterminateConfigurationException, RegistryException {
Registry section = registry.getSection(KEY + ".user");
Registry baseSection = registry.getSection(KEY + ".base");
this.configuration = unescapeExpressions(configuration);
isConfigurationDefaulted = false;
- triggerEvent(ConfigurationEvent.SAVED);
+ triggerEvent(ConfigurationEvent.SAVED, eventTag);
}
private void escapeCronExpressions(Configuration configuration) {
addRegistryChangeListener(regListener);
}
- triggerEvent(ConfigurationEvent.SAVED);
+ triggerEvent(ConfigurationEvent.SAVED, "default-file");
Registry section = registry.getSection(KEY + ".user");
if (section == null) {
}
}
- private void triggerEvent(int type) {
- ConfigurationEvent evt = new ConfigurationEvent(type);
+ private void triggerEvent(int type, String eventTag) {
+ ConfigurationEvent evt = new ConfigurationEvent(type, eventTag);
for (ConfigurationListener listener : listeners) {
listener.configurationEvent(evt);
}
import org.apache.archiva.repository.ManagedRepositoryContent;
import org.apache.archiva.repository.RepositoryRegistry;
import org.apache.archiva.repository.base.ArchivaRepositoryRegistry;
+import org.apache.archiva.repository.base.RepositoryGroupHandler;
import org.apache.archiva.repository.maven.metadata.storage.Maven2RepositoryPathTranslator;
import org.apache.archiva.repository.base.BasicManagedRepository;
import org.apache.archiva.repository.ReleaseScheme;
@Inject
protected ApplicationContext applicationContext;
+ @SuppressWarnings( "unused" )
+ @Inject
+ RepositoryGroupHandler repositoryGroupHandler;
+
@Before
public void setUp()
@Inject
MetadataTools metadataTools;
+
+
@Before
@Override
public void setUp()
import org.apache.archiva.repository.base.ArchivaRepositoryRegistry;
import org.apache.archiva.repository.base.BasicManagedRepository;
import org.apache.archiva.repository.ReleaseScheme;
+import org.apache.archiva.repository.base.RepositoryGroupHandler;
import org.apache.archiva.scheduler.ArchivaTaskScheduler;
import org.apache.archiva.scheduler.indexing.ArtifactIndexingTask;
import org.apache.archiva.test.utils.ArchivaSpringJUnit4ClassRunner;
@Inject
ArchivaRepositoryRegistry repositoryRegistry;
+ @SuppressWarnings( "unused" )
+ @Inject
+ RepositoryGroupHandler repositoryGroupHandler;
@Override
@Before
import org.apache.archiva.admin.repository.AbstractRepositoryAdmin;
import org.apache.archiva.configuration.Configuration;
import org.apache.archiva.configuration.RepositoryGroupConfiguration;
+import org.apache.archiva.event.Event;
+import org.apache.archiva.event.EventHandler;
+import org.apache.archiva.event.EventType;
import org.apache.archiva.metadata.model.facets.AuditEvent;
import org.apache.archiva.indexer.merger.MergedRemoteIndexesScheduler;
import org.apache.archiva.repository.EditableRepositoryGroup;
import org.apache.archiva.repository.RepositoryException;
import org.apache.archiva.repository.RepositoryRegistry;
+import org.apache.archiva.repository.event.RepositoryRegistryEvent;
import org.apache.archiva.repository.features.IndexCreationFeature;
import org.apache.archiva.repository.storage.StorageAsset;
import org.apache.commons.lang3.StringUtils;
@Service("repositoryGroupAdmin#default")
public class DefaultRepositoryGroupAdmin
extends AbstractRepositoryAdmin
- implements RepositoryGroupAdmin
+ implements RepositoryGroupAdmin, EventHandler<Event>
{
private Logger log = LoggerFactory.getLogger( getClass() );
private Path groupsDirectory;
@PostConstruct
+ public void baseInit() {
+ this.repositoryRegistry.registerEventHandler( EventType.ROOT, this );
+ }
+
public void initialize()
{
String appServerBase = getRegistry().getString( "appserver.base" );
rg.setLocation( group.getLocation().toString() );
return rg;
}
+
+ @Override
+ public void handle( Event event )
+ {
+ if ( EventType.isInstanceOf( event.getType( ), RepositoryRegistryEvent.INITIALIZED ) )
+ {
+ log.debug( "Initializing RepositoryGroupAdmin" );
+ initialize();
+ }
+ }
}
import org.apache.archiva.redback.role.RoleManager;
import org.apache.archiva.redback.users.User;
import org.apache.archiva.redback.users.memory.SimpleUser;
+import org.apache.archiva.repository.base.RepositoryGroupHandler;
import org.apache.archiva.test.utils.ArchivaSpringJUnit4ClassRunner;
import org.apache.commons.lang3.StringUtils;
import org.junit.Before;
@Inject
private ArchivaConfiguration archivaConfiguration;
+ @SuppressWarnings( "unused" )
+ @Inject
+ RepositoryGroupHandler repositoryGroupHandler;
+
@Before
public void initialize() {
Path confFile = Paths.get(APPSERVER_BASE_PATH, "conf/archiva.xml");
import org.apache.archiva.metadata.model.facets.AuditEvent;
import org.apache.archiva.repository.Repository;
import org.apache.archiva.repository.RepositoryRegistry;
+import org.apache.archiva.repository.base.RepositoryGroupHandler;
import org.junit.Test;
import javax.inject.Inject;
@Inject
RepositoryRegistry repositoryRegistry;
+ @Inject
+ RepositoryGroupHandler repositoryGroupHandler;
+
@Test
public void addAndDeleteGroup()
throws Exception
*/
public static EventType<RepositoryRegistryEvent> INITIALIZED = new EventType(ANY, "REGISTRY.INITIALIZED");
+ /**
+ * When the repository groups are initialized
+ */
+ public static EventType<RepositoryRegistryEvent> GROUPS_INITIALIZED = new EventType(ANY, "REGISTRY.GROUPS_INITIALIZED");
+
+ /**
+ * When the managed repositories are initialized
+ */
+ public static EventType<RepositoryRegistryEvent> MANAGED_REPOS_INITIALIZED = new EventType(ANY, "REGISTRY.MANAGED_REPOS_INITIALIZED");
+
+ /**
+ * When the remote repositories are initialized
+ */
+ public static EventType<RepositoryRegistryEvent> REMOTE_REPOS_INITIALIZED = new EventType(ANY, "REGISTRY.REMOTE_REPOS_INITIALIZED");
+
public RepositoryRegistryEvent(EventType<? extends RepositoryRegistryEvent> type, Object origin) {
super(type, origin);
}
import org.apache.archiva.repository.EditableManagedRepository;
import org.apache.archiva.repository.EditableRemoteRepository;
import org.apache.archiva.repository.EditableRepository;
-import org.apache.archiva.repository.EditableRepositoryGroup;
import org.apache.archiva.repository.ManagedRepository;
import org.apache.archiva.repository.RemoteRepository;
import org.apache.archiva.repository.Repository;
import javax.inject.Inject;
import javax.inject.Named;
import java.util.*;
+import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.locks.ReentrantReadWriteLock;
import java.util.stream.Collectors;
import java.util.stream.Stream;
-import static org.apache.archiva.indexer.ArchivaIndexManager.DEFAULT_INDEX_PATH;
-
/**
* Registry for repositories. This is the central entry point for repositories. It provides methods for
* retrieving, adding and removing repositories.
{
private static final Logger log = LoggerFactory.getLogger(RepositoryRegistry.class);
+ private final ConfigurationHandler configurationHandler;
/**
* We inject all repository providers
@Inject
IndexManagerFactory indexManagerFactory;
- @Inject
- ArchivaConfiguration archivaConfiguration;
-
@Inject
List<MetadataReader> metadataReaderList;
@Named("repositoryContentFactory#default")
RepositoryContentFactory repositoryContentFactory;
+
+
private final EventManager eventManager;
private Map<String, RemoteRepository> remoteRepositories = new HashMap<>();
private Map<String, RemoteRepository> uRemoteRepositories = Collections.unmodifiableMap(remoteRepositories);
- private Map<String, RepositoryGroup> repositoryGroups = new HashMap<>();
- private Map<String, RepositoryGroup> uRepositoryGroups = Collections.unmodifiableMap(repositoryGroups);
-
private ReentrantReadWriteLock rwLock = new ReentrantReadWriteLock();
- private volatile boolean ignoreConfigEvents = false;
+ private RepositoryGroupHandler groupHandler;
- public ArchivaRepositoryRegistry() {
+ private AtomicBoolean groups_initalized = new AtomicBoolean( false );
+ private AtomicBoolean managed_initialized = new AtomicBoolean( false );
+ private AtomicBoolean remote_initialized = new AtomicBoolean( false );
+
+
+ public ArchivaRepositoryRegistry(ConfigurationHandler configurationHandler) {
this.eventManager = new EventManager(this);
+ this.configurationHandler = configurationHandler;
}
@Override
public void setArchivaConfiguration( ArchivaConfiguration archivaConfiguration ) {
- this.archivaConfiguration = archivaConfiguration;
+ this.configurationHandler.setArchivaConfiguration( archivaConfiguration );
}
@PostConstruct
rwLock.writeLock().lock();
try {
log.debug("Initializing repository registry");
- updateManagedRepositoriesFromConfig();
- updateRemoteRepositoriesFromConfig();
-
- repositoryGroups.clear();
- Map<String, RepositoryGroup> repositoryGroups = getRepositorGroupsFromConfig();
- this.repositoryGroups.putAll(repositoryGroups);
-
- // archivaConfiguration.addChangeListener(this);
- archivaConfiguration.addListener(this);
+ updateManagedRepositoriesFromConfig( );
+ pushEvent( new RepositoryRegistryEvent( RepositoryRegistryEvent.MANAGED_REPOS_INITIALIZED, this ) );
+ managed_initialized.set( true );
+ updateRemoteRepositoriesFromConfig( );
+ pushEvent( new RepositoryRegistryEvent( RepositoryRegistryEvent.REMOTE_REPOS_INITIALIZED, this ) );
+ remote_initialized.set( true );
+
+ initializeRepositoryGroups();
+ this.configurationHandler.addListener(this);
} finally {
rwLock.writeLock().unlock();
}
pushEvent(new RepositoryRegistryEvent(RepositoryRegistryEvent.RELOADED, this));
+ if (managed_initialized.get() && remote_initialized.get() && groups_initalized.get( )) {
+ pushEvent( new RepositoryRegistryEvent( RepositoryRegistryEvent.INITIALIZED, this ) );
+ }
}
+ private void initializeRepositoryGroups() {
+ if (this.groupHandler!=null) {
+ this.groupHandler.initializeFromConfig();
+ this.groups_initalized.set( true );
+ pushEvent( new RepositoryRegistryEvent( RepositoryRegistryEvent.GROUPS_INITIALIZED, this ) );
+ }
+ }
+
+ public void registerGroupHandler(RepositoryGroupHandler groupHandler) {
+ this.groupHandler = groupHandler;
+ initializeRepositoryGroups();
+ if (managed_initialized.get() && remote_initialized.get() && groups_initalized.get( )) {
+ pushEvent( new RepositoryRegistryEvent( RepositoryRegistryEvent.INITIALIZED, this ) );
+ }
+ }
+
+
@PreDestroy
public void destroy() {
for (ManagedRepository rep : managedRepositories.values()) {
repo.close();
}
remoteRepositories.clear();
+ groupHandler.close();
pushEvent(new RepositoryRegistryEvent(RepositoryRegistryEvent.DESTROYED, this));
}
- private Map<RepositoryType, RepositoryProvider> createProviderMap() {
+ protected Map<RepositoryType, RepositoryProvider> getRepositoryProviderMap() {
Map<RepositoryType, RepositoryProvider> map = new HashMap<>();
if (repositoryProviders != null) {
for (RepositoryProvider provider : repositoryProviders) {
return map;
}
- private RepositoryProvider getProvider(RepositoryType type) throws RepositoryException
+ protected RepositoryProvider getProvider(RepositoryType type) throws RepositoryException
{
return repositoryProviders.stream().filter(repositoryProvider -> repositoryProvider.provides().contains(type)).findFirst().orElseThrow(() -> new RepositoryException("Repository type cannot be handled: " + type));
}
Set<String> configRepoIds = new HashSet<>();
List<ManagedRepositoryConfiguration> managedRepoConfigs =
- getArchivaConfiguration().getConfiguration().getManagedRepositories();
+ configurationHandler.getBaseConfiguration().getManagedRepositories();
if (managedRepoConfigs == null) {
return;
private void updateRemoteRepositoriesFromConfig() {
try {
List<RemoteRepositoryConfiguration> remoteRepoConfigs =
- getArchivaConfiguration().getConfiguration().getRemoteRepositories();
+ configurationHandler.getBaseConfiguration().getRemoteRepositories();
if (remoteRepoConfigs == null) {
return;
repo.registerEventHandler(RepositoryEvent.ANY, this);
}
- private Map<String, RepositoryGroup> getRepositorGroupsFromConfig() {
- try {
- List<RepositoryGroupConfiguration> repositoryGroupConfigurations =
- getArchivaConfiguration().getConfiguration().getRepositoryGroups();
-
- if (repositoryGroupConfigurations == null) {
- return Collections.emptyMap();
- }
-
- Map<String, RepositoryGroup> repositoryGroupMap = new LinkedHashMap<>(repositoryGroupConfigurations.size());
-
- Map<RepositoryType, RepositoryProvider> providerMap = createProviderMap();
- for (RepositoryGroupConfiguration repoConfig : repositoryGroupConfigurations) {
- RepositoryType repositoryType = RepositoryType.valueOf(repoConfig.getType());
- if (providerMap.containsKey(repositoryType)) {
- try {
- RepositoryGroup repo = createNewRepositoryGroup(providerMap.get(repositoryType), repoConfig);
- repositoryGroupMap.put(repo.getId(), repo);
- } catch (Exception e) {
- log.error("Could not create repository group {}: {}", repoConfig.getId(), e.getMessage(), e);
- }
- }
- }
- return repositoryGroupMap;
- } catch (Throwable e) {
- log.error("Could not initialize repositories from config: {}", e.getMessage(), e);
- return Collections.emptyMap();
- }
- }
-
- private RepositoryGroup createNewRepositoryGroup(RepositoryProvider provider, RepositoryGroupConfiguration config) throws RepositoryException {
- RepositoryGroup repositoryGroup = provider.createRepositoryGroup(config);
- repositoryGroup.registerEventHandler(RepositoryEvent.ANY, this);
- updateRepositoryReferences(provider, repositoryGroup, config);
- return repositoryGroup;
- }
- private void updateRepositoryReferences(RepositoryProvider provider, RepositoryGroup group, RepositoryGroupConfiguration configuration) {
- if (group instanceof EditableRepositoryGroup ) {
- EditableRepositoryGroup eGroup = (EditableRepositoryGroup) group;
- eGroup.setRepositories(configuration.getRepositories().stream().map(r -> getManagedRepository(r)).collect(Collectors.toList()));
- }
- }
- private ArchivaConfiguration getArchivaConfiguration() {
- return this.archivaConfiguration;
- }
/**
* Returns all repositories that are registered. There is no defined order of the returned repositories.
public Collection<RepositoryGroup> getRepositoryGroups( ) {
rwLock.readLock().lock();
try {
- return uRepositoryGroups.values();
+ return groupHandler.getRepositoryGroups( );
} finally {
rwLock.readLock().unlock();
}
} else if (remoteRepositories.containsKey(repoId)) {
log.debug("Remote repo");
return remoteRepositories.get(repoId);
- } else if (repositoryGroups.containsKey(repoId)) {
- return repositoryGroups.get(repoId);
+ } else if (groupHandler.hasRepositoryGroup(repoId)) {
+ return groupHandler.getRepositoryGroup(repoId);
} else {
return null;
}
public RepositoryGroup getRepositoryGroup( String groupId ) {
rwLock.readLock().lock();
try {
- return repositoryGroups.get(groupId);
+ return groupHandler.getRepositoryGroup(groupId);
} finally {
rwLock.readLock().unlock();
}
}
- /*
- * The <code>ignoreConfigEvents</code> works only for synchronized configuration events.
- * If the configuration throws async events, we cannot know, if the event is caused by this instance or another thread.
- */
- private void saveConfiguration(Configuration configuration) throws IndeterminateConfigurationException, RegistryException {
- ignoreConfigEvents = true;
- try {
- getArchivaConfiguration().save(configuration);
- } finally {
- ignoreConfigEvents = false;
- }
+ protected void saveConfiguration(Configuration configuration) throws IndeterminateConfigurationException, RegistryException {
+ configurationHandler.save(configuration, ConfigurationHandler.REGISTRY_EVENT_TAG );
}
/**
}
RepositoryProvider provider = getProvider(managedRepository.getType());
ManagedRepositoryConfiguration newCfg = provider.getManagedConfiguration(managedRepository);
- Configuration configuration = getArchivaConfiguration().getConfiguration();
+ Configuration configuration = configurationHandler.getBaseConfiguration();
updateRepositoryReferences(provider, managedRepository, newCfg, configuration);
ManagedRepositoryConfiguration oldCfg = configuration.findManagedRepositoryById(id);
if (oldCfg != null) {
try {
final String id = managedRepositoryConfiguration.getId();
final RepositoryType repositoryType = RepositoryType.valueOf(managedRepositoryConfiguration.getType());
- Configuration configuration = getArchivaConfiguration().getConfiguration();
+ Configuration configuration = configurationHandler.getBaseConfiguration();
ManagedRepository repo = managedRepositories.get(id);
ManagedRepositoryConfiguration oldCfg = repo != null ? getProvider(repositoryType).getManagedConfiguration(repo) : null;
repo = putRepository(managedRepositoryConfiguration, configuration);
public RepositoryGroup putRepositoryGroup( RepositoryGroup repositoryGroup ) throws RepositoryException {
rwLock.writeLock().lock();
try {
- final String id = repositoryGroup.getId();
- RepositoryGroup originRepoGroup = repositoryGroups.put(id, repositoryGroup);
- try {
- if (originRepoGroup != null && originRepoGroup != repositoryGroup) {
- originRepoGroup.close();
- }
- RepositoryProvider provider = getProvider(repositoryGroup.getType());
- RepositoryGroupConfiguration newCfg = provider.getRepositoryGroupConfiguration(repositoryGroup);
- Configuration configuration = getArchivaConfiguration().getConfiguration();
- updateRepositoryReferences(provider, repositoryGroup, newCfg);
- RepositoryGroupConfiguration oldCfg = configuration.findRepositoryGroupById(id);
- if (oldCfg != null) {
- configuration.removeRepositoryGroup(oldCfg);
- }
- configuration.addRepositoryGroup(newCfg);
- saveConfiguration(configuration);
- return repositoryGroup;
- } catch (Exception e) {
- // Rollback
- if (originRepoGroup != null) {
- repositoryGroups.put(id, originRepoGroup);
- } else {
- repositoryGroups.remove(id);
- }
- log.error("Exception during configuration update {}", e.getMessage(), e);
- throw new RepositoryException("Could not save the configuration" + (e.getMessage() == null ? "" : ": " + e.getMessage()));
+ if (this.groupHandler==null) {
+ throw new RepositoryException( "Fatal error. RepositoryGroupHandler not registered!" );
}
+ return this.groupHandler.putRepositoryGroup( repositoryGroup );
} finally {
rwLock.writeLock().unlock();
}
public RepositoryGroup putRepositoryGroup( RepositoryGroupConfiguration repositoryGroupConfiguration ) throws RepositoryException {
rwLock.writeLock().lock();
try {
- final String id = repositoryGroupConfiguration.getId();
- final RepositoryType repositoryType = RepositoryType.valueOf(repositoryGroupConfiguration.getType());
- Configuration configuration = getArchivaConfiguration().getConfiguration();
- RepositoryGroup repo = repositoryGroups.get(id);
- RepositoryGroupConfiguration oldCfg = repo != null ? getProvider(repositoryType).getRepositoryGroupConfiguration(repo) : null;
- repo = putRepositoryGroup(repositoryGroupConfiguration, configuration);
- try {
- saveConfiguration(configuration);
- } catch (IndeterminateConfigurationException | RegistryException e) {
- if (oldCfg != null) {
- getProvider(repositoryType).updateRepositoryGroupInstance((EditableRepositoryGroup) repo, oldCfg);
- }
- log.error("Could not save the configuration for repository group {}: {}", id, e.getMessage(), e);
- throw new RepositoryException("Could not save the configuration for repository group " + id + ": " + e.getMessage());
- }
- return repo;
+ return groupHandler.putRepositoryGroup( repositoryGroupConfiguration );
} finally {
rwLock.writeLock().unlock();
}
public RepositoryGroup putRepositoryGroup( RepositoryGroupConfiguration repositoryGroupConfiguration, Configuration configuration ) throws RepositoryException {
rwLock.writeLock().lock();
try {
- final String id = repositoryGroupConfiguration.getId();
- final RepositoryType repoType = RepositoryType.valueOf(repositoryGroupConfiguration.getType());
- RepositoryGroup repo;
- setRepositoryGroupDefaults(repositoryGroupConfiguration);
- if (repositoryGroups.containsKey(id)) {
- repo = repositoryGroups.get(id);
- if (repo instanceof EditableRepositoryGroup) {
- getProvider(repoType).updateRepositoryGroupInstance((EditableRepositoryGroup) repo, repositoryGroupConfiguration);
- } else {
- throw new RepositoryException("The repository is not editable " + id);
- }
- } else {
- repo = getProvider(repoType).createRepositoryGroup(repositoryGroupConfiguration);
- repositoryGroups.put(id, repo);
- }
- updateRepositoryReferences(getProvider(repoType), repo, repositoryGroupConfiguration);
- replaceOrAddRepositoryConfig(repositoryGroupConfiguration, configuration);
- return repo;
+ return groupHandler.putRepositoryGroup( repositoryGroupConfiguration, configuration );
} finally {
rwLock.writeLock().unlock();
}
}
- private void setRepositoryGroupDefaults(RepositoryGroupConfiguration repositoryGroupConfiguration) {
- if (StringUtils.isEmpty(repositoryGroupConfiguration.getMergedIndexPath())) {
- repositoryGroupConfiguration.setMergedIndexPath(DEFAULT_INDEX_PATH);
- }
- if (repositoryGroupConfiguration.getMergedIndexTtl() <= 0) {
- repositoryGroupConfiguration.setMergedIndexTtl(300);
- }
- if (StringUtils.isEmpty(repositoryGroupConfiguration.getCronExpression())) {
- repositoryGroupConfiguration.setCronExpression("0 0 03 ? * MON");
- }
- }
-
private void replaceOrAddRepositoryConfig(ManagedRepositoryConfiguration managedRepositoryConfiguration, Configuration configuration) {
if (configuration != null) {
ManagedRepositoryConfiguration oldCfg = configuration.findManagedRepositoryById(managedRepositoryConfiguration.getId());
public RemoteRepository putRepository( RemoteRepository remoteRepository ) throws RepositoryException {
rwLock.writeLock().lock();
try {
- Configuration configuration = getArchivaConfiguration().getConfiguration();
+ Configuration configuration = configurationHandler.getBaseConfiguration();
try {
RemoteRepository repo = putRepository(remoteRepository, configuration);
saveConfiguration(configuration);
try {
final String id = remoteRepositoryConfiguration.getId();
final RepositoryType repositoryType = RepositoryType.valueOf(remoteRepositoryConfiguration.getType());
- Configuration configuration = getArchivaConfiguration().getConfiguration();
+ Configuration configuration = configurationHandler.getBaseConfiguration();
RemoteRepository repo = remoteRepositories.get(id);
RemoteRepositoryConfiguration oldCfg = repo != null ? getProvider(repositoryType).getRemoteConfiguration(repo) : null;
repo = putRepository(remoteRepositoryConfiguration, configuration);
repo = managedRepositories.remove(id);
if (repo != null) {
repo.close();
- removeRepositoryFromGroups(repo);
- Configuration configuration = getArchivaConfiguration().getConfiguration();
+ this.groupHandler.removeRepositoryFromGroups(repo);
+ Configuration configuration = configurationHandler.getBaseConfiguration();
ManagedRepositoryConfiguration cfg = configuration.findManagedRepositoryById(id);
if (cfg != null) {
configuration.removeManagedRepository(cfg);
}
}
- private void removeRepositoryFromGroups(ManagedRepository repo) {
- if (repo != null) {
- repositoryGroups.values().stream().filter(repoGroup -> repoGroup instanceof EditableRepository).
- map(repoGroup -> (EditableRepositoryGroup) repoGroup).forEach(repoGroup -> repoGroup.removeRepository(repo));
- }
- }
@Override
public void removeRepository( ManagedRepository managedRepository, Configuration configuration ) throws RepositoryException {
repo = managedRepositories.remove(id);
if (repo != null) {
repo.close();
- removeRepositoryFromGroups(repo);
+ this.groupHandler.removeRepositoryFromGroups(repo);
ManagedRepositoryConfiguration cfg = configuration.findManagedRepositoryById(id);
if (cfg != null) {
configuration.removeManagedRepository(cfg);
return;
}
final String id = repositoryGroup.getId();
- RepositoryGroup repo = getRepositoryGroup(id);
- if (repo != null) {
+ if (groupHandler.hasRepositoryGroup( id )) {
rwLock.writeLock().lock();
try {
- repo = repositoryGroups.remove(id);
- if (repo != null) {
- repo.close();
- Configuration configuration = getArchivaConfiguration().getConfiguration();
- RepositoryGroupConfiguration cfg = configuration.findRepositoryGroupById(id);
- if (cfg != null) {
- configuration.removeRepositoryGroup(cfg);
- }
- saveConfiguration(configuration);
- }
-
- } catch (RegistryException | IndeterminateConfigurationException e) {
- // Rollback
- log.error("Could not save config after repository removal: {}", e.getMessage(), e);
- repositoryGroups.put(repo.getId(), repo);
- throw new RepositoryException("Could not save configuration after repository removal: " + e.getMessage());
+ groupHandler.removeRepositoryGroup( id );
} finally {
rwLock.writeLock().unlock();
}
return;
}
final String id = repositoryGroup.getId();
- RepositoryGroup repo = getRepositoryGroup(id);
- if (repo != null) {
+ if (groupHandler.hasRepositoryGroup( id )) {
rwLock.writeLock().lock();
try {
- repo = repositoryGroups.remove(id);
- if (repo != null) {
- repo.close();
- RepositoryGroupConfiguration cfg = configuration.findRepositoryGroupById(id);
- if (cfg != null) {
- configuration.removeRepositoryGroup(cfg);
- }
- }
+ groupHandler.removeRepositoryGroup( id, configuration );
} finally {
rwLock.writeLock().unlock();
}
}
-
}
private void doRemoveRepo(RemoteRepository repo, Configuration configuration) {
try {
repo = remoteRepositories.remove(id);
if (repo != null) {
- Configuration configuration = getArchivaConfiguration().getConfiguration();
+ Configuration configuration = configurationHandler.getBaseConfiguration();
doRemoveRepo(repo, configuration);
saveConfiguration(configuration);
}
@Override
public void configurationEvent(ConfigurationEvent event) {
- // Note: the ignoreConfigEvents flag does not work, if the config events are asynchronous.
- if (!ignoreConfigEvents) {
+ // We ignore the event, if the save was triggered by ourself
+ if ( !ConfigurationHandler.REGISTRY_EVENT_TAG.equals( event.getTag( ) ) )
+ {
reload();
}
}
--- /dev/null
+package org.apache.archiva.repository.base;
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import org.apache.archiva.components.registry.RegistryException;
+import org.apache.archiva.configuration.ArchivaConfiguration;
+import org.apache.archiva.configuration.Configuration;
+import org.apache.archiva.configuration.ConfigurationListener;
+import org.apache.archiva.configuration.IndeterminateConfigurationException;
+import org.springframework.stereotype.Service;
+
+/**
+ * This is just a simple wrapper to access the archiva configuration used by the registry and associated classes
+ *
+ * @author Martin Stockhammer <martin_s@apache.org>
+ */
+@Service("configurationHandler#default")
+public class ConfigurationHandler
+{
+ public static final String REGISTRY_EVENT_TAG = "repositoryRegistry";
+
+ private ArchivaConfiguration archivaConfiguration;
+
+ public ConfigurationHandler( ArchivaConfiguration archivaConfiguration ) {
+ this.archivaConfiguration = archivaConfiguration;
+ }
+
+ public void addListener( ConfigurationListener listener ) {
+ this.archivaConfiguration.addListener( listener );
+ }
+
+ public ArchivaConfiguration getArchivaConfiguration( )
+ {
+ return archivaConfiguration;
+ }
+
+ public void setArchivaConfiguration( ArchivaConfiguration archivaConfiguration )
+ {
+ this.archivaConfiguration = archivaConfiguration;
+ }
+
+ public Configuration getBaseConfiguration() {
+ return archivaConfiguration.getConfiguration( );
+ }
+
+ public void save(Configuration configuration, String eventTag) throws IndeterminateConfigurationException, RegistryException
+ {
+ archivaConfiguration.save( configuration, eventTag);
+ }
+
+ public void save(Configuration configuration) throws IndeterminateConfigurationException, RegistryException
+ {
+ archivaConfiguration.save( configuration, "" );
+ }
+
+}
--- /dev/null
+package org.apache.archiva.repository.base;
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import org.apache.archiva.components.registry.RegistryException;
+import org.apache.archiva.configuration.Configuration;
+import org.apache.archiva.configuration.IndeterminateConfigurationException;
+import org.apache.archiva.configuration.RepositoryGroupConfiguration;
+import org.apache.archiva.indexer.merger.MergedRemoteIndexesScheduler;
+import org.apache.archiva.repository.EditableRepository;
+import org.apache.archiva.repository.EditableRepositoryGroup;
+import org.apache.archiva.repository.ManagedRepository;
+import org.apache.archiva.repository.RepositoryException;
+import org.apache.archiva.repository.RepositoryGroup;
+import org.apache.archiva.repository.RepositoryProvider;
+import org.apache.archiva.repository.RepositoryType;
+import org.apache.archiva.repository.event.RepositoryEvent;
+import org.apache.commons.lang3.StringUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.stereotype.Service;
+
+import javax.annotation.PostConstruct;
+import javax.annotation.PreDestroy;
+import javax.inject.Named;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.stream.Collectors;
+
+import static org.apache.archiva.indexer.ArchivaIndexManager.DEFAULT_INDEX_PATH;
+
+/**
+ * This class manages repository groups for the RepositoryRegistry.
+ * It is tightly coupled with the {@link ArchivaRepositoryRegistry}.
+ *
+ * @author Martin Stockhammer <martin_s@apache.org>
+ */
+@Service("repositoryGroupHandler#default")
+public class RepositoryGroupHandler
+{
+ private static final Logger log = LoggerFactory.getLogger(RepositoryGroupHandler.class);
+
+ private final ArchivaRepositoryRegistry repositoryRegistry;
+ private final ConfigurationHandler configurationHandler;
+ private final MergedRemoteIndexesScheduler mergedRemoteIndexesScheduler;
+
+ private Map<String, RepositoryGroup> repositoryGroups = new HashMap<>();
+
+ /**
+ * Creates a new instance. All dependencies are injected on the constructor.
+ * @param repositoryRegistry the registry. To avoid circular dependencies via DI, this class registers itself on the registry.
+ * @param configurationHandler the configuration handler is used to retrieve and save configuration.
+ * @param mergedRemoteIndexesScheduler the index scheduler is used for merging the indexes from all group members
+ */
+ public RepositoryGroupHandler( ArchivaRepositoryRegistry repositoryRegistry,
+ ConfigurationHandler configurationHandler,
+ @Named("mergedRemoteIndexesScheduler#default") MergedRemoteIndexesScheduler mergedRemoteIndexesScheduler) {
+ this.configurationHandler = configurationHandler;
+ this.mergedRemoteIndexesScheduler = mergedRemoteIndexesScheduler;
+ this.repositoryRegistry = repositoryRegistry;
+ }
+
+ @PostConstruct
+ private void init() {
+ log.debug( "Initializing repository group handler " + repositoryRegistry.toString( ) );
+ // We are registering this class on the registry. This is necessary to avoid circular dependencies via injection.
+ this.repositoryRegistry.registerGroupHandler( this );
+ }
+
+ public void initializeFromConfig() {
+ this.repositoryGroups.clear();
+ this.repositoryGroups.putAll( getRepositorGroupsFromConfig( ) );
+ }
+
+ public Map<String, RepositoryGroup> getRepositorGroupsFromConfig() {
+ try {
+ List<RepositoryGroupConfiguration> repositoryGroupConfigurations =
+ this.configurationHandler.getBaseConfiguration().getRepositoryGroups();
+
+ if (repositoryGroupConfigurations == null) {
+ return Collections.emptyMap();
+ }
+
+ Map<String, RepositoryGroup> repositoryGroupMap = new LinkedHashMap<>(repositoryGroupConfigurations.size());
+
+ Map<RepositoryType, RepositoryProvider> providerMap = repositoryRegistry.getRepositoryProviderMap();
+ for (RepositoryGroupConfiguration repoConfig : repositoryGroupConfigurations) {
+ RepositoryType repositoryType = RepositoryType.valueOf(repoConfig.getType());
+ if (providerMap.containsKey(repositoryType)) {
+ try {
+ RepositoryGroup repo = createNewRepositoryGroup(providerMap.get(repositoryType), repoConfig);
+ repositoryGroupMap.put(repo.getId(), repo);
+ } catch (Exception e) {
+ log.error("Could not create repository group {}: {}", repoConfig.getId(), e.getMessage(), e);
+ }
+ }
+ }
+ return repositoryGroupMap;
+ } catch (Throwable e) {
+ log.error("Could not initialize repositories from config: {}", e.getMessage(), e);
+ return Collections.emptyMap();
+ }
+ }
+
+ public RepositoryGroup createNewRepositoryGroup(RepositoryProvider provider, RepositoryGroupConfiguration config) throws RepositoryException
+ {
+ RepositoryGroup repositoryGroup = provider.createRepositoryGroup(config);
+ repositoryGroup.registerEventHandler( RepositoryEvent.ANY, repositoryRegistry);
+ updateRepositoryReferences(provider, repositoryGroup, config);
+ return repositoryGroup;
+ }
+
+ public void updateRepositoryReferences( RepositoryProvider provider, RepositoryGroup group, RepositoryGroupConfiguration configuration) {
+ if (group instanceof EditableRepositoryGroup ) {
+ EditableRepositoryGroup eGroup = (EditableRepositoryGroup) group;
+ eGroup.setRepositories(configuration.getRepositories().stream()
+ .map(r -> repositoryRegistry.getManagedRepository(r)).collect( Collectors.toList()));
+ }
+ }
+
+ /**
+ * Adds a new repository group to the current list, or replaces the repository group definition with
+ * the same id, if it exists already.
+ * The change is saved to the configuration immediately.
+ *
+ * @param repositoryGroup the new repository group.
+ * @throws RepositoryException if the new repository group could not be saved to the configuration.
+ */
+ public RepositoryGroup putRepositoryGroup( RepositoryGroup repositoryGroup ) throws RepositoryException {
+ final String id = repositoryGroup.getId();
+ RepositoryGroup originRepoGroup = repositoryGroups.put(id, repositoryGroup);
+ try {
+ if (originRepoGroup != null && originRepoGroup != repositoryGroup) {
+ originRepoGroup.close();
+ }
+ RepositoryProvider provider = repositoryRegistry.getProvider( repositoryGroup.getType());
+ RepositoryGroupConfiguration newCfg = provider.getRepositoryGroupConfiguration(repositoryGroup);
+ Configuration configuration = this.configurationHandler.getBaseConfiguration();
+ updateRepositoryReferences(provider, repositoryGroup, newCfg);
+ RepositoryGroupConfiguration oldCfg = configuration.findRepositoryGroupById(id);
+ if (oldCfg != null) {
+ configuration.removeRepositoryGroup(oldCfg);
+ }
+ configuration.addRepositoryGroup(newCfg);
+ repositoryRegistry.saveConfiguration(configuration);
+ return repositoryGroup;
+ } catch (Exception e) {
+ // Rollback
+ if (originRepoGroup != null) {
+ repositoryGroups.put(id, originRepoGroup);
+ } else {
+ repositoryGroups.remove(id);
+ }
+ log.error("Exception during configuration update {}", e.getMessage(), e);
+ throw new RepositoryException("Could not save the configuration" + (e.getMessage() == null ? "" : ": " + e.getMessage()));
+ }
+ }
+
+ /**
+ * Adds a new repository group or updates the repository with the same id, if it exists already.
+ * The configuration is saved immediately.
+ *
+ * @param repositoryGroupConfiguration the repository configuration
+ * @return the updated or created repository
+ * @throws RepositoryException if an error occurs, or the configuration is not valid.
+ */
+ public RepositoryGroup putRepositoryGroup( RepositoryGroupConfiguration repositoryGroupConfiguration ) throws RepositoryException {
+ final String id = repositoryGroupConfiguration.getId();
+ final RepositoryType repositoryType = RepositoryType.valueOf(repositoryGroupConfiguration.getType());
+ Configuration configuration = this.configurationHandler.getBaseConfiguration();
+ RepositoryGroup repo = repositoryGroups.get(id);
+ RepositoryGroupConfiguration oldCfg = repo != null ? repositoryRegistry.getProvider(repositoryType).getRepositoryGroupConfiguration(repo) : null;
+ repo = putRepositoryGroup(repositoryGroupConfiguration, configuration);
+ try {
+ repositoryRegistry.saveConfiguration(configuration);
+ } catch ( IndeterminateConfigurationException | RegistryException e) {
+ if (oldCfg != null) {
+ repositoryRegistry.getProvider(repositoryType).updateRepositoryGroupInstance((EditableRepositoryGroup) repo, oldCfg);
+ }
+ log.error("Could not save the configuration for repository group {}: {}", id, e.getMessage(), e);
+ throw new RepositoryException("Could not save the configuration for repository group " + id + ": " + e.getMessage());
+ }
+ return repo;
+ }
+
+ public RepositoryGroup putRepositoryGroup( RepositoryGroupConfiguration repositoryGroupConfiguration, Configuration configuration ) throws RepositoryException {
+ final String id = repositoryGroupConfiguration.getId();
+ final RepositoryType repoType = RepositoryType.valueOf(repositoryGroupConfiguration.getType());
+ RepositoryGroup repo;
+ setRepositoryGroupDefaults(repositoryGroupConfiguration);
+ if (repositoryGroups.containsKey(id)) {
+ repo = repositoryGroups.get(id);
+ if (repo instanceof EditableRepositoryGroup) {
+ repositoryRegistry.getProvider(repoType).updateRepositoryGroupInstance((EditableRepositoryGroup) repo, repositoryGroupConfiguration);
+ } else {
+ throw new RepositoryException("The repository is not editable " + id);
+ }
+ } else {
+ repo = repositoryRegistry.getProvider(repoType).createRepositoryGroup(repositoryGroupConfiguration);
+ repositoryGroups.put(id, repo);
+ }
+ updateRepositoryReferences(repositoryRegistry.getProvider(repoType), repo, repositoryGroupConfiguration);
+ replaceOrAddRepositoryConfig(repositoryGroupConfiguration, configuration);
+ return repo;
+ }
+
+ private void setRepositoryGroupDefaults(RepositoryGroupConfiguration repositoryGroupConfiguration) {
+ if ( StringUtils.isEmpty(repositoryGroupConfiguration.getMergedIndexPath())) {
+ repositoryGroupConfiguration.setMergedIndexPath(DEFAULT_INDEX_PATH);
+ }
+ if (repositoryGroupConfiguration.getMergedIndexTtl() <= 0) {
+ repositoryGroupConfiguration.setMergedIndexTtl(300);
+ }
+ if (StringUtils.isEmpty(repositoryGroupConfiguration.getCronExpression())) {
+ repositoryGroupConfiguration.setCronExpression("0 0 03 ? * MON");
+ }
+ }
+
+ private void replaceOrAddRepositoryConfig(RepositoryGroupConfiguration repositoryGroupConfiguration, Configuration configuration) {
+ RepositoryGroupConfiguration oldCfg = configuration.findRepositoryGroupById(repositoryGroupConfiguration.getId());
+ if (oldCfg != null) {
+ configuration.removeRepositoryGroup(oldCfg);
+ }
+ configuration.addRepositoryGroup(repositoryGroupConfiguration);
+ }
+
+ public void removeRepositoryFromGroups( ManagedRepository repo) {
+ if (repo != null) {
+ repositoryGroups.values().stream().filter(repoGroup -> repoGroup instanceof EditableRepository ).
+ map(repoGroup -> (EditableRepositoryGroup) repoGroup).forEach(repoGroup -> repoGroup.removeRepository(repo));
+ }
+ }
+
+ /**
+ * Removes a repository group from the registry and configuration, if it exists.
+ * The change is saved to the configuration immediately.
+ *
+ * @param id the id of the repository group to remove
+ * @throws RepositoryException if a error occurs during configuration save
+ */
+ public void removeRepositoryGroup( final String id ) throws RepositoryException {
+ RepositoryGroup repo = getRepositoryGroup(id);
+ if (repo != null) {
+ try {
+ repo = repositoryGroups.remove(id);
+ if (repo != null) {
+ repo.close();
+ Configuration configuration = this.configurationHandler.getBaseConfiguration();
+ RepositoryGroupConfiguration cfg = configuration.findRepositoryGroupById(id);
+ if (cfg != null) {
+ configuration.removeRepositoryGroup(cfg);
+ }
+ this.configurationHandler.save(configuration, ConfigurationHandler.REGISTRY_EVENT_TAG );
+ }
+
+ } catch (RegistryException | IndeterminateConfigurationException e) {
+ // Rollback
+ log.error("Could not save config after repository removal: {}", e.getMessage(), e);
+ repositoryGroups.put(repo.getId(), repo);
+ throw new RepositoryException("Could not save configuration after repository removal: " + e.getMessage());
+ }
+ }
+ }
+
+ public void removeRepositoryGroup( String id, Configuration configuration ) throws RepositoryException {
+ RepositoryGroup repo = repositoryGroups.get(id);
+ if (repo != null) {
+ repo = repositoryGroups.remove(id);
+ if (repo != null) {
+ repo.close();
+ RepositoryGroupConfiguration cfg = configuration.findRepositoryGroupById(id);
+ if (cfg != null) {
+ configuration.removeRepositoryGroup(cfg);
+ }
+ }
+ }
+
+ }
+
+ public RepositoryGroup getRepositoryGroup( String groupId ) {
+ return repositoryGroups.get(groupId);
+ }
+
+ public Collection<RepositoryGroup> getRepositoryGroups() {
+ return repositoryGroups.values( );
+ }
+
+ public boolean hasRepositoryGroup(String id) {
+ return repositoryGroups.containsKey( id );
+ }
+
+ @PreDestroy
+ private void destroy() {
+ this.close( );
+ }
+
+ public void close() {
+ for (RepositoryGroup group : repositoryGroups.values()) {
+ try
+ {
+ group.close( );
+ } catch (Throwable e) {
+ log.error( "Could not close repository group {}: {}", group.getId( ), e.getMessage( ) );
+ }
+ }
+ this.repositoryGroups.clear();
+ }
+
+}
@Inject
ArchivaConfiguration archivaConfiguration;
+ @SuppressWarnings( "unused" )
+ @Inject
+ RepositoryGroupHandler repositoryGroupHandler;
+
private static final Path userCfg = Paths.get(System.getProperty( "user.home" ), ".m2/archiva.xml");
private static Path cfgCopy;
import org.apache.archiva.indexer.IndexCreationFailedException;
import org.apache.archiva.repository.base.ArchivaRepositoryRegistry;
import org.apache.archiva.repository.RepositoryType;
+import org.apache.archiva.repository.base.RepositoryGroupHandler;
import org.apache.archiva.repository.features.IndexCreationFeature;
import org.apache.archiva.repository.features.RemoteIndexFeature;
import org.apache.archiva.repository.maven.MavenManagedRepository;
@Inject
ArchivaRepositoryRegistry repositoryRegistry;
+ @Inject
+ RepositoryGroupHandler groupHandler;
+
private Path indexPath;
private MavenManagedRepository repository;
import org.apache.archiva.proxy.ProxyRegistry;
import org.apache.archiva.repository.base.ArchivaRepositoryRegistry;
import org.apache.archiva.repository.Repository;
+import org.apache.archiva.repository.base.ConfigurationHandler;
+import org.apache.archiva.repository.base.RepositoryGroupHandler;
import org.apache.archiva.repository.features.IndexCreationFeature;
import org.apache.archiva.test.utils.ArchivaSpringJUnit4ClassRunner;
import org.apache.commons.lang3.SystemUtils;
@Inject
ArchivaRepositoryRegistry repositoryRegistry;
+ @Inject
+ RepositoryGroupHandler repositoryGroupHandler;
+
@Inject
ProxyRegistry proxyRegistry;
archivaConfig.addListener( EasyMock.anyObject( ConfigurationListener.class ) );
EasyMock.expect( archivaConfig.getDefaultLocale() ).andReturn( Locale.getDefault( ) ).anyTimes();
EasyMock.expect( archivaConfig.getConfiguration() ).andReturn(config).anyTimes();
- archivaConfig.save(EasyMock.anyObject(Configuration.class));
+ archivaConfig.save(EasyMock.anyObject(Configuration.class), EasyMock.anyString());
EasyMock.expectLastCall().anyTimes();
archivaConfigControl.replay();
repositoryRegistry.reload();
archivaConfigControl.reset();
EasyMock.expect( archivaConfig.getDefaultLocale() ).andReturn( Locale.getDefault( ) ).anyTimes();
EasyMock.expect( archivaConfig.getConfiguration() ).andReturn(config).anyTimes();
- archivaConfig.save(EasyMock.anyObject(Configuration.class));
+ archivaConfig.save(EasyMock.anyObject(Configuration.class), EasyMock.anyString());
EasyMock.expectLastCall().anyTimes();
archivaConfigControl.replay();
repositoryRegistry.removeRepository(TEST_REPO_1);
archivaConfigControl.reset();
archivaConfig.addListener( EasyMock.anyObject( ConfigurationListener.class ) );
EasyMock.expect( archivaConfig.getConfiguration() ).andReturn(config).anyTimes();
- archivaConfig.save(EasyMock.anyObject(Configuration.class));
+ archivaConfig.save(EasyMock.anyObject(Configuration.class), EasyMock.anyString());
EasyMock.expectLastCall().anyTimes();
archivaConfigControl.replay();
repositoryRegistry.reload();
import org.apache.archiva.indexer.search.SearchResultHit;
import org.apache.archiva.indexer.search.SearchResults;
import org.apache.archiva.repository.base.ArchivaRepositoryRegistry;
+import org.apache.archiva.repository.base.RepositoryGroupHandler;
import org.easymock.EasyMock;
import org.junit.After;
import org.junit.Test;
@Inject
ArchivaRepositoryRegistry repositoryRegistry;
+ @Inject
+ RepositoryGroupHandler repositoryGroupHandler;
+
@After
@Override
public void tearDown() throws Exception {
import org.apache.archiva.indexer.search.SearchResults;
import org.apache.archiva.indexer.util.SearchUtil;
import org.apache.archiva.repository.base.ArchivaRepositoryRegistry;
+import org.apache.archiva.repository.base.RepositoryGroupHandler;
import org.apache.archiva.test.utils.ArchivaSpringJUnit4ClassRunner;
import org.junit.After;
import org.junit.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
+import javax.inject.Inject;
import java.util.Arrays;
/**
extends TestCase
{
- @Autowired
+ @Inject
ArchivaRepositoryRegistry repositoryRegistry;
+ @Inject
+ RepositoryGroupHandler repositoryGroupHandler;
+
@After
public void endTests() {
assert repositoryRegistry!=null;
/* do nothing */
}
+ @Override
+ public void save( Configuration configuration, String eventTag ) throws RegistryException, IndeterminateConfigurationException
+ {
+ // do nothing
+ }
+
public void triggerChange( String name, String value )
{
for ( org.apache.archiva.components.registry.RegistryListener listener : registryListeners )
import org.apache.archiva.configuration.Configuration;
import org.apache.archiva.configuration.ConfigurationListener;
import org.apache.archiva.configuration.FileType;
+import org.apache.archiva.configuration.IndeterminateConfigurationException;
import org.apache.archiva.configuration.RepositoryScanningConfiguration;
import org.apache.commons.lang3.StringUtils;
import org.easymock.IMocksControl;
/* do nothing */
}
+ @Override
+ public void save( Configuration configuration, String eventTag ) throws RegistryException, IndeterminateConfigurationException
+ {
+ // do nothing
+ }
+
public void triggerChange( String name, String value )
{
for(RegistryListener listener: registryListeners)
import org.apache.archiva.repository.Repository;
import org.apache.archiva.repository.RepositoryException;
import org.apache.archiva.repository.base.ArchivaRepositoryRegistry;
+import org.apache.archiva.repository.base.ConfigurationHandler;
import java.util.Map;
import java.util.TreeMap;
private Map<String, ManagedRepository> managedRepositories = new TreeMap<>();
+ public RepositoryRegistryMock( ConfigurationHandler configurationHandler )
+ {
+ super( configurationHandler );
+ }
+
@Override
public ManagedRepository putRepository(ManagedRepository managedRepository) throws RepositoryException
{
this.configuration = configuration;
}
+ @Override
+ public void save( Configuration configuration, String eventTag ) throws RegistryException, IndeterminateConfigurationException
+ {
+ this.configuration = configuration;
+ }
+
@Override
public boolean isDefaulted()
{
this.configuration = configuration;
}
+ @Override
+ public void save( Configuration configuration, String eventTag ) throws RegistryException, IndeterminateConfigurationException
+ {
+ this.configuration = configuration;
+ }
+
@Override
public boolean isDefaulted()
{
import org.apache.archiva.repository.base.BasicManagedRepository;
import org.apache.archiva.repository.ManagedRepository;
import org.apache.archiva.repository.ReleaseScheme;
+import org.apache.archiva.repository.base.RepositoryGroupHandler;
import org.apache.archiva.repository.storage.StorageAsset;
import org.apache.archiva.repository.features.IndexCreationFeature;
import org.apache.archiva.scheduler.indexing.ArtifactIndexingTask;
@Inject
ArchivaRepositoryRegistry repositoryRegistry;
+ @Inject
+ RepositoryGroupHandler repositoryGroupHandler;
+
@Inject
private IndexUpdater indexUpdater;
import org.apache.archiva.components.taskqueue.execution.TaskExecutor;
import org.apache.archiva.repository.ManagedRepository;
import org.apache.archiva.repository.RepositoryRegistry;
+import org.apache.archiva.repository.base.RepositoryGroupHandler;
import org.apache.archiva.scheduler.repository.model.RepositoryTask;
import org.apache.archiva.test.utils.ArchivaSpringJUnit4ClassRunner;
import org.junit.After;
@Inject
RepositoryRegistry repositoryRegistry;
+ @Inject
+ RepositoryGroupHandler groupHandler;
+
@Inject
@Named( value = "taskExecutor#test-repository-scanning" )
protected TaskExecutor<RepositoryTask> taskExecutor;
+++ /dev/null
-package org.apache.archiva.rest.api.services.v2;
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-import io.swagger.v3.oas.annotations.Operation;
-import io.swagger.v3.oas.annotations.Parameter;
-import io.swagger.v3.oas.annotations.headers.Header;
-import io.swagger.v3.oas.annotations.media.Content;
-import io.swagger.v3.oas.annotations.media.Schema;
-import io.swagger.v3.oas.annotations.responses.ApiResponse;
-import io.swagger.v3.oas.annotations.security.OAuthScope;
-import io.swagger.v3.oas.annotations.security.SecurityRequirement;
-import io.swagger.v3.oas.annotations.tags.Tag;
-import org.apache.archiva.components.rest.model.PagedResult;
-import org.apache.archiva.redback.authorization.RedbackAuthorization;
-import org.apache.archiva.rest.api.model.v2.FileInfo;
-import org.apache.archiva.rest.api.model.v2.MavenManagedRepository;
-import org.apache.archiva.rest.api.model.v2.MavenManagedRepositoryUpdate;
-import org.apache.archiva.security.common.ArchivaRoleConstants;
-
-import javax.ws.rs.Consumes;
-import javax.ws.rs.DELETE;
-import javax.ws.rs.DefaultValue;
-import javax.ws.rs.GET;
-import javax.ws.rs.POST;
-import javax.ws.rs.PUT;
-import javax.ws.rs.Path;
-import javax.ws.rs.PathParam;
-import javax.ws.rs.Produces;
-import javax.ws.rs.QueryParam;
-import javax.ws.rs.core.MediaType;
-import javax.ws.rs.core.Response;
-import java.util.List;
-
-import static javax.ws.rs.core.MediaType.APPLICATION_JSON;
-import static org.apache.archiva.rest.api.services.v2.RestConfiguration.DEFAULT_PAGE_LIMIT;
-
-/**
- * @author Martin Stockhammer <martin_s@apache.org>
- * @since 3.0
- */
-@Schema( name = "ManagedRepositoryService", description = "Managing and configuration of managed repositories" )
-@Path( "repositories/maven/managed" )
-@Tag(name = "v2")
-@Tag(name = "v2/Repositories")
-public interface MavenManagedRepositoryService
-{
- @Path( "" )
- @GET
- @Produces( {APPLICATION_JSON} )
- @RedbackAuthorization( permissions = ArchivaRoleConstants.OPERATION_MANAGE_CONFIGURATION )
- @Operation( summary = "Returns all managed repositories.",
- parameters = {
- @Parameter( name = "q", description = "Search term" ),
- @Parameter( name = "offset", description = "The offset of the first element returned" ),
- @Parameter( name = "limit", description = "Maximum number of items to return in the response" ),
- @Parameter( name = "orderBy", description = "List of attribute used for sorting (key, value)" ),
- @Parameter( name = "order", description = "The sort order. Either ascending (asc) or descending (desc)" )
- },
- security = {
- @SecurityRequirement(
- name = ArchivaRoleConstants.OPERATION_MANAGE_CONFIGURATION
- )
- },
- responses = {
- @ApiResponse( responseCode = "200",
- description = "If the list could be returned",
- content = @Content( mediaType = APPLICATION_JSON, schema = @Schema( implementation = PagedResult.class ) )
- ),
- @ApiResponse( responseCode = "403", description = "Authenticated user is not permitted to gather the information",
- content = @Content( mediaType = APPLICATION_JSON, schema = @Schema( implementation = ArchivaRestError.class ) ) )
- }
- )
- PagedResult<MavenManagedRepository> getManagedRepositories(
- @QueryParam( "q" ) @DefaultValue( "" ) String searchTerm,
- @QueryParam( "offset" ) @DefaultValue( "0" ) Integer offset,
- @QueryParam( "limit" ) @DefaultValue( value = DEFAULT_PAGE_LIMIT ) Integer limit,
- @QueryParam( "orderBy" ) @DefaultValue( "id" ) List<String> orderBy,
- @QueryParam( "order" ) @DefaultValue( "asc" ) String order )
- throws ArchivaRestServiceException;
-
-
- @Path( "{id}" )
- @GET
- @Produces( {MediaType.APPLICATION_JSON} )
- @RedbackAuthorization( permissions = ArchivaRoleConstants.OPERATION_MANAGE_CONFIGURATION )
- @Operation( summary = "Returns the managed repository with the given id.",
- security = {
- @SecurityRequirement(
- name = ArchivaRoleConstants.OPERATION_MANAGE_CONFIGURATION
- )
- },
- responses = {
- @ApiResponse( responseCode = "200",
- description = "If the managed repository could be returned",
- content = @Content( mediaType = APPLICATION_JSON, schema = @Schema( implementation = MavenManagedRepository.class ) )
- ),
- @ApiResponse( responseCode = "403", description = "Authenticated user is not permitted to gather the information",
- content = @Content( mediaType = APPLICATION_JSON, schema = @Schema( implementation = ArchivaRestError.class ) ) ),
- @ApiResponse( responseCode = "404", description = "The managed repository with this id does not exist",
- content = @Content( mediaType = APPLICATION_JSON, schema = @Schema( implementation = ArchivaRestError.class ) ) )
- }
- )
- MavenManagedRepository getManagedRepository( @PathParam( "id" ) String repositoryId )
- throws ArchivaRestServiceException;
-
-
- @Path( "{id}" )
- @DELETE
- @Produces( {MediaType.APPLICATION_JSON} )
- @RedbackAuthorization( permissions = ArchivaRoleConstants.OPERATION_MANAGE_CONFIGURATION )
- @Operation( summary = "Deletes the managed repository with the given id.",
- security = {
- @SecurityRequirement(
- name = ArchivaRoleConstants.OPERATION_MANAGE_CONFIGURATION
- )
- },
- responses = {
- @ApiResponse( responseCode = "200",
- description = "If the managed repository could be returned"
- ),
- @ApiResponse( responseCode = "403", description = "Authenticated user is not permitted to gather the information",
- content = @Content( mediaType = APPLICATION_JSON, schema = @Schema( implementation = ArchivaRestError.class ) ) ),
- @ApiResponse( responseCode = "404", description = "The managed repository with this id does not exist",
- content = @Content( mediaType = APPLICATION_JSON, schema = @Schema( implementation = ArchivaRestError.class ) ) )
- }
- )
- Response deleteManagedRepository( @PathParam( "id" ) String repositoryId,
- @QueryParam( "deleteContent" ) boolean deleteContent )
- throws ArchivaRestServiceException;
-
-
- @Path( "" )
- @POST
- @Consumes( {MediaType.APPLICATION_JSON} )
- @Produces( {MediaType.APPLICATION_JSON} )
- @RedbackAuthorization( permissions = ArchivaRoleConstants.OPERATION_MANAGE_CONFIGURATION )
- @Operation( summary = "Creates the managed repository",
- security = {
- @SecurityRequirement(
- name = ArchivaRoleConstants.OPERATION_MANAGE_CONFIGURATION
- )
- },
- responses = {
- @ApiResponse( responseCode = "201",
- description = "If the managed repository could be created",
- content = @Content( mediaType = APPLICATION_JSON, schema = @Schema( implementation = MavenManagedRepository.class ) )
- ),
- @ApiResponse( responseCode = "303", description = "The repository exists already",
- headers = {
- @Header( name = "Location", description = "The URL of existing repository ", schema = @Schema( type = "string" ) )
- }
- ),
- @ApiResponse( responseCode = "403", description = "Authenticated user is not permitted to add repositories",
- content = @Content( mediaType = APPLICATION_JSON, schema = @Schema( implementation = ArchivaRestError.class ) ) ),
- @ApiResponse( responseCode = "422", description = "The body data is not valid",
- content = @Content( mediaType = APPLICATION_JSON, schema = @Schema( implementation = ArchivaRestError.class ) ) )
- }
- )
- MavenManagedRepository addManagedRepository( MavenManagedRepository managedRepository )
- throws ArchivaRestServiceException;
-
-
- @Path( "{id}" )
- @PUT
- @Consumes( {MediaType.APPLICATION_JSON} )
- @Produces( {MediaType.APPLICATION_JSON} )
- @RedbackAuthorization( permissions = ArchivaRoleConstants.OPERATION_MANAGE_CONFIGURATION )
- @Operation( summary = "Updates the managed repository with the given id",
- security = {
- @SecurityRequirement(
- name = ArchivaRoleConstants.OPERATION_MANAGE_CONFIGURATION
- )
- },
- responses = {
- @ApiResponse( responseCode = "200",
- description = "If the managed repository could be updated",
- content = @Content( mediaType = APPLICATION_JSON, schema = @Schema( implementation = MavenManagedRepository.class ) )
- ),
- @ApiResponse( responseCode = "403", description = "Authenticated user is not permitted to add repositories",
- content = @Content( mediaType = APPLICATION_JSON, schema = @Schema( implementation = ArchivaRestError.class ) ) ),
- @ApiResponse( responseCode = "422", description = "The body data is not valid",
- content = @Content( mediaType = APPLICATION_JSON, schema = @Schema( implementation = ArchivaRestError.class ) ) ),
- @ApiResponse( responseCode = "404", description = "The managed repository with this id does not exist",
- content = @Content( mediaType = APPLICATION_JSON, schema = @Schema( implementation = ArchivaRestError.class ) ) )
- }
- )
- MavenManagedRepository updateManagedRepository( @PathParam( "id" ) String repositoryId, MavenManagedRepositoryUpdate managedRepository )
- throws ArchivaRestServiceException;
-
-
- @Path( "{id}/path/{filePath: .+}" )
- @GET
- @Produces( {MediaType.APPLICATION_JSON} )
- @RedbackAuthorization( permissions = ArchivaRoleConstants.OPERATION_REPOSITORY_ACCESS, resource = "{id}")
- @Operation( summary = "Returns the status of a given file in the repository",
- security = {
- @SecurityRequirement(
- name = ArchivaRoleConstants.OPERATION_MANAGE_CONFIGURATION
- )
- },
- responses = {
- @ApiResponse( responseCode = "200",
- description = "If the file status is returned",
- content = @Content( mediaType = APPLICATION_JSON, schema = @Schema( implementation = FileInfo.class ) )
- ),
- @ApiResponse( responseCode = "403", description = "Authenticated user is not permitted to add repositories",
- content = @Content( mediaType = APPLICATION_JSON, schema = @Schema( implementation = ArchivaRestError.class ) ) ),
- @ApiResponse( responseCode = "404", description = "The managed repository with this id does not exist. Or the file does not exist.",
- content = @Content( mediaType = APPLICATION_JSON, schema = @Schema( implementation = ArchivaRestError.class ) ) )
- }
- )
- FileInfo getFileStatus( @PathParam( "id" ) String repositoryId, @PathParam( "filePath" ) String fileLocation )
- throws ArchivaRestServiceException;
-
-
- /**
- * Permissions are checked in impl
- * will copy an artifact from the source repository to the target repository
- */
- @Path ("{srcId}/path/{path: .+}/copyto/{dstId}")
- @POST
- @Produces({APPLICATION_JSON})
- @RedbackAuthorization (noPermission = true)
- @Operation( summary = "Copies a artifact from the source repository to the destination repository",
- security = {
- @SecurityRequirement(
- name = ArchivaRoleConstants.OPERATION_REPOSITORY_ACCESS,
- scopes = {
- "{srcId}"
- }
- ),
- @SecurityRequirement(
- name= ArchivaRoleConstants.OPERATION_REPOSITORY_UPLOAD,
- scopes = {
- "{dstId}"
- }
- )
-
- },
- responses = {
- @ApiResponse( responseCode = "200",
- description = "If the artifact was copied"
- ),
- @ApiResponse( responseCode = "403", description = "Authenticated user is not permitted to gather the information",
- content = @Content( mediaType = APPLICATION_JSON, schema = @Schema( implementation = ArchivaRestError.class ) ) ),
- @ApiResponse( responseCode = "404", description = "The repository does not exist, or if the artifact was not found",
- content = @Content( mediaType = APPLICATION_JSON, schema = @Schema( implementation = ArchivaRestError.class ) ) )
- }
- )
- Response copyArtifact( @PathParam( "srcId" ) String srcRepositoryId, @PathParam( "dstId" ) String dstRepositoryId,
- @PathParam( "path" ) String path )
- throws ArchivaRestServiceException;
-
-
- @Path ("{id}/path/{path: .+}")
- @DELETE
- @Consumes ({ APPLICATION_JSON })
- @RedbackAuthorization (noPermission = true)
- @Operation( summary = "Deletes a artifact in the repository.",
- security = {
- @SecurityRequirement(
- name = ArchivaRoleConstants.OPERATION_RUN_INDEXER
- )
- },
- responses = {
- @ApiResponse( responseCode = "200",
- description = "If the artifact was deleted"
- ),
- @ApiResponse( responseCode = "403", description = "Authenticated user is not permitted to gather the information",
- content = @Content( mediaType = APPLICATION_JSON, schema = @Schema( implementation = ArchivaRestError.class ) ) ),
- @ApiResponse( responseCode = "404", description = "The repository or the artifact does not exist",
- content = @Content( mediaType = APPLICATION_JSON, schema = @Schema( implementation = ArchivaRestError.class ) ) )
- }
- )
- Response deleteArtifact( @PathParam( "id" ) String repositoryId, @PathParam( "path" ) String path )
- throws ArchivaRestServiceException;
-
- @Path ( "{id}/co/{group}/{project}/{version}" )
- @DELETE
- @Produces ({ MediaType.APPLICATION_JSON })
- @RedbackAuthorization (noPermission = true)
- @Operation( summary = "Removes a version tree in the repository",
- security = {
- @SecurityRequirement(
- name = ArchivaRoleConstants.OPERATION_MANAGE_CONFIGURATION
- )
- },
- responses = {
- @ApiResponse( responseCode = "200",
- description = "If the deletion was successful"
- ),
- @ApiResponse( responseCode = "403", description = "Authenticated user is not permitted to delete in repositories",
- content = @Content( mediaType = APPLICATION_JSON, schema = @Schema( implementation = ArchivaRestError.class ) ) ),
- @ApiResponse( responseCode = "404", description = "The managed repository with this id does not exist. Or the version does not exist.",
- content = @Content( mediaType = APPLICATION_JSON, schema = @Schema( implementation = ArchivaRestError.class ) ) )
- }
- )
- Response removeProjectVersion( @PathParam ( "id" ) String repositoryId,
- @PathParam ( "group" ) String namespace, @PathParam ( "project" ) String projectId,
- @PathParam ( "version" ) String version )
- throws org.apache.archiva.rest.api.services.ArchivaRestServiceException;
-
-
- @Path ( "{id}/co/{group}/{project}" )
- @DELETE
- @Produces ({ MediaType.APPLICATION_JSON })
- @RedbackAuthorization (noPermission = true)
- @Operation( summary = "Removes a project tree in the repository",
- security = {
- @SecurityRequirement(
- name = ArchivaRoleConstants.OPERATION_MANAGE_CONFIGURATION
- )
- },
- responses = {
- @ApiResponse( responseCode = "200",
- description = "If the deletion was successful"
- ),
- @ApiResponse( responseCode = "403", description = "Authenticated user is not permitted to delete in repositories",
- content = @Content( mediaType = APPLICATION_JSON, schema = @Schema( implementation = ArchivaRestError.class ) ) ),
- @ApiResponse( responseCode = "404", description = "The managed repository with this id does not exist. Or the project does not exist.",
- content = @Content( mediaType = APPLICATION_JSON, schema = @Schema( implementation = ArchivaRestError.class ) ) )
- }
- )
- Response deleteProject( @PathParam ("id") String repositoryId, @PathParam ( "group" ) String namespace, @PathParam ( "project" ) String projectId )
- throws org.apache.archiva.rest.api.services.ArchivaRestServiceException;
-
- @Path ( "{id}/co/{namespace}" )
- @DELETE
- @Produces ({ MediaType.APPLICATION_JSON })
- @RedbackAuthorization (noPermission = true)
- @Operation( summary = "Removes a namespace tree in the repository",
- security = {
- @SecurityRequirement(
- name = ArchivaRoleConstants.OPERATION_MANAGE_CONFIGURATION
- )
- },
- responses = {
- @ApiResponse( responseCode = "200",
- description = "If the deletion was successful"
- ),
- @ApiResponse( responseCode = "403", description = "Authenticated user is not permitted to delete namespaces in repositories",
- content = @Content( mediaType = APPLICATION_JSON, schema = @Schema( implementation = ArchivaRestError.class ) ) ),
- @ApiResponse( responseCode = "404", description = "The managed repository with this id does not exist. Or the namespace does not exist.",
- content = @Content( mediaType = APPLICATION_JSON, schema = @Schema( implementation = ArchivaRestError.class ) ) )
- }
- )
- Response deleteNamespace( @PathParam ("id") String repositoryId, @PathParam ( "namespace" ) String namespace )
- throws org.apache.archiva.rest.api.services.ArchivaRestServiceException;
-
-}
* @since 3.0
*/
@Path( "/repository_groups" )
-@Schema( name="RepositoryGroups", description = "Managing of repository groups or virtual repositories")
+@Schema( name = "RepositoryGroups", description = "Managing of repository groups or virtual repositories" )
public interface RepositoryGroupService
{
@Path( "" )
@GET
- @Produces( { APPLICATION_JSON } )
+ @Produces( {APPLICATION_JSON} )
@RedbackAuthorization( permissions = ArchivaRoleConstants.OPERATION_MANAGE_CONFIGURATION )
@Operation( summary = "Returns all repository group entries.",
parameters = {
- @Parameter(name = "q", description = "Search term"),
- @Parameter(name = "offset", description = "The offset of the first element returned"),
- @Parameter(name = "limit", description = "Maximum number of items to return in the response"),
- @Parameter(name = "orderBy", description = "List of attribute used for sorting (key, value)"),
- @Parameter(name = "order", description = "The sort order. Either ascending (asc) or descending (desc)")
+ @Parameter( name = "q", description = "Search term" ),
+ @Parameter( name = "offset", description = "The offset of the first element returned" ),
+ @Parameter( name = "limit", description = "Maximum number of items to return in the response" ),
+ @Parameter( name = "orderBy", description = "List of attribute used for sorting (key, value)" ),
+ @Parameter( name = "order", description = "The sort order. Either ascending (asc) or descending (desc)" )
},
security = {
@SecurityRequirement(
responses = {
@ApiResponse( responseCode = "200",
description = "If the list could be returned",
- content = @Content(mediaType = APPLICATION_JSON, schema = @Schema(implementation = PagedResult.class))
+ content = @Content( mediaType = APPLICATION_JSON, schema = @Schema( implementation = PagedResult.class ) )
),
@ApiResponse( responseCode = "403", description = "Authenticated user is not permitted to gather the information",
- content = @Content(mediaType = APPLICATION_JSON, schema = @Schema(implementation = ArchivaRestError.class )) )
+ content = @Content( mediaType = APPLICATION_JSON, schema = @Schema( implementation = ArchivaRestError.class ) ) )
}
)
- PagedResult<RepositoryGroup> getRepositoriesGroups(@QueryParam("q") @DefaultValue( "" ) String searchTerm,
- @QueryParam( "offset" ) @DefaultValue( "0" ) Integer offset,
- @QueryParam( "limit" ) @DefaultValue( value = DEFAULT_PAGE_LIMIT ) Integer limit,
- @QueryParam( "orderBy") @DefaultValue( "id" ) List<String> orderBy,
- @QueryParam("order") @DefaultValue( "asc" ) String order)
+ PagedResult<RepositoryGroup> getRepositoriesGroups( @QueryParam( "q" ) @DefaultValue( "" ) String searchTerm,
+ @QueryParam( "offset" ) @DefaultValue( "0" ) Integer offset,
+ @QueryParam( "limit" ) @DefaultValue( value = DEFAULT_PAGE_LIMIT ) Integer limit,
+ @QueryParam( "orderBy" ) @DefaultValue( "id" ) List<String> orderBy,
+ @QueryParam( "order" ) @DefaultValue( "asc" ) String order )
throws ArchivaRestServiceException;
@Path( "{repositoryGroupId}" )
@GET
- @Produces( { APPLICATION_JSON } )
+ @Produces( {APPLICATION_JSON} )
@RedbackAuthorization( permissions = ArchivaRoleConstants.OPERATION_MANAGE_CONFIGURATION )
@Operation( summary = "Returns a single repository group configuration.",
security = {
responses = {
@ApiResponse( responseCode = "200",
description = "If the configuration is returned",
- content = @Content(mediaType = APPLICATION_JSON, schema = @Schema(implementation = RepositoryGroup.class))
+ content = @Content( mediaType = APPLICATION_JSON, schema = @Schema( implementation = RepositoryGroup.class ) )
),
@ApiResponse( responseCode = "403", description = "Authenticated user is not permitted to gather the information",
- content = @Content(mediaType = APPLICATION_JSON, schema = @Schema(implementation = ArchivaRestError.class )) ),
+ content = @Content( mediaType = APPLICATION_JSON, schema = @Schema( implementation = ArchivaRestError.class ) ) ),
@ApiResponse( responseCode = "404", description = "The repository group with the given id does not exist",
- content = @Content(mediaType = APPLICATION_JSON, schema = @Schema(implementation = ArchivaRestError.class )) )
+ content = @Content( mediaType = APPLICATION_JSON, schema = @Schema( implementation = ArchivaRestError.class ) ) )
}
)
RepositoryGroup getRepositoryGroup( @PathParam( "repositoryGroupId" ) String repositoryGroupId )
@Path( "" )
@POST
- @Consumes( { APPLICATION_JSON } )
- @Produces( { APPLICATION_JSON } )
+ @Consumes( {APPLICATION_JSON} )
+ @Produces( {APPLICATION_JSON} )
@RedbackAuthorization( permissions = ArchivaRoleConstants.OPERATION_MANAGE_CONFIGURATION )
@Operation( summary = "Creates a new group entry.",
requestBody =
- @RequestBody(required = true, description = "The configuration of the repository group.",
- content = @Content(mediaType = APPLICATION_JSON, schema = @Schema(implementation = RepositoryGroup.class))
- )
+ @RequestBody( required = true, description = "The configuration of the repository group.",
+ content = @Content( mediaType = APPLICATION_JSON, schema = @Schema( implementation = RepositoryGroup.class ) )
+ )
,
security = {
@SecurityRequirement(
responses = {
@ApiResponse( responseCode = "201",
description = "If the list could be returned",
- content = @Content(mediaType = APPLICATION_JSON, schema = @Schema(implementation = RepositoryGroup.class))
+ content = @Content( mediaType = APPLICATION_JSON, schema = @Schema( implementation = RepositoryGroup.class ) )
),
@ApiResponse( responseCode = "303", description = "The repository group exists already",
headers = {
- @Header( name="Location", description = "The URL of existing group", schema = @Schema(type="string"))
+ @Header( name = "Location", description = "The URL of existing group", schema = @Schema( type = "string" ) )
}
),
@ApiResponse( responseCode = "403", description = "Authenticated user is not permitted to gather the information",
- content = @Content(mediaType = APPLICATION_JSON, schema = @Schema(implementation = ArchivaRestError.class )) ),
+ content = @Content( mediaType = APPLICATION_JSON, schema = @Schema( implementation = ArchivaRestError.class ) ) ),
@ApiResponse( responseCode = "422", description = "The body data is not valid",
- content = @Content(mediaType = APPLICATION_JSON, schema = @Schema(implementation = ArchivaRestError.class )) )
+ content = @Content( mediaType = APPLICATION_JSON, schema = @Schema( implementation = ArchivaRestError.class ) ) )
}
)
RepositoryGroup addRepositoryGroup( RepositoryGroup repositoryGroup )
@Path( "{repositoryGroupId}" )
@PUT
- @Consumes( { APPLICATION_JSON } )
- @Produces( { APPLICATION_JSON } )
+ @Consumes( {APPLICATION_JSON} )
+ @Produces( {APPLICATION_JSON} )
@RedbackAuthorization( permissions = ArchivaRoleConstants.OPERATION_MANAGE_CONFIGURATION )
@Operation( summary = "Returns all repository group entries.",
requestBody =
- @RequestBody(required = true, description = "The configuration of the repository group.",
- content = @Content(mediaType = APPLICATION_JSON, schema = @Schema(implementation = RepositoryGroup.class))
+ @RequestBody( required = true, description = "The configuration of the repository group.",
+ content = @Content( mediaType = APPLICATION_JSON, schema = @Schema( implementation = RepositoryGroup.class ) )
)
,
security = {
responses = {
@ApiResponse( responseCode = "200",
description = "If the group is returned",
- content = @Content(mediaType = APPLICATION_JSON, schema = @Schema(implementation = RepositoryGroup.class))
+ content = @Content( mediaType = APPLICATION_JSON, schema = @Schema( implementation = RepositoryGroup.class ) )
),
@ApiResponse( responseCode = "403", description = "Authenticated user is not permitted to gather the information",
- content = @Content(mediaType = APPLICATION_JSON, schema = @Schema(implementation = ArchivaRestError.class )) ),
+ content = @Content( mediaType = APPLICATION_JSON, schema = @Schema( implementation = ArchivaRestError.class ) ) ),
@ApiResponse( responseCode = "404", description = "The group with the given id does not exist",
- content = @Content(mediaType = APPLICATION_JSON, schema = @Schema(implementation = ArchivaRestError.class )) ),
+ content = @Content( mediaType = APPLICATION_JSON, schema = @Schema( implementation = ArchivaRestError.class ) ) ),
@ApiResponse( responseCode = "422", description = "The body data is not valid",
- content = @Content(mediaType = APPLICATION_JSON, schema = @Schema(implementation = ArchivaRestError.class )) )
+ content = @Content( mediaType = APPLICATION_JSON, schema = @Schema( implementation = ArchivaRestError.class ) ) )
}
)
RepositoryGroup updateRepositoryGroup( @PathParam( "repositoryGroupId" ) String groupId, RepositoryGroup repositoryGroup )
@Path( "{repositoryGroupId}" )
@DELETE
- @Produces( { APPLICATION_JSON } )
+ @Produces( {APPLICATION_JSON} )
@RedbackAuthorization( permissions = ArchivaRoleConstants.OPERATION_MANAGE_CONFIGURATION )
@Operation( summary = "Deletes the repository group entry with the given id.",
security = {
description = "If the group was deleted"
),
@ApiResponse( responseCode = "403", description = "Authenticated user is not permitted to delete the group",
- content = @Content(mediaType = APPLICATION_JSON, schema = @Schema(implementation = ArchivaRestError.class )) ),
+ content = @Content( mediaType = APPLICATION_JSON, schema = @Schema( implementation = ArchivaRestError.class ) ) ),
@ApiResponse( responseCode = "404", description = "The group with the given id does not exist",
- content = @Content(mediaType = APPLICATION_JSON, schema = @Schema(implementation = ArchivaRestError.class )) ),
+ content = @Content( mediaType = APPLICATION_JSON, schema = @Schema( implementation = ArchivaRestError.class ) ) ),
}
)
Response deleteRepositoryGroup( @PathParam( "repositoryGroupId" ) String repositoryGroupId )
@Path( "{repositoryGroupId}/repositories/{repositoryId}" )
@PUT
- @Produces( { APPLICATION_JSON } )
+ @Produces( {APPLICATION_JSON} )
@RedbackAuthorization( permissions = ArchivaRoleConstants.OPERATION_MANAGE_CONFIGURATION )
@Operation( summary = "Adds the repository with the given id to the repository group.",
security = {
description = "If the repository was added or if it was already part of the group"
),
@ApiResponse( responseCode = "403", description = "Authenticated user is not permitted to delete the group",
- content = @Content(mediaType = APPLICATION_JSON, schema = @Schema(implementation = ArchivaRestError.class )) ),
+ content = @Content( mediaType = APPLICATION_JSON, schema = @Schema( implementation = ArchivaRestError.class ) ) ),
@ApiResponse( responseCode = "404", description = "The group with the given id does not exist",
- content = @Content(mediaType = APPLICATION_JSON, schema = @Schema(implementation = ArchivaRestError.class )) ),
+ content = @Content( mediaType = APPLICATION_JSON, schema = @Schema( implementation = ArchivaRestError.class ) ) ),
}
)
RepositoryGroup addRepositoryToGroup( @PathParam( "repositoryGroupId" ) String repositoryGroupId,
- @PathParam( "repositoryId" ) String repositoryId )
+ @PathParam( "repositoryId" ) String repositoryId )
throws ArchivaRestServiceException;
@Path( "{repositoryGroupId}/repositories/{repositoryId}" )
@DELETE
- @Produces( { APPLICATION_JSON } )
+ @Produces( {APPLICATION_JSON} )
@RedbackAuthorization( permissions = ArchivaRoleConstants.OPERATION_MANAGE_CONFIGURATION )
@Operation( summary = "Removes the repository with the given id from the repository group.",
security = {
description = "If the repository was removed."
),
@ApiResponse( responseCode = "403", description = "Authenticated user is not permitted to delete the group",
- content = @Content(mediaType = APPLICATION_JSON, schema = @Schema(implementation = ArchivaRestError.class )) ),
+ content = @Content( mediaType = APPLICATION_JSON, schema = @Schema( implementation = ArchivaRestError.class ) ) ),
@ApiResponse( responseCode = "404", description = "The group with the given id does not exist, or the repository was not part of the group.",
- content = @Content(mediaType = APPLICATION_JSON, schema = @Schema(implementation = ArchivaRestError.class )) ),
+ content = @Content( mediaType = APPLICATION_JSON, schema = @Schema( implementation = ArchivaRestError.class ) ) ),
}
)
RepositoryGroup deleteRepositoryFromGroup( @PathParam( "repositoryGroupId" ) String repositoryGroupId,
- @PathParam( "repositoryId" ) String repositoryId )
+ @PathParam( "repositoryId" ) String repositoryId )
throws ArchivaRestServiceException;
--- /dev/null
+package org.apache.archiva.rest.api.services.v2.maven;
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import io.swagger.v3.oas.annotations.Operation;
+import io.swagger.v3.oas.annotations.Parameter;
+import io.swagger.v3.oas.annotations.headers.Header;
+import io.swagger.v3.oas.annotations.media.Content;
+import io.swagger.v3.oas.annotations.media.Schema;
+import io.swagger.v3.oas.annotations.responses.ApiResponse;
+import io.swagger.v3.oas.annotations.security.OAuthScope;
+import io.swagger.v3.oas.annotations.security.SecurityRequirement;
+import io.swagger.v3.oas.annotations.tags.Tag;
+import org.apache.archiva.components.rest.model.PagedResult;
+import org.apache.archiva.redback.authorization.RedbackAuthorization;
+import org.apache.archiva.rest.api.model.v2.FileInfo;
+import org.apache.archiva.rest.api.model.v2.MavenManagedRepository;
+import org.apache.archiva.rest.api.model.v2.MavenManagedRepositoryUpdate;
+import org.apache.archiva.rest.api.services.v2.ArchivaRestError;
+import org.apache.archiva.rest.api.services.v2.ArchivaRestServiceException;
+import org.apache.archiva.security.common.ArchivaRoleConstants;
+
+import javax.ws.rs.Consumes;
+import javax.ws.rs.DELETE;
+import javax.ws.rs.DefaultValue;
+import javax.ws.rs.GET;
+import javax.ws.rs.POST;
+import javax.ws.rs.PUT;
+import javax.ws.rs.Path;
+import javax.ws.rs.PathParam;
+import javax.ws.rs.Produces;
+import javax.ws.rs.QueryParam;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.Response;
+import java.util.List;
+
+import static javax.ws.rs.core.MediaType.APPLICATION_JSON;
+import static org.apache.archiva.rest.api.services.v2.RestConfiguration.DEFAULT_PAGE_LIMIT;
+
+/**
+ * Service interface for managing managed maven repositories
+ *
+ * @author Martin Stockhammer <martin_s@apache.org>
+ * @since 3.0
+ */
+@Schema( name = "ManagedRepositoryService", description = "Managing and configuration of managed repositories" )
+@Path( "repositories/maven/managed" )
+@Tag(name = "v2")
+@Tag(name = "v2/Repositories")
+public interface MavenManagedRepositoryService
+{
+ @Path( "" )
+ @GET
+ @Produces( {APPLICATION_JSON} )
+ @RedbackAuthorization( permissions = ArchivaRoleConstants.OPERATION_MANAGE_CONFIGURATION )
+ @Operation( summary = "Returns all managed repositories.",
+ parameters = {
+ @Parameter( name = "q", description = "Search term" ),
+ @Parameter( name = "offset", description = "The offset of the first element returned" ),
+ @Parameter( name = "limit", description = "Maximum number of items to return in the response" ),
+ @Parameter( name = "orderBy", description = "List of attribute used for sorting (key, value)" ),
+ @Parameter( name = "order", description = "The sort order. Either ascending (asc) or descending (desc)" )
+ },
+ security = {
+ @SecurityRequirement(
+ name = ArchivaRoleConstants.OPERATION_MANAGE_CONFIGURATION
+ )
+ },
+ responses = {
+ @ApiResponse( responseCode = "200",
+ description = "If the list could be returned",
+ content = @Content( mediaType = APPLICATION_JSON, schema = @Schema( implementation = PagedResult.class ) )
+ ),
+ @ApiResponse( responseCode = "403", description = "Authenticated user is not permitted to gather the information",
+ content = @Content( mediaType = APPLICATION_JSON, schema = @Schema( implementation = ArchivaRestError.class ) ) )
+ }
+ )
+ PagedResult<MavenManagedRepository> getManagedRepositories(
+ @QueryParam( "q" ) @DefaultValue( "" ) String searchTerm,
+ @QueryParam( "offset" ) @DefaultValue( "0" ) Integer offset,
+ @QueryParam( "limit" ) @DefaultValue( value = DEFAULT_PAGE_LIMIT ) Integer limit,
+ @QueryParam( "orderBy" ) @DefaultValue( "id" ) List<String> orderBy,
+ @QueryParam( "order" ) @DefaultValue( "asc" ) String order )
+ throws ArchivaRestServiceException;
+
+
+ @Path( "{id}" )
+ @GET
+ @Produces( {MediaType.APPLICATION_JSON} )
+ @RedbackAuthorization( permissions = ArchivaRoleConstants.OPERATION_MANAGE_CONFIGURATION )
+ @Operation( summary = "Returns the managed repository with the given id.",
+ security = {
+ @SecurityRequirement(
+ name = ArchivaRoleConstants.OPERATION_MANAGE_CONFIGURATION
+ )
+ },
+ responses = {
+ @ApiResponse( responseCode = "200",
+ description = "If the managed repository could be returned",
+ content = @Content( mediaType = APPLICATION_JSON, schema = @Schema( implementation = MavenManagedRepository.class ) )
+ ),
+ @ApiResponse( responseCode = "403", description = "Authenticated user is not permitted to gather the information",
+ content = @Content( mediaType = APPLICATION_JSON, schema = @Schema( implementation = ArchivaRestError.class ) ) ),
+ @ApiResponse( responseCode = "404", description = "The managed repository with this id does not exist",
+ content = @Content( mediaType = APPLICATION_JSON, schema = @Schema( implementation = ArchivaRestError.class ) ) )
+ }
+ )
+ MavenManagedRepository getManagedRepository( @PathParam( "id" ) String repositoryId )
+ throws ArchivaRestServiceException;
+
+
+ @Path( "{id}" )
+ @DELETE
+ @Produces( {MediaType.APPLICATION_JSON} )
+ @RedbackAuthorization( permissions = ArchivaRoleConstants.OPERATION_MANAGE_CONFIGURATION )
+ @Operation( summary = "Deletes the managed repository with the given id.",
+ security = {
+ @SecurityRequirement(
+ name = ArchivaRoleConstants.OPERATION_MANAGE_CONFIGURATION
+ )
+ },
+ responses = {
+ @ApiResponse( responseCode = "200",
+ description = "If the managed repository could be returned"
+ ),
+ @ApiResponse( responseCode = "403", description = "Authenticated user is not permitted to gather the information",
+ content = @Content( mediaType = APPLICATION_JSON, schema = @Schema( implementation = ArchivaRestError.class ) ) ),
+ @ApiResponse( responseCode = "404", description = "The managed repository with this id does not exist",
+ content = @Content( mediaType = APPLICATION_JSON, schema = @Schema( implementation = ArchivaRestError.class ) ) )
+ }
+ )
+ Response deleteManagedRepository( @PathParam( "id" ) String repositoryId,
+ @QueryParam( "deleteContent" ) boolean deleteContent )
+ throws ArchivaRestServiceException;
+
+
+ @Path( "" )
+ @POST
+ @Consumes( {MediaType.APPLICATION_JSON} )
+ @Produces( {MediaType.APPLICATION_JSON} )
+ @RedbackAuthorization( permissions = ArchivaRoleConstants.OPERATION_MANAGE_CONFIGURATION )
+ @Operation( summary = "Creates the managed repository",
+ security = {
+ @SecurityRequirement(
+ name = ArchivaRoleConstants.OPERATION_MANAGE_CONFIGURATION
+ )
+ },
+ responses = {
+ @ApiResponse( responseCode = "201",
+ description = "If the managed repository could be created",
+ content = @Content( mediaType = APPLICATION_JSON, schema = @Schema( implementation = MavenManagedRepository.class ) )
+ ),
+ @ApiResponse( responseCode = "303", description = "The repository exists already",
+ headers = {
+ @Header( name = "Location", description = "The URL of existing repository ", schema = @Schema( type = "string" ) )
+ }
+ ),
+ @ApiResponse( responseCode = "403", description = "Authenticated user is not permitted to add repositories",
+ content = @Content( mediaType = APPLICATION_JSON, schema = @Schema( implementation = ArchivaRestError.class ) ) ),
+ @ApiResponse( responseCode = "422", description = "The body data is not valid",
+ content = @Content( mediaType = APPLICATION_JSON, schema = @Schema( implementation = ArchivaRestError.class ) ) )
+ }
+ )
+ MavenManagedRepository addManagedRepository( MavenManagedRepository managedRepository )
+ throws ArchivaRestServiceException;
+
+
+ @Path( "{id}" )
+ @PUT
+ @Consumes( {MediaType.APPLICATION_JSON} )
+ @Produces( {MediaType.APPLICATION_JSON} )
+ @RedbackAuthorization( permissions = ArchivaRoleConstants.OPERATION_MANAGE_CONFIGURATION )
+ @Operation( summary = "Updates the managed repository with the given id",
+ security = {
+ @SecurityRequirement(
+ name = ArchivaRoleConstants.OPERATION_MANAGE_CONFIGURATION
+ )
+ },
+ responses = {
+ @ApiResponse( responseCode = "200",
+ description = "If the managed repository could be updated",
+ content = @Content( mediaType = APPLICATION_JSON, schema = @Schema( implementation = MavenManagedRepository.class ) )
+ ),
+ @ApiResponse( responseCode = "403", description = "Authenticated user is not permitted to add repositories",
+ content = @Content( mediaType = APPLICATION_JSON, schema = @Schema( implementation = ArchivaRestError.class ) ) ),
+ @ApiResponse( responseCode = "422", description = "The body data is not valid",
+ content = @Content( mediaType = APPLICATION_JSON, schema = @Schema( implementation = ArchivaRestError.class ) ) ),
+ @ApiResponse( responseCode = "404", description = "The managed repository with this id does not exist",
+ content = @Content( mediaType = APPLICATION_JSON, schema = @Schema( implementation = ArchivaRestError.class ) ) )
+ }
+ )
+ MavenManagedRepository updateManagedRepository( @PathParam( "id" ) String repositoryId, MavenManagedRepositoryUpdate managedRepository )
+ throws ArchivaRestServiceException;
+
+
+ @Path( "{id}/path/{filePath: .+}" )
+ @GET
+ @Produces( {MediaType.APPLICATION_JSON} )
+ @RedbackAuthorization( permissions = ArchivaRoleConstants.OPERATION_REPOSITORY_ACCESS, resource = "{id}")
+ @Operation( summary = "Returns the status of a given file in the repository",
+ security = {
+ @SecurityRequirement(
+ name = ArchivaRoleConstants.OPERATION_MANAGE_CONFIGURATION
+ )
+ },
+ responses = {
+ @ApiResponse( responseCode = "200",
+ description = "If the file status is returned",
+ content = @Content( mediaType = APPLICATION_JSON, schema = @Schema( implementation = FileInfo.class ) )
+ ),
+ @ApiResponse( responseCode = "403", description = "Authenticated user is not permitted to add repositories",
+ content = @Content( mediaType = APPLICATION_JSON, schema = @Schema( implementation = ArchivaRestError.class ) ) ),
+ @ApiResponse( responseCode = "404", description = "The managed repository with this id does not exist. Or the file does not exist.",
+ content = @Content( mediaType = APPLICATION_JSON, schema = @Schema( implementation = ArchivaRestError.class ) ) )
+ }
+ )
+ FileInfo getFileStatus( @PathParam( "id" ) String repositoryId, @PathParam( "filePath" ) String fileLocation )
+ throws ArchivaRestServiceException;
+
+
+ /**
+ * Permissions are checked in impl
+ * will copy an artifact from the source repository to the target repository
+ */
+ @Path ("{srcId}/path/{path: .+}/copyto/{dstId}")
+ @POST
+ @Produces({APPLICATION_JSON})
+ @RedbackAuthorization (noPermission = true)
+ @Operation( summary = "Copies a artifact from the source repository to the destination repository",
+ security = {
+ @SecurityRequirement(
+ name = ArchivaRoleConstants.OPERATION_REPOSITORY_ACCESS,
+ scopes = {
+ "{srcId}"
+ }
+ ),
+ @SecurityRequirement(
+ name= ArchivaRoleConstants.OPERATION_REPOSITORY_UPLOAD,
+ scopes = {
+ "{dstId}"
+ }
+ )
+
+ },
+ responses = {
+ @ApiResponse( responseCode = "200",
+ description = "If the artifact was copied"
+ ),
+ @ApiResponse( responseCode = "403", description = "Authenticated user is not permitted to gather the information",
+ content = @Content( mediaType = APPLICATION_JSON, schema = @Schema( implementation = ArchivaRestError.class ) ) ),
+ @ApiResponse( responseCode = "404", description = "The repository does not exist, or if the artifact was not found",
+ content = @Content( mediaType = APPLICATION_JSON, schema = @Schema( implementation = ArchivaRestError.class ) ) )
+ }
+ )
+ Response copyArtifact( @PathParam( "srcId" ) String srcRepositoryId, @PathParam( "dstId" ) String dstRepositoryId,
+ @PathParam( "path" ) String path )
+ throws ArchivaRestServiceException;
+
+
+ @Path ("{id}/path/{path: .+}")
+ @DELETE
+ @Consumes ({ APPLICATION_JSON })
+ @RedbackAuthorization (noPermission = true)
+ @Operation( summary = "Deletes a artifact in the repository.",
+ security = {
+ @SecurityRequirement(
+ name = ArchivaRoleConstants.OPERATION_RUN_INDEXER
+ )
+ },
+ responses = {
+ @ApiResponse( responseCode = "200",
+ description = "If the artifact was deleted"
+ ),
+ @ApiResponse( responseCode = "403", description = "Authenticated user is not permitted to gather the information",
+ content = @Content( mediaType = APPLICATION_JSON, schema = @Schema( implementation = ArchivaRestError.class ) ) ),
+ @ApiResponse( responseCode = "404", description = "The repository or the artifact does not exist",
+ content = @Content( mediaType = APPLICATION_JSON, schema = @Schema( implementation = ArchivaRestError.class ) ) )
+ }
+ )
+ Response deleteArtifact( @PathParam( "id" ) String repositoryId, @PathParam( "path" ) String path )
+ throws ArchivaRestServiceException;
+
+ @Path ( "{id}/co/{group}/{project}/{version}" )
+ @DELETE
+ @Produces ({ MediaType.APPLICATION_JSON })
+ @RedbackAuthorization (noPermission = true)
+ @Operation( summary = "Removes a version tree in the repository",
+ security = {
+ @SecurityRequirement(
+ name = ArchivaRoleConstants.OPERATION_MANAGE_CONFIGURATION
+ )
+ },
+ responses = {
+ @ApiResponse( responseCode = "200",
+ description = "If the deletion was successful"
+ ),
+ @ApiResponse( responseCode = "403", description = "Authenticated user is not permitted to delete in repositories",
+ content = @Content( mediaType = APPLICATION_JSON, schema = @Schema( implementation = ArchivaRestError.class ) ) ),
+ @ApiResponse( responseCode = "404", description = "The managed repository with this id does not exist. Or the version does not exist.",
+ content = @Content( mediaType = APPLICATION_JSON, schema = @Schema( implementation = ArchivaRestError.class ) ) )
+ }
+ )
+ Response removeProjectVersion( @PathParam ( "id" ) String repositoryId,
+ @PathParam ( "group" ) String namespace, @PathParam ( "project" ) String projectId,
+ @PathParam ( "version" ) String version )
+ throws org.apache.archiva.rest.api.services.ArchivaRestServiceException;
+
+
+ @Path ( "{id}/co/{group}/{project}" )
+ @DELETE
+ @Produces ({ MediaType.APPLICATION_JSON })
+ @RedbackAuthorization (noPermission = true)
+ @Operation( summary = "Removes a project tree in the repository",
+ security = {
+ @SecurityRequirement(
+ name = ArchivaRoleConstants.OPERATION_MANAGE_CONFIGURATION
+ )
+ },
+ responses = {
+ @ApiResponse( responseCode = "200",
+ description = "If the deletion was successful"
+ ),
+ @ApiResponse( responseCode = "403", description = "Authenticated user is not permitted to delete in repositories",
+ content = @Content( mediaType = APPLICATION_JSON, schema = @Schema( implementation = ArchivaRestError.class ) ) ),
+ @ApiResponse( responseCode = "404", description = "The managed repository with this id does not exist. Or the project does not exist.",
+ content = @Content( mediaType = APPLICATION_JSON, schema = @Schema( implementation = ArchivaRestError.class ) ) )
+ }
+ )
+ Response deleteProject( @PathParam ("id") String repositoryId, @PathParam ( "group" ) String namespace, @PathParam ( "project" ) String projectId )
+ throws org.apache.archiva.rest.api.services.ArchivaRestServiceException;
+
+ @Path ( "{id}/co/{namespace}" )
+ @DELETE
+ @Produces ({ MediaType.APPLICATION_JSON })
+ @RedbackAuthorization (noPermission = true)
+ @Operation( summary = "Removes a namespace tree in the repository",
+ security = {
+ @SecurityRequirement(
+ name = ArchivaRoleConstants.OPERATION_MANAGE_CONFIGURATION
+ )
+ },
+ responses = {
+ @ApiResponse( responseCode = "200",
+ description = "If the deletion was successful"
+ ),
+ @ApiResponse( responseCode = "403", description = "Authenticated user is not permitted to delete namespaces in repositories",
+ content = @Content( mediaType = APPLICATION_JSON, schema = @Schema( implementation = ArchivaRestError.class ) ) ),
+ @ApiResponse( responseCode = "404", description = "The managed repository with this id does not exist. Or the namespace does not exist.",
+ content = @Content( mediaType = APPLICATION_JSON, schema = @Schema( implementation = ArchivaRestError.class ) ) )
+ }
+ )
+ Response deleteNamespace( @PathParam ("id") String repositoryId, @PathParam ( "namespace" ) String namespace )
+ throws org.apache.archiva.rest.api.services.ArchivaRestServiceException;
+
+}
import org.apache.archiva.redback.users.User;
import org.apache.archiva.redback.users.UserManagerException;
import org.apache.archiva.redback.users.UserNotFoundException;
+import org.apache.archiva.repository.base.RepositoryGroupHandler;
import org.apache.archiva.repository.content.BaseRepositoryContentLayout;
import org.apache.archiva.repository.content.ContentNotFoundException;
import org.apache.archiva.repository.content.LayoutException;
@Inject
private RepositoryRegistry repositoryRegistry;
+ @SuppressWarnings( "unused" )
+ @Inject
+ private RepositoryGroupHandler repositoryGroupHandler;
+
@Inject
private SecuritySystem securitySystem;
--- /dev/null
+package org.apache.archiva.rest.services.utils;
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import org.apache.archiva.admin.model.AuditInformation;
+import org.apache.archiva.redback.rest.services.RedbackAuthenticationThreadLocal;
+import org.apache.archiva.redback.rest.services.RedbackRequestInformation;
+import org.apache.archiva.redback.users.User;
+
+/**
+ * @author Martin Stockhammer <martin_s@apache.org>
+ */
+public class AuditHelper
+{
+ private static final AuditInformation NULL_RESULT = new AuditInformation( null, null );
+ public static AuditInformation getAuditData() {
+ RedbackRequestInformation redbackRequestInformation = RedbackAuthenticationThreadLocal.get( );
+ if (redbackRequestInformation==null) {
+ return NULL_RESULT;
+ } else
+ {
+ return new AuditInformation( redbackRequestInformation.getUser( ), redbackRequestInformation.getRemoteAddr( ) );
+ }
+ }
+}
import org.apache.archiva.repository.ManagedRepository;
import org.apache.archiva.repository.ReleaseScheme;
import org.apache.archiva.repository.Repository;
-import org.apache.archiva.repository.RepositoryException;
import org.apache.archiva.repository.RepositoryRegistry;
import org.apache.archiva.repository.RepositoryType;
import org.apache.archiva.repository.content.ContentItem;
import org.apache.archiva.repository.content.LayoutException;
-import org.apache.archiva.repository.storage.fs.FilesystemStorage;
import org.apache.archiva.repository.storage.fs.FsStorageUtil;
-import org.apache.archiva.repository.storage.util.StorageUtil;
-import org.apache.archiva.rest.api.model.v2.Artifact;
import org.apache.archiva.rest.api.model.v2.FileInfo;
import org.apache.archiva.rest.api.model.v2.MavenManagedRepository;
import org.apache.archiva.rest.api.model.v2.MavenManagedRepositoryUpdate;
import org.apache.archiva.rest.api.services.v2.ArchivaRestServiceException;
import org.apache.archiva.rest.api.services.v2.ErrorKeys;
import org.apache.archiva.rest.api.services.v2.ErrorMessage;
-import org.apache.archiva.rest.api.services.v2.MavenManagedRepositoryService;
+import org.apache.archiva.rest.api.services.v2.maven.MavenManagedRepositoryService;
import org.apache.archiva.security.common.ArchivaRoleConstants;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
-import javax.inject.Inject;
import javax.servlet.http.HttpServletResponse;
-import javax.ws.rs.PathParam;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.UriInfo;
-import java.io.File;
import java.io.IOException;
import java.util.Collection;
import java.util.Comparator;
private RepositoryRegistry repositoryRegistry;
private SecuritySystem securitySystem;
- public DefaultMavenManagedRepositoryService( SecuritySystem securitySystem, RepositoryRegistry repositoryRegistry, ManagedRepositoryAdmin managedRepositoryAdmin )
+ public DefaultMavenManagedRepositoryService( SecuritySystem securitySystem,
+ RepositoryRegistry repositoryRegistry,
+ ManagedRepositoryAdmin managedRepositoryAdmin )
{
this.securitySystem = securitySystem;
this.repositoryRegistry = repositoryRegistry;
protected AuditInformation getAuditInformation( )
{
RedbackRequestInformation redbackRequestInformation = RedbackAuthenticationThreadLocal.get( );
- User user = redbackRequestInformation == null ? null : redbackRequestInformation.getUser( );
- String remoteAddr = redbackRequestInformation == null ? null : redbackRequestInformation.getRemoteAddr( );
+ User user;
+ String remoteAddr;
+ if (redbackRequestInformation==null) {
+ user = null;
+ remoteAddr = null;
+ } else
+ {
+ user = redbackRequestInformation.getUser( );
+ remoteAddr = redbackRequestInformation.getRemoteAddr( );
+ }
return new AuditInformation( user, remoteAddr );
}
* under the License.
*/
-import org.apache.archiva.admin.model.AuditInformation;
import org.apache.archiva.admin.model.EntityExistsException;
import org.apache.archiva.admin.model.EntityNotFoundException;
import org.apache.archiva.admin.model.RepositoryAdminException;
import org.apache.archiva.admin.model.group.RepositoryGroupAdmin;
import org.apache.archiva.components.rest.model.PagedResult;
import org.apache.archiva.components.rest.util.QueryHelper;
-import org.apache.archiva.redback.rest.services.RedbackAuthenticationThreadLocal;
-import org.apache.archiva.redback.rest.services.RedbackRequestInformation;
-import org.apache.archiva.redback.users.User;
import org.apache.archiva.rest.api.model.v2.RepositoryGroup;
import org.apache.archiva.rest.api.services.v2.ArchivaRestServiceException;
import org.apache.archiva.rest.api.services.v2.ErrorKeys;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
-import javax.inject.Inject;
import javax.servlet.http.HttpServletResponse;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.Response;
import java.util.function.Predicate;
import java.util.stream.Collectors;
+import static org.apache.archiva.rest.services.utils.AuditHelper.getAuditData;
+
/**
* REST V2 Implementation for repository groups.
*
@Context
UriInfo uriInfo;
- @Inject
- private RepositoryGroupAdmin repositoryGroupAdmin;
+ final private RepositoryGroupAdmin repositoryGroupAdmin;
private static final Logger log = LoggerFactory.getLogger( DefaultRepositoryGroupService.class );
private static final QueryHelper<org.apache.archiva.admin.model.beans.RepositoryGroup> QUERY_HELPER = new QueryHelper<>( new String[]{"id"} );
}
- protected AuditInformation getAuditInformation( )
- {
- RedbackRequestInformation redbackRequestInformation = RedbackAuthenticationThreadLocal.get( );
- User user = redbackRequestInformation == null ? null : redbackRequestInformation.getUser( );
- String remoteAddr = redbackRequestInformation == null ? null : redbackRequestInformation.getRemoteAddr( );
- return new AuditInformation( user, remoteAddr );
+ public DefaultRepositoryGroupService(RepositoryGroupAdmin repositoryGroupAdmin) {
+ this.repositoryGroupAdmin = repositoryGroupAdmin;
}
@Override
{
try
{
- Boolean result = repositoryGroupAdmin.addRepositoryGroup( toModel( repositoryGroup ), getAuditInformation( ) );
+ Boolean result = repositoryGroupAdmin.addRepositoryGroup( toModel( repositoryGroup ), getAuditData() );
if ( result )
{
org.apache.archiva.admin.model.beans.RepositoryGroup newGroup = repositoryGroupAdmin.getRepositoryGroup( repositoryGroup.getId( ) );
{
updateGroup.setMergedIndexTtl( originGroup.getMergedIndexTtl( ) );
}
- repositoryGroupAdmin.updateRepositoryGroup( updateGroup, getAuditInformation( ) );
+ repositoryGroupAdmin.updateRepositoryGroup( updateGroup, getAuditData( ) );
return RepositoryGroup.of( repositoryGroupAdmin.getRepositoryGroup( repositoryGroupId ) );
}
catch ( EntityNotFoundException e )
}
try
{
- Boolean deleted = repositoryGroupAdmin.deleteRepositoryGroup( repositoryGroupId, getAuditInformation( ) );
+ Boolean deleted = repositoryGroupAdmin.deleteRepositoryGroup( repositoryGroupId, getAuditData( ) );
if ( !deleted )
{
throw new ArchivaRestServiceException( ErrorMessage.of( ErrorKeys.REPOSITORY_GROUP_DELETE_FAILED ) );
}
try
{
- repositoryGroupAdmin.addRepositoryToGroup( repositoryGroupId, repositoryId, getAuditInformation( ) );
+ repositoryGroupAdmin.addRepositoryToGroup( repositoryGroupId, repositoryId, getAuditData( ) );
return RepositoryGroup.of( repositoryGroupAdmin.getRepositoryGroup( repositoryGroupId ) );
}
catch ( EntityNotFoundException e )
}
try
{
- repositoryGroupAdmin.deleteRepositoryFromGroup( repositoryGroupId, repositoryId, getAuditInformation( ) );
+ repositoryGroupAdmin.deleteRepositoryFromGroup( repositoryGroupId, repositoryId, getAuditData( ) );
return RepositoryGroup.of( repositoryGroupAdmin.getRepositoryGroup( repositoryGroupId ) );
}
catch ( EntityNotFoundException e )
http://cxf.apache.org/jaxrs
http://cxf.apache.org/schemas/jaxrs.xsd" default-lazy-init="true">
- <import resource="classpath:META-INF/cxf/cxf.xml"/>
- <!--
- <import resource="classpath:META-INF/cxf/cxf-extension-jaxrs-binding.xml"/>
- -->
- <import resource="classpath:META-INF/cxf/cxf-servlet.xml"/>
+ <import resource="classpath*:META-INF/cxf/cxf.xml"/>
+ <import resource="classpath*:META-INF/cxf/cxf-servlet.xml"/>
<context:annotation-config/>
<context:component-scan
<ref bean="v2.defaultSecurityConfigurationService" />
<ref bean="v2.repositoryGroupService#rest" />
<ref bean="v2.repositoryService#rest"/>
+ <ref bean="v2.managedMavenRepositoryService#rest"/>
</jaxrs:serviceBeans>
<jaxrs:features>
}
else
{
- log.error( "Serer is not in STARTED state!" );
+ log.error( "Server is not in STARTED state!" );
}
}
this.requestSpec = getRequestSpecBuilder( ).build( );
RestAssured.basePath = basePath;
RestAssured.config = RestAssuredConfig.config().objectMapperConfig(new ObjectMapperConfig().jackson2ObjectMapperFactory(
- new Jackson2ObjectMapperFactory() {
- @Override
- public ObjectMapper create( Type cls, String charset) {
- ObjectMapper om = new ObjectMapper().findAndRegisterModules();
- om.configure( DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
- om.setPropertyNamingStrategy( PropertyNamingStrategy.SNAKE_CASE );
- return om;
- }
-
+ ( cls, charset ) -> {
+ ObjectMapper om = new ObjectMapper().findAndRegisterModules();
+ om.configure( DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
+ om.setPropertyNamingStrategy( PropertyNamingStrategy.SNAKE_CASE );
+ return om;
}
));
}
--- /dev/null
+package org.apache.archiva.rest.services.v2;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import io.restassured.path.json.JsonPath;
+import io.restassured.response.Response;
+import io.restassured.response.ResponseBody;
+import org.apache.archiva.components.rest.model.PagedResult;
+import org.apache.archiva.components.rest.model.PropertyEntry;
+import org.apache.archiva.rest.api.model.v2.BeanInformation;
+import org.apache.archiva.rest.api.model.v2.CacheConfiguration;
+import org.apache.archiva.rest.api.model.v2.LdapConfiguration;
+import org.apache.archiva.rest.api.model.v2.MavenManagedRepository;
+import org.apache.archiva.rest.api.services.v2.RestConfiguration;
+import org.junit.jupiter.api.AfterAll;
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.DisplayName;
+import org.junit.jupiter.api.MethodOrderer;
+import org.junit.jupiter.api.Order;
+import org.junit.jupiter.api.Tag;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.TestInstance;
+import org.junit.jupiter.api.TestMethodOrder;
+
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import static io.restassured.RestAssured.given;
+import static io.restassured.http.ContentType.JSON;
+import static org.junit.jupiter.api.Assertions.*;
+
+/**
+ * @author Martin Stockhammer <martin_s@apache.org>
+ */
+@TestInstance( TestInstance.Lifecycle.PER_CLASS )
+@Tag( "rest-native" )
+@TestMethodOrder( MethodOrderer.OrderAnnotation.class )
+@DisplayName( "Native REST tests for V2 ManagedRepositoryService" )
+public class NativeMavenManagedRepositoryServiceTest extends AbstractNativeRestServices
+{
+ @Override
+ protected String getServicePath( )
+ {
+ return "/repositories/maven/managed";
+ }
+
+ @BeforeAll
+ void setup( ) throws Exception
+ {
+ super.setupNative( );
+ }
+
+ @AfterAll
+ void destroy( ) throws Exception
+ {
+ super.shutdownNative( );
+ }
+
+ @Test
+ @Order( 1 )
+ void testGetRepositories( )
+ {
+ String token = getAdminToken( );
+ Response response = given( ).spec( getRequestSpec( token ) ).contentType( JSON )
+ .when( )
+ .get( "" )
+ .then( ).statusCode( 200 ).extract( ).response( );
+ JsonPath json = response.getBody( ).jsonPath( );
+ assertEquals( 2, json.getInt( "pagination.total_count" ) );
+ assertEquals( 0, json.getInt( "pagination.offset" ) );
+ assertEquals( Integer.valueOf( RestConfiguration.DEFAULT_PAGE_LIMIT ), json.getInt( "pagination.limit" ) );
+ List<MavenManagedRepository> repositories = json.getList( "data", MavenManagedRepository.class );
+ assertEquals( "internal", repositories.get( 0 ).getId( ) );
+ assertEquals( "snapshots", repositories.get( 1 ).getId( ) );
+ }
+
+
+
+}
<context:annotation-config/>
<context:component-scan
- base-package="org.apache.archiva.redback.keys,org.apache.archiva.rest.services.utils,org.apache.archiva.repository.content.maven2"/>
+ base-package="org.apache.archiva.redback.keys,org.apache.archiva.rest.services.utils,org.apache.archiva.repository.maven.content"/>
<bean name="scheduler" class="org.apache.archiva.components.scheduler.DefaultScheduler">
<property name="properties">
import org.apache.archiva.repository.base.ArchivaRepositoryRegistry;
import org.apache.archiva.repository.ManagedRepository;
import org.apache.archiva.repository.RepositoryType;
+import org.apache.archiva.repository.base.RepositoryGroupHandler;
import org.apache.archiva.test.utils.ArchivaSpringJUnit4ClassRunner;
import org.apache.archiva.webdav.httpunit.MkColMethodWebRequest;
import org.apache.commons.io.FileUtils;
@Inject
protected ApplicationContext applicationContext;
+ @SuppressWarnings( "unused" )
+ @Inject
+ RepositoryGroupHandler repositoryGroupHandler;
@Inject
ArchivaRepositoryRegistry repositoryRegistry;
import org.apache.archiva.configuration.RepositoryGroupConfiguration;
import org.apache.archiva.metadata.repository.storage.RepositoryPathTranslator;
import org.apache.archiva.repository.ManagedRepositoryContent;
+import org.apache.archiva.repository.base.RepositoryGroupHandler;
import org.apache.archiva.repository.maven.content.MavenContentHelper;
import org.apache.archiva.repository.maven.metadata.storage.ArtifactMappingProvider;
import org.apache.archiva.proxy.ProxyRegistry;
@Inject
FileTypes fileTypes;
+ @SuppressWarnings( "unused" )
+ @Inject
+ RepositoryGroupHandler repositoryGroupHandler;
+
public Path getProjectBase() {
if (this.projectBase.get()==null) {
String pathVal = System.getProperty("mvn.project.base.dir");
expect (archivaConfiguration.getDefaultLocale()).andReturn( Locale.getDefault() ).anyTimes();
archivaConfiguration.addListener( EasyMock.anyObject( ) );
expectLastCall().times(0, 4);
- archivaConfiguration.save( config );
-
+ archivaConfiguration.save( eq(config));
+ expectLastCall().times( 0, 5 );
+ archivaConfiguration.save( eq(config), EasyMock.anyString());
expectLastCall().times( 0, 5 );
archivaConfigurationControl.replay();
import org.apache.archiva.redback.users.memory.SimpleUser;
import org.apache.archiva.repository.RepositoryRegistry;
import org.apache.archiva.metadata.audit.TestAuditListener;
+import org.apache.archiva.repository.base.RepositoryGroupHandler;
import org.apache.archiva.security.ServletAuthenticator;
import org.apache.archiva.security.common.ArchivaRoleConstants;
import org.apache.archiva.test.utils.ArchivaSpringJUnit4ClassRunner;
@Inject
protected RepositoryRegistry repositoryRegistry;
+ @SuppressWarnings( "unused" )
+ @Inject
+ RepositoryGroupHandler repositoryGroupHandler;
+
private DavSessionProvider davSessionProvider;
private IMocksControl servletAuthControl;