@@ -128,5 +128,10 @@ public interface EditableRepository extends Repository | |||
*/ | |||
void setIndexingContext(ArchivaIndexingContext context); | |||
/** | |||
* Sets the last repository state. | |||
* @param state the state value | |||
*/ | |||
void setLastState(RepositoryState state); | |||
} |
@@ -173,5 +173,14 @@ public interface Repository extends EventSource, RepositoryStorage { | |||
*/ | |||
boolean isOpen(); | |||
/** | |||
* Returns the last state of this repository instance. As multiple repository instances may point to the | |||
* same repository, this is only a representation of the last state, when this particular instance was | |||
* used by the registry. | |||
* | |||
* @return the last known state of this repository instance | |||
*/ | |||
default RepositoryState getLastState() { | |||
return RepositoryState.CREATED; | |||
} | |||
} |
@@ -32,6 +32,17 @@ import java.util.Map; | |||
* This is the generic interface that handles different repository flavours, currently for | |||
* ManagedRepository, RemoteRepository and RepositoryGroup | |||
* | |||
* Lifecycle/states of a repository: | |||
* <ul> | |||
* <li>Instance created: This state is reached by the newInstance-methods. The instance is created, filled with the | |||
* corresponding attribute data and references are updated. References are object references to other repositories, if they exist. | |||
* The instance is not registered on the registry (stored) and configuration is not updated.</li> | |||
* <li>Instance registered: Instances added/updated by the put()-methods are created and registered on the registry. | |||
* If all goes well, the configuration is updated.</li> | |||
* <li>Instance initialized: </li> | |||
* </ul> | |||
* | |||
* | |||
* @author Martin Stockhammer <martin_s@apache.org> | |||
*/ | |||
public interface RepositoryHandler<R extends Repository, C> |
@@ -0,0 +1,37 @@ | |||
package org.apache.archiva.repository; | |||
/* | |||
* 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. | |||
*/ | |||
/** | |||
* @author Martin Stockhammer <martin_s@apache.org> | |||
*/ | |||
public enum RepositoryState | |||
{ | |||
CREATED(0),REFERENCES_SET(100),SAVED(200),INITIALIZED(300),REGISTERED(400),UNREGISTERED(500),CLOSED(600); | |||
private final int orderNumber; | |||
RepositoryState( int orderNumber ) | |||
{ | |||
this.orderNumber = orderNumber; | |||
} | |||
public int getOrderNumber() { | |||
return orderNumber; | |||
} | |||
} |
@@ -30,6 +30,7 @@ import org.apache.archiva.event.EventType; | |||
import org.apache.archiva.indexer.ArchivaIndexingContext; | |||
import org.apache.archiva.repository.EditableRepository; | |||
import org.apache.archiva.repository.RepositoryCapabilities; | |||
import org.apache.archiva.repository.RepositoryState; | |||
import org.apache.archiva.repository.RepositoryType; | |||
import org.apache.archiva.repository.UnsupportedFeatureException; | |||
import org.apache.archiva.repository.event.*; | |||
@@ -85,6 +86,7 @@ public abstract class AbstractRepository implements EditableRepository, EventHan | |||
String schedulingDefinition = "0 0 02 * * ?"; | |||
private String layout = "default"; | |||
public static final CronDefinition CRON_DEFINITION = CronDefinitionBuilder.instanceDefinitionFor(CronType.QUARTZ); | |||
private RepositoryState state; | |||
private final EventManager eventManager; | |||
@@ -324,6 +326,7 @@ public abstract class AbstractRepository implements EditableRepository, EventHan | |||
sf.getStagingRepository().close(); | |||
} | |||
} | |||
setLastState( RepositoryState.CLOSED ); | |||
} | |||
} | |||
@@ -425,4 +428,17 @@ public abstract class AbstractRepository implements EditableRepository, EventHan | |||
protected RepositoryStorage getStorage() { | |||
return storage; | |||
} | |||
@Override | |||
public RepositoryState getLastState( ) | |||
{ | |||
return this.state; | |||
} | |||
@Override | |||
public void setLastState( RepositoryState state ) | |||
{ | |||
this.state = state; | |||
} | |||
} |
@@ -17,10 +17,15 @@ package org.apache.archiva.repository.base; | |||
* under the License. | |||
*/ | |||
import org.apache.archiva.repository.EditableRepository; | |||
import org.apache.archiva.repository.Repository; | |||
import org.apache.archiva.repository.RepositoryHandler; | |||
import org.apache.archiva.repository.RepositoryState; | |||
import org.apache.archiva.repository.base.group.RepositoryGroupHandler; | |||
import org.apache.archiva.repository.validation.CombinedValidator; | |||
import org.apache.archiva.repository.validation.RepositoryValidator; | |||
import org.slf4j.Logger; | |||
import org.slf4j.LoggerFactory; | |||
import java.util.Collections; | |||
import java.util.List; | |||
@@ -32,6 +37,9 @@ import java.util.stream.Collectors; | |||
*/ | |||
public abstract class AbstractRepositoryHandler<R extends Repository, C> implements RepositoryHandler<R, C> | |||
{ | |||
private static final Logger log = LoggerFactory.getLogger( AbstractRepositoryHandler.class ); | |||
protected List<RepositoryValidator<R>> initValidators( Class<R> clazz, List<RepositoryValidator<? extends Repository>> repositoryGroupValidatorList) { | |||
if (repositoryGroupValidatorList!=null && repositoryGroupValidatorList.size()>0) { | |||
return repositoryGroupValidatorList.stream( ).filter( | |||
@@ -46,4 +54,14 @@ public abstract class AbstractRepositoryHandler<R extends Repository, C> impleme | |||
return new CombinedValidator<>( clazz, initValidators( clazz, repositoryGroupValidatorList ) ); | |||
} | |||
protected void setLastState(Repository repo, RepositoryState state) { | |||
if (repo instanceof EditableRepository ) { | |||
if (state.getOrderNumber()>repo.getLastState().getOrderNumber()) | |||
{ | |||
( (EditableRepository) repo ).setLastState( state ); | |||
} | |||
} else { | |||
log.error( "Found a not editable repository instance: {}, {}", repo.getId( ), repo.getClass().getName() ); | |||
} | |||
} | |||
} |
@@ -24,6 +24,7 @@ import org.apache.archiva.repository.ManagedRepository; | |||
import org.apache.archiva.repository.ReleaseScheme; | |||
import org.apache.archiva.repository.RepositoryCapabilities; | |||
import org.apache.archiva.repository.RepositoryGroup; | |||
import org.apache.archiva.repository.RepositoryState; | |||
import org.apache.archiva.repository.RepositoryType; | |||
import org.apache.archiva.repository.StandardCapabilities; | |||
import org.apache.archiva.repository.base.AbstractRepository; | |||
@@ -70,6 +71,7 @@ public class BasicRepositoryGroup extends AbstractRepository implements Editable | |||
feature.setLocalIndexPath( repositoryStorage.getRoot( ).resolve(".indexer") ); | |||
feature.setLocalPackedIndexPath( repositoryStorage.getRoot( ).resolve(".index") ); | |||
addFeature( feature ); | |||
setLastState( RepositoryState.CREATED ); | |||
} | |||
@Override |
@@ -22,6 +22,7 @@ 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.RepositoryState; | |||
import org.apache.archiva.repository.base.AbstractRepositoryHandler; | |||
import org.apache.archiva.repository.base.ArchivaRepositoryRegistry; | |||
import org.apache.archiva.repository.base.ConfigurationHandler; | |||
@@ -174,6 +175,7 @@ public class RepositoryGroupHandler | |||
} | |||
mergedRemoteIndexesScheduler.schedule( repositoryGroup, | |||
indexDirectory ); | |||
setLastState( repositoryGroup, RepositoryState.INITIALIZED ); | |||
} | |||
public StorageAsset getMergedIndexDirectory( RepositoryGroup group ) | |||
@@ -251,10 +253,13 @@ public class RepositoryGroupHandler | |||
{ | |||
RepositoryGroup repositoryGroup = provider.createRepositoryGroup( config ); | |||
updateReferences( repositoryGroup, config ); | |||
if (repositoryGroup instanceof EditableRepository) | |||
{ | |||
( (EditableRepository) repositoryGroup ).setLastState( RepositoryState.REFERENCES_SET ); | |||
} | |||
return repositoryGroup; | |||
} | |||
/** | |||
* Adds a new repository group to the current list, or replaces the repository group definition with | |||
* the same id, if it exists already. | |||
@@ -290,6 +295,7 @@ public class RepositoryGroupHandler | |||
} | |||
configuration.addRepositoryGroup( newCfg ); | |||
configurationHandler.save( configuration, ConfigurationHandler.REGISTRY_EVENT_TAG ); | |||
setLastState( repositoryGroup, RepositoryState.SAVED ); | |||
initialize( repositoryGroup ); | |||
} | |||
finally | |||
@@ -297,6 +303,7 @@ public class RepositoryGroupHandler | |||
configLock.unlock( ); | |||
} | |||
repositoryGroups.put( id, repositoryGroup ); | |||
setLastState( repositoryGroup, RepositoryState.REGISTERED ); | |||
return repositoryGroup; | |||
} | |||
catch ( Exception e ) | |||
@@ -349,8 +356,10 @@ public class RepositoryGroupHandler | |||
} | |||
configurationHandler.save( configuration, ConfigurationHandler.REGISTRY_EVENT_TAG ); | |||
updateReferences( currentRepository, repositoryGroupConfiguration ); | |||
setLastState( currentRepository, RepositoryState.REFERENCES_SET ); | |||
initialize( currentRepository ); | |||
this.repositoryGroups.put( id, currentRepository ); | |||
setLastState( currentRepository, RepositoryState.REGISTERED ); | |||
} | |||
catch ( IndeterminateConfigurationException | RegistryException | RepositoryException e ) | |||
{ | |||
@@ -369,7 +378,12 @@ public class RepositoryGroupHandler | |||
log.error( "Fatal error, config save during rollback failed: {}", e.getMessage( ), e ); | |||
} | |||
updateReferences( oldRepository, oldCfg ); | |||
setLastState( oldRepository, RepositoryState.REFERENCES_SET ); | |||
initialize( oldRepository ); | |||
repositoryGroups.put( id, oldRepository ); | |||
setLastState( oldRepository, RepositoryState.REGISTERED ); | |||
} else { | |||
repositoryGroups.remove( id ); | |||
} | |||
log.error( "Could not save the configuration for repository group {}: {}", id, e.getMessage( ), e ); | |||
if (e instanceof RepositoryException) { | |||
@@ -409,9 +423,11 @@ public class RepositoryGroupHandler | |||
else | |||
{ | |||
repo = repositoryRegistry.getProvider( repoType ).createRepositoryGroup( repositoryGroupConfiguration ); | |||
setLastState( repo, RepositoryState.CREATED ); | |||
} | |||
replaceOrAddRepositoryConfig( repositoryGroupConfiguration, configuration ); | |||
updateReferences( repo, repositoryGroupConfiguration ); | |||
setLastState( repo, RepositoryState.REFERENCES_SET ); | |||
return repo; | |||
} | |||
@@ -501,6 +517,7 @@ public class RepositoryGroupHandler | |||
configuration.removeRepositoryGroup( cfg ); | |||
} | |||
this.configurationHandler.save( configuration, ConfigurationHandler.REGISTRY_EVENT_TAG ); | |||
setLastState( repo, RepositoryState.UNREGISTERED ); | |||
} | |||
} | |||
@@ -530,6 +547,7 @@ public class RepositoryGroupHandler | |||
{ | |||
configuration.removeRepositoryGroup( cfg ); | |||
} | |||
setLastState( repo, RepositoryState.UNREGISTERED ); | |||
} | |||
} | |||
@@ -548,6 +566,7 @@ public class RepositoryGroupHandler | |||
RepositoryGroupConfiguration cfg = provider.getRepositoryGroupConfiguration( repo ); | |||
RepositoryGroup cloned = provider.createRepositoryGroup( cfg ); | |||
cloned.registerEventHandler( RepositoryEvent.ANY, repositoryRegistry ); | |||
setLastState( cloned, RepositoryState.CREATED ); | |||
return cloned; | |||
} | |||
@@ -23,6 +23,7 @@ import org.apache.archiva.common.filelock.FileLockManager; | |||
import org.apache.archiva.repository.ReleaseScheme; | |||
import org.apache.archiva.repository.RepositoryCapabilities; | |||
import org.apache.archiva.repository.RepositoryRequestInfo; | |||
import org.apache.archiva.repository.RepositoryState; | |||
import org.apache.archiva.repository.RepositoryType; | |||
import org.apache.archiva.repository.StandardCapabilities; | |||
import org.apache.archiva.repository.storage.fs.FilesystemStorage; | |||
@@ -61,12 +62,14 @@ public class BasicManagedRepository extends AbstractManagedRepository | |||
{ | |||
super( RepositoryType.MAVEN, id, name, repositoryStorage ); | |||
initFeatures(); | |||
setLastState( RepositoryState.CREATED ); | |||
} | |||
public BasicManagedRepository( Locale primaryLocale, RepositoryType type, String id, String name, RepositoryStorage repositoryStorage ) | |||
{ | |||
super( primaryLocale, type, id, name, repositoryStorage); | |||
initFeatures(); | |||
setLastState( RepositoryState.CREATED ); | |||
} | |||
private void initFeatures() { |
@@ -22,6 +22,7 @@ import org.apache.archiva.common.filelock.DefaultFileLockManager; | |||
import org.apache.archiva.common.filelock.FileLockManager; | |||
import org.apache.archiva.repository.ReleaseScheme; | |||
import org.apache.archiva.repository.RepositoryCapabilities; | |||
import org.apache.archiva.repository.RepositoryState; | |||
import org.apache.archiva.repository.RepositoryType; | |||
import org.apache.archiva.repository.StandardCapabilities; | |||
import org.apache.archiva.repository.storage.fs.FilesystemStorage; | |||
@@ -61,12 +62,14 @@ public class BasicRemoteRepository extends AbstractRemoteRepository | |||
{ | |||
super( RepositoryType.MAVEN, id, name, storage); | |||
initFeatures(); | |||
setLastState( RepositoryState.CREATED ); | |||
} | |||
public BasicRemoteRepository( Locale primaryLocale, RepositoryType type, String id, String name, RepositoryStorage storage ) | |||
{ | |||
super( primaryLocale, type, id, name, storage ); | |||
initFeatures(); | |||
setLastState( RepositoryState.CREATED ); | |||
} | |||
private void initFeatures() { |
@@ -28,10 +28,6 @@ import static org.junit.jupiter.api.Assertions.*; | |||
class RepositoryGroupHandlerTest | |||
{ | |||
@Test | |||
void init( ) | |||
{ | |||
} | |||
@Test | |||
void initializeFromConfig( ) |
@@ -25,6 +25,7 @@ import org.apache.archiva.indexer.ArchivaIndexingContext; | |||
import org.apache.archiva.repository.ReleaseScheme; | |||
import org.apache.archiva.repository.RepositoryCapabilities; | |||
import org.apache.archiva.repository.RepositoryRequestInfo; | |||
import org.apache.archiva.repository.RepositoryState; | |||
import org.apache.archiva.repository.RepositoryType; | |||
import org.apache.archiva.repository.StandardCapabilities; | |||
import org.apache.archiva.repository.UnsupportedFeatureException; | |||
@@ -77,12 +78,14 @@ public class MavenManagedRepository extends AbstractManagedRepository | |||
super( RepositoryType.MAVEN, id, name, storage); | |||
this.indexCreationFeature = new IndexCreationFeature(this, this); | |||
setLocation(storage.getRoot().getFilePath().toUri()); | |||
setLastState( RepositoryState.CREATED ); | |||
} | |||
public MavenManagedRepository( Locale primaryLocale, String id, String name, FilesystemStorage storage ) | |||
{ | |||
super( primaryLocale, RepositoryType.MAVEN, id, name, storage ); | |||
setLocation(storage.getRoot().getFilePath().toUri()); | |||
setLastState( RepositoryState.CREATED ); | |||
} | |||
@Override |
@@ -5,6 +5,7 @@ import org.apache.archiva.common.filelock.FileLockManager; | |||
import org.apache.archiva.repository.ReleaseScheme; | |||
import org.apache.archiva.repository.RemoteRepository; | |||
import org.apache.archiva.repository.RepositoryCapabilities; | |||
import org.apache.archiva.repository.RepositoryState; | |||
import org.apache.archiva.repository.RepositoryType; | |||
import org.apache.archiva.repository.StandardCapabilities; | |||
import org.apache.archiva.repository.UnsupportedFeatureException; | |||
@@ -67,13 +68,14 @@ public class MavenRemoteRepository extends AbstractRemoteRepository | |||
{ | |||
super( RepositoryType.MAVEN, id, name, storage ); | |||
this.indexCreationFeature = new IndexCreationFeature(this, this); | |||
setLastState( RepositoryState.CREATED ); | |||
} | |||
public MavenRemoteRepository( Locale primaryLocale, String id, String name, FilesystemStorage storage ) | |||
{ | |||
super( primaryLocale, RepositoryType.MAVEN, id, name, storage ); | |||
this.indexCreationFeature = new IndexCreationFeature(this, this); | |||
setLastState( RepositoryState.CREATED ); | |||
} | |||
@Override |
@@ -24,6 +24,7 @@ import org.apache.archiva.common.filelock.FileLockManager; | |||
import org.apache.archiva.repository.EditableRepositoryGroup; | |||
import org.apache.archiva.repository.ReleaseScheme; | |||
import org.apache.archiva.repository.RepositoryCapabilities; | |||
import org.apache.archiva.repository.RepositoryState; | |||
import org.apache.archiva.repository.RepositoryType; | |||
import org.apache.archiva.repository.StandardCapabilities; | |||
import org.apache.archiva.repository.base.group.AbstractRepositoryGroup; | |||
@@ -58,11 +59,13 @@ public class MavenRepositoryGroup extends AbstractRepositoryGroup implements Edi | |||
public MavenRepositoryGroup(String id, String name, FilesystemStorage storage) { | |||
super(RepositoryType.MAVEN, id, name, storage); | |||
init(); | |||
setLastState( RepositoryState.CREATED ); | |||
} | |||
public MavenRepositoryGroup(Locale primaryLocale, String id, String name, FilesystemStorage storage) { | |||
super(primaryLocale, RepositoryType.MAVEN, id, name, storage); | |||
init(); | |||
setLastState( RepositoryState.CREATED ); | |||
} | |||
private Path getRepositoryPath() { |