From 0b38562dd9afeb1b9a0d60bd5b9c43b1f3d9773c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christoph=20L=C3=A4ubrich?= Date: Sat, 28 Dec 2024 09:33:36 +0100 Subject: [PATCH] Add support to plug-in additional ArtifactDownloadProvider The transport now support to supply an artifact descriptor that then can be used to look-up the artifact in several other places to prevent downloading it several times. This now adds an abstraction for components to supply an ArtifactDownloadProvider component to implement such strategies independent from the actual transport implementation. In addition to this, also the interface for TransportProtocolHandler is moved to the SPI. --- .../FileTransportProtocolHandler.java | 1 + .../FtpTransportProtocolHandler.java | 1 + .../HttpTransportProtocolHandler.java | 1 + .../HttpsTransportProtocolHandler.java | 1 + .../transport/TransportProtocolHandler.java | 13 ----- .../transport/TychoRepositoryTransport.java | 19 ++++++++ .../TychoRepositoryTransportCacheManager.java | 1 + .../transport/ArtifactDownloadProvider.java | 48 +++++++++++++++++++ .../transport/TransportProtocolHandler.java | 25 ++++++++++ 9 files changed, 97 insertions(+), 13 deletions(-) delete mode 100644 p2-maven-plugin/src/main/java/org/eclipse/tycho/p2maven/transport/TransportProtocolHandler.java create mode 100644 tycho-spi/src/main/java/org/eclipse/tycho/transport/ArtifactDownloadProvider.java create mode 100644 tycho-spi/src/main/java/org/eclipse/tycho/transport/TransportProtocolHandler.java diff --git a/p2-maven-plugin/src/main/java/org/eclipse/tycho/p2maven/transport/FileTransportProtocolHandler.java b/p2-maven-plugin/src/main/java/org/eclipse/tycho/p2maven/transport/FileTransportProtocolHandler.java index 6abc31bd28..3a52e37d6c 100644 --- a/p2-maven-plugin/src/main/java/org/eclipse/tycho/p2maven/transport/FileTransportProtocolHandler.java +++ b/p2-maven-plugin/src/main/java/org/eclipse/tycho/p2maven/transport/FileTransportProtocolHandler.java @@ -17,6 +17,7 @@ import java.net.URI; import org.codehaus.plexus.component.annotations.Component; +import org.eclipse.tycho.transport.TransportProtocolHandler; @Component(role = TransportProtocolHandler.class, hint = "file") public class FileTransportProtocolHandler implements TransportProtocolHandler { diff --git a/p2-maven-plugin/src/main/java/org/eclipse/tycho/p2maven/transport/FtpTransportProtocolHandler.java b/p2-maven-plugin/src/main/java/org/eclipse/tycho/p2maven/transport/FtpTransportProtocolHandler.java index 89f431daec..f39595a5c4 100644 --- a/p2-maven-plugin/src/main/java/org/eclipse/tycho/p2maven/transport/FtpTransportProtocolHandler.java +++ b/p2-maven-plugin/src/main/java/org/eclipse/tycho/p2maven/transport/FtpTransportProtocolHandler.java @@ -27,6 +27,7 @@ import org.codehaus.plexus.logging.Logger; import org.codehaus.plexus.personality.plexus.lifecycle.phase.Disposable; import org.eclipse.tycho.MavenRepositorySettings.Credentials; +import org.eclipse.tycho.transport.TransportProtocolHandler; /** * Handles files discovery over the FTP protocol. diff --git a/p2-maven-plugin/src/main/java/org/eclipse/tycho/p2maven/transport/HttpTransportProtocolHandler.java b/p2-maven-plugin/src/main/java/org/eclipse/tycho/p2maven/transport/HttpTransportProtocolHandler.java index 456a491956..e278801d99 100644 --- a/p2-maven-plugin/src/main/java/org/eclipse/tycho/p2maven/transport/HttpTransportProtocolHandler.java +++ b/p2-maven-plugin/src/main/java/org/eclipse/tycho/p2maven/transport/HttpTransportProtocolHandler.java @@ -21,6 +21,7 @@ import org.codehaus.plexus.component.annotations.Component; import org.codehaus.plexus.component.annotations.Requirement; import org.codehaus.plexus.logging.Logger; +import org.eclipse.tycho.transport.TransportProtocolHandler; @Component(role = TransportProtocolHandler.class, hint = "http") public class HttpTransportProtocolHandler implements TransportProtocolHandler { diff --git a/p2-maven-plugin/src/main/java/org/eclipse/tycho/p2maven/transport/HttpsTransportProtocolHandler.java b/p2-maven-plugin/src/main/java/org/eclipse/tycho/p2maven/transport/HttpsTransportProtocolHandler.java index 279ab8f274..95b5d9d62a 100644 --- a/p2-maven-plugin/src/main/java/org/eclipse/tycho/p2maven/transport/HttpsTransportProtocolHandler.java +++ b/p2-maven-plugin/src/main/java/org/eclipse/tycho/p2maven/transport/HttpsTransportProtocolHandler.java @@ -13,6 +13,7 @@ package org.eclipse.tycho.p2maven.transport; import org.codehaus.plexus.component.annotations.Component; +import org.eclipse.tycho.transport.TransportProtocolHandler; @Component(role = TransportProtocolHandler.class, hint = "https") public class HttpsTransportProtocolHandler extends HttpTransportProtocolHandler { diff --git a/p2-maven-plugin/src/main/java/org/eclipse/tycho/p2maven/transport/TransportProtocolHandler.java b/p2-maven-plugin/src/main/java/org/eclipse/tycho/p2maven/transport/TransportProtocolHandler.java deleted file mode 100644 index dede30f13c..0000000000 --- a/p2-maven-plugin/src/main/java/org/eclipse/tycho/p2maven/transport/TransportProtocolHandler.java +++ /dev/null @@ -1,13 +0,0 @@ -package org.eclipse.tycho.p2maven.transport; - -import java.io.File; -import java.io.IOException; -import java.net.URI; - -public interface TransportProtocolHandler { - - long getLastModified(URI uri) throws IOException; - - File getFile(URI remoteFile) throws IOException; - -} diff --git a/p2-maven-plugin/src/main/java/org/eclipse/tycho/p2maven/transport/TychoRepositoryTransport.java b/p2-maven-plugin/src/main/java/org/eclipse/tycho/p2maven/transport/TychoRepositoryTransport.java index b09f5a991d..a649b0c89f 100644 --- a/p2-maven-plugin/src/main/java/org/eclipse/tycho/p2maven/transport/TychoRepositoryTransport.java +++ b/p2-maven-plugin/src/main/java/org/eclipse/tycho/p2maven/transport/TychoRepositoryTransport.java @@ -23,6 +23,9 @@ import java.nio.file.Files; import java.nio.file.Path; import java.text.NumberFormat; +import java.util.Comparator; +import java.util.Iterator; +import java.util.List; import java.util.Map; import java.util.concurrent.Executor; import java.util.concurrent.Executors; @@ -44,6 +47,8 @@ import org.eclipse.equinox.p2.core.IProvisioningAgent; import org.eclipse.equinox.p2.core.spi.IAgentServiceFactory; import org.eclipse.equinox.p2.repository.artifact.IArtifactDescriptor; +import org.eclipse.tycho.transport.ArtifactDownloadProvider; +import org.eclipse.tycho.transport.TransportProtocolHandler; @Component(role = org.eclipse.equinox.internal.p2.repository.Transport.class, hint = "tycho") public class TychoRepositoryTransport extends org.eclipse.equinox.internal.p2.repository.Transport @@ -78,6 +83,9 @@ public Thread newThread(Runnable r) { @Requirement(role = TransportProtocolHandler.class) Map transportProtocolHandlers; + @Requirement // TODO @Inject results in a list with multiple items of the same provider! + List artifactDownloadProvider; + private LongAdder requests = new LongAdder(); private LongAdder indexRequests = new LongAdder(); @@ -88,6 +96,17 @@ public TychoRepositoryTransport() { @Override public IStatus downloadArtifact(URI source, OutputStream target, IArtifactDescriptor descriptor, IProgressMonitor monitor) { + if (descriptor != null) { + Iterator iterator = artifactDownloadProvider.stream().distinct() + .sorted(Comparator.comparingInt(ArtifactDownloadProvider::getPriority).reversed()).iterator(); + while (iterator.hasNext()) { + ArtifactDownloadProvider provider = iterator.next(); + IStatus status = provider.downloadArtifact(source, target, descriptor); + if (!status.matches(IStatus.CANCEL)) { + return reportStatus(status, target); + } + } + } String id = "p2"; // TODO we might compute the id from the IRepositoryIdManager based on the URI? if (cacheConfig.isInteractive()) { logger.info("Downloading from " + id + ": " + source); diff --git a/p2-maven-plugin/src/main/java/org/eclipse/tycho/p2maven/transport/TychoRepositoryTransportCacheManager.java b/p2-maven-plugin/src/main/java/org/eclipse/tycho/p2maven/transport/TychoRepositoryTransportCacheManager.java index c3c8654fe5..facd6168a4 100644 --- a/p2-maven-plugin/src/main/java/org/eclipse/tycho/p2maven/transport/TychoRepositoryTransportCacheManager.java +++ b/p2-maven-plugin/src/main/java/org/eclipse/tycho/p2maven/transport/TychoRepositoryTransportCacheManager.java @@ -22,6 +22,7 @@ import org.eclipse.core.runtime.URIUtil; import org.eclipse.equinox.internal.p2.repository.CacheManager; import org.eclipse.equinox.p2.core.ProvisionException; +import org.eclipse.tycho.transport.TransportProtocolHandler; public class TychoRepositoryTransportCacheManager extends CacheManager { diff --git a/tycho-spi/src/main/java/org/eclipse/tycho/transport/ArtifactDownloadProvider.java b/tycho-spi/src/main/java/org/eclipse/tycho/transport/ArtifactDownloadProvider.java new file mode 100644 index 0000000000..d4f5c6bb8d --- /dev/null +++ b/tycho-spi/src/main/java/org/eclipse/tycho/transport/ArtifactDownloadProvider.java @@ -0,0 +1,48 @@ +/******************************************************************************* + * Copyright (c) 2024 Christoph Läubrich and others. + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Christoph Läubrich - initial API and implementation + *******************************************************************************/ +package org.eclipse.tycho.transport; + +import java.io.OutputStream; +import java.net.URI; + +import org.eclipse.core.runtime.IStatus; +import org.eclipse.equinox.internal.p2.repository.DownloadStatus; +import org.eclipse.equinox.p2.repository.artifact.IArtifactDescriptor; + +/** + * An {@link ArtifactDownloadProvider} can supply an alternative caching strategy for artifacts + * fetched from P2 + */ +public interface ArtifactDownloadProvider { + + /** + * Ask the provider to download the given artifact and transfer it to the given target + * + * @param source + * the source URI, might be a mirror URL + * @param target + * the target where the result should be transfered to + * @param descriptor + * the artifact descriptor to be queried + * @return a status of type cancel if this provider can't supply the artifact, or a + * {@link DownloadStatus} in case of success to supply additional information to P2, or + * an error if the download failed even though it should not. + */ + public IStatus downloadArtifact(URI source, OutputStream target, IArtifactDescriptor descriptor); + + /** + * @return the priority, higher values are considered first + */ + int getPriority(); + +} diff --git a/tycho-spi/src/main/java/org/eclipse/tycho/transport/TransportProtocolHandler.java b/tycho-spi/src/main/java/org/eclipse/tycho/transport/TransportProtocolHandler.java new file mode 100644 index 0000000000..e276707f1f --- /dev/null +++ b/tycho-spi/src/main/java/org/eclipse/tycho/transport/TransportProtocolHandler.java @@ -0,0 +1,25 @@ +/******************************************************************************* + * Copyright (c) 2022 Christoph Läubrich and others. + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Christoph Läubrich - initial API and implementation + *******************************************************************************/ +package org.eclipse.tycho.transport; + +import java.io.File; +import java.io.IOException; +import java.net.URI; + +public interface TransportProtocolHandler { + + long getLastModified(URI uri) throws IOException; + + File getFile(URI remoteFile) throws IOException; + +}