diff --git a/application/src/main/java/org/thingsboard/server/actors/ActorSystemContext.java b/application/src/main/java/org/thingsboard/server/actors/ActorSystemContext.java index 9b108e9b8a..c43b643045 100644 --- a/application/src/main/java/org/thingsboard/server/actors/ActorSystemContext.java +++ b/application/src/main/java/org/thingsboard/server/actors/ActorSystemContext.java @@ -335,6 +335,9 @@ public class ActorSystemContext { @Getter private long statisticsPersistFrequency; + @Value("${edges.rpc.enabled}") + @Getter + private boolean edgesRpcEnabled; @Scheduled(fixedDelayString = "${actors.statistics.js_print_interval_ms}") public void printStats() { diff --git a/application/src/main/java/org/thingsboard/server/actors/app/AppActor.java b/application/src/main/java/org/thingsboard/server/actors/app/AppActor.java index ba8654854c..3f938e5003 100644 --- a/application/src/main/java/org/thingsboard/server/actors/app/AppActor.java +++ b/application/src/main/java/org/thingsboard/server/actors/app/AppActor.java @@ -89,7 +89,9 @@ public class AppActor extends ContextAwareActor { case DEVICE_ATTRIBUTES_UPDATE_TO_DEVICE_ACTOR_MSG: case DEVICE_CREDENTIALS_UPDATE_TO_DEVICE_ACTOR_MSG: case DEVICE_NAME_OR_TYPE_UPDATE_TO_DEVICE_ACTOR_MSG: + case DEVICE_EDGE_UPDATE_TO_DEVICE_ACTOR_MSG: case DEVICE_RPC_REQUEST_TO_DEVICE_ACTOR_MSG: + case DEVICE_RPC_RESPONSE_TO_DEVICE_ACTOR_MSG: case SERVER_RPC_RESPONSE_TO_DEVICE_ACTOR_MSG: onToDeviceActorMsg((TenantAwareMsg) msg, true); break; diff --git a/application/src/main/java/org/thingsboard/server/actors/device/DeviceActor.java b/application/src/main/java/org/thingsboard/server/actors/device/DeviceActor.java index feecef859f..9662db46c1 100644 --- a/application/src/main/java/org/thingsboard/server/actors/device/DeviceActor.java +++ b/application/src/main/java/org/thingsboard/server/actors/device/DeviceActor.java @@ -17,6 +17,7 @@ package org.thingsboard.server.actors.device; import lombok.extern.slf4j.Slf4j; import org.thingsboard.rule.engine.api.msg.DeviceAttributesEventNotificationMsg; +import org.thingsboard.rule.engine.api.msg.DeviceEdgeUpdateMsg; import org.thingsboard.rule.engine.api.msg.DeviceNameOrTypeUpdateMsg; import org.thingsboard.server.actors.ActorSystemContext; import org.thingsboard.server.actors.TbActorCtx; @@ -26,6 +27,7 @@ import org.thingsboard.server.common.data.id.DeviceId; import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.common.msg.TbActorMsg; import org.thingsboard.server.common.msg.timeout.DeviceActorServerSideRpcTimeoutMsg; +import org.thingsboard.server.service.rpc.FromDeviceRpcResponseActorMsg; import org.thingsboard.server.service.rpc.ToDeviceRpcRequestActorMsg; import org.thingsboard.server.service.transport.msg.TransportToDeviceActorMsgWrapper; @@ -70,12 +72,18 @@ public class DeviceActor extends ContextAwareActor { case DEVICE_RPC_REQUEST_TO_DEVICE_ACTOR_MSG: processor.processRpcRequest(ctx, (ToDeviceRpcRequestActorMsg) msg); break; + case DEVICE_RPC_RESPONSE_TO_DEVICE_ACTOR_MSG: + processor.processRpcResponsesFromEdge(ctx, (FromDeviceRpcResponseActorMsg) msg); + break; case DEVICE_ACTOR_SERVER_SIDE_RPC_TIMEOUT_MSG: processor.processServerSideRpcTimeout(ctx, (DeviceActorServerSideRpcTimeoutMsg) msg); break; case SESSION_TIMEOUT_MSG: processor.checkSessionsTimeout(); break; + case DEVICE_EDGE_UPDATE_TO_DEVICE_ACTOR_MSG: + processor.processEdgeUpdate((DeviceEdgeUpdateMsg) msg); + break; default: return false; } diff --git a/application/src/main/java/org/thingsboard/server/actors/device/DeviceActorMessageProcessor.java b/application/src/main/java/org/thingsboard/server/actors/device/DeviceActorMessageProcessor.java index cf4aa3edda..4589640575 100644 --- a/application/src/main/java/org/thingsboard/server/actors/device/DeviceActorMessageProcessor.java +++ b/application/src/main/java/org/thingsboard/server/actors/device/DeviceActorMessageProcessor.java @@ -15,6 +15,7 @@ */ package org.thingsboard.server.actors.device; +import com.fasterxml.jackson.databind.node.ObjectNode; import com.google.common.util.concurrent.FutureCallback; import com.google.common.util.concurrent.Futures; import com.google.common.util.concurrent.ListenableFuture; @@ -24,17 +25,24 @@ import lombok.extern.slf4j.Slf4j; import org.apache.commons.collections.CollectionUtils; import org.thingsboard.rule.engine.api.RpcError; import org.thingsboard.rule.engine.api.msg.DeviceAttributesEventNotificationMsg; +import org.thingsboard.rule.engine.api.msg.DeviceEdgeUpdateMsg; import org.thingsboard.rule.engine.api.msg.DeviceNameOrTypeUpdateMsg; import org.thingsboard.server.actors.ActorSystemContext; import org.thingsboard.server.actors.TbActorCtx; import org.thingsboard.server.actors.shared.AbstractContextAwareMsgProcessor; import org.thingsboard.server.common.data.DataConstants; import org.thingsboard.server.common.data.Device; +import org.thingsboard.server.common.data.edge.EdgeEvent; +import org.thingsboard.server.common.data.edge.EdgeEventActionType; +import org.thingsboard.server.common.data.edge.EdgeEventType; import org.thingsboard.server.common.data.id.DeviceId; +import org.thingsboard.server.common.data.id.EdgeId; import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.common.data.kv.AttributeKey; import org.thingsboard.server.common.data.kv.AttributeKvEntry; import org.thingsboard.server.common.data.kv.KvEntry; +import org.thingsboard.server.common.data.relation.EntityRelation; +import org.thingsboard.server.common.data.relation.RelationTypeGroup; import org.thingsboard.server.common.data.rpc.ToDeviceRpcRequestBody; import org.thingsboard.server.common.msg.TbMsgMetaData; import org.thingsboard.server.common.msg.queue.TbCallback; @@ -63,6 +71,7 @@ import org.thingsboard.server.gen.transport.TransportProtos.ToTransportMsg; import org.thingsboard.server.gen.transport.TransportProtos.TransportToDeviceActorMsg; import org.thingsboard.server.gen.transport.TransportProtos.TsKvProto; import org.thingsboard.server.service.rpc.FromDeviceRpcResponse; +import org.thingsboard.server.service.rpc.FromDeviceRpcResponseActorMsg; import org.thingsboard.server.service.rpc.ToDeviceRpcRequestActorMsg; import org.thingsboard.server.service.transport.msg.TransportToDeviceActorMsgWrapper; @@ -98,6 +107,7 @@ class DeviceActorMessageProcessor extends AbstractContextAwareMsgProcessor { private String deviceName; private String deviceType; private TbMsgMetaData defaultMetaData; + private EdgeId edgeId; DeviceActorMessageProcessor(ActorSystemContext systemContext, TenantId tenantId, DeviceId deviceId) { super(systemContext); @@ -120,12 +130,27 @@ class DeviceActorMessageProcessor extends AbstractContextAwareMsgProcessor { this.defaultMetaData = new TbMsgMetaData(); this.defaultMetaData.putValue("deviceName", deviceName); this.defaultMetaData.putValue("deviceType", deviceType); + if (systemContext.isEdgesRpcEnabled()) { + this.edgeId = findRelatedEdgeId(); + } return true; } else { return false; } } + private EdgeId findRelatedEdgeId() { + List result = + systemContext.getRelationService().findByToAndType(tenantId, deviceId, EntityRelation.EDGE_TYPE, RelationTypeGroup.COMMON); + if (result != null && result.size() > 0) { + EntityRelation relationToEdge = result.get(0); + if (relationToEdge.getFrom() != null && relationToEdge.getFrom().getId() != null) { + return new EdgeId(relationToEdge.getFrom().getId()); + } + } + return null; + } + void processRpcRequest(TbActorCtx context, ToDeviceRpcRequestActorMsg msg) { ToDeviceRpcRequest request = msg.getMsg(); ToDeviceRpcRequestBody body = request.getBody(); @@ -138,15 +163,21 @@ class DeviceActorMessageProcessor extends AbstractContextAwareMsgProcessor { return; } - boolean sent = rpcSubscriptions.size() > 0; - Set syncSessionSet = new HashSet<>(); - rpcSubscriptions.forEach((key, value) -> { - sendToTransport(rpcRequest, key, value.getNodeId()); - if (SessionType.SYNC == value.getType()) { - syncSessionSet.add(key); - } - }); - syncSessionSet.forEach(rpcSubscriptions::remove); + boolean sent; + if (systemContext.isEdgesRpcEnabled() && edgeId != null) { + saveRpcRequestToEdgeQueue(request, rpcRequest.getRequestId()); + sent = true; + } else { + sent = rpcSubscriptions.size() > 0; + Set syncSessionSet = new HashSet<>(); + rpcSubscriptions.forEach((key, value) -> { + sendToTransport(rpcRequest, key, value.getNodeId()); + if (SessionType.SYNC == value.getType()) { + syncSessionSet.add(key); + } + }); + syncSessionSet.forEach(rpcSubscriptions::remove); + } if (request.isOneway() && sent) { log.debug("[{}] Rpc command response sent [{}]!", deviceId, request.getId()); @@ -161,6 +192,17 @@ class DeviceActorMessageProcessor extends AbstractContextAwareMsgProcessor { } } + void processRpcResponsesFromEdge(TbActorCtx context, FromDeviceRpcResponseActorMsg responseMsg) { + log.debug("[{}] Processing rpc command response from edge session", deviceId); + ToDeviceRpcRequestMetadata requestMd = toDeviceRpcPendingMap.remove(responseMsg.getRequestId()); + boolean success = requestMd != null; + if (success) { + systemContext.getTbCoreDeviceRpcService().processRpcResponseFromDeviceActor(responseMsg.getMsg()); + } else { + log.debug("[{}] Rpc command response [{}] is stale!", deviceId, responseMsg.getRequestId()); + } + } + private void registerPendingRpcRequest(TbActorCtx context, ToDeviceRpcRequestActorMsg msg, boolean sent, ToDeviceRpcRequestMsg rpcRequest, long timeout) { toDeviceRpcPendingMap.put(rpcRequest.getRequestId(), new ToDeviceRpcRequestMetadata(msg, sent)); DeviceActorServerSideRpcTimeoutMsg timeoutMsg = new DeviceActorServerSideRpcTimeoutMsg(rpcRequest.getRequestId(), timeout); @@ -473,6 +515,10 @@ class DeviceActorMessageProcessor extends AbstractContextAwareMsgProcessor { this.defaultMetaData.putValue("deviceType", deviceType); } + void processEdgeUpdate(DeviceEdgeUpdateMsg msg) { + this.edgeId = msg.getEdgeId(); + } + private void sendToTransport(GetAttributeResponseMsg responseMsg, SessionInfoProto sessionInfo) { ToTransportMsg msg = ToTransportMsg.newBuilder() .setSessionIdMSB(sessionInfo.getSessionIdMSB()) @@ -505,6 +551,25 @@ class DeviceActorMessageProcessor extends AbstractContextAwareMsgProcessor { systemContext.getTbCoreToTransportService().process(nodeId, msg); } + private void saveRpcRequestToEdgeQueue(ToDeviceRpcRequest msg, Integer requestId) { + EdgeEvent edgeEvent = new EdgeEvent(); + edgeEvent.setTenantId(tenantId); + edgeEvent.setAction(EdgeEventActionType.RPC_CALL); + edgeEvent.setEntityId(deviceId.getId()); + edgeEvent.setType(EdgeEventType.DEVICE); + + ObjectNode body = mapper.createObjectNode(); + body.put("requestId", requestId); + body.put("requestUUID", msg.getId().toString()); + body.put("oneway", msg.isOneway()); + body.put("expirationTime", msg.getExpirationTime()); + body.put("method", msg.getBody().getMethod()); + body.put("params", msg.getBody().getParams()); + edgeEvent.setBody(body); + + edgeEvent.setEdgeId(edgeId); + systemContext.getEdgeEventService().saveAsync(edgeEvent); + } private List toTsKvProtos(@Nullable List result) { List clientAttributes; diff --git a/application/src/main/java/org/thingsboard/server/actors/ruleChain/RuleChainActorMessageProcessor.java b/application/src/main/java/org/thingsboard/server/actors/ruleChain/RuleChainActorMessageProcessor.java index 9feac853ca..e9f2a1da02 100644 --- a/application/src/main/java/org/thingsboard/server/actors/ruleChain/RuleChainActorMessageProcessor.java +++ b/application/src/main/java/org/thingsboard/server/actors/ruleChain/RuleChainActorMessageProcessor.java @@ -99,19 +99,17 @@ public class RuleChainActorMessageProcessor extends ComponentMsgProcessor ruleNodeList = service.getRuleChainNodes(tenantId, entityId); - log.trace("[{}][{}] Starting rule chain with {} nodes", tenantId, entityId, ruleNodeList.size()); - // Creating and starting the actors; - for (RuleNode ruleNode : ruleNodeList) { - log.trace("[{}][{}] Creating rule node [{}]: {}", entityId, ruleNode.getId(), ruleNode.getName(), ruleNode); - TbActorRef ruleNodeActor = createRuleNodeActor(context, ruleNode); - nodeActors.put(ruleNode.getId(), new RuleNodeCtx(tenantId, self, ruleNodeActor, ruleNode)); - } - initRoutes(ruleChain, ruleNodeList); - started = true; + if (ruleChain != null && RuleChainType.CORE.equals(ruleChain.getType())) { + List ruleNodeList = service.getRuleChainNodes(tenantId, entityId); + log.trace("[{}][{}] Starting rule chain with {} nodes", tenantId, entityId, ruleNodeList.size()); + // Creating and starting the actors; + for (RuleNode ruleNode : ruleNodeList) { + log.trace("[{}][{}] Creating rule node [{}]: {}", entityId, ruleNode.getId(), ruleNode.getName(), ruleNode); + TbActorRef ruleNodeActor = createRuleNodeActor(context, ruleNode); + nodeActors.put(ruleNode.getId(), new RuleNodeCtx(tenantId, self, ruleNodeActor, ruleNode)); } + initRoutes(ruleChain, ruleNodeList); + started = true; } } else { onUpdate(context); @@ -121,23 +119,22 @@ public class RuleChainActorMessageProcessor extends ComponentMsgProcessor ruleNodeList = service.getRuleChainNodes(tenantId, entityId); - log.trace("[{}][{}] Updating rule chain with {} nodes", tenantId, entityId, ruleNodeList.size()); - for (RuleNode ruleNode : ruleNodeList) { - RuleNodeCtx existing = nodeActors.get(ruleNode.getId()); - if (existing == null) { - log.trace("[{}][{}] Creating rule node [{}]: {}", entityId, ruleNode.getId(), ruleNode.getName(), ruleNode); - TbActorRef ruleNodeActor = createRuleNodeActor(context, ruleNode); - nodeActors.put(ruleNode.getId(), new RuleNodeCtx(tenantId, self, ruleNodeActor, ruleNode)); - } else { - log.trace("[{}][{}] Updating rule node [{}]: {}", entityId, ruleNode.getId(), ruleNode.getName(), ruleNode); - existing.setSelf(ruleNode); - existing.getSelfActor().tellWithHighPriority(new ComponentLifecycleMsg(tenantId, existing.getSelf().getId(), ComponentLifecycleEvent.UPDATED)); - } + if (ruleChain != null && RuleChainType.CORE.equals(ruleChain.getType())) { + ruleChainName = ruleChain.getName(); + List ruleNodeList = service.getRuleChainNodes(tenantId, entityId); + log.trace("[{}][{}] Updating rule chain with {} nodes", tenantId, entityId, ruleNodeList.size()); + for (RuleNode ruleNode : ruleNodeList) { + RuleNodeCtx existing = nodeActors.get(ruleNode.getId()); + if (existing == null) { + log.trace("[{}][{}] Creating rule node [{}]: {}", entityId, ruleNode.getId(), ruleNode.getName(), ruleNode); + TbActorRef ruleNodeActor = createRuleNodeActor(context, ruleNode); + nodeActors.put(ruleNode.getId(), new RuleNodeCtx(tenantId, self, ruleNodeActor, ruleNode)); + } else { + log.trace("[{}][{}] Updating rule node [{}]: {}", entityId, ruleNode.getId(), ruleNode.getName(), ruleNode); + existing.setSelf(ruleNode); + existing.getSelfActor().tellWithHighPriority(new ComponentLifecycleMsg(tenantId, existing.getSelf().getId(), ComponentLifecycleEvent.UPDATED)); } + } Set existingNodes = ruleNodeList.stream().map(RuleNode::getId).collect(Collectors.toSet()); List removedRules = nodeActors.keySet().stream().filter(node -> !existingNodes.contains(node)).collect(Collectors.toList()); @@ -147,10 +144,7 @@ public class RuleChainActorMessageProcessor extends ComponentMsgProcessor edgeFuture; switch (actionType) { @@ -193,12 +193,12 @@ public class DefaultEdgeNotificationService implements EdgeNotificationService { @Override public void onSuccess(@Nullable Edge edge) { if (edge != null && !customerId.isNullUid()) { - saveEdgeEvent(edge.getTenantId(), edge.getId(), EdgeEventType.CUSTOMER, ActionType.ADDED, customerId, null); + saveEdgeEvent(edge.getTenantId(), edge.getId(), EdgeEventType.CUSTOMER, EdgeEventActionType.ADDED, customerId, null); PageData pageData = userService.findCustomerUsers(tenantId, customerId, new PageLink(Integer.MAX_VALUE)); if (pageData != null && pageData.getData() != null && !pageData.getData().isEmpty()) { log.trace("[{}] [{}] user(s) are going to be added to edge.", edge.getId(), pageData.getData().size()); for (User user : pageData.getData()) { - saveEdgeEvent(edge.getTenantId(), edge.getId(), EdgeEventType.USER, ActionType.ADDED, user.getId(), null); + saveEdgeEvent(edge.getTenantId(), edge.getId(), EdgeEventType.USER, EdgeEventActionType.ADDED, user.getId(), null); } } } @@ -217,7 +217,7 @@ public class DefaultEdgeNotificationService implements EdgeNotificationService { @Override public void onSuccess(@Nullable Edge edge) { if (edge != null && !customerIdToDelete.isNullUid()) { - saveEdgeEvent(edge.getTenantId(), edge.getId(), EdgeEventType.CUSTOMER, ActionType.DELETED, customerIdToDelete, null); + saveEdgeEvent(edge.getTenantId(), edge.getId(), EdgeEventType.CUSTOMER, EdgeEventActionType.DELETED, customerIdToDelete, null); } } @@ -234,7 +234,7 @@ public class DefaultEdgeNotificationService implements EdgeNotificationService { } private void processWidgetBundleOrWidgetType(TenantId tenantId, TransportProtos.EdgeNotificationMsgProto edgeNotificationMsg) { - ActionType actionType = ActionType.valueOf(edgeNotificationMsg.getAction()); + EdgeEventActionType actionType = EdgeEventActionType.valueOf(edgeNotificationMsg.getAction()); EdgeEventType type = EdgeEventType.valueOf(edgeNotificationMsg.getType()); EntityId entityId = EntityIdFactory.getByEdgeEventTypeAndUuid(type, new UUID(edgeNotificationMsg.getEntityIdMSB(), edgeNotificationMsg.getEntityIdLSB())); switch (actionType) { @@ -252,7 +252,7 @@ public class DefaultEdgeNotificationService implements EdgeNotificationService { } private void processCustomer(TenantId tenantId, TransportProtos.EdgeNotificationMsgProto edgeNotificationMsg) { - ActionType actionType = ActionType.valueOf(edgeNotificationMsg.getAction()); + EdgeEventActionType actionType = EdgeEventActionType.valueOf(edgeNotificationMsg.getAction()); EdgeEventType type = EdgeEventType.valueOf(edgeNotificationMsg.getType()); EntityId entityId = EntityIdFactory.getByEdgeEventTypeAndUuid(type, new UUID(edgeNotificationMsg.getEntityIdMSB(), edgeNotificationMsg.getEntityIdLSB())); PageData edgesByTenantId = edgeService.findEdgesByTenantId(tenantId, new PageLink(Integer.MAX_VALUE)); @@ -273,7 +273,7 @@ public class DefaultEdgeNotificationService implements EdgeNotificationService { } private void processEntity(TenantId tenantId, TransportProtos.EdgeNotificationMsgProto edgeNotificationMsg) { - ActionType actionType = ActionType.valueOf(edgeNotificationMsg.getAction()); + EdgeEventActionType actionType = EdgeEventActionType.valueOf(edgeNotificationMsg.getAction()); EdgeEventType type = EdgeEventType.valueOf(edgeNotificationMsg.getType()); EntityId entityId = EntityIdFactory.getByEdgeEventTypeAndUuid(type, new UUID(edgeNotificationMsg.getEntityIdMSB(), edgeNotificationMsg.getEntityIdLSB())); @@ -367,7 +367,7 @@ public class DefaultEdgeNotificationService implements EdgeNotificationService { saveEdgeEvent(tenantId, edgeId, EdgeEventType.RULE_CHAIN_METADATA, - ActionType.UPDATED, + EdgeEventActionType.UPDATED, ruleChain.getId(), null); } @@ -392,7 +392,7 @@ public class DefaultEdgeNotificationService implements EdgeNotificationService { saveEdgeEvent(tenantId, edgeId, EdgeEventType.ALARM, - ActionType.valueOf(edgeNotificationMsg.getAction()), + EdgeEventActionType.valueOf(edgeNotificationMsg.getAction()), alarmId, null); } @@ -427,7 +427,7 @@ public class DefaultEdgeNotificationService implements EdgeNotificationService { saveEdgeEvent(tenantId, edgeId, EdgeEventType.RELATION, - ActionType.valueOf(edgeNotificationMsg.getAction()), + EdgeEventActionType.valueOf(edgeNotificationMsg.getAction()), null, mapper.valueToTree(relation)); } diff --git a/application/src/main/java/org/thingsboard/server/service/edge/rpc/EdgeGrpcService.java b/application/src/main/java/org/thingsboard/server/service/edge/rpc/EdgeGrpcService.java index 936a805ea0..384ccafc9c 100644 --- a/application/src/main/java/org/thingsboard/server/service/edge/rpc/EdgeGrpcService.java +++ b/application/src/main/java/org/thingsboard/server/service/edge/rpc/EdgeGrpcService.java @@ -36,10 +36,12 @@ import org.thingsboard.server.common.data.kv.LongDataEntry; import org.thingsboard.server.gen.edge.EdgeRpcServiceGrpc; import org.thingsboard.server.gen.edge.RequestMsg; import org.thingsboard.server.gen.edge.ResponseMsg; +import org.thingsboard.server.queue.util.TbCoreComponent; import org.thingsboard.server.service.edge.EdgeContextComponent; import org.thingsboard.server.service.state.DefaultDeviceStateService; import org.thingsboard.server.service.telemetry.TelemetrySubscriptionService; +import javax.annotation.Nullable; import javax.annotation.PostConstruct; import javax.annotation.PreDestroy; import java.io.File; @@ -54,6 +56,7 @@ import java.util.concurrent.TimeUnit; @Service @Slf4j @ConditionalOnProperty(prefix = "edges.rpc", value = "enabled", havingValue = "true") +@TbCoreComponent public class EdgeGrpcService extends EdgeRpcServiceGrpc.EdgeRpcServiceImplBase implements EdgeRpcService { private final Map sessions = new ConcurrentHashMap<>(); @@ -116,6 +119,9 @@ public class EdgeGrpcService extends EdgeRpcServiceGrpc.EdgeRpcServiceImplBase i if (server != null) { server.shutdownNow(); } + if (executor != null) { + executor.shutdownNow(); + } } @Override @@ -127,7 +133,10 @@ public class EdgeGrpcService extends EdgeRpcServiceGrpc.EdgeRpcServiceImplBase i public void updateEdge(Edge edge) { EdgeGrpcSession session = sessions.get(edge.getId()); if (session != null && session.isConnected()) { + log.debug("[{}] Updating configuration for edge [{}] [{}]", edge.getTenantId(), edge.getName(), edge.getId()); session.onConfigurationUpdate(edge); + } else { + log.warn("[{}] Session doesn't exist for edge [{}] [{}]", edge.getTenantId(), edge.getName(), edge.getId()); } } @@ -135,12 +144,14 @@ public class EdgeGrpcService extends EdgeRpcServiceGrpc.EdgeRpcServiceImplBase i public void deleteEdge(EdgeId edgeId) { EdgeGrpcSession session = sessions.get(edgeId); if (session != null && session.isConnected()) { + log.debug("Closing and removing session for edge [{}]", edgeId); session.close(); sessions.remove(edgeId); } } private void onEdgeConnect(EdgeId edgeId, EdgeGrpcSession edgeGrpcSession) { + log.debug("[{}] onEdgeConnect [{}]", edgeId, edgeGrpcSession.getSessionId()); sessions.put(edgeId, edgeGrpcSession); save(edgeId, DefaultDeviceStateService.ACTIVITY_STATE, true); save(edgeId, DefaultDeviceStateService.LAST_CONNECT_TIME, System.currentTimeMillis()); @@ -167,25 +178,29 @@ public class EdgeGrpcService extends EdgeRpcServiceGrpc.EdgeRpcServiceImplBase i log.trace("No sessions available, sleep for the next run"); try { Thread.sleep(1000); - } catch (InterruptedException ignore) {} + } catch (InterruptedException ignore) { + } } } catch (Exception e) { log.warn("Failed to process messages handling!", e); try { Thread.sleep(1000); - } catch (InterruptedException ignore) {} + } catch (InterruptedException ignore) { + } } } }); } private void onEdgeDisconnect(EdgeId edgeId) { + log.debug("[{}] onEdgeDisconnect", edgeId); sessions.remove(edgeId); save(edgeId, DefaultDeviceStateService.ACTIVITY_STATE, false); save(edgeId, DefaultDeviceStateService.LAST_DISCONNECT_TIME, System.currentTimeMillis()); } private void save(EdgeId edgeId, String key, long value) { + log.debug("[{}] Updating long edge telemetry [{}] [{}]", edgeId, key, value); if (persistToTelemetry) { tsSubService.saveAndNotify( TenantId.SYS_TENANT_ID, edgeId, @@ -197,6 +212,7 @@ public class EdgeGrpcService extends EdgeRpcServiceGrpc.EdgeRpcServiceImplBase i } private void save(EdgeId edgeId, String key, boolean value) { + log.debug("[{}] Updating boolean edge telemetry [{}] [{}]", edgeId, key, value); if (persistToTelemetry) { tsSubService.saveAndNotify( TenantId.SYS_TENANT_ID, edgeId, @@ -219,7 +235,7 @@ public class EdgeGrpcService extends EdgeRpcServiceGrpc.EdgeRpcServiceImplBase i } @Override - public void onSuccess(@javax.annotation.Nullable Void result) { + public void onSuccess(@Nullable Void result) { log.trace("[{}] Successfully updated attribute [{}] with value [{}]", edgeId, key, value); } diff --git a/application/src/main/java/org/thingsboard/server/service/edge/rpc/EdgeGrpcSession.java b/application/src/main/java/org/thingsboard/server/service/edge/rpc/EdgeGrpcSession.java index 2de4465480..73194b18fd 100644 --- a/application/src/main/java/org/thingsboard/server/service/edge/rpc/EdgeGrpcSession.java +++ b/application/src/main/java/org/thingsboard/server/service/edge/rpc/EdgeGrpcSession.java @@ -37,9 +37,9 @@ import org.thingsboard.server.common.data.HasCustomerId; import org.thingsboard.server.common.data.User; import org.thingsboard.server.common.data.alarm.Alarm; import org.thingsboard.server.common.data.asset.Asset; -import org.thingsboard.server.common.data.audit.ActionType; import org.thingsboard.server.common.data.edge.Edge; import org.thingsboard.server.common.data.edge.EdgeEvent; +import org.thingsboard.server.common.data.edge.EdgeEventActionType; import org.thingsboard.server.common.data.edge.EdgeEventType; import org.thingsboard.server.common.data.id.AlarmId; import org.thingsboard.server.common.data.id.AssetId; @@ -224,26 +224,29 @@ public final class EdgeGrpcSession implements Closeable { } latch.countDown(); } catch (Exception e) { - log.error("Can't process downlink response message [{}]", msg, e); + log.error("[{}] Can't process downlink response message [{}]", this.sessionId, msg, e); } } private void sendResponseMsg(ResponseMsg responseMsg) { + log.trace("[{}] Sending response msg [{}]", this.sessionId, responseMsg); if (isConnected()) { try { responseMsgLock.lock(); outputStream.onNext(responseMsg); } catch (Exception e) { - log.error("Failed to send response message [{}]", responseMsg, e); + log.error("[{}] Failed to send response message [{}]", this.sessionId, responseMsg, e); connected = false; sessionCloseListener.accept(edge.getId()); } finally { responseMsgLock.unlock(); } + log.trace("[{}] Response msg successfully sent [{}]", this.sessionId, responseMsg); } } void onConfigurationUpdate(Edge edge) { + log.debug("[{}] onConfigurationUpdate [{}]", this.sessionId, edge); try { this.edge = edge; EdgeUpdateMsg edgeConfig = EdgeUpdateMsg.newBuilder() @@ -252,11 +255,12 @@ public final class EdgeGrpcSession implements Closeable { .setEdgeUpdateMsg(edgeConfig) .build()); } catch (Exception e) { - log.error("Failed to construct proto objects!", e); + log.error("[{}] Failed to construct proto objects!", this.sessionId, e); } } void processHandleMessages() throws ExecutionException, InterruptedException { + log.trace("[{}] processHandleMessages started", this.sessionId); if (isConnected()) { Long queueStartTs = getQueueStartTs().get(); TimePageLink pageLink = new TimePageLink( @@ -274,7 +278,7 @@ public final class EdgeGrpcSession implements Closeable { if (isConnected() && !pageData.getData().isEmpty()) { log.trace("[{}] [{}] event(s) are going to be processed.", this.sessionId, pageData.getData().size()); List downlinkMsgsPack = convertToDownlinkMsgsPack(pageData.getData()); - log.trace("[{}] downlink msg(s) are going to be send.", downlinkMsgsPack.size()); + log.trace("[{}] [{}] downlink msg(s) are going to be send.", this.sessionId, downlinkMsgsPack.size()); latch = new CountDownLatch(downlinkMsgsPack.size()); for (DownlinkMsg downlinkMsg : downlinkMsgsPack) { @@ -287,14 +291,14 @@ public final class EdgeGrpcSession implements Closeable { success = latch.await(10, TimeUnit.SECONDS); if (!success) { - log.warn("Failed to deliver the batch: {}", downlinkMsgsPack); + log.warn("[{}] Failed to deliver the batch: {}", this.sessionId, downlinkMsgsPack); } } if (isConnected() && (!success || pageData.hasNext())) { try { Thread.sleep(ctx.getEdgeEventStorageSettings().getSleepIntervalBetweenBatches()); } catch (InterruptedException e) { - log.error("Error during sleep between batches", e); + log.error("[{}] Error during sleep between batches", this.sessionId, e); } if (success) { pageLink = pageLink.nextPageLink(); @@ -309,19 +313,19 @@ public final class EdgeGrpcSession implements Closeable { try { Thread.sleep(ctx.getEdgeEventStorageSettings().getNoRecordsSleepInterval()); } catch (InterruptedException e) { - log.error("Error during sleep", e); + log.error("[{}] Error during sleep between no records interval", this.sessionId, e); } } + log.trace("[{}] processHandleMessages finished", this.sessionId); } private List convertToDownlinkMsgsPack(List edgeEvents) { List result = new ArrayList<>(); for (EdgeEvent edgeEvent : edgeEvents) { - log.trace("Processing edge event [{}]", edgeEvent); + log.trace("[{}] Processing edge event [{}]", this.sessionId, edgeEvent); try { DownlinkMsg downlinkMsg = null; - ActionType action = ActionType.valueOf(edgeEvent.getAction()); - switch (action) { + switch (edgeEvent.getAction()) { case UPDATED: case ADDED: case DELETED: @@ -334,9 +338,10 @@ public final class EdgeGrpcSession implements Closeable { case RELATION_DELETED: case ASSIGNED_TO_CUSTOMER: case UNASSIGNED_FROM_CUSTOMER: - downlinkMsg = processEntityMessage(edgeEvent, action); + downlinkMsg = processEntityMessage(edgeEvent, edgeEvent.getAction()); break; case ATTRIBUTES_UPDATED: + case POST_ATTRIBUTES: case ATTRIBUTES_DELETED: case TIMESERIES_UPDATED: downlinkMsg = processTelemetryMessage(edgeEvent); @@ -378,7 +383,7 @@ public final class EdgeGrpcSession implements Closeable { private DownlinkMsg processRpcCallMsg(EdgeEvent edgeEvent) { log.trace("Executing processRpcCall, edgeEvent [{}]", edgeEvent); DeviceRpcCallMsg deviceRpcCallMsg = - ctx.getDeviceMsgConstructor().constructDeviceRpcCallMsg(edgeEvent.getBody()); + ctx.getDeviceMsgConstructor().constructDeviceRpcCallMsg(edgeEvent.getEntityId(), edgeEvent.getBody()); return DownlinkMsg.newBuilder() .addAllDeviceRpcCallMsg(Collections.singletonList(deviceRpcCallMsg)) .build(); @@ -399,7 +404,6 @@ public final class EdgeGrpcSession implements Closeable { return downlinkMsg; } - private ListenableFuture getQueueStartTs() { ListenableFuture> future = ctx.getAttributesService().find(edge.getTenantId(), edge.getId(), DataConstants.SERVER_SCOPE, QUEUE_START_TS_ATTR_KEY); @@ -414,13 +418,14 @@ public final class EdgeGrpcSession implements Closeable { } private void updateQueueStartTs(Long newStartTs) { + log.trace("[{}] updating QueueStartTs [{}][{}]", this.sessionId, edge.getId(), newStartTs); newStartTs = ++newStartTs; // increments ts by 1 - next edge event search starts from current offset + 1 List attributes = Collections.singletonList(new BaseAttributeKvEntry(new LongDataEntry(QUEUE_START_TS_ATTR_KEY, newStartTs), System.currentTimeMillis())); ctx.getAttributesService().save(edge.getTenantId(), edge.getId(), DataConstants.SERVER_SCOPE, attributes); } private DownlinkMsg processTelemetryMessage(EdgeEvent edgeEvent) { - log.trace("Executing processTelemetryMessage, edgeEvent [{}]", edgeEvent); + log.trace("[{}] Executing processTelemetryMessage, edgeEvent [{}]", this.sessionId, edgeEvent); EntityId entityId = null; switch (edgeEvent.getType()) { case DEVICE: @@ -444,24 +449,20 @@ public final class EdgeGrpcSession implements Closeable { } DownlinkMsg downlinkMsg = null; if (entityId != null) { - log.debug("Sending telemetry data msg, entityId [{}], body [{}]", edgeEvent.getEntityId(), edgeEvent.getBody()); + log.debug("[{}] Sending telemetry data msg, entityId [{}], body [{}]", this.sessionId, edgeEvent.getEntityId(), edgeEvent.getBody()); try { - ActionType actionType = ActionType.valueOf(edgeEvent.getAction()); - downlinkMsg = constructEntityDataProtoMsg(entityId, actionType, JsonUtils.parse(mapper.writeValueAsString(edgeEvent.getBody()))); + downlinkMsg = constructEntityDataProtoMsg(entityId, edgeEvent.getAction(), JsonUtils.parse(mapper.writeValueAsString(edgeEvent.getBody()))); } catch (Exception e) { - log.warn("Can't send telemetry data msg, entityId [{}], body [{}]", edgeEvent.getEntityId(), edgeEvent.getBody(), e); + log.warn("[{}] Can't send telemetry data msg, entityId [{}], body [{}]", this.sessionId, edgeEvent.getEntityId(), edgeEvent.getBody(), e); } } return downlinkMsg; } - private DownlinkMsg processEntityMessage(EdgeEvent edgeEvent, ActionType action) { - UpdateMsgType msgType = getResponseMsgType(ActionType.valueOf(edgeEvent.getAction())); + private DownlinkMsg processEntityMessage(EdgeEvent edgeEvent, EdgeEventActionType action) { + UpdateMsgType msgType = getResponseMsgType(edgeEvent.getAction()); log.trace("Executing processEntityMessage, edgeEvent [{}], action [{}], msgType [{}]", edgeEvent, action, msgType); switch (edgeEvent.getType()) { - case EDGE: - // TODO: voba - add edge update logic - return null; case DEVICE: return processDevice(edgeEvent, msgType, action); case ASSET: @@ -494,10 +495,10 @@ public final class EdgeGrpcSession implements Closeable { } } - private DownlinkMsg processDevice(EdgeEvent edgeEvent, UpdateMsgType msgType, ActionType edgeActionType) { + private DownlinkMsg processDevice(EdgeEvent edgeEvent, UpdateMsgType msgType, EdgeEventActionType edgeEdgeEventActionType) { DeviceId deviceId = new DeviceId(edgeEvent.getEntityId()); DownlinkMsg downlinkMsg = null; - switch (edgeActionType) { + switch (edgeEdgeEventActionType) { case ADDED: case UPDATED: case ASSIGNED_TO_EDGE: @@ -532,10 +533,11 @@ public final class EdgeGrpcSession implements Closeable { } break; } + log.trace("[{}] device processed [{}]", this.sessionId, downlinkMsg); return downlinkMsg; } - private DownlinkMsg processAsset(EdgeEvent edgeEvent, UpdateMsgType msgType, ActionType action) { + private DownlinkMsg processAsset(EdgeEvent edgeEvent, UpdateMsgType msgType, EdgeEventActionType action) { AssetId assetId = new AssetId(edgeEvent.getEntityId()); DownlinkMsg downlinkMsg = null; switch (action) { @@ -563,10 +565,11 @@ public final class EdgeGrpcSession implements Closeable { .build(); break; } + log.trace("[{}] asset processed [{}]", this.sessionId, downlinkMsg); return downlinkMsg; } - private DownlinkMsg processEntityView(EdgeEvent edgeEvent, UpdateMsgType msgType, ActionType action) { + private DownlinkMsg processEntityView(EdgeEvent edgeEvent, UpdateMsgType msgType, EdgeEventActionType action) { EntityViewId entityViewId = new EntityViewId(edgeEvent.getEntityId()); DownlinkMsg downlinkMsg = null; switch (action) { @@ -594,10 +597,11 @@ public final class EdgeGrpcSession implements Closeable { .build(); break; } + log.trace("[{}] entity view processed [{}]", this.sessionId, downlinkMsg); return downlinkMsg; } - private DownlinkMsg processDashboard(EdgeEvent edgeEvent, UpdateMsgType msgType, ActionType action) { + private DownlinkMsg processDashboard(EdgeEvent edgeEvent, UpdateMsgType msgType, EdgeEventActionType action) { DashboardId dashboardId = new DashboardId(edgeEvent.getEntityId()); DownlinkMsg downlinkMsg = null; switch (action) { @@ -628,10 +632,11 @@ public final class EdgeGrpcSession implements Closeable { .build(); break; } + log.trace("[{}] dashboard processed [{}]", this.sessionId, downlinkMsg); return downlinkMsg; } - private DownlinkMsg processCustomer(EdgeEvent edgeEvent, UpdateMsgType msgType, ActionType action) { + private DownlinkMsg processCustomer(EdgeEvent edgeEvent, UpdateMsgType msgType, EdgeEventActionType action) { CustomerId customerId = new CustomerId(edgeEvent.getEntityId()); DownlinkMsg downlinkMsg = null; switch (action) { @@ -654,10 +659,11 @@ public final class EdgeGrpcSession implements Closeable { .build(); break; } + log.trace("[{}] customer processed [{}]", this.sessionId, downlinkMsg); return downlinkMsg; } - private DownlinkMsg processRuleChain(EdgeEvent edgeEvent, UpdateMsgType msgType, ActionType action) { + private DownlinkMsg processRuleChain(EdgeEvent edgeEvent, UpdateMsgType msgType, EdgeEventActionType action) { RuleChainId ruleChainId = new RuleChainId(edgeEvent.getEntityId()); DownlinkMsg downlinkMsg = null; switch (action) { @@ -680,6 +686,7 @@ public final class EdgeGrpcSession implements Closeable { .build(); break; } + log.trace("[{}] rule chain processed [{}]", this.sessionId, downlinkMsg); return downlinkMsg; } @@ -697,13 +704,14 @@ public final class EdgeGrpcSession implements Closeable { .build(); } } + log.trace("[{}] rule chain metadata processed [{}]", this.sessionId, downlinkMsg); return downlinkMsg; } - private DownlinkMsg processUser(EdgeEvent edgeEvent, UpdateMsgType msgType, ActionType edgeActionType) { + private DownlinkMsg processUser(EdgeEvent edgeEvent, UpdateMsgType msgType, EdgeEventActionType edgeEdgeEventActionType) { UserId userId = new UserId(edgeEvent.getEntityId()); DownlinkMsg downlinkMsg = null; - switch (edgeActionType) { + switch (edgeEdgeEventActionType) { case ADDED: case UPDATED: User user = ctx.getUserService().findUserById(edgeEvent.getTenantId(), userId); @@ -729,6 +737,7 @@ public final class EdgeGrpcSession implements Closeable { .build(); } } + log.trace("[{}] user processed [{}]", this.sessionId, downlinkMsg); return downlinkMsg; } @@ -743,9 +752,11 @@ public final class EdgeGrpcSession implements Closeable { private DownlinkMsg processRelation(EdgeEvent edgeEvent, UpdateMsgType msgType) { EntityRelation entityRelation = mapper.convertValue(edgeEvent.getBody(), EntityRelation.class); RelationUpdateMsg r = ctx.getRelationMsgConstructor().constructRelationUpdatedMsg(msgType, entityRelation); - return DownlinkMsg.newBuilder() + DownlinkMsg downlinkMsg = DownlinkMsg.newBuilder() .addAllRelationUpdateMsg(Collections.singletonList(r)) .build(); + log.trace("[{}] relation processed [{}]", this.sessionId, downlinkMsg); + return downlinkMsg; } private DownlinkMsg processAlarm(EdgeEvent edgeEvent, UpdateMsgType msgType) { @@ -761,13 +772,14 @@ public final class EdgeGrpcSession implements Closeable { } catch (Exception e) { log.error("Can't process alarm msg [{}] [{}]", edgeEvent, msgType, e); } + log.trace("[{}] alarm processed [{}]", this.sessionId, downlinkMsg); return downlinkMsg; } - private DownlinkMsg processWidgetsBundle(EdgeEvent edgeEvent, UpdateMsgType msgType, ActionType edgeActionType) { + private DownlinkMsg processWidgetsBundle(EdgeEvent edgeEvent, UpdateMsgType msgType, EdgeEventActionType edgeEdgeEventActionType) { WidgetsBundleId widgetsBundleId = new WidgetsBundleId(edgeEvent.getEntityId()); DownlinkMsg downlinkMsg = null; - switch (edgeActionType) { + switch (edgeEdgeEventActionType) { case ADDED: case UPDATED: WidgetsBundle widgetsBundle = ctx.getWidgetsBundleService().findWidgetsBundleById(edgeEvent.getTenantId(), widgetsBundleId); @@ -787,13 +799,14 @@ public final class EdgeGrpcSession implements Closeable { .build(); break; } + log.trace("[{}] widget bundle processed [{}]", this.sessionId, downlinkMsg); return downlinkMsg; } - private DownlinkMsg processWidgetType(EdgeEvent edgeEvent, UpdateMsgType msgType, ActionType edgeActionType) { + private DownlinkMsg processWidgetType(EdgeEvent edgeEvent, UpdateMsgType msgType, EdgeEventActionType edgeEdgeEventActionType) { WidgetTypeId widgetTypeId = new WidgetTypeId(edgeEvent.getEntityId()); DownlinkMsg downlinkMsg = null; - switch (edgeActionType) { + switch (edgeEdgeEventActionType) { case ADDED: case UPDATED: WidgetType widgetType = ctx.getWidgetTypeService().findWidgetTypeById(edgeEvent.getTenantId(), widgetTypeId); @@ -813,18 +826,21 @@ public final class EdgeGrpcSession implements Closeable { .build(); break; } + log.trace("[{}] widget type processed [{}]", this.sessionId, downlinkMsg); return downlinkMsg; } private DownlinkMsg processAdminSettings(EdgeEvent edgeEvent) { AdminSettings adminSettings = mapper.convertValue(edgeEvent.getBody(), AdminSettings.class); AdminSettingsUpdateMsg t = ctx.getAdminSettingsMsgConstructor().constructAdminSettingsUpdateMsg(adminSettings); - return DownlinkMsg.newBuilder() + DownlinkMsg downlinkMsg = DownlinkMsg.newBuilder() .addAllAdminSettingsUpdateMsg(Collections.singletonList(t)) .build(); + log.trace("[{}] admin settings processed [{}]", this.sessionId, downlinkMsg); + return downlinkMsg; } - private UpdateMsgType getResponseMsgType(ActionType actionType) { + private UpdateMsgType getResponseMsgType(EdgeEventActionType actionType) { switch (actionType) { case UPDATED: case CREDENTIALS_UPDATED: @@ -848,11 +864,13 @@ public final class EdgeGrpcSession implements Closeable { } } - private DownlinkMsg constructEntityDataProtoMsg(EntityId entityId, ActionType actionType, JsonElement entityData) { + private DownlinkMsg constructEntityDataProtoMsg(EntityId entityId, EdgeEventActionType actionType, JsonElement entityData) { EntityDataProto entityDataProto = ctx.getEntityDataMsgConstructor().constructEntityDataMsg(entityId, actionType, entityData); - DownlinkMsg.Builder builder = DownlinkMsg.newBuilder() - .addAllEntityData(Collections.singletonList(entityDataProto)); - return builder.build(); + DownlinkMsg downlinkMsg = DownlinkMsg.newBuilder() + .addAllEntityData(Collections.singletonList(entityDataProto)) + .build(); + log.trace("[{}] entity data proto processed [{}]", this.sessionId, downlinkMsg); + return downlinkMsg; } private ListenableFuture> processUplinkMsg(UplinkMsg uplinkMsg) { @@ -863,7 +881,6 @@ public final class EdgeGrpcSession implements Closeable { result.addAll(ctx.getTelemetryProcessor().onTelemetryUpdate(edge.getTenantId(), entityData)); } } - if (uplinkMsg.getDeviceUpdateMsgList() != null && !uplinkMsg.getDeviceUpdateMsgList().isEmpty()) { for (DeviceUpdateMsg deviceUpdateMsg : uplinkMsg.getDeviceUpdateMsgList()) { result.add(ctx.getDeviceProcessor().onDeviceUpdate(edge.getTenantId(), edge, deviceUpdateMsg)); @@ -915,12 +932,13 @@ public final class EdgeGrpcSession implements Closeable { } } } catch (Exception e) { - log.error("Can't process uplink msg [{}]", uplinkMsg, e); + log.error("[{}] Can't process uplink msg [{}]", this.sessionId, uplinkMsg, e); } return Futures.allAsList(result); } private ConnectResponseMsg processConnect(ConnectRequestMsg request) { + log.trace("[{}] processConnect [{}]", this.sessionId, request); Optional optional = ctx.getEdgeService().findEdgeByRoutingKey(TenantId.SYS_TENANT_ID, request.getEdgeRoutingKey()); if (optional.isPresent()) { edge = optional.get(); @@ -950,7 +968,7 @@ public final class EdgeGrpcSession implements Closeable { .setConfiguration(EdgeConfiguration.getDefaultInstance()).build(); } - private EdgeConfiguration constructEdgeConfigProto(Edge edge) throws JsonProcessingException { + private EdgeConfiguration constructEdgeConfigProto(Edge edge) { return EdgeConfiguration.newBuilder() .setEdgeIdMSB(edge.getId().getId().getMostSignificantBits()) .setEdgeIdLSB(edge.getId().getId().getLeastSignificantBits()) @@ -967,6 +985,7 @@ public final class EdgeGrpcSession implements Closeable { @Override public void close() { + log.debug("[{}] Closing session", sessionId); connected = false; try { outputStream.onCompleted(); diff --git a/application/src/main/java/org/thingsboard/server/service/edge/rpc/constructor/AdminSettingsMsgConstructor.java b/application/src/main/java/org/thingsboard/server/service/edge/rpc/constructor/AdminSettingsMsgConstructor.java index 6a6b67e2e6..17aa50907f 100644 --- a/application/src/main/java/org/thingsboard/server/service/edge/rpc/constructor/AdminSettingsMsgConstructor.java +++ b/application/src/main/java/org/thingsboard/server/service/edge/rpc/constructor/AdminSettingsMsgConstructor.java @@ -15,14 +15,14 @@ */ package org.thingsboard.server.service.edge.rpc.constructor; -import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Component; import org.thingsboard.server.common.data.AdminSettings; import org.thingsboard.server.dao.util.mapping.JacksonUtil; import org.thingsboard.server.gen.edge.AdminSettingsUpdateMsg; +import org.thingsboard.server.queue.util.TbCoreComponent; -@Slf4j @Component +@TbCoreComponent public class AdminSettingsMsgConstructor { public AdminSettingsUpdateMsg constructAdminSettingsUpdateMsg(AdminSettings adminSettings) { diff --git a/application/src/main/java/org/thingsboard/server/service/edge/rpc/constructor/AlarmMsgConstructor.java b/application/src/main/java/org/thingsboard/server/service/edge/rpc/constructor/AlarmMsgConstructor.java index 3414727575..aa03aa4b87 100644 --- a/application/src/main/java/org/thingsboard/server/service/edge/rpc/constructor/AlarmMsgConstructor.java +++ b/application/src/main/java/org/thingsboard/server/service/edge/rpc/constructor/AlarmMsgConstructor.java @@ -15,12 +15,9 @@ */ package org.thingsboard.server.service.edge.rpc.constructor; -import lombok.extern.slf4j.Slf4j; -import org.bouncycastle.jcajce.provider.symmetric.DES; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; import org.thingsboard.server.common.data.alarm.Alarm; -import org.thingsboard.server.common.data.entityview.EntityViewSearchQuery; import org.thingsboard.server.common.data.id.AssetId; import org.thingsboard.server.common.data.id.DeviceId; import org.thingsboard.server.common.data.id.EntityViewId; @@ -31,9 +28,10 @@ import org.thingsboard.server.dao.entityview.EntityViewService; import org.thingsboard.server.dao.util.mapping.JacksonUtil; import org.thingsboard.server.gen.edge.AlarmUpdateMsg; import org.thingsboard.server.gen.edge.UpdateMsgType; +import org.thingsboard.server.queue.util.TbCoreComponent; @Component -@Slf4j +@TbCoreComponent public class AlarmMsgConstructor { @Autowired diff --git a/application/src/main/java/org/thingsboard/server/service/edge/rpc/constructor/AssetMsgConstructor.java b/application/src/main/java/org/thingsboard/server/service/edge/rpc/constructor/AssetMsgConstructor.java index c6eb3d32f4..52cd201bf0 100644 --- a/application/src/main/java/org/thingsboard/server/service/edge/rpc/constructor/AssetMsgConstructor.java +++ b/application/src/main/java/org/thingsboard/server/service/edge/rpc/constructor/AssetMsgConstructor.java @@ -15,7 +15,6 @@ */ package org.thingsboard.server.service.edge.rpc.constructor; -import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Component; import org.thingsboard.server.common.data.asset.Asset; import org.thingsboard.server.common.data.id.AssetId; @@ -23,9 +22,10 @@ import org.thingsboard.server.common.data.id.CustomerId; import org.thingsboard.server.dao.util.mapping.JacksonUtil; import org.thingsboard.server.gen.edge.AssetUpdateMsg; import org.thingsboard.server.gen.edge.UpdateMsgType; +import org.thingsboard.server.queue.util.TbCoreComponent; @Component -@Slf4j +@TbCoreComponent public class AssetMsgConstructor { public AssetUpdateMsg constructAssetUpdatedMsg(UpdateMsgType msgType, Asset asset, CustomerId customerId) { diff --git a/application/src/main/java/org/thingsboard/server/service/edge/rpc/constructor/CustomerMsgConstructor.java b/application/src/main/java/org/thingsboard/server/service/edge/rpc/constructor/CustomerMsgConstructor.java index 94687b88d4..f1f0247e66 100644 --- a/application/src/main/java/org/thingsboard/server/service/edge/rpc/constructor/CustomerMsgConstructor.java +++ b/application/src/main/java/org/thingsboard/server/service/edge/rpc/constructor/CustomerMsgConstructor.java @@ -15,16 +15,16 @@ */ package org.thingsboard.server.service.edge.rpc.constructor; -import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Component; import org.thingsboard.server.common.data.Customer; import org.thingsboard.server.common.data.id.CustomerId; import org.thingsboard.server.dao.util.mapping.JacksonUtil; import org.thingsboard.server.gen.edge.CustomerUpdateMsg; import org.thingsboard.server.gen.edge.UpdateMsgType; +import org.thingsboard.server.queue.util.TbCoreComponent; @Component -@Slf4j +@TbCoreComponent public class CustomerMsgConstructor { public CustomerUpdateMsg constructCustomerUpdatedMsg(UpdateMsgType msgType, Customer customer) { diff --git a/application/src/main/java/org/thingsboard/server/service/edge/rpc/constructor/DashboardMsgConstructor.java b/application/src/main/java/org/thingsboard/server/service/edge/rpc/constructor/DashboardMsgConstructor.java index a41b987c1c..02ef71bb46 100644 --- a/application/src/main/java/org/thingsboard/server/service/edge/rpc/constructor/DashboardMsgConstructor.java +++ b/application/src/main/java/org/thingsboard/server/service/edge/rpc/constructor/DashboardMsgConstructor.java @@ -15,18 +15,17 @@ */ package org.thingsboard.server.service.edge.rpc.constructor; -import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Component; import org.thingsboard.server.common.data.Dashboard; import org.thingsboard.server.common.data.id.CustomerId; import org.thingsboard.server.common.data.id.DashboardId; -import org.thingsboard.server.common.data.id.EntityId; import org.thingsboard.server.dao.util.mapping.JacksonUtil; import org.thingsboard.server.gen.edge.DashboardUpdateMsg; import org.thingsboard.server.gen.edge.UpdateMsgType; +import org.thingsboard.server.queue.util.TbCoreComponent; @Component -@Slf4j +@TbCoreComponent public class DashboardMsgConstructor { public DashboardUpdateMsg constructDashboardUpdatedMsg(UpdateMsgType msgType, Dashboard dashboard, CustomerId customerId) { diff --git a/application/src/main/java/org/thingsboard/server/service/edge/rpc/constructor/DeviceMsgConstructor.java b/application/src/main/java/org/thingsboard/server/service/edge/rpc/constructor/DeviceMsgConstructor.java index ffc635075d..1f5b360d5b 100644 --- a/application/src/main/java/org/thingsboard/server/service/edge/rpc/constructor/DeviceMsgConstructor.java +++ b/application/src/main/java/org/thingsboard/server/service/edge/rpc/constructor/DeviceMsgConstructor.java @@ -17,9 +17,7 @@ package org.thingsboard.server.service.edge.rpc.constructor; import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; -import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Component; -import org.thingsboard.rule.engine.api.RuleEngineDeviceRpcRequest; import org.thingsboard.server.common.data.Device; import org.thingsboard.server.common.data.id.CustomerId; import org.thingsboard.server.common.data.id.DeviceId; @@ -30,9 +28,12 @@ import org.thingsboard.server.gen.edge.DeviceRpcCallMsg; import org.thingsboard.server.gen.edge.DeviceUpdateMsg; import org.thingsboard.server.gen.edge.RpcRequestMsg; import org.thingsboard.server.gen.edge.UpdateMsgType; +import org.thingsboard.server.queue.util.TbCoreComponent; + +import java.util.UUID; @Component -@Slf4j +@TbCoreComponent public class DeviceMsgConstructor { protected static final ObjectMapper mapper = new ObjectMapper(); @@ -78,19 +79,25 @@ public class DeviceMsgConstructor { .setIdLSB(deviceId.getId().getLeastSignificantBits()).build(); } - public DeviceRpcCallMsg constructDeviceRpcCallMsg(JsonNode body) { - RuleEngineDeviceRpcRequest request = mapper.convertValue(body, RuleEngineDeviceRpcRequest.class); + public DeviceRpcCallMsg constructDeviceRpcCallMsg(UUID deviceId, JsonNode body) { + int requestId = body.get("requestId").asInt(); + boolean oneway = body.get("oneway").asBoolean(); + UUID requestUUID = UUID.fromString(body.get("requestUUID").asText()); + long expirationTime = body.get("expirationTime").asLong(); + String method = body.get("method").asText(); + String params = body.get("params").asText(); + RpcRequestMsg.Builder requestBuilder = RpcRequestMsg.newBuilder(); - requestBuilder.setMethod(request.getMethod()); - requestBuilder.setParams(request.getBody()); + requestBuilder.setMethod(method); + requestBuilder.setParams(params); DeviceRpcCallMsg.Builder builder = DeviceRpcCallMsg.newBuilder() - .setDeviceIdMSB(request.getDeviceId().getId().getMostSignificantBits()) - .setDeviceIdLSB(request.getDeviceId().getId().getLeastSignificantBits()) - .setRequestIdMSB(request.getRequestUUID().getMostSignificantBits()) - .setRequestIdLSB(request.getRequestUUID().getLeastSignificantBits()) - .setExpirationTime(request.getExpirationTime()) - .setOriginServiceId(request.getOriginServiceId()) - .setOneway(request.isOneway()) + .setDeviceIdMSB(deviceId.getMostSignificantBits()) + .setDeviceIdLSB(deviceId.getLeastSignificantBits()) + .setRequestUuidMSB(requestUUID.getMostSignificantBits()) + .setRequestUuidLSB(requestUUID.getLeastSignificantBits()) + .setRequestId(requestId) + .setExpirationTime(expirationTime) + .setOneway(oneway) .setRequestMsg(requestBuilder.build()); return builder.build(); } diff --git a/application/src/main/java/org/thingsboard/server/service/edge/rpc/constructor/EntityDataMsgConstructor.java b/application/src/main/java/org/thingsboard/server/service/edge/rpc/constructor/EntityDataMsgConstructor.java index ffa2ada070..469207a0cc 100644 --- a/application/src/main/java/org/thingsboard/server/service/edge/rpc/constructor/EntityDataMsgConstructor.java +++ b/application/src/main/java/org/thingsboard/server/service/edge/rpc/constructor/EntityDataMsgConstructor.java @@ -22,19 +22,22 @@ import com.google.gson.JsonObject; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Component; import org.thingsboard.server.common.data.audit.ActionType; +import org.thingsboard.server.common.data.edge.EdgeEventActionType; import org.thingsboard.server.common.data.id.EntityId; import org.thingsboard.server.common.transport.adaptor.JsonConverter; import org.thingsboard.server.gen.edge.AttributeDeleteMsg; import org.thingsboard.server.gen.edge.EntityDataProto; import org.thingsboard.server.gen.transport.TransportProtos; +import org.thingsboard.server.queue.util.TbCoreComponent; import java.util.List; @Component @Slf4j +@TbCoreComponent public class EntityDataMsgConstructor { - public EntityDataProto constructEntityDataMsg(EntityId entityId, ActionType actionType, JsonElement entityData) { + public EntityDataProto constructEntityDataMsg(EntityId entityId, EdgeEventActionType actionType, JsonElement entityData) { EntityDataProto.Builder builder = EntityDataProto.newBuilder() .setEntityIdMSB(entityId.getId().getMostSignificantBits()) .setEntityIdLSB(entityId.getId().getLeastSignificantBits()) @@ -51,21 +54,27 @@ public class EntityDataMsgConstructor { } builder.setPostTelemetryMsg(JsonConverter.convertToTelemetryProto(data.getAsJsonObject("data"), ts)); } catch (Exception e) { - log.warn("Can't convert to telemetry proto, entityData [{}]", entityData, e); + log.warn("[{}] Can't convert to telemetry proto, entityData [{}]", entityId, entityData, e); } break; case ATTRIBUTES_UPDATED: try { JsonObject data = entityData.getAsJsonObject(); - TransportProtos.PostAttributeMsg postAttributeMsg = JsonConverter.convertToAttributesProto(data.getAsJsonObject("kv")); - if (data.has("isPostAttributes") && data.getAsJsonPrimitive("isPostAttributes").getAsBoolean()) { - builder.setPostAttributesMsg(postAttributeMsg); - } else { - builder.setAttributesUpdatedMsg(postAttributeMsg); - } + TransportProtos.PostAttributeMsg attributesUpdatedMsg = JsonConverter.convertToAttributesProto(data.getAsJsonObject("kv")); + builder.setAttributesUpdatedMsg(attributesUpdatedMsg); + builder.setPostAttributeScope(data.getAsJsonPrimitive("scope").getAsString()); + } catch (Exception e) { + log.warn("[{}] Can't convert to AttributesUpdatedMsg proto, entityData [{}]", entityId, entityData, e); + } + break; + case POST_ATTRIBUTES: + try { + JsonObject data = entityData.getAsJsonObject(); + TransportProtos.PostAttributeMsg postAttributesMsg = JsonConverter.convertToAttributesProto(data.getAsJsonObject("kv")); + builder.setPostAttributesMsg(postAttributesMsg); builder.setPostAttributeScope(data.getAsJsonPrimitive("scope").getAsString()); } catch (Exception e) { - log.warn("Can't convert to attributes proto, entityData [{}]", entityData, e); + log.warn("[{}] Can't convert to PostAttributesMsg, entityData [{}]", entityId, entityData, e); } break; case ATTRIBUTES_DELETED: @@ -78,7 +87,7 @@ public class EntityDataMsgConstructor { attributeDeleteMsg.build(); builder.setAttributeDeleteMsg(attributeDeleteMsg); } catch (Exception e) { - log.warn("Can't convert to AttributeDeleteMsg proto, entityData [{}]", entityData, e); + log.warn("[{}] Can't convert to AttributeDeleteMsg proto, entityData [{}]", entityId, entityData, e); } break; } diff --git a/application/src/main/java/org/thingsboard/server/service/edge/rpc/constructor/EntityViewMsgConstructor.java b/application/src/main/java/org/thingsboard/server/service/edge/rpc/constructor/EntityViewMsgConstructor.java index abe32dec77..7d29fa8734 100644 --- a/application/src/main/java/org/thingsboard/server/service/edge/rpc/constructor/EntityViewMsgConstructor.java +++ b/application/src/main/java/org/thingsboard/server/service/edge/rpc/constructor/EntityViewMsgConstructor.java @@ -15,7 +15,6 @@ */ package org.thingsboard.server.service.edge.rpc.constructor; -import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Component; import org.thingsboard.server.common.data.EntityView; import org.thingsboard.server.common.data.id.CustomerId; @@ -24,9 +23,10 @@ import org.thingsboard.server.dao.util.mapping.JacksonUtil; import org.thingsboard.server.gen.edge.EdgeEntityType; import org.thingsboard.server.gen.edge.EntityViewUpdateMsg; import org.thingsboard.server.gen.edge.UpdateMsgType; +import org.thingsboard.server.queue.util.TbCoreComponent; @Component -@Slf4j +@TbCoreComponent public class EntityViewMsgConstructor { public EntityViewUpdateMsg constructEntityViewUpdatedMsg(UpdateMsgType msgType, EntityView entityView, CustomerId customerId) { diff --git a/application/src/main/java/org/thingsboard/server/service/edge/rpc/constructor/RelationMsgConstructor.java b/application/src/main/java/org/thingsboard/server/service/edge/rpc/constructor/RelationMsgConstructor.java index 5a1f7ce39d..f50b2376ab 100644 --- a/application/src/main/java/org/thingsboard/server/service/edge/rpc/constructor/RelationMsgConstructor.java +++ b/application/src/main/java/org/thingsboard/server/service/edge/rpc/constructor/RelationMsgConstructor.java @@ -15,15 +15,15 @@ */ package org.thingsboard.server.service.edge.rpc.constructor; -import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Component; import org.thingsboard.server.common.data.relation.EntityRelation; import org.thingsboard.server.dao.util.mapping.JacksonUtil; import org.thingsboard.server.gen.edge.RelationUpdateMsg; import org.thingsboard.server.gen.edge.UpdateMsgType; +import org.thingsboard.server.queue.util.TbCoreComponent; @Component -@Slf4j +@TbCoreComponent public class RelationMsgConstructor { public RelationUpdateMsg constructRelationUpdatedMsg(UpdateMsgType msgType, EntityRelation entityRelation) { diff --git a/application/src/main/java/org/thingsboard/server/service/edge/rpc/constructor/RuleChainMsgConstructor.java b/application/src/main/java/org/thingsboard/server/service/edge/rpc/constructor/RuleChainMsgConstructor.java index 22017c56c2..e6cabd2755 100644 --- a/application/src/main/java/org/thingsboard/server/service/edge/rpc/constructor/RuleChainMsgConstructor.java +++ b/application/src/main/java/org/thingsboard/server/service/edge/rpc/constructor/RuleChainMsgConstructor.java @@ -32,12 +32,14 @@ import org.thingsboard.server.gen.edge.RuleChainMetadataUpdateMsg; import org.thingsboard.server.gen.edge.RuleChainUpdateMsg; import org.thingsboard.server.gen.edge.RuleNodeProto; import org.thingsboard.server.gen.edge.UpdateMsgType; +import org.thingsboard.server.queue.util.TbCoreComponent; import java.util.ArrayList; import java.util.List; @Component @Slf4j +@TbCoreComponent public class RuleChainMsgConstructor { private static final ObjectMapper objectMapper = new ObjectMapper(); diff --git a/application/src/main/java/org/thingsboard/server/service/edge/rpc/constructor/UserMsgConstructor.java b/application/src/main/java/org/thingsboard/server/service/edge/rpc/constructor/UserMsgConstructor.java index b5b6b080f7..ea0b60c970 100644 --- a/application/src/main/java/org/thingsboard/server/service/edge/rpc/constructor/UserMsgConstructor.java +++ b/application/src/main/java/org/thingsboard/server/service/edge/rpc/constructor/UserMsgConstructor.java @@ -15,22 +15,19 @@ */ package org.thingsboard.server.service.edge.rpc.constructor; -import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Component; import org.thingsboard.server.common.data.User; import org.thingsboard.server.common.data.id.CustomerId; -import org.thingsboard.server.common.data.id.EntityId; import org.thingsboard.server.common.data.id.UserId; import org.thingsboard.server.common.data.security.UserCredentials; import org.thingsboard.server.dao.util.mapping.JacksonUtil; import org.thingsboard.server.gen.edge.UpdateMsgType; import org.thingsboard.server.gen.edge.UserCredentialsUpdateMsg; import org.thingsboard.server.gen.edge.UserUpdateMsg; - -import java.util.UUID; +import org.thingsboard.server.queue.util.TbCoreComponent; @Component -@Slf4j +@TbCoreComponent public class UserMsgConstructor { public UserUpdateMsg constructUserUpdatedMsg(UpdateMsgType msgType, User user, CustomerId customerId) { diff --git a/application/src/main/java/org/thingsboard/server/service/edge/rpc/constructor/WidgetTypeMsgConstructor.java b/application/src/main/java/org/thingsboard/server/service/edge/rpc/constructor/WidgetTypeMsgConstructor.java index e01b2afa66..3ee8e4ec3b 100644 --- a/application/src/main/java/org/thingsboard/server/service/edge/rpc/constructor/WidgetTypeMsgConstructor.java +++ b/application/src/main/java/org/thingsboard/server/service/edge/rpc/constructor/WidgetTypeMsgConstructor.java @@ -15,7 +15,6 @@ */ package org.thingsboard.server.service.edge.rpc.constructor; -import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Component; import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.common.data.id.WidgetTypeId; @@ -23,9 +22,10 @@ import org.thingsboard.server.common.data.widget.WidgetType; import org.thingsboard.server.dao.util.mapping.JacksonUtil; import org.thingsboard.server.gen.edge.UpdateMsgType; import org.thingsboard.server.gen.edge.WidgetTypeUpdateMsg; +import org.thingsboard.server.queue.util.TbCoreComponent; @Component -@Slf4j +@TbCoreComponent public class WidgetTypeMsgConstructor { public WidgetTypeUpdateMsg constructWidgetTypeUpdateMsg(UpdateMsgType msgType, WidgetType widgetType) { diff --git a/application/src/main/java/org/thingsboard/server/service/edge/rpc/constructor/WidgetsBundleMsgConstructor.java b/application/src/main/java/org/thingsboard/server/service/edge/rpc/constructor/WidgetsBundleMsgConstructor.java index 13dd78980c..d8bb24dc4f 100644 --- a/application/src/main/java/org/thingsboard/server/service/edge/rpc/constructor/WidgetsBundleMsgConstructor.java +++ b/application/src/main/java/org/thingsboard/server/service/edge/rpc/constructor/WidgetsBundleMsgConstructor.java @@ -16,16 +16,16 @@ package org.thingsboard.server.service.edge.rpc.constructor; import com.google.protobuf.ByteString; -import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Component; import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.common.data.id.WidgetsBundleId; import org.thingsboard.server.common.data.widget.WidgetsBundle; import org.thingsboard.server.gen.edge.UpdateMsgType; import org.thingsboard.server.gen.edge.WidgetsBundleUpdateMsg; +import org.thingsboard.server.queue.util.TbCoreComponent; @Component -@Slf4j +@TbCoreComponent public class WidgetsBundleMsgConstructor { public WidgetsBundleUpdateMsg constructWidgetsBundleUpdateMsg(UpdateMsgType msgType, WidgetsBundle widgetsBundle) { diff --git a/application/src/main/java/org/thingsboard/server/service/edge/rpc/init/DefaultSyncEdgeService.java b/application/src/main/java/org/thingsboard/server/service/edge/rpc/init/DefaultSyncEdgeService.java index 45f72bba0a..88e330fbbd 100644 --- a/application/src/main/java/org/thingsboard/server/service/edge/rpc/init/DefaultSyncEdgeService.java +++ b/application/src/main/java/org/thingsboard/server/service/edge/rpc/init/DefaultSyncEdgeService.java @@ -39,9 +39,9 @@ import org.thingsboard.server.common.data.EntityType; import org.thingsboard.server.common.data.EntityView; import org.thingsboard.server.common.data.User; import org.thingsboard.server.common.data.asset.Asset; -import org.thingsboard.server.common.data.audit.ActionType; import org.thingsboard.server.common.data.edge.Edge; import org.thingsboard.server.common.data.edge.EdgeEvent; +import org.thingsboard.server.common.data.edge.EdgeEventActionType; import org.thingsboard.server.common.data.edge.EdgeEventType; import org.thingsboard.server.common.data.id.AdminSettingsId; import org.thingsboard.server.common.data.id.DeviceId; @@ -139,6 +139,7 @@ public class DefaultSyncEdgeService implements SyncEdgeService { @Override public void sync(Edge edge) { + log.trace("[{}] staring sync process for edge [{}]", edge.getTenantId(), edge.getName()); try { syncWidgetsBundleAndWidgetTypes(edge); syncAdminSettings(edge); @@ -154,13 +155,14 @@ public class DefaultSyncEdgeService implements SyncEdgeService { } private void syncRuleChains(Edge edge) { + log.trace("[{}] syncRuleChains [{}]", edge.getTenantId(), edge.getName()); try { PageData pageData = ruleChainService.findRuleChainsByTenantIdAndEdgeId(edge.getTenantId(), edge.getId(), new TimePageLink(Integer.MAX_VALUE)); if (pageData != null && pageData.getData() != null && !pageData.getData().isEmpty()) { log.trace("[{}] [{}] rule chains(s) are going to be pushed to edge.", edge.getId(), pageData.getData().size()); for (RuleChain ruleChain : pageData.getData()) { - saveEdgeEvent(edge.getTenantId(), edge.getId(), EdgeEventType.RULE_CHAIN, ActionType.ADDED, ruleChain.getId(), null); + saveEdgeEvent(edge.getTenantId(), edge.getId(), EdgeEventType.RULE_CHAIN, EdgeEventActionType.ADDED, ruleChain.getId(), null); } } } catch (Exception e) { @@ -169,13 +171,14 @@ public class DefaultSyncEdgeService implements SyncEdgeService { } private void syncDevices(Edge edge) { + log.trace("[{}] syncDevices [{}]", edge.getTenantId(), edge.getName()); try { PageData pageData = deviceService.findDevicesByTenantIdAndEdgeId(edge.getTenantId(), edge.getId(), new TimePageLink(Integer.MAX_VALUE)); if (pageData != null && pageData.getData() != null && !pageData.getData().isEmpty()) { log.trace("[{}] [{}] device(s) are going to be pushed to edge.", edge.getId(), pageData.getData().size()); for (Device device : pageData.getData()) { - saveEdgeEvent(edge.getTenantId(), edge.getId(), EdgeEventType.DEVICE, ActionType.ADDED, device.getId(), null); + saveEdgeEvent(edge.getTenantId(), edge.getId(), EdgeEventType.DEVICE, EdgeEventActionType.ADDED, device.getId(), null); } } } catch (Exception e) { @@ -184,12 +187,13 @@ public class DefaultSyncEdgeService implements SyncEdgeService { } private void syncAssets(Edge edge) { + log.trace("[{}] syncAssets [{}]", edge.getTenantId(), edge.getName()); try { PageData pageData = assetService.findAssetsByTenantIdAndEdgeId(edge.getTenantId(), edge.getId(), new TimePageLink(Integer.MAX_VALUE)); if (pageData != null && pageData.getData() != null && !pageData.getData().isEmpty()) { log.trace("[{}] [{}] asset(s) are going to be pushed to edge.", edge.getId(), pageData.getData().size()); for (Asset asset : pageData.getData()) { - saveEdgeEvent(edge.getTenantId(), edge.getId(), EdgeEventType.ASSET, ActionType.ADDED, asset.getId(), null); + saveEdgeEvent(edge.getTenantId(), edge.getId(), EdgeEventType.ASSET, EdgeEventActionType.ADDED, asset.getId(), null); } } } catch (Exception e) { @@ -198,12 +202,13 @@ public class DefaultSyncEdgeService implements SyncEdgeService { } private void syncEntityViews(Edge edge) { + log.trace("[{}] syncEntityViews [{}]", edge.getTenantId(), edge.getName()); try { PageData pageData = entityViewService.findEntityViewsByTenantIdAndEdgeId(edge.getTenantId(), edge.getId(), new TimePageLink(Integer.MAX_VALUE)); if (pageData != null && pageData.getData() != null && !pageData.getData().isEmpty()) { log.trace("[{}] [{}] entity view(s) are going to be pushed to edge.", edge.getId(), pageData.getData().size()); for (EntityView entityView : pageData.getData()) { - saveEdgeEvent(edge.getTenantId(), edge.getId(), EdgeEventType.ENTITY_VIEW, ActionType.ADDED, entityView.getId(), null); + saveEdgeEvent(edge.getTenantId(), edge.getId(), EdgeEventType.ENTITY_VIEW, EdgeEventActionType.ADDED, entityView.getId(), null); } } } catch (Exception e) { @@ -212,12 +217,13 @@ public class DefaultSyncEdgeService implements SyncEdgeService { } private void syncDashboards(Edge edge) { + log.trace("[{}] syncDashboards [{}]", edge.getTenantId(), edge.getName()); try { PageData pageData = dashboardService.findDashboardsByTenantIdAndEdgeId(edge.getTenantId(), edge.getId(), new TimePageLink(Integer.MAX_VALUE)); if (pageData != null && pageData.getData() != null && !pageData.getData().isEmpty()) { log.trace("[{}] [{}] dashboard(s) are going to be pushed to edge.", edge.getId(), pageData.getData().size()); for (DashboardInfo dashboardInfo : pageData.getData()) { - saveEdgeEvent(edge.getTenantId(), edge.getId(), EdgeEventType.DASHBOARD, ActionType.ADDED, dashboardInfo.getId(), null); + saveEdgeEvent(edge.getTenantId(), edge.getId(), EdgeEventType.DASHBOARD, EdgeEventActionType.ADDED, dashboardInfo.getId(), null); } } } catch (Exception e) { @@ -226,11 +232,12 @@ public class DefaultSyncEdgeService implements SyncEdgeService { } private void syncUsers(Edge edge) { + log.trace("[{}] syncUsers [{}]", edge.getTenantId(), edge.getName()); try { PageData pageData = userService.findTenantAdmins(edge.getTenantId(), new PageLink(Integer.MAX_VALUE)); pushUsersToEdge(pageData, edge); if (edge.getCustomerId() != null && !EntityId.NULL_UUID.equals(edge.getCustomerId().getId())) { - saveEdgeEvent(edge.getTenantId(), edge.getId(), EdgeEventType.CUSTOMER, ActionType.ADDED, edge.getCustomerId(), null); + saveEdgeEvent(edge.getTenantId(), edge.getId(), EdgeEventType.CUSTOMER, EdgeEventActionType.ADDED, edge.getCustomerId(), null); pageData = userService.findCustomerUsers(edge.getTenantId(), edge.getCustomerId(), new PageLink(Integer.MAX_VALUE)); pushUsersToEdge(pageData, edge); } @@ -240,17 +247,18 @@ public class DefaultSyncEdgeService implements SyncEdgeService { } private void syncWidgetsBundleAndWidgetTypes(Edge edge) { + log.trace("[{}] syncWidgetsBundleAndWidgetTypes [{}]", edge.getTenantId(), edge.getName()); List widgetsBundlesToPush = new ArrayList<>(); List widgetTypesToPush = new ArrayList<>(); widgetsBundlesToPush.addAll(widgetsBundleService.findAllTenantWidgetsBundlesByTenantId(edge.getTenantId())); widgetsBundlesToPush.addAll(widgetsBundleService.findSystemWidgetsBundles(edge.getTenantId())); try { for (WidgetsBundle widgetsBundle: widgetsBundlesToPush) { - saveEdgeEvent(edge.getTenantId(), edge.getId(), EdgeEventType.WIDGETS_BUNDLE, ActionType.ADDED, widgetsBundle.getId(), null); + saveEdgeEvent(edge.getTenantId(), edge.getId(), EdgeEventType.WIDGETS_BUNDLE, EdgeEventActionType.ADDED, widgetsBundle.getId(), null); widgetTypesToPush.addAll(widgetTypeService.findWidgetTypesByTenantIdAndBundleAlias(widgetsBundle.getTenantId(), widgetsBundle.getAlias())); } for (WidgetType widgetType: widgetTypesToPush) { - saveEdgeEvent(edge.getTenantId(), edge.getId(), EdgeEventType.WIDGET_TYPE, ActionType.ADDED, widgetType.getId(), null); + saveEdgeEvent(edge.getTenantId(), edge.getId(), EdgeEventType.WIDGET_TYPE, EdgeEventActionType.ADDED, widgetType.getId(), null); } } catch (Exception e) { log.error("Exception during loading widgets bundle(s) and widget type(s) on sync!", e); @@ -258,15 +266,16 @@ public class DefaultSyncEdgeService implements SyncEdgeService { } private void syncAdminSettings(Edge edge) { + log.trace("[{}] syncAdminSettings [{}]", edge.getTenantId(), edge.getName()); try { AdminSettings systemMailSettings = adminSettingsService.findAdminSettingsByKey(TenantId.SYS_TENANT_ID, "mail"); - saveEdgeEvent(edge.getTenantId(), edge.getId(), EdgeEventType.ADMIN_SETTINGS, ActionType.UPDATED, null, mapper.valueToTree(systemMailSettings)); + saveEdgeEvent(edge.getTenantId(), edge.getId(), EdgeEventType.ADMIN_SETTINGS, EdgeEventActionType.UPDATED, null, mapper.valueToTree(systemMailSettings)); AdminSettings tenantMailSettings = convertToTenantAdminSettings(systemMailSettings.getKey(), (ObjectNode) systemMailSettings.getJsonValue()); - saveEdgeEvent(edge.getTenantId(), edge.getId(), EdgeEventType.ADMIN_SETTINGS, ActionType.UPDATED, null, mapper.valueToTree(tenantMailSettings)); + saveEdgeEvent(edge.getTenantId(), edge.getId(), EdgeEventType.ADMIN_SETTINGS, EdgeEventActionType.UPDATED, null, mapper.valueToTree(tenantMailSettings)); AdminSettings systemMailTemplates = loadMailTemplates(); - saveEdgeEvent(edge.getTenantId(), edge.getId(), EdgeEventType.ADMIN_SETTINGS, ActionType.UPDATED, null, mapper.valueToTree(systemMailTemplates)); + saveEdgeEvent(edge.getTenantId(), edge.getId(), EdgeEventType.ADMIN_SETTINGS, EdgeEventActionType.UPDATED, null, mapper.valueToTree(systemMailTemplates)); AdminSettings tenantMailTemplates = convertToTenantAdminSettings(systemMailTemplates.getKey(), (ObjectNode) systemMailTemplates.getJsonValue()); - saveEdgeEvent(edge.getTenantId(), edge.getId(), EdgeEventType.ADMIN_SETTINGS, ActionType.UPDATED, null, mapper.valueToTree(tenantMailTemplates)); + saveEdgeEvent(edge.getTenantId(), edge.getId(), EdgeEventType.ADMIN_SETTINGS, EdgeEventActionType.UPDATED, null, mapper.valueToTree(tenantMailTemplates)); } catch (Exception e) { log.error("Can't load admin settings", e); } @@ -328,18 +337,19 @@ public class DefaultSyncEdgeService implements SyncEdgeService { if (pageData != null && pageData.getData() != null && !pageData.getData().isEmpty()) { log.trace("[{}] [{}] user(s) are going to be pushed to edge.", edge.getId(), pageData.getData().size()); for (User user : pageData.getData()) { - saveEdgeEvent(edge.getTenantId(), edge.getId(), EdgeEventType.USER, ActionType.ADDED, user.getId(), null); + saveEdgeEvent(edge.getTenantId(), edge.getId(), EdgeEventType.USER, EdgeEventActionType.ADDED, user.getId(), null); } } } @Override public ListenableFuture processRuleChainMetadataRequestMsg(Edge edge, RuleChainMetadataRequestMsg ruleChainMetadataRequestMsg) { + log.trace("[{}] processRuleChainMetadataRequestMsg [{}][{}]", edge.getTenantId(), edge.getName(), ruleChainMetadataRequestMsg); SettableFuture futureToSet = SettableFuture.create(); if (ruleChainMetadataRequestMsg.getRuleChainIdMSB() != 0 && ruleChainMetadataRequestMsg.getRuleChainIdLSB() != 0) { RuleChainId ruleChainId = new RuleChainId(new UUID(ruleChainMetadataRequestMsg.getRuleChainIdMSB(), ruleChainMetadataRequestMsg.getRuleChainIdLSB())); - ListenableFuture future = saveEdgeEvent(edge.getTenantId(), edge.getId(), EdgeEventType.RULE_CHAIN_METADATA, ActionType.ADDED, ruleChainId, null); + ListenableFuture future = saveEdgeEvent(edge.getTenantId(), edge.getId(), EdgeEventType.RULE_CHAIN_METADATA, EdgeEventActionType.ADDED, ruleChainId, null); Futures.addCallback(future, new FutureCallback() { @Override public void onSuccess(@Nullable EdgeEvent result) { @@ -358,6 +368,7 @@ public class DefaultSyncEdgeService implements SyncEdgeService { @Override public ListenableFuture processAttributesRequestMsg(Edge edge, AttributesRequestMsg attributesRequestMsg) { + log.trace("[{}] processAttributesRequestMsg [{}][{}]", edge.getTenantId(), edge.getName(), attributesRequestMsg); EntityId entityId = EntityIdFactory.getByTypeAndUuid( EntityType.valueOf(attributesRequestMsg.getEntityType()), new UUID(attributesRequestMsg.getEntityIdMSB(), attributesRequestMsg.getEntityIdLSB())); @@ -390,7 +401,7 @@ public class DefaultSyncEdgeService implements SyncEdgeService { saveEdgeEvent(edge.getTenantId(), edge.getId(), type, - ActionType.ATTRIBUTES_UPDATED, + EdgeEventActionType.ATTRIBUTES_UPDATED, entityId, body); } catch (Exception e) { @@ -431,6 +442,7 @@ public class DefaultSyncEdgeService implements SyncEdgeService { @Override public ListenableFuture processRelationRequestMsg(Edge edge, RelationRequestMsg relationRequestMsg) { + log.trace("[{}] processRelationRequestMsg [{}][{}]", edge.getTenantId(), edge.getName(), relationRequestMsg); EntityId entityId = EntityIdFactory.getByTypeAndUuid( EntityType.valueOf(relationRequestMsg.getEntityType()), new UUID(relationRequestMsg.getEntityIdMSB(), relationRequestMsg.getEntityIdLSB())); @@ -451,7 +463,7 @@ public class DefaultSyncEdgeService implements SyncEdgeService { saveEdgeEvent(edge.getTenantId(), edge.getId(), EdgeEventType.RELATION, - ActionType.ADDED, + EdgeEventActionType.ADDED, null, mapper.valueToTree(relation)); } @@ -477,10 +489,11 @@ public class DefaultSyncEdgeService implements SyncEdgeService { @Override public ListenableFuture processDeviceCredentialsRequestMsg(Edge edge, DeviceCredentialsRequestMsg deviceCredentialsRequestMsg) { + log.trace("[{}] processDeviceCredentialsRequestMsg [{}][{}]", edge.getTenantId(), edge.getName(), deviceCredentialsRequestMsg); SettableFuture futureToSet = SettableFuture.create(); if (deviceCredentialsRequestMsg.getDeviceIdMSB() != 0 && deviceCredentialsRequestMsg.getDeviceIdLSB() != 0) { DeviceId deviceId = new DeviceId(new UUID(deviceCredentialsRequestMsg.getDeviceIdMSB(), deviceCredentialsRequestMsg.getDeviceIdLSB())); - ListenableFuture future = saveEdgeEvent(edge.getTenantId(), edge.getId(), EdgeEventType.DEVICE, ActionType.CREDENTIALS_UPDATED, deviceId, null); + ListenableFuture future = saveEdgeEvent(edge.getTenantId(), edge.getId(), EdgeEventType.DEVICE, EdgeEventActionType.CREDENTIALS_UPDATED, deviceId, null); Futures.addCallback(future, new FutureCallback() { @Override public void onSuccess(@Nullable EdgeEvent result) { @@ -499,10 +512,11 @@ public class DefaultSyncEdgeService implements SyncEdgeService { @Override public ListenableFuture processUserCredentialsRequestMsg(Edge edge, UserCredentialsRequestMsg userCredentialsRequestMsg) { + log.trace("[{}] processUserCredentialsRequestMsg [{}][{}]", edge.getTenantId(), edge.getName(), userCredentialsRequestMsg); SettableFuture futureToSet = SettableFuture.create(); if (userCredentialsRequestMsg.getUserIdMSB() != 0 && userCredentialsRequestMsg.getUserIdLSB() != 0) { UserId userId = new UserId(new UUID(userCredentialsRequestMsg.getUserIdMSB(), userCredentialsRequestMsg.getUserIdLSB())); - ListenableFuture future = saveEdgeEvent(edge.getTenantId(), edge.getId(), EdgeEventType.USER, ActionType.CREDENTIALS_UPDATED, userId, null); + ListenableFuture future = saveEdgeEvent(edge.getTenantId(), edge.getId(), EdgeEventType.USER, EdgeEventActionType.CREDENTIALS_UPDATED, userId, null); Futures.addCallback(future, new FutureCallback() { @Override public void onSuccess(@Nullable EdgeEvent result) { @@ -522,17 +536,17 @@ public class DefaultSyncEdgeService implements SyncEdgeService { private ListenableFuture saveEdgeEvent(TenantId tenantId, EdgeId edgeId, EdgeEventType type, - ActionType action, + EdgeEventActionType action, EntityId entityId, JsonNode body) { - log.debug("Pushing edge event to edge queue. tenantId [{}], edgeId [{}], type [{}], action[{}], entityId [{}], body [{}]", + log.trace("Pushing edge event to edge queue. tenantId [{}], edgeId [{}], type [{}], action[{}], entityId [{}], body [{}]", tenantId, edgeId, type, action, entityId, body); EdgeEvent edgeEvent = new EdgeEvent(); edgeEvent.setTenantId(tenantId); edgeEvent.setEdgeId(edgeId); edgeEvent.setType(type); - edgeEvent.setAction(action.name()); + edgeEvent.setAction(action); if (entityId != null) { edgeEvent.setEntityId(entityId.getId()); } diff --git a/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/AlarmProcessor.java b/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/AlarmProcessor.java index c24b127e73..ac562a4dc5 100644 --- a/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/AlarmProcessor.java +++ b/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/AlarmProcessor.java @@ -34,6 +34,7 @@ import org.thingsboard.server.queue.util.TbCoreComponent; public class AlarmProcessor extends BaseProcessor { public ListenableFuture onAlarmUpdate(TenantId tenantId, AlarmUpdateMsg alarmUpdateMsg) { + log.trace("[{}] onAlarmUpdate [{}]", tenantId, alarmUpdateMsg); EntityId originatorId = getAlarmOriginator(tenantId, alarmUpdateMsg.getOriginatorName(), EntityType.valueOf(alarmUpdateMsg.getOriginatorType())); if (originatorId == null) { diff --git a/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/BaseProcessor.java b/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/BaseProcessor.java index 576c8ba667..8c43223c5c 100644 --- a/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/BaseProcessor.java +++ b/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/BaseProcessor.java @@ -20,8 +20,8 @@ import com.fasterxml.jackson.databind.ObjectMapper; import com.google.common.util.concurrent.ListenableFuture; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; -import org.thingsboard.server.common.data.audit.ActionType; import org.thingsboard.server.common.data.edge.EdgeEvent; +import org.thingsboard.server.common.data.edge.EdgeEventActionType; import org.thingsboard.server.common.data.edge.EdgeEventType; import org.thingsboard.server.common.data.id.EdgeId; import org.thingsboard.server.common.data.id.EntityId; @@ -39,7 +39,6 @@ import org.thingsboard.server.dao.relation.RelationService; import org.thingsboard.server.dao.user.UserService; import org.thingsboard.server.service.executors.DbCallbackExecutorService; import org.thingsboard.server.service.queue.TbClusterService; -import org.thingsboard.server.service.rpc.TbRuleEngineDeviceRpcService; import org.thingsboard.server.service.state.DeviceStateService; @Slf4j @@ -92,7 +91,7 @@ public abstract class BaseProcessor { protected ListenableFuture saveEdgeEvent(TenantId tenantId, EdgeId edgeId, EdgeEventType type, - ActionType action, + EdgeEventActionType action, EntityId entityId, JsonNode body) { log.debug("Pushing event to edge queue. tenantId [{}], edgeId [{}], type[{}], " + @@ -103,7 +102,7 @@ public abstract class BaseProcessor { edgeEvent.setTenantId(tenantId); edgeEvent.setEdgeId(edgeId); edgeEvent.setType(type); - edgeEvent.setAction(action.name()); + edgeEvent.setAction(action); if (entityId != null) { edgeEvent.setEntityId(entityId.getId()); } diff --git a/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/DeviceProcessor.java b/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/DeviceProcessor.java index 9d0f03cfab..aafcb73de3 100644 --- a/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/DeviceProcessor.java +++ b/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/DeviceProcessor.java @@ -27,8 +27,8 @@ import org.springframework.stereotype.Component; import org.thingsboard.rule.engine.api.RpcError; import org.thingsboard.server.common.data.DataConstants; import org.thingsboard.server.common.data.Device; -import org.thingsboard.server.common.data.audit.ActionType; import org.thingsboard.server.common.data.edge.Edge; +import org.thingsboard.server.common.data.edge.EdgeEventActionType; import org.thingsboard.server.common.data.edge.EdgeEventType; import org.thingsboard.server.common.data.id.CustomerId; import org.thingsboard.server.common.data.id.DeviceId; @@ -50,6 +50,7 @@ import org.thingsboard.server.queue.TbQueueCallback; import org.thingsboard.server.queue.TbQueueMsgMetadata; import org.thingsboard.server.queue.util.TbCoreComponent; import org.thingsboard.server.service.rpc.FromDeviceRpcResponse; +import org.thingsboard.server.service.rpc.FromDeviceRpcResponseActorMsg; import java.util.UUID; import java.util.concurrent.locks.ReentrantLock; @@ -62,22 +63,28 @@ public class DeviceProcessor extends BaseProcessor { private static final ReentrantLock deviceCreationLock = new ReentrantLock(); public ListenableFuture onDeviceUpdate(TenantId tenantId, Edge edge, DeviceUpdateMsg deviceUpdateMsg) { + log.trace("[{}] onDeviceUpdate [{}] from edge [{}]", tenantId, deviceUpdateMsg, edge.getName()); DeviceId edgeDeviceId = new DeviceId(new UUID(deviceUpdateMsg.getIdMSB(), deviceUpdateMsg.getIdLSB())); switch (deviceUpdateMsg.getMsgType()) { case ENTITY_CREATED_RPC_MESSAGE: String deviceName = deviceUpdateMsg.getName(); Device device = deviceService.findDeviceByTenantIdAndName(tenantId, deviceName); if (device != null) { - // device with this name already exists on the cloud - update ID on the edge + log.info("[{}] Device with name '{}' already exists on the cloud. Updating id of device entity on the edge", tenantId, deviceName); if (!device.getId().equals(edgeDeviceId)) { - saveEdgeEvent(tenantId, edge.getId(), EdgeEventType.DEVICE, ActionType.ENTITY_EXISTS_REQUEST, device.getId(), null); + saveEdgeEvent(tenantId, edge.getId(), EdgeEventType.DEVICE, EdgeEventActionType.ENTITY_EXISTS_REQUEST, device.getId(), null); } } else { - device = createDevice(tenantId, edge, deviceUpdateMsg); - saveEdgeEvent(tenantId, edge.getId(), EdgeEventType.DEVICE, ActionType.ENTITY_EXISTS_REQUEST, device.getId(), null); + Device deviceById = deviceService.findDeviceById(edge.getTenantId(), edgeDeviceId); + if (deviceById != null) { + log.info("[{}] Device ID [{}] already used by other device on the cloud. Creating new device and replacing device entity on the edge", tenantId, edgeDeviceId.getId()); + device = createDevice(tenantId, edge, deviceUpdateMsg); - // TODO: voba - properly handle device credentials from edge to cloud - // saveEdgeEvent(tenantId, edge.getId(), EdgeEventType.DEVICE, ActionType.CREDENTIALS_REQUEST, device.getId(), null); + // TODO: voba - properly handle device credentials from edge to cloud + saveEdgeEvent(tenantId, edge.getId(), EdgeEventType.DEVICE, EdgeEventActionType.ENTITY_EXISTS_REQUEST, device.getId(), null); + } else { + device = createDevice(tenantId, edge, deviceUpdateMsg); + } } // TODO: voba - assign device only in case device is not assigned yet. Missing functionality to check this relation prior assignment deviceService.assignDeviceToEdge(edge.getTenantId(), device.getId(), edge.getId()); @@ -132,13 +139,14 @@ public class DeviceProcessor extends BaseProcessor { device.setAdditionalInfo(JacksonUtil.toJsonNode(deviceUpdateMsg.getAdditionalInfo())); deviceService.saveDevice(device); - saveEdgeEvent(tenantId, edge.getId(), EdgeEventType.DEVICE, ActionType.CREDENTIALS_REQUEST, deviceId, null); + saveEdgeEvent(tenantId, edge.getId(), EdgeEventType.DEVICE, EdgeEventActionType.CREDENTIALS_REQUEST, deviceId, null); } private Device createDevice(TenantId tenantId, Edge edge, DeviceUpdateMsg deviceUpdateMsg) { Device device; try { deviceCreationLock.lock(); + log.debug("[{}] Creating device entity [{}] from edge [{}]", tenantId, deviceUpdateMsg, edge.getName()); device = new Device(); device.setTenantId(edge.getTenantId()); device.setCustomerId(edge.getCustomerId()); @@ -152,6 +160,8 @@ public class DeviceProcessor extends BaseProcessor { createRelationFromEdge(tenantId, edge.getId(), device.getId()); deviceStateService.onDeviceAdded(device); pushDeviceCreatedEventToRuleEngine(tenantId, edge, device); + + // saveEdgeEvent(tenantId, edge.getId(), EdgeEventType.DEVICE, EdgeEventActionType.CREDENTIALS_REQUEST, deviceId, null); } finally { deviceCreationLock.unlock(); } @@ -184,24 +194,19 @@ public class DeviceProcessor extends BaseProcessor { tbClusterService.pushMsgToRuleEngine(tenantId, deviceId, tbMsg, new TbQueueCallback() { @Override public void onSuccess(TbQueueMsgMetadata metadata) { - // TODO: voba - handle success log.debug("Successfully send ENTITY_CREATED EVENT to rule engine [{}]", device); } @Override public void onFailure(Throwable t) { - // TODO: voba - handle failure log.debug("Failed to send ENTITY_CREATED EVENT to rule engine [{}]", device, t); } - - ; }); } catch (JsonProcessingException | IllegalArgumentException e) { log.warn("[{}] Failed to push device action to rule engine: {}", device.getId(), DataConstants.ENTITY_CREATED, e); } } - private TbMsgMetaData getActionTbMsgMetaData(Edge edge, CustomerId customerId) { TbMsgMetaData metaData = getTbMsgMetaData(edge); if (customerId != null && !customerId.isNullUid()) { @@ -210,7 +215,6 @@ public class DeviceProcessor extends BaseProcessor { return metaData; } - private TbMsgMetaData getTbMsgMetaData(Edge edge) { TbMsgMetaData metaData = new TbMsgMetaData(); metaData.putValue("edgeId", edge.getId().toString()); @@ -219,13 +223,16 @@ public class DeviceProcessor extends BaseProcessor { } public ListenableFuture processDeviceRpcCallResponseMsg(TenantId tenantId, DeviceRpcCallMsg deviceRpcCallMsg) { + log.trace("[{}] processDeviceRpcCallResponseMsg [{}]", tenantId, deviceRpcCallMsg); SettableFuture futureToSet = SettableFuture.create(); - UUID uuid = new UUID(deviceRpcCallMsg.getRequestIdMSB(), deviceRpcCallMsg.getRequestIdLSB()); + UUID requestUuid = new UUID(deviceRpcCallMsg.getRequestUuidMSB(), deviceRpcCallMsg.getRequestUuidLSB()); + DeviceId deviceId = new DeviceId(new UUID(deviceRpcCallMsg.getDeviceIdMSB(), deviceRpcCallMsg.getDeviceIdLSB())); + FromDeviceRpcResponse response; if (!StringUtils.isEmpty(deviceRpcCallMsg.getResponseMsg().getError())) { - response = new FromDeviceRpcResponse(uuid, null, RpcError.valueOf(deviceRpcCallMsg.getResponseMsg().getError())); + response = new FromDeviceRpcResponse(requestUuid, null, RpcError.valueOf(deviceRpcCallMsg.getResponseMsg().getError())); } else { - response = new FromDeviceRpcResponse(uuid, deviceRpcCallMsg.getResponseMsg().getResponse(), null); + response = new FromDeviceRpcResponse(requestUuid, deviceRpcCallMsg.getResponseMsg().getResponse(), null); } TbQueueCallback callback = new TbQueueCallback() { @Override @@ -239,7 +246,11 @@ public class DeviceProcessor extends BaseProcessor { futureToSet.setException(t); } }; - tbClusterService.pushNotificationToCore(deviceRpcCallMsg.getOriginServiceId(), response, callback); + FromDeviceRpcResponseActorMsg msg = + new FromDeviceRpcResponseActorMsg(deviceRpcCallMsg.getRequestId(), + tenantId, + deviceId, response); + tbClusterService.pushMsgToCore(msg, callback); return futureToSet; } diff --git a/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/RelationProcessor.java b/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/RelationProcessor.java index 21849e74cd..7ad316e70a 100644 --- a/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/RelationProcessor.java +++ b/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/RelationProcessor.java @@ -44,7 +44,7 @@ import java.util.UUID; public class RelationProcessor extends BaseProcessor { public ListenableFuture onRelationUpdate(TenantId tenantId, RelationUpdateMsg relationUpdateMsg) { - log.info("onRelationUpdate {}", relationUpdateMsg); + log.trace("[{}] onRelationUpdate [{}]", tenantId, relationUpdateMsg); try { EntityRelation entityRelation = new EntityRelation(); diff --git a/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/TelemetryProcessor.java b/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/TelemetryProcessor.java index 2fdd5614aa..7fa76d7d67 100644 --- a/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/TelemetryProcessor.java +++ b/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/TelemetryProcessor.java @@ -66,6 +66,7 @@ public class TelemetryProcessor extends BaseProcessor { private final Gson gson = new Gson(); public List> onTelemetryUpdate(TenantId tenantId, EntityDataProto entityData) { + log.trace("[{}] onTelemetryUpdate [{}]", tenantId, entityData); List> result = new ArrayList<>(); EntityId entityId = constructEntityId(entityData); if ((entityData.hasPostAttributesMsg() || entityData.hasPostTelemetryMsg() || entityData.hasAttributesUpdatedMsg()) && entityId != null) { diff --git a/application/src/main/java/org/thingsboard/server/service/install/InstallScripts.java b/application/src/main/java/org/thingsboard/server/service/install/InstallScripts.java index 163d215f89..ff74c1cb14 100644 --- a/application/src/main/java/org/thingsboard/server/service/install/InstallScripts.java +++ b/application/src/main/java/org/thingsboard/server/service/install/InstallScripts.java @@ -211,7 +211,6 @@ public class InstallScripts { try { createDefaultRuleChains(tenantId); createDefaultRuleChain(tenantId, "Thermostat"); - createDefaultEdgeRuleChains(tenantId); } catch (Exception e) { log.error("Unable to load dashboard from json", e); throw new RuntimeException("Unable to load dashboard from json", e); diff --git a/application/src/main/java/org/thingsboard/server/service/rpc/DefaultTbRuleEngineRpcService.java b/application/src/main/java/org/thingsboard/server/service/rpc/DefaultTbRuleEngineRpcService.java index 9ebbed0e44..80d47a84e8 100644 --- a/application/src/main/java/org/thingsboard/server/service/rpc/DefaultTbRuleEngineRpcService.java +++ b/application/src/main/java/org/thingsboard/server/service/rpc/DefaultTbRuleEngineRpcService.java @@ -151,8 +151,7 @@ public class DefaultTbRuleEngineRpcService implements TbRuleEngineDeviceRpcServi } } - @Override - public void sendRpcResponseToTbCore(String originServiceId, FromDeviceRpcResponse response) { + private void sendRpcResponseToTbCore(String originServiceId, FromDeviceRpcResponse response) { if (serviceId.equals(originServiceId)) { if (tbCoreRpcService.isPresent()) { tbCoreRpcService.get().processRpcResponseFromRuleEngine(response); diff --git a/application/src/main/java/org/thingsboard/server/service/rpc/FromDeviceRpcResponse.java b/application/src/main/java/org/thingsboard/server/service/rpc/FromDeviceRpcResponse.java index c1e5e2e038..7f684edc32 100644 --- a/application/src/main/java/org/thingsboard/server/service/rpc/FromDeviceRpcResponse.java +++ b/application/src/main/java/org/thingsboard/server/service/rpc/FromDeviceRpcResponse.java @@ -20,6 +20,7 @@ import lombok.RequiredArgsConstructor; import lombok.ToString; import org.thingsboard.rule.engine.api.RpcError; +import java.io.Serializable; import java.util.Optional; import java.util.UUID; @@ -28,7 +29,7 @@ import java.util.UUID; */ @RequiredArgsConstructor @ToString -public class FromDeviceRpcResponse { +public class FromDeviceRpcResponse implements Serializable { @Getter private final UUID id; private final String response; diff --git a/application/src/main/java/org/thingsboard/server/service/rpc/FromDeviceRpcResponseActorMsg.java b/application/src/main/java/org/thingsboard/server/service/rpc/FromDeviceRpcResponseActorMsg.java new file mode 100644 index 0000000000..9db6795251 --- /dev/null +++ b/application/src/main/java/org/thingsboard/server/service/rpc/FromDeviceRpcResponseActorMsg.java @@ -0,0 +1,44 @@ +/** + * Copyright © 2016-2020 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.rpc; + +import lombok.Getter; +import lombok.RequiredArgsConstructor; +import lombok.ToString; +import org.thingsboard.rule.engine.api.msg.ToDeviceActorNotificationMsg; +import org.thingsboard.server.common.data.id.DeviceId; +import org.thingsboard.server.common.data.id.TenantId; +import org.thingsboard.server.common.msg.MsgType; + +@ToString +@RequiredArgsConstructor +public class FromDeviceRpcResponseActorMsg implements ToDeviceActorNotificationMsg { + + @Getter + private final Integer requestId; + @Getter + private final TenantId tenantId; + @Getter + private final DeviceId deviceId; + + @Getter + private final FromDeviceRpcResponse msg; + + @Override + public MsgType getMsgType() { + return MsgType.DEVICE_RPC_RESPONSE_TO_DEVICE_ACTOR_MSG; + } +} diff --git a/application/src/main/java/org/thingsboard/server/service/rpc/TbRuleEngineDeviceRpcService.java b/application/src/main/java/org/thingsboard/server/service/rpc/TbRuleEngineDeviceRpcService.java index 4739338c6c..f12ac6a9ae 100644 --- a/application/src/main/java/org/thingsboard/server/service/rpc/TbRuleEngineDeviceRpcService.java +++ b/application/src/main/java/org/thingsboard/server/service/rpc/TbRuleEngineDeviceRpcService.java @@ -28,14 +28,4 @@ public interface TbRuleEngineDeviceRpcService extends RuleEngineRpcService { * @param response the RPC response */ void processRpcResponseFromDevice(FromDeviceRpcResponse response); - - - /** - * Sends Rpc response from the Device to TB Core. - * - * @param originServiceId Service ID of the origin component - * @param response the RPC response - */ - void sendRpcResponseToTbCore(String originServiceId, FromDeviceRpcResponse response); - } diff --git a/application/src/main/java/org/thingsboard/server/service/security/permission/Resource.java b/application/src/main/java/org/thingsboard/server/service/security/permission/Resource.java index 0ee1fa9266..5f751f9f68 100644 --- a/application/src/main/java/org/thingsboard/server/service/security/permission/Resource.java +++ b/application/src/main/java/org/thingsboard/server/service/security/permission/Resource.java @@ -27,7 +27,6 @@ public enum Resource { CUSTOMER(EntityType.CUSTOMER), DASHBOARD(EntityType.DASHBOARD), ENTITY_VIEW(EntityType.ENTITY_VIEW), - EDGE(EntityType.EDGE), TENANT(EntityType.TENANT), RULE_CHAIN(EntityType.RULE_CHAIN), USER(EntityType.USER), @@ -37,7 +36,8 @@ public enum Resource { OAUTH2_CONFIGURATION_TEMPLATE(), TENANT_PROFILE(EntityType.TENANT_PROFILE), DEVICE_PROFILE(EntityType.DEVICE_PROFILE), - API_USAGE_STATE(EntityType.API_USAGE_STATE); + API_USAGE_STATE(EntityType.API_USAGE_STATE), + EDGE(EntityType.EDGE); private final EntityType entityType; diff --git a/application/src/main/java/org/thingsboard/server/service/ttl/edge/EdgeEventsCleanUpService.java b/application/src/main/java/org/thingsboard/server/service/ttl/edge/EdgeEventsCleanUpService.java index 3a84701a36..53fea1e01f 100644 --- a/application/src/main/java/org/thingsboard/server/service/ttl/edge/EdgeEventsCleanUpService.java +++ b/application/src/main/java/org/thingsboard/server/service/ttl/edge/EdgeEventsCleanUpService.java @@ -53,4 +53,4 @@ public class EdgeEventsCleanUpService extends AbstractCleanUpService { long totalEdgeEventsRemoved = executeQuery(connection, "call cleanup_edge_events_by_ttl(" + ttl + ", 0);"); log.info("Total edge events removed by TTL: [{}]", totalEdgeEventsRemoved); } -} \ No newline at end of file +} 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 3a2f5f8bde..4b73534957 100644 --- a/application/src/test/java/org/thingsboard/server/edge/BaseEdgeTest.java +++ b/application/src/test/java/org/thingsboard/server/edge/BaseEdgeTest.java @@ -16,11 +16,15 @@ package org.thingsboard.server.edge; import com.datastax.oss.driver.api.core.uuid.Uuids; +import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.core.type.TypeReference; import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.node.ObjectNode; import com.google.gson.JsonObject; import com.google.protobuf.AbstractMessage; +import com.google.protobuf.InvalidProtocolBufferException; +import com.google.protobuf.MessageLite; import lombok.extern.slf4j.Slf4j; import org.junit.After; import org.junit.Assert; @@ -40,11 +44,13 @@ import org.thingsboard.server.common.data.alarm.AlarmInfo; import org.thingsboard.server.common.data.alarm.AlarmSeverity; import org.thingsboard.server.common.data.alarm.AlarmStatus; import org.thingsboard.server.common.data.asset.Asset; -import org.thingsboard.server.common.data.audit.ActionType; import org.thingsboard.server.common.data.edge.Edge; import org.thingsboard.server.common.data.edge.EdgeEvent; +import org.thingsboard.server.common.data.edge.EdgeEventActionType; import org.thingsboard.server.common.data.edge.EdgeEventType; import org.thingsboard.server.common.data.id.EdgeId; +import org.thingsboard.server.common.data.id.EntityId; +import org.thingsboard.server.common.data.id.EntityIdFactory; import org.thingsboard.server.common.data.id.RuleChainId; import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.common.data.id.UserId; @@ -53,9 +59,12 @@ import org.thingsboard.server.common.data.page.PageLink; import org.thingsboard.server.common.data.relation.EntityRelation; import org.thingsboard.server.common.data.relation.RelationTypeGroup; import org.thingsboard.server.common.data.rule.RuleChain; +import org.thingsboard.server.common.data.rule.RuleChainMetaData; import org.thingsboard.server.common.data.rule.RuleChainType; +import org.thingsboard.server.common.data.rule.RuleNode; import org.thingsboard.server.common.data.security.Authority; import org.thingsboard.server.common.data.security.DeviceCredentials; +import org.thingsboard.server.common.data.security.DeviceCredentialsType; import org.thingsboard.server.common.data.widget.WidgetType; import org.thingsboard.server.common.data.widget.WidgetsBundle; import org.thingsboard.server.common.transport.adaptor.JsonConverter; @@ -65,15 +74,20 @@ import org.thingsboard.server.dao.util.mapping.JacksonUtil; import org.thingsboard.server.edge.imitator.EdgeImitator; import org.thingsboard.server.gen.edge.AlarmUpdateMsg; import org.thingsboard.server.gen.edge.AssetUpdateMsg; +import org.thingsboard.server.gen.edge.AttributeDeleteMsg; +import org.thingsboard.server.gen.edge.AttributesRequestMsg; import org.thingsboard.server.gen.edge.CustomerUpdateMsg; import org.thingsboard.server.gen.edge.DashboardUpdateMsg; import org.thingsboard.server.gen.edge.DeviceCredentialsRequestMsg; import org.thingsboard.server.gen.edge.DeviceCredentialsUpdateMsg; +import org.thingsboard.server.gen.edge.DeviceRpcCallMsg; import org.thingsboard.server.gen.edge.DeviceUpdateMsg; import org.thingsboard.server.gen.edge.EdgeConfiguration; import org.thingsboard.server.gen.edge.EntityDataProto; import org.thingsboard.server.gen.edge.EntityViewUpdateMsg; +import org.thingsboard.server.gen.edge.RelationRequestMsg; import org.thingsboard.server.gen.edge.RelationUpdateMsg; +import org.thingsboard.server.gen.edge.RpcResponseMsg; import org.thingsboard.server.gen.edge.RuleChainMetadataRequestMsg; import org.thingsboard.server.gen.edge.RuleChainMetadataUpdateMsg; import org.thingsboard.server.gen.edge.RuleChainUpdateMsg; @@ -85,10 +99,13 @@ import org.thingsboard.server.gen.edge.WidgetTypeUpdateMsg; import org.thingsboard.server.gen.edge.WidgetsBundleUpdateMsg; import org.thingsboard.server.gen.transport.TransportProtos; +import java.util.ArrayList; import java.util.List; import java.util.Map; import java.util.Optional; +import java.util.Random; import java.util.UUID; +import java.util.concurrent.TimeUnit; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; @@ -134,7 +151,6 @@ abstract public class BaseEdgeTest extends AbstractControllerTest { @After public void afterTest() throws Exception { edgeImitator.disconnect(); - uninstallation(); loginSysAdmin(); @@ -158,9 +174,68 @@ abstract public class BaseEdgeTest extends AbstractControllerTest { testTimeseries(); testAttributes(); testSendMessagesToCloud(); + testRpcCall(); // TODO: voba - test conflict messages in case device with current name already exist or ID is already used } + private Device findDeviceByName(String deviceName) throws Exception { + List edgeDevices = doGetTypedWithPageLink("/api/edge/" + edge.getId().getId().toString() + "/devices?", + new TypeReference>() { + }, new PageLink(100)).getData(); + Optional foundDevice = edgeDevices.stream().filter(d -> d.getName().equals(deviceName)).findAny(); + Assert.assertTrue(foundDevice.isPresent()); + Device device = foundDevice.get(); + Assert.assertEquals(deviceName, device.getName()); + return device; + } + + private Asset findAssetByName(String assetName) throws Exception { + List edgeAssets = doGetTypedWithPageLink("/api/edge/" + edge.getId().getId().toString() + "/assets?", + new TypeReference>() { + }, new PageLink(100)).getData(); + + Assert.assertEquals(1, edgeAssets.size()); + Asset asset = edgeAssets.get(0); + Assert.assertEquals(assetName, asset.getName()); + return asset; + } + + private Device saveDevice(String deviceName) throws Exception { + Device device = new Device(); + device.setName(deviceName); + device.setType("test"); + return doPost("/api/device", device, Device.class); + } + + private Asset saveAsset(String assetName) throws Exception { + Asset asset = new Asset(); + asset.setName(assetName); + asset.setType("test"); + return doPost("/api/asset", asset, Asset.class); + } + + private void testRpcCall() throws Exception { + Device device = findDeviceByName("Edge Device 1"); + + ObjectNode body = mapper.createObjectNode(); + body.put("requestId", new Random().nextInt()); + body.put("requestUUID", Uuids.timeBased().toString()); + body.put("oneway", false); + body.put("expirationTime", System.currentTimeMillis() + TimeUnit.SECONDS.toMillis(10)); + body.put("method", "test_method"); + body.put("params", "{\"param1\":\"value1\"}"); + + EdgeEvent edgeEvent = constructEdgeEvent(tenantId, edge.getId(), EdgeEventActionType.RPC_CALL, device.getId().getId(), EdgeEventType.DEVICE, body); + edgeImitator.expectMessageAmount(1); + edgeEventService.saveAsync(edgeEvent); + edgeImitator.waitForMessages(); + + AbstractMessage latestMessage = edgeImitator.getLatestMessage(); + Assert.assertTrue(latestMessage instanceof DeviceRpcCallMsg); + DeviceRpcCallMsg latestDeviceRpcCallMsg = (DeviceRpcCallMsg) latestMessage; + Assert.assertEquals("test_method", latestDeviceRpcCallMsg.getRequestMsg().getMethod()); + } + private void testReceivedInitialData() throws Exception { log.info("Checking received data"); edgeImitator.waitForMessages(); @@ -168,6 +243,8 @@ abstract public class BaseEdgeTest extends AbstractControllerTest { EdgeConfiguration configuration = edgeImitator.getConfiguration(); Assert.assertNotNull(configuration); + testAutoGeneratedCodeByProtobuf(configuration); + UserId userId = edgeImitator.getUserId(); Assert.assertNotNull(userId); @@ -193,6 +270,8 @@ abstract public class BaseEdgeTest extends AbstractControllerTest { new TypeReference>() {}, new PageLink(100)).getData(); Assert.assertTrue(edgeAssets.contains(asset)); + testAutoGeneratedCodeByProtobuf(assetUpdateMsg); + Optional optionalMsg3 = edgeImitator.findMessageByType(RuleChainUpdateMsg.class); Assert.assertTrue(optionalMsg3.isPresent()); RuleChainUpdateMsg ruleChainUpdateMsg = optionalMsg3.get(); @@ -204,16 +283,15 @@ abstract public class BaseEdgeTest extends AbstractControllerTest { new TypeReference>() {}, new PageLink(100)).getData(); Assert.assertTrue(edgeRuleChains.contains(ruleChain)); + testAutoGeneratedCodeByProtobuf(ruleChainUpdateMsg); + log.info("Received data checked"); } - private void testDevices() throws Exception { + private void testDevices() throws Exception { log.info("Testing devices"); - Device device = new Device(); - device.setName("Edge Device 2"); - device.setType("test"); - Device savedDevice = doPost("/api/device", device, Device.class); + Device savedDevice = saveDevice("Edge Device 2"); edgeImitator.expectMessageAmount(1); doPost("/api/edge/" + edge.getId().getId().toString() @@ -259,10 +337,7 @@ abstract public class BaseEdgeTest extends AbstractControllerTest { private void testAssets() throws Exception { log.info("Testing assets"); - Asset asset = new Asset(); - asset.setName("Edge Asset 2"); - asset.setType("test"); - Asset savedAsset = doPost("/api/asset", asset, Asset.class); + Asset savedAsset = saveAsset("Edge Asset 2"); edgeImitator.expectMessageAmount(1); doPost("/api/edge/" + edge.getId().getId().toString() @@ -312,6 +387,11 @@ abstract public class BaseEdgeTest extends AbstractControllerTest { ruleChain.setType(RuleChainType.EDGE); RuleChain savedRuleChain = doPost("/api/ruleChain", ruleChain, RuleChain.class); + createRuleChainMetadata(savedRuleChain); + + // Wait before rule chain metadata saved to database before rule chain is assigned to edge + Thread.sleep(1000); + edgeImitator.expectMessageAmount(1); doPost("/api/edge/" + edge.getId().getId().toString() + "/ruleChain/" + savedRuleChain.getId().getId().toString(), RuleChain.class); @@ -325,6 +405,8 @@ abstract public class BaseEdgeTest extends AbstractControllerTest { Assert.assertEquals(ruleChainUpdateMsg.getIdLSB(), savedRuleChain.getUuidId().getLeastSignificantBits()); Assert.assertEquals(ruleChainUpdateMsg.getName(), savedRuleChain.getName()); + testRuleChainMetadataRequestMsg(savedRuleChain.getId()); + edgeImitator.expectMessageAmount(1); doDelete("/api/edge/" + edge.getId().getId().toString() + "/ruleChain/" + savedRuleChain.getId().getId().toString(), RuleChain.class); @@ -352,6 +434,67 @@ abstract public class BaseEdgeTest extends AbstractControllerTest { log.info("RuleChains tested successfully"); } + private void testRuleChainMetadataRequestMsg(RuleChainId ruleChainId) throws Exception { + RuleChainMetadataRequestMsg.Builder ruleChainMetadataRequestMsgBuilder = RuleChainMetadataRequestMsg.newBuilder() + .setRuleChainIdMSB(ruleChainId.getId().getMostSignificantBits()) + .setRuleChainIdLSB(ruleChainId.getId().getLeastSignificantBits()); + testAutoGeneratedCodeByProtobuf(ruleChainMetadataRequestMsgBuilder); + + UplinkMsg.Builder uplinkMsgBuilder = UplinkMsg.newBuilder() + .addRuleChainMetadataRequestMsg(ruleChainMetadataRequestMsgBuilder.build()); + testAutoGeneratedCodeByProtobuf(uplinkMsgBuilder); + + edgeImitator.expectResponsesAmount(1); + edgeImitator.expectMessageAmount(1); + edgeImitator.sendUplinkMsg(uplinkMsgBuilder.build()); + edgeImitator.waitForResponses(); + edgeImitator.waitForMessages(); + + AbstractMessage latestMessage = edgeImitator.getLatestMessage(); + Assert.assertTrue(latestMessage instanceof RuleChainMetadataUpdateMsg); + RuleChainMetadataUpdateMsg ruleChainMetadataUpdateMsg = (RuleChainMetadataUpdateMsg) latestMessage; + RuleChainId receivedRuleChainId = + new RuleChainId(new UUID(ruleChainMetadataUpdateMsg.getRuleChainIdMSB(), ruleChainMetadataUpdateMsg.getRuleChainIdLSB())); + Assert.assertEquals(ruleChainId, receivedRuleChainId); + } + + private void createRuleChainMetadata(RuleChain ruleChain) throws Exception { + RuleChainMetaData ruleChainMetaData = new RuleChainMetaData(); + ruleChainMetaData.setRuleChainId(ruleChain.getId()); + + ObjectMapper mapper = new ObjectMapper(); + + RuleNode ruleNode1 = new RuleNode(); + ruleNode1.setName("name1"); + ruleNode1.setType("type1"); + ruleNode1.setConfiguration(mapper.readTree("\"key1\": \"val1\"")); + + RuleNode ruleNode2 = new RuleNode(); + ruleNode2.setName("name2"); + ruleNode2.setType("type2"); + ruleNode2.setConfiguration(mapper.readTree("\"key2\": \"val2\"")); + + RuleNode ruleNode3 = new RuleNode(); + ruleNode3.setName("name3"); + ruleNode3.setType("type3"); + ruleNode3.setConfiguration(mapper.readTree("\"key3\": \"val3\"")); + + List ruleNodes = new ArrayList<>(); + ruleNodes.add(ruleNode1); + ruleNodes.add(ruleNode2); + ruleNodes.add(ruleNode3); + ruleChainMetaData.setFirstNodeIndex(0); + ruleChainMetaData.setNodes(ruleNodes); + + ruleChainMetaData.addConnectionInfo(0, 1, "success"); + 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); + } + private void testDashboards() throws Exception { log.info("Testing Dashboards"); Dashboard dashboard = new Dashboard(); @@ -371,6 +514,8 @@ abstract public class BaseEdgeTest extends AbstractControllerTest { Assert.assertEquals(dashboardUpdateMsg.getIdLSB(), savedDashboard.getUuidId().getLeastSignificantBits()); Assert.assertEquals(dashboardUpdateMsg.getTitle(), savedDashboard.getName()); + testAutoGeneratedCodeByProtobuf(dashboardUpdateMsg); + edgeImitator.expectMessageAmount(1); savedDashboard.setTitle("Updated Edge Test Dashboard"); doPost("/api/dashboard", savedDashboard, Dashboard.class); @@ -411,17 +556,9 @@ abstract public class BaseEdgeTest extends AbstractControllerTest { private void testRelations() throws Exception { log.info("Testing Relations"); - List edgeDevices = doGetTypedWithPageLink("/api/edge/" + edge.getId().getId().toString() + "/devices?", - new TypeReference>() {}, new PageLink(100)).getData(); - List edgeAssets = doGetTypedWithPageLink("/api/edge/" + edge.getId().getId().toString() + "/assets?", - new TypeReference>() {}, new PageLink(100)).getData(); - Assert.assertEquals(1, edgeDevices.size()); - Assert.assertEquals(1, edgeAssets.size()); - Device device = edgeDevices.get(0); - Asset asset = edgeAssets.get(0); - Assert.assertEquals("Edge Device 1", device.getName()); - Assert.assertEquals("Edge Asset 1", asset.getName()); + Device device = findDeviceByName("Edge Device 1"); + Asset asset = findAssetByName("Edge Asset 1"); EntityRelation relation = new EntityRelation(); relation.setType("test"); @@ -464,7 +601,8 @@ abstract public class BaseEdgeTest extends AbstractControllerTest { Assert.assertEquals(relationUpdateMsg.getType(), relation.getType()); Assert.assertEquals(relationUpdateMsg.getFromIdMSB(), relation.getFrom().getId().getMostSignificantBits()); Assert.assertEquals(relationUpdateMsg.getFromIdLSB(), relation.getFrom().getId().getLeastSignificantBits()); - Assert.assertEquals(relationUpdateMsg.getToEntityType(), relation.getTo().getEntityType().name());Assert.assertEquals(relationUpdateMsg.getFromIdMSB(), relation.getFrom().getId().getMostSignificantBits()); + Assert.assertEquals(relationUpdateMsg.getToEntityType(), relation.getTo().getEntityType().name()); + Assert.assertEquals(relationUpdateMsg.getFromIdMSB(), relation.getFrom().getId().getMostSignificantBits()); Assert.assertEquals(relationUpdateMsg.getToIdLSB(), relation.getTo().getId().getLeastSignificantBits()); Assert.assertEquals(relationUpdateMsg.getToEntityType(), relation.getTo().getEntityType().name()); Assert.assertEquals(relationUpdateMsg.getTypeGroup(), relation.getTypeGroup().name()); @@ -474,11 +612,7 @@ abstract public class BaseEdgeTest extends AbstractControllerTest { private void testAlarms() throws Exception { log.info("Testing Alarms"); - List edgeDevices = doGetTypedWithPageLink("/api/edge/" + edge.getId().getId().toString() + "/devices?", - new TypeReference>() {}, new PageLink(100)).getData(); - Assert.assertEquals(1, edgeDevices.size()); - Device device = edgeDevices.get(0); - Assert.assertEquals("Edge Device 1", device.getName()); + Device device = findDeviceByName("Edge Device 1"); Alarm alarm = new Alarm(); alarm.setOriginator(device.getId()); @@ -527,17 +661,13 @@ abstract public class BaseEdgeTest extends AbstractControllerTest { Assert.assertEquals(alarmUpdateMsg.getStatus(), AlarmStatus.CLEARED_ACK.name()); doDelete("/api/alarm/" + savedAlarm.getId().getId().toString()) - .andExpect(status().isOk()); + .andExpect(status().isOk()); log.info("Alarms tested successfully"); } private void testEntityView() throws Exception { log.info("Testing EntityView"); - List edgeDevices = doGetTypedWithPageLink("/api/edge/" + edge.getId().getId().toString() + "/devices?", - new TypeReference>() {}, new PageLink(100)).getData(); - Assert.assertEquals(1, edgeDevices.size()); - Device device = edgeDevices.get(0); - Assert.assertEquals("Edge Device 1", device.getName()); + Device device = findDeviceByName("Edge Device 1"); EntityView entityView = new EntityView(); entityView.setName("Edge EntityView 1"); @@ -609,6 +739,8 @@ abstract public class BaseEdgeTest extends AbstractControllerTest { Assert.assertEquals(customerUpdateMsg.getIdLSB(), savedCustomer.getUuidId().getLeastSignificantBits()); Assert.assertEquals(customerUpdateMsg.getTitle(), savedCustomer.getTitle()); + testAutoGeneratedCodeByProtobuf(customerUpdateMsg); + edgeImitator.expectMessageAmount(1); doDelete("/api/customer/edge/" + edge.getId().getId().toString(), Edge.class); edgeImitator.waitForMessages(); @@ -654,6 +786,8 @@ abstract public class BaseEdgeTest extends AbstractControllerTest { Assert.assertEquals(widgetsBundleUpdateMsg.getAlias(), savedWidgetsBundle.getAlias()); Assert.assertEquals(widgetsBundleUpdateMsg.getTitle(), savedWidgetsBundle.getTitle()); + testAutoGeneratedCodeByProtobuf(widgetsBundleUpdateMsg); + WidgetType widgetType = new WidgetType(); widgetType.setName("Test Widget Type"); widgetType.setBundleAlias(savedWidgetsBundle.getAlias()); @@ -704,15 +838,11 @@ abstract public class BaseEdgeTest extends AbstractControllerTest { private void testTimeseries() throws Exception { log.info("Testing timeseries"); - List edgeDevices = doGetTypedWithPageLink("/api/edge/" + edge.getId().getId().toString() + "/devices?", - new TypeReference>() {}, new PageLink(100)).getData(); - Assert.assertEquals(1, edgeDevices.size()); - Device device = edgeDevices.get(0); - Assert.assertEquals("Edge Device 1", device.getName()); + Device device = findDeviceByName("Edge Device 1"); String timeseriesData = "{\"data\":{\"temperature\":25},\"ts\":" + System.currentTimeMillis() + "}"; JsonNode timeseriesEntityData = mapper.readTree(timeseriesData); - EdgeEvent edgeEvent1 = constructEdgeEvent(tenantId, edge.getId(), ActionType.TIMESERIES_UPDATED, device.getId().getId(), EdgeEventType.DEVICE, timeseriesEntityData); + EdgeEvent edgeEvent1 = constructEdgeEvent(tenantId, edge.getId(), EdgeEventActionType.TIMESERIES_UPDATED, device.getId().getId(), EdgeEventType.DEVICE, timeseriesEntityData); edgeImitator.expectMessageAmount(1); edgeEventService.saveAsync(edgeEvent1); edgeImitator.waitForMessages(); @@ -738,61 +868,92 @@ abstract public class BaseEdgeTest extends AbstractControllerTest { private void testAttributes() throws Exception { log.info("Testing attributes"); - List edgeDevices = doGetTypedWithPageLink("/api/edge/" + edge.getId().getId().toString() + "/devices?", - new TypeReference>() {}, new PageLink(100)).getData(); - Assert.assertEquals(1, edgeDevices.size()); - Device device = edgeDevices.get(0); - Assert.assertEquals("Edge Device 1", device.getName()); + Device device = findDeviceByName("Edge Device 1"); - String attributesData = "{\"scope\":\"SERVER_SCOPE\",\"kv\":{\"key\":\"value\"}}"; - JsonNode attributesEntityData = mapper.readTree(attributesData); - EdgeEvent edgeEvent1 = constructEdgeEvent(tenantId, edge.getId(), ActionType.ATTRIBUTES_UPDATED, device.getId().getId(), EdgeEventType.DEVICE, attributesEntityData); + testAttributesUpdatedMsg(device); + testPostAttributesMsg(device); + testAttributesDeleteMsg(device); + + log.info("Attributes tested successfully"); + } + + private void testAttributesDeleteMsg(Device device) throws JsonProcessingException, InterruptedException { + String deleteAttributesData = "{\"scope\":\"SERVER_SCOPE\",\"keys\":[\"key1\",\"key2\"]}"; + JsonNode deleteAttributesEntityData = mapper.readTree(deleteAttributesData); + EdgeEvent edgeEvent = constructEdgeEvent(tenantId, edge.getId(), EdgeEventActionType.ATTRIBUTES_DELETED, device.getId().getId(), EdgeEventType.DEVICE, deleteAttributesEntityData); edgeImitator.expectMessageAmount(1); - edgeEventService.saveAsync(edgeEvent1); + edgeEventService.saveAsync(edgeEvent); edgeImitator.waitForMessages(); AbstractMessage latestMessage = edgeImitator.getLatestMessage(); Assert.assertTrue(latestMessage instanceof EntityDataProto); EntityDataProto latestEntityDataMsg = (EntityDataProto) latestMessage; - Assert.assertEquals(latestEntityDataMsg.getEntityIdMSB(), device.getUuidId().getMostSignificantBits()); - Assert.assertEquals(latestEntityDataMsg.getEntityIdLSB(), device.getUuidId().getLeastSignificantBits()); - Assert.assertEquals(latestEntityDataMsg.getEntityType(), device.getId().getEntityType().name()); - Assert.assertEquals(latestEntityDataMsg.getPostAttributeScope(), attributesEntityData.get("scope").asText()); - Assert.assertTrue(latestEntityDataMsg.hasAttributesUpdatedMsg()); + Assert.assertEquals(device.getUuidId().getMostSignificantBits(), latestEntityDataMsg.getEntityIdMSB()); + Assert.assertEquals(device.getUuidId().getLeastSignificantBits(), latestEntityDataMsg.getEntityIdLSB()); + Assert.assertEquals(device.getId().getEntityType().name(), latestEntityDataMsg.getEntityType()); - TransportProtos.PostAttributeMsg attributesUpdatedMsg = latestEntityDataMsg.getAttributesUpdatedMsg(); - Assert.assertEquals(1, attributesUpdatedMsg.getKvCount()); - TransportProtos.KeyValueProto keyValueProto = attributesUpdatedMsg.getKv(0); - Assert.assertEquals("key", keyValueProto.getKey()); - Assert.assertEquals("value", keyValueProto.getStringV()); + Assert.assertTrue(latestEntityDataMsg.hasAttributeDeleteMsg()); - ((ObjectNode) attributesEntityData).put("isPostAttributes", true); - EdgeEvent edgeEvent2 = constructEdgeEvent(tenantId, edge.getId(), ActionType.ATTRIBUTES_UPDATED, device.getId().getId(), EdgeEventType.DEVICE, attributesEntityData); + AttributeDeleteMsg attributeDeleteMsg = latestEntityDataMsg.getAttributeDeleteMsg(); + Assert.assertEquals(attributeDeleteMsg.getScope(), deleteAttributesEntityData.get("scope").asText()); + + Assert.assertEquals(2, attributeDeleteMsg.getAttributeNamesCount()); + Assert.assertEquals("key1", attributeDeleteMsg.getAttributeNames(0)); + Assert.assertEquals("key2", attributeDeleteMsg.getAttributeNames(1)); + } + + private void testPostAttributesMsg(Device device) throws JsonProcessingException, InterruptedException { + String postAttributesData = "{\"scope\":\"SERVER_SCOPE\",\"kv\":{\"key2\":\"value2\"}}"; + JsonNode postAttributesEntityData = mapper.readTree(postAttributesData); + EdgeEvent edgeEvent = constructEdgeEvent(tenantId, edge.getId(), EdgeEventActionType.POST_ATTRIBUTES, device.getId().getId(), EdgeEventType.DEVICE, postAttributesEntityData); edgeImitator.expectMessageAmount(1); - edgeEventService.saveAsync(edgeEvent2); + edgeEventService.saveAsync(edgeEvent); edgeImitator.waitForMessages(); - latestMessage = edgeImitator.getLatestMessage(); + AbstractMessage latestMessage = edgeImitator.getLatestMessage(); Assert.assertTrue(latestMessage instanceof EntityDataProto); - latestEntityDataMsg = (EntityDataProto) latestMessage; - Assert.assertEquals(latestEntityDataMsg.getEntityIdMSB(), device.getUuidId().getMostSignificantBits()); - Assert.assertEquals(latestEntityDataMsg.getEntityIdLSB(), device.getUuidId().getLeastSignificantBits()); - Assert.assertEquals(latestEntityDataMsg.getEntityType(), device.getId().getEntityType().name()); - Assert.assertEquals(latestEntityDataMsg.getPostAttributeScope(), attributesEntityData.get("scope").asText()); + EntityDataProto latestEntityDataMsg = (EntityDataProto) latestMessage; + Assert.assertEquals(device.getUuidId().getMostSignificantBits(), latestEntityDataMsg.getEntityIdMSB()); + Assert.assertEquals(device.getUuidId().getLeastSignificantBits(), latestEntityDataMsg.getEntityIdLSB()); + Assert.assertEquals(device.getId().getEntityType().name(), latestEntityDataMsg.getEntityType()); + Assert.assertEquals("SERVER_SCOPE", latestEntityDataMsg.getPostAttributeScope()); Assert.assertTrue(latestEntityDataMsg.hasPostAttributesMsg()); - attributesUpdatedMsg = latestEntityDataMsg.getPostAttributesMsg(); - Assert.assertEquals(1, attributesUpdatedMsg.getKvCount()); - keyValueProto = attributesUpdatedMsg.getKv(0); - Assert.assertEquals("key", keyValueProto.getKey()); - Assert.assertEquals("value", keyValueProto.getStringV()); + TransportProtos.PostAttributeMsg postAttributesMsg = latestEntityDataMsg.getPostAttributesMsg(); + Assert.assertEquals(1, postAttributesMsg.getKvCount()); + TransportProtos.KeyValueProto keyValueProto = postAttributesMsg.getKv(0); + Assert.assertEquals("key2", keyValueProto.getKey()); + Assert.assertEquals("value2", keyValueProto.getStringV()); + } - log.info("Attributes tested successfully"); + private void testAttributesUpdatedMsg(Device device) throws JsonProcessingException, InterruptedException { + String attributesData = "{\"scope\":\"SERVER_SCOPE\",\"kv\":{\"key1\":\"value1\"}}"; + JsonNode attributesEntityData = mapper.readTree(attributesData); + EdgeEvent edgeEvent1 = constructEdgeEvent(tenantId, edge.getId(), EdgeEventActionType.ATTRIBUTES_UPDATED, device.getId().getId(), EdgeEventType.DEVICE, attributesEntityData); + edgeImitator.expectMessageAmount(1); + edgeEventService.saveAsync(edgeEvent1); + edgeImitator.waitForMessages(); + + AbstractMessage latestMessage = edgeImitator.getLatestMessage(); + Assert.assertTrue(latestMessage instanceof EntityDataProto); + EntityDataProto latestEntityDataMsg = (EntityDataProto) latestMessage; + Assert.assertEquals(device.getUuidId().getMostSignificantBits(), latestEntityDataMsg.getEntityIdMSB()); + Assert.assertEquals(device.getUuidId().getLeastSignificantBits(), latestEntityDataMsg.getEntityIdLSB()); + Assert.assertEquals(device.getId().getEntityType().name(), latestEntityDataMsg.getEntityType()); + Assert.assertEquals("SERVER_SCOPE", latestEntityDataMsg.getPostAttributeScope()); + Assert.assertTrue(latestEntityDataMsg.hasAttributesUpdatedMsg()); + + TransportProtos.PostAttributeMsg attributesUpdatedMsg = latestEntityDataMsg.getAttributesUpdatedMsg(); + Assert.assertEquals(1, attributesUpdatedMsg.getKvCount()); + TransportProtos.KeyValueProto keyValueProto = attributesUpdatedMsg.getKv(0); + Assert.assertEquals("key1", keyValueProto.getKey()); + Assert.assertEquals("value1", keyValueProto.getStringV()); } private void testSendMessagesToCloud() throws Exception { log.info("Sending messages to cloud"); sendDevice(); + sendRelationRequest(); sendAlarm(); sendTelemetry(); sendRelation(); @@ -800,22 +961,30 @@ abstract public class BaseEdgeTest extends AbstractControllerTest { sendRuleChainMetadataRequest(); sendUserCredentialsRequest(); sendDeviceCredentialsRequest(); + sendDeviceRpcResponse(); + sendDeviceCredentialsUpdate(); + sendAttributesRequest(); log.info("Messages were sent successfully"); } private void sendDevice() throws Exception { UUID uuid = Uuids.timeBased(); - UplinkMsg.Builder builder = UplinkMsg.newBuilder(); + UplinkMsg.Builder uplinkMsgBuilder = UplinkMsg.newBuilder(); DeviceUpdateMsg.Builder deviceUpdateMsgBuilder = DeviceUpdateMsg.newBuilder(); deviceUpdateMsgBuilder.setIdMSB(uuid.getMostSignificantBits()); deviceUpdateMsgBuilder.setIdLSB(uuid.getLeastSignificantBits()); deviceUpdateMsgBuilder.setName("Edge Device 2"); deviceUpdateMsgBuilder.setType("test"); deviceUpdateMsgBuilder.setMsgType(UpdateMsgType.ENTITY_CREATED_RPC_MESSAGE); - builder.addDeviceUpdateMsg(deviceUpdateMsgBuilder.build()); - edgeImitator.expectResponsesAmount(2); - edgeImitator.sendUplinkMsg(builder.build()); + testAutoGeneratedCodeByProtobuf(deviceUpdateMsgBuilder); + uplinkMsgBuilder.addDeviceUpdateMsg(deviceUpdateMsgBuilder.build()); + + edgeImitator.expectResponsesAmount(1); + + testAutoGeneratedCodeByProtobuf(uplinkMsgBuilder); + + edgeImitator.sendUplinkMsg(uplinkMsgBuilder.build()); edgeImitator.waitForResponses(); AbstractMessage latestMessage = edgeImitator.getLatestMessage(); @@ -829,23 +998,70 @@ abstract public class BaseEdgeTest extends AbstractControllerTest { Assert.assertEquals("Edge Device 2", device.getName()); } + private void sendRelationRequest() throws Exception { + Device device = findDeviceByName("Edge Device 1"); + Asset asset = findAssetByName("Edge Asset 1"); + + EntityRelation relation = new EntityRelation(); + relation.setType("test"); + relation.setFrom(device.getId()); + relation.setTo(asset.getId()); + relation.setTypeGroup(RelationTypeGroup.COMMON); + + edgeImitator.expectMessageAmount(1); + doPost("/api/relation", relation); + edgeImitator.waitForMessages(); + + UplinkMsg.Builder uplinkMsgBuilder = UplinkMsg.newBuilder(); + RelationRequestMsg.Builder relationRequestMsgBuilder = RelationRequestMsg.newBuilder(); + relationRequestMsgBuilder.setEntityIdMSB(device.getId().getId().getMostSignificantBits()); + relationRequestMsgBuilder.setEntityIdLSB(device.getId().getId().getLeastSignificantBits()); + relationRequestMsgBuilder.setEntityType(device.getId().getEntityType().name()); + testAutoGeneratedCodeByProtobuf(relationRequestMsgBuilder); + + uplinkMsgBuilder.addRelationRequestMsg(relationRequestMsgBuilder.build()); + testAutoGeneratedCodeByProtobuf(uplinkMsgBuilder); + + edgeImitator.expectResponsesAmount(1); + edgeImitator.expectMessageAmount(1); + edgeImitator.sendUplinkMsg(uplinkMsgBuilder.build()); + edgeImitator.waitForResponses(); + edgeImitator.waitForMessages(); + + AbstractMessage latestMessage = edgeImitator.getLatestMessage(); + Assert.assertTrue(latestMessage instanceof RelationUpdateMsg); + RelationUpdateMsg relationUpdateMsg = (RelationUpdateMsg) latestMessage; + Assert.assertEquals(UpdateMsgType.ENTITY_CREATED_RPC_MESSAGE, relationUpdateMsg.getMsgType()); + Assert.assertEquals(relation.getType(), relationUpdateMsg.getType()); + + UUID fromUUID = new UUID(relationUpdateMsg.getFromIdMSB(), relationUpdateMsg.getFromIdLSB()); + EntityId fromEntityId = EntityIdFactory.getByTypeAndUuid(relationUpdateMsg.getFromEntityType(), fromUUID); + Assert.assertEquals(relation.getFrom(), fromEntityId); + + UUID toUUID = new UUID(relationUpdateMsg.getToIdMSB(), relationUpdateMsg.getToIdLSB()); + EntityId toEntityId = EntityIdFactory.getByTypeAndUuid(relationUpdateMsg.getToEntityType(), toUUID); + Assert.assertEquals(relation.getTo(), toEntityId); + + Assert.assertEquals(relation.getTypeGroup().name(), relationUpdateMsg.getTypeGroup()); + } + private void sendAlarm() throws Exception { - List edgeDevices = doGetTypedWithPageLink("/api/edge/" + edge.getId().getId().toString() + "/devices?", - new TypeReference>() {}, new PageLink(100)).getData(); - Optional foundDevice = edgeDevices.stream().filter(device1 -> device1.getName().equals("Edge Device 2")).findAny(); - Assert.assertTrue(foundDevice.isPresent()); - Device device = foundDevice.get(); + Device device = findDeviceByName("Edge Device 2"); - UplinkMsg.Builder builder = UplinkMsg.newBuilder(); + UplinkMsg.Builder uplinkMsgBuilder = UplinkMsg.newBuilder(); AlarmUpdateMsg.Builder alarmUpdateMgBuilder = AlarmUpdateMsg.newBuilder(); alarmUpdateMgBuilder.setName("alarm from edge"); alarmUpdateMgBuilder.setStatus(AlarmStatus.ACTIVE_UNACK.name()); alarmUpdateMgBuilder.setSeverity(AlarmSeverity.CRITICAL.name()); alarmUpdateMgBuilder.setOriginatorName(device.getName()); alarmUpdateMgBuilder.setOriginatorType(EntityType.DEVICE.name()); - builder.addAlarmUpdateMsg(alarmUpdateMgBuilder.build()); + testAutoGeneratedCodeByProtobuf(alarmUpdateMgBuilder); + uplinkMsgBuilder.addAlarmUpdateMsg(alarmUpdateMgBuilder.build()); + + testAutoGeneratedCodeByProtobuf(uplinkMsgBuilder); + edgeImitator.expectResponsesAmount(1); - edgeImitator.sendUplinkMsg(builder.build()); + edgeImitator.sendUplinkMsg(uplinkMsgBuilder.build()); edgeImitator.waitForResponses(); @@ -871,7 +1087,7 @@ abstract public class BaseEdgeTest extends AbstractControllerTest { Assert.assertTrue(foundDevice2.isPresent()); Device device2 = foundDevice2.get(); - UplinkMsg.Builder builder = UplinkMsg.newBuilder(); + UplinkMsg.Builder uplinkMsgBuilder = UplinkMsg.newBuilder(); RelationUpdateMsg.Builder relationUpdateMsgBuilder = RelationUpdateMsg.newBuilder(); relationUpdateMsgBuilder.setType("test"); relationUpdateMsgBuilder.setTypeGroup(RelationTypeGroup.COMMON.name()); @@ -882,10 +1098,13 @@ abstract public class BaseEdgeTest extends AbstractControllerTest { relationUpdateMsgBuilder.setFromIdLSB(device2.getId().getId().getLeastSignificantBits()); relationUpdateMsgBuilder.setFromEntityType(device2.getId().getEntityType().name()); relationUpdateMsgBuilder.setAdditionalInfo("{}"); - builder.addRelationUpdateMsg(relationUpdateMsgBuilder.build()); - UplinkMsg msg = builder.build(); + testAutoGeneratedCodeByProtobuf(relationUpdateMsgBuilder); + uplinkMsgBuilder.addRelationUpdateMsg(relationUpdateMsgBuilder.build()); + + testAutoGeneratedCodeByProtobuf(uplinkMsgBuilder); + edgeImitator.expectResponsesAmount(1); - edgeImitator.sendUplinkMsg(msg); + edgeImitator.sendUplinkMsg(uplinkMsgBuilder.build()); edgeImitator.waitForResponses(); EntityRelation relation = doGet("/api/relation?" + @@ -911,28 +1130,35 @@ abstract public class BaseEdgeTest extends AbstractControllerTest { String timeseriesKey = "key"; String timeseriesValue = "25"; data.addProperty(timeseriesKey, timeseriesValue); - UplinkMsg.Builder builder1 = UplinkMsg.newBuilder(); + UplinkMsg.Builder uplinkMsgBuilder1 = UplinkMsg.newBuilder(); EntityDataProto.Builder entityDataBuilder = EntityDataProto.newBuilder(); entityDataBuilder.setPostTelemetryMsg(JsonConverter.convertToTelemetryProto(data, System.currentTimeMillis())); entityDataBuilder.setEntityType(device.getId().getEntityType().name()); entityDataBuilder.setEntityIdMSB(device.getUuidId().getMostSignificantBits()); entityDataBuilder.setEntityIdLSB(device.getUuidId().getLeastSignificantBits()); - builder1.addEntityData(entityDataBuilder.build()); - edgeImitator.sendUplinkMsg(builder1.build()); + testAutoGeneratedCodeByProtobuf(entityDataBuilder); + uplinkMsgBuilder1.addEntityData(entityDataBuilder.build()); + + testAutoGeneratedCodeByProtobuf(uplinkMsgBuilder1); + edgeImitator.sendUplinkMsg(uplinkMsgBuilder1.build()); JsonObject attributesData = new JsonObject(); String attributesKey = "test_attr"; String attributesValue = "test_value"; attributesData.addProperty(attributesKey, attributesValue); - UplinkMsg.Builder builder2 = UplinkMsg.newBuilder(); + UplinkMsg.Builder uplinkMsgBuilder2 = UplinkMsg.newBuilder(); EntityDataProto.Builder entityDataBuilder2 = EntityDataProto.newBuilder(); entityDataBuilder2.setEntityType(device.getId().getEntityType().name()); entityDataBuilder2.setEntityIdMSB(device.getId().getId().getMostSignificantBits()); entityDataBuilder2.setEntityIdLSB(device.getId().getId().getLeastSignificantBits()); entityDataBuilder2.setAttributesUpdatedMsg(JsonConverter.convertToAttributesProto(attributesData)); entityDataBuilder2.setPostAttributeScope(DataConstants.SERVER_SCOPE); - builder2.addEntityData(entityDataBuilder2.build()); - edgeImitator.sendUplinkMsg(builder2.build()); + testAutoGeneratedCodeByProtobuf(entityDataBuilder2); + + uplinkMsgBuilder2.addEntityData(entityDataBuilder2.build()); + testAutoGeneratedCodeByProtobuf(uplinkMsgBuilder2); + + edgeImitator.sendUplinkMsg(uplinkMsgBuilder2.build()); edgeImitator.waitForResponses(); Thread.sleep(1000); @@ -951,14 +1177,18 @@ abstract public class BaseEdgeTest extends AbstractControllerTest { private void sendRuleChainMetadataRequest() throws Exception { RuleChainId edgeRootRuleChainId = edge.getRootRuleChainId(); - UplinkMsg.Builder builder = UplinkMsg.newBuilder(); + UplinkMsg.Builder uplinkMsgBuilder = UplinkMsg.newBuilder(); RuleChainMetadataRequestMsg.Builder ruleChainMetadataRequestMsgBuilder = RuleChainMetadataRequestMsg.newBuilder(); ruleChainMetadataRequestMsgBuilder.setRuleChainIdMSB(edgeRootRuleChainId.getId().getMostSignificantBits()); ruleChainMetadataRequestMsgBuilder.setRuleChainIdLSB(edgeRootRuleChainId.getId().getLeastSignificantBits()); - builder.addRuleChainMetadataRequestMsg(ruleChainMetadataRequestMsgBuilder.build()); + testAutoGeneratedCodeByProtobuf(ruleChainMetadataRequestMsgBuilder); + uplinkMsgBuilder.addRuleChainMetadataRequestMsg(ruleChainMetadataRequestMsgBuilder.build()); + + testAutoGeneratedCodeByProtobuf(uplinkMsgBuilder); + edgeImitator.expectResponsesAmount(1); edgeImitator.expectMessageAmount(1); - edgeImitator.sendUplinkMsg(builder.build()); + edgeImitator.sendUplinkMsg(uplinkMsgBuilder.build()); edgeImitator.waitForResponses(); edgeImitator.waitForMessages(); @@ -967,19 +1197,25 @@ abstract public class BaseEdgeTest extends AbstractControllerTest { RuleChainMetadataUpdateMsg ruleChainMetadataUpdateMsg = (RuleChainMetadataUpdateMsg) latestMessage; Assert.assertEquals(ruleChainMetadataUpdateMsg.getRuleChainIdMSB(), edgeRootRuleChainId.getId().getMostSignificantBits()); Assert.assertEquals(ruleChainMetadataUpdateMsg.getRuleChainIdLSB(), edgeRootRuleChainId.getId().getLeastSignificantBits()); + + testAutoGeneratedCodeByProtobuf(ruleChainMetadataUpdateMsg); } private void sendUserCredentialsRequest() throws Exception { UserId userId = edgeImitator.getUserId(); - UplinkMsg.Builder builder = UplinkMsg.newBuilder(); + UplinkMsg.Builder uplinkMsgBuilder = UplinkMsg.newBuilder(); UserCredentialsRequestMsg.Builder userCredentialsRequestMsgBuilder = UserCredentialsRequestMsg.newBuilder(); userCredentialsRequestMsgBuilder.setUserIdMSB(userId.getId().getMostSignificantBits()); userCredentialsRequestMsgBuilder.setUserIdLSB(userId.getId().getLeastSignificantBits()); - builder.addUserCredentialsRequestMsg(userCredentialsRequestMsgBuilder.build()); + testAutoGeneratedCodeByProtobuf(userCredentialsRequestMsgBuilder); + uplinkMsgBuilder.addUserCredentialsRequestMsg(userCredentialsRequestMsgBuilder.build()); + + testAutoGeneratedCodeByProtobuf(uplinkMsgBuilder); + edgeImitator.expectResponsesAmount(1); edgeImitator.expectMessageAmount(1); - edgeImitator.sendUplinkMsg(builder.build()); + edgeImitator.sendUplinkMsg(uplinkMsgBuilder.build()); edgeImitator.waitForResponses(); edgeImitator.waitForMessages(); @@ -988,26 +1224,27 @@ abstract public class BaseEdgeTest extends AbstractControllerTest { UserCredentialsUpdateMsg userCredentialsUpdateMsg = (UserCredentialsUpdateMsg) latestMessage; Assert.assertEquals(userCredentialsUpdateMsg.getUserIdMSB(), userId.getId().getMostSignificantBits()); Assert.assertEquals(userCredentialsUpdateMsg.getUserIdLSB(), userId.getId().getLeastSignificantBits()); + + testAutoGeneratedCodeByProtobuf(userCredentialsUpdateMsg); } private void sendDeviceCredentialsRequest() throws Exception { - List edgeDevices = doGetTypedWithPageLink("/api/edge/" + edge.getId().getId().toString() + "/devices?", - new TypeReference>() {}, new PageLink(100)).getData(); - Optional foundDevice = edgeDevices.stream().filter(device1 -> device1.getName().equals("Edge Device 1")).findAny(); - Assert.assertTrue(foundDevice.isPresent()); - Device device = foundDevice.get(); + Device device = findDeviceByName("Edge Device 1"); DeviceCredentials deviceCredentials = doGet("/api/device/" + device.getId().getId().toString() + "/credentials", DeviceCredentials.class); - UplinkMsg.Builder builder = UplinkMsg.newBuilder(); + UplinkMsg.Builder uplinkMsgBuilder = UplinkMsg.newBuilder(); DeviceCredentialsRequestMsg.Builder deviceCredentialsRequestMsgBuilder = DeviceCredentialsRequestMsg.newBuilder(); deviceCredentialsRequestMsgBuilder.setDeviceIdMSB(device.getUuidId().getMostSignificantBits()); deviceCredentialsRequestMsgBuilder.setDeviceIdLSB(device.getUuidId().getLeastSignificantBits()); - builder.addDeviceCredentialsRequestMsg(deviceCredentialsRequestMsgBuilder.build()); + testAutoGeneratedCodeByProtobuf(deviceCredentialsRequestMsgBuilder); + uplinkMsgBuilder.addDeviceCredentialsRequestMsg(deviceCredentialsRequestMsgBuilder.build()); + + testAutoGeneratedCodeByProtobuf(uplinkMsgBuilder); edgeImitator.expectResponsesAmount(1); edgeImitator.expectMessageAmount(1); - edgeImitator.sendUplinkMsg(builder.build()); + edgeImitator.sendUplinkMsg(uplinkMsgBuilder.build()); edgeImitator.waitForResponses(); edgeImitator.waitForMessages(); @@ -1020,24 +1257,108 @@ abstract public class BaseEdgeTest extends AbstractControllerTest { Assert.assertEquals(deviceCredentialsUpdateMsg.getCredentialsId(), deviceCredentials.getCredentialsId()); } + private void sendDeviceCredentialsUpdate() throws Exception { + Device device = findDeviceByName("Edge Device 1"); + + UplinkMsg.Builder uplinkMsgBuilder = UplinkMsg.newBuilder(); + DeviceCredentialsUpdateMsg.Builder deviceCredentialsUpdateMsgBuilder = DeviceCredentialsUpdateMsg.newBuilder(); + deviceCredentialsUpdateMsgBuilder.setDeviceIdMSB(device.getUuidId().getMostSignificantBits()); + deviceCredentialsUpdateMsgBuilder.setDeviceIdLSB(device.getUuidId().getLeastSignificantBits()); + deviceCredentialsUpdateMsgBuilder.setCredentialsType(DeviceCredentialsType.ACCESS_TOKEN.name()); + deviceCredentialsUpdateMsgBuilder.setCredentialsId("NEW_TOKEN"); + testAutoGeneratedCodeByProtobuf(deviceCredentialsUpdateMsgBuilder); + uplinkMsgBuilder.addDeviceCredentialsUpdateMsg(deviceCredentialsUpdateMsgBuilder.build()); + + testAutoGeneratedCodeByProtobuf(uplinkMsgBuilder); + + edgeImitator.expectResponsesAmount(1); + edgeImitator.sendUplinkMsg(uplinkMsgBuilder.build()); + edgeImitator.waitForResponses(); + } + + private void sendDeviceRpcResponse() throws Exception { + Device device = findDeviceByName("Edge Device 1"); + + UplinkMsg.Builder uplinkMsgBuilder = UplinkMsg.newBuilder(); + DeviceRpcCallMsg.Builder deviceRpcCallResponseBuilder = DeviceRpcCallMsg.newBuilder(); + deviceRpcCallResponseBuilder.setDeviceIdMSB(device.getUuidId().getMostSignificantBits()); + deviceRpcCallResponseBuilder.setDeviceIdLSB(device.getUuidId().getLeastSignificantBits()); + deviceRpcCallResponseBuilder.setOneway(true); + deviceRpcCallResponseBuilder.setRequestId(0); + deviceRpcCallResponseBuilder.setExpirationTime(System.currentTimeMillis() + TimeUnit.SECONDS.toMillis(10)); + RpcResponseMsg.Builder responseBuilder = + RpcResponseMsg.newBuilder().setResponse("{}"); + testAutoGeneratedCodeByProtobuf(responseBuilder); + + deviceRpcCallResponseBuilder.setResponseMsg(responseBuilder.build()); + testAutoGeneratedCodeByProtobuf(deviceRpcCallResponseBuilder); + + uplinkMsgBuilder.addDeviceRpcCallMsg(deviceRpcCallResponseBuilder.build()); + testAutoGeneratedCodeByProtobuf(uplinkMsgBuilder); + + edgeImitator.expectResponsesAmount(1); + edgeImitator.sendUplinkMsg(uplinkMsgBuilder.build()); + edgeImitator.waitForResponses(); + } + + private void sendAttributesRequest() throws Exception { + Device device = findDeviceByName("Edge Device 1"); + + String attributesDataStr = "{\"key1\":\"value1\"}"; + JsonNode attributesData = mapper.readTree(attributesDataStr); + + doPost("/api/plugins/telemetry/DEVICE/" + device.getId().getId().toString() + "/attributes/" + DataConstants.SERVER_SCOPE, + attributesData); + + UplinkMsg.Builder uplinkMsgBuilder = UplinkMsg.newBuilder(); + AttributesRequestMsg.Builder attributesRequestMsgBuilder = AttributesRequestMsg.newBuilder(); + attributesRequestMsgBuilder.setEntityIdMSB(device.getUuidId().getMostSignificantBits()); + attributesRequestMsgBuilder.setEntityIdLSB(device.getUuidId().getLeastSignificantBits()); + attributesRequestMsgBuilder.setEntityType(EntityType.DEVICE.name()); + testAutoGeneratedCodeByProtobuf(attributesRequestMsgBuilder); + uplinkMsgBuilder.addAttributesRequestMsg(attributesRequestMsgBuilder.build()); + testAutoGeneratedCodeByProtobuf(uplinkMsgBuilder); + + edgeImitator.expectResponsesAmount(1); + edgeImitator.expectMessageAmount(1); + edgeImitator.sendUplinkMsg(uplinkMsgBuilder.build()); + edgeImitator.waitForResponses(); + edgeImitator.waitForMessages(); + + AbstractMessage latestMessage = edgeImitator.getLatestMessage(); + Assert.assertTrue(latestMessage instanceof EntityDataProto); + EntityDataProto latestEntityDataMsg = (EntityDataProto) latestMessage; + Assert.assertEquals(device.getUuidId().getMostSignificantBits(), latestEntityDataMsg.getEntityIdMSB()); + Assert.assertEquals(device.getUuidId().getLeastSignificantBits(), latestEntityDataMsg.getEntityIdLSB()); + Assert.assertEquals(device.getId().getEntityType().name(), latestEntityDataMsg.getEntityType()); + Assert.assertEquals("SERVER_SCOPE", latestEntityDataMsg.getPostAttributeScope()); + Assert.assertTrue(latestEntityDataMsg.hasAttributesUpdatedMsg()); + + TransportProtos.PostAttributeMsg attributesUpdatedMsg = latestEntityDataMsg.getAttributesUpdatedMsg(); + Assert.assertEquals(1, attributesUpdatedMsg.getKvCount()); + TransportProtos.KeyValueProto keyValueProto = attributesUpdatedMsg.getKv(0); + Assert.assertEquals("key1", keyValueProto.getKey()); + Assert.assertEquals("value1", keyValueProto.getStringV()); + } + private void sendDeleteDeviceOnEdge() throws Exception { - List edgeDevices = doGetTypedWithPageLink("/api/edge/" + edge.getId().getId().toString() + "/devices?", - new TypeReference>() {}, new PageLink(100)).getData(); - Optional foundDevice = edgeDevices.stream().filter(device1 -> device1.getName().equals("Edge Device 2")).findAny(); - Assert.assertTrue(foundDevice.isPresent()); - Device device = foundDevice.get(); - UplinkMsg.Builder builder = UplinkMsg.newBuilder(); + Device device = findDeviceByName("Edge Device 2"); + UplinkMsg.Builder upLinkMsgBuilder = UplinkMsg.newBuilder(); DeviceUpdateMsg.Builder deviceDeleteMsgBuilder = DeviceUpdateMsg.newBuilder(); deviceDeleteMsgBuilder.setMsgType(UpdateMsgType.ENTITY_DELETED_RPC_MESSAGE); deviceDeleteMsgBuilder.setIdMSB(device.getId().getId().getMostSignificantBits()); deviceDeleteMsgBuilder.setIdLSB(device.getId().getId().getLeastSignificantBits()); - builder.addDeviceUpdateMsg(deviceDeleteMsgBuilder.build()); + testAutoGeneratedCodeByProtobuf(deviceDeleteMsgBuilder); + + upLinkMsgBuilder.addDeviceUpdateMsg(deviceDeleteMsgBuilder.build()); + testAutoGeneratedCodeByProtobuf(upLinkMsgBuilder); + edgeImitator.expectResponsesAmount(1); - edgeImitator.sendUplinkMsg(builder.build()); + edgeImitator.sendUplinkMsg(upLinkMsgBuilder.build()); edgeImitator.waitForResponses(); device = doGet("/api/device/" + device.getId().getId().toString(), Device.class); Assert.assertNotNull(device); - edgeDevices = doGetTypedWithPageLink("/api/edge/" + edge.getId().getId().toString() + "/devices?", + List edgeDevices = doGetTypedWithPageLink("/api/edge/" + edge.getId().getId().toString() + "/devices?", new TypeReference>() { }, new PageLink(100)).getData(); Assert.assertFalse(edgeDevices.contains(device)); @@ -1046,49 +1367,38 @@ abstract public class BaseEdgeTest extends AbstractControllerTest { private void installation() throws Exception { edge = doPost("/api/edge", constructEdge("Test Edge", "test"), Edge.class); - Device device = new Device(); - device.setName("Edge Device 1"); - device.setType("test"); - Device savedDevice = doPost("/api/device", device, Device.class); + Device savedDevice = saveDevice("Edge Device 1"); doPost("/api/edge/" + edge.getId().getId().toString() + "/device/" + savedDevice.getId().getId().toString(), Device.class); - Asset asset = new Asset(); - asset.setName("Edge Asset 1"); - asset.setType("test"); - Asset savedAsset = doPost("/api/asset", asset, Asset.class); + Asset savedAsset = saveAsset("Edge Asset 1"); doPost("/api/edge/" + edge.getId().getId().toString() + "/asset/" + savedAsset.getId().getId().toString(), Asset.class); } - private void uninstallation() throws Exception { - - PageData pageDataDevices = doGetTypedWithPageLink("/api/edge/" + edge.getId().getId().toString() + "/devices?", - new TypeReference>() {}, new PageLink(100)); - for (Device device: pageDataDevices.getData()) { - doDelete("/api/device/" + device.getId().getId().toString()) - .andExpect(status().isOk()); - } - - PageData pageDataAssets = doGetTypedWithPageLink("/api/edge/" + edge.getId().getId().toString() + "/assets?", - new TypeReference>() {}, new PageLink(100)); - for (Asset asset: pageDataAssets.getData()) { - doDelete("/api/asset/" + asset.getId().getId().toString()) - .andExpect(status().isOk()); - } - - doDelete("/api/edge/" + edge.getId().getId().toString()) - .andExpect(status().isOk()); - } - - private EdgeEvent constructEdgeEvent(TenantId tenantId, EdgeId edgeId, ActionType edgeEventAction, UUID entityId, EdgeEventType edgeEventType, JsonNode entityBody) { + private EdgeEvent constructEdgeEvent(TenantId tenantId, EdgeId edgeId, EdgeEventActionType edgeEventAction, UUID entityId, EdgeEventType edgeEventType, JsonNode entityBody) { EdgeEvent edgeEvent = new EdgeEvent(); edgeEvent.setEdgeId(edgeId); edgeEvent.setTenantId(tenantId); - edgeEvent.setAction(edgeEventAction.name()); + edgeEvent.setAction(edgeEventAction); edgeEvent.setEntityId(entityId); edgeEvent.setType(edgeEventType); edgeEvent.setBody(entityBody); return edgeEvent; } + + private void testAutoGeneratedCodeByProtobuf(MessageLite.Builder builder) throws InvalidProtocolBufferException { + MessageLite source = builder.build(); + + testAutoGeneratedCodeByProtobuf(source); + + MessageLite target = source.getParserForType().parseFrom(source.toByteArray()); + builder.clear().mergeFrom(target); + } + + private void testAutoGeneratedCodeByProtobuf(MessageLite source) throws InvalidProtocolBufferException { + MessageLite target = source.getParserForType().parseFrom(source.toByteArray()); + Assert.assertEquals(source, target); + Assert.assertEquals(source.hashCode(), target.hashCode()); + } } diff --git a/application/src/test/java/org/thingsboard/server/edge/imitator/EdgeImitator.java b/application/src/test/java/org/thingsboard/server/edge/imitator/EdgeImitator.java index 3eca5438dd..c2122a9c83 100644 --- a/application/src/test/java/org/thingsboard/server/edge/imitator/EdgeImitator.java +++ b/application/src/test/java/org/thingsboard/server/edge/imitator/EdgeImitator.java @@ -30,7 +30,9 @@ import org.thingsboard.server.gen.edge.AlarmUpdateMsg; import org.thingsboard.server.gen.edge.AssetUpdateMsg; import org.thingsboard.server.gen.edge.CustomerUpdateMsg; import org.thingsboard.server.gen.edge.DashboardUpdateMsg; +import org.thingsboard.server.gen.edge.DeviceCredentialsRequestMsg; import org.thingsboard.server.gen.edge.DeviceCredentialsUpdateMsg; +import org.thingsboard.server.gen.edge.DeviceRpcCallMsg; import org.thingsboard.server.gen.edge.DeviceUpdateMsg; import org.thingsboard.server.gen.edge.DownlinkMsg; import org.thingsboard.server.gen.edge.DownlinkResponseMsg; @@ -224,6 +226,16 @@ public class EdgeImitator { result.add(saveDownlinkMsg(userCredentialsUpdateMsg)); } } + if (downlinkMsg.getDeviceRpcCallMsgList() != null && !downlinkMsg.getDeviceRpcCallMsgList().isEmpty()) { + for (DeviceRpcCallMsg deviceRpcCallMsg: downlinkMsg.getDeviceRpcCallMsgList()) { + result.add(saveDownlinkMsg(deviceRpcCallMsg)); + } + } + if (downlinkMsg.getDeviceCredentialsRequestMsgList() != null && !downlinkMsg.getDeviceCredentialsRequestMsgList().isEmpty()) { + for (DeviceCredentialsRequestMsg deviceCredentialsRequestMsg: downlinkMsg.getDeviceCredentialsRequestMsgList()) { + result.add(saveDownlinkMsg(deviceCredentialsRequestMsg)); + } + } return Futures.allAsList(result); } diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/audit/ActionType.java b/common/data/src/main/java/org/thingsboard/server/common/data/audit/ActionType.java index 0fe921968f..cd78d39534 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/audit/ActionType.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/audit/ActionType.java @@ -24,7 +24,6 @@ public enum ActionType { UPDATED(false), // log entity ATTRIBUTES_UPDATED(false), // log attributes/values ATTRIBUTES_DELETED(false), // log attributes - TIMESERIES_UPDATED(false), // log timeseries TIMESERIES_DELETED(false), // log timeseries RPC_CALL(false), // log method and params CREDENTIALS_UPDATED(false), // log new credentials @@ -47,9 +46,7 @@ public enum ActionType { PROVISION_SUCCESS(false), PROVISION_FAILURE(false), ASSIGNED_TO_EDGE(false), // log edge name - UNASSIGNED_FROM_EDGE(false), // log edge name - CREDENTIALS_REQUEST(false), // request credentials from edge - ENTITY_EXISTS_REQUEST(false); // request to recreate entity on edge + UNASSIGNED_FROM_EDGE(false); private final boolean isRead; diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/edge/EdgeEvent.java b/common/data/src/main/java/org/thingsboard/server/common/data/edge/EdgeEvent.java index c76a03fa43..dae4738faf 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/edge/EdgeEvent.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/edge/EdgeEvent.java @@ -29,7 +29,7 @@ public class EdgeEvent extends BaseData { private TenantId tenantId; private EdgeId edgeId; - private String action; + private EdgeEventActionType action; private UUID entityId; private String uid; private EdgeEventType type; diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/edge/EdgeEventActionType.java b/common/data/src/main/java/org/thingsboard/server/common/data/edge/EdgeEventActionType.java new file mode 100644 index 0000000000..b8b386ac1a --- /dev/null +++ b/common/data/src/main/java/org/thingsboard/server/common/data/edge/EdgeEventActionType.java @@ -0,0 +1,38 @@ +/** + * Copyright © 2016-2020 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.common.data.edge; + +public enum EdgeEventActionType { + ADDED, + DELETED, + UPDATED, + POST_ATTRIBUTES, + ATTRIBUTES_UPDATED, + ATTRIBUTES_DELETED, + TIMESERIES_UPDATED, + CREDENTIALS_UPDATED, + ASSIGNED_TO_CUSTOMER, + UNASSIGNED_FROM_CUSTOMER, + RELATION_ADD_OR_UPDATE, + RELATION_DELETED, + RPC_CALL, + ALARM_ACK, + ALARM_CLEAR, + ASSIGNED_TO_EDGE, + UNASSIGNED_FROM_EDGE, + CREDENTIALS_REQUEST, + ENTITY_EXISTS_REQUEST +} \ No newline at end of file diff --git a/common/edge-api/src/main/proto/edge.proto b/common/edge-api/src/main/proto/edge.proto index fd26e1fcd4..88d93a256a 100644 --- a/common/edge-api/src/main/proto/edge.proto +++ b/common/edge-api/src/main/proto/edge.proto @@ -105,7 +105,6 @@ message EntityDataProto { transport.PostAttributeMsg attributesUpdatedMsg = 6; string postAttributeScope = 7; AttributeDeleteMsg attributeDeleteMsg = 8; - // transport.ToDeviceRpcRequestMsg ??? } message AttributeDeleteMsg { @@ -337,11 +336,11 @@ message DeviceCredentialsRequestMsg { message DeviceRpcCallMsg { int64 deviceIdMSB = 1; int64 deviceIdLSB = 2; - int64 requestIdMSB = 3; - int64 requestIdLSB = 4; - int64 expirationTime = 5; - bool oneway = 6; - string originServiceId = 7; + int64 requestUuidMSB = 3; + int64 requestUuidLSB = 4; + int32 requestId = 5; + int64 expirationTime = 6; + bool oneway = 7; RpcRequestMsg requestMsg = 8; RpcResponseMsg responseMsg = 9; } diff --git a/common/message/src/main/java/org/thingsboard/server/common/msg/MsgType.java b/common/message/src/main/java/org/thingsboard/server/common/msg/MsgType.java index d7f0df9838..83aa6c5108 100644 --- a/common/message/src/main/java/org/thingsboard/server/common/msg/MsgType.java +++ b/common/message/src/main/java/org/thingsboard/server/common/msg/MsgType.java @@ -82,8 +82,12 @@ public enum MsgType { DEVICE_NAME_OR_TYPE_UPDATE_TO_DEVICE_ACTOR_MSG, + DEVICE_EDGE_UPDATE_TO_DEVICE_ACTOR_MSG, + DEVICE_RPC_REQUEST_TO_DEVICE_ACTOR_MSG, + DEVICE_RPC_RESPONSE_TO_DEVICE_ACTOR_MSG, + SERVER_RPC_RESPONSE_TO_DEVICE_ACTOR_MSG, DEVICE_ACTOR_SERVER_SIDE_RPC_TIMEOUT_MSG, diff --git a/dao/src/main/java/org/thingsboard/server/dao/edge/BaseEdgeEventService.java b/dao/src/main/java/org/thingsboard/server/dao/edge/BaseEdgeEventService.java index 8c1382c500..ce2bffb350 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/edge/BaseEdgeEventService.java +++ b/dao/src/main/java/org/thingsboard/server/dao/edge/BaseEdgeEventService.java @@ -53,7 +53,7 @@ public class BaseEdgeEventService implements EdgeEventService { if (edgeEvent.getEdgeId() == null) { throw new DataValidationException("Edge id should be specified!"); } - if (StringUtils.isEmpty(edgeEvent.getAction())) { + if (edgeEvent.getAction() == null) { throw new DataValidationException("Edge Event action should be specified!"); } } diff --git a/dao/src/main/java/org/thingsboard/server/dao/edge/EdgeServiceImpl.java b/dao/src/main/java/org/thingsboard/server/dao/edge/EdgeServiceImpl.java index 6b81e86a89..f434c80442 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/edge/EdgeServiceImpl.java +++ b/dao/src/main/java/org/thingsboard/server/dao/edge/EdgeServiceImpl.java @@ -81,6 +81,7 @@ import java.util.Map; import java.util.Optional; import java.util.stream.Collectors; +import static org.apache.commons.lang3.StringUtils.isNotEmpty; import static org.thingsboard.server.common.data.CacheConstants.EDGE_CACHE; import static org.thingsboard.server.dao.DaoUtil.toUUIDs; import static org.thingsboard.server.dao.model.ModelConstants.NULL_UUID; @@ -172,6 +173,7 @@ public class EdgeServiceImpl extends AbstractEntityService implements EdgeServic @Override public Edge assignEdgeToCustomer(TenantId tenantId, EdgeId edgeId, CustomerId customerId) { + log.trace("[{}] Executing assignEdgeToCustomer [{}][{}]", tenantId, edgeId, customerId); Edge edge = findEdgeById(tenantId, edgeId); edge.setCustomerId(customerId); return saveEdge(edge); @@ -179,6 +181,7 @@ public class EdgeServiceImpl extends AbstractEntityService implements EdgeServic @Override public Edge unassignEdgeFromCustomer(TenantId tenantId, EdgeId edgeId) { + log.trace("[{}] Executing unassignEdgeFromCustomer [{}]", tenantId, edgeId); Edge edge = findEdgeById(tenantId, edgeId); edge.setCustomerId(null); return saveEdge(edge); @@ -309,6 +312,7 @@ public class EdgeServiceImpl extends AbstractEntityService implements EdgeServic @Override public ListenableFuture> findEdgesByQuery(TenantId tenantId, EdgeSearchQuery query) { + log.trace("[{}] Executing findEdgesByQuery [{}]", tenantId, query); ListenableFuture> relations = relationService.findByQuery(tenantId, query.toEntitySearchQuery()); ListenableFuture> edges = Futures.transformAsync(relations, r -> { EntitySearchDirection direction = query.toEntitySearchQuery().getParameters().getDirection(); @@ -457,6 +461,7 @@ public class EdgeServiceImpl extends AbstractEntityService implements EdgeServic @Override public ListenableFuture> findRelatedEdgeIdsByEntityId(TenantId tenantId, EntityId entityId) { + log.trace("[{}] Executing findRelatedEdgeIdsByEntityId [{}]", tenantId, entityId); if (EntityType.TENANT.equals(entityId.getEntityType())) { PageData edgesByTenantId = findEdgesByTenantId(tenantId, new PageLink(Integer.MAX_VALUE)); return Futures.immediateFuture(edgesByTenantId.getData().stream().map(IdBased::getId).collect(Collectors.toList())); @@ -521,9 +526,9 @@ public class EdgeServiceImpl extends AbstractEntityService implements EdgeServic } private void initRestTemplate() { - boolean jdkHttpClientEnabled = org.apache.commons.lang3.StringUtils.isNotEmpty(System.getProperty("tb.proxy.jdk")) && System.getProperty("tb.proxy.jdk").equalsIgnoreCase("true"); - boolean systemProxyEnabled = org.apache.commons.lang3.StringUtils.isNotEmpty(System.getProperty("tb.proxy.system")) && System.getProperty("tb.proxy.system").equalsIgnoreCase("true"); - boolean proxyEnabled = org.apache.commons.lang3.StringUtils.isNotEmpty(System.getProperty("tb.proxy.host")) && org.apache.commons.lang3.StringUtils.isNotEmpty(System.getProperty("tb.proxy.port")); + boolean jdkHttpClientEnabled = isNotEmpty(System.getProperty("tb.proxy.jdk")) && System.getProperty("tb.proxy.jdk").equalsIgnoreCase("true"); + boolean systemProxyEnabled = isNotEmpty(System.getProperty("tb.proxy.system")) && System.getProperty("tb.proxy.system").equalsIgnoreCase("true"); + boolean proxyEnabled = isNotEmpty(System.getProperty("tb.proxy.host")) && isNotEmpty(System.getProperty("tb.proxy.port")); if (jdkHttpClientEnabled) { log.warn("Going to use plain JDK Http Client!"); SimpleClientHttpRequestFactory factory = new SimpleClientHttpRequestFactory(); diff --git a/dao/src/main/java/org/thingsboard/server/dao/model/sql/EdgeEventEntity.java b/dao/src/main/java/org/thingsboard/server/dao/model/sql/EdgeEventEntity.java index dc7c5fc0de..2168eb7658 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/model/sql/EdgeEventEntity.java +++ b/dao/src/main/java/org/thingsboard/server/dao/model/sql/EdgeEventEntity.java @@ -23,6 +23,7 @@ import lombok.NoArgsConstructor; import org.hibernate.annotations.Type; import org.hibernate.annotations.TypeDef; import org.thingsboard.server.common.data.edge.EdgeEvent; +import org.thingsboard.server.common.data.edge.EdgeEventActionType; import org.thingsboard.server.common.data.edge.EdgeEventType; import org.thingsboard.server.common.data.id.EdgeEventId; import org.thingsboard.server.common.data.id.EdgeId; @@ -71,8 +72,9 @@ public class EdgeEventEntity extends BaseSqlEntity implements BaseEnt @Column(name = EDGE_EVENT_TYPE_PROPERTY) private EdgeEventType edgeEventType; + @Enumerated(EnumType.STRING) @Column(name = EDGE_EVENT_ACTION_PROPERTY) - private String edgeEventAction; + private EdgeEventActionType edgeEventAction; @Type(type = "json") @Column(name = EDGE_EVENT_BODY_PROPERTY) 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 8737d1fba2..864052354d 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 @@ -346,7 +346,6 @@ public class BaseRuleChainService extends AbstractEntityService implements RuleC } } - @Override public List getRuleChainNodes(TenantId tenantId, RuleChainId ruleChainId) { Validator.validateId(ruleChainId, "Incorrect rule chain id for search request."); diff --git a/dao/src/main/java/org/thingsboard/server/dao/sql/edge/JpaBaseEdgeEventDao.java b/dao/src/main/java/org/thingsboard/server/dao/sql/edge/JpaBaseEdgeEventDao.java index 69a8ee1991..1894c945a2 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/sql/edge/JpaBaseEdgeEventDao.java +++ b/dao/src/main/java/org/thingsboard/server/dao/sql/edge/JpaBaseEdgeEventDao.java @@ -23,6 +23,7 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.repository.CrudRepository; import org.springframework.stereotype.Component; import org.thingsboard.server.common.data.edge.EdgeEvent; +import org.thingsboard.server.common.data.edge.EdgeEventActionType; import org.thingsboard.server.common.data.id.EdgeEventId; import org.thingsboard.server.common.data.id.EdgeId; import org.thingsboard.server.common.data.id.EventId; diff --git a/dao/src/test/java/org/thingsboard/server/dao/service/BaseEdgeEventServiceTest.java b/dao/src/test/java/org/thingsboard/server/dao/service/BaseEdgeEventServiceTest.java index 21477c24de..ea33172921 100644 --- a/dao/src/test/java/org/thingsboard/server/dao/service/BaseEdgeEventServiceTest.java +++ b/dao/src/test/java/org/thingsboard/server/dao/service/BaseEdgeEventServiceTest.java @@ -18,9 +18,8 @@ package org.thingsboard.server.dao.service; import com.datastax.oss.driver.api.core.uuid.Uuids; import org.junit.Assert; import org.junit.Test; -import org.thingsboard.server.common.data.DataConstants; -import org.thingsboard.server.common.data.audit.ActionType; import org.thingsboard.server.common.data.edge.EdgeEvent; +import org.thingsboard.server.common.data.edge.EdgeEventActionType; import org.thingsboard.server.common.data.edge.EdgeEventType; import org.thingsboard.server.common.data.id.DeviceId; import org.thingsboard.server.common.data.id.EdgeEventId; @@ -42,7 +41,7 @@ public abstract class BaseEdgeEventServiceTest extends AbstractServiceTest { public void saveEdgeEvent() throws Exception { EdgeId edgeId = new EdgeId(Uuids.timeBased()); DeviceId deviceId = new DeviceId(Uuids.timeBased()); - EdgeEvent edgeEvent = generateEdgeEvent(null, edgeId, deviceId, DataConstants.ENTITY_CREATED); + EdgeEvent edgeEvent = generateEdgeEvent(null, edgeId, deviceId, EdgeEventActionType.ADDED); EdgeEvent saved = edgeEventService.saveAsync(edgeEvent).get(); Assert.assertEquals(saved.getTenantId(), edgeEvent.getTenantId()); Assert.assertEquals(saved.getEdgeId(), edgeEvent.getEdgeId()); @@ -52,7 +51,7 @@ public abstract class BaseEdgeEventServiceTest extends AbstractServiceTest { Assert.assertEquals(saved.getBody(), edgeEvent.getBody()); } - protected EdgeEvent generateEdgeEvent(TenantId tenantId, EdgeId edgeId, EntityId entityId, String edgeEventAction) throws IOException { + protected EdgeEvent generateEdgeEvent(TenantId tenantId, EdgeId edgeId, EntityId entityId, EdgeEventActionType edgeEventAction) throws IOException { if (tenantId == null) { tenantId = new TenantId(Uuids.timeBased()); } @@ -109,7 +108,7 @@ public abstract class BaseEdgeEventServiceTest extends AbstractServiceTest { TenantId tenantId = new TenantId(Uuids.timeBased()); TimePageLink pageLink = new TimePageLink(1); - EdgeEvent edgeEventWithTsUpdate = generateEdgeEvent(tenantId, edgeId, deviceId, ActionType.TIMESERIES_UPDATED.name()); + EdgeEvent edgeEventWithTsUpdate = generateEdgeEvent(tenantId, edgeId, deviceId, EdgeEventActionType.TIMESERIES_UPDATED); edgeEventService.saveAsync(edgeEventWithTsUpdate).get(); PageData allEdgeEvents = edgeEventService.findEdgeEvents(tenantId, edgeId, pageLink, true); @@ -123,7 +122,7 @@ public abstract class BaseEdgeEventServiceTest extends AbstractServiceTest { } private EdgeEvent saveEdgeEventWithProvidedTime(long time, EdgeId edgeId, EntityId entityId, TenantId tenantId) throws Exception { - EdgeEvent edgeEvent = generateEdgeEvent(tenantId, edgeId, entityId, DataConstants.ENTITY_CREATED); + EdgeEvent edgeEvent = generateEdgeEvent(tenantId, edgeId, entityId, EdgeEventActionType.ADDED); edgeEvent.setId(new EdgeEventId(Uuids.startOf(time))); return edgeEventService.saveAsync(edgeEvent).get(); } diff --git a/dao/src/test/resources/sql/hsql/drop-all-tables.sql b/dao/src/test/resources/sql/hsql/drop-all-tables.sql index c09b1fc78c..90a9ba3657 100644 --- a/dao/src/test/resources/sql/hsql/drop-all-tables.sql +++ b/dao/src/test/resources/sql/hsql/drop-all-tables.sql @@ -30,4 +30,4 @@ DROP TABLE IF EXISTS oauth2_client_registration_template; DROP TABLE IF EXISTS api_usage_state; DROP TABLE IF EXISTS edge; DROP TABLE IF EXISTS edge_event; -DROP FUNCTION IF EXISTS to_uuid; \ No newline at end of file +DROP FUNCTION IF EXISTS to_uuid; diff --git a/dao/src/test/resources/sql/psql/drop-all-tables.sql b/dao/src/test/resources/sql/psql/drop-all-tables.sql index 3bbf088415..1d1298ef56 100644 --- a/dao/src/test/resources/sql/psql/drop-all-tables.sql +++ b/dao/src/test/resources/sql/psql/drop-all-tables.sql @@ -30,4 +30,4 @@ DROP TABLE IF EXISTS tb_schema_settings; DROP TABLE IF EXISTS oauth2_client_registration; DROP TABLE IF EXISTS oauth2_client_registration_info; DROP TABLE IF EXISTS oauth2_client_registration_template; -DROP TABLE IF EXISTS api_usage_state; \ No newline at end of file +DROP TABLE IF EXISTS api_usage_state; diff --git a/dao/src/test/resources/sql/timescale/drop-all-tables.sql b/dao/src/test/resources/sql/timescale/drop-all-tables.sql index 2454dfc9f2..17cf4b6575 100644 --- a/dao/src/test/resources/sql/timescale/drop-all-tables.sql +++ b/dao/src/test/resources/sql/timescale/drop-all-tables.sql @@ -30,4 +30,4 @@ DROP TABLE IF EXISTS tb_schema_settings; DROP TABLE IF EXISTS oauth2_client_registration; DROP TABLE IF EXISTS oauth2_client_registration_info; DROP TABLE IF EXISTS oauth2_client_registration_template; -DROP TABLE IF EXISTS api_usage_state; \ No newline at end of file +DROP TABLE IF EXISTS api_usage_state; diff --git a/rule-engine/rule-engine-api/src/main/java/org/thingsboard/rule/engine/api/msg/DeviceEdgeUpdateMsg.java b/rule-engine/rule-engine-api/src/main/java/org/thingsboard/rule/engine/api/msg/DeviceEdgeUpdateMsg.java new file mode 100644 index 0000000000..7ed10548fb --- /dev/null +++ b/rule-engine/rule-engine-api/src/main/java/org/thingsboard/rule/engine/api/msg/DeviceEdgeUpdateMsg.java @@ -0,0 +1,37 @@ +/** + * Copyright © 2016-2020 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.rule.engine.api.msg; + +import lombok.AllArgsConstructor; +import lombok.Data; +import org.thingsboard.server.common.data.id.DeviceId; +import org.thingsboard.server.common.data.id.EdgeId; +import org.thingsboard.server.common.data.id.TenantId; +import org.thingsboard.server.common.msg.MsgType; + +@Data +@AllArgsConstructor +public class DeviceEdgeUpdateMsg implements ToDeviceActorNotificationMsg { + + private final TenantId tenantId; + private final DeviceId deviceId; + private final EdgeId edgeId; + + @Override + public MsgType getMsgType() { + return MsgType.DEVICE_EDGE_UPDATE_TO_DEVICE_ACTOR_MSG; + } +} diff --git a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/edge/TbMsgPushToEdgeNode.java b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/edge/TbMsgPushToEdgeNode.java index b510af10b0..b706a81399 100644 --- a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/edge/TbMsgPushToEdgeNode.java +++ b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/edge/TbMsgPushToEdgeNode.java @@ -22,6 +22,7 @@ import com.google.common.util.concurrent.FutureCallback; import com.google.common.util.concurrent.Futures; import com.google.common.util.concurrent.ListenableFuture; import lombok.extern.slf4j.Slf4j; +import org.springframework.util.StringUtils; import org.thingsboard.rule.engine.api.EmptyNodeConfiguration; import org.thingsboard.rule.engine.api.RuleNode; import org.thingsboard.rule.engine.api.TbContext; @@ -32,8 +33,8 @@ import org.thingsboard.rule.engine.api.util.TbNodeUtils; import org.thingsboard.server.common.data.DataConstants; import org.thingsboard.server.common.data.EdgeUtils; import org.thingsboard.server.common.data.EntityType; -import org.thingsboard.server.common.data.audit.ActionType; import org.thingsboard.server.common.data.edge.EdgeEvent; +import org.thingsboard.server.common.data.edge.EdgeEventActionType; import org.thingsboard.server.common.data.edge.EdgeEventType; import org.thingsboard.server.common.data.id.EdgeId; import org.thingsboard.server.common.data.id.TenantId; @@ -68,6 +69,8 @@ public class TbMsgPushToEdgeNode implements TbNode { private static final ObjectMapper json = new ObjectMapper(); + private static final String SCOPE = "scope"; + @Override public void init(TbContext ctx, TbNodeConfiguration configuration) throws TbNodeException { this.config = TbNodeUtils.convert(configuration, EmptyNodeConfiguration.class); @@ -140,28 +143,26 @@ public class TbMsgPushToEdgeNode implements TbNode { private EdgeEvent buildEdgeEvent(TbMsg msg, TbContext ctx) throws JsonProcessingException { String msgType = msg.getType(); if (DataConstants.ALARM.equals(msgType)) { - return buildEdgeEvent(ctx.getTenantId(), ActionType.ADDED, getUUIDFromMsgData(msg), EdgeEventType.ALARM, null); + return buildEdgeEvent(ctx.getTenantId(), EdgeEventActionType.ADDED, getUUIDFromMsgData(msg), EdgeEventType.ALARM, null); } else { EdgeEventType edgeEventTypeByEntityType = EdgeUtils.getEdgeEventTypeByEntityType(msg.getOriginator().getEntityType()); if (edgeEventTypeByEntityType == null) { return null; } - ActionType actionType = getActionTypeByMsgType(msgType); + EdgeEventActionType actionType = getEdgeEventActionTypeByMsgType(msgType); Map entityBody = new HashMap<>(); Map metadata = msg.getMetaData().getData(); JsonNode dataJson = json.readTree(msg.getData()); switch (actionType) { case ATTRIBUTES_UPDATED: + case POST_ATTRIBUTES: entityBody.put("kv", dataJson); - entityBody.put("scope", metadata.get("scope")); - if (SessionMsgType.POST_ATTRIBUTES_REQUEST.name().equals(msgType)) { - entityBody.put("isPostAttributes", true); - } + entityBody.put(SCOPE, getScope(metadata)); break; case ATTRIBUTES_DELETED: List keys = json.treeToValue(dataJson.get("attributes"), List.class); entityBody.put("keys", keys); - entityBody.put("scope", metadata.get("scope")); + entityBody.put(SCOPE, getScope(metadata)); break; case TIMESERIES_UPDATED: entityBody.put("data", dataJson); @@ -172,10 +173,19 @@ public class TbMsgPushToEdgeNode implements TbNode { } } - private EdgeEvent buildEdgeEvent(TenantId tenantId, ActionType edgeEventAction, UUID entityId, EdgeEventType edgeEventType, JsonNode entityBody) { + private String getScope(Map metadata) { + String scope = metadata.get(SCOPE); + if (StringUtils.isEmpty(scope)) { + // TODO: voba - move this to configuration of the node UI or some other place + scope = DataConstants.SERVER_SCOPE; + } + return scope; + } + + private EdgeEvent buildEdgeEvent(TenantId tenantId, EdgeEventActionType edgeEventAction, UUID entityId, EdgeEventType edgeEventType, JsonNode entityBody) { EdgeEvent edgeEvent = new EdgeEvent(); edgeEvent.setTenantId(tenantId); - edgeEvent.setAction(edgeEventAction.name()); + edgeEvent.setAction(edgeEventAction); edgeEvent.setEntityId(entityId); edgeEvent.setType(edgeEventType); edgeEvent.setBody(entityBody); @@ -188,15 +198,16 @@ public class TbMsgPushToEdgeNode implements TbNode { return UUID.fromString(id); } - private ActionType getActionTypeByMsgType(String msgType) { - ActionType actionType; + private EdgeEventActionType getEdgeEventActionTypeByMsgType(String msgType) { + EdgeEventActionType actionType; if (SessionMsgType.POST_TELEMETRY_REQUEST.name().equals(msgType)) { - actionType = ActionType.TIMESERIES_UPDATED; - } else if (SessionMsgType.POST_ATTRIBUTES_REQUEST.name().equals(msgType) - || DataConstants.ATTRIBUTES_UPDATED.equals(msgType)) { - actionType = ActionType.ATTRIBUTES_UPDATED; + actionType = EdgeEventActionType.TIMESERIES_UPDATED; + } else if (DataConstants.ATTRIBUTES_UPDATED.equals(msgType)) { + actionType = EdgeEventActionType.ATTRIBUTES_UPDATED; + } else if (SessionMsgType.POST_ATTRIBUTES_REQUEST.name().equals(msgType)) { + actionType = EdgeEventActionType.POST_ATTRIBUTES; } else { - actionType = ActionType.ATTRIBUTES_DELETED; + actionType = EdgeEventActionType.ATTRIBUTES_DELETED; } return actionType; } diff --git a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/rpc/TbSendRPCRequestNode.java b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/rpc/TbSendRPCRequestNode.java index e91d509b4f..777a79e284 100644 --- a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/rpc/TbSendRPCRequestNode.java +++ b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/rpc/TbSendRPCRequestNode.java @@ -36,18 +36,10 @@ import org.thingsboard.rule.engine.api.TbRelationTypes; import org.thingsboard.rule.engine.api.util.TbNodeUtils; import org.thingsboard.server.common.data.DataConstants; import org.thingsboard.server.common.data.EntityType; -import org.thingsboard.server.common.data.audit.ActionType; -import org.thingsboard.server.common.data.edge.EdgeEvent; -import org.thingsboard.server.common.data.edge.EdgeEventType; import org.thingsboard.server.common.data.id.DeviceId; -import org.thingsboard.server.common.data.id.EdgeId; import org.thingsboard.server.common.data.plugin.ComponentType; -import org.thingsboard.server.common.data.relation.EntityRelation; -import org.thingsboard.server.common.data.relation.RelationTypeGroup; import org.thingsboard.server.common.msg.TbMsg; -import javax.annotation.Nullable; -import java.util.List; import java.util.Random; import java.util.UUID; import java.util.concurrent.TimeUnit; @@ -66,7 +58,6 @@ import java.util.concurrent.TimeUnit; ) public class TbSendRPCRequestNode implements TbNode { - private static final ObjectMapper json = new ObjectMapper(); private Random random = new Random(); private Gson gson = new Gson(); private JsonParser jsonParser = new JsonParser(); @@ -123,59 +114,19 @@ public class TbSendRPCRequestNode implements TbNode { .restApiCall(restApiCall) .build(); - EdgeId edgeId = findRelatedEdgeId(ctx, msg); - if (edgeId != null) { - sendRpcRequestToEdgeDevice(ctx, msg, edgeId, request); - } else { - ctx.getRpcService().sendRpcRequestToDevice(request, ruleEngineDeviceRpcResponse -> { - if (!ruleEngineDeviceRpcResponse.getError().isPresent()) { - TbMsg next = ctx.newMsg(msg.getQueueName(), msg.getType(), msg.getOriginator(), msg.getMetaData(), ruleEngineDeviceRpcResponse.getResponse().orElse("{}")); - ctx.enqueueForTellNext(next, TbRelationTypes.SUCCESS); - } else { - TbMsg next = ctx.newMsg(msg.getQueueName(), msg.getType(), msg.getOriginator(), msg.getMetaData(), wrap("error", ruleEngineDeviceRpcResponse.getError().get().name())); - ctx.tellFailure(next, new RuntimeException(ruleEngineDeviceRpcResponse.getError().get().name())); - } - }); - } + ctx.getRpcService().sendRpcRequestToDevice(request, ruleEngineDeviceRpcResponse -> { + if (!ruleEngineDeviceRpcResponse.getError().isPresent()) { + TbMsg next = ctx.newMsg(msg.getQueueName(), msg.getType(), msg.getOriginator(), msg.getMetaData(), ruleEngineDeviceRpcResponse.getResponse().orElse("{}")); + ctx.enqueueForTellNext(next, TbRelationTypes.SUCCESS); + } else { + TbMsg next = ctx.newMsg(msg.getQueueName(), msg.getType(), msg.getOriginator(), msg.getMetaData(), wrap("error", ruleEngineDeviceRpcResponse.getError().get().name())); + ctx.tellFailure(next, new RuntimeException(ruleEngineDeviceRpcResponse.getError().get().name())); + } + }); ctx.ack(msg); } } - private EdgeId findRelatedEdgeId(TbContext ctx, TbMsg msg) { - List result = - ctx.getRelationService().findByToAndType(ctx.getTenantId(), msg.getOriginator(), EntityRelation.EDGE_TYPE, RelationTypeGroup.COMMON); - if (result != null && result.size() > 0) { - EntityRelation relationToEdge = result.get(0); - if (relationToEdge.getFrom() != null && relationToEdge.getFrom().getId() != null) { - return new EdgeId(relationToEdge.getFrom().getId()); - } - } - return null; - } - - private void sendRpcRequestToEdgeDevice(TbContext ctx, TbMsg msg, EdgeId edgeId, RuleEngineDeviceRpcRequest request) { - EdgeEvent edgeEvent = new EdgeEvent(); - edgeEvent.setTenantId(ctx.getTenantId()); - edgeEvent.setAction(ActionType.RPC_CALL.name()); - edgeEvent.setEntityId(request.getDeviceId().getId()); - edgeEvent.setType(EdgeEventType.DEVICE); - edgeEvent.setBody(json.valueToTree(request)); - edgeEvent.setEdgeId(edgeId); - ListenableFuture saveFuture = ctx.getEdgeEventService().saveAsync(edgeEvent); - Futures.addCallback(saveFuture, new FutureCallback() { - @Override - public void onSuccess(@Nullable EdgeEvent event) { - ctx.tellSuccess(msg); - } - - @Override - public void onFailure(Throwable th) { - log.error("Could not save edge event", th); - ctx.tellFailure(msg, th); - } - }, ctx.getDbCallbackExecutor()); - } - @Override public void destroy() { } diff --git a/ui/src/app/dashboard/add-dashboards-to-edge.controller.js b/ui/src/app/dashboard/add-dashboards-to-edge.controller.js index e5dcc00b33..52276f34de 100644 --- a/ui/src/app/dashboard/add-dashboards-to-edge.controller.js +++ b/ui/src/app/dashboard/add-dashboards-to-edge.controller.js @@ -14,7 +14,7 @@ * limitations under the License. */ /*@ngInject*/ -export default function AddDashboardsToEdgeController(dashboardService, types, $mdDialog, $q, edgeId, edgeCustomerId, dashboards) { +export default function AddDashboardsToEdgeController(dashboardService, types, $mdDialog, $q, edgeId, dashboards) { var vm = this; diff --git a/ui/src/app/edge/edge-fieldset.tpl.html b/ui/src/app/edge/edge-fieldset.tpl.html index bf0f09d972..ddc109a2cc 100644 --- a/ui/src/app/edge/edge-fieldset.tpl.html +++ b/ui/src/app/edge/edge-fieldset.tpl.html @@ -48,6 +48,20 @@ edge.copy-id + + + edge.copy-edge-key + + + + edge.copy-edge-secret + @@ -105,6 +119,7 @@
+ diff --git a/ui/src/app/edge/edge.directive.js b/ui/src/app/edge/edge.directive.js index 04165418e9..bdd3b44b67 100644 --- a/ui/src/app/edge/edge.directive.js +++ b/ui/src/app/edge/edge.directive.js @@ -83,19 +83,18 @@ export default function EdgeDirective($compile, $templateCache, $translate, $mdD $compile(element.contents())(scope); scope.onEdgeInfoCopied = function(type) { - let translateInstant = ""; + let infoTypeLabel = ""; switch (type) { case 'key': - translateInstant = "edge.edge-key-copied-message"; + infoTypeLabel = "edge.edge-key-copied-message"; break; case 'secret': - translateInstant = "edge.edge-secret-copied-message"; + infoTypeLabel = "edge.edge-secret-copied-message"; break; } - toast.showSuccess($translate.instant(translateInstant), 750, angular.element(element).parent().parent(), 'top left'); + toast.showSuccess($translate.instant(infoTypeLabel), 750, angular.element(element).parent().parent(), 'bottom left'); }; - }; return { restrict: "E", diff --git a/ui/src/app/edge/edge.routes.js b/ui/src/app/edge/edge.routes.js index bcba2cffe1..43bfe9850a 100644 --- a/ui/src/app/edge/edge.routes.js +++ b/ui/src/app/edge/edge.routes.js @@ -198,7 +198,7 @@ export default function EdgeRoutes($stateProvider, types) { ruleChainsType: 'edge' }, ncyBreadcrumb: { - label: '{"icon": "settings_ethernet", "label": "rulechain.edge-rulechains"}' + label: '{"icon": "code", "label": "rulechain.edge-rulechains"}' } }).state('home.edges.ruleChains.ruleChain', { url: '/:ruleChainId', @@ -235,7 +235,7 @@ export default function EdgeRoutes($stateProvider, types) { pageTitle: 'edge.rulechain' }, ncyBreadcrumb: { - label: '{"icon": "settings_ethernet", "label": "{{ vm.ruleChain.name }}", "translate": "false"}' + label: '{"icon": "code", "label": "{{ vm.ruleChain.name }}", "translate": "false"}' } }); } diff --git a/ui/src/app/event/event-row-edge-event.tpl.html b/ui/src/app/event/event-row-edge-event.tpl.html index 6cc06d0cc3..01b6c6e261 100644 --- a/ui/src/app/event/event-row-edge-event.tpl.html +++ b/ui/src/app/event/event-row-edge-event.tpl.html @@ -19,7 +19,7 @@
{{ event.type }}
{{ event.action }}
{{ event.entityId }}
-
{{ updateStatus(event.createdTime) | translate }}
+
{{ updateStatus(event.createdTime) }}