diff --git a/rewrite-maven/build.gradle.kts b/rewrite-maven/build.gradle.kts
index a6bcfe34cdc..64b4be8bef4 100755
--- a/rewrite-maven/build.gradle.kts
+++ b/rewrite-maven/build.gradle.kts
@@ -38,7 +38,8 @@ dependencies {
testImplementation(project(":rewrite-test"))
testImplementation("com.squareup.okhttp3:mockwebserver:4.+")
- testImplementation("com.squareup.okio:okio-jvm:3.0.0")
+ testImplementation("com.squareup.okhttp3:okhttp-tls:4.+")
+ testImplementation("com.squareup.okio:okio-jvm:3.9.1")
testImplementation("org.mapdb:mapdb:latest.release")
testImplementation("guru.nidi:graphviz-java:latest.release")
diff --git a/rewrite-maven/src/test/java/org/openrewrite/maven/MavenParserTest.java b/rewrite-maven/src/test/java/org/openrewrite/maven/MavenParserTest.java
index 50a829f0a8c..b3cbe440c88 100644
--- a/rewrite-maven/src/test/java/org/openrewrite/maven/MavenParserTest.java
+++ b/rewrite-maven/src/test/java/org/openrewrite/maven/MavenParserTest.java
@@ -17,16 +17,21 @@
import com.fasterxml.jackson.databind.node.JsonNodeFactory;
import com.fasterxml.jackson.databind.node.ObjectNode;
+import okhttp3.OkHttpClient;
import okhttp3.mockwebserver.Dispatcher;
import okhttp3.mockwebserver.MockResponse;
import okhttp3.mockwebserver.MockWebServer;
import okhttp3.mockwebserver.RecordedRequest;
+import okhttp3.tls.HandshakeCertificates;
+import okhttp3.tls.HeldCertificate;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
+import org.openrewrite.HttpSenderExecutionContextView;
import org.openrewrite.InMemoryExecutionContext;
import org.openrewrite.Issue;
import org.openrewrite.ParseExceptionResult;
import org.openrewrite.Parser;
+import org.openrewrite.ipc.http.OkHttpSender;
import org.openrewrite.maven.internal.MavenParsingException;
import org.openrewrite.maven.tree.*;
import org.openrewrite.test.RewriteTest;
@@ -34,10 +39,11 @@
import org.openrewrite.tree.ParseError;
import java.io.IOException;
+import java.net.InetAddress;
import java.nio.file.Paths;
import java.util.Base64;
import java.util.List;
-import java.util.stream.StreamSupport;
+import java.util.Objects;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
@@ -906,13 +912,23 @@ void mirrorsAndAuth() throws IOException {
var username = "admin";
var password = "password";
try (MockWebServer mockRepo = new MockWebServer()) {
+ // TLS server setup based on https://github.com/square/okhttp/blob/master/okhttp-tls/README.md
+ String localhost = InetAddress.getByName("localhost").getCanonicalHostName();
+ HeldCertificate localhostCertificate = new HeldCertificate.Builder()
+ .addSubjectAlternativeName(localhost)
+ .build();
+ HandshakeCertificates serverCertificates = new HandshakeCertificates.Builder()
+ .heldCertificate(localhostCertificate)
+ .build();
+ mockRepo.useHttps(serverCertificates.sslSocketFactory(), false);
+
mockRepo.setDispatcher(new Dispatcher() {
@Override
public MockResponse dispatch(RecordedRequest request) {
MockResponse resp = new MockResponse();
- if (StreamSupport.stream(request.getHeaders().spliterator(), false)
- .noneMatch(it -> it.getFirst().equals("Authorization") &&
- it.getSecond().equals("Basic " + Base64.getEncoder().encodeToString((username + ":" + password).getBytes())))) {
+ if (!Objects.equals(
+ request.getHeader("Authorization"),
+ "Basic " + Base64.getEncoder().encodeToString((username + ":" + password).getBytes()))) {
return resp.setResponseCode(401);
} else {
if (!"HEAD".equalsIgnoreCase(request.getMethod())) {
@@ -935,7 +951,7 @@ public MockResponse dispatch(RecordedRequest request) {
});
mockRepo.start();
- var ctx = MavenExecutionContextView.view(new InMemoryExecutionContext(t -> {
+ var mavenCtx = MavenExecutionContextView.view(new InMemoryExecutionContext(t -> {
throw new RuntimeException(t);
}));
var settings = MavenSettings.parse(Parser.Input.fromString(Paths.get("settings.xml"),
@@ -959,8 +975,17 @@ public MockResponse dispatch(RecordedRequest request) {
""".formatted(mockRepo.getHostName(), mockRepo.getPort(), username, password)
- ), ctx);
- ctx.setMavenSettings(settings);
+ ), mavenCtx);
+ mavenCtx.setMavenSettings(settings);
+
+ // TLS client setup (just make it trust the self-signed certificate)
+ HandshakeCertificates clientCertificates = new HandshakeCertificates.Builder()
+ .addTrustedCertificate(localhostCertificate.certificate())
+ .build();
+ OkHttpClient client = new OkHttpClient.Builder()
+ .sslSocketFactory(clientCertificates.sslSocketFactory(), clientCertificates.trustManager())
+ .build();
+ var ctx = new HttpSenderExecutionContextView(mavenCtx).setHttpSender(new OkHttpSender(client));
var maven = MavenParser.builder().build().parse(
ctx,
diff --git a/rewrite-maven/src/test/java/org/openrewrite/maven/UpgradeParentVersionTest.java b/rewrite-maven/src/test/java/org/openrewrite/maven/UpgradeParentVersionTest.java
index e248627b44c..9b25228a908 100644
--- a/rewrite-maven/src/test/java/org/openrewrite/maven/UpgradeParentVersionTest.java
+++ b/rewrite-maven/src/test/java/org/openrewrite/maven/UpgradeParentVersionTest.java
@@ -61,7 +61,7 @@ void doesNotDowngradeVersion() {
void nonMavenCentralRepository() {
rewriteRun(
spec -> spec
- .recipe(new UpgradeParentVersion("org.jenkins-ci.plugins", "plugin", "4.40", null))
+ .recipe(new UpgradeParentVersion("org.jenkins-ci", "jenkins", "1.125", null))
.executionContext(
MavenExecutionContextView
.view(new InMemoryExecutionContext())
@@ -73,22 +73,22 @@ void nonMavenCentralRepository() {
"""
- org.jenkins-ci.plugins
- plugin
- 4.33
+ org.jenkins-ci
+ jenkins
+ 1.124
- antisamy-markup-formatter
+ example
1.0.0
""",
"""
- org.jenkins-ci.plugins
- plugin
- 4.40
+ org.jenkins-ci
+ jenkins
+ 1.125
- antisamy-markup-formatter
+ example
1.0.0
"""
diff --git a/rewrite-maven/src/test/java/org/openrewrite/maven/internal/MavenPomDownloaderTest.java b/rewrite-maven/src/test/java/org/openrewrite/maven/internal/MavenPomDownloaderTest.java
index 93d9bd3f599..9e3be221b3f 100755
--- a/rewrite-maven/src/test/java/org/openrewrite/maven/internal/MavenPomDownloaderTest.java
+++ b/rewrite-maven/src/test/java/org/openrewrite/maven/internal/MavenPomDownloaderTest.java
@@ -15,12 +15,16 @@
*/
package org.openrewrite.maven.internal;
+import okhttp3.OkHttpClient;
import okhttp3.mockwebserver.*;
+import okhttp3.tls.HandshakeCertificates;
+import okhttp3.tls.HeldCertificate;
import org.assertj.core.api.Condition;
import org.intellij.lang.annotations.Language;
import org.jspecify.annotations.Nullable;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.DisplayName;
+import org.junit.jupiter.api.Nested;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.io.TempDir;
import org.junit.jupiter.params.ParameterizedTest;
@@ -29,13 +33,16 @@
import org.openrewrite.*;
import org.openrewrite.ipc.http.HttpSender;
import org.openrewrite.ipc.http.HttpUrlConnectionSender;
+import org.openrewrite.ipc.http.OkHttpSender;
import org.openrewrite.maven.MavenDownloadingException;
import org.openrewrite.maven.MavenExecutionContextView;
import org.openrewrite.maven.MavenParser;
import org.openrewrite.maven.MavenSettings;
import org.openrewrite.maven.tree.*;
+import javax.net.ssl.SSLSocketFactory;
import java.io.IOException;
+import java.net.InetAddress;
import java.net.UnknownHostException;
import java.nio.file.Files;
import java.nio.file.Path;
@@ -45,10 +52,7 @@
import java.util.concurrent.atomic.AtomicInteger;
import java.util.function.Consumer;
-import static java.util.Collections.emptyList;
-import static java.util.Collections.emptyMap;
-import static java.util.Collections.singletonList;
-import static java.util.Collections.singletonMap;
+import static java.util.Collections.*;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatThrownBy;
import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
@@ -57,28 +61,6 @@
@SuppressWarnings({"HttpUrlsUsage"})
class MavenPomDownloaderTest {
- private final ExecutionContext ctx = HttpSenderExecutionContextView.view(new InMemoryExecutionContext())
- .setHttpSender(new HttpUrlConnectionSender(Duration.ofMillis(250), Duration.ofMillis(250)));
-
- private void mockServer(Integer responseCode, Consumer block) {
- try (MockWebServer mockRepo = new MockWebServer()) {
- mockRepo.setDispatcher(new Dispatcher() {
- @Override
- public MockResponse dispatch(RecordedRequest recordedRequest) {
- return new MockResponse().setResponseCode(responseCode).setBody("");
- }
- });
- mockRepo.start();
- block.accept(mockRepo);
- assertThat(mockRepo.getRequestCount())
- .as("The mock repository received no requests. The test is not using it.")
- .isGreaterThan(0);
- mockRepo.shutdown();
- } catch (IOException e) {
- throw new RuntimeException(e);
- }
- }
-
@Test
void ossSonatype() {
InMemoryExecutionContext ctx = new InMemoryExecutionContext();
@@ -92,831 +74,923 @@ void ossSonatype() {
assertThat(repo).isNotNull().extracting((MavenRepository::getUri)).isEqualTo(ossSonatype.getUri());
}
- @Issue("https://github.com/openrewrite/rewrite/issues/3908")
- @Test
- void centralIdOverridesDefaultRepository() {
- var ctx = MavenExecutionContextView.view(this.ctx);
- ctx.setMavenSettings(MavenSettings.parse(Parser.Input.fromString(Paths.get("settings.xml"),
- //language=xml
- """
-
-
-
- central
-
-
- central
- https://internalartifactrepository.yourorg.com
-
-
-
-
-
- central
-
-
- """
- ), ctx));
-
- // Avoid actually trying to reach the made-up https://internalartifactrepository.yourorg.com
- for (MavenRepository repository : ctx.getRepositories()) {
- repository.setKnownToExist(true);
- }
-
- var downloader = new MavenPomDownloader(emptyMap(), ctx);
- Collection repos = downloader.distinctNormalizedRepositories(emptyList(), null, null);
- assertThat(repos).areExactly(1, new Condition<>(repo -> "central".equals(repo.getId()),
- "id \"central\""));
- assertThat(repos).areExactly(1, new Condition<>(repo -> "https://internalartifactrepository.yourorg.com".equals(repo.getUri()),
- "URI https://internalartifactrepository.yourorg.com"));
+ @CsvSource(textBlock = """
+ https://repo1.maven.org/maven2/, https://repo1.maven.org/maven2/
+ https://repo1.maven.org/maven2, https://repo1.maven.org/maven2/
+ http://repo1.maven.org/maven2/, https://repo1.maven.org/maven2/
+
+ https://oss.sonatype.org/content/repositories/snapshots/, https://oss.sonatype.org/content/repositories/snapshots/
+ https://artifactory.moderne.ninja/artifactory/moderne-public/, https://artifactory.moderne.ninja/artifactory/moderne-public/
+ https://repo.maven.apache.org/maven2/, https://repo.maven.apache.org/maven2/
+ https://jitpack.io/, https://jitpack.io/
+ """)
+ @ParameterizedTest
+ void normalizeRepository(String originalUrl, String expectedUrl) throws Throwable {
+ MavenPomDownloader downloader = new MavenPomDownloader(new InMemoryExecutionContext());
+ MavenRepository repository = new MavenRepository("id", originalUrl, null, null, null, null, null);
+ MavenRepository normalized = downloader.normalizeRepository(repository);
+ assertThat(normalized).isNotNull();
+ assertThat(normalized.getUri()).isEqualTo(expectedUrl);
}
- @Test
- void listenerRecordsRepository() {
- var ctx = MavenExecutionContextView.view(this.ctx);
- // Avoid actually trying to reach the made-up https://internalartifactrepository.yourorg.com
- for (MavenRepository repository : ctx.getRepositories()) {
- repository.setKnownToExist(true);
- }
+ @Nested
+ class WithNativeHttpURLConnectionAndTLS {
+ private final ExecutionContext ctx = HttpSenderExecutionContextView.view(new InMemoryExecutionContext())
+ .setHttpSender(new HttpUrlConnectionSender(Duration.ofMillis(250), Duration.ofMillis(250)));
- MavenRepository nonexistentRepo = new MavenRepository("repo", "http://internalartifactrepository.yourorg.com", null, null, true, null, null, null, null);
- List attemptedUris = new ArrayList<>();
- List discoveredRepositories = new ArrayList<>();
- ctx.setResolutionListener(new ResolutionEventListener() {
- @Override
- public void downloadError(GroupArtifactVersion gav, List uris, @Nullable Pom containing) {
- attemptedUris.addAll(uris);
+ @Issue("https://github.com/openrewrite/rewrite/issues/3908")
+ @Test
+ void centralIdOverridesDefaultRepository() {
+ var ctx = MavenExecutionContextView.view(this.ctx);
+ ctx.setMavenSettings(MavenSettings.parse(Parser.Input.fromString(Paths.get("settings.xml"),
+ //language=xml
+ """
+
+
+
+ central
+
+
+ central
+ https://internalartifactrepository.yourorg.com
+
+
+
+
+
+ central
+
+
+ """
+ ), ctx));
+
+ // Avoid actually trying to reach the made-up https://internalartifactrepository.yourorg.com
+ for (MavenRepository repository : ctx.getRepositories()) {
+ repository.setKnownToExist(true);
}
- @Override
- public void repository(MavenRepository mavenRepository, @Nullable ResolvedPom containing) {
- discoveredRepositories.add(mavenRepository);
+ var downloader = new MavenPomDownloader(emptyMap(), ctx);
+ Collection repos = downloader.distinctNormalizedRepositories(emptyList(), null, null);
+ assertThat(repos).areExactly(1, new Condition<>(repo -> "central".equals(repo.getId()),
+ "id \"central\""));
+ assertThat(repos).areExactly(1, new Condition<>(repo -> "https://internalartifactrepository.yourorg.com".equals(repo.getUri()),
+ "URI https://internalartifactrepository.yourorg.com"));
+ }
+
+ @Test
+ void listenerRecordsRepository() {
+ var ctx = MavenExecutionContextView.view(this.ctx);
+ // Avoid actually trying to reach the made-up https://internalartifactrepository.yourorg.com
+ for (MavenRepository repository : ctx.getRepositories()) {
+ repository.setKnownToExist(true);
}
- });
- try {
- new MavenPomDownloader(ctx)
- .download(new GroupArtifactVersion("org.openrewrite", "rewrite-core", "7.0.0"), null, null, singletonList(nonexistentRepo));
- } catch (Exception e) {
- // not expected to succeed
- }
- assertThat(attemptedUris)
- .containsExactly("http://internalartifactrepository.yourorg.com/org/openrewrite/rewrite-core/7.0.0/rewrite-core-7.0.0.pom");
- assertThat(discoveredRepositories)
- .containsExactly(nonexistentRepo);
- }
+ MavenRepository nonexistentRepo = new MavenRepository("repo", "http://internalartifactrepository.yourorg.com", null, null, true, null, null, null, null);
+ List attemptedUris = new ArrayList<>();
+ List discoveredRepositories = new ArrayList<>();
+ ctx.setResolutionListener(new ResolutionEventListener() {
+ @Override
+ public void downloadError(GroupArtifactVersion gav, List uris, @Nullable Pom containing) {
+ attemptedUris.addAll(uris);
+ }
- @Test
- void listenerRecordsFailedRepositoryAccess() {
- var ctx = MavenExecutionContextView.view(new InMemoryExecutionContext());
- // Avoid actually trying to reach a made-up URL
- String httpUrl = "http://%s.com".formatted(UUID.randomUUID());
- MavenRepository nonexistentRepo = new MavenRepository("repo", httpUrl, null, null, false, null, null, null, null);
- Map attemptedUris = new HashMap<>();
- List discoveredRepositories = new ArrayList<>();
- ctx.setResolutionListener(new ResolutionEventListener() {
- @Override
- public void repositoryAccessFailed(String uri, Throwable e) {
- attemptedUris.put(uri, e);
+ @Override
+ public void repository(MavenRepository mavenRepository, @Nullable ResolvedPom containing) {
+ discoveredRepositories.add(mavenRepository);
+ }
+ });
+
+ try {
+ new MavenPomDownloader(ctx)
+ .download(new GroupArtifactVersion("org.openrewrite", "rewrite-core", "7.0.0"), null, null, singletonList(nonexistentRepo));
+ } catch (Exception e) {
+ // not expected to succeed
}
- });
+ assertThat(attemptedUris)
+ .containsExactly("http://internalartifactrepository.yourorg.com/org/openrewrite/rewrite-core/7.0.0/rewrite-core-7.0.0.pom");
+ assertThat(discoveredRepositories)
+ .containsExactly(nonexistentRepo);
+ }
+
+ @Test
+ void listenerRecordsFailedRepositoryAccess() {
+ var ctx = MavenExecutionContextView.view(new InMemoryExecutionContext());
+ // Avoid actually trying to reach a made-up URL
+ String httpUrl = "http://%s.com".formatted(UUID.randomUUID());
+ MavenRepository nonexistentRepo = new MavenRepository("repo", httpUrl, null, null, false, null, null, null, null);
+ Map attemptedUris = new HashMap<>();
+ List discoveredRepositories = new ArrayList<>();
+ ctx.setResolutionListener(new ResolutionEventListener() {
+ @Override
+ public void repositoryAccessFailed(String uri, Throwable e) {
+ attemptedUris.put(uri, e);
+ }
+ });
- try {
- new MavenPomDownloader(ctx)
- .download(new GroupArtifactVersion("org.openrewrite", "rewrite-core", "7.0.0"), null, null, singletonList(nonexistentRepo));
- } catch (Exception e) {
- // not expected to succeed
+ try {
+ new MavenPomDownloader(ctx)
+ .download(new GroupArtifactVersion("org.openrewrite", "rewrite-core", "7.0.0"), null, null, singletonList(nonexistentRepo));
+ } catch (Exception e) {
+ // not expected to succeed
+ }
+ assertThat(attemptedUris).isNotEmpty();
+ assertThat(attemptedUris.get(httpUrl)).isInstanceOf(UnknownHostException.class);
+ assertThat(discoveredRepositories).isEmpty();
}
- assertThat(attemptedUris).isNotEmpty();
- assertThat(attemptedUris.get(httpUrl)).isInstanceOf(UnknownHostException.class);
- assertThat(discoveredRepositories).isEmpty();
- }
- @Test
- void mirrorsOverrideRepositoriesInPom() {
- var ctx = MavenExecutionContextView.view(this.ctx);
- ctx.setMavenSettings(MavenSettings.parse(Parser.Input.fromString(Paths.get("settings.xml"),
- //language=xml
- """
-
-
-
- mirror
- https://artifactory.moderne.ninja/artifactory/moderne-cache
- *
-
-
-
- """
- ), ctx));
-
- Path pomPath = Paths.get("pom.xml");
- Pom pom = Pom.builder()
- .sourcePath(pomPath)
- .repository(MAVEN_CENTRAL)
- .properties(singletonMap("REPO_URL", MAVEN_CENTRAL.getUri()))
- .gav(new ResolvedGroupArtifactVersion(
- "${REPO_URL}", "org.openrewrite", "rewrite-core", "7.0.0", null))
- .build();
- ResolvedPom resolvedPom = ResolvedPom.builder()
- .requested(pom)
- .properties(singletonMap("REPO_URL", MAVEN_CENTRAL.getUri()))
- .repositories(singletonList(MAVEN_CENTRAL))
- .build();
+ @Test
+ void mirrorsOverrideRepositoriesInPom() {
+ var ctx = MavenExecutionContextView.view(this.ctx);
+ ctx.setMavenSettings(MavenSettings.parse(Parser.Input.fromString(Paths.get("settings.xml"),
+ //language=xml
+ """
+
+
+
+ mirror
+ https://artifactory.moderne.ninja/artifactory/moderne-cache
+ *
+
+
+
+ """
+ ), ctx));
+
+ Path pomPath = Paths.get("pom.xml");
+ Pom pom = Pom.builder()
+ .sourcePath(pomPath)
+ .repository(MAVEN_CENTRAL)
+ .properties(singletonMap("REPO_URL", MAVEN_CENTRAL.getUri()))
+ .gav(new ResolvedGroupArtifactVersion(
+ "${REPO_URL}", "org.openrewrite", "rewrite-core", "7.0.0", null))
+ .build();
+ ResolvedPom resolvedPom = ResolvedPom.builder()
+ .requested(pom)
+ .properties(singletonMap("REPO_URL", MAVEN_CENTRAL.getUri()))
+ .repositories(singletonList(MAVEN_CENTRAL))
+ .build();
- Map pomsByPath = new HashMap<>();
- pomsByPath.put(pomPath, pom);
-
- MavenPomDownloader mpd = new MavenPomDownloader(pomsByPath, ctx);
- MavenRepository normalized = mpd.normalizeRepository(
- MavenRepository.builder().id("whatever").uri("${REPO_URL}").build(),
- ctx,
- resolvedPom
- );
- assertThat(normalized)
- .extracting(MavenRepository::getUri)
- .isEqualTo("https://artifactory.moderne.ninja/artifactory/moderne-cache/");
- }
+ Map pomsByPath = new HashMap<>();
+ pomsByPath.put(pomPath, pom);
- @Disabled("Flaky on CI")
- @Test
- void normalizeOssSnapshots() {
- var downloader = new MavenPomDownloader(emptyMap(), ctx);
- MavenRepository oss = downloader.normalizeRepository(
- MavenRepository.builder().id("oss").uri("https://oss.sonatype.org/content/repositories/snapshots").build(),
- MavenExecutionContextView.view(ctx), null);
+ MavenPomDownloader mpd = new MavenPomDownloader(pomsByPath, ctx);
+ MavenRepository normalized = mpd.normalizeRepository(
+ MavenRepository.builder().id("whatever").uri("${REPO_URL}").build(),
+ ctx,
+ resolvedPom
+ );
+ assertThat(normalized)
+ .extracting(MavenRepository::getUri)
+ .isEqualTo("https://artifactory.moderne.ninja/artifactory/moderne-cache/");
+ }
- assertThat(oss).isNotNull();
- assertThat(oss.getUri()).isEqualTo("https://oss.sonatype.org/content/repositories/snapshots/");
- }
+ @Disabled("Flaky on CI")
+ @Test
+ void normalizeOssSnapshots() {
+ var downloader = new MavenPomDownloader(emptyMap(), ctx);
+ MavenRepository oss = downloader.normalizeRepository(
+ MavenRepository.builder().id("oss").uri("https://oss.sonatype.org/content/repositories/snapshots").build(),
+ MavenExecutionContextView.view(ctx), null);
- @ParameterizedTest
- @Issue("https://github.com/openrewrite/rewrite/issues/3141")
- @ValueSource(strings = {"http://0.0.0.0", "https://0.0.0.0", "0.0.0.0:443"})
- void skipBlockedRepository(String url) {
- var downloader = new MavenPomDownloader(emptyMap(), ctx);
- MavenRepository oss = downloader.normalizeRepository(
- MavenRepository.builder().id("myRepo").uri(url).build(),
- MavenExecutionContextView.view(ctx), null);
+ assertThat(oss).isNotNull();
+ assertThat(oss.getUri()).isEqualTo("https://oss.sonatype.org/content/repositories/snapshots/");
+ }
- assertThat(oss).isNull();
- }
+ @ParameterizedTest
+ @Issue("https://github.com/openrewrite/rewrite/issues/3141")
+ @ValueSource(strings = {"http://0.0.0.0", "https://0.0.0.0", "0.0.0.0:443"})
+ void skipBlockedRepository(String url) {
+ var downloader = new MavenPomDownloader(emptyMap(), ctx);
+ MavenRepository oss = downloader.normalizeRepository(
+ MavenRepository.builder().id("myRepo").uri(url).build(),
+ MavenExecutionContextView.view(ctx), null);
- @ParameterizedTest
- @ValueSource(ints = {500, 400})
- void normalizeAcceptErrorStatuses(Integer status) {
- var downloader = new MavenPomDownloader(emptyMap(), ctx);
- mockServer(status, mockRepo -> {
- var originalRepo = MavenRepository.builder()
- .id("id")
- .uri("http://%s:%d/maven".formatted(mockRepo.getHostName(), mockRepo.getPort()))
- .build();
- var normalizedRepo = downloader.normalizeRepository(originalRepo, MavenExecutionContextView.view(ctx), null);
- assertThat(normalizedRepo).isEqualTo(originalRepo);
- });
- }
+ assertThat(oss).isNull();
+ }
- @Test
- void retryConnectException() throws Throwable {
- var downloader = new MavenPomDownloader(emptyMap(), ctx);
- try (MockWebServer server = new MockWebServer()) {
- server.enqueue(new MockResponse().setSocketPolicy(SocketPolicy.NO_RESPONSE));
- server.enqueue(new MockResponse().setResponseCode(200).setBody("body"));
- String body = new String(downloader.sendRequest(new HttpSender.Request(server.url("/test").url(), "request".getBytes(), HttpSender.Method.GET, Map.of(), null, null)));
- assertThat(body).isEqualTo("body");
- assertThat(server.getRequestCount()).isEqualTo(2);
- server.shutdown();
+ @Test
+ void retryConnectException() throws Throwable {
+ var downloader = new MavenPomDownloader(emptyMap(), ctx);
+ try (MockWebServer server = new MockWebServer()) {
+ server.enqueue(new MockResponse().setSocketPolicy(SocketPolicy.NO_RESPONSE));
+ server.enqueue(new MockResponse().setResponseCode(200).setBody("body"));
+ String body = new String(downloader.sendRequest(new HttpSender.Request(server.url("/test").url(), "request".getBytes(), HttpSender.Method.GET, Map.of(), null, null)));
+ assertThat(body).isEqualTo("body");
+ assertThat(server.getRequestCount()).isEqualTo(2);
+ server.shutdown();
+ }
}
- }
- @Test
- void normalizeRejectConnectException() {
- var downloader = new MavenPomDownloader(emptyMap(), ctx);
- var normalizedRepository = downloader.normalizeRepository(
- MavenRepository.builder().id("id").uri("https//localhost").build(),
- MavenExecutionContextView.view(ctx), null);
- assertThat(normalizedRepository).isEqualTo(null);
- }
+ @Test
+ void normalizeRejectConnectException() {
+ var downloader = new MavenPomDownloader(emptyMap(), ctx);
+ var normalizedRepository = downloader.normalizeRepository(
+ MavenRepository.builder().id("id").uri("https//localhost").build(),
+ MavenExecutionContextView.view(ctx), null);
+ assertThat(normalizedRepository).isEqualTo(null);
+ }
- @Test
- void invalidArtifact() {
- var downloader = new MavenPomDownloader(emptyMap(), ctx);
- var gav = new GroupArtifactVersion("fred", "fred", "1.0.0");
- mockServer(500,
- repo1 -> mockServer(400, repo2 -> {
- var repositories = List.of(
- MavenRepository.builder()
+ @Test
+ void useHttpWhenHttpsFails() throws IOException {
+ var downloader = new MavenPomDownloader(emptyMap(), ctx);
+ try (MockWebServer mockRepo = new MockWebServer()) {
+ mockRepo.enqueue(new MockResponse().setResponseCode(200).setBody("body"));
+ var httpRepo = MavenRepository.builder()
.id("id")
- .uri("http://%s:%d/maven".formatted(repo1.getHostName(), repo1.getPort()))
- .build(),
- MavenRepository.builder()
- .id("id2")
- .uri("http://%s:%d/maven".formatted(repo2.getHostName(), repo2.getPort()))
- .build()
- );
-
- assertThatThrownBy(() -> downloader.download(gav, null, null, repositories))
- .isInstanceOf(MavenDownloadingException.class)
- .hasMessageContaining("http://%s:%d/maven".formatted(repo1.getHostName(), repo1.getPort()))
- .hasMessageContaining("http://%s:%d/maven".formatted(repo2.getHostName(), repo2.getPort()));
- })
- );
- }
+ .uri("http://%s:%d/maven/".formatted(mockRepo.getHostName(), mockRepo.getPort()))
+ .build();
- @Test
- @Issue("https://github.com/openrewrite/rewrite/issues/3152")
- void useSnapshotTimestampVersion() {
- var downloader = new MavenPomDownloader(emptyMap(), ctx);
- var gav = new GroupArtifactVersion("fred", "fred", "2020.0.2-20210127.131051-2");
- try (MockWebServer mockRepo = new MockWebServer()) {
- mockRepo.setDispatcher(new Dispatcher() {
- @Override
- public MockResponse dispatch(RecordedRequest recordedRequest) {
- assert recordedRequest.getPath() != null;
- return !recordedRequest.getPath().endsWith("fred/fred/2020.0.2-SNAPSHOT/fred-2020.0.2-20210127.131051-2.pom") ?
- new MockResponse().setResponseCode(404).setBody("") :
- new MockResponse().setResponseCode(200).setBody(
- //language=xml
- """
-
- org.springframework.cloud
- spring-cloud-dataflow-build
- 2.10.0-SNAPSHOT
-
- """);
- }
- });
- mockRepo.start();
- var repositories = List.of(MavenRepository.builder()
- .id("id")
- .uri("http://%s:%d/maven".formatted(mockRepo.getHostName(), mockRepo.getPort()))
- .username("user")
- .password("pass")
- .build());
-
- assertDoesNotThrow(() -> downloader.download(gav, null, null, repositories));
- } catch (IOException e) {
- throw new RuntimeException(e);
- }
- }
+ var normalizedRepository = downloader.normalizeRepository(httpRepo, MavenExecutionContextView.view(ctx), null);
- @Test
- void usesAnonymousRequestIfRepositoryRejectsCredentials() {
- var downloader = new MavenPomDownloader(emptyMap(), ctx);
- var gav = new GroupArtifactVersion("fred", "fred", "1.0.0");
- try (MockWebServer mockRepo = new MockWebServer()) {
- mockRepo.setDispatcher(new Dispatcher() {
- @Override
- public MockResponse dispatch(RecordedRequest recordedRequest) {
- return recordedRequest.getHeaders().get("Authorization") != null ?
- new MockResponse().setResponseCode(401).setBody("") :
- new MockResponse().setResponseCode(200).setBody(
- //language=xml
- """
-
- org.springframework.cloud
- spring-cloud-dataflow-build
- 2.10.0-SNAPSHOT
-
- """);
- }
- });
- mockRepo.start();
- var repositories = List.of(MavenRepository.builder()
- .id("id")
- .uri("http://%s:%d/maven".formatted(mockRepo.getHostName(), mockRepo.getPort()))
- .username("user")
- .password("pass")
- .build());
-
- assertDoesNotThrow(() -> downloader.download(gav, null, null, repositories));
- } catch (IOException e) {
- throw new RuntimeException(e);
+ assertThat(normalizedRepository).isEqualTo(httpRepo);
+ }
}
- }
- @Test
- void usesAuthenticationIfRepositoryHasCredentials() {
- var downloader = new MavenPomDownloader(emptyMap(), ctx);
- var gav = new GroupArtifactVersion("fred", "fred", "1.0.0");
- try (MockWebServer mockRepo = new MockWebServer()) {
- mockRepo.setDispatcher(new Dispatcher() {
- @Override
- public MockResponse dispatch(RecordedRequest recordedRequest) {
- MockResponse response = new MockResponse();
- if (recordedRequest.getHeaders().get("Authorization") != null) {
- response.setResponseCode(200);
- if (!"HEAD".equalsIgnoreCase(recordedRequest.getMethod())) {
+ @Test
+ @Disabled
+ void dontFetchSnapshotsFromReleaseRepos() {
+ try (MockWebServer snapshotRepo = new MockWebServer();
+ MockWebServer releaseRepo = new MockWebServer()) {
+ snapshotRepo.setDispatcher(new Dispatcher() {
+ @Override
+ public MockResponse dispatch(RecordedRequest request) {
+ MockResponse response = new MockResponse().setResponseCode(200);
+ if (request.getPath() != null && request.getPath().contains("maven-metadata")) {
response.setBody(
//language=xml
"""
-
+
+ org.springframework.cloud
+ spring-cloud-dataflow-build
+ 2.10.0-SNAPSHOT
+
+
+ 20220201.001946
+ 85
+
+ 20220201001950
+
+
+ pom
+ 2.10.0-20220201.001946-85
+ 20220201001946
+
+
+
+
+ """
+ );
+ } else if (request.getPath() != null && request.getPath().endsWith(".pom")) {
+ response.setBody(
+ //language=xml
+ """
+
+ org.springframework.cloud
+ spring-cloud-dataflow-build
+ 2.10.0-SNAPSHOT
+
+ """
+ );
+ }
+ return response;
+ }
+ });
+
+ var metadataPaths = new AtomicInteger(0);
+ releaseRepo.setDispatcher(new Dispatcher() {
+ @Override
+ public MockResponse dispatch(RecordedRequest request) {
+ MockResponse response = new MockResponse().setResponseCode(404);
+ if (request.getPath() != null && request.getPath().contains("maven-metadata")) {
+ metadataPaths.incrementAndGet();
+ }
+ return response;
+ }
+ });
+
+ releaseRepo.start();
+ snapshotRepo.start();
+
+ MavenParser.builder().build().parse(ctx,
+ //language=xml
+ """
+
+ 4.0.0
+
+ org.openrewrite.test
+ foo
+ 0.1.0-SNAPSHOT
+
+
+
+ snapshot
+
+ true
+
+ http://%s:%d
+
+
+ release
+
+ false
+
+ http://%s:%d
+
+
+
+
+
org.springframework.cloud
spring-cloud-dataflow-build
2.10.0-SNAPSHOT
-
- """);
- }
- } else {
- response.setResponseCode(401);
- }
- return response;
- }
- });
- mockRepo.start();
- var repositories = List.of(MavenRepository.builder()
- .id("id")
- .uri("http://%s:%d/maven".formatted(mockRepo.getHostName(), mockRepo.getPort()))
- .username("user")
- .password("pass")
- .build());
-
- assertDoesNotThrow(() -> downloader.download(gav, null, null, repositories));
- } catch (IOException e) {
- throw new RuntimeException(e);
+
+
+
+ """.formatted(snapshotRepo.getHostName(), snapshotRepo.getPort(), releaseRepo.getHostName(), releaseRepo.getPort())
+ );
+
+ assertThat(snapshotRepo.getRequestCount()).isGreaterThan(1);
+ assertThat(metadataPaths.get()).isEqualTo(0);
+ } catch (IOException e) {
+ throw new RuntimeException(e);
+ }
}
- }
- @Test
- @DisplayName("When username or password are environment properties that cannot be resolved, they should not be used")
- @Issue("https://github.com/openrewrite/rewrite/issues/3142")
- void doesNotUseAuthenticationIfCredentialsCannotBeResolved() {
- var downloader = new MavenPomDownloader(emptyMap(), ctx);
- var gav = new GroupArtifactVersion("fred", "fred", "1.0.0");
- try (MockWebServer mockRepo = new MockWebServer()) {
- mockRepo.setDispatcher(new Dispatcher() {
- @Override
- public MockResponse dispatch(RecordedRequest recordedRequest) {
- MockResponse response = new MockResponse();
- if (recordedRequest.getHeaders().get("Authorization") != null) {
- response.setResponseCode(401);
- } else if (recordedRequest.getMethod() == null || !recordedRequest.getMethod().equalsIgnoreCase("HEAD")) {
- response.setBody(
- //language=xml
- """
-
- org.springframework.cloud
- spring-cloud-dataflow-build
- 2.10.0-SNAPSHOT
-
- """);
- }
- return response;
- }
- });
- mockRepo.start();
- var repositories = List.of(MavenRepository.builder()
- .id("id")
- .uri("http://%s:%d/maven".formatted(mockRepo.getHostName(), mockRepo.getPort()))
- .username("${env.ARTIFACTORY_USERNAME}")
- .password("${env.ARTIFACTORY_USERNAME}")
- .build());
-
- assertDoesNotThrow(() -> downloader.download(gav, null, null, repositories));
- } catch (IOException e) {
- throw new RuntimeException(e);
+ @Test
+ void deriveMetaDataFromFileRepository(@TempDir Path repoPath) throws IOException, MavenDownloadingException {
+ Path fred = repoPath.resolve("fred/fred");
+
+ for (String version : Arrays.asList("1.0.0", "1.1.0", "2.0.0")) {
+ Path versionPath = fred.resolve(version);
+ Files.createDirectories(versionPath);
+ Files.writeString(versionPath.resolve("fred-" + version + ".pom"), "");
+ }
+
+ MavenRepository repository = MavenRepository.builder()
+ .id("file-based")
+ .uri(repoPath.toUri().toString())
+ .knownToExist(true)
+ .deriveMetadataIfMissing(true)
+ .build();
+ MavenMetadata metaData = new MavenPomDownloader(emptyMap(), ctx)
+ .downloadMetadata(new GroupArtifact("fred", "fred"), null, List.of(repository));
+ assertThat(metaData.getVersioning().getVersions()).hasSize(3).containsAll(Arrays.asList("1.0.0", "1.1.0", "2.0.0"));
}
- }
- @Test
- @Disabled
- void dontFetchSnapshotsFromReleaseRepos() {
- try (MockWebServer snapshotRepo = new MockWebServer();
- MockWebServer releaseRepo = new MockWebServer()) {
- snapshotRepo.setDispatcher(new Dispatcher() {
- @Override
- public MockResponse dispatch(RecordedRequest request) {
- MockResponse response = new MockResponse().setResponseCode(200);
- if (request.getPath() != null && request.getPath().contains("maven-metadata")) {
- response.setBody(
- //language=xml
- """
-
- org.springframework.cloud
- spring-cloud-dataflow-build
- 2.10.0-SNAPSHOT
-
-
- 20220201.001946
- 85
-
- 20220201001950
-
-
- pom
- 2.10.0-20220201.001946-85
- 20220201001946
-
-
-
-
- """
- );
- } else if (request.getPath() != null && request.getPath().endsWith(".pom")) {
- response.setBody(
- //language=xml
- """
-
- org.springframework.cloud
- spring-cloud-dataflow-build
- 2.10.0-SNAPSHOT
-
- """
- );
- }
- return response;
- }
- });
+ @SuppressWarnings("ConstantConditions")
+ @Test
+ void mergeMetadata() throws IOException {
+ @Language("xml") String metadata1 = """
+
+ org.springframework.boot
+ spring-boot
+
+
+ 2.3.3
+ 2.4.1
+ 2.4.2
+
+
+ 20220927.033510
+ 223
+
+
+
+ pom.asc
+ 0.1.0-20220927.033510-223
+ 20220927033510
+
+
+
+
+ """;
+
+ @Language("xml") String metadata2 = """
+
+ org.springframework.boot
+ spring-boot
+
+
+ 2.3.2
+ 2.3.3
+
+
+ 20210115.042754
+ 180
+
+
+
+ pom.asc
+ 0.1.0-20210115.042754-180
+ 20210115042754
+
+
+
+
+ """;
+
+ var m1 = MavenMetadata.parse(metadata1.getBytes());
+ var m2 = MavenMetadata.parse(metadata2.getBytes());
+
+ var merged = new MavenPomDownloader(emptyMap(), ctx).mergeMetadata(m1, m2);
+
+ assertThat(merged.getVersioning().getSnapshot().getTimestamp()).isEqualTo("20220927.033510");
+ assertThat(merged.getVersioning().getSnapshot().getBuildNumber()).isEqualTo("223");
+ assertThat(merged.getVersioning().getVersions()).hasSize(4).contains("2.3.2", "2.3.3", "2.4.1", "2.4.2");
+ assertThat(merged.getVersioning().getSnapshotVersions()).hasSize(2);
+ assertThat(merged.getVersioning().getSnapshotVersions().get(0).getExtension()).isNotNull();
+ assertThat(merged.getVersioning().getSnapshotVersions().get(0).getValue()).isNotNull();
+ assertThat(merged.getVersioning().getSnapshotVersions().get(0).getUpdated()).isNotNull();
+ }
- var metadataPaths = new AtomicInteger(0);
- releaseRepo.setDispatcher(new Dispatcher() {
- @Override
- public MockResponse dispatch(RecordedRequest request) {
- MockResponse response = new MockResponse().setResponseCode(404);
- if (request.getPath() != null && request.getPath().contains("maven-metadata")) {
- metadataPaths.incrementAndGet();
- }
- return response;
- }
- });
+ @Test
+ void skipsLocalInvalidArtifactsMissingJar(@TempDir Path localRepository) throws IOException {
+ Path localArtifact = localRepository.resolve("com/bad/bad-artifact");
+ assertThat(localArtifact.toFile().mkdirs()).isTrue();
+ Files.createDirectories(localArtifact.resolve("1"));
- releaseRepo.start();
- snapshotRepo.start();
+ Path localPom = localRepository.resolve("com/bad/bad-artifact/1/bad-artifact-1.pom");
+ Files.writeString(localPom,
+ //language=xml
+ """
+
+ com.bad
+ bad-artifact
+ 1
+
+ """
+ );
+
+ MavenRepository mavenLocal = MavenRepository.builder()
+ .id("local")
+ .uri(localRepository.toUri().toString())
+ .snapshots(false)
+ .knownToExist(true)
+ .build();
+
+ // Does not return invalid dependency.
+ assertThrows(MavenDownloadingException.class, () ->
+ new MavenPomDownloader(emptyMap(), ctx)
+ .download(new GroupArtifactVersion("com.bad", "bad-artifact", "1"), null, null, List.of(mavenLocal)));
+ }
+
+ @Test
+ void skipsLocalInvalidArtifactsEmptyJar(@TempDir Path localRepository) throws IOException {
+ Path localArtifact = localRepository.resolve("com/bad/bad-artifact");
+ assertThat(localArtifact.toFile().mkdirs()).isTrue();
+ Files.createDirectories(localArtifact.resolve("1"));
- MavenParser.builder().build().parse(ctx,
+ Path localPom = localRepository.resolve("com/bad/bad-artifact/1/bad-artifact-1.pom");
+ Files.writeString(localPom,
//language=xml
"""
-
- 4.0.0
-
- org.openrewrite.test
- foo
- 0.1.0-SNAPSHOT
-
-
-
- snapshot
-
- true
-
- http://%s:%d
-
-
- release
-
- false
-
- http://%s:%d
-
-
-
-
-
- org.springframework.cloud
- spring-cloud-dataflow-build
- 2.10.0-SNAPSHOT
-
-
-
- """.formatted(snapshotRepo.getHostName(), snapshotRepo.getPort(), releaseRepo.getHostName(), releaseRepo.getPort())
+
+ com.bad
+ bad-artifact
+ 1
+
+ """
);
+ Path localJar = localRepository.resolve("com/bad/bad-artifact/1/bad-artifact-1.jar");
+ Files.writeString(localJar, "");
+
+ MavenRepository mavenLocal = MavenRepository.builder()
+ .id("local")
+ .uri(localRepository.toUri().toString())
+ .snapshots(false)
+ .knownToExist(true)
+ .build();
- assertThat(snapshotRepo.getRequestCount()).isGreaterThan(1);
- assertThat(metadataPaths.get()).isEqualTo(0);
- } catch (IOException e) {
- throw new RuntimeException(e);
+ // Does not return invalid dependency.
+ assertThrows(MavenDownloadingException.class, () ->
+ new MavenPomDownloader(emptyMap(), ctx)
+ .download(new GroupArtifactVersion("com.bad", "bad-artifact", "1"), null, null, List.of(mavenLocal)));
}
- }
- @Test
- void deriveMetaDataFromFileRepository(@TempDir Path repoPath) throws IOException, MavenDownloadingException {
- Path fred = repoPath.resolve("fred/fred");
+ @Test
+ void doNotRenameRepoForCustomMavenLocal(@TempDir Path tempDir) throws MavenDownloadingException, IOException {
+ GroupArtifactVersion gav = createArtifact(tempDir);
+ MavenExecutionContextView.view(ctx).setLocalRepository(MavenRepository.MAVEN_LOCAL_DEFAULT.withUri(tempDir.toUri().toString()));
+ var downloader = new MavenPomDownloader(emptyMap(), ctx);
- for (String version : Arrays.asList("1.0.0", "1.1.0", "2.0.0")) {
- Path versionPath = fred.resolve(version);
- Files.createDirectories(versionPath);
- Files.writeString(versionPath.resolve("fred-" + version + ".pom"), "");
+ var result = downloader.download(gav, null, null, List.of());
+ //noinspection DataFlowIssue
+ assertThat(result.getRepository()).isNotNull();
+ assertThat(result.getRepository().getUri()).startsWith(tempDir.toUri().toString());
}
- MavenRepository repository = MavenRepository.builder()
- .id("file-based")
- .uri(repoPath.toUri().toString())
- .knownToExist(true)
- .deriveMetadataIfMissing(true)
- .build();
- MavenMetadata metaData = new MavenPomDownloader(emptyMap(), ctx)
- .downloadMetadata(new GroupArtifact("fred", "fred"), null, List.of(repository));
- assertThat(metaData.getVersioning().getVersions()).hasSize(3).containsAll(Arrays.asList("1.0.0", "1.1.0", "2.0.0"));
- }
+ @Issue("https://github.com/openrewrite/rewrite/issues/4080")
+ @Test
+ void connectTimeout() {
+ var downloader = new MavenPomDownloader(ctx);
+ var gav = new GroupArtifactVersion("org.openrewrite", "rewrite-core", "7.0.0");
+ var repos = singletonList(MavenRepository.builder()
+ .id("non-routable").uri("http://10.0.0.0/maven").knownToExist(true).build());
+
+ assertThatThrownBy(() -> downloader.download(gav, null, null, repos))
+ .isInstanceOf(MavenDownloadingException.class)
+ .hasMessageContaining("rewrite-core")
+ .hasMessageContaining("10.0.0.0");
+ }
- @SuppressWarnings("ConstantConditions")
- @Test
- void mergeMetadata() throws IOException {
- @Language("xml") String metadata1 = """
-
- org.springframework.boot
- spring-boot
-
-
- 2.3.3
- 2.4.1
- 2.4.2
-
-
- 20220927.033510
- 223
-
-
-
- pom.asc
- 0.1.0-20220927.033510-223
- 20220927033510
-
-
-
-
- """;
-
- @Language("xml") String metadata2 = """
-
- org.springframework.boot
- spring-boot
-
-
- 2.3.2
- 2.3.3
-
-
- 20210115.042754
- 180
-
-
-
- pom.asc
- 0.1.0-20210115.042754-180
- 20210115042754
-
-
-
-
- """;
-
- var m1 = MavenMetadata.parse(metadata1.getBytes());
- var m2 = MavenMetadata.parse(metadata2.getBytes());
-
- var merged = new MavenPomDownloader(emptyMap(), ctx).mergeMetadata(m1, m2);
-
- assertThat(merged.getVersioning().getSnapshot().getTimestamp()).isEqualTo("20220927.033510");
- assertThat(merged.getVersioning().getSnapshot().getBuildNumber()).isEqualTo("223");
- assertThat(merged.getVersioning().getVersions()).hasSize(4).contains("2.3.2", "2.3.3", "2.4.1", "2.4.2");
- assertThat(merged.getVersioning().getSnapshotVersions()).hasSize(2);
- assertThat(merged.getVersioning().getSnapshotVersions().get(0).getExtension()).isNotNull();
- assertThat(merged.getVersioning().getSnapshotVersions().get(0).getValue()).isNotNull();
- assertThat(merged.getVersioning().getSnapshotVersions().get(0).getUpdated()).isNotNull();
- }
+ private static GroupArtifactVersion createArtifact(Path repository) throws IOException {
+ Path target = repository.resolve(Paths.get("org", "openrewrite", "rewrite", "1.0.0"));
+ Path pom = target.resolve("rewrite-1.0.0.pom");
+ Path jar = target.resolve("rewrite-1.0.0.jar");
+ Files.createDirectories(target);
+ Files.createFile(pom);
+ Files.createFile(jar);
- @Test
- void skipsLocalInvalidArtifactsMissingJar(@TempDir Path localRepository) throws IOException {
- Path localArtifact = localRepository.resolve("com/bad/bad-artifact");
- assertThat(localArtifact.toFile().mkdirs()).isTrue();
- Files.createDirectories(localArtifact.resolve("1"));
-
- Path localPom = localRepository.resolve("com/bad/bad-artifact/1/bad-artifact-1.pom");
- Files.writeString(localPom,
- //language=xml
- """
-
- com.bad
- bad-artifact
- 1
-
- """
- );
-
- MavenRepository mavenLocal = MavenRepository.builder()
- .id("local")
- .uri(localRepository.toUri().toString())
- .snapshots(false)
- .knownToExist(true)
- .build();
+ Files.write(pom,
+ //language=xml
+ """
+
+ org.openrewrite
+ rewrite
+ 1.0.0
+
+ """.getBytes());
+ Files.write(jar, "I'm a jar".getBytes()); // empty jars get ignored
+ return new GroupArtifactVersion("org.openrewrite", "rewrite", "1.0.0");
+ }
- // Does not return invalid dependency.
- assertThrows(MavenDownloadingException.class, () ->
- new MavenPomDownloader(emptyMap(), ctx)
- .download(new GroupArtifactVersion("com.bad", "bad-artifact", "1"), null, null, List.of(mavenLocal)));
- }
+ @Test
+ void shouldNotThrowExceptionForModulesInModulesWithRightProperty() {
+ var gav = new GroupArtifactVersion("test", "test2", "${test}");
+
+ Path pomPath = Paths.get("test/test2/pom.xml");
+ Pom pom = Pom.builder()
+ .sourcePath(pomPath)
+ .repository(MAVEN_CENTRAL)
+ .properties(singletonMap("REPO_URL", MAVEN_CENTRAL.getUri()))
+ .parent(new Parent(new GroupArtifactVersion("test", "test", "${test}"), "../pom.xml"))
+ .gav(new ResolvedGroupArtifactVersion(
+ "${REPO_URL}", "test", "test2", "7.0.0", null))
+ .build();
- @Test
- void skipsLocalInvalidArtifactsEmptyJar(@TempDir Path localRepository) throws IOException {
- Path localArtifact = localRepository.resolve("com/bad/bad-artifact");
- assertThat(localArtifact.toFile().mkdirs()).isTrue();
- Files.createDirectories(localArtifact.resolve("1"));
-
- Path localPom = localRepository.resolve("com/bad/bad-artifact/1/bad-artifact-1.pom");
- Files.writeString(localPom,
- //language=xml
- """
-
- com.bad
- bad-artifact
- 1
-
- """
- );
- Path localJar = localRepository.resolve("com/bad/bad-artifact/1/bad-artifact-1.jar");
- Files.writeString(localJar, "");
-
- MavenRepository mavenLocal = MavenRepository.builder()
- .id("local")
- .uri(localRepository.toUri().toString())
- .snapshots(false)
- .knownToExist(true)
- .build();
+ ResolvedPom resolvedPom = ResolvedPom.builder()
+ .requested(pom)
+ .properties(singletonMap("REPO_URL", MAVEN_CENTRAL.getUri()))
+ .repositories(singletonList(MAVEN_CENTRAL))
+ .build();
- // Does not return invalid dependency.
- assertThrows(MavenDownloadingException.class, () ->
- new MavenPomDownloader(emptyMap(), ctx)
- .download(new GroupArtifactVersion("com.bad", "bad-artifact", "1"), null, null, List.of(mavenLocal)));
- }
+ Path pomPath2 = Paths.get("test/pom.xml");
+ Pom pom2 = Pom.builder()
+ .sourcePath(pomPath)
+ .repository(MAVEN_CENTRAL)
+ .properties(singletonMap("REPO_URL", MAVEN_CENTRAL.getUri()))
+ .parent(new Parent(new GroupArtifactVersion("test", "root-test", "${test}"), "../pom.xml"))
+ .gav(new ResolvedGroupArtifactVersion(
+ "${REPO_URL}", "test", "test", "7.0.0", null))
+ .build();
- @Test
- void doNotRenameRepoForCustomMavenLocal(@TempDir Path tempDir) throws MavenDownloadingException, IOException {
- GroupArtifactVersion gav = createArtifact(tempDir);
- MavenExecutionContextView.view(ctx).setLocalRepository(MavenRepository.MAVEN_LOCAL_DEFAULT.withUri(tempDir.toUri().toString()));
- var downloader = new MavenPomDownloader(emptyMap(), ctx);
-
- var result = downloader.download(gav, null, null, List.of());
- //noinspection DataFlowIssue
- assertThat(result.getRepository()).isNotNull();
- assertThat(result.getRepository().getUri()).startsWith(tempDir.toUri().toString());
- }
- @Issue("https://github.com/openrewrite/rewrite/issues/4080")
- @Test
- void connectTimeout() {
- var downloader = new MavenPomDownloader(ctx);
- var gav = new GroupArtifactVersion("org.openrewrite", "rewrite-core", "7.0.0");
- var repos = singletonList(MavenRepository.builder()
- .id("non-routable").uri("http://10.0.0.0/maven").knownToExist(true).build());
-
- assertThatThrownBy(() -> downloader.download(gav, null, null, repos))
- .isInstanceOf(MavenDownloadingException.class)
- .hasMessageContaining("rewrite-core")
- .hasMessageContaining("10.0.0.0");
- }
+ Path parentPomPath = Paths.get("pom.xml");
+ Pom parentPom = Pom.builder()
+ .sourcePath(parentPomPath)
+ .repository(MAVEN_CENTRAL)
+ .properties(singletonMap("test", "7.0.0"))
+ .parent(null)
+ .gav(new ResolvedGroupArtifactVersion(
+ "${REPO_URL}", "test", "root-test", "7.0.0", null))
+ .build();
- @CsvSource(textBlock = """
- https://repo1.maven.org/maven2/, https://repo1.maven.org/maven2/
- https://repo1.maven.org/maven2, https://repo1.maven.org/maven2/
- http://repo1.maven.org/maven2/, https://repo1.maven.org/maven2/
-
- https://oss.sonatype.org/content/repositories/snapshots/, https://oss.sonatype.org/content/repositories/snapshots/
- https://artifactory.moderne.ninja/artifactory/moderne-public/, https://artifactory.moderne.ninja/artifactory/moderne-public/
- https://repo.maven.apache.org/maven2/, https://repo.maven.apache.org/maven2/
- https://jitpack.io/, https://jitpack.io/
- """)
- @ParameterizedTest
- void normalizeRepository(String originalUrl, String expectedUrl) throws Throwable {
- MavenPomDownloader downloader = new MavenPomDownloader(new InMemoryExecutionContext());
- MavenRepository repository = new MavenRepository("id", originalUrl, null, null, null, null, null);
- MavenRepository normalized = downloader.normalizeRepository(repository);
- assertThat(normalized).isNotNull();
- assertThat(normalized.getUri()).isEqualTo(expectedUrl);
- }
+ Map pomsByPath = new HashMap<>();
+ pomsByPath.put(parentPomPath, parentPom);
+ pomsByPath.put(pomPath, pom);
+ pomsByPath.put(pomPath2, pom2);
- private static GroupArtifactVersion createArtifact(Path repository) throws IOException {
- Path target = repository.resolve(Paths.get("org", "openrewrite", "rewrite", "1.0.0"));
- Path pom = target.resolve("rewrite-1.0.0.pom");
- Path jar = target.resolve("rewrite-1.0.0.jar");
- Files.createDirectories(target);
- Files.createFile(pom);
- Files.createFile(jar);
-
- Files.write(pom,
- //language=xml
- """
-
- org.openrewrite
- rewrite
- 1.0.0
-
- """.getBytes());
- Files.write(jar, "I'm a jar".getBytes()); // empty jars get ignored
- return new GroupArtifactVersion("org.openrewrite", "rewrite", "1.0.0");
- }
+ String httpUrl = "http://%s.com".formatted(UUID.randomUUID());
+ MavenRepository nonexistentRepo = new MavenRepository("repo", httpUrl, null, null, false, null, null, null, null);
- @Test
- void shouldNotThrowExceptionForModulesInModulesWithRightProperty() {
- var gav = new GroupArtifactVersion("test", "test2", "${test}");
-
- Path pomPath = Paths.get("test/test2/pom.xml");
- Pom pom = Pom.builder()
- .sourcePath(pomPath)
- .repository(MAVEN_CENTRAL)
- .properties(singletonMap("REPO_URL", MAVEN_CENTRAL.getUri()))
- .parent(new Parent(new GroupArtifactVersion("test", "test", "${test}"), "../pom.xml"))
- .gav(new ResolvedGroupArtifactVersion(
- "${REPO_URL}", "test", "test2", "7.0.0", null))
- .build();
+ MavenPomDownloader downloader = new MavenPomDownloader(pomsByPath, ctx);
- ResolvedPom resolvedPom = ResolvedPom.builder()
- .requested(pom)
- .properties(singletonMap("REPO_URL", MAVEN_CENTRAL.getUri()))
- .repositories(singletonList(MAVEN_CENTRAL))
- .build();
+ assertDoesNotThrow(() -> downloader.download(gav, Objects.requireNonNull(pom.getParent()).getRelativePath(), resolvedPom, singletonList(nonexistentRepo)));
+ }
- Path pomPath2 = Paths.get("test/pom.xml");
- Pom pom2 = Pom.builder()
- .sourcePath(pomPath)
- .repository(MAVEN_CENTRAL)
- .properties(singletonMap("REPO_URL", MAVEN_CENTRAL.getUri()))
- .parent(new Parent(new GroupArtifactVersion("test", "root-test", "${test}"), "../pom.xml"))
- .gav(new ResolvedGroupArtifactVersion(
- "${REPO_URL}", "test", "test", "7.0.0", null))
- .build();
+ @Test
+ void shouldThrowExceptionForModulesInModulesWithNoRightProperty() {
+ var gav = new GroupArtifactVersion("test", "test2", "${test}");
+
+ Path pomPath = Paths.get("test/test2/pom.xml");
+ Pom pom = Pom.builder()
+ .sourcePath(pomPath)
+ .repository(MAVEN_CENTRAL)
+ .properties(singletonMap("REPO_URL", MAVEN_CENTRAL.getUri()))
+ .parent(new Parent(new GroupArtifactVersion("test", "test", "${test}"), "../pom.xml"))
+ .gav(new ResolvedGroupArtifactVersion(
+ "${REPO_URL}", "test", "test2", "7.0.0", null))
+ .build();
+ ResolvedPom resolvedPom = ResolvedPom.builder()
+ .requested(pom)
+ .properties(singletonMap("REPO_URL", MAVEN_CENTRAL.getUri()))
+ .repositories(singletonList(MAVEN_CENTRAL))
+ .build();
- Path parentPomPath = Paths.get("pom.xml");
- Pom parentPom = Pom.builder()
- .sourcePath(parentPomPath)
- .repository(MAVEN_CENTRAL)
- .properties(singletonMap("test", "7.0.0"))
- .parent(null)
- .gav(new ResolvedGroupArtifactVersion(
- "${REPO_URL}", "test", "root-test", "7.0.0", null))
- .build();
+ Path pomPath2 = Paths.get("test/pom.xml");
+ Pom pom2 = Pom.builder()
+ .sourcePath(pomPath)
+ .repository(MAVEN_CENTRAL)
+ .properties(singletonMap("REPO_URL", MAVEN_CENTRAL.getUri()))
+ .parent(new Parent(new GroupArtifactVersion("test", "root-test", "${test}"), "../pom.xml"))
+ .gav(new ResolvedGroupArtifactVersion(
+ "${REPO_URL}", "test", "test", "7.0.0", null))
+ .build();
- Map pomsByPath = new HashMap<>();
- pomsByPath.put(parentPomPath, parentPom);
- pomsByPath.put(pomPath, pom);
- pomsByPath.put(pomPath2, pom2);
- String httpUrl = "http://%s.com".formatted(UUID.randomUUID());
- MavenRepository nonexistentRepo = new MavenRepository("repo", httpUrl, null, null, false, null, null, null, null);
+ Path parentPomPath = Paths.get("pom.xml");
+ Pom parentPom = Pom.builder()
+ .sourcePath(parentPomPath)
+ .repository(MAVEN_CENTRAL)
+ .properties(singletonMap("tt", "7.0.0"))
+ .parent(null)
+ .gav(new ResolvedGroupArtifactVersion(
+ "${REPO_URL}", "test", "root-test", "7.0.0", null))
+ .build();
+
+ Map pomsByPath = new HashMap<>();
+ pomsByPath.put(parentPomPath, parentPom);
+ pomsByPath.put(pomPath, pom);
+ pomsByPath.put(pomPath2, pom2);
- MavenPomDownloader downloader = new MavenPomDownloader(pomsByPath, ctx);
+ String httpUrl = "http://%s.com".formatted(UUID.randomUUID());
+ MavenRepository nonexistentRepo = new MavenRepository("repo", httpUrl, null, null, false, null, null, null, null);
- assertDoesNotThrow(() -> downloader.download(gav, Objects.requireNonNull(pom.getParent()).getRelativePath(), resolvedPom, singletonList(nonexistentRepo)));
+ MavenPomDownloader downloader = new MavenPomDownloader(pomsByPath, ctx);
+
+ assertThrows(IllegalArgumentException.class, () -> downloader.download(gav, Objects.requireNonNull(pom.getParent()).getRelativePath(), resolvedPom, singletonList(nonexistentRepo)));
+ }
}
- @Test
- void shouldThrowExceptionForModulesInModulesWithNoRightProperty() {
- var gav = new GroupArtifactVersion("test", "test2", "${test}");
-
- Path pomPath = Paths.get("test/test2/pom.xml");
- Pom pom = Pom.builder()
- .sourcePath(pomPath)
- .repository(MAVEN_CENTRAL)
- .properties(singletonMap("REPO_URL", MAVEN_CENTRAL.getUri()))
- .parent(new Parent(new GroupArtifactVersion("test", "test", "${test}"), "../pom.xml"))
- .gav(new ResolvedGroupArtifactVersion(
- "${REPO_URL}", "test", "test2", "7.0.0", null))
- .build();
+ @Nested
+ class WithOkHttpClientAndSelfSignedTLS {
+ private final SSLSocketFactory sslSocketFactory;
+ private final ExecutionContext ctx;
- ResolvedPom resolvedPom = ResolvedPom.builder()
- .requested(pom)
- .properties(singletonMap("REPO_URL", MAVEN_CENTRAL.getUri()))
- .repositories(singletonList(MAVEN_CENTRAL))
- .build();
+ WithOkHttpClientAndSelfSignedTLS() throws UnknownHostException {
+ String localhost = InetAddress.getByName("localhost").getCanonicalHostName();
+ HeldCertificate localhostCertificate = new HeldCertificate.Builder()
+ .addSubjectAlternativeName(localhost)
+ .build();
+ sslSocketFactory = new HandshakeCertificates.Builder()
+ .heldCertificate(localhostCertificate)
+ .build().sslSocketFactory();
- Path pomPath2 = Paths.get("test/pom.xml");
- Pom pom2 = Pom.builder()
- .sourcePath(pomPath)
- .repository(MAVEN_CENTRAL)
- .properties(singletonMap("REPO_URL", MAVEN_CENTRAL.getUri()))
- .parent(new Parent(new GroupArtifactVersion("test", "root-test", "${test}"), "../pom.xml"))
- .gav(new ResolvedGroupArtifactVersion(
- "${REPO_URL}", "test", "test", "7.0.0", null))
- .build();
+ HandshakeCertificates clientCertificates = new HandshakeCertificates.Builder()
+ .addTrustedCertificate(localhostCertificate.certificate())
+ .build();
+ OkHttpClient client = new OkHttpClient.Builder()
+ .sslSocketFactory(clientCertificates.sslSocketFactory(), clientCertificates.trustManager())
+ .connectTimeout(Duration.ofMillis(250))
+ .readTimeout(Duration.ofMillis(250))
+ .build();
+ ctx = HttpSenderExecutionContextView.view(new InMemoryExecutionContext())
+ .setHttpSender(new OkHttpSender(client));
+ }
+ private MockWebServer getMockServer() {
+ var mockWebServer = new MockWebServer();
+ mockWebServer.useHttps(sslSocketFactory, false);
+ return mockWebServer;
+ }
- Path parentPomPath = Paths.get("pom.xml");
- Pom parentPom = Pom.builder()
- .sourcePath(parentPomPath)
- .repository(MAVEN_CENTRAL)
- .properties(singletonMap("tt", "7.0.0"))
- .parent(null)
- .gav(new ResolvedGroupArtifactVersion(
- "${REPO_URL}", "test", "root-test", "7.0.0", null))
- .build();
+ private void mockServer(Integer responseCode, Consumer block) {
+ try (MockWebServer mockRepo = getMockServer()) {
+ mockRepo.setDispatcher(new Dispatcher() {
+ @Override
+ public MockResponse dispatch(RecordedRequest recordedRequest) {
+ return new MockResponse().setResponseCode(responseCode).setBody("");
+ }
+ });
+ mockRepo.start();
+ block.accept(mockRepo);
+ assertThat(mockRepo.getRequestCount())
+ .as("The mock repository received no requests. The test is not using it.")
+ .isGreaterThan(0);
+ } catch (IOException e) {
+ throw new RuntimeException(e);
+ }
+ }
- Map pomsByPath = new HashMap<>();
- pomsByPath.put(parentPomPath, parentPom);
- pomsByPath.put(pomPath, pom);
- pomsByPath.put(pomPath2, pom2);
+ @Test
+ void useHttpsWhenAvailable() {
+ var downloader = new MavenPomDownloader(emptyMap(), ctx);
+ mockServer(200, mockRepo -> {
+ var normalizedRepository = downloader.normalizeRepository(
+ MavenRepository.builder()
+ .id("id")
+ .uri("http://%s:%d/maven/".formatted(mockRepo.getHostName(), mockRepo.getPort()))
+ .build(),
+ MavenExecutionContextView.view(ctx),
+ null);
+
+ assertThat(normalizedRepository).isEqualTo(
+ MavenRepository.builder()
+ .id("id")
+ .uri("https://%s:%d/maven/".formatted(mockRepo.getHostName(), mockRepo.getPort()))
+ .build());
+ });
+ }
- String httpUrl = "http://%s.com".formatted(UUID.randomUUID());
- MavenRepository nonexistentRepo = new MavenRepository("repo", httpUrl, null, null, false, null, null, null, null);
+ @ParameterizedTest
+ @ValueSource(ints = {500, 400})
+ void normalizeAcceptErrorStatuses(Integer status) {
+ var downloader = new MavenPomDownloader(emptyMap(), ctx);
+ mockServer(status, mockRepo -> {
+ var originalRepo = MavenRepository.builder()
+ .id("id")
+ .uri("https://%s:%d/maven/".formatted(mockRepo.getHostName(), mockRepo.getPort()))
+ .build();
+ var normalizedRepo = downloader.normalizeRepository(originalRepo, MavenExecutionContextView.view(ctx), null);
+ assertThat(normalizedRepo).isEqualTo(originalRepo);
+ });
+ }
- MavenPomDownloader downloader = new MavenPomDownloader(pomsByPath, ctx);
+ @Test
+ void invalidArtifact() {
+ var downloader = new MavenPomDownloader(emptyMap(), ctx);
+ var gav = new GroupArtifactVersion("fred", "fred", "1.0.0");
+ mockServer(500,
+ repo1 -> mockServer(400, repo2 -> {
+ var repositories = List.of(
+ MavenRepository.builder()
+ .id("id")
+ .uri("http://%s:%d/maven".formatted(repo1.getHostName(), repo1.getPort()))
+ .build(),
+ MavenRepository.builder()
+ .id("id2")
+ .uri("http://%s:%d/maven".formatted(repo2.getHostName(), repo2.getPort()))
+ .build()
+ );
+
+ assertThatThrownBy(() -> downloader.download(gav, null, null, repositories))
+ .isInstanceOf(MavenDownloadingException.class)
+ .hasMessageContaining("https://%s:%d/maven".formatted(repo1.getHostName(), repo1.getPort()))
+ .hasMessageContaining("https://%s:%d/maven".formatted(repo2.getHostName(), repo2.getPort()));
+ })
+ );
+ }
- assertThrows(IllegalArgumentException.class, () -> downloader.download(gav, Objects.requireNonNull(pom.getParent()).getRelativePath(), resolvedPom, singletonList(nonexistentRepo)));
- }
+ @Test
+ @Issue("https://github.com/openrewrite/rewrite/issues/3152")
+ void useSnapshotTimestampVersion() {
+ var downloader = new MavenPomDownloader(emptyMap(), ctx);
+ var gav = new GroupArtifactVersion("fred", "fred", "2020.0.2-20210127.131051-2");
+ try (MockWebServer mockRepo = getMockServer()) {
+ mockRepo.setDispatcher(new Dispatcher() {
+ @Override
+ public MockResponse dispatch(RecordedRequest recordedRequest) {
+ assert recordedRequest.getPath() != null;
+ return !recordedRequest.getPath().endsWith("fred/fred/2020.0.2-SNAPSHOT/fred-2020.0.2-20210127.131051-2.pom") ?
+ new MockResponse().setResponseCode(404).setBody("") :
+ new MockResponse().setResponseCode(200).setBody(
+ //language=xml
+ """
+
+ org.springframework.cloud
+ spring-cloud-dataflow-build
+ 2.10.0-SNAPSHOT
+
+ """);
+ }
+ });
+ mockRepo.start();
+ var repositories = List.of(MavenRepository.builder()
+ .id("id")
+ .uri("http://%s:%d/maven".formatted(mockRepo.getHostName(), mockRepo.getPort()))
+ .username("user")
+ .password("pass")
+ .build());
+
+ assertDoesNotThrow(() -> downloader.download(gav, null, null, repositories));
+ } catch (IOException e) {
+ throw new RuntimeException(e);
+ }
+ }
+ @Test
+ void usesAnonymousRequestIfRepositoryRejectsCredentials() {
+ var downloader = new MavenPomDownloader(emptyMap(), ctx);
+ var gav = new GroupArtifactVersion("fred", "fred", "1.0.0");
+ try (MockWebServer mockRepo = getMockServer()) {
+ mockRepo.setDispatcher(new Dispatcher() {
+ @Override
+ public MockResponse dispatch(RecordedRequest recordedRequest) {
+ return recordedRequest.getHeaders().get("Authorization") != null ?
+ new MockResponse().setResponseCode(401).setBody("") :
+ new MockResponse().setResponseCode(200).setBody(
+ //language=xml
+ """
+
+ org.springframework.cloud
+ spring-cloud-dataflow-build
+ 2.10.0-SNAPSHOT
+
+ """);
+ }
+ });
+ mockRepo.start();
+ var repositories = List.of(MavenRepository.builder()
+ .id("id")
+ .uri("http://%s:%d/maven".formatted(mockRepo.getHostName(), mockRepo.getPort()))
+ .username("user")
+ .password("pass")
+ .build());
+
+ assertDoesNotThrow(() -> downloader.download(gav, null, null, repositories));
+ } catch (IOException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ @Test
+ void usesAuthenticationIfRepositoryHasCredentials() {
+ var downloader = new MavenPomDownloader(emptyMap(), ctx);
+ var gav = new GroupArtifactVersion("fred", "fred", "1.0.0");
+ try (MockWebServer mockRepo = getMockServer()) {
+ mockRepo.setDispatcher(new Dispatcher() {
+ @Override
+ public MockResponse dispatch(RecordedRequest recordedRequest) {
+ MockResponse response = new MockResponse();
+ if (recordedRequest.getHeaders().get("Authorization") != null) {
+ response.setResponseCode(200);
+ if (!"HEAD".equalsIgnoreCase(recordedRequest.getMethod())) {
+ response.setBody(
+ //language=xml
+ """
+
+ org.springframework.cloud
+ spring-cloud-dataflow-build
+ 2.10.0-SNAPSHOT
+
+ """);
+ }
+ } else {
+ response.setResponseCode(401);
+ }
+ return response;
+ }
+ });
+ mockRepo.start();
+ var repositories = List.of(MavenRepository.builder()
+ .id("id")
+ .uri("http://%s:%d/maven".formatted(mockRepo.getHostName(), mockRepo.getPort()))
+ .username("user")
+ .password("pass")
+ .build());
+
+ assertDoesNotThrow(() -> downloader.download(gav, null, null, repositories));
+ } catch (IOException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ @Test
+ @DisplayName("When username or password are environment properties that cannot be resolved, they should not be used")
+ @Issue("https://github.com/openrewrite/rewrite/issues/3142")
+ void doesNotUseAuthenticationIfCredentialsCannotBeResolved() {
+ var downloader = new MavenPomDownloader(emptyMap(), ctx);
+ var gav = new GroupArtifactVersion("fred", "fred", "1.0.0");
+ try (MockWebServer mockRepo = getMockServer()) {
+ mockRepo.setDispatcher(new Dispatcher() {
+ @Override
+ public MockResponse dispatch(RecordedRequest recordedRequest) {
+ MockResponse response = new MockResponse();
+ if (recordedRequest.getHeaders().get("Authorization") != null) {
+ response.setResponseCode(401);
+ } else if (recordedRequest.getMethod() == null || !recordedRequest.getMethod().equalsIgnoreCase("HEAD")) {
+ response.setBody(
+ //language=xml
+ """
+
+ org.springframework.cloud
+ spring-cloud-dataflow-build
+ 2.10.0-SNAPSHOT
+
+ """);
+ }
+ return response;
+ }
+ });
+ mockRepo.start();
+ var repositories = List.of(MavenRepository.builder()
+ .id("id")
+ .uri("http://%s:%d/maven".formatted(mockRepo.getHostName(), mockRepo.getPort()))
+ .username("${env.ARTIFACTORY_USERNAME}")
+ .password("${env.ARTIFACTORY_USERNAME}")
+ .build());
+
+ assertDoesNotThrow(() -> downloader.download(gav, null, null, repositories));
+ } catch (IOException e) {
+ throw new RuntimeException(e);
+ }
+ }
+ }
}