From 8f7af7dbc8025ca6b72d599647d6b305b5cc957e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christoph=20L=C3=A4ubrich?= Date: Fri, 1 Apr 2022 11:35:18 +0200 Subject: [PATCH] Fix #692 Check Hashsums for local cached artifacts MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Christoph Läubrich --- .../META-INF/MANIFEST.MF | 3 +- .../local/LocalArtifactRepository.java | 10 +++- .../local/MirroringArtifactProvider.java | 56 ++++++++++++++++++- .../ArtifactRepositoryBaseImpl.java | 2 +- 4 files changed, 64 insertions(+), 7 deletions(-) diff --git a/tycho-bundles/org.eclipse.tycho.p2.maven.repository/META-INF/MANIFEST.MF b/tycho-bundles/org.eclipse.tycho.p2.maven.repository/META-INF/MANIFEST.MF index c08b36d2b5..9aa856b8a0 100644 --- a/tycho-bundles/org.eclipse.tycho.p2.maven.repository/META-INF/MANIFEST.MF +++ b/tycho-bundles/org.eclipse.tycho.p2.maven.repository/META-INF/MANIFEST.MF @@ -11,7 +11,8 @@ Require-Bundle: org.eclipse.equinox.common;bundle-version="3.6.100", org.eclipse.equinox.p2.metadata;bundle-version="2.1.0", org.eclipse.equinox.p2.core;bundle-version="2.2.0", org.eclipse.equinox.p2.metadata.repository;bundle-version="1.2.100", - org.eclipse.equinox.p2.artifact.repository;bundle-version="1.1.200" + org.eclipse.equinox.p2.artifact.repository;bundle-version="1.1.200", + org.apache.commons.codec;bundle-version="1.14.0" Export-Package: org.eclipse.tycho.p2.maven.repository, org.eclipse.tycho.p2.maven.repository.xmlio, org.eclipse.tycho.repository.local, diff --git a/tycho-bundles/org.eclipse.tycho.p2.maven.repository/src/main/java/org/eclipse/tycho/repository/local/LocalArtifactRepository.java b/tycho-bundles/org.eclipse.tycho.p2.maven.repository/src/main/java/org/eclipse/tycho/repository/local/LocalArtifactRepository.java index 4bd98e8ad8..5e9ca08126 100644 --- a/tycho-bundles/org.eclipse.tycho.p2.maven.repository/src/main/java/org/eclipse/tycho/repository/local/LocalArtifactRepository.java +++ b/tycho-bundles/org.eclipse.tycho.p2.maven.repository/src/main/java/org/eclipse/tycho/repository/local/LocalArtifactRepository.java @@ -92,9 +92,9 @@ private void loadMaven() { descriptor.getProperties().forEach(copy::setProperty); copy.setProcessingSteps(descriptor.getProcessingSteps()); copy.setRepository(this); - internalAddDescriptor(copy); + super.internalAddDescriptor(copy); } else { - internalAddDescriptor(descriptor); + super.internalAddDescriptor(descriptor); } } } @@ -214,4 +214,10 @@ protected void internalRemoveDescriptors(IArtifactKey key) { super.internalRemoveDescriptors(key); descriptorsOnLastSave.remove(key); } + + @Override + protected void internalAddDescriptor(IArtifactDescriptor descriptor) { + super.internalAddDescriptor(descriptor); + descriptorsOnLastSave.remove(descriptor.getArtifactKey()); + } } diff --git a/tycho-bundles/org.eclipse.tycho.p2.maven.repository/src/main/java/org/eclipse/tycho/repository/local/MirroringArtifactProvider.java b/tycho-bundles/org.eclipse.tycho.p2.maven.repository/src/main/java/org/eclipse/tycho/repository/local/MirroringArtifactProvider.java index 4316f1fb00..ce146eafef 100644 --- a/tycho-bundles/org.eclipse.tycho.p2.maven.repository/src/main/java/org/eclipse/tycho/repository/local/MirroringArtifactProvider.java +++ b/tycho-bundles/org.eclipse.tycho.p2.maven.repository/src/main/java/org/eclipse/tycho/repository/local/MirroringArtifactProvider.java @@ -9,19 +9,23 @@ * * Contributors: * Tobias Oberlies (SAP SE) - initial API and implementation - * Christoph Läubrich - Issue #658 - Tycho strips p2 artifact properties (eg PGP, maven info...) + * Christoph Läubrich - Issue #658 - Tycho strips p2 artifact properties (eg PGP, maven info...) + * - Issue #692 - Check Hashsums for local cached artifacts *******************************************************************************/ package org.eclipse.tycho.repository.local; import static org.eclipse.tycho.repository.util.internal.BundleConstants.BUNDLE_ID; import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; import java.util.LinkedHashMap; import java.util.Map; import java.util.Objects; import java.util.TreeSet; import java.util.concurrent.locks.Lock; +import org.apache.commons.codec.digest.DigestUtils; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.NullProgressMonitor; @@ -225,8 +229,22 @@ protected boolean makeOneFormatLocallyAvailable(IArtifactKey key) downloadLock.lock(); try { if (!isFileAlreadyAvailable(key)) { // check again within lock + File artifactFile; if (localArtifactRepository.contains(key)) { + artifactFile = localArtifactRepository.getArtifactFile(key); localArtifactRepository.removeDescriptor(key); + } else { + artifactFile = localArtifactRepository.internalGetArtifactStorageLocation( + localArtifactRepository.createArtifactDescriptor(key)); + } + if (artifactFile != null && artifactFile.isFile()) { + //check if only properties has changed... + GAVArtifactDescriptor descriptor = newLocalDescriptor(key); + if (fileMatchesProperties(artifactFile, descriptor.getProperties())) { + localArtifactRepository.internalAddDescriptor(descriptor); + localArtifactRepository.save(); + return true; + } } downloadArtifact(key); localArtifactRepository.save(); @@ -240,6 +258,33 @@ protected boolean makeOneFormatLocallyAvailable(IArtifactKey key) } } + private boolean fileMatchesProperties(File file, Map properties) { + String downloadSize = properties.get("download.size"); + if (downloadSize != null && !downloadSize.equals(String.valueOf(file.length()))) { + //early break out... + return false; + } + String sha256 = properties.get("download.checksum.sha-256"); + if (sha256 != null) { + try (FileInputStream stream = new FileInputStream(file)) { + String fileSha256 = DigestUtils.sha256Hex(stream); + return fileSha256.equalsIgnoreCase(sha256); + } catch (IOException e) { + return false; + } + } + String md5 = properties.get("download.checksum.md5"); + if (md5 != null) { + try (FileInputStream stream = new FileInputStream(file)) { + String fileMd5 = DigestUtils.md5Hex(stream); + return fileMd5.equalsIgnoreCase(md5); + } catch (IOException e) { + return false; + } + } + return false; + } + protected final void downloadArtifact(IArtifactKey key) throws MirroringFailedException, ProvisionException, ArtifactSinkException { @@ -264,12 +309,17 @@ protected IStatus downloadMostSpecificNeededFormatOfArtifact(IArtifactKey key) protected final IStatus downloadCanonicalArtifact(IArtifactKey key) throws ProvisionException, ArtifactSinkException { + GAVArtifactDescriptor localDescriptor = newLocalDescriptor(key); + IArtifactSink localSink = localArtifactRepository.newAddingArtifactSink(localDescriptor); + return remoteProviders.getArtifact(localSink, monitorForDownload()); + } + + protected GAVArtifactDescriptor newLocalDescriptor(IArtifactKey key) { GAVArtifactDescriptor localDescriptor = localArtifactRepository.createArtifactDescriptor(key); IArtifactDescriptor remoteDescriptor = findCanonicalDescriptor(remoteProviders.getArtifactDescriptors(key)); Map properties = getProperties(remoteDescriptor); properties.forEach(localDescriptor::setProperty); - IArtifactSink localSink = localArtifactRepository.newAddingArtifactSink(localDescriptor); - return remoteProviders.getArtifact(localSink, monitorForDownload()); + return localDescriptor; } private void ensureArtifactIsPresentInCanonicalFormat(IArtifactKey key) diff --git a/tycho-bundles/org.eclipse.tycho.p2.maven.repository/src/main/java/org/eclipse/tycho/repository/p2base/artifact/repository/ArtifactRepositoryBaseImpl.java b/tycho-bundles/org.eclipse.tycho.p2.maven.repository/src/main/java/org/eclipse/tycho/repository/p2base/artifact/repository/ArtifactRepositoryBaseImpl.java index c057953235..684d74f174 100644 --- a/tycho-bundles/org.eclipse.tycho.p2.maven.repository/src/main/java/org/eclipse/tycho/repository/p2base/artifact/repository/ArtifactRepositoryBaseImpl.java +++ b/tycho-bundles/org.eclipse.tycho.p2.maven.repository/src/main/java/org/eclipse/tycho/repository/p2base/artifact/repository/ArtifactRepositoryBaseImpl.java @@ -159,7 +159,7 @@ protected abstract ArtifactDescriptorT getInternalDescriptorForAdding(IArtifactD throws IllegalArgumentException; @Override - protected final void internalAddDescriptor(IArtifactDescriptor descriptor) { + protected void internalAddDescriptor(IArtifactDescriptor descriptor) { internalAddInternalDescriptor(getInternalDescriptorForAdding(descriptor)); }