From 051373729148082f7793f068046bbddb12decd33 Mon Sep 17 00:00:00 2001 From: Thomas Segismont Date: Thu, 13 Feb 2025 16:30:54 +0100 Subject: [PATCH] Migrate Reactive DB2 Client extension Apply changes from previous commits to the Reactive DB2 Client extension --- .../main/asciidoc/reactive-sql-clients.adoc | 9 +- .../client/deployment/DB2PoolBuildItem.java | 1 + .../ReactiveDB2ClientProcessor.java | 99 +++++++++++++------ .../reactive/db2/client/DB2PoolCreator.java | 8 +- .../db2/client/runtime/DB2PoolRecorder.java | 64 ++++++++---- .../db2/client/runtime/DB2PoolSupport.java | 16 +++ .../ReactiveDB2DataSourcesHealthCheck.java | 69 +++---------- .../db2/HibernateReactiveDB2TestEndpoint.java | 4 +- .../it/reactive/db2/client/PlantResource.java | 6 +- 9 files changed, 157 insertions(+), 119 deletions(-) create mode 100644 extensions/reactive-db2-client/runtime/src/main/java/io/quarkus/reactive/db2/client/runtime/DB2PoolSupport.java diff --git a/docs/src/main/asciidoc/reactive-sql-clients.adoc b/docs/src/main/asciidoc/reactive-sql-clients.adoc index b4a95a8f5818e..8ccfc20be61d7 100644 --- a/docs/src/main/asciidoc/reactive-sql-clients.adoc +++ b/docs/src/main/asciidoc/reactive-sql-clients.adoc @@ -524,33 +524,28 @@ Navigate to http://localhost:8080/fruits.html and read/create/delete some fruits [[reactive-sql-clients-details]] == Database Clients details -[cols="10,40,40,10"] +[cols="15,70,15"] |=== -|Database |Extension name |Pool class name |Placeholders +|Database |Extension name |Placeholders |IBM Db2 |`quarkus-reactive-db2-client` -|`io.vertx.mutiny.db2client.DB2Pool` |`?` |MariaDB/MySQL |`quarkus-reactive-mysql-client` -|`io.vertx.mutiny.sqlclient.Pool` |`?` |Microsoft SQL Server |`quarkus-reactive-mssql-client` -|`io.vertx.mutiny.sqlclient.Pool` |`@p1`, `@p2`, etc. |Oracle |`quarkus-reactive-oracle-client` -|`io.vertx.mutiny.sqlclient.Pool` |`?` |PostgreSQL |`quarkus-reactive-pg-client` -|`io.vertx.mutiny.sqlclient.Pool` |`$1`, `$2`, etc. |=== 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 a63b88b6c2796..d4610a21a6620 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 @@ -7,6 +7,7 @@ import io.quarkus.datasource.common.runtime.DataSourceUtil; import io.vertx.db2client.DB2Pool; +@Deprecated(forRemoval = true) public final class DB2PoolBuildItem extends MultiBuildItem { private final String dataSourceName; 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 7beac2a52a16f..43e1e15b1df90 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 @@ -1,7 +1,10 @@ package io.quarkus.reactive.db2.client.deployment; +import static io.quarkus.reactive.datasource.deployment.ReactiveDataSourceBuildUtil.VERTX_POOL_TYPE; import static io.quarkus.reactive.datasource.deployment.ReactiveDataSourceBuildUtil.qualifier; import static io.quarkus.reactive.datasource.deployment.ReactiveDataSourceBuildUtil.qualifiers; +import static io.quarkus.reactive.datasource.deployment.ReactiveDataSourceDotNames.INJECT_INSTANCE; +import static java.util.stream.Collectors.toSet; import java.util.HashMap; import java.util.List; @@ -12,9 +15,10 @@ import java.util.function.Function; import java.util.function.Predicate; import java.util.stream.Collectors; +import java.util.stream.Stream; import jakarta.enterprise.context.ApplicationScoped; -import jakarta.enterprise.inject.Instance; +import jakarta.inject.Singleton; import org.jboss.jandex.AnnotationInstance; import org.jboss.jandex.ClassType; @@ -55,6 +59,7 @@ import io.quarkus.reactive.datasource.runtime.DataSourcesReactiveRuntimeConfig; import io.quarkus.reactive.db2.client.DB2PoolCreator; import io.quarkus.reactive.db2.client.runtime.DB2PoolRecorder; +import io.quarkus.reactive.db2.client.runtime.DB2PoolSupport; import io.quarkus.reactive.db2.client.runtime.DB2ServiceBindingConverter; import io.quarkus.reactive.db2.client.runtime.DataSourcesReactiveDB2Config; import io.quarkus.smallrye.health.deployment.spi.HealthBuildItem; @@ -65,12 +70,12 @@ class ReactiveDB2ClientProcessor { - private static final ParameterizedType POOL_CREATOR_INJECTION_TYPE = ParameterizedType.create( - DotName.createSimple(Instance.class), - new Type[] { ClassType.create(DotName.createSimple(DB2PoolCreator.class.getName())) }, null); + private static final Type DB2_POOL_CREATOR = ClassType.create(DotName.createSimple(DB2PoolCreator.class.getName())); + private static final ParameterizedType POOL_CREATOR_INJECTION_TYPE = ParameterizedType.create(INJECT_INSTANCE, + new Type[] { DB2_POOL_CREATOR }, null); private static final DotName VERTX_DB2_POOL = DotName.createSimple(DB2Pool.class); - private static final Type VERTX_DB2_POOL_TYPE = Type.create(VERTX_DB2_POOL, Type.Kind.CLASS); + private static final Type VERTX_DB2_POOL_TYPE = ClassType.create(VERTX_DB2_POOL); @BuildStep @Record(ExecutionTime.RUNTIME_INIT) @@ -92,11 +97,28 @@ ServiceStartBuildItem build(BuildProducer feature, feature.produce(new FeatureBuildItem(Feature.REACTIVE_DB2_CLIENT)); + Stream.Builder db2PoolNamesBuilder = Stream.builder(); for (String dataSourceName : dataSourcesBuildTimeConfig.dataSources().keySet()) { - createPoolIfDefined(recorder, vertx, eventLoopCount, shutdown, db2Pool, syntheticBeans, dataSourceName, - dataSourcesBuildTimeConfig, dataSourcesRuntimeConfig, dataSourcesReactiveBuildTimeConfig, - dataSourcesReactiveRuntimeConfig, dataSourcesReactiveDB2Config, defaultDataSourceDbKindBuildItems, - curateOutcomeBuildItem); + + if (!isReactiveDB2PoolDefined(dataSourcesBuildTimeConfig, dataSourcesReactiveBuildTimeConfig, dataSourceName, + defaultDataSourceDbKindBuildItems, curateOutcomeBuildItem)) { + continue; + } + + createPool(recorder, vertx, eventLoopCount, shutdown, db2Pool, syntheticBeans, dataSourceName, + dataSourcesRuntimeConfig, dataSourcesReactiveRuntimeConfig, dataSourcesReactiveDB2Config); + + db2PoolNamesBuilder.add(dataSourceName); + } + + Set db2PoolNames = db2PoolNamesBuilder.build().collect(toSet()); + if (!db2PoolNames.isEmpty()) { + syntheticBeans.produce(SyntheticBeanBuildItem.configure(DB2PoolSupport.class) + .scope(Singleton.class) + .unremovable() + .runtimeValue(recorder.createDB2PoolSupport(db2PoolNames)) + .setRuntimeInit() + .done()); } // Enable SSL support by default @@ -176,38 +198,27 @@ void addHealthCheck( dataSourcesBuildTimeConfig.healthEnabled())); } - private void createPoolIfDefined(DB2PoolRecorder recorder, + private void createPool(DB2PoolRecorder recorder, VertxBuildItem vertx, EventLoopCountBuildItem eventLoopCount, ShutdownContextBuildItem shutdown, BuildProducer db2Pool, BuildProducer syntheticBeans, String dataSourceName, - DataSourcesBuildTimeConfig dataSourcesBuildTimeConfig, DataSourcesRuntimeConfig dataSourcesRuntimeConfig, - DataSourcesReactiveBuildTimeConfig dataSourcesReactiveBuildTimeConfig, DataSourcesReactiveRuntimeConfig dataSourcesReactiveRuntimeConfig, - DataSourcesReactiveDB2Config dataSourcesReactiveDB2Config, - List defaultDataSourceDbKindBuildItems, - CurateOutcomeBuildItem curateOutcomeBuildItem) { - - if (!isReactiveDB2PoolDefined(dataSourcesBuildTimeConfig, dataSourcesReactiveBuildTimeConfig, dataSourceName, - defaultDataSourceDbKindBuildItems, curateOutcomeBuildItem)) { - return; - } + DataSourcesReactiveDB2Config dataSourcesReactiveDB2Config) { - Function, DB2Pool> poolFunction = recorder.configureDB2Pool(vertx.getVertx(), + Function, Pool> poolFunction = recorder.configureDB2Pool(vertx.getVertx(), eventLoopCount.getEventLoopCount(), dataSourceName, dataSourcesRuntimeConfig, dataSourcesReactiveRuntimeConfig, dataSourcesReactiveDB2Config, shutdown); - db2Pool.produce(new DB2PoolBuildItem(dataSourceName, poolFunction)); - ExtendedBeanConfigurator db2PoolBeanConfigurator = SyntheticBeanBuildItem.configure(DB2Pool.class) + ExtendedBeanConfigurator poolBeanConfigurator = SyntheticBeanBuildItem.configure(Pool.class) .defaultBean() - .addType(Pool.class) .scope(ApplicationScoped.class) .qualifiers(qualifiers(dataSourceName)) .addInjectionPoint(POOL_CREATOR_INJECTION_TYPE, qualifier(dataSourceName)) @@ -217,22 +228,50 @@ private void createPoolIfDefined(DB2PoolRecorder recorder, .setRuntimeInit() .startup(); - syntheticBeans.produce(db2PoolBeanConfigurator.done()); + syntheticBeans.produce(poolBeanConfigurator.done()); + + Function, DB2Pool> vendorPoolFunction = recorder.vendorPool(dataSourceName); + db2Pool.produce(new DB2PoolBuildItem(dataSourceName, vendorPoolFunction)); + + ExtendedBeanConfigurator vendorPoolBeanConfigurator = SyntheticBeanBuildItem.configure(DB2Pool.class) + .defaultBean() + .scope(ApplicationScoped.class) + .qualifiers(qualifiers(dataSourceName)) + .addInjectionPoint(VERTX_POOL_TYPE, qualifier(dataSourceName)) + .checkActive(recorder.poolCheckActiveSupplier(dataSourceName)) + .createWith(vendorPoolFunction) + .unremovable() + .setRuntimeInit() + .startup(); + + syntheticBeans.produce(vendorPoolBeanConfigurator.done()); + + ExtendedBeanConfigurator mutinyPoolConfigurator = SyntheticBeanBuildItem.configure(io.vertx.mutiny.sqlclient.Pool.class) + .defaultBean() + .scope(ApplicationScoped.class) + .qualifiers(qualifiers(dataSourceName)) + .addInjectionPoint(VERTX_POOL_TYPE, qualifier(dataSourceName)) + .checkActive(recorder.poolCheckActiveSupplier(dataSourceName)) + .createWith(recorder.mutinyPool(dataSourceName)) + .unremovable() + .setRuntimeInit() + .startup(); + + syntheticBeans.produce(mutinyPoolConfigurator.done()); - ExtendedBeanConfigurator mutinyDB2PoolConfigurator = SyntheticBeanBuildItem + ExtendedBeanConfigurator mutinyVendorPoolConfigurator = SyntheticBeanBuildItem .configure(io.vertx.mutiny.db2client.DB2Pool.class) .defaultBean() - .addType(io.vertx.mutiny.sqlclient.Pool.class) .scope(ApplicationScoped.class) .qualifiers(qualifiers(dataSourceName)) .addInjectionPoint(VERTX_DB2_POOL_TYPE, qualifier(dataSourceName)) .checkActive(recorder.poolCheckActiveSupplier(dataSourceName)) - .createWith(recorder.mutinyDB2Pool(dataSourceName)) + .createWith(recorder.mutinyVendorPool(dataSourceName)) .unremovable() .setRuntimeInit() .startup(); - syntheticBeans.produce(mutinyDB2PoolConfigurator.done()); + syntheticBeans.produce(mutinyVendorPoolConfigurator.done()); } private static boolean isReactiveDB2PoolDefined(DataSourcesBuildTimeConfig dataSourcesBuildTimeConfig, @@ -282,8 +321,6 @@ private boolean hasPools(DataSourcesBuildTimeConfig dataSourcesBuildTimeConfig, } private static class DB2PoolCreatorBeanClassPredicate implements Predicate> { - private static final Type DB2_POOL_CREATOR = Type.create(DotName.createSimple(DB2PoolCreator.class.getName()), - Type.Kind.CLASS); @Override public boolean test(Set types) { diff --git a/extensions/reactive-db2-client/runtime/src/main/java/io/quarkus/reactive/db2/client/DB2PoolCreator.java b/extensions/reactive-db2-client/runtime/src/main/java/io/quarkus/reactive/db2/client/DB2PoolCreator.java index 3538d678e8670..637c0fb3fa18d 100644 --- a/extensions/reactive-db2-client/runtime/src/main/java/io/quarkus/reactive/db2/client/DB2PoolCreator.java +++ b/extensions/reactive-db2-client/runtime/src/main/java/io/quarkus/reactive/db2/client/DB2PoolCreator.java @@ -3,21 +3,21 @@ import io.quarkus.reactive.datasource.ReactiveDataSource; import io.vertx.core.Vertx; import io.vertx.db2client.DB2ConnectOptions; -import io.vertx.db2client.DB2Pool; +import io.vertx.sqlclient.Pool; import io.vertx.sqlclient.PoolOptions; /** * This interface is an integration point that allows users to use the {@link Vertx}, {@link PoolOptions} and * {@link DB2ConnectOptions} objects configured automatically by Quarkus, in addition to a custom strategy - * for creating the final {@link DB2Pool}. - * + * for creating the final {@link Pool}. + *

