Upgrade Tool: Split upgrade commands into individual classes
Signed-off-by: Jimmy Tanagra <jcode@tanagra.id.au>pull/4718/head
parent
d6fb61d0c7
commit
2515b05ee3
|
@ -12,8 +12,10 @@
|
|||
*/
|
||||
package org.openhab.core.tools;
|
||||
|
||||
import static org.openhab.core.tools.internal.Upgrader.*;
|
||||
|
||||
import java.io.PrintStream;
|
||||
import java.nio.file.Path;
|
||||
import java.time.ZonedDateTime;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import org.apache.commons.cli.CommandLine;
|
||||
|
@ -23,27 +25,47 @@ import org.apache.commons.cli.Option;
|
|||
import org.apache.commons.cli.Options;
|
||||
import org.apache.commons.cli.ParseException;
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
import org.openhab.core.tools.internal.Upgrader;
|
||||
import org.eclipse.jdt.annotation.Nullable;
|
||||
import org.openhab.core.storage.json.internal.JsonStorage;
|
||||
import org.openhab.core.tools.internal.*;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
/**
|
||||
* The {@link UpgradeTool} is a tool for upgrading openHAB to mitigate breaking changes
|
||||
*
|
||||
* @author Jan N. Klug - Initial contribution
|
||||
* @author Jimmy Tanagra - Refactor upgraders into individual classes
|
||||
*/
|
||||
@NonNullByDefault
|
||||
public class UpgradeTool {
|
||||
private static final Set<String> LOG_LEVELS = Set.of("TRACE", "DEBUG", "INFO", "WARN", "ERROR");
|
||||
private static final String OPT_COMMAND = "command";
|
||||
private static final String OPT_DIR = "dir";
|
||||
private static final String OPT_LIST_COMMANDS = "list-commands";
|
||||
private static final String OPT_USERDATA_DIR = "userdata";
|
||||
private static final String OPT_CONF_DIR = "conf";
|
||||
private static final String OPT_LOG = "log";
|
||||
private static final String OPT_FORCE = "force";
|
||||
|
||||
private static final List<Upgrader> UPGRADERS = List.of( //
|
||||
new ItemUnitToMetadataUpgrader(), //
|
||||
new JSProfileUpgrader(), //
|
||||
new ScriptProfileUpgrader() //
|
||||
);
|
||||
|
||||
private static final Logger logger = LoggerFactory.getLogger(UpgradeTool.class);
|
||||
private static @Nullable JsonStorage<UpgradeRecord> upgradeRecords = null;
|
||||
|
||||
private static Options getOptions() {
|
||||
Options options = new Options();
|
||||
|
||||
options.addOption(Option.builder().longOpt(OPT_DIR).desc("directory to process").numberOfArgs(1).build());
|
||||
options.addOption(Option.builder().longOpt(OPT_USERDATA_DIR).desc("USERDATA directory to process")
|
||||
.numberOfArgs(1).build());
|
||||
options.addOption(
|
||||
Option.builder().longOpt(OPT_CONF_DIR).desc("CONF directory to process").numberOfArgs(1).build());
|
||||
options.addOption(Option.builder().longOpt(OPT_COMMAND).numberOfArgs(1)
|
||||
.desc("command to execute (executes all if omitted)").build());
|
||||
options.addOption(Option.builder().longOpt(OPT_LIST_COMMANDS).desc("list available commands").build());
|
||||
options.addOption(Option.builder().longOpt(OPT_LOG).numberOfArgs(1).desc("log verbosity").build());
|
||||
options.addOption(Option.builder().longOpt(OPT_FORCE).desc("force execution (even if already done)").build());
|
||||
|
||||
|
@ -58,42 +80,110 @@ public class UpgradeTool {
|
|||
String loglevel = commandLine.hasOption(OPT_LOG) ? commandLine.getOptionValue(OPT_LOG).toUpperCase()
|
||||
: "INFO";
|
||||
if (!LOG_LEVELS.contains(loglevel)) {
|
||||
System.out.println("Allowed log-levels are " + LOG_LEVELS);
|
||||
println("Allowed log-levels are " + LOG_LEVELS);
|
||||
System.exit(0);
|
||||
}
|
||||
|
||||
if (commandLine.hasOption(OPT_LIST_COMMANDS)) {
|
||||
println("Available commands:");
|
||||
UPGRADERS.stream().forEach(upgrader -> {
|
||||
println(" - " + upgrader.getName() + ": " + upgrader.getDescription());
|
||||
});
|
||||
System.exit(0);
|
||||
}
|
||||
|
||||
System.setProperty(org.slf4j.simple.SimpleLogger.DEFAULT_LOG_LEVEL_KEY, loglevel);
|
||||
|
||||
String baseDir = commandLine.hasOption(OPT_DIR) ? commandLine.getOptionValue(OPT_DIR)
|
||||
String userdataDir = commandLine.hasOption(OPT_USERDATA_DIR) ? commandLine.getOptionValue(OPT_USERDATA_DIR)
|
||||
: System.getenv("OPENHAB_USERDATA");
|
||||
if (baseDir == null || baseDir.isBlank()) {
|
||||
System.out.println(
|
||||
"Please either set the environment variable ${OPENHAB_USERDATA} or provide a directory through the --dir option.");
|
||||
if (userdataDir == null || userdataDir.isBlank()) {
|
||||
println("Please either set the environment variable ${OPENHAB_USERDATA} or provide a directory through the --userdata option.");
|
||||
System.exit(0);
|
||||
} else {
|
||||
boolean force = commandLine.hasOption(OPT_FORCE);
|
||||
return;
|
||||
}
|
||||
|
||||
Upgrader upgrader = new Upgrader(baseDir, force);
|
||||
if (!commandLine.hasOption(OPT_COMMAND)
|
||||
|| ITEM_COPY_UNIT_TO_METADATA.equals(commandLine.getOptionValue(OPT_COMMAND))) {
|
||||
upgrader.itemCopyUnitToMetadata();
|
||||
String confDir = commandLine.hasOption(OPT_CONF_DIR) ? commandLine.getOptionValue(OPT_CONF_DIR)
|
||||
: System.getenv("OPENHAB_CONF");
|
||||
if (confDir == null || confDir.isBlank()) {
|
||||
println("Please either set the environment variable ${OPENHAB_CONF} or provide a directory through the --conf option.");
|
||||
System.exit(0);
|
||||
return;
|
||||
}
|
||||
if (!commandLine.hasOption(OPT_COMMAND)
|
||||
|| LINK_UPGRADE_JS_PROFILE.equals(commandLine.getOptionValue(OPT_COMMAND))) {
|
||||
upgrader.linkUpgradeJsProfile();
|
||||
|
||||
boolean force = commandLine.hasOption(OPT_FORCE);
|
||||
String command = commandLine.hasOption(OPT_COMMAND) ? commandLine.getOptionValue(OPT_COMMAND) : null;
|
||||
|
||||
if (command != null && UPGRADERS.stream().filter(u -> u.getName().equals(command)).findAny().isEmpty()) {
|
||||
println("Unknown command: " + command);
|
||||
System.exit(0);
|
||||
}
|
||||
if (!commandLine.hasOption(OPT_COMMAND)
|
||||
|| LINK_UPGRADE_SCRIPT_PROFILE.equals(commandLine.getOptionValue(OPT_COMMAND))) {
|
||||
upgrader.linkUpgradeScriptProfile();
|
||||
|
||||
Path upgradeJsonDatabasePath = Path.of(userdataDir, "jsondb", "org.openhab.core.tools.UpgradeTool");
|
||||
upgradeRecords = new JsonStorage<>(upgradeJsonDatabasePath.toFile(), null, 5, 0, 0, List.of());
|
||||
|
||||
UPGRADERS.forEach(upgrader -> {
|
||||
String upgraderName = upgrader.getName();
|
||||
if (command != null && !upgraderName.equals(command)) {
|
||||
return;
|
||||
}
|
||||
if (!force && lastExecuted(upgraderName) instanceof String executionDate) {
|
||||
logger.info("Already executed '{}' on {}. Use '--force' to execute it again.", upgraderName,
|
||||
executionDate);
|
||||
return;
|
||||
}
|
||||
try {
|
||||
logger.info("Executing {}: {}", upgraderName, upgrader.getDescription());
|
||||
if (upgrader.execute(userdataDir, confDir)) {
|
||||
updateUpgradeRecord(upgraderName);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
logger.error("Error executing upgrader {}: {}", upgraderName, e.getMessage());
|
||||
}
|
||||
});
|
||||
} catch (ParseException e) {
|
||||
HelpFormatter formatter = new HelpFormatter();
|
||||
String commands = Set.of(ITEM_COPY_UNIT_TO_METADATA, LINK_UPGRADE_JS_PROFILE, LINK_UPGRADE_SCRIPT_PROFILE)
|
||||
.toString();
|
||||
formatter.printHelp("upgradetool", "", options, "Available commands: " + commands, true);
|
||||
formatter.printHelp("upgradetool", "", options, "", true);
|
||||
}
|
||||
|
||||
System.exit(0);
|
||||
}
|
||||
|
||||
private static @Nullable String lastExecuted(String upgrader) {
|
||||
JsonStorage<UpgradeRecord> records = upgradeRecords;
|
||||
if (records != null) {
|
||||
UpgradeRecord upgradeRecord = records.get(upgrader);
|
||||
if (upgradeRecord != null) {
|
||||
return upgradeRecord.executionDate;
|
||||
}
|
||||
} else {
|
||||
logger.error("Upgrade records storage is not initialized.");
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private static void updateUpgradeRecord(String upgrader) {
|
||||
JsonStorage<UpgradeRecord> records = upgradeRecords;
|
||||
if (records != null) {
|
||||
records.put(upgrader, new UpgradeRecord(ZonedDateTime.now()));
|
||||
records.flush();
|
||||
} else {
|
||||
logger.error("Upgrade records storage is not initialized.");
|
||||
}
|
||||
}
|
||||
|
||||
// to avoid compiler's null pointer warnings
|
||||
private static void println(String message) {
|
||||
PrintStream out = System.out;
|
||||
if (out != null) {
|
||||
out.println(message);
|
||||
}
|
||||
}
|
||||
|
||||
private static class UpgradeRecord {
|
||||
public final String executionDate;
|
||||
|
||||
public UpgradeRecord(ZonedDateTime executionDate) {
|
||||
this.executionDate = executionDate.toString();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,40 @@
|
|||
/*
|
||||
* Copyright (c) 2010-2025 Contributors to the openHAB project
|
||||
*
|
||||
* See the NOTICE file(s) distributed with this work for additional
|
||||
* information.
|
||||
*
|
||||
* This program and the accompanying materials are made available under the
|
||||
* terms of the Eclipse Public License 2.0 which is available at
|
||||
* http://www.eclipse.org/legal/epl-2.0
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*/
|
||||
package org.openhab.core.tools;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
|
||||
/**
|
||||
* The {@link Upgrader} provides an interface for upgrading openHAB configuration files.
|
||||
*
|
||||
* Implementing class MUST provide a no-argument constructor.
|
||||
*
|
||||
* @author Jimmy Tanagra - Initial contribution
|
||||
*/
|
||||
@NonNullByDefault
|
||||
public interface Upgrader {
|
||||
String getName();
|
||||
|
||||
String getDescription();
|
||||
|
||||
/**
|
||||
* Executes the upgrade process.
|
||||
*
|
||||
* @param userdataDir the OPENHAB_USERDATA directory for the upgrade,
|
||||
* or a custom path given by the user as --userdata argument
|
||||
* @param confDir the OPENHAB_CONF directory for the upgrade,
|
||||
* or a custom path given by the user as --conf argument
|
||||
* @return true if the upgrade was successful, false otherwise
|
||||
*/
|
||||
boolean execute(String userdataDir, String confDir);
|
||||
}
|
|
@ -18,77 +18,57 @@ import static org.openhab.core.thing.DefaultSystemChannelTypeProvider.SYSTEM_CHA
|
|||
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.time.ZonedDateTime;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
|
||||
import javax.measure.Unit;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
import org.openhab.core.config.core.Configuration;
|
||||
import org.openhab.core.items.ManagedItemProvider;
|
||||
import org.openhab.core.items.Metadata;
|
||||
import org.openhab.core.items.MetadataKey;
|
||||
import org.openhab.core.library.items.NumberItem;
|
||||
import org.openhab.core.storage.json.internal.JsonStorage;
|
||||
import org.openhab.core.thing.dto.ThingDTO;
|
||||
import org.openhab.core.thing.internal.link.ItemChannelLinkConfigDescriptionProvider;
|
||||
import org.openhab.core.thing.link.ItemChannelLink;
|
||||
import org.openhab.core.tools.Upgrader;
|
||||
import org.openhab.core.types.util.UnitUtils;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
/**
|
||||
* The {@link Upgrader} contains the implementation of the upgrade methods
|
||||
* The {@link ItemUnitToMetadataUpgrader} copies the unit from the item to the metadata.
|
||||
*
|
||||
* @author Jan N. Klug - Initial contribution
|
||||
* @author Florian Hotze - Add script profile upgrade
|
||||
* @author Jimmy Tanagra - Refactored into a separate class
|
||||
*/
|
||||
@NonNullByDefault
|
||||
public class Upgrader {
|
||||
public static final String ITEM_COPY_UNIT_TO_METADATA = "itemCopyUnitToMetadata";
|
||||
public static final String LINK_UPGRADE_JS_PROFILE = "linkUpgradeJsProfile";
|
||||
public static final String LINK_UPGRADE_SCRIPT_PROFILE = "linkUpgradeScriptProfile";
|
||||
public class ItemUnitToMetadataUpgrader implements Upgrader {
|
||||
private final Logger logger = LoggerFactory.getLogger(ItemUnitToMetadataUpgrader.class);
|
||||
|
||||
private final Logger logger = LoggerFactory.getLogger(Upgrader.class);
|
||||
private final String baseDir;
|
||||
private final boolean force;
|
||||
private final JsonStorage<UpgradeRecord> upgradeRecords;
|
||||
|
||||
public Upgrader(String baseDir, boolean force) {
|
||||
this.baseDir = baseDir;
|
||||
this.force = force;
|
||||
|
||||
Path upgradeJsonDatabasePath = Path.of(baseDir, "jsondb", "org.openhab.core.tools.UpgradeTool");
|
||||
|
||||
upgradeRecords = new JsonStorage<>(upgradeJsonDatabasePath.toFile(), null, 5, 0, 0, List.of());
|
||||
@Override
|
||||
public String getName() {
|
||||
return "itemCopyUnitToMetadata"; // keep the old name for backwards compatibility
|
||||
}
|
||||
|
||||
private boolean checkUpgradeRecord(String key) {
|
||||
UpgradeRecord upgradeRecord = upgradeRecords.get(key);
|
||||
if (upgradeRecord != null && !force) {
|
||||
logger.info("Already executed '{}' on {}. Use '--force' to execute it again.", key,
|
||||
upgradeRecord.executionDate);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
@Override
|
||||
public String getDescription() {
|
||||
return "Copy item unit from state description to metadata";
|
||||
}
|
||||
|
||||
public void itemCopyUnitToMetadata() {
|
||||
@Override
|
||||
public boolean execute(String userdataDir, String confDir) {
|
||||
boolean noLink;
|
||||
|
||||
if (!checkUpgradeRecord(ITEM_COPY_UNIT_TO_METADATA)) {
|
||||
return;
|
||||
}
|
||||
Path itemJsonDatabasePath = Path.of(baseDir, "jsondb", "org.openhab.core.items.Item.json");
|
||||
Path metadataJsonDatabasePath = Path.of(baseDir, "jsondb", "org.openhab.core.items.Metadata.json");
|
||||
Path linkJsonDatabasePath = Path.of(baseDir, "jsondb", "org.openhab.core.thing.link.ItemChannelLink.json");
|
||||
Path thingJsonDatabasePath = Path.of(baseDir, "jsondb", "org.openhab.core.thing.Thing.json");
|
||||
Path itemJsonDatabasePath = Path.of(userdataDir, "jsondb", "org.openhab.core.items.Item.json");
|
||||
Path metadataJsonDatabasePath = Path.of(userdataDir, "jsondb", "org.openhab.core.items.Metadata.json");
|
||||
Path linkJsonDatabasePath = Path.of(userdataDir, "jsondb", "org.openhab.core.thing.link.ItemChannelLink.json");
|
||||
Path thingJsonDatabasePath = Path.of(userdataDir, "jsondb", "org.openhab.core.thing.Thing.json");
|
||||
logger.info("Copying item unit from state description to metadata in database '{}'", itemJsonDatabasePath);
|
||||
|
||||
if (!Files.isReadable(itemJsonDatabasePath)) {
|
||||
logger.error("Cannot access item database '{}', check path and access rights.", itemJsonDatabasePath);
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!Files.isReadable(linkJsonDatabasePath) || !Files.isReadable(thingJsonDatabasePath)) {
|
||||
|
@ -102,7 +82,7 @@ public class Upgrader {
|
|||
if (!Files.isWritable(metadataJsonDatabasePath) && Files.exists(metadataJsonDatabasePath)) {
|
||||
logger.error("Cannot access metadata database '{}', check path and access rights.",
|
||||
metadataJsonDatabasePath);
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
|
||||
JsonStorage<ManagedItemProvider.PersistedItem> itemStorage = new JsonStorage<>(itemJsonDatabasePath.toFile(),
|
||||
|
@ -121,7 +101,7 @@ public class Upgrader {
|
|||
logger.debug("{}: Already contains a 'unit' metadata, skipping it", itemName);
|
||||
} else {
|
||||
String unit = null;
|
||||
if (!noLink) {
|
||||
if (linkStorage != null && thingStorage != null) {
|
||||
List<ItemChannelLink> links = linkStorage.getValues().stream().map(Objects::requireNonNull)
|
||||
.filter(link -> itemName.equals(link.getItemName())).toList();
|
||||
// check if we can find the channel for these links
|
||||
|
@ -192,98 +172,7 @@ public class Upgrader {
|
|||
});
|
||||
|
||||
metadataStorage.flush();
|
||||
upgradeRecords.put(ITEM_COPY_UNIT_TO_METADATA, new UpgradeRecord(ZonedDateTime.now()));
|
||||
upgradeRecords.flush();
|
||||
}
|
||||
|
||||
public void linkUpgradeJsProfile() {
|
||||
if (!checkUpgradeRecord(LINK_UPGRADE_JS_PROFILE)) {
|
||||
return;
|
||||
}
|
||||
|
||||
Path linkJsonDatabasePath = Path.of(baseDir, "jsondb", "org.openhab.core.thing.link.ItemChannelLink.json");
|
||||
logger.info("Upgrading JS profile configuration in database '{}'", linkJsonDatabasePath);
|
||||
|
||||
if (!Files.isWritable(linkJsonDatabasePath)) {
|
||||
logger.error("Cannot access link database '{}', check path and access rights.", linkJsonDatabasePath);
|
||||
return;
|
||||
}
|
||||
JsonStorage<ItemChannelLink> linkStorage = new JsonStorage<>(linkJsonDatabasePath.toFile(), null, 5, 0, 0,
|
||||
List.of());
|
||||
|
||||
List.copyOf(linkStorage.getKeys()).forEach(linkUid -> {
|
||||
ItemChannelLink link = Objects.requireNonNull(linkStorage.get(linkUid));
|
||||
Configuration configuration = link.getConfiguration();
|
||||
String profileName = (String) configuration.get(ItemChannelLinkConfigDescriptionProvider.PARAM_PROFILE);
|
||||
if ("transform:JS".equals(profileName)) {
|
||||
String function = (String) configuration.get("function");
|
||||
if (function != null) {
|
||||
configuration.put("toItemScript", function);
|
||||
configuration.put("toHandlerScript", "|input");
|
||||
configuration.remove("function");
|
||||
configuration.remove("sourceFormat");
|
||||
|
||||
linkStorage.put(linkUid, link);
|
||||
logger.info("{}: rewrote JS profile link to new format", linkUid);
|
||||
} else {
|
||||
logger.info("{}: link already has correct configuration", linkUid);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
linkStorage.flush();
|
||||
upgradeRecords.put(LINK_UPGRADE_JS_PROFILE, new UpgradeRecord(ZonedDateTime.now()));
|
||||
upgradeRecords.flush();
|
||||
}
|
||||
|
||||
/**
|
||||
* Upgrades the ItemChannelLink database for the separation of {@code toHandlerScript} into
|
||||
* {@code commandFromItemScript} and {@code stateFromItemScript}.
|
||||
* See <a href="https://github.com/openhab/openhab-core/pull/4058">openhab/openhab-core#4058</a>.
|
||||
*/
|
||||
public void linkUpgradeScriptProfile() {
|
||||
if (!checkUpgradeRecord(LINK_UPGRADE_SCRIPT_PROFILE)) {
|
||||
return;
|
||||
}
|
||||
|
||||
Path linkJsonDatabasePath = Path.of(baseDir, "jsondb", "org.openhab.core.thing.link.ItemChannelLink.json");
|
||||
logger.info("Upgrading script profile configuration in database '{}'", linkJsonDatabasePath);
|
||||
|
||||
if (!Files.isWritable(linkJsonDatabasePath)) {
|
||||
logger.error("Cannot access link database '{}', check path and access rights.", linkJsonDatabasePath);
|
||||
return;
|
||||
}
|
||||
JsonStorage<ItemChannelLink> linkStorage = new JsonStorage<>(linkJsonDatabasePath.toFile(), null, 5, 0, 0,
|
||||
List.of());
|
||||
|
||||
List.copyOf(linkStorage.getKeys()).forEach(linkUid -> {
|
||||
ItemChannelLink link = Objects.requireNonNull(linkStorage.get(linkUid));
|
||||
Configuration configuration = link.getConfiguration();
|
||||
String profileName = (String) configuration.get(ItemChannelLinkConfigDescriptionProvider.PARAM_PROFILE);
|
||||
if (profileName != null && profileName.startsWith("transform:")) {
|
||||
String toHandlerScript = (String) configuration.get("toHandlerScript");
|
||||
if (toHandlerScript != null) {
|
||||
configuration.put("commandFromItemScript", toHandlerScript);
|
||||
configuration.remove("toHandlerScript");
|
||||
|
||||
linkStorage.put(linkUid, link);
|
||||
logger.info("{}: rewrote script profile link to new format", linkUid);
|
||||
} else {
|
||||
logger.info("{}: link already has correct configuration", linkUid);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
linkStorage.flush();
|
||||
upgradeRecords.put(LINK_UPGRADE_SCRIPT_PROFILE, new UpgradeRecord(ZonedDateTime.now()));
|
||||
upgradeRecords.flush();
|
||||
}
|
||||
|
||||
private static class UpgradeRecord {
|
||||
public final String executionDate;
|
||||
|
||||
public UpgradeRecord(ZonedDateTime executionDate) {
|
||||
this.executionDate = executionDate.toString();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,84 @@
|
|||
/*
|
||||
* Copyright (c) 2010-2025 Contributors to the openHAB project
|
||||
*
|
||||
* See the NOTICE file(s) distributed with this work for additional
|
||||
* information.
|
||||
*
|
||||
* This program and the accompanying materials are made available under the
|
||||
* terms of the Eclipse Public License 2.0 which is available at
|
||||
* http://www.eclipse.org/legal/epl-2.0
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*/
|
||||
package org.openhab.core.tools.internal;
|
||||
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
import org.openhab.core.config.core.Configuration;
|
||||
import org.openhab.core.storage.json.internal.JsonStorage;
|
||||
import org.openhab.core.thing.internal.link.ItemChannelLinkConfigDescriptionProvider;
|
||||
import org.openhab.core.thing.link.ItemChannelLink;
|
||||
import org.openhab.core.tools.Upgrader;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
/**
|
||||
* The {@link JSProfileUpgrader} upgrades JS Profile configurations
|
||||
*
|
||||
* @author Jan N. Klug - Initial contribution
|
||||
* @author Jimmy Tanagra - Refactored into a separate class
|
||||
*/
|
||||
@NonNullByDefault
|
||||
public class JSProfileUpgrader implements Upgrader {
|
||||
private final Logger logger = LoggerFactory.getLogger(JSProfileUpgrader.class);
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return "linkUpgradeJSProfile"; // keep the old name for backwards compatibility
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDescription() {
|
||||
return "Upgrade JS profile configuration to new format";
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean execute(String userdataDir, String confDir) {
|
||||
Path linkJsonDatabasePath = Path.of(userdataDir, "jsondb", "org.openhab.core.thing.link.ItemChannelLink.json");
|
||||
logger.info("Upgrading JS profile configuration in database '{}'", linkJsonDatabasePath);
|
||||
|
||||
if (!Files.isWritable(linkJsonDatabasePath)) {
|
||||
logger.error("Cannot access link database '{}', check path and access rights.", linkJsonDatabasePath);
|
||||
return false;
|
||||
}
|
||||
JsonStorage<ItemChannelLink> linkStorage = new JsonStorage<>(linkJsonDatabasePath.toFile(), null, 5, 0, 0,
|
||||
List.of());
|
||||
|
||||
List.copyOf(linkStorage.getKeys()).forEach(linkUid -> {
|
||||
ItemChannelLink link = Objects.requireNonNull(linkStorage.get(linkUid));
|
||||
Configuration configuration = link.getConfiguration();
|
||||
String profileName = (String) configuration.get(ItemChannelLinkConfigDescriptionProvider.PARAM_PROFILE);
|
||||
if ("transform:JS".equals(profileName)) {
|
||||
String function = (String) configuration.get("function");
|
||||
if (function != null) {
|
||||
configuration.put("toItemScript", function);
|
||||
configuration.put("toHandlerScript", "|input");
|
||||
configuration.remove("function");
|
||||
configuration.remove("sourceFormat");
|
||||
|
||||
linkStorage.put(linkUid, link);
|
||||
logger.info("{}: rewrote JS profile link to new format", linkUid);
|
||||
} else {
|
||||
logger.info("{}: link already has correct configuration", linkUid);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
linkStorage.flush();
|
||||
return true;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,85 @@
|
|||
/*
|
||||
* Copyright (c) 2010-2025 Contributors to the openHAB project
|
||||
*
|
||||
* See the NOTICE file(s) distributed with this work for additional
|
||||
* information.
|
||||
*
|
||||
* This program and the accompanying materials are made available under the
|
||||
* terms of the Eclipse Public License 2.0 which is available at
|
||||
* http://www.eclipse.org/legal/epl-2.0
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*/
|
||||
package org.openhab.core.tools.internal;
|
||||
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
import org.openhab.core.config.core.Configuration;
|
||||
import org.openhab.core.storage.json.internal.JsonStorage;
|
||||
import org.openhab.core.thing.internal.link.ItemChannelLinkConfigDescriptionProvider;
|
||||
import org.openhab.core.thing.link.ItemChannelLink;
|
||||
import org.openhab.core.tools.Upgrader;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
/**
|
||||
* The {@link ScriptProfileUpgrader} upgrades the ItemChannelLink database
|
||||
* for the separation of {@code toHandlerScript} into
|
||||
* {@code commandFromItemScript} and {@code stateFromItemScript}.
|
||||
* See <a href="https://github.com/openhab/openhab-core/pull/4058">openhab/openhab-core#4058</a>.
|
||||
*
|
||||
* @author Florian Hotze - Initial contribution
|
||||
* @author Jimmy Tanagra - Refactored into a separate class
|
||||
*/
|
||||
@NonNullByDefault
|
||||
public class ScriptProfileUpgrader implements Upgrader {
|
||||
private final Logger logger = LoggerFactory.getLogger(ScriptProfileUpgrader.class);
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return "linkUpgradeScriptProfile"; // keep the old name for backwards compatibility
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDescription() {
|
||||
return "Upgrade script profile configuration toHandlerScript to commandFromItemScript";
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean execute(String userdataDir, String confDir) {
|
||||
Path linkJsonDatabasePath = Path.of(userdataDir, "jsondb", "org.openhab.core.thing.link.ItemChannelLink.json");
|
||||
logger.info("Upgrading script profile configuration in database '{}'", linkJsonDatabasePath);
|
||||
|
||||
if (!Files.isWritable(linkJsonDatabasePath)) {
|
||||
logger.error("Cannot access link database '{}', check path and access rights.", linkJsonDatabasePath);
|
||||
return false;
|
||||
}
|
||||
JsonStorage<ItemChannelLink> linkStorage = new JsonStorage<>(linkJsonDatabasePath.toFile(), null, 5, 0, 0,
|
||||
List.of());
|
||||
|
||||
List.copyOf(linkStorage.getKeys()).forEach(linkUid -> {
|
||||
ItemChannelLink link = Objects.requireNonNull(linkStorage.get(linkUid));
|
||||
Configuration configuration = link.getConfiguration();
|
||||
String profileName = (String) configuration.get(ItemChannelLinkConfigDescriptionProvider.PARAM_PROFILE);
|
||||
if (profileName != null && profileName.startsWith("transform:")) {
|
||||
String toHandlerScript = (String) configuration.get("toHandlerScript");
|
||||
if (toHandlerScript != null) {
|
||||
configuration.put("commandFromItemScript", toHandlerScript);
|
||||
configuration.remove("toHandlerScript");
|
||||
|
||||
linkStorage.put(linkUid, link);
|
||||
logger.info("{}: rewrote script profile link to new format", linkUid);
|
||||
} else {
|
||||
logger.info("{}: link already has correct configuration", linkUid);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
linkStorage.flush();
|
||||
return true;
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue