Browse Source

Fix RuleChainMetadata for older Edge versions

- refactoring test
pull/12843/head
yevhenii 1 year ago
parent
commit
bfb4757440
  1. 171
      application/src/test/java/org/thingsboard/server/service/edge/EdgeMsgConstructorUtilsTest.java

171
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<NodeConfiguration, String> 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<String, Integer> 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<EdgeVersion> 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<NodeConfiguration, String> 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<TbNode> 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<RuleNode> 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<RuleNode> 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<RuleNode> ruleNodes = extractRuleNodesFromMetadata(metaData, edgeVersion);
List<RuleNode> 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<NodeConfiguration, String> nodeConfigMap) {
RuleChainMetaData ruleChainMetaData = new RuleChainMetaData();
List<RuleNode> 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<RuleNode> extractRuleNodesFromMetadata(RuleChainMetaData metaData, EdgeVersion edgeVersion) {
private List<RuleNode> 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<RuleNode> 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()));
}
}

Loading…
Cancel
Save