Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Make sure projects based on non-recommended platform versions can still list relevant extensions #19430

Merged
merged 1 commit into from
Aug 17, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -572,7 +572,7 @@ private static void persistPlatformCatalog(PlatformCatalog catalog, Path dir) {
}
}

static Path getRegistryMemberCatalogPath(Path registryDir, ArtifactCoords bom) {
public static Path getRegistryMemberCatalogPath(Path registryDir, ArtifactCoords bom) {
return getMemberCatalogPath(registryDir.resolve("members"), bom);
}

Expand Down Expand Up @@ -605,7 +605,7 @@ static Path getRegistryDescriptorPath(Path registryDir) {
return registryDir.resolve("config.json");
}

static Path getRegistryDir(Path baseDir, String registryId) {
public static Path getRegistryDir(Path baseDir, String registryId) {
return baseDir.resolve(registryId);
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
package io.quarkus.devtools.project.create;

import static org.assertj.core.api.Assertions.assertThat;

import io.quarkus.bootstrap.resolver.maven.workspace.ModelUtils;
import io.quarkus.devtools.testing.registry.client.TestRegistryClientBuilder;
import io.quarkus.maven.ArtifactCoords;
import io.quarkus.registry.ExtensionCatalogResolver;
import io.quarkus.registry.catalog.ExtensionCatalog;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.Collections;
import java.util.stream.Collectors;
import org.apache.maven.model.Dependency;
import org.apache.maven.model.Model;
import org.assertj.core.util.Arrays;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;

public class ExtensionCatalogFromProvidedPlatformsTest extends MultiplePlatformBomsTestBase {

private static final String MAIN_PLATFORM_KEY = "org.acme.platform";

@BeforeAll
public static void setup() throws Exception {
TestRegistryClientBuilder.newInstance()
//.debug()
.baseDir(configDir())
// registry
.newRegistry("registry.acme.org")
// platform key
.newPlatform(MAIN_PLATFORM_KEY)
// 2.0 STREAM
.newStream("2.0")
// 2.0.4 release
.newRelease("2.0.4")
.quarkusVersion("2.2.2")
// default bom including quarkus-core + essential metadata
.addCoreMember()
// foo platform member
.newMember("acme-foo-bom").addExtension("acme-foo").release()
.stream().platform()
// 1.0 STREAM
.newStream("1.0")
// 1.0.1 release
.newRelease("1.0.1")
.quarkusVersion("1.1.2")
.addCoreMember()
.newMember("acme-foo-bom").addExtension("acme-foo").release()
.newMember("acme-baz-bom").addExtension("acme-baz").release()
.registry()
.newNonPlatformCatalog("1.1.2")
.addExtension("org.acme", "acme-quarkus-other", "5.5.5")
.registry()
.clientBuilder()
.build();

enableRegistryClient();

// install 1.0.0 version which is not recommended by the registry any more
installNotRecommendedVersion("1.0.1", "1.0.0", "acme-foo-bom");
installNotRecommendedVersion("1.0.1", "1.0.0", "acme-baz-bom");
installNotRecommendedVersion("1.0.1", "1.0.0", "quarkus-bom");
}

private static void installNotRecommendedVersion(String baseRecommendedVersion, String nonRecommendedVersion,
String memberArtifactId) throws IOException {
Path repoDir = TestRegistryClientBuilder.getMavenRepoDir(configDir());
Path p = repoDir;
for (String s : MAIN_PLATFORM_KEY.split("\\.")) {
p = p.resolve(s);
}
final Path groupIdDir = p;

p = groupIdDir.resolve(memberArtifactId).resolve(baseRecommendedVersion)
.resolve(memberArtifactId + "-" + baseRecommendedVersion + ".pom");
final Model model = ModelUtils.readModel(p);
model.setVersion(nonRecommendedVersion);
for (Dependency d : model.getDependencyManagement().getDependencies()) {
if (baseRecommendedVersion.equals(d.getVersion())) {
d.setVersion(nonRecommendedVersion);
}
}
p = p.getParent().getParent().resolve(nonRecommendedVersion)
.resolve(memberArtifactId + "-" + nonRecommendedVersion + ".pom");
Files.createDirectories(p.getParent());
ModelUtils.persistModel(p, model);

p = TestRegistryClientBuilder.getRegistryMemberCatalogPath(
TestRegistryClientBuilder.getRegistryDir(configDir(), "registry.acme.org"),
new ArtifactCoords(MAIN_PLATFORM_KEY, memberArtifactId, null, "pom", baseRecommendedVersion));
final String jsonContent = Files.readString(p).replace(baseRecommendedVersion, nonRecommendedVersion);
String jsonName = p.getFileName().toString().replace(baseRecommendedVersion, nonRecommendedVersion);
Files.writeString(p.getParent().resolve(jsonName), jsonContent);
}

protected String getMainPlatformKey() {
return MAIN_PLATFORM_KEY;
}

@Test
public void test() throws Exception {
final ExtensionCatalog catalog = ExtensionCatalogResolver.builder().build().resolveExtensionCatalog(
Collections.singletonList(ArtifactCoords.fromString(MAIN_PLATFORM_KEY + ":acme-baz-bom::pom:1.0.0")));
assertThat(Arrays.asList(new ArtifactCoords[] {
ArtifactCoords.fromString("io.quarkus:quarkus-core:1.1.2"),
ArtifactCoords.fromString(MAIN_PLATFORM_KEY + ":acme-foo:1.0.0"),
ArtifactCoords.fromString(MAIN_PLATFORM_KEY + ":acme-baz:1.0.0"),
ArtifactCoords.fromString("org.acme:acme-quarkus-other:5.5.5")
})).isEqualTo(
catalog.getExtensions().stream().map(e -> e.getArtifact()).collect(Collectors.toList()));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -310,6 +310,7 @@ private class ExtensionCatalogBuilder {
private final List<ExtensionCatalog> catalogs = new ArrayList<>();
final Map<String, List<RegistryExtensionResolver>> registriesByQuarkusCore = new HashMap<>();
private final Map<String, Integer> compatibilityCodes = new LinkedHashMap<>();
final List<String> upstreamQuarkusVersions = new ArrayList<>(1);

void addCatalog(ExtensionCatalog c) {
catalogs.add(c);
Expand Down Expand Up @@ -399,10 +400,9 @@ public ExtensionCatalog resolveExtensionCatalog() throws RegistryResolutionExcep
private void addOriginPreference(final ExtensionCatalog ec, OriginPreference originPreference) {
Map<String, Object> metadata = ec.getMetadata();
if (metadata.isEmpty()) {
metadata = new HashMap<>();
metadata = new HashMap<>(1);
((JsonExtensionCatalog) ec).setMetadata(metadata);
}

metadata.put("origin-preference", originPreference);
}

Expand All @@ -416,17 +416,16 @@ public ExtensionCatalog resolveExtensionCatalog(String quarkusCoreVersion) throw
throw new RegistryResolutionException("No registries configured");
}

return resolveExtensionCatalog(quarkusCoreVersion, new ExtensionCatalogBuilder(), Collections.emptyMap());
return resolveExtensionCatalog(quarkusCoreVersion, new ExtensionCatalogBuilder(), Collections.emptySet());
}

private ExtensionCatalog resolveExtensionCatalog(String quarkusCoreVersion,
final ExtensionCatalogBuilder catalogBuilder, Map<String, Platform> preferredPlatforms)
final ExtensionCatalogBuilder catalogBuilder, Set<String> preferredPlatforms)
throws RegistryResolutionException {
final List<String> upstreamQuarkusVersions = new ArrayList<>(1);
collectPlatforms(quarkusCoreVersion, catalogBuilder, upstreamQuarkusVersions, preferredPlatforms);
collectPlatforms(quarkusCoreVersion, catalogBuilder, preferredPlatforms);
int i = 0;
while (i < upstreamQuarkusVersions.size()) {
collectPlatforms(upstreamQuarkusVersions.get(i++), catalogBuilder, upstreamQuarkusVersions, preferredPlatforms);
while (i < catalogBuilder.upstreamQuarkusVersions.size()) {
collectPlatforms(catalogBuilder.upstreamQuarkusVersions.get(i++), catalogBuilder, preferredPlatforms);
}
return catalogBuilder.build();
}
Expand Down Expand Up @@ -528,17 +527,17 @@ public ExtensionCatalog resolveExtensionCatalog(StreamCoords streamCoords) throw
}

@SuppressWarnings("unchecked")
public ExtensionCatalog resolveExtensionCatalog(Collection<ArtifactCoords> platforms)
public ExtensionCatalog resolveExtensionCatalog(Collection<ArtifactCoords> preferredPlatforms)
throws RegistryResolutionException {
if (platforms.isEmpty()) {
if (preferredPlatforms.isEmpty()) {
return resolveExtensionCatalog();
}

final ExtensionCatalogBuilder catalogBuilder = new ExtensionCatalogBuilder();
final Map<String, Platform> preferredPlatforms = new LinkedHashMap<>();
final Set<String> preferredPlatformKeys = new HashSet<>();
String quarkusVersion = null;
int platformIndex = 0;
for (ArtifactCoords bom : platforms) {
for (ArtifactCoords bom : preferredPlatforms) {
final List<RegistryExtensionResolver> registries;
try {
registries = filterRegistries(r -> r.checkPlatform(bom));
Expand All @@ -554,8 +553,30 @@ public ExtensionCatalog resolveExtensionCatalog(Collection<ArtifactCoords> platf
throw new RuntimeException(buf.toString());
}

final ExtensionCatalog catalog = resolvePlatformExtensions(bom, registries);
if (registries.isEmpty()) {
log.warn("None of the configured registries recognizes platform %s", bom);
continue;
}

ExtensionCatalog catalog = null;
RegistryExtensionResolver registry = null;
for (int i = 0; i < registries.size(); ++i) {
registry = registries.get(i);
try {
catalog = registry.resolvePlatformExtensions(bom);
break;
} catch (RegistryResolutionException e) {
}
}

if (catalog == null) {
final StringBuilder buf = new StringBuilder();
buf.append("Failed to resolve platform ").append(bom).append(" using the following registries: ");
buf.append(registries.get(0).getId());
for (int i = 1; i < registries.size(); ++i) {
buf.append(", ").append(registries.get(i++));
}
log.warn(buf.toString());
continue;
}

Expand All @@ -571,12 +592,11 @@ public ExtensionCatalog resolveExtensionCatalog(Collection<ArtifactCoords> platf
o = md.get("platform-key");
if (o != null && o instanceof String) {
final String platformKey = o.toString();
if (preferredPlatforms.containsKey(platformKey)) {
if (!preferredPlatformKeys.add(platformKey)) {
continue;
}
final JsonPlatform p = new JsonPlatform();
p.setPlatformKey(platformKey);
preferredPlatforms.put(platformKey, p);

final JsonPlatformStream stream = new JsonPlatformStream();
stream.setId(String.valueOf(md.getOrDefault("stream", "default")));
Expand All @@ -598,20 +618,21 @@ public ExtensionCatalog resolveExtensionCatalog(Collection<ArtifactCoords> platf
}
release.setMemberBoms(coords);
}

collectPlatforms(quarkusVersion, catalogBuilder, registry, platformIndex,
p);
continue;
}
}
}

catalogBuilder.addCatalog(catalog);

final OriginPreference originPreference = new OriginPreference(0, ++platformIndex, 1, 1,
catalogBuilder.getCompatibilityCode(quarkusVersion));
addOriginPreference(catalog, originPreference);
catalogBuilder.addCatalog(catalog);
}

return preferredPlatforms.isEmpty() ? catalogBuilder.build()
: resolveExtensionCatalog(quarkusVersion, catalogBuilder, preferredPlatforms);
: resolveExtensionCatalog(quarkusVersion, catalogBuilder, preferredPlatformKeys);
}

public void clearRegistryCache() throws RegistryResolutionException {
Expand All @@ -627,27 +648,6 @@ private void ensureRegistriesConfigured() throws RegistryResolutionException {
}
}

private ExtensionCatalog resolvePlatformExtensions(ArtifactCoords bom, List<RegistryExtensionResolver> registries) {
if (registries.isEmpty()) {
log.debug("None of the configured registries recognizes platform %s", bom);
return null;
}
for (RegistryExtensionResolver registry : registries) {
try {
return registry.resolvePlatformExtensions(bom);
} catch (RegistryResolutionException e) {
}
}
final StringBuilder buf = new StringBuilder();
buf.append("Failed to resolve platform ").append(bom).append(" using the following registries: ");
buf.append(registries.get(0).getId());
for (int i = 1; i < registries.size(); ++i) {
buf.append(", ").append(registries.get(i++));
}
log.warn(buf.toString());
return null;
}

private void appendNonPlatformExtensions(
ExtensionCatalogBuilder catalogBuilder,
String quarkusVersion) throws RegistryResolutionException {
Expand Down Expand Up @@ -684,9 +684,8 @@ private int getRegistryIndex(String registryId) {
throw new IllegalStateException(buf.toString());
}

private void collectPlatforms(String quarkusCoreVersion,
ExtensionCatalogBuilder catalogBuilder,
Collection<String> upstreamQuarkusVersions, Map<String, Platform> preferredPlatforms)
private void collectPlatforms(String quarkusCoreVersion, ExtensionCatalogBuilder catalogBuilder,
Set<String> preferredPlatforms)
throws RegistryResolutionException {
final List<RegistryExtensionResolver> quarkusVersionRegistries = catalogBuilder
.getRegistriesForQuarkusCore(quarkusCoreVersion);
Expand All @@ -700,25 +699,19 @@ private void collectPlatforms(String quarkusCoreVersion,
if (platforms.isEmpty()) {
continue;
}
int platformIndex = 0;
for (Platform p : preferredPlatforms.values()) {
++platformIndex;
collectPlatforms(quarkusCoreVersion, catalogBuilder, upstreamQuarkusVersions, registry, platformIndex,
p);
}
int platformIndex = preferredPlatforms.size();
for (Platform p : platforms) {
if (preferredPlatforms.containsKey(p.getPlatformKey())) {
if (preferredPlatforms.contains(p.getPlatformKey())) {
continue;
}
++platformIndex;
collectPlatforms(quarkusCoreVersion, catalogBuilder, upstreamQuarkusVersions, registry, platformIndex,
p);
collectPlatforms(quarkusCoreVersion, catalogBuilder, registry, platformIndex, p);
}
}
}

private void collectPlatforms(String quarkusCoreVersion, ExtensionCatalogBuilder catalogBuilder,
Collection<String> upstreamQuarkusVersions, RegistryExtensionResolver registry, int platformIndex,
RegistryExtensionResolver registry, int platformIndex,
Platform p) throws RegistryResolutionException {
for (PlatformStream s : p.getStreams()) {
int releaseIndex = 0;
Expand All @@ -741,10 +734,9 @@ private void collectPlatforms(String quarkusCoreVersion, ExtensionCatalogBuilder
}

final String upstreamQuarkusVersion = r.getUpstreamQuarkusCoreVersion();
if (upstreamQuarkusVersion != null) {
if (!upstreamQuarkusVersions.contains(upstreamQuarkusVersion)) {
upstreamQuarkusVersions.add(upstreamQuarkusVersion);
}
if (upstreamQuarkusVersion != null
&& !catalogBuilder.upstreamQuarkusVersions.contains(upstreamQuarkusVersion)) {
catalogBuilder.upstreamQuarkusVersions.add(upstreamQuarkusVersion);
}
}
}
Expand Down