mirror of https://github.com/apache/archiva.git
[MRM-1025] change duplicate artifact reporting to be a repository scanned consumer to facilitate removing the database unprocessed consumers
git-svn-id: https://svn.apache.org/repos/asf/archiva/branches/MRM-1025@886035 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
ab97829db0
commit
cb96e18f97
|
@ -9,7 +9,7 @@ package org.apache.maven.archiva.consumers.database;
|
|||
* "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
|
||||
* 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
|
||||
|
@ -34,10 +34,7 @@ import org.apache.maven.archiva.database.updater.DatabaseUnprocessedArtifactCons
|
|||
import org.apache.maven.archiva.model.ArchivaArtifact;
|
||||
import org.apache.maven.archiva.model.ArchivaModelCloner;
|
||||
import org.apache.maven.archiva.model.ArchivaProjectModel;
|
||||
import org.apache.maven.archiva.model.CiManagement;
|
||||
import org.apache.maven.archiva.model.IssueManagement;
|
||||
import org.apache.maven.archiva.model.Keys;
|
||||
import org.apache.maven.archiva.model.Organization;
|
||||
import org.apache.maven.archiva.model.RepositoryProblem;
|
||||
import org.apache.maven.archiva.reporting.artifact.CorruptArtifactReport;
|
||||
import org.apache.maven.archiva.repository.ManagedRepositoryContent;
|
||||
|
|
|
@ -40,6 +40,10 @@
|
|||
<groupId>org.apache.archiva</groupId>
|
||||
<artifactId>archiva-repository-layer</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.codehaus.plexus</groupId>
|
||||
<artifactId>plexus-digest</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.codehaus.plexus</groupId>
|
||||
<artifactId>plexus-utils</artifactId>
|
||||
|
|
|
@ -19,25 +19,32 @@ package org.apache.maven.archiva.reporting.artifact;
|
|||
* under the License.
|
||||
*/
|
||||
|
||||
import java.io.File;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.commons.collections.CollectionUtils;
|
||||
import org.apache.maven.archiva.configuration.ArchivaConfiguration;
|
||||
import org.apache.maven.archiva.configuration.ConfigurationNames;
|
||||
import org.apache.maven.archiva.configuration.FileTypes;
|
||||
import org.apache.maven.archiva.configuration.ManagedRepositoryConfiguration;
|
||||
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.database.ArchivaDAO;
|
||||
import org.apache.maven.archiva.database.ArchivaDatabaseException;
|
||||
import org.apache.maven.archiva.database.ObjectNotFoundException;
|
||||
import org.apache.maven.archiva.database.constraints.ArtifactsByChecksumConstraint;
|
||||
import org.apache.maven.archiva.database.updater.ArchivaArtifactConsumer;
|
||||
import org.apache.maven.archiva.model.ArchivaArtifact;
|
||||
import org.apache.maven.archiva.model.RepositoryProblem;
|
||||
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.digest.Digester;
|
||||
import org.codehaus.plexus.digest.DigesterException;
|
||||
import org.codehaus.plexus.personality.plexus.lifecycle.phase.Initializable;
|
||||
import org.codehaus.plexus.personality.plexus.lifecycle.phase.InitializationException;
|
||||
import org.codehaus.plexus.registry.Registry;
|
||||
|
@ -48,17 +55,19 @@ import org.slf4j.LoggerFactory;
|
|||
/**
|
||||
* Search the database of known SHA1 Checksums for potential duplicate artifacts.
|
||||
*
|
||||
* TODO: no need for this to be a scanner - we can just query the database / content repository to get a full list
|
||||
*
|
||||
* @version $Id$
|
||||
*
|
||||
* @plexus.component role="org.apache.maven.archiva.database.updater.ArchivaArtifactConsumer"
|
||||
* role-hint="duplicate-artifacts"
|
||||
* @plexus.component role="org.apache.maven.archiva.consumers.KnownRepositoryContentConsumer"
|
||||
* role-hint="duplicate-artifacts"
|
||||
* instantiation-strategy="per-lookup"
|
||||
*/
|
||||
public class DuplicateArtifactsConsumer
|
||||
extends AbstractMonitoredConsumer
|
||||
implements ArchivaArtifactConsumer, RegistryListener, Initializable
|
||||
implements KnownRepositoryContentConsumer, RegistryListener, Initializable
|
||||
{
|
||||
private Logger log = LoggerFactory.getLogger( DuplicateArtifactsConsumer.class );
|
||||
|
||||
|
||||
/**
|
||||
* @plexus.configuration default-value="duplicate-artifacts"
|
||||
*/
|
||||
|
@ -89,9 +98,19 @@ public class DuplicateArtifactsConsumer
|
|||
*/
|
||||
private RepositoryContentFactory repositoryFactory;
|
||||
|
||||
// TODO: why is this not used? If it should be, what about excludes?
|
||||
private List<String> includes = new ArrayList<String>();
|
||||
|
||||
private File repositoryDir;
|
||||
|
||||
/**
|
||||
* @plexus.requirement role-hint="sha1"
|
||||
*/
|
||||
private Digester digestSha1;
|
||||
|
||||
private String repoId;
|
||||
|
||||
private ManagedRepositoryContent repository;
|
||||
|
||||
public String getId()
|
||||
{
|
||||
return id;
|
||||
|
@ -107,40 +126,62 @@ public class DuplicateArtifactsConsumer
|
|||
return false;
|
||||
}
|
||||
|
||||
public void beginScan()
|
||||
public List<String> getIncludes()
|
||||
{
|
||||
/* do nothing */
|
||||
return includes;
|
||||
}
|
||||
|
||||
public void completeScan()
|
||||
public List<String> getExcludes()
|
||||
{
|
||||
/* do nothing */
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
public List<String> getIncludedTypes()
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
public void processArchivaArtifact( ArchivaArtifact artifact )
|
||||
public void beginScan( ManagedRepositoryConfiguration repo, Date whenGathered )
|
||||
throws ConsumerException
|
||||
{
|
||||
String checksumSha1 = artifact.getModel().getChecksumSHA1();
|
||||
|
||||
List<ArchivaArtifact> results = null;
|
||||
try
|
||||
{
|
||||
results = dao.getArtifactDAO().queryArtifacts( new ArtifactsByChecksumConstraint(
|
||||
checksumSha1, ArtifactsByChecksumConstraint.SHA1 ) );
|
||||
repoId = repo.getId();
|
||||
repository = repositoryFactory.getManagedRepositoryContent( repoId );
|
||||
this.repositoryDir = new File( repository.getRepoRoot() );
|
||||
}
|
||||
catch ( RepositoryException e )
|
||||
{
|
||||
throw new ConsumerException( e.getMessage(), e );
|
||||
}
|
||||
}
|
||||
|
||||
public void processFile( String path )
|
||||
throws ConsumerException
|
||||
{
|
||||
File artifactFile = new File( this.repositoryDir, path );
|
||||
|
||||
// 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
|
||||
String checksumSha1;
|
||||
try
|
||||
{
|
||||
checksumSha1 = digestSha1.calc( artifactFile );
|
||||
}
|
||||
catch ( DigesterException e )
|
||||
{
|
||||
throw new ConsumerException( e.getMessage(), e );
|
||||
}
|
||||
|
||||
List<ArchivaArtifact> results;
|
||||
try
|
||||
{
|
||||
results = dao.getArtifactDAO().queryArtifacts(
|
||||
new ArtifactsByChecksumConstraint( checksumSha1, ArtifactsByChecksumConstraint.SHA1 ) );
|
||||
}
|
||||
catch ( ObjectNotFoundException e )
|
||||
{
|
||||
log.debug( "No duplicates for artifact: " + artifact );
|
||||
log.debug( "No duplicates for artifact: " + path + " (repository " + repoId + ")" );
|
||||
return;
|
||||
}
|
||||
catch ( ArchivaDatabaseException e )
|
||||
{
|
||||
log.warn( "Unable to query DB for potential duplicates with : " + artifact );
|
||||
log.warn( "Unable to query DB for potential duplicates with: " + path + " (repository " + repoId + "): " + e.getMessage(), e );
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -149,10 +190,20 @@ public class DuplicateArtifactsConsumer
|
|||
if ( results.size() <= 1 )
|
||||
{
|
||||
// No duplicates detected.
|
||||
log.debug( "Found no duplicate artifact results on: " + artifact );
|
||||
log.debug( "Found no duplicate artifact results on: " + path + " (repository " + repoId + ")" );
|
||||
return;
|
||||
}
|
||||
|
||||
ArchivaArtifact artifact;
|
||||
try
|
||||
{
|
||||
artifact = new ArchivaArtifact( repository.toArtifactReference( path ), repoId );
|
||||
}
|
||||
catch ( LayoutException e )
|
||||
{
|
||||
log.warn( "Unable to report problem for path: " + path );
|
||||
return;
|
||||
}
|
||||
for ( ArchivaArtifact dupArtifact : results )
|
||||
{
|
||||
if ( dupArtifact.equals( artifact ) )
|
||||
|
@ -163,7 +214,7 @@ public class DuplicateArtifactsConsumer
|
|||
|
||||
RepositoryProblem problem = new RepositoryProblem();
|
||||
problem.setRepositoryId( dupArtifact.getModel().getRepositoryId() );
|
||||
problem.setPath( toPath( dupArtifact ) );
|
||||
problem.setPath( path );
|
||||
problem.setGroupId( artifact.getGroupId() );
|
||||
problem.setArtifactId( artifact.getArtifactId() );
|
||||
problem.setVersion( artifact.getVersion() );
|
||||
|
@ -186,19 +237,9 @@ public class DuplicateArtifactsConsumer
|
|||
}
|
||||
}
|
||||
|
||||
private String toPath( ArchivaArtifact artifact )
|
||||
public void completeScan()
|
||||
{
|
||||
try
|
||||
{
|
||||
String repoId = artifact.getModel().getRepositoryId();
|
||||
ManagedRepositoryContent repo = repositoryFactory.getManagedRepositoryContent( repoId );
|
||||
return repo.toPath( artifact );
|
||||
}
|
||||
catch ( RepositoryException e )
|
||||
{
|
||||
log.warn( "Unable to calculate path for artifact: " + artifact );
|
||||
return "";
|
||||
}
|
||||
// nothing to do
|
||||
}
|
||||
|
||||
public void afterConfigurationChange( Registry registry, String propertyName, Object propertyValue )
|
||||
|
|
|
@ -20,17 +20,20 @@ package org.apache.maven.archiva.reporting.artifact;
|
|||
*/
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.commons.io.FileUtils;
|
||||
import org.apache.maven.archiva.configuration.ArchivaConfiguration;
|
||||
import org.apache.maven.archiva.configuration.ManagedRepositoryConfiguration;
|
||||
import org.apache.maven.archiva.consumers.KnownRepositoryContentConsumer;
|
||||
import org.apache.maven.archiva.database.ArtifactDAO;
|
||||
import org.apache.maven.archiva.database.updater.ArchivaArtifactConsumer;
|
||||
import org.apache.maven.archiva.model.ArchivaArtifact;
|
||||
import org.apache.maven.archiva.model.RepositoryProblem;
|
||||
import org.apache.maven.archiva.reporting.DynamicReportSource;
|
||||
import org.apache.maven.archiva.repository.ManagedRepositoryContent;
|
||||
import org.apache.maven.archiva.repository.RepositoryContentFactory;
|
||||
|
||||
/**
|
||||
* DuplicateArtifactReportTest
|
||||
|
@ -42,14 +45,18 @@ public class DuplicateArtifactReportTest
|
|||
{
|
||||
private static final String TESTABLE_REPO = "testable";
|
||||
|
||||
private static final String HASH3 = "f3f653289f3217c65324830ab3415bc92feddefa";
|
||||
private static final String HASH3 = "94ca33031e37aa3f3b67e5b921c729f08a6bba75";
|
||||
|
||||
private static final String HASH2 = "a49810ad3eba8651677ab57cd40a0f76fdef9538";
|
||||
private static final String HASH2 = "43f7aa390f1a0265fc2de7010133951c0718a67e";
|
||||
|
||||
private static final String HASH1 = "232f01b24b1617c46a3d4b0ab3415bc9237dcdec";
|
||||
private static final String HASH1 = "8107759ababcbfa34bcb02bc4309caf6354982ab";
|
||||
|
||||
private ArtifactDAO artifactDao;
|
||||
|
||||
private ManagedRepositoryConfiguration repoConfig;
|
||||
|
||||
private ManagedRepositoryContent content;
|
||||
|
||||
@Override
|
||||
protected void setUp()
|
||||
throws Exception
|
||||
|
@ -60,19 +67,41 @@ public class DuplicateArtifactReportTest
|
|||
|
||||
ArchivaConfiguration config = (ArchivaConfiguration) lookup( ArchivaConfiguration.class.getName(), "default" );
|
||||
|
||||
ManagedRepositoryConfiguration repoConfig = new ManagedRepositoryConfiguration();
|
||||
repoConfig = new ManagedRepositoryConfiguration();
|
||||
repoConfig.setId( TESTABLE_REPO );
|
||||
repoConfig.setLayout( "default" );
|
||||
File testRepoDir = new File( getBasedir(), "target/test-repository" );
|
||||
FileUtils.forceMkdir( testRepoDir );
|
||||
repoConfig.setLocation( testRepoDir.getAbsolutePath() );
|
||||
config.getConfiguration().addManagedRepository( repoConfig );
|
||||
|
||||
RepositoryContentFactory factory = (RepositoryContentFactory) lookup( RepositoryContentFactory.class );
|
||||
content = factory.getManagedRepositoryContent( TESTABLE_REPO );
|
||||
|
||||
createArtifactFile( testRepoDir, "test-one", "1.0", "value1" );
|
||||
createArtifactFile( testRepoDir, "test-one", "1.1", "value1" );
|
||||
createArtifactFile( testRepoDir, "test-one", "1.2", "value1" );
|
||||
createArtifactFile( testRepoDir, "test-two", "1.0", "value1" );
|
||||
createArtifactFile( testRepoDir, "test-two", "2.0", "value3" );
|
||||
createArtifactFile( testRepoDir, "test-two", "2.1", "value2" );
|
||||
createArtifactFile( testRepoDir, "test-two", "3.0", "value2" );
|
||||
}
|
||||
|
||||
private void createArtifactFile( File testRepoDir, String artifactId, String version, String value )
|
||||
throws IOException
|
||||
{
|
||||
File file = new File( testRepoDir,
|
||||
"org/apache/maven/archiva/test/" + artifactId + "/" + version + "/" + artifactId + "-" +
|
||||
version + ".jar" );
|
||||
file.getParentFile().mkdirs();
|
||||
FileUtils.writeStringToFile( file, value );
|
||||
}
|
||||
|
||||
public ArchivaArtifact createArtifact( String artifactId, String version )
|
||||
{
|
||||
ArchivaArtifact artifact =
|
||||
artifactDao.createArtifact( "org.apache.maven.archiva.test", artifactId, version, "", "jar", TESTABLE_REPO );
|
||||
artifactDao.createArtifact( "org.apache.maven.archiva.test", artifactId, version, "", "jar",
|
||||
TESTABLE_REPO );
|
||||
artifact.getModel().setLastModified( new Date() );
|
||||
return artifact;
|
||||
}
|
||||
|
@ -142,14 +171,15 @@ public class DuplicateArtifactReportTest
|
|||
throws Exception
|
||||
{
|
||||
List<ArchivaArtifact> artifacts = dao.getArtifactDAO().queryArtifacts( null );
|
||||
ArchivaArtifactConsumer consumer =
|
||||
(ArchivaArtifactConsumer) lookup( ArchivaArtifactConsumer.class.getName(), "duplicate-artifacts" );
|
||||
consumer.beginScan();
|
||||
KnownRepositoryContentConsumer consumer =
|
||||
(KnownRepositoryContentConsumer) lookup( KnownRepositoryContentConsumer.class.getName(),
|
||||
"duplicate-artifacts" );
|
||||
consumer.beginScan( repoConfig, new Date() );
|
||||
try
|
||||
{
|
||||
for ( ArchivaArtifact artifact : artifacts )
|
||||
{
|
||||
consumer.processArchivaArtifact( artifact );
|
||||
consumer.processFile( content.toPath( artifact ) );
|
||||
}
|
||||
}
|
||||
finally
|
||||
|
|
|
@ -1,100 +0,0 @@
|
|||
package org.apache.maven.archiva.reporting.project;
|
||||
|
||||
/*
|
||||
* 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.consumers.AbstractMonitoredConsumer;
|
||||
import org.apache.maven.archiva.consumers.ConsumerException;
|
||||
import org.apache.maven.archiva.database.updater.ArchivaArtifactConsumer;
|
||||
import org.apache.maven.archiva.model.ArchivaArtifact;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* ProjectDependenciesConsumer
|
||||
*
|
||||
* @version $Id$
|
||||
*
|
||||
* @plexus.component role="org.apache.maven.archiva.database.updater.ArchivaArtifactConsumer"
|
||||
* role-hint="missing-dependencies"
|
||||
*/
|
||||
public class ProjectDependenciesConsumer
|
||||
extends AbstractMonitoredConsumer
|
||||
implements ArchivaArtifactConsumer
|
||||
{
|
||||
/**
|
||||
* @plexus.configuration default-value="missing-dependencies"
|
||||
*/
|
||||
private String id;
|
||||
|
||||
/**
|
||||
* @plexus.configuration default-value="Check for missing dependencies."
|
||||
*/
|
||||
private String description;
|
||||
|
||||
private List<String> includes;
|
||||
|
||||
public ProjectDependenciesConsumer()
|
||||
{
|
||||
this.includes = new ArrayList<String>();
|
||||
this.includes.add( "pom" );
|
||||
}
|
||||
|
||||
public String getId()
|
||||
{
|
||||
return id;
|
||||
}
|
||||
|
||||
public String getDescription()
|
||||
{
|
||||
return description;
|
||||
}
|
||||
|
||||
public boolean isPermanent()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
public void beginScan()
|
||||
{
|
||||
/* do nothing */
|
||||
}
|
||||
|
||||
public void completeScan()
|
||||
{
|
||||
/* do nothing */
|
||||
}
|
||||
|
||||
public List<String> getIncludedTypes()
|
||||
{
|
||||
return includes;
|
||||
}
|
||||
|
||||
public void processArchivaArtifact( ArchivaArtifact artifact )
|
||||
throws ConsumerException
|
||||
{
|
||||
// TODO: consider loading this logic into the 'update-db-project' consumer.
|
||||
|
||||
// TODO: Load the ArchivaProjectModel.
|
||||
// TODO: Attach a monitor for missing parent poms to resolvers / filters.
|
||||
// TODO: Attach a monitor for missing dependencies to resolvers / filters.
|
||||
// TODO: Fully resolve the ArchivaProjectModel and listen on monitors.
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue