Commit cd2908fb59ec4628429adae6684809d3f40d9de1

Authored by Volodymyr Babak
1 parent 600c9ec5

Refactoring notification engine

Showing 110 changed files with 1332 additions and 324 deletions
... ... @@ -58,6 +58,7 @@ import org.thingsboard.server.dao.customer.CustomerService;
58 58 import org.thingsboard.server.dao.dashboard.DashboardService;
59 59 import org.thingsboard.server.dao.device.ClaimDevicesService;
60 60 import org.thingsboard.server.dao.device.DeviceService;
  61 +import org.thingsboard.server.dao.edge.EdgeEventService;
61 62 import org.thingsboard.server.dao.edge.EdgeService;
62 63 import org.thingsboard.server.dao.entityview.EntityViewService;
63 64 import org.thingsboard.server.dao.event.EventService;
... ... @@ -258,6 +259,11 @@ public class ActorSystemContext {
258 259 @Getter
259 260 private EdgeService edgeService;
260 261
  262 + @Lazy
  263 + @Autowired
  264 + @Getter
  265 + private EdgeEventService edgeEventService;
  266 +
261 267 @Value("${actors.session.max_concurrent_sessions_per_device:1}")
262 268 @Getter
263 269 private long maxConcurrentSessionsPerDevice;
... ...
... ... @@ -51,6 +51,7 @@ import org.thingsboard.server.dao.cassandra.CassandraCluster;
51 51 import org.thingsboard.server.dao.customer.CustomerService;
52 52 import org.thingsboard.server.dao.dashboard.DashboardService;
53 53 import org.thingsboard.server.dao.device.DeviceService;
  54 +import org.thingsboard.server.dao.edge.EdgeEventService;
54 55 import org.thingsboard.server.dao.edge.EdgeService;
55 56 import org.thingsboard.server.dao.entityview.EntityViewService;
56 57 import org.thingsboard.server.dao.nosql.CassandraStatementTask;
... ... @@ -407,6 +408,11 @@ class DefaultTbContext implements TbContext {
407 408 }
408 409
409 410 @Override
  411 + public EdgeEventService getEdgeEventService() {
  412 + return mainCtx.getEdgeEventService();
  413 + }
  414 +
  415 + @Override
410 416 public EventLoopGroup getSharedEventLoop() {
411 417 return mainCtx.getSharedEventLoopGroupService().getSharedEventLoopGroup();
412 418 }
... ...
... ... @@ -18,14 +18,11 @@ package org.thingsboard.server.actors.ruleChain;
18 18 import akka.actor.ActorContext;
19 19 import akka.actor.ActorRef;
20 20 import akka.actor.Props;
21   -import com.google.common.util.concurrent.FutureCallback;
22   -import com.sun.istack.Nullable;
23 21 import lombok.extern.slf4j.Slf4j;
24 22 import org.thingsboard.rule.engine.api.TbRelationTypes;
25 23 import org.thingsboard.server.actors.ActorSystemContext;
26 24 import org.thingsboard.server.actors.service.DefaultActorService;
27 25 import org.thingsboard.server.actors.shared.ComponentMsgProcessor;
28   -import org.thingsboard.server.common.data.DataConstants;
29 26 import org.thingsboard.server.common.data.EntityType;
30 27 import org.thingsboard.server.common.data.id.EntityId;
31 28 import org.thingsboard.server.common.data.id.RuleChainId;
... ... @@ -102,7 +99,7 @@ public class RuleChainActorMessageProcessor extends ComponentMsgProcessor<RuleCh
102 99 if (!started) {
103 100 RuleChain ruleChain = service.findRuleChainById(tenantId, entityId);
104 101 if (ruleChain != null) {
105   - if (ruleChain.getType().equals(RuleChainType.SYSTEM)) {
  102 + if (ruleChain.getType().equals(RuleChainType.CORE)) {
106 103 List<RuleNode> ruleNodeList = service.getRuleChainNodes(tenantId, entityId);
107 104 log.trace("[{}][{}] Starting rule chain with {} nodes", tenantId, entityId, ruleNodeList.size());
108 105 // Creating and starting the actors;
... ... @@ -124,7 +121,7 @@ public class RuleChainActorMessageProcessor extends ComponentMsgProcessor<RuleCh
124 121 public void onUpdate(ActorContext context) {
125 122 RuleChain ruleChain = service.findRuleChainById(tenantId, entityId);
126 123 if (ruleChain != null) {
127   - if (ruleChain.getType().equals(RuleChainType.SYSTEM)) {
  124 + if (ruleChain.getType().equals(RuleChainType.CORE)) {
128 125 ruleChainName = ruleChain.getName();
129 126 List<RuleNode> ruleNodeList = service.getRuleChainNodes(tenantId, entityId);
130 127 log.trace("[{}][{}] Updating rule chain with {} nodes", tenantId, entityId, ruleNodeList.size());
... ... @@ -224,7 +221,6 @@ public class RuleChainActorMessageProcessor extends ComponentMsgProcessor<RuleCh
224 221 if (targetCtx != null) {
225 222 log.trace("[{}][{}] Pushing message to target rule node", entityId, targetId);
226 223 pushMsgToNode(targetCtx, msg, "");
227   - pushUpdatesToEdges(msg);
228 224 } else {
229 225 log.trace("[{}][{}] Rule node does not exist. Probably old message", entityId, targetId);
230 226 msg.getCallback().onSuccess();
... ... @@ -354,30 +350,6 @@ public class RuleChainActorMessageProcessor extends ComponentMsgProcessor<RuleCh
354 350 }
355 351 }
356 352
357   - private void pushUpdatesToEdges(TbMsg msg) {
358   - switch (msg.getType()) {
359   - case DataConstants.ENTITY_CREATED:
360   - case DataConstants.ENTITY_UPDATED:
361   - case DataConstants.ENTITY_DELETED:
362   - case DataConstants.ENTITY_ASSIGNED_TO_EDGE:
363   - case DataConstants.ENTITY_UNASSIGNED_FROM_EDGE:
364   - case DataConstants.ALARM_ACK:
365   - case DataConstants.ALARM_CLEAR:
366   - edgeService.pushEventToEdge(tenantId, msg, new FutureCallback<Void>() {
367   - @Override
368   - public void onSuccess(@Nullable Void aVoid) {
369   - log.debug("Event saved successfully!");
370   - }
371   -
372   - @Override
373   - public void onFailure(Throwable t) {
374   - log.debug("Failure during event save", t);
375   - }
376   - });
377   - }
378   -
379   - }
380   -
381 353 @Override
382 354 protected RuleNodeException getInactiveException() {
383 355 RuleNode firstRuleNode = firstNode != null ? firstNode.getSelf() : null;
... ...
... ... @@ -56,7 +56,7 @@ public abstract class RuleChainManagerActor extends ContextAwareActor {
56 56 }
57 57
58 58 protected void initRuleChains() {
59   - for (RuleChain ruleChain : new PageDataIterable<>(link -> ruleChainService.findTenantRuleChainsByType(tenantId, RuleChainType.SYSTEM, link), ContextAwareActor.ENTITY_PACK_LIMIT)) {
  59 + for (RuleChain ruleChain : new PageDataIterable<>(link -> ruleChainService.findTenantRuleChainsByType(tenantId, RuleChainType.CORE, link), ContextAwareActor.ENTITY_PACK_LIMIT)) {
60 60 RuleChainId ruleChainId = ruleChain.getId();
61 61 log.debug("[{}|{}] Creating rule chain actor", ruleChainId.getEntityType(), ruleChain.getId());
62 62 //TODO: remove this cast making UUIDBased subclass of EntityId an interface and vice versa.
... ... @@ -67,7 +67,7 @@ public abstract class RuleChainManagerActor extends ContextAwareActor {
67 67 }
68 68
69 69 protected void visit(RuleChain entity, ActorRef actorRef) {
70   - if (entity != null && entity.isRoot() && entity.getType().equals(RuleChainType.SYSTEM)) {
  70 + if (entity != null && entity.isRoot() && entity.getType().equals(RuleChainType.CORE)) {
71 71 rootChain = entity;
72 72 rootChainActor = actorRef;
73 73 }
... ...
... ... @@ -206,7 +206,7 @@ public class TenantActor extends RuleChainManagerActor {
206 206 if (msg.getEntityId().getEntityType() == EntityType.RULE_CHAIN) {
207 207 RuleChain ruleChain = systemContext.getRuleChainService().
208 208 findRuleChainById(tenantId, new RuleChainId(msg.getEntityId().getId()));
209   - if (ruleChain != null && ruleChain.getType().equals(RuleChainType.SYSTEM)) {
  209 + if (ruleChain != null && ruleChain.getType().equals(RuleChainType.CORE)) {
210 210 visit(ruleChain, target);
211 211 }
212 212 }
... ...
... ... @@ -125,6 +125,8 @@ public class AlarmController extends BaseController {
125 125 alarmService.ackAlarm(getCurrentUser().getTenantId(), alarmId, ackTs).get();
126 126 alarm.setAckTs(ackTs);
127 127 logEntityAction(alarmId, alarm, getCurrentUser().getCustomerId(), ActionType.ALARM_ACK, null);
  128 +
  129 + sendNotificationMsgToEdgeService(getTenantId(), alarmId, ActionType.ALARM_ACK);
128 130 } catch (Exception e) {
129 131 throw handleException(e);
130 132 }
... ... @@ -142,6 +144,8 @@ public class AlarmController extends BaseController {
142 144 alarmService.clearAlarm(getCurrentUser().getTenantId(), alarmId, null, clearTs).get();
143 145 alarm.setClearTs(clearTs);
144 146 logEntityAction(alarmId, alarm, getCurrentUser().getCustomerId(), ActionType.ALARM_CLEAR, null);
  147 +
  148 + sendNotificationMsgToEdgeService(getTenantId(), alarmId, ActionType.ALARM_CLEAR);
145 149 } catch (Exception e) {
146 150 throw handleException(e);
147 151 }
... ...
... ... @@ -27,12 +27,14 @@ import org.springframework.web.bind.annotation.ResponseBody;
27 27 import org.springframework.web.bind.annotation.ResponseStatus;
28 28 import org.springframework.web.bind.annotation.RestController;
29 29 import org.thingsboard.server.common.data.Customer;
  30 +import org.thingsboard.server.common.data.DataConstants;
30 31 import org.thingsboard.server.common.data.EntitySubtype;
31 32 import org.thingsboard.server.common.data.EntityType;
32 33 import org.thingsboard.server.common.data.asset.Asset;
33 34 import org.thingsboard.server.common.data.asset.AssetSearchQuery;
34 35 import org.thingsboard.server.common.data.audit.ActionType;
35 36 import org.thingsboard.server.common.data.edge.Edge;
  37 +import org.thingsboard.server.common.data.edge.EdgeEventType;
36 38 import org.thingsboard.server.common.data.exception.ThingsboardException;
37 39 import org.thingsboard.server.common.data.id.AssetId;
38 40 import org.thingsboard.server.common.data.id.CustomerId;
... ... @@ -86,6 +88,8 @@ public class AssetController extends BaseController {
86 88
87 89 Asset savedAsset = checkNotNull(assetService.saveAsset(asset));
88 90
  91 + sendNotificationMsgToEdgeService(savedAsset.getTenantId(), savedAsset.getId(), EdgeEventType.ASSET, asset.getId() == null ? ActionType.ADDED : ActionType.UPDATED);
  92 +
89 93 logEntityAction(savedAsset.getId(), savedAsset,
90 94 savedAsset.getCustomerId(),
91 95 asset.getId() == null ? ActionType.ADDED : ActionType.UPDATED, null);
... ... @@ -112,6 +116,7 @@ public class AssetController extends BaseController {
112 116 asset.getCustomerId(),
113 117 ActionType.DELETED, null, strAssetId);
114 118
  119 + sendNotificationMsgToEdgeService(getTenantId(), assetId, EdgeEventType.ASSET, ActionType.DELETED);
115 120 } catch (Exception e) {
116 121 logEntityAction(emptyId(EntityType.ASSET),
117 122 null,
... ... @@ -354,6 +359,8 @@ public class AssetController extends BaseController {
354 359 savedAsset.getCustomerId(),
355 360 ActionType.ASSIGNED_TO_EDGE, null, strAssetId, strEdgeId, edge.getName());
356 361
  362 + sendNotificationMsgToEdgeService(getTenantId(), savedAsset.getId(), EdgeEventType.ASSET, ActionType.ASSIGNED_TO_EDGE);
  363 +
357 364 return savedAsset;
358 365 } catch (Exception e) {
359 366
... ... @@ -385,6 +392,8 @@ public class AssetController extends BaseController {
385 392 asset.getCustomerId(),
386 393 ActionType.UNASSIGNED_FROM_EDGE, null, strAssetId, edge.getId().toString(), edge.getName());
387 394
  395 + sendNotificationMsgToEdgeService(getTenantId(), savedAsset.getId(), EdgeEventType.ASSET, ActionType.UNASSIGNED_FROM_EDGE);
  396 +
388 397 return savedAsset;
389 398 } catch (Exception e) {
390 399
... ...
... ... @@ -39,6 +39,7 @@ import org.thingsboard.server.common.data.HasTenantId;
39 39 import org.thingsboard.server.common.data.Tenant;
40 40 import org.thingsboard.server.common.data.User;
41 41 import org.thingsboard.server.common.data.alarm.Alarm;
  42 +import org.thingsboard.server.common.data.edge.EdgeEventType;
42 43 import org.thingsboard.server.common.data.id.AlarmId;
43 44 import org.thingsboard.server.common.data.alarm.AlarmInfo;
44 45 import org.thingsboard.server.common.data.asset.Asset;
... ... @@ -66,6 +67,7 @@ import org.thingsboard.server.common.data.page.TextPageLink;
66 67 import org.thingsboard.server.common.data.page.TimePageLink;
67 68 import org.thingsboard.server.common.data.plugin.ComponentDescriptor;
68 69 import org.thingsboard.server.common.data.plugin.ComponentType;
  70 +import org.thingsboard.server.common.data.relation.EntityRelation;
69 71 import org.thingsboard.server.common.data.rule.RuleChain;
70 72 import org.thingsboard.server.common.data.rule.RuleChainType;
71 73 import org.thingsboard.server.common.data.rule.RuleNode;
... ... @@ -83,6 +85,7 @@ import org.thingsboard.server.dao.dashboard.DashboardService;
83 85 import org.thingsboard.server.dao.device.ClaimDevicesService;
84 86 import org.thingsboard.server.dao.device.DeviceCredentialsService;
85 87 import org.thingsboard.server.dao.device.DeviceService;
  88 +import org.thingsboard.server.dao.edge.EdgeEventService;
86 89 import org.thingsboard.server.dao.edge.EdgeService;
87 90 import org.thingsboard.server.dao.entityview.EntityViewService;
88 91 import org.thingsboard.server.dao.exception.DataValidationException;
... ... @@ -95,10 +98,12 @@ import org.thingsboard.server.dao.user.UserService;
95 98 import org.thingsboard.server.dao.widget.WidgetTypeService;
96 99 import org.thingsboard.server.dao.widget.WidgetsBundleService;
97 100 import org.thingsboard.server.exception.ThingsboardErrorResponseHandler;
  101 +import org.thingsboard.server.gen.transport.TransportProtos;
98 102 import org.thingsboard.server.queue.discovery.PartitionService;
99 103 import org.thingsboard.server.queue.provider.TbQueueProducerProvider;
100 104 import org.thingsboard.server.queue.util.TbCoreComponent;
101 105 import org.thingsboard.server.service.component.ComponentDiscoveryService;
  106 +import org.thingsboard.server.service.edge.EdgeNotificationService;
102 107 import org.thingsboard.server.service.queue.TbClusterService;
103 108 import org.thingsboard.server.service.security.model.SecurityUser;
104 109 import org.thingsboard.server.service.security.permission.AccessControlService;
... ... @@ -108,6 +113,7 @@ import org.thingsboard.server.service.state.DeviceStateService;
108 113 import org.thingsboard.server.service.telemetry.TelemetrySubscriptionService;
109 114
110 115 import javax.mail.MessagingException;
  116 +import javax.management.relation.Relation;
111 117 import javax.servlet.http.HttpServletResponse;
112 118 import java.util.List;
113 119 import java.util.Optional;
... ... @@ -200,6 +206,12 @@ public abstract class BaseController {
200 206 @Autowired
201 207 protected EdgeService edgeService;
202 208
  209 + @Autowired
  210 + protected EdgeNotificationService edgeNotificationService;
  211 +
  212 + @Autowired
  213 + protected EdgeEventService edgeEventService;
  214 +
203 215 @Value("${server.log_controller_error_stack_trace}")
204 216 @Getter
205 217 private boolean logControllerErrorStackTrace;
... ... @@ -559,7 +571,6 @@ public abstract class BaseController {
559 571 }
560 572 if (e == null) {
561 573 pushEntityActionToRuleEngine(entityId, entity, user, customerId, actionType, additionalInfo);
562   - // TODO: voba - refactor to push events to edge queue directly, instead of the rule engine flow
563 574 }
564 575 auditLogService.logEntityAction(user.getTenantId(), customerId, user.getId(), user.getName(), entityId, entity, actionType, e, additionalInfo);
565 576 }
... ... @@ -600,16 +611,6 @@ public abstract class BaseController {
600 611 case ALARM_CLEAR:
601 612 msgType = DataConstants.ALARM_CLEAR;
602 613 break;
603   - case ASSIGNED_TO_EDGE:
604   - msgType = DataConstants.ENTITY_ASSIGNED_TO_EDGE;
605   - break;
606   - case UNASSIGNED_FROM_EDGE:
607   - msgType = DataConstants.ENTITY_UNASSIGNED_FROM_EDGE;
608   - break;
609   - case CREDENTIALS_UPDATED:
610   - //TODO: voba - this is not efficient way to do this. Refactor on later stages
611   - msgType = DataConstants.ENTITY_UPDATED;
612   - break;
613 614 }
614 615 if (!StringUtils.isEmpty(msgType)) {
615 616 try {
... ... @@ -698,5 +699,42 @@ public abstract class BaseController {
698 699 return result;
699 700 }
700 701
  702 + protected void sendNotificationMsgToEdgeService(TenantId tenantId, EntityRelation relation, ActionType edgeEventAction) {
  703 + try {
  704 + sendNotificationMsgToEdgeService(tenantId, null, json.writeValueAsString(relation), EdgeEventType.RELATION, edgeEventAction);
  705 + } catch (Exception e) {
  706 + log.warn("Failed to push relation to core: {}", relation, e);
  707 + }
  708 + }
  709 +
  710 + protected void sendNotificationMsgToEdgeService(TenantId tenantId, EntityId entityId, ActionType edgeEventAction) {
  711 + EdgeEventType edgeEventType = edgeEventService.getEdgeEventTypeByEntityType(entityId.getEntityType());
  712 + if (edgeEventType != null) {
  713 + sendNotificationMsgToEdgeService(tenantId, entityId, null, edgeEventType, edgeEventAction);
  714 + }
  715 + }
  716 +
  717 + protected void sendNotificationMsgToEdgeService(TenantId tenantId, EntityId entityId, EdgeEventType edgeEventType, ActionType edgeEventAction) {
  718 + sendNotificationMsgToEdgeService(tenantId, entityId, null, edgeEventType, edgeEventAction);
  719 + }
  720 +
  721 + private void sendNotificationMsgToEdgeService(TenantId tenantId, EntityId entityId, String entityBody, EdgeEventType edgeEventType, ActionType edgeEventAction) {
  722 + TransportProtos.EdgeNotificationMsgProto.Builder builder = TransportProtos.EdgeNotificationMsgProto.newBuilder();
  723 + builder.setTenantIdMSB(tenantId.getId().getMostSignificantBits());
  724 + builder.setTenantIdLSB(tenantId.getId().getLeastSignificantBits());
  725 + builder.setEdgeEventType(edgeEventType.name());
  726 + builder.setEdgeEventAction(edgeEventAction.name());
  727 + if (entityId != null) {
  728 + builder.setEntityIdMSB(entityId.getId().getMostSignificantBits());
  729 + builder.setEntityIdLSB(entityId.getId().getLeastSignificantBits());
  730 + builder.setEntityType(entityId.getEntityType().name());
  731 + }
  732 + if (entityBody != null) {
  733 + builder.setEntityBody(entityBody);
  734 + }
  735 + TransportProtos.EdgeNotificationMsgProto msg = builder.build();
  736 + tbClusterService.pushMsgToCore(tenantId, entityId != null ? entityId : tenantId,
  737 + TransportProtos.ToCoreMsg.newBuilder().setEdgeNotificationMsg(msg).build(), null);
  738 + }
701 739
702 740 }
... ...
... ... @@ -34,6 +34,7 @@ import org.thingsboard.server.common.data.ShortCustomerInfo;
34 34 import org.thingsboard.server.common.data.ShortEdgeInfo;
35 35 import org.thingsboard.server.common.data.audit.ActionType;
36 36 import org.thingsboard.server.common.data.edge.Edge;
  37 +import org.thingsboard.server.common.data.edge.EdgeEventType;
37 38 import org.thingsboard.server.common.data.exception.ThingsboardException;
38 39 import org.thingsboard.server.common.data.id.CustomerId;
39 40 import org.thingsboard.server.common.data.id.DashboardId;
... ... @@ -116,6 +117,9 @@ public class DashboardController extends BaseController {
116 117 null,
117 118 dashboard.getId() == null ? ActionType.ADDED : ActionType.UPDATED, null);
118 119
  120 + sendNotificationMsgToEdgeService(savedDashboard.getTenantId(), savedDashboard.getId(),
  121 + EdgeEventType.DASHBOARD, savedDashboard.getId() == null ? ActionType.ADDED : ActionType.UPDATED);
  122 +
119 123 return savedDashboard;
120 124 } catch (Exception e) {
121 125 logEntityAction(emptyId(EntityType.DASHBOARD), dashboard,
... ... @@ -139,6 +143,7 @@ public class DashboardController extends BaseController {
139 143 null,
140 144 ActionType.DELETED, null, strDashboardId);
141 145
  146 + sendNotificationMsgToEdgeService(getTenantId(), dashboardId, EdgeEventType.DASHBOARD, ActionType.DELETED);
142 147 } catch (Exception e) {
143 148
144 149 logEntityAction(emptyId(EntityType.DASHBOARD),
... ... @@ -495,6 +500,7 @@ public class DashboardController extends BaseController {
495 500 null,
496 501 ActionType.ASSIGNED_TO_EDGE, null, strDashboardId, strEdgeId, edge.getName());
497 502
  503 + sendNotificationMsgToEdgeService(getTenantId(), savedDashboard.getId(), EdgeEventType.DASHBOARD, ActionType.ASSIGNED_TO_EDGE);
498 504
499 505 return savedDashboard;
500 506 } catch (Exception e) {
... ... @@ -526,6 +532,8 @@ public class DashboardController extends BaseController {
526 532 null,
527 533 ActionType.UNASSIGNED_FROM_EDGE, null, strDashboardId, edge.getId().toString(), edge.getName());
528 534
  535 + sendNotificationMsgToEdgeService(getTenantId(), savedDashboard.getId(), EdgeEventType.DASHBOARD, ActionType.UNASSIGNED_FROM_EDGE);
  536 +
529 537 return savedDashboard;
530 538 } catch (Exception e) {
531 539
... ...
... ... @@ -42,6 +42,7 @@ import org.thingsboard.server.common.data.EntityType;
42 42 import org.thingsboard.server.common.data.audit.ActionType;
43 43 import org.thingsboard.server.common.data.device.DeviceSearchQuery;
44 44 import org.thingsboard.server.common.data.edge.Edge;
  45 +import org.thingsboard.server.common.data.edge.EdgeEventType;
45 46 import org.thingsboard.server.common.data.exception.ThingsboardException;
46 47 import org.thingsboard.server.common.data.id.CustomerId;
47 48 import org.thingsboard.server.common.data.id.DeviceId;
... ... @@ -57,6 +58,7 @@ import org.thingsboard.server.dao.device.claim.ClaimResponse;
57 58 import org.thingsboard.server.dao.device.claim.ClaimResult;
58 59 import org.thingsboard.server.dao.exception.IncorrectParameterException;
59 60 import org.thingsboard.server.dao.model.ModelConstants;
  61 +import org.thingsboard.server.gen.transport.TransportProtos;
60 62 import org.thingsboard.server.queue.util.TbCoreComponent;
61 63 import org.thingsboard.server.service.security.model.SecurityUser;
62 64 import org.thingsboard.server.service.security.permission.Operation;
... ... @@ -106,6 +108,8 @@ public class DeviceController extends BaseController {
106 108 tbClusterService.pushMsgToCore(new DeviceNameOrTypeUpdateMsg(savedDevice.getTenantId(),
107 109 savedDevice.getId(), savedDevice.getName(), savedDevice.getType()), null);
108 110
  111 + sendNotificationMsgToEdgeService(savedDevice.getTenantId(), savedDevice.getId(), EdgeEventType.DEVICE, device.getId() == null ? ActionType.ADDED : ActionType.UPDATED);
  112 +
109 113 logEntityAction(savedDevice.getId(), savedDevice,
110 114 savedDevice.getCustomerId(),
111 115 device.getId() == null ? ActionType.ADDED : ActionType.UPDATED, null);
... ... @@ -137,6 +141,8 @@ public class DeviceController extends BaseController {
137 141 device.getCustomerId(),
138 142 ActionType.DELETED, null, strDeviceId);
139 143
  144 + sendNotificationMsgToEdgeService(getTenantId(), deviceId, EdgeEventType.DEVICE, ActionType.DELETED);
  145 +
140 146 deviceStateService.onDeviceDeleted(device);
141 147 } catch (Exception e) {
142 148 logEntityAction(emptyId(EntityType.DEVICE),
... ... @@ -260,6 +266,8 @@ public class DeviceController extends BaseController {
260 266
261 267 tbClusterService.pushMsgToCore(new DeviceCredentialsUpdateNotificationMsg(getCurrentUser().getTenantId(), deviceCredentials.getDeviceId()), null);
262 268
  269 + sendNotificationMsgToEdgeService(getTenantId(), device.getId(), EdgeEventType.DEVICE, ActionType.CREDENTIALS_UPDATED);
  270 +
263 271 logEntityAction(device.getId(), device,
264 272 device.getCustomerId(),
265 273 ActionType.CREDENTIALS_UPDATED, null, deviceCredentials);
... ... @@ -509,6 +517,8 @@ public class DeviceController extends BaseController {
509 517 savedDevice.getCustomerId(),
510 518 ActionType.ASSIGNED_TO_EDGE, null, strDeviceId, strEdgeId, edge.getName());
511 519
  520 + sendNotificationMsgToEdgeService(getTenantId(), savedDevice.getId(), EdgeEventType.DEVICE, ActionType.ASSIGNED_TO_EDGE);
  521 +
512 522 return savedDevice;
513 523 } catch (Exception e) {
514 524 logEntityAction(emptyId(EntityType.DEVICE), null,
... ... @@ -538,6 +548,8 @@ public class DeviceController extends BaseController {
538 548 device.getCustomerId(),
539 549 ActionType.UNASSIGNED_FROM_EDGE, null, strDeviceId, edge.getId().toString(), edge.getName());
540 550
  551 + sendNotificationMsgToEdgeService(getTenantId(), savedDevice.getId(), EdgeEventType.DEVICE, ActionType.UNASSIGNED_FROM_EDGE);
  552 +
541 553 return savedDevice;
542 554 } catch (Exception e) {
543 555 logEntityAction(emptyId(EntityType.DEVICE), null,
... ...
... ... @@ -97,7 +97,7 @@ public class EdgeController extends BaseController {
97 97
98 98 if (created) {
99 99 ruleChainService.assignRuleChainToEdge(tenantId, defaultRootEdgeRuleChain.getId(), savedEdge.getId());
100   - edgeService.setEdgeRootRuleChain(tenantId, savedEdge, defaultRootEdgeRuleChain.getId());
  100 + edgeNotificationService.setEdgeRootRuleChain(tenantId, savedEdge, defaultRootEdgeRuleChain.getId());
101 101 edgeService.assignDefaultRuleChainsToEdge(tenantId, savedEdge.getId());
102 102 }
103 103
... ... @@ -257,8 +257,7 @@ public class EdgeController extends BaseController {
257 257 @PreAuthorize("hasAuthority('TENANT_ADMIN')")
258 258 @RequestMapping(value = "/tenant/edges", params = {"edgeName"}, method = RequestMethod.GET)
259 259 @ResponseBody
260   - public Edge getTenantEdge(
261   - @RequestParam String edgeName) throws ThingsboardException {
  260 + public Edge getTenantEdge(@RequestParam String edgeName) throws ThingsboardException {
262 261 try {
263 262 TenantId tenantId = getCurrentUser().getTenantId();
264 263 return checkNotNull(edgeService.findEdgeByTenantIdAndName(tenantId, edgeName));
... ... @@ -283,7 +282,7 @@ public class EdgeController extends BaseController {
283 282 accessControlService.checkPermission(getCurrentUser(), Resource.EDGE, Operation.WRITE,
284 283 edge.getId(), edge);
285 284
286   - Edge updatedEdge = edgeService.setEdgeRootRuleChain(getTenantId(), edge, ruleChainId);
  285 + Edge updatedEdge = edgeNotificationService.setEdgeRootRuleChain(getTenantId(), edge, ruleChainId);
287 286
288 287 logEntityAction(updatedEdge.getId(), updatedEdge, null, ActionType.UPDATED, null);
289 288
... ...
... ... @@ -24,7 +24,9 @@ import org.springframework.web.bind.annotation.RequestParam;
24 24 import org.springframework.web.bind.annotation.ResponseBody;
25 25 import org.springframework.web.bind.annotation.ResponseStatus;
26 26 import org.springframework.web.bind.annotation.RestController;
  27 +import org.thingsboard.server.common.data.DataConstants;
27 28 import org.thingsboard.server.common.data.audit.ActionType;
  29 +import org.thingsboard.server.common.data.edge.EdgeEventType;
28 30 import org.thingsboard.server.common.data.exception.ThingsboardErrorCode;
29 31 import org.thingsboard.server.common.data.exception.ThingsboardException;
30 32 import org.thingsboard.server.common.data.id.EntityId;
... ... @@ -63,10 +65,13 @@ public class EntityRelationController extends BaseController {
63 65 relation.setTypeGroup(RelationTypeGroup.COMMON);
64 66 }
65 67 relationService.saveRelation(getTenantId(), relation);
  68 +
66 69 logEntityAction(relation.getFrom(), null, getCurrentUser().getCustomerId(),
67 70 ActionType.RELATION_ADD_OR_UPDATE, null, relation);
68 71 logEntityAction(relation.getTo(), null, getCurrentUser().getCustomerId(),
69 72 ActionType.RELATION_ADD_OR_UPDATE, null, relation);
  73 +
  74 + sendNotificationMsgToEdgeService(getTenantId(), relation, ActionType.RELATION_ADD_OR_UPDATE);
70 75 } catch (Exception e) {
71 76 logEntityAction(relation.getFrom(), null, getCurrentUser().getCustomerId(),
72 77 ActionType.RELATION_ADD_OR_UPDATE, e, relation);
... ... @@ -104,6 +109,8 @@ public class EntityRelationController extends BaseController {
104 109 ActionType.RELATION_DELETED, null, relation);
105 110 logEntityAction(relation.getTo(), null, getCurrentUser().getCustomerId(),
106 111 ActionType.RELATION_DELETED, null, relation);
  112 +
  113 + sendNotificationMsgToEdgeService(getTenantId(), relation, ActionType.RELATION_DELETED);
107 114 } catch (Exception e) {
108 115 logEntityAction(relation.getFrom(), null, getCurrentUser().getCustomerId(),
109 116 ActionType.RELATION_DELETED, e, relation);
... ... @@ -125,6 +132,8 @@ public class EntityRelationController extends BaseController {
125 132 try {
126 133 relationService.deleteEntityRelations(getTenantId(), entityId);
127 134 logEntityAction(entityId, null, getCurrentUser().getCustomerId(), ActionType.RELATIONS_DELETED, null);
  135 +
  136 + sendNotificationMsgToEdgeService(getTenantId(), entityId, ActionType.RELATIONS_DELETED);
128 137 } catch (Exception e) {
129 138 logEntityAction(entityId, null, getCurrentUser().getCustomerId(), ActionType.RELATIONS_DELETED, e);
130 139 throw handleException(e);
... ...
... ... @@ -37,6 +37,7 @@ import org.thingsboard.server.common.data.EntityType;
37 37 import org.thingsboard.server.common.data.EntityView;
38 38 import org.thingsboard.server.common.data.audit.ActionType;
39 39 import org.thingsboard.server.common.data.edge.Edge;
  40 +import org.thingsboard.server.common.data.edge.EdgeEventType;
40 41 import org.thingsboard.server.common.data.entityview.EntityViewSearchQuery;
41 42 import org.thingsboard.server.common.data.exception.ThingsboardException;
42 43 import org.thingsboard.server.common.data.id.CustomerId;
... ... @@ -116,6 +117,8 @@ public class EntityViewController extends BaseController {
116 117
117 118 logEntityAction(savedEntityView.getId(), savedEntityView, null,
118 119 entityView.getId() == null ? ActionType.ADDED : ActionType.UPDATED, null);
  120 +
  121 + sendNotificationMsgToEdgeService(getTenantId(), savedEntityView.getId(), EdgeEventType.ENTITY_VIEW, entityView.getId() == null ? ActionType.ADDED : ActionType.UPDATED);
119 122 return savedEntityView;
120 123 } catch (Exception e) {
121 124 logEntityAction(emptyId(EntityType.ENTITY_VIEW), entityView, null,
... ... @@ -185,6 +188,8 @@ public class EntityViewController extends BaseController {
185 188 entityViewService.deleteEntityView(getTenantId(), entityViewId);
186 189 logEntityAction(entityViewId, entityView, entityView.getCustomerId(),
187 190 ActionType.DELETED, null, strEntityViewId);
  191 +
  192 + sendNotificationMsgToEdgeService(getTenantId(), entityViewId, EdgeEventType.ENTITY_VIEW, ActionType.DELETED);
188 193 } catch (Exception e) {
189 194 logEntityAction(emptyId(EntityType.ENTITY_VIEW),
190 195 null,
... ... @@ -389,6 +394,9 @@ public class EntityViewController extends BaseController {
389 394 logEntityAction(entityViewId, savedEntityView,
390 395 savedEntityView.getCustomerId(),
391 396 ActionType.ASSIGNED_TO_EDGE, null, strEntityViewId, strEdgeId, edge.getName());
  397 +
  398 + sendNotificationMsgToEdgeService(getTenantId(), savedEntityView.getId(), EdgeEventType.ENTITY_VIEW, ActionType.ASSIGNED_TO_EDGE);
  399 +
392 400 return savedEntityView;
393 401 } catch (Exception e) {
394 402 logEntityAction(emptyId(EntityType.ENTITY_VIEW), null,
... ... @@ -417,6 +425,8 @@ public class EntityViewController extends BaseController {
417 425 entityView.getCustomerId(),
418 426 ActionType.UNASSIGNED_FROM_EDGE, null, strEntityViewId, edge.getId().toString(), edge.getName());
419 427
  428 + sendNotificationMsgToEdgeService(getTenantId(), savedEntityView.getId(), EdgeEventType.ENTITY_VIEW, ActionType.UNASSIGNED_FROM_EDGE);
  429 +
420 430 return savedEntityView;
421 431 } catch (Exception e) {
422 432 logEntityAction(emptyId(EntityType.ENTITY_VIEW), null,
... ...
... ... @@ -41,6 +41,7 @@ import org.thingsboard.server.common.data.EntityType;
41 41 import org.thingsboard.server.common.data.Event;
42 42 import org.thingsboard.server.common.data.audit.ActionType;
43 43 import org.thingsboard.server.common.data.edge.Edge;
  44 +import org.thingsboard.server.common.data.edge.EdgeEventType;
44 45 import org.thingsboard.server.common.data.exception.ThingsboardException;
45 46 import org.thingsboard.server.common.data.id.EdgeId;
46 47 import org.thingsboard.server.common.data.id.RuleChainId;
... ... @@ -134,7 +135,7 @@ public class RuleChainController extends BaseController {
134 135
135 136 RuleChain savedRuleChain = checkNotNull(ruleChainService.saveRuleChain(ruleChain));
136 137
137   - if (RuleChainType.SYSTEM.equals(savedRuleChain.getType())) {
  138 + if (RuleChainType.CORE.equals(savedRuleChain.getType())) {
138 139 tbClusterService.onEntityStateChange(ruleChain.getTenantId(), savedRuleChain.getId(),
139 140 created ? ComponentLifecycleEvent.CREATED : ComponentLifecycleEvent.UPDATED);
140 141 }
... ... @@ -143,6 +144,12 @@ public class RuleChainController extends BaseController {
143 144 null,
144 145 created ? ActionType.ADDED : ActionType.UPDATED, null);
145 146
  147 + if (RuleChainType.EDGE.equals(savedRuleChain.getType())) {
  148 + sendNotificationMsgToEdgeService(savedRuleChain.getTenantId(),
  149 + savedRuleChain.getId(), EdgeEventType.RULE_CHAIN,
  150 + savedRuleChain.getId() == null ? ActionType.ADDED : ActionType.UPDATED);
  151 + }
  152 +
146 153 return savedRuleChain;
147 154 } catch (Exception e) {
148 155
... ... @@ -209,7 +216,7 @@ public class RuleChainController extends BaseController {
209 216 RuleChain ruleChain = checkRuleChain(ruleChainMetaData.getRuleChainId(), Operation.WRITE);
210 217 RuleChainMetaData savedRuleChainMetaData = checkNotNull(ruleChainService.saveRuleChainMetaData(tenantId, ruleChainMetaData));
211 218
212   - if (RuleChainType.SYSTEM.equals(ruleChain.getType())) {
  219 + if (RuleChainType.CORE.equals(ruleChain.getType())) {
213 220 tbClusterService.onEntityStateChange(ruleChain.getTenantId(), ruleChain.getId(), ComponentLifecycleEvent.UPDATED);
214 221 }
215 222
... ... @@ -217,6 +224,12 @@ public class RuleChainController extends BaseController {
217 224 null,
218 225 ActionType.UPDATED, null, ruleChainMetaData);
219 226
  227 + if (RuleChainType.EDGE.equals(ruleChain.getType())) {
  228 + sendNotificationMsgToEdgeService(ruleChain.getTenantId(),
  229 + ruleChain.getId(), EdgeEventType.RULE_CHAIN,
  230 + ActionType.UPDATED);
  231 + }
  232 +
220 233 return savedRuleChainMetaData;
221 234 } catch (Exception e) {
222 235
... ... @@ -243,7 +256,7 @@ public class RuleChainController extends BaseController {
243 256 RuleChainType type = RuleChainType.valueOf(typeStr);
244 257 return checkNotNull(ruleChainService.findTenantRuleChainsByType(tenantId, type, pageLink));
245 258 } else {
246   - return checkNotNull(ruleChainService.findTenantRuleChainsByType(tenantId, RuleChainType.SYSTEM, pageLink));
  259 + return checkNotNull(ruleChainService.findTenantRuleChainsByType(tenantId, RuleChainType.CORE, pageLink));
247 260 }
248 261 } catch (Exception e) {
249 262 throw handleException(e);
... ... @@ -267,7 +280,7 @@ public class RuleChainController extends BaseController {
267 280
268 281 referencingRuleChainIds.remove(ruleChain.getId());
269 282
270   - if (RuleChainType.SYSTEM.equals(ruleChain.getType())) {
  283 + if (RuleChainType.CORE.equals(ruleChain.getType())) {
271 284 referencingRuleChainIds.forEach(referencingRuleChainId ->
272 285 tbClusterService.onEntityStateChange(ruleChain.getTenantId(), referencingRuleChainId, ComponentLifecycleEvent.UPDATED));
273 286
... ... @@ -278,6 +291,12 @@ public class RuleChainController extends BaseController {
278 291 null,
279 292 ActionType.DELETED, null, strRuleChainId);
280 293
  294 + if (RuleChainType.EDGE.equals(ruleChain.getType())) {
  295 + sendNotificationMsgToEdgeService(ruleChain.getTenantId(),
  296 + ruleChain.getId(), EdgeEventType.RULE_CHAIN,
  297 + ActionType.DELETED);
  298 + }
  299 +
281 300 } catch (Exception e) {
282 301 logEntityAction(emptyId(EntityType.RULE_CHAIN),
283 302 null,
... ... @@ -407,6 +426,8 @@ public class RuleChainController extends BaseController {
407 426 null,
408 427 ActionType.ASSIGNED_TO_EDGE, null, strRuleChainId, strEdgeId, edge.getName());
409 428
  429 + sendNotificationMsgToEdgeService(getTenantId(), savedRuleChain.getId(),
  430 + EdgeEventType.RULE_CHAIN, ActionType.ASSIGNED_TO_EDGE);
410 431
411 432 return savedRuleChain;
412 433 } catch (Exception e) {
... ... @@ -438,6 +459,9 @@ public class RuleChainController extends BaseController {
438 459 null,
439 460 ActionType.UNASSIGNED_FROM_EDGE, null, strRuleChainId, edge.getId().toString(), edge.getName());
440 461
  462 + sendNotificationMsgToEdgeService(getTenantId(), savedRuleChain.getId(),
  463 + EdgeEventType.RULE_CHAIN, ActionType.UNASSIGNED_FROM_EDGE);
  464 +
441 465 return savedRuleChain;
442 466 } catch (Exception e) {
443 467
... ...
... ... @@ -116,7 +116,7 @@ public class AnnotationComponentDiscoveryService implements ComponentDiscoverySe
116 116 }
117 117
118 118 private void putComponentIntoMaps(ComponentType type, RuleNode ruleNodeAnnotation, ComponentDescriptor component) {
119   - if (ruleChainTypeContainsArray(RuleChainType.SYSTEM, ruleNodeAnnotation.ruleChainTypes())) {
  119 + if (ruleChainTypeContainsArray(RuleChainType.CORE, ruleNodeAnnotation.ruleChainTypes())) {
120 120 systemComponentsMap.computeIfAbsent(type, k -> new ArrayList<>()).add(component);
121 121 }
122 122 if (ruleChainTypeContainsArray(RuleChainType.EDGE, ruleNodeAnnotation.ruleChainTypes())) {
... ... @@ -225,7 +225,7 @@ public class AnnotationComponentDiscoveryService implements ComponentDiscoverySe
225 225
226 226 @Override
227 227 public List<ComponentDescriptor> getComponents(Set<ComponentType> types, RuleChainType ruleChainType) {
228   - if (RuleChainType.SYSTEM.equals(ruleChainType)) {
  228 + if (RuleChainType.CORE.equals(ruleChainType)) {
229 229 return getComponents(types, systemComponentsMap);
230 230 } else if (RuleChainType.EDGE.equals(ruleChainType)) {
231 231 return getComponents(types, edgeComponentsMap);
... ...
  1 +/**
  2 + * Copyright © 2016-2020 The Thingsboard Authors
  3 + *
  4 + * Licensed under the Apache License, Version 2.0 (the "License");
  5 + * you may not use this file except in compliance with the License.
  6 + * You may obtain a copy of the License at
  7 + *
  8 + * http://www.apache.org/licenses/LICENSE-2.0
  9 + *
  10 + * Unless required by applicable law or agreed to in writing, software
  11 + * distributed under the License is distributed on an "AS IS" BASIS,
  12 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13 + * See the License for the specific language governing permissions and
  14 + * limitations under the License.
  15 + */
1 16 package org.thingsboard.server.service.edge;
2 17
3 18 import com.fasterxml.jackson.databind.ObjectMapper;
... ... @@ -17,9 +32,10 @@ import org.thingsboard.server.common.data.EntityView;
17 32 import org.thingsboard.server.common.data.Event;
18 33 import org.thingsboard.server.common.data.alarm.Alarm;
19 34 import org.thingsboard.server.common.data.asset.Asset;
  35 +import org.thingsboard.server.common.data.audit.ActionType;
20 36 import org.thingsboard.server.common.data.edge.Edge;
21   -import org.thingsboard.server.common.data.edge.EdgeQueueEntityType;
22   -import org.thingsboard.server.common.data.edge.EdgeQueueEntry;
  37 +import org.thingsboard.server.common.data.edge.EdgeEvent;
  38 +import org.thingsboard.server.common.data.edge.EdgeEventType;
23 39 import org.thingsboard.server.common.data.id.EdgeId;
24 40 import org.thingsboard.server.common.data.id.EntityId;
25 41 import org.thingsboard.server.common.data.id.RuleChainId;
... ... @@ -36,6 +52,7 @@ import org.thingsboard.server.common.msg.queue.TbCallback;
36 52 import org.thingsboard.server.common.msg.session.SessionMsgType;
37 53 import org.thingsboard.server.dao.asset.AssetService;
38 54 import org.thingsboard.server.dao.device.DeviceService;
  55 +import org.thingsboard.server.dao.edge.EdgeEventService;
39 56 import org.thingsboard.server.dao.edge.EdgeService;
40 57 import org.thingsboard.server.dao.entityview.EntityViewService;
41 58 import org.thingsboard.server.dao.event.EventService;
... ... @@ -79,7 +96,7 @@ public class DefaultEdgeNotificationService implements EdgeNotificationService {
79 96 private RelationService relationService;
80 97
81 98 @Autowired
82   - private EventService eventService;
  99 + private EdgeEventService edgeEventService;
83 100
84 101 private ExecutorService tsCallBackExecutor;
85 102
... ... @@ -96,8 +113,8 @@ public class DefaultEdgeNotificationService implements EdgeNotificationService {
96 113 }
97 114
98 115 @Override
99   - public TimePageData<Event> findQueueEvents(TenantId tenantId, EdgeId edgeId, TimePageLink pageLink) {
100   - return eventService.findEvents(tenantId, edgeId, DataConstants.EDGE_QUEUE_EVENT_TYPE, pageLink);
  116 + public TimePageData<EdgeEvent> findEdgeEvents(TenantId tenantId, EdgeId edgeId, TimePageLink pageLink) {
  117 + return edgeEventService.findEdgeEvents(tenantId, edgeId, pageLink);
101 118 }
102 119
103 120 @Override
... ... @@ -105,7 +122,7 @@ public class DefaultEdgeNotificationService implements EdgeNotificationService {
105 122 edge.setRootRuleChainId(ruleChainId);
106 123 Edge savedEdge = edgeService.saveEdge(edge);
107 124 RuleChain ruleChain = ruleChainService.findRuleChainById(tenantId, ruleChainId);
108   - saveEventToEdgeQueue(tenantId, edge.getId(), EdgeQueueEntityType.RULE_CHAIN, DataConstants.ENTITY_UPDATED, mapper.writeValueAsString(ruleChain), new FutureCallback<Void>() {
  125 + saveEventToEdgeQueue(tenantId, edge.getId(), EdgeEventType.RULE_CHAIN, DataConstants.ENTITY_UPDATED, mapper.writeValueAsString(ruleChain), new FutureCallback<Void>() {
109 126 @Override
110 127 public void onSuccess(@Nullable Void aVoid) {
111 128 log.debug("Event saved successfully!");
... ... @@ -119,28 +136,28 @@ public class DefaultEdgeNotificationService implements EdgeNotificationService {
119 136 return savedEdge;
120 137 }
121 138
122   - private void saveEventToEdgeQueue(TenantId tenantId, EdgeId edgeId, EdgeQueueEntityType entityType, String type, String data, FutureCallback<Void> callback) throws IOException {
  139 + private void saveEventToEdgeQueue(TenantId tenantId, EdgeId edgeId, EdgeEventType entityType, String type, String data, FutureCallback<Void> callback) throws IOException {
123 140 log.debug("Pushing single event to edge queue. tenantId [{}], edgeId [{}], entityType [{}], type[{}], data [{}]", tenantId, edgeId, entityType, type, data);
124 141
125   - EdgeQueueEntry queueEntry = new EdgeQueueEntry();
126   - queueEntry.setEntityType(entityType);
127   - queueEntry.setType(type);
128   - queueEntry.setData(data);
  142 +// EdgeEQueueEntry queueEntry = new EdgeQueueEntry();
  143 +// queueEntry.setEntityType(entityType);
  144 +// queueEntry.setType(type);
  145 +// queueEntry.setData(data);
129 146
130   - Event event = new Event();
131   - event.setEntityId(edgeId);
132   - event.setTenantId(tenantId);
133   - event.setType(DataConstants.EDGE_QUEUE_EVENT_TYPE);
134   - event.setBody(mapper.valueToTree(queueEntry));
135   - ListenableFuture<Event> saveFuture = eventService.saveAsync(event);
  147 + EdgeEvent edgeEvent = new EdgeEvent();
  148 + edgeEvent.setEdgeId(edgeId);
  149 + edgeEvent.setTenantId(tenantId);
  150 +// event.setType(DataConstants.EDGE_QUEUE_EVENT_TYPE);
  151 +// event.setBody(mapper.valueToTree(queueEntry));
  152 + ListenableFuture<EdgeEvent> saveFuture = edgeEventService.saveAsync(edgeEvent);
136 153
137 154 addMainCallback(saveFuture, callback);
138 155 }
139 156
140   - private void addMainCallback(ListenableFuture<Event> saveFuture, final FutureCallback<Void> callback) {
141   - Futures.addCallback(saveFuture, new FutureCallback<Event>() {
  157 + private void addMainCallback(ListenableFuture<EdgeEvent> saveFuture, final FutureCallback<Void> callback) {
  158 + Futures.addCallback(saveFuture, new FutureCallback<EdgeEvent>() {
142 159 @Override
143   - public void onSuccess(@Nullable Event result) {
  160 + public void onSuccess(@Nullable EdgeEvent result) {
144 161 callback.onSuccess(null);
145 162 }
146 163
... ... @@ -153,52 +170,52 @@ public class DefaultEdgeNotificationService implements EdgeNotificationService {
153 170
154 171 @Override
155 172 public void pushNotificationToEdge(TransportProtos.EdgeNotificationMsgProto edgeNotificationMsg, TbCallback callback) {
156   - if (tbMsg.getType().equals(SessionMsgType.POST_TELEMETRY_REQUEST.name()) ||
157   - tbMsg.getType().equals(SessionMsgType.POST_ATTRIBUTES_REQUEST.name()) ||
158   - tbMsg.getType().equals(DataConstants.ATTRIBUTES_UPDATED) ||
159   - tbMsg.getType().equals(DataConstants.ATTRIBUTES_DELETED)) {
160   - processCustomTbMsg(tenantId, tbMsg, callback);
161   - } else {
162   - try {
163   - switch (tbMsg.getOriginator().getEntityType()) {
164   - case EDGE:
165   - processEdge(tenantId, tbMsg, callback);
166   - break;
167   - case ASSET:
168   - processAsset(tenantId, tbMsg, callback);
169   - break;
170   - case DEVICE:
171   - processDevice(tenantId, tbMsg, callback);
172   - break;
173   - case DASHBOARD:
174   - processDashboard(tenantId, tbMsg, callback);
175   - break;
176   - case RULE_CHAIN:
177   - processRuleChain(tenantId, tbMsg, callback);
178   - break;
179   - case ENTITY_VIEW:
180   - processEntityView(tenantId, tbMsg, callback);
181   - break;
182   - case ALARM:
183   - processAlarm(tenantId, tbMsg, callback);
184   - break;
185   - default:
186   - log.debug("Entity type [{}] is not designed to be pushed to edge", tbMsg.getOriginator().getEntityType());
187   - }
188   - } catch (IOException e) {
189   - log.error("Can't push to edge updates, entity type [{}], data [{}]", tbMsg.getOriginator().getEntityType(), tbMsg.getData(), e);
190   - }
191   - }
  173 +// if (tbMsg.getType().equals(SessionMsgType.POST_TELEMETRY_REQUEST.name()) ||
  174 +// tbMsg.getType().equals(SessionMsgType.POST_ATTRIBUTES_REQUEST.name()) ||
  175 +// tbMsg.getType().equals(DataConstants.ATTRIBUTES_UPDATED) ||
  176 +// tbMsg.getType().equals(DataConstants.ATTRIBUTES_DELETED)) {
  177 +// processCustomTbMsg(tenantId, tbMsg, callback);
  178 +// } else {
  179 +// try {
  180 +// switch (tbMsg.getOriginator().getEntityType()) {
  181 +// case EDGE:
  182 +// processEdge(tenantId, tbMsg, callback);
  183 +// break;
  184 +// case ASSET:
  185 +// processAsset(tenantId, tbMsg, callback);
  186 +// break;
  187 +// case DEVICE:
  188 +// processDevice(tenantId, tbMsg, callback);
  189 +// break;
  190 +// case DASHBOARD:
  191 +// processDashboard(tenantId, tbMsg, callback);
  192 +// break;
  193 +// case RULE_CHAIN:
  194 +// processRuleChain(tenantId, tbMsg, callback);
  195 +// break;
  196 +// case ENTITY_VIEW:
  197 +// processEntityView(tenantId, tbMsg, callback);
  198 +// break;
  199 +// case ALARM:
  200 +// processAlarm(tenantId, tbMsg, callback);
  201 +// break;
  202 +// default:
  203 +// log.debug("Entity type [{}] is not designed to be pushed to edge", tbMsg.getOriginator().getEntityType());
  204 +// }
  205 +// } catch (IOException e) {
  206 +// log.error("Can't push to edge updates, entity type [{}], data [{}]", tbMsg.getOriginator().getEntityType(), tbMsg.getData(), e);
  207 +// }
  208 +// }
192 209 }
193 210
194 211
195 212 private void processCustomTbMsg(TenantId tenantId, TbMsg tbMsg, FutureCallback<Void> callback) {
196 213 ListenableFuture<EdgeId> edgeIdFuture = getEdgeIdByOriginatorId(tenantId, tbMsg.getOriginator());
197 214 Futures.transform(edgeIdFuture, edgeId -> {
198   - EdgeQueueEntityType edgeQueueEntityType = getEdgeQueueTypeByEntityType(tbMsg.getOriginator().getEntityType());
199   - if (edgeId != null && edgeQueueEntityType != null) {
  215 + EdgeEventType edgeEventType = getEdgeQueueTypeByEntityType(tbMsg.getOriginator().getEntityType());
  216 + if (edgeId != null && edgeEventType != null) {
200 217 try {
201   - saveEventToEdgeQueue(tenantId, edgeId, edgeQueueEntityType, tbMsg.getType(), Base64.encodeBase64String(TbMsg.toByteArray(tbMsg)), callback);
  218 + saveEventToEdgeQueue(tenantId, edgeId, edgeEventType, tbMsg.getType(), Base64.encodeBase64String(TbMsg.toByteArray(tbMsg)), callback);
202 219 } catch (IOException e) {
203 220 log.error("Error while saving custom tbMsg into Edge Queue", e);
204 221 }
... ... @@ -211,13 +228,13 @@ public class DefaultEdgeNotificationService implements EdgeNotificationService {
211 228 switch (tbMsg.getType()) {
212 229 case DataConstants.ENTITY_ASSIGNED_TO_EDGE:
213 230 case DataConstants.ENTITY_UNASSIGNED_FROM_EDGE:
214   - processAssignedEntity(tenantId, tbMsg, EdgeQueueEntityType.DEVICE, callback);
  231 + processAssignedEntity(tenantId, tbMsg, EdgeEventType.DEVICE, callback);
215 232 break;
216 233 case DataConstants.ENTITY_DELETED:
217 234 case DataConstants.ENTITY_CREATED:
218 235 case DataConstants.ENTITY_UPDATED:
219 236 Device device = mapper.readValue(tbMsg.getData(), Device.class);
220   - pushEventToEdge(tenantId, device.getId(), EdgeQueueEntityType.DEVICE, tbMsg, callback);
  237 + pushEventToEdge(tenantId, device.getId(), EdgeEventType.DEVICE, tbMsg, callback);
221 238 break;
222 239 default:
223 240 log.warn("Unsupported msgType [{}], tbMsg [{}]", tbMsg.getType(), tbMsg);
... ... @@ -240,13 +257,13 @@ public class DefaultEdgeNotificationService implements EdgeNotificationService {
240 257 switch (tbMsg.getType()) {
241 258 case DataConstants.ENTITY_ASSIGNED_TO_EDGE:
242 259 case DataConstants.ENTITY_UNASSIGNED_FROM_EDGE:
243   - processAssignedEntity(tenantId, tbMsg, EdgeQueueEntityType.ASSET, callback);
  260 + processAssignedEntity(tenantId, tbMsg, EdgeEventType.ASSET, callback);
244 261 break;
245 262 case DataConstants.ENTITY_DELETED:
246 263 case DataConstants.ENTITY_CREATED:
247 264 case DataConstants.ENTITY_UPDATED:
248 265 Asset asset = mapper.readValue(tbMsg.getData(), Asset.class);
249   - pushEventToEdge(tenantId, asset.getId(), EdgeQueueEntityType.ASSET, tbMsg, callback);
  266 + pushEventToEdge(tenantId, asset.getId(), EdgeEventType.ASSET, tbMsg, callback);
250 267 break;
251 268 default:
252 269 log.warn("Unsupported msgType [{}], tbMsg [{}]", tbMsg.getType(), tbMsg);
... ... @@ -257,13 +274,13 @@ public class DefaultEdgeNotificationService implements EdgeNotificationService {
257 274 switch (tbMsg.getType()) {
258 275 case DataConstants.ENTITY_ASSIGNED_TO_EDGE:
259 276 case DataConstants.ENTITY_UNASSIGNED_FROM_EDGE:
260   - processAssignedEntity(tenantId, tbMsg, EdgeQueueEntityType.ENTITY_VIEW, callback);
  277 + processAssignedEntity(tenantId, tbMsg, EdgeEventType.ENTITY_VIEW, callback);
261 278 break;
262 279 case DataConstants.ENTITY_DELETED:
263 280 case DataConstants.ENTITY_CREATED:
264 281 case DataConstants.ENTITY_UPDATED:
265 282 EntityView entityView = mapper.readValue(tbMsg.getData(), EntityView.class);
266   - pushEventToEdge(tenantId, entityView.getId(), EdgeQueueEntityType.ENTITY_VIEW, tbMsg, callback);
  283 + pushEventToEdge(tenantId, entityView.getId(), EdgeEventType.ENTITY_VIEW, tbMsg, callback);
267 284 break;
268 285 default:
269 286 log.warn("Unsupported msgType [{}], tbMsg [{}]", tbMsg.getType(), tbMsg);
... ... @@ -278,9 +295,9 @@ public class DefaultEdgeNotificationService implements EdgeNotificationService {
278 295 case DataConstants.ALARM_ACK:
279 296 case DataConstants.ALARM_CLEAR:
280 297 Alarm alarm = mapper.readValue(tbMsg.getData(), Alarm.class);
281   - EdgeQueueEntityType edgeQueueEntityType = getEdgeQueueTypeByEntityType(alarm.getOriginator().getEntityType());
282   - if (edgeQueueEntityType != null) {
283   - pushEventToEdge(tenantId, alarm.getOriginator(), EdgeQueueEntityType.ALARM, tbMsg, callback);
  298 + EdgeEventType edgeEventType = getEdgeQueueTypeByEntityType(alarm.getOriginator().getEntityType());
  299 + if (edgeEventType != null) {
  300 + pushEventToEdge(tenantId, alarm.getOriginator(), EdgeEventType.ALARM, tbMsg, callback);
284 301 }
285 302 break;
286 303 default:
... ... @@ -292,7 +309,7 @@ public class DefaultEdgeNotificationService implements EdgeNotificationService {
292 309 switch (tbMsg.getType()) {
293 310 case DataConstants.ENTITY_ASSIGNED_TO_EDGE:
294 311 case DataConstants.ENTITY_UNASSIGNED_FROM_EDGE:
295   - processAssignedEntity(tenantId, tbMsg, EdgeQueueEntityType.DASHBOARD, callback);
  312 + processAssignedEntity(tenantId, tbMsg, EdgeEventType.DASHBOARD, callback);
296 313 break;
297 314 case DataConstants.ENTITY_DELETED:
298 315 case DataConstants.ENTITY_CREATED:
... ... @@ -303,7 +320,7 @@ public class DefaultEdgeNotificationService implements EdgeNotificationService {
303 320 if (edges != null && edges.getData() != null && !edges.getData().isEmpty()) {
304 321 try {
305 322 for (Edge edge : edges.getData()) {
306   - pushEventToEdge(tenantId, edge.getId(), EdgeQueueEntityType.DASHBOARD, tbMsg, callback);
  323 + pushEventToEdge(tenantId, edge.getId(), EdgeEventType.DASHBOARD, tbMsg, callback);
307 324 }
308 325 } catch (IOException e) {
309 326 log.error("Can't push event to edge", e);
... ... @@ -321,7 +338,7 @@ public class DefaultEdgeNotificationService implements EdgeNotificationService {
321 338 switch (tbMsg.getType()) {
322 339 case DataConstants.ENTITY_ASSIGNED_TO_EDGE:
323 340 case DataConstants.ENTITY_UNASSIGNED_FROM_EDGE:
324   - processAssignedEntity(tenantId, tbMsg, EdgeQueueEntityType.RULE_CHAIN, callback);
  341 + processAssignedEntity(tenantId, tbMsg, EdgeEventType.RULE_CHAIN, callback);
325 342 break;
326 343 case DataConstants.ENTITY_DELETED:
327 344 case DataConstants.ENTITY_CREATED:
... ... @@ -333,7 +350,7 @@ public class DefaultEdgeNotificationService implements EdgeNotificationService {
333 350 if (edges != null && edges.getData() != null && !edges.getData().isEmpty()) {
334 351 try {
335 352 for (Edge edge : edges.getData()) {
336   - pushEventToEdge(tenantId, edge.getId(), EdgeQueueEntityType.RULE_CHAIN, tbMsg, callback);
  353 + pushEventToEdge(tenantId, edge.getId(), EdgeEventType.RULE_CHAIN, tbMsg, callback);
337 354 }
338 355 } catch (IOException e) {
339 356 log.error("Can't push event to edge", e);
... ... @@ -349,7 +366,7 @@ public class DefaultEdgeNotificationService implements EdgeNotificationService {
349 366 }
350 367
351 368
352   - private void processAssignedEntity(TenantId tenantId, TbMsg tbMsg, EdgeQueueEntityType entityType, FutureCallback<Void> callback) throws IOException {
  369 + private void processAssignedEntity(TenantId tenantId, TbMsg tbMsg, EdgeEventType entityType, FutureCallback<Void> callback) throws IOException {
353 370 EdgeId edgeId;
354 371 switch (tbMsg.getType()) {
355 372 case DataConstants.ENTITY_ASSIGNED_TO_EDGE:
... ... @@ -364,13 +381,12 @@ public class DefaultEdgeNotificationService implements EdgeNotificationService {
364 381 }
365 382 }
366 383
367   -
368   - private void pushEventToEdge(TenantId tenantId, EntityId originatorId, EdgeQueueEntityType edgeQueueEntityType, TbMsg tbMsg, FutureCallback<Void> callback) {
  384 + private void pushEventToEdge(TenantId tenantId, EntityId originatorId, EdgeEventType edgeEventType, TbMsg tbMsg, FutureCallback<Void> callback) {
369 385 ListenableFuture<EdgeId> edgeIdFuture = getEdgeIdByOriginatorId(tenantId, originatorId);
370 386 Futures.transform(edgeIdFuture, edgeId -> {
371 387 if (edgeId != null) {
372 388 try {
373   - pushEventToEdge(tenantId, edgeId, edgeQueueEntityType, tbMsg, callback);
  389 + pushEventToEdge(tenantId, edgeId, edgeEventType, tbMsg, callback);
374 390 } catch (Exception e) {
375 391 log.error("Failed to push event to edge, edgeId [{}], tbMsg [{}]", edgeId, tbMsg, e);
376 392 }
... ... @@ -380,7 +396,6 @@ public class DefaultEdgeNotificationService implements EdgeNotificationService {
380 396 MoreExecutors.directExecutor());
381 397 }
382 398
383   -
384 399 private ListenableFuture<EdgeId> getEdgeIdByOriginatorId(TenantId tenantId, EntityId originatorId) {
385 400 List<EntityRelation> originatorEdgeRelations = relationService.findByToAndType(tenantId, originatorId, EntityRelation.CONTAINS_TYPE, RelationTypeGroup.EDGE);
386 401 if (originatorEdgeRelations != null && originatorEdgeRelations.size() > 0) {
... ... @@ -391,12 +406,12 @@ public class DefaultEdgeNotificationService implements EdgeNotificationService {
391 406 }
392 407
393 408
394   - private void pushEventToEdge(TenantId tenantId, EdgeId edgeId, EdgeQueueEntityType entityType, TbMsg tbMsg, FutureCallback<Void> callback) throws IOException {
  409 + private void pushEventToEdge(TenantId tenantId, EdgeId edgeId, EdgeEventType entityType, TbMsg tbMsg, FutureCallback<Void> callback) throws IOException {
395 410 log.debug("Pushing event(s) to edge queue. tenantId [{}], edgeId [{}], entityType [{}], tbMsg [{}]", tenantId, edgeId, entityType, tbMsg);
396 411
397 412 saveEventToEdgeQueue(tenantId, edgeId, entityType, tbMsg.getType(), tbMsg.getData(), callback);
398 413
399   - if (entityType.equals(EdgeQueueEntityType.RULE_CHAIN)) {
  414 + if (entityType.equals(EdgeEventType.RULE_CHAIN)) {
400 415 pushRuleChainMetadataToEdge(tenantId, edgeId, tbMsg, callback);
401 416 }
402 417 }
... ... @@ -408,7 +423,7 @@ public class DefaultEdgeNotificationService implements EdgeNotificationService {
408 423 case DataConstants.ENTITY_UNASSIGNED_FROM_EDGE:
409 424 case DataConstants.ENTITY_UPDATED:
410 425 RuleChainMetaData ruleChainMetaData = ruleChainService.loadRuleChainMetaData(tenantId, ruleChain.getId());
411   - saveEventToEdgeQueue(tenantId, edgeId, EdgeQueueEntityType.RULE_CHAIN_METADATA, tbMsg.getType(), mapper.writeValueAsString(ruleChainMetaData), callback);
  426 + saveEventToEdgeQueue(tenantId, edgeId, EdgeEventType.RULE_CHAIN_METADATA, tbMsg.getType(), mapper.writeValueAsString(ruleChainMetaData), callback);
412 427 break;
413 428 default:
414 429 log.warn("Unsupported msgType [{}], tbMsg [{}]", tbMsg.getType(), tbMsg);
... ... @@ -416,14 +431,14 @@ public class DefaultEdgeNotificationService implements EdgeNotificationService {
416 431 }
417 432
418 433
419   - private EdgeQueueEntityType getEdgeQueueTypeByEntityType(EntityType entityType) {
  434 + private EdgeEventType getEdgeQueueTypeByEntityType(EntityType entityType) {
420 435 switch (entityType) {
421 436 case DEVICE:
422   - return EdgeQueueEntityType.DEVICE;
  437 + return EdgeEventType.DEVICE;
423 438 case ASSET:
424   - return EdgeQueueEntityType.ASSET;
  439 + return EdgeEventType.ASSET;
425 440 case ENTITY_VIEW:
426   - return EdgeQueueEntityType.ENTITY_VIEW;
  441 + return EdgeEventType.ENTITY_VIEW;
427 442 default:
428 443 log.info("Unsupported entity type: [{}]", entityType);
429 444 return null;
... ...
  1 +/**
  2 + * Copyright © 2016-2020 The Thingsboard Authors
  3 + *
  4 + * Licensed under the Apache License, Version 2.0 (the "License");
  5 + * you may not use this file except in compliance with the License.
  6 + * You may obtain a copy of the License at
  7 + *
  8 + * http://www.apache.org/licenses/LICENSE-2.0
  9 + *
  10 + * Unless required by applicable law or agreed to in writing, software
  11 + * distributed under the License is distributed on an "AS IS" BASIS,
  12 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13 + * See the License for the specific language governing permissions and
  14 + * limitations under the License.
  15 + */
1 16 package org.thingsboard.server.service.edge;
2 17
3 18 import org.thingsboard.server.common.data.Event;
4 19 import org.thingsboard.server.common.data.edge.Edge;
  20 +import org.thingsboard.server.common.data.edge.EdgeEvent;
5 21 import org.thingsboard.server.common.data.id.EdgeId;
6 22 import org.thingsboard.server.common.data.id.RuleChainId;
7 23 import org.thingsboard.server.common.data.id.TenantId;
... ... @@ -14,7 +30,7 @@ import java.io.IOException;
14 30
15 31 public interface EdgeNotificationService {
16 32
17   - TimePageData<Event> findQueueEvents(TenantId tenantId, EdgeId edgeId, TimePageLink pageLink);
  33 + TimePageData<EdgeEvent> findEdgeEvents(TenantId tenantId, EdgeId edgeId, TimePageLink pageLink);
18 34
19 35 Edge setEdgeRootRuleChain(TenantId tenantId, Edge edge, RuleChainId ruleChainId) throws IOException;
20 36
... ...
... ... @@ -33,14 +33,14 @@ import org.thingsboard.server.common.data.DataConstants;
33 33 import org.thingsboard.server.common.data.Device;
34 34 import org.thingsboard.server.common.data.EntityType;
35 35 import org.thingsboard.server.common.data.EntityView;
36   -import org.thingsboard.server.common.data.Event;
37 36 import org.thingsboard.server.common.data.User;
38 37 import org.thingsboard.server.common.data.alarm.Alarm;
39 38 import org.thingsboard.server.common.data.alarm.AlarmSeverity;
40 39 import org.thingsboard.server.common.data.alarm.AlarmStatus;
41 40 import org.thingsboard.server.common.data.asset.Asset;
  41 +import org.thingsboard.server.common.data.audit.ActionType;
42 42 import org.thingsboard.server.common.data.edge.Edge;
43   -import org.thingsboard.server.common.data.edge.EdgeQueueEntry;
  43 +import org.thingsboard.server.common.data.edge.EdgeEvent;
44 44 import org.thingsboard.server.common.data.id.AssetId;
45 45 import org.thingsboard.server.common.data.id.DeviceId;
46 46 import org.thingsboard.server.common.data.id.EdgeId;
... ... @@ -63,7 +63,6 @@ import org.thingsboard.server.common.msg.TbMsg;
63 63 import org.thingsboard.server.common.msg.TbMsgDataType;
64 64 import org.thingsboard.server.common.msg.TbMsgMetaData;
65 65 import org.thingsboard.server.common.msg.queue.TbMsgCallback;
66   -import org.thingsboard.server.common.msg.session.SessionMsgType;
67 66 import org.thingsboard.server.gen.edge.AlarmUpdateMsg;
68 67 import org.thingsboard.server.gen.edge.ConnectRequestMsg;
69 68 import org.thingsboard.server.gen.edge.ConnectResponseCode;
... ... @@ -169,36 +168,28 @@ public final class EdgeGrpcSession implements Closeable {
169 168 void processHandleMessages() throws ExecutionException, InterruptedException {
170 169 Long queueStartTs = getQueueStartTs().get();
171 170 TimePageLink pageLink = new TimePageLink(ctx.getEdgeEventStorageSettings().getMaxReadRecordsCount(), queueStartTs, null, true);
172   - TimePageData<Event> pageData;
  171 + TimePageData<EdgeEvent> pageData;
173 172 UUID ifOffset = null;
174 173 do {
175   - pageData = ctx.getEdgeNotificationService().findQueueEvents(edge.getTenantId(), edge.getId(), pageLink);
  174 + pageData = ctx.getEdgeNotificationService().findEdgeEvents(edge.getTenantId(), edge.getId(), pageLink);
176 175 if (isConnected() && !pageData.getData().isEmpty()) {
177 176 log.trace("[{}] [{}] event(s) are going to be processed.", this.sessionId, pageData.getData().size());
178   - for (Event event : pageData.getData()) {
179   - log.trace("[{}] Processing event [{}]", this.sessionId, event);
  177 + for (EdgeEvent edgeEvent : pageData.getData()) {
  178 + log.trace("[{}] Processing edge event [{}]", this.sessionId, edgeEvent);
180 179 try {
181   - EdgeQueueEntry entry = objectMapper.treeToValue(event.getBody(), EdgeQueueEntry.class);
182   - UpdateMsgType msgType = getResponseMsgType(entry.getType());
183   - switch (msgType) {
184   - case ENTITY_DELETED_RPC_MESSAGE:
185   - case ENTITY_UPDATED_RPC_MESSAGE:
186   - case ENTITY_CREATED_RPC_MESSAGE:
187   - case ALARM_ACK_RPC_MESSAGE:
188   - case ALARM_CLEAR_RPC_MESSAGE:
189   - processEntityCRUDMessage(entry, msgType);
190   - break;
191   - case RULE_CHAIN_CUSTOM_MESSAGE:
192   - processCustomDownlinkMessage(entry);
193   - break;
  180 + UpdateMsgType msgType = getResponseMsgType(ActionType.valueOf(edgeEvent.getEdgeEventAction()));
  181 + if (msgType == null) {
  182 + processTelemetryMessage(edgeEvent);
  183 + } else {
  184 + processEntityCRUDMessage(edgeEvent, msgType);
194 185 }
195 186 if (ENTITY_CREATED_RPC_MESSAGE.equals(msgType)) {
196   - pushEntityAttributesToEdge(entry);
  187 + pushEntityAttributesToEdge(edgeEvent);
197 188 }
198 189 } catch (Exception e) {
199 190 log.error("Exception during processing records from queue", e);
200 191 }
201   - ifOffset = event.getUuidId();
  192 + ifOffset = edgeEvent.getUuidId();
202 193 }
203 194 }
204 195 if (isConnected() && pageData.hasNext()) {
... ... @@ -222,10 +213,10 @@ public final class EdgeGrpcSession implements Closeable {
222 213 }
223 214 }
224 215
225   - private void pushEntityAttributesToEdge(EdgeQueueEntry entry) throws IOException {
  216 + private void pushEntityAttributesToEdge(EdgeEvent edgeEvent) throws IOException {
226 217 EntityId entityId = null;
227 218 String entityName = null;
228   - switch (entry.getEntityType()) {
  219 + switch (edgeEvent.getEdgeEventType()) {
229 220 case EDGE:
230 221 Edge edge = objectMapper.readValue(entry.getData(), Edge.class);
231 222 entityId = edge.getId();
... ... @@ -277,7 +268,7 @@ public final class EdgeGrpcSession implements Closeable {
277 268 , objectMapper.writeValueAsString(entityNode));
278 269 log.debug("Sending donwlink entity data msg, entityName [{}], tbMsg [{}]", finalEntityName, tbMsg);
279 270 outputStream.onNext(ResponseMsg.newBuilder()
280   - .setDownlinkMsg(constructDownlinkEntityDataMsg(finalEntityName, finalEntityId, tbMsg))
  271 + .setDownlinkMsg(constructEntityDataProtoMsg(finalEntityName, finalEntityId, tbMsg))
281 272 .build());
282 273 } catch (Exception e) {
283 274 log.error("[{}] Failed to send attribute updates to the edge", edge.getName(), e);
... ... @@ -290,12 +281,12 @@ public final class EdgeGrpcSession implements Closeable {
290 281 }
291 282 }
292 283
293   - private void processCustomDownlinkMessage(EdgeQueueEntry entry) throws IOException {
294   - log.trace("Executing processCustomDownlinkMessage, entry [{}]", entry);
  284 + private void processTelemetryMessage(EdgeEvent edgeEvent) throws IOException {
  285 + log.trace("Executing processTelemetryMessage, edgeEvent [{}]", edgeEvent);
295 286 TbMsg tbMsg = TbMsg.fromBytes(Base64.decodeBase64(entry.getData()), TbMsgCallback.EMPTY);
296 287 String entityName = null;
297 288 EntityId entityId = null;
298   - switch (entry.getEntityType()) {
  289 + switch (edgeEvent.getEdgeEventType()) {
299 290 case DEVICE:
300 291 Device device = ctx.getDeviceService().findDeviceById(edge.getTenantId(), new DeviceId(tbMsg.getOriginator().getId()));
301 292 entityName = device.getName();
... ... @@ -316,14 +307,14 @@ public final class EdgeGrpcSession implements Closeable {
316 307 if (entityName != null && entityId != null) {
317 308 log.debug("Sending downlink entity data msg, entityName [{}], tbMsg [{}]", entityName, tbMsg);
318 309 outputStream.onNext(ResponseMsg.newBuilder()
319   - .setDownlinkMsg(constructDownlinkEntityDataMsg(entityName, entityId, tbMsg))
  310 + .setDownlinkMsg(constructEntityDataProtoMsg(entityName, entityId, tbMsg))
320 311 .build());
321 312 }
322 313 }
323 314
324   - private void processEntityCRUDMessage(EdgeQueueEntry entry, UpdateMsgType msgType) throws java.io.IOException {
325   - log.trace("Executing processEntityCRUDMessage, entry [{}], msgType [{}]", entry, msgType);
326   - switch (entry.getEntityType()) {
  315 + private void processEntityCRUDMessage(EdgeEvent edgeEvent, UpdateMsgType msgType) throws java.io.IOException {
  316 + log.trace("Executing processEntityCRUDMessage, edgeEvent [{}], msgType [{}]", edgeEvent, msgType);
  317 + switch (edgeEvent.getEdgeEventType()) {
327 318 case EDGE:
328 319 Edge edge = objectMapper.readValue(entry.getData(), Edge.class);
329 320 onEdgeUpdated(msgType, edge);
... ... @@ -476,33 +467,30 @@ public final class EdgeGrpcSession implements Closeable {
476 467 .build());
477 468 }
478 469
479   - private UpdateMsgType getResponseMsgType(String msgType) {
480   - if (msgType.equals(SessionMsgType.POST_TELEMETRY_REQUEST.name()) ||
481   - msgType.equals(SessionMsgType.POST_ATTRIBUTES_REQUEST.name()) ||
482   - msgType.equals(DataConstants.ATTRIBUTES_UPDATED) ||
483   - msgType.equals(DataConstants.ATTRIBUTES_DELETED)) {
484   - return UpdateMsgType.RULE_CHAIN_CUSTOM_MESSAGE;
485   - } else {
486   - switch (msgType) {
487   - case DataConstants.ENTITY_UPDATED:
488   - return UpdateMsgType.ENTITY_UPDATED_RPC_MESSAGE;
489   - case DataConstants.ENTITY_CREATED:
490   - case DataConstants.ENTITY_ASSIGNED_TO_EDGE:
491   - return ENTITY_CREATED_RPC_MESSAGE;
492   - case DataConstants.ENTITY_DELETED:
493   - case DataConstants.ENTITY_UNASSIGNED_FROM_EDGE:
494   - return UpdateMsgType.ENTITY_DELETED_RPC_MESSAGE;
495   - case DataConstants.ALARM_ACK:
496   - return UpdateMsgType.ALARM_ACK_RPC_MESSAGE;
497   - case DataConstants.ALARM_CLEAR:
498   - return UpdateMsgType.ALARM_CLEAR_RPC_MESSAGE;
499   - default:
500   - throw new RuntimeException("Unsupported msgType [" + msgType + "]");
501   - }
  470 + private UpdateMsgType getResponseMsgType(ActionType actionType) {
  471 + switch (actionType) {
  472 + case ADDED:
  473 + return UpdateMsgType.ENTITY_UPDATED_RPC_MESSAGE;
  474 + case UPDATED:
  475 + case ASSIGNED_TO_EDGE:
  476 + return ENTITY_CREATED_RPC_MESSAGE;
  477 + case DELETED:
  478 + case UNASSIGNED_FROM_EDGE:
  479 + return UpdateMsgType.ENTITY_DELETED_RPC_MESSAGE;
  480 + case ALARM_ACK:
  481 + return UpdateMsgType.ALARM_ACK_RPC_MESSAGE;
  482 + case ALARM_CLEAR:
  483 + return UpdateMsgType.ALARM_CLEAR_RPC_MESSAGE;
  484 + case ATTRIBUTES_UPDATED:
  485 + case ATTRIBUTES_DELETED:
  486 + case TIMESERIES_DELETED:
  487 + return null;
  488 + default:
  489 + throw new RuntimeException("Unsupported actionType [" + actionType + "]");
502 490 }
503 491 }
504 492
505   - private DownlinkMsg constructDownlinkEntityDataMsg(String entityName, EntityId entityId, TbMsg tbMsg) {
  493 + private DownlinkMsg constructEntityDataProtoMsg(String entityName, EntityId entityId, TbMsg tbMsg) {
506 494 EntityDataProto entityData = EntityDataProto.newBuilder()
507 495 .setEntityName(entityName)
508 496 .setTbMsg(ByteString.copyFrom(TbMsg.toByteArray(tbMsg)))
... ...
... ... @@ -239,7 +239,7 @@ public class SqlDatabaseUpgradeService implements DatabaseEntitiesUpgradeService
239 239 schemaUpdateFile = Paths.get(installScripts.getDataDir(), "upgrade", "2.6.0", SCHEMA_UPDATE_SQL);
240 240 loadSql(schemaUpdateFile, conn);
241 241 try {
242   - conn.createStatement().execute("ALTER TABLE rule_chain ADD type varchar(255) DEFAULT 'SYSTEM'"); //NOSONAR, ignoring because method used to execute thingsboard database upgrade script
  242 + conn.createStatement().execute("ALTER TABLE rule_chain ADD type varchar(255) DEFAULT 'CORE'"); //NOSONAR, ignoring because method used to execute thingsboard database upgrade script
243 243 } catch (Exception e) {}
244 244 log.info("Schema updated.");
245 245 }
... ...
  1 +/**
  2 + * Copyright © 2016-2020 The Thingsboard Authors
  3 + *
  4 + * Licensed under the Apache License, Version 2.0 (the "License");
  5 + * you may not use this file except in compliance with the License.
  6 + * You may obtain a copy of the License at
  7 + *
  8 + * http://www.apache.org/licenses/LICENSE-2.0
  9 + *
  10 + * Unless required by applicable law or agreed to in writing, software
  11 + * distributed under the License is distributed on an "AS IS" BASIS,
  12 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13 + * See the License for the specific language governing permissions and
  14 + * limitations under the License.
  15 + */
  16 +package org.thingsboard.server.dao.edge;
  17 +
  18 +import com.google.common.util.concurrent.ListenableFuture;
  19 +import org.thingsboard.server.common.data.EntityType;
  20 +import org.thingsboard.server.common.data.edge.EdgeEvent;
  21 +import org.thingsboard.server.common.data.edge.EdgeEventType;
  22 +import org.thingsboard.server.common.data.id.EdgeId;
  23 +import org.thingsboard.server.common.data.id.TenantId;
  24 +import org.thingsboard.server.common.data.page.TimePageData;
  25 +import org.thingsboard.server.common.data.page.TimePageLink;
  26 +
  27 +public interface EdgeEventService {
  28 +
  29 + EdgeEventType getEdgeEventTypeByEntityType(EntityType entityType);
  30 +
  31 + ListenableFuture<EdgeEvent> saveAsync(EdgeEvent edgeEvent);
  32 +
  33 + TimePageData<EdgeEvent> findEdgeEvents(TenantId tenantId, EdgeId edgeId, TimePageLink pageLink);
  34 +
  35 +}
... ...
... ... @@ -5,7 +5,7 @@
5 5 * you may not use this file except in compliance with the License.
6 6 * You may obtain a copy of the License at
7 7 *
8   - * http://www.apache.org/licenses/LICENSE-2.0
  8 + * http://www.apache.org/licenses/LICENSE-2.0
9 9 *
10 10 * Unless required by applicable law or agreed to in writing, software
11 11 * distributed under the License is distributed on an "AS IS" BASIS,
... ...
... ... @@ -65,7 +65,4 @@ public class DataConstants {
65 65 public static final String DEFAULT_SECRET_KEY = "";
66 66 public static final String SECRET_KEY_FIELD_NAME = "secretKey";
67 67 public static final String DURATION_MS_FIELD_NAME = "durationMs";
68   -
69   - public static final String EDGE_QUEUE_EVENT_TYPE = "EDGE_QUEUE";
70   -
71 68 }
... ...
... ... @@ -24,6 +24,7 @@ public enum ActionType {
24 24 UPDATED(false), // log entity
25 25 ATTRIBUTES_UPDATED(false), // log attributes/values
26 26 ATTRIBUTES_DELETED(false), // log attributes
  27 + TIMESERIES_UPDATED(false), // log timeseries
27 28 TIMESERIES_DELETED(false), // log timeseries
28 29 RPC_CALL(false), // log method and params
29 30 CREDENTIALS_UPDATED(false), // log new credentials
... ...
  1 +/**
  2 + * Copyright © 2016-2020 The Thingsboard Authors
  3 + *
  4 + * Licensed under the Apache License, Version 2.0 (the "License");
  5 + * you may not use this file except in compliance with the License.
  6 + * You may obtain a copy of the License at
  7 + *
  8 + * http://www.apache.org/licenses/LICENSE-2.0
  9 + *
  10 + * Unless required by applicable law or agreed to in writing, software
  11 + * distributed under the License is distributed on an "AS IS" BASIS,
  12 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13 + * See the License for the specific language governing permissions and
  14 + * limitations under the License.
  15 + */
  16 +package org.thingsboard.server.common.data.edge;
  17 +
  18 +import com.fasterxml.jackson.databind.JsonNode;
  19 +import lombok.Data;
  20 +import org.thingsboard.server.common.data.BaseData;
  21 +import org.thingsboard.server.common.data.id.EdgeEventId;
  22 +import org.thingsboard.server.common.data.id.EdgeId;
  23 +import org.thingsboard.server.common.data.id.EntityId;
  24 +import org.thingsboard.server.common.data.id.TenantId;
  25 +
  26 +import java.util.UUID;
  27 +
  28 +@Data
  29 +public class EdgeEvent extends BaseData<EdgeEventId> {
  30 +
  31 + private TenantId tenantId;
  32 + private EdgeId edgeId;
  33 + private String edgeEventAction;
  34 + private UUID entityId;
  35 + private EdgeEventType edgeEventType;
  36 + private transient JsonNode entityBody;
  37 +
  38 + public EdgeEvent() {
  39 + super();
  40 + }
  41 +
  42 + public EdgeEvent(EdgeEventId id) {
  43 + super(id);
  44 + }
  45 +
  46 + public EdgeEvent(EdgeEvent event) {
  47 + super(event);
  48 + }
  49 +
  50 +}
... ...
common/data/src/main/java/org/thingsboard/server/common/data/edge/EdgeEventType.java renamed from common/data/src/main/java/org/thingsboard/server/common/data/edge/EdgeQueueEntityType.java
... ... @@ -15,6 +15,6 @@
15 15 */
16 16 package org.thingsboard.server.common.data.edge;
17 17
18   -public enum EdgeQueueEntityType {
  18 +public enum EdgeEventType {
19 19 DASHBOARD, ASSET, DEVICE, ENTITY_VIEW, ALARM, RULE_CHAIN, RULE_CHAIN_METADATA, EDGE, USER, CUSTOMER, RELATION
20 20 }
... ...
  1 +/**
  2 + * Copyright © 2016-2020 The Thingsboard Authors
  3 + *
  4 + * Licensed under the Apache License, Version 2.0 (the "License");
  5 + * you may not use this file except in compliance with the License.
  6 + * You may obtain a copy of the License at
  7 + *
  8 + * http://www.apache.org/licenses/LICENSE-2.0
  9 + *
  10 + * Unless required by applicable law or agreed to in writing, software
  11 + * distributed under the License is distributed on an "AS IS" BASIS,
  12 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13 + * See the License for the specific language governing permissions and
  14 + * limitations under the License.
  15 + */
  16 +package org.thingsboard.server.common.data.id;
  17 +
  18 +import com.fasterxml.jackson.annotation.JsonCreator;
  19 +import com.fasterxml.jackson.annotation.JsonProperty;
  20 +
  21 +import java.util.UUID;
  22 +
  23 +public class EdgeEventId extends UUIDBased {
  24 +
  25 + private static final long serialVersionUID = 1L;
  26 +
  27 + @JsonCreator
  28 + public EdgeEventId(@JsonProperty("id") UUID id) {
  29 + super(id);
  30 + }
  31 +
  32 + public static EdgeEventId fromString(String edgeEventId) {
  33 + return new EdgeEventId(UUID.fromString(edgeEventId));
  34 + }
  35 +}
... ...
... ... @@ -16,5 +16,5 @@
16 16 package org.thingsboard.server.common.data.rule;
17 17
18 18 public enum RuleChainType {
19   - SYSTEM, EDGE
  19 + CORE, EDGE
20 20 }
... ...
... ... @@ -42,6 +42,10 @@
42 42 </dependency>
43 43 <dependency>
44 44 <groupId>org.thingsboard.common</groupId>
  45 + <artifactId>queue</artifactId>
  46 + </dependency>
  47 + <dependency>
  48 + <groupId>org.thingsboard.common</groupId>
45 49 <artifactId>message</artifactId>
46 50 </dependency>
47 51 <dependency>
... ...
... ... @@ -19,6 +19,8 @@ option java_package = "org.thingsboard.server.gen.edge";
19 19 option java_multiple_files = true;
20 20 option java_outer_classname = "EdgeProtos";
21 21
  22 +import "queue.proto";
  23 +
22 24 package edge;
23 25
24 26 // Interface exported by the ThingsBoard Edge Transport.
... ... @@ -94,15 +96,16 @@ enum UpdateMsgType {
94 96 ENTITY_DELETED_RPC_MESSAGE = 2;
95 97 ALARM_ACK_RPC_MESSAGE = 3;
96 98 ALARM_CLEAR_RPC_MESSAGE = 4;
97   - RULE_CHAIN_CUSTOM_MESSAGE = 5;
98   - DEVICE_CONFLICT_RPC_MESSAGE = 6;
  99 + DEVICE_CONFLICT_RPC_MESSAGE = 5;
99 100 }
100 101
101 102 message EntityDataProto {
102 103 string entityName = 1;
103 104 int64 entityIdMSB = 2;
104 105 int64 entityIdLSB = 3;
105   - bytes tbMsg = 4;
  106 + transport.PostTelemetryMsg postTelemetryMsg = 4;
  107 + transport.PostAttributeMsg postAttributesMsg = 5;
  108 + // transport.ToDeviceRpcRequestMsg ???
106 109 }
107 110
108 111 message RuleChainUpdateMsg {
... ...
... ... @@ -356,6 +356,14 @@ message FromDeviceRPCResponseProto {
356 356 message EdgeNotificationMsgProto {
357 357 int64 tenantIdMSB = 1;
358 358 int64 tenantIdLSB = 2;
  359 + string edgeEventType = 3;
  360 + string edgeEventAction = 4;
  361 + int64 entityIdMSB = 5;
  362 + int64 entityIdLSB = 6;
  363 + string entityType = 7;
  364 + string entityBody = 8;
  365 + PostTelemetryMsg postTelemetryMsg = 9;
  366 + PostAttributeMsg postAttributesMsg = 10;
359 367 }
360 368
361 369 /**
... ...
  1 +/**
  2 + * Copyright © 2016-2020 The Thingsboard Authors
  3 + *
  4 + * Licensed under the Apache License, Version 2.0 (the "License");
  5 + * you may not use this file except in compliance with the License.
  6 + * You may obtain a copy of the License at
  7 + *
  8 + * http://www.apache.org/licenses/LICENSE-2.0
  9 + *
  10 + * Unless required by applicable law or agreed to in writing, software
  11 + * distributed under the License is distributed on an "AS IS" BASIS,
  12 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13 + * See the License for the specific language governing permissions and
  14 + * limitations under the License.
  15 + */
  16 +package org.thingsboard.server.dao.edge;
  17 +
  18 +import com.google.common.util.concurrent.ListenableFuture;
  19 +import lombok.extern.slf4j.Slf4j;
  20 +import org.apache.commons.lang3.StringUtils;
  21 +import org.springframework.beans.factory.annotation.Autowired;
  22 +import org.springframework.stereotype.Service;
  23 +import org.thingsboard.server.common.data.EntityType;
  24 +import org.thingsboard.server.common.data.edge.EdgeEvent;
  25 +import org.thingsboard.server.common.data.edge.EdgeEventType;
  26 +import org.thingsboard.server.common.data.id.EdgeId;
  27 +import org.thingsboard.server.common.data.id.TenantId;
  28 +import org.thingsboard.server.common.data.page.TimePageData;
  29 +import org.thingsboard.server.common.data.page.TimePageLink;
  30 +import org.thingsboard.server.dao.exception.DataValidationException;
  31 +import org.thingsboard.server.dao.service.DataValidator;
  32 +
  33 +import java.util.List;
  34 +
  35 +@Service
  36 +@Slf4j
  37 +public class BaseEdgeEventService implements EdgeEventService {
  38 +
  39 + @Autowired
  40 + public EdgeEventDao edgeEventDao;
  41 +
  42 + @Override
  43 + public EdgeEventType getEdgeEventTypeByEntityType(EntityType entityType) {
  44 + switch (entityType) {
  45 + case DEVICE:
  46 + return EdgeEventType.DEVICE;
  47 + case ASSET:
  48 + return EdgeEventType.ASSET;
  49 + case ENTITY_VIEW:
  50 + return EdgeEventType.ENTITY_VIEW;
  51 + case DASHBOARD:
  52 + return EdgeEventType.DASHBOARD;
  53 + case USER:
  54 + return EdgeEventType.USER;
  55 + default:
  56 + log.warn("Failed to push notification to edge service. Unsupported entity type [{}]", entityType);
  57 + return null;
  58 + }
  59 + }
  60 +
  61 + @Override
  62 + public ListenableFuture<EdgeEvent> saveAsync(EdgeEvent edgeEvent) {
  63 + edgeEventValidator.validate(edgeEvent, EdgeEvent::getTenantId);
  64 + return edgeEventDao.saveAsync(edgeEvent);
  65 + }
  66 +
  67 + @Override
  68 + public TimePageData<EdgeEvent> findEdgeEvents(TenantId tenantId, EdgeId edgeId, TimePageLink pageLink) {
  69 + List<EdgeEvent> events = edgeEventDao.findEdgeEvents(tenantId.getId(), edgeId, pageLink);
  70 + return new TimePageData<>(events, pageLink);
  71 + }
  72 +
  73 + private DataValidator<EdgeEvent> edgeEventValidator =
  74 + new DataValidator<EdgeEvent>() {
  75 + @Override
  76 + protected void validateDataImpl(TenantId tenantId, EdgeEvent edgeEvent) {
  77 + if (edgeEvent.getEdgeId() == null) {
  78 + throw new DataValidationException("Edge id should be specified!");
  79 + }
  80 + if (StringUtils.isEmpty(edgeEvent.getEdgeEventAction())) {
  81 + throw new DataValidationException("Edge Event action should be specified!");
  82 + }
  83 + }
  84 + };
  85 +}
... ...
  1 +/**
  2 + * Copyright © 2016-2020 The Thingsboard Authors
  3 + *
  4 + * Licensed under the Apache License, Version 2.0 (the "License");
  5 + * you may not use this file except in compliance with the License.
  6 + * You may obtain a copy of the License at
  7 + *
  8 + * http://www.apache.org/licenses/LICENSE-2.0
  9 + *
  10 + * Unless required by applicable law or agreed to in writing, software
  11 + * distributed under the License is distributed on an "AS IS" BASIS,
  12 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13 + * See the License for the specific language governing permissions and
  14 + * limitations under the License.
  15 + */
  16 +package org.thingsboard.server.dao.edge;
  17 +
  18 +import com.google.common.util.concurrent.ListenableFuture;
  19 +import org.thingsboard.server.common.data.edge.EdgeEvent;
  20 +import org.thingsboard.server.common.data.id.EdgeId;
  21 +import org.thingsboard.server.common.data.page.TimePageLink;
  22 +import org.thingsboard.server.dao.Dao;
  23 +
  24 +import java.util.List;
  25 +import java.util.UUID;
  26 +
  27 +/**
  28 + * The Interface EdgeEventDao.
  29 + */
  30 +public interface EdgeEventDao extends Dao<EdgeEvent> {
  31 +
  32 + /**
  33 + * Save or update edge event object async
  34 + *
  35 + * @param edgeEvent the event object
  36 + * @return saved edge event object future
  37 + */
  38 + ListenableFuture<EdgeEvent> saveAsync(EdgeEvent edgeEvent);
  39 +
  40 +
  41 + /**
  42 + * Find edge events by tenantId, edgeId and pageLink.
  43 + *
  44 + * @param tenantId the tenantId
  45 + * @param edgeId the edgeId
  46 + * @param pageLink the pageLink
  47 + * @return the event list
  48 + */
  49 + List<EdgeEvent> findEdgeEvents(UUID tenantId, EdgeId edgeId, TimePageLink pageLink);
  50 +
  51 +}
... ...
... ... @@ -5,7 +5,7 @@
5 5 * you may not use this file except in compliance with the License.
6 6 * You may obtain a copy of the License at
7 7 *
8   - * http://www.apache.org/licenses/LICENSE-2.0
  8 + * http://www.apache.org/licenses/LICENSE-2.0
9 9 *
10 10 * Unless required by applicable law or agreed to in writing, software
11 11 * distributed under the License is distributed on an "AS IS" BASIS,
... ...
... ... @@ -372,6 +372,16 @@ public class ModelConstants {
372 372 public static final String EDGE_ROUTING_KEY_PROPERTY = "routing_key";
373 373 public static final String EDGE_SECRET_PROPERTY = "secret";
374 374
  375 + /**
  376 + * Cassandra edge queue constants.
  377 + */
  378 + public static final String EDGE_EVENT_COLUMN_FAMILY_NAME = "edge_event";
  379 + public static final String EDGE_EVENT_TENANT_ID_PROPERTY = TENANT_ID_PROPERTY;
  380 + public static final String EDGE_EVENT_EDGE_ID_PROPERTY = "edge_id";
  381 + public static final String EDGE_EVENT_TYPE_PROPERTY = "edge_event_type";
  382 + public static final String EDGE_EVENT_ACTION_PROPERTY = "edge_event_action";
  383 + public static final String EDGE_EVENT_ENTITY_ID_PROPERTY = "entity_id";
  384 + public static final String EDGE_EVENT_ENTITY_BODY_PROPERTY = "entity_body";
375 385
376 386 /**
377 387 * Cassandra attributes and timeseries constants.
... ...
  1 +/**
  2 + * Copyright © 2016-2020 The Thingsboard Authors
  3 + *
  4 + * Licensed under the Apache License, Version 2.0 (the "License");
  5 + * you may not use this file except in compliance with the License.
  6 + * You may obtain a copy of the License at
  7 + *
  8 + * http://www.apache.org/licenses/LICENSE-2.0
  9 + *
  10 + * Unless required by applicable law or agreed to in writing, software
  11 + * distributed under the License is distributed on an "AS IS" BASIS,
  12 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13 + * See the License for the specific language governing permissions and
  14 + * limitations under the License.
  15 + */
  16 +package org.thingsboard.server.dao.model.nosql;
  17 +
  18 +import com.datastax.driver.core.utils.UUIDs;
  19 +import com.datastax.driver.mapping.annotations.ClusteringColumn;
  20 +import com.datastax.driver.mapping.annotations.Column;
  21 +import com.datastax.driver.mapping.annotations.PartitionKey;
  22 +import com.datastax.driver.mapping.annotations.Table;
  23 +import com.fasterxml.jackson.databind.JsonNode;
  24 +import lombok.Data;
  25 +import lombok.NoArgsConstructor;
  26 +import org.thingsboard.server.common.data.EntityType;
  27 +import org.thingsboard.server.common.data.Event;
  28 +import org.thingsboard.server.common.data.edge.EdgeEvent;
  29 +import org.thingsboard.server.common.data.edge.EdgeEventType;
  30 +import org.thingsboard.server.common.data.id.EdgeEventId;
  31 +import org.thingsboard.server.common.data.id.EdgeId;
  32 +import org.thingsboard.server.common.data.id.EntityIdFactory;
  33 +import org.thingsboard.server.common.data.id.EventId;
  34 +import org.thingsboard.server.common.data.id.TenantId;
  35 +import org.thingsboard.server.dao.model.BaseEntity;
  36 +import org.thingsboard.server.dao.model.type.EdgeEventTypeCodec;
  37 +import org.thingsboard.server.dao.model.type.EntityTypeCodec;
  38 +import org.thingsboard.server.dao.model.type.JsonCodec;
  39 +
  40 +import java.util.UUID;
  41 +
  42 +import static org.thingsboard.server.dao.model.ModelConstants.EDGE_EVENT_ACTION_PROPERTY;
  43 +import static org.thingsboard.server.dao.model.ModelConstants.EDGE_EVENT_COLUMN_FAMILY_NAME;
  44 +import static org.thingsboard.server.dao.model.ModelConstants.EDGE_EVENT_EDGE_ID_PROPERTY;
  45 +import static org.thingsboard.server.dao.model.ModelConstants.EDGE_EVENT_ENTITY_BODY_PROPERTY;
  46 +import static org.thingsboard.server.dao.model.ModelConstants.EDGE_EVENT_ENTITY_ID_PROPERTY;
  47 +import static org.thingsboard.server.dao.model.ModelConstants.EDGE_EVENT_TENANT_ID_PROPERTY;
  48 +import static org.thingsboard.server.dao.model.ModelConstants.EDGE_EVENT_TYPE_PROPERTY;
  49 +import static org.thingsboard.server.dao.model.ModelConstants.EVENT_BODY_PROPERTY;
  50 +import static org.thingsboard.server.dao.model.ModelConstants.EVENT_COLUMN_FAMILY_NAME;
  51 +import static org.thingsboard.server.dao.model.ModelConstants.EVENT_ENTITY_ID_PROPERTY;
  52 +import static org.thingsboard.server.dao.model.ModelConstants.EVENT_ENTITY_TYPE_PROPERTY;
  53 +import static org.thingsboard.server.dao.model.ModelConstants.EVENT_TENANT_ID_PROPERTY;
  54 +import static org.thingsboard.server.dao.model.ModelConstants.EVENT_TYPE_PROPERTY;
  55 +import static org.thingsboard.server.dao.model.ModelConstants.EVENT_UID_PROPERTY;
  56 +import static org.thingsboard.server.dao.model.ModelConstants.ID_PROPERTY;
  57 +
  58 +@Data
  59 +@NoArgsConstructor
  60 +@Table(name = EDGE_EVENT_COLUMN_FAMILY_NAME)
  61 +public class EdgeEventEntity implements BaseEntity<EdgeEvent> {
  62 +
  63 + @Column(name = ID_PROPERTY)
  64 + private UUID id;
  65 +
  66 + @PartitionKey()
  67 + @Column(name = EDGE_EVENT_TENANT_ID_PROPERTY)
  68 + private UUID tenantId;
  69 +
  70 + @PartitionKey(value = 1)
  71 + @Column(name = EDGE_EVENT_EDGE_ID_PROPERTY)
  72 + private UUID edgeId;
  73 +
  74 + @PartitionKey(value = 2)
  75 + @Column(name = EDGE_EVENT_TYPE_PROPERTY, codec = EdgeEventTypeCodec.class)
  76 + private EdgeEventType edgeEventType;
  77 +
  78 + @PartitionKey(value = 3)
  79 + @Column(name = EDGE_EVENT_ENTITY_ID_PROPERTY)
  80 + private UUID entityId;
  81 +
  82 + @ClusteringColumn()
  83 + @Column(name = EDGE_EVENT_ACTION_PROPERTY)
  84 + private String edgeEventAction;
  85 +
  86 + // TODO
  87 + @ClusteringColumn(value = 1)
  88 + @Column(name = EVENT_UID_PROPERTY)
  89 + private String eventUid;
  90 +
  91 + @Column(name = EDGE_EVENT_ENTITY_BODY_PROPERTY, codec = JsonCodec.class)
  92 + private JsonNode entityBody;
  93 +
  94 + public EdgeEventEntity(EdgeEvent edgeEvent) {
  95 + if (edgeEvent.getId() != null) {
  96 + this.id = edgeEvent.getId().getId();
  97 + }
  98 + if (edgeEvent.getTenantId() != null) {
  99 + this.tenantId = edgeEvent.getTenantId().getId();
  100 + }
  101 + if (edgeEvent.getEdgeId() != null) {
  102 + this.edgeId = edgeEvent.getEdgeId().getId();
  103 + }
  104 +// if (event.getEntityId() != null) {
  105 +// this.entityType = event.getEntityId().getEntityType();
  106 +// this.entityId = event.getEntityId().getId();
  107 +// }
  108 +// this.edgeEventType = edgeEvent.getEdgeEventType();
  109 +// this.edgeEventAction = edgeEvent.getEdgeEventAction();
  110 +// this.entityBody = edgeEvent.getEntityBody();
  111 + }
  112 +
  113 + @Override
  114 + public UUID getUuid() {
  115 + return id;
  116 + }
  117 +
  118 + @Override
  119 + public void setUuid(UUID id) {
  120 + this.id = id;
  121 + }
  122 +
  123 + @Override
  124 + public EdgeEvent toData() {
  125 + EdgeEvent edgeEvent = new EdgeEvent(new EdgeEventId(id));
  126 +// edgeEvent.setCreatedTime(UUIDs.unixTimestamp(id));
  127 +// edgeEvent.setTenantId(new TenantId(tenantId));
  128 +// edgeEvent.setEdgeId(new EdgeId(edgeId));
  129 +// edgeEvent.setEntityId(entityId);
  130 +// event.setBody(body);
  131 +// event.setType(eventType);
  132 +// event.setUid(eventUid);
  133 + return edgeEvent;
  134 + }
  135 +}
... ...
  1 +/**
  2 + * Copyright © 2016-2020 The Thingsboard Authors
  3 + *
  4 + * Licensed under the Apache License, Version 2.0 (the "License");
  5 + * you may not use this file except in compliance with the License.
  6 + * You may obtain a copy of the License at
  7 + *
  8 + * http://www.apache.org/licenses/LICENSE-2.0
  9 + *
  10 + * Unless required by applicable law or agreed to in writing, software
  11 + * distributed under the License is distributed on an "AS IS" BASIS,
  12 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13 + * See the License for the specific language governing permissions and
  14 + * limitations under the License.
  15 + */
  16 +package org.thingsboard.server.dao.model.sql;
  17 +
  18 +import com.datastax.driver.core.utils.UUIDs;
  19 +import com.fasterxml.jackson.databind.JsonNode;
  20 +import lombok.Data;
  21 +import lombok.EqualsAndHashCode;
  22 +import lombok.NoArgsConstructor;
  23 +import org.hibernate.annotations.Type;
  24 +import org.hibernate.annotations.TypeDef;
  25 +import org.thingsboard.server.common.data.edge.EdgeEvent;
  26 +import org.thingsboard.server.common.data.edge.EdgeEventType;
  27 +import org.thingsboard.server.common.data.id.EdgeEventId;
  28 +import org.thingsboard.server.common.data.id.EdgeId;
  29 +import org.thingsboard.server.common.data.id.TenantId;
  30 +import org.thingsboard.server.dao.model.BaseEntity;
  31 +import org.thingsboard.server.dao.model.BaseSqlEntity;
  32 +import org.thingsboard.server.dao.util.mapping.JsonStringType;
  33 +
  34 +import javax.persistence.Column;
  35 +import javax.persistence.Entity;
  36 +import javax.persistence.EnumType;
  37 +import javax.persistence.Enumerated;
  38 +import javax.persistence.Table;
  39 +import java.util.UUID;
  40 +
  41 +import static org.thingsboard.server.dao.model.ModelConstants.EDGE_EVENT_ACTION_PROPERTY;
  42 +import static org.thingsboard.server.dao.model.ModelConstants.EDGE_EVENT_COLUMN_FAMILY_NAME;
  43 +import static org.thingsboard.server.dao.model.ModelConstants.EDGE_EVENT_EDGE_ID_PROPERTY;
  44 +import static org.thingsboard.server.dao.model.ModelConstants.EDGE_EVENT_ENTITY_BODY_PROPERTY;
  45 +import static org.thingsboard.server.dao.model.ModelConstants.EDGE_EVENT_ENTITY_ID_PROPERTY;
  46 +import static org.thingsboard.server.dao.model.ModelConstants.EDGE_EVENT_TENANT_ID_PROPERTY;
  47 +import static org.thingsboard.server.dao.model.ModelConstants.EDGE_EVENT_TYPE_PROPERTY;
  48 +import static org.thingsboard.server.dao.model.ModelConstants.EPOCH_DIFF;
  49 +import static org.thingsboard.server.dao.model.ModelConstants.TS_COLUMN;
  50 +
  51 +@Data
  52 +@EqualsAndHashCode(callSuper = true)
  53 +@Entity
  54 +@TypeDef(name = "json", typeClass = JsonStringType.class)
  55 +@Table(name = EDGE_EVENT_COLUMN_FAMILY_NAME)
  56 +@NoArgsConstructor
  57 +public class EdgeEventEntity extends BaseSqlEntity<EdgeEvent> implements BaseEntity<EdgeEvent> {
  58 +
  59 + @Column(name = EDGE_EVENT_TENANT_ID_PROPERTY)
  60 + private String tenantId;
  61 +
  62 + @Column(name = EDGE_EVENT_EDGE_ID_PROPERTY)
  63 + private String edgeId;
  64 +
  65 + @Column(name = EDGE_EVENT_ENTITY_ID_PROPERTY)
  66 + private String entityId;
  67 +
  68 + @Enumerated(EnumType.STRING)
  69 + @Column(name = EDGE_EVENT_TYPE_PROPERTY)
  70 + private EdgeEventType edgeEventType;
  71 +
  72 + @Column(name = EDGE_EVENT_ACTION_PROPERTY)
  73 + private String edgeEventAction;
  74 +
  75 + @Type(type = "json")
  76 + @Column(name = EDGE_EVENT_ENTITY_BODY_PROPERTY)
  77 + private JsonNode entityBody;
  78 +
  79 + @Column(name = TS_COLUMN)
  80 + private long ts;
  81 +
  82 + public EdgeEventEntity(EdgeEvent edgeEvent) {
  83 + if (edgeEvent.getId() != null) {
  84 + this.setUuid(edgeEvent.getId().getId());
  85 + this.ts = getTs(edgeEvent.getId().getId());
  86 + } else {
  87 + this.ts = System.currentTimeMillis();
  88 + }
  89 + if (edgeEvent.getTenantId() != null) {
  90 + this.tenantId = toString(edgeEvent.getTenantId().getId());
  91 + }
  92 + if (edgeEvent.getEdgeId() != null) {
  93 + this.edgeId = toString(edgeEvent.getEdgeId().getId());
  94 + }
  95 + if (edgeEvent.getEntityId() != null) {
  96 + this.entityId = toString(edgeEvent.getEntityId());
  97 + }
  98 + this.edgeEventType = edgeEvent.getEdgeEventType();
  99 + this.edgeEventAction = edgeEvent.getEdgeEventAction();
  100 + this.entityBody = edgeEvent.getEntityBody();
  101 + }
  102 +
  103 + @Override
  104 + public EdgeEvent toData() {
  105 + EdgeEvent edgeEvent = new EdgeEvent(new EdgeEventId(this.getUuid()));
  106 + edgeEvent.setCreatedTime(UUIDs.unixTimestamp(this.getUuid()));
  107 + edgeEvent.setTenantId(new TenantId(toUUID(tenantId)));
  108 + edgeEvent.setEdgeId(new EdgeId(toUUID(edgeId)));
  109 + if (entityId != null) {
  110 + edgeEvent.setEntityId(toUUID(entityId));
  111 + }
  112 + edgeEvent.setEdgeEventType(edgeEventType);
  113 + edgeEvent.setEdgeEventAction(edgeEventAction);
  114 + edgeEvent.setEntityBody(entityBody);
  115 + return edgeEvent;
  116 + }
  117 +
  118 + private static long getTs(UUID uuid) {
  119 + return (uuid.timestamp() - EPOCH_DIFF) / 10000;
  120 + }
  121 +}
... ...
dao/src/main/java/org/thingsboard/server/dao/model/type/EdgeEventTypeCodec.java renamed from rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/edge/PushToEdgeNodeCallback.java
... ... @@ -13,29 +13,15 @@
13 13 * See the License for the specific language governing permissions and
14 14 * limitations under the License.
15 15 */
16   -package org.thingsboard.rule.engine.edge;
  16 +package org.thingsboard.server.dao.model.type;
17 17
18   -import com.google.common.util.concurrent.FutureCallback;
19   -import lombok.Data;
20   -import org.thingsboard.rule.engine.api.TbContext;
21   -import org.thingsboard.server.common.msg.TbMsg;
  18 +import com.datastax.driver.extras.codecs.enums.EnumNameCodec;
  19 +import org.thingsboard.server.common.data.edge.EdgeEventType;
22 20
23   -import javax.annotation.Nullable;
  21 +public class EdgeEventTypeCodec extends EnumNameCodec<EdgeEventType> {
24 22
25   -import static org.thingsboard.rule.engine.api.TbRelationTypes.SUCCESS;
26   -
27   -@Data
28   -class PushToEdgeNodeCallback implements FutureCallback<Void> {
29   - private final TbContext ctx;
30   - private final TbMsg msg;
31   -
32   - @Override
33   - public void onSuccess(@Nullable Void result) {
34   - ctx.tellNext(msg, SUCCESS);
  23 + public EdgeEventTypeCodec() {
  24 + super(EdgeEventType.class);
35 25 }
36 26
37   - @Override
38   - public void onFailure(Throwable t) {
39   - ctx.tellFailure(msg, t);
40   - }
41 27 }
... ...
... ... @@ -289,7 +289,7 @@ public class BaseRuleChainService extends AbstractEntityService implements RuleC
289 289
290 290 @Override
291 291 public RuleChain getRootTenantRuleChain(TenantId tenantId) {
292   - return getRootRuleChainByType(tenantId, RuleChainType.SYSTEM);
  292 + return getRootRuleChainByType(tenantId, RuleChainType.CORE);
293 293 }
294 294
295 295 private RuleChain getRootRuleChainByType(TenantId tenantId, RuleChainType type) {
... ... @@ -566,7 +566,7 @@ public class BaseRuleChainService extends AbstractEntityService implements RuleC
566 566 throw new DataValidationException("Rule chain name should be specified!");
567 567 }
568 568 if (ruleChain.getType() == null) {
569   - ruleChain.setType(RuleChainType.SYSTEM);
  569 + ruleChain.setType(RuleChainType.CORE);
570 570 }
571 571 if (ruleChain.getTenantId() == null || ruleChain.getTenantId().isNullUid()) {
572 572 throw new DataValidationException("Rule chain should be assigned to tenant!");
... ... @@ -575,7 +575,7 @@ public class BaseRuleChainService extends AbstractEntityService implements RuleC
575 575 if (tenant == null) {
576 576 throw new DataValidationException("Rule chain is referencing to non-existent tenant!");
577 577 }
578   - if (ruleChain.isRoot() && RuleChainType.SYSTEM.equals(ruleChain.getType())) {
  578 + if (ruleChain.isRoot() && RuleChainType.CORE.equals(ruleChain.getType())) {
579 579 RuleChain rootRuleChain = getRootTenantRuleChain(ruleChain.getTenantId());
580 580 if (rootRuleChain != null && !rootRuleChain.getId().equals(ruleChain.getId())) {
581 581 throw new DataValidationException("Another root rule chain is present in scope of current tenant!");
... ...
  1 +/**
  2 + * Copyright © 2016-2020 The Thingsboard Authors
  3 + *
  4 + * Licensed under the Apache License, Version 2.0 (the "License");
  5 + * you may not use this file except in compliance with the License.
  6 + * You may obtain a copy of the License at
  7 + *
  8 + * http://www.apache.org/licenses/LICENSE-2.0
  9 + *
  10 + * Unless required by applicable law or agreed to in writing, software
  11 + * distributed under the License is distributed on an "AS IS" BASIS,
  12 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13 + * See the License for the specific language governing permissions and
  14 + * limitations under the License.
  15 + */
  16 +package org.thingsboard.server.dao.sql.edge;
  17 +
  18 +import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
  19 +import org.springframework.data.repository.CrudRepository;
  20 +import org.thingsboard.server.dao.model.sql.EdgeEventEntity;
  21 +import org.thingsboard.server.dao.util.SqlDao;
  22 +
  23 +@SqlDao
  24 +public interface EdgeEventRepository extends CrudRepository<EdgeEventEntity, String>, JpaSpecificationExecutor<EdgeEventEntity> {
  25 +
  26 +}
... ...
  1 +/**
  2 + * Copyright © 2016-2020 The Thingsboard Authors
  3 + *
  4 + * Licensed under the Apache License, Version 2.0 (the "License");
  5 + * you may not use this file except in compliance with the License.
  6 + * You may obtain a copy of the License at
  7 + *
  8 + * http://www.apache.org/licenses/LICENSE-2.0
  9 + *
  10 + * Unless required by applicable law or agreed to in writing, software
  11 + * distributed under the License is distributed on an "AS IS" BASIS,
  12 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13 + * See the License for the specific language governing permissions and
  14 + * limitations under the License.
  15 + */
  16 +package org.thingsboard.server.dao.sql.edge;
  17 +
  18 +import com.datastax.driver.core.utils.UUIDs;
  19 +import com.google.common.util.concurrent.ListenableFuture;
  20 +import lombok.extern.slf4j.Slf4j;
  21 +import org.springframework.beans.factory.annotation.Autowired;
  22 +import org.springframework.data.domain.PageRequest;
  23 +import org.springframework.data.domain.Pageable;
  24 +import org.springframework.data.domain.Sort;
  25 +import org.springframework.data.jpa.domain.Specification;
  26 +import org.springframework.data.repository.CrudRepository;
  27 +import org.springframework.stereotype.Component;
  28 +import org.thingsboard.server.common.data.UUIDConverter;
  29 +import org.thingsboard.server.common.data.edge.EdgeEvent;
  30 +import org.thingsboard.server.common.data.id.EdgeEventId;
  31 +import org.thingsboard.server.common.data.id.EdgeId;
  32 +import org.thingsboard.server.common.data.page.TimePageLink;
  33 +import org.thingsboard.server.dao.DaoUtil;
  34 +import org.thingsboard.server.dao.edge.EdgeEventDao;
  35 +import org.thingsboard.server.dao.model.sql.EdgeEventEntity;
  36 +import org.thingsboard.server.dao.sql.JpaAbstractSearchTimeDao;
  37 +import org.thingsboard.server.dao.util.SqlDao;
  38 +
  39 +import javax.persistence.criteria.Predicate;
  40 +import java.util.ArrayList;
  41 +import java.util.List;
  42 +import java.util.Optional;
  43 +import java.util.UUID;
  44 +
  45 +import static org.thingsboard.server.dao.model.ModelConstants.ID_PROPERTY;
  46 +import static org.thingsboard.server.dao.model.ModelConstants.NULL_UUID;
  47 +
  48 +@Slf4j
  49 +@Component
  50 +@SqlDao
  51 +public class JpaBaseEdgeEventDao extends JpaAbstractSearchTimeDao<EdgeEventEntity, EdgeEvent> implements EdgeEventDao {
  52 +
  53 + private final UUID systemTenantId = NULL_UUID;
  54 +
  55 + @Autowired
  56 + private EdgeEventRepository edgeEventRepository;
  57 +
  58 + @Override
  59 + protected Class<EdgeEventEntity> getEntityClass() {
  60 + return EdgeEventEntity.class;
  61 + }
  62 +
  63 + @Override
  64 + protected CrudRepository<EdgeEventEntity, String> getCrudRepository() {
  65 + return edgeEventRepository;
  66 + }
  67 +
  68 + @Override
  69 + public ListenableFuture<EdgeEvent> saveAsync(EdgeEvent edgeEvent) {
  70 + log.debug("Save edge event [{}] ", edgeEvent);
  71 + if (edgeEvent.getId() == null) {
  72 + edgeEvent.setId(new EdgeEventId(UUIDs.timeBased()));
  73 + }
  74 + return service.submit(() -> save(new EdgeEventEntity(edgeEvent)).orElse(null));
  75 + }
  76 +
  77 + @Override
  78 + public List<EdgeEvent> findEdgeEvents(UUID tenantId, EdgeId edgeId, TimePageLink pageLink) {
  79 + Specification<EdgeEventEntity> timeSearchSpec = JpaAbstractSearchTimeDao.getTimeSearchPageSpec(pageLink, "id");
  80 + Specification<EdgeEventEntity> fieldsSpec = getEntityFieldsSpec(tenantId, edgeId);
  81 + Sort.Direction sortDirection = pageLink.isAscOrder() ? Sort.Direction.ASC : Sort.Direction.DESC;
  82 + Pageable pageable = PageRequest.of(0, pageLink.getLimit(), sortDirection, ID_PROPERTY);
  83 + return DaoUtil.convertDataList(edgeEventRepository.findAll(Specification.where(timeSearchSpec).and(fieldsSpec), pageable).getContent());
  84 + }
  85 +
  86 + public Optional<EdgeEvent> save(EdgeEventEntity entity) {
  87 + log.debug("Save edge event [{}] ", entity);
  88 + if (entity.getTenantId() == null) {
  89 + log.trace("Save system edge event with predefined id {}", systemTenantId);
  90 + entity.setTenantId(UUIDConverter.fromTimeUUID(systemTenantId));
  91 + }
  92 + if (entity.getUuid() == null) {
  93 + entity.setUuid(UUIDs.timeBased());
  94 + }
  95 + return Optional.of(DaoUtil.getData(edgeEventRepository.save(entity)));
  96 + }
  97 +
  98 + private Specification<EdgeEventEntity> getEntityFieldsSpec(UUID tenantId, EdgeId edgeId) {
  99 + return (root, criteriaQuery, criteriaBuilder) -> {
  100 + List<Predicate> predicates = new ArrayList<>();
  101 + if (tenantId != null) {
  102 + Predicate tenantIdPredicate = criteriaBuilder.equal(root.get("tenantId"), UUIDConverter.fromTimeUUID(tenantId));
  103 + predicates.add(tenantIdPredicate);
  104 + }
  105 + if (edgeId != null) {
  106 + Predicate entityIdPredicate = criteriaBuilder.equal(root.get("edgeId"), UUIDConverter.fromTimeUUID(edgeId.getId()));
  107 + predicates.add(entityIdPredicate);
  108 + }
  109 + return criteriaBuilder.and(predicates.toArray(new Predicate[]{}));
  110 + };
  111 + }
  112 +}
... ...
... ... @@ -270,3 +270,14 @@ CREATE TABLE IF NOT EXISTS edge (
270 270 CONSTRAINT edge_name_unq_key UNIQUE (tenant_id, name),
271 271 CONSTRAINT edge_routing_key_unq_key UNIQUE (routing_key)
272 272 );
  273 +
  274 +CREATE TABLE IF NOT EXISTS edge_event (
  275 + id varchar(31) NOT NULL CONSTRAINT edge_event_pkey PRIMARY KEY,
  276 + edge_id varchar(31),
  277 + edge_event_type varchar(255),
  278 + entity_id varchar(31),
  279 + edge_event_action varchar(255),
  280 + entity_body varchar(10000000),
  281 + tenant_id varchar(31),
  282 + ts bigint NOT NULL
  283 +);
\ No newline at end of file
... ...
... ... @@ -271,6 +271,18 @@ CREATE TABLE IF NOT EXISTS edge (
271 271 CONSTRAINT edge_routing_key_unq_key UNIQUE (routing_key)
272 272 );
273 273
  274 +CREATE TABLE IF NOT EXISTS edge_event (
  275 + id varchar(31) NOT NULL CONSTRAINT edge_event_pkey PRIMARY KEY,
  276 + edge_id varchar(31),
  277 + edge_event_type varchar(255),
  278 + entity_id varchar(31),
  279 + edge_event_action varchar(255),
  280 + entity_body varchar(10000000),
  281 + tenant_id varchar(31),
  282 + ts bigint NOT NULL
  283 +);
  284 +
  285 +
274 286 CREATE OR REPLACE PROCEDURE cleanup_events_by_ttl(IN ttl bigint, IN debug_ttl bigint, INOUT deleted bigint)
275 287 LANGUAGE plpgsql AS
276 288 $$
... ...
... ... @@ -45,6 +45,7 @@ import org.thingsboard.server.dao.customer.CustomerService;
45 45 import org.thingsboard.server.dao.dashboard.DashboardService;
46 46 import org.thingsboard.server.dao.device.DeviceCredentialsService;
47 47 import org.thingsboard.server.dao.device.DeviceService;
  48 +import org.thingsboard.server.dao.edge.EdgeEventService;
48 49 import org.thingsboard.server.dao.edge.EdgeService;
49 50 import org.thingsboard.server.dao.entityview.EntityViewService;
50 51 import org.thingsboard.server.dao.event.EventService;
... ... @@ -126,6 +127,9 @@ public abstract class AbstractServiceTest {
126 127 protected EdgeService edgeService;
127 128
128 129 @Autowired
  130 + protected EdgeEventService edgeEventService;
  131 +
  132 + @Autowired
129 133 private ComponentDescriptorService componentDescriptorService;
130 134
131 135 class IdComparator<D extends BaseData<? extends UUIDBased>> implements Comparator<D> {
... ...
  1 +/**
  2 + * Copyright © 2016-2020 The Thingsboard Authors
  3 + *
  4 + * Licensed under the Apache License, Version 2.0 (the "License");
  5 + * you may not use this file except in compliance with the License.
  6 + * You may obtain a copy of the License at
  7 + *
  8 + * http://www.apache.org/licenses/LICENSE-2.0
  9 + *
  10 + * Unless required by applicable law or agreed to in writing, software
  11 + * distributed under the License is distributed on an "AS IS" BASIS,
  12 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13 + * See the License for the specific language governing permissions and
  14 + * limitations under the License.
  15 + */
  16 +package org.thingsboard.server.dao.service;
  17 +
  18 +import com.datastax.driver.core.utils.UUIDs;
  19 +import org.junit.Assert;
  20 +import org.junit.Test;
  21 +import org.thingsboard.server.common.data.DataConstants;
  22 +import org.thingsboard.server.common.data.edge.EdgeEvent;
  23 +import org.thingsboard.server.common.data.edge.EdgeEventType;
  24 +import org.thingsboard.server.common.data.id.DeviceId;
  25 +import org.thingsboard.server.common.data.id.EdgeEventId;
  26 +import org.thingsboard.server.common.data.id.EdgeId;
  27 +import org.thingsboard.server.common.data.id.EntityId;
  28 +import org.thingsboard.server.common.data.id.TenantId;
  29 +import org.thingsboard.server.common.data.page.TimePageData;
  30 +import org.thingsboard.server.common.data.page.TimePageLink;
  31 +
  32 +import java.io.IOException;
  33 +import java.time.LocalDateTime;
  34 +import java.time.Month;
  35 +import java.time.ZoneOffset;
  36 +
  37 +public abstract class BaseEdgeEventServiceTest extends AbstractServiceTest {
  38 +
  39 + @Test
  40 + public void saveEdgeEvent() throws Exception {
  41 + EdgeId edgeId = new EdgeId(UUIDs.timeBased());
  42 + DeviceId deviceId = new DeviceId(UUIDs.timeBased());
  43 + EdgeEvent edgeEvent = generateEdgeEvent(null, edgeId, deviceId, DataConstants.ENTITY_CREATED);
  44 + EdgeEvent saved = edgeEventService.saveAsync(edgeEvent).get();
  45 + Assert.assertEquals(saved.getTenantId(), edgeEvent.getTenantId());
  46 + Assert.assertEquals(saved.getEdgeId(), edgeEvent.getEdgeId());
  47 + Assert.assertEquals(saved.getEntityId(), edgeEvent.getEntityId());
  48 + Assert.assertEquals(saved.getEdgeEventType(), edgeEvent.getEdgeEventType());
  49 + Assert.assertEquals(saved.getEdgeEventAction(), edgeEvent.getEdgeEventAction());
  50 + Assert.assertEquals(saved.getEntityBody(), edgeEvent.getEntityBody());
  51 + }
  52 +
  53 + protected EdgeEvent generateEdgeEvent(TenantId tenantId, EdgeId edgeId, EntityId entityId, String edgeEventAction) throws IOException {
  54 + if (tenantId == null) {
  55 + tenantId = new TenantId(UUIDs.timeBased());
  56 + }
  57 + EdgeEvent edgeEvent = new EdgeEvent();
  58 + edgeEvent.setTenantId(tenantId);
  59 + edgeEvent.setEdgeId(edgeId);
  60 + edgeEvent.setEntityId(entityId.getId());
  61 + edgeEvent.setEdgeEventType(EdgeEventType.DEVICE);
  62 + edgeEvent.setEdgeEventAction(edgeEventAction);
  63 + edgeEvent.setEntityBody(readFromResource("TestJsonData.json"));
  64 + return edgeEvent;
  65 + }
  66 +
  67 +
  68 + @Test
  69 + public void findEdgeEventsByTimeDescOrder() throws Exception {
  70 + long timeBeforeStartTime = LocalDateTime.of(2020, Month.NOVEMBER, 1, 11, 30).toEpochSecond(ZoneOffset.UTC);
  71 + long startTime = LocalDateTime.of(2020, Month.NOVEMBER, 1, 12, 0).toEpochSecond(ZoneOffset.UTC);
  72 + long eventTime = LocalDateTime.of(2020, Month.NOVEMBER, 1, 12, 30).toEpochSecond(ZoneOffset.UTC);
  73 + long endTime = LocalDateTime.of(2020, Month.NOVEMBER, 1, 13, 0).toEpochSecond(ZoneOffset.UTC);
  74 + long timeAfterEndTime = LocalDateTime.of(2020, Month.NOVEMBER, 1, 13, 30).toEpochSecond(ZoneOffset.UTC);
  75 +
  76 + EdgeId edgeId = new EdgeId(UUIDs.timeBased());
  77 + DeviceId deviceId = new DeviceId(UUIDs.timeBased());
  78 + TenantId tenantId = new TenantId(UUIDs.timeBased());
  79 + saveEdgeEventWithProvidedTime(timeBeforeStartTime, edgeId, deviceId, tenantId);
  80 + EdgeEvent savedEdgeEvent = saveEdgeEventWithProvidedTime(eventTime, edgeId, deviceId, tenantId);
  81 + EdgeEvent savedEdgeEvent2 = saveEdgeEventWithProvidedTime(eventTime + 1, edgeId, deviceId, tenantId);
  82 + EdgeEvent savedEdgeEvent3 = saveEdgeEventWithProvidedTime(eventTime + 2, edgeId, deviceId, tenantId);
  83 + saveEdgeEventWithProvidedTime(timeAfterEndTime, edgeId, deviceId, tenantId);
  84 +
  85 + TimePageData<EdgeEvent> edgeEvents = edgeEventService.findEdgeEvents(tenantId, edgeId, new TimePageLink(2, startTime, endTime, false));
  86 +
  87 + Assert.assertNotNull(edgeEvents.getData());
  88 + Assert.assertTrue(edgeEvents.getData().size() == 2);
  89 + Assert.assertTrue(edgeEvents.getData().get(0).getUuidId().equals(savedEdgeEvent3.getUuidId()));
  90 + Assert.assertTrue(edgeEvents.getData().get(1).getUuidId().equals(savedEdgeEvent2.getUuidId()));
  91 + Assert.assertTrue(edgeEvents.hasNext());
  92 + Assert.assertNotNull(edgeEvents.getNextPageLink());
  93 +
  94 + edgeEvents = edgeEventService.findEdgeEvents(tenantId, edgeId, edgeEvents.getNextPageLink());
  95 +
  96 + Assert.assertNotNull(edgeEvents.getData());
  97 + Assert.assertTrue(edgeEvents.getData().size() == 1);
  98 + Assert.assertTrue(edgeEvents.getData().get(0).getUuidId().equals(savedEdgeEvent.getUuidId()));
  99 + Assert.assertFalse(edgeEvents.hasNext());
  100 + Assert.assertNull(edgeEvents.getNextPageLink());
  101 + }
  102 +
  103 + private EdgeEvent saveEdgeEventWithProvidedTime(long time, EdgeId edgeId, EntityId entityId, TenantId tenantId) throws Exception {
  104 + EdgeEvent edgeEvent = generateEdgeEvent(tenantId, edgeId, entityId, DataConstants.ENTITY_CREATED);
  105 + edgeEvent.setId(new EdgeEventId(UUIDs.startOf(time)));
  106 + return edgeEventService.saveAsync(edgeEvent).get();
  107 + }
  108 +}
\ No newline at end of file
... ...
dao/src/test/java/org/thingsboard/server/dao/service/BaseEdgeServiceTest.java renamed from dao/src/test/java/org/thingsboard/server/dao/service/EdgeServiceImplTest.java
... ... @@ -37,7 +37,7 @@ import java.util.List;
37 37
38 38 import static org.thingsboard.server.dao.model.ModelConstants.NULL_UUID;
39 39
40   -public abstract class EdgeServiceImplTest extends AbstractServiceTest {
  40 +public abstract class BaseEdgeServiceTest extends AbstractServiceTest {
41 41
42 42 private IdComparator<Edge> idComparator = new IdComparator<>();
43 43
... ...
... ... @@ -145,7 +145,7 @@ public abstract class BaseRuleChainServiceTest extends AbstractServiceTest {
145 145 TextPageLink pageLink = new TextPageLink(16);
146 146 TextPageData<RuleChain> pageData = null;
147 147 do {
148   - pageData = ruleChainService.findTenantRuleChainsByType(tenantId, RuleChainType.SYSTEM, pageLink);
  148 + pageData = ruleChainService.findTenantRuleChainsByType(tenantId, RuleChainType.CORE, pageLink);
149 149 loadedRuleChains.addAll(pageData.getData());
150 150 if (pageData.hasNext()) {
151 151 pageLink = pageData.getNextPageLink();
... ... @@ -160,7 +160,7 @@ public abstract class BaseRuleChainServiceTest extends AbstractServiceTest {
160 160 ruleChainService.deleteRuleChainsByTenantId(tenantId);
161 161
162 162 pageLink = new TextPageLink(31);
163   - pageData = ruleChainService.findTenantRuleChainsByType(tenantId, RuleChainType.SYSTEM, pageLink);
  163 + pageData = ruleChainService.findTenantRuleChainsByType(tenantId, RuleChainType.CORE, pageLink);
164 164 Assert.assertFalse(pageData.hasNext());
165 165 Assert.assertTrue(pageData.getData().isEmpty());
166 166
... ... @@ -196,7 +196,7 @@ public abstract class BaseRuleChainServiceTest extends AbstractServiceTest {
196 196 TextPageLink pageLink = new TextPageLink(19, name1);
197 197 TextPageData<RuleChain> pageData = null;
198 198 do {
199   - pageData = ruleChainService.findTenantRuleChainsByType(tenantId, RuleChainType.SYSTEM, pageLink);
  199 + pageData = ruleChainService.findTenantRuleChainsByType(tenantId, RuleChainType.CORE, pageLink);
200 200 loadedRuleChainsName1.addAll(pageData.getData());
201 201 if (pageData.hasNext()) {
202 202 pageLink = pageData.getNextPageLink();
... ... @@ -211,7 +211,7 @@ public abstract class BaseRuleChainServiceTest extends AbstractServiceTest {
211 211 List<RuleChain> loadedRuleChainsName2 = new ArrayList<>();
212 212 pageLink = new TextPageLink(4, name2);
213 213 do {
214   - pageData = ruleChainService.findTenantRuleChainsByType(tenantId, RuleChainType.SYSTEM, pageLink);
  214 + pageData = ruleChainService.findTenantRuleChainsByType(tenantId, RuleChainType.CORE, pageLink);
215 215 loadedRuleChainsName2.addAll(pageData.getData());
216 216 if (pageData.hasNext()) {
217 217 pageLink = pageData.getNextPageLink();
... ... @@ -228,7 +228,7 @@ public abstract class BaseRuleChainServiceTest extends AbstractServiceTest {
228 228 }
229 229
230 230 pageLink = new TextPageLink(4, name1);
231   - pageData = ruleChainService.findTenantRuleChainsByType(tenantId, RuleChainType.SYSTEM, pageLink);
  231 + pageData = ruleChainService.findTenantRuleChainsByType(tenantId, RuleChainType.CORE, pageLink);
232 232 Assert.assertFalse(pageData.hasNext());
233 233 Assert.assertEquals(0, pageData.getData().size());
234 234
... ... @@ -237,7 +237,7 @@ public abstract class BaseRuleChainServiceTest extends AbstractServiceTest {
237 237 }
238 238
239 239 pageLink = new TextPageLink(4, name2);
240   - pageData = ruleChainService.findTenantRuleChainsByType(tenantId, RuleChainType.SYSTEM, pageLink);
  240 + pageData = ruleChainService.findTenantRuleChainsByType(tenantId, RuleChainType.CORE, pageLink);
241 241 Assert.assertFalse(pageData.hasNext());
242 242 Assert.assertEquals(0, pageData.getData().size());
243 243 }
... ...
dao/src/test/java/org/thingsboard/server/dao/service/nosql/EdgeEventServiceNoSqlTest.java renamed from common/data/src/main/java/org/thingsboard/server/common/data/edge/EdgeQueueEntry.java
... ... @@ -13,13 +13,11 @@
13 13 * See the License for the specific language governing permissions and
14 14 * limitations under the License.
15 15 */
16   -package org.thingsboard.server.common.data.edge;
  16 +package org.thingsboard.server.dao.service.nosql;
17 17
18   -import lombok.Data;
  18 +import org.thingsboard.server.dao.service.BaseEdgeEventServiceTest;
  19 +import org.thingsboard.server.dao.service.DaoNoSqlTest;
19 20
20   -@Data
21   -public class EdgeQueueEntry {
22   - private String type;
23   - private EdgeQueueEntityType entityType;
24   - private String data;
  21 +@DaoNoSqlTest
  22 +public class EdgeEventServiceNoSqlTest extends BaseEdgeEventServiceTest {
25 23 }
... ...
... ... @@ -15,9 +15,9 @@
15 15 */
16 16 package org.thingsboard.server.dao.service.nosql;
17 17
18   -import org.thingsboard.server.dao.service.EdgeServiceImplTest;
  18 +import org.thingsboard.server.dao.service.BaseEdgeServiceTest;
19 19 import org.thingsboard.server.dao.service.DaoNoSqlTest;
20 20
21 21 @DaoNoSqlTest
22   -public class EdgeServiceNoSqlTest extends EdgeServiceImplTest {
  22 +public class EdgeServiceNoSqlTest extends BaseEdgeServiceTest {
23 23 }
... ...
  1 +/**
  2 + * Copyright © 2016-2020 The Thingsboard Authors
  3 + *
  4 + * Licensed under the Apache License, Version 2.0 (the "License");
  5 + * you may not use this file except in compliance with the License.
  6 + * You may obtain a copy of the License at
  7 + *
  8 + * http://www.apache.org/licenses/LICENSE-2.0
  9 + *
  10 + * Unless required by applicable law or agreed to in writing, software
  11 + * distributed under the License is distributed on an "AS IS" BASIS,
  12 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13 + * See the License for the specific language governing permissions and
  14 + * limitations under the License.
  15 + */
  16 +package org.thingsboard.server.dao.service.sql;
  17 +
  18 +import org.thingsboard.server.dao.service.BaseEdgeEventServiceTest;
  19 +import org.thingsboard.server.dao.service.DaoSqlTest;
  20 +
  21 +@DaoSqlTest
  22 +public class EdgeEventServiceSqlTest extends BaseEdgeEventServiceTest {
  23 +}
... ...
... ... @@ -15,9 +15,9 @@
15 15 */
16 16 package org.thingsboard.server.dao.service.sql;
17 17
18   -import org.thingsboard.server.dao.service.EdgeServiceImplTest;
  18 +import org.thingsboard.server.dao.service.BaseEdgeServiceTest;
19 19 import org.thingsboard.server.dao.service.DaoSqlTest;
20 20
21 21 @DaoSqlTest
22   -public class EdgeServiceSqlTest extends EdgeServiceImplTest {
  22 +public class EdgeServiceSqlTest extends BaseEdgeServiceTest {
23 23 }
... ...
... ... @@ -20,4 +20,5 @@ DROP TABLE IF EXISTS widgets_bundle;
20 20 DROP TABLE IF EXISTS rule_node;
21 21 DROP TABLE IF EXISTS rule_chain;
22 22 DROP TABLE IF EXISTS entity_view;
23   -DROP TABLE IF EXISTS edge;
\ No newline at end of file
  23 +DROP TABLE IF EXISTS edge;
  24 +DROP TABLE IF EXISTS edge_event;
\ No newline at end of file
... ...
... ... @@ -58,6 +58,6 @@ public @interface RuleNode {
58 58
59 59 boolean customRelations() default false;
60 60
61   - RuleChainType[] ruleChainTypes() default RuleChainType.SYSTEM;
  61 + RuleChainType[] ruleChainTypes() default RuleChainType.CORE;
62 62
63 63 }
... ...
... ... @@ -35,6 +35,7 @@ import org.thingsboard.server.dao.cassandra.CassandraCluster;
35 35 import org.thingsboard.server.dao.customer.CustomerService;
36 36 import org.thingsboard.server.dao.dashboard.DashboardService;
37 37 import org.thingsboard.server.dao.device.DeviceService;
  38 +import org.thingsboard.server.dao.edge.EdgeEventService;
38 39 import org.thingsboard.server.dao.edge.EdgeService;
39 40 import org.thingsboard.server.dao.entityview.EntityViewService;
40 41 import org.thingsboard.server.dao.nosql.CassandraStatementTask;
... ... @@ -190,6 +191,8 @@ public interface TbContext {
190 191
191 192 EdgeService getEdgeService();
192 193
  194 + EdgeEventService getEdgeEventService();
  195 +
193 196 ListeningExecutor getJsExecutor();
194 197
195 198 ListeningExecutor getMailExecutor();
... ...
... ... @@ -38,7 +38,7 @@ import org.thingsboard.server.common.msg.TbMsg;
38 38 uiResources = {"static/rulenode/rulenode-core-config.js"},
39 39 configDirective = "tbActionNodeAssignToCustomerConfig",
40 40 icon = "add_circle",
41   - ruleChainTypes = {RuleChainType.SYSTEM, RuleChainType.EDGE}
  41 + ruleChainTypes = {RuleChainType.CORE, RuleChainType.EDGE}
42 42 )
43 43 public class TbAssignToCustomerNode extends TbAbstractCustomerActionNode<TbAssignToCustomerNodeConfiguration> {
44 44
... ...
... ... @@ -46,7 +46,7 @@ import org.thingsboard.server.common.msg.TbMsg;
46 46 uiResources = {"static/rulenode/rulenode-core-config.js"},
47 47 configDirective = "tbActionNodeClearAlarmConfig",
48 48 icon = "notifications_off",
49   - ruleChainTypes = {RuleChainType.SYSTEM, RuleChainType.EDGE}
  49 + ruleChainTypes = {RuleChainType.CORE, RuleChainType.EDGE}
50 50 )
51 51 public class TbClearAlarmNode extends TbAbstractAlarmNode<TbClearAlarmNodeConfiguration> {
52 52
... ...
... ... @@ -58,7 +58,7 @@ import static org.thingsboard.rule.engine.api.TbRelationTypes.SUCCESS;
58 58 uiResources = {"static/rulenode/rulenode-core-config.js"},
59 59 configDirective = "tbNodeEmptyConfig",
60 60 icon = "content_copy",
61   - ruleChainTypes = {RuleChainType.SYSTEM, RuleChainType.EDGE}
  61 + ruleChainTypes = {RuleChainType.CORE, RuleChainType.EDGE}
62 62 )
63 63 public class TbCopyAttributesToEntityViewNode implements TbNode {
64 64
... ...
... ... @@ -52,7 +52,7 @@ import java.util.List;
52 52 uiResources = {"static/rulenode/rulenode-core-config.js"},
53 53 configDirective = "tbActionNodeCreateAlarmConfig",
54 54 icon = "notifications_active",
55   - ruleChainTypes = {RuleChainType.SYSTEM, RuleChainType.EDGE}
  55 + ruleChainTypes = {RuleChainType.CORE, RuleChainType.EDGE}
56 56 )
57 57 public class TbCreateAlarmNode extends TbAbstractAlarmNode<TbCreateAlarmNodeConfiguration> {
58 58
... ...
... ... @@ -55,7 +55,7 @@ import java.util.List;
55 55 uiResources = {"static/rulenode/rulenode-core-config.js"},
56 56 configDirective = "tbActionNodeCreateRelationConfig",
57 57 icon = "add_circle",
58   - ruleChainTypes = {RuleChainType.SYSTEM, RuleChainType.EDGE}
  58 + ruleChainTypes = {RuleChainType.CORE, RuleChainType.EDGE}
59 59 )
60 60 public class TbCreateRelationNode extends TbAbstractRelationActionNode<TbCreateRelationNodeConfiguration> {
61 61
... ...
... ... @@ -45,7 +45,7 @@ import java.util.List;
45 45 uiResources = {"static/rulenode/rulenode-core-config.js"},
46 46 configDirective = "tbActionNodeDeleteRelationConfig",
47 47 icon = "remove_circle",
48   - ruleChainTypes = {RuleChainType.SYSTEM, RuleChainType.EDGE}
  48 + ruleChainTypes = {RuleChainType.CORE, RuleChainType.EDGE}
49 49 )
50 50 public class TbDeleteRelationNode extends TbAbstractRelationActionNode<TbDeleteRelationNodeConfiguration> {
51 51
... ...
... ... @@ -38,7 +38,7 @@ import static org.thingsboard.rule.engine.api.TbRelationTypes.SUCCESS;
38 38 uiResources = {"static/rulenode/rulenode-core-config.js"},
39 39 configDirective = "tbActionNodeLogConfig",
40 40 icon = "menu",
41   - ruleChainTypes = {RuleChainType.SYSTEM, RuleChainType.EDGE}
  41 + ruleChainTypes = {RuleChainType.CORE, RuleChainType.EDGE}
42 42 )
43 43
44 44 public class TbLogNode implements TbNode {
... ...
... ... @@ -44,7 +44,7 @@ import static org.thingsboard.rule.engine.api.TbRelationTypes.SUCCESS;
44 44 icon = "functions",
45 45 uiResources = {"static/rulenode/rulenode-core-config.js"},
46 46 configDirective = "tbActionNodeMsgCountConfig",
47   - ruleChainTypes = {RuleChainType.SYSTEM, RuleChainType.EDGE}
  47 + ruleChainTypes = {RuleChainType.CORE, RuleChainType.EDGE}
48 48 )
49 49 public class TbMsgCountNode implements TbNode {
50 50
... ...
... ... @@ -35,7 +35,7 @@ import org.thingsboard.server.common.msg.TbMsg;
35 35 uiResources = {"static/rulenode/rulenode-core-config.js"},
36 36 configDirective = "tbActionNodeUnAssignToCustomerConfig",
37 37 icon = "remove_circle",
38   - ruleChainTypes = {RuleChainType.SYSTEM, RuleChainType.EDGE}
  38 + ruleChainTypes = {RuleChainType.CORE, RuleChainType.EDGE}
39 39 )
40 40 public class TbUnassignFromCustomerNode extends TbAbstractCustomerActionNode<TbUnassignFromCustomerNodeConfiguration> {
41 41
... ...
... ... @@ -47,7 +47,7 @@ import static org.thingsboard.common.util.DonAsynchron.withCallback;
47 47 uiResources = {"static/rulenode/rulenode-core-config.js"},
48 48 configDirective = "tbActionNodeSnsConfig",
49 49 iconUrl = "data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNCAyNCIgd2lkdGg9IjQ4IiBoZWlnaHQ9IjQ4Ij48cGF0aCBkPSJNMTMuMjMgMTAuNTZWMTBjLTEuOTQgMC0zLjk5LjM5LTMuOTkgMi42NyAwIDEuMTYuNjEgMS45NSAxLjYzIDEuOTUuNzYgMCAxLjQzLS40NyAxLjg2LTEuMjIuNTItLjkzLjUtMS44LjUtMi44NG0yLjcgNi41M2MtLjE4LjE2LS40My4xNy0uNjMuMDYtLjg5LS43NC0xLjA1LTEuMDgtMS41NC0xLjc5LTEuNDcgMS41LTIuNTEgMS45NS00LjQyIDEuOTUtMi4yNSAwLTQuMDEtMS4zOS00LjAxLTQuMTcgMC0yLjE4IDEuMTctMy42NCAyLjg2LTQuMzggMS40Ni0uNjQgMy40OS0uNzYgNS4wNC0uOTNWNy41YzAtLjY2LjA1LTEuNDEtLjMzLTEuOTYtLjMyLS40OS0uOTUtLjctMS41LS43LTEuMDIgMC0xLjkzLjUzLTIuMTUgMS42MS0uMDUuMjQtLjI1LjQ4LS40Ny40OWwtMi42LS4yOGMtLjIyLS4wNS0uNDYtLjIyLS40LS41Ni42LTMuMTUgMy40NS00LjEgNi00LjEgMS4zIDAgMyAuMzUgNC4wMyAxLjMzQzE3LjExIDQuNTUgMTcgNi4xOCAxNyA3Ljk1djQuMTdjMCAxLjI1LjUgMS44MSAxIDIuNDguMTcuMjUuMjEuNTQgMCAuNzFsLTIuMDYgMS43OGgtLjAxIj48L3BhdGg+PHBhdGggZD0iTTIwLjE2IDE5LjU0QzE4IDIxLjE0IDE0LjgyIDIyIDEyLjEgMjJjLTMuODEgMC03LjI1LTEuNDEtOS44NS0zLjc2LS4yLS4xOC0uMDItLjQzLjI1LS4yOSAyLjc4IDEuNjMgNi4yNSAyLjYxIDkuODMgMi42MSAyLjQxIDAgNS4wNy0uNSA3LjUxLTEuNTMuMzctLjE2LjY2LjI0LjMyLjUxIj48L3BhdGg+PHBhdGggZD0iTTIxLjA3IDE4LjVjLS4yOC0uMzYtMS44NS0uMTctMi41Ny0uMDgtLjE5LjAyLS4yMi0uMTYtLjAzLS4zIDEuMjQtLjg4IDMuMjktLjYyIDMuNTMtLjMzLjI0LjMtLjA3IDIuMzUtMS4yNCAzLjMyLS4xOC4xNi0uMzUuMDctLjI2LS4xMS4yNi0uNjcuODUtMi4xNC41Ny0yLjV6Ij48L3BhdGg+PC9zdmc+",
50   - ruleChainTypes = {RuleChainType.SYSTEM, RuleChainType.EDGE}
  50 + ruleChainTypes = {RuleChainType.CORE, RuleChainType.EDGE}
51 51 )
52 52 public class TbSnsNode implements TbNode {
53 53
... ...
... ... @@ -52,7 +52,7 @@ import static org.thingsboard.common.util.DonAsynchron.withCallback;
52 52 uiResources = {"static/rulenode/rulenode-core-config.js"},
53 53 configDirective = "tbActionNodeSqsConfig",
54 54 iconUrl = "data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNCAyNCIgd2lkdGg9IjQ4IiBoZWlnaHQ9IjQ4Ij48cGF0aCBkPSJNMTMuMjMgMTAuNTZWMTBjLTEuOTQgMC0zLjk5LjM5LTMuOTkgMi42NyAwIDEuMTYuNjEgMS45NSAxLjYzIDEuOTUuNzYgMCAxLjQzLS40NyAxLjg2LTEuMjIuNTItLjkzLjUtMS44LjUtMi44NG0yLjcgNi41M2MtLjE4LjE2LS40My4xNy0uNjMuMDYtLjg5LS43NC0xLjA1LTEuMDgtMS41NC0xLjc5LTEuNDcgMS41LTIuNTEgMS45NS00LjQyIDEuOTUtMi4yNSAwLTQuMDEtMS4zOS00LjAxLTQuMTcgMC0yLjE4IDEuMTctMy42NCAyLjg2LTQuMzggMS40Ni0uNjQgMy40OS0uNzYgNS4wNC0uOTNWNy41YzAtLjY2LjA1LTEuNDEtLjMzLTEuOTYtLjMyLS40OS0uOTUtLjctMS41LS43LTEuMDIgMC0xLjkzLjUzLTIuMTUgMS42MS0uMDUuMjQtLjI1LjQ4LS40Ny40OWwtMi42LS4yOGMtLjIyLS4wNS0uNDYtLjIyLS40LS41Ni42LTMuMTUgMy40NS00LjEgNi00LjEgMS4zIDAgMyAuMzUgNC4wMyAxLjMzQzE3LjExIDQuNTUgMTcgNi4xOCAxNyA3Ljk1djQuMTdjMCAxLjI1LjUgMS44MSAxIDIuNDguMTcuMjUuMjEuNTQgMCAuNzFsLTIuMDYgMS43OGgtLjAxIj48L3BhdGg+PHBhdGggZD0iTTIwLjE2IDE5LjU0QzE4IDIxLjE0IDE0LjgyIDIyIDEyLjEgMjJjLTMuODEgMC03LjI1LTEuNDEtOS44NS0zLjc2LS4yLS4xOC0uMDItLjQzLjI1LS4yOSAyLjc4IDEuNjMgNi4yNSAyLjYxIDkuODMgMi42MSAyLjQxIDAgNS4wNy0uNSA3LjUxLTEuNTMuMzctLjE2LjY2LjI0LjMyLjUxIj48L3BhdGg+PHBhdGggZD0iTTIxLjA3IDE4LjVjLS4yOC0uMzYtMS44NS0uMTctMi41Ny0uMDgtLjE5LjAyLS4yMi0uMTYtLjAzLS4zIDEuMjQtLjg4IDMuMjktLjYyIDMuNTMtLjMzLjI0LjMtLjA3IDIuMzUtMS4yNCAzLjMyLS4xOC4xNi0uMzUuMDctLjI2LS4xMS4yNi0uNjcuODUtMi4xNC41Ny0yLjV6Ij48L3BhdGg+PC9zdmc+",
55   - ruleChainTypes = {RuleChainType.SYSTEM, RuleChainType.EDGE}
  55 + ruleChainTypes = {RuleChainType.CORE, RuleChainType.EDGE}
56 56 )
57 57 public class TbSqsNode implements TbNode {
58 58
... ...
... ... @@ -45,7 +45,7 @@ import static org.thingsboard.rule.engine.api.TbRelationTypes.SUCCESS;
45 45 uiResources = {"static/rulenode/rulenode-core-config.js", "static/rulenode/rulenode-core-config.css"},
46 46 configDirective = "tbActionNodeGeneratorConfig",
47 47 icon = "repeat",
48   - ruleChainTypes = {RuleChainType.SYSTEM, RuleChainType.EDGE}
  48 + ruleChainTypes = {RuleChainType.CORE, RuleChainType.EDGE}
49 49 )
50 50
51 51 public class TbMsgGeneratorNode implements TbNode {
... ...
... ... @@ -46,7 +46,7 @@ import static org.thingsboard.rule.engine.api.TbRelationTypes.SUCCESS;
46 46 icon = "pause",
47 47 uiResources = {"static/rulenode/rulenode-core-config.js"},
48 48 configDirective = "tbActionNodeMsgDelayConfig",
49   - ruleChainTypes = {RuleChainType.SYSTEM, RuleChainType.EDGE}
  49 + ruleChainTypes = {RuleChainType.CORE, RuleChainType.EDGE}
50 50 )
51 51
52 52 public class TbMsgDelayNode implements TbNode {
... ...
... ... @@ -15,6 +15,10 @@
15 15 */
16 16 package org.thingsboard.rule.engine.edge;
17 17
  18 +import com.fasterxml.jackson.databind.ObjectMapper;
  19 +import com.google.common.util.concurrent.FutureCallback;
  20 +import com.google.common.util.concurrent.Futures;
  21 +import com.google.common.util.concurrent.ListenableFuture;
18 22 import lombok.extern.slf4j.Slf4j;
19 23 import org.thingsboard.rule.engine.api.EmptyNodeConfiguration;
20 24 import org.thingsboard.rule.engine.api.RuleNode;
... ... @@ -23,10 +27,25 @@ import org.thingsboard.rule.engine.api.TbNode;
23 27 import org.thingsboard.rule.engine.api.TbNodeConfiguration;
24 28 import org.thingsboard.rule.engine.api.TbNodeException;
25 29 import org.thingsboard.rule.engine.api.util.TbNodeUtils;
  30 +import org.thingsboard.server.common.data.DataConstants;
  31 +import org.thingsboard.server.common.data.EntityType;
  32 +import org.thingsboard.server.common.data.audit.ActionType;
  33 +import org.thingsboard.server.common.data.edge.EdgeEvent;
  34 +import org.thingsboard.server.common.data.edge.EdgeEventType;
  35 +import org.thingsboard.server.common.data.id.EdgeId;
  36 +import org.thingsboard.server.common.data.id.EntityId;
  37 +import org.thingsboard.server.common.data.id.TenantId;
26 38 import org.thingsboard.server.common.data.plugin.ComponentType;
  39 +import org.thingsboard.server.common.data.relation.EntityRelation;
  40 +import org.thingsboard.server.common.data.relation.RelationTypeGroup;
27 41 import org.thingsboard.server.common.msg.TbMsg;
28 42 import org.thingsboard.server.common.msg.session.SessionMsgType;
29 43
  44 +import javax.annotation.Nullable;
  45 +import java.util.List;
  46 +
  47 +import static org.thingsboard.rule.engine.api.TbRelationTypes.SUCCESS;
  48 +
30 49 @Slf4j
31 50 @RuleNode(
32 51 type = ComponentType.ACTION,
... ... @@ -40,13 +59,10 @@ import org.thingsboard.server.common.msg.session.SessionMsgType;
40 59 )
41 60 public class TbMsgPushToEdgeNode implements TbNode {
42 61
43   - private static final String CLOUD_MSG_SOURCE = "cloud";
44   - private static final String EDGE_MSG_SOURCE = "edge";
45   - private static final String MSG_SOURCE_KEY = "source";
46   - private static final String TS_METADATA_KEY = "ts";
47   -
48 62 private EmptyNodeConfiguration config;
49 63
  64 + private static final ObjectMapper json = new ObjectMapper();
  65 +
50 66 @Override
51 67 public void init(TbContext ctx, TbNodeConfiguration configuration) throws TbNodeException {
52 68 this.config = TbNodeUtils.convert(configuration, EmptyNodeConfiguration.class);
... ... @@ -54,14 +70,71 @@ public class TbMsgPushToEdgeNode implements TbNode {
54 70
55 71 @Override
56 72 public void onMsg(TbContext ctx, TbMsg msg) {
57   - if (EDGE_MSG_SOURCE.equalsIgnoreCase(msg.getMetaData().getValue(MSG_SOURCE_KEY))) {
58   - return;
59   - }
60   - if (msg.getType().equals(SessionMsgType.POST_TELEMETRY_REQUEST.name())) {
61   - msg.getMetaData().putValue(TS_METADATA_KEY, Long.toString(System.currentTimeMillis()));
  73 + if (EntityType.DEVICE.equals(msg.getOriginator().getEntityType()) ||
  74 + EntityType.DEVICE.equals(msg.getOriginator().getEntityType()) ||
  75 + EntityType.DEVICE.equals(msg.getOriginator().getEntityType()) ||
  76 + EntityType.DEVICE.equals(msg.getOriginator().getEntityType())) {
  77 + if (SessionMsgType.POST_TELEMETRY_REQUEST.name().equals(msg.getType()) ||
  78 + SessionMsgType.POST_ATTRIBUTES_REQUEST.name().equals(msg.getType()) ||
  79 + DataConstants.ATTRIBUTES_UPDATED.equals(msg.getType()) ||
  80 + DataConstants.ATTRIBUTES_DELETED.equals(msg.getType())) {
  81 + ListenableFuture<EdgeId> getEdgeIdFuture = getEdgeIdByOriginatorId(ctx, ctx.getTenantId(), msg.getOriginator());
  82 + Futures.transform(getEdgeIdFuture, edgeId -> {
  83 + EdgeEventType edgeEventTypeByEntityType = ctx.getEdgeEventService().getEdgeEventTypeByEntityType(msg.getOriginator().getEntityType());
  84 + if (edgeEventTypeByEntityType == null) {
  85 + log.debug("Edge event type is null. Entity Type {}", msg.getOriginator().getEntityType());
  86 + ctx.tellFailure(msg, new RuntimeException("Edge event type is null. Entity Type '"+ msg.getOriginator().getEntityType() + "'"));
  87 + }
  88 + ActionType actionType;
  89 + if (SessionMsgType.POST_TELEMETRY_REQUEST.name().equals(msg.getType())) {
  90 + actionType = ActionType.TIMESERIES_UPDATED;
  91 + } else if (SessionMsgType.POST_ATTRIBUTES_REQUEST.name().equals(msg.getType()) ||
  92 + DataConstants.ATTRIBUTES_UPDATED.equals(msg.getType())) {
  93 + actionType = ActionType.ATTRIBUTES_UPDATED;
  94 + } else {
  95 + actionType = ActionType.ATTRIBUTES_DELETED;
  96 + }
  97 + EdgeEvent edgeEvent = new EdgeEvent();
  98 + edgeEvent.setTenantId(ctx.getTenantId());
  99 + edgeEvent.setEdgeId(edgeId);
  100 + edgeEvent.setEdgeEventAction(actionType.name());
  101 + edgeEvent.setEntityId(msg.getOriginator().getId());
  102 + edgeEvent.setEdgeEventType(edgeEventTypeByEntityType);
  103 + edgeEvent.setEntityBody(json.valueToTree(msg.getData()));
  104 + ListenableFuture<EdgeEvent> saveFuture = ctx.getEdgeEventService().saveAsync(edgeEvent);
  105 + Futures.addCallback(saveFuture, new FutureCallback<EdgeEvent>() {
  106 + @Override
  107 + public void onSuccess(@Nullable EdgeEvent event) {
  108 + ctx.tellNext(msg, SUCCESS);
  109 + }
  110 +
  111 + @Override
  112 + public void onFailure(Throwable th) {
  113 + log.error("Could not save edge event", th);
  114 + ctx.tellFailure(msg, th);
  115 + }
  116 + }, ctx.getDbCallbackExecutor());
  117 + return null;
  118 + }, ctx.getDbCallbackExecutor());
  119 + } else {
  120 + log.debug("Unsupported msg type {}", msg.getType());
  121 + ctx.tellFailure(msg, new RuntimeException("Unsupported msg type '" + msg.getType() + "'"));
  122 + }
  123 + } else {
  124 + log.debug("Unsupported originator type {}", msg.getOriginator().getEntityType());
  125 + ctx.tellFailure(msg, new RuntimeException("Unsupported originator type '" + msg.getOriginator().getEntityType() + "'"));
62 126 }
63   - msg.getMetaData().putValue(MSG_SOURCE_KEY, CLOUD_MSG_SOURCE);
64   - ctx.getEdgeService().pushEventToEdge(ctx.getTenantId(), msg, new PushToEdgeNodeCallback(ctx, msg));
  127 + }
  128 +
  129 + private ListenableFuture<EdgeId> getEdgeIdByOriginatorId(TbContext ctx, TenantId tenantId, EntityId originatorId) {
  130 + ListenableFuture<List<EntityRelation>> future = ctx.getRelationService().findByToAndTypeAsync(tenantId, originatorId, EntityRelation.CONTAINS_TYPE, RelationTypeGroup.EDGE);
  131 + return Futures.transform(future, relations -> {
  132 + if (relations != null && relations.size() > 0) {
  133 + return new EdgeId(relations.get(0).getFrom().getId());
  134 + } else {
  135 + return null;
  136 + }
  137 + }, ctx.getDbCallbackExecutor());
65 138 }
66 139
67 140 @Override
... ...
... ... @@ -41,7 +41,7 @@ import java.util.Map;
41 41 "Else if the checkbox is not selected, and at least one of the keys from data or metadata of the message exists - send Message via <b>True</b> chain, otherwise, <b>False</b> chain is used. ",
42 42 uiResources = {"static/rulenode/rulenode-core-config.js"},
43 43 configDirective = "tbFilterNodeCheckMessageConfig",
44   - ruleChainTypes = {RuleChainType.SYSTEM, RuleChainType.EDGE}
  44 + ruleChainTypes = {RuleChainType.CORE, RuleChainType.EDGE}
45 45 )
46 46 public class TbCheckMessageNode implements TbNode {
47 47
... ...
... ... @@ -53,7 +53,7 @@ import static org.thingsboard.common.util.DonAsynchron.withCallback;
53 53 nodeDetails = "If at least one relation exists - send Message via <b>True</b> chain, otherwise <b>False</b> chain is used.",
54 54 uiResources = {"static/rulenode/rulenode-core-config.js"},
55 55 configDirective = "tbFilterNodeCheckRelationConfig",
56   - ruleChainTypes = {RuleChainType.SYSTEM, RuleChainType.EDGE}
  56 + ruleChainTypes = {RuleChainType.CORE, RuleChainType.EDGE}
57 57 )
58 58 public class TbCheckRelationNode implements TbNode {
59 59
... ...
... ... @@ -38,7 +38,7 @@ import static org.thingsboard.common.util.DonAsynchron.withCallback;
38 38 "Message type can be accessed via <code>msgType</code> property.",
39 39 uiResources = {"static/rulenode/rulenode-core-config.js"},
40 40 configDirective = "tbFilterNodeScriptConfig",
41   - ruleChainTypes = {RuleChainType.SYSTEM, RuleChainType.EDGE}
  41 + ruleChainTypes = {RuleChainType.CORE, RuleChainType.EDGE}
42 42 )
43 43
44 44 public class TbJsFilterNode implements TbNode {
... ...
... ... @@ -41,7 +41,7 @@ import static org.thingsboard.common.util.DonAsynchron.withCallback;
41 41 "Message type can be accessed via <code>msgType</code> property.",
42 42 uiResources = {"static/rulenode/rulenode-core-config.js"},
43 43 configDirective = "tbFilterNodeSwitchConfig",
44   - ruleChainTypes = {RuleChainType.SYSTEM, RuleChainType.EDGE}
  44 + ruleChainTypes = {RuleChainType.CORE, RuleChainType.EDGE}
45 45 )
46 46 public class TbJsSwitchNode implements TbNode {
47 47
... ...
... ... @@ -35,7 +35,7 @@ import org.thingsboard.server.common.msg.TbMsg;
35 35 nodeDetails = "If incoming MessageType is expected - send Message via <b>True</b> chain, otherwise <b>False</b> chain is used.",
36 36 uiResources = {"static/rulenode/rulenode-core-config.js", "static/rulenode/rulenode-core-config.css"},
37 37 configDirective = "tbFilterNodeMessageTypeConfig",
38   - ruleChainTypes = {RuleChainType.SYSTEM, RuleChainType.EDGE}
  38 + ruleChainTypes = {RuleChainType.CORE, RuleChainType.EDGE}
39 39 )
40 40 public class TbMsgTypeFilterNode implements TbNode {
41 41
... ...
... ... @@ -36,7 +36,7 @@ import org.thingsboard.server.common.msg.session.SessionMsgType;
36 36 nodeDetails = "Sends messages with message types <b>\"Post attributes\", \"Post telemetry\", \"RPC Request\"</b> etc. via corresponding chain, otherwise <b>Other</b> chain is used.",
37 37 uiResources = {"static/rulenode/rulenode-core-config.js"},
38 38 configDirective = "tbNodeEmptyConfig",
39   - ruleChainTypes = {RuleChainType.SYSTEM, RuleChainType.EDGE}
  39 + ruleChainTypes = {RuleChainType.CORE, RuleChainType.EDGE}
40 40 )
41 41 public class TbMsgTypeSwitchNode implements TbNode {
42 42
... ...
... ... @@ -33,7 +33,7 @@ import org.thingsboard.server.common.msg.TbMsg;
33 33 nodeDetails = "If Originator Type of incoming message is expected - send Message via <b>True</b> chain, otherwise <b>False</b> chain is used.",
34 34 uiResources = {"static/rulenode/rulenode-core-config.js", "static/rulenode/rulenode-core-config.css"},
35 35 configDirective = "tbFilterNodeOriginatorTypeConfig",
36   - ruleChainTypes = {RuleChainType.SYSTEM, RuleChainType.EDGE}
  36 + ruleChainTypes = {RuleChainType.CORE, RuleChainType.EDGE}
37 37 )
38 38 public class TbOriginatorTypeFilterNode implements TbNode {
39 39
... ...
... ... @@ -33,7 +33,7 @@ import org.thingsboard.server.common.msg.TbMsg;
33 33 nodeDetails = "Routes messages to chain according to the originator type ('Device', 'Asset', etc.).",
34 34 uiResources = {"static/rulenode/rulenode-core-config.js"},
35 35 configDirective = "tbNodeEmptyConfig",
36   - ruleChainTypes = {RuleChainType.SYSTEM, RuleChainType.EDGE}
  36 + ruleChainTypes = {RuleChainType.CORE, RuleChainType.EDGE}
37 37 )
38 38 public class TbOriginatorTypeSwitchNode implements TbNode {
39 39
... ...
... ... @@ -51,7 +51,7 @@ import static org.thingsboard.common.util.DonAsynchron.withCallback;
51 51 uiResources = {"static/rulenode/rulenode-core-config.js"},
52 52 configDirective = "tbActionNodePubSubConfig",
53 53 iconUrl = "data:image/svg+xml;base64,PHN2ZyBpZD0iTGF5ZXJfMSIgZGF0YS1uYW1lPSJMYXllciAxIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMjgiIGhlaWdodD0iMTI4IiB2aWV3Qm94PSIwIDAgMTI4IDEyOCI+Cjx0aXRsZT5DbG91ZCBQdWJTdWI8L3RpdGxlPgo8Zz4KPHBhdGggZD0iTTEyNi40Nyw1OC4xMmwtMjYuMy00NS43NEExMS41NiwxMS41NiwwLDAsMCw5MC4zMSw2LjVIMzcuN2ExMS41NSwxMS41NSwwLDAsMC05Ljg2LDUuODhMMS41Myw1OGExMS40OCwxMS40OCwwLDAsMCwwLDExLjQ0bDI2LjMsNDZhMTEuNzcsMTEuNzcsMCwwLDAsOS44Niw2LjA5SDkwLjNhMTEuNzMsMTEuNzMsMCwwLDAsOS44Ny02LjA2bDI2LjMtNDUuNzRBMTEuNzMsMTEuNzMsMCwwLDAsMTI2LjQ3LDU4LjEyWiIgc3R5bGU9ImZpbGw6ICM3MzViMmYiLz4KPHBhdGggZD0iTTg5LjIyLDQ3Ljc0LDgzLjM2LDQ5bC0xNC42LTE0LjZMNjQuMDksNDMuMSw2MS41NSw1My4ybDQuMjksNC4yOUw1Ny42LDU5LjE4LDQ2LjMsNDcuODhsLTcuNjcsNy4zOEw1Mi43Niw2OS4zN2wtMTUsMTEuOUw3OCwxMjEuNUg5MC4zYTExLjczLDExLjczLDAsMCwwLDkuODctNi4wNmwyMC43Mi0zNloiIHN0eWxlPSJvcGFjaXR5OiAwLjA3MDAwMDAwMDI5ODAyMztpc29sYXRpb246IGlzb2xhdGUiLz4KPHBhdGggZD0iTTgyLjg2LDQ3YTUuMzIsNS4zMiwwLDEsMS0xLjk1LDcuMjdBNS4zMiw1LjMyLDAsMCwxLDgyLjg2LDQ3IiBzdHlsZT0iZmlsbDogI2ZmZiIvPgo8cGF0aCBkPSJNMzkuODIsNTYuMThhNS4zMiw1LjMyLDAsMSwxLDcuMjctMS45NSw1LjMyLDUuMzIsMCwwLDEtNy4yNywxLjk1IiBzdHlsZT0iZmlsbDogI2ZmZiIvPgo8cGF0aCBkPSJNNjkuMzIsODguODVBNS4zMiw1LjMyLDAsMSwxLDY0LDgzLjUyYTUuMzIsNS4zMiwwLDAsMSw1LjMyLDUuMzIiIHN0eWxlPSJmaWxsOiAjZmZmIi8+CjxnPgo8cGF0aCBkPSJNNjQsNTIuOTRhMTEuMDYsMTEuMDYsMCwwLDEsMi40Ni4yOFYzOS4xNUg2MS41NFY1My4yMkExMS4wNiwxMS4wNiwwLDAsMSw2NCw1Mi45NFoiIHN0eWxlPSJmaWxsOiAjZmZmIi8+CjxwYXRoIGQ9Ik03NC41Nyw2Ny4yNmExMSwxMSwwLDAsMS0yLjQ3LDQuMjVsMTIuMTksNywyLjQ2LTQuMjZaIiBzdHlsZT0iZmlsbDogI2ZmZiIvPgo8cGF0aCBkPSJNNTMuNDMsNjcuMjZsLTEyLjE4LDcsMi40Niw0LjI2LDEyLjE5LTdBMTEsMTEsMCwwLDEsNTMuNDMsNjcuMjZaIiBzdHlsZT0iZmlsbDogI2ZmZiIvPgo8L2c+CjxwYXRoIGQ9Ik03Mi42LDY0QTguNiw4LjYsMCwxLDEsNjQsNTUuNCw4LjYsOC42LDAsMCwxLDcyLjYsNjQiIHN0eWxlPSJmaWxsOiAjZmZmIi8+CjxwYXRoIGQ9Ik0zOS4xLDcwLjU3YTYuNzYsNi43NiwwLDEsMS0yLjQ3LDkuMjMsNi43Niw2Ljc2LDAsMCwxLDIuNDctOS4yMyIgc3R5bGU9ImZpbGw6ICNmZmYiLz4KPHBhdGggZD0iTTgyLjE0LDgyLjI3YTYuNzYsNi43NiwwLDEsMSw5LjIzLTIuNDcsNi43NSw2Ljc1LDAsMCwxLTkuMjMsMi40NyIgc3R5bGU9ImZpbGw6ICNmZmYiLz4KPHBhdGggZD0iTTcwLjc2LDM5LjE1QTYuNzYsNi43NiwwLDEsMSw2NCwzMi4zOWE2Ljc2LDYuNzYsMCwwLDEsNi43Niw2Ljc2IiBzdHlsZT0iZmlsbDogI2ZmZiIvPgo8L2c+Cjwvc3ZnPgo=",
54   - ruleChainTypes = {RuleChainType.SYSTEM, RuleChainType.EDGE}
  54 + ruleChainTypes = {RuleChainType.CORE, RuleChainType.EDGE}
55 55 )
56 56 public class TbPubSubNode implements TbNode {
57 57
... ...
... ... @@ -53,7 +53,7 @@ import java.util.concurrent.TimeoutException;
53 53 nodeDetails = "Extracts latitude and longitude parameters from incoming message and returns different events based on configuration parameters",
54 54 uiResources = {"static/rulenode/rulenode-core-config.js"},
55 55 configDirective = "tbActionNodeGpsGeofencingConfig",
56   - ruleChainTypes = {RuleChainType.SYSTEM, RuleChainType.EDGE}
  56 + ruleChainTypes = {RuleChainType.CORE, RuleChainType.EDGE}
57 57 )
58 58 public class TbGpsGeofencingActionNode extends AbstractGeofencingNode<TbGpsGeofencingActionNodeConfiguration> {
59 59
... ...
... ... @@ -54,7 +54,7 @@ import java.util.List;
54 54 nodeDetails = "Extracts latitude and longitude parameters from incoming message and returns 'True' if they are inside configured perimeters, 'False' otherwise.",
55 55 uiResources = {"static/rulenode/rulenode-core-config.js"},
56 56 configDirective = "tbFilterNodeGpsGeofencingConfig",
57   - ruleChainTypes = {RuleChainType.SYSTEM, RuleChainType.EDGE}
  57 + ruleChainTypes = {RuleChainType.CORE, RuleChainType.EDGE}
58 58 )
59 59 public class TbGpsGeofencingFilterNode extends AbstractGeofencingNode<TbGpsGeofencingFilterNodeConfiguration> {
60 60
... ...
... ... @@ -53,7 +53,7 @@ import java.util.Properties;
53 53 uiResources = {"static/rulenode/rulenode-core-config.js"},
54 54 configDirective = "tbActionNodeKafkaConfig",
55 55 iconUrl = "data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMTUzOCIgaGVpZ2h0PSIyNTAwIiB2aWV3Qm94PSIwIDAgMjU2IDQxNiIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiBwcmVzZXJ2ZUFzcGVjdFJhdGlvPSJ4TWlkWU1pZCI+PHBhdGggZD0iTTIwMS44MTYgMjMwLjIxNmMtMTYuMTg2IDAtMzAuNjk3IDcuMTcxLTQwLjYzNCAxOC40NjFsLTI1LjQ2My0xOC4wMjZjMi43MDMtNy40NDIgNC4yNTUtMTUuNDMzIDQuMjU1LTIzLjc5NyAwLTguMjE5LTEuNDk4LTE2LjA3Ni00LjExMi0yMy40MDhsMjUuNDA2LTE3LjgzNWM5LjkzNiAxMS4yMzMgMjQuNDA5IDE4LjM2NSA0MC41NDggMTguMzY1IDI5Ljg3NSAwIDU0LjE4NC0yNC4zMDUgNTQuMTg0LTU0LjE4NCAwLTI5Ljg3OS0yNC4zMDktNTQuMTg0LTU0LjE4NC01NC4xODQtMjkuODc1IDAtNTQuMTg0IDI0LjMwNS01NC4xODQgNTQuMTg0IDAgNS4zNDguODA4IDEwLjUwNSAyLjI1OCAxNS4zODlsLTI1LjQyMyAxNy44NDRjLTEwLjYyLTEzLjE3NS0yNS45MTEtMjIuMzc0LTQzLjMzMy0yNS4xODJ2LTMwLjY0YzI0LjU0NC01LjE1NSA0My4wMzctMjYuOTYyIDQzLjAzNy01My4wMTlDMTI0LjE3MSAyNC4zMDUgOTkuODYyIDAgNjkuOTg3IDAgNDAuMTEyIDAgMTUuODAzIDI0LjMwNSAxNS44MDMgNTQuMTg0YzAgMjUuNzA4IDE4LjAxNCA0Ny4yNDYgNDIuMDY3IDUyLjc2OXYzMS4wMzhDMjUuMDQ0IDE0My43NTMgMCAxNzIuNDAxIDAgMjA2Ljg1NGMwIDM0LjYyMSAyNS4yOTIgNjMuMzc0IDU4LjM1NSA2OC45NHYzMi43NzRjLTI0LjI5OSA1LjM0MS00Mi41NTIgMjcuMDExLTQyLjU1MiA1Mi44OTQgMCAyOS44NzkgMjQuMzA5IDU0LjE4NCA1NC4xODQgNTQuMTg0IDI5Ljg3NSAwIDU0LjE4NC0yNC4zMDUgNTQuMTg0LTU0LjE4NCAwLTI1Ljg4My0xOC4yNTMtNDcuNTUzLTQyLjU1Mi01Mi44OTR2LTMyLjc3NWE2OS45NjUgNjkuOTY1IDAgMCAwIDQyLjYtMjQuNzc2bDI1LjYzMyAxOC4xNDNjLTEuNDIzIDQuODQtMi4yMiA5Ljk0Ni0yLjIyIDE1LjI0IDAgMjkuODc5IDI0LjMwOSA1NC4xODQgNTQuMTg0IDU0LjE4NCAyOS44NzUgMCA1NC4xODQtMjQuMzA1IDU0LjE4NC01NC4xODQgMC0yOS44NzktMjQuMzA5LTU0LjE4NC01NC4xODQtNTQuMTg0em0wLTEyNi42OTVjMTQuNDg3IDAgMjYuMjcgMTEuNzg4IDI2LjI3IDI2LjI3MXMtMTEuNzgzIDI2LjI3LTI2LjI3IDI2LjI3LTI2LjI3LTExLjc4Ny0yNi4yNy0yNi4yN2MwLTE0LjQ4MyAxMS43ODMtMjYuMjcxIDI2LjI3LTI2LjI3MXptLTE1OC4xLTQ5LjMzN2MwLTE0LjQ4MyAxMS43ODQtMjYuMjcgMjYuMjcxLTI2LjI3czI2LjI3IDExLjc4NyAyNi4yNyAyNi4yN2MwIDE0LjQ4My0xMS43ODMgMjYuMjctMjYuMjcgMjYuMjdzLTI2LjI3MS0xMS43ODctMjYuMjcxLTI2LjI3em01Mi41NDEgMzA3LjI3OGMwIDE0LjQ4My0xMS43ODMgMjYuMjctMjYuMjcgMjYuMjdzLTI2LjI3MS0xMS43ODctMjYuMjcxLTI2LjI3YzAtMTQuNDgzIDExLjc4NC0yNi4yNyAyNi4yNzEtMjYuMjdzMjYuMjcgMTEuNzg3IDI2LjI3IDI2LjI3em0tMjYuMjcyLTExNy45N2MtMjAuMjA1IDAtMzYuNjQyLTE2LjQzNC0zNi42NDItMzYuNjM4IDAtMjAuMjA1IDE2LjQzNy0zNi42NDIgMzYuNjQyLTM2LjY0MiAyMC4yMDQgMCAzNi42NDEgMTYuNDM3IDM2LjY0MSAzNi42NDIgMCAyMC4yMDQtMTYuNDM3IDM2LjYzOC0zNi42NDEgMzYuNjM4em0xMzEuODMxIDY3LjE3OWMtMTQuNDg3IDAtMjYuMjctMTEuNzg4LTI2LjI3LTI2LjI3MXMxMS43ODMtMjYuMjcgMjYuMjctMjYuMjcgMjYuMjcgMTEuNzg3IDI2LjI3IDI2LjI3YzAgMTQuNDgzLTExLjc4MyAyNi4yNzEtMjYuMjcgMjYuMjcxeiIvPjwvc3ZnPg==",
56   - ruleChainTypes = {RuleChainType.SYSTEM, RuleChainType.EDGE}
  56 + ruleChainTypes = {RuleChainType.CORE, RuleChainType.EDGE}
57 57 )
58 58 public class TbKafkaNode implements TbNode {
59 59
... ...
... ... @@ -42,7 +42,7 @@ import static org.thingsboard.rule.engine.mail.TbSendEmailNode.SEND_EMAIL_TYPE;
42 42 uiResources = {"static/rulenode/rulenode-core-config.js"},
43 43 configDirective = "tbTransformationNodeToEmailConfig",
44 44 icon = "email",
45   - ruleChainTypes = {RuleChainType.SYSTEM, RuleChainType.EDGE}
  45 + ruleChainTypes = {RuleChainType.CORE, RuleChainType.EDGE}
46 46 )
47 47 public class TbMsgToEmailNode implements TbNode {
48 48
... ...
... ... @@ -48,7 +48,7 @@ import static org.thingsboard.common.util.DonAsynchron.withCallback;
48 48 uiResources = {"static/rulenode/rulenode-core-config.js"},
49 49 configDirective = "tbActionNodeSendEmailConfig",
50 50 icon = "send",
51   - ruleChainTypes = {RuleChainType.SYSTEM, RuleChainType.EDGE}
  51 + ruleChainTypes = {RuleChainType.CORE, RuleChainType.EDGE}
52 52 )
53 53 public class TbSendEmailNode implements TbNode {
54 54
... ...
... ... @@ -42,7 +42,7 @@ import org.thingsboard.server.common.msg.TbMsg;
42 42 "<code>metadata.cs_temperature</code> or <code>metadata.shared_limit</code> ",
43 43 uiResources = {"static/rulenode/rulenode-core-config.js"},
44 44 configDirective = "tbEnrichmentNodeOriginatorAttributesConfig",
45   - ruleChainTypes = {RuleChainType.SYSTEM, RuleChainType.EDGE}
  45 + ruleChainTypes = {RuleChainType.CORE, RuleChainType.EDGE}
46 46 )
47 47 public class TbGetAttributesNode extends TbAbstractGetAttributesNode<TbGetAttributesNodeConfiguration, EntityId> {
48 48
... ...
... ... @@ -35,7 +35,7 @@ import org.thingsboard.server.common.data.rule.RuleChainType;
35 35 "<code>metadata.temperature</code>.",
36 36 uiResources = {"static/rulenode/rulenode-core-config.js", "static/rulenode/rulenode-core-config.css"},
37 37 configDirective = "tbEnrichmentNodeCustomerAttributesConfig",
38   - ruleChainTypes = {RuleChainType.SYSTEM, RuleChainType.EDGE}
  38 + ruleChainTypes = {RuleChainType.CORE, RuleChainType.EDGE}
39 39 )
40 40 public class TbGetCustomerAttributeNode extends TbEntityGetAttrNode<CustomerId> {
41 41
... ...
... ... @@ -44,7 +44,7 @@ import org.thingsboard.server.common.msg.TbMsg;
44 44 "If the originator of the message is not assigned to Customer, or originator type is not supported - Message will be forwarded to <b>Failure</b> chain, otherwise, <b>Success</b> chain will be used.",
45 45 uiResources = {"static/rulenode/rulenode-core-config.js"},
46 46 configDirective = "tbEnrichmentNodeEntityDetailsConfig",
47   - ruleChainTypes = {RuleChainType.SYSTEM, RuleChainType.EDGE}
  47 + ruleChainTypes = {RuleChainType.CORE, RuleChainType.EDGE}
48 48 )
49 49 public class TbGetCustomerDetailsNode extends TbAbstractGetEntityDetailsNode<TbGetCustomerDetailsNodeConfiguration> {
50 50
... ...
... ... @@ -40,7 +40,7 @@ import org.thingsboard.server.common.msg.TbMsg;
40 40 "<code>metadata.cs_temperature</code> or <code>metadata.shared_limit</code> ",
41 41 uiResources = {"static/rulenode/rulenode-core-config.js"},
42 42 configDirective = "tbEnrichmentNodeDeviceAttributesConfig",
43   - ruleChainTypes = {RuleChainType.SYSTEM, RuleChainType.EDGE}
  43 + ruleChainTypes = {RuleChainType.CORE, RuleChainType.EDGE}
44 44 )
45 45 public class TbGetDeviceAttrNode extends TbAbstractGetAttributesNode<TbGetDeviceAttrNodeConfiguration, DeviceId> {
46 46
... ...
... ... @@ -45,7 +45,7 @@ import static org.thingsboard.rule.engine.api.TbRelationTypes.SUCCESS;
45 45 nodeDetails = "Will fetch fields values specified in mapping. If specified field is not part of originator fields it will be ignored.",
46 46 uiResources = {"static/rulenode/rulenode-core-config.js"},
47 47 configDirective = "tbEnrichmentNodeOriginatorFieldsConfig",
48   - ruleChainTypes = {RuleChainType.SYSTEM, RuleChainType.EDGE}
  48 + ruleChainTypes = {RuleChainType.CORE, RuleChainType.EDGE}
49 49 )
50 50 public class TbGetOriginatorFieldsNode implements TbNode {
51 51
... ...
... ... @@ -37,7 +37,7 @@ import org.thingsboard.server.common.data.rule.RuleChainType;
37 37 "<code>metadata.temperature</code>.",
38 38 uiResources = {"static/rulenode/rulenode-core-config.js", "static/rulenode/rulenode-core-config.css"},
39 39 configDirective = "tbEnrichmentNodeRelatedAttributesConfig",
40   - ruleChainTypes = {RuleChainType.SYSTEM, RuleChainType.EDGE}
  40 + ruleChainTypes = {RuleChainType.CORE, RuleChainType.EDGE}
41 41 )
42 42
43 43 public class TbGetRelatedAttributeNode extends TbEntityGetAttrNode<EntityId> {
... ...
... ... @@ -68,7 +68,7 @@ import static org.thingsboard.server.common.data.kv.Aggregation.NONE;
68 68 "<b>Note</b>: The maximum size of the fetched array is 1000 records.\n ",
69 69 uiResources = {"static/rulenode/rulenode-core-config.js"},
70 70 configDirective = "tbEnrichmentNodeGetTelemetryFromDatabase",
71   - ruleChainTypes = {RuleChainType.SYSTEM, RuleChainType.EDGE}
  71 + ruleChainTypes = {RuleChainType.CORE, RuleChainType.EDGE}
72 72 )
73 73 public class TbGetTelemetryNode implements TbNode {
74 74
... ...
... ... @@ -37,7 +37,7 @@ import org.thingsboard.server.common.data.rule.RuleChainType;
37 37 "<code>metadata.temperature</code>.",
38 38 uiResources = {"static/rulenode/rulenode-core-config.js", "static/rulenode/rulenode-core-config.css"},
39 39 configDirective = "tbEnrichmentNodeTenantAttributesConfig",
40   - ruleChainTypes = {RuleChainType.SYSTEM, RuleChainType.EDGE}
  40 + ruleChainTypes = {RuleChainType.CORE, RuleChainType.EDGE}
41 41 )
42 42 public class TbGetTenantAttributeNode extends TbEntityGetAttrNode<TenantId> {
43 43
... ...
... ... @@ -39,7 +39,7 @@ import org.thingsboard.server.common.msg.TbMsg;
39 39 "If the originator of the message is not assigned to Tenant, or originator type is not supported - Message will be forwarded to <b>Failure</b> chain, otherwise, <b>Success</b> chain will be used.",
40 40 uiResources = {"static/rulenode/rulenode-core-config.js"},
41 41 configDirective = "tbEnrichmentNodeEntityDetailsConfig",
42   - ruleChainTypes = {RuleChainType.SYSTEM, RuleChainType.EDGE}
  42 + ruleChainTypes = {RuleChainType.CORE, RuleChainType.EDGE}
43 43 )
44 44 public class TbGetTenantDetailsNode extends TbAbstractGetEntityDetailsNode<TbGetTenantDetailsNodeConfiguration> {
45 45
... ...
... ... @@ -51,7 +51,7 @@ import java.util.concurrent.TimeoutException;
51 51 uiResources = {"static/rulenode/rulenode-core-config.js", "static/rulenode/rulenode-core-config.css"},
52 52 configDirective = "tbActionNodeMqttConfig",
53 53 icon = "call_split",
54   - ruleChainTypes = {RuleChainType.SYSTEM, RuleChainType.EDGE}
  54 + ruleChainTypes = {RuleChainType.CORE, RuleChainType.EDGE}
55 55 )
56 56 public class TbMqttNode implements TbNode {
57 57
... ...
... ... @@ -41,7 +41,7 @@ import static org.thingsboard.common.util.DonAsynchron.withCallback;
41 41 uiResources = {"static/rulenode/rulenode-core-config.js"},
42 42 configDirective = "tbActionNodeRabbitMqConfig",
43 43 iconUrl = "data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHhtbDpzcGFjZT0icHJlc2VydmUiIHZlcnNpb249IjEuMSIgeT0iMHB4IiB4PSIwcHgiIHZpZXdCb3g9IjAgMCAxMDAwIDEwMDAiPjxwYXRoIHN0cm9rZS13aWR0aD0iLjg0OTU2IiBkPSJtODYwLjQ3IDQxNi4zMmgtMjYyLjAxYy0xMi45MTMgMC0yMy42MTgtMTAuNzA0LTIzLjYxOC0yMy42MTh2LTI3Mi43MWMwLTIwLjMwNS0xNi4yMjctMzYuMjc2LTM2LjI3Ni0zNi4yNzZoLTkzLjc5MmMtMjAuMzA1IDAtMzYuMjc2IDE2LjIyNy0zNi4yNzYgMzYuMjc2djI3MC44NGMtMC4yNTQ4NyAxNC4xMDMtMTEuNDY5IDI1LjU3Mi0yNS43NDIgMjUuNTcybC04NS42MzYgMC42Nzk2NWMtMTQuMTAzIDAtMjUuNTcyLTExLjQ2OS0yNS41NzItMjUuNTcybDAuNjc5NjUtMjcxLjUyYzAtMjAuMzA1LTE2LjIyNy0zNi4yNzYtMzYuMjc2LTM2LjI3NmgtOTMuNTM3Yy0yMC4zMDUgMC0zNi4yNzYgMTYuMjI3LTM2LjI3NiAzNi4yNzZ2NzYzLjg0YzAgMTguMDk2IDE0Ljc4MiAzMi40NTMgMzIuNDUzIDMyLjQ1M2g3MjIuODFjMTguMDk2IDAgMzIuNDUzLTE0Ljc4MiAzMi40NTMtMzIuNDUzdi00MzUuMzFjLTEuMTg5NC0xOC4xODEtMTUuMjkyLTMyLjE5OC0zMy4zODgtMzIuMTk4em0tMTIyLjY4IDI4Ny4wN2MwIDIzLjYxOC0xOC44NiA0Mi40NzgtNDIuNDc4IDQyLjQ3OGgtNzMuOTk3Yy0yMy42MTggMC00Mi40NzgtMTguODYtNDIuNDc4LTQyLjQ3OHYtNzQuMjUyYzAtMjMuNjE4IDE4Ljg2LTQyLjQ3OCA0Mi40NzgtNDIuNDc4aDczLjk5N2MyMy42MTggMCA0Mi40NzggMTguODYgNDIuNDc4IDQyLjQ3OHoiLz48L3N2Zz4=",
44   - ruleChainTypes = {RuleChainType.SYSTEM, RuleChainType.EDGE}
  44 + ruleChainTypes = {RuleChainType.CORE, RuleChainType.EDGE}
45 45 )
46 46 public class TbRabbitMqNode implements TbNode {
47 47
... ...
... ... @@ -41,7 +41,7 @@ import org.thingsboard.server.common.msg.TbMsg;
41 41 uiResources = {"static/rulenode/rulenode-core-config.js"},
42 42 configDirective = "tbActionNodeRestApiCallConfig",
43 43 iconUrl = "data:image/svg+xml;base64,PHN2ZyBzdHlsZT0iZW5hYmxlLWJhY2tncm91bmQ6bmV3IDAgMCA1MTIgNTEyIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHhtbDpzcGFjZT0icHJlc2VydmUiIHZpZXdCb3g9IjAgMCA1MTIgNTEyIiB2ZXJzaW9uPSIxLjEiIHk9IjBweCIgeD0iMHB4Ij48ZyB0cmFuc2Zvcm09Im1hdHJpeCguOTQ5NzUgMCAwIC45NDk3NSAxNy4xMiAyNi40OTIpIj48cGF0aCBkPSJtMTY5LjExIDEwOC41NGMtOS45MDY2IDAuMDczNC0xOS4wMTQgNi41NzI0LTIyLjAxNCAxNi40NjlsLTY5Ljk5MyAyMzEuMDhjLTMuNjkwNCAxMi4xODEgMy4yODkyIDI1LjIyIDE1LjQ2OSAyOC45MSAyLjIyNTkgMC42NzQ4MSA0LjQ5NjkgMSA2LjcyODUgMSA5Ljk3MjEgMCAxOS4xNjUtNi41MTUzIDIyLjE4Mi0xNi40NjdhNi41MjI0IDYuNTIyNCAwIDAgMCAwLjAwMiAtMC4wMDJsNjkuOTktMjMxLjA3YTYuNTIyNCA2LjUyMjQgMCAwIDAgMCAtMC4wMDJjMy42ODU1LTEyLjE4MS0zLjI4Ny0yNS4yMjUtMTUuNDcxLTI4LjkxMi0yLjI4MjUtMC42OTE0NS00LjYxMTYtMS4wMTY5LTYuODk4NC0xem04NC45ODggMGMtOS45MDQ4IDAuMDczNC0xOS4wMTggNi41Njc1LTIyLjAxOCAxNi40NjlsLTY5Ljk4NiAyMzEuMDhjLTMuNjg5OCAxMi4xNzkgMy4yODUzIDI1LjIxNyAxNS40NjUgMjguOTA4IDIuMjI5NyAwLjY3NjQ3IDQuNTAwOCAxLjAwMiA2LjczMjQgMS4wMDIgOS45NzIxIDAgMTkuMTY1LTYuNTE1MyAyMi4xODItMTYuNDY3YTYuNTIyNCA2LjUyMjQgMCAwIDAgMC4wMDIgLTAuMDAybDY5Ljk4OC0yMzEuMDdjMy42OTA4LTEyLjE4MS0zLjI4NTItMjUuMjIzLTE1LjQ2Ny0yOC45MTItMi4yODE0LTAuNjkyMzEtNC42MTA4LTEuMDE4OS02Ljg5ODQtMS4wMDJ6bS0yMTcuMjkgNDIuMjNjLTEyLjcyOS0wLjAwMDg3LTIzLjE4OCAxMC40NTYtMjMuMTg4IDIzLjE4NiAwLjAwMSAxMi43MjggMTAuNDU5IDIzLjE4NiAyMy4xODggMjMuMTg2IDEyLjcyNy0wLjAwMSAyMy4xODMtMTAuNDU5IDIzLjE4NC0yMy4xODYgMC4wMDA4NzYtMTIuNzI4LTEwLjQ1Ni0yMy4xODUtMjMuMTg0LTIzLjE4NnptMCAxNDYuNjRjLTEyLjcyNy0wLjAwMDg3LTIzLjE4NiAxMC40NTUtMjMuMTg4IDIzLjE4NC0wLjAwMDg3MyAxMi43MjkgMTAuNDU4IDIzLjE4OCAyMy4xODggMjMuMTg4IDEyLjcyOC0wLjAwMSAyMy4xODQtMTAuNDYgMjMuMTg0LTIzLjE4OC0wLjAwMS0xMi43MjYtMTAuNDU3LTIzLjE4My0yMy4xODQtMjMuMTg0em0yNzAuNzkgNDIuMjExYy0xMi43MjcgMC0yMy4xODQgMTAuNDU3LTIzLjE4NCAyMy4xODRzMTAuNDU1IDIzLjE4OCAyMy4xODQgMjMuMTg4aDE1NC45OGMxMi43MjkgMCAyMy4xODYtMTAuNDYgMjMuMTg2LTIzLjE4OCAwLjAwMS0xMi43MjgtMTAuNDU4LTIzLjE4NC0yMy4xODYtMjMuMTg0eiIgdHJhbnNmb3JtPSJtYXRyaXgoMS4wMzc2IDAgMCAxLjAzNzYgLTcuNTY3NiAtMTQuOTI1KSIgc3Ryb2tlLXdpZHRoPSIxLjI2OTMiLz48L2c+PC9zdmc+",
44   - ruleChainTypes = {RuleChainType.SYSTEM, RuleChainType.EDGE}
  44 + ruleChainTypes = {RuleChainType.CORE, RuleChainType.EDGE}
45 45 )
46 46 public class TbRestApiCallNode implements TbNode {
47 47
... ...
... ... @@ -41,7 +41,7 @@ import java.util.UUID;
41 41 uiResources = {"static/rulenode/rulenode-core-config.js"},
42 42 configDirective = "tbActionNodeRpcReplyConfig",
43 43 icon = "call_merge",
44   - ruleChainTypes = {RuleChainType.SYSTEM, RuleChainType.EDGE}
  44 + ruleChainTypes = {RuleChainType.CORE, RuleChainType.EDGE}
45 45 )
46 46 public class TbSendRPCReplyNode implements TbNode {
47 47
... ...
... ... @@ -52,7 +52,7 @@ import java.util.concurrent.TimeUnit;
52 52 uiResources = {"static/rulenode/rulenode-core-config.js"},
53 53 configDirective = "tbActionNodeRpcRequestConfig",
54 54 icon = "call_made",
55   - ruleChainTypes = {RuleChainType.SYSTEM, RuleChainType.EDGE}
  55 + ruleChainTypes = {RuleChainType.CORE, RuleChainType.EDGE}
56 56 )
57 57 public class TbSendRPCRequestNode implements TbNode {
58 58
... ...
... ... @@ -46,7 +46,7 @@ import java.util.Set;
46 46 uiResources = {"static/rulenode/rulenode-core-config.js", "static/rulenode/rulenode-core-config.css"},
47 47 configDirective = "tbActionNodeAttributesConfig",
48 48 icon = "file_upload",
49   - ruleChainTypes = {RuleChainType.SYSTEM, RuleChainType.EDGE}
  49 + ruleChainTypes = {RuleChainType.CORE, RuleChainType.EDGE}
50 50 )
51 51 public class TbMsgAttributesNode implements TbNode {
52 52
... ...
... ... @@ -47,7 +47,7 @@ import java.util.Map;
47 47 uiResources = {"static/rulenode/rulenode-core-config.js", "static/rulenode/rulenode-core-config.css"},
48 48 configDirective = "tbActionNodeTimeseriesConfig",
49 49 icon = "file_upload",
50   - ruleChainTypes = {RuleChainType.SYSTEM, RuleChainType.EDGE}
  50 + ruleChainTypes = {RuleChainType.CORE, RuleChainType.EDGE}
51 51 )
52 52 public class TbMsgTimeseriesNode implements TbNode {
53 53
... ...
... ... @@ -40,7 +40,7 @@ import static org.thingsboard.rule.engine.api.TbRelationTypes.SUCCESS;
40 40 "Size of the queue per originator and timeout values are configurable on a system level",
41 41 uiResources = {"static/rulenode/rulenode-core-config.js"},
42 42 configDirective = "tbNodeEmptyConfig",
43   - ruleChainTypes = {RuleChainType.SYSTEM, RuleChainType.EDGE}
  43 + ruleChainTypes = {RuleChainType.CORE, RuleChainType.EDGE}
44 44 )
45 45 @Deprecated
46 46 public class TbSynchronizationBeginNode implements TbNode {
... ...
... ... @@ -40,7 +40,7 @@ import static org.thingsboard.rule.engine.api.TbRelationTypes.SUCCESS;
40 40 nodeDetails = "",
41 41 uiResources = {"static/rulenode/rulenode-core-config.js"},
42 42 configDirective = ("tbNodeEmptyConfig"),
43   - ruleChainTypes = {RuleChainType.SYSTEM, RuleChainType.EDGE}
  43 + ruleChainTypes = {RuleChainType.CORE, RuleChainType.EDGE}
44 44 )
45 45 @Deprecated
46 46 public class TbSynchronizationEndNode implements TbNode {
... ...
... ... @@ -48,7 +48,7 @@ import java.util.HashSet;
48 48 uiResources = {"static/rulenode/rulenode-core-config.js", "static/rulenode/rulenode-core-config.css"},
49 49 configDirective = "tbTransformationNodeChangeOriginatorConfig",
50 50 icon = "find_replace",
51   - ruleChainTypes = {RuleChainType.SYSTEM, RuleChainType.EDGE}
  51 + ruleChainTypes = {RuleChainType.CORE, RuleChainType.EDGE}
52 52 )
53 53 public class TbChangeOriginatorNode extends TbAbstractTransformNode {
54 54
... ...
... ... @@ -39,7 +39,7 @@ import static org.thingsboard.rule.engine.api.TbRelationTypes.SUCCESS;
39 39 "All fields in resulting object are optional and will be taken from original message if not specified.",
40 40 uiResources = {"static/rulenode/rulenode-core-config.js", "static/rulenode/rulenode-core-config.css"},
41 41 configDirective = "tbTransformationNodeScriptConfig",
42   - ruleChainTypes = {RuleChainType.SYSTEM, RuleChainType.EDGE}
  42 + ruleChainTypes = {RuleChainType.CORE, RuleChainType.EDGE}
43 43 )
44 44 public class TbTransformMsgNode extends TbAbstractTransformNode {
45 45
... ...
... ... @@ -744,7 +744,7 @@ export default angular.module('thingsboard.types', [])
744 744 clientSide: false
745 745 }
746 746 },
747   - systemRuleChainType: "SYSTEM",
  747 + coreRuleChainType: "CORE",
748 748 edgeRuleChainType: "EDGE",
749 749 ruleNodeTypeComponentTypes: ["FILTER", "ENRICHMENT", "TRANSFORMATION", "ACTION", "EXTERNAL"],
750 750 ruleChainNodeComponent: {
... ...
... ... @@ -1351,7 +1351,7 @@
1351 1351 "rulechain": {
1352 1352 "rulechain": "Regelkette",
1353 1353 "rulechains": "Regelketten",
1354   - "system-rulechains": "Systemeregelketten",
  1354 + "core-rulechains": "Kernregelketten",
1355 1355 "edge-rulechains": "Randregelketten",
1356 1356 "root": "Wurzel",
1357 1357 "delete": "Regelkette löschen",
... ...
... ... @@ -1533,7 +1533,7 @@
1533 1533 "rulechain": {
1534 1534 "rulechain": "Rule chain",
1535 1535 "rulechains": "Rule chains",
1536   - "system-rulechains": "System Rule chains",
  1536 + "core-rulechains": "Core Rule chains",
1537 1537 "edge-rulechains": "Edge Rule chains",
1538 1538 "root": "Root",
1539 1539 "delete": "Delete rule chain",
... ...
... ... @@ -1410,7 +1410,7 @@
1410 1410 "rulechain": {
1411 1411 "rulechain": "Cadena de reglas",
1412 1412 "rulechains": "Cadenas de reglas",
1413   - "system-rulechains": "Cadenas de reglas del sistema",
  1413 + "core-rulechains": "Cadenas de reglas centrales",
1414 1414 "edge-rulechains": "Cadenas de reglas de borde",
1415 1415 "root": "Raíz",
1416 1416 "delete": "Eliminar cadena de reglas",
... ...
... ... @@ -1429,7 +1429,7 @@
1429 1429 "rulechain-required": "Chaîne de règles requise",
1430 1430 "rulechains": "Chaînes de règles",
1431 1431 "select-rulechain": "Sélectionner la chaîne de règles",
1432   - "system-rulechains": "Chaînes de règles du système",
  1432 + "core-rulechains": "Chaînes de règles fondamentales",
1433 1433 "edge-rulechains": "Chaînes de règles de la bordure",
1434 1434 "set-root": "Rend la chaîne de règles racine (root) ",
1435 1435 "set-root-rulechain-text": "Après la confirmation, la chaîne de règles deviendra racine (root) et gérera tous les messages de transport entrants.",
... ...
... ... @@ -1270,7 +1270,7 @@ export function RuleChainController($state, $scope, $compile, $q, $mdUtil, $time
1270 1270 vm.isImport = false;
1271 1271 $mdUtil.nextTick(() => {
1272 1272 if (vm.ruleChain.type === vm.types.systemRuleChainType) {
1273   - $state.go('home.ruleChains.system.ruleChain', {ruleChainId: vm.ruleChain.id.id});
  1273 + $state.go('home.ruleChains.core.ruleChain', {ruleChainId: vm.ruleChain.id.id});
1274 1274 } else {
1275 1275 $state.go('home.ruleChains.edge.ruleChain', {ruleChainId: vm.ruleChain.id.id});
1276 1276 }
... ...
... ... @@ -31,12 +31,12 @@ export default function RuleChainRoutes($stateProvider, NodeTemplatePathProvider
31 31 url: '/ruleChains',
32 32 module: 'private',
33 33 auth: ['SYS_ADMIN', 'TENANT_ADMIN'],
34   - redirectTo: 'home.ruleChains.system',
  34 + redirectTo: 'home.ruleChains.core',
35 35 ncyBreadcrumb: {
36 36 label: '{"icon": "settings_ethernet", "label": "rulechain.rulechains"}'
37 37 }
38 38 })
39   - .state('home.ruleChains.system', {
  39 + .state('home.ruleChains.core', {
40 40 url: '/ruleChains/system',
41 41 params: {'topIndex': 0},
42 42 module: 'private',
... ... @@ -50,13 +50,13 @@ export default function RuleChainRoutes($stateProvider, NodeTemplatePathProvider
50 50 },
51 51 data: {
52 52 searchEnabled: true,
53   - pageTitle: 'rulechain.system-rulechains',
  53 + pageTitle: 'rulechain.core-rulechains',
54 54 ruleChainsType: 'tenant'
55 55 },
56 56 ncyBreadcrumb: {
57   - label: '{"icon": "settings_ethernet", "label": "rulechain.system-rulechains"}'
  57 + label: '{"icon": "settings_ethernet", "label": "rulechain.core-rulechains"}'
58 58 }
59   - }).state('home.ruleChains.system.ruleChain', {
  59 + }).state('home.ruleChains.core.ruleChain', {
60 60 url: '/:ruleChainId',
61 61 reloadOnSearch: false,
62 62 module: 'private',
... ...
... ... @@ -401,7 +401,7 @@ export default function RuleChainsController(ruleChainService, userService, edge
401 401 } else if (vm.ruleChainsScope === 'edges') {
402 402 $state.go('home.ruleChains.edge.ruleChain', {ruleChainId: ruleChain.id.id});
403 403 } else {
404   - $state.go('home.ruleChains.system.ruleChain', {ruleChainId: ruleChain.id.id});
  404 + $state.go('home.ruleChains.core.ruleChain', {ruleChainId: ruleChain.id.id});
405 405 }
406 406 }
407 407
... ...
... ... @@ -162,9 +162,9 @@ function Menu(userService, $state, $rootScope) {
162 162 icon: 'settings_ethernet',
163 163 pages: [
164 164 {
165   - name: 'rulechain.system-rulechains',
  165 + name: 'rulechain.core-rulechains',
166 166 type: 'link',
167   - state: 'home.ruleChains.system',
  167 + state: 'home.ruleChains.core',
168 168 icon: 'settings_ethernet'
169 169 },
170 170 {
... ... @@ -229,9 +229,9 @@ function Menu(userService, $state, $rootScope) {
229 229 name: 'rulechain.management',
230 230 places: [
231 231 {
232   - name: 'rulechain.system-rulechains',
  232 + name: 'rulechain.core-rulechains',
233 233 icon: 'settings_ethernet',
234   - state: 'home.ruleChains.system'
  234 + state: 'home.ruleChains.core'
235 235 },
236 236 {
237 237 name: 'rulechain.edge-rulechains',
... ...