diff --git a/extensions/datasource/deployment-spi/src/main/java/io/quarkus/datasource/deployment/spi/DevServicesDatasourceConfigurationHandlerBuildItem.java b/extensions/datasource/deployment-spi/src/main/java/io/quarkus/datasource/deployment/spi/DevServicesDatasourceConfigurationHandlerBuildItem.java index 0b246e4a123e6..65a1a1a02138d 100644 --- a/extensions/datasource/deployment-spi/src/main/java/io/quarkus/datasource/deployment/spi/DevServicesDatasourceConfigurationHandlerBuildItem.java +++ b/extensions/datasource/deployment-spi/src/main/java/io/quarkus/datasource/deployment/spi/DevServicesDatasourceConfigurationHandlerBuildItem.java @@ -3,6 +3,7 @@ import java.util.Collections; import java.util.Map; import java.util.function.BiFunction; +import java.util.function.Function; import java.util.function.Predicate; import io.quarkus.builder.item.MultiBuildItem; @@ -85,17 +86,31 @@ private static String datasourceURLPropName(String dsName) { } public static DevServicesDatasourceConfigurationHandlerBuildItem reactive(String dbKind) { + return reactive(dbKind, new Function() { + @Override + public String apply(String url) { + return url.replaceFirst("jdbc:", "vertx-reactive:"); + } + }); + } + + public static DevServicesDatasourceConfigurationHandlerBuildItem reactive(String dbKind, + Function jdbcUrlTransformer) { return new DevServicesDatasourceConfigurationHandlerBuildItem(dbKind, new BiFunction>() { @Override public Map apply(String dsName, DevServicesDatasourceProvider.RunningDevServicesDatasource runningDevDb) { + String url = jdbcUrlTransformer.apply(runningDevDb.getUrl()); if (dsName == null) { - return Collections.singletonMap("quarkus.datasource.reactive.url", - runningDevDb.getUrl().replaceFirst("jdbc:", "vertx-reactive:")); + return Collections.singletonMap("quarkus.datasource.reactive.url", url); } else { - return Collections.singletonMap("quarkus.datasource.\"" + dsName + "\".reactive.url", - runningDevDb.getUrl().replaceFirst("jdbc:", "vertx-reactive:")); + // we use quoted and unquoted versions because depending on whether a user configured other JDBC properties + // one of the URLs may be ignored + // see https://github.com/quarkusio/quarkus/issues/21387 + return Map.of( + datasourceReactiveURLPropName(dsName, false), url, + datasourceReactiveURLPropName(dsName, true), url); } } }, new Predicate() { @@ -104,10 +119,24 @@ public boolean test(String dsName) { if (dsName == null) { return ConfigUtils.isPropertyPresent("quarkus.datasource.reactive.url"); } else { - return ConfigUtils.isPropertyPresent("quarkus.datasource.\"" + dsName + "\".reactive.url") || - ConfigUtils.isPropertyPresent("quarkus.datasource." + dsName + ".reactive.url"); + return ConfigUtils.isPropertyPresent(datasourceReactiveURLPropName(dsName, false)) || + ConfigUtils.isPropertyPresent(datasourceReactiveURLPropName(dsName, true)); } } }); } + + private static String datasourceReactiveURLPropName(String dsName, boolean quotedName) { + StringBuilder key = new StringBuilder("quarkus.datasource"); + key.append('.'); + if (quotedName) { + key.append('"'); + } + key.append(dsName); + if (quotedName) { + key.append('"'); + } + key.append(".reactive.url"); + return key.toString(); + } } diff --git a/extensions/reactive-mssql-client/deployment/pom.xml b/extensions/reactive-mssql-client/deployment/pom.xml index 986ccd6f20919..1e9e6a924112c 100644 --- a/extensions/reactive-mssql-client/deployment/pom.xml +++ b/extensions/reactive-mssql-client/deployment/pom.xml @@ -64,6 +64,11 @@ quarkus-smallrye-health-deployment test + + org.assertj + assertj-core + 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 02a98ae5f3e0d..f7e517d21257a 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 @@ -2,6 +2,7 @@ import java.util.List; import java.util.Optional; +import java.util.function.Function; import javax.enterprise.context.ApplicationScoped; @@ -83,7 +84,16 @@ ServiceStartBuildItem build(BuildProducer feature, @BuildStep DevServicesDatasourceConfigurationHandlerBuildItem devDbHandler() { - return DevServicesDatasourceConfigurationHandlerBuildItem.reactive(DatabaseKind.MSSQL); + return DevServicesDatasourceConfigurationHandlerBuildItem.reactive(DatabaseKind.MSSQL, new Function() { + @Override + public String apply(String url) { + url = url.replaceFirst("jdbc:", "vertx-reactive:"); + if (url.endsWith(";encrypt=false")) { + return url.substring(0, url.length() - ";encrypt=false".length()); + } + return url; + } + }); } @BuildStep diff --git a/extensions/reactive-mssql-client/deployment/src/test/java/io/quarkus/reactive/mssql/client/DevServicesMsSQLDatasourceTestCase.java b/extensions/reactive-mssql-client/deployment/src/test/java/io/quarkus/reactive/mssql/client/DevServicesMsSQLDatasourceTestCase.java new file mode 100644 index 0000000000000..13d9012c7e235 --- /dev/null +++ b/extensions/reactive-mssql-client/deployment/src/test/java/io/quarkus/reactive/mssql/client/DevServicesMsSQLDatasourceTestCase.java @@ -0,0 +1,40 @@ +package io.quarkus.reactive.mssql.client; + +import static org.assertj.core.api.Assertions.assertThat; + +import java.time.Duration; +import java.util.Locale; +import java.util.logging.Level; +import java.util.logging.LogRecord; + +import javax.inject.Inject; + +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.RegisterExtension; + +import io.quarkus.test.QuarkusUnitTest; +import io.vertx.mutiny.mssqlclient.MSSQLPool; + +public class DevServicesMsSQLDatasourceTestCase { + + @RegisterExtension + static QuarkusUnitTest test = new QuarkusUnitTest() + .withApplicationRoot((jar) -> jar + .addAsResource("container-license-acceptance.txt")) + // Expect no warnings from reactive + .setLogRecordPredicate(record -> record.getLevel().intValue() >= Level.WARNING.intValue() + && record.getMessage().toLowerCase(Locale.ENGLISH).contains("reactive")) + .assertLogRecords(records -> assertThat(records) + // This is just to get meaningful error messages, as LogRecord doesn't have a toString() + .extracting(LogRecord::getMessage) + .isEmpty()); + + @Inject + MSSQLPool pool; + + @Test + public void testDatasource() throws Exception { + pool.withConnection(conn -> conn.query("SELECT 1").execute().replaceWithVoid()) + .await().atMost(Duration.ofMinutes(2)); + } +}