diff options
author | Martin Stockhammer <martin.stockhammer@ars.de> | 2018-03-24 17:41:50 +0100 |
---|---|---|
committer | Martin Stockhammer <martin.stockhammer@ars.de> | 2018-03-24 17:44:13 +0100 |
commit | c544376afbec84689eae8ca5cc1a8f6a0ddb768d (patch) | |
tree | dfa67aabe758715dad9684e1909f6c6f649ee2b0 /archiva-modules/archiva-base | |
parent | e2eb9fe940feaa1606489c894182f2923bd54458 (diff) | |
download | archiva-c544376afbec84689eae8ca5cc1a8f6a0ddb768d.tar.gz archiva-c544376afbec84689eae8ca5cc1a8f6a0ddb768d.zip |
Switching repository admin and dependent classes to RepositoryRegistry
RepositoryRegistry is used for indexing context now. There is still more work to do
to move the maven dependent parts into its own projects and update the dependencies.
Diffstat (limited to 'archiva-modules/archiva-base')
53 files changed, 2058 insertions, 526 deletions
diff --git a/archiva-modules/archiva-base/archiva-configuration/src/main/java/org/apache/archiva/configuration/DefaultArchivaConfiguration.java b/archiva-modules/archiva-base/archiva-configuration/src/main/java/org/apache/archiva/configuration/DefaultArchivaConfiguration.java index 71b4c3103..caedee308 100644 --- a/archiva-modules/archiva-base/archiva-configuration/src/main/java/org/apache/archiva/configuration/DefaultArchivaConfiguration.java +++ b/archiva-modules/archiva-base/archiva-configuration/src/main/java/org/apache/archiva/configuration/DefaultArchivaConfiguration.java @@ -644,6 +644,7 @@ public class DefaultArchivaConfiguration this.configuration = unescapeExpressions( configuration ); + isConfigurationDefaulted=false; triggerEvent( ConfigurationEvent.SAVED ); } diff --git a/archiva-modules/archiva-base/archiva-consumers/archiva-consumer-archetype/src/main/resources/archetype-resources/src/test/java/RepositoryProviderMock.java b/archiva-modules/archiva-base/archiva-consumers/archiva-consumer-archetype/src/main/resources/archetype-resources/src/test/java/RepositoryProviderMock.java index a140842a2..ec13f21f0 100644 --- a/archiva-modules/archiva-base/archiva-consumers/archiva-consumer-archetype/src/main/resources/archetype-resources/src/test/java/RepositoryProviderMock.java +++ b/archiva-modules/archiva-base/archiva-consumers/archiva-consumer-archetype/src/main/resources/archetype-resources/src/test/java/RepositoryProviderMock.java @@ -230,4 +230,8 @@ public class RepositoryProviderMock implements RepositoryProvider return configuration; } + @Override + public <T> void raise(org.apache.archiva.repository.RepositoryEvent<T> event) { + + } } diff --git a/archiva-modules/archiva-base/archiva-consumers/archiva-consumer-archetype/src/main/resourcesstatic/archetype-resources/pom.xml b/archiva-modules/archiva-base/archiva-consumers/archiva-consumer-archetype/src/main/resourcesstatic/archetype-resources/pom.xml index bb98a2d45..2217e8ead 100644 --- a/archiva-modules/archiva-base/archiva-consumers/archiva-consumer-archetype/src/main/resourcesstatic/archetype-resources/pom.xml +++ b/archiva-modules/archiva-base/archiva-consumers/archiva-consumer-archetype/src/main/resourcesstatic/archetype-resources/pom.xml @@ -79,6 +79,12 @@ <scope>test</scope> </dependency> <dependency> + <groupId>org.apache.archiva</groupId> + <artifactId>archiva-maven2-indexer</artifactId> + <version>${archiva.version}</version> + <scope>test</scope> + </dependency> + <dependency> <groupId>org.apache.archiva.redback.components.registry</groupId> <artifactId>spring-registry-api</artifactId> <version>${redback.registry.version}</version> diff --git a/archiva-modules/archiva-base/archiva-consumers/archiva-core-consumers/pom.xml b/archiva-modules/archiva-base/archiva-consumers/archiva-core-consumers/pom.xml index c01a30b57..3bfca1107 100644 --- a/archiva-modules/archiva-base/archiva-consumers/archiva-core-consumers/pom.xml +++ b/archiva-modules/archiva-base/archiva-consumers/archiva-core-consumers/pom.xml @@ -155,6 +155,11 @@ <artifactId>archiva-mock</artifactId> <scope>test</scope> </dependency> + <dependency> + <groupId>org.apache.archiva</groupId> + <artifactId>archiva-maven2-indexer</artifactId> + <scope>test</scope> + </dependency> </dependencies> <build> <pluginManagement> diff --git a/archiva-modules/archiva-base/archiva-consumers/archiva-core-consumers/src/test/java/org/apache/archiva/consumers/core/repository/AbstractRepositoryPurgeTest.java b/archiva-modules/archiva-base/archiva-consumers/archiva-core-consumers/src/test/java/org/apache/archiva/consumers/core/repository/AbstractRepositoryPurgeTest.java index e9e73530b..345d257fa 100644 --- a/archiva-modules/archiva-base/archiva-consumers/archiva-core-consumers/src/test/java/org/apache/archiva/consumers/core/repository/AbstractRepositoryPurgeTest.java +++ b/archiva-modules/archiva-base/archiva-consumers/archiva-core-consumers/src/test/java/org/apache/archiva/consumers/core/repository/AbstractRepositoryPurgeTest.java @@ -19,7 +19,6 @@ package org.apache.archiva.consumers.core.repository; * under the License. */ -import org.apache.archiva.admin.model.beans.ManagedRepository; import org.apache.archiva.metadata.model.ArtifactMetadata; import org.apache.archiva.metadata.repository.MetadataRepository; import org.apache.archiva.metadata.repository.RepositorySession; @@ -54,7 +53,6 @@ import java.nio.file.Paths; import java.time.Period; import java.util.ArrayList; import java.util.List; -import java.util.Locale; import java.util.stream.Collectors; import static org.junit.Assert.assertFalse; diff --git a/archiva-modules/archiva-base/archiva-consumers/archiva-core-consumers/src/test/java/org/apache/archiva/consumers/core/repository/CleanupReleasedSnapshotsRepositoryPurgeTest.java b/archiva-modules/archiva-base/archiva-consumers/archiva-core-consumers/src/test/java/org/apache/archiva/consumers/core/repository/CleanupReleasedSnapshotsRepositoryPurgeTest.java index a289734d1..1ef4bf9a0 100644 --- a/archiva-modules/archiva-base/archiva-consumers/archiva-core-consumers/src/test/java/org/apache/archiva/consumers/core/repository/CleanupReleasedSnapshotsRepositoryPurgeTest.java +++ b/archiva-modules/archiva-base/archiva-consumers/archiva-core-consumers/src/test/java/org/apache/archiva/consumers/core/repository/CleanupReleasedSnapshotsRepositoryPurgeTest.java @@ -107,7 +107,7 @@ public class CleanupReleasedSnapshotsRepositoryPurgeTest { RepositoryRegistry repositoryRegistry = applicationContext.getBean( RepositoryRegistry.class ); ManagedRepository managedRepository = repositoryRegistry.getManagedRepository( TEST_REPO_ID ); - repositoryRegistry.removeRepository( managedRepository ); + repositoryRegistry.removeRepository( TEST_REPO_ID ); repositoryRegistry.putRepository( getRepoConfiguration( TEST_REPO_ID, TEST_REPO_NAME )); @@ -217,7 +217,7 @@ public class CleanupReleasedSnapshotsRepositoryPurgeTest RepositoryRegistry repositoryRegistry = applicationContext.getBean(RepositoryRegistry.class); ManagedRepository managedRepository = repositoryRegistry.getManagedRepository( TEST_REPO_ID ); - repositoryRegistry.removeRepository( managedRepository ); + repositoryRegistry.removeRepository( TEST_REPO_ID ); repositoryRegistry.putRepository( getRepoConfiguration( TEST_REPO_ID, TEST_REPO_NAME )); @@ -298,7 +298,7 @@ public class CleanupReleasedSnapshotsRepositoryPurgeTest RepositoryRegistry repositoryRegistry = applicationContext.getBean(RepositoryRegistry.class); ManagedRepository managedRepository = repositoryRegistry.getManagedRepository( TEST_REPO_ID ); - repositoryRegistry.removeRepository( managedRepository ); + repositoryRegistry.removeRepository( TEST_REPO_ID ); repositoryRegistry.putRepository( getRepoConfiguration( TEST_REPO_ID, TEST_REPO_NAME )); diff --git a/archiva-modules/archiva-base/archiva-consumers/archiva-core-consumers/src/test/java/org/apache/archiva/repository/mock/RepositoryProviderMock.java b/archiva-modules/archiva-base/archiva-consumers/archiva-core-consumers/src/test/java/org/apache/archiva/repository/mock/RepositoryProviderMock.java index 286dd38e4..4af39c33a 100644 --- a/archiva-modules/archiva-base/archiva-consumers/archiva-core-consumers/src/test/java/org/apache/archiva/repository/mock/RepositoryProviderMock.java +++ b/archiva-modules/archiva-base/archiva-consumers/archiva-core-consumers/src/test/java/org/apache/archiva/repository/mock/RepositoryProviderMock.java @@ -21,18 +21,7 @@ package org.apache.archiva.repository.mock; import org.apache.archiva.configuration.ManagedRepositoryConfiguration; import org.apache.archiva.configuration.RemoteRepositoryConfiguration; -import org.apache.archiva.repository.BasicManagedRepository; -import org.apache.archiva.repository.BasicRemoteRepository; -import org.apache.archiva.repository.EditableManagedRepository; -import org.apache.archiva.repository.EditableRemoteRepository; -import org.apache.archiva.repository.ManagedRepository; -import org.apache.archiva.repository.PasswordCredentials; -import org.apache.archiva.repository.ReleaseScheme; -import org.apache.archiva.repository.RemoteRepository; -import org.apache.archiva.repository.RepositoryCredentials; -import org.apache.archiva.repository.RepositoryException; -import org.apache.archiva.repository.RepositoryProvider; -import org.apache.archiva.repository.RepositoryType; +import org.apache.archiva.repository.*; import org.apache.archiva.repository.features.ArtifactCleanupFeature; import org.apache.archiva.repository.features.IndexCreationFeature; import org.apache.archiva.repository.features.RemoteIndexFeature; @@ -229,4 +218,8 @@ public class RepositoryProviderMock implements RepositoryProvider return configuration; } + @Override + public <T> void raise(RepositoryEvent<T> event) { + + } } diff --git a/archiva-modules/archiva-base/archiva-consumers/archiva-core-consumers/src/test/resources/spring-context-cleanup-released-snapshots.xml b/archiva-modules/archiva-base/archiva-consumers/archiva-core-consumers/src/test/resources/spring-context-cleanup-released-snapshots.xml index 5119c55e9..ddc8bfff8 100644 --- a/archiva-modules/archiva-base/archiva-consumers/archiva-core-consumers/src/test/resources/spring-context-cleanup-released-snapshots.xml +++ b/archiva-modules/archiva-base/archiva-consumers/archiva-core-consumers/src/test/resources/spring-context-cleanup-released-snapshots.xml @@ -32,7 +32,7 @@ </bean> <alias name="archivaConfiguration#cleanup-released-snapshots" alias="archivaConfiguration"/> <alias name="archivaConfiguration#cleanup-released-snapshots" alias="archivaConfiguration#default"/> - <context:component-scan base-package="org.apache.archiva.configuration,org.apache.archiva.repository.content.maven2"/> + <context:component-scan base-package="org.apache.archiva.configuration,org.apache.archiva.repository.content.maven2,org.apache.archiva.indexer.maven"/> <alias name="repositoryContentFactory#cleanup-released-snapshots" alias="repositoryContentFactory#default" /> diff --git a/archiva-modules/archiva-base/archiva-consumers/archiva-lucene-consumers/pom.xml b/archiva-modules/archiva-base/archiva-consumers/archiva-lucene-consumers/pom.xml index 208825140..bb489a215 100644 --- a/archiva-modules/archiva-base/archiva-consumers/archiva-lucene-consumers/pom.xml +++ b/archiva-modules/archiva-base/archiva-consumers/archiva-lucene-consumers/pom.xml @@ -136,6 +136,11 @@ <artifactId>xercesImpl</artifactId> <scope>test</scope> </dependency> + <dependency> + <groupId>org.apache.archiva</groupId> + <artifactId>archiva-maven2-indexer</artifactId> + <scope>test</scope> + </dependency> </dependencies> <build> <plugins> diff --git a/archiva-modules/archiva-base/archiva-consumers/archiva-lucene-consumers/src/main/java/org/apache/archiva/consumers/lucene/NexusIndexerConsumer.java b/archiva-modules/archiva-base/archiva-consumers/archiva-lucene-consumers/src/main/java/org/apache/archiva/consumers/lucene/NexusIndexerConsumer.java index 50dd8c1c4..6cadd2730 100644 --- a/archiva-modules/archiva-base/archiva-consumers/archiva-lucene-consumers/src/main/java/org/apache/archiva/consumers/lucene/NexusIndexerConsumer.java +++ b/archiva-modules/archiva-base/archiva-consumers/archiva-lucene-consumers/src/main/java/org/apache/archiva/consumers/lucene/NexusIndexerConsumer.java @@ -28,11 +28,13 @@ import org.apache.archiva.configuration.FileTypes; import org.apache.archiva.consumers.AbstractMonitoredConsumer; import org.apache.archiva.consumers.ConsumerException; import org.apache.archiva.consumers.KnownRepositoryContentConsumer; +import org.apache.archiva.indexer.UnsupportedBaseContextException; import org.apache.archiva.redback.components.registry.Registry; import org.apache.archiva.redback.components.registry.RegistryListener; import org.apache.archiva.redback.components.taskqueue.TaskQueueException; import org.apache.archiva.repository.ManagedRepository; import org.apache.archiva.repository.RepositoryRegistry; +import org.apache.archiva.repository.RepositoryType; import org.apache.archiva.scheduler.ArchivaTaskScheduler; import org.apache.archiva.scheduler.indexing.ArtifactIndexingTask; import org.apache.maven.index.NexusIndexer; @@ -124,11 +126,14 @@ public class NexusIndexerConsumer try { log.info( "Creating indexing context for repo : {}", repository.getId() ); - indexingContext = managedRepositoryAdmin.createIndexContext( repository ); - } - catch ( RepositoryAdminException e ) - { - throw new ConsumerException( e.getMessage(), e ); + if (repository.getType()== RepositoryType.MAVEN) { + indexingContext = repository.getIndexingContext().getBaseContext(IndexingContext.class); + } else { + indexingContext= null; + } + } catch (UnsupportedBaseContextException e) { + log.error("Bad repository type. Not nexus indexer compatible."); + throw new ConsumerException("Bad repository type "+repository.getType()); } } @@ -154,7 +159,7 @@ public class NexusIndexerConsumer Path artifactFile = managedRepository.resolve(path); ArtifactIndexingTask task = - new ArtifactIndexingTask( repository, artifactFile, ArtifactIndexingTask.Action.ADD, getIndexingContext() ); + new ArtifactIndexingTask( repository, artifactFile, ArtifactIndexingTask.Action.ADD, repository.getIndexingContext() ); try { log.debug( "Queueing indexing task '{}' to add or update the artifact in the index.", task ); @@ -181,7 +186,7 @@ public class NexusIndexerConsumer // specify in indexing task that this is not a repo scan request! ArtifactIndexingTask task = new ArtifactIndexingTask( repository, artifactFile, ArtifactIndexingTask.Action.ADD, - getIndexingContext(), false ); + repository.getIndexingContext(), false ); // only update index we don't need to scan the full repo here task.setOnlyUpdate( true ); try @@ -199,21 +204,8 @@ public class NexusIndexerConsumer @Override public void completeScan() { - IndexingContext context = this.indexingContext; - if ( context == null ) - { - try - { - context = getIndexingContext(); - } - catch ( ConsumerException e ) - { - log.warn( "failed to get an IndexingContext:{}", e.getMessage() ); - return; - } - } ArtifactIndexingTask task = - new ArtifactIndexingTask( repository, null, ArtifactIndexingTask.Action.FINISH, context ); + new ArtifactIndexingTask( repository, null, ArtifactIndexingTask.Action.FINISH, repository.getIndexingContext()); try { log.debug( "Queueing indexing task '{}' to finish indexing.", task ); @@ -292,11 +284,10 @@ public class NexusIndexerConsumer { try { - indexingContext = managedRepositoryAdmin.createIndexContext( repository ); - } - catch ( RepositoryAdminException e ) - { - throw new ConsumerException( e.getMessage(), e ); + indexingContext = repository.getIndexingContext().getBaseContext(IndexingContext.class); + } catch (UnsupportedBaseContextException e) { + log.error("Bad repository type. Not nexus indexer compatible. "+repository.getType()); + throw new ConsumerException("Bad repository type "+repository.getType()); } } return indexingContext; diff --git a/archiva-modules/archiva-base/archiva-consumers/archiva-lucene-consumers/src/test/java/org/apache/archiva/consumers/lucene/NexusIndexerConsumerTest.java b/archiva-modules/archiva-base/archiva-consumers/archiva-lucene-consumers/src/test/java/org/apache/archiva/consumers/lucene/NexusIndexerConsumerTest.java index e34dc7e12..2efebfb78 100644 --- a/archiva-modules/archiva-base/archiva-consumers/archiva-lucene-consumers/src/test/java/org/apache/archiva/consumers/lucene/NexusIndexerConsumerTest.java +++ b/archiva-modules/archiva-base/archiva-consumers/archiva-lucene-consumers/src/test/java/org/apache/archiva/consumers/lucene/NexusIndexerConsumerTest.java @@ -26,14 +26,13 @@ import org.apache.archiva.configuration.ArchivaConfiguration; import org.apache.archiva.configuration.FileTypes; import org.apache.archiva.redback.components.taskqueue.TaskQueueException; import org.apache.archiva.repository.BasicManagedRepository; -import org.apache.archiva.repository.ManagedRepository; import org.apache.archiva.repository.ReleaseScheme; +import org.apache.archiva.repository.RepositoryRegistry; import org.apache.archiva.scheduler.ArchivaTaskScheduler; import org.apache.archiva.scheduler.indexing.ArtifactIndexingTask; import org.apache.archiva.test.utils.ArchivaSpringJUnit4ClassRunner; import org.apache.maven.index.NexusIndexer; import org.apache.maven.index.context.IndexCreator; -import org.apache.regexp.RE; import org.junit.After; import org.junit.Before; import org.junit.Test; @@ -47,12 +46,7 @@ import java.net.URI; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; -import java.util.Calendar; -import java.util.Date; -import java.util.HashSet; -import java.util.List; -import java.util.Locale; -import java.util.Set; +import java.util.*; /** * NexusIndexerConsumerTest @@ -111,6 +105,9 @@ public class NexusIndexerConsumerTest @Inject private ManagedRepositoryAdmin managedRepositoryAdmin; + @Inject + RepositoryRegistry repositoryRegistry; + @Override @Before @@ -138,6 +135,7 @@ public class NexusIndexerConsumerTest repositoryConfig.setScanned( true ); repositoryConfig.addActiveReleaseScheme( ReleaseScheme.RELEASE ); repositoryConfig.removeActiveReleaseScheme( ReleaseScheme.SNAPSHOT ); + repositoryRegistry.putRepository(repositoryConfig); } @@ -156,6 +154,8 @@ public class NexusIndexerConsumerTest org.apache.archiva.common.utils.FileUtils.deleteDirectory( indexDir ); assertFalse( Files.exists(indexDir) ); + repositoryRegistry.destroy(); + super.tearDown(); } diff --git a/archiva-modules/archiva-base/archiva-consumers/archiva-lucene-consumers/src/test/resources/spring-context.xml b/archiva-modules/archiva-base/archiva-consumers/archiva-lucene-consumers/src/test/resources/spring-context.xml index a89137295..ebf31812a 100644 --- a/archiva-modules/archiva-base/archiva-consumers/archiva-lucene-consumers/src/test/resources/spring-context.xml +++ b/archiva-modules/archiva-base/archiva-consumers/archiva-lucene-consumers/src/test/resources/spring-context.xml @@ -28,7 +28,7 @@ http://www.springframework.org/schema/context/spring-context-3.0.xsd" default-lazy-init="true"> <context:annotation-config/> - <context:component-scan base-package="org.apache.archiva.consumers.lucene.test"/> + <context:component-scan base-package="org.apache.archiva.consumers.lucene.test,org.apache.maven.index"/> <bean name="commons-configuration" class="org.apache.archiva.redback.components.registry.commons.CommonsConfigurationRegistry"> <property name="properties"> diff --git a/archiva-modules/archiva-base/archiva-maven2-indexer/pom.xml b/archiva-modules/archiva-base/archiva-maven2-indexer/pom.xml index e51f82443..2a2e1c4d0 100644 --- a/archiva-modules/archiva-base/archiva-maven2-indexer/pom.xml +++ b/archiva-modules/archiva-base/archiva-maven2-indexer/pom.xml @@ -56,6 +56,11 @@ </dependency> <dependency> + <groupId>org.slf4j</groupId> + <artifactId>slf4j-api</artifactId> + </dependency> + + <dependency> <groupId>org.codehaus.plexus</groupId> <artifactId>plexus-utils</artifactId> </dependency> @@ -142,6 +147,12 @@ <artifactId>archiva-test-utils</artifactId> <version>${project.version}</version> <scope>test</scope> + <exclusions> + <exclusion> + <groupId>org.slf4j</groupId> + <artifactId>slf4j-simple</artifactId> + </exclusion> + </exclusions> </dependency> <dependency> <groupId>org.apache.derby</groupId> @@ -216,6 +227,19 @@ </exclusion> </exclusions> </dependency> + + + <dependency> + <groupId>org.apache.logging.log4j</groupId> + <artifactId>log4j-slf4j-impl</artifactId> + <scope>test</scope> + </dependency> + + <dependency> + <groupId>org.apache.logging.log4j</groupId> + <artifactId>log4j-jcl</artifactId> + <scope>test</scope> + </dependency> </dependencies> <build> diff --git a/archiva-modules/archiva-base/archiva-maven2-indexer/src/main/java/org/apache/archiva/indexer/maven/MavenIndexContext.java b/archiva-modules/archiva-base/archiva-maven2-indexer/src/main/java/org/apache/archiva/indexer/maven/MavenIndexContext.java index 4ee80794d..37f602f79 100644 --- a/archiva-modules/archiva-base/archiva-maven2-indexer/src/main/java/org/apache/archiva/indexer/maven/MavenIndexContext.java +++ b/archiva-modules/archiva-base/archiva-maven2-indexer/src/main/java/org/apache/archiva/indexer/maven/MavenIndexContext.java @@ -26,6 +26,7 @@ import org.apache.maven.index.context.IndexingContext; import java.io.IOException; import java.net.URI; import java.nio.file.Files; +import java.nio.file.NoSuchFileException; import java.sql.Date; import java.time.ZonedDateTime; import java.util.Set; @@ -81,12 +82,20 @@ public class MavenIndexContext implements ArchivaIndexingContext { @Override public void close(boolean deleteFiles) throws IOException { - delegate.close(deleteFiles); + try { + delegate.close(deleteFiles); + } catch (NoSuchFileException e) { + // Ignore missing directory + } } @Override public void close() throws IOException { - delegate.close(false); + try { + delegate.close(false); + } catch (NoSuchFileException e) { + // Ignore missing directory + } } @Override diff --git a/archiva-modules/archiva-base/archiva-maven2-indexer/src/main/java/org/apache/archiva/indexer/maven/MavenIndexManager.java b/archiva-modules/archiva-base/archiva-maven2-indexer/src/main/java/org/apache/archiva/indexer/maven/MavenIndexManager.java index 00e67e42f..51a5f70d7 100644 --- a/archiva-modules/archiva-base/archiva-maven2-indexer/src/main/java/org/apache/archiva/indexer/maven/MavenIndexManager.java +++ b/archiva-modules/archiva-base/archiva-maven2-indexer/src/main/java/org/apache/archiva/indexer/maven/MavenIndexManager.java @@ -22,6 +22,7 @@ package org.apache.archiva.indexer.maven; import org.apache.archiva.admin.model.RepositoryAdminException; import org.apache.archiva.admin.model.beans.NetworkProxy; import org.apache.archiva.admin.model.networkproxy.NetworkProxyAdmin; +import org.apache.archiva.common.utils.FileUtils; import org.apache.archiva.common.utils.PathUtil; import org.apache.archiva.configuration.ArchivaConfiguration; import org.apache.archiva.indexer.ArchivaIndexManager; @@ -32,12 +33,7 @@ import org.apache.archiva.indexer.UnsupportedBaseContextException; import org.apache.archiva.proxy.common.WagonFactory; import org.apache.archiva.proxy.common.WagonFactoryException; import org.apache.archiva.proxy.common.WagonFactoryRequest; -import org.apache.archiva.repository.ManagedRepository; -import org.apache.archiva.repository.PasswordCredentials; -import org.apache.archiva.repository.RemoteRepository; -import org.apache.archiva.repository.Repository; -import org.apache.archiva.repository.RepositoryType; -import org.apache.archiva.repository.UnsupportedRepositoryTypeException; +import org.apache.archiva.repository.*; import org.apache.archiva.repository.features.IndexCreationFeature; import org.apache.archiva.repository.features.RemoteIndexFeature; import org.apache.commons.lang.StringUtils; @@ -425,7 +421,7 @@ public class MavenIndexManager implements ArchivaIndexManager @Override public ArchivaIndexingContext createContext( Repository repository ) throws IndexCreationFailedException { - + log.debug("Creating context for repo {}, type: {}", repository.getId(), repository.getType()); if ( repository.getType( ) != RepositoryType.MAVEN ) { throw new UnsupportedRepositoryTypeException( repository.getType( ) ); @@ -449,44 +445,120 @@ public class MavenIndexManager implements ArchivaIndexManager + ( StringUtils.isNotEmpty( e.getMessage( ) ) ? ": " + e.getMessage( ) : "" ), e ); } MavenIndexContext context = new MavenIndexContext( repository, mvnCtx ); + return context; } - private IndexingContext createRemoteContext( RemoteRepository remoteRepository ) throws IOException + @Override + public ArchivaIndexingContext reset(ArchivaIndexingContext context) throws IndexUpdateFailedException { + ArchivaIndexingContext ctx; + executeUpdateFunction(context, indexingContext -> { + try { + indexingContext.close(true); + } catch (IOException e) { + log.warn("Index close failed"); + } + try { + FileUtils.deleteDirectory(Paths.get(context.getPath())); + } catch (IOException e) { + throw new IndexUpdateFailedException("Could not delete index files"); + } + }); + try { + Repository repo = context.getRepository(); + ctx = createContext(context.getRepository()); + if (repo instanceof EditableRepository) { + ((EditableRepository)repo).setIndexingContext(ctx); + } + } catch (IndexCreationFailedException e) { + throw new IndexUpdateFailedException("Could not create index"); + } + return ctx; + } + + @Override + public ArchivaIndexingContext move(ArchivaIndexingContext context, Repository repo) throws IndexCreationFailedException { + if (context==null) { + return null; + } + if (context.supports(IndexingContext.class)) { + try { + Path newPath = getIndexPath(repo); + IndexingContext ctx = context.getBaseContext(IndexingContext.class); + Path oldPath = ctx.getIndexDirectoryFile().toPath(); + if (oldPath.equals(newPath)) { + // Nothing to do, if path does not change + return context; + } + if (!Files.exists(oldPath)) { + return createContext(repo); + } else if (context.isEmpty()) { + context.close(); + return createContext(repo); + } else { + context.close(false); + Files.move(oldPath, newPath); + return createContext(repo); + } + } catch (IOException e) { + log.error("IOException while moving index directory {}", e.getMessage(), e); + throw new IndexCreationFailedException("Could not recreated the index.", e); + } catch (UnsupportedBaseContextException e) { + throw new IndexCreationFailedException("The given context, is not a maven context."); + } + } else { + throw new IndexCreationFailedException("Bad context type. This is not a maven context."); + } + } + + private Path getIndexPath(Repository repo) throws IOException { + IndexCreationFeature icf = repo.getFeature(IndexCreationFeature.class).get(); + Path repoDir = repo.getLocalPath(); + URI indexDir = icf.getIndexPath(); + Path indexDirectory = null; + if ( ! StringUtils.isEmpty(indexDir.toString( ) ) ) + { + + indexDirectory = PathUtil.getPathFromUri( indexDir ); + // not absolute so create it in repository directory + if ( !indexDirectory.isAbsolute( ) ) + { + indexDirectory = repoDir.resolve( indexDirectory ); + } + } + else + { + indexDirectory = repoDir.resolve( ".index" ); + } + + if ( !Files.exists( indexDirectory ) ) + { + Files.createDirectories( indexDirectory ); + } + return indexDirectory; + } + + private IndexingContext createRemoteContext(RemoteRepository remoteRepository ) throws IOException { Path appServerBase = archivaConfiguration.getAppServerBaseDir( ); String contextKey = "remote-" + remoteRepository.getId( ); + // create remote repository path - Path repoDir = appServerBase.resolve( "data" ).resolve( "remotes" ).resolve( remoteRepository.getId( ) ); + Path repoDir = remoteRepository.getLocalPath(); if ( !Files.exists( repoDir ) ) { Files.createDirectories( repoDir ); } - Path indexDirectory; + Path indexDirectory = null; // is there configured indexDirectory ? if ( remoteRepository.supportsFeature( RemoteIndexFeature.class ) ) { RemoteIndexFeature rif = remoteRepository.getFeature( RemoteIndexFeature.class ).get( ); - indexDirectory = PathUtil.getPathFromUri( rif.getIndexUri( ) ); - if ( !indexDirectory.isAbsolute( ) ) - { - indexDirectory = repoDir.resolve( indexDirectory ); - } - - // if not configured use a default value - if ( indexDirectory == null ) - { - indexDirectory = repoDir.resolve( ".index" ); - } - if ( !Files.exists( indexDirectory ) ) - { - Files.createDirectories( indexDirectory ); - } - + indexDirectory = getIndexPath(remoteRepository); String remoteIndexUrl = calculateIndexRemoteUrl( remoteRepository.getLocation( ), rif ); try { @@ -538,35 +610,11 @@ public class MavenIndexManager implements ArchivaIndexManager } } + Path indexDirectory = null; if ( repository.supportsFeature( IndexCreationFeature.class ) ) { - IndexCreationFeature icf = repository.getFeature( IndexCreationFeature.class ).get( ); - URI indexDir = icf.getIndexPath( ); - //File managedRepository = new File( repository.getLocation() ); - - Path indexDirectory = null; - if ( indexDir != null && !"".equals( indexDir.toString( ) ) ) - { - - indexDirectory = PathUtil.getPathFromUri( indexDir ); - // not absolute so create it in repository directory - if ( !indexDirectory.isAbsolute( ) ) - { - indexDirectory = repositoryDirectory.resolve( indexDirectory ); - } - icf.setIndexPath( indexDirectory.normalize( ).toUri( ) ); - } - else - { - indexDirectory = repositoryDirectory.resolve( ".indexer" ); - icf.setIndexPath( indexDirectory.toUri( ) ); - } - - if ( !Files.exists( indexDirectory ) ) - { - Files.createDirectories( indexDirectory ); - } + indexDirectory = getIndexPath(repository); String indexUrl = repositoryDirectory.toUri( ).toURL( ).toExternalForm( ); try diff --git a/archiva-modules/archiva-base/archiva-maven2-indexer/src/main/java/org/apache/archiva/indexer/maven/search/MavenRepositorySearch.java b/archiva-modules/archiva-base/archiva-maven2-indexer/src/main/java/org/apache/archiva/indexer/maven/search/MavenRepositorySearch.java index 590cdd244..c861a9bf6 100644 --- a/archiva-modules/archiva-base/archiva-maven2-indexer/src/main/java/org/apache/archiva/indexer/maven/search/MavenRepositorySearch.java +++ b/archiva-modules/archiva-base/archiva-maven2-indexer/src/main/java/org/apache/archiva/indexer/maven/search/MavenRepositorySearch.java @@ -20,24 +20,20 @@ package org.apache.archiva.indexer.maven.search; */ import org.apache.archiva.admin.model.RepositoryAdminException; -import org.apache.archiva.admin.model.beans.ManagedRepository; import org.apache.archiva.admin.model.beans.ProxyConnector; -import org.apache.archiva.admin.model.managed.ManagedRepositoryAdmin; import org.apache.archiva.admin.model.proxyconnector.ProxyConnectorAdmin; import org.apache.archiva.common.plexusbridge.PlexusSisuBridgeException; +import org.apache.archiva.indexer.UnsupportedBaseContextException; +import org.apache.archiva.indexer.search.ArtifactInfoFilter; import org.apache.archiva.indexer.search.*; import org.apache.archiva.indexer.util.SearchUtil; import org.apache.archiva.model.ArchivaArtifactModel; -import org.apache.archiva.model.ArtifactReference; +import org.apache.archiva.repository.RemoteRepository; +import org.apache.archiva.repository.Repository; +import org.apache.archiva.repository.RepositoryRegistry; +import org.apache.archiva.repository.RepositoryType; import org.apache.commons.lang.StringUtils; -import org.apache.maven.index.ArtifactInfo; -import org.apache.maven.index.FlatSearchRequest; -import org.apache.maven.index.FlatSearchResponse; -import org.apache.maven.index.MAVEN; -import org.apache.maven.index.NexusIndexer; -import org.apache.maven.index.OSGI; -import org.apache.maven.index.QueryCreator; -import org.apache.maven.index.SearchType; +import org.apache.maven.index.*; import org.apache.maven.index.context.IndexingContext; import org.apache.maven.index.expr.SearchExpression; import org.apache.maven.index.expr.SearchTyped; @@ -52,13 +48,7 @@ import org.springframework.stereotype.Service; import javax.inject.Inject; import java.io.IOException; -import java.util.ArrayList; -import java.util.Collection; -import java.util.Collections; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Set; +import java.util.*; /** * RepositorySearch implementation which uses the Maven Indexer for searching. @@ -69,11 +59,12 @@ public class MavenRepositorySearch { private Logger log = LoggerFactory.getLogger( getClass() ); - private NexusIndexer indexer; + private Indexer indexer; private QueryCreator queryCreator; - private ManagedRepositoryAdmin managedRepositoryAdmin; + + RepositoryRegistry repositoryRegistry; private ProxyConnectorAdmin proxyConnectorAdmin; @@ -83,13 +74,14 @@ public class MavenRepositorySearch } @Inject - public MavenRepositorySearch( NexusIndexer nexusIndexer, ManagedRepositoryAdmin managedRepositoryAdmin, + public MavenRepositorySearch( Indexer nexusIndexer, RepositoryRegistry repositoryRegistry, + ProxyConnectorAdmin proxyConnectorAdmin, QueryCreator queryCreator ) throws PlexusSisuBridgeException { this.indexer = nexusIndexer; this.queryCreator = queryCreator; - this.managedRepositoryAdmin = managedRepositoryAdmin; + this.repositoryRegistry = repositoryRegistry; this.proxyConnectorAdmin = proxyConnectorAdmin; } @@ -335,13 +327,36 @@ public class MavenRepositorySearch } + private IndexingContext getIndexingContext(String id) { + String repoId; + if (StringUtils.startsWith(id, "remote-")) { + repoId = StringUtils.substringAfter(id, "remote-"); + } else { + repoId = id; + } + Repository repo = repositoryRegistry.getRepository(repoId); + if (repo==null) { + return null; + } else { + if (repo.getIndexingContext()!=null) { + try { + return repo.getIndexingContext().getBaseContext(IndexingContext.class); + } catch (UnsupportedBaseContextException e) { + return null; + } + } else { + return null; + } + } + } + private List<IndexingContext> getIndexingContexts( List<String> ids ) { List<IndexingContext> contexts = new ArrayList<>( ids.size() ); for ( String id : ids ) { - IndexingContext context = indexer.getIndexingContexts().get( id ); + IndexingContext context = getIndexingContext(id); if ( context != null ) { contexts.add( context ); @@ -382,20 +397,20 @@ public class MavenRepositorySearch { try { - ManagedRepository repoConfig = managedRepositoryAdmin.getManagedRepository( repo ); + Repository rRepo = repositoryRegistry.getRepository(repo); - if ( repoConfig != null ) + if ( rRepo != null ) { - IndexingContext context = managedRepositoryAdmin.createIndexContext( repoConfig ); - if ( context.isSearchable() ) - { - indexingContextIds.addAll( getRemoteIndexingContextIds( repo ) ); - indexingContextIds.add( context.getId() ); - } - else - { - log.warn( "indexingContext with id {} not searchable", repoConfig.getId() ); + if (rRepo.getType().equals(RepositoryType.MAVEN)) { + assert rRepo.getIndexingContext() != null; + IndexingContext context = rRepo.getIndexingContext().getBaseContext(IndexingContext.class); + if (context.isSearchable()) { + indexingContextIds.addAll(getRemoteIndexingContextIds(repo)); + indexingContextIds.add(context.getId()); + } else { + log.warn("indexingContext with id {} not searchable", rRepo.getId()); + } } } @@ -404,17 +419,14 @@ public class MavenRepositorySearch log.warn( "Repository '{}' not found in configuration.", repo ); } } - catch ( RepositoryAdminException e ) - { - log.warn( "RepositoryAdminException occured while accessing index of repository '{}' : {}", repo, - e.getMessage() ); - continue; - } catch ( RepositorySearchException e ) { log.warn( "RepositorySearchException occured while accessing index of repository '{}' : {}", repo, e.getMessage() ); continue; + } catch (UnsupportedBaseContextException e) { + log.error("Fatal situation: Maven repository without IndexingContext found."); + continue; } } @@ -446,10 +458,16 @@ public class MavenRepositorySearch for ( ProxyConnector proxyConnector : proxyConnectors ) { String remoteId = "remote-" + proxyConnector.getTargetRepoId(); - IndexingContext context = indexer.getIndexingContexts().get( remoteId ); - if ( context != null && context.isSearchable() ) - { - ids.add( remoteId ); + RemoteRepository repo = repositoryRegistry.getRemoteRepository(proxyConnector.getTargetRepoId()); + if (repo.getType()==RepositoryType.MAVEN) { + try { + IndexingContext context = repo.getIndexingContext() != null ? repo.getIndexingContext().getBaseContext(IndexingContext.class) : null; + if (context!=null && context.isSearchable()) { + ids.add(remoteId); + } + } catch (UnsupportedBaseContextException e) { + // Ignore this one + } } } diff --git a/archiva-modules/archiva-base/archiva-maven2-indexer/src/test/java/org/apache/archiva/indexer/maven/MavenIndexManagerTest.java b/archiva-modules/archiva-base/archiva-maven2-indexer/src/test/java/org/apache/archiva/indexer/maven/MavenIndexManagerTest.java index 53cdaad81..32e3b6f2f 100644 --- a/archiva-modules/archiva-base/archiva-maven2-indexer/src/test/java/org/apache/archiva/indexer/maven/MavenIndexManagerTest.java +++ b/archiva-modules/archiva-base/archiva-maven2-indexer/src/test/java/org/apache/archiva/indexer/maven/MavenIndexManagerTest.java @@ -22,6 +22,7 @@ package org.apache.archiva.indexer.maven; import org.apache.archiva.common.utils.FileUtils; import org.apache.archiva.indexer.ArchivaIndexingContext; import org.apache.archiva.indexer.IndexCreationFailedException; +import org.apache.archiva.repository.RepositoryRegistry; import org.apache.archiva.repository.RepositoryType; import org.apache.archiva.repository.features.IndexCreationFeature; import org.apache.archiva.repository.features.RemoteIndexFeature; @@ -58,6 +59,10 @@ import static org.junit.Assert.*; @ContextConfiguration( locations = { "classpath*:/META-INF/spring-context.xml", "classpath:/spring-context.xml" } ) public class MavenIndexManagerTest { + @Inject + RepositoryRegistry repositoryRegistry; + + private Path indexPath; private MavenManagedRepository repository; private ArchivaIndexingContext ctx; @@ -72,6 +77,7 @@ public class MavenIndexManagerTest { @After public void tearDown() { + repositoryRegistry.destroy(); if (ctx!=null) { try { ctx.close(true); diff --git a/archiva-modules/archiva-base/archiva-maven2-indexer/src/test/java/org/apache/archiva/indexer/maven/search/AbstractMavenRepositorySearch.java b/archiva-modules/archiva-base/archiva-maven2-indexer/src/test/java/org/apache/archiva/indexer/maven/search/AbstractMavenRepositorySearch.java index 07fcc09ba..e5171d206 100644 --- a/archiva-modules/archiva-base/archiva-maven2-indexer/src/test/java/org/apache/archiva/indexer/maven/search/AbstractMavenRepositorySearch.java +++ b/archiva-modules/archiva-base/archiva-maven2-indexer/src/test/java/org/apache/archiva/indexer/maven/search/AbstractMavenRepositorySearch.java @@ -28,18 +28,14 @@ import org.apache.archiva.configuration.ArchivaConfiguration; import org.apache.archiva.configuration.Configuration; import org.apache.archiva.configuration.ConfigurationListener; import org.apache.archiva.configuration.ManagedRepositoryConfiguration; -import org.apache.archiva.indexer.maven.search.MavenRepositorySearch; import org.apache.archiva.indexer.search.SearchResultHit; import org.apache.archiva.indexer.search.SearchResults; +import org.apache.archiva.repository.Repository; import org.apache.archiva.repository.RepositoryRegistry; +import org.apache.archiva.repository.features.IndexCreationFeature; import org.apache.archiva.test.utils.ArchivaSpringJUnit4ClassRunner; import org.apache.commons.lang.SystemUtils; -import org.apache.maven.index.ArtifactContext; -import org.apache.maven.index.ArtifactContextProducer; -import org.apache.maven.index.ArtifactScanningListener; -import org.apache.maven.index.NexusIndexer; -import org.apache.maven.index.QueryCreator; -import org.apache.maven.index.ScanningResult; +import org.apache.maven.index.*; import org.apache.maven.index.context.IndexCreator; import org.apache.maven.index.context.IndexingContext; import org.easymock.EasyMock; @@ -87,6 +83,9 @@ public abstract class AbstractMavenRepositorySearch @Inject RepositoryRegistry repositoryRegistry; + @Inject + private IndexerEngine indexerEngine; + IMocksControl archivaConfigControl; Configuration config; @@ -98,7 +97,10 @@ public abstract class AbstractMavenRepositorySearch List<IndexCreator> indexCreators; @Inject - NexusIndexer nexusIndexer; + Indexer indexer; + + @Inject + Scanner scanner; @Inject QueryCreator queryCreator; @@ -127,11 +129,9 @@ public abstract class AbstractMavenRepositorySearch defaultProxyConnectorAdmin.setArchivaConfiguration( archivaConfig ); repositoryRegistry.setArchivaConfiguration( archivaConfig ); - search = new MavenRepositorySearch( nexusIndexer, defaultManagedRepositoryAdmin, defaultProxyConnectorAdmin, + search = new MavenRepositorySearch( indexer, repositoryRegistry, defaultProxyConnectorAdmin, queryCreator ); - defaultManagedRepositoryAdmin.setIndexer( nexusIndexer ); - defaultManagedRepositoryAdmin.setIndexCreators( indexCreators ); assertNotNull( repositoryRegistry ); defaultManagedRepositoryAdmin.setRepositoryRegistry( repositoryRegistry ); @@ -144,6 +144,8 @@ public abstract class AbstractMavenRepositorySearch archivaConfig.addListener( EasyMock.anyObject( ConfigurationListener.class ) ); EasyMock.expect( archivaConfig.getDefaultLocale() ).andReturn( Locale.getDefault( ) ).anyTimes(); EasyMock.expect( archivaConfig.getConfiguration() ).andReturn(config).anyTimes(); + archivaConfig.save(EasyMock.anyObject(Configuration.class)); + EasyMock.expectLastCall().anyTimes(); archivaConfigControl.replay(); repositoryRegistry.reload(); archivaConfigControl.reset(); @@ -154,11 +156,16 @@ public abstract class AbstractMavenRepositorySearch public void tearDown() throws Exception { - for ( IndexingContext indexingContext : nexusIndexer.getIndexingContexts().values() ) - { - nexusIndexer.removeIndexingContext( indexingContext, true ); - } - + archivaConfigControl.reset(); + EasyMock.expect( archivaConfig.getDefaultLocale() ).andReturn( Locale.getDefault( ) ).anyTimes(); + EasyMock.expect( archivaConfig.getConfiguration() ).andReturn(config).anyTimes(); + archivaConfig.save(EasyMock.anyObject(Configuration.class)); + EasyMock.expectLastCall().anyTimes(); + archivaConfigControl.replay(); + repositoryRegistry.removeRepository(TEST_REPO_1); + repositoryRegistry.removeRepository(TEST_REPO_2); + repositoryRegistry.removeRepository(REPO_RELEASE); + repositoryRegistry.destroy(); FileUtils.deleteDirectory( Paths.get( org.apache.archiva.common.utils.FileUtils.getBasedir(), "/target/repos/" + TEST_REPO_1 ) ); assertFalse( Files.exists(Paths.get( org.apache.archiva.common.utils.FileUtils.getBasedir(), "/target/repos/" + TEST_REPO_1 )) ); @@ -190,22 +197,32 @@ public abstract class AbstractMavenRepositorySearch repositoryConfig.setScanned( true ); repositoryConfig.setSnapshots( false ); repositoryConfig.setReleases( true ); + repositoryConfig.setIndexDir(".indexer"); return repositoryConfig; } - protected void createIndex( String repository, List<Path> filesToBeIndexed, boolean scan ) + protected void createIndex( String repository, List<Path> filesToBeIndexed, boolean scan) throws Exception { + createIndex(repository, filesToBeIndexed, scan, null); + } + + protected void createIndex( String repository, List<Path> filesToBeIndexed, boolean scan, Path indexDir) throws Exception { + Repository rRepo = repositoryRegistry.getRepository(repository); + IndexCreationFeature icf = rRepo.getFeature(IndexCreationFeature.class).get(); + - IndexingContext context = nexusIndexer.getIndexingContexts().get( repository ); + IndexingContext context = rRepo.getIndexingContext().getBaseContext(IndexingContext.class); if ( context != null ) { - nexusIndexer.removeIndexingContext( context, true ); + context.close(true); } - Path indexerDirectory = Paths.get( org.apache.archiva.common.utils.FileUtils.getBasedir(), "/target/repos/" + repository + "/.indexer" ); + Path repoDir = Paths.get(org.apache.archiva.common.utils.FileUtils.getBasedir()).resolve("target").resolve("repos").resolve(repository); + + Path indexerDirectory = repoDir.resolve(".indexer" ); if ( Files.exists(indexerDirectory) ) { @@ -214,7 +231,7 @@ public abstract class AbstractMavenRepositorySearch assertFalse( Files.exists(indexerDirectory) ); - Path lockFile = Paths.get( org.apache.archiva.common.utils.FileUtils.getBasedir(), "/target/repos/" + repository + "/.indexer/write.lock" ); + Path lockFile = repoDir.resolve(".indexer/write.lock" ); if ( Files.exists(lockFile) ) { Files.delete(lockFile); @@ -224,14 +241,20 @@ public abstract class AbstractMavenRepositorySearch Path repo = Paths.get( org.apache.archiva.common.utils.FileUtils.getBasedir(), "src/test/" + repository ); assertTrue( Files.exists(repo) ); - Path indexDirectory = - Paths.get( org.apache.archiva.common.utils.FileUtils.getBasedir(), "target/index/test-" + Long.toString( System.currentTimeMillis() ) ); - indexDirectory.toFile().deleteOnExit(); - FileUtils.deleteDirectory( indexDirectory ); + org.apache.commons.io.FileUtils.copyDirectory(repo.toFile(), repoDir.toFile()); + + if (indexDir==null) { + Path indexDirectory = + Paths.get(org.apache.archiva.common.utils.FileUtils.getBasedir(), "target/index/test-" + Long.toString(System.currentTimeMillis())); + indexDirectory.toFile().deleteOnExit(); + FileUtils.deleteDirectory(indexDirectory); + icf.setIndexPath(indexDirectory.toUri()); + } else { + + icf.setIndexPath(indexDir.toUri()); + } + context = rRepo.getIndexingContext().getBaseContext(IndexingContext.class); - context = nexusIndexer.addIndexingContext( repository, repository, repo.toFile(), indexDirectory.toFile(), - repo.toUri().toURL().toExternalForm(), - indexDirectory.toUri().toURL().toString(), indexCreators ); // minimize datas in memory // context.getIndexWriter().setMaxBufferedDocs( -1 ); @@ -247,16 +270,20 @@ public abstract class AbstractMavenRepositorySearch ac.getArtifactInfo().setPackaging( "pom" ); ac.getArtifactInfo().setClassifier( "pom" ); } - nexusIndexer.addArtifactToIndex( ac, context ); + indexer.addArtifactToIndex( ac, context ); context.updateTimestamp( true ); } if ( scan ) { - nexusIndexer.scan( context, new ArtifactScanListener(), false ); + DefaultScannerListener listener = new DefaultScannerListener( context, indexerEngine, true, new ArtifactScanListener()); + ScanningRequest req = new ScanningRequest(context, listener ); + scanner.scan( req ); + context.commit(); } // force flushing - context.getIndexWriter().commit(); + context.commit(); + // context.getIndexWriter().commit(); context.setSearchable( true ); } diff --git a/archiva-modules/archiva-base/archiva-maven2-indexer/src/test/java/org/apache/archiva/indexer/maven/search/MavenRepositorySearchOSGITest.java b/archiva-modules/archiva-base/archiva-maven2-indexer/src/test/java/org/apache/archiva/indexer/maven/search/MavenRepositorySearchOSGITest.java index e99947fa8..066b2af92 100644 --- a/archiva-modules/archiva-base/archiva-maven2-indexer/src/test/java/org/apache/archiva/indexer/maven/search/MavenRepositorySearchOSGITest.java +++ b/archiva-modules/archiva-base/archiva-maven2-indexer/src/test/java/org/apache/archiva/indexer/maven/search/MavenRepositorySearchOSGITest.java @@ -22,9 +22,12 @@ package org.apache.archiva.indexer.maven.search; import org.apache.archiva.indexer.search.SearchFields; import org.apache.archiva.indexer.search.SearchResultHit; import org.apache.archiva.indexer.search.SearchResults; +import org.apache.archiva.repository.RepositoryRegistry; import org.easymock.EasyMock; +import org.junit.After; import org.junit.Test; +import javax.inject.Inject; import java.nio.file.Path; import java.util.Arrays; import java.util.Collections; @@ -38,6 +41,16 @@ public class MavenRepositorySearchOSGITest extends AbstractMavenRepositorySearch { + @Inject + RepositoryRegistry repositoryRegistry; + + @After + @Override + public void tearDown() throws Exception { + super.tearDown(); + repositoryRegistry.destroy(); + } + @Test public void searchFelixWithSymbolicName() throws Exception diff --git a/archiva-modules/archiva-base/archiva-maven2-indexer/src/test/java/org/apache/archiva/indexer/maven/search/MavenRepositorySearchPaginateTest.java b/archiva-modules/archiva-base/archiva-maven2-indexer/src/test/java/org/apache/archiva/indexer/maven/search/MavenRepositorySearchPaginateTest.java index c8498b29a..d679edf27 100644 --- a/archiva-modules/archiva-base/archiva-maven2-indexer/src/test/java/org/apache/archiva/indexer/maven/search/MavenRepositorySearchPaginateTest.java +++ b/archiva-modules/archiva-base/archiva-maven2-indexer/src/test/java/org/apache/archiva/indexer/maven/search/MavenRepositorySearchPaginateTest.java @@ -24,19 +24,37 @@ import org.apache.archiva.indexer.search.SearchResultHit; import org.apache.archiva.indexer.search.SearchResultLimits; import org.apache.archiva.indexer.search.SearchResults; import org.apache.archiva.indexer.util.SearchUtil; +import org.apache.archiva.repository.RepositoryRegistry; +import org.apache.archiva.test.utils.ArchivaSpringJUnit4ClassRunner; +import org.junit.After; import org.junit.Test; import org.junit.runner.RunWith; import java.util.Arrays; import org.apache.archiva.test.utils.ArchivaBlockJUnit4ClassRunner; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.test.context.ContextConfiguration; + +import javax.inject.Inject; /** * @author Olivier Lamy */ -@RunWith( ArchivaBlockJUnit4ClassRunner.class ) +@RunWith( ArchivaSpringJUnit4ClassRunner.class ) +@ContextConfiguration( locations = { "classpath*:/META-INF/spring-context.xml", "classpath:/spring-context.xml" } ) public class MavenRepositorySearchPaginateTest extends TestCase { + + @Autowired + RepositoryRegistry repositoryRegistry; + + @After + public void endTests() { + assert repositoryRegistry!=null; + repositoryRegistry.destroy(); + } + @Test public void nonPaginatedResult() throws Exception diff --git a/archiva-modules/archiva-base/archiva-maven2-indexer/src/test/java/org/apache/archiva/indexer/maven/search/MavenRepositorySearchTest.java b/archiva-modules/archiva-base/archiva-maven2-indexer/src/test/java/org/apache/archiva/indexer/maven/search/MavenRepositorySearchTest.java index 1cc157482..eff589fce 100644 --- a/archiva-modules/archiva-base/archiva-maven2-indexer/src/test/java/org/apache/archiva/indexer/maven/search/MavenRepositorySearchTest.java +++ b/archiva-modules/archiva-base/archiva-maven2-indexer/src/test/java/org/apache/archiva/indexer/maven/search/MavenRepositorySearchTest.java @@ -50,11 +50,11 @@ public class MavenRepositorySearchTest throws Exception { List<Path> files = new ArrayList<>(); - files.add( Paths.get( org.apache.archiva.common.utils.FileUtils.getBasedir(), "src/test", TEST_REPO_1, + files.add( Paths.get( org.apache.archiva.common.utils.FileUtils.getBasedir(), "target/repos", TEST_REPO_1, "/org/apache/archiva/archiva-search/1.0/archiva-search-1.0.jar" ) ); - files.add( Paths.get( org.apache.archiva.common.utils.FileUtils.getBasedir(), "src/test", TEST_REPO_1, + files.add( Paths.get( org.apache.archiva.common.utils.FileUtils.getBasedir(), "target/repos", TEST_REPO_1, "/org/apache/archiva/archiva-test/1.0/archiva-test-1.0.jar" )); - files.add( Paths.get( org.apache.archiva.common.utils.FileUtils.getBasedir(), "src/test", TEST_REPO_1, + files.add( Paths.get( org.apache.archiva.common.utils.FileUtils.getBasedir(), "target/repos", TEST_REPO_1, "org/apache/archiva/archiva-test/2.0/archiva-test-2.0.jar" )); createIndex( TEST_REPO_1, files, scan ); @@ -64,20 +64,20 @@ public class MavenRepositorySearchTest throws Exception { List<Path> files = new ArrayList<>(); - files.add( Paths.get( org.apache.archiva.common.utils.FileUtils.getBasedir(), "src/test/" + TEST_REPO_1 + files.add( Paths.get( org.apache.archiva.common.utils.FileUtils.getBasedir(), "target/repos/" + TEST_REPO_1 + "/org/apache/archiva/archiva-search/1.0/archiva-search-1.0.jar" ) ); - files.add( Paths.get( org.apache.archiva.common.utils.FileUtils.getBasedir(), "src/test/" + TEST_REPO_1 + files.add( Paths.get( org.apache.archiva.common.utils.FileUtils.getBasedir(), "target/repos/" + TEST_REPO_1 + "/org/apache/archiva/archiva-test/1.0/archiva-test-1.0.jar" ) ); - files.add( Paths.get( org.apache.archiva.common.utils.FileUtils.getBasedir(), "src/test/" + TEST_REPO_1 + files.add( Paths.get( org.apache.archiva.common.utils.FileUtils.getBasedir(), "target/repos/" + TEST_REPO_1 + "/org/apache/archiva/archiva-test/2.0/archiva-test-2.0.jar" ) ); - files.add( Paths.get( org.apache.archiva.common.utils.FileUtils.getBasedir(), "src/test/" + TEST_REPO_1 + files.add( Paths.get( org.apache.archiva.common.utils.FileUtils.getBasedir(), "target/repos/" + TEST_REPO_1 + "/org/apache/archiva/archiva-webapp/1.0/archiva-webapp-1.0.war" ) ); files.add( Paths.get( org.apache.archiva.common.utils.FileUtils.getBasedir(), - "src/test/" + TEST_REPO_1 + "/com/artifactid-numeric/1.0/artifactid-numeric-1.0.jar" ) ); - files.add( Paths.get( org.apache.archiva.common.utils.FileUtils.getBasedir(), "src/test/" + TEST_REPO_1 + "target/repos/" + TEST_REPO_1 + "/com/artifactid-numeric/1.0/artifactid-numeric-1.0.jar" ) ); + files.add( Paths.get( org.apache.archiva.common.utils.FileUtils.getBasedir(), "target/repos/" + TEST_REPO_1 + "/com/artifactid-numeric123/1.0/artifactid-numeric123-1.0.jar" ) ); files.add( Paths.get( org.apache.archiva.common.utils.FileUtils.getBasedir(), - "src/test/" + TEST_REPO_1 + "/com/classname-search/1.0/classname-search-1.0.jar" ) ); + "target/repos/" + TEST_REPO_1 + "/com/classname-search/1.0/classname-search-1.0.jar" ) ); createIndex( TEST_REPO_1, files, scan ); } @@ -87,13 +87,13 @@ public class MavenRepositorySearchTest { List<Path> files = new ArrayList<>(); - files.add( Paths.get( org.apache.archiva.common.utils.FileUtils.getBasedir(), "src/test/" + TEST_REPO_1 + files.add( Paths.get( org.apache.archiva.common.utils.FileUtils.getBasedir(), "target/repos/" + TEST_REPO_1 + "/org/apache/archiva/archiva-search/1.0/archiva-search-1.0.jar" ) ); - files.add( Paths.get( org.apache.archiva.common.utils.FileUtils.getBasedir(), "src/test/" + TEST_REPO_1 + files.add( Paths.get( org.apache.archiva.common.utils.FileUtils.getBasedir(), "target/repos/" + TEST_REPO_1 + "/org/apache/archiva/archiva-search/1.0/archiva-search-1.0.pom" ) ); - files.add( Paths.get( org.apache.archiva.common.utils.FileUtils.getBasedir(), "src/test/" + TEST_REPO_1 + files.add( Paths.get( org.apache.archiva.common.utils.FileUtils.getBasedir(), "target/repos/" + TEST_REPO_1 + "/org/apache/archiva/archiva-search/1.0/archiva-search-1.0-sources.jar" ) ); createIndex( TEST_REPO_1, files, scan ); @@ -337,9 +337,9 @@ public class MavenRepositorySearchTest createSimpleIndex( true ); List<Path> files = new ArrayList<>(); - files.add( Paths.get( org.apache.archiva.common.utils.FileUtils.getBasedir(), "src/test/" + TEST_REPO_2 + files.add( Paths.get( org.apache.archiva.common.utils.FileUtils.getBasedir(), "target/repos/" + TEST_REPO_2 + "/org/apache/archiva/archiva-search/1.0/archiva-search-1.0.jar" ) ); - files.add( Paths.get( org.apache.archiva.common.utils.FileUtils.getBasedir(), "src/test/" + TEST_REPO_2 + files.add( Paths.get( org.apache.archiva.common.utils.FileUtils.getBasedir(), "target/repos/" + TEST_REPO_2 + "/org/apache/archiva/archiva-search/1.1/archiva-search-1.1.jar" ) ); createIndex( TEST_REPO_2, files, false ); @@ -365,6 +365,7 @@ public class MavenRepositorySearchTest SearchResultHit hit = results.getSearchResultHit( SearchUtil.getHitId( "org.apache.archiva", "archiva-search", null, "jar" ) ); + assertNotNull(hit); assertEquals( "org.apache.archiva", hit.getGroupId() ); assertEquals( "archiva-search", hit.getArtifactId() ); assertEquals( "not 2 version for hit " + hit + "::" + niceDisplay( results ), 2, hit.getVersions().size() ); @@ -470,9 +471,9 @@ public class MavenRepositorySearchTest throws Exception { List<Path> files = new ArrayList<>(); - files.add( Paths.get( org.apache.archiva.common.utils.FileUtils.getBasedir(), "src/test/" + TEST_REPO_2 + files.add( Paths.get( org.apache.archiva.common.utils.FileUtils.getBasedir(), "target/repos/" + TEST_REPO_2 + "/org/apache/archiva/archiva-search/1.0/archiva-search-1.0.jar" ) ); - files.add( Paths.get( org.apache.archiva.common.utils.FileUtils.getBasedir(), "src/test/" + TEST_REPO_2 + files.add( Paths.get( org.apache.archiva.common.utils.FileUtils.getBasedir(), "target/repos/" + TEST_REPO_2 + "/org/apache/archiva/archiva-search/1.1/archiva-search-1.1.jar" ) ); createIndex( TEST_REPO_2, files, false ); @@ -560,8 +561,8 @@ public class MavenRepositorySearchTest { List<Path> files = new ArrayList<>(); files.add( Paths.get( org.apache.archiva.common.utils.FileUtils.getBasedir(), - "src/test/" + TEST_REPO_1 + "/com/artifactid-numeric/1.0/artifactid-numeric-1.0.jar" ) ); - files.add( Paths.get( org.apache.archiva.common.utils.FileUtils.getBasedir(), "src/test/" + TEST_REPO_1 + "target/repos/" + TEST_REPO_1 + "/com/artifactid-numeric/1.0/artifactid-numeric-1.0.jar" ) ); + files.add( Paths.get( org.apache.archiva.common.utils.FileUtils.getBasedir(), "target/repos/" + TEST_REPO_1 + "/com/artifactid-numeric123/1.0/artifactid-numeric123-1.0.jar" ) ); createIndex( TEST_REPO_1, files, true ); @@ -891,16 +892,19 @@ public class MavenRepositorySearchTest { Path repo = Paths.get( "target/repo-release" ); + FileUtils.deleteDirectory(repo.toFile()); Path indexDirectory = repo.resolve(".index" ); FileUtils.copyDirectoryStructure( Paths.get( "src/test/repo-release" ).toFile(), repo.toFile() ); IndexUpgrader.main( new String[]{ indexDirectory.toAbsolutePath().toString() } ); - createIndex( "repo-release", Collections.emptyList(), false ); + createIndex(REPO_RELEASE, Collections.emptyList(), false, indexDirectory ); + +// indexer.addIndexingContext( REPO_RELEASE, REPO_RELEASE, repo.toFile(), indexDirectory.toFile(), +// repo.toUri().toURL().toExternalForm(), +// indexDirectory.toUri().toURL().toString(), indexCreators ); + - nexusIndexer.addIndexingContext( REPO_RELEASE, REPO_RELEASE, repo.toFile(), indexDirectory.toFile(), - repo.toUri().toURL().toExternalForm(), - indexDirectory.toUri().toURL().toString(), indexCreators ); SearchResultLimits limits = new SearchResultLimits( SearchResultLimits.ALL_PAGES ); limits.setPageSize( 300 ); diff --git a/archiva-modules/archiva-base/archiva-maven2-indexer/src/test/resources/log4j2-test.xml b/archiva-modules/archiva-base/archiva-maven2-indexer/src/test/resources/log4j2-test.xml new file mode 100644 index 000000000..db1c64d28 --- /dev/null +++ b/archiva-modules/archiva-base/archiva-maven2-indexer/src/test/resources/log4j2-test.xml @@ -0,0 +1,45 @@ +<?xml version="1.0" encoding="UTF-8" ?> +<!-- + ~ 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. + --> + + +<configuration status="debug"> + <appenders> + <Console name="console" target="SYSTEM_OUT"> + <PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"/> + </Console> + </appenders> + <loggers> + + <logger name="org.apache.archiva.repository" level="info"/> + <logger name="org.apache.archiva.indexer" level="info" /> + + <logger name="JPOX" level="error"/> + + + <logger name="org.springframework" level="error"/> + + + <root level="info"> + <appender-ref ref="console"/> + </root> + </loggers> +</configuration> + + diff --git a/archiva-modules/archiva-base/archiva-maven2-indexer/src/test/resources/spring-context.xml b/archiva-modules/archiva-base/archiva-maven2-indexer/src/test/resources/spring-context.xml index fbf53be07..83a361f17 100644 --- a/archiva-modules/archiva-base/archiva-maven2-indexer/src/test/resources/spring-context.xml +++ b/archiva-modules/archiva-base/archiva-maven2-indexer/src/test/resources/spring-context.xml @@ -28,7 +28,7 @@ default-lazy-init="false"> <context:annotation-config/> - <context:component-scan base-package="org.apache.archiva.indexer.maven" /> + <context:component-scan base-package="org.apache.archiva.indexer.maven,org.apache.archiva.repository,org.apache.archiva.repository.content.maven2" /> <bean name="wagon#file" scope="prototype" class="org.apache.maven.wagon.providers.file.FileWagon"/> diff --git a/archiva-modules/archiva-base/archiva-proxy/pom.xml b/archiva-modules/archiva-base/archiva-proxy/pom.xml index efe7be3c5..85a3e6080 100644 --- a/archiva-modules/archiva-base/archiva-proxy/pom.xml +++ b/archiva-modules/archiva-base/archiva-proxy/pom.xml @@ -215,6 +215,11 @@ <scope>test</scope> </dependency> + <dependency> + <groupId>org.apache.archiva</groupId> + <artifactId>archiva-maven2-indexer</artifactId> + <scope>test</scope> + </dependency> </dependencies> <build> <plugins> diff --git a/archiva-modules/archiva-base/archiva-proxy/src/test/java/org/apache/archiva/metadata/repository/MockRepositoryArchivaTaskScheduler.java b/archiva-modules/archiva-base/archiva-proxy/src/test/java/org/apache/archiva/metadata/repository/MockRepositoryArchivaTaskScheduler.java index 2b8b9ab63..08bcd9640 100644 --- a/archiva-modules/archiva-base/archiva-proxy/src/test/java/org/apache/archiva/metadata/repository/MockRepositoryArchivaTaskScheduler.java +++ b/archiva-modules/archiva-base/archiva-proxy/src/test/java/org/apache/archiva/metadata/repository/MockRepositoryArchivaTaskScheduler.java @@ -26,7 +26,7 @@ import org.springframework.stereotype.Service; /** * @author Olivier Lamy */ -@Service ("archivaTaskScheduler#repository") +@Service ("archivaTaskScheduler#repositoryMock") public class MockRepositoryArchivaTaskScheduler implements RepositoryArchivaTaskScheduler { diff --git a/archiva-modules/archiva-base/archiva-proxy/src/test/java/org/apache/archiva/proxy/AbstractProxyTestCase.java b/archiva-modules/archiva-base/archiva-proxy/src/test/java/org/apache/archiva/proxy/AbstractProxyTestCase.java index 4dcf74760..3ab65bcb2 100644 --- a/archiva-modules/archiva-base/archiva-proxy/src/test/java/org/apache/archiva/proxy/AbstractProxyTestCase.java +++ b/archiva-modules/archiva-base/archiva-proxy/src/test/java/org/apache/archiva/proxy/AbstractProxyTestCase.java @@ -82,6 +82,9 @@ public abstract class AbstractProxyTestCase @Inject protected ApplicationContext applicationContext; + @Inject + RepositoryRegistry repositoryRegistry; + protected static final String ID_PROXIED1 = "proxied1"; protected static final String ID_PROXIED1_TARGET = "proxied1-target"; @@ -121,7 +124,6 @@ public abstract class AbstractProxyTestCase WagonDelegate delegate; - protected RepositoryRegistry repositoryRegistry; @Inject protected NexusIndexer nexusIndexer; @@ -156,7 +158,6 @@ public abstract class AbstractProxyTestCase // to prevent windauze file leaking removeMavenIndexes(); - repositoryRegistry = applicationContext.getBean( RepositoryRegistry.class ); repositoryRegistry.setArchivaConfiguration( config ); // Setup target (proxied to) repository. @@ -167,6 +168,7 @@ public abstract class AbstractProxyTestCase saveRemoteRepositoryConfig( ID_PROXIED2, "Proxied Repository 2", Paths.get( REPOPATH_PROXIED2 ).toUri().toURL().toExternalForm(), "default" ); + repositoryRegistry.reload(); if ( repositoryRegistry.getManagedRepository( repoConfig.getId() ) != null ) diff --git a/archiva-modules/archiva-base/archiva-proxy/src/test/java/org/apache/archiva/repository/mock/RepositoryProviderMock.java b/archiva-modules/archiva-base/archiva-proxy/src/test/java/org/apache/archiva/repository/mock/RepositoryProviderMock.java index c923ba960..81563b625 100644 --- a/archiva-modules/archiva-base/archiva-proxy/src/test/java/org/apache/archiva/repository/mock/RepositoryProviderMock.java +++ b/archiva-modules/archiva-base/archiva-proxy/src/test/java/org/apache/archiva/repository/mock/RepositoryProviderMock.java @@ -21,18 +21,7 @@ package org.apache.archiva.repository.mock; import org.apache.archiva.configuration.ManagedRepositoryConfiguration; import org.apache.archiva.configuration.RemoteRepositoryConfiguration; -import org.apache.archiva.repository.BasicManagedRepository; -import org.apache.archiva.repository.BasicRemoteRepository; -import org.apache.archiva.repository.EditableManagedRepository; -import org.apache.archiva.repository.EditableRemoteRepository; -import org.apache.archiva.repository.ManagedRepository; -import org.apache.archiva.repository.PasswordCredentials; -import org.apache.archiva.repository.ReleaseScheme; -import org.apache.archiva.repository.RemoteRepository; -import org.apache.archiva.repository.RepositoryCredentials; -import org.apache.archiva.repository.RepositoryException; -import org.apache.archiva.repository.RepositoryProvider; -import org.apache.archiva.repository.RepositoryType; +import org.apache.archiva.repository.*; import org.apache.archiva.repository.features.ArtifactCleanupFeature; import org.apache.archiva.repository.features.IndexCreationFeature; import org.apache.archiva.repository.features.RemoteIndexFeature; @@ -165,6 +154,8 @@ public class RepositoryProviderMock implements RepositoryProvider rif.setIndexUri( new URI( configuration.getIndexDir( ) ) ); rif.setDownloadTimeout( Duration.ofSeconds( configuration.getRemoteDownloadTimeout( ) ) ); rif.setProxyId( configuration.getRemoteDownloadNetworkProxyId( ) ); + IndexCreationFeature icf = remoteRepository.getFeature(IndexCreationFeature.class).get(); + icf.setIndexPath(new URI(".index" )); } catch ( Exception e ) { @@ -229,4 +220,8 @@ public class RepositoryProviderMock implements RepositoryProvider return configuration; } + @Override + public <T> void raise(RepositoryEvent<T> event) { + + } } diff --git a/archiva-modules/archiva-base/archiva-proxy/src/test/resources/spring-context.xml b/archiva-modules/archiva-base/archiva-proxy/src/test/resources/spring-context.xml index baef8a5e4..65599f758 100755 --- a/archiva-modules/archiva-base/archiva-proxy/src/test/resources/spring-context.xml +++ b/archiva-modules/archiva-base/archiva-proxy/src/test/resources/spring-context.xml @@ -33,6 +33,7 @@ <alias name="archivaConfiguration#mock" alias="archivaConfiguration#default"/> <alias name="archivaConfiguration#mock" alias="archivaConfiguration"/> + <alias name="archivaTaskScheduler#repositoryMock" alias="archivaTaskScheduler#repository" /> <bean name="scheduler" class="org.apache.archiva.redback.components.scheduler.DefaultScheduler"> <property name="properties"> diff --git a/archiva-modules/archiva-base/archiva-repository-admin/archiva-repository-admin-api/src/main/java/org/apache/archiva/admin/model/managed/ManagedRepositoryAdmin.java b/archiva-modules/archiva-base/archiva-repository-admin/archiva-repository-admin-api/src/main/java/org/apache/archiva/admin/model/managed/ManagedRepositoryAdmin.java index a73e457d1..08d68cf90 100644 --- a/archiva-modules/archiva-base/archiva-repository-admin/archiva-repository-admin-api/src/main/java/org/apache/archiva/admin/model/managed/ManagedRepositoryAdmin.java +++ b/archiva-modules/archiva-base/archiva-repository-admin/archiva-repository-admin-api/src/main/java/org/apache/archiva/admin/model/managed/ManagedRepositoryAdmin.java @@ -22,6 +22,7 @@ package org.apache.archiva.admin.model.managed; import org.apache.archiva.admin.model.AuditInformation; import org.apache.archiva.admin.model.RepositoryAdminException; import org.apache.archiva.admin.model.beans.ManagedRepository; +import org.apache.archiva.indexer.ArchivaIndexingContext; import org.apache.maven.index.context.IndexingContext; import java.util.List; @@ -57,16 +58,5 @@ public interface ManagedRepositoryAdmin AuditInformation auditInformation, boolean resetStats ) throws RepositoryAdminException; - /** - * - * @param repository - * @return - * @throws RepositoryAdminException - * @since 1.4-M2 - */ - IndexingContext createIndexContext( ManagedRepository repository ) - throws RepositoryAdminException; - - IndexingContext createIndexContext( org.apache.archiva.repository.ManagedRepository repository) throws RepositoryAdminException; } diff --git a/archiva-modules/archiva-base/archiva-repository-admin/archiva-repository-admin-default/src/main/java/org/apache/archiva/admin/repository/managed/DefaultManagedRepositoryAdmin.java b/archiva-modules/archiva-base/archiva-repository-admin/archiva-repository-admin-default/src/main/java/org/apache/archiva/admin/repository/managed/DefaultManagedRepositoryAdmin.java index ae7cd6255..469d12244 100644 --- a/archiva-modules/archiva-base/archiva-repository-admin/archiva-repository-admin-default/src/main/java/org/apache/archiva/admin/repository/managed/DefaultManagedRepositoryAdmin.java +++ b/archiva-modules/archiva-base/archiva-repository-admin/archiva-repository-admin-default/src/main/java/org/apache/archiva/admin/repository/managed/DefaultManagedRepositoryAdmin.java @@ -28,6 +28,10 @@ import org.apache.archiva.configuration.IndeterminateConfigurationException; import org.apache.archiva.configuration.ManagedRepositoryConfiguration; import org.apache.archiva.configuration.ProxyConnectorConfiguration; import org.apache.archiva.configuration.RepositoryGroupConfiguration; +import org.apache.archiva.indexer.ArchivaIndexManager; +import org.apache.archiva.indexer.ArchivaIndexingContext; +import org.apache.archiva.indexer.IndexManagerFactory; +import org.apache.archiva.indexer.IndexUpdateFailedException; import org.apache.archiva.metadata.model.facets.AuditEvent; import org.apache.archiva.metadata.repository.MetadataRepository; import org.apache.archiva.metadata.repository.MetadataRepositoryException; @@ -40,6 +44,7 @@ import org.apache.archiva.redback.components.taskqueue.TaskQueueException; import org.apache.archiva.redback.role.RoleManager; import org.apache.archiva.redback.role.RoleManagerException; import org.apache.archiva.repository.ReleaseScheme; +import org.apache.archiva.repository.Repository; import org.apache.archiva.repository.RepositoryException; import org.apache.archiva.repository.RepositoryRegistry; import org.apache.archiva.repository.features.ArtifactCleanupFeature; @@ -50,10 +55,8 @@ import org.apache.archiva.scheduler.repository.model.RepositoryTask; import org.apache.archiva.security.common.ArchivaRoleConstants; import org.apache.commons.lang.StringUtils; import org.apache.maven.index.NexusIndexer; -import org.apache.maven.index.context.IndexCreator; + import org.apache.maven.index.context.IndexingContext; -import org.apache.maven.index.context.UnsupportedExistingLuceneIndexException; -import org.apache.maven.index_shaded.lucene.index.IndexFormatTooOldException; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.stereotype.Service; @@ -112,12 +115,11 @@ public class DefaultManagedRepositoryAdmin @Named(value = "cache#namespaces") private Cache<String, Collection<String>> namespacesCache; - // fields @Inject - private List<? extends IndexCreator> indexCreators; + private IndexManagerFactory indexManagerFactory; + + - @Inject - private NexusIndexer indexer; @PostConstruct public void initialize() @@ -127,7 +129,6 @@ public class DefaultManagedRepositoryAdmin for ( ManagedRepository managedRepository : getManagedRepositories() ) { log.debug("Initializating {}", managedRepository.getId()); - createIndexContext( managedRepository ); addRepositoryRoles( managedRepository.getId() ); } @@ -137,22 +138,6 @@ public class DefaultManagedRepositoryAdmin public void shutdown() throws RepositoryAdminException { - try - { - // close index on shutdown - for ( ManagedRepository managedRepository : getManagedRepositories() ) - { - IndexingContext context = indexer.getIndexingContexts().get( managedRepository.getId() ); - if ( context != null ) - { - indexer.removeIndexingContext( context, false ); - } - } - } - catch ( IOException e ) - { - throw new RepositoryAdminException( e.getMessage(), e ); - } } /* @@ -290,7 +275,6 @@ public class DefaultManagedRepositoryAdmin log.error("Could not add repository roles for repository [{}]: {}", managedRepository.getId(), e.getMessage(), e); throw new RepositoryAdminException( "Could not add roles to repository "+e.getMessage() ); } - createIndexContext( managedRepository ); return Boolean.TRUE; } @@ -304,64 +288,56 @@ public class DefaultManagedRepositoryAdmin { Configuration config = getArchivaConfiguration().getConfiguration(); ManagedRepositoryConfiguration repoConfig=config.findManagedRepositoryById( repositoryId ); - - log.debug("Repo location "+repoConfig.getLocation()); - - org.apache.archiva.repository.ManagedRepository repo = repositoryRegistry.getManagedRepository( repositoryId ); - org.apache.archiva.repository.ManagedRepository stagingRepository = null; - if (repo!=null) { - try - { - if (repo.supportsFeature( StagingRepositoryFeature.class )) { - stagingRepository = repo.getFeature( StagingRepositoryFeature.class ).get().getStagingRepository(); + if (repoConfig!=null) { + + log.debug("Repo location " + repoConfig.getLocation()); + + org.apache.archiva.repository.ManagedRepository repo = repositoryRegistry.getManagedRepository(repositoryId); + org.apache.archiva.repository.ManagedRepository stagingRepository = null; + if (repo != null) { + try { + if (repo.supportsFeature(StagingRepositoryFeature.class)) { + stagingRepository = repo.getFeature(StagingRepositoryFeature.class).get().getStagingRepository(); + } + repositoryRegistry.removeRepository(repo, config); + } catch (RepositoryException e) { + log.error("Removal of repository {} failed: {}", repositoryId, e.getMessage(), e); + throw new RepositoryAdminException("Removal of repository " + repositoryId + " failed."); } - repositoryRegistry.removeRepository( repo, config ); - } - catch ( RepositoryException e ) - { - log.error("Removal of repository {} failed: {}", repositoryId, e.getMessage(), e); - throw new RepositoryAdminException( "Removal of repository "+repositoryId+" failed." ); + } else { + throw new RepositoryAdminException("A repository with that id does not exist"); } - } else { - throw new RepositoryAdminException( "A repository with that id does not exist" ); - } - triggerAuditEvent( repositoryId, null, AuditEvent.DELETE_MANAGED_REPO, auditInformation ); - if (repoConfig!=null) - { - deleteManagedRepository( repoConfig, deleteContent, config, false ); - } + triggerAuditEvent(repositoryId, null, AuditEvent.DELETE_MANAGED_REPO, auditInformation); + if (repoConfig != null) { + deleteManagedRepository(repoConfig, deleteContent, config, false); + } - // stage repo exists ? - if ( stagingRepository != null ) - { - // do not trigger event when deleting the staged one - ManagedRepositoryConfiguration stagingRepositoryConfig = config.findManagedRepositoryById( stagingRepository.getId( ) ); - try - { - repositoryRegistry.removeRepository( stagingRepository ); - if (stagingRepositoryConfig!=null) - { - deleteManagedRepository( stagingRepositoryConfig, deleteContent, config, true ); + // stage repo exists ? + if (stagingRepository != null) { + // do not trigger event when deleting the staged one + ManagedRepositoryConfiguration stagingRepositoryConfig = config.findManagedRepositoryById(stagingRepository.getId()); + try { + repositoryRegistry.removeRepository(stagingRepository); + if (stagingRepositoryConfig != null) { + deleteManagedRepository(stagingRepositoryConfig, deleteContent, config, true); + } + } catch (RepositoryException e) { + log.error("Removal of staging repository {} failed: {}", stagingRepository.getId(), e.getMessage(), e); } } - catch ( RepositoryException e ) - { - log.error("Removal of staging repository {} failed: {}", stagingRepository.getId(), e.getMessage(), e); + + try { + saveConfiguration(config); + } catch (Exception e) { + throw new RepositoryAdminException("Error saving configuration for delete action" + e.getMessage(), e); } - } - try - { - saveConfiguration( config ); - } - catch ( Exception e ) - { - throw new RepositoryAdminException( "Error saving configuration for delete action" + e.getMessage(), e ); + return Boolean.TRUE; + } else { + return Boolean.FALSE; } - - return Boolean.TRUE; } private Boolean deleteManagedRepository( ManagedRepositoryConfiguration repository, boolean deleteContent, @@ -369,20 +345,6 @@ public class DefaultManagedRepositoryAdmin throws RepositoryAdminException { - try - { - IndexingContext context = indexer.getIndexingContexts().get( repository.getId() ); - if ( context != null ) - { - // delete content only if directory exists - indexer.removeIndexingContext( context, - deleteContent && context.getIndexDirectoryFile().exists() ); - } - } - catch ( IOException e ) - { - throw new RepositoryAdminException( e.getMessage(), e ); - } if ( !stagedOne ) { RepositorySession repositorySession = getRepositorySessionFactory().createSession(); @@ -454,11 +416,24 @@ public class DefaultManagedRepositoryAdmin "fail to remove repository roles for repository " + repository.getId() + " : " + e.getMessage(), e ); } + try { + final RepositoryRegistry reg = getRepositoryRegistry(); + if (reg.getManagedRepository(repository.getId())!=null) { + reg.removeRepository(reg.getManagedRepository(repository.getId())); + } + } catch (RepositoryException e) { + throw new RepositoryAdminException("Removal of repository "+repository.getId()+ " failed: "+e.getMessage()); + } + saveConfiguration( config ); return Boolean.TRUE; } + ArchivaIndexManager getIndexManager(ManagedRepository managedRepository) { + org.apache.archiva.repository.ManagedRepository repo = getRepositoryRegistry().getManagedRepository(managedRepository.getId()); + return indexManagerFactory.getIndexManager(repo.getType()); + } @Override public Boolean updateManagedRepository( ManagedRepository managedRepository, boolean needStageRepo, @@ -486,11 +461,11 @@ public class DefaultManagedRepositoryAdmin stagingExists = oldRepo.getFeature( StagingRepositoryFeature.class ).get().getStagingRepository() != null; } boolean updateIndexContext = !StringUtils.equals( updatedRepoConfig.getIndexDir(), managedRepository.getIndexDirectory() ); - + org.apache.archiva.repository.ManagedRepository newRepo; // TODO remove content from old if path has changed !!!!! try { - org.apache.archiva.repository.ManagedRepository newRepo = repositoryRegistry.putRepository( updatedRepoConfig, configuration ); + newRepo = repositoryRegistry.putRepository( updatedRepoConfig, configuration ); if (newRepo.supportsFeature( StagingRepositoryFeature.class )) { org.apache.archiva.repository.ManagedRepository stagingRepo = newRepo.getFeature( StagingRepositoryFeature.class ).get( ).getStagingRepository( ); if (stagingRepo!=null && !stagingExists) @@ -551,21 +526,10 @@ public class DefaultManagedRepositoryAdmin { try { - IndexingContext indexingContext = indexer.getIndexingContexts().get( managedRepository.getId() ); - if ( indexingContext != null ) - { - indexer.removeIndexingContext( indexingContext, true ); - } - - // delete directory too as only content is deleted - Path indexDirectory = indexingContext.getIndexDirectoryFile().toPath(); - org.apache.archiva.common.utils.FileUtils.deleteDirectory( indexDirectory ); - createIndexContext( managedRepository ); - } - catch ( IOException e ) - { - throw new RepositoryAdminException( e.getMessage(), e ); + repositoryRegistry.resetIndexingContext(newRepo); + } catch (IndexUpdateFailedException e) { + e.printStackTrace(); } } @@ -591,110 +555,6 @@ public class DefaultManagedRepositoryAdmin } - public IndexingContext createIndexContext( org.apache.archiva.repository.ManagedRepository repository) throws RepositoryAdminException - { - return createIndexContext( convertRepo( repository ) ); - } - - @Override - public IndexingContext createIndexContext( ManagedRepository repository ) - throws RepositoryAdminException - { - - IndexingContext context = indexer.getIndexingContexts().get( repository.getId() ); - - if ( context != null ) - { - log.debug( "skip creating repository indexingContent with id {} as already exists", repository.getId() ); - return context; - } - - // take care first about repository location as can be relative - Path repositoryDirectory = Paths.get( repository.getLocation() ); - - if ( !repositoryDirectory.isAbsolute() ) - { - repositoryDirectory = - Paths.get( getRegistry().getString( "appserver.base" ), "repositories", - repository.getLocation() ); - } - - if ( !Files.exists(repositoryDirectory) ) - { - try { - Files.createDirectories(repositoryDirectory); - } catch (IOException e) { - log.error("Could not create directory {}", repositoryDirectory); - } - } - - try - { - - String indexDir = repository.getIndexDirectory(); - //File managedRepository = new File( repository.getLocation() ); - - Path indexDirectory = null; - if ( StringUtils.isNotBlank( indexDir ) ) - { - indexDirectory = Paths.get( repository.getIndexDirectory() ); - // not absolute so create it in repository directory - if ( !indexDirectory.isAbsolute() ) - { - indexDirectory = repositoryDirectory.resolve(repository.getIndexDirectory() ); - } - repository.setIndexDirectory( indexDirectory.toAbsolutePath().toString() ); - } - else - { - indexDirectory = repositoryDirectory.resolve(".indexer" ); - if ( !repositoryDirectory.isAbsolute() ) - { - indexDirectory = repositoryDirectory.resolve( ".indexer" ); - } - repository.setIndexDirectory( indexDirectory.toAbsolutePath().toString() ); - } - - if ( !Files.exists(indexDirectory) ) - { - Files.createDirectories(indexDirectory); - } - - context = indexer.getIndexingContexts().get( repository.getId() ); - - if ( context == null ) - { - try - { - context = indexer.addIndexingContext( repository.getId(), repository.getId(), repositoryDirectory.toFile(), - indexDirectory.toFile(), - repositoryDirectory.toUri().toURL().toExternalForm(), - indexDirectory.toUri().toURL().toString(), indexCreators ); - - context.setSearchable( repository.isScanned() ); - } - catch ( IndexFormatTooOldException e ) - { - // existing index with an old lucene format so we need to delete it!!! - // delete it first then recreate it. - log.warn( "the index of repository {} is too old we have to delete and recreate it", // - repository.getId() ); - org.apache.archiva.common.utils.FileUtils.deleteDirectory( indexDirectory ); - context = indexer.addIndexingContext( repository.getId(), repository.getId(), repositoryDirectory.toFile(), - indexDirectory.toFile(), - repositoryDirectory.toUri().toURL().toExternalForm(), - indexDirectory.toUri().toURL().toString(), indexCreators ); - - context.setSearchable( repository.isScanned() ); - } - } - return context; - } - catch ( IOException| UnsupportedExistingLuceneIndexException e ) - { - throw new RepositoryAdminException( e.getMessage(), e ); - } - } public Boolean scanRepository( String repositoryId, boolean fullScan ) { @@ -799,25 +659,6 @@ public class DefaultManagedRepositoryAdmin this.repositoryTaskScheduler = repositoryTaskScheduler; } - public NexusIndexer getIndexer() - { - return indexer; - } - - public void setIndexer( NexusIndexer indexer ) - { - this.indexer = indexer; - } - - public List<? extends IndexCreator> getIndexCreators() - { - return indexCreators; - } - - public void setIndexCreators( List<? extends IndexCreator> indexCreators ) - { - this.indexCreators = indexCreators; - } public RepositoryRegistry getRepositoryRegistry( ) { diff --git a/archiva-modules/archiva-base/archiva-repository-admin/archiva-repository-admin-default/src/main/java/org/apache/archiva/admin/repository/proxyconnector/DefaultProxyConnectorAdmin.java b/archiva-modules/archiva-base/archiva-repository-admin/archiva-repository-admin-default/src/main/java/org/apache/archiva/admin/repository/proxyconnector/DefaultProxyConnectorAdmin.java index fbf20481c..94ace55b3 100644 --- a/archiva-modules/archiva-base/archiva-repository-admin/archiva-repository-admin-default/src/main/java/org/apache/archiva/admin/repository/proxyconnector/DefaultProxyConnectorAdmin.java +++ b/archiva-modules/archiva-base/archiva-repository-admin/archiva-repository-admin-default/src/main/java/org/apache/archiva/admin/repository/proxyconnector/DefaultProxyConnectorAdmin.java @@ -30,6 +30,7 @@ import org.apache.archiva.configuration.Configuration; import org.apache.archiva.configuration.ProxyConnectorConfiguration; import org.apache.archiva.configuration.functors.ProxyConnectorSelectionPredicate; import org.apache.archiva.metadata.model.facets.AuditEvent; +import org.apache.archiva.repository.RepositoryRegistry; import org.apache.commons.collections.CollectionUtils; import org.apache.commons.lang.StringUtils; import org.springframework.stereotype.Service; @@ -53,10 +54,7 @@ public class DefaultProxyConnectorAdmin { @Inject - private ManagedRepositoryAdmin managedRepositoryAdmin; - - @Inject - private RemoteRepositoryAdmin remoteRepositoryAdmin; + RepositoryRegistry repositoryRegistry; @Override public List<ProxyConnector> getProxyConnectors() @@ -230,13 +228,13 @@ public class DefaultProxyConnectorAdmin throws RepositoryAdminException { // validate source a Managed target a Remote - if ( managedRepositoryAdmin.getManagedRepository( proxyConnector.getSourceRepoId() ) == null ) + if ( repositoryRegistry.getManagedRepository( proxyConnector.getSourceRepoId() ) == null ) { throw new RepositoryAdminException( "non valid ProxyConnector sourceRepo with id " + proxyConnector.getSourceRepoId() + " is not a ManagedRepository" ); } - if ( remoteRepositoryAdmin.getRemoteRepository( proxyConnector.getTargetRepoId() ) == null ) + if ( repositoryRegistry.getRemoteRepository( proxyConnector.getTargetRepoId() ) == null ) { throw new RepositoryAdminException( "non valid ProxyConnector sourceRepo with id " + proxyConnector.getTargetRepoId() diff --git a/archiva-modules/archiva-base/archiva-repository-admin/archiva-repository-admin-default/src/main/java/org/apache/archiva/admin/repository/remote/DefaultRemoteRepositoryAdmin.java b/archiva-modules/archiva-base/archiva-repository-admin/archiva-repository-admin-default/src/main/java/org/apache/archiva/admin/repository/remote/DefaultRemoteRepositoryAdmin.java index 19b540a98..3f8c58bbe 100644 --- a/archiva-modules/archiva-base/archiva-repository-admin/archiva-repository-admin-default/src/main/java/org/apache/archiva/admin/repository/remote/DefaultRemoteRepositoryAdmin.java +++ b/archiva-modules/archiva-base/archiva-repository-admin/archiva-repository-admin-default/src/main/java/org/apache/archiva/admin/repository/remote/DefaultRemoteRepositoryAdmin.java @@ -26,6 +26,7 @@ import org.apache.archiva.configuration.Configuration; import org.apache.archiva.configuration.ProxyConnectorConfiguration; import org.apache.archiva.configuration.RemoteRepositoryConfiguration; import org.apache.archiva.configuration.RepositoryCheckPath; +import org.apache.archiva.indexer.UnsupportedBaseContextException; import org.apache.archiva.metadata.model.facets.AuditEvent; import org.apache.archiva.repository.RemoteRepository; import org.apache.archiva.repository.PasswordCredentials; @@ -307,7 +308,9 @@ public class DefaultRemoteRepositoryAdmin { try { - String appServerBase = getRegistry().getString( "appserver.base" ); + RemoteRepository repo = repositoryRegistry.getRemoteRepository(remoteRepository.getId()); + return repo.getIndexingContext().getBaseContext(IndexingContext.class); + /*String appServerBase = getRegistry().getString( "appserver.base" ); String contextKey = "remote-" + remoteRepository.getId(); IndexingContext indexingContext = indexer.getIndexingContexts().get( contextKey ); @@ -359,11 +362,9 @@ public class DefaultRemoteRepositoryAdmin remoteRepository.getUrl(), calculateIndexRemoteUrl( remoteRepository ), indexCreators ); - } - } - catch ( IOException | UnsupportedExistingLuceneIndexException e ) - { - throw new RepositoryAdminException( e.getMessage(), e ); + }*/ + } catch (UnsupportedBaseContextException e) { + throw new RepositoryAdminException( e.getMessage(), e); } } diff --git a/archiva-modules/archiva-base/archiva-repository-admin/archiva-repository-admin-default/src/test/java/org/apache/archiva/admin/mock/ArchivaIndexManagerMock.java b/archiva-modules/archiva-base/archiva-repository-admin/archiva-repository-admin-default/src/test/java/org/apache/archiva/admin/mock/ArchivaIndexManagerMock.java new file mode 100644 index 000000000..049f4a7be --- /dev/null +++ b/archiva-modules/archiva-base/archiva-repository-admin/archiva-repository-admin-default/src/test/java/org/apache/archiva/admin/mock/ArchivaIndexManagerMock.java @@ -0,0 +1,777 @@ +package org.apache.archiva.admin.mock; + +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import org.apache.archiva.admin.model.RepositoryAdminException; +import org.apache.archiva.admin.model.beans.NetworkProxy; +import org.apache.archiva.admin.model.networkproxy.NetworkProxyAdmin; +import org.apache.archiva.common.utils.FileUtils; +import org.apache.archiva.common.utils.PathUtil; +import org.apache.archiva.configuration.ArchivaConfiguration; +import org.apache.archiva.indexer.*; +import org.apache.archiva.proxy.common.WagonFactory; +import org.apache.archiva.proxy.common.WagonFactoryException; +import org.apache.archiva.proxy.common.WagonFactoryRequest; +import org.apache.archiva.repository.*; +import org.apache.archiva.repository.features.IndexCreationFeature; +import org.apache.archiva.repository.features.RemoteIndexFeature; +import org.apache.commons.lang.StringUtils; +import org.apache.maven.index.*; +import org.apache.maven.index.context.IndexCreator; +import org.apache.maven.index.context.IndexingContext; +import org.apache.maven.index.packer.IndexPacker; +import org.apache.maven.index.packer.IndexPackingRequest; +import org.apache.maven.index.updater.IndexUpdateRequest; +import org.apache.maven.index.updater.ResourceFetcher; +import org.apache.maven.index_shaded.lucene.index.IndexFormatTooOldException; +import org.apache.maven.wagon.*; +import org.apache.maven.wagon.authentication.AuthenticationException; +import org.apache.maven.wagon.authentication.AuthenticationInfo; +import org.apache.maven.wagon.authorization.AuthorizationException; +import org.apache.maven.wagon.events.TransferEvent; +import org.apache.maven.wagon.events.TransferListener; +import org.apache.maven.wagon.proxy.ProxyInfo; +import org.apache.maven.wagon.shared.http.AbstractHttpClientWagon; +import org.apache.maven.wagon.shared.http.HttpConfiguration; +import org.apache.maven.wagon.shared.http.HttpMethodConfiguration; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.stereotype.Service; + +import javax.inject.Inject; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.io.InputStream; +import java.net.MalformedURLException; +import java.net.URI; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.Collection; +import java.util.List; +import java.util.Map; +import java.util.concurrent.ConcurrentSkipListSet; +import java.util.stream.Collectors; + +@Service("archivaIndexManager#maven") +public class ArchivaIndexManagerMock implements ArchivaIndexManager { + + private static final Logger log = LoggerFactory.getLogger( ArchivaIndexManagerMock.class ); + + @Inject + private Indexer indexer; + + @Inject + private IndexerEngine indexerEngine; + + @Inject + private List<? extends IndexCreator> indexCreators; + + @Inject + private IndexPacker indexPacker; + + @Inject + private Scanner scanner; + + @Inject + private ArchivaConfiguration archivaConfiguration; + + @Inject + private WagonFactory wagonFactory; + + @Inject + private NetworkProxyAdmin networkProxyAdmin; + + + @Inject + private ArtifactContextProducer artifactContextProducer; + + private ConcurrentSkipListSet<Path> activeContexts = new ConcurrentSkipListSet<>( ); + + private static final int WAIT_TIME = 100; + private static final int MAX_WAIT = 10; + + + public static IndexingContext getMvnContext(ArchivaIndexingContext context ) throws UnsupportedBaseContextException + { + if ( !context.supports( IndexingContext.class ) ) + { + log.error( "The provided archiva index context does not support the maven IndexingContext" ); + throw new UnsupportedBaseContextException( "The context does not support the Maven IndexingContext" ); + } + return context.getBaseContext( IndexingContext.class ); + } + + private Path getIndexPath( ArchivaIndexingContext ctx ) + { + return PathUtil.getPathFromUri( ctx.getPath( ) ); + } + + @FunctionalInterface + interface IndexUpdateConsumer + { + + void accept( IndexingContext indexingContext ) throws IndexUpdateFailedException; + } + + /* + * This method is used to do some actions around the update execution code. And to make sure, that no other + * method is running on the same index. + */ + private void executeUpdateFunction( ArchivaIndexingContext context, IndexUpdateConsumer function ) throws IndexUpdateFailedException + { + IndexingContext indexingContext = null; + try + { + indexingContext = getMvnContext( context ); + } + catch ( UnsupportedBaseContextException e ) + { + throw new IndexUpdateFailedException( "Maven index is not supported by this context", e ); + } + final Path ctxPath = getIndexPath( context ); + int loop = MAX_WAIT; + boolean active = false; + while ( loop-- > 0 && !active ) + { + active = activeContexts.add( ctxPath ); + try + { + Thread.currentThread( ).sleep( WAIT_TIME ); + } + catch ( InterruptedException e ) + { + // Ignore this + } + } + if ( active ) + { + try + { + function.accept( indexingContext ); + } + finally + { + activeContexts.remove( ctxPath ); + } + } + else + { + throw new IndexUpdateFailedException( "Timeout while waiting for index release on context " + context.getId( ) ); + } + } + + @Override + public void pack( final ArchivaIndexingContext context ) throws IndexUpdateFailedException + { + executeUpdateFunction( context, indexingContext -> { + try + { + IndexPackingRequest request = new IndexPackingRequest( indexingContext, + indexingContext.acquireIndexSearcher( ).getIndexReader( ), + indexingContext.getIndexDirectoryFile( ) ); + indexPacker.packIndex( request ); + indexingContext.updateTimestamp( true ); + } + catch ( IOException e ) + { + log.error( "IOException while packing index of context " + context.getId( ) + ( StringUtils.isNotEmpty( e.getMessage( ) ) ? ": " + e.getMessage( ) : "" ) ); + throw new IndexUpdateFailedException( "IOException during update of " + context.getId( ), e ); + } + } + ); + + } + + @Override + public void scan(final ArchivaIndexingContext context) throws IndexUpdateFailedException + { + executeUpdateFunction( context, indexingContext -> { + DefaultScannerListener listener = new DefaultScannerListener( indexingContext, indexerEngine, true, null ); + ScanningRequest request = new ScanningRequest( indexingContext, listener ); + ScanningResult result = scanner.scan( request ); + if ( result.hasExceptions( ) ) + { + log.error( "Exceptions occured during index scan of " + context.getId( ) ); + result.getExceptions( ).stream( ).map( e -> e.getMessage( ) ).distinct( ).limit( 5 ).forEach( + s -> log.error( "Message: " + s ) + ); + } + + } ); + } + + @Override + public void update(final ArchivaIndexingContext context, final boolean fullUpdate) throws IndexUpdateFailedException + { + log.info( "start download remote index for remote repository {}", context.getRepository( ).getId( ) ); + URI remoteUpdateUri; + if ( !( context.getRepository( ) instanceof RemoteRepository) || !(context.getRepository().supportsFeature(RemoteIndexFeature.class)) ) + { + throw new IndexUpdateFailedException( "The context is not associated to a remote repository with remote index " + context.getId( ) ); + } else { + RemoteIndexFeature rif = context.getRepository().getFeature(RemoteIndexFeature.class).get(); + remoteUpdateUri = context.getRepository().getLocation().resolve(rif.getIndexUri()); + } + final RemoteRepository remoteRepository = (RemoteRepository) context.getRepository( ); + + executeUpdateFunction( context, + indexingContext -> { + try + { + // create a temp directory to download files + Path tempIndexDirectory = Paths.get( indexingContext.getIndexDirectoryFile( ).getParent( ), ".tmpIndex" ); + Path indexCacheDirectory = Paths.get( indexingContext.getIndexDirectoryFile( ).getParent( ), ".indexCache" ); + Files.createDirectories( indexCacheDirectory ); + if ( Files.exists( tempIndexDirectory ) ) + { + org.apache.archiva.common.utils.FileUtils.deleteDirectory( tempIndexDirectory ); + } + Files.createDirectories( tempIndexDirectory ); + tempIndexDirectory.toFile( ).deleteOnExit( ); + String baseIndexUrl = indexingContext.getIndexUpdateUrl( ); + + String wagonProtocol = remoteUpdateUri.toURL( ).getProtocol( ); + + NetworkProxy networkProxy = null; + if ( remoteRepository.supportsFeature( RemoteIndexFeature.class ) ) + { + RemoteIndexFeature rif = remoteRepository.getFeature( RemoteIndexFeature.class ).get( ); + if ( StringUtils.isNotBlank( rif.getProxyId( ) ) ) + { + try + { + networkProxy = networkProxyAdmin.getNetworkProxy( rif.getProxyId( ) ); + } + catch ( RepositoryAdminException e ) + { + log.error( "Error occured while retrieving proxy {}", e.getMessage( ) ); + } + if ( networkProxy == null ) + { + log.warn( + "your remote repository is configured to download remote index trought a proxy we cannot find id:{}", + rif.getProxyId( ) ); + } + } + + final StreamWagon wagon = (StreamWagon) wagonFactory.getWagon( + new WagonFactoryRequest( wagonProtocol, remoteRepository.getExtraHeaders( ) ).networkProxy( + networkProxy ) + ); + int readTimeout = (int) rif.getDownloadTimeout( ).toMillis( ) * 1000; + wagon.setReadTimeout( readTimeout ); + wagon.setTimeout( (int) remoteRepository.getTimeout( ).toMillis( ) * 1000 ); + + if ( wagon instanceof AbstractHttpClientWagon) + { + HttpConfiguration httpConfiguration = new HttpConfiguration( ); + HttpMethodConfiguration httpMethodConfiguration = new HttpMethodConfiguration( ); + httpMethodConfiguration.setUsePreemptive( true ); + httpMethodConfiguration.setReadTimeout( readTimeout ); + httpConfiguration.setGet( httpMethodConfiguration ); + AbstractHttpClientWagon.class.cast( wagon ).setHttpConfiguration( httpConfiguration ); + } + + wagon.addTransferListener( new DownloadListener( ) ); + ProxyInfo proxyInfo = null; + if ( networkProxy != null ) + { + proxyInfo = new ProxyInfo( ); + proxyInfo.setType( networkProxy.getProtocol( ) ); + proxyInfo.setHost( networkProxy.getHost( ) ); + proxyInfo.setPort( networkProxy.getPort( ) ); + proxyInfo.setUserName( networkProxy.getUsername( ) ); + proxyInfo.setPassword( networkProxy.getPassword( ) ); + } + AuthenticationInfo authenticationInfo = null; + if ( remoteRepository.getLoginCredentials( ) != null && ( remoteRepository.getLoginCredentials( ) instanceof PasswordCredentials) ) + { + PasswordCredentials creds = (PasswordCredentials) remoteRepository.getLoginCredentials( ); + authenticationInfo = new AuthenticationInfo( ); + authenticationInfo.setUserName( creds.getUsername( ) ); + authenticationInfo.setPassword( new String( creds.getPassword( ) ) ); + } + wagon.connect( new org.apache.maven.wagon.repository.Repository( remoteRepository.getId( ), baseIndexUrl ), authenticationInfo, + proxyInfo ); + + Path indexDirectory = indexingContext.getIndexDirectoryFile( ).toPath( ); + if ( !Files.exists( indexDirectory ) ) + { + Files.createDirectories( indexDirectory ); + } + + ResourceFetcher resourceFetcher = + new WagonResourceFetcher( log, tempIndexDirectory, wagon, remoteRepository ); + IndexUpdateRequest request = new IndexUpdateRequest( indexingContext, resourceFetcher ); + request.setForceFullUpdate( fullUpdate ); + request.setLocalIndexCacheDir( indexCacheDirectory.toFile( ) ); + + // indexUpdater.fetchAndUpdateIndex( request ); + + indexingContext.updateTimestamp( true ); + } + + } + catch ( AuthenticationException e ) + { + log.error( "Could not login to the remote proxy for updating index of {}", remoteRepository.getId( ), e ); + throw new IndexUpdateFailedException( "Login in to proxy failed while updating remote repository " + remoteRepository.getId( ), e ); + } + catch ( ConnectionException e ) + { + log.error( "Connection error during index update for remote repository {}", remoteRepository.getId( ), e ); + throw new IndexUpdateFailedException( "Connection error during index update for remote repository " + remoteRepository.getId( ), e ); + } + catch ( MalformedURLException e ) + { + log.error( "URL for remote index update of remote repository {} is not correct {}", remoteRepository.getId( ), remoteUpdateUri, e ); + throw new IndexUpdateFailedException( "URL for remote index update of repository is not correct " + remoteUpdateUri, e ); + } + catch ( IOException e ) + { + log.error( "IOException during index update of remote repository {}: {}", remoteRepository.getId( ), e.getMessage( ), e ); + throw new IndexUpdateFailedException( "IOException during index update of remote repository " + remoteRepository.getId( ) + + ( StringUtils.isNotEmpty( e.getMessage( ) ) ? ": " + e.getMessage( ) : "" ), e ); + } + catch ( WagonFactoryException e ) + { + log.error( "Wagon for remote index download of {} could not be created: {}", remoteRepository.getId( ), e.getMessage( ), e ); + throw new IndexUpdateFailedException( "Error while updating the remote index of " + remoteRepository.getId( ), e ); + } + } ); + + } + + @Override + public void addArtifactsToIndex( final ArchivaIndexingContext context, final Collection<URI> artifactReference ) throws IndexUpdateFailedException + { + final URI ctxUri = context.getPath(); + executeUpdateFunction(context, indexingContext -> { + Collection<ArtifactContext> artifacts = artifactReference.stream().map(r -> artifactContextProducer.getArtifactContext(indexingContext, Paths.get(ctxUri.resolve(r)).toFile())).collect(Collectors.toList()); + try { + indexer.addArtifactsToIndex(artifacts, indexingContext); + } catch (IOException e) { + log.error("IOException while adding artifact {}", e.getMessage(), e); + throw new IndexUpdateFailedException("Error occured while adding artifact to index of "+context.getId() + + (StringUtils.isNotEmpty(e.getMessage()) ? ": "+e.getMessage() : "")); + } + }); + } + + @Override + public void removeArtifactsFromIndex( ArchivaIndexingContext context, Collection<URI> artifactReference ) throws IndexUpdateFailedException + { + final URI ctxUri = context.getPath(); + executeUpdateFunction(context, indexingContext -> { + Collection<ArtifactContext> artifacts = artifactReference.stream().map(r -> artifactContextProducer.getArtifactContext(indexingContext, Paths.get(ctxUri.resolve(r)).toFile())).collect(Collectors.toList()); + try { + indexer.deleteArtifactsFromIndex(artifacts, indexingContext); + } catch (IOException e) { + log.error("IOException while removing artifact {}", e.getMessage(), e); + throw new IndexUpdateFailedException("Error occured while removing artifact from index of "+context.getId() + + (StringUtils.isNotEmpty(e.getMessage()) ? ": "+e.getMessage() : "")); + } + }); + + } + + @Override + public boolean supportsRepository( RepositoryType type ) + { + return type == RepositoryType.MAVEN; + } + + @Override + public ArchivaIndexingContext createContext( Repository repository ) throws IndexCreationFailedException + { + log.debug("Creating context for repo {}, type: {}", repository.getId(), repository.getType()); + if ( repository.getType( ) != RepositoryType.MAVEN ) + { + throw new UnsupportedRepositoryTypeException( repository.getType( ) ); + } + IndexingContext mvnCtx = null; + try + { + if ( repository instanceof RemoteRepository ) + { + mvnCtx = createRemoteContext( (RemoteRepository) repository ); + } + else if ( repository instanceof ManagedRepository ) + { + mvnCtx = createManagedContext( (ManagedRepository) repository ); + } + } + catch ( IOException e ) + { + log.error( "IOException during context creation " + e.getMessage( ), e ); + throw new IndexCreationFailedException( "Could not create index context for repository " + repository.getId( ) + + ( StringUtils.isNotEmpty( e.getMessage( ) ) ? ": " + e.getMessage( ) : "" ), e ); + } + MavenIndexContextMock context = new MavenIndexContextMock( repository, mvnCtx ); + + return context; + } + + @Override + public ArchivaIndexingContext reset(ArchivaIndexingContext context) throws IndexUpdateFailedException { + ArchivaIndexingContext ctx; + executeUpdateFunction(context, indexingContext -> { + try { + indexingContext.close(true); + } catch (IOException e) { + log.warn("Index close failed"); + } + try { + FileUtils.deleteDirectory(Paths.get(context.getPath())); + } catch (IOException e) { + throw new IndexUpdateFailedException("Could not delete index files"); + } + }); + try { + Repository repo = context.getRepository(); + ctx = createContext(context.getRepository()); + if (repo instanceof EditableRepository) { + ((EditableRepository)repo).setIndexingContext(ctx); + } + } catch (IndexCreationFailedException e) { + throw new IndexUpdateFailedException("Could not create index"); + } + return ctx; + } + + @Override + public ArchivaIndexingContext move(ArchivaIndexingContext context, Repository repo) throws IndexCreationFailedException { + if (context==null) { + return null; + } + if (context.supports(IndexingContext.class)) { + try { + Path newPath = getIndexPath(repo); + IndexingContext ctx = context.getBaseContext(IndexingContext.class); + Path oldPath = ctx.getIndexDirectoryFile().toPath(); + if (oldPath.equals(newPath)) { + // Nothing to do, if path does not change + return context; + } + if (!Files.exists(oldPath)) { + return createContext(repo); + } else if (context.isEmpty()) { + context.close(); + return createContext(repo); + } else { + context.close(false); + Files.move(oldPath, newPath); + return createContext(repo); + } + } catch (IOException e) { + log.error("IOException while moving index directory {}", e.getMessage(), e); + throw new IndexCreationFailedException("Could not recreated the index.", e); + } catch (UnsupportedBaseContextException e) { + throw new IndexCreationFailedException("The given context, is not a maven context."); + } + } else { + throw new IndexCreationFailedException("Bad context type. This is not a maven context."); + } + } + + private Path getIndexPath(Repository repo) throws IOException { + IndexCreationFeature icf = repo.getFeature(IndexCreationFeature.class).get(); + Path repoDir = repo.getLocalPath(); + URI indexDir = icf.getIndexPath(); + Path indexDirectory = null; + if ( ! StringUtils.isEmpty(indexDir.toString( ) ) ) + { + + indexDirectory = PathUtil.getPathFromUri( indexDir ); + // not absolute so create it in repository directory + if ( !indexDirectory.isAbsolute( ) ) + { + indexDirectory = repoDir.resolve( indexDirectory ); + } + } + else + { + indexDirectory = repoDir.resolve( ".index" ); + } + + if ( !Files.exists( indexDirectory ) ) + { + Files.createDirectories( indexDirectory ); + } + return indexDirectory; + } + + private IndexingContext createRemoteContext(RemoteRepository remoteRepository ) throws IOException + { + Path appServerBase = archivaConfiguration.getAppServerBaseDir( ); + + String contextKey = "remote-" + remoteRepository.getId( ); + + + // create remote repository path + Path repoDir = remoteRepository.getLocalPath(); + if ( !Files.exists( repoDir ) ) + { + Files.createDirectories( repoDir ); + } + + Path indexDirectory = null; + + // is there configured indexDirectory ? + if ( remoteRepository.supportsFeature( RemoteIndexFeature.class ) ) + { + RemoteIndexFeature rif = remoteRepository.getFeature( RemoteIndexFeature.class ).get( ); + indexDirectory = getIndexPath(remoteRepository); + String remoteIndexUrl = calculateIndexRemoteUrl( remoteRepository.getLocation( ), rif ); + try + { + + return getIndexingContext( remoteRepository, contextKey, repoDir, indexDirectory, remoteIndexUrl ); + } + catch ( IndexFormatTooOldException e ) + { + // existing index with an old lucene format so we need to delete it!!! + // delete it first then recreate it. + log.warn( "the index of repository {} is too old we have to delete and recreate it", // + remoteRepository.getId( ) ); + org.apache.archiva.common.utils.FileUtils.deleteDirectory( indexDirectory ); + return getIndexingContext( remoteRepository, contextKey, repoDir, indexDirectory, remoteIndexUrl ); + + } + } + else + { + throw new IOException( "No remote index defined" ); + } + } + + private IndexingContext getIndexingContext( Repository repository, String contextKey, Path repoDir, Path indexDirectory, String indexUrl ) throws IOException + { + return indexer.createIndexingContext( contextKey, repository.getId( ), repoDir.toFile( ), indexDirectory.toFile( ), + repository.getLocation( ) == null ? null : repository.getLocation( ).toString( ), + indexUrl, + true, false, + indexCreators ); + } + + private IndexingContext createManagedContext( ManagedRepository repository ) throws IOException + { + + IndexingContext context; + // take care first about repository location as can be relative + Path repositoryDirectory = repository.getLocalPath(); + + if ( !Files.exists( repositoryDirectory ) ) + { + try + { + Files.createDirectories( repositoryDirectory ); + } + catch ( IOException e ) + { + log.error( "Could not create directory {}", repositoryDirectory ); + } + } + + Path indexDirectory = null; + + if ( repository.supportsFeature( IndexCreationFeature.class ) ) + { + indexDirectory = getIndexPath(repository); + + String indexUrl = repositoryDirectory.toUri( ).toURL( ).toExternalForm( ); + try + { + context = getIndexingContext( repository, repository.getId( ), repositoryDirectory, indexDirectory, indexUrl ); + context.setSearchable( repository.isScanned( ) ); + } + catch ( IndexFormatTooOldException e ) + { + // existing index with an old lucene format so we need to delete it!!! + // delete it first then recreate it. + log.warn( "the index of repository {} is too old we have to delete and recreate it", // + repository.getId( ) ); + org.apache.archiva.common.utils.FileUtils.deleteDirectory( indexDirectory ); + context = getIndexingContext( repository, repository.getId( ), repositoryDirectory, indexDirectory, indexUrl ); + context.setSearchable( repository.isScanned( ) ); + } + return context; + } + else + { + throw new IOException( "No repository index defined" ); + } + } + + private String calculateIndexRemoteUrl( URI baseUri, RemoteIndexFeature rif ) + { + if ( rif.getIndexUri( ) == null ) + { + return baseUri.resolve( ".index" ).toString( ); + } + else + { + return baseUri.resolve( rif.getIndexUri( ) ).toString( ); + } + } + + private static final class DownloadListener + implements TransferListener + { + private Logger log = LoggerFactory.getLogger( getClass( ) ); + + private String resourceName; + + private long startTime; + + private int totalLength = 0; + + @Override + public void transferInitiated( TransferEvent transferEvent ) + { + startTime = System.currentTimeMillis( ); + resourceName = transferEvent.getResource( ).getName( ); + log.debug( "initiate transfer of {}", resourceName ); + } + + @Override + public void transferStarted( TransferEvent transferEvent ) + { + this.totalLength = 0; + resourceName = transferEvent.getResource( ).getName( ); + log.info( "start transfer of {}", transferEvent.getResource( ).getName( ) ); + } + + @Override + public void transferProgress( TransferEvent transferEvent, byte[] buffer, int length ) + { + log.debug( "transfer of {} : {}/{}", transferEvent.getResource( ).getName( ), buffer.length, length ); + this.totalLength += length; + } + + @Override + public void transferCompleted( TransferEvent transferEvent ) + { + resourceName = transferEvent.getResource( ).getName( ); + long endTime = System.currentTimeMillis( ); + log.info( "end of transfer file {} {} kb: {}s", transferEvent.getResource( ).getName( ), + this.totalLength / 1024, ( endTime - startTime ) / 1000 ); + } + + @Override + public void transferError( TransferEvent transferEvent ) + { + log.info( "error of transfer file {}: {}", transferEvent.getResource( ).getName( ), + transferEvent.getException( ).getMessage( ), transferEvent.getException( ) ); + } + + @Override + public void debug( String message ) + { + log.debug( "transfer debug {}", message ); + } + } + + private static class WagonResourceFetcher + implements ResourceFetcher + { + + Logger log; + + Path tempIndexDirectory; + + Wagon wagon; + + RemoteRepository remoteRepository; + + private WagonResourceFetcher( Logger log, Path tempIndexDirectory, Wagon wagon, + RemoteRepository remoteRepository ) + { + this.log = log; + this.tempIndexDirectory = tempIndexDirectory; + this.wagon = wagon; + this.remoteRepository = remoteRepository; + } + + @Override + public void connect( String id, String url ) + throws IOException + { + //no op + } + + @Override + public void disconnect( ) + throws IOException + { + // no op + } + + @Override + public InputStream retrieve(String name ) + throws IOException, FileNotFoundException + { + try + { + log.info( "index update retrieve file, name:{}", name ); + Path file = tempIndexDirectory.resolve( name ); + Files.deleteIfExists( file ); + file.toFile( ).deleteOnExit( ); + wagon.get( addParameters( name, remoteRepository ), file.toFile( ) ); + return Files.newInputStream( file ); + } + catch ( AuthorizationException | TransferFailedException e ) + { + throw new IOException( e.getMessage( ), e ); + } + catch ( ResourceDoesNotExistException e ) + { + FileNotFoundException fnfe = new FileNotFoundException( e.getMessage( ) ); + fnfe.initCause( e ); + throw fnfe; + } + } + + // FIXME remove crappy copy/paste + protected String addParameters( String path, RemoteRepository remoteRepository ) + { + if ( remoteRepository.getExtraParameters( ).isEmpty( ) ) + { + return path; + } + + boolean question = false; + + StringBuilder res = new StringBuilder( path == null ? "" : path ); + + for ( Map.Entry<String, String> entry : remoteRepository.getExtraParameters( ).entrySet( ) ) + { + if ( !question ) + { + res.append( '?' ).append( entry.getKey( ) ).append( '=' ).append( entry.getValue( ) ); + } + } + + return res.toString( ); + } + + } +} diff --git a/archiva-modules/archiva-base/archiva-repository-admin/archiva-repository-admin-default/src/test/java/org/apache/archiva/admin/mock/MavenIndexContextMock.java b/archiva-modules/archiva-base/archiva-repository-admin/archiva-repository-admin-default/src/test/java/org/apache/archiva/admin/mock/MavenIndexContextMock.java new file mode 100644 index 000000000..1b6a54b01 --- /dev/null +++ b/archiva-modules/archiva-base/archiva-repository-admin/archiva-repository-admin-default/src/test/java/org/apache/archiva/admin/mock/MavenIndexContextMock.java @@ -0,0 +1,136 @@ +package org.apache.archiva.admin.mock; + +/* + * 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.indexer.ArchivaIndexingContext; +import org.apache.archiva.repository.Repository; +import org.apache.maven.index.context.IndexingContext; + +import java.io.IOException; +import java.net.URI; +import java.nio.file.Files; +import java.nio.file.NoSuchFileException; +import java.sql.Date; +import java.time.ZonedDateTime; +import java.util.Set; + +/** + * Maven implementation of index context + */ +public class MavenIndexContextMock implements ArchivaIndexingContext { + + private IndexingContext delegate; + private Repository repository; + + MavenIndexContextMock(Repository repository, IndexingContext delegate) { + this.delegate = delegate; + this.repository = repository; + + } + + @Override + public String getId() { + return delegate.getId(); + } + + @Override + public Repository getRepository() { + return repository; + } + + @Override + public URI getPath() { + return delegate.getIndexDirectoryFile().toURI(); + } + + @Override + public boolean isEmpty() throws IOException { + return Files.list(delegate.getIndexDirectoryFile().toPath()).count()==0; + } + + @Override + public void commit() throws IOException { + delegate.commit(); + } + + @Override + public void rollback() throws IOException { + delegate.rollback(); + } + + @Override + public void optimize() throws IOException { + delegate.optimize(); + } + + @Override + public void close(boolean deleteFiles) throws IOException { + try { + delegate.close(deleteFiles); + } catch (NoSuchFileException e) { + // Ignore missing directory + } + } + + @Override + public void close() throws IOException { + try { + delegate.close(false); + } catch (NoSuchFileException e) { + // Ignore missing directory + } + } + + @Override + public void purge() throws IOException { + delegate.purge(); + } + + @Override + public boolean supports(Class<?> clazz) { + return IndexingContext.class.equals(clazz); + } + + @Override + public <T> T getBaseContext(Class<T> clazz) throws UnsupportedOperationException { + if (IndexingContext.class.equals(clazz)) { + return (T) delegate; + } else { + throw new UnsupportedOperationException("The class "+clazz+" is not supported by the maven indexer"); + } + } + + @Override + public Set<String> getGroups() throws IOException { + return delegate.getAllGroups(); + } + + @Override + public void updateTimestamp(boolean save) throws IOException { + delegate.updateTimestamp(save); + } + + @Override + public void updateTimestamp(boolean save, ZonedDateTime time) throws IOException { + delegate.updateTimestamp(save, Date.from(time.toInstant())); + } + + +} diff --git a/archiva-modules/archiva-base/archiva-repository-admin/archiva-repository-admin-default/src/test/java/org/apache/archiva/admin/repository/group/RepositoryGroupAdminTest.java b/archiva-modules/archiva-base/archiva-repository-admin/archiva-repository-admin-default/src/test/java/org/apache/archiva/admin/repository/group/RepositoryGroupAdminTest.java index c586f23c6..ed6e28683 100644 --- a/archiva-modules/archiva-base/archiva-repository-admin/archiva-repository-admin-default/src/test/java/org/apache/archiva/admin/repository/group/RepositoryGroupAdminTest.java +++ b/archiva-modules/archiva-base/archiva-repository-admin/archiva-repository-admin-default/src/test/java/org/apache/archiva/admin/repository/group/RepositoryGroupAdminTest.java @@ -24,6 +24,8 @@ import org.apache.archiva.admin.model.beans.RepositoryGroup; import org.apache.archiva.admin.model.group.RepositoryGroupAdmin; import org.apache.archiva.admin.repository.AbstractRepositoryAdminTest; import org.apache.archiva.metadata.model.facets.AuditEvent; +import org.apache.archiva.repository.Repository; +import org.apache.archiva.repository.RepositoryRegistry; import org.junit.Test; import javax.inject.Inject; @@ -39,12 +41,23 @@ public class RepositoryGroupAdminTest @Inject RepositoryGroupAdmin repositoryGroupAdmin; + @Inject + RepositoryRegistry repositoryRegistry; + @Test public void addAndDeleteGroup() throws Exception { try { + Repository repo = repositoryRegistry.getRepository("test-new-one"); + if (repo!=null) { + repositoryRegistry.removeRepository(repo); + } + repo = repositoryRegistry.getRepository("test-new-two"); + if (repo!=null) { + repositoryRegistry.removeRepository(repo); + } ManagedRepository managedRepositoryOne = getTestManagedRepository( "test-new-one", Paths.get(APPSERVER_BASE_PATH,"test-new-one" ).toString()); @@ -55,8 +68,10 @@ public class RepositoryGroupAdminTest managedRepositoryAdmin.addManagedRepository( managedRepositoryTwo, false, getFakeAuditInformation() ); + RepositoryGroup repositoryGroup = new RepositoryGroup( "repo-group-one", Arrays.asList( "test-new-one", "test-new-two" ) ); + // repositoryGroupAdmin.deleteRepositoryGroup("repo-group-one", null); mockAuditListener.clearEvents(); @@ -84,8 +99,8 @@ public class RepositoryGroupAdminTest finally { mockAuditListener.clearEvents(); - managedRepositoryAdmin.deleteManagedRepository( "test-new-one", getFakeAuditInformation(), true ); - managedRepositoryAdmin.deleteManagedRepository( "test-new-two", getFakeAuditInformation(), true ); + repositoryRegistry.removeRepository(repositoryRegistry.getManagedRepository("test-new-one")); + repositoryRegistry.removeRepository(repositoryRegistry.getManagedRepository("test-new-two")); } } @@ -202,8 +217,7 @@ public class RepositoryGroupAdminTest finally { mockAuditListener.clearEvents(); - - managedRepositoryAdmin.deleteManagedRepository( "test-new-two", getFakeAuditInformation(), true ); + repositoryRegistry.removeRepository(repositoryRegistry.getRepository("test-new-two")); } } @@ -231,8 +245,8 @@ public class RepositoryGroupAdminTest finally { mockAuditListener.clearEvents(); - managedRepositoryAdmin.deleteManagedRepository( "test-new-one", getFakeAuditInformation(), true ); - managedRepositoryAdmin.deleteManagedRepository( "test-new-two", getFakeAuditInformation(), true ); + repositoryRegistry.removeRepository(repositoryRegistry.getRepository("test-new-one")); + repositoryRegistry.removeRepository(repositoryRegistry.getRepository("test-new-two")); } } diff --git a/archiva-modules/archiva-base/archiva-repository-admin/archiva-repository-admin-default/src/test/resources/default-archiva.xml b/archiva-modules/archiva-base/archiva-repository-admin/archiva-repository-admin-default/src/test/resources/default-archiva.xml index 795579843..36d467ff7 100644 --- a/archiva-modules/archiva-base/archiva-repository-admin/archiva-repository-admin-default/src/test/resources/default-archiva.xml +++ b/archiva-modules/archiva-base/archiva-repository-admin/archiva-repository-admin-default/src/test/resources/default-archiva.xml @@ -53,6 +53,7 @@ <name>Central Repository</name> <url>https://repo.maven.apache.org/maven2</url> <layout>default</layout> + <indexDir>.index</indexDir> </remoteRepository> </remoteRepositories> diff --git a/archiva-modules/archiva-base/archiva-repository-api/src/main/java/org/apache/archiva/indexer/ArchivaIndexManager.java b/archiva-modules/archiva-base/archiva-repository-api/src/main/java/org/apache/archiva/indexer/ArchivaIndexManager.java index fb34eb2ff..63a8a9297 100644 --- a/archiva-modules/archiva-base/archiva-repository-api/src/main/java/org/apache/archiva/indexer/ArchivaIndexManager.java +++ b/archiva-modules/archiva-base/archiva-repository-api/src/main/java/org/apache/archiva/indexer/ArchivaIndexManager.java @@ -20,6 +20,7 @@ package org.apache.archiva.indexer; */ import org.apache.archiva.repository.Repository; +import org.apache.archiva.repository.RepositoryEventListener; import org.apache.archiva.repository.RepositoryType; import java.net.URI; @@ -75,4 +76,23 @@ public interface ArchivaIndexManager { * @return the index context */ ArchivaIndexingContext createContext(Repository repository) throws IndexCreationFailedException; + + /** + * Reinitializes the index. E.g. remove the files and create a new empty index. + * + * @param context + * @return the new created index + */ + ArchivaIndexingContext reset(ArchivaIndexingContext context) throws IndexUpdateFailedException; + + /** + * Moves the context to a new directory. It's up to the implementation, if a new context is created + * or the context is moved only. + * + * @param context The current context + * @param repo The repository + * @return The new context + * @throws IndexCreationFailedException + */ + ArchivaIndexingContext move(ArchivaIndexingContext context, Repository repo) throws IndexCreationFailedException; } diff --git a/archiva-modules/archiva-base/archiva-repository-api/src/main/java/org/apache/archiva/indexer/GenericIndexManager.java b/archiva-modules/archiva-base/archiva-repository-api/src/main/java/org/apache/archiva/indexer/GenericIndexManager.java index d0f803416..8d8072e32 100644 --- a/archiva-modules/archiva-base/archiva-repository-api/src/main/java/org/apache/archiva/indexer/GenericIndexManager.java +++ b/archiva-modules/archiva-base/archiva-repository-api/src/main/java/org/apache/archiva/indexer/GenericIndexManager.java @@ -20,6 +20,7 @@ package org.apache.archiva.indexer; */ import org.apache.archiva.repository.Repository; +import org.apache.archiva.repository.RepositoryEvent; import org.apache.archiva.repository.RepositoryType; import org.springframework.stereotype.Service; @@ -63,4 +64,15 @@ public class GenericIndexManager implements ArchivaIndexManager { public ArchivaIndexingContext createContext(Repository repository) { return null; } + + @Override + public ArchivaIndexingContext reset(ArchivaIndexingContext context) throws IndexUpdateFailedException { + return null; + } + + @Override + public ArchivaIndexingContext move(ArchivaIndexingContext context, Repository repo) throws IndexCreationFailedException { + return null; + } + } diff --git a/archiva-modules/archiva-base/archiva-repository-api/src/main/java/org/apache/archiva/repository/EditableRepository.java b/archiva-modules/archiva-base/archiva-repository-api/src/main/java/org/apache/archiva/repository/EditableRepository.java index b27549211..7b7dd8f8a 100644 --- a/archiva-modules/archiva-base/archiva-repository-api/src/main/java/org/apache/archiva/repository/EditableRepository.java +++ b/archiva-modules/archiva-base/archiva-repository-api/src/main/java/org/apache/archiva/repository/EditableRepository.java @@ -19,6 +19,8 @@ package org.apache.archiva.repository; * under the License. */ +import org.apache.archiva.indexer.ArchivaIndexingContext; + import java.net.URI; import java.util.Locale; @@ -120,5 +122,11 @@ public interface EditableRepository extends Repository */ void setLayout(String layout); + /** + * Sets the indexing context reference. + * @param context + */ + void setIndexingContext(ArchivaIndexingContext context); + } diff --git a/archiva-modules/archiva-base/archiva-repository-api/src/main/java/org/apache/archiva/repository/Repository.java b/archiva-modules/archiva-base/archiva-repository-api/src/main/java/org/apache/archiva/repository/Repository.java index fae5745dd..78a330a96 100644 --- a/archiva-modules/archiva-base/archiva-repository-api/src/main/java/org/apache/archiva/repository/Repository.java +++ b/archiva-modules/archiva-base/archiva-repository-api/src/main/java/org/apache/archiva/repository/Repository.java @@ -22,6 +22,7 @@ package org.apache.archiva.repository; import org.apache.archiva.indexer.ArchivaIndexingContext; import org.apache.archiva.repository.features.RepositoryFeature; +import java.io.IOException; import java.net.URI; import java.nio.file.Path; import java.util.List; @@ -34,7 +35,7 @@ import java.util.Set; * * Created by Martin Stockhammer on 21.09.17. */ -public interface Repository { +public interface Repository extends RepositoryEventHandler { /** * Return the identifier of the repository. Repository identifier should be unique at least @@ -175,4 +176,10 @@ public interface Repository { * @throws UnsupportedOperationException */ ArchivaIndexingContext getIndexingContext(); + + /** + * Closes all resources that are opened by this repository. + */ + void close(); + } diff --git a/archiva-modules/archiva-base/archiva-repository-api/src/main/java/org/apache/archiva/repository/RepositoryEvent.java b/archiva-modules/archiva-base/archiva-repository-api/src/main/java/org/apache/archiva/repository/RepositoryEvent.java new file mode 100644 index 000000000..d8bdf95fe --- /dev/null +++ b/archiva-modules/archiva-base/archiva-repository-api/src/main/java/org/apache/archiva/repository/RepositoryEvent.java @@ -0,0 +1,69 @@ +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. + */ + +import java.time.LocalDateTime; + +/** + * Repository event. Repository events are used for providing information about repository changes. + * + * @param <T> + */ +public class RepositoryEvent<T> { + + final EventType type; + final String repo; + final T value; + final T oldValue; + final LocalDateTime instant; + + public RepositoryEvent(EventType type, String repo, T oldValue, T value) { + this.type = type; + this.repo = repo; + this.value = value; + this.oldValue = oldValue; + this.instant = LocalDateTime.now(); + } + + public interface EventType { + String name(); + } + + + EventType getType() { + return type; + }; + + String getRepositoryId() { + return repo; + }; + + T getValue() { + return value; + } + + T getOldValue() { + return oldValue; + } + + public LocalDateTime getInstant() { + return instant; + } +} diff --git a/archiva-modules/archiva-base/archiva-repository-api/src/main/java/org/apache/archiva/repository/RepositoryEventHandler.java b/archiva-modules/archiva-base/archiva-repository-api/src/main/java/org/apache/archiva/repository/RepositoryEventHandler.java new file mode 100644 index 000000000..74326270c --- /dev/null +++ b/archiva-modules/archiva-base/archiva-repository-api/src/main/java/org/apache/archiva/repository/RepositoryEventHandler.java @@ -0,0 +1,32 @@ +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. + */ + +/** + * Implementations of this interface are able to handle repository event listeners + */ +public interface RepositoryEventHandler { + + void addListener(RepositoryEventListener listener); + + void removeListener(RepositoryEventListener listener); + + void clearListeners(); +} diff --git a/archiva-modules/archiva-base/archiva-repository-api/src/main/java/org/apache/archiva/repository/RepositoryEventListener.java b/archiva-modules/archiva-base/archiva-repository-api/src/main/java/org/apache/archiva/repository/RepositoryEventListener.java new file mode 100644 index 000000000..0234f34b4 --- /dev/null +++ b/archiva-modules/archiva-base/archiva-repository-api/src/main/java/org/apache/archiva/repository/RepositoryEventListener.java @@ -0,0 +1,28 @@ +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. + */ + +/** + * Listener that accepts repository events. + */ +public interface RepositoryEventListener { + + <T> void raise(RepositoryEvent<T> event); +} diff --git a/archiva-modules/archiva-base/archiva-repository-api/src/main/java/org/apache/archiva/repository/RepositoryProvider.java b/archiva-modules/archiva-base/archiva-repository-api/src/main/java/org/apache/archiva/repository/RepositoryProvider.java index a501514da..4492b01cb 100644 --- a/archiva-modules/archiva-base/archiva-repository-api/src/main/java/org/apache/archiva/repository/RepositoryProvider.java +++ b/archiva-modules/archiva-base/archiva-repository-api/src/main/java/org/apache/archiva/repository/RepositoryProvider.java @@ -37,7 +37,7 @@ import java.util.Set; * * */ -public interface RepositoryProvider +public interface RepositoryProvider extends RepositoryEventListener { /** diff --git a/archiva-modules/archiva-base/archiva-repository-layer/src/main/java/org/apache/archiva/repository/AbstractRepository.java b/archiva-modules/archiva-base/archiva-repository-layer/src/main/java/org/apache/archiva/repository/AbstractRepository.java index c90c5bff6..d63007a52 100644 --- a/archiva-modules/archiva-base/archiva-repository-layer/src/main/java/org/apache/archiva/repository/AbstractRepository.java +++ b/archiva-modules/archiva-base/archiva-repository-layer/src/main/java/org/apache/archiva/repository/AbstractRepository.java @@ -26,26 +26,28 @@ import com.cronutils.parser.CronParser; import org.apache.archiva.common.utils.PathUtil; import org.apache.archiva.indexer.ArchivaIndexingContext; import org.apache.archiva.repository.features.RepositoryFeature; +import org.apache.archiva.repository.features.StagingRepositoryFeature; import org.apache.commons.lang.StringUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import java.io.IOException; import java.net.URI; import java.nio.file.Path; import java.nio.file.Paths; -import java.util.Collections; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Locale; -import java.util.Map; -import java.util.Set; +import java.util.*; /** * Implementation of a repository with the necessary fields for a bare repository. * No features are provided. Capabilities and features must be implemented by concrete classes. * */ -public abstract class AbstractRepository implements EditableRepository +public abstract class AbstractRepository implements EditableRepository, RepositoryEventListener { + + Logger log = LoggerFactory.getLogger(AbstractRepository.class); + private final RepositoryType type; private final String id; private Map<Locale, String> names = new HashMap<>( ); @@ -60,10 +62,13 @@ public abstract class AbstractRepository implements EditableRepository String schedulingDefinition = "0 0 02 * * ?"; private String layout = "default"; public static final CronDefinition CRON_DEFINITION = CronDefinitionBuilder.instanceDefinitionFor(CronType.QUARTZ); + private List<RepositoryEventListener> listeners = new ArrayList<>(); + Map<Class<? extends RepositoryFeature<?>>, RepositoryFeature<?>> featureMap = new HashMap<>( ); protected Path repositoryBase; + private ArchivaIndexingContext indexingContext; public AbstractRepository(RepositoryType type, String id, String name, Path repositoryBase) { this.id = id; @@ -129,7 +134,7 @@ public abstract class AbstractRepository implements EditableRepository @Override public Path getLocalPath() { Path localPath; - if (getLocation().getScheme()=="file" || StringUtils.isEmpty(getLocation().getScheme())) { + if (StringUtils.isEmpty(getLocation().getScheme()) || "file".equals(getLocation().getScheme()) ) { localPath = PathUtil.getPathFromUri(getLocation()); if (localPath.isAbsolute()) { return localPath; @@ -259,8 +264,53 @@ public abstract class AbstractRepository implements EditableRepository } @Override + public void setIndexingContext(ArchivaIndexingContext context) { + this.indexingContext = context; + } + + @Override public ArchivaIndexingContext getIndexingContext() { - // TODO: Implement - return null; + return indexingContext; + } + + @Override + public void close() { + ArchivaIndexingContext ctx = getIndexingContext(); + if (ctx!=null) { + try { + ctx.close(); + } catch (IOException e) { + log.warn("Error during index context close.",e); + } + } + if (supportsFeature(StagingRepositoryFeature.class)) { + StagingRepositoryFeature sf = getFeature(StagingRepositoryFeature.class).get(); + if (sf.getStagingRepository()!=null) { + sf.getStagingRepository().close(); + } + } + clearListeners(); } + + @Override + public <T> void raise(RepositoryEvent<T> event) { + for(RepositoryEventListener listener : listeners) { + listener.raise(event); + } + } + + public void addListener(RepositoryEventListener listener) { + if (!this.listeners.contains(listener)) { + this.listeners.add(listener); + } + } + + public void removeListener(RepositoryEventListener listener) { + this.removeListener(listener); + } + + public void clearListeners() { + this.listeners.clear(); + } + } diff --git a/archiva-modules/archiva-base/archiva-repository-layer/src/main/java/org/apache/archiva/repository/BasicManagedRepository.java b/archiva-modules/archiva-base/archiva-repository-layer/src/main/java/org/apache/archiva/repository/BasicManagedRepository.java index 6c1a28525..8df9883a0 100644 --- a/archiva-modules/archiva-base/archiva-repository-layer/src/main/java/org/apache/archiva/repository/BasicManagedRepository.java +++ b/archiva-modules/archiva-base/archiva-repository-layer/src/main/java/org/apache/archiva/repository/BasicManagedRepository.java @@ -19,10 +19,14 @@ package org.apache.archiva.repository; * under the License. */ +import org.apache.archiva.indexer.ArchivaIndexingContext; import org.apache.archiva.repository.features.ArtifactCleanupFeature; import org.apache.archiva.repository.features.IndexCreationFeature; import org.apache.archiva.repository.features.StagingRepositoryFeature; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import java.io.IOException; import java.nio.file.Path; import java.util.Locale; @@ -35,8 +39,8 @@ import java.util.Locale; public class BasicManagedRepository extends AbstractManagedRepository { + Logger log = LoggerFactory.getLogger(BasicManagedRepository.class); ArtifactCleanupFeature artifactCleanupFeature = new ArtifactCleanupFeature( ); - IndexCreationFeature indexCreationFeature = new IndexCreationFeature( ); StagingRepositoryFeature stagingRepositoryFeature = new StagingRepositoryFeature( ); @@ -60,6 +64,7 @@ public class BasicManagedRepository extends AbstractManagedRepository } private void initFeatures() { + IndexCreationFeature indexCreationFeature = new IndexCreationFeature(this.getId(), this); addFeature( artifactCleanupFeature ); addFeature( indexCreationFeature ); addFeature( stagingRepositoryFeature ); diff --git a/archiva-modules/archiva-base/archiva-repository-layer/src/main/java/org/apache/archiva/repository/BasicRemoteRepository.java b/archiva-modules/archiva-base/archiva-repository-layer/src/main/java/org/apache/archiva/repository/BasicRemoteRepository.java index 64b705c3b..70c38a5a0 100644 --- a/archiva-modules/archiva-base/archiva-repository-layer/src/main/java/org/apache/archiva/repository/BasicRemoteRepository.java +++ b/archiva-modules/archiva-base/archiva-repository-layer/src/main/java/org/apache/archiva/repository/BasicRemoteRepository.java @@ -19,8 +19,13 @@ package org.apache.archiva.repository; * under the License. */ +import org.apache.archiva.indexer.ArchivaIndexingContext; +import org.apache.archiva.repository.features.IndexCreationFeature; import org.apache.archiva.repository.features.RemoteIndexFeature; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import java.io.IOException; import java.nio.file.Path; import java.util.Locale; @@ -33,13 +38,17 @@ import java.util.Locale; public class BasicRemoteRepository extends AbstractRemoteRepository { + Logger log = LoggerFactory.getLogger(BasicRemoteRepository.class); + RemoteIndexFeature remoteIndexFeature = new RemoteIndexFeature(); + IndexCreationFeature indexCreationFeature = new IndexCreationFeature(true); static final StandardCapabilities CAPABILITIES = new StandardCapabilities( new ReleaseScheme[] { ReleaseScheme.RELEASE, ReleaseScheme.SNAPSHOT }, new String[] {"default"}, new String[0], new String[] { - RemoteIndexFeature.class.toString() + RemoteIndexFeature.class.toString(), + IndexCreationFeature.class.toString() }, true, true, true, true, true ); public BasicRemoteRepository( String id, String name, Path basePath ) @@ -56,6 +65,7 @@ public class BasicRemoteRepository extends AbstractRemoteRepository private void initFeatures() { addFeature( remoteIndexFeature ); + addFeature( indexCreationFeature ); } @Override diff --git a/archiva-modules/archiva-base/archiva-repository-layer/src/main/java/org/apache/archiva/repository/RepositoryRegistry.java b/archiva-modules/archiva-base/archiva-repository-layer/src/main/java/org/apache/archiva/repository/RepositoryRegistry.java index 557ee9ea8..17a08f760 100644 --- a/archiva-modules/archiva-base/archiva-repository-layer/src/main/java/org/apache/archiva/repository/RepositoryRegistry.java +++ b/archiva-modules/archiva-base/archiva-repository-layer/src/main/java/org/apache/archiva/repository/RepositoryRegistry.java @@ -26,24 +26,22 @@ import org.apache.archiva.configuration.ConfigurationListener; import org.apache.archiva.configuration.IndeterminateConfigurationException; import org.apache.archiva.configuration.ManagedRepositoryConfiguration; import org.apache.archiva.configuration.RemoteRepositoryConfiguration; -import org.apache.archiva.indexer.ArchivaIndexingContext; -import org.apache.archiva.indexer.IndexManagerFactory; +import org.apache.archiva.indexer.*; import org.apache.archiva.redback.components.registry.RegistryException; import org.apache.archiva.repository.features.ArtifactCleanupFeature; +import org.apache.archiva.repository.features.IndexCreationEvent; +import org.apache.archiva.repository.features.IndexCreationFeature; import org.apache.archiva.repository.features.StagingRepositoryFeature; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.stereotype.Service; import javax.annotation.PostConstruct; +import javax.annotation.PreDestroy; import javax.inject.Inject; import javax.inject.Named; -import java.util.Collection; -import java.util.Collections; -import java.util.HashMap; -import java.util.LinkedHashMap; -import java.util.List; -import java.util.Map; +import java.io.IOException; +import java.util.*; import java.util.concurrent.locks.ReentrantReadWriteLock; import java.util.stream.Collectors; import java.util.stream.Stream; @@ -58,7 +56,7 @@ import java.util.stream.Stream; * TODO: Audit events should be sent, but we don't want dependency to the repsitory-metadata-api */ @Service( "repositoryRegistry" ) -public class RepositoryRegistry implements ConfigurationListener { +public class RepositoryRegistry implements ConfigurationListener, RepositoryEventHandler, RepositoryEventListener { private static final Logger log = LoggerFactory.getLogger( RepositoryRegistry.class ); @@ -78,6 +76,7 @@ public class RepositoryRegistry implements ConfigurationListener { @Named("repositoryContentFactory#default") RepositoryContentFactory repositoryContentFactory; + private List<RepositoryEventListener> listeners = new ArrayList<>(); private Map<String, ManagedRepository> managedRepositories = new HashMap<>( ); @@ -98,8 +97,15 @@ public class RepositoryRegistry implements ConfigurationListener { rwLock.writeLock( ).lock( ); try { + log.debug("Initializing repository registry"); + for(ManagedRepository rep : managedRepositories.values()) { + rep.close(); + } managedRepositories.clear( ); managedRepositories.putAll( getManagedRepositoriesFromConfig( ) ); + for (RemoteRepository repo : remoteRepositories.values()) { + repo.close(); + } remoteRepositories.clear( ); remoteRepositories.putAll( getRemoteRepositoriesFromConfig( ) ); // archivaConfiguration.addChangeListener(this); @@ -111,6 +117,18 @@ public class RepositoryRegistry implements ConfigurationListener { } } + @PreDestroy + public void destroy() { + for(ManagedRepository rep : managedRepositories.values()) { + rep.close(); + } + for (RemoteRepository repo : remoteRepositories.values()) { + repo.close(); + } + } + + + private Map<RepositoryType, RepositoryProvider> createProviderMap( ) { Map<RepositoryType, RepositoryProvider> map = new HashMap<>( ); @@ -173,7 +191,9 @@ public class RepositoryRegistry implements ConfigurationListener { private ManagedRepository createNewManagedRepository( RepositoryProvider provider, ManagedRepositoryConfiguration cfg ) throws RepositoryException { + log.debug("Creating repo {}", cfg.getId()); ManagedRepository repo = provider.createManagedInstance( cfg ); + repo.addListener(this); updateRepositoryReferences( provider, repo, cfg , null); return repo; @@ -181,6 +201,7 @@ public class RepositoryRegistry implements ConfigurationListener { private void updateRepositoryReferences(RepositoryProvider provider, ManagedRepository repo, ManagedRepositoryConfiguration cfg, Configuration configuration) throws RepositoryException { + log.debug("Updating references of repo {}",repo.getId()); if ( repo.supportsFeature( StagingRepositoryFeature.class ) ) { StagingRepositoryFeature feature = repo.getFeature( StagingRepositoryFeature.class ).get( ); @@ -194,9 +215,33 @@ public class RepositoryRegistry implements ConfigurationListener { } } } - if ( repo instanceof EditableManagedRepository && repo.getContent() == null) + if ( repo instanceof EditableManagedRepository) { - ( (EditableManagedRepository) repo ).setContent( repositoryContentFactory.getManagedRepositoryContent( repo ) ); + EditableManagedRepository editableRepo = (EditableManagedRepository) repo; + if (repo.getContent()==null) { + editableRepo.setContent(repositoryContentFactory.getManagedRepositoryContent(repo)); + } + log.debug("Index repo: "+repo.hasIndex()); + if (repo.hasIndex() && repo.getIndexingContext()==null) { + log.debug("Creating indexing context for {}", repo.getId()); + createIndexingContext(editableRepo); + } + } + + } + + private ArchivaIndexManager getIndexManager(RepositoryType type) { + return indexManagerFactory.getIndexManager(type); + } + + private void createIndexingContext(EditableRepository editableRepo) throws RepositoryException { + if (editableRepo.supportsFeature(IndexCreationFeature.class)) { + ArchivaIndexManager idxManager = getIndexManager(editableRepo.getType()); + try { + editableRepo.setIndexingContext(idxManager.createContext(editableRepo)); + } catch (IndexCreationFailedException e) { + throw new RepositoryException("Could not create index for repository "+editableRepo.getId()+": "+e.getMessage(),e); + } } } @@ -263,7 +308,9 @@ public class RepositoryRegistry implements ConfigurationListener { private RemoteRepository createNewRemoteRepository( RepositoryProvider provider, RemoteRepositoryConfiguration cfg ) throws RepositoryException { + log.debug("Creating remote repo {}", cfg.getId()); RemoteRepository repo = provider.createRemoteInstance( cfg ); + repo.addListener(this); updateRepositoryReferences( provider, repo, cfg , null); return repo; @@ -273,7 +320,13 @@ public class RepositoryRegistry implements ConfigurationListener { { if ( repo instanceof EditableRemoteRepository && repo.getContent() == null) { - ( (EditableRemoteRepository) repo ).setContent( repositoryContentFactory.getRemoteRepositoryContent( repo ) ); + EditableRemoteRepository editableRepo = (EditableRemoteRepository) repo; + if (repo.getContent()==null) { + editableRepo.setContent( repositoryContentFactory.getRemoteRepositoryContent( repo ) ); + } + if (repo.supportsFeature(IndexCreationFeature.class) && repo.getIndexingContext()==null ) { + createIndexingContext(editableRepo); + } } } @@ -346,12 +399,15 @@ public class RepositoryRegistry implements ConfigurationListener { rwLock.readLock( ).lock( ); try { + log.debug("getRepository {}", repoId); if ( managedRepositories.containsKey( repoId ) ) { + log.debug("Managed repo"); return managedRepositories.get( repoId ); } else { + log.debug("Remote repo"); return remoteRepositories.get( repoId ); } } @@ -422,6 +478,9 @@ public class RepositoryRegistry implements ConfigurationListener { ManagedRepository originRepo = managedRepositories.put( id, managedRepository ); try { + if (originRepo!=null) { + originRepo.close(); + } RepositoryProvider provider = getProvider( managedRepository.getType() ); ManagedRepositoryConfiguration newCfg = provider.getManagedConfiguration( managedRepository ); Configuration configuration = getArchivaConfiguration( ).getConfiguration( ); @@ -521,6 +580,7 @@ public class RepositoryRegistry implements ConfigurationListener { } else { repo = getProvider( repoType ).createManagedInstance( managedRepositoryConfiguration ); + repo.addListener(this); managedRepositories.put(id, repo); } updateRepositoryReferences( getProvider( repoType ), repo, managedRepositoryConfiguration, configuration ); @@ -563,6 +623,9 @@ public class RepositoryRegistry implements ConfigurationListener { RemoteRepositoryConfiguration newCfg=null; try { + if (originRepo!=null) { + originRepo.close(); + } final RepositoryProvider provider = getProvider( remoteRepository.getType() ); newCfg = provider.getRemoteConfiguration( remoteRepository ); updateRepositoryReferences( provider, remoteRepository, newCfg, configuration ); @@ -698,6 +761,7 @@ public class RepositoryRegistry implements ConfigurationListener { } else { repo = getProvider( repoType ).createRemoteInstance( remoteRepositoryConfiguration ); + repo.addListener(this); remoteRepositories.put(id, repo); } updateRepositoryReferences( getProvider( repoType ), repo, remoteRepositoryConfiguration, configuration ); @@ -712,6 +776,12 @@ public class RepositoryRegistry implements ConfigurationListener { } + public void removeRepository(String repoId) throws RepositoryException { + Repository repo = getRepository(repoId); + if (repo!=null) { + removeRepository(repo); + } + } public void removeRepository(Repository repo) throws RepositoryException { if (repo instanceof RemoteRepository ) { @@ -739,6 +809,7 @@ public class RepositoryRegistry implements ConfigurationListener { try { repo = managedRepositories.remove( id ); if (repo!=null) { + repo.close(); Configuration configuration = getArchivaConfiguration().getConfiguration(); ManagedRepositoryConfiguration cfg = configuration.findManagedRepositoryById( id ); if (cfg!=null) { @@ -754,8 +825,7 @@ public class RepositoryRegistry implements ConfigurationListener { log.error("Could not save config after repository removal: {}", e.getMessage(), e); managedRepositories.put(repo.getId(), repo); throw new RepositoryException( "Could not save configuration after repository removal: "+e.getMessage() ); - } - finally + } finally { rwLock.writeLock().unlock(); } @@ -771,13 +841,13 @@ public class RepositoryRegistry implements ConfigurationListener { try { repo = managedRepositories.remove( id ); if (repo!=null) { + repo.close(); ManagedRepositoryConfiguration cfg = configuration.findManagedRepositoryById( id ); if (cfg!=null) { configuration.removeManagedRepository( cfg ); } } - } - finally + } finally { rwLock.writeLock().unlock(); } @@ -800,7 +870,9 @@ public class RepositoryRegistry implements ConfigurationListener { rwLock.writeLock().lock(); try { repo = remoteRepositories.remove( id ); + if (repo!=null) { + repo.close(); Configuration configuration = getArchivaConfiguration().getConfiguration(); RemoteRepositoryConfiguration cfg = configuration.findRemoteRepositoryById( id ); if (cfg!=null) { @@ -816,8 +888,7 @@ public class RepositoryRegistry implements ConfigurationListener { log.error("Could not save config after repository removal: {}", e.getMessage(), e); remoteRepositories.put(repo.getId(), repo); throw new RepositoryException( "Could not save configuration after repository removal: "+e.getMessage() ); - } - finally + } finally { rwLock.writeLock().unlock(); } @@ -833,13 +904,13 @@ public class RepositoryRegistry implements ConfigurationListener { try { repo = remoteRepositories.remove( id ); if (repo!=null) { + repo.close(); RemoteRepositoryConfiguration cfg = configuration.findRemoteRepositoryById( id ); if (cfg!=null) { configuration.removeRemoteRepository( cfg ); } } - } - finally + } finally { rwLock.writeLock().unlock(); } @@ -854,6 +925,20 @@ public class RepositoryRegistry implements ConfigurationListener { initialize(); } + /** + * Resets the indexing context of a given repository. + * + * @param repo + * @throws IndexUpdateFailedException + */ + public void resetIndexingContext(Repository repo) throws IndexUpdateFailedException { + if (repo.hasIndex() && repo instanceof EditableRepository) { + EditableRepository eRepo = (EditableRepository) repo; + ArchivaIndexingContext newCtx = getIndexManager(repo.getType()).reset(repo.getIndexingContext()); + eRepo.setIndexingContext(newCtx); + } + } + /** * Creates a new repository instance with the same settings as this one. The cloned repository is not @@ -871,6 +956,7 @@ public class RepositoryRegistry implements ConfigurationListener { ManagedRepositoryConfiguration cfg = provider.getManagedConfiguration(repo); cfg.setId(newId); ManagedRepository cloned = provider.createManagedInstance(cfg); + cloned.addListener(this); return cloned; } @@ -900,6 +986,7 @@ public class RepositoryRegistry implements ConfigurationListener { RemoteRepositoryConfiguration cfg = provider.getRemoteConfiguration(repo); cfg.setId(newId); RemoteRepository cloned = provider.createRemoteInstance(cfg); + cloned.addListener(this); return cloned; } @@ -910,5 +997,41 @@ public class RepositoryRegistry implements ConfigurationListener { } + @Override + public void addListener(RepositoryEventListener listener) { + if (!this.listeners.contains(listener)) { + this.listeners.add(listener); + } + } + + @Override + public void removeListener(RepositoryEventListener listener) { + this.listeners.remove(listener); + } + + @Override + public void clearListeners() { + this.listeners.clear(); + } + @Override + public <T> void raise(RepositoryEvent<T> event) { + if (event.getType().equals(IndexCreationEvent.Index.URI_CHANGE)) { + if (managedRepositories.containsKey(event.getRepositoryId()) || + remoteRepositories.containsKey(event.getRepositoryId())) { + EditableRepository repo = (EditableRepository) getRepository(event.getRepositoryId()); + if (repo != null && repo.getIndexingContext()!=null) { + try { + ArchivaIndexingContext newCtx = getIndexManager(repo.getType()).move(repo.getIndexingContext(), repo); + repo.setIndexingContext(newCtx); + } catch (IndexCreationFailedException e) { + log.error("Could not move index to new directory {}", e.getMessage(), e); + } + } + } + } + for(RepositoryEventListener listener : listeners) { + listener.raise(event); + } + } } diff --git a/archiva-modules/archiva-base/archiva-repository-layer/src/main/java/org/apache/archiva/repository/features/AbstractFeature.java b/archiva-modules/archiva-base/archiva-repository-layer/src/main/java/org/apache/archiva/repository/features/AbstractFeature.java new file mode 100644 index 000000000..2f5831fea --- /dev/null +++ b/archiva-modules/archiva-base/archiva-repository-layer/src/main/java/org/apache/archiva/repository/features/AbstractFeature.java @@ -0,0 +1,66 @@ +package org.apache.archiva.repository.features; + +/* + * 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.RepositoryEvent; +import org.apache.archiva.repository.RepositoryEventListener; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; + +public class AbstractFeature { + private List<RepositoryEventListener> listener = new ArrayList<>(); + + AbstractFeature() { + + } + + AbstractFeature(RepositoryEventListener listener) { + this.listener.add(listener); + } + + AbstractFeature(Collection<RepositoryEventListener> listeners) { + this.listener.addAll(listeners); + } + + public void addListener(RepositoryEventListener listener) { + if (!this.listener.contains(listener)) { + this.listener.add(listener); + } + this.listener.add(listener); + } + + public void removeListener(RepositoryEventListener listener) { + this.listener.remove(listener); + } + + public void clearListeners() { + this.listener.clear(); + } + + protected void raiseEvent(RepositoryEvent event) { + for(RepositoryEventListener listr : listener) { + listr.raise(event); + } + } + + +} diff --git a/archiva-modules/archiva-base/archiva-repository-layer/src/main/java/org/apache/archiva/repository/features/IndexCreationEvent.java b/archiva-modules/archiva-base/archiva-repository-layer/src/main/java/org/apache/archiva/repository/features/IndexCreationEvent.java new file mode 100644 index 000000000..f871dc98c --- /dev/null +++ b/archiva-modules/archiva-base/archiva-repository-layer/src/main/java/org/apache/archiva/repository/features/IndexCreationEvent.java @@ -0,0 +1,35 @@ +package org.apache.archiva.repository.features; + +/* + * 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.RepositoryEvent; + +import java.net.URI; + +public class IndexCreationEvent extends RepositoryEvent<URI> { + + public enum Index implements EventType { + URI_CHANGE + } + + IndexCreationEvent(String repo, URI oldValue, URI value) { + super(Index.URI_CHANGE, repo, oldValue, value); + } +} diff --git a/archiva-modules/archiva-base/archiva-repository-layer/src/main/java/org/apache/archiva/repository/features/IndexCreationFeature.java b/archiva-modules/archiva-base/archiva-repository-layer/src/main/java/org/apache/archiva/repository/features/IndexCreationFeature.java index 9c6b70c14..eaf532fac 100644 --- a/archiva-modules/archiva-base/archiva-repository-layer/src/main/java/org/apache/archiva/repository/features/IndexCreationFeature.java +++ b/archiva-modules/archiva-base/archiva-repository-layer/src/main/java/org/apache/archiva/repository/features/IndexCreationFeature.java @@ -20,26 +20,36 @@ package org.apache.archiva.repository.features; */ +import org.apache.archiva.repository.Repository; +import org.apache.archiva.repository.RepositoryEventListener; import org.apache.commons.lang.StringUtils; import java.net.URI; import java.net.URISyntaxException; +import java.util.ArrayList; +import java.util.EventListener; +import java.util.List; /** * * This feature provides some information about index creation. * */ -public class IndexCreationFeature implements RepositoryFeature<IndexCreationFeature> { +public class IndexCreationFeature extends AbstractFeature implements RepositoryFeature<IndexCreationFeature>{ + private boolean skipPackedIndexCreation = false; private URI indexPath; - public IndexCreationFeature() { + private String repo; + + public IndexCreationFeature(String repoId, RepositoryEventListener listener) { + super(listener); + this.repo = repoId; try { - this.indexPath = new URI(".indexer"); + setIndexPath(new URI(".indexer")); } catch ( URISyntaxException e ) { @@ -89,7 +99,10 @@ public class IndexCreationFeature implements RepositoryFeature<IndexCreationFeat */ public void setIndexPath( URI indexPath ) { + URI oldVal = this.indexPath; this.indexPath = indexPath; + raiseEvent(new IndexCreationEvent(repo, oldVal, this.indexPath)); + } diff --git a/archiva-modules/archiva-base/archiva-repository-layer/src/test/java/org/apache/archiva/repository/mock/ArchivaIndexManagerMock.java b/archiva-modules/archiva-base/archiva-repository-layer/src/test/java/org/apache/archiva/repository/mock/ArchivaIndexManagerMock.java new file mode 100644 index 000000000..e81bcff08 --- /dev/null +++ b/archiva-modules/archiva-base/archiva-repository-layer/src/test/java/org/apache/archiva/repository/mock/ArchivaIndexManagerMock.java @@ -0,0 +1,85 @@ +package org.apache.archiva.repository.mock; + +/* + * 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.indexer.ArchivaIndexManager; +import org.apache.archiva.indexer.ArchivaIndexingContext; +import org.apache.archiva.indexer.IndexCreationFailedException; +import org.apache.archiva.indexer.IndexUpdateFailedException; +import org.apache.archiva.repository.Repository; +import org.apache.archiva.repository.RepositoryType; +import org.springframework.stereotype.Service; + +import java.net.URI; +import java.util.Collection; + +/** + * @author Martin Stockhammer <martin_s@apache.org> + */ +@Service("archivaIndexManager#maven") +public class ArchivaIndexManagerMock implements ArchivaIndexManager { + + + + @Override + public void pack(ArchivaIndexingContext context) throws IndexUpdateFailedException { + + } + + @Override + public void scan(ArchivaIndexingContext context) throws IndexUpdateFailedException { + + } + + @Override + public void update(ArchivaIndexingContext context, boolean fullUpdate) throws IndexUpdateFailedException { + + } + + @Override + public void addArtifactsToIndex(ArchivaIndexingContext context, Collection<URI> artifactReference) throws IndexUpdateFailedException { + + } + + @Override + public void removeArtifactsFromIndex(ArchivaIndexingContext context, Collection<URI> artifactReference) throws IndexUpdateFailedException { + + } + + @Override + public boolean supportsRepository(RepositoryType type) { + return true; + } + + @Override + public ArchivaIndexingContext createContext(Repository repository) throws IndexCreationFailedException { + return null; + } + + @Override + public ArchivaIndexingContext reset(ArchivaIndexingContext context) throws IndexUpdateFailedException { + return null; + } + + @Override + public ArchivaIndexingContext move(ArchivaIndexingContext context, Repository repo) throws IndexCreationFailedException { + return null; + } +} diff --git a/archiva-modules/archiva-base/archiva-repository-layer/src/test/java/org/apache/archiva/repository/mock/RepositoryProviderMock.java b/archiva-modules/archiva-base/archiva-repository-layer/src/test/java/org/apache/archiva/repository/mock/RepositoryProviderMock.java index d4a78a693..82e10477b 100644 --- a/archiva-modules/archiva-base/archiva-repository-layer/src/test/java/org/apache/archiva/repository/mock/RepositoryProviderMock.java +++ b/archiva-modules/archiva-base/archiva-repository-layer/src/test/java/org/apache/archiva/repository/mock/RepositoryProviderMock.java @@ -21,18 +21,7 @@ package org.apache.archiva.repository.mock; import org.apache.archiva.configuration.ManagedRepositoryConfiguration; import org.apache.archiva.configuration.RemoteRepositoryConfiguration; -import org.apache.archiva.repository.BasicManagedRepository; -import org.apache.archiva.repository.BasicRemoteRepository; -import org.apache.archiva.repository.EditableManagedRepository; -import org.apache.archiva.repository.EditableRemoteRepository; -import org.apache.archiva.repository.ManagedRepository; -import org.apache.archiva.repository.PasswordCredentials; -import org.apache.archiva.repository.ReleaseScheme; -import org.apache.archiva.repository.RemoteRepository; -import org.apache.archiva.repository.RepositoryCredentials; -import org.apache.archiva.repository.RepositoryException; -import org.apache.archiva.repository.RepositoryProvider; -import org.apache.archiva.repository.RepositoryType; +import org.apache.archiva.repository.*; import org.apache.archiva.repository.features.ArtifactCleanupFeature; import org.apache.archiva.repository.features.IndexCreationFeature; import org.apache.archiva.repository.features.RemoteIndexFeature; @@ -230,4 +219,8 @@ public class RepositoryProviderMock implements RepositoryProvider return configuration; } + @Override + public <T> void raise(RepositoryEvent<T> event) { + + } } |