diff options
5 files changed, 243 insertions, 53 deletions
diff --git a/archiva-modules/archiva-base/archiva-plexus-bridge/src/main/java/org/apache/archiva/common/plexusbridge/MavenIndexerUtils.java b/archiva-modules/archiva-base/archiva-plexus-bridge/src/main/java/org/apache/archiva/common/plexusbridge/MavenIndexerUtils.java index 2deae9d1f..8dd948c43 100644 --- a/archiva-modules/archiva-base/archiva-plexus-bridge/src/main/java/org/apache/archiva/common/plexusbridge/MavenIndexerUtils.java +++ b/archiva-modules/archiva-base/archiva-plexus-bridge/src/main/java/org/apache/archiva/common/plexusbridge/MavenIndexerUtils.java @@ -24,7 +24,7 @@ import org.apache.maven.index.creator.JarFileContentsIndexCreator; import org.apache.maven.index.creator.MavenArchetypeArtifactInfoIndexCreator; import org.apache.maven.index.creator.MavenPluginArtifactInfoIndexCreator; import org.apache.maven.index.creator.MinimalArtifactInfoIndexCreator; -import org.apache.maven.index.creator.OSGIArtifactIndexCreator; +import org.apache.maven.index.creator.OsgiArtifactIndexCreator; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.stereotype.Service; @@ -59,7 +59,7 @@ public class MavenIndexerUtils log.warn( "using lookupList from sisu plexus failed so build indexCreator manually" ); allIndexCreators = - Arrays.asList( plexusSisuBridge.lookup( IndexCreator.class, OSGIArtifactIndexCreator.ID ), + Arrays.asList( plexusSisuBridge.lookup( IndexCreator.class, OsgiArtifactIndexCreator.ID ), plexusSisuBridge.lookup( IndexCreator.class, MavenArchetypeArtifactInfoIndexCreator.ID ), plexusSisuBridge.lookup( IndexCreator.class, MinimalArtifactInfoIndexCreator.ID ), plexusSisuBridge.lookup( IndexCreator.class, JarFileContentsIndexCreator.ID ), diff --git a/archiva-modules/archiva-web/archiva-rest/archiva-rest-api/src/main/java/org/apache/archiva/rest/api/services/RepositoriesService.java b/archiva-modules/archiva-web/archiva-rest/archiva-rest-api/src/main/java/org/apache/archiva/rest/api/services/RepositoriesService.java index c48ec945b..182fcf0f5 100644 --- a/archiva-modules/archiva-web/archiva-rest/archiva-rest-api/src/main/java/org/apache/archiva/rest/api/services/RepositoriesService.java +++ b/archiva-modules/archiva-web/archiva-rest/archiva-rest-api/src/main/java/org/apache/archiva/rest/api/services/RepositoriesService.java @@ -70,6 +70,14 @@ public interface RepositoriesService throws Exception; + @Path( "updateManagedRepository" ) + @POST + @Consumes( { MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML } ) + @Produces( { MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML, MediaType.TEXT_PLAIN } ) + @RedbackAuthorization( permission = ArchivaRoleConstants.OPERATION_MANAGE_CONFIGURATION ) + Boolean updateManagedRepository( ManagedRepository managedRepository ) + throws Exception; + @Path( "getRemoteRepositories" ) @GET @Produces( { MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML, MediaType.TEXT_PLAIN } ) diff --git a/archiva-modules/archiva-web/archiva-rest/archiva-rest-services/pom.xml b/archiva-modules/archiva-web/archiva-rest/archiva-rest-services/pom.xml index 8103ec42e..c48ec6a2f 100644 --- a/archiva-modules/archiva-web/archiva-rest/archiva-rest-services/pom.xml +++ b/archiva-modules/archiva-web/archiva-rest/archiva-rest-services/pom.xml @@ -39,6 +39,10 @@ </dependency> <dependency> <groupId>org.apache.archiva</groupId> + <artifactId>audit</artifactId> + </dependency> + <dependency> + <groupId>org.apache.archiva</groupId> <artifactId>archiva-scheduler-repository</artifactId> </dependency> <dependency> diff --git a/archiva-modules/archiva-web/archiva-rest/archiva-rest-services/src/main/java/org.apache.archiva.rest.services/DefaultRepositoriesService.java b/archiva-modules/archiva-web/archiva-rest/archiva-rest-services/src/main/java/org.apache.archiva.rest.services/DefaultRepositoriesService.java index 4f9b55986..09afde1a7 100644 --- a/archiva-modules/archiva-web/archiva-rest/archiva-rest-services/src/main/java/org.apache.archiva.rest.services/DefaultRepositoriesService.java +++ b/archiva-modules/archiva-web/archiva-rest/archiva-rest-services/src/main/java/org.apache.archiva.rest.services/DefaultRepositoriesService.java @@ -1,6 +1,9 @@ package org.apache.archiva.rest.services; +import org.apache.archiva.audit.AuditEvent; +import org.apache.archiva.audit.AuditListener; import org.apache.archiva.metadata.repository.MetadataRepository; +import org.apache.archiva.metadata.repository.MetadataRepositoryException; import org.apache.archiva.metadata.repository.RepositorySession; import org.apache.archiva.metadata.repository.RepositorySessionFactory; import org.apache.archiva.metadata.repository.stats.RepositoryStatisticsManager; @@ -18,11 +21,15 @@ import org.apache.maven.archiva.configuration.IndeterminateConfigurationExceptio import org.apache.maven.archiva.configuration.ManagedRepositoryConfiguration; import org.apache.maven.archiva.configuration.ProxyConnectorConfiguration; import org.apache.maven.archiva.configuration.RemoteRepositoryConfiguration; +import org.apache.maven.archiva.security.ArchivaRoleConstants; +import org.codehaus.plexus.redback.role.RoleManager; +import org.codehaus.plexus.redback.role.RoleManagerException; +import org.codehaus.plexus.redback.users.User; import org.codehaus.plexus.registry.Registry; import org.codehaus.plexus.registry.RegistryException; import org.codehaus.plexus.taskqueue.TaskQueueException; import org.codehaus.redback.components.scheduler.CronExpressionValidator; -import org.codehaus.redback.components.scheduler.Scheduler; +import org.codehaus.redback.rest.services.RedbackAuthenticationThreadLocal; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.stereotype.Service; @@ -54,6 +61,12 @@ public class DefaultRepositoriesService private static final String REPOSITORY_LOCATION_VALID_EXPRESSION = "^[-a-zA-Z0-9._/~:?!&=\\\\]+$"; + // TODO move this field to an abstract class + @Inject + private List<AuditListener> auditListeners = new ArrayList<AuditListener>(); + + @Inject + protected RoleManager roleManager; @Inject protected ArchivaConfiguration archivaConfiguration; @@ -144,6 +157,7 @@ public class DefaultRepositoriesService throw new Exception( "Error saving configuration for delete action" + e.getMessage() ); } + // TODO could be async ? as directory can be huge File dir = new File( repository.getLocation() ); if ( !FileUtils.deleteQuietly( dir ) ) { @@ -193,60 +207,21 @@ public class DefaultRepositoriesService return remoteRepos; } - public Boolean scanRepository( String repositoryId, boolean fullScan ) - { - if ( repositoryTaskScheduler.isProcessingRepositoryTask( repositoryId ) ) - { - log.info( "scanning of repository with id {} already scheduled" ); - } - RepositoryTask task = new RepositoryTask(); - task.setRepositoryId( repositoryId ); - task.setScanAll( fullScan ); - try - { - repositoryTaskScheduler.queueTask( task ); - } - catch ( TaskQueueException e ) - { - log.error( "failed to schedule scanning of repo with id {}", repositoryId, e ); - return false; - } - return true; - } - - public Boolean alreadyScanning( String repositoryId ) - { - return repositoryTaskScheduler.isProcessingRepositoryTask( repositoryId ); - } - - public Boolean removeScanningTaskFromQueue( @PathParam( "repositoryId" ) String repositoryId ) - { - RepositoryTask task = new RepositoryTask(); - task.setRepositoryId( repositoryId ); - try - { - return repositoryTaskScheduler.unQueueTask( task ); - } - catch ( TaskQueueException e ) - { - log.error( "failed to unschedule scanning of repo with id {}", repositoryId, e ); - return false; - } - } - public Boolean addManagedRepository( ManagedRepository managedRepository ) throws Exception { - return addManagedRepository( managedRepository.getId(), managedRepository.getLayout(), - managedRepository.getName(), managedRepository.getUrl(), - managedRepository.isBlockRedeployments(), managedRepository.isReleases(), - managedRepository.isSnapshots(), managedRepository.isStageRepoNeeded(), - managedRepository.getCronExpression() ); + return + addManagedRepository( managedRepository.getId(), managedRepository.getLayout(), managedRepository.getName(), + managedRepository.getUrl(), managedRepository.isBlockRedeployments(), + managedRepository.isReleases(), managedRepository.isSnapshots(), + managedRepository.isStageRepoNeeded(), managedRepository.getCronExpression() ) + != null; } - private Boolean addManagedRepository( String repoId, String layout, String name, String location, - boolean blockRedeployments, boolean releasesIncluded, - boolean snapshotsIncluded, boolean stageRepoNeeded, String cronExpression ) + private ManagedRepositoryConfiguration addManagedRepository( String repoId, String layout, String name, + String location, boolean blockRedeployments, + boolean releasesIncluded, boolean snapshotsIncluded, + boolean stageRepoNeeded, String cronExpression ) throws Exception { @@ -335,7 +310,145 @@ public class DefaultRepositoriesService e.getMessage() ).toString(), e ); } - return Boolean.TRUE; + return repository; + } + + public Boolean updateManagedRepository( ManagedRepository repository ) + throws Exception + { + // Ensure that the fields are valid. + Configuration configuration = archivaConfiguration.getConfiguration(); + + ManagedRepositoryConfiguration toremove = configuration.findManagedRepositoryById( repository.getId() ); + + if ( toremove != null ) + { + configuration.removeManagedRepository( toremove ); + } + // FIXME the case of the attached staging repository + /* + if ( stagingRepository != null ) + { + removeRepository( stagingRepository.getId(), configuration ); + }*/ + + // Save the repository configuration. + String result; + RepositorySession repositorySession = repositorySessionFactory.createSession(); + ManagedRepositoryConfiguration managedRepositoryConfiguration = + addManagedRepository( repository.getId(), repository.getLayout(), repository.getName(), repository.getUrl(), + repository.isBlockRedeployments(), repository.isReleases(), repository.isSnapshots(), + repository.isStageRepoNeeded(), repository.getCronExpression() ); + + // FIXME only location has changed from previous + boolean resetStats = true; + + try + { + triggerAuditEvent( repository.getId(), null, AuditEvent.MODIFY_MANAGED_REPO ); + addRepositoryRoles( managedRepositoryConfiguration ); + + // FIXME this staging part !! + + //update changes of the staging repo + /*if ( stageNeeded ) + { + + stagingRepository = getStageRepoConfig( configuration ); + addRepository( stagingRepository, configuration ); + addRepositoryRoles( stagingRepository ); + + }*/ + //delete staging repo when we dont need it + /* + if ( !stageNeeded ) + { + stagingRepository = getStageRepoConfig( configuration ); + removeRepository( stagingRepository.getId(), configuration ); + removeContents( stagingRepository ); + removeRepositoryRoles( stagingRepository ); + }*/ + + saveConfiguration( this.archivaConfiguration.getConfiguration() ); + if ( resetStats ) + { + repositoryStatisticsManager.deleteStatistics( repositorySession.getRepository(), repository.getId() ); + repositorySession.save(); + } + + //MRM-1342 Repository statistics report doesn't appear to be working correctly + //scan repository when modification of repository is successful + // olamy : IMHO we are fine to ignore issue with scheduling scanning + // as here the repo has been updated + scanRepository( repository.getId(), true ); + // FIXME staging !! + /* + if ( stageNeeded ) + { + executeRepositoryScanner( stagingRepository.getId() ); + }*/ + + } + catch ( IOException e ) + { + throw e; + } + catch ( RoleManagerException e ) + { + throw e; + } + catch ( MetadataRepositoryException e ) + { + throw e; + } + finally + { + repositorySession.close(); + } + + return true; + } + + + public Boolean scanRepository( String repositoryId, boolean fullScan ) + { + if ( repositoryTaskScheduler.isProcessingRepositoryTask( repositoryId ) ) + { + log.info( "scanning of repository with id {} already scheduled" ); + } + RepositoryTask task = new RepositoryTask(); + task.setRepositoryId( repositoryId ); + task.setScanAll( fullScan ); + try + { + repositoryTaskScheduler.queueTask( task ); + } + catch ( TaskQueueException e ) + { + log.error( "failed to schedule scanning of repo with id {}", repositoryId, e ); + return false; + } + return true; + } + + public Boolean alreadyScanning( String repositoryId ) + { + return repositoryTaskScheduler.isProcessingRepositoryTask( repositoryId ); + } + + public Boolean removeScanningTaskFromQueue( @PathParam( "repositoryId" ) String repositoryId ) + { + RepositoryTask task = new RepositoryTask(); + task.setRepositoryId( repositoryId ); + try + { + return repositoryTaskScheduler.unQueueTask( task ); + } + catch ( TaskQueueException e ) + { + log.error( "failed to unschedule scanning of repo with id {}", repositoryId, e ); + return false; + } } //----------------------------------------------- @@ -344,6 +457,43 @@ public class DefaultRepositoriesService // olamt move those in common utility classes //----------------------------------------------- + protected void triggerAuditEvent( String repositoryId, String resource, String action ) + { + User user = RedbackAuthenticationThreadLocal.get(); + if ( user == null ) + { + log.warn( "no user found in Redback ThreadLocal" ); + AuditEvent event = + new AuditEvent( repositoryId, user == null ? "null" : user.getUsername(), resource, action ); + // FIXME use a thread local through cxf interceptors to store this + //event.setRemoteIP( getRemoteAddr() ); + + for ( AuditListener listener : auditListeners ) + { + listener.auditEvent( event ); + } + } + } + + protected void addRepositoryRoles( ManagedRepositoryConfiguration newRepository ) + throws RoleManagerException + { + String repoId = newRepository.getId(); + + // TODO: double check these are configured on start up + // TODO: belongs in the business logic + + if ( !roleManager.templatedRoleExists( ArchivaRoleConstants.TEMPLATE_REPOSITORY_OBSERVER, repoId ) ) + { + roleManager.createTemplatedRole( ArchivaRoleConstants.TEMPLATE_REPOSITORY_OBSERVER, repoId ); + } + + if ( !roleManager.templatedRoleExists( ArchivaRoleConstants.TEMPLATE_REPOSITORY_MANAGER, repoId ) ) + { + roleManager.createTemplatedRole( ArchivaRoleConstants.TEMPLATE_REPOSITORY_MANAGER, repoId ); + } + } + public Boolean executeRepositoryScanner( String repoId ) throws Exception { diff --git a/archiva-modules/archiva-web/archiva-rest/archiva-rest-services/src/test/java/org/apache/archiva/rest/services/RepositoriesServiceTest.java b/archiva-modules/archiva-web/archiva-rest/archiva-rest-services/src/test/java/org/apache/archiva/rest/services/RepositoriesServiceTest.java index 14350b669..6664c615c 100644 --- a/archiva-modules/archiva-web/archiva-rest/archiva-rest-services/src/test/java/org/apache/archiva/rest/services/RepositoriesServiceTest.java +++ b/archiva-modules/archiva-web/archiva-rest/archiva-rest-services/src/test/java/org/apache/archiva/rest/services/RepositoriesServiceTest.java @@ -123,6 +123,34 @@ public class RepositoriesServiceTest assertNotNull( service.getManagedRepository( repo.getId() ) ); } + @Test + public void updateManagedRepo() + throws Exception + { + RepositoriesService service = getRepositoriesService(); + WebClient.client( service ).header( "Authorization", authorizationHeader ); + WebClient.getConfig( service ).getHttpConduit().getClient().setReceiveTimeout( 300000 ); + ManagedRepository repo = getTestManagedRepository(); + if ( service.getManagedRepository( repo.getId() ) != null ) + { + service.deleteManagedRepository( repo.getId() ); + assertNull( service.getManagedRepository( repo.getId() ) ); + } + service.addManagedRepository( repo ); + repo = service.getManagedRepository( repo.getId() ); + assertNotNull( repo ); + assertEquals( "foo", repo.getName() ); + // toto is foo in French :-) + repo.setName( "toto" ); + + service.updateManagedRepository( repo ); + + repo = service.getManagedRepository( repo.getId() ); + assertNotNull( repo ); + assertEquals( "toto", repo.getName() ); + + } + private ManagedRepository getTestManagedRepository() { |