From 7418a44535043f0090b9da02c4be3818cdd9b35c Mon Sep 17 00:00:00 2001 From: Andriy Dmytruk Date: Thu, 16 Nov 2023 12:30:44 -0500 Subject: [PATCH] Improve client factories Use the client builders as a parameter to clients to allow users to configure the builders. When they are used as parameters, the builder singleton becomes requires and therefore can be configured with bean creation event listener. --- ...naut.build.internal.oraclecloud-bom.gradle | 1 + .../core/sdk/AbstractSdkClientFactory.java | 10 ++- .../processor/OracleCloudSdkProcessor.java | 15 ++--- .../database/DatabaseFactoryTest.java | 66 +++++++++++++++++++ 4 files changed, 81 insertions(+), 11 deletions(-) create mode 100644 oraclecloud-sdk/src/test/java/io/micronaut/oraclecloud/database/DatabaseFactoryTest.java diff --git a/buildSrc/src/main/groovy/io.micronaut.build.internal.oraclecloud-bom.gradle b/buildSrc/src/main/groovy/io.micronaut.build.internal.oraclecloud-bom.gradle index 268cc470b..eed014651 100644 --- a/buildSrc/src/main/groovy/io.micronaut.build.internal.oraclecloud-bom.gradle +++ b/buildSrc/src/main/groovy/io.micronaut.build.internal.oraclecloud-bom.gradle @@ -11,6 +11,7 @@ static Collection parseOciBomArtifacts(String version) { if (!extraPropertiesExtension.has('ociArtifacts')) { String ociVersion = libs.oci.bom.get().version def ociArtifacts = parseOciBomArtifacts(ociVersion) + .stream().filter(artifact -> artifact != "oci-java-sdk-shaded-full").toList() String ociProjectVersion = new XmlSlurper().parse("checkouts/oci-java-sdk/bmc-bom/pom.xml").version.text() def ociProjectArtifacts = parseOciBomArtifacts(ociProjectVersion) diff --git a/oraclecloud-common/src/main/java/io/micronaut/oraclecloud/core/sdk/AbstractSdkClientFactory.java b/oraclecloud-common/src/main/java/io/micronaut/oraclecloud/core/sdk/AbstractSdkClientFactory.java index 016fd4108..b48bd5c2f 100644 --- a/oraclecloud-common/src/main/java/io/micronaut/oraclecloud/core/sdk/AbstractSdkClientFactory.java +++ b/oraclecloud-common/src/main/java/io/micronaut/oraclecloud/core/sdk/AbstractSdkClientFactory.java @@ -66,11 +66,17 @@ protected AbstractSdkClientFactory( } /** - * Builds the client. + * Builds the client based on its builder to make sure user can configure + * required parameters in the builder. + * + * @param clientBuilder The builder for client * @param authenticationDetailsProvider The authentication details provider * @return The client to build */ - protected abstract @NonNull T build(@NonNull AbstractAuthenticationDetailsProvider authenticationDetailsProvider); + protected abstract @NonNull T build( + @NonNull B clientBuilder, + @NonNull AbstractAuthenticationDetailsProvider authenticationDetailsProvider + ); /** * Set the HTTP provider for this client. This is injected by the application context, in order diff --git a/oraclecloud-sdk-processor/src/main/java/io/micronaut/oraclecloud/clients/processor/OracleCloudSdkProcessor.java b/oraclecloud-sdk-processor/src/main/java/io/micronaut/oraclecloud/clients/processor/OracleCloudSdkProcessor.java index 63e00f44b..551ae28e7 100644 --- a/oraclecloud-sdk-processor/src/main/java/io/micronaut/oraclecloud/clients/processor/OracleCloudSdkProcessor.java +++ b/oraclecloud-sdk-processor/src/main/java/io/micronaut/oraclecloud/clients/processor/OracleCloudSdkProcessor.java @@ -122,14 +122,10 @@ public boolean process(Set annotations, RoundEnvironment if (isRxJava2) { writeRxJava2Clients(e, packageName, simpleName); - } else { - if (isReactor) { - writeReactorClients(e, packageName, simpleName); - } else { - if (isAsync) { - factoryClassNames.add(writeClientFactory(e, packageName, simpleName)); - } - } + } else if (isReactor) { + writeReactorClients(e, packageName, simpleName); + } else if (isAsync) { + factoryClassNames.add(writeClientFactory(e, packageName, simpleName)); } } @@ -414,12 +410,13 @@ private String writeClientFactory(Element e, String packageName, String simpleNa final MethodSpec.Builder buildMethod = MethodSpec.methodBuilder("build"); buildMethod.returns(ClassName.get(packageName, simpleName)) + .addParameter(builderType, "clientBuilder") .addParameter(authProviderType, "authenticationDetailsProvider") .addAnnotation(Singleton.class) .addAnnotation(requiresSpec.build()) .addAnnotation(preDestroy.build()) .addModifiers(Modifier.PROTECTED) - .addCode("return builder.build(authenticationDetailsProvider);"); + .addCode("return clientBuilder.build(authenticationDetailsProvider);"); if (isBootstrapCompatible) { buildMethod.addAnnotation(BootstrapContextCompatible.class); } diff --git a/oraclecloud-sdk/src/test/java/io/micronaut/oraclecloud/database/DatabaseFactoryTest.java b/oraclecloud-sdk/src/test/java/io/micronaut/oraclecloud/database/DatabaseFactoryTest.java new file mode 100644 index 000000000..464209228 --- /dev/null +++ b/oraclecloud-sdk/src/test/java/io/micronaut/oraclecloud/database/DatabaseFactoryTest.java @@ -0,0 +1,66 @@ +package io.micronaut.oraclecloud.database; + +import com.oracle.bmc.database.DatabaseAsyncClient; +import com.oracle.bmc.database.DatabaseClient; +import io.micronaut.context.event.BeanCreatedEvent; +import io.micronaut.context.event.BeanCreatedEventListener; +import io.micronaut.core.annotation.NonNull; +import io.micronaut.test.extensions.junit5.annotation.MicronautTest; +import jakarta.inject.Singleton; +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +@MicronautTest +public class DatabaseFactoryTest { + + public static final String ENDPOINT = "http://my_endpoint"; + public static final String ASYNC_ENDPOINT = "http://my_endpoint_async"; + private final DatabaseClient databaseClient; + private final DatabaseAsyncClient databaseAsyncClient; + + public DatabaseFactoryTest( + DatabaseClient databaseClient, + DatabaseAsyncClient databaseAsyncClient + ) { + this.databaseClient = databaseClient; + this.databaseAsyncClient = databaseAsyncClient; + } + + @Test + void testDataBaseClientConfiguration() { + assertEquals(ENDPOINT, databaseClient.getEndpoint()); + } + + @Test + void testDataBaseAsyncClientConfiguration() { + assertEquals(ASYNC_ENDPOINT, databaseAsyncClient.getEndpoint()); + } + + @Singleton + static class DatabaseClientBuilderListener + implements BeanCreatedEventListener { + @Override + public DatabaseClient.Builder onCreated( + @NonNull BeanCreatedEvent event + ) { + DatabaseClient.Builder builder = event.getBean(); + builder.endpoint(DatabaseFactoryTest.ENDPOINT); + return builder; + } + } + + @Singleton + static class DatabaseAsyncClientBuilderListener + implements BeanCreatedEventListener { + @Override + public DatabaseAsyncClient.Builder onCreated( + @NonNull BeanCreatedEvent event + ) { + DatabaseAsyncClient.Builder builder = event.getBean(); + builder.endpoint(DatabaseFactoryTest.ASYNC_ENDPOINT); + return builder; + } + } + +}