Browse Source

Merge remote-tracking branch 'origin/develop/2.6-edge' into develop/3.3-edge

pull/3811/head
Volodymyr Babak 6 years ago
parent
commit
9f79f83d83
  1. 3
      application/src/main/java/org/thingsboard/server/actors/ActorSystemContext.java
  2. 2
      application/src/main/java/org/thingsboard/server/actors/app/AppActor.java
  3. 8
      application/src/main/java/org/thingsboard/server/actors/device/DeviceActor.java
  4. 83
      application/src/main/java/org/thingsboard/server/actors/device/DeviceActorMessageProcessor.java
  5. 58
      application/src/main/java/org/thingsboard/server/actors/ruleChain/RuleChainActorMessageProcessor.java
  6. 4
      application/src/main/java/org/thingsboard/server/actors/tenant/TenantActor.java
  7. 9
      application/src/main/java/org/thingsboard/server/controller/AlarmController.java
  8. 18
      application/src/main/java/org/thingsboard/server/controller/AssetController.java
  9. 5
      application/src/main/java/org/thingsboard/server/controller/AuthController.java
  10. 27
      application/src/main/java/org/thingsboard/server/controller/BaseController.java
  11. 5
      application/src/main/java/org/thingsboard/server/controller/CustomerController.java
  12. 25
      application/src/main/java/org/thingsboard/server/controller/DashboardController.java
  13. 26
      application/src/main/java/org/thingsboard/server/controller/DeviceController.java
  14. 7
      application/src/main/java/org/thingsboard/server/controller/EdgeController.java
  15. 5
      application/src/main/java/org/thingsboard/server/controller/EntityRelationController.java
  16. 18
      application/src/main/java/org/thingsboard/server/controller/EntityViewController.java
  17. 16
      application/src/main/java/org/thingsboard/server/controller/RuleChainController.java
  18. 5
      application/src/main/java/org/thingsboard/server/controller/UserController.java
  19. 5
      application/src/main/java/org/thingsboard/server/controller/WidgetTypeController.java
  20. 5
      application/src/main/java/org/thingsboard/server/controller/WidgetsBundleController.java
  21. 28
      application/src/main/java/org/thingsboard/server/service/edge/DefaultEdgeNotificationService.java
  22. 22
      application/src/main/java/org/thingsboard/server/service/edge/rpc/EdgeGrpcService.java
  23. 113
      application/src/main/java/org/thingsboard/server/service/edge/rpc/EdgeGrpcSession.java
  24. 4
      application/src/main/java/org/thingsboard/server/service/edge/rpc/constructor/AdminSettingsMsgConstructor.java
  25. 6
      application/src/main/java/org/thingsboard/server/service/edge/rpc/constructor/AlarmMsgConstructor.java
  26. 4
      application/src/main/java/org/thingsboard/server/service/edge/rpc/constructor/AssetMsgConstructor.java
  27. 4
      application/src/main/java/org/thingsboard/server/service/edge/rpc/constructor/CustomerMsgConstructor.java
  28. 5
      application/src/main/java/org/thingsboard/server/service/edge/rpc/constructor/DashboardMsgConstructor.java
  29. 35
      application/src/main/java/org/thingsboard/server/service/edge/rpc/constructor/DeviceMsgConstructor.java
  30. 29
      application/src/main/java/org/thingsboard/server/service/edge/rpc/constructor/EntityDataMsgConstructor.java
  31. 4
      application/src/main/java/org/thingsboard/server/service/edge/rpc/constructor/EntityViewMsgConstructor.java
  32. 4
      application/src/main/java/org/thingsboard/server/service/edge/rpc/constructor/RelationMsgConstructor.java
  33. 2
      application/src/main/java/org/thingsboard/server/service/edge/rpc/constructor/RuleChainMsgConstructor.java
  34. 7
      application/src/main/java/org/thingsboard/server/service/edge/rpc/constructor/UserMsgConstructor.java
  35. 4
      application/src/main/java/org/thingsboard/server/service/edge/rpc/constructor/WidgetTypeMsgConstructor.java
  36. 4
      application/src/main/java/org/thingsboard/server/service/edge/rpc/constructor/WidgetsBundleMsgConstructor.java
  37. 58
      application/src/main/java/org/thingsboard/server/service/edge/rpc/init/DefaultSyncEdgeService.java
  38. 1
      application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/AlarmProcessor.java
  39. 7
      application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/BaseProcessor.java
  40. 47
      application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/DeviceProcessor.java
  41. 2
      application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/RelationProcessor.java
  42. 1
      application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/TelemetryProcessor.java
  43. 1
      application/src/main/java/org/thingsboard/server/service/install/InstallScripts.java
  44. 3
      application/src/main/java/org/thingsboard/server/service/rpc/DefaultTbRuleEngineRpcService.java
  45. 3
      application/src/main/java/org/thingsboard/server/service/rpc/FromDeviceRpcResponse.java
  46. 44
      application/src/main/java/org/thingsboard/server/service/rpc/FromDeviceRpcResponseActorMsg.java
  47. 10
      application/src/main/java/org/thingsboard/server/service/rpc/TbRuleEngineDeviceRpcService.java
  48. 4
      application/src/main/java/org/thingsboard/server/service/security/permission/Resource.java
  49. 2
      application/src/main/java/org/thingsboard/server/service/ttl/edge/EdgeEventsCleanUpService.java
  50. 606
      application/src/test/java/org/thingsboard/server/edge/BaseEdgeTest.java
  51. 12
      application/src/test/java/org/thingsboard/server/edge/imitator/EdgeImitator.java
  52. 5
      common/data/src/main/java/org/thingsboard/server/common/data/audit/ActionType.java
  53. 2
      common/data/src/main/java/org/thingsboard/server/common/data/edge/EdgeEvent.java
  54. 38
      common/data/src/main/java/org/thingsboard/server/common/data/edge/EdgeEventActionType.java
  55. 11
      common/edge-api/src/main/proto/edge.proto
  56. 4
      common/message/src/main/java/org/thingsboard/server/common/msg/MsgType.java
  57. 2
      dao/src/main/java/org/thingsboard/server/dao/edge/BaseEdgeEventService.java
  58. 11
      dao/src/main/java/org/thingsboard/server/dao/edge/EdgeServiceImpl.java
  59. 4
      dao/src/main/java/org/thingsboard/server/dao/model/sql/EdgeEventEntity.java
  60. 1
      dao/src/main/java/org/thingsboard/server/dao/rule/BaseRuleChainService.java
  61. 1
      dao/src/main/java/org/thingsboard/server/dao/sql/edge/JpaBaseEdgeEventDao.java
  62. 11
      dao/src/test/java/org/thingsboard/server/dao/service/BaseEdgeEventServiceTest.java
  63. 2
      dao/src/test/resources/sql/hsql/drop-all-tables.sql
  64. 2
      dao/src/test/resources/sql/psql/drop-all-tables.sql
  65. 2
      dao/src/test/resources/sql/timescale/drop-all-tables.sql
  66. 37
      rule-engine/rule-engine-api/src/main/java/org/thingsboard/rule/engine/api/msg/DeviceEdgeUpdateMsg.java
  67. 45
      rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/edge/TbMsgPushToEdgeNode.java
  68. 67
      rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/rpc/TbSendRPCRequestNode.java
  69. 2
      ui/src/app/dashboard/add-dashboards-to-edge.controller.js
  70. 15
      ui/src/app/edge/edge-fieldset.tpl.html
  71. 9
      ui/src/app/edge/edge.directive.js
  72. 4
      ui/src/app/edge/edge.routes.js
  73. 2
      ui/src/app/event/event-row-edge-event.tpl.html

3
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() {

2
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;

8
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;
}

