Changing repository registry and layer

Adding unit tests for the registry.
Fixing some uri issues.
Removing dependency to consumer to break circular dependency


Project: http://git-wip-us.apache.org/repos/asf/archiva/repo
Commit: http://git-wip-us.apache.org/repos/asf/archiva/commit/d6e4a5b4
Tree: http://git-wip-us.apache.org/repos/asf/archiva/tree/d6e4a5b4
Diff: http://git-wip-us.apache.org/repos/asf/archiva/diff/d6e4a5b4

Branch: refs/heads/master
Commit: d6e4a5b48580ffc0420df5c6b2486fa0e57ab7c4
Parents: 55f72f2
Author: Martin Stockhammer <[email protected]>
Authored: Wed Nov 1 15:27:45 2017 +0100
Committer: Martin Stockhammer <[email protected]>
Committed: Wed Nov 1 15:27:45 2017 +0100

----------------------------------------------------------------------
 .../archiva-repository-layer/pom.xml            |  25 +-
 .../archiva/repository/AbstractRepository.java  |  19 +-
 .../repository/BasicManagedRepository.java      |  79 +++
 .../repository/BasicRemoteRepository.java       |  73 +++
 .../repository/ManagedRepositoryContent.java    |   5 +-
 .../archiva/repository/PasswordCredentials.java |   5 +
 .../repository/RemoteRepositoryContent.java     |   1 -
 .../repository/RepositoryContentFactory.java    | 134 ++---
 .../archiva/repository/RepositoryProvider.java  |  89 +++-
 .../archiva/repository/RepositoryRegistry.java  | 231 +++++++--
 .../features/ArtifactCleanupFeature.java        |  16 +-
 .../features/IndexCreationFeature.java          |  11 +-
 .../repository/RepositoryRegistryTest.java      | 511 +++++++++++++++++++
 .../mock/ManagedRepositoryContentMock.java      | 169 ++++++
 .../mock/RemoteRepositoryContentMock.java       |  78 +++
 .../repository/mock/RepositoryProviderMock.java | 231 +++++++++
 .../repository/RepositoryRegistryTest.java      |  87 ----
 .../src/main/test/resources/archiva.xml         | 202 ++++++++
 .../src/main/test/resources/log4j2-test.xml     |  45 ++
 .../src/main/test/resources/spring-context.xml  |  53 ++
 20 files changed, 1849 insertions(+), 215 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/archiva/blob/d6e4a5b4/archiva-modules/archiva-base/archiva-repository-layer/pom.xml
----------------------------------------------------------------------
diff --git a/archiva-modules/archiva-base/archiva-repository-layer/pom.xml 
b/archiva-modules/archiva-base/archiva-repository-layer/pom.xml
index 16df6e4..8f21534 100644
--- a/archiva-modules/archiva-base/archiva-repository-layer/pom.xml
+++ b/archiva-modules/archiva-base/archiva-repository-layer/pom.xml
@@ -39,10 +39,6 @@
     </dependency>
     <dependency>
       <groupId>org.apache.archiva</groupId>
-      <artifactId>archiva-consumer-api</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.archiva</groupId>
       <artifactId>archiva-checksum</artifactId>
     </dependency>
     <dependency>
@@ -105,6 +101,27 @@
       <artifactId>cron-utils</artifactId>
       <version>6.0.2</version>
     </dependency>
+
+    <dependency>
+      <groupId>org.apache.logging.log4j</groupId>
+      <artifactId>log4j-slf4j-impl</artifactId>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.logging.log4j</groupId>
+      <artifactId>log4j-1.2-api</artifactId>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.logging.log4j</groupId>
+      <artifactId>log4j-core</artifactId>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.logging.log4j</groupId>
+      <artifactId>log4j-jcl</artifactId>
+      <scope>test</scope>
+    </dependency>
   </dependencies>
   <build>
     <plugins>

http://git-wip-us.apache.org/repos/asf/archiva/blob/d6e4a5b4/archiva-modules/archiva-base/archiva-repository-layer/src/main/java/org/apache/archiva/repository/AbstractRepository.java
----------------------------------------------------------------------
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 4bac7e7..0ff3cb1 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
@@ -52,10 +52,12 @@ public abstract class AbstractRepository implements 
EditableRepository
     private Set<URI> failoverLocations = new HashSet<>(  );
     private Set<URI> uFailoverLocations = Collections.unmodifiableSet( 
failoverLocations );
     private boolean scanned = true;
-    String schedulingDefinition = "0 0 02 * *";
-    private String layout;
+    String schedulingDefinition = "0 0 02 * * ?";
+    private String layout = "default";
     public static final CronDefinition CRON_DEFINITION = 
CronDefinitionBuilder.instanceDefinitionFor(CronType.QUARTZ);
 
