Skip to content

Commit a07d65d

Browse files
committed
Migrate Reactive DB2 Client extension
Apply changes from previous commits to the Reactive DB2 Client extension
1 parent fe6822b commit a07d65d

File tree

9 files changed

+89
-103
lines changed

9 files changed

+89
-103
lines changed

docs/src/main/asciidoc/reactive-sql-clients.adoc

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -524,33 +524,28 @@ Navigate to http://localhost:8080/fruits.html and read/create/delete some fruits
524524
[[reactive-sql-clients-details]]
525525
== Database Clients details
526526

527-
[cols="10,40,40,10"]
527+
[cols="15,70,15"]
528528
|===
529-
|Database |Extension name |Pool class name |Placeholders
529+
|Database |Extension name |Placeholders
530530

531531
|IBM Db2
532532
|`quarkus-reactive-db2-client`
533-
|`io.vertx.mutiny.db2client.DB2Pool`
534533
|`?`
535534

536535
|MariaDB/MySQL
537536
|`quarkus-reactive-mysql-client`
538-
|`io.vertx.mutiny.sqlclient.Pool`
539537
|`?`
540538

541539
|Microsoft SQL Server
542540
|`quarkus-reactive-mssql-client`
543-
|`io.vertx.mutiny.sqlclient.Pool`
544541
|`@p1`, `@p2`, etc.
545542

546543
|Oracle
547544
|`quarkus-reactive-oracle-client`
548-
|`io.vertx.mutiny.sqlclient.Pool`
549545
|`?`
550546

551547
|PostgreSQL
552548
|`quarkus-reactive-pg-client`
553-
|`io.vertx.mutiny.sqlclient.Pool`
554549
|`$1`, `$2`, etc.
555550
|===
556551

extensions/reactive-db2-client/deployment/src/main/java/io/quarkus/reactive/db2/client/deployment/DB2PoolBuildItem.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
import io.quarkus.datasource.common.runtime.DataSourceUtil;
88
import io.vertx.db2client.DB2Pool;
99

