Fix edge cycling: update edge root rule chain, add test. Improve Edge rpc request to edge device. Add support for originator fields for rule nodes
This commit is contained in:
		
							parent
							
								
									fe46c69dd4
								
							
						
					
					
						commit
						7cd4d477ff
					
				@ -66,7 +66,6 @@ import org.thingsboard.server.common.msg.rule.engine.DeviceCredentialsUpdateNoti
 | 
				
			|||||||
import org.thingsboard.server.common.msg.rule.engine.DeviceEdgeUpdateMsg;
 | 
					import org.thingsboard.server.common.msg.rule.engine.DeviceEdgeUpdateMsg;
 | 
				
			||||||
import org.thingsboard.server.common.msg.rule.engine.DeviceNameOrTypeUpdateMsg;
 | 
					import org.thingsboard.server.common.msg.rule.engine.DeviceNameOrTypeUpdateMsg;
 | 
				
			||||||
import org.thingsboard.server.common.msg.timeout.DeviceActorServerSideRpcTimeoutMsg;
 | 
					import org.thingsboard.server.common.msg.timeout.DeviceActorServerSideRpcTimeoutMsg;
 | 
				
			||||||
import org.thingsboard.server.gen.transport.TransportProtos;
 | 
					 | 
				
			||||||
import org.thingsboard.server.gen.transport.TransportProtos.AttributeUpdateNotificationMsg;
 | 
					import org.thingsboard.server.gen.transport.TransportProtos.AttributeUpdateNotificationMsg;
 | 
				
			||||||
import org.thingsboard.server.gen.transport.TransportProtos.ClaimDeviceMsg;
 | 
					import org.thingsboard.server.gen.transport.TransportProtos.ClaimDeviceMsg;
 | 
				
			||||||
import org.thingsboard.server.gen.transport.TransportProtos.DeviceSessionsCacheEntry;
 | 
					import org.thingsboard.server.gen.transport.TransportProtos.DeviceSessionsCacheEntry;
 | 
				
			||||||
@ -90,7 +89,9 @@ import org.thingsboard.server.gen.transport.TransportProtos.ToTransportMsg;
 | 
				
			|||||||
import org.thingsboard.server.gen.transport.TransportProtos.ToTransportUpdateCredentialsProto;
 | 
					import org.thingsboard.server.gen.transport.TransportProtos.ToTransportUpdateCredentialsProto;
 | 
				
			||||||
import org.thingsboard.server.gen.transport.TransportProtos.TransportToDeviceActorMsg;
 | 
					import org.thingsboard.server.gen.transport.TransportProtos.TransportToDeviceActorMsg;
 | 
				
			||||||
import org.thingsboard.server.gen.transport.TransportProtos.TsKvProto;
 | 
					import org.thingsboard.server.gen.transport.TransportProtos.TsKvProto;
 | 
				
			||||||
 | 
					import org.thingsboard.server.gen.transport.TransportProtos.UplinkNotificationMsg;
 | 
				
			||||||
import org.thingsboard.server.service.rpc.RpcSubmitStrategy;
 | 
					import org.thingsboard.server.service.rpc.RpcSubmitStrategy;
 | 
				
			||||||
 | 
					import org.thingsboard.server.service.state.DefaultDeviceStateService;
 | 
				
			||||||
import org.thingsboard.server.service.transport.msg.TransportToDeviceActorMsgWrapper;
 | 
					import org.thingsboard.server.service.transport.msg.TransportToDeviceActorMsgWrapper;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import javax.annotation.Nullable;
 | 
					import javax.annotation.Nullable;
 | 
				
			||||||