* Implementations of this class are meant to be used as CDI beans. * If a bean of this type is used without a {@link ReactiveDataSource} qualifier, then it's applied to the default datasource, * otherwise it applies to the datasource matching the name of the annotation. */ public interface DB2PoolCreator { - DB2Pool create(Input input); + Pool create(Input input); interface Input { 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 25e24c2a14bbb..892feeb6fc6aa 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 @@ -14,6 +14,7 @@ import java.util.List; import java.util.Map; import java.util.Optional; +import java.util.Set; import java.util.function.Function; import java.util.function.Supplier; @@ -24,6 +25,7 @@ import org.jboss.logging.Logger; import io.quarkus.arc.ActiveResult; +import io.quarkus.arc.ClientProxy; import io.quarkus.arc.SyntheticCreationalContext; import io.quarkus.credentials.CredentialsProvider; import io.quarkus.credentials.runtime.CredentialsProviderFinder; @@ -42,6 +44,8 @@ import io.vertx.core.impl.VertxInternal; import io.vertx.db2client.DB2ConnectOptions; import io.vertx.db2client.DB2Pool; +import io.vertx.db2client.spi.DB2Driver; +import io.vertx.sqlclient.Pool; import io.vertx.sqlclient.PoolOptions; import io.vertx.sqlclient.impl.Utils; @@ -79,7 +83,7 @@ public ActiveResult get() { }; } - public Function, DB2Pool> configureDB2Pool(RuntimeValue vertx, + public Function, Pool> configureDB2Pool(RuntimeValue vertx, Supplier eventLoopCount, String dataSourceName, DataSourcesRuntimeConfig dataSourcesRuntimeConfig, @@ -88,8 +92,8 @@ public Function, DB2Pool> configureDB2Pool(R ShutdownContext shutdown) { return new Function<>() { @Override - public DB2Pool apply(SyntheticCreationalContext context) { - DB2Pool db2Pool = initialize((VertxInternal) vertx.getValue(), + public Pool apply(SyntheticCreationalContext context) { + Pool db2Pool = initialize((VertxInternal) vertx.getValue(), eventLoopCount.get(), dataSourceName, dataSourcesRuntimeConfig.dataSources().get(dataSourceName), @@ -103,28 +107,49 @@ public DB2Pool apply(SyntheticCreationalContext context) { }; } - public Function, io.vertx.mutiny.db2client.DB2Pool> mutinyDB2Pool( + public Function, DB2Pool> vendorPool( String dataSourceName) { return new Function<>() { @SuppressWarnings("unchecked") @Override - public io.vertx.mutiny.db2client.DB2Pool apply( - SyntheticCreationalContext context) { - DB2Pool db2Pool = context.getInjectedReference(DB2Pool.class, qualifier(dataSourceName)); - return io.vertx.mutiny.db2client.DB2Pool.newInstance(db2Pool); + public DB2Pool apply(SyntheticCreationalContext context) { + return (DB2Pool) ClientProxy.unwrap(context.getInjectedReference(Pool.class, qualifier(dataSourceName))); } }; } - private DB2Pool initialize(VertxInternal vertx, + public Function, io.vertx.mutiny.sqlclient.Pool> mutinyPool( + String dataSourceName) { + return new Function<>() { + @SuppressWarnings("unchecked") + @Override + public io.vertx.mutiny.sqlclient.Pool apply(SyntheticCreationalContext context) { + return io.vertx.mutiny.sqlclient.Pool.newInstance( + (Pool) context.getInjectedReference(Pool.class, qualifier(dataSourceName))); + } + }; + } + + public Function, io.vertx.mutiny.db2client.DB2Pool> mutinyVendorPool( + String dataSourceName) { + return new Function<>() { + @SuppressWarnings("unchecked") + @Override + public io.vertx.mutiny.db2client.DB2Pool apply(SyntheticCreationalContext context) { + return io.vertx.mutiny.db2client.DB2Pool.newInstance( + (DB2Pool) context.getInjectedReference(DB2Pool.class, qualifier(dataSourceName))); + } + }; + } + + private Pool initialize(VertxInternal vertx, Integer eventLoopCount, String dataSourceName, DataSourceRuntimeConfig dataSourceRuntimeConfig, DataSourceReactiveRuntimeConfig dataSourceReactiveRuntimeConfig, DataSourceReactiveDB2Config dataSourceReactiveDB2Config, - SyntheticCreationalContext context) { - PoolOptions poolOptions = toPoolOptions(eventLoopCount, dataSourceRuntimeConfig, dataSourceReactiveRuntimeConfig, - dataSourceReactiveDB2Config); + SyntheticCreationalContext context) { + PoolOptions poolOptions = toPoolOptions(eventLoopCount, dataSourceReactiveRuntimeConfig); DB2ConnectOptions db2ConnectOptions = toConnectOptions(dataSourceName, dataSourceRuntimeConfig, dataSourceReactiveRuntimeConfig, dataSourceReactiveDB2Config); Supplier> databasesSupplier = toDatabasesSupplier(vertx, List.of(db2ConnectOptions), @@ -147,10 +172,7 @@ private Supplier> toDatabasesSupplier(Vertx vertx, Lis return supplier; } - private PoolOptions toPoolOptions(Integer eventLoopCount, - DataSourceRuntimeConfig dataSourceRuntimeConfig, - DataSourceReactiveRuntimeConfig dataSourceReactiveRuntimeConfig, - DataSourceReactiveDB2Config dataSourceReactiveDB2Config) { + private PoolOptions toPoolOptions(Integer eventLoopCount, DataSourceReactiveRuntimeConfig dataSourceReactiveRuntimeConfig) { PoolOptions poolOptions; poolOptions = new PoolOptions(); @@ -263,15 +285,15 @@ private DB2ConnectOptions toConnectOptions(String dataSourceName, DataSourceRunt return connectOptions; } - private DB2Pool createPool(Vertx vertx, PoolOptions poolOptions, DB2ConnectOptions dB2ConnectOptions, + private Pool createPool(Vertx vertx, PoolOptions poolOptions, DB2ConnectOptions dB2ConnectOptions, String dataSourceName, Supplier> databases, - SyntheticCreationalContext context) { + SyntheticCreationalContext context) { Instance instance = context.getInjectedReference(POOL_CREATOR_TYPE_LITERAL, qualifier(dataSourceName)); if (instance.isResolvable()) { DB2PoolCreator.Input input = new DefaultInput(vertx, poolOptions, dB2ConnectOptions); return instance.get().create(input); } - return DB2Pool.pool(vertx, databases, poolOptions); + return DB2Driver.INSTANCE.createPool(vertx, databases, poolOptions); } private static class DefaultInput implements DB2PoolCreator.Input { @@ -300,4 +322,8 @@ public DB2ConnectOptions db2ConnectOptions() { return dB2ConnectOptions; } } + + public RuntimeValue createDB2PoolSupport(Set db2PoolNames) { + return new RuntimeValue<>(new DB2PoolSupport(db2PoolNames)); + } } diff --git a/extensions/reactive-db2-client/runtime/src/main/java/io/quarkus/reactive/db2/client/runtime/DB2PoolSupport.java b/extensions/reactive-db2-client/runtime/src/main/java/io/quarkus/reactive/db2/client/runtime/DB2PoolSupport.java new file mode 100644 index 0000000000000..c0e4431b372dd --- /dev/null +++ b/extensions/reactive-db2-client/runtime/src/main/java/io/quarkus/reactive/db2/client/runtime/DB2PoolSupport.java @@ -0,0 +1,16 @@ +package io.quarkus.reactive.db2.client.runtime; + +import java.util.Set; + +public class DB2PoolSupport { + + private final Set db2PoolNames; + + public DB2PoolSupport(Set db2PoolNames) { + this.db2PoolNames = Set.copyOf(db2PoolNames); + } + + public Set getDB2PoolNames() { + return db2PoolNames; + } +} \ No newline at end of file diff --git a/extensions/reactive-db2-client/runtime/src/main/java/io/quarkus/reactive/db2/client/runtime/health/ReactiveDB2DataSourcesHealthCheck.java b/extensions/reactive-db2-client/runtime/src/main/java/io/quarkus/reactive/db2/client/runtime/health/ReactiveDB2DataSourcesHealthCheck.java index 49d661561afc4..b28b8716ecbca 100644 --- a/extensions/reactive-db2-client/runtime/src/main/java/io/quarkus/reactive/db2/client/runtime/health/ReactiveDB2DataSourcesHealthCheck.java +++ b/extensions/reactive-db2-client/runtime/src/main/java/io/quarkus/reactive/db2/client/runtime/health/ReactiveDB2DataSourcesHealthCheck.java @@ -1,84 +1,47 @@ package io.quarkus.reactive.db2.client.runtime.health; -import java.time.Duration; -import java.util.HashMap; -import java.util.Map; -import java.util.Map.Entry; import java.util.Set; import jakarta.annotation.PostConstruct; import jakarta.enterprise.context.ApplicationScoped; import jakarta.enterprise.inject.Any; -import jakarta.enterprise.inject.spi.Bean; -import org.eclipse.microprofile.health.HealthCheck; -import org.eclipse.microprofile.health.HealthCheckResponse; -import org.eclipse.microprofile.health.HealthCheckResponseBuilder; import org.eclipse.microprofile.health.Readiness; import io.quarkus.arc.Arc; import io.quarkus.arc.ArcContainer; import io.quarkus.arc.InstanceHandle; -import io.quarkus.datasource.common.runtime.DataSourceUtil; import io.quarkus.datasource.runtime.DataSourceSupport; -import io.quarkus.reactive.datasource.ReactiveDataSource; -import io.vertx.mutiny.db2client.DB2Pool; +import io.quarkus.reactive.datasource.runtime.ReactiveDataSourceUtil; +import io.quarkus.reactive.datasource.runtime.ReactiveDatasourceHealthCheck; +import io.quarkus.reactive.db2.client.runtime.DB2PoolSupport; +import io.vertx.sqlclient.Pool; @Readiness @ApplicationScoped -/** - * Implementation note: this health check doesn't extend ReactiveDatasourceHealthCheck - * as a DB2Pool is based on Mutiny: does not extend io.vertx.sqlclient.Pool - */ -class ReactiveDB2DataSourcesHealthCheck implements HealthCheck { +class ReactiveDB2DataSourcesHealthCheck extends ReactiveDatasourceHealthCheck { - private Map db2Pools = new HashMap<>(); + public ReactiveDB2DataSourcesHealthCheck() { + super("Reactive DB2 connections health check", "SELECT 1 FROM SYSIBM.SYSDUMMY1"); + } @PostConstruct protected void init() { ArcContainer container = Arc.container(); - DataSourceSupport support = container.instance(DataSourceSupport.class).get(); - Set excludedNames = support.getHealthCheckExcludedNames(); - for (InstanceHandle handle : container.select(DB2Pool.class, Any.Literal.INSTANCE).handles()) { + DataSourceSupport dataSourceSupport = container.instance(DataSourceSupport.class).get(); + Set excludedNames = dataSourceSupport.getHealthCheckExcludedNames(); + DB2PoolSupport db2PoolSupport = container.instance(DB2PoolSupport.class).get(); + Set db2PoolNames = db2PoolSupport.getDB2PoolNames(); + for (InstanceHandle handle : container.select(Pool.class, Any.Literal.INSTANCE).handles()) { if (!handle.getBean().isActive()) { continue; } - String poolName = getDB2PoolName(handle.getBean()); - if (excludedNames.contains(poolName)) { + String poolName = ReactiveDataSourceUtil.dataSourceName(handle.getBean()); + if (!db2PoolNames.contains(poolName) || excludedNames.contains(poolName)) { continue; } - db2Pools.put(poolName, handle.get()); - } - } - - @Override - public HealthCheckResponse call() { - HealthCheckResponseBuilder builder = HealthCheckResponse.named("Reactive DB2 connections health check"); - builder.up(); - - for (Entry db2PoolEntry : db2Pools.entrySet()) { - String dataSourceName = db2PoolEntry.getKey(); - DB2Pool db2Pool = db2PoolEntry.getValue(); - try { - db2Pool.query("SELECT 1 FROM SYSIBM.SYSDUMMY1") - .execute() - .await().atMost(Duration.ofSeconds(10)); - builder.withData(dataSourceName, "up"); - } catch (Exception exception) { - builder.down(); - builder.withData(dataSourceName, "down - connection failed: " + exception.getMessage()); - } + addPool(poolName, handle.get()); } - - return builder.build(); } - private String getDB2PoolName(Bean bean) { - for (Object qualifier : bean.getQualifiers()) { - if (qualifier instanceof ReactiveDataSource) { - return ((ReactiveDataSource) qualifier).value(); - } - } - return DataSourceUtil.DEFAULT_DATASOURCE_NAME; - } } diff --git a/integration-tests/hibernate-reactive-db2/src/main/java/io/quarkus/it/hibernate/reactive/db2/HibernateReactiveDB2TestEndpoint.java b/integration-tests/hibernate-reactive-db2/src/main/java/io/quarkus/it/hibernate/reactive/db2/HibernateReactiveDB2TestEndpoint.java index 6045686acf5cb..701b65765bcbc 100644 --- a/integration-tests/hibernate-reactive-db2/src/main/java/io/quarkus/it/hibernate/reactive/db2/HibernateReactiveDB2TestEndpoint.java +++ b/integration-tests/hibernate-reactive-db2/src/main/java/io/quarkus/it/hibernate/reactive/db2/HibernateReactiveDB2TestEndpoint.java @@ -7,7 +7,7 @@ import org.hibernate.reactive.mutiny.Mutiny; import io.smallrye.mutiny.Uni; -import io.vertx.mutiny.db2client.DB2Pool; +import io.vertx.mutiny.sqlclient.Pool; import io.vertx.mutiny.sqlclient.Row; import io.vertx.mutiny.sqlclient.RowSet; import io.vertx.mutiny.sqlclient.Tuple; @@ -21,7 +21,7 @@ public class HibernateReactiveDB2TestEndpoint { // Injecting a Vert.x Pool is not required, it us only used to // independently validate the contents of the database for the test @Inject - DB2Pool db2Pool; + Pool db2Pool; @GET @Path("/reactiveFindMutiny") diff --git a/integration-tests/reactive-db2-client/src/main/java/io/quarkus/it/reactive/db2/client/PlantResource.java b/integration-tests/reactive-db2-client/src/main/java/io/quarkus/it/reactive/db2/client/PlantResource.java index 54b2d9e0b8556..107f1b37713ab 100644 --- a/integration-tests/reactive-db2-client/src/main/java/io/quarkus/it/reactive/db2/client/PlantResource.java +++ b/integration-tests/reactive-db2-client/src/main/java/io/quarkus/it/reactive/db2/client/PlantResource.java @@ -10,18 +10,18 @@ import io.quarkus.reactive.datasource.ReactiveDataSource; import io.vertx.core.json.JsonArray; import io.vertx.core.json.JsonObject; -import io.vertx.mutiny.db2client.DB2Pool; +import io.vertx.mutiny.sqlclient.Pool; import io.vertx.mutiny.sqlclient.Row; @Path("/plants") public class PlantResource { @Inject - DB2Pool client; + Pool client; @Inject @ReactiveDataSource("additional") - DB2Pool additionalClient; + Pool additionalClient; @PostConstruct void setupDb() {