mirror of https://github.com/apache/archiva.git
Centralizing repository group handling. First part.
This commit is contained in:
parent
ca18ec34d7
commit
0ce53483a8
|
@ -55,6 +55,20 @@ public interface ArchivaConfiguration
|
|||
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.
|
||||
*
|
||||
|
|
|
@ -32,9 +32,17 @@ public class ConfigurationEvent
|
|||
|
||||
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()
|
||||
|
@ -42,35 +50,33 @@ public class ConfigurationEvent
|
|||
return type;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode()
|
||||
public String getTag( )
|
||||
{
|
||||
final int prime = 31;
|
||||
int result = 1;
|
||||
result = prime * result + type;
|
||||
return result;
|
||||
return tag;
|
||||
}
|
||||
|
||||
public void setTag( String tag )
|
||||
{
|
||||
this.tag = tag;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals( Object obj )
|
||||
public boolean equals( Object o )
|
||||
{
|
||||
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;
|
||||
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 int hashCode( )
|
||||
{
|
||||
int result = type;
|
||||
result = 31 * result + tag.hashCode( );
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -410,7 +410,20 @@ public class DefaultArchivaConfiguration
|
|||
|
||||
@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");
|
||||
|
@ -491,7 +504,7 @@ public class DefaultArchivaConfiguration
|
|||
this.configuration = unescapeExpressions(configuration);
|
||||
isConfigurationDefaulted = false;
|
||||
|
||||
triggerEvent(ConfigurationEvent.SAVED);
|
||||
triggerEvent(ConfigurationEvent.SAVED, eventTag);
|
||||
}
|
||||
|
||||
private void escapeCronExpressions(Configuration configuration) {
|
||||
|
@ -530,7 +543,7 @@ public class DefaultArchivaConfiguration
|
|||
addRegistryChangeListener(regListener);
|
||||
}
|
||||
|
||||
triggerEvent(ConfigurationEvent.SAVED);
|
||||
triggerEvent(ConfigurationEvent.SAVED, "default-file");
|
||||
|
||||
Registry section = registry.getSection(KEY + ".user");
|
||||
if (section == null) {
|
||||
|
@ -580,8 +593,8 @@ public class DefaultArchivaConfiguration
|
|||
}
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
|
|
@ -26,6 +26,7 @@ import org.apache.archiva.metadata.repository.RepositorySessionFactory;
|
|||
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;
|
||||
|
@ -113,6 +114,10 @@ public abstract class AbstractRepositoryPurgeTest
|
|||
@Inject
|
||||
protected ApplicationContext applicationContext;
|
||||
|
||||
@SuppressWarnings( "unused" )
|
||||
@Inject
|
||||
RepositoryGroupHandler repositoryGroupHandler;
|
||||
|
||||
|
||||
@Before
|
||||
public void setUp()
|
||||
|
|
|
@ -74,6 +74,8 @@ public class CleanupReleasedSnapshotsRepositoryPurgeTest
|
|||
@Inject
|
||||
MetadataTools metadataTools;
|
||||
|
||||
|
||||
|
||||
@Before
|
||||
@Override
|
||||
public void setUp()
|
||||
|
|
|
@ -27,6 +27,7 @@ import org.apache.archiva.components.taskqueue.TaskQueueException;
|
|||
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;
|
||||
|
@ -96,6 +97,9 @@ public class NexusIndexerConsumerTest
|
|||
@Inject
|
||||
ArchivaRepositoryRegistry repositoryRegistry;
|
||||
|
||||
@SuppressWarnings( "unused" )
|
||||
@Inject
|
||||
RepositoryGroupHandler repositoryGroupHandler;
|
||||
|
||||
@Override
|
||||
@Before
|
||||
|
|
|
@ -29,11 +29,15 @@ import org.apache.archiva.admin.model.managed.ManagedRepositoryAdmin;
|
|||
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;
|
||||
|
@ -62,7 +66,7 @@ import java.util.stream.Collectors;
|
|||
@Service("repositoryGroupAdmin#default")
|
||||
public class DefaultRepositoryGroupAdmin
|
||||
extends AbstractRepositoryAdmin
|
||||
implements RepositoryGroupAdmin
|
||||
implements RepositoryGroupAdmin, EventHandler<Event>
|
||||
{
|
||||
|
||||
private Logger log = LoggerFactory.getLogger( getClass() );
|
||||
|
@ -82,6 +86,10 @@ public class DefaultRepositoryGroupAdmin
|
|||
private Path groupsDirectory;
|
||||
|
||||
@PostConstruct
|
||||
public void baseInit() {
|
||||
this.repositoryRegistry.registerEventHandler( EventType.ROOT, this );
|
||||
}
|
||||
|
||||
public void initialize()
|
||||
{
|
||||
String appServerBase = getRegistry().getString( "appserver.base" );
|
||||
|
@ -438,4 +446,14 @@ public class DefaultRepositoryGroupAdmin
|
|||
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();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -31,6 +31,7 @@ import org.apache.archiva.configuration.ArchivaConfiguration;
|
|||
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;
|
||||
|
@ -84,6 +85,10 @@ public abstract class AbstractRepositoryAdminTest
|
|||
@Inject
|
||||
private ArchivaConfiguration archivaConfiguration;
|
||||
|
||||
@SuppressWarnings( "unused" )
|
||||
@Inject
|
||||
RepositoryGroupHandler repositoryGroupHandler;
|
||||
|
||||
@Before
|
||||
public void initialize() {
|
||||
Path confFile = Paths.get(APPSERVER_BASE_PATH, "conf/archiva.xml");
|
||||
|
|
|
@ -26,6 +26,7 @@ import org.apache.archiva.admin.repository.AbstractRepositoryAdminTest;
|
|||
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;
|
||||
|
@ -44,6 +45,9 @@ public class RepositoryGroupAdminTest
|
|||
@Inject
|
||||
RepositoryRegistry repositoryRegistry;
|
||||
|
||||
@Inject
|
||||
RepositoryGroupHandler repositoryGroupHandler;
|
||||
|
||||
@Test
|
||||
public void addAndDeleteGroup()
|
||||
throws Exception
|
||||
|
|
|
@ -47,6 +47,21 @@ public class RepositoryRegistryEvent extends Event
|
|||
*/
|
||||
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);
|
||||
}
|
||||
|
|
|
@ -28,7 +28,6 @@ import org.apache.archiva.components.registry.RegistryException;
|
|||
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;
|
||||
|
@ -55,12 +54,11 @@ import javax.annotation.PreDestroy;
|
|||
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.
|
||||
|
@ -78,6 +76,7 @@ public class ArchivaRepositoryRegistry implements ConfigurationListener, EventHa
|
|||
{
|
||||
|
||||
private static final Logger log = LoggerFactory.getLogger(RepositoryRegistry.class);
|
||||
private final ConfigurationHandler configurationHandler;
|
||||
|
||||
/**
|
||||
* We inject all repository providers
|
||||
|
@ -88,9 +87,6 @@ public class ArchivaRepositoryRegistry implements ConfigurationListener, EventHa
|
|||
@Inject
|
||||
IndexManagerFactory indexManagerFactory;
|
||||
|
||||
@Inject
|
||||
ArchivaConfiguration archivaConfiguration;
|
||||
|
||||
@Inject
|
||||
List<MetadataReader> metadataReaderList;
|
||||
|
||||
|
@ -98,6 +94,8 @@ public class ArchivaRepositoryRegistry implements ConfigurationListener, EventHa
|
|||
@Named("repositoryContentFactory#default")
|
||||
RepositoryContentFactory repositoryContentFactory;
|
||||
|
||||
|
||||
|
||||
private final EventManager eventManager;
|
||||
|
||||
|
||||
|
@ -107,20 +105,23 @@ public class ArchivaRepositoryRegistry implements ConfigurationListener, EventHa
|
|||
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
|
||||
|
@ -128,21 +129,41 @@ public class ArchivaRepositoryRegistry implements ConfigurationListener, EventHa
|
|||
rwLock.writeLock().lock();
|
||||
try {
|
||||
log.debug("Initializing repository registry");
|
||||
updateManagedRepositoriesFromConfig();
|
||||
updateRemoteRepositoriesFromConfig();
|
||||
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 );
|
||||
|
||||
repositoryGroups.clear();
|
||||
Map<String, RepositoryGroup> repositoryGroups = getRepositorGroupsFromConfig();
|
||||
this.repositoryGroups.putAll(repositoryGroups);
|
||||
|
||||
// archivaConfiguration.addChangeListener(this);
|
||||
archivaConfiguration.addListener(this);
|
||||
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()) {
|
||||
|
@ -153,11 +174,12 @@ public class ArchivaRepositoryRegistry implements ConfigurationListener, EventHa
|
|||
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) {
|
||||
|
@ -169,7 +191,7 @@ public class ArchivaRepositoryRegistry implements ConfigurationListener, EventHa
|
|||
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));
|
||||
}
|
||||
|
@ -182,7 +204,7 @@ public class ArchivaRepositoryRegistry implements ConfigurationListener, EventHa
|
|||
|
||||
Set<String> configRepoIds = new HashSet<>();
|
||||
List<ManagedRepositoryConfiguration> managedRepoConfigs =
|
||||
getArchivaConfiguration().getConfiguration().getManagedRepositories();
|
||||
configurationHandler.getBaseConfiguration().getManagedRepositories();
|
||||
|
||||
if (managedRepoConfigs == null) {
|
||||
return;
|
||||
|
@ -299,7 +321,7 @@ public class ArchivaRepositoryRegistry implements ConfigurationListener, EventHa
|
|||
private void updateRemoteRepositoriesFromConfig() {
|
||||
try {
|
||||
List<RemoteRepositoryConfiguration> remoteRepoConfigs =
|
||||
getArchivaConfiguration().getConfiguration().getRemoteRepositories();
|
||||
configurationHandler.getBaseConfiguration().getRemoteRepositories();
|
||||
|
||||
if (remoteRepoConfigs == null) {
|
||||
return;
|
||||
|
@ -341,53 +363,8 @@ public class ArchivaRepositoryRegistry implements ConfigurationListener, EventHa
|
|||
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.
|
||||
|
@ -438,7 +415,7 @@ public class ArchivaRepositoryRegistry implements ConfigurationListener, EventHa
|
|||
public Collection<RepositoryGroup> getRepositoryGroups( ) {
|
||||
rwLock.readLock().lock();
|
||||
try {
|
||||
return uRepositoryGroups.values();
|
||||
return groupHandler.getRepositoryGroups( );
|
||||
} finally {
|
||||
rwLock.readLock().unlock();
|
||||
}
|
||||
|
@ -462,8 +439,8 @@ public class ArchivaRepositoryRegistry implements ConfigurationListener, EventHa
|
|||
} 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;
|
||||
}
|
||||
|
@ -510,23 +487,14 @@ public class ArchivaRepositoryRegistry implements ConfigurationListener, EventHa
|
|||
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 );
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -552,7 +520,7 @@ public class ArchivaRepositoryRegistry implements ConfigurationListener, EventHa
|
|||
}
|
||||
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) {
|
||||
|
@ -595,7 +563,7 @@ public class ArchivaRepositoryRegistry implements ConfigurationListener, EventHa
|
|||
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);
|
||||
|
@ -670,33 +638,10 @@ public class ArchivaRepositoryRegistry implements ConfigurationListener, EventHa
|
|||
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();
|
||||
}
|
||||
|
@ -714,22 +659,7 @@ public class ArchivaRepositoryRegistry implements ConfigurationListener, EventHa
|
|||
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();
|
||||
}
|
||||
|
@ -749,41 +679,12 @@ public class ArchivaRepositoryRegistry implements ConfigurationListener, EventHa
|
|||
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());
|
||||
|
@ -874,7 +775,7 @@ public class ArchivaRepositoryRegistry implements ConfigurationListener, EventHa
|
|||
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);
|
||||
|
@ -902,7 +803,7 @@ public class ArchivaRepositoryRegistry implements ConfigurationListener, EventHa
|
|||
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);
|
||||
|
@ -1012,8 +913,8 @@ public class ArchivaRepositoryRegistry implements ConfigurationListener, EventHa
|
|||
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);
|
||||
|
@ -1032,12 +933,6 @@ public class ArchivaRepositoryRegistry implements ConfigurationListener, EventHa
|
|||
}
|
||||
}
|
||||
|
||||
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 {
|
||||
|
@ -1052,7 +947,7 @@ public class ArchivaRepositoryRegistry implements ConfigurationListener, EventHa
|
|||
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);
|
||||
|
@ -1080,26 +975,10 @@ public class ArchivaRepositoryRegistry implements ConfigurationListener, EventHa
|
|||
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();
|
||||
}
|
||||
|
@ -1112,23 +991,14 @@ public class ArchivaRepositoryRegistry implements ConfigurationListener, EventHa
|
|||
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) {
|
||||
|
@ -1164,7 +1034,7 @@ public class ArchivaRepositoryRegistry implements ConfigurationListener, EventHa
|
|||
try {
|
||||
repo = remoteRepositories.remove(id);
|
||||
if (repo != null) {
|
||||
Configuration configuration = getArchivaConfiguration().getConfiguration();
|
||||
Configuration configuration = configurationHandler.getBaseConfiguration();
|
||||
doRemoveRepo(repo, configuration);
|
||||
saveConfiguration(configuration);
|
||||
}
|
||||
|
@ -1292,8 +1162,9 @@ public class ArchivaRepositoryRegistry implements ConfigurationListener, EventHa
|
|||
|
||||
@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();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,71 @@
|
|||
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, "" );
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,328 @@
|
|||
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();
|
||||
}
|
||||
|
||||
}
|
|
@ -66,6 +66,10 @@ public class ArchivaRepositoryRegistryTest
|
|||
@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;
|
||||
|
|
|
@ -24,6 +24,7 @@ import org.apache.archiva.indexer.ArchivaIndexingContext;
|
|||
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;
|
||||
|
@ -61,6 +62,9 @@ public class MavenIndexManagerTest {
|
|||
@Inject
|
||||
ArchivaRepositoryRegistry repositoryRegistry;
|
||||
|
||||
@Inject
|
||||
RepositoryGroupHandler groupHandler;
|
||||
|
||||
|
||||
private Path indexPath;
|
||||
private MavenManagedRepository repository;
|
||||
|
|
|
@ -31,6 +31,8 @@ import org.apache.archiva.indexer.search.SearchResults;
|
|||
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;
|
||||
|
@ -92,6 +94,9 @@ public abstract class AbstractMavenRepositorySearch
|
|||
@Inject
|
||||
ArchivaRepositoryRegistry repositoryRegistry;
|
||||
|
||||
@Inject
|
||||
RepositoryGroupHandler repositoryGroupHandler;
|
||||
|
||||
@Inject
|
||||
ProxyRegistry proxyRegistry;
|
||||
|
||||
|
@ -143,7 +148,7 @@ public abstract class AbstractMavenRepositorySearch
|
|||
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();
|
||||
|
@ -158,7 +163,7 @@ public abstract class AbstractMavenRepositorySearch
|
|||
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);
|
||||
|
@ -259,7 +264,7 @@ public abstract class AbstractMavenRepositorySearch
|
|||
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();
|
||||
|
|
|
@ -23,6 +23,7 @@ import org.apache.archiva.indexer.search.SearchFields;
|
|||
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;
|
||||
|
@ -43,6 +44,9 @@ public class MavenRepositorySearchOSGITest
|
|||
@Inject
|
||||
ArchivaRepositoryRegistry repositoryRegistry;
|
||||
|
||||
@Inject
|
||||
RepositoryGroupHandler repositoryGroupHandler;
|
||||
|
||||
@After
|
||||
@Override
|
||||
public void tearDown() throws Exception {
|
||||
|
|
|
@ -24,6 +24,7 @@ import org.apache.archiva.indexer.search.SearchResultLimits;
|
|||
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;
|
||||
|
@ -31,6 +32,7 @@ import org.junit.runner.RunWith;
|
|||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.test.context.ContextConfiguration;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import java.util.Arrays;
|
||||
|
||||
/**
|
||||
|
@ -42,9 +44,12 @@ public class MavenRepositorySearchPaginateTest
|
|||
extends TestCase
|
||||
{
|
||||
|
||||
@Autowired
|
||||
@Inject
|
||||
ArchivaRepositoryRegistry repositoryRegistry;
|
||||
|
||||
@Inject
|
||||
RepositoryGroupHandler repositoryGroupHandler;
|
||||
|
||||
@After
|
||||
public void endTests() {
|
||||
assert repositoryRegistry!=null;
|
||||
|
|
|
@ -111,6 +111,12 @@ public class MockConfiguration
|
|||
/* 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 )
|
||||
|
|
|
@ -27,6 +27,7 @@ import org.apache.archiva.configuration.ArchivaRuntimeConfiguration;
|
|||
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;
|
||||
|
@ -109,6 +110,12 @@ public class MockConfiguration
|
|||
/* 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)
|
||||
|
|
|
@ -22,6 +22,7 @@ import org.apache.archiva.repository.ManagedRepository;
|
|||
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;
|
||||
|
@ -31,6 +32,11 @@ public class RepositoryRegistryMock extends ArchivaRepositoryRegistry
|
|||
|
||||
private Map<String, ManagedRepository> managedRepositories = new TreeMap<>();
|
||||
|
||||
public RepositoryRegistryMock( ConfigurationHandler configurationHandler )
|
||||
{
|
||||
super( configurationHandler );
|
||||
}
|
||||
|
||||
@Override
|
||||
public ManagedRepository putRepository(ManagedRepository managedRepository) throws RepositoryException
|
||||
{
|
||||
|
|
|
@ -56,6 +56,12 @@ public class StubConfiguration
|
|||
this.configuration = configuration;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void save( Configuration configuration, String eventTag ) throws RegistryException, IndeterminateConfigurationException
|
||||
{
|
||||
this.configuration = configuration;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isDefaulted()
|
||||
{
|
||||
|
|
|
@ -51,6 +51,12 @@ public class TestConfiguration
|
|||
this.configuration = configuration;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void save( Configuration configuration, String eventTag ) throws RegistryException, IndeterminateConfigurationException
|
||||
{
|
||||
this.configuration = configuration;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isDefaulted()
|
||||
{
|
||||
|
|
|
@ -26,6 +26,7 @@ import org.apache.archiva.repository.base.ArchivaRepositoryRegistry;
|
|||
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;
|
||||
|
@ -73,6 +74,9 @@ public class ArchivaIndexingTaskExecutorTest
|
|||
@Inject
|
||||
ArchivaRepositoryRegistry repositoryRegistry;
|
||||
|
||||
@Inject
|
||||
RepositoryGroupHandler repositoryGroupHandler;
|
||||
|
||||
@Inject
|
||||
private IndexUpdater indexUpdater;
|
||||
|
||||
|
|
|
@ -29,6 +29,7 @@ import org.apache.archiva.mock.MockRepositorySessionFactory;
|
|||
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;
|
||||
|
@ -65,6 +66,9 @@ public abstract class AbstractArchivaRepositoryScanningTaskExecutorTest
|
|||
@Inject
|
||||
RepositoryRegistry repositoryRegistry;
|
||||
|
||||
@Inject
|
||||
RepositoryGroupHandler groupHandler;
|
||||
|
||||
@Inject
|
||||
@Named( value = "taskExecutor#test-repository-scanning" )
|
||||
protected TaskExecutor<RepositoryTask> taskExecutor;
|
||||
|
|
|
@ -55,20 +55,20 @@ import static org.apache.archiva.rest.api.services.v2.RestConfiguration.DEFAULT_
|
|||
* @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(
|
||||
|
@ -78,22 +78,22 @@ public interface RepositoryGroupService
|
|||
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 = {
|
||||
|
@ -104,12 +104,12 @@ public interface RepositoryGroupService
|
|||
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 )
|
||||
|
@ -117,14 +117,14 @@ public interface RepositoryGroupService
|
|||
|
||||
@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(
|
||||
|
@ -134,17 +134,17 @@ public interface RepositoryGroupService
|
|||
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 )
|
||||
|
@ -152,13 +152,13 @@ public interface RepositoryGroupService
|
|||
|
||||
@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 = {
|
||||
|
@ -169,14 +169,14 @@ public interface RepositoryGroupService
|
|||
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 )
|
||||
|
@ -184,7 +184,7 @@ public interface RepositoryGroupService
|
|||
|
||||
@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 = {
|
||||
|
@ -197,9 +197,9 @@ public interface RepositoryGroupService
|
|||
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 )
|
||||
|
@ -207,7 +207,7 @@ public interface RepositoryGroupService
|
|||
|
||||
@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 = {
|
||||
|
@ -220,18 +220,18 @@ public interface RepositoryGroupService
|
|||
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 = {
|
||||
|
@ -244,13 +244,13 @@ public interface RepositoryGroupService
|
|||
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;
|
||||
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
package org.apache.archiva.rest.api.services.v2;
|
||||
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
|
||||
|
@ -31,6 +31,8 @@ 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;
|
||||
|
@ -51,6 +53,8 @@ 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
|
||||
*/
|
|
@ -47,6 +47,7 @@ import org.apache.archiva.redback.system.SecuritySystem;
|
|||
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;
|
||||
|
@ -128,6 +129,10 @@ public class DefaultRepositoriesService
|
|||
@Inject
|
||||
private RepositoryRegistry repositoryRegistry;
|
||||
|
||||
@SuppressWarnings( "unused" )
|
||||
@Inject
|
||||
private RepositoryGroupHandler repositoryGroupHandler;
|
||||
|
||||
@Inject
|
||||
private SecuritySystem securitySystem;
|
||||
|
||||
|
|
|
@ -0,0 +1,40 @@
|
|||
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( ) );
|
||||
}
|
||||
}
|
||||
}
|
|
@ -35,35 +35,28 @@ import org.apache.archiva.redback.users.UserNotFoundException;
|
|||
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;
|
||||
|
@ -103,7 +96,9 @@ public class DefaultMavenManagedRepositoryService implements MavenManagedReposit
|
|||
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;
|
||||
|
@ -113,8 +108,16 @@ public class DefaultMavenManagedRepositoryService implements MavenManagedReposit
|
|||
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 );
|
||||
}
|
||||
|
||||
|
|
|
@ -34,16 +34,12 @@ package org.apache.archiva.rest.services.v2;/*
|
|||
* 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;
|
||||
|
@ -54,7 +50,6 @@ 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.core.Context;
|
||||
import javax.ws.rs.core.Response;
|
||||
|
@ -65,6 +60,8 @@ import java.util.List;
|
|||
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.
|
||||
*
|
||||
|
@ -81,8 +78,7 @@ public class DefaultRepositoryGroupService implements RepositoryGroupService
|
|||
@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"} );
|
||||
|
@ -93,12 +89,8 @@ public class DefaultRepositoryGroupService implements RepositoryGroupService
|
|||
}
|
||||
|
||||
|
||||
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
|
||||
|
@ -166,7 +158,7 @@ public class DefaultRepositoryGroupService implements RepositoryGroupService
|
|||
{
|
||||
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( ) );
|
||||
|
@ -243,7 +235,7 @@ public class DefaultRepositoryGroupService implements RepositoryGroupService
|
|||
{
|
||||
updateGroup.setMergedIndexTtl( originGroup.getMergedIndexTtl( ) );
|
||||
}
|
||||
repositoryGroupAdmin.updateRepositoryGroup( updateGroup, getAuditInformation( ) );
|
||||
repositoryGroupAdmin.updateRepositoryGroup( updateGroup, getAuditData( ) );
|
||||
return RepositoryGroup.of( repositoryGroupAdmin.getRepositoryGroup( repositoryGroupId ) );
|
||||
}
|
||||
catch ( EntityNotFoundException e )
|
||||
|
@ -265,7 +257,7 @@ public class DefaultRepositoryGroupService implements RepositoryGroupService
|
|||
}
|
||||
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 ) );
|
||||
|
@ -297,7 +289,7 @@ public class DefaultRepositoryGroupService implements RepositoryGroupService
|
|||
}
|
||||
try
|
||||
{
|
||||
repositoryGroupAdmin.addRepositoryToGroup( repositoryGroupId, repositoryId, getAuditInformation( ) );
|
||||
repositoryGroupAdmin.addRepositoryToGroup( repositoryGroupId, repositoryId, getAuditData( ) );
|
||||
return RepositoryGroup.of( repositoryGroupAdmin.getRepositoryGroup( repositoryGroupId ) );
|
||||
}
|
||||
catch ( EntityNotFoundException e )
|
||||
|
@ -335,7 +327,7 @@ public class DefaultRepositoryGroupService implements RepositoryGroupService
|
|||
}
|
||||
try
|
||||
{
|
||||
repositoryGroupAdmin.deleteRepositoryFromGroup( repositoryGroupId, repositoryId, getAuditInformation( ) );
|
||||
repositoryGroupAdmin.deleteRepositoryFromGroup( repositoryGroupId, repositoryId, getAuditData( ) );
|
||||
return RepositoryGroup.of( repositoryGroupAdmin.getRepositoryGroup( repositoryGroupId ) );
|
||||
}
|
||||
catch ( EntityNotFoundException e )
|
||||
|
|
|
@ -29,11 +29,8 @@
|
|||
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
|
||||
|
@ -119,6 +116,7 @@
|
|||
<ref bean="v2.defaultSecurityConfigurationService" />
|
||||
<ref bean="v2.repositoryGroupService#rest" />
|
||||
<ref bean="v2.repositoryService#rest"/>
|
||||
<ref bean="v2.managedMavenRepositoryService#rest"/>
|
||||
</jaxrs:serviceBeans>
|
||||
|
||||
<jaxrs:features>
|
||||
|
|
|
@ -378,7 +378,7 @@ public abstract class AbstractNativeRestServices
|
|||
}
|
||||
else
|
||||
{
|
||||
log.error( "Serer is not in STARTED state!" );
|
||||
log.error( "Server is not in STARTED state!" );
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -410,15 +410,11 @@ public abstract class AbstractNativeRestServices
|
|||
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;
|
||||
}
|
||||
));
|
||||
}
|
||||
|
|
|
@ -0,0 +1,97 @@
|
|||
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( ) );
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
|
@ -32,7 +32,7 @@
|
|||
|
||||
<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">
|
||||
|
|
|
@ -30,6 +30,7 @@ import org.apache.archiva.indexer.ArchivaIndexingContext;
|
|||
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;
|
||||
|
@ -99,6 +100,9 @@ public abstract class AbstractRepositoryServletTestCase
|
|||
@Inject
|
||||
protected ApplicationContext applicationContext;
|
||||
|
||||
@SuppressWarnings( "unused" )
|
||||
@Inject
|
||||
RepositoryGroupHandler repositoryGroupHandler;
|
||||
|
||||
@Inject
|
||||
ArchivaRepositoryRegistry repositoryRegistry;
|
||||
|
|
|
@ -34,6 +34,7 @@ import org.apache.archiva.configuration.FileTypes;
|
|||
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;
|
||||
|
@ -158,6 +159,10 @@ public class ArchivaDavResourceFactoryTest
|
|||
@Inject
|
||||
FileTypes fileTypes;
|
||||
|
||||
@SuppressWarnings( "unused" )
|
||||
@Inject
|
||||
RepositoryGroupHandler repositoryGroupHandler;
|
||||
|
||||
public Path getProjectBase() {
|
||||
if (this.projectBase.get()==null) {
|
||||
String pathVal = System.getProperty("mvn.project.base.dir");
|
||||
|
@ -194,8 +199,9 @@ public class ArchivaDavResourceFactoryTest
|
|||
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();
|
||||
|
||||
|
|
|
@ -35,6 +35,7 @@ import org.apache.archiva.redback.users.User;
|
|||
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;
|
||||
|
@ -91,6 +92,10 @@ public class RepositoryServletSecurityTest
|
|||
@Inject
|
||||
protected RepositoryRegistry repositoryRegistry;
|
||||
|
||||
@SuppressWarnings( "unused" )
|
||||
@Inject
|
||||
RepositoryGroupHandler repositoryGroupHandler;
|
||||
|
||||
private DavSessionProvider davSessionProvider;
|
||||
|
||||
private IMocksControl servletAuthControl;
|
||||
|
|
Loading…
Reference in New Issue