Skip to content

Commit

Permalink
Migrate Reactive DB2 Client extension
Browse files Browse the repository at this point in the history
Apply changes from previous commits to the Reactive DB2 Client extension
  • Loading branch information
tsegismont committed Feb 13, 2025
1 parent 83cbccf commit 0513737
Show file tree
Hide file tree
Showing 9 changed files with 157 additions and 119 deletions.
9 changes: 2 additions & 7 deletions docs/src/main/asciidoc/reactive-sql-clients.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -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.
|===

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
Original file line number Diff line number Diff line change
@@ -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;
Expand All @@ -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;
Expand Down Expand Up @@ -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;
Expand All @@ -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)
Expand All @@ -92,11 +97,28 @@ ServiceStartBuildItem build(BuildProducer<FeatureBuildItem> feature,

feature.produce(new FeatureBuildItem(Feature.REACTIVE_DB2_CLIENT));

Stream.Builder<String> 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<String> 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
Expand Down Expand Up @@ -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<DB2PoolBuildItem> db2Pool,
BuildProducer<SyntheticBeanBuildItem> syntheticBeans,
String dataSourceName,
DataSourcesBuildTimeConfig dataSourcesBuildTimeConfig,
DataSourcesRuntimeConfig dataSourcesRuntimeConfig,
DataSourcesReactiveBuildTimeConfig dataSourcesReactiveBuildTimeConfig,
DataSourcesReactiveRuntimeConfig dataSourcesReactiveRuntimeConfig,
DataSourcesReactiveDB2Config dataSourcesReactiveDB2Config,
List<DefaultDataSourceDbKindBuildItem> defaultDataSourceDbKindBuildItems,
CurateOutcomeBuildItem curateOutcomeBuildItem) {

if (!isReactiveDB2PoolDefined(dataSourcesBuildTimeConfig, dataSourcesReactiveBuildTimeConfig, dataSourceName,
defaultDataSourceDbKindBuildItems, curateOutcomeBuildItem)) {
return;
}
DataSourcesReactiveDB2Config dataSourcesReactiveDB2Config) {

Function<SyntheticCreationalContext<DB2Pool>, DB2Pool> poolFunction = recorder.configureDB2Pool(vertx.getVertx(),
Function<SyntheticCreationalContext<Pool>, 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))
Expand All @@ -217,22 +228,50 @@ private void createPoolIfDefined(DB2PoolRecorder recorder,
.setRuntimeInit()
.startup();

syntheticBeans.produce(db2PoolBeanConfigurator.done());
syntheticBeans.produce(poolBeanConfigurator.done());

Function<SyntheticCreationalContext<DB2Pool>, 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,
Expand Down Expand Up @@ -282,8 +321,6 @@ private boolean hasPools(DataSourcesBuildTimeConfig dataSourcesBuildTimeConfig,
}

private static class DB2PoolCreatorBeanClassPredicate implements Predicate<Set<Type>> {
private static final Type DB2_POOL_CREATOR = Type.create(DotName.createSimple(DB2PoolCreator.class.getName()),
Type.Kind.CLASS);

@Override
public boolean test(Set<Type> types) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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}.
* <p>
* 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 {

Expand Down
Loading

0 comments on commit 0513737

Please sign in to comment.