Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--bundles/org.eclipse.equinox.p2.artifact.repository/META-INF/MANIFEST.MF1
-rw-r--r--bundles/org.eclipse.equinox.p2.artifact.repository/plugin.xml13
-rw-r--r--bundles/org.eclipse.equinox.p2.artifact.repository/schema/artifactChecksums.exsd139
-rw-r--r--bundles/org.eclipse.equinox.p2.artifact.repository/src/org/eclipse/equinox/internal/p2/artifact/processors/checksum/ChecksumUtilities.java142
-rw-r--r--bundles/org.eclipse.equinox.p2.artifact.repository/src/org/eclipse/equinox/internal/p2/artifact/processors/checksum/ChecksumVerifier.java86
-rw-r--r--bundles/org.eclipse.equinox.p2.artifact.repository/src/org/eclipse/equinox/internal/p2/artifact/processors/checksum/Messages.java31
-rw-r--r--bundles/org.eclipse.equinox.p2.artifact.repository/src/org/eclipse/equinox/internal/p2/artifact/processors/checksum/messages.properties14
-rw-r--r--bundles/org.eclipse.equinox.p2.artifact.repository/src/org/eclipse/equinox/internal/p2/artifact/processors/md5/MD5Verifier.java13
-rw-r--r--bundles/org.eclipse.equinox.p2.artifact.repository/src/org/eclipse/equinox/internal/p2/artifact/repository/Messages.java6
-rw-r--r--bundles/org.eclipse.equinox.p2.artifact.repository/src/org/eclipse/equinox/internal/p2/artifact/repository/RawMirrorRequest.java9
-rw-r--r--bundles/org.eclipse.equinox.p2.artifact.repository/src/org/eclipse/equinox/internal/p2/artifact/repository/messages.properties6
-rw-r--r--bundles/org.eclipse.equinox.p2.artifact.repository/src/org/eclipse/equinox/internal/p2/artifact/repository/simple/SimpleArtifactRepository.java27
-rw-r--r--bundles/org.eclipse.equinox.p2.publisher/META-INF/MANIFEST.MF1
-rw-r--r--bundles/org.eclipse.equinox.p2.publisher/src/org/eclipse/equinox/spi/p2/publisher/PublisherHelper.java45
-rw-r--r--bundles/org.eclipse.equinox.p2.repository.tools/META-INF/MANIFEST.MF1
-rw-r--r--bundles/org.eclipse.equinox.p2.repository.tools/plugin.xml6
-rw-r--r--bundles/org.eclipse.equinox.p2.repository.tools/src/org/eclipse/equinox/p2/internal/repository/comparator/ArtifactChecksumComparator.java62
-rw-r--r--bundles/org.eclipse.equinox.p2.repository.tools/src/org/eclipse/equinox/p2/internal/repository/comparator/MD5ArtifactComparator.java9
-rw-r--r--bundles/org.eclipse.equinox.p2.repository.tools/src/org/eclipse/equinox/p2/internal/repository/tools/Messages.java6
-rw-r--r--bundles/org.eclipse.equinox.p2.repository.tools/src/org/eclipse/equinox/p2/internal/repository/tools/RecreateRepositoryApplication.java28
-rw-r--r--bundles/org.eclipse.equinox.p2.repository.tools/src/org/eclipse/equinox/p2/internal/repository/tools/messages.properties8
-rw-r--r--bundles/org.eclipse.equinox.p2.repository.tools/src/org/eclipse/equinox/p2/repository/tools/comparator/ArtifactComparatorFactory.java63
-rw-r--r--bundles/org.eclipse.equinox.p2.repository/src/org/eclipse/equinox/internal/p2/repository/helpers/ChecksumHelper.java79
-rw-r--r--bundles/org.eclipse.equinox.p2.repository/src/org/eclipse/equinox/internal/p2/repository/helpers/ChecksumProducer.java58
-rw-r--r--bundles/org.eclipse.equinox.p2.repository/src/org/eclipse/equinox/p2/repository/artifact/IArtifactDescriptor.java25
-rw-r--r--bundles/org.eclipse.equinox.p2.tests/META-INF/MANIFEST.MF1
-rw-r--r--bundles/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/artifact/processors/AllTests.java3
-rw-r--r--bundles/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/artifact/processors/ChecksumVerifierTest.java114
-rw-r--r--bundles/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/publisher/AllTests.java3
-rw-r--r--bundles/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/publisher/ChecksumGenerationTest.java57
-rw-r--r--bundles/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/repository/AllTests.java3
-rw-r--r--bundles/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/repository/ChecksumHelperTest.java51
32 files changed, 1018 insertions, 92 deletions
diff --git a/bundles/org.eclipse.equinox.p2.artifact.repository/META-INF/MANIFEST.MF b/bundles/org.eclipse.equinox.p2.artifact.repository/META-INF/MANIFEST.MF
index 4e24d6fe3..657a43558 100644
--- a/bundles/org.eclipse.equinox.p2.artifact.repository/META-INF/MANIFEST.MF
+++ b/bundles/org.eclipse.equinox.p2.artifact.repository/META-INF/MANIFEST.MF
@@ -7,6 +7,7 @@ Bundle-Activator: org.eclipse.equinox.internal.p2.artifact.repository.Activator
Bundle-Vendor: %providerName
Bundle-Localization: plugin
Export-Package: org.eclipse.equinox.internal.p2.artifact.processing;x-friends:="org.eclipse.equinox.p2.artifact.processors,org.eclipse.equinox.p2.artifact.optimizers",
+ org.eclipse.equinox.internal.p2.artifact.processors.checksum;x-friends:="org.eclipse.equinox.p2.publisher",
org.eclipse.equinox.internal.p2.artifact.processors.md5;x-internal:=true,
org.eclipse.equinox.internal.p2.artifact.processors.pack200;x-friends:="org.eclipse.equinox.p2.artifact.processors,org.eclipse.equinox.p2.artifact.optimizers",
org.eclipse.equinox.internal.p2.artifact.repository;
diff --git a/bundles/org.eclipse.equinox.p2.artifact.repository/plugin.xml b/bundles/org.eclipse.equinox.p2.artifact.repository/plugin.xml
index fa791fe2c..6abe0c6f5 100644
--- a/bundles/org.eclipse.equinox.p2.artifact.repository/plugin.xml
+++ b/bundles/org.eclipse.equinox.p2.artifact.repository/plugin.xml
@@ -4,6 +4,7 @@
<extension-point id="artifactRepositories" name="Artifact Repositories" schema="schema/artifactRepositories.exsd"/>
<extension-point id="processingSteps" name="Processing Steps" schema="schema/processingSteps.exsd"/>
<extension-point id="artifactComparators" name="Artifact Comparators" schema="schema/artifactComparators.exsd"/>
+ <extension-point id="artifactChecksums" name="Artifact Checksum support" schema="schema/artifactChecksums.exsd"/>
<extension
point="org.eclipse.equinox.p2.artifact.repository.processingSteps"
@@ -37,4 +38,16 @@
id="org.eclipse.equinox.p2.processing.MD5Verifier">
<step class="org.eclipse.equinox.internal.p2.artifact.processors.md5.MD5Verifier"/>
</extension>
+ <extension
+ point="org.eclipse.equinox.p2.artifact.repository.processingSteps"
+ id="org.eclipse.equinox.p2.processing.ChecksumVerifier">
+ <step class="org.eclipse.equinox.internal.p2.artifact.processors.checksum.ChecksumVerifier"/>
+ </extension>
+ <extension
+ point="org.eclipse.equinox.p2.artifact.repository.artifactChecksums">
+ <artifactChecksum
+ algorithm="SHA-256"
+ id="sha-256">
+ </artifactChecksum>
+ </extension>
</plugin>
diff --git a/bundles/org.eclipse.equinox.p2.artifact.repository/schema/artifactChecksums.exsd b/bundles/org.eclipse.equinox.p2.artifact.repository/schema/artifactChecksums.exsd
new file mode 100644
index 000000000..2dc494040
--- /dev/null
+++ b/bundles/org.eclipse.equinox.p2.artifact.repository/schema/artifactChecksums.exsd
@@ -0,0 +1,139 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<!-- Schema file written by PDE -->
+<schema targetNamespace="org.eclipse.equinox.p2.artifact.repository" xmlns="http://www.w3.org/2001/XMLSchema">
+<annotation>
+ <appInfo>
+ <meta.schema plugin="org.eclipse.equinox.p2.artifact.repository" id="artifactChecksums" name="Artifact Checksum support"/>
+ </appInfo>
+ <documentation>
+ Provides a mapping from checksum algorithm id and &lt;code&gt;java.security.MessageDigest&lt;/code&gt; implementations.
+
+&lt;p&gt;p2 detects errors which may have been introduced during artifact transmission/storage by calculating artifact checksum using MD5 hash function. As a &lt;a href=&quot;https://en.wikipedia.org/wiki/Collision_attack&quot;&gt;collision attack&lt;/a&gt; and a &lt;a href=&quot;https://en.wikipedia.org/wiki/Chosen-prefix_collision_attack&quot;&gt;chosen-prefix collision attack&lt;/a&gt; against MD5 have been demonstrated in public, it can be used but only to detect unintentional corruption. Current implementation is not extensible and doesn&apos;t allow to use other, more collision-resistant, hash functions.&lt;/p&gt;
+
+&lt;p&gt;With this extension point, any &lt;code&gt;java.security.MessageDigest&lt;/code&gt; from Java Security API can be used to check integrity of artifacts. For more information on these APIs, see &lt;a href=&quot;https://docs.oracle.com/javase/8/docs/technotes/guides/security/crypto/CryptoSpec.html&quot;&gt;Java Cryptography Architecture (JCA) Reference Guide&lt;/a&gt;.&lt;/p&gt;
+ </documentation>
+ </annotation>
+
+ <element name="extension">
+ <annotation>
+ <appInfo>
+ <meta.element />
+ </appInfo>
+ </annotation>
+ <complexType>
+ <sequence>
+ <element ref="artifactChecksum" minOccurs="1" maxOccurs="unbounded"/>
+ </sequence>
+ <attribute name="point" type="string" use="required">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ </annotation>
+ </attribute>
+ <attribute name="id" type="string">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ </annotation>
+ </attribute>
+ <attribute name="name" type="string">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ <appInfo>
+ <meta.attribute translatable="true"/>
+ </appInfo>
+ </annotation>
+ </attribute>
+ </complexType>
+ </element>
+
+ <element name="artifactChecksum">
+ <complexType>
+ <attribute name="id" type="string" use="required">
+ <annotation>
+ <documentation>
+ id of the checksum algorithm, i.e. &lt;code&gt;sha-512&lt;/code&gt;.
+
+As other tools will rely on this id, consider using some well-defined value (i.e. &lt;a href=&quot;https://www.iana.org/assignments/hash-function-text-names/hash-function-text-names.xhtml&quot;&gt;Hash Function Textual Names&lt;/a&gt; ).
+ </documentation>
+ </annotation>
+ </attribute>
+ <attribute name="algorithm" type="string" use="required">
+ <annotation>
+ <documentation>
+ Name of the message digest algorithm as expected by &lt;code&gt;java.security.MessageDigest&lt;/code&gt;&apos;s method &lt;code&gt;getInstance(String)&lt;/code&gt;. Also check the MessageDigest section in the Java Cryptography Architecture Standard Algorithm Name Documentation for information about standard algorithm names.
+ </documentation>
+ </annotation>
+ </attribute>
+ </complexType>
+ </element>
+
+ <annotation>
+ <appInfo>
+ <meta.section type="since"/>
+ </appInfo>
+ <documentation>
+ 2.4.0
+ </documentation>
+ </annotation>
+
+ <annotation>
+ <appInfo>
+ <meta.section type="examples"/>
+ </appInfo>
+ <documentation>
+ To enable support for MessageDigest implementation which is provided by a statically registered Provider, contributing bundle should only register an extension:
+
+&lt;pre&gt;
+&lt;extension point=&quot;org.eclipse.equinox.p2.artifact.repository.artifactChecksums&quot;&gt;
+ &lt;artifactChecksum
+ algorithm=&quot;SHA3-512&quot;
+ id=&quot;sha3-512&quot;&gt;
+ &lt;/artifactChecksum&gt;
+&lt;/extension&gt;
+&lt;/pre&gt;
+
+If the MessageDigest implementation is provided by a custom Provider (from the contributing bundle itself or some other bundle), it should be first dynamically registered:
+
+&lt;pre&gt;
+import java.security.Security;
+import org.bouncycastle.jce.provider.BouncyCastleProvider;
+
+public class Activator implements BundleActivator {
+
+ public void start(BundleContext context) throws Exception {
+ Security.addProvider(new BouncyCastleProvider());
+ }
+}
+&lt;/pre&gt;
+ </documentation>
+ </annotation>
+
+ <annotation>
+ <appInfo>
+ <meta.section type="implementation"/>
+ </appInfo>
+ <documentation>
+ Contributes a checksum algorithm with id &lt;code&gt;sha-256&lt;code&gt; and maps it to &lt;code&gt;SHA-256&lt;/code&gt; MessageDigest implementation.
+ </documentation>
+ </annotation>
+
+ <annotation>
+ <appInfo>
+ <meta.section type="copyright"/>
+ </appInfo>
+ <documentation>
+ Copyright (c) 2015, 2018 Mykola Nikishov.
+
+All rights reserved. This program and the accompanying materials
+are made available under the terms of the Eclipse Public License v1.0
+which accompanies this distribution, and is available at
+http://www.eclipse.org/legal/epl-v10.html
+ </documentation>
+ </annotation>
+
+</schema>
diff --git a/bundles/org.eclipse.equinox.p2.artifact.repository/src/org/eclipse/equinox/internal/p2/artifact/processors/checksum/ChecksumUtilities.java b/bundles/org.eclipse.equinox.p2.artifact.repository/src/org/eclipse/equinox/internal/p2/artifact/processors/checksum/ChecksumUtilities.java
index 38635d9f2..b7f9f04fb 100644
--- a/bundles/org.eclipse.equinox.p2.artifact.repository/src/org/eclipse/equinox/internal/p2/artifact/processors/checksum/ChecksumUtilities.java
+++ b/bundles/org.eclipse.equinox.p2.artifact.repository/src/org/eclipse/equinox/internal/p2/artifact/processors/checksum/ChecksumUtilities.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2007, 2018 Mykola Nikishov.
+ * Copyright (c) 2015, 2018 Mykola Nikishov.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
@@ -10,21 +10,147 @@
*******************************************************************************/
package org.eclipse.equinox.internal.p2.artifact.processors.checksum;
-import java.util.ArrayList;
+import java.io.File;
+import java.io.IOException;
+import java.security.NoSuchAlgorithmException;
+import java.util.*;
+import java.util.Map.Entry;
+import org.eclipse.core.runtime.*;
import org.eclipse.equinox.internal.p2.artifact.processors.md5.MD5Verifier;
+import org.eclipse.equinox.internal.p2.artifact.repository.Messages;
+import org.eclipse.equinox.internal.p2.repository.Activator;
+import org.eclipse.equinox.internal.p2.repository.helpers.ChecksumHelper;
+import org.eclipse.equinox.internal.p2.repository.helpers.ChecksumProducer;
import org.eclipse.equinox.internal.provisional.p2.artifact.repository.processing.ProcessingStep;
import org.eclipse.equinox.p2.repository.artifact.IArtifactDescriptor;
+import org.eclipse.osgi.util.NLS;
public class ChecksumUtilities {
+
+ private static final String ARTIFACT_CHECKSUMS_POINT = "org.eclipse.equinox.p2.artifact.repository.artifactChecksums"; //$NON-NLS-1$
+ public static final String MD5 = "md5"; //$NON-NLS-1$
+
+ /**
+ * Instances of checksum verifiers applicable for the artifact descriptor
+ *
+ * @param descriptor
+ * @param property either {@link IArtifactDescriptor#ARTIFACT_CHECKSUM} or {@link IArtifactDescriptor#DOWNLOAD_CHECKSUM}
+ * @param checksumsToSkip
+ * @return list of checksum verifiers
+ * @throws IllegalArgumentException if property neither {@link IArtifactDescriptor#ARTIFACT_CHECKSUM} nor {@link IArtifactDescriptor#DOWNLOAD_CHECKSUM}
+ * @see ChecksumHelper#getChecksums(IArtifactDescriptor, String)
+ */
+ public static Collection<ProcessingStep> getChecksumVerifiers(IArtifactDescriptor descriptor, String property, Set<String> checksumsToSkip) throws IllegalArgumentException {
+ Collection<ProcessingStep> steps = new ArrayList<>();
+ Map<String, String> checksums = ChecksumHelper.getChecksums(descriptor, property);
+
+ IConfigurationElement[] checksumVerifierConfigurations = getChecksumComparatorConfigurations();
+
+ for (Entry<String, String> checksumEntry : checksums.entrySet()) {
+ if (checksumsToSkip.contains(checksumEntry.getKey()))
+ continue;
+
+ for (IConfigurationElement checksumVerifierConfiguration : checksumVerifierConfigurations) {
+ String checksumId = checksumVerifierConfiguration.getAttribute("id"); //$NON-NLS-1$
+ if (checksumEntry.getKey().equals(checksumId)) {
+ String checksumAlgorithm = checksumVerifierConfiguration.getAttribute("algorithm"); //$NON-NLS-1$
+ ChecksumVerifier checksumVerifier = new ChecksumVerifier(checksumAlgorithm, checksumId, checksumEntry.getValue());
+ if (checksumVerifier.getStatus().isOK())
+ steps.add(checksumVerifier);
+ else
+ // TODO log something?
+ continue;
+ }
+ }
+ }
+
+ Optional<MD5Verifier> legacyMd5Verifier = getLegacyMd5Verifier(descriptor, property);
+ legacyMd5Verifier.ifPresent(verifier -> steps.add(verifier));
+
+ return steps;
+ }
+
+ public static IConfigurationElement[] getChecksumComparatorConfigurations() {
+ return RegistryFactory.getRegistry().getConfigurationElementsFor(ARTIFACT_CHECKSUMS_POINT);
+ }
+
/**
- * When enabled, extract property from the artifact descriptor, create instance of MD5Verifier and add it to steps.
- */
- public static void addChecksumVerificationStep(boolean enabled, String property, IArtifactDescriptor descriptor, ArrayList<ProcessingStep> steps) {
- if (enabled && descriptor.getProperty(property) != null) {
- MD5Verifier checksumVerifier = new MD5Verifier(descriptor.getProperty(property));
+ * Caller is responsible for checking the returned status and decide if problems are fatal or not.
+ *
+ * @param pathOnDisk file to calculate checksums for
+ * @param checksums calculated checksums
+ * @param checksumsToSkip
+ * @return status
+ */
+ public static IStatus calculateChecksums(File pathOnDisk, Map<String, String> checksums, Collection<String> checksumsToSkip) {
+ // TODO pathOnDisk.getAbsolutePath() || pathOnDisk.getCanonicalPath()
+ MultiStatus status = new MultiStatus(Activator.ID, IStatus.OK, NLS.bind(Messages.calculateChecksum_file, pathOnDisk.getAbsolutePath()), null);
+ for (IConfigurationElement checksumVerifierConfiguration : ChecksumUtilities.getChecksumComparatorConfigurations()) {
+ String id = checksumVerifierConfiguration.getAttribute("id"); //$NON-NLS-1$
+ if (checksumsToSkip.contains(id))
+ // don't calculate checksum if algo is disabled
+ continue;
+ String algorithm = checksumVerifierConfiguration.getAttribute("algorithm"); //$NON-NLS-1$
+ try {
+ String checksum = ChecksumProducer.produce(pathOnDisk, algorithm);
+ checksums.put(id, checksum);
+ String message = NLS.bind(Messages.calculateChecksum_ok, new Object[] {id, algorithm, checksum});
+ status.add(new Status(IStatus.OK, Activator.ID, message));
+ } catch (NoSuchAlgorithmException e) {
+ String message = NLS.bind(Messages.calculateChecksum_error, id, algorithm);
+ status.add(new Status(IStatus.ERROR, Activator.ID, message, e));
+ } catch (IOException e) {
+ String message = NLS.bind(Messages.calculateChecksum_error, id, algorithm);
+ status.add(new Status(IStatus.ERROR, Activator.ID, message, e));
+ }
+ }
+ return status;
+ }
+
+ /**
+ * @param property either {@link IArtifactDescriptor#ARTIFACT_CHECKSUM} or {@link IArtifactDescriptor#DOWNLOAD_CHECKSUM}
+ * @param checksums
+ */
+ public static Map<String, String> checksumsToProperties(String property, Map<String, String> checksums) {
+ HashMap<String, String> properties = new HashMap<>();
+ for (Entry<String, String> checksum : checksums.entrySet()) {
+ properties.put(String.join(".", property, checksum.getKey()), checksum.getValue()); //$NON-NLS-1$
+ }
+
+ putLegacyMd5Property(property, checksums, properties);
+
+ return properties;
+ }
+
+ private static Optional<MD5Verifier> getLegacyMd5Verifier(IArtifactDescriptor descriptor, String propertyNamespace) {
+ String md5 = null;
+ switch (propertyNamespace) {
+ case IArtifactDescriptor.ARTIFACT_CHECKSUM :
+ md5 = descriptor.getProperty(IArtifactDescriptor.ARTIFACT_MD5);
+ break;
+ case IArtifactDescriptor.DOWNLOAD_CHECKSUM :
+ md5 = descriptor.getProperty(IArtifactDescriptor.DOWNLOAD_MD5);
+ break;
+ default :
+ throw new IllegalArgumentException(propertyNamespace);
+ }
+
+ if (md5 != null) {
+ MD5Verifier checksumVerifier = new MD5Verifier(md5);
if (checksumVerifier.getStatus().isOK())
- steps.add(checksumVerifier);
+ return Optional.of(checksumVerifier);
}
+
+ return Optional.empty();
}
+ private static void putLegacyMd5Property(String propertyNamespace, Map<String, String> checksums, HashMap<String, String> result) {
+ String md5 = checksums.get(ChecksumUtilities.MD5);
+ if (md5 != null) {
+ if (IArtifactDescriptor.ARTIFACT_CHECKSUM.equals(propertyNamespace))
+ result.put(IArtifactDescriptor.ARTIFACT_MD5, md5);
+ if (IArtifactDescriptor.DOWNLOAD_CHECKSUM.equals(propertyNamespace))
+ result.put(IArtifactDescriptor.DOWNLOAD_MD5, md5);
+ }
+ }
}
diff --git a/bundles/org.eclipse.equinox.p2.artifact.repository/src/org/eclipse/equinox/internal/p2/artifact/processors/checksum/ChecksumVerifier.java b/bundles/org.eclipse.equinox.p2.artifact.repository/src/org/eclipse/equinox/internal/p2/artifact/processors/checksum/ChecksumVerifier.java
new file mode 100644
index 000000000..2aa55ea9c
--- /dev/null
+++ b/bundles/org.eclipse.equinox.p2.artifact.repository/src/org/eclipse/equinox/internal/p2/artifact/processors/checksum/ChecksumVerifier.java
@@ -0,0 +1,86 @@
+/*******************************************************************************
+ * Copyright (c) 2015, 2018 Mykola Nikishov.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Mykola Nikishov - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.equinox.internal.p2.artifact.processors.checksum;
+
+import java.io.IOException;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+import java.util.Optional;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.equinox.internal.p2.artifact.repository.Activator;
+import org.eclipse.equinox.internal.p2.repository.helpers.ChecksumHelper;
+import org.eclipse.equinox.internal.provisional.p2.artifact.repository.processing.ProcessingStep;
+import org.eclipse.equinox.p2.core.IProvisioningAgent;
+import org.eclipse.equinox.p2.core.ProvisionException;
+import org.eclipse.equinox.p2.repository.artifact.IArtifactDescriptor;
+import org.eclipse.equinox.p2.repository.artifact.IProcessingStepDescriptor;
+import org.eclipse.osgi.util.NLS;
+
+final public class ChecksumVerifier extends ProcessingStep {
+
+ private String expectedChecksum;
+ private MessageDigest messageDigest;
+ private String algorithmName;
+ private String algorithmId;
+
+ // public to access from tests
+ public ChecksumVerifier(String digestAlgorithm, String algorithmId, String expectedChecksum) {
+ this.algorithmName = digestAlgorithm;
+ this.algorithmId = algorithmId;
+ this.expectedChecksum = expectedChecksum;
+ basicInitialize(null);
+ }
+
+ @Override
+ public final void initialize(IProvisioningAgent agent, IProcessingStepDescriptor descriptor, IArtifactDescriptor context) {
+ super.initialize(agent, descriptor, context);
+ String data = descriptor.getData();
+ if (IArtifactDescriptor.DOWNLOAD_CHECKSUM.concat(".").concat(algorithmId).equals(data)) //$NON-NLS-1$
+ expectedChecksum = ChecksumHelper.getChecksums(context, IArtifactDescriptor.DOWNLOAD_CHECKSUM).get(algorithmId);
+ else if (IArtifactDescriptor.ARTIFACT_CHECKSUM.concat(".").concat(algorithmId).equals(data)) //$NON-NLS-1$
+ expectedChecksum = ChecksumHelper.getChecksums(context, IArtifactDescriptor.ARTIFACT_CHECKSUM).get(algorithmId);
+ else
+ expectedChecksum = data;
+
+ basicInitialize(descriptor);
+ }
+
+ private void basicInitialize(IProcessingStepDescriptor descriptor) {
+ int code = (descriptor == null) ? IStatus.ERROR : descriptor.isRequired() ? IStatus.ERROR : IStatus.INFO;
+ if (Optional.ofNullable(expectedChecksum).orElse("").isEmpty()) //$NON-NLS-1$
+ setStatus(new Status(code, Activator.ID, NLS.bind(Messages.Error_invalid_checksum, algorithmName, expectedChecksum)));
+ try {
+ messageDigest = MessageDigest.getInstance(algorithmName);
+ } catch (NoSuchAlgorithmException e) {
+ setStatus(new Status(code, Activator.ID, NLS.bind(Messages.Error_checksum_unavailable, algorithmName), e));
+ }
+ }
+
+ @Override
+ final public void write(int b) throws IOException {
+ messageDigest.update((byte) b);
+ getDestination().write(b);
+ }
+
+ @Override
+ final public void close() throws IOException {
+ byte[] hashBytes = messageDigest.digest();
+ String hash = ChecksumHelper.toHexString(hashBytes);
+
+ // if the hashes don't line up set the status to error.
+ if (!hash.equals(expectedChecksum))
+ // TODO like ProvisionException.ARTIFACT_MD5_NOT_MATCH but for any checksum
+ setStatus(new Status(IStatus.ERROR, Activator.ID, ProvisionException.ARTIFACT_MD5_NOT_MATCH, NLS.bind(Messages.Error_unexpected_checksum, new Object[] {algorithmName, expectedChecksum, hash}), null));
+ super.close();
+ }
+
+}
diff --git a/bundles/org.eclipse.equinox.p2.artifact.repository/src/org/eclipse/equinox/internal/p2/artifact/processors/checksum/Messages.java b/bundles/org.eclipse.equinox.p2.artifact.repository/src/org/eclipse/equinox/internal/p2/artifact/processors/checksum/Messages.java
new file mode 100644
index 000000000..4d48550a4
--- /dev/null
+++ b/bundles/org.eclipse.equinox.p2.artifact.repository/src/org/eclipse/equinox/internal/p2/artifact/processors/checksum/Messages.java
@@ -0,0 +1,31 @@
+/*******************************************************************************
+ * Copyright (c) 2015, 2018 Mykola Nikishov.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Mykola Nikishov - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.equinox.internal.p2.artifact.processors.checksum;
+
+import org.eclipse.osgi.util.NLS;
+
+public class Messages extends NLS {
+ private static final String BUNDLE_NAME = "org.eclipse.equinox.internal.p2.artifact.processors.checksum.messages"; //$NON-NLS-1$
+
+ public static String Error_invalid_checksum;
+ public static String Error_checksum_unavailable;
+ public static String Error_unexpected_checksum;
+
+ static {
+ // initialize resource bundle
+ NLS.initializeMessages(BUNDLE_NAME, Messages.class);
+ }
+
+ private Messages() {
+ //empty
+ }
+}
diff --git a/bundles/org.eclipse.equinox.p2.artifact.repository/src/org/eclipse/equinox/internal/p2/artifact/processors/checksum/messages.properties b/bundles/org.eclipse.equinox.p2.artifact.repository/src/org/eclipse/equinox/internal/p2/artifact/processors/checksum/messages.properties
new file mode 100644
index 000000000..1281c9061
--- /dev/null
+++ b/bundles/org.eclipse.equinox.p2.artifact.repository/src/org/eclipse/equinox/internal/p2/artifact/processors/checksum/messages.properties
@@ -0,0 +1,14 @@
+###############################################################################
+# Copyright (c) 2015, 2018 Mykola Nikishov.
+# All rights reserved. This program and the accompanying materials
+# are made available under the terms of the Eclipse Public License v1.0
+# which accompanies this distribution, and is available at
+# http://www.eclipse.org/legal/epl-v10.html
+#
+# Contributors:
+# Mykola Nikishov - initial API and implementation
+###############################################################################
+
+Error_invalid_checksum={0} value not available or incorrect size, {1}.
+Error_checksum_unavailable=Could not create {0} algorithm.
+Error_unexpected_checksum={0} hash is not as expected. Expected: {1} and found {2}.
diff --git a/bundles/org.eclipse.equinox.p2.artifact.repository/src/org/eclipse/equinox/internal/p2/artifact/processors/md5/MD5Verifier.java b/bundles/org.eclipse.equinox.p2.artifact.repository/src/org/eclipse/equinox/internal/p2/artifact/processors/md5/MD5Verifier.java
index f152b9997..50d2ff0d3 100644
--- a/bundles/org.eclipse.equinox.p2.artifact.repository/src/org/eclipse/equinox/internal/p2/artifact/processors/md5/MD5Verifier.java
+++ b/bundles/org.eclipse.equinox.p2.artifact.repository/src/org/eclipse/equinox/internal/p2/artifact/processors/md5/MD5Verifier.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2007, 2017 compeople AG and others.
+ * Copyright (c) 2007, 2018 compeople AG and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
@@ -17,6 +17,7 @@ import java.security.NoSuchAlgorithmException;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.equinox.internal.p2.artifact.repository.Activator;
+import org.eclipse.equinox.internal.p2.repository.helpers.ChecksumHelper;
import org.eclipse.equinox.internal.provisional.p2.artifact.repository.processing.ProcessingStep;
import org.eclipse.equinox.p2.core.IProvisioningAgent;
import org.eclipse.equinox.p2.core.ProvisionException;
@@ -24,6 +25,7 @@ import org.eclipse.equinox.p2.repository.artifact.IArtifactDescriptor;
import org.eclipse.equinox.p2.repository.artifact.IProcessingStepDescriptor;
import org.eclipse.osgi.util.NLS;
+@Deprecated
public class MD5Verifier extends ProcessingStep {
protected String expectedMD5;
@@ -73,15 +75,10 @@ public class MD5Verifier extends ProcessingStep {
@Override
public void close() throws IOException {
byte[] digest = md5.digest();
- StringBuilder buf = new StringBuilder();
- for (byte element : digest) {
- if ((element & 0xFF) < 0x10)
- buf.append('0');
- buf.append(Integer.toHexString(element & 0xFF));
- }
+ String buf = ChecksumHelper.toHexString(digest);
// if the hashes don't line up set the status to error.
- if (!buf.toString().equals(expectedMD5))
+ if (!buf.equals(expectedMD5))
setStatus(new Status(IStatus.ERROR, Activator.ID, ProvisionException.ARTIFACT_MD5_NOT_MATCH, NLS.bind(Messages.Error_unexpected_hash, expectedMD5, buf), null));
super.close();
}
diff --git a/bundles/org.eclipse.equinox.p2.artifact.repository/src/org/eclipse/equinox/internal/p2/artifact/repository/Messages.java b/bundles/org.eclipse.equinox.p2.artifact.repository/src/org/eclipse/equinox/internal/p2/artifact/repository/Messages.java
index 4588cec90..e6a4a4091 100644
--- a/bundles/org.eclipse.equinox.p2.artifact.repository/src/org/eclipse/equinox/internal/p2/artifact/repository/Messages.java
+++ b/bundles/org.eclipse.equinox.p2.artifact.repository/src/org/eclipse/equinox/internal/p2/artifact/repository/Messages.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2007, 2010 IBM Corporation and others.
+ * Copyright (c) 2007, 2018 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
@@ -64,6 +64,10 @@ public class Messages extends NLS {
public static String error_copying_local_file;
+ public static String calculateChecksum_file;
+ public static String calculateChecksum_ok;
+ public static String calculateChecksum_error;
+
static {
// initialize resource bundles
NLS.initializeMessages(BUNDLE_NAME, Messages.class);
diff --git a/bundles/org.eclipse.equinox.p2.artifact.repository/src/org/eclipse/equinox/internal/p2/artifact/repository/RawMirrorRequest.java b/bundles/org.eclipse.equinox.p2.artifact.repository/src/org/eclipse/equinox/internal/p2/artifact/repository/RawMirrorRequest.java
index 0e992ba84..cfe61e2dc 100644
--- a/bundles/org.eclipse.equinox.p2.artifact.repository/src/org/eclipse/equinox/internal/p2/artifact/repository/RawMirrorRequest.java
+++ b/bundles/org.eclipse.equinox.p2.artifact.repository/src/org/eclipse/equinox/internal/p2/artifact/repository/RawMirrorRequest.java
@@ -13,7 +13,8 @@
package org.eclipse.equinox.internal.p2.artifact.repository;
import java.io.OutputStream;
-import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
import org.eclipse.core.runtime.*;
import org.eclipse.equinox.internal.p2.artifact.processors.checksum.ChecksumUtilities;
import org.eclipse.equinox.internal.p2.artifact.repository.simple.SimpleArtifactRepository;
@@ -81,15 +82,15 @@ public class RawMirrorRequest extends MirrorRequest {
// Perform the mirror operation without any processing steps
@Override
protected IStatus getArtifact(IArtifactDescriptor artifactDescriptor, OutputStream destination, IProgressMonitor monitor) {
- ArrayList<ProcessingStep> steps = new ArrayList<>();
- ChecksumUtilities.addChecksumVerificationStep(SimpleArtifactRepository.DOWNLOAD_MD5_CHECKSUM_ENABLED, IArtifactDescriptor.DOWNLOAD_MD5, artifactDescriptor, steps);
- if (!steps.isEmpty()) {
+ if (SimpleArtifactRepository.CHECKSUMS_ENABLED) {
+ Collection<ProcessingStep> steps = ChecksumUtilities.getChecksumVerifiers(artifactDescriptor, IArtifactDescriptor.DOWNLOAD_CHECKSUM, Collections.<String> emptySet());
ProcessingStep[] stepArray = steps.toArray(new ProcessingStep[steps.size()]);
// TODO should probably be using createAndLink here
ProcessingStepHandler handler = new ProcessingStepHandler();
destination = handler.link(stepArray, destination, monitor);
}
+
return getSourceRepository().getRawArtifact(artifactDescriptor, destination, monitor);
}
}
diff --git a/bundles/org.eclipse.equinox.p2.artifact.repository/src/org/eclipse/equinox/internal/p2/artifact/repository/messages.properties b/bundles/org.eclipse.equinox.p2.artifact.repository/src/org/eclipse/equinox/internal/p2/artifact/repository/messages.properties
index ada52de67..65c781144 100644
--- a/bundles/org.eclipse.equinox.p2.artifact.repository/src/org/eclipse/equinox/internal/p2/artifact/repository/messages.properties
+++ b/bundles/org.eclipse.equinox.p2.artifact.repository/src/org/eclipse/equinox/internal/p2/artifact/repository/messages.properties
@@ -1,5 +1,5 @@
###############################################################################
-# Copyright (c) 2007, 2010 IBM Corporation and others.
+# Copyright (c) 2007, 2018 IBM Corporation and others.
# All rights reserved. This program and the accompanying materials
# are made available under the terms of the Eclipse Public License v1.0
# which accompanies this distribution, and is available at
@@ -51,6 +51,10 @@ exception_unsupportedAddToComposite = Cannot add descriptors to a composite repo
exception_unsupportedGetOutputStream=Cannot write artifacts to a composite repository.
exception_unsupportedRemoveFromComposite = Cannot remove descriptors from a composite repository.
+calculateChecksum_file=Calculating checksums for file {0}.
+calculateChecksum_ok=Calculated checksum using id={0} algorithm={1}: {2}.
+calculateChecksum_error=Error calculating checksum using id={0} algorithm={1}.
+
exception_unableToCreateParentDir = Unable to create parent directory.
folder_artifact_not_file_repo=Artifact {0} is a folder but the repository is an archive or remote location.
retryRequest=Download of {0} failed on repository {1}. Retrying.
diff --git a/bundles/org.eclipse.equinox.p2.artifact.repository/src/org/eclipse/equinox/internal/p2/artifact/repository/simple/SimpleArtifactRepository.java b/bundles/org.eclipse.equinox.p2.artifact.repository/src/org/eclipse/equinox/internal/p2/artifact/repository/simple/SimpleArtifactRepository.java
index 4dfdbb9ed..efdfca82b 100644
--- a/bundles/org.eclipse.equinox.p2.artifact.repository/src/org/eclipse/equinox/internal/p2/artifact/repository/simple/SimpleArtifactRepository.java
+++ b/bundles/org.eclipse.equinox.p2.artifact.repository/src/org/eclipse/equinox/internal/p2/artifact/repository/simple/SimpleArtifactRepository.java
@@ -12,6 +12,7 @@
* Sonatype Inc - ongoing development
* EclipseSource - file locking and ongoing development
* Red Hat Inc. - Fix compiler problems from generified IAdaptable#getAdapter
+ * Mykola Nikishov - multiple artifact checksums
*******************************************************************************/
package org.eclipse.equinox.internal.p2.artifact.repository.simple;
@@ -55,8 +56,18 @@ public class SimpleArtifactRepository extends AbstractArtifactRepository impleme
public static final boolean MIRRORS_ENABLED = !"false".equals(Activator.getContext().getProperty("eclipse.p2.mirrors")); //$NON-NLS-1$//$NON-NLS-2$
/**
+ * A boolean property controlling whether any checksums of the artifact should be checked.
+ * @see IArtifactDescriptor#DOWNLOAD_MD5
+ * @see IArtifactDescriptor#DOWNLOAD_CHECKSUM
+ * @see IArtifactDescriptor#ARTIFACT_MD5
+ * @see IArtifactDescriptor#ARTIFACT_CHECKSUM
+ */
+ public static final boolean CHECKSUMS_ENABLED = !"true".equals(Activator.getContext().getProperty("eclipse.p2.checksums.disable")); //$NON-NLS-1$//$NON-NLS-2$
+
+ /**
* A boolean property controlling whether MD5 checksum of the artifact bytes that are transferred should be checked.
* @see IArtifactDescriptor#DOWNLOAD_MD5
+ * @see IArtifactDescriptor#DOWNLOAD_CHECKSUM
*/
public static final boolean DOWNLOAD_MD5_CHECKSUM_ENABLED = !"false".equals(Activator.getContext().getProperty("eclipse.p2.MD5Check")); //$NON-NLS-1$//$NON-NLS-2$
@@ -64,6 +75,7 @@ public class SimpleArtifactRepository extends AbstractArtifactRepository impleme
* A boolean property controlling whether MD5 checksum of the artifact bytes in its native format (after processing steps have
* been applied) should be checked.
* @see IArtifactDescriptor#ARTIFACT_MD5
+ * @see IArtifactDescriptor#ARTIFACT_CHECKSUM
*/
public static final boolean ARTIFACT_MD5_CHECKSUM_ENABLED = !"false".equals(Activator.getContext().getProperty("eclipse.p2.MD5ArtifactCheck")); //$NON-NLS-1$//$NON-NLS-2$
@@ -459,7 +471,9 @@ public class SimpleArtifactRepository extends AbstractArtifactRepository impleme
private synchronized OutputStream addPostSteps(ProcessingStepHandler handler, IArtifactDescriptor descriptor, OutputStream destination, IProgressMonitor monitor) {
ArrayList<ProcessingStep> steps = new ArrayList<>();
steps.add(new SignatureVerifier());
- ChecksumUtilities.addChecksumVerificationStep(ARTIFACT_MD5_CHECKSUM_ENABLED, IArtifactDescriptor.ARTIFACT_MD5, descriptor, steps);
+
+ Set<String> skipChecksums = ARTIFACT_MD5_CHECKSUM_ENABLED ? Collections.emptySet() : Collections.singleton(ChecksumUtilities.MD5);
+ addChecksumVerifiers(descriptor, steps, skipChecksums, IArtifactDescriptor.ARTIFACT_CHECKSUM);
if (steps.isEmpty())
return destination;
@@ -472,7 +486,9 @@ public class SimpleArtifactRepository extends AbstractArtifactRepository impleme
ArrayList<ProcessingStep> steps = new ArrayList<>();
if (IArtifactDescriptor.TYPE_ZIP.equals(descriptor.getProperty(IArtifactDescriptor.DOWNLOAD_CONTENTTYPE)))
steps.add(new ZipVerifierStep());
- ChecksumUtilities.addChecksumVerificationStep(DOWNLOAD_MD5_CHECKSUM_ENABLED, IArtifactDescriptor.DOWNLOAD_MD5, descriptor, steps);
+
+ Set<String> skipChecksums = DOWNLOAD_MD5_CHECKSUM_ENABLED ? Collections.emptySet() : Collections.singleton(ChecksumUtilities.MD5);
+ addChecksumVerifiers(descriptor, steps, skipChecksums, IArtifactDescriptor.DOWNLOAD_CHECKSUM);
// Add steps here if needed
if (steps.isEmpty())
@@ -482,6 +498,13 @@ public class SimpleArtifactRepository extends AbstractArtifactRepository impleme
return handler.link(stepArray, destination, monitor);
}
+ private void addChecksumVerifiers(IArtifactDescriptor descriptor, ArrayList<ProcessingStep> steps, Set<String> skipChecksums, String property) {
+ if (CHECKSUMS_ENABLED) {
+ Collection<ProcessingStep> checksumVerifiers = ChecksumUtilities.getChecksumVerifiers(descriptor, property, skipChecksums);
+ steps.addAll(checksumVerifiers);
+ }
+ }
+
private byte[] bytesFromHexString(String string) {
byte[] bytes = new byte[UniversalUniqueIdentifier.BYTES_SIZE];
for (int i = 0; i < string.length(); i += 2) {
diff --git a/bundles/org.eclipse.equinox.p2.publisher/META-INF/MANIFEST.MF b/bundles/org.eclipse.equinox.p2.publisher/META-INF/MANIFEST.MF
index e6f90ca50..f8a5e5464 100644
--- a/bundles/org.eclipse.equinox.p2.publisher/META-INF/MANIFEST.MF
+++ b/bundles/org.eclipse.equinox.p2.publisher/META-INF/MANIFEST.MF
@@ -29,6 +29,7 @@ Require-Bundle: org.eclipse.equinox.common;bundle-version="[3.5.0,4.0.0)",
Bundle-RequiredExecutionEnvironment: JavaSE-1.8
Bundle-ActivationPolicy: lazy
Import-Package: org.eclipse.equinox.app;version="1.0.0";resolution:=optional,
+ org.eclipse.equinox.internal.p2.artifact.processors.checksum,
org.eclipse.equinox.internal.p2.artifact.repository,
org.eclipse.equinox.internal.p2.artifact.repository.simple,
org.eclipse.equinox.internal.p2.core.helpers,
diff --git a/bundles/org.eclipse.equinox.p2.publisher/src/org/eclipse/equinox/spi/p2/publisher/PublisherHelper.java b/bundles/org.eclipse.equinox.p2.publisher/src/org/eclipse/equinox/spi/p2/publisher/PublisherHelper.java
index 8fc15de68..5c9186ea8 100644
--- a/bundles/org.eclipse.equinox.p2.publisher/src/org/eclipse/equinox/spi/p2/publisher/PublisherHelper.java
+++ b/bundles/org.eclipse.equinox.p2.publisher/src/org/eclipse/equinox/spi/p2/publisher/PublisherHelper.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2007, 2017 IBM Corporation and others.
+ * Copyright (c) 2007, 2018 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
@@ -10,7 +10,7 @@
* Genuitec, LLC - added license support
* Code 9 - Ongoing development
* SAP AG - consolidation of publishers for PDE formats
- * Mykola Nikishov - extract MD5 checksum calculation
+ * Mykola Nikishov - multiple artifact checksums
*******************************************************************************/
package org.eclipse.equinox.spi.p2.publisher;
@@ -19,6 +19,7 @@ import java.io.IOException;
import java.util.*;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
+import org.eclipse.equinox.internal.p2.artifact.processors.checksum.ChecksumUtilities;
import org.eclipse.equinox.internal.p2.core.helpers.LogHelper;
import org.eclipse.equinox.internal.p2.metadata.ArtifactKey;
import org.eclipse.equinox.internal.p2.metadata.BasicVersion;
@@ -111,22 +112,42 @@ public class PublisherHelper {
ArtifactDescriptor descriptor = (ArtifactDescriptor) result;
descriptor.setProperty(IArtifactDescriptor.ARTIFACT_SIZE, Long.toString(pathOnDisk.length()));
descriptor.setProperty(IArtifactDescriptor.DOWNLOAD_SIZE, Long.toString(pathOnDisk.length()));
- if (info == null || (info.getArtifactOptions() & IPublisherInfo.A_NO_MD5) == 0) {
- try {
- String md5 = ChecksumProducer.computeMD5(pathOnDisk);
- if (md5 != null)
- descriptor.setProperty(IArtifactDescriptor.DOWNLOAD_MD5, md5);
- } catch (IOException e) {
- // don't care if failed to compute checksum
- // TODO provide message?
- LogHelper.log(new Status(IStatus.WARNING, Activator.ID, "", e)); //$NON-NLS-1$
- }
+
+ boolean generateChecksums = info == null || (info.getArtifactOptions() & IPublisherInfo.A_NO_MD5) == 0;
+ if (generateChecksums) {
+ calculateLegacyMd5(pathOnDisk, descriptor);
+ calculateChecksums(pathOnDisk, descriptor);
}
}
}
return result;
}
+ private static void calculateLegacyMd5(File pathOnDisk, ArtifactDescriptor descriptor) {
+ try {
+ String md5 = ChecksumProducer.computeMD5(pathOnDisk);
+ if (md5 != null)
+ descriptor.setProperty(IArtifactDescriptor.DOWNLOAD_MD5, md5);
+ } catch (IOException e) {
+ // don't care if failed to compute checksum
+ // TODO provide message?
+ LogHelper.log(new Status(IStatus.WARNING, Activator.ID, "", e)); //$NON-NLS-1$
+ }
+ }
+
+ private static void calculateChecksums(File pathOnDisk, ArtifactDescriptor descriptor) {
+ // TODO disable specific algorithms
+ List<String> checksumsToSkip = Collections.<String> emptyList();
+ Map<String, String> checksums = new HashMap<>();
+ IStatus status = ChecksumUtilities.calculateChecksums(pathOnDisk, checksums, checksumsToSkip);
+ if (!status.isOK()) {
+ // TODO handle errors in some way
+ LogHelper.log(status);
+ }
+ Map<String, String> checksumProperties = ChecksumUtilities.checksumsToProperties(IArtifactDescriptor.DOWNLOAD_CHECKSUM, checksums);
+ descriptor.addProperties(checksumProperties);
+ }
+
public static IProvidedCapability makeTranslationCapability(String hostId, Locale locale) {
return MetadataFactory.createProvidedCapability(NAMESPACE_IU_LOCALIZATION, locale.toString(), Version.createOSGi(1, 0, 0));
}
diff --git a/bundles/org.eclipse.equinox.p2.repository.tools/META-INF/MANIFEST.MF b/bundles/org.eclipse.equinox.p2.repository.tools/META-INF/MANIFEST.MF
index fd0759bc8..88e69664e 100644
--- a/bundles/org.eclipse.equinox.p2.repository.tools/META-INF/MANIFEST.MF
+++ b/bundles/org.eclipse.equinox.p2.repository.tools/META-INF/MANIFEST.MF
@@ -19,6 +19,7 @@ Bundle-RequiredExecutionEnvironment: JavaSE-1.8
Bundle-ActivationPolicy: lazy
Import-Package: org.eclipse.equinox.app;version="1.0.0",
org.eclipse.equinox.frameworkadmin;version="2.0.0",
+ org.eclipse.equinox.internal.p2.artifact.processors.checksum,
org.eclipse.equinox.internal.p2.artifact.repository,
org.eclipse.equinox.internal.p2.artifact.repository.simple,
org.eclipse.equinox.internal.p2.core.helpers,
diff --git a/bundles/org.eclipse.equinox.p2.repository.tools/plugin.xml b/bundles/org.eclipse.equinox.p2.repository.tools/plugin.xml
index f48caf239..09c381b47 100644
--- a/bundles/org.eclipse.equinox.p2.repository.tools/plugin.xml
+++ b/bundles/org.eclipse.equinox.p2.repository.tools/plugin.xml
@@ -125,6 +125,12 @@
</extension>
<extension point="org.eclipse.equinox.p2.artifact.repository.artifactComparators">
<artifactComparator
+ class="org.eclipse.equinox.p2.internal.repository.comparator.ArtifactChecksumComparator"
+ id="org.eclipse.equinox.artifact.comparator.checksum">
+ </artifactComparator>
+ </extension>
+ <extension point="org.eclipse.equinox.p2.artifact.repository.artifactComparators">
+ <artifactComparator
class="org.eclipse.equinox.p2.internal.repository.comparator.JarComparator"
id="org.eclipse.equinox.p2.repository.tools.jar.comparator">
</artifactComparator>
diff --git a/bundles/org.eclipse.equinox.p2.repository.tools/src/org/eclipse/equinox/p2/internal/repository/comparator/ArtifactChecksumComparator.java b/bundles/org.eclipse.equinox.p2.repository.tools/src/org/eclipse/equinox/p2/internal/repository/comparator/ArtifactChecksumComparator.java
new file mode 100644
index 000000000..0c156e0cb
--- /dev/null
+++ b/bundles/org.eclipse.equinox.p2.repository.tools/src/org/eclipse/equinox/p2/internal/repository/comparator/ArtifactChecksumComparator.java
@@ -0,0 +1,62 @@
+/*******************************************************************************
+ * Copyright (c) 2015, 2018 Mykola Nikishov.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Mykola Nikishov - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.equinox.p2.internal.repository.comparator;
+
+import org.eclipse.core.runtime.*;
+import org.eclipse.equinox.internal.p2.artifact.repository.Activator;
+import org.eclipse.equinox.internal.p2.repository.helpers.ChecksumHelper;
+import org.eclipse.equinox.p2.internal.repository.tools.Messages;
+import org.eclipse.equinox.p2.repository.artifact.IArtifactDescriptor;
+import org.eclipse.equinox.p2.repository.artifact.IArtifactRepository;
+import org.eclipse.equinox.p2.repository.tools.comparator.IArtifactComparator;
+import org.eclipse.osgi.util.NLS;
+
+/**
+ * A comparator that compares two artifacts by checking the checksum
+ * recorded in the artifact descriptor. This comparator doesn't actually compute
+ * checksums directly.
+ */
+final public class ArtifactChecksumComparator implements IArtifactComparator {
+ final public static String COMPARATOR_ID = "org.eclipse.equinox.artifact.comparator.checksum"; //$NON-NLS-1$
+
+ final private String name;
+ final private String id;
+
+ /**
+ * @param checksumId
+ * @param checksumName human-readable name of the checksum algorithm
+ */
+ public ArtifactChecksumComparator(String checksumId, String checksumName) {
+ this.name = checksumName;
+ this.id = checksumId;
+ }
+
+ @Override
+ final public IStatus compare(IArtifactRepository source, IArtifactDescriptor sourceDescriptor, IArtifactRepository destination, IArtifactDescriptor destDescriptor) {
+ String sourceChecksum = ChecksumHelper.getChecksums(sourceDescriptor, IArtifactDescriptor.DOWNLOAD_CHECKSUM).get(id);
+ String destChecksum = ChecksumHelper.getChecksums(destDescriptor, IArtifactDescriptor.DOWNLOAD_CHECKSUM).get(id);
+
+ if (sourceChecksum == null && destChecksum == null)
+ return new Status(IStatus.INFO, Activator.ID, NLS.bind(Messages.info_noChecksumInfomation, name, sourceDescriptor));
+
+ if (sourceChecksum == null)
+ return new Status(IStatus.INFO, Activator.ID, NLS.bind(Messages.info_noChecksumInRepository, new Object[] {source, name, sourceDescriptor}));
+
+ if (destChecksum == null)
+ return new Status(IStatus.INFO, Activator.ID, NLS.bind(Messages.info_noChecksumInRepository, new Object[] {destination, name, destDescriptor}));
+
+ if (sourceChecksum.equals(destChecksum))
+ return Status.OK_STATUS;
+
+ return new Status(IStatus.WARNING, Activator.ID, NLS.bind(Messages.warning_different_checksum, new Object[] {URIUtil.toUnencodedString(sourceDescriptor.getRepository().getLocation()), URIUtil.toUnencodedString(destDescriptor.getRepository().getLocation()), name, sourceDescriptor}));
+ }
+
+}
diff --git a/bundles/org.eclipse.equinox.p2.repository.tools/src/org/eclipse/equinox/p2/internal/repository/comparator/MD5ArtifactComparator.java b/bundles/org.eclipse.equinox.p2.repository.tools/src/org/eclipse/equinox/p2/internal/repository/comparator/MD5ArtifactComparator.java
index a83e931f3..dc0ee1c73 100644
--- a/bundles/org.eclipse.equinox.p2.repository.tools/src/org/eclipse/equinox/p2/internal/repository/comparator/MD5ArtifactComparator.java
+++ b/bundles/org.eclipse.equinox.p2.repository.tools/src/org/eclipse/equinox/p2/internal/repository/comparator/MD5ArtifactComparator.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2008, 2017 IBM Corporation and others.
+ * Copyright (c) 2008, 2018 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
@@ -23,7 +23,14 @@ import org.eclipse.osgi.util.NLS;
* A comparator that compares two artifacts by checking the MD5 checksum
* recorded in the artifact descriptor. This comparator doesn't actually compute MD5
* checksums directly.
+ *
+ * @deprecated
+ * @noreference
+ * @noextend
+ * @noinstantiate
+ * @see ArtifactChecksumComparator
*/
+@Deprecated
public class MD5ArtifactComparator implements IArtifactComparator {
public static String MD5_COMPARATOR_ID = "org.eclipse.equinox.artifact.md5.comparator"; //$NON-NLS-1$
diff --git a/bundles/org.eclipse.equinox.p2.repository.tools/src/org/eclipse/equinox/p2/internal/repository/tools/Messages.java b/bundles/org.eclipse.equinox.p2.repository.tools/src/org/eclipse/equinox/p2/internal/repository/tools/Messages.java
index 47cc723c1..648cd795f 100644
--- a/bundles/org.eclipse.equinox.p2.repository.tools/src/org/eclipse/equinox/p2/internal/repository/tools/Messages.java
+++ b/bundles/org.eclipse.equinox.p2.repository.tools/src/org/eclipse/equinox/p2/internal/repository/tools/Messages.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2009, 2010 IBM Corporation and others.
+ * Copyright (c) 2009, 2018 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
@@ -67,6 +67,10 @@ public class Messages extends NLS {
public static String info_noMD5InRepository;
public static String warning_differentMD5;
+ public static String info_noChecksumInfomation;
+ public static String info_noChecksumInRepository;
+ public static String warning_different_checksum;
+
static {
// initialize resource bundles
NLS.initializeMessages(BUNDLE_NAME, Messages.class);
diff --git a/bundles/org.eclipse.equinox.p2.repository.tools/src/org/eclipse/equinox/p2/internal/repository/tools/RecreateRepositoryApplication.java b/bundles/org.eclipse.equinox.p2.repository.tools/src/org/eclipse/equinox/p2/internal/repository/tools/RecreateRepositoryApplication.java
index 0c56617b9..a56fdb73d 100644
--- a/bundles/org.eclipse.equinox.p2.repository.tools/src/org/eclipse/equinox/p2/internal/repository/tools/RecreateRepositoryApplication.java
+++ b/bundles/org.eclipse.equinox.p2.repository.tools/src/org/eclipse/equinox/p2/internal/repository/tools/RecreateRepositoryApplication.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2009, 2017 IBM Corporation and others.
+ * Copyright (c) 2009, 2018 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
@@ -8,18 +8,18 @@
* Contributors:
* IBM Corporation - initial API and implementation
* Sonatype Inc - ongoing development
+ * Mykola Nikishov - multiple artifact checksums
*******************************************************************************/
package org.eclipse.equinox.p2.internal.repository.tools;
import java.io.File;
-import java.io.IOException;
import java.net.URI;
import java.util.*;
import org.eclipse.core.runtime.*;
+import org.eclipse.equinox.internal.p2.artifact.processors.checksum.ChecksumUtilities;
import org.eclipse.equinox.internal.p2.artifact.repository.simple.SimpleArtifactRepository;
import org.eclipse.equinox.internal.p2.core.helpers.LogHelper;
-import org.eclipse.equinox.internal.p2.repository.helpers.ChecksumProducer;
import org.eclipse.equinox.p2.core.ProvisionException;
import org.eclipse.equinox.p2.metadata.IArtifactKey;
import org.eclipse.equinox.p2.query.IQueryResult;
@@ -31,6 +31,7 @@ import org.eclipse.equinox.p2.repository.artifact.spi.ProcessingStepDescriptor;
import org.eclipse.osgi.util.NLS;
public class RecreateRepositoryApplication extends AbstractApplication {
+ private static final String MD5_CHECKSUM_ID = "md5"; //$NON-NLS-1$
static final private String PUBLISH_PACK_FILES_AS_SIBLINGS = "publishPackFilesAsSiblings"; //$NON-NLS-1$
private URI repoLocation;
private String repoName = null;
@@ -121,15 +122,18 @@ public class RecreateRepositoryApplication extends AbstractApplication {
newDescriptor.setProperty(IArtifactDescriptor.ARTIFACT_SIZE, size);
newDescriptor.setProperty(IArtifactDescriptor.DOWNLOAD_SIZE, size);
- try {
- String md5 = ChecksumProducer.computeMD5(artifactFile);
- if (md5 != null)
- newDescriptor.setProperty(IArtifactDescriptor.DOWNLOAD_MD5, md5);
- } catch (IOException e) {
- // don't care if failed to compute checksum
- // TODO provide message?
- LogHelper.log(new Status(IStatus.WARNING, Activator.ID, "", e));
- }
+ Map<String, String> checksums = new HashMap<>();
+ IStatus status = ChecksumUtilities.calculateChecksums(artifactFile, checksums, Collections.emptyList());
+ if (!status.isOK())
+ // TODO handle errors in some way
+ LogHelper.log(status);
+
+ String md5 = checksums.get(MD5_CHECKSUM_ID);
+ if (md5 != null)
+ // preserve legacy MD5 checksum location
+ newDescriptor.setProperty(IArtifactDescriptor.DOWNLOAD_MD5, md5);
+
+ newDescriptor.addProperties(ChecksumUtilities.checksumsToProperties(IArtifactDescriptor.DOWNLOAD_CHECKSUM, checksums));
File temp = new File(artifactFile.getParentFile(), artifactFile.getName() + ".pack.gz"); //$NON-NLS-1$
if (temp.exists()) {
diff --git a/bundles/org.eclipse.equinox.p2.repository.tools/src/org/eclipse/equinox/p2/internal/repository/tools/messages.properties b/bundles/org.eclipse.equinox.p2.repository.tools/src/org/eclipse/equinox/p2/internal/repository/tools/messages.properties
index aef9767a3..097b86b86 100644
--- a/bundles/org.eclipse.equinox.p2.repository.tools/src/org/eclipse/equinox/p2/internal/repository/tools/messages.properties
+++ b/bundles/org.eclipse.equinox.p2.repository.tools/src/org/eclipse/equinox/p2/internal/repository/tools/messages.properties
@@ -1,5 +1,5 @@
###############################################################################
-# Copyright (c) 2009, 2010 IBM Corporation and others.
+# Copyright (c) 2009, 2018 IBM Corporation and others.
# All rights reserved. This program and the accompanying materials
# are made available under the terms of the Eclipse Public License v1.0
# which accompanies this distribution, and is available at
@@ -15,9 +15,9 @@ CompositeRepository_composite_repository_exists=Composite repository already exi
CompositeRepository_default_artifactRepo_name=Composite Artifact Repository
CompositeRepository_default_metadataRepo_name=Composite Artifact Repository
-info_noMD5Infomation=No MD5 information available for the artifact [{0}].
-info_noMD5InRepository=The repository {0} does not contain MD5 information for artifact [{1}].
-warning_differentMD5=The repositories {0} and {1} have different MD5 sums for the artifact [{2}].
+info_noChecksumInfomation=No {0} information available for the artifact [{1}].
+info_noChecksumInRepository=The repository {0} does not contain {1} information for artifact [{2}].
+warning_different_checksum=The repositories {0} and {1} have different MessageDigest={2} sums for the artifact [{3}].
no_artifactRepo_manager=Unable to acquire artifact repository manager service.
no_metadataRepo_manager=Unable to acquire metadata repository manager service.
diff --git a/bundles/org.eclipse.equinox.p2.repository.tools/src/org/eclipse/equinox/p2/repository/tools/comparator/ArtifactComparatorFactory.java b/bundles/org.eclipse.equinox.p2.repository.tools/src/org/eclipse/equinox/p2/repository/tools/comparator/ArtifactComparatorFactory.java
index 68a249bbc..47074aca1 100644
--- a/bundles/org.eclipse.equinox.p2.repository.tools/src/org/eclipse/equinox/p2/repository/tools/comparator/ArtifactComparatorFactory.java
+++ b/bundles/org.eclipse.equinox.p2.repository.tools/src/org/eclipse/equinox/p2/repository/tools/comparator/ArtifactComparatorFactory.java
@@ -8,14 +8,17 @@
* Contributors:
* IBM Corporation - initial API and implementation
* Compeople AG (Stefan Liebig) - various ongoing maintenance
- * Mykola Nikishov - maintenance and documentation
+ * Mykola Nikishov - multiple artifact checksums
*******************************************************************************/
package org.eclipse.equinox.p2.repository.tools.comparator;
-import java.util.*;
+import java.util.List;
+import java.util.Optional;
import java.util.stream.Collectors;
+import java.util.stream.Stream;
import org.eclipse.core.runtime.IConfigurationElement;
import org.eclipse.core.runtime.RegistryFactory;
+import org.eclipse.equinox.internal.p2.artifact.processors.checksum.ChecksumUtilities;
import org.eclipse.equinox.internal.p2.artifact.repository.Messages;
import org.eclipse.equinox.p2.internal.repository.comparator.*;
import org.eclipse.osgi.util.NLS;
@@ -35,20 +38,43 @@ public class ArtifactComparatorFactory {
* <li><code>org.eclipse.equinox.artifact.md5.comparator</code> for {@link MD5ArtifactComparator}</li>
* </ul>
*
+ * For {@link ArtifactChecksumComparator}, there is no static id that could be used directly. Instead, its extension point id <code>org.eclipse.equinox.artifact.comparator.checksum</code> should be concatenated with id of desired checksum algorithm:
+ * <ul>
+ * <li><code>org.eclipse.equinox.artifact.comparator.checksum.sha-256</code> to use artifact checksum comparator with SHA-256 message digest</li>
+ * <li><code>org.eclipse.equinox.artifact.comparator.checksum.tiger</code> to use Tiger message digest</li>
+ * </ul>
+ *
* @param comparatorID id of the extension contributed to <code>org.eclipse.equinox.p2.artifact.repository.artifactComparators</code> extension point
* @return if found, instance of artifact comparator
* @throws {@link IllegalArgumentException} otherwise
*/
public static IArtifactComparator getArtifactComparator(String comparatorID) {
- List<IConfigurationElement> extensions = Arrays.asList(RegistryFactory.getRegistry().getConfigurationElementsFor(COMPARATOR_POINT));
+ List<IConfigurationElement> extensions = Stream.of(RegistryFactory.getRegistry().getConfigurationElementsFor(COMPARATOR_POINT))
+ .collect(Collectors.toList());
+ // exclude artifact checksum comparator, needs special care
+ extensions.removeIf(extension -> extension.getAttribute(ATTR_ID).equals(ArtifactChecksumComparator.COMPARATOR_ID));
- Optional<IArtifactComparator> artifactComparator = findComparatorConfiguration(comparatorID, extensions).map(ArtifactComparatorFactory::createArtifactComparator);
+ // handle generic artifact comparators
+ Optional<IArtifactComparator> artifactComparator = findComparatorConfiguration(comparatorID, extensions)
+ .map(ArtifactComparatorFactory::createArtifactComparator);
if (artifactComparator.isPresent())
return artifactComparator.get();
+ // handle artifact checksum comparator
+ if (comparatorID != null && comparatorID.startsWith(ArtifactChecksumComparator.COMPARATOR_ID)) {
+ Optional<ArtifactChecksumComparator> checksumComparator = getChecksumComparator(comparatorID);
+ if (checksumComparator.isPresent())
+ return checksumComparator.get();
+ }
+
if (comparatorID != null) {
- String comparators = extensions.stream().map(extension -> extension.getAttribute(ATTR_ID)).collect(Collectors.joining(", ")); //$NON-NLS-1$
- throw new IllegalArgumentException(NLS.bind(Messages.exception_comparatorNotFound, comparatorID, comparators));
+ Stream<String> checksumComparators = Stream.of(ChecksumUtilities.getChecksumComparatorConfigurations())
+ .map(element -> element.getAttribute(CHECKSUM_ID))
+ .map(checksumId -> ArtifactChecksumComparator.COMPARATOR_ID.concat(".").concat(checksumId)); //$NON-NLS-1$
+ Stream<String> comparators = extensions.stream()
+ .map(extension -> extension.getAttribute(ATTR_ID));
+ String availableComparators = Stream.concat(comparators, checksumComparators).collect(Collectors.joining(", ")); //$NON-NLS-1$
+ throw new IllegalArgumentException(NLS.bind(Messages.exception_comparatorNotFound, comparatorID, availableComparators));
}
throw new IllegalArgumentException(Messages.exception_noComparators);
}
@@ -71,4 +97,29 @@ public class ArtifactComparatorFactory {
}
return null;
}
+
+ private static final String CHECKSUM_ID = "id"; //$NON-NLS-1$
+ private static final String CHECKSUM_ALGORITHM = "algorithm"; //$NON-NLS-1$
+
+ private static Optional<ArtifactChecksumComparator> getChecksumComparator(String comparatorId) {
+ boolean hasNoChecksumId = !comparatorId.startsWith(ArtifactChecksumComparator.COMPARATOR_ID.concat(".")); //$NON-NLS-1$
+ if (hasNoChecksumId)
+ return Optional.empty();
+
+ String comparatorChecksum = Optional.ofNullable(comparatorId.substring(ArtifactChecksumComparator.COMPARATOR_ID.length() + 1))
+ .orElse(""); //$NON-NLS-1$
+ if (comparatorChecksum.isEmpty())
+ return Optional.empty();
+
+ IConfigurationElement[] comparatorConfigurations = ChecksumUtilities.getChecksumComparatorConfigurations();
+ Optional<IConfigurationElement> comparator = Stream.of(comparatorConfigurations)
+ .filter(config -> config.getAttribute(CHECKSUM_ID).equals(comparatorChecksum))
+ .findAny();
+
+ return comparator.map(c -> {
+ String checksumName = c.getAttribute(CHECKSUM_ALGORITHM);
+ String checksumId = c.getAttribute(CHECKSUM_ID);
+ return Optional.of(new ArtifactChecksumComparator(checksumId, checksumName));
+ }).orElse(Optional.empty());
+ }
}
diff --git a/bundles/org.eclipse.equinox.p2.repository/src/org/eclipse/equinox/internal/p2/repository/helpers/ChecksumHelper.java b/bundles/org.eclipse.equinox.p2.repository/src/org/eclipse/equinox/internal/p2/repository/helpers/ChecksumHelper.java
new file mode 100644
index 000000000..f87747535
--- /dev/null
+++ b/bundles/org.eclipse.equinox.p2.repository/src/org/eclipse/equinox/internal/p2/repository/helpers/ChecksumHelper.java
@@ -0,0 +1,79 @@
+/*******************************************************************************
+ * Copyright (c) 2015, 2018 Mykola Nikishov
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Mykola Nikishov - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.equinox.internal.p2.repository.helpers;
+
+import java.util.*;
+import java.util.Map.Entry;
+import org.eclipse.equinox.p2.repository.artifact.IArtifactDescriptor;
+
+public class ChecksumHelper {
+
+ private static final String MD5 = "md5"; //$NON-NLS-1$
+
+ /**
+ * @param property either {@link IArtifactDescriptor#ARTIFACT_CHECKSUM} or {@link IArtifactDescriptor#DOWNLOAD_CHECKSUM}
+ * @return (mutable) map of <algorithm,checksum>
+ * @throws IllegalArgumentException if checksum property neither {@link IArtifactDescriptor#ARTIFACT_CHECKSUM} nor {@link IArtifactDescriptor#DOWNLOAD_CHECKSUM}
+ */
+ static public Map<String, String> getChecksums(IArtifactDescriptor descriptor, String property) throws IllegalArgumentException {
+ if (!IArtifactDescriptor.ARTIFACT_CHECKSUM.equals(property) && !IArtifactDescriptor.DOWNLOAD_CHECKSUM.equals(property))
+ // TODO provide more details
+ throw new IllegalArgumentException();
+
+ Map<String, String> checksumsByAlgo = new HashMap<>();
+
+ String md5Checksum = getLegacyMd5Checksum(descriptor, property);
+ if (md5Checksum != null) {
+ checksumsByAlgo.put(MD5, md5Checksum);
+ }
+
+ // get checksum properties
+ for (Entry<String, String> p : descriptor.getProperties().entrySet()) {
+ String key = p.getKey();
+ if (key.startsWith(property)) {
+ String checksumAlgorithmId = key // "artifact.checksum.sha3"
+ .substring(property.length()) // ".sha3"
+ .substring(1); // "sha3"
+ String checksumValue = Objects.requireNonNull(p.getValue());
+ String duplicatedChecksum = checksumsByAlgo.put(checksumAlgorithmId, checksumValue);
+ if (duplicatedChecksum != null)
+ // should never happen - duplicated checksum
+ ;
+ }
+ }
+
+ return checksumsByAlgo;
+ }
+
+ /**
+ * @return MD5 checksum from legacy property, either {@link IArtifactDescriptor#DOWNLOAD_MD5} or {@link IArtifactDescriptor#ARTIFACT_MD5}
+ */
+ private static String getLegacyMd5Checksum(IArtifactDescriptor descriptor, String property) {
+ switch (property) {
+ case IArtifactDescriptor.ARTIFACT_CHECKSUM :
+ return descriptor.getProperty(IArtifactDescriptor.ARTIFACT_MD5);
+ case IArtifactDescriptor.DOWNLOAD_CHECKSUM :
+ return descriptor.getProperty(IArtifactDescriptor.DOWNLOAD_MD5);
+ default :
+ return null;
+ }
+ }
+
+ public static String toHexString(byte[] digest) {
+ StringBuilder buf = new StringBuilder();
+ for (byte element : digest) {
+ if ((element & 0xFF) < 0x10)
+ buf.append('0');
+ buf.append(Integer.toHexString(element & 0xFF));
+ }
+ return buf.toString();
+ }
+}
diff --git a/bundles/org.eclipse.equinox.p2.repository/src/org/eclipse/equinox/internal/p2/repository/helpers/ChecksumProducer.java b/bundles/org.eclipse.equinox.p2.repository/src/org/eclipse/equinox/internal/p2/repository/helpers/ChecksumProducer.java
index fc8cabec6..c6616eb6c 100644
--- a/bundles/org.eclipse.equinox.p2.repository/src/org/eclipse/equinox/internal/p2/repository/helpers/ChecksumProducer.java
+++ b/bundles/org.eclipse.equinox.p2.repository/src/org/eclipse/equinox/internal/p2/repository/helpers/ChecksumProducer.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2009, 2017 IBM Corporation and others.
+ * Copyright (c) 2009, 2018 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
@@ -7,51 +7,53 @@
*
* Contributors:
* IBM Corporation - initial API and implementation
- * Mykola Nikishov - extract MD5 checksum calculation
+ * Mykola Nikishov - multiple artifact checksums
*******************************************************************************/
package org.eclipse.equinox.internal.p2.repository.helpers;
import java.io.*;
-import java.security.MessageDigest;
-import java.security.NoSuchAlgorithmException;
+import java.security.*;
+/**
+ * Calculates a checksum using {@link java.security.MessageDigest}
+ */
public class ChecksumProducer {
+ private static final int BUFFER_SIZE = 4 * 1024;
+
/**
* @param file should not be <code>null</code>
* @return MD5 checksum of the file or <code>null</code> in case of NoSuchAlgorithmException
* @throws IOException
*/
+ @Deprecated
+ // bug #509401 - still here to not break x-friends like in bug #507193
public static String computeMD5(File file) throws IOException {
- InputStream fis = null;
try {
- MessageDigest md5Checker = MessageDigest.getInstance("MD5"); //$NON-NLS-1$
- fis = new BufferedInputStream(new FileInputStream(file));
- int read = -1;
- final int bufferSize = 4 * 1024;
- byte[] buffer = new byte[bufferSize];
- while ((read = fis.read(buffer, 0, bufferSize)) != -1) {
- md5Checker.update(buffer, 0, read);
- }
- byte[] digest = md5Checker.digest();
- StringBuffer buf = new StringBuffer();
- for (int i = 0; i < digest.length; i++) {
- if ((digest[i] & 0xFF) < 0x10)
- buf.append('0');
- buf.append(Integer.toHexString(digest[i] & 0xFF));
- }
- return buf.toString();
+ return produce(file, "MD5"); //$NON-NLS-1$
} catch (NoSuchAlgorithmException e) {
return null;
- } finally {
- if (fis != null)
- try {
- fis.close();
- } catch (IOException e) {
- // ignore
- }
}
}
+ /**
+ * @param file should not be <code>null</code>
+ * @param algorithm {@link java.security.MessageDigest#getInstance(String)}
+ * @return checksum of the file
+ * @throws IOException
+ * @throws NoSuchAlgorithmException
+ */
+ public static String produce(File file, String algorithm) throws IOException, NoSuchAlgorithmException {
+ MessageDigest messageDigest = MessageDigest.getInstance(algorithm);
+ try (InputStream fis = new DigestInputStream(new BufferedInputStream(new FileInputStream(file)), messageDigest)) {
+ byte[] buffer = new byte[BUFFER_SIZE];
+ while (fis.read(buffer) != -1) {
+ // consume stream to update digest
+ }
+ }
+ byte[] digest = messageDigest.digest();
+ return ChecksumHelper.toHexString(digest);
+ }
+
}
diff --git a/bundles/org.eclipse.equinox.p2.repository/src/org/eclipse/equinox/p2/repository/artifact/IArtifactDescriptor.java b/bundles/org.eclipse.equinox.p2.repository/src/org/eclipse/equinox/p2/repository/artifact/IArtifactDescriptor.java
index 81557cf03..826e17a59 100644
--- a/bundles/org.eclipse.equinox.p2.repository/src/org/eclipse/equinox/p2/repository/artifact/IArtifactDescriptor.java
+++ b/bundles/org.eclipse.equinox.p2.repository/src/org/eclipse/equinox/p2/repository/artifact/IArtifactDescriptor.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2007, 2010 IBM Corporation and others.
+ * Copyright (c) 2007, 2018 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
@@ -7,6 +7,7 @@
*
* Contributors:
* IBM Corporation - initial API and implementation
+ * Mykola Nikishov - multiple artifact checksums
*******************************************************************************/
package org.eclipse.equinox.p2.repository.artifact;
@@ -36,11 +37,22 @@ public interface IArtifactDescriptor {
* bytes of the artifact in its native format (after processing steps have been applied).
*/
public static final String ARTIFACT_SIZE = "artifact.size"; //$NON-NLS-1$
+
+ /**
+ * A prefix of an artifact descriptor properties (value "download.checksums") storing checksum
+ * of the artifact bytes that are transferred.
+ * @since 2.4.0
+ */
+ public static final String DOWNLOAD_CHECKSUM = "download.checksum"; //$NON-NLS-1$
+
/**
* An artifact descriptor property (value "download.md5") indicating the MD5
* checksum of the artifact bytes that are transferred.
+ * @see #DOWNLOAD_CHECKSUM
*/
+ @Deprecated
public static final String DOWNLOAD_MD5 = "download.md5"; //$NON-NLS-1$
+
/**
* An artifact descriptor property (value "download.contentType") indicating the
* content type of the artifact bytes that are transferred.
@@ -50,11 +62,22 @@ public interface IArtifactDescriptor {
* An content type (value "application/zip") indicating the content is a zip file.
*/
public static final String TYPE_ZIP = "application/zip"; //$NON-NLS-1$
+
+ /**
+ * An artifact descriptor property (value "artifact.checksums") storing list of
+ * checksums of the artifact bytes in its native format (after processing steps have
+ * been applied).
+ * @since 2.4.0
+ */
+ public static final String ARTIFACT_CHECKSUM = "artifact.checksum"; //$NON-NLS-1$
+
/**
* An artifact descriptor property (value "artifact.md5") indicating the MD5
* checksum of the artifact bytes in its native format (after processing steps have
* been applied).
+ * @see #ARTIFACT_CHECKSUM
*/
+ @Deprecated
public static final String ARTIFACT_MD5 = "artifact.md5"; //$NON-NLS-1$
/**
diff --git a/bundles/org.eclipse.equinox.p2.tests/META-INF/MANIFEST.MF b/bundles/org.eclipse.equinox.p2.tests/META-INF/MANIFEST.MF
index 933a27c65..52d576d36 100644
--- a/bundles/org.eclipse.equinox.p2.tests/META-INF/MANIFEST.MF
+++ b/bundles/org.eclipse.equinox.p2.tests/META-INF/MANIFEST.MF
@@ -63,6 +63,7 @@ Import-Package: javax.xml.parsers,
org.eclipse.ant.core,
org.eclipse.core.filesystem,
org.eclipse.ecf.filetransfer,
+ org.eclipse.equinox.internal.p2.artifact.processors.checksum,
org.eclipse.equinox.internal.p2.artifact.processors.md5,
org.eclipse.equinox.internal.p2.artifact.processors.pack200,
org.eclipse.equinox.internal.p2.artifact.repository,
diff --git a/bundles/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/artifact/processors/AllTests.java b/bundles/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/artifact/processors/AllTests.java
index aeaca5a72..92dac347c 100644
--- a/bundles/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/artifact/processors/AllTests.java
+++ b/bundles/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/artifact/processors/AllTests.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2007, 2008 compeople AG and others.
+ * Copyright (c) 2007, 2018 compeople AG and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
@@ -21,6 +21,7 @@ public class AllTests extends TestCase {
TestSuite suite = new TestSuite(AllTests.class.getName());
suite.addTestSuite(Pack200ProcessorTest.class);
suite.addTestSuite(ZipVerifierProcessorTest.class);
+ suite.addTest(new JUnit4TestAdapter(ChecksumVerifierTest.class));
return suite;
}
diff --git a/bundles/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/artifact/processors/ChecksumVerifierTest.java b/bundles/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/artifact/processors/ChecksumVerifierTest.java
new file mode 100644
index 000000000..c71515105
--- /dev/null
+++ b/bundles/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/artifact/processors/ChecksumVerifierTest.java
@@ -0,0 +1,114 @@
+/*******************************************************************************
+ * Copyright (c) 2015, 2018 Mykola Nikishov.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Mykola Nikishov - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.equinox.p2.tests.artifact.processors;
+
+import static org.easymock.EasyMock.*;
+
+import java.io.IOException;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.HashMap;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.equinox.internal.p2.artifact.processors.checksum.ChecksumVerifier;
+import org.eclipse.equinox.p2.repository.artifact.IArtifactDescriptor;
+import org.eclipse.equinox.p2.repository.artifact.IProcessingStepDescriptor;
+import org.junit.Assert;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+import org.junit.runners.Parameterized.Parameter;
+import org.junit.runners.Parameterized.Parameters;
+
+@RunWith(Parameterized.class)
+public class ChecksumVerifierTest {
+ @Parameters
+ public static Collection<Object[]> generateData() {
+ return Arrays.asList(new Object[][] {
+ {"MD5", "md5", IArtifactDescriptor.DOWNLOAD_CHECKSUM.concat(".md5"), IArtifactDescriptor.ARTIFACT_CHECKSUM.concat(".md5"), "123456789_123456789_123456789_12"},
+ {"SHA-256", "sha-256", IArtifactDescriptor.DOWNLOAD_CHECKSUM.concat(".sha-256"), IArtifactDescriptor.ARTIFACT_CHECKSUM.concat(".sha-256"), "123456789_123456789_123456789_123456789_123456789_123456789_1234"}});
+ }
+
+ @Parameter(0)
+ public String digestAlgorithm;
+ @Parameter(1)
+ public String algorithmId;
+ @Parameter(2)
+ public String downloadProperty;
+ @Parameter(3)
+ public String artifactProperty;
+ @Parameter(4)
+ public String checksum;
+
+ @Test
+ public void testInitialize() throws IOException, IllegalArgumentException, SecurityException {
+ IProcessingStepDescriptor processingStepDescriptor = createMock(IProcessingStepDescriptor.class);
+ expect(processingStepDescriptor.getData()).andReturn(checksum);
+ expect(processingStepDescriptor.isRequired()).andReturn(true);
+ replay(processingStepDescriptor);
+
+ ChecksumVerifier verifier = new ChecksumVerifier(digestAlgorithm, algorithmId, checksum);
+
+ verifier.initialize(null, processingStepDescriptor, null);
+
+ Assert.assertEquals(Status.OK_STATUS, verifier.getStatus());
+
+ verifier.close();
+ verify(processingStepDescriptor);
+ }
+
+ @Test
+ public void testInitialize_DownloadChecksum() throws IOException, IllegalArgumentException, SecurityException {
+ IProcessingStepDescriptor processingStepDescriptor = createMock(IProcessingStepDescriptor.class);
+ expect(processingStepDescriptor.getData()).andReturn(downloadProperty);
+ expect(processingStepDescriptor.isRequired()).andReturn(true);
+ IArtifactDescriptor artifactDescriptor = createMock(IArtifactDescriptor.class);
+ replay(processingStepDescriptor);
+ expect(artifactDescriptor.getProperty(eq(downloadProperty))).andReturn(checksum);
+ expect(artifactDescriptor.getProperty(not(eq(downloadProperty)))).andReturn(null).times(1, 2);
+ HashMap<String, String> properties = new HashMap<>();
+ properties.put(downloadProperty, checksum);
+ expect(artifactDescriptor.getProperties()).andReturn(properties);
+ replay(artifactDescriptor);
+
+ ChecksumVerifier verifier = new ChecksumVerifier(digestAlgorithm, algorithmId, checksum);
+
+ verifier.initialize(null, processingStepDescriptor, artifactDescriptor);
+
+ Assert.assertEquals(Status.OK_STATUS, verifier.getStatus());
+
+ verifier.close();
+ verify(processingStepDescriptor);
+ }
+
+ @Test
+ public void testInitialize_ArtifactChecksum() throws IOException, IllegalArgumentException, SecurityException {
+ IProcessingStepDescriptor processingStepDescriptor = createMock(IProcessingStepDescriptor.class);
+ expect(processingStepDescriptor.getData()).andReturn(artifactProperty);
+ expect(processingStepDescriptor.isRequired()).andReturn(true);
+ IArtifactDescriptor artifactDescriptor = createMock(IArtifactDescriptor.class);
+ replay(processingStepDescriptor);
+ expect(artifactDescriptor.getProperty(eq(artifactProperty))).andReturn(checksum);
+ HashMap<String, String> properties = new HashMap<>();
+ properties.put(artifactProperty, checksum);
+ expect(artifactDescriptor.getProperties()).andReturn(properties);
+ expect(artifactDescriptor.getProperty(not(eq(artifactProperty)))).andReturn(null).times(1, 2);
+ replay(artifactDescriptor);
+
+ ChecksumVerifier verifier = new ChecksumVerifier(digestAlgorithm, algorithmId, checksum);
+
+ verifier.initialize(null, processingStepDescriptor, artifactDescriptor);
+
+ Assert.assertEquals(Status.OK_STATUS, verifier.getStatus());
+
+ verifier.close();
+ verify(processingStepDescriptor);
+ }
+}
diff --git a/bundles/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/publisher/AllTests.java b/bundles/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/publisher/AllTests.java
index 348b1b170..d2697791c 100644
--- a/bundles/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/publisher/AllTests.java
+++ b/bundles/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/publisher/AllTests.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2008, 2011 Code 9 and others. All rights reserved. This
+ * Copyright (c) 2008, 2018 Code 9 and others. All rights reserved. This
* program and the accompanying materials are made available under the terms of
* the Eclipse Public License v1.0 which accompanies this distribution, and is
* available at http://www.eclipse.org/legal/epl-v10.html
@@ -34,6 +34,7 @@ public class AllTests extends TestCase {
suite.addTestSuite(LocalizationTests.class);
suite.addTestSuite(LocalUpdateSiteActionTest.class);
suite.addTestSuite(MD5GenerationTest.class);
+ suite.addTest(new JUnit4TestAdapter(ChecksumGenerationTest.class));
suite.addTestSuite(ProductActionTest.class);
suite.addTestSuite(ProductActionCapturingTest.class);
suite.addTestSuite(ProductActionTestMac.class);
diff --git a/bundles/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/publisher/ChecksumGenerationTest.java b/bundles/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/publisher/ChecksumGenerationTest.java
new file mode 100644
index 000000000..e6d3cca2e
--- /dev/null
+++ b/bundles/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/publisher/ChecksumGenerationTest.java
@@ -0,0 +1,57 @@
+/*******************************************************************************
+ * Copyright (c) 2015, 2018 Mykola Nikishov.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Mykola Nikishov - multiple artifact checksums
+ *******************************************************************************/
+package org.eclipse.equinox.p2.tests.publisher;
+
+import java.util.Arrays;
+import java.util.Collection;
+import org.eclipse.equinox.internal.p2.metadata.ArtifactKey;
+import org.eclipse.equinox.p2.metadata.Version;
+import org.eclipse.equinox.p2.repository.artifact.IArtifactDescriptor;
+import org.eclipse.equinox.p2.tests.AbstractProvisioningTest;
+import org.eclipse.equinox.spi.p2.publisher.PublisherHelper;
+import org.hamcrest.CoreMatchers;
+import org.junit.Assert;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+import org.junit.runners.Parameterized.Parameter;
+import org.junit.runners.Parameterized.Parameters;
+
+@RunWith(Parameterized.class)
+public class ChecksumGenerationTest extends AbstractProvisioningTest {
+ @Parameter(0)
+ public String checksumProperty;
+ @Parameter(1)
+ public String checksumValue;
+
+ @Parameters
+ public static Collection<Object[]> generateChecksums() {
+ return Arrays.asList(new Object[][] {{IArtifactDescriptor.DOWNLOAD_MD5, "50d4ea58b02706ab373a908338877e02"}, {IArtifactDescriptor.DOWNLOAD_CHECKSUM.concat(".sha-256"), "11da2dd636ab76f460513cbcbfe8c56a6e5ad47aa9b38b36c6d04f8ee7722252"}});
+ }
+
+ @Test
+ public void testGenerationFile() {
+ IArtifactDescriptor ad = PublisherHelper.createArtifactDescriptor(new ArtifactKey("classifierTest", "idTest", Version.createOSGi(1, 0, 0)), getTestData("Artifact to generate from", "testData/artifactRepo/simpleWithMD5/plugins/aaPlugin_1.0.0.jar"));
+ assertEquals(String.format("%s checksum property", checksumProperty), checksumValue, ad.getProperty(checksumProperty));
+ }
+
+ @Test
+ public void testGenerationFolder() {
+ IArtifactDescriptor ad = PublisherHelper.createArtifactDescriptor(new ArtifactKey("classifierTest", "idTest", Version.createOSGi(1, 0, 0)), getTestData("Artifact to generate from", "testData/artifactRepo/simpleWithMD5/plugins/"));
+ assertEquals(String.format("%s checksum property", checksumProperty), null, ad.getProperty(checksumProperty));
+ }
+
+ @Test
+ public void testGenerationNoFolder() {
+ IArtifactDescriptor ad = PublisherHelper.createArtifactDescriptor(new ArtifactKey("classifierTest", "idTest", Version.createOSGi(1, 0, 0)), null);
+ Assert.assertThat(ad.getProperty(checksumProperty), CoreMatchers.not(CoreMatchers.containsString(checksumValue)));
+ }
+}
diff --git a/bundles/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/repository/AllTests.java b/bundles/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/repository/AllTests.java
index f01588cda..852cb758f 100644
--- a/bundles/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/repository/AllTests.java
+++ b/bundles/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/repository/AllTests.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2009, 2012 Cloudsmith Inc and others.
+ * Copyright (c) 2009, 2018 Cloudsmith Inc and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
@@ -23,6 +23,7 @@ public class AllTests extends TestCase {
suite.addTestSuite(RepositoryHelperTest.class);
suite.addTestSuite(RepositoryExtensionPointTest.class);
suite.addTestSuite(FileReaderTest2.class);
+ suite.addTest(new JUnit4TestAdapter(ChecksumHelperTest.class));
return suite;
}
}
diff --git a/bundles/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/repository/ChecksumHelperTest.java b/bundles/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/repository/ChecksumHelperTest.java
new file mode 100644
index 000000000..7eeddfb6e
--- /dev/null
+++ b/bundles/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/repository/ChecksumHelperTest.java
@@ -0,0 +1,51 @@
+/*******************************************************************************
+ * Copyright (c) 2015, 2018 Mykola Nikishov.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Mykola Nikishov - initial API and implementation
+ ******************************************************************************/
+package org.eclipse.equinox.p2.tests.repository;
+
+import java.util.*;
+import org.eclipse.equinox.internal.p2.metadata.ArtifactKey;
+import org.eclipse.equinox.internal.p2.metadata.OSGiVersion;
+import org.eclipse.equinox.internal.p2.repository.helpers.ChecksumHelper;
+import org.eclipse.equinox.p2.repository.artifact.IArtifactDescriptor;
+import org.eclipse.equinox.p2.repository.artifact.spi.ArtifactDescriptor;
+import org.junit.Assert;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+import org.junit.runners.Parameterized.Parameter;
+import org.junit.runners.Parameterized.Parameters;
+
+@RunWith(Parameterized.class)
+public class ChecksumHelperTest {
+ @Parameters
+ public static Collection<Object[]> generateData() {
+ return Arrays.asList(new Object[][] {{IArtifactDescriptor.ARTIFACT_CHECKSUM}, {IArtifactDescriptor.DOWNLOAD_CHECKSUM}});
+ }
+
+ @Parameter(0)
+ public String property;
+
+ @Test
+ public void testGetChecksums() {
+ String checksumId = "checksumAlgo";
+ String checksumValue = "value";
+ ArtifactDescriptor descriptor = new ArtifactDescriptor(new ArtifactKey("", "", new OSGiVersion(1, 1, 1, "")));
+ descriptor.setProperty(property.concat(".").concat(checksumId), checksumValue);
+ descriptor.setProperty("download.size", "1234");
+ Map<String, String> expectedChecksums = new HashMap<>();
+ expectedChecksums.put(checksumId, checksumValue);
+
+ Map<String, String> checksums = ChecksumHelper.getChecksums(descriptor, property);
+
+ Assert.assertEquals(expectedChecksums, checksums);
+ }
+
+}

Back to the top