@ -173,7 +174,7 @@ public class DeviceActorMessageProcessor extends AbstractContextAwareMsgProcesso
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    private EdgeId findRelatedEdgeId() {
 | 
					    private EdgeId findRelatedEdgeId() {
 | 
				
			||||||
        List<EntityRelation> result =
 | 
					        List<EntityRelation> result =
 | 
				
			||||||
                systemContext.getRelationService().findByToAndType(tenantId, deviceId, EntityRelation.CONTAINS_TYPE, RelationTypeGroup.COMMON);
 | 
					                systemContext.getRelationService().findByToAndType(tenantId, deviceId, EntityRelation.CONTAINS_TYPE, RelationTypeGroup.EDGE);
 | 
				
			||||||
        if (result != null && result.size() > 0) {
 | 
					        if (result != null && result.size() > 0) {
 | 
				
			||||||
            EntityRelation relationToEdge = result.get(0);
 | 
					            EntityRelation relationToEdge = result.get(0);
 | 
				
			||||||
            if (relationToEdge.getFrom() != null && relationToEdge.getFrom().getId() != null) {
 | 
					            if (relationToEdge.getFrom() != null && relationToEdge.getFrom().getId() != null) {
 | 
				
			||||||
@ -212,8 +213,12 @@ public class DeviceActorMessageProcessor extends AbstractContextAwareMsgProcesso
 | 
				
			|||||||
        if (systemContext.isEdgesEnabled() && edgeId != null) {
 | 
					        if (systemContext.isEdgesEnabled() && edgeId != null) {
 | 
				
			||||||
            log.debug("[{}][{}] device is related to edge: [{}]. Saving RPC request: [{}][{}] to edge queue", tenantId, deviceId, edgeId.getId(), rpcId, requestId);
 | 
					            log.debug("[{}][{}] device is related to edge: [{}]. Saving RPC request: [{}][{}] to edge queue", tenantId, deviceId, edgeId.getId(), rpcId, requestId);
 | 
				
			||||||
            try {
 | 
					            try {
 | 
				
			||||||
                saveRpcRequestToEdgeQueue(request, requestId).get();
 | 
					                Optional<AttributeKvEntry> edgeAttributeOpt = systemContext.getAttributesService().find(tenantId, edgeId, DataConstants.SERVER_SCOPE, DefaultDeviceStateService.ACTIVITY_STATE).get();
 | 
				
			||||||
                sent = true;
 | 
					                if (edgeAttributeOpt.isPresent() && edgeAttributeOpt.get().getBooleanValue().orElse(false)) {
 | 
				
			||||||
 | 
					                    saveRpcRequestToEdgeQueue(request, requestId).get();
 | 
				
			||||||
 | 
					                } else {
 | 
				
			||||||
 | 
					                    log.error("[{}][{}][{}] Failed to save RPC request to edge queue {}. The Edge is currently offline or unreachable", tenantId, deviceId, edgeId.getId(), request);
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
            } catch (InterruptedException | ExecutionException e) {
 | 
					            } catch (InterruptedException | ExecutionException e) {
 | 
				
			||||||
                log.error("[{}][{}][{}] Failed to save RPC request to edge queue {}", tenantId, deviceId, edgeId.getId(), request, e);
 | 
					                log.error("[{}][{}][{}] Failed to save RPC request to edge queue {}", tenantId, deviceId, edgeId.getId(), request, e);
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
@ -470,7 +475,7 @@ public class DeviceActorMessageProcessor extends AbstractContextAwareMsgProcesso
 | 
				
			|||||||
        callback.onSuccess();
 | 
					        callback.onSuccess();
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    private void processUplinkNotificationMsg(SessionInfoProto sessionInfo, TransportProtos.UplinkNotificationMsg uplinkNotificationMsg) {
 | 
					    private void processUplinkNotificationMsg(SessionInfoProto sessionInfo, UplinkNotificationMsg uplinkNotificationMsg) {
 | 
				
			||||||
        String nodeId = sessionInfo.getNodeId();
 | 
					        String nodeId = sessionInfo.getNodeId();
 | 
				
			||||||
        sessions.entrySet().stream()
 | 
					        sessions.entrySet().stream()
 | 
				
			||||||
                .filter(kv -> kv.getValue().getSessionInfo().getNodeId().equals(nodeId) && (kv.getValue().isSubscribedToAttributes() || kv.getValue().isSubscribedToRPC()))
 | 
					                .filter(kv -> kv.getValue().getSessionInfo().getNodeId().equals(nodeId) && (kv.getValue().isSubscribedToAttributes() || kv.getValue().isSubscribedToRPC()))
 | 
				
			||||||
 | 
				
			|||||||
@ -16,7 +16,6 @@
 | 
				
			|||||||
package org.thingsboard.server.actors.ruleChain;
 | 
					package org.thingsboard.server.actors.ruleChain;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import lombok.extern.slf4j.Slf4j;
 | 
					import lombok.extern.slf4j.Slf4j;
 | 
				
			||||||
import org.thingsboard.server.common.data.msg.TbNodeConnectionType;
 | 
					 | 
				
			||||||
import org.thingsboard.server.actors.ActorSystemContext;
 | 
					import org.thingsboard.server.actors.ActorSystemContext;
 | 
				
			||||||
import org.thingsboard.server.actors.TbActorCtx;
 | 
					import org.thingsboard.server.actors.TbActorCtx;
 | 
				
			||||||
import org.thingsboard.server.actors.TbActorRef;
 | 
					import org.thingsboard.server.actors.TbActorRef;
 | 
				
			||||||
@ -29,6 +28,7 @@ import org.thingsboard.server.common.data.id.EntityId;
 | 
				
			|||||||
import org.thingsboard.server.common.data.id.RuleChainId;
 | 
					import org.thingsboard.server.common.data.id.RuleChainId;
 | 
				
			||||||
import org.thingsboard.server.common.data.id.RuleNodeId;
 | 
					import org.thingsboard.server.common.data.id.RuleNodeId;
 | 
				
			||||||
import org.thingsboard.server.common.data.id.TenantId;
 | 
					import org.thingsboard.server.common.data.id.TenantId;
 | 
				
			||||||
 | 
					import org.thingsboard.server.common.data.msg.TbNodeConnectionType;
 | 
				
			||||||
import org.thingsboard.server.common.data.plugin.ComponentLifecycleEvent;
 | 
					import org.thingsboard.server.common.data.plugin.ComponentLifecycleEvent;
 | 
				
			||||||
import org.thingsboard.server.common.data.plugin.ComponentLifecycleState;
 | 
					import org.thingsboard.server.common.data.plugin.ComponentLifecycleState;
 | 
				
			||||||
import org.thingsboard.server.common.data.relation.EntityRelation;
 | 
					import org.thingsboard.server.common.data.relation.EntityRelation;
 | 
				
			||||||
 | 
				
			|||||||
@ -477,6 +477,8 @@ public class EdgeGrpcService extends EdgeRpcServiceGrpc.EdgeRpcServiceImplBase i
 | 
				
			|||||||
            TbMsgMetaData md = new TbMsgMetaData();
 | 
					            TbMsgMetaData md = new TbMsgMetaData();
 | 
				
			||||||
            if (!persistToTelemetry) {
 | 
					            if (!persistToTelemetry) {
 | 
				
			||||||
                md.putValue(DataConstants.SCOPE, DataConstants.SERVER_SCOPE);
 | 
					                md.putValue(DataConstants.SCOPE, DataConstants.SERVER_SCOPE);
 | 
				
			||||||
 | 
					                md.putValue("edgeName", edge.getName());
 | 
				
			||||||
 | 
					                md.putValue("edgeType", edge.getType());
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            TbMsg tbMsg = TbMsg.newMsg(msgType, edgeId, md, TbMsgDataType.JSON, data);
 | 
					            TbMsg tbMsg = TbMsg.newMsg(msgType, edgeId, md, TbMsgDataType.JSON, data);
 | 
				
			||||||
            clusterService.pushMsgToRuleEngine(tenantId, edgeId, tbMsg, null);
 | 
					            clusterService.pushMsgToRuleEngine(tenantId, edgeId, tbMsg, null);
 | 
				
			||||||
 | 
				
			|||||||
@ -18,6 +18,7 @@ package org.thingsboard.server.service.edge.rpc.processor.rule;
 | 
				
			|||||||
import lombok.extern.slf4j.Slf4j;
 | 
					import lombok.extern.slf4j.Slf4j;
 | 
				
			||||||
import org.springframework.stereotype.Component;
 | 
					import org.springframework.stereotype.Component;
 | 
				
			||||||
import org.thingsboard.server.common.data.EdgeUtils;
 | 
					import org.thingsboard.server.common.data.EdgeUtils;
 | 
				
			||||||
 | 
					import org.thingsboard.server.common.data.edge.Edge;
 | 
				
			||||||
import org.thingsboard.server.common.data.edge.EdgeEvent;
 | 
					import org.thingsboard.server.common.data.edge.EdgeEvent;
 | 
				
			||||||
import org.thingsboard.server.common.data.id.RuleChainId;
 | 
					import org.thingsboard.server.common.data.id.RuleChainId;
 | 
				
			||||||
import org.thingsboard.server.common.data.rule.RuleChain;
 | 
					import org.thingsboard.server.common.data.rule.RuleChain;
 | 
				
			||||||
@ -53,6 +54,10 @@ public class RuleChainEdgeProcessor extends BaseEdgeProcessor {
 | 
				
			|||||||
                            isRoot = Boolean.parseBoolean(edgeEvent.getBody().get(EDGE_IS_ROOT_BODY_KEY).asText());
 | 
					                            isRoot = Boolean.parseBoolean(edgeEvent.getBody().get(EDGE_IS_ROOT_BODY_KEY).asText());
 | 
				
			||||||
                        } catch (Exception ignored) {}
 | 
					                        } catch (Exception ignored) {}
 | 
				
			||||||
                    }
 | 
					                    }
 | 
				
			||||||
 | 
					                    if (!isRoot) {
 | 
				
			||||||
 | 
					                        Edge edge = edgeService.findEdgeById(edgeEvent.getTenantId(), edgeEvent.getEdgeId());
 | 
				
			||||||
 | 
					                        isRoot = edge.getRootRuleChainId().equals(ruleChainId);
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
                    UpdateMsgType msgType = getUpdateMsgType(edgeEvent.getAction());
 | 
					                    UpdateMsgType msgType = getUpdateMsgType(edgeEvent.getAction());
 | 
				
			||||||
                    RuleChainUpdateMsg ruleChainUpdateMsg = ((RuleChainMsgConstructor)
 | 
					                    RuleChainUpdateMsg ruleChainUpdateMsg = ((RuleChainMsgConstructor)
 | 
				
			||||||
                            ruleChainMsgConstructorFactory.getMsgConstructorByEdgeVersion(edgeVersion))
 | 
					                            ruleChainMsgConstructorFactory.getMsgConstructorByEdgeVersion(edgeVersion))
 | 
				
			||||||
 | 
				
			|||||||
@ -24,7 +24,6 @@ import org.thingsboard.server.common.data.id.TenantId;
 | 
				
			|||||||
import org.thingsboard.server.common.msg.queue.RuleEngineException;
 | 
					import org.thingsboard.server.common.msg.queue.RuleEngineException;
 | 
				
			||||||
import org.thingsboard.server.common.msg.queue.RuleNodeInfo;
 | 
					import org.thingsboard.server.common.msg.queue.RuleNodeInfo;
 | 
				
			||||||
import org.thingsboard.server.common.msg.queue.TbMsgCallback;
 | 
					import org.thingsboard.server.common.msg.queue.TbMsgCallback;
 | 
				
			||||||
import org.thingsboard.server.common.msg.tools.TbRateLimitsException;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
import java.util.UUID;
 | 
					import java.util.UUID;
 | 
				
			||||||
import java.util.concurrent.TimeUnit;
 | 
					import java.util.concurrent.TimeUnit;
 | 
				
			||||||
 | 
				
			|||||||
@ -146,7 +146,7 @@ public class RuleChainEdgeTest extends AbstractEdgeTest {
 | 
				
			|||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    private void createRuleChainMetadata(RuleChain ruleChain) {
 | 
					    private RuleChainMetaData createRuleChainMetadata(RuleChain ruleChain) {
 | 
				
			||||||
        RuleChainMetaData ruleChainMetaData = new RuleChainMetaData();
 | 
					        RuleChainMetaData ruleChainMetaData = new RuleChainMetaData();
 | 
				
			||||||
        ruleChainMetaData.setRuleChainId(ruleChain.getId());
 | 
					        ruleChainMetaData.setRuleChainId(ruleChain.getId());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -182,7 +182,7 @@ public class RuleChainEdgeTest extends AbstractEdgeTest {
 | 
				
			|||||||
        ruleChainMetaData.addConnectionInfo(0, 2, "fail");
 | 
					        ruleChainMetaData.addConnectionInfo(0, 2, "fail");
 | 
				
			||||||
        ruleChainMetaData.addConnectionInfo(1, 2, "success");
 | 
					        ruleChainMetaData.addConnectionInfo(1, 2, "success");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        doPost("/api/ruleChain/metadata", ruleChainMetaData, RuleChainMetaData.class);
 | 
					        return doPost("/api/ruleChain/metadata", ruleChainMetaData, RuleChainMetaData.class);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @Test
 | 
					    @Test
 | 
				
			||||||
@ -193,9 +193,10 @@ public class RuleChainEdgeTest extends AbstractEdgeTest {
 | 
				
			|||||||
        ruleChain.setType(RuleChainType.EDGE);
 | 
					        ruleChain.setType(RuleChainType.EDGE);
 | 
				
			||||||
        RuleChain savedRuleChain = doPost("/api/ruleChain", ruleChain, RuleChain.class);
 | 
					        RuleChain savedRuleChain = doPost("/api/ruleChain", ruleChain, RuleChain.class);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        edgeImitator.expectMessageAmount(1);
 | 
					        edgeImitator.expectMessageAmount(2);
 | 
				
			||||||
        doPost("/api/edge/" + edge.getUuidId()
 | 
					        doPost("/api/edge/" + edge.getUuidId()
 | 
				
			||||||
                + "/ruleChain/" + savedRuleChain.getUuidId(), RuleChain.class);
 | 
					                + "/ruleChain/" + savedRuleChain.getUuidId(), RuleChain.class);
 | 
				
			||||||
 | 
					        RuleChainMetaData metaData = createRuleChainMetadata(savedRuleChain);
 | 
				
			||||||
        Assert.assertTrue(edgeImitator.waitForMessages());
 | 
					        Assert.assertTrue(edgeImitator.waitForMessages());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        // set new rule chain as root
 | 
					        // set new rule chain as root
 | 
				
			||||||
@ -213,6 +214,22 @@ public class RuleChainEdgeTest extends AbstractEdgeTest {
 | 
				
			|||||||
        Assert.assertTrue(ruleChainMsg.isRoot());
 | 
					        Assert.assertTrue(ruleChainMsg.isRoot());
 | 
				
			||||||
        Assert.assertEquals(savedRuleChain.getId(), ruleChainMsg.getId());
 | 
					        Assert.assertEquals(savedRuleChain.getId(), ruleChainMsg.getId());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // update metadata for root rule chain
 | 
				
			||||||
 | 
					        edgeImitator.expectMessageAmount(1);
 | 
				
			||||||
 | 
					        metaData.getNodes().forEach(n -> n.setDebugMode(true));
 | 
				
			||||||
 | 
					        doPost("/api/ruleChain/metadata", metaData, RuleChainMetaData.class);
 | 
				
			||||||
 | 
					        Assert.assertTrue(edgeImitator.waitForMessages());
 | 
				
			||||||
 | 
					        ruleChainUpdateMsgOpt = edgeImitator.findMessageByType(RuleChainUpdateMsg.class);
 | 
				
			||||||
 | 
					        Assert.assertTrue(ruleChainUpdateMsgOpt.isPresent());
 | 
				
			||||||
 | 
					        ruleChainUpdateMsg = ruleChainUpdateMsgOpt.get();
 | 
				
			||||||
 | 
					        ruleChainMsg = JacksonUtil.fromString(ruleChainUpdateMsg.getEntity(), RuleChain.class, true);
 | 
				
			||||||
 | 
					        Assert.assertNotNull(ruleChainMsg);
 | 
				
			||||||
 | 
					        Assert.assertTrue(UpdateMsgType.ENTITY_CREATED_RPC_MESSAGE.equals(ruleChainUpdateMsg.getMsgType()) ||
 | 
				
			||||||
 | 
					                UpdateMsgType.ENTITY_UPDATED_RPC_MESSAGE.equals(ruleChainUpdateMsg.getMsgType()));
 | 
				
			||||||
 | 
					        Assert.assertEquals(savedRuleChain.getId(), ruleChainMsg.getId());
 | 
				
			||||||
 | 
					        Assert.assertEquals(savedRuleChain.getName(), ruleChainMsg.getName());
 | 
				
			||||||
 | 
					        Assert.assertTrue(ruleChainMsg.isRoot());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        // revert root rule chain
 | 
					        // revert root rule chain
 | 
				
			||||||
        edgeImitator.expectMessageAmount(1);
 | 
					        edgeImitator.expectMessageAmount(1);
 | 
				
			||||||
        doPost("/api/edge/" + edge.getUuidId()
 | 
					        doPost("/api/edge/" + edge.getUuidId()
 | 
				
			||||||
 | 
				
			|||||||
@ -15,7 +15,6 @@
 | 
				
			|||||||
 */
 | 
					 */
 | 
				
			||||||
package org.thingsboard.server.service.edge.rpc.constructor;
 | 
					package org.thingsboard.server.service.edge.rpc.constructor;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import com.fasterxml.jackson.core.JsonProcessingException;
 | 
					 | 
				
			||||||
import com.fasterxml.jackson.databind.JsonNode;
 | 
					import com.fasterxml.jackson.databind.JsonNode;
 | 
				
			||||||
import lombok.extern.slf4j.Slf4j;
 | 
					import lombok.extern.slf4j.Slf4j;
 | 
				
			||||||
import org.junit.Assert;
 | 
					import org.junit.Assert;
 | 
				
			||||||
@ -61,7 +60,7 @@ public class RuleChainMsgConstructorTest {
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @Test
 | 
					    @Test
 | 
				
			||||||
    public void testConstructRuleChainMetadataUpdatedMsg_V_3_4_0() throws JsonProcessingException {
 | 
					    public void testConstructRuleChainMetadataUpdatedMsg_V_3_4_0() {
 | 
				
			||||||
        RuleChainId ruleChainId = new RuleChainId(UUID.randomUUID());
 | 
					        RuleChainId ruleChainId = new RuleChainId(UUID.randomUUID());
 | 
				
			||||||
        RuleChainMetaData ruleChainMetaData = createRuleChainMetaData(
 | 
					        RuleChainMetaData ruleChainMetaData = createRuleChainMetaData(
 | 
				
			||||||
                ruleChainId, 3, createRuleNodes(ruleChainId), createConnections());
 | 
					                ruleChainId, 3, createRuleNodes(ruleChainId), createConnections());
 | 
				
			||||||
@ -80,7 +79,7 @@ public class RuleChainMsgConstructorTest {
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @Test
 | 
					    @Test
 | 
				
			||||||
    public void testConstructRuleChainMetadataUpdatedMsg_V_3_3_3() throws JsonProcessingException {
 | 
					    public void testConstructRuleChainMetadataUpdatedMsg_V_3_3_3() {
 | 
				
			||||||
        RuleChainId ruleChainId = new RuleChainId(UUID.randomUUID());
 | 
					        RuleChainId ruleChainId = new RuleChainId(UUID.randomUUID());
 | 
				
			||||||
        RuleChainMetaData ruleChainMetaData = createRuleChainMetaData(
 | 
					        RuleChainMetaData ruleChainMetaData = createRuleChainMetaData(
 | 
				
			||||||
                ruleChainId, 3, createRuleNodes(ruleChainId), createConnections());
 | 
					                ruleChainId, 3, createRuleNodes(ruleChainId), createConnections());
 | 
				
			||||||
@ -120,7 +119,7 @@ public class RuleChainMsgConstructorTest {
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @Test
 | 
					    @Test
 | 
				
			||||||
    public void testConstructRuleChainMetadataUpdatedMsg_V_3_3_0() throws JsonProcessingException {
 | 
					    public void testConstructRuleChainMetadataUpdatedMsg_V_3_3_0() {
 | 
				
			||||||
        RuleChainId ruleChainId = new RuleChainId(UUID.randomUUID());
 | 
					        RuleChainId ruleChainId = new RuleChainId(UUID.randomUUID());
 | 
				
			||||||
        RuleChainMetaData ruleChainMetaData = createRuleChainMetaData(ruleChainId, 3, createRuleNodes(ruleChainId), createConnections());
 | 
					        RuleChainMetaData ruleChainMetaData = createRuleChainMetaData(ruleChainId, 3, createRuleNodes(ruleChainId), createConnections());
 | 
				
			||||||
        RuleChainMetadataUpdateMsg ruleChainMetadataUpdateMsg =
 | 
					        RuleChainMetadataUpdateMsg ruleChainMetadataUpdateMsg =
 | 
				
			||||||
@ -161,7 +160,7 @@ public class RuleChainMsgConstructorTest {
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @Test
 | 
					    @Test
 | 
				
			||||||
    public void testConstructRuleChainMetadataUpdatedMsg_V_3_3_0_inDifferentOrder() throws JsonProcessingException {
 | 
					    public void testConstructRuleChainMetadataUpdatedMsg_V_3_3_0_inDifferentOrder() {
 | 
				
			||||||
        // same rule chain metadata, but different order of rule nodes
 | 
					        // same rule chain metadata, but different order of rule nodes
 | 
				
			||||||
        RuleChainId ruleChainId = new RuleChainId(UUID.randomUUID());
 | 
					        RuleChainId ruleChainId = new RuleChainId(UUID.randomUUID());
 | 
				
			||||||
        RuleChainMetaData ruleChainMetaData1 = createRuleChainMetaData(ruleChainId, 8, createRuleNodesInDifferentOrder(ruleChainId), createConnectionsInDifferentOrder());
 | 
					        RuleChainMetaData ruleChainMetaData1 = createRuleChainMetaData(ruleChainId, 8, createRuleNodesInDifferentOrder(ruleChainId), createConnectionsInDifferentOrder());
 | 
				
			||||||
@ -254,7 +253,7 @@ public class RuleChainMsgConstructorTest {
 | 
				
			|||||||
        return result;
 | 
					        return result;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    private List<RuleNode> createRuleNodes(RuleChainId ruleChainId) throws JsonProcessingException {
 | 
					    private List<RuleNode> createRuleNodes(RuleChainId ruleChainId) {
 | 
				
			||||||
        List<RuleNode> result = new ArrayList<>();
 | 
					        List<RuleNode> result = new ArrayList<>();
 | 
				
			||||||
        result.add(getOutputNode(ruleChainId));
 | 
					        result.add(getOutputNode(ruleChainId));
 | 
				
			||||||
        result.add(getAcknowledgeNode(ruleChainId));
 | 
					        result.add(getAcknowledgeNode(ruleChainId));
 | 
				
			||||||
@ -301,7 +300,7 @@ public class RuleChainMsgConstructorTest {
 | 
				
			|||||||
        return result;
 | 
					        return result;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    private List<RuleNode> createRuleNodesInDifferentOrder(RuleChainId ruleChainId) throws JsonProcessingException {
 | 
					    private List<RuleNode> createRuleNodesInDifferentOrder(RuleChainId ruleChainId) {
 | 
				
			||||||
        List<RuleNode> result = new ArrayList<>();
 | 
					        List<RuleNode> result = new ArrayList<>();
 | 
				
			||||||
        result.add(getPushToAnalyticsNode(ruleChainId));
 | 
					        result.add(getPushToAnalyticsNode(ruleChainId));
 | 
				
			||||||
        result.add(getPushToCloudNode(ruleChainId));
 | 
					        result.add(getPushToCloudNode(ruleChainId));
 | 
				
			||||||
@ -319,99 +318,99 @@ public class RuleChainMsgConstructorTest {
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    private RuleNode getOutputNode(RuleChainId ruleChainId) throws JsonProcessingException {
 | 
					    private RuleNode getOutputNode(RuleChainId ruleChainId) {
 | 
				
			||||||
        return createRuleNode(ruleChainId,
 | 
					        return createRuleNode(ruleChainId,
 | 
				
			||||||
                "org.thingsboard.rule.engine.flow.TbRuleChainOutputNode",
 | 
					                "org.thingsboard.rule.engine.flow.TbRuleChainOutputNode",
 | 
				
			||||||
                "Output node",
 | 
					                "Output node",
 | 
				
			||||||
                JacksonUtil.OBJECT_MAPPER.readTree("{\"version\":0}"),
 | 
					                JacksonUtil.toJsonNode("{\"version\":0}"),
 | 
				
			||||||
                JacksonUtil.OBJECT_MAPPER.readTree("{\"description\":\"\",\"layoutX\":178,\"layoutY\":592}"));
 | 
					                JacksonUtil.toJsonNode("{\"description\":\"\",\"layoutX\":178,\"layoutY\":592}"));
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    private RuleNode getCheckpointNode(RuleChainId ruleChainId) throws JsonProcessingException {
 | 
					    private RuleNode getCheckpointNode(RuleChainId ruleChainId) {
 | 
				
			||||||
        return createRuleNode(ruleChainId,
 | 
					        return createRuleNode(ruleChainId,
 | 
				
			||||||
                "org.thingsboard.rule.engine.flow.TbCheckpointNode",
 | 
					                "org.thingsboard.rule.engine.flow.TbCheckpointNode",
 | 
				
			||||||
                "Checkpoint node",
 | 
					                "Checkpoint node",
 | 
				
			||||||
                JacksonUtil.OBJECT_MAPPER.readTree("{\"queueName\":\"HighPriority\"}"),
 | 
					                JacksonUtil.toJsonNode("{\"queueName\":\"HighPriority\"}"),
 | 
				
			||||||
                JacksonUtil.OBJECT_MAPPER.readTree("{\"description\":\"\",\"layoutX\":178,\"layoutY\":647}"));
 | 
					                JacksonUtil.toJsonNode("{\"description\":\"\",\"layoutX\":178,\"layoutY\":647}"));
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    private RuleNode getSaveTimeSeriesNode(RuleChainId ruleChainId) throws JsonProcessingException {
 | 
					    private RuleNode getSaveTimeSeriesNode(RuleChainId ruleChainId) {
 | 
				
			||||||
        return createRuleNode(ruleChainId,
 | 
					        return createRuleNode(ruleChainId,
 | 
				
			||||||
                "org.thingsboard.rule.engine.telemetry.TbMsgTimeseriesNode",
 | 
					                "org.thingsboard.rule.engine.telemetry.TbMsgTimeseriesNode",
 | 
				
			||||||
                "Save Timeseries",
 | 
					                "Save Timeseries",
 | 
				
			||||||
                JacksonUtil.OBJECT_MAPPER.readTree("{\"defaultTTL\":0}"),
 | 
					                JacksonUtil.toJsonNode("{\"defaultTTL\":0}"),
 | 
				
			||||||
                JacksonUtil.OBJECT_MAPPER.readTree("{\"layoutX\":823,\"layoutY\":157}"));
 | 
					                JacksonUtil.toJsonNode("{\"layoutX\":823,\"layoutY\":157}"));
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    private RuleNode getMessageTypeSwitchNode(RuleChainId ruleChainId) throws JsonProcessingException {
 | 
					    private RuleNode getMessageTypeSwitchNode(RuleChainId ruleChainId) {
 | 
				
			||||||
        return createRuleNode(ruleChainId,
 | 
					        return createRuleNode(ruleChainId,
 | 
				
			||||||
                "org.thingsboard.rule.engine.filter.TbMsgTypeSwitchNode",
 | 
					                "org.thingsboard.rule.engine.filter.TbMsgTypeSwitchNode",
 | 
				
			||||||
                "Message Type Switch",
 | 
					                "Message Type Switch",
 | 
				
			||||||
                JacksonUtil.OBJECT_MAPPER.readTree("{\"version\":0}"),
 | 
					                JacksonUtil.toJsonNode("{\"version\":0}"),
 | 
				
			||||||
                JacksonUtil.OBJECT_MAPPER.readTree("{\"layoutX\":347,\"layoutY\":149}"));
 | 
					                JacksonUtil.toJsonNode("{\"layoutX\":347,\"layoutY\":149}"));
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    private RuleNode getLogOtherNode(RuleChainId ruleChainId) throws JsonProcessingException {
 | 
					    private RuleNode getLogOtherNode(RuleChainId ruleChainId) {
 | 
				
			||||||
        return createRuleNode(ruleChainId,
 | 
					        return createRuleNode(ruleChainId,
 | 
				
			||||||
                "org.thingsboard.rule.engine.action.TbLogNode",
 | 
					                "org.thingsboard.rule.engine.action.TbLogNode",
 | 
				
			||||||
                "Log Other",
 | 
					                "Log Other",
 | 
				
			||||||
                JacksonUtil.OBJECT_MAPPER.readTree("{\"jsScript\":\"return '\\\\nIncoming message:\\\\n' + JSON.stringify(msg) + '\\\\nIncoming metadata:\\\\n' + JSON.stringify(metadata);\"}"),
 | 
					                JacksonUtil.toJsonNode("{\"jsScript\":\"return '\\\\nIncoming message:\\\\n' + JSON.stringify(msg) + '\\\\nIncoming metadata:\\\\n' + JSON.stringify(metadata);\"}"),
 | 
				
			||||||
                JacksonUtil.OBJECT_MAPPER.readTree("{\"layoutX\":824,\"layoutY\":378}"));
 | 
					                JacksonUtil.toJsonNode("{\"layoutX\":824,\"layoutY\":378}"));
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    private RuleNode getPushToCloudNode(RuleChainId ruleChainId) throws JsonProcessingException {
 | 
					    private RuleNode getPushToCloudNode(RuleChainId ruleChainId) {
 | 
				
			||||||
        return createRuleNode(ruleChainId,
 | 
					        return createRuleNode(ruleChainId,
 | 
				
			||||||
                "org.thingsboard.rule.engine.edge.TbMsgPushToCloudNode",
 | 
					                "org.thingsboard.rule.engine.edge.TbMsgPushToCloudNode",
 | 
				
			||||||
                "Push to cloud",
 | 
					                "Push to cloud",
 | 
				
			||||||
                JacksonUtil.OBJECT_MAPPER.readTree("{\"scope\":\"SERVER_SCOPE\"}"),
 | 
					                JacksonUtil.toJsonNode("{\"scope\":\"SERVER_SCOPE\"}"),
 | 
				
			||||||
                JacksonUtil.OBJECT_MAPPER.readTree("{\"layoutX\":1129,\"layoutY\":52}"));
 | 
					                JacksonUtil.toJsonNode("{\"layoutX\":1129,\"layoutY\":52}"));
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    private RuleNode getAcknowledgeNode(RuleChainId ruleChainId) throws JsonProcessingException {
 | 
					    private RuleNode getAcknowledgeNode(RuleChainId ruleChainId) {
 | 
				
			||||||
        return createRuleNode(ruleChainId,
 | 
					        return createRuleNode(ruleChainId,
 | 
				
			||||||
                "org.thingsboard.rule.engine.flow.TbAckNode",
 | 
					                "org.thingsboard.rule.engine.flow.TbAckNode",
 | 
				
			||||||
                "Acknowledge node",
 | 
					                "Acknowledge node",
 | 
				
			||||||
                JacksonUtil.OBJECT_MAPPER.readTree("{\"version\":0}"),
 | 
					                JacksonUtil.toJsonNode("{\"version\":0}"),
 | 
				
			||||||
                JacksonUtil.OBJECT_MAPPER.readTree("{\"description\":\"\",\"layoutX\":177,\"layoutY\":703}"));
 | 
					                JacksonUtil.toJsonNode("{\"description\":\"\",\"layoutX\":177,\"layoutY\":703}"));
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    private RuleNode getDeviceProfileNode(RuleChainId ruleChainId) throws JsonProcessingException {
 | 
					    private RuleNode getDeviceProfileNode(RuleChainId ruleChainId) {
 | 
				
			||||||
        return createRuleNode(ruleChainId,
 | 
					        return createRuleNode(ruleChainId,
 | 
				
			||||||
                "org.thingsboard.rule.engine.profile.TbDeviceProfileNode",
 | 
					                "org.thingsboard.rule.engine.profile.TbDeviceProfileNode",
 | 
				
			||||||
                "Device Profile Node",
 | 
					                "Device Profile Node",
 | 
				
			||||||
                JacksonUtil.OBJECT_MAPPER.readTree("{\"persistAlarmRulesState\":false,\"fetchAlarmRulesStateOnStart\":false}"),
 | 
					                JacksonUtil.toJsonNode("{\"persistAlarmRulesState\":false,\"fetchAlarmRulesStateOnStart\":false}"),
 | 
				
			||||||
                JacksonUtil.OBJECT_MAPPER.readTree("{\"description\":\"Process incoming messages from devices with the alarm rules defined in the device profile. Dispatch all incoming messages with \\\"Success\\\" relation type.\",\"layoutX\":187,\"layoutY\":468}"));
 | 
					                JacksonUtil.toJsonNode("{\"description\":\"Process incoming messages from devices with the alarm rules defined in the device profile. Dispatch all incoming messages with \\\"Success\\\" relation type.\",\"layoutX\":187,\"layoutY\":468}"));
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    private RuleNode getSaveClientAttributesNode(RuleChainId ruleChainId) throws JsonProcessingException {
 | 
					    private RuleNode getSaveClientAttributesNode(RuleChainId ruleChainId) {
 | 
				
			||||||
        return createRuleNode(ruleChainId,
 | 
					        return createRuleNode(ruleChainId,
 | 
				
			||||||
                "org.thingsboard.rule.engine.telemetry.TbMsgAttributesNode",
 | 
					                "org.thingsboard.rule.engine.telemetry.TbMsgAttributesNode",
 | 
				
			||||||
                "Save Client Attributes",
 | 
					                "Save Client Attributes",
 | 
				
			||||||
                JacksonUtil.OBJECT_MAPPER.readTree("{\"scope\":\"CLIENT_SCOPE\"}"),
 | 
					                JacksonUtil.toJsonNode("{\"scope\":\"CLIENT_SCOPE\"}"),
 | 
				
			||||||
                JacksonUtil.OBJECT_MAPPER.readTree("{\"layoutX\":824,\"layoutY\":52}"));
 | 
					                JacksonUtil.toJsonNode("{\"layoutX\":824,\"layoutY\":52}"));
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    private RuleNode getLogRpcFromDeviceNode(RuleChainId ruleChainId) throws JsonProcessingException {
 | 
					    private RuleNode getLogRpcFromDeviceNode(RuleChainId ruleChainId) {
 | 
				
			||||||
        return createRuleNode(ruleChainId,
 | 
					        return createRuleNode(ruleChainId,
 | 
				
			||||||
                "org.thingsboard.rule.engine.action.TbLogNode",
 | 
					                "org.thingsboard.rule.engine.action.TbLogNode",
 | 
				
			||||||
                "Log RPC from Device",
 | 
					                "Log RPC from Device",
 | 
				
			||||||
                JacksonUtil.OBJECT_MAPPER.readTree("{\"jsScript\":\"return '\\\\nIncoming message:\\\\n' + JSON.stringify(msg) + '\\\\nIncoming metadata:\\\\n' + JSON.stringify(metadata);\"}"),
 | 
					                JacksonUtil.toJsonNode("{\"jsScript\":\"return '\\\\nIncoming message:\\\\n' + JSON.stringify(msg) + '\\\\nIncoming metadata:\\\\n' + JSON.stringify(metadata);\"}"),
 | 
				
			||||||
                JacksonUtil.OBJECT_MAPPER.readTree("{\"layoutX\":825,\"layoutY\":266}"));
 | 
					                JacksonUtil.toJsonNode("{\"layoutX\":825,\"layoutY\":266}"));
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    private RuleNode getRpcCallRequestNode(RuleChainId ruleChainId) throws JsonProcessingException {
 | 
					    private RuleNode getRpcCallRequestNode(RuleChainId ruleChainId) {
 | 
				
			||||||
        return createRuleNode(ruleChainId,
 | 
					        return createRuleNode(ruleChainId,
 | 
				
			||||||
                "org.thingsboard.rule.engine.rpc.TbSendRPCRequestNode",
 | 
					                "org.thingsboard.rule.engine.rpc.TbSendRPCRequestNode",
 | 
				
			||||||
                "RPC Call Request",
 | 
					                "RPC Call Request",
 | 
				
			||||||
                JacksonUtil.OBJECT_MAPPER.readTree("{\"timeoutInSeconds\":60}"),
 | 
					                JacksonUtil.toJsonNode("{\"timeoutInSeconds\":60}"),
 | 
				
			||||||
                JacksonUtil.OBJECT_MAPPER.readTree("{\"layoutX\":824,\"layoutY\":466}"));
 | 
					                JacksonUtil.toJsonNode("{\"layoutX\":824,\"layoutY\":466}"));
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    private RuleNode getPushToAnalyticsNode(RuleChainId ruleChainId) throws JsonProcessingException {
 | 
					    private RuleNode getPushToAnalyticsNode(RuleChainId ruleChainId) {
 | 
				
			||||||
        return createRuleNode(ruleChainId,
 | 
					        return createRuleNode(ruleChainId,
 | 
				
			||||||
                "org.thingsboard.rule.engine.flow.TbRuleChainInputNode",
 | 
					                "org.thingsboard.rule.engine.flow.TbRuleChainInputNode",
 | 
				
			||||||
                "Push to Analytics",
 | 
					                "Push to Analytics",
 | 
				
			||||||
                JacksonUtil.OBJECT_MAPPER.readTree("{\"ruleChainId\":\"af588000-6c7c-11ec-bafd-c9a47a5c8d99\"}"),
 | 
					                JacksonUtil.toJsonNode("{\"ruleChainId\":\"af588000-6c7c-11ec-bafd-c9a47a5c8d99\"}"),
 | 
				
			||||||
                JacksonUtil.OBJECT_MAPPER.readTree("{\"description\":\"\",\"layoutX\":477,\"layoutY\":560}"));
 | 
					                JacksonUtil.toJsonNode("{\"description\":\"\",\"layoutX\":477,\"layoutY\":560}"));
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -40,9 +40,9 @@ import org.thingsboard.server.common.data.notification.rule.trigger.config.Alarm
 | 
				
			|||||||
import org.thingsboard.server.common.data.notification.rule.trigger.config.ApiUsageLimitNotificationRuleTriggerConfig;
 | 
					import org.thingsboard.server.common.data.notification.rule.trigger.config.ApiUsageLimitNotificationRuleTriggerConfig;
 | 
				
			||||||
import org.thingsboard.server.common.data.notification.rule.trigger.config.DeviceActivityNotificationRuleTriggerConfig;
 | 
					import org.thingsboard.server.common.data.notification.rule.trigger.config.DeviceActivityNotificationRuleTriggerConfig;
 | 
				
			||||||
import org.thingsboard.server.common.data.notification.rule.trigger.config.DeviceActivityNotificationRuleTriggerConfig.DeviceEvent;
 | 
					import org.thingsboard.server.common.data.notification.rule.trigger.config.DeviceActivityNotificationRuleTriggerConfig.DeviceEvent;
 | 
				
			||||||
 | 
					import org.thingsboard.server.common.data.notification.rule.trigger.config.EdgeCommunicationFailureNotificationRuleTriggerConfig;
 | 
				
			||||||
import org.thingsboard.server.common.data.notification.rule.trigger.config.EdgeConnectionNotificationRuleTriggerConfig;
 | 
					import org.thingsboard.server.common.data.notification.rule.trigger.config.EdgeConnectionNotificationRuleTriggerConfig;
 | 
				
			||||||
import org.thingsboard.server.common.data.notification.rule.trigger.config.EdgeConnectionNotificationRuleTriggerConfig.EdgeConnectivityEvent;
 | 
					import org.thingsboard.server.common.data.notification.rule.trigger.config.EdgeConnectionNotificationRuleTriggerConfig.EdgeConnectivityEvent;
 | 
				
			||||||
import org.thingsboard.server.common.data.notification.rule.trigger.config.EdgeCommunicationFailureNotificationRuleTriggerConfig;
 | 
					 | 
				
			||||||
import org.thingsboard.server.common.data.notification.rule.trigger.config.EntitiesLimitNotificationRuleTriggerConfig;
 | 
					import org.thingsboard.server.common.data.notification.rule.trigger.config.EntitiesLimitNotificationRuleTriggerConfig;
 | 
				
			||||||
import org.thingsboard.server.common.data.notification.rule.trigger.config.EntityActionNotificationRuleTriggerConfig;
 | 
					import org.thingsboard.server.common.data.notification.rule.trigger.config.EntityActionNotificationRuleTriggerConfig;
 | 
				
			||||||
import org.thingsboard.server.common.data.notification.rule.trigger.config.NewPlatformVersionNotificationRuleTriggerConfig;
 | 
					import org.thingsboard.server.common.data.notification.rule.trigger.config.NewPlatformVersionNotificationRuleTriggerConfig;
 | 
				
			||||||
@ -347,7 +347,7 @@ public class DefaultNotifications {
 | 
				
			|||||||
    public static final DefaultNotification edgeCommunicationFailures = DefaultNotification.builder()
 | 
					    public static final DefaultNotification edgeCommunicationFailures = DefaultNotification.builder()
 | 
				
			||||||
            .name("Edge communication failure notification")
 | 
					            .name("Edge communication failure notification")
 | 
				
			||||||
            .type(NotificationType.EDGE_COMMUNICATION_FAILURE)
 | 
					            .type(NotificationType.EDGE_COMMUNICATION_FAILURE)
 | 
				
			||||||
            .subject("Edge '${edgeName}' communication failure occured")
 | 
					            .subject("Edge '${edgeName}' communication failure occurred")
 | 
				
			||||||
            .text("Failure message: '${failureMsg}'")
 | 
					            .text("Failure message: '${failureMsg}'")
 | 
				
			||||||
            .icon("error").color(RED_COLOR)
 | 
					            .icon("error").color(RED_COLOR)
 | 
				
			||||||
            .button("Go to Edge").link("/edgeManagement/instances/${edgeId}")
 | 
					            .button("Go to Edge").link("/edgeManagement/instances/${edgeId}")
 | 
				
			||||||
 | 
				
			|||||||
@ -525,12 +525,11 @@ public class RestClient implements Closeable {
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public PageData<AlarmCommentInfo> getAlarmComments(AlarmId alarmId, PageLink pageLink) {
 | 
					    public PageData<AlarmCommentInfo> getAlarmComments(AlarmId alarmId, PageLink pageLink) {
 | 
				
			||||||
        String urlSecondPart = "/api/alarm/{alarmId}/comment";
 | 
					 | 
				
			||||||
        Map<String, String> params = new HashMap<>();
 | 
					        Map<String, String> params = new HashMap<>();
 | 
				
			||||||
        params.put("alarmId", alarmId.getId().toString());
 | 
					        params.put("alarmId", alarmId.getId().toString());
 | 
				
			||||||
 | 
					        addPageLinkToParam(params, pageLink);
 | 
				
			||||||
        return restTemplate.exchange(
 | 
					        return restTemplate.exchange(
 | 
				
			||||||
                baseURL + urlSecondPart + "&" + getUrlParams(pageLink),
 | 
					                baseURL + "/api/alarm/{alarmId}/comment?" + getUrlParams(pageLink),
 | 
				
			||||||
                HttpMethod.GET,
 | 
					                HttpMethod.GET,
 | 
				
			||||||
                HttpEntity.EMPTY,
 | 
					                HttpEntity.EMPTY,
 | 
				
			||||||
                new ParameterizedTypeReference<PageData<AlarmCommentInfo>>() {
 | 
					                new ParameterizedTypeReference<PageData<AlarmCommentInfo>>() {
 | 
				
			||||||
 | 
				
			|||||||
@ -25,6 +25,7 @@ import org.thingsboard.server.common.data.id.AlarmId;
 | 
				
			|||||||
import org.thingsboard.server.common.data.id.AssetId;
 | 
					import org.thingsboard.server.common.data.id.AssetId;
 | 
				
			||||||
import org.thingsboard.server.common.data.id.CustomerId;
 | 
					import org.thingsboard.server.common.data.id.CustomerId;
 | 
				
			||||||
import org.thingsboard.server.common.data.id.DeviceId;
 | 
					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.EntityId;
 | 
				
			||||||
import org.thingsboard.server.common.data.id.EntityViewId;
 | 
					import org.thingsboard.server.common.data.id.EntityViewId;
 | 
				
			||||||
import org.thingsboard.server.common.data.id.RuleChainId;
 | 
					import org.thingsboard.server.common.data.id.RuleChainId;
 | 
				
			||||||
@ -63,6 +64,9 @@ public class EntitiesFieldsAsyncLoader {
 | 
				
			|||||||
            case ENTITY_VIEW:
 | 
					            case ENTITY_VIEW:
 | 
				
			||||||
                return toEntityFieldsDataAsync(ctx.getEntityViewService().findEntityViewByIdAsync(ctx.getTenantId(), (EntityViewId) originatorId),
 | 
					                return toEntityFieldsDataAsync(ctx.getEntityViewService().findEntityViewByIdAsync(ctx.getTenantId(), (EntityViewId) originatorId),
 | 
				
			||||||
                        EntityFieldsData::new, ctx);
 | 
					                        EntityFieldsData::new, ctx);
 | 
				
			||||||
 | 
					            case EDGE:
 | 
				
			||||||
 | 
					                return toEntityFieldsDataAsync(ctx.getEdgeService().findEdgeByIdAsync(ctx.getTenantId(), (EdgeId) originatorId),
 | 
				
			||||||
 | 
					                        EntityFieldsData::new, ctx);
 | 
				
			||||||
            default:
 | 
					            default:
 | 
				
			||||||
                return Futures.immediateFailedFuture(new TbNodeException("Unexpected originator EntityType: " + originatorId.getEntityType()));
 | 
					                return Futures.immediateFailedFuture(new TbNodeException("Unexpected originator EntityType: " + originatorId.getEntityType()));
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user