From 93674c842caadbab3aae91af4bc5b9696ff873ee Mon Sep 17 00:00:00 2001 From: Thomas Segismont Date: Mon, 20 Sep 2021 16:43:11 +0200 Subject: [PATCH] Datasource "health-excluded" property should apply to reactive pools too Closes #20059 In #13375, we got a way to exclude a datasource from health-checks. Yet the implementation for reactive datasources was missing. --- .../agroal/deployment/AgroalProcessor.java | 12 +------ .../agroal/runtime/AgroalRecorder.java | 27 --------------- .../runtime/health/DataSourceHealthCheck.java | 3 +- ...rcesExcludedFromHealthChecksProcessor.java | 34 +++++++++++++++++++ .../DataSourcesExcludedFromHealthChecks.java | 10 +++--- ...urcesExcludedFromHealthChecksRecorder.java | 30 ++++++++++++++++ .../ReactiveDB2ClientProcessor.java | 7 ++++ .../ReactiveDB2DataSourcesHealthCheck.java | 13 +++++-- .../reactive-mssql-client/deployment/pom.xml | 5 +++ .../ReactiveMSSQLClientProcessor.java | 7 ++++ .../DataSourceHealthCheckExclusionTest.java | 26 ++++++++++++++ ...ication-datasources-with-health.properties | 11 ++++++ .../ReactiveMSSQLDataSourcesHealthCheck.java | 14 ++++++-- .../reactive-mysql-client/deployment/pom.xml | 5 +++ .../ReactiveMySQLClientProcessor.java | 7 ++++ .../DataSourceHealthCheckExclusionTest.java | 26 ++++++++++++++ ...ication-datasources-with-health.properties | 11 ++++++ .../ReactiveMySQLDataSourcesHealthCheck.java | 14 ++++++-- .../reactive-pg-client/deployment/pom.xml | 5 +++ .../deployment/ReactivePgClientProcessor.java | 7 ++++ .../DataSourceHealthCheckExclusionTest.java | 26 ++++++++++++++ ...ication-datasources-with-health.properties | 13 +++++++ .../ReactivePgDataSourcesHealthCheck.java | 14 ++++++-- 23 files changed, 274 insertions(+), 53 deletions(-) create mode 100644 extensions/datasource/deployment/src/main/java/io/quarkus/datasource/deployment/DataSourcesExcludedFromHealthChecksProcessor.java create mode 100644 extensions/datasource/runtime/src/main/java/io/quarkus/datasource/runtime/DataSourcesExcludedFromHealthChecksRecorder.java create mode 100644 extensions/reactive-mssql-client/deployment/src/test/java/io/quarkus/reactive/mssql/client/DataSourceHealthCheckExclusionTest.java create mode 100644 extensions/reactive-mssql-client/deployment/src/test/resources/application-datasources-with-health.properties create mode 100644 extensions/reactive-mysql-client/deployment/src/test/java/io/quarkus/reactive/mysql/client/DataSourceHealthCheckExclusionTest.java create mode 100644 extensions/reactive-mysql-client/deployment/src/test/resources/application-datasources-with-health.properties create mode 100644 extensions/reactive-pg-client/deployment/src/test/java/io/quarkus/reactive/pg/client/DataSourceHealthCheckExclusionTest.java create mode 100644 extensions/reactive-pg-client/deployment/src/test/resources/application-datasources-with-health.properties diff --git a/extensions/agroal/deployment/src/main/java/io/quarkus/agroal/deployment/AgroalProcessor.java b/extensions/agroal/deployment/src/main/java/io/quarkus/agroal/deployment/AgroalProcessor.java index fc26bbd41c625..76c4207a38c3a 100644 --- a/extensions/agroal/deployment/src/main/java/io/quarkus/agroal/deployment/AgroalProcessor.java +++ b/extensions/agroal/deployment/src/main/java/io/quarkus/agroal/deployment/AgroalProcessor.java @@ -1,7 +1,5 @@ package io.quarkus.agroal.deployment; -import static io.quarkus.deployment.annotations.ExecutionTime.STATIC_INIT; - import java.sql.Driver; import java.util.ArrayList; import java.util.HashMap; @@ -35,7 +33,6 @@ import io.quarkus.datasource.deployment.spi.DefaultDataSourceDbKindBuildItem; import io.quarkus.datasource.runtime.DataSourceBuildTimeConfig; import io.quarkus.datasource.runtime.DataSourcesBuildTimeConfig; -import io.quarkus.datasource.runtime.DataSourcesExcludedFromHealthChecks; import io.quarkus.datasource.runtime.DataSourcesRuntimeConfig; import io.quarkus.deployment.Capabilities; import io.quarkus.deployment.Capability; @@ -336,15 +333,8 @@ private String resolveDriver(String dataSourceName, String dbKind, } @BuildStep - @Record(ExecutionTime.STATIC_INIT) - HealthBuildItem addHealthCheck(Capabilities capabilities, DataSourcesBuildTimeConfig dataSourcesBuildTimeConfig, - AgroalRecorder recorder, BuildProducer syntheticBeans) { + HealthBuildItem addHealthCheck(Capabilities capabilities, DataSourcesBuildTimeConfig dataSourcesBuildTimeConfig) { if (capabilities.isPresent(Capability.SMALLRYE_HEALTH)) { - syntheticBeans.produce(SyntheticBeanBuildItem.configure(DataSourcesExcludedFromHealthChecks.class) - .scope(Singleton.class) - .unremovable() - .supplier(recorder.dataSourcesExcludedFromHealthChecks(dataSourcesBuildTimeConfig)) - .done()); return new HealthBuildItem("io.quarkus.agroal.runtime.health.DataSourceHealthCheck", dataSourcesBuildTimeConfig.healthEnabled); } else { diff --git a/extensions/agroal/runtime/src/main/java/io/quarkus/agroal/runtime/AgroalRecorder.java b/extensions/agroal/runtime/src/main/java/io/quarkus/agroal/runtime/AgroalRecorder.java index a953583dc8330..3c52c35983506 100644 --- a/extensions/agroal/runtime/src/main/java/io/quarkus/agroal/runtime/AgroalRecorder.java +++ b/extensions/agroal/runtime/src/main/java/io/quarkus/agroal/runtime/AgroalRecorder.java @@ -1,15 +1,8 @@ package io.quarkus.agroal.runtime; -import java.util.ArrayList; -import java.util.List; -import java.util.Map; import java.util.function.Supplier; import io.agroal.api.AgroalDataSource; -import io.quarkus.datasource.common.runtime.DataSourceUtil; -import io.quarkus.datasource.runtime.DataSourceBuildTimeConfig; -import io.quarkus.datasource.runtime.DataSourcesBuildTimeConfig; -import io.quarkus.datasource.runtime.DataSourcesExcludedFromHealthChecks; import io.quarkus.datasource.runtime.DataSourcesRuntimeConfig; import io.quarkus.runtime.annotations.Recorder; @@ -35,24 +28,4 @@ public AgroalDataSource get() { } }; } - - public Supplier dataSourcesExcludedFromHealthChecks( - DataSourcesBuildTimeConfig dataSourcesBuildTimeConfig) { - return new Supplier() { - @Override - public DataSourcesExcludedFromHealthChecks get() { - List excludedNames = new ArrayList<>(); - if (dataSourcesBuildTimeConfig.defaultDataSource.healthExclude) { - excludedNames.add(DataSourceUtil.DEFAULT_DATASOURCE_NAME); - } - for (Map.Entry dataSource : dataSourcesBuildTimeConfig.namedDataSources - .entrySet()) { - if (dataSource.getValue().healthExclude) { - excludedNames.add(dataSource.getKey()); - } - } - return new DataSourcesExcludedFromHealthChecks(excludedNames); - } - }; - } } diff --git a/extensions/agroal/runtime/src/main/java/io/quarkus/agroal/runtime/health/DataSourceHealthCheck.java b/extensions/agroal/runtime/src/main/java/io/quarkus/agroal/runtime/health/DataSourceHealthCheck.java index 7f36c269f1ee2..1f753f95a0e42 100644 --- a/extensions/agroal/runtime/src/main/java/io/quarkus/agroal/runtime/health/DataSourceHealthCheck.java +++ b/extensions/agroal/runtime/src/main/java/io/quarkus/agroal/runtime/health/DataSourceHealthCheck.java @@ -3,7 +3,6 @@ import java.sql.Connection; import java.sql.SQLException; import java.util.HashMap; -import java.util.List; import java.util.Map; import java.util.Set; @@ -32,7 +31,7 @@ protected void init() { Set> beans = Arc.container().beanManager().getBeans(DataSource.class); DataSourcesExcludedFromHealthChecks excluded = Arc.container().instance(DataSourcesExcludedFromHealthChecks.class) .get(); - List excludedNames = excluded.getExcludedNames(); + Set excludedNames = excluded.getExcludedNames(); for (Bean bean : beans) { if (bean.getName() == null) { if (!excludedNames.contains(DataSourceUtil.DEFAULT_DATASOURCE_NAME)) { diff --git a/extensions/datasource/deployment/src/main/java/io/quarkus/datasource/deployment/DataSourcesExcludedFromHealthChecksProcessor.java b/extensions/datasource/deployment/src/main/java/io/quarkus/datasource/deployment/DataSourcesExcludedFromHealthChecksProcessor.java new file mode 100644 index 0000000000000..47c389cbeeb8f --- /dev/null +++ b/extensions/datasource/deployment/src/main/java/io/quarkus/datasource/deployment/DataSourcesExcludedFromHealthChecksProcessor.java @@ -0,0 +1,34 @@ +package io.quarkus.datasource.deployment; + +import static io.quarkus.deployment.annotations.ExecutionTime.STATIC_INIT; + +import javax.inject.Singleton; + +import io.quarkus.arc.deployment.SyntheticBeanBuildItem; +import io.quarkus.datasource.runtime.DataSourcesBuildTimeConfig; +import io.quarkus.datasource.runtime.DataSourcesExcludedFromHealthChecks; +import io.quarkus.datasource.runtime.DataSourcesExcludedFromHealthChecksRecorder; +import io.quarkus.deployment.Capabilities; +import io.quarkus.deployment.Capability; +import io.quarkus.deployment.annotations.BuildProducer; +import io.quarkus.deployment.annotations.BuildStep; +import io.quarkus.deployment.annotations.Record; + +public class DataSourcesExcludedFromHealthChecksProcessor { + + @BuildStep + @Record(STATIC_INIT) + void produceBean( + Capabilities capabilities, + DataSourcesExcludedFromHealthChecksRecorder recorder, + DataSourcesBuildTimeConfig config, + BuildProducer syntheticBeans) { + if (capabilities.isPresent(Capability.SMALLRYE_HEALTH)) { + syntheticBeans.produce(SyntheticBeanBuildItem.configure(DataSourcesExcludedFromHealthChecks.class) + .scope(Singleton.class) + .unremovable() + .runtimeValue(recorder.configureDataSourcesExcludedFromHealthChecks(config)) + .done()); + } + } +} diff --git a/extensions/datasource/runtime/src/main/java/io/quarkus/datasource/runtime/DataSourcesExcludedFromHealthChecks.java b/extensions/datasource/runtime/src/main/java/io/quarkus/datasource/runtime/DataSourcesExcludedFromHealthChecks.java index af46c9180151d..1069bf4bed79f 100644 --- a/extensions/datasource/runtime/src/main/java/io/quarkus/datasource/runtime/DataSourcesExcludedFromHealthChecks.java +++ b/extensions/datasource/runtime/src/main/java/io/quarkus/datasource/runtime/DataSourcesExcludedFromHealthChecks.java @@ -1,16 +1,16 @@ package io.quarkus.datasource.runtime; -import java.util.List; +import java.util.Set; public class DataSourcesExcludedFromHealthChecks { - private List excludedNames; + private final Set excludedNames; - public DataSourcesExcludedFromHealthChecks(List names) { - this.excludedNames = names; + public DataSourcesExcludedFromHealthChecks(Set excludedNames) { + this.excludedNames = excludedNames; } - public List getExcludedNames() { + public Set getExcludedNames() { return excludedNames; } } diff --git a/extensions/datasource/runtime/src/main/java/io/quarkus/datasource/runtime/DataSourcesExcludedFromHealthChecksRecorder.java b/extensions/datasource/runtime/src/main/java/io/quarkus/datasource/runtime/DataSourcesExcludedFromHealthChecksRecorder.java new file mode 100644 index 0000000000000..2c6eeb27622d9 --- /dev/null +++ b/extensions/datasource/runtime/src/main/java/io/quarkus/datasource/runtime/DataSourcesExcludedFromHealthChecksRecorder.java @@ -0,0 +1,30 @@ +package io.quarkus.datasource.runtime; + +import static java.util.stream.Collectors.toUnmodifiableSet; + +import java.util.Map; +import java.util.Set; +import java.util.stream.Stream; + +import io.quarkus.datasource.common.runtime.DataSourceUtil; +import io.quarkus.runtime.RuntimeValue; +import io.quarkus.runtime.annotations.Recorder; + +@Recorder +public class DataSourcesExcludedFromHealthChecksRecorder { + + public RuntimeValue configureDataSourcesExcludedFromHealthChecks( + DataSourcesBuildTimeConfig config) { + Stream.Builder builder = Stream.builder(); + if (config.defaultDataSource.healthExclude) { + builder.add(DataSourceUtil.DEFAULT_DATASOURCE_NAME); + } + for (Map.Entry dataSource : config.namedDataSources.entrySet()) { + if (dataSource.getValue().healthExclude) { + builder.add(dataSource.getKey()); + } + } + Set excludedNames = builder.build().collect(toUnmodifiableSet()); + return new RuntimeValue<>(new DataSourcesExcludedFromHealthChecks(excludedNames)); + } +} 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 ff7f9b7409019..78ff2e7e3d487 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 @@ -15,6 +15,8 @@ import io.quarkus.datasource.runtime.DataSourceBuildTimeConfig; import io.quarkus.datasource.runtime.DataSourcesBuildTimeConfig; import io.quarkus.datasource.runtime.DataSourcesRuntimeConfig; +import io.quarkus.deployment.Capabilities; +import io.quarkus.deployment.Capability; import io.quarkus.deployment.Feature; import io.quarkus.deployment.annotations.BuildProducer; import io.quarkus.deployment.annotations.BuildStep; @@ -93,11 +95,16 @@ void registerServiceBinding(BuildProducer dbKi */ @BuildStep void addHealthCheck( + Capabilities capabilities, BuildProducer healthChecks, DataSourcesBuildTimeConfig dataSourcesBuildTimeConfig, DataSourcesReactiveBuildTimeConfig dataSourcesReactiveBuildTimeConfig, List defaultDataSourceDbKindBuildItems, CurateOutcomeBuildItem curateOutcomeBuildItem) { + if (!capabilities.isPresent(Capability.SMALLRYE_HEALTH)) { + return; + } + if (!hasPools(dataSourcesBuildTimeConfig, dataSourcesReactiveBuildTimeConfig, defaultDataSourceDbKindBuildItems, curateOutcomeBuildItem)) { return; 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 b6ca074c3956e..78548f24d0ede 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 @@ -4,6 +4,7 @@ import java.util.HashMap; import java.util.Map; import java.util.Map.Entry; +import java.util.Set; import javax.annotation.PostConstruct; import javax.enterprise.context.ApplicationScoped; @@ -16,8 +17,10 @@ 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.DataSourcesExcludedFromHealthChecks; import io.quarkus.reactive.datasource.ReactiveDataSource; import io.vertx.mutiny.db2client.DB2Pool; @@ -33,8 +36,14 @@ class ReactiveDB2DataSourcesHealthCheck implements HealthCheck { @PostConstruct protected void init() { - for (InstanceHandle handle : Arc.container().select(DB2Pool.class, Any.Literal.INSTANCE).handles()) { - db2Pools.put(getDB2PoolName(handle.getBean()), handle.get()); + ArcContainer container = Arc.container(); + DataSourcesExcludedFromHealthChecks excluded = container.instance(DataSourcesExcludedFromHealthChecks.class).get(); + Set excludedNames = excluded.getExcludedNames(); + for (InstanceHandle handle : container.select(DB2Pool.class, Any.Literal.INSTANCE).handles()) { + String db2PoolName = getDB2PoolName(handle.getBean()); + if (!excludedNames.contains(db2PoolName)) { + db2Pools.put(db2PoolName, handle.get()); + } } } diff --git a/extensions/reactive-mssql-client/deployment/pom.xml b/extensions/reactive-mssql-client/deployment/pom.xml index d53634e42b686..e1511b1c1488b 100644 --- a/extensions/reactive-mssql-client/deployment/pom.xml +++ b/extensions/reactive-mssql-client/deployment/pom.xml @@ -60,6 +60,11 @@ quarkus-junit5-internal test + + io.quarkus + quarkus-smallrye-health-deployment + test + 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 ff0c8e3253c05..d4557ddbe1205 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 @@ -15,6 +15,8 @@ import io.quarkus.datasource.runtime.DataSourceBuildTimeConfig; import io.quarkus.datasource.runtime.DataSourcesBuildTimeConfig; import io.quarkus.datasource.runtime.DataSourcesRuntimeConfig; +import io.quarkus.deployment.Capabilities; +import io.quarkus.deployment.Capability; import io.quarkus.deployment.Feature; import io.quarkus.deployment.annotations.BuildProducer; import io.quarkus.deployment.annotations.BuildStep; @@ -90,11 +92,16 @@ void registerServiceBinding(BuildProducer dbKi */ @BuildStep void addHealthCheck( + Capabilities capabilities, BuildProducer healthChecks, DataSourcesBuildTimeConfig dataSourcesBuildTimeConfig, DataSourcesReactiveBuildTimeConfig dataSourcesReactiveBuildTimeConfig, List defaultDataSourceDbKindBuildItems, CurateOutcomeBuildItem curateOutcomeBuildItem) { + if (!capabilities.isPresent(Capability.SMALLRYE_HEALTH)) { + return; + } + if (!hasPools(dataSourcesBuildTimeConfig, dataSourcesReactiveBuildTimeConfig, defaultDataSourceDbKindBuildItems, curateOutcomeBuildItem)) { return; diff --git a/extensions/reactive-mssql-client/deployment/src/test/java/io/quarkus/reactive/mssql/client/DataSourceHealthCheckExclusionTest.java b/extensions/reactive-mssql-client/deployment/src/test/java/io/quarkus/reactive/mssql/client/DataSourceHealthCheckExclusionTest.java new file mode 100644 index 0000000000000..2745937d22e7d --- /dev/null +++ b/extensions/reactive-mssql-client/deployment/src/test/java/io/quarkus/reactive/mssql/client/DataSourceHealthCheckExclusionTest.java @@ -0,0 +1,26 @@ +package io.quarkus.reactive.mssql.client; + +import org.hamcrest.CoreMatchers; +import org.jboss.shrinkwrap.api.ShrinkWrap; +import org.jboss.shrinkwrap.api.spec.JavaArchive; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.RegisterExtension; + +import io.quarkus.test.QuarkusUnitTest; +import io.restassured.RestAssured; + +public class DataSourceHealthCheckExclusionTest { + + @RegisterExtension + static final QuarkusUnitTest config = new QuarkusUnitTest() + .setArchiveProducer(() -> ShrinkWrap.create(JavaArchive.class)) + .withConfigurationResource("application-datasources-with-health.properties"); + + @Test + public void testDataSourceHealthCheckExclusion() { + RestAssured.when().get("/q/health/ready") + .then() + .body("status", CoreMatchers.equalTo("UP")); + } + +} diff --git a/extensions/reactive-mssql-client/deployment/src/test/resources/application-datasources-with-health.properties b/extensions/reactive-mssql-client/deployment/src/test/resources/application-datasources-with-health.properties new file mode 100644 index 0000000000000..4fb0acc923234 --- /dev/null +++ b/extensions/reactive-mssql-client/deployment/src/test/resources/application-datasources-with-health.properties @@ -0,0 +1,11 @@ +quarkus.datasource.db-kind=mssql +quarkus.datasource.username=sa +quarkus.datasource.password=A_Str0ng_Required_Password +quarkus.datasource.reactive.url=${reactive-mssql.url} +# this data source is broken, but will be excluded from the health check, so the overall check should pass +quarkus.datasource."broken".db-kind=mssql +quarkus.datasource."broken".username=BROKEN +quarkus.datasource."broken".password=A_Str0ng_Required_Password +quarkus.datasource."broken".reactive.url=${reactive-mssql.url} +quarkus.datasource."broken".health-exclude=true +quarkus.datasource.health.enabled=true \ No newline at end of file diff --git a/extensions/reactive-mssql-client/runtime/src/main/java/io/quarkus/reactive/mssql/client/runtime/health/ReactiveMSSQLDataSourcesHealthCheck.java b/extensions/reactive-mssql-client/runtime/src/main/java/io/quarkus/reactive/mssql/client/runtime/health/ReactiveMSSQLDataSourcesHealthCheck.java index 15420bfe61c47..da79a9a2e7216 100644 --- a/extensions/reactive-mssql-client/runtime/src/main/java/io/quarkus/reactive/mssql/client/runtime/health/ReactiveMSSQLDataSourcesHealthCheck.java +++ b/extensions/reactive-mssql-client/runtime/src/main/java/io/quarkus/reactive/mssql/client/runtime/health/ReactiveMSSQLDataSourcesHealthCheck.java @@ -1,5 +1,7 @@ package io.quarkus.reactive.mssql.client.runtime.health; +import java.util.Set; + import javax.annotation.PostConstruct; import javax.enterprise.context.ApplicationScoped; import javax.enterprise.inject.Any; @@ -7,7 +9,9 @@ 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.runtime.DataSourcesExcludedFromHealthChecks; import io.quarkus.reactive.datasource.runtime.ReactiveDatasourceHealthCheck; import io.vertx.mssqlclient.MSSQLPool; @@ -21,8 +25,14 @@ public ReactiveMSSQLDataSourcesHealthCheck() { @PostConstruct protected void init() { - for (InstanceHandle handle : Arc.container().select(MSSQLPool.class, Any.Literal.INSTANCE).handles()) { - addPool(getPoolName(handle.getBean()), handle.get()); + ArcContainer container = Arc.container(); + DataSourcesExcludedFromHealthChecks excluded = container.instance(DataSourcesExcludedFromHealthChecks.class).get(); + Set excludedNames = excluded.getExcludedNames(); + for (InstanceHandle handle : container.select(MSSQLPool.class, Any.Literal.INSTANCE).handles()) { + String poolName = getPoolName(handle.getBean()); + if (!excludedNames.contains(poolName)) { + addPool(poolName, handle.get()); + } } } diff --git a/extensions/reactive-mysql-client/deployment/pom.xml b/extensions/reactive-mysql-client/deployment/pom.xml index 870cd4666b9f8..94f1c5c29736a 100644 --- a/extensions/reactive-mysql-client/deployment/pom.xml +++ b/extensions/reactive-mysql-client/deployment/pom.xml @@ -76,6 +76,11 @@ quarkus-junit5-internal test + + io.quarkus + quarkus-smallrye-health-deployment + test + 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 490eb8034fc20..13b282e330264 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 @@ -15,6 +15,8 @@ import io.quarkus.datasource.runtime.DataSourceBuildTimeConfig; import io.quarkus.datasource.runtime.DataSourcesBuildTimeConfig; import io.quarkus.datasource.runtime.DataSourcesRuntimeConfig; +import io.quarkus.deployment.Capabilities; +import io.quarkus.deployment.Capability; import io.quarkus.deployment.Feature; import io.quarkus.deployment.annotations.BuildProducer; import io.quarkus.deployment.annotations.BuildStep; @@ -93,11 +95,16 @@ void registerServiceBinding(BuildProducer dbKi */ @BuildStep void addHealthCheck( + Capabilities capabilities, BuildProducer healthChecks, DataSourcesBuildTimeConfig dataSourcesBuildTimeConfig, DataSourcesReactiveBuildTimeConfig dataSourcesReactiveBuildTimeConfig, List defaultDataSourceDbKindBuildItems, CurateOutcomeBuildItem curateOutcomeBuildItem) { + if (!capabilities.isPresent(Capability.SMALLRYE_HEALTH)) { + return; + } + if (!hasPools(dataSourcesBuildTimeConfig, dataSourcesReactiveBuildTimeConfig, defaultDataSourceDbKindBuildItems, curateOutcomeBuildItem)) { return; diff --git a/extensions/reactive-mysql-client/deployment/src/test/java/io/quarkus/reactive/mysql/client/DataSourceHealthCheckExclusionTest.java b/extensions/reactive-mysql-client/deployment/src/test/java/io/quarkus/reactive/mysql/client/DataSourceHealthCheckExclusionTest.java new file mode 100644 index 0000000000000..b08e1db8b7b44 --- /dev/null +++ b/extensions/reactive-mysql-client/deployment/src/test/java/io/quarkus/reactive/mysql/client/DataSourceHealthCheckExclusionTest.java @@ -0,0 +1,26 @@ +package io.quarkus.reactive.mysql.client; + +import org.hamcrest.CoreMatchers; +import org.jboss.shrinkwrap.api.ShrinkWrap; +import org.jboss.shrinkwrap.api.spec.JavaArchive; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.RegisterExtension; + +import io.quarkus.test.QuarkusUnitTest; +import io.restassured.RestAssured; + +public class DataSourceHealthCheckExclusionTest { + + @RegisterExtension + static final QuarkusUnitTest config = new QuarkusUnitTest() + .setArchiveProducer(() -> ShrinkWrap.create(JavaArchive.class)) + .withConfigurationResource("application-datasources-with-health.properties"); + + @Test + public void testDataSourceHealthCheckExclusion() { + RestAssured.when().get("/q/health/ready") + .then() + .body("status", CoreMatchers.equalTo("UP")); + } + +} diff --git a/extensions/reactive-mysql-client/deployment/src/test/resources/application-datasources-with-health.properties b/extensions/reactive-mysql-client/deployment/src/test/resources/application-datasources-with-health.properties new file mode 100644 index 0000000000000..d27699a782a3b --- /dev/null +++ b/extensions/reactive-mysql-client/deployment/src/test/resources/application-datasources-with-health.properties @@ -0,0 +1,11 @@ +quarkus.datasource.db-kind=mysql +quarkus.datasource.username=hibernate_orm_test +quarkus.datasource.password=hibernate_orm_test +quarkus.datasource.reactive.url=${reactive-mysql.url} +# this data source is broken, but will be excluded from the health check, so the overall check should pass +quarkus.datasource."broken".db-kind=mysql +quarkus.datasource."broken".username=BROKEN +quarkus.datasource."broken".password=hibernate_orm_test +quarkus.datasource."broken".reactive.url=${reactive-mysql.url} +quarkus.datasource."broken".health-exclude=true +quarkus.datasource.health.enabled=true \ No newline at end of file diff --git a/extensions/reactive-mysql-client/runtime/src/main/java/io/quarkus/reactive/mysql/client/runtime/health/ReactiveMySQLDataSourcesHealthCheck.java b/extensions/reactive-mysql-client/runtime/src/main/java/io/quarkus/reactive/mysql/client/runtime/health/ReactiveMySQLDataSourcesHealthCheck.java index 4cf78acaa85b3..c9420f2a0ddb1 100644 --- a/extensions/reactive-mysql-client/runtime/src/main/java/io/quarkus/reactive/mysql/client/runtime/health/ReactiveMySQLDataSourcesHealthCheck.java +++ b/extensions/reactive-mysql-client/runtime/src/main/java/io/quarkus/reactive/mysql/client/runtime/health/ReactiveMySQLDataSourcesHealthCheck.java @@ -1,5 +1,7 @@ package io.quarkus.reactive.mysql.client.runtime.health; +import java.util.Set; + import javax.annotation.PostConstruct; import javax.enterprise.context.ApplicationScoped; import javax.enterprise.inject.Any; @@ -7,7 +9,9 @@ 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.runtime.DataSourcesExcludedFromHealthChecks; import io.quarkus.reactive.datasource.runtime.ReactiveDatasourceHealthCheck; import io.vertx.mysqlclient.MySQLPool; @@ -21,8 +25,14 @@ public ReactiveMySQLDataSourcesHealthCheck() { @PostConstruct protected void init() { - for (InstanceHandle handle : Arc.container().select(MySQLPool.class, Any.Literal.INSTANCE).handles()) { - addPool(getPoolName(handle.getBean()), handle.get()); + ArcContainer container = Arc.container(); + DataSourcesExcludedFromHealthChecks excluded = container.instance(DataSourcesExcludedFromHealthChecks.class).get(); + Set excludedNames = excluded.getExcludedNames(); + for (InstanceHandle handle : container.select(MySQLPool.class, Any.Literal.INSTANCE).handles()) { + String poolName = getPoolName(handle.getBean()); + if (!excludedNames.contains(poolName)) { + addPool(poolName, handle.get()); + } } } diff --git a/extensions/reactive-pg-client/deployment/pom.xml b/extensions/reactive-pg-client/deployment/pom.xml index d11e5cbacef76..5dae7febfb301 100644 --- a/extensions/reactive-pg-client/deployment/pom.xml +++ b/extensions/reactive-pg-client/deployment/pom.xml @@ -60,6 +60,11 @@ quarkus-junit5-internal test + + io.quarkus + quarkus-smallrye-health-deployment + test + 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 15767fdcaf364..b79c052d757ef 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 @@ -15,6 +15,8 @@ import io.quarkus.datasource.runtime.DataSourceBuildTimeConfig; import io.quarkus.datasource.runtime.DataSourcesBuildTimeConfig; import io.quarkus.datasource.runtime.DataSourcesRuntimeConfig; +import io.quarkus.deployment.Capabilities; +import io.quarkus.deployment.Capability; import io.quarkus.deployment.Feature; import io.quarkus.deployment.annotations.BuildProducer; import io.quarkus.deployment.annotations.BuildStep; @@ -95,11 +97,16 @@ ServiceStartBuildItem build(BuildProducer feature, */ @BuildStep void addHealthCheck( + Capabilities capabilities, BuildProducer healthChecks, DataSourcesBuildTimeConfig dataSourcesBuildTimeConfig, DataSourcesReactiveBuildTimeConfig dataSourcesReactiveBuildTimeConfig, List defaultDataSourceDbKindBuildItems, CurateOutcomeBuildItem curateOutcomeBuildItem) { + if (!capabilities.isPresent(Capability.SMALLRYE_HEALTH)) { + return; + } + if (!hasPools(dataSourcesBuildTimeConfig, dataSourcesReactiveBuildTimeConfig, defaultDataSourceDbKindBuildItems, curateOutcomeBuildItem)) { return; diff --git a/extensions/reactive-pg-client/deployment/src/test/java/io/quarkus/reactive/pg/client/DataSourceHealthCheckExclusionTest.java b/extensions/reactive-pg-client/deployment/src/test/java/io/quarkus/reactive/pg/client/DataSourceHealthCheckExclusionTest.java new file mode 100644 index 0000000000000..09ad8bb8f7d02 --- /dev/null +++ b/extensions/reactive-pg-client/deployment/src/test/java/io/quarkus/reactive/pg/client/DataSourceHealthCheckExclusionTest.java @@ -0,0 +1,26 @@ +package io.quarkus.reactive.pg.client; + +import org.hamcrest.CoreMatchers; +import org.jboss.shrinkwrap.api.ShrinkWrap; +import org.jboss.shrinkwrap.api.spec.JavaArchive; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.RegisterExtension; + +import io.quarkus.test.QuarkusUnitTest; +import io.restassured.RestAssured; + +public class DataSourceHealthCheckExclusionTest { + + @RegisterExtension + static final QuarkusUnitTest config = new QuarkusUnitTest() + .setArchiveProducer(() -> ShrinkWrap.create(JavaArchive.class)) + .withConfigurationResource("application-datasources-with-health.properties"); + + @Test + public void testDataSourceHealthCheckExclusion() { + RestAssured.when().get("/q/health/ready") + .then() + .body("status", CoreMatchers.equalTo("UP")); + } + +} diff --git a/extensions/reactive-pg-client/deployment/src/test/resources/application-datasources-with-health.properties b/extensions/reactive-pg-client/deployment/src/test/resources/application-datasources-with-health.properties new file mode 100644 index 0000000000000..c3360ad688ed4 --- /dev/null +++ b/extensions/reactive-pg-client/deployment/src/test/resources/application-datasources-with-health.properties @@ -0,0 +1,13 @@ +quarkus.datasource.db-kind=postgresql +quarkus.datasource.username=hibernate_orm_test +quarkus.datasource.password=hibernate_orm_test +quarkus.datasource.reactive.url=${reactive-postgres.url} +quarkus.datasource.reactive.postgresql.pipelining-limit=10 +# this data source is broken, but will be excluded from the health check, so the overall check should pass +quarkus.datasource."broken".db-kind=postgresql +quarkus.datasource."broken".username=BROKEN +quarkus.datasource."broken".password=hibernate_orm_test +quarkus.datasource."broken".reactive.url=${reactive-postgres.url} +quarkus.datasource."broken".reactive.postgresql.pipelining-limit=7 +quarkus.datasource."broken".health-exclude=true +quarkus.datasource.health.enabled=true \ No newline at end of file diff --git a/extensions/reactive-pg-client/runtime/src/main/java/io/quarkus/reactive/pg/client/runtime/health/ReactivePgDataSourcesHealthCheck.java b/extensions/reactive-pg-client/runtime/src/main/java/io/quarkus/reactive/pg/client/runtime/health/ReactivePgDataSourcesHealthCheck.java index ff5b22afe419b..c84d420677022 100644 --- a/extensions/reactive-pg-client/runtime/src/main/java/io/quarkus/reactive/pg/client/runtime/health/ReactivePgDataSourcesHealthCheck.java +++ b/extensions/reactive-pg-client/runtime/src/main/java/io/quarkus/reactive/pg/client/runtime/health/ReactivePgDataSourcesHealthCheck.java @@ -1,5 +1,7 @@ package io.quarkus.reactive.pg.client.runtime.health; +import java.util.Set; + import javax.annotation.PostConstruct; import javax.enterprise.context.ApplicationScoped; import javax.enterprise.inject.Any; @@ -7,7 +9,9 @@ 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.runtime.DataSourcesExcludedFromHealthChecks; import io.quarkus.reactive.datasource.runtime.ReactiveDatasourceHealthCheck; import io.vertx.pgclient.PgPool; @@ -21,8 +25,14 @@ public ReactivePgDataSourcesHealthCheck() { @PostConstruct protected void init() { - for (InstanceHandle handle : Arc.container().select(PgPool.class, Any.Literal.INSTANCE).handles()) { - addPool(getPoolName(handle.getBean()), handle.get()); + ArcContainer container = Arc.container(); + DataSourcesExcludedFromHealthChecks excluded = container.instance(DataSourcesExcludedFromHealthChecks.class).get(); + Set excludedNames = excluded.getExcludedNames(); + for (InstanceHandle handle : container.select(PgPool.class, Any.Literal.INSTANCE).handles()) { + String poolName = getPoolName(handle.getBean()); + if (!excludedNames.contains(poolName)) { + addPool(poolName, handle.get()); + } } }