Skip to content

Commit

Permalink
Support for providing a custom extension registry client impl in a ma…
Browse files Browse the repository at this point in the history
…ven artifact
  • Loading branch information
aloubyansky committed Mar 23, 2021
1 parent 17645be commit 00cffa9
Show file tree
Hide file tree
Showing 12 changed files with 212 additions and 59 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,14 @@
import io.quarkus.registry.catalog.json.JsonPlatformCatalog;
import io.quarkus.registry.client.RegistryClientFactory;
import io.quarkus.registry.client.maven.MavenRegistryClientFactory;
import io.quarkus.registry.client.spi.RegistryClientEnvironment;
import io.quarkus.registry.client.spi.RegistryClientFactoryProvider;
import io.quarkus.registry.config.RegistriesConfig;
import io.quarkus.registry.config.RegistriesConfigLocator;
import io.quarkus.registry.config.RegistryConfig;
import java.io.File;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
Expand All @@ -24,8 +29,10 @@
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.ServiceLoader;
import java.util.Set;
import java.util.function.Function;
import org.eclipse.aether.artifact.DefaultArtifact;

public class ExtensionCatalogResolver {

Expand All @@ -45,6 +52,9 @@ public class Builder {
private RegistriesConfig config;
private boolean built;

private RegistryClientFactory defaultClientFactory;
private RegistryClientEnvironment clientEnv;

private Builder() {
}

Expand Down Expand Up @@ -95,14 +105,13 @@ private void completeConfig() {

private void buildRegistryClients() {
registries = new ArrayList<>(config.getRegistries().size());
final RegistryClientFactory defaultClientFactory = new MavenRegistryClientFactory(artifactResolver,
log);
for (RegistryConfig config : config.getRegistries()) {
if (config.isDisabled()) {
continue;
}
final RegistryClientFactory clientFactory = getClientFactory(config);
try {
registries.add(new RegistryExtensionResolver(defaultClientFactory.buildRegistryClient(config), log));
registries.add(new RegistryExtensionResolver(clientFactory.buildRegistryClient(config), log));
} catch (RegistryResolutionException e) {
// TODO this should be enabled once the registry comes to life
log.debug(e.getMessage());
Expand All @@ -111,6 +120,72 @@ private void buildRegistryClients() {
}
}

private RegistryClientFactory getClientFactory(RegistryConfig config) {
final Object providerValue = config.getExtra().get("client-factory-artifact");
if (providerValue == null) {
return getDefaultClientFactory();
}
ArtifactCoords providerArtifact = null;
try {
final String providerStr = (String) providerValue;
providerArtifact = ArtifactCoords.fromString(providerStr);
} catch (Exception e) {
throw new IllegalStateException("Failed to process configuration of " + config.getId()
+ " registry: failed to cast " + providerValue + " to String", e);
}
final File providerJar;
try {
providerJar = artifactResolver.resolve(new DefaultArtifact(providerArtifact.getGroupId(),
providerArtifact.getArtifactId(), providerArtifact.getClassifier(),
providerArtifact.getType(), providerArtifact.getVersion())).getArtifact().getFile();
} catch (BootstrapMavenException e) {
throw new IllegalStateException(
"Failed to resolve the registry client factory provider artifact " + providerArtifact, e);
}
log.debug("Loading registry client factory for %s from %s", config.getId(), providerArtifact);
final ClassLoader originalCl = Thread.currentThread().getContextClassLoader();
try {
ClassLoader providerCl = new URLClassLoader(new URL[] { providerJar.toURI().toURL() }, originalCl);
final Iterator<RegistryClientFactoryProvider> i = ServiceLoader
.load(RegistryClientFactoryProvider.class, providerCl).iterator();
final RegistryClientFactoryProvider provider = i.next();
if (i.hasNext()) {
final StringBuilder buf = new StringBuilder();
buf.append("Found more than one registry client factory provider "
+ provider.getClass().getName());
while (i.hasNext()) {
buf.append(", ").append(i.next().getClass().getName());
}
throw new Exception(buf.toString());
}
return provider.newRegistryClientFactory(getClientEnv());
} catch (Exception e) {
throw new IllegalStateException("Failed to load registry client factory from " + providerJar, e);
} finally {
Thread.currentThread().setContextClassLoader(originalCl);
}
}

private RegistryClientFactory getDefaultClientFactory() {
return defaultClientFactory == null ? defaultClientFactory = new MavenRegistryClientFactory(artifactResolver, log)
: defaultClientFactory;
}

private RegistryClientEnvironment getClientEnv() {
return clientEnv == null ? clientEnv = new RegistryClientEnvironment() {

@Override
public MessageWriter log() {
return log;
}

@Override
public MavenArtifactResolver resolver() {
return artifactResolver;
}
} : clientEnv;
}

private void assertNotBuilt() {
if (built) {
throw new IllegalStateException("The builder has already built an instance");
Expand Down
Original file line number Diff line number Diff line change
@@ -1,55 +1,11 @@
package io.quarkus.registry.client;

import io.quarkus.maven.ArtifactCoords;
import io.quarkus.registry.RegistryResolutionException;
import io.quarkus.registry.catalog.ExtensionCatalog;
import io.quarkus.registry.catalog.PlatformCatalog;
import io.quarkus.registry.config.RegistryConfig;
import java.util.Objects;

/**
* Implements the basic queries a registry client is supposed to handle.
* Although there are only a few kinds of queries, a registry is not required to support
* all of them. For example, a registry may be configured to only provide platform extensions or
* the other way around - provide only non-platform extensions but not platforms.
*/
public class RegistryClient
implements RegistryNonPlatformExtensionsResolver, RegistryPlatformExtensionsResolver, RegistryPlatformsResolver,
RegistryConfigResolver {

private final RegistryPlatformsResolver platforms;
private final RegistryPlatformExtensionsResolver platformExtensions;
private final RegistryNonPlatformExtensionsResolver nonPlatformExtensions;
protected RegistryConfig config;

public RegistryClient(RegistryConfig config, RegistryPlatformsResolver platforms,
RegistryPlatformExtensionsResolver platformExtensions,
RegistryNonPlatformExtensionsResolver nonPlatformExtensions) {
this.config = config;
this.platforms = platforms;
this.platformExtensions = Objects.requireNonNull(platformExtensions);
this.nonPlatformExtensions = nonPlatformExtensions;
}

@Override
public PlatformCatalog resolvePlatforms(String quarkusVersion) throws RegistryResolutionException {
return platforms == null ? null : platforms.resolvePlatforms(quarkusVersion);
}

@Override
public ExtensionCatalog resolvePlatformExtensions(ArtifactCoords platformCoords)
throws RegistryResolutionException {
return platformExtensions.resolvePlatformExtensions(platformCoords);
}

@Override
public ExtensionCatalog resolveNonPlatformExtensions(String quarkusVersion) throws RegistryResolutionException {
return nonPlatformExtensions == null ? null
: nonPlatformExtensions.resolveNonPlatformExtensions(quarkusVersion);
}

@Override
public RegistryConfig resolveRegistryConfig() throws RegistryResolutionException {
return config;
}
public interface RegistryClient extends RegistryNonPlatformExtensionsResolver, RegistryPlatformExtensionsResolver,
RegistryPlatformsResolver, RegistryConfigResolver {
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
package io.quarkus.registry.client;

import io.quarkus.maven.ArtifactCoords;
import io.quarkus.registry.RegistryResolutionException;
import io.quarkus.registry.catalog.ExtensionCatalog;
import io.quarkus.registry.catalog.PlatformCatalog;
import io.quarkus.registry.config.RegistryConfig;
import java.util.Objects;

public class RegistryClientDispatcher implements RegistryClient {

private final RegistryPlatformsResolver platforms;
private final RegistryPlatformExtensionsResolver platformExtensions;
private final RegistryNonPlatformExtensionsResolver nonPlatformExtensions;
protected RegistryConfig config;

public RegistryClientDispatcher(RegistryConfig config, RegistryPlatformsResolver platforms,
RegistryPlatformExtensionsResolver platformExtensions,
RegistryNonPlatformExtensionsResolver nonPlatformExtensions) {
this.config = config;
this.platforms = platforms;
this.platformExtensions = Objects.requireNonNull(platformExtensions);
this.nonPlatformExtensions = nonPlatformExtensions;
}

@Override
public PlatformCatalog resolvePlatforms(String quarkusVersion) throws RegistryResolutionException {
return platforms == null ? null : platforms.resolvePlatforms(quarkusVersion);
}

@Override
public ExtensionCatalog resolvePlatformExtensions(ArtifactCoords platformCoords)
throws RegistryResolutionException {
return platformExtensions.resolvePlatformExtensions(platformCoords);
}

@Override
public ExtensionCatalog resolveNonPlatformExtensions(String quarkusVersion) throws RegistryResolutionException {
return nonPlatformExtensions == null ? null
: nonPlatformExtensions.resolveNonPlatformExtensions(quarkusVersion);
}

@Override
public RegistryConfig resolveRegistryConfig() throws RegistryResolutionException {
return config;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,12 @@
import io.quarkus.bootstrap.resolver.maven.MavenArtifactResolver;
import io.quarkus.devtools.messagewriter.MessageWriter;
import io.quarkus.maven.ArtifactCoords;
import io.quarkus.registry.Constants;
import io.quarkus.registry.RegistryResolutionException;
import io.quarkus.registry.catalog.ExtensionCatalog;
import io.quarkus.registry.catalog.json.JsonCatalogMapperHelper;
import io.quarkus.registry.catalog.json.JsonExtensionCatalog;
import io.quarkus.registry.client.RegistryPlatformExtensionsResolver;
import io.quarkus.registry.util.PlatformArtifacts;
import java.io.IOException;
import java.nio.file.Path;
import java.util.Objects;
Expand Down Expand Up @@ -37,9 +37,7 @@ public ExtensionCatalog resolvePlatformExtensions(ArtifactCoords platformCoords)
version = platformCoords.getVersion();
}
final String groupId = platformCoords.getGroupId();
final String artifactId = platformCoords.getArtifactId().endsWith(Constants.PLATFORM_DESCRIPTOR_ARTIFACT_ID_SUFFIX)
? platformCoords.getArtifactId()
: platformCoords.getArtifactId() + Constants.PLATFORM_DESCRIPTOR_ARTIFACT_ID_SUFFIX;
final String artifactId = PlatformArtifacts.ensureCatalogArtifactId(platformCoords.getArtifactId());
final String classifier = version;
final Artifact catalogArtifact = new DefaultArtifact(groupId, artifactId, classifier, "json", version);
log.debug("Resolving platform extension catalog %s", catalogArtifact);
Expand All @@ -60,11 +58,7 @@ public ExtensionCatalog resolvePlatformExtensions(ArtifactCoords platformCoords)
private String resolveLatestBomVersion(ArtifactCoords bom, String versionRange)
throws RegistryResolutionException {
final Artifact bomArtifact = new DefaultArtifact(bom.getGroupId(),
bom.getArtifactId().endsWith(Constants.PLATFORM_DESCRIPTOR_ARTIFACT_ID_SUFFIX)
? bom.getArtifactId().substring(0,
bom.getArtifactId().length()
- Constants.PLATFORM_DESCRIPTOR_ARTIFACT_ID_SUFFIX.length())
: bom.getArtifactId(),
PlatformArtifacts.ensureBomArtifactId(bom.getArtifactId()),
"", "pom", bom.getVersion());
log.debug("Resolving the latest version of %s:%s:%s:%s in the range %s", bom.getGroupId(), bom.getArtifactId(),
bom.getClassifier(), bom.getType(), versionRange);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
import io.quarkus.registry.Constants;
import io.quarkus.registry.RegistryResolutionException;
import io.quarkus.registry.client.RegistryClient;
import io.quarkus.registry.client.RegistryClientDispatcher;
import io.quarkus.registry.client.RegistryClientFactory;
import io.quarkus.registry.client.RegistryNonPlatformExtensionsResolver;
import io.quarkus.registry.client.RegistryPlatformsResolver;
Expand Down Expand Up @@ -151,7 +152,7 @@ public RegistryClient buildRegistryClient(RegistryConfig config) throws Registry
platformsResolver = new MavenPlatformsResolver(platformsConfig, resolver, log);
}

return new RegistryClient(config, platformsResolver,
return new RegistryClientDispatcher(config, platformsResolver,
Boolean.TRUE.equals(config.getPlatforms().getExtensionCatalogsIncluded())
? new MavenPlatformExtensionsResolver(resolver, log)
: new MavenPlatformExtensionsResolver(originalResolver, log),
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package io.quarkus.registry.client.spi;

import io.quarkus.bootstrap.resolver.maven.MavenArtifactResolver;
import io.quarkus.devtools.messagewriter.MessageWriter;

public interface RegistryClientEnvironment {

MessageWriter log();

MavenArtifactResolver resolver();
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package io.quarkus.registry.client.spi;

import io.quarkus.registry.client.RegistryClientFactory;

/**
* Registry client factory service provider interface that will be looked up on the class path using the ServiceLoader
* mechanism.
*/
public interface RegistryClientFactoryProvider {

RegistryClientFactory newRegistryClientFactory(RegistryClientEnvironment env);
}
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,9 @@ private static RegistryConfig completeRequiredConfig(RegistryConfig original) {
if (original.getPlatforms() != null) {
config.setPlatforms(original.getPlatforms());
}
if (!original.getExtra().isEmpty()) {
config.setExtra(original.getExtra());
}
}
return config;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package io.quarkus.registry.config;

import java.util.Map;

public interface RegistryConfig {

String getId();
Expand All @@ -17,4 +19,6 @@ public interface RegistryConfig {
RegistryMavenConfig getMaven();

RegistryQuarkusVersionsConfig getQuarkusVersions();

Map<String, Object> getExtra();
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package io.quarkus.registry.config.json;

import com.fasterxml.jackson.annotation.JsonAnyGetter;
import com.fasterxml.jackson.annotation.JsonAnySetter;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
Expand All @@ -9,6 +11,9 @@
import io.quarkus.registry.config.RegistryNonPlatformExtensionsConfig;
import io.quarkus.registry.config.RegistryPlatformsConfig;
import io.quarkus.registry.config.RegistryQuarkusVersionsConfig;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;

@JsonInclude(JsonInclude.Include.NON_NULL)
Expand All @@ -22,6 +27,7 @@ public class JsonRegistryConfig implements RegistryConfig {
private RegistryNonPlatformExtensionsConfig nonPlatformExtensions;
private RegistryMavenConfig mavenConfig;
private RegistryQuarkusVersionsConfig versionsConfig;
private Map<String, Object> extra;

public JsonRegistryConfig() {
}
Expand Down Expand Up @@ -112,6 +118,24 @@ public void setQuarkusVersions(RegistryQuarkusVersionsConfig quarkusVersions) {
this.versionsConfig = quarkusVersions;
}

@JsonAnyGetter
@Override
public Map<String, Object> getExtra() {
return extra == null ? Collections.emptyMap() : extra;
}

public void setExtra(Map<String, Object> extra) {
this.extra = extra;
}

@JsonAnySetter
public void setAny(String name, Object value) {
if (extra == null) {
extra = new HashMap<>();
}
extra.put(name, value);
}

public String toString() {
return "[" + id + " maven=" + mavenConfig + "]";
}
Expand Down
Loading

0 comments on commit 00cffa9

Please sign in to comment.