You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@archiva.apache.org by oc...@apache.org on 2010/10/01 05:50:05 UTC

svn commit: r1003378 - in /archiva/trunk: ./ archiva-modules/archiva-web/archiva-webapp/src/main/java/org/apache/maven/archiva/web/action/ archiva-modules/archiva-web/archiva-webapp/src/main/webapp/WEB-INF/ archiva-modules/archiva-web/archiva-xmlrpc/ar...

Author: oching
Date: Fri Oct  1 03:50:04 2010
New Revision: 1003378

URL: http://svn.apache.org/viewvc?rev=1003378&view=rev
Log:
[MRM-1409] web services for repository merge
submitted by Gwen Harold Autencio

Modified:
    archiva/trunk/archiva-modules/archiva-web/archiva-webapp/src/main/java/org/apache/maven/archiva/web/action/MergeAction.java
    archiva/trunk/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/WEB-INF/applicationContext.xml
    archiva/trunk/archiva-modules/archiva-web/archiva-xmlrpc/archiva-xmlrpc-api/pom.xml
    archiva/trunk/archiva-modules/archiva-web/archiva-xmlrpc/archiva-xmlrpc-api/src/main/java/org/apache/archiva/web/xmlrpc/api/AdministrationService.java
    archiva/trunk/archiva-modules/archiva-web/archiva-xmlrpc/archiva-xmlrpc-security/src/main/java/org/apache/archiva/web/xmlrpc/security/ServiceMethodsPermissionsMapping.java
    archiva/trunk/archiva-modules/archiva-web/archiva-xmlrpc/archiva-xmlrpc-services/pom.xml
    archiva/trunk/archiva-modules/archiva-web/archiva-xmlrpc/archiva-xmlrpc-services/src/main/java/org/apache/archiva/web/xmlrpc/services/AdministrationServiceImpl.java
    archiva/trunk/archiva-modules/archiva-web/archiva-xmlrpc/archiva-xmlrpc-services/src/test/java/org/apache/archiva/web/xmlrpc/services/AdministrationServiceImplTest.java
    archiva/trunk/archiva-modules/plugins/audit/src/main/java/org/apache/archiva/audit/AuditEvent.java
    archiva/trunk/archiva-modules/plugins/stage-repository-merge/src/main/java/org/apache/archiva/stagerepository/merge/Maven2RepositoryMerger.java
    archiva/trunk/archiva-modules/plugins/stage-repository-merge/src/main/java/org/apache/archiva/stagerepository/merge/RepositoryMerger.java
    archiva/trunk/archiva-modules/plugins/stage-repository-merge/src/test/java/org/apache/archiva/stagerepository/merge/Maven2RepositoryMergerTest.java
    archiva/trunk/pom.xml

Modified: archiva/trunk/archiva-modules/archiva-web/archiva-webapp/src/main/java/org/apache/maven/archiva/web/action/MergeAction.java
URL: http://svn.apache.org/viewvc/archiva/trunk/archiva-modules/archiva-web/archiva-webapp/src/main/java/org/apache/maven/archiva/web/action/MergeAction.java?rev=1003378&r1=1003377&r2=1003378&view=diff
==============================================================================
--- archiva/trunk/archiva-modules/archiva-web/archiva-webapp/src/main/java/org/apache/maven/archiva/web/action/MergeAction.java (original)
+++ archiva/trunk/archiva-modules/archiva-web/archiva-webapp/src/main/java/org/apache/maven/archiva/web/action/MergeAction.java Fri Oct  1 03:50:04 2010
@@ -167,14 +167,14 @@ public class
         }
     }
 
