From 72861ca005c18782b0a686e6341175417d4d606e Mon Sep 17 00:00:00 2001 From: "Edwin L. Punzalan" Date: Wed, 7 Dec 2005 06:06:27 +0000 Subject: [PATCH] PR: MRM-17 Submitted by: Maria Odea Ching Applied patch for metadata checksum validation git-svn-id: https://svn.apache.org/repos/asf/maven/repository-manager/trunk@354729 13f79535-47bb-0310-9956-ffa450edef68 --- .../reporting/ChecksumArtifactReporter.java | 97 +++++++--- .../resources/META-INF/plexus/components.xml | 6 + .../AbstractChecksumArtifactReporterTest.java | 179 +++++++++++++++++- .../ChecksumArtifactReporterTest.java | 115 ++++++++++- 4 files changed, 362 insertions(+), 35 deletions(-) diff --git a/maven-repository-reports-standard/src/main/java/org/apache/maven/repository/reporting/ChecksumArtifactReporter.java b/maven-repository-reports-standard/src/main/java/org/apache/maven/repository/reporting/ChecksumArtifactReporter.java index 7631053c0..dd773d142 100644 --- a/maven-repository-reports-standard/src/main/java/org/apache/maven/repository/reporting/ChecksumArtifactReporter.java +++ b/maven-repository-reports-standard/src/main/java/org/apache/maven/repository/reporting/ChecksumArtifactReporter.java @@ -34,6 +34,9 @@ import org.apache.maven.artifact.repository.*; /** * This class reports invalid and mismatched checksums of artifacts and metadata files. * It validates MD5 and SHA-1 chacksums. + * + * @TODO + * - Validate using remote repository. */ public class ChecksumArtifactReporter implements ArtifactReportProcessor, MetadataReportProcessor @@ -54,16 +57,22 @@ public class ChecksumArtifactReporter public void processArtifact( Model model, Artifact artifact, ArtifactReporter reporter, ArtifactRepository repository ) { + System.out.println( " " ); + System.out + .println( "===================================== +++++ PROCESS ARTIFACT +++++ ====================================" ); String artifactUrl = ""; String repositoryUrl = repository.getUrl(); + System.out.println("REPOSITORY PROTOCOL ------>>>> " + repository.getProtocol()); artifactUrl = repositoryUrl + artifact.getGroupId() + "/" + artifact.getArtifactId() + "/" + artifact.getBaseVersion() + "/" + artifact.getArtifactId() + "-" + artifact.getBaseVersion() + "." + artifact.getType(); + //System.out.println("ARTIFACT URL ------->>>> " + artifactUrl); //check if checksum files exist boolean md5Exists = getMD5File( artifactUrl ); boolean sha1Exists = getSHA1File( artifactUrl ); + if ( md5Exists ) { if ( validateChecksum( artifactUrl, "MD5" ) ) @@ -95,37 +104,63 @@ public class ChecksumArtifactReporter */ public void processMetadata( RepositoryMetadata metadata, ArtifactRepository repository, ArtifactReporter reporter ) { + System.out.println( " " ); + System.out + .println( "====================================== +++++ PROCESS METADATA +++++ ==============================" ); + + String metadataUrl = ""; + String repositoryUrl = repository.getUrl(); + String filename = metadata.getRemoteFilename(); + + //version metadata + if ( metadata.storedInArtifactVersionDirectory() == true && metadata.storedInGroupDirectory() == false ) + { + metadataUrl = repositoryUrl + metadata.getGroupId() + "/" + metadata.getArtifactId() + "/" + + metadata.getBaseVersion() + "/"; + //group metadata + } + else if ( metadata.storedInArtifactVersionDirectory() == false && metadata.storedInGroupDirectory() == true ) + { + metadataUrl = repositoryUrl + metadata.getGroupId() + "/"; + //artifact metadata + } + else + { + metadataUrl = repositoryUrl + metadata.getGroupId() + "/" + metadata.getArtifactId() + "/"; + } + + //add the file name of the metadata + metadataUrl = metadataUrl + filename; + //System.out.println( "METADATA URL -------> " + metadataUrl ); + + //check if checksum files exist + boolean md5Exists = getMD5File( metadataUrl ); + boolean sha1Exists = getSHA1File( metadataUrl ); + + if ( md5Exists ) + { + if ( validateChecksum( metadataUrl, "MD5" ) ) + { + reporter.addSuccess( metadata ); + } + else + { + reporter.addFailure( metadata, "MD5 checksum does not match." ); + } + } + + if ( sha1Exists ) + { + if ( validateChecksum( metadataUrl, "SHA-1" ) ) + { + reporter.addSuccess( metadata ); + } + else + { + reporter.addFailure( metadata, "SHA-1 checksum does not match." ); + } + } - /* - String metadataUrl = ""; - String filename = metadata.getLocalFilename(repository); - String repositoryUrl = repository.getUrl(); - - String groupId, artifactId, version; - version = metadata.getBaseVersion(); - groupId = metadata.getGroupId(); - artifactId = metadata.getArtifactId(); - - //version metadata - if(metadata.storedInArtifactVersionDirectory() == true && metadata.storedInGroupDirectory() == false){ - metadataUrl = repositoryUrl + groupId + "/" + artifactId + "/" + version; - //group metadata - }else if(metadata.storedInArtifactVersionDirectory() == false && metadata.storedInGroupDirectory() == true){ - metadataUrl = repositoryUrl + groupId; - //artifact metadata - }else{ - metadataUrl = repositoryUrl + groupId + "/" + artifactId; - } - - metadataUrl = metadataUrl + "/" + filename; - boolean valid = validateChecksum(metadataUrl); - - if(!valid){ - reporter.addFailure(metadata, "Mismatched metadata checksum."); - }else{ - reporter.addSuccess(metadata); - } - */ } /** @@ -138,6 +173,7 @@ public class ChecksumArtifactReporter try { md5InputStream = new FileInputStream( filename + ".md5" ); + md5InputStream.close(); } catch ( Exception e ) { @@ -156,6 +192,7 @@ public class ChecksumArtifactReporter try { sha1InputStream = new FileInputStream( filename + ".sha1" ); + sha1InputStream.close(); } catch ( Exception e ) { diff --git a/maven-repository-reports-standard/src/main/resources/META-INF/plexus/components.xml b/maven-repository-reports-standard/src/main/resources/META-INF/plexus/components.xml index c840b62a9..4aba02130 100644 --- a/maven-repository-reports-standard/src/main/resources/META-INF/plexus/components.xml +++ b/maven-repository-reports-standard/src/main/resources/META-INF/plexus/components.xml @@ -23,5 +23,11 @@ org.apache.maven.repository.reporting.ChecksumArtifactReporter per-lookup + + org.apache.maven.repository.reporting.MetadataReportProcessor + checksum-metadata + org.apache.maven.repository.reporting.ChecksumArtifactReporter + per-lookup + diff --git a/maven-repository-reports-standard/src/test/java/org/apache/maven/repository/reporting/AbstractChecksumArtifactReporterTest.java b/maven-repository-reports-standard/src/test/java/org/apache/maven/repository/reporting/AbstractChecksumArtifactReporterTest.java index ac1faf20d..bc75e85d8 100644 --- a/maven-repository-reports-standard/src/test/java/org/apache/maven/repository/reporting/AbstractChecksumArtifactReporterTest.java +++ b/maven-repository-reports-standard/src/test/java/org/apache/maven/repository/reporting/AbstractChecksumArtifactReporterTest.java @@ -33,6 +33,13 @@ import java.security.NoSuchAlgorithmException; import java.util.jar.JarEntry; import java.util.jar.JarOutputStream; +/** + * @TODO + * - Create more valid and invalid artifacts & metadata files for further testing. + * + * This class creates the artifact and metadata files used for testing the ChecksumArtifactReporter. + * It is extended by ChecksumArtifactReporterTest class. + */ public class AbstractChecksumArtifactReporterTest extends AbstractRepositoryReportsTestCase { @@ -40,6 +47,8 @@ public class AbstractChecksumArtifactReporterTest protected static final String[] invalidArtifactChecksumJars = { "invalidArtifact-1.0" }; + protected static final String metadataChecksumFilename = "maven-metadata"; + public AbstractChecksumArtifactReporterTest() { } @@ -92,6 +101,29 @@ public class AbstractChecksumArtifactReporterTest return written; } + /** + * Create checksum files for metadata. + * @param type The type of checksum to be created. (Valid or invalid) + * @return + */ + protected boolean createMetadataFile( String type ) + { + boolean written = true; + + //loop through the valid artifact names.. + if ( type.equals( "VALID" ) ) + { + writeMetadataFile( "checksumTest/validArtifact/1.0/", metadataChecksumFilename, "xml", true ); + + } + else if ( type.equals( "INVALID" ) ) + { + writeMetadataFile( "checksumTest/invalidArtifact/1.0/", metadataChecksumFilename, "xml", false ); + } + + return written; + } + /** * Create artifact together with its checksums. * @param relativePath The groupId @@ -102,12 +134,13 @@ public class AbstractChecksumArtifactReporterTest */ private boolean writeChecksumFile( String relativePath, String filename, String type, boolean isValid ) { + System.out.println( " " ); + System.out.println( "========================= ARTIFACT CHECKSUM ==================================" ); //Initialize variables for creating jar files FileOutputStream f = null; JarOutputStream out = null; String repoUrl = super.repository.getUrl(); - try { String dirs = filename.replace( '-', '/' ); @@ -178,6 +211,76 @@ public class AbstractChecksumArtifactReporterTest return true; } + /** + * Create metadata file together with its checksums. + * @param relativePath The groupId + * @param filename The filename of the artifact to be created. + * @param type The file type (JAR) + * @param isValid Indicates whether the checksum to be created is valid or not. + * @return + */ + private boolean writeMetadataFile( String relativePath, String filename, String type, boolean isValid ) + { + System.out.println( " " ); + System.out.println( "========================= METADATA CHECKSUM ==================================" ); + try + { + //create checksum for the metadata file.. + String repoUrl = super.repository.getUrl(); + + //System.out.println( "REPO URL :::: " + repoUrl ); + String[] split1 = repoUrl.split( "file:/" ); + split1[1] = split1[1] + "/"; + + // get the pre-created metadata file + String[] split = split1[1].split( "/repository" ); + String url = split[0] + "/" + filename + "." + type; + //System.out.println( "URL of maven-metadata file :: " + url ); + + boolean copied = copyFile( url, split1[1] + relativePath + filename + "." + type ); + //System.out.println( "META FILE COPIED ---->>> " + copied ); + + //Create md5 and sha-1 checksum files.. + byte[] md5chk = createChecksum( split1[1] + relativePath + filename + "." + type, "MD5" ); + byte[] sha1chk = createChecksum( split1[1] + relativePath + filename + "." + type, "SHA-1" ); + System.out.println( "----- CREATED MD5 checksum ::: " + byteArrayToHexStr( md5chk ) ); + System.out.println( "----- CREATED SHA-1 checksum ::: " + byteArrayToHexStr( sha1chk ) ); + + File file = null; + + if ( md5chk != null ) + { + file = new File( split1[1] + relativePath + filename + "." + type + ".md5" ); + OutputStream os = new FileOutputStream( file ); + OutputStreamWriter osw = new OutputStreamWriter( os ); + if ( !isValid ) + osw.write( byteArrayToHexStr( md5chk ) + "1" ); + else + osw.write( byteArrayToHexStr( md5chk ) ); + osw.close(); + } + + if ( sha1chk != null ) + { + file = new File( split1[1] + relativePath + filename + "." + type + ".sha1" ); + OutputStream os = new FileOutputStream( file ); + OutputStreamWriter osw = new OutputStreamWriter( os ); + if ( !isValid ) + osw.write( byteArrayToHexStr( sha1chk ) + "2" ); + else + osw.write( byteArrayToHexStr( sha1chk ) ); + osw.close(); + } + } + catch ( Exception e ) + { + e.printStackTrace(); + return false; + } + + return true; + } + /** * Create the sample file that will be included in the jar. * @param filename @@ -257,4 +360,78 @@ public class AbstractChecksumArtifactReporterTest return output.toUpperCase(); } + /** + * Copy created metadata file to the repository. + * @param srcUrl + * @param destUrl + * @return + */ + private boolean copyFile( String srcUrl, String destUrl ) + { + try + { + //source file + File src = new File( srcUrl ); + //destination file + File dest = new File( destUrl ); + + InputStream in = new FileInputStream( src ); + OutputStream out = new FileOutputStream( dest ); + + byte[] buf = new byte[1024]; + int len; + while ( ( len = in.read( buf ) ) > 0 ) + { + out.write( buf, 0, len ); + } + in.close(); + out.close(); + } + catch ( Exception e ) + { + return false; + } + return true; + } + + /** + * Delete the test directory created in the repository. + * @param dirname The directory to be deleted. + * @return + */ + protected boolean deleteTestDirectory( File dir ) + { + boolean b = false; + + if ( dir.isDirectory() == true ) + { + if ( dir.listFiles().length > 0 ) + { + File[] files = dir.listFiles(); + for ( int i = 0; i < files.length; i++ ) + { + b = this.deleteTestDirectory( files[i] ); + + //check if this is the last file in the directory + //delete the parent file + if((i == (files.length - 1)) && b == true){ + String[] split = dir.getAbsolutePath().split("/repository"); + if(!files[i].getParent().equals(split[0] + "/repository")){ + b = this.deleteTestDirectory(new File(files[i].getParent())); + } + } + } + + }else{ + b = dir.delete(); + } + } + else + { + b = dir.delete(); + } + + return b; + } + } diff --git a/maven-repository-reports-standard/src/test/java/org/apache/maven/repository/reporting/ChecksumArtifactReporterTest.java b/maven-repository-reports-standard/src/test/java/org/apache/maven/repository/reporting/ChecksumArtifactReporterTest.java index 3cb486357..940b3cd5d 100644 --- a/maven-repository-reports-standard/src/test/java/org/apache/maven/repository/reporting/ChecksumArtifactReporterTest.java +++ b/maven-repository-reports-standard/src/test/java/org/apache/maven/repository/reporting/ChecksumArtifactReporterTest.java @@ -17,6 +17,8 @@ package org.apache.maven.repository.reporting; * limitations under the License. */ +import java.io.File; +import java.util.Iterator; import org.apache.maven.artifact.Artifact; import org.apache.maven.artifact.DefaultArtifact; import org.apache.maven.artifact.handler.ArtifactHandler; @@ -24,10 +26,18 @@ import org.apache.maven.artifact.handler.DefaultArtifactHandler; import org.apache.maven.artifact.repository.ArtifactRepository; import org.apache.maven.artifact.repository.DefaultArtifactRepository; import org.apache.maven.artifact.repository.layout.DefaultRepositoryLayout; +import org.apache.maven.artifact.repository.metadata.RepositoryMetadata; +import org.apache.maven.artifact.repository.metadata.SnapshotArtifactRepositoryMetadata; import org.apache.maven.artifact.versioning.VersionRange; -import java.util.Iterator; - +/** + * @TODO + * - Test with multiple success and multiple failures + * - Test using remote repository + * + * This class tests the ChecksumArtifactReporter. + * It extends the AbstractChecksumArtifactReporterTest class. + */ public class ChecksumArtifactReporterTest extends AbstractChecksumArtifactReporterTest { @@ -35,6 +45,8 @@ public class ChecksumArtifactReporterTest private ArtifactReporter reporter = new MockArtifactReporter(); + private MetadataReportProcessor metadataReportProcessor; + public ChecksumArtifactReporterTest() { @@ -45,20 +57,39 @@ public class ChecksumArtifactReporterTest { super.setUp(); artifactReportProcessor = (ArtifactReportProcessor) lookup( ArtifactReportProcessor.ROLE, "default" ); + metadataReportProcessor = (MetadataReportProcessor) lookup( MetadataReportProcessor.ROLE, "checksum-metadata" ); + + // boolean b = createChecksumFile( "VALID" ); + // b = createChecksumFile( "INVALID" ); + // b = createMetadataFile( "VALID" ); + // b = createMetadataFile( "INVALID" ); } public void tearDown() throws Exception { super.tearDown(); + //String[] split = super.repository.getUrl().split("file:/"); + //boolean b = deleteTestDirectory(new File(split[1] + "checksumTest") ); } + /** + * Test creation of artifact with checksum files. + * + */ public void testCreateChecksumFile() { assertTrue( createChecksumFile( "VALID" ) ); assertTrue( createChecksumFile( "INVALID" ) ); } + public void testCreateMetadataFile() + { + assertTrue( createMetadataFile( "VALID" ) ); + assertTrue( createMetadataFile( "INVALID" ) ); + } + + /** * Test the ChecksumArtifactReporter when the checksum files are valid. */ @@ -73,6 +104,13 @@ public class ChecksumArtifactReporterTest ArtifactRepository repository = new DefaultArtifactRepository( "repository", System.getProperty( "basedir" ) + "/src/test/repository/", new DefaultRepositoryLayout() ); + /* VersionRange version = VersionRange.createFromVersion("0.3-3"); + Artifact artifact = new DefaultArtifact("HTTPClient", "HTTPClient", version, "compile", "jar", "", + handler); + ArtifactRepository repository = new DefaultArtifactRepository("remote-repo", "http://www.ibiblio.org/maven2/", + new DefaultRepositoryLayout()); + */ + artifactReportProcessor.processArtifact( null, artifact, reporter, repository ); Iterator iter = reporter.getArtifactSuccessIterator(); @@ -82,7 +120,7 @@ public class ChecksumArtifactReporterTest ArtifactResult result = (ArtifactResult) iter.next(); ctr++; } - System.out.println( "Number of success --- " + ctr ); + System.out.println( "ARTIFACT Number of success --- " + ctr ); } catch ( Exception e ) @@ -115,7 +153,7 @@ public class ChecksumArtifactReporterTest ArtifactResult result = (ArtifactResult) iter.next(); ctr++; } - System.out.println( "Number of failures --- " + ctr ); + System.out.println( "ARTIFACT Number of failures --- " + ctr ); } catch ( Exception e ) @@ -123,4 +161,73 @@ public class ChecksumArtifactReporterTest e.printStackTrace(); } } + + public void testChecksumMetadataReporterSuccess() + { + + try + { + ArtifactHandler handler = new DefaultArtifactHandler( "jar" ); + ArtifactRepository repository = new DefaultArtifactRepository( "repository", System.getProperty( "basedir" ) + + "/src/test/repository/", new DefaultRepositoryLayout() ); + VersionRange version = VersionRange.createFromVersion( "1.0" ); + Artifact artifact = new DefaultArtifact( "checksumTest", "validArtifact", version, "compile", "jar", "", + handler ); + + RepositoryMetadata metadata = new SnapshotArtifactRepositoryMetadata( artifact ); + metadataReportProcessor.processMetadata( metadata, repository, reporter ); + + Iterator iter = reporter.getRepositoryMetadataSuccessIterator(); + int ctr = 0; + while ( iter.hasNext() ) + { + RepositoryMetadataResult result = (RepositoryMetadataResult) iter.next(); + ctr++; + } + System.out.println( "REPORT METADATA Number of success --- " + ctr ); + + } + catch ( Exception e ) + { + e.printStackTrace(); + } + } + + public void testChecksumMetadataReporterFailure() + { + + try + { + ArtifactHandler handler = new DefaultArtifactHandler( "jar" ); + ArtifactRepository repository = new DefaultArtifactRepository( "repository", System.getProperty( "basedir" ) + + "/src/test/repository/", new DefaultRepositoryLayout() ); + VersionRange version = VersionRange.createFromVersion( "1.0" ); + Artifact artifact = new DefaultArtifact( "checksumTest", "invalidArtifact", version, "compile", "jar", "", + handler ); + + RepositoryMetadata metadata = new SnapshotArtifactRepositoryMetadata( artifact ); + metadataReportProcessor.processMetadata( metadata, repository, reporter ); + + Iterator iter = reporter.getRepositoryMetadataFailureIterator(); + int ctr = 0; + while ( iter.hasNext() ) + { + RepositoryMetadataResult result = (RepositoryMetadataResult) iter.next(); + ctr++; + } + System.out.println( "REPORT METADATA Number of failures --- " + ctr ); + + } + catch ( Exception e ) + { + e.printStackTrace(); + } + } + + + public void testDeleteTestDirectory(){ + String[] split = super.repository.getUrl().split("file:/"); + assertTrue(deleteTestDirectory(new File(split[1] + "checksumTest") )); + } + }