From cd2908fb59ec4628429adae6684809d3f40d9de1 Mon Sep 17 00:00:00 2001 From: Volodymyr Babak Date: Tue, 16 Jun 2020 16:49:27 +0300 Subject: [PATCH] Refactoring notification engine --- .../server/actors/ActorSystemContext.java | 6 + .../actors/ruleChain/DefaultTbContext.java | 6 + .../RuleChainActorMessageProcessor.java | 32 +-- .../ruleChain/RuleChainManagerActor.java | 4 +- .../server/actors/tenant/TenantActor.java | 2 +- .../server/controller/AlarmController.java | 4 + .../server/controller/AssetController.java | 9 + .../server/controller/BaseController.java | 60 ++++-- .../controller/DashboardController.java | 8 + .../server/controller/DeviceController.java | 12 ++ .../server/controller/EdgeController.java | 7 +- .../controller/EntityRelationController.java | 9 + .../controller/EntityViewController.java | 10 + .../controller/RuleChainController.java | 32 ++- .../AnnotationComponentDiscoveryService.java | 4 +- .../edge/DefaultEdgeNotificationService.java | 183 ++++++++++-------- .../service/edge/EdgeNotificationService.java | 18 +- .../service/edge/rpc/EdgeGrpcSession.java | 100 +++++----- .../install/SqlDatabaseUpgradeService.java | 2 +- .../server/dao/edge/EdgeEventService.java | 35 ++++ .../server/dao/edge/EdgeService.java | 2 +- .../server/common/data/DataConstants.java | 3 - .../server/common/data/audit/ActionType.java | 1 + .../server/common/data/edge/EdgeEvent.java | 50 +++++ ...ueueEntityType.java => EdgeEventType.java} | 2 +- .../server/common/data/id/EdgeEventId.java | 35 ++++ .../common/data/rule/RuleChainType.java | 2 +- common/edge-api/pom.xml | 4 + common/edge-api/src/main/proto/edge.proto | 9 +- common/queue/src/main/proto/queue.proto | 8 + .../server/dao/edge/BaseEdgeEventService.java | 85 ++++++++ .../server/dao/edge/EdgeEventDao.java | 51 +++++ .../server/dao/edge/EdgeServiceImpl.java | 2 +- .../server/dao/model/ModelConstants.java | 10 + .../dao/model/nosql/EdgeEventEntity.java | 135 +++++++++++++ .../server/dao/model/sql/EdgeEventEntity.java | 121 ++++++++++++ .../dao/model/type/EdgeEventTypeCodec.java | 27 +++ .../server/dao/rule/BaseRuleChainService.java | 6 +- .../dao/sql/edge/EdgeEventRepository.java | 26 +++ .../dao/sql/edge/JpaBaseEdgeEventDao.java | 112 +++++++++++ .../resources/sql/schema-entities-hsql.sql | 11 ++ .../main/resources/sql/schema-entities.sql | 12 ++ .../dao/service/AbstractServiceTest.java | 4 + .../dao/service/BaseEdgeEventServiceTest.java | 108 +++++++++++ ...ImplTest.java => BaseEdgeServiceTest.java} | 2 +- .../dao/service/BaseRuleChainServiceTest.java | 12 +- .../nosql/EdgeEventServiceNoSqlTest.java | 23 +++ .../service/nosql/EdgeServiceNoSqlTest.java | 4 +- .../service/sql/EdgeEventServiceSqlTest.java | 12 +- .../dao/service/sql/EdgeServiceSqlTest.java | 4 +- .../resources/sql/hsql/drop-all-tables.sql | 3 +- .../thingsboard/rule/engine/api/RuleNode.java | 2 +- .../rule/engine/api/TbContext.java | 3 + .../engine/action/TbAssignToCustomerNode.java | 2 +- .../rule/engine/action/TbClearAlarmNode.java | 2 +- .../TbCopyAttributesToEntityViewNode.java | 2 +- .../rule/engine/action/TbCreateAlarmNode.java | 2 +- .../engine/action/TbCreateRelationNode.java | 2 +- .../engine/action/TbDeleteRelationNode.java | 2 +- .../rule/engine/action/TbLogNode.java | 2 +- .../rule/engine/action/TbMsgCountNode.java | 2 +- .../action/TbUnassignFromCustomerNode.java | 2 +- .../rule/engine/aws/sns/TbSnsNode.java | 2 +- .../rule/engine/aws/sqs/TbSqsNode.java | 2 +- .../rule/engine/debug/TbMsgGeneratorNode.java | 2 +- .../rule/engine/delay/TbMsgDelayNode.java | 2 +- .../engine/edge/PushToEdgeNodeCallback.java | 41 ---- .../rule/engine/edge/TbMsgPushToEdgeNode.java | 97 ++++++++-- .../engine/filter/TbCheckMessageNode.java | 2 +- .../engine/filter/TbCheckRelationNode.java | 2 +- .../rule/engine/filter/TbJsFilterNode.java | 2 +- .../rule/engine/filter/TbJsSwitchNode.java | 2 +- .../engine/filter/TbMsgTypeFilterNode.java | 2 +- .../engine/filter/TbMsgTypeSwitchNode.java | 2 +- .../filter/TbOriginatorTypeFilterNode.java | 2 +- .../filter/TbOriginatorTypeSwitchNode.java | 2 +- .../rule/engine/gcp/pubsub/TbPubSubNode.java | 2 +- .../engine/geo/TbGpsGeofencingActionNode.java | 2 +- .../engine/geo/TbGpsGeofencingFilterNode.java | 2 +- .../rule/engine/kafka/TbKafkaNode.java | 2 +- .../rule/engine/mail/TbMsgToEmailNode.java | 2 +- .../rule/engine/mail/TbSendEmailNode.java | 2 +- .../engine/metadata/TbGetAttributesNode.java | 2 +- .../metadata/TbGetCustomerAttributeNode.java | 2 +- .../metadata/TbGetCustomerDetailsNode.java | 2 +- .../engine/metadata/TbGetDeviceAttrNode.java | 2 +- .../metadata/TbGetOriginatorFieldsNode.java | 2 +- .../metadata/TbGetRelatedAttributeNode.java | 2 +- .../engine/metadata/TbGetTelemetryNode.java | 2 +- .../metadata/TbGetTenantAttributeNode.java | 2 +- .../metadata/TbGetTenantDetailsNode.java | 2 +- .../rule/engine/mqtt/TbMqttNode.java | 2 +- .../rule/engine/rabbitmq/TbRabbitMqNode.java | 2 +- .../rule/engine/rest/TbRestApiCallNode.java | 2 +- .../rule/engine/rpc/TbSendRPCReplyNode.java | 2 +- .../rule/engine/rpc/TbSendRPCRequestNode.java | 2 +- .../engine/telemetry/TbMsgAttributesNode.java | 2 +- .../engine/telemetry/TbMsgTimeseriesNode.java | 2 +- .../TbSynchronizationBeginNode.java | 2 +- .../transaction/TbSynchronizationEndNode.java | 2 +- .../transform/TbChangeOriginatorNode.java | 2 +- .../engine/transform/TbTransformMsgNode.java | 2 +- ui/src/app/common/types.constant.js | 2 +- ui/src/app/locale/locale.constant-de_DE.json | 2 +- ui/src/app/locale/locale.constant-en_US.json | 2 +- ui/src/app/locale/locale.constant-es_ES.json | 2 +- ui/src/app/locale/locale.constant-fr_FR.json | 2 +- ui/src/app/rulechain/rulechain.controller.js | 2 +- ui/src/app/rulechain/rulechain.routes.js | 10 +- ui/src/app/rulechain/rulechains.controller.js | 2 +- ui/src/app/services/menu.service.js | 8 +- 111 files changed, 1353 insertions(+), 345 deletions(-) create mode 100644 common/dao-api/src/main/java/org/thingsboard/server/dao/edge/EdgeEventService.java create mode 100644 common/data/src/main/java/org/thingsboard/server/common/data/edge/EdgeEvent.java rename common/data/src/main/java/org/thingsboard/server/common/data/edge/{EdgeQueueEntityType.java => EdgeEventType.java} (95%) create mode 100644 common/data/src/main/java/org/thingsboard/server/common/data/id/EdgeEventId.java create mode 100644 dao/src/main/java/org/thingsboard/server/dao/edge/BaseEdgeEventService.java create mode 100644 dao/src/main/java/org/thingsboard/server/dao/edge/EdgeEventDao.java create mode 100644 dao/src/main/java/org/thingsboard/server/dao/model/nosql/EdgeEventEntity.java create mode 100644 dao/src/main/java/org/thingsboard/server/dao/model/sql/EdgeEventEntity.java create mode 100644 dao/src/main/java/org/thingsboard/server/dao/model/type/EdgeEventTypeCodec.java create mode 100644 dao/src/main/java/org/thingsboard/server/dao/sql/edge/EdgeEventRepository.java create mode 100644 dao/src/main/java/org/thingsboard/server/dao/sql/edge/JpaBaseEdgeEventDao.java create mode 100644 dao/src/test/java/org/thingsboard/server/dao/service/BaseEdgeEventServiceTest.java rename dao/src/test/java/org/thingsboard/server/dao/service/{EdgeServiceImplTest.java => BaseEdgeServiceTest.java} (99%) create mode 100644 dao/src/test/java/org/thingsboard/server/dao/service/nosql/EdgeEventServiceNoSqlTest.java rename common/data/src/main/java/org/thingsboard/server/common/data/edge/EdgeQueueEntry.java => dao/src/test/java/org/thingsboard/server/dao/service/sql/EdgeEventServiceSqlTest.java (70%) delete mode 100644 rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/edge/PushToEdgeNodeCallback.java diff --git a/application/src/main/java/org/thingsboard/server/actors/ActorSystemContext.java b/application/src/main/java/org/thingsboard/server/actors/ActorSystemContext.java index cf26a5aff8..e0c4e502e1 100644 --- a/application/src/main/java/org/thingsboard/server/actors/ActorSystemContext.java +++ b/application/src/main/java/org/thingsboard/server/actors/ActorSystemContext.java @@ -58,6 +58,7 @@ import org.thingsboard.server.dao.customer.CustomerService; import org.thingsboard.server.dao.dashboard.DashboardService; import org.thingsboard.server.dao.device.ClaimDevicesService; import org.thingsboard.server.dao.device.DeviceService; +import org.thingsboard.server.dao.edge.EdgeEventService; import org.thingsboard.server.dao.edge.EdgeService; import org.thingsboard.server.dao.entityview.EntityViewService; import org.thingsboard.server.dao.event.EventService; @@ -258,6 +259,11 @@ public class ActorSystemContext { @Getter private EdgeService edgeService; + @Lazy + @Autowired + @Getter + private EdgeEventService edgeEventService; + @Value("${actors.session.max_concurrent_sessions_per_device:1}") @Getter private long maxConcurrentSessionsPerDevice; diff --git a/application/src/main/java/org/thingsboard/server/actors/ruleChain/DefaultTbContext.java b/application/src/main/java/org/thingsboard/server/actors/ruleChain/DefaultTbContext.java index f222c4d862..55229694a7 100644 --- a/application/src/main/java/org/thingsboard/server/actors/ruleChain/DefaultTbContext.java +++ b/application/src/main/java/org/thingsboard/server/actors/ruleChain/DefaultTbContext.java @@ -51,6 +51,7 @@ import org.thingsboard.server.dao.cassandra.CassandraCluster; import org.thingsboard.server.dao.customer.CustomerService; import org.thingsboard.server.dao.dashboard.DashboardService; import org.thingsboard.server.dao.device.DeviceService; +import org.thingsboard.server.dao.edge.EdgeEventService; import org.thingsboard.server.dao.edge.EdgeService; import org.thingsboard.server.dao.entityview.EntityViewService; import org.thingsboard.server.dao.nosql.CassandraStatementTask; @@ -406,6 +407,11 @@ class DefaultTbContext implements TbContext { return mainCtx.getEdgeService(); } + @Override + public EdgeEventService getEdgeEventService() { + return mainCtx.getEdgeEventService(); + } + @Override public EventLoopGroup getSharedEventLoop() { return mainCtx.getSharedEventLoopGroupService().getSharedEventLoopGroup(); diff --git a/application/src/main/java/org/thingsboard/server/actors/ruleChain/RuleChainActorMessageProcessor.java b/application/src/main/java/org/thingsboard/server/actors/ruleChain/RuleChainActorMessageProcessor.java index 30e4e56ff3..d583eb6b0a 100644 --- a/application/src/main/java/org/thingsboard/server/actors/ruleChain/RuleChainActorMessageProcessor.java +++ b/application/src/main/java/org/thingsboard/server/actors/ruleChain/RuleChainActorMessageProcessor.java @@ -18,14 +18,11 @@ package org.thingsboard.server.actors.ruleChain; import akka.actor.ActorContext; import akka.actor.ActorRef; import akka.actor.Props; -import com.google.common.util.concurrent.FutureCallback; -import com.sun.istack.Nullable; import lombok.extern.slf4j.Slf4j; import org.thingsboard.rule.engine.api.TbRelationTypes; import org.thingsboard.server.actors.ActorSystemContext; import org.thingsboard.server.actors.service.DefaultActorService; import org.thingsboard.server.actors.shared.ComponentMsgProcessor; -import org.thingsboard.server.common.data.DataConstants; import org.thingsboard.server.common.data.EntityType; import org.thingsboard.server.common.data.id.EntityId; import org.thingsboard.server.common.data.id.RuleChainId; @@ -102,7 +99,7 @@ public class RuleChainActorMessageProcessor extends ComponentMsgProcessor ruleNodeList = service.getRuleChainNodes(tenantId, entityId); log.trace("[{}][{}] Starting rule chain with {} nodes", tenantId, entityId, ruleNodeList.size()); // Creating and starting the actors; @@ -124,7 +121,7 @@ public class RuleChainActorMessageProcessor extends ComponentMsgProcessor ruleNodeList = service.getRuleChainNodes(tenantId, entityId); log.trace("[{}][{}] Updating rule chain with {} nodes", tenantId, entityId, ruleNodeList.size()); @@ -224,7 +221,6 @@ public class RuleChainActorMessageProcessor extends ComponentMsgProcessor() { - @Override - public void onSuccess(@Nullable Void aVoid) { - log.debug("Event saved successfully!"); - } - - @Override - public void onFailure(Throwable t) { - log.debug("Failure during event save", t); - } - }); - } - - } - @Override protected RuleNodeException getInactiveException() { RuleNode firstRuleNode = firstNode != null ? firstNode.getSelf() : null; diff --git a/application/src/main/java/org/thingsboard/server/actors/ruleChain/RuleChainManagerActor.java b/application/src/main/java/org/thingsboard/server/actors/ruleChain/RuleChainManagerActor.java index 6a08a3e1ed..f591c394a3 100644 --- a/application/src/main/java/org/thingsboard/server/actors/ruleChain/RuleChainManagerActor.java +++ b/application/src/main/java/org/thingsboard/server/actors/ruleChain/RuleChainManagerActor.java @@ -56,7 +56,7 @@ public abstract class RuleChainManagerActor extends ContextAwareActor { } protected void initRuleChains() { - for (RuleChain ruleChain : new PageDataIterable<>(link -> ruleChainService.findTenantRuleChainsByType(tenantId, RuleChainType.SYSTEM, link), ContextAwareActor.ENTITY_PACK_LIMIT)) { + for (RuleChain ruleChain : new PageDataIterable<>(link -> ruleChainService.findTenantRuleChainsByType(tenantId, RuleChainType.CORE, link), ContextAwareActor.ENTITY_PACK_LIMIT)) { RuleChainId ruleChainId = ruleChain.getId(); log.debug("[{}|{}] Creating rule chain actor", ruleChainId.getEntityType(), ruleChain.getId()); //TODO: remove this cast making UUIDBased subclass of EntityId an interface and vice versa. @@ -67,7 +67,7 @@ public abstract class RuleChainManagerActor extends ContextAwareActor { } protected void visit(RuleChain entity, ActorRef actorRef) { - if (entity != null && entity.isRoot() && entity.getType().equals(RuleChainType.SYSTEM)) { + if (entity != null && entity.isRoot() && entity.getType().equals(RuleChainType.CORE)) { rootChain = entity; rootChainActor = actorRef; } diff --git a/application/src/main/java/org/thingsboard/server/actors/tenant/TenantActor.java b/application/src/main/java/org/thingsboard/server/actors/tenant/TenantActor.java index 900a3a88c3..246b5ad1e5 100644 --- a/application/src/main/java/org/thingsboard/server/actors/tenant/TenantActor.java +++ b/application/src/main/java/org/thingsboard/server/actors/tenant/TenantActor.java @@ -206,7 +206,7 @@ public class TenantActor extends RuleChainManagerActor { if (msg.getEntityId().getEntityType() == EntityType.RULE_CHAIN) { RuleChain ruleChain = systemContext.getRuleChainService(). findRuleChainById(tenantId, new RuleChainId(msg.getEntityId().getId())); - if (ruleChain != null && ruleChain.getType().equals(RuleChainType.SYSTEM)) { + if (ruleChain != null && ruleChain.getType().equals(RuleChainType.CORE)) { visit(ruleChain, target); } } diff --git a/application/src/main/java/org/thingsboard/server/controller/AlarmController.java b/application/src/main/java/org/thingsboard/server/controller/AlarmController.java index 7553448c09..e56b4b34ef 100644 --- a/application/src/main/java/org/thingsboard/server/controller/AlarmController.java +++ b/application/src/main/java/org/thingsboard/server/controller/AlarmController.java @@ -125,6 +125,8 @@ public class AlarmController extends BaseController { alarmService.ackAlarm(getCurrentUser().getTenantId(), alarmId, ackTs).get(); alarm.setAckTs(ackTs); logEntityAction(alarmId, alarm, getCurrentUser().getCustomerId(), ActionType.ALARM_ACK, null); + + sendNotificationMsgToEdgeService(getTenantId(), alarmId, ActionType.ALARM_ACK); } catch (Exception e) { throw handleException(e); } @@ -142,6 +144,8 @@ public class AlarmController extends BaseController { alarmService.clearAlarm(getCurrentUser().getTenantId(), alarmId, null, clearTs).get(); alarm.setClearTs(clearTs); logEntityAction(alarmId, alarm, getCurrentUser().getCustomerId(), ActionType.ALARM_CLEAR, null); + + sendNotificationMsgToEdgeService(getTenantId(), alarmId, ActionType.ALARM_CLEAR); } catch (Exception e) { throw handleException(e); } diff --git a/application/src/main/java/org/thingsboard/server/controller/AssetController.java b/application/src/main/java/org/thingsboard/server/controller/AssetController.java index dcd6bca3a2..31f256c03a 100644 --- a/application/src/main/java/org/thingsboard/server/controller/AssetController.java +++ b/application/src/main/java/org/thingsboard/server/controller/AssetController.java @@ -27,12 +27,14 @@ import org.springframework.web.bind.annotation.ResponseBody; import org.springframework.web.bind.annotation.ResponseStatus; import org.springframework.web.bind.annotation.RestController; import org.thingsboard.server.common.data.Customer; +import org.thingsboard.server.common.data.DataConstants; import org.thingsboard.server.common.data.EntitySubtype; import org.thingsboard.server.common.data.EntityType; import org.thingsboard.server.common.data.asset.Asset; import org.thingsboard.server.common.data.asset.AssetSearchQuery; import org.thingsboard.server.common.data.audit.ActionType; import org.thingsboard.server.common.data.edge.Edge; +import org.thingsboard.server.common.data.edge.EdgeEventType; import org.thingsboard.server.common.data.exception.ThingsboardException; import org.thingsboard.server.common.data.id.AssetId; import org.thingsboard.server.common.data.id.CustomerId; @@ -86,6 +88,8 @@ public class AssetController extends BaseController { Asset savedAsset = checkNotNull(assetService.saveAsset(asset)); + sendNotificationMsgToEdgeService(savedAsset.getTenantId(), savedAsset.getId(), EdgeEventType.ASSET, asset.getId() == null ? ActionType.ADDED : ActionType.UPDATED); + logEntityAction(savedAsset.getId(), savedAsset, savedAsset.getCustomerId(), asset.getId() == null ? ActionType.ADDED : ActionType.UPDATED, null); @@ -112,6 +116,7 @@ public class AssetController extends BaseController { asset.getCustomerId(), ActionType.DELETED, null, strAssetId); + sendNotificationMsgToEdgeService(getTenantId(), assetId, EdgeEventType.ASSET, ActionType.DELETED); } catch (Exception e) { logEntityAction(emptyId(EntityType.ASSET), null, @@ -354,6 +359,8 @@ public class AssetController extends BaseController { savedAsset.getCustomerId(), ActionType.ASSIGNED_TO_EDGE, null, strAssetId, strEdgeId, edge.getName()); + sendNotificationMsgToEdgeService(getTenantId(), savedAsset.getId(), EdgeEventType.ASSET, ActionType.ASSIGNED_TO_EDGE); + return savedAsset; } catch (Exception e) { @@ -385,6 +392,8 @@ public class AssetController extends BaseController { asset.getCustomerId(), ActionType.UNASSIGNED_FROM_EDGE, null, strAssetId, edge.getId().toString(), edge.getName()); + sendNotificationMsgToEdgeService(getTenantId(), savedAsset.getId(), EdgeEventType.ASSET, ActionType.UNASSIGNED_FROM_EDGE); + return savedAsset; } catch (Exception e) { diff --git a/application/src/main/java/org/thingsboard/server/controller/BaseController.java b/application/src/main/java/org/thingsboard/server/controller/BaseController.java index e3f0c381d1..77f066795c 100644 --- a/application/src/main/java/org/thingsboard/server/controller/BaseController.java +++ b/application/src/main/java/org/thingsboard/server/controller/BaseController.java @@ -39,6 +39,7 @@ import org.thingsboard.server.common.data.HasTenantId; import org.thingsboard.server.common.data.Tenant; import org.thingsboard.server.common.data.User; import org.thingsboard.server.common.data.alarm.Alarm; +import org.thingsboard.server.common.data.edge.EdgeEventType; import org.thingsboard.server.common.data.id.AlarmId; import org.thingsboard.server.common.data.alarm.AlarmInfo; import org.thingsboard.server.common.data.asset.Asset; @@ -66,6 +67,7 @@ import org.thingsboard.server.common.data.page.TextPageLink; import org.thingsboard.server.common.data.page.TimePageLink; import org.thingsboard.server.common.data.plugin.ComponentDescriptor; import org.thingsboard.server.common.data.plugin.ComponentType; +import org.thingsboard.server.common.data.relation.EntityRelation; import org.thingsboard.server.common.data.rule.RuleChain; import org.thingsboard.server.common.data.rule.RuleChainType; import org.thingsboard.server.common.data.rule.RuleNode; @@ -83,6 +85,7 @@ import org.thingsboard.server.dao.dashboard.DashboardService; import org.thingsboard.server.dao.device.ClaimDevicesService; import org.thingsboard.server.dao.device.DeviceCredentialsService; import org.thingsboard.server.dao.device.DeviceService; +import org.thingsboard.server.dao.edge.EdgeEventService; import org.thingsboard.server.dao.edge.EdgeService; import org.thingsboard.server.dao.entityview.EntityViewService; import org.thingsboard.server.dao.exception.DataValidationException; @@ -95,10 +98,12 @@ import org.thingsboard.server.dao.user.UserService; import org.thingsboard.server.dao.widget.WidgetTypeService; import org.thingsboard.server.dao.widget.WidgetsBundleService; import org.thingsboard.server.exception.ThingsboardErrorResponseHandler; +import org.thingsboard.server.gen.transport.TransportProtos; import org.thingsboard.server.queue.discovery.PartitionService; import org.thingsboard.server.queue.provider.TbQueueProducerProvider; import org.thingsboard.server.queue.util.TbCoreComponent; import org.thingsboard.server.service.component.ComponentDiscoveryService; +import org.thingsboard.server.service.edge.EdgeNotificationService; import org.thingsboard.server.service.queue.TbClusterService; import org.thingsboard.server.service.security.model.SecurityUser; import org.thingsboard.server.service.security.permission.AccessControlService; @@ -108,6 +113,7 @@ import org.thingsboard.server.service.state.DeviceStateService; import org.thingsboard.server.service.telemetry.TelemetrySubscriptionService; import javax.mail.MessagingException; +import javax.management.relation.Relation; import javax.servlet.http.HttpServletResponse; import java.util.List; import java.util.Optional; @@ -200,6 +206,12 @@ public abstract class BaseController { @Autowired protected EdgeService edgeService; + @Autowired + protected EdgeNotificationService edgeNotificationService; + + @Autowired + protected EdgeEventService edgeEventService; + @Value("${server.log_controller_error_stack_trace}") @Getter private boolean logControllerErrorStackTrace; @@ -559,7 +571,6 @@ public abstract class BaseController { } if (e == null) { pushEntityActionToRuleEngine(entityId, entity, user, customerId, actionType, additionalInfo); - // TODO: voba - refactor to push events to edge queue directly, instead of the rule engine flow } auditLogService.logEntityAction(user.getTenantId(), customerId, user.getId(), user.getName(), entityId, entity, actionType, e, additionalInfo); } @@ -600,16 +611,6 @@ public abstract class BaseController { case ALARM_CLEAR: msgType = DataConstants.ALARM_CLEAR; break; - case ASSIGNED_TO_EDGE: - msgType = DataConstants.ENTITY_ASSIGNED_TO_EDGE; - break; - case UNASSIGNED_FROM_EDGE: - msgType = DataConstants.ENTITY_UNASSIGNED_FROM_EDGE; - break; - case CREDENTIALS_UPDATED: - //TODO: voba - this is not efficient way to do this. Refactor on later stages - msgType = DataConstants.ENTITY_UPDATED; - break; } if (!StringUtils.isEmpty(msgType)) { try { @@ -698,5 +699,42 @@ public abstract class BaseController { return result; } + protected void sendNotificationMsgToEdgeService(TenantId tenantId, EntityRelation relation, ActionType edgeEventAction) { + try { + sendNotificationMsgToEdgeService(tenantId, null, json.writeValueAsString(relation), EdgeEventType.RELATION, edgeEventAction); + } catch (Exception e) { + log.warn("Failed to push relation to core: {}", relation, e); + } + } + + protected void sendNotificationMsgToEdgeService(TenantId tenantId, EntityId entityId, ActionType edgeEventAction) { + EdgeEventType edgeEventType = edgeEventService.getEdgeEventTypeByEntityType(entityId.getEntityType()); + if (edgeEventType != null) { + sendNotificationMsgToEdgeService(tenantId, entityId, null, edgeEventType, edgeEventAction); + } + } + + protected void sendNotificationMsgToEdgeService(TenantId tenantId, EntityId entityId, EdgeEventType edgeEventType, ActionType edgeEventAction) { + sendNotificationMsgToEdgeService(tenantId, entityId, null, edgeEventType, edgeEventAction); + } + + private void sendNotificationMsgToEdgeService(TenantId tenantId, EntityId entityId, String entityBody, EdgeEventType edgeEventType, ActionType edgeEventAction) { + TransportProtos.EdgeNotificationMsgProto.Builder builder = TransportProtos.EdgeNotificationMsgProto.newBuilder(); + builder.setTenantIdMSB(tenantId.getId().getMostSignificantBits()); + builder.setTenantIdLSB(tenantId.getId().getLeastSignificantBits()); + builder.setEdgeEventType(edgeEventType.name()); + builder.setEdgeEventAction(edgeEventAction.name()); + if (entityId != null) { + builder.setEntityIdMSB(entityId.getId().getMostSignificantBits()); + builder.setEntityIdLSB(entityId.getId().getLeastSignificantBits()); + builder.setEntityType(entityId.getEntityType().name()); + } + if (entityBody != null) { + builder.setEntityBody(entityBody); + } + TransportProtos.EdgeNotificationMsgProto msg = builder.build(); + tbClusterService.pushMsgToCore(tenantId, entityId != null ? entityId : tenantId, + TransportProtos.ToCoreMsg.newBuilder().setEdgeNotificationMsg(msg).build(), null); + } } diff --git a/application/src/main/java/org/thingsboard/server/controller/DashboardController.java b/application/src/main/java/org/thingsboard/server/controller/DashboardController.java index 5012e775ec..90d991a400 100644 --- a/application/src/main/java/org/thingsboard/server/controller/DashboardController.java +++ b/application/src/main/java/org/thingsboard/server/controller/DashboardController.java @@ -34,6 +34,7 @@ import org.thingsboard.server.common.data.ShortCustomerInfo; import org.thingsboard.server.common.data.ShortEdgeInfo; import org.thingsboard.server.common.data.audit.ActionType; import org.thingsboard.server.common.data.edge.Edge; +import org.thingsboard.server.common.data.edge.EdgeEventType; import org.thingsboard.server.common.data.exception.ThingsboardException; import org.thingsboard.server.common.data.id.CustomerId; import org.thingsboard.server.common.data.id.DashboardId; @@ -116,6 +117,9 @@ public class DashboardController extends BaseController { null, dashboard.getId() == null ? ActionType.ADDED : ActionType.UPDATED, null); + sendNotificationMsgToEdgeService(savedDashboard.getTenantId(), savedDashboard.getId(), + EdgeEventType.DASHBOARD, savedDashboard.getId() == null ? ActionType.ADDED : ActionType.UPDATED); + return savedDashboard; } catch (Exception e) { logEntityAction(emptyId(EntityType.DASHBOARD), dashboard, @@ -139,6 +143,7 @@ public class DashboardController extends BaseController { null, ActionType.DELETED, null, strDashboardId); + sendNotificationMsgToEdgeService(getTenantId(), dashboardId, EdgeEventType.DASHBOARD, ActionType.DELETED); } catch (Exception e) { logEntityAction(emptyId(EntityType.DASHBOARD), @@ -495,6 +500,7 @@ public class DashboardController extends BaseController { null, ActionType.ASSIGNED_TO_EDGE, null, strDashboardId, strEdgeId, edge.getName()); + sendNotificationMsgToEdgeService(getTenantId(), savedDashboard.getId(), EdgeEventType.DASHBOARD, ActionType.ASSIGNED_TO_EDGE); return savedDashboard; } catch (Exception e) { @@ -526,6 +532,8 @@ public class DashboardController extends BaseController { null, ActionType.UNASSIGNED_FROM_EDGE, null, strDashboardId, edge.getId().toString(), edge.getName()); + sendNotificationMsgToEdgeService(getTenantId(), savedDashboard.getId(), EdgeEventType.DASHBOARD, ActionType.UNASSIGNED_FROM_EDGE); + return savedDashboard; } catch (Exception e) { diff --git a/application/src/main/java/org/thingsboard/server/controller/DeviceController.java b/application/src/main/java/org/thingsboard/server/controller/DeviceController.java index 0218ebf47e..0f24507cbc 100644 --- a/application/src/main/java/org/thingsboard/server/controller/DeviceController.java +++ b/application/src/main/java/org/thingsboard/server/controller/DeviceController.java @@ -42,6 +42,7 @@ import org.thingsboard.server.common.data.EntityType; import org.thingsboard.server.common.data.audit.ActionType; import org.thingsboard.server.common.data.device.DeviceSearchQuery; import org.thingsboard.server.common.data.edge.Edge; +import org.thingsboard.server.common.data.edge.EdgeEventType; import org.thingsboard.server.common.data.exception.ThingsboardException; import org.thingsboard.server.common.data.id.CustomerId; import org.thingsboard.server.common.data.id.DeviceId; @@ -57,6 +58,7 @@ import org.thingsboard.server.dao.device.claim.ClaimResponse; import org.thingsboard.server.dao.device.claim.ClaimResult; import org.thingsboard.server.dao.exception.IncorrectParameterException; import org.thingsboard.server.dao.model.ModelConstants; +import org.thingsboard.server.gen.transport.TransportProtos; import org.thingsboard.server.queue.util.TbCoreComponent; import org.thingsboard.server.service.security.model.SecurityUser; import org.thingsboard.server.service.security.permission.Operation; @@ -106,6 +108,8 @@ public class DeviceController extends BaseController { tbClusterService.pushMsgToCore(new DeviceNameOrTypeUpdateMsg(savedDevice.getTenantId(), savedDevice.getId(), savedDevice.getName(), savedDevice.getType()), null); + sendNotificationMsgToEdgeService(savedDevice.getTenantId(), savedDevice.getId(), EdgeEventType.DEVICE, device.getId() == null ? ActionType.ADDED : ActionType.UPDATED); + logEntityAction(savedDevice.getId(), savedDevice, savedDevice.getCustomerId(), device.getId() == null ? ActionType.ADDED : ActionType.UPDATED, null); @@ -137,6 +141,8 @@ public class DeviceController extends BaseController { device.getCustomerId(), ActionType.DELETED, null, strDeviceId); + sendNotificationMsgToEdgeService(getTenantId(), deviceId, EdgeEventType.DEVICE, ActionType.DELETED); + deviceStateService.onDeviceDeleted(device); } catch (Exception e) { logEntityAction(emptyId(EntityType.DEVICE), @@ -260,6 +266,8 @@ public class DeviceController extends BaseController { tbClusterService.pushMsgToCore(new DeviceCredentialsUpdateNotificationMsg(getCurrentUser().getTenantId(), deviceCredentials.getDeviceId()), null); + sendNotificationMsgToEdgeService(getTenantId(), device.getId(), EdgeEventType.DEVICE, ActionType.CREDENTIALS_UPDATED); + logEntityAction(device.getId(), device, device.getCustomerId(), ActionType.CREDENTIALS_UPDATED, null, deviceCredentials); @@ -509,6 +517,8 @@ public class DeviceController extends BaseController { savedDevice.getCustomerId(), ActionType.ASSIGNED_TO_EDGE, null, strDeviceId, strEdgeId, edge.getName()); + sendNotificationMsgToEdgeService(getTenantId(), savedDevice.getId(), EdgeEventType.DEVICE, ActionType.ASSIGNED_TO_EDGE); + return savedDevice; } catch (Exception e) { logEntityAction(emptyId(EntityType.DEVICE), null, @@ -538,6 +548,8 @@ public class DeviceController extends BaseController { device.getCustomerId(), ActionType.UNASSIGNED_FROM_EDGE, null, strDeviceId, edge.getId().toString(), edge.getName()); + sendNotificationMsgToEdgeService(getTenantId(), savedDevice.getId(), EdgeEventType.DEVICE, ActionType.UNASSIGNED_FROM_EDGE); + return savedDevice; } catch (Exception e) { logEntityAction(emptyId(EntityType.DEVICE), null, diff --git a/application/src/main/java/org/thingsboard/server/controller/EdgeController.java b/application/src/main/java/org/thingsboard/server/controller/EdgeController.java index d263497527..b6f2c31561 100644 --- a/application/src/main/java/org/thingsboard/server/controller/EdgeController.java +++ b/application/src/main/java/org/thingsboard/server/controller/EdgeController.java @@ -97,7 +97,7 @@ public class EdgeController extends BaseController { if (created) { ruleChainService.assignRuleChainToEdge(tenantId, defaultRootEdgeRuleChain.getId(), savedEdge.getId()); - edgeService.setEdgeRootRuleChain(tenantId, savedEdge, defaultRootEdgeRuleChain.getId()); + edgeNotificationService.setEdgeRootRuleChain(tenantId, savedEdge, defaultRootEdgeRuleChain.getId()); edgeService.assignDefaultRuleChainsToEdge(tenantId, savedEdge.getId()); } @@ -257,8 +257,7 @@ public class EdgeController extends BaseController { @PreAuthorize("hasAuthority('TENANT_ADMIN')") @RequestMapping(value = "/tenant/edges", params = {"edgeName"}, method = RequestMethod.GET) @ResponseBody - public Edge getTenantEdge( - @RequestParam String edgeName) throws ThingsboardException { + public Edge getTenantEdge(@RequestParam String edgeName) throws ThingsboardException { try { TenantId tenantId = getCurrentUser().getTenantId(); return checkNotNull(edgeService.findEdgeByTenantIdAndName(tenantId, edgeName)); @@ -283,7 +282,7 @@ public class EdgeController extends BaseController { accessControlService.checkPermission(getCurrentUser(), Resource.EDGE, Operation.WRITE, edge.getId(), edge); - Edge updatedEdge = edgeService.setEdgeRootRuleChain(getTenantId(), edge, ruleChainId); + Edge updatedEdge = edgeNotificationService.setEdgeRootRuleChain(getTenantId(), edge, ruleChainId); logEntityAction(updatedEdge.getId(), updatedEdge, null, ActionType.UPDATED, null); diff --git a/application/src/main/java/org/thingsboard/server/controller/EntityRelationController.java b/application/src/main/java/org/thingsboard/server/controller/EntityRelationController.java index 88aa9ce850..38060c7731 100644 --- a/application/src/main/java/org/thingsboard/server/controller/EntityRelationController.java +++ b/application/src/main/java/org/thingsboard/server/controller/EntityRelationController.java @@ -24,7 +24,9 @@ import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.ResponseBody; import org.springframework.web.bind.annotation.ResponseStatus; import org.springframework.web.bind.annotation.RestController; +import org.thingsboard.server.common.data.DataConstants; import org.thingsboard.server.common.data.audit.ActionType; +import org.thingsboard.server.common.data.edge.EdgeEventType; import org.thingsboard.server.common.data.exception.ThingsboardErrorCode; import org.thingsboard.server.common.data.exception.ThingsboardException; import org.thingsboard.server.common.data.id.EntityId; @@ -63,10 +65,13 @@ public class EntityRelationController extends BaseController { relation.setTypeGroup(RelationTypeGroup.COMMON); } relationService.saveRelation(getTenantId(), relation); + logEntityAction(relation.getFrom(), null, getCurrentUser().getCustomerId(), ActionType.RELATION_ADD_OR_UPDATE, null, relation); logEntityAction(relation.getTo(), null, getCurrentUser().getCustomerId(), ActionType.RELATION_ADD_OR_UPDATE, null, relation); + + sendNotificationMsgToEdgeService(getTenantId(), relation, ActionType.RELATION_ADD_OR_UPDATE); } catch (Exception e) { logEntityAction(relation.getFrom(), null, getCurrentUser().getCustomerId(), ActionType.RELATION_ADD_OR_UPDATE, e, relation); @@ -104,6 +109,8 @@ public class EntityRelationController extends BaseController { ActionType.RELATION_DELETED, null, relation); logEntityAction(relation.getTo(), null, getCurrentUser().getCustomerId(), ActionType.RELATION_DELETED, null, relation); + + sendNotificationMsgToEdgeService(getTenantId(), relation, ActionType.RELATION_DELETED); } catch (Exception e) { logEntityAction(relation.getFrom(), null, getCurrentUser().getCustomerId(), ActionType.RELATION_DELETED, e, relation); @@ -125,6 +132,8 @@ public class EntityRelationController extends BaseController { try { relationService.deleteEntityRelations(getTenantId(), entityId); logEntityAction(entityId, null, getCurrentUser().getCustomerId(), ActionType.RELATIONS_DELETED, null); + + sendNotificationMsgToEdgeService(getTenantId(), entityId, ActionType.RELATIONS_DELETED); } catch (Exception e) { logEntityAction(entityId, null, getCurrentUser().getCustomerId(), ActionType.RELATIONS_DELETED, e); throw handleException(e); diff --git a/application/src/main/java/org/thingsboard/server/controller/EntityViewController.java b/application/src/main/java/org/thingsboard/server/controller/EntityViewController.java index 3318ff8e79..970cd98db3 100644 --- a/application/src/main/java/org/thingsboard/server/controller/EntityViewController.java +++ b/application/src/main/java/org/thingsboard/server/controller/EntityViewController.java @@ -37,6 +37,7 @@ import org.thingsboard.server.common.data.EntityType; import org.thingsboard.server.common.data.EntityView; import org.thingsboard.server.common.data.audit.ActionType; import org.thingsboard.server.common.data.edge.Edge; +import org.thingsboard.server.common.data.edge.EdgeEventType; import org.thingsboard.server.common.data.entityview.EntityViewSearchQuery; import org.thingsboard.server.common.data.exception.ThingsboardException; import org.thingsboard.server.common.data.id.CustomerId; @@ -116,6 +117,8 @@ public class EntityViewController extends BaseController { logEntityAction(savedEntityView.getId(), savedEntityView, null, entityView.getId() == null ? ActionType.ADDED : ActionType.UPDATED, null); + + sendNotificationMsgToEdgeService(getTenantId(), savedEntityView.getId(), EdgeEventType.ENTITY_VIEW, entityView.getId() == null ? ActionType.ADDED : ActionType.UPDATED); return savedEntityView; } catch (Exception e) { logEntityAction(emptyId(EntityType.ENTITY_VIEW), entityView, null, @@ -185,6 +188,8 @@ public class EntityViewController extends BaseController { entityViewService.deleteEntityView(getTenantId(), entityViewId); logEntityAction(entityViewId, entityView, entityView.getCustomerId(), ActionType.DELETED, null, strEntityViewId); + + sendNotificationMsgToEdgeService(getTenantId(), entityViewId, EdgeEventType.ENTITY_VIEW, ActionType.DELETED); } catch (Exception e) { logEntityAction(emptyId(EntityType.ENTITY_VIEW), null, @@ -389,6 +394,9 @@ public class EntityViewController extends BaseController { logEntityAction(entityViewId, savedEntityView, savedEntityView.getCustomerId(), ActionType.ASSIGNED_TO_EDGE, null, strEntityViewId, strEdgeId, edge.getName()); + + sendNotificationMsgToEdgeService(getTenantId(), savedEntityView.getId(), EdgeEventType.ENTITY_VIEW, ActionType.ASSIGNED_TO_EDGE); + return savedEntityView; } catch (Exception e) { logEntityAction(emptyId(EntityType.ENTITY_VIEW), null, @@ -417,6 +425,8 @@ public class EntityViewController extends BaseController { entityView.getCustomerId(), ActionType.UNASSIGNED_FROM_EDGE, null, strEntityViewId, edge.getId().toString(), edge.getName()); + sendNotificationMsgToEdgeService(getTenantId(), savedEntityView.getId(), EdgeEventType.ENTITY_VIEW, ActionType.UNASSIGNED_FROM_EDGE); + return savedEntityView; } catch (Exception e) { logEntityAction(emptyId(EntityType.ENTITY_VIEW), null, diff --git a/application/src/main/java/org/thingsboard/server/controller/RuleChainController.java b/application/src/main/java/org/thingsboard/server/controller/RuleChainController.java index 604d3b62dd..ce4a96c2c9 100644 --- a/application/src/main/java/org/thingsboard/server/controller/RuleChainController.java +++ b/application/src/main/java/org/thingsboard/server/controller/RuleChainController.java @@ -41,6 +41,7 @@ import org.thingsboard.server.common.data.EntityType; import org.thingsboard.server.common.data.Event; import org.thingsboard.server.common.data.audit.ActionType; import org.thingsboard.server.common.data.edge.Edge; +import org.thingsboard.server.common.data.edge.EdgeEventType; import org.thingsboard.server.common.data.exception.ThingsboardException; import org.thingsboard.server.common.data.id.EdgeId; import org.thingsboard.server.common.data.id.RuleChainId; @@ -134,7 +135,7 @@ public class RuleChainController extends BaseController { RuleChain savedRuleChain = checkNotNull(ruleChainService.saveRuleChain(ruleChain)); - if (RuleChainType.SYSTEM.equals(savedRuleChain.getType())) { + if (RuleChainType.CORE.equals(savedRuleChain.getType())) { tbClusterService.onEntityStateChange(ruleChain.getTenantId(), savedRuleChain.getId(), created ? ComponentLifecycleEvent.CREATED : ComponentLifecycleEvent.UPDATED); } @@ -143,6 +144,12 @@ public class RuleChainController extends BaseController { null, created ? ActionType.ADDED : ActionType.UPDATED, null); + if (RuleChainType.EDGE.equals(savedRuleChain.getType())) { + sendNotificationMsgToEdgeService(savedRuleChain.getTenantId(), + savedRuleChain.getId(), EdgeEventType.RULE_CHAIN, + savedRuleChain.getId() == null ? ActionType.ADDED : ActionType.UPDATED); + } + return savedRuleChain; } catch (Exception e) { @@ -209,7 +216,7 @@ public class RuleChainController extends BaseController { RuleChain ruleChain = checkRuleChain(ruleChainMetaData.getRuleChainId(), Operation.WRITE); RuleChainMetaData savedRuleChainMetaData = checkNotNull(ruleChainService.saveRuleChainMetaData(tenantId, ruleChainMetaData)); - if (RuleChainType.SYSTEM.equals(ruleChain.getType())) { + if (RuleChainType.CORE.equals(ruleChain.getType())) { tbClusterService.onEntityStateChange(ruleChain.getTenantId(), ruleChain.getId(), ComponentLifecycleEvent.UPDATED); } @@ -217,6 +224,12 @@ public class RuleChainController extends BaseController { null, ActionType.UPDATED, null, ruleChainMetaData); + if (RuleChainType.EDGE.equals(ruleChain.getType())) { + sendNotificationMsgToEdgeService(ruleChain.getTenantId(), + ruleChain.getId(), EdgeEventType.RULE_CHAIN, + ActionType.UPDATED); + } + return savedRuleChainMetaData; } catch (Exception e) { @@ -243,7 +256,7 @@ public class RuleChainController extends BaseController { RuleChainType type = RuleChainType.valueOf(typeStr); return checkNotNull(ruleChainService.findTenantRuleChainsByType(tenantId, type, pageLink)); } else { - return checkNotNull(ruleChainService.findTenantRuleChainsByType(tenantId, RuleChainType.SYSTEM, pageLink)); + return checkNotNull(ruleChainService.findTenantRuleChainsByType(tenantId, RuleChainType.CORE, pageLink)); } } catch (Exception e) { throw handleException(e); @@ -267,7 +280,7 @@ public class RuleChainController extends BaseController { referencingRuleChainIds.remove(ruleChain.getId()); - if (RuleChainType.SYSTEM.equals(ruleChain.getType())) { + if (RuleChainType.CORE.equals(ruleChain.getType())) { referencingRuleChainIds.forEach(referencingRuleChainId -> tbClusterService.onEntityStateChange(ruleChain.getTenantId(), referencingRuleChainId, ComponentLifecycleEvent.UPDATED)); @@ -278,6 +291,12 @@ public class RuleChainController extends BaseController { null, ActionType.DELETED, null, strRuleChainId); + if (RuleChainType.EDGE.equals(ruleChain.getType())) { + sendNotificationMsgToEdgeService(ruleChain.getTenantId(), + ruleChain.getId(), EdgeEventType.RULE_CHAIN, + ActionType.DELETED); + } + } catch (Exception e) { logEntityAction(emptyId(EntityType.RULE_CHAIN), null, @@ -407,6 +426,8 @@ public class RuleChainController extends BaseController { null, ActionType.ASSIGNED_TO_EDGE, null, strRuleChainId, strEdgeId, edge.getName()); + sendNotificationMsgToEdgeService(getTenantId(), savedRuleChain.getId(), + EdgeEventType.RULE_CHAIN, ActionType.ASSIGNED_TO_EDGE); return savedRuleChain; } catch (Exception e) { @@ -438,6 +459,9 @@ public class RuleChainController extends BaseController { null, ActionType.UNASSIGNED_FROM_EDGE, null, strRuleChainId, edge.getId().toString(), edge.getName()); + sendNotificationMsgToEdgeService(getTenantId(), savedRuleChain.getId(), + EdgeEventType.RULE_CHAIN, ActionType.UNASSIGNED_FROM_EDGE); + return savedRuleChain; } catch (Exception e) { diff --git a/application/src/main/java/org/thingsboard/server/service/component/AnnotationComponentDiscoveryService.java b/application/src/main/java/org/thingsboard/server/service/component/AnnotationComponentDiscoveryService.java index 2203fb461b..43231768f9 100644 --- a/application/src/main/java/org/thingsboard/server/service/component/AnnotationComponentDiscoveryService.java +++ b/application/src/main/java/org/thingsboard/server/service/component/AnnotationComponentDiscoveryService.java @@ -116,7 +116,7 @@ public class AnnotationComponentDiscoveryService implements ComponentDiscoverySe } private void putComponentIntoMaps(ComponentType type, RuleNode ruleNodeAnnotation, ComponentDescriptor component) { - if (ruleChainTypeContainsArray(RuleChainType.SYSTEM, ruleNodeAnnotation.ruleChainTypes())) { + if (ruleChainTypeContainsArray(RuleChainType.CORE, ruleNodeAnnotation.ruleChainTypes())) { systemComponentsMap.computeIfAbsent(type, k -> new ArrayList<>()).add(component); } if (ruleChainTypeContainsArray(RuleChainType.EDGE, ruleNodeAnnotation.ruleChainTypes())) { @@ -225,7 +225,7 @@ public class AnnotationComponentDiscoveryService implements ComponentDiscoverySe @Override public List getComponents(Set types, RuleChainType ruleChainType) { - if (RuleChainType.SYSTEM.equals(ruleChainType)) { + if (RuleChainType.CORE.equals(ruleChainType)) { return getComponents(types, systemComponentsMap); } else if (RuleChainType.EDGE.equals(ruleChainType)) { return getComponents(types, edgeComponentsMap); diff --git a/application/src/main/java/org/thingsboard/server/service/edge/DefaultEdgeNotificationService.java b/application/src/main/java/org/thingsboard/server/service/edge/DefaultEdgeNotificationService.java index a65e95d0ff..96f127d9be 100644 --- a/application/src/main/java/org/thingsboard/server/service/edge/DefaultEdgeNotificationService.java +++ b/application/src/main/java/org/thingsboard/server/service/edge/DefaultEdgeNotificationService.java @@ -1,3 +1,18 @@ +/** + * Copyright © 2016-2020 The Thingsboard Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package org.thingsboard.server.service.edge; import com.fasterxml.jackson.databind.ObjectMapper; @@ -17,9 +32,10 @@ import org.thingsboard.server.common.data.EntityView; import org.thingsboard.server.common.data.Event; import org.thingsboard.server.common.data.alarm.Alarm; import org.thingsboard.server.common.data.asset.Asset; +import org.thingsboard.server.common.data.audit.ActionType; import org.thingsboard.server.common.data.edge.Edge; -import org.thingsboard.server.common.data.edge.EdgeQueueEntityType; -import org.thingsboard.server.common.data.edge.EdgeQueueEntry; +import org.thingsboard.server.common.data.edge.EdgeEvent; +import org.thingsboard.server.common.data.edge.EdgeEventType; import org.thingsboard.server.common.data.id.EdgeId; import org.thingsboard.server.common.data.id.EntityId; import org.thingsboard.server.common.data.id.RuleChainId; @@ -36,6 +52,7 @@ import org.thingsboard.server.common.msg.queue.TbCallback; import org.thingsboard.server.common.msg.session.SessionMsgType; import org.thingsboard.server.dao.asset.AssetService; import org.thingsboard.server.dao.device.DeviceService; +import org.thingsboard.server.dao.edge.EdgeEventService; import org.thingsboard.server.dao.edge.EdgeService; import org.thingsboard.server.dao.entityview.EntityViewService; import org.thingsboard.server.dao.event.EventService; @@ -79,7 +96,7 @@ public class DefaultEdgeNotificationService implements EdgeNotificationService { private RelationService relationService; @Autowired - private EventService eventService; + private EdgeEventService edgeEventService; private ExecutorService tsCallBackExecutor; @@ -96,8 +113,8 @@ public class DefaultEdgeNotificationService implements EdgeNotificationService { } @Override - public TimePageData findQueueEvents(TenantId tenantId, EdgeId edgeId, TimePageLink pageLink) { - return eventService.findEvents(tenantId, edgeId, DataConstants.EDGE_QUEUE_EVENT_TYPE, pageLink); + public TimePageData findEdgeEvents(TenantId tenantId, EdgeId edgeId, TimePageLink pageLink) { + return edgeEventService.findEdgeEvents(tenantId, edgeId, pageLink); } @Override @@ -105,7 +122,7 @@ public class DefaultEdgeNotificationService implements EdgeNotificationService { edge.setRootRuleChainId(ruleChainId); Edge savedEdge = edgeService.saveEdge(edge); RuleChain ruleChain = ruleChainService.findRuleChainById(tenantId, ruleChainId); - saveEventToEdgeQueue(tenantId, edge.getId(), EdgeQueueEntityType.RULE_CHAIN, DataConstants.ENTITY_UPDATED, mapper.writeValueAsString(ruleChain), new FutureCallback() { + saveEventToEdgeQueue(tenantId, edge.getId(), EdgeEventType.RULE_CHAIN, DataConstants.ENTITY_UPDATED, mapper.writeValueAsString(ruleChain), new FutureCallback() { @Override public void onSuccess(@Nullable Void aVoid) { log.debug("Event saved successfully!"); @@ -119,28 +136,28 @@ public class DefaultEdgeNotificationService implements EdgeNotificationService { return savedEdge; } - private void saveEventToEdgeQueue(TenantId tenantId, EdgeId edgeId, EdgeQueueEntityType entityType, String type, String data, FutureCallback callback) throws IOException { + private void saveEventToEdgeQueue(TenantId tenantId, EdgeId edgeId, EdgeEventType entityType, String type, String data, FutureCallback callback) throws IOException { log.debug("Pushing single event to edge queue. tenantId [{}], edgeId [{}], entityType [{}], type[{}], data [{}]", tenantId, edgeId, entityType, type, data); - EdgeQueueEntry queueEntry = new EdgeQueueEntry(); - queueEntry.setEntityType(entityType); - queueEntry.setType(type); - queueEntry.setData(data); +// EdgeEQueueEntry queueEntry = new EdgeQueueEntry(); +// queueEntry.setEntityType(entityType); +// queueEntry.setType(type); +// queueEntry.setData(data); - Event event = new Event(); - event.setEntityId(edgeId); - event.setTenantId(tenantId); - event.setType(DataConstants.EDGE_QUEUE_EVENT_TYPE); - event.setBody(mapper.valueToTree(queueEntry)); - ListenableFuture saveFuture = eventService.saveAsync(event); + EdgeEvent edgeEvent = new EdgeEvent(); + edgeEvent.setEdgeId(edgeId); + edgeEvent.setTenantId(tenantId); +// event.setType(DataConstants.EDGE_QUEUE_EVENT_TYPE); +// event.setBody(mapper.valueToTree(queueEntry)); + ListenableFuture saveFuture = edgeEventService.saveAsync(edgeEvent); addMainCallback(saveFuture, callback); } - private void addMainCallback(ListenableFuture saveFuture, final FutureCallback callback) { - Futures.addCallback(saveFuture, new FutureCallback() { + private void addMainCallback(ListenableFuture saveFuture, final FutureCallback callback) { + Futures.addCallback(saveFuture, new FutureCallback() { @Override - public void onSuccess(@Nullable Event result) { + public void onSuccess(@Nullable EdgeEvent result) { callback.onSuccess(null); } @@ -153,52 +170,52 @@ public class DefaultEdgeNotificationService implements EdgeNotificationService { @Override public void pushNotificationToEdge(TransportProtos.EdgeNotificationMsgProto edgeNotificationMsg, TbCallback callback) { - if (tbMsg.getType().equals(SessionMsgType.POST_TELEMETRY_REQUEST.name()) || - tbMsg.getType().equals(SessionMsgType.POST_ATTRIBUTES_REQUEST.name()) || - tbMsg.getType().equals(DataConstants.ATTRIBUTES_UPDATED) || - tbMsg.getType().equals(DataConstants.ATTRIBUTES_DELETED)) { - processCustomTbMsg(tenantId, tbMsg, callback); - } else { - try { - switch (tbMsg.getOriginator().getEntityType()) { - case EDGE: - processEdge(tenantId, tbMsg, callback); - break; - case ASSET: - processAsset(tenantId, tbMsg, callback); - break; - case DEVICE: - processDevice(tenantId, tbMsg, callback); - break; - case DASHBOARD: - processDashboard(tenantId, tbMsg, callback); - break; - case RULE_CHAIN: - processRuleChain(tenantId, tbMsg, callback); - break; - case ENTITY_VIEW: - processEntityView(tenantId, tbMsg, callback); - break; - case ALARM: - processAlarm(tenantId, tbMsg, callback); - break; - default: - log.debug("Entity type [{}] is not designed to be pushed to edge", tbMsg.getOriginator().getEntityType()); - } - } catch (IOException e) { - log.error("Can't push to edge updates, entity type [{}], data [{}]", tbMsg.getOriginator().getEntityType(), tbMsg.getData(), e); - } - } +// if (tbMsg.getType().equals(SessionMsgType.POST_TELEMETRY_REQUEST.name()) || +// tbMsg.getType().equals(SessionMsgType.POST_ATTRIBUTES_REQUEST.name()) || +// tbMsg.getType().equals(DataConstants.ATTRIBUTES_UPDATED) || +// tbMsg.getType().equals(DataConstants.ATTRIBUTES_DELETED)) { +// processCustomTbMsg(tenantId, tbMsg, callback); +// } else { +// try { +// switch (tbMsg.getOriginator().getEntityType()) { +// case EDGE: +// processEdge(tenantId, tbMsg, callback); +// break; +// case ASSET: +// processAsset(tenantId, tbMsg, callback); +// break; +// case DEVICE: +// processDevice(tenantId, tbMsg, callback); +// break; +// case DASHBOARD: +// processDashboard(tenantId, tbMsg, callback); +// break; +// case RULE_CHAIN: +// processRuleChain(tenantId, tbMsg, callback); +// break; +// case ENTITY_VIEW: +// processEntityView(tenantId, tbMsg, callback); +// break; +// case ALARM: +// processAlarm(tenantId, tbMsg, callback); +// break; +// default: +// log.debug("Entity type [{}] is not designed to be pushed to edge", tbMsg.getOriginator().getEntityType()); +// } +// } catch (IOException e) { +// log.error("Can't push to edge updates, entity type [{}], data [{}]", tbMsg.getOriginator().getEntityType(), tbMsg.getData(), e); +// } +// } } private void processCustomTbMsg(TenantId tenantId, TbMsg tbMsg, FutureCallback callback) { ListenableFuture edgeIdFuture = getEdgeIdByOriginatorId(tenantId, tbMsg.getOriginator()); Futures.transform(edgeIdFuture, edgeId -> { - EdgeQueueEntityType edgeQueueEntityType = getEdgeQueueTypeByEntityType(tbMsg.getOriginator().getEntityType()); - if (edgeId != null && edgeQueueEntityType != null) { + EdgeEventType edgeEventType = getEdgeQueueTypeByEntityType(tbMsg.getOriginator().getEntityType()); + if (edgeId != null && edgeEventType != null) { try { - saveEventToEdgeQueue(tenantId, edgeId, edgeQueueEntityType, tbMsg.getType(), Base64.encodeBase64String(TbMsg.toByteArray(tbMsg)), callback); + saveEventToEdgeQueue(tenantId, edgeId, edgeEventType, tbMsg.getType(), Base64.encodeBase64String(TbMsg.toByteArray(tbMsg)), callback); } catch (IOException e) { log.error("Error while saving custom tbMsg into Edge Queue", e); } @@ -211,13 +228,13 @@ public class DefaultEdgeNotificationService implements EdgeNotificationService { switch (tbMsg.getType()) { case DataConstants.ENTITY_ASSIGNED_TO_EDGE: case DataConstants.ENTITY_UNASSIGNED_FROM_EDGE: - processAssignedEntity(tenantId, tbMsg, EdgeQueueEntityType.DEVICE, callback); + processAssignedEntity(tenantId, tbMsg, EdgeEventType.DEVICE, callback); break; case DataConstants.ENTITY_DELETED: case DataConstants.ENTITY_CREATED: case DataConstants.ENTITY_UPDATED: Device device = mapper.readValue(tbMsg.getData(), Device.class); - pushEventToEdge(tenantId, device.getId(), EdgeQueueEntityType.DEVICE, tbMsg, callback); + pushEventToEdge(tenantId, device.getId(), EdgeEventType.DEVICE, tbMsg, callback); break; default: log.warn("Unsupported msgType [{}], tbMsg [{}]", tbMsg.getType(), tbMsg); @@ -240,13 +257,13 @@ public class DefaultEdgeNotificationService implements EdgeNotificationService { switch (tbMsg.getType()) { case DataConstants.ENTITY_ASSIGNED_TO_EDGE: case DataConstants.ENTITY_UNASSIGNED_FROM_EDGE: - processAssignedEntity(tenantId, tbMsg, EdgeQueueEntityType.ASSET, callback); + processAssignedEntity(tenantId, tbMsg, EdgeEventType.ASSET, callback); break; case DataConstants.ENTITY_DELETED: case DataConstants.ENTITY_CREATED: case DataConstants.ENTITY_UPDATED: Asset asset = mapper.readValue(tbMsg.getData(), Asset.class); - pushEventToEdge(tenantId, asset.getId(), EdgeQueueEntityType.ASSET, tbMsg, callback); + pushEventToEdge(tenantId, asset.getId(), EdgeEventType.ASSET, tbMsg, callback); break; default: log.warn("Unsupported msgType [{}], tbMsg [{}]", tbMsg.getType(), tbMsg); @@ -257,13 +274,13 @@ public class DefaultEdgeNotificationService implements EdgeNotificationService { switch (tbMsg.getType()) { case DataConstants.ENTITY_ASSIGNED_TO_EDGE: case DataConstants.ENTITY_UNASSIGNED_FROM_EDGE: - processAssignedEntity(tenantId, tbMsg, EdgeQueueEntityType.ENTITY_VIEW, callback); + processAssignedEntity(tenantId, tbMsg, EdgeEventType.ENTITY_VIEW, callback); break; case DataConstants.ENTITY_DELETED: case DataConstants.ENTITY_CREATED: case DataConstants.ENTITY_UPDATED: EntityView entityView = mapper.readValue(tbMsg.getData(), EntityView.class); - pushEventToEdge(tenantId, entityView.getId(), EdgeQueueEntityType.ENTITY_VIEW, tbMsg, callback); + pushEventToEdge(tenantId, entityView.getId(), EdgeEventType.ENTITY_VIEW, tbMsg, callback); break; default: log.warn("Unsupported msgType [{}], tbMsg [{}]", tbMsg.getType(), tbMsg); @@ -278,9 +295,9 @@ public class DefaultEdgeNotificationService implements EdgeNotificationService { case DataConstants.ALARM_ACK: case DataConstants.ALARM_CLEAR: Alarm alarm = mapper.readValue(tbMsg.getData(), Alarm.class); - EdgeQueueEntityType edgeQueueEntityType = getEdgeQueueTypeByEntityType(alarm.getOriginator().getEntityType()); - if (edgeQueueEntityType != null) { - pushEventToEdge(tenantId, alarm.getOriginator(), EdgeQueueEntityType.ALARM, tbMsg, callback); + EdgeEventType edgeEventType = getEdgeQueueTypeByEntityType(alarm.getOriginator().getEntityType()); + if (edgeEventType != null) { + pushEventToEdge(tenantId, alarm.getOriginator(), EdgeEventType.ALARM, tbMsg, callback); } break; default: @@ -292,7 +309,7 @@ public class DefaultEdgeNotificationService implements EdgeNotificationService { switch (tbMsg.getType()) { case DataConstants.ENTITY_ASSIGNED_TO_EDGE: case DataConstants.ENTITY_UNASSIGNED_FROM_EDGE: - processAssignedEntity(tenantId, tbMsg, EdgeQueueEntityType.DASHBOARD, callback); + processAssignedEntity(tenantId, tbMsg, EdgeEventType.DASHBOARD, callback); break; case DataConstants.ENTITY_DELETED: case DataConstants.ENTITY_CREATED: @@ -303,7 +320,7 @@ public class DefaultEdgeNotificationService implements EdgeNotificationService { if (edges != null && edges.getData() != null && !edges.getData().isEmpty()) { try { for (Edge edge : edges.getData()) { - pushEventToEdge(tenantId, edge.getId(), EdgeQueueEntityType.DASHBOARD, tbMsg, callback); + pushEventToEdge(tenantId, edge.getId(), EdgeEventType.DASHBOARD, tbMsg, callback); } } catch (IOException e) { log.error("Can't push event to edge", e); @@ -321,7 +338,7 @@ public class DefaultEdgeNotificationService implements EdgeNotificationService { switch (tbMsg.getType()) { case DataConstants.ENTITY_ASSIGNED_TO_EDGE: case DataConstants.ENTITY_UNASSIGNED_FROM_EDGE: - processAssignedEntity(tenantId, tbMsg, EdgeQueueEntityType.RULE_CHAIN, callback); + processAssignedEntity(tenantId, tbMsg, EdgeEventType.RULE_CHAIN, callback); break; case DataConstants.ENTITY_DELETED: case DataConstants.ENTITY_CREATED: @@ -333,7 +350,7 @@ public class DefaultEdgeNotificationService implements EdgeNotificationService { if (edges != null && edges.getData() != null && !edges.getData().isEmpty()) { try { for (Edge edge : edges.getData()) { - pushEventToEdge(tenantId, edge.getId(), EdgeQueueEntityType.RULE_CHAIN, tbMsg, callback); + pushEventToEdge(tenantId, edge.getId(), EdgeEventType.RULE_CHAIN, tbMsg, callback); } } catch (IOException e) { log.error("Can't push event to edge", e); @@ -349,7 +366,7 @@ public class DefaultEdgeNotificationService implements EdgeNotificationService { } - private void processAssignedEntity(TenantId tenantId, TbMsg tbMsg, EdgeQueueEntityType entityType, FutureCallback callback) throws IOException { + private void processAssignedEntity(TenantId tenantId, TbMsg tbMsg, EdgeEventType entityType, FutureCallback callback) throws IOException { EdgeId edgeId; switch (tbMsg.getType()) { case DataConstants.ENTITY_ASSIGNED_TO_EDGE: @@ -364,13 +381,12 @@ public class DefaultEdgeNotificationService implements EdgeNotificationService { } } - - private void pushEventToEdge(TenantId tenantId, EntityId originatorId, EdgeQueueEntityType edgeQueueEntityType, TbMsg tbMsg, FutureCallback callback) { + private void pushEventToEdge(TenantId tenantId, EntityId originatorId, EdgeEventType edgeEventType, TbMsg tbMsg, FutureCallback callback) { ListenableFuture edgeIdFuture = getEdgeIdByOriginatorId(tenantId, originatorId); Futures.transform(edgeIdFuture, edgeId -> { if (edgeId != null) { try { - pushEventToEdge(tenantId, edgeId, edgeQueueEntityType, tbMsg, callback); + pushEventToEdge(tenantId, edgeId, edgeEventType, tbMsg, callback); } catch (Exception e) { log.error("Failed to push event to edge, edgeId [{}], tbMsg [{}]", edgeId, tbMsg, e); } @@ -380,7 +396,6 @@ public class DefaultEdgeNotificationService implements EdgeNotificationService { MoreExecutors.directExecutor()); } - private ListenableFuture getEdgeIdByOriginatorId(TenantId tenantId, EntityId originatorId) { List originatorEdgeRelations = relationService.findByToAndType(tenantId, originatorId, EntityRelation.CONTAINS_TYPE, RelationTypeGroup.EDGE); if (originatorEdgeRelations != null && originatorEdgeRelations.size() > 0) { @@ -391,12 +406,12 @@ public class DefaultEdgeNotificationService implements EdgeNotificationService { } - private void pushEventToEdge(TenantId tenantId, EdgeId edgeId, EdgeQueueEntityType entityType, TbMsg tbMsg, FutureCallback callback) throws IOException { + private void pushEventToEdge(TenantId tenantId, EdgeId edgeId, EdgeEventType entityType, TbMsg tbMsg, FutureCallback callback) throws IOException { log.debug("Pushing event(s) to edge queue. tenantId [{}], edgeId [{}], entityType [{}], tbMsg [{}]", tenantId, edgeId, entityType, tbMsg); saveEventToEdgeQueue(tenantId, edgeId, entityType, tbMsg.getType(), tbMsg.getData(), callback); - if (entityType.equals(EdgeQueueEntityType.RULE_CHAIN)) { + if (entityType.equals(EdgeEventType.RULE_CHAIN)) { pushRuleChainMetadataToEdge(tenantId, edgeId, tbMsg, callback); } } @@ -408,7 +423,7 @@ public class DefaultEdgeNotificationService implements EdgeNotificationService { case DataConstants.ENTITY_UNASSIGNED_FROM_EDGE: case DataConstants.ENTITY_UPDATED: RuleChainMetaData ruleChainMetaData = ruleChainService.loadRuleChainMetaData(tenantId, ruleChain.getId()); - saveEventToEdgeQueue(tenantId, edgeId, EdgeQueueEntityType.RULE_CHAIN_METADATA, tbMsg.getType(), mapper.writeValueAsString(ruleChainMetaData), callback); + saveEventToEdgeQueue(tenantId, edgeId, EdgeEventType.RULE_CHAIN_METADATA, tbMsg.getType(), mapper.writeValueAsString(ruleChainMetaData), callback); break; default: log.warn("Unsupported msgType [{}], tbMsg [{}]", tbMsg.getType(), tbMsg); @@ -416,14 +431,14 @@ public class DefaultEdgeNotificationService implements EdgeNotificationService { } - private EdgeQueueEntityType getEdgeQueueTypeByEntityType(EntityType entityType) { + private EdgeEventType getEdgeQueueTypeByEntityType(EntityType entityType) { switch (entityType) { case DEVICE: - return EdgeQueueEntityType.DEVICE; + return EdgeEventType.DEVICE; case ASSET: - return EdgeQueueEntityType.ASSET; + return EdgeEventType.ASSET; case ENTITY_VIEW: - return EdgeQueueEntityType.ENTITY_VIEW; + return EdgeEventType.ENTITY_VIEW; default: log.info("Unsupported entity type: [{}]", entityType); return null; diff --git a/application/src/main/java/org/thingsboard/server/service/edge/EdgeNotificationService.java b/application/src/main/java/org/thingsboard/server/service/edge/EdgeNotificationService.java index f4de0f974e..6f35d4c32c 100644 --- a/application/src/main/java/org/thingsboard/server/service/edge/EdgeNotificationService.java +++ b/application/src/main/java/org/thingsboard/server/service/edge/EdgeNotificationService.java @@ -1,7 +1,23 @@ +/** + * Copyright © 2016-2020 The Thingsboard Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package org.thingsboard.server.service.edge; import org.thingsboard.server.common.data.Event; import org.thingsboard.server.common.data.edge.Edge; +import org.thingsboard.server.common.data.edge.EdgeEvent; import org.thingsboard.server.common.data.id.EdgeId; import org.thingsboard.server.common.data.id.RuleChainId; import org.thingsboard.server.common.data.id.TenantId; @@ -14,7 +30,7 @@ import java.io.IOException; public interface EdgeNotificationService { - TimePageData findQueueEvents(TenantId tenantId, EdgeId edgeId, TimePageLink pageLink); + TimePageData findEdgeEvents(TenantId tenantId, EdgeId edgeId, TimePageLink pageLink); Edge setEdgeRootRuleChain(TenantId tenantId, Edge edge, RuleChainId ruleChainId) throws IOException; diff --git a/application/src/main/java/org/thingsboard/server/service/edge/rpc/EdgeGrpcSession.java b/application/src/main/java/org/thingsboard/server/service/edge/rpc/EdgeGrpcSession.java index 1e77f438c5..aa48f0a370 100644 --- a/application/src/main/java/org/thingsboard/server/service/edge/rpc/EdgeGrpcSession.java +++ b/application/src/main/java/org/thingsboard/server/service/edge/rpc/EdgeGrpcSession.java @@ -33,14 +33,14 @@ import org.thingsboard.server.common.data.DataConstants; import org.thingsboard.server.common.data.Device; import org.thingsboard.server.common.data.EntityType; import org.thingsboard.server.common.data.EntityView; -import org.thingsboard.server.common.data.Event; import org.thingsboard.server.common.data.User; import org.thingsboard.server.common.data.alarm.Alarm; import org.thingsboard.server.common.data.alarm.AlarmSeverity; import org.thingsboard.server.common.data.alarm.AlarmStatus; import org.thingsboard.server.common.data.asset.Asset; +import org.thingsboard.server.common.data.audit.ActionType; import org.thingsboard.server.common.data.edge.Edge; -import org.thingsboard.server.common.data.edge.EdgeQueueEntry; +import org.thingsboard.server.common.data.edge.EdgeEvent; import org.thingsboard.server.common.data.id.AssetId; import org.thingsboard.server.common.data.id.DeviceId; import org.thingsboard.server.common.data.id.EdgeId; @@ -63,7 +63,6 @@ import org.thingsboard.server.common.msg.TbMsg; import org.thingsboard.server.common.msg.TbMsgDataType; import org.thingsboard.server.common.msg.TbMsgMetaData; import org.thingsboard.server.common.msg.queue.TbMsgCallback; -import org.thingsboard.server.common.msg.session.SessionMsgType; import org.thingsboard.server.gen.edge.AlarmUpdateMsg; import org.thingsboard.server.gen.edge.ConnectRequestMsg; import org.thingsboard.server.gen.edge.ConnectResponseCode; @@ -169,36 +168,28 @@ public final class EdgeGrpcSession implements Closeable { void processHandleMessages() throws ExecutionException, InterruptedException { Long queueStartTs = getQueueStartTs().get(); TimePageLink pageLink = new TimePageLink(ctx.getEdgeEventStorageSettings().getMaxReadRecordsCount(), queueStartTs, null, true); - TimePageData pageData; + TimePageData pageData; UUID ifOffset = null; do { - pageData = ctx.getEdgeNotificationService().findQueueEvents(edge.getTenantId(), edge.getId(), pageLink); + pageData = ctx.getEdgeNotificationService().findEdgeEvents(edge.getTenantId(), edge.getId(), pageLink); if (isConnected() && !pageData.getData().isEmpty()) { log.trace("[{}] [{}] event(s) are going to be processed.", this.sessionId, pageData.getData().size()); - for (Event event : pageData.getData()) { - log.trace("[{}] Processing event [{}]", this.sessionId, event); + for (EdgeEvent edgeEvent : pageData.getData()) { + log.trace("[{}] Processing edge event [{}]", this.sessionId, edgeEvent); try { - EdgeQueueEntry entry = objectMapper.treeToValue(event.getBody(), EdgeQueueEntry.class); - UpdateMsgType msgType = getResponseMsgType(entry.getType()); - switch (msgType) { - case ENTITY_DELETED_RPC_MESSAGE: - case ENTITY_UPDATED_RPC_MESSAGE: - case ENTITY_CREATED_RPC_MESSAGE: - case ALARM_ACK_RPC_MESSAGE: - case ALARM_CLEAR_RPC_MESSAGE: - processEntityCRUDMessage(entry, msgType); - break; - case RULE_CHAIN_CUSTOM_MESSAGE: - processCustomDownlinkMessage(entry); - break; + UpdateMsgType msgType = getResponseMsgType(ActionType.valueOf(edgeEvent.getEdgeEventAction())); + if (msgType == null) { + processTelemetryMessage(edgeEvent); + } else { + processEntityCRUDMessage(edgeEvent, msgType); } if (ENTITY_CREATED_RPC_MESSAGE.equals(msgType)) { - pushEntityAttributesToEdge(entry); + pushEntityAttributesToEdge(edgeEvent); } } catch (Exception e) { log.error("Exception during processing records from queue", e); } - ifOffset = event.getUuidId(); + ifOffset = edgeEvent.getUuidId(); } } if (isConnected() && pageData.hasNext()) { @@ -222,10 +213,10 @@ public final class EdgeGrpcSession implements Closeable { } } - private void pushEntityAttributesToEdge(EdgeQueueEntry entry) throws IOException { + private void pushEntityAttributesToEdge(EdgeEvent edgeEvent) throws IOException { EntityId entityId = null; String entityName = null; - switch (entry.getEntityType()) { + switch (edgeEvent.getEdgeEventType()) { case EDGE: Edge edge = objectMapper.readValue(entry.getData(), Edge.class); entityId = edge.getId(); @@ -277,7 +268,7 @@ public final class EdgeGrpcSession implements Closeable { , objectMapper.writeValueAsString(entityNode)); log.debug("Sending donwlink entity data msg, entityName [{}], tbMsg [{}]", finalEntityName, tbMsg); outputStream.onNext(ResponseMsg.newBuilder() - .setDownlinkMsg(constructDownlinkEntityDataMsg(finalEntityName, finalEntityId, tbMsg)) + .setDownlinkMsg(constructEntityDataProtoMsg(finalEntityName, finalEntityId, tbMsg)) .build()); } catch (Exception e) { log.error("[{}] Failed to send attribute updates to the edge", edge.getName(), e); @@ -290,12 +281,12 @@ public final class EdgeGrpcSession implements Closeable { } } - private void processCustomDownlinkMessage(EdgeQueueEntry entry) throws IOException { - log.trace("Executing processCustomDownlinkMessage, entry [{}]", entry); + private void processTelemetryMessage(EdgeEvent edgeEvent) throws IOException { + log.trace("Executing processTelemetryMessage, edgeEvent [{}]", edgeEvent); TbMsg tbMsg = TbMsg.fromBytes(Base64.decodeBase64(entry.getData()), TbMsgCallback.EMPTY); String entityName = null; EntityId entityId = null; - switch (entry.getEntityType()) { + switch (edgeEvent.getEdgeEventType()) { case DEVICE: Device device = ctx.getDeviceService().findDeviceById(edge.getTenantId(), new DeviceId(tbMsg.getOriginator().getId())); entityName = device.getName(); @@ -316,14 +307,14 @@ public final class EdgeGrpcSession implements Closeable { if (entityName != null && entityId != null) { log.debug("Sending downlink entity data msg, entityName [{}], tbMsg [{}]", entityName, tbMsg); outputStream.onNext(ResponseMsg.newBuilder() - .setDownlinkMsg(constructDownlinkEntityDataMsg(entityName, entityId, tbMsg)) + .setDownlinkMsg(constructEntityDataProtoMsg(entityName, entityId, tbMsg)) .build()); } } - private void processEntityCRUDMessage(EdgeQueueEntry entry, UpdateMsgType msgType) throws java.io.IOException { - log.trace("Executing processEntityCRUDMessage, entry [{}], msgType [{}]", entry, msgType); - switch (entry.getEntityType()) { + private void processEntityCRUDMessage(EdgeEvent edgeEvent, UpdateMsgType msgType) throws java.io.IOException { + log.trace("Executing processEntityCRUDMessage, edgeEvent [{}], msgType [{}]", edgeEvent, msgType); + switch (edgeEvent.getEdgeEventType()) { case EDGE: Edge edge = objectMapper.readValue(entry.getData(), Edge.class); onEdgeUpdated(msgType, edge); @@ -476,33 +467,30 @@ public final class EdgeGrpcSession implements Closeable { .build()); } - private UpdateMsgType getResponseMsgType(String msgType) { - if (msgType.equals(SessionMsgType.POST_TELEMETRY_REQUEST.name()) || - msgType.equals(SessionMsgType.POST_ATTRIBUTES_REQUEST.name()) || - msgType.equals(DataConstants.ATTRIBUTES_UPDATED) || - msgType.equals(DataConstants.ATTRIBUTES_DELETED)) { - return UpdateMsgType.RULE_CHAIN_CUSTOM_MESSAGE; - } else { - switch (msgType) { - case DataConstants.ENTITY_UPDATED: - return UpdateMsgType.ENTITY_UPDATED_RPC_MESSAGE; - case DataConstants.ENTITY_CREATED: - case DataConstants.ENTITY_ASSIGNED_TO_EDGE: - return ENTITY_CREATED_RPC_MESSAGE; - case DataConstants.ENTITY_DELETED: - case DataConstants.ENTITY_UNASSIGNED_FROM_EDGE: - return UpdateMsgType.ENTITY_DELETED_RPC_MESSAGE; - case DataConstants.ALARM_ACK: - return UpdateMsgType.ALARM_ACK_RPC_MESSAGE; - case DataConstants.ALARM_CLEAR: - return UpdateMsgType.ALARM_CLEAR_RPC_MESSAGE; - default: - throw new RuntimeException("Unsupported msgType [" + msgType + "]"); - } + private UpdateMsgType getResponseMsgType(ActionType actionType) { + switch (actionType) { + case ADDED: + return UpdateMsgType.ENTITY_UPDATED_RPC_MESSAGE; + case UPDATED: + case ASSIGNED_TO_EDGE: + return ENTITY_CREATED_RPC_MESSAGE; + case DELETED: + case UNASSIGNED_FROM_EDGE: + return UpdateMsgType.ENTITY_DELETED_RPC_MESSAGE; + case ALARM_ACK: + return UpdateMsgType.ALARM_ACK_RPC_MESSAGE; + case ALARM_CLEAR: + return UpdateMsgType.ALARM_CLEAR_RPC_MESSAGE; + case ATTRIBUTES_UPDATED: + case ATTRIBUTES_DELETED: + case TIMESERIES_DELETED: + return null; + default: + throw new RuntimeException("Unsupported actionType [" + actionType + "]"); } } - private DownlinkMsg constructDownlinkEntityDataMsg(String entityName, EntityId entityId, TbMsg tbMsg) { + private DownlinkMsg constructEntityDataProtoMsg(String entityName, EntityId entityId, TbMsg tbMsg) { EntityDataProto entityData = EntityDataProto.newBuilder() .setEntityName(entityName) .setTbMsg(ByteString.copyFrom(TbMsg.toByteArray(tbMsg))) diff --git a/application/src/main/java/org/thingsboard/server/service/install/SqlDatabaseUpgradeService.java b/application/src/main/java/org/thingsboard/server/service/install/SqlDatabaseUpgradeService.java index f9c5e53fd5..eda9cf88cb 100644 --- a/application/src/main/java/org/thingsboard/server/service/install/SqlDatabaseUpgradeService.java +++ b/application/src/main/java/org/thingsboard/server/service/install/SqlDatabaseUpgradeService.java @@ -239,7 +239,7 @@ public class SqlDatabaseUpgradeService implements DatabaseEntitiesUpgradeService schemaUpdateFile = Paths.get(installScripts.getDataDir(), "upgrade", "2.6.0", SCHEMA_UPDATE_SQL); loadSql(schemaUpdateFile, conn); try { - conn.createStatement().execute("ALTER TABLE rule_chain ADD type varchar(255) DEFAULT 'SYSTEM'"); //NOSONAR, ignoring because method used to execute thingsboard database upgrade script + conn.createStatement().execute("ALTER TABLE rule_chain ADD type varchar(255) DEFAULT 'CORE'"); //NOSONAR, ignoring because method used to execute thingsboard database upgrade script } catch (Exception e) {} log.info("Schema updated."); } diff --git a/common/dao-api/src/main/java/org/thingsboard/server/dao/edge/EdgeEventService.java b/common/dao-api/src/main/java/org/thingsboard/server/dao/edge/EdgeEventService.java new file mode 100644 index 0000000000..6c3e189d41 --- /dev/null +++ b/common/dao-api/src/main/java/org/thingsboard/server/dao/edge/EdgeEventService.java @@ -0,0 +1,35 @@ +/** + * Copyright © 2016-2020 The Thingsboard Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.thingsboard.server.dao.edge; + +import com.google.common.util.concurrent.ListenableFuture; +import org.thingsboard.server.common.data.EntityType; +import org.thingsboard.server.common.data.edge.EdgeEvent; +import org.thingsboard.server.common.data.edge.EdgeEventType; +import org.thingsboard.server.common.data.id.EdgeId; +import org.thingsboard.server.common.data.id.TenantId; +import org.thingsboard.server.common.data.page.TimePageData; +import org.thingsboard.server.common.data.page.TimePageLink; + +public interface EdgeEventService { + + EdgeEventType getEdgeEventTypeByEntityType(EntityType entityType); + + ListenableFuture saveAsync(EdgeEvent edgeEvent); + + TimePageData findEdgeEvents(TenantId tenantId, EdgeId edgeId, TimePageLink pageLink); + +} diff --git a/common/dao-api/src/main/java/org/thingsboard/server/dao/edge/EdgeService.java b/common/dao-api/src/main/java/org/thingsboard/server/dao/edge/EdgeService.java index 496d6a2425..60c6b24918 100644 --- a/common/dao-api/src/main/java/org/thingsboard/server/dao/edge/EdgeService.java +++ b/common/dao-api/src/main/java/org/thingsboard/server/dao/edge/EdgeService.java @@ -5,7 +5,7 @@ * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/DataConstants.java b/common/data/src/main/java/org/thingsboard/server/common/data/DataConstants.java index 4dd9bb1076..01b9e86d25 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/DataConstants.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/DataConstants.java @@ -65,7 +65,4 @@ public class DataConstants { public static final String DEFAULT_SECRET_KEY = ""; public static final String SECRET_KEY_FIELD_NAME = "secretKey"; public static final String DURATION_MS_FIELD_NAME = "durationMs"; - - public static final String EDGE_QUEUE_EVENT_TYPE = "EDGE_QUEUE"; - } diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/audit/ActionType.java b/common/data/src/main/java/org/thingsboard/server/common/data/audit/ActionType.java index 7e78a03bb4..48de5fedb6 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/audit/ActionType.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/audit/ActionType.java @@ -24,6 +24,7 @@ public enum ActionType { UPDATED(false), // log entity ATTRIBUTES_UPDATED(false), // log attributes/values ATTRIBUTES_DELETED(false), // log attributes + TIMESERIES_UPDATED(false), // log timeseries TIMESERIES_DELETED(false), // log timeseries RPC_CALL(false), // log method and params CREDENTIALS_UPDATED(false), // log new credentials diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/edge/EdgeEvent.java b/common/data/src/main/java/org/thingsboard/server/common/data/edge/EdgeEvent.java new file mode 100644 index 0000000000..1c9ea9343c --- /dev/null +++ b/common/data/src/main/java/org/thingsboard/server/common/data/edge/EdgeEvent.java @@ -0,0 +1,50 @@ +/** + * Copyright © 2016-2020 The Thingsboard Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.thingsboard.server.common.data.edge; + +import com.fasterxml.jackson.databind.JsonNode; +import lombok.Data; +import org.thingsboard.server.common.data.BaseData; +import org.thingsboard.server.common.data.id.EdgeEventId; +import org.thingsboard.server.common.data.id.EdgeId; +import org.thingsboard.server.common.data.id.EntityId; +import org.thingsboard.server.common.data.id.TenantId; + +import java.util.UUID; + +@Data +public class EdgeEvent extends BaseData { + + private TenantId tenantId; + private EdgeId edgeId; + private String edgeEventAction; + private UUID entityId; + private EdgeEventType edgeEventType; + private transient JsonNode entityBody; + + public EdgeEvent() { + super(); + } + + public EdgeEvent(EdgeEventId id) { + super(id); + } + + public EdgeEvent(EdgeEvent event) { + super(event); + } + +} diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/edge/EdgeQueueEntityType.java b/common/data/src/main/java/org/thingsboard/server/common/data/edge/EdgeEventType.java similarity index 95% rename from common/data/src/main/java/org/thingsboard/server/common/data/edge/EdgeQueueEntityType.java rename to common/data/src/main/java/org/thingsboard/server/common/data/edge/EdgeEventType.java index 7ba316a529..ada50c9998 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/edge/EdgeQueueEntityType.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/edge/EdgeEventType.java @@ -15,6 +15,6 @@ */ package org.thingsboard.server.common.data.edge; -public enum EdgeQueueEntityType { +public enum EdgeEventType { DASHBOARD, ASSET, DEVICE, ENTITY_VIEW, ALARM, RULE_CHAIN, RULE_CHAIN_METADATA, EDGE, USER, CUSTOMER, RELATION } diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/id/EdgeEventId.java b/common/data/src/main/java/org/thingsboard/server/common/data/id/EdgeEventId.java new file mode 100644 index 0000000000..705c46e2fa --- /dev/null +++ b/common/data/src/main/java/org/thingsboard/server/common/data/id/EdgeEventId.java @@ -0,0 +1,35 @@ +/** + * Copyright © 2016-2020 The Thingsboard Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.thingsboard.server.common.data.id; + +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonProperty; + +import java.util.UUID; + +public class EdgeEventId extends UUIDBased { + + private static final long serialVersionUID = 1L; + + @JsonCreator + public EdgeEventId(@JsonProperty("id") UUID id) { + super(id); + } + + public static EdgeEventId fromString(String edgeEventId) { + return new EdgeEventId(UUID.fromString(edgeEventId)); + } +} diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/rule/RuleChainType.java b/common/data/src/main/java/org/thingsboard/server/common/data/rule/RuleChainType.java index d6a806f95f..9dc3dc4e5e 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/rule/RuleChainType.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/rule/RuleChainType.java @@ -16,5 +16,5 @@ package org.thingsboard.server.common.data.rule; public enum RuleChainType { - SYSTEM, EDGE + CORE, EDGE } diff --git a/common/edge-api/pom.xml b/common/edge-api/pom.xml index dfd42240c4..53b7d62472 100644 --- a/common/edge-api/pom.xml +++ b/common/edge-api/pom.xml @@ -40,6 +40,10 @@ org.thingsboard.common data + + org.thingsboard.common + queue + org.thingsboard.common message diff --git a/common/edge-api/src/main/proto/edge.proto b/common/edge-api/src/main/proto/edge.proto index 4a941b279e..787de743be 100644 --- a/common/edge-api/src/main/proto/edge.proto +++ b/common/edge-api/src/main/proto/edge.proto @@ -19,6 +19,8 @@ option java_package = "org.thingsboard.server.gen.edge"; option java_multiple_files = true; option java_outer_classname = "EdgeProtos"; +import "queue.proto"; + package edge; // Interface exported by the ThingsBoard Edge Transport. @@ -94,15 +96,16 @@ enum UpdateMsgType { ENTITY_DELETED_RPC_MESSAGE = 2; ALARM_ACK_RPC_MESSAGE = 3; ALARM_CLEAR_RPC_MESSAGE = 4; - RULE_CHAIN_CUSTOM_MESSAGE = 5; - DEVICE_CONFLICT_RPC_MESSAGE = 6; + DEVICE_CONFLICT_RPC_MESSAGE = 5; } message EntityDataProto { string entityName = 1; int64 entityIdMSB = 2; int64 entityIdLSB = 3; - bytes tbMsg = 4; + transport.PostTelemetryMsg postTelemetryMsg = 4; + transport.PostAttributeMsg postAttributesMsg = 5; + // transport.ToDeviceRpcRequestMsg ??? } message RuleChainUpdateMsg { diff --git a/common/queue/src/main/proto/queue.proto b/common/queue/src/main/proto/queue.proto index ab0193318a..54a8148fbe 100644 --- a/common/queue/src/main/proto/queue.proto +++ b/common/queue/src/main/proto/queue.proto @@ -356,6 +356,14 @@ message FromDeviceRPCResponseProto { message EdgeNotificationMsgProto { int64 tenantIdMSB = 1; int64 tenantIdLSB = 2; + string edgeEventType = 3; + string edgeEventAction = 4; + int64 entityIdMSB = 5; + int64 entityIdLSB = 6; + string entityType = 7; + string entityBody = 8; + PostTelemetryMsg postTelemetryMsg = 9; + PostAttributeMsg postAttributesMsg = 10; } /** diff --git a/dao/src/main/java/org/thingsboard/server/dao/edge/BaseEdgeEventService.java b/dao/src/main/java/org/thingsboard/server/dao/edge/BaseEdgeEventService.java new file mode 100644 index 0000000000..134ffe3b06 --- /dev/null +++ b/dao/src/main/java/org/thingsboard/server/dao/edge/BaseEdgeEventService.java @@ -0,0 +1,85 @@ +/** + * Copyright © 2016-2020 The Thingsboard Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.thingsboard.server.dao.edge; + +import com.google.common.util.concurrent.ListenableFuture; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.StringUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.thingsboard.server.common.data.EntityType; +import org.thingsboard.server.common.data.edge.EdgeEvent; +import org.thingsboard.server.common.data.edge.EdgeEventType; +import org.thingsboard.server.common.data.id.EdgeId; +import org.thingsboard.server.common.data.id.TenantId; +import org.thingsboard.server.common.data.page.TimePageData; +import org.thingsboard.server.common.data.page.TimePageLink; +import org.thingsboard.server.dao.exception.DataValidationException; +import org.thingsboard.server.dao.service.DataValidator; + +import java.util.List; + +@Service +@Slf4j +public class BaseEdgeEventService implements EdgeEventService { + + @Autowired + public EdgeEventDao edgeEventDao; + + @Override + public EdgeEventType getEdgeEventTypeByEntityType(EntityType entityType) { + switch (entityType) { + case DEVICE: + return EdgeEventType.DEVICE; + case ASSET: + return EdgeEventType.ASSET; + case ENTITY_VIEW: + return EdgeEventType.ENTITY_VIEW; + case DASHBOARD: + return EdgeEventType.DASHBOARD; + case USER: + return EdgeEventType.USER; + default: + log.warn("Failed to push notification to edge service. Unsupported entity type [{}]", entityType); + return null; + } + } + + @Override + public ListenableFuture saveAsync(EdgeEvent edgeEvent) { + edgeEventValidator.validate(edgeEvent, EdgeEvent::getTenantId); + return edgeEventDao.saveAsync(edgeEvent); + } + + @Override + public TimePageData findEdgeEvents(TenantId tenantId, EdgeId edgeId, TimePageLink pageLink) { + List events = edgeEventDao.findEdgeEvents(tenantId.getId(), edgeId, pageLink); + return new TimePageData<>(events, pageLink); + } + + private DataValidator edgeEventValidator = + new DataValidator() { + @Override + protected void validateDataImpl(TenantId tenantId, EdgeEvent edgeEvent) { + if (edgeEvent.getEdgeId() == null) { + throw new DataValidationException("Edge id should be specified!"); + } + if (StringUtils.isEmpty(edgeEvent.getEdgeEventAction())) { + throw new DataValidationException("Edge Event action should be specified!"); + } + } + }; +} diff --git a/dao/src/main/java/org/thingsboard/server/dao/edge/EdgeEventDao.java b/dao/src/main/java/org/thingsboard/server/dao/edge/EdgeEventDao.java new file mode 100644 index 0000000000..426bada645 --- /dev/null +++ b/dao/src/main/java/org/thingsboard/server/dao/edge/EdgeEventDao.java @@ -0,0 +1,51 @@ +/** + * Copyright © 2016-2020 The Thingsboard Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.thingsboard.server.dao.edge; + +import com.google.common.util.concurrent.ListenableFuture; +import org.thingsboard.server.common.data.edge.EdgeEvent; +import org.thingsboard.server.common.data.id.EdgeId; +import org.thingsboard.server.common.data.page.TimePageLink; +import org.thingsboard.server.dao.Dao; + +import java.util.List; +import java.util.UUID; + +/** + * The Interface EdgeEventDao. + */ +public interface EdgeEventDao extends Dao { + + /** + * Save or update edge event object async + * + * @param edgeEvent the event object + * @return saved edge event object future + */ + ListenableFuture saveAsync(EdgeEvent edgeEvent); + + + /** + * Find edge events by tenantId, edgeId and pageLink. + * + * @param tenantId the tenantId + * @param edgeId the edgeId + * @param pageLink the pageLink + * @return the event list + */ + List findEdgeEvents(UUID tenantId, EdgeId edgeId, TimePageLink pageLink); + +} diff --git a/dao/src/main/java/org/thingsboard/server/dao/edge/EdgeServiceImpl.java b/dao/src/main/java/org/thingsboard/server/dao/edge/EdgeServiceImpl.java index 48e8912225..39e0513637 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/edge/EdgeServiceImpl.java +++ b/dao/src/main/java/org/thingsboard/server/dao/edge/EdgeServiceImpl.java @@ -5,7 +5,7 @@ * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, diff --git a/dao/src/main/java/org/thingsboard/server/dao/model/ModelConstants.java b/dao/src/main/java/org/thingsboard/server/dao/model/ModelConstants.java index dcdf9460bf..5a7b5ce45f 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/model/ModelConstants.java +++ b/dao/src/main/java/org/thingsboard/server/dao/model/ModelConstants.java @@ -372,6 +372,16 @@ public class ModelConstants { public static final String EDGE_ROUTING_KEY_PROPERTY = "routing_key"; public static final String EDGE_SECRET_PROPERTY = "secret"; + /** + * Cassandra edge queue constants. + */ + public static final String EDGE_EVENT_COLUMN_FAMILY_NAME = "edge_event"; + public static final String EDGE_EVENT_TENANT_ID_PROPERTY = TENANT_ID_PROPERTY; + public static final String EDGE_EVENT_EDGE_ID_PROPERTY = "edge_id"; + public static final String EDGE_EVENT_TYPE_PROPERTY = "edge_event_type"; + public static final String EDGE_EVENT_ACTION_PROPERTY = "edge_event_action"; + public static final String EDGE_EVENT_ENTITY_ID_PROPERTY = "entity_id"; + public static final String EDGE_EVENT_ENTITY_BODY_PROPERTY = "entity_body"; /** * Cassandra attributes and timeseries constants. diff --git a/dao/src/main/java/org/thingsboard/server/dao/model/nosql/EdgeEventEntity.java b/dao/src/main/java/org/thingsboard/server/dao/model/nosql/EdgeEventEntity.java new file mode 100644 index 0000000000..8a3ed1b437 --- /dev/null +++ b/dao/src/main/java/org/thingsboard/server/dao/model/nosql/EdgeEventEntity.java @@ -0,0 +1,135 @@ +/** + * Copyright © 2016-2020 The Thingsboard Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.thingsboard.server.dao.model.nosql; + +import com.datastax.driver.core.utils.UUIDs; +import com.datastax.driver.mapping.annotations.ClusteringColumn; +import com.datastax.driver.mapping.annotations.Column; +import com.datastax.driver.mapping.annotations.PartitionKey; +import com.datastax.driver.mapping.annotations.Table; +import com.fasterxml.jackson.databind.JsonNode; +import lombok.Data; +import lombok.NoArgsConstructor; +import org.thingsboard.server.common.data.EntityType; +import org.thingsboard.server.common.data.Event; +import org.thingsboard.server.common.data.edge.EdgeEvent; +import org.thingsboard.server.common.data.edge.EdgeEventType; +import org.thingsboard.server.common.data.id.EdgeEventId; +import org.thingsboard.server.common.data.id.EdgeId; +import org.thingsboard.server.common.data.id.EntityIdFactory; +import org.thingsboard.server.common.data.id.EventId; +import org.thingsboard.server.common.data.id.TenantId; +import org.thingsboard.server.dao.model.BaseEntity; +import org.thingsboard.server.dao.model.type.EdgeEventTypeCodec; +import org.thingsboard.server.dao.model.type.EntityTypeCodec; +import org.thingsboard.server.dao.model.type.JsonCodec; + +import java.util.UUID; + +import static org.thingsboard.server.dao.model.ModelConstants.EDGE_EVENT_ACTION_PROPERTY; +import static org.thingsboard.server.dao.model.ModelConstants.EDGE_EVENT_COLUMN_FAMILY_NAME; +import static org.thingsboard.server.dao.model.ModelConstants.EDGE_EVENT_EDGE_ID_PROPERTY; +import static org.thingsboard.server.dao.model.ModelConstants.EDGE_EVENT_ENTITY_BODY_PROPERTY; +import static org.thingsboard.server.dao.model.ModelConstants.EDGE_EVENT_ENTITY_ID_PROPERTY; +import static org.thingsboard.server.dao.model.ModelConstants.EDGE_EVENT_TENANT_ID_PROPERTY; +import static org.thingsboard.server.dao.model.ModelConstants.EDGE_EVENT_TYPE_PROPERTY; +import static org.thingsboard.server.dao.model.ModelConstants.EVENT_BODY_PROPERTY; +import static org.thingsboard.server.dao.model.ModelConstants.EVENT_COLUMN_FAMILY_NAME; +import static org.thingsboard.server.dao.model.ModelConstants.EVENT_ENTITY_ID_PROPERTY; +import static org.thingsboard.server.dao.model.ModelConstants.EVENT_ENTITY_TYPE_PROPERTY; +import static org.thingsboard.server.dao.model.ModelConstants.EVENT_TENANT_ID_PROPERTY; +import static org.thingsboard.server.dao.model.ModelConstants.EVENT_TYPE_PROPERTY; +import static org.thingsboard.server.dao.model.ModelConstants.EVENT_UID_PROPERTY; +import static org.thingsboard.server.dao.model.ModelConstants.ID_PROPERTY; + +@Data +@NoArgsConstructor +@Table(name = EDGE_EVENT_COLUMN_FAMILY_NAME) +public class EdgeEventEntity implements BaseEntity { + + @Column(name = ID_PROPERTY) + private UUID id; + + @PartitionKey() + @Column(name = EDGE_EVENT_TENANT_ID_PROPERTY) + private UUID tenantId; + + @PartitionKey(value = 1) + @Column(name = EDGE_EVENT_EDGE_ID_PROPERTY) + private UUID edgeId; + + @PartitionKey(value = 2) + @Column(name = EDGE_EVENT_TYPE_PROPERTY, codec = EdgeEventTypeCodec.class) + private EdgeEventType edgeEventType; + + @PartitionKey(value = 3) + @Column(name = EDGE_EVENT_ENTITY_ID_PROPERTY) + private UUID entityId; + + @ClusteringColumn() + @Column(name = EDGE_EVENT_ACTION_PROPERTY) + private String edgeEventAction; + + // TODO + @ClusteringColumn(value = 1) + @Column(name = EVENT_UID_PROPERTY) + private String eventUid; + + @Column(name = EDGE_EVENT_ENTITY_BODY_PROPERTY, codec = JsonCodec.class) + private JsonNode entityBody; + + public EdgeEventEntity(EdgeEvent edgeEvent) { + if (edgeEvent.getId() != null) { + this.id = edgeEvent.getId().getId(); + } + if (edgeEvent.getTenantId() != null) { + this.tenantId = edgeEvent.getTenantId().getId(); + } + if (edgeEvent.getEdgeId() != null) { + this.edgeId = edgeEvent.getEdgeId().getId(); + } +// if (event.getEntityId() != null) { +// this.entityType = event.getEntityId().getEntityType(); +// this.entityId = event.getEntityId().getId(); +// } +// this.edgeEventType = edgeEvent.getEdgeEventType(); +// this.edgeEventAction = edgeEvent.getEdgeEventAction(); +// this.entityBody = edgeEvent.getEntityBody(); + } + + @Override + public UUID getUuid() { + return id; + } + + @Override + public void setUuid(UUID id) { + this.id = id; + } + + @Override + public EdgeEvent toData() { + EdgeEvent edgeEvent = new EdgeEvent(new EdgeEventId(id)); +// edgeEvent.setCreatedTime(UUIDs.unixTimestamp(id)); +// edgeEvent.setTenantId(new TenantId(tenantId)); +// edgeEvent.setEdgeId(new EdgeId(edgeId)); +// edgeEvent.setEntityId(entityId); +// event.setBody(body); +// event.setType(eventType); +// event.setUid(eventUid); + return edgeEvent; + } +} diff --git a/dao/src/main/java/org/thingsboard/server/dao/model/sql/EdgeEventEntity.java b/dao/src/main/java/org/thingsboard/server/dao/model/sql/EdgeEventEntity.java new file mode 100644 index 0000000000..9c6dca59ef --- /dev/null +++ b/dao/src/main/java/org/thingsboard/server/dao/model/sql/EdgeEventEntity.java @@ -0,0 +1,121 @@ +/** + * Copyright © 2016-2020 The Thingsboard Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.thingsboard.server.dao.model.sql; + +import com.datastax.driver.core.utils.UUIDs; +import com.fasterxml.jackson.databind.JsonNode; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.NoArgsConstructor; +import org.hibernate.annotations.Type; +import org.hibernate.annotations.TypeDef; +import org.thingsboard.server.common.data.edge.EdgeEvent; +import org.thingsboard.server.common.data.edge.EdgeEventType; +import org.thingsboard.server.common.data.id.EdgeEventId; +import org.thingsboard.server.common.data.id.EdgeId; +import org.thingsboard.server.common.data.id.TenantId; +import org.thingsboard.server.dao.model.BaseEntity; +import org.thingsboard.server.dao.model.BaseSqlEntity; +import org.thingsboard.server.dao.util.mapping.JsonStringType; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.EnumType; +import javax.persistence.Enumerated; +import javax.persistence.Table; +import java.util.UUID; + +import static org.thingsboard.server.dao.model.ModelConstants.EDGE_EVENT_ACTION_PROPERTY; +import static org.thingsboard.server.dao.model.ModelConstants.EDGE_EVENT_COLUMN_FAMILY_NAME; +import static org.thingsboard.server.dao.model.ModelConstants.EDGE_EVENT_EDGE_ID_PROPERTY; +import static org.thingsboard.server.dao.model.ModelConstants.EDGE_EVENT_ENTITY_BODY_PROPERTY; +import static org.thingsboard.server.dao.model.ModelConstants.EDGE_EVENT_ENTITY_ID_PROPERTY; +import static org.thingsboard.server.dao.model.ModelConstants.EDGE_EVENT_TENANT_ID_PROPERTY; +import static org.thingsboard.server.dao.model.ModelConstants.EDGE_EVENT_TYPE_PROPERTY; +import static org.thingsboard.server.dao.model.ModelConstants.EPOCH_DIFF; +import static org.thingsboard.server.dao.model.ModelConstants.TS_COLUMN; + +@Data +@EqualsAndHashCode(callSuper = true) +@Entity +@TypeDef(name = "json", typeClass = JsonStringType.class) +@Table(name = EDGE_EVENT_COLUMN_FAMILY_NAME) +@NoArgsConstructor +public class EdgeEventEntity extends BaseSqlEntity implements BaseEntity { + + @Column(name = EDGE_EVENT_TENANT_ID_PROPERTY) + private String tenantId; + + @Column(name = EDGE_EVENT_EDGE_ID_PROPERTY) + private String edgeId; + + @Column(name = EDGE_EVENT_ENTITY_ID_PROPERTY) + private String entityId; + + @Enumerated(EnumType.STRING) + @Column(name = EDGE_EVENT_TYPE_PROPERTY) + private EdgeEventType edgeEventType; + + @Column(name = EDGE_EVENT_ACTION_PROPERTY) + private String edgeEventAction; + + @Type(type = "json") + @Column(name = EDGE_EVENT_ENTITY_BODY_PROPERTY) + private JsonNode entityBody; + + @Column(name = TS_COLUMN) + private long ts; + + public EdgeEventEntity(EdgeEvent edgeEvent) { + if (edgeEvent.getId() != null) { + this.setUuid(edgeEvent.getId().getId()); + this.ts = getTs(edgeEvent.getId().getId()); + } else { + this.ts = System.currentTimeMillis(); + } + if (edgeEvent.getTenantId() != null) { + this.tenantId = toString(edgeEvent.getTenantId().getId()); + } + if (edgeEvent.getEdgeId() != null) { + this.edgeId = toString(edgeEvent.getEdgeId().getId()); + } + if (edgeEvent.getEntityId() != null) { + this.entityId = toString(edgeEvent.getEntityId()); + } + this.edgeEventType = edgeEvent.getEdgeEventType(); + this.edgeEventAction = edgeEvent.getEdgeEventAction(); + this.entityBody = edgeEvent.getEntityBody(); + } + + @Override + public EdgeEvent toData() { + EdgeEvent edgeEvent = new EdgeEvent(new EdgeEventId(this.getUuid())); + edgeEvent.setCreatedTime(UUIDs.unixTimestamp(this.getUuid())); + edgeEvent.setTenantId(new TenantId(toUUID(tenantId))); + edgeEvent.setEdgeId(new EdgeId(toUUID(edgeId))); + if (entityId != null) { + edgeEvent.setEntityId(toUUID(entityId)); + } + edgeEvent.setEdgeEventType(edgeEventType); + edgeEvent.setEdgeEventAction(edgeEventAction); + edgeEvent.setEntityBody(entityBody); + return edgeEvent; + } + + private static long getTs(UUID uuid) { + return (uuid.timestamp() - EPOCH_DIFF) / 10000; + } +} diff --git a/dao/src/main/java/org/thingsboard/server/dao/model/type/EdgeEventTypeCodec.java b/dao/src/main/java/org/thingsboard/server/dao/model/type/EdgeEventTypeCodec.java new file mode 100644 index 0000000000..4a32c3a9ab --- /dev/null +++ b/dao/src/main/java/org/thingsboard/server/dao/model/type/EdgeEventTypeCodec.java @@ -0,0 +1,27 @@ +/** + * Copyright © 2016-2020 The Thingsboard Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.thingsboard.server.dao.model.type; + +import com.datastax.driver.extras.codecs.enums.EnumNameCodec; +import org.thingsboard.server.common.data.edge.EdgeEventType; + +public class EdgeEventTypeCodec extends EnumNameCodec { + + public EdgeEventTypeCodec() { + super(EdgeEventType.class); + } + +} diff --git a/dao/src/main/java/org/thingsboard/server/dao/rule/BaseRuleChainService.java b/dao/src/main/java/org/thingsboard/server/dao/rule/BaseRuleChainService.java index d0c37903a8..592f20f4f2 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/rule/BaseRuleChainService.java +++ b/dao/src/main/java/org/thingsboard/server/dao/rule/BaseRuleChainService.java @@ -289,7 +289,7 @@ public class BaseRuleChainService extends AbstractEntityService implements RuleC @Override public RuleChain getRootTenantRuleChain(TenantId tenantId) { - return getRootRuleChainByType(tenantId, RuleChainType.SYSTEM); + return getRootRuleChainByType(tenantId, RuleChainType.CORE); } private RuleChain getRootRuleChainByType(TenantId tenantId, RuleChainType type) { @@ -566,7 +566,7 @@ public class BaseRuleChainService extends AbstractEntityService implements RuleC throw new DataValidationException("Rule chain name should be specified!"); } if (ruleChain.getType() == null) { - ruleChain.setType(RuleChainType.SYSTEM); + ruleChain.setType(RuleChainType.CORE); } if (ruleChain.getTenantId() == null || ruleChain.getTenantId().isNullUid()) { throw new DataValidationException("Rule chain should be assigned to tenant!"); @@ -575,7 +575,7 @@ public class BaseRuleChainService extends AbstractEntityService implements RuleC if (tenant == null) { throw new DataValidationException("Rule chain is referencing to non-existent tenant!"); } - if (ruleChain.isRoot() && RuleChainType.SYSTEM.equals(ruleChain.getType())) { + if (ruleChain.isRoot() && RuleChainType.CORE.equals(ruleChain.getType())) { RuleChain rootRuleChain = getRootTenantRuleChain(ruleChain.getTenantId()); if (rootRuleChain != null && !rootRuleChain.getId().equals(ruleChain.getId())) { throw new DataValidationException("Another root rule chain is present in scope of current tenant!"); diff --git a/dao/src/main/java/org/thingsboard/server/dao/sql/edge/EdgeEventRepository.java b/dao/src/main/java/org/thingsboard/server/dao/sql/edge/EdgeEventRepository.java new file mode 100644 index 0000000000..9a19cfd4b8 --- /dev/null +++ b/dao/src/main/java/org/thingsboard/server/dao/sql/edge/EdgeEventRepository.java @@ -0,0 +1,26 @@ +/** + * Copyright © 2016-2020 The Thingsboard Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.thingsboard.server.dao.sql.edge; + +import org.springframework.data.jpa.repository.JpaSpecificationExecutor; +import org.springframework.data.repository.CrudRepository; +import org.thingsboard.server.dao.model.sql.EdgeEventEntity; +import org.thingsboard.server.dao.util.SqlDao; + +@SqlDao +public interface EdgeEventRepository extends CrudRepository, JpaSpecificationExecutor { + +} diff --git a/dao/src/main/java/org/thingsboard/server/dao/sql/edge/JpaBaseEdgeEventDao.java b/dao/src/main/java/org/thingsboard/server/dao/sql/edge/JpaBaseEdgeEventDao.java new file mode 100644 index 0000000000..11a4a1dc64 --- /dev/null +++ b/dao/src/main/java/org/thingsboard/server/dao/sql/edge/JpaBaseEdgeEventDao.java @@ -0,0 +1,112 @@ +/** + * Copyright © 2016-2020 The Thingsboard Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.thingsboard.server.dao.sql.edge; + +import com.datastax.driver.core.utils.UUIDs; +import com.google.common.util.concurrent.ListenableFuture; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.data.domain.PageRequest; +import org.springframework.data.domain.Pageable; +import org.springframework.data.domain.Sort; +import org.springframework.data.jpa.domain.Specification; +import org.springframework.data.repository.CrudRepository; +import org.springframework.stereotype.Component; +import org.thingsboard.server.common.data.UUIDConverter; +import org.thingsboard.server.common.data.edge.EdgeEvent; +import org.thingsboard.server.common.data.id.EdgeEventId; +import org.thingsboard.server.common.data.id.EdgeId; +import org.thingsboard.server.common.data.page.TimePageLink; +import org.thingsboard.server.dao.DaoUtil; +import org.thingsboard.server.dao.edge.EdgeEventDao; +import org.thingsboard.server.dao.model.sql.EdgeEventEntity; +import org.thingsboard.server.dao.sql.JpaAbstractSearchTimeDao; +import org.thingsboard.server.dao.util.SqlDao; + +import javax.persistence.criteria.Predicate; +import java.util.ArrayList; +import java.util.List; +import java.util.Optional; +import java.util.UUID; + +import static org.thingsboard.server.dao.model.ModelConstants.ID_PROPERTY; +import static org.thingsboard.server.dao.model.ModelConstants.NULL_UUID; + +@Slf4j +@Component +@SqlDao +public class JpaBaseEdgeEventDao extends JpaAbstractSearchTimeDao implements EdgeEventDao { + + private final UUID systemTenantId = NULL_UUID; + + @Autowired + private EdgeEventRepository edgeEventRepository; + + @Override + protected Class getEntityClass() { + return EdgeEventEntity.class; + } + + @Override + protected CrudRepository getCrudRepository() { + return edgeEventRepository; + } + + @Override + public ListenableFuture saveAsync(EdgeEvent edgeEvent) { + log.debug("Save edge event [{}] ", edgeEvent); + if (edgeEvent.getId() == null) { + edgeEvent.setId(new EdgeEventId(UUIDs.timeBased())); + } + return service.submit(() -> save(new EdgeEventEntity(edgeEvent)).orElse(null)); + } + + @Override + public List findEdgeEvents(UUID tenantId, EdgeId edgeId, TimePageLink pageLink) { + Specification timeSearchSpec = JpaAbstractSearchTimeDao.getTimeSearchPageSpec(pageLink, "id"); + Specification fieldsSpec = getEntityFieldsSpec(tenantId, edgeId); + Sort.Direction sortDirection = pageLink.isAscOrder() ? Sort.Direction.ASC : Sort.Direction.DESC; + Pageable pageable = PageRequest.of(0, pageLink.getLimit(), sortDirection, ID_PROPERTY); + return DaoUtil.convertDataList(edgeEventRepository.findAll(Specification.where(timeSearchSpec).and(fieldsSpec), pageable).getContent()); + } + + public Optional save(EdgeEventEntity entity) { + log.debug("Save edge event [{}] ", entity); + if (entity.getTenantId() == null) { + log.trace("Save system edge event with predefined id {}", systemTenantId); + entity.setTenantId(UUIDConverter.fromTimeUUID(systemTenantId)); + } + if (entity.getUuid() == null) { + entity.setUuid(UUIDs.timeBased()); + } + return Optional.of(DaoUtil.getData(edgeEventRepository.save(entity))); + } + + private Specification getEntityFieldsSpec(UUID tenantId, EdgeId edgeId) { + return (root, criteriaQuery, criteriaBuilder) -> { + List predicates = new ArrayList<>(); + if (tenantId != null) { + Predicate tenantIdPredicate = criteriaBuilder.equal(root.get("tenantId"), UUIDConverter.fromTimeUUID(tenantId)); + predicates.add(tenantIdPredicate); + } + if (edgeId != null) { + Predicate entityIdPredicate = criteriaBuilder.equal(root.get("edgeId"), UUIDConverter.fromTimeUUID(edgeId.getId())); + predicates.add(entityIdPredicate); + } + return criteriaBuilder.and(predicates.toArray(new Predicate[]{})); + }; + } +} diff --git a/dao/src/main/resources/sql/schema-entities-hsql.sql b/dao/src/main/resources/sql/schema-entities-hsql.sql index cd8eae9e34..53042215cd 100644 --- a/dao/src/main/resources/sql/schema-entities-hsql.sql +++ b/dao/src/main/resources/sql/schema-entities-hsql.sql @@ -270,3 +270,14 @@ CREATE TABLE IF NOT EXISTS edge ( CONSTRAINT edge_name_unq_key UNIQUE (tenant_id, name), CONSTRAINT edge_routing_key_unq_key UNIQUE (routing_key) ); + +CREATE TABLE IF NOT EXISTS edge_event ( + id varchar(31) NOT NULL CONSTRAINT edge_event_pkey PRIMARY KEY, + edge_id varchar(31), + edge_event_type varchar(255), + entity_id varchar(31), + edge_event_action varchar(255), + entity_body varchar(10000000), + tenant_id varchar(31), + ts bigint NOT NULL +); \ No newline at end of file diff --git a/dao/src/main/resources/sql/schema-entities.sql b/dao/src/main/resources/sql/schema-entities.sql index de526788d3..606dd0c8a7 100644 --- a/dao/src/main/resources/sql/schema-entities.sql +++ b/dao/src/main/resources/sql/schema-entities.sql @@ -271,6 +271,18 @@ CREATE TABLE IF NOT EXISTS edge ( CONSTRAINT edge_routing_key_unq_key UNIQUE (routing_key) ); +CREATE TABLE IF NOT EXISTS edge_event ( + id varchar(31) NOT NULL CONSTRAINT edge_event_pkey PRIMARY KEY, + edge_id varchar(31), + edge_event_type varchar(255), + entity_id varchar(31), + edge_event_action varchar(255), + entity_body varchar(10000000), + tenant_id varchar(31), + ts bigint NOT NULL +); + + CREATE OR REPLACE PROCEDURE cleanup_events_by_ttl(IN ttl bigint, IN debug_ttl bigint, INOUT deleted bigint) LANGUAGE plpgsql AS $$ diff --git a/dao/src/test/java/org/thingsboard/server/dao/service/AbstractServiceTest.java b/dao/src/test/java/org/thingsboard/server/dao/service/AbstractServiceTest.java index 3311b49388..adb986cb03 100644 --- a/dao/src/test/java/org/thingsboard/server/dao/service/AbstractServiceTest.java +++ b/dao/src/test/java/org/thingsboard/server/dao/service/AbstractServiceTest.java @@ -45,6 +45,7 @@ import org.thingsboard.server.dao.customer.CustomerService; import org.thingsboard.server.dao.dashboard.DashboardService; import org.thingsboard.server.dao.device.DeviceCredentialsService; import org.thingsboard.server.dao.device.DeviceService; +import org.thingsboard.server.dao.edge.EdgeEventService; import org.thingsboard.server.dao.edge.EdgeService; import org.thingsboard.server.dao.entityview.EntityViewService; import org.thingsboard.server.dao.event.EventService; @@ -125,6 +126,9 @@ public abstract class AbstractServiceTest { @Autowired protected EdgeService edgeService; + @Autowired + protected EdgeEventService edgeEventService; + @Autowired private ComponentDescriptorService componentDescriptorService; diff --git a/dao/src/test/java/org/thingsboard/server/dao/service/BaseEdgeEventServiceTest.java b/dao/src/test/java/org/thingsboard/server/dao/service/BaseEdgeEventServiceTest.java new file mode 100644 index 0000000000..f4d622daa5 --- /dev/null +++ b/dao/src/test/java/org/thingsboard/server/dao/service/BaseEdgeEventServiceTest.java @@ -0,0 +1,108 @@ +/** + * Copyright © 2016-2020 The Thingsboard Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.thingsboard.server.dao.service; + +import com.datastax.driver.core.utils.UUIDs; +import org.junit.Assert; +import org.junit.Test; +import org.thingsboard.server.common.data.DataConstants; +import org.thingsboard.server.common.data.edge.EdgeEvent; +import org.thingsboard.server.common.data.edge.EdgeEventType; +import org.thingsboard.server.common.data.id.DeviceId; +import org.thingsboard.server.common.data.id.EdgeEventId; +import org.thingsboard.server.common.data.id.EdgeId; +import org.thingsboard.server.common.data.id.EntityId; +import org.thingsboard.server.common.data.id.TenantId; +import org.thingsboard.server.common.data.page.TimePageData; +import org.thingsboard.server.common.data.page.TimePageLink; + +import java.io.IOException; +import java.time.LocalDateTime; +import java.time.Month; +import java.time.ZoneOffset; + +public abstract class BaseEdgeEventServiceTest extends AbstractServiceTest { + + @Test + public void saveEdgeEvent() throws Exception { + EdgeId edgeId = new EdgeId(UUIDs.timeBased()); + DeviceId deviceId = new DeviceId(UUIDs.timeBased()); + EdgeEvent edgeEvent = generateEdgeEvent(null, edgeId, deviceId, DataConstants.ENTITY_CREATED); + EdgeEvent saved = edgeEventService.saveAsync(edgeEvent).get(); + Assert.assertEquals(saved.getTenantId(), edgeEvent.getTenantId()); + Assert.assertEquals(saved.getEdgeId(), edgeEvent.getEdgeId()); + Assert.assertEquals(saved.getEntityId(), edgeEvent.getEntityId()); + Assert.assertEquals(saved.getEdgeEventType(), edgeEvent.getEdgeEventType()); + Assert.assertEquals(saved.getEdgeEventAction(), edgeEvent.getEdgeEventAction()); + Assert.assertEquals(saved.getEntityBody(), edgeEvent.getEntityBody()); + } + + protected EdgeEvent generateEdgeEvent(TenantId tenantId, EdgeId edgeId, EntityId entityId, String edgeEventAction) throws IOException { + if (tenantId == null) { + tenantId = new TenantId(UUIDs.timeBased()); + } + EdgeEvent edgeEvent = new EdgeEvent(); + edgeEvent.setTenantId(tenantId); + edgeEvent.setEdgeId(edgeId); + edgeEvent.setEntityId(entityId.getId()); + edgeEvent.setEdgeEventType(EdgeEventType.DEVICE); + edgeEvent.setEdgeEventAction(edgeEventAction); + edgeEvent.setEntityBody(readFromResource("TestJsonData.json")); + return edgeEvent; + } + + + @Test + public void findEdgeEventsByTimeDescOrder() throws Exception { + long timeBeforeStartTime = LocalDateTime.of(2020, Month.NOVEMBER, 1, 11, 30).toEpochSecond(ZoneOffset.UTC); + long startTime = LocalDateTime.of(2020, Month.NOVEMBER, 1, 12, 0).toEpochSecond(ZoneOffset.UTC); + long eventTime = LocalDateTime.of(2020, Month.NOVEMBER, 1, 12, 30).toEpochSecond(ZoneOffset.UTC); + long endTime = LocalDateTime.of(2020, Month.NOVEMBER, 1, 13, 0).toEpochSecond(ZoneOffset.UTC); + long timeAfterEndTime = LocalDateTime.of(2020, Month.NOVEMBER, 1, 13, 30).toEpochSecond(ZoneOffset.UTC); + + EdgeId edgeId = new EdgeId(UUIDs.timeBased()); + DeviceId deviceId = new DeviceId(UUIDs.timeBased()); + TenantId tenantId = new TenantId(UUIDs.timeBased()); + saveEdgeEventWithProvidedTime(timeBeforeStartTime, edgeId, deviceId, tenantId); + EdgeEvent savedEdgeEvent = saveEdgeEventWithProvidedTime(eventTime, edgeId, deviceId, tenantId); + EdgeEvent savedEdgeEvent2 = saveEdgeEventWithProvidedTime(eventTime + 1, edgeId, deviceId, tenantId); + EdgeEvent savedEdgeEvent3 = saveEdgeEventWithProvidedTime(eventTime + 2, edgeId, deviceId, tenantId); + saveEdgeEventWithProvidedTime(timeAfterEndTime, edgeId, deviceId, tenantId); + + TimePageData edgeEvents = edgeEventService.findEdgeEvents(tenantId, edgeId, new TimePageLink(2, startTime, endTime, false)); + + Assert.assertNotNull(edgeEvents.getData()); + Assert.assertTrue(edgeEvents.getData().size() == 2); + Assert.assertTrue(edgeEvents.getData().get(0).getUuidId().equals(savedEdgeEvent3.getUuidId())); + Assert.assertTrue(edgeEvents.getData().get(1).getUuidId().equals(savedEdgeEvent2.getUuidId())); + Assert.assertTrue(edgeEvents.hasNext()); + Assert.assertNotNull(edgeEvents.getNextPageLink()); + + edgeEvents = edgeEventService.findEdgeEvents(tenantId, edgeId, edgeEvents.getNextPageLink()); + + Assert.assertNotNull(edgeEvents.getData()); + Assert.assertTrue(edgeEvents.getData().size() == 1); + Assert.assertTrue(edgeEvents.getData().get(0).getUuidId().equals(savedEdgeEvent.getUuidId())); + Assert.assertFalse(edgeEvents.hasNext()); + Assert.assertNull(edgeEvents.getNextPageLink()); + } + + private EdgeEvent saveEdgeEventWithProvidedTime(long time, EdgeId edgeId, EntityId entityId, TenantId tenantId) throws Exception { + EdgeEvent edgeEvent = generateEdgeEvent(tenantId, edgeId, entityId, DataConstants.ENTITY_CREATED); + edgeEvent.setId(new EdgeEventId(UUIDs.startOf(time))); + return edgeEventService.saveAsync(edgeEvent).get(); + } +} \ No newline at end of file diff --git a/dao/src/test/java/org/thingsboard/server/dao/service/EdgeServiceImplTest.java b/dao/src/test/java/org/thingsboard/server/dao/service/BaseEdgeServiceTest.java similarity index 99% rename from dao/src/test/java/org/thingsboard/server/dao/service/EdgeServiceImplTest.java rename to dao/src/test/java/org/thingsboard/server/dao/service/BaseEdgeServiceTest.java index 7dbedce770..7d31ff4236 100644 --- a/dao/src/test/java/org/thingsboard/server/dao/service/EdgeServiceImplTest.java +++ b/dao/src/test/java/org/thingsboard/server/dao/service/BaseEdgeServiceTest.java @@ -37,7 +37,7 @@ import java.util.List; import static org.thingsboard.server.dao.model.ModelConstants.NULL_UUID; -public abstract class EdgeServiceImplTest extends AbstractServiceTest { +public abstract class BaseEdgeServiceTest extends AbstractServiceTest { private IdComparator idComparator = new IdComparator<>(); diff --git a/dao/src/test/java/org/thingsboard/server/dao/service/BaseRuleChainServiceTest.java b/dao/src/test/java/org/thingsboard/server/dao/service/BaseRuleChainServiceTest.java index b7ecc1f784..2ab0fa4067 100644 --- a/dao/src/test/java/org/thingsboard/server/dao/service/BaseRuleChainServiceTest.java +++ b/dao/src/test/java/org/thingsboard/server/dao/service/BaseRuleChainServiceTest.java @@ -145,7 +145,7 @@ public abstract class BaseRuleChainServiceTest extends AbstractServiceTest { TextPageLink pageLink = new TextPageLink(16); TextPageData pageData = null; do { - pageData = ruleChainService.findTenantRuleChainsByType(tenantId, RuleChainType.SYSTEM, pageLink); + pageData = ruleChainService.findTenantRuleChainsByType(tenantId, RuleChainType.CORE, pageLink); loadedRuleChains.addAll(pageData.getData()); if (pageData.hasNext()) { pageLink = pageData.getNextPageLink(); @@ -160,7 +160,7 @@ public abstract class BaseRuleChainServiceTest extends AbstractServiceTest { ruleChainService.deleteRuleChainsByTenantId(tenantId); pageLink = new TextPageLink(31); - pageData = ruleChainService.findTenantRuleChainsByType(tenantId, RuleChainType.SYSTEM, pageLink); + pageData = ruleChainService.findTenantRuleChainsByType(tenantId, RuleChainType.CORE, pageLink); Assert.assertFalse(pageData.hasNext()); Assert.assertTrue(pageData.getData().isEmpty()); @@ -196,7 +196,7 @@ public abstract class BaseRuleChainServiceTest extends AbstractServiceTest { TextPageLink pageLink = new TextPageLink(19, name1); TextPageData pageData = null; do { - pageData = ruleChainService.findTenantRuleChainsByType(tenantId, RuleChainType.SYSTEM, pageLink); + pageData = ruleChainService.findTenantRuleChainsByType(tenantId, RuleChainType.CORE, pageLink); loadedRuleChainsName1.addAll(pageData.getData()); if (pageData.hasNext()) { pageLink = pageData.getNextPageLink(); @@ -211,7 +211,7 @@ public abstract class BaseRuleChainServiceTest extends AbstractServiceTest { List loadedRuleChainsName2 = new ArrayList<>(); pageLink = new TextPageLink(4, name2); do { - pageData = ruleChainService.findTenantRuleChainsByType(tenantId, RuleChainType.SYSTEM, pageLink); + pageData = ruleChainService.findTenantRuleChainsByType(tenantId, RuleChainType.CORE, pageLink); loadedRuleChainsName2.addAll(pageData.getData()); if (pageData.hasNext()) { pageLink = pageData.getNextPageLink(); @@ -228,7 +228,7 @@ public abstract class BaseRuleChainServiceTest extends AbstractServiceTest { } pageLink = new TextPageLink(4, name1); - pageData = ruleChainService.findTenantRuleChainsByType(tenantId, RuleChainType.SYSTEM, pageLink); + pageData = ruleChainService.findTenantRuleChainsByType(tenantId, RuleChainType.CORE, pageLink); Assert.assertFalse(pageData.hasNext()); Assert.assertEquals(0, pageData.getData().size()); @@ -237,7 +237,7 @@ public abstract class BaseRuleChainServiceTest extends AbstractServiceTest { } pageLink = new TextPageLink(4, name2); - pageData = ruleChainService.findTenantRuleChainsByType(tenantId, RuleChainType.SYSTEM, pageLink); + pageData = ruleChainService.findTenantRuleChainsByType(tenantId, RuleChainType.CORE, pageLink); Assert.assertFalse(pageData.hasNext()); Assert.assertEquals(0, pageData.getData().size()); } diff --git a/dao/src/test/java/org/thingsboard/server/dao/service/nosql/EdgeEventServiceNoSqlTest.java b/dao/src/test/java/org/thingsboard/server/dao/service/nosql/EdgeEventServiceNoSqlTest.java new file mode 100644 index 0000000000..fa6a25f6da --- /dev/null +++ b/dao/src/test/java/org/thingsboard/server/dao/service/nosql/EdgeEventServiceNoSqlTest.java @@ -0,0 +1,23 @@ +/** + * Copyright © 2016-2020 The Thingsboard Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.thingsboard.server.dao.service.nosql; + +import org.thingsboard.server.dao.service.BaseEdgeEventServiceTest; +import org.thingsboard.server.dao.service.DaoNoSqlTest; + +@DaoNoSqlTest +public class EdgeEventServiceNoSqlTest extends BaseEdgeEventServiceTest { +} diff --git a/dao/src/test/java/org/thingsboard/server/dao/service/nosql/EdgeServiceNoSqlTest.java b/dao/src/test/java/org/thingsboard/server/dao/service/nosql/EdgeServiceNoSqlTest.java index cf365464f8..4b91ee9a6e 100644 --- a/dao/src/test/java/org/thingsboard/server/dao/service/nosql/EdgeServiceNoSqlTest.java +++ b/dao/src/test/java/org/thingsboard/server/dao/service/nosql/EdgeServiceNoSqlTest.java @@ -15,9 +15,9 @@ */ package org.thingsboard.server.dao.service.nosql; -import org.thingsboard.server.dao.service.EdgeServiceImplTest; +import org.thingsboard.server.dao.service.BaseEdgeServiceTest; import org.thingsboard.server.dao.service.DaoNoSqlTest; @DaoNoSqlTest -public class EdgeServiceNoSqlTest extends EdgeServiceImplTest { +public class EdgeServiceNoSqlTest extends BaseEdgeServiceTest { } diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/edge/EdgeQueueEntry.java b/dao/src/test/java/org/thingsboard/server/dao/service/sql/EdgeEventServiceSqlTest.java similarity index 70% rename from common/data/src/main/java/org/thingsboard/server/common/data/edge/EdgeQueueEntry.java rename to dao/src/test/java/org/thingsboard/server/dao/service/sql/EdgeEventServiceSqlTest.java index 3299ab07be..58b7a3014e 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/edge/EdgeQueueEntry.java +++ b/dao/src/test/java/org/thingsboard/server/dao/service/sql/EdgeEventServiceSqlTest.java @@ -13,13 +13,11 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.thingsboard.server.common.data.edge; +package org.thingsboard.server.dao.service.sql; -import lombok.Data; +import org.thingsboard.server.dao.service.BaseEdgeEventServiceTest; +import org.thingsboard.server.dao.service.DaoSqlTest; -@Data -public class EdgeQueueEntry { - private String type; - private EdgeQueueEntityType entityType; - private String data; +@DaoSqlTest +public class EdgeEventServiceSqlTest extends BaseEdgeEventServiceTest { } diff --git a/dao/src/test/java/org/thingsboard/server/dao/service/sql/EdgeServiceSqlTest.java b/dao/src/test/java/org/thingsboard/server/dao/service/sql/EdgeServiceSqlTest.java index 445a9718ec..989b8f3148 100644 --- a/dao/src/test/java/org/thingsboard/server/dao/service/sql/EdgeServiceSqlTest.java +++ b/dao/src/test/java/org/thingsboard/server/dao/service/sql/EdgeServiceSqlTest.java @@ -15,9 +15,9 @@ */ package org.thingsboard.server.dao.service.sql; -import org.thingsboard.server.dao.service.EdgeServiceImplTest; +import org.thingsboard.server.dao.service.BaseEdgeServiceTest; import org.thingsboard.server.dao.service.DaoSqlTest; @DaoSqlTest -public class EdgeServiceSqlTest extends EdgeServiceImplTest { +public class EdgeServiceSqlTest extends BaseEdgeServiceTest { } diff --git a/dao/src/test/resources/sql/hsql/drop-all-tables.sql b/dao/src/test/resources/sql/hsql/drop-all-tables.sql index 8946f77d6c..5b1234483f 100644 --- a/dao/src/test/resources/sql/hsql/drop-all-tables.sql +++ b/dao/src/test/resources/sql/hsql/drop-all-tables.sql @@ -20,4 +20,5 @@ DROP TABLE IF EXISTS widgets_bundle; DROP TABLE IF EXISTS rule_node; DROP TABLE IF EXISTS rule_chain; DROP TABLE IF EXISTS entity_view; -DROP TABLE IF EXISTS edge; \ No newline at end of file +DROP TABLE IF EXISTS edge; +DROP TABLE IF EXISTS edge_event; \ No newline at end of file diff --git a/rule-engine/rule-engine-api/src/main/java/org/thingsboard/rule/engine/api/RuleNode.java b/rule-engine/rule-engine-api/src/main/java/org/thingsboard/rule/engine/api/RuleNode.java index 96b45c2cbb..1efe0081d7 100644 --- a/rule-engine/rule-engine-api/src/main/java/org/thingsboard/rule/engine/api/RuleNode.java +++ b/rule-engine/rule-engine-api/src/main/java/org/thingsboard/rule/engine/api/RuleNode.java @@ -58,6 +58,6 @@ public @interface RuleNode { boolean customRelations() default false; - RuleChainType[] ruleChainTypes() default RuleChainType.SYSTEM; + RuleChainType[] ruleChainTypes() default RuleChainType.CORE; } diff --git a/rule-engine/rule-engine-api/src/main/java/org/thingsboard/rule/engine/api/TbContext.java b/rule-engine/rule-engine-api/src/main/java/org/thingsboard/rule/engine/api/TbContext.java index bd26d59f6d..3761933c96 100644 --- a/rule-engine/rule-engine-api/src/main/java/org/thingsboard/rule/engine/api/TbContext.java +++ b/rule-engine/rule-engine-api/src/main/java/org/thingsboard/rule/engine/api/TbContext.java @@ -35,6 +35,7 @@ import org.thingsboard.server.dao.cassandra.CassandraCluster; import org.thingsboard.server.dao.customer.CustomerService; import org.thingsboard.server.dao.dashboard.DashboardService; import org.thingsboard.server.dao.device.DeviceService; +import org.thingsboard.server.dao.edge.EdgeEventService; import org.thingsboard.server.dao.edge.EdgeService; import org.thingsboard.server.dao.entityview.EntityViewService; import org.thingsboard.server.dao.nosql.CassandraStatementTask; @@ -190,6 +191,8 @@ public interface TbContext { EdgeService getEdgeService(); + EdgeEventService getEdgeEventService(); + ListeningExecutor getJsExecutor(); ListeningExecutor getMailExecutor(); diff --git a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/action/TbAssignToCustomerNode.java b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/action/TbAssignToCustomerNode.java index 07a8744873..5d0fe87fa9 100644 --- a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/action/TbAssignToCustomerNode.java +++ b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/action/TbAssignToCustomerNode.java @@ -38,7 +38,7 @@ import org.thingsboard.server.common.msg.TbMsg; uiResources = {"static/rulenode/rulenode-core-config.js"}, configDirective = "tbActionNodeAssignToCustomerConfig", icon = "add_circle", - ruleChainTypes = {RuleChainType.SYSTEM, RuleChainType.EDGE} + ruleChainTypes = {RuleChainType.CORE, RuleChainType.EDGE} ) public class TbAssignToCustomerNode extends TbAbstractCustomerActionNode { diff --git a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/action/TbClearAlarmNode.java b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/action/TbClearAlarmNode.java index b8e328344a..b7f7b8ca04 100644 --- a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/action/TbClearAlarmNode.java +++ b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/action/TbClearAlarmNode.java @@ -46,7 +46,7 @@ import org.thingsboard.server.common.msg.TbMsg; uiResources = {"static/rulenode/rulenode-core-config.js"}, configDirective = "tbActionNodeClearAlarmConfig", icon = "notifications_off", - ruleChainTypes = {RuleChainType.SYSTEM, RuleChainType.EDGE} + ruleChainTypes = {RuleChainType.CORE, RuleChainType.EDGE} ) public class TbClearAlarmNode extends TbAbstractAlarmNode { diff --git a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/action/TbCopyAttributesToEntityViewNode.java b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/action/TbCopyAttributesToEntityViewNode.java index 954e1bed27..0d256b302c 100644 --- a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/action/TbCopyAttributesToEntityViewNode.java +++ b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/action/TbCopyAttributesToEntityViewNode.java @@ -58,7 +58,7 @@ import static org.thingsboard.rule.engine.api.TbRelationTypes.SUCCESS; uiResources = {"static/rulenode/rulenode-core-config.js"}, configDirective = "tbNodeEmptyConfig", icon = "content_copy", - ruleChainTypes = {RuleChainType.SYSTEM, RuleChainType.EDGE} + ruleChainTypes = {RuleChainType.CORE, RuleChainType.EDGE} ) public class TbCopyAttributesToEntityViewNode implements TbNode { diff --git a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/action/TbCreateAlarmNode.java b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/action/TbCreateAlarmNode.java index 4644b7820b..4bd56be6be 100644 --- a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/action/TbCreateAlarmNode.java +++ b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/action/TbCreateAlarmNode.java @@ -52,7 +52,7 @@ import java.util.List; uiResources = {"static/rulenode/rulenode-core-config.js"}, configDirective = "tbActionNodeCreateAlarmConfig", icon = "notifications_active", - ruleChainTypes = {RuleChainType.SYSTEM, RuleChainType.EDGE} + ruleChainTypes = {RuleChainType.CORE, RuleChainType.EDGE} ) public class TbCreateAlarmNode extends TbAbstractAlarmNode { diff --git a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/action/TbCreateRelationNode.java b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/action/TbCreateRelationNode.java index 6404246ed0..c9c0edd96f 100644 --- a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/action/TbCreateRelationNode.java +++ b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/action/TbCreateRelationNode.java @@ -55,7 +55,7 @@ import java.util.List; uiResources = {"static/rulenode/rulenode-core-config.js"}, configDirective = "tbActionNodeCreateRelationConfig", icon = "add_circle", - ruleChainTypes = {RuleChainType.SYSTEM, RuleChainType.EDGE} + ruleChainTypes = {RuleChainType.CORE, RuleChainType.EDGE} ) public class TbCreateRelationNode extends TbAbstractRelationActionNode { diff --git a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/action/TbDeleteRelationNode.java b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/action/TbDeleteRelationNode.java index cf53645e84..2ea2264dad 100644 --- a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/action/TbDeleteRelationNode.java +++ b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/action/TbDeleteRelationNode.java @@ -45,7 +45,7 @@ import java.util.List; uiResources = {"static/rulenode/rulenode-core-config.js"}, configDirective = "tbActionNodeDeleteRelationConfig", icon = "remove_circle", - ruleChainTypes = {RuleChainType.SYSTEM, RuleChainType.EDGE} + ruleChainTypes = {RuleChainType.CORE, RuleChainType.EDGE} ) public class TbDeleteRelationNode extends TbAbstractRelationActionNode { diff --git a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/action/TbLogNode.java b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/action/TbLogNode.java index d84a6f4e2e..393cc72b0b 100644 --- a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/action/TbLogNode.java +++ b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/action/TbLogNode.java @@ -38,7 +38,7 @@ import static org.thingsboard.rule.engine.api.TbRelationTypes.SUCCESS; uiResources = {"static/rulenode/rulenode-core-config.js"}, configDirective = "tbActionNodeLogConfig", icon = "menu", - ruleChainTypes = {RuleChainType.SYSTEM, RuleChainType.EDGE} + ruleChainTypes = {RuleChainType.CORE, RuleChainType.EDGE} ) public class TbLogNode implements TbNode { diff --git a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/action/TbMsgCountNode.java b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/action/TbMsgCountNode.java index e909045755..4aeee24e1b 100644 --- a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/action/TbMsgCountNode.java +++ b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/action/TbMsgCountNode.java @@ -44,7 +44,7 @@ import static org.thingsboard.rule.engine.api.TbRelationTypes.SUCCESS; icon = "functions", uiResources = {"static/rulenode/rulenode-core-config.js"}, configDirective = "tbActionNodeMsgCountConfig", - ruleChainTypes = {RuleChainType.SYSTEM, RuleChainType.EDGE} + ruleChainTypes = {RuleChainType.CORE, RuleChainType.EDGE} ) public class TbMsgCountNode implements TbNode { diff --git a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/action/TbUnassignFromCustomerNode.java b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/action/TbUnassignFromCustomerNode.java index 73f9e2da08..79513c728d 100644 --- a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/action/TbUnassignFromCustomerNode.java +++ b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/action/TbUnassignFromCustomerNode.java @@ -35,7 +35,7 @@ import org.thingsboard.server.common.msg.TbMsg; uiResources = {"static/rulenode/rulenode-core-config.js"}, configDirective = "tbActionNodeUnAssignToCustomerConfig", icon = "remove_circle", - ruleChainTypes = {RuleChainType.SYSTEM, RuleChainType.EDGE} + ruleChainTypes = {RuleChainType.CORE, RuleChainType.EDGE} ) public class TbUnassignFromCustomerNode extends TbAbstractCustomerActionNode { diff --git a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/aws/sns/TbSnsNode.java b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/aws/sns/TbSnsNode.java index 697c139588..bfc9a0c865 100644 --- a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/aws/sns/TbSnsNode.java +++ b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/aws/sns/TbSnsNode.java @@ -47,7 +47,7 @@ import static org.thingsboard.common.util.DonAsynchron.withCallback; uiResources = {"static/rulenode/rulenode-core-config.js"}, configDirective = "tbActionNodeSnsConfig", iconUrl = "data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNCAyNCIgd2lkdGg9IjQ4IiBoZWlnaHQ9IjQ4Ij48cGF0aCBkPSJNMTMuMjMgMTAuNTZWMTBjLTEuOTQgMC0zLjk5LjM5LTMuOTkgMi42NyAwIDEuMTYuNjEgMS45NSAxLjYzIDEuOTUuNzYgMCAxLjQzLS40NyAxLjg2LTEuMjIuNTItLjkzLjUtMS44LjUtMi44NG0yLjcgNi41M2MtLjE4LjE2LS40My4xNy0uNjMuMDYtLjg5LS43NC0xLjA1LTEuMDgtMS41NC0xLjc5LTEuNDcgMS41LTIuNTEgMS45NS00LjQyIDEuOTUtMi4yNSAwLTQuMDEtMS4zOS00LjAxLTQuMTcgMC0yLjE4IDEuMTctMy42NCAyLjg2LTQuMzggMS40Ni0uNjQgMy40OS0uNzYgNS4wNC0uOTNWNy41YzAtLjY2LjA1LTEuNDEtLjMzLTEuOTYtLjMyLS40OS0uOTUtLjctMS41LS43LTEuMDIgMC0xLjkzLjUzLTIuMTUgMS42MS0uMDUuMjQtLjI1LjQ4LS40Ny40OWwtMi42LS4yOGMtLjIyLS4wNS0uNDYtLjIyLS40LS41Ni42LTMuMTUgMy40NS00LjEgNi00LjEgMS4zIDAgMyAuMzUgNC4wMyAxLjMzQzE3LjExIDQuNTUgMTcgNi4xOCAxNyA3Ljk1djQuMTdjMCAxLjI1LjUgMS44MSAxIDIuNDguMTcuMjUuMjEuNTQgMCAuNzFsLTIuMDYgMS43OGgtLjAxIj48L3BhdGg+PHBhdGggZD0iTTIwLjE2IDE5LjU0QzE4IDIxLjE0IDE0LjgyIDIyIDEyLjEgMjJjLTMuODEgMC03LjI1LTEuNDEtOS44NS0zLjc2LS4yLS4xOC0uMDItLjQzLjI1LS4yOSAyLjc4IDEuNjMgNi4yNSAyLjYxIDkuODMgMi42MSAyLjQxIDAgNS4wNy0uNSA3LjUxLTEuNTMuMzctLjE2LjY2LjI0LjMyLjUxIj48L3BhdGg+PHBhdGggZD0iTTIxLjA3IDE4LjVjLS4yOC0uMzYtMS44NS0uMTctMi41Ny0uMDgtLjE5LjAyLS4yMi0uMTYtLjAzLS4zIDEuMjQtLjg4IDMuMjktLjYyIDMuNTMtLjMzLjI0LjMtLjA3IDIuMzUtMS4yNCAzLjMyLS4xOC4xNi0uMzUuMDctLjI2LS4xMS4yNi0uNjcuODUtMi4xNC41Ny0yLjV6Ij48L3BhdGg+PC9zdmc+", - ruleChainTypes = {RuleChainType.SYSTEM, RuleChainType.EDGE} + ruleChainTypes = {RuleChainType.CORE, RuleChainType.EDGE} ) public class TbSnsNode implements TbNode { diff --git a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/aws/sqs/TbSqsNode.java b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/aws/sqs/TbSqsNode.java index cb39979369..27359dc8f3 100644 --- a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/aws/sqs/TbSqsNode.java +++ b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/aws/sqs/TbSqsNode.java @@ -52,7 +52,7 @@ import static org.thingsboard.common.util.DonAsynchron.withCallback; uiResources = {"static/rulenode/rulenode-core-config.js"}, configDirective = "tbActionNodeSqsConfig", iconUrl = "data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNCAyNCIgd2lkdGg9IjQ4IiBoZWlnaHQ9IjQ4Ij48cGF0aCBkPSJNMTMuMjMgMTAuNTZWMTBjLTEuOTQgMC0zLjk5LjM5LTMuOTkgMi42NyAwIDEuMTYuNjEgMS45NSAxLjYzIDEuOTUuNzYgMCAxLjQzLS40NyAxLjg2LTEuMjIuNTItLjkzLjUtMS44LjUtMi44NG0yLjcgNi41M2MtLjE4LjE2LS40My4xNy0uNjMuMDYtLjg5LS43NC0xLjA1LTEuMDgtMS41NC0xLjc5LTEuNDcgMS41LTIuNTEgMS45NS00LjQyIDEuOTUtMi4yNSAwLTQuMDEtMS4zOS00LjAxLTQuMTcgMC0yLjE4IDEuMTctMy42NCAyLjg2LTQuMzggMS40Ni0uNjQgMy40OS0uNzYgNS4wNC0uOTNWNy41YzAtLjY2LjA1LTEuNDEtLjMzLTEuOTYtLjMyLS40OS0uOTUtLjctMS41LS43LTEuMDIgMC0xLjkzLjUzLTIuMTUgMS42MS0uMDUuMjQtLjI1LjQ4LS40Ny40OWwtMi42LS4yOGMtLjIyLS4wNS0uNDYtLjIyLS40LS41Ni42LTMuMTUgMy40NS00LjEgNi00LjEgMS4zIDAgMyAuMzUgNC4wMyAxLjMzQzE3LjExIDQuNTUgMTcgNi4xOCAxNyA3Ljk1djQuMTdjMCAxLjI1LjUgMS44MSAxIDIuNDguMTcuMjUuMjEuNTQgMCAuNzFsLTIuMDYgMS43OGgtLjAxIj48L3BhdGg+PHBhdGggZD0iTTIwLjE2IDE5LjU0QzE4IDIxLjE0IDE0LjgyIDIyIDEyLjEgMjJjLTMuODEgMC03LjI1LTEuNDEtOS44NS0zLjc2LS4yLS4xOC0uMDItLjQzLjI1LS4yOSAyLjc4IDEuNjMgNi4yNSAyLjYxIDkuODMgMi42MSAyLjQxIDAgNS4wNy0uNSA3LjUxLTEuNTMuMzctLjE2LjY2LjI0LjMyLjUxIj48L3BhdGg+PHBhdGggZD0iTTIxLjA3IDE4LjVjLS4yOC0uMzYtMS44NS0uMTctMi41Ny0uMDgtLjE5LjAyLS4yMi0uMTYtLjAzLS4zIDEuMjQtLjg4IDMuMjktLjYyIDMuNTMtLjMzLjI0LjMtLjA3IDIuMzUtMS4yNCAzLjMyLS4xOC4xNi0uMzUuMDctLjI2LS4xMS4yNi0uNjcuODUtMi4xNC41Ny0yLjV6Ij48L3BhdGg+PC9zdmc+", - ruleChainTypes = {RuleChainType.SYSTEM, RuleChainType.EDGE} + ruleChainTypes = {RuleChainType.CORE, RuleChainType.EDGE} ) public class TbSqsNode implements TbNode { diff --git a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/debug/TbMsgGeneratorNode.java b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/debug/TbMsgGeneratorNode.java index ca89d6d2a1..c646b1ca36 100644 --- a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/debug/TbMsgGeneratorNode.java +++ b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/debug/TbMsgGeneratorNode.java @@ -45,7 +45,7 @@ import static org.thingsboard.rule.engine.api.TbRelationTypes.SUCCESS; uiResources = {"static/rulenode/rulenode-core-config.js", "static/rulenode/rulenode-core-config.css"}, configDirective = "tbActionNodeGeneratorConfig", icon = "repeat", - ruleChainTypes = {RuleChainType.SYSTEM, RuleChainType.EDGE} + ruleChainTypes = {RuleChainType.CORE, RuleChainType.EDGE} ) public class TbMsgGeneratorNode implements TbNode { diff --git a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/delay/TbMsgDelayNode.java b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/delay/TbMsgDelayNode.java index e3b1e71ecc..d7ceefda36 100644 --- a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/delay/TbMsgDelayNode.java +++ b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/delay/TbMsgDelayNode.java @@ -46,7 +46,7 @@ import static org.thingsboard.rule.engine.api.TbRelationTypes.SUCCESS; icon = "pause", uiResources = {"static/rulenode/rulenode-core-config.js"}, configDirective = "tbActionNodeMsgDelayConfig", - ruleChainTypes = {RuleChainType.SYSTEM, RuleChainType.EDGE} + ruleChainTypes = {RuleChainType.CORE, RuleChainType.EDGE} ) public class TbMsgDelayNode implements TbNode { diff --git a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/edge/PushToEdgeNodeCallback.java b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/edge/PushToEdgeNodeCallback.java deleted file mode 100644 index 77c6a64194..0000000000 --- a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/edge/PushToEdgeNodeCallback.java +++ /dev/null @@ -1,41 +0,0 @@ -/** - * Copyright © 2016-2020 The Thingsboard Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.thingsboard.rule.engine.edge; - -import com.google.common.util.concurrent.FutureCallback; -import lombok.Data; -import org.thingsboard.rule.engine.api.TbContext; -import org.thingsboard.server.common.msg.TbMsg; - -import javax.annotation.Nullable; - -import static org.thingsboard.rule.engine.api.TbRelationTypes.SUCCESS; - -@Data -class PushToEdgeNodeCallback implements FutureCallback { - private final TbContext ctx; - private final TbMsg msg; - - @Override - public void onSuccess(@Nullable Void result) { - ctx.tellNext(msg, SUCCESS); - } - - @Override - public void onFailure(Throwable t) { - ctx.tellFailure(msg, t); - } -} diff --git a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/edge/TbMsgPushToEdgeNode.java b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/edge/TbMsgPushToEdgeNode.java index 92a4103867..1e42224c70 100644 --- a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/edge/TbMsgPushToEdgeNode.java +++ b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/edge/TbMsgPushToEdgeNode.java @@ -15,6 +15,10 @@ */ package org.thingsboard.rule.engine.edge; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.google.common.util.concurrent.FutureCallback; +import com.google.common.util.concurrent.Futures; +import com.google.common.util.concurrent.ListenableFuture; import lombok.extern.slf4j.Slf4j; import org.thingsboard.rule.engine.api.EmptyNodeConfiguration; import org.thingsboard.rule.engine.api.RuleNode; @@ -23,10 +27,25 @@ import org.thingsboard.rule.engine.api.TbNode; import org.thingsboard.rule.engine.api.TbNodeConfiguration; import org.thingsboard.rule.engine.api.TbNodeException; import org.thingsboard.rule.engine.api.util.TbNodeUtils; +import org.thingsboard.server.common.data.DataConstants; +import org.thingsboard.server.common.data.EntityType; +import org.thingsboard.server.common.data.audit.ActionType; +import org.thingsboard.server.common.data.edge.EdgeEvent; +import org.thingsboard.server.common.data.edge.EdgeEventType; +import org.thingsboard.server.common.data.id.EdgeId; +import org.thingsboard.server.common.data.id.EntityId; +import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.common.data.plugin.ComponentType; +import org.thingsboard.server.common.data.relation.EntityRelation; +import org.thingsboard.server.common.data.relation.RelationTypeGroup; import org.thingsboard.server.common.msg.TbMsg; import org.thingsboard.server.common.msg.session.SessionMsgType; +import javax.annotation.Nullable; +import java.util.List; + +import static org.thingsboard.rule.engine.api.TbRelationTypes.SUCCESS; + @Slf4j @RuleNode( type = ComponentType.ACTION, @@ -40,13 +59,10 @@ import org.thingsboard.server.common.msg.session.SessionMsgType; ) public class TbMsgPushToEdgeNode implements TbNode { - private static final String CLOUD_MSG_SOURCE = "cloud"; - private static final String EDGE_MSG_SOURCE = "edge"; - private static final String MSG_SOURCE_KEY = "source"; - private static final String TS_METADATA_KEY = "ts"; - private EmptyNodeConfiguration config; + private static final ObjectMapper json = new ObjectMapper(); + @Override public void init(TbContext ctx, TbNodeConfiguration configuration) throws TbNodeException { this.config = TbNodeUtils.convert(configuration, EmptyNodeConfiguration.class); @@ -54,14 +70,71 @@ public class TbMsgPushToEdgeNode implements TbNode { @Override public void onMsg(TbContext ctx, TbMsg msg) { - if (EDGE_MSG_SOURCE.equalsIgnoreCase(msg.getMetaData().getValue(MSG_SOURCE_KEY))) { - return; - } - if (msg.getType().equals(SessionMsgType.POST_TELEMETRY_REQUEST.name())) { - msg.getMetaData().putValue(TS_METADATA_KEY, Long.toString(System.currentTimeMillis())); + if (EntityType.DEVICE.equals(msg.getOriginator().getEntityType()) || + EntityType.DEVICE.equals(msg.getOriginator().getEntityType()) || + EntityType.DEVICE.equals(msg.getOriginator().getEntityType()) || + EntityType.DEVICE.equals(msg.getOriginator().getEntityType())) { + if (SessionMsgType.POST_TELEMETRY_REQUEST.name().equals(msg.getType()) || + SessionMsgType.POST_ATTRIBUTES_REQUEST.name().equals(msg.getType()) || + DataConstants.ATTRIBUTES_UPDATED.equals(msg.getType()) || + DataConstants.ATTRIBUTES_DELETED.equals(msg.getType())) { + ListenableFuture getEdgeIdFuture = getEdgeIdByOriginatorId(ctx, ctx.getTenantId(), msg.getOriginator()); + Futures.transform(getEdgeIdFuture, edgeId -> { + EdgeEventType edgeEventTypeByEntityType = ctx.getEdgeEventService().getEdgeEventTypeByEntityType(msg.getOriginator().getEntityType()); + if (edgeEventTypeByEntityType == null) { + log.debug("Edge event type is null. Entity Type {}", msg.getOriginator().getEntityType()); + ctx.tellFailure(msg, new RuntimeException("Edge event type is null. Entity Type '"+ msg.getOriginator().getEntityType() + "'")); + } + ActionType actionType; + if (SessionMsgType.POST_TELEMETRY_REQUEST.name().equals(msg.getType())) { + actionType = ActionType.TIMESERIES_UPDATED; + } else if (SessionMsgType.POST_ATTRIBUTES_REQUEST.name().equals(msg.getType()) || + DataConstants.ATTRIBUTES_UPDATED.equals(msg.getType())) { + actionType = ActionType.ATTRIBUTES_UPDATED; + } else { + actionType = ActionType.ATTRIBUTES_DELETED; + } + EdgeEvent edgeEvent = new EdgeEvent(); + edgeEvent.setTenantId(ctx.getTenantId()); + edgeEvent.setEdgeId(edgeId); + edgeEvent.setEdgeEventAction(actionType.name()); + edgeEvent.setEntityId(msg.getOriginator().getId()); + edgeEvent.setEdgeEventType(edgeEventTypeByEntityType); + edgeEvent.setEntityBody(json.valueToTree(msg.getData())); + ListenableFuture saveFuture = ctx.getEdgeEventService().saveAsync(edgeEvent); + Futures.addCallback(saveFuture, new FutureCallback() { + @Override + public void onSuccess(@Nullable EdgeEvent event) { + ctx.tellNext(msg, SUCCESS); + } + + @Override + public void onFailure(Throwable th) { + log.error("Could not save edge event", th); + ctx.tellFailure(msg, th); + } + }, ctx.getDbCallbackExecutor()); + return null; + }, ctx.getDbCallbackExecutor()); + } else { + log.debug("Unsupported msg type {}", msg.getType()); + ctx.tellFailure(msg, new RuntimeException("Unsupported msg type '" + msg.getType() + "'")); + } + } else { + log.debug("Unsupported originator type {}", msg.getOriginator().getEntityType()); + ctx.tellFailure(msg, new RuntimeException("Unsupported originator type '" + msg.getOriginator().getEntityType() + "'")); } - msg.getMetaData().putValue(MSG_SOURCE_KEY, CLOUD_MSG_SOURCE); - ctx.getEdgeService().pushEventToEdge(ctx.getTenantId(), msg, new PushToEdgeNodeCallback(ctx, msg)); + } + + private ListenableFuture getEdgeIdByOriginatorId(TbContext ctx, TenantId tenantId, EntityId originatorId) { + ListenableFuture> future = ctx.getRelationService().findByToAndTypeAsync(tenantId, originatorId, EntityRelation.CONTAINS_TYPE, RelationTypeGroup.EDGE); + return Futures.transform(future, relations -> { + if (relations != null && relations.size() > 0) { + return new EdgeId(relations.get(0).getFrom().getId()); + } else { + return null; + } + }, ctx.getDbCallbackExecutor()); } @Override diff --git a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/filter/TbCheckMessageNode.java b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/filter/TbCheckMessageNode.java index 44175abac6..e9d54de5de 100644 --- a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/filter/TbCheckMessageNode.java +++ b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/filter/TbCheckMessageNode.java @@ -41,7 +41,7 @@ import java.util.Map; "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 True chain, otherwise, False chain is used. ", uiResources = {"static/rulenode/rulenode-core-config.js"}, configDirective = "tbFilterNodeCheckMessageConfig", - ruleChainTypes = {RuleChainType.SYSTEM, RuleChainType.EDGE} + ruleChainTypes = {RuleChainType.CORE, RuleChainType.EDGE} ) public class TbCheckMessageNode implements TbNode { diff --git a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/filter/TbCheckRelationNode.java b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/filter/TbCheckRelationNode.java index 01ac3db853..f5912d1e5b 100644 --- a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/filter/TbCheckRelationNode.java +++ b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/filter/TbCheckRelationNode.java @@ -53,7 +53,7 @@ import static org.thingsboard.common.util.DonAsynchron.withCallback; nodeDetails = "If at least one relation exists - send Message via True chain, otherwise False chain is used.", uiResources = {"static/rulenode/rulenode-core-config.js"}, configDirective = "tbFilterNodeCheckRelationConfig", - ruleChainTypes = {RuleChainType.SYSTEM, RuleChainType.EDGE} + ruleChainTypes = {RuleChainType.CORE, RuleChainType.EDGE} ) public class TbCheckRelationNode implements TbNode { diff --git a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/filter/TbJsFilterNode.java b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/filter/TbJsFilterNode.java index 3d1aa94b9b..997a872a4a 100644 --- a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/filter/TbJsFilterNode.java +++ b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/filter/TbJsFilterNode.java @@ -38,7 +38,7 @@ import static org.thingsboard.common.util.DonAsynchron.withCallback; "Message type can be accessed via msgType property.", uiResources = {"static/rulenode/rulenode-core-config.js"}, configDirective = "tbFilterNodeScriptConfig", - ruleChainTypes = {RuleChainType.SYSTEM, RuleChainType.EDGE} + ruleChainTypes = {RuleChainType.CORE, RuleChainType.EDGE} ) public class TbJsFilterNode implements TbNode { diff --git a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/filter/TbJsSwitchNode.java b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/filter/TbJsSwitchNode.java index 207c029a5d..fa8f332d69 100644 --- a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/filter/TbJsSwitchNode.java +++ b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/filter/TbJsSwitchNode.java @@ -41,7 +41,7 @@ import static org.thingsboard.common.util.DonAsynchron.withCallback; "Message type can be accessed via msgType property.", uiResources = {"static/rulenode/rulenode-core-config.js"}, configDirective = "tbFilterNodeSwitchConfig", - ruleChainTypes = {RuleChainType.SYSTEM, RuleChainType.EDGE} + ruleChainTypes = {RuleChainType.CORE, RuleChainType.EDGE} ) public class TbJsSwitchNode implements TbNode { diff --git a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/filter/TbMsgTypeFilterNode.java b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/filter/TbMsgTypeFilterNode.java index c11a75a313..f0dac68130 100644 --- a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/filter/TbMsgTypeFilterNode.java +++ b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/filter/TbMsgTypeFilterNode.java @@ -35,7 +35,7 @@ import org.thingsboard.server.common.msg.TbMsg; nodeDetails = "If incoming MessageType is expected - send Message via True chain, otherwise False chain is used.", uiResources = {"static/rulenode/rulenode-core-config.js", "static/rulenode/rulenode-core-config.css"}, configDirective = "tbFilterNodeMessageTypeConfig", - ruleChainTypes = {RuleChainType.SYSTEM, RuleChainType.EDGE} + ruleChainTypes = {RuleChainType.CORE, RuleChainType.EDGE} ) public class TbMsgTypeFilterNode implements TbNode { diff --git a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/filter/TbMsgTypeSwitchNode.java b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/filter/TbMsgTypeSwitchNode.java index bbb7b5a113..0973b49a97 100644 --- a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/filter/TbMsgTypeSwitchNode.java +++ b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/filter/TbMsgTypeSwitchNode.java @@ -36,7 +36,7 @@ import org.thingsboard.server.common.msg.session.SessionMsgType; nodeDetails = "Sends messages with message types \"Post attributes\", \"Post telemetry\", \"RPC Request\" etc. via corresponding chain, otherwise Other chain is used.", uiResources = {"static/rulenode/rulenode-core-config.js"}, configDirective = "tbNodeEmptyConfig", - ruleChainTypes = {RuleChainType.SYSTEM, RuleChainType.EDGE} + ruleChainTypes = {RuleChainType.CORE, RuleChainType.EDGE} ) public class TbMsgTypeSwitchNode implements TbNode { diff --git a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/filter/TbOriginatorTypeFilterNode.java b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/filter/TbOriginatorTypeFilterNode.java index 2ba96e1ed8..6687ae461e 100644 --- a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/filter/TbOriginatorTypeFilterNode.java +++ b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/filter/TbOriginatorTypeFilterNode.java @@ -33,7 +33,7 @@ import org.thingsboard.server.common.msg.TbMsg; nodeDetails = "If Originator Type of incoming message is expected - send Message via True chain, otherwise False chain is used.", uiResources = {"static/rulenode/rulenode-core-config.js", "static/rulenode/rulenode-core-config.css"}, configDirective = "tbFilterNodeOriginatorTypeConfig", - ruleChainTypes = {RuleChainType.SYSTEM, RuleChainType.EDGE} + ruleChainTypes = {RuleChainType.CORE, RuleChainType.EDGE} ) public class TbOriginatorTypeFilterNode implements TbNode { diff --git a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/filter/TbOriginatorTypeSwitchNode.java b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/filter/TbOriginatorTypeSwitchNode.java index efedadf9ee..9bd2109746 100644 --- a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/filter/TbOriginatorTypeSwitchNode.java +++ b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/filter/TbOriginatorTypeSwitchNode.java @@ -33,7 +33,7 @@ import org.thingsboard.server.common.msg.TbMsg; nodeDetails = "Routes messages to chain according to the originator type ('Device', 'Asset', etc.).", uiResources = {"static/rulenode/rulenode-core-config.js"}, configDirective = "tbNodeEmptyConfig", - ruleChainTypes = {RuleChainType.SYSTEM, RuleChainType.EDGE} + ruleChainTypes = {RuleChainType.CORE, RuleChainType.EDGE} ) public class TbOriginatorTypeSwitchNode implements TbNode { diff --git a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/gcp/pubsub/TbPubSubNode.java b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/gcp/pubsub/TbPubSubNode.java index 681fac3ef1..036bfbd762 100644 --- a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/gcp/pubsub/TbPubSubNode.java +++ b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/gcp/pubsub/TbPubSubNode.java @@ -51,7 +51,7 @@ import static org.thingsboard.common.util.DonAsynchron.withCallback; uiResources = {"static/rulenode/rulenode-core-config.js"}, configDirective = "tbActionNodePubSubConfig", iconUrl = "data:image/svg+xml;base64,PHN2ZyBpZD0iTGF5ZXJfMSIgZGF0YS1uYW1lPSJMYXllciAxIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMjgiIGhlaWdodD0iMTI4IiB2aWV3Qm94PSIwIDAgMTI4IDEyOCI+Cjx0aXRsZT5DbG91ZCBQdWJTdWI8L3RpdGxlPgo8Zz4KPHBhdGggZD0iTTEyNi40Nyw1OC4xMmwtMjYuMy00NS43NEExMS41NiwxMS41NiwwLDAsMCw5MC4zMSw2LjVIMzcuN2ExMS41NSwxMS41NSwwLDAsMC05Ljg2LDUuODhMMS41Myw1OGExMS40OCwxMS40OCwwLDAsMCwwLDExLjQ0bDI2LjMsNDZhMTEuNzcsMTEuNzcsMCwwLDAsOS44Niw2LjA5SDkwLjNhMTEuNzMsMTEuNzMsMCwwLDAsOS44Ny02LjA2bDI2LjMtNDUuNzRBMTEuNzMsMTEuNzMsMCwwLDAsMTI2LjQ3LDU4LjEyWiIgc3R5bGU9ImZpbGw6ICM3MzViMmYiLz4KPHBhdGggZD0iTTg5LjIyLDQ3Ljc0LDgzLjM2LDQ5bC0xNC42LTE0LjZMNjQuMDksNDMuMSw2MS41NSw1My4ybDQuMjksNC4yOUw1Ny42LDU5LjE4LDQ2LjMsNDcuODhsLTcuNjcsNy4zOEw1Mi43Niw2OS4zN2wtMTUsMTEuOUw3OCwxMjEuNUg5MC4zYTExLjczLDExLjczLDAsMCwwLDkuODctNi4wNmwyMC43Mi0zNloiIHN0eWxlPSJvcGFjaXR5OiAwLjA3MDAwMDAwMDI5ODAyMztpc29sYXRpb246IGlzb2xhdGUiLz4KPHBhdGggZD0iTTgyLjg2LDQ3YTUuMzIsNS4zMiwwLDEsMS0xLjk1LDcuMjdBNS4zMiw1LjMyLDAsMCwxLDgyLjg2LDQ3IiBzdHlsZT0iZmlsbDogI2ZmZiIvPgo8cGF0aCBkPSJNMzkuODIsNTYuMThhNS4zMiw1LjMyLDAsMSwxLDcuMjctMS45NSw1LjMyLDUuMzIsMCwwLDEtNy4yNywxLjk1IiBzdHlsZT0iZmlsbDogI2ZmZiIvPgo8cGF0aCBkPSJNNjkuMzIsODguODVBNS4zMiw1LjMyLDAsMSwxLDY0LDgzLjUyYTUuMzIsNS4zMiwwLDAsMSw1LjMyLDUuMzIiIHN0eWxlPSJmaWxsOiAjZmZmIi8+CjxnPgo8cGF0aCBkPSJNNjQsNTIuOTRhMTEuMDYsMTEuMDYsMCwwLDEsMi40Ni4yOFYzOS4xNUg2MS41NFY1My4yMkExMS4wNiwxMS4wNiwwLDAsMSw2NCw1Mi45NFoiIHN0eWxlPSJmaWxsOiAjZmZmIi8+CjxwYXRoIGQ9Ik03NC41Nyw2Ny4yNmExMSwxMSwwLDAsMS0yLjQ3LDQuMjVsMTIuMTksNywyLjQ2LTQuMjZaIiBzdHlsZT0iZmlsbDogI2ZmZiIvPgo8cGF0aCBkPSJNNTMuNDMsNjcuMjZsLTEyLjE4LDcsMi40Niw0LjI2LDEyLjE5LTdBMTEsMTEsMCwwLDEsNTMuNDMsNjcuMjZaIiBzdHlsZT0iZmlsbDogI2ZmZiIvPgo8L2c+CjxwYXRoIGQ9Ik03Mi42LDY0QTguNiw4LjYsMCwxLDEsNjQsNTUuNCw4LjYsOC42LDAsMCwxLDcyLjYsNjQiIHN0eWxlPSJmaWxsOiAjZmZmIi8+CjxwYXRoIGQ9Ik0zOS4xLDcwLjU3YTYuNzYsNi43NiwwLDEsMS0yLjQ3LDkuMjMsNi43Niw2Ljc2LDAsMCwxLDIuNDctOS4yMyIgc3R5bGU9ImZpbGw6ICNmZmYiLz4KPHBhdGggZD0iTTgyLjE0LDgyLjI3YTYuNzYsNi43NiwwLDEsMSw5LjIzLTIuNDcsNi43NSw2Ljc1LDAsMCwxLTkuMjMsMi40NyIgc3R5bGU9ImZpbGw6ICNmZmYiLz4KPHBhdGggZD0iTTcwLjc2LDM5LjE1QTYuNzYsNi43NiwwLDEsMSw2NCwzMi4zOWE2Ljc2LDYuNzYsMCwwLDEsNi43Niw2Ljc2IiBzdHlsZT0iZmlsbDogI2ZmZiIvPgo8L2c+Cjwvc3ZnPgo=", - ruleChainTypes = {RuleChainType.SYSTEM, RuleChainType.EDGE} + ruleChainTypes = {RuleChainType.CORE, RuleChainType.EDGE} ) public class TbPubSubNode implements TbNode { diff --git a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/geo/TbGpsGeofencingActionNode.java b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/geo/TbGpsGeofencingActionNode.java index 0a177cdce6..bb2e0bbca9 100644 --- a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/geo/TbGpsGeofencingActionNode.java +++ b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/geo/TbGpsGeofencingActionNode.java @@ -53,7 +53,7 @@ import java.util.concurrent.TimeoutException; nodeDetails = "Extracts latitude and longitude parameters from incoming message and returns different events based on configuration parameters", uiResources = {"static/rulenode/rulenode-core-config.js"}, configDirective = "tbActionNodeGpsGeofencingConfig", - ruleChainTypes = {RuleChainType.SYSTEM, RuleChainType.EDGE} + ruleChainTypes = {RuleChainType.CORE, RuleChainType.EDGE} ) public class TbGpsGeofencingActionNode extends AbstractGeofencingNode { diff --git a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/geo/TbGpsGeofencingFilterNode.java b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/geo/TbGpsGeofencingFilterNode.java index 260c630bd9..a40f416f92 100644 --- a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/geo/TbGpsGeofencingFilterNode.java +++ b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/geo/TbGpsGeofencingFilterNode.java @@ -54,7 +54,7 @@ import java.util.List; nodeDetails = "Extracts latitude and longitude parameters from incoming message and returns 'True' if they are inside configured perimeters, 'False' otherwise.", uiResources = {"static/rulenode/rulenode-core-config.js"}, configDirective = "tbFilterNodeGpsGeofencingConfig", - ruleChainTypes = {RuleChainType.SYSTEM, RuleChainType.EDGE} + ruleChainTypes = {RuleChainType.CORE, RuleChainType.EDGE} ) public class TbGpsGeofencingFilterNode extends AbstractGeofencingNode { diff --git a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/kafka/TbKafkaNode.java b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/kafka/TbKafkaNode.java index 485505e2d5..3504f7bd85 100644 --- a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/kafka/TbKafkaNode.java +++ b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/kafka/TbKafkaNode.java @@ -53,7 +53,7 @@ import java.util.Properties; uiResources = {"static/rulenode/rulenode-core-config.js"}, configDirective = "tbActionNodeKafkaConfig", iconUrl = "data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMTUzOCIgaGVpZ2h0PSIyNTAwIiB2aWV3Qm94PSIwIDAgMjU2IDQxNiIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiBwcmVzZXJ2ZUFzcGVjdFJhdGlvPSJ4TWlkWU1pZCI+PHBhdGggZD0iTTIwMS44MTYgMjMwLjIxNmMtMTYuMTg2IDAtMzAuNjk3IDcuMTcxLTQwLjYzNCAxOC40NjFsLTI1LjQ2My0xOC4wMjZjMi43MDMtNy40NDIgNC4yNTUtMTUuNDMzIDQuMjU1LTIzLjc5NyAwLTguMjE5LTEuNDk4LTE2LjA3Ni00LjExMi0yMy40MDhsMjUuNDA2LTE3LjgzNWM5LjkzNiAxMS4yMzMgMjQuNDA5IDE4LjM2NSA0MC41NDggMTguMzY1IDI5Ljg3NSAwIDU0LjE4NC0yNC4zMDUgNTQuMTg0LTU0LjE4NCAwLTI5Ljg3OS0yNC4zMDktNTQuMTg0LTU0LjE4NC01NC4xODQtMjkuODc1IDAtNTQuMTg0IDI0LjMwNS01NC4xODQgNTQuMTg0IDAgNS4zNDguODA4IDEwLjUwNSAyLjI1OCAxNS4zODlsLTI1LjQyMyAxNy44NDRjLTEwLjYyLTEzLjE3NS0yNS45MTEtMjIuMzc0LTQzLjMzMy0yNS4xODJ2LTMwLjY0YzI0LjU0NC01LjE1NSA0My4wMzctMjYuOTYyIDQzLjAzNy01My4wMTlDMTI0LjE3MSAyNC4zMDUgOTkuODYyIDAgNjkuOTg3IDAgNDAuMTEyIDAgMTUuODAzIDI0LjMwNSAxNS44MDMgNTQuMTg0YzAgMjUuNzA4IDE4LjAxNCA0Ny4yNDYgNDIuMDY3IDUyLjc2OXYzMS4wMzhDMjUuMDQ0IDE0My43NTMgMCAxNzIuNDAxIDAgMjA2Ljg1NGMwIDM0LjYyMSAyNS4yOTIgNjMuMzc0IDU4LjM1NSA2OC45NHYzMi43NzRjLTI0LjI5OSA1LjM0MS00Mi41NTIgMjcuMDExLTQyLjU1MiA1Mi44OTQgMCAyOS44NzkgMjQuMzA5IDU0LjE4NCA1NC4xODQgNTQuMTg0IDI5Ljg3NSAwIDU0LjE4NC0yNC4zMDUgNTQuMTg0LTU0LjE4NCAwLTI1Ljg4My0xOC4yNTMtNDcuNTUzLTQyLjU1Mi01Mi44OTR2LTMyLjc3NWE2OS45NjUgNjkuOTY1IDAgMCAwIDQyLjYtMjQuNzc2bDI1LjYzMyAxOC4xNDNjLTEuNDIzIDQuODQtMi4yMiA5Ljk0Ni0yLjIyIDE1LjI0IDAgMjkuODc5IDI0LjMwOSA1NC4xODQgNTQuMTg0IDU0LjE4NCAyOS44NzUgMCA1NC4xODQtMjQuMzA1IDU0LjE4NC01NC4xODQgMC0yOS44NzktMjQuMzA5LTU0LjE4NC01NC4xODQtNTQuMTg0em0wLTEyNi42OTVjMTQuNDg3IDAgMjYuMjcgMTEuNzg4IDI2LjI3IDI2LjI3MXMtMTEuNzgzIDI2LjI3LTI2LjI3IDI2LjI3LTI2LjI3LTExLjc4Ny0yNi4yNy0yNi4yN2MwLTE0LjQ4MyAxMS43ODMtMjYuMjcxIDI2LjI3LTI2LjI3MXptLTE1OC4xLTQ5LjMzN2MwLTE0LjQ4MyAxMS43ODQtMjYuMjcgMjYuMjcxLTI2LjI3czI2LjI3IDExLjc4NyAyNi4yNyAyNi4yN2MwIDE0LjQ4My0xMS43ODMgMjYuMjctMjYuMjcgMjYuMjdzLTI2LjI3MS0xMS43ODctMjYuMjcxLTI2LjI3em01Mi41NDEgMzA3LjI3OGMwIDE0LjQ4My0xMS43ODMgMjYuMjctMjYuMjcgMjYuMjdzLTI2LjI3MS0xMS43ODctMjYuMjcxLTI2LjI3YzAtMTQuNDgzIDExLjc4NC0yNi4yNyAyNi4yNzEtMjYuMjdzMjYuMjcgMTEuNzg3IDI2LjI3IDI2LjI3em0tMjYuMjcyLTExNy45N2MtMjAuMjA1IDAtMzYuNjQyLTE2LjQzNC0zNi42NDItMzYuNjM4IDAtMjAuMjA1IDE2LjQzNy0zNi42NDIgMzYuNjQyLTM2LjY0MiAyMC4yMDQgMCAzNi42NDEgMTYuNDM3IDM2LjY0MSAzNi42NDIgMCAyMC4yMDQtMTYuNDM3IDM2LjYzOC0zNi42NDEgMzYuNjM4em0xMzEuODMxIDY3LjE3OWMtMTQuNDg3IDAtMjYuMjctMTEuNzg4LTI2LjI3LTI2LjI3MXMxMS43ODMtMjYuMjcgMjYuMjctMjYuMjcgMjYuMjcgMTEuNzg3IDI2LjI3IDI2LjI3YzAgMTQuNDgzLTExLjc4MyAyNi4yNzEtMjYuMjcgMjYuMjcxeiIvPjwvc3ZnPg==", - ruleChainTypes = {RuleChainType.SYSTEM, RuleChainType.EDGE} + ruleChainTypes = {RuleChainType.CORE, RuleChainType.EDGE} ) public class TbKafkaNode implements TbNode { diff --git a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/mail/TbMsgToEmailNode.java b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/mail/TbMsgToEmailNode.java index 2133314e61..1a4fb244b3 100644 --- a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/mail/TbMsgToEmailNode.java +++ b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/mail/TbMsgToEmailNode.java @@ -42,7 +42,7 @@ import static org.thingsboard.rule.engine.mail.TbSendEmailNode.SEND_EMAIL_TYPE; uiResources = {"static/rulenode/rulenode-core-config.js"}, configDirective = "tbTransformationNodeToEmailConfig", icon = "email", - ruleChainTypes = {RuleChainType.SYSTEM, RuleChainType.EDGE} + ruleChainTypes = {RuleChainType.CORE, RuleChainType.EDGE} ) public class TbMsgToEmailNode implements TbNode { diff --git a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/mail/TbSendEmailNode.java b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/mail/TbSendEmailNode.java index 237a56a36c..043b5008c4 100644 --- a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/mail/TbSendEmailNode.java +++ b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/mail/TbSendEmailNode.java @@ -48,7 +48,7 @@ import static org.thingsboard.common.util.DonAsynchron.withCallback; uiResources = {"static/rulenode/rulenode-core-config.js"}, configDirective = "tbActionNodeSendEmailConfig", icon = "send", - ruleChainTypes = {RuleChainType.SYSTEM, RuleChainType.EDGE} + ruleChainTypes = {RuleChainType.CORE, RuleChainType.EDGE} ) public class TbSendEmailNode implements TbNode { diff --git a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetAttributesNode.java b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetAttributesNode.java index cbe0054864..92aca60332 100644 --- a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetAttributesNode.java +++ b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetAttributesNode.java @@ -42,7 +42,7 @@ import org.thingsboard.server.common.msg.TbMsg; "metadata.cs_temperature or metadata.shared_limit ", uiResources = {"static/rulenode/rulenode-core-config.js"}, configDirective = "tbEnrichmentNodeOriginatorAttributesConfig", - ruleChainTypes = {RuleChainType.SYSTEM, RuleChainType.EDGE} + ruleChainTypes = {RuleChainType.CORE, RuleChainType.EDGE} ) public class TbGetAttributesNode extends TbAbstractGetAttributesNode { diff --git a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetCustomerAttributeNode.java b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetCustomerAttributeNode.java index 25979097ac..1b0e0b7efb 100644 --- a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetCustomerAttributeNode.java +++ b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetCustomerAttributeNode.java @@ -35,7 +35,7 @@ import org.thingsboard.server.common.data.rule.RuleChainType; "metadata.temperature.", uiResources = {"static/rulenode/rulenode-core-config.js", "static/rulenode/rulenode-core-config.css"}, configDirective = "tbEnrichmentNodeCustomerAttributesConfig", - ruleChainTypes = {RuleChainType.SYSTEM, RuleChainType.EDGE} + ruleChainTypes = {RuleChainType.CORE, RuleChainType.EDGE} ) public class TbGetCustomerAttributeNode extends TbEntityGetAttrNode { diff --git a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetCustomerDetailsNode.java b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetCustomerDetailsNode.java index 84d94eb614..93a03498d7 100644 --- a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetCustomerDetailsNode.java +++ b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetCustomerDetailsNode.java @@ -44,7 +44,7 @@ import org.thingsboard.server.common.msg.TbMsg; "If the originator of the message is not assigned to Customer, or originator type is not supported - Message will be forwarded to Failure chain, otherwise, Success chain will be used.", uiResources = {"static/rulenode/rulenode-core-config.js"}, configDirective = "tbEnrichmentNodeEntityDetailsConfig", - ruleChainTypes = {RuleChainType.SYSTEM, RuleChainType.EDGE} + ruleChainTypes = {RuleChainType.CORE, RuleChainType.EDGE} ) public class TbGetCustomerDetailsNode extends TbAbstractGetEntityDetailsNode { diff --git a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetDeviceAttrNode.java b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetDeviceAttrNode.java index 48649aab58..af6cbf9265 100644 --- a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetDeviceAttrNode.java +++ b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetDeviceAttrNode.java @@ -40,7 +40,7 @@ import org.thingsboard.server.common.msg.TbMsg; "metadata.cs_temperature or metadata.shared_limit ", uiResources = {"static/rulenode/rulenode-core-config.js"}, configDirective = "tbEnrichmentNodeDeviceAttributesConfig", - ruleChainTypes = {RuleChainType.SYSTEM, RuleChainType.EDGE} + ruleChainTypes = {RuleChainType.CORE, RuleChainType.EDGE} ) public class TbGetDeviceAttrNode extends TbAbstractGetAttributesNode { diff --git a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetOriginatorFieldsNode.java b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetOriginatorFieldsNode.java index 6885b1362d..6f240d2df6 100644 --- a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetOriginatorFieldsNode.java +++ b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetOriginatorFieldsNode.java @@ -45,7 +45,7 @@ import static org.thingsboard.rule.engine.api.TbRelationTypes.SUCCESS; nodeDetails = "Will fetch fields values specified in mapping. If specified field is not part of originator fields it will be ignored.", uiResources = {"static/rulenode/rulenode-core-config.js"}, configDirective = "tbEnrichmentNodeOriginatorFieldsConfig", - ruleChainTypes = {RuleChainType.SYSTEM, RuleChainType.EDGE} + ruleChainTypes = {RuleChainType.CORE, RuleChainType.EDGE} ) public class TbGetOriginatorFieldsNode implements TbNode { diff --git a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetRelatedAttributeNode.java b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetRelatedAttributeNode.java index 0d2dc5c82a..44cf94163e 100644 --- a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetRelatedAttributeNode.java +++ b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetRelatedAttributeNode.java @@ -37,7 +37,7 @@ import org.thingsboard.server.common.data.rule.RuleChainType; "metadata.temperature.", uiResources = {"static/rulenode/rulenode-core-config.js", "static/rulenode/rulenode-core-config.css"}, configDirective = "tbEnrichmentNodeRelatedAttributesConfig", - ruleChainTypes = {RuleChainType.SYSTEM, RuleChainType.EDGE} + ruleChainTypes = {RuleChainType.CORE, RuleChainType.EDGE} ) public class TbGetRelatedAttributeNode extends TbEntityGetAttrNode { diff --git a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetTelemetryNode.java b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetTelemetryNode.java index a438208bcb..009870e404 100644 --- a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetTelemetryNode.java +++ b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetTelemetryNode.java @@ -68,7 +68,7 @@ import static org.thingsboard.server.common.data.kv.Aggregation.NONE; "Note: The maximum size of the fetched array is 1000 records.\n ", uiResources = {"static/rulenode/rulenode-core-config.js"}, configDirective = "tbEnrichmentNodeGetTelemetryFromDatabase", - ruleChainTypes = {RuleChainType.SYSTEM, RuleChainType.EDGE} + ruleChainTypes = {RuleChainType.CORE, RuleChainType.EDGE} ) public class TbGetTelemetryNode implements TbNode { diff --git a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetTenantAttributeNode.java b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetTenantAttributeNode.java index 659217eaa2..1d31a6bc0d 100644 --- a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetTenantAttributeNode.java +++ b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetTenantAttributeNode.java @@ -37,7 +37,7 @@ import org.thingsboard.server.common.data.rule.RuleChainType; "metadata.temperature.", uiResources = {"static/rulenode/rulenode-core-config.js", "static/rulenode/rulenode-core-config.css"}, configDirective = "tbEnrichmentNodeTenantAttributesConfig", - ruleChainTypes = {RuleChainType.SYSTEM, RuleChainType.EDGE} + ruleChainTypes = {RuleChainType.CORE, RuleChainType.EDGE} ) public class TbGetTenantAttributeNode extends TbEntityGetAttrNode { diff --git a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetTenantDetailsNode.java b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetTenantDetailsNode.java index 434200228f..cf4bcaf064 100644 --- a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetTenantDetailsNode.java +++ b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetTenantDetailsNode.java @@ -39,7 +39,7 @@ import org.thingsboard.server.common.msg.TbMsg; "If the originator of the message is not assigned to Tenant, or originator type is not supported - Message will be forwarded to Failure chain, otherwise, Success chain will be used.", uiResources = {"static/rulenode/rulenode-core-config.js"}, configDirective = "tbEnrichmentNodeEntityDetailsConfig", - ruleChainTypes = {RuleChainType.SYSTEM, RuleChainType.EDGE} + ruleChainTypes = {RuleChainType.CORE, RuleChainType.EDGE} ) public class TbGetTenantDetailsNode extends TbAbstractGetEntityDetailsNode { diff --git a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/mqtt/TbMqttNode.java b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/mqtt/TbMqttNode.java index 4badd94bc1..b7d76f8968 100644 --- a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/mqtt/TbMqttNode.java +++ b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/mqtt/TbMqttNode.java @@ -51,7 +51,7 @@ import java.util.concurrent.TimeoutException; uiResources = {"static/rulenode/rulenode-core-config.js", "static/rulenode/rulenode-core-config.css"}, configDirective = "tbActionNodeMqttConfig", icon = "call_split", - ruleChainTypes = {RuleChainType.SYSTEM, RuleChainType.EDGE} + ruleChainTypes = {RuleChainType.CORE, RuleChainType.EDGE} ) public class TbMqttNode implements TbNode { diff --git a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/rabbitmq/TbRabbitMqNode.java b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/rabbitmq/TbRabbitMqNode.java index 7756dd71c4..78ac75a642 100644 --- a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/rabbitmq/TbRabbitMqNode.java +++ b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/rabbitmq/TbRabbitMqNode.java @@ -41,7 +41,7 @@ import static org.thingsboard.common.util.DonAsynchron.withCallback; uiResources = {"static/rulenode/rulenode-core-config.js"}, configDirective = "tbActionNodeRabbitMqConfig", iconUrl = "data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHhtbDpzcGFjZT0icHJlc2VydmUiIHZlcnNpb249IjEuMSIgeT0iMHB4IiB4PSIwcHgiIHZpZXdCb3g9IjAgMCAxMDAwIDEwMDAiPjxwYXRoIHN0cm9rZS13aWR0aD0iLjg0OTU2IiBkPSJtODYwLjQ3IDQxNi4zMmgtMjYyLjAxYy0xMi45MTMgMC0yMy42MTgtMTAuNzA0LTIzLjYxOC0yMy42MTh2LTI3Mi43MWMwLTIwLjMwNS0xNi4yMjctMzYuMjc2LTM2LjI3Ni0zNi4yNzZoLTkzLjc5MmMtMjAuMzA1IDAtMzYuMjc2IDE2LjIyNy0zNi4yNzYgMzYuMjc2djI3MC44NGMtMC4yNTQ4NyAxNC4xMDMtMTEuNDY5IDI1LjU3Mi0yNS43NDIgMjUuNTcybC04NS42MzYgMC42Nzk2NWMtMTQuMTAzIDAtMjUuNTcyLTExLjQ2OS0yNS41NzItMjUuNTcybDAuNjc5NjUtMjcxLjUyYzAtMjAuMzA1LTE2LjIyNy0zNi4yNzYtMzYuMjc2LTM2LjI3NmgtOTMuNTM3Yy0yMC4zMDUgMC0zNi4yNzYgMTYuMjI3LTM2LjI3NiAzNi4yNzZ2NzYzLjg0YzAgMTguMDk2IDE0Ljc4MiAzMi40NTMgMzIuNDUzIDMyLjQ1M2g3MjIuODFjMTguMDk2IDAgMzIuNDUzLTE0Ljc4MiAzMi40NTMtMzIuNDUzdi00MzUuMzFjLTEuMTg5NC0xOC4xODEtMTUuMjkyLTMyLjE5OC0zMy4zODgtMzIuMTk4em0tMTIyLjY4IDI4Ny4wN2MwIDIzLjYxOC0xOC44NiA0Mi40NzgtNDIuNDc4IDQyLjQ3OGgtNzMuOTk3Yy0yMy42MTggMC00Mi40NzgtMTguODYtNDIuNDc4LTQyLjQ3OHYtNzQuMjUyYzAtMjMuNjE4IDE4Ljg2LTQyLjQ3OCA0Mi40NzgtNDIuNDc4aDczLjk5N2MyMy42MTggMCA0Mi40NzggMTguODYgNDIuNDc4IDQyLjQ3OHoiLz48L3N2Zz4=", - ruleChainTypes = {RuleChainType.SYSTEM, RuleChainType.EDGE} + ruleChainTypes = {RuleChainType.CORE, RuleChainType.EDGE} ) public class TbRabbitMqNode implements TbNode { diff --git a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/rest/TbRestApiCallNode.java b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/rest/TbRestApiCallNode.java index 930d145259..0ee938f7b7 100644 --- a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/rest/TbRestApiCallNode.java +++ b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/rest/TbRestApiCallNode.java @@ -41,7 +41,7 @@ import org.thingsboard.server.common.msg.TbMsg; uiResources = {"static/rulenode/rulenode-core-config.js"}, configDirective = "tbActionNodeRestApiCallConfig", iconUrl = "data:image/svg+xml;base64,PHN2ZyBzdHlsZT0iZW5hYmxlLWJhY2tncm91bmQ6bmV3IDAgMCA1MTIgNTEyIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHhtbDpzcGFjZT0icHJlc2VydmUiIHZpZXdCb3g9IjAgMCA1MTIgNTEyIiB2ZXJzaW9uPSIxLjEiIHk9IjBweCIgeD0iMHB4Ij48ZyB0cmFuc2Zvcm09Im1hdHJpeCguOTQ5NzUgMCAwIC45NDk3NSAxNy4xMiAyNi40OTIpIj48cGF0aCBkPSJtMTY5LjExIDEwOC41NGMtOS45MDY2IDAuMDczNC0xOS4wMTQgNi41NzI0LTIyLjAxNCAxNi40NjlsLTY5Ljk5MyAyMzEuMDhjLTMuNjkwNCAxMi4xODEgMy4yODkyIDI1LjIyIDE1LjQ2OSAyOC45MSAyLjIyNTkgMC42NzQ4MSA0LjQ5NjkgMSA2LjcyODUgMSA5Ljk3MjEgMCAxOS4xNjUtNi41MTUzIDIyLjE4Mi0xNi40NjdhNi41MjI0IDYuNTIyNCAwIDAgMCAwLjAwMiAtMC4wMDJsNjkuOTktMjMxLjA3YTYuNTIyNCA2LjUyMjQgMCAwIDAgMCAtMC4wMDJjMy42ODU1LTEyLjE4MS0zLjI4Ny0yNS4yMjUtMTUuNDcxLTI4LjkxMi0yLjI4MjUtMC42OTE0NS00LjYxMTYtMS4wMTY5LTYuODk4NC0xem04NC45ODggMGMtOS45MDQ4IDAuMDczNC0xOS4wMTggNi41Njc1LTIyLjAxOCAxNi40NjlsLTY5Ljk4NiAyMzEuMDhjLTMuNjg5OCAxMi4xNzkgMy4yODUzIDI1LjIxNyAxNS40NjUgMjguOTA4IDIuMjI5NyAwLjY3NjQ3IDQuNTAwOCAxLjAwMiA2LjczMjQgMS4wMDIgOS45NzIxIDAgMTkuMTY1LTYuNTE1MyAyMi4xODItMTYuNDY3YTYuNTIyNCA2LjUyMjQgMCAwIDAgMC4wMDIgLTAuMDAybDY5Ljk4OC0yMzEuMDdjMy42OTA4LTEyLjE4MS0zLjI4NTItMjUuMjIzLTE1LjQ2Ny0yOC45MTItMi4yODE0LTAuNjkyMzEtNC42MTA4LTEuMDE4OS02Ljg5ODQtMS4wMDJ6bS0yMTcuMjkgNDIuMjNjLTEyLjcyOS0wLjAwMDg3LTIzLjE4OCAxMC40NTYtMjMuMTg4IDIzLjE4NiAwLjAwMSAxMi43MjggMTAuNDU5IDIzLjE4NiAyMy4xODggMjMuMTg2IDEyLjcyNy0wLjAwMSAyMy4xODMtMTAuNDU5IDIzLjE4NC0yMy4xODYgMC4wMDA4NzYtMTIuNzI4LTEwLjQ1Ni0yMy4xODUtMjMuMTg0LTIzLjE4NnptMCAxNDYuNjRjLTEyLjcyNy0wLjAwMDg3LTIzLjE4NiAxMC40NTUtMjMuMTg4IDIzLjE4NC0wLjAwMDg3MyAxMi43MjkgMTAuNDU4IDIzLjE4OCAyMy4xODggMjMuMTg4IDEyLjcyOC0wLjAwMSAyMy4xODQtMTAuNDYgMjMuMTg0LTIzLjE4OC0wLjAwMS0xMi43MjYtMTAuNDU3LTIzLjE4My0yMy4xODQtMjMuMTg0em0yNzAuNzkgNDIuMjExYy0xMi43MjcgMC0yMy4xODQgMTAuNDU3LTIzLjE4NCAyMy4xODRzMTAuNDU1IDIzLjE4OCAyMy4xODQgMjMuMTg4aDE1NC45OGMxMi43MjkgMCAyMy4xODYtMTAuNDYgMjMuMTg2LTIzLjE4OCAwLjAwMS0xMi43MjgtMTAuNDU4LTIzLjE4NC0yMy4xODYtMjMuMTg0eiIgdHJhbnNmb3JtPSJtYXRyaXgoMS4wMzc2IDAgMCAxLjAzNzYgLTcuNTY3NiAtMTQuOTI1KSIgc3Ryb2tlLXdpZHRoPSIxLjI2OTMiLz48L2c+PC9zdmc+", - ruleChainTypes = {RuleChainType.SYSTEM, RuleChainType.EDGE} + ruleChainTypes = {RuleChainType.CORE, RuleChainType.EDGE} ) public class TbRestApiCallNode implements TbNode { diff --git a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/rpc/TbSendRPCReplyNode.java b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/rpc/TbSendRPCReplyNode.java index 4ab84d935f..2fc84e1c32 100644 --- a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/rpc/TbSendRPCReplyNode.java +++ b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/rpc/TbSendRPCReplyNode.java @@ -41,7 +41,7 @@ import java.util.UUID; uiResources = {"static/rulenode/rulenode-core-config.js"}, configDirective = "tbActionNodeRpcReplyConfig", icon = "call_merge", - ruleChainTypes = {RuleChainType.SYSTEM, RuleChainType.EDGE} + ruleChainTypes = {RuleChainType.CORE, RuleChainType.EDGE} ) public class TbSendRPCReplyNode implements TbNode { diff --git a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/rpc/TbSendRPCRequestNode.java b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/rpc/TbSendRPCRequestNode.java index a192596614..6e04afd123 100644 --- a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/rpc/TbSendRPCRequestNode.java +++ b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/rpc/TbSendRPCRequestNode.java @@ -52,7 +52,7 @@ import java.util.concurrent.TimeUnit; uiResources = {"static/rulenode/rulenode-core-config.js"}, configDirective = "tbActionNodeRpcRequestConfig", icon = "call_made", - ruleChainTypes = {RuleChainType.SYSTEM, RuleChainType.EDGE} + ruleChainTypes = {RuleChainType.CORE, RuleChainType.EDGE} ) public class TbSendRPCRequestNode implements TbNode { diff --git a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/telemetry/TbMsgAttributesNode.java b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/telemetry/TbMsgAttributesNode.java index 9f70677453..cb536714e7 100644 --- a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/telemetry/TbMsgAttributesNode.java +++ b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/telemetry/TbMsgAttributesNode.java @@ -46,7 +46,7 @@ import java.util.Set; uiResources = {"static/rulenode/rulenode-core-config.js", "static/rulenode/rulenode-core-config.css"}, configDirective = "tbActionNodeAttributesConfig", icon = "file_upload", - ruleChainTypes = {RuleChainType.SYSTEM, RuleChainType.EDGE} + ruleChainTypes = {RuleChainType.CORE, RuleChainType.EDGE} ) public class TbMsgAttributesNode implements TbNode { diff --git a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/telemetry/TbMsgTimeseriesNode.java b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/telemetry/TbMsgTimeseriesNode.java index cb0cf8a4e2..24ba417b89 100644 --- a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/telemetry/TbMsgTimeseriesNode.java +++ b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/telemetry/TbMsgTimeseriesNode.java @@ -47,7 +47,7 @@ import java.util.Map; uiResources = {"static/rulenode/rulenode-core-config.js", "static/rulenode/rulenode-core-config.css"}, configDirective = "tbActionNodeTimeseriesConfig", icon = "file_upload", - ruleChainTypes = {RuleChainType.SYSTEM, RuleChainType.EDGE} + ruleChainTypes = {RuleChainType.CORE, RuleChainType.EDGE} ) public class TbMsgTimeseriesNode implements TbNode { diff --git a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/transaction/TbSynchronizationBeginNode.java b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/transaction/TbSynchronizationBeginNode.java index eabff52f8f..c66cbc1652 100644 --- a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/transaction/TbSynchronizationBeginNode.java +++ b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/transaction/TbSynchronizationBeginNode.java @@ -40,7 +40,7 @@ import static org.thingsboard.rule.engine.api.TbRelationTypes.SUCCESS; "Size of the queue per originator and timeout values are configurable on a system level", uiResources = {"static/rulenode/rulenode-core-config.js"}, configDirective = "tbNodeEmptyConfig", - ruleChainTypes = {RuleChainType.SYSTEM, RuleChainType.EDGE} + ruleChainTypes = {RuleChainType.CORE, RuleChainType.EDGE} ) @Deprecated public class TbSynchronizationBeginNode implements TbNode { diff --git a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/transaction/TbSynchronizationEndNode.java b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/transaction/TbSynchronizationEndNode.java index 5febcf2276..83d221285a 100644 --- a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/transaction/TbSynchronizationEndNode.java +++ b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/transaction/TbSynchronizationEndNode.java @@ -40,7 +40,7 @@ import static org.thingsboard.rule.engine.api.TbRelationTypes.SUCCESS; nodeDetails = "", uiResources = {"static/rulenode/rulenode-core-config.js"}, configDirective = ("tbNodeEmptyConfig"), - ruleChainTypes = {RuleChainType.SYSTEM, RuleChainType.EDGE} + ruleChainTypes = {RuleChainType.CORE, RuleChainType.EDGE} ) @Deprecated public class TbSynchronizationEndNode implements TbNode { diff --git a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/transform/TbChangeOriginatorNode.java b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/transform/TbChangeOriginatorNode.java index 9ff11922d3..0a0de55a46 100644 --- a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/transform/TbChangeOriginatorNode.java +++ b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/transform/TbChangeOriginatorNode.java @@ -48,7 +48,7 @@ import java.util.HashSet; uiResources = {"static/rulenode/rulenode-core-config.js", "static/rulenode/rulenode-core-config.css"}, configDirective = "tbTransformationNodeChangeOriginatorConfig", icon = "find_replace", - ruleChainTypes = {RuleChainType.SYSTEM, RuleChainType.EDGE} + ruleChainTypes = {RuleChainType.CORE, RuleChainType.EDGE} ) public class TbChangeOriginatorNode extends TbAbstractTransformNode { diff --git a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/transform/TbTransformMsgNode.java b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/transform/TbTransformMsgNode.java index 4d8dcef644..434a5ce61a 100644 --- a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/transform/TbTransformMsgNode.java +++ b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/transform/TbTransformMsgNode.java @@ -39,7 +39,7 @@ import static org.thingsboard.rule.engine.api.TbRelationTypes.SUCCESS; "All fields in resulting object are optional and will be taken from original message if not specified.", uiResources = {"static/rulenode/rulenode-core-config.js", "static/rulenode/rulenode-core-config.css"}, configDirective = "tbTransformationNodeScriptConfig", - ruleChainTypes = {RuleChainType.SYSTEM, RuleChainType.EDGE} + ruleChainTypes = {RuleChainType.CORE, RuleChainType.EDGE} ) public class TbTransformMsgNode extends TbAbstractTransformNode { diff --git a/ui/src/app/common/types.constant.js b/ui/src/app/common/types.constant.js index a877f1d3b2..a4036362c9 100644 --- a/ui/src/app/common/types.constant.js +++ b/ui/src/app/common/types.constant.js @@ -744,7 +744,7 @@ export default angular.module('thingsboard.types', []) clientSide: false } }, - systemRuleChainType: "SYSTEM", + coreRuleChainType: "CORE", edgeRuleChainType: "EDGE", ruleNodeTypeComponentTypes: ["FILTER", "ENRICHMENT", "TRANSFORMATION", "ACTION", "EXTERNAL"], ruleChainNodeComponent: { diff --git a/ui/src/app/locale/locale.constant-de_DE.json b/ui/src/app/locale/locale.constant-de_DE.json index 5e69ab6758..62f0bc5156 100644 --- a/ui/src/app/locale/locale.constant-de_DE.json +++ b/ui/src/app/locale/locale.constant-de_DE.json @@ -1351,7 +1351,7 @@ "rulechain": { "rulechain": "Regelkette", "rulechains": "Regelketten", - "system-rulechains": "Systemeregelketten", + "core-rulechains": "Kernregelketten", "edge-rulechains": "Randregelketten", "root": "Wurzel", "delete": "Regelkette löschen", diff --git a/ui/src/app/locale/locale.constant-en_US.json b/ui/src/app/locale/locale.constant-en_US.json index 32960b16ab..d6b186c42e 100644 --- a/ui/src/app/locale/locale.constant-en_US.json +++ b/ui/src/app/locale/locale.constant-en_US.json @@ -1533,7 +1533,7 @@ "rulechain": { "rulechain": "Rule chain", "rulechains": "Rule chains", - "system-rulechains": "System Rule chains", + "core-rulechains": "Core Rule chains", "edge-rulechains": "Edge Rule chains", "root": "Root", "delete": "Delete rule chain", diff --git a/ui/src/app/locale/locale.constant-es_ES.json b/ui/src/app/locale/locale.constant-es_ES.json index 31083093dc..75fed86ed1 100644 --- a/ui/src/app/locale/locale.constant-es_ES.json +++ b/ui/src/app/locale/locale.constant-es_ES.json @@ -1410,7 +1410,7 @@ "rulechain": { "rulechain": "Cadena de reglas", "rulechains": "Cadenas de reglas", - "system-rulechains": "Cadenas de reglas del sistema", + "core-rulechains": "Cadenas de reglas centrales", "edge-rulechains": "Cadenas de reglas de borde", "root": "Raíz", "delete": "Eliminar cadena de reglas", diff --git a/ui/src/app/locale/locale.constant-fr_FR.json b/ui/src/app/locale/locale.constant-fr_FR.json index fd25adced3..0a0e385350 100644 --- a/ui/src/app/locale/locale.constant-fr_FR.json +++ b/ui/src/app/locale/locale.constant-fr_FR.json @@ -1429,7 +1429,7 @@ "rulechain-required": "Chaîne de règles requise", "rulechains": "Chaînes de règles", "select-rulechain": "Sélectionner la chaîne de règles", - "system-rulechains": "Chaînes de règles du système", + "core-rulechains": "Chaînes de règles fondamentales", "edge-rulechains": "Chaînes de règles de la bordure", "set-root": "Rend la chaîne de règles racine (root) ", "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.", diff --git a/ui/src/app/rulechain/rulechain.controller.js b/ui/src/app/rulechain/rulechain.controller.js index edeefb18e4..292c3f71c1 100644 --- a/ui/src/app/rulechain/rulechain.controller.js +++ b/ui/src/app/rulechain/rulechain.controller.js @@ -1270,7 +1270,7 @@ export function RuleChainController($state, $scope, $compile, $q, $mdUtil, $time vm.isImport = false; $mdUtil.nextTick(() => { if (vm.ruleChain.type === vm.types.systemRuleChainType) { - $state.go('home.ruleChains.system.ruleChain', {ruleChainId: vm.ruleChain.id.id}); + $state.go('home.ruleChains.core.ruleChain', {ruleChainId: vm.ruleChain.id.id}); } else { $state.go('home.ruleChains.edge.ruleChain', {ruleChainId: vm.ruleChain.id.id}); } diff --git a/ui/src/app/rulechain/rulechain.routes.js b/ui/src/app/rulechain/rulechain.routes.js index 8f12031873..2991000e58 100644 --- a/ui/src/app/rulechain/rulechain.routes.js +++ b/ui/src/app/rulechain/rulechain.routes.js @@ -31,12 +31,12 @@ export default function RuleChainRoutes($stateProvider, NodeTemplatePathProvider url: '/ruleChains', module: 'private', auth: ['SYS_ADMIN', 'TENANT_ADMIN'], - redirectTo: 'home.ruleChains.system', + redirectTo: 'home.ruleChains.core', ncyBreadcrumb: { label: '{"icon": "settings_ethernet", "label": "rulechain.rulechains"}' } }) - .state('home.ruleChains.system', { + .state('home.ruleChains.core', { url: '/ruleChains/system', params: {'topIndex': 0}, module: 'private', @@ -50,13 +50,13 @@ export default function RuleChainRoutes($stateProvider, NodeTemplatePathProvider }, data: { searchEnabled: true, - pageTitle: 'rulechain.system-rulechains', + pageTitle: 'rulechain.core-rulechains', ruleChainsType: 'tenant' }, ncyBreadcrumb: { - label: '{"icon": "settings_ethernet", "label": "rulechain.system-rulechains"}' + label: '{"icon": "settings_ethernet", "label": "rulechain.core-rulechains"}' } - }).state('home.ruleChains.system.ruleChain', { + }).state('home.ruleChains.core.ruleChain', { url: '/:ruleChainId', reloadOnSearch: false, module: 'private', diff --git a/ui/src/app/rulechain/rulechains.controller.js b/ui/src/app/rulechain/rulechains.controller.js index 0261af3301..aba5c3bb2a 100644 --- a/ui/src/app/rulechain/rulechains.controller.js +++ b/ui/src/app/rulechain/rulechains.controller.js @@ -401,7 +401,7 @@ export default function RuleChainsController(ruleChainService, userService, edge } else if (vm.ruleChainsScope === 'edges') { $state.go('home.ruleChains.edge.ruleChain', {ruleChainId: ruleChain.id.id}); } else { - $state.go('home.ruleChains.system.ruleChain', {ruleChainId: ruleChain.id.id}); + $state.go('home.ruleChains.core.ruleChain', {ruleChainId: ruleChain.id.id}); } } diff --git a/ui/src/app/services/menu.service.js b/ui/src/app/services/menu.service.js index d8e975a226..0f53b54158 100644 --- a/ui/src/app/services/menu.service.js +++ b/ui/src/app/services/menu.service.js @@ -162,9 +162,9 @@ function Menu(userService, $state, $rootScope) { icon: 'settings_ethernet', pages: [ { - name: 'rulechain.system-rulechains', + name: 'rulechain.core-rulechains', type: 'link', - state: 'home.ruleChains.system', + state: 'home.ruleChains.core', icon: 'settings_ethernet' }, { @@ -229,9 +229,9 @@ function Menu(userService, $state, $rootScope) { name: 'rulechain.management', places: [ { - name: 'rulechain.system-rulechains', + name: 'rulechain.core-rulechains', icon: 'settings_ethernet', - state: 'home.ruleChains.system' + state: 'home.ruleChains.core' }, { name: 'rulechain.edge-rulechains',