Skip to content

Commit

Permalink
Only cache a subset of properties in datasource restart cache
Browse files Browse the repository at this point in the history
  • Loading branch information
Malandril committed Jul 10, 2024
1 parent b0f4244 commit eb559d8
Showing 1 changed file with 51 additions and 41 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,25 @@ public class DevServicesDatasourceProcessor {

// list of devservices properties we should not check for restart
// see issue #30390
private static final Set<String> EXCLUDED_PROPERTIES = Set.of("quarkus.datasource.devservices.enabled");
private static final Set<String> EXCLUDED_RESTART_PROPERTIES = Set.of();

/**
* Properties that if modified will trigger a datasource dev service restart
*/
private static final Set<String> 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<RunningDevService> databases;

Expand All @@ -78,14 +96,10 @@ DevServicesDatasourceResultBuildItem launchDatabases(
//if not and the DB's have already started we just return
if (databases != null) {
boolean restartRequired = false;
Map<String, String> newDatasourceConfigs = ConfigProvider.getConfig()
.unwrap(SmallRyeConfig.class)
.getOptionalValues("quarkus.datasource",
String.class, String.class)
.orElse(Map.of());
Map<String, String> newDatasourceConfigs = getRestartTriggeringPropertiesValues();
for (Map.Entry<String, String> 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;
}
Expand Down Expand Up @@ -124,7 +138,6 @@ DevServicesDatasourceResultBuildItem launchDatabases(
//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<String, String> propertiesMap = new HashMap<>();
List<RunningDevService> runningDevServices = new ArrayList<>();
Map<String, List<DevServicesDatasourceConfigurationHandlerBuildItem>> configHandlersByDbType = configurationHandlerBuildItems
.stream()
Expand All @@ -142,8 +155,8 @@ DevServicesDatasourceResultBuildItem launchDatabases(

for (Map.Entry<String, DataSourceBuildTimeConfig> entry : dataSourcesBuildTimeConfig.dataSources().entrySet()) {
RunningDevService devService = startDevDb(entry.getKey(), capabilities, curateOutcomeBuildItem,
installedDrivers, dataSourcesBuildTimeConfig.hasNamedDataSources(),
devDBProviderMap, entry.getValue(), configHandlersByDbType, propertiesMap,
installedDrivers, dataSourcesBuildTimeConfig.hasNamedDataSources(), devDBProviderMap,
entry.getValue(), configHandlersByDbType,
dockerStatusBuildItem,
launchMode.getLaunchMode(), consoleInstalledBuildItem, loggingSetupBuildItem, globalDevServicesConfig);
if (devService != null) {
Expand Down Expand Up @@ -174,17 +187,40 @@ 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<String, String> getRestartTriggeringPropertiesValues() {
Map<String, String> datasourceProperties = ConfigProvider.getConfig()
.unwrap(SmallRyeConfig.class)
.getOptionalValues("quarkus.datasource", String.class,
String.class)
.orElse(Map.of());
Map<String, String> 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;
}
Expand All @@ -199,7 +235,6 @@ private RunningDevService startDevDb(
boolean hasNamedDatasources,
Map<String, DevServicesDatasourceProvider> devDBProviders, DataSourceBuildTimeConfig dataSourceBuildTimeConfig,
Map<String, List<DevServicesDatasourceConfigurationHandlerBuildItem>> configurationHandlerBuildItems,
Map<String, String> propertiesMap,
DockerStatusBuildItem dockerStatusBuildItem,
LaunchMode launchMode, Optional<ConsoleInstalledBuildItem> consoleInstalledBuildItem,
LoggingSetupBuildItem loggingSetupBuildItem, GlobalDevServicesConfig globalDevServicesConfig) {
Expand Down Expand Up @@ -298,31 +333,6 @@ private RunningDevService startDevDb(
dbName, containerConfig,
launchMode, globalDevServicesConfig.timeout);

for (String key : DataSourceUtil.dataSourcePropertyKeys(dbName, "db-kind")) {
propertiesMap.put(key, dataSourceBuildTimeConfig.dbKind().orElse(null));
}
String devServicesPrefix = "devservices.";
if (dataSourceBuildTimeConfig.devservices().command().isPresent()) {
setDataSourceProperties(propertiesMap, dbName, devServicesPrefix + "command",
dataSourceBuildTimeConfig.devservices().command().get());
}
if (dataSourceBuildTimeConfig.devservices().imageName().isPresent()) {
setDataSourceProperties(propertiesMap, dbName, devServicesPrefix + "image-name",
dataSourceBuildTimeConfig.devservices().imageName().get());
}
if (dataSourceBuildTimeConfig.devservices().port().isPresent()) {
setDataSourceProperties(propertiesMap, dbName, devServicesPrefix + "port",
Integer.toString(dataSourceBuildTimeConfig.devservices().port().getAsInt()));
}
if (!dataSourceBuildTimeConfig.devservices().properties().isEmpty()) {
for (var e : dataSourceBuildTimeConfig.devservices().properties().entrySet()) {
setDataSourceProperties(propertiesMap, dbName, devServicesPrefix + "properties." + e.getKey(),
e.getValue());
}
}
setDataSourceProperties(propertiesMap, dbName, devServicesPrefix + "reuse",
String.valueOf(dataSourceBuildTimeConfig.devservices().reuse()));

Map<String, String> devDebProperties = new HashMap<>();
for (DevServicesDatasourceConfigurationHandlerBuildItem devDbConfigurationHandlerBuildItem : configHandlers) {
Map<String, String> properties = devDbConfigurationHandlerBuildItem.getConfigProviderFunction().apply(dbName,
Expand Down

0 comments on commit eb559d8

Please sign in to comment.