Skip to content

Commit

Permalink
[#292] During channel initialisation the version of resolved manifest…
Browse files Browse the repository at this point in the history
… is made available
  • Loading branch information
spyrkob committed Oct 3, 2024
1 parent 4c6b7bb commit c06cdfe
Show file tree
Hide file tree
Showing 4 changed files with 149 additions and 19 deletions.
95 changes: 88 additions & 7 deletions core/src/main/java/org/wildfly/channel/ChannelImpl.java
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
*/
package org.wildfly.channel;

import static java.util.Collections.singleton;
import static java.util.Objects.requireNonNull;
import static org.wildfly.channel.version.VersionMatcher.COMPARATOR;

Expand All @@ -24,6 +25,7 @@
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Optional;
Expand All @@ -41,7 +43,8 @@ class ChannelImpl implements AutoCloseable {

private static final Logger LOG = Logger.getLogger(ChannelImpl.class);

private Channel channelDefinition;
private final Channel channelDefinition;
private Channel resolvedChannel;

private List<ChannelImpl> requiredChannels = Collections.emptyList();

Expand All @@ -53,6 +56,7 @@ class ChannelImpl implements AutoCloseable {
private boolean dependency = false;

public Optional<Blocklist> blocklist = Optional.empty();
private ChannelManifestCoordinate resolvedCoordinate;

public ChannelManifest getManifest() {
return channelManifest;
Expand All @@ -78,8 +82,11 @@ void init(MavenVersionsResolver.Factory factory, List<ChannelImpl> channels) {

resolver = factory.create(channelDefinition.getRepositories());

final Channel.Builder resolvedChannelBuilder = new Channel.Builder(channelDefinition);
if (channelDefinition.getManifestCoordinate() != null) {
channelManifest = resolveManifest(channelDefinition.getManifestCoordinate());
final ChannelManifestCoordinate coordinate = resolveManifestVersion(channelDefinition);
resolvedChannelBuilder.setManifestCoordinate(coordinate);
channelManifest = resolveManifest(coordinate);
} else {
channelManifest = new ChannelManifest(null, null, null, Collections.emptyList());
}
Expand All @@ -95,11 +102,14 @@ void init(MavenVersionsResolver.Factory factory, List<ChannelImpl> channels) {

if (channelDefinition.getBlocklistCoordinate() != null) {
BlocklistCoordinate blocklistCoordinate = channelDefinition.getBlocklistCoordinate();
resolvedChannelBuilder.setBlocklistCoordinate(blocklistCoordinate);
final List<URL> urls = resolver.resolveChannelMetadata(List.of(blocklistCoordinate));
this.blocklist = urls.stream()
.map(Blocklist::from)
.findFirst();
}

this.resolvedChannel = resolvedChannelBuilder.build();
}

private ChannelImpl findRequiredChannel(MavenVersionsResolver.Factory factory, List<ChannelImpl> channels, ManifestRequirement manifestRequirement) {
Expand Down Expand Up @@ -179,8 +189,8 @@ boolean isDependency() {
return dependency;
}

Channel getChannelDefinition() {
return channelDefinition;
Channel getResolvedChannelDefinition() {
return resolvedChannel;
}

static class ResolveLatestVersionResult {
Expand All @@ -193,8 +203,79 @@ static class ResolveLatestVersionResult {
}
}

private Set<Repository> attemptedRepositories() {
return new HashSet<>(channelDefinition.getRepositories());
}

private ChannelManifestCoordinate resolveManifestVersion(Channel baseDefinition) {
final ChannelManifestCoordinate manifestCoordinate = baseDefinition.getManifestCoordinate();

// if we already have a version or it is a URL blocklist, return it
if (manifestCoordinate.getUrl() != null || manifestCoordinate.getMaven().getVersion() != null) {
return manifestCoordinate;
}

final Set<String> allVersions = resolver.getAllVersions(
manifestCoordinate.getGroupId(),
manifestCoordinate.getArtifactId(),
manifestCoordinate.getExtension(),
manifestCoordinate.getClassifier()
);
Optional<String> latestVersion = VersionMatcher.getLatestVersion(allVersions);
String version = latestVersion.orElseThrow(() ->
new ArtifactTransferException(String.format("Unable to resolve the latest version of channel metadata %s:%s", manifestCoordinate.getGroupId(), manifestCoordinate.getArtifactId()),
singleton(new ArtifactCoordinate(manifestCoordinate.getGroupId(), manifestCoordinate.getArtifactId(), manifestCoordinate.getExtension(), manifestCoordinate.getClassifier(), "")),
attemptedRepositories()));
return new ChannelManifestCoordinate(manifestCoordinate.getGroupId(), manifestCoordinate.getArtifactId(), version);

}

private BlocklistCoordinate resolveBlocklistVersion(Channel baseDefinition) {
final BlocklistCoordinate blocklistCoordinate = baseDefinition.getBlocklistCoordinate();

if (blocklistCoordinate == null) {
return null;
}

// if we already have a version or it is a URL blocklist, return it
if (blocklistCoordinate.getUrl() != null || blocklistCoordinate.getMaven().getVersion() != null) {
return blocklistCoordinate;
}


final Set<String> allVersions = resolver.getAllVersions(
blocklistCoordinate.getGroupId(),
blocklistCoordinate.getArtifactId(),
blocklistCoordinate.getExtension(),
blocklistCoordinate.getClassifier()
);
Optional<String> latestVersion = VersionMatcher.getLatestVersion(allVersions);
String version = latestVersion.orElseThrow(() ->
new ArtifactTransferException(String.format("Unable to resolve the latest version of channel metadata %s:%s", blocklistCoordinate.getGroupId(), blocklistCoordinate.getArtifactId()),
singleton(new ArtifactCoordinate(blocklistCoordinate.getGroupId(), blocklistCoordinate.getArtifactId(), blocklistCoordinate.getExtension(), blocklistCoordinate.getClassifier(), "")),
attemptedRepositories()));
return new BlocklistCoordinate(blocklistCoordinate.getGroupId(), blocklistCoordinate.getArtifactId(), version);

}

private ChannelManifest resolveManifest(ChannelManifestCoordinate manifestCoordinate) throws UnresolvedMavenArtifactException {
return resolver.resolveChannelMetadata(List.of(manifestCoordinate))
if (manifestCoordinate.getUrl() == null && manifestCoordinate.getMaven().getVersion() == null) {
final Set<String> allVersions = resolver.getAllVersions(
manifestCoordinate.getGroupId(),
manifestCoordinate.getArtifactId(),
manifestCoordinate.getExtension(),
manifestCoordinate.getClassifier()
);
Optional<String> latestVersion = VersionMatcher.getLatestVersion(allVersions);
String version = latestVersion.orElseThrow(() ->
new ArtifactTransferException(String.format("Unable to resolve the latest version of channel metadata %s:%s", manifestCoordinate.getGroupId(), manifestCoordinate.getArtifactId()),
singleton(new ArtifactCoordinate(manifestCoordinate.getGroupId(), manifestCoordinate.getArtifactId(), manifestCoordinate.getExtension(), manifestCoordinate.getClassifier(), "")),
attemptedRepositories()));
resolvedCoordinate = new ChannelManifestCoordinate(manifestCoordinate.getGroupId(), manifestCoordinate.getArtifactId(), version);
} else {
resolvedCoordinate = manifestCoordinate;
}
return resolver.resolveChannelMetadata(List.of(resolvedCoordinate))
.stream()
.map(ChannelManifestMapper::from)
.findFirst().orElseThrow();
Expand Down Expand Up @@ -248,7 +329,7 @@ Optional<ResolveLatestVersionResult> resolveLatestVersion(String groupId, String
return Optional.of(new ResolveLatestVersionResult(latestMetadataVersion, this));
} catch (NoStreamFoundException e) {
LOG.debugf(e, "Metadata resolution for %s:%s failed in channel %s",
groupId, artifactId, this.getChannelDefinition().getName());
groupId, artifactId, this.getResolvedChannelDefinition().getName());
return Optional.empty();
}
case MAVEN_RELEASE:
Expand All @@ -260,7 +341,7 @@ Optional<ResolveLatestVersionResult> resolveLatestVersion(String groupId, String
return Optional.of(new ResolveLatestVersionResult(releaseMetadataVersion, this));
} catch (NoStreamFoundException e) {
LOG.debugf(e, "Metadata resolution for %s:%s failed in channel %s",
groupId, artifactId, this.getChannelDefinition().getName());
groupId, artifactId, this.getResolvedChannelDefinition().getName());
return Optional.empty();
}
default:
Expand Down
20 changes: 16 additions & 4 deletions core/src/main/java/org/wildfly/channel/ChannelSession.java
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,18 @@ public ChannelSession(List<Channel> channelDefinitions, MavenVersionsResolver.Fa
validateNoDuplicatedManifests();
}

/**
* Get the definitions of channels used by this session. Returned version contains resolved versions
* of channel metadata (if applicable).
*
* @return List of {@code Channel}s used to resolve artifacts by this session
*/
public List<Channel> getResolvedChannelDefinitions() {
return this.channels.stream()
.map(ChannelImpl::getResolvedChannelDefinition)
.collect(Collectors.toList());
}

/**
* Resolve the Maven artifact according to the session's channels.
* <p>
Expand Down Expand Up @@ -121,7 +133,7 @@ public MavenArtifact resolveMavenArtifact(String groupId, String artifactId, Str

ChannelImpl.ResolveArtifactResult artifact = channel.resolveArtifact(groupId, artifactId, extension, classifier, latestVersion);
recorder.recordStream(groupId, artifactId, latestVersion);
return new MavenArtifact(groupId, artifactId, extension, classifier, latestVersion, artifact.file, artifact.channel.getChannelDefinition().getName());
return new MavenArtifact(groupId, artifactId, extension, classifier, latestVersion, artifact.file, artifact.channel.getResolvedChannelDefinition().getName());
}

/**
Expand Down Expand Up @@ -153,7 +165,7 @@ public List<MavenArtifact> resolveMavenArtifacts(List<ArtifactCoordinate> coordi
final MavenArtifact resolvedArtifact = new MavenArtifact(request.getGroupId(), request.getArtifactId(),
request.getExtension(), request.getClassifier(), request.getVersion(),
resolveArtifactResults.get(i).file,
resolveArtifactResults.get(i).channel.getChannelDefinition().getName());
resolveArtifactResults.get(i).channel.getResolvedChannelDefinition().getName());

recorder.recordStream(resolvedArtifact.getGroupId(), resolvedArtifact.getArtifactId(), resolvedArtifact.getVersion());
res.add(resolvedArtifact);
Expand Down Expand Up @@ -227,7 +239,7 @@ public List<MavenArtifact> resolveDirectMavenArtifacts(List<ArtifactCoordinate>
*/
public VersionResult findLatestMavenArtifactVersion(String groupId, String artifactId, String extension, String classifier, String baseVersion) throws NoStreamFoundException {
final ChannelImpl.ResolveLatestVersionResult channelWithLatestVersion = findChannelWithLatestVersion(groupId, artifactId, extension, classifier, baseVersion);
return new VersionResult(channelWithLatestVersion.version, channelWithLatestVersion.channel.getChannelDefinition().getName());
return new VersionResult(channelWithLatestVersion.version, channelWithLatestVersion.channel.getResolvedChannelDefinition().getName());
}

@Override
Expand Down Expand Up @@ -274,7 +286,7 @@ private ChannelImpl.ResolveLatestVersionResult findChannelWithLatestVersion(Stri
return foundVersions.get(foundLatestVersionInChannels.orElseThrow(() -> {
final ArtifactCoordinate coord = new ArtifactCoordinate(groupId, artifactId, extension, classifier, "");
final Set<Repository> repositories = channels.stream()
.map(ChannelImpl::getChannelDefinition)
.map(ChannelImpl::getResolvedChannelDefinition)
.flatMap(d -> d.getRepositories().stream())
.collect(Collectors.toSet());
throw new NoStreamFoundException(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,9 @@
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.List;
import java.util.Set;

import static org.assertj.core.api.Assertions.assertThat;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertNull;
Expand Down Expand Up @@ -359,6 +361,33 @@ public void duplicatedManifestIDsAreDetected() throws Exception {
assertThrows(RuntimeException.class, () -> new ChannelSession(channels, factory));
}

@Test
public void getVersionOfResolvedManifest() throws Exception {
final MavenVersionsResolver.Factory factory = mock(MavenVersionsResolver.Factory.class);
MavenVersionsResolver resolver = mock(MavenVersionsResolver.class);
when(factory.create(any())).thenReturn(resolver);

final ChannelManifest requiredManifest = new ManifestBuilder()
.setId("manifest-one")
.build();
mockManifest(resolver, requiredManifest, "test.channels:base-manifest:1.0.0");
when(resolver.getAllVersions("test.channels", "base-manifest", ChannelManifest.EXTENSION, ChannelManifest.CLASSIFIER))
.thenReturn(Set.of("1.0.0"));

final List<Channel> channels = List.of(new Channel.Builder()
.setName("channel one")
.addRepository("test", "test")
.setManifestCoordinate("test.channels", "base-manifest")
.build());
try (ChannelSession channelSession = new ChannelSession(channels, factory)) {
assertThat(channelSession.getResolvedChannelDefinitions())
.map(Channel::getManifestCoordinate)
.map(ChannelManifestCoordinate::getVersion)
.containsOnly("1.0.0");

}
}

private void mockManifest(MavenVersionsResolver resolver, ChannelManifest manifest, String gav) throws IOException {
mockManifest(resolver, ChannelManifestMapper.toYaml(manifest), gav);
}
Expand Down
Loading

0 comments on commit c06cdfe

Please sign in to comment.