From cfcf539c5048ece226760f47aeb774f91c28271f Mon Sep 17 00:00:00 2001 From: ShvaykaD Date: Thu, 18 May 2023 18:55:00 +0300 Subject: [PATCH] added upgrade logic tests && added fixes for review comments --- .../server/ThingsboardInstallApplication.java | 1 + .../bean/AnnotationBeanDiscoveryService.java | 45 ++++++ .../service/bean/BeanDiscoveryService.java | 27 ++++ .../AnnotationComponentDiscoveryService.java | 23 +--- .../update/DefaultDataUpdateService.java | 128 ++++++++---------- .../controller/RuleChainControllerTest.java | 79 +++++++++++ .../server/dao/rule/BaseRuleChainService.java | 97 +++++++------ ...ersionedNode.java => TbVersionedNode.java} | 5 +- .../metadata/TbAbstractNodeWithFetchTo.java | 6 +- .../TbFetchDeviceCredentialsNode.java | 3 +- .../engine/metadata/TbGetAttributesNode.java | 3 +- .../metadata/TbGetCustomerAttributeNode.java | 3 +- .../metadata/TbGetCustomerDetailsNode.java | 3 +- .../engine/metadata/TbGetDeviceAttrNode.java | 3 +- .../metadata/TbGetOriginatorFieldsNode.java | 3 +- .../metadata/TbGetRelatedAttributeNode.java | 3 +- .../metadata/TbGetTenantAttributeNode.java | 3 +- .../metadata/TbGetTenantDetailsNode.java | 3 +- .../TbFetchDeviceCredentialsNodeTest.java | 14 +- .../metadata/TbGetAttributesNodeTest.java | 20 +++ .../TbGetCustomerAttributeNodeTest.java | 14 ++ .../TbGetCustomerDetailsNodeTest.java | 14 ++ .../metadata/TbGetDeviceAttrNodeTest.java | 45 ++++++ .../TbGetOriginatorFieldsNodeTest.java | 14 ++ .../TbGetRelatedAttributeNodeTest.java | 18 +++ .../TbGetTenantAttributeNodeTest.java | 14 ++ .../metadata/TbGetTenantDetailsNodeTest.java | 14 ++ .../rulechain/rulechain-page.component.ts | 2 + .../src/app/shared/models/rule-node.models.ts | 1 + 29 files changed, 451 insertions(+), 157 deletions(-) create mode 100644 application/src/main/java/org/thingsboard/server/service/bean/AnnotationBeanDiscoveryService.java create mode 100644 application/src/main/java/org/thingsboard/server/service/bean/BeanDiscoveryService.java rename rule-engine/rule-engine-api/src/main/java/org/thingsboard/rule/engine/api/{VersionedNode.java => TbVersionedNode.java} (77%) create mode 100644 rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/metadata/TbGetDeviceAttrNodeTest.java diff --git a/application/src/main/java/org/thingsboard/server/ThingsboardInstallApplication.java b/application/src/main/java/org/thingsboard/server/ThingsboardInstallApplication.java index b780f0e8cd..b99674f416 100644 --- a/application/src/main/java/org/thingsboard/server/ThingsboardInstallApplication.java +++ b/application/src/main/java/org/thingsboard/server/ThingsboardInstallApplication.java @@ -27,6 +27,7 @@ import java.util.Arrays; @Slf4j @SpringBootConfiguration @ComponentScan({"org.thingsboard.server.install", + "org.thingsboard.server.service.bean", "org.thingsboard.server.service.component", "org.thingsboard.server.service.install", "org.thingsboard.server.service.security.auth.jwt.settings", diff --git a/application/src/main/java/org/thingsboard/server/service/bean/AnnotationBeanDiscoveryService.java b/application/src/main/java/org/thingsboard/server/service/bean/AnnotationBeanDiscoveryService.java new file mode 100644 index 0000000000..3ee1c14540 --- /dev/null +++ b/application/src/main/java/org/thingsboard/server/service/bean/AnnotationBeanDiscoveryService.java @@ -0,0 +1,45 @@ +/** + * Copyright © 2016-2023 The Thingsboard Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.thingsboard.server.service.bean; + +import org.springframework.beans.factory.annotation.Value; +import org.springframework.beans.factory.config.BeanDefinition; +import org.springframework.context.annotation.ClassPathScanningCandidateComponentProvider; +import org.springframework.core.type.filter.AnnotationTypeFilter; +import org.springframework.stereotype.Service; + +import java.lang.annotation.Annotation; +import java.util.HashSet; +import java.util.Set; + +@Service +public class AnnotationBeanDiscoveryService implements BeanDiscoveryService { + + @Value("${plugins.scan_packages}") + private String[] scanPackages; + + @Override + public Set discoverBeansByAnnotationType(Class annotationType) { + ClassPathScanningCandidateComponentProvider scanner = new ClassPathScanningCandidateComponentProvider(false); + scanner.addIncludeFilter(new AnnotationTypeFilter(annotationType)); + Set defs = new HashSet<>(); + for (String scanPackage : scanPackages) { + defs.addAll(scanner.findCandidateComponents(scanPackage)); + } + return defs; + } + +} diff --git a/application/src/main/java/org/thingsboard/server/service/bean/BeanDiscoveryService.java b/application/src/main/java/org/thingsboard/server/service/bean/BeanDiscoveryService.java new file mode 100644 index 0000000000..5ca615a94d --- /dev/null +++ b/application/src/main/java/org/thingsboard/server/service/bean/BeanDiscoveryService.java @@ -0,0 +1,27 @@ +/** + * Copyright © 2016-2023 The Thingsboard Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.thingsboard.server.service.bean; + +import org.springframework.beans.factory.config.BeanDefinition; + +import java.lang.annotation.Annotation; +import java.util.Set; + +public interface BeanDiscoveryService { + + Set discoverBeansByAnnotationType(Class annotationType); + +} diff --git a/application/src/main/java/org/thingsboard/server/service/component/AnnotationComponentDiscoveryService.java b/application/src/main/java/org/thingsboard/server/service/component/AnnotationComponentDiscoveryService.java index b425694e81..d4c6e7a18c 100644 --- a/application/src/main/java/org/thingsboard/server/service/component/AnnotationComponentDiscoveryService.java +++ b/application/src/main/java/org/thingsboard/server/service/component/AnnotationComponentDiscoveryService.java @@ -20,12 +20,9 @@ import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.node.ObjectNode; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.beans.factory.annotation.Value; import org.springframework.beans.factory.config.BeanDefinition; -import org.springframework.context.annotation.ClassPathScanningCandidateComponentProvider; import org.springframework.core.env.Environment; import org.springframework.core.env.Profiles; -import org.springframework.core.type.filter.AnnotationTypeFilter; import org.springframework.stereotype.Service; import org.thingsboard.rule.engine.api.NodeConfiguration; import org.thingsboard.rule.engine.api.NodeDefinition; @@ -36,14 +33,13 @@ import org.thingsboard.server.common.data.plugin.ComponentDescriptor; import org.thingsboard.server.common.data.plugin.ComponentType; import org.thingsboard.server.common.data.rule.RuleChainType; import org.thingsboard.server.dao.component.ComponentDescriptorService; +import org.thingsboard.server.service.bean.BeanDiscoveryService; import javax.annotation.PostConstruct; -import java.lang.annotation.Annotation; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.HashMap; -import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Optional; @@ -54,12 +50,13 @@ import java.util.Set; public class AnnotationComponentDiscoveryService implements ComponentDiscoveryService { public static final int MAX_OPTIMISITC_RETRIES = 3; - @Value("${plugins.scan_packages}") - private String[] scanPackages; @Autowired private Environment environment; + @Autowired(required = false) + private BeanDiscoveryService beanDiscoveryService; + @Autowired private ComponentDescriptorService componentDescriptorService; @@ -83,7 +80,7 @@ public class AnnotationComponentDiscoveryService implements ComponentDiscoverySe } private void registerRuleNodeComponents() { - Set ruleNodeBeanDefinitions = getBeanDefinitions(RuleNode.class); + Set ruleNodeBeanDefinitions = beanDiscoveryService.discoverBeansByAnnotationType(RuleNode.class); for (BeanDefinition def : ruleNodeBeanDefinitions) { int retryCount = 0; Exception cause = null; @@ -212,16 +209,6 @@ public class AnnotationComponentDiscoveryService implements ComponentDiscoverySe return relationTypes.toArray(new String[relationTypes.size()]); } - private Set getBeanDefinitions(Class componentType) { - ClassPathScanningCandidateComponentProvider scanner = new ClassPathScanningCandidateComponentProvider(false); - scanner.addIncludeFilter(new AnnotationTypeFilter(componentType)); - Set defs = new HashSet<>(); - for (String scanPackage : scanPackages) { - defs.addAll(scanner.findCandidateComponents(scanPackage)); - } - return defs; - } - @Override public void discoverComponents() { registerRuleNodeComponents(); diff --git a/application/src/main/java/org/thingsboard/server/service/install/update/DefaultDataUpdateService.java b/application/src/main/java/org/thingsboard/server/service/install/update/DefaultDataUpdateService.java index 0334730e2d..c896e10dc3 100644 --- a/application/src/main/java/org/thingsboard/server/service/install/update/DefaultDataUpdateService.java +++ b/application/src/main/java/org/thingsboard/server/service/install/update/DefaultDataUpdateService.java @@ -17,22 +17,18 @@ package org.thingsboard.server.service.install.update; import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.node.ObjectNode; +import com.google.common.collect.Iterables; import com.google.common.util.concurrent.Futures; import com.google.common.util.concurrent.ListenableFuture; import com.google.common.util.concurrent.MoreExecutors; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.beans.factory.annotation.Value; -import org.springframework.beans.factory.config.BeanDefinition; -import org.springframework.context.annotation.ClassPathScanningCandidateComponentProvider; import org.springframework.context.annotation.Lazy; import org.springframework.context.annotation.Profile; -import org.springframework.core.type.filter.AnnotationTypeFilter; import org.springframework.stereotype.Service; import org.thingsboard.common.util.JacksonUtil; -import org.thingsboard.rule.engine.api.TbNode; import org.thingsboard.rule.engine.api.TbNodeException; -import org.thingsboard.rule.engine.api.VersionedNode; +import org.thingsboard.rule.engine.api.TbVersionedNode; import org.thingsboard.rule.engine.flow.TbRuleChainInputNode; import org.thingsboard.rule.engine.flow.TbRuleChainInputNodeConfiguration; import org.thingsboard.rule.engine.profile.TbDeviceProfileNode; @@ -86,17 +82,14 @@ import org.thingsboard.server.dao.sql.device.DeviceProfileRepository; import org.thingsboard.server.dao.tenant.TenantProfileService; import org.thingsboard.server.dao.tenant.TenantService; import org.thingsboard.server.dao.timeseries.TimeseriesService; +import org.thingsboard.server.service.bean.BeanDiscoveryService; import org.thingsboard.server.service.install.InstallScripts; import org.thingsboard.server.service.install.SystemDataLoaderService; -import org.thingsboard.server.service.install.TbRuleEngineQueueConfigService; -import java.lang.annotation.Annotation; +import java.lang.reflect.InvocationTargetException; import java.util.ArrayList; import java.util.Collections; -import java.util.HashMap; -import java.util.HashSet; import java.util.List; -import java.util.Set; import java.util.concurrent.ExecutionException; import java.util.concurrent.atomic.AtomicLong; import java.util.stream.Collectors; @@ -108,9 +101,6 @@ import static org.thingsboard.server.common.data.StringUtils.isBlank; @Slf4j public class DefaultDataUpdateService implements DataUpdateService { - @Value("${plugins.scan_packages}") - private String[] scanPackages; - @Autowired private TenantService tenantService; @@ -149,7 +139,7 @@ public class DefaultDataUpdateService implements DataUpdateService { private QueueService queueService; @Autowired - private TbRuleEngineQueueConfigService queueConfig; + private BeanDiscoveryService beanDiscoveryService; @Autowired private SystemDataLoaderService systemDataLoaderService; @@ -229,57 +219,54 @@ public class DefaultDataUpdateService implements DataUpdateService { } private void upgradeRuleNodes() { - var ruleChainIdToTenantIdMap = new HashMap(); try { - log.info("Starting rule nodes upgrade ..."); - var ruleNodeDefinitions = getBeanDefinitions( - org.thingsboard.rule.engine.api.RuleNode.class - ); - for (BeanDefinition def : ruleNodeDefinitions) { - String clazzName = def.getBeanClassName(); - Class clazz = Class.forName(clazzName); - TbNode tbNode = (TbNode) clazz.getDeclaredConstructor().newInstance(); - if (tbNode instanceof VersionedNode) { - var versionedNode = (VersionedNode) tbNode; - var ruleNodeName = versionedNode.getClass().getName(); - int currentVersion = versionedNode.getCurrentVersion(); - var ruleNodesToUpdate = new PageDataIterable<>( - pageLink -> - ruleChainService.findAllRuleNodesByTypeAndVersionLessThan(ruleNodeName, currentVersion, pageLink), - 1024 - ); + log.info("Lookup rule nodes to upgrade ..."); + ArrayList tbVersionedNodes = getTbVersionedNodes(); + log.info("Found {} versioned nodes to check for upgrade!", tbVersionedNodes.size()); + for (TbVersionedNode tbVersionedNode : tbVersionedNodes) { + String ruleNodeType = tbVersionedNode.getClass().getName(); + String ruleNodeTypeForLogs = tbVersionedNode.getClass().getSimpleName(); + int toVersion = tbVersionedNode.getCurrentVersion(); + log.info("Going to check for nodes with type: {} to upgrade to version: {}.", ruleNodeTypeForLogs, toVersion); + var ruleNodesToUpdate = new PageDataIterable<>( + pageLink -> + ruleChainService.findAllRuleNodesByTypeAndVersionLessThan( + ruleNodeType, + toVersion, + pageLink + ), + 1024 + ); + if (Iterables.isEmpty(ruleNodesToUpdate)) { + log.info("There are no active nodes with type: {}, or all nodes with this type already set to latest version!", ruleNodeTypeForLogs); + } else { for (RuleNode ruleNode : ruleNodesToUpdate) { RuleNodeId ruleNodeId = ruleNode.getId(); var oldConfiguration = ruleNode.getConfiguration(); int fromVersion = ruleNode.getConfigurationVersion(); log.info("Going to upgrade rule node with id: {} type: {} fromVersion: {} toVersion: {}", ruleNodeId, - clazzName, + ruleNodeTypeForLogs, fromVersion, - currentVersion); + toVersion); try { - TbPair upgradeRuleNodeConfigurationResult = versionedNode.upgrade(ruleNodeId, fromVersion, oldConfiguration); + TbPair upgradeRuleNodeConfigurationResult = tbVersionedNode.upgrade(fromVersion, oldConfiguration); if (upgradeRuleNodeConfigurationResult.getFirst()) { ruleNode.setConfiguration(upgradeRuleNodeConfigurationResult.getSecond()); - var ruleChainId = ruleNode.getRuleChainId(); - var tenantId = getTenantId(ruleChainIdToTenantIdMap, ruleNodeId, ruleChainId); - if (tenantId == null) { - log.warn("Failed to find tenant id for rule chain with id: {}", ruleChainId); - continue; - } - ruleChainService.saveRuleNode(tenantId, ruleNode); - log.info("Successfully upgrade rule node with id: {} type: {} fromVersion: {} toVersion: {}", - ruleNodeId, - clazzName, - fromVersion, - currentVersion); } + ruleNode.setConfigurationVersion(toVersion); + ruleChainService.saveRuleNode(TenantId.SYS_TENANT_ID, ruleNode); + log.info("Successfully upgrade rule node with id: {} type: {} fromVersion: {} toVersion: {}", + ruleNodeId, + ruleNodeTypeForLogs, + fromVersion, + toVersion); } catch (TbNodeException e) { log.warn("Failed to upgrade rule node with id: {} type: {} fromVersion: {} toVersion: {} due to: ", ruleNodeId, - clazzName, + ruleNodeTypeForLogs, fromVersion, - currentVersion, + toVersion, e); } } @@ -290,27 +277,28 @@ public class DefaultDataUpdateService implements DataUpdateService { log.error("Unexpected error during rule nodes upgrade: ", e); } } - - private TenantId getTenantId(HashMap ruleChainIdToTenantId, RuleNodeId ruleNodeId, RuleChainId ruleChainId) { - return ruleChainIdToTenantId.computeIfAbsent(ruleChainId, - id -> { - RuleChain ruleChain = ruleChainService.findRuleChainById(TenantId.SYS_TENANT_ID, id); - if (ruleChain == null) { - log.warn("Failed to find rule chain by id: {} ruleNodeId: {}", ruleChainId, ruleNodeId); - return null; - } - return ruleChain.getTenantId(); - }); - } - - private Set getBeanDefinitions(Class componentType) { - ClassPathScanningCandidateComponentProvider scanner = new ClassPathScanningCandidateComponentProvider(false); - scanner.addIncludeFilter(new AnnotationTypeFilter(componentType)); - Set defs = new HashSet<>(); - for (String scanPackage : scanPackages) { - defs.addAll(scanner.findCandidateComponents(scanPackage)); + private ArrayList getTbVersionedNodes() { + var ruleNodeDefinitions = beanDiscoveryService.discoverBeansByAnnotationType( + org.thingsboard.rule.engine.api.RuleNode.class + ); + var tbVersionedNodes = new ArrayList(); + for (var def : ruleNodeDefinitions) { + String clazzName = def.getBeanClassName(); + try { + var clazz = Class.forName(clazzName); + if (TbVersionedNode.class.isAssignableFrom(clazz)) { + tbVersionedNodes.add((TbVersionedNode) clazz.getDeclaredConstructor().newInstance()); + } + } catch (NoSuchMethodException | + InstantiationException | + IllegalAccessException | + InvocationTargetException | + ClassNotFoundException e + ) { + log.warn("Failed to create instance of rule node type: {} due to: ", clazzName, e); + } } - return defs; + return tbVersionedNodes; } private final PaginatedUpdater deviceProfileEntityDynamicConditionsUpdater = diff --git a/application/src/test/java/org/thingsboard/server/controller/RuleChainControllerTest.java b/application/src/test/java/org/thingsboard/server/controller/RuleChainControllerTest.java index 16a266e485..eb989ac5b6 100644 --- a/application/src/test/java/org/thingsboard/server/controller/RuleChainControllerTest.java +++ b/application/src/test/java/org/thingsboard/server/controller/RuleChainControllerTest.java @@ -27,8 +27,11 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Primary; import org.springframework.test.context.ContextConfiguration; +import org.thingsboard.common.util.JacksonUtil; import org.thingsboard.rule.engine.action.TbCreateAlarmNode; import org.thingsboard.rule.engine.action.TbCreateAlarmNodeConfiguration; +import org.thingsboard.rule.engine.api.TbVersionedNode; +import org.thingsboard.rule.engine.metadata.TbGetRelatedAttributeNode; import org.thingsboard.server.common.data.StringUtils; import org.thingsboard.server.common.data.Tenant; import org.thingsboard.server.common.data.User; @@ -128,6 +131,82 @@ public class RuleChainControllerTest extends AbstractControllerTest { ActionType.UPDATED); } + @Test + public void testSaveRuleChainMetadataWithVersionedNodes() throws Exception { + RuleChain ruleChain = new RuleChain(); + ruleChain.setName("RuleChain"); + + RuleChain savedRuleChain = doPost("/api/ruleChain", ruleChain, RuleChain.class); + Assert.assertNotNull(savedRuleChain); + RuleChainId ruleChainId = savedRuleChain.getId(); + Assert.assertNotNull(ruleChainId); + Assert.assertTrue(savedRuleChain.getCreatedTime() > 0); + Assert.assertEquals(ruleChain.getName(), savedRuleChain.getName()); + + TbVersionedNode tbVersionedNode = new TbGetRelatedAttributeNode(); + String ruleNodeType = tbVersionedNode.getClass().getName(); + int currentVersion = tbVersionedNode.getCurrentVersion(); + + String oldConfig = "{\"attrMapping\":{\"serialNumber\":\"sn\"}," + + "\"relationsQuery\":{\"direction\":\"FROM\",\"maxLevel\":1," + + "\"filters\":[{\"relationType\":\"Contains\",\"entityTypes\":[]}]," + + "\"fetchLastLevelOnly\":false},\"telemetry\":false}"; + + String newConfig = "{\"fetchTo\":\"METADATA\"," + + "\"attrMapping\":{\"serialNumber\":\"sn\"}," + + "\"dataToFetch\":\"ATTRIBUTES\"," + + "\"relationsQuery\":{\"direction\":\"FROM\",\"maxLevel\":1," + + "\"filters\":[{\"relationType\":\"Contains\",\"entityTypes\":[]}]," + + "\"fetchLastLevelOnly\":false}}"; + + var ruleChainMetaData = createRuleChainMetadataWithTbVersionedNodes( + ruleChainId, + ruleNodeType, + currentVersion, + oldConfig, + newConfig + ); + var savedRuleChainMetaData = doPost("/api/ruleChain/metadata", ruleChainMetaData, RuleChainMetaData.class); + + Assert.assertEquals(ruleChainId, savedRuleChainMetaData.getRuleChainId()); + Assert.assertEquals(2, savedRuleChainMetaData.getNodes().size()); + + for (RuleNode ruleNode : savedRuleChainMetaData.getNodes()) { + Assert.assertNotNull(ruleNode.getId()); + Assert.assertEquals(currentVersion, ruleNode.getConfigurationVersion()); + Assert.assertEquals(JacksonUtil.toJsonNode(newConfig), ruleNode.getConfiguration()); + } + } + + private RuleChainMetaData createRuleChainMetadataWithTbVersionedNodes( + RuleChainId ruleChainId, + String ruleNodeType, + int currentVersion, + String oldConfig, + String newConfig + ) { + RuleChainMetaData ruleChainMetaData = new RuleChainMetaData(); + ruleChainMetaData.setRuleChainId(ruleChainId); + + var ruleNodeWithOldConfig = new RuleNode(); + ruleNodeWithOldConfig.setName("Old Rule Node"); + ruleNodeWithOldConfig.setType(ruleNodeType); + ruleNodeWithOldConfig.setConfiguration(JacksonUtil.toJsonNode(oldConfig)); + + var ruleNodeWithNewConfig = new RuleNode(); + ruleNodeWithNewConfig.setName("New Rule Node"); + ruleNodeWithNewConfig.setType(ruleNodeType); + ruleNodeWithNewConfig.setConfigurationVersion(currentVersion); + ruleNodeWithNewConfig.setConfiguration(JacksonUtil.toJsonNode(newConfig)); + + List ruleNodes = new ArrayList<>(); + ruleNodes.add(ruleNodeWithOldConfig); + ruleNodes.add(ruleNodeWithNewConfig); + ruleChainMetaData.setFirstNodeIndex(0); + ruleChainMetaData.setNodes(ruleNodes); + return ruleChainMetaData; + } + @Test public void testSaveRuleChainWithViolationOfLengthValidation() throws Exception { diff --git a/dao/src/main/java/org/thingsboard/server/dao/rule/BaseRuleChainService.java b/dao/src/main/java/org/thingsboard/server/dao/rule/BaseRuleChainService.java index 601b6d333e..4cf96dfa0d 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/rule/BaseRuleChainService.java +++ b/dao/src/main/java/org/thingsboard/server/dao/rule/BaseRuleChainService.java @@ -28,7 +28,7 @@ import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import org.thingsboard.common.util.JacksonUtil; import org.thingsboard.rule.engine.api.TbNodeException; -import org.thingsboard.rule.engine.api.VersionedNode; +import org.thingsboard.rule.engine.api.TbVersionedNode; import org.thingsboard.server.common.data.BaseData; import org.thingsboard.server.common.data.EntityType; import org.thingsboard.server.common.data.edge.Edge; @@ -185,17 +185,62 @@ public class BaseRuleChainService extends AbstractEntityService implements RuleC } updatedRuleNodes.add(new RuleNodeUpdateResult(existingNode, newRuleNode)); } + RuleChainId ruleChainId = ruleChain.getId(); if (nodes != null) { for (RuleNode node : toAddOrUpdate) { - node.setRuleChainId(ruleChain.getId()); + node.setRuleChainId(ruleChainId); + String ruleNodeType = node.getType(); + RuleNodeId ruleNodeId = node.getId(); + try { + var ruleNodeClazz = Class.forName(ruleNodeType); + if (TbVersionedNode.class.isAssignableFrom(ruleNodeClazz)) { + TbVersionedNode tbVersionedNode = (TbVersionedNode) ruleNodeClazz.getDeclaredConstructor().newInstance(); + int fromVersion = node.getConfigurationVersion(); + int toVersion = tbVersionedNode.getCurrentVersion(); + if (fromVersion < toVersion) { + log.debug("Going to upgrade rule node with id: {} type: {} fromVersion: {} toVersion: {}", + ruleNodeId, + ruleNodeType, + fromVersion, + toVersion); + try { + TbPair upgradeResult = tbVersionedNode.upgrade(fromVersion, node.getConfiguration()); + if (upgradeResult.getFirst()) { + node.setConfiguration(upgradeResult.getSecond()); + log.info("Successfully upgrade rule node with id: {} type: {}, rule chain id: {} fromVersion: {} toVersion: {}", + ruleNodeId, + ruleNodeType, + ruleChainId, + fromVersion, + toVersion); + } + node.setConfigurationVersion(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 { + log.debug("Rule node with id: {} type: {} ruleChainId: {} already set to latest version!", + ruleNodeId, + ruleChainId, + ruleNodeType); + } + } + } catch (ClassNotFoundException | + InvocationTargetException | + InstantiationException | + IllegalAccessException | + NoSuchMethodException e) { + log.error("Failed to create instance of rule node with id: {} type: {}, rule chain id: {}", ruleNodeId, ruleNodeType, ruleChainId); + } RuleNode savedNode = ruleNodeDao.save(tenantId, node); relations.add(new EntityRelation(ruleChainMetaData.getRuleChainId(), savedNode.getId(), EntityRelation.CONTAINS_TYPE, RelationTypeGroup.RULE_CHAIN)); -// TbPair upgradeResult = upgradeRuleNode(savedNode); -// if (upgradeResult.getFirst()) { -// savedNode.setConfiguration(upgradeResult.getSecond()); -// savedNode = ruleNodeDao.save(tenantId, savedNode); -// } int index = nodes.indexOf(node); nodes.set(index, savedNode); ruleNodeIndexMap.put(savedNode.getId(), index); @@ -228,7 +273,7 @@ public class BaseRuleChainService extends AbstractEntityService implements RuleC RuleChain targetRuleChain = findRuleChainById(TenantId.SYS_TENANT_ID, targetRuleChainId); RuleNode targetNode = new RuleNode(); targetNode.setName(targetRuleChain != null ? targetRuleChain.getName() : "Rule Chain Input"); - targetNode.setRuleChainId(ruleChain.getId()); + targetNode.setRuleChainId(ruleChainId); targetNode.setType("org.thingsboard.rule.engine.flow.TbRuleChainInputNode"); var configuration = JacksonUtil.newObjectNode(); configuration.put("ruleChainId", targetRuleChainId.getId().toString()); @@ -241,7 +286,7 @@ public class BaseRuleChainService extends AbstractEntityService implements RuleC targetNode = ruleNodeDao.save(tenantId, targetNode); EntityRelation sourceRuleChainToRuleNode = new EntityRelation(); - sourceRuleChainToRuleNode.setFrom(ruleChain.getId()); + sourceRuleChainToRuleNode.setFrom(ruleChainId); sourceRuleChainToRuleNode.setTo(targetNode.getId()); sourceRuleChainToRuleNode.setType(EntityRelation.CONTAINS_TYPE); sourceRuleChainToRuleNode.setTypeGroup(RelationTypeGroup.RULE_CHAIN); @@ -265,40 +310,6 @@ public class BaseRuleChainService extends AbstractEntityService implements RuleC return RuleChainUpdateResult.successful(updatedRuleNodes); } - private TbPair upgradeRuleNode(RuleNode ruleNode) { - RuleNodeId ruleNodeId = ruleNode.getId(); - String ruleNodeType = ruleNode.getType(); - int fromVersion = ruleNode.getConfigurationVersion(); - try { - var ruleNodeClass = Class.forName(ruleNodeType).getDeclaredConstructor().newInstance(); - if (ruleNodeClass instanceof VersionedNode) { - VersionedNode versionedNode = (VersionedNode) ruleNodeClass; - int toVersion = versionedNode.getCurrentVersion(); - log.info("Going to upgrade rule node with id: {} type: {} fromVersion: {} toVersion: {}", - ruleNodeId, - ruleNodeType, - fromVersion, - toVersion); - try { - return versionedNode.upgrade(ruleNodeId, fromVersion, ruleNode.getConfiguration()); - } catch (TbNodeException e) { - log.warn("Failed to upgrade rule node with id: {} fromVersion: {} toVersion: {} due to: ", - ruleNodeId, - fromVersion, - toVersion, - e); - } - } - } catch (ClassNotFoundException | - InvocationTargetException | - InstantiationException | - IllegalAccessException | - NoSuchMethodException e) { - log.warn("Failed to create instance of rule node with id: {} and type: {}", ruleNodeId, ruleNodeType); - } - return new TbPair<>(false, ruleNode.getConfiguration()); - } - @Override public RuleChainMetaData loadRuleChainMetaData(TenantId tenantId, RuleChainId ruleChainId) { Validator.validateId(ruleChainId, "Incorrect rule chain id."); diff --git a/rule-engine/rule-engine-api/src/main/java/org/thingsboard/rule/engine/api/VersionedNode.java b/rule-engine/rule-engine-api/src/main/java/org/thingsboard/rule/engine/api/TbVersionedNode.java similarity index 77% rename from rule-engine/rule-engine-api/src/main/java/org/thingsboard/rule/engine/api/VersionedNode.java rename to rule-engine/rule-engine-api/src/main/java/org/thingsboard/rule/engine/api/TbVersionedNode.java index 2c442588eb..ce9a63111b 100644 --- a/rule-engine/rule-engine-api/src/main/java/org/thingsboard/rule/engine/api/VersionedNode.java +++ b/rule-engine/rule-engine-api/src/main/java/org/thingsboard/rule/engine/api/TbVersionedNode.java @@ -16,12 +16,11 @@ package org.thingsboard.rule.engine.api; import com.fasterxml.jackson.databind.JsonNode; -import org.thingsboard.server.common.data.id.RuleNodeId; import org.thingsboard.server.common.data.util.TbPair; -public interface VersionedNode extends TbNode { +public interface TbVersionedNode extends TbNode { - TbPair upgrade(RuleNodeId ruleNodeId, int fromVersion, JsonNode oldConfiguration) throws TbNodeException; + TbPair upgrade(int fromVersion, JsonNode oldConfiguration) throws TbNodeException; int getCurrentVersion(); diff --git a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbAbstractNodeWithFetchTo.java b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbAbstractNodeWithFetchTo.java index ebf99765b5..924092ad87 100644 --- a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbAbstractNodeWithFetchTo.java +++ b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbAbstractNodeWithFetchTo.java @@ -22,12 +22,10 @@ import com.google.common.util.concurrent.Futures; import lombok.extern.slf4j.Slf4j; import org.thingsboard.common.util.JacksonUtil; import org.thingsboard.rule.engine.api.TbContext; -import org.thingsboard.rule.engine.api.TbNode; import org.thingsboard.rule.engine.api.TbNodeConfiguration; import org.thingsboard.rule.engine.api.TbNodeException; -import org.thingsboard.rule.engine.api.VersionedNode; +import org.thingsboard.rule.engine.api.TbVersionedNode; import org.thingsboard.server.common.data.id.EntityId; -import org.thingsboard.server.common.data.id.RuleNodeId; import org.thingsboard.server.common.data.kv.KvEntry; import org.thingsboard.server.common.data.util.TbPair; import org.thingsboard.server.common.msg.TbMsg; @@ -36,7 +34,7 @@ import org.thingsboard.server.common.msg.TbMsgMetaData; import java.util.NoSuchElementException; @Slf4j -public abstract class TbAbstractNodeWithFetchTo implements VersionedNode { +public abstract class TbAbstractNodeWithFetchTo implements TbVersionedNode { protected final static String FETCH_TO_PROPERTY_NAME = "fetchTo"; diff --git a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbFetchDeviceCredentialsNode.java b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbFetchDeviceCredentialsNode.java index 2d9804b8d8..ec21706ff1 100644 --- a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbFetchDeviceCredentialsNode.java +++ b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbFetchDeviceCredentialsNode.java @@ -25,7 +25,6 @@ import org.thingsboard.rule.engine.api.TbNodeException; import org.thingsboard.rule.engine.api.util.TbNodeUtils; import org.thingsboard.server.common.data.EntityType; import org.thingsboard.server.common.data.id.DeviceId; -import org.thingsboard.server.common.data.id.RuleNodeId; import org.thingsboard.server.common.data.plugin.ComponentType; import org.thingsboard.server.common.data.security.DeviceCredentialsType; import org.thingsboard.server.common.data.util.TbPair; @@ -89,7 +88,7 @@ public class TbFetchDeviceCredentialsNode extends TbAbstractNodeWithFetchTo upgrade(RuleNodeId ruleNodeId, int fromVersion, JsonNode oldConfiguration) throws TbNodeException { + public TbPair upgrade(int fromVersion, JsonNode oldConfiguration) throws TbNodeException { return fromVersion == 0 ? upgradeRuleNodesWithOldPropertyToUseFetchTo( oldConfiguration, diff --git a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetAttributesNode.java b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetAttributesNode.java index 8281db6a26..2d1f02acf8 100644 --- a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetAttributesNode.java +++ b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetAttributesNode.java @@ -25,7 +25,6 @@ import org.thingsboard.rule.engine.api.TbNodeConfiguration; import org.thingsboard.rule.engine.api.TbNodeException; import org.thingsboard.rule.engine.api.util.TbNodeUtils; import org.thingsboard.server.common.data.id.EntityId; -import org.thingsboard.server.common.data.id.RuleNodeId; import org.thingsboard.server.common.data.plugin.ComponentType; import org.thingsboard.server.common.data.util.TbPair; import org.thingsboard.server.common.msg.TbMsg; @@ -57,7 +56,7 @@ public class TbGetAttributesNode extends TbAbstractGetAttributesNode upgrade(RuleNodeId ruleNodeId, int fromVersion, JsonNode oldConfiguration) throws TbNodeException { + public TbPair upgrade(int fromVersion, JsonNode oldConfiguration) throws TbNodeException { return fromVersion == 0 ? upgradeRuleNodesWithOldPropertyToUseFetchTo( oldConfiguration, diff --git a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetCustomerAttributeNode.java b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetCustomerAttributeNode.java index eaf197c6a5..f9cbba2ffd 100644 --- a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetCustomerAttributeNode.java +++ b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetCustomerAttributeNode.java @@ -27,7 +27,6 @@ import org.thingsboard.rule.engine.api.util.TbNodeUtils; import org.thingsboard.rule.engine.util.EntitiesCustomerIdAsyncLoader; import org.thingsboard.server.common.data.id.CustomerId; import org.thingsboard.server.common.data.id.EntityId; -import org.thingsboard.server.common.data.id.RuleNodeId; import org.thingsboard.server.common.data.plugin.ComponentType; import org.thingsboard.server.common.data.util.TbPair; @@ -72,7 +71,7 @@ public class TbGetCustomerAttributeNode extends TbAbstractGetEntityAttrNode upgrade(RuleNodeId ruleNodeId, int fromVersion, JsonNode oldConfiguration) throws TbNodeException { + public TbPair upgrade(int fromVersion, JsonNode oldConfiguration) throws TbNodeException { return fromVersion == 0 ? upgradeToUseFetchToAndDataToFetch(oldConfiguration) : new TbPair<>(false, oldConfiguration); diff --git a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetCustomerDetailsNode.java b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetCustomerDetailsNode.java index aff1f3b00e..c31f9cbcef 100644 --- a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetCustomerDetailsNode.java +++ b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetCustomerDetailsNode.java @@ -33,7 +33,6 @@ import org.thingsboard.server.common.data.id.DeviceId; import org.thingsboard.server.common.data.id.EdgeId; import org.thingsboard.server.common.data.id.EntityId; import org.thingsboard.server.common.data.id.EntityViewId; -import org.thingsboard.server.common.data.id.RuleNodeId; import org.thingsboard.server.common.data.id.UserId; import org.thingsboard.server.common.data.plugin.ComponentType; import org.thingsboard.server.common.data.util.TbPair; @@ -107,7 +106,7 @@ public class TbGetCustomerDetailsNode extends TbAbstractGetEntityDetailsNode upgrade(RuleNodeId ruleNodeId, int fromVersion, JsonNode oldConfiguration) throws TbNodeException { + public TbPair upgrade(int fromVersion, JsonNode oldConfiguration) throws TbNodeException { return fromVersion == 0 ? upgradeRuleNodesWithOldPropertyToUseFetchTo( oldConfiguration, diff --git a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetDeviceAttrNode.java b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetDeviceAttrNode.java index d47f8445b4..d671a61536 100644 --- a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetDeviceAttrNode.java +++ b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetDeviceAttrNode.java @@ -26,7 +26,6 @@ import org.thingsboard.rule.engine.api.TbNodeException; import org.thingsboard.rule.engine.api.util.TbNodeUtils; import org.thingsboard.rule.engine.util.EntitiesRelatedDeviceIdAsyncLoader; import org.thingsboard.server.common.data.id.DeviceId; -import org.thingsboard.server.common.data.id.RuleNodeId; import org.thingsboard.server.common.data.plugin.ComponentType; import org.thingsboard.server.common.data.util.TbPair; import org.thingsboard.server.common.msg.TbMsg; @@ -60,7 +59,7 @@ public class TbGetDeviceAttrNode extends TbAbstractGetAttributesNode upgrade(RuleNodeId ruleNodeId, int fromVersion, JsonNode oldConfiguration) throws TbNodeException { + public TbPair upgrade(int fromVersion, JsonNode oldConfiguration) throws TbNodeException { return fromVersion == 0 ? upgradeRuleNodesWithOldPropertyToUseFetchTo( oldConfiguration, diff --git a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetOriginatorFieldsNode.java b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetOriginatorFieldsNode.java index 4b1f5e1b07..79d9a982c2 100644 --- a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetOriginatorFieldsNode.java +++ b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetOriginatorFieldsNode.java @@ -28,7 +28,6 @@ import org.thingsboard.rule.engine.api.TbNodeException; import org.thingsboard.rule.engine.api.util.TbNodeUtils; import org.thingsboard.rule.engine.util.EntitiesFieldsAsyncLoader; import org.thingsboard.server.common.data.id.EntityId; -import org.thingsboard.server.common.data.id.RuleNodeId; import org.thingsboard.server.common.data.plugin.ComponentType; import org.thingsboard.server.common.data.util.TbPair; import org.thingsboard.server.common.msg.TbMsg; @@ -102,7 +101,7 @@ public class TbGetOriginatorFieldsNode extends TbAbstractNodeWithFetchTo upgrade(RuleNodeId ruleNodeId, int fromVersion, JsonNode oldConfiguration) { + public TbPair upgrade(int fromVersion, JsonNode oldConfiguration) { if (fromVersion == 0) { var newConfigObjectNode = (ObjectNode) oldConfiguration; newConfigObjectNode.put(FETCH_TO_PROPERTY_NAME, FetchTo.METADATA.name()); diff --git a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetRelatedAttributeNode.java b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetRelatedAttributeNode.java index 3193dee09d..c89d7c4b59 100644 --- a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetRelatedAttributeNode.java +++ b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetRelatedAttributeNode.java @@ -26,7 +26,6 @@ import org.thingsboard.rule.engine.api.TbNodeException; import org.thingsboard.rule.engine.api.util.TbNodeUtils; import org.thingsboard.rule.engine.util.EntitiesRelatedEntityIdAsyncLoader; import org.thingsboard.server.common.data.id.EntityId; -import org.thingsboard.server.common.data.id.RuleNodeId; import org.thingsboard.server.common.data.plugin.ComponentType; import org.thingsboard.server.common.data.util.TbPair; @@ -75,7 +74,7 @@ public class TbGetRelatedAttributeNode extends TbAbstractGetEntityAttrNode upgrade(RuleNodeId ruleNodeId, int fromVersion, JsonNode oldConfiguration) throws TbNodeException { + public TbPair upgrade(int fromVersion, JsonNode oldConfiguration) throws TbNodeException { return fromVersion == 0 ? upgradeToUseFetchToAndDataToFetch(oldConfiguration) : new TbPair<>(false, oldConfiguration); } diff --git a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetTenantAttributeNode.java b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetTenantAttributeNode.java index 4ae7b1d3a4..8ff44e297c 100644 --- a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetTenantAttributeNode.java +++ b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetTenantAttributeNode.java @@ -25,7 +25,6 @@ import org.thingsboard.rule.engine.api.TbNodeConfiguration; import org.thingsboard.rule.engine.api.TbNodeException; import org.thingsboard.rule.engine.api.util.TbNodeUtils; import org.thingsboard.server.common.data.id.EntityId; -import org.thingsboard.server.common.data.id.RuleNodeId; import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.common.data.plugin.ComponentType; import org.thingsboard.server.common.data.util.TbPair; @@ -66,7 +65,7 @@ public class TbGetTenantAttributeNode extends TbAbstractGetEntityAttrNode upgrade(RuleNodeId ruleNodeId, int fromVersion, JsonNode oldConfiguration) throws TbNodeException { + public TbPair upgrade(int fromVersion, JsonNode oldConfiguration) throws TbNodeException { return fromVersion == 0 ? upgradeToUseFetchToAndDataToFetch(oldConfiguration) : new TbPair<>(false, oldConfiguration); } diff --git a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetTenantDetailsNode.java b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetTenantDetailsNode.java index 9d934121b8..759a91785c 100644 --- a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetTenantDetailsNode.java +++ b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetTenantDetailsNode.java @@ -24,7 +24,6 @@ import org.thingsboard.rule.engine.api.TbNodeConfiguration; import org.thingsboard.rule.engine.api.TbNodeException; import org.thingsboard.rule.engine.api.util.TbNodeUtils; import org.thingsboard.server.common.data.Tenant; -import org.thingsboard.server.common.data.id.RuleNodeId; import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.common.data.plugin.ComponentType; import org.thingsboard.server.common.data.util.TbPair; @@ -62,7 +61,7 @@ public class TbGetTenantDetailsNode extends TbAbstractGetEntityDetailsNode upgrade(RuleNodeId ruleNodeId, int fromVersion, JsonNode oldConfiguration) throws TbNodeException { + public TbPair upgrade(int fromVersion, JsonNode oldConfiguration) throws TbNodeException { return fromVersion == 0 ? upgradeRuleNodesWithOldPropertyToUseFetchTo( oldConfiguration, diff --git a/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/metadata/TbFetchDeviceCredentialsNodeTest.java b/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/metadata/TbFetchDeviceCredentialsNodeTest.java index 0c589df01c..353317a1a3 100644 --- a/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/metadata/TbFetchDeviceCredentialsNodeTest.java +++ b/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/metadata/TbFetchDeviceCredentialsNodeTest.java @@ -15,6 +15,7 @@ */ package org.thingsboard.rule.engine.metadata; +import com.fasterxml.jackson.databind.JsonNode; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; @@ -31,6 +32,7 @@ import org.thingsboard.server.common.data.id.CustomerId; import org.thingsboard.server.common.data.id.DeviceId; import org.thingsboard.server.common.data.id.EntityId; import org.thingsboard.server.common.data.security.DeviceCredentials; +import org.thingsboard.server.common.data.util.TbPair; import org.thingsboard.server.common.msg.TbMsg; import org.thingsboard.server.common.msg.TbMsgMetaData; import org.thingsboard.server.common.msg.queue.TbMsgCallback; @@ -40,6 +42,8 @@ import java.util.Map; import java.util.UUID; import static org.assertj.core.api.Assertions.assertThat; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; import static org.mockito.ArgumentMatchers.any; import static org.mockito.BDDMockito.willAnswer; import static org.mockito.Mockito.doAnswer; @@ -67,7 +71,6 @@ public class TbFetchDeviceCredentialsNodeTest { void setUp() throws TbNodeException { deviceId = new DeviceId(UUID.randomUUID()); config = new TbFetchDeviceCredentialsNodeConfiguration().defaultConfiguration(); - config.setFetchTo(FetchTo.METADATA); node.init(ctxMock, new TbNodeConfiguration(JacksonUtil.valueToTree(config))); } @@ -150,6 +153,15 @@ public class TbFetchDeviceCredentialsNodeTest { assertThat(exceptionCaptor.getValue()).isInstanceOf(RuntimeException.class); } + @Test + void givenOldConfig_whenUpgrade_thenShouldReturnSuccessResult() throws Exception { + String oldConfig = "{\"fetchToMetadata\":true}"; + JsonNode configJson = JacksonUtil.toJsonNode(oldConfig); + TbPair upgrade = node.upgrade(0, configJson); + assertTrue(upgrade.getFirst()); + assertEquals(JacksonUtil.valueToTree(config), upgrade.getSecond()); + } + private TbMsg getTbMsg(EntityId entityId) { final Map mdMap = Map.of( "country", "US", diff --git a/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/metadata/TbGetAttributesNodeTest.java b/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/metadata/TbGetAttributesNodeTest.java index b627b8e5f8..52f11cd4a8 100644 --- a/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/metadata/TbGetAttributesNodeTest.java +++ b/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/metadata/TbGetAttributesNodeTest.java @@ -16,10 +16,12 @@ package org.thingsboard.rule.engine.metadata; import com.datastax.oss.driver.api.core.uuid.Uuids; +import com.fasterxml.jackson.databind.JsonNode; import com.google.common.util.concurrent.Futures; import org.junit.After; import org.junit.Before; import org.junit.Test; +import org.junit.jupiter.api.Assertions; import org.junit.runner.RunWith; import org.mockito.ArgumentCaptor; import org.mockito.Mock; @@ -39,6 +41,7 @@ import org.thingsboard.server.common.data.kv.BasicTsKvEntry; import org.thingsboard.server.common.data.kv.JsonDataEntry; import org.thingsboard.server.common.data.kv.StringDataEntry; import org.thingsboard.server.common.data.kv.TsKvEntry; +import org.thingsboard.server.common.data.util.TbPair; import org.thingsboard.server.common.msg.TbMsg; import org.thingsboard.server.common.msg.TbMsgMetaData; import org.thingsboard.server.dao.attributes.AttributesService; @@ -247,6 +250,23 @@ public class TbGetAttributesNodeTest { assertThat(exception.getMessage()).isEqualTo("Message body is not an object!"); } + @Test + public void givenOldConfig_whenUpgrade_thenShouldReturnSuccessResult() throws Exception { + var defaultConfig = new TbGetAttributesNodeConfiguration().defaultConfiguration(); + var node = new TbGetAttributesNode(); + String oldConfig = "{\"fetchToData\":false," + + "\"clientAttributeNames\":[]," + + "\"sharedAttributeNames\":[]," + + "\"serverAttributeNames\":[]," + + "\"latestTsKeyNames\":[]," + + "\"tellFailureIfAbsent\":true," + + "\"getLatestValueWithTs\":false}"; + JsonNode configJson = JacksonUtil.toJsonNode(oldConfig); + TbPair upgrade = node.upgrade(0, configJson); + Assertions.assertTrue(upgrade.getFirst()); + Assertions.assertEquals(JacksonUtil.valueToTree(defaultConfig), upgrade.getSecond()); + } + private TbMsg checkMsg(boolean checkSuccess) { var msgCaptor = ArgumentCaptor.forClass(TbMsg.class); if (checkSuccess) { diff --git a/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/metadata/TbGetCustomerAttributeNodeTest.java b/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/metadata/TbGetCustomerAttributeNodeTest.java index bc1ba87322..201992e949 100644 --- a/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/metadata/TbGetCustomerAttributeNodeTest.java +++ b/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/metadata/TbGetCustomerAttributeNodeTest.java @@ -15,10 +15,12 @@ */ package org.thingsboard.rule.engine.metadata; +import com.fasterxml.jackson.databind.JsonNode; import com.google.common.util.concurrent.Futures; import com.google.common.util.concurrent.ListenableFuture; import lombok.RequiredArgsConstructor; import org.jetbrains.annotations.NotNull; +import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; @@ -46,6 +48,7 @@ import org.thingsboard.server.common.data.kv.BaseAttributeKvEntry; import org.thingsboard.server.common.data.kv.BasicTsKvEntry; import org.thingsboard.server.common.data.kv.StringDataEntry; import org.thingsboard.server.common.data.kv.TsKvEntry; +import org.thingsboard.server.common.data.util.TbPair; import org.thingsboard.server.common.msg.TbMsg; import org.thingsboard.server.common.msg.TbMsgMetaData; import org.thingsboard.server.dao.asset.AssetService; @@ -451,6 +454,17 @@ public class TbGetCustomerAttributeNodeTest { assertThat(actualMessageCaptor.getValue().getMetaData()).isEqualTo(expectedMsgMetaData); } + @Test + public void givenOldConfig_whenUpgrade_thenShouldReturnSuccessResult() throws Exception { + var defaultConfig = new TbGetEntityAttrNodeConfiguration().defaultConfiguration(); + var node = new TbGetCustomerAttributeNode(); + String oldConfig = "{\"attrMapping\":{\"alarmThreshold\":\"threshold\"},\"telemetry\":false}"; + JsonNode configJson = JacksonUtil.toJsonNode(oldConfig); + TbPair upgrade = node.upgrade(0, configJson); + Assertions.assertTrue(upgrade.getFirst()); + Assertions.assertEquals(JacksonUtil.valueToTree(defaultConfig), upgrade.getSecond()); + } + private void prepareMsgAndConfig(FetchTo fetchTo, DataToFetch dataToFetch, EntityId originator) { config.setAttrMapping(Map.of( "sourceKey1", "targetKey1", diff --git a/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/metadata/TbGetCustomerDetailsNodeTest.java b/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/metadata/TbGetCustomerDetailsNodeTest.java index fc61b0d2b7..901172d344 100644 --- a/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/metadata/TbGetCustomerDetailsNodeTest.java +++ b/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/metadata/TbGetCustomerDetailsNodeTest.java @@ -15,9 +15,11 @@ */ package org.thingsboard.rule.engine.metadata; +import com.fasterxml.jackson.databind.JsonNode; import com.google.common.util.concurrent.Futures; import com.google.common.util.concurrent.ListenableFuture; import org.jetbrains.annotations.NotNull; +import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; @@ -44,6 +46,7 @@ import org.thingsboard.server.common.data.id.EdgeId; import org.thingsboard.server.common.data.id.EntityId; import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.common.data.id.UserId; +import org.thingsboard.server.common.data.util.TbPair; import org.thingsboard.server.common.msg.TbMsg; import org.thingsboard.server.common.msg.TbMsgMetaData; import org.thingsboard.server.dao.asset.AssetService; @@ -444,6 +447,17 @@ public class TbGetCustomerDetailsNodeTest { assertThat(actualException.getMessage()).isEqualTo("Entity with entityType 'DASHBOARD' is not supported."); } + @Test + public void givenOldConfig_whenUpgrade_thenShouldReturnSuccessResult() throws Exception { + var defaultConfig = new TbGetCustomerDetailsNodeConfiguration().defaultConfiguration(); + var node = new TbGetCustomerDetailsNode(); + String oldConfig = "{\"detailsList\":[],\"addToMetadata\":false}"; + JsonNode configJson = JacksonUtil.toJsonNode(oldConfig); + TbPair upgrade = node.upgrade(0, configJson); + Assertions.assertTrue(upgrade.getFirst()); + Assertions.assertEquals(JacksonUtil.valueToTree(defaultConfig), upgrade.getSecond()); + } + private void prepareMsgAndConfig(FetchTo fetchTo, List detailsList, EntityId originator) { config.setDetailsList(detailsList); config.setFetchTo(fetchTo); diff --git a/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/metadata/TbGetDeviceAttrNodeTest.java b/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/metadata/TbGetDeviceAttrNodeTest.java new file mode 100644 index 0000000000..c7d5e1c0c3 --- /dev/null +++ b/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/metadata/TbGetDeviceAttrNodeTest.java @@ -0,0 +1,45 @@ +/** + * Copyright © 2016-2023 The Thingsboard Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.thingsboard.rule.engine.metadata; + +import com.fasterxml.jackson.databind.JsonNode; +import org.junit.Test; +import org.junit.jupiter.api.Assertions; +import org.thingsboard.common.util.JacksonUtil; +import org.thingsboard.server.common.data.util.TbPair; + +public class TbGetDeviceAttrNodeTest { + + @Test + public void givenOldConfig_whenUpgrade_thenShouldReturnSuccessResult() throws Exception { + var defaultConfig = new TbGetDeviceAttrNodeConfiguration().defaultConfiguration(); + var node = new TbGetDeviceAttrNode(); + String oldConfig = "{\"fetchToData\":false," + + "\"clientAttributeNames\":[]," + + "\"sharedAttributeNames\":[]," + + "\"serverAttributeNames\":[]," + + "\"latestTsKeyNames\":[]," + + "\"tellFailureIfAbsent\":true," + + "\"getLatestValueWithTs\":false," + + "\"deviceRelationsQuery\":{\"direction\":\"FROM\",\"maxLevel\":1,\"relationType\":\"Contains\",\"deviceTypes\":[\"default\"]," + + "\"fetchLastLevelOnly\":false}}"; + JsonNode configJson = JacksonUtil.toJsonNode(oldConfig); + TbPair upgrade = node.upgrade(0, configJson); + Assertions.assertTrue(upgrade.getFirst()); + Assertions.assertEquals(JacksonUtil.valueToTree(defaultConfig), upgrade.getSecond()); + } + +} \ No newline at end of file diff --git a/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/metadata/TbGetOriginatorFieldsNodeTest.java b/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/metadata/TbGetOriginatorFieldsNodeTest.java index 7743fda2be..6b162d08fb 100644 --- a/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/metadata/TbGetOriginatorFieldsNodeTest.java +++ b/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/metadata/TbGetOriginatorFieldsNodeTest.java @@ -15,9 +15,11 @@ */ package org.thingsboard.rule.engine.metadata; +import com.fasterxml.jackson.databind.JsonNode; import com.google.common.util.concurrent.Futures; import com.google.common.util.concurrent.ListenableFuture; import org.jetbrains.annotations.NotNull; +import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; @@ -33,6 +35,7 @@ import org.thingsboard.server.common.data.Device; import org.thingsboard.server.common.data.id.DashboardId; import org.thingsboard.server.common.data.id.DeviceId; import org.thingsboard.server.common.data.id.TenantId; +import org.thingsboard.server.common.data.util.TbPair; import org.thingsboard.server.common.msg.TbMsg; import org.thingsboard.server.common.msg.TbMsgMetaData; import org.thingsboard.server.dao.device.DeviceService; @@ -339,4 +342,15 @@ public class TbGetOriginatorFieldsNodeTest { assertThat(actualMessageCaptor.getValue().getMetaData()).isEqualTo(msgMetaData); } + @Test + public void givenOldConfig_whenUpgrade_thenShouldReturnSuccessResult() throws Exception { + var defaultConfig = new TbGetOriginatorFieldsConfiguration().defaultConfiguration(); + var node = new TbGetOriginatorFieldsNode(); + String oldConfig = "{\"fieldsMapping\":{\"name\":\"originatorName\",\"type\":\"originatorType\"},\"ignoreNullStrings\":false}"; + JsonNode configJson = JacksonUtil.toJsonNode(oldConfig); + TbPair upgrade = node.upgrade(0, configJson); + Assertions.assertTrue(upgrade.getFirst()); + Assertions.assertEquals(JacksonUtil.valueToTree(defaultConfig), upgrade.getSecond()); + } + } diff --git a/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/metadata/TbGetRelatedAttributeNodeTest.java b/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/metadata/TbGetRelatedAttributeNodeTest.java index f5684d1786..a9a04fb3df 100644 --- a/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/metadata/TbGetRelatedAttributeNodeTest.java +++ b/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/metadata/TbGetRelatedAttributeNodeTest.java @@ -15,10 +15,12 @@ */ package org.thingsboard.rule.engine.metadata; +import com.fasterxml.jackson.databind.JsonNode; import com.google.common.util.concurrent.Futures; import com.google.common.util.concurrent.ListenableFuture; import lombok.RequiredArgsConstructor; import org.jetbrains.annotations.NotNull; +import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; @@ -43,6 +45,7 @@ import org.thingsboard.server.common.data.kv.TsKvEntry; import org.thingsboard.server.common.data.relation.EntityRelation; import org.thingsboard.server.common.data.relation.EntitySearchDirection; import org.thingsboard.server.common.data.relation.RelationEntityTypeFilter; +import org.thingsboard.server.common.data.util.TbPair; import org.thingsboard.server.common.msg.TbMsg; import org.thingsboard.server.common.msg.TbMsgMetaData; import org.thingsboard.server.common.msg.session.SessionMsgType; @@ -548,6 +551,21 @@ public class TbGetRelatedAttributeNodeTest { assertThat(actualMessageCaptor.getValue().getMetaData()).isEqualTo(expectedMsgMetadata); } + @Test + public void givenOldConfig_whenUpgrade_thenShouldReturnSuccessResult() throws Exception { + var defaultConfig = new TbGetRelatedAttrNodeConfiguration().defaultConfiguration(); + var node = new TbGetRelatedAttributeNode(); + String oldConfig = "{\"attrMapping\":{\"serialNumber\":\"sn\"}," + + "\"relationsQuery\":{\"direction\":\"FROM\",\"maxLevel\":1," + + "\"filters\":[{\"relationType\":\"Contains\",\"entityTypes\":[]}]," + + "\"fetchLastLevelOnly\":false}," + + "\"telemetry\":false}"; + JsonNode configJson = JacksonUtil.toJsonNode(oldConfig); + TbPair upgrade = node.upgrade(0, configJson); + Assertions.assertTrue(upgrade.getFirst()); + Assertions.assertEquals(JacksonUtil.valueToTree(defaultConfig), upgrade.getSecond()); + } + private void prepareMsgAndConfig(FetchTo fetchTo, DataToFetch dataToFetch, EntityId originator) { config.setDataToFetch(dataToFetch); diff --git a/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/metadata/TbGetTenantAttributeNodeTest.java b/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/metadata/TbGetTenantAttributeNodeTest.java index 19641b7000..5c56561a48 100644 --- a/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/metadata/TbGetTenantAttributeNodeTest.java +++ b/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/metadata/TbGetTenantAttributeNodeTest.java @@ -15,10 +15,12 @@ */ package org.thingsboard.rule.engine.metadata; +import com.fasterxml.jackson.databind.JsonNode; import com.google.common.util.concurrent.Futures; import com.google.common.util.concurrent.ListenableFuture; import lombok.RequiredArgsConstructor; import org.jetbrains.annotations.NotNull; +import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; @@ -41,6 +43,7 @@ import org.thingsboard.server.common.data.kv.BaseAttributeKvEntry; import org.thingsboard.server.common.data.kv.BasicTsKvEntry; import org.thingsboard.server.common.data.kv.StringDataEntry; import org.thingsboard.server.common.data.kv.TsKvEntry; +import org.thingsboard.server.common.data.util.TbPair; import org.thingsboard.server.common.msg.TbMsg; import org.thingsboard.server.common.msg.TbMsgMetaData; import org.thingsboard.server.dao.attributes.AttributesService; @@ -381,6 +384,17 @@ public class TbGetTenantAttributeNodeTest { assertThat(actualMessageCaptor.getValue().getMetaData()).isEqualTo(expectedMsgMetaData); } + @Test + public void givenOldConfig_whenUpgrade_thenShouldReturnSuccessResult() throws Exception { + var defaultConfig = new TbGetEntityAttrNodeConfiguration().defaultConfiguration(); + var node = new TbGetTenantAttributeNode(); + String oldConfig = "{\"attrMapping\":{\"alarmThreshold\":\"threshold\"},\"telemetry\":false}"; + JsonNode configJson = JacksonUtil.toJsonNode(oldConfig); + TbPair upgrade = node.upgrade(0, configJson); + Assertions.assertTrue(upgrade.getFirst()); + Assertions.assertEquals(JacksonUtil.valueToTree(defaultConfig), upgrade.getSecond()); + } + private void prepareMsgAndConfig(FetchTo fetchTo, DataToFetch dataToFetch, EntityId originator) { config.setAttrMapping(Map.of( "sourceKey1", "targetKey1", diff --git a/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/metadata/TbGetTenantDetailsNodeTest.java b/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/metadata/TbGetTenantDetailsNodeTest.java index e5333cb459..87e933f5bd 100644 --- a/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/metadata/TbGetTenantDetailsNodeTest.java +++ b/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/metadata/TbGetTenantDetailsNodeTest.java @@ -15,7 +15,9 @@ */ package org.thingsboard.rule.engine.metadata; +import com.fasterxml.jackson.databind.JsonNode; import com.google.common.util.concurrent.Futures; +import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; @@ -30,6 +32,7 @@ import org.thingsboard.rule.engine.util.ContactBasedEntityDetails; import org.thingsboard.server.common.data.Tenant; import org.thingsboard.server.common.data.id.DeviceId; import org.thingsboard.server.common.data.id.TenantId; +import org.thingsboard.server.common.data.util.TbPair; import org.thingsboard.server.common.msg.TbMsg; import org.thingsboard.server.common.msg.TbMsgMetaData; import org.thingsboard.server.dao.tenant.TenantService; @@ -259,6 +262,17 @@ public class TbGetTenantDetailsNodeTest { assertThat(actualMessageCaptor.getValue().getMetaData()).isEqualTo(msg.getMetaData()); } + @Test + public void givenOldConfig_whenUpgrade_thenShouldReturnSuccessResult() throws Exception { + var defaultConfig = new TbGetTenantDetailsNodeConfiguration().defaultConfiguration(); + var node = new TbGetTenantDetailsNode(); + String oldConfig = "{\"detailsList\":[],\"addToMetadata\":false}"; + JsonNode configJson = JacksonUtil.toJsonNode(oldConfig); + TbPair upgrade = node.upgrade(0, configJson); + Assertions.assertTrue(upgrade.getFirst()); + Assertions.assertEquals(JacksonUtil.valueToTree(defaultConfig), upgrade.getSecond()); + } + private void prepareMsgAndConfig(FetchTo fetchTo, List detailsList) { config.setDetailsList(detailsList); config.setFetchTo(fetchTo); diff --git a/ui-ngx/src/app/modules/home/pages/rulechain/rulechain-page.component.ts b/ui-ngx/src/app/modules/home/pages/rulechain/rulechain-page.component.ts index 7fff22a12a..a06c06ba36 100644 --- a/ui-ngx/src/app/modules/home/pages/rulechain/rulechain-page.component.ts +++ b/ui-ngx/src/app/modules/home/pages/rulechain/rulechain-page.component.ts @@ -555,6 +555,7 @@ export class RuleChainPageComponent extends PageComponent ruleNodeId: ruleNode.id, additionalInfo: ruleNode.additionalInfo, configuration: ruleNode.configuration, + configurationVersion: ruleNode.configurationVersion, debugMode: ruleNode.debugMode, singletonMode: ruleNode.singletonMode, x: Math.round(ruleNode.additionalInfo.layoutX), @@ -1424,6 +1425,7 @@ export class RuleChainPageComponent extends PageComponent id: node.ruleNodeId, type: node.component.clazz, name: node.name, + configurationVersion: node.configurationVersion, configuration: node.configuration, additionalInfo: node.additionalInfo ? node.additionalInfo : {}, debugMode: node.debugMode, diff --git a/ui-ngx/src/app/shared/models/rule-node.models.ts b/ui-ngx/src/app/shared/models/rule-node.models.ts index dbb065f7f2..19d4a24a9d 100644 --- a/ui-ngx/src/app/shared/models/rule-node.models.ts +++ b/ui-ngx/src/app/shared/models/rule-node.models.ts @@ -37,6 +37,7 @@ export interface RuleNode extends BaseData { name: string; debugMode: boolean; singletonMode: boolean; + configurationVersion?: number; configuration: RuleNodeConfiguration; additionalInfo?: any; }