diff --git a/extensions/datasource/deployment/src/main/java/io/quarkus/datasource/deployment/devservices/DevServicesDatasourceProcessor.java b/extensions/datasource/deployment/src/main/java/io/quarkus/datasource/deployment/devservices/DevServicesDatasourceProcessor.java index b254874043b5d..92f016d6f93b0 100644 --- a/extensions/datasource/deployment/src/main/java/io/quarkus/datasource/deployment/devservices/DevServicesDatasourceProcessor.java +++ b/extensions/datasource/deployment/src/main/java/io/quarkus/datasource/deployment/devservices/DevServicesDatasourceProcessor.java @@ -6,6 +6,7 @@ import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.NoSuchElementException; import java.util.Objects; import java.util.Optional; import java.util.Set; @@ -51,7 +52,25 @@ public class DevServicesDatasourceProcessor { // list of devservices properties we should not check for restart // see issue #30390 - private static final Set EXCLUDED_PROPERTIES = Set.of("quarkus.datasource.devservices.enabled"); + private static final Set EXCLUDED_RESTART_PROPERTIES = Set.of(); + + /** + * Properties that if modified will trigger a datasource dev service restart + */ + private static final Set RESTART_TRIGGERING_PROPERTIES = Set.of("db-kind", + "db-version", + "devservices.command", + "devservices.container-env.", + "devservices.container-properties.", + "devservices.db-name", + "devservices.image-name", + "devservices.init-script-path", + "devservices.port", + "devservices.properties.", + "devservices.reuse", + "devservices.volumes.", + "password", + "username"); static volatile List databases; @@ -78,14 +97,10 @@ DevServicesDatasourceResultBuildItem launchDatabases( //if not and the DB's have already started we just return if (databases != null) { boolean restartRequired = false; - Map newDatasourceConfigs = ConfigProvider.getConfig() - .unwrap(SmallRyeConfig.class) - .getOptionalValues("quarkus.datasource", - String.class, String.class) - .orElse(Map.of()); + Map newDatasourceConfigs = getRestartTriggeringPropertiesValues(); for (Map.Entry entry : cachedProperties.entrySet()) { String newValue = newDatasourceConfigs.get(entry.getKey()); - if (!Objects.equals(entry.getValue(), trim(newValue))) { + if (!Objects.equals(entry.getValue(), newValue)) { restartRequired = true; break; } @@ -174,17 +189,47 @@ public void run() { closeBuildItem.addCloseTask(closeTask, true); } databases = runningDevServices; - cachedProperties = ConfigProvider.getConfig() - .unwrap(SmallRyeConfig.class) - .getOptionalValues("quarkus.datasource", String.class, String.class) - .orElse(Map.of()); + cachedProperties = getRestartTriggeringPropertiesValues(); for (RunningDevService database : databases) { devServicesResultBuildItemBuildProducer.produce(database.toBuildItem()); } return new DevServicesDatasourceResultBuildItem(results); } - private String trim(String optional) { + /** + * Returns a map of properties that are can trigger a datasource dev service restart if modified. + * It excludes EXCLUDED_PROPERTIES and includes only RESTART_TRIGGERING_PROPERTIES. + * If a property ends with {@code .} then it will also trigger a restart on any sub properties change + */ + private static Map getRestartTriggeringPropertiesValues() { + Map datasourceProperties; + try { + datasourceProperties = ConfigProvider.getConfig() + .unwrap(SmallRyeConfig.class) + .getOptionalValues("quarkus.datasource", + String.class, + String.class) + .orElse(Map.of()); + } catch (NoSuchElementException e) { + log.error("Could not get datasource properties", e); + datasourceProperties = Map.of(); + } + Map filteredProperties = new HashMap<>(); + for (var entry : datasourceProperties.entrySet()) { + if (!EXCLUDED_RESTART_PROPERTIES.contains(entry.getKey())) { + for (String property : RESTART_TRIGGERING_PROPERTIES) { + if (property.endsWith(".") && entry.getKey().contains(property) || entry.getKey() + .endsWith(property)) { + filteredProperties.put(entry.getKey(), trim(entry.getValue())); + break; + } + } + } + } + return filteredProperties; + } + + private static String trim(String optional) { if (optional == null) { return null; }