diff --git a/core/src/main/java/org/wildfly/channel/ChannelImpl.java b/core/src/main/java/org/wildfly/channel/ChannelImpl.java index 190aec45..85eb7027 100644 --- a/core/src/main/java/org/wildfly/channel/ChannelImpl.java +++ b/core/src/main/java/org/wildfly/channel/ChannelImpl.java @@ -101,12 +101,14 @@ void init(MavenVersionsResolver.Factory factory, List channels) { } if (channelDefinition.getBlocklistCoordinate() != null) { - BlocklistCoordinate blocklistCoordinate = channelDefinition.getBlocklistCoordinate(); - resolvedChannelBuilder.setBlocklistCoordinate(blocklistCoordinate); - final List urls = resolver.resolveChannelMetadata(List.of(blocklistCoordinate)); - this.blocklist = urls.stream() - .map(Blocklist::from) - .findFirst(); + BlocklistCoordinate blocklistCoordinate = resolveBlocklistVersion(channelDefinition); + if (blocklistCoordinate != null) { + resolvedChannelBuilder.setBlocklistCoordinate(blocklistCoordinate); + final List urls = resolver.resolveChannelMetadata(List.of(blocklistCoordinate)); + this.blocklist = urls.stream() + .map(Blocklist::from) + .findFirst(); + } } this.resolvedChannel = resolvedChannelBuilder.build(); @@ -193,6 +195,10 @@ Channel getResolvedChannelDefinition() { return resolvedChannel; } + public Blocklist getBlocklist() { + return blocklist.orElse(null); + } + static class ResolveLatestVersionResult { final String version; final ChannelImpl channel; @@ -210,7 +216,7 @@ private Set attemptedRepositories() { 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 we already have a version or it is a URL manifest, return it if (manifestCoordinate.getUrl() != null || manifestCoordinate.getMaven().getVersion() != null) { return manifestCoordinate; } @@ -226,6 +232,7 @@ private ChannelManifestCoordinate resolveManifestVersion(Channel baseDefinition) 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); } @@ -242,7 +249,6 @@ private BlocklistCoordinate resolveBlocklistVersion(Channel baseDefinition) { return blocklistCoordinate; } - final Set allVersions = resolver.getAllVersions( blocklistCoordinate.getGroupId(), blocklistCoordinate.getArtifactId(), @@ -250,12 +256,12 @@ private BlocklistCoordinate resolveBlocklistVersion(Channel baseDefinition) { blocklistCoordinate.getClassifier() ); Optional 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); + // different from manifest resolution. If we were not able to resolve the blocklist, we assume it doesn't exist (yet) and + // we proceed without blocklist + return latestVersion + .map(v->new BlocklistCoordinate(blocklistCoordinate.getGroupId(), blocklistCoordinate.getArtifactId(), v)) + .orElse(null); } private ChannelManifest resolveManifest(ChannelManifestCoordinate manifestCoordinate) throws UnresolvedMavenArtifactException { diff --git a/core/src/main/java/org/wildfly/channel/ChannelSession.java b/core/src/main/java/org/wildfly/channel/ChannelSession.java index 689c50b1..d8d95b7a 100644 --- a/core/src/main/java/org/wildfly/channel/ChannelSession.java +++ b/core/src/main/java/org/wildfly/channel/ChannelSession.java @@ -94,11 +94,11 @@ public ChannelSession(List channelDefinitions, MavenVersionsResolver.Fa * 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 + * @return List of {@code RuntimeChannel}s used to resolve artifacts by this session */ - public List getResolvedChannelDefinitions() { + public List getRuntimeChannels() { return this.channels.stream() - .map(ChannelImpl::getResolvedChannelDefinition) + .map(c->new RuntimeChannel(c.getResolvedChannelDefinition(), c.getManifest(), c.getBlocklist())) .collect(Collectors.toList()); } diff --git a/core/src/main/java/org/wildfly/channel/RuntimeChannel.java b/core/src/main/java/org/wildfly/channel/RuntimeChannel.java new file mode 100644 index 00000000..1a63df80 --- /dev/null +++ b/core/src/main/java/org/wildfly/channel/RuntimeChannel.java @@ -0,0 +1,58 @@ +/* + * Copyright 2024 Red Hat, Inc. and/or its affiliates + * and other contributors as indicated by the @author tags. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.wildfly.channel; + +import java.util.Objects; + +public class RuntimeChannel { + + private final Channel channel; + private final ChannelManifest channelManifest; + private final Blocklist blocklist; + + public RuntimeChannel(Channel channel, ChannelManifest channelManifest, Blocklist blocklist) { + this.channel = channel; + this.channelManifest = channelManifest; + this.blocklist = blocklist; + } + + public Channel getChannelDefinition() { + return channel; + } + + public ChannelManifest getChannelManifest() { + return channelManifest; + } + + public Blocklist getChannelBlocklist() { + return blocklist; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + RuntimeChannel that = (RuntimeChannel) o; + return Objects.equals(channel, that.channel) && Objects.equals(channelManifest, that.channelManifest) && Objects.equals(blocklist, that.blocklist); + } + + @Override + public int hashCode() { + return Objects.hash(channel, channelManifest, blocklist); + } +} diff --git a/core/src/test/java/org/wildfly/channel/ChannelSessionInitTestCase.java b/core/src/test/java/org/wildfly/channel/ChannelSessionInitTestCase.java index 0da5698b..3f1a8d9a 100644 --- a/core/src/test/java/org/wildfly/channel/ChannelSessionInitTestCase.java +++ b/core/src/test/java/org/wildfly/channel/ChannelSessionInitTestCase.java @@ -380,7 +380,8 @@ public void getVersionOfResolvedManifest() throws Exception { .setManifestCoordinate("test.channels", "base-manifest") .build()); try (ChannelSession channelSession = new ChannelSession(channels, factory)) { - assertThat(channelSession.getResolvedChannelDefinitions()) + assertThat(channelSession.getRuntimeChannels()) + .map(RuntimeChannel::getChannelDefinition) .map(Channel::getManifestCoordinate) .map(ChannelManifestCoordinate::getVersion) .containsOnly("1.0.0"); @@ -388,6 +389,35 @@ public void getVersionOfResolvedManifest() throws Exception { } } + @Test + public void getVersionOfResolvedBlocklist() 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", "blocklist", BlocklistCoordinate.EXTENSION, BlocklistCoordinate.CLASSIFIER)) + .thenReturn(Set.of("1.0.0")); + + final List channels = List.of(new Channel.Builder() + .setName("channel one") + .addRepository("test", "test") + .setManifestCoordinate("test.channels", "base-manifest", "1.0.0") + .setBlocklistCoordinate(new BlocklistCoordinate("test.channels", "blocklist")) + .build()); + try (ChannelSession channelSession = new ChannelSession(channels, factory)) { + assertThat(channelSession.getRuntimeChannels()) + .map(RuntimeChannel::getChannelDefinition) + .map(Channel::getBlocklistCoordinate) + .map(BlocklistCoordinate::getVersion) + .containsOnly("1.0.0"); + + } + } + private void mockManifest(MavenVersionsResolver resolver, ChannelManifest manifest, String gav) throws IOException { mockManifest(resolver, ChannelManifestMapper.toYaml(manifest), gav); } diff --git a/core/src/test/java/org/wildfly/channel/ChannelWithBlocklistTestCase.java b/core/src/test/java/org/wildfly/channel/ChannelWithBlocklistTestCase.java index be0d3aed..4a0a2c39 100644 --- a/core/src/test/java/org/wildfly/channel/ChannelWithBlocklistTestCase.java +++ b/core/src/test/java/org/wildfly/channel/ChannelWithBlocklistTestCase.java @@ -83,8 +83,7 @@ public void testFindLatestMavenArtifactVersion() throws Exception { when(resolver.resolveChannelMetadata(List.of(new ChannelManifestCoordinate("test", "test.manifest", "1.0.0")))) .thenReturn(List.of(tempDir.resolve("manifest.yaml").toUri().toURL())); - when(resolver.resolveChannelMetadata(List.of(new BlocklistCoordinate("org.wildfly", "wildfly-blocklist")))) - .thenReturn(List.of(this.getClass().getClassLoader().getResource("channels/test-blocklist.yaml"))); + mockBlocklistResolution(resolver, "channels/test-blocklist.yaml"); when(factory.create(any())).thenReturn(resolver); when(resolver.getAllVersions("org.wildfly", "wildfly-ee-galleon-pack", null, null)) @@ -177,8 +176,7 @@ public void testFindLatestMavenArtifactVersionWithWildcardBlocklist() throws Exc when(resolver.resolveChannelMetadata(List.of(new ChannelManifestCoordinate("test", "test.manifest", "1.0.0")))) .thenReturn(List.of(tempDir.resolve("manifest.yaml").toUri().toURL())); - when(resolver.resolveChannelMetadata(List.of(new BlocklistCoordinate("org.wildfly", "wildfly-blocklist")))) - .thenReturn(List.of(this.getClass().getClassLoader().getResource("channels/test-blocklist-with-wildcards.yaml"))); + mockBlocklistResolution(resolver, "channels/test-blocklist-with-wildcards.yaml"); when(factory.create(any())).thenReturn(resolver); when(resolver.getAllVersions("org.wildfly", "wildfly-ee-galleon-pack", null, null)) @@ -223,8 +221,7 @@ public void testFindLatestMavenArtifactVersionBlocklistsAllVersionsException() t when(resolver.resolveChannelMetadata(List.of(new ChannelManifestCoordinate("test", "test.manifest", "1.0.0")))) .thenReturn(List.of(tempDir.resolve("manifest.yaml").toUri().toURL())); - when(resolver.resolveChannelMetadata(List.of(new BlocklistCoordinate("org.wildfly", "wildfly-blocklist")))) - .thenReturn(List.of(this.getClass().getClassLoader().getResource("channels/test-blocklist.yaml"))); + mockBlocklistResolution(resolver, "channels/test-blocklist.yaml"); when(factory.create(any())).thenReturn(resolver); when(resolver.getAllVersions("org.wildfly", "wildfly-ee-galleon-pack", null, null)).thenReturn(new HashSet<>(singleton("25.0.1.Final"))); @@ -272,8 +269,7 @@ public void testResolveLatestMavenArtifact() throws Exception { when(resolver.resolveChannelMetadata(List.of(new ChannelManifestCoordinate("test", "test.manifest", "1.0.0")))) .thenReturn(List.of(tempDir.resolve("manifest.yaml").toUri().toURL())); - when(resolver.resolveChannelMetadata(List.of(new BlocklistCoordinate("org.wildfly", "wildfly-blocklist")))) - .thenReturn(List.of(this.getClass().getClassLoader().getResource("channels/test-blocklist.yaml"))); + mockBlocklistResolution(resolver, "channels/test-blocklist.yaml"); File resolvedArtifactFile = mock(File.class); @@ -328,8 +324,7 @@ public void testResolveLatestMavenArtifactThrowUnresolvedMavenArtifactException( when(resolver.resolveChannelMetadata(List.of(new ChannelManifestCoordinate("test", "test.manifest", "1.0.0")))) .thenReturn(List.of(tempDir.resolve("manifest.yaml").toUri().toURL())); - when(resolver.resolveChannelMetadata(List.of(new BlocklistCoordinate("org.wildfly", "wildfly-blocklist")))) - .thenReturn(List.of(this.getClass().getClassLoader().getResource("channels/test-blocklist.yaml"))); + mockBlocklistResolution(resolver, "channels/test-blocklist.yaml"); when(factory.create(any())).thenReturn(resolver); when(resolver.getAllVersions("org.wildfly", "wildfly-ee-galleon-pack", null, null)).thenReturn(new HashSet<>(Set.of("25.0.1.Final","26.0.0.Final"))); @@ -346,6 +341,13 @@ public void testResolveLatestMavenArtifactThrowUnresolvedMavenArtifactException( verify(resolver, times(2)).close(); } + private void mockBlocklistResolution(MavenVersionsResolver resolver, String fileName) { + when(resolver.getAllVersions("org.wildfly", "wildfly-blocklist", BlocklistCoordinate.EXTENSION, BlocklistCoordinate.CLASSIFIER)) + .thenReturn(Set.of("1.0.0")); + when(resolver.resolveChannelMetadata(List.of(new BlocklistCoordinate("org.wildfly", "wildfly-blocklist", "1.0.0")))) + .thenReturn(List.of(this.getClass().getClassLoader().getResource(fileName))); + } + @Test public void testResolveMavenArtifactsFromOneChannel() throws Exception { List channels = ChannelMapper.fromString( @@ -380,8 +382,7 @@ public void testResolveMavenArtifactsFromOneChannel() throws Exception { when(resolver.resolveChannelMetadata(List.of(new ChannelManifestCoordinate("test", "test.manifest", "1.0.0")))) .thenReturn(List.of(tempDir.resolve("manifest.yaml").toUri().toURL())); - when(resolver.resolveChannelMetadata(List.of(new BlocklistCoordinate("org.wildfly", "wildfly-blocklist")))) - .thenReturn(List.of(this.getClass().getClassLoader().getResource("channels/test-blocklist.yaml"))); + mockBlocklistResolution(resolver, "channels/test-blocklist.yaml"); File resolvedArtifactFile1 = mock(File.class); File resolvedArtifactFile2 = mock(File.class); @@ -502,8 +503,7 @@ public void testChannelWithInvalidBlacklist() throws Exception { when(resolver.resolveChannelMetadata(List.of(new ChannelManifestCoordinate("test", "test.manifest", "1.0.0")))) .thenReturn(List.of(tempDir.resolve("manifest.yaml").toUri().toURL())); - when(resolver.resolveChannelMetadata(List.of(new BlocklistCoordinate("org.wildfly", "wildfly-blocklist")))) - .thenReturn(List.of(this.getClass().getClassLoader().getResource("channels/invalid-blocklist.yaml"))); + mockBlocklistResolution(resolver, "channels/invalid-blocklist.yaml"); when(factory.create(any())).thenReturn(resolver);