From 80a7edc8f784465765ba710d1ab201187133e5f4 Mon Sep 17 00:00:00 2001 From: yevhenii Date: Tue, 11 Mar 2025 17:58:27 +0200 Subject: [PATCH] Fix RuleChainMetadata for older Edge versions - added test - refactoring --- .../service/edge/EdgeMsgConstructorUtils.java | 16 ++-- .../edge/EdgeMsgConstructorUtilsTest.java | 91 +++++++++++++++++++ 2 files changed, 99 insertions(+), 8 deletions(-) create mode 100644 application/src/test/java/org/thingsboard/server/service/edge/EdgeMsgConstructorUtilsTest.java diff --git a/application/src/main/java/org/thingsboard/server/service/edge/EdgeMsgConstructorUtils.java b/application/src/main/java/org/thingsboard/server/service/edge/EdgeMsgConstructorUtils.java index d3e8e3104e..11e3172168 100644 --- a/application/src/main/java/org/thingsboard/server/service/edge/EdgeMsgConstructorUtils.java +++ b/application/src/main/java/org/thingsboard/server/service/edge/EdgeMsgConstructorUtils.java @@ -422,7 +422,7 @@ public class EdgeMsgConstructorUtils { } public static RuleChainMetadataUpdateMsg constructRuleChainMetadataUpdatedMsg(UpdateMsgType msgType, RuleChainMetaData ruleChainMetaData, EdgeVersion edgeVersion) { - String metaData = prepareMetaDataForEdgeVersion(ruleChainMetaData, edgeVersion); + String metaData = filterMetadataForOldEdgeVersions(ruleChainMetaData, edgeVersion); return RuleChainMetadataUpdateMsg.newBuilder() .setMsgType(msgType) @@ -430,14 +430,15 @@ public class EdgeMsgConstructorUtils { .build(); } - private static String prepareMetaDataForEdgeVersion(RuleChainMetaData ruleChainMetaData, EdgeVersion edgeVersion) { + private static String filterMetadataForOldEdgeVersions(RuleChainMetaData ruleChainMetaData, EdgeVersion edgeVersion) { if (EdgeVersionUtils.isEdgeVersionOlderThan(edgeVersion, EdgeVersion.V_3_9_0)) { JsonNode jsonNode = JacksonUtil.valueToTree(ruleChainMetaData); JsonNode nodes = jsonNode.get("nodes"); for (JsonNode node : nodes) { - if (node.isObject()) - prepareRuleNodeForOldEdgeVersion((ObjectNode) node); + if (node.isObject()) { + removeIncompatibleFields((ObjectNode) node); + } } return JacksonUtil.toString(jsonNode); } else { @@ -445,11 +446,10 @@ public class EdgeMsgConstructorUtils { } } - private static void prepareRuleNodeForOldEdgeVersion(ObjectNode node) { + private static void removeIncompatibleFields(ObjectNode node) { if (TbMsgTimeseriesNode.class.getName().equals(node.get("type").asText())) { - JsonNode configurationNode = node.get("configuration"); - if (configurationNode != null && configurationNode.isObject()) { - ((ObjectNode) configurationNode).remove("processingSettings"); + if (node.has("configuration") && node.get("configuration").isObject()) { + ((ObjectNode) node.get("configuration")).remove("processingSettings"); } } } 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 new file mode 100644 index 0000000000..5e7cfcfc28 --- /dev/null +++ b/application/src/test/java/org/thingsboard/server/service/edge/EdgeMsgConstructorUtilsTest.java @@ -0,0 +1,91 @@ +/** + * Copyright © 2016-2025 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.edge; + +import org.junit.Assert; +import org.junit.Test; +import org.thingsboard.common.util.JacksonUtil; +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.gen.edge.v1.EdgeVersion; +import org.thingsboard.server.gen.edge.v1.RuleChainMetadataUpdateMsg; +import org.thingsboard.server.gen.edge.v1.UpdateMsgType; +import org.thingsboard.server.service.edge.rpc.utils.EdgeVersionUtils; + +import java.util.Collections; + +public class EdgeMsgConstructorUtilsTest { + private static final int CONFIGURATION_VERSION = 5; + + @Test + public void testRuleChainMetadataUpdateMsgForAllEdgeVersions() { + // GIVEN + RuleChainMetaData metaData = createIncompatibleRuleNodesForOldEdge(); + + // WHEN + RuleNode ruleNode_V_4_0_0 = getRuleNodeFromMetadataUpdateMessage(metaData, EdgeVersion.V_4_0_0); + RuleNode ruleNode_V_3_9_0 = getRuleNodeFromMetadataUpdateMessage(metaData, EdgeVersion.V_3_9_0); + RuleNode ruleNode_V_3_8_0 = getRuleNodeFromMetadataUpdateMessage(metaData, EdgeVersion.V_3_8_0); + RuleNode ruleNode_V_3_7_0 = getRuleNodeFromMetadataUpdateMessage(metaData, EdgeVersion.V_3_7_0); + + // THEN + assertRuleNodeConfiguration(ruleNode_V_4_0_0, EdgeVersion.V_4_0_0); + assertRuleNodeConfiguration(ruleNode_V_3_9_0, EdgeVersion.V_3_9_0); + assertRuleNodeConfiguration(ruleNode_V_3_8_0, EdgeVersion.V_3_8_0); + assertRuleNodeConfiguration(ruleNode_V_3_7_0, EdgeVersion.V_3_7_0); + } + + private RuleChainMetaData createIncompatibleRuleNodesForOldEdge() { + RuleChainMetaData ruleChainMetaData = new RuleChainMetaData(); + + RuleNode ruleNode1 = new RuleNode(); + ruleNode1.setName("TbMsgTimeseriesNode"); + ruleNode1.setType(org.thingsboard.rule.engine.telemetry.TbMsgTimeseriesNode.class.getName()); + ruleNode1.setConfigurationVersion(CONFIGURATION_VERSION); + ruleNode1.setConfiguration(JacksonUtil.valueToTree(new TbMsgTimeseriesNodeConfiguration().defaultConfiguration())); + + ruleChainMetaData.setFirstNodeIndex(0); + ruleChainMetaData.setNodes(Collections.singletonList(ruleNode1)); + + return ruleChainMetaData; + } + + + private RuleNode getRuleNodeFromMetadataUpdateMessage(RuleChainMetaData metaData, EdgeVersion edgeVersion) { + RuleChainMetadataUpdateMsg ruleChainMetadataUpdateMsg = + EdgeMsgConstructorUtils.constructRuleChainMetadataUpdatedMsg(UpdateMsgType.ENTITY_CREATED_RPC_MESSAGE, metaData, edgeVersion); + + RuleChainMetaData ruleChainMetaData = JacksonUtil.fromString(ruleChainMetadataUpdateMsg.getEntity(), RuleChainMetaData.class, true); + Assert.assertNotNull("RuleChainMetaData is null", ruleChainMetaData); + + RuleNode ruleNode = ruleChainMetaData.getNodes().stream().findFirst().orElse(null); + Assert.assertNotNull("RuleNode is null for Edge version " + edgeVersion, ruleNode); + Assert.assertNotNull("Configuration is null for Edge version " + edgeVersion, ruleNode.getConfiguration()); + + return ruleNode; + } + + private void assertRuleNodeConfiguration(RuleNode ruleNode, EdgeVersion edgeVersion) { + if (EdgeVersionUtils.isEdgeVersionOlderThan(edgeVersion, EdgeVersion.V_3_9_0)) { + Assert.assertEquals("Unexpected config size", 2, ruleNode.getConfiguration().size()); + Assert.assertFalse("Unexpected field 'processingSettings'", ruleNode.getConfiguration().has("processingSettings")); + }else{ + Assert.assertEquals("Unexpected config size", 3, ruleNode.getConfiguration().size()); + Assert.assertTrue("Missing field 'processingSettings'", ruleNode.getConfiguration().has("processingSettings")); + } + } +}