-    public String mergeWithOutConlficts()
+    public String mergeWithOutConlficts()        
     {
 
         sourceRepoId = repoid + "-stage";
 
         try
         {
-            conflictSourceArtifacts = repositoryMerger.getConflictsartifacts( sourceRepoId, repoid );
+            conflictSourceArtifacts = repositoryMerger.getConflictingArtifacts( sourceRepoId, repoid );
         }
         catch ( Exception e )
         {
@@ -201,7 +201,7 @@ public class
         throws Exception
     {
         sourceRepoId = repoid + "-stage";
-        conflictSourceArtifacts = repositoryMerger.getConflictsartifacts( sourceRepoId, repoid );
+        conflictSourceArtifacts = repositoryMerger.getConflictingArtifacts( sourceRepoId, repoid );
         this.scheduler.setRepoid( repoid );
         
         Configuration config = archivaConfiguration.getConfiguration();

Modified: archiva/trunk/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/WEB-INF/applicationContext.xml
URL: http://svn.apache.org/viewvc/archiva/trunk/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/WEB-INF/applicationContext.xml?rev=1003378&r1=1003377&r2=1003378&view=diff
==============================================================================
--- archiva/trunk/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/WEB-INF/applicationContext.xml (original)
+++ archiva/trunk/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/WEB-INF/applicationContext.xml Fri Oct  1 03:50:04 2010
@@ -57,7 +57,10 @@
     <constructor-arg>
       <bean class="org.apache.archiva.web.spring.RepositoryListenerFactoryBean" />
     </constructor-arg>       
-    <constructor-arg ref="repositoryStatisticsManager"/>    
+    <constructor-arg ref="repositoryStatisticsManager"/>
+    <constructor-arg ref="repositoryMerger#maven2"/>
+    <constructor-arg ref="auditListener#logging"/>
+       
   </bean> 
 
   <bean name="xmlrpcServicesList" lazy-init="true" scope="singleton" class="java.util.ArrayList">

Modified: archiva/trunk/archiva-modules/archiva-web/archiva-xmlrpc/archiva-xmlrpc-api/pom.xml
URL: http://svn.apache.org/viewvc/archiva/trunk/archiva-modules/archiva-web/archiva-xmlrpc/archiva-xmlrpc-api/pom.xml?rev=1003378&r1=1003377&r2=1003378&view=diff
==============================================================================
--- archiva/trunk/archiva-modules/archiva-web/archiva-xmlrpc/archiva-xmlrpc-api/pom.xml (original)
+++ archiva/trunk/archiva-modules/archiva-web/archiva-xmlrpc/archiva-xmlrpc-api/pom.xml Fri Oct  1 03:50:04 2010
@@ -14,6 +14,10 @@
       <artifactId>archiva-indexer</artifactId>
     </dependency>
     <dependency>
+      <groupId>org.apache.archiva</groupId>
+      <artifactId>stage-repository-merge</artifactId>
+    </dependency>
+    <dependency>
       <groupId>com.atlassian.xmlrpc</groupId>
       <artifactId>atlassian-xmlrpc-binder-annotations</artifactId>
     </dependency>

Modified: archiva/trunk/archiva-modules/archiva-web/archiva-xmlrpc/archiva-xmlrpc-api/src/main/java/org/apache/archiva/web/xmlrpc/api/AdministrationService.java
URL: http://svn.apache.org/viewvc/archiva/trunk/archiva-modules/archiva-web/archiva-xmlrpc/archiva-xmlrpc-api/src/main/java/org/apache/archiva/web/xmlrpc/api/AdministrationService.java?rev=1003378&r1=1003377&r2=1003378&view=diff
==============================================================================
--- archiva/trunk/archiva-modules/archiva-web/archiva-xmlrpc/archiva-xmlrpc-api/src/main/java/org/apache/archiva/web/xmlrpc/api/AdministrationService.java (original)
+++ archiva/trunk/archiva-modules/archiva-web/archiva-xmlrpc/archiva-xmlrpc-api/src/main/java/org/apache/archiva/web/xmlrpc/api/AdministrationService.java Fri Oct  1 03:50:04 2010
@@ -24,7 +24,6 @@ import java.util.List;
 import com.atlassian.xmlrpc.ServiceObject;
 import org.apache.archiva.web.xmlrpc.api.beans.ManagedRepository;
 import org.apache.archiva.web.xmlrpc.api.beans.RemoteRepository;
-import org.apache.maven.archiva.configuration.ManagedRepositoryConfiguration;
 
 @ServiceObject( "AdministrationService" )
 public interface AdministrationService
@@ -125,4 +124,14 @@ public interface AdministrationService
     // consider the following as additional services:
     // - getAllConfiguredRepositoryConsumers( String repoId ) - list all enabled consumers for the repo
     // - getAllConfiguredDatabaseConsumers() - list all enabled db consumers
+
+    /**
+     * Merge staging repository with the managed repository and skips if there are conflicts
+     * @param repoId
+     * @param skipConflicts
+     * @return
+     * @throws Exception
+     */
+    public boolean merge( String repoId, boolean skipConflicts ) throws Exception;
+   
 }

Modified: archiva/trunk/archiva-modules/archiva-web/archiva-xmlrpc/archiva-xmlrpc-security/src/main/java/org/apache/archiva/web/xmlrpc/security/ServiceMethodsPermissionsMapping.java
URL: http://svn.apache.org/viewvc/archiva/trunk/archiva-modules/archiva-web/archiva-xmlrpc/archiva-xmlrpc-security/src/main/java/org/apache/archiva/web/xmlrpc/security/ServiceMethodsPermissionsMapping.java?rev=1003378&r1=1003377&r2=1003378&view=diff
==============================================================================
--- archiva/trunk/archiva-modules/archiva-web/archiva-xmlrpc/archiva-xmlrpc-security/src/main/java/org/apache/archiva/web/xmlrpc/security/ServiceMethodsPermissionsMapping.java (original)
+++ archiva/trunk/archiva-modules/archiva-web/archiva-xmlrpc/archiva-xmlrpc-security/src/main/java/org/apache/archiva/web/xmlrpc/security/ServiceMethodsPermissionsMapping.java Fri Oct  1 03:50:04 2010
@@ -42,7 +42,8 @@ public class ServiceMethodsPermissionsMa
                        "AdministrationService.getAllRepositoryConsumers", 
                        "AdministrationService.deleteArtifact", 
                        "AdministrationService.addManagedRepository",
-                       "AdministrationService.deleteManagedRepository", "AdministrationService.getManagedRepository" );
+                       "AdministrationService.deleteManagedRepository", "AdministrationService.getManagedRepository",
+                       "AdministrationService.merge");
 
     public static final List<String> SERVICE_METHODS_FOR_OPERATION_RUN_INDEXER =
         Arrays.asList( "AdministrationService.executeRepositoryScanner" );

