Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Properly initialize reactive Pool beans #35949

Merged
merged 1 commit into from
Sep 18, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -10,28 +10,26 @@
* If you inject this build item when recording runtime init template calls, you are guaranteed the Pool configuration
* has been injected and Pools can be created.
*/
@Deprecated(forRemoval = true)
public final class VertxPoolBuildItem extends MultiBuildItem {
geoand marked this conversation as resolved.
Show resolved Hide resolved
geoand marked this conversation as resolved.
Show resolved Hide resolved

private final RuntimeValue<? extends Pool> vertxPool;
private final String dbKind;
private final boolean isDefault;
public VertxPoolBuildItem() {
}

public VertxPoolBuildItem(RuntimeValue<? extends Pool> vertxPool, String dbKind, boolean isDefault) {
this.vertxPool = vertxPool;
this.dbKind = dbKind;
this.isDefault = isDefault;

}

public RuntimeValue<? extends Pool> 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");
}

}
Original file line number Diff line number Diff line change
@@ -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> db2Pool;
private final Function<SyntheticCreationalContext<DB2Pool>, DB2Pool> db2Pool;

public DB2PoolBuildItem(String dataSourceName, RuntimeValue<DB2Pool> db2Pool) {
public DB2PoolBuildItem(String dataSourceName, Function<SyntheticCreationalContext<DB2Pool>, DB2Pool> db2Pool) {
this.dataSourceName = dataSourceName;
this.db2Pool = db2Pool;
}
Expand All @@ -20,7 +22,7 @@ public String getDataSourceName() {
return dataSourceName;
}

public RuntimeValue<DB2Pool> getDB2Pool() {
public Function<SyntheticCreationalContext<DB2Pool>, DB2Pool> getDB2Pool() {
return db2Pool;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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;
Expand All @@ -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<FeatureBuildItem> feature,
Expand All @@ -81,7 +91,7 @@ ServiceStartBuildItem build(BuildProducer<FeatureBuildItem> 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);
Expand All @@ -90,6 +100,7 @@ ServiceStartBuildItem build(BuildProducer<FeatureBuildItem> feature,
// Enable SSL support by default
sslNativeSupport.produce(new ExtensionSslNativeSupportBuildItem(Feature.REACTIVE_DB2_CLIENT));

vertxPool.produce(new VertxPoolBuildItem());
return new ServiceStartBuildItem("reactive-db2-client");
}

Expand Down Expand Up @@ -168,7 +179,6 @@ private void createPoolIfDefined(DB2PoolRecorder recorder,
EventLoopCountBuildItem eventLoopCount,
ShutdownContextBuildItem shutdown,
BuildProducer<DB2PoolBuildItem> db2Pool,
BuildProducer<VertxPoolBuildItem> vertxPool,
BuildProducer<SyntheticBeanBuildItem> syntheticBeans,
String dataSourceName,
DataSourcesBuildTimeConfig dataSourcesBuildTimeConfig,
Expand All @@ -184,20 +194,21 @@ private void createPoolIfDefined(DB2PoolRecorder recorder,
return;
}

RuntimeValue<DB2Pool> pool = recorder.configureDB2Pool(vertx.getVertx(),
Function<SyntheticCreationalContext<DB2Pool>, 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();

Expand All @@ -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,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -44,43 +46,58 @@
public class DB2PoolRecorder {

private static final Logger log = Logger.getLogger(DB2PoolRecorder.class);
private static final TypeLiteral<Instance<DB2PoolCreator>> TYPE_LITERAL = new TypeLiteral<>() {
};

public RuntimeValue<DB2Pool> configureDB2Pool(RuntimeValue<Vertx> vertx,
public Function<SyntheticCreationalContext<DB2Pool>, DB2Pool> configureDB2Pool(RuntimeValue<Vertx> vertx,
Supplier<Integer> 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<DB2Pool> 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<io.vertx.mutiny.db2client.DB2Pool> mutinyDB2Pool(RuntimeValue<DB2Pool> db2Pool) {
return new RuntimeValue<>(io.vertx.mutiny.db2client.DB2Pool.newInstance(db2Pool.getValue()));
public Function<SyntheticCreationalContext<io.vertx.mutiny.db2client.DB2Pool>, io.vertx.mutiny.db2client.DB2Pool> mutinyDB2Pool(
Function<SyntheticCreationalContext<DB2Pool>, 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,
Integer eventLoopCount,
String dataSourceName,
DataSourceRuntimeConfig dataSourceRuntimeConfig,
DataSourceReactiveRuntimeConfig dataSourceReactiveRuntimeConfig,
DataSourceReactiveDB2Config dataSourceReactiveDB2Config) {
DataSourceReactiveDB2Config dataSourceReactiveDB2Config,
SyntheticCreationalContext<DB2Pool> context) {
PoolOptions poolOptions = toPoolOptions(eventLoopCount, dataSourceRuntimeConfig, dataSourceReactiveRuntimeConfig,
dataSourceReactiveDB2Config);
DB2ConnectOptions db2ConnectOptions = toConnectOptions(dataSourceName, dataSourceRuntimeConfig,
dataSourceReactiveRuntimeConfig, dataSourceReactiveDB2Config);
Supplier<Future<DB2ConnectOptions>> databasesSupplier = toDatabasesSupplier(vertx, List.of(db2ConnectOptions),
dataSourceRuntimeConfig);
return createPool(vertx, poolOptions, db2ConnectOptions, dataSourceName, databasesSupplier);
return createPool(vertx, poolOptions, db2ConnectOptions, dataSourceName, databasesSupplier, context);
}

private Supplier<Future<DB2ConnectOptions>> toDatabasesSupplier(Vertx vertx, List<DB2ConnectOptions> db2ConnectOptionsList,
Expand Down Expand Up @@ -213,12 +230,13 @@ private DB2ConnectOptions toConnectOptions(String dataSourceName, DataSourceRunt
}

private DB2Pool createPool(Vertx vertx, PoolOptions poolOptions, DB2ConnectOptions dB2ConnectOptions,
String dataSourceName, Supplier<Future<DB2ConnectOptions>> databases) {
String dataSourceName, Supplier<Future<DB2ConnectOptions>> databases,
SyntheticCreationalContext<DB2Pool> context) {
Instance<DB2PoolCreator> 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()) {
Expand Down
Original file line number Diff line number Diff line change
@@ -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> mssqlPool;
private final Function<SyntheticCreationalContext<MSSQLPool>, MSSQLPool> mssqlPool;

public MSSQLPoolBuildItem(String dataSourceName, RuntimeValue<MSSQLPool> mssqlPool) {
public MSSQLPoolBuildItem(String dataSourceName, Function<SyntheticCreationalContext<MSSQLPool>, MSSQLPool> mssqlPool) {
this.dataSourceName = dataSourceName;
this.mssqlPool = mssqlPool;
}
Expand All @@ -20,7 +22,7 @@ public String getDataSourceName() {
return dataSourceName;
}

public RuntimeValue<MSSQLPool> getMSSQLPool() {
public Function<SyntheticCreationalContext<MSSQLPool>, MSSQLPool> getMSSQLPool() {
return mssqlPool;
}

Expand Down