From bfb475744069614f78ffed25c3ce25ab33eee86d Mon Sep 17 00:00:00 2001 From: yevhenii Date: Tue, 1 Apr 2025 16:50:04 +0300 Subject: [PATCH] Fix RuleChainMetadata for older Edge versions - refactoring test --- .../edge/EdgeMsgConstructorUtilsTest.java | 171 +++++++++--------- 1 file changed, 84 insertions(+), 87 deletions(-) diff --git a/application/src/test/java/org/thingsboard/server/service/edge/EdgeMsgConstructorUtilsTest.java b/application/src/test/java/org/thingsboard/server/service/edge/EdgeMsgConstructorUtilsTest.java index ea82ec1780..a4c2133f1c 100644 --- a/application/src/test/java/org/thingsboard/server/service/edge/EdgeMsgConstructorUtilsTest.java +++ b/application/src/test/java/org/thingsboard/server/service/edge/EdgeMsgConstructorUtilsTest.java @@ -16,34 +16,34 @@ package org.thingsboard.server.service.edge; import lombok.extern.slf4j.Slf4j; -import org.junit.Assert; import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.TestInstance; import org.junit.jupiter.params.ParameterizedTest; -import org.junit.jupiter.params.provider.EnumSource; +import org.junit.jupiter.params.provider.MethodSource; import org.thingsboard.common.util.JacksonUtil; import org.thingsboard.rule.engine.action.TbSaveToCustomCassandraTableNode; -import org.thingsboard.rule.engine.action.TbSaveToCustomCassandraTableNodeConfiguration; import org.thingsboard.rule.engine.api.NodeConfiguration; +import org.thingsboard.rule.engine.api.TbNode; import org.thingsboard.rule.engine.aws.lambda.TbAwsLambdaNode; -import org.thingsboard.rule.engine.aws.lambda.TbAwsLambdaNodeConfiguration; +import org.thingsboard.rule.engine.filter.TbCheckRelationNode; +import org.thingsboard.rule.engine.flow.TbAckNode; +import org.thingsboard.rule.engine.math.TbMathNode; +import org.thingsboard.rule.engine.metadata.CalculateDeltaNode; +import org.thingsboard.rule.engine.metadata.TbGetTelemetryNode; import org.thingsboard.rule.engine.rest.TbSendRestApiCallReplyNode; -import org.thingsboard.rule.engine.rest.TbSendRestApiCallReplyNodeConfiguration; import org.thingsboard.rule.engine.telemetry.TbMsgAttributesNode; -import org.thingsboard.rule.engine.telemetry.TbMsgAttributesNodeConfiguration; import org.thingsboard.rule.engine.telemetry.TbMsgTimeseriesNode; -import org.thingsboard.rule.engine.telemetry.TbMsgTimeseriesNodeConfiguration; import org.thingsboard.server.common.data.rule.RuleChainMetaData; import org.thingsboard.server.common.data.rule.RuleNode; -import org.thingsboard.server.common.data.util.TbPair; import org.thingsboard.server.gen.edge.v1.EdgeVersion; import org.thingsboard.server.gen.edge.v1.UpdateMsgType; -import java.util.ArrayList; -import java.util.HashMap; +import java.lang.reflect.Constructor; import java.util.List; -import java.util.Map; +import java.util.Optional; +import java.util.stream.Stream; import static org.thingsboard.server.service.edge.EdgeMsgConstructorUtils.EXCLUDED_NODES_BY_EDGE_VERSION; import static org.thingsboard.server.service.edge.EdgeMsgConstructorUtils.IGNORED_PARAMS_BY_EDGE_VERSION; @@ -51,109 +51,106 @@ import static org.thingsboard.server.service.edge.EdgeMsgConstructorUtils.IGNORE @Slf4j @TestInstance(TestInstance.Lifecycle.PER_CLASS) public class EdgeMsgConstructorUtilsTest { - private static final int CONFIGURATION_VERSION = 5; - - private static final Map NODE_CONFIG_TO_NAME_MAP = Map.of( - new TbMsgTimeseriesNodeConfiguration(), TbMsgTimeseriesNode.class.getName(), - new TbMsgAttributesNodeConfiguration(), TbMsgAttributesNode.class.getName(), - new TbSaveToCustomCassandraTableNodeConfiguration(), TbSaveToCustomCassandraTableNode.class.getName() - ); - private static final Map NODE_NAME_TO_CONFIG_PARAM_COUNT_MAP = Map.of( - TbMsgTimeseriesNode.class.getName(), 3, - TbMsgAttributesNode.class.getName(), 5, - TbSaveToCustomCassandraTableNode.class.getName(), 3 - ); + private static final int CONFIGURATION_VERSION = 5; + static Stream provideEdgeVersions() { + return Stream.of( + EdgeVersion.V_4_0_0, + EdgeVersion.V_3_9_0, + EdgeVersion.V_3_8_0, + EdgeVersion.V_3_7_0 + ); + } - private static final Map MISSING_NODE_CONFIGS_FOR_OLD_EDGES = Map.of( - new TbSendRestApiCallReplyNodeConfiguration(), TbSendRestApiCallReplyNode.class.getName(), - new TbAwsLambdaNodeConfiguration(), TbAwsLambdaNode.class.getName() - ); + private static final RuleChainMetaData RULE_CHAIN_META_DATA = new RuleChainMetaData(); + private static final List TEST_NODES = + List.of( + new TbSaveToCustomCassandraTableNode(), + new TbMsgAttributesNode(), + new TbMsgTimeseriesNode(), + new TbSendRestApiCallReplyNode(), + new TbAwsLambdaNode(), + + new TbMathNode(), + new CalculateDeltaNode(), + new TbAckNode(), + new TbCheckRelationNode(), + new TbGetTelemetryNode() + ); - @ParameterizedTest(name = "Testing metadata update for EdgeVersion: {0}") - @EnumSource(value = EdgeVersion.class, names = {"V_4_0_0", "V_3_9_0", "V_3_8_0", "V_3_7_0"}) - @DisplayName("Test RuleChain Metadata Update for Supported Edge Versions") - public void testRuleChainMetadataUpdateForSupportedEdgeVersions(EdgeVersion edgeVersion) { - // GIVEN - RuleChainMetaData metaData = createMetadataWithNodes(NODE_CONFIG_TO_NAME_MAP); + @BeforeAll + static void setUp() { + List ruleNodes = TEST_NODES.stream() + .map(node -> { + RuleNode ruleNode = new RuleNode(); + ruleNode.setName(node.getClass().getName()); + ruleNode.setType(node.getClass().getName()); + ruleNode.setConfigurationVersion(CONFIGURATION_VERSION); + ruleNode.setConfiguration(JacksonUtil.valueToTree(createDefaultConfiguration(node))); + return ruleNode; + }) + .toList(); + + RULE_CHAIN_META_DATA.setFirstNodeIndex(0); + RULE_CHAIN_META_DATA.setNodes(ruleNodes); + } - // WHEN - List ruleNodes = extractRuleNodesFromMetadata(metaData, edgeVersion); + private static NodeConfiguration createDefaultConfiguration(TbNode node) { + try { + org.thingsboard.rule.engine.api.RuleNode annotation = node.getClass().getAnnotation(org.thingsboard.rule.engine.api.RuleNode.class); + Constructor constructor = annotation.configClazz().getConstructor(); + NodeConfiguration configInstance = (NodeConfiguration) constructor.newInstance(); - // THEN - verifyRuleNodeConfigurations(ruleNodes, edgeVersion); + return configInstance.defaultConfiguration(); + } catch (Exception e) { + throw new RuntimeException("Exception during creating RuleNodeConfiguration for node - " + node, e); + } } - @ParameterizedTest(name = "Testing metadata with missing nodes for EdgeVersion: {0}") - @EnumSource(value = EdgeVersion.class, names = {"V_4_0_0", "V_3_9_0", "V_3_8_0", "V_3_7_0"}) - @DisplayName("Test RuleChain Metadata with Missing Nodes for Old Edge Versions") - public void testRuleChainMetadataWithMissingNodesForOldEdgeVersions(EdgeVersion edgeVersion) { - // GIVEN - RuleChainMetaData metaData = createMetadataWithNodes(MISSING_NODE_CONFIGS_FOR_OLD_EDGES); - + @ParameterizedTest(name = "Test Sanitize Metadata For Edge: {0}") + @MethodSource("provideEdgeVersions") + @DisplayName("Test Sanitize Metadata For Legacy Edge Version") + public void testSanitizeMetadataForLegacyEdgeVersion(EdgeVersion edgeVersion) { // WHEN - List ruleNodes = extractRuleNodesFromMetadata(metaData, edgeVersion); + List ruleNodes = sanitizeMetadataForLegacyEdgeVersion(edgeVersion); // THEN - int expectedNodeCount = EXCLUDED_NODES_BY_EDGE_VERSION.containsKey(edgeVersion) ? - MISSING_NODE_CONFIGS_FOR_OLD_EDGES.size() - EXCLUDED_NODES_BY_EDGE_VERSION.get(edgeVersion).size() : - MISSING_NODE_CONFIGS_FOR_OLD_EDGES.size(); - Assertions.assertEquals( - expectedNodeCount, - ruleNodes.size(), - String.format("EdgeVersion '%s' should have %d nodes, but found %d.", edgeVersion, expectedNodeCount, ruleNodes.size()) - ); - } - - private RuleChainMetaData createMetadataWithNodes(Map nodeConfigMap) { - RuleChainMetaData ruleChainMetaData = new RuleChainMetaData(); - List ruleNodes = new ArrayList<>(); - - nodeConfigMap.forEach((config, nodeName) -> { - RuleNode ruleNode = new RuleNode(); - ruleNode.setName(nodeName); - ruleNode.setType(nodeName); - ruleNode.setConfigurationVersion(CONFIGURATION_VERSION); - ruleNode.setConfiguration(JacksonUtil.valueToTree(config.defaultConfiguration())); - ruleNodes.add(ruleNode); + ruleNodes.forEach(ruleNode -> { + checkUpdateNodeConfigurationsForLegacyEdge(ruleNode, edgeVersion); + checkRemoveExcludedNodesForLegacyEdge(ruleNode, edgeVersion); }); - - ruleChainMetaData.setFirstNodeIndex(0); - ruleChainMetaData.setNodes(ruleNodes); - return ruleChainMetaData; } - private List extractRuleNodesFromMetadata(RuleChainMetaData metaData, EdgeVersion edgeVersion) { + private List sanitizeMetadataForLegacyEdgeVersion(EdgeVersion edgeVersion) { String metadataUpdateMsg = EdgeMsgConstructorUtils.constructRuleChainMetadataUpdatedMsg( UpdateMsgType.ENTITY_CREATED_RPC_MESSAGE, - metaData, + RULE_CHAIN_META_DATA, edgeVersion ).getEntity(); RuleChainMetaData updatedMetaData = JacksonUtil.fromString(metadataUpdateMsg, RuleChainMetaData.class, true); Assertions.assertNotNull(updatedMetaData, "RuleChainMetaData should not be null after update."); + return updatedMetaData.getNodes(); } - private void verifyRuleNodeConfigurations(List ruleNodes, EdgeVersion edgeVersion) { - ruleNodes.forEach(ruleNode -> { - String nodeType = ruleNode.getType(); - int expectedParamCount = NODE_NAME_TO_CONFIG_PARAM_COUNT_MAP.getOrDefault(nodeType, 0); + private void checkUpdateNodeConfigurationsForLegacyEdge(RuleNode ruleNode, EdgeVersion edgeVersion) { + if (IGNORED_PARAMS_BY_EDGE_VERSION.containsKey(edgeVersion) && IGNORED_PARAMS_BY_EDGE_VERSION.get(edgeVersion).containsKey(ruleNode.getType())) { + String ignoredParam = IGNORED_PARAMS_BY_EDGE_VERSION.get(edgeVersion).get(ruleNode.getType()); - boolean isRuleNodeModified = IGNORED_PARAMS_BY_EDGE_VERSION - .getOrDefault(edgeVersion, Map.of()) - .containsKey(nodeType); + Assertions.assertFalse(ruleNode.getConfiguration().has(ignoredParam), + String.format("RuleNode '%s' for EdgeVersion '%s' should ignore '%s' config parameter.", ruleNode.getName(), edgeVersion, ignoredParam)); + } + } - int actualParamCount = isRuleNodeModified ? expectedParamCount - 1 : expectedParamCount; + private void checkRemoveExcludedNodesForLegacyEdge(RuleNode ruleNode, EdgeVersion edgeVersion) { + boolean isNodeExcluded = Optional.ofNullable(EXCLUDED_NODES_BY_EDGE_VERSION.get(edgeVersion)) + .map(excludedNodes -> !excludedNodes.contains(ruleNode.getType())) + .orElse(true); - Assertions.assertEquals( - actualParamCount, - ruleNode.getConfiguration().size(), - String.format("RuleNode '%s' for EdgeVersion '%s' should have %d config parameters.", - ruleNode.getName(), edgeVersion, actualParamCount) - ); - }); + Assertions.assertTrue(isNodeExcluded, + String.format("For EdgeVersion '%s', ruleNode '%s' should not be included.", edgeVersion, ruleNode.getType())); } }