Adding absolute URI to repositories

This commit is contained in:
Martin Stockhammer 2017-10-22 18:22:03 +02:00
parent acbcb48747
commit 1026c8eeb8
7 changed files with 332 additions and 29 deletions

View File

@ -48,6 +48,7 @@ public abstract class AbstractRepository implements EditableRepository
private Locale primaryLocale = new Locale("en_US");
private URI location;
private URI baseUri;
private Set<URI> failoverLocations = new HashSet<>( );
private Set<URI> uFailoverLocations = Collections.unmodifiableSet( failoverLocations );
private boolean scanned = true;
@ -114,6 +115,10 @@ public abstract class AbstractRepository implements EditableRepository
return location;
}
public URI getAbsoluteLocation() {
return baseUri.resolve( location );
}
@Override
public Set<URI> getFailoverLocations( )
{
@ -210,6 +215,11 @@ public abstract class AbstractRepository implements EditableRepository
this.layout = layout;
}
@Override
public void setBaseUri(URI baseUri) {
this.baseUri = baseUri;
}
@Override
public void setSchedulingDefinition(String cronExpression) {
CronParser parser = new CronParser(CRON_DEFINITION);

View File

@ -67,6 +67,13 @@ public interface EditableRepository extends Repository
*/
void setLocation(URI location) throws UnsupportedURIException;
/**
* Sets the base uri for relative location uris.
*
* @param baseUri
*/
void setBaseUri(URI baseUri);
/**
* Adds a failover location for the repository.
*

View File

@ -85,6 +85,14 @@ public interface Repository {
*/
URI getLocation();
/**
* This returns the absolute location uri of this repository. Some repository locations may be relative to
* the base repository directory or uri. This returns the absolute path of the repository.
* If the location is absolute already this method returns the same URI as getLocation().
*
* @return the absolute uri of the location.
*/
URI getAbsoluteLocation();
/**
* A repository may allow additional locations that can be used, if the primary location is not available.

View File

@ -40,10 +40,14 @@ public interface RepositoryProvider
ManagedRepository createManagedInstance( ManagedRepositoryConfiguration configuration) throws RepositoryException;
void updateManagedInstance( EditableManagedRepository repo, ManagedRepositoryConfiguration configuration) throws RepositoryException;
ManagedRepository createStagingInstance(ManagedRepositoryConfiguration baseConfiguration) throws RepositoryException;
RemoteRepository createRemoteInstance( RemoteRepositoryConfiguration configuration) throws RepositoryException;
void updateRemoteInstance(EditableRemoteRepository repo, RemoteRepositoryConfiguration configuration) throws RepositoryException;
RemoteRepositoryConfiguration getRemoteConfiguration(RemoteRepository remoteRepository) throws RepositoryException;
ManagedRepositoryConfiguration getManagedConfiguration(ManagedRepository managedRepository) throws RepositoryException;

View File

@ -19,7 +19,13 @@ package org.apache.archiva.repository;
* under the License.
*/
import org.apache.archiva.configuration.*;
import org.apache.archiva.configuration.ArchivaConfiguration;
import org.apache.archiva.configuration.Configuration;
import org.apache.archiva.configuration.ConfigurationEvent;
import org.apache.archiva.configuration.ConfigurationListener;
import org.apache.archiva.configuration.IndeterminateConfigurationException;
import org.apache.archiva.configuration.ManagedRepositoryConfiguration;
import org.apache.archiva.configuration.RemoteRepositoryConfiguration;
import org.apache.archiva.redback.components.registry.RegistryException;
import org.apache.archiva.repository.features.StagingRepositoryFeature;
import org.slf4j.Logger;
@ -28,7 +34,12 @@ import org.springframework.stereotype.Service;
import javax.annotation.PostConstruct;
import javax.inject.Inject;
import java.util.*;
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.concurrent.locks.ReentrantReadWriteLock;
import java.util.stream.Collectors;
import java.util.stream.Stream;
@ -139,6 +150,7 @@ public class RepositoryRegistry implements ConfigurationListener {
return managedRepos;
} catch (Throwable e) {
log.error("Could not initialize repositories from config: {}",e.getMessage(), e );
//noinspection unchecked
return Collections.EMPTY_MAP;
}
}
@ -185,6 +197,7 @@ public class RepositoryRegistry implements ConfigurationListener {
if ( remoteRepoConfigs == null )
{
//noinspection unchecked
return Collections.EMPTY_MAP;
}
@ -210,6 +223,7 @@ public class RepositoryRegistry implements ConfigurationListener {
return remoteRepos;
} catch (Throwable e) {
log.error("Could not initialize remote repositories from config: {}", e.getMessage(), e);
//noinspection unchecked
return Collections.EMPTY_MAP;
}
}
@ -339,23 +353,20 @@ public class RepositoryRegistry implements ConfigurationListener {
}
/**
* Adds a new repository to the current list, or overwrites the repository definition with
* Adds a new repository to the current list, or replaces the repository definition with
* the same id, if it exists already.
* The change is saved to the configuration immediately.
*
* @param managedRepository the new repository.
* @throws RepositoryException if the new repository could not be saved to the configuration.
*/
public void addRepository( ManagedRepository managedRepository ) throws RepositoryException
public void putRepository( ManagedRepository managedRepository ) throws RepositoryException
{
rwLock.writeLock( ).lock( );
try
{
final String id = managedRepository.getId();
ManagedRepository originRepo = managedRepositories.put( id, managedRepository );
ManagedRepositoryConfiguration originCfg = null;
List<ManagedRepositoryConfiguration> cfgList = null;
int index = 0;
try
{
ManagedRepositoryConfiguration newCfg = getProvider( managedRepository.getType( ) ).getManagedConfiguration( managedRepository );
@ -385,6 +396,91 @@ public class RepositoryRegistry implements ConfigurationListener {
}
}
/**
* Adds a new repository or updates the repository with the same id, if it exists already.
* The configuration is saved immediately.
*
* @param managedRepositoryConfiguration the repository configuration
* @return the updated or created repository
* @throws RepositoryException if an error occurs, or the configuration is not valid.
*/
public ManagedRepository putRepository( ManagedRepositoryConfiguration managedRepositoryConfiguration) throws RepositoryException
{
rwLock.writeLock( ).lock( );
try
{
final String id = managedRepositoryConfiguration.getId();
final RepositoryType repositoryType = RepositoryType.valueOf( managedRepositoryConfiguration.getType() );
Configuration configuration = getArchivaConfiguration().getConfiguration();
ManagedRepository repo = managedRepositories.get(id);
ManagedRepositoryConfiguration oldCfg = repo!=null ? getProvider( repositoryType ).getManagedConfiguration( repo ) : null;
repo = putRepository( managedRepositoryConfiguration, configuration );
try
{
getArchivaConfiguration().save(configuration);
}
catch ( IndeterminateConfigurationException | RegistryException e )
{
if (oldCfg!=null) {
getProvider( repositoryType ).updateManagedInstance( (EditableManagedRepository)repo, oldCfg );
}
log.error("Could not save the configuration for repository {}: {}", id, e.getMessage(),e );
throw new RepositoryException( "Could not save the configuration for repository "+id+": "+e.getMessage() );
}
return repo;
}
finally
{
rwLock.writeLock( ).unlock( );
}
}
/**
* Adds a new repository or updates the repository with the same id. The given configuration object is updated, but
* the configuration is not saved.
*
* @param managedRepositoryConfiguration the new or changed repository configuration
* @param configuration the configuration object
* @return the new or updated repository
* @throws RepositoryException if the configuration cannot be saved or updated
*/
public ManagedRepository putRepository( ManagedRepositoryConfiguration managedRepositoryConfiguration, Configuration configuration) throws RepositoryException
{
rwLock.writeLock( ).lock( );
try
{
final String id = managedRepositoryConfiguration.getId();
final RepositoryType repoType = RepositoryType.valueOf( managedRepositoryConfiguration.getType() );
ManagedRepository repo;
if (managedRepositories.containsKey( id )) {
repo = managedRepositories.get(id);
if (repo instanceof EditableManagedRepository)
{
getProvider( repoType ).updateManagedInstance( (EditableManagedRepository) repo, managedRepositoryConfiguration );
} else {
throw new RepositoryException( "The repository is not editable "+id );
}
} else
{
repo = getProvider( repoType ).createManagedInstance( managedRepositoryConfiguration );
managedRepositories.put(id, repo);
}
ManagedRepositoryConfiguration oldCfg;
if ((oldCfg = configuration.findManagedRepositoryById( id ))!=null) {
configuration.removeManagedRepository( oldCfg );
}
configuration.addManagedRepository( managedRepositoryConfiguration );
return repo;
}
finally
{
rwLock.writeLock( ).unlock( );
}
}
/**
* Adds a remote repository, or overwrites the repository definition with the same id, if it exists already.
* The modification is saved to the configuration immediately.
@ -392,16 +488,13 @@ public class RepositoryRegistry implements ConfigurationListener {
* @param remoteRepository the remote repository to add
* @throws RepositoryException if an error occurs during configuration save
*/
public void addRepository( RemoteRepository remoteRepository ) throws RepositoryException
public void putRepository( RemoteRepository remoteRepository ) throws RepositoryException
{
rwLock.writeLock( ).lock( );
try
{
final String id = remoteRepository.getId();
RemoteRepository originRepo = remoteRepositories.put( id, remoteRepository );
RemoteRepositoryConfiguration originCfg = null;
List<RemoteRepositoryConfiguration> cfgList = null;
int index = 0;
try
{
RemoteRepositoryConfiguration newCfg = getProvider( remoteRepository.getType( ) ).getRemoteConfiguration( remoteRepository );
@ -431,6 +524,91 @@ public class RepositoryRegistry implements ConfigurationListener {
}
}
/**
* Adds a new repository or updates the repository with the same id, if it exists already.
* The configuration is saved immediately.
*
* @param remoteRepositoryConfiguration the repository configuration
* @return the updated or created repository
* @throws RepositoryException if an error occurs, or the configuration is not valid.
*/
public RemoteRepository putRepository( RemoteRepositoryConfiguration remoteRepositoryConfiguration) throws RepositoryException
{
rwLock.writeLock( ).lock( );
try
{
final String id = remoteRepositoryConfiguration.getId();
final RepositoryType repositoryType = RepositoryType.valueOf( remoteRepositoryConfiguration.getType() );
Configuration configuration = getArchivaConfiguration().getConfiguration();
RemoteRepository repo = remoteRepositories.get(id);
RemoteRepositoryConfiguration oldCfg = repo!=null ? getProvider( repositoryType ).getRemoteConfiguration( repo ) : null;
repo = putRepository( remoteRepositoryConfiguration, configuration );
try
{
getArchivaConfiguration().save(configuration);
}
catch ( IndeterminateConfigurationException | RegistryException e )
{
if (oldCfg!=null) {
getProvider( repositoryType ).updateRemoteInstance( (EditableRemoteRepository)repo, oldCfg );
}
log.error("Could not save the configuration for repository {}: {}", id, e.getMessage(),e );
throw new RepositoryException( "Could not save the configuration for repository "+id+": "+e.getMessage() );
}
return repo;
}
finally
{
rwLock.writeLock( ).unlock( );
}
}
/**
* Adds a new repository or updates the repository with the same id. The given configuration object is updated, but
* the configuration is not saved.
*
* @param remoteRepositoryConfiguration the new or changed repository configuration
* @param configuration the configuration object
* @return the new or updated repository
* @throws RepositoryException if the configuration cannot be saved or updated
*/
public RemoteRepository putRepository( RemoteRepositoryConfiguration remoteRepositoryConfiguration, Configuration configuration) throws RepositoryException
{
rwLock.writeLock( ).lock( );
try
{
final String id = remoteRepositoryConfiguration.getId();
final RepositoryType repoType = RepositoryType.valueOf( remoteRepositoryConfiguration.getType() );
RemoteRepository repo;
if (remoteRepositories.containsKey( id )) {
repo = remoteRepositories.get(id);
if (repo instanceof EditableRemoteRepository)
{
getProvider( repoType ).updateRemoteInstance( (EditableRemoteRepository) repo, remoteRepositoryConfiguration );
} else {
throw new RepositoryException( "The repository is not editable "+id );
}
} else
{
repo = getProvider( repoType ).createRemoteInstance( remoteRepositoryConfiguration );
remoteRepositories.put(id, repo);
}
RemoteRepositoryConfiguration oldCfg;
if ((oldCfg = configuration.findRemoteRepositoryById( id ))!=null) {
configuration.removeRemoteRepository( oldCfg );
}
configuration.addRemoteRepository( remoteRepositoryConfiguration );
return repo;
}
finally
{
rwLock.writeLock( ).unlock( );
}
}
/**
* Removes a managed repository from the registry and configuration, if it exists.
* The change is saved to the configuration immediately.
@ -460,9 +638,7 @@ public class RepositoryRegistry implements ConfigurationListener {
{
// Rollback
log.error("Could not save config after repository removal: {}", e.getMessage(), e);
if (repo!=null) {
managedRepositories.put(repo.getId(), repo);
}
managedRepositories.put(repo.getId(), repo);
throw new RepositoryException( "Could not save configuration after repository removal: "+e.getMessage() );
}
finally
@ -501,9 +677,7 @@ public class RepositoryRegistry implements ConfigurationListener {
{
// Rollback
log.error("Could not save config after repository removal: {}", e.getMessage(), e);
if (repo!=null) {
remoteRepositories.put(repo.getId(), repo);
}
remoteRepositories.put(repo.getId(), repo);
throw new RepositoryException( "Could not save configuration after repository removal: "+e.getMessage() );
}
finally

View File

@ -20,9 +20,21 @@ package org.apache.archiva.repository.maven2;
*/
import org.apache.archiva.configuration.AbstractRepositoryConfiguration;
import org.apache.archiva.configuration.ArchivaConfiguration;
import org.apache.archiva.configuration.ManagedRepositoryConfiguration;
import org.apache.archiva.configuration.RemoteRepositoryConfiguration;
import org.apache.archiva.repository.*;
import org.apache.archiva.repository.EditableManagedRepository;
import org.apache.archiva.repository.EditableRemoteRepository;
import org.apache.archiva.repository.EditableRepository;
import org.apache.archiva.repository.ManagedRepository;
import org.apache.archiva.repository.PasswordCredentials;
import org.apache.archiva.repository.ReleaseScheme;
import org.apache.archiva.repository.RemoteRepository;
import org.apache.archiva.repository.RepositoryCredentials;
import org.apache.archiva.repository.RepositoryException;
import org.apache.archiva.repository.RepositoryProvider;
import org.apache.archiva.repository.RepositoryType;
import org.apache.archiva.repository.UnsupportedURIException;
import org.apache.archiva.repository.features.ArtifactCleanupFeature;
import org.apache.archiva.repository.features.IndexCreationFeature;
import org.apache.archiva.repository.features.RemoteIndexFeature;
@ -32,8 +44,11 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import javax.inject.Inject;
import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.time.Duration;
@ -49,6 +64,10 @@ import java.util.Set;
public class MavenRepositoryProvider implements RepositoryProvider
{
@Inject
private ArchivaConfiguration archivaConfiguration;
private static final Logger log = LoggerFactory.getLogger( MavenRepositoryProvider.class );
static final Set<RepositoryType> TYPES = new HashSet<>( );
@ -105,13 +124,39 @@ public class MavenRepositoryProvider implements RepositoryProvider
public ManagedRepository createManagedInstance( ManagedRepositoryConfiguration cfg ) throws RepositoryException
{
MavenManagedRepository repo = new MavenManagedRepository(cfg.getId() ,cfg.getName());
repo.setLocation( getURIFromString( cfg.getLocation() ) );
updateManagedInstance( repo, cfg );
return repo;
}
@Override
public void updateManagedInstance( EditableManagedRepository repo , ManagedRepositoryConfiguration cfg ) throws RepositoryException
{
try
{
repo.setLocation( getURIFromString( cfg.getLocation() ) );
}
catch ( UnsupportedURIException e )
{
throw new RepositoryException( "The location entry is not a valid uri: "+cfg.getLocation() );
}
setBaseConfig( repo, cfg );
Path repoDir = Paths.get(repo.getAbsoluteLocation());
if (!Files.exists(repoDir)) {
try
{
Files.createDirectories( repoDir );
}
catch ( IOException e )
{
log.error("Could not create directory {} for repository {}", repo.getAbsoluteLocation(), repo.getId(), e);
throw new RepositoryException( "Could not create directory for repository "+repo.getAbsoluteLocation() );
}
}
repo.setSchedulingDefinition(cfg.getRefreshCronExpression());
repo.setBlocksRedeployment( cfg.isBlockRedeployments() );
repo.setScanned( cfg.isScanned() );
if (cfg.isReleases()) {
repo.addActiveReleaseScheme(ReleaseScheme.RELEASE);
repo.addActiveReleaseScheme( ReleaseScheme.RELEASE);
}
if (cfg.isSnapshots()) {
repo.addActiveReleaseScheme(ReleaseScheme.SNAPSHOT);
@ -129,10 +174,9 @@ public class MavenRepositoryProvider implements RepositoryProvider
artifactCleanupFeature.setDeleteReleasedSnapshots( cfg.isDeleteReleasedSnapshots() );
artifactCleanupFeature.setRetentionCount( cfg.getRetentionCount() );
artifactCleanupFeature.setRetentionTime( Period.ofDays( cfg.getRetentionTime() ) );
return repo;
}
@Override
public ManagedRepository createStagingInstance( ManagedRepositoryConfiguration baseConfiguration ) throws RepositoryException
{
@ -144,6 +188,13 @@ public class MavenRepositoryProvider implements RepositoryProvider
public RemoteRepository createRemoteInstance( RemoteRepositoryConfiguration cfg ) throws RepositoryException
{
MavenRemoteRepository repo = new MavenRemoteRepository( cfg.getId( ), cfg.getName( ) );
updateRemoteInstance( repo, cfg );
return repo;
}
@Override
public void updateRemoteInstance( EditableRemoteRepository repo, RemoteRepositoryConfiguration cfg ) throws RepositoryException
{
setBaseConfig( repo, cfg );
repo.setCheckPath( cfg.getCheckPath() );
repo.setSchedulingDefinition( cfg.getRefreshCronExpression() );
@ -151,9 +202,10 @@ public class MavenRepositoryProvider implements RepositoryProvider
{
repo.setLocation(new URI(cfg.getUrl()));
}
catch ( URISyntaxException e )
catch ( UnsupportedURIException | URISyntaxException e )
{
log.error("Could not set remote url "+cfg.getUrl());
throw new RepositoryException( "The url config is not a valid uri: "+cfg.getUrl() );
}
repo.setTimeout( Duration.ofSeconds( cfg.getTimeout() ) );
RemoteIndexFeature remoteIndexFeature = repo.getFeature( RemoteIndexFeature.class ).get();
@ -189,8 +241,6 @@ public class MavenRepositoryProvider implements RepositoryProvider
IndexCreationFeature indexCreationFeature = repo.getFeature( IndexCreationFeature.class ).get();
indexCreationFeature.setIndexPath( getURIFromString( cfg.getIndexDir() ) );
}
return repo;
}
@Override
@ -321,9 +371,30 @@ public class MavenRepositoryProvider implements RepositoryProvider
return stagingRepository;
}
private void setBaseConfig( EditableRepository repo, AbstractRepositoryConfiguration cfg) {
private void setBaseConfig( EditableRepository repo, AbstractRepositoryConfiguration cfg) throws RepositoryException {
final String baseUriStr = archivaConfiguration.getConfiguration().getArchivaRuntimeConfiguration().getRepositoryBaseDirectory();
try
{
URI baseUri = new URI(baseUriStr);
repo.setBaseUri( baseUri );
}
catch ( URISyntaxException e )
{
log.error("Could not set base URI {}: {}", baseUriStr, e.getMessage(), e);
throw new RepositoryException( "Could not set base URI "+ baseUriStr);
}
repo.setDescription( repo.getPrimaryLocale(), cfg.getDescription() );
repo.setLayout( cfg.getLayout() );
}
public ArchivaConfiguration getArchivaConfiguration( )
{
return archivaConfiguration;
}
public void setArchivaConfiguration( ArchivaConfiguration archivaConfiguration )
{
this.archivaConfiguration = archivaConfiguration;
}
}

View File

@ -19,9 +19,18 @@ package org.apache.archiva.repository.maven2;
* under the License.
*/
import org.apache.archiva.common.utils.FileUtils;
import org.apache.archiva.configuration.ArchivaConfiguration;
import org.apache.archiva.configuration.ArchivaRuntimeConfiguration;
import org.apache.archiva.configuration.Configuration;
import org.apache.archiva.configuration.ConfigurationListener;
import org.apache.archiva.configuration.DefaultArchivaConfiguration;
import org.apache.archiva.configuration.IndeterminateConfigurationException;
import org.apache.archiva.configuration.ManagedRepositoryConfiguration;
import org.apache.archiva.configuration.RemoteRepositoryConfiguration;
import org.apache.archiva.metadata.repository.storage.maven2.conf.MockConfiguration;
import org.apache.archiva.redback.components.registry.RegistryException;
import org.apache.archiva.redback.components.registry.RegistryListener;
import org.apache.archiva.repository.ManagedRepository;
import org.apache.archiva.repository.PasswordCredentials;
import org.apache.archiva.repository.ReleaseScheme;
@ -33,6 +42,7 @@ import org.apache.archiva.repository.features.IndexCreationFeature;
import org.apache.archiva.repository.features.RemoteIndexFeature;
import org.apache.archiva.repository.features.StagingRepositoryFeature;
import org.apache.archiva.test.utils.ArchivaSpringJUnit4ClassRunner;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
@ -42,6 +52,8 @@ import org.springframework.test.context.ContextConfiguration;
import javax.inject.Inject;
import javax.inject.Named;
import java.net.URI;
import java.nio.file.Files;
import java.nio.file.Path;
import java.time.Duration;
import java.time.Period;
import java.time.temporal.ChronoUnit;
@ -59,12 +71,25 @@ public class MavenRepositoryProviderTest
MavenRepositoryProvider provider;
Path repoLocation;
@Before
public void setUp()
throws Exception
{
provider = new MavenRepositoryProvider();
provider = new MavenRepositoryProvider( );
MockConfiguration mockConfiguration =new MockConfiguration();
mockConfiguration.getConfiguration().setArchivaRuntimeConfiguration( new ArchivaRuntimeConfiguration() );
mockConfiguration.getConfiguration().getArchivaRuntimeConfiguration().setRepositoryBaseDirectory( "repositories" );
provider.setArchivaConfiguration( mockConfiguration );
}
@After
public void cleanUp() {
if (repoLocation!=null && Files.exists( repoLocation )) {
FileUtils.deleteQuietly( repoLocation );
}
}
@Test
@ -82,7 +107,8 @@ public class MavenRepositoryProviderTest
repo.setName("Managed Test Repo 001");
repo.setDescription( "This is a managed test" );
repo.setRetentionTime( 37 );
repo.setLocation( "file:///test/dir/repository" );
repoLocation = Files.createTempDirectory( "test-repo-001");
repo.setLocation( repoLocation.toAbsolutePath().toString() );
repo.setSnapshots( true );
repo.setReleases( true );
repo.setRefreshCronExpression( "4 0 0 ? * TUE" );
@ -99,7 +125,10 @@ public class MavenRepositoryProviderTest
ManagedRepository mr = provider.createManagedInstance( repo );
assertNotNull(mr.getLocation());
assertEquals("file:///test/dir/repository", mr.getLocation().toString());
String repoUri = repoLocation.toUri().toString();
assertTrue(Files.exists(repoLocation));
repoUri = repoUri.substring( 0, repoUri.length()-1 );
assertEquals(repoUri, mr.getLocation().toString());
assertEquals("This is a managed test", mr.getDescription());
assertEquals("Managed Test Repo 001", mr.getName());
assertEquals(2, mr.getActiveReleaseSchemes().size());