+    Map<Class<? extends RepositoryFeature<?>>, RepositoryFeature<?>> 
featureMap = new HashMap<>(  );
+
     public AbstractRepository(RepositoryType type, String id, String name) {
         this.id = id;
         this.names.put( primaryLocale, name);
@@ -152,13 +154,18 @@ public abstract class AbstractRepository implements 
EditableRepository
     @Override
     public <T extends RepositoryFeature<T>> RepositoryFeature<T> getFeature( 
Class<T> clazz ) throws UnsupportedFeatureException
     {
-        throw new UnsupportedFeatureException( "Feature "+clazz+" not 
supported"  );
+        if (featureMap.containsKey( clazz )) {
+            return (RepositoryFeature<T>) featureMap.get(clazz);
+        } else
+        {
+            throw new UnsupportedFeatureException( "Feature " + clazz + " not 
supported" );
+        }
     }
 
     @Override
     public <T extends RepositoryFeature<T>> boolean supportsFeature( Class<T> 
clazz )
     {
-        return false;
+        return featureMap.containsKey( clazz );
     }
 
     @Override
@@ -226,4 +233,8 @@ public abstract class AbstractRepository implements 
EditableRepository
         parser.parse(cronExpression).validate();
         this.schedulingDefinition = cronExpression;
     }
+
+    protected <T extends RepositoryFeature<T>> void 
addFeature(RepositoryFeature<T> feature) {
+       featureMap.put( (Class<? extends RepositoryFeature<?>>) 
feature.getClass(), feature);
+    }
 }

http://git-wip-us.apache.org/repos/asf/archiva/blob/d6e4a5b4/archiva-modules/archiva-base/archiva-repository-layer/src/main/java/org/apache/archiva/repository/BasicManagedRepository.java
----------------------------------------------------------------------
diff --git 
a/archiva-modules/archiva-base/archiva-repository-layer/src/main/java/org/apache/archiva/repository/BasicManagedRepository.java
 
b/archiva-modules/archiva-base/archiva-repository-layer/src/main/java/org/apache/archiva/repository/BasicManagedRepository.java
new file mode 100644
index 0000000..0ab88f3
--- /dev/null
+++ 
b/archiva-modules/archiva-base/archiva-repository-layer/src/main/java/org/apache/archiva/repository/BasicManagedRepository.java
@@ -0,0 +1,79 @@
+package org.apache.archiva.repository;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import org.apache.archiva.repository.features.ArtifactCleanupFeature;
+import org.apache.archiva.repository.features.IndexCreationFeature;
+import org.apache.archiva.repository.features.StagingRepositoryFeature;
+
+import java.util.Locale;
+
+/**
+ *
+ * Just a helper class, mainly used for unit tests.
+ *
+ *
+ */
+public class BasicManagedRepository extends AbstractManagedRepository
+
+{
+    ArtifactCleanupFeature artifactCleanupFeature = new 
ArtifactCleanupFeature(  );
+    IndexCreationFeature indexCreationFeature = new IndexCreationFeature(  );
+    StagingRepositoryFeature stagingRepositoryFeature = new 
StagingRepositoryFeature( );
+
+
+    static final StandardCapabilities CAPABILITIES = new StandardCapabilities( 
new ReleaseScheme[] {
+        ReleaseScheme.RELEASE, ReleaseScheme.SNAPSHOT
+    }, new String[] {"default"}, new String[0], new String[] {
+        ArtifactCleanupFeature.class.toString(), 
IndexCreationFeature.class.toString(),
+        StagingRepositoryFeature.class.toString()
+    }, true, true, true, true, true  );
+
+    public BasicManagedRepository( String id, String name )
+    {
+        super( RepositoryType.MAVEN, id, name );
+        initFeatures();
+    }
+
+    public BasicManagedRepository( Locale primaryLocale, RepositoryType type, 
String id, String name )
+    {
+        super( primaryLocale, type, id, name );
+        initFeatures();
+    }
+
+    private void initFeatures() {
+        addFeature( artifactCleanupFeature );
+        addFeature( indexCreationFeature );
+        addFeature( stagingRepositoryFeature );
+    }
+
+    @Override
+    public boolean hasIndex( )
+    {
+        return true;
+    }
+
+    @Override
+    public RepositoryCapabilities getCapabilities( )
+    {
+        return CAPABILITIES;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/archiva/blob/d6e4a5b4/archiva-modules/archiva-base/archiva-repository-layer/src/main/java/org/apache/archiva/repository/BasicRemoteRepository.java
----------------------------------------------------------------------
diff --git 
a/archiva-modules/archiva-base/archiva-repository-layer/src/main/java/org/apache/archiva/repository/BasicRemoteRepository.java
 
b/archiva-modules/archiva-base/archiva-repository-layer/src/main/java/org/apache/archiva/repository/BasicRemoteRepository.java
new file mode 100644
index 0000000..d241854
--- /dev/null
+++ 
b/archiva-modules/archiva-base/archiva-repository-layer/src/main/java/org/apache/archiva/repository/BasicRemoteRepository.java
@@ -0,0 +1,73 @@
+package org.apache.archiva.repository;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import org.apache.archiva.repository.features.RemoteIndexFeature;
+
+import java.util.Locale;
+
+/**
+ *
+ * Just a helper class, mainly used for unit tests.
+ *
+ *
+ */
+public class BasicRemoteRepository extends AbstractRemoteRepository
+
+{
+    RemoteIndexFeature remoteIndexFeature = new RemoteIndexFeature();
+
+
+    static final StandardCapabilities CAPABILITIES = new StandardCapabilities( 
new ReleaseScheme[] {
+        ReleaseScheme.RELEASE, ReleaseScheme.SNAPSHOT
+    }, new String[] {"default"}, new String[0], new String[] {
+        RemoteIndexFeature.class.toString()
+    }, true, true, true, true, true  );
+
+    public BasicRemoteRepository( String id, String name )
+    {
+        super( RepositoryType.MAVEN, id, name );
+        initFeatures();
+    }
+
+    public BasicRemoteRepository( Locale primaryLocale, RepositoryType type, 
String id, String name )
+    {
+        super( primaryLocale, type, id, name );
+        initFeatures();
+    }
+
+    private void initFeatures() {
+        addFeature( remoteIndexFeature );
+    }
+
+    @Override
+    public boolean hasIndex( )
+    {
+        return true;
+    }
+
+    @Override
+    public RepositoryCapabilities getCapabilities( )
+    {
+        return CAPABILITIES;
+    }
+
+
+}

http://git-wip-us.apache.org/repos/asf/archiva/blob/d6e4a5b4/archiva-modules/archiva-base/archiva-repository-layer/src/main/java/org/apache/archiva/repository/ManagedRepositoryContent.java
----------------------------------------------------------------------
diff --git 
a/archiva-modules/archiva-base/archiva-repository-layer/src/main/java/org/apache/archiva/repository/ManagedRepositoryContent.java
 
b/archiva-modules/archiva-base/archiva-repository-layer/src/main/java/org/apache/archiva/repository/ManagedRepositoryContent.java
index 643f3e9..c209c38 100644
--- 
a/archiva-modules/archiva-base/archiva-repository-layer/src/main/java/org/apache/archiva/repository/ManagedRepositoryContent.java
+++ 
b/archiva-modules/archiva-base/archiva-repository-layer/src/main/java/org/apache/archiva/repository/ManagedRepositoryContent.java
@@ -19,7 +19,6 @@ package org.apache.archiva.repository;
  * under the License.
  */
 
-import org.apache.archiva.admin.model.beans.ManagedRepository;
 import org.apache.archiva.model.ArchivaArtifact;
 import org.apache.archiva.model.ArtifactReference;
 import org.apache.archiva.model.ProjectReference;
@@ -118,7 +117,7 @@ public interface ManagedRepositoryContent
      *
      * @return the repository that is associated with this repository content.
      */
-    ManagedRepository getRepository();
+    org.apache.archiva.repository.ManagedRepository getRepository();
 
     /**
      * Given a specific {@link ProjectReference}, return the list of available 
versions for
@@ -178,7 +177,7 @@ public interface ManagedRepositoryContent
      *
      * @param repo the repository to associate with this repository content.
      */
-    void setRepository( ManagedRepository repo );
+    void setRepository( org.apache.archiva.repository.ManagedRepository repo );
 
     /**
      * Given a repository relative path to a filename, return the {@link 
VersionedReference} object suitable for the path.

http://git-wip-us.apache.org/repos/asf/archiva/blob/d6e4a5b4/archiva-modules/archiva-base/archiva-repository-layer/src/main/java/org/apache/archiva/repository/PasswordCredentials.java
----------------------------------------------------------------------
diff --git 
a/archiva-modules/archiva-base/archiva-repository-layer/src/main/java/org/apache/archiva/repository/PasswordCredentials.java
 
b/archiva-modules/archiva-base/archiva-repository-layer/src/main/java/org/apache/archiva/repository/PasswordCredentials.java
index 44b087b..97ed05c 100644
--- 
a/archiva-modules/archiva-base/archiva-repository-layer/src/main/java/org/apache/archiva/repository/PasswordCredentials.java
+++ 
b/archiva-modules/archiva-base/archiva-repository-layer/src/main/java/org/apache/archiva/repository/PasswordCredentials.java
@@ -27,6 +27,11 @@ public class PasswordCredentials implements 
RepositoryCredentials
     String username;
     char[] password;
 
+    public PasswordCredentials(String username, char[] password) {
+        this.username = username;
+        this.password = password;
+    }
+
     public String getUsername( )
     {
         return username;

http://git-wip-us.apache.org/repos/asf/archiva/blob/d6e4a5b4/archiva-modules/archiva-base/archiva-repository-layer/src/main/java/org/apache/archiva/repository/RemoteRepositoryContent.java
----------------------------------------------------------------------
diff --git 
a/archiva-modules/archiva-base/archiva-repository-layer/src/main/java/org/apache/archiva/repository/RemoteRepositoryContent.java
 
b/archiva-modules/archiva-base/archiva-repository-layer/src/main/java/org/apache/archiva/repository/RemoteRepositoryContent.java
index b4d7709..6745dd8 100644
--- 
a/archiva-modules/archiva-base/archiva-repository-layer/src/main/java/org/apache/archiva/repository/RemoteRepositoryContent.java
+++ 
b/archiva-modules/archiva-base/archiva-repository-layer/src/main/java/org/apache/archiva/repository/RemoteRepositoryContent.java
@@ -19,7 +19,6 @@ package org.apache.archiva.repository;
  * under the License.
  */
 
-import org.apache.archiva.admin.model.beans.RemoteRepository;
 import org.apache.archiva.model.ArtifactReference;
 import org.apache.archiva.model.RepositoryURL;
 import org.apache.archiva.repository.layout.LayoutException;

http://git-wip-us.apache.org/repos/asf/archiva/blob/d6e4a5b4/archiva-modules/archiva-base/archiva-repository-layer/src/main/java/org/apache/archiva/repository/RepositoryContentFactory.java
----------------------------------------------------------------------
diff --git 
a/archiva-modules/archiva-base/archiva-repository-layer/src/main/java/org/apache/archiva/repository/RepositoryContentFactory.java
 
b/archiva-modules/archiva-base/archiva-repository-layer/src/main/java/org/apache/archiva/repository/RepositoryContentFactory.java
index 85ed80f..5547458 100644
--- 
a/archiva-modules/archiva-base/archiva-repository-layer/src/main/java/org/apache/archiva/repository/RepositoryContentFactory.java
+++ 
b/archiva-modules/archiva-base/archiva-repository-layer/src/main/java/org/apache/archiva/repository/RepositoryContentFactory.java
@@ -19,13 +19,10 @@ package org.apache.archiva.repository;
  * under the License.
  */
 
-import org.apache.archiva.admin.model.RepositoryAdminException;
-import org.apache.archiva.admin.model.beans.ManagedRepository;
-import org.apache.archiva.admin.model.beans.RemoteRepository;
-import org.apache.archiva.admin.model.managed.ManagedRepositoryAdmin;
-import org.apache.archiva.admin.model.remote.RemoteRepositoryAdmin;
 import org.apache.archiva.configuration.ArchivaConfiguration;
 import org.apache.archiva.configuration.ConfigurationNames;
+import org.apache.archiva.configuration.ManagedRepositoryConfiguration;
+import org.apache.archiva.configuration.RemoteRepositoryConfiguration;
 import org.apache.archiva.redback.components.registry.Registry;
 import org.apache.archiva.redback.components.registry.RegistryListener;
 import org.springframework.context.ApplicationContext;
@@ -38,8 +35,6 @@ import java.util.concurrent.ConcurrentHashMap;
 
 /**
  * RepositoryContentRequest
- *
- *
  */
 @Service( "repositoryContentFactory#default" )
 public class RepositoryContentFactory
@@ -52,12 +47,6 @@ public class RepositoryContentFactory
     private ArchivaConfiguration archivaConfiguration;
 
     @Inject
-    private ManagedRepositoryAdmin managedRepositoryAdmin;
-
-    @Inject
-    private RemoteRepositoryAdmin remoteRepositoryAdmin;
-
-    @Inject
     private ApplicationContext applicationContext;
 
     private final Map<String, ManagedRepositoryContent> managedContentMap;
@@ -65,10 +54,10 @@ public class RepositoryContentFactory
     private final Map<String, RemoteRepositoryContent> remoteContentMap;
 
 
-    public RepositoryContentFactory()
+    public RepositoryContentFactory( )
     {
-        managedContentMap = new ConcurrentHashMap<String, 
ManagedRepositoryContent>();
-        remoteContentMap = new ConcurrentHashMap<String, 
RemoteRepositoryContent>();
+        managedContentMap = new ConcurrentHashMap<String, 
ManagedRepositoryContent>( );
+        remoteContentMap = new ConcurrentHashMap<String, 
RemoteRepositoryContent>( );
     }
 
     /**
@@ -82,65 +71,86 @@ public class RepositoryContentFactory
     public ManagedRepositoryContent getManagedRepositoryContent( String repoId 
)
         throws RepositoryNotFoundException, RepositoryException
     {
-        try
-        {
-            ManagedRepositoryContent repo = managedContentMap.get( repoId );
-
-            if ( repo != null )
-            {
-                return repo;
-            }
-
-            ManagedRepository repoConfig = 
managedRepositoryAdmin.getManagedRepository( repoId );
-            if ( repoConfig == null )
-            {
-                throw new RepositoryNotFoundException(
-                    "Unable to find managed repository configuration for id:" 
+ repoId );
-            }
-
-            repo = applicationContext.getBean( "managedRepositoryContent#" + 
repoConfig.getLayout(),
-                                               ManagedRepositoryContent.class 
);
-            repo.setRepository( repoConfig );
-            managedContentMap.put( repoId, repo );
+        ManagedRepositoryContent repo = managedContentMap.get( repoId );
 
+        if ( repo != null )
+        {
             return repo;
         }
-        catch ( RepositoryAdminException e )
+        else
         {
-            throw new RepositoryException( e.getMessage(), e );
+            throw new RepositoryNotFoundException(
+                "Unable to find managed repository configuration for id " + 
repoId );
         }
+
     }
 
-    public RemoteRepositoryContent getRemoteRepositoryContent( String repoId )
+    public ManagedRepositoryContent getManagedRepositoryContent( 
ManagedRepositoryConfiguration repoConfig, 
org.apache.archiva.repository.ManagedRepository mRepo )
         throws RepositoryNotFoundException, RepositoryException
     {
-        try
+        ManagedRepositoryContent repo = managedContentMap.get( 
repoConfig.getId( ) );
+
+        if ( repo != null && repo.getRepository()==mRepo)
         {
-            RemoteRepositoryContent repo = remoteContentMap.get( repoId );
+            return repo;
+        }
 
-            if ( repo != null )
-            {
-                return repo;
+        repo = applicationContext.getBean( "managedRepositoryContent#" + 
repoConfig.getLayout( ),
+            ManagedRepositoryContent.class );
+        repo.setRepository( mRepo );
+        ManagedRepositoryContent previousRepo = managedContentMap.put( 
repoConfig.getId( ), repo );
+        if (previousRepo!=null) {
+            ManagedRepository previousMRepo = previousRepo.getRepository( );
+            if (previousMRepo!=null && previousMRepo instanceof 
EditableManagedRepository) {
+                ((EditableManagedRepository)previousMRepo).setContent( null );
             }
+            previousRepo.setRepository( null );
+        }
 
-            RemoteRepository repoConfig = 
remoteRepositoryAdmin.getRemoteRepository( repoId );
-            if ( repoConfig == null )
-            {
-                throw new RepositoryNotFoundException(
-                    "Unable to find remote repository configuration for id:" + 
repoId );
-            }
+        return repo;
+    }
 
-            repo = applicationContext.getBean( "remoteRepositoryContent#" + 
repoConfig.getLayout(),
-                                               RemoteRepositoryContent.class );
-            repo.setRepository( repoConfig );
-            remoteContentMap.put( repoId, repo );
+    public RemoteRepositoryContent getRemoteRepositoryContent( String repoId )
+        throws RepositoryNotFoundException, RepositoryException
+    {
+        RemoteRepositoryContent repo = remoteContentMap.get( repoId );
 
+        if ( repo != null )
+        {
             return repo;
         }
-        catch ( RepositoryAdminException e )
+        else
         {
-            throw new RepositoryException( e.getMessage(), e );
+            throw new RepositoryNotFoundException(
+                "Unable to find remote repository configuration for id:" + 
repoId );
         }
+
+    }
+
+    public RemoteRepositoryContent getRemoteRepositoryContent( 
RemoteRepositoryConfiguration repoConfig, RemoteRepository mRepo )
+        throws RepositoryNotFoundException, RepositoryException
+    {
+        RemoteRepositoryContent repo = remoteContentMap.get( repoConfig.getId( 
) );
+
+        if ( repo != null && repo.getRepository()==mRepo)
+        {
+            return repo;
+        }
+
+        repo = applicationContext.getBean( "remoteRepositoryContent#" + 
repoConfig.getLayout( ),
+            RemoteRepositoryContent.class );
+        repo.setRepository( mRepo );
+        RemoteRepositoryContent previousRepo = remoteContentMap.put( 
repoConfig.getId( ), repo );
+        if (previousRepo!=null) {
+            RemoteRepository previousMRepo = previousRepo.getRepository( );
+            if (previousMRepo!=null && previousMRepo instanceof 
EditableRemoteRepository) {
+                ((EditableRemoteRepository)previousMRepo).setContent( null );
+            }
+            previousRepo.setRepository( null );
+        }
+
+
+        return repo;
     }
 
 
@@ -150,7 +160,7 @@ public class RepositoryContentFactory
         if ( ConfigurationNames.isManagedRepositories( propertyName ) || 
ConfigurationNames.isRemoteRepositories(
             propertyName ) )
         {
-            initMaps();
+            initMaps( );
         }
     }
 
@@ -161,26 +171,26 @@ public class RepositoryContentFactory
     }
 
     @PostConstruct
-    public void initialize()
+    public void initialize( )
     {
         archivaConfiguration.addChangeListener( this );
     }
 
-    private void initMaps()
+    private void initMaps( )
     {
         // olamy we use concurent so no need of synchronize
         //synchronized ( managedContentMap )
         //{
-        managedContentMap.clear();
+        managedContentMap.clear( );
         //}
 
         //synchronized ( remoteContentMap )
         //{
-        remoteContentMap.clear();
+        remoteContentMap.clear( );
         //}
     }
 
-    public ArchivaConfiguration getArchivaConfiguration()
+    public ArchivaConfiguration getArchivaConfiguration( )
     {
         return archivaConfiguration;
     }

http://git-wip-us.apache.org/repos/asf/archiva/blob/d6e4a5b4/archiva-modules/archiva-base/archiva-repository-layer/src/main/java/org/apache/archiva/repository/RepositoryProvider.java
----------------------------------------------------------------------
diff --git 
a/archiva-modules/archiva-base/archiva-repository-layer/src/main/java/org/apache/archiva/repository/RepositoryProvider.java
 
b/archiva-modules/archiva-base/archiva-repository-layer/src/main/java/org/apache/archiva/repository/RepositoryProvider.java
index a45c05e..a501514 100644
--- 
a/archiva-modules/archiva-base/archiva-repository-layer/src/main/java/org/apache/archiva/repository/RepositoryProvider.java
+++ 
b/archiva-modules/archiva-base/archiva-repository-layer/src/main/java/org/apache/archiva/repository/RepositoryProvider.java
@@ -26,29 +26,114 @@ import java.util.Set;
 
 /**
  *
- * This interface must be implemented by the repository implementations. These
- * are responsible for creating the instances.
+ * This interface must be implemented by the repository implementations. The 
repository provider knows all
+ * about the repositories and should be the only part that uses the repository 
specific classes and libraries
+ * (e.g. the maven libraries).
+ *
+ * Newly created instances should always be filled with default values that 
make sense. null values should
+ * be avoided.
+ *
+ * References like staging repositories must not be set.
+ *
  *
  */
 public interface RepositoryProvider
 {
+
+    /**
+     * Returns the types of repositories this provider can handle.
+     *
+     * @return the set of supported repository types
+     */
     Set<RepositoryType> provides();
 
+    /**
+     * Creates a editable managed repository instance. The provider must not 
check the uniqueness of the
+     * id parameter and must not track the already created instances. Each 
call to this method will create
+     * a new instance.
+     *
+     * @param id the repository identifier
+     * @param name the repository name
+     * @return a new created managed repository instance
+     */
     EditableManagedRepository createManagedInstance(String id, String name);
 
+    /**
+     * Creates a editable remote repository instance. The provider must not 
check the uniqueness of the
+     * id parameter and must not track the already created instances. Each 
call to this method will create
+     * a new instance.
+     *
+     * @param id the repository identifier
+     * @param name the repository name
+     * @return a new created remote repository instance
+     */
     EditableRemoteRepository createRemoteInstance(String id, String name);
 
+    /**
+     * Creates a new managed repository instance from the given configuration. 
All attributes are filled from the
+     * provided configuration object.
+     *
+     * @param configuration the repository configuration that contains the 
repository data
+     * @return a new created managed repository instance
+     * @throws RepositoryException if some of the configuration values are not 
valid
+     */
     ManagedRepository createManagedInstance( ManagedRepositoryConfiguration 
configuration) throws RepositoryException;
 
+    /**
+     * Updates the given managed repository instance from the given 
configuration. All attributes are filled from the
+     * provided configuration object.
+     *
+     * @param repo the repository instance that should be updated
+     * @param configuration the repository configuration that contains the 
repository data
+     * @throws RepositoryException if some of the configuration values are not 
valid
+     */
     void updateManagedInstance( EditableManagedRepository repo, 
ManagedRepositoryConfiguration configuration) throws RepositoryException;
 
+    /**
+     * Creates a new managed staging repository instance from the given 
configuration. All attributes are filled from the
+     * provided configuration object.
+     *
+     * @param baseConfiguration the repository configuration of the base 
repository that references the staging repository
+     * @return a new created managed staging repository instance
+     * @throws RepositoryException if some of the configuration values are not 
valid
+     */
     ManagedRepository createStagingInstance(ManagedRepositoryConfiguration 
baseConfiguration) throws RepositoryException;
 
+    /**
+     * Creates a new remote repository instance from the given configuration. 
All attributes are filled from the
+     * provided configuration object.
+     *
+     * @param configuration the repository configuration that contains the 
repository data
+     * @return a new created remote repository instance
+     * @throws RepositoryException if some of the configuration values are not 
valid
+     */
     RemoteRepository createRemoteInstance( RemoteRepositoryConfiguration 
configuration) throws RepositoryException;
 
+    /**
+     * Updates the given remote repository instance from the given 
configuration. All attributes are filled from the
+     * provided configuration object.
+     *
+     * @param repo the repository instance that should be updated
+     * @param configuration the repository configuration that contains the 
repository data
+     * @throws RepositoryException if some of the configuration values are not 
valid
+     */
     void updateRemoteInstance(EditableRemoteRepository repo, 
RemoteRepositoryConfiguration configuration) throws RepositoryException;
 
+    /**
+     * Returns a configuration object from the given remote repository 
instance.
+     *
+     * @param remoteRepository the remote repository instance
+     * @return the repository configuration with all the data that is stored 
in the repository instance
+     * @throws RepositoryException if the data cannot be converted
+     */
     RemoteRepositoryConfiguration getRemoteConfiguration(RemoteRepository 
remoteRepository) throws RepositoryException;
 
+    /**
+     * Returns a configuration object from the given managed repository 
instance.
+     *
+     * @param managedRepository the managed repository instance
+     * @return the repository configuration with all the data that is stored 
in the repository instance
+     * @throws RepositoryException if the data cannot be converted
+     */
     ManagedRepositoryConfiguration getManagedConfiguration(ManagedRepository 
managedRepository) throws RepositoryException;
 }

http://git-wip-us.apache.org/repos/asf/archiva/blob/d6e4a5b4/archiva-modules/archiva-base/archiva-repository-layer/src/main/java/org/apache/archiva/repository/RepositoryRegistry.java
----------------------------------------------------------------------
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 a5f2f03..385cd16 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
@@ -27,6 +27,7 @@ import 
org.apache.archiva.configuration.IndeterminateConfigurationException;
 import org.apache.archiva.configuration.ManagedRepositoryConfiguration;
 import org.apache.archiva.configuration.RemoteRepositoryConfiguration;
 import org.apache.archiva.redback.components.registry.RegistryException;
+import org.apache.archiva.repository.features.ArtifactCleanupFeature;
 import org.apache.archiva.repository.features.StagingRepositoryFeature;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -34,6 +35,7 @@ import org.springframework.stereotype.Service;
 
 import javax.annotation.PostConstruct;
 import javax.inject.Inject;
+import javax.inject.Named;
 import java.util.Collection;
 import java.util.Collections;
 import java.util.HashMap;
@@ -50,6 +52,8 @@ import java.util.stream.Stream;
  *
  * The modification methods addXX and removeXX persist the changes immediately 
to the configuration. If the
  * configuration save fails the changes are rolled back.
+ *
+ * TODO: Audit events should be sent, but we don't want dependency to the 
repsitory-metadata-api
  */
 @Service( "repositoryRegistry" )
 public class RepositoryRegistry implements ConfigurationListener {
@@ -66,8 +70,11 @@ public class RepositoryRegistry implements 
ConfigurationListener {
     ArchivaConfiguration archivaConfiguration;
 
     @Inject
+    @Named("repositoryContentFactory#default")
     RepositoryContentFactory repositoryContentFactory;
 
+
+
     private Map<String, ManagedRepository> managedRepositories = new 
HashMap<>( );
     private Map<String, ManagedRepository> uManagedRepository = 
Collections.unmodifiableMap( managedRepositories );
 
@@ -76,6 +83,10 @@ public class RepositoryRegistry implements 
ConfigurationListener {
 
     private ReentrantReadWriteLock rwLock = new ReentrantReadWriteLock( );
 
+    public void setArchivaConfiguration( ArchivaConfiguration 
archivaConfiguration) {
+        this.archivaConfiguration = archivaConfiguration;
+    }
+
     @PostConstruct
     private void initialize( )
     {
@@ -158,29 +169,40 @@ public class RepositoryRegistry implements 
ConfigurationListener {
     private ManagedRepository createNewManagedRepository( RepositoryProvider 
provider, ManagedRepositoryConfiguration cfg ) throws RepositoryException
     {
         ManagedRepository repo = provider.createManagedInstance( cfg );
+        updateRepositoryReferences( provider, repo, cfg , null);
+        return repo;
+
+    }
+
+    private void updateRepositoryReferences(RepositoryProvider provider, 
ManagedRepository repo, ManagedRepositoryConfiguration cfg, Configuration 
configuration) throws RepositoryException
+    {
         if ( repo.supportsFeature( StagingRepositoryFeature.class ) )
         {
             StagingRepositoryFeature feature = repo.getFeature( 
StagingRepositoryFeature.class ).get( );
-            if ( feature.isStageRepoNeeded( ) )
+            if ( feature.isStageRepoNeeded( ) && 
feature.getStagingRepository() == null)
             {
-                ManagedRepository stageRepo = getStagingRepository( provider, 
cfg );
+                ManagedRepository stageRepo = getStagingRepository( provider, 
cfg, configuration);
+                managedRepositories.put(stageRepo.getId(), stageRepo);
                 feature.setStagingRepository( stageRepo );
+                if (configuration!=null) {
+                    replaceOrAddRepositoryConfig( 
provider.getManagedConfiguration( stageRepo ), configuration );
+                }
             }
         }
-        if ( repo instanceof EditableManagedRepository )
+        if ( repo instanceof EditableManagedRepository && repo.getContent() == 
null)
         {
-            ( (EditableManagedRepository) repo ).setContent( 
repositoryContentFactory.getManagedRepositoryContent( repo.getId( ) ) );
+            ( (EditableManagedRepository) repo ).setContent( 
repositoryContentFactory.getManagedRepositoryContent( cfg, repo ) );
         }
-        return repo;
-
     }
 
-    private ManagedRepository getStagingRepository(RepositoryProvider 
provider, ManagedRepositoryConfiguration baseRepoCfg ) throws 
RepositoryException
+    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 );
+            ManagedRepositoryConfiguration stageCfg = 
provider.getManagedConfiguration( stageRepo );
+            updateRepositoryReferences( provider, stageRepo, stageCfg, 
configuration);
         }
         return stageRepo;
     }
@@ -209,9 +231,12 @@ public class RepositoryRegistry implements 
ConfigurationListener {
                 RepositoryType repositoryType = RepositoryType.valueOf( 
repoConfig.getType( ) );
                 if ( providerMap.containsKey( repositoryType ) )
                 {
+                    RepositoryProvider provider = getProvider( repositoryType 
);
                     try
                     {
-                        remoteRepos.put( repoConfig.getId( ), providerMap.get( 
repositoryType ).createRemoteInstance( repoConfig ) );
+
+                        RemoteRepository remoteRepository = 
createNewRemoteRepository( provider, repoConfig );
+                        remoteRepos.put( repoConfig.getId( ), 
remoteRepository);
                     }
                     catch ( Exception e )
                     {
@@ -228,6 +253,22 @@ public class RepositoryRegistry implements 
ConfigurationListener {
         }
     }
 
+    private RemoteRepository createNewRemoteRepository( RepositoryProvider 
provider, RemoteRepositoryConfiguration cfg ) throws RepositoryException
+    {
+        RemoteRepository repo = provider.createRemoteInstance( cfg );
+        updateRepositoryReferences( provider, repo, cfg , null);
+        return repo;
+
+    }
+
+    private void updateRepositoryReferences( RepositoryProvider provider, 
RemoteRepository repo, RemoteRepositoryConfiguration cfg, Configuration 
configuration) throws RepositoryException
+    {
+        if ( repo instanceof EditableRemoteRepository && repo.getContent() == 
null)
+        {
+            ( (EditableRemoteRepository) repo ).setContent( 
repositoryContentFactory.getRemoteRepositoryContent( cfg, repo ) );
+        }
+    }
+
     private ArchivaConfiguration getArchivaConfiguration( )
     {
         return this.archivaConfiguration;
@@ -360,23 +401,30 @@ public class RepositoryRegistry implements 
ConfigurationListener {
      * @param managedRepository the new repository.
      * @throws RepositoryException if the new repository could not be saved to 
the configuration.
      */
-    public void putRepository( ManagedRepository managedRepository ) throws 
RepositoryException
+    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." );
+            }
+
             ManagedRepository originRepo = managedRepositories.put( id, 
managedRepository );
             try
             {
-                ManagedRepositoryConfiguration newCfg = getProvider( 
managedRepository.getType( ) ).getManagedConfiguration( managedRepository );
+                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 );
+                return managedRepository;
             }
             catch ( Exception e )
             {
@@ -387,7 +435,8 @@ public class RepositoryRegistry implements 
ConfigurationListener {
                 } else {
                     managedRepositories.remove(id);
                 }
-                throw new RepositoryException( "Could not save the 
configuration: " + e.getMessage( ) );
+                log.error("Exception during configuration update {}", 
e.getMessage(), e);
+                throw new RepositoryException( "Could not save the 
configuration" + (e.getMessage( )==null?"":": "+e.getMessage()) );
             }
         }
         finally
@@ -466,45 +515,55 @@ public class RepositoryRegistry implements 
ConfigurationListener {
                 repo = getProvider( repoType ).createManagedInstance( 
managedRepositoryConfiguration );
                 managedRepositories.put(id, repo);
             }
-            ManagedRepositoryConfiguration oldCfg;
-            if ((oldCfg = configuration.findManagedRepositoryById( id 
))!=null) {
-                configuration.removeManagedRepository( oldCfg );
-            }
-            configuration.addManagedRepository( managedRepositoryConfiguration 
);
+            updateRepositoryReferences( getProvider( repoType  ), repo, 
managedRepositoryConfiguration, configuration );
+            replaceOrAddRepositoryConfig( managedRepositoryConfiguration, 
configuration );
             return repo;
         }
         finally
         {
             rwLock.writeLock( ).unlock( );
         }
+    }
 
+    private void replaceOrAddRepositoryConfig(ManagedRepositoryConfiguration 
managedRepositoryConfiguration, Configuration configuration) {
+        ManagedRepositoryConfiguration oldCfg = 
configuration.findManagedRepositoryById( managedRepositoryConfiguration.getId() 
);
+        if ( oldCfg !=null) {
+            configuration.removeManagedRepository( oldCfg );
+        }
+        configuration.addManagedRepository( managedRepositoryConfiguration );
+    }
 
+    private void replaceOrAddRepositoryConfig(RemoteRepositoryConfiguration 
remoteRepositoryConfiguration, Configuration configuration) {
+        RemoteRepositoryConfiguration oldCfg = 
configuration.findRemoteRepositoryById( remoteRepositoryConfiguration.getId() );
+        if ( oldCfg !=null) {
+            configuration.removeRemoteRepository( oldCfg );
+        }
+        configuration.addRemoteRepository( remoteRepositoryConfiguration );
     }
 
-    /**
-     * Adds a remote repository, or overwrites the repository definition with 
the same id, if it exists already.
-     * The modification is saved to the configuration immediately.
-     *
-     * @param remoteRepository the remote repository to add
-     * @throws RepositoryException if an error occurs during configuration save
-     */
-    public void putRepository( RemoteRepository remoteRepository ) throws 
RepositoryException
+    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." );
+            }
             RemoteRepository originRepo = remoteRepositories.put( id, 
remoteRepository );
+            RemoteRepositoryConfiguration oldCfg=null;
+            RemoteRepositoryConfiguration newCfg=null;
             try
             {
-                RemoteRepositoryConfiguration newCfg = getProvider( 
remoteRepository.getType( ) ).getRemoteConfiguration( remoteRepository );
-                Configuration configuration = getArchivaConfiguration( 
).getConfiguration( );
-                RemoteRepositoryConfiguration oldCfg = 
configuration.findRemoteRepositoryById( id );
+                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 );
-                getArchivaConfiguration( ).save( configuration );
+                return remoteRepository;
             }
             catch ( Exception e )
             {
@@ -515,7 +574,46 @@ public class RepositoryRegistry implements 
ConfigurationListener {
                 } else {
                     remoteRepositories.remove( id);
                 }
-                throw new RepositoryException( "Could not save the 
configuration: " + e.getMessage( ) );
+                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()) );
+            }
+        }
+        finally
+        {
+            rwLock.writeLock( ).unlock( );
+        }
+    }
+
+    /**
+     * Adds a remote repository, or overwrites the repository definition with 
the same id, if it exists already.
+     * The modification is saved to the configuration immediately.
+     *
+     * @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
+        {
+            Configuration configuration = 
getArchivaConfiguration().getConfiguration();
+            try
+            {
+                RemoteRepository repo = putRepository( remoteRepository, 
configuration );
+                getArchivaConfiguration().save(configuration);
+                return repo;
+            }
+            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()) );
             }
         }
         finally
@@ -594,11 +692,8 @@ public class RepositoryRegistry implements 
ConfigurationListener {
                 repo = getProvider( repoType ).createRemoteInstance( 
remoteRepositoryConfiguration );
                 remoteRepositories.put(id, repo);
             }
-            RemoteRepositoryConfiguration oldCfg;
-            if ((oldCfg = configuration.findRemoteRepositoryById( id ))!=null) 
{
-                configuration.removeRemoteRepository( oldCfg );
-            }
-            configuration.addRemoteRepository( remoteRepositoryConfiguration );
+            updateRepositoryReferences( getProvider( repoType  ), repo, 
remoteRepositoryConfiguration, configuration );
+            replaceOrAddRepositoryConfig( remoteRepositoryConfiguration, 
configuration );
             return repo;
         }
         finally
@@ -609,6 +704,17 @@ public class RepositoryRegistry implements 
ConfigurationListener {
 
     }
 
+    public void removeRepository(Repository repo) throws RepositoryException
+    {
+        if (repo instanceof RemoteRepository ) {
+            removeRepository( (RemoteRepository)repo );
+        } else if (repo instanceof ManagedRepository) {
+            removeRepository( (ManagedRepository)repo);
+        } else {
+            throw new RepositoryException( "Repository type not known: 
"+repo.getClass() );
+        }
+    }
+
     /**
      * Removes a managed repository from the registry and configuration, if it 
exists.
      * The change is saved to the configuration immediately.
@@ -648,6 +754,29 @@ public class RepositoryRegistry implements 
ConfigurationListener {
         }
     }
 
+    public void removeRepository(ManagedRepository managedRepository, 
Configuration configuration) throws RepositoryException
+    {
+        final String id = managedRepository.getId();
+        ManagedRepository repo = getManagedRepository( id );
+        if (repo!=null) {
+            rwLock.writeLock().lock();
+            try {
+                repo = managedRepositories.remove( id );
+                if (repo!=null) {
+                    ManagedRepositoryConfiguration cfg = 
configuration.findManagedRepositoryById( id );
+                    if (cfg!=null) {
+                        configuration.removeManagedRepository( cfg );
+                    }
+                }
+            }
+            finally
+            {
+                rwLock.writeLock().unlock();
+            }
+        }
+
+    }
+
     /**
      * Removes the remote repository from the registry and configuration.
      * The change is saved to the configuration immediately.
@@ -687,6 +816,29 @@ public class RepositoryRegistry implements 
ConfigurationListener {
         }
     }
 
+    public void removeRepository( RemoteRepository remoteRepository, 
Configuration configuration) throws RepositoryException
+    {
+        final String id = remoteRepository.getId();
+        RemoteRepository repo = getRemoteRepository( id );
+        if (repo!=null) {
+            rwLock.writeLock().lock();
+            try {
+                repo = remoteRepositories.remove( id );
+                if (repo!=null) {
+                    RemoteRepositoryConfiguration cfg = 
configuration.findRemoteRepositoryById( id );
+                    if (cfg!=null) {
+                        configuration.removeRemoteRepository( cfg );
+                    }
+                }
+            }
+            finally
+            {
+                rwLock.writeLock().unlock();
+            }
+        }
+
+    }
+
     /**
      * Reloads the registry from the configuration.
      */
@@ -715,7 +867,7 @@ public class RepositoryRegistry implements 
ConfigurationListener {
     }
 
     public <T extends Repository> Repository clone(T repo, String newId) 
throws RepositoryException {
-        if (repo instanceof RemoteRepository) {
+        if (repo instanceof RemoteRepository ) {
             return this.clone((RemoteRepository)repo, newId);
         } else if (repo instanceof ManagedRepository) {
             return this.clone((ManagedRepository)repo, newId);
@@ -731,7 +883,7 @@ public class RepositoryRegistry implements 
ConfigurationListener {
      * @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);
@@ -743,13 +895,6 @@ public class RepositoryRegistry implements 
ConfigurationListener {
         return cloned;
     }
 
-    public EditableManagedRepository createNewManaged(RepositoryType type, 
String id, String name) throws RepositoryException {
-        return getProvider(type).createManagedInstance(id, name);
-    }
-
-    public EditableRemoteRepository createNewRemote(RepositoryType type, 
String id, String name) throws RepositoryException {
-        return getProvider(type).createRemoteInstance(id, name);
-    }
 
     @Override
     public void configurationEvent(ConfigurationEvent event) {

http://git-wip-us.apache.org/repos/asf/archiva/blob/d6e4a5b4/archiva-modules/archiva-base/archiva-repository-layer/src/main/java/org/apache/archiva/repository/features/ArtifactCleanupFeature.java
----------------------------------------------------------------------
diff --git 
a/archiva-modules/archiva-base/archiva-repository-layer/src/main/java/org/apache/archiva/repository/features/ArtifactCleanupFeature.java
 
b/archiva-modules/archiva-base/archiva-repository-layer/src/main/java/org/apache/archiva/repository/features/ArtifactCleanupFeature.java
index 0243ff4..57c6830 100644
--- 
a/archiva-modules/archiva-base/archiva-repository-layer/src/main/java/org/apache/archiva/repository/features/ArtifactCleanupFeature.java
+++ 
b/archiva-modules/archiva-base/archiva-repository-layer/src/main/java/org/apache/archiva/repository/features/ArtifactCleanupFeature.java
@@ -30,16 +30,16 @@ import java.time.Period;
 public class ArtifactCleanupFeature implements 
RepositoryFeature<ArtifactCleanupFeature> {
 
     private boolean deleteReleasedSnapshots = false;
-    private Period retentionTime = Period.ofDays(100);
+    private Period retentionPeriod = Period.ofDays(100);
     private int retentionCount = 2;
 
     public ArtifactCleanupFeature() {
 
     }
 
-    public ArtifactCleanupFeature(boolean deleteReleasedSnapshots, Period 
retentionTime, int retentionCount) {
+    public ArtifactCleanupFeature( boolean deleteReleasedSnapshots, Period 
retentionPeriod, int retentionCount) {
         this.deleteReleasedSnapshots = deleteReleasedSnapshots;
-        this.retentionTime = retentionTime;
+        this.retentionPeriod = retentionPeriod;
         this.retentionCount = retentionCount;
     }
 
@@ -70,16 +70,16 @@ public class ArtifactCleanupFeature implements 
RepositoryFeature<ArtifactCleanup
      *
      * @return The time period after that the artifacts can be deleted.
      */
-    public Period getRetentionTime() {
-        return retentionTime;
+    public Period getRetentionPeriod() {
+        return retentionPeriod;
     }
 
     /**
      * Sets time period, after that artifacts can be deleted.
-     * @param retentionTime
+     * @param retentionPeriod
      */
-    public void setRetentionTime(Period retentionTime) {
-        this.retentionTime = retentionTime;
+    public void setRetentionPeriod( Period retentionPeriod ) {
+        this.retentionPeriod = retentionPeriod;
     }
 
     /**

http://git-wip-us.apache.org/repos/asf/archiva/blob/d6e4a5b4/archiva-modules/archiva-base/archiva-repository-layer/src/main/java/org/apache/archiva/repository/features/IndexCreationFeature.java
----------------------------------------------------------------------
diff --git 
a/archiva-modules/archiva-base/archiva-repository-layer/src/main/java/org/apache/archiva/repository/features/IndexCreationFeature.java
 
b/archiva-modules/archiva-base/archiva-repository-layer/src/main/java/org/apache/archiva/repository/features/IndexCreationFeature.java
index 276232e..9c6b70c 100644
--- 
a/archiva-modules/archiva-base/archiva-repository-layer/src/main/java/org/apache/archiva/repository/features/IndexCreationFeature.java
+++ 
b/archiva-modules/archiva-base/archiva-repository-layer/src/main/java/org/apache/archiva/repository/features/IndexCreationFeature.java
@@ -23,6 +23,7 @@ package org.apache.archiva.repository.features;
 import org.apache.commons.lang.StringUtils;
 
 import java.net.URI;
+import java.net.URISyntaxException;
 
 /**
  *
@@ -36,7 +37,15 @@ public class IndexCreationFeature implements 
RepositoryFeature<IndexCreationFeat
     private URI indexPath;
 
     public IndexCreationFeature() {
-
+        try
+        {
+            this.indexPath = new URI(".indexer");
+        }
+        catch ( URISyntaxException e )
+        {
+            // This may not happen.
+            e.printStackTrace( );
+        }
     }
 
     public IndexCreationFeature(boolean skipPackedIndexCreation) {

http://git-wip-us.apache.org/repos/asf/archiva/blob/d6e4a5b4/archiva-modules/archiva-base/archiva-repository-layer/src/main/test/java/org/apache/archiva/repository/RepositoryRegistryTest.java
----------------------------------------------------------------------
diff --git 
a/archiva-modules/archiva-base/archiva-repository-layer/src/main/test/java/org/apache/archiva/repository/RepositoryRegistryTest.java
 
b/archiva-modules/archiva-base/archiva-repository-layer/src/main/test/java/org/apache/archiva/repository/RepositoryRegistryTest.java
new file mode 100644
index 0000000..01dcbd2
--- /dev/null
+++ 
b/archiva-modules/archiva-base/archiva-repository-layer/src/main/test/java/org/apache/archiva/repository/RepositoryRegistryTest.java
@@ -0,0 +1,511 @@
+package org.apache.archiva.repository;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import org.apache.archiva.configuration.ArchivaConfiguration;
+import org.apache.archiva.configuration.Configuration;
+import org.apache.archiva.configuration.ManagedRepositoryConfiguration;
+import org.apache.archiva.configuration.RemoteRepositoryConfiguration;
+import org.apache.archiva.test.utils.ArchivaSpringJUnit4ClassRunner;
+import org.junit.After;
+import org.junit.AfterClass;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.springframework.test.context.ContextConfiguration;
+
+import javax.inject.Inject;
+import java.io.IOException;
+import java.net.URISyntaxException;
+import java.net.URL;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.nio.file.StandardCopyOption;
+import java.util.Collection;
+
+import static org.junit.Assert.*;
+
+/**
+ * Test for RepositoryRegistry
+ */
+@RunWith(ArchivaSpringJUnit4ClassRunner.class)
+@ContextConfiguration(locations = { "classpath*:/META-INF/spring-context.xml", 
"classpath:/spring-context.xml" })
+public class RepositoryRegistryTest
+{
+
+    @Inject
+    RepositoryRegistry repositoryRegistry;
+
+    @Inject
+    ArchivaConfiguration archivaConfiguration;
+
+    private static final Path userCfg = Paths.get(System.getProperty( 
"user.home" ), ".m2/archiva.xml");
+
+    private static Path cfgCopy;
+    private static Path archivaCfg;
+
+    @BeforeClass
+    public static void classSetup() throws IOException, URISyntaxException
+    {
+        URL archivaCfgUri = 
Thread.currentThread().getContextClassLoader().getResource( "archiva.xml" );
+        if (archivaCfgUri!=null) {
+            archivaCfg = Paths.get(archivaCfgUri.toURI());
+            cfgCopy = Files.createTempFile( "archiva-backup", ".xml" );
+            Files.copy( archivaCfg, cfgCopy, 
StandardCopyOption.REPLACE_EXISTING);
+        }
+    }
+
+    @AfterClass
+    public static void classTearDown() throws IOException
+    {
+        if (cfgCopy!=null) {
+            Files.deleteIfExists( cfgCopy );
+        }
+    }
+
+    @Before
+    public void setUp( ) throws Exception
+    {
+        assertNotNull( repositoryRegistry );
+        Files.deleteIfExists( userCfg );
+        URL archivaCfgUri = 
Thread.currentThread().getContextClassLoader().getResource( "archiva.xml" );
+        if (archivaCfgUri!=null) {
+            archivaCfg = Paths.get(archivaCfgUri.toURI());
+            if (Files.exists(cfgCopy))
+            {
+                Files.copy( cfgCopy, archivaCfg , 
StandardCopyOption.REPLACE_EXISTING);
+            }
+        }
+        archivaConfiguration.reload();
+        repositoryRegistry.reload();
+    }
+
+    @After
+    public void tearDown( ) throws Exception
+    {
+        Files.deleteIfExists( userCfg );
+        if (cfgCopy!=null && Files.exists(cfgCopy)) {
+            Files.copy(cfgCopy, archivaCfg, 
StandardCopyOption.REPLACE_EXISTING);
+        }
+    }
+
+    @Test
+    public void getRepositories( ) throws Exception
+    {
+        Collection<Repository> repos = repositoryRegistry.getRepositories( );
+        assertEquals( 5, repos.size( ) );
+        assertTrue(repos.stream().anyMatch( rep -> 
rep.getId().equals("internal") ));
+        assertTrue( repos.stream( ).anyMatch( rep -> rep.getId( ).equals( 
"snapshots") ) );
+        assertTrue(repos.stream().anyMatch( rep -> rep.getId().equals( 
"central") ));
+    }
+
+    @Test
+    public void getManagedRepositories( ) throws Exception
+    {
+        Collection<ManagedRepository> repos = 
repositoryRegistry.getManagedRepositories();
+        assertEquals( 4, repos.size( ) );
+        assertTrue(repos.stream().anyMatch( rep -> 
rep.getId().equals("internal") ));
+        assertTrue( repos.stream( ).anyMatch( rep -> rep.getId( ).equals( 
"snapshots") ) );
+    }
+
+    @Test
+    public void getRemoteRepositories( ) throws Exception
+    {
+        Collection<RemoteRepository> repos = 
repositoryRegistry.getRemoteRepositories( );
+        assertEquals( 1, repos.size( ) );
+        assertTrue(repos.stream().anyMatch( rep -> rep.getId().equals( 
"central") ));
+    }
+
+    @Test
+    public void getRepository( ) throws Exception
+    {
+        Repository repo = repositoryRegistry.getRepository( "internal" );
+        assertNotNull(repo);
+        assertEquals("internal", repo.getId());
+        assertEquals("Archiva Managed Internal Repository", repo.getName());
+        assertEquals("This is internal repository.", repo.getDescription());
+        assertEquals( "default", repo.getLayout( ) );
+        assertEquals("0 0 * * * ?", repo.getSchedulingDefinition());
+        assertTrue(repo instanceof ManagedRepository);
+        assertTrue( repo.hasIndex( ) );
+        assertTrue(repo.isScanned());
+        assertEquals(RepositoryType.MAVEN, repo.getType());
+    }
+
+    @Test
+    public void getManagedRepository( ) throws Exception
+    {
+        ManagedRepository repo = repositoryRegistry.getManagedRepository( 
"internal" );
+        assertNotNull(repo);
+        assertEquals("internal", repo.getId());
+        assertEquals("Archiva Managed Internal Repository", repo.getName());
+        assertEquals("This is internal repository.", repo.getDescription());
+        assertEquals( "default", repo.getLayout( ) );
+        assertEquals("0 0 * * * ?", repo.getSchedulingDefinition());
+        assertTrue( repo.hasIndex( ) );
+        assertTrue(repo.isScanned());
+        assertEquals(RepositoryType.MAVEN, repo.getType());
+        
assertTrue(repo.getActiveReleaseSchemes().contains(ReleaseScheme.RELEASE));
+        assertFalse( repo.getActiveReleaseSchemes( ).contains( 
ReleaseScheme.SNAPSHOT ) );
+        assertNotNull(repo.getContent());
+
+        assertNull(repositoryRegistry.getManagedRepository( "xyu" ));
+
+    }
+
+    @Test
+    public void getRemoteRepository( ) throws Exception
+    {
+        RemoteRepository repo = repositoryRegistry.getRemoteRepository( 
"central" );
+        assertNotNull(repo);
+        assertEquals("central", repo.getId());
+        assertEquals("Central Repository", repo.getName());
+        assertEquals("", repo.getDescription());
+        assertEquals( "default", repo.getLayout( ) );
+        assertEquals("0 0 08 ? * SUN", repo.getSchedulingDefinition());
+        assertTrue( repo.hasIndex( ) );
+        assertTrue(repo.isScanned());
+        assertEquals(RepositoryType.MAVEN, repo.getType());
+
+        assertEquals(35, repo.getTimeout().getSeconds());
+    }
+
+    @Test
+    public void putManagedRepository( ) throws Exception
+    {
+        BasicManagedRepository managedRepository = new BasicManagedRepository( 
"test001", "Test repo" );
+        managedRepository.setDescription( 
managedRepository.getPrimaryLocale(), "This is just a test" );
+        repositoryRegistry.putRepository(managedRepository);
+
+        assertNotNull(managedRepository.getContent());
+        assertEquals(6, repositoryRegistry.getRepositories().size());
+
+        managedRepository = new BasicManagedRepository( "central", "Test repo" 
);
+        managedRepository.setDescription( 
managedRepository.getPrimaryLocale(), "This is just a test" );
+        ManagedRepository updatedRepo = null;
+        try {
+            repositoryRegistry.putRepository( managedRepository );
+            throw new RuntimeException("Repository exception should be thrown, 
if there exists a remote repository already with that id");
+        } catch (RepositoryException e) {
+            // OK
+        }
+        managedRepository = new BasicManagedRepository( "internal", "Test 
repo" );
+        managedRepository.setDescription( 
managedRepository.getPrimaryLocale(), "This is just a test" );
+        updatedRepo = repositoryRegistry.putRepository( managedRepository );
+
+        assertTrue(updatedRepo==managedRepository);
+        assertNotNull(managedRepository.getContent());
+        assertEquals(6, repositoryRegistry.getRepositories().size());
+        ManagedRepository managedRepository1 = 
repositoryRegistry.getManagedRepository( "internal" );
+        assertEquals("Test repo", managedRepository1.getName());
+        assertTrue(managedRepository1==managedRepository);
+
+    }
+
+    @Test
+    public void putManagedRepositoryFromConfig( ) throws Exception
+    {
+        ManagedRepositoryConfiguration cfg = new 
ManagedRepositoryConfiguration();
+        cfg.setId("test002");
+        cfg.setName("This is test 002");
+        ManagedRepository repo = repositoryRegistry.putRepository( cfg );
+        assertNotNull(repo);
+        assertEquals("test002", repo.getId());
+        assertEquals("This is test 002", repo.getName());
+        assertNotNull(repo.getContent());
+        archivaConfiguration.reload();
+        Collection<ManagedRepository> repos = 
repositoryRegistry.getManagedRepositories();
+        assertEquals(5, repos.size());
+
+        ManagedRepository internalRepo = 
repositoryRegistry.getManagedRepository( "internal" );
+        cfg = new ManagedRepositoryConfiguration();
+        cfg.setId("internal");
+        cfg.setName("This is internal test 002");
+        repo = repositoryRegistry.putRepository( cfg );
+        assertTrue(internalRepo==repo);
+        assertEquals("This is internal test 002",repo.getName());
+        assertEquals(5, repositoryRegistry.getManagedRepositories().size());
+
+        repositoryRegistry.reload();
+        assertEquals(5, repositoryRegistry.getManagedRepositories().size());
+
+    }
+
+    @Test
+    public void putManagedRepositoryFromConfigWithoutSave( ) throws Exception
+    {
+        Configuration configuration = archivaConfiguration.getConfiguration();
+        ManagedRepositoryConfiguration cfg = new 
ManagedRepositoryConfiguration();
+        cfg.setId("test002");
+        cfg.setName("This is test 002");
+        ManagedRepository repo = repositoryRegistry.putRepository( cfg, 
configuration );
+        assertNotNull(repo);
+        assertEquals("test002", repo.getId());
+        assertEquals("This is test 002", repo.getName());
+        assertNotNull(repo.getContent());
+        archivaConfiguration.reload();
+        assertEquals(3, 
archivaConfiguration.getConfiguration().getManagedRepositories().size());
+        Collection<ManagedRepository> repos = 
repositoryRegistry.getManagedRepositories();
+        assertEquals(5, repos.size());
+
+        ManagedRepository internalRepo = 
repositoryRegistry.getManagedRepository( "internal" );
+        cfg = new ManagedRepositoryConfiguration();
+        cfg.setId("internal");
+        cfg.setName("This is internal test 002");
+        repo = repositoryRegistry.putRepository( cfg, configuration );
+        assertTrue(internalRepo==repo);
+        assertEquals("This is internal test 002",repo.getName());
+        assertEquals(5, repositoryRegistry.getManagedRepositories().size());
+
+        repositoryRegistry.reload();
+        assertEquals(4, repositoryRegistry.getManagedRepositories().size());
+    }
+
+    @Test
+    public void putRemoteRepository( ) throws Exception
+    {
+        BasicRemoteRepository remoteRepository = new BasicRemoteRepository( 
"test001", "Test repo" );
+        remoteRepository.setDescription( remoteRepository.getPrimaryLocale(), 
"This is just a test" );
+        RemoteRepository newRepo = 
repositoryRegistry.putRepository(remoteRepository);
+
+        assertTrue(remoteRepository==newRepo);
+        assertNotNull(remoteRepository.getContent());
+        assertEquals(6, repositoryRegistry.getRepositories().size());
+
+        remoteRepository = new BasicRemoteRepository( "internal", "Test repo" 
);
+        remoteRepository.setDescription( remoteRepository.getPrimaryLocale(), 
"This is just a test" );
+        RemoteRepository updatedRepo = null;
+        try
+        {
+            updatedRepo = repositoryRegistry.putRepository( remoteRepository );
+            throw new RuntimeException("Should throw repository exception, if 
repository exists already and is not the same type.");
+        } catch (RepositoryException e) {
+            // OK
+        }
+
+        remoteRepository = new BasicRemoteRepository( "central", "Test repo" );
+        remoteRepository.setDescription( remoteRepository.getPrimaryLocale(), 
"This is just a test" );
+        updatedRepo = repositoryRegistry.putRepository( remoteRepository );
+
+        assertTrue(updatedRepo==remoteRepository);
+        assertNotNull(remoteRepository.getContent());
+        assertEquals(6, repositoryRegistry.getRepositories().size());
+        RemoteRepository remoteRepository1 = 
repositoryRegistry.getRemoteRepository( "central" );
+        assertEquals("Test repo", remoteRepository1.getName());
+        assertTrue(remoteRepository1==remoteRepository);
+    }
+
+    @Test
+    public void putRemoteRepositoryFromConfig( ) throws Exception
+    {
+        RemoteRepositoryConfiguration cfg = new 
RemoteRepositoryConfiguration();
+        cfg.setId("test002");
+        cfg.setName("This is test 002");
+        RemoteRepository repo = repositoryRegistry.putRepository( cfg );
+        assertNotNull(repo);
+        assertEquals("test002", repo.getId());
+        assertEquals("This is test 002", repo.getName());
+        assertNotNull(repo.getContent());
+        archivaConfiguration.reload();
+        Collection<RemoteRepository> repos = 
repositoryRegistry.getRemoteRepositories();
+        assertEquals(2, repos.size());
+
+        RemoteRepository internalRepo = 
repositoryRegistry.getRemoteRepository( "central" );
+        cfg = new RemoteRepositoryConfiguration();
+        cfg.setId("central");
+        cfg.setName("This is central test 002");
+        repo = repositoryRegistry.putRepository( cfg );
+        assertTrue(internalRepo==repo);
+        assertEquals("This is central test 002",repo.getName());
+        assertEquals(2, repositoryRegistry.getRemoteRepositories().size());
+
+        repositoryRegistry.reload();
+        assertEquals(2, repositoryRegistry.getRemoteRepositories().size());
+    }
+
+    @Test
+    public void putRemoteRepositoryFromConfigWithoutSave( ) throws Exception
+    {
+        Configuration configuration = archivaConfiguration.getConfiguration();
+        RemoteRepositoryConfiguration cfg = new 
RemoteRepositoryConfiguration();
+        cfg.setId("test002");
+        cfg.setName("This is test 002");
+        RemoteRepository repo = repositoryRegistry.putRepository( cfg, 
configuration );
+        assertNotNull(repo);
+        assertEquals("test002", repo.getId());
+        assertEquals("This is test 002", repo.getName());
+        assertNotNull(repo.getContent());
+        archivaConfiguration.reload();
+        assertEquals(1, 
archivaConfiguration.getConfiguration().getRemoteRepositories().size());
+        Collection<RemoteRepository> repos = 
repositoryRegistry.getRemoteRepositories();
+        assertEquals(2, repos.size());
+
+        RemoteRepository internalRepo = 
repositoryRegistry.getRemoteRepository( "central" );
+        cfg = new RemoteRepositoryConfiguration();
+        cfg.setId("central");
+        cfg.setName("This is central test 002");
+        repo = repositoryRegistry.putRepository( cfg, configuration );
+        assertTrue(internalRepo==repo);
+        assertEquals("This is central test 002",repo.getName());
+        assertEquals(2, repositoryRegistry.getRemoteRepositories().size());
+
+        repositoryRegistry.reload();
+        assertEquals(1, repositoryRegistry.getRemoteRepositories().size());
+    }
+
+    @Test
+    public void removeRepository( ) throws Exception
+    {
+        assertEquals(5, repositoryRegistry.getRepositories().size());
+        Repository repo = repositoryRegistry.getRepository( "snapshots" );
+        repositoryRegistry.removeRepository( repo );
+        assertEquals(4, repositoryRegistry.getRepositories().size());
+        assertTrue( repositoryRegistry.getRepositories( ).stream( ).noneMatch( 
rep -> rep.getId( ).equals( "snapshots" ) ) );
+        archivaConfiguration.reload();
+        repositoryRegistry.reload();
+        assertEquals(4, repositoryRegistry.getRepositories().size());
+    }
+
+    @Test
+    public void removeManagedRepository( ) throws Exception
+    {
+
+        assertEquals(4, repositoryRegistry.getManagedRepositories().size());
+        ManagedRepository repo = repositoryRegistry.getManagedRepository( 
"snapshots" );
+        repositoryRegistry.removeRepository( repo );
+        assertEquals(3, repositoryRegistry.getManagedRepositories().size());
+        assertTrue( repositoryRegistry.getManagedRepositories( ).stream( 
).noneMatch( rep -> rep.getId( ).equals( "snapshots" ) ) );
+        archivaConfiguration.reload();
+        repositoryRegistry.reload();
+        assertEquals(3, repositoryRegistry.getManagedRepositories().size());
+    }
+
+    @Test
+    public void removeManagedRepositoryWithoutSave( ) throws Exception
+    {
+        Configuration configuration = archivaConfiguration.getConfiguration();
+        assertEquals(4, repositoryRegistry.getManagedRepositories().size());
+        ManagedRepository repo = repositoryRegistry.getManagedRepository( 
"snapshots" );
+        repositoryRegistry.removeRepository( repo, configuration );
+        assertEquals(3, repositoryRegistry.getManagedRepositories().size());
+        assertTrue( repositoryRegistry.getManagedRepositories( ).stream( 
).noneMatch( rep -> rep.getId( ).equals( "snapshots" ) ) );
+        archivaConfiguration.reload();
+        repositoryRegistry.reload();
+        assertEquals(4, repositoryRegistry.getManagedRepositories().size());
+    }
+
+
+    @Test
+    public void removeRemoteRepository( ) throws Exception
+    {
+        assertEquals(1, repositoryRegistry.getRemoteRepositories().size());
+        RemoteRepository repo = repositoryRegistry.getRemoteRepository( 
"central" );
+        repositoryRegistry.removeRepository( repo );
+        assertEquals(0, repositoryRegistry.getRemoteRepositories().size());
+        assertTrue( repositoryRegistry.getRemoteRepositories( ).stream( 
).noneMatch( rep -> rep.getId( ).equals( "central" ) ) );
+        archivaConfiguration.reload();
+        repositoryRegistry.reload();
+        assertEquals(0, repositoryRegistry.getRemoteRepositories().size());
+    }
+
+    @Test
+    public void removeRemoteRepositoryWithoutSave( ) throws Exception
+    {
+        Configuration configuration = archivaConfiguration.getConfiguration();
+        assertEquals(1, repositoryRegistry.getRemoteRepositories().size());
+        RemoteRepository repo = repositoryRegistry.getRemoteRepository( 
"central" );
+        repositoryRegistry.removeRepository( repo, configuration );
+        assertEquals(0, repositoryRegistry.getRemoteRepositories().size());
+        assertTrue( repositoryRegistry.getRemoteRepositories( ).stream( 
).noneMatch( rep -> rep.getId( ).equals( "central" ) ) );
+        archivaConfiguration.reload();
+        repositoryRegistry.reload();
+        assertEquals(1, repositoryRegistry.getRemoteRepositories().size());
+    }
+
+
+    @Test
+    public void cloneManagedRepo( ) throws Exception
+    {
+        ManagedRepository managedRepository = 
repositoryRegistry.getManagedRepository( "internal" );
+
+        try
+        {
+            repositoryRegistry.clone(managedRepository, "snapshots");
+            throw new RuntimeException("RepositoryRegistry exception should be 
thrown if id exists already.");
+        }
+        catch ( RepositoryException e )
+        {
+            // OK
+        }
+
+        try
+        {
+            repositoryRegistry.clone(managedRepository, "central");
+            throw new RuntimeException("RepositoryRegistry exception should be 
thrown if id exists already.");
+        }
+        catch ( RepositoryException e )
+        {
+            // OK
+        }
+
+        ManagedRepository clone = repositoryRegistry.clone( managedRepository, 
"newinternal" );
+        assertNotNull(clone);
+        assertNull(clone.getContent());
+        assertEquals("Archiva Managed Internal Repository", clone.getName());
+        assertFalse(managedRepository==clone);
+
+    }
+
+    @Test
+    public void cloneRemoteRepo( ) throws Exception
+    {
+        RemoteRepository remoteRepository = 
repositoryRegistry.getRemoteRepository( "central" );
+
+        try
+        {
+            repositoryRegistry.clone(remoteRepository, "snapshots");
+            throw new RuntimeException("RepositoryRegistry exception should be 
thrown if id exists already.");
+        }
+        catch ( RepositoryException e )
+        {
+            // OK
+        }
+
+        try
+        {
+            repositoryRegistry.clone(remoteRepository, "central");
+            throw new RuntimeException("RepositoryRegistry exception should be 
thrown if id exists already.");
+        }
+        catch ( RepositoryException e )
+        {
+            // OK
+        }
+
+        RemoteRepository clone = repositoryRegistry.clone( remoteRepository, 
"newCentral" );
+        assertNotNull(clone);
+        assertNull(clone.getContent());
+        assertEquals("Central Repository", clone.getName());
+        assertFalse(remoteRepository==clone);
+
+    }
+
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/archiva/blob/d6e4a5b4/archiva-modules/archiva-base/archiva-repository-layer/src/main/test/java/org/apache/archiva/repository/mock/ManagedRepositoryContentMock.java
----------------------------------------------------------------------
diff --git 
a/archiva-modules/archiva-base/archiva-repository-layer/src/main/test/java/org/apache/archiva/repository/mock/ManagedRepositoryContentMock.java
 
b/archiva-modules/archiva-base/archiva-repository-layer/src/main/test/java/org/apache/archiva/repository/mock/ManagedRepositoryContentMock.java
new file mode 100644
index 0000000..1fb6133
--- /dev/null
+++ 
b/archiva-modules/archiva-base/archiva-repository-layer/src/main/test/java/org/apache/archiva/repository/mock/ManagedRepositoryContentMock.java
@@ -0,0 +1,169 @@
+package org.apache.archiva.repository.mock;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import org.apache.archiva.model.ArchivaArtifact;
+import org.apache.archiva.model.ArtifactReference;
+import org.apache.archiva.model.ProjectReference;
+import org.apache.archiva.model.VersionedReference;
+import org.apache.archiva.repository.ContentNotFoundException;
+import org.apache.archiva.repository.ManagedRepository;
+import org.apache.archiva.repository.ManagedRepositoryContent;
+import org.apache.archiva.repository.RepositoryException;
+import org.apache.archiva.repository.layout.LayoutException;
+import org.springframework.stereotype.Service;
+
+import java.nio.file.Path;
+import java.util.Set;
+
+/**
+ * @author Martin Stockhammer <[email protected]>
+ */
+@Service("managedRepositoryContent#mock")
+public class ManagedRepositoryContentMock implements ManagedRepositoryContent
+{
+    private ManagedRepository repository;
+
+    @Override
+    public void deleteVersion( VersionedReference reference ) throws 
ContentNotFoundException
+    {
+
+    }
+
+    @Override
+    public void deleteArtifact( ArtifactReference artifactReference ) throws 
ContentNotFoundException
+    {
+
+    }
+
+    @Override
+    public void deleteGroupId( String groupId ) throws ContentNotFoundException
+    {
+
+    }
+
+    @Override
+    public void deleteProject( String namespace, String projectId ) throws 
RepositoryException
+    {
+
+    }
+
+    @Override
+    public String getId( )
+    {
+        return null;
+    }
+
+    @Override
+    public Set<ArtifactReference> getRelatedArtifacts( ArtifactReference 
reference ) throws ContentNotFoundException
+    {
+        return null;
+    }
+
+    @Override
+    public String getRepoRoot( )
+    {
+        return null;
+    }
+
+    @Override
+    public ManagedRepository getRepository( )
+    {
+        return repository;
+    }
+
+    @Override
+    public Set<String> getVersions( ProjectReference reference ) throws 
ContentNotFoundException, LayoutException
+    {
+        return null;
+    }
+
+    @Override
+    public Set<String> getVersions( VersionedReference reference ) throws 
ContentNotFoundException
+    {
+        return null;
+    }
+
+    @Override
+    public boolean hasContent( ArtifactReference reference )
+    {
+        return false;
+    }
+
+    @Override
+    public boolean hasContent( ProjectReference reference )
+    {
+        return false;
+    }
+
+    @Override
+    public boolean hasContent( VersionedReference reference )
+    {
+        return false;
+    }
+
+    @Override
+    public void setRepository( ManagedRepository repo )
+    {
+        this.repository = repo;
+    }
+
+    @Override
+    public ArtifactReference toArtifactReference( String path ) throws 
LayoutException
+    {
+        return null;
+    }
+
+    @Override
+    public Path toFile( ArtifactReference reference )
+    {
+        return null;
+    }
+
+    @Override
+    public Path toFile( ArchivaArtifact reference )
+    {
+        return null;
+    }
+
+    @Override
+    public String toMetadataPath( ProjectReference reference )
+    {
+        return null;
+    }
+
+    @Override
+    public String toMetadataPath( VersionedReference reference )
+    {
+        return null;
+    }
+
+    @Override
+    public String toPath( ArtifactReference reference )
+    {
+        return null;
+    }
+
+    @Override
+    public String toPath( ArchivaArtifact reference )
+    {
+        return null;
+    }
+}

http://git-wip-us.apache.org/repos/asf/archiva/blob/d6e4a5b4/archiva-modules/archiva-base/archiva-repository-layer/src/main/test/java/org/apache/archiva/repository/mock/RemoteRepositoryContentMock.java
----------------------------------------------------------------------
diff --git 
a/archiva-modules/archiva-base/archiva-repository-layer/src/main/test/java/org/apache/archiva/repository/mock/RemoteRepositoryContentMock.java
 
b/archiva-modules/archiva-base/archiva-repository-layer/src/main/test/java/org/apache/archiva/repository/mock/RemoteRepositoryContentMock.java
new file mode 100644
index 0000000..238b0cf
--- /dev/null
+++ 
b/archiva-modules/archiva-base/archiva-repository-layer/src/main/test/java/org/apache/archiva/repository/mock/RemoteRepositoryContentMock.java
@@ -0,0 +1,78 @@
+package org.apache.archiva.repository.mock;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import org.apache.archiva.model.ArtifactReference;
+import org.apache.archiva.model.RepositoryURL;
+import org.apache.archiva.repository.RemoteRepository;
+import org.apache.archiva.repository.RemoteRepositoryContent;
+import org.apache.archiva.repository.layout.LayoutException;
+import org.springframework.stereotype.Service;
+
+/**
+ * @author Martin Stockhammer <[email protected]>
+ */
+@Service("remoteRepositoryContent#mock")
+public class RemoteRepositoryContentMock implements RemoteRepositoryContent
+{
+    RemoteRepository repository;
+
+    @Override
+    public String getId( )
+    {
+        return null;
+    }
+
+    @Override
+    public RemoteRepository getRepository( )
+    {
+        return null;
+    }
+
+    @Override
+    public RepositoryURL getURL( )
+    {
+        return null;
+    }
+
+    @Override
+    public void setRepository( RemoteRepository repo )
+    {
+        this.repository = repo;
+    }
+
+    @Override
+    public ArtifactReference toArtifactReference( String path ) throws 
LayoutException
+    {
+        return null;
+    }
+
+    @Override
+    public String toPath( ArtifactReference reference )
+    {
+        return null;
+    }
+
+    @Override
+    public RepositoryURL toURL( ArtifactReference reference )
+    {
+        return null;
+    }
+}

Reply via email to