Modified: archiva/trunk/archiva-modules/archiva-web/archiva-xmlrpc/archiva-xmlrpc-services/pom.xml
URL: http://svn.apache.org/viewvc/archiva/trunk/archiva-modules/archiva-web/archiva-xmlrpc/archiva-xmlrpc-services/pom.xml?rev=1003378&r1=1003377&r2=1003378&view=diff
==============================================================================
--- archiva/trunk/archiva-modules/archiva-web/archiva-xmlrpc/archiva-xmlrpc-services/pom.xml (original)
+++ archiva/trunk/archiva-modules/archiva-web/archiva-xmlrpc/archiva-xmlrpc-services/pom.xml Fri Oct  1 03:50:04 2010
@@ -48,6 +48,10 @@
     </dependency>
     <dependency>
       <groupId>org.apache.archiva</groupId>
+      <artifactId>audit</artifactId>
+    </dependency>    
+    <dependency>
+      <groupId>org.apache.archiva</groupId>
       <artifactId>archiva-repository-scanner</artifactId>
     </dependency>
     <dependency>
@@ -79,6 +83,6 @@
       <groupId>org.slf4j</groupId>
       <artifactId>slf4j-simple</artifactId>
       <scope>test</scope>
-    </dependency>
+    </dependency>    
   </dependencies>
 </project>

Modified: archiva/trunk/archiva-modules/archiva-web/archiva-xmlrpc/archiva-xmlrpc-services/src/main/java/org/apache/archiva/web/xmlrpc/services/AdministrationServiceImpl.java
URL: http://svn.apache.org/viewvc/archiva/trunk/archiva-modules/archiva-web/archiva-xmlrpc/archiva-xmlrpc-services/src/main/java/org/apache/archiva/web/xmlrpc/services/AdministrationServiceImpl.java?rev=1003378&r1=1003377&r2=1003378&view=diff
==============================================================================
--- archiva/trunk/archiva-modules/archiva-web/archiva-xmlrpc/archiva-xmlrpc-services/src/main/java/org/apache/archiva/web/xmlrpc/services/AdministrationServiceImpl.java (original)
+++ archiva/trunk/archiva-modules/archiva-web/archiva-xmlrpc/archiva-xmlrpc-services/src/main/java/org/apache/archiva/web/xmlrpc/services/AdministrationServiceImpl.java Fri Oct  1 03:50:04 2010
@@ -19,13 +19,26 @@ package org.apache.archiva.web.xmlrpc.se
  * under the License.
  */
 
+import java.io.File;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Date;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.archiva.audit.AuditEvent;
+import org.apache.archiva.audit.AuditListener;
 import org.apache.archiva.metadata.model.ArtifactMetadata;
 import org.apache.archiva.metadata.repository.MetadataRepository;
+import org.apache.archiva.metadata.repository.filter.Filter;
+import org.apache.archiva.metadata.repository.filter.IncludesFilter;
 import org.apache.archiva.metadata.repository.stats.RepositoryStatisticsManager;
 import org.apache.archiva.repository.events.RepositoryListener;
 import org.apache.archiva.repository.scanner.RepositoryContentConsumers;
 import org.apache.archiva.scheduler.repository.RepositoryArchivaTaskScheduler;
 import org.apache.archiva.scheduler.repository.RepositoryTask;
+import org.apache.archiva.stagerepository.merge.RepositoryMerger;
 import org.apache.archiva.web.xmlrpc.api.AdministrationService;
 import org.apache.archiva.web.xmlrpc.api.beans.ManagedRepository;
 import org.apache.archiva.web.xmlrpc.api.beans.RemoteRepository;
@@ -46,20 +59,11 @@ import org.apache.maven.archiva.reposito
 import org.apache.maven.archiva.repository.RepositoryContentFactory;
 import org.apache.maven.archiva.repository.RepositoryException;
 import org.apache.maven.archiva.repository.RepositoryNotFoundException;
