From dc78468f027944b66396fd5b89abd111e219e54a Mon Sep 17 00:00:00 2001 From: Georgios Andrianakis Date: Thu, 14 Sep 2023 18:01:20 +0300 Subject: [PATCH] Properly initialize reactive Pool beans We introduce an injection point to the synthetic bean creation process thus giving Arc all the declarative context it needs in order to ensure proper bean creation order --- .../deployment/VertxPoolBuildItem.java | 16 +++--- .../client/deployment/DB2PoolBuildItem.java | 10 ++-- .../ReactiveDB2ClientProcessor.java | 34 ++++++++--- .../db2/client/runtime/DB2PoolRecorder.java | 56 +++++++++++------- .../client/deployment/MSSQLPoolBuildItem.java | 10 ++-- .../ReactiveMSSQLClientProcessor.java | 33 ++++++++--- .../client/runtime/MSSQLPoolRecorder.java | 56 ++++++++++++------ .../client/deployment/MySQLPoolBuildItem.java | 10 ++-- .../ReactiveMySQLClientProcessor.java | 33 ++++++++--- .../client/runtime/MySQLPoolRecorder.java | 57 ++++++++++++------- .../deployment/OraclePoolBuildItem.java | 10 ++-- .../ReactiveOracleClientProcessor.java | 34 ++++++++--- .../client/runtime/OraclePoolRecorder.java | 57 ++++++++++++------- .../pg/client/deployment/PgPoolBuildItem.java | 10 ++-- .../deployment/ReactivePgClientProcessor.java | 33 ++++++++--- .../pg/client/runtime/PgPoolRecorder.java | 57 ++++++++++++------- 16 files changed, 353 insertions(+), 163 deletions(-) diff --git a/extensions/reactive-datasource/deployment/src/main/java/io/quarkus/reactive/datasource/deployment/VertxPoolBuildItem.java b/extensions/reactive-datasource/deployment/src/main/java/io/quarkus/reactive/datasource/deployment/VertxPoolBuildItem.java index 01e475b64c66f..ced3f83275f99 100644 --- a/extensions/reactive-datasource/deployment/src/main/java/io/quarkus/reactive/datasource/deployment/VertxPoolBuildItem.java +++ b/extensions/reactive-datasource/deployment/src/main/java/io/quarkus/reactive/datasource/deployment/VertxPoolBuildItem.java @@ -10,28 +10,26 @@ * If you inject this build item when recording runtime init template calls, you are guaranteed the Pool configuration * has been injected and Pools can be created. */ +@Deprecated(forRemoval = true) public final class VertxPoolBuildItem extends MultiBuildItem { - private final RuntimeValue vertxPool; - private final String dbKind; - private final boolean isDefault; + public VertxPoolBuildItem() { + } public VertxPoolBuildItem(RuntimeValue vertxPool, String dbKind, boolean isDefault) { - this.vertxPool = vertxPool; - this.dbKind = dbKind; - this.isDefault = isDefault; + } public RuntimeValue getPool() { - return vertxPool; + throw new IllegalStateException("should never be called"); } public String getDbKind() { - return dbKind; + throw new IllegalStateException("should never be called"); } public boolean isDefault() { - return isDefault; + throw new IllegalStateException("should never be called"); } } diff --git a/extensions/reactive-db2-client/deployment/src/main/java/io/quarkus/reactive/db2/client/deployment/DB2PoolBuildItem.java b/extensions/reactive-db2-client/deployment/src/main/java/io/quarkus/reactive/db2/client/deployment/DB2PoolBuildItem.java index 95b5c18a89872..a63b88b6c2796 100644 --- a/extensions/reactive-db2-client/deployment/src/main/java/io/quarkus/reactive/db2/client/deployment/DB2PoolBuildItem.java +++ b/extensions/reactive-db2-client/deployment/src/main/java/io/quarkus/reactive/db2/client/deployment/DB2PoolBuildItem.java @@ -1,17 +1,19 @@ package io.quarkus.reactive.db2.client.deployment; +import java.util.function.Function; + +import io.quarkus.arc.SyntheticCreationalContext; import io.quarkus.builder.item.MultiBuildItem; import io.quarkus.datasource.common.runtime.DataSourceUtil; -import io.quarkus.runtime.RuntimeValue; import io.vertx.db2client.DB2Pool; public final class DB2PoolBuildItem extends MultiBuildItem { private final String dataSourceName; - private final RuntimeValue db2Pool; + private final Function, DB2Pool> db2Pool; - public DB2PoolBuildItem(String dataSourceName, RuntimeValue db2Pool) { + public DB2PoolBuildItem(String dataSourceName, Function, DB2Pool> db2Pool) { this.dataSourceName = dataSourceName; this.db2Pool = db2Pool; } @@ -20,7 +22,7 @@ public String getDataSourceName() { return dataSourceName; } - public RuntimeValue getDB2Pool() { + public Function, DB2Pool> getDB2Pool() { return db2Pool; } diff --git a/extensions/reactive-db2-client/deployment/src/main/java/io/quarkus/reactive/db2/client/deployment/ReactiveDB2ClientProcessor.java b/extensions/reactive-db2-client/deployment/src/main/java/io/quarkus/reactive/db2/client/deployment/ReactiveDB2ClientProcessor.java index d20b951f8d517..d21106cfd1baf 100644 --- a/extensions/reactive-db2-client/deployment/src/main/java/io/quarkus/reactive/db2/client/deployment/ReactiveDB2ClientProcessor.java +++ b/extensions/reactive-db2-client/deployment/src/main/java/io/quarkus/reactive/db2/client/deployment/ReactiveDB2ClientProcessor.java @@ -6,15 +6,20 @@ import java.util.Optional; import java.util.Set; import java.util.TreeSet; +import java.util.function.Function; import java.util.function.Predicate; import java.util.stream.Collectors; import jakarta.enterprise.context.ApplicationScoped; +import jakarta.enterprise.inject.Instance; import org.jboss.jandex.AnnotationInstance; +import org.jboss.jandex.ClassType; import org.jboss.jandex.DotName; +import org.jboss.jandex.ParameterizedType; import org.jboss.jandex.Type; +import io.quarkus.arc.SyntheticCreationalContext; import io.quarkus.arc.deployment.SyntheticBeanBuildItem; import io.quarkus.arc.deployment.SyntheticBeanBuildItem.ExtendedBeanConfigurator; import io.quarkus.arc.deployment.UnremovableBeanBuildItem; @@ -51,7 +56,6 @@ import io.quarkus.reactive.db2.client.runtime.DB2PoolRecorder; import io.quarkus.reactive.db2.client.runtime.DB2ServiceBindingConverter; import io.quarkus.reactive.db2.client.runtime.DataSourcesReactiveDB2Config; -import io.quarkus.runtime.RuntimeValue; import io.quarkus.smallrye.health.deployment.spi.HealthBuildItem; import io.quarkus.vertx.core.deployment.EventLoopCountBuildItem; import io.quarkus.vertx.deployment.VertxBuildItem; @@ -60,6 +64,12 @@ class ReactiveDB2ClientProcessor { + private static final ParameterizedType POOL_INJECTION_TYPE = ParameterizedType.create(DotName.createSimple(Instance.class), + new Type[] { ClassType.create(DotName.createSimple(DB2PoolCreator.class.getName())) }, null); + private static final AnnotationInstance[] EMPTY_ANNOTATIONS = new AnnotationInstance[0]; + + private static final DotName REACTIVE_DATASOURCE = DotName.createSimple(ReactiveDataSource.class); + @BuildStep @Record(ExecutionTime.RUNTIME_INIT) ServiceStartBuildItem build(BuildProducer feature, @@ -81,7 +91,7 @@ ServiceStartBuildItem build(BuildProducer feature, feature.produce(new FeatureBuildItem(Feature.REACTIVE_DB2_CLIENT)); for (String dataSourceName : dataSourcesBuildTimeConfig.dataSources().keySet()) { - createPoolIfDefined(recorder, vertx, eventLoopCount, shutdown, db2Pool, vertxPool, syntheticBeans, dataSourceName, + createPoolIfDefined(recorder, vertx, eventLoopCount, shutdown, db2Pool, syntheticBeans, dataSourceName, dataSourcesBuildTimeConfig, dataSourcesRuntimeConfig, dataSourcesReactiveBuildTimeConfig, dataSourcesReactiveRuntimeConfig, dataSourcesReactiveDB2Config, defaultDataSourceDbKindBuildItems, curateOutcomeBuildItem); @@ -90,6 +100,7 @@ ServiceStartBuildItem build(BuildProducer feature, // Enable SSL support by default sslNativeSupport.produce(new ExtensionSslNativeSupportBuildItem(Feature.REACTIVE_DB2_CLIENT)); + vertxPool.produce(new VertxPoolBuildItem()); return new ServiceStartBuildItem("reactive-db2-client"); } @@ -168,7 +179,6 @@ private void createPoolIfDefined(DB2PoolRecorder recorder, EventLoopCountBuildItem eventLoopCount, ShutdownContextBuildItem shutdown, BuildProducer db2Pool, - BuildProducer vertxPool, BuildProducer syntheticBeans, String dataSourceName, DataSourcesBuildTimeConfig dataSourcesBuildTimeConfig, @@ -184,20 +194,21 @@ private void createPoolIfDefined(DB2PoolRecorder recorder, return; } - RuntimeValue pool = recorder.configureDB2Pool(vertx.getVertx(), + Function, DB2Pool> poolFunction = recorder.configureDB2Pool(vertx.getVertx(), eventLoopCount.getEventLoopCount(), dataSourceName, dataSourcesRuntimeConfig, dataSourcesReactiveRuntimeConfig, dataSourcesReactiveDB2Config, shutdown); - db2Pool.produce(new DB2PoolBuildItem(dataSourceName, pool)); + db2Pool.produce(new DB2PoolBuildItem(dataSourceName, poolFunction)); ExtendedBeanConfigurator db2PoolBeanConfigurator = SyntheticBeanBuildItem.configure(DB2Pool.class) .defaultBean() .addType(Pool.class) .scope(ApplicationScoped.class) - .runtimeValue(pool) + .addInjectionPoint(POOL_INJECTION_TYPE, injectionPointAnnotations(dataSourceName)) + .createWith(poolFunction) .unremovable() .setRuntimeInit(); @@ -209,14 +220,21 @@ private void createPoolIfDefined(DB2PoolRecorder recorder, .configure(io.vertx.mutiny.db2client.DB2Pool.class) .defaultBean() .scope(ApplicationScoped.class) - .runtimeValue(recorder.mutinyDB2Pool(pool)) + .addInjectionPoint(POOL_INJECTION_TYPE, injectionPointAnnotations(dataSourceName)) + .createWith(recorder.mutinyDB2Pool(poolFunction)) .setRuntimeInit(); addQualifiers(mutinyDB2PoolConfigurator, dataSourceName); syntheticBeans.produce(mutinyDB2PoolConfigurator.done()); + } - vertxPool.produce(new VertxPoolBuildItem(pool, DatabaseKind.DB2, DataSourceUtil.isDefault(dataSourceName))); + private AnnotationInstance[] injectionPointAnnotations(String dataSourceName) { + if (DataSourceUtil.isDefault(dataSourceName)) { + return EMPTY_ANNOTATIONS; + } + return new AnnotationInstance[] { + AnnotationInstance.builder(REACTIVE_DATASOURCE).add("value", dataSourceName).build() }; } private static boolean isReactiveDB2PoolDefined(DataSourcesBuildTimeConfig dataSourcesBuildTimeConfig, diff --git a/extensions/reactive-db2-client/runtime/src/main/java/io/quarkus/reactive/db2/client/runtime/DB2PoolRecorder.java b/extensions/reactive-db2-client/runtime/src/main/java/io/quarkus/reactive/db2/client/runtime/DB2PoolRecorder.java index 90681e5e63bde..d5e372b88779b 100644 --- a/extensions/reactive-db2-client/runtime/src/main/java/io/quarkus/reactive/db2/client/runtime/DB2PoolRecorder.java +++ b/extensions/reactive-db2-client/runtime/src/main/java/io/quarkus/reactive/db2/client/runtime/DB2PoolRecorder.java @@ -12,13 +12,15 @@ import java.util.List; import java.util.Map; +import java.util.function.Function; import java.util.function.Supplier; import jakarta.enterprise.inject.Instance; +import jakarta.enterprise.util.TypeLiteral; import org.jboss.logging.Logger; -import io.quarkus.arc.Arc; +import io.quarkus.arc.SyntheticCreationalContext; import io.quarkus.credentials.CredentialsProvider; import io.quarkus.credentials.runtime.CredentialsProviderFinder; import io.quarkus.datasource.common.runtime.DataSourceUtil; @@ -44,28 +46,42 @@ public class DB2PoolRecorder { private static final Logger log = Logger.getLogger(DB2PoolRecorder.class); + private static final TypeLiteral> TYPE_LITERAL = new TypeLiteral<>() { + }; - public RuntimeValue configureDB2Pool(RuntimeValue vertx, + public Function, DB2Pool> configureDB2Pool(RuntimeValue vertx, Supplier eventLoopCount, String dataSourceName, DataSourcesRuntimeConfig dataSourcesRuntimeConfig, DataSourcesReactiveRuntimeConfig dataSourcesReactiveRuntimeConfig, DataSourcesReactiveDB2Config dataSourcesReactiveDB2Config, ShutdownContext shutdown) { - - DB2Pool db2Pool = initialize((VertxInternal) vertx.getValue(), - eventLoopCount.get(), - dataSourceName, - dataSourcesRuntimeConfig.dataSources().get(dataSourceName), - dataSourcesReactiveRuntimeConfig.getDataSourceReactiveRuntimeConfig(dataSourceName), - dataSourcesReactiveDB2Config.dataSources().get(dataSourceName).reactive().db2()); - - shutdown.addShutdownTask(db2Pool::close); - return new RuntimeValue<>(db2Pool); + return new Function<>() { + @Override + public DB2Pool apply(SyntheticCreationalContext context) { + DB2Pool db2Pool = initialize((VertxInternal) vertx.getValue(), + eventLoopCount.get(), + dataSourceName, + dataSourcesRuntimeConfig.dataSources().get(dataSourceName), + dataSourcesReactiveRuntimeConfig.getDataSourceReactiveRuntimeConfig(dataSourceName), + dataSourcesReactiveDB2Config.dataSources().get(dataSourceName).reactive().db2(), + context); + + shutdown.addShutdownTask(db2Pool::close); + return db2Pool; + } + }; } - public RuntimeValue mutinyDB2Pool(RuntimeValue db2Pool) { - return new RuntimeValue<>(io.vertx.mutiny.db2client.DB2Pool.newInstance(db2Pool.getValue())); + public Function, io.vertx.mutiny.db2client.DB2Pool> mutinyDB2Pool( + Function, DB2Pool> function) { + return new Function<>() { + @SuppressWarnings("unchecked") + @Override + public io.vertx.mutiny.db2client.DB2Pool apply(SyntheticCreationalContext context) { + return io.vertx.mutiny.db2client.DB2Pool.newInstance(function.apply(context)); + } + }; } private DB2Pool initialize(VertxInternal vertx, @@ -73,14 +89,15 @@ private DB2Pool initialize(VertxInternal vertx, String dataSourceName, DataSourceRuntimeConfig dataSourceRuntimeConfig, DataSourceReactiveRuntimeConfig dataSourceReactiveRuntimeConfig, - DataSourceReactiveDB2Config dataSourceReactiveDB2Config) { + DataSourceReactiveDB2Config dataSourceReactiveDB2Config, + SyntheticCreationalContext context) { PoolOptions poolOptions = toPoolOptions(eventLoopCount, dataSourceRuntimeConfig, dataSourceReactiveRuntimeConfig, dataSourceReactiveDB2Config); DB2ConnectOptions db2ConnectOptions = toConnectOptions(dataSourceName, dataSourceRuntimeConfig, dataSourceReactiveRuntimeConfig, dataSourceReactiveDB2Config); Supplier> databasesSupplier = toDatabasesSupplier(vertx, List.of(db2ConnectOptions), dataSourceRuntimeConfig); - return createPool(vertx, poolOptions, db2ConnectOptions, dataSourceName, databasesSupplier); + return createPool(vertx, poolOptions, db2ConnectOptions, dataSourceName, databasesSupplier, context); } private Supplier> toDatabasesSupplier(Vertx vertx, List db2ConnectOptionsList, @@ -213,12 +230,13 @@ private DB2ConnectOptions toConnectOptions(String dataSourceName, DataSourceRunt } private DB2Pool createPool(Vertx vertx, PoolOptions poolOptions, DB2ConnectOptions dB2ConnectOptions, - String dataSourceName, Supplier> databases) { + String dataSourceName, Supplier> databases, + SyntheticCreationalContext context) { Instance instance; if (DataSourceUtil.isDefault(dataSourceName)) { - instance = Arc.container().select(DB2PoolCreator.class); + instance = context.getInjectedReference(TYPE_LITERAL); } else { - instance = Arc.container().select(DB2PoolCreator.class, + instance = context.getInjectedReference(TYPE_LITERAL, new ReactiveDataSource.ReactiveDataSourceLiteral(dataSourceName)); } if (instance.isResolvable()) { diff --git a/extensions/reactive-mssql-client/deployment/src/main/java/io/quarkus/reactive/mssql/client/deployment/MSSQLPoolBuildItem.java b/extensions/reactive-mssql-client/deployment/src/main/java/io/quarkus/reactive/mssql/client/deployment/MSSQLPoolBuildItem.java index 0eb56a6071d9d..639f59dac3e25 100644 --- a/extensions/reactive-mssql-client/deployment/src/main/java/io/quarkus/reactive/mssql/client/deployment/MSSQLPoolBuildItem.java +++ b/extensions/reactive-mssql-client/deployment/src/main/java/io/quarkus/reactive/mssql/client/deployment/MSSQLPoolBuildItem.java @@ -1,17 +1,19 @@ package io.quarkus.reactive.mssql.client.deployment; +import java.util.function.Function; + +import io.quarkus.arc.SyntheticCreationalContext; import io.quarkus.builder.item.MultiBuildItem; import io.quarkus.datasource.common.runtime.DataSourceUtil; -import io.quarkus.runtime.RuntimeValue; import io.vertx.mssqlclient.MSSQLPool; public final class MSSQLPoolBuildItem extends MultiBuildItem { private final String dataSourceName; - private final RuntimeValue mssqlPool; + private final Function, MSSQLPool> mssqlPool; - public MSSQLPoolBuildItem(String dataSourceName, RuntimeValue mssqlPool) { + public MSSQLPoolBuildItem(String dataSourceName, Function, MSSQLPool> mssqlPool) { this.dataSourceName = dataSourceName; this.mssqlPool = mssqlPool; } @@ -20,7 +22,7 @@ public String getDataSourceName() { return dataSourceName; } - public RuntimeValue getMSSQLPool() { + public Function, MSSQLPool> getMSSQLPool() { return mssqlPool; } diff --git a/extensions/reactive-mssql-client/deployment/src/main/java/io/quarkus/reactive/mssql/client/deployment/ReactiveMSSQLClientProcessor.java b/extensions/reactive-mssql-client/deployment/src/main/java/io/quarkus/reactive/mssql/client/deployment/ReactiveMSSQLClientProcessor.java index 5e5d06baf8bdd..fc29eb683d158 100644 --- a/extensions/reactive-mssql-client/deployment/src/main/java/io/quarkus/reactive/mssql/client/deployment/ReactiveMSSQLClientProcessor.java +++ b/extensions/reactive-mssql-client/deployment/src/main/java/io/quarkus/reactive/mssql/client/deployment/ReactiveMSSQLClientProcessor.java @@ -6,15 +6,20 @@ import java.util.Optional; import java.util.Set; import java.util.TreeSet; +import java.util.function.Function; import java.util.function.Predicate; import java.util.stream.Collectors; import jakarta.enterprise.context.ApplicationScoped; +import jakarta.enterprise.inject.Instance; import org.jboss.jandex.AnnotationInstance; +import org.jboss.jandex.ClassType; import org.jboss.jandex.DotName; +import org.jboss.jandex.ParameterizedType; import org.jboss.jandex.Type; +import io.quarkus.arc.SyntheticCreationalContext; import io.quarkus.arc.deployment.SyntheticBeanBuildItem; import io.quarkus.arc.deployment.SyntheticBeanBuildItem.ExtendedBeanConfigurator; import io.quarkus.arc.deployment.UnremovableBeanBuildItem; @@ -51,7 +56,6 @@ import io.quarkus.reactive.mssql.client.runtime.DataSourcesReactiveMSSQLConfig; import io.quarkus.reactive.mssql.client.runtime.MSSQLPoolRecorder; import io.quarkus.reactive.mssql.client.runtime.MsSQLServiceBindingConverter; -import io.quarkus.runtime.RuntimeValue; import io.quarkus.smallrye.health.deployment.spi.HealthBuildItem; import io.quarkus.vertx.core.deployment.EventLoopCountBuildItem; import io.quarkus.vertx.deployment.VertxBuildItem; @@ -60,6 +64,11 @@ class ReactiveMSSQLClientProcessor { + private static final ParameterizedType POOL_INJECTION_TYPE = ParameterizedType.create(DotName.createSimple(Instance.class), + new Type[] { ClassType.create(DotName.createSimple(MSSQLPoolCreator.class.getName())) }, null); + private static final AnnotationInstance[] EMPTY_ANNOTATIONS = new AnnotationInstance[0]; + private static final DotName REACTIVE_DATASOURCE = DotName.createSimple(ReactiveDataSource.class); + @BuildStep @Record(ExecutionTime.RUNTIME_INIT) ServiceStartBuildItem build(BuildProducer feature, @@ -81,7 +90,7 @@ ServiceStartBuildItem build(BuildProducer feature, feature.produce(new FeatureBuildItem(Feature.REACTIVE_MSSQL_CLIENT)); for (String dataSourceName : dataSourcesBuildTimeConfig.dataSources().keySet()) { - createPoolIfDefined(recorder, vertx, eventLoopCount, shutdown, msSQLPool, vertxPool, syntheticBeans, dataSourceName, + createPoolIfDefined(recorder, vertx, eventLoopCount, shutdown, msSQLPool, syntheticBeans, dataSourceName, dataSourcesBuildTimeConfig, dataSourcesRuntimeConfig, dataSourcesReactiveBuildTimeConfig, dataSourcesReactiveRuntimeConfig, dataSourcesReactiveMSSQLConfig, defaultDataSourceDbKindBuildItems, curateOutcomeBuildItem); @@ -90,6 +99,7 @@ ServiceStartBuildItem build(BuildProducer feature, // Enable SSL support by default sslNativeSupport.produce(new ExtensionSslNativeSupportBuildItem(Feature.REACTIVE_MSSQL_CLIENT)); + vertxPool.produce(new VertxPoolBuildItem()); return new ServiceStartBuildItem("reactive-mssql-client"); } @@ -168,7 +178,6 @@ private void createPoolIfDefined(MSSQLPoolRecorder recorder, EventLoopCountBuildItem eventLoopCount, ShutdownContextBuildItem shutdown, BuildProducer msSQLPool, - BuildProducer vertxPool, BuildProducer syntheticBeans, String dataSourceName, DataSourcesBuildTimeConfig dataSourcesBuildTimeConfig, @@ -184,20 +193,21 @@ private void createPoolIfDefined(MSSQLPoolRecorder recorder, return; } - RuntimeValue pool = recorder.configureMSSQLPool(vertx.getVertx(), + Function, MSSQLPool> poolFunction = recorder.configureMSSQLPool(vertx.getVertx(), eventLoopCount.getEventLoopCount(), dataSourceName, dataSourcesRuntimeConfig, dataSourcesReactiveRuntimeConfig, dataSourcesReactiveMSSQLConfig, shutdown); - msSQLPool.produce(new MSSQLPoolBuildItem(dataSourceName, pool)); + msSQLPool.produce(new MSSQLPoolBuildItem(dataSourceName, poolFunction)); ExtendedBeanConfigurator msSQLPoolBeanConfigurator = SyntheticBeanBuildItem.configure(MSSQLPool.class) .defaultBean() .addType(Pool.class) .scope(ApplicationScoped.class) - .runtimeValue(pool) + .addInjectionPoint(POOL_INJECTION_TYPE, injectionPointAnnotations(dataSourceName)) + .createWith(poolFunction) .unremovable() .setRuntimeInit(); @@ -209,14 +219,21 @@ private void createPoolIfDefined(MSSQLPoolRecorder recorder, .configure(io.vertx.mutiny.mssqlclient.MSSQLPool.class) .defaultBean() .scope(ApplicationScoped.class) - .runtimeValue(recorder.mutinyMSSQLPool(pool)) + .addInjectionPoint(POOL_INJECTION_TYPE, injectionPointAnnotations(dataSourceName)) + .createWith(recorder.mutinyMSSQLPool(poolFunction)) .setRuntimeInit(); addQualifiers(mutinyMSSQLPoolConfigurator, dataSourceName); syntheticBeans.produce(mutinyMSSQLPoolConfigurator.done()); + } - vertxPool.produce(new VertxPoolBuildItem(pool, DatabaseKind.MSSQL, DataSourceUtil.isDefault(dataSourceName))); + private AnnotationInstance[] injectionPointAnnotations(String dataSourceName) { + if (DataSourceUtil.isDefault(dataSourceName)) { + return EMPTY_ANNOTATIONS; + } + return new AnnotationInstance[] { + AnnotationInstance.builder(REACTIVE_DATASOURCE).add("value", dataSourceName).build() }; } private static boolean isReactiveMSSQLPoolDefined(DataSourcesBuildTimeConfig dataSourcesBuildTimeConfig, diff --git a/extensions/reactive-mssql-client/runtime/src/main/java/io/quarkus/reactive/mssql/client/runtime/MSSQLPoolRecorder.java b/extensions/reactive-mssql-client/runtime/src/main/java/io/quarkus/reactive/mssql/client/runtime/MSSQLPoolRecorder.java index 3c9dc91c63deb..dad7ed85e5f86 100644 --- a/extensions/reactive-mssql-client/runtime/src/main/java/io/quarkus/reactive/mssql/client/runtime/MSSQLPoolRecorder.java +++ b/extensions/reactive-mssql-client/runtime/src/main/java/io/quarkus/reactive/mssql/client/runtime/MSSQLPoolRecorder.java @@ -12,13 +12,15 @@ import java.util.List; import java.util.Map; +import java.util.function.Function; import java.util.function.Supplier; import jakarta.enterprise.inject.Instance; +import jakarta.enterprise.util.TypeLiteral; import org.jboss.logging.Logger; -import io.quarkus.arc.Arc; +import io.quarkus.arc.SyntheticCreationalContext; import io.quarkus.credentials.CredentialsProvider; import io.quarkus.credentials.runtime.CredentialsProviderFinder; import io.quarkus.datasource.common.runtime.DataSourceUtil; @@ -43,9 +45,12 @@ @Recorder public class MSSQLPoolRecorder { + private static final TypeLiteral> TYPE_LITERAL = new TypeLiteral<>() { + }; + private static final Logger log = Logger.getLogger(MSSQLPoolRecorder.class); - public RuntimeValue configureMSSQLPool(RuntimeValue vertx, + public Function, MSSQLPool> configureMSSQLPool(RuntimeValue vertx, Supplier eventLoopCount, String dataSourceName, DataSourcesRuntimeConfig dataSourcesRuntimeConfig, @@ -53,33 +58,47 @@ public RuntimeValue configureMSSQLPool(RuntimeValue vertx, DataSourcesReactiveMSSQLConfig dataSourcesReactiveMSSQLConfig, ShutdownContext shutdown) { - MSSQLPool mssqlPool = initialize((VertxInternal) vertx.getValue(), - eventLoopCount.get(), - dataSourceName, - dataSourcesRuntimeConfig.dataSources().get(dataSourceName), - dataSourcesReactiveRuntimeConfig.getDataSourceReactiveRuntimeConfig(dataSourceName), - dataSourcesReactiveMSSQLConfig.dataSources().get(dataSourceName).reactive().mssql()); - - shutdown.addShutdownTask(mssqlPool::close); - return new RuntimeValue<>(mssqlPool); + return new Function<>() { + @Override + public MSSQLPool apply(SyntheticCreationalContext context) { + MSSQLPool pool = initialize((VertxInternal) vertx.getValue(), + eventLoopCount.get(), + dataSourceName, + dataSourcesRuntimeConfig.dataSources().get(dataSourceName), + dataSourcesReactiveRuntimeConfig.getDataSourceReactiveRuntimeConfig(dataSourceName), + dataSourcesReactiveMSSQLConfig.dataSources().get(dataSourceName).reactive().mssql(), + context); + + shutdown.addShutdownTask(pool::close); + return pool; + } + }; } - public RuntimeValue mutinyMSSQLPool(RuntimeValue mssqlPool) { - return new RuntimeValue<>(io.vertx.mutiny.mssqlclient.MSSQLPool.newInstance(mssqlPool.getValue())); + public Function, io.vertx.mutiny.mssqlclient.MSSQLPool> mutinyMSSQLPool( + Function, MSSQLPool> function) { + return new Function, io.vertx.mutiny.mssqlclient.MSSQLPool>() { + @Override + @SuppressWarnings("unchecked") + public io.vertx.mutiny.mssqlclient.MSSQLPool apply(SyntheticCreationalContext context) { + return io.vertx.mutiny.mssqlclient.MSSQLPool.newInstance(function.apply(context)); + } + }; } private MSSQLPool initialize(VertxInternal vertx, Integer eventLoopCount, String dataSourceName, DataSourceRuntimeConfig dataSourceRuntimeConfig, DataSourceReactiveRuntimeConfig dataSourceReactiveRuntimeConfig, - DataSourceReactiveMSSQLConfig dataSourceReactiveMSSQLConfig) { + DataSourceReactiveMSSQLConfig dataSourceReactiveMSSQLConfig, + SyntheticCreationalContext context) { PoolOptions poolOptions = toPoolOptions(eventLoopCount, dataSourceRuntimeConfig, dataSourceReactiveRuntimeConfig, dataSourceReactiveMSSQLConfig); MSSQLConnectOptions mssqlConnectOptions = toMSSQLConnectOptions(dataSourceName, dataSourceRuntimeConfig, dataSourceReactiveRuntimeConfig, dataSourceReactiveMSSQLConfig); Supplier> databasesSupplier = toDatabasesSupplier(vertx, List.of(mssqlConnectOptions), dataSourceRuntimeConfig); - return createPool(vertx, poolOptions, mssqlConnectOptions, dataSourceName, databasesSupplier); + return createPool(vertx, poolOptions, mssqlConnectOptions, dataSourceName, databasesSupplier, context); } private Supplier> toDatabasesSupplier(Vertx vertx, @@ -214,12 +233,13 @@ private MSSQLConnectOptions toMSSQLConnectOptions(String dataSourceName, DataSou } private MSSQLPool createPool(Vertx vertx, PoolOptions poolOptions, MSSQLConnectOptions mSSQLConnectOptions, - String dataSourceName, Supplier> databases) { + String dataSourceName, Supplier> databases, + SyntheticCreationalContext context) { Instance instance; if (DataSourceUtil.isDefault(dataSourceName)) { - instance = Arc.container().select(MSSQLPoolCreator.class); + instance = context.getInjectedReference(TYPE_LITERAL); } else { - instance = Arc.container().select(MSSQLPoolCreator.class, + instance = context.getInjectedReference(TYPE_LITERAL, new ReactiveDataSource.ReactiveDataSourceLiteral(dataSourceName)); } if (instance.isResolvable()) { diff --git a/extensions/reactive-mysql-client/deployment/src/main/java/io/quarkus/reactive/mysql/client/deployment/MySQLPoolBuildItem.java b/extensions/reactive-mysql-client/deployment/src/main/java/io/quarkus/reactive/mysql/client/deployment/MySQLPoolBuildItem.java index b8c40a65cef57..0b64cbf31d0c5 100644 --- a/extensions/reactive-mysql-client/deployment/src/main/java/io/quarkus/reactive/mysql/client/deployment/MySQLPoolBuildItem.java +++ b/extensions/reactive-mysql-client/deployment/src/main/java/io/quarkus/reactive/mysql/client/deployment/MySQLPoolBuildItem.java @@ -1,17 +1,19 @@ package io.quarkus.reactive.mysql.client.deployment; +import java.util.function.Function; + +import io.quarkus.arc.SyntheticCreationalContext; import io.quarkus.builder.item.MultiBuildItem; import io.quarkus.datasource.common.runtime.DataSourceUtil; -import io.quarkus.runtime.RuntimeValue; import io.vertx.mysqlclient.MySQLPool; public final class MySQLPoolBuildItem extends MultiBuildItem { private final String dataSourceName; - private final RuntimeValue mysqlPool; + private final Function, MySQLPool> mysqlPool; - public MySQLPoolBuildItem(String dataSourceName, RuntimeValue mysqlPool) { + public MySQLPoolBuildItem(String dataSourceName, Function, MySQLPool> mysqlPool) { this.dataSourceName = dataSourceName; this.mysqlPool = mysqlPool; } @@ -20,7 +22,7 @@ public String getDataSourceName() { return dataSourceName; } - public RuntimeValue getMySQLPool() { + public Function, MySQLPool> getMySQLPool() { return mysqlPool; } diff --git a/extensions/reactive-mysql-client/deployment/src/main/java/io/quarkus/reactive/mysql/client/deployment/ReactiveMySQLClientProcessor.java b/extensions/reactive-mysql-client/deployment/src/main/java/io/quarkus/reactive/mysql/client/deployment/ReactiveMySQLClientProcessor.java index b512986ade9ee..7f61ab1eb9231 100644 --- a/extensions/reactive-mysql-client/deployment/src/main/java/io/quarkus/reactive/mysql/client/deployment/ReactiveMySQLClientProcessor.java +++ b/extensions/reactive-mysql-client/deployment/src/main/java/io/quarkus/reactive/mysql/client/deployment/ReactiveMySQLClientProcessor.java @@ -6,15 +6,20 @@ import java.util.Optional; import java.util.Set; import java.util.TreeSet; +import java.util.function.Function; import java.util.function.Predicate; import java.util.stream.Collectors; import jakarta.enterprise.context.ApplicationScoped; +import jakarta.enterprise.inject.Instance; import org.jboss.jandex.AnnotationInstance; +import org.jboss.jandex.ClassType; import org.jboss.jandex.DotName; +import org.jboss.jandex.ParameterizedType; import org.jboss.jandex.Type; +import io.quarkus.arc.SyntheticCreationalContext; import io.quarkus.arc.deployment.SyntheticBeanBuildItem; import io.quarkus.arc.deployment.SyntheticBeanBuildItem.ExtendedBeanConfigurator; import io.quarkus.arc.deployment.UnremovableBeanBuildItem; @@ -51,7 +56,6 @@ import io.quarkus.reactive.mysql.client.runtime.DataSourcesReactiveMySQLConfig; import io.quarkus.reactive.mysql.client.runtime.MySQLPoolRecorder; import io.quarkus.reactive.mysql.client.runtime.MySQLServiceBindingConverter; -import io.quarkus.runtime.RuntimeValue; import io.quarkus.smallrye.health.deployment.spi.HealthBuildItem; import io.quarkus.vertx.core.deployment.EventLoopCountBuildItem; import io.quarkus.vertx.deployment.VertxBuildItem; @@ -60,6 +64,11 @@ class ReactiveMySQLClientProcessor { + private static final ParameterizedType POOL_INJECTION_TYPE = ParameterizedType.create(DotName.createSimple(Instance.class), + new Type[] { ClassType.create(DotName.createSimple(MySQLPoolCreator.class.getName())) }, null); + private static final AnnotationInstance[] EMPTY_ANNOTATIONS = new AnnotationInstance[0]; + private static final DotName REACTIVE_DATASOURCE = DotName.createSimple(ReactiveDataSource.class); + @BuildStep @Record(ExecutionTime.RUNTIME_INIT) ServiceStartBuildItem build(BuildProducer feature, @@ -81,7 +90,7 @@ ServiceStartBuildItem build(BuildProducer feature, feature.produce(new FeatureBuildItem(Feature.REACTIVE_MYSQL_CLIENT)); for (String dataSourceName : dataSourcesBuildTimeConfig.dataSources().keySet()) { - createPoolIfDefined(recorder, vertx, eventLoopCount, shutdown, mySQLPool, vertxPool, syntheticBeans, dataSourceName, + createPoolIfDefined(recorder, vertx, eventLoopCount, shutdown, mySQLPool, syntheticBeans, dataSourceName, dataSourcesBuildTimeConfig, dataSourcesRuntimeConfig, dataSourcesReactiveBuildTimeConfig, dataSourcesReactiveRuntimeConfig, dataSourcesReactiveMySQLConfig, defaultDataSourceDbKindBuildItems, curateOutcomeBuildItem); @@ -90,6 +99,7 @@ ServiceStartBuildItem build(BuildProducer feature, // Enable SSL support by default sslNativeSupport.produce(new ExtensionSslNativeSupportBuildItem(Feature.REACTIVE_MYSQL_CLIENT)); + vertxPool.produce(new VertxPoolBuildItem()); return new ServiceStartBuildItem("reactive-mysql-client"); } @@ -169,7 +179,6 @@ private void createPoolIfDefined(MySQLPoolRecorder recorder, EventLoopCountBuildItem eventLoopCount, ShutdownContextBuildItem shutdown, BuildProducer mySQLPool, - BuildProducer vertxPool, BuildProducer syntheticBeans, String dataSourceName, DataSourcesBuildTimeConfig dataSourcesBuildTimeConfig, @@ -185,20 +194,21 @@ private void createPoolIfDefined(MySQLPoolRecorder recorder, return; } - RuntimeValue pool = recorder.configureMySQLPool(vertx.getVertx(), + Function, MySQLPool> poolFunction = recorder.configureMySQLPool(vertx.getVertx(), eventLoopCount.getEventLoopCount(), dataSourceName, dataSourcesRuntimeConfig, dataSourcesReactiveRuntimeConfig, dataSourcesReactiveMySQLConfig, shutdown); - mySQLPool.produce(new MySQLPoolBuildItem(dataSourceName, pool)); + mySQLPool.produce(new MySQLPoolBuildItem(dataSourceName, poolFunction)); ExtendedBeanConfigurator mySQLPoolBeanConfigurator = SyntheticBeanBuildItem.configure(MySQLPool.class) .defaultBean() .addType(Pool.class) .scope(ApplicationScoped.class) - .runtimeValue(pool) + .addInjectionPoint(POOL_INJECTION_TYPE, injectionPointAnnotations(dataSourceName)) + .createWith(poolFunction) .unremovable() .setRuntimeInit(); @@ -210,14 +220,21 @@ private void createPoolIfDefined(MySQLPoolRecorder recorder, .configure(io.vertx.mutiny.mysqlclient.MySQLPool.class) .defaultBean() .scope(ApplicationScoped.class) - .runtimeValue(recorder.mutinyMySQLPool(pool)) + .addInjectionPoint(POOL_INJECTION_TYPE, injectionPointAnnotations(dataSourceName)) + .createWith(recorder.mutinyMySQLPool(poolFunction)) .setRuntimeInit(); addQualifiers(mutinyMySQLPoolConfigurator, dataSourceName); syntheticBeans.produce(mutinyMySQLPoolConfigurator.done()); + } - vertxPool.produce(new VertxPoolBuildItem(pool, DatabaseKind.MYSQL, DataSourceUtil.isDefault(dataSourceName))); + private AnnotationInstance[] injectionPointAnnotations(String dataSourceName) { + if (DataSourceUtil.isDefault(dataSourceName)) { + return EMPTY_ANNOTATIONS; + } + return new AnnotationInstance[] { + AnnotationInstance.builder(REACTIVE_DATASOURCE).add("value", dataSourceName).build() }; } private static boolean isReactiveMySQLPoolDefined(DataSourcesBuildTimeConfig dataSourcesBuildTimeConfig, diff --git a/extensions/reactive-mysql-client/runtime/src/main/java/io/quarkus/reactive/mysql/client/runtime/MySQLPoolRecorder.java b/extensions/reactive-mysql-client/runtime/src/main/java/io/quarkus/reactive/mysql/client/runtime/MySQLPoolRecorder.java index b3db354d08583..8b0d101285326 100644 --- a/extensions/reactive-mysql-client/runtime/src/main/java/io/quarkus/reactive/mysql/client/runtime/MySQLPoolRecorder.java +++ b/extensions/reactive-mysql-client/runtime/src/main/java/io/quarkus/reactive/mysql/client/runtime/MySQLPoolRecorder.java @@ -14,11 +14,13 @@ import java.util.List; import java.util.Map; import java.util.concurrent.TimeUnit; +import java.util.function.Function; import java.util.function.Supplier; import jakarta.enterprise.inject.Instance; +import jakarta.enterprise.util.TypeLiteral; -import io.quarkus.arc.Arc; +import io.quarkus.arc.SyntheticCreationalContext; import io.quarkus.credentials.CredentialsProvider; import io.quarkus.credentials.runtime.CredentialsProviderFinder; import io.quarkus.datasource.common.runtime.DataSourceUtil; @@ -44,27 +46,42 @@ @Recorder public class MySQLPoolRecorder { - public RuntimeValue configureMySQLPool(RuntimeValue vertx, + private static final TypeLiteral> TYPE_LITERAL = new TypeLiteral<>() { + }; + + public Function, MySQLPool> configureMySQLPool(RuntimeValue vertx, Supplier eventLoopCount, String dataSourceName, DataSourcesRuntimeConfig dataSourcesRuntimeConfig, DataSourcesReactiveRuntimeConfig dataSourcesReactiveRuntimeConfig, DataSourcesReactiveMySQLConfig dataSourcesReactiveMySQLConfig, ShutdownContext shutdown) { - - MySQLPool mysqlPool = initialize((VertxInternal) vertx.getValue(), - eventLoopCount.get(), - dataSourceName, - dataSourcesRuntimeConfig.dataSources().get(dataSourceName), - dataSourcesReactiveRuntimeConfig.getDataSourceReactiveRuntimeConfig(dataSourceName), - dataSourcesReactiveMySQLConfig.dataSources().get(dataSourceName).reactive().mysql()); - - shutdown.addShutdownTask(mysqlPool::close); - return new RuntimeValue<>(mysqlPool); + return new Function<>() { + @Override + public MySQLPool apply(SyntheticCreationalContext context) { + MySQLPool pool = initialize((VertxInternal) vertx.getValue(), + eventLoopCount.get(), + dataSourceName, + dataSourcesRuntimeConfig.dataSources().get(dataSourceName), + dataSourcesReactiveRuntimeConfig.getDataSourceReactiveRuntimeConfig(dataSourceName), + dataSourcesReactiveMySQLConfig.dataSources().get(dataSourceName).reactive().mysql(), + context); + + shutdown.addShutdownTask(pool::close); + return pool; + } + }; } - public RuntimeValue mutinyMySQLPool(RuntimeValue mysqlPool) { - return new RuntimeValue<>(io.vertx.mutiny.mysqlclient.MySQLPool.newInstance(mysqlPool.getValue())); + public Function, io.vertx.mutiny.mysqlclient.MySQLPool> mutinyMySQLPool( + Function, MySQLPool> function) { + return new Function<>() { + @Override + @SuppressWarnings("unchecked") + public io.vertx.mutiny.mysqlclient.MySQLPool apply(SyntheticCreationalContext context) { + return io.vertx.mutiny.mysqlclient.MySQLPool.newInstance(function.apply(context)); + } + }; } private MySQLPool initialize(VertxInternal vertx, @@ -72,14 +89,15 @@ private MySQLPool initialize(VertxInternal vertx, String dataSourceName, DataSourceRuntimeConfig dataSourceRuntimeConfig, DataSourceReactiveRuntimeConfig dataSourceReactiveRuntimeConfig, - DataSourceReactiveMySQLConfig dataSourceReactiveMySQLConfig) { + DataSourceReactiveMySQLConfig dataSourceReactiveMySQLConfig, + SyntheticCreationalContext context) { PoolOptions poolOptions = toPoolOptions(eventLoopCount, dataSourceRuntimeConfig, dataSourceReactiveRuntimeConfig, dataSourceReactiveMySQLConfig); List mySQLConnectOptions = toMySQLConnectOptions(dataSourceName, dataSourceRuntimeConfig, dataSourceReactiveRuntimeConfig, dataSourceReactiveMySQLConfig); Supplier> databasesSupplier = toDatabasesSupplier(vertx, mySQLConnectOptions, dataSourceRuntimeConfig); - return createPool(vertx, poolOptions, mySQLConnectOptions, dataSourceName, databasesSupplier); + return createPool(vertx, poolOptions, mySQLConnectOptions, dataSourceName, databasesSupplier, context); } private Supplier> toDatabasesSupplier(Vertx vertx, @@ -232,12 +250,13 @@ private List toMySQLConnectOptions(String dataSourceName, } private MySQLPool createPool(Vertx vertx, PoolOptions poolOptions, List mySQLConnectOptionsList, - String dataSourceName, Supplier> databases) { + String dataSourceName, Supplier> databases, + SyntheticCreationalContext context) { Instance instance; if (DataSourceUtil.isDefault(dataSourceName)) { - instance = Arc.container().select(MySQLPoolCreator.class); + instance = context.getInjectedReference(TYPE_LITERAL); } else { - instance = Arc.container().select(MySQLPoolCreator.class, + instance = context.getInjectedReference(TYPE_LITERAL, new ReactiveDataSource.ReactiveDataSourceLiteral(dataSourceName)); } if (instance.isResolvable()) { diff --git a/extensions/reactive-oracle-client/deployment/src/main/java/io/quarkus/reactive/oracle/client/deployment/OraclePoolBuildItem.java b/extensions/reactive-oracle-client/deployment/src/main/java/io/quarkus/reactive/oracle/client/deployment/OraclePoolBuildItem.java index 4a8a264324cfe..a7bba6abd8c71 100644 --- a/extensions/reactive-oracle-client/deployment/src/main/java/io/quarkus/reactive/oracle/client/deployment/OraclePoolBuildItem.java +++ b/extensions/reactive-oracle-client/deployment/src/main/java/io/quarkus/reactive/oracle/client/deployment/OraclePoolBuildItem.java @@ -1,17 +1,19 @@ package io.quarkus.reactive.oracle.client.deployment; +import java.util.function.Function; + +import io.quarkus.arc.SyntheticCreationalContext; import io.quarkus.builder.item.MultiBuildItem; import io.quarkus.datasource.common.runtime.DataSourceUtil; -import io.quarkus.runtime.RuntimeValue; import io.vertx.oracleclient.OraclePool; public final class OraclePoolBuildItem extends MultiBuildItem { private final String dataSourceName; - private final RuntimeValue oraclePool; + private final Function, OraclePool> oraclePool; - public OraclePoolBuildItem(String dataSourceName, RuntimeValue oraclePool) { + public OraclePoolBuildItem(String dataSourceName, Function, OraclePool> oraclePool) { this.dataSourceName = dataSourceName; this.oraclePool = oraclePool; } @@ -20,7 +22,7 @@ public String getDataSourceName() { return dataSourceName; } - public RuntimeValue getOraclePool() { + public Function, OraclePool> getOraclePool() { return oraclePool; } diff --git a/extensions/reactive-oracle-client/deployment/src/main/java/io/quarkus/reactive/oracle/client/deployment/ReactiveOracleClientProcessor.java b/extensions/reactive-oracle-client/deployment/src/main/java/io/quarkus/reactive/oracle/client/deployment/ReactiveOracleClientProcessor.java index 25918da0fca34..a82812d3d8409 100644 --- a/extensions/reactive-oracle-client/deployment/src/main/java/io/quarkus/reactive/oracle/client/deployment/ReactiveOracleClientProcessor.java +++ b/extensions/reactive-oracle-client/deployment/src/main/java/io/quarkus/reactive/oracle/client/deployment/ReactiveOracleClientProcessor.java @@ -6,15 +6,20 @@ import java.util.Optional; import java.util.Set; import java.util.TreeSet; +import java.util.function.Function; import java.util.function.Predicate; import java.util.stream.Collectors; import jakarta.enterprise.context.ApplicationScoped; +import jakarta.enterprise.inject.Instance; import org.jboss.jandex.AnnotationInstance; +import org.jboss.jandex.ClassType; import org.jboss.jandex.DotName; +import org.jboss.jandex.ParameterizedType; import org.jboss.jandex.Type; +import io.quarkus.arc.SyntheticCreationalContext; import io.quarkus.arc.deployment.SyntheticBeanBuildItem; import io.quarkus.arc.deployment.SyntheticBeanBuildItem.ExtendedBeanConfigurator; import io.quarkus.arc.deployment.UnremovableBeanBuildItem; @@ -51,7 +56,6 @@ import io.quarkus.reactive.oracle.client.runtime.DataSourcesReactiveOracleConfig; import io.quarkus.reactive.oracle.client.runtime.OraclePoolRecorder; import io.quarkus.reactive.oracle.client.runtime.OracleServiceBindingConverter; -import io.quarkus.runtime.RuntimeValue; import io.quarkus.smallrye.health.deployment.spi.HealthBuildItem; import io.quarkus.vertx.core.deployment.EventLoopCountBuildItem; import io.quarkus.vertx.deployment.VertxBuildItem; @@ -60,6 +64,11 @@ class ReactiveOracleClientProcessor { + private static final ParameterizedType POOL_INJECTION_TYPE = ParameterizedType.create(DotName.createSimple(Instance.class), + new Type[] { ClassType.create(DotName.createSimple(OraclePoolCreator.class.getName())) }, null); + private static final AnnotationInstance[] EMPTY_ANNOTATIONS = new AnnotationInstance[0]; + private static final DotName REACTIVE_DATASOURCE = DotName.createSimple(ReactiveDataSource.class); + @BuildStep @Record(ExecutionTime.RUNTIME_INIT) ServiceStartBuildItem build(BuildProducer feature, @@ -81,7 +90,7 @@ ServiceStartBuildItem build(BuildProducer feature, feature.produce(new FeatureBuildItem(Feature.REACTIVE_ORACLE_CLIENT)); for (String dataSourceName : dataSourcesBuildTimeConfig.dataSources().keySet()) { - createPoolIfDefined(recorder, vertx, eventLoopCount, shutdown, oraclePool, vertxPool, syntheticBeans, + createPoolIfDefined(recorder, vertx, eventLoopCount, shutdown, oraclePool, syntheticBeans, dataSourceName, dataSourcesBuildTimeConfig, dataSourcesRuntimeConfig, dataSourcesReactiveBuildTimeConfig, dataSourcesReactiveRuntimeConfig, dataSourcesReactiveOracleConfig, defaultDataSourceDbKindBuildItems, @@ -91,6 +100,7 @@ ServiceStartBuildItem build(BuildProducer feature, // Enable SSL support by default sslNativeSupport.produce(new ExtensionSslNativeSupportBuildItem(Feature.REACTIVE_ORACLE_CLIENT)); + vertxPool.produce(new VertxPoolBuildItem()); return new ServiceStartBuildItem("reactive-oracle-client"); } @@ -169,7 +179,6 @@ private void createPoolIfDefined(OraclePoolRecorder recorder, EventLoopCountBuildItem eventLoopCount, ShutdownContextBuildItem shutdown, BuildProducer oraclePool, - BuildProducer vertxPool, BuildProducer syntheticBeans, String dataSourceName, DataSourcesBuildTimeConfig dataSourcesBuildTimeConfig, @@ -185,20 +194,22 @@ private void createPoolIfDefined(OraclePoolRecorder recorder, return; } - RuntimeValue pool = recorder.configureOraclePool(vertx.getVertx(), + Function, OraclePool> poolFunction = recorder.configureOraclePool( + vertx.getVertx(), eventLoopCount.getEventLoopCount(), dataSourceName, dataSourcesRuntimeConfig, dataSourcesReactiveRuntimeConfig, dataSourcesReactiveOracleConfig, shutdown); - oraclePool.produce(new OraclePoolBuildItem(dataSourceName, pool)); + oraclePool.produce(new OraclePoolBuildItem(dataSourceName, poolFunction)); ExtendedBeanConfigurator oraclePoolBeanConfigurator = SyntheticBeanBuildItem.configure(OraclePool.class) .defaultBean() .addType(Pool.class) .scope(ApplicationScoped.class) - .runtimeValue(pool) + .addInjectionPoint(POOL_INJECTION_TYPE, injectionPointAnnotations(dataSourceName)) + .createWith(poolFunction) .unremovable() .setRuntimeInit(); @@ -210,14 +221,21 @@ private void createPoolIfDefined(OraclePoolRecorder recorder, .configure(io.vertx.mutiny.oracleclient.OraclePool.class) .defaultBean() .scope(ApplicationScoped.class) - .runtimeValue(recorder.mutinyOraclePool(pool)) + .addInjectionPoint(POOL_INJECTION_TYPE, injectionPointAnnotations(dataSourceName)) + .createWith(recorder.mutinyOraclePool(poolFunction)) .setRuntimeInit(); addQualifiers(mutinyOraclePoolConfigurator, dataSourceName); syntheticBeans.produce(mutinyOraclePoolConfigurator.done()); + } - vertxPool.produce(new VertxPoolBuildItem(pool, DatabaseKind.ORACLE, DataSourceUtil.isDefault(dataSourceName))); + private AnnotationInstance[] injectionPointAnnotations(String dataSourceName) { + if (DataSourceUtil.isDefault(dataSourceName)) { + return EMPTY_ANNOTATIONS; + } + return new AnnotationInstance[] { + AnnotationInstance.builder(REACTIVE_DATASOURCE).add("value", dataSourceName).build() }; } private static boolean isReactiveOraclePoolDefined(DataSourcesBuildTimeConfig dataSourcesBuildTimeConfig, diff --git a/extensions/reactive-oracle-client/runtime/src/main/java/io/quarkus/reactive/oracle/client/runtime/OraclePoolRecorder.java b/extensions/reactive-oracle-client/runtime/src/main/java/io/quarkus/reactive/oracle/client/runtime/OraclePoolRecorder.java index e217cc1a818af..dc49a6eafd261 100644 --- a/extensions/reactive-oracle-client/runtime/src/main/java/io/quarkus/reactive/oracle/client/runtime/OraclePoolRecorder.java +++ b/extensions/reactive-oracle-client/runtime/src/main/java/io/quarkus/reactive/oracle/client/runtime/OraclePoolRecorder.java @@ -6,13 +6,15 @@ import java.util.List; import java.util.Map; +import java.util.function.Function; import java.util.function.Supplier; import jakarta.enterprise.inject.Instance; +import jakarta.enterprise.util.TypeLiteral; import org.jboss.logging.Logger; -import io.quarkus.arc.Arc; +import io.quarkus.arc.SyntheticCreationalContext; import io.quarkus.credentials.CredentialsProvider; import io.quarkus.credentials.runtime.CredentialsProviderFinder; import io.quarkus.datasource.common.runtime.DataSourceUtil; @@ -38,29 +40,44 @@ @Recorder public class OraclePoolRecorder { + private static final TypeLiteral> TYPE_LITERAL = new TypeLiteral<>() { + }; + private static final Logger log = Logger.getLogger(OraclePoolRecorder.class); - public RuntimeValue configureOraclePool(RuntimeValue vertx, + public Function, OraclePool> configureOraclePool(RuntimeValue vertx, Supplier eventLoopCount, String dataSourceName, DataSourcesRuntimeConfig dataSourcesRuntimeConfig, DataSourcesReactiveRuntimeConfig dataSourcesReactiveRuntimeConfig, DataSourcesReactiveOracleConfig dataSourcesReactiveOracleConfig, ShutdownContext shutdown) { - - OraclePool oraclePool = initialize((VertxInternal) vertx.getValue(), - eventLoopCount.get(), - dataSourceName, - dataSourcesRuntimeConfig.dataSources().get(dataSourceName), - dataSourcesReactiveRuntimeConfig.getDataSourceReactiveRuntimeConfig(dataSourceName), - dataSourcesReactiveOracleConfig.dataSources().get(dataSourceName).reactive().oracle()); - - shutdown.addShutdownTask(oraclePool::close); - return new RuntimeValue<>(oraclePool); + return new Function, OraclePool>() { + @Override + public OraclePool apply(SyntheticCreationalContext context) { + OraclePool pool = initialize((VertxInternal) vertx.getValue(), + eventLoopCount.get(), + dataSourceName, + dataSourcesRuntimeConfig.dataSources().get(dataSourceName), + dataSourcesReactiveRuntimeConfig.getDataSourceReactiveRuntimeConfig(dataSourceName), + dataSourcesReactiveOracleConfig.dataSources().get(dataSourceName).reactive().oracle(), + context); + + shutdown.addShutdownTask(pool::close); + return pool; + } + }; } - public RuntimeValue mutinyOraclePool(RuntimeValue oraclePool) { - return new RuntimeValue<>(io.vertx.mutiny.oracleclient.OraclePool.newInstance(oraclePool.getValue())); + public Function, io.vertx.mutiny.oracleclient.OraclePool> mutinyOraclePool( + Function, OraclePool> function) { + return new Function<>() { + @SuppressWarnings("unchecked") + @Override + public io.vertx.mutiny.oracleclient.OraclePool apply(SyntheticCreationalContext context) { + return io.vertx.mutiny.oracleclient.OraclePool.newInstance(function.apply(context)); + } + }; } private OraclePool initialize(VertxInternal vertx, @@ -68,14 +85,15 @@ private OraclePool initialize(VertxInternal vertx, String dataSourceName, DataSourceRuntimeConfig dataSourceRuntimeConfig, DataSourceReactiveRuntimeConfig dataSourceReactiveRuntimeConfig, - DataSourceReactiveOracleConfig dataSourceReactiveOracleConfig) { + DataSourceReactiveOracleConfig dataSourceReactiveOracleConfig, + SyntheticCreationalContext context) { PoolOptions poolOptions = toPoolOptions(eventLoopCount, dataSourceRuntimeConfig, dataSourceReactiveRuntimeConfig, dataSourceReactiveOracleConfig); OracleConnectOptions oracleConnectOptions = toOracleConnectOptions(dataSourceName, dataSourceRuntimeConfig, dataSourceReactiveRuntimeConfig, dataSourceReactiveOracleConfig); Supplier> databasesSupplier = toDatabasesSupplier(vertx, List.of(oracleConnectOptions), dataSourceRuntimeConfig); - return createPool(vertx, poolOptions, oracleConnectOptions, dataSourceName, databasesSupplier); + return createPool(vertx, poolOptions, oracleConnectOptions, dataSourceName, databasesSupplier, context); } private Supplier> toDatabasesSupplier(Vertx vertx, @@ -185,12 +203,13 @@ private OracleConnectOptions toOracleConnectOptions(String dataSourceName, DataS } private OraclePool createPool(Vertx vertx, PoolOptions poolOptions, OracleConnectOptions oracleConnectOptions, - String dataSourceName, Supplier> databases) { + String dataSourceName, Supplier> databases, + SyntheticCreationalContext context) { Instance instance; if (DataSourceUtil.isDefault(dataSourceName)) { - instance = Arc.container().select(OraclePoolCreator.class); + instance = context.getInjectedReference(TYPE_LITERAL); } else { - instance = Arc.container().select(OraclePoolCreator.class, + instance = context.getInjectedReference(TYPE_LITERAL, new ReactiveDataSource.ReactiveDataSourceLiteral(dataSourceName)); } if (instance.isResolvable()) { diff --git a/extensions/reactive-pg-client/deployment/src/main/java/io/quarkus/reactive/pg/client/deployment/PgPoolBuildItem.java b/extensions/reactive-pg-client/deployment/src/main/java/io/quarkus/reactive/pg/client/deployment/PgPoolBuildItem.java index 518bf7df817a8..0d19c802ead05 100644 --- a/extensions/reactive-pg-client/deployment/src/main/java/io/quarkus/reactive/pg/client/deployment/PgPoolBuildItem.java +++ b/extensions/reactive-pg-client/deployment/src/main/java/io/quarkus/reactive/pg/client/deployment/PgPoolBuildItem.java @@ -1,17 +1,19 @@ package io.quarkus.reactive.pg.client.deployment; +import java.util.function.Function; + +import io.quarkus.arc.SyntheticCreationalContext; import io.quarkus.builder.item.MultiBuildItem; import io.quarkus.datasource.common.runtime.DataSourceUtil; -import io.quarkus.runtime.RuntimeValue; import io.vertx.pgclient.PgPool; public final class PgPoolBuildItem extends MultiBuildItem { private final String dataSourceName; - private final RuntimeValue pgPool; + private final Function, PgPool> pgPool; - public PgPoolBuildItem(String dataSourceName, RuntimeValue pgPool) { + public PgPoolBuildItem(String dataSourceName, Function, PgPool> pgPool) { this.dataSourceName = dataSourceName; this.pgPool = pgPool; } @@ -20,7 +22,7 @@ public String getDataSourceName() { return dataSourceName; } - public RuntimeValue getPgPool() { + public Function, PgPool> getPgPool() { return pgPool; } diff --git a/extensions/reactive-pg-client/deployment/src/main/java/io/quarkus/reactive/pg/client/deployment/ReactivePgClientProcessor.java b/extensions/reactive-pg-client/deployment/src/main/java/io/quarkus/reactive/pg/client/deployment/ReactivePgClientProcessor.java index 77690e5430e3d..e1db7a21692b0 100644 --- a/extensions/reactive-pg-client/deployment/src/main/java/io/quarkus/reactive/pg/client/deployment/ReactivePgClientProcessor.java +++ b/extensions/reactive-pg-client/deployment/src/main/java/io/quarkus/reactive/pg/client/deployment/ReactivePgClientProcessor.java @@ -6,15 +6,20 @@ import java.util.Optional; import java.util.Set; import java.util.TreeSet; +import java.util.function.Function; import java.util.function.Predicate; import java.util.stream.Collectors; import jakarta.enterprise.context.ApplicationScoped; +import jakarta.enterprise.inject.Instance; import org.jboss.jandex.AnnotationInstance; +import org.jboss.jandex.ClassType; import org.jboss.jandex.DotName; +import org.jboss.jandex.ParameterizedType; import org.jboss.jandex.Type; +import io.quarkus.arc.SyntheticCreationalContext; import io.quarkus.arc.deployment.SyntheticBeanBuildItem; import io.quarkus.arc.deployment.SyntheticBeanBuildItem.ExtendedBeanConfigurator; import io.quarkus.arc.deployment.UnremovableBeanBuildItem; @@ -52,7 +57,6 @@ import io.quarkus.reactive.pg.client.runtime.DataSourcesReactivePostgreSQLConfig; import io.quarkus.reactive.pg.client.runtime.PgPoolRecorder; import io.quarkus.reactive.pg.client.runtime.PostgreSQLServiceBindingConverter; -import io.quarkus.runtime.RuntimeValue; import io.quarkus.smallrye.health.deployment.spi.HealthBuildItem; import io.quarkus.vertx.core.deployment.EventLoopCountBuildItem; import io.quarkus.vertx.deployment.VertxBuildItem; @@ -61,6 +65,11 @@ class ReactivePgClientProcessor { + private static final ParameterizedType POOL_INJECTION_TYPE = ParameterizedType.create(DotName.createSimple(Instance.class), + new Type[] { ClassType.create(DotName.createSimple(PgPoolCreator.class.getName())) }, null); + private static final AnnotationInstance[] EMPTY_ANNOTATIONS = new AnnotationInstance[0]; + private static final DotName REACTIVE_DATASOURCE = DotName.createSimple(ReactiveDataSource.class); + @BuildStep NativeImageConfigBuildItem config() { return NativeImageConfigBuildItem.builder().addRuntimeInitializedClass("io.vertx.pgclient.impl.codec.StartupMessage") @@ -93,7 +102,7 @@ ServiceStartBuildItem build(BuildProducer feature, feature.produce(new FeatureBuildItem(Feature.REACTIVE_PG_CLIENT)); for (String dataSourceName : dataSourcesBuildTimeConfig.dataSources().keySet()) { - createPoolIfDefined(recorder, vertx, eventLoopCount, shutdown, pgPool, vertxPool, syntheticBeans, dataSourceName, + createPoolIfDefined(recorder, vertx, eventLoopCount, shutdown, pgPool, syntheticBeans, dataSourceName, dataSourcesBuildTimeConfig, dataSourcesRuntimeConfig, dataSourcesReactiveBuildTimeConfig, dataSourcesReactiveRuntimeConfig, dataSourcesReactivePostgreSQLConfig, defaultDataSourceDbKindBuildItems, curateOutcomeBuildItem); @@ -102,6 +111,7 @@ ServiceStartBuildItem build(BuildProducer feature, // Enable SSL support by default sslNativeSupport.produce(new ExtensionSslNativeSupportBuildItem(Feature.REACTIVE_PG_CLIENT)); + vertxPool.produce(new VertxPoolBuildItem()); return new ServiceStartBuildItem("reactive-pg-client"); } @@ -174,7 +184,6 @@ private void createPoolIfDefined(PgPoolRecorder recorder, EventLoopCountBuildItem eventLoopCount, ShutdownContextBuildItem shutdown, BuildProducer pgPool, - BuildProducer vertxPool, BuildProducer syntheticBeans, String dataSourceName, DataSourcesBuildTimeConfig dataSourcesBuildTimeConfig, @@ -190,20 +199,21 @@ private void createPoolIfDefined(PgPoolRecorder recorder, return; } - RuntimeValue pool = recorder.configurePgPool(vertx.getVertx(), + Function, PgPool> poolFunction = recorder.configurePgPool(vertx.getVertx(), eventLoopCount.getEventLoopCount(), dataSourceName, dataSourcesRuntimeConfig, dataSourcesReactiveRuntimeConfig, dataSourcesReactivePostgreSQLConfig, shutdown); - pgPool.produce(new PgPoolBuildItem(dataSourceName, pool)); + pgPool.produce(new PgPoolBuildItem(dataSourceName, poolFunction)); ExtendedBeanConfigurator pgPoolBeanConfigurator = SyntheticBeanBuildItem.configure(PgPool.class) .defaultBean() .addType(Pool.class) .scope(ApplicationScoped.class) - .runtimeValue(pool) + .addInjectionPoint(POOL_INJECTION_TYPE, injectionPointAnnotations(dataSourceName)) + .createWith(poolFunction) .unremovable() .setRuntimeInit(); @@ -215,14 +225,21 @@ private void createPoolIfDefined(PgPoolRecorder recorder, .configure(io.vertx.mutiny.pgclient.PgPool.class) .defaultBean() .scope(ApplicationScoped.class) - .runtimeValue(recorder.mutinyPgPool(pool)) + .addInjectionPoint(POOL_INJECTION_TYPE, injectionPointAnnotations(dataSourceName)) + .createWith(recorder.mutinyPgPool(poolFunction)) .setRuntimeInit(); addQualifiers(mutinyPgPoolConfigurator, dataSourceName); syntheticBeans.produce(mutinyPgPoolConfigurator.done()); + } - vertxPool.produce(new VertxPoolBuildItem(pool, DatabaseKind.POSTGRESQL, DataSourceUtil.isDefault(dataSourceName))); + private AnnotationInstance[] injectionPointAnnotations(String dataSourceName) { + if (DataSourceUtil.isDefault(dataSourceName)) { + return EMPTY_ANNOTATIONS; + } + return new AnnotationInstance[] { + AnnotationInstance.builder(REACTIVE_DATASOURCE).add("value", dataSourceName).build() }; } private static boolean isReactivePostgreSQLPoolDefined(DataSourcesBuildTimeConfig dataSourcesBuildTimeConfig, diff --git a/extensions/reactive-pg-client/runtime/src/main/java/io/quarkus/reactive/pg/client/runtime/PgPoolRecorder.java b/extensions/reactive-pg-client/runtime/src/main/java/io/quarkus/reactive/pg/client/runtime/PgPoolRecorder.java index 7988a6f86afa7..053c68a56708f 100644 --- a/extensions/reactive-pg-client/runtime/src/main/java/io/quarkus/reactive/pg/client/runtime/PgPoolRecorder.java +++ b/extensions/reactive-pg-client/runtime/src/main/java/io/quarkus/reactive/pg/client/runtime/PgPoolRecorder.java @@ -13,11 +13,13 @@ import java.util.ArrayList; import java.util.List; import java.util.Map; +import java.util.function.Function; import java.util.function.Supplier; import jakarta.enterprise.inject.Instance; +import jakarta.enterprise.util.TypeLiteral; -import io.quarkus.arc.Arc; +import io.quarkus.arc.SyntheticCreationalContext; import io.quarkus.credentials.CredentialsProvider; import io.quarkus.credentials.runtime.CredentialsProviderFinder; import io.quarkus.datasource.common.runtime.DataSourceUtil; @@ -43,27 +45,42 @@ @Recorder public class PgPoolRecorder { - public RuntimeValue configurePgPool(RuntimeValue vertx, + private static final TypeLiteral> TYPE_LITERAL = new TypeLiteral<>() { + }; + + public Function, PgPool> configurePgPool(RuntimeValue vertx, Supplier eventLoopCount, String dataSourceName, DataSourcesRuntimeConfig dataSourcesRuntimeConfig, DataSourcesReactiveRuntimeConfig dataSourcesReactiveRuntimeConfig, DataSourcesReactivePostgreSQLConfig dataSourcesReactivePostgreSQLConfig, ShutdownContext shutdown) { - - PgPool pgPool = initialize((VertxInternal) vertx.getValue(), - eventLoopCount.get(), - dataSourceName, - dataSourcesRuntimeConfig.dataSources().get(dataSourceName), - dataSourcesReactiveRuntimeConfig.getDataSourceReactiveRuntimeConfig(dataSourceName), - dataSourcesReactivePostgreSQLConfig.dataSources().get(dataSourceName).reactive().postgresql()); - - shutdown.addShutdownTask(pgPool::close); - return new RuntimeValue<>(pgPool); + return new Function<>() { + @Override + public PgPool apply(SyntheticCreationalContext context) { + PgPool pgPool = initialize((VertxInternal) vertx.getValue(), + eventLoopCount.get(), + dataSourceName, + dataSourcesRuntimeConfig.dataSources().get(dataSourceName), + dataSourcesReactiveRuntimeConfig.getDataSourceReactiveRuntimeConfig(dataSourceName), + dataSourcesReactivePostgreSQLConfig.dataSources().get(dataSourceName).reactive().postgresql(), + context); + + shutdown.addShutdownTask(pgPool::close); + return pgPool; + } + }; } - public RuntimeValue mutinyPgPool(RuntimeValue pgPool) { - return new RuntimeValue<>(io.vertx.mutiny.pgclient.PgPool.newInstance(pgPool.getValue())); + public Function, io.vertx.mutiny.pgclient.PgPool> mutinyPgPool( + Function, PgPool> function) { + return new Function<>() { + @SuppressWarnings("unchecked") + @Override + public io.vertx.mutiny.pgclient.PgPool apply(SyntheticCreationalContext context) { + return io.vertx.mutiny.pgclient.PgPool.newInstance(function.apply(context)); + } + }; } private PgPool initialize(VertxInternal vertx, @@ -71,14 +88,15 @@ private PgPool initialize(VertxInternal vertx, String dataSourceName, DataSourceRuntimeConfig dataSourceRuntimeConfig, DataSourceReactiveRuntimeConfig dataSourceReactiveRuntimeConfig, - DataSourceReactivePostgreSQLConfig dataSourceReactivePostgreSQLConfig) { + DataSourceReactivePostgreSQLConfig dataSourceReactivePostgreSQLConfig, + SyntheticCreationalContext context) { PoolOptions poolOptions = toPoolOptions(eventLoopCount, dataSourceRuntimeConfig, dataSourceReactiveRuntimeConfig, dataSourceReactivePostgreSQLConfig); List pgConnectOptionsList = toPgConnectOptions(dataSourceName, dataSourceRuntimeConfig, dataSourceReactiveRuntimeConfig, dataSourceReactivePostgreSQLConfig); Supplier> databasesSupplier = toDatabasesSupplier(vertx, pgConnectOptionsList, dataSourceRuntimeConfig); - return createPool(vertx, poolOptions, pgConnectOptionsList, dataSourceName, databasesSupplier); + return createPool(vertx, poolOptions, pgConnectOptionsList, dataSourceName, databasesSupplier, context); } private Supplier> toDatabasesSupplier(Vertx vertx, List pgConnectOptionsList, @@ -220,12 +238,13 @@ private List toPgConnectOptions(String dataSourceName, DataSou } private PgPool createPool(Vertx vertx, PoolOptions poolOptions, List pgConnectOptionsList, - String dataSourceName, Supplier> databases) { + String dataSourceName, Supplier> databases, + SyntheticCreationalContext context) { Instance instance; if (DataSourceUtil.isDefault(dataSourceName)) { - instance = Arc.container().select(PgPoolCreator.class); + instance = context.getInjectedReference(TYPE_LITERAL); } else { - instance = Arc.container().select(PgPoolCreator.class, + instance = context.getInjectedReference(TYPE_LITERAL, new ReactiveDataSource.ReactiveDataSourceLiteral(dataSourceName)); } if (instance.isResolvable()) {