Merge pull request #9665 from ShvaykaD/fix/version-update-for-nodes-with-valid-config
Force update of version for nodes with valid config and old configuration version
This commit is contained in:
commit
9128c7b7b4
@ -19,7 +19,6 @@ import lombok.RequiredArgsConstructor;
|
|||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
import org.thingsboard.common.util.JacksonUtil;
|
import org.thingsboard.common.util.JacksonUtil;
|
||||||
import org.thingsboard.rule.engine.api.TbNodeException;
|
|
||||||
import org.thingsboard.rule.engine.flow.TbRuleChainInputNode;
|
import org.thingsboard.rule.engine.flow.TbRuleChainInputNode;
|
||||||
import org.thingsboard.rule.engine.flow.TbRuleChainInputNodeConfiguration;
|
import org.thingsboard.rule.engine.flow.TbRuleChainInputNodeConfiguration;
|
||||||
import org.thingsboard.rule.engine.flow.TbRuleChainOutputNode;
|
import org.thingsboard.rule.engine.flow.TbRuleChainOutputNode;
|
||||||
@ -405,21 +404,16 @@ public class DefaultTbRuleChainService extends AbstractTbEntityService implement
|
|||||||
if (fromVersion < toVersion) {
|
if (fromVersion < toVersion) {
|
||||||
log.debug("Going to upgrade rule node with id: {} type: {} fromVersion: {} toVersion: {}",
|
log.debug("Going to upgrade rule node with id: {} type: {} fromVersion: {} toVersion: {}",
|
||||||
ruleNodeId, ruleNodeType, fromVersion, toVersion);
|
ruleNodeId, ruleNodeType, fromVersion, toVersion);
|
||||||
try {
|
|
||||||
TbNodeUpgradeUtils.upgradeConfigurationAndVersion(node, ruleNodeClass);
|
TbNodeUpgradeUtils.upgradeConfigurationAndVersion(node, ruleNodeClass);
|
||||||
log.debug("Successfully upgrade rule node with id: {} type: {}, rule chain id: {} fromVersion: {} toVersion: {}",
|
log.debug("Successfully upgrade rule node with id: {} type: {}, rule chain id: {} fromVersion: {} toVersion: {}",
|
||||||
ruleNodeId, ruleNodeType, ruleChainId, fromVersion, toVersion);
|
ruleNodeId, ruleNodeType, ruleChainId, fromVersion, toVersion);
|
||||||
} catch (TbNodeException e) {
|
|
||||||
log.warn("Failed to upgrade rule node with id: {} type: {} rule chain id: {} fromVersion: {} toVersion: {} due to: ",
|
|
||||||
ruleNodeId, ruleNodeType, ruleChainId, fromVersion, toVersion, e);
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
log.debug("Rule node with id: {} type: {} ruleChainId: {} already set to latest version!",
|
log.debug("Rule node with id: {} type: {} ruleChainId: {} already set to latest version!",
|
||||||
ruleNodeId, ruleChainId, ruleNodeType);
|
ruleNodeId, ruleChainId, ruleNodeType);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
log.error("Failed to update the rule node with id: {} type: {}, rule chain id: {}",
|
log.error("Failed to upgrade rule node with id: {} type: {}, rule chain id: {}",
|
||||||
ruleNodeId, ruleNodeType, ruleChainId, e);
|
ruleNodeId, ruleNodeType, ruleChainId, e);
|
||||||
}
|
}
|
||||||
return node;
|
return node;
|
||||||
|
|||||||
@ -16,27 +16,60 @@
|
|||||||
package org.thingsboard.server.utils;
|
package org.thingsboard.server.utils;
|
||||||
|
|
||||||
import com.fasterxml.jackson.databind.JsonNode;
|
import com.fasterxml.jackson.databind.JsonNode;
|
||||||
|
import lombok.SneakyThrows;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.thingsboard.common.util.JacksonUtil;
|
import org.thingsboard.common.util.JacksonUtil;
|
||||||
|
import org.thingsboard.rule.engine.api.NodeConfiguration;
|
||||||
import org.thingsboard.rule.engine.api.TbNode;
|
import org.thingsboard.rule.engine.api.TbNode;
|
||||||
import org.thingsboard.server.common.data.rule.RuleNode;
|
import org.thingsboard.server.common.data.rule.RuleNode;
|
||||||
import org.thingsboard.server.common.data.util.TbPair;
|
import org.thingsboard.server.common.data.util.TbPair;
|
||||||
import org.thingsboard.server.service.component.RuleNodeClassInfo;
|
import org.thingsboard.server.service.component.RuleNodeClassInfo;
|
||||||
|
|
||||||
|
@Slf4j
|
||||||
public class TbNodeUpgradeUtils {
|
public class TbNodeUpgradeUtils {
|
||||||
|
|
||||||
public static void upgradeConfigurationAndVersion(RuleNode node, RuleNodeClassInfo nodeInfo) throws Exception {
|
public static void upgradeConfigurationAndVersion(RuleNode node, RuleNodeClassInfo nodeInfo) {
|
||||||
JsonNode oldConfiguration = node.getConfiguration();
|
JsonNode oldConfiguration = node.getConfiguration();
|
||||||
if (oldConfiguration == null || !oldConfiguration.isObject()) {
|
int configurationVersion = node.getConfigurationVersion();
|
||||||
|
|
||||||
|
int currentVersion = nodeInfo.getCurrentVersion();
|
||||||
var configClass = nodeInfo.getAnnotation().configClazz();
|
var configClass = nodeInfo.getAnnotation().configClazz();
|
||||||
node.setConfiguration(JacksonUtil.valueToTree(configClass.getDeclaredConstructor().newInstance().defaultConfiguration()));
|
|
||||||
|
if (oldConfiguration == null || !oldConfiguration.isObject()) {
|
||||||
|
log.warn("Failed to upgrade rule node with id: {} type: {} fromVersion: {} toVersion: {}. " +
|
||||||
|
"Current configuration is null or not a json object. " +
|
||||||
|
"Going to set default configuration ... ",
|
||||||
|
node.getId(), node.getType(), configurationVersion, currentVersion);
|
||||||
|
node.setConfiguration(getDefaultConfig(configClass));
|
||||||
} else {
|
} else {
|
||||||
var tbVersionedNode = (TbNode) nodeInfo.getClazz().getDeclaredConstructor().newInstance();
|
var tbVersionedNode = getTbVersionedNode(nodeInfo);
|
||||||
TbPair<Boolean, JsonNode> upgradeResult = tbVersionedNode.upgrade(node.getConfigurationVersion(), oldConfiguration);
|
try {
|
||||||
|
TbPair<Boolean, JsonNode> upgradeResult = tbVersionedNode.upgrade(configurationVersion, oldConfiguration);
|
||||||
if (upgradeResult.getFirst()) {
|
if (upgradeResult.getFirst()) {
|
||||||
node.setConfiguration(upgradeResult.getSecond());
|
node.setConfiguration(upgradeResult.getSecond());
|
||||||
}
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
try {
|
||||||
|
JacksonUtil.treeToValue(oldConfiguration, configClass);
|
||||||
|
} catch (Exception ex) {
|
||||||
|
log.warn("Failed to upgrade rule node with id: {} type: {} fromVersion: {} toVersion: {}. " +
|
||||||
|
"Going to set default configuration ... ",
|
||||||
|
node.getId(), node.getType(), configurationVersion, currentVersion, e);
|
||||||
|
node.setConfiguration(getDefaultConfig(configClass));
|
||||||
}
|
}
|
||||||
node.setConfigurationVersion(nodeInfo.getCurrentVersion());
|
}
|
||||||
|
}
|
||||||
|
node.setConfigurationVersion(currentVersion);
|
||||||
|
}
|
||||||
|
|
||||||
|
@SneakyThrows
|
||||||
|
private static TbNode getTbVersionedNode(RuleNodeClassInfo nodeInfo) {
|
||||||
|
return (TbNode) nodeInfo.getClazz().getDeclaredConstructor().newInstance();
|
||||||
|
}
|
||||||
|
|
||||||
|
@SneakyThrows
|
||||||
|
private static JsonNode getDefaultConfig(Class<? extends NodeConfiguration> configClass) {
|
||||||
|
return JacksonUtil.valueToTree(configClass.getDeclaredConstructor().newInstance().defaultConfiguration());
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -21,6 +21,8 @@ import org.junit.Test;
|
|||||||
import org.thingsboard.common.util.JacksonUtil;
|
import org.thingsboard.common.util.JacksonUtil;
|
||||||
import org.thingsboard.rule.engine.metadata.TbGetAttributesNode;
|
import org.thingsboard.rule.engine.metadata.TbGetAttributesNode;
|
||||||
import org.thingsboard.rule.engine.metadata.TbGetAttributesNodeConfiguration;
|
import org.thingsboard.rule.engine.metadata.TbGetAttributesNodeConfiguration;
|
||||||
|
import org.thingsboard.rule.engine.metadata.TbGetCustomerAttributeNode;
|
||||||
|
import org.thingsboard.rule.engine.metadata.TbGetEntityDataNodeConfiguration;
|
||||||
import org.thingsboard.server.common.data.rule.RuleNode;
|
import org.thingsboard.server.common.data.rule.RuleNode;
|
||||||
import org.thingsboard.server.service.component.RuleNodeClassInfo;
|
import org.thingsboard.server.service.component.RuleNodeClassInfo;
|
||||||
|
|
||||||
@ -38,7 +40,7 @@ public class TbNodeUpgradeUtilsTest {
|
|||||||
var annotation = mock(org.thingsboard.rule.engine.api.RuleNode.class);
|
var annotation = mock(org.thingsboard.rule.engine.api.RuleNode.class);
|
||||||
var defaultConfig = JacksonUtil.valueToTree(nodeConfigClazz.getDeclaredConstructor().newInstance().defaultConfiguration());
|
var defaultConfig = JacksonUtil.valueToTree(nodeConfigClazz.getDeclaredConstructor().newInstance().defaultConfiguration());
|
||||||
|
|
||||||
when(nodeInfo.getClazz()).thenReturn((Class)TbGetAttributesNode.class);
|
when(nodeInfo.getClazz()).thenReturn((Class) TbGetAttributesNode.class);
|
||||||
when(nodeInfo.getCurrentVersion()).thenReturn(1);
|
when(nodeInfo.getCurrentVersion()).thenReturn(1);
|
||||||
when(nodeInfo.getAnnotation()).thenReturn(annotation);
|
when(nodeInfo.getAnnotation()).thenReturn(annotation);
|
||||||
when(annotation.configClazz()).thenReturn((Class) nodeConfigClazz);
|
when(annotation.configClazz()).thenReturn((Class) nodeConfigClazz);
|
||||||
@ -60,7 +62,7 @@ public class TbNodeUpgradeUtilsTest {
|
|||||||
var annotation = mock(org.thingsboard.rule.engine.api.RuleNode.class);
|
var annotation = mock(org.thingsboard.rule.engine.api.RuleNode.class);
|
||||||
var defaultConfig = JacksonUtil.valueToTree(nodeConfigClazz.getDeclaredConstructor().newInstance().defaultConfiguration());
|
var defaultConfig = JacksonUtil.valueToTree(nodeConfigClazz.getDeclaredConstructor().newInstance().defaultConfiguration());
|
||||||
|
|
||||||
when(nodeInfo.getClazz()).thenReturn((Class)TbGetAttributesNode.class);
|
when(nodeInfo.getClazz()).thenReturn((Class) TbGetAttributesNode.class);
|
||||||
when(nodeInfo.getCurrentVersion()).thenReturn(1);
|
when(nodeInfo.getCurrentVersion()).thenReturn(1);
|
||||||
when(nodeInfo.getAnnotation()).thenReturn(annotation);
|
when(nodeInfo.getAnnotation()).thenReturn(annotation);
|
||||||
when(annotation.configClazz()).thenReturn((Class) nodeConfigClazz);
|
when(annotation.configClazz()).thenReturn((Class) nodeConfigClazz);
|
||||||
@ -81,7 +83,7 @@ public class TbNodeUpgradeUtilsTest {
|
|||||||
var annotation = mock(org.thingsboard.rule.engine.api.RuleNode.class);
|
var annotation = mock(org.thingsboard.rule.engine.api.RuleNode.class);
|
||||||
var defaultConfig = JacksonUtil.valueToTree(nodeConfigClazz.getDeclaredConstructor().newInstance().defaultConfiguration());
|
var defaultConfig = JacksonUtil.valueToTree(nodeConfigClazz.getDeclaredConstructor().newInstance().defaultConfiguration());
|
||||||
|
|
||||||
when(nodeInfo.getClazz()).thenReturn((Class)TbGetAttributesNode.class);
|
when(nodeInfo.getClazz()).thenReturn((Class) TbGetAttributesNode.class);
|
||||||
when(nodeInfo.getCurrentVersion()).thenReturn(1);
|
when(nodeInfo.getCurrentVersion()).thenReturn(1);
|
||||||
when(nodeInfo.getAnnotation()).thenReturn(annotation);
|
when(nodeInfo.getAnnotation()).thenReturn(annotation);
|
||||||
when(annotation.configClazz()).thenReturn((Class) nodeConfigClazz);
|
when(annotation.configClazz()).thenReturn((Class) nodeConfigClazz);
|
||||||
@ -102,4 +104,55 @@ public class TbNodeUpgradeUtilsTest {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testUpgradeRuleNodeConfigurationWithNewConfigAndOldConfigVersion() throws Exception {
|
||||||
|
// GIVEN
|
||||||
|
var node = new RuleNode();
|
||||||
|
var nodeInfo = mock(RuleNodeClassInfo.class);
|
||||||
|
var nodeConfigClazz = TbGetEntityDataNodeConfiguration.class;
|
||||||
|
var annotation = mock(org.thingsboard.rule.engine.api.RuleNode.class);
|
||||||
|
var defaultConfig = JacksonUtil.valueToTree(nodeConfigClazz.getDeclaredConstructor().newInstance().defaultConfiguration());
|
||||||
|
|
||||||
|
when(nodeInfo.getClazz()).thenReturn((Class) TbGetCustomerAttributeNode.class);
|
||||||
|
when(nodeInfo.getCurrentVersion()).thenReturn(1);
|
||||||
|
when(nodeInfo.getAnnotation()).thenReturn(annotation);
|
||||||
|
when(annotation.configClazz()).thenReturn((Class) nodeConfigClazz);
|
||||||
|
|
||||||
|
String versionOneDefaultConfig = "{\"fetchTo\":\"METADATA\"," +
|
||||||
|
"\"dataMapping\":{\"alarmThreshold\":\"threshold\"}," +
|
||||||
|
"\"dataToFetch\":\"ATTRIBUTES\"}";
|
||||||
|
node.setConfiguration(JacksonUtil.toJsonNode(versionOneDefaultConfig));
|
||||||
|
// WHEN
|
||||||
|
TbNodeUpgradeUtils.upgradeConfigurationAndVersion(node, nodeInfo);
|
||||||
|
// THEN
|
||||||
|
Assertions.assertThat(node.getConfiguration()).isEqualTo(defaultConfig);
|
||||||
|
Assertions.assertThat(node.getConfigurationVersion()).isEqualTo(1);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testUpgradeRuleNodeConfigurationWithInvalidConfigAndOldConfigVersion() throws Exception {
|
||||||
|
// GIVEN
|
||||||
|
var node = new RuleNode();
|
||||||
|
var nodeInfo = mock(RuleNodeClassInfo.class);
|
||||||
|
var nodeConfigClazz = TbGetEntityDataNodeConfiguration.class;
|
||||||
|
var annotation = mock(org.thingsboard.rule.engine.api.RuleNode.class);
|
||||||
|
var defaultConfig = JacksonUtil.valueToTree(nodeConfigClazz.getDeclaredConstructor().newInstance().defaultConfiguration());
|
||||||
|
|
||||||
|
when(nodeInfo.getClazz()).thenReturn((Class) TbGetCustomerAttributeNode.class);
|
||||||
|
when(nodeInfo.getCurrentVersion()).thenReturn(1);
|
||||||
|
when(nodeInfo.getAnnotation()).thenReturn(annotation);
|
||||||
|
when(annotation.configClazz()).thenReturn((Class) nodeConfigClazz);
|
||||||
|
|
||||||
|
// missing telemetry field
|
||||||
|
String oldConfig = "{\"attrMapping\":{\"alarmThreshold\":\"threshold\"}}";;
|
||||||
|
node.setConfiguration(JacksonUtil.toJsonNode(oldConfig));
|
||||||
|
// WHEN
|
||||||
|
TbNodeUpgradeUtils.upgradeConfigurationAndVersion(node, nodeInfo);
|
||||||
|
// THEN
|
||||||
|
Assertions.assertThat(node.getConfiguration()).isEqualTo(defaultConfig);
|
||||||
|
Assertions.assertThat(node.getConfigurationVersion()).isEqualTo(1);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user