-import org.apache.maven.archiva.security.ArchivaRoleConstants;
-import org.codehaus.plexus.redback.role.RoleManager;
 import org.codehaus.plexus.registry.RegistryException;
 import org.codehaus.plexus.scheduler.CronExpressionValidator;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-import java.io.File;
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.List;
-import java.util.Map;
-
 /**
  * AdministrationServiceImpl
  * 
@@ -83,12 +87,19 @@ public class AdministrationServiceImpl
     private MetadataRepository metadataRepository;
 
     private RepositoryStatisticsManager repositoryStatisticsManager;
+    
+    private RepositoryMerger repositoryMerger;
+    
+    private static final String STAGE = "-stage";
+    
+    private AuditListener auditListener;
 
     public AdministrationServiceImpl( ArchivaConfiguration archivaConfig, RepositoryContentConsumers repoConsumersUtil,
                                       RepositoryContentFactory repoFactory, MetadataRepository metadataRepository,
                                       RepositoryArchivaTaskScheduler repositoryTaskScheduler,
                                       Collection<RepositoryListener> listeners,
-                                      RepositoryStatisticsManager repositoryStatisticsManager )
+                                      RepositoryStatisticsManager repositoryStatisticsManager, RepositoryMerger repositoryMerger,
+                                      AuditListener auditListener )
     {
         this.archivaConfiguration = archivaConfig;
         this.repoConsumersUtil = repoConsumersUtil;
@@ -97,6 +108,8 @@ public class AdministrationServiceImpl
         this.listeners = listeners;
         this.metadataRepository = metadataRepository;
         this.repositoryStatisticsManager = repositoryStatisticsManager;
+        this.repositoryMerger = repositoryMerger;
+        this.auditListener = auditListener;
     }
 
     /**
@@ -459,4 +472,111 @@ public class AdministrationServiceImpl
         return repo;
     }
 
+    public boolean merge( String repoId, boolean skipConflicts )
+        throws Exception
+    {
+        String stagingId = repoId + STAGE;
+        ManagedRepositoryConfiguration repoConfig;
+        ManagedRepositoryConfiguration stagingConfig;
+        
+        Configuration config = archivaConfiguration.getConfiguration();
+        repoConfig = config.findManagedRepositoryById( repoId );
+
+        if( repoConfig != null )
+        { 
+            stagingConfig = config.findManagedRepositoryById( stagingId );
+            
+            if( stagingConfig != null )
+            {
+                List<ArtifactMetadata> sourceArtifacts = metadataRepository.getArtifacts( stagingId );
+                
+                if( repoConfig.isReleases() && !repoConfig.isSnapshots() )
+                {
+                    if( skipConflicts )
+                    {        
+                        List<ArtifactMetadata> conflicts = repositoryMerger.getConflictingArtifacts( stagingId, stagingId );
+                        sourceArtifacts.removeAll( conflicts );
+                        mergeWithOutSnapshots( sourceArtifacts, stagingId, repoId );
+                    }
+                    else
+                    {
+                        mergeWithOutSnapshots( sourceArtifacts, stagingId, repoId );    
+                    }       
+                }
+                else
+                {
+                    if( skipConflicts )
+                    {
+                        List<ArtifactMetadata> conflicts = repositoryMerger.getConflictingArtifacts( stagingId, stagingId );
+                        sourceArtifacts.removeAll( conflicts );
+                        Filter<ArtifactMetadata> artifactsWithOutConflicts = new IncludesFilter<ArtifactMetadata>( sourceArtifacts );
+                        repositoryMerger.merge( stagingId, repoId, artifactsWithOutConflicts );   
+                    }
+                    else
+                    {
+                        repositoryMerger.merge( stagingId, repoId );    
+                    }
+                }
+            }
+            else
+            {
+                throw new Exception( "Staging Id : " + stagingId + " not found." );
+            }
+        }
+        else
+        {
+            throw new Exception( "Repository Id : " + repoId + " not found." );
+        }
+        
+        if ( !repositoryTaskScheduler.isProcessingRepositoryTask( repoId ) )
+        {
+            RepositoryTask task = new RepositoryTask();
+            task.setRepositoryId( repoId );
+
+            repositoryTaskScheduler.queueTask( task );            
+        }
+
+        AuditEvent event = createAuditEvent( repoConfig );
+
+        // add event for audit log reports
+        metadataRepository.addMetadataFacet( event.getRepositoryId(), event );
+        
+        // log event in archiva audit log 
+        auditListener.auditEvent( createAuditEvent( repoConfig ) );
+        
+        return true;
+    }
+ 
+    // todo: setting userid of audit event
+    private AuditEvent createAuditEvent( ManagedRepositoryConfiguration repoConfig )
+    {
+
+        AuditEvent event = new AuditEvent();
+        event.setAction( AuditEvent.MERGE_REPO_REMOTE );
+        event.setRepositoryId( repoConfig.getId() );
+        event.setResource( repoConfig.getLocation() );
+        event.setTimestamp( new Date( ) );
+        
+        return event;
+    }
+
+    private void mergeWithOutSnapshots( List<ArtifactMetadata> sourceArtifacts, String sourceRepoId, String repoid )
+        throws Exception
+    {
+        List<ArtifactMetadata> artifactsWithOutSnapshots = new ArrayList<ArtifactMetadata>();
+        for ( ArtifactMetadata metadata : sourceArtifacts )
+        {
+    
+            if ( metadata.getProjectVersion().contains( "SNAPSHOT" ) )
+            {
+                artifactsWithOutSnapshots.add( metadata );
+            }
+    
+        }
+        sourceArtifacts.removeAll( artifactsWithOutSnapshots );
+    
+        Filter<ArtifactMetadata> artifactListWithOutSnapShots = new IncludesFilter<ArtifactMetadata>( sourceArtifacts );
+        
+        repositoryMerger.merge( sourceRepoId, repoid, artifactListWithOutSnapShots );
+    }
 }

Modified: archiva/trunk/archiva-modules/archiva-web/archiva-xmlrpc/archiva-xmlrpc-services/src/test/java/org/apache/archiva/web/xmlrpc/services/AdministrationServiceImplTest.java
URL: http://svn.apache.org/viewvc/archiva/trunk/archiva-modules/archiva-web/archiva-xmlrpc/archiva-xmlrpc-services/src/test/java/org/apache/archiva/web/xmlrpc/services/AdministrationServiceImplTest.java?rev=1003378&r1=1003377&r2=1003378&view=diff
==============================================================================
--- archiva/trunk/archiva-modules/archiva-web/archiva-xmlrpc/archiva-xmlrpc-services/src/test/java/org/apache/archiva/web/xmlrpc/services/AdministrationServiceImplTest.java (original)
+++ archiva/trunk/archiva-modules/archiva-web/archiva-xmlrpc/archiva-xmlrpc-services/src/test/java/org/apache/archiva/web/xmlrpc/services/AdministrationServiceImplTest.java Fri Oct  1 03:50:04 2010
@@ -19,13 +19,18 @@ package org.apache.archiva.web.xmlrpc.se
  * under the License.
  */
 
