You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@archiva.apache.org by ma...@apache.org on 2019/09/21 22:11:57 UTC

[archiva] branch master updated (0fef7e9 -> 302185e)

This is an automated email from the ASF dual-hosted git repository.

martin_s pushed a change to branch master
in repository https://gitbox.apache.org/repos/asf/archiva.git.


    from 0fef7e9  DOAP information for release 2.2.4
     new b072f69  Proxy changes
     new 9948797  Enhancing repository events
     new d9d8796  Fixing proxy connector handling
     new df8da96  Modifying repository registry behaviour
     new 71919be  Fixing search test
     new 74d69f3  Setting directory hint for root path of asset
     new d9f8834  Adding null checks for index manager
     new 302185e  Migrating servlet to repository registry usage

The 8 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.


Summary of changes:
 .../AbstractRepositoryConnectorConfiguration.java  |    8 +-
 .../src/test/java/RepositoryProviderMock.java      |    3 +-
 .../repository/mock/RepositoryProviderMock.java    |    5 +-
 .../org/apache/archiva/proxy/ProxyRegistry.java    |    9 +-
 .../apache/archiva/proxy/model/ProxyConnector.java |  120 +-
 .../proxy/model/RepositoryProxyHandler.java        |  123 +-
 .../apache/archiva/proxy/ArchivaProxyRegistry.java |   80 +-
 .../proxy/DefaultRepositoryProxyHandler.java       |  349 +++---
 .../archiva/admin/mock/MavenIndexContextMock.java  |    8 +
 .../managed/ManagedRepositoryAdminTest.java        |    1 -
 .../networkproxy/NetworkProxyAdminTest.java        |    3 +-
 .../archiva/indexer/ArchivaIndexingContext.java    |    8 +
 .../org/apache/archiva/repository/Repository.java  |    9 +-
 .../archiva/repository/RepositoryProvider.java     |    1 +
 .../repository/connector/RepositoryConnector.java  |   41 +-
 .../{RepositoryEvent.java => events/Event.java}    |   50 +-
 .../archiva/repository/events/EventType.java}      |   10 +-
 .../{features => events}/IndexCreationEvent.java   |   21 +-
 .../archiva/repository/events/LifecycleEvent.java} |   24 +-
 .../repository/events/RepositoryEvent.java}        |   27 +-
 .../{ => events}/RepositoryEventHandler.java       |   16 +-
 .../{ => events}/RepositoryEventListener.java      |    6 +-
 .../events/RepositoryRegistryEvent.java}           |   22 +-
 .../repository/events/RepositoryValueEvent.java}   |   33 +-
 .../repository/features/AbstractFeature.java       |    6 +-
 .../repository/features/IndexCreationFeature.java  |   51 +-
 .../repository/features/RemoteIndexFeature.java    |   10 +
 .../repository/features/RepositoryFeature.java     |   38 +-
 .../archiva/repository/AbstractRepository.java     |   98 +-
 .../archiva/repository/RepositoryRegistry.java     | 1285 ++++++++++----------
 .../repository/mock/RepositoryProviderMock.java    |    4 +-
 .../repository/storage/FilesystemAsset.java        |    4 +
 .../test/utils/ArchivaSpringJUnit4ClassRunner.java |   15 +
 .../archiva/indexer/maven/MavenIndexContext.java   |   29 +-
 .../archiva/indexer/maven/MavenIndexManager.java   |   16 +-
 .../search/AbstractMavenRepositorySearch.java      |   39 +-
 .../search/MavenRepositorySearchOSGITest.java      |    2 +-
 .../maven/search/MavenRepositorySearchTest.java    |   30 +-
 .../src/test/repo-release/.index/write.lock        |    0
 .../test/repo-release/{.index => .indexer}/_8.fdt  |  Bin
 .../test/repo-release/{.index => .indexer}/_8.fdx  |  Bin
 .../test/repo-release/{.index => .indexer}/_8.fnm  |  Bin
 .../test/repo-release/{.index => .indexer}/_8.nvd  |  Bin
 .../test/repo-release/{.index => .indexer}/_8.nvm  |  Bin
 .../test/repo-release/{.index => .indexer}/_8.si   |  Bin
 .../{.index => .indexer}/_8_Lucene41_0.doc         |  Bin
 .../{.index => .indexer}/_8_Lucene41_0.pos         |  Bin
 .../{.index => .indexer}/_8_Lucene41_0.tim         |  Bin
 .../{.index => .indexer}/_8_Lucene41_0.tip         |  Bin
 .../repo-release/{.index => .indexer}/segments.gen |  Bin
 .../repo-release/{.index => .indexer}/segments_9   |  Bin
 .../repo-release/{.index => .indexer}/timestamp    |  Bin
 .../src/test/repo-release/.indexer/write.lock}     |    0
 .../proxy/maven/MavenRepositoryProxyHandler.java   |   74 +-
 .../archiva/proxy/AbstractProxyTestCase.java       |    9 +-
 .../archiva/proxy/CacheFailuresTransferTest.java   |   18 +-
 .../apache/archiva/proxy/ChecksumTransferTest.java |   40 +-
 .../apache/archiva/proxy/ErrorHandlingTest.java    |    8 +-
 .../archiva/proxy/HttpProxyTransferTest.java       |   27 +-
 .../archiva/proxy/ManagedDefaultTransferTest.java  |   33 +-
 .../apache/archiva/proxy/MetadataTransferTest.java |   12 +-
 .../apache/archiva/proxy/MockConfiguration.java    |    5 +
 .../apache/archiva/proxy/SnapshotTransferTest.java |   18 +-
 .../org/apache/archiva/proxy/WagonDelegate.java    |    8 +-
 .../repository/mock/RepositoryProviderMock.java    |    5 +-
 .../src/test/resources/spring-context.xml          |    6 +-
 .../maven2/ArchivaRepositoryConnectorFactory.java  |    2 +
 .../storage/maven2/Maven2RepositoryStorage.java    |    6 +-
 .../repository/maven2/MavenManagedRepository.java  |    7 +
 .../repository/maven2/MavenRepositoryProvider.java |   20 +-
 .../maven2/DependencyTreeBuilderTestMaven3.java    |    2 +
 ...aven2RepositoryMetadataResolverMRM1411Test.java |    2 +
 .../index/mock/MavenIndexContextMock.java          |    8 +
 .../apache/archiva/mock/MavenIndexContextMock.java |    9 +
 .../rest/services/DefaultBrowseService.java        |    4 +-
 .../archiva/security/mock/MockBeanServices.java    |    3 +-
 archiva-modules/archiva-web/archiva-webdav/pom.xml |    1 +
 .../archiva/webdav/ArchivaDavResourceFactory.java  |   16 +-
 .../apache/archiva/webdav/RepositoryServlet.java   |   48 +-
 .../webdav/AbstractRepositoryServletTestCase.java  |   19 +-
 .../webdav/OverridingRepositoryProxyHandler.java   |    8 +-
 .../archiva/webdav/RepositoryServletTest.java      |    7 +-
 .../repository/storage/RepositoryStorage.java      |    3 +-
 .../cassandra/MockRepositoryStorage.java           |    3 +-
 84 files changed, 1720 insertions(+), 1315 deletions(-)
 rename archiva-modules/archiva-base/archiva-repository-api/src/main/java/org/apache/archiva/repository/{RepositoryEvent.java => events/Event.java} (60%)
 copy archiva-modules/{archiva-web/archiva-webdav/src/main/java/org/apache/archiva/webdav/RepositoryLocator.java => archiva-base/archiva-repository-api/src/main/java/org/apache/archiva/repository/events/EventType.java} (88%)
 rename archiva-modules/archiva-base/archiva-repository-api/src/main/java/org/apache/archiva/repository/{features => events}/IndexCreationEvent.java (57%)
 copy archiva-modules/{metadata/metadata-repository-api/src/main/java/org/apache/archiva/repository/events/AuditListener.java => archiva-base/archiva-repository-api/src/main/java/org/apache/archiva/repository/events/LifecycleEvent.java} (70%)
 copy archiva-modules/{metadata/metadata-repository-api/src/main/java/org/apache/archiva/repository/events/AuditListener.java => archiva-base/archiva-repository-api/src/main/java/org/apache/archiva/repository/events/RepositoryEvent.java} (69%)
 rename archiva-modules/archiva-base/archiva-repository-api/src/main/java/org/apache/archiva/repository/{ => events}/RepositoryEventHandler.java (64%)
 rename archiva-modules/archiva-base/archiva-repository-api/src/main/java/org/apache/archiva/repository/{ => events}/RepositoryEventListener.java (86%)
 copy archiva-modules/{metadata/metadata-repository-api/src/main/java/org/apache/archiva/repository/events/AuditListener.java => archiva-base/archiva-repository-api/src/main/java/org/apache/archiva/repository/events/RepositoryRegistryEvent.java} (75%)
 copy archiva-modules/{metadata/metadata-repository-api/src/main/java/org/apache/archiva/repository/events/AuditListener.java => archiva-base/archiva-repository-api/src/main/java/org/apache/archiva/repository/events/RepositoryValueEvent.java} (59%)
 delete mode 100644 archiva-modules/archiva-maven/archiva-maven-indexer/src/test/repo-release/.index/write.lock
 rename archiva-modules/archiva-maven/archiva-maven-indexer/src/test/repo-release/{.index => .indexer}/_8.fdt (100%)
 rename archiva-modules/archiva-maven/archiva-maven-indexer/src/test/repo-release/{.index => .indexer}/_8.fdx (100%)
 rename archiva-modules/archiva-maven/archiva-maven-indexer/src/test/repo-release/{.index => .indexer}/_8.fnm (100%)
 rename archiva-modules/archiva-maven/archiva-maven-indexer/src/test/repo-release/{.index => .indexer}/_8.nvd (100%)
 rename archiva-modules/archiva-maven/archiva-maven-indexer/src/test/repo-release/{.index => .indexer}/_8.nvm (100%)
 rename archiva-modules/archiva-maven/archiva-maven-indexer/src/test/repo-release/{.index => .indexer}/_8.si (100%)
 rename archiva-modules/archiva-maven/archiva-maven-indexer/src/test/repo-release/{.index => .indexer}/_8_Lucene41_0.doc (100%)
 rename archiva-modules/archiva-maven/archiva-maven-indexer/src/test/repo-release/{.index => .indexer}/_8_Lucene41_0.pos (100%)
 rename archiva-modules/archiva-maven/archiva-maven-indexer/src/test/repo-release/{.index => .indexer}/_8_Lucene41_0.tim (100%)
 rename archiva-modules/archiva-maven/archiva-maven-indexer/src/test/repo-release/{.index => .indexer}/_8_Lucene41_0.tip (100%)
 rename archiva-modules/archiva-maven/archiva-maven-indexer/src/test/repo-release/{.index => .indexer}/segments.gen (100%)
 rename archiva-modules/archiva-maven/archiva-maven-indexer/src/test/repo-release/{.index => .indexer}/segments_9 (100%)
 rename archiva-modules/archiva-maven/archiva-maven-indexer/src/test/repo-release/{.index => .indexer}/timestamp (100%)
 copy archiva-modules/{metadata/test-repository/src/main/resources/org/codehaus/plexus/plexus-spring/1.2/plexus-spring-1.2.jar => archiva-maven/archiva-maven-indexer/src/test/repo-release/.indexer/write.lock} (100%)


[archiva] 08/08: Migrating servlet to repository registry usage

Posted by ma...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

martin_s pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/archiva.git

commit 302185ede1e2928ebbe77349aa839fea477b9d81
Author: Martin Stockhammer <ma...@apache.org>
AuthorDate: Sun Sep 22 00:08:46 2019 +0200

    Migrating servlet to repository registry usage
---
 .../apache/archiva/webdav/RepositoryServlet.java   | 48 +---------------------
 .../webdav/AbstractRepositoryServletTestCase.java  | 11 +++--
 .../archiva/webdav/RepositoryServletTest.java      |  7 ++--
 3 files changed, 12 insertions(+), 54 deletions(-)

diff --git a/archiva-modules/archiva-web/archiva-webdav/src/main/java/org/apache/archiva/webdav/RepositoryServlet.java b/archiva-modules/archiva-web/archiva-webdav/src/main/java/org/apache/archiva/webdav/RepositoryServlet.java
index 800b81b..ef1e6c1 100644
--- a/archiva-modules/archiva-web/archiva-webdav/src/main/java/org/apache/archiva/webdav/RepositoryServlet.java
+++ b/archiva-modules/archiva-web/archiva-webdav/src/main/java/org/apache/archiva/webdav/RepositoryServlet.java
@@ -26,7 +26,6 @@ import org.apache.archiva.configuration.ConfigurationListener;
 import org.apache.archiva.redback.integration.filter.authentication.HttpAuthenticator;
 import org.apache.archiva.repository.ManagedRepository;
 import org.apache.archiva.repository.RepositoryRegistry;
-import org.apache.archiva.repository.storage.StorageAsset;
 import org.apache.archiva.security.ServletAuthenticator;
 import org.apache.jackrabbit.webdav.DavException;
 import org.apache.jackrabbit.webdav.DavLocatorFactory;
@@ -51,10 +50,7 @@ import javax.servlet.ServletException;
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
 import java.io.IOException;
-import java.util.LinkedHashMap;
-import java.util.Map;
 import java.util.concurrent.locks.ReentrantReadWriteLock;
-import java.util.stream.Collectors;
 
 /**
  * RepositoryServlet
@@ -69,8 +65,6 @@ public class RepositoryServlet
 
     RepositoryRegistry repositoryRegistry;
 
-    private Map<String, ManagedRepository> repositoryMap;
-
     private DavLocatorFactory locatorFactory;
 
     private DavResourceFactory resourceFactory;
@@ -176,23 +170,6 @@ public class RepositoryServlet
             configuration.addListener(this);
 
             repositoryRegistry = wac.getBean(RepositoryRegistry.class);
-            repositoryMap = new LinkedHashMap<>();
-
-            fillRepositoryMap();
-
-            for (ManagedRepository repo : repositoryMap.values()) {
-                StorageAsset repoDir = repo.getAsset("");
-
-                if (!repoDir.exists()) {
-                    try {
-                        repoDir.create();
-                    } catch (IOException e) {
-                        log.info("Unable to create missing directory for {}", repo.getLocation());
-                        continue;
-                    }
-                }
-            }
-
             resourceFactory = wac.getBean("davResourceFactory#archiva", DavResourceFactory.class);
             locatorFactory = new ArchivaDavLocatorFactory();
 
@@ -208,17 +185,6 @@ public class RepositoryServlet
         log.debug( "initServers done in {} ms", (end - start) );
     }
 
-    private void fillRepositoryMap() {
-        final Map<String, ManagedRepository> repos = repositoryRegistry.getManagedRepositories().stream().collect(Collectors.toMap(r -> r.getId(), r -> r));
-        rwLock.writeLock().lock();
-        try {
-            repositoryMap.clear();
-            repositoryMap.putAll(repos);
-        } finally {
-            rwLock.writeLock().unlock();
-        }
-    }
-
     @Override
     public void configurationEvent( ConfigurationEvent event )
     {
@@ -245,17 +211,7 @@ public class RepositoryServlet
     public ManagedRepository getRepository( String prefix )
         throws RepositoryAdminException
     {
-        rwLock.readLock().lock();
-        try {
-            if (repositoryMap.isEmpty()) {
-                rwLock.readLock().unlock();
-                fillRepositoryMap();
-                rwLock.readLock().lock();
-            }
-            return repositoryMap.get(prefix);
-        } finally {
-            rwLock.readLock().unlock();
-        }
+        return repositoryRegistry.getManagedRepository( prefix );
     }
 
     ArchivaConfiguration getConfiguration()
@@ -329,8 +285,6 @@ public class RepositoryServlet
             configuration = null;
             locatorFactory = null;
             sessionProvider = null;
-            repositoryMap.clear();
-            repositoryMap = null;
 
             WebApplicationContext wac = WebApplicationContextUtils.getRequiredWebApplicationContext(getServletContext());
 
diff --git a/archiva-modules/archiva-web/archiva-webdav/src/test/java/org/apache/archiva/webdav/AbstractRepositoryServletTestCase.java b/archiva-modules/archiva-web/archiva-webdav/src/test/java/org/apache/archiva/webdav/AbstractRepositoryServletTestCase.java
index 2094ba3..c5b01e3 100644
--- a/archiva-modules/archiva-web/archiva-webdav/src/test/java/org/apache/archiva/webdav/AbstractRepositoryServletTestCase.java
+++ b/archiva-modules/archiva-web/archiva-webdav/src/test/java/org/apache/archiva/webdav/AbstractRepositoryServletTestCase.java
@@ -195,7 +195,10 @@ public abstract class AbstractRepositoryServletTestCase
             }
         } finally
         {
-            ctx.close(  );
+            if (ctx!=null)
+            {
+                ctx.close( );
+            }
         }
 
         CacheManager.getInstance().clearAll();
@@ -727,18 +730,18 @@ public abstract class AbstractRepositoryServletTestCase
 
         if ( Files.exists(repoRootInternal) )
         {
-            org.apache.archiva.common.utils.FileUtils.deleteDirectory( repoRootInternal );
+            org.apache.archiva.common.utils.FileUtils.deleteQuietly( repoRootInternal );
         }
 
         if ( Files.exists(repoRootLegacy) )
         {
-            org.apache.archiva.common.utils.FileUtils.deleteDirectory( repoRootLegacy );
+            org.apache.archiva.common.utils.FileUtils.deleteQuietly( repoRootLegacy );
         }
 
         String appserverBase = System.getProperty( "appserver.base" );
         if ( StringUtils.isNotEmpty( appserverBase ) )
         {
-            org.apache.archiva.common.utils.FileUtils.deleteDirectory( Paths.get( appserverBase ) );
+            org.apache.archiva.common.utils.FileUtils.deleteQuietly( Paths.get( appserverBase ) );
         }
 
     }
diff --git a/archiva-modules/archiva-web/archiva-webdav/src/test/java/org/apache/archiva/webdav/RepositoryServletTest.java b/archiva-modules/archiva-web/archiva-webdav/src/test/java/org/apache/archiva/webdav/RepositoryServletTest.java
index 024d387..909d9c7 100644
--- a/archiva-modules/archiva-web/archiva-webdav/src/test/java/org/apache/archiva/webdav/RepositoryServletTest.java
+++ b/archiva-modules/archiva-web/archiva-webdav/src/test/java/org/apache/archiva/webdav/RepositoryServletTest.java
@@ -79,6 +79,7 @@ public class RepositoryServletTest
         Configuration c = archivaConfiguration.getConfiguration();
         c.removeManagedRepository( c.findManagedRepositoryById( REPOID_INTERNAL ) );
         saveConfiguration( archivaConfiguration );
+        repositoryRegistry.removeRepository( REPOID_INTERNAL );
 
         org.apache.archiva.repository.ManagedRepository repository = servlet.getRepository( REPOID_INTERNAL );
         assertNull( repository );
@@ -117,9 +118,9 @@ public class RepositoryServletTest
     public void testGetRepositoryInvalidPathPassthroughPresent()
         throws Exception
     {
-        String path = REQUEST_PATH + ".index/filecontent/segments.gen";
+        String path = REQUEST_PATH + ".indexer/filecontent/segments.gen";
 
-        populateRepo( repoRootInternal, ".index/filecontent/segments.gen", "index file" );
+        populateRepo( repoRootInternal, ".indexer/filecontent/segments.gen", "index file" );
 
         WebRequest request = new GetMethodWebRequest( path );
         WebResponse response = getServletUnitClient().getResponse( request );
@@ -131,7 +132,7 @@ public class RepositoryServletTest
     public void testGetRepositoryInvalidPathPassthroughMissing()
         throws Exception
     {
-        String path = REQUEST_PATH + ".index/filecontent/foo.bar";
+        String path = REQUEST_PATH + ".indexer/filecontent/foo.bar";
 
         WebRequest request = new GetMethodWebRequest( path );
         WebResponse response = getServletUnitClient().getResponse( request );


[archiva] 04/08: Modifying repository registry behaviour

Posted by ma...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

martin_s pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/archiva.git

commit df8da96f9869522b6fc1b9270927942550555b99
Author: Martin Stockhammer <ma...@apache.org>
AuthorDate: Sat Sep 14 15:15:31 2019 +0200

    Modifying repository registry behaviour
---
 .../archiva/admin/mock/MavenIndexContextMock.java  |   8 +
 .../networkproxy/NetworkProxyAdminTest.java        |   3 +-
 .../archiva/indexer/ArchivaIndexingContext.java    |   8 +
 .../org/apache/archiva/repository/Repository.java  |   7 +
 .../apache/archiva/repository/events/Event.java    |   2 +-
 .../{features => events}/IndexCreationEvent.java   |   4 +-
 .../archiva/repository/events/LifecycleEvent.java  |   2 +-
 .../archiva/repository/events/RepositoryEvent.java |   2 +-
 .../repository/events/RepositoryRegistryEvent.java |   4 +-
 .../repository/features/IndexCreationFeature.java  |  47 +++-
 .../repository/features/RepositoryFeature.java     |  38 ++-
 .../archiva/repository/AbstractRepository.java     |  44 ++--
 .../archiva/repository/RepositoryRegistry.java     | 254 +++++++++++----------
 .../test/utils/ArchivaSpringJUnit4ClassRunner.java |  15 ++
 .../archiva/indexer/maven/MavenIndexContext.java   |  29 ++-
 .../search/AbstractMavenRepositorySearch.java      |  39 +++-
 .../search/MavenRepositorySearchOSGITest.java      |   2 +-
 .../maven/search/MavenRepositorySearchTest.java    |  28 +--
 .../repository/maven2/MavenManagedRepository.java  |   7 +
 .../repository/maven2/MavenRepositoryProvider.java |  16 +-
 ...aven2RepositoryMetadataResolverMRM1411Test.java |   2 +
 .../index/mock/MavenIndexContextMock.java          |   8 +
 .../apache/archiva/mock/MavenIndexContextMock.java |   9 +
 archiva-modules/archiva-web/archiva-webdav/pom.xml |   1 +
 .../webdav/AbstractRepositoryServletTestCase.java  |   8 +-
 25 files changed, 396 insertions(+), 191 deletions(-)

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
index 4b4528b..843df59 100644
--- 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
@@ -40,6 +40,7 @@ import java.util.Set;
  */
 public class MavenIndexContextMock implements ArchivaIndexingContext {
 
+    private boolean open = true;
     private IndexingContext delegate;
     private Repository repository;
     private FilesystemStorage filesystemStorage;
@@ -93,6 +94,7 @@ public class MavenIndexContextMock implements ArchivaIndexingContext {
 
     @Override
     public void close(boolean deleteFiles) throws IOException {
+        open = false;
         try {
             delegate.close(deleteFiles);
         } catch (NoSuchFileException e) {
@@ -102,6 +104,7 @@ public class MavenIndexContextMock implements ArchivaIndexingContext {
 
     @Override
     public void close() throws IOException {
+        open = false;
         try {
             delegate.close(false);
         } catch (NoSuchFileException e) {
@@ -110,6 +113,11 @@ public class MavenIndexContextMock implements ArchivaIndexingContext {
     }
 
     @Override
+    public boolean isOpen() {
+        return open;
+    }
+
+    @Override
     public void purge() throws IOException {
         delegate.purge();
     }
diff --git a/archiva-modules/archiva-base/archiva-repository-admin/archiva-repository-admin-default/src/test/java/org/apache/archiva/admin/repository/networkproxy/NetworkProxyAdminTest.java b/archiva-modules/archiva-base/archiva-repository-admin/archiva-repository-admin-default/src/test/java/org/apache/archiva/admin/repository/networkproxy/NetworkProxyAdminTest.java
index 21020d1..cf8f91b 100644
--- a/archiva-modules/archiva-base/archiva-repository-admin/archiva-repository-admin-default/src/test/java/org/apache/archiva/admin/repository/networkproxy/NetworkProxyAdminTest.java
+++ b/archiva-modules/archiva-base/archiva-repository-admin/archiva-repository-admin-default/src/test/java/org/apache/archiva/admin/repository/networkproxy/NetworkProxyAdminTest.java
@@ -23,6 +23,7 @@ import org.apache.archiva.admin.model.beans.RemoteRepository;
 import org.apache.archiva.admin.model.networkproxy.NetworkProxyAdmin;
 import org.apache.archiva.admin.repository.AbstractRepositoryAdminTest;
 import org.apache.archiva.metadata.model.facets.AuditEvent;
+import org.apache.commons.lang.StringUtils;
 import org.junit.Test;
 
 import javax.inject.Inject;
@@ -157,7 +158,7 @@ public class NetworkProxyAdminTest
 
         remoteRepository = remoteRepositoryAdmin.getRemoteRepository( getRemoteRepository().getId() );
 
-        assertNull( remoteRepository.getRemoteDownloadNetworkProxyId() );
+        assertTrue(StringUtils.isEmpty(remoteRepository.getRemoteDownloadNetworkProxyId()) );
 
         remoteRepositoryAdmin.deleteRemoteRepository( getRemoteRepository().getId(), getFakeAuditInformation() );
     }
diff --git a/archiva-modules/archiva-base/archiva-repository-api/src/main/java/org/apache/archiva/indexer/ArchivaIndexingContext.java b/archiva-modules/archiva-base/archiva-repository-api/src/main/java/org/apache/archiva/indexer/ArchivaIndexingContext.java
index 2dee441..902d21c 100644
--- a/archiva-modules/archiva-base/archiva-repository-api/src/main/java/org/apache/archiva/indexer/ArchivaIndexingContext.java
+++ b/archiva-modules/archiva-base/archiva-repository-api/src/main/java/org/apache/archiva/indexer/ArchivaIndexingContext.java
@@ -90,6 +90,14 @@ public interface ArchivaIndexingContext {
     void close() throws IOException;
 
     /**
+     * Returns the status of this context. This method will return <code>false</code>, after the {@link #close()} method
+     * has been called.
+     *
+     * @return <code>true</code>, if the <code>close()</code> method has not been called, otherwise <code>false</code>
+     */
+    boolean isOpen();
+
+    /**
      * Removes all entries from the index. After this method finished,
      * isEmpty() should return true.
      * @throws IOException
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 9b26143..b26627f 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
@@ -175,5 +175,12 @@ public interface Repository extends RepositoryEventHandler, RepositoryStorage {
      */
     void close();
 
+    /**
+     * Returns the current status of this repository.
+     *
+     * @return <code>true</code>, if repository has not been closed, otherwise <code>false</code>
+     */
+    boolean isOpen();
+
 
 }
diff --git a/archiva-modules/archiva-base/archiva-repository-api/src/main/java/org/apache/archiva/repository/events/Event.java b/archiva-modules/archiva-base/archiva-repository-api/src/main/java/org/apache/archiva/repository/events/Event.java
index afac04c..7ba7f34 100644
--- a/archiva-modules/archiva-base/archiva-repository-api/src/main/java/org/apache/archiva/repository/events/Event.java
+++ b/archiva-modules/archiva-base/archiva-repository-api/src/main/java/org/apache/archiva/repository/events/Event.java
@@ -28,7 +28,7 @@ public class Event<O> {
     final EventType type;
     final LocalDateTime instant;
 
-    public Event(EventType type, O originator) {
+    public <OO extends O> Event(EventType type, OO originator) {
         this.originator = originator;
         this.type = type;
         this.instant = LocalDateTime.now();
diff --git a/archiva-modules/archiva-base/archiva-repository-api/src/main/java/org/apache/archiva/repository/features/IndexCreationEvent.java b/archiva-modules/archiva-base/archiva-repository-api/src/main/java/org/apache/archiva/repository/events/IndexCreationEvent.java
similarity index 91%
rename from archiva-modules/archiva-base/archiva-repository-api/src/main/java/org/apache/archiva/repository/features/IndexCreationEvent.java
rename to archiva-modules/archiva-base/archiva-repository-api/src/main/java/org/apache/archiva/repository/events/IndexCreationEvent.java
index 037ba47..847b679 100644
--- a/archiva-modules/archiva-base/archiva-repository-api/src/main/java/org/apache/archiva/repository/features/IndexCreationEvent.java
+++ b/archiva-modules/archiva-base/archiva-repository-api/src/main/java/org/apache/archiva/repository/events/IndexCreationEvent.java
@@ -1,4 +1,4 @@
-package org.apache.archiva.repository.features;
+package org.apache.archiva.repository.events;
 
 /*
  * Licensed to the Apache Software Foundation (ASF) under one
@@ -20,8 +20,6 @@ package org.apache.archiva.repository.features;
  */
 
 import org.apache.archiva.repository.Repository;
-import org.apache.archiva.repository.events.EventType;
-import org.apache.archiva.repository.events.RepositoryValueEvent;
 
 import java.net.URI;
 
diff --git a/archiva-modules/archiva-base/archiva-repository-api/src/main/java/org/apache/archiva/repository/events/LifecycleEvent.java b/archiva-modules/archiva-base/archiva-repository-api/src/main/java/org/apache/archiva/repository/events/LifecycleEvent.java
index 5f69d1e..2c55dd8 100644
--- a/archiva-modules/archiva-base/archiva-repository-api/src/main/java/org/apache/archiva/repository/events/LifecycleEvent.java
+++ b/archiva-modules/archiva-base/archiva-repository-api/src/main/java/org/apache/archiva/repository/events/LifecycleEvent.java
@@ -27,7 +27,7 @@ public class LifecycleEvent<O> extends RepositoryEvent<O> {
         REGISTERED,UNREGISTERED,UPDATED
     }
 
-    public LifecycleEvent(LifecycleEventType type, O origin, Repository repository) {
+    public <OO extends O> LifecycleEvent(LifecycleEventType type, OO origin, Repository repository) {
         super(type, origin, repository);
     }
 }
diff --git a/archiva-modules/archiva-base/archiva-repository-api/src/main/java/org/apache/archiva/repository/events/RepositoryEvent.java b/archiva-modules/archiva-base/archiva-repository-api/src/main/java/org/apache/archiva/repository/events/RepositoryEvent.java
index dd5550b..7c97b87 100644
--- a/archiva-modules/archiva-base/archiva-repository-api/src/main/java/org/apache/archiva/repository/events/RepositoryEvent.java
+++ b/archiva-modules/archiva-base/archiva-repository-api/src/main/java/org/apache/archiva/repository/events/RepositoryEvent.java
@@ -25,7 +25,7 @@ public class RepositoryEvent<O> extends Event<O> {
 
     private final Repository repository;
 
-    public RepositoryEvent(EventType type, O origin, Repository repository) {
+    public <OO extends O> RepositoryEvent(EventType type, OO origin, Repository repository) {
         super(type, origin);
         this.repository = repository;
     }
diff --git a/archiva-modules/archiva-base/archiva-repository-api/src/main/java/org/apache/archiva/repository/events/RepositoryRegistryEvent.java b/archiva-modules/archiva-base/archiva-repository-api/src/main/java/org/apache/archiva/repository/events/RepositoryRegistryEvent.java
index d9b891c..1a138cf 100644
--- a/archiva-modules/archiva-base/archiva-repository-api/src/main/java/org/apache/archiva/repository/events/RepositoryRegistryEvent.java
+++ b/archiva-modules/archiva-base/archiva-repository-api/src/main/java/org/apache/archiva/repository/events/RepositoryRegistryEvent.java
@@ -19,13 +19,13 @@ package org.apache.archiva.repository.events;
  * under the License.
  */
 
-public class RepositoryRegistryEvent<O> extends Event {
+public class RepositoryRegistryEvent<O> extends Event<O> {
 
     public enum RegistryEventType implements EventType {
         RELOADED,DESTROYED
     }
 
-    public RepositoryRegistryEvent(RegistryEventType type, O origin) {
+    public <OO extends O> RepositoryRegistryEvent(RegistryEventType type, OO origin) {
         super(type, origin);
     }
 }
diff --git a/archiva-modules/archiva-base/archiva-repository-api/src/main/java/org/apache/archiva/repository/features/IndexCreationFeature.java b/archiva-modules/archiva-base/archiva-repository-api/src/main/java/org/apache/archiva/repository/features/IndexCreationFeature.java
index cf7432c..f834be1 100644
--- a/archiva-modules/archiva-base/archiva-repository-api/src/main/java/org/apache/archiva/repository/features/IndexCreationFeature.java
+++ b/archiva-modules/archiva-base/archiva-repository-api/src/main/java/org/apache/archiva/repository/features/IndexCreationFeature.java
@@ -21,6 +21,7 @@ package org.apache.archiva.repository.features;
 
 
 import org.apache.archiva.repository.Repository;
+import org.apache.archiva.repository.events.IndexCreationEvent;
 import org.apache.archiva.repository.events.RepositoryEventListener;
 import org.apache.archiva.repository.storage.StorageAsset;
 import org.apache.commons.lang3.StringUtils;
@@ -33,7 +34,17 @@ import static org.apache.archiva.indexer.ArchivaIndexManager.DEFAULT_PACKED_INDE
 
 /**
  *
- * This feature provides some information about index creation.
+ * This feature provides information about index creation.
+ *
+ * Repositories that support this feature are able to create indexes and download them from remote repositories.
+ *
+ * Repositories may have a normal and packed index. A normal index is used by repository search utilities, the packed
+ * index is for downloading purpose.
+ *
+ * A index may have a remote and a local representation. The remote representation is used for downloading and
+ * updating the local representation.
+ *
+ * The feature is throwing a {@link IndexCreationEvent}, if the URI of the index has been changed.
  *
  */
 public class IndexCreationFeature extends AbstractFeature implements RepositoryFeature<IndexCreationFeature>{
@@ -51,9 +62,9 @@ public class IndexCreationFeature extends AbstractFeature implements RepositoryF
 
     private Repository repo;
 
-    public IndexCreationFeature(Repository repoId, RepositoryEventListener listener) {
+    public IndexCreationFeature(Repository repository, RepositoryEventListener listener) {
         super(listener);
-        this.repo = repoId;
+        this.repo = repository;
         try {
             this.indexPath = new URI(DEFAULT_INDEX_PATH);
             this.packedIndexPath = new URI(DEFAULT_PACKED_INDEX_PATH);
@@ -97,7 +108,9 @@ public class IndexCreationFeature extends AbstractFeature implements RepositoryF
     }
 
     /**
-     * Returns the path that is used to store the index.
+     * Returns the path that is used to store the index. The path may be a absolute URI or relative to the
+     * base URI of the repository.
+     *
      * @return the uri (may be relative or absolute)
      */
     public URI getIndexPath( )
@@ -106,18 +119,26 @@ public class IndexCreationFeature extends AbstractFeature implements RepositoryF
     }
 
     /**
-     * Sets the path that is used to store the index.
+     * Sets the path that is used to store the index. The path may be either absolute or a
+     * path that is relative to the repository storage path (either a local or remote path).
+     *
      * @param indexPath the uri to the index path (may be relative)
      */
     public void setIndexPath( URI indexPath )
     {
-        URI oldVal = this.indexPath;
-        this.indexPath = indexPath;
-        pushEvent(IndexCreationEvent.indexUriChange(this, repo, oldVal, this.indexPath));
+        if ((this.indexPath==null && indexPath!=null) || !this.indexPath.equals(indexPath)) {
+            URI oldVal = this.indexPath;
+            this.indexPath = indexPath;
+            pushEvent(IndexCreationEvent.indexUriChange(this, repo, oldVal, this.indexPath));
+        }
 
     }
 
-
+    /**
+     * Returns true, if this repository has a index defined.
+     *
+     * @return <code>true</code>, if a index path is set, otherwise <code>false</code>
+     */
     public boolean hasIndex() {
         return this.indexPath!=null && !StringUtils.isEmpty( this.indexPath.getPath() );
     }
@@ -132,8 +153,7 @@ public class IndexCreationFeature extends AbstractFeature implements RepositoryF
     }
 
     /**
-     * Sets the path where the index is stored physically. This method should only be used by the
-     * MavenIndexProvider implementations.
+     * Sets the path where the index is stored locally.
      *
      * @param localIndexPath
      */
@@ -152,7 +172,10 @@ public class IndexCreationFeature extends AbstractFeature implements RepositoryF
 
     /**
      * Sets the path (relative or absolute) of the packed index.
-     * @param packedIndexPath
+     *
+     * Throws a {@link IndexCreationEvent.Index#PACKED_INDEX_URI_CHANGE}, if the value changes.
+     *
+     * @param packedIndexPath the new path uri for the packed index
      */
     public void setPackedIndexPath(URI packedIndexPath) {
         URI oldVal = this.packedIndexPath;
diff --git a/archiva-modules/archiva-base/archiva-repository-api/src/main/java/org/apache/archiva/repository/features/RepositoryFeature.java b/archiva-modules/archiva-base/archiva-repository-api/src/main/java/org/apache/archiva/repository/features/RepositoryFeature.java
index a4df8a2..813d39d 100644
--- a/archiva-modules/archiva-base/archiva-repository-api/src/main/java/org/apache/archiva/repository/features/RepositoryFeature.java
+++ b/archiva-modules/archiva-base/archiva-repository-api/src/main/java/org/apache/archiva/repository/features/RepositoryFeature.java
@@ -21,21 +21,57 @@ package org.apache.archiva.repository.features;
 
 
 /**
- * Created by martin on 30.09.17.
+ *
+ * The repository feature holds information about specific features. The may not be available by all repository implementations.
+ * Features should be simple objects for storing additional data, the should not implement too much functionality.
+ * Additional functionality the uses the information in the feature objects should be implemented in the specific repository
+ * provider and repository implementations, or in the repository registry if it is generic.
+ *
+ * But features may throw events, if it's data is changed.
+ *
+ *
+ * This interface is to get access to a concrete feature by accessing the generic interface.
+ *
+ * @param <T> the concrete feature implementation.
+ *
+ * @author Martin Stockhammer <ma...@apache.org>
+ * @since 3.0
  */
 public interface RepositoryFeature<T extends RepositoryFeature<T>> {
 
+    /**
+     * Unique Identifier of this feature. Each feature implementation has its own unique identifier.
+     *
+     * @return the identifier string which should be unique for the implementation class.
+     */
     default String getId() {
         return this.getClass().getName();
     }
 
+    /**
+     * Tells, if this instance is a feature of the given identifier.
+     *
+     * @param featureId the feature identifier string to check
+     * @return true, if this instance is a instance with the feature id, otherwise <code>false</code>
+     */
     default boolean isFeature(String featureId) {
         return this.getClass().getName().equals(featureId);
     }
 
+    /**
+     * Tells, if the this instance is a feature of the given feature class.
+     *
+     * @param clazz The class to check against.
+     * @param <K> the concrete feature implementation.
+     * @return
+     */
     default <K extends RepositoryFeature<K>> boolean isFeature(Class<K> clazz) {
         return this.getClass().equals(clazz);
     }
 
+    /**
+     * Returns the concrete feature instance.
+     * @return the feature instance.
+     */
     T get();
 }
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 d8c9e3b..0f71880 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
@@ -48,6 +48,7 @@ import java.util.List;
 import java.util.Locale;
 import java.util.Map;
 import java.util.Set;
+import java.util.concurrent.atomic.AtomicBoolean;
 import java.util.function.Consumer;
 
 /**
@@ -61,6 +62,9 @@ public abstract class AbstractRepository implements EditableRepository, Reposito
 
     Logger log = LoggerFactory.getLogger(AbstractRepository.class);
 
+    private final AtomicBoolean openStatus = new AtomicBoolean(false);
+
+
     private final RepositoryType type;
     private final String id;
     private Map<Locale, String> names = new HashMap<>(  );
@@ -90,6 +94,7 @@ public abstract class AbstractRepository implements EditableRepository, Reposito
         this.type = type;
         this.storage = repositoryStorage;
         this.location = repositoryStorage.getLocation();
+        this.openStatus.compareAndSet(false, true);
     }
 
     public AbstractRepository(Locale primaryLocale, RepositoryType type, String id, String name, RepositoryStorage repositoryStorage) {
@@ -99,6 +104,7 @@ public abstract class AbstractRepository implements EditableRepository, Reposito
         this.type = type;
         this.storage = repositoryStorage;
         this.location = repositoryStorage.getLocation();
+        this.openStatus.compareAndSet(false, true);
     }
 
     protected void setPrimaryLocale(Locale locale) {
@@ -288,6 +294,9 @@ public abstract class AbstractRepository implements EditableRepository, Reposito
 
     @Override
     public void setIndexingContext(ArchivaIndexingContext context) {
+        if (this.indexingContext!=null) {
+
+        }
         this.indexingContext = context;
     }
 
@@ -298,21 +307,30 @@ public abstract class AbstractRepository implements EditableRepository, Reposito
 
     @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 (this.openStatus.compareAndSet(true, false)) {
+            ArchivaIndexingContext ctx = getIndexingContext();
+            if (ctx != null) {
+                try {
+                    ctx.close();
+                } catch (IOException e) {
+                    log.warn("Error during index context close.", e);
+                }
+                this.indexingContext = null;
+
             }
-        }
-        if (supportsFeature(StagingRepositoryFeature.class)) {
-            StagingRepositoryFeature sf = getFeature(StagingRepositoryFeature.class).get();
-            if (sf.getStagingRepository()!=null) {
-                sf.getStagingRepository().close();
+            if (supportsFeature(StagingRepositoryFeature.class)) {
+                StagingRepositoryFeature sf = getFeature(StagingRepositoryFeature.class).get();
+                if (sf.getStagingRepository() != null) {
+                    sf.getStagingRepository().close();
+                }
             }
+            clearListeners();
         }
-        clearListeners();
+    }
+
+    @Override
+    public boolean isOpen() {
+        return openStatus.get();
     }
 
     @Override
@@ -326,7 +344,7 @@ public abstract class AbstractRepository implements EditableRepository, Reposito
     private void callListeners(Event event, List<RepositoryEventListener> evtListeners) {
         for(RepositoryEventListener listener : evtListeners) {
             try {
-                listener.raise(event);
+                listener.raise(event.recreate(this));
             } catch (Throwable e) {
                 log.error("Could not raise event {} on listener {}: {}", event, listener, e.getMessage());
             }
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 a58f960..28ffc5a 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
@@ -23,7 +23,6 @@ import org.apache.archiva.configuration.*;
 import org.apache.archiva.indexer.*;
 import org.apache.archiva.redback.components.registry.RegistryException;
 import org.apache.archiva.repository.events.*;
-import org.apache.archiva.repository.features.IndexCreationEvent;
 import org.apache.archiva.repository.features.IndexCreationFeature;
 import org.apache.archiva.repository.features.StagingRepositoryFeature;
 import org.apache.commons.lang3.StringUtils;
@@ -50,6 +49,8 @@ import static org.apache.archiva.indexer.ArchivaIndexManager.DEFAULT_INDEX_PATH;
  * configuration save fails the changes are rolled back.
  * <p>
  * TODO: Audit events
+ *
+ * @since 3.0
  */
 @Service("repositoryRegistry")
 public class RepositoryRegistry implements ConfigurationListener, RepositoryEventHandler, RepositoryEventListener {
@@ -98,15 +99,7 @@ public class RepositoryRegistry implements ConfigurationListener, RepositoryEven
         rwLock.writeLock().lock();
         try {
             log.debug("Initializing repository registry");
-            for (ManagedRepository rep : managedRepositories.values()) {
-                rep.close();
-            }
-            managedRepositories.clear();
             updateManagedRepositoriesFromConfig();
-            for (RemoteRepository repo : remoteRepositories.values()) {
-                repo.close();
-            }
-            remoteRepositories.clear();
             updateRemoteRepositoriesFromConfig();
 
             repositoryGroups.clear();
@@ -118,7 +111,7 @@ public class RepositoryRegistry implements ConfigurationListener, RepositoryEven
         } finally {
             rwLock.writeLock().unlock();
         }
-        pushEvent(new RepositoryRegistryEvent(RepositoryRegistryEvent.RegistryEventType.RELOADED, this));
+        pushEvent(new RepositoryRegistryEvent<>(RepositoryRegistryEvent.RegistryEventType.RELOADED, this));
     }
 
     @PreDestroy
@@ -131,7 +124,7 @@ public class RepositoryRegistry implements ConfigurationListener, RepositoryEven
             repo.close();
         }
         remoteRepositories.clear();
-        pushEvent(new RepositoryRegistryEvent(RepositoryRegistryEvent.RegistryEventType.DESTROYED, this));
+        pushEvent(new RepositoryRegistryEvent<>(RepositoryRegistryEvent.RegistryEventType.DESTROYED, this));
     }
 
 
@@ -151,8 +144,13 @@ public class RepositoryRegistry implements ConfigurationListener, RepositoryEven
         return repositoryProviders.stream().filter(repositoryProvider -> repositoryProvider.provides().contains(type)).findFirst().orElseThrow(() -> new RepositoryException("Repository type cannot be handled: " + type));
     }
 
+    /*
+     * Updates the repositories
+     */
     private void updateManagedRepositoriesFromConfig() {
         try {
+
+            Set<String> configRepoIds = new HashSet<>();
             List<ManagedRepositoryConfiguration> managedRepoConfigs =
                     getArchivaConfiguration().getConfiguration().getManagedRepositories();
 
@@ -160,27 +158,23 @@ public class RepositoryRegistry implements ConfigurationListener, RepositoryEven
                 return;
             }
 
-            Map<RepositoryType, RepositoryProvider> providerMap = createProviderMap();
             for (ManagedRepositoryConfiguration repoConfig : managedRepoConfigs) {
-                if (managedRepositories.containsKey(repoConfig.getId())) {
-                    log.warn("Duplicate repository definitions for {} in config found.", repoConfig.getId());
-                    continue;
-                }
-                RepositoryType repositoryType = RepositoryType.valueOf(repoConfig.getType());
-                if (providerMap.containsKey(repositoryType)) {
-                    try {
-                        ManagedRepository repo = createNewManagedRepository(providerMap.get(repositoryType), repoConfig);
-                        managedRepositories.put(repo.getId(), repo);
-                        pushEvent(new LifecycleEvent(LifecycleEvent.LifecycleEventType.REGISTERED, this, repo));
-                    } catch (Exception e) {
-                        log.error("Could not create managed repository {}: {}", repoConfig.getId(), e.getMessage(), e);
+                ManagedRepository repo = putRepository(repoConfig, null);
+                configRepoIds.add(repoConfig.getId());
+                if (repo.supportsFeature(StagingRepositoryFeature.class)) {
+                    StagingRepositoryFeature stagF = repo.getFeature(StagingRepositoryFeature.class).get();
+                    if (stagF.getStagingRepository() != null) {
+                        configRepoIds.add(stagF.getStagingRepository().getId());
                     }
                 }
             }
-            return;
+            List<String> toRemove = managedRepositories.keySet().stream().filter(id -> !configRepoIds.contains(id)).collect(Collectors.toList());
+            for (String id : toRemove) {
+                ManagedRepository removed = managedRepositories.remove(id);
+                removed.close();
+            }
         } catch (Throwable e) {
             log.error("Could not initialize repositories from config: {}", e.getMessage(), e);
-            //noinspection unchecked
             return;
         }
     }
@@ -205,15 +199,15 @@ public class RepositoryRegistry implements ConfigurationListener, RepositoryEven
             StagingRepositoryFeature feature = repo.getFeature(StagingRepositoryFeature.class).get();
             if (feature.isStageRepoNeeded() && feature.getStagingRepository() == null) {
                 ManagedRepository stageRepo = getManagedRepository(getStagingId(repo.getId()));
-                if (stageRepo==null) {
+                if (stageRepo == null) {
                     stageRepo = getStagingRepository(provider, cfg, configuration);
                     managedRepositories.put(stageRepo.getId(), stageRepo);
                     if (configuration != null) {
                         replaceOrAddRepositoryConfig(provider.getManagedConfiguration(stageRepo), configuration);
                     }
+                    pushEvent(new LifecycleEvent(LifecycleEvent.LifecycleEventType.REGISTERED, this, stageRepo));
                 }
                 feature.setStagingRepository(stageRepo);
-                pushEvent(new LifecycleEvent(LifecycleEvent.LifecycleEventType.REGISTERED, this, stageRepo));
             }
         }
         if (repo instanceof EditableManagedRepository) {
@@ -223,12 +217,12 @@ public class RepositoryRegistry implements ConfigurationListener, RepositoryEven
                 editableRepo.getContent().setRepository(editableRepo);
             }
             log.debug("Index repo: " + repo.hasIndex());
-            if (repo.hasIndex() && repo.getIndexingContext() == null) {
+            if (repo.hasIndex() && ( repo.getIndexingContext() == null || !repo.getIndexingContext().isOpen() )) {
                 log.debug("Creating indexing context for {}", repo.getId());
                 createIndexingContext(editableRepo);
             }
         }
-
+        repo.register(this);
     }
 
     public ArchivaIndexManager getIndexManager(RepositoryType type) {
@@ -267,30 +261,22 @@ public class RepositoryRegistry implements ConfigurationListener, RepositoryEven
                     getArchivaConfiguration().getConfiguration().getRemoteRepositories();
 
             if (remoteRepoConfigs == null) {
-                //noinspection unchecked
                 return;
             }
-
-            Map<RepositoryType, RepositoryProvider> providerMap = createProviderMap();
+            Set<String> repoIds = new HashSet<>();
             for (RemoteRepositoryConfiguration repoConfig : remoteRepoConfigs) {
-                RepositoryType repositoryType = RepositoryType.valueOf(repoConfig.getType());
-                if (providerMap.containsKey(repositoryType)) {
-                    RepositoryProvider provider = getProvider(repositoryType);
-                    try {
+                putRepository(repoConfig, null);
+                repoIds.add(repoConfig.getId());
+            }
 
-                        RemoteRepository remoteRepository = createNewRemoteRepository(provider, repoConfig);
-                        remoteRepositories.put(repoConfig.getId(), remoteRepository);
-                        pushEvent(new LifecycleEvent(LifecycleEvent.LifecycleEventType.REGISTERED, this, remoteRepository));
-                    } catch (Exception e) {
-                        log.error("Could not create repository {} from config: {}", repoConfig.getId(), e.getMessage(), e);
-                    }
-                }
+            List<String> toRemove = remoteRepositories.keySet().stream().filter(id -> !repoIds.contains(id)).collect(Collectors.toList());
+            for (String id : toRemove) {
+                RemoteRepository removed = remoteRepositories.remove(id);
+                removed.close();
             }
 
-            return;
         } catch (Throwable e) {
             log.error("Could not initialize remote repositories from config: {}", e.getMessage(), e);
-            //noinspection unchecked
             return;
         }
     }
@@ -298,13 +284,11 @@ public class RepositoryRegistry implements ConfigurationListener, RepositoryEven
     private RemoteRepository createNewRemoteRepository(RepositoryProvider provider, RemoteRepositoryConfiguration cfg) throws RepositoryException {
         log.debug("Creating remote repo {}", cfg.getId());
         RemoteRepository repo = provider.createRemoteInstance(cfg);
-        repo.register(this);
         updateRepositoryReferences(provider, repo, cfg, null);
         return repo;
 
     }
 
-    @SuppressWarnings("unchecked")
     private void updateRepositoryReferences(RepositoryProvider provider, RemoteRepository repo, RemoteRepositoryConfiguration cfg, Configuration configuration) throws RepositoryException {
         if (repo instanceof EditableRemoteRepository && repo.getContent() == null) {
             EditableRemoteRepository editableRepo = (EditableRemoteRepository) repo;
@@ -313,6 +297,7 @@ public class RepositoryRegistry implements ConfigurationListener, RepositoryEven
                 createIndexingContext(editableRepo);
             }
         }
+        repo.register(this);
     }
 
     private Map<String, RepositoryGroup> getRepositorGroupsFromConfig() {
@@ -341,12 +326,11 @@ public class RepositoryRegistry implements ConfigurationListener, RepositoryEven
             return repositoryGroupMap;
         } catch (Throwable e) {
             log.error("Could not initialize repositories from config: {}", e.getMessage(), e);
-            //noinspection unchecked
             return Collections.emptyMap();
         }
     }
 
-    RepositoryGroup createNewRepositoryGroup(RepositoryProvider provider, RepositoryGroupConfiguration config) throws RepositoryException {
+    private RepositoryGroup createNewRepositoryGroup(RepositoryProvider provider, RepositoryGroupConfiguration config) throws RepositoryException {
         RepositoryGroup repositoryGroup = provider.createRepositoryGroup(config);
         repositoryGroup.register(this);
         updateRepositoryReferences(provider, repositoryGroup, config);
@@ -511,10 +495,9 @@ public class RepositoryRegistry implements ConfigurationListener, RepositoryEven
             if (remoteRepositories.containsKey(id)) {
                 throw new RepositoryException("There exists a remote repository with id " + id + ". Could not update with managed repository.");
             }
-
             ManagedRepository originRepo = managedRepositories.put(id, managedRepository);
             try {
-                if (originRepo != null) {
+                if (originRepo != null && originRepo != managedRepository) {
                     originRepo.close();
                 }
                 RepositoryProvider provider = getProvider(managedRepository.getType());
@@ -527,10 +510,14 @@ public class RepositoryRegistry implements ConfigurationListener, RepositoryEven
                 }
                 configuration.addManagedRepository(newCfg);
                 saveConfiguration(configuration);
-                pushEvent(new LifecycleEvent(LifecycleEvent.LifecycleEventType.REGISTERED, this, managedRepository));
+                if (originRepo != managedRepository) {
+                    pushEvent(new LifecycleEvent<>(LifecycleEvent.LifecycleEventType.REGISTERED, this, managedRepository));
+                } else {
+                    pushEvent(new LifecycleEvent<>(LifecycleEvent.LifecycleEventType.UPDATED, this, managedRepository));
+                }
                 return managedRepository;
             } catch (Exception e) {
-                // Rollback
+                // Rollback only partly, because repository is closed already
                 if (originRepo != null) {
                     managedRepositories.put(id, originRepo);
                 } else {
@@ -581,20 +568,20 @@ public class RepositoryRegistry implements ConfigurationListener, RepositoryEven
      * Adds a new repository or updates the repository with the same id. The given configuration object is updated, but
      * the configuration is not saved.
      *
-     * @param managedRepositoryConfiguration the new or changed repository configuration
-     * @param configuration                  the configuration object
+     * @param managedRepositoryConfiguration the new or changed managed repository configuration
+     * @param configuration                  the configuration object (may be <code>null</code>)
      * @return the new or updated repository
      * @throws RepositoryException if the configuration cannot be saved or updated
      */
-    @SuppressWarnings("unchecked")
     public ManagedRepository putRepository(ManagedRepositoryConfiguration managedRepositoryConfiguration, Configuration configuration) throws RepositoryException {
         rwLock.writeLock().lock();
         try {
             final String id = managedRepositoryConfiguration.getId();
             final RepositoryType repoType = RepositoryType.valueOf(managedRepositoryConfiguration.getType());
             ManagedRepository repo;
-            if (managedRepositories.containsKey(id)) {
-                repo = managedRepositories.get(id);
+            boolean registeredNew = false;
+            repo = managedRepositories.get(id);
+            if (repo != null && repo.isOpen()) {
                 if (repo instanceof EditableManagedRepository) {
                     getProvider(repoType).updateManagedInstance((EditableManagedRepository) repo, managedRepositoryConfiguration);
                 } else {
@@ -602,12 +589,16 @@ public class RepositoryRegistry implements ConfigurationListener, RepositoryEven
                 }
             } else {
                 repo = getProvider(repoType).createManagedInstance(managedRepositoryConfiguration);
-                repo.register(this);
                 managedRepositories.put(id, repo);
+                registeredNew = true;
             }
             updateRepositoryReferences(getProvider(repoType), repo, managedRepositoryConfiguration, configuration);
             replaceOrAddRepositoryConfig(managedRepositoryConfiguration, configuration);
-            pushEvent(new LifecycleEvent(LifecycleEvent.LifecycleEventType.REGISTERED, this, repo));
+            if (registeredNew) {
+                pushEvent(new LifecycleEvent<>(LifecycleEvent.LifecycleEventType.REGISTERED, this, repo));
+            } else {
+                pushEvent(new LifecycleEvent<>(LifecycleEvent.LifecycleEventType.UPDATED, this, repo));
+            }
             return repo;
         } finally {
             rwLock.writeLock().unlock();
@@ -627,10 +618,10 @@ public class RepositoryRegistry implements ConfigurationListener, RepositoryEven
         rwLock.writeLock().lock();
         try {
             final String id = repositoryGroup.getId();
-            RepositoryGroup originRepo = repositoryGroups.put(id, repositoryGroup);
+            RepositoryGroup originRepoGroup = repositoryGroups.put(id, repositoryGroup);
             try {
-                if (originRepo != null) {
-                    originRepo.close();
+                if (originRepoGroup != null && originRepoGroup != repositoryGroup) {
+                    originRepoGroup.close();
                 }
                 RepositoryProvider provider = getProvider(repositoryGroup.getType());
                 RepositoryGroupConfiguration newCfg = provider.getRepositoryGroupConfiguration(repositoryGroup);
@@ -645,8 +636,8 @@ public class RepositoryRegistry implements ConfigurationListener, RepositoryEven
                 return repositoryGroup;
             } catch (Exception e) {
                 // Rollback
-                if (originRepo != null) {
-                    repositoryGroups.put(id, originRepo);
+                if (originRepoGroup != null) {
+                    repositoryGroups.put(id, originRepoGroup);
                 } else {
                     repositoryGroups.remove(id);
                 }
@@ -695,12 +686,11 @@ public class RepositoryRegistry implements ConfigurationListener, RepositoryEven
      * Adds a new repository group or updates the repository group with the same id. The given configuration object is updated, but
      * the configuration is not saved.
      *
-     * @param repositoryGroupConfiguration the new or changed repository configuration
-     * @param configuration                the configuration object
-     * @return the new or updated repository
+     * @param repositoryGroupConfiguration The configuration of the new or changed repository group.
+     * @param configuration                The configuration object. If it is <code>null</code>, the configuration is not saved.
+     * @return The new or updated repository group
      * @throws RepositoryException if the configuration cannot be saved or updated
      */
-    @SuppressWarnings("unchecked")
     public RepositoryGroup putRepositoryGroup(RepositoryGroupConfiguration repositoryGroupConfiguration, Configuration configuration) throws RepositoryException {
         rwLock.writeLock().lock();
         try {
@@ -717,7 +707,6 @@ public class RepositoryRegistry implements ConfigurationListener, RepositoryEven
                 }
             } else {
                 repo = getProvider(repoType).createRepositoryGroup(repositoryGroupConfiguration);
-                repo.register(this);
                 repositoryGroups.put(id, repo);
             }
             updateRepositoryReferences(getProvider(repoType), repo, repositoryGroupConfiguration);
@@ -741,19 +730,23 @@ public class RepositoryRegistry implements ConfigurationListener, RepositoryEven
     }
 
     private void replaceOrAddRepositoryConfig(ManagedRepositoryConfiguration managedRepositoryConfiguration, Configuration configuration) {
-        ManagedRepositoryConfiguration oldCfg = configuration.findManagedRepositoryById(managedRepositoryConfiguration.getId());
-        if (oldCfg != null) {
-            configuration.removeManagedRepository(oldCfg);
+        if (configuration != null) {
+            ManagedRepositoryConfiguration oldCfg = configuration.findManagedRepositoryById(managedRepositoryConfiguration.getId());
+            if (oldCfg != null) {
+                configuration.removeManagedRepository(oldCfg);
+            }
+            configuration.addManagedRepository(managedRepositoryConfiguration);
         }
-        configuration.addManagedRepository(managedRepositoryConfiguration);
     }
 
     private void replaceOrAddRepositoryConfig(RemoteRepositoryConfiguration remoteRepositoryConfiguration, Configuration configuration) {
-        RemoteRepositoryConfiguration oldCfg = configuration.findRemoteRepositoryById(remoteRepositoryConfiguration.getId());
-        if (oldCfg != null) {
-            configuration.removeRemoteRepository(oldCfg);
+        if (configuration != null) {
+            RemoteRepositoryConfiguration oldCfg = configuration.findRemoteRepositoryById(remoteRepositoryConfiguration.getId());
+            if (oldCfg != null) {
+                configuration.removeRemoteRepository(oldCfg);
+            }
+            configuration.addRemoteRepository(remoteRepositoryConfiguration);
         }
-        configuration.addRemoteRepository(remoteRepositoryConfiguration);
     }
 
     private void replaceOrAddRepositoryConfig(RepositoryGroupConfiguration repositoryGroupConfiguration, Configuration configuration) {
@@ -775,7 +768,7 @@ public class RepositoryRegistry implements ConfigurationListener, RepositoryEven
             RemoteRepositoryConfiguration oldCfg = null;
             RemoteRepositoryConfiguration newCfg;
             try {
-                if (originRepo != null) {
+                if (originRepo != null && originRepo != remoteRepository) {
                     originRepo.close();
                 }
                 final RepositoryProvider provider = getProvider(remoteRepository.getType());
@@ -786,7 +779,11 @@ public class RepositoryRegistry implements ConfigurationListener, RepositoryEven
                     configuration.removeRemoteRepository(oldCfg);
                 }
                 configuration.addRemoteRepository(newCfg);
-                pushEvent(new LifecycleEvent(LifecycleEvent.LifecycleEventType.REGISTERED, this, remoteRepository));
+                if (remoteRepository != originRepo) {
+                    pushEvent(new LifecycleEvent<>(LifecycleEvent.LifecycleEventType.REGISTERED, this, remoteRepository));
+                } else {
+                    pushEvent(new LifecycleEvent<>(LifecycleEvent.LifecycleEventType.UPDATED, this, remoteRepository));
+                }
                 return remoteRepository;
             } catch (Exception e) {
                 // Rollback
@@ -883,8 +880,9 @@ public class RepositoryRegistry implements ConfigurationListener, RepositoryEven
             final String id = remoteRepositoryConfiguration.getId();
             final RepositoryType repoType = RepositoryType.valueOf(remoteRepositoryConfiguration.getType());
             RemoteRepository repo;
-            if (remoteRepositories.containsKey(id)) {
-                repo = remoteRepositories.get(id);
+            boolean registeredNew = false;
+            repo = remoteRepositories.get(id);
+            if (repo != null && repo.isOpen()) {
                 if (repo instanceof EditableRemoteRepository) {
                     getProvider(repoType).updateRemoteInstance((EditableRemoteRepository) repo, remoteRepositoryConfiguration);
                 } else {
@@ -892,12 +890,16 @@ public class RepositoryRegistry implements ConfigurationListener, RepositoryEven
                 }
             } else {
                 repo = getProvider(repoType).createRemoteInstance(remoteRepositoryConfiguration);
-                repo.register(this);
                 remoteRepositories.put(id, repo);
+                registeredNew = true;
             }
             updateRepositoryReferences(getProvider(repoType), repo, remoteRepositoryConfiguration, configuration);
             replaceOrAddRepositoryConfig(remoteRepositoryConfiguration, configuration);
-            pushEvent(new LifecycleEvent(LifecycleEvent.LifecycleEventType.REGISTERED, this, repo));
+            if (registeredNew) {
+                pushEvent(new LifecycleEvent(LifecycleEvent.LifecycleEventType.REGISTERED, this, repo));
+            } else {
+                pushEvent(new LifecycleEvent(LifecycleEvent.LifecycleEventType.UPDATED, this, repo));
+            }
             return repo;
         } finally {
             rwLock.writeLock().unlock();
@@ -913,7 +915,6 @@ public class RepositoryRegistry implements ConfigurationListener, RepositoryEven
         }
     }
 
-    @SuppressWarnings("unchecked")
     public void removeRepository(Repository repo) throws RepositoryException {
         if (repo == null) {
             log.warn("Trying to remove null repository");
@@ -938,6 +939,9 @@ public class RepositoryRegistry implements ConfigurationListener, RepositoryEven
      * @throws RepositoryException if a error occurs during configuration save
      */
     public void removeRepository(ManagedRepository managedRepository) throws RepositoryException {
+        if (managedRepository == null) {
+            return;
+        }
         final String id = managedRepository.getId();
         ManagedRepository repo = getManagedRepository(id);
         if (repo != null) {
@@ -954,7 +958,7 @@ public class RepositoryRegistry implements ConfigurationListener, RepositoryEven
                     }
                     saveConfiguration(configuration);
                 }
-                pushEvent(new LifecycleEvent(LifecycleEvent.LifecycleEventType.UNREGISTERED, this, repo));
+                pushEvent(new LifecycleEvent<>(LifecycleEvent.LifecycleEventType.UNREGISTERED, this, repo));
             } catch (RegistryException | IndeterminateConfigurationException e) {
                 // Rollback
                 log.error("Could not save config after repository removal: {}", e.getMessage(), e);
@@ -974,6 +978,9 @@ public class RepositoryRegistry implements ConfigurationListener, RepositoryEven
     }
 
     public void removeRepository(ManagedRepository managedRepository, Configuration configuration) throws RepositoryException {
+        if (managedRepository == null) {
+            return;
+        }
         final String id = managedRepository.getId();
         ManagedRepository repo = getManagedRepository(id);
         if (repo != null) {
@@ -988,7 +995,7 @@ public class RepositoryRegistry implements ConfigurationListener, RepositoryEven
                         configuration.removeManagedRepository(cfg);
                     }
                 }
-                pushEvent(new LifecycleEvent(LifecycleEvent.LifecycleEventType.UNREGISTERED, this, repo));
+                pushEvent(new LifecycleEvent<>(LifecycleEvent.LifecycleEventType.UNREGISTERED, this, repo));
             } finally {
                 rwLock.writeLock().unlock();
             }
@@ -1005,6 +1012,9 @@ public class RepositoryRegistry implements ConfigurationListener, RepositoryEven
      * @throws RepositoryException if a error occurs during configuration save
      */
     public void removeRepositoryGroup(RepositoryGroup repositoryGroup) throws RepositoryException {
+        if (repositoryGroup == null) {
+            return;
+        }
         final String id = repositoryGroup.getId();
         RepositoryGroup repo = getRepositoryGroup(id);
         if (repo != null) {
@@ -1033,6 +1043,9 @@ public class RepositoryRegistry implements ConfigurationListener, RepositoryEven
     }
 
     public void removeRepositoryGroup(RepositoryGroup repositoryGroup, Configuration configuration) throws RepositoryException {
+        if (repositoryGroup == null) {
+            return;
+        }
         final String id = repositoryGroup.getId();
         RepositoryGroup repo = getRepositoryGroup(id);
         if (repo != null) {
@@ -1075,7 +1088,9 @@ public class RepositoryRegistry implements ConfigurationListener, RepositoryEven
      * @throws RepositoryException if a error occurs during configuration save
      */
     public void removeRepository(RemoteRepository remoteRepository) throws RepositoryException {
-
+        if (remoteRepository == null) {
+            return;
+        }
         final String id = remoteRepository.getId();
         RemoteRepository repo = getRemoteRepository(id);
         if (repo != null) {
@@ -1087,7 +1102,7 @@ public class RepositoryRegistry implements ConfigurationListener, RepositoryEven
                     doRemoveRepo(repo, configuration);
                     saveConfiguration(configuration);
                 }
-                pushEvent(new LifecycleEvent(LifecycleEvent.LifecycleEventType.UNREGISTERED, this, repo));
+                pushEvent(new LifecycleEvent<>(LifecycleEvent.LifecycleEventType.UNREGISTERED, this, repo));
             } catch (RegistryException | IndeterminateConfigurationException e) {
                 // Rollback
                 log.error("Could not save config after repository removal: {}", e.getMessage(), e);
@@ -1100,6 +1115,9 @@ public class RepositoryRegistry implements ConfigurationListener, RepositoryEven
     }
 
     public void removeRepository(RemoteRepository remoteRepository, Configuration configuration) throws RepositoryException {
+        if (remoteRepository == null) {
+            return;
+        }
         final String id = remoteRepository.getId();
         RemoteRepository repo = getRemoteRepository(id);
         if (repo != null) {
@@ -1109,7 +1127,7 @@ public class RepositoryRegistry implements ConfigurationListener, RepositoryEven
                 if (repo != null) {
                     doRemoveRepo(repo, configuration);
                 }
-                pushEvent(new LifecycleEvent(LifecycleEvent.LifecycleEventType.UNREGISTERED, this, repo));
+                pushEvent(new LifecycleEvent<>(LifecycleEvent.LifecycleEventType.UNREGISTERED, this, repo));
             } finally {
                 rwLock.writeLock().unlock();
             }
@@ -1127,14 +1145,13 @@ public class RepositoryRegistry implements ConfigurationListener, RepositoryEven
     /**
      * Resets the indexing context of a given repository.
      *
-     * @param repo
-     * @throws IndexUpdateFailedException
+     * @param repository The repository
+     * @throws IndexUpdateFailedException If the index could not be resetted.
      */
-    @SuppressWarnings("unchecked")
-    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());
+    public void resetIndexingContext(Repository repository) throws IndexUpdateFailedException {
+        if (repository.hasIndex() && repository instanceof EditableRepository) {
+            EditableRepository eRepo = (EditableRepository) repository;
+            ArchivaIndexingContext newCtx = getIndexManager(repository.getType()).reset(repository.getIndexingContext());
             eRepo.setIndexingContext(newCtx);
         }
     }
@@ -1159,7 +1176,6 @@ public class RepositoryRegistry implements ConfigurationListener, RepositoryEven
         return cloned;
     }
 
-    @SuppressWarnings("unchecked")
     public <T extends Repository> Repository clone(T repo, String newId) throws RepositoryException {
         if (repo instanceof RemoteRepository) {
             return this.clone((RemoteRepository) repo, newId);
@@ -1249,31 +1265,35 @@ public class RepositoryRegistry implements ConfigurationListener, RepositoryEven
             return;
         }
         if (event instanceof IndexCreationEvent) {
-            IndexCreationEvent idxEvent = (IndexCreationEvent) event;
-            if (managedRepositories.containsKey(idxEvent.getRepository().getId()) ||
-                    remoteRepositories.containsKey(idxEvent.getRepository().getId())) {
-                EditableRepository repo = (EditableRepository) idxEvent.getRepository();
-                if (repo != null && repo.getIndexingContext() != null) {
-                    try {
-                        ArchivaIndexManager idxmgr = getIndexManager(repo.getType());
-                        if (idxmgr != null) {
-                            ArchivaIndexingContext newCtx = idxmgr.move(repo.getIndexingContext(), repo);
-                            repo.setIndexingContext(newCtx);
-                            idxmgr.updateLocalIndexPath(repo);
-                        }
-
-                    } catch (IndexCreationFailedException e) {
-                        log.error("Could not move index to new directory {}", e.getMessage(), e);
+            handleIndexCreationEvent((IndexCreationEvent) event);
+        }
+        // We propagate all events to our listeners, but with context of repository registry
+        pushEvent(event.recreate(this));
+    }
+
+    private void handleIndexCreationEvent(IndexCreationEvent event) {
+        IndexCreationEvent idxEvent = event;
+        if (managedRepositories.containsKey(idxEvent.getRepository().getId()) ||
+                remoteRepositories.containsKey(idxEvent.getRepository().getId())) {
+            EditableRepository repo = (EditableRepository) idxEvent.getRepository();
+            if (repo != null && repo.getIndexingContext() != null) {
+                try {
+                    ArchivaIndexManager idxmgr = getIndexManager(repo.getType());
+                    if (idxmgr != null) {
+                        ArchivaIndexingContext newCtx = idxmgr.move(repo.getIndexingContext(), repo);
+                        repo.setIndexingContext(newCtx);
+                        idxmgr.updateLocalIndexPath(repo);
                     }
+
+                } catch (IndexCreationFailedException e) {
+                    log.error("Could not move index to new directory {}", e.getMessage(), e);
                 }
             }
         }
-        // We propagate all events to our listeners
-        pushEvent(event.recreate(this));
     }
 
     private boolean sameOriginator(Event event) {
-        if (event.getOriginator()==this) {
+        if (event.getOriginator() == this) {
             return true;
         } else if (event.hasPreviousEvent()) {
             return sameOriginator(event.getPreviousEvent());
diff --git a/archiva-modules/archiva-base/archiva-test-utils/src/main/java/org/apache/archiva/test/utils/ArchivaSpringJUnit4ClassRunner.java b/archiva-modules/archiva-base/archiva-test-utils/src/main/java/org/apache/archiva/test/utils/ArchivaSpringJUnit4ClassRunner.java
index 34a9db0..81a9158 100644
--- a/archiva-modules/archiva-base/archiva-test-utils/src/main/java/org/apache/archiva/test/utils/ArchivaSpringJUnit4ClassRunner.java
+++ b/archiva-modules/archiva-base/archiva-test-utils/src/main/java/org/apache/archiva/test/utils/ArchivaSpringJUnit4ClassRunner.java
@@ -20,6 +20,9 @@ import org.junit.runners.model.FrameworkMethod;
 import org.junit.runners.model.InitializationError;
 import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
 
+import java.io.IOException;
+import java.nio.file.Files;
+import java.nio.file.Path;
 import java.util.List;
 
 /**
@@ -29,6 +32,18 @@ public class ArchivaSpringJUnit4ClassRunner
     extends SpringJUnit4ClassRunner
 {
 
+    static {
+
+        if (System.getProperty("archiva.user.configFileName")!=null && !"".equals(System.getProperty("archiva.user.configFileName").trim())) {
+            try {
+                Path file = Files.createTempFile("archiva-test-conf", ".xml");
+                System.setProperty("archiva.user.configFileName", file.toAbsolutePath().toString());
+            } catch (IOException e) {
+                e.printStackTrace();
+            }
+        }
+    }
+
     public ArchivaSpringJUnit4ClassRunner( Class<?> clazz )
         throws InitializationError
     {
diff --git a/archiva-modules/archiva-maven/archiva-maven-indexer/src/main/java/org/apache/archiva/indexer/maven/MavenIndexContext.java b/archiva-modules/archiva-maven/archiva-maven-indexer/src/main/java/org/apache/archiva/indexer/maven/MavenIndexContext.java
index 7f18ad1..c4c5e3b 100644
--- a/archiva-modules/archiva-maven/archiva-maven-indexer/src/main/java/org/apache/archiva/indexer/maven/MavenIndexContext.java
+++ b/archiva-modules/archiva-maven/archiva-maven-indexer/src/main/java/org/apache/archiva/indexer/maven/MavenIndexContext.java
@@ -37,6 +37,7 @@ import java.nio.file.Path;
 import java.sql.Date;
 import java.time.ZonedDateTime;
 import java.util.Set;
+import java.util.concurrent.atomic.AtomicBoolean;
 
 /**
  * Maven implementation of index context
@@ -45,6 +46,8 @@ public class MavenIndexContext implements ArchivaIndexingContext {
 
     private static final Logger log = LoggerFactory.getLogger(ArchivaIndexingContext.class);
 
+
+    private AtomicBoolean openStatus = new AtomicBoolean(false);
     private IndexingContext delegate;
     private Repository repository;
     private StorageAsset dir = null;
@@ -52,6 +55,7 @@ public class MavenIndexContext implements ArchivaIndexingContext {
     protected MavenIndexContext(Repository repository, IndexingContext delegate) {
         this.delegate = delegate;
         this.repository = repository;
+        this.openStatus.set(true);
 
     }
 
@@ -107,23 +111,32 @@ public class MavenIndexContext implements ArchivaIndexingContext {
 
     @Override
     public void close(boolean deleteFiles) throws IOException {
-        try {
-            delegate.close(deleteFiles);
-        } catch (NoSuchFileException e) {
-            // Ignore missing directory
+        if (openStatus.compareAndSet(true,false)) {
+            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
+        if (openStatus.compareAndSet(true,false)) {
+            try {
+                delegate.close(false);
+            } catch (NoSuchFileException e) {
+                // Ignore missing directory
+            }
         }
     }
 
     @Override
+    public boolean isOpen() {
+        return openStatus.get();
+    }
+
+    @Override
     public void purge() throws IOException {
         delegate.purge();
     }
diff --git a/archiva-modules/archiva-maven/archiva-maven-indexer/src/test/java/org/apache/archiva/indexer/maven/search/AbstractMavenRepositorySearch.java b/archiva-modules/archiva-maven/archiva-maven-indexer/src/test/java/org/apache/archiva/indexer/maven/search/AbstractMavenRepositorySearch.java
index f2170f2..f36e261 100644
--- a/archiva-modules/archiva-maven/archiva-maven-indexer/src/test/java/org/apache/archiva/indexer/maven/search/AbstractMavenRepositorySearch.java
+++ b/archiva-modules/archiva-maven/archiva-maven-indexer/src/test/java/org/apache/archiva/indexer/maven/search/AbstractMavenRepositorySearch.java
@@ -26,6 +26,7 @@ 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.ArchivaIndexingContext;
 import org.apache.archiva.indexer.search.SearchResultHit;
 import org.apache.archiva.indexer.search.SearchResults;
 import org.apache.archiva.repository.Repository;
@@ -145,7 +146,7 @@ public abstract class AbstractMavenRepositorySearch
         EasyMock.expectLastCall().anyTimes();
         archivaConfigControl.replay();
         repositoryRegistry.reload();
-        archivaConfigControl.reset();
+
     }
 
     @After
@@ -210,11 +211,12 @@ public abstract class AbstractMavenRepositorySearch
         IndexCreationFeature icf = rRepo.getFeature(IndexCreationFeature.class).get();
 
 
-        IndexingContext context = rRepo.getIndexingContext().getBaseContext(IndexingContext.class);
+        ArchivaIndexingContext archivaCtx = rRepo.getIndexingContext();
+        IndexingContext context = archivaCtx.getBaseContext(IndexingContext.class);
 
-        if ( context != null )
+        if ( archivaCtx != null )
         {
-            context.close(true);
+            archivaCtx.close(true);
         }
 
         Path repoDir = Paths.get(org.apache.archiva.common.utils.FileUtils.getBasedir()).resolve("target").resolve("repos").resolve(repository);
@@ -233,13 +235,7 @@ public abstract class AbstractMavenRepositorySearch
         {
             Files.delete(lockFile);
         }
-
         assertFalse( Files.exists(lockFile) );
-
-        Path repo = Paths.get( org.apache.archiva.common.utils.FileUtils.getBasedir(), "src/test/" + repository );
-        assertTrue( Files.exists(repo) );
-        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()));
@@ -250,7 +246,28 @@ public abstract class AbstractMavenRepositorySearch
 
             icf.setIndexPath(indexDir.toUri());
         }
-        context = rRepo.getIndexingContext().getBaseContext(IndexingContext.class);
+        Path repo = Paths.get( org.apache.archiva.common.utils.FileUtils.getBasedir(), "src/test/" + repository );
+        assertTrue( Files.exists(repo) );
+        org.apache.commons.io.FileUtils.copyDirectory(repo.toFile(), repoDir.toFile());
+
+
+
+
+        archivaConfigControl.reset();
+        archivaConfig.addListener( EasyMock.anyObject( ConfigurationListener.class ) );
+        EasyMock.expect( archivaConfig.getConfiguration() ).andReturn(config).anyTimes();
+        archivaConfig.save(EasyMock.anyObject(Configuration.class));
+        EasyMock.expectLastCall().anyTimes();
+        archivaConfigControl.replay();
+        repositoryRegistry.reload();
+        archivaConfigControl.reset();
+
+        rRepo = repositoryRegistry.getRepository(repository);
+        icf = rRepo.getFeature(IndexCreationFeature.class).get();
+
+
+        archivaCtx = rRepo.getIndexingContext();
+        context = archivaCtx.getBaseContext(IndexingContext.class);
 
 
         // minimize datas in memory
diff --git a/archiva-modules/archiva-maven/archiva-maven-indexer/src/test/java/org/apache/archiva/indexer/maven/search/MavenRepositorySearchOSGITest.java b/archiva-modules/archiva-maven/archiva-maven-indexer/src/test/java/org/apache/archiva/indexer/maven/search/MavenRepositorySearchOSGITest.java
index 066b2af..74819f9 100644
--- a/archiva-modules/archiva-maven/archiva-maven-indexer/src/test/java/org/apache/archiva/indexer/maven/search/MavenRepositorySearchOSGITest.java
+++ b/archiva-modules/archiva-maven/archiva-maven-indexer/src/test/java/org/apache/archiva/indexer/maven/search/MavenRepositorySearchOSGITest.java
@@ -61,7 +61,7 @@ public class MavenRepositorySearchOSGITest
         List<String> selectedRepos = Arrays.asList( TEST_REPO_1 );
 
         // search artifactId
-        EasyMock.expect( archivaConfig.getDefaultLocale() ).andReturn( Locale.getDefault( ) ).anyTimes();
+        // EasyMock.expect( archivaConfig.getDefaultLocale() ).andReturn( Locale.getDefault( ) ).anyTimes();
         EasyMock.expect( archivaConfig.getConfiguration()).andReturn(config).anyTimes();
 
         archivaConfigControl.replay();
diff --git a/archiva-modules/archiva-maven/archiva-maven-indexer/src/test/java/org/apache/archiva/indexer/maven/search/MavenRepositorySearchTest.java b/archiva-modules/archiva-maven/archiva-maven-indexer/src/test/java/org/apache/archiva/indexer/maven/search/MavenRepositorySearchTest.java
index cb43a1a..0b5b1bd 100644
--- a/archiva-modules/archiva-maven/archiva-maven-indexer/src/test/java/org/apache/archiva/indexer/maven/search/MavenRepositorySearchTest.java
+++ b/archiva-modules/archiva-maven/archiva-maven-indexer/src/test/java/org/apache/archiva/indexer/maven/search/MavenRepositorySearchTest.java
@@ -410,10 +410,10 @@ public class MavenRepositorySearchTest
         List<String> selectedRepos = new ArrayList<>();
         selectedRepos.add( TEST_REPO_1 );
 
-        EasyMock.expect( archivaConfig.getDefaultLocale() ).andReturn( Locale.getDefault( ) ).anyTimes();
-        EasyMock.expect( archivaConfig.getConfiguration()).andReturn(config).anyTimes();
+        // EasyMock.expect( archivaConfig.getDefaultLocale() ).andReturn( Locale.getDefault( ) ).anyTimes();
+        // EasyMock.expect( archivaConfig.getConfiguration()).andReturn(config).anyTimes();
 
-        archivaConfigControl.replay();
+        // archivaConfigControl.replay();
 
         SearchResults results = search.search( "user", selectedRepos, "org.apache.archiva", null, null );
         assertNotNull( results );
@@ -429,7 +429,7 @@ public class MavenRepositorySearchTest
         List<String> selectedRepos = new ArrayList<>();
         selectedRepos.add( "non-existing-repo" );
 
-        archivaConfigControl.replay();
+        // archivaConfigControl.replay();
 
         SearchResults results = search.search( "user", selectedRepos, "org.apache.archiva", null, null );
         assertNotNull( results );
@@ -621,10 +621,10 @@ public class MavenRepositorySearchTest
 
         try
         {
-            EasyMock.expect( archivaConfig.getDefaultLocale() ).andReturn( Locale.getDefault( ) ).anyTimes();
-            EasyMock.expect( archivaConfig.getConfiguration()).andReturn(config).anyTimes();
+            // EasyMock.expect( archivaConfig.getDefaultLocale() ).andReturn( Locale.getDefault( ) ).anyTimes();
+            // EasyMock.expect( archivaConfig.getConfiguration()).andReturn(config).anyTimes();
 
-            archivaConfigControl.replay();
+            // archivaConfigControl.replay();
 
             search.search( "user", searchFields, null );
 
@@ -657,9 +657,9 @@ public class MavenRepositorySearchTest
         try
         {
 
-            EasyMock.expect( archivaConfig.getDefaultLocale() ).andReturn( Locale.getDefault( ) ).anyTimes();
-            EasyMock.expect( archivaConfig.getConfiguration()).andReturn(config).anyTimes();
-            archivaConfigControl.replay();
+            // EasyMock.expect( archivaConfig.getDefaultLocale() ).andReturn( Locale.getDefault( ) ).anyTimes();
+            // EasyMock.expect( archivaConfig.getConfiguration()).andReturn(config).anyTimes();
+            // archivaConfigControl.replay();
 
             search.search( "user", searchFields, null );
 
@@ -805,10 +805,10 @@ public class MavenRepositorySearchTest
         searchFields.setGroupId( "org.apache.archiva" );
         searchFields.setRepositories( selectedRepos );
 
-        EasyMock.expect( archivaConfig.getDefaultLocale() ).andReturn( Locale.getDefault( ) ).anyTimes();
-        EasyMock.expect( archivaConfig.getConfiguration()).andReturn(config).anyTimes();
+        // EasyMock.expect( archivaConfig.getDefaultLocale() ).andReturn( Locale.getDefault( ) ).anyTimes();
+        // EasyMock.expect( archivaConfig.getConfiguration()).andReturn(config).anyTimes();
 
-        archivaConfigControl.replay();
+        // archivaConfigControl.replay();
 
         SearchResults results = search.search( "user", searchFields, null );
 
@@ -913,7 +913,7 @@ public class MavenRepositorySearchTest
         SearchResultLimits limits = new SearchResultLimits( SearchResultLimits.ALL_PAGES );
         limits.setPageSize( 300 );
 
-        EasyMock.expect( archivaConfig.getDefaultLocale() ).andReturn( Locale.getDefault( ) ).anyTimes();
+        // EasyMock.expect( archivaConfig.getDefaultLocale() ).andReturn( Locale.getDefault( ) ).anyTimes();
         EasyMock.expect( archivaConfig.getConfiguration()).andReturn(config).anyTimes();
 
         archivaConfigControl.replay();
diff --git a/archiva-modules/archiva-maven/archiva-maven-repository/src/main/java/org/apache/archiva/repository/maven2/MavenManagedRepository.java b/archiva-modules/archiva-maven/archiva-maven-repository/src/main/java/org/apache/archiva/repository/maven2/MavenManagedRepository.java
index 2836ca2..96eb6e9 100644
--- a/archiva-modules/archiva-maven/archiva-maven-repository/src/main/java/org/apache/archiva/repository/maven2/MavenManagedRepository.java
+++ b/archiva-modules/archiva-maven/archiva-maven-repository/src/main/java/org/apache/archiva/repository/maven2/MavenManagedRepository.java
@@ -22,6 +22,7 @@ package org.apache.archiva.repository.maven2;
 import org.apache.archiva.common.filelock.DefaultFileLockManager;
 import org.apache.archiva.common.filelock.FileLockManager;
 import org.apache.archiva.common.utils.PathUtil;
+import org.apache.archiva.indexer.ArchivaIndexingContext;
 import org.apache.archiva.repository.*;
 import org.apache.archiva.repository.storage.FilesystemStorage;
 import org.apache.archiva.repository.content.maven2.MavenRepositoryRequestInfo;
@@ -131,4 +132,10 @@ public class MavenManagedRepository extends AbstractManagedRepository
         FilesystemStorage storage = new FilesystemStorage(basePath.resolve(id), lockManager);
         return new MavenManagedRepository(id, name, storage);
     }
+
+    @Override
+    public void setIndexingContext(ArchivaIndexingContext context) {
+        super.setIndexingContext(context);
+    }
+
 }
diff --git a/archiva-modules/archiva-maven/archiva-maven-repository/src/main/java/org/apache/archiva/repository/maven2/MavenRepositoryProvider.java b/archiva-modules/archiva-maven/archiva-maven-repository/src/main/java/org/apache/archiva/repository/maven2/MavenRepositoryProvider.java
index 15dbf6a..ec78a94 100644
--- a/archiva-modules/archiva-maven/archiva-maven-repository/src/main/java/org/apache/archiva/repository/maven2/MavenRepositoryProvider.java
+++ b/archiva-modules/archiva-maven/archiva-maven-repository/src/main/java/org/apache/archiva/repository/maven2/MavenRepositoryProvider.java
@@ -23,12 +23,11 @@ import org.apache.archiva.common.filelock.FileLockManager;
 import org.apache.archiva.configuration.*;
 import org.apache.archiva.repository.*;
 import org.apache.archiva.repository.events.Event;
-import org.apache.archiva.repository.events.RepositoryValueEvent;
-import org.apache.archiva.repository.storage.FilesystemStorage;
 import org.apache.archiva.repository.features.ArtifactCleanupFeature;
 import org.apache.archiva.repository.features.IndexCreationFeature;
 import org.apache.archiva.repository.features.RemoteIndexFeature;
 import org.apache.archiva.repository.features.StagingRepositoryFeature;
+import org.apache.archiva.repository.storage.FilesystemStorage;
 import org.apache.commons.lang3.StringUtils;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -184,9 +183,13 @@ public class MavenRepositoryProvider implements RepositoryProvider {
         repo.setScanned(cfg.isScanned());
         if (cfg.isReleases()) {
             repo.addActiveReleaseScheme(ReleaseScheme.RELEASE);
+        } else {
+            repo.removeActiveReleaseScheme(ReleaseScheme.RELEASE);
         }
         if (cfg.isSnapshots()) {
             repo.addActiveReleaseScheme(ReleaseScheme.SNAPSHOT);
+        } else {
+            repo.removeActiveReleaseScheme(ReleaseScheme.SNAPSHOT);
         }
 
         StagingRepositoryFeature stagingRepositoryFeature = repo.getFeature(StagingRepositoryFeature.class).get();
@@ -349,13 +352,20 @@ public class MavenRepositoryProvider implements RepositoryProvider {
         cfg.setPackedIndexDir(convertUriToPath(indexCreationFeature.getPackedIndexPath()));
 
         RemoteIndexFeature remoteIndexFeature = remoteRepository.getFeature(RemoteIndexFeature.class).get();
-        if (remoteIndexFeature.getIndexUri()!=null) {
+        if (remoteIndexFeature.getIndexUri() != null) {
             cfg.setRemoteIndexUrl(remoteIndexFeature.getIndexUri().toString());
         }
         cfg.setRemoteDownloadTimeout((int) remoteIndexFeature.getDownloadTimeout().get(ChronoUnit.SECONDS));
         cfg.setDownloadRemoteIndexOnStartup(remoteIndexFeature.isDownloadRemoteIndexOnStartup());
         cfg.setDownloadRemoteIndex(remoteIndexFeature.isDownloadRemoteIndex());
         cfg.setRemoteDownloadNetworkProxyId(remoteIndexFeature.getProxyId());
+        if (!StringUtils.isEmpty(remoteIndexFeature.getProxyId())) {
+            cfg.setRemoteDownloadNetworkProxyId(remoteIndexFeature.getProxyId());
+        } else {
+            cfg.setRemoteDownloadNetworkProxyId("");
+        }
+
+
 
 
         return cfg;
diff --git a/archiva-modules/archiva-maven/archiva-maven-repository/src/test/java/org/apache/archiva/metadata/repository/storage/maven2/Maven2RepositoryMetadataResolverMRM1411Test.java b/archiva-modules/archiva-maven/archiva-maven-repository/src/test/java/org/apache/archiva/metadata/repository/storage/maven2/Maven2RepositoryMetadataResolverMRM1411Test.java
index 3bb6146..1788b9f 100644
--- a/archiva-modules/archiva-maven/archiva-maven-repository/src/test/java/org/apache/archiva/metadata/repository/storage/maven2/Maven2RepositoryMetadataResolverMRM1411Test.java
+++ b/archiva-modules/archiva-maven/archiva-maven-repository/src/test/java/org/apache/archiva/metadata/repository/storage/maven2/Maven2RepositoryMetadataResolverMRM1411Test.java
@@ -36,6 +36,7 @@ import org.apache.archiva.metadata.repository.storage.ReadMetadataRequest;
 import org.apache.archiva.metadata.repository.storage.RepositoryStorageRuntimeException;
 import org.apache.archiva.proxy.maven.WagonFactory;
 import org.apache.archiva.proxy.maven.WagonFactoryRequest;
+import org.apache.archiva.repository.ReleaseScheme;
 import org.apache.archiva.repository.RepositoryRegistry;
 import org.apache.archiva.test.utils.ArchivaSpringJUnit4ClassRunner;
 import org.apache.commons.io.FileUtils;
@@ -311,6 +312,7 @@ public class Maven2RepositoryMetadataResolverMRM1411Test
         testRepo.setSnapshots( false );
         configuration.save( c );
         repositoryRegistry.reload();
+        assertFalse(repositoryRegistry.getManagedRepository(testRepo.getId()).getActiveReleaseSchemes().contains(ReleaseScheme.SNAPSHOT));
         assertFalse( c.getManagedRepositories().get( 0 ).isSnapshots() );
         copyTestArtifactWithParent( "target/test-classes/com/example/test/test-snapshot-artifact-module-a",
                                     "target/test-repository/com/example/test/test-snapshot-artifact-module-a" );
diff --git a/archiva-modules/archiva-maven/archiva-maven-repository/src/test/java/org/apache/archiva/repository/index/mock/MavenIndexContextMock.java b/archiva-modules/archiva-maven/archiva-maven-repository/src/test/java/org/apache/archiva/repository/index/mock/MavenIndexContextMock.java
index a6dddae..ded8ed3 100644
--- a/archiva-modules/archiva-maven/archiva-maven-repository/src/test/java/org/apache/archiva/repository/index/mock/MavenIndexContextMock.java
+++ b/archiva-modules/archiva-maven/archiva-maven-repository/src/test/java/org/apache/archiva/repository/index/mock/MavenIndexContextMock.java
@@ -38,6 +38,7 @@ import java.util.Set;
  */
 public class MavenIndexContextMock implements ArchivaIndexingContext {
 
+    private boolean open = true;
     private IndexingContext delegate;
     private Repository repository;
     private FilesystemStorage indexStorage;
@@ -86,6 +87,7 @@ public class MavenIndexContextMock implements ArchivaIndexingContext {
 
     @Override
     public void close(boolean deleteFiles) throws IOException {
+        open = false;
         try {
             delegate.close(deleteFiles);
         } catch (NoSuchFileException e) {
@@ -95,6 +97,7 @@ public class MavenIndexContextMock implements ArchivaIndexingContext {
 
     @Override
     public void close() throws IOException {
+        open = false;
         try {
             delegate.close(false);
         } catch (NoSuchFileException e) {
@@ -103,6 +106,11 @@ public class MavenIndexContextMock implements ArchivaIndexingContext {
     }
 
     @Override
+    public boolean isOpen() {
+        return open;
+    }
+
+    @Override
     public void purge() throws IOException {
         delegate.purge();
     }
diff --git a/archiva-modules/archiva-scheduler/archiva-scheduler-repository/src/test/java/org/apache/archiva/mock/MavenIndexContextMock.java b/archiva-modules/archiva-scheduler/archiva-scheduler-repository/src/test/java/org/apache/archiva/mock/MavenIndexContextMock.java
index fa070a7..c8e2cd4 100644
--- a/archiva-modules/archiva-scheduler/archiva-scheduler-repository/src/test/java/org/apache/archiva/mock/MavenIndexContextMock.java
+++ b/archiva-modules/archiva-scheduler/archiva-scheduler-repository/src/test/java/org/apache/archiva/mock/MavenIndexContextMock.java
@@ -40,6 +40,8 @@ import java.util.Set;
  */
 public class MavenIndexContextMock implements ArchivaIndexingContext {
 
+    private boolean open = true;
+
     private IndexingContext delegate;
     private Repository repository;
     private FilesystemStorage filesystemStorage;
@@ -93,6 +95,7 @@ public class MavenIndexContextMock implements ArchivaIndexingContext {
 
     @Override
     public void close(boolean deleteFiles) throws IOException {
+        this.open = false;
         try {
             delegate.close(deleteFiles);
         } catch (NoSuchFileException e) {
@@ -102,6 +105,7 @@ public class MavenIndexContextMock implements ArchivaIndexingContext {
 
     @Override
     public void close() throws IOException {
+        this.open = false;
         try {
             delegate.close(false);
         } catch (NoSuchFileException e) {
@@ -110,6 +114,11 @@ public class MavenIndexContextMock implements ArchivaIndexingContext {
     }
 
     @Override
+    public boolean isOpen() {
+        return open;
+    }
+
+    @Override
     public void purge() throws IOException {
         delegate.purge();
     }
diff --git a/archiva-modules/archiva-web/archiva-webdav/pom.xml b/archiva-modules/archiva-web/archiva-webdav/pom.xml
index 79a8e9d..37cb92a 100644
--- a/archiva-modules/archiva-web/archiva-webdav/pom.xml
+++ b/archiva-modules/archiva-web/archiva-webdav/pom.xml
@@ -332,6 +332,7 @@
             <openjpa.Log>${openjpa.Log}</openjpa.Log>
             <org.apache.jackrabbit.core.state.validatehierarchy>true</org.apache.jackrabbit.core.state.validatehierarchy>
           </systemPropertyVariables>
+          <trimStackTrace>false</trimStackTrace>
         </configuration>
       </plugin>
     </plugins>
diff --git a/archiva-modules/archiva-web/archiva-webdav/src/test/java/org/apache/archiva/webdav/AbstractRepositoryServletTestCase.java b/archiva-modules/archiva-web/archiva-webdav/src/test/java/org/apache/archiva/webdav/AbstractRepositoryServletTestCase.java
index 2d2b42c..2094ba3 100644
--- a/archiva-modules/archiva-web/archiva-webdav/src/test/java/org/apache/archiva/webdav/AbstractRepositoryServletTestCase.java
+++ b/archiva-modules/archiva-web/archiva-webdav/src/test/java/org/apache/archiva/webdav/AbstractRepositoryServletTestCase.java
@@ -190,7 +190,9 @@ public abstract class AbstractRepositoryServletTestCase
         ArchivaIndexingContext ctx = repositoryRegistry.getManagedRepository( REPOID_INTERNAL ).getIndexingContext( );
         try
         {
-            repositoryRegistry.getIndexManager( RepositoryType.MAVEN ).pack( ctx );
+            if (repositoryRegistry.getIndexManager(RepositoryType.MAVEN)!=null) {
+                repositoryRegistry.getIndexManager(RepositoryType.MAVEN).pack(ctx);
+            }
         } finally
         {
             ctx.close(  );
@@ -810,6 +812,8 @@ public abstract class AbstractRepositoryServletTestCase
         repo.setLocation( location.toAbsolutePath().toString() );
         repo.setBlockRedeployments( blockRedeployments );
         repo.setType( "MAVEN" );
+        repo.setIndexDir(".indexer");
+        repo.setPackedIndexDir(".index");
 
         return repo;
     }
@@ -835,7 +839,7 @@ public abstract class AbstractRepositoryServletTestCase
         throws Exception
     {
         repositoryRegistry.setArchivaConfiguration(archivaConfiguration);
-        repositoryRegistry.reload();
+        // repositoryRegistry.reload();
         archivaConfiguration.save( archivaConfiguration.getConfiguration() );
 
     }


[archiva] 05/08: Fixing search test

Posted by ma...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

martin_s pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/archiva.git

commit 71919be853aadbc9d7632e4f8d66c8f19e35ab5f
Author: Martin Stockhammer <ma...@apache.org>
AuthorDate: Fri Sep 20 17:11:16 2019 +0200

    Fixing search test
---
 .../indexer/maven/search/MavenRepositorySearchTest.java     |   2 +-
 .../src/test/repo-release/{.index => .indexer}/_8.fdt       | Bin
 .../src/test/repo-release/{.index => .indexer}/_8.fdx       | Bin
 .../src/test/repo-release/{.index => .indexer}/_8.fnm       | Bin
 .../src/test/repo-release/{.index => .indexer}/_8.nvd       | Bin
 .../src/test/repo-release/{.index => .indexer}/_8.nvm       | Bin
 .../src/test/repo-release/{.index => .indexer}/_8.si        | Bin
 .../repo-release/{.index => .indexer}/_8_Lucene41_0.doc     | Bin
 .../repo-release/{.index => .indexer}/_8_Lucene41_0.pos     | Bin
 .../repo-release/{.index => .indexer}/_8_Lucene41_0.tim     | Bin
 .../repo-release/{.index => .indexer}/_8_Lucene41_0.tip     | Bin
 .../src/test/repo-release/{.index => .indexer}/segments.gen | Bin
 .../src/test/repo-release/{.index => .indexer}/segments_9   | Bin
 .../src/test/repo-release/{.index => .indexer}/timestamp    | Bin
 .../src/test/repo-release/{.index => .indexer}/write.lock   |   0
 15 files changed, 1 insertion(+), 1 deletion(-)

diff --git a/archiva-modules/archiva-maven/archiva-maven-indexer/src/test/java/org/apache/archiva/indexer/maven/search/MavenRepositorySearchTest.java b/archiva-modules/archiva-maven/archiva-maven-indexer/src/test/java/org/apache/archiva/indexer/maven/search/MavenRepositorySearchTest.java
index 0b5b1bd..261c1f7 100644
--- a/archiva-modules/archiva-maven/archiva-maven-indexer/src/test/java/org/apache/archiva/indexer/maven/search/MavenRepositorySearchTest.java
+++ b/archiva-modules/archiva-maven/archiva-maven-indexer/src/test/java/org/apache/archiva/indexer/maven/search/MavenRepositorySearchTest.java
@@ -897,7 +897,7 @@ public class MavenRepositorySearchTest
 
         Path repo = Paths.get( "target/repo-release" );
         FileUtils.deleteDirectory(repo.toFile());
-        Path indexDirectory = repo.resolve(".index" );
+        Path indexDirectory = repo.resolve(".indexer" );
         FileUtils.copyDirectoryStructure( Paths.get( "src/test/repo-release" ).toFile(), repo.toFile() );
 
         IndexUpgrader.main( new String[]{ indexDirectory.toAbsolutePath().toString() } );
diff --git a/archiva-modules/archiva-maven/archiva-maven-indexer/src/test/repo-release/.index/_8.fdt b/archiva-modules/archiva-maven/archiva-maven-indexer/src/test/repo-release/.indexer/_8.fdt
similarity index 100%
rename from archiva-modules/archiva-maven/archiva-maven-indexer/src/test/repo-release/.index/_8.fdt
rename to archiva-modules/archiva-maven/archiva-maven-indexer/src/test/repo-release/.indexer/_8.fdt
diff --git a/archiva-modules/archiva-maven/archiva-maven-indexer/src/test/repo-release/.index/_8.fdx b/archiva-modules/archiva-maven/archiva-maven-indexer/src/test/repo-release/.indexer/_8.fdx
similarity index 100%
rename from archiva-modules/archiva-maven/archiva-maven-indexer/src/test/repo-release/.index/_8.fdx
rename to archiva-modules/archiva-maven/archiva-maven-indexer/src/test/repo-release/.indexer/_8.fdx
diff --git a/archiva-modules/archiva-maven/archiva-maven-indexer/src/test/repo-release/.index/_8.fnm b/archiva-modules/archiva-maven/archiva-maven-indexer/src/test/repo-release/.indexer/_8.fnm
similarity index 100%
rename from archiva-modules/archiva-maven/archiva-maven-indexer/src/test/repo-release/.index/_8.fnm
rename to archiva-modules/archiva-maven/archiva-maven-indexer/src/test/repo-release/.indexer/_8.fnm
diff --git a/archiva-modules/archiva-maven/archiva-maven-indexer/src/test/repo-release/.index/_8.nvd b/archiva-modules/archiva-maven/archiva-maven-indexer/src/test/repo-release/.indexer/_8.nvd
similarity index 100%
rename from archiva-modules/archiva-maven/archiva-maven-indexer/src/test/repo-release/.index/_8.nvd
rename to archiva-modules/archiva-maven/archiva-maven-indexer/src/test/repo-release/.indexer/_8.nvd
diff --git a/archiva-modules/archiva-maven/archiva-maven-indexer/src/test/repo-release/.index/_8.nvm b/archiva-modules/archiva-maven/archiva-maven-indexer/src/test/repo-release/.indexer/_8.nvm
similarity index 100%
rename from archiva-modules/archiva-maven/archiva-maven-indexer/src/test/repo-release/.index/_8.nvm
rename to archiva-modules/archiva-maven/archiva-maven-indexer/src/test/repo-release/.indexer/_8.nvm
diff --git a/archiva-modules/archiva-maven/archiva-maven-indexer/src/test/repo-release/.index/_8.si b/archiva-modules/archiva-maven/archiva-maven-indexer/src/test/repo-release/.indexer/_8.si
similarity index 100%
rename from archiva-modules/archiva-maven/archiva-maven-indexer/src/test/repo-release/.index/_8.si
rename to archiva-modules/archiva-maven/archiva-maven-indexer/src/test/repo-release/.indexer/_8.si
diff --git a/archiva-modules/archiva-maven/archiva-maven-indexer/src/test/repo-release/.index/_8_Lucene41_0.doc b/archiva-modules/archiva-maven/archiva-maven-indexer/src/test/repo-release/.indexer/_8_Lucene41_0.doc
similarity index 100%
rename from archiva-modules/archiva-maven/archiva-maven-indexer/src/test/repo-release/.index/_8_Lucene41_0.doc
rename to archiva-modules/archiva-maven/archiva-maven-indexer/src/test/repo-release/.indexer/_8_Lucene41_0.doc
diff --git a/archiva-modules/archiva-maven/archiva-maven-indexer/src/test/repo-release/.index/_8_Lucene41_0.pos b/archiva-modules/archiva-maven/archiva-maven-indexer/src/test/repo-release/.indexer/_8_Lucene41_0.pos
similarity index 100%
rename from archiva-modules/archiva-maven/archiva-maven-indexer/src/test/repo-release/.index/_8_Lucene41_0.pos
rename to archiva-modules/archiva-maven/archiva-maven-indexer/src/test/repo-release/.indexer/_8_Lucene41_0.pos
diff --git a/archiva-modules/archiva-maven/archiva-maven-indexer/src/test/repo-release/.index/_8_Lucene41_0.tim b/archiva-modules/archiva-maven/archiva-maven-indexer/src/test/repo-release/.indexer/_8_Lucene41_0.tim
similarity index 100%
rename from archiva-modules/archiva-maven/archiva-maven-indexer/src/test/repo-release/.index/_8_Lucene41_0.tim
rename to archiva-modules/archiva-maven/archiva-maven-indexer/src/test/repo-release/.indexer/_8_Lucene41_0.tim
diff --git a/archiva-modules/archiva-maven/archiva-maven-indexer/src/test/repo-release/.index/_8_Lucene41_0.tip b/archiva-modules/archiva-maven/archiva-maven-indexer/src/test/repo-release/.indexer/_8_Lucene41_0.tip
similarity index 100%
rename from archiva-modules/archiva-maven/archiva-maven-indexer/src/test/repo-release/.index/_8_Lucene41_0.tip
rename to archiva-modules/archiva-maven/archiva-maven-indexer/src/test/repo-release/.indexer/_8_Lucene41_0.tip
diff --git a/archiva-modules/archiva-maven/archiva-maven-indexer/src/test/repo-release/.index/segments.gen b/archiva-modules/archiva-maven/archiva-maven-indexer/src/test/repo-release/.indexer/segments.gen
similarity index 100%
rename from archiva-modules/archiva-maven/archiva-maven-indexer/src/test/repo-release/.index/segments.gen
rename to archiva-modules/archiva-maven/archiva-maven-indexer/src/test/repo-release/.indexer/segments.gen
diff --git a/archiva-modules/archiva-maven/archiva-maven-indexer/src/test/repo-release/.index/segments_9 b/archiva-modules/archiva-maven/archiva-maven-indexer/src/test/repo-release/.indexer/segments_9
similarity index 100%
rename from archiva-modules/archiva-maven/archiva-maven-indexer/src/test/repo-release/.index/segments_9
rename to archiva-modules/archiva-maven/archiva-maven-indexer/src/test/repo-release/.indexer/segments_9
diff --git a/archiva-modules/archiva-maven/archiva-maven-indexer/src/test/repo-release/.index/timestamp b/archiva-modules/archiva-maven/archiva-maven-indexer/src/test/repo-release/.indexer/timestamp
similarity index 100%
rename from archiva-modules/archiva-maven/archiva-maven-indexer/src/test/repo-release/.index/timestamp
rename to archiva-modules/archiva-maven/archiva-maven-indexer/src/test/repo-release/.indexer/timestamp
diff --git a/archiva-modules/archiva-maven/archiva-maven-indexer/src/test/repo-release/.index/write.lock b/archiva-modules/archiva-maven/archiva-maven-indexer/src/test/repo-release/.indexer/write.lock
similarity index 100%
rename from archiva-modules/archiva-maven/archiva-maven-indexer/src/test/repo-release/.index/write.lock
rename to archiva-modules/archiva-maven/archiva-maven-indexer/src/test/repo-release/.indexer/write.lock


[archiva] 03/08: Fixing proxy connector handling

Posted by ma...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

martin_s pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/archiva.git

commit d9d87966655ca4a82e9be780caf3f70b2bcdc853
Author: Martin Stockhammer <ma...@apache.org>
AuthorDate: Thu Sep 12 13:10:22 2019 +0200

    Fixing proxy connector handling
---
 .../apache/archiva/proxy/ArchivaProxyRegistry.java | 34 +++++++++++++++-------
 .../managed/ManagedRepositoryAdminTest.java        |  1 -
 .../archiva/proxy/HttpProxyTransferTest.java       |  2 ++
 .../maven2/ArchivaRepositoryConnectorFactory.java  |  2 ++
 .../repository/maven2/MavenRepositoryProvider.java |  8 +++--
 .../maven2/DependencyTreeBuilderTestMaven3.java    |  2 ++
 6 files changed, 36 insertions(+), 13 deletions(-)

diff --git a/archiva-modules/archiva-base/archiva-proxy/src/main/java/org/apache/archiva/proxy/ArchivaProxyRegistry.java b/archiva-modules/archiva-base/archiva-proxy/src/main/java/org/apache/archiva/proxy/ArchivaProxyRegistry.java
index 17b1f4e..b59091a 100644
--- a/archiva-modules/archiva-base/archiva-proxy/src/main/java/org/apache/archiva/proxy/ArchivaProxyRegistry.java
+++ b/archiva-modules/archiva-base/archiva-proxy/src/main/java/org/apache/archiva/proxy/ArchivaProxyRegistry.java
@@ -27,6 +27,9 @@ import org.apache.archiva.proxy.model.NetworkProxy;
 import org.apache.archiva.proxy.model.ProxyConnector;
 import org.apache.archiva.proxy.model.RepositoryProxyHandler;
 import org.apache.archiva.repository.*;
+import org.apache.archiva.repository.events.Event;
+import org.apache.archiva.repository.events.RepositoryEventListener;
+import org.apache.archiva.repository.events.RepositoryRegistryEvent;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.stereotype.Service;
@@ -44,7 +47,7 @@ import java.util.stream.Collectors;
  */
 @SuppressWarnings( "SpringJavaInjectionPointsAutowiringInspection" )
 @Service("proxyRegistry#default")
-public class ArchivaProxyRegistry implements ProxyRegistry, ConfigurationListener {
+public class ArchivaProxyRegistry implements ProxyRegistry, RepositoryEventListener {
 
     private static final Logger log = LoggerFactory.getLogger(ArchivaProxyRegistry.class);
 
@@ -74,10 +77,10 @@ public class ArchivaProxyRegistry implements ProxyRegistry, ConfigurationListene
         if (repositoryProxyHandlers == null) {
             repositoryProxyHandlers = new ArrayList<>();
         }
-        archivaConfiguration.addListener( this );
         updateHandler();
         updateConnectors();
         updateNetworkProxies();
+        repositoryRegistry.register(this, RepositoryRegistryEvent.RegistryEventType.RELOADED);
     }
 
     private ArchivaConfiguration getArchivaConfiguration() {
@@ -125,7 +128,9 @@ public class ArchivaProxyRegistry implements ProxyRegistry, ConfigurationListene
             getArchivaConfiguration().getConfiguration().getProxyConnectors();
 
         connectorList = proxyConnectorConfigurations.stream()
-                .map(configuration -> buildProxyConnector(configuration))
+                .map(this::buildProxyConnector)
+                .filter(Optional::isPresent)
+                .map(Optional::get)
                 .sorted(comparator).collect(Collectors.toList());
         connectorMap = connectorList.stream().collect(Collectors.groupingBy(a -> a.getSourceRepository().getId()));
         for (RepositoryProxyHandler handler : repositoryProxyHandlers) {
@@ -139,7 +144,7 @@ public class ArchivaProxyRegistry implements ProxyRegistry, ConfigurationListene
         return policies.stream().collect( Collectors.toMap( Function.identity(), p -> PolicyUtil.findOption( policyConfig.get(p.getId()), p ) ) );
     }
 
-    private ProxyConnector buildProxyConnector(ProxyConnectorConfiguration configuration) {
+    private Optional<ProxyConnector> buildProxyConnector(ProxyConnectorConfiguration configuration) {
         ProxyConnector proxyConnector = new ProxyConnector();
         proxyConnector.setOrder(configuration.getOrder());
         proxyConnector.setBlacklist(configuration.getBlackListPatterns());
@@ -153,10 +158,16 @@ public class ArchivaProxyRegistry implements ProxyRegistry, ConfigurationListene
         proxyConnector.setProperties(configuration.getProperties());
         proxyConnector.setProxyId(configuration.getProxyId());
         ManagedRepository srcRepo = repositoryRegistry.getManagedRepository(configuration.getSourceRepoId());
+        if (srcRepo==null) {
+            return Optional.empty();
+        }
         proxyConnector.setSourceRepository(srcRepo);
         RemoteRepository targetRepo = repositoryRegistry.getRemoteRepository(configuration.getTargetRepoId());
+        if (targetRepo==null) {
+            return Optional.empty();
+        }
         proxyConnector.setTargetRepository(targetRepo);
-        return proxyConnector;
+        return Optional.of(proxyConnector);
     }
 
     @Override
@@ -183,11 +194,6 @@ public class ArchivaProxyRegistry implements ProxyRegistry, ConfigurationListene
         return this.handlerMap.containsKey(type);
     }
 
-    @Override
-    public void configurationEvent(ConfigurationEvent event) {
-        log.debug("Config changed updating proxy list");
-        init( );
-    }
 
     @Override
     public List<ProxyConnector> getProxyConnectors() {
@@ -205,4 +211,12 @@ public class ArchivaProxyRegistry implements ProxyRegistry, ConfigurationListene
     {
         init();
     }
+
+    @Override
+    public void raise(Event event) {
+        log.debug("Reload happened, updating proxy list");
+        if (event.getType()== RepositoryRegistryEvent.RegistryEventType.RELOADED) {
+            init();
+        }
+    }
 }
diff --git a/archiva-modules/archiva-base/archiva-repository-admin/archiva-repository-admin-default/src/test/java/org/apache/archiva/admin/repository/managed/ManagedRepositoryAdminTest.java b/archiva-modules/archiva-base/archiva-repository-admin/archiva-repository-admin-default/src/test/java/org/apache/archiva/admin/repository/managed/ManagedRepositoryAdminTest.java
index 05b40c3..2e542d5 100644
--- a/archiva-modules/archiva-base/archiva-repository-admin/archiva-repository-admin-default/src/test/java/org/apache/archiva/admin/repository/managed/ManagedRepositoryAdminTest.java
+++ b/archiva-modules/archiva-base/archiva-repository-admin/archiva-repository-admin-default/src/test/java/org/apache/archiva/admin/repository/managed/ManagedRepositoryAdminTest.java
@@ -316,7 +316,6 @@ public class ManagedRepositoryAdminTest
         managedRepositoryAdmin.updateManagedRepository( repo, true, getFakeAuditInformation(), false );
 
         repo = managedRepositoryAdmin.getManagedRepository( repoId );
-        System.err.println("REPOSITORY "+repo.getLocation());
         assertNotNull( repo );
         assertEquals( newName, repo.getName() );
         assertEquals( Paths.get( repoLocation ).toAbsolutePath(), Paths.get( repo.getLocation() ).toAbsolutePath() );
diff --git a/archiva-modules/archiva-maven/archiva-maven-proxy/src/test/java/org/apache/archiva/proxy/HttpProxyTransferTest.java b/archiva-modules/archiva-maven/archiva-maven-proxy/src/test/java/org/apache/archiva/proxy/HttpProxyTransferTest.java
index b35967f..dd74487 100644
--- a/archiva-modules/archiva-maven/archiva-maven-proxy/src/test/java/org/apache/archiva/proxy/HttpProxyTransferTest.java
+++ b/archiva-modules/archiva-maven/archiva-maven-proxy/src/test/java/org/apache/archiva/proxy/HttpProxyTransferTest.java
@@ -219,6 +219,8 @@ public class HttpProxyTransferTest
         // Configure Connector (usually done within archiva.xml configuration)
         addConnector();
 
+        managedDefaultRepository = repositoryRegistry.getManagedRepository(MANAGED_ID).getContent();
+
         Path expectedFile = Paths.get( managedDefaultRepository.getRepoRoot() ).resolve( path );
         Files.deleteIfExists( expectedFile );
         ArtifactReference artifact = managedDefaultRepository.toArtifactReference( path );
diff --git a/archiva-modules/archiva-maven/archiva-maven-repository/src/main/java/org/apache/archiva/dependency/tree/maven2/ArchivaRepositoryConnectorFactory.java b/archiva-modules/archiva-maven/archiva-maven-repository/src/main/java/org/apache/archiva/dependency/tree/maven2/ArchivaRepositoryConnectorFactory.java
index dd401ae..f099292 100644
--- a/archiva-modules/archiva-maven/archiva-maven-repository/src/main/java/org/apache/archiva/dependency/tree/maven2/ArchivaRepositoryConnectorFactory.java
+++ b/archiva-modules/archiva-maven/archiva-maven-repository/src/main/java/org/apache/archiva/dependency/tree/maven2/ArchivaRepositoryConnectorFactory.java
@@ -19,6 +19,7 @@ package org.apache.archiva.dependency.tree.maven2;
  */
 
 import org.eclipse.aether.connector.basic.BasicRepositoryConnectorFactory;
+import org.eclipse.aether.internal.impl.DefaultRepositoryLayoutProvider;
 import org.eclipse.aether.spi.connector.RepositoryConnectorFactory;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -49,6 +50,7 @@ public class ArchivaRepositoryConnectorFactory
     public ArchivaRepositoryConnectorFactory()
     {
         // no op but empty constructor needed by aether
+        delegate.setRepositoryLayoutProvider(new DefaultRepositoryLayoutProvider());
     }
 
     @Override
diff --git a/archiva-modules/archiva-maven/archiva-maven-repository/src/main/java/org/apache/archiva/repository/maven2/MavenRepositoryProvider.java b/archiva-modules/archiva-maven/archiva-maven-repository/src/main/java/org/apache/archiva/repository/maven2/MavenRepositoryProvider.java
index cdc03db..15dbf6a 100644
--- a/archiva-modules/archiva-maven/archiva-maven-repository/src/main/java/org/apache/archiva/repository/maven2/MavenRepositoryProvider.java
+++ b/archiva-modules/archiva-maven/archiva-maven-repository/src/main/java/org/apache/archiva/repository/maven2/MavenRepositoryProvider.java
@@ -22,6 +22,8 @@ package org.apache.archiva.repository.maven2;
 import org.apache.archiva.common.filelock.FileLockManager;
 import org.apache.archiva.configuration.*;
 import org.apache.archiva.repository.*;
+import org.apache.archiva.repository.events.Event;
+import org.apache.archiva.repository.events.RepositoryValueEvent;
 import org.apache.archiva.repository.storage.FilesystemStorage;
 import org.apache.archiva.repository.features.ArtifactCleanupFeature;
 import org.apache.archiva.repository.features.IndexCreationFeature;
@@ -347,7 +349,9 @@ public class MavenRepositoryProvider implements RepositoryProvider {
         cfg.setPackedIndexDir(convertUriToPath(indexCreationFeature.getPackedIndexPath()));
 
         RemoteIndexFeature remoteIndexFeature = remoteRepository.getFeature(RemoteIndexFeature.class).get();
-        cfg.setRemoteIndexUrl(remoteIndexFeature.getIndexUri().toString());
+        if (remoteIndexFeature.getIndexUri()!=null) {
+            cfg.setRemoteIndexUrl(remoteIndexFeature.getIndexUri().toString());
+        }
         cfg.setRemoteDownloadTimeout((int) remoteIndexFeature.getDownloadTimeout().get(ChronoUnit.SECONDS));
         cfg.setDownloadRemoteIndexOnStartup(remoteIndexFeature.isDownloadRemoteIndexOnStartup());
         cfg.setDownloadRemoteIndex(remoteIndexFeature.isDownloadRemoteIndex());
@@ -495,7 +499,7 @@ public class MavenRepositoryProvider implements RepositoryProvider {
     }
 
     @Override
-    public <T> void raise(RepositoryEvent<T> event) {
+    public void raise(Event event) {
         //
     }
 
diff --git a/archiva-modules/archiva-maven/archiva-maven-repository/src/test/java/org/apache/archiva/dependency/tree/maven2/DependencyTreeBuilderTestMaven3.java b/archiva-modules/archiva-maven/archiva-maven-repository/src/test/java/org/apache/archiva/dependency/tree/maven2/DependencyTreeBuilderTestMaven3.java
index fb0b802..df2f104 100644
--- a/archiva-modules/archiva-maven/archiva-maven-repository/src/test/java/org/apache/archiva/dependency/tree/maven2/DependencyTreeBuilderTestMaven3.java
+++ b/archiva-modules/archiva-maven/archiva-maven-repository/src/test/java/org/apache/archiva/dependency/tree/maven2/DependencyTreeBuilderTestMaven3.java
@@ -81,6 +81,8 @@ public class DependencyTreeBuilderTestMaven3
         repoConfig.setId( TEST_REPO_ID );
         repoConfig.setLocation(Paths.get("target/test-repository").toAbsolutePath().toString() );
         configuration.addManagedRepository( repoConfig );
+
+        config.getConfiguration().getProxyConnectors().clear();
         config.save( configuration );
 
         repositoryRegistry.reload();


[archiva] 07/08: Adding null checks for index manager

Posted by ma...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

martin_s pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/archiva.git

commit d9f8834dc181923a466f57e46791cd3383d89cb4
Author: Martin Stockhammer <ma...@apache.org>
AuthorDate: Sun Sep 22 00:08:17 2019 +0200

    Adding null checks for index manager
---
 .../apache/archiva/indexer/maven/MavenIndexManager.java  | 16 ++++++++++++----
 1 file changed, 12 insertions(+), 4 deletions(-)

diff --git a/archiva-modules/archiva-maven/archiva-maven-indexer/src/main/java/org/apache/archiva/indexer/maven/MavenIndexManager.java b/archiva-modules/archiva-maven/archiva-maven-indexer/src/main/java/org/apache/archiva/indexer/maven/MavenIndexManager.java
index 73a8900..4a4ad80 100644
--- a/archiva-modules/archiva-maven/archiva-maven-indexer/src/main/java/org/apache/archiva/indexer/maven/MavenIndexManager.java
+++ b/archiva-modules/archiva-maven/archiva-maven-indexer/src/main/java/org/apache/archiva/indexer/maven/MavenIndexManager.java
@@ -149,12 +149,17 @@ public class MavenIndexManager implements ArchivaIndexManager {
 
     public static IndexingContext getMvnContext( ArchivaIndexingContext context ) throws UnsupportedBaseContextException
     {
-        if ( !context.supports( IndexingContext.class ) )
+        if (context!=null)
         {
-            log.error( "The provided archiva index context does not support the maven IndexingContext" );
-            throw new UnsupportedBaseContextException( "The context does not support the Maven IndexingContext" );
+            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 );
+        } else {
+            return null;
         }
-        return context.getBaseContext( IndexingContext.class );
     }
 
     private StorageAsset getIndexPath( ArchivaIndexingContext ctx )
@@ -175,6 +180,9 @@ public class MavenIndexManager implements ArchivaIndexManager {
      */
     private void executeUpdateFunction( ArchivaIndexingContext context, IndexUpdateConsumer function ) throws IndexUpdateFailedException
     {
+        if (context==null) {
+            throw new IndexUpdateFailedException( "Given context is null" );
+        }
         IndexingContext indexingContext = null;
         try
         {


[archiva] 01/08: Proxy changes

Posted by ma...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

martin_s pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/archiva.git

commit b072f6921df0b59843f9c411b292b467dbe0f01a
Author: Martin Stockhammer <ma...@apache.org>
AuthorDate: Sun Sep 8 21:05:34 2019 +0200

    Proxy changes
---
 .../AbstractRepositoryConnectorConfiguration.java  |   8 +-
 .../org/apache/archiva/proxy/ProxyRegistry.java    |   9 +-
 .../apache/archiva/proxy/model/ProxyConnector.java | 120 +++++--
 .../proxy/model/RepositoryProxyHandler.java        | 123 ++++++--
 .../apache/archiva/proxy/ArchivaProxyRegistry.java |  50 ++-
 .../proxy/DefaultRepositoryProxyHandler.java       | 349 +++++++++------------
 .../repository/connector/RepositoryConnector.java  |  41 ++-
 .../proxy/maven/MavenRepositoryProxyHandler.java   |  74 +++--
 .../archiva/proxy/AbstractProxyTestCase.java       |   9 +-
 .../archiva/proxy/CacheFailuresTransferTest.java   |  18 +-
 .../apache/archiva/proxy/ChecksumTransferTest.java |  40 +--
 .../apache/archiva/proxy/ErrorHandlingTest.java    |   8 +-
 .../archiva/proxy/HttpProxyTransferTest.java       |  25 +-
 .../archiva/proxy/ManagedDefaultTransferTest.java  |  33 +-
 .../apache/archiva/proxy/MetadataTransferTest.java |  12 +-
 .../apache/archiva/proxy/MockConfiguration.java    |   5 +
 .../apache/archiva/proxy/SnapshotTransferTest.java |  18 +-
 .../org/apache/archiva/proxy/WagonDelegate.java    |   8 +-
 .../src/test/resources/spring-context.xml          |   6 +-
 .../storage/maven2/Maven2RepositoryStorage.java    |   6 +-
 .../rest/services/DefaultBrowseService.java        |   4 +-
 .../archiva/security/mock/MockBeanServices.java    |   3 +-
 .../archiva/webdav/ArchivaDavResourceFactory.java  |  16 +-
 .../webdav/OverridingRepositoryProxyHandler.java   |   8 +-
 .../repository/storage/RepositoryStorage.java      |   3 +-
 .../cassandra/MockRepositoryStorage.java           |   3 +-
 26 files changed, 609 insertions(+), 390 deletions(-)

diff --git a/archiva-modules/archiva-base/archiva-configuration/src/main/java/org/apache/archiva/configuration/AbstractRepositoryConnectorConfiguration.java b/archiva-modules/archiva-base/archiva-configuration/src/main/java/org/apache/archiva/configuration/AbstractRepositoryConnectorConfiguration.java
index 22a4bc6..5a7bc58 100644
--- a/archiva-modules/archiva-base/archiva-configuration/src/main/java/org/apache/archiva/configuration/AbstractRepositoryConnectorConfiguration.java
+++ b/archiva-modules/archiva-base/archiva-configuration/src/main/java/org/apache/archiva/configuration/AbstractRepositoryConnectorConfiguration.java
@@ -103,7 +103,7 @@ public class AbstractRepositoryConnectorConfiguration
      * @param key
      * @param value
      */
-    public void addPolicy( Object key, String value )
+    public void addPolicy( String key, String value )
     {
         getPolicies().put( key, value );
     } //-- void addPolicy( Object, String )
@@ -114,7 +114,7 @@ public class AbstractRepositoryConnectorConfiguration
      * @param key
      * @param value
      */
-    public void addProperty( Object key, String value )
+    public void addProperty( String key, String value )
     {
         getProperties().put( key, value );
     } //-- void addProperty( Object, String )
@@ -149,7 +149,7 @@ public class AbstractRepositoryConnectorConfiguration
      * 
      * @return Map
      */
-    public java.util.Map getPolicies()
+    public java.util.Map<String, String> getPolicies()
     {
         if ( this.policies == null )
         {
@@ -164,7 +164,7 @@ public class AbstractRepositoryConnectorConfiguration
      * 
      * @return Map
      */
-    public java.util.Map getProperties()
+    public java.util.Map<String, String> getProperties()
     {
         if ( this.properties == null )
         {
diff --git a/archiva-modules/archiva-base/archiva-proxy-api/src/main/java/org/apache/archiva/proxy/ProxyRegistry.java b/archiva-modules/archiva-base/archiva-proxy-api/src/main/java/org/apache/archiva/proxy/ProxyRegistry.java
index f01d23a..89e31f1 100644
--- a/archiva-modules/archiva-base/archiva-proxy-api/src/main/java/org/apache/archiva/proxy/ProxyRegistry.java
+++ b/archiva-modules/archiva-base/archiva-proxy-api/src/main/java/org/apache/archiva/proxy/ProxyRegistry.java
@@ -69,11 +69,16 @@ public interface ProxyRegistry {
      * Returns the list of all proxy connectors.
      * @return
      */
-    public List<org.apache.archiva.proxy.model.ProxyConnector> getProxyConnectors();
+    List<org.apache.archiva.proxy.model.ProxyConnector> getProxyConnectors( );
 
     /**
      * Returns a map of connector lists with the source repository id as key
      * @return A map with source repository ids as key and list of corresponding proxy connector objects as value.
      */
-    public Map<String, List<ProxyConnector>> getProxyConnectorAsMap();
+    Map<String, List<ProxyConnector>> getProxyConnectorAsMap( );
+
+    /**
+     * Reloads the proxies from the configuration.
+     */
+    void reload();
 }
diff --git a/archiva-modules/archiva-base/archiva-proxy-api/src/main/java/org/apache/archiva/proxy/model/ProxyConnector.java b/archiva-modules/archiva-base/archiva-proxy-api/src/main/java/org/apache/archiva/proxy/model/ProxyConnector.java
index 8ad2a4b..763616c 100644
--- a/archiva-modules/archiva-base/archiva-proxy-api/src/main/java/org/apache/archiva/proxy/model/ProxyConnector.java
+++ b/archiva-modules/archiva-base/archiva-proxy-api/src/main/java/org/apache/archiva/proxy/model/ProxyConnector.java
@@ -19,10 +19,10 @@ package org.apache.archiva.proxy.model;
  * under the License.
  */
 
+import org.apache.archiva.policies.Policy;
+import org.apache.archiva.policies.PolicyOption;
 import org.apache.archiva.repository.ManagedRepository;
-import org.apache.archiva.repository.ManagedRepositoryContent;
 import org.apache.archiva.repository.RemoteRepository;
-import org.apache.archiva.repository.RemoteRepositoryContent;
 import org.apache.archiva.repository.connector.RepositoryConnector;
 
 import java.util.Iterator;
@@ -30,7 +30,7 @@ import java.util.List;
 import java.util.Map;
 
 /**
- * This represents a connector for a repository to repository proxy.
+ * This represents a connector for a repository to a remote repository that is proxied.
  */
 public class ProxyConnector
     implements RepositoryConnector
@@ -47,9 +47,9 @@ public class ProxyConnector
 
     private int order;
 
-    private Map<String, String> policies;
+    private Map<Policy, PolicyOption> policies;
 
-    private boolean disabled;
+    private boolean enabled;
 
     private Map<String, String> properties;
 
@@ -58,77 +58,148 @@ public class ProxyConnector
         // no op
     }
 
+    /**
+     * @see RepositoryConnector#isEnabled()
+     */
     @Override
-    public boolean isDisabled()
+    public boolean isEnabled()
     {
-        return disabled;
+        return enabled;
     }
 
+
+    /**
+     * @see RepositoryConnector#enable()
+     */
+    @Override
+    public void enable()
+    {
+        this.enabled = true;
+    }
+
+    /**
+     * @see RepositoryConnector#disable()
+     */
     @Override
-    public void setDisabled( boolean disabled )
+    public void disable( )
     {
-        this.disabled = disabled;
+        this.enabled = false;
     }
 
+    /**
+     * @see RepositoryConnector#getBlacklist()
+     */
     @Override
     public List<String> getBlacklist()
     {
         return blacklist;
     }
 
+    /**
+     * Sets the blacklist. The list is a string of paths.
+     *
+     * @param blacklist List of paths.
+     */
     public void setBlacklist( List<String> blacklist )
     {
         this.blacklist = blacklist;
     }
 
+    /**
+     * @see RepositoryConnector#getSourceRepository()
+     */
     @Override
     public ManagedRepository getSourceRepository()
     {
         return sourceRepository;
     }
 
+    /**
+     * Sets the source repository.
+     * @param sourceRepository The managed repository which is the local representation of the proxy.
+     */
     public void setSourceRepository( ManagedRepository sourceRepository )
     {
         this.sourceRepository = sourceRepository;
     }
 
+    /**
+     * @see ProxyConnector#getTargetRepository()
+     */
     @Override
     public RemoteRepository getTargetRepository()
     {
         return targetRepository;
     }
 
+    /**
+     * Sets the target repository.
+     * @param targetRepository The remote repository, where the artifacts are downloaded from.
+     */
     public void setTargetRepository( RemoteRepository targetRepository )
     {
         this.targetRepository = targetRepository;
     }
 
+    /**
+     * @see ProxyConnector#getWhitelist()
+     */
     @Override
     public List<String> getWhitelist()
     {
         return whitelist;
     }
 
+    /**
+     * Sets the list of paths that are proxied.
+     * @param whitelist List of paths.
+     */
     public void setWhitelist( List<String> whitelist )
     {
         this.whitelist = whitelist;
     }
 
-    public Map<String, String> getPolicies()
+    /**
+     * Returns the policies that are defined
+     * @return
+     */
+    public Map<Policy, PolicyOption> getPolicies()
     {
         return policies;
     }
 
-    public void setPolicies( Map<String, String> policies )
+    /**
+     * Sets policies that set the behaviour of this proxy connector.
+     * @param policies A map of policies with each option.
+     */
+    public void setPolicies( Map<Policy, PolicyOption> policies )
     {
         this.policies = policies;
     }
 
+    /**
+     * Adds a new policy.
+     * @param policy The policy to add.
+     * @param option  The option for the policy.
+     */
+    public void addPolicy( Policy policy, PolicyOption option )
+    {
+        this.policies.put( policy, option );
+    }
+
+    /**
+     * Returns the id of this proxy connector.
+     * @return The id string.
+     */
     public String getProxyId()
     {
         return proxyId;
     }
 
+    /**
+     * Sets the id of this proxy connector.
+     * @param proxyId A id string.
+     */
     public void setProxyId( String proxyId )
     {
         this.proxyId = proxyId;
@@ -144,10 +215,10 @@ public class ProxyConnector
         sb.append( "  target: [remote] " ).append( this.targetRepository.getId() ).append( "\n" );
         sb.append( "  proxyId:" ).append( this.proxyId ).append( "\n" );
 
-        Iterator<String> keys = this.policies.keySet().iterator();
+        Iterator<Policy> keys = this.policies.keySet().iterator();
         while ( keys.hasNext() )
         {
-            String name = keys.next();
+            String name = keys.next().getId();
             sb.append( "  policy[" ).append( name ).append( "]:" );
             sb.append( this.policies.get( name ) ).append( "\n" );
         }
@@ -157,26 +228,37 @@ public class ProxyConnector
         return sb.toString();
     }
 
-    public void setPolicy( String policyId, String policySetting )
-    {
-        this.policies.put( policyId, policySetting );
-    }
-
+    /**
+     * Returns a number that orders the proxy connectors numerically.
+     * @return The order number of this connector.
+     */
     public int getOrder()
     {
         return order;
     }
 
+    /**
+     * Set the order number of this proxy connector.
+     *
+     * @param order The order number.
+     */
     public void setOrder( int order )
     {
         this.order = order;
     }
 
-
+    /**
+     * Returns additional properties defined for this connector.
+     * @return Map of key, value pairs.
+     */
     public Map<String, String> getProperties() {
         return properties;
     }
 
+    /**
+     * Sets additional properties for this connector.
+     * @param properties Map of key, value pairs.
+     */
     public void setProperties(Map<String, String> properties) {
         this.properties = properties;
     }
diff --git a/archiva-modules/archiva-base/archiva-proxy-api/src/main/java/org/apache/archiva/proxy/model/RepositoryProxyHandler.java b/archiva-modules/archiva-base/archiva-proxy-api/src/main/java/org/apache/archiva/proxy/model/RepositoryProxyHandler.java
index efcd901..dc13b11 100644
--- a/archiva-modules/archiva-base/archiva-proxy-api/src/main/java/org/apache/archiva/proxy/model/RepositoryProxyHandler.java
+++ b/archiva-modules/archiva-base/archiva-proxy-api/src/main/java/org/apache/archiva/proxy/model/RepositoryProxyHandler.java
@@ -20,8 +20,9 @@ package org.apache.archiva.proxy.model;
  */
 
 import org.apache.archiva.model.ArtifactReference;
+import org.apache.archiva.policies.Policy;
 import org.apache.archiva.policies.ProxyDownloadException;
-import org.apache.archiva.repository.ManagedRepositoryContent;
+import org.apache.archiva.repository.ManagedRepository;
 import org.apache.archiva.repository.RepositoryType;
 import org.apache.archiva.repository.storage.StorageAsset;
 
@@ -29,76 +30,148 @@ import java.util.List;
 import java.util.Map;
 
 /**
- * Handler for potential repository proxy connectors.
+ * A repository proxy handler is used to fetch remote artifacts from different remote repositories.
+ * A proxy handler is connected to one managed repository and a list of remote repositories.
  *
+ * Repository proxies should not be confused with network proxies. Network are proxies for specific network protocols,
+ * like HTTP. A repository proxy delegates the repository requests to remote repositories and caches artifacts.
+ *
+ * If a artifact is requested for the managed repository and the artifact is not cached locally, the handler goes through
+ * the list of remotes and tries to download the artifact. If a download was successful the artifact is cached locally.
+ *
+ * The connection between managed and remote repositories is defined by list of {@link ProxyConnector} each defines a one-to-one relationship.
+ *
+ * A proxy connector defines specifics about the download behaviour:
+ * <ul>
+ * <li>Policies {@link org.apache.archiva.policies.Policy} define the behaviour for different cases (errors, not available, caching lifetime).</li>
+ * <li>Black- and Whitelists are used to ban or allow certain paths on the remote repositories.
+ * </ul>
+ *
+ * The policies and black- and whitelist are set on the {@link ProxyConnector}
+ *
+ * There may be network proxies needed to connect the remote repositories.
  *
  */
 public interface RepositoryProxyHandler
 {
 
-    List<RepositoryType> supports();
+    List<RepositoryType> supports( );
 
     /**
      * Performs the artifact fetch operation against the target repositories
      * of the provided source repository.
-     * 
+     * <p>
      * If the artifact is found, it is downloaded and placed into the source repository
      * filesystem.
-     * 
+     *
      * @param repository the source repository to use. (must be a managed repository)
-     * @param artifact the artifact to fetch.
+     * @param artifact   the artifact to fetch.
      * @return the file that was obtained, or null if no content was obtained
      * @throws ProxyDownloadException if there was a problem fetching the content from the target repositories.
      */
-    StorageAsset fetchFromProxies( ManagedRepositoryContent repository, ArtifactReference artifact )
+    StorageAsset fetchFromProxies( ManagedRepository repository, ArtifactReference artifact )
         throws ProxyDownloadException;
-    
+
     /**
      * Performs the metadata fetch operation against the target repositories
      * of the provided source repository.
-     * 
+     * <p>
      * If the metadata is found, it is downloaded and placed into the source repository
      * filesystem.
-     * 
-     * @param repository the source repository to use. (must be a managed repository)
+     *
+     * @param repository  the source repository to use. (must be a managed repository)
      * @param logicalPath the metadata to fetch.
      * @return the file that was obtained, or null if no content was obtained
      */
-    ProxyFetchResult fetchMetadataFromProxies( ManagedRepositoryContent repository, String logicalPath );
+    ProxyFetchResult fetchMetadataFromProxies( ManagedRepository repository, String logicalPath );
 
     /**
      * Performs the fetch operation against the target repositories
-     * of the provided source repository.
-     * 
+     * of the provided source repository by a specific path.
+     *
      * @param managedRepository the source repository to use. (must be a managed repository)
-     * @param path the path of the resource to fetch
+     * @param path              the path of the resource to fetch
      * @return the file that was obtained, or null if no content was obtained
      */
-    StorageAsset fetchFromProxies( ManagedRepositoryContent managedRepository, String path );
+    StorageAsset fetchFromProxies( ManagedRepository managedRepository, String path );
 
     /**
      * Get the List of {@link ProxyConnector} objects of the source repository.
-     * 
+     *
      * @param repository the source repository to look for.
      * @return the List of {@link ProxyConnector} objects.
      */
-    List<ProxyConnector> getProxyConnectors( ManagedRepositoryContent repository );
+    List<ProxyConnector> getProxyConnectors( ManagedRepository repository );
 
     /**
      * Tests to see if the provided repository is a source repository for
      * any {@link ProxyConnector} objects.
-     * 
+     *
      * @param repository the source repository to look for.
-     * @return true if there are proxy connectors that use the provided 
-     *   repository as a source repository.
+     * @return true if there are proxy connectors that use the provided
+     * repository as a source repository.
      */
-    boolean hasProxies( ManagedRepositoryContent repository );
+    boolean hasProxies( ManagedRepository repository );
 
-    void setNetworkProxies(Map<String, NetworkProxy> proxies);
+    /**
+     * Sets network proxies (normally HTTP proxies) to access the remote repositories.
+     *
+     * @param networkProxies A map of (repository id, network proxy) where the repository id must be the id of an
+     *                existing remote repository.
+     */
+    void setNetworkProxies( Map<String, NetworkProxy> networkProxies );
 
-    Map<String, NetworkProxy> getNetworkProxies();
+    /**
+     * Adds a network proxy that is used to access the remote repository.
+     *
+     * @param id The repository id
+     * @param networkProxy The network proxy to use
+     */
+    void addNetworkproxy( String id, NetworkProxy networkProxy);
+
+    /**
+     * Returns a map of the defined network proxies, or a empty map, if no proxy is defined.
+     *
+     * @return A map (repository id, network proxy). If none is defined, a empty map is returned.
+     */
+    Map<String, NetworkProxy> getNetworkProxies( );
 
-    NetworkProxy getNetworkProxy(String id);
+    /**
+     * Returns the network proxy that is defined for the given repository id.
+     * @param id The remote repository id
+     * @return A network proxy or <code>null</code> if no one is defined for this id.
+     */
+    NetworkProxy getNetworkProxy( String id );
+
+    /**
+     * Returns the proxy handler implementation. This can be used, if the underlying implementation for a specific
+     * repository type is needed.
+     *
+     * @param clazz The class to convert to
+     * @param <T>   The type
+     * @return The handler
+     */
+    <T extends RepositoryProxyHandler> T getHandler( Class<T> clazz ) throws IllegalArgumentException;
+
+    /**
+     * Sets the policies that this handler should validate.
+     * @param policyList
+     */
+    void setPolicies(List<Policy> policyList);
+
+    /**
+     * Adds a policy
+     * @param policy
+     */
+    void addPolicy( Policy policy );
+
+    /**
+     * Removes a policy
+     * @param policy
+     */
+    void removePolicy( Policy policy );
 
+    void addProxyConnector(ProxyConnector connector);
 
+    void setProxyConnectors( List<ProxyConnector> proxyConnectors );
 }
diff --git a/archiva-modules/archiva-base/archiva-proxy/src/main/java/org/apache/archiva/proxy/ArchivaProxyRegistry.java b/archiva-modules/archiva-base/archiva-proxy/src/main/java/org/apache/archiva/proxy/ArchivaProxyRegistry.java
index 3036212..17b1f4e 100644
--- a/archiva-modules/archiva-base/archiva-proxy/src/main/java/org/apache/archiva/proxy/ArchivaProxyRegistry.java
+++ b/archiva-modules/archiva-base/archiva-proxy/src/main/java/org/apache/archiva/proxy/ArchivaProxyRegistry.java
@@ -20,6 +20,9 @@ package org.apache.archiva.proxy;
  */
 
 import org.apache.archiva.configuration.*;
+import org.apache.archiva.policies.Policy;
+import org.apache.archiva.policies.PolicyOption;
+import org.apache.archiva.policies.PolicyUtil;
 import org.apache.archiva.proxy.model.NetworkProxy;
 import org.apache.archiva.proxy.model.ProxyConnector;
 import org.apache.archiva.proxy.model.RepositoryProxyHandler;
@@ -31,6 +34,7 @@ import org.springframework.stereotype.Service;
 import javax.annotation.PostConstruct;
 import javax.inject.Inject;
 import java.util.*;
+import java.util.function.Function;
 import java.util.stream.Collectors;
 
 /**
@@ -38,6 +42,7 @@ import java.util.stream.Collectors;
  * proxy information.
  *
  */
+@SuppressWarnings( "SpringJavaInjectionPointsAutowiringInspection" )
 @Service("proxyRegistry#default")
 public class ArchivaProxyRegistry implements ProxyRegistry, ConfigurationListener {
 
@@ -50,6 +55,9 @@ public class ArchivaProxyRegistry implements ProxyRegistry, ConfigurationListene
     List<RepositoryProxyHandler> repositoryProxyHandlers;
 
     @Inject
+    List<Policy> policies;
+
+    @Inject
     RepositoryRegistry repositoryRegistry;
 
     private Map<String, NetworkProxy> networkProxyMap = new HashMap<>();
@@ -58,6 +66,7 @@ public class ArchivaProxyRegistry implements ProxyRegistry, ConfigurationListene
 
     private Map<String, List<ProxyConnector>> connectorMap = new HashMap<>();
     private List<ProxyConnector> connectorList = new ArrayList<>();
+    private Map<Policy, PolicyOption> policyMap = new HashMap<>( );
 
 
     @PostConstruct
@@ -65,7 +74,9 @@ public class ArchivaProxyRegistry implements ProxyRegistry, ConfigurationListene
         if (repositoryProxyHandlers == null) {
             repositoryProxyHandlers = new ArrayList<>();
         }
+        archivaConfiguration.addListener( this );
         updateHandler();
+        updateConnectors();
         updateNetworkProxies();
     }
 
@@ -85,17 +96,18 @@ public class ArchivaProxyRegistry implements ProxyRegistry, ConfigurationListene
             proxy.setHost(networkProxyConfig.getHost());
             proxy.setPort(networkProxyConfig.getPort());
             proxy.setUsername(networkProxyConfig.getUsername());
-            proxy.setPassword(networkProxyConfig.getPassword().toCharArray());
+            proxy.setPassword(networkProxyConfig.getPassword()==null? new char[0] : networkProxyConfig.getPassword().toCharArray());
             proxy.setUseNtlm(networkProxyConfig.isUseNtlm());
 
             this.networkProxyMap.put(key, proxy);
         }
-        for (RepositoryProxyHandler connectors : repositoryProxyHandlers) {
-            connectors.setNetworkProxies(this.networkProxyMap);
+        for (RepositoryProxyHandler proxyHandler : repositoryProxyHandlers) {
+            proxyHandler.setNetworkProxies(this.networkProxyMap);
         }
     }
 
-    private void updateHandler() {
+    private void updateHandler( ) {
+
         for (RepositoryProxyHandler handler : repositoryProxyHandlers) {
             List<RepositoryType> types = handler.supports();
             for (RepositoryType type : types) {
@@ -104,16 +116,27 @@ public class ArchivaProxyRegistry implements ProxyRegistry, ConfigurationListene
                 }
                 handlerMap.get(type).add(handler);
             }
+            handler.setPolicies( policies );
         }
     }
 
     private void updateConnectors() {
         List<ProxyConnectorConfiguration> proxyConnectorConfigurations =
-                getArchivaConfiguration().getConfiguration().getProxyConnectors();
+            getArchivaConfiguration().getConfiguration().getProxyConnectors();
+
         connectorList = proxyConnectorConfigurations.stream()
                 .map(configuration -> buildProxyConnector(configuration))
                 .sorted(comparator).collect(Collectors.toList());
         connectorMap = connectorList.stream().collect(Collectors.groupingBy(a -> a.getSourceRepository().getId()));
+        for (RepositoryProxyHandler handler : repositoryProxyHandlers) {
+            handler.setProxyConnectors( connectorList );
+        }
+    }
+
+
+    private Map<Policy, PolicyOption> getPolicyMap(ProxyConnectorConfiguration configuration) {
+        Map<String, String> policyConfig = configuration.getPolicies( );
+        return policies.stream().collect( Collectors.toMap( Function.identity(), p -> PolicyUtil.findOption( policyConfig.get(p.getId()), p ) ) );
     }
 
     private ProxyConnector buildProxyConnector(ProxyConnectorConfiguration configuration) {
@@ -121,8 +144,12 @@ public class ArchivaProxyRegistry implements ProxyRegistry, ConfigurationListene
         proxyConnector.setOrder(configuration.getOrder());
         proxyConnector.setBlacklist(configuration.getBlackListPatterns());
         proxyConnector.setWhitelist(configuration.getWhiteListPatterns());
-        proxyConnector.setDisabled(configuration.isDisabled());
-        proxyConnector.setPolicies(configuration.getPolicies());
+        if (configuration.isDisabled()) {
+            proxyConnector.disable();
+        } else {
+            proxyConnector.enable();
+        }
+        proxyConnector.setPolicies(getPolicyMap( configuration ));
         proxyConnector.setProperties(configuration.getProperties());
         proxyConnector.setProxyId(configuration.getProxyId());
         ManagedRepository srcRepo = repositoryRegistry.getManagedRepository(configuration.getSourceRepoId());
@@ -159,8 +186,7 @@ public class ArchivaProxyRegistry implements ProxyRegistry, ConfigurationListene
     @Override
     public void configurationEvent(ConfigurationEvent event) {
         log.debug("Config changed updating proxy list");
-        updateNetworkProxies();
-        updateConnectors();
+        init( );
     }
 
     @Override
@@ -173,4 +199,10 @@ public class ArchivaProxyRegistry implements ProxyRegistry, ConfigurationListene
     public Map<String, List<ProxyConnector>> getProxyConnectorAsMap() {
         return connectorMap;
     }
+
+    @Override
+    public void reload( )
+    {
+        init();
+    }
 }
diff --git a/archiva-modules/archiva-base/archiva-proxy/src/main/java/org/apache/archiva/proxy/DefaultRepositoryProxyHandler.java b/archiva-modules/archiva-base/archiva-proxy/src/main/java/org/apache/archiva/proxy/DefaultRepositoryProxyHandler.java
index f954158..11e8154 100644
--- a/archiva-modules/archiva-base/archiva-proxy/src/main/java/org/apache/archiva/proxy/DefaultRepositoryProxyHandler.java
+++ b/archiva-modules/archiva-base/archiva-proxy/src/main/java/org/apache/archiva/proxy/DefaultRepositoryProxyHandler.java
@@ -21,26 +21,36 @@ package org.apache.archiva.proxy;
 
 import org.apache.archiva.checksum.ChecksumAlgorithm;
 import org.apache.archiva.checksum.ChecksumUtil;
-import org.apache.archiva.proxy.model.ProxyConnectorRuleType;
 import org.apache.archiva.common.filelock.FileLockManager;
-import org.apache.archiva.configuration.*;
+import org.apache.archiva.configuration.ArchivaConfiguration;
+import org.apache.archiva.configuration.ProxyConnectorConfiguration;
+import org.apache.archiva.configuration.ProxyConnectorRuleConfiguration;
 import org.apache.archiva.model.ArtifactReference;
 import org.apache.archiva.model.Keys;
-import org.apache.archiva.policies.*;
+import org.apache.archiva.policies.DownloadErrorPolicy;
+import org.apache.archiva.policies.DownloadPolicy;
+import org.apache.archiva.policies.Policy;
+import org.apache.archiva.policies.PolicyConfigurationException;
+import org.apache.archiva.policies.PolicyOption;
+import org.apache.archiva.policies.PolicyViolationException;
+import org.apache.archiva.policies.PostDownloadPolicy;
+import org.apache.archiva.policies.PreDownloadPolicy;
+import org.apache.archiva.policies.ProxyDownloadException;
 import org.apache.archiva.policies.urlcache.UrlFailureCache;
 import org.apache.archiva.proxy.model.NetworkProxy;
 import org.apache.archiva.proxy.model.ProxyConnector;
 import org.apache.archiva.proxy.model.ProxyFetchResult;
 import org.apache.archiva.proxy.model.RepositoryProxyHandler;
-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.*;
+import org.apache.archiva.repository.ManagedRepository;
+import org.apache.archiva.repository.RemoteRepository;
+import org.apache.archiva.repository.RemoteRepositoryContent;
+import org.apache.archiva.repository.RepositoryType;
+import org.apache.archiva.repository.metadata.MetadataTools;
+import org.apache.archiva.repository.metadata.RepositoryMetadataException;
 import org.apache.archiva.repository.storage.FilesystemStorage;
 import org.apache.archiva.repository.storage.StorageAsset;
 import org.apache.archiva.repository.storage.StorageUtil;
-import org.apache.archiva.repository.metadata.MetadataTools;
-import org.apache.archiva.repository.metadata.RepositoryMetadataException;
 import org.apache.archiva.scheduler.ArchivaTaskScheduler;
 import org.apache.archiva.scheduler.repository.model.RepositoryTask;
 import org.apache.commons.collections4.CollectionUtils;
@@ -56,41 +66,41 @@ import javax.annotation.PostConstruct;
 import javax.inject.Inject;
 import javax.inject.Named;
 import java.io.IOException;
+import java.net.MalformedURLException;
 import java.nio.file.Files;
 import java.nio.file.Path;
 import java.nio.file.StandardCopyOption;
-import java.util.*;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Properties;
 import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.ConcurrentMap;
-import java.util.stream.Collectors;
 
-public abstract class DefaultRepositoryProxyHandler implements RepositoryProxyHandler, RegistryListener {
+public abstract class DefaultRepositoryProxyHandler implements RepositoryProxyHandler {
 
     protected Logger log = LoggerFactory.getLogger( DefaultRepositoryProxyHandler.class );
     @Inject
     protected UrlFailureCache urlFailureCache;
 
     @Inject
-    @Named(value = "archivaConfiguration#default")
-    private ArchivaConfiguration archivaConfiguration;
-
-    @Inject
     @Named(value = "metadataTools#default")
     private MetadataTools metadataTools;
 
-    @Inject
-    private Map<String, PreDownloadPolicy> preDownloadPolicies;
-    @Inject
-    private Map<String, PostDownloadPolicy> postDownloadPolicies;
-    @Inject
-    private Map<String, DownloadErrorPolicy> downloadErrorPolicies;
+    private Map<String, PreDownloadPolicy> preDownloadPolicies = new HashMap<>(  );
+    private Map<String, PostDownloadPolicy> postDownloadPolicies = new HashMap<>(  );
+    private Map<String, DownloadErrorPolicy> downloadErrorPolicies = new HashMap<>(  );
     private ConcurrentMap<String, List<ProxyConnector>> proxyConnectorMap = new ConcurrentHashMap<>();
 
     @Inject
     @Named(value = "archivaTaskScheduler#repository")
     private ArchivaTaskScheduler<RepositoryTask> scheduler;
+
     @Inject
-    private RepositoryRegistry repositoryRegistry;
+    private ArchivaConfiguration archivaConfiguration;
 
     @Inject
     @Named(value = "fileLockManager#default")
@@ -102,113 +112,7 @@ public abstract class DefaultRepositoryProxyHandler implements RepositoryProxyHa
     @PostConstruct
     public void initialize()
     {
-        initConnectors();
-        archivaConfiguration.addChangeListener( this );
         checksumAlgorithms = ChecksumUtil.getAlgorithms(archivaConfiguration.getConfiguration().getArchivaRuntimeConfiguration().getChecksumTypes());
-
-    }
-
-    @SuppressWarnings("unchecked")
-    private void initConnectors()
-    {
-
-        ProxyConnectorOrderComparator proxyOrderSorter = new ProxyConnectorOrderComparator();
-        this.proxyConnectorMap.clear();
-
-        Configuration configuration = archivaConfiguration.getConfiguration();
-
-        List<ProxyConnectorRuleConfiguration> allProxyConnectorRuleConfigurations =
-            configuration.getProxyConnectorRuleConfigurations();
-
-        List<ProxyConnectorConfiguration> proxyConfigs = configuration.getProxyConnectors();
-        for ( ProxyConnectorConfiguration proxyConfig : proxyConfigs )
-        {
-            String key = proxyConfig.getSourceRepoId();
-
-            // Create connector object.
-            ProxyConnector connector = new ProxyConnector();
-
-            ManagedRepository repo = repositoryRegistry.getManagedRepository( proxyConfig.getSourceRepoId( ) );
-            if (repo==null) {
-                log.error("Cannot find source repository after config change "+proxyConfig.getSourceRepoId());
-                continue;
-            }
-            connector.setSourceRepository(repo);
-            RemoteRepository rRepo = repositoryRegistry.getRemoteRepository( proxyConfig.getTargetRepoId() );
-            if (rRepo==null) {
-                log.error("Cannot find target repository after config change "+proxyConfig.getSourceRepoId());
-                continue;
-            }
-            connector.setTargetRepository(rRepo);
-
-            connector.setProxyId( proxyConfig.getProxyId() );
-            connector.setPolicies( proxyConfig.getPolicies() );
-            connector.setOrder( proxyConfig.getOrder() );
-            connector.setDisabled( proxyConfig.isDisabled() );
-
-            // Copy any blacklist patterns.
-            List<String> blacklist = new ArrayList<>( 0 );
-            if ( CollectionUtils.isNotEmpty( proxyConfig.getBlackListPatterns() ) )
-            {
-                blacklist.addAll( proxyConfig.getBlackListPatterns() );
-            }
-            connector.setBlacklist( blacklist );
-
-            // Copy any whitelist patterns.
-            List<String> whitelist = new ArrayList<>( 0 );
-            if ( CollectionUtils.isNotEmpty( proxyConfig.getWhiteListPatterns() ) )
-            {
-                whitelist.addAll( proxyConfig.getWhiteListPatterns() );
-            }
-            connector.setWhitelist( whitelist );
-
-            List<ProxyConnectorRuleConfiguration> proxyConnectorRuleConfigurations =
-                findProxyConnectorRules( connector.getSourceRepository().getId(),
-                                         connector.getTargetRepository().getId(),
-                                         allProxyConnectorRuleConfigurations );
-
-            if ( !proxyConnectorRuleConfigurations.isEmpty() )
-            {
-                for ( ProxyConnectorRuleConfiguration proxyConnectorRuleConfiguration : proxyConnectorRuleConfigurations )
-                {
-                    if ( StringUtils.equals( proxyConnectorRuleConfiguration.getRuleType(),
-                                             ProxyConnectorRuleType.BLACK_LIST.getRuleType() ) )
-                    {
-                        connector.getBlacklist().add( proxyConnectorRuleConfiguration.getPattern() );
-                    }
-
-                    if ( StringUtils.equals( proxyConnectorRuleConfiguration.getRuleType(),
-                                             ProxyConnectorRuleType.WHITE_LIST.getRuleType() ) )
-                    {
-                        connector.getWhitelist().add( proxyConnectorRuleConfiguration.getPattern() );
-                    }
-                }
-            }
-
-            // Get other connectors
-            List<ProxyConnector> connectors = this.proxyConnectorMap.get( key );
-            if ( connectors == null )
-            {
-                // Create if we are the first.
-                connectors = new ArrayList<>( 1 );
-            }
-
-            // Add the connector.
-            connectors.add( connector );
-
-            // Ensure the list is sorted.
-            Collections.sort( connectors, proxyOrderSorter );
-
-            // Set the key to the list of connectors.
-            this.proxyConnectorMap.put( key, connectors );
-
-
-        }
-
-
-
-
-
     }
 
     private List<ProxyConnectorRuleConfiguration> findProxyConnectorRules(String sourceRepository,
@@ -232,23 +136,8 @@ public abstract class DefaultRepositoryProxyHandler implements RepositoryProxyHa
         return proxyConnectorRuleConfigurations;
     }
 
-    private void updateNetworkProxies() {
-        Map<String, NetworkProxy> proxies = archivaConfiguration.getConfiguration().getNetworkProxies().stream().map(p -> {
-            NetworkProxy np = new NetworkProxy();
-            np.setId(p.getId());
-            np.setUseNtlm(p.isUseNtlm());
-            np.setUsername(p.getUsername());
-            np.setPassword(p.getPassword() == null ? new char[0] : p.getPassword().toCharArray());
-            np.setProtocol(p.getProtocol());
-            np.setHost(p.getHost());
-            np.setPort(p.getPort());
-            return np;
-        }).collect(Collectors.toMap(p -> p.getId(), p -> p));
-        setNetworkProxies(proxies);
-    }
-
     @Override
-    public StorageAsset fetchFromProxies( ManagedRepositoryContent repository, ArtifactReference artifact )
+    public StorageAsset fetchFromProxies( ManagedRepository repository, ArtifactReference artifact )
         throws ProxyDownloadException
     {
         StorageAsset localFile = toLocalFile( repository, artifact );
@@ -262,7 +151,7 @@ public abstract class DefaultRepositoryProxyHandler implements RepositoryProxyHa
         Map<String, Exception> previousExceptions = new LinkedHashMap<>();
         for ( ProxyConnector connector : connectors )
         {
-            if ( connector.isDisabled() )
+            if ( !connector.isEnabled() )
             {
                 continue;
             }
@@ -281,7 +170,7 @@ public abstract class DefaultRepositoryProxyHandler implements RepositoryProxyHa
             try
             {
                 StorageAsset downloadedFile =
-                    transferFile( connector, targetRepository.getContent(), targetPath, repository, localFile, requestProperties,
+                    transferFile( connector, targetRepository, targetPath, repository, localFile, requestProperties,
                                   true );
 
                 if ( fileExists(downloadedFile) )
@@ -319,9 +208,9 @@ public abstract class DefaultRepositoryProxyHandler implements RepositoryProxyHa
     }
 
     @Override
-    public StorageAsset fetchFromProxies( ManagedRepositoryContent repository, String path )
+    public StorageAsset fetchFromProxies( ManagedRepository repository, String path )
     {
-        StorageAsset localFile = repository.getRepository().getAsset( path );
+        StorageAsset localFile = repository.getAsset( path );
 
         // no update policies for these paths
         if ( localFile.exists() )
@@ -336,7 +225,7 @@ public abstract class DefaultRepositoryProxyHandler implements RepositoryProxyHa
         List<ProxyConnector> connectors = getProxyConnectors( repository );
         for ( ProxyConnector connector : connectors )
         {
-            if ( connector.isDisabled() )
+            if ( !connector.isEnabled() )
             {
                 continue;
             }
@@ -349,7 +238,7 @@ public abstract class DefaultRepositoryProxyHandler implements RepositoryProxyHa
             try
             {
                 StorageAsset downloadedFile =
-                    transferFile( connector, targetRepository.getContent(), targetPath, repository, localFile, requestProperties,
+                    transferFile( connector, targetRepository, targetPath, repository, localFile, requestProperties,
                                   false );
 
                 if ( fileExists( downloadedFile ) )
@@ -387,9 +276,9 @@ public abstract class DefaultRepositoryProxyHandler implements RepositoryProxyHa
     }
 
     @Override
-    public ProxyFetchResult fetchMetadataFromProxies(ManagedRepositoryContent repository, String logicalPath )
+    public ProxyFetchResult fetchMetadataFromProxies( ManagedRepository repository, String logicalPath )
     {
-        StorageAsset localFile = repository.getRepository().getAsset( logicalPath );
+        StorageAsset localFile = repository.getAsset( logicalPath );
 
         Properties requestProperties = new Properties();
         requestProperties.setProperty( "filetype", "metadata" );
@@ -399,7 +288,7 @@ public abstract class DefaultRepositoryProxyHandler implements RepositoryProxyHa
         List<ProxyConnector> connectors = new ArrayList<>( getProxyConnectors( repository ) );
         for ( ProxyConnector connector : connectors )
         {
-            if ( connector.isDisabled() )
+            if ( !connector.isEnabled() )
             {
                 continue;
             }
@@ -411,7 +300,7 @@ public abstract class DefaultRepositoryProxyHandler implements RepositoryProxyHa
 
             try
             {
-                transferFile( connector, targetRepository.getContent(), logicalPath, repository, localRepoFile, requestProperties,
+                transferFile( connector, targetRepository, logicalPath, repository, localRepoFile, requestProperties,
                               true );
 
                 if ( hasBeenUpdated( localRepoFile, originalMetadataTimestamp ) )
@@ -451,7 +340,7 @@ public abstract class DefaultRepositoryProxyHandler implements RepositoryProxyHa
         {
             try
             {
-                metadataTools.updateMetadata( repository, logicalPath );
+                metadataTools.updateMetadata( repository.getContent(), logicalPath );
             }
             catch ( RepositoryMetadataException e )
             {
@@ -489,18 +378,19 @@ public abstract class DefaultRepositoryProxyHandler implements RepositoryProxyHa
         return ( currentLastModified > originalLastModified );
     }
 
-    private StorageAsset toLocalRepoFile( ManagedRepositoryContent repository, RemoteRepositoryContent targetRepository,
+    private StorageAsset toLocalRepoFile( ManagedRepository repository, RemoteRepositoryContent targetRepository,
                                           String targetPath )
     {
         String repoPath = metadataTools.getRepositorySpecificName( targetRepository, targetPath );
-        return repository.getRepository().getAsset( repoPath );
+        return repository.getAsset( repoPath );
     }
 
     /**
      * Test if the provided ManagedRepositoryContent has any proxies configured for it.
+     * @param repository
      */
     @Override
-    public boolean hasProxies( ManagedRepositoryContent repository )
+    public boolean hasProxies( ManagedRepository repository )
     {
         synchronized ( this.proxyConnectorMap )
         {
@@ -508,9 +398,9 @@ public abstract class DefaultRepositoryProxyHandler implements RepositoryProxyHa
         }
     }
 
-    private StorageAsset toLocalFile(ManagedRepositoryContent repository, ArtifactReference artifact )
+    private StorageAsset toLocalFile(ManagedRepository repository, ArtifactReference artifact )
     {
-        return repository.toFile( artifact );
+        return repository.getContent().toFile( artifact );
     }
 
     /**
@@ -550,12 +440,20 @@ public abstract class DefaultRepositoryProxyHandler implements RepositoryProxyHa
      *                              the remote resource is not newer than the local File.
      * @throws ProxyException       if transfer was unsuccessful.
      */
-    protected StorageAsset transferFile( ProxyConnector connector, RemoteRepositoryContent remoteRepository, String remotePath,
-                                         ManagedRepositoryContent repository, StorageAsset resource, Properties requestProperties,
+    protected StorageAsset transferFile( ProxyConnector connector, RemoteRepository remoteRepository, String remotePath,
+                                         ManagedRepository repository, StorageAsset resource, Properties requestProperties,
                                          boolean executeConsumers )
         throws ProxyException, NotModifiedException
     {
-        String url = remoteRepository.getURL().getUrl();
+        String url = null;
+        try
+        {
+            url = remoteRepository.getLocation().toURL().toString();
+        }
+        catch ( MalformedURLException e )
+        {
+            throw new ProxyException( e.getMessage(), e );
+        }
         if ( !url.endsWith( "/" ) )
         {
             url = url + "/";
@@ -570,7 +468,7 @@ public abstract class DefaultRepositoryProxyHandler implements RepositoryProxyHa
             if ( !matchesPattern( remotePath, connector.getWhitelist() ) )
             {
                 log.debug( "Path [{}] is not part of defined whitelist (skipping transfer from repository [{}]).",
-                           remotePath, remoteRepository.getRepository().getName() );
+                           remotePath, remoteRepository.getId() );
                 return null;
             }
         }
@@ -579,7 +477,7 @@ public abstract class DefaultRepositoryProxyHandler implements RepositoryProxyHa
         if ( matchesPattern( remotePath, connector.getBlacklist() ) )
         {
             log.debug( "Path [{}] is part of blacklist (skipping transfer from repository [{}]).", remotePath,
-                       remoteRepository.getRepository().getName() );
+                       remoteRepository.getId() );
             return null;
         }
 
@@ -666,9 +564,9 @@ public abstract class DefaultRepositoryProxyHandler implements RepositoryProxyHa
         return resource;
     }
 
-    protected abstract void transferResources( ProxyConnector connector, RemoteRepositoryContent remoteRepository,
+    protected abstract void transferResources( ProxyConnector connector, RemoteRepository remoteRepository,
                                                StorageAsset tmpResource, StorageAsset[] checksumFiles, String url, String remotePath, StorageAsset resource, Path workingDirectory,
-                                               ManagedRepositoryContent repository ) throws ProxyException;
+                                               ManagedRepository repository ) throws ProxyException;
 
     private void queueRepositoryTask(String repositoryId, StorageAsset localFile )
     {
@@ -716,7 +614,7 @@ public abstract class DefaultRepositoryProxyHandler implements RepositoryProxyHa
      * @param localFile the local file (utilized by the {@link DownloadPolicy#applyPolicy(PolicyOption, Properties, StorageAsset)})
      * @throws PolicyViolationException
      */
-    private void validatePolicies( Map<String, ? extends DownloadPolicy> policies, Map<String, String> settings,
+    private void validatePolicies( Map<String, ? extends DownloadPolicy> policies, Map<Policy, PolicyOption> settings,
                                    Properties request, StorageAsset localFile )
         throws PolicyViolationException
     {
@@ -724,9 +622,9 @@ public abstract class DefaultRepositoryProxyHandler implements RepositoryProxyHa
         {
             // olamy with spring rolehint is now downloadPolicy#hint
             // so substring after last # to get the hint as with plexus
-            String key = StringUtils.substringAfterLast( entry.getKey(), "#" );
+            String key = entry.getValue( ).getId( );
             DownloadPolicy policy = entry.getValue();
-            PolicyOption option = PolicyUtil.findOption(settings.get(key), policy);
+            PolicyOption option = settings.containsKey(policy ) ? settings.get(policy) : policy.getDefaultOption();
 
             log.debug( "Applying [{}] policy with [{}]", key, option );
             try
@@ -740,7 +638,7 @@ public abstract class DefaultRepositoryProxyHandler implements RepositoryProxyHa
         }
     }
 
-    private void validatePolicies( Map<String, DownloadErrorPolicy> policies, Map<String, String> settings,
+    private void validatePolicies( Map<String, DownloadErrorPolicy> policies, Map<Policy, PolicyOption> settings,
                                    Properties request, ArtifactReference artifact, RemoteRepositoryContent content,
                                    StorageAsset localFile, Exception exception, Map<String, Exception> previousExceptions )
         throws ProxyDownloadException
@@ -751,9 +649,9 @@ public abstract class DefaultRepositoryProxyHandler implements RepositoryProxyHa
 
             // olamy with spring rolehint is now downloadPolicy#hint
             // so substring after last # to get the hint as with plexus
-            String key = StringUtils.substringAfterLast( entry.getKey(), "#" );
+            String key = entry.getValue( ).getId( );
             DownloadErrorPolicy policy = entry.getValue();
-            PolicyOption option = PolicyUtil.findOption(settings.get(key), policy);
+            PolicyOption option = settings.containsKey( policy ) ? settings.get(policy) : policy.getDefaultOption();
 
             log.debug( "Applying [{}] policy with [{}]", key, option );
             try
@@ -799,7 +697,7 @@ public abstract class DefaultRepositoryProxyHandler implements RepositoryProxyHa
      * @param repository
      * @return file location of working directory
      */
-    private Path createWorkingDirectory( ManagedRepositoryContent repository )
+    private Path createWorkingDirectory( ManagedRepository repository )
     {
         try
         {
@@ -883,9 +781,10 @@ public abstract class DefaultRepositoryProxyHandler implements RepositoryProxyHa
 
     /**
      * TODO: Ensure that list is correctly ordered based on configuration. See MRM-477
+     * @param repository
      */
     @Override
-    public List<ProxyConnector> getProxyConnectors( ManagedRepositoryContent repository )
+    public List<ProxyConnector> getProxyConnectors( ManagedRepository repository )
     {
 
         if ( !this.proxyConnectorMap.containsKey( repository.getId() ) )
@@ -899,18 +798,6 @@ public abstract class DefaultRepositoryProxyHandler implements RepositoryProxyHa
 
     }
 
-    @Override
-    public void afterConfigurationChange(Registry registry, String propertyName, Object propertyValue )
-    {
-        if ( ConfigurationNames.isManagedRepositories( propertyName ) //
-            || ConfigurationNames.isRemoteRepositories( propertyName ) //
-            || ConfigurationNames.isProxyConnector( propertyName ) ) //
-        {
-            initConnectors();
-        } else if (ConfigurationNames.isNetworkProxy(propertyName)) {
-            updateNetworkProxies();
-        }
-    }
 
     protected String addParameters(String path, RemoteRepository remoteRepository )
     {
@@ -934,17 +821,6 @@ public abstract class DefaultRepositoryProxyHandler implements RepositoryProxyHa
         return res.toString();
     }
 
-    @Override
-    public void beforeConfigurationChange( Registry registry, String propertyName, Object propertyValue )
-    {
-        /* do nothing */
-    }
-
-    public ArchivaConfiguration getArchivaConfiguration()
-    {
-        return archivaConfiguration;
-    }
-
     public void setArchivaConfiguration(ArchivaConfiguration archivaConfiguration )
     {
         this.archivaConfiguration = archivaConfiguration;
@@ -1001,9 +877,9 @@ public abstract class DefaultRepositoryProxyHandler implements RepositoryProxyHa
     }
 
     @Override
-    public void setNetworkProxies(Map<String, NetworkProxy> proxies) {
+    public void setNetworkProxies(Map<String, NetworkProxy> networkProxies ) {
         this.networkProxyMap.clear();
-        this.networkProxyMap.putAll(proxies);
+        this.networkProxyMap.putAll( networkProxies );
     }
 
     @Override
@@ -1018,4 +894,77 @@ public abstract class DefaultRepositoryProxyHandler implements RepositoryProxyHa
 
     @Override
     public abstract List<RepositoryType> supports();
+
+    @Override
+    public void setPolicies( List<Policy> policyList )
+    {
+        preDownloadPolicies.clear();
+        postDownloadPolicies.clear();
+        downloadErrorPolicies.clear();
+        for (Policy policy : policyList) {
+            addPolicy( policy );
+        }
+    }
+
+    void addPolicy(PreDownloadPolicy policy) {
+        preDownloadPolicies.put( policy.getId( ), policy );
+    }
+
+    void addPolicy(PostDownloadPolicy policy) {
+        postDownloadPolicies.put( policy.getId( ), policy );
+    }
+    void addPolicy(DownloadErrorPolicy policy) {
+        downloadErrorPolicies.put( policy.getId( ), policy );
+    }
+
+    @Override
+    public void addPolicy( Policy policy )
+    {
+        if (policy instanceof PreDownloadPolicy) {
+            addPolicy( (PreDownloadPolicy)policy );
+        } else if (policy instanceof PostDownloadPolicy) {
+            addPolicy( (PostDownloadPolicy) policy );
+        } else if (policy instanceof DownloadErrorPolicy) {
+            addPolicy( (DownloadErrorPolicy) policy );
+        } else {
+            log.warn( "Policy not known: {}, {}", policy.getId( ), policy.getClass( ).getName( ) );
+        }
+    }
+
+    @Override
+    public void removePolicy( Policy policy )
+    {
+        final String id = policy.getId();
+        if (preDownloadPolicies.containsKey( id )) {
+            preDownloadPolicies.remove( id );
+        } else if (postDownloadPolicies.containsKey( id )) {
+            postDownloadPolicies.remove( id );
+        } else if (downloadErrorPolicies.containsKey( id )) {
+            downloadErrorPolicies.remove( id );
+        }
+    }
+
+    @Override
+    public void addProxyConnector( ProxyConnector connector )
+    {
+        final String sourceId = connector.getSourceRepository( ).getId( );
+        List<ProxyConnector> connectors;
+        if (proxyConnectorMap.containsKey( sourceId )) {
+            connectors = proxyConnectorMap.get( sourceId );
+        } else {
+            connectors = new ArrayList<>( );
+            proxyConnectorMap.put( sourceId, connectors );
+        }
+        connectors.add( connector );
+    }
+
+    @Override
+    public void setProxyConnectors( List<ProxyConnector> proxyConnectors )
+    {
+        proxyConnectorMap.clear();
+        for ( ProxyConnector connector : proxyConnectors )
+        {
+            addProxyConnector( connector );
+        }
+    }
 }
diff --git a/archiva-modules/archiva-base/archiva-repository-api/src/main/java/org/apache/archiva/repository/connector/RepositoryConnector.java b/archiva-modules/archiva-base/archiva-repository-api/src/main/java/org/apache/archiva/repository/connector/RepositoryConnector.java
index 1cf461c..d4ae118 100644
--- a/archiva-modules/archiva-base/archiva-repository-api/src/main/java/org/apache/archiva/repository/connector/RepositoryConnector.java
+++ b/archiva-modules/archiva-base/archiva-repository-api/src/main/java/org/apache/archiva/repository/connector/RepositoryConnector.java
@@ -32,15 +32,46 @@ import java.util.List;
  */
 public interface RepositoryConnector
 {
+    /**
+     * Returns the local repository that is connected to the remote.
+     * @return The local managed repository.
+     */
     ManagedRepository getSourceRepository();
 
+    /**
+     * Returns the remote repository that is connected to the local.
+     * @return The remote repository.
+     */
     RemoteRepository getTargetRepository();
 
+    /**
+     * Returns a list of paths that are not fetched from the remote repository.
+     * @return A list of paths.
+     */
     List<String> getBlacklist();
-    
+
+    /**
+     * Returns a list of paths that are fetched from the remote repository, even if a
+     * parent path is in the blacklist.
+     *
+     * @return The list of paths.
+     */
     List<String> getWhitelist();
-    
-    boolean isDisabled();
-    
-    void setDisabled(boolean disabled);
+
+    /**
+     * Returns true, if this connector is enabled, otherwise false.
+     * @return True, if enabled.
+     */
+    boolean isEnabled();
+
+    /**
+     * Enables this connector, if it was disabled before, otherwise does nothing.
+     */
+    void enable();
+
+    /**
+     * Disables this connector, if it was enabled before, otherwise does nothing.
+     */
+    void disable();
+
 }
diff --git a/archiva-modules/archiva-maven/archiva-maven-proxy/src/main/java/org/apache/archiva/proxy/maven/MavenRepositoryProxyHandler.java b/archiva-modules/archiva-maven/archiva-maven-proxy/src/main/java/org/apache/archiva/proxy/maven/MavenRepositoryProxyHandler.java
index 25dfcb6..b8006d3 100644
--- a/archiva-modules/archiva-maven/archiva-maven-proxy/src/main/java/org/apache/archiva/proxy/maven/MavenRepositoryProxyHandler.java
+++ b/archiva-modules/archiva-maven/archiva-maven-proxy/src/main/java/org/apache/archiva/proxy/maven/MavenRepositoryProxyHandler.java
@@ -27,6 +27,7 @@ import org.apache.archiva.proxy.NotModifiedException;
 import org.apache.archiva.proxy.ProxyException;
 import org.apache.archiva.proxy.model.NetworkProxy;
 import org.apache.archiva.proxy.model.ProxyConnector;
+import org.apache.archiva.proxy.model.RepositoryProxyHandler;
 import org.apache.archiva.repository.*;
 import org.apache.archiva.repository.storage.StorageAsset;
 import org.apache.commons.lang3.StringUtils;
@@ -55,7 +56,7 @@ import java.util.concurrent.ConcurrentMap;
  * TODO exception handling needs work - "not modified" is not really an exceptional case, and it has more layers than
  * your average brown onion
  */
-@Service("repositoryProxyConnectors#maven")
+@Service( "repositoryProxyHandler#maven" )
 public class MavenRepositoryProxyHandler extends DefaultRepositoryProxyHandler {
 
     private static final List<RepositoryType> REPOSITORY_TYPES = new ArrayList<>();
@@ -76,7 +77,6 @@ public class MavenRepositoryProxyHandler extends DefaultRepositoryProxyHandler {
 
     private void updateWagonProxyInfo(Map<String, NetworkProxy> proxyList) {
         this.networkProxyMap.clear();
-        List<NetworkProxyConfiguration> networkProxies = getArchivaConfiguration().getConfiguration().getNetworkProxies();
         for (Map.Entry<String, NetworkProxy> proxyEntry : proxyList.entrySet()) {
             String key = proxyEntry.getKey();
             NetworkProxy networkProxyDef = proxyEntry.getValue();
@@ -94,9 +94,9 @@ public class MavenRepositoryProxyHandler extends DefaultRepositoryProxyHandler {
     }
 
     @Override
-    public void setNetworkProxies(Map<String, NetworkProxy> proxies) {
-        super.setNetworkProxies(proxies);
-        updateWagonProxyInfo(proxies);
+    public void setNetworkProxies(Map<String, NetworkProxy> networkProxies ) {
+        super.setNetworkProxies( networkProxies );
+        updateWagonProxyInfo( networkProxies );
     }
 
     /**
@@ -112,13 +112,13 @@ public class MavenRepositoryProxyHandler extends DefaultRepositoryProxyHandler {
      * @throws ProxyException
      * @throws NotModifiedException
      */
-    protected void transferResources( ProxyConnector connector, RemoteRepositoryContent remoteRepository,
+    protected void transferResources( ProxyConnector connector, RemoteRepository remoteRepository,
                                       StorageAsset tmpResource, StorageAsset[] checksumFiles, String url, String remotePath, StorageAsset resource,
-                                      Path workingDirectory, ManagedRepositoryContent repository )
+                                      Path workingDirectory, ManagedRepository repository )
             throws ProxyException, NotModifiedException {
         Wagon wagon = null;
         try {
-            RepositoryURL repoUrl = remoteRepository.getURL();
+            RepositoryURL repoUrl = remoteRepository.getContent().getURL();
             String protocol = repoUrl.getProtocol();
             NetworkProxy networkProxy = null;
             String proxyId = connector.getProxyId();
@@ -127,7 +127,7 @@ public class MavenRepositoryProxyHandler extends DefaultRepositoryProxyHandler {
                 networkProxy = getNetworkProxy(proxyId);
             }
             WagonFactoryRequest wagonFactoryRequest = new WagonFactoryRequest("wagon#" + protocol,
-                    remoteRepository.getRepository().getExtraHeaders());
+                    remoteRepository.getExtraHeaders());
             if (networkProxy == null) {
 
                 log.warn("No network proxy with id {} found for connector {}->{}", proxyId,
@@ -180,8 +180,8 @@ public class MavenRepositoryProxyHandler extends DefaultRepositoryProxyHandler {
         }
     }
 
-    protected void transferArtifact(Wagon wagon, RemoteRepositoryContent remoteRepository, String remotePath,
-                                    ManagedRepositoryContent repository, Path resource, Path tmpDirectory,
+    protected void transferArtifact(Wagon wagon, RemoteRepository remoteRepository, String remotePath,
+                                    ManagedRepository repository, Path resource, Path tmpDirectory,
                                     StorageAsset destFile)
             throws ProxyException {
         transferSimpleFile(wagon, remoteRepository, remotePath, repository, resource, destFile.getFilePath());
@@ -200,11 +200,11 @@ public class MavenRepositoryProxyHandler extends DefaultRepositoryProxyHandler {
      * @param ext              the type of checksum to transfer (example: ".md5" or ".sha1")
      * @throws ProxyException if copying the downloaded file into place did not succeed.
      */
-    protected void transferChecksum( Wagon wagon, RemoteRepositoryContent remoteRepository, String remotePath,
-                                     ManagedRepositoryContent repository, Path resource, String ext,
+    protected void transferChecksum( Wagon wagon, RemoteRepository remoteRepository, String remotePath,
+                                     ManagedRepository repository, Path resource, String ext,
                                      Path destFile )
             throws ProxyException {
-        String url = remoteRepository.getURL().getUrl() + remotePath + ext;
+        String url = remoteRepository.getLocation().toString() + remotePath + ext;
 
         // Transfer checksum does not use the policy.
         if (urlFailureCache.hasFailedBefore(url)) {
@@ -239,8 +239,8 @@ public class MavenRepositoryProxyHandler extends DefaultRepositoryProxyHandler {
      * @param origFile         the local file to save to
      * @throws ProxyException if there was a problem moving the downloaded file into place.
      */
-    protected void transferSimpleFile(Wagon wagon, RemoteRepositoryContent remoteRepository, String remotePath,
-                                      ManagedRepositoryContent repository, Path origFile, Path destFile)
+    protected void transferSimpleFile(Wagon wagon, RemoteRepository remoteRepository, String remotePath,
+                                      ManagedRepository repository, Path origFile, Path destFile)
             throws ProxyException {
         assert (remotePath != null);
 
@@ -249,16 +249,16 @@ public class MavenRepositoryProxyHandler extends DefaultRepositoryProxyHandler {
             boolean success = false;
 
             if (!Files.exists(origFile)) {
-                log.debug("Retrieving {} from {}", remotePath, remoteRepository.getRepository().getName());
-                wagon.get(addParameters(remotePath, remoteRepository.getRepository()), destFile.toFile());
+                log.debug("Retrieving {} from {}", remotePath, remoteRepository.getId());
+                wagon.get(addParameters(remotePath, remoteRepository), destFile.toFile());
                 success = true;
 
                 // You wouldn't get here on failure, a WagonException would have been thrown.
                 log.debug("Downloaded successfully.");
             } else {
-                log.debug("Retrieving {} from {} if updated", remotePath, remoteRepository.getRepository().getName());
+                log.debug("Retrieving {} from {} if updated", remotePath, remoteRepository.getId());
                 try {
-                    success = wagon.getIfNewer(addParameters(remotePath, remoteRepository.getRepository()), destFile.toFile(),
+                    success = wagon.getIfNewer(addParameters(remotePath, remoteRepository), destFile.toFile(),
                             Files.getLastModifiedTime(origFile).toMillis());
                 } catch (IOException e) {
                     throw new ProxyException("Failed to the modification time of " + origFile.toAbsolutePath());
@@ -274,13 +274,13 @@ public class MavenRepositoryProxyHandler extends DefaultRepositoryProxyHandler {
             }
         } catch (ResourceDoesNotExistException e) {
             throw new NotFoundException(
-                    "Resource [" + remoteRepository.getURL() + "/" + remotePath + "] does not exist: " + e.getMessage(),
+                    "Resource [" + remoteRepository.getLocation() + "/" + remotePath + "] does not exist: " + e.getMessage(),
                     e);
         } catch (WagonException e) {
             // TODO: shouldn't have to drill into the cause, but TransferFailedException is often not descriptive enough
 
             String msg =
-                    "Download failure on resource [" + remoteRepository.getURL() + "/" + remotePath + "]:" + e.getMessage();
+                    "Download failure on resource [" + remoteRepository.getLocation() + "/" + remotePath + "]:" + e.getMessage();
             if (e.getCause() != null) {
                 msg += " (cause: " + e.getCause() + ")";
             }
@@ -297,7 +297,7 @@ public class MavenRepositoryProxyHandler extends DefaultRepositoryProxyHandler {
      * @return true if the connection was successful. false if not connected.
      */
     protected boolean connectToRepository(ProxyConnector connector, Wagon wagon,
-                                          RemoteRepositoryContent remoteRepository) {
+                                          RemoteRepository remoteRepository) {
         boolean connected = false;
 
         final ProxyInfo networkProxy =
@@ -307,7 +307,7 @@ public class MavenRepositoryProxyHandler extends DefaultRepositoryProxyHandler {
             if (networkProxy != null) {
                 // TODO: move to proxyInfo.toString()
                 String msg = "Using network proxy " + networkProxy.getHost() + ":" + networkProxy.getPort()
-                        + " to connect to remote repository " + remoteRepository.getURL();
+                        + " to connect to remote repository " + remoteRepository.getLocation();
                 if (networkProxy.getNonProxyHosts() != null) {
                     msg += "; excluding hosts: " + networkProxy.getNonProxyHosts();
                 }
@@ -321,7 +321,7 @@ public class MavenRepositoryProxyHandler extends DefaultRepositoryProxyHandler {
         AuthenticationInfo authInfo = null;
         String username = "";
         String password = "";
-        RepositoryCredentials repCred = remoteRepository.getRepository().getLoginCredentials();
+        RepositoryCredentials repCred = remoteRepository.getLoginCredentials();
         if (repCred != null && repCred instanceof PasswordCredentials) {
             PasswordCredentials pwdCred = (PasswordCredentials) repCred;
             username = pwdCred.getUsername();
@@ -329,7 +329,7 @@ public class MavenRepositoryProxyHandler extends DefaultRepositoryProxyHandler {
         }
 
         if (StringUtils.isNotBlank(username) && StringUtils.isNotBlank(password)) {
-            log.debug("Using username {} to connect to remote repository {}", username, remoteRepository.getURL());
+            log.debug("Using username {} to connect to remote repository {}", username, remoteRepository.getLocation());
             authInfo = new AuthenticationInfo();
             authInfo.setUserName(username);
             authInfo.setPassword(password);
@@ -337,7 +337,7 @@ public class MavenRepositoryProxyHandler extends DefaultRepositoryProxyHandler {
 
         // Convert seconds to milliseconds
 
-        long timeoutInMilliseconds = remoteRepository.getRepository().getTimeout().toMillis();
+        long timeoutInMilliseconds = remoteRepository.getTimeout().toMillis();
 
         // Set timeout  read and connect
         // FIXME olamy having 2 config values
@@ -346,11 +346,11 @@ public class MavenRepositoryProxyHandler extends DefaultRepositoryProxyHandler {
 
         try {
             Repository wagonRepository =
-                    new Repository(remoteRepository.getId(), remoteRepository.getURL().toString());
+                    new Repository(remoteRepository.getId(), remoteRepository.getLocation().toString());
             wagon.connect(wagonRepository, authInfo, networkProxy);
             connected = true;
         } catch (ConnectionException | AuthenticationException e) {
-            log.warn("Could not connect to {}: {}", remoteRepository.getRepository().getName(), e.getMessage());
+            log.warn("Could not connect to {}: {}", remoteRepository.getId(), e.getMessage());
             connected = false;
         }
 
@@ -370,4 +370,20 @@ public class MavenRepositoryProxyHandler extends DefaultRepositoryProxyHandler {
     public List<RepositoryType> supports() {
         return REPOSITORY_TYPES;
     }
+
+    @Override
+    public void addNetworkproxy( String id, NetworkProxy networkProxy )
+    {
+
+    }
+
+    @Override
+    public <T extends RepositoryProxyHandler> T getHandler( Class<T> clazz ) throws IllegalArgumentException
+    {
+        if (clazz.isAssignableFrom( this.getClass() )) {
+            return (T)this;
+        } else {
+            throw new IllegalArgumentException( "This Proxy Handler is no subclass of " + clazz );
+        }
+    }
 }
diff --git a/archiva-modules/archiva-maven/archiva-maven-proxy/src/test/java/org/apache/archiva/proxy/AbstractProxyTestCase.java b/archiva-modules/archiva-maven/archiva-maven-proxy/src/test/java/org/apache/archiva/proxy/AbstractProxyTestCase.java
index 3331525..7659052 100644
--- a/archiva-modules/archiva-maven/archiva-maven-proxy/src/test/java/org/apache/archiva/proxy/AbstractProxyTestCase.java
+++ b/archiva-modules/archiva-maven/archiva-maven-proxy/src/test/java/org/apache/archiva/proxy/AbstractProxyTestCase.java
@@ -64,6 +64,9 @@ public abstract class AbstractProxyTestCase
     protected ApplicationContext applicationContext;
 
     @Inject
+    private ProxyRegistry proxyRegistry;
+
+    @Inject
     RepositoryRegistry repositoryRegistry;
 
     protected static final String ID_PROXIED1 = "proxied1";
@@ -152,14 +155,16 @@ public abstract class AbstractProxyTestCase
         // Setup the proxy handler.
         //proxyHandler = applicationContext.getBean (RepositoryProxyHandler) lookup( RepositoryProxyHandler.class.getName() );
 
-        proxyHandler = applicationContext.getBean( "repositoryProxyConnectors#test", RepositoryProxyHandler.class );
+        proxyHandler = applicationContext.getBean( "repositoryProxyHandler#test", RepositoryProxyHandler.class );
+        assertNotNull( proxyRegistry );
+        assertTrue(proxyRegistry.getAllHandler( ).get( RepositoryType.MAVEN).contains( proxyHandler ));
 
 
         // Setup the wagon mock.
         wagonMockControl = EasyMock.createNiceControl();
         wagonMock = wagonMockControl.createMock( Wagon.class );
 
-        delegate = (WagonDelegate) applicationContext.getBean( "wagon#test", Wagon.class );
+        delegate = (WagonDelegate) applicationContext.getBean( "wagon#http", Wagon.class );
 
         delegate.setDelegate( wagonMock );
 
diff --git a/archiva-modules/archiva-maven/archiva-maven-proxy/src/test/java/org/apache/archiva/proxy/CacheFailuresTransferTest.java b/archiva-modules/archiva-maven/archiva-maven-proxy/src/test/java/org/apache/archiva/proxy/CacheFailuresTransferTest.java
index 5a9032f..de9b78c 100644
--- a/archiva-modules/archiva-maven/archiva-maven-proxy/src/test/java/org/apache/archiva/proxy/CacheFailuresTransferTest.java
+++ b/archiva-modules/archiva-maven/archiva-maven-proxy/src/test/java/org/apache/archiva/proxy/CacheFailuresTransferTest.java
@@ -67,8 +67,8 @@ public class CacheFailuresTransferTest
         ArtifactReference artifact = managedDefaultRepository.toArtifactReference( path );
 
         // Configure Repository (usually done within archiva.xml configuration)
-        saveRemoteRepositoryConfig( "badproxied1", "Bad Proxied 1", "test://bad.machine.com/repo/", "default" );
-        saveRemoteRepositoryConfig( "badproxied2", "Bad Proxied 2", "test://bad.machine.com/anotherrepo/", "default" );
+        saveRemoteRepositoryConfig( "badproxied1", "Bad Proxied 1", "http://bad.machine.com/repo/", "default" );
+        saveRemoteRepositoryConfig( "badproxied2", "Bad Proxied 2", "http://bad.machine.com/anotherrepo/", "default" );
 
         // Configure Connector (usually done within archiva.xml configuration)
         saveConnector( ID_DEFAULT_MANAGED, "badproxied1", ChecksumPolicy.FIX, ReleasesPolicy.ALWAYS,
@@ -84,14 +84,14 @@ public class CacheFailuresTransferTest
         wagonMockControl.replay();
 
         //noinspection UnusedAssignment
-        StorageAsset downloadedFile = proxyHandler.fetchFromProxies( managedDefaultRepository, artifact );
+        StorageAsset downloadedFile = proxyHandler.fetchFromProxies( managedDefaultRepository.getRepository(), artifact );
 
         wagonMockControl.verify();
 
         // Second attempt to download same artifact use cache
         wagonMockControl.reset();
         wagonMockControl.replay();
-        downloadedFile = proxyHandler.fetchFromProxies( managedDefaultRepository, artifact );
+        downloadedFile = proxyHandler.fetchFromProxies( managedDefaultRepository.getRepository(), artifact );
         wagonMockControl.verify();
 
         assertNotDownloaded( downloadedFile);
@@ -111,8 +111,8 @@ public class CacheFailuresTransferTest
         ArtifactReference artifact = managedDefaultRepository.toArtifactReference( path );
 
         // Configure Repository (usually done within archiva.xml configuration)
-        saveRemoteRepositoryConfig( "badproxied1", "Bad Proxied 1", "test://bad.machine.com/repo/", "default" );
-        saveRemoteRepositoryConfig( "badproxied2", "Bad Proxied 2", "test://bad.machine.com/anotherrepo/", "default" );
+        saveRemoteRepositoryConfig( "badproxied1", "Bad Proxied 1", "http://bad.machine.com/repo/", "default" );
+        saveRemoteRepositoryConfig( "badproxied2", "Bad Proxied 2", "http://bad.machine.com/anotherrepo/", "default" );
 
 
         // Configure Connector (usually done within archiva.xml configuration)
@@ -126,7 +126,7 @@ public class CacheFailuresTransferTest
 
         wagonMockControl.replay();
 
-        StorageAsset downloadedFile = proxyHandler.fetchFromProxies( managedDefaultRepository, artifact );
+        StorageAsset downloadedFile = proxyHandler.fetchFromProxies( managedDefaultRepository.getRepository(), artifact );
 
         wagonMockControl.verify();
 
@@ -138,7 +138,7 @@ public class CacheFailuresTransferTest
 
         wagonMockControl.replay();
 
-        downloadedFile = proxyHandler.fetchFromProxies( managedDefaultRepository, artifact );
+        downloadedFile = proxyHandler.fetchFromProxies( managedDefaultRepository.getRepository(), artifact );
 
         wagonMockControl.verify();
 
@@ -170,7 +170,7 @@ public class CacheFailuresTransferTest
         saveConnector( ID_DEFAULT_MANAGED, "proxied2", ChecksumPolicy.FIX, ReleasesPolicy.ALWAYS,
                        SnapshotsPolicy.ALWAYS, CachedFailuresPolicy.YES, false );
 
-        StorageAsset downloadedFile = proxyHandler.fetchFromProxies( managedDefaultRepository, artifact );
+        StorageAsset downloadedFile = proxyHandler.fetchFromProxies( managedDefaultRepository.getRepository(), artifact );
 
         // Validate that file actually came from proxied2 (as intended).
         Path proxied2File = Paths.get( REPOPATH_PROXIED2, path );
diff --git a/archiva-modules/archiva-maven/archiva-maven-proxy/src/test/java/org/apache/archiva/proxy/ChecksumTransferTest.java b/archiva-modules/archiva-maven/archiva-maven-proxy/src/test/java/org/apache/archiva/proxy/ChecksumTransferTest.java
index f0066c3..d249885 100644
--- a/archiva-modules/archiva-maven/archiva-maven-proxy/src/test/java/org/apache/archiva/proxy/ChecksumTransferTest.java
+++ b/archiva-modules/archiva-maven/archiva-maven-proxy/src/test/java/org/apache/archiva/proxy/ChecksumTransferTest.java
@@ -64,7 +64,7 @@ public class ChecksumTransferTest
         saveConnector( ID_DEFAULT_MANAGED, "proxied1", ChecksumPolicy.IGNORE, ReleasesPolicy.ALWAYS,
                        SnapshotsPolicy.ALWAYS, CachedFailuresPolicy.NO, true );
 
-        StorageAsset downloadedFile = proxyHandler.fetchFromProxies( managedDefaultRepository, artifact );
+        StorageAsset downloadedFile = proxyHandler.fetchFromProxies( managedDefaultRepository.getRepository(), artifact );
 
         assertNull( downloadedFile );
     }
@@ -86,7 +86,7 @@ public class ChecksumTransferTest
         saveConnector( ID_DEFAULT_MANAGED, "proxied1", ChecksumPolicy.IGNORE, ReleasesPolicy.ALWAYS,
                        SnapshotsPolicy.ALWAYS, CachedFailuresPolicy.NO, false );
 
-        StorageAsset downloadedFile = proxyHandler.fetchFromProxies( managedDefaultRepository, artifact );
+        StorageAsset downloadedFile = proxyHandler.fetchFromProxies( managedDefaultRepository.getRepository(), artifact );
 
         Path proxied1File = Paths.get( REPOPATH_PROXIED1, path );
         assertFileEquals( expectedFile, downloadedFile.getFilePath(), proxied1File );
@@ -112,7 +112,7 @@ public class ChecksumTransferTest
         saveConnector( ID_DEFAULT_MANAGED, "proxied1", ChecksumPolicy.IGNORE, ReleasesPolicy.ALWAYS,
                        SnapshotsPolicy.ALWAYS, CachedFailuresPolicy.NO, false );
 
-        StorageAsset downloadedFile = proxyHandler.fetchFromProxies( managedDefaultRepository, artifact );
+        StorageAsset downloadedFile = proxyHandler.fetchFromProxies( managedDefaultRepository.getRepository(), artifact );
 
         Path proxied1File = Paths.get( REPOPATH_PROXIED1, path );
         assertFileEquals( expectedFile, downloadedFile.getFilePath(), proxied1File );
@@ -138,7 +138,7 @@ public class ChecksumTransferTest
         saveConnector( ID_DEFAULT_MANAGED, "proxied1", ChecksumPolicy.IGNORE, ReleasesPolicy.ALWAYS,
                        SnapshotsPolicy.ALWAYS, CachedFailuresPolicy.NO, false );
 
-        StorageAsset downloadedFile = proxyHandler.fetchFromProxies( managedDefaultRepository, artifact );
+        StorageAsset downloadedFile = proxyHandler.fetchFromProxies( managedDefaultRepository.getRepository(), artifact );
 
         Path proxied1File = Paths.get( REPOPATH_PROXIED1, path );
         assertFileEquals( expectedFile, downloadedFile.getFilePath(), proxied1File );
@@ -163,7 +163,7 @@ public class ChecksumTransferTest
         saveConnector( ID_DEFAULT_MANAGED, "proxied1", ChecksumPolicy.IGNORE, ReleasesPolicy.ALWAYS,
                        SnapshotsPolicy.ALWAYS, CachedFailuresPolicy.NO, false );
 
-        StorageAsset downloadedFile = proxyHandler.fetchFromProxies( managedDefaultRepository, artifact );
+        StorageAsset downloadedFile = proxyHandler.fetchFromProxies( managedDefaultRepository.getRepository(), artifact );
 
         Path proxied1File = Paths.get( REPOPATH_PROXIED1, path );
         assertFileEquals( expectedFile, downloadedFile.getFilePath(), proxied1File );
@@ -188,7 +188,7 @@ public class ChecksumTransferTest
         saveConnector( ID_DEFAULT_MANAGED, "proxied1", ChecksumPolicy.IGNORE, ReleasesPolicy.ALWAYS,
                        SnapshotsPolicy.ALWAYS, CachedFailuresPolicy.NO, false );
 
-        StorageAsset downloadedFile = proxyHandler.fetchFromProxies( managedDefaultRepository, artifact );
+        StorageAsset downloadedFile = proxyHandler.fetchFromProxies( managedDefaultRepository.getRepository(), artifact );
 
         Path proxied1File = Paths.get( REPOPATH_PROXIED1, path );
         assertFileEquals( expectedFile, downloadedFile.getFilePath(), proxied1File );
@@ -213,7 +213,7 @@ public class ChecksumTransferTest
         saveConnector( ID_DEFAULT_MANAGED, "proxied1", ChecksumPolicy.FAIL, ReleasesPolicy.ALWAYS,
                        SnapshotsPolicy.ALWAYS, CachedFailuresPolicy.NO, false );
 
-        StorageAsset downloadedFile = proxyHandler.fetchFromProxies( managedDefaultRepository, artifact );
+        StorageAsset downloadedFile = proxyHandler.fetchFromProxies( managedDefaultRepository.getRepository(), artifact );
 
         assertNotDownloaded( downloadedFile );
         assertChecksums( expectedFile, null, null );
@@ -236,7 +236,7 @@ public class ChecksumTransferTest
         saveConnector( ID_DEFAULT_MANAGED, "proxied1", ChecksumPolicy.FIX, ReleasesPolicy.ALWAYS,
                        SnapshotsPolicy.ALWAYS, CachedFailuresPolicy.NO, false );
 
-        StorageAsset downloadedFile = proxyHandler.fetchFromProxies( managedDefaultRepository, artifact );
+        StorageAsset downloadedFile = proxyHandler.fetchFromProxies( managedDefaultRepository.getRepository(), artifact );
 
         Path proxied1File = Paths.get( REPOPATH_PROXIED1, path );
         assertFileEquals( expectedFile, downloadedFile.getFilePath(), proxied1File );
@@ -262,7 +262,7 @@ public class ChecksumTransferTest
         saveConnector( ID_DEFAULT_MANAGED, "proxied1", ChecksumPolicy.FAIL, ReleasesPolicy.ALWAYS,
                        SnapshotsPolicy.ALWAYS, CachedFailuresPolicy.NO, false );
 
-        StorageAsset downloadedFile = proxyHandler.fetchFromProxies( managedDefaultRepository, artifact );
+        StorageAsset downloadedFile = proxyHandler.fetchFromProxies( managedDefaultRepository.getRepository(), artifact );
 
         assertNotDownloaded( downloadedFile );
         assertChecksums( expectedFile, null, null );
@@ -285,7 +285,7 @@ public class ChecksumTransferTest
         saveConnector( ID_DEFAULT_MANAGED, "proxied1", ChecksumPolicy.FAIL, ReleasesPolicy.ALWAYS,
                        SnapshotsPolicy.ALWAYS, CachedFailuresPolicy.NO, false );
 
-        StorageAsset downloadedFile = proxyHandler.fetchFromProxies( managedDefaultRepository, artifact );
+        StorageAsset downloadedFile = proxyHandler.fetchFromProxies( managedDefaultRepository.getRepository(), artifact );
 
         // This is a success situation. No SHA1 with a Good MD5.
         Path proxied1File = Paths.get(REPOPATH_PROXIED1, path);
@@ -311,7 +311,7 @@ public class ChecksumTransferTest
         saveConnector( ID_DEFAULT_MANAGED, "proxied1", ChecksumPolicy.FAIL, ReleasesPolicy.ALWAYS,
                        SnapshotsPolicy.ALWAYS, CachedFailuresPolicy.NO, false );
 
-        StorageAsset downloadedFile = proxyHandler.fetchFromProxies( managedDefaultRepository, artifact );
+        StorageAsset downloadedFile = proxyHandler.fetchFromProxies( managedDefaultRepository.getRepository(), artifact );
 
         assertNotDownloaded( downloadedFile );
         assertChecksums( expectedFile, null, null );
@@ -334,7 +334,7 @@ public class ChecksumTransferTest
         saveConnector( ID_DEFAULT_MANAGED, "proxied1", ChecksumPolicy.IGNORE, ReleasesPolicy.ALWAYS,
                        SnapshotsPolicy.ALWAYS, CachedFailuresPolicy.NO, false );
 
-        StorageAsset downloadedFile = proxyHandler.fetchFromProxies( managedDefaultRepository, artifact );
+        StorageAsset downloadedFile = proxyHandler.fetchFromProxies( managedDefaultRepository.getRepository(), artifact );
 
         Path proxied1File = Paths.get(REPOPATH_PROXIED1, path);
         assertFileEquals( expectedFile, downloadedFile.getFilePath(), proxied1File );
@@ -361,7 +361,7 @@ public class ChecksumTransferTest
                        SnapshotsPolicy.ALWAYS, CachedFailuresPolicy.NO, false );
 
 
-        StorageAsset downloadedFile = proxyHandler.fetchFromProxies( managedDefaultRepository, artifact );
+        StorageAsset downloadedFile = proxyHandler.fetchFromProxies( managedDefaultRepository.getRepository(), artifact );
 
         Path proxied1File = Paths.get(REPOPATH_PROXIED1, path);
         assertFileEquals( expectedFile, downloadedFile.getFilePath(), proxied1File );
@@ -387,7 +387,7 @@ public class ChecksumTransferTest
         saveConnector( ID_DEFAULT_MANAGED, "proxied1", ChecksumPolicy.FIX, ReleasesPolicy.ALWAYS,
                        SnapshotsPolicy.ALWAYS, CachedFailuresPolicy.NO, false );
 
-        StorageAsset downloadedFile = proxyHandler.fetchFromProxies( managedDefaultRepository, artifact );
+        StorageAsset downloadedFile = proxyHandler.fetchFromProxies( managedDefaultRepository.getRepository(), artifact );
 
         Path proxied1File = Paths.get(REPOPATH_PROXIED1, path);
         assertFileEquals( expectedFile, downloadedFile.getFilePath(), proxied1File );
@@ -413,7 +413,7 @@ public class ChecksumTransferTest
         saveConnector( ID_DEFAULT_MANAGED, "proxied1", ChecksumPolicy.FIX, ReleasesPolicy.ALWAYS,
                        SnapshotsPolicy.ALWAYS, CachedFailuresPolicy.NO, false );
 
-        StorageAsset downloadedFile = proxyHandler.fetchFromProxies( managedDefaultRepository, artifact );
+        StorageAsset downloadedFile = proxyHandler.fetchFromProxies( managedDefaultRepository.getRepository(), artifact );
 
         Path proxied1File = Paths.get(REPOPATH_PROXIED1, path);
         assertFileEquals( expectedFile, downloadedFile.getFilePath(), proxied1File );
@@ -436,7 +436,7 @@ public class ChecksumTransferTest
         assertFalse( Files.exists(expectedFile.getParent()) );
         assertFalse( Files.exists(expectedFile) );
 
-        saveRemoteRepositoryConfig( "badproxied", "Bad Proxied", "test://bad.machine.com/repo/", "default" );
+        saveRemoteRepositoryConfig( "badproxied", "Bad Proxied", "http://bad.machine.com/repo/", "default" );
 
         // Configure Connector (usually done within archiva.xml configuration)
         saveConnector( ID_DEFAULT_MANAGED, "badproxied", ChecksumPolicy.IGNORE, ReleasesPolicy.ALWAYS,
@@ -453,7 +453,7 @@ public class ChecksumTransferTest
 
         wagonMockControl.replay();
 
-        StorageAsset downloadedFile = proxyHandler.fetchFromProxies( managedDefaultRepository, artifact );
+        StorageAsset downloadedFile = proxyHandler.fetchFromProxies( managedDefaultRepository.getRepository(), artifact );
 
         wagonMockControl.verify();
 
@@ -490,7 +490,7 @@ public class ChecksumTransferTest
         saveConnector( ID_DEFAULT_MANAGED, "proxied1", ChecksumPolicy.IGNORE, ReleasesPolicy.ALWAYS,
                        SnapshotsPolicy.ALWAYS, CachedFailuresPolicy.NO, false );
 
-        StorageAsset downloadedFile = proxyHandler.fetchFromProxies( managedDefaultRepository, artifact );
+        StorageAsset downloadedFile = proxyHandler.fetchFromProxies( managedDefaultRepository.getRepository(), artifact );
 
         Path proxied1File = Paths.get( REPOPATH_PROXIED1, path );
         assertFileEquals( expectedFile, downloadedFile.getFilePath(), proxied1File );
@@ -517,7 +517,7 @@ public class ChecksumTransferTest
         saveConnector( ID_DEFAULT_MANAGED, ID_PROXIED1, ChecksumPolicy.FAIL, ReleasesPolicy.ALWAYS,
                        SnapshotsPolicy.ALWAYS, CachedFailuresPolicy.NO, false );
 
-        StorageAsset downloadedFile = proxyHandler.fetchFromProxies( managedDefaultRepository, artifact );
+        StorageAsset downloadedFile = proxyHandler.fetchFromProxies( managedDefaultRepository.getRepository(), artifact );
 
         assertNotDownloaded( downloadedFile );
         assertNoTempFiles( expectedFile );
@@ -545,7 +545,7 @@ public class ChecksumTransferTest
         saveConnector( ID_DEFAULT_MANAGED, "proxied1", ChecksumPolicy.FIX, ReleasesPolicy.ALWAYS,
                        SnapshotsPolicy.ALWAYS, CachedFailuresPolicy.NO, false );
 
-        StorageAsset downloadedFile = proxyHandler.fetchFromProxies( managedDefaultRepository, artifact );
+        StorageAsset downloadedFile = proxyHandler.fetchFromProxies( managedDefaultRepository.getRepository(), artifact );
 
         Path proxied1File = Paths.get(REPOPATH_PROXIED1, path);
         assertFileEquals( expectedFile, downloadedFile.getFilePath(), proxied1File );
diff --git a/archiva-modules/archiva-maven/archiva-maven-proxy/src/test/java/org/apache/archiva/proxy/ErrorHandlingTest.java b/archiva-modules/archiva-maven/archiva-maven-proxy/src/test/java/org/apache/archiva/proxy/ErrorHandlingTest.java
index 8bafb42..2f7d2dc 100644
--- a/archiva-modules/archiva-maven/archiva-maven-proxy/src/test/java/org/apache/archiva/proxy/ErrorHandlingTest.java
+++ b/archiva-modules/archiva-maven/archiva-maven-proxy/src/test/java/org/apache/archiva/proxy/ErrorHandlingTest.java
@@ -526,14 +526,14 @@ public class ErrorHandlingTest
 
     private void createMockedProxyConnector( String id, String name, PolicyOption errorPolicy )
     {
-        saveRemoteRepositoryConfig( id, name, "test://bad.machine.com/repo/", "default" );
+        saveRemoteRepositoryConfig( id, name, "http://bad.machine.com/repo/", "default" );
         saveConnector( ID_DEFAULT_MANAGED, id, ChecksumPolicy.FIX, ReleasesPolicy.ALWAYS, SnapshotsPolicy.ALWAYS,
                        CachedFailuresPolicy.NO, errorPolicy, false );
     }
 
     private void createMockedProxyConnector( String id, String name, PolicyOption errorPolicy, PolicyOption errorOnUpdatePolicy )
     {
-        saveRemoteRepositoryConfig( id, name, "test://bad.machine.com/repo/", "default" );
+        saveRemoteRepositoryConfig( id, name, "http://bad.machine.com/repo/", "default" );
         saveConnector( ID_DEFAULT_MANAGED, id, ChecksumPolicy.FIX, ReleasesPolicy.ALWAYS, SnapshotsPolicy.ALWAYS,
                        CachedFailuresPolicy.NO, errorPolicy, errorOnUpdatePolicy, false );
     }
@@ -596,7 +596,7 @@ public class ErrorHandlingTest
         StorageAsset downloadedFile = null;
         try
         {
-            downloadedFile = proxyHandler.fetchFromProxies( managedDefaultRepository,
+            downloadedFile = proxyHandler.fetchFromProxies( managedDefaultRepository.getRepository(),
                                                             managedDefaultRepository.toArtifactReference( path ) );
             fail( "Proxy should not have succeeded" );
         }
@@ -637,7 +637,7 @@ public class ErrorHandlingTest
         wagonMockControl.replay();
 
         // Attempt the proxy fetch.
-        StorageAsset downloadedFile = proxyHandler.fetchFromProxies( managedDefaultRepository,
+        StorageAsset downloadedFile = proxyHandler.fetchFromProxies( managedDefaultRepository.getRepository(),
                                                              managedDefaultRepository.toArtifactReference( path ) );
 
         wagonMockControl.verify();
diff --git a/archiva-modules/archiva-maven/archiva-maven-proxy/src/test/java/org/apache/archiva/proxy/HttpProxyTransferTest.java b/archiva-modules/archiva-maven/archiva-maven-proxy/src/test/java/org/apache/archiva/proxy/HttpProxyTransferTest.java
index 90cb217..b35967f 100644
--- a/archiva-modules/archiva-maven/archiva-maven-proxy/src/test/java/org/apache/archiva/proxy/HttpProxyTransferTest.java
+++ b/archiva-modules/archiva-maven/archiva-maven-proxy/src/test/java/org/apache/archiva/proxy/HttpProxyTransferTest.java
@@ -30,11 +30,16 @@ import org.apache.archiva.policies.PropagateErrorsDownloadPolicy;
 import org.apache.archiva.policies.PropagateErrorsOnUpdateDownloadPolicy;
 import org.apache.archiva.policies.ReleasesPolicy;
 import org.apache.archiva.policies.SnapshotsPolicy;
+import org.apache.archiva.proxy.maven.DefaultWagonFactory;
+import org.apache.archiva.proxy.maven.WagonFactory;
+import org.apache.archiva.proxy.maven.WagonFactoryRequest;
 import org.apache.archiva.proxy.model.RepositoryProxyHandler;
 import org.apache.archiva.repository.*;
 import org.apache.archiva.repository.storage.StorageAsset;
 import org.apache.archiva.test.utils.ArchivaSpringJUnit4ClassRunner;
 import org.apache.commons.io.FileUtils;
+import org.apache.maven.wagon.Wagon;
+import org.apache.maven.wagon.providers.http.HttpWagon;
 import org.assertj.core.api.Assertions;
 import org.eclipse.jetty.server.Handler;
 import org.eclipse.jetty.server.HttpConnectionFactory;
@@ -80,8 +85,6 @@ public class HttpProxyTransferTest
 
     private RepositoryProxyHandler proxyHandler;
 
-    private ArchivaConfiguration config;
-
     private ManagedRepositoryContent managedDefaultRepository;
 
     @Inject
@@ -90,6 +93,12 @@ public class HttpProxyTransferTest
     @Inject
     private RepositoryRegistry repositoryRegistry;
 
+    @Inject
+    private ArchivaConfiguration config;
+
+    @Inject
+    private ProxyRegistry proxyRegistry;
+
     private Server server;
 
     protected ManagedRepositoryContent createRepository( String id, String name, String path, String layout )
@@ -104,9 +113,7 @@ public class HttpProxyTransferTest
     public void setUp()
         throws Exception
     {
-        proxyHandler = applicationContext.getBean( "repositoryProxyConnectors#test", RepositoryProxyHandler.class );
-
-        config = applicationContext.getBean( "archivaConfiguration#mock", ArchivaConfiguration.class );
+        proxyHandler = applicationContext.getBean( "repositoryProxyHandler#test", RepositoryProxyHandler.class );
 
         // clear from previous tests - TODO the spring context should be initialised per test instead, or the config
         // made a complete mock
@@ -180,6 +187,11 @@ public class HttpProxyTransferTest
 
         config.getConfiguration().addRemoteRepository( repoConfig );
 
+        Wagon wagon = new HttpWagon( );
+        WagonDelegate delegate = (WagonDelegate) applicationContext.getBean( "wagon#http", Wagon.class );
+        delegate.setDelegate( wagon );
+
+        proxyRegistry.reload();
         repositoryRegistry.reload();
 
         managedDefaultRepository = createRepository(MANAGED_ID, "Default Managed Repository", repoPath, "default");
@@ -208,10 +220,11 @@ public class HttpProxyTransferTest
         addConnector();
 
         Path expectedFile = Paths.get( managedDefaultRepository.getRepoRoot() ).resolve( path );
+        Files.deleteIfExists( expectedFile );
         ArtifactReference artifact = managedDefaultRepository.toArtifactReference( path );
 
         // Attempt the proxy fetch.
-        StorageAsset downloadedFile = proxyHandler.fetchFromProxies( managedDefaultRepository, artifact );
+        StorageAsset downloadedFile = proxyHandler.fetchFromProxies( managedDefaultRepository.getRepository(), artifact );
 
         Path sourceFile = Paths.get( PROXIED_BASEDIR, path );
         assertNotNull( "Expected File should not be null.", expectedFile );
diff --git a/archiva-modules/archiva-maven/archiva-maven-proxy/src/test/java/org/apache/archiva/proxy/ManagedDefaultTransferTest.java b/archiva-modules/archiva-maven/archiva-maven-proxy/src/test/java/org/apache/archiva/proxy/ManagedDefaultTransferTest.java
index aad62e8..f1491f8 100644
--- a/archiva-modules/archiva-maven/archiva-maven-proxy/src/test/java/org/apache/archiva/proxy/ManagedDefaultTransferTest.java
+++ b/archiva-modules/archiva-maven/archiva-maven-proxy/src/test/java/org/apache/archiva/proxy/ManagedDefaultTransferTest.java
@@ -65,7 +65,7 @@ public class ManagedDefaultTransferTest
                        CachedFailuresPolicy.NO, true );
 
         // Attempt the proxy fetch.
-        StorageAsset downloadedFile = proxyHandler.fetchFromProxies( managedDefaultRepository, artifact );
+        StorageAsset downloadedFile = proxyHandler.fetchFromProxies( managedDefaultRepository.getRepository(), artifact );
         assertNull( "File should not have been downloaded", downloadedFile );
     }
 
@@ -87,7 +87,7 @@ public class ManagedDefaultTransferTest
                        CachedFailuresPolicy.NO, false );
 
         // Attempt the proxy fetch.
-        StorageAsset downloadedFile = proxyHandler.fetchFromProxies( managedDefaultRepository, artifact );
+        StorageAsset downloadedFile = proxyHandler.fetchFromProxies( managedDefaultRepository.getRepository(), artifact );
 
         Path sourceFile = Paths.get(REPOPATH_PROXIED1, path);
         assertFileEquals( expectedFile, downloadedFile.getFilePath(), sourceFile );
@@ -111,7 +111,7 @@ public class ManagedDefaultTransferTest
                        CachedFailuresPolicy.NO, false );
 
         // Attempt the proxy fetch.
-        StorageAsset downloadedFile = proxyHandler.fetchFromProxies( managedDefaultRepository, path );
+        StorageAsset downloadedFile = proxyHandler.fetchFromProxies( managedDefaultRepository.getRepository(), path );
 
         Path sourceFile = Paths.get(REPOPATH_PROXIED1, path);
         assertNotNull(downloadedFile);
@@ -147,7 +147,7 @@ public class ManagedDefaultTransferTest
                        CachedFailuresPolicy.NO, false );
 
         // Attempt the proxy fetch.
-        StorageAsset downloadedFile = proxyHandler.fetchFromProxies( managedDefaultRepository, artifact );
+        StorageAsset downloadedFile = proxyHandler.fetchFromProxies( managedDefaultRepository.getRepository(), artifact );
 
         assertFileEquals( expectedFile, downloadedFile.getFilePath(), expectedFile );
         assertNoTempFiles( expectedFile );
@@ -181,7 +181,7 @@ public class ManagedDefaultTransferTest
                        CachedFailuresPolicy.NO, false );
 
         // Attempt the proxy fetch.
-        StorageAsset downloadedFile = proxyHandler.fetchFromProxies( managedDefaultRepository, path );
+        StorageAsset downloadedFile = proxyHandler.fetchFromProxies( managedDefaultRepository.getRepository(), path );
 
         assertNotDownloaded( downloadedFile );
         assertNotModified( expectedFile, originalModificationTime );
@@ -227,7 +227,7 @@ public class ManagedDefaultTransferTest
                        SnapshotsPolicy.ALWAYS, CachedFailuresPolicy.NO, false );
 
         // Attempt the proxy fetch.
-        StorageAsset downloadedFile = proxyHandler.fetchFromProxies( managedDefaultRepository, artifact );
+        StorageAsset downloadedFile = proxyHandler.fetchFromProxies( managedDefaultRepository.getRepository(), artifact );
 
         assertNotDownloaded( downloadedFile );
         assertNotModified( expectedFile, originalModificationTime );
@@ -272,7 +272,7 @@ public class ManagedDefaultTransferTest
                        SnapshotsPolicy.ALWAYS, CachedFailuresPolicy.NO, false );
 
         // Attempt the proxy fetch.
-        StorageAsset downloadedFile = proxyHandler.fetchFromProxies( managedDefaultRepository, artifact );
+        StorageAsset downloadedFile = proxyHandler.fetchFromProxies( managedDefaultRepository.getRepository(), artifact );
 
         Path proxiedFile = Paths.get(REPOPATH_PROXIED1, path);
         assertFileEquals( expectedFile, downloadedFile.getFilePath(), proxiedFile );
@@ -304,7 +304,7 @@ public class ManagedDefaultTransferTest
                        CachedFailuresPolicy.NO, false );
 
         // Attempt the proxy fetch.
-        StorageAsset downloadedFile = proxyHandler.fetchFromProxies( managedDefaultRepository, artifact );
+        StorageAsset downloadedFile = proxyHandler.fetchFromProxies( managedDefaultRepository.getRepository(), artifact );
 
         Path proxiedFile = Paths.get(REPOPATH_PROXIED1, path);
         assertFileEquals( expectedFile, downloadedFile.getFilePath(), proxiedFile );
@@ -328,7 +328,7 @@ public class ManagedDefaultTransferTest
         saveConnector( ID_DEFAULT_MANAGED, ID_PROXIED2, false );
 
         // Attempt the proxy fetch.
-        StorageAsset downloadedFile = proxyHandler.fetchFromProxies( managedDefaultRepository, artifact );
+        StorageAsset downloadedFile = proxyHandler.fetchFromProxies( managedDefaultRepository.getRepository(), artifact );
 
         Path proxied1File = Paths.get(REPOPATH_PROXIED1, path);
         Path proxied2File = Paths.get(REPOPATH_PROXIED2, path);
@@ -359,7 +359,7 @@ public class ManagedDefaultTransferTest
         saveConnector( ID_DEFAULT_MANAGED, ID_PROXIED2, false );
 
         // Attempt the proxy fetch.
-        StorageAsset downloadedFile = proxyHandler.fetchFromProxies( managedDefaultRepository, artifact );
+        StorageAsset downloadedFile = proxyHandler.fetchFromProxies( managedDefaultRepository.getRepository(), artifact );
 
         Path proxied2File = Paths.get(REPOPATH_PROXIED2, path);
         assertFileEquals( expectedFile, downloadedFile.getFilePath(), proxied2File );
@@ -383,7 +383,7 @@ public class ManagedDefaultTransferTest
         saveConnector( ID_DEFAULT_MANAGED, ID_PROXIED2, false );
 
         // Attempt the proxy fetch.
-        StorageAsset downloadedFile = proxyHandler.fetchFromProxies( managedDefaultRepository, artifact );
+        StorageAsset downloadedFile = proxyHandler.fetchFromProxies( managedDefaultRepository.getRepository(), artifact );
 
         assertNull( "File returned was: " + downloadedFile + "; should have got a not found exception",
                     downloadedFile );
@@ -403,7 +403,8 @@ public class ManagedDefaultTransferTest
         assertNotExistsInManagedDefaultRepo( expectedFile );
 
         // Configure Repository (usually done within archiva.xml configuration)
-        saveRemoteRepositoryConfig( "badproxied", "Bad Proxied", "test://bad.machine.com/repo/", "default" );
+        saveRemoteRepositoryConfig( "badproxied", "Bad Proxied", "" +
+            "http://bad.machine.com/repo/", "default" );
 
         wagonMock.get( EasyMock.eq( path), EasyMock.anyObject( File.class ) );
         EasyMock.expectLastCall().andThrow( new ResourceDoesNotExistException( "transfer failed" )  );
@@ -414,7 +415,7 @@ public class ManagedDefaultTransferTest
         saveConnector( ID_DEFAULT_MANAGED, ID_PROXIED2, false );
 
         // Attempt the proxy fetch.
-        StorageAsset downloadedFile = proxyHandler.fetchFromProxies( managedDefaultRepository, artifact );
+        StorageAsset downloadedFile = proxyHandler.fetchFromProxies( managedDefaultRepository.getRepository(), artifact );
 
         wagonMockControl.verify();
 
@@ -436,8 +437,8 @@ public class ManagedDefaultTransferTest
         assertNotExistsInManagedDefaultRepo( expectedFile );
 
         // Configure Repository (usually done within archiva.xml configuration)
-        saveRemoteRepositoryConfig( "badproxied1", "Bad Proxied 1", "test://bad.machine.com/repo/", "default" );
-        saveRemoteRepositoryConfig( "badproxied2", "Bad Proxied 2", "test://dead.machine.com/repo/", "default" );
+        saveRemoteRepositoryConfig( "badproxied1", "Bad Proxied 1", "http://bad.machine.com/repo/", "default" );
+        saveRemoteRepositoryConfig( "badproxied2", "Bad Proxied 2", "http://dead.machine.com/repo/", "default" );
 
         // Configure Connector (usually done within archiva.xml configuration)
         saveConnector( ID_DEFAULT_MANAGED, "badproxied1", false );
@@ -453,7 +454,7 @@ public class ManagedDefaultTransferTest
 
         wagonMockControl.replay();
 
-        StorageAsset downloadedFile = proxyHandler.fetchFromProxies( managedDefaultRepository, artifact );
+        StorageAsset downloadedFile = proxyHandler.fetchFromProxies( managedDefaultRepository.getRepository(), artifact );
 
         assertNotDownloaded( downloadedFile );
 
diff --git a/archiva-modules/archiva-maven/archiva-maven-proxy/src/test/java/org/apache/archiva/proxy/MetadataTransferTest.java b/archiva-modules/archiva-maven/archiva-maven-proxy/src/test/java/org/apache/archiva/proxy/MetadataTransferTest.java
index 323f666..289a82c 100644
--- a/archiva-modules/archiva-maven/archiva-maven-proxy/src/test/java/org/apache/archiva/proxy/MetadataTransferTest.java
+++ b/archiva-modules/archiva-maven/archiva-maven-proxy/src/test/java/org/apache/archiva/proxy/MetadataTransferTest.java
@@ -128,7 +128,7 @@ public class MetadataTransferTest
 
         ProjectReference metadata = createProjectReference( requestedResource );
 
-        StorageAsset downloadedFile = proxyHandler.fetchMetadataFromProxies( managedDefaultRepository,
+        StorageAsset downloadedFile = proxyHandler.fetchMetadataFromProxies( managedDefaultRepository.getRepository(),
                                                                      managedDefaultRepository.toMetadataPath(
                                                                          metadata ) ).getFile();
 
@@ -145,7 +145,7 @@ public class MetadataTransferTest
         String requestedResource = "org/apache/maven/test/get-default-layout/maven-metadata.xml";
         setupTestableManagedRepository( requestedResource );
 
-        saveRemoteRepositoryConfig( "badproxied1", "Bad Proxied 1", "test://bad.machine.com/repo/", "default" );
+        saveRemoteRepositoryConfig( "badproxied1", "Bad Proxied 1", "http://bad.machine.com/repo/", "default" );
 
         // Configure Connector (usually done within archiva.xml configuration)
         saveConnector( ID_DEFAULT_MANAGED, "badproxied1", ChecksumPolicy.FIX, ReleasesPolicy.ALWAYS,
@@ -991,7 +991,7 @@ public class MetadataTransferTest
 
         ProjectReference metadata = createProjectReference( requestedResource );
 
-        StorageAsset downloadedFile = proxyHandler.fetchMetadataFromProxies( managedDefaultRepository,
+        StorageAsset downloadedFile = proxyHandler.fetchMetadataFromProxies( managedDefaultRepository.getRepository(),
                                                                      managedDefaultRepository.toMetadataPath(
                                                                          metadata ) ).getFile();
 
@@ -1017,7 +1017,7 @@ public class MetadataTransferTest
         Path expectedFile = managedDefaultDir.resolve(requestedResource);
         ProjectReference metadata = createProjectReference( requestedResource );
 
-        StorageAsset downloadedFile = proxyHandler.fetchMetadataFromProxies( managedDefaultRepository,
+        StorageAsset downloadedFile = proxyHandler.fetchMetadataFromProxies( managedDefaultRepository.getRepository(),
                                                                      managedDefaultRepository.toMetadataPath(
                                                                          metadata ) ).getFile();
 
@@ -1038,7 +1038,7 @@ public class MetadataTransferTest
 
         VersionedReference metadata = createVersionedReference( requestedResource );
 
-        StorageAsset downloadedFile = proxyHandler.fetchMetadataFromProxies( managedDefaultRepository,
+        StorageAsset downloadedFile = proxyHandler.fetchMetadataFromProxies( managedDefaultRepository.getRepository(),
                                                                      managedDefaultRepository.toMetadataPath(
                                                                          metadata ) ).getFile();
 
@@ -1064,7 +1064,7 @@ public class MetadataTransferTest
         Path expectedFile = managedDefaultDir.resolve(requestedResource);
         VersionedReference metadata = createVersionedReference( requestedResource );
 
-        StorageAsset downloadedFile = proxyHandler.fetchMetadataFromProxies( managedDefaultRepository,
+        StorageAsset downloadedFile = proxyHandler.fetchMetadataFromProxies( managedDefaultRepository.getRepository(),
                                                                      managedDefaultRepository.toMetadataPath(
                                                                          metadata ) ).getFile();
 
diff --git a/archiva-modules/archiva-maven/archiva-maven-proxy/src/test/java/org/apache/archiva/proxy/MockConfiguration.java b/archiva-modules/archiva-maven/archiva-maven-proxy/src/test/java/org/apache/archiva/proxy/MockConfiguration.java
index c686e8d..1579ce7 100644
--- a/archiva-modules/archiva-maven/archiva-maven-proxy/src/test/java/org/apache/archiva/proxy/MockConfiguration.java
+++ b/archiva-modules/archiva-maven/archiva-maven-proxy/src/test/java/org/apache/archiva/proxy/MockConfiguration.java
@@ -91,6 +91,7 @@ public class MockConfiguration
         registryListeners.add( listener );
     }
 
+
     @Override
     public void removeChangeListener( RegistryListener listener )
     {
@@ -123,6 +124,10 @@ public class MockConfiguration
                 e.printStackTrace();
             }
         }
+
+        for (ConfigurationListener listener : configListeners) {
+            listener.configurationEvent( new ConfigurationEvent( ConfigurationEvent.CHANGED ) );
+        }
     }
 
     @Override
diff --git a/archiva-modules/archiva-maven/archiva-maven-proxy/src/test/java/org/apache/archiva/proxy/SnapshotTransferTest.java b/archiva-modules/archiva-maven/archiva-maven-proxy/src/test/java/org/apache/archiva/proxy/SnapshotTransferTest.java
index 98055b5..01d59c2 100644
--- a/archiva-modules/archiva-maven/archiva-maven-proxy/src/test/java/org/apache/archiva/proxy/SnapshotTransferTest.java
+++ b/archiva-modules/archiva-maven/archiva-maven-proxy/src/test/java/org/apache/archiva/proxy/SnapshotTransferTest.java
@@ -60,7 +60,7 @@ public class SnapshotTransferTest
         // Configure Connector (usually done within archiva.xml configuration)
         saveConnector( ID_DEFAULT_MANAGED, ID_PROXIED1, false);
 
-        StorageAsset downloadedFile = proxyHandler.fetchFromProxies( managedDefaultRepository, artifact );
+        StorageAsset downloadedFile = proxyHandler.fetchFromProxies( managedDefaultRepository.getRepository(), artifact );
         assertNotDownloaded( downloadedFile );
         assertNoTempFiles( expectedFile );
     }
@@ -81,7 +81,7 @@ public class SnapshotTransferTest
         // Configure Connector (usually done within archiva.xml configuration)
         saveConnector( ID_DEFAULT_MANAGED, ID_PROXIED1, false);
 
-        StorageAsset downloadedFile = proxyHandler.fetchFromProxies( managedDefaultRepository, artifact );
+        StorageAsset downloadedFile = proxyHandler.fetchFromProxies( managedDefaultRepository.getRepository(), artifact );
 
         Path proxiedFile = Paths.get(REPOPATH_PROXIED1, path);
         assertFileEquals( expectedFile, downloadedFile.getFilePath(), proxiedFile );
@@ -104,7 +104,7 @@ public class SnapshotTransferTest
         // Configure Connector (usually done within archiva.xml configuration)
         saveConnector( ID_DEFAULT_MANAGED, ID_PROXIED1, false);
 
-        StorageAsset downloadedFile = proxyHandler.fetchFromProxies( managedDefaultRepository, artifact );
+        StorageAsset downloadedFile = proxyHandler.fetchFromProxies( managedDefaultRepository.getRepository(), artifact );
 
         Path proxiedFile = Paths.get(REPOPATH_PROXIED1, path);
         assertFileEquals( expectedFile, downloadedFile.getFilePath(), proxiedFile );
@@ -129,7 +129,7 @@ public class SnapshotTransferTest
         saveConnector( ID_DEFAULT_MANAGED, ID_PROXIED1, false );
 
         // Attempt to download.
-        StorageAsset downloadedFile = proxyHandler.fetchFromProxies( managedDefaultRepository, artifact );
+        StorageAsset downloadedFile = proxyHandler.fetchFromProxies( managedDefaultRepository.getRepository(), artifact );
 
         // Should not have downloaded as managed is newer than remote.
         assertNotDownloaded( downloadedFile );
@@ -221,7 +221,7 @@ public class SnapshotTransferTest
         // Configure Connector (usually done within archiva.xml configuration)
         saveConnector( ID_DEFAULT_MANAGED, ID_PROXIED1, false);
 
-        StorageAsset downloadedFile = proxyHandler.fetchFromProxies( managedDefaultRepository, artifact );
+        StorageAsset downloadedFile = proxyHandler.fetchFromProxies( managedDefaultRepository.getRepository(), artifact );
 
         assertFileEquals( expectedFile, downloadedFile.getFilePath(), proxiedFile );
         assertNoTempFiles( expectedFile );
@@ -245,7 +245,7 @@ public class SnapshotTransferTest
         // Configure Connector (usually done within archiva.xml configuration)
         saveConnector( ID_DEFAULT_MANAGED, ID_PROXIED1, false);
 
-        StorageAsset downloadedFile = proxyHandler.fetchFromProxies( managedDefaultRepository, artifact );
+        StorageAsset downloadedFile = proxyHandler.fetchFromProxies( managedDefaultRepository.getRepository(), artifact );
 
         assertNotDownloaded( downloadedFile );
         assertNotModified( expectedFile, expectedTimestamp );
@@ -271,7 +271,7 @@ public class SnapshotTransferTest
         saveConnector( ID_DEFAULT_MANAGED, ID_PROXIED2, ChecksumPolicy.IGNORE, ReleasesPolicy.ALWAYS,
                        SnapshotsPolicy.ALWAYS, CachedFailuresPolicy.YES , false);
 
-        StorageAsset downloadedFile = proxyHandler.fetchFromProxies( managedDefaultRepository, artifact );
+        StorageAsset downloadedFile = proxyHandler.fetchFromProxies( managedDefaultRepository.getRepository(), artifact );
 
         Path proxiedFile = Paths.get(REPOPATH_PROXIED1, path);
         assertFileEquals( expectedFile, downloadedFile.getFilePath(), proxiedFile );
@@ -294,7 +294,7 @@ public class SnapshotTransferTest
         // Configure Connector (usually done within archiva.xml configuration)
         saveConnector( ID_DEFAULT_MANAGED, ID_PROXIED1, false);
 
-        StorageAsset downloadedFile = proxyHandler.fetchFromProxies( managedDefaultRepository, artifact );
+        StorageAsset downloadedFile = proxyHandler.fetchFromProxies( managedDefaultRepository.getRepository(), artifact );
 
         Path proxiedFile = Paths.get(REPOPATH_PROXIED1, path);
         assertFileEquals( expectedFile, downloadedFile.getFilePath(), proxiedFile );
@@ -321,7 +321,7 @@ public class SnapshotTransferTest
         // Configure Connector (usually done within archiva.xml configuration)
         saveConnector( ID_DEFAULT_MANAGED, ID_PROXIED1, false);
 
-        StorageAsset downloadedFile = proxyHandler.fetchFromProxies( managedDefaultRepository, artifact );
+        StorageAsset downloadedFile = proxyHandler.fetchFromProxies( managedDefaultRepository.getRepository(), artifact );
 
         Path proxiedFile = Paths.get(REPOPATH_PROXIED1, path);
         assertFileEquals( expectedFile, downloadedFile.getFilePath(), proxiedFile );
diff --git a/archiva-modules/archiva-maven/archiva-maven-proxy/src/test/java/org/apache/archiva/proxy/WagonDelegate.java b/archiva-modules/archiva-maven/archiva-maven-proxy/src/test/java/org/apache/archiva/proxy/WagonDelegate.java
index 702fe99..6c733a2 100644
--- a/archiva-modules/archiva-maven/archiva-maven-proxy/src/test/java/org/apache/archiva/proxy/WagonDelegate.java
+++ b/archiva-modules/archiva-maven/archiva-maven-proxy/src/test/java/org/apache/archiva/proxy/WagonDelegate.java
@@ -269,11 +269,11 @@ public class WagonDelegate
         try
         {
             Files.createDirectories(destination.getParent());
-            if ( contentToGet == null )
+            if ( contentToGet == null && !Files.exists(destination))
             {
                 Files.createFile(destination);
             }
-            else
+            else if (contentToGet != null)
             {
                 org.apache.archiva.common.utils.FileUtils.writeStringToFile(destination, Charset.defaultCharset(), contentToGet);
             }
@@ -283,4 +283,8 @@ public class WagonDelegate
             throw new RuntimeException( e.getMessage(), e );
         }
     }
+
+    public void cleanup() {
+
+    }
 }
diff --git a/archiva-modules/archiva-maven/archiva-maven-proxy/src/test/resources/spring-context.xml b/archiva-modules/archiva-maven/archiva-maven-proxy/src/test/resources/spring-context.xml
index d79ce1a..488c1e6 100755
--- a/archiva-modules/archiva-maven/archiva-maven-proxy/src/test/resources/spring-context.xml
+++ b/archiva-modules/archiva-maven/archiva-maven-proxy/src/test/resources/spring-context.xml
@@ -50,11 +50,13 @@
   <bean name="repositoryContentProvider#mocked" class="org.apache.archiva.repository.mock.RepositoryContentProviderMock" />
 
 
-  <bean name="repositoryProxyConnectors#test" class="org.apache.archiva.proxy.maven.MavenRepositoryProxyHandler">
+  <bean name="repositoryProxyHandler#test" class="org.apache.archiva.proxy.maven.MavenRepositoryProxyHandler">
     <property name="archivaConfiguration" ref="archivaConfiguration#mock"/>
     <property name="metadataTools" ref="metadataTools#mocked"/>
   </bean>
 
+  <alias name="repositoryProxyHandler#test" alias="repositoryProxyHandler#maven"/>
+
   <bean name="metadataTools#default" class="org.apache.archiva.repository.metadata.MetadataTools">
     <property name="configuration" ref="archivaConfiguration#mock"/>
   </bean>
@@ -79,7 +81,7 @@
     <property name="timeToLiveSeconds" value="1800"/>
   </bean>
 
-  <bean name="wagon#test" class="org.apache.archiva.proxy.WagonDelegate" scope="singleton"/>
+  <bean name="wagon#http" class="org.apache.archiva.proxy.WagonDelegate" scope="singleton"/>
   <bean name="wagon#file" scope="prototype" class="org.apache.maven.wagon.providers.file.FileWagon"/>
 
   <alias name="userConfiguration#redback" alias="userConfiguration#default"/>
diff --git a/archiva-modules/archiva-maven/archiva-maven-repository/src/main/java/org/apache/archiva/metadata/repository/storage/maven2/Maven2RepositoryStorage.java b/archiva-modules/archiva-maven/archiva-maven-repository/src/main/java/org/apache/archiva/metadata/repository/storage/maven2/Maven2RepositoryStorage.java
index d6668b6..3725769 100644
--- a/archiva-modules/archiva-maven/archiva-maven-repository/src/main/java/org/apache/archiva/metadata/repository/storage/maven2/Maven2RepositoryStorage.java
+++ b/archiva-modules/archiva-maven/archiva-maven-repository/src/main/java/org/apache/archiva/metadata/repository/storage/maven2/Maven2RepositoryStorage.java
@@ -558,7 +558,7 @@ public class Maven2RepositoryStorage
     }
 
     @Override
-    public void applyServerSideRelocation(ManagedRepositoryContent managedRepository, ArtifactReference artifact)
+    public void applyServerSideRelocation(ManagedRepository managedRepository, ArtifactReference artifact)
             throws ProxyDownloadException {
         if ("pom".equals(artifact.getType())) {
             return;
@@ -571,7 +571,7 @@ public class Maven2RepositoryStorage
         pomReference.setVersion(artifact.getVersion());
         pomReference.setType("pom");
 
-        RepositoryType repositoryType = managedRepository.getRepository().getType();
+        RepositoryType repositoryType = managedRepository.getType();
         if (!proxyRegistry.hasHandler(repositoryType)) {
             throw new ProxyDownloadException("No proxy handler found for repository type " + repositoryType, new HashMap<>());
         }
@@ -582,7 +582,7 @@ public class Maven2RepositoryStorage
         proxyHandler.fetchFromProxies(managedRepository, pomReference);
 
         // Open and read the POM from the managed repo
-        StorageAsset pom = managedRepository.toFile(pomReference);
+        StorageAsset pom = managedRepository.getContent().toFile(pomReference);
 
         if (!pom.exists()) {
             return;
diff --git a/archiva-modules/archiva-web/archiva-rest/archiva-rest-services/src/main/java/org/apache/archiva/rest/services/DefaultBrowseService.java b/archiva-modules/archiva-web/archiva-rest/archiva-rest-services/src/main/java/org/apache/archiva/rest/services/DefaultBrowseService.java
index a6dcb73..256d97f 100644
--- a/archiva-modules/archiva-web/archiva-rest/archiva-rest-services/src/main/java/org/apache/archiva/rest/services/DefaultBrowseService.java
+++ b/archiva-modules/archiva-web/archiva-rest/archiva-rest-services/src/main/java/org/apache/archiva/rest/services/DefaultBrowseService.java
@@ -949,13 +949,13 @@ public class DefaultBrowseService
 
                 String path = managedRepositoryContent.toPath( archivaArtifact );
 
-                file = proxyHandler.fetchFromProxies( managedRepositoryContent, path );
+                file = proxyHandler.fetchFromProxies( managedRepositoryContent.getRepository(), path );
 
                 if ( file != null && file.exists() )
                 {
                     // download pom now
                     String pomPath = StringUtils.substringBeforeLast( path, ".jar" ) + ".pom";
-                    proxyHandler.fetchFromProxies( managedRepositoryContent, pomPath );
+                    proxyHandler.fetchFromProxies( managedRepositoryContent.getRepository(), pomPath );
                     return true;
                 }
             }
diff --git a/archiva-modules/archiva-web/archiva-security/src/test/java/org/apache/archiva/security/mock/MockBeanServices.java b/archiva-modules/archiva-web/archiva-security/src/test/java/org/apache/archiva/security/mock/MockBeanServices.java
index 929921a..e0d5585 100644
--- a/archiva-modules/archiva-web/archiva-security/src/test/java/org/apache/archiva/security/mock/MockBeanServices.java
+++ b/archiva-modules/archiva-web/archiva-security/src/test/java/org/apache/archiva/security/mock/MockBeanServices.java
@@ -28,6 +28,7 @@ import org.apache.archiva.metadata.repository.storage.*;
 import org.apache.archiva.model.ArtifactReference;
 import org.apache.archiva.policies.ProxyDownloadException;
 import org.apache.archiva.redback.components.taskqueue.TaskQueueException;
+import org.apache.archiva.repository.ManagedRepository;
 import org.apache.archiva.repository.ManagedRepositoryContent;
 import org.apache.archiva.repository.events.RepositoryListener;
 import org.apache.archiva.scheduler.repository.model.RepositoryArchivaTaskScheduler;
@@ -101,7 +102,7 @@ public class MockBeanServices
     }
 
     @Override
-    public void applyServerSideRelocation( ManagedRepositoryContent managedRepository, ArtifactReference artifact )
+    public void applyServerSideRelocation( ManagedRepository managedRepository, ArtifactReference artifact )
         throws ProxyDownloadException
     {
 
diff --git a/archiva-modules/archiva-web/archiva-webdav/src/main/java/org/apache/archiva/webdav/ArchivaDavResourceFactory.java b/archiva-modules/archiva-web/archiva-webdav/src/main/java/org/apache/archiva/webdav/ArchivaDavResourceFactory.java
index c2f2365..e839bda 100644
--- a/archiva-modules/archiva-web/archiva-webdav/src/main/java/org/apache/archiva/webdav/ArchivaDavResourceFactory.java
+++ b/archiva-modules/archiva-web/archiva-webdav/src/main/java/org/apache/archiva/webdav/ArchivaDavResourceFactory.java
@@ -598,7 +598,7 @@ public class ArchivaDavResourceFactory
                     {
                         boolean previouslyExisted = repoAsset.exists();
 
-                        boolean fromProxy = fetchContentFromProxies( managedRepositoryContent, request, logicalResource );
+                        boolean fromProxy = fetchContentFromProxies( managedRepository, request, logicalResource );
 
                         StorageAsset resourceAsset=null;
                         // At this point the incoming request can either be in default or
@@ -753,16 +753,16 @@ public class ArchivaDavResourceFactory
         return resource;
     }
 
-    private boolean fetchContentFromProxies( ManagedRepositoryContent managedRepository, DavServletRequest request,
+    private boolean fetchContentFromProxies( ManagedRepository managedRepository, DavServletRequest request,
                                              LogicalResource resource )
         throws DavException
     {
         String path = resource.getPath();
-        if (!proxyRegistry.hasHandler(managedRepository.getRepository().getType())) {
-            throw new DavException(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, "No proxy handler found for repository type "+managedRepository.getRepository().getType());
+        if (!proxyRegistry.hasHandler(managedRepository.getType())) {
+            throw new DavException(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, "No proxy handler found for repository type "+managedRepository.getType());
         }
-        RepositoryRequestInfo repositoryRequestInfo = managedRepository.getRepository().getRequestInfo();
-        RepositoryProxyHandler proxyHandler = proxyRegistry.getHandler(managedRepository.getRepository().getType()).get(0);
+        RepositoryRequestInfo repositoryRequestInfo = managedRepository.getRequestInfo();
+        RepositoryProxyHandler proxyHandler = proxyRegistry.getHandler(managedRepository.getType()).get(0);
         if ( repositoryRequestInfo.isSupportFile( path ) )
         {
             StorageAsset proxiedFile = proxyHandler.fetchFromProxies( managedRepository, path );
@@ -793,7 +793,7 @@ public class ArchivaDavResourceFactory
 
             if ( artifact != null )
             {
-                String repositoryLayout = managedRepository.getRepository().getLayout();
+                String repositoryLayout = managedRepository.getLayout();
 
                 RepositoryStorage repositoryStorage =
                     this.applicationContext.getBean( "repositoryStorage#" + repositoryLayout, RepositoryStorage.class );
@@ -801,7 +801,7 @@ public class ArchivaDavResourceFactory
 
                 StorageAsset proxiedFile = proxyHandler.fetchFromProxies( managedRepository, artifact );
 
-                resource.setPath( managedRepository.toPath( artifact ) );
+                resource.setPath( managedRepository.getContent().toPath( artifact ) );
 
                 log.debug( "Proxied artifact '{}:{}:{}'", artifact.getGroupId(), artifact.getArtifactId(),
                            artifact.getVersion() );
diff --git a/archiva-modules/archiva-web/archiva-webdav/src/test/java/org/apache/archiva/webdav/OverridingRepositoryProxyHandler.java b/archiva-modules/archiva-web/archiva-webdav/src/test/java/org/apache/archiva/webdav/OverridingRepositoryProxyHandler.java
index 1343c94..9f7c551 100644
--- a/archiva-modules/archiva-web/archiva-webdav/src/test/java/org/apache/archiva/webdav/OverridingRepositoryProxyHandler.java
+++ b/archiva-modules/archiva-web/archiva-webdav/src/test/java/org/apache/archiva/webdav/OverridingRepositoryProxyHandler.java
@@ -21,13 +21,11 @@ package org.apache.archiva.webdav;
 
 import org.apache.archiva.proxy.maven.MavenRepositoryProxyHandler;
 import org.apache.archiva.proxy.model.ProxyFetchResult;
-import org.apache.archiva.repository.ManagedRepositoryContent;
+import org.apache.archiva.repository.ManagedRepository;
 import org.apache.archiva.repository.storage.StorageAsset;
 import org.apache.commons.io.FileUtils;
 
 import java.io.IOException;
-import java.nio.file.Path;
-import java.nio.file.Paths;
 
 class OverridingRepositoryProxyHandler
     extends MavenRepositoryProxyHandler
@@ -39,9 +37,9 @@ class OverridingRepositoryProxyHandler
     }
 
     @Override
-    public ProxyFetchResult fetchMetadataFromProxies(ManagedRepositoryContent repository, String logicalPath )
+    public ProxyFetchResult fetchMetadataFromProxies( ManagedRepository repository, String logicalPath )
     {
-        StorageAsset target = repository.getRepository().getAsset( logicalPath );
+        StorageAsset target = repository.getAsset( logicalPath );
         try
         {
             FileUtils.copyFile( archivaDavResourceFactoryTest.getProjectBase().resolve( "target/test-classes/maven-metadata.xml" ).toFile(), target.getFilePath().toFile() );
diff --git a/archiva-modules/metadata/metadata-repository-api/src/main/java/org/apache/archiva/metadata/repository/storage/RepositoryStorage.java b/archiva-modules/metadata/metadata-repository-api/src/main/java/org/apache/archiva/metadata/repository/storage/RepositoryStorage.java
index 6fb46d6..794532a 100644
--- a/archiva-modules/metadata/metadata-repository-api/src/main/java/org/apache/archiva/metadata/repository/storage/RepositoryStorage.java
+++ b/archiva-modules/metadata/metadata-repository-api/src/main/java/org/apache/archiva/metadata/repository/storage/RepositoryStorage.java
@@ -25,6 +25,7 @@ import org.apache.archiva.metadata.model.ProjectVersionMetadata;
 import org.apache.archiva.filter.Filter;
 import org.apache.archiva.model.ArtifactReference;
 import org.apache.archiva.policies.ProxyDownloadException;
+import org.apache.archiva.repository.ManagedRepository;
 import org.apache.archiva.repository.ManagedRepositoryContent;
 import org.apache.archiva.xml.XMLException;
 
@@ -70,7 +71,7 @@ public interface RepositoryStorage
      * @param artifact the artifact reference
      * @throws org.apache.archiva.policies.ProxyDownloadException
      */    
-    void applyServerSideRelocation( ManagedRepositoryContent managedRepository, ArtifactReference artifact )
+    void applyServerSideRelocation( ManagedRepository managedRepository, ArtifactReference artifact )
         throws ProxyDownloadException;
 
     /**
diff --git a/archiva-modules/plugins/metadata-store-cassandra/src/test/java/org/apache/archiva/metadata/repository/cassandra/MockRepositoryStorage.java b/archiva-modules/plugins/metadata-store-cassandra/src/test/java/org/apache/archiva/metadata/repository/cassandra/MockRepositoryStorage.java
index 3ebed1a..70f6cf0 100644
--- a/archiva-modules/plugins/metadata-store-cassandra/src/test/java/org/apache/archiva/metadata/repository/cassandra/MockRepositoryStorage.java
+++ b/archiva-modules/plugins/metadata-store-cassandra/src/test/java/org/apache/archiva/metadata/repository/cassandra/MockRepositoryStorage.java
@@ -34,6 +34,7 @@ import org.apache.archiva.metadata.repository.storage.RepositoryStorageMetadataN
 import org.apache.archiva.metadata.repository.storage.RepositoryStorageRuntimeException;
 import org.apache.archiva.model.ArtifactReference;
 import org.apache.archiva.policies.ProxyDownloadException;
+import org.apache.archiva.repository.ManagedRepository;
 import org.apache.archiva.repository.ManagedRepositoryContent;
 import org.apache.archiva.repository.events.RepositoryListener;
 import org.apache.archiva.xml.XMLException;
@@ -105,7 +106,7 @@ public class MockRepositoryStorage
     }
 
     @Override
-    public void applyServerSideRelocation( ManagedRepositoryContent managedRepository, ArtifactReference artifact )
+    public void applyServerSideRelocation( ManagedRepository managedRepository, ArtifactReference artifact )
         throws ProxyDownloadException
     {
 


[archiva] 02/08: Enhancing repository events

Posted by ma...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

martin_s pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/archiva.git

commit 9948797e50b4af71913bdbf0dec7810b2f676fd7
Author: Martin Stockhammer <ma...@apache.org>
AuthorDate: Thu Sep 12 13:09:40 2019 +0200

    Enhancing repository events
---
 .../src/test/java/RepositoryProviderMock.java      |    3 +-
 .../repository/mock/RepositoryProviderMock.java    |    5 +-
 .../org/apache/archiva/repository/Repository.java  |    2 +-
 .../archiva/repository/RepositoryProvider.java     |    1 +
 .../{RepositoryEvent.java => events/Event.java}    |   50 +-
 .../EventType.java}                                |    9 +-
 .../LifecycleEvent.java}                           |   17 +-
 .../RepositoryEvent.java}                          |   20 +-
 .../{ => events}/RepositoryEventHandler.java       |   16 +-
 .../{ => events}/RepositoryEventListener.java      |    6 +-
 .../RepositoryRegistryEvent.java}                  |   17 +-
 .../RepositoryValueEvent.java}                     |   41 +-
 .../repository/features/AbstractFeature.java       |    6 +-
 .../repository/features/IndexCreationEvent.java    |   21 +-
 .../repository/features/IndexCreationFeature.java  |    6 +-
 .../repository/features/RemoteIndexFeature.java    |   10 +
 .../archiva/repository/AbstractRepository.java     |   56 +-
 .../archiva/repository/RepositoryRegistry.java     | 1181 +++++++++-----------
 .../repository/mock/RepositoryProviderMock.java    |    4 +-
 .../repository/mock/RepositoryProviderMock.java    |    5 +-
 20 files changed, 723 insertions(+), 753 deletions(-)

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 15cf17e..5302a74 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
@@ -36,6 +36,7 @@ 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.events.Event;
 import org.apache.archiva.repository.features.ArtifactCleanupFeature;
 import org.apache.archiva.repository.features.IndexCreationFeature;
 import org.apache.archiva.repository.features.RemoteIndexFeature;
@@ -255,7 +256,7 @@ public class RepositoryProviderMock implements RepositoryProvider
     }
 
     @Override
-    public <T> void raise(org.apache.archiva.repository.RepositoryEvent<T> event) {
+    public void raise(Event event) {
 
     }
 
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 a23ae0f..c10a5a8 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
@@ -32,7 +32,8 @@ 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.RepositoryEvent;
+import org.apache.archiva.repository.events.Event;
+import org.apache.archiva.repository.events.RepositoryValueEvent;
 import org.apache.archiva.repository.RepositoryException;
 import org.apache.archiva.repository.RepositoryGroup;
 import org.apache.archiva.repository.RepositoryProvider;
@@ -284,7 +285,7 @@ public class RepositoryProviderMock implements RepositoryProvider
     }
 
     @Override
-    public <T> void raise(RepositoryEvent<T> event) {
+    public void raise(Event event) {
 
     }
 }
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 cc43ab2..9b26143 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
@@ -20,12 +20,12 @@ package org.apache.archiva.repository;
  */
 
 import org.apache.archiva.indexer.ArchivaIndexingContext;
+import org.apache.archiva.repository.events.RepositoryEventHandler;
 import org.apache.archiva.repository.storage.RepositoryStorage;
 import org.apache.archiva.repository.features.RepositoryFeature;
 import org.apache.archiva.repository.storage.StorageAsset;
 
 import java.net.URI;
-import java.nio.file.Path;
 import java.util.Locale;
 import java.util.Set;
 
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 1f26a5d..3a405fb 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
@@ -22,6 +22,7 @@ package org.apache.archiva.repository;
 import org.apache.archiva.configuration.ManagedRepositoryConfiguration;
 import org.apache.archiva.configuration.RemoteRepositoryConfiguration;
 import org.apache.archiva.configuration.RepositoryGroupConfiguration;
+import org.apache.archiva.repository.events.RepositoryEventListener;
 
 import java.io.IOException;
 import java.util.Set;
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/events/Event.java
similarity index 61%
copy from archiva-modules/archiva-base/archiva-repository-api/src/main/java/org/apache/archiva/repository/RepositoryEvent.java
copy to archiva-modules/archiva-base/archiva-repository-api/src/main/java/org/apache/archiva/repository/events/Event.java
index 8a9db88..afac04c 100644
--- 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/events/Event.java
@@ -1,4 +1,4 @@
-package org.apache.archiva.repository;
+package org.apache.archiva.repository.events;
 
 /*
  * Licensed to the Apache Software Foundation (ASF) under one
@@ -21,49 +21,47 @@ package org.apache.archiva.repository;
 
 import java.time.LocalDateTime;
 
-/**
- * Repository event. Repository events are used for providing information about repository changes.
- *
- * @param <T>
- */
-public class RepositoryEvent<T> {
+public class Event<O> {
 
+    Event previous;
+    final O originator;
     final EventType type;
-    final Repository repo;
-    final T value;
-    final T oldValue;
     final LocalDateTime instant;
 
-    public RepositoryEvent(EventType type, Repository repo, T oldValue, T value) {
+    public Event(EventType type, O originator) {
+        this.originator = originator;
         this.type = type;
-        this.repo = repo;
-        this.value = value;
-        this.oldValue = oldValue;
         this.instant = LocalDateTime.now();
     }
 
-    public interface EventType {
-        String name();
+    private <OO> Event(Event<OO> previous, O originator) {
+        this.previous = previous;
+        this.originator = originator;
+        this.type = previous.getType();
+        this.instant = previous.getInstant();
     }
 
-
     public EventType getType() {
         return type;
     };
 
-    public Repository getRepository() {
-        return repo;
-    };
+    public LocalDateTime getInstant() {
+        return instant;
+    }
 
-    public T getValue() {
-        return value;
+    public O getOriginator() {
+        return originator;
     }
 
-    public T getOldValue() {
-        return oldValue;
+    public <NO> Event<NO> recreate(NO newOrigin) {
+        return new Event(this, newOrigin);
     }
 
-    public LocalDateTime getInstant() {
-        return instant;
+    public Event getPreviousEvent() {
+        return previous;
+    }
+
+    public boolean hasPreviousEvent() {
+        return previous!=null;
     }
 }
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/events/EventType.java
similarity index 81%
copy from archiva-modules/archiva-base/archiva-repository-api/src/main/java/org/apache/archiva/repository/RepositoryEventListener.java
copy to archiva-modules/archiva-base/archiva-repository-api/src/main/java/org/apache/archiva/repository/events/EventType.java
index 0234f34..5004a15 100644
--- 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/events/EventType.java
@@ -1,4 +1,4 @@
-package org.apache.archiva.repository;
+package org.apache.archiva.repository.events;
 
 /*
  * Licensed to the Apache Software Foundation (ASF) under one
@@ -19,10 +19,7 @@ package org.apache.archiva.repository;
  * under the License.
  */
 
-/**
- * Listener that accepts repository events.
- */
-public interface RepositoryEventListener {
+public interface EventType {
 
-    <T> void raise(RepositoryEvent<T> event);
+    String name();
 }
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/events/LifecycleEvent.java
similarity index 67%
copy from archiva-modules/archiva-base/archiva-repository-api/src/main/java/org/apache/archiva/repository/RepositoryEventHandler.java
copy to archiva-modules/archiva-base/archiva-repository-api/src/main/java/org/apache/archiva/repository/events/LifecycleEvent.java
index 7432627..5f69d1e 100644
--- 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/events/LifecycleEvent.java
@@ -1,4 +1,4 @@
-package org.apache.archiva.repository;
+package org.apache.archiva.repository.events;
 
 /*
  * Licensed to the Apache Software Foundation (ASF) under one
@@ -19,14 +19,15 @@ package org.apache.archiva.repository;
  * under the License.
  */
 
-/**
- * Implementations of this interface are able to handle repository event listeners
- */
-public interface RepositoryEventHandler {
+import org.apache.archiva.repository.Repository;
 
-    void addListener(RepositoryEventListener listener);
+public class LifecycleEvent<O> extends RepositoryEvent<O> {
 
-    void removeListener(RepositoryEventListener listener);
+    public enum LifecycleEventType implements EventType {
+        REGISTERED,UNREGISTERED,UPDATED
+    }
 
-    void clearListeners();
+    public LifecycleEvent(LifecycleEventType type, O origin, Repository repository) {
+        super(type, origin, repository);
+    }
 }
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/events/RepositoryEvent.java
similarity index 66%
copy from archiva-modules/archiva-base/archiva-repository-api/src/main/java/org/apache/archiva/repository/RepositoryEventHandler.java
copy to archiva-modules/archiva-base/archiva-repository-api/src/main/java/org/apache/archiva/repository/events/RepositoryEvent.java
index 7432627..dd5550b 100644
--- 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/events/RepositoryEvent.java
@@ -1,4 +1,4 @@
-package org.apache.archiva.repository;
+package org.apache.archiva.repository.events;
 
 /*
  * Licensed to the Apache Software Foundation (ASF) under one
@@ -19,14 +19,18 @@ package org.apache.archiva.repository;
  * under the License.
  */
 
-/**
- * Implementations of this interface are able to handle repository event listeners
- */
-public interface RepositoryEventHandler {
+import org.apache.archiva.repository.Repository;
+
+public class RepositoryEvent<O> extends Event<O> {
 
-    void addListener(RepositoryEventListener listener);
+    private final Repository repository;
 
-    void removeListener(RepositoryEventListener listener);
+    public RepositoryEvent(EventType type, O origin, Repository repository) {
+        super(type, origin);
+        this.repository = repository;
+    }
 
-    void clearListeners();
+    public Repository getRepository() {
+        return repository;
+    }
 }
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/events/RepositoryEventHandler.java
similarity index 64%
copy from archiva-modules/archiva-base/archiva-repository-api/src/main/java/org/apache/archiva/repository/RepositoryEventHandler.java
copy to archiva-modules/archiva-base/archiva-repository-api/src/main/java/org/apache/archiva/repository/events/RepositoryEventHandler.java
index 7432627..123ffb2 100644
--- 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/events/RepositoryEventHandler.java
@@ -1,4 +1,4 @@
-package org.apache.archiva.repository;
+package org.apache.archiva.repository.events;
 
 /*
  * Licensed to the Apache Software Foundation (ASF) under one
@@ -19,14 +19,22 @@ package org.apache.archiva.repository;
  * under the License.
  */
 
+import java.util.Set;
+
 /**
- * Implementations of this interface are able to handle repository event listeners
+ * A repository event handler raises events to its registered listeners.
+ * Listeners may register for all events that are raised or only to a subset of events.
+ *
  */
 public interface RepositoryEventHandler {
 
-    void addListener(RepositoryEventListener listener);
+    void register(RepositoryEventListener listener);
+
+    void register(RepositoryEventListener listener, EventType type);
+
+    void register(RepositoryEventListener listener, Set<? extends EventType> types);
 
-    void removeListener(RepositoryEventListener listener);
+    void unregister(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/events/RepositoryEventListener.java
similarity index 86%
rename from archiva-modules/archiva-base/archiva-repository-api/src/main/java/org/apache/archiva/repository/RepositoryEventListener.java
rename to archiva-modules/archiva-base/archiva-repository-api/src/main/java/org/apache/archiva/repository/events/RepositoryEventListener.java
index 0234f34..1f0b203 100644
--- 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/events/RepositoryEventListener.java
@@ -1,4 +1,4 @@
-package org.apache.archiva.repository;
+package org.apache.archiva.repository.events;
 
 /*
  * Licensed to the Apache Software Foundation (ASF) under one
@@ -19,10 +19,12 @@ package org.apache.archiva.repository;
  * under the License.
  */
 
+import org.apache.archiva.repository.events.RepositoryValueEvent;
+
 /**
  * Listener that accepts repository events.
  */
 public interface RepositoryEventListener {
 
-    <T> void raise(RepositoryEvent<T> event);
+    void raise(Event event);
 }
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/events/RepositoryRegistryEvent.java
similarity index 72%
rename from archiva-modules/archiva-base/archiva-repository-api/src/main/java/org/apache/archiva/repository/RepositoryEventHandler.java
rename to archiva-modules/archiva-base/archiva-repository-api/src/main/java/org/apache/archiva/repository/events/RepositoryRegistryEvent.java
index 7432627..d9b891c 100644
--- 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/events/RepositoryRegistryEvent.java
@@ -1,4 +1,4 @@
-package org.apache.archiva.repository;
+package org.apache.archiva.repository.events;
 
 /*
  * Licensed to the Apache Software Foundation (ASF) under one
@@ -19,14 +19,13 @@ package org.apache.archiva.repository;
  * under the License.
  */
 
-/**
- * Implementations of this interface are able to handle repository event listeners
- */
-public interface RepositoryEventHandler {
-
-    void addListener(RepositoryEventListener listener);
+public class RepositoryRegistryEvent<O> extends Event {
 
-    void removeListener(RepositoryEventListener listener);
+    public enum RegistryEventType implements EventType {
+        RELOADED,DESTROYED
+    }
 
-    void clearListeners();
+    public RepositoryRegistryEvent(RegistryEventType type, O origin) {
+        super(type, origin);
+    }
 }
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/events/RepositoryValueEvent.java
similarity index 58%
rename from archiva-modules/archiva-base/archiva-repository-api/src/main/java/org/apache/archiva/repository/RepositoryEvent.java
rename to archiva-modules/archiva-base/archiva-repository-api/src/main/java/org/apache/archiva/repository/events/RepositoryValueEvent.java
index 8a9db88..6081717 100644
--- 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/events/RepositoryValueEvent.java
@@ -1,4 +1,4 @@
-package org.apache.archiva.repository;
+package org.apache.archiva.repository.events;
 
 /*
  * Licensed to the Apache Software Foundation (ASF) under one
@@ -19,51 +19,30 @@ package org.apache.archiva.repository;
  * under the License.
  */
 
-import java.time.LocalDateTime;
+import org.apache.archiva.repository.Repository;
 
 /**
  * Repository event. Repository events are used for providing information about repository changes.
  *
- * @param <T>
+ * @param <V>
  */
-public class RepositoryEvent<T> {
+public class RepositoryValueEvent<O, V> extends RepositoryEvent<O> {
 
-    final EventType type;
-    final Repository repo;
-    final T value;
-    final T oldValue;
-    final LocalDateTime instant;
+    final V value;
+    final V oldValue;
 
-    public RepositoryEvent(EventType type, Repository repo, T oldValue, T value) {
-        this.type = type;
-        this.repo = repo;
+    public RepositoryValueEvent(EventType type, O origin, Repository repo, V oldValue, V value) {
+        super(type, origin, repo);
         this.value = value;
         this.oldValue = oldValue;
-        this.instant = LocalDateTime.now();
     }
 
-    public interface EventType {
-        String name();
-    }
-
-
-    public EventType getType() {
-        return type;
-    };
-
-    public Repository getRepository() {
-        return repo;
-    };
-
-    public T getValue() {
+    public V getValue() {
         return value;
     }
 
-    public T getOldValue() {
+    public V 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/features/AbstractFeature.java b/archiva-modules/archiva-base/archiva-repository-api/src/main/java/org/apache/archiva/repository/features/AbstractFeature.java
index 08d0bba..6b64d93 100644
--- a/archiva-modules/archiva-base/archiva-repository-api/src/main/java/org/apache/archiva/repository/features/AbstractFeature.java
+++ b/archiva-modules/archiva-base/archiva-repository-api/src/main/java/org/apache/archiva/repository/features/AbstractFeature.java
@@ -19,8 +19,8 @@ package org.apache.archiva.repository.features;
  * under the License.
  */
 
-import org.apache.archiva.repository.RepositoryEvent;
-import org.apache.archiva.repository.RepositoryEventListener;
+import org.apache.archiva.repository.events.Event;
+import org.apache.archiva.repository.events.RepositoryEventListener;
 
 import java.util.ArrayList;
 import java.util.Collection;
@@ -56,7 +56,7 @@ public class AbstractFeature {
         this.listener.clear();
     }
 
-    protected <T> void raiseEvent(RepositoryEvent<T> event) {
+    public void pushEvent(Event event) {
         for(RepositoryEventListener listr : listener) {
             listr.raise(event);
         }
diff --git a/archiva-modules/archiva-base/archiva-repository-api/src/main/java/org/apache/archiva/repository/features/IndexCreationEvent.java b/archiva-modules/archiva-base/archiva-repository-api/src/main/java/org/apache/archiva/repository/features/IndexCreationEvent.java
index 49a3d44..037ba47 100644
--- a/archiva-modules/archiva-base/archiva-repository-api/src/main/java/org/apache/archiva/repository/features/IndexCreationEvent.java
+++ b/archiva-modules/archiva-base/archiva-repository-api/src/main/java/org/apache/archiva/repository/features/IndexCreationEvent.java
@@ -20,29 +20,30 @@ package org.apache.archiva.repository.features;
  */
 
 import org.apache.archiva.repository.Repository;
-import org.apache.archiva.repository.RepositoryEvent;
+import org.apache.archiva.repository.events.EventType;
+import org.apache.archiva.repository.events.RepositoryValueEvent;
 
 import java.net.URI;
 
-public class IndexCreationEvent extends RepositoryEvent<URI> {
+public class IndexCreationEvent<O> extends RepositoryValueEvent<O, URI> {
 
     public enum Index implements EventType {
         INDEX_URI_CHANGE, PACKED_INDEX_URI_CHANGE
     }
 
-    IndexCreationEvent(Repository repo, URI oldValue, URI value) {
-        super(Index.INDEX_URI_CHANGE, repo, oldValue, value);
+    IndexCreationEvent(Repository repo, O origin, URI oldValue, URI value) {
+        super(Index.INDEX_URI_CHANGE, origin, repo, oldValue, value);
     }
 
-    IndexCreationEvent(Index type, Repository repo, URI oldValue, URI value) {
-        super(type, repo, oldValue, value);
+    IndexCreationEvent(Index type, O origin, Repository repo, URI oldValue, URI value) {
+        super(type, origin, repo, oldValue, value);
     }
 
-    public static final IndexCreationEvent indexUriChange(Repository repo, URI oldValue, URI newValue) {
-        return new IndexCreationEvent(Index.INDEX_URI_CHANGE, repo, oldValue, newValue);
+    public static final <O> IndexCreationEvent indexUriChange(O origin, Repository repo, URI oldValue, URI newValue) {
+        return new IndexCreationEvent(Index.INDEX_URI_CHANGE, origin, repo, oldValue, newValue);
     }
 
-    public static final IndexCreationEvent packedIndexUriChange(Repository repo, URI oldValue, URI newValue) {
-        return new IndexCreationEvent(Index.PACKED_INDEX_URI_CHANGE, repo, oldValue, newValue);
+    public static final <O> IndexCreationEvent packedIndexUriChange(O origin, Repository repo, URI oldValue, URI newValue) {
+        return new IndexCreationEvent(Index.PACKED_INDEX_URI_CHANGE, origin, repo, oldValue, newValue);
     }
 }
diff --git a/archiva-modules/archiva-base/archiva-repository-api/src/main/java/org/apache/archiva/repository/features/IndexCreationFeature.java b/archiva-modules/archiva-base/archiva-repository-api/src/main/java/org/apache/archiva/repository/features/IndexCreationFeature.java
index 94812fc..cf7432c 100644
--- a/archiva-modules/archiva-base/archiva-repository-api/src/main/java/org/apache/archiva/repository/features/IndexCreationFeature.java
+++ b/archiva-modules/archiva-base/archiva-repository-api/src/main/java/org/apache/archiva/repository/features/IndexCreationFeature.java
@@ -21,7 +21,7 @@ package org.apache.archiva.repository.features;
 
 
 import org.apache.archiva.repository.Repository;
-import org.apache.archiva.repository.RepositoryEventListener;
+import org.apache.archiva.repository.events.RepositoryEventListener;
 import org.apache.archiva.repository.storage.StorageAsset;
 import org.apache.commons.lang3.StringUtils;
 
@@ -113,7 +113,7 @@ public class IndexCreationFeature extends AbstractFeature implements RepositoryF
     {
         URI oldVal = this.indexPath;
         this.indexPath = indexPath;
-        raiseEvent(IndexCreationEvent.indexUriChange(repo, oldVal, this.indexPath));
+        pushEvent(IndexCreationEvent.indexUriChange(this, repo, oldVal, this.indexPath));
 
     }
 
@@ -157,7 +157,7 @@ public class IndexCreationFeature extends AbstractFeature implements RepositoryF
     public void setPackedIndexPath(URI packedIndexPath) {
         URI oldVal = this.packedIndexPath;
         this.packedIndexPath = packedIndexPath;
-        raiseEvent(IndexCreationEvent.packedIndexUriChange(repo, oldVal, this.packedIndexPath));
+        pushEvent(IndexCreationEvent.packedIndexUriChange(this, repo, oldVal, this.packedIndexPath));
     }
 
     /**
diff --git a/archiva-modules/archiva-base/archiva-repository-api/src/main/java/org/apache/archiva/repository/features/RemoteIndexFeature.java b/archiva-modules/archiva-base/archiva-repository-api/src/main/java/org/apache/archiva/repository/features/RemoteIndexFeature.java
index 3e15487..245b8b0 100644
--- a/archiva-modules/archiva-base/archiva-repository-api/src/main/java/org/apache/archiva/repository/features/RemoteIndexFeature.java
+++ b/archiva-modules/archiva-base/archiva-repository-api/src/main/java/org/apache/archiva/repository/features/RemoteIndexFeature.java
@@ -23,6 +23,7 @@ package org.apache.archiva.repository.features;
 import org.apache.commons.lang3.StringUtils;
 
 import java.net.URI;
+import java.net.URISyntaxException;
 import java.time.Duration;
 
 /**
@@ -32,6 +33,15 @@ public class RemoteIndexFeature implements RepositoryFeature<RemoteIndexFeature>
 
     private boolean downloadRemoteIndex = false;
     private URI indexUri;
+
+    {
+        try {
+            indexUri = new URI(".index");
+        } catch (URISyntaxException e) {
+            // Ignore
+        }
+    }
+
     private boolean downloadRemoteIndexOnStartup = false;
     private Duration downloadTimeout = Duration.ofSeconds( 600 );
     private String proxyId = "";
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 99c3dd0..d8c9e3b 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
@@ -24,6 +24,7 @@ import com.cronutils.model.definition.CronDefinition;
 import com.cronutils.model.definition.CronDefinitionBuilder;
 import com.cronutils.parser.CronParser;
 import org.apache.archiva.indexer.ArchivaIndexingContext;
+import org.apache.archiva.repository.events.*;
 import org.apache.archiva.repository.storage.RepositoryStorage;
 import org.apache.archiva.repository.storage.StorageAsset;
 import org.apache.archiva.repository.features.RepositoryFeature;
@@ -39,7 +40,6 @@ import java.net.URI;
 import java.nio.channels.ReadableByteChannel;
 import java.nio.channels.WritableByteChannel;
 import java.nio.file.CopyOption;
-import java.nio.file.Path;
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.HashMap;
@@ -76,6 +76,7 @@ public abstract class AbstractRepository implements EditableRepository, Reposito
     private String layout = "default";
     public static final CronDefinition CRON_DEFINITION = CronDefinitionBuilder.instanceDefinitionFor(CronType.QUARTZ);
     private List<RepositoryEventListener> listeners = new ArrayList<>();
+    private Map<EventType, List<RepositoryEventListener>> listenerTypeMap = new HashMap<>();
 
 
     Map<Class<? extends RepositoryFeature<?>>, RepositoryFeature<?>> featureMap = new HashMap<>(  );
@@ -315,24 +316,65 @@ public abstract class AbstractRepository implements EditableRepository, Reposito
     }
 
     @Override
-    public <T> void raise(RepositoryEvent<T> event) {
-        for(RepositoryEventListener listener : listeners) {
-            listener.raise(event);
+    public void raise(Event event) {
+        callListeners(event, listeners);
+        if (listenerTypeMap.containsKey(event.getType())) {
+            callListeners(event, listenerTypeMap.get(event.getType()));
         }
     }
 
-    public void addListener(RepositoryEventListener listener) {
+    private void callListeners(Event event, List<RepositoryEventListener> evtListeners) {
+        for(RepositoryEventListener listener : evtListeners) {
+            try {
+                listener.raise(event);
+            } catch (Throwable e) {
+                log.error("Could not raise event {} on listener {}: {}", event, listener, e.getMessage());
+            }
+        }
+
+    }
+
+    @Override
+    public void register(RepositoryEventListener listener) {
         if (!this.listeners.contains(listener)) {
             this.listeners.add(listener);
         }
     }
 
-    public void removeListener(RepositoryEventListener listener) {
-        this.removeListener(listener);
+    @Override
+    public void register(RepositoryEventListener listener, EventType type) {
+        List<RepositoryEventListener> listeners;
+        if (listenerTypeMap.containsKey(type)) {
+            listeners = listenerTypeMap.get(type);
+        } else {
+            listeners = new ArrayList<>();
+            listenerTypeMap.put(type, listeners);
+        }
+        if (!listeners.contains(listener)) {
+            listeners.add(listener);
+        }
+
+    }
+
+    @Override
+    public void register(RepositoryEventListener listener, Set<? extends EventType> types) {
+        for (EventType type : types) {
+            register(listener, type);
+        }
+    }
+
+    @Override
+    public void unregister(RepositoryEventListener listener) {
+        listeners.remove(listener);
+        for (List<RepositoryEventListener> listeners : listenerTypeMap.values()) {
+            listeners.remove(listener);
+        }
     }
 
+    @Override
     public void clearListeners() {
         this.listeners.clear();
+        this.listenerTypeMap.clear();
     }
 
     @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 316b1cf..a58f960 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
@@ -20,12 +20,9 @@ package org.apache.archiva.repository;
  */
 
 import org.apache.archiva.configuration.*;
-import org.apache.archiva.indexer.ArchivaIndexManager;
-import org.apache.archiva.indexer.ArchivaIndexingContext;
-import org.apache.archiva.indexer.IndexCreationFailedException;
-import org.apache.archiva.indexer.IndexManagerFactory;
-import org.apache.archiva.indexer.IndexUpdateFailedException;
+import org.apache.archiva.indexer.*;
 import org.apache.archiva.redback.components.registry.RegistryException;
+import org.apache.archiva.repository.events.*;
 import org.apache.archiva.repository.features.IndexCreationEvent;
 import org.apache.archiva.repository.features.IndexCreationFeature;
 import org.apache.archiva.repository.features.StagingRepositoryFeature;
@@ -38,13 +35,7 @@ import javax.annotation.PostConstruct;
 import javax.annotation.PreDestroy;
 import javax.inject.Inject;
 import javax.inject.Named;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.LinkedHashMap;
-import java.util.List;
-import java.util.Map;
+import java.util.*;
 import java.util.concurrent.locks.ReentrantReadWriteLock;
 import java.util.stream.Collectors;
 import java.util.stream.Stream;
@@ -54,16 +45,16 @@ import static org.apache.archiva.indexer.ArchivaIndexManager.DEFAULT_INDEX_PATH;
 /**
  * Registry for repositories. This is the central entry point for repositories. It provides methods for
  * retrieving, adding and removing repositories.
- *
+ * <p>
  * The modification methods addXX and removeXX persist the changes immediately to the configuration. If the
  * configuration save fails the changes are rolled back.
- *
+ * <p>
  * TODO: Audit events
  */
-@Service( "repositoryRegistry" )
+@Service("repositoryRegistry")
 public class RepositoryRegistry implements ConfigurationListener, RepositoryEventHandler, RepositoryEventListener {
 
-    private static final Logger log = LoggerFactory.getLogger( RepositoryRegistry.class );
+    private static final Logger log = LoggerFactory.getLogger(RepositoryRegistry.class);
 
     /**
      * We inject all repository providers
@@ -82,164 +73,157 @@ public class RepositoryRegistry implements ConfigurationListener, RepositoryEven
     RepositoryContentFactory repositoryContentFactory;
 
     private List<RepositoryEventListener> listeners = new ArrayList<>();
+    private Map<EventType, List<RepositoryEventListener>> typeListenerMap = new HashMap<>();
 
 
-    private Map<String, ManagedRepository> managedRepositories = new HashMap<>( );
-    private Map<String, ManagedRepository> uManagedRepository = Collections.unmodifiableMap( managedRepositories );
+    private Map<String, ManagedRepository> managedRepositories = new HashMap<>();
+    private Map<String, ManagedRepository> uManagedRepository = Collections.unmodifiableMap(managedRepositories);
 
-    private Map<String, RemoteRepository> remoteRepositories = new HashMap<>( );
-    private Map<String, RemoteRepository> uRemoteRepositories = Collections.unmodifiableMap( remoteRepositories );
+    private Map<String, RemoteRepository> remoteRepositories = new HashMap<>();
+    private Map<String, RemoteRepository> uRemoteRepositories = Collections.unmodifiableMap(remoteRepositories);
 
     private Map<String, RepositoryGroup> repositoryGroups = new HashMap<>();
     private Map<String, RepositoryGroup> uRepositoryGroups = Collections.unmodifiableMap(repositoryGroups);
 
-    private ReentrantReadWriteLock rwLock = new ReentrantReadWriteLock( );
+    private ReentrantReadWriteLock rwLock = new ReentrantReadWriteLock();
+
+    private volatile boolean ignoreConfigEvents = false;
 
-    public void setArchivaConfiguration( ArchivaConfiguration archivaConfiguration) {
+    public void setArchivaConfiguration(ArchivaConfiguration archivaConfiguration) {
         this.archivaConfiguration = archivaConfiguration;
     }
 
     @PostConstruct
-    private void initialize( )
-    {
-        rwLock.writeLock( ).lock( );
-        try
-        {
+    private void initialize() {
+        rwLock.writeLock().lock();
+        try {
             log.debug("Initializing repository registry");
-            for(ManagedRepository rep : managedRepositories.values()) {
+            for (ManagedRepository rep : managedRepositories.values()) {
                 rep.close();
             }
-            managedRepositories.clear( );
-            managedRepositories.putAll( getManagedRepositoriesFromConfig( ) );
+            managedRepositories.clear();
+            updateManagedRepositoriesFromConfig();
             for (RemoteRepository repo : remoteRepositories.values()) {
                 repo.close();
             }
-            remoteRepositories.clear( );
-            remoteRepositories.putAll( getRemoteRepositoriesFromConfig( ) );
+            remoteRepositories.clear();
+            updateRemoteRepositoriesFromConfig();
 
             repositoryGroups.clear();
-            repositoryGroups.putAll(getRepositorGroupsFromConfig());
+            Map<String, RepositoryGroup> repositoryGroups = getRepositorGroupsFromConfig();
+            this.repositoryGroups.putAll(repositoryGroups);
 
             // archivaConfiguration.addChangeListener(this);
             archivaConfiguration.addListener(this);
+        } finally {
+            rwLock.writeLock().unlock();
         }
-        finally
-        {
-            rwLock.writeLock( ).unlock( );
-        }
+        pushEvent(new RepositoryRegistryEvent(RepositoryRegistryEvent.RegistryEventType.RELOADED, this));
     }
 
     @PreDestroy
     public void destroy() {
-        for(ManagedRepository rep : managedRepositories.values()) {
+        for (ManagedRepository rep : managedRepositories.values()) {
             rep.close();
         }
+        managedRepositories.clear();
         for (RemoteRepository repo : remoteRepositories.values()) {
             repo.close();
         }
+        remoteRepositories.clear();
+        pushEvent(new RepositoryRegistryEvent(RepositoryRegistryEvent.RegistryEventType.DESTROYED, this));
     }
 
 
-
-    private Map<RepositoryType, RepositoryProvider> createProviderMap( )
-    {
-        Map<RepositoryType, RepositoryProvider> map = new HashMap<>( );
-        if ( repositoryProviders != null )
-        {
-            for ( RepositoryProvider provider : repositoryProviders )
-            {
-                for ( RepositoryType type : provider.provides( ) )
-                {
-                    map.put( type, provider );
+    private Map<RepositoryType, RepositoryProvider> createProviderMap() {
+        Map<RepositoryType, RepositoryProvider> map = new HashMap<>();
+        if (repositoryProviders != null) {
+            for (RepositoryProvider provider : repositoryProviders) {
+                for (RepositoryType type : provider.provides()) {
+                    map.put(type, provider);
                 }
             }
         }
         return map;
     }
 
-    private RepositoryProvider getProvider( RepositoryType type ) throws RepositoryException
-    {
-        return repositoryProviders.stream( ).filter( repositoryProvider -> repositoryProvider.provides( ).contains( type ) ).findFirst( ).orElseThrow( ( ) -> new RepositoryException( "Repository type cannot be handled: " + type ) );
+    private RepositoryProvider getProvider(RepositoryType type) throws RepositoryException {
+        return repositoryProviders.stream().filter(repositoryProvider -> repositoryProvider.provides().contains(type)).findFirst().orElseThrow(() -> new RepositoryException("Repository type cannot be handled: " + type));
     }
 
-    private Map<String, ManagedRepository> getManagedRepositoriesFromConfig( )
-    {
-        try
-        {
+    private void updateManagedRepositoriesFromConfig() {
+        try {
             List<ManagedRepositoryConfiguration> managedRepoConfigs =
-                getArchivaConfiguration( ).getConfiguration( ).getManagedRepositories( );
+                    getArchivaConfiguration().getConfiguration().getManagedRepositories();
 
-            if ( managedRepoConfigs == null )
-            {
-                return Collections.emptyMap();
+            if (managedRepoConfigs == null) {
+                return;
             }
 
-            Map<String, ManagedRepository> managedRepos = new LinkedHashMap<>( managedRepoConfigs.size( ) );
-
-            Map<RepositoryType, RepositoryProvider> providerMap = createProviderMap( );
-            for ( ManagedRepositoryConfiguration repoConfig : managedRepoConfigs )
-            {
-                if (managedRepos.containsKey(repoConfig.getId())) {
-                    log.warn( "Duplicate repository definitions for {} in config found.", repoConfig.getId( ) );
+            Map<RepositoryType, RepositoryProvider> providerMap = createProviderMap();
+            for (ManagedRepositoryConfiguration repoConfig : managedRepoConfigs) {
+                if (managedRepositories.containsKey(repoConfig.getId())) {
+                    log.warn("Duplicate repository definitions for {} in config found.", repoConfig.getId());
                     continue;
                 }
-                RepositoryType repositoryType = RepositoryType.valueOf( repoConfig.getType( ) );
-                if ( providerMap.containsKey( repositoryType ) )
-                {
-                    try
-                    {
-                        ManagedRepository repo = createNewManagedRepository( providerMap.get( repositoryType ), repoConfig );
-                        managedRepos.put( repo.getId( ), repo );
-                    }
-                    catch ( Exception e )
-                    {
-                        log.error( "Could not create managed repository {}: {}", repoConfig.getId( ), e.getMessage( ), e );
+                RepositoryType repositoryType = RepositoryType.valueOf(repoConfig.getType());
+                if (providerMap.containsKey(repositoryType)) {
+                    try {
+                        ManagedRepository repo = createNewManagedRepository(providerMap.get(repositoryType), repoConfig);
+                        managedRepositories.put(repo.getId(), repo);
+                        pushEvent(new LifecycleEvent(LifecycleEvent.LifecycleEventType.REGISTERED, this, repo));
+                    } catch (Exception e) {
+                        log.error("Could not create managed repository {}: {}", repoConfig.getId(), e.getMessage(), e);
                     }
                 }
             }
-            return managedRepos;
+            return;
         } catch (Throwable e) {
-            log.error("Could not initialize repositories from config: {}",e.getMessage(), e );
+            log.error("Could not initialize repositories from config: {}", e.getMessage(), e);
             //noinspection unchecked
-            return Collections.emptyMap();
+            return;
         }
     }
 
-    private ManagedRepository createNewManagedRepository( RepositoryProvider provider, ManagedRepositoryConfiguration cfg ) throws RepositoryException
-    {
+    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);
+        ManagedRepository repo = provider.createManagedInstance(cfg);
+        repo.register(this);
+        updateRepositoryReferences(provider, repo, cfg, null);
         return repo;
 
     }
 
-    @SuppressWarnings( "unchecked" )
-    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( );
-            if ( feature.isStageRepoNeeded( ) && feature.getStagingRepository() == null)
-            {
-                ManagedRepository stageRepo = getStagingRepository( provider, cfg, configuration);
-                managedRepositories.put(stageRepo.getId(), stageRepo);
-                feature.setStagingRepository( stageRepo );
-                if (configuration!=null) {
-                    replaceOrAddRepositoryConfig( provider.getManagedConfiguration( stageRepo ), configuration );
+    private String getStagingId(String repoId) {
+        return repoId + StagingRepositoryFeature.STAGING_REPO_POSTFIX;
+    }
+
+    @SuppressWarnings("unchecked")
+    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();
+            if (feature.isStageRepoNeeded() && feature.getStagingRepository() == null) {
+                ManagedRepository stageRepo = getManagedRepository(getStagingId(repo.getId()));
+                if (stageRepo==null) {
+                    stageRepo = getStagingRepository(provider, cfg, configuration);
+                    managedRepositories.put(stageRepo.getId(), stageRepo);
+                    if (configuration != null) {
+                        replaceOrAddRepositoryConfig(provider.getManagedConfiguration(stageRepo), configuration);
+                    }
                 }
+                feature.setStagingRepository(stageRepo);
+                pushEvent(new LifecycleEvent(LifecycleEvent.LifecycleEventType.REGISTERED, this, stageRepo));
             }
         }
-        if ( repo instanceof EditableManagedRepository)
-        {
+        if (repo instanceof EditableManagedRepository) {
             EditableManagedRepository editableRepo = (EditableManagedRepository) repo;
-            if (repo.getContent()==null) {
+            if (repo.getContent() == null) {
                 editableRepo.setContent(repositoryContentFactory.getManagedRepositoryContent(repo));
+                editableRepo.getContent().setRepository(editableRepo);
             }
-            log.debug("Index repo: "+repo.hasIndex());
-            if (repo.hasIndex() && repo.getIndexingContext()==null) {
+            log.debug("Index repo: " + repo.hasIndex());
+            if (repo.hasIndex() && repo.getIndexingContext() == null) {
                 log.debug("Creating indexing context for {}", repo.getId());
                 createIndexingContext(editableRepo);
             }
@@ -258,129 +242,105 @@ public class RepositoryRegistry implements ConfigurationListener, RepositoryEven
                 editableRepo.setIndexingContext(idxManager.createContext(editableRepo));
                 idxManager.updateLocalIndexPath(editableRepo);
             } catch (IndexCreationFailedException e) {
-                throw new RepositoryException("Could not create index for repository "+editableRepo.getId()+": "+e.getMessage(),e);
+                throw new RepositoryException("Could not create index for repository " + editableRepo.getId() + ": " + e.getMessage(), e);
             }
         }
     }
 
-    private ManagedRepository getStagingRepository(RepositoryProvider provider, ManagedRepositoryConfiguration baseRepoCfg, Configuration configuration) throws RepositoryException
-    {
-        ManagedRepository stageRepo = getManagedRepository( baseRepoCfg.getId( ) + StagingRepositoryFeature.STAGING_REPO_POSTFIX );
-        if ( stageRepo == null )
-        {
-            stageRepo = provider.createStagingInstance( baseRepoCfg );
+    private ManagedRepository getStagingRepository(RepositoryProvider provider, ManagedRepositoryConfiguration baseRepoCfg, Configuration configuration) throws RepositoryException {
+        ManagedRepository stageRepo = getManagedRepository(getStagingId(baseRepoCfg.getId()));
+        if (stageRepo == null) {
+            stageRepo = provider.createStagingInstance(baseRepoCfg);
             if (stageRepo.supportsFeature(StagingRepositoryFeature.class)) {
                 stageRepo.getFeature(StagingRepositoryFeature.class).get().setStageRepoNeeded(false);
             }
-            ManagedRepositoryConfiguration stageCfg = provider.getManagedConfiguration( stageRepo );
-            updateRepositoryReferences( provider, stageRepo, stageCfg, configuration);
+            ManagedRepositoryConfiguration stageCfg = provider.getManagedConfiguration(stageRepo);
+            updateRepositoryReferences(provider, stageRepo, stageCfg, configuration);
         }
         return stageRepo;
     }
 
 
-
-
-    private Map<String, RemoteRepository> getRemoteRepositoriesFromConfig( )
-    {
-        try
-        {
+    private void updateRemoteRepositoriesFromConfig() {
+        try {
             List<RemoteRepositoryConfiguration> remoteRepoConfigs =
-                getArchivaConfiguration( ).getConfiguration( ).getRemoteRepositories( );
+                    getArchivaConfiguration().getConfiguration().getRemoteRepositories();
 
-            if ( remoteRepoConfigs == null )
-            {
+            if (remoteRepoConfigs == null) {
                 //noinspection unchecked
-                return Collections.emptyMap();
+                return;
             }
 
-            Map<String, RemoteRepository> remoteRepos = new LinkedHashMap<>( remoteRepoConfigs.size( ) );
-
-            Map<RepositoryType, RepositoryProvider> providerMap = createProviderMap( );
-            for ( RemoteRepositoryConfiguration repoConfig : remoteRepoConfigs )
-            {
-                RepositoryType repositoryType = RepositoryType.valueOf( repoConfig.getType( ) );
-                if ( providerMap.containsKey( repositoryType ) )
-                {
-                    RepositoryProvider provider = getProvider( repositoryType );
-                    try
-                    {
+            Map<RepositoryType, RepositoryProvider> providerMap = createProviderMap();
+            for (RemoteRepositoryConfiguration repoConfig : remoteRepoConfigs) {
+                RepositoryType repositoryType = RepositoryType.valueOf(repoConfig.getType());
+                if (providerMap.containsKey(repositoryType)) {
+                    RepositoryProvider provider = getProvider(repositoryType);
+                    try {
 
-                        RemoteRepository remoteRepository = createNewRemoteRepository( provider, repoConfig );
-                        remoteRepos.put( repoConfig.getId( ), remoteRepository);
-                    }
-                    catch ( Exception e )
-                    {
-                        log.error( "Could not create repository {} from config: {}", repoConfig.getId( ), e.getMessage( ), e );
+                        RemoteRepository remoteRepository = createNewRemoteRepository(provider, repoConfig);
+                        remoteRepositories.put(repoConfig.getId(), remoteRepository);
+                        pushEvent(new LifecycleEvent(LifecycleEvent.LifecycleEventType.REGISTERED, this, remoteRepository));
+                    } catch (Exception e) {
+                        log.error("Could not create repository {} from config: {}", repoConfig.getId(), e.getMessage(), e);
                     }
                 }
             }
 
-            return remoteRepos;
+            return;
         } catch (Throwable e) {
             log.error("Could not initialize remote repositories from config: {}", e.getMessage(), e);
             //noinspection unchecked
-            return Collections.emptyMap();
+            return;
         }
     }
 
-    private RemoteRepository createNewRemoteRepository( RepositoryProvider provider, RemoteRepositoryConfiguration cfg ) throws RepositoryException
-    {
+    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);
+        RemoteRepository repo = provider.createRemoteInstance(cfg);
+        repo.register(this);
+        updateRepositoryReferences(provider, repo, cfg, null);
         return repo;
 
     }
 
-    @SuppressWarnings( "unchecked" )
-    private void updateRepositoryReferences( RepositoryProvider provider, RemoteRepository repo, RemoteRepositoryConfiguration cfg, Configuration configuration) throws RepositoryException
-    {
-        if ( repo instanceof EditableRemoteRepository && repo.getContent() == null)
-        {
+    @SuppressWarnings("unchecked")
+    private void updateRepositoryReferences(RepositoryProvider provider, RemoteRepository repo, RemoteRepositoryConfiguration cfg, Configuration configuration) throws RepositoryException {
+        if (repo instanceof EditableRemoteRepository && repo.getContent() == null) {
             EditableRemoteRepository editableRepo = (EditableRemoteRepository) repo;
-            editableRepo.setContent( repositoryContentFactory.getRemoteRepositoryContent( repo ) );
-            if (repo.supportsFeature(IndexCreationFeature.class) && repo.getIndexingContext()==null ) {
+            editableRepo.setContent(repositoryContentFactory.getRemoteRepositoryContent(repo));
+            if (repo.supportsFeature(IndexCreationFeature.class) && repo.getIndexingContext() == null) {
                 createIndexingContext(editableRepo);
             }
         }
     }
 
-    private Map<String, RepositoryGroup> getRepositorGroupsFromConfig( )
-    {
-        try
-        {
+    private Map<String, RepositoryGroup> getRepositorGroupsFromConfig() {
+        try {
             List<RepositoryGroupConfiguration> repositoryGroupConfigurations =
-                    getArchivaConfiguration( ).getConfiguration( ).getRepositoryGroups();
+                    getArchivaConfiguration().getConfiguration().getRepositoryGroups();
 
-            if ( repositoryGroupConfigurations == null )
-            {
+            if (repositoryGroupConfigurations == null) {
                 return Collections.emptyMap();
             }
 
-            Map<String, RepositoryGroup> repositoryGroupMap = new LinkedHashMap<>( repositoryGroupConfigurations.size( ) );
-
-            Map<RepositoryType, RepositoryProvider> providerMap = createProviderMap( );
-            for ( RepositoryGroupConfiguration repoConfig : repositoryGroupConfigurations )
-            {
-                RepositoryType repositoryType = RepositoryType.valueOf( repoConfig.getType( ) );
-                if ( providerMap.containsKey( repositoryType ) )
-                {
-                    try
-                    {
-                        RepositoryGroup repo = createNewRepositoryGroup( providerMap.get( repositoryType ), repoConfig );
-                        repositoryGroupMap.put( repo.getId( ), repo );
-                    }
-                    catch ( Exception e )
-                    {
-                        log.error( "Could not create repository group {}: {}", repoConfig.getId( ), e.getMessage( ), e );
+            Map<String, RepositoryGroup> repositoryGroupMap = new LinkedHashMap<>(repositoryGroupConfigurations.size());
+
+            Map<RepositoryType, RepositoryProvider> providerMap = createProviderMap();
+            for (RepositoryGroupConfiguration repoConfig : repositoryGroupConfigurations) {
+                RepositoryType repositoryType = RepositoryType.valueOf(repoConfig.getType());
+                if (providerMap.containsKey(repositoryType)) {
+                    try {
+                        RepositoryGroup repo = createNewRepositoryGroup(providerMap.get(repositoryType), repoConfig);
+                        repositoryGroupMap.put(repo.getId(), repo);
+                    } catch (Exception e) {
+                        log.error("Could not create repository group {}: {}", repoConfig.getId(), e.getMessage(), e);
                     }
                 }
             }
             return repositoryGroupMap;
         } catch (Throwable e) {
-            log.error("Could not initialize repositories from config: {}",e.getMessage(), e );
+            log.error("Could not initialize repositories from config: {}", e.getMessage(), e);
             //noinspection unchecked
             return Collections.emptyMap();
         }
@@ -388,7 +348,7 @@ public class RepositoryRegistry implements ConfigurationListener, RepositoryEven
 
     RepositoryGroup createNewRepositoryGroup(RepositoryProvider provider, RepositoryGroupConfiguration config) throws RepositoryException {
         RepositoryGroup repositoryGroup = provider.createRepositoryGroup(config);
-        repositoryGroup.addListener(this);
+        repositoryGroup.register(this);
         updateRepositoryReferences(provider, repositoryGroup, config);
         return repositoryGroup;
     }
@@ -400,8 +360,7 @@ public class RepositoryRegistry implements ConfigurationListener, RepositoryEven
         }
     }
 
-    private ArchivaConfiguration getArchivaConfiguration( )
-    {
+    private ArchivaConfiguration getArchivaConfiguration() {
         return this.archivaConfiguration;
     }
 
@@ -410,16 +369,12 @@ public class RepositoryRegistry implements ConfigurationListener, RepositoryEven
      *
      * @return a list of managed and remote repositories
      */
-    public Collection<Repository> getRepositories( )
-    {
-        rwLock.readLock( ).lock( );
-        try
-        {
-            return Stream.concat( managedRepositories.values( ).stream( ), remoteRepositories.values( ).stream( )).collect( Collectors.toList( ) );
-        }
-        finally
-        {
-            rwLock.readLock( ).unlock( );
+    public Collection<Repository> getRepositories() {
+        rwLock.readLock().lock();
+        try {
+            return Stream.concat(managedRepositories.values().stream(), remoteRepositories.values().stream()).collect(Collectors.toList());
+        } finally {
+            rwLock.readLock().unlock();
         }
     }
 
@@ -428,14 +383,11 @@ public class RepositoryRegistry implements ConfigurationListener, RepositoryEven
      *
      * @return a list of managed repositories
      */
-    public Collection<ManagedRepository> getManagedRepositories( )
-    {
+    public Collection<ManagedRepository> getManagedRepositories() {
         rwLock.readLock().lock();
-        try
-        {
-            return uManagedRepository.values( );
-        } finally
-        {
+        try {
+            return uManagedRepository.values();
+        } finally {
             rwLock.readLock().unlock();
         }
     }
@@ -445,19 +397,16 @@ public class RepositoryRegistry implements ConfigurationListener, RepositoryEven
      *
      * @return a list of remote repositories
      */
-    public Collection<RemoteRepository> getRemoteRepositories( )
-    {
+    public Collection<RemoteRepository> getRemoteRepositories() {
         rwLock.readLock().lock();
-        try
-        {
-            return uRemoteRepositories.values( );
-        } finally
-        {
+        try {
+            return uRemoteRepositories.values();
+        } finally {
             rwLock.readLock().unlock();
         }
     }
 
-    public Collection<RepositoryGroup>  getRepositoryGroups() {
+    public Collection<RepositoryGroup> getRepositoryGroups() {
         rwLock.readLock().lock();
         try {
             return uRepositoryGroups.values();
@@ -473,30 +422,23 @@ public class RepositoryRegistry implements ConfigurationListener, RepositoryEven
      * @param repoId the repository id
      * @return the repository if found, otherwise null
      */
-    public Repository getRepository( String repoId )
-    {
-        rwLock.readLock( ).lock( );
-        try
-        {
+    public Repository getRepository(String repoId) {
+        rwLock.readLock().lock();
+        try {
             log.debug("getRepository {}", repoId);
-            if ( managedRepositories.containsKey( repoId ) )
-            {
+            if (managedRepositories.containsKey(repoId)) {
                 log.debug("Managed repo");
-                return managedRepositories.get( repoId );
-            }
-            else if (remoteRepositories.containsKey(repoId))
-            {
+                return managedRepositories.get(repoId);
+            } else if (remoteRepositories.containsKey(repoId)) {
                 log.debug("Remote repo");
-                return remoteRepositories.get( repoId );
+                return remoteRepositories.get(repoId);
             } else if (repositoryGroups.containsKey(repoId)) {
                 return repositoryGroups.get(repoId);
             } else {
                 return null;
             }
-        }
-        finally
-        {
-            rwLock.readLock( ).unlock( );
+        } finally {
+            rwLock.readLock().unlock();
         }
     }
 
@@ -507,16 +449,12 @@ public class RepositoryRegistry implements ConfigurationListener, RepositoryEven
      * @param repoId the repository id
      * @return the managed repository if found, otherwise null
      */
-    public ManagedRepository getManagedRepository( String repoId )
-    {
-        rwLock.readLock( ).lock( );
-        try
-        {
-            return managedRepositories.get( repoId );
-        }
-        finally
-        {
-            rwLock.readLock( ).unlock( );
+    public ManagedRepository getManagedRepository(String repoId) {
+        rwLock.readLock().lock();
+        try {
+            return managedRepositories.get(repoId);
+        } finally {
+            rwLock.readLock().unlock();
         }
     }
 
@@ -527,20 +465,16 @@ public class RepositoryRegistry implements ConfigurationListener, RepositoryEven
      * @param repoId the repository id
      * @return the remote repository if found, otherwise null
      */
-    public RemoteRepository getRemoteRepository( String repoId )
-    {
-        rwLock.readLock( ).lock( );
-        try
-        {
-            return remoteRepositories.get( repoId );
-        }
-        finally
-        {
-            rwLock.readLock( ).unlock( );
+    public RemoteRepository getRemoteRepository(String repoId) {
+        rwLock.readLock().lock();
+        try {
+            return remoteRepositories.get(repoId);
+        } finally {
+            rwLock.readLock().unlock();
         }
     }
 
-    public RepositoryGroup getRepositoryGroup( String groupId ) {
+    public RepositoryGroup getRepositoryGroup(String groupId) {
         rwLock.readLock().lock();
         try {
             return repositoryGroups.get(groupId);
@@ -549,6 +483,19 @@ public class RepositoryRegistry implements ConfigurationListener, RepositoryEven
         }
     }
 
+    /*
+     * The <code>ignoreConfigEvents</code> works only for synchronized configuration events.
+     * If the configuration throws async events, we cannot know, if the event is caused by this instance or another thread.
+     */
+    private void saveConfiguration(Configuration configuration) throws IndeterminateConfigurationException, RegistryException {
+        ignoreConfigEvents = true;
+        try {
+            getArchivaConfiguration().save(configuration);
+        } finally {
+            ignoreConfigEvents = false;
+        }
+    }
+
     /**
      * Adds a new repository to the current list, or replaces the repository definition with
      * the same id, if it exists already.
@@ -557,50 +504,43 @@ public class RepositoryRegistry implements ConfigurationListener, RepositoryEven
      * @param managedRepository the new repository.
      * @throws RepositoryException if the new repository could not be saved to the configuration.
      */
-    public ManagedRepository putRepository( ManagedRepository managedRepository ) throws RepositoryException
-    {
-        rwLock.writeLock( ).lock( );
-        try
-        {
+    public ManagedRepository putRepository(ManagedRepository managedRepository) throws RepositoryException {
+        rwLock.writeLock().lock();
+        try {
             final String id = managedRepository.getId();
-            if (remoteRepositories.containsKey( id )) {
-                throw new RepositoryException( "There exists a remote repository with id "+id+". Could not update with managed repository." );
+            if (remoteRepositories.containsKey(id)) {
+                throw new RepositoryException("There exists a remote repository with id " + id + ". Could not update with managed repository.");
             }
 
-            ManagedRepository originRepo = managedRepositories.put( id, managedRepository );
-            try
-            {
-                if (originRepo!=null) {
+            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( );
-                updateRepositoryReferences( provider, managedRepository, newCfg, configuration );
-                ManagedRepositoryConfiguration oldCfg = configuration.findManagedRepositoryById( id );
-                if (oldCfg!=null) {
-                    configuration.removeManagedRepository( oldCfg );
+                RepositoryProvider provider = getProvider(managedRepository.getType());
+                ManagedRepositoryConfiguration newCfg = provider.getManagedConfiguration(managedRepository);
+                Configuration configuration = getArchivaConfiguration().getConfiguration();
+                updateRepositoryReferences(provider, managedRepository, newCfg, configuration);
+                ManagedRepositoryConfiguration oldCfg = configuration.findManagedRepositoryById(id);
+                if (oldCfg != null) {
+                    configuration.removeManagedRepository(oldCfg);
                 }
-                configuration.addManagedRepository( newCfg );
-                getArchivaConfiguration( ).save( configuration );
+                configuration.addManagedRepository(newCfg);
+                saveConfiguration(configuration);
+                pushEvent(new LifecycleEvent(LifecycleEvent.LifecycleEventType.REGISTERED, this, managedRepository));
                 return managedRepository;
-            }
-            catch ( Exception e )
-            {
+            } catch (Exception e) {
                 // Rollback
-                if ( originRepo != null )
-                {
-                    managedRepositories.put( id, originRepo );
+                if (originRepo != null) {
+                    managedRepositories.put(id, originRepo);
                 } else {
                     managedRepositories.remove(id);
                 }
                 log.error("Exception during configuration update {}", e.getMessage(), e);
-                throw new RepositoryException( "Could not save the configuration" + (e.getMessage( )==null?"":": "+e.getMessage()) );
+                throw new RepositoryException("Could not save the configuration" + (e.getMessage() == null ? "" : ": " + e.getMessage()));
             }
-        }
-        finally
-        {
-            rwLock.writeLock( ).unlock( );
+        } finally {
+            rwLock.writeLock().unlock();
         }
     }
 
@@ -612,34 +552,27 @@ public class RepositoryRegistry implements ConfigurationListener, RepositoryEven
      * @return the updated or created repository
      * @throws RepositoryException if an error occurs, or the configuration is not valid.
      */
-    public ManagedRepository putRepository( ManagedRepositoryConfiguration managedRepositoryConfiguration) throws RepositoryException
-    {
-        rwLock.writeLock( ).lock( );
-        try
-        {
+    public ManagedRepository putRepository(ManagedRepositoryConfiguration managedRepositoryConfiguration) throws RepositoryException {
+        rwLock.writeLock().lock();
+        try {
             final String id = managedRepositoryConfiguration.getId();
-            final RepositoryType repositoryType = RepositoryType.valueOf( managedRepositoryConfiguration.getType() );
+            final RepositoryType repositoryType = RepositoryType.valueOf(managedRepositoryConfiguration.getType());
             Configuration configuration = getArchivaConfiguration().getConfiguration();
             ManagedRepository repo = managedRepositories.get(id);
-            ManagedRepositoryConfiguration oldCfg = repo!=null ? getProvider( repositoryType ).getManagedConfiguration( repo ) : null;
-            repo = putRepository( managedRepositoryConfiguration, configuration );
-            try
-            {
-                getArchivaConfiguration().save(configuration);
-            }
-            catch ( IndeterminateConfigurationException | RegistryException e )
-            {
-                if (oldCfg!=null) {
-                    getProvider( repositoryType ).updateManagedInstance( (EditableManagedRepository)repo, oldCfg );
+            ManagedRepositoryConfiguration oldCfg = repo != null ? getProvider(repositoryType).getManagedConfiguration(repo) : null;
+            repo = putRepository(managedRepositoryConfiguration, configuration);
+            try {
+                saveConfiguration(configuration);
+            } catch (IndeterminateConfigurationException | RegistryException e) {
+                if (oldCfg != null) {
+                    getProvider(repositoryType).updateManagedInstance((EditableManagedRepository) repo, oldCfg);
                 }
-                log.error("Could not save the configuration for repository {}: {}", id, e.getMessage(),e );
-                throw new RepositoryException( "Could not save the configuration for repository "+id+": "+e.getMessage() );
+                log.error("Could not save the configuration for repository {}: {}", id, e.getMessage(), e);
+                throw new RepositoryException("Could not save the configuration for repository " + id + ": " + e.getMessage());
             }
             return repo;
-        }
-        finally
-        {
-            rwLock.writeLock( ).unlock( );
+        } finally {
+            rwLock.writeLock().unlock();
         }
 
     }
@@ -649,40 +582,35 @@ public class RepositoryRegistry implements ConfigurationListener, RepositoryEven
      * the configuration is not saved.
      *
      * @param managedRepositoryConfiguration the new or changed repository configuration
-     * @param configuration the configuration object
+     * @param configuration                  the configuration object
      * @return the new or updated repository
      * @throws RepositoryException if the configuration cannot be saved or updated
      */
-    @SuppressWarnings( "unchecked" )
-    public ManagedRepository putRepository( ManagedRepositoryConfiguration managedRepositoryConfiguration, Configuration configuration) throws RepositoryException
-    {
-        rwLock.writeLock( ).lock( );
-        try
-        {
+    @SuppressWarnings("unchecked")
+    public ManagedRepository putRepository(ManagedRepositoryConfiguration managedRepositoryConfiguration, Configuration configuration) throws RepositoryException {
+        rwLock.writeLock().lock();
+        try {
             final String id = managedRepositoryConfiguration.getId();
-            final RepositoryType repoType = RepositoryType.valueOf( managedRepositoryConfiguration.getType() );
+            final RepositoryType repoType = RepositoryType.valueOf(managedRepositoryConfiguration.getType());
             ManagedRepository repo;
-            if (managedRepositories.containsKey( id )) {
+            if (managedRepositories.containsKey(id)) {
                 repo = managedRepositories.get(id);
-                if (repo instanceof EditableManagedRepository)
-                {
-                    getProvider( repoType ).updateManagedInstance( (EditableManagedRepository) repo, managedRepositoryConfiguration );
+                if (repo instanceof EditableManagedRepository) {
+                    getProvider(repoType).updateManagedInstance((EditableManagedRepository) repo, managedRepositoryConfiguration);
                 } else {
-                    throw new RepositoryException( "The repository is not editable "+id );
+                    throw new RepositoryException("The repository is not editable " + id);
                 }
-            } else
-            {
-                repo = getProvider( repoType ).createManagedInstance( managedRepositoryConfiguration );
-                repo.addListener(this);
+            } else {
+                repo = getProvider(repoType).createManagedInstance(managedRepositoryConfiguration);
+                repo.register(this);
                 managedRepositories.put(id, repo);
             }
-            updateRepositoryReferences( getProvider( repoType  ), repo, managedRepositoryConfiguration, configuration );
-            replaceOrAddRepositoryConfig( managedRepositoryConfiguration, configuration );
+            updateRepositoryReferences(getProvider(repoType), repo, managedRepositoryConfiguration, configuration);
+            replaceOrAddRepositoryConfig(managedRepositoryConfiguration, configuration);
+            pushEvent(new LifecycleEvent(LifecycleEvent.LifecycleEventType.REGISTERED, this, repo));
             return repo;
-        }
-        finally
-        {
-            rwLock.writeLock( ).unlock( );
+        } finally {
+            rwLock.writeLock().unlock();
         }
     }
 
@@ -695,46 +623,38 @@ public class RepositoryRegistry implements ConfigurationListener, RepositoryEven
      * @param repositoryGroup the new repository group.
      * @throws RepositoryException if the new repository group could not be saved to the configuration.
      */
-    public RepositoryGroup putRepositoryGroup( RepositoryGroup repositoryGroup ) throws RepositoryException
-    {
-        rwLock.writeLock( ).lock( );
-        try
-        {
+    public RepositoryGroup putRepositoryGroup(RepositoryGroup repositoryGroup) throws RepositoryException {
+        rwLock.writeLock().lock();
+        try {
             final String id = repositoryGroup.getId();
-            RepositoryGroup originRepo = repositoryGroups.put( id, repositoryGroup );
-            try
-            {
-                if (originRepo!=null) {
+            RepositoryGroup originRepo = repositoryGroups.put(id, repositoryGroup);
+            try {
+                if (originRepo != null) {
                     originRepo.close();
                 }
-                RepositoryProvider provider = getProvider( repositoryGroup.getType() );
-                RepositoryGroupConfiguration newCfg = provider.getRepositoryGroupConfiguration( repositoryGroup );
-                Configuration configuration = getArchivaConfiguration( ).getConfiguration( );
-                updateRepositoryReferences( provider, repositoryGroup, newCfg );
-                RepositoryGroupConfiguration oldCfg = configuration.findRepositoryGroupById( id );
-                if (oldCfg!=null) {
-                    configuration.removeRepositoryGroup( oldCfg );
+                RepositoryProvider provider = getProvider(repositoryGroup.getType());
+                RepositoryGroupConfiguration newCfg = provider.getRepositoryGroupConfiguration(repositoryGroup);
+                Configuration configuration = getArchivaConfiguration().getConfiguration();
+                updateRepositoryReferences(provider, repositoryGroup, newCfg);
+                RepositoryGroupConfiguration oldCfg = configuration.findRepositoryGroupById(id);
+                if (oldCfg != null) {
+                    configuration.removeRepositoryGroup(oldCfg);
                 }
-                configuration.addRepositoryGroup( newCfg );
-                getArchivaConfiguration( ).save( configuration );
+                configuration.addRepositoryGroup(newCfg);
+                saveConfiguration(configuration);
                 return repositoryGroup;
-            }
-            catch ( Exception e )
-            {
+            } catch (Exception e) {
                 // Rollback
-                if ( originRepo != null )
-                {
-                    repositoryGroups.put( id, originRepo );
+                if (originRepo != null) {
+                    repositoryGroups.put(id, originRepo);
                 } else {
                     repositoryGroups.remove(id);
                 }
                 log.error("Exception during configuration update {}", e.getMessage(), e);
-                throw new RepositoryException( "Could not save the configuration" + (e.getMessage( )==null?"":": "+e.getMessage()) );
+                throw new RepositoryException("Could not save the configuration" + (e.getMessage() == null ? "" : ": " + e.getMessage()));
             }
-        }
-        finally
-        {
-            rwLock.writeLock( ).unlock( );
+        } finally {
+            rwLock.writeLock().unlock();
         }
     }
 
@@ -746,34 +666,27 @@ public class RepositoryRegistry implements ConfigurationListener, RepositoryEven
      * @return the updated or created repository
      * @throws RepositoryException if an error occurs, or the configuration is not valid.
      */
-    public RepositoryGroup putRepositoryGroup( RepositoryGroupConfiguration repositoryGroupConfiguration) throws RepositoryException
-    {
-        rwLock.writeLock( ).lock( );
-        try
-        {
+    public RepositoryGroup putRepositoryGroup(RepositoryGroupConfiguration repositoryGroupConfiguration) throws RepositoryException {
+        rwLock.writeLock().lock();
+        try {
             final String id = repositoryGroupConfiguration.getId();
-            final RepositoryType repositoryType = RepositoryType.valueOf( repositoryGroupConfiguration.getType() );
+            final RepositoryType repositoryType = RepositoryType.valueOf(repositoryGroupConfiguration.getType());
             Configuration configuration = getArchivaConfiguration().getConfiguration();
             RepositoryGroup repo = repositoryGroups.get(id);
-            RepositoryGroupConfiguration oldCfg = repo!=null ? getProvider( repositoryType ).getRepositoryGroupConfiguration( repo ) : null;
-            repo = putRepositoryGroup( repositoryGroupConfiguration, configuration );
-            try
-            {
-                getArchivaConfiguration().save(configuration);
-            }
-            catch ( IndeterminateConfigurationException | RegistryException e )
-            {
-                if (oldCfg!=null) {
-                    getProvider( repositoryType ).updateRepositoryGroupInstance( (EditableRepositoryGroup) repo, oldCfg );
+            RepositoryGroupConfiguration oldCfg = repo != null ? getProvider(repositoryType).getRepositoryGroupConfiguration(repo) : null;
+            repo = putRepositoryGroup(repositoryGroupConfiguration, configuration);
+            try {
+                saveConfiguration(configuration);
+            } catch (IndeterminateConfigurationException | RegistryException e) {
+                if (oldCfg != null) {
+                    getProvider(repositoryType).updateRepositoryGroupInstance((EditableRepositoryGroup) repo, oldCfg);
                 }
-                log.error("Could not save the configuration for repository group {}: {}", id, e.getMessage(),e );
-                throw new RepositoryException( "Could not save the configuration for repository group "+id+": "+e.getMessage() );
+                log.error("Could not save the configuration for repository group {}: {}", id, e.getMessage(), e);
+                throw new RepositoryException("Could not save the configuration for repository group " + id + ": " + e.getMessage());
             }
             return repo;
-        }
-        finally
-        {
-            rwLock.writeLock( ).unlock( );
+        } finally {
+            rwLock.writeLock().unlock();
         }
 
     }
@@ -783,41 +696,35 @@ public class RepositoryRegistry implements ConfigurationListener, RepositoryEven
      * the configuration is not saved.
      *
      * @param repositoryGroupConfiguration the new or changed repository configuration
-     * @param configuration the configuration object
+     * @param configuration                the configuration object
      * @return the new or updated repository
      * @throws RepositoryException if the configuration cannot be saved or updated
      */
-    @SuppressWarnings( "unchecked" )
-    public RepositoryGroup putRepositoryGroup( RepositoryGroupConfiguration repositoryGroupConfiguration, Configuration configuration) throws RepositoryException
-    {
-        rwLock.writeLock( ).lock( );
-        try
-        {
+    @SuppressWarnings("unchecked")
+    public RepositoryGroup putRepositoryGroup(RepositoryGroupConfiguration repositoryGroupConfiguration, Configuration configuration) throws RepositoryException {
+        rwLock.writeLock().lock();
+        try {
             final String id = repositoryGroupConfiguration.getId();
-            final RepositoryType repoType = RepositoryType.valueOf( repositoryGroupConfiguration.getType() );
+            final RepositoryType repoType = RepositoryType.valueOf(repositoryGroupConfiguration.getType());
             RepositoryGroup repo;
             setRepositoryGroupDefaults(repositoryGroupConfiguration);
-            if (repositoryGroups.containsKey( id )) {
+            if (repositoryGroups.containsKey(id)) {
                 repo = repositoryGroups.get(id);
-                if (repo instanceof EditableRepositoryGroup)
-                {
-                    getProvider( repoType ).updateRepositoryGroupInstance( (EditableRepositoryGroup) repo, repositoryGroupConfiguration );
+                if (repo instanceof EditableRepositoryGroup) {
+                    getProvider(repoType).updateRepositoryGroupInstance((EditableRepositoryGroup) repo, repositoryGroupConfiguration);
                 } else {
-                    throw new RepositoryException( "The repository is not editable "+id );
+                    throw new RepositoryException("The repository is not editable " + id);
                 }
-            } else
-            {
-                repo = getProvider( repoType ).createRepositoryGroup( repositoryGroupConfiguration );
-                repo.addListener(this);
+            } else {
+                repo = getProvider(repoType).createRepositoryGroup(repositoryGroupConfiguration);
+                repo.register(this);
                 repositoryGroups.put(id, repo);
             }
-            updateRepositoryReferences( getProvider( repoType  ), repo, repositoryGroupConfiguration );
-            replaceOrAddRepositoryConfig( repositoryGroupConfiguration, configuration );
+            updateRepositoryReferences(getProvider(repoType), repo, repositoryGroupConfiguration);
+            replaceOrAddRepositoryConfig(repositoryGroupConfiguration, configuration);
             return repo;
-        }
-        finally
-        {
-            rwLock.writeLock( ).unlock( );
+        } finally {
+            rwLock.writeLock().unlock();
         }
     }
 
@@ -825,7 +732,7 @@ public class RepositoryRegistry implements ConfigurationListener, RepositoryEven
         if (StringUtils.isEmpty(repositoryGroupConfiguration.getMergedIndexPath())) {
             repositoryGroupConfiguration.setMergedIndexPath(DEFAULT_INDEX_PATH);
         }
-        if (repositoryGroupConfiguration.getMergedIndexTtl()<=0) {
+        if (repositoryGroupConfiguration.getMergedIndexTtl() <= 0) {
             repositoryGroupConfiguration.setMergedIndexTtl(300);
         }
         if (StringUtils.isEmpty(repositoryGroupConfiguration.getCronExpression())) {
@@ -834,79 +741,72 @@ public class RepositoryRegistry implements ConfigurationListener, RepositoryEven
     }
 
     private void replaceOrAddRepositoryConfig(ManagedRepositoryConfiguration managedRepositoryConfiguration, Configuration configuration) {
-        ManagedRepositoryConfiguration oldCfg = configuration.findManagedRepositoryById( managedRepositoryConfiguration.getId() );
-        if ( oldCfg !=null) {
-            configuration.removeManagedRepository( oldCfg );
+        ManagedRepositoryConfiguration oldCfg = configuration.findManagedRepositoryById(managedRepositoryConfiguration.getId());
+        if (oldCfg != null) {
+            configuration.removeManagedRepository(oldCfg);
         }
-        configuration.addManagedRepository( managedRepositoryConfiguration );
+        configuration.addManagedRepository(managedRepositoryConfiguration);
     }
 
     private void replaceOrAddRepositoryConfig(RemoteRepositoryConfiguration remoteRepositoryConfiguration, Configuration configuration) {
-        RemoteRepositoryConfiguration oldCfg = configuration.findRemoteRepositoryById( remoteRepositoryConfiguration.getId() );
-        if ( oldCfg !=null) {
-            configuration.removeRemoteRepository( oldCfg );
+        RemoteRepositoryConfiguration oldCfg = configuration.findRemoteRepositoryById(remoteRepositoryConfiguration.getId());
+        if (oldCfg != null) {
+            configuration.removeRemoteRepository(oldCfg);
         }
-        configuration.addRemoteRepository( remoteRepositoryConfiguration );
+        configuration.addRemoteRepository(remoteRepositoryConfiguration);
     }
 
     private void replaceOrAddRepositoryConfig(RepositoryGroupConfiguration repositoryGroupConfiguration, Configuration configuration) {
-        RepositoryGroupConfiguration oldCfg = configuration.findRepositoryGroupById( repositoryGroupConfiguration.getId() );
-        if ( oldCfg !=null) {
-            configuration.removeRepositoryGroup( oldCfg );
+        RepositoryGroupConfiguration oldCfg = configuration.findRepositoryGroupById(repositoryGroupConfiguration.getId());
+        if (oldCfg != null) {
+            configuration.removeRepositoryGroup(oldCfg);
         }
-        configuration.addRepositoryGroup( repositoryGroupConfiguration);
+        configuration.addRepositoryGroup(repositoryGroupConfiguration);
     }
 
-    public RemoteRepository putRepository( RemoteRepository remoteRepository, Configuration configuration) throws RepositoryException
-    {
-        rwLock.writeLock( ).lock( );
-        try
-        {
+    public RemoteRepository putRepository(RemoteRepository remoteRepository, Configuration configuration) throws RepositoryException {
+        rwLock.writeLock().lock();
+        try {
             final String id = remoteRepository.getId();
-            if (managedRepositories.containsKey( id )) {
-                throw new RepositoryException( "There exists a managed repository with id "+id+". Could not update with remote repository." );
+            if (managedRepositories.containsKey(id)) {
+                throw new RepositoryException("There exists a managed repository with id " + id + ". Could not update with remote repository.");
             }
-            RemoteRepository originRepo = remoteRepositories.put( id, remoteRepository );
-            RemoteRepositoryConfiguration oldCfg=null;
+            RemoteRepository originRepo = remoteRepositories.put(id, remoteRepository);
+            RemoteRepositoryConfiguration oldCfg = null;
             RemoteRepositoryConfiguration newCfg;
-            try
-            {
-                if (originRepo!=null) {
+            try {
+                if (originRepo != null) {
                     originRepo.close();
                 }
-                final RepositoryProvider provider = getProvider( remoteRepository.getType() );
-                newCfg = provider.getRemoteConfiguration( remoteRepository );
-                updateRepositoryReferences( provider, remoteRepository, newCfg, configuration );
-                oldCfg = configuration.findRemoteRepositoryById( id );
-                if (oldCfg!=null) {
-                    configuration.removeRemoteRepository( oldCfg );
+                final RepositoryProvider provider = getProvider(remoteRepository.getType());
+                newCfg = provider.getRemoteConfiguration(remoteRepository);
+                updateRepositoryReferences(provider, remoteRepository, newCfg, configuration);
+                oldCfg = configuration.findRemoteRepositoryById(id);
+                if (oldCfg != null) {
+                    configuration.removeRemoteRepository(oldCfg);
                 }
-                configuration.addRemoteRepository( newCfg );
+                configuration.addRemoteRepository(newCfg);
+                pushEvent(new LifecycleEvent(LifecycleEvent.LifecycleEventType.REGISTERED, this, remoteRepository));
                 return remoteRepository;
-            }
-            catch ( Exception e )
-            {
+            } catch (Exception e) {
                 // Rollback
-                if ( originRepo != null )
-                {
-                    remoteRepositories.put( id, originRepo );
+                if (originRepo != null) {
+                    remoteRepositories.put(id, originRepo);
                 } else {
-                    remoteRepositories.remove( id);
+                    remoteRepositories.remove(id);
                 }
-                if (oldCfg!=null) {
-                    RemoteRepositoryConfiguration cfg = configuration.findRemoteRepositoryById( id );
-                    if (cfg!=null) {
-                        configuration.removeRemoteRepository( cfg );
-                        configuration.addRemoteRepository( oldCfg );
+                if (oldCfg != null) {
+                    RemoteRepositoryConfiguration cfg = configuration.findRemoteRepositoryById(id);
+                    if (cfg != null) {
+                        configuration.removeRemoteRepository(cfg);
+                        configuration.addRemoteRepository(oldCfg);
                     }
                 }
                 log.error("Error while adding remote repository {}", e.getMessage(), e);
-                throw new RepositoryException( "Could not save the configuration" + (e.getMessage( )==null?"":": "+e.getMessage()) );
+                throw new RepositoryException("Could not save the configuration" + (e.getMessage() == null ? "" : ": " + e.getMessage()));
             }
-        }
-        finally
-        {
-            rwLock.writeLock( ).unlock( );
+        } finally {
+            rwLock.writeLock().unlock();
         }
     }
 
@@ -917,27 +817,20 @@ public class RepositoryRegistry implements ConfigurationListener, RepositoryEven
      * @param remoteRepository the remote repository to add
      * @throws RepositoryException if an error occurs during configuration save
      */
-    public RemoteRepository putRepository( RemoteRepository remoteRepository ) throws RepositoryException
-    {
-        rwLock.writeLock( ).lock( );
-        try
-        {
+    public RemoteRepository putRepository(RemoteRepository remoteRepository) throws RepositoryException {
+        rwLock.writeLock().lock();
+        try {
             Configuration configuration = getArchivaConfiguration().getConfiguration();
-            try
-            {
-                RemoteRepository repo = putRepository( remoteRepository, configuration );
-                getArchivaConfiguration().save(configuration);
+            try {
+                RemoteRepository repo = putRepository(remoteRepository, configuration);
+                saveConfiguration(configuration);
                 return repo;
-            }
-            catch ( RegistryException | IndeterminateConfigurationException e )
-            {
+            } catch (RegistryException | IndeterminateConfigurationException e) {
                 log.error("Error while saving remote repository {}", e.getMessage(), e);
-                throw new RepositoryException( "Could not save the configuration" + (e.getMessage( )==null?"":": "+e.getMessage()) );
+                throw new RepositoryException("Could not save the configuration" + (e.getMessage() == null ? "" : ": " + e.getMessage()));
             }
-        }
-        finally
-        {
-            rwLock.writeLock( ).unlock( );
+        } finally {
+            rwLock.writeLock().unlock();
         }
     }
 
@@ -949,34 +842,27 @@ public class RepositoryRegistry implements ConfigurationListener, RepositoryEven
      * @return the updated or created repository
      * @throws RepositoryException if an error occurs, or the configuration is not valid.
      */
-    public RemoteRepository putRepository( RemoteRepositoryConfiguration remoteRepositoryConfiguration) throws RepositoryException
-    {
-        rwLock.writeLock( ).lock( );
-        try
-        {
+    public RemoteRepository putRepository(RemoteRepositoryConfiguration remoteRepositoryConfiguration) throws RepositoryException {
+        rwLock.writeLock().lock();
+        try {
             final String id = remoteRepositoryConfiguration.getId();
-            final RepositoryType repositoryType = RepositoryType.valueOf( remoteRepositoryConfiguration.getType() );
+            final RepositoryType repositoryType = RepositoryType.valueOf(remoteRepositoryConfiguration.getType());
             Configuration configuration = getArchivaConfiguration().getConfiguration();
             RemoteRepository repo = remoteRepositories.get(id);
-            RemoteRepositoryConfiguration oldCfg = repo!=null ? getProvider( repositoryType ).getRemoteConfiguration( repo ) : null;
-            repo = putRepository( remoteRepositoryConfiguration, configuration );
-            try
-            {
-                getArchivaConfiguration().save(configuration);
-            }
-            catch ( IndeterminateConfigurationException | RegistryException e )
-            {
-                if (oldCfg!=null) {
-                    getProvider( repositoryType ).updateRemoteInstance( (EditableRemoteRepository)repo, oldCfg );
+            RemoteRepositoryConfiguration oldCfg = repo != null ? getProvider(repositoryType).getRemoteConfiguration(repo) : null;
+            repo = putRepository(remoteRepositoryConfiguration, configuration);
+            try {
+                saveConfiguration(configuration);
+            } catch (IndeterminateConfigurationException | RegistryException e) {
+                if (oldCfg != null) {
+                    getProvider(repositoryType).updateRemoteInstance((EditableRemoteRepository) repo, oldCfg);
                 }
-                log.error("Could not save the configuration for repository {}: {}", id, e.getMessage(),e );
-                throw new RepositoryException( "Could not save the configuration for repository "+id+": "+e.getMessage() );
+                log.error("Could not save the configuration for repository {}: {}", id, e.getMessage(), e);
+                throw new RepositoryException("Could not save the configuration for repository " + id + ": " + e.getMessage());
             }
             return repo;
-        }
-        finally
-        {
-            rwLock.writeLock( ).unlock( );
+        } finally {
+            rwLock.writeLock().unlock();
         }
 
     }
@@ -986,40 +872,35 @@ public class RepositoryRegistry implements ConfigurationListener, RepositoryEven
      * the configuration is not saved.
      *
      * @param remoteRepositoryConfiguration the new or changed repository configuration
-     * @param configuration the configuration object
+     * @param configuration                 the configuration object
      * @return the new or updated repository
      * @throws RepositoryException if the configuration cannot be saved or updated
      */
-    @SuppressWarnings( "unchecked" )
-    public RemoteRepository putRepository( RemoteRepositoryConfiguration remoteRepositoryConfiguration, Configuration configuration) throws RepositoryException
-    {
-        rwLock.writeLock( ).lock( );
-        try
-        {
+    @SuppressWarnings("unchecked")
+    public RemoteRepository putRepository(RemoteRepositoryConfiguration remoteRepositoryConfiguration, Configuration configuration) throws RepositoryException {
+        rwLock.writeLock().lock();
+        try {
             final String id = remoteRepositoryConfiguration.getId();
-            final RepositoryType repoType = RepositoryType.valueOf( remoteRepositoryConfiguration.getType() );
+            final RepositoryType repoType = RepositoryType.valueOf(remoteRepositoryConfiguration.getType());
             RemoteRepository repo;
-            if (remoteRepositories.containsKey( id )) {
+            if (remoteRepositories.containsKey(id)) {
                 repo = remoteRepositories.get(id);
-                if (repo instanceof EditableRemoteRepository)
-                {
-                    getProvider( repoType ).updateRemoteInstance( (EditableRemoteRepository) repo, remoteRepositoryConfiguration );
+                if (repo instanceof EditableRemoteRepository) {
+                    getProvider(repoType).updateRemoteInstance((EditableRemoteRepository) repo, remoteRepositoryConfiguration);
                 } else {
-                    throw new RepositoryException( "The repository is not editable "+id );
+                    throw new RepositoryException("The repository is not editable " + id);
                 }
-            } else
-            {
-                repo = getProvider( repoType ).createRemoteInstance( remoteRepositoryConfiguration );
-                repo.addListener(this);
+            } else {
+                repo = getProvider(repoType).createRemoteInstance(remoteRepositoryConfiguration);
+                repo.register(this);
                 remoteRepositories.put(id, repo);
             }
-            updateRepositoryReferences( getProvider( repoType  ), repo, remoteRepositoryConfiguration, configuration );
-            replaceOrAddRepositoryConfig( remoteRepositoryConfiguration, configuration );
+            updateRepositoryReferences(getProvider(repoType), repo, remoteRepositoryConfiguration, configuration);
+            replaceOrAddRepositoryConfig(remoteRepositoryConfiguration, configuration);
+            pushEvent(new LifecycleEvent(LifecycleEvent.LifecycleEventType.REGISTERED, this, repo));
             return repo;
-        }
-        finally
-        {
-            rwLock.writeLock( ).unlock( );
+        } finally {
+            rwLock.writeLock().unlock();
         }
 
 
@@ -1027,26 +908,25 @@ public class RepositoryRegistry implements ConfigurationListener, RepositoryEven
 
     public void removeRepository(String repoId) throws RepositoryException {
         Repository repo = getRepository(repoId);
-        if (repo!=null) {
+        if (repo != null) {
             removeRepository(repo);
         }
     }
 
-    @SuppressWarnings( "unchecked" )
-    public void removeRepository(Repository repo) throws RepositoryException
-    {
-        if (repo==null) {
+    @SuppressWarnings("unchecked")
+    public void removeRepository(Repository repo) throws RepositoryException {
+        if (repo == null) {
             log.warn("Trying to remove null repository");
             return;
         }
-        if (repo instanceof RemoteRepository ) {
-            removeRepository( (RemoteRepository)repo );
+        if (repo instanceof RemoteRepository) {
+            removeRepository((RemoteRepository) repo);
         } else if (repo instanceof ManagedRepository) {
-            removeRepository( (ManagedRepository)repo);
-        } else if (repo instanceof RepositoryGroup ) {
+            removeRepository((ManagedRepository) repo);
+        } else if (repo instanceof RepositoryGroup) {
             removeRepositoryGroup((RepositoryGroup) repo);
-        }else {
-            throw new RepositoryException( "Repository type not known: "+repo.getClass() );
+        } else {
+            throw new RepositoryException("Repository type not known: " + repo.getClass());
         }
     }
 
@@ -1057,64 +937,59 @@ public class RepositoryRegistry implements ConfigurationListener, RepositoryEven
      * @param managedRepository the managed repository to remove
      * @throws RepositoryException if a error occurs during configuration save
      */
-    public void removeRepository( ManagedRepository managedRepository ) throws RepositoryException
-    {
+    public void removeRepository(ManagedRepository managedRepository) throws RepositoryException {
         final String id = managedRepository.getId();
-        ManagedRepository repo = getManagedRepository( id );
-        if (repo!=null) {
+        ManagedRepository repo = getManagedRepository(id);
+        if (repo != null) {
             rwLock.writeLock().lock();
             try {
-                repo = managedRepositories.remove( id );
-                if (repo!=null) {
+                repo = managedRepositories.remove(id);
+                if (repo != null) {
                     repo.close();
                     removeRepositoryFromGroups(repo);
                     Configuration configuration = getArchivaConfiguration().getConfiguration();
-                    ManagedRepositoryConfiguration cfg = configuration.findManagedRepositoryById( id );
-                    if (cfg!=null) {
-                        configuration.removeManagedRepository( cfg );
+                    ManagedRepositoryConfiguration cfg = configuration.findManagedRepositoryById(id);
+                    if (cfg != null) {
+                        configuration.removeManagedRepository(cfg);
                     }
-                    getArchivaConfiguration().save( configuration );
+                    saveConfiguration(configuration);
                 }
-
-            }
-            catch ( RegistryException | IndeterminateConfigurationException e )
-            {
+                pushEvent(new LifecycleEvent(LifecycleEvent.LifecycleEventType.UNREGISTERED, this, repo));
+            } catch (RegistryException | IndeterminateConfigurationException e) {
                 // Rollback
                 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
-            {
+                throw new RepositoryException("Could not save configuration after repository removal: " + e.getMessage());
+            } finally {
                 rwLock.writeLock().unlock();
             }
         }
     }
 
     private void removeRepositoryFromGroups(ManagedRepository repo) {
-        if (repo!=null) {
+        if (repo != null) {
             repositoryGroups.values().stream().filter(repoGroup -> repoGroup instanceof EditableRepository).
                     map(repoGroup -> (EditableRepositoryGroup) repoGroup).forEach(repoGroup -> repoGroup.removeRepository(repo));
         }
     }
 
-    public void removeRepository(ManagedRepository managedRepository, Configuration configuration) throws RepositoryException
-    {
+    public void removeRepository(ManagedRepository managedRepository, Configuration configuration) throws RepositoryException {
         final String id = managedRepository.getId();
-        ManagedRepository repo = getManagedRepository( id );
-        if (repo!=null) {
+        ManagedRepository repo = getManagedRepository(id);
+        if (repo != null) {
             rwLock.writeLock().lock();
             try {
-                repo = managedRepositories.remove( id );
-                if (repo!=null) {
+                repo = managedRepositories.remove(id);
+                if (repo != null) {
                     repo.close();
                     removeRepositoryFromGroups(repo);
-                    ManagedRepositoryConfiguration cfg = configuration.findManagedRepositoryById( id );
-                    if (cfg!=null) {
-                        configuration.removeManagedRepository( cfg );
+                    ManagedRepositoryConfiguration cfg = configuration.findManagedRepositoryById(id);
+                    if (cfg != null) {
+                        configuration.removeManagedRepository(cfg);
                     }
                 }
-            } finally
-            {
+                pushEvent(new LifecycleEvent(LifecycleEvent.LifecycleEventType.UNREGISTERED, this, repo));
+            } finally {
                 rwLock.writeLock().unlock();
             }
         }
@@ -1129,55 +1004,49 @@ public class RepositoryRegistry implements ConfigurationListener, RepositoryEven
      * @param repositoryGroup the repository group to remove
      * @throws RepositoryException if a error occurs during configuration save
      */
-    public void removeRepositoryGroup( RepositoryGroup repositoryGroup ) throws RepositoryException
-    {
+    public void removeRepositoryGroup(RepositoryGroup repositoryGroup) throws RepositoryException {
         final String id = repositoryGroup.getId();
-        RepositoryGroup repo = getRepositoryGroup( id );
-        if (repo!=null) {
+        RepositoryGroup repo = getRepositoryGroup(id);
+        if (repo != null) {
             rwLock.writeLock().lock();
             try {
-                repo = repositoryGroups.remove( id );
-                if (repo!=null) {
+                repo = repositoryGroups.remove(id);
+                if (repo != null) {
                     repo.close();
                     Configuration configuration = getArchivaConfiguration().getConfiguration();
-                    RepositoryGroupConfiguration cfg = configuration.findRepositoryGroupById( id );
-                    if (cfg!=null) {
-                        configuration.removeRepositoryGroup( cfg );
+                    RepositoryGroupConfiguration cfg = configuration.findRepositoryGroupById(id);
+                    if (cfg != null) {
+                        configuration.removeRepositoryGroup(cfg);
                     }
-                    getArchivaConfiguration().save( configuration );
+                    saveConfiguration(configuration);
                 }
 
-            }
-            catch ( RegistryException | IndeterminateConfigurationException e )
-            {
+            } catch (RegistryException | IndeterminateConfigurationException e) {
                 // Rollback
                 log.error("Could not save config after repository removal: {}", e.getMessage(), e);
                 repositoryGroups.put(repo.getId(), repo);
-                throw new RepositoryException( "Could not save configuration after repository removal: "+e.getMessage() );
-            } finally
-            {
+                throw new RepositoryException("Could not save configuration after repository removal: " + e.getMessage());
+            } finally {
                 rwLock.writeLock().unlock();
             }
         }
     }
 
-    public void removeRepositoryGroup(RepositoryGroup repositoryGroup, Configuration configuration) throws RepositoryException
-    {
+    public void removeRepositoryGroup(RepositoryGroup repositoryGroup, Configuration configuration) throws RepositoryException {
         final String id = repositoryGroup.getId();
-        RepositoryGroup repo = getRepositoryGroup( id );
-        if (repo!=null) {
+        RepositoryGroup repo = getRepositoryGroup(id);
+        if (repo != null) {
             rwLock.writeLock().lock();
             try {
-                repo = repositoryGroups.remove( id );
-                if (repo!=null) {
+                repo = repositoryGroups.remove(id);
+                if (repo != null) {
                     repo.close();
-                    RepositoryGroupConfiguration cfg = configuration.findRepositoryGroupById( id );
-                    if (cfg!=null) {
-                        configuration.removeRepositoryGroup( cfg );
+                    RepositoryGroupConfiguration cfg = configuration.findRepositoryGroupById(id);
+                    if (cfg != null) {
+                        configuration.removeRepositoryGroup(cfg);
                     }
                 }
-            } finally
-            {
+            } finally {
                 rwLock.writeLock().unlock();
             }
         }
@@ -1185,17 +1054,17 @@ public class RepositoryRegistry implements ConfigurationListener, RepositoryEven
     }
 
     private void doRemoveRepo(RemoteRepository repo, Configuration configuration) {
-            repo.close();
-            RemoteRepositoryConfiguration cfg = configuration.findRemoteRepositoryById(repo.getId());
-            if (cfg != null) {
-                configuration.removeRemoteRepository(cfg);
-            }
-            List<ProxyConnectorConfiguration> proxyConnectors = new ArrayList<>(configuration.getProxyConnectors());
-            for (ProxyConnectorConfiguration proxyConnector : proxyConnectors) {
-                if (StringUtils.equals(proxyConnector.getTargetRepoId(), repo.getId())) {
-                    configuration.removeProxyConnector(proxyConnector);
-                }
+        repo.close();
+        RemoteRepositoryConfiguration cfg = configuration.findRemoteRepositoryById(repo.getId());
+        if (cfg != null) {
+            configuration.removeRemoteRepository(cfg);
+        }
+        List<ProxyConnectorConfiguration> proxyConnectors = new ArrayList<>(configuration.getProxyConnectors());
+        for (ProxyConnectorConfiguration proxyConnector : proxyConnectors) {
+            if (StringUtils.equals(proxyConnector.getTargetRepoId(), repo.getId())) {
+                configuration.removeProxyConnector(proxyConnector);
             }
+        }
     }
 
     /**
@@ -1205,47 +1074,43 @@ public class RepositoryRegistry implements ConfigurationListener, RepositoryEven
      * @param remoteRepository the remote repository to remove
      * @throws RepositoryException if a error occurs during configuration save
      */
-    public void removeRepository( RemoteRepository remoteRepository ) throws RepositoryException
-    {
+    public void removeRepository(RemoteRepository remoteRepository) throws RepositoryException {
 
         final String id = remoteRepository.getId();
-        RemoteRepository repo = getRemoteRepository( id );
-        if (repo!=null) {
+        RemoteRepository repo = getRemoteRepository(id);
+        if (repo != null) {
             rwLock.writeLock().lock();
             try {
-                repo = remoteRepositories.remove( id );
-                if (repo!=null) {
+                repo = remoteRepositories.remove(id);
+                if (repo != null) {
                     Configuration configuration = getArchivaConfiguration().getConfiguration();
                     doRemoveRepo(repo, configuration);
-                    getArchivaConfiguration().save( configuration );
+                    saveConfiguration(configuration);
                 }
-            }
-            catch ( RegistryException | IndeterminateConfigurationException e )
-            {
+                pushEvent(new LifecycleEvent(LifecycleEvent.LifecycleEventType.UNREGISTERED, this, repo));
+            } catch (RegistryException | IndeterminateConfigurationException e) {
                 // Rollback
                 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
-            {
+                throw new RepositoryException("Could not save configuration after repository removal: " + e.getMessage());
+            } finally {
                 rwLock.writeLock().unlock();
             }
         }
     }
 
-    public void removeRepository( RemoteRepository remoteRepository, Configuration configuration) throws RepositoryException
-    {
+    public void removeRepository(RemoteRepository remoteRepository, Configuration configuration) throws RepositoryException {
         final String id = remoteRepository.getId();
-        RemoteRepository repo = getRemoteRepository( id );
-        if (repo!=null) {
+        RemoteRepository repo = getRemoteRepository(id);
+        if (repo != null) {
             rwLock.writeLock().lock();
             try {
-                repo = remoteRepositories.remove( id );
-                if (repo!=null) {
+                repo = remoteRepositories.remove(id);
+                if (repo != null) {
                     doRemoveRepo(repo, configuration);
                 }
-            } finally
-            {
+                pushEvent(new LifecycleEvent(LifecycleEvent.LifecycleEventType.UNREGISTERED, this, repo));
+            } finally {
                 rwLock.writeLock().unlock();
             }
         }
@@ -1265,7 +1130,7 @@ public class RepositoryRegistry implements ConfigurationListener, RepositoryEven
      * @param repo
      * @throws IndexUpdateFailedException
      */
-    @SuppressWarnings( "unchecked" )
+    @SuppressWarnings("unchecked")
     public void resetIndexingContext(Repository repo) throws IndexUpdateFailedException {
         if (repo.hasIndex() && repo instanceof EditableRepository) {
             EditableRepository eRepo = (EditableRepository) repo;
@@ -1282,27 +1147,26 @@ public class RepositoryRegistry implements ConfigurationListener, RepositoryEven
      * @param repo The origin repository
      * @return The cloned repository.
      */
-    public ManagedRepository clone(ManagedRepository repo, String newId) throws RepositoryException
-    {
+    public ManagedRepository clone(ManagedRepository repo, String newId) throws RepositoryException {
         if (managedRepositories.containsKey(newId) || remoteRepositories.containsKey(newId)) {
-            throw new RepositoryException("The given id exists already "+newId);
+            throw new RepositoryException("The given id exists already " + newId);
         }
         RepositoryProvider provider = getProvider(repo.getType());
         ManagedRepositoryConfiguration cfg = provider.getManagedConfiguration(repo);
         cfg.setId(newId);
         ManagedRepository cloned = provider.createManagedInstance(cfg);
-        cloned.addListener(this);
+        cloned.register(this);
         return cloned;
     }
 
-    @SuppressWarnings( "unchecked" )
+    @SuppressWarnings("unchecked")
     public <T extends Repository> Repository clone(T repo, String newId) throws RepositoryException {
-        if (repo instanceof RemoteRepository ) {
-            return this.clone((RemoteRepository)repo, newId);
+        if (repo instanceof RemoteRepository) {
+            return this.clone((RemoteRepository) repo, newId);
         } else if (repo instanceof ManagedRepository) {
-            return this.clone((ManagedRepository)repo, newId);
+            return this.clone((ManagedRepository) repo, newId);
         } else {
-            throw new RepositoryException("This repository class is not supported "+ repo.getClass().getName());
+            throw new RepositoryException("This repository class is not supported " + repo.getClass().getName());
         }
     }
 
@@ -1313,51 +1177,83 @@ public class RepositoryRegistry implements ConfigurationListener, RepositoryEven
      * @param repo The origin repository
      * @return The cloned repository.
      */
-    public RemoteRepository clone( RemoteRepository repo, String newId) throws RepositoryException
-    {
+    public RemoteRepository clone(RemoteRepository repo, String newId) throws RepositoryException {
         if (managedRepositories.containsKey(newId) || remoteRepositories.containsKey(newId)) {
-            throw new RepositoryException("The given id exists already "+newId);
+            throw new RepositoryException("The given id exists already " + newId);
         }
         RepositoryProvider provider = getProvider(repo.getType());
         RemoteRepositoryConfiguration cfg = provider.getRemoteConfiguration(repo);
         cfg.setId(newId);
         RemoteRepository cloned = provider.createRemoteInstance(cfg);
-        cloned.addListener(this);
+        cloned.register(this);
         return cloned;
     }
 
 
     @Override
     public void configurationEvent(ConfigurationEvent event) {
-
+        // Note: the ignoreConfigEvents flag does not work, if the config events are asynchronous.
+        if (!ignoreConfigEvents) {
+            reload();
+        }
     }
 
 
     @Override
-    public void addListener(RepositoryEventListener listener) {
+    public void register(RepositoryEventListener listener) {
         if (!this.listeners.contains(listener)) {
             this.listeners.add(listener);
         }
     }
 
     @Override
-    public void removeListener(RepositoryEventListener listener) {
+    public void register(RepositoryEventListener listener, EventType type) {
+        List<RepositoryEventListener> listeners;
+        if (typeListenerMap.containsKey(type)) {
+            listeners = typeListenerMap.get(type);
+        } else {
+            listeners = new ArrayList<>();
+            typeListenerMap.put(type, listeners);
+        }
+        if (!listeners.contains(listener)) {
+            listeners.add(listener);
+        }
+    }
+
+    @Override
+    public void register(RepositoryEventListener listener, Set<? extends EventType> types) {
+        for (EventType type : types) {
+            register(listener, type);
+        }
+    }
+
+    @Override
+    public void unregister(RepositoryEventListener listener) {
         this.listeners.remove(listener);
+        for (List<RepositoryEventListener> listeners : typeListenerMap.values()) {
+            listeners.remove(listener);
+        }
     }
 
     @Override
     public void clearListeners() {
         this.listeners.clear();
+        this.typeListenerMap.clear();
     }
 
-    @SuppressWarnings( "unchecked" )
+    @SuppressWarnings("unchecked")
     @Override
-    public <T> void raise(RepositoryEvent<T> event) {
-        if (event instanceof IndexCreationEvent ) {
-            if (managedRepositories.containsKey(event.getRepository().getId()) ||
-                    remoteRepositories.containsKey(event.getRepository().getId())) {
-                EditableRepository repo = (EditableRepository) event.getRepository();
-                if (repo != null && repo.getIndexingContext()!=null) {
+    public void raise(Event event) {
+        // To avoid event cycles:
+        if (sameOriginator(event)) {
+            return;
+        }
+        if (event instanceof IndexCreationEvent) {
+            IndexCreationEvent idxEvent = (IndexCreationEvent) event;
+            if (managedRepositories.containsKey(idxEvent.getRepository().getId()) ||
+                    remoteRepositories.containsKey(idxEvent.getRepository().getId())) {
+                EditableRepository repo = (EditableRepository) idxEvent.getRepository();
+                if (repo != null && repo.getIndexingContext() != null) {
                     try {
                         ArchivaIndexManager idxmgr = getIndexManager(repo.getType());
                         if (idxmgr != null) {
@@ -1372,9 +1268,36 @@ public class RepositoryRegistry implements ConfigurationListener, RepositoryEven
                 }
             }
         }
-        for(RepositoryEventListener listener : listeners) {
-            listener.raise(event);
+        // We propagate all events to our listeners
+        pushEvent(event.recreate(this));
+    }
+
+    private boolean sameOriginator(Event event) {
+        if (event.getOriginator()==this) {
+            return true;
+        } else if (event.hasPreviousEvent()) {
+            return sameOriginator(event.getPreviousEvent());
+        } else {
+            return false;
+        }
+    }
+
+    private void pushEvent(Event<RepositoryRegistry> event) {
+        callListeners(event, listeners);
+        if (typeListenerMap.containsKey(event.getType())) {
+            callListeners(event, typeListenerMap.get(event.getType()));
         }
     }
 
+    private void callListeners(final Event<RepositoryRegistry> event, final List<RepositoryEventListener> evtListeners) {
+        for (RepositoryEventListener listener : evtListeners) {
+            try {
+                listener.raise(event);
+            } catch (Throwable e) {
+                log.error("Could not raise event {} on listener {}: {}", event, listener, e.getMessage());
+            }
+        }
+    }
+
+
 }
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 3a5e476..0f75218 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
@@ -23,6 +23,8 @@ import org.apache.archiva.configuration.ManagedRepositoryConfiguration;
 import org.apache.archiva.configuration.RemoteRepositoryConfiguration;
 import org.apache.archiva.configuration.RepositoryGroupConfiguration;
 import org.apache.archiva.repository.*;
+import org.apache.archiva.repository.events.Event;
+import org.apache.archiva.repository.events.RepositoryValueEvent;
 import org.apache.archiva.repository.features.ArtifactCleanupFeature;
 import org.apache.archiva.repository.features.IndexCreationFeature;
 import org.apache.archiva.repository.features.RemoteIndexFeature;
@@ -259,7 +261,7 @@ public class RepositoryProviderMock implements RepositoryProvider
     }
 
     @Override
-    public <T> void raise(RepositoryEvent<T> event) {
+    public void raise(Event event) {
 
     }
 }
diff --git a/archiva-modules/archiva-maven/archiva-maven-proxy/src/test/java/org/apache/archiva/repository/mock/RepositoryProviderMock.java b/archiva-modules/archiva-maven/archiva-maven-proxy/src/test/java/org/apache/archiva/repository/mock/RepositoryProviderMock.java
index cc99d15..0a8c573 100644
--- a/archiva-modules/archiva-maven/archiva-maven-proxy/src/test/java/org/apache/archiva/repository/mock/RepositoryProviderMock.java
+++ b/archiva-modules/archiva-maven/archiva-maven-proxy/src/test/java/org/apache/archiva/repository/mock/RepositoryProviderMock.java
@@ -32,7 +32,8 @@ 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.RepositoryEvent;
+import org.apache.archiva.repository.events.Event;
+import org.apache.archiva.repository.events.RepositoryValueEvent;
 import org.apache.archiva.repository.RepositoryException;
 import org.apache.archiva.repository.RepositoryGroup;
 import org.apache.archiva.repository.RepositoryProvider;
@@ -280,7 +281,7 @@ public class RepositoryProviderMock implements RepositoryProvider
     }
 
     @Override
-    public <T> void raise(RepositoryEvent<T> event) {
+    public void raise(Event event) {
 
     }
 }


[archiva] 06/08: Setting directory hint for root path of asset

Posted by ma...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

martin_s pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/archiva.git

commit 74d69f36c8f15366e21608aa6cce4648b6202833
Author: Martin Stockhammer <ma...@apache.org>
AuthorDate: Sun Sep 22 00:07:12 2019 +0200

    Setting directory hint for root path of asset
---
 .../java/org/apache/archiva/repository/storage/FilesystemAsset.java   | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/archiva-modules/archiva-base/archiva-storage-fs/src/main/java/org/apache/archiva/repository/storage/FilesystemAsset.java b/archiva-modules/archiva-base/archiva-storage-fs/src/main/java/org/apache/archiva/repository/storage/FilesystemAsset.java
index 4e35e5d..271dc1e 100644
--- a/archiva-modules/archiva-base/archiva-storage-fs/src/main/java/org/apache/archiva/repository/storage/FilesystemAsset.java
+++ b/archiva-modules/archiva-base/archiva-storage-fs/src/main/java/org/apache/archiva/repository/storage/FilesystemAsset.java
@@ -118,6 +118,10 @@ public class FilesystemAsset implements StorageAsset, Comparable {
         this.setPermissionsForNew = false;
         this.basePath = null;
         this.storage = storage;
+        // The base directory is always a directory
+        if ("".equals(path) || "/".equals(path)) {
+            this.directoryHint = true;
+        }
         init();
     }