Modified: archiva/trunk/archiva-modules/plugins/problem-reports/src/main/java/org/apache/archiva/reports/consumers/DuplicateArtifactsConsumer.java URL: http://svn.apache.org/viewvc/archiva/trunk/archiva-modules/plugins/problem-reports/src/main/java/org/apache/archiva/reports/consumers/DuplicateArtifactsConsumer.java?rev=920649&r1=920648&r2=920649&view=diff ============================================================================== --- archiva/trunk/archiva-modules/plugins/problem-reports/src/main/java/org/apache/archiva/reports/consumers/DuplicateArtifactsConsumer.java (original) +++ archiva/trunk/archiva-modules/plugins/problem-reports/src/main/java/org/apache/archiva/reports/consumers/DuplicateArtifactsConsumer.java Tue Mar 9 04:24:32 2010 @@ -19,17 +19,11 @@ package org.apache.archiva.reports.consu * under the License. */ -import java.io.File; -import java.io.IOException; -import java.util.ArrayList; -import java.util.Collections; -import java.util.Date; -import java.util.List; - import org.apache.archiva.checksum.ChecksumAlgorithm; import org.apache.archiva.checksum.ChecksummedFile; import org.apache.archiva.metadata.model.ArtifactMetadata; import org.apache.archiva.metadata.repository.MetadataRepository; +import org.apache.archiva.metadata.repository.storage.RepositoryPathTranslator; import org.apache.archiva.reports.RepositoryProblemFacet; import org.apache.commons.collections.CollectionUtils; import org.apache.maven.archiva.configuration.ArchivaConfiguration; @@ -39,11 +33,6 @@ import org.apache.maven.archiva.configur import org.apache.maven.archiva.consumers.AbstractMonitoredConsumer; import org.apache.maven.archiva.consumers.ConsumerException; import org.apache.maven.archiva.consumers.KnownRepositoryContentConsumer; -import org.apache.maven.archiva.model.ArtifactReference; -import org.apache.maven.archiva.repository.ManagedRepositoryContent; -import org.apache.maven.archiva.repository.RepositoryContentFactory; -import org.apache.maven.archiva.repository.RepositoryException; -import org.apache.maven.archiva.repository.layout.LayoutException; import org.codehaus.plexus.personality.plexus.lifecycle.phase.Initializable; import org.codehaus.plexus.personality.plexus.lifecycle.phase.InitializationException; import org.codehaus.plexus.registry.Registry; @@ -51,6 +40,13 @@ import org.codehaus.plexus.registry.Regi import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import java.io.File; +import java.io.IOException; +import java.util.ArrayList; +import java.util.Collections; +import java.util.Date; +import java.util.List; + /** * Search the database of known SHA1 Checksums for potential duplicate artifacts. * @@ -87,24 +83,23 @@ public class DuplicateArtifactsConsumer */ private FileTypes filetypes; - /** - * @plexus.requirement - */ - private RepositoryContentFactory repositoryFactory; - private List<String> includes = new ArrayList<String>(); private File repositoryDir; private String repoId; - private ManagedRepositoryContent repository; - /** * @plexus.requirement */ private MetadataRepository metadataRepository; + /** + * FIXME: needs to be selected based on the repository in question + * @plexus.requirement role-hint="maven2" + */ + private RepositoryPathTranslator pathTranslator; + public String getId() { return id; @@ -133,16 +128,8 @@ public class DuplicateArtifactsConsumer public void beginScan( ManagedRepositoryConfiguration repo, Date whenGathered ) throws ConsumerException { - try - { - repoId = repo.getId(); - repository = repositoryFactory.getManagedRepositoryContent( repoId ); - this.repositoryDir = new File( repository.getRepoRoot() ); - } - catch ( RepositoryException e ) - { - throw new ConsumerException( e.getMessage(), e ); - } + repoId = repo.getId(); + this.repositoryDir = new File( repo.getLocation() ); } public void processFile( String path ) @@ -152,6 +139,8 @@ public class DuplicateArtifactsConsumer // TODO: would be quicker to somehow make sure it ran after the update database consumer, or as a part of that // perhaps could use an artifact context that is retained for all consumers? First in can set the SHA-1 + // alternatively this could come straight from the storage resolver, which could populate the artifact metadata + // in the later parse call with the desired checksum and use that String checksumSha1; ChecksummedFile checksummedFile = new ChecksummedFile( artifactFile ); try @@ -167,46 +156,45 @@ public class DuplicateArtifactsConsumer if ( CollectionUtils.isNotEmpty( results ) ) { - if ( results.size() <= 1 ) - { - // No duplicates detected. - log.debug( "Found no duplicate artifact results on: " + path + " (repository " + repoId + ")" ); - return; - } - - ArtifactReference artifactReference; + ArtifactMetadata originalArtifact; try { - artifactReference = repository.toArtifactReference( path ); + originalArtifact = pathTranslator.getArtifactForPath( repoId, path ); } - catch ( LayoutException e ) + catch ( Exception e ) { - log.warn( "Unable to report problem for path: " + path ); + log.warn( "Not reporting problem for invalid artifact in checksum check: " + e.getMessage() ); return; } for ( ArtifactMetadata dupArtifact : results ) { String id = path.substring( path.lastIndexOf( "/" ) + 1 ); - if ( dupArtifact.getId().equals( id ) && - dupArtifact.getNamespace().equals( artifactReference.getGroupId() ) && - dupArtifact.getProject().equals( artifactReference.getArtifactId() ) && - dupArtifact.getVersion().equals( artifactReference.getVersion() ) ) + if ( dupArtifact.getId().equals( id ) && dupArtifact.getNamespace().equals( + originalArtifact.getNamespace() ) && dupArtifact.getProject().equals( + originalArtifact.getProject() ) && dupArtifact.getVersion().equals( + originalArtifact.getVersion() ) ) { // Skip reference to itself. + if ( log.isDebugEnabled() ) + { + log.debug( "Not counting duplicate for artifact " + dupArtifact + " for path " + path ); + } continue; } RepositoryProblemFacet problem = new RepositoryProblemFacet(); problem.setRepositoryId( repoId ); - problem.setNamespace( artifactReference.getGroupId() ); - problem.setProject( artifactReference.getArtifactId() ); - problem.setVersion( artifactReference.getVersion() ); + problem.setNamespace( originalArtifact.getNamespace() ); + problem.setProject( originalArtifact.getProject() ); + problem.setVersion( originalArtifact.getVersion() ); problem.setId( id ); - // TODO: proper path conversion for new metadata - problem.setMessage( - "Duplicate Artifact Detected: " + path + " <--> " + dupArtifact.getNamespace().replace( '.', '/' ) + - "/" + dupArtifact.getProject() + "/" + dupArtifact.getVersion() + "/" + dupArtifact.getId() ); + // TODO: need to get the right storage resolver for the repository the dupe artifact is in, it might be + // a different type + // TODO: we need the project version here, not the artifact version + problem.setMessage( "Duplicate Artifact Detected: " + path + " <--> " + pathTranslator.toPath( + dupArtifact.getNamespace(), dupArtifact.getProject(), dupArtifact.getVersion(), + dupArtifact.getId() ) ); problem.setProblem( "duplicate-artifact" ); metadataRepository.addMetadataFacet( repoId, problem );
Added: archiva/trunk/archiva-modules/plugins/problem-reports/src/test/java/org/apache/archiva/reports/consumers/DuplicateArtifactsConsumerTest.java URL: http://svn.apache.org/viewvc/archiva/trunk/archiva-modules/plugins/problem-reports/src/test/java/org/apache/archiva/reports/consumers/DuplicateArtifactsConsumerTest.java?rev=920649&view=auto ============================================================================== --- archiva/trunk/archiva-modules/plugins/problem-reports/src/test/java/org/apache/archiva/reports/consumers/DuplicateArtifactsConsumerTest.java (added) +++ archiva/trunk/archiva-modules/plugins/problem-reports/src/test/java/org/apache/archiva/reports/consumers/DuplicateArtifactsConsumerTest.java Tue Mar 9 04:24:32 2010 @@ -0,0 +1,215 @@ +package org.apache.archiva.reports.consumers; + +/* + * 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.model.MetadataFacet; +import org.apache.archiva.metadata.repository.MetadataRepository; +import org.apache.archiva.metadata.repository.storage.RepositoryPathTranslator; +import org.apache.archiva.reports.RepositoryProblemFacet; +import org.apache.maven.archiva.configuration.ManagedRepositoryConfiguration; +import org.apache.maven.archiva.consumers.ConsumerException; +import org.apache.maven.archiva.consumers.KnownRepositoryContentConsumer; +import org.codehaus.plexus.spring.PlexusInSpringTestCase; +import org.mockito.ArgumentCaptor; +import org.mockito.Matchers; + +import java.io.FileNotFoundException; +import java.util.Arrays; +import java.util.Date; + +import static org.mockito.Mockito.*; + +...@suppresswarnings( {"ThrowableInstanceNeverThrown"} ) +public class DuplicateArtifactsConsumerTest + extends PlexusInSpringTestCase +{ + private DuplicateArtifactsConsumer consumer; + + private ManagedRepositoryConfiguration config; + + private MetadataRepository metadataRepository; + + private static final String TEST_REPO = "test-repo"; + + private static final String TEST_CHECKSUM = "edf5938e646956f445c6ecb719d44579cdeed974"; + + private static final String TEST_PROJECT = "test-artifact"; + + private static final String TEST_NAMESPACE = "com.example.test"; + + private static final String TEST_FILE = + "com/example/test/test-artifact/1.0-SNAPSHOT/test-artifact-1.0-20100308.230825-1.jar"; + + private static final String TEST_VERSION = "1.0-20100308.230825-1"; + + private static final ArtifactMetadata TEST_METADATA = createMetadata( TEST_VERSION ); + + private RepositoryPathTranslator pathTranslator; + + public void setUp() + throws Exception + { + super.setUp(); + + consumer = (DuplicateArtifactsConsumer) lookup( KnownRepositoryContentConsumer.class, "duplicate-artifacts" ); + assertNotNull( consumer ); + + config = new ManagedRepositoryConfiguration(); + config.setId( TEST_REPO ); + config.setLocation( getTestFile( "target/test-repository" ).getAbsolutePath() ); + + metadataRepository = (MetadataRepository) lookup( MetadataRepository.class ); + + pathTranslator = (RepositoryPathTranslator) lookup( RepositoryPathTranslator.class, "maven2" ); + when( pathTranslator.getArtifactForPath( TEST_REPO, TEST_FILE ) ).thenReturn( TEST_METADATA ); + } + + public void testConsumerArtifactNotDuplicated() + throws ConsumerException + { + when( metadataRepository.getArtifactsByChecksum( TEST_REPO, TEST_CHECKSUM ) ).thenReturn( Arrays.asList( + TEST_METADATA ) ); + + consumer.beginScan( config, new Date() ); + consumer.processFile( TEST_FILE ); + consumer.completeScan(); + + verify( metadataRepository, never() ).addMetadataFacet( eq( TEST_REPO ), Matchers.<MetadataFacet>anyObject() ); + } + + // TODO: Doesn't currently work +// public void testConsumerArtifactNotDuplicatedForOtherSnapshots() +// throws ConsumerException +// { +// when( metadataRepository.getArtifactsByChecksum( TEST_REPO, TEST_CHECKSUM ) ).thenReturn( Arrays.asList( +// TEST_METADATA, createMetadata( "1.0-20100309.002023-2" ) ) ); +// +// consumer.beginScan( config, new Date() ); +// consumer.processFile( TEST_FILE ); +// consumer.completeScan(); +// +// verify( metadataRepository, never() ).addMetadataFacet( eq( TEST_REPO ), Matchers.<MetadataFacet>anyObject() ); +// } + + public void testConsumerArtifactDuplicated() + throws ConsumerException + { + when( metadataRepository.getArtifactsByChecksum( TEST_REPO, TEST_CHECKSUM ) ).thenReturn( Arrays.asList( + TEST_METADATA, createMetadata( "1.0" ) ) ); + + consumer.beginScan( config, new Date() ); + consumer.processFile( TEST_FILE ); + consumer.completeScan(); + + ArgumentCaptor<RepositoryProblemFacet> argument = ArgumentCaptor.forClass( RepositoryProblemFacet.class ); + verify( metadataRepository ).addMetadataFacet( eq( TEST_REPO ), argument.capture() ); + RepositoryProblemFacet problem = argument.getValue(); + assertProblem( problem ); + } + + public void testConsumerArtifactDuplicatedButSelfNotInMetadataRepository() + throws ConsumerException + { + when( metadataRepository.getArtifactsByChecksum( TEST_REPO, TEST_CHECKSUM ) ).thenReturn( Arrays.asList( + createMetadata( "1.0" ) ) ); + + consumer.beginScan( config, new Date() ); + consumer.processFile( TEST_FILE ); + consumer.completeScan(); + + ArgumentCaptor<RepositoryProblemFacet> argument = ArgumentCaptor.forClass( RepositoryProblemFacet.class ); + verify( metadataRepository ).addMetadataFacet( eq( TEST_REPO ), argument.capture() ); + RepositoryProblemFacet problem = argument.getValue(); + assertProblem( problem ); + } + + public void testConsumerArtifactFileNotExist() + throws ConsumerException + { + consumer.beginScan( config, new Date() ); + try + { + consumer.processFile( "com/example/test/test-artifact/2.0/test-artifact-2.0.jar" ); + fail( "Should have failed to find file" ); + } + catch ( ConsumerException e ) + { + assertTrue( e.getCause() instanceof FileNotFoundException ); + } + finally + { + consumer.completeScan(); + } + + verify( metadataRepository, never() ).addMetadataFacet( eq( TEST_REPO ), Matchers.<MetadataFacet>anyObject() ); + } + + public void testConsumerArtifactNotAnArtifactPathNoResults() + throws ConsumerException + { + consumer.beginScan( config, new Date() ); + // No exception unnecessarily for something we can't report on + consumer.processFile( "com/example/invalid-artifact.txt" ); + consumer.completeScan(); + + verify( metadataRepository, never() ).addMetadataFacet( eq( TEST_REPO ), Matchers.<MetadataFacet>anyObject() ); + } + + public void testConsumerArtifactNotAnArtifactPathResults() + throws ConsumerException + { + when( metadataRepository.getArtifactsByChecksum( eq( TEST_REPO ), anyString() ) ).thenReturn( Arrays.asList( + TEST_METADATA, createMetadata( "1.0" ) ) ); + + // override, this feels a little overspecified though + when( pathTranslator.getArtifactForPath( TEST_REPO, "com/example/invalid-artifact.txt" ) ).thenThrow( + new IllegalArgumentException() ); + + consumer.beginScan( config, new Date() ); + // No exception unnecessarily for something we can't report on + consumer.processFile( "com/example/invalid-artifact.txt" ); + consumer.completeScan(); + + verify( metadataRepository, never() ).addMetadataFacet( eq( TEST_REPO ), Matchers.<MetadataFacet>anyObject() ); + } + + private static void assertProblem( RepositoryProblemFacet problem ) + { + assertEquals( TEST_REPO, problem.getRepositoryId() ); + assertEquals( TEST_NAMESPACE, problem.getNamespace() ); + assertEquals( TEST_PROJECT, problem.getProject() ); + assertEquals( TEST_VERSION, problem.getVersion() ); + assertEquals( TEST_PROJECT + "-" + TEST_VERSION + ".jar", problem.getId() ); + assertNotNull( problem.getMessage() ); + assertEquals( "duplicate-artifact", problem.getProblem() ); + } + + private static ArtifactMetadata createMetadata( String version ) + { + ArtifactMetadata artifact = new ArtifactMetadata(); + artifact.setId( TEST_PROJECT + "-" + version + ".jar" ); + artifact.setNamespace( TEST_NAMESPACE ); + artifact.setProject( TEST_PROJECT ); + artifact.setVersion( version ); + artifact.setRepositoryId( TEST_REPO ); + return artifact; + } +} Added: archiva/trunk/archiva-modules/plugins/problem-reports/src/test/java/org/apache/archiva/reports/consumers/MockitoFactory.java URL: http://svn.apache.org/viewvc/archiva/trunk/archiva-modules/plugins/problem-reports/src/test/java/org/apache/archiva/reports/consumers/MockitoFactory.java?rev=920649&view=auto ============================================================================== --- archiva/trunk/archiva-modules/plugins/problem-reports/src/test/java/org/apache/archiva/reports/consumers/MockitoFactory.java (added) +++ archiva/trunk/archiva-modules/plugins/problem-reports/src/test/java/org/apache/archiva/reports/consumers/MockitoFactory.java Tue Mar 9 04:24:32 2010 @@ -0,0 +1,51 @@ +package org.apache.archiva.reports.consumers; + +/* + * 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.springframework.beans.factory.FactoryBean; + +import static org.mockito.Mockito.mock; + +public class MockitoFactory + implements FactoryBean +{ + private final Class<Object> type; + + public MockitoFactory( Class<Object> type ) + { + this.type = type; + } + + public Object getObject() + throws Exception + { + return mock( type ); + } + + public Class getObjectType() + { + return type; + } + + public boolean isSingleton() + { + return true; + } +} Added: archiva/trunk/archiva-modules/plugins/problem-reports/src/test/resources/META-INF/spring-context.xml URL: http://svn.apache.org/viewvc/archiva/trunk/archiva-modules/plugins/problem-reports/src/test/resources/META-INF/spring-context.xml?rev=920649&view=auto ============================================================================== --- archiva/trunk/archiva-modules/plugins/problem-reports/src/test/resources/META-INF/spring-context.xml (added) +++ archiva/trunk/archiva-modules/plugins/problem-reports/src/test/resources/META-INF/spring-context.xml Tue Mar 9 04:24:32 2010 @@ -0,0 +1,32 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + ~ Licensed to the Apache Software Foundation (ASF) under one + ~ or more contributor license agreements. See the NOTICE file + ~ distributed with this work for additional information + ~ regarding copyright ownership. The ASF licenses this file + ~ to you under the Apache License, Version 2.0 (the + ~ "License"); you may not use this file except in compliance + ~ with the License. You may obtain a copy of the License at + ~ + ~ http://www.apache.org/licenses/LICENSE-2.0 + ~ + ~ Unless required by applicable law or agreed to in writing, + ~ software distributed under the License is distributed on an + ~ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + ~ KIND, either express or implied. See the License for the + ~ specific language governing permissions and limitations + ~ under the License. + --> + +<beans xmlns="http://www.springframework.org/schema/beans" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> + <bean id="metadataRepositoryFactory" class="org.apache.archiva.reports.consumers.MockitoFactory" + name="metadataRepository"> + <constructor-arg value="org.apache.archiva.metadata.repository.MetadataRepository"/> + </bean> + <bean id="repositoryPathTranslatorFactory" class="org.apache.archiva.reports.consumers.MockitoFactory" + name="repositoryPathTranslator#maven2"> + <constructor-arg value="org.apache.archiva.metadata.repository.storage.RepositoryPathTranslator"/> + </bean> +</beans> \ No newline at end of file Modified: archiva/trunk/pom.xml URL: http://svn.apache.org/viewvc/archiva/trunk/pom.xml?rev=920649&r1=920648&r2=920649&view=diff ============================================================================== --- archiva/trunk/pom.xml (original) +++ archiva/trunk/pom.xml Tue Mar 9 04:24:32 2010 @@ -331,11 +331,6 @@ </dependency> <dependency> <groupId>org.apache.archiva</groupId> - <artifactId>archiva-artifact-reports</artifactId> - <version>1.4-SNAPSHOT</version> - </dependency> - <dependency> - <groupId>org.apache.archiva</groupId> <artifactId>archiva-checksum</artifactId> <version>1.4-SNAPSHOT</version> </dependency> @@ -361,11 +356,6 @@ </dependency> <dependency> <groupId>org.apache.archiva</groupId> - <artifactId>archiva-dependency-graph</artifactId> - <version>1.4-SNAPSHOT</version> - </dependency> - <dependency> - <groupId>org.apache.archiva</groupId> <artifactId>archiva-core-consumers</artifactId> <version>1.4-SNAPSHOT</version> </dependency> @@ -376,12 +366,7 @@ </dependency> <dependency> <groupId>org.apache.archiva</groupId> - <artifactId>archiva-database</artifactId> - <version>1.4-SNAPSHOT</version> - </dependency> - <dependency> - <groupId>org.apache.archiva</groupId> - <artifactId>archiva-database-consumers</artifactId> + <artifactId>test-repository</artifactId> <version>1.4-SNAPSHOT</version> </dependency> <dependency>
