Skip to content

Commit

Permalink
Improve maven ResolutionEventListener with new event for repository d…
Browse files Browse the repository at this point in the history
…iscovery, additional information when downloads fail
  • Loading branch information
sambsnyd committed Jan 17, 2024
1 parent 888f51a commit 7041060
Show file tree
Hide file tree
Showing 4 changed files with 81 additions and 54 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@
import java.util.regex.Pattern;
import java.util.stream.Stream;

import static java.util.Collections.emptyList;
import static java.util.Collections.emptyMap;
import static java.util.Objects.requireNonNull;
import static java.util.stream.Collectors.toList;
Expand Down Expand Up @@ -223,10 +224,13 @@ public MavenMetadata downloadMetadata(GroupArtifactVersion gav, @Nullable Resolv
MavenMetadata mavenMetadata = null;
Collection<MavenRepository> normalizedRepos = distinctNormalizedRepositories(repositories, containingPom, null);
Map<MavenRepository, String> repositoryResponses = new LinkedHashMap<>();
List<String> attemptedUris = new ArrayList<>(normalizedRepos.size());
for (MavenRepository repo : normalizedRepos) {
ctx.getResolutionListener().repository(repo, containingPom);
if (gav.getVersion() != null && !repositoryAcceptsVersion(repo, gav.getVersion(), containingPom)) {
continue;
}
attemptedUris.add(repo.getUri());
Optional<MavenMetadata> result = mavenCache.getMavenMetadata(URI.create(repo.getUri()), gav);
if (result == null) {
// Not in the cache, attempt to download it.
Expand Down Expand Up @@ -298,6 +302,7 @@ public MavenMetadata downloadMetadata(GroupArtifactVersion gav, @Nullable Resolv

if (mavenMetadata == null) {
sample.stop(timer.tags("outcome", "unavailable").register(Metrics.globalRegistry));
ctx.getResolutionListener().downloadError(gav, attemptedUris, null);
throw new MavenDownloadingException("Unable to download metadata.", null, gav)
.setRepositoryResponses(repositoryResponses);
}
Expand Down Expand Up @@ -447,7 +452,7 @@ public Pom download(GroupArtifactVersion gav,
List<MavenRepository> repositories) throws MavenDownloadingException {
if (gav.getGroupId() == null || gav.getArtifactId() == null || gav.getVersion() == null) {
if (containingPom != null) {
ctx.getResolutionListener().downloadError(gav, containingPom.getRequested());
ctx.getResolutionListener().downloadError(gav, emptyList(), containingPom.getRequested());
}
throw new MavenDownloadingException("Group id, artifact id, or version are missing.", null, gav);
}
Expand Down Expand Up @@ -495,8 +500,9 @@ public Pom download(GroupArtifactVersion gav,
String versionMaybeDatedSnapshot = datedSnapshotVersion(gav, containingPom, repositories, ctx);
GroupArtifactVersion originalGav = gav;
gav = handleSnapshotTimestampVersion(gav);

List<String> uris = new ArrayList<>();
for (MavenRepository repo : normalizedRepos) {
ctx.getResolutionListener().repository(repo, containingPom);
//noinspection DataFlowIssue
if (!repositoryAcceptsVersion(repo, gav.getVersion(), containingPom)) {
continue;
Expand All @@ -505,13 +511,14 @@ public Pom download(GroupArtifactVersion gav,
ResolvedGroupArtifactVersion resolvedGav = new ResolvedGroupArtifactVersion(
repo.getUri(), gav.getGroupId(), gav.getArtifactId(), gav.getVersion(), versionMaybeDatedSnapshot);
Optional<Pom> result = mavenCache.getPom(resolvedGav);

if (result == null) {
URI uri = URI.create(repo.getUri() + (repo.getUri().endsWith("/") ? "" : "/") +
requireNonNull(gav.getGroupId()).replace('.', '/') + '/' +
gav.getArtifactId() + '/' +
gav.getVersion() + '/' +
gav.getArtifactId() + '-' + versionMaybeDatedSnapshot + ".pom");

uris.add(uri.toString());
if ("file".equals(uri.getScheme())) {
Path inputPath = Paths.get(gav.getGroupId(), gav.getArtifactId(), gav.getVersion());

Expand Down Expand Up @@ -571,6 +578,7 @@ public Pom download(GroupArtifactVersion gav,
return pom;
} catch (HttpSenderResponseException e) {
repositoryResponses.put(repo, e.getMessage());
ctx.getResolutionListener().downloadError(gav, uris, (containingPom == null) ? null : containingPom.getRequested());
if (e.isClientSideException()) {
//If the exception is a common, client-side exception, cache an empty result.
mavenCache.putPom(resolvedGav, null);
Expand All @@ -586,10 +594,6 @@ public Pom download(GroupArtifactVersion gav,
}

sample.stop(timer.tags("outcome", "unavailable").register(Metrics.globalRegistry));
if (containingPom != null) {
ctx.getResolutionListener().downloadError(originalGav, containingPom.getRequested());
}

throw new MavenDownloadingException("Unable to download POM.", null, originalGav)
.setRepositoryResponses(repositoryResponses);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -121,11 +121,13 @@ public void dependencyManagement(ManagedDependency dependencyManagement, Pom con
}

@Override
public void downloadError(GroupArtifactVersion gav, Pom containing) {
public void downloadError(GroupArtifactVersion gav, List<String> attemptedUris, @Nullable Pom containing) {
Link link = to(gavNode(gav).add(Style.FILLED, Color.rgb("ff1947")))
.with(Label.of("error"));
gavNode(containing.getGav())
.addLink(link);
if(containing != null) {
gavNode(containing.getGav())
.addLink(link);
}
}

@Override
Expand All @@ -142,6 +144,7 @@ public void bomImport(ResolvedGroupArtifactVersion gav, Pom containing) {
gavNode(containing.getGav()).addLink(link);
}

@SuppressWarnings("unused")
public Graphviz graphviz() {
return Graphviz.fromGraph(g);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,50 +17,37 @@

import org.openrewrite.internal.lang.Nullable;

public interface ResolutionEventListener {
ResolutionEventListener NOOP = new ResolutionEventListener() {
@Override
public void downloadError(GroupArtifactVersion gav, Pom containing) {
}

@Override
public void parent(Pom parent, Pom containing) {
}

@Override
public void dependency(Scope scope, ResolvedDependency resolvedDependency, ResolvedPom containing) {
}

@Override
public void bomImport(ResolvedGroupArtifactVersion gav, Pom containing) {
}

@Override
public void property(String key, String value, Pom containing) {
}
import java.util.List;

@Override
public void dependencyManagement(ManagedDependency dependencyManagement, Pom containing) {
}

@Override
public void clear() {
}

@Override
public void downloadSuccess(ResolvedGroupArtifactVersion gav, @Nullable ResolvedPom containing) {
}
};
@SuppressWarnings("unused")
public interface ResolutionEventListener {
ResolutionEventListener NOOP = new ResolutionEventListener() {};

void clear();
default void clear() {
}

default void downloadSuccess(ResolvedGroupArtifactVersion gav, @Nullable ResolvedPom containing) {
}

void downloadError(GroupArtifactVersion gav, Pom containing);
void parent(Pom parent, Pom containing);
void dependency(Scope scope, ResolvedDependency resolvedDependency, ResolvedPom containing);
void bomImport(ResolvedGroupArtifactVersion gav, Pom containing);
void property(String key, String value, Pom containing);
void dependencyManagement(ManagedDependency dependencyManagement, Pom containing);
/**
*
* @param gav - GAV coordinate of the dependency which failed to download
* @param attemptedUris - The URIs which were attempted, in the order they were attempted, before resolution was determined to have failed
* @param containing - The pom containing the dependency which failed to resolve, if resolution was attempted from such a context
*/
default void downloadError(GroupArtifactVersion gav, List<String> attemptedUris, @Nullable Pom containing) {
}
default void parent(Pom parent, Pom containing) {
}
default void dependency(Scope scope, ResolvedDependency resolvedDependency, ResolvedPom containing) {
}
default void bomImport(ResolvedGroupArtifactVersion gav, Pom containing) {
}
default void property(String key, String value, Pom containing) {
}
default void dependencyManagement(ManagedDependency dependencyManagement, Pom containing) {
}

default void repository(MavenRepository mavenRepository, @Nullable ResolvedPom containing) {
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -25,16 +25,14 @@
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.ValueSource;
import org.openrewrite.*;
import org.openrewrite.internal.lang.Nullable;
import org.openrewrite.ipc.http.HttpSender;
import org.openrewrite.ipc.http.HttpUrlConnectionSender;
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.GroupArtifact;
import org.openrewrite.maven.tree.GroupArtifactVersion;
import org.openrewrite.maven.tree.MavenMetadata;
import org.openrewrite.maven.tree.MavenRepository;
import org.openrewrite.maven.tree.*;

import java.io.ByteArrayInputStream;
import java.io.IOException;
Expand Down Expand Up @@ -118,6 +116,41 @@ void centralIdOverridesDefaultRepository() {
"URI https://internalartifactrepository.yourorg.com"));
}

@Test
void listenerRecordsAttemptedUris() {
var ctx = MavenExecutionContextView.view(new InMemoryExecutionContext());
// Avoid actually trying to reach the made-up https://internalartifactrepository.yourorg.com
for (MavenRepository repository : ctx.getRepositories()) {
repository.setKnownToExist(true);
}

MavenRepository nonexistentRepo = new MavenRepository("repo", "http://internalartifactrepository.yourorg.com", null, null, true, null, null, null);
List<String> attemptedUris = new ArrayList<>();
List<MavenRepository> discoveredRepositories = new ArrayList<>();
ctx.setResolutionListener(new ResolutionEventListener() {
@Override
public void downloadError(GroupArtifactVersion gav, List<String> uris, @Nullable Pom containing) {
attemptedUris.addAll(uris);
}

@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, Collections.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);
}

@Disabled("Flaky on CI")
@Test
void normalizeOssSnapshots() {
Expand Down

0 comments on commit 7041060

Please sign in to comment.