+import org.apache.archiva.audit.AuditEvent;
+import org.apache.archiva.audit.AuditListener;
 import org.apache.archiva.metadata.model.ArtifactMetadata;
 import org.apache.archiva.metadata.repository.MetadataRepository;
+import org.apache.archiva.metadata.repository.filter.Filter;
+import org.apache.archiva.metadata.repository.filter.IncludesFilter;
 import org.apache.archiva.metadata.repository.stats.RepositoryStatisticsManager;
 import org.apache.archiva.repository.events.RepositoryListener;
 import org.apache.archiva.repository.scanner.RepositoryContentConsumers;
 import org.apache.archiva.scheduler.repository.RepositoryArchivaTaskScheduler;
 import org.apache.archiva.scheduler.repository.RepositoryTask;
+import org.apache.archiva.stagerepository.merge.RepositoryMerger;
 import org.apache.archiva.web.xmlrpc.api.beans.ManagedRepository;
 import org.apache.archiva.web.xmlrpc.api.beans.RemoteRepository;
 import org.apache.commons.io.FileUtils;
@@ -52,6 +57,7 @@ import java.io.File;
 import java.io.IOException;
 import java.util.ArrayList;
 import java.util.Collections;
+import java.util.Date;
 import java.util.List;
 
 /**
@@ -109,7 +115,17 @@ public class AdministrationServiceImplTe
     private MockControl repositoryStatisticsManagerControl;
 
     private RepositoryStatisticsManager repositoryStatisticsManager;
+    
+    private MockControl repositoryMergerControl;
+    
+    private RepositoryMerger repositoryMerger;
+    
+    private MockControl auditListenerControl;
+    
+    private AuditListener auditListener;
 
+    private static final String STAGE = "-stage";
+    
     protected void setUp()
         throws Exception
     {
@@ -148,12 +164,17 @@ public class AdministrationServiceImplTe
 
         repositoryStatisticsManagerControl = MockControl.createControl( RepositoryStatisticsManager.class );
         repositoryStatisticsManager = (RepositoryStatisticsManager) repositoryStatisticsManagerControl.getMock();
-
         
+        repositoryMergerControl = MockControl.createControl( RepositoryMerger.class );
+        repositoryMerger = (RepositoryMerger) repositoryMergerControl.getMock();
+        
+        auditListenerControl = MockControl.createControl( AuditListener.class );
+        auditListener = ( AuditListener ) auditListenerControl.getMock();
+
         service =
             new AdministrationServiceImpl( archivaConfig, repoConsumersUtil, repositoryFactory,
                                            metadataRepository, repositoryTaskScheduler,
-                                           Collections.singletonList( listener ), repositoryStatisticsManager );
+                                           Collections.singletonList( listener ), repositoryStatisticsManager, repositoryMerger, auditListener );
     }
   
     /* Tests for repository consumers  */
@@ -617,6 +638,174 @@ public class AdministrationServiceImplTe
         assertRemoteRepo( repos.get( 1 ), remoteRepos.get( 1 ) );        
     }
     
