diff --git a/application/src/test/java/org/thingsboard/server/edge/BaseEdgeTest.java b/application/src/test/java/org/thingsboard/server/edge/BaseEdgeTest.java index cd3b14c796..5f7acd0422 100644 --- a/application/src/test/java/org/thingsboard/server/edge/BaseEdgeTest.java +++ b/application/src/test/java/org/thingsboard/server/edge/BaseEdgeTest.java @@ -612,8 +612,6 @@ abstract public class BaseEdgeTest extends AbstractControllerTest { ruleChainMetaData.addConnectionInfo(0, 2, "fail"); ruleChainMetaData.addConnectionInfo(1, 2, "success"); - ruleChainMetaData.addRuleChainConnectionInfo(2, edge.getRootRuleChainId(), "success", mapper.createObjectNode()); - doPost("/api/ruleChain/metadata", ruleChainMetaData, RuleChainMetaData.class); } diff --git a/application/src/test/java/org/thingsboard/server/rules/flow/AbstractRuleEngineFlowIntegrationTest.java b/application/src/test/java/org/thingsboard/server/rules/flow/AbstractRuleEngineFlowIntegrationTest.java index dcc8f35ba3..9d96fe9d9c 100644 --- a/application/src/test/java/org/thingsboard/server/rules/flow/AbstractRuleEngineFlowIntegrationTest.java +++ b/application/src/test/java/org/thingsboard/server/rules/flow/AbstractRuleEngineFlowIntegrationTest.java @@ -25,6 +25,7 @@ import org.mockito.Mockito; import org.mockito.stubbing.Answer; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.test.util.ReflectionTestUtils; +import org.thingsboard.rule.engine.flow.TbRuleChainInputNodeConfiguration; import org.thingsboard.rule.engine.metadata.TbGetAttributesNodeConfiguration; import org.thingsboard.server.actors.ActorSystemContext; import org.thingsboard.server.common.data.DataConstants; @@ -35,6 +36,7 @@ import org.thingsboard.server.common.data.User; import org.thingsboard.server.common.data.kv.BaseAttributeKvEntry; import org.thingsboard.server.common.data.kv.StringDataEntry; import org.thingsboard.server.common.data.page.PageData; +import org.thingsboard.server.common.data.rule.NodeConnectionInfo; import org.thingsboard.server.common.data.rule.RuleChain; import org.thingsboard.server.common.data.rule.RuleChainMetaData; import org.thingsboard.server.common.data.rule.RuleNode; @@ -240,16 +242,27 @@ public abstract class AbstractRuleEngineFlowIntegrationTest extends AbstractRule configuration1.setServerAttributeNames(Collections.singletonList("serverAttributeKey1")); ruleNode1.setConfiguration(mapper.valueToTree(configuration1)); - rootMetaData.setNodes(Collections.singletonList(ruleNode1)); + RuleNode ruleNode12 = new RuleNode(); + ruleNode12.setName("Simple Rule Node 1"); + ruleNode12.setType(org.thingsboard.rule.engine.flow.TbRuleChainInputNode.class.getName()); + ruleNode12.setDebugMode(true); + TbRuleChainInputNodeConfiguration configuration12 = new TbRuleChainInputNodeConfiguration(); + configuration12.setRuleChainId(secondaryRuleChain.getId().getId().toString()); + ruleNode12.setConfiguration(mapper.valueToTree(configuration12)); + + rootMetaData.setNodes(Arrays.asList(ruleNode1, ruleNode12)); rootMetaData.setFirstNodeIndex(0); - rootMetaData.addRuleChainConnectionInfo(0, secondaryRuleChain.getId(), "Success", mapper.createObjectNode()); + NodeConnectionInfo connection = new NodeConnectionInfo(); + connection.setFromIndex(0); + connection.setToIndex(1); + connection.setType("Success"); + rootMetaData.setConnections(Collections.singletonList(connection)); rootMetaData = saveRuleChainMetaData(rootMetaData); Assert.assertNotNull(rootMetaData); rootRuleChain = getRuleChain(rootRuleChain.getId()); Assert.assertNotNull(rootRuleChain.getFirstRuleNodeId()); - RuleChainMetaData secondaryMetaData = new RuleChainMetaData(); secondaryMetaData.setRuleChainId(secondaryRuleChain.getId()); diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/rule/RuleChainMetaData.java b/common/data/src/main/java/org/thingsboard/server/common/data/rule/RuleChainMetaData.java index d51725f153..7bd19e2441 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/rule/RuleChainMetaData.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/rule/RuleChainMetaData.java @@ -59,15 +59,4 @@ public class RuleChainMetaData { } connections.add(connectionInfo); } - public void addRuleChainConnectionInfo(int fromIndex, RuleChainId targetRuleChainId, String type, JsonNode additionalInfo) { - RuleChainConnectionInfo connectionInfo = new RuleChainConnectionInfo(); - connectionInfo.setFromIndex(fromIndex); - connectionInfo.setTargetRuleChainId(targetRuleChainId); - connectionInfo.setType(type); - connectionInfo.setAdditionalInfo(additionalInfo); - if (ruleChainConnections == null) { - ruleChainConnections = new ArrayList<>(); - } - ruleChainConnections.add(connectionInfo); - } } 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 6916566307..0f62c57741 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 @@ -26,6 +26,7 @@ import org.hibernate.exception.ConstraintViolationException; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; +import org.thingsboard.common.util.JacksonUtil; import org.thingsboard.server.common.data.BaseData; import org.thingsboard.server.common.data.EntityType; import org.thingsboard.server.common.data.edge.Edge; @@ -199,11 +200,42 @@ public class BaseRuleChainService extends AbstractEntityService implements RuleC } if (ruleChainMetaData.getRuleChainConnections() != null) { for (RuleChainConnectionInfo nodeToRuleChainConnection : ruleChainMetaData.getRuleChainConnections()) { + RuleChainId targetRuleChainId = nodeToRuleChainConnection.getTargetRuleChainId(); + RuleChain targetRuleChain = findRuleChainById(TenantId.SYS_TENANT_ID, targetRuleChainId); + if (targetRuleChain == null) { + log.info("Skip processing of relation for non existing target rule chain: [{}]", targetRuleChainId); + continue; + } + + RuleNode targetNode = new RuleNode(); + targetNode.setName(targetRuleChain.getName()); + targetNode.setRuleChainId(ruleChain.getId()); + targetNode.setType("org.thingsboard.rule.engine.flow.TbRuleChainInputNode"); + var configuration = JacksonUtil.newObjectNode(); + configuration.put("ruleChainId", targetRuleChain.getId().toString()); + targetNode.setConfiguration(configuration); + ObjectNode layout = (ObjectNode) nodeToRuleChainConnection.getAdditionalInfo(); + layout.remove("description"); + layout.remove("ruleChainNodeId"); + targetNode.setAdditionalInfo(layout); + targetNode.setDebugMode(false); + targetNode = ruleNodeDao.save(tenantId, targetNode); + + EntityRelation sourceRuleChainToRuleNode = new EntityRelation(); + sourceRuleChainToRuleNode.setFrom(ruleChain.getId()); + sourceRuleChainToRuleNode.setTo(targetNode.getId()); + sourceRuleChainToRuleNode.setType(EntityRelation.CONTAINS_TYPE); + sourceRuleChainToRuleNode.setTypeGroup(RelationTypeGroup.RULE_CHAIN); + relationService.saveRelation(tenantId, sourceRuleChainToRuleNode); + + EntityRelation sourceRuleNodeToTargetRuleNode = new EntityRelation(); EntityId from = nodes.get(nodeToRuleChainConnection.getFromIndex()).getId(); - EntityId to = nodeToRuleChainConnection.getTargetRuleChainId(); - String type = nodeToRuleChainConnection.getType(); - createRelation(tenantId, new EntityRelation(from, to, type, RelationTypeGroup.RULE_NODE, nodeToRuleChainConnection.getAdditionalInfo())); - } + sourceRuleNodeToTargetRuleNode.setFrom(from); + sourceRuleNodeToTargetRuleNode.setTo(targetNode.getId()); + sourceRuleNodeToTargetRuleNode.setType(nodeToRuleChainConnection.getType()); + sourceRuleNodeToTargetRuleNode.setTypeGroup(RelationTypeGroup.RULE_NODE); + relationService.saveRelation(tenantId, sourceRuleNodeToTargetRuleNode); + } } } @@ -263,8 +295,7 @@ public class BaseRuleChainService extends AbstractEntityService implements RuleC int toIndex = ruleNodeIndexMap.get(toNodeId); ruleChainMetaData.addConnectionInfo(fromIndex, toIndex, type); } else if (nodeRelation.getTo().getEntityType() == EntityType.RULE_CHAIN) { - RuleChainId targetRuleChainId = new RuleChainId(nodeRelation.getTo().getId()); - ruleChainMetaData.addRuleChainConnectionInfo(fromIndex, targetRuleChainId, type, nodeRelation.getAdditionalInfo()); + log.warn("[{}][{}] Unsupported node relation: {}", tenantId, ruleChainId, nodeRelation.getTo()); } } }