diff --git a/bom/application/pom.xml b/bom/application/pom.xml
index 0476256b31b27..85cfbb70c0695 100644
--- a/bom/application/pom.xml
+++ b/bom/application/pom.xml
@@ -208,6 +208,7 @@
1.0.0.Beta1
1.2.0.Final
1.10.0
+ 1.15.1
@@ -321,6 +322,14 @@
import
+
+
+ org.testcontainers
+ testcontainers-bom
+ ${testcontainers.version}
+ pom
+ import
+
@@ -506,6 +515,11 @@
quarkus-datasource-common
${project.version}
+
+ io.quarkus
+ quarkus-datasource-deployment-spi
+ ${project.version}
+
io.quarkus
quarkus-datasource
@@ -516,6 +530,31 @@
quarkus-datasource-deployment
${project.version}
+
+ io.quarkus
+ quarkus-devdb-postgresql
+ ${project.version}
+
+
+ io.quarkus
+ quarkus-devdb-h2
+ ${project.version}
+
+
+ io.quarkus
+ quarkus-devdb-mysql
+ ${project.version}
+
+
+ io.quarkus
+ quarkus-devdb-mariadb
+ ${project.version}
+
+
+ io.quarkus
+ quarkus-devdb-derby
+ ${project.version}
+
io.quarkus
quarkus-elasticsearch-rest-client-common
diff --git a/build-parent/pom.xml b/build-parent/pom.xml
index 0920251660292..9eee450da23f1 100644
--- a/build-parent/pom.xml
+++ b/build-parent/pom.xml
@@ -481,14 +481,12 @@
io.rest-assured:*
org.assertj:*
org.junit.jupiter:*
- org.testcontainers:*
io.quarkus:quarkus-test-*:*:*:test
io.rest-assured:*:*:*:test
org.assertj:*:*:*:test
org.junit.jupiter:*:*:*:test
- org.testcontainers:*:*:*:test
Found test dependencies with wrong scope:
diff --git a/core/deployment/src/main/java/io/quarkus/runner/bootstrap/AugmentActionImpl.java b/core/deployment/src/main/java/io/quarkus/runner/bootstrap/AugmentActionImpl.java
index b73e99541793b..ffeb9cf08e559 100644
--- a/core/deployment/src/main/java/io/quarkus/runner/bootstrap/AugmentActionImpl.java
+++ b/core/deployment/src/main/java/io/quarkus/runner/bootstrap/AugmentActionImpl.java
@@ -1,9 +1,11 @@
package io.quarkus.runner.bootstrap;
import java.io.File;
+import java.lang.reflect.InvocationTargetException;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.StandardOpenOption;
+import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Map;
@@ -13,6 +15,7 @@
import java.util.concurrent.ConcurrentHashMap;
import java.util.function.BiConsumer;
import java.util.function.Consumer;
+import java.util.function.Function;
import java.util.stream.Collectors;
import org.eclipse.microprofile.config.spi.ConfigProviderResolver;
@@ -132,6 +135,55 @@ public AugmentActionImpl(CuratedApplication curatedApplication, List[] targets = Arrays.stream(finalOutputs)
+ .map(new Function>() {
+ @Override
+ public Class extends BuildItem> apply(String s) {
+ try {
+ return (Class extends BuildItem>) Class.forName(s, false, classLoader);
+ } catch (ClassNotFoundException e) {
+ throw new RuntimeException(e);
+ }
+ }
+ }).toArray(Class[]::new);
+ BuildResult result = runAugment(true, Collections.emptySet(), null, classLoader, targets);
+
+ String debugSourcesDir = BootstrapDebug.DEBUG_SOURCES_DIR;
+ if (debugSourcesDir != null) {
+ for (GeneratedClassBuildItem i : result.consumeMulti(GeneratedClassBuildItem.class)) {
+ try {
+ if (i.getSource() != null) {
+ File debugPath = new File(debugSourcesDir);
+ if (!debugPath.exists()) {
+ debugPath.mkdir();
+ }
+ File sourceFile = new File(debugPath, i.getName() + ".zig");
+ sourceFile.getParentFile().mkdirs();
+ Files.write(sourceFile.toPath(), i.getSource().getBytes(StandardCharsets.UTF_8),
+ StandardOpenOption.CREATE);
+ log.infof("Wrote source: %s", sourceFile.getAbsolutePath());
+ } else {
+ log.infof("Source not available: %s", i.getName());
+ }
+ } catch (Exception t) {
+ log.errorf(t, "Failed to write debug source file: %s", i.getName());
+ }
+ }
+ }
+ try {
+ BiConsumer
+
+ io.quarkus
+ quarkus-datasource-deployment-spi
+
diff --git a/extensions/datasource/deployment/src/main/java/io/quarkus/datasource/deployment/DummyForJavadoc.java b/extensions/datasource/deployment/src/main/java/io/quarkus/datasource/deployment/DummyForJavadoc.java
deleted file mode 100644
index 02399e135310f..0000000000000
--- a/extensions/datasource/deployment/src/main/java/io/quarkus/datasource/deployment/DummyForJavadoc.java
+++ /dev/null
@@ -1,8 +0,0 @@
-package io.quarkus.datasource.deployment;
-
-/**
- * Quick workaround to have at least one public class and generate a Javadoc jar.
- */
-public class DummyForJavadoc {
-
-}
diff --git a/extensions/datasource/deployment/src/main/java/io/quarkus/datasource/deployment/devdb/DevDBProcessor.java b/extensions/datasource/deployment/src/main/java/io/quarkus/datasource/deployment/devdb/DevDBProcessor.java
new file mode 100644
index 0000000000000..e4b4135306693
--- /dev/null
+++ b/extensions/datasource/deployment/src/main/java/io/quarkus/datasource/deployment/devdb/DevDBProcessor.java
@@ -0,0 +1,206 @@
+package io.quarkus.datasource.deployment.devdb;
+
+import java.io.Closeable;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
+import java.util.Optional;
+import java.util.stream.Collectors;
+
+import org.eclipse.microprofile.config.ConfigProvider;
+import org.jboss.logging.Logger;
+
+import io.quarkus.datasource.deployment.spi.DefaultDataSourceDbKindBuildItem;
+import io.quarkus.datasource.deployment.spi.DevDBProvider;
+import io.quarkus.datasource.deployment.spi.DevDbConfigurationHandlerBuildItem;
+import io.quarkus.datasource.deployment.spi.DevDbResultBuildItem;
+import io.quarkus.datasource.runtime.DataSourceBuildTimeConfig;
+import io.quarkus.datasource.runtime.DataSourcesBuildTimeConfig;
+import io.quarkus.deployment.IsNormal;
+import io.quarkus.deployment.annotations.BuildProducer;
+import io.quarkus.deployment.annotations.BuildStep;
+import io.quarkus.deployment.builditem.RunTimeConfigurationDefaultBuildItem;
+import io.quarkus.deployment.builditem.ServiceStartBuildItem;
+import io.quarkus.deployment.pkg.builditem.CurateOutcomeBuildItem;
+
+public class DevDBProcessor {
+
+ private static final Logger log = Logger.getLogger(DevDBProcessor.class);
+
+ static volatile List databases;
+
+ static volatile Map cachedProperties;
+
+ static volatile boolean first = true;
+
+ @BuildStep(onlyIfNot = IsNormal.class)
+ DevDbResultBuildItem launchDatabases(CurateOutcomeBuildItem curateOutcomeBuildItem,
+ List installedDrivers,
+ List devDBProviders,
+ DataSourcesBuildTimeConfig dataSourceBuildTimeConfig,
+ BuildProducer runTimeConfigurationDefaultBuildItemBuildProducer,
+ List configurationHandlerBuildItems,
+ BuildProducer serviceStartBuildItemBuildProducer) {
+ //figure out if we need to shut down and restart existing databases
+ //if not and the DB's have already started we just return
+ if (databases != null) {
+ boolean restartRequired = false;
+ for (Map.Entry i : cachedProperties.entrySet()) {
+ if (!Objects.equals(i.getValue(),
+ ConfigProvider.getConfig().getOptionalValue(i.getKey(), String.class).orElse(null))) {
+ restartRequired = true;
+ break;
+ }
+ }
+ if (!restartRequired) {
+ return null;
+ }
+ for (Closeable i : databases) {
+ try {
+ i.close();
+ } catch (Throwable e) {
+ log.error("Failed to stop database", e);
+ }
+ }
+ databases = null;
+ cachedProperties = null;
+ }
+ DevDbResultBuildItem.DbResult defaultResult;
+ Map namedResults = new HashMap<>();
+ //now we need to figure out if we need to launch some databases
+ //note that because we run in dev and test mode only we know the runtime
+ //config at build time, as they both execute in the same JVM
+
+ //to keep things simpler for now we are only going to support this for the default datasource
+ //support for named datasources will come later
+
+ Map propertiesMap = new HashMap<>();
+ List closeableList = new ArrayList<>();
+ Map> configHandlersByDbType = configurationHandlerBuildItems.stream()
+ .collect(Collectors.toMap(DevDbConfigurationHandlerBuildItem::getDbKind, Collections::singletonList,
+ (configurationHandlerBuildItems1, configurationHandlerBuildItems2) -> {
+ List ret = new ArrayList<>();
+ ret.addAll(configurationHandlerBuildItems1);
+ ret.addAll(configurationHandlerBuildItems2);
+ return ret;
+ }));
+ Map devDBProviderMap = devDBProviders.stream()
+ .collect(Collectors.toMap(DevDBProviderBuildItem::getDatabase, DevDBProviderBuildItem::getDevDBProvider));
+
+ defaultResult = startDevDb(null, curateOutcomeBuildItem, installedDrivers, devDBProviderMap,
+ dataSourceBuildTimeConfig.defaultDataSource,
+ configHandlersByDbType, propertiesMap, closeableList);
+ if (defaultResult != null) {
+ for (Map.Entry i : defaultResult.getConfigProperties().entrySet()) {
+ runTimeConfigurationDefaultBuildItemBuildProducer
+ .produce(new RunTimeConfigurationDefaultBuildItem(i.getKey(), i.getValue()));
+ }
+ }
+ for (Map.Entry entry : dataSourceBuildTimeConfig.namedDataSources.entrySet()) {
+ DevDbResultBuildItem.DbResult result = startDevDb(entry.getKey(), curateOutcomeBuildItem, installedDrivers,
+ devDBProviderMap, entry.getValue(), configHandlersByDbType, propertiesMap, closeableList);
+ if (result != null) {
+ namedResults.put(entry.getKey(), result);
+ for (Map.Entry i : result.getConfigProperties().entrySet()) {
+ runTimeConfigurationDefaultBuildItemBuildProducer
+ .produce(new RunTimeConfigurationDefaultBuildItem(i.getKey(), i.getValue()));
+ }
+ }
+ }
+
+ if (first) {
+ first = false;
+ Runtime.getRuntime().addShutdownHook(new Thread(new Runnable() {
+ @Override
+ public void run() {
+ if (databases != null) {
+ for (Closeable i : databases) {
+ try {
+ i.close();
+ } catch (Throwable t) {
+ log.error("Failed to stop database", t);
+ }
+ }
+ }
+ }
+ }, "Database shutdown thread"));
+ }
+ databases = closeableList;
+ cachedProperties = propertiesMap;
+ return new DevDbResultBuildItem(defaultResult, namedResults);
+ }
+
+ private DevDbResultBuildItem.DbResult startDevDb(String dbName, CurateOutcomeBuildItem curateOutcomeBuildItem,
+ List installedDrivers,
+ Map devDBProviders, DataSourceBuildTimeConfig dataSourceBuildTimeConfig,
+ Map> configurationHandlerBuildItems,
+ Map propertiesMap, List closeableList) {
+ Optional defaultDbKind = DefaultDataSourceDbKindBuildItem.resolve(
+ dataSourceBuildTimeConfig.dbKind,
+ installedDrivers, curateOutcomeBuildItem);
+
+ if (!defaultDbKind.isPresent()) {
+ //nothing we can do
+ log.warn("Unable to determine a database type for " + (dbName == null ? "default datasource" : dbName));
+ return null;
+ }
+ DevDBProvider devDbProvider = devDBProviders.get(defaultDbKind.get());
+ List configHandlers = configurationHandlerBuildItems.get(defaultDbKind.get());
+ if (devDbProvider == null || configHandlers == null) {
+ log.warn("Unable to start devdb for " + (dbName == null ? "default datasource" : dbName)
+ + " as this datasource type (" + defaultDbKind.get() + ") does not support devdb");
+ return null;
+ }
+
+ Optional enabled = dataSourceBuildTimeConfig.devdb.enabled;
+ if (enabled.isPresent()) {
+ if (!enabled.get()) {
+ //explicitly disabled
+ log.debug("Not starting devdb for " + (dbName == null ? "default datasource" : dbName)
+ + " as it has been disabled in the config");
+ return null;
+ }
+ } else {
+ for (DevDbConfigurationHandlerBuildItem i : configHandlers) {
+ if (i.getCheckConfiguredFunction().test(dbName)) {
+ //this database has explicit configuration
+ //we don't start the devdb
+ log.debug("Not starting devdb for " + (dbName == null ? "default datasource" : dbName)
+ + " as it has explicit configuration");
+ return null;
+ }
+ }
+ }
+ //ok, so we know we need to start one
+
+ String prefix = "quarkus.datasource.";
+ if (dbName != null) {
+ prefix = prefix + dbName + ".";
+ }
+
+ DevDBProvider.RunningDevDb datasource = devDbProvider
+ .startDatabase(ConfigProvider.getConfig().getOptionalValue(prefix + "username", String.class),
+ ConfigProvider.getConfig().getOptionalValue(prefix + "password", String.class),
+ Optional.ofNullable(dbName), dataSourceBuildTimeConfig.devdb.imageName,
+ dataSourceBuildTimeConfig.devdb.properties);
+ closeableList.add(datasource.getCloseTask());
+
+ Map devDebProperties = new HashMap<>();
+ propertiesMap.put(prefix + "db-kind", dataSourceBuildTimeConfig.dbKind.orElse(null));
+ for (DevDbConfigurationHandlerBuildItem devDbConfigurationHandlerBuildItem : configHandlers) {
+ devDebProperties.putAll(devDbConfigurationHandlerBuildItem.getConfigProviderFunction()
+ .apply(dbName, datasource));
+ }
+ devDebProperties.put(prefix + "db-kind", defaultDbKind.get());
+ if (datasource.getUsername() != null) {
+ devDebProperties.put(prefix + "username", datasource.getUsername());
+ }
+ if (datasource.getPassword() != null) {
+ devDebProperties.put(prefix + "password", datasource.getPassword());
+ }
+ return new DevDbResultBuildItem.DbResult(defaultDbKind.get(), devDebProperties);
+ }
+}
diff --git a/extensions/datasource/deployment/src/main/java/io/quarkus/datasource/deployment/devdb/DevDBProviderBuildItem.java b/extensions/datasource/deployment/src/main/java/io/quarkus/datasource/deployment/devdb/DevDBProviderBuildItem.java
new file mode 100644
index 0000000000000..8e55797fe8d84
--- /dev/null
+++ b/extensions/datasource/deployment/src/main/java/io/quarkus/datasource/deployment/devdb/DevDBProviderBuildItem.java
@@ -0,0 +1,26 @@
+package io.quarkus.datasource.deployment.devdb;
+
+import io.quarkus.builder.item.MultiBuildItem;
+import io.quarkus.datasource.deployment.spi.DevDBProvider;
+
+/**
+ * A provider that knows how to start a database of a specific type.
+ */
+public final class DevDBProviderBuildItem extends MultiBuildItem {
+
+ private final String database;
+ private final DevDBProvider devDBProvider;
+
+ public DevDBProviderBuildItem(String database, DevDBProvider devDBProvider) {
+ this.database = database;
+ this.devDBProvider = devDBProvider;
+ }
+
+ public String getDatabase() {
+ return database;
+ }
+
+ public DevDBProvider getDevDBProvider() {
+ return devDBProvider;
+ }
+}
diff --git a/extensions/datasource/pom.xml b/extensions/datasource/pom.xml
index f4b99a7a33b0d..3831e40d41a48 100644
--- a/extensions/datasource/pom.xml
+++ b/extensions/datasource/pom.xml
@@ -17,5 +17,6 @@
common
deployment
runtime
+ deployment-spi
diff --git a/extensions/datasource/runtime/src/main/java/io/quarkus/datasource/runtime/DataSourceBuildTimeConfig.java b/extensions/datasource/runtime/src/main/java/io/quarkus/datasource/runtime/DataSourceBuildTimeConfig.java
index af5286e0d65f2..49ecb2bacdbe7 100644
--- a/extensions/datasource/runtime/src/main/java/io/quarkus/datasource/runtime/DataSourceBuildTimeConfig.java
+++ b/extensions/datasource/runtime/src/main/java/io/quarkus/datasource/runtime/DataSourceBuildTimeConfig.java
@@ -16,4 +16,10 @@ public class DataSourceBuildTimeConfig {
@ConvertWith(DatabaseKindConverter.class)
public Optional dbKind = Optional.empty();
+ /**
+ * Configuration for DevDB. DevDB allows Quarkus to automatically start a database in dev and test mode.
+ */
+ @ConfigItem
+ public DevDbBuildTimeConfig devdb;
+
}
diff --git a/extensions/datasource/runtime/src/main/java/io/quarkus/datasource/runtime/DataSourceRuntimeConfig.java b/extensions/datasource/runtime/src/main/java/io/quarkus/datasource/runtime/DataSourceRuntimeConfig.java
index 82c9f351e8ce0..843523b3b0849 100644
--- a/extensions/datasource/runtime/src/main/java/io/quarkus/datasource/runtime/DataSourceRuntimeConfig.java
+++ b/extensions/datasource/runtime/src/main/java/io/quarkus/datasource/runtime/DataSourceRuntimeConfig.java
@@ -36,4 +36,13 @@ public class DataSourceRuntimeConfig {
*/
@ConfigItem
public Optional credentialsProviderName = Optional.empty();
+
+ /**
+ * If this is true then when running in dev or test mode Quarkus will attempt to start a testcontainers based
+ * database with these provided settings.
+ *
+ * This is not supported for all databases, and will not work in production.
+ */
+ @ConfigItem(defaultValue = "false")
+ public boolean startContainer;
}
diff --git a/extensions/datasource/runtime/src/main/java/io/quarkus/datasource/runtime/DevDbBuildTimeConfig.java b/extensions/datasource/runtime/src/main/java/io/quarkus/datasource/runtime/DevDbBuildTimeConfig.java
new file mode 100644
index 0000000000000..90db447d88997
--- /dev/null
+++ b/extensions/datasource/runtime/src/main/java/io/quarkus/datasource/runtime/DevDbBuildTimeConfig.java
@@ -0,0 +1,37 @@
+package io.quarkus.datasource.runtime;
+
+import java.util.Map;
+import java.util.Optional;
+
+import io.quarkus.runtime.annotations.ConfigGroup;
+import io.quarkus.runtime.annotations.ConfigItem;
+
+@ConfigGroup
+public class DevDbBuildTimeConfig {
+
+ /**
+ * If DevDb has been explicitly enabled or disabled. DevDB is generally enabled
+ * by default, unless there is an existing configuration present.
+ *
+ * When DevDB is enabled Quarkus will attempt to automatically configure and start
+ * a database when running in Dev or Test mode.
+ */
+ @ConfigItem(name = ConfigItem.PARENT)
+ public Optional enabled = Optional.empty();
+
+ /**
+ * The container image name to use, for container based DevDB providers.
+ *
+ * If the provider is not container based (e.g. a H2 Database) then this has no effect.
+ */
+ @ConfigItem
+ public Optional imageName;
+
+ /**
+ * Generic properties that are passed into the DevDB database provider. These properties are provider
+ * speficic.
+ */
+ @ConfigItem
+ public Map properties;
+
+}
diff --git a/extensions/devdb/devdb-derby/pom.xml b/extensions/devdb/devdb-derby/pom.xml
new file mode 100644
index 0000000000000..2f1640a200dd9
--- /dev/null
+++ b/extensions/devdb/devdb-derby/pom.xml
@@ -0,0 +1,54 @@
+
+
+
+ quarkus-devdb-parent
+ io.quarkus
+ 999-SNAPSHOT
+
+ 4.0.0
+
+ quarkus-devdb-derby
+ Quarkus - DevDB - Derby
+
+
+ io.quarkus
+ quarkus-datasource-deployment
+
+
+ org.apache.derby
+ derbynet
+
+
+ org.apache.derby
+ derbytools
+
+
+ org.junit.jupiter
+ junit-jupiter
+ test
+
+
+ org.jboss.logmanager
+ jboss-logmanager-embedded
+ test
+
+
+
+
+
+ maven-compiler-plugin
+
+
+
+ io.quarkus
+ quarkus-extension-processor
+ ${project.version}
+
+
+
+
+
+
+
diff --git a/extensions/devdb/devdb-derby/src/main/java/io/quarkus/devdb/postgresql/deployment/DerbyDevDBProcessor.java b/extensions/devdb/devdb-derby/src/main/java/io/quarkus/devdb/postgresql/deployment/DerbyDevDBProcessor.java
new file mode 100644
index 0000000000000..beb0b43f0b4ff
--- /dev/null
+++ b/extensions/devdb/devdb-derby/src/main/java/io/quarkus/devdb/postgresql/deployment/DerbyDevDBProcessor.java
@@ -0,0 +1,68 @@
+package io.quarkus.devdb.postgresql.deployment;
+
+import java.io.Closeable;
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.util.Map;
+import java.util.Optional;
+
+import org.apache.derby.drda.NetworkServerControl;
+
+import io.quarkus.datasource.common.runtime.DatabaseKind;
+import io.quarkus.datasource.deployment.devdb.DevDBProviderBuildItem;
+import io.quarkus.datasource.deployment.spi.DevDBProvider;
+import io.quarkus.deployment.annotations.BuildStep;
+
+public class DerbyDevDBProcessor {
+
+ static final int NUMBER_OF_PINGS = 10;
+ static final int SLEEP_BETWEEN_PINGS = 500;
+
+ @BuildStep
+ DevDBProviderBuildItem setupDerby() {
+ return new DevDBProviderBuildItem(DatabaseKind.DERBY, new DevDBProvider() {
+ @Override
+ public RunningDevDb startDatabase(Optional username, Optional password,
+ Optional datasourceName, Optional imageName, Map additionalProperties) {
+ try {
+ NetworkServerControl server = new NetworkServerControl();
+ server.start(new PrintWriter(System.out));
+ for (int i = 1; i <= NUMBER_OF_PINGS; i++) {
+ try {
+ System.out.println("[INFO] Attempt " + i + " to see if Derby Network server started");
+ server.ping();
+ break;
+ } catch (Exception ex) {
+ if (i == NUMBER_OF_PINGS) {
+ System.out.println("Derby Network server failed to start");
+ ex.printStackTrace();
+ throw ex;
+ }
+ try {
+ Thread.sleep(SLEEP_BETWEEN_PINGS);
+ } catch (InterruptedException ignore) {
+ }
+ }
+ }
+ return new RunningDevDb(
+ "jdbc:derby://localhost:1527/memory:" + datasourceName.orElse("quarkus") + ";create=true", null,
+ null,
+ new Closeable() {
+ @Override
+ public void close() throws IOException {
+ try {
+ NetworkServerControl server = new NetworkServerControl();
+ server.shutdown();
+ System.out.println("[INFO] Derby database was shut down");
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+ }
+ });
+ } catch (Exception throwable) {
+ throw new RuntimeException(throwable);
+ }
+ }
+ });
+ }
+}
diff --git a/extensions/devdb/devdb-h2/pom.xml b/extensions/devdb/devdb-h2/pom.xml
new file mode 100644
index 0000000000000..6f03a709a75ff
--- /dev/null
+++ b/extensions/devdb/devdb-h2/pom.xml
@@ -0,0 +1,50 @@
+
+
+
+ quarkus-devdb-parent
+ io.quarkus
+ 999-SNAPSHOT
+
+ 4.0.0
+
+ quarkus-devdb-h2
+ Quarkus - DevDB - H2
+
+
+ io.quarkus
+ quarkus-datasource-deployment
+
+
+ com.h2database
+ h2
+
+
+ org.junit.jupiter
+ junit-jupiter
+ test
+
+
+ org.jboss.logmanager
+ jboss-logmanager-embedded
+ test
+
+
+
+
+
+ maven-compiler-plugin
+
+
+
+ io.quarkus
+ quarkus-extension-processor
+ ${project.version}
+
+
+
+
+
+
+
diff --git a/extensions/devdb/devdb-h2/src/main/java/io/quarkus/devdb/postgresql/deployment/H2DevDBProcessor.java b/extensions/devdb/devdb-h2/src/main/java/io/quarkus/devdb/postgresql/deployment/H2DevDBProcessor.java
new file mode 100644
index 0000000000000..4abd089abde4b
--- /dev/null
+++ b/extensions/devdb/devdb-h2/src/main/java/io/quarkus/devdb/postgresql/deployment/H2DevDBProcessor.java
@@ -0,0 +1,46 @@
+package io.quarkus.devdb.postgresql.deployment;
+
+import java.io.Closeable;
+import java.io.IOException;
+import java.sql.SQLException;
+import java.util.Map;
+import java.util.Optional;
+
+import org.h2.tools.Server;
+
+import io.quarkus.datasource.common.runtime.DatabaseKind;
+import io.quarkus.datasource.deployment.devdb.DevDBProviderBuildItem;
+import io.quarkus.datasource.deployment.spi.DevDBProvider;
+import io.quarkus.deployment.annotations.BuildStep;
+
+public class H2DevDBProcessor {
+
+ @BuildStep
+ DevDBProviderBuildItem setupH2() {
+ return new DevDBProviderBuildItem(DatabaseKind.H2, new DevDBProvider() {
+ @Override
+ public RunningDevDb startDatabase(Optional username, Optional password,
+ Optional datasourceName, Optional imageName, Map additionalProperties) {
+ try {
+ final Server tcpServer = Server.createTcpServer();
+ tcpServer.start();
+ System.out
+ .println("[INFO] H2 database started in TCP server mode; server status: " + tcpServer.getStatus());
+ return new RunningDevDb(
+ "jdbc:h2:tcp://localhost/mem:" + datasourceName.orElse("default") + ";DB_CLOSE_DELAY=-1", "sa",
+ "sa",
+ new Closeable() {
+ @Override
+ public void close() throws IOException {
+ tcpServer.stop();
+ System.out.println(
+ "[INFO] H2 database was shut down; server status: " + tcpServer.getStatus());
+ }
+ });
+ } catch (SQLException throwables) {
+ throw new RuntimeException(throwables);
+ }
+ }
+ });
+ }
+}
diff --git a/extensions/devdb/devdb-mariadb/pom.xml b/extensions/devdb/devdb-mariadb/pom.xml
new file mode 100644
index 0000000000000..5ed621a8c981f
--- /dev/null
+++ b/extensions/devdb/devdb-mariadb/pom.xml
@@ -0,0 +1,50 @@
+
+
+
+ quarkus-devdb-parent
+ io.quarkus
+ 999-SNAPSHOT
+
+ 4.0.0
+
+ quarkus-devdb-mariadb
+ Quarkus - DevDB - MariaDB
+
+
+ io.quarkus
+ quarkus-datasource-deployment
+
+
+ org.testcontainers
+ mariadb
+
+
+ org.junit.jupiter
+ junit-jupiter
+ test
+
+
+ org.jboss.logmanager
+ jboss-logmanager-embedded
+ test
+
+
+
+
+
+ maven-compiler-plugin
+
+
+
+ io.quarkus
+ quarkus-extension-processor
+ ${project.version}
+
+
+
+
+
+
+
diff --git a/extensions/devdb/devdb-mariadb/src/main/java/io/quarkus/devdb/postgresql/deployment/MariaDBDebDBProcessor.java b/extensions/devdb/devdb-mariadb/src/main/java/io/quarkus/devdb/postgresql/deployment/MariaDBDebDBProcessor.java
new file mode 100644
index 0000000000000..9eee4e75d578c
--- /dev/null
+++ b/extensions/devdb/devdb-mariadb/src/main/java/io/quarkus/devdb/postgresql/deployment/MariaDBDebDBProcessor.java
@@ -0,0 +1,40 @@
+package io.quarkus.devdb.postgresql.deployment;
+
+import java.io.Closeable;
+import java.io.IOException;
+import java.util.Map;
+import java.util.Optional;
+
+import org.testcontainers.containers.MariaDBContainer;
+
+import io.quarkus.datasource.common.runtime.DatabaseKind;
+import io.quarkus.datasource.deployment.devdb.DevDBProviderBuildItem;
+import io.quarkus.datasource.deployment.spi.DevDBProvider;
+import io.quarkus.deployment.annotations.BuildStep;
+
+public class MariaDBDebDBProcessor {
+
+ @BuildStep
+ DevDBProviderBuildItem setupMariaDB() {
+ return new DevDBProviderBuildItem(DatabaseKind.MARIADB, new DevDBProvider() {
+ @Override
+ public RunningDevDb startDatabase(Optional username, Optional password,
+ Optional datasourceName, Optional imageName, Map additionalProperties) {
+ MariaDBContainer container = new MariaDBContainer(
+ imageName.orElse(MariaDBContainer.IMAGE + ":" + MariaDBContainer.DEFAULT_TAG))
+ .withPassword(password.orElse("quarkus"))
+ .withUsername(username.orElse("quarkus"))
+ .withDatabaseName(datasourceName.orElse("default"));
+ container.start();
+ return new RunningDevDb(container.getJdbcUrl(), container.getUsername(), container.getPassword(),
+ new Closeable() {
+ @Override
+ public void close() throws IOException {
+ container.stop();
+ }
+ });
+ }
+ });
+ }
+
+}
diff --git a/extensions/devdb/devdb-mysql/pom.xml b/extensions/devdb/devdb-mysql/pom.xml
new file mode 100644
index 0000000000000..2f2988d938042
--- /dev/null
+++ b/extensions/devdb/devdb-mysql/pom.xml
@@ -0,0 +1,50 @@
+
+
+
+ quarkus-devdb-parent
+ io.quarkus
+ 999-SNAPSHOT
+
+ 4.0.0
+
+ quarkus-devdb-mysql
+ Quarkus - DevDB - MySQL
+
+
+ io.quarkus
+ quarkus-datasource-deployment
+
+
+ org.testcontainers
+ mysql
+
+
+ org.junit.jupiter
+ junit-jupiter
+ test
+
+
+ org.jboss.logmanager
+ jboss-logmanager-embedded
+ test
+
+
+
+
+
+ maven-compiler-plugin
+
+
+
+ io.quarkus
+ quarkus-extension-processor
+ ${project.version}
+
+
+
+
+
+
+
diff --git a/extensions/devdb/devdb-mysql/src/main/java/io/quarkus/devdb/postgresql/deployment/MySQLDevDBProcessor.java b/extensions/devdb/devdb-mysql/src/main/java/io/quarkus/devdb/postgresql/deployment/MySQLDevDBProcessor.java
new file mode 100644
index 0000000000000..3ced01da9c05e
--- /dev/null
+++ b/extensions/devdb/devdb-mysql/src/main/java/io/quarkus/devdb/postgresql/deployment/MySQLDevDBProcessor.java
@@ -0,0 +1,40 @@
+package io.quarkus.devdb.postgresql.deployment;
+
+import java.io.Closeable;
+import java.io.IOException;
+import java.util.Map;
+import java.util.Optional;
+
+import org.testcontainers.containers.MySQLContainer;
+
+import io.quarkus.datasource.common.runtime.DatabaseKind;
+import io.quarkus.datasource.deployment.devdb.DevDBProviderBuildItem;
+import io.quarkus.datasource.deployment.spi.DevDBProvider;
+import io.quarkus.deployment.annotations.BuildStep;
+
+public class MySQLDevDBProcessor {
+
+ @BuildStep
+ DevDBProviderBuildItem setupMysql() {
+ return new DevDBProviderBuildItem(DatabaseKind.MYSQL, new DevDBProvider() {
+ @Override
+ public RunningDevDb startDatabase(Optional username, Optional password,
+ Optional datasourceName, Optional imageName, Map additionalProperties) {
+ MySQLContainer container = new MySQLContainer(
+ imageName.orElse(MySQLContainer.IMAGE + ":" + MySQLContainer.DEFAULT_TAG))
+ .withPassword(password.orElse("quarkus"))
+ .withUsername(username.orElse("quarkus"))
+ .withDatabaseName(datasourceName.orElse("default"));
+ container.start();
+ return new RunningDevDb(container.getJdbcUrl(), container.getUsername(), container.getPassword(),
+ new Closeable() {
+ @Override
+ public void close() throws IOException {
+ container.stop();
+ }
+ });
+ }
+ });
+ }
+
+}
diff --git a/extensions/devdb/devdb-postgresql/pom.xml b/extensions/devdb/devdb-postgresql/pom.xml
new file mode 100644
index 0000000000000..6509c716419de
--- /dev/null
+++ b/extensions/devdb/devdb-postgresql/pom.xml
@@ -0,0 +1,50 @@
+
+
+
+ quarkus-devdb-parent
+ io.quarkus
+ 999-SNAPSHOT
+
+ 4.0.0
+
+ quarkus-devdb-postgresql
+ Quarkus - DevDB - Postgresql
+
+
+ io.quarkus
+ quarkus-datasource-deployment
+
+
+ org.testcontainers
+ postgresql
+
+
+ org.junit.jupiter
+ junit-jupiter
+ test
+
+
+ org.jboss.logmanager
+ jboss-logmanager-embedded
+ test
+
+
+
+
+
+ maven-compiler-plugin
+
+
+
+ io.quarkus
+ quarkus-extension-processor
+ ${project.version}
+
+
+
+
+
+
+
diff --git a/extensions/devdb/devdb-postgresql/src/main/java/io/quarkus/devdb/postgresql/deployment/PostgresqlDevDBProcessor.java b/extensions/devdb/devdb-postgresql/src/main/java/io/quarkus/devdb/postgresql/deployment/PostgresqlDevDBProcessor.java
new file mode 100644
index 0000000000000..259c59281e235
--- /dev/null
+++ b/extensions/devdb/devdb-postgresql/src/main/java/io/quarkus/devdb/postgresql/deployment/PostgresqlDevDBProcessor.java
@@ -0,0 +1,40 @@
+package io.quarkus.devdb.postgresql.deployment;
+
+import java.io.Closeable;
+import java.io.IOException;
+import java.util.Map;
+import java.util.Optional;
+
+import org.testcontainers.containers.PostgreSQLContainer;
+
+import io.quarkus.datasource.common.runtime.DatabaseKind;
+import io.quarkus.datasource.deployment.devdb.DevDBProviderBuildItem;
+import io.quarkus.datasource.deployment.spi.DevDBProvider;
+import io.quarkus.deployment.annotations.BuildStep;
+
+public class PostgresqlDevDBProcessor {
+
+ @BuildStep
+ DevDBProviderBuildItem setupPostgres() {
+ return new DevDBProviderBuildItem(DatabaseKind.POSTGRESQL, new DevDBProvider() {
+ @Override
+ public RunningDevDb startDatabase(Optional username, Optional password,
+ Optional datasourceName, Optional imageName, Map additionalProperties) {
+ PostgreSQLContainer container = new PostgreSQLContainer(
+ imageName.orElse(PostgreSQLContainer.IMAGE + ":" + PostgreSQLContainer.DEFAULT_TAG))
+ .withPassword(password.orElse("quarkus"))
+ .withUsername(username.orElse("quarkus"))
+ .withDatabaseName(datasourceName.orElse("default"));
+ container.start();
+ return new RunningDevDb(container.getJdbcUrl(), container.getUsername(), container.getPassword(),
+ new Closeable() {
+ @Override
+ public void close() throws IOException {
+ container.stop();
+ }
+ });
+ }
+ });
+ }
+
+}
diff --git a/extensions/devdb/pom.xml b/extensions/devdb/pom.xml
new file mode 100644
index 0000000000000..fe0e4f0be9201
--- /dev/null
+++ b/extensions/devdb/pom.xml
@@ -0,0 +1,28 @@
+
+
+
+ quarkus-extensions-parent
+ io.quarkus
+ 999-SNAPSHOT
+ ../pom.xml
+
+ 4.0.0
+
+ quarkus-devdb-parent
+ Quarkus - DevDB
+
+ DevDB allows Quarkus to automatically configure and start databases in
+ dev and test mode.
+
+ pom
+
+ devdb-postgresql
+ devdb-mysql
+ devdb-mariadb
+ devdb-h2
+ devdb-derby
+
+
+
diff --git a/extensions/hibernate-reactive/deployment/src/main/java/io/quarkus/hibernate/reactive/deployment/HibernateReactiveProcessor.java b/extensions/hibernate-reactive/deployment/src/main/java/io/quarkus/hibernate/reactive/deployment/HibernateReactiveProcessor.java
index a83a76665adf5..36694f7f8cd6b 100644
--- a/extensions/hibernate-reactive/deployment/src/main/java/io/quarkus/hibernate/reactive/deployment/HibernateReactiveProcessor.java
+++ b/extensions/hibernate-reactive/deployment/src/main/java/io/quarkus/hibernate/reactive/deployment/HibernateReactiveProcessor.java
@@ -24,6 +24,7 @@
import org.hibernate.loader.BatchFetchStyle;
import io.quarkus.arc.deployment.AdditionalBeanBuildItem;
+import io.quarkus.datasource.deployment.spi.DefaultDataSourceDbKindBuildItem;
import io.quarkus.datasource.runtime.DataSourcesBuildTimeConfig;
import io.quarkus.deployment.Capability;
import io.quarkus.deployment.Feature;
@@ -40,6 +41,7 @@
import io.quarkus.deployment.builditem.nativeimage.NativeImageResourceBuildItem;
import io.quarkus.deployment.builditem.nativeimage.ReflectiveClassBuildItem;
import io.quarkus.deployment.configuration.ConfigurationError;
+import io.quarkus.deployment.pkg.builditem.CurateOutcomeBuildItem;
import io.quarkus.deployment.recording.RecorderContext;
import io.quarkus.hibernate.orm.deployment.HibernateConfigUtil;
import io.quarkus.hibernate.orm.deployment.HibernateOrmConfig;
@@ -119,7 +121,9 @@ public void buildReactivePersistenceUnit(
BuildProducer systemProperties,
BuildProducer nativeImageResources,
BuildProducer hotDeploymentWatchedFiles,
- BuildProducer persistenceUnitDescriptors) {
+ BuildProducer persistenceUnitDescriptors,
+ List defaultDataSourceDbKindBuildItems,
+ CurateOutcomeBuildItem curateOutcomeBuildItem) {
final boolean enableHR = hasEntities(domainObjects, nonJpaModelBuildItems);
if (!enableHR) {
@@ -139,7 +143,8 @@ public void buildReactivePersistenceUnit(
}
// we only support the default pool for now
- Optional dbKindOptional = dataSourcesBuildTimeConfig.defaultDataSource.dbKind;
+ Optional dbKindOptional = DefaultDataSourceDbKindBuildItem.resolve(
+ dataSourcesBuildTimeConfig.defaultDataSource.dbKind, defaultDataSourceDbKindBuildItems, curateOutcomeBuildItem);
if (dbKindOptional.isPresent()) {
final String dbKind = dbKindOptional.get();
ParsedPersistenceXmlDescriptor reactivePU = generateReactivePersistenceUnit(
diff --git a/extensions/jdbc/jdbc-db2/deployment/pom.xml b/extensions/jdbc/jdbc-db2/deployment/pom.xml
index 9bfe433e2ca74..4b25ac81ce157 100644
--- a/extensions/jdbc/jdbc-db2/deployment/pom.xml
+++ b/extensions/jdbc/jdbc-db2/deployment/pom.xml
@@ -25,6 +25,10 @@
io.quarkus
quarkus-agroal-spi
+
+ io.quarkus
+ quarkus-datasource-deployment-spi
+
io.quarkus
quarkus-jdbc-db2
diff --git a/extensions/jdbc/jdbc-db2/deployment/src/main/java/io/quarkus/jdbc/db2/deployment/JDBCDB2Processor.java b/extensions/jdbc/jdbc-db2/deployment/src/main/java/io/quarkus/jdbc/db2/deployment/JDBCDB2Processor.java
index b2936e9aaaa29..506033c7ec14a 100644
--- a/extensions/jdbc/jdbc-db2/deployment/src/main/java/io/quarkus/jdbc/db2/deployment/JDBCDB2Processor.java
+++ b/extensions/jdbc/jdbc-db2/deployment/src/main/java/io/quarkus/jdbc/db2/deployment/JDBCDB2Processor.java
@@ -1,10 +1,10 @@
package io.quarkus.jdbc.db2.deployment;
-import io.quarkus.agroal.spi.DefaultDataSourceDbKindBuildItem;
import io.quarkus.agroal.spi.JdbcDriverBuildItem;
import io.quarkus.arc.deployment.AdditionalBeanBuildItem;
import io.quarkus.arc.processor.BuiltinScope;
import io.quarkus.datasource.common.runtime.DatabaseKind;
+import io.quarkus.datasource.deployment.spi.DefaultDataSourceDbKindBuildItem;
import io.quarkus.deployment.Capabilities;
import io.quarkus.deployment.Capability;
import io.quarkus.deployment.Feature;
@@ -68,7 +68,7 @@ void registerServiceBinding(Capabilities capabilities,
serviceProvider.produce(
new ServiceProviderBuildItem("io.quarkus.kubernetes.service.binding.runtime.ServiceBindingConverter",
DB2ServiceBindingConverter.class.getName()));
- dbKind.produce(new DefaultDataSourceDbKindBuildItem(DatabaseKind.DB2));
}
+ dbKind.produce(new DefaultDataSourceDbKindBuildItem(DatabaseKind.DB2));
}
}
diff --git a/extensions/jdbc/jdbc-derby/deployment/pom.xml b/extensions/jdbc/jdbc-derby/deployment/pom.xml
index 60ac6c285bfa8..0fb78f016980f 100644
--- a/extensions/jdbc/jdbc-derby/deployment/pom.xml
+++ b/extensions/jdbc/jdbc-derby/deployment/pom.xml
@@ -17,6 +17,10 @@
io.quarkus
quarkus-core-deployment
+
+ io.quarkus
+ quarkus-datasource-deployment-spi
+
io.quarkus
quarkus-arc-deployment
@@ -29,6 +33,20 @@
io.quarkus
quarkus-jdbc-derby
+
+ io.quarkus
+ quarkus-devdb-derby
+
+
+ io.quarkus
+ quarkus-agroal-deployment
+ test
+
+
+ io.quarkus
+ quarkus-junit5-internal
+ test
+
diff --git a/extensions/jdbc/jdbc-derby/deployment/src/main/java/io/quarkus/jdbc/derby/deployment/JDBCDerbyProcessor.java b/extensions/jdbc/jdbc-derby/deployment/src/main/java/io/quarkus/jdbc/derby/deployment/JDBCDerbyProcessor.java
index ce5c278533ba8..e777f52db3330 100644
--- a/extensions/jdbc/jdbc-derby/deployment/src/main/java/io/quarkus/jdbc/derby/deployment/JDBCDerbyProcessor.java
+++ b/extensions/jdbc/jdbc-derby/deployment/src/main/java/io/quarkus/jdbc/derby/deployment/JDBCDerbyProcessor.java
@@ -4,6 +4,8 @@
import io.quarkus.arc.deployment.AdditionalBeanBuildItem;
import io.quarkus.arc.processor.BuiltinScope;
import io.quarkus.datasource.common.runtime.DatabaseKind;
+import io.quarkus.datasource.deployment.spi.DefaultDataSourceDbKindBuildItem;
+import io.quarkus.datasource.deployment.spi.DevDbConfigurationHandlerBuildItem;
import io.quarkus.deployment.Capabilities;
import io.quarkus.deployment.Capability;
import io.quarkus.deployment.Feature;
@@ -28,6 +30,11 @@ void registerDriver(BuildProducer jdbcDriver,
"org.apache.derby.jdbc.ClientXADataSource"));
}
+ @BuildStep
+ DevDbConfigurationHandlerBuildItem devDbHandler() {
+ return DevDbConfigurationHandlerBuildItem.jdbc(DatabaseKind.DERBY);
+ }
+
@BuildStep
void configureAgroalConnection(BuildProducer additionalBeans,
Capabilities capabilities) {
@@ -47,4 +54,8 @@ void registerDriverForReflection(BuildProducer reflect
reflectiveClass.produce(new ReflectiveClassBuildItem(false, false, org.apache.derby.jdbc.ClientDriver.class.getName()));
}
+ @BuildStep
+ void registerDefaultDbType(BuildProducer dbKind) {
+ dbKind.produce(new DefaultDataSourceDbKindBuildItem(DatabaseKind.DERBY));
+ }
}
diff --git a/extensions/jdbc/jdbc-derby/deployment/src/test/java/io/quarkus/jdbc/derby/deployment/DevDBDerbyDatasourceTestCase.java b/extensions/jdbc/jdbc-derby/deployment/src/test/java/io/quarkus/jdbc/derby/deployment/DevDBDerbyDatasourceTestCase.java
new file mode 100644
index 0000000000000..dfa59cb73bff7
--- /dev/null
+++ b/extensions/jdbc/jdbc-derby/deployment/src/test/java/io/quarkus/jdbc/derby/deployment/DevDBDerbyDatasourceTestCase.java
@@ -0,0 +1,51 @@
+package io.quarkus.jdbc.derby.deployment;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+import static org.junit.jupiter.api.Assertions.fail;
+
+import java.sql.Connection;
+import java.util.function.Supplier;
+
+import javax.inject.Inject;
+
+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.agroal.api.AgroalDataSource;
+import io.agroal.api.configuration.AgroalConnectionPoolConfiguration;
+import io.quarkus.test.QuarkusUnitTest;
+
+public class DevDBDerbyDatasourceTestCase {
+
+ @RegisterExtension
+ static QuarkusUnitTest test = new QuarkusUnitTest()
+ .setArchiveProducer(new Supplier() {
+ @Override
+ public JavaArchive get() {
+ return ShrinkWrap.create(JavaArchive.class);
+ }
+ });
+
+ @Inject
+ AgroalDataSource dataSource;
+
+ @Test
+ public void testDatasource() throws Exception {
+ AgroalConnectionPoolConfiguration configuration = null;
+
+ try {
+ configuration = dataSource.getConfiguration().connectionPoolConfiguration();
+ } catch (NullPointerException e) {
+ // we catch the NPE here as we have a proxycd and we can't test dataSource directly
+ fail("Datasource should not be null");
+ }
+ assertTrue(configuration.connectionFactoryConfiguration().jdbcUrl().contains("jdbc:derby:"));
+ assertEquals(20, configuration.maxSize());
+
+ try (Connection connection = dataSource.getConnection()) {
+ }
+ }
+}
diff --git a/extensions/jdbc/jdbc-h2/deployment/pom.xml b/extensions/jdbc/jdbc-h2/deployment/pom.xml
index 96eb9b55fb9cd..67f12f98cfa84 100644
--- a/extensions/jdbc/jdbc-h2/deployment/pom.xml
+++ b/extensions/jdbc/jdbc-h2/deployment/pom.xml
@@ -21,6 +21,14 @@
io.quarkus
quarkus-arc-deployment
+
+ io.quarkus
+ quarkus-datasource-deployment-spi
+
+
+ io.quarkus
+ quarkus-devdb-h2
+
io.quarkus
quarkus-agroal-spi
diff --git a/extensions/jdbc/jdbc-h2/deployment/src/main/java/io/quarkus/jdbc/h2/deployment/JDBCH2Processor.java b/extensions/jdbc/jdbc-h2/deployment/src/main/java/io/quarkus/jdbc/h2/deployment/JDBCH2Processor.java
index 53c22c5a280ca..17d28be0f4757 100644
--- a/extensions/jdbc/jdbc-h2/deployment/src/main/java/io/quarkus/jdbc/h2/deployment/JDBCH2Processor.java
+++ b/extensions/jdbc/jdbc-h2/deployment/src/main/java/io/quarkus/jdbc/h2/deployment/JDBCH2Processor.java
@@ -4,6 +4,8 @@
import io.quarkus.arc.deployment.AdditionalBeanBuildItem;
import io.quarkus.arc.processor.BuiltinScope;
import io.quarkus.datasource.common.runtime.DatabaseKind;
+import io.quarkus.datasource.deployment.spi.DefaultDataSourceDbKindBuildItem;
+import io.quarkus.datasource.deployment.spi.DevDbConfigurationHandlerBuildItem;
import io.quarkus.deployment.Capabilities;
import io.quarkus.deployment.Capability;
import io.quarkus.deployment.Feature;
@@ -27,6 +29,11 @@ void registerDriver(BuildProducer jdbcDriver,
.produce(new JdbcDriverBuildItem(DatabaseKind.H2, "org.h2.Driver", "org.h2.jdbcx.JdbcDataSource"));
}
+ @BuildStep
+ DevDbConfigurationHandlerBuildItem devDbHandler() {
+ return DevDbConfigurationHandlerBuildItem.jdbc(DatabaseKind.H2);
+ }
+
@BuildStep
void configureAgroalConnection(BuildProducer additionalBeans,
Capabilities capabilities) {
@@ -37,4 +44,9 @@ void configureAgroalConnection(BuildProducer additional
.build());
}
}
+
+ @BuildStep
+ void registerDefaultDbType(BuildProducer dbKind) {
+ dbKind.produce(new DefaultDataSourceDbKindBuildItem(DatabaseKind.H2));
+ }
}
diff --git a/extensions/jdbc/jdbc-mariadb/deployment/pom.xml b/extensions/jdbc/jdbc-mariadb/deployment/pom.xml
index 20e38330aa127..126d9cc97684a 100644
--- a/extensions/jdbc/jdbc-mariadb/deployment/pom.xml
+++ b/extensions/jdbc/jdbc-mariadb/deployment/pom.xml
@@ -21,6 +21,10 @@
io.quarkus
quarkus-arc-deployment
+
+ io.quarkus
+ quarkus-datasource-deployment-spi
+
io.quarkus
quarkus-agroal-spi
@@ -29,6 +33,20 @@
io.quarkus
quarkus-jdbc-mariadb
+
+ io.quarkus
+ quarkus-devdb-mariadb
+
+
+ io.quarkus
+ quarkus-agroal-deployment
+ test
+
+
+ io.quarkus
+ quarkus-junit5-internal
+ test
+
@@ -45,6 +63,36 @@
+
+ org.apache.maven.plugins
+ maven-surefire-plugin
+
+ true
+
+
+
+
+
+
+ test-devdb
+
+
+ test-containers
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-surefire-plugin
+
+ false
+
+
+
+
+
+
diff --git a/extensions/jdbc/jdbc-mariadb/deployment/src/main/java/io/quarkus/jdbc/mariadb/deployment/JDBCMariaDBProcessor.java b/extensions/jdbc/jdbc-mariadb/deployment/src/main/java/io/quarkus/jdbc/mariadb/deployment/JDBCMariaDBProcessor.java
index 21353ab369ce8..29f738b7d576d 100644
--- a/extensions/jdbc/jdbc-mariadb/deployment/src/main/java/io/quarkus/jdbc/mariadb/deployment/JDBCMariaDBProcessor.java
+++ b/extensions/jdbc/jdbc-mariadb/deployment/src/main/java/io/quarkus/jdbc/mariadb/deployment/JDBCMariaDBProcessor.java
@@ -1,10 +1,11 @@
package io.quarkus.jdbc.mariadb.deployment;
-import io.quarkus.agroal.spi.DefaultDataSourceDbKindBuildItem;
import io.quarkus.agroal.spi.JdbcDriverBuildItem;
import io.quarkus.arc.deployment.AdditionalBeanBuildItem;
import io.quarkus.arc.processor.BuiltinScope;
import io.quarkus.datasource.common.runtime.DatabaseKind;
+import io.quarkus.datasource.deployment.spi.DefaultDataSourceDbKindBuildItem;
+import io.quarkus.datasource.deployment.spi.DevDbConfigurationHandlerBuildItem;
import io.quarkus.deployment.Capabilities;
import io.quarkus.deployment.Capability;
import io.quarkus.deployment.Feature;
@@ -30,6 +31,11 @@ void registerDriver(BuildProducer jdbcDriver,
"org.mariadb.jdbc.MySQLDataSource"));
}
+ @BuildStep
+ DevDbConfigurationHandlerBuildItem devDbHandler() {
+ return DevDbConfigurationHandlerBuildItem.jdbc(DatabaseKind.MARIADB);
+ }
+
@BuildStep
void configureAgroalConnection(BuildProducer additionalBeans,
Capabilities capabilities) {
@@ -49,7 +55,7 @@ void registerServiceBinding(Capabilities capabilities,
serviceProvider.produce(
new ServiceProviderBuildItem("io.quarkus.kubernetes.service.binding.runtime.ServiceBindingConverter",
MariaDBServiceBindingConverter.class.getName()));
- dbKind.produce(new DefaultDataSourceDbKindBuildItem(DatabaseKind.MARIADB));
}
+ dbKind.produce(new DefaultDataSourceDbKindBuildItem(DatabaseKind.MARIADB));
}
}
diff --git a/extensions/jdbc/jdbc-mariadb/deployment/src/test/java/io/quarkus/jdbc/mariadb/deployment/DevDBMariaDBDatasourceTestCase.java b/extensions/jdbc/jdbc-mariadb/deployment/src/test/java/io/quarkus/jdbc/mariadb/deployment/DevDBMariaDBDatasourceTestCase.java
new file mode 100644
index 0000000000000..96c4661173975
--- /dev/null
+++ b/extensions/jdbc/jdbc-mariadb/deployment/src/test/java/io/quarkus/jdbc/mariadb/deployment/DevDBMariaDBDatasourceTestCase.java
@@ -0,0 +1,52 @@
+package io.quarkus.jdbc.mariadb.deployment;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+import static org.junit.jupiter.api.Assertions.fail;
+
+import java.sql.Connection;
+import java.util.function.Supplier;
+
+import javax.inject.Inject;
+
+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.agroal.api.AgroalDataSource;
+import io.agroal.api.configuration.AgroalConnectionPoolConfiguration;
+import io.quarkus.test.QuarkusUnitTest;
+
+public class DevDBMariaDBDatasourceTestCase {
+
+ @RegisterExtension
+ static QuarkusUnitTest test = new QuarkusUnitTest()
+ .setArchiveProducer(new Supplier() {
+ @Override
+ public JavaArchive get() {
+ return ShrinkWrap.create(JavaArchive.class);
+ }
+ });
+
+ @Inject
+ AgroalDataSource dataSource;
+
+ @Test
+ public void testDatasource() throws Exception {
+ AgroalConnectionPoolConfiguration configuration = null;
+
+ try {
+ configuration = dataSource.getConfiguration().connectionPoolConfiguration();
+ } catch (NullPointerException e) {
+ // we catch the NPE here as we have a proxycd and we can't test dataSource directly
+ fail("Datasource should not be null");
+ }
+ assertTrue(configuration.connectionFactoryConfiguration().jdbcUrl().contains("jdbc:mariadb:"));
+ assertEquals("quarkus", configuration.connectionFactoryConfiguration().principal().getName());
+ assertEquals(20, configuration.maxSize());
+
+ try (Connection connection = dataSource.getConnection()) {
+ }
+ }
+}
diff --git a/extensions/jdbc/jdbc-mssql/deployment/pom.xml b/extensions/jdbc/jdbc-mssql/deployment/pom.xml
index 091ecb2a6fbb6..0d2499bbb6445 100644
--- a/extensions/jdbc/jdbc-mssql/deployment/pom.xml
+++ b/extensions/jdbc/jdbc-mssql/deployment/pom.xml
@@ -25,6 +25,10 @@
io.quarkus
quarkus-agroal-spi
+
+ io.quarkus
+ quarkus-datasource-deployment-spi
+
io.quarkus
quarkus-jdbc-mssql
diff --git a/extensions/jdbc/jdbc-mssql/deployment/src/main/java/io/quarkus/jdbc/mssql/deployment/MsSQLProcessor.java b/extensions/jdbc/jdbc-mssql/deployment/src/main/java/io/quarkus/jdbc/mssql/deployment/MsSQLProcessor.java
index 05e50351f1c05..62c37ebabacd7 100644
--- a/extensions/jdbc/jdbc-mssql/deployment/src/main/java/io/quarkus/jdbc/mssql/deployment/MsSQLProcessor.java
+++ b/extensions/jdbc/jdbc-mssql/deployment/src/main/java/io/quarkus/jdbc/mssql/deployment/MsSQLProcessor.java
@@ -1,10 +1,10 @@
package io.quarkus.jdbc.mssql.deployment;
-import io.quarkus.agroal.spi.DefaultDataSourceDbKindBuildItem;
import io.quarkus.agroal.spi.JdbcDriverBuildItem;
import io.quarkus.arc.deployment.AdditionalBeanBuildItem;
import io.quarkus.arc.processor.BuiltinScope;
import io.quarkus.datasource.common.runtime.DatabaseKind;
+import io.quarkus.datasource.deployment.spi.DefaultDataSourceDbKindBuildItem;
import io.quarkus.deployment.Capabilities;
import io.quarkus.deployment.Capability;
import io.quarkus.deployment.Feature;
@@ -64,7 +64,7 @@ void registerServiceBinding(Capabilities capabilities,
serviceProvider.produce(
new ServiceProviderBuildItem("io.quarkus.kubernetes.service.binding.runtime.ServiceBindingConverter",
MsSQLServiceBindingConverter.class.getName()));
- dbKind.produce(new DefaultDataSourceDbKindBuildItem(DatabaseKind.MSSQL));
}
+ dbKind.produce(new DefaultDataSourceDbKindBuildItem(DatabaseKind.MSSQL));
}
}
diff --git a/extensions/jdbc/jdbc-mysql/deployment/pom.xml b/extensions/jdbc/jdbc-mysql/deployment/pom.xml
index fe4f807e89723..ebfd42998b17e 100644
--- a/extensions/jdbc/jdbc-mysql/deployment/pom.xml
+++ b/extensions/jdbc/jdbc-mysql/deployment/pom.xml
@@ -25,10 +25,28 @@
io.quarkus
quarkus-agroal-spi
+
+ io.quarkus
+ quarkus-datasource-deployment-spi
+
io.quarkus
quarkus-jdbc-mysql
+
+ io.quarkus
+ quarkus-devdb-mysql
+
+
+ io.quarkus
+ quarkus-agroal-deployment
+ test
+
+
+ io.quarkus
+ quarkus-junit5-internal
+ test
+
@@ -45,6 +63,35 @@
+
+ org.apache.maven.plugins
+ maven-surefire-plugin
+
+ true
+
+
+
+
+
+ test-devdb
+
+
+ test-containers
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-surefire-plugin
+
+ false
+
+
+
+
+
+
diff --git a/extensions/jdbc/jdbc-mysql/deployment/src/main/java/io/quarkus/jdbc/mysql/deployment/JDBCMySQLProcessor.java b/extensions/jdbc/jdbc-mysql/deployment/src/main/java/io/quarkus/jdbc/mysql/deployment/JDBCMySQLProcessor.java
index d959568276e8e..6fc731d16c6a9 100644
--- a/extensions/jdbc/jdbc-mysql/deployment/src/main/java/io/quarkus/jdbc/mysql/deployment/JDBCMySQLProcessor.java
+++ b/extensions/jdbc/jdbc-mysql/deployment/src/main/java/io/quarkus/jdbc/mysql/deployment/JDBCMySQLProcessor.java
@@ -19,11 +19,12 @@
import com.mysql.cj.jdbc.result.ResultSetInternalMethods;
import com.mysql.cj.protocol.Resultset;
-import io.quarkus.agroal.spi.DefaultDataSourceDbKindBuildItem;
import io.quarkus.agroal.spi.JdbcDriverBuildItem;
import io.quarkus.arc.deployment.AdditionalBeanBuildItem;
import io.quarkus.arc.processor.BuiltinScope;
import io.quarkus.datasource.common.runtime.DatabaseKind;
+import io.quarkus.datasource.deployment.spi.DefaultDataSourceDbKindBuildItem;
+import io.quarkus.datasource.deployment.spi.DevDbConfigurationHandlerBuildItem;
import io.quarkus.deployment.Capabilities;
import io.quarkus.deployment.Capability;
import io.quarkus.deployment.Feature;
@@ -56,6 +57,11 @@ void registerDriver(BuildProducer jdbcDriver,
"com.mysql.cj.jdbc.MysqlXADataSource"));
}
+ @BuildStep
+ DevDbConfigurationHandlerBuildItem devDbHandler() {
+ return DevDbConfigurationHandlerBuildItem.jdbc(DatabaseKind.MYSQL);
+ }
+
@BuildStep
void configureAgroalConnection(BuildProducer additionalBeans,
Capabilities capabilities) {
@@ -126,7 +132,7 @@ void registerServiceBinding(Capabilities capabilities,
serviceProvider.produce(
new ServiceProviderBuildItem("io.quarkus.kubernetes.service.binding.runtime.ServiceBindingConverter",
MySQLServiceBindingConverter.class.getName()));
- dbKind.produce(new DefaultDataSourceDbKindBuildItem(DatabaseKind.MYSQL));
}
+ dbKind.produce(new DefaultDataSourceDbKindBuildItem(DatabaseKind.MYSQL));
}
}
diff --git a/extensions/jdbc/jdbc-mysql/deployment/src/test/java/io/quarkus/jdbc/mysql/deployment/DevDBMySQLDatasourceTestCase.java b/extensions/jdbc/jdbc-mysql/deployment/src/test/java/io/quarkus/jdbc/mysql/deployment/DevDBMySQLDatasourceTestCase.java
new file mode 100644
index 0000000000000..08923c2211115
--- /dev/null
+++ b/extensions/jdbc/jdbc-mysql/deployment/src/test/java/io/quarkus/jdbc/mysql/deployment/DevDBMySQLDatasourceTestCase.java
@@ -0,0 +1,52 @@
+package io.quarkus.jdbc.mysql.deployment;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+import static org.junit.jupiter.api.Assertions.fail;
+
+import java.sql.Connection;
+import java.util.function.Supplier;
+
+import javax.inject.Inject;
+
+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.agroal.api.AgroalDataSource;
+import io.agroal.api.configuration.AgroalConnectionPoolConfiguration;
+import io.quarkus.test.QuarkusUnitTest;
+
+public class DevDBMySQLDatasourceTestCase {
+
+ @RegisterExtension
+ static QuarkusUnitTest test = new QuarkusUnitTest()
+ .setArchiveProducer(new Supplier() {
+ @Override
+ public JavaArchive get() {
+ return ShrinkWrap.create(JavaArchive.class);
+ }
+ });
+
+ @Inject
+ AgroalDataSource dataSource;
+
+ @Test
+ public void testDatasource() throws Exception {
+ AgroalConnectionPoolConfiguration configuration = null;
+
+ try {
+ configuration = dataSource.getConfiguration().connectionPoolConfiguration();
+ } catch (NullPointerException e) {
+ // we catch the NPE here as we have a proxycd and we can't test dataSource directly
+ fail("Datasource should not be null");
+ }
+ assertTrue(configuration.connectionFactoryConfiguration().jdbcUrl().contains("jdbc:mysql:"));
+ assertEquals("quarkus", configuration.connectionFactoryConfiguration().principal().getName());
+ assertEquals(20, configuration.maxSize());
+
+ try (Connection connection = dataSource.getConnection()) {
+ }
+ }
+}
diff --git a/extensions/jdbc/jdbc-postgresql/deployment/pom.xml b/extensions/jdbc/jdbc-postgresql/deployment/pom.xml
index 6f4c0e9adcc11..f8bcc2b896109 100644
--- a/extensions/jdbc/jdbc-postgresql/deployment/pom.xml
+++ b/extensions/jdbc/jdbc-postgresql/deployment/pom.xml
@@ -13,6 +13,10 @@
Quarkus - JDBC - PostgreSQL - Deployment
+
+ org.testcontainers
+ postgresql
+
io.quarkus
quarkus-core-deployment
@@ -25,10 +29,28 @@
io.quarkus
quarkus-agroal-spi
+
+ io.quarkus
+ quarkus-devdb-postgresql
+
+
+ io.quarkus
+ quarkus-datasource-deployment-spi
+
io.quarkus
quarkus-jdbc-postgresql
+
+ io.quarkus
+ quarkus-agroal-deployment
+ test
+
+
+ io.quarkus
+ quarkus-junit5-internal
+ test
+
@@ -45,6 +67,35 @@
+
+ org.apache.maven.plugins
+ maven-surefire-plugin
+
+ true
+
+
+
+
+
+ test-devdb
+
+
+ test-containers
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-surefire-plugin
+
+ false
+
+
+
+
+
+
diff --git a/extensions/jdbc/jdbc-postgresql/deployment/src/main/java/io/quarkus/jdbc/postgresql/deployment/JDBCPostgreSQLProcessor.java b/extensions/jdbc/jdbc-postgresql/deployment/src/main/java/io/quarkus/jdbc/postgresql/deployment/JDBCPostgreSQLProcessor.java
index 31b7f0dcc9e3c..9441d22a1690a 100644
--- a/extensions/jdbc/jdbc-postgresql/deployment/src/main/java/io/quarkus/jdbc/postgresql/deployment/JDBCPostgreSQLProcessor.java
+++ b/extensions/jdbc/jdbc-postgresql/deployment/src/main/java/io/quarkus/jdbc/postgresql/deployment/JDBCPostgreSQLProcessor.java
@@ -1,10 +1,11 @@
package io.quarkus.jdbc.postgresql.deployment;
-import io.quarkus.agroal.spi.DefaultDataSourceDbKindBuildItem;
import io.quarkus.agroal.spi.JdbcDriverBuildItem;
import io.quarkus.arc.deployment.AdditionalBeanBuildItem;
import io.quarkus.arc.processor.BuiltinScope;
import io.quarkus.datasource.common.runtime.DatabaseKind;
+import io.quarkus.datasource.deployment.spi.DefaultDataSourceDbKindBuildItem;
+import io.quarkus.datasource.deployment.spi.DevDbConfigurationHandlerBuildItem;
import io.quarkus.deployment.Capabilities;
import io.quarkus.deployment.Capability;
import io.quarkus.deployment.Feature;
@@ -30,6 +31,11 @@ void registerDriver(BuildProducer jdbcDriver,
"org.postgresql.xa.PGXADataSource"));
}
+ @BuildStep
+ DevDbConfigurationHandlerBuildItem devDbHandler() {
+ return DevDbConfigurationHandlerBuildItem.jdbc(DatabaseKind.POSTGRESQL);
+ }
+
@BuildStep
void configureAgroalConnection(BuildProducer additionalBeans,
Capabilities capabilities) {
@@ -50,7 +56,7 @@ void registerServiceBinding(Capabilities capabilities,
serviceProvider.produce(
new ServiceProviderBuildItem("io.quarkus.kubernetes.service.binding.runtime.ServiceBindingConverter",
PostgreSqlServiceBindingConverter.class.getName()));
- dbKind.produce(new DefaultDataSourceDbKindBuildItem(DatabaseKind.POSTGRESQL));
}
+ dbKind.produce(new DefaultDataSourceDbKindBuildItem(DatabaseKind.POSTGRESQL));
}
}
diff --git a/extensions/jdbc/jdbc-postgresql/deployment/src/test/java/io/quarkus/jdbc/postgresql/deployment/DevDBPostgresqlDatasourceTestCase.java b/extensions/jdbc/jdbc-postgresql/deployment/src/test/java/io/quarkus/jdbc/postgresql/deployment/DevDBPostgresqlDatasourceTestCase.java
new file mode 100644
index 0000000000000..b881423c39dc8
--- /dev/null
+++ b/extensions/jdbc/jdbc-postgresql/deployment/src/test/java/io/quarkus/jdbc/postgresql/deployment/DevDBPostgresqlDatasourceTestCase.java
@@ -0,0 +1,52 @@
+package io.quarkus.jdbc.postgresql.deployment;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+import static org.junit.jupiter.api.Assertions.fail;
+
+import java.sql.Connection;
+import java.util.function.Supplier;
+
+import javax.inject.Inject;
+
+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.agroal.api.AgroalDataSource;
+import io.agroal.api.configuration.AgroalConnectionPoolConfiguration;
+import io.quarkus.test.QuarkusUnitTest;
+
+public class DevDBPostgresqlDatasourceTestCase {
+
+ @RegisterExtension
+ static QuarkusUnitTest test = new QuarkusUnitTest()
+ .setArchiveProducer(new Supplier() {
+ @Override
+ public JavaArchive get() {
+ return ShrinkWrap.create(JavaArchive.class);
+ }
+ });
+
+ @Inject
+ AgroalDataSource dataSource;
+
+ @Test
+ public void testDatasource() throws Exception {
+ AgroalConnectionPoolConfiguration configuration = null;
+
+ try {
+ configuration = dataSource.getConfiguration().connectionPoolConfiguration();
+ } catch (NullPointerException e) {
+ // we catch the NPE here as we have a proxycd and we can't test dataSource directly
+ fail("Datasource should not be null");
+ }
+ assertTrue(configuration.connectionFactoryConfiguration().jdbcUrl().contains("jdbc:postgresql:"));
+ assertEquals("quarkus", configuration.connectionFactoryConfiguration().principal().getName());
+ assertEquals(20, configuration.maxSize());
+
+ try (Connection connection = dataSource.getConnection()) {
+ }
+ }
+}
diff --git a/extensions/pom.xml b/extensions/pom.xml
index e5bb63b91e578..1ac5249c865bf 100644
--- a/extensions/pom.xml
+++ b/extensions/pom.xml
@@ -111,6 +111,7 @@
artemis-core
artemis-jms
avro
+ devdb
spring-di
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 b240cf22e744a..3d882b0cbaf7a 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
@@ -1,5 +1,8 @@
package io.quarkus.reactive.db2.client.deployment;
+import java.util.List;
+import java.util.Optional;
+
import javax.enterprise.context.ApplicationScoped;
import io.quarkus.arc.deployment.SyntheticBeanBuildItem;
@@ -7,6 +10,7 @@
import io.quarkus.arc.processor.DotNames;
import io.quarkus.datasource.common.runtime.DataSourceUtil;
import io.quarkus.datasource.common.runtime.DatabaseKind;
+import io.quarkus.datasource.deployment.spi.DefaultDataSourceDbKindBuildItem;
import io.quarkus.datasource.runtime.DataSourceBuildTimeConfig;
import io.quarkus.datasource.runtime.DataSourcesBuildTimeConfig;
import io.quarkus.datasource.runtime.DataSourcesRuntimeConfig;
@@ -19,6 +23,7 @@
import io.quarkus.deployment.builditem.FeatureBuildItem;
import io.quarkus.deployment.builditem.ServiceStartBuildItem;
import io.quarkus.deployment.builditem.ShutdownContextBuildItem;
+import io.quarkus.deployment.pkg.builditem.CurateOutcomeBuildItem;
import io.quarkus.reactive.datasource.ReactiveDataSource;
import io.quarkus.reactive.datasource.deployment.VertxPoolBuildItem;
import io.quarkus.reactive.datasource.runtime.DataSourceReactiveBuildTimeConfig;
@@ -47,19 +52,22 @@ ServiceStartBuildItem build(BuildProducer feature,
DataSourcesBuildTimeConfig dataSourcesBuildTimeConfig, DataSourcesRuntimeConfig dataSourcesRuntimeConfig,
DataSourcesReactiveBuildTimeConfig dataSourcesReactiveBuildTimeConfig,
DataSourcesReactiveRuntimeConfig dataSourcesReactiveRuntimeConfig,
- DataSourcesReactiveDB2Config dataSourcesReactiveDB2Config) {
+ DataSourcesReactiveDB2Config dataSourcesReactiveDB2Config,
+ List defaultDataSourceDbKindBuildItems,
+ CurateOutcomeBuildItem curateOutcomeBuildItem) {
feature.produce(new FeatureBuildItem(Feature.REACTIVE_DB2_CLIENT));
createPoolIfDefined(recorder, vertx, shutdown, db2Pool, vertxPool, syntheticBeans,
DataSourceUtil.DEFAULT_DATASOURCE_NAME, dataSourcesBuildTimeConfig,
dataSourcesRuntimeConfig, dataSourcesReactiveBuildTimeConfig, dataSourcesReactiveRuntimeConfig,
- dataSourcesReactiveDB2Config);
+ dataSourcesReactiveDB2Config, defaultDataSourceDbKindBuildItems, curateOutcomeBuildItem);
for (String dataSourceName : dataSourcesBuildTimeConfig.namedDataSources.keySet()) {
createPoolIfDefined(recorder, vertx, shutdown, db2Pool, vertxPool, syntheticBeans, dataSourceName,
dataSourcesBuildTimeConfig, dataSourcesRuntimeConfig, dataSourcesReactiveBuildTimeConfig,
- dataSourcesReactiveRuntimeConfig, dataSourcesReactiveDB2Config);
+ dataSourcesReactiveRuntimeConfig, dataSourcesReactiveDB2Config, defaultDataSourceDbKindBuildItems,
+ curateOutcomeBuildItem);
}
// Enable SSL support by default
@@ -76,8 +84,11 @@ ServiceStartBuildItem build(BuildProducer feature,
void addHealthCheck(
BuildProducer healthChecks,
DataSourcesBuildTimeConfig dataSourcesBuildTimeConfig,
- DataSourcesReactiveBuildTimeConfig dataSourcesReactiveBuildTimeConfig) {
- if (!hasPools(dataSourcesBuildTimeConfig, dataSourcesReactiveBuildTimeConfig)) {
+ DataSourcesReactiveBuildTimeConfig dataSourcesReactiveBuildTimeConfig,
+ List defaultDataSourceDbKindBuildItems,
+ CurateOutcomeBuildItem curateOutcomeBuildItem) {
+ if (!hasPools(dataSourcesBuildTimeConfig, dataSourcesReactiveBuildTimeConfig, defaultDataSourceDbKindBuildItems,
+ curateOutcomeBuildItem)) {
return;
}
@@ -97,9 +108,12 @@ private void createPoolIfDefined(DB2PoolRecorder recorder,
DataSourcesRuntimeConfig dataSourcesRuntimeConfig,
DataSourcesReactiveBuildTimeConfig dataSourcesReactiveBuildTimeConfig,
DataSourcesReactiveRuntimeConfig dataSourcesReactiveRuntimeConfig,
- DataSourcesReactiveDB2Config dataSourcesReactiveDB2Config) {
+ DataSourcesReactiveDB2Config dataSourcesReactiveDB2Config,
+ List defaultDataSourceDbKindBuildItems,
+ CurateOutcomeBuildItem curateOutcomeBuildItem) {
- if (!isReactiveDB2PoolDefined(dataSourcesBuildTimeConfig, dataSourcesReactiveBuildTimeConfig, dataSourceName)) {
+ if (!isReactiveDB2PoolDefined(dataSourcesBuildTimeConfig, dataSourcesReactiveBuildTimeConfig, dataSourceName,
+ defaultDataSourceDbKindBuildItems, curateOutcomeBuildItem)) {
return;
}
@@ -138,17 +152,21 @@ private void createPoolIfDefined(DB2PoolRecorder recorder,
}
private static boolean isReactiveDB2PoolDefined(DataSourcesBuildTimeConfig dataSourcesBuildTimeConfig,
- DataSourcesReactiveBuildTimeConfig dataSourcesReactiveBuildTimeConfig, String dataSourceName) {
+ DataSourcesReactiveBuildTimeConfig dataSourcesReactiveBuildTimeConfig, String dataSourceName,
+ List defaultDataSourceDbKindBuildItems,
+ CurateOutcomeBuildItem curateOutcomeBuildItem) {
DataSourceBuildTimeConfig dataSourceBuildTimeConfig = dataSourcesBuildTimeConfig
.getDataSourceRuntimeConfig(dataSourceName);
DataSourceReactiveBuildTimeConfig dataSourceReactiveBuildTimeConfig = dataSourcesReactiveBuildTimeConfig
.getDataSourceReactiveBuildTimeConfig(dataSourceName);
- if (!dataSourceBuildTimeConfig.dbKind.isPresent()) {
+ Optional dbKind = DefaultDataSourceDbKindBuildItem.resolve(dataSourceBuildTimeConfig.dbKind,
+ defaultDataSourceDbKindBuildItems, curateOutcomeBuildItem);
+ if (!dbKind.isPresent()) {
return false;
}
- if (!DatabaseKind.isDB2(dataSourceBuildTimeConfig.dbKind.get())
+ if (!DatabaseKind.isDB2(dbKind.get())
|| !dataSourceReactiveBuildTimeConfig.enabled) {
return false;
}
@@ -157,15 +175,17 @@ private static boolean isReactiveDB2PoolDefined(DataSourcesBuildTimeConfig dataS
}
private boolean hasPools(DataSourcesBuildTimeConfig dataSourcesBuildTimeConfig,
- DataSourcesReactiveBuildTimeConfig dataSourcesReactiveBuildTimeConfig) {
+ DataSourcesReactiveBuildTimeConfig dataSourcesReactiveBuildTimeConfig,
+ List defaultDataSourceDbKindBuildItems,
+ CurateOutcomeBuildItem curateOutcomeBuildItem) {
if (isReactiveDB2PoolDefined(dataSourcesBuildTimeConfig, dataSourcesReactiveBuildTimeConfig,
- DataSourceUtil.DEFAULT_DATASOURCE_NAME)) {
+ DataSourceUtil.DEFAULT_DATASOURCE_NAME, defaultDataSourceDbKindBuildItems, curateOutcomeBuildItem)) {
return true;
}
for (String dataSourceName : dataSourcesBuildTimeConfig.namedDataSources.keySet()) {
if (isReactiveDB2PoolDefined(dataSourcesBuildTimeConfig, dataSourcesReactiveBuildTimeConfig,
- dataSourceName)) {
+ dataSourceName, defaultDataSourceDbKindBuildItems, curateOutcomeBuildItem)) {
return true;
}
}
diff --git a/extensions/reactive-mysql-client/deployment/pom.xml b/extensions/reactive-mysql-client/deployment/pom.xml
index 77bc080ee36db..f53f735176cf9 100644
--- a/extensions/reactive-mysql-client/deployment/pom.xml
+++ b/extensions/reactive-mysql-client/deployment/pom.xml
@@ -56,6 +56,10 @@
io.quarkus
quarkus-smallrye-health-spi
+
+ io.quarkus
+ quarkus-devdb-mysql
+
io.quarkus
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 a149d296ac395..d1a34a1c2c541 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
@@ -1,5 +1,8 @@
package io.quarkus.reactive.mysql.client.deployment;
+import java.util.List;
+import java.util.Optional;
+
import javax.enterprise.context.ApplicationScoped;
import io.quarkus.arc.deployment.SyntheticBeanBuildItem;
@@ -7,6 +10,8 @@
import io.quarkus.arc.processor.DotNames;
import io.quarkus.datasource.common.runtime.DataSourceUtil;
import io.quarkus.datasource.common.runtime.DatabaseKind;
+import io.quarkus.datasource.deployment.spi.DefaultDataSourceDbKindBuildItem;
+import io.quarkus.datasource.deployment.spi.DevDbConfigurationHandlerBuildItem;
import io.quarkus.datasource.runtime.DataSourceBuildTimeConfig;
import io.quarkus.datasource.runtime.DataSourcesBuildTimeConfig;
import io.quarkus.datasource.runtime.DataSourcesRuntimeConfig;
@@ -19,6 +24,7 @@
import io.quarkus.deployment.builditem.FeatureBuildItem;
import io.quarkus.deployment.builditem.ServiceStartBuildItem;
import io.quarkus.deployment.builditem.ShutdownContextBuildItem;
+import io.quarkus.deployment.pkg.builditem.CurateOutcomeBuildItem;
import io.quarkus.reactive.datasource.ReactiveDataSource;
import io.quarkus.reactive.datasource.deployment.VertxPoolBuildItem;
import io.quarkus.reactive.datasource.runtime.DataSourceReactiveBuildTimeConfig;
@@ -47,19 +53,22 @@ ServiceStartBuildItem build(BuildProducer feature,
DataSourcesBuildTimeConfig dataSourcesBuildTimeConfig, DataSourcesRuntimeConfig dataSourcesRuntimeConfig,
DataSourcesReactiveBuildTimeConfig dataSourcesReactiveBuildTimeConfig,
DataSourcesReactiveRuntimeConfig dataSourcesReactiveRuntimeConfig,
- DataSourcesReactiveMySQLConfig dataSourcesReactiveMySQLConfig) {
+ DataSourcesReactiveMySQLConfig dataSourcesReactiveMySQLConfig,
+ List defaultDataSourceDbKindBuildItems,
+ CurateOutcomeBuildItem curateOutcomeBuildItem) {
feature.produce(new FeatureBuildItem(Feature.REACTIVE_MYSQL_CLIENT));
createPoolIfDefined(recorder, vertx, shutdown, mySQLPool, vertxPool, syntheticBeans,
DataSourceUtil.DEFAULT_DATASOURCE_NAME, dataSourcesBuildTimeConfig,
dataSourcesRuntimeConfig, dataSourcesReactiveBuildTimeConfig, dataSourcesReactiveRuntimeConfig,
- dataSourcesReactiveMySQLConfig);
+ dataSourcesReactiveMySQLConfig, defaultDataSourceDbKindBuildItems, curateOutcomeBuildItem);
for (String dataSourceName : dataSourcesBuildTimeConfig.namedDataSources.keySet()) {
createPoolIfDefined(recorder, vertx, shutdown, mySQLPool, vertxPool, syntheticBeans, dataSourceName,
dataSourcesBuildTimeConfig, dataSourcesRuntimeConfig, dataSourcesReactiveBuildTimeConfig,
- dataSourcesReactiveRuntimeConfig, dataSourcesReactiveMySQLConfig);
+ dataSourcesReactiveRuntimeConfig, dataSourcesReactiveMySQLConfig, defaultDataSourceDbKindBuildItems,
+ curateOutcomeBuildItem);
}
// Enable SSL support by default
@@ -68,6 +77,11 @@ ServiceStartBuildItem build(BuildProducer feature,
return new ServiceStartBuildItem("reactive-mysql-client");
}
+ @BuildStep
+ DevDbConfigurationHandlerBuildItem devDbHandler() {
+ return DevDbConfigurationHandlerBuildItem.reactive(DatabaseKind.MYSQL);
+ }
+
/**
* The health check needs to be produced in a separate method to avoid a circular dependency (the Vert.x instance creation
* consumes the AdditionalBeanBuildItems).
@@ -76,8 +90,11 @@ ServiceStartBuildItem build(BuildProducer feature,
void addHealthCheck(
BuildProducer healthChecks,
DataSourcesBuildTimeConfig dataSourcesBuildTimeConfig,
- DataSourcesReactiveBuildTimeConfig dataSourcesReactiveBuildTimeConfig) {
- if (!hasPools(dataSourcesBuildTimeConfig, dataSourcesReactiveBuildTimeConfig)) {
+ DataSourcesReactiveBuildTimeConfig dataSourcesReactiveBuildTimeConfig,
+ List defaultDataSourceDbKindBuildItems,
+ CurateOutcomeBuildItem curateOutcomeBuildItem) {
+ if (!hasPools(dataSourcesBuildTimeConfig, dataSourcesReactiveBuildTimeConfig, defaultDataSourceDbKindBuildItems,
+ curateOutcomeBuildItem)) {
return;
}
@@ -97,9 +114,12 @@ private void createPoolIfDefined(MySQLPoolRecorder recorder,
DataSourcesRuntimeConfig dataSourcesRuntimeConfig,
DataSourcesReactiveBuildTimeConfig dataSourcesReactiveBuildTimeConfig,
DataSourcesReactiveRuntimeConfig dataSourcesReactiveRuntimeConfig,
- DataSourcesReactiveMySQLConfig dataSourcesReactiveMySQLConfig) {
+ DataSourcesReactiveMySQLConfig dataSourcesReactiveMySQLConfig,
+ List defaultDataSourceDbKindBuildItems,
+ CurateOutcomeBuildItem curateOutcomeBuildItem) {
- if (!isReactiveMySQLPoolDefined(dataSourcesBuildTimeConfig, dataSourcesReactiveBuildTimeConfig, dataSourceName)) {
+ if (!isReactiveMySQLPoolDefined(dataSourcesBuildTimeConfig, dataSourcesReactiveBuildTimeConfig, dataSourceName,
+ defaultDataSourceDbKindBuildItems, curateOutcomeBuildItem)) {
return;
}
@@ -138,18 +158,22 @@ private void createPoolIfDefined(MySQLPoolRecorder recorder,
}
private static boolean isReactiveMySQLPoolDefined(DataSourcesBuildTimeConfig dataSourcesBuildTimeConfig,
- DataSourcesReactiveBuildTimeConfig dataSourcesReactiveBuildTimeConfig, String dataSourceName) {
+ DataSourcesReactiveBuildTimeConfig dataSourcesReactiveBuildTimeConfig, String dataSourceName,
+ List defaultDataSourceDbKindBuildItems,
+ CurateOutcomeBuildItem curateOutcomeBuildItem) {
DataSourceBuildTimeConfig dataSourceBuildTimeConfig = dataSourcesBuildTimeConfig
.getDataSourceRuntimeConfig(dataSourceName);
DataSourceReactiveBuildTimeConfig dataSourceReactiveBuildTimeConfig = dataSourcesReactiveBuildTimeConfig
.getDataSourceReactiveBuildTimeConfig(dataSourceName);
- if (!dataSourceBuildTimeConfig.dbKind.isPresent()) {
+ Optional dbKind = DefaultDataSourceDbKindBuildItem.resolve(dataSourceBuildTimeConfig.dbKind,
+ defaultDataSourceDbKindBuildItems, curateOutcomeBuildItem);
+ if (!dbKind.isPresent()) {
return false;
}
- if ((!DatabaseKind.isMySQL(dataSourceBuildTimeConfig.dbKind.get())
- && !DatabaseKind.isMariaDB(dataSourceBuildTimeConfig.dbKind.get()))
+ if ((!DatabaseKind.isMySQL(dbKind.get())
+ && !DatabaseKind.isMariaDB(dbKind.get()))
|| !dataSourceReactiveBuildTimeConfig.enabled) {
return false;
}
@@ -158,15 +182,17 @@ private static boolean isReactiveMySQLPoolDefined(DataSourcesBuildTimeConfig dat
}
private boolean hasPools(DataSourcesBuildTimeConfig dataSourcesBuildTimeConfig,
- DataSourcesReactiveBuildTimeConfig dataSourcesReactiveBuildTimeConfig) {
+ DataSourcesReactiveBuildTimeConfig dataSourcesReactiveBuildTimeConfig,
+ List defaultDataSourceDbKindBuildItems,
+ CurateOutcomeBuildItem curateOutcomeBuildItem) {
if (isReactiveMySQLPoolDefined(dataSourcesBuildTimeConfig, dataSourcesReactiveBuildTimeConfig,
- DataSourceUtil.DEFAULT_DATASOURCE_NAME)) {
+ DataSourceUtil.DEFAULT_DATASOURCE_NAME, defaultDataSourceDbKindBuildItems, curateOutcomeBuildItem)) {
return true;
}
for (String dataSourceName : dataSourcesBuildTimeConfig.namedDataSources.keySet()) {
if (isReactiveMySQLPoolDefined(dataSourcesBuildTimeConfig, dataSourcesReactiveBuildTimeConfig,
- dataSourceName)) {
+ dataSourceName, defaultDataSourceDbKindBuildItems, curateOutcomeBuildItem)) {
return true;
}
}
diff --git a/extensions/reactive-pg-client/deployment/pom.xml b/extensions/reactive-pg-client/deployment/pom.xml
index f6494c8b7eb1a..e7ee45b513376 100644
--- a/extensions/reactive-pg-client/deployment/pom.xml
+++ b/extensions/reactive-pg-client/deployment/pom.xml
@@ -24,6 +24,10 @@
io.quarkus
quarkus-reactive-datasource-deployment
+
+ io.quarkus
+ quarkus-devdb-postgresql
+
io.quarkus
quarkus-vertx-deployment
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 976cd9ce12a11..7df814de5a9ca 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
@@ -1,5 +1,8 @@
package io.quarkus.reactive.pg.client.deployment;
+import java.util.List;
+import java.util.Optional;
+
import javax.enterprise.context.ApplicationScoped;
import io.quarkus.arc.deployment.SyntheticBeanBuildItem;
@@ -7,6 +10,8 @@
import io.quarkus.arc.processor.DotNames;
import io.quarkus.datasource.common.runtime.DataSourceUtil;
import io.quarkus.datasource.common.runtime.DatabaseKind;
+import io.quarkus.datasource.deployment.spi.DefaultDataSourceDbKindBuildItem;
+import io.quarkus.datasource.deployment.spi.DevDbConfigurationHandlerBuildItem;
import io.quarkus.datasource.runtime.DataSourceBuildTimeConfig;
import io.quarkus.datasource.runtime.DataSourcesBuildTimeConfig;
import io.quarkus.datasource.runtime.DataSourcesRuntimeConfig;
@@ -20,6 +25,7 @@
import io.quarkus.deployment.builditem.ServiceStartBuildItem;
import io.quarkus.deployment.builditem.ShutdownContextBuildItem;
import io.quarkus.deployment.builditem.nativeimage.NativeImageConfigBuildItem;
+import io.quarkus.deployment.pkg.builditem.CurateOutcomeBuildItem;
import io.quarkus.reactive.datasource.ReactiveDataSource;
import io.quarkus.reactive.datasource.deployment.VertxPoolBuildItem;
import io.quarkus.reactive.datasource.runtime.DataSourceReactiveBuildTimeConfig;
@@ -41,6 +47,11 @@ NativeImageConfigBuildItem config() {
.build();
}
+ @BuildStep
+ DevDbConfigurationHandlerBuildItem devDbHandler() {
+ return DevDbConfigurationHandlerBuildItem.reactive(DatabaseKind.POSTGRESQL);
+ }
+
@BuildStep
@Record(ExecutionTime.RUNTIME_INIT)
ServiceStartBuildItem build(BuildProducer feature,
@@ -54,19 +65,22 @@ ServiceStartBuildItem build(BuildProducer feature,
DataSourcesBuildTimeConfig dataSourcesBuildTimeConfig, DataSourcesRuntimeConfig dataSourcesRuntimeConfig,
DataSourcesReactiveBuildTimeConfig dataSourcesReactiveBuildTimeConfig,
DataSourcesReactiveRuntimeConfig dataSourcesReactiveRuntimeConfig,
- DataSourcesReactivePostgreSQLConfig dataSourcesReactivePostgreSQLConfig) {
+ DataSourcesReactivePostgreSQLConfig dataSourcesReactivePostgreSQLConfig,
+ List defaultDataSourceDbKindBuildItems,
+ CurateOutcomeBuildItem curateOutcomeBuildItem) {
feature.produce(new FeatureBuildItem(Feature.REACTIVE_PG_CLIENT));
createPoolIfDefined(recorder, vertx, shutdown, pgPool, vertxPool, syntheticBeans,
DataSourceUtil.DEFAULT_DATASOURCE_NAME, dataSourcesBuildTimeConfig,
dataSourcesRuntimeConfig, dataSourcesReactiveBuildTimeConfig, dataSourcesReactiveRuntimeConfig,
- dataSourcesReactivePostgreSQLConfig);
+ dataSourcesReactivePostgreSQLConfig, defaultDataSourceDbKindBuildItems, curateOutcomeBuildItem);
for (String dataSourceName : dataSourcesBuildTimeConfig.namedDataSources.keySet()) {
createPoolIfDefined(recorder, vertx, shutdown, pgPool, vertxPool, syntheticBeans, dataSourceName,
dataSourcesBuildTimeConfig, dataSourcesRuntimeConfig, dataSourcesReactiveBuildTimeConfig,
- dataSourcesReactiveRuntimeConfig, dataSourcesReactivePostgreSQLConfig);
+ dataSourcesReactiveRuntimeConfig, dataSourcesReactivePostgreSQLConfig, defaultDataSourceDbKindBuildItems,
+ curateOutcomeBuildItem);
}
// Enable SSL support by default
@@ -83,8 +97,11 @@ ServiceStartBuildItem build(BuildProducer feature,
void addHealthCheck(
BuildProducer healthChecks,
DataSourcesBuildTimeConfig dataSourcesBuildTimeConfig,
- DataSourcesReactiveBuildTimeConfig dataSourcesReactiveBuildTimeConfig) {
- if (!hasPools(dataSourcesBuildTimeConfig, dataSourcesReactiveBuildTimeConfig)) {
+ DataSourcesReactiveBuildTimeConfig dataSourcesReactiveBuildTimeConfig,
+ List defaultDataSourceDbKindBuildItems,
+ CurateOutcomeBuildItem curateOutcomeBuildItem) {
+ if (!hasPools(dataSourcesBuildTimeConfig, dataSourcesReactiveBuildTimeConfig, defaultDataSourceDbKindBuildItems,
+ curateOutcomeBuildItem)) {
return;
}
@@ -93,6 +110,11 @@ void addHealthCheck(
dataSourcesBuildTimeConfig.healthEnabled));
}
+ @BuildStep
+ void registerServiceBinding(BuildProducer dbKind) {
+ dbKind.produce(new DefaultDataSourceDbKindBuildItem(DatabaseKind.POSTGRESQL));
+ }
+
private void createPoolIfDefined(PgPoolRecorder recorder,
VertxBuildItem vertx,
ShutdownContextBuildItem shutdown,
@@ -104,9 +126,12 @@ private void createPoolIfDefined(PgPoolRecorder recorder,
DataSourcesRuntimeConfig dataSourcesRuntimeConfig,
DataSourcesReactiveBuildTimeConfig dataSourcesReactiveBuildTimeConfig,
DataSourcesReactiveRuntimeConfig dataSourcesReactiveRuntimeConfig,
- DataSourcesReactivePostgreSQLConfig dataSourcesReactivePostgreSQLConfig) {
+ DataSourcesReactivePostgreSQLConfig dataSourcesReactivePostgreSQLConfig,
+ List defaultDataSourceDbKindBuildItems,
+ CurateOutcomeBuildItem curateOutcomeBuildItem) {
- if (!isReactivePostgreSQLPoolDefined(dataSourcesBuildTimeConfig, dataSourcesReactiveBuildTimeConfig, dataSourceName)) {
+ if (!isReactivePostgreSQLPoolDefined(dataSourcesBuildTimeConfig, dataSourcesReactiveBuildTimeConfig, dataSourceName,
+ defaultDataSourceDbKindBuildItems, curateOutcomeBuildItem)) {
return;
}
@@ -145,17 +170,22 @@ private void createPoolIfDefined(PgPoolRecorder recorder,
}
private static boolean isReactivePostgreSQLPoolDefined(DataSourcesBuildTimeConfig dataSourcesBuildTimeConfig,
- DataSourcesReactiveBuildTimeConfig dataSourcesReactiveBuildTimeConfig, String dataSourceName) {
+ DataSourcesReactiveBuildTimeConfig dataSourcesReactiveBuildTimeConfig, String dataSourceName,
+ List defaultDataSourceDbKindBuildItems,
+ CurateOutcomeBuildItem curateOutcomeBuildItem) {
DataSourceBuildTimeConfig dataSourceBuildTimeConfig = dataSourcesBuildTimeConfig
.getDataSourceRuntimeConfig(dataSourceName);
DataSourceReactiveBuildTimeConfig dataSourceReactiveBuildTimeConfig = dataSourcesReactiveBuildTimeConfig
.getDataSourceReactiveBuildTimeConfig(dataSourceName);
- if (!dataSourceBuildTimeConfig.dbKind.isPresent()) {
+ Optional dbKind = DefaultDataSourceDbKindBuildItem.resolve(dataSourceBuildTimeConfig.dbKind,
+ defaultDataSourceDbKindBuildItems, curateOutcomeBuildItem);
+
+ if (!dbKind.isPresent()) {
return false;
}
- if (!DatabaseKind.isPostgreSQL(dataSourceBuildTimeConfig.dbKind.get())
+ if (!DatabaseKind.isPostgreSQL(dbKind.get())
|| !dataSourceReactiveBuildTimeConfig.enabled) {
return false;
}
@@ -164,15 +194,17 @@ private static boolean isReactivePostgreSQLPoolDefined(DataSourcesBuildTimeConfi
}
private boolean hasPools(DataSourcesBuildTimeConfig dataSourcesBuildTimeConfig,
- DataSourcesReactiveBuildTimeConfig dataSourcesReactiveBuildTimeConfig) {
+ DataSourcesReactiveBuildTimeConfig dataSourcesReactiveBuildTimeConfig,
+ List defaultDataSourceDbKindBuildItems,
+ CurateOutcomeBuildItem curateOutcomeBuildItem) {
if (isReactivePostgreSQLPoolDefined(dataSourcesBuildTimeConfig, dataSourcesReactiveBuildTimeConfig,
- DataSourceUtil.DEFAULT_DATASOURCE_NAME)) {
+ DataSourceUtil.DEFAULT_DATASOURCE_NAME, defaultDataSourceDbKindBuildItems, curateOutcomeBuildItem)) {
return true;
}
for (String dataSourceName : dataSourcesBuildTimeConfig.namedDataSources.keySet()) {
if (isReactivePostgreSQLPoolDefined(dataSourcesBuildTimeConfig, dataSourcesReactiveBuildTimeConfig,
- dataSourceName)) {
+ dataSourceName, defaultDataSourceDbKindBuildItems, curateOutcomeBuildItem)) {
return true;
}
}
diff --git a/independent-projects/bootstrap/core/src/main/java/io/quarkus/bootstrap/app/AugmentAction.java b/independent-projects/bootstrap/core/src/main/java/io/quarkus/bootstrap/app/AugmentAction.java
index c280e2b5f5ec2..058559227bcfa 100644
--- a/independent-projects/bootstrap/core/src/main/java/io/quarkus/bootstrap/app/AugmentAction.java
+++ b/independent-projects/bootstrap/core/src/main/java/io/quarkus/bootstrap/app/AugmentAction.java
@@ -3,6 +3,9 @@
import java.util.Set;
public interface AugmentAction {
+
+ void performCustomBuild(String resultConsumer, Object context, String... finalOutputs);
+
AugmentResult createProductionApplication();
StartupAction createInitialRuntimeApplication();
diff --git a/integration-tests/jpa-h2/src/main/resources/application.properties b/integration-tests/jpa-h2/src/main/resources/application.properties
index abb95fef00079..bf4226d2762fd 100644
--- a/integration-tests/jpa-h2/src/main/resources/application.properties
+++ b/integration-tests/jpa-h2/src/main/resources/application.properties
@@ -1,3 +1 @@
-quarkus.datasource.db-kind=h2
-quarkus.datasource.jdbc.url=jdbc:h2:tcp://localhost/mem:test
quarkus.datasource.jdbc.max-size=8
diff --git a/integration-tests/jpa-h2/src/test/java/io/quarkus/it/jpa/h2/TestResources.java b/integration-tests/jpa-h2/src/test/java/io/quarkus/it/jpa/h2/TestResources.java
deleted file mode 100644
index cab3615f001d3..0000000000000
--- a/integration-tests/jpa-h2/src/test/java/io/quarkus/it/jpa/h2/TestResources.java
+++ /dev/null
@@ -1,8 +0,0 @@
-package io.quarkus.it.jpa.h2;
-
-import io.quarkus.test.common.QuarkusTestResource;
-import io.quarkus.test.h2.H2DatabaseTestResource;
-
-@QuarkusTestResource(H2DatabaseTestResource.class)
-public class TestResources {
-}
diff --git a/integration-tests/jpa-postgresql/src/main/resources/application.properties b/integration-tests/jpa-postgresql/src/main/resources/application.properties
index eb32fc3b47311..59bf46a494b07 100644
--- a/integration-tests/jpa-postgresql/src/main/resources/application.properties
+++ b/integration-tests/jpa-postgresql/src/main/resources/application.properties
@@ -1,4 +1,3 @@
-quarkus.datasource.db-kind=postgresql
quarkus.datasource.username=hibernate_orm_test
quarkus.datasource.password=hibernate_orm_test
quarkus.datasource.jdbc.url=${postgres.url}
diff --git a/test-framework/junit5/pom.xml b/test-framework/junit5/pom.xml
index 6c1b4ae52a777..a0c32c731ba93 100644
--- a/test-framework/junit5/pom.xml
+++ b/test-framework/junit5/pom.xml
@@ -44,6 +44,10 @@
io.quarkus
quarkus-core
+
+ io.quarkus
+ quarkus-datasource-deployment-spi
+
com.thoughtworks.xstream
xstream
diff --git a/test-framework/junit5/src/main/java/io/quarkus/test/junit/NativeDevDbHandler.java b/test-framework/junit5/src/main/java/io/quarkus/test/junit/NativeDevDbHandler.java
new file mode 100644
index 0000000000000..bcc933b3a7555
--- /dev/null
+++ b/test-framework/junit5/src/main/java/io/quarkus/test/junit/NativeDevDbHandler.java
@@ -0,0 +1,27 @@
+package io.quarkus.test.junit;
+
+import java.util.Map;
+import java.util.function.BiConsumer;
+
+import io.quarkus.builder.BuildResult;
+import io.quarkus.datasource.deployment.spi.DevDbResultBuildItem;
+
+public class NativeDevDbHandler implements BiConsumer {
+ @Override
+ public void accept(Object o, BuildResult buildResult) {
+ BiConsumer propertyConsumer = (BiConsumer) o;
+ DevDbResultBuildItem res = buildResult.consumeOptional(DevDbResultBuildItem.class);
+ if (res != null) {
+ if (res.getDefaultDatasource() != null) {
+ for (Map.Entry entry : res.getDefaultDatasource().getConfigProperties().entrySet()) {
+ propertyConsumer.accept(entry.getKey(), entry.getValue());
+ }
+ }
+ for (DevDbResultBuildItem.DbResult i : res.getNamedDatasources().values()) {
+ for (Map.Entry entry : i.getConfigProperties().entrySet()) {
+ propertyConsumer.accept(entry.getKey(), entry.getValue());
+ }
+ }
+ }
+ }
+}
diff --git a/test-framework/junit5/src/main/java/io/quarkus/test/junit/NativeTestExtension.java b/test-framework/junit5/src/main/java/io/quarkus/test/junit/NativeTestExtension.java
index 06da57d3aa9c5..adb7ce5b4a53b 100644
--- a/test-framework/junit5/src/main/java/io/quarkus/test/junit/NativeTestExtension.java
+++ b/test-framework/junit5/src/main/java/io/quarkus/test/junit/NativeTestExtension.java
@@ -1,19 +1,28 @@
package io.quarkus.test.junit;
+import static io.quarkus.test.common.PathTestHelper.getAppClassLocationForTestLocation;
+import static io.quarkus.test.common.PathTestHelper.getTestClassesLocation;
+
import java.io.Closeable;
+import java.io.File;
import java.io.IOException;
import java.lang.reflect.Field;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
+import java.util.function.BiConsumer;
import java.util.function.Function;
import java.util.stream.Collectors;
import javax.enterprise.inject.Alternative;
import javax.inject.Inject;
+import org.jboss.jandex.Index;
import org.junit.jupiter.api.extension.AfterEachCallback;
import org.junit.jupiter.api.extension.BeforeAllCallback;
import org.junit.jupiter.api.extension.BeforeEachCallback;
@@ -22,11 +31,20 @@
import org.junit.platform.commons.JUnitException;
import org.opentest4j.TestAbortedException;
+import io.quarkus.bootstrap.BootstrapConstants;
+import io.quarkus.bootstrap.app.CuratedApplication;
+import io.quarkus.bootstrap.app.QuarkusBootstrap;
+import io.quarkus.bootstrap.model.PathsCollection;
+import io.quarkus.bootstrap.resolver.model.QuarkusModel;
+import io.quarkus.bootstrap.utils.BuildToolHelper;
+import io.quarkus.datasource.deployment.spi.DevDbResultBuildItem;
import io.quarkus.runtime.configuration.ProfileManager;
import io.quarkus.runtime.test.TestHttpEndpointProvider;
import io.quarkus.test.common.NativeImageLauncher;
+import io.quarkus.test.common.PathTestHelper;
import io.quarkus.test.common.PropertyTestUtil;
import io.quarkus.test.common.RestAssuredURLManager;
+import io.quarkus.test.common.TestClassIndexer;
import io.quarkus.test.common.TestResourceManager;
import io.quarkus.test.common.TestScopeManager;
import io.quarkus.test.common.http.TestHTTPResourceManager;
@@ -82,7 +100,8 @@ private void ensureNoInjectAnnotationIsUsed(Class> testClass) {
}
- private ExtensionState ensureStarted(ExtensionContext extensionContext) {
+ private ExtensionState ensureStarted(ExtensionContext extensionContext) throws Exception {
+
Class> testClass = extensionContext.getRequiredTestClass();
ensureNoInjectAnnotationIsUsed(testClass);
@@ -118,8 +137,91 @@ private ExtensionState ensureStarted(ExtensionContext extensionContext) {
return state;
}
+ private Map handleDevDb(ExtensionContext context) throws Exception {
+ Class> requiredTestClass = context.getRequiredTestClass();
+ Path testClassLocation = getTestClassesLocation(requiredTestClass);
+ final Path appClassLocation = getAppClassLocationForTestLocation(testClassLocation.toString());
+
+ PathsCollection.Builder rootBuilder = PathsCollection.builder();
+
+ if (!appClassLocation.equals(testClassLocation)) {
+ rootBuilder.add(testClassLocation);
+ // if test classes is a dir, we should also check whether test resources dir exists as a separate dir (gradle)
+ // TODO: this whole app/test path resolution logic is pretty dumb, it needs be re-worked using proper workspace discovery
+ final Path testResourcesLocation = PathTestHelper.getResourcesForClassesDirOrNull(testClassLocation, "test");
+ if (testResourcesLocation != null) {
+ rootBuilder.add(testResourcesLocation);
+ }
+ }
+ final QuarkusBootstrap.Builder runnerBuilder = QuarkusBootstrap.builder()
+ .setIsolateDeployment(true)
+ .setMode(QuarkusBootstrap.Mode.TEST);
+ QuarkusTestProfile profileInstance = null;
+
+ final Path projectRoot = Paths.get("").normalize().toAbsolutePath();
+ runnerBuilder.setProjectRoot(projectRoot);
+ Path outputDir;
+ try {
+ // this should work for both maven and gradle
+ outputDir = projectRoot.resolve(projectRoot.relativize(testClassLocation).getName(0));
+ } catch (Exception e) {
+ // this shouldn't happen since testClassLocation is usually found under the project dir
+ outputDir = projectRoot;
+ }
+ runnerBuilder.setTargetDirectory(outputDir);
+
+ rootBuilder.add(appClassLocation);
+ final Path appResourcesLocation = PathTestHelper.getResourcesForClassesDirOrNull(appClassLocation, "main");
+ if (appResourcesLocation != null) {
+ rootBuilder.add(appResourcesLocation);
+ }
+
+ // If gradle project running directly with IDE
+ if (System.getProperty(BootstrapConstants.SERIALIZED_APP_MODEL) == null) {
+ QuarkusModel model = BuildToolHelper.enableGradleAppModelForTest(projectRoot);
+ if (model != null) {
+ final Set classDirectories = model.getWorkspace().getMainModule().getSourceSet()
+ .getSourceDirectories();
+ for (File classes : classDirectories) {
+ if (classes.exists() && !rootBuilder.contains(classes.toPath())) {
+ rootBuilder.add(classes.toPath());
+ }
+ }
+ }
+ } else if (System.getProperty(BootstrapConstants.OUTPUT_SOURCES_DIR) != null) {
+ final String[] sourceDirectories = System.getProperty(BootstrapConstants.OUTPUT_SOURCES_DIR).split(",");
+ for (String sourceDirectory : sourceDirectories) {
+ final Path directory = Paths.get(sourceDirectory);
+ if (Files.exists(directory) && !rootBuilder.contains(directory)) {
+ rootBuilder.add(directory);
+ }
+ }
+ }
+ runnerBuilder.setApplicationRoot(rootBuilder.build());
+
+ CuratedApplication curatedApplication = runnerBuilder
+ .setTest(true)
+ .build()
+ .bootstrap();
+
+ Index testClassesIndex = TestClassIndexer.indexTestClasses(requiredTestClass);
+ // we need to write the Index to make it reusable from other parts of the testing infrastructure that run in different ClassLoaders
+ TestClassIndexer.writeIndex(testClassesIndex, requiredTestClass);
+
+ Map propertyMap = new HashMap<>();
+ curatedApplication
+ .createAugmentor().performCustomBuild(NativeDevDbHandler.class.getName(), new BiConsumer() {
+ @Override
+ public void accept(String s, String s2) {
+ propertyMap.put(s, s2);
+ }
+ }, DevDbResultBuildItem.class.getName());
+ return propertyMap;
+ }
+
private ExtensionState doNativeStart(ExtensionContext context, Class extends QuarkusTestProfile> profile)
throws Throwable {
+ Map devDbProps = handleDevDb(context);
quarkusTestProfile = profile;
TestResourceManager testResourceManager = null;
try {
@@ -130,7 +232,7 @@ private ExtensionState doNativeStart(ExtensionContext context, Class extends Q
System.getProperty(ProfileManager.QUARKUS_TEST_PROFILE_PROP));
QuarkusTestProfile profileInstance = null;
- final Map additional = new HashMap<>();
+ final Map additional = new HashMap<>(devDbProps);
if (profile != null) {
profileInstance = profile.newInstance();
additional.putAll(profileInstance.getConfigOverrides());