mirror of
https://github.com/danieldemus/openhab-core.git
synced 2026-07-29 12:34:22 +02:00
Persistence upgrader: Create default persistence settings if no configuration so far (#5212)
* fix persistence upgrade Signed-off-by: Florian Hotze <dev@florianhotze.com> Co-authored-by: Mark Herwege <mark.herwege@telenet.be>
This commit is contained in:
co-authored by
Mark Herwege
parent
1ea34bf464
commit
a221c4fa41
+130
-6
@@ -12,16 +12,20 @@
|
|||||||
*/
|
*/
|
||||||
package org.openhab.core.tools.internal;
|
package org.openhab.core.tools.internal;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
import java.nio.file.Files;
|
import java.nio.file.Files;
|
||||||
import java.nio.file.Path;
|
import java.nio.file.Path;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||||
import org.eclipse.jdt.annotation.Nullable;
|
import org.eclipse.jdt.annotation.Nullable;
|
||||||
|
import org.openhab.core.persistence.dto.PersistenceCronStrategyDTO;
|
||||||
import org.openhab.core.persistence.dto.PersistenceItemConfigurationDTO;
|
import org.openhab.core.persistence.dto.PersistenceItemConfigurationDTO;
|
||||||
import org.openhab.core.persistence.dto.PersistenceServiceConfigurationDTO;
|
import org.openhab.core.persistence.dto.PersistenceServiceConfigurationDTO;
|
||||||
|
import org.openhab.core.persistence.strategy.PersistenceStrategy;
|
||||||
import org.openhab.core.storage.json.internal.JsonStorage;
|
import org.openhab.core.storage.json.internal.JsonStorage;
|
||||||
import org.openhab.core.tools.Upgrader;
|
import org.openhab.core.tools.Upgrader;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
@@ -56,16 +60,38 @@ public class PersistenceUpgrader implements Upgrader {
|
|||||||
logger.error("{} skipped: no userdata directory found.", getName());
|
logger.error("{} skipped: no userdata directory found.", getName());
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
if (confPath == null) {
|
||||||
|
logger.error("{} skipped: no conf directory found.", getName());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
Path persistenceJsonDatabasePath = userdataPath
|
List<String> managedConfigs;
|
||||||
.resolve(Path.of("jsondb", "org.openhab.core.persistence.PersistenceServiceConfiguration.json"));
|
try {
|
||||||
if (Files.notExists(persistenceJsonDatabasePath)) {
|
managedConfigs = managedPersistenceConfigs(installedPersistenceAddons(userdataPath),
|
||||||
|
unmanagedPersistenceConfigs(confPath));
|
||||||
|
} catch (IOException e) {
|
||||||
|
logger.error("{} skipped: failed to read config: {}", getName(), e.getMessage());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (managedConfigs.isEmpty()) {
|
||||||
// No managed persistence configurations, so no need to upgrade
|
// No managed persistence configurations, so no need to upgrade
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
logger.info("Setting default strategy on managed persistence configurations without strategy '{}'",
|
Path persistenceJsonDatabasePath = userdataPath
|
||||||
persistenceJsonDatabasePath);
|
.resolve(Path.of("jsondb", "org.openhab.core.persistence.PersistenceServiceConfiguration.json"));
|
||||||
|
if (Files.notExists(persistenceJsonDatabasePath)) {
|
||||||
|
// No configuration, but persistence addons are installed and there is no unmanaged configuration for it, so
|
||||||
|
// it needs to be created. Add JSON content to avoid warning from JSONDB.
|
||||||
|
try {
|
||||||
|
Files.createFile(persistenceJsonDatabasePath);
|
||||||
|
Files.writeString(persistenceJsonDatabasePath, "{}");
|
||||||
|
} catch (IOException e) {
|
||||||
|
logger.error("Cannot create persistence configuration database '{}', check path and access rights.",
|
||||||
|
persistenceJsonDatabasePath);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (!Files.isWritable(persistenceJsonDatabasePath)) {
|
if (!Files.isWritable(persistenceJsonDatabasePath)) {
|
||||||
logger.error("Cannot access persistence configuration database '{}', check path and access rights.",
|
logger.error("Cannot access persistence configuration database '{}', check path and access rights.",
|
||||||
@@ -75,7 +101,23 @@ public class PersistenceUpgrader implements Upgrader {
|
|||||||
JsonStorage<PersistenceServiceConfigurationDTO> persistenceStorage = new JsonStorage<>(
|
JsonStorage<PersistenceServiceConfigurationDTO> persistenceStorage = new JsonStorage<>(
|
||||||
persistenceJsonDatabasePath.toFile(), null, 5, 0, 0, List.of());
|
persistenceJsonDatabasePath.toFile(), null, 5, 0, 0, List.of());
|
||||||
|
|
||||||
List.copyOf(persistenceStorage.getKeys()).forEach(serviceId -> {
|
List<String> persistenceStorageKeys = List.copyOf(persistenceStorage.getKeys());
|
||||||
|
|
||||||
|
// Add all installed persistence services without explicit configuration with their previous default
|
||||||
|
// configuration
|
||||||
|
List<String> managedConfigsToAdd = managedConfigs.stream()
|
||||||
|
.filter(serviceId -> !persistenceStorageKeys.contains(serviceId)).toList();
|
||||||
|
managedConfigsToAdd.forEach(serviceId -> {
|
||||||
|
PersistenceServiceConfigurationDTO serviceConfigDTO = defaultServiceConfig(serviceId);
|
||||||
|
if (serviceConfigDTO != null) {
|
||||||
|
persistenceStorage.put(serviceId, serviceConfigDTO);
|
||||||
|
logger.info("{}: added strategy configurations for persistence service without configuration",
|
||||||
|
serviceId);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// Update existing managed configurations
|
||||||
|
persistenceStorageKeys.forEach(serviceId -> {
|
||||||
PersistenceServiceConfigurationDTO serviceConfigDTO = Objects
|
PersistenceServiceConfigurationDTO serviceConfigDTO = Objects
|
||||||
.requireNonNull(persistenceStorage.get(serviceId));
|
.requireNonNull(persistenceStorage.get(serviceId));
|
||||||
Collection<String> defaults = serviceConfigDTO.defaults;
|
Collection<String> defaults = serviceConfigDTO.defaults;
|
||||||
@@ -97,4 +139,86 @@ public class PersistenceUpgrader implements Upgrader {
|
|||||||
persistenceStorage.flush();
|
persistenceStorage.flush();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private List<String> installedPersistenceAddons(Path userdataPath) throws IOException {
|
||||||
|
Path addonsConfigPath = userdataPath.resolve("config/org/openhab/addons.config");
|
||||||
|
if (Files.notExists(addonsConfigPath)) {
|
||||||
|
throw new IOException(
|
||||||
|
"Cannot access addon config '" + addonsConfigPath + "', check path and access rights.");
|
||||||
|
}
|
||||||
|
|
||||||
|
List<String> configLines;
|
||||||
|
configLines = Files.readAllLines(addonsConfigPath);
|
||||||
|
|
||||||
|
for (String line : configLines) {
|
||||||
|
if (line.startsWith("persistence")) {
|
||||||
|
String[] persistenceLine = line.split("=");
|
||||||
|
if (persistenceLine.length > 1) {
|
||||||
|
String[] persistenceAddons = persistenceLine[1].replace("\"", "").split(",");
|
||||||
|
return Stream.of(persistenceAddons).map(String::trim).toList();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return List.of();
|
||||||
|
}
|
||||||
|
|
||||||
|
private List<String> unmanagedPersistenceConfigs(Path configPath) throws IOException {
|
||||||
|
Path persistenceConfigPath = configPath.resolve("persistence");
|
||||||
|
try (Stream<Path> files = Files.list(persistenceConfigPath)) {
|
||||||
|
return files.filter(configFile -> configFile.endsWith(".persist"))
|
||||||
|
.map(configFile -> configFile.getFileName().toString().replace(".persist", "")).toList();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private List<String> managedPersistenceConfigs(List<String> installedAddons, List<String> unmanagedConfigs) {
|
||||||
|
return installedAddons.stream().filter(a -> !unmanagedConfigs.contains(a)).toList();
|
||||||
|
}
|
||||||
|
|
||||||
|
private @Nullable PersistenceServiceConfigurationDTO defaultServiceConfig(String serviceId) {
|
||||||
|
PersistenceItemConfigurationDTO itemConfigDTO = new PersistenceItemConfigurationDTO();
|
||||||
|
List<String> strategies = defaultPersistenceStrategies(serviceId);
|
||||||
|
if (strategies != null) {
|
||||||
|
itemConfigDTO.items = List.of("*");
|
||||||
|
itemConfigDTO.strategies = strategies;
|
||||||
|
PersistenceServiceConfigurationDTO serviceConfigDTO = new PersistenceServiceConfigurationDTO();
|
||||||
|
serviceConfigDTO.serviceId = serviceId;
|
||||||
|
serviceConfigDTO.configs = List.of(itemConfigDTO);
|
||||||
|
List<PersistenceCronStrategyDTO> cronStrategies = defaultCronStrategies(serviceId);
|
||||||
|
if (cronStrategies != null) {
|
||||||
|
serviceConfigDTO.cronStrategies = cronStrategies;
|
||||||
|
}
|
||||||
|
return serviceConfigDTO;
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private @Nullable List<String> defaultPersistenceStrategies(String service) {
|
||||||
|
return switch (service) {
|
||||||
|
case "rrd4j" -> List.of(PersistenceStrategy.Globals.RESTORE.getName(),
|
||||||
|
PersistenceStrategy.Globals.CHANGE.getName(), "everyMinute");
|
||||||
|
case "mapdb" ->
|
||||||
|
List.of(PersistenceStrategy.Globals.RESTORE.getName(), PersistenceStrategy.Globals.CHANGE.getName());
|
||||||
|
case "inmemory" -> List.of(PersistenceStrategy.Globals.FORECAST.getName());
|
||||||
|
case "jdbc" -> List.of(PersistenceStrategy.Globals.CHANGE.getName());
|
||||||
|
case "influxdb" ->
|
||||||
|
List.of(PersistenceStrategy.Globals.RESTORE.getName(), PersistenceStrategy.Globals.CHANGE.getName());
|
||||||
|
case "dynamodb" ->
|
||||||
|
List.of(PersistenceStrategy.Globals.RESTORE.getName(), PersistenceStrategy.Globals.CHANGE.getName());
|
||||||
|
default -> null;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
private @Nullable List<PersistenceCronStrategyDTO> defaultCronStrategies(String service) {
|
||||||
|
return switch (service) {
|
||||||
|
case "rrd4j" -> List.of(everyMinuteStrategy());
|
||||||
|
default -> null;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
private PersistenceCronStrategyDTO everyMinuteStrategy() {
|
||||||
|
PersistenceCronStrategyDTO everyMinuteStrategy = new PersistenceCronStrategyDTO();
|
||||||
|
everyMinuteStrategy.name = "everyMinute";
|
||||||
|
everyMinuteStrategy.cronExpression = "0 * * * * ?";
|
||||||
|
return everyMinuteStrategy;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user