From de3ea2b93e1dc957758fc46f668631d96b559b9e Mon Sep 17 00:00:00 2001 From: "Maria Odea B. Ching" Date: Sat, 10 Jul 2010 04:04:32 +0000 Subject: [PATCH] [MRM-980] add implementation and test case for repository merger submitted by Patti Arachchige Eshan Sudharaka git-svn-id: https://svn.apache.org/repos/asf/archiva/branches/archiva-MRM-980@962756 13f79535-47bb-0310-9956-ffa450edef68 --- .../file/FileMetadataRepositoryTest.java | 1 - .../plugins/stage-repository-merge/pom.xml | 9 +- .../merge/Maven2RepositoryMerger.java | 304 ++++++++++++++++++ .../merge/RepositoryMerger.java | 31 ++ .../configuration/StubConfiguration.java | 64 ++++ .../merge/Maven2RepositoryMergerTest.java | 89 +++++ .../merge/Maven2RepositoryMergerTest.xml | 27 ++ 7 files changed, 522 insertions(+), 3 deletions(-) create mode 100644 archiva-modules/plugins/stage-repository-merge/src/main/java/org/apache/archiva/stagerepository/merge/Maven2RepositoryMerger.java create mode 100644 archiva-modules/plugins/stage-repository-merge/src/main/java/org/apache/archiva/stagerepository/merge/RepositoryMerger.java create mode 100644 archiva-modules/plugins/stage-repository-merge/src/test/java/org/apache/archiva/configuration/StubConfiguration.java create mode 100644 archiva-modules/plugins/stage-repository-merge/src/test/java/org/apache/archiva/stagerepository/merge/Maven2RepositoryMergerTest.java create mode 100644 archiva-modules/plugins/stage-repository-merge/src/test/resources/org/apache/archiva/stagerepository/merge/Maven2RepositoryMergerTest.xml diff --git a/archiva-modules/plugins/metadata-repository-file/src/test/java/org/apache/archiva/metadata/repository/file/FileMetadataRepositoryTest.java b/archiva-modules/plugins/metadata-repository-file/src/test/java/org/apache/archiva/metadata/repository/file/FileMetadataRepositoryTest.java index 60aaffb02..05448af61 100644 --- a/archiva-modules/plugins/metadata-repository-file/src/test/java/org/apache/archiva/metadata/repository/file/FileMetadataRepositoryTest.java +++ b/archiva-modules/plugins/metadata-repository-file/src/test/java/org/apache/archiva/metadata/repository/file/FileMetadataRepositoryTest.java @@ -50,7 +50,6 @@ public class FileMetadataRepositoryTest FileMetadataRepository repository = new FileMetadataRepository(); repository.setConfiguration( config ); repository.setMetadataFacetFactories( factories ); - this.repository = repository; } diff --git a/archiva-modules/plugins/stage-repository-merge/pom.xml b/archiva-modules/plugins/stage-repository-merge/pom.xml index 0ca732039..7f096705b 100644 --- a/archiva-modules/plugins/stage-repository-merge/pom.xml +++ b/archiva-modules/plugins/stage-repository-merge/pom.xml @@ -1,7 +1,7 @@ + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" + xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> 4.0.0 plugins @@ -44,6 +44,11 @@ archiva-model 1.4-MRM-980-SNAPSHOT + + org.apache.archiva + metadata-repository-file + 1.4-MRM-980-SNAPSHOT + org.mockito mockito-all diff --git a/archiva-modules/plugins/stage-repository-merge/src/main/java/org/apache/archiva/stagerepository/merge/Maven2RepositoryMerger.java b/archiva-modules/plugins/stage-repository-merge/src/main/java/org/apache/archiva/stagerepository/merge/Maven2RepositoryMerger.java new file mode 100644 index 000000000..b8bf53058 --- /dev/null +++ b/archiva-modules/plugins/stage-repository-merge/src/main/java/org/apache/archiva/stagerepository/merge/Maven2RepositoryMerger.java @@ -0,0 +1,304 @@ +package org.apache.archiva.stagerepository.merge; + +/* + * 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.metadata.model.ArtifactMetadata; +import org.apache.archiva.metadata.repository.filter.Filter; +import org.apache.archiva.metadata.repository.filter.IncludesFilter; +import org.apache.archiva.metadata.repository.MetadataRepository; +import org.apache.archiva.metadata.repository.storage.RepositoryPathTranslator; +import org.apache.maven.archiva.repository.RepositoryContentFactory; +import org.apache.maven.archiva.repository.ManagedRepositoryContent; +import org.apache.maven.archiva.repository.RepositoryNotFoundException; +import org.apache.maven.archiva.repository.RepositoryException; +import org.apache.maven.archiva.repository.metadata.RepositoryMetadataException; +import org.apache.maven.archiva.repository.metadata.RepositoryMetadataWriter; +import org.apache.maven.archiva.repository.metadata.RepositoryMetadataReader; +import org.apache.maven.archiva.configuration.ArchivaConfiguration; +import org.apache.maven.archiva.configuration.Configuration; +import org.apache.maven.archiva.configuration.ManagedRepositoryConfiguration; +import org.apache.maven.archiva.model.ArchivaArtifact; +import org.apache.maven.archiva.model.ArchivaRepositoryMetadata; +import org.apache.maven.archiva.common.utils.VersionComparator; +import org.apache.maven.archiva.common.utils.VersionUtil; + +import java.util.List; +import java.util.Date; +import java.util.Calendar; +import java.util.TimeZone; +import java.util.ArrayList; +import java.util.Collections; +import java.io.IOException; +import java.io.File; +import java.io.FileOutputStream; +import java.io.FileInputStream; +import java.text.DateFormat; +import java.text.SimpleDateFormat; + +/** + * @plexus.component role="org.apache.archiva.stagerepository.merge.RepositoryMerger" role-hint="maven2" + */ +public class Maven2RepositoryMerger + implements RepositoryMerger +{ + + /** + * @plexus.requirement role-hint="default" + */ + private MetadataRepository metadataRepository; + + /** + * @plexus.requirement role-hint="default" + */ + private ArchivaConfiguration configuration; + + /** + * @plexus.requirement role-hint="maven2" + */ + private RepositoryPathTranslator pathTranslator; + + private static final String METADATA_FILENAME = "maven-metadata.xml"; + + public void setConfiguration( ArchivaConfiguration configuration ) + { + this.configuration = configuration; + } + + public void merge( String sourceRepoId, String targetRepoId ) + throws Exception + { + + List artifactsInSourceRepo = metadataRepository.getArtifacts( sourceRepoId ); + for ( ArtifactMetadata artifactMetadata : artifactsInSourceRepo ) + { + createFolderStructure( sourceRepoId, targetRepoId, artifactMetadata ); + } + } + + // TODO when UI needs a subset to merge + public void merge( String sourceRepoId, String targetRepoId, Filter filter ) + { + + } + + private void createFolderStructure( String sourceRepoId, String targetRepoId, ArtifactMetadata artifactMetadata ) + throws IOException, RepositoryException + { + Configuration config = configuration.getConfiguration(); + + ManagedRepositoryConfiguration targetRepoConfig = config.findManagedRepositoryById( targetRepoId ); + + ManagedRepositoryConfiguration sourceRepoConfig = config.findManagedRepositoryById( sourceRepoId ); + + Date lastUpdatedTimestamp = Calendar.getInstance().getTime(); + + TimeZone timezone = TimeZone.getTimeZone( "UTC" ); + + DateFormat fmt = new SimpleDateFormat( "yyyyMMdd.HHmmss" ); + + fmt.setTimeZone( timezone ); + + String timestamp = fmt.format( lastUpdatedTimestamp ); + + String targetRepoPath = targetRepoConfig.getLocation(); + + String sourceRepoPath = sourceRepoConfig.getLocation(); + + String artifactPath = + pathTranslator.toPath( artifactMetadata.getNamespace(), artifactMetadata.getProject(), + artifactMetadata.getProjectVersion(), artifactMetadata.getId() ); + + File sourceArtifactFile = new File( sourceRepoPath, artifactPath ); + + File targetArtifactFile = new File( targetRepoPath, artifactPath ); + + int lastIndex = artifactPath.lastIndexOf( '/' ); + + File targetFile = new File( targetRepoPath, artifactPath.substring( 0, lastIndex ) ); + + if ( !targetFile.exists() ) + { + // create the folder structure when it does not exist + targetFile.mkdirs(); + } + // artifact copying + copyFile( sourceArtifactFile, targetArtifactFile ); + + // pom file copying + String fileName = artifactMetadata.getProject() + "-" + artifactMetadata.getVersion() + ".pom"; + + File sourcePomFile = + pathTranslator.toFile( new File( sourceRepoPath ), artifactMetadata.getId(), artifactMetadata.getProject(), + artifactMetadata.getVersion(), fileName ); + String relativePathToPomFile = sourcePomFile.getAbsolutePath().split( sourceRepoPath )[1]; + File targetPomFile = new File( targetRepoPath, relativePathToPomFile ); + + if ( !targetPomFile.exists() ) + { + copyFile( sourcePomFile, targetPomFile ); + } + + // explicitly update only if metadata-updater consumer is not enabled! + if ( !config.getRepositoryScanning().getKnownContentConsumers().contains( "metadata-updater" ) ) + { + + // updating version metadata files + File versionMetaDataFileInSourceRepo = + pathTranslator.toFile( new File( sourceRepoPath ), artifactMetadata.getNamespace(), + artifactMetadata.getProject(), artifactMetadata.getVersion(), METADATA_FILENAME ); + String relativePathToVersionMetadataFile = + versionMetaDataFileInSourceRepo.getAbsolutePath().split( sourceRepoPath )[1]; + File versionMetaDataFileInTargetRepo = new File( targetRepoPath, relativePathToVersionMetadataFile ); + + if ( !versionMetaDataFileInTargetRepo.exists() ) + { + copyFile( versionMetaDataFileInSourceRepo, versionMetaDataFileInTargetRepo ); + } + else + { + updateVersionMetadata( versionMetaDataFileInTargetRepo, artifactMetadata, lastUpdatedTimestamp ); + + } + + // updating project meta data file + String projectDirectoryInSourceRepo = new File( versionMetaDataFileInSourceRepo.getParent() ).getParent(); + File projectMetadataFileInSourceRepo = new File( projectDirectoryInSourceRepo, METADATA_FILENAME ); + + String relativePathToProjectMetadataFile = + projectMetadataFileInSourceRepo.getAbsolutePath().split( sourceRepoPath )[1]; + File projectMetadataFileInTargetRepo = new File( targetRepoPath, relativePathToProjectMetadataFile ); + + if ( !projectMetadataFileInTargetRepo.exists() ) + { + + copyFile( versionMetaDataFileInSourceRepo, projectMetadataFileInSourceRepo ); + } + else + { + updateProjectMetadata( projectMetadataFileInTargetRepo, artifactMetadata, lastUpdatedTimestamp, + timestamp ); + } + } + + } + + private void copyFile( File sourceFile, File targetFile ) + throws IOException + { + + FileOutputStream out = new FileOutputStream( targetFile ); + FileInputStream input = new FileInputStream( sourceFile ); + + try + { + int i; + while ( ( i = input.read() ) != -1 ) + { + out.write( i ); + } + out.flush(); + } + finally + { + out.close(); + input.close(); + } + } + + private void updateProjectMetadata( File projectMetaDataFileIntargetRepo, ArtifactMetadata artifactMetadata, + Date lastUpdatedTimestamp, String timestamp ) + throws RepositoryMetadataException + { + ArrayList availableVersions = new ArrayList(); + String latestVersion = artifactMetadata.getProjectVersion(); + + ArchivaRepositoryMetadata projectMetadata = getMetadata( projectMetaDataFileIntargetRepo ); + + if ( projectMetaDataFileIntargetRepo.exists() ) + { + availableVersions = (ArrayList) projectMetadata.getAvailableVersions(); + + Collections.sort( availableVersions, VersionComparator.getInstance() ); + + if ( !availableVersions.contains( artifactMetadata.getVersion() ) ) + { + availableVersions.add( artifactMetadata.getVersion() ); + } + + latestVersion = availableVersions.get( availableVersions.size() - 1 ); + } + else + { + availableVersions.add( artifactMetadata.getProjectVersion() ); + projectMetadata.setGroupId( artifactMetadata.getNamespace() ); + projectMetadata.setArtifactId( artifactMetadata.getProject() ); + } + + if ( projectMetadata.getGroupId() == null ) + { + projectMetadata.setGroupId( artifactMetadata.getNamespace() ); + } + + if ( projectMetadata.getArtifactId() == null ) + { + projectMetadata.setArtifactId( artifactMetadata.getProject() ); + } + + projectMetadata.setLatestVersion( latestVersion ); + projectMetadata.setAvailableVersions( availableVersions ); + projectMetadata.setLastUpdated( timestamp ); + projectMetadata.setLastUpdatedTimestamp( lastUpdatedTimestamp ); + + if ( !VersionUtil.isSnapshot( artifactMetadata.getVersion() ) ) + { + projectMetadata.setReleasedVersion( latestVersion ); + } + + RepositoryMetadataWriter.write( projectMetadata, projectMetaDataFileIntargetRepo ); + + } + + private void updateVersionMetadata( File versionMetaDataFileInTargetRepo, ArtifactMetadata artifactMetadata, + Date lastUpdatedTimestamp ) + throws RepositoryMetadataException + { + ArchivaRepositoryMetadata versionMetadata = getMetadata( versionMetaDataFileInTargetRepo ); + if ( !versionMetaDataFileInTargetRepo.exists() ) + { + versionMetadata.setGroupId( artifactMetadata.getNamespace() ); + versionMetadata.setArtifactId( artifactMetadata.getProject() ); + versionMetadata.setVersion( artifactMetadata.getProjectVersion() ); + } + + versionMetadata.setLastUpdatedTimestamp( lastUpdatedTimestamp ); + RepositoryMetadataWriter.write( versionMetadata, versionMetaDataFileInTargetRepo ); + } + + private ArchivaRepositoryMetadata getMetadata( File metadataFile ) + throws RepositoryMetadataException + { + ArchivaRepositoryMetadata metadata = new ArchivaRepositoryMetadata(); + if ( metadataFile.exists() ) + { + metadata = RepositoryMetadataReader.read( metadataFile ); + } + return metadata; + } +} diff --git a/archiva-modules/plugins/stage-repository-merge/src/main/java/org/apache/archiva/stagerepository/merge/RepositoryMerger.java b/archiva-modules/plugins/stage-repository-merge/src/main/java/org/apache/archiva/stagerepository/merge/RepositoryMerger.java new file mode 100644 index 000000000..c19bc3881 --- /dev/null +++ b/archiva-modules/plugins/stage-repository-merge/src/main/java/org/apache/archiva/stagerepository/merge/RepositoryMerger.java @@ -0,0 +1,31 @@ +package org.apache.archiva.stagerepository.merge; + +/* + * 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.metadata.model.ArtifactMetadata; +import org.apache.archiva.metadata.repository.filter.Filter; + +public interface RepositoryMerger +{ + void merge( String sourceRepoId, String targetRepoId ) + throws Exception; + + void merge( String sourceRepoId, String targetRepoId, Filter filter ); +} diff --git a/archiva-modules/plugins/stage-repository-merge/src/test/java/org/apache/archiva/configuration/StubConfiguration.java b/archiva-modules/plugins/stage-repository-merge/src/test/java/org/apache/archiva/configuration/StubConfiguration.java new file mode 100644 index 000000000..00c29ea1c --- /dev/null +++ b/archiva-modules/plugins/stage-repository-merge/src/test/java/org/apache/archiva/configuration/StubConfiguration.java @@ -0,0 +1,64 @@ +package org.apache.archiva.configuration; + +/* + * 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.maven.archiva.configuration.ArchivaConfiguration; +import org.apache.maven.archiva.configuration.Configuration; +import org.apache.maven.archiva.configuration.ConfigurationListener; +import org.apache.maven.archiva.configuration.IndeterminateConfigurationException; +import org.codehaus.plexus.registry.RegistryException; +import org.codehaus.plexus.registry.RegistryListener; + +public class StubConfiguration + implements ArchivaConfiguration +{ + private Configuration configuration; + + public Configuration getConfiguration() + { + return configuration; + } + + public void save( Configuration configuration ) + throws RegistryException, IndeterminateConfigurationException + { + this.configuration = configuration; + } + + public boolean isDefaulted() + { + return false; + } + + public void addListener( ConfigurationListener listener ) + { + throw new UnsupportedOperationException(); + } + + public void removeListener( ConfigurationListener listener ) + { + throw new UnsupportedOperationException(); + } + + public void addChangeListener( RegistryListener listener ) + { + throw new UnsupportedOperationException(); + } +} diff --git a/archiva-modules/plugins/stage-repository-merge/src/test/java/org/apache/archiva/stagerepository/merge/Maven2RepositoryMergerTest.java b/archiva-modules/plugins/stage-repository-merge/src/test/java/org/apache/archiva/stagerepository/merge/Maven2RepositoryMergerTest.java new file mode 100644 index 000000000..b2baca3b0 --- /dev/null +++ b/archiva-modules/plugins/stage-repository-merge/src/test/java/org/apache/archiva/stagerepository/merge/Maven2RepositoryMergerTest.java @@ -0,0 +1,89 @@ +package org.apache.archiva.stagerepository.merge; + +/* + * 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.codehaus.plexus.spring.PlexusInSpringTestCase; +import org.apache.maven.archiva.configuration.Configuration; +import org.apache.maven.archiva.configuration.ArchivaConfiguration; +import org.apache.maven.archiva.configuration.ManagedRepositoryConfiguration; +import org.apache.maven.archiva.repository.RepositoryContentFactory; +import org.apache.archiva.metadata.repository.MetadataRepository; +import org.apache.archiva.reports.RepositoryProblemFacet; +import org.mockito.MockitoAnnotations; +import org.junit.Before; + +public class Maven2RepositoryMergerTest + extends PlexusInSpringTestCase +{ + + private static final String SOURCE_REPOSITORY_ID = "test-repository"; + + private static final String TARGET_REPOSITORY_ID = "target-repo"; + + private static final String TEST_REPO_ID = "test"; + + // private static final String TARGET_REPOSITORY_ID = "target-repo"; + + private Configuration config; + + @MockitoAnnotations.Mock + private MetadataRepository metadataResolver; + + private RepositoryContentFactory repositoryFactory; + + private ArchivaConfiguration configuration; + + private Maven2RepositoryMerger repositoryMerger; + + private MetadataRepository metadataRepository; + + @Before + public void setUp() + throws Exception + { + super.setUp(); + ArchivaConfiguration configuration = (ArchivaConfiguration) lookup( ArchivaConfiguration.class ); + Configuration c = new Configuration(); + ManagedRepositoryConfiguration testRepo = new ManagedRepositoryConfiguration(); + testRepo.setId( TEST_REPO_ID ); + testRepo.setLocation( getTestPath( "target/test-repository" ) ); + // testRepo.setLocation( "/boot/gsoc/apps/apache-archiva-1.4-SNAPSHOT/data/repositories/internal" ); + + ManagedRepositoryConfiguration targetRepo = new ManagedRepositoryConfiguration(); + targetRepo.setId( "target-rep" ); + targetRepo.setLocation( getTestPath( "src/test/resources/target-repo" ) ); + c.addManagedRepository( testRepo ); + c.addManagedRepository( targetRepo ); + configuration.save( c ); + + repositoryMerger = (Maven2RepositoryMerger) lookup( RepositoryMerger.class, "maven2" ); + + metadataRepository = (MetadataRepository) lookup( MetadataRepository.class ); + + } + + public void testMerge() + throws Exception + { + repositoryMerger.merge( TEST_REPO_ID, "target-rep" ); + // assert( true , (metadataRepository.getArtifacts( TEST_REPO_ID ).size() > 0 ) ); + + } +} \ No newline at end of file diff --git a/archiva-modules/plugins/stage-repository-merge/src/test/resources/org/apache/archiva/stagerepository/merge/Maven2RepositoryMergerTest.xml b/archiva-modules/plugins/stage-repository-merge/src/test/resources/org/apache/archiva/stagerepository/merge/Maven2RepositoryMergerTest.xml new file mode 100644 index 000000000..e4367441a --- /dev/null +++ b/archiva-modules/plugins/stage-repository-merge/src/test/resources/org/apache/archiva/stagerepository/merge/Maven2RepositoryMergerTest.xml @@ -0,0 +1,27 @@ + + + + + + org.apache.maven.archiva.configuration.ArchivaConfiguration + org.apache.archiva.configuration.StubConfiguration + + + \ No newline at end of file -- 2.39.5