83
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<EntityRelation> 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<UUID> 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<UUID> 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<TsKvProto> toTsKvProtos(@Nullable List<AttributeKvEntry> result) {
List<TsKvProto> clientAttributes;

58
application/src/main/java/org/thingsboard/server/actors/ruleChain/RuleChainActorMessageProcessor.java

@ -99,19 +99,17 @@ public class RuleChainActorMessageProcessor extends ComponentMsgProcessor<RuleCh
public void start(TbActorCtx context) {
if (!started) {
RuleChain ruleChain = service.findRuleChainById(tenantId, entityId);
if (ruleChain != null) {
if (ruleChain.getType().equals(RuleChainType.CORE)) {
List<RuleNode> 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<RuleNode> 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<RuleCh
@Override
public void onUpdate(TbActorCtx context) {
RuleChain ruleChain = service.findRuleChainById(tenantId, entityId);
if (ruleChain != null) {
if (ruleChain.getType().equals(RuleChainType.CORE)) {
ruleChainName = ruleChain.getName();
List<RuleNode> 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<RuleNode> 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<RuleNodeId> existingNodes = ruleNodeList.stream().map(RuleNode::getId).collect(Collectors.toSet());
List<RuleNodeId> removedRules = nodeActors.keySet().stream().filter(node -> !existingNodes.contains(node)).collect(Collectors.toList());
@ -147,10 +144,7 @@ public class RuleChainActorMessageProcessor extends ComponentMsgProcessor<RuleCh
removed.getSelfActor().tellWithHighPriority(new ComponentLifecycleMsg(tenantId, removed.getSelf().getId(), ComponentLifecycleEvent.DELETED));
});
initRoutes(ruleChain, ruleNodeList);
} else if (ruleChain.getType().equals(RuleChainType.EDGE)) {
stop(context);
}
initRoutes(ruleChain, ruleNodeList);
}
}

4
application/src/main/java/org/thingsboard/server/actors/tenant/TenantActor.java

@ -160,7 +160,9 @@ public class TenantActor extends RuleChainManagerActor {
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((DeviceAwareMsg) msg, true);
break;
@ -252,7 +254,7 @@ public class TenantActor extends RuleChainManagerActor {
if (msg.getEntityId().getEntityType() == EntityType.RULE_CHAIN) {
RuleChain ruleChain = systemContext.getRuleChainService().
findRuleChainById(tenantId, new RuleChainId(msg.getEntityId().getId()));
if (ruleChain != null && ruleChain.getType().equals(RuleChainType.CORE)) {
if (ruleChain != null && RuleChainType.CORE.equals(ruleChain.getType())) {
visit(ruleChain, target);
}
}

9
application/src/main/java/org/thingsboard/server/controller/AlarmController.java

@ -34,6 +34,7 @@ import org.thingsboard.server.common.data.alarm.AlarmSearchStatus;
import org.thingsboard.server.common.data.alarm.AlarmSeverity;
import org.thingsboard.server.common.data.alarm.AlarmStatus;
import org.thingsboard.server.common.data.audit.ActionType;
import org.thingsboard.server.common.data.edge.EdgeEventActionType;
import org.thingsboard.server.common.data.exception.ThingsboardErrorCode;
import org.thingsboard.server.common.data.exception.ThingsboardException;
import org.thingsboard.server.common.data.id.AlarmId;
@ -95,7 +96,7 @@ public class AlarmController extends BaseController {
alarm.getId() == null ? ActionType.ADDED : ActionType.UPDATED, null);
sendNotificationMsgToEdgeService(getTenantId(), savedAlarm.getId(),
alarm.getId() == null ? ActionType.ADDED : ActionType.UPDATED);
alarm.getId() == null ? EdgeEventActionType.ADDED : EdgeEventActionType.UPDATED);
return savedAlarm;
} catch (Exception e) {
@ -114,7 +115,7 @@ public class AlarmController extends BaseController {
AlarmId alarmId = new AlarmId(toUUID(strAlarmId));
checkAlarmId(alarmId, Operation.WRITE);
sendNotificationMsgToEdgeService(getTenantId(), alarmId, ActionType.DELETED);
sendNotificationMsgToEdgeService(getTenantId(), alarmId, EdgeEventActionType.DELETED);
return alarmService.deleteAlarm(getTenantId(), alarmId);
} catch (Exception e) {
@ -136,7 +137,7 @@ public class AlarmController extends BaseController {
alarm.setStatus(alarm.getStatus().isCleared() ? AlarmStatus.CLEARED_ACK : AlarmStatus.ACTIVE_ACK);
logEntityAction(alarm.getOriginator(), alarm, getCurrentUser().getCustomerId(), ActionType.ALARM_ACK, null);
sendNotificationMsgToEdgeService(getTenantId(), alarmId, ActionType.ALARM_ACK);
sendNotificationMsgToEdgeService(getTenantId(), alarmId, EdgeEventActionType.ALARM_ACK);
} catch (Exception e) {
throw handleException(e);
}
@ -156,7 +157,7 @@ public class AlarmController extends BaseController {
alarm.setStatus(alarm.getStatus().isAck() ? AlarmStatus.CLEARED_ACK : AlarmStatus.CLEARED_UNACK);
logEntityAction(alarm.getOriginator(), alarm, getCurrentUser().getCustomerId(), ActionType.ALARM_CLEAR, null);
sendNotificationMsgToEdgeService(getTenantId(), alarmId, ActionType.ALARM_CLEAR);
sendNotificationMsgToEdgeService(getTenantId(), alarmId, EdgeEventActionType.ALARM_CLEAR);
} catch (Exception e) {
throw handleException(e);
}

18
application/src/main/java/org/thingsboard/server/controller/AssetController.java

@ -27,7 +27,6 @@ import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.bind.annotation.RestController;
import org.thingsboard.server.common.data.Customer;
import org.thingsboard.server.common.data.DataConstants;
import org.thingsboard.server.common.data.EntitySubtype;
import org.thingsboard.server.common.data.EntityType;
import org.thingsboard.server.common.data.asset.Asset;
@ -37,6 +36,7 @@ import org.thingsboard.server.common.data.audit.ActionType;
import org.thingsboard.server.common.data.edge.Edge;
import org.thingsboard.server.common.data.edge.EdgeEventType;
import org.thingsboard.server.common.data.exception.ThingsboardErrorCode;
import org.thingsboard.server.common.data.edge.EdgeEventActionType;
import org.thingsboard.server.common.data.exception.ThingsboardException;
import org.thingsboard.server.common.data.id.AssetId;
import org.thingsboard.server.common.data.id.CustomerId;
@ -113,7 +113,7 @@ public class AssetController extends BaseController {
asset.getId() == null ? ActionType.ADDED : ActionType.UPDATED, null);
if (asset.getId() != null) {
sendNotificationMsgToEdgeService(savedAsset.getTenantId(), savedAsset.getId(), ActionType.UPDATED);
sendNotificationMsgToEdgeService(savedAsset.getTenantId(), savedAsset.getId(), EdgeEventActionType.UPDATED);
}
return savedAsset;
@ -138,7 +138,7 @@ public class AssetController extends BaseController {
asset.getCustomerId(),
ActionType.DELETED, null, strAssetId);
sendNotificationMsgToEdgeService(getTenantId(), assetId, ActionType.DELETED);
sendNotificationMsgToEdgeService(getTenantId(), assetId, EdgeEventActionType.DELETED);
} catch (Exception e) {
logEntityAction(emptyId(EntityType.ASSET),
null,
@ -169,7 +169,7 @@ public class AssetController extends BaseController {
ActionType.ASSIGNED_TO_CUSTOMER, null, strAssetId, strCustomerId, customer.getName());
sendNotificationMsgToEdgeService(savedAsset.getTenantId(), savedAsset.getId(),
customerId, ActionType.ASSIGNED_TO_CUSTOMER);
customerId, EdgeEventActionType.ASSIGNED_TO_CUSTOMER);
return savedAsset;
} catch (Exception e) {
@ -203,7 +203,7 @@ public class AssetController extends BaseController {
ActionType.UNASSIGNED_FROM_CUSTOMER, null, strAssetId, customer.getId().toString(), customer.getName());
sendNotificationMsgToEdgeService(savedAsset.getTenantId(), savedAsset.getId(),
customer.getId(), ActionType.UNASSIGNED_FROM_CUSTOMER);
customer.getId(), EdgeEventActionType.UNASSIGNED_FROM_CUSTOMER);
return savedAsset;
} catch (Exception e) {
@ -439,7 +439,7 @@ public class AssetController extends BaseController {
savedAsset.getCustomerId(),
ActionType.ASSIGNED_TO_EDGE, null, strAssetId, strEdgeId, edge.getName());
sendNotificationMsgToEdgeService(getTenantId(), edgeId, savedAsset.getId(), ActionType.ASSIGNED_TO_EDGE);
sendNotificationMsgToEdgeService(getTenantId(), edgeId, savedAsset.getId(), EdgeEventActionType.ASSIGNED_TO_EDGE);
return savedAsset;
} catch (Exception e) {
@ -470,16 +470,16 @@ public class AssetController extends BaseController {
logEntityAction(assetId, asset,
asset.getCustomerId(),
ActionType.UNASSIGNED_FROM_EDGE, null, strAssetId, edge.getId().toString(), edge.getName());
ActionType.UNASSIGNED_FROM_EDGE, null, strAssetId, strEdgeId, edge.getName());
sendNotificationMsgToEdgeService(getTenantId(), edgeId, savedAsset.getId(), ActionType.UNASSIGNED_FROM_EDGE);
sendNotificationMsgToEdgeService(getTenantId(), edgeId, savedAsset.getId(), EdgeEventActionType.UNASSIGNED_FROM_EDGE);
return savedAsset;
} catch (Exception e) {
logEntityAction(emptyId(EntityType.ASSET), null,
null,
ActionType.UNASSIGNED_FROM_EDGE, e, strAssetId);
ActionType.UNASSIGNED_FROM_EDGE, e, strAssetId, strEdgeId);
throw handleException(e);
}

5
application/src/main/java/org/thingsboard/server/controller/AuthController.java

@ -35,6 +35,7 @@ import org.springframework.web.bind.annotation.RestController;
import org.thingsboard.rule.engine.api.MailService;
import org.thingsboard.server.common.data.User;
import org.thingsboard.server.common.data.audit.ActionType;
import org.thingsboard.server.common.data.edge.EdgeEventActionType;
import org.thingsboard.server.common.data.edge.EdgeEventType;
import org.thingsboard.server.common.data.exception.ThingsboardErrorCode;
import org.thingsboard.server.common.data.exception.ThingsboardException;
@ -121,7 +122,7 @@ public class AuthController extends BaseController {
userCredentials.setPassword(passwordEncoder.encode(newPassword));
userService.replaceUserCredentials(securityUser.getTenantId(), userCredentials);
sendNotificationMsgToEdgeService(getTenantId(), userCredentials.getUserId(), ActionType.CREDENTIALS_UPDATED);
sendNotificationMsgToEdgeService(getTenantId(), userCredentials.getUserId(), EdgeEventActionType.CREDENTIALS_UPDATED);
} catch (Exception e) {
throw handleException(e);
@ -231,7 +232,7 @@ public class AuthController extends BaseController {
}
}
sendNotificationMsgToEdgeService(user.getTenantId(), user.getId(), ActionType.CREDENTIALS_UPDATED);
sendNotificationMsgToEdgeService(user.getTenantId(), user.getId(), EdgeEventActionType.CREDENTIALS_UPDATED);
JwtToken accessToken = tokenFactory.createAccessJwtToken(securityUser);
JwtToken refreshToken = refreshTokenRepository.requestRefreshToken(securityUser);

27
application/src/main/java/org/thingsboard/server/controller/BaseController.java

@ -50,6 +50,7 @@ import org.thingsboard.server.common.data.asset.Asset;
import org.thingsboard.server.common.data.asset.AssetInfo;
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.exception.ThingsboardErrorCode;
import org.thingsboard.server.common.data.exception.ThingsboardException;
@ -255,7 +256,7 @@ public abstract class BaseController {
@Value("${edges.rpc.enabled}")
@Getter
private boolean edgesSupportEnabled;
private boolean edgesRpcEnabled;
@ExceptionHandler(ThingsboardException.class)
public void handleThingsboardException(ThingsboardException ex, HttpServletResponse response) {
@ -802,10 +803,14 @@ public abstract class BaseController {
metaData.putValue("assignedToTenantName", strTenantName);
} else if (actionType == ActionType.ASSIGNED_TO_EDGE) {
String strEdgeId = extractParameter(String.class, 1, additionalInfo);
String strEdgeName = extractParameter(String.class, 2, additionalInfo);
metaData.putValue("assignedEdgeId", strEdgeId);
metaData.putValue("assignedEdgeName", strEdgeName);
} else if (actionType == ActionType.UNASSIGNED_FROM_EDGE) {
String strEdgeId = extractParameter(String.class, 1, additionalInfo);
String strEdgeName = extractParameter(String.class, 2, additionalInfo);
metaData.putValue("unassignedEdgeId", strEdgeId);
metaData.putValue("unassignedEdgeName", strEdgeName);
}
ObjectNode entityNode;
if (entity != null) {
@ -878,8 +883,8 @@ public abstract class BaseController {
return null;
}
protected void sendNotificationMsgToEdgeService(TenantId tenantId, EdgeId edgeId, CustomerId customerId, ActionType action) {
if (!edgesSupportEnabled) {
protected void sendNotificationMsgToEdgeService(TenantId tenantId, EdgeId edgeId, CustomerId customerId, EdgeEventActionType action) {
if (!edgesRpcEnabled) {
return;
}
try {
@ -889,8 +894,8 @@ public abstract class BaseController {
}
}
protected void sendNotificationMsgToEdgeService(TenantId tenantId, EntityId entityId, CustomerId customerId, ActionType action) {
if (!edgesSupportEnabled) {
protected void sendNotificationMsgToEdgeService(TenantId tenantId, EntityId entityId, CustomerId customerId, EdgeEventActionType action) {
if (!edgesRpcEnabled) {
return;
}
EdgeEventType type = EdgeUtils.getEdgeEventTypeByEntityType(entityId.getEntityType());
@ -903,8 +908,8 @@ public abstract class BaseController {
}
}
protected void sendNotificationMsgToEdgeService(TenantId tenantId, EntityRelation relation, ActionType action) {
if (!edgesSupportEnabled) {
protected void sendNotificationMsgToEdgeService(TenantId tenantId, EntityRelation relation, EdgeEventActionType action) {
if (!edgesRpcEnabled) {
return;
}
try {
@ -917,12 +922,12 @@ public abstract class BaseController {
}
}
protected void sendNotificationMsgToEdgeService(TenantId tenantId, EntityId entityId, ActionType action) {
protected void sendNotificationMsgToEdgeService(TenantId tenantId, EntityId entityId, EdgeEventActionType action) {
sendNotificationMsgToEdgeService(tenantId, null, entityId, action);
}
protected void sendNotificationMsgToEdgeService(TenantId tenantId, EdgeId edgeId, EntityId entityId, ActionType action) {
if (!edgesSupportEnabled) {
protected void sendNotificationMsgToEdgeService(TenantId tenantId, EdgeId edgeId, EntityId entityId, EdgeEventActionType action) {
if (!edgesRpcEnabled) {
return;
}
EdgeEventType type = EdgeUtils.getEdgeEventTypeByEntityType(entityId.getEntityType());
@ -931,7 +936,7 @@ public abstract class BaseController {
}
}
private void sendNotificationMsgToEdgeService(TenantId tenantId, EdgeId edgeId, EntityId entityId, String body, EdgeEventType type, ActionType action) {
private void sendNotificationMsgToEdgeService(TenantId tenantId, EdgeId edgeId, EntityId entityId, String body, EdgeEventType type, EdgeEventActionType action) {
TransportProtos.EdgeNotificationMsgProto.Builder builder = TransportProtos.EdgeNotificationMsgProto.newBuilder();
builder.setTenantIdMSB(tenantId.getId().getMostSignificantBits());
builder.setTenantIdLSB(tenantId.getId().getLeastSignificantBits());

5
application/src/main/java/org/thingsboard/server/controller/CustomerController.java

@ -31,6 +31,7 @@ import org.springframework.web.bind.annotation.RestController;
import org.thingsboard.server.common.data.Customer;
import org.thingsboard.server.common.data.EntityType;
import org.thingsboard.server.common.data.audit.ActionType;
import org.thingsboard.server.common.data.edge.EdgeEventActionType;
import org.thingsboard.server.common.data.exception.ThingsboardException;
import org.thingsboard.server.common.data.id.CustomerId;
import org.thingsboard.server.common.data.id.TenantId;
@ -109,7 +110,7 @@ public class CustomerController extends BaseController {
customer.getId() == null ? ActionType.ADDED : ActionType.UPDATED, null);
if (customer.getId() != null) {
sendNotificationMsgToEdgeService(savedCustomer.getTenantId(), savedCustomer.getId(),ActionType.UPDATED);
sendNotificationMsgToEdgeService(savedCustomer.getTenantId(), savedCustomer.getId(), EdgeEventActionType.UPDATED);
}
return savedCustomer;
@ -136,7 +137,7 @@ public class CustomerController extends BaseController {
customer.getId(),
ActionType.DELETED, null, strCustomerId);
sendNotificationMsgToEdgeService(getTenantId(), customerId, ActionType.DELETED);
sendNotificationMsgToEdgeService(getTenantId(), customerId, EdgeEventActionType.DELETED);
} catch (Exception e) {
logEntityAction(emptyId(EntityType.CUSTOMER),

25
application/src/main/java/org/thingsboard/server/controller/DashboardController.java

@ -33,6 +33,7 @@ import org.thingsboard.server.common.data.EntityType;
import org.thingsboard.server.common.data.ShortCustomerInfo;
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.exception.ThingsboardException;
import org.thingsboard.server.common.data.id.CustomerId;
import org.thingsboard.server.common.data.id.DashboardId;
@ -115,7 +116,7 @@ public class DashboardController extends BaseController {
dashboard.getId() == null ? ActionType.ADDED : ActionType.UPDATED, null);
if (dashboard.getId() != null) {
sendNotificationMsgToEdgeService(savedDashboard.getTenantId(), savedDashboard.getId(), ActionType.UPDATED);
sendNotificationMsgToEdgeService(savedDashboard.getTenantId(), savedDashboard.getId(), EdgeEventActionType.UPDATED);
}
return savedDashboard;
@ -141,7 +142,7 @@ public class DashboardController extends BaseController {
null,
ActionType.DELETED, null, strDashboardId);
sendNotificationMsgToEdgeService(getTenantId(), dashboardId, ActionType.DELETED);
sendNotificationMsgToEdgeService(getTenantId(), dashboardId, EdgeEventActionType.DELETED);
} catch (Exception e) {
logEntityAction(emptyId(EntityType.DASHBOARD),
@ -173,7 +174,7 @@ public class DashboardController extends BaseController {
customerId,
ActionType.ASSIGNED_TO_CUSTOMER, null, strDashboardId, strCustomerId, customer.getName());
sendNotificationMsgToEdgeService(savedDashboard.getTenantId(), savedDashboard.getId(), customerId, ActionType.ASSIGNED_TO_CUSTOMER);
sendNotificationMsgToEdgeService(savedDashboard.getTenantId(), savedDashboard.getId(), customerId, EdgeEventActionType.ASSIGNED_TO_CUSTOMER);
return savedDashboard;
} catch (Exception e) {
@ -205,7 +206,7 @@ public class DashboardController extends BaseController {
customerId,
ActionType.UNASSIGNED_FROM_CUSTOMER, null, strDashboardId, customer.getId().toString(), customer.getName());
sendNotificationMsgToEdgeService(savedDashboard.getTenantId(), savedDashboard.getId(), customerId, ActionType.UNASSIGNED_FROM_CUSTOMER);
sendNotificationMsgToEdgeService(savedDashboard.getTenantId(), savedDashboard.getId(), customerId, EdgeEventActionType.UNASSIGNED_FROM_CUSTOMER);
return savedDashboard;
} catch (Exception e) {
@ -262,7 +263,7 @@ public class DashboardController extends BaseController {
logEntityAction(dashboardId, savedDashboard,
customerId,
ActionType.ASSIGNED_TO_CUSTOMER, null, strDashboardId, customerId.toString(), customerInfo.getTitle());
sendNotificationMsgToEdgeService(savedDashboard.getTenantId(), savedDashboard.getId(), customerId, ActionType.ASSIGNED_TO_CUSTOMER);
sendNotificationMsgToEdgeService(savedDashboard.getTenantId(), savedDashboard.getId(), customerId, EdgeEventActionType.ASSIGNED_TO_CUSTOMER);
}
for (CustomerId customerId : removedCustomerIds) {
ShortCustomerInfo customerInfo = dashboard.getAssignedCustomerInfo(customerId);
@ -270,7 +271,7 @@ public class DashboardController extends BaseController {
logEntityAction(dashboardId, dashboard,
customerId,
ActionType.UNASSIGNED_FROM_CUSTOMER, null, strDashboardId, customerId.toString(), customerInfo.getTitle());
sendNotificationMsgToEdgeService(savedDashboard.getTenantId(), savedDashboard.getId(), customerId, ActionType.UNASSIGNED_FROM_CUSTOMER);
sendNotificationMsgToEdgeService(savedDashboard.getTenantId(), savedDashboard.getId(), customerId, EdgeEventActionType.UNASSIGNED_FROM_CUSTOMER);
}
return savedDashboard;
}
@ -314,7 +315,7 @@ public class DashboardController extends BaseController {
logEntityAction(dashboardId, savedDashboard,
customerId,
ActionType.ASSIGNED_TO_CUSTOMER, null, strDashboardId, customerId.toString(), customerInfo.getTitle());
sendNotificationMsgToEdgeService(savedDashboard.getTenantId(), savedDashboard.getId(), customerId, ActionType.ASSIGNED_TO_CUSTOMER);
sendNotificationMsgToEdgeService(savedDashboard.getTenantId(), savedDashboard.getId(), customerId, EdgeEventActionType.ASSIGNED_TO_CUSTOMER);
}
return savedDashboard;
}
@ -358,7 +359,7 @@ public class DashboardController extends BaseController {
logEntityAction(dashboardId, dashboard,
customerId,
ActionType.UNASSIGNED_FROM_CUSTOMER, null, strDashboardId, customerId.toString(), customerInfo.getTitle());
sendNotificationMsgToEdgeService(savedDashboard.getTenantId(), savedDashboard.getId(), customerId, ActionType.UNASSIGNED_FROM_CUSTOMER);
sendNotificationMsgToEdgeService(savedDashboard.getTenantId(), savedDashboard.getId(), customerId, EdgeEventActionType.UNASSIGNED_FROM_CUSTOMER);
}
return savedDashboard;
}
@ -505,7 +506,7 @@ public class DashboardController extends BaseController {
null,
ActionType.ASSIGNED_TO_EDGE, null, strDashboardId, strEdgeId, edge.getName());
sendNotificationMsgToEdgeService(getTenantId(), edgeId, savedDashboard.getId(), ActionType.ASSIGNED_TO_EDGE);
sendNotificationMsgToEdgeService(getTenantId(), edgeId, savedDashboard.getId(), EdgeEventActionType.ASSIGNED_TO_EDGE);
return savedDashboard;
} catch (Exception e) {
@ -535,16 +536,16 @@ public class DashboardController extends BaseController {
logEntityAction(dashboardId, dashboard,
null,
ActionType.UNASSIGNED_FROM_EDGE, null, strDashboardId, edge.getId().toString(), edge.getName());
ActionType.UNASSIGNED_FROM_EDGE, null, strDashboardId, strEdgeId, edge.getName());
sendNotificationMsgToEdgeService(getTenantId(), edgeId, savedDashboard.getId(), ActionType.UNASSIGNED_FROM_EDGE);
sendNotificationMsgToEdgeService(getTenantId(), edgeId, savedDashboard.getId(), EdgeEventActionType.UNASSIGNED_FROM_EDGE);
return savedDashboard;
} catch (Exception e) {
logEntityAction(emptyId(EntityType.DASHBOARD), null,
null,
ActionType.UNASSIGNED_FROM_EDGE, e, strDashboardId);
ActionType.UNASSIGNED_FROM_EDGE, e, strDashboardId, strEdgeId);
throw handleException(e);
}

26
application/src/main/java/org/thingsboard/server/controller/DeviceController.java

@ -32,6 +32,7 @@ import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.context.request.async.DeferredResult;
import org.thingsboard.rule.engine.api.msg.DeviceCredentialsUpdateNotificationMsg;
import org.thingsboard.rule.engine.api.msg.DeviceEdgeUpdateMsg;
import org.thingsboard.rule.engine.api.msg.DeviceNameOrTypeUpdateMsg;
import org.thingsboard.server.common.data.ClaimRequest;
import org.thingsboard.server.common.data.Customer;
@ -44,6 +45,7 @@ import org.thingsboard.server.common.data.Tenant;
import org.thingsboard.server.common.data.audit.ActionType;
import org.thingsboard.server.common.data.device.DeviceSearchQuery;
import org.thingsboard.server.common.data.edge.Edge;
import org.thingsboard.server.common.data.edge.EdgeEventActionType;
import org.thingsboard.server.common.data.exception.ThingsboardErrorCode;
import org.thingsboard.server.common.data.exception.ThingsboardException;
import org.thingsboard.server.common.data.id.CustomerId;
@ -130,7 +132,7 @@ public class DeviceController extends BaseController {
device.getId() == null ? ComponentLifecycleEvent.CREATED : ComponentLifecycleEvent.UPDATED);
if (device.getId() != null) {
sendNotificationMsgToEdgeService(savedDevice.getTenantId(), savedDevice.getId(), ActionType.UPDATED);
sendNotificationMsgToEdgeService(savedDevice.getTenantId(), savedDevice.getId(), EdgeEventActionType.UPDATED);
}
logEntityAction(savedDevice.getId(), savedDevice,
@ -167,7 +169,7 @@ public class DeviceController extends BaseController {
device.getCustomerId(),
ActionType.DELETED, null, strDeviceId);
sendNotificationMsgToEdgeService(getTenantId(), deviceId, ActionType.DELETED);
sendNotificationMsgToEdgeService(getTenantId(), deviceId, EdgeEventActionType.DELETED);
deviceStateService.onDeviceDeleted(device);
} catch (Exception e) {
@ -200,7 +202,7 @@ public class DeviceController extends BaseController {
ActionType.ASSIGNED_TO_CUSTOMER, null, strDeviceId, strCustomerId, customer.getName());
sendNotificationMsgToEdgeService(savedDevice.getTenantId(), savedDevice.getId(),
customerId, ActionType.ASSIGNED_TO_CUSTOMER);
customerId, EdgeEventActionType.ASSIGNED_TO_CUSTOMER);
return savedDevice;
} catch (Exception e) {
@ -231,7 +233,7 @@ public class DeviceController extends BaseController {
ActionType.UNASSIGNED_FROM_CUSTOMER, null, strDeviceId, customer.getId().toString(), customer.getName());
sendNotificationMsgToEdgeService(savedDevice.getTenantId(), savedDevice.getId(),
customer.getId(), ActionType.UNASSIGNED_FROM_CUSTOMER);
customer.getId(), EdgeEventActionType.UNASSIGNED_FROM_CUSTOMER);
return savedDevice;
} catch (Exception e) {
@ -298,7 +300,7 @@ public class DeviceController extends BaseController {
tbClusterService.pushMsgToCore(new DeviceCredentialsUpdateNotificationMsg(getCurrentUser().getTenantId(), deviceCredentials.getDeviceId()), null);
sendNotificationMsgToEdgeService(getTenantId(), device.getId(), ActionType.CREDENTIALS_UPDATED);
sendNotificationMsgToEdgeService(getTenantId(), device.getId(), EdgeEventActionType.CREDENTIALS_UPDATED);
logEntityAction(device.getId(), device,
device.getCustomerId(),
@ -655,11 +657,14 @@ public class DeviceController extends BaseController {
Device savedDevice = checkNotNull(deviceService.assignDeviceToEdge(getCurrentUser().getTenantId(), deviceId, edgeId));
tbClusterService.pushMsgToCore(new DeviceEdgeUpdateMsg(savedDevice.getTenantId(),
savedDevice.getId(), edgeId), null);
logEntityAction(deviceId, savedDevice,
savedDevice.getCustomerId(),
ActionType.ASSIGNED_TO_EDGE, null, strDeviceId, strEdgeId, edge.getName());
sendNotificationMsgToEdgeService(getTenantId(), edgeId, savedDevice.getId(), ActionType.ASSIGNED_TO_EDGE);
sendNotificationMsgToEdgeService(getTenantId(), edgeId, savedDevice.getId(), EdgeEventActionType.ASSIGNED_TO_EDGE);
return savedDevice;
} catch (Exception e) {
@ -686,17 +691,20 @@ public class DeviceController extends BaseController {
Device savedDevice = checkNotNull(deviceService.unassignDeviceFromEdge(getCurrentUser().getTenantId(), deviceId, edgeId));
tbClusterService.pushMsgToCore(new DeviceEdgeUpdateMsg(savedDevice.getTenantId(),
savedDevice.getId(), null), null);
logEntityAction(deviceId, device,
device.getCustomerId(),
ActionType.UNASSIGNED_FROM_EDGE, null, strDeviceId, edge.getId().toString(), edge.getName());
ActionType.UNASSIGNED_FROM_EDGE, null, strDeviceId, strEdgeId, edge.getName());
sendNotificationMsgToEdgeService(getTenantId(), edgeId, savedDevice.getId(), ActionType.UNASSIGNED_FROM_EDGE);
sendNotificationMsgToEdgeService(getTenantId(), edgeId, savedDevice.getId(), EdgeEventActionType.UNASSIGNED_FROM_EDGE);
return savedDevice;
} catch (Exception e) {
logEntityAction(emptyId(EntityType.DEVICE), null,
null,
ActionType.UNASSIGNED_FROM_EDGE, e, strDeviceId);
ActionType.UNASSIGNED_FROM_EDGE, e, strDeviceId, strEdgeId);
throw handleException(e);
}
}

7
application/src/main/java/org/thingsboard/server/controller/EdgeController.java

@ -32,6 +32,7 @@ import org.thingsboard.server.common.data.EntityType;
import org.thingsboard.server.common.data.audit.ActionType;
import org.thingsboard.server.common.data.edge.Edge;
import org.thingsboard.server.common.data.edge.EdgeInfo;
import org.thingsboard.server.common.data.edge.EdgeEventActionType;
import org.thingsboard.server.common.data.edge.EdgeSearchQuery;
import org.thingsboard.server.common.data.exception.ThingsboardErrorCode;
import org.thingsboard.server.common.data.exception.ThingsboardException;
@ -187,7 +188,7 @@ public class EdgeController extends BaseController {
ActionType.ASSIGNED_TO_CUSTOMER, null, strEdgeId, strCustomerId, customer.getName());
sendNotificationMsgToEdgeService(savedEdge.getTenantId(), savedEdge.getId(),
customerId, ActionType.ASSIGNED_TO_CUSTOMER);
customerId, EdgeEventActionType.ASSIGNED_TO_CUSTOMER);
return savedEdge;
} catch (Exception e) {
@ -221,7 +222,7 @@ public class EdgeController extends BaseController {
ActionType.UNASSIGNED_FROM_CUSTOMER, null, strEdgeId, customer.getId().toString(), customer.getName());
sendNotificationMsgToEdgeService(savedEdge.getTenantId(), savedEdge.getId(),
customer.getId(), ActionType.UNASSIGNED_FROM_CUSTOMER);
customer.getId(), EdgeEventActionType.UNASSIGNED_FROM_CUSTOMER);
return savedEdge;
} catch (Exception e) {
@ -469,7 +470,7 @@ public class EdgeController extends BaseController {
public void syncEdge(@RequestBody EdgeId edgeId) throws ThingsboardException {
try {
edgeId = checkNotNull(edgeId);
if (isEdgesSupportEnabled()) {
if (isEdgesRpcEnabled()) {
EdgeGrpcSession session = edgeGrpcService.getEdgeGrpcSessionById(edgeId);
Edge edge = session.getEdge();
syncEdgeService.sync(edge);

5
application/src/main/java/org/thingsboard/server/controller/EntityRelationController.java

@ -25,6 +25,7 @@ import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.bind.annotation.RestController;
import org.thingsboard.server.common.data.audit.ActionType;
import org.thingsboard.server.common.data.edge.EdgeEventActionType;
import org.thingsboard.server.common.data.exception.ThingsboardErrorCode;
import org.thingsboard.server.common.data.exception.ThingsboardException;
import org.thingsboard.server.common.data.id.EntityId;
@ -69,7 +70,7 @@ public class EntityRelationController extends BaseController {
logEntityAction(relation.getTo(), null, getCurrentUser().getCustomerId(),
ActionType.RELATION_ADD_OR_UPDATE, null, relation);
sendNotificationMsgToEdgeService(getTenantId(), relation, ActionType.RELATION_ADD_OR_UPDATE);
sendNotificationMsgToEdgeService(getTenantId(), relation, EdgeEventActionType.RELATION_ADD_OR_UPDATE);
} catch (Exception e) {
logEntityAction(relation.getFrom(), null, getCurrentUser().getCustomerId(),
ActionType.RELATION_ADD_OR_UPDATE, e, relation);
@ -108,7 +109,7 @@ public class EntityRelationController extends BaseController {
logEntityAction(relation.getTo(), null, getCurrentUser().getCustomerId(),
ActionType.RELATION_DELETED, null, relation);
sendNotificationMsgToEdgeService(getTenantId(), relation, ActionType.RELATION_DELETED);
sendNotificationMsgToEdgeService(getTenantId(), relation, EdgeEventActionType.RELATION_DELETED);
} catch (Exception e) {
logEntityAction(relation.getFrom(), null, getCurrentUser().getCustomerId(),
ActionType.RELATION_DELETED, e, relation);

18
application/src/main/java/org/thingsboard/server/controller/EntityViewController.java

@ -40,7 +40,7 @@ import org.thingsboard.server.common.data.EntityView;
import org.thingsboard.server.common.data.EntityViewInfo;
import org.thingsboard.server.common.data.audit.ActionType;
import org.thingsboard.server.common.data.edge.Edge;
import org.thingsboard.server.common.data.edge.EdgeEventType;
import org.thingsboard.server.common.data.edge.EdgeEventActionType;
import org.thingsboard.server.common.data.entityview.EntityViewSearchQuery;
import org.thingsboard.server.common.data.exception.ThingsboardException;
import org.thingsboard.server.common.data.id.CustomerId;
@ -162,7 +162,7 @@ public class EntityViewController extends BaseController {
entityView.getId() == null ? ActionType.ADDED : ActionType.UPDATED, null);
if (entityView.getId() != null) {
sendNotificationMsgToEdgeService(savedEntityView.getTenantId(), savedEntityView.getId(), ActionType.UPDATED);
sendNotificationMsgToEdgeService(savedEntityView.getTenantId(), savedEntityView.getId(), EdgeEventActionType.UPDATED);
}
return savedEntityView;
@ -364,7 +364,7 @@ public class EntityViewController extends BaseController {
logEntityAction(entityViewId, entityView, entityView.getCustomerId(),
ActionType.DELETED, null, strEntityViewId);
sendNotificationMsgToEdgeService(getTenantId(), entityViewId, ActionType.DELETED);
sendNotificationMsgToEdgeService(getTenantId(), entityViewId, EdgeEventActionType.DELETED);
} catch (Exception e) {
logEntityAction(emptyId(EntityType.ENTITY_VIEW),
null,
@ -407,7 +407,7 @@ public class EntityViewController extends BaseController {
ActionType.ASSIGNED_TO_CUSTOMER, null, strEntityViewId, strCustomerId, customer.getName());
sendNotificationMsgToEdgeService(savedEntityView.getTenantId(), savedEntityView.getId(),
customerId, ActionType.ASSIGNED_TO_CUSTOMER);
customerId, EdgeEventActionType.ASSIGNED_TO_CUSTOMER);
return savedEntityView;
} catch (Exception e) {
@ -436,7 +436,7 @@ public class EntityViewController extends BaseController {
ActionType.UNASSIGNED_FROM_CUSTOMER, null, strEntityViewId, customer.getId().toString(), customer.getName());
sendNotificationMsgToEdgeService(savedEntityView.getTenantId(), savedEntityView.getId(),
customer.getId(), ActionType.UNASSIGNED_FROM_CUSTOMER);
customer.getId(), EdgeEventActionType.UNASSIGNED_FROM_CUSTOMER);
return savedEntityView;
} catch (Exception e) {
@ -629,7 +629,7 @@ public class EntityViewController extends BaseController {
savedEntityView.getCustomerId(),
ActionType.ASSIGNED_TO_EDGE, null, strEntityViewId, strEdgeId, edge.getName());
sendNotificationMsgToEdgeService(getTenantId(), edgeId, savedEntityView.getId(), ActionType.ASSIGNED_TO_EDGE);
sendNotificationMsgToEdgeService(getTenantId(), edgeId, savedEntityView.getId(), EdgeEventActionType.ASSIGNED_TO_EDGE);
return savedEntityView;
} catch (Exception e) {
@ -657,15 +657,15 @@ public class EntityViewController extends BaseController {
EntityView savedEntityView = checkNotNull(entityViewService.unassignEntityViewFromEdge(getTenantId(), entityViewId, edgeId));
logEntityAction(entityViewId, entityView,
entityView.getCustomerId(),
ActionType.UNASSIGNED_FROM_EDGE, null, strEntityViewId, edge.getId().toString(), edge.getName());
ActionType.UNASSIGNED_FROM_EDGE, null, strEntityViewId, strEdgeId, edge.getName());
sendNotificationMsgToEdgeService(getTenantId(), edgeId, savedEntityView.getId(), ActionType.UNASSIGNED_FROM_EDGE);
sendNotificationMsgToEdgeService(getTenantId(), edgeId, savedEntityView.getId(), EdgeEventActionType.UNASSIGNED_FROM_EDGE);
return savedEntityView;
} catch (Exception e) {
logEntityAction(emptyId(EntityType.ENTITY_VIEW), null,
null,
ActionType.UNASSIGNED_FROM_EDGE, e, strEntityViewId);
ActionType.UNASSIGNED_FROM_EDGE, e, strEntityViewId, strEdgeId);
throw handleException(e);
}
}

16
application/src/main/java/org/thingsboard/server/controller/RuleChainController.java

@ -42,7 +42,7 @@ import org.thingsboard.server.common.data.EntityType;
import org.thingsboard.server.common.data.Event;
import org.thingsboard.server.common.data.audit.ActionType;
import org.thingsboard.server.common.data.edge.Edge;
import org.thingsboard.server.common.data.edge.EdgeEventType;
import org.thingsboard.server.common.data.edge.EdgeEventActionType;
import org.thingsboard.server.common.data.exception.ThingsboardException;
import org.thingsboard.server.common.data.id.EdgeId;
import org.thingsboard.server.common.data.id.RuleChainId;
@ -153,7 +153,7 @@ public class RuleChainController extends BaseController {
if (RuleChainType.EDGE.equals(savedRuleChain.getType())) {
if (!created) {
sendNotificationMsgToEdgeService(savedRuleChain.getTenantId(), savedRuleChain.getId(), ActionType.UPDATED);
sendNotificationMsgToEdgeService(savedRuleChain.getTenantId(), savedRuleChain.getId(), EdgeEventActionType.UPDATED);
}
}
@ -256,7 +256,7 @@ public class RuleChainController extends BaseController {
if (RuleChainType.EDGE.equals(ruleChain.getType())) {
sendNotificationMsgToEdgeService(ruleChain.getTenantId(),
ruleChain.getId(), ActionType.UPDATED);
ruleChain.getId(), EdgeEventActionType.UPDATED);
}
return savedRuleChainMetaData;
@ -322,7 +322,7 @@ public class RuleChainController extends BaseController {
ActionType.DELETED, null, strRuleChainId);
if (RuleChainType.EDGE.equals(ruleChain.getType())) {
sendNotificationMsgToEdgeService(ruleChain.getTenantId(), ruleChain.getId(), ActionType.DELETED);
sendNotificationMsgToEdgeService(ruleChain.getTenantId(), ruleChain.getId(), EdgeEventActionType.DELETED);
}
} catch (Exception e) {
@ -484,7 +484,7 @@ public class RuleChainController extends BaseController {
null,
ActionType.ASSIGNED_TO_EDGE, null, strRuleChainId, strEdgeId, edge.getName());
sendNotificationMsgToEdgeService(getTenantId(), edgeId, savedRuleChain.getId(), ActionType.ASSIGNED_TO_EDGE);
sendNotificationMsgToEdgeService(getTenantId(), edgeId, savedRuleChain.getId(), EdgeEventActionType.ASSIGNED_TO_EDGE);
return savedRuleChain;
} catch (Exception e) {
@ -514,16 +514,16 @@ public class RuleChainController extends BaseController {
logEntityAction(ruleChainId, ruleChain,
null,
ActionType.UNASSIGNED_FROM_EDGE, null, strRuleChainId, edge.getId().toString(), edge.getName());
ActionType.UNASSIGNED_FROM_EDGE, null, strRuleChainId, strEdgeId, edge.getName());
sendNotificationMsgToEdgeService(getTenantId(), edgeId, savedRuleChain.getId(), ActionType.UNASSIGNED_FROM_EDGE);
sendNotificationMsgToEdgeService(getTenantId(), edgeId, savedRuleChain.getId(), EdgeEventActionType.UNASSIGNED_FROM_EDGE);
return savedRuleChain;
} catch (Exception e) {
logEntityAction(emptyId(EntityType.RULE_CHAIN), null,
null,
ActionType.UNASSIGNED_FROM_EDGE, e, strRuleChainId);
ActionType.UNASSIGNED_FROM_EDGE, e, strRuleChainId, strEdgeId);
throw handleException(e);
}

5
application/src/main/java/org/thingsboard/server/controller/UserController.java

@ -35,6 +35,7 @@ import org.thingsboard.rule.engine.api.MailService;
import org.thingsboard.server.common.data.EntityType;
import org.thingsboard.server.common.data.User;
import org.thingsboard.server.common.data.audit.ActionType;
import org.thingsboard.server.common.data.edge.EdgeEventActionType;
import org.thingsboard.server.common.data.exception.ThingsboardErrorCode;
import org.thingsboard.server.common.data.exception.ThingsboardException;
import org.thingsboard.server.common.data.id.CustomerId;
@ -167,7 +168,7 @@ public class UserController extends BaseController {
user.getId() == null ? ActionType.ADDED : ActionType.UPDATED, null);
sendNotificationMsgToEdgeService(getTenantId(), savedUser.getId(),
user.getId() == null ? ActionType.ADDED : ActionType.UPDATED);
user.getId() == null ? EdgeEventActionType.ADDED : EdgeEventActionType.UPDATED);
return savedUser;
} catch (Exception e) {
@ -244,7 +245,7 @@ public class UserController extends BaseController {
user.getCustomerId(),
ActionType.DELETED, null, strUserId);
sendNotificationMsgToEdgeService(getTenantId(), user.getId(), ActionType.DELETED);
sendNotificationMsgToEdgeService(getTenantId(), user.getId(), EdgeEventActionType.DELETED);
} catch (Exception e) {
logEntityAction(emptyId(EntityType.USER),

5
application/src/main/java/org/thingsboard/server/controller/WidgetTypeController.java

@ -27,6 +27,7 @@ import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.bind.annotation.RestController;
import org.thingsboard.server.common.data.audit.ActionType;
import org.thingsboard.server.common.data.edge.EdgeEventActionType;
import org.thingsboard.server.common.data.exception.ThingsboardException;
import org.thingsboard.server.common.data.id.TenantId;
import org.thingsboard.server.common.data.id.WidgetTypeId;
@ -73,7 +74,7 @@ public class WidgetTypeController extends BaseController {
WidgetType savedWidgetType = widgetTypeService.saveWidgetType(widgetType);
sendNotificationMsgToEdgeService(getTenantId(), savedWidgetType.getId(),
widgetType.getId() == null ? ActionType.ADDED : ActionType.UPDATED);
widgetType.getId() == null ? EdgeEventActionType.ADDED : EdgeEventActionType.UPDATED);
return checkNotNull(savedWidgetType);
} catch (Exception e) {
@ -91,7 +92,7 @@ public class WidgetTypeController extends BaseController {
checkWidgetTypeId(widgetTypeId, Operation.DELETE);
widgetTypeService.deleteWidgetType(getCurrentUser().getTenantId(), widgetTypeId);
sendNotificationMsgToEdgeService(getTenantId(), widgetTypeId, ActionType.DELETED);
sendNotificationMsgToEdgeService(getTenantId(), widgetTypeId, EdgeEventActionType.DELETED);
} catch (Exception e) {
throw handleException(e);

5
application/src/main/java/org/thingsboard/server/controller/WidgetsBundleController.java

@ -26,6 +26,7 @@ import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.bind.annotation.RestController;
import org.thingsboard.server.common.data.audit.ActionType;
import org.thingsboard.server.common.data.edge.EdgeEventActionType;
import org.thingsboard.server.common.data.exception.ThingsboardException;
import org.thingsboard.server.common.data.id.TenantId;
import org.thingsboard.server.common.data.id.WidgetsBundleId;
@ -72,7 +73,7 @@ public class WidgetsBundleController extends BaseController {
WidgetsBundle savedWidgetsBundle = widgetsBundleService.saveWidgetsBundle(widgetsBundle);
sendNotificationMsgToEdgeService(getTenantId(), savedWidgetsBundle.getId(),
widgetsBundle.getId() == null ? ActionType.ADDED : ActionType.UPDATED);
widgetsBundle.getId() == null ? EdgeEventActionType.ADDED : EdgeEventActionType.UPDATED);
return checkNotNull(savedWidgetsBundle);
} catch (Exception e) {
@ -90,7 +91,7 @@ public class WidgetsBundleController extends BaseController {
checkWidgetsBundleId(widgetsBundleId, Operation.DELETE);
widgetsBundleService.deleteWidgetsBundle(getTenantId(), widgetsBundleId);
sendNotificationMsgToEdgeService(getTenantId(), widgetsBundleId, ActionType.DELETED);
sendNotificationMsgToEdgeService(getTenantId(), widgetsBundleId, EdgeEventActionType.DELETED);
} catch (Exception e) {
throw handleException(e);

28
application/src/main/java/org/thingsboard/server/service/edge/DefaultEdgeNotificationService.java

@ -28,9 +28,9 @@ import org.springframework.stereotype.Service;
import org.thingsboard.server.common.data.EntityType;
import org.thingsboard.server.common.data.User;
import org.thingsboard.server.common.data.alarm.Alarm;
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.CustomerId;
@ -114,14 +114,14 @@ public class DefaultEdgeNotificationService implements EdgeNotificationService {
public Edge setEdgeRootRuleChain(TenantId tenantId, Edge edge, RuleChainId ruleChainId) throws IOException {
edge.setRootRuleChainId(ruleChainId);
Edge savedEdge = edgeService.saveEdge(edge);
saveEdgeEvent(tenantId, edge.getId(), EdgeEventType.RULE_CHAIN, ActionType.UPDATED, ruleChainId, null);
saveEdgeEvent(tenantId, edge.getId(), EdgeEventType.RULE_CHAIN, EdgeEventActionType.UPDATED, ruleChainId, null);
return savedEdge;
}
private void 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 [{}]",
@ -131,7 +131,7 @@ public class DefaultEdgeNotificationService implements EdgeNotificationService {
edgeEvent.setEdgeId(edgeId);
edgeEvent.setTenantId(tenantId);
edgeEvent.setType(type);
edgeEvent.setAction(action.name());
edgeEvent.setAction(action);
if (entityId != null) {
edgeEvent.setEntityId(entityId.getId());
}
@ -182,7 +182,7 @@ public class DefaultEdgeNotificationService implements EdgeNotificationService {
private void processEdge(TenantId tenantId, TransportProtos.EdgeNotificationMsgProto edgeNotificationMsg) {
try {
ActionType actionType = ActionType.valueOf(edgeNotificationMsg.getAction());
EdgeEventActionType actionType = EdgeEventActionType.valueOf(edgeNotificationMsg.getAction());
EdgeId edgeId = new EdgeId(new UUID(edgeNotificationMsg.getEdgeIdMSB(), edgeNotificationMsg.getEdgeIdLSB()));
ListenableFuture<Edge> 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<User> 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<Edge> 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));
}

22
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<EdgeId, EdgeGrpcSession> 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);
}

113
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<DownlinkMsg> 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<DownlinkMsg> convertToDownlinkMsgsPack(List<EdgeEvent> edgeEvents) {
List<DownlinkMsg> 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<Long> getQueueStartTs() {
ListenableFuture<Optional<AttributeKvEntry>> 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<AttributeKvEntry> 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<List<Void>> 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<Edge> 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();

4
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) {

6
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

4
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) {

4
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) {

5
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) {

35
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();
}

29
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;
}

4
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) {

4
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) {

2
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();

7
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) {

4
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) {

4
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) {

58
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<RuleChain> 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<Device> 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<Asset> 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<EntityView> 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<DashboardInfo> 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<User> 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<WidgetsBundle> widgetsBundlesToPush = new ArrayList<>();
List<WidgetType> 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<Void> processRuleChainMetadataRequestMsg(Edge edge, RuleChainMetadataRequestMsg ruleChainMetadataRequestMsg) {
log.trace("[{}] processRuleChainMetadataRequestMsg [{}][{}]", edge.getTenantId(), edge.getName(), ruleChainMetadataRequestMsg);
SettableFuture<Void> futureToSet = SettableFuture.create();
if (ruleChainMetadataRequestMsg.getRuleChainIdMSB() != 0 && ruleChainMetadataRequestMsg.getRuleChainIdLSB() != 0) {
RuleChainId ruleChainId =
new RuleChainId(new UUID(ruleChainMetadataRequestMsg.getRuleChainIdMSB(), ruleChainMetadataRequestMsg.getRuleChainIdLSB()));
ListenableFuture<EdgeEvent> future = saveEdgeEvent(edge.getTenantId(), edge.getId(), EdgeEventType.RULE_CHAIN_METADATA, ActionType.ADDED, ruleChainId, null);
ListenableFuture<EdgeEvent> future = saveEdgeEvent(edge.getTenantId(), edge.getId(), EdgeEventType.RULE_CHAIN_METADATA, EdgeEventActionType.ADDED, ruleChainId, null);
Futures.addCallback(future, new FutureCallback<EdgeEvent>() {
@Override
public void onSuccess(@Nullable EdgeEvent result) {
@ -358,6 +368,7 @@ public class DefaultSyncEdgeService implements SyncEdgeService {
@Override
public ListenableFuture<Void> 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<Void> 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<Void> processDeviceCredentialsRequestMsg(Edge edge, DeviceCredentialsRequestMsg deviceCredentialsRequestMsg) {
log.trace("[{}] processDeviceCredentialsRequestMsg [{}][{}]", edge.getTenantId(), edge.getName(), deviceCredentialsRequestMsg);
SettableFuture<Void> futureToSet = SettableFuture.create();
if (deviceCredentialsRequestMsg.getDeviceIdMSB() != 0 && deviceCredentialsRequestMsg.getDeviceIdLSB() != 0) {
DeviceId deviceId = new DeviceId(new UUID(deviceCredentialsRequestMsg.getDeviceIdMSB(), deviceCredentialsRequestMsg.getDeviceIdLSB()));
ListenableFuture<EdgeEvent> future = saveEdgeEvent(edge.getTenantId(), edge.getId(), EdgeEventType.DEVICE, ActionType.CREDENTIALS_UPDATED, deviceId, null);
ListenableFuture<EdgeEvent> future = saveEdgeEvent(edge.getTenantId(), edge.getId(), EdgeEventType.DEVICE, EdgeEventActionType.CREDENTIALS_UPDATED, deviceId, null);
Futures.addCallback(future, new FutureCallback<EdgeEvent>() {
@Override
public void onSuccess(@Nullable EdgeEvent result) {
@ -499,10 +512,11 @@ public class DefaultSyncEdgeService implements SyncEdgeService {
@Override
public ListenableFuture<Void> processUserCredentialsRequestMsg(Edge edge, UserCredentialsRequestMsg userCredentialsRequestMsg) {
log.trace("[{}] processUserCredentialsRequestMsg [{}][{}]", edge.getTenantId(), edge.getName(), userCredentialsRequestMsg);
SettableFuture<Void> futureToSet = SettableFuture.create();
if (userCredentialsRequestMsg.getUserIdMSB() != 0 && userCredentialsRequestMsg.getUserIdLSB() != 0) {
UserId userId = new UserId(new UUID(userCredentialsRequestMsg.getUserIdMSB(), userCredentialsRequestMsg.getUserIdLSB()));
ListenableFuture<EdgeEvent> future = saveEdgeEvent(edge.getTenantId(), edge.getId(), EdgeEventType.USER, ActionType.CREDENTIALS_UPDATED, userId, null);
ListenableFuture<EdgeEvent> future = saveEdgeEvent(edge.getTenantId(), edge.getId(), EdgeEventType.USER, EdgeEventActionType.CREDENTIALS_UPDATED, userId, null);
Futures.addCallback(future, new FutureCallback<EdgeEvent>() {
@Override
public void onSuccess(@Nullable EdgeEvent result) {
@ -522,17 +536,17 @@ public class DefaultSyncEdgeService implements SyncEdgeService {
private ListenableFuture<EdgeEvent> 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());
}

1
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<Void> onAlarmUpdate(TenantId tenantId, AlarmUpdateMsg alarmUpdateMsg) {
log.trace("[{}] onAlarmUpdate [{}]", tenantId, alarmUpdateMsg);
EntityId originatorId = getAlarmOriginator(tenantId, alarmUpdateMsg.getOriginatorName(),
EntityType.valueOf(alarmUpdateMsg.getOriginatorType()));
if (originatorId == null) {

7
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<EdgeEvent> 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());
}

47
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<Void> 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<Void> processDeviceRpcCallResponseMsg(TenantId tenantId, DeviceRpcCallMsg deviceRpcCallMsg) {
log.trace("[{}] processDeviceRpcCallResponseMsg [{}]", tenantId, deviceRpcCallMsg);
SettableFuture<Void> 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;
}

2
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<Void> onRelationUpdate(TenantId tenantId, RelationUpdateMsg relationUpdateMsg) {
log.info("onRelationUpdate {}", relationUpdateMsg);
log.trace("[{}] onRelationUpdate [{}]", tenantId, relationUpdateMsg);
try {
EntityRelation entityRelation = new EntityRelation();

1
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<ListenableFuture<Void>> onTelemetryUpdate(TenantId tenantId, EntityDataProto entityData) {
log.trace("[{}] onTelemetryUpdate [{}]", tenantId, entityData);
List<ListenableFuture<Void>> result = new ArrayList<>();
EntityId entityId = constructEntityId(entityData);
if ((entityData.hasPostAttributesMsg() || entityData.hasPostTelemetryMsg() || entityData.hasAttributesUpdatedMsg()) && entityId != null) {

1
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);

3
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);

3
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;

44
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;
}
}

10
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);
}

4
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;

2
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);
}
}
}

606
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<Device> edgeDevices = doGetTypedWithPageLink("/api/edge/" + edge.getId().getId().toString() + "/devices?",
new TypeReference<PageData<Device>>() {
}, new PageLink(100)).getData();
Optional<Device> 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<Asset> edgeAssets = doGetTypedWithPageLink("/api/edge/" + edge.getId().getId().toString() + "/assets?",
new TypeReference<PageData<Asset>>() {
}, 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<PageData<Asset>>() {}, new PageLink(100)).getData();
Assert.assertTrue(edgeAssets.contains(asset));
testAutoGeneratedCodeByProtobuf(assetUpdateMsg);
Optional<RuleChainUpdateMsg> 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<PageData<RuleChain>>() {}, 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<RuleNode> 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<Device> edgeDevices = doGetTypedWithPageLink("/api/edge/" + edge.getId().getId().toString() + "/devices?",
new TypeReference<PageData<Device>>() {}, new PageLink(100)).getData();
List<Asset> edgeAssets = doGetTypedWithPageLink("/api/edge/" + edge.getId().getId().toString() + "/assets?",
new TypeReference<PageData<Asset>>() {}, 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<Device> edgeDevices = doGetTypedWithPageLink("/api/edge/" + edge.getId().getId().toString() + "/devices?",
new TypeReference<PageData<Device>>() {}, 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<Device> edgeDevices = doGetTypedWithPageLink("/api/edge/" + edge.getId().getId().toString() + "/devices?",
new TypeReference<PageData<Device>>() {}, 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<Device> edgeDevices = doGetTypedWithPageLink("/api/edge/" + edge.getId().getId().toString() + "/devices?",
new TypeReference<PageData<Device>>() {}, 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<Device> edgeDevices = doGetTypedWithPageLink("/api/edge/" + edge.getId().getId().toString() + "/devices?",
new TypeReference<PageData<Device>>() {}, 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<Device> edgeDevices = doGetTypedWithPageLink("/api/edge/" + edge.getId().getId().toString() + "/devices?",
new TypeReference<PageData<Device>>() {}, new PageLink(100)).getData();
Optional<Device> 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<Device> edgeDevices = doGetTypedWithPageLink("/api/edge/" + edge.getId().getId().toString() + "/devices?",
new TypeReference<PageData<Device>>() {}, new PageLink(100)).getData();
Optional<Device> 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<Device> edgeDevices = doGetTypedWithPageLink("/api/edge/" + edge.getId().getId().toString() + "/devices?",
new TypeReference<PageData<Device>>() {}, new PageLink(100)).getData();
Optional<Device> 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<Device> edgeDevices = doGetTypedWithPageLink("/api/edge/" + edge.getId().getId().toString() + "/devices?",
new TypeReference<PageData<Device>>() {
}, 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<Device> pageDataDevices = doGetTypedWithPageLink("/api/edge/" + edge.getId().getId().toString() + "/devices?",
new TypeReference<PageData<Device>>() {}, new PageLink(100));
for (Device device: pageDataDevices.getData()) {
doDelete("/api/device/" + device.getId().getId().toString())
.andExpect(status().isOk());
}
PageData<Asset> pageDataAssets = doGetTypedWithPageLink("/api/edge/" + edge.getId().getId().toString() + "/assets?",
new TypeReference<PageData<Asset>>() {}, 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());
}
}

12
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);
}

5
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;

2
common/data/src/main/java/org/thingsboard/server/common/data/edge/EdgeEvent.java

@ -29,7 +29,7 @@ public class EdgeEvent extends BaseData<EdgeEventId> {
private TenantId tenantId;
private EdgeId edgeId;
private String action;
private EdgeEventActionType action;
private UUID entityId;
private String uid;
private EdgeEventType type;

38
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
}

11
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;
}

4
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,

2
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!");
}
}

11
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<List<Edge>> findEdgesByQuery(TenantId tenantId, EdgeSearchQuery query) {
log.trace("[{}] Executing findEdgesByQuery [{}]", tenantId, query);
ListenableFuture<List<EntityRelation>> relations = relationService.findByQuery(tenantId, query.toEntitySearchQuery());
ListenableFuture<List<Edge>> 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<List<EdgeId>> findRelatedEdgeIdsByEntityId(TenantId tenantId, EntityId entityId) {
log.trace("[{}] Executing findRelatedEdgeIdsByEntityId [{}]", tenantId, entityId);
if (EntityType.TENANT.equals(entityId.getEntityType())) {
PageData<Edge> 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();

4
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<EdgeEvent> 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)

1
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<RuleNode> getRuleChainNodes(TenantId tenantId, RuleChainId ruleChainId) {
Validator.validateId(ruleChainId, "Incorrect rule chain id for search request.");

1
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;

11
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<EdgeEvent> 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();
}

2
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;
DROP FUNCTION IF EXISTS to_uuid;

2
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;
DROP TABLE IF EXISTS api_usage_state;

2
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;
DROP TABLE IF EXISTS api_usage_state;

37
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;
}
}

45
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<String, Object> entityBody = new HashMap<>();
Map<String, String> 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<String> 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<String, String> 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;
}

67
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<EntityRelation> 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<EdgeEvent> saveFuture = ctx.getEdgeEventService().saveAsync(edgeEvent);
Futures.addCallback(saveFuture, new FutureCallback<EdgeEvent>() {
@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() {
}

2
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;

15
ui/src/app/edge/edge-fieldset.tpl.html

@ -48,6 +48,20 @@
<md-icon md-svg-icon="mdi:clipboard-arrow-left"></md-icon>
<span translate>edge.copy-id</span>
</md-button>
<md-button ngclipboard data-clipboard-action="copy"
ngclipboard-success="onEdgeInfoCopied('key')"
data-clipboard-text="{{edge.routingKey}}" ng-show="!isEdit"
class="md-raised">
<md-icon md-svg-icon="mdi:clipboard-arrow-left"></md-icon>
<span translate>edge.copy-edge-key</span>
</md-button>
<md-button ngclipboard data-clipboard-action="copy"
ngclipboard-success="onEdgeInfoCopied('secret')"
data-clipboard-text="{{edge.secret}}" ng-show="!isEdit"
class="md-raised">
<md-icon md-svg-icon="mdi:clipboard-arrow-left"></md-icon>
<span translate>edge.copy-edge-secret</span>
</md-button>
<md-button ng-click="onEdgeSync(edge.id)"
ng-show="!isEdit"
class="md-raised">
@ -105,6 +119,7 @@
</md-input-container>
</fieldset>
<div layout="row">
<md-input-container class="md-block" flex>
<label translate>edge.edge-key</label>
<input ng-model="edge.routingKey" disabled>

9
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",

4
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"}'
}
});
}

2
ui/src/app/event/event-row-edge-event.tpl.html

@ -19,7 +19,7 @@
<div class="tb-cell" flex="20">{{ event.type }}</div>
<div class="tb-cell" flex="40">{{ event.action }}</div>
<div class="tb-cell" flex="20">{{ event.entityId }}</div>
<div class="tb-cell" flex="15" ng-style="isPending ? {'color': 'rgba(0, 0, 0, .38)'} : {'color': '#000'}">{{ updateStatus(event.createdTime) | translate }}</div>
<div class="tb-cell" flex="15" ng-style="{'color': statusColor}">{{ updateStatus(event.createdTime) }}</div>
<div class="tb-cell" flex="10">
<md-button ng-if="checkEdgeEventType(event.type)" class="md-icon-button md-primary"
ng-click="showEdgeEntityContent($event, 'edge.entity-info', 'JSON')"

Loading…
Cancel
Save