Skip to content

Commit

Permalink
Make sure projects based on non-recommended platform versions can sti…
Browse files Browse the repository at this point in the history
…ll list relevant extensions
  • Loading branch information
aloubyansky committed Aug 16, 2021
1 parent d67d5ec commit 9d94816
Show file tree
Hide file tree
Showing 3 changed files with 165 additions and 59 deletions.
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

0 comments on commit 9d94816

Please sign in to comment.