+/* Merge method */
+    
+    public void testMergeRepositoryWithInvalidRepository()
+        throws Exception
+    {
+        archivaConfigControl.expectAndReturn( archivaConfig.getConfiguration(), config );
+        configControl.expectAndReturn( config.findManagedRepositoryById( "invalid" ), null );
+        
+        archivaConfigControl.replay();
+        configControl.replay();
+        
+        try
+        {
+            service.merge( "invalid", true );
+        }
+        catch( Exception e )
+        {
+            assertEquals( "Repository Id : invalid not found.", e.getMessage() );
+        }
+        
+        archivaConfigControl.verify();
+        configControl.verify();
+    }
+    
+    public void testMergeWithNoStagingRepository()
+        throws Exception 
+    {
+        archivaConfigControl.expectAndReturn( archivaConfig.getConfiguration(), config );
+        configControl.expectAndReturn( config.findManagedRepositoryById( "repo" ), createManagedRepo( "repo", "default", "repo", true, false ) );
+        configControl.expectAndReturn( config.findManagedRepositoryById( "repo-stage" ), null );
+        
+        archivaConfigControl.replay();
+        configControl.replay();
+        
+        try
+        {
+            service.merge( "repo", true );
+        }
+        catch( Exception e )
+        {
+            assertEquals( "Staging Id : repo-stage not found.", e.getMessage() );
+        }
+        
+        archivaConfigControl.verify();
+        configControl.verify();   
+    }
+    
+    public void testMergeRepositoriesAndScan( )
+        throws Exception
+    {
+        List<ArtifactMetadata> sources = new ArrayList<ArtifactMetadata>();
+        
+        ArtifactMetadata artifact = new ArtifactMetadata();
+        artifact.setId( "artifact" );
+        artifact.setFileLastModified( System.currentTimeMillis() );
+        
+        sources.add( artifact );
+        
+        ManagedRepositoryConfiguration merge = createManagedRepo( "merge", "default", "merge", true, true );
+        merge.setLocation( "target/test-repository/merge" );
+        ManagedRepositoryConfiguration staging = createStagingRepo( merge );
+        
+        RepositoryTask task = new RepositoryTask();
+        task.setScanAll( true );
+        
+        archivaConfigControl.expectAndReturn( archivaConfig.getConfiguration(), config );
+        configControl.expectAndReturn( config.findManagedRepositoryById( "merge" ), merge );
+        configControl.expectAndReturn( config.findManagedRepositoryById( "merge-stage" ), staging );
+        
+        metadataRepositoryControl.expectAndReturn( metadataRepository.getArtifacts( staging.getId() ), sources );
+        repositoryMergerControl.expectAndDefaultReturn( repositoryMerger.getConflictingArtifacts( staging.getId(), merge.getId() ), sources );
+        repositoryMerger.merge( staging.getId(), merge.getId() );
+        repositoryMergerControl.setMatcher( MockControl.ALWAYS_MATCHER );
+        repositoryMergerControl.setVoidCallable();
+        repositoryTaskSchedulerControl.expectAndReturn( repositoryTaskScheduler.isProcessingRepositoryTask( "merge" ), false);
+        
+        // scanning after merge
+        repositoryTaskScheduler.queueTask( task );
+        repositoryTaskSchedulerControl.setMatcher( MockControl.ALWAYS_MATCHER );
+        repositoryTaskSchedulerControl.setVoidCallable();
+        
+        // audit logs
+        metadataRepository.addMetadataFacet( merge.getId() ,createAuditEvent( merge) );
+        metadataRepositoryControl.setMatcher( MockControl.ALWAYS_MATCHER );
+        metadataRepositoryControl.setVoidCallable();
+        
+        archivaConfigControl.replay();
+        metadataRepositoryControl.replay();
+        configControl.replay();
+        repositoryMergerControl.replay();
+        repositoryTaskSchedulerControl.replay();
+
+        boolean a = service.merge( "merge", false );
+        assertTrue( a );
+        
+        archivaConfigControl.verify();
+        configControl.verify();
+        configControl.verify();
+        metadataRepositoryControl.verify();
+        repositoryMergerControl.verify();
+        repositoryTaskSchedulerControl.verify();
+    }
+    
+    public void testMergeRepositoriesWithConflictsAndScan( )
+        throws Exception
+    {
+        List<ArtifactMetadata> sources = new ArrayList<ArtifactMetadata>();
+        ArtifactMetadata one = new ArtifactMetadata();
+        one.setId( "one" );
+        one.setVersion( "1.0" );
+        
+        ArtifactMetadata two = new ArtifactMetadata();
+        two.setId( "two" );
+        two.setVersion( "1.0-SNAPSHOT" );
+        
+        sources.add( one );
+        sources.add( two );
+        
+        List<ArtifactMetadata> conflicts = new ArrayList<ArtifactMetadata>();
+        conflicts.add( one );
+        
+        sources.removeAll( conflicts );
+        
+        Filter<ArtifactMetadata> artifactsWithOutConflicts = new IncludesFilter<ArtifactMetadata>( sources );
+        
+        RepositoryTask task = new RepositoryTask();
+        task.setScanAll( true );
+        
+        ManagedRepositoryConfiguration repo = createManagedRepo( "repo", "default", "repo", true, true );
+        repo.setLocation( "target/test-repository/one" );
+        ManagedRepositoryConfiguration staging = createStagingRepo( repo );
+        
+        archivaConfigControl.expectAndReturn( archivaConfig.getConfiguration(), config );
+        configControl.expectAndReturn( config.findManagedRepositoryById( "repo" ), repo );
+        configControl.expectAndReturn( config.findManagedRepositoryById( "repo-stage" ), staging );
+        
+        metadataRepositoryControl.expectAndReturn( metadataRepository.getArtifacts( staging.getId() ), sources );
+        repositoryMergerControl.expectAndDefaultReturn( repositoryMerger.getConflictingArtifacts( staging.getId(), repo.getId() ), conflicts );
+        repositoryMerger.merge( staging.getId(), repo.getId(), artifactsWithOutConflicts );
+        repositoryMergerControl.setMatcher( MockControl.ALWAYS_MATCHER );
+        repositoryMergerControl.setVoidCallable();
+        repositoryTaskSchedulerControl.expectAndReturn( repositoryTaskScheduler.isProcessingRepositoryTask( "repo" ), false);
+        repositoryTaskScheduler.queueTask( task );
+        repositoryTaskSchedulerControl.setMatcher( MockControl.ALWAYS_MATCHER );
+        repositoryTaskSchedulerControl.setVoidCallable();
+        
+        // audit logs
+        metadataRepository.addMetadataFacet( repo.getId() ,createAuditEvent( repo ) );
+        metadataRepositoryControl.setMatcher( MockControl.ALWAYS_MATCHER );
+        metadataRepositoryControl.setVoidCallable();        
+        
+        archivaConfigControl.replay();
+        metadataRepositoryControl.replay();
+        configControl.replay();
+        repositoryMergerControl.replay();
+        repositoryTaskSchedulerControl.replay();
+
+        boolean a = service.merge( "repo", true );
+        assertTrue( a );
+        
+        archivaConfigControl.verify();
+        configControl.verify();
+        configControl.verify();
+        metadataRepositoryControl.verify();
+        repositoryMergerControl.verify();        
+        repositoryTaskSchedulerControl.verify();
+    }
+    
 /* private methods  */
     
     private void assertRemoteRepo( RemoteRepository remoteRepo, RemoteRepositoryConfiguration expectedRepoConfig )
