public RepositoryGroupConfiguration findRepositoryGroupById( String id )
{
- if ( repositoryGroups != null )
+ if ( repositoryGroups != null && id!=null)
{
- for ( RepositoryGroupConfiguration group : (java.util.List<RepositoryGroupConfiguration>) repositoryGroups )
- {
- if ( group.getId().equals( id ) )
- {
- return group;
- }
- }
+ return ( (java.util.List<RepositoryGroupConfiguration>) repositoryGroups ).stream( ).filter( g -> g != null && id.equals( g.getId( ) ) ).findFirst( ).orElse( null );
}
return null;
}
import org.apache.archiva.repository.validation.CheckedResult;
import org.apache.archiva.repository.validation.RepositoryChecker;
import org.apache.archiva.repository.validation.RepositoryValidator;
+import org.apache.archiva.repository.validation.ValidationError;
import org.apache.archiva.repository.validation.ValidationResponse;
import java.util.Collection;
+import java.util.List;
import java.util.Map;
/**
- *
- * This is the generic interface that handles different repository flavours.
+ * This is the generic interface that handles different repository flavours, currently for
+ * ManagedRepository, RemoteRepository and RepositoryGroup
*
* @author Martin Stockhammer <martin_s@apache.org>
*/
{
/**
- * Creates instances from the archiva configuration. The instances are not registered in the registry.
+ * Initializes the current state from the configuration
+ */
+ void initializeFromConfig( );
+
+ /**
+ * Initializes the repository. E.g. starts scheduling and activate additional processes.
+ * @param repository the repository to initialize
+ */
+ void initialize( R repository );
+
+ /**
+ * Creates new instances from the archiva configuration. The instances are not registered in the registry.
*
* @return A map of (repository id, Repository) pairs
*/
- Map<String, R> newInstancesFromConfig();
+ Map<String, R> newInstancesFromConfig( );
/**
* Creates a new instance without registering and without updating the archiva configuration
*
* @param type the repository type
- * @param id the repository identifier
+ * @param id the repository identifier
* @return the repository instance
* @throws RepositoryException if the creation failed
*/
- R newInstance(RepositoryType type, String id) throws RepositoryException;
+ R newInstance( RepositoryType type, String id ) throws RepositoryException;
/**
* Creates a new instance and updates the given configuration object.
* and not initialized. References are not updated.
*
* @param repositoryConfiguration the repository configuration
- * @param configuration the configuration instance
+ * @param configuration the configuration instance
* @return the repository instance that was created or updated
* @throws RepositoryException if the update or creation failed
*/
* If the checker returns a valid result, the registry is updated and configuration is saved.
*
* @param repositoryConfiguration the repository configuration
- * @param checker the checker that validates the repository data
+ * @param checker the checker that validates the repository data
* @return the repository and the check result
* @throws RepositoryException if the creation or update failed
*/
<D> CheckedResult<R, D>
- putWithCheck( C repositoryConfiguration, RepositoryChecker<R, D> checker) throws RepositoryException;
+ putWithCheck( C repositoryConfiguration, RepositoryChecker<R, D> checker ) throws RepositoryException;
/**
* Removes the given repository from the registry and updates references and saves the new configuration.
* Removes the given repository from the registry and updates only the given configuration instance.
* The archiva registry is not updated
*
- * @param id the repository identifier
+ * @param id the repository identifier
* @param configuration the configuration to update
* @throws RepositoryException if the repository could not be removed
*/
* @param repo the repository that should be cloned
* @return a newly created instance with the same repository data
*/
- R clone(R repo) throws RepositoryException;
+ R clone( R repo ) throws RepositoryException;
/**
* Updates the references and stores updates in the given <code>configuration</code> instance.
* This method may register/unregister repositories depending on the implementation. That means there is no simple
* way to roll back, if an error occurs.
*
- * @param repo the repository for which references are updated
+ * @param repo the repository for which references are updated
* @param repositoryConfiguration the repository configuration
*/
void updateReferences( R repo, C repositoryConfiguration ) throws RepositoryException;
*
* @return the list of repositories
*/
- Collection<R> getAll();
+ Collection<R> getAll( );
/**
* Returns a validator that can be used to validate repository data
+ *
* @return a validator instance
*/
RepositoryValidator<R> getValidator( );
* @param repository the repository to validate against
* @return the result of the validation.
*/
- ValidationResponse<R> validateRepository( R repository);
+ CheckedResult<R,Map<String, List<ValidationError>>> validateRepository( R repository );
/**
* Validates the set attributes of the given repository instance for a repository update and returns the validation result.
* @param repository the repository to validate against
* @return the result of the validation.
*/
- ValidationResponse<R> validateRepositoryForUpdate( R repository);
-
+ CheckedResult<R,Map<String, List<ValidationError>>> validateRepositoryForUpdate( R repository );
/**
* Returns <code>true</code>, if the repository is registered with the given id, otherwise <code>false</code>
+ *
* @param id the repository identifier
* @return <code>true</code>, if it is registered, otherwise <code>false</code>
*/
- boolean has(String id);
+ boolean has( String id );
/**
* Initializes
*/
- void init();
+ void init( );
/**
* Closes the handler
*/
- void close();
+ void close( );
}
}
AbstractFeature(EventHandler listener) {
- this.listener.add(listener);
+ if (listener!=null)
+ {
+ this.listener.add( listener );
+ }
}
AbstractFeature(Collection<EventHandler> listeners) {
/**
* Sets the path (relative or absolute) of the packed index.
*
- * Throws a {@link RepositoryIndexEvent.Index#PACKED_INDEX_URI_CHANGE}, if the value changes.
+ * Throws a {@link RepositoryIndexEvent#packedIndexUriChange(Object, Repository, URI, URI)}, if the value changes.
*
* @param packedIndexPath the new path uri for the packed index
*/
String MAX_LENGTH_EXCEEDED = "max_length";
String INVALID_CHARS = "invalid_chars";
String BELOW_MIN = "min";
- String INVALID_SCHEDULING_EXPRESSION = "scheduling_exp_invalid";
- String INVALID_LOCATION = "location_invalid";
+ String INVALID_SCHEDULING_EXPRESSION = "invalid_scheduling_exp";
+ String INVALID_LOCATION = "invalid_location";
}
{
String REPOSITORY_ID_VALID_EXPRESSION = "^[a-zA-Z0-9._-]+$";
+ String[] REPOSITORY_ID_ALLOWED = new String[]{"alphanumeric, '.', '-','_'"};
String REPOSITORY_NAME_VALID_EXPRESSION = "^([a-zA-Z0-9.)/_(-]|\\s)+$";
+ String[] REPOSITORY_NAME_ALLOWED = new String[]{"alphanumeric", "whitespace", "/", "(", ")", "_", ".", "-"};
String REPOSITORY_LOCATION_VALID_EXPRESSION = "^[-a-zA-Z0-9._/~:?!&=\\\\]+$";
@Override
public void setSchedulingDefinition(String cronExpression) {
- if (StringUtils.isNotEmpty( cronExpression ))
- {
- CronParser parser = new CronParser( CRON_DEFINITION );
- parser.parse( cronExpression ).validate( );
- }
this.schedulingDefinition = cronExpression;
}
@Override
public void setIndexingContext(ArchivaIndexingContext context) {
- if (this.indexingContext!=null) {
-
- }
this.indexingContext = context;
}
--- /dev/null
+package org.apache.archiva.repository.base;
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import org.apache.archiva.repository.Repository;
+import org.apache.archiva.repository.RepositoryHandler;
+import org.apache.archiva.repository.validation.CombinedValidator;
+import org.apache.archiva.repository.validation.RepositoryValidator;
+
+import java.util.Collections;
+import java.util.List;
+import java.util.stream.Collectors;
+
+/**
+ * Base abstract class for repository handlers.
+ * @author Martin Stockhammer <martin_s@apache.org>
+ */
+public abstract class AbstractRepositoryHandler<R extends Repository, C> implements RepositoryHandler<R, C>
+{
+ protected List<RepositoryValidator<R>> initValidators( Class<R> clazz, List<RepositoryValidator<? extends Repository>> repositoryGroupValidatorList) {
+ if (repositoryGroupValidatorList!=null && repositoryGroupValidatorList.size()>0) {
+ return repositoryGroupValidatorList.stream( ).filter(
+ v -> v.isFlavour( clazz )
+ ).map( v -> v.narrowTo( clazz ) ).collect( Collectors.toList( ) );
+ } else {
+ return Collections.emptyList( );
+ }
+ }
+
+ protected CombinedValidator<R> getCombinedValidatdor(Class<R> clazz, List<RepositoryValidator<? extends Repository>> repositoryGroupValidatorList) {
+ return new CombinedValidator<>( clazz, initValidators( clazz, repositoryGroupValidatorList ) );
+ }
+
+}
--- /dev/null
+package org.apache.archiva.repository.base.group;
+/*
+ * 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.common.filelock.DefaultFileLockManager;
+import org.apache.archiva.common.filelock.FileLockManager;
+import org.apache.archiva.repository.EditableRepositoryGroup;
+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.RepositoryType;
+import org.apache.archiva.repository.StandardCapabilities;
+import org.apache.archiva.repository.base.AbstractRepository;
+import org.apache.archiva.repository.base.managed.BasicManagedRepository;
+import org.apache.archiva.repository.features.IndexCreationFeature;
+import org.apache.archiva.repository.storage.RepositoryStorage;
+import org.apache.archiva.repository.storage.fs.FilesystemStorage;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.io.IOException;
+import java.nio.file.Path;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * @author Martin Stockhammer <martin_s@apache.org>
+ */
+public class BasicRepositoryGroup extends AbstractRepository implements EditableRepositoryGroup
+{
+ private static final RepositoryCapabilities CAPABILITIES = new StandardCapabilities(
+ new ReleaseScheme[] { ReleaseScheme.RELEASE, ReleaseScheme.SNAPSHOT },
+ new String[] {},
+ new String[] {},
+ new String[] {IndexCreationFeature.class.getName()},
+ false,
+ false,
+ false,
+ false,
+ false
+ );
+
+ private int mergedIndexTtl = 0;
+ private boolean hasIndex = false;
+
+ private final Logger log = LoggerFactory.getLogger(BasicRepositoryGroup.class);
+
+ private List<ManagedRepository> repositories = new ArrayList<>( );
+
+ public BasicRepositoryGroup( String id, String name, RepositoryStorage repositoryStorage )
+ {
+ super( RepositoryType.MAVEN, id, name, repositoryStorage );
+ IndexCreationFeature feature = new IndexCreationFeature( this, null );
+ feature.setLocalIndexPath( repositoryStorage.getRoot( ).resolve(".indexer") );
+ feature.setLocalPackedIndexPath( repositoryStorage.getRoot( ).resolve(".index") );
+ addFeature( feature );
+ }
+
+ @Override
+ public List<ManagedRepository> getRepositories( )
+ {
+ return repositories;
+ }
+
+ @Override
+ public boolean contains( ManagedRepository repository )
+ {
+ return repositories.contains( repository );
+ }
+
+ @Override
+ public boolean contains( String id )
+ {
+ return repositories.stream( ).anyMatch( v -> id.equals( v.getId( ) ) );
+ }
+
+ @Override
+ public int getMergedIndexTTL( )
+ {
+ return mergedIndexTtl;
+ }
+
+ @Override
+ public boolean hasIndex( )
+ {
+ return hasIndex;
+ }
+
+ @Override
+ public RepositoryCapabilities getCapabilities( )
+ {
+ return CAPABILITIES;
+ }
+
+ @Override
+ public void clearRepositories( )
+ {
+ this.repositories.clear( );
+ }
+
+ @Override
+ public void setRepositories( List<ManagedRepository> repositories )
+ {
+ this.repositories.clear();
+ this.repositories.addAll( repositories );
+ }
+
+ @Override
+ public void addRepository( ManagedRepository repository )
+ {
+ if ( !this.repositories.contains( repository ) )
+ {
+ this.repositories.add( repository );
+ }
+ }
+
+ @Override
+ public void addRepository( int index, ManagedRepository repository )
+ {
+ if (!this.repositories.contains( repository )) {
+ this.repositories.add( index, repository );
+ }
+ }
+
+ @Override
+ public boolean removeRepository( ManagedRepository repository )
+ {
+ return this.repositories.remove( repository );
+ }
+
+ @Override
+ public ManagedRepository removeRepository( String repoId )
+ {
+ for (ManagedRepository repo : this.repositories) {
+
+ if (repoId.equals( repo.getId() )) {
+ this.repositories.remove( repo );
+ return repo;
+ }
+ }
+ return null;
+ }
+
+ @Override
+ public void setMergedIndexTTL( int timeInSeconds )
+ {
+ this.mergedIndexTtl = timeInSeconds;
+ }
+
+ /**
+ * Creates a filesystem based repository instance. The path is built by basePath/repository-id
+ *
+ * @param id The repository id
+ * @param name The name of the repository
+ * @param repositoryPath The path to the repository
+ * @return The repository instance
+ * @throws IOException
+ */
+ public static BasicRepositoryGroup newFilesystemInstance( String id, String name, Path repositoryPath) throws IOException {
+ FileLockManager lockManager = new DefaultFileLockManager();
+ FilesystemStorage storage = new FilesystemStorage(repositoryPath, lockManager);
+ return new BasicRepositoryGroup(id, name, storage);
+ }
+
+}
{
private static final String CATEGORY = "repository_group";
- private static final Pattern REPO_GROUP_ID_PATTERN = Pattern.compile( "[A-Za-z0-9._\\-]+" );
+ private static final Pattern REPOSITORY_ID_VALID_EXPRESSION_PATTERN = Pattern.compile( REPOSITORY_ID_VALID_EXPRESSION );
+ private static final Pattern REPOSITORY_NAME_VALID_EXPRESSION_PATTERN = Pattern.compile( REPOSITORY_NAME_VALID_EXPRESSION );
+
private final ConfigurationHandler configurationHandler;
private RepositoryRegistry repositoryRegistry;
@Override
public ValidationResponse<RepositoryGroup> apply( RepositoryGroup repositoryGroup, boolean updateMode ) throws IllegalArgumentException
{
- final String repoGroupId = repositoryGroup.getId( );
Map<String, List<ValidationError>> errors = null;
+ if (repositoryGroup==null) {
+ errors = appendError( null, "object", ISNULL );
+ return new ValidationResponse<>( repositoryGroup, errors );
+ }
+ final String repoGroupId = repositoryGroup.getId( );
if ( StringUtils.isBlank( repoGroupId ) )
{
errors = appendError( null, "id", ISEMPTY );
}
- Matcher matcher = REPO_GROUP_ID_PATTERN.matcher( repoGroupId );
+ Matcher matcher = REPOSITORY_ID_VALID_EXPRESSION_PATTERN.matcher( repoGroupId );
if ( !matcher.matches( ) )
{
- errors = appendError( errors, "id", INVALID_CHARS, repoGroupId, new String[]{"alphanumeric, '.', '-','_'"} );
+ errors = appendError( errors, "id", INVALID_CHARS, repoGroupId, REPOSITORY_ID_ALLOWED );
}
if ( repositoryGroup.getMergedIndexTTL( ) <= 0 )
errors = appendError( errors, "merged_index_ttl",BELOW_MIN, "0" );
}
+ if (StringUtils.isBlank( repositoryGroup.getName() )) {
+ errors = appendError( errors, "name", ISEMPTY );
+ } else
+ {
+ matcher = REPOSITORY_NAME_VALID_EXPRESSION_PATTERN.matcher( repositoryGroup.getName( ) );
+ if ( !matcher.matches( ) )
+ {
+ errors = appendError( errors, "name", INVALID_CHARS, repoGroupId, REPOSITORY_NAME_ALLOWED );
+ }
+ }
+
+
if ( repositoryRegistry != null && !updateMode )
{
import org.apache.archiva.configuration.IndeterminateConfigurationException;
import org.apache.archiva.configuration.RepositoryGroupConfiguration;
import org.apache.archiva.indexer.merger.MergedRemoteIndexesScheduler;
+import org.apache.archiva.repository.base.AbstractRepositoryHandler;
import org.apache.archiva.repository.base.ArchivaRepositoryRegistry;
import org.apache.archiva.repository.base.ConfigurationHandler;
import org.apache.archiva.repository.validation.CheckedResult;
import org.apache.archiva.repository.event.RepositoryEvent;
import org.apache.archiva.repository.features.IndexCreationFeature;
import org.apache.archiva.repository.storage.StorageAsset;
-import org.apache.archiva.repository.validation.CombinedValidator;
import org.apache.archiva.repository.validation.RepositoryChecker;
import org.apache.archiva.repository.validation.RepositoryValidator;
+import org.apache.archiva.repository.validation.ValidationError;
import org.apache.archiva.repository.validation.ValidationResponse;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
* @author Martin Stockhammer <martin_s@apache.org>
*/
@Service( "repositoryGroupHandler#default" )
-public class RepositoryGroupHandler implements RepositoryHandler<RepositoryGroup, RepositoryGroupConfiguration>
+public class RepositoryGroupHandler
+ extends AbstractRepositoryHandler<RepositoryGroup, RepositoryGroupConfiguration>
+ implements RepositoryHandler<RepositoryGroup, RepositoryGroupConfiguration>
{
private static final Logger log = LoggerFactory.getLogger( RepositoryGroupHandler.class );
* @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
+ * @param repositoryValidatorList the list of validators that are registered
*/
public RepositoryGroupHandler( ArchivaRepositoryRegistry repositoryRegistry,
ConfigurationHandler configurationHandler,
@Named( "mergedRemoteIndexesScheduler#default" ) MergedRemoteIndexesScheduler mergedRemoteIndexesScheduler,
- List<RepositoryValidator<? extends Repository>> repositoryGroupValidatorList
+ List<RepositoryValidator<? extends Repository>> repositoryValidatorList
)
{
this.configurationHandler = configurationHandler;
this.mergedRemoteIndexesScheduler = mergedRemoteIndexesScheduler;
this.repositoryRegistry = repositoryRegistry;
- List<RepositoryValidator<RepositoryGroup>> validatorList = initValidators( repositoryGroupValidatorList );
- this.validator = new CombinedValidator<>( RepositoryGroup.class, validatorList );
- }
-
- private List<RepositoryValidator<RepositoryGroup>> initValidators(List<RepositoryValidator<? extends Repository>> repositoryGroupValidatorList) {
- if (repositoryGroupValidatorList!=null && repositoryGroupValidatorList.size()>0) {
- return repositoryGroupValidatorList.stream( ).filter(
- v -> v.isFlavour( RepositoryGroup.class )
- ).map( v -> v.narrowTo( RepositoryGroup.class ) ).collect( Collectors.toList( ) );
- } else {
- return Collections.emptyList( );
- }
+ this.validator = getCombinedValidatdor( RepositoryGroup.class, repositoryValidatorList );
}
@Override
this.repositoryRegistry.registerGroupHandler( this );
}
+ @Override
public void initializeFromConfig( )
{
this.repositoryGroups.clear( );
this.repositoryGroups.putAll( newInstancesFromConfig( ) );
for ( RepositoryGroup group : this.repositoryGroups.values( ) )
{
- initializeGroup( group );
+ initialize( group );
}
}
this.groupsDirectory = baseDir;
}
- private void initializeGroup( RepositoryGroup repositoryGroup )
+ @Override
+ public void initialize( RepositoryGroup repositoryGroup )
{
StorageAsset indexDirectory = getMergedIndexDirectory( repositoryGroup );
if ( !indexDirectory.exists( ) )
}
configuration.addRepositoryGroup( newCfg );
configurationHandler.save( configuration, ConfigurationHandler.REGISTRY_EVENT_TAG );
- initializeGroup( repositoryGroup );
+ initialize( repositoryGroup );
}
finally
{
}
configurationHandler.save( configuration, ConfigurationHandler.REGISTRY_EVENT_TAG );
updateReferences( currentRepository, repositoryGroupConfiguration );
- initializeGroup( currentRepository );
+ initialize( currentRepository );
this.repositoryGroups.put( id, currentRepository );
}
catch ( IndeterminateConfigurationException | RegistryException | RepositoryException e )
log.error( "Fatal error, config save during rollback failed: {}", e.getMessage( ), e );
}
updateReferences( oldRepository, oldCfg );
- initializeGroup( oldRepository );
+ initialize( oldRepository );
}
log.error( "Could not save the configuration for repository group {}: {}", id, e.getMessage( ), e );
if (e instanceof RepositoryException) {
@Override
public void updateReferences( RepositoryGroup repo, RepositoryGroupConfiguration repositoryConfiguration ) throws RepositoryException
{
- if ( repo instanceof EditableRepositoryGroup )
+ if ( repo instanceof EditableRepositoryGroup && repositoryConfiguration!=null)
{
EditableRepositoryGroup eGroup = (EditableRepositoryGroup) repo;
eGroup.setRepositories( repositoryConfiguration.getRepositories( ).stream( )
}
@Override
- public ValidationResponse<RepositoryGroup> validateRepository( RepositoryGroup repository )
+ public CheckedResult<RepositoryGroup, Map<String, List<ValidationError>>> validateRepository( RepositoryGroup repository )
{
- return null;
+ return this.validator.apply( repository );
+
}
@Override
- public ValidationResponse<RepositoryGroup> validateRepositoryForUpdate( RepositoryGroup repository )
+ public CheckedResult<RepositoryGroup,Map<String, List<ValidationError>>> validateRepositoryForUpdate( RepositoryGroup repository )
{
- return null;
+ return this.validator.applyForUpdate( repository );
}
-
@Override
public boolean has( String id )
{
{
Map<String, List<ValidationError>> errors = null;
if (managedRepository==null) {
- errors = appendError( errors, "id", ISNULL );
+ errors = appendError( errors, "object", ISNULL );
+ return new ValidationResponse<>( managedRepository, errors );
}
final String repoId = managedRepository.getId( );
if ( StringUtils.isBlank( repoId ) ) {
if ( !REPOSITORY_ID_VALID_EXPRESSION_PATTERN.matcher( repoId ).matches( ) )
{
- errors = appendError( errors, "id", INVALID_CHARS, repoId, new String[]{"alphanumeric", "_", ".", "-"} );
+ errors = appendError( errors, "id", INVALID_CHARS, repoId, REPOSITORY_ID_ALLOWED );
}
if ( StringUtils.isBlank( managedRepository.getName() ) )
{
if ( !REPOSITORY_NAME_VALID_EXPRESSION_PATTERN.matcher( managedRepository.getName() ).matches( ) )
{
- errors = appendError( errors, "name", INVALID_CHARS, managedRepository.getName( ), new String[]{"alphanumeric", "whitespace", "/", "(", ")", "_", ".", "-"} );
+ errors = appendError( errors, "name", INVALID_CHARS, managedRepository.getName( ), REPOSITORY_NAME_ALLOWED );
}
String cronExpression = managedRepository.getSchedulingDefinition( );
import org.apache.archiva.configuration.Configuration;
import org.apache.archiva.configuration.ManagedRepositoryConfiguration;
-import org.apache.archiva.repository.base.ArchivaRepositoryRegistry;
-import org.apache.archiva.repository.base.ConfigurationHandler;
-import org.apache.archiva.repository.validation.CheckedResult;
import org.apache.archiva.repository.ManagedRepository;
+import org.apache.archiva.repository.Repository;
import org.apache.archiva.repository.RepositoryException;
import org.apache.archiva.repository.RepositoryHandler;
import org.apache.archiva.repository.RepositoryType;
+import org.apache.archiva.repository.base.AbstractRepositoryHandler;
+import org.apache.archiva.repository.base.ArchivaRepositoryRegistry;
+import org.apache.archiva.repository.base.ConfigurationHandler;
+import org.apache.archiva.repository.features.StagingRepositoryFeature;
+import org.apache.archiva.repository.validation.CheckedResult;
import org.apache.archiva.repository.validation.RepositoryChecker;
import org.apache.archiva.repository.validation.RepositoryValidator;
import org.apache.archiva.repository.validation.ValidationResponse;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
-import javax.inject.Named;
import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
import java.util.Map;
+import java.util.Set;
+import java.util.stream.Collectors;
/**
* Handler implementation for managed repositories.
* @author Martin Stockhammer <martin_s@apache.org>
*/
public class ManagedRepositoryHandler
+ extends AbstractRepositoryHandler<ManagedRepository, ManagedRepositoryConfiguration>
implements RepositoryHandler<ManagedRepository, ManagedRepositoryConfiguration>
{
+ private static final Logger log = LoggerFactory.getLogger( ManagedRepositoryHandler.class );
+ private final ConfigurationHandler configurationHandler;
+ private final ArchivaRepositoryRegistry repositoryRegistry;
+ private final RepositoryValidator<ManagedRepository> validator;
+ private Map<String, ManagedRepository> managedRepositories = new HashMap<>( );
+ private Map<String, ManagedRepository> uManagedRepositories = Collections.unmodifiableMap( managedRepositories );
+
public ManagedRepositoryHandler( ArchivaRepositoryRegistry repositoryRegistry,
ConfigurationHandler configurationHandler,
- @Named( "repositoryValidator#common#managed") RepositoryValidator<ManagedRepository> managedRepositoryValidator )
+ List<RepositoryValidator<? extends Repository>> repositoryValidatorList )
+ {
+ this.configurationHandler = configurationHandler;
+ this.repositoryRegistry = repositoryRegistry;
+ this.validator = getCombinedValidatdor( ManagedRepository.class, repositoryValidatorList );
+ }
+
+ @Override
+ public void initializeFromConfig( )
{
+ this.managedRepositories.clear( );
+ this.managedRepositories.putAll( newInstancesFromConfig( ) );
+ for ( ManagedRepository managedRepository : this.managedRepositories.values( ) )
+ {
+ initialize( managedRepository );
+ }
+
+ }
+
+ @Override
+ public void initialize( ManagedRepository repository )
+ {
+
}
@Override
public Map<String, ManagedRepository> newInstancesFromConfig( )
{
- return null;
+ try
+ {
+ Set<String> configRepoIds = new HashSet<>( );
+ List<ManagedRepositoryConfiguration> managedRepoConfigs =
+ configurationHandler.getBaseConfiguration( ).getManagedRepositories( );
+
+ if ( managedRepoConfigs == null )
+ {
+ return managedRepositories;
+ }
+
+ for ( ManagedRepositoryConfiguration repoConfig : managedRepoConfigs )
+ {
+ ManagedRepository repo = put( repoConfig, null );
+ configRepoIds.add( repoConfig.getId( ) );
+ if ( repo.supportsFeature( StagingRepositoryFeature.class ) )
+ {
+ StagingRepositoryFeature stagF = repo.getFeature( StagingRepositoryFeature.class ).get( );
+ if ( stagF.getStagingRepository( ) != null )
+ {
+ configRepoIds.add( stagF.getStagingRepository( ).getId( ) );
+ }
+ }
+ }
+ List<String> toRemove = managedRepositories.keySet( ).stream( ).filter( id -> !configRepoIds.contains( id ) ).collect( Collectors.toList( ) );
+ for ( String id : toRemove )
+ {
+ ManagedRepository removed = managedRepositories.remove( id );
+ removed.close( );
+ }
+ }
+ catch ( Throwable e )
+ {
+ log.error( "Could not initialize repositories from config: {}", e.getMessage( ), e );
+ return managedRepositories;
+ }
+ return managedRepositories;
}
@Override
+++ /dev/null
-package org.apache.archiva.repository.base.group;
-
-/*
- * 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.junit.jupiter.api.Test;
-
-/**
- * @author Martin Stockhammer <martin_s@apache.org>
- */
-class BasicManagedRepositoryValidatorTest
-{
-
- @Test
- void apply( )
- {
- }
-
- @Test
- void applyForUpdate( )
- {
- }
-
- @Test
- void getFlavour( )
- {
- }
-
- @Test
- void isFlavour( )
- {
- }
-}
\ No newline at end of file
--- /dev/null
+package org.apache.archiva.repository.base.group;
+
+/*
+ * 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.common.filelock.DefaultFileLockManager;
+import org.apache.archiva.common.filelock.FileLockManager;
+import org.apache.archiva.repository.EditableManagedRepository;
+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.RepositoryRegistry;
+import org.apache.archiva.repository.base.ConfigurationHandler;
+import org.apache.archiva.repository.base.managed.BasicManagedRepository;
+import org.apache.archiva.repository.base.managed.BasicManagedRepositoryValidator;
+import org.apache.archiva.repository.mock.ManagedRepositoryContentMock;
+import org.apache.archiva.repository.storage.fs.FilesystemStorage;
+import org.apache.archiva.repository.validation.ValidationResponse;
+import org.junit.jupiter.api.AfterEach;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.springframework.test.context.ContextConfiguration;
+import org.springframework.test.context.junit.jupiter.SpringExtension;
+
+import javax.inject.Inject;
+import java.io.IOException;
+import java.net.URISyntaxException;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+
+import static org.junit.jupiter.api.Assertions.*;
+
+/**
+ * @author Martin Stockhammer <martin_s@apache.org>
+ */
+@ExtendWith( SpringExtension.class)
+@ContextConfiguration(locations = { "classpath*:/META-INF/spring-context.xml", "classpath:/spring-context.xml" })
+class BasicRepositoryGroupValidatorTest
+{
+
+ @Inject
+ ConfigurationHandler configurationHandler;
+
+ @Inject
+ RepositoryRegistry repositoryRegistry;
+
+ @SuppressWarnings( "unused" )
+ @Inject
+ RepositoryGroupHandler repositoryGroupHandler;
+
+ Path repoBaseDir;
+
+ @AfterEach
+ void cleanup() throws RepositoryException
+ {
+ repositoryRegistry.removeRepository("test");
+ }
+
+ protected EditableManagedRepository createRepository( String id, String name, Path location ) throws IOException
+ {
+ BasicManagedRepository repo = BasicManagedRepository.newFilesystemInstance(id, name, location);
+ repo.setLocation( location.toAbsolutePath().toUri());
+ repo.setContent(new ManagedRepositoryContentMock());
+ return repo;
+ }
+
+ protected EditableRepositoryGroup createGroup(String id, String name) throws IOException
+ {
+ return BasicRepositoryGroup.newFilesystemInstance( id, name, getRepoBaseDir( ).resolve( id ) );
+ }
+
+ private Path getRepoBaseDir() {
+ if (repoBaseDir==null) {
+ try
+ {
+ repoBaseDir = Paths.get(Thread.currentThread( ).getContextClassLoader( ).getResource( "repositories" ).toURI());
+ }
+ catch ( URISyntaxException e )
+ {
+ throw new RuntimeException( "Could not retrieve repository base directory" );
+ }
+ }
+ return repoBaseDir;
+ }
+
+ @Test
+ void apply( ) throws IOException
+ {
+ BasicRepositoryGroupValidator validator = new BasicRepositoryGroupValidator( configurationHandler );
+ EditableRepositoryGroup group = createGroup( "test", "test" );
+ group.setMergedIndexTTL( 360 );
+ ValidationResponse<RepositoryGroup> result = validator.apply( group );
+ assertNotNull( result );
+ assertTrue( result.isValid( ) );
+ }
+
+ @Test
+ void applyWithExisting( ) throws IOException, RepositoryException
+ {
+ BasicRepositoryGroupValidator validator = new BasicRepositoryGroupValidator( configurationHandler );
+ validator.setRepositoryRegistry( repositoryRegistry );
+ EditableRepositoryGroup group = createGroup( "test", "test" );
+ group.setMergedIndexTTL( 360 );
+ repositoryRegistry.putRepositoryGroup( group );
+ EditableRepositoryGroup group2 = createGroup( "test", "test2" );
+ group2.setMergedIndexTTL( 360 );
+ ValidationResponse<RepositoryGroup> result = validator.apply( group2 );
+ assertNotNull( result );
+ assertFalse( result.isValid( ) );
+ assertEquals( "group_exists", result.getResult( ).get( "id" ).get( 0 ).getType( ) );
+ }
+
+ @Test
+ void applyWithBadTTL( ) throws IOException
+ {
+ BasicRepositoryGroupValidator validator = new BasicRepositoryGroupValidator( configurationHandler );
+ EditableRepositoryGroup group = createGroup( "test", "test" );
+ group.setMergedIndexTTL( 0 );
+ ValidationResponse<RepositoryGroup> result = validator.apply( group );
+ assertNotNull( result );
+ assertFalse( result.isValid( ) );
+ assertTrue( result.getResult( ).containsKey( "merged_index_ttl" ) );
+ assertEquals( "repository_group", result.getResult( ).get( "merged_index_ttl" ).get( 0 ).getCategory( ) );
+ assertEquals( "min", result.getResult( ).get( "merged_index_ttl" ).get( 0 ).getType( ) );
+ assertEquals( "merged_index_ttl", result.getResult( ).get( "merged_index_ttl" ).get( 0 ).getAttribute() );
+ }
+
+ @Test
+ void applyWithNullObject( ) throws IOException
+ {
+ BasicRepositoryGroupValidator validator = new BasicRepositoryGroupValidator( configurationHandler );
+ EditableRepositoryGroup group = createGroup( "", "test" );
+ group.setMergedIndexTTL( 0 );
+ ValidationResponse<RepositoryGroup> result = validator.apply( null );
+ assertNotNull( result );
+ assertFalse( result.isValid( ) );
+ assertTrue( result.getResult( ).containsKey( "object" ) );
+ assertEquals( "repository_group", result.getResult( ).get( "object" ).get( 0 ).getCategory( ) );
+ assertEquals( "isnull", result.getResult( ).get( "object" ).get( 0 ).getType( ) );
+ assertEquals( "object", result.getResult( ).get( "object" ).get( 0 ).getAttribute() );
+ }
+
+ @Test
+ void applyWithEmptyId( ) throws IOException
+ {
+ BasicRepositoryGroupValidator validator = new BasicRepositoryGroupValidator( configurationHandler );
+ EditableRepositoryGroup group = createGroup( "", "test" );
+ group.setMergedIndexTTL( 0 );
+ ValidationResponse<RepositoryGroup> result = validator.apply( group );
+ assertNotNull( result );
+ assertFalse( result.isValid( ) );
+ assertTrue( result.getResult( ).containsKey( "id" ) );
+ assertEquals( "repository_group", result.getResult( ).get( "id" ).get( 0 ).getCategory( ) );
+ assertEquals( "empty", result.getResult( ).get( "id" ).get( 0 ).getType( ) );
+ assertEquals( "id", result.getResult( ).get( "id" ).get( 0 ).getAttribute() );
+ }
+
+ @Test
+ void applyWithBadName( ) throws IOException
+ {
+ BasicRepositoryGroupValidator validator = new BasicRepositoryGroupValidator( configurationHandler );
+ validator.setRepositoryRegistry( repositoryRegistry );
+ EditableRepositoryGroup group = createGroup( "test", "badtest\\name" );
+ group.setMergedIndexTTL( 360);
+ ValidationResponse<RepositoryGroup> result = validator.apply( group );
+ assertFalse( result.isValid( ) );
+ assertEquals( 1, result.getResult( ).size( ) );
+ assertEquals( "invalid_chars", result.getResult( ).get( "name" ).get( 0 ).getType( ) );
+ }
+
+ @Test
+ void getFlavour( )
+ {
+ BasicRepositoryGroupValidator validator = new BasicRepositoryGroupValidator( configurationHandler );
+ assertEquals( RepositoryGroup.class, validator.getFlavour( ) );
+ }
+
+ @Test
+ void isFlavour() {
+ BasicRepositoryGroupValidator validator = new BasicRepositoryGroupValidator( configurationHandler );
+ assertTrue( validator.isFlavour( RepositoryGroup.class ) );
+ assertFalse( validator.isFlavour( ManagedRepository.class ) );
+ assertTrue( validator.isFlavour( BasicRepositoryGroup.class ) );
+ }
+}
\ No newline at end of file
--- /dev/null
+package org.apache.archiva.repository.base.group;
+
+/*
+ * 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.junit.jupiter.api.Test;
+
+import static org.junit.jupiter.api.Assertions.*;
+
+/**
+ * @author Martin Stockhammer <martin_s@apache.org>
+ */
+class RepositoryGroupHandlerTest
+{
+
+ @Test
+ void init( )
+ {
+ }
+
+ @Test
+ void initializeFromConfig( )
+ {
+ }
+
+ @Test
+ void initialize( )
+ {
+ }
+
+ @Test
+ void newInstancesFromConfig( )
+ {
+ }
+
+ @Test
+ void newInstance( )
+ {
+ }
+
+ @Test
+ void testNewInstance( )
+ {
+ }
+
+ @Test
+ void put( )
+ {
+ }
+
+ @Test
+ void testPut( )
+ {
+ }
+
+ @Test
+ void testPut1( )
+ {
+ }
+
+ @Test
+ void putWithCheck( )
+ {
+ }
+
+ @Test
+ void remove( )
+ {
+ }
+
+ @Test
+ void testRemove( )
+ {
+ }
+
+ @Test
+ void get( )
+ {
+ }
+
+ @Test
+ void testClone( )
+ {
+ }
+
+ @Test
+ void updateReferences( )
+ {
+ }
+
+ @Test
+ void getAll( )
+ {
+ }
+
+ @Test
+ void getValidator( )
+ {
+ }
+
+ @Test
+ void validateRepository( )
+ {
+ }
+
+ @Test
+ void validateRepositoryForUpdate( )
+ {
+ }
+
+ @Test
+ void has( )
+ {
+ }
+
+ @Test
+ void close( )
+ {
+ }
+}
\ No newline at end of file
--- /dev/null
+package org.apache.archiva.repository.base.managed;
+
+/*
+ * 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.common.filelock.DefaultFileLockManager;
+import org.apache.archiva.common.filelock.FileLockManager;
+import org.apache.archiva.configuration.ArchivaConfiguration;
+import org.apache.archiva.repository.EditableManagedRepository;
+import org.apache.archiva.repository.ManagedRepository;
+import org.apache.archiva.repository.RepositoryException;
+import org.apache.archiva.repository.RepositoryRegistry;
+import org.apache.archiva.repository.base.ConfigurationHandler;
+import org.apache.archiva.repository.base.group.RepositoryGroupHandler;
+import org.apache.archiva.repository.mock.ManagedRepositoryContentMock;
+import org.apache.archiva.repository.storage.fs.FilesystemStorage;
+import org.apache.archiva.repository.validation.ValidationResponse;
+import org.junit.jupiter.api.AfterEach;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.springframework.test.context.ContextConfiguration;
+import org.springframework.test.context.junit.jupiter.SpringExtension;
+
+import javax.inject.Inject;
+import java.io.IOException;
+import java.net.URISyntaxException;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+
+import static org.junit.jupiter.api.Assertions.*;
+
+/**
+ * @author Martin Stockhammer <martin_s@apache.org>
+ */
+@ExtendWith( SpringExtension.class)
+@ContextConfiguration(locations = { "classpath*:/META-INF/spring-context.xml", "classpath:/spring-context.xml" })
+class BasicManagedRepositoryValidatorTest
+{
+
+ @Inject
+ ConfigurationHandler configurationHandler;
+
+ @Inject
+ RepositoryRegistry repositoryRegistry;
+
+ @SuppressWarnings( "unused" )
+ @Inject
+ RepositoryGroupHandler repositoryGroupHandler;
+
+ Path repoBaseDir;
+
+ @AfterEach
+ void cleanup() {
+ try
+ {
+ repositoryRegistry.removeRepository( "test" );
+ }
+ catch ( RepositoryException e )
+ {
+ // Ignore this
+ }
+
+ }
+
+ protected EditableManagedRepository createRepository( String id, String name, Path location ) throws IOException
+ {
+ FileLockManager lockManager = new DefaultFileLockManager();
+ FilesystemStorage storage = new FilesystemStorage(location.toAbsolutePath(), lockManager);
+ BasicManagedRepository repo = new BasicManagedRepository(id, name, storage);
+ repo.setLocation( location.toAbsolutePath().toUri());
+ repo.setContent(new ManagedRepositoryContentMock());
+ return repo;
+ }
+
+ private Path getRepoBaseDir() {
+ if (repoBaseDir==null) {
+ try
+ {
+ repoBaseDir = Paths.get(Thread.currentThread( ).getContextClassLoader( ).getResource( "repositories" ).toURI());
+ }
+ catch ( URISyntaxException e )
+ {
+ throw new RuntimeException( "Could not retrieve repository base directory" );
+ }
+ }
+ return repoBaseDir;
+ }
+
+
+ @Test
+ void apply( ) throws IOException
+ {
+ BasicManagedRepositoryValidator validator = new BasicManagedRepositoryValidator( configurationHandler );
+ validator.setRepositoryRegistry( repositoryRegistry );
+ Path repoDir = getRepoBaseDir().resolve("test" );
+ EditableManagedRepository repo = createRepository( "test", "test", repoDir );
+ ValidationResponse<ManagedRepository> result = validator.apply( repo );
+ assertTrue( result.isValid( ) );
+ }
+
+ @Test
+ void applyWithExistingRepo( ) throws IOException, RepositoryException
+ {
+ BasicManagedRepositoryValidator validator = new BasicManagedRepositoryValidator( configurationHandler );
+ validator.setRepositoryRegistry( repositoryRegistry );
+ Path repoDir = getRepoBaseDir().resolve("test" );
+ EditableManagedRepository repo = createRepository( "test", "test", repoDir );
+ Path repoDir2 = getRepoBaseDir().resolve("test2" );
+ EditableManagedRepository repo2 = createRepository( "test", "test", repoDir2 );
+ repositoryRegistry.putRepository( repo );
+ ValidationResponse<ManagedRepository> result = validator.apply( repo );
+ assertFalse( result.isValid( ) );
+ assertEquals( 1, result.getResult( ).size( ) );
+ assertTrue( result.getResult( ).containsKey( "id" ) );
+ assertEquals( "managed_repository", result.getResult( ).get( "id" ).get( 0 ).getCategory( ) );
+ assertEquals( "managed_repo_exists", result.getResult( ).get( "id" ).get( 0 ).getType( ) );
+ assertEquals( "id", result.getResult( ).get( "id" ).get( 0 ).getAttribute() );
+ }
+
+ @Test
+ void applyUpdateWithExistingRepo( ) throws IOException, RepositoryException
+ {
+ BasicManagedRepositoryValidator validator = new BasicManagedRepositoryValidator( configurationHandler );
+ validator.setRepositoryRegistry( repositoryRegistry );
+ Path repoDir = getRepoBaseDir().resolve("test" );
+ EditableManagedRepository repo = createRepository( "test", "test", repoDir );
+ Path repoDir2 = getRepoBaseDir().resolve("test2" );
+ EditableManagedRepository repo2 = createRepository( "test", "test", repoDir2 );
+ repositoryRegistry.putRepository( repo );
+ ValidationResponse<ManagedRepository> result = validator.applyForUpdate( repo );
+ assertTrue( result.isValid( ) );
+ assertEquals( 0, result.getResult( ).size( ) );
+ }
+
+ @Test
+ void applyWithNullObject( ) throws IOException
+ {
+ BasicManagedRepositoryValidator validator = new BasicManagedRepositoryValidator( configurationHandler );
+ validator.setRepositoryRegistry( repositoryRegistry );
+ ValidationResponse<ManagedRepository> result = validator.apply( null );
+ assertFalse( result.isValid( ) );
+ assertEquals( 1, result.getResult( ).size( ) );
+ assertTrue( result.getResult( ).containsKey( "object" ) );
+ assertEquals( "managed_repository", result.getResult( ).get( "object" ).get( 0 ).getCategory( ) );
+ assertEquals( "isnull", result.getResult( ).get( "object" ).get( 0 ).getType( ) );
+ assertEquals( "object", result.getResult( ).get( "object" ).get( 0 ).getAttribute() );
+ }
+
+ @Test
+ void applyWithEmptyId( ) throws IOException
+ {
+ BasicManagedRepositoryValidator validator = new BasicManagedRepositoryValidator( configurationHandler );
+ validator.setRepositoryRegistry( repositoryRegistry );
+ Path repoDir = getRepoBaseDir().resolve("test" );
+ EditableManagedRepository repo = createRepository( "", "test", repoDir );
+ ValidationResponse<ManagedRepository> result = validator.apply( repo );
+ assertFalse( result.isValid( ) );
+ assertEquals( 1, result.getResult( ).size( ) );
+ assertTrue( result.getResult( ).containsKey( "id" ) );
+ assertEquals( "managed_repository", result.getResult( ).get( "id" ).get( 0 ).getCategory( ) );
+ assertEquals( "empty", result.getResult( ).get( "id" ).get( 0 ).getType( ) );
+ assertEquals( "id", result.getResult( ).get( "id" ).get( 0 ).getAttribute() );
+ }
+
+ @Test
+ void applyWithBadName( ) throws IOException
+ {
+ BasicManagedRepositoryValidator validator = new BasicManagedRepositoryValidator( configurationHandler );
+ validator.setRepositoryRegistry( repositoryRegistry );
+ Path repoDir = getRepoBaseDir().resolve("test" );
+ EditableManagedRepository repo = createRepository( "test", "badtest\\name", repoDir );
+ ValidationResponse<ManagedRepository> result = validator.apply( repo );
+ assertFalse( result.isValid( ) );
+ assertEquals( 1, result.getResult( ).size( ) );
+ assertEquals( "invalid_chars", result.getResult( ).get( "name" ).get( 0 ).getType( ) );
+ }
+
+ @Test
+ void applyWithBadSchedulingExpression( ) throws IOException
+ {
+ BasicManagedRepositoryValidator validator = new BasicManagedRepositoryValidator( configurationHandler );
+ validator.setRepositoryRegistry( repositoryRegistry );
+ Path repoDir = getRepoBaseDir().resolve("test" );
+ EditableManagedRepository repo = createRepository( "test", "test", repoDir );
+ repo.setSchedulingDefinition( "xxxxx" );
+ ValidationResponse<ManagedRepository> result = validator.apply( repo );
+ assertFalse( result.isValid( ) );
+ assertEquals( 1, result.getResult( ).size( ) );
+ assertEquals( "invalid_scheduling_exp", result.getResult( ).get( "scheduling_definition" ).get( 0 ).getType( ) );
+ }
+
+ @Test
+ void applyForUpdate( )
+ {
+ }
+
+ @Test
+ void getFlavour( )
+ {
+ BasicManagedRepositoryValidator validator = new BasicManagedRepositoryValidator( configurationHandler );
+ validator.setRepositoryRegistry( repositoryRegistry );
+ assertEquals( ManagedRepository.class, validator.getFlavour( ) );
+ }
+
+ @Test
+ void isFlavour( )
+ {
+ BasicManagedRepositoryValidator validator = new BasicManagedRepositoryValidator( configurationHandler );
+ validator.setRepositoryRegistry( repositoryRegistry );
+ assertTrue( validator.isFlavour( ManagedRepository.class ) );
+ assertTrue( validator.isFlavour( BasicManagedRepository.class ) );
+ }
+}
\ No newline at end of file
{
private static final long serialVersionUID = -7319687481737616081L;
private String id;
+ private String name;
private List<String> repositories = new ArrayList<>( );
private String location;
MergeConfiguration mergeConfiguration;
MergeConfiguration mergeConfig = new MergeConfiguration( );
result.setMergeConfiguration( mergeConfig );
result.setId( modelObj.getId() );
+ result.setName( modelObj.getName() );
result.setLocation( modelObj.getLocation().toString() );
result.setRepositories( modelObj.getRepositories().stream().map( Repository::getId ).collect( Collectors.toList()) );
if (modelObj.supportsFeature( IndexCreationFeature.class )) {
this.location = location;
}
+ @Schema(description = "The name of the repository group")
+ public String getName( )
+ {
+ return name;
+ }
+
+ public void setName( String name )
+ {
+ this.name = name;
+ }
+
@Override
public boolean equals( Object o )
{
RepositoryGroup that = (RepositoryGroup) o;
- if ( !Objects.equals( id, that.id ) ) return false;
- if ( !repositories.equals( that.repositories ) )
- return false;
- if ( !Objects.equals( location, that.location ) ) return false;
- return Objects.equals( mergeConfiguration, that.mergeConfiguration );
+ return id.equals( that.id );
}
@Override
public int hashCode( )
{
- int result = id != null ? id.hashCode( ) : 0;
- result = 31 * result + repositories.hashCode( );
- result = 31 * result + ( location != null ? location.hashCode( ) : 0 );
- result = 31 * result + ( mergeConfiguration != null ? mergeConfiguration.hashCode( ) : 0 );
- return result;
+ return id.hashCode( );
}
- @SuppressWarnings( "StringBufferReplaceableByString" )
@Override
public String toString( )
{
final StringBuilder sb = new StringBuilder( "RepositoryGroup{" );
sb.append( "id='" ).append( id ).append( '\'' );
+ sb.append( ", name='" ).append( name ).append( '\'' );
sb.append( ", repositories=" ).append( repositories );
sb.append( ", location='" ).append( location ).append( '\'' );
sb.append( ", mergeConfiguration=" ).append( mergeConfiguration );
import org.apache.archiva.components.rest.model.PagedResult;
import org.apache.archiva.components.rest.util.QueryHelper;
import org.apache.archiva.configuration.RepositoryGroupConfiguration;
-import org.apache.archiva.repository.validation.CheckedResult;
import org.apache.archiva.repository.EditableRepositoryGroup;
import org.apache.archiva.repository.RepositoryException;
import org.apache.archiva.repository.RepositoryRegistry;
import org.apache.archiva.repository.base.ConfigurationHandler;
+import org.apache.archiva.repository.validation.CheckedResult;
import org.apache.archiva.repository.validation.ValidationError;
import org.apache.archiva.rest.api.model.v2.MergeConfiguration;
import org.apache.archiva.rest.api.model.v2.RepositoryGroup;
* @see RepositoryGroupService
* @since 3.0
*/
-@Service("v2.repositoryGroupService#rest")
+@Service( "v2.repositoryGroupService#rest" )
public class DefaultRepositoryGroupService implements RepositoryGroupService
{
private final ConfigurationHandler configurationHandler;
final private RepositoryRegistry repositoryRegistry;
-
private static final Logger log = LoggerFactory.getLogger( DefaultRepositoryGroupService.class );
private static final QueryHelper<org.apache.archiva.repository.RepositoryGroup> QUERY_HELPER = new QueryHelper<>( new String[]{"id"} );
+
static
{
QUERY_HELPER.addStringFilter( "id", org.apache.archiva.repository.RepositoryGroup::getId );
}
- public DefaultRepositoryGroupService( RepositoryRegistry repositoryRegistry, ConfigurationHandler configurationHandler ) {
+ public DefaultRepositoryGroupService( RepositoryRegistry repositoryRegistry, ConfigurationHandler configurationHandler )
+ {
this.repositoryRegistry = repositoryRegistry;
this.configurationHandler = configurationHandler;
}
{
RepositoryGroupConfiguration result = new RepositoryGroupConfiguration( );
result.setId( group.getId( ) );
+ result.setName( group.getName() );
result.setLocation( group.getLocation( ) );
result.setRepositories( group.getRepositories( ) );
MergeConfiguration mergeConfig = group.getMergeConfiguration( );
- if (mergeConfig!=null)
+ if ( mergeConfig != null )
{
result.setMergedIndexPath( mergeConfig.getMergedIndexPath( ) );
result.setMergedIndexTtl( mergeConfig.getMergedIndexTtlMinutes( ) );
public RepositoryGroup addRepositoryGroup( RepositoryGroup repositoryGroup ) throws ArchivaRestServiceException
{
final String groupId = repositoryGroup.getId( );
- if ( StringUtils.isEmpty( groupId ) ) {
+ if ( StringUtils.isEmpty( groupId ) )
+ {
throw new ArchivaRestServiceException( ErrorMessage.of( ErrorKeys.REPOSITORY_INVALID_ID, groupId ), 422 );
}
- if (repositoryRegistry.hasRepositoryGroup( groupId )) {
+ if ( repositoryRegistry.hasRepositoryGroup( groupId ) )
+ {
httpServletResponse.setHeader( "Location", uriInfo.getAbsolutePathBuilder( ).path( groupId ).build( ).toString( ) );
throw new ArchivaRestServiceException( ErrorMessage.of( ErrorKeys.REPOSITORY_ID_EXISTS, groupId ), 303 );
}
RepositoryGroupConfiguration configuration = toConfig( repositoryGroup );
CheckedResult<org.apache.archiva.repository.RepositoryGroup, Map<String, List<ValidationError>>> validationResult = repositoryRegistry.putRepositoryGroupAndValidate( configuration );
- if ( validationResult.isValid( ) )
- {
- httpServletResponse.setStatus( 201 );
- return RepositoryGroup.of( validationResult.getRepository() );
- } else {
- throw ValidationException.of( validationResult.getResult() );
- }
+ if ( validationResult.isValid( ) )
+ {
+ httpServletResponse.setStatus( 201 );
+ return RepositoryGroup.of( validationResult.getRepository( ) );
+ }
+ else
+ {
+ throw ValidationException.of( validationResult.getResult( ) );
+ }
}
catch ( RepositoryException e )
{
try
{
RepositoryGroupConfiguration configuration = toConfig( repositoryGroup );
- CheckedResult<org.apache.archiva.repository.RepositoryGroup, Map<String, List<ValidationError>>> validationResult = repositoryRegistry.putRepositoryGroupAndValidate( configuration );
- if ( validationResult.isValid( ) )
- {
- httpServletResponse.setStatus( 201 );
- return RepositoryGroup.of( validationResult.getRepository() );
- } else {
- throw ValidationException.of( validationResult.getResult() );
- }
+ CheckedResult<org.apache.archiva.repository.RepositoryGroup, Map<String, List<ValidationError>>> validationResult = repositoryRegistry.putRepositoryGroupAndValidate( configuration );
+ if ( validationResult.isValid( ) )
+ {
+ httpServletResponse.setStatus( 201 );
+ return RepositoryGroup.of( validationResult.getRepository( ) );
+ }
+ else
+ {
+ throw ValidationException.of( validationResult.getResult( ) );
+ }
}
catch ( RepositoryException e )
{
log.error( "Exception during repository group update: {}", e.getMessage( ), e );
- throw new ArchivaRestServiceException( ErrorMessage.of( ErrorKeys.REPOSITORY_GROUP_UPDATE_FAILED, e.getMessage() ) );
+ throw new ArchivaRestServiceException( ErrorMessage.of( ErrorKeys.REPOSITORY_GROUP_UPDATE_FAILED, e.getMessage( ) ) );
}
}
try
{
org.apache.archiva.repository.RepositoryGroup group = repositoryRegistry.getRepositoryGroup( repositoryGroupId );
- if (group==null) {
+ if ( group == null )
+ {
throw new ArchivaRestServiceException( ErrorMessage.of( ErrorKeys.REPOSITORY_GROUP_NOT_FOUND, "" ), 404 );
}
repositoryRegistry.removeRepositoryGroup( group );
try
{
org.apache.archiva.repository.RepositoryGroup repositoryGroup = repositoryRegistry.getRepositoryGroup( repositoryGroupId );
- if (repositoryGroup==null) {
+ if ( repositoryGroup == null )
+ {
throw new ArchivaRestServiceException( ErrorMessage.of( ErrorKeys.REPOSITORY_GROUP_NOT_FOUND, "" ), 404 );
}
- if (!(repositoryGroup instanceof EditableRepositoryGroup )) {
+ if ( !( repositoryGroup instanceof EditableRepositoryGroup ) )
+ {
log.error( "This group instance is not editable: {}", repositoryGroupId );
throw new ArchivaRestServiceException( ErrorMessage.of( ErrorKeys.REPOSITORY_GROUP_UPDATE_FAILED, "" ), 500 );
}
EditableRepositoryGroup editableRepositoryGroup = (EditableRepositoryGroup) repositoryGroup;
- if ( editableRepositoryGroup.getRepositories().stream().anyMatch( repo -> repositoryId.equals(repo.getId())) )
+ if ( editableRepositoryGroup.getRepositories( ).stream( ).anyMatch( repo -> repositoryId.equals( repo.getId( ) ) ) )
{
log.info( "Repository {} is already member of group {}", repositoryId, repositoryGroupId );
return RepositoryGroup.of( editableRepositoryGroup );
}
- org.apache.archiva.repository.ManagedRepository managedRepo = repositoryRegistry.getManagedRepository(repositoryId);
- if (managedRepo==null) {
+ org.apache.archiva.repository.ManagedRepository managedRepo = repositoryRegistry.getManagedRepository( repositoryId );
+ if ( managedRepo == null )
+ {
throw new ArchivaRestServiceException( ErrorMessage.of( ErrorKeys.REPOSITORY_NOT_FOUND, "" ), 404 );
}
editableRepositoryGroup.addRepository( managedRepo );
}
catch ( RepositoryException e )
{
- throw new ArchivaRestServiceException( ErrorMessage.of( ErrorKeys.REPOSITORY_GROUP_UPDATE_FAILED, e.getMessage() ), 500 );
+ throw new ArchivaRestServiceException( ErrorMessage.of( ErrorKeys.REPOSITORY_GROUP_UPDATE_FAILED, e.getMessage( ) ), 500 );
}
}
try
{
org.apache.archiva.repository.RepositoryGroup repositoryGroup = repositoryRegistry.getRepositoryGroup( repositoryGroupId );
- if (repositoryGroup==null) {
+ if ( repositoryGroup == null )
+ {
throw new ArchivaRestServiceException( ErrorMessage.of( ErrorKeys.REPOSITORY_GROUP_NOT_FOUND, "" ), 404 );
}
- if (repositoryGroup.getRepositories().stream().noneMatch( r -> repositoryId.equals( r.getId() ) )) {
+ if ( repositoryGroup.getRepositories( ).stream( ).noneMatch( r -> repositoryId.equals( r.getId( ) ) ) )
+ {
throw new ArchivaRestServiceException( ErrorMessage.of( ErrorKeys.REPOSITORY_NOT_FOUND, repositoryId ), 404 );
}
- if (!(repositoryGroup instanceof EditableRepositoryGroup)) {
+ if ( !( repositoryGroup instanceof EditableRepositoryGroup ) )
+ {
log.error( "This group instance is not editable: {}", repositoryGroupId );
throw new ArchivaRestServiceException( ErrorMessage.of( ErrorKeys.REPOSITORY_GROUP_UPDATE_FAILED, "" ), 500 );
}
}
catch ( RepositoryException e )
{
- throw new ArchivaRestServiceException( ErrorMessage.of( ErrorKeys.REPOSITORY_GROUP_UPDATE_FAILED, e.getMessage() ), 500 );
+ throw new ArchivaRestServiceException( ErrorMessage.of( ErrorKeys.REPOSITORY_GROUP_UPDATE_FAILED, e.getMessage( ) ), 500 );
}
}
{
Map<String, Object> jsonAsMap = new HashMap<>( );
jsonAsMap.put( "id", "group_001" );
+ jsonAsMap.put( "name", "group_001" );
Response response = given( ).spec( getRequestSpec( token ) ).contentType( JSON )
.when( )
.body( jsonAsMap )
.post( "" )
- .prettyPeek()
.then( ).statusCode( 201 ).extract( ).response( );
assertNotNull( response );
RepositoryGroup result = response.getBody( ).jsonPath( ).getObject( "", RepositoryGroup.class );
{
Map<String, Object> jsonAsMap = new HashMap<>( );
jsonAsMap.put( "id", "group_001" );
+ jsonAsMap.put( "name", "group_001" );
Response response = given( ).spec( getRequestSpec( token ) ).contentType( JSON )
.when( )
.body( jsonAsMap )
.post( "" )
+ .prettyPeek()
.then( ).statusCode( 201 ).extract( ).response( );
assertNotNull( response );
response = given( ).spec( getRequestSpec( token ) ).contentType( JSON )
{
given( ).spec( getRequestSpec( token ) ).contentType( JSON )
.when( )
- .delete( "group_001" )
- .then( ).statusCode( 200 );
+ .delete( "group_001" );
}
}
groups.add( groupName );
Map<String, Object> jsonAsMap = new HashMap<>( );
jsonAsMap.put( "id", groupName );
+ jsonAsMap.put( "name", groupName );
Response response = given( ).spec( getRequestSpec( token ) ).contentType( JSON )
.when( )
.body( jsonAsMap )
{
given( ).spec( getRequestSpec( token ) ).contentType( JSON )
.when( )
- .delete( groupName )
- .then( ).statusCode( 200 );
+ .delete( groupName );
}
}
}
groups.add( groupName );
Map<String, Object> jsonAsMap = new HashMap<>( );
jsonAsMap.put( "id", groupName );
+ jsonAsMap.put( "name", groupName );
Response response = given( ).spec( getRequestSpec( token ) ).contentType( JSON )
.when( )
.body( jsonAsMap )
{
given( ).spec( getRequestSpec( token ) ).contentType( JSON )
.when( )
- .delete( groupName )
- .then( ).statusCode( 200 );
+ .delete( groupName );
}
}
}
{
Map<String, Object> jsonAsMap = new HashMap<>( );
jsonAsMap.put( "id", "group_001" );
+ jsonAsMap.put( "name", "group_001" );
Response response = given( ).spec( getRequestSpec( token ) ).contentType( JSON )
.when( )
.body( jsonAsMap )
{
given( ).spec( getRequestSpec( token ) ).contentType( JSON )
.when( )
- .delete( "group_001" )
- .then( ).statusCode( 200 );
+ .delete( "group_001" );
}
}
{
Map<String, Object> jsonAsMap = new HashMap<>( );
jsonAsMap.put( "id", "group_001" );
+ jsonAsMap.put( "name", "group_001" );
Response response = given( ).spec( getRequestSpec( token ) ).contentType( JSON )
.when( )
.body( jsonAsMap )
{
Map<String, Object> jsonAsMap = new HashMap<>( );
jsonAsMap.put( "id", "group_001" );
+ jsonAsMap.put( "name", "group_001" );
jsonAsMap.put( "repositories", Arrays.asList( "internal" ) );
Response response = given( ).spec( getRequestSpec( token ) ).contentType( JSON )
.when( )
{
Map<String, Object> jsonAsMap = new HashMap<>( );
jsonAsMap.put( "id", "group_001" );
+ jsonAsMap.put( "name", "group_001" );
jsonAsMap.put( "repositories", Arrays.asList( "internal" ) );
Response response = given( ).spec( getRequestSpec( token ) ).contentType( JSON )
.when( )
{
given( ).spec( getRequestSpec( token ) ).contentType( JSON )
.when( )
- .delete( "group_001" )
- .then( ).statusCode( 200 );
+ .delete( "group_001" );
}
}