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 01e475b64c66fa..4c81df53d17ceb 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 @@ -12,26 +12,23 @@ */ 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 95b5c18a89872a..a63b88b6c27969 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 d20b951f8d517d..d21106cfd1baf8 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 90681e5e63bde5..d5e372b88779b9 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 0eb56a6071d9d3..639f59dac3e25d 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 5e5d06baf8bdd0..fc29eb683d158c 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 3c9dc91c63debd..dad7ed85e5f863 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 b8c40a65cef57d..0b64cbf31d0c57 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 b512986ade9ee1..7f61ab1eb92310 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 b3db354d085835..8b0d101285326c 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 4a8a264324cfea..a7bba6abd8c716 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 25918da0fca34d..a82812d3d84092 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 e217cc1a818af3..dc49a6eafd2611 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 518bf7df817a83..0d19c802ead055 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 77690e5430e3d5..e1db7a21692b09 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 7988a6f86afa79..d9df24b0b69917 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,43 @@ @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) { + // Only create the OtlpGrpcSpanExporter if an endpoint was set in runtime config and was properly validated at startup + 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 +89,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 +239,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()) {