@@ -663,6 +852,31 @@ public class AdministrationServiceImplTe
         return repoConfig;
     }
     
+    private ManagedRepositoryConfiguration createStagingRepo( ManagedRepositoryConfiguration repoConfig )
+    {
+        ManagedRepositoryConfiguration stagingRepo = new ManagedRepositoryConfiguration();
+        stagingRepo.setId( repoConfig.getId() + STAGE );
+        stagingRepo.setLayout( repoConfig.getLayout() );
+        stagingRepo.setName( repoConfig + STAGE );
+        stagingRepo.setReleases( repoConfig.isReleases() );
+        stagingRepo.setSnapshots( repoConfig.isSnapshots() );
+        stagingRepo.setLocation( repoConfig.getLocation() );
+        
+        return stagingRepo;
+    }
+    
+    private AuditEvent createAuditEvent( ManagedRepositoryConfiguration repoConfig )
+    {
+        AuditEvent auditEvent = new AuditEvent();
+        
+        auditEvent.setAction( AuditEvent.MERGE_REPO_REMOTE );
+        auditEvent.setRepositoryId( repoConfig.getId() );
+        auditEvent.setResource( repoConfig.getLocation() );
+        auditEvent.setTimestamp( new Date( ) );
+        
+        return auditEvent;
+    }
+    
     private void recordRepoConsumers()
     {
         List<KnownRepositoryContentConsumer> availableKnownConsumers = new ArrayList<KnownRepositoryContentConsumer>();

Modified: archiva/trunk/archiva-modules/plugins/audit/src/main/java/org/apache/archiva/audit/AuditEvent.java
URL: http://svn.apache.org/viewvc/archiva/trunk/archiva-modules/plugins/audit/src/main/java/org/apache/archiva/audit/AuditEvent.java?rev=1003378&r1=1003377&r2=1003378&view=diff
==============================================================================
--- archiva/trunk/archiva-modules/plugins/audit/src/main/java/org/apache/archiva/audit/AuditEvent.java (original)
+++ archiva/trunk/archiva-modules/plugins/audit/src/main/java/org/apache/archiva/audit/AuditEvent.java Fri Oct  1 03:50:04 2010
@@ -101,6 +101,8 @@ public class AuditEvent
 
     public static final String REMOVE_PATTERN = "Removed File Type Pattern";
 
+    public static final String MERGE_REPO_REMOTE = "Merged Staging Repository Triggered Remotely";
+    
     private String repositoryId;
 
     private String userId;

Modified: archiva/trunk/archiva-modules/plugins/stage-repository-merge/src/main/java/org/apache/archiva/stagerepository/merge/Maven2RepositoryMerger.java
URL: http://svn.apache.org/viewvc/archiva/trunk/archiva-modules/plugins/stage-repository-merge/src/main/java/org/apache/archiva/stagerepository/merge/Maven2RepositoryMerger.java?rev=1003378&r1=1003377&r2=1003378&view=diff
==============================================================================
--- archiva/trunk/archiva-modules/plugins/stage-repository-merge/src/main/java/org/apache/archiva/stagerepository/merge/Maven2RepositoryMerger.java (original)
+++ archiva/trunk/archiva-modules/plugins/stage-repository-merge/src/main/java/org/apache/archiva/stagerepository/merge/Maven2RepositoryMerger.java Fri Oct  1 03:50:04 2010
@@ -325,7 +325,7 @@ public class Maven2RepositoryMerger
         return metadata;
     }
 
