Skip to content

Commit

Permalink
Merge pull request #17836 from gsmet/amazon-instance
Browse files Browse the repository at this point in the history
Refactor Amazon Services initialization a bit
  • Loading branch information
gsmet authored Jun 10, 2021
2 parents c5dc7c4 + 34d8f4b commit 9b8a19f
Show file tree
Hide file tree
Showing 28 changed files with 345 additions and 658 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,10 @@
import java.util.Optional;
import java.util.function.Function;

import javax.enterprise.context.ApplicationScoped;

import org.jboss.jandex.DotName;
import org.jboss.jandex.ParameterizedType;
import org.jboss.jandex.Type;

import io.quarkus.amazon.common.runtime.AmazonClientApacheTransportRecorder;
Expand All @@ -18,15 +21,16 @@
import io.quarkus.amazon.common.runtime.SyncHttpClientBuildTimeConfig;
import io.quarkus.amazon.common.runtime.SyncHttpClientConfig;
import io.quarkus.arc.deployment.BeanRegistrationPhaseBuildItem;
import io.quarkus.arc.deployment.SyntheticBeanBuildItem;
import io.quarkus.arc.processor.BuildExtension;
import io.quarkus.arc.processor.DotNames;
import io.quarkus.arc.processor.InjectionPointInfo;
import io.quarkus.deployment.Feature;
import io.quarkus.deployment.annotations.BuildProducer;
import io.quarkus.deployment.builditem.ExtensionSslNativeSupportBuildItem;
import io.quarkus.deployment.builditem.FeatureBuildItem;
import io.quarkus.runtime.RuntimeValue;
import software.amazon.awssdk.awscore.client.builder.AwsClientBuilder;
import software.amazon.awssdk.core.SdkClient;
import software.amazon.awssdk.http.SdkHttpClient;
import software.amazon.awssdk.http.async.SdkAsyncHttpClient;