10+
@Deprecated(forRemoval = true)
1011
public final class DB2PoolBuildItem extends MultiBuildItem {
1112

1213
private final String dataSourceName;

extensions/reactive-db2-client/deployment/src/main/java/io/quarkus/reactive/db2/client/deployment/ReactiveDB2ClientProcessor.java

Lines changed: 32 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22

33
import static io.quarkus.reactive.datasource.deployment.ReactiveDataSourceBuildUtil.qualifier;
44
import static io.quarkus.reactive.datasource.deployment.ReactiveDataSourceBuildUtil.qualifiers;
5+
import static io.quarkus.reactive.datasource.deployment.ReactiveDataSourceDotNames.INJECT_INSTANCE;
6+
import static java.util.stream.Collectors.toSet;
57

68
import java.util.HashMap;
79
import java.util.List;
@@ -12,9 +14,10 @@
1214
import java.util.function.Function;
1315
import java.util.function.Predicate;
1416
import java.util.stream.Collectors;
17+
import java.util.stream.Stream;
1518

1619
import jakarta.enterprise.context.ApplicationScoped;
17-
import jakarta.enterprise.inject.Instance;
20+
import jakarta.inject.Singleton;
1821

1922
import org.jboss.jandex.AnnotationInstance;
2023
import org.jboss.jandex.ClassType;
@@ -55,6 +58,7 @@
5558
import io.quarkus.reactive.datasource.runtime.DataSourcesReactiveRuntimeConfig;
5659
import io.quarkus.reactive.db2.client.DB2PoolCreator;
5760
import io.quarkus.reactive.db2.client.runtime.DB2PoolRecorder;
61+
import io.quarkus.reactive.db2.client.runtime.DB2PoolSupport;
5862
import io.quarkus.reactive.db2.client.runtime.DB2ServiceBindingConverter;
5963
import io.quarkus.reactive.db2.client.runtime.DataSourcesReactiveDB2Config;
6064
import io.quarkus.smallrye.health.deployment.spi.HealthBuildItem;
@@ -65,12 +69,12 @@
6569

6670
class ReactiveDB2ClientProcessor {
6771

68-
private static final ParameterizedType POOL_CREATOR_INJECTION_TYPE = ParameterizedType.create(
69-
DotName.createSimple(Instance.class),
70-
new Type[] { ClassType.create(DotName.createSimple(DB2PoolCreator.class.getName())) }, null);
72+
private static final Type DB2_POOL_CREATOR = ClassType.create(DotName.createSimple(DB2PoolCreator.class.getName()));
73+
private static final ParameterizedType POOL_CREATOR_INJECTION_TYPE = ParameterizedType.create(INJECT_INSTANCE,
74+
new Type[] { DB2_POOL_CREATOR }, null);
7175

7276
private static final DotName VERTX_DB2_POOL = DotName.createSimple(DB2Pool.class);
73-
private static final Type VERTX_DB2_POOL_TYPE = Type.create(VERTX_DB2_POOL, Type.Kind.CLASS);
77+
private static final Type VERTX_DB2_POOL_TYPE = ClassType.create(VERTX_DB2_POOL);
7478

7579
@BuildStep
7680
@Record(ExecutionTime.RUNTIME_INIT)
@@ -92,11 +96,28 @@ ServiceStartBuildItem build(BuildProducer<FeatureBuildItem> feature,
9296

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

99+
Stream.Builder<String> db2PoolNamesBuilder = Stream.builder();
95100
for (String dataSourceName : dataSourcesBuildTimeConfig.dataSources().keySet()) {
96-
createPoolIfDefined(recorder, vertx, eventLoopCount, shutdown, db2Pool, syntheticBeans, dataSourceName,
97-
dataSourcesBuildTimeConfig, dataSourcesRuntimeConfig, dataSourcesReactiveBuildTimeConfig,
98-
dataSourcesReactiveRuntimeConfig, dataSourcesReactiveDB2Config, defaultDataSourceDbKindBuildItems,
99-
curateOutcomeBuildItem);
101+
102+
if (!isReactiveDB2PoolDefined(dataSourcesBuildTimeConfig, dataSourcesReactiveBuildTimeConfig, dataSourceName,
103+
defaultDataSourceDbKindBuildItems, curateOutcomeBuildItem)) {
104+
continue;
105+
}
106+
107+
createPool(recorder, vertx, eventLoopCount, shutdown, db2Pool, syntheticBeans, dataSourceName,
108+
dataSourcesRuntimeConfig, dataSourcesReactiveRuntimeConfig, dataSourcesReactiveDB2Config);
109+
110+
db2PoolNamesBuilder.add(dataSourceName);
111+
}
112+
113+
Set<String> db2PoolNames = db2PoolNamesBuilder.build().collect(toSet());
114+
if (!db2PoolNames.isEmpty()) {
115+
syntheticBeans.produce(SyntheticBeanBuildItem.configure(DB2PoolSupport.class)
116+
.scope(Singleton.class)
117+
.unremovable()
118+
.runtimeValue(recorder.createDB2PoolSupport(db2PoolNames))
119+
.setRuntimeInit()
120+
.done());
100121
}
101122

102123
// Enable SSL support by default
@@ -176,25 +197,16 @@ void addHealthCheck(
176197
dataSourcesBuildTimeConfig.healthEnabled()));
177198
}
178199

179-
private void createPoolIfDefined(DB2PoolRecorder recorder,
200+
private void createPool(DB2PoolRecorder recorder,
180201
VertxBuildItem vertx,
181202
EventLoopCountBuildItem eventLoopCount,
182203
ShutdownContextBuildItem shutdown,
183204
BuildProducer<DB2PoolBuildItem> db2Pool,
184205
BuildProducer<SyntheticBeanBuildItem> syntheticBeans,
185206
String dataSourceName,
186-
DataSourcesBuildTimeConfig dataSourcesBuildTimeConfig,
187207
DataSourcesRuntimeConfig dataSourcesRuntimeConfig,
188-
DataSourcesReactiveBuildTimeConfig dataSourcesReactiveBuildTimeConfig,
189208
DataSourcesReactiveRuntimeConfig dataSourcesReactiveRuntimeConfig,
190-
DataSourcesReactiveDB2Config dataSourcesReactiveDB2Config,
191-
List<DefaultDataSourceDbKindBuildItem> defaultDataSourceDbKindBuildItems,
192-
CurateOutcomeBuildItem curateOutcomeBuildItem) {
193-
194-
if (!isReactiveDB2PoolDefined(dataSourcesBuildTimeConfig, dataSourcesReactiveBuildTimeConfig, dataSourceName,
195-
defaultDataSourceDbKindBuildItems, curateOutcomeBuildItem)) {
196-
return;
197-
}
209+
DataSourcesReactiveDB2Config dataSourcesReactiveDB2Config) {
198210

199211
Function<SyntheticCreationalContext<DB2Pool>, DB2Pool> poolFunction = recorder.configureDB2Pool(vertx.getVertx(),
200212
eventLoopCount.getEventLoopCount(),
@@ -282,8 +294,6 @@ private boolean hasPools(DataSourcesBuildTimeConfig dataSourcesBuildTimeConfig,
282294
}
283295

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

288298
@Override
289299
public boolean test(Set<Type> types) {

extensions/reactive-db2-client/runtime/src/main/java/io/quarkus/reactive/db2/client/DB2PoolCreator.java

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,21 +3,21 @@
33
import io.quarkus.reactive.datasource.ReactiveDataSource;
44
import io.vertx.core.Vertx;
55
import io.vertx.db2client.DB2ConnectOptions;
6-
import io.vertx.db2client.DB2Pool;
6+
import io.vertx.sqlclient.Pool;
77
import io.vertx.sqlclient.PoolOptions;
88

99
/**
1010
* This interface is an integration point that allows users to use the {@link Vertx}, {@link PoolOptions} and
1111
* {@link DB2ConnectOptions} objects configured automatically by Quarkus, in addition to a custom strategy
12-
* for creating the final {@link DB2Pool}.
13-
*
12+
* for creating the final {@link Pool}.
13+
* <p>
1414
* Implementations of this class are meant to be used as CDI beans.
1515
* If a bean of this type is used without a {@link ReactiveDataSource} qualifier, then it's applied to the default datasource,
1616
* otherwise it applies to the datasource matching the name of the annotation.
1717
*/
1818
public interface DB2PoolCreator {
1919

20-
DB2Pool create(Input input);
20+
Pool create(Input input);
2121

2222
interface Input {
2323

extensions/reactive-db2-client/runtime/src/main/java/io/quarkus/reactive/db2/client/runtime/DB2PoolRecorder.java

Lines changed: 13 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
import java.util.List;
1515
import java.util.Map;
1616
import java.util.Optional;
17+
import java.util.Set;
1718
import java.util.function.Function;
1819
import java.util.function.Supplier;
1920

@@ -42,6 +43,7 @@
4243
import io.vertx.core.impl.VertxInternal;
4344
import io.vertx.db2client.DB2ConnectOptions;
4445
import io.vertx.db2client.DB2Pool;
46+
import io.vertx.db2client.spi.DB2Driver;
4547
import io.vertx.sqlclient.PoolOptions;
4648
import io.vertx.sqlclient.impl.Utils;
4749

@@ -108,10 +110,9 @@ public Function<SyntheticCreationalContext<io.vertx.mutiny.db2client.DB2Pool>, i
108110
return new Function<>() {
109111
@SuppressWarnings("unchecked")
110112
@Override
111-
public io.vertx.mutiny.db2client.DB2Pool apply(
112-
SyntheticCreationalContext<io.vertx.mutiny.db2client.DB2Pool> context) {
113-
DB2Pool db2Pool = context.getInjectedReference(DB2Pool.class, qualifier(dataSourceName));
114-
return io.vertx.mutiny.db2client.DB2Pool.newInstance(db2Pool);
113+
public io.vertx.mutiny.db2client.DB2Pool apply(SyntheticCreationalContext context) {
114+
return io.vertx.mutiny.db2client.DB2Pool.newInstance(
115+
(DB2Pool) context.getInjectedReference(DB2Pool.class, qualifier(dataSourceName)));
115116
}
116117
};
117118
}
@@ -123,8 +124,7 @@ private DB2Pool initialize(VertxInternal vertx,
123124
DataSourceReactiveRuntimeConfig dataSourceReactiveRuntimeConfig,
124125
DataSourceReactiveDB2Config dataSourceReactiveDB2Config,
125126
SyntheticCreationalContext<DB2Pool> context) {
126-
PoolOptions poolOptions = toPoolOptions(eventLoopCount, dataSourceRuntimeConfig, dataSourceReactiveRuntimeConfig,
127-
dataSourceReactiveDB2Config);
127+
PoolOptions poolOptions = toPoolOptions(eventLoopCount, dataSourceReactiveRuntimeConfig);
128128
DB2ConnectOptions db2ConnectOptions = toConnectOptions(dataSourceName, dataSourceRuntimeConfig,
129129
dataSourceReactiveRuntimeConfig, dataSourceReactiveDB2Config);
130130
Supplier<Future<DB2ConnectOptions>> databasesSupplier = toDatabasesSupplier(vertx, List.of(db2ConnectOptions),
@@ -147,10 +147,7 @@ private Supplier<Future<DB2ConnectOptions>> toDatabasesSupplier(Vertx vertx, Lis
147147
return supplier;
148148
}
149149

150-
private PoolOptions toPoolOptions(Integer eventLoopCount,
151-
DataSourceRuntimeConfig dataSourceRuntimeConfig,
152-
DataSourceReactiveRuntimeConfig dataSourceReactiveRuntimeConfig,
153-
DataSourceReactiveDB2Config dataSourceReactiveDB2Config) {
150+
private PoolOptions toPoolOptions(Integer eventLoopCount, DataSourceReactiveRuntimeConfig dataSourceReactiveRuntimeConfig) {
154151
PoolOptions poolOptions;
155152
poolOptions = new PoolOptions();
156153

@@ -269,9 +266,9 @@ private DB2Pool createPool(Vertx vertx, PoolOptions poolOptions, DB2ConnectOptio
269266
Instance<DB2PoolCreator> instance = context.getInjectedReference(POOL_CREATOR_TYPE_LITERAL, qualifier(dataSourceName));
270267
if (instance.isResolvable()) {
271268
DB2PoolCreator.Input input = new DefaultInput(vertx, poolOptions, dB2ConnectOptions);
272-
return instance.get().create(input);
269+
return (DB2Pool) instance.get().create(input);
273270
}
274-
return DB2Pool.pool(vertx, databases, poolOptions);
271+
return (DB2Pool) DB2Driver.INSTANCE.createPool(vertx, databases, poolOptions);
275272
}
276273

277274
private static class DefaultInput implements DB2PoolCreator.Input {
@@ -300,4 +297,8 @@ public DB2ConnectOptions db2ConnectOptions() {
300297
return dB2ConnectOptions;
301298
}
302299
}
300+
301+
public RuntimeValue<DB2PoolSupport> createDB2PoolSupport(Set<String> db2PoolNames) {
302+
return new RuntimeValue<>(new DB2PoolSupport(db2PoolNames));
303+
}
303304
}
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
package io.quarkus.reactive.db2.client.runtime;
2+
3+
import java.util.Set;
4+
5+
public class DB2PoolSupport {
6+
7+
private final Set<String> db2PoolNames;
8+
9+
public DB2PoolSupport(Set<String> db2PoolNames) {
10+
this.db2PoolNames = Set.copyOf(db2PoolNames);
11+
}
12+
13+
public Set<String> getDB2PoolNames() {
14+
return db2PoolNames;
15+
}
16+
}
Original file line numberDiff line numberDiff line change
@@ -1,84 +1,47 @@
11
package io.quarkus.reactive.db2.client.runtime.health;
22

3-
import java.time.Duration;
4-
import java.util.HashMap;
5-
import java.util.Map;
6-
import java.util.Map.Entry;
73
import java.util.Set;
84

95
import jakarta.annotation.PostConstruct;
106
import jakarta.enterprise.context.ApplicationScoped;
117
import jakarta.enterprise.inject.Any;
12-
import jakarta.enterprise.inject.spi.Bean;
138

14-
import org.eclipse.microprofile.health.HealthCheck;
15-
import org.eclipse.microprofile.health.HealthCheckResponse;
16-
import org.eclipse.microprofile.health.HealthCheckResponseBuilder;
179
import org.eclipse.microprofile.health.Readiness;
1810

1911
import io.quarkus.arc.Arc;
2012
import io.quarkus.arc.ArcContainer;
2113
import io.quarkus.arc.InstanceHandle;
22-
import io.quarkus.datasource.common.runtime.DataSourceUtil;
2314
import io.quarkus.datasource.runtime.DataSourceSupport;
24-
import io.quarkus.reactive.datasource.ReactiveDataSource;
25-
import io.vertx.mutiny.db2client.DB2Pool;
15+
import io.quarkus.reactive.datasource.runtime.ReactiveDataSourceUtil;
16+
import io.quarkus.reactive.datasource.runtime.ReactiveDatasourceHealthCheck;
17+
import io.quarkus.reactive.db2.client.runtime.DB2PoolSupport;
18+
import io.vertx.sqlclient.Pool;
2619

2720
@Readiness
2821
@ApplicationScoped
29-
/**
30-
* Implementation note: this health check doesn't extend ReactiveDatasourceHealthCheck
31-
* as a DB2Pool is based on Mutiny: does not extend io.vertx.sqlclient.Pool
32-
*/
33-
class ReactiveDB2DataSourcesHealthCheck implements HealthCheck {
22+
class ReactiveDB2DataSourcesHealthCheck extends ReactiveDatasourceHealthCheck {
3423

35-
private Map<String, DB2Pool> db2Pools = new HashMap<>();
24+
public ReactiveDB2DataSourcesHealthCheck() {
25+
super("Reactive DB2 connections health check", "SELECT 1 FROM SYSIBM.SYSDUMMY1");
26+
}
3627

3728
@PostConstruct
3829
protected void init() {
3930
ArcContainer container = Arc.container();
40-
DataSourceSupport support = container.instance(DataSourceSupport.class).get();
41-
Set<String> excludedNames = support.getHealthCheckExcludedNames();
42-
for (InstanceHandle<DB2Pool> handle : container.select(DB2Pool.class, Any.Literal.INSTANCE).handles()) {
31+
DataSourceSupport dataSourceSupport = container.instance(DataSourceSupport.class).get();
32+
Set<String> excludedNames = dataSourceSupport.getHealthCheckExcludedNames();
33+
DB2PoolSupport db2PoolSupport = container.instance(DB2PoolSupport.class).get();
34+
Set<String> db2PoolNames = db2PoolSupport.getDB2PoolNames();
35+
for (InstanceHandle<Pool> handle : container.select(Pool.class, Any.Literal.INSTANCE).handles()) {
4336
if (!handle.getBean().isActive()) {
4437
continue;
4538
}
46-
String poolName = getDB2PoolName(handle.getBean());
47-
if (excludedNames.contains(poolName)) {
39+
String poolName = ReactiveDataSourceUtil.dataSourceName(handle.getBean());
40+
if (!db2PoolNames.contains(poolName) || excludedNames.contains(poolName)) {
4841
continue;
4942
}
50-
db2Pools.put(poolName, handle.get());
51-
}
52-
}
53-
54-
@Override
55-
public HealthCheckResponse call() {
56-
HealthCheckResponseBuilder builder = HealthCheckResponse.named("Reactive DB2 connections health check");
57-
builder.up();
58-
59-
for (Entry<String, DB2Pool> db2PoolEntry : db2Pools.entrySet()) {
60-
String dataSourceName = db2PoolEntry.getKey();
61-
DB2Pool db2Pool = db2PoolEntry.getValue();
62-
try {
63-
db2Pool.query("SELECT 1 FROM SYSIBM.SYSDUMMY1")
64-
.execute()
65-
.await().atMost(Duration.ofSeconds(10));
66-
builder.withData(dataSourceName, "up");
67-
} catch (Exception exception) {
68-
builder.down();
69-
builder.withData(dataSourceName, "down - connection failed: " + exception.getMessage());
70-
}
43+
addPool(poolName, handle.get());
7144
}
72-
73-
return builder.build();
7445
}
7546

76-
private String getDB2PoolName(Bean<?> bean) {
77-
for (Object qualifier : bean.getQualifiers()) {
78-
if (qualifier instanceof ReactiveDataSource) {
79-
return ((ReactiveDataSource) qualifier).value();
80-
}
81-
}
82-
return DataSourceUtil.DEFAULT_DATASOURCE_NAME;
83-
}
8447
}

integration-tests/hibernate-reactive-db2/src/main/java/io/quarkus/it/hibernate/reactive/db2/HibernateReactiveDB2TestEndpoint.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
import org.hibernate.reactive.mutiny.Mutiny;
88

99
import io.smallrye.mutiny.Uni;
10-
import io.vertx.mutiny.db2client.DB2Pool;
10+
import io.vertx.mutiny.sqlclient.Pool;
1111
import io.vertx.mutiny.sqlclient.Row;
1212
import io.vertx.mutiny.sqlclient.RowSet;
1313
import io.vertx.mutiny.sqlclient.Tuple;
@@ -21,7 +21,7 @@ public class HibernateReactiveDB2TestEndpoint {
2121
// Injecting a Vert.x Pool is not required, it us only used to
2222
// independently validate the contents of the database for the test
2323
@Inject
24-
DB2Pool db2Pool;
24+
Pool db2Pool;
2525

2626
@GET
2727
@Path("/reactiveFindMutiny")

0 commit comments

Comments
 (0)