-    public List<ArtifactMetadata> getConflictsartifacts( String sourceRepo, String targetRepo )
+    public List<ArtifactMetadata> getConflictingArtifacts( String sourceRepo, String targetRepo )
         throws Exception
     {
         List<ArtifactMetadata> targetArtifacts = metadataRepository.getArtifacts( targetRepo );

Modified: archiva/trunk/archiva-modules/plugins/stage-repository-merge/src/main/java/org/apache/archiva/stagerepository/merge/RepositoryMerger.java
URL: http://svn.apache.org/viewvc/archiva/trunk/archiva-modules/plugins/stage-repository-merge/src/main/java/org/apache/archiva/stagerepository/merge/RepositoryMerger.java?rev=1003378&r1=1003377&r2=1003378&view=diff
==============================================================================
--- archiva/trunk/archiva-modules/plugins/stage-repository-merge/src/main/java/org/apache/archiva/stagerepository/merge/RepositoryMerger.java (original)
+++ archiva/trunk/archiva-modules/plugins/stage-repository-merge/src/main/java/org/apache/archiva/stagerepository/merge/RepositoryMerger.java Fri Oct  1 03:50:04 2010
@@ -19,6 +19,8 @@ package org.apache.archiva.stagereposito
  * under the License.
  */
 
+import java.util.List;
+
 import org.apache.archiva.metadata.model.ArtifactMetadata;
 import org.apache.archiva.metadata.repository.filter.Filter;
 
@@ -28,4 +30,7 @@ public interface RepositoryMerger
         throws Exception;
 
     void merge( String sourceRepoId, String targetRepoId, Filter<ArtifactMetadata> filter ) throws Exception;
-}
+    
+    public List<ArtifactMetadata> getConflictingArtifacts( String sourceRepo, String targetRepo )
+        throws Exception;
+}
\ No newline at end of file

Modified: archiva/trunk/archiva-modules/plugins/stage-repository-merge/src/test/java/org/apache/archiva/stagerepository/merge/Maven2RepositoryMergerTest.java
URL: http://svn.apache.org/viewvc/archiva/trunk/archiva-modules/plugins/stage-repository-merge/src/test/java/org/apache/archiva/stagerepository/merge/Maven2RepositoryMergerTest.java?rev=1003378&r1=1003377&r2=1003378&view=diff
==============================================================================
--- archiva/trunk/archiva-modules/plugins/stage-repository-merge/src/test/java/org/apache/archiva/stagerepository/merge/Maven2RepositoryMergerTest.java (original)
+++ archiva/trunk/archiva-modules/plugins/stage-repository-merge/src/test/java/org/apache/archiva/stagerepository/merge/Maven2RepositoryMergerTest.java Fri Oct  1 03:50:04 2010
@@ -154,7 +154,7 @@ public class Maven2RepositoryMergerTest
         when( metadataRepository.getArtifacts( sourceRepoId ) ).thenReturn( sourceRepoArtifactsList );
         when( metadataRepository.getArtifacts( TEST_REPO_ID ) ).thenReturn( targetRepoArtifactsList );
 
-        assertEquals( 1, repositoryMerger.getConflictsartifacts( sourceRepoId, TEST_REPO_ID ).size() );
+        assertEquals( 1, repositoryMerger.getConflictingArtifacts( sourceRepoId, TEST_REPO_ID ).size() );
         verify( metadataRepository ).getArtifacts( TEST_REPO_ID );
     }
 

Modified: archiva/trunk/pom.xml
URL: http://svn.apache.org/viewvc/archiva/trunk/pom.xml?rev=1003378&r1=1003377&r2=1003378&view=diff
==============================================================================
--- archiva/trunk/pom.xml (original)
+++ archiva/trunk/pom.xml Fri Oct  1 03:50:04 2010
@@ -509,6 +509,11 @@
         <version>1.4-SNAPSHOT</version>
       </dependency>
       <dependency>
+        <groupId>org.apache.archiva</groupId>
+        <artifactId>stage-repository-merge</artifactId>
+        <version>1.4-SNAPSHOT</version>
+      </dependency>
+      <dependency>
         <groupId>org.codehaus.plexus</groupId>
         <artifactId>plexus-spring</artifactId>
         <version>1.2</version>