Expand Down Expand Up @@ -59,12 +63,12 @@ protected void setupExtension(BeanRegistrationPhaseBuildItem beanRegistrationPha

//Discover all clients injections in order to determine if async or sync client is required
for (InjectionPointInfo injectionPoint : beanRegistrationPhase.getContext().get(BuildExtension.Key.INJECTION_POINTS)) {
Type requiredType = injectionPoint.getRequiredType();
Type injectedType = getInjectedType(injectionPoint);

if (syncClientName().equals(requiredType.name())) {
if (syncClientName().equals(injectedType.name())) {
syncClassName = Optional.of(syncClientName());
}
if (asyncClientName().equals(requiredType.name())) {
if (asyncClientName().equals(injectedType.name())) {
asyncClassName = Optional.of(asyncClientName());
}
}
Expand Down Expand Up @@ -148,68 +152,68 @@ protected void createNettyAsyncTransportBuilder(List<AmazonClientBuildItem> amaz
});
}

protected void createClientBuilders(List<AmazonClientSyncTransportBuildItem> syncClientBuilders,
List<AmazonClientAsyncTransportBuildItem> asyncClientBuilders,
BuildProducer<AmazonClientBuilderBuildItem> builderProducer,
Function<RuntimeValue<SdkHttpClient.Builder>, RuntimeValue<AwsClientBuilder>> syncFunc,
Function<RuntimeValue<SdkAsyncHttpClient.Builder>, RuntimeValue<AwsClientBuilder>> asyncFunc) {
protected void createClientBuilders(
AmazonClientRecorder recorder,
RuntimeValue<AwsConfig> awsConfigRuntime,
RuntimeValue<SdkConfig> sdkConfigRuntime,
SdkBuildTimeConfig sdkBuildConfig,
List<AmazonClientSyncTransportBuildItem> amazonClientSyncTransports,
List<AmazonClientAsyncTransportBuildItem> amazonClientAsyncTransports,
Class<?> syncClientBuilderClass,
Function<RuntimeValue<SdkHttpClient.Builder>, RuntimeValue<AwsClientBuilder>> syncClientBuilderFunction,
Class<?> asyncClientBuilderClass,
Function<RuntimeValue<SdkAsyncHttpClient.Builder>, RuntimeValue<AwsClientBuilder>> asyncClientBuilderFunction,
BuildProducer<SyntheticBeanBuildItem> syntheticBeans) {
String configName = configName();

Optional<RuntimeValue<SdkHttpClient.Builder>> syncClientBuilder = syncClientBuilders.stream()
Optional<RuntimeValue<SdkHttpClient.Builder>> syncSdkHttpClientBuilder = amazonClientSyncTransports.stream()
.filter(c -> configName.equals(c.getAwsClientName()))
.map(c -> c.getClientBuilder())
.findFirst();
Optional<RuntimeValue<SdkAsyncHttpClient.Builder>> asyncClientBuilder = asyncClientBuilders.stream()
Optional<RuntimeValue<SdkAsyncHttpClient.Builder>> asyncSdkAsyncHttpClientBuilder = amazonClientAsyncTransports.stream()
.filter(c -> configName.equals(c.getAwsClientName()))
.map(c -> c.getClientBuilder())
.findFirst();

if (!syncClientBuilder.isPresent() && !asyncClientBuilder.isPresent()) {
if (!syncSdkHttpClientBuilder.isPresent() && !asyncSdkAsyncHttpClientBuilder.isPresent()) {
return;
}

builderProducer.produce(new AmazonClientBuilderBuildItem(configName,
syncClientBuilder.isPresent() ? syncFunc.apply(syncClientBuilder.get()) : null,
asyncClientBuilder.isPresent() ? asyncFunc.apply(asyncClientBuilder.get()) : null));
}

protected void buildClients(List<AmazonClientBuilderConfiguredBuildItem> configuredClients,
Function<RuntimeValue<? extends AwsClientBuilder>, RuntimeValue<? extends SdkClient>> syncClient,
Function<RuntimeValue<? extends AwsClientBuilder>, RuntimeValue<? extends SdkClient>> asyncClient) {

for (AmazonClientBuilderConfiguredBuildItem client : configuredClients) {
if (configName().equals(client.getAwsClientName())) {
if (client.getSyncBuilder() != null) {
syncClient.apply(client.getSyncBuilder());
}
if (client.getAsyncBuilder() != null) {
asyncClient.apply(client.getAsyncBuilder());
}
}
RuntimeValue<AwsClientBuilder> syncClientBuilder = syncSdkHttpClientBuilder.isPresent()
? syncClientBuilderFunction.apply(syncSdkHttpClientBuilder.get())
: null;
RuntimeValue<AwsClientBuilder> asyncClientBuilder = asyncSdkAsyncHttpClientBuilder.isPresent()
? asyncClientBuilderFunction.apply(asyncSdkAsyncHttpClientBuilder.get())
: null;

if (syncClientBuilder != null) {
syncClientBuilder = recorder.configure(syncClientBuilder, awsConfigRuntime, sdkConfigRuntime,
sdkBuildConfig, configName());
syntheticBeans.produce(SyntheticBeanBuildItem.configure(syncClientBuilderClass)
.setRuntimeInit()
.scope(ApplicationScoped.class)
.runtimeValue(syncClientBuilder)
.done());
}
if (asyncClientBuilder != null) {
asyncClientBuilder = recorder.configure(asyncClientBuilder, awsConfigRuntime, sdkConfigRuntime,
sdkBuildConfig, configName());
syntheticBeans.produce(SyntheticBeanBuildItem.configure(asyncClientBuilderClass)
.setRuntimeInit()
.scope(ApplicationScoped.class)
.runtimeValue(asyncClientBuilder)
.done());
}
}

protected void initClientBuilders(List<AmazonClientBuilderBuildItem> clients, AmazonClientRecorder recorder,
RuntimeValue<AwsConfig> awsConfigRuntime,
RuntimeValue<SdkConfig> sdkConfigRuntime, SdkBuildTimeConfig sdkBuildConfig,
BuildProducer<AmazonClientBuilderConfiguredBuildItem> producer) {
Optional<AmazonClientBuilderBuildItem> matchingClientBuilderBuildItem = clients.stream()
.filter(c -> c.getAwsClientName().equals(configName()))
.findAny();
private Type getInjectedType(InjectionPointInfo injectionPoint) {
Type requiredType = injectionPoint.getRequiredType();
Type injectedType = requiredType;

matchingClientBuilderBuildItem.ifPresent(client -> {
RuntimeValue<? extends AwsClientBuilder> syncBuilder = null;
RuntimeValue<? extends AwsClientBuilder> asyncBuilder = null;
if (DotNames.INSTANCE.equals(requiredType.name()) && requiredType instanceof ParameterizedType) {
injectedType = requiredType.asParameterizedType().arguments().get(0);
}

if (client.getSyncBuilder() != null) {
syncBuilder = recorder.configure(client.getSyncBuilder(), awsConfigRuntime, sdkConfigRuntime,
sdkBuildConfig, configName());
}
if (client.getAsyncBuilder() != null) {
asyncBuilder = recorder.configure(client.getAsyncBuilder(), awsConfigRuntime, sdkConfigRuntime,
sdkBuildConfig, configName());
}
producer.produce(new AmazonClientBuilderConfiguredBuildItem(configName(), syncBuilder, asyncBuilder));
});
return injectedType;
}
}

This file was deleted.

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,6 @@
import io.quarkus.amazon.common.deployment.AbstractAmazonServiceProcessor;
import io.quarkus.amazon.common.deployment.AmazonClientAsyncTransportBuildItem;
import io.quarkus.amazon.common.deployment.AmazonClientBuildItem;
import io.quarkus.amazon.common.deployment.AmazonClientBuilderBuildItem;
import io.quarkus.amazon.common.deployment.AmazonClientBuilderConfiguredBuildItem;
import io.quarkus.amazon.common.deployment.AmazonClientInterceptorsPathBuildItem;
import io.quarkus.amazon.common.deployment.AmazonClientSyncTransportBuildItem;
import io.quarkus.amazon.common.deployment.AmazonHttpClients;
Expand All @@ -21,19 +19,20 @@
import io.quarkus.amazon.dynamodb.runtime.DynamodbConfig;
import io.quarkus.amazon.dynamodb.runtime.DynamodbRecorder;
import io.quarkus.arc.deployment.AdditionalBeanBuildItem;
import io.quarkus.arc.deployment.BeanContainerBuildItem;
import io.quarkus.arc.deployment.BeanRegistrationPhaseBuildItem;
import io.quarkus.arc.deployment.SyntheticBeanBuildItem;
import io.quarkus.deployment.Feature;
import io.quarkus.deployment.annotations.BuildProducer;
import io.quarkus.deployment.annotations.BuildStep;
import io.quarkus.deployment.annotations.ExecutionTime;
import io.quarkus.deployment.annotations.Record;
import io.quarkus.deployment.builditem.ExtensionSslNativeSupportBuildItem;
import io.quarkus.deployment.builditem.FeatureBuildItem;
import io.quarkus.deployment.builditem.ShutdownContextBuildItem;
import io.quarkus.deployment.builditem.nativeimage.RuntimeInitializedClassBuildItem;
import software.amazon.awssdk.services.dynamodb.DynamoDbAsyncClient;
import software.amazon.awssdk.services.dynamodb.DynamoDbAsyncClientBuilder;
import software.amazon.awssdk.services.dynamodb.DynamoDbClient;
import software.amazon.awssdk.services.dynamodb.DynamoDbClientBuilder;

public class DynamodbProcessor extends AbstractAmazonServiceProcessor {

Expand Down Expand Up @@ -128,34 +127,23 @@ void setupNettyAsyncTransport(List<AmazonClientBuildItem> amazonClients, Dynamod

@BuildStep
@Record(ExecutionTime.RUNTIME_INIT)
void createClientBuilders(List<AmazonClientSyncTransportBuildItem> syncTransports,
List<AmazonClientAsyncTransportBuildItem> asyncTransports, DynamodbRecorder recorder,
DynamodbConfig runtimeConfig, BuildProducer<AmazonClientBuilderBuildItem> builderProducer) {

createClientBuilders(syncTransports, asyncTransports, builderProducer,
(syncTransport) -> recorder.createSyncBuilder(runtimeConfig, syncTransport),
(asyncTransport) -> recorder.createAsyncBuilder(runtimeConfig, asyncTransport));
}

@BuildStep
@Record(ExecutionTime.RUNTIME_INIT)
void configureClient(List<AmazonClientBuilderBuildItem> clients, DynamodbRecorder recorder,
void createClientBuilders(DynamodbRecorder recorder,
AmazonClientRecorder commonRecorder,
DynamodbConfig runtimeConfig,
BuildProducer<AmazonClientBuilderConfiguredBuildItem> producer) {

initClientBuilders(clients, commonRecorder, recorder.getAwsConfig(runtimeConfig), recorder.getSdkConfig(runtimeConfig),
buildTimeConfig.sdk, producer);
}

@BuildStep
@Record(ExecutionTime.RUNTIME_INIT)
void buildClients(List<AmazonClientBuilderConfiguredBuildItem> configuredClients, DynamodbRecorder recorder,
BeanContainerBuildItem beanContainer,
ShutdownContextBuildItem shutdown) {

buildClients(configuredClients,
(syncBuilder) -> recorder.buildClient(syncBuilder, beanContainer.getValue(), shutdown),
(asyncBuilder) -> recorder.buildAsyncClient(asyncBuilder, beanContainer.getValue(), shutdown));
List<AmazonClientSyncTransportBuildItem> syncTransports,
List<AmazonClientAsyncTransportBuildItem> asyncTransports,
BuildProducer<SyntheticBeanBuildItem> syntheticBeans) {

createClientBuilders(commonRecorder,
recorder.getAwsConfig(runtimeConfig),
recorder.getSdkConfig(runtimeConfig),
buildTimeConfig.sdk,
syncTransports,
asyncTransports,
DynamoDbClientBuilder.class,
(syncTransport) -> recorder.createSyncBuilder(runtimeConfig, syncTransport),
DynamoDbAsyncClientBuilder.class,
(asyncTransport) -> recorder.createAsyncBuilder(runtimeConfig, asyncTransport),
syntheticBeans);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import javax.annotation.PreDestroy;
import javax.enterprise.context.ApplicationScoped;
import javax.enterprise.inject.Instance;
import javax.enterprise.inject.Produces;

import software.amazon.awssdk.services.dynamodb.DynamoDbAsyncClient;
Expand All @@ -12,41 +13,40 @@
@ApplicationScoped
public class DynamodbClientProducer {

private volatile DynamoDbClientBuilder syncConfiguredBuilder;
private volatile DynamoDbAsyncClientBuilder asyncConfiguredBuilder;
private final DynamoDbClient syncClient;
private final DynamoDbAsyncClient asyncClient;

private DynamoDbClient client;
private DynamoDbAsyncClient asyncClient;
DynamodbClientProducer(Instance<DynamoDbClientBuilder> syncClientBuilderInstance,
Instance<DynamoDbAsyncClientBuilder> asyncClientBuilderInstance) {
this.syncClient = syncClientBuilderInstance.isResolvable() ? syncClientBuilderInstance.get().build() : null;
this.asyncClient = asyncClientBuilderInstance.isResolvable() ? asyncClientBuilderInstance.get().build() : null;
}

@Produces
@ApplicationScoped
public DynamoDbClient client() {
client = syncConfiguredBuilder.build();
return client;
if (syncClient == null) {
throw new IllegalStateException("The DynamoDbClient is required but has not been detected/configured.");
}
return syncClient;
}

@Produces
@ApplicationScoped
public DynamoDbAsyncClient asyncClient() {
asyncClient = asyncConfiguredBuilder.build();
if (asyncClient == null) {
throw new IllegalStateException("The DynamoDbAsyncClient is required but has not been detected/configured.");
}
return asyncClient;
}

@PreDestroy
public void destroy() {
if (client != null) {
client.close();
if (syncClient != null) {
syncClient.close();
}
if (asyncClient != null) {
asyncClient.close();
}
}

public void setSyncConfiguredBuilder(DynamoDbClientBuilder syncConfiguredBuilder) {
this.syncConfiguredBuilder = syncConfiguredBuilder;
}

public void setAsyncConfiguredBuilder(DynamoDbAsyncClientBuilder asyncConfiguredBuilder) {
this.asyncConfiguredBuilder = asyncConfiguredBuilder;
}
}
Loading

0 comments on commit 9b8a19f

Please sign in to comment.