Browse Source

Added cassandra edge dao. Tests fixed

pull/2436/head
Volodymyr Babak 6 years ago
parent
commit
4bb56df51a
  1. 1
      application/src/main/data/json/demo/rule_chains/root_rule_chain.json
  2. 34
      application/src/main/data/upgrade/2.6.0/schema_update.cql
  3. 16
      application/src/main/data/upgrade/2.6.0/schema_update.sql
  4. 15
      application/src/main/java/org/thingsboard/server/controller/BaseController.java
  5. 2
      application/src/main/java/org/thingsboard/server/controller/DashboardController.java
  6. 9
      application/src/main/java/org/thingsboard/server/service/edge/DefaultEdgeNotificationService.java
  7. 26
      application/src/main/java/org/thingsboard/server/service/edge/rpc/EdgeGrpcSession.java
  8. 6
      application/src/main/java/org/thingsboard/server/service/edge/rpc/init/DefaultSyncEdgeService.java
  9. 6
      application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/BaseProcessor.java
  10. 6
      application/src/main/java/org/thingsboard/server/service/rpc/TbRuleEngineDeviceRpcService.java
  11. 1
      application/src/main/resources/logback.xml
  12. 1
      application/src/main/resources/thingsboard.yml
  13. 14
      application/src/test/java/org/thingsboard/server/controller/AbstractControllerTest.java
  14. 28
      application/src/test/java/org/thingsboard/server/controller/BaseAssetControllerTest.java
  15. 56
      application/src/test/java/org/thingsboard/server/controller/BaseDashboardControllerTest.java
  16. 29
      application/src/test/java/org/thingsboard/server/controller/BaseDeviceControllerTest.java
  17. 13
      application/src/test/java/org/thingsboard/server/controller/BaseEdgeControllerTest.java
  18. 25
      application/src/test/java/org/thingsboard/server/controller/BaseEdgeEventControllerTest.java
  19. 30
      application/src/test/java/org/thingsboard/server/controller/BaseEntityViewControllerTest.java
  20. 3
      application/src/test/java/org/thingsboard/server/controller/ControllerNoSqlTestSuite.java
  21. 3
      application/src/test/java/org/thingsboard/server/mqtt/MqttNoSqlTestSuite.java
  22. 3
      application/src/test/java/org/thingsboard/server/system/SystemNoSqlTestSuite.java
  23. 11
      common/dao-api/src/main/java/org/thingsboard/server/dao/edge/EdgeService.java
  24. 7
      common/data/src/main/java/org/thingsboard/server/common/data/DashboardInfo.java
  25. 50
      common/data/src/main/java/org/thingsboard/server/common/data/ShortEdgeInfo.java
  26. 8
      common/data/src/main/java/org/thingsboard/server/common/data/edge/Edge.java
  27. 7
      common/data/src/main/java/org/thingsboard/server/common/data/edge/EdgeEvent.java
  28. 7
      common/data/src/main/java/org/thingsboard/server/common/data/rule/RuleChain.java
  29. 2
      dao/src/main/java/org/thingsboard/server/dao/edge/BaseEdgeEventService.java
  30. 125
      dao/src/main/java/org/thingsboard/server/dao/edge/CassandraEdgeDao.java
  31. 74
      dao/src/main/java/org/thingsboard/server/dao/edge/CassandraEdgeEventDao.java
  32. 11
      dao/src/main/java/org/thingsboard/server/dao/model/ModelConstants.java
  33. 10
      dao/src/main/java/org/thingsboard/server/dao/model/nosql/EdgeEntity.java
  34. 64
      dao/src/main/java/org/thingsboard/server/dao/model/nosql/EdgeEventEntity.java
  35. 23
      dao/src/main/java/org/thingsboard/server/dao/model/sql/EdgeEventEntity.java
  36. 4
      dao/src/main/java/org/thingsboard/server/dao/nosql/CassandraAbstractDao.java
  37. 6
      dao/src/main/java/org/thingsboard/server/dao/rule/BaseRuleChainService.java
  38. 33
      dao/src/main/resources/cassandra/schema-entities.cql
  39. 5
      dao/src/main/resources/sql/schema-entities-hsql.sql
  40. 4
      dao/src/main/resources/sql/schema-entities.sql
  41. 3
      dao/src/test/java/org/thingsboard/server/dao/NoSqlDaoServiceTestSuite.java
  42. 14
      dao/src/test/java/org/thingsboard/server/dao/service/BaseEdgeEventServiceTest.java
  43. 2
      dao/src/test/resources/application-test.properties
  44. 11
      rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/action/TbAssignToCustomerNode.java
  45. 4
      rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/action/TbClearAlarmNode.java
  46. 6
      rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/action/TbCopyAttributesToEntityViewNode.java
  47. 4
      rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/action/TbCreateAlarmNode.java
  48. 4
      rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/action/TbCreateRelationNode.java
  49. 4
      rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/action/TbDeleteRelationNode.java
  50. 12
      rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/action/TbLogNode.java
  51. 12
      rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/action/TbMsgCountNode.java
  52. 4
      rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/action/TbSaveToCustomCassandraTableNode.java
  53. 7
      rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/aws/sns/TbSnsNode.java
  54. 8
      rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/aws/sqs/TbSqsNode.java
  55. 8
      rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/debug/TbMsgGeneratorNode.java
  56. 2
      rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/delay/TbMsgDelayNode.java
  57. 6
      rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/edge/TbMsgPushToEdgeNode.java
  58. 4
      rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/filter/TbCheckMessageNode.java
  59. 4
      rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/filter/TbCheckRelationNode.java
  60. 12
      rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/filter/TbJsFilterNode.java
  61. 11
      rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/filter/TbJsSwitchNode.java
  62. 10
      rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/filter/TbMsgTypeFilterNode.java
  63. 4
      rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/filter/TbMsgTypeSwitchNode.java
  64. 10
      rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/filter/TbOriginatorTypeFilterNode.java
  65. 11
      rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/filter/TbOriginatorTypeSwitchNode.java
  66. 9
      rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/gcp/pubsub/TbPubSubNode.java
  67. 1
      rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/geo/TbGpsGeofencingActionNode.java
  68. 22
      rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/geo/TbGpsGeofencingFilterNode.java
  69. 1
      rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/kafka/TbKafkaNode.java
  70. 7
      rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/mail/TbMsgToEmailNode.java
  71. 1
      rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/mail/TbSendEmailNode.java
  72. 6
      rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetAttributesNode.java
  73. 4
      rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetCustomerAttributeNode.java
  74. 4
      rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetCustomerDetailsNode.java
  75. 7
      rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetDeviceAttrNode.java
  76. 5
      rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetOriginatorFieldsNode.java
  77. 10
      rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetRelatedAttributeNode.java
  78. 5
      rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetTelemetryNode.java
  79. 4
      rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetTenantAttributeNode.java
  80. 4
      rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetTenantDetailsNode.java
  81. 9
      rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/mqtt/TbMqttNode.java
  82. 14
      rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/rabbitmq/TbRabbitMqNode.java
  83. 1
      rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/rest/TbRestApiCallNode.java
  84. 4
      rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/rpc/TbSendRPCReplyNode.java
  85. 14
      rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/rpc/TbSendRPCRequestNode.java
  86. 13
      rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/telemetry/TbMsgAttributesNode.java
  87. 3
      rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/telemetry/TbMsgTimeseriesNode.java
  88. 7
      rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/transaction/TbSynchronizationBeginNode.java
  89. 6
      rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/transaction/TbSynchronizationEndNode.java
  90. 3
      rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/transform/TbChangeOriginatorNode.java
  91. 13
      rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/transform/TbTransformMsgNode.java

1
application/src/main/data/json/demo/rule_chains/root_rule_chain.json

@ -2,6 +2,7 @@
"ruleChain": { "ruleChain": {
"additionalInfo": null, "additionalInfo": null,
"name": "Root Rule Chain", "name": "Root Rule Chain",
"type": "CORE",
"firstRuleNodeId": null, "firstRuleNodeId": null,
"root": true, "root": true,
"debugMode": false, "debugMode": false,

34
application/src/main/data/upgrade/2.6.0/schema_update.cql

@ -18,11 +18,16 @@ CREATE TABLE IF NOT EXISTS thingsboard.edge (
id timeuuid, id timeuuid,
tenant_id timeuuid, tenant_id timeuuid,
customer_id timeuuid, customer_id timeuuid,
root_rule_chain_id timeuuid,
type text,
name text, name text,
label text,
search_text text, search_text text,
routing_key text,
secret text,
configuration text, configuration text,
additional_info text, additional_info text,
PRIMARY KEY (id, tenant_id) PRIMARY KEY (id, tenant_id, customer_id, type)
); );
CREATE MATERIALIZED VIEW IF NOT EXISTS thingsboard.edge_by_tenant_and_name AS CREATE MATERIALIZED VIEW IF NOT EXISTS thingsboard.edge_by_tenant_and_name AS
@ -32,6 +37,13 @@ CREATE MATERIALIZED VIEW IF NOT EXISTS thingsboard.edge_by_tenant_and_name AS
PRIMARY KEY ( tenant_id, name, id, customer_id, type) PRIMARY KEY ( tenant_id, name, id, customer_id, type)
WITH CLUSTERING ORDER BY ( name ASC, id DESC, customer_id DESC); WITH CLUSTERING ORDER BY ( name ASC, id DESC, customer_id DESC);
CREATE MATERIALIZED VIEW IF NOT EXISTS thingsboard.edge_by_tenant_and_routing_key AS
SELECT *
from thingsboard.edge
WHERE tenant_id IS NOT NULL AND customer_id IS NOT NULL AND type IS NOT NULL AND routing_key IS NOT NULL AND id IS NOT NULL
PRIMARY KEY ( tenant_id, routing_key, id, customer_id, type)
WITH CLUSTERING ORDER BY ( routing_key ASC, id DESC, customer_id DESC);
CREATE MATERIALIZED VIEW IF NOT EXISTS thingsboard.edge_by_tenant_and_search_text AS CREATE MATERIALIZED VIEW IF NOT EXISTS thingsboard.edge_by_tenant_and_search_text AS
SELECT * SELECT *
from thingsboard.edge from thingsboard.edge
@ -60,4 +72,22 @@ CREATE MATERIALIZED VIEW IF NOT EXISTS thingsboard.edge_by_customer_by_type_and_
PRIMARY KEY ( customer_id, tenant_id, type, search_text, id ) PRIMARY KEY ( customer_id, tenant_id, type, search_text, id )
WITH CLUSTERING ORDER BY ( tenant_id DESC, type ASC, search_text ASC, id DESC ); WITH CLUSTERING ORDER BY ( tenant_id DESC, type ASC, search_text ASC, id DESC );
-- VOBA ADD changes for the MATERIALIZED view for DEVICE ASSET ENTITY_VIEW RULE_CHAIN CREATE TABLE IF NOT EXISTS thingsboard.edge_event (
id timeuuid,
tenant_id timeuuid,
edge_id timeuuid,
edge_event_type text,
edge_event_action text,
edge_event_uid text,
entity_id timeuuid,
body text,
PRIMARY KEY ((tenant_id, edge_id), edge_event_type, edge_event_uid)
);
CREATE MATERIALIZED VIEW IF NOT EXISTS thingsboard.edge_event_by_id AS
SELECT *
FROM thingsboard.edge_event
WHERE tenant_id IS NOT NULL AND edge_id IS NOT NULL AND edge_event_type IS NOT NULL
AND id IS NOT NULL AND edge_event_uid IS NOT NULL
PRIMARY KEY ((tenant_id, edge_id), id, edge_event_type, edge_event_uid)
WITH CLUSTERING ORDER BY (id ASC);

16
application/src/main/data/upgrade/2.6.0/schema_update.sql

@ -26,5 +26,19 @@ CREATE TABLE IF NOT EXISTS edge (
routing_key varchar(255), routing_key varchar(255),
secret varchar(255), secret varchar(255),
search_text varchar(255), search_text varchar(255),
tenant_id varchar(31) tenant_id varchar(31),
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),
edge_event_uid varchar(255),
entity_id varchar(31),
edge_event_action varchar(255),
body varchar(10000000),
tenant_id varchar(31),
ts bigint NOT NULL
); );

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

@ -212,6 +212,9 @@ public abstract class BaseController {
@Getter @Getter
private boolean logControllerErrorStackTrace; private boolean logControllerErrorStackTrace;
@Value("${edges.rpc.enabled}")
@Getter
private boolean edgesSupportEnabled;
@ExceptionHandler(ThingsboardException.class) @ExceptionHandler(ThingsboardException.class)
public void handleThingsboardException(ThingsboardException ex, HttpServletResponse response) { public void handleThingsboardException(ThingsboardException ex, HttpServletResponse response) {
@ -745,6 +748,9 @@ public abstract class BaseController {
} }
protected void sendNotificationMsgToEdgeService(TenantId tenantId, EdgeId edgeId, CustomerId customerId, ActionType edgeEventAction) { protected void sendNotificationMsgToEdgeService(TenantId tenantId, EdgeId edgeId, CustomerId customerId, ActionType edgeEventAction) {
if (!edgesSupportEnabled) {
return;
}
try { try {
sendNotificationMsgToEdgeService(tenantId, edgeId, null, json.writeValueAsString(customerId), EdgeEventType.EDGE, edgeEventAction); sendNotificationMsgToEdgeService(tenantId, edgeId, null, json.writeValueAsString(customerId), EdgeEventType.EDGE, edgeEventAction);
} catch (Exception e) { } catch (Exception e) {
@ -753,6 +759,9 @@ public abstract class BaseController {
} }
protected void sendNotificationMsgToEdgeService(TenantId tenantId, EntityId entityId, CustomerId customerId, ActionType edgeEventAction) { protected void sendNotificationMsgToEdgeService(TenantId tenantId, EntityId entityId, CustomerId customerId, ActionType edgeEventAction) {
if (!edgesSupportEnabled) {
return;
}
EdgeEventType edgeEventType = EdgeUtils.getEdgeEventTypeByEntityType(entityId.getEntityType()); EdgeEventType edgeEventType = EdgeUtils.getEdgeEventTypeByEntityType(entityId.getEntityType());
try { try {
if (edgeEventType != null) { if (edgeEventType != null) {
@ -764,6 +773,9 @@ public abstract class BaseController {
} }
protected void sendNotificationMsgToEdgeService(TenantId tenantId, EntityRelation relation, ActionType edgeEventAction) { protected void sendNotificationMsgToEdgeService(TenantId tenantId, EntityRelation relation, ActionType edgeEventAction) {
if (!edgesSupportEnabled) {
return;
}
try { try {
if (!relation.getFrom().getEntityType().equals(EntityType.EDGE) && if (!relation.getFrom().getEntityType().equals(EntityType.EDGE) &&
!relation.getTo().getEntityType().equals(EntityType.EDGE)) { !relation.getTo().getEntityType().equals(EntityType.EDGE)) {
@ -779,6 +791,9 @@ public abstract class BaseController {
} }
protected void sendNotificationMsgToEdgeService(TenantId tenantId, EdgeId edgeId, EntityId entityId, ActionType edgeEventAction) { protected void sendNotificationMsgToEdgeService(TenantId tenantId, EdgeId edgeId, EntityId entityId, ActionType edgeEventAction) {
if (!edgesSupportEnabled) {
return;
}
EdgeEventType edgeEventType = EdgeUtils.getEdgeEventTypeByEntityType(entityId.getEntityType()); EdgeEventType edgeEventType = EdgeUtils.getEdgeEventTypeByEntityType(entityId.getEntityType());
if (edgeEventType != null) { if (edgeEventType != null) {
sendNotificationMsgToEdgeService(tenantId, edgeId, entityId, null, edgeEventType, edgeEventAction); sendNotificationMsgToEdgeService(tenantId, edgeId, entityId, null, edgeEventType, edgeEventAction);

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

@ -31,10 +31,8 @@ import org.thingsboard.server.common.data.Dashboard;
import org.thingsboard.server.common.data.DashboardInfo; import org.thingsboard.server.common.data.DashboardInfo;
import org.thingsboard.server.common.data.EntityType; import org.thingsboard.server.common.data.EntityType;
import org.thingsboard.server.common.data.ShortCustomerInfo; 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.audit.ActionType;
import org.thingsboard.server.common.data.edge.Edge; 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.exception.ThingsboardException;
import org.thingsboard.server.common.data.id.CustomerId; import org.thingsboard.server.common.data.id.CustomerId;
import org.thingsboard.server.common.data.id.DashboardId; import org.thingsboard.server.common.data.id.DashboardId;

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

@ -87,9 +87,6 @@ public class DefaultEdgeNotificationService implements EdgeNotificationService {
@Autowired @Autowired
private RuleChainService ruleChainService; private RuleChainService ruleChainService;
@Autowired
private RelationService relationService;
@Autowired @Autowired
private EdgeEventService edgeEventService; private EdgeEventService edgeEventService;
@ -135,12 +132,12 @@ public class DefaultEdgeNotificationService implements EdgeNotificationService {
EdgeEvent edgeEvent = new EdgeEvent(); EdgeEvent edgeEvent = new EdgeEvent();
edgeEvent.setEdgeId(edgeId); edgeEvent.setEdgeId(edgeId);
edgeEvent.setTenantId(tenantId); edgeEvent.setTenantId(tenantId);
edgeEvent.setEdgeEventType(edgeEventType); edgeEvent.setType(edgeEventType);
edgeEvent.setEdgeEventAction(edgeEventAction.name()); edgeEvent.setAction(edgeEventAction.name());
if (entityId != null) { if (entityId != null) {
edgeEvent.setEntityId(entityId.getId()); edgeEvent.setEntityId(entityId.getId());
} }
edgeEvent.setEntityBody(entityBody); edgeEvent.setBody(entityBody);
edgeEventService.saveAsync(edgeEvent); edgeEventService.saveAsync(edgeEvent);
} }

26
application/src/main/java/org/thingsboard/server/service/edge/rpc/EdgeGrpcSession.java

@ -307,7 +307,7 @@ public final class EdgeGrpcSession implements Closeable {
log.trace("Processing edge event [{}]", edgeEvent); log.trace("Processing edge event [{}]", edgeEvent);
try { try {
DownlinkMsg downlinkMsg = null; DownlinkMsg downlinkMsg = null;
ActionType edgeEventAction = ActionType.valueOf(edgeEvent.getEdgeEventAction()); ActionType edgeEventAction = ActionType.valueOf(edgeEvent.getAction());
switch (edgeEventAction) { switch (edgeEventAction) {
case UPDATED: case UPDATED:
case ADDED: case ADDED:
@ -350,7 +350,7 @@ public final class EdgeGrpcSession implements Closeable {
private DownlinkMsg processEntityExistsRequestMessage(EdgeEvent edgeEvent) { private DownlinkMsg processEntityExistsRequestMessage(EdgeEvent edgeEvent) {
DownlinkMsg downlinkMsg = null; DownlinkMsg downlinkMsg = null;
if (EdgeEventType.DEVICE.equals(edgeEvent.getEdgeEventType())) { if (EdgeEventType.DEVICE.equals(edgeEvent.getType())) {
DeviceId deviceId = new DeviceId(edgeEvent.getEntityId()); DeviceId deviceId = new DeviceId(edgeEvent.getEntityId());
Device device = ctx.getDeviceService().findDeviceById(edge.getTenantId(), deviceId); Device device = ctx.getDeviceService().findDeviceById(edge.getTenantId(), deviceId);
CustomerId customerId = getCustomerIdIfEdgeAssignedToCustomer(device); CustomerId customerId = getCustomerIdIfEdgeAssignedToCustomer(device);
@ -365,7 +365,7 @@ public final class EdgeGrpcSession implements Closeable {
private DownlinkMsg processRpcCallMsg(EdgeEvent edgeEvent) { private DownlinkMsg processRpcCallMsg(EdgeEvent edgeEvent) {
log.trace("Executing processRpcCall, edgeEvent [{}]", edgeEvent); log.trace("Executing processRpcCall, edgeEvent [{}]", edgeEvent);
DeviceRpcCallMsg deviceRpcCallMsg = DeviceRpcCallMsg deviceRpcCallMsg =
ctx.getDeviceMsgConstructor().constructDeviceRpcCallMsg(edgeEvent.getEntityBody()); ctx.getDeviceMsgConstructor().constructDeviceRpcCallMsg(edgeEvent.getBody());
return DownlinkMsg.newBuilder() return DownlinkMsg.newBuilder()
.addAllDeviceRpcCallMsg(Collections.singletonList(deviceRpcCallMsg)) .addAllDeviceRpcCallMsg(Collections.singletonList(deviceRpcCallMsg))
.build(); .build();
@ -373,7 +373,7 @@ public final class EdgeGrpcSession implements Closeable {
private DownlinkMsg processCredentialsRequestMessage(EdgeEvent edgeEvent) { private DownlinkMsg processCredentialsRequestMessage(EdgeEvent edgeEvent) {
DownlinkMsg downlinkMsg = null; DownlinkMsg downlinkMsg = null;
if (EdgeEventType.DEVICE.equals(edgeEvent.getEdgeEventType())) { if (EdgeEventType.DEVICE.equals(edgeEvent.getType())) {
DeviceId deviceId = new DeviceId(edgeEvent.getEntityId()); DeviceId deviceId = new DeviceId(edgeEvent.getEntityId());
DeviceCredentialsRequestMsg deviceCredentialsRequestMsg = DeviceCredentialsRequestMsg.newBuilder() DeviceCredentialsRequestMsg deviceCredentialsRequestMsg = DeviceCredentialsRequestMsg.newBuilder()
.setDeviceIdMSB(deviceId.getId().getMostSignificantBits()) .setDeviceIdMSB(deviceId.getId().getMostSignificantBits())
@ -409,7 +409,7 @@ public final class EdgeGrpcSession implements Closeable {
private DownlinkMsg processTelemetryMessage(EdgeEvent edgeEvent) { private DownlinkMsg processTelemetryMessage(EdgeEvent edgeEvent) {
log.trace("Executing processTelemetryMessage, edgeEvent [{}]", edgeEvent); log.trace("Executing processTelemetryMessage, edgeEvent [{}]", edgeEvent);
EntityId entityId = null; EntityId entityId = null;
switch (edgeEvent.getEdgeEventType()) { switch (edgeEvent.getType()) {
case DEVICE: case DEVICE:
entityId = new DeviceId(edgeEvent.getEntityId()); entityId = new DeviceId(edgeEvent.getEntityId());
break; break;
@ -431,21 +431,21 @@ public final class EdgeGrpcSession implements Closeable {
} }
DownlinkMsg downlinkMsg = null; DownlinkMsg downlinkMsg = null;
if (entityId != null) { if (entityId != null) {
log.debug("Sending telemetry data msg, entityId [{}], body [{}]", edgeEvent.getEntityId(), edgeEvent.getEntityBody()); log.debug("Sending telemetry data msg, entityId [{}], body [{}]", edgeEvent.getEntityId(), edgeEvent.getBody());
try { try {
ActionType actionType = ActionType.valueOf(edgeEvent.getEdgeEventAction()); ActionType actionType = ActionType.valueOf(edgeEvent.getAction());
downlinkMsg = constructEntityDataProtoMsg(entityId, actionType, JsonUtils.parse(mapper.writeValueAsString(edgeEvent.getEntityBody()))); downlinkMsg = constructEntityDataProtoMsg(entityId, actionType, JsonUtils.parse(mapper.writeValueAsString(edgeEvent.getBody())));
} catch (Exception e) { } catch (Exception e) {
log.warn("Can't send telemetry data msg, entityId [{}], body [{}]", edgeEvent.getEntityId(), edgeEvent.getEntityBody(), e); log.warn("Can't send telemetry data msg, entityId [{}], body [{}]", edgeEvent.getEntityId(), edgeEvent.getBody(), e);
} }
} }
return downlinkMsg; return downlinkMsg;
} }
private DownlinkMsg processEntityMessage(EdgeEvent edgeEvent, ActionType edgeEventAction) { private DownlinkMsg processEntityMessage(EdgeEvent edgeEvent, ActionType edgeEventAction) {
UpdateMsgType msgType = getResponseMsgType(ActionType.valueOf(edgeEvent.getEdgeEventAction())); UpdateMsgType msgType = getResponseMsgType(ActionType.valueOf(edgeEvent.getAction()));
log.trace("Executing processEntityMessage, edgeEvent [{}], edgeEventAction [{}], msgType [{}]", edgeEvent, edgeEventAction, msgType); log.trace("Executing processEntityMessage, edgeEvent [{}], edgeEventAction [{}], msgType [{}]", edgeEvent, edgeEventAction, msgType);
switch (edgeEvent.getEdgeEventType()) { switch (edgeEvent.getType()) {
case EDGE: case EDGE:
// TODO: voba - add edge update logic // TODO: voba - add edge update logic
return null; return null;
@ -728,7 +728,7 @@ public final class EdgeGrpcSession implements Closeable {
} }
private DownlinkMsg processRelation(EdgeEvent edgeEvent, UpdateMsgType msgType) { private DownlinkMsg processRelation(EdgeEvent edgeEvent, UpdateMsgType msgType) {
EntityRelation entityRelation = mapper.convertValue(edgeEvent.getEntityBody(), EntityRelation.class); EntityRelation entityRelation = mapper.convertValue(edgeEvent.getBody(), EntityRelation.class);
RelationUpdateMsg r = ctx.getRelationMsgConstructor().constructRelationUpdatedMsg(msgType, entityRelation); RelationUpdateMsg r = ctx.getRelationMsgConstructor().constructRelationUpdatedMsg(msgType, entityRelation);
return DownlinkMsg.newBuilder() return DownlinkMsg.newBuilder()
.addAllRelationUpdateMsg(Collections.singletonList(r)) .addAllRelationUpdateMsg(Collections.singletonList(r))
@ -804,7 +804,7 @@ public final class EdgeGrpcSession implements Closeable {
} }
private DownlinkMsg processAdminSettings(EdgeEvent edgeEvent) { private DownlinkMsg processAdminSettings(EdgeEvent edgeEvent) {
AdminSettings adminSettings = mapper.convertValue(edgeEvent.getEntityBody(), AdminSettings.class); AdminSettings adminSettings = mapper.convertValue(edgeEvent.getBody(), AdminSettings.class);
AdminSettingsUpdateMsg t = ctx.getAdminSettingsMsgConstructor().constructAdminSettingsUpdateMsg(adminSettings); AdminSettingsUpdateMsg t = ctx.getAdminSettingsMsgConstructor().constructAdminSettingsUpdateMsg(adminSettings);
return DownlinkMsg.newBuilder() return DownlinkMsg.newBuilder()
.addAllAdminSettingsUpdateMsg(Collections.singletonList(t)) .addAllAdminSettingsUpdateMsg(Collections.singletonList(t))

6
application/src/main/java/org/thingsboard/server/service/edge/rpc/init/DefaultSyncEdgeService.java

@ -534,12 +534,12 @@ public class DefaultSyncEdgeService implements SyncEdgeService {
EdgeEvent edgeEvent = new EdgeEvent(); EdgeEvent edgeEvent = new EdgeEvent();
edgeEvent.setTenantId(tenantId); edgeEvent.setTenantId(tenantId);
edgeEvent.setEdgeId(edgeId); edgeEvent.setEdgeId(edgeId);
edgeEvent.setEdgeEventType(edgeEventType); edgeEvent.setType(edgeEventType);
edgeEvent.setEdgeEventAction(edgeEventAction.name()); edgeEvent.setAction(edgeEventAction.name());
if (entityId != null) { if (entityId != null) {
edgeEvent.setEntityId(entityId.getId()); edgeEvent.setEntityId(entityId.getId());
} }
edgeEvent.setEntityBody(entityBody); edgeEvent.setBody(entityBody);
return edgeEventService.saveAsync(edgeEvent); return edgeEventService.saveAsync(edgeEvent);
} }
} }

6
application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/BaseProcessor.java

@ -105,12 +105,12 @@ public abstract class BaseProcessor {
EdgeEvent edgeEvent = new EdgeEvent(); EdgeEvent edgeEvent = new EdgeEvent();
edgeEvent.setTenantId(tenantId); edgeEvent.setTenantId(tenantId);
edgeEvent.setEdgeId(edgeId); edgeEvent.setEdgeId(edgeId);
edgeEvent.setEdgeEventType(edgeEventType); edgeEvent.setType(edgeEventType);
edgeEvent.setEdgeEventAction(edgeEventAction.name()); edgeEvent.setAction(edgeEventAction.name());
if (entityId != null) { if (entityId != null) {
edgeEvent.setEntityId(entityId.getId()); edgeEvent.setEntityId(entityId.getId());
} }
edgeEvent.setEntityBody(entityBody); edgeEvent.setBody(entityBody);
return edgeEventService.saveAsync(edgeEvent); return edgeEventService.saveAsync(edgeEvent);
} }
} }

6
application/src/main/java/org/thingsboard/server/service/rpc/TbRuleEngineDeviceRpcService.java

@ -30,6 +30,12 @@ public interface TbRuleEngineDeviceRpcService extends RuleEngineRpcService {
void processRpcResponseFromDevice(FromDeviceRpcResponse response); void processRpcResponseFromDevice(FromDeviceRpcResponse response);
/**
* Sends Rpc response from the Device to TB Core.
*
* @param originServiceId Service ID of the origin component
* @param response the RPC response
*/
void sendRpcResponseToTbCore(String originServiceId, FromDeviceRpcResponse response); void sendRpcResponseToTbCore(String originServiceId, FromDeviceRpcResponse response);
} }

1
application/src/main/resources/logback.xml

@ -26,7 +26,6 @@
</appender> </appender>
<logger name="org.thingsboard.server" level="INFO" /> <logger name="org.thingsboard.server" level="INFO" />
<logger name="org.thingsboard.server.service.edge" level="TRACE" />
<!-- <logger name="org.thingsboard.server.service.queue" level="TRACE" />--> <!-- <logger name="org.thingsboard.server.service.queue" level="TRACE" />-->
<!-- <logger name="org.thingsboard.server.service.transport" level="TRACE" />--> <!-- <logger name="org.thingsboard.server.service.transport" level="TRACE" />-->

1
application/src/main/resources/thingsboard.yml

@ -599,6 +599,7 @@ edges:
max_read_records_count: "${EDGES_RPC_STORAGE_MAX_READ_RECORDS_COUNT:50}" max_read_records_count: "${EDGES_RPC_STORAGE_MAX_READ_RECORDS_COUNT:50}"
no_read_records_sleep: "${EDGES_RPC_NO_READ_RECORDS_SLEEP:1000}" no_read_records_sleep: "${EDGES_RPC_NO_READ_RECORDS_SLEEP:1000}"
sleep_between_batches: "${EDGES_RPC_SLEEP_BETWEEN_BATCHES:1000}" sleep_between_batches: "${EDGES_RPC_SLEEP_BETWEEN_BATCHES:1000}"
edge_events_ttl: "${EDGES_EDGE_EVENTS_TTL:0}"
state: state:
persistToTelemetry: "${EDGES_PERSIST_STATE_TO_TELEMETRY:false}" persistToTelemetry: "${EDGES_PERSIST_STATE_TO_TELEMETRY:false}"

14
application/src/test/java/org/thingsboard/server/controller/AbstractControllerTest.java

@ -23,6 +23,7 @@ import io.jsonwebtoken.Header;
import io.jsonwebtoken.Jwt; import io.jsonwebtoken.Jwt;
import io.jsonwebtoken.Jwts; import io.jsonwebtoken.Jwts;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.RandomStringUtils;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import org.hamcrest.Matcher; import org.hamcrest.Matcher;
import org.junit.After; import org.junit.After;
@ -62,6 +63,7 @@ import org.thingsboard.server.common.data.BaseData;
import org.thingsboard.server.common.data.Customer; import org.thingsboard.server.common.data.Customer;
import org.thingsboard.server.common.data.Tenant; import org.thingsboard.server.common.data.Tenant;
import org.thingsboard.server.common.data.User; import org.thingsboard.server.common.data.User;
import org.thingsboard.server.common.data.edge.Edge;
import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.common.data.id.TenantId;
import org.thingsboard.server.common.data.id.UUIDBased; import org.thingsboard.server.common.data.id.UUIDBased;
import org.thingsboard.server.common.data.page.TextPageLink; import org.thingsboard.server.common.data.page.TextPageLink;
@ -498,4 +500,16 @@ public abstract class AbstractControllerTest {
return jsonPath("$.message", matcher); return jsonPath("$.message", matcher);
} }
protected Edge constructEdge(String name, String type) {
return constructEdge(tenantId, name, type);
}
protected Edge constructEdge(TenantId tenantId, String name, String type) {
Edge edge = new Edge();
edge.setTenantId(tenantId);
edge.setName(name);
edge.setType(type);
edge.setSecret(RandomStringUtils.randomAlphanumeric(20));
edge.setRoutingKey(RandomStringUtils.randomAlphanumeric(20));
return edge;
}
} }

28
application/src/test/java/org/thingsboard/server/controller/BaseAssetControllerTest.java

@ -27,9 +27,11 @@ import org.thingsboard.server.common.data.EntitySubtype;
import org.thingsboard.server.common.data.Tenant; import org.thingsboard.server.common.data.Tenant;
import org.thingsboard.server.common.data.User; import org.thingsboard.server.common.data.User;
import org.thingsboard.server.common.data.asset.Asset; import org.thingsboard.server.common.data.asset.Asset;
import org.thingsboard.server.common.data.edge.Edge;
import org.thingsboard.server.common.data.id.CustomerId; import org.thingsboard.server.common.data.id.CustomerId;
import org.thingsboard.server.common.data.page.TextPageData; import org.thingsboard.server.common.data.page.TextPageData;
import org.thingsboard.server.common.data.page.TextPageLink; import org.thingsboard.server.common.data.page.TextPageLink;
import org.thingsboard.server.common.data.page.TimePageData;
import org.thingsboard.server.common.data.security.Authority; import org.thingsboard.server.common.data.security.Authority;
import org.thingsboard.server.dao.model.ModelConstants; import org.thingsboard.server.dao.model.ModelConstants;
import org.thingsboard.server.service.stats.DefaultRuleEngineStatisticsService; import org.thingsboard.server.service.stats.DefaultRuleEngineStatisticsService;
@ -690,4 +692,30 @@ public abstract class BaseAssetControllerTest extends AbstractControllerTest {
Assert.assertEquals(0, pageData.getData().size()); Assert.assertEquals(0, pageData.getData().size());
} }
@Test
public void testAssignAssetToEdge() throws Exception {
Edge edge = constructEdge("My edge", "default");
Edge savedEdge = doPost("/api/edge", edge, Edge.class);
Asset asset = new Asset();
asset.setName("My asset");
asset.setType("default");
Asset savedAsset = doPost("/api/asset", asset, Asset.class);
doPost("/api/edge/" + savedEdge.getId().getId().toString()
+ "/asset/" + savedAsset.getId().getId().toString(), Asset.class);
TimePageData<Asset> pageData = doGetTypedWithPageLink("/api/edge/" + savedEdge.getId().getId().toString() + "/assets?",
new TypeReference<TimePageData<Asset>>() {}, new TextPageLink(100));
Assert.assertEquals(1, pageData.getData().size());
doDelete("/api/edge/" + savedEdge.getId().getId().toString()
+ "/asset/" + savedAsset.getId().getId().toString(), Asset.class);
pageData = doGetTypedWithPageLink("/api/edge/" + savedEdge.getId().getId().toString() + "/assets?",
new TypeReference<TimePageData<Asset>>() {}, new TextPageLink(100));
Assert.assertEquals(0, pageData.getData().size());
}
} }

56
application/src/test/java/org/thingsboard/server/controller/BaseDashboardControllerTest.java

@ -15,28 +15,32 @@
*/ */
package org.thingsboard.server.controller; package org.thingsboard.server.controller;
import static org.hamcrest.Matchers.containsString;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import com.datastax.driver.core.utils.UUIDs; import com.datastax.driver.core.utils.UUIDs;
import com.fasterxml.jackson.core.type.TypeReference;
import org.apache.commons.lang3.RandomStringUtils; import org.apache.commons.lang3.RandomStringUtils;
import org.thingsboard.server.common.data.*; import org.junit.After;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import org.thingsboard.server.common.data.Customer;
import org.thingsboard.server.common.data.Dashboard;
import org.thingsboard.server.common.data.DashboardInfo;
import org.thingsboard.server.common.data.Tenant;
import org.thingsboard.server.common.data.User;
import org.thingsboard.server.common.data.edge.Edge;
import org.thingsboard.server.common.data.id.CustomerId; import org.thingsboard.server.common.data.id.CustomerId;
import org.thingsboard.server.common.data.page.TextPageData; import org.thingsboard.server.common.data.page.TextPageData;
import org.thingsboard.server.common.data.page.TextPageLink; import org.thingsboard.server.common.data.page.TextPageLink;
import org.thingsboard.server.common.data.page.TimePageData; import org.thingsboard.server.common.data.page.TimePageData;
import org.thingsboard.server.common.data.page.TimePageLink; import org.thingsboard.server.common.data.page.TimePageLink;
import org.thingsboard.server.common.data.security.Authority; import org.thingsboard.server.common.data.security.Authority;
import org.junit.After;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import com.fasterxml.jackson.core.type.TypeReference; import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import static org.hamcrest.Matchers.containsString;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
public abstract class BaseDashboardControllerTest extends AbstractControllerTest { public abstract class BaseDashboardControllerTest extends AbstractControllerTest {
@ -349,4 +353,30 @@ public abstract class BaseDashboardControllerTest extends AbstractControllerTest
Assert.assertEquals(dashboards, loadedDashboards); Assert.assertEquals(dashboards, loadedDashboards);
} }
@Test
public void testAssignDashboardToEdge() throws Exception {
Edge edge = constructEdge("My edge", "default");
Edge savedEdge = doPost("/api/edge", edge, Edge.class);
Dashboard dashboard = new Dashboard();
dashboard.setTitle("My dashboard");
Dashboard savedDashboard = doPost("/api/dashboard", dashboard, Dashboard.class);
doPost("/api/edge/" + savedEdge.getId().getId().toString()
+ "/dashboard/" + savedDashboard.getId().getId().toString(), Dashboard.class);
TimePageData<Dashboard> pageData = doGetTypedWithPageLink("/api/edge/" + savedEdge.getId().getId().toString() + "/dashboards?",
new TypeReference<TimePageData<Dashboard>>() {}, new TextPageLink(100));
Assert.assertEquals(1, pageData.getData().size());
doDelete("/api/edge/" + savedEdge.getId().getId().toString()
+ "/dashboard/" + savedDashboard.getId().getId().toString(), Dashboard.class);
pageData = doGetTypedWithPageLink("/api/edge/" + savedEdge.getId().getId().toString() + "/dashboards?",
new TypeReference<TimePageData<Dashboard>>() {}, new TextPageLink(100));
Assert.assertEquals(0, pageData.getData().size());
}
} }

29
application/src/test/java/org/thingsboard/server/controller/BaseDeviceControllerTest.java

@ -27,11 +27,13 @@ import org.thingsboard.server.common.data.Device;
import org.thingsboard.server.common.data.EntitySubtype; import org.thingsboard.server.common.data.EntitySubtype;
import org.thingsboard.server.common.data.Tenant; import org.thingsboard.server.common.data.Tenant;
import org.thingsboard.server.common.data.User; import org.thingsboard.server.common.data.User;
import org.thingsboard.server.common.data.edge.Edge;
import org.thingsboard.server.common.data.id.CustomerId; import org.thingsboard.server.common.data.id.CustomerId;
import org.thingsboard.server.common.data.id.DeviceCredentialsId; import org.thingsboard.server.common.data.id.DeviceCredentialsId;
import org.thingsboard.server.common.data.id.DeviceId; import org.thingsboard.server.common.data.id.DeviceId;
import org.thingsboard.server.common.data.page.TextPageData; import org.thingsboard.server.common.data.page.TextPageData;
import org.thingsboard.server.common.data.page.TextPageLink; import org.thingsboard.server.common.data.page.TextPageLink;
import org.thingsboard.server.common.data.page.TimePageData;
import org.thingsboard.server.common.data.relation.EntityRelation; import org.thingsboard.server.common.data.relation.EntityRelation;
import org.thingsboard.server.common.data.relation.RelationTypeGroup; import org.thingsboard.server.common.data.relation.RelationTypeGroup;
import org.thingsboard.server.common.data.security.Authority; import org.thingsboard.server.common.data.security.Authority;
@ -849,4 +851,31 @@ public abstract class BaseDeviceControllerTest extends AbstractControllerTest {
doDelete("/api/tenant/" + savedDifferentTenant.getId().getId().toString()) doDelete("/api/tenant/" + savedDifferentTenant.getId().getId().toString())
.andExpect(status().isOk()); .andExpect(status().isOk());
} }
@Test
public void testAssignDeviceToEdge() throws Exception {
Edge edge = constructEdge("My edge", "default");
Edge savedEdge = doPost("/api/edge", edge, Edge.class);
Device device = new Device();
device.setName("My device");
device.setType("default");
Device savedDevice = doPost("/api/device", device, Device.class);
doPost("/api/edge/" + savedEdge.getId().getId().toString()
+ "/device/" + savedDevice.getId().getId().toString(), Device.class);
TimePageData<Device> pageData = doGetTypedWithPageLink("/api/edge/" + savedEdge.getId().getId().toString() + "/devices?",
new TypeReference<TimePageData<Device>>() {}, new TextPageLink(100));
Assert.assertEquals(1, pageData.getData().size());
doDelete("/api/edge/" + savedEdge.getId().getId().toString()
+ "/device/" + savedDevice.getId().getId().toString(), Device.class);
pageData = doGetTypedWithPageLink("/api/edge/" + savedEdge.getId().getId().toString() + "/devices?",
new TypeReference<TimePageData<Device>>() {}, new TextPageLink(100));
Assert.assertEquals(0, pageData.getData().size());
}
} }

13
application/src/test/java/org/thingsboard/server/controller/BaseEdgeControllerTest.java

@ -638,17 +638,4 @@ public abstract class BaseEdgeControllerTest extends AbstractControllerTest {
Assert.assertEquals(0, pageData.getData().size()); Assert.assertEquals(0, pageData.getData().size());
} }
private Edge constructEdge(String name, String type) {
return constructEdge(tenantId, name, type);
}
private Edge constructEdge(TenantId tenantId, String name, String type) {
Edge edge = new Edge();
edge.setTenantId(tenantId);
edge.setName(name);
edge.setType(type);
edge.setSecret(RandomStringUtils.randomAlphanumeric(20));
edge.setRoutingKey(RandomStringUtils.randomAlphanumeric(20));
return edge;
}
} }

25
application/src/test/java/org/thingsboard/server/controller/BaseEdgeEventControllerTest.java

@ -83,38 +83,29 @@ public class BaseEdgeEventControllerTest extends AbstractControllerTest {
Device savedDevice = doPost("/api/device", device, Device.class); Device savedDevice = doPost("/api/device", device, Device.class);
doPost("/api/edge/" + edge.getId().toString() + "/device/" + savedDevice.getId().toString(), Device.class); doPost("/api/edge/" + edge.getId().toString() + "/device/" + savedDevice.getId().toString(), Device.class);
Thread.sleep(1000);
Asset asset = constructAsset("TestAsset", "default"); Asset asset = constructAsset("TestAsset", "default");
Asset savedAsset = doPost("/api/asset", asset, Asset.class); Asset savedAsset = doPost("/api/asset", asset, Asset.class);
doPost("/api/edge/" + edge.getId().toString() + "/asset/" + savedAsset.getId().toString(), Asset.class); doPost("/api/edge/" + edge.getId().toString() + "/asset/" + savedAsset.getId().toString(), Asset.class);
Thread.sleep(1000);
EntityRelation relation = new EntityRelation(savedAsset.getId(), savedDevice.getId(), EntityRelation.CONTAINS_TYPE); EntityRelation relation = new EntityRelation(savedAsset.getId(), savedDevice.getId(), EntityRelation.CONTAINS_TYPE);
doPost("/api/relation", relation); doPost("/api/relation", relation);
Thread.sleep(1000);
Thread.sleep(2000);
List<EdgeEvent> edgeEvents = doGetTypedWithTimePageLink("/api/edge/" + edge.getId().toString() + "/events?", List<EdgeEvent> edgeEvents = doGetTypedWithTimePageLink("/api/edge/" + edge.getId().toString() + "/events?",
new TypeReference<TimePageData<EdgeEvent>>() { new TypeReference<TimePageData<EdgeEvent>>() {
}, new TimePageLink(5)).getData(); }, new TimePageLink(4)).getData();
Assert.assertFalse(edgeEvents.isEmpty()); Assert.assertFalse(edgeEvents.isEmpty());
Assert.assertEquals(4, edgeEvents.size()); Assert.assertEquals(4, edgeEvents.size());
Assert.assertEquals(edgeEvents.get(0).getEdgeEventType(), EdgeEventType.RELATION); Assert.assertEquals(EdgeEventType.RELATION, edgeEvents.get(0).getType());
Assert.assertEquals(edgeEvents.get(1).getEdgeEventType(), EdgeEventType.ASSET); Assert.assertEquals(EdgeEventType.ASSET, edgeEvents.get(1).getType());
Assert.assertEquals(edgeEvents.get(2).getEdgeEventType(), EdgeEventType.DEVICE); Assert.assertEquals(EdgeEventType.DEVICE, edgeEvents.get(2).getType());
Assert.assertEquals(edgeEvents.get(3).getEdgeEventType(), EdgeEventType.RULE_CHAIN); Assert.assertEquals(EdgeEventType.RULE_CHAIN, edgeEvents.get(3).getType());
}
private Edge constructEdge(String name, String type) {
Edge edge = new Edge();
edge.setTenantId(tenantId);
edge.setName(name);
edge.setType(type);
edge.setSecret(RandomStringUtils.randomAlphanumeric(20));
edge.setRoutingKey(RandomStringUtils.randomAlphanumeric(20));
return edge;
} }
private Device constructDevice(String name, String type) { private Device constructDevice(String name, String type) {

30
application/src/test/java/org/thingsboard/server/controller/BaseEntityViewControllerTest.java

@ -31,11 +31,13 @@ import org.thingsboard.server.common.data.Device;
import org.thingsboard.server.common.data.EntityView; import org.thingsboard.server.common.data.EntityView;
import org.thingsboard.server.common.data.Tenant; import org.thingsboard.server.common.data.Tenant;
import org.thingsboard.server.common.data.User; import org.thingsboard.server.common.data.User;
import org.thingsboard.server.common.data.edge.Edge;
import org.thingsboard.server.common.data.id.CustomerId; import org.thingsboard.server.common.data.id.CustomerId;
import org.thingsboard.server.common.data.objects.AttributesEntityView; import org.thingsboard.server.common.data.objects.AttributesEntityView;
import org.thingsboard.server.common.data.objects.TelemetryEntityView; import org.thingsboard.server.common.data.objects.TelemetryEntityView;
import org.thingsboard.server.common.data.page.TextPageData; import org.thingsboard.server.common.data.page.TextPageData;
import org.thingsboard.server.common.data.page.TextPageLink; import org.thingsboard.server.common.data.page.TextPageLink;
import org.thingsboard.server.common.data.page.TimePageData;
import org.thingsboard.server.common.data.security.Authority; import org.thingsboard.server.common.data.security.Authority;
import org.thingsboard.server.common.data.security.DeviceCredentials; import org.thingsboard.server.common.data.security.DeviceCredentials;
import org.thingsboard.server.dao.model.ModelConstants; import org.thingsboard.server.dao.model.ModelConstants;
@ -52,7 +54,6 @@ import java.util.concurrent.TimeUnit;
import static org.hamcrest.Matchers.containsString; import static org.hamcrest.Matchers.containsString;
import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue; import static org.junit.Assert.assertTrue;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
import static org.thingsboard.server.dao.model.ModelConstants.NULL_UUID; import static org.thingsboard.server.dao.model.ModelConstants.NULL_UUID;
@ -552,4 +553,31 @@ public abstract class BaseEntityViewControllerTest extends AbstractControllerTes
return loadedItems; return loadedItems;
} }
@Test
public void testAssignEntityViewToEdge() throws Exception {
Edge edge = constructEdge("My edge", "default");
Edge savedEdge = doPost("/api/edge", edge, Edge.class);
EntityView savedEntityView = getNewSavedEntityView("My entityView");
doPost("/api/edge/" + savedEdge.getId().getId().toString()
+ "/device/" + testDevice.getId().getId().toString(), Device.class);
doPost("/api/edge/" + savedEdge.getId().getId().toString()
+ "/entityView/" + savedEntityView.getId().getId().toString(), EntityView.class);
TimePageData<EntityView> pageData = doGetTypedWithPageLink("/api/edge/" + savedEdge.getId().getId().toString() + "/entityViews?",
new TypeReference<TimePageData<EntityView>>() {}, new TextPageLink(100));
Assert.assertEquals(1, pageData.getData().size());
doDelete("/api/edge/" + savedEdge.getId().getId().toString()
+ "/entityView/" + savedEntityView.getId().getId().toString(), EntityView.class);
pageData = doGetTypedWithPageLink("/api/edge/" + savedEdge.getId().getId().toString() + "/entityViews?",
new TypeReference<TimePageData<EntityView>>() {}, new TextPageLink(100));
Assert.assertEquals(0, pageData.getData().size());
}
} }

3
application/src/test/java/org/thingsboard/server/controller/ControllerNoSqlTestSuite.java

@ -27,8 +27,7 @@ import java.util.Arrays;
@RunWith(ClasspathSuite.class) @RunWith(ClasspathSuite.class)
@ClasspathSuite.ClassnameFilters({ @ClasspathSuite.ClassnameFilters({
// TODO: voba - fix before final test on cassandra "org.thingsboard.server.controller.nosql.*Test"})
"org.thingsboard.server.controller.nosql.*VOBA_FIX_BEFORE_FINAL_TESTTest"})
public class ControllerNoSqlTestSuite { public class ControllerNoSqlTestSuite {
@ClassRule @ClassRule

3
application/src/test/java/org/thingsboard/server/mqtt/MqttNoSqlTestSuite.java

@ -27,8 +27,7 @@ import java.util.Arrays;
@RunWith(ClasspathSuite.class) @RunWith(ClasspathSuite.class)
@ClasspathSuite.ClassnameFilters({ @ClasspathSuite.ClassnameFilters({
// TODO: voba - fix before final test on cassandra "org.thingsboard.server.mqtt.*.nosql.*Test"})
"org.thingsboard.server.mqtt.*.nosql.*VOBA_FIX_BEFORE_FINAL_TESTTest"})
public class MqttNoSqlTestSuite { public class MqttNoSqlTestSuite {
@ClassRule @ClassRule

3
application/src/test/java/org/thingsboard/server/system/SystemNoSqlTestSuite.java

@ -30,8 +30,7 @@ import java.util.Arrays;
*/ */
@RunWith(ClasspathSuite.class) @RunWith(ClasspathSuite.class)
@ClasspathSuite.ClassnameFilters({ @ClasspathSuite.ClassnameFilters({
// TODO: voba - fix before final test on cassandra "org.thingsboard.server.system.*NoSqlTest"})
"org.thingsboard.server.system.*VOBA_FIX_BEFORE_FINAL_TESTNoSqlTest"})
public class SystemNoSqlTestSuite { public class SystemNoSqlTestSuite {
@ClassRule @ClassRule

11
common/dao-api/src/main/java/org/thingsboard/server/dao/edge/EdgeService.java

@ -77,14 +77,3 @@ public interface EdgeService {
ListenableFuture<List<EdgeId>> findRelatedEdgeIdsByEntityId(TenantId tenantId, EntityId entityId); ListenableFuture<List<EdgeId>> findRelatedEdgeIdsByEntityId(TenantId tenantId, EntityId entityId);
} }

7
common/data/src/main/java/org/thingsboard/server/common/data/DashboardInfo.java

@ -16,15 +16,12 @@
package org.thingsboard.server.common.data; package org.thingsboard.server.common.data;
import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.Getter;
import lombok.Setter;
import org.thingsboard.server.common.data.edge.Edge;
import org.thingsboard.server.common.data.id.CustomerId; import org.thingsboard.server.common.data.id.CustomerId;
import org.thingsboard.server.common.data.id.DashboardId; import org.thingsboard.server.common.data.id.DashboardId;
import org.thingsboard.server.common.data.id.EdgeId;
import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.common.data.id.TenantId;
import java.util.*; import java.util.HashSet;
import java.util.Set;
public class DashboardInfo extends SearchTextBased<DashboardId> implements HasName, HasTenantId { public class DashboardInfo extends SearchTextBased<DashboardId> implements HasName, HasTenantId {

50
common/data/src/main/java/org/thingsboard/server/common/data/ShortEdgeInfo.java

@ -1,50 +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.server.common.data;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.Setter;
import org.thingsboard.server.common.data.id.EdgeId;
import org.thingsboard.server.common.data.id.RuleChainId;
@AllArgsConstructor
public class ShortEdgeInfo {
@Getter @Setter
private EdgeId edgeId;
@Getter @Setter
private String title;
@Getter @Setter
private RuleChainId rootRuleChainId;
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
ShortEdgeInfo that = (ShortEdgeInfo) o;
return edgeId.equals(that.edgeId);
}
@Override
public int hashCode() {
return edgeId.hashCode();
}
}

8
common/data/src/main/java/org/thingsboard/server/common/data/edge/Edge.java

@ -15,7 +15,6 @@
*/ */
package org.thingsboard.server.common.data.edge; package org.thingsboard.server.common.data.edge;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.JsonNode;
import lombok.EqualsAndHashCode; import lombok.EqualsAndHashCode;
import lombok.Getter; import lombok.Getter;
@ -25,8 +24,6 @@ import org.thingsboard.server.common.data.HasCustomerId;
import org.thingsboard.server.common.data.HasName; import org.thingsboard.server.common.data.HasName;
import org.thingsboard.server.common.data.HasTenantId; import org.thingsboard.server.common.data.HasTenantId;
import org.thingsboard.server.common.data.SearchTextBasedWithAdditionalInfo; import org.thingsboard.server.common.data.SearchTextBasedWithAdditionalInfo;
import org.thingsboard.server.common.data.ShortCustomerInfo;
import org.thingsboard.server.common.data.ShortEdgeInfo;
import org.thingsboard.server.common.data.id.CustomerId; import org.thingsboard.server.common.data.id.CustomerId;
import org.thingsboard.server.common.data.id.EdgeId; import org.thingsboard.server.common.data.id.EdgeId;
import org.thingsboard.server.common.data.id.RuleChainId; import org.thingsboard.server.common.data.id.RuleChainId;
@ -70,11 +67,6 @@ public class Edge extends SearchTextBasedWithAdditionalInfo<EdgeId> implements H
this.configuration = edge.getConfiguration(); this.configuration = edge.getConfiguration();
} }
@JsonIgnore
public ShortEdgeInfo toShortEdgeInfo() {
return new ShortEdgeInfo(id, name, rootRuleChainId);
}
@Override @Override
public String getSearchText() { public String getSearchText() {
return getName(); return getName();

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

@ -29,10 +29,11 @@ public class EdgeEvent extends BaseData<EdgeEventId> {
private TenantId tenantId; private TenantId tenantId;
private EdgeId edgeId; private EdgeId edgeId;
private String edgeEventAction; private String action;
private UUID entityId; private UUID entityId;
private EdgeEventType edgeEventType; private String uid;
private transient JsonNode entityBody; private EdgeEventType type;
private transient JsonNode body;
public EdgeEvent() { public EdgeEvent() {
super(); super();

7
common/data/src/main/java/org/thingsboard/server/common/data/rule/RuleChain.java

@ -20,20 +20,13 @@ import com.fasterxml.jackson.databind.JsonNode;
import lombok.Data; import lombok.Data;
import lombok.EqualsAndHashCode; import lombok.EqualsAndHashCode;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.thingsboard.server.common.data.EdgeUtils;
import org.thingsboard.server.common.data.HasName; import org.thingsboard.server.common.data.HasName;
import org.thingsboard.server.common.data.HasTenantId; import org.thingsboard.server.common.data.HasTenantId;
import org.thingsboard.server.common.data.SearchTextBasedWithAdditionalInfo; import org.thingsboard.server.common.data.SearchTextBasedWithAdditionalInfo;
import org.thingsboard.server.common.data.ShortEdgeInfo;
import org.thingsboard.server.common.data.edge.Edge;
import org.thingsboard.server.common.data.id.EdgeId;
import org.thingsboard.server.common.data.id.RuleChainId; import org.thingsboard.server.common.data.id.RuleChainId;
import org.thingsboard.server.common.data.id.RuleNodeId; import org.thingsboard.server.common.data.id.RuleNodeId;
import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.common.data.id.TenantId;
import java.util.HashSet;
import java.util.Set;
@Data @Data
@EqualsAndHashCode(callSuper = true) @EqualsAndHashCode(callSuper = true)
@Slf4j @Slf4j

2
dao/src/main/java/org/thingsboard/server/dao/edge/BaseEdgeEventService.java

@ -56,7 +56,7 @@ public class BaseEdgeEventService implements EdgeEventService {
if (edgeEvent.getEdgeId() == null) { if (edgeEvent.getEdgeId() == null) {
throw new DataValidationException("Edge id should be specified!"); throw new DataValidationException("Edge id should be specified!");
} }
if (StringUtils.isEmpty(edgeEvent.getEdgeEventAction())) { if (StringUtils.isEmpty(edgeEvent.getAction())) {
throw new DataValidationException("Edge Event action should be specified!"); throw new DataValidationException("Edge Event action should be specified!");
} }
} }

125
dao/src/main/java/org/thingsboard/server/dao/edge/CassandraEdgeDao.java

@ -15,13 +15,21 @@
*/ */
package org.thingsboard.server.dao.edge; package org.thingsboard.server.dao.edge;
import com.datastax.driver.core.ResultSet;
import com.datastax.driver.core.ResultSetFuture;
import com.datastax.driver.core.Statement;
import com.datastax.driver.core.querybuilder.Select;
import com.datastax.driver.mapping.Result;
import com.google.common.base.Function;
import com.google.common.util.concurrent.Futures; import com.google.common.util.concurrent.Futures;
import com.google.common.util.concurrent.ListenableFuture; import com.google.common.util.concurrent.ListenableFuture;
import com.google.common.util.concurrent.MoreExecutors; import com.google.common.util.concurrent.MoreExecutors;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import org.thingsboard.server.common.data.Device;
import org.thingsboard.server.common.data.EntitySubtype; import org.thingsboard.server.common.data.EntitySubtype;
import org.thingsboard.server.common.data.EntityType;
import org.thingsboard.server.common.data.edge.Edge; import org.thingsboard.server.common.data.edge.Edge;
import org.thingsboard.server.common.data.id.DashboardId; import org.thingsboard.server.common.data.id.DashboardId;
import org.thingsboard.server.common.data.id.RuleChainId; import org.thingsboard.server.common.data.id.RuleChainId;
@ -29,17 +37,40 @@ import org.thingsboard.server.common.data.id.TenantId;
import org.thingsboard.server.common.data.page.TextPageLink; import org.thingsboard.server.common.data.page.TextPageLink;
import org.thingsboard.server.common.data.relation.EntityRelation; import org.thingsboard.server.common.data.relation.EntityRelation;
import org.thingsboard.server.common.data.relation.RelationTypeGroup; import org.thingsboard.server.common.data.relation.RelationTypeGroup;
import org.thingsboard.server.dao.DaoUtil;
import org.thingsboard.server.dao.model.EntitySubtypeEntity;
import org.thingsboard.server.dao.model.nosql.EdgeEntity; import org.thingsboard.server.dao.model.nosql.EdgeEntity;
import org.thingsboard.server.dao.nosql.CassandraAbstractSearchTextDao; import org.thingsboard.server.dao.nosql.CassandraAbstractSearchTextDao;
import org.thingsboard.server.dao.relation.RelationDao; import org.thingsboard.server.dao.relation.RelationDao;
import org.thingsboard.server.dao.util.NoSqlDao; import org.thingsboard.server.dao.util.NoSqlDao;
import javax.annotation.Nullable;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List; import java.util.List;
import java.util.Optional; import java.util.Optional;
import java.util.UUID; import java.util.UUID;
import static com.datastax.driver.core.querybuilder.QueryBuilder.eq;
import static com.datastax.driver.core.querybuilder.QueryBuilder.in;
import static com.datastax.driver.core.querybuilder.QueryBuilder.select;
import static org.thingsboard.server.dao.model.ModelConstants.EDGE_BY_CUSTOMER_AND_SEARCH_TEXT_COLUMN_FAMILY_NAME;
import static org.thingsboard.server.dao.model.ModelConstants.EDGE_BY_CUSTOMER_BY_TYPE_AND_SEARCH_TEXT_COLUMN_FAMILY_NAME;
import static org.thingsboard.server.dao.model.ModelConstants.EDGE_BY_TENANT_AND_NAME_VIEW_NAME;
import static org.thingsboard.server.dao.model.ModelConstants.EDGE_BY_TENANT_AND_ROUTING_KEY_VIEW_NAME;
import static org.thingsboard.server.dao.model.ModelConstants.EDGE_BY_TENANT_AND_SEARCH_TEXT_COLUMN_FAMILY_NAME;
import static org.thingsboard.server.dao.model.ModelConstants.EDGE_BY_TENANT_BY_TYPE_AND_SEARCH_TEXT_COLUMN_FAMILY_NAME;
import static org.thingsboard.server.dao.model.ModelConstants.EDGE_COLUMN_FAMILY_NAME; import static org.thingsboard.server.dao.model.ModelConstants.EDGE_COLUMN_FAMILY_NAME;
import static org.thingsboard.server.dao.model.ModelConstants.EDGE_CUSTOMER_ID_PROPERTY;
import static org.thingsboard.server.dao.model.ModelConstants.EDGE_NAME_PROPERTY;
import static org.thingsboard.server.dao.model.ModelConstants.EDGE_ROUTING_KEY_PROPERTY;
import static org.thingsboard.server.dao.model.ModelConstants.EDGE_TENANT_ID_PROPERTY;
import static org.thingsboard.server.dao.model.ModelConstants.EDGE_TYPE_PROPERTY;
import static org.thingsboard.server.dao.model.ModelConstants.ENTITY_SUBTYPE_COLUMN_FAMILY_NAME;
import static org.thingsboard.server.dao.model.ModelConstants.ENTITY_SUBTYPE_ENTITY_TYPE_PROPERTY;
import static org.thingsboard.server.dao.model.ModelConstants.ENTITY_SUBTYPE_TENANT_ID_PROPERTY;
import static org.thingsboard.server.dao.model.ModelConstants.ID_PROPERTY;
@Component @Component
@Slf4j @Slf4j
@ -59,50 +90,124 @@ public class CassandraEdgeDao extends CassandraAbstractSearchTextDao<EdgeEntity,
return EDGE_COLUMN_FAMILY_NAME; return EDGE_COLUMN_FAMILY_NAME;
} }
@Override
public Edge save(TenantId tenantId, Edge domain) {
Edge savedEdge = super.save(tenantId, domain);
EntitySubtype entitySubtype = new EntitySubtype(savedEdge.getTenantId(), EntityType.EDGE, savedEdge.getType());
EntitySubtypeEntity entitySubtypeEntity = new EntitySubtypeEntity(entitySubtype);
Statement saveStatement = cluster.getMapper(EntitySubtypeEntity.class).saveQuery(entitySubtypeEntity);
executeWrite(tenantId, saveStatement);
return savedEdge;
}
@Override @Override
public List<Edge> findEdgesByTenantId(UUID tenantId, TextPageLink pageLink) { public List<Edge> findEdgesByTenantId(UUID tenantId, TextPageLink pageLink) {
return null; log.debug("Try to find edge by tenantId [{}] and pageLink [{}]", tenantId, pageLink);
List<EdgeEntity> edgeEntities = findPageWithTextSearch(new TenantId(tenantId), EDGE_BY_TENANT_AND_SEARCH_TEXT_COLUMN_FAMILY_NAME,
Collections.singletonList(eq(EDGE_TENANT_ID_PROPERTY, tenantId)), pageLink);
log.trace("Found edges [{}] by tenantId [{}] and pageLink [{}]", edgeEntities, tenantId, pageLink);
return DaoUtil.convertDataList(edgeEntities);
} }
@Override @Override
public List<Edge> findEdgesByTenantIdAndType(UUID tenantId, String type, TextPageLink pageLink) { public List<Edge> findEdgesByTenantIdAndType(UUID tenantId, String type, TextPageLink pageLink) {
return null; log.debug("Try to find edges by tenantId [{}], type [{}] and pageLink [{}]", tenantId, type, pageLink);
List<EdgeEntity> edgeEntities = findPageWithTextSearch(new TenantId(tenantId), EDGE_BY_TENANT_BY_TYPE_AND_SEARCH_TEXT_COLUMN_FAMILY_NAME,
Arrays.asList(eq(EDGE_TYPE_PROPERTY, type),
eq(EDGE_TENANT_ID_PROPERTY, tenantId)), pageLink);
log.trace("Found edges [{}] by tenantId [{}], type [{}] and pageLink [{}]", edgeEntities, tenantId, type, pageLink);
return DaoUtil.convertDataList(edgeEntities);
} }
@Override @Override
public ListenableFuture<List<Edge>> findEdgesByTenantIdAndIdsAsync(UUID tenantId, List<UUID> edgeIds) { public ListenableFuture<List<Edge>> findEdgesByTenantIdAndIdsAsync(UUID tenantId, List<UUID> edgeIds) {
return null; log.debug("Try to find edges by tenantId [{}] and edge Ids [{}]", tenantId, edgeIds);
Select select = select().from(getColumnFamilyName());
Select.Where query = select.where();
query.and(eq(EDGE_TENANT_ID_PROPERTY, tenantId));
query.and(in(ID_PROPERTY, edgeIds));
return findListByStatementAsync(new TenantId(tenantId), query);
} }
@Override @Override
public List<Edge> findEdgesByTenantIdAndCustomerId(UUID tenantId, UUID customerId, TextPageLink pageLink) { public List<Edge> findEdgesByTenantIdAndCustomerId(UUID tenantId, UUID customerId, TextPageLink pageLink) {
return null; log.debug("Try to find edges by tenantId [{}], customerId[{}] and pageLink [{}]", tenantId, customerId, pageLink);
List<EdgeEntity> edgeEntities = findPageWithTextSearch(new TenantId(tenantId), EDGE_BY_CUSTOMER_AND_SEARCH_TEXT_COLUMN_FAMILY_NAME,
Arrays.asList(eq(EDGE_CUSTOMER_ID_PROPERTY, customerId),
eq(EDGE_TENANT_ID_PROPERTY, tenantId)),
pageLink);
log.trace("Found edges [{}] by tenantId [{}], customerId [{}] and pageLink [{}]", edgeEntities, tenantId, customerId, pageLink);
return DaoUtil.convertDataList(edgeEntities);
} }
@Override @Override
public List<Edge> findEdgesByTenantIdAndCustomerIdAndType(UUID tenantId, UUID customerId, String type, TextPageLink pageLink) { public List<Edge> findEdgesByTenantIdAndCustomerIdAndType(UUID tenantId, UUID customerId, String type, TextPageLink pageLink) {
return null; log.debug("Try to find edges by tenantId [{}], customerId [{}], type [{}] and pageLink [{}]", tenantId, customerId, type, pageLink);
List<EdgeEntity> edgeEntities = findPageWithTextSearch(new TenantId(tenantId), EDGE_BY_CUSTOMER_BY_TYPE_AND_SEARCH_TEXT_COLUMN_FAMILY_NAME,
Arrays.asList(eq(EDGE_TYPE_PROPERTY, type),
eq(EDGE_CUSTOMER_ID_PROPERTY, customerId),
eq(EDGE_TENANT_ID_PROPERTY, tenantId)),
pageLink);
log.trace("Found edges [{}] by tenantId [{}], customerId [{}], type [{}] and pageLink [{}]", edgeEntities, tenantId, customerId, type, pageLink);
return DaoUtil.convertDataList(edgeEntities);
} }
@Override @Override
public ListenableFuture<List<Edge>> findEdgesByTenantIdCustomerIdAndIdsAsync(UUID tenantId, UUID customerId, List<UUID> edgeIds) { public ListenableFuture<List<Edge>> findEdgesByTenantIdCustomerIdAndIdsAsync(UUID tenantId, UUID customerId, List<UUID> edgeIds) {
return null; log.debug("Try to find edges by tenantId [{}], customerId [{}] and edges Ids [{}]", tenantId, customerId, edgeIds);
Select select = select().from(getColumnFamilyName());
Select.Where query = select.where();
query.and(eq(EDGE_TENANT_ID_PROPERTY, tenantId));
query.and(eq(EDGE_CUSTOMER_ID_PROPERTY, customerId));
query.and(in(ID_PROPERTY, edgeIds));
return findListByStatementAsync(new TenantId(tenantId), query);
} }
@Override @Override
public Optional<Edge> findEdgeByTenantIdAndName(UUID tenantId, String name) { public Optional<Edge> findEdgeByTenantIdAndName(UUID tenantId, String edgeName) {
return Optional.empty(); Select select = select().from(EDGE_BY_TENANT_AND_NAME_VIEW_NAME);
Select.Where query = select.where();
query.and(eq(EDGE_TENANT_ID_PROPERTY, tenantId));
query.and(eq(EDGE_NAME_PROPERTY, edgeName));
return Optional.ofNullable(DaoUtil.getData(findOneByStatement(new TenantId(tenantId), query)));
} }
@Override @Override
public ListenableFuture<List<EntitySubtype>> findTenantEdgeTypesAsync(UUID tenantId) { public ListenableFuture<List<EntitySubtype>> findTenantEdgeTypesAsync(UUID tenantId) {
return null; Select select = select().from(ENTITY_SUBTYPE_COLUMN_FAMILY_NAME);
Select.Where query = select.where();
query.and(eq(ENTITY_SUBTYPE_TENANT_ID_PROPERTY, tenantId));
query.and(eq(ENTITY_SUBTYPE_ENTITY_TYPE_PROPERTY, EntityType.EDGE));
query.setConsistencyLevel(cluster.getDefaultReadConsistencyLevel());
ResultSetFuture resultSetFuture = executeAsyncRead(new TenantId(tenantId), query);
return Futures.transform(resultSetFuture, new Function<ResultSet, List<EntitySubtype>>() {
@Nullable
@Override
public List<EntitySubtype> apply(@Nullable ResultSet resultSet) {
Result<EntitySubtypeEntity> result = cluster.getMapper(EntitySubtypeEntity.class).map(resultSet);
if (result != null) {
List<EntitySubtype> entitySubtypes = new ArrayList<>();
result.all().forEach((entitySubtypeEntity) ->
entitySubtypes.add(entitySubtypeEntity.toEntitySubtype())
);
return entitySubtypes;
} else {
return Collections.emptyList();
}
}
}, MoreExecutors.directExecutor());
} }
@Override @Override
public Optional<Edge> findByRoutingKey(UUID tenantId, String routingKey) { public Optional<Edge> findByRoutingKey(UUID tenantId, String routingKey) {
return Optional.empty(); Select select = select().from(EDGE_BY_TENANT_AND_ROUTING_KEY_VIEW_NAME);
Select.Where query = select.where();
query.and(eq(EDGE_TENANT_ID_PROPERTY, tenantId));
query.and(eq(EDGE_ROUTING_KEY_PROPERTY, routingKey));
return Optional.ofNullable(DaoUtil.getData(findOneByStatement(new TenantId(tenantId), query)));
} }
@Override @Override

74
dao/src/main/java/org/thingsboard/server/dao/edge/CassandraEdgeEventDao.java

@ -15,19 +15,38 @@
*/ */
package org.thingsboard.server.dao.edge; package org.thingsboard.server.dao.edge;
import com.datastax.driver.core.ResultSetFuture;
import com.datastax.driver.core.querybuilder.Insert;
import com.datastax.driver.core.querybuilder.QueryBuilder;
import com.datastax.driver.core.utils.UUIDs;
import com.google.common.util.concurrent.Futures;
import com.google.common.util.concurrent.ListenableFuture; import com.google.common.util.concurrent.ListenableFuture;
import com.google.common.util.concurrent.MoreExecutors;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import org.thingsboard.server.common.data.audit.ActionType;
import org.thingsboard.server.common.data.edge.EdgeEvent; 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.id.EdgeId;
import org.thingsboard.server.common.data.id.TenantId;
import org.thingsboard.server.common.data.page.TimePageLink; import org.thingsboard.server.common.data.page.TimePageLink;
import org.thingsboard.server.dao.DaoUtil;
import org.thingsboard.server.dao.model.ModelConstants;
import org.thingsboard.server.dao.model.nosql.EdgeEventEntity; import org.thingsboard.server.dao.model.nosql.EdgeEventEntity;
import org.thingsboard.server.dao.nosql.CassandraAbstractSearchTimeDao; import org.thingsboard.server.dao.nosql.CassandraAbstractSearchTimeDao;
import org.thingsboard.server.dao.util.NoSqlDao; import org.thingsboard.server.dao.util.NoSqlDao;
import java.util.Arrays;
import java.util.List; import java.util.List;
import java.util.Optional;
import java.util.UUID; import java.util.UUID;
import java.util.stream.Collectors;
import static com.datastax.driver.core.querybuilder.QueryBuilder.eq;
import static com.datastax.driver.core.querybuilder.QueryBuilder.ttl;
import static org.thingsboard.server.dao.model.ModelConstants.EDGE_EVENT_BY_ID_VIEW_NAME;
import static org.thingsboard.server.dao.model.ModelConstants.EDGE_EVENT_COLUMN_FAMILY_NAME; import static org.thingsboard.server.dao.model.ModelConstants.EDGE_EVENT_COLUMN_FAMILY_NAME;
@Component @Component
@ -35,6 +54,8 @@ import static org.thingsboard.server.dao.model.ModelConstants.EDGE_EVENT_COLUMN_
@NoSqlDao @NoSqlDao
public class CassandraEdgeEventDao extends CassandraAbstractSearchTimeDao<EdgeEventEntity, EdgeEvent> implements EdgeEventDao { public class CassandraEdgeEventDao extends CassandraAbstractSearchTimeDao<EdgeEventEntity, EdgeEvent> implements EdgeEventDao {
@Value("${edges.edge_events_ttl:0}")
private int edgeEventsTtl;
@Override @Override
protected Class<EdgeEventEntity> getColumnFamilyClass() { protected Class<EdgeEventEntity> getColumnFamilyClass() {
@ -46,14 +67,61 @@ public class CassandraEdgeEventDao extends CassandraAbstractSearchTimeDao<EdgeEv
return EDGE_EVENT_COLUMN_FAMILY_NAME; return EDGE_EVENT_COLUMN_FAMILY_NAME;
} }
@Override @Override
public ListenableFuture<EdgeEvent> saveAsync(EdgeEvent edgeEvent) { public ListenableFuture<EdgeEvent> saveAsync(EdgeEvent edgeEvent) {
return null; log.debug("Save edge event [{}] ", edgeEvent);
if (edgeEvent.getId() == null) {
edgeEvent.setId(new EdgeEventId(UUIDs.timeBased()));
}
if (StringUtils.isEmpty(edgeEvent.getUid())) {
edgeEvent.setUid(edgeEvent.getId().toString());
}
ListenableFuture<Optional<EdgeEvent>> optionalSave = saveAsync(edgeEvent.getTenantId(), new EdgeEventEntity(edgeEvent), edgeEventsTtl);
return Futures.transform(optionalSave, opt -> opt.orElse(null), MoreExecutors.directExecutor());
}
private ListenableFuture<Optional<EdgeEvent>> saveAsync(TenantId tenantId, EdgeEventEntity entity, int ttl) {
if (entity.getUuid() == null) {
entity.setUuid(UUIDs.timeBased());
}
Insert insert = QueryBuilder.insertInto(getColumnFamilyName())
.value(ModelConstants.ID_PROPERTY, entity.getUuid())
.value(ModelConstants.EDGE_EVENT_TENANT_ID_PROPERTY, entity.getTenantId())
.value(ModelConstants.EDGE_EVENT_EDGE_ID_PROPERTY, entity.getEdgeId())
.value(ModelConstants.EDGE_EVENT_TYPE_PROPERTY, entity.getEdgeEventType())
.value(ModelConstants.EDGE_EVENT_UID_PROPERTY, entity.getEdgeEventUid())
.value(ModelConstants.EDGE_EVENT_ENTITY_ID_PROPERTY, entity.getEntityId())
.value(ModelConstants.EDGE_EVENT_ACTION_PROPERTY, entity.getEdgeEventAction())
.value(ModelConstants.EDGE_EVENT_BODY_PROPERTY, entity.getBody());
if (ttl > 0) {
insert.using(ttl(ttl));
}
ResultSetFuture resultSetFuture = executeAsyncWrite(tenantId, insert);
return Futures.transform(resultSetFuture, rs -> {
if (rs.wasApplied()) {
return Optional.of(DaoUtil.getData(entity));
} else {
return Optional.empty();
}
}, MoreExecutors.directExecutor());
} }
@Override @Override
public List<EdgeEvent> findEdgeEvents(UUID tenantId, EdgeId edgeId, TimePageLink pageLink, boolean withTsUpdate) { public List<EdgeEvent> findEdgeEvents(UUID tenantId, EdgeId edgeId, TimePageLink pageLink, boolean withTsUpdate) {
return null; log.trace("Try to find edge events by tenant [{}], edgeId [{}] and pageLink [{}]", tenantId, edgeId, pageLink);
List<EdgeEventEntity> entities = findPageWithTimeSearch(new TenantId(tenantId), EDGE_EVENT_BY_ID_VIEW_NAME,
Arrays.asList(eq(ModelConstants.EDGE_EVENT_TENANT_ID_PROPERTY, tenantId),
eq(ModelConstants.EDGE_EVENT_EDGE_ID_PROPERTY, edgeId.getId())),
pageLink);
log.trace("Found events by tenant [{}], edgeId [{}] and pageLink [{}]", tenantId, edgeId, pageLink);
List<EdgeEvent> edgeEvents = DaoUtil.convertDataList(entities);
if (!withTsUpdate) {
return edgeEvents.stream()
.filter(edgeEvent -> !edgeEvent.getAction().equals(ActionType.TIMESERIES_UPDATED.name()))
.collect(Collectors.toList());
} else {
return edgeEvents;
}
} }
} }

11
dao/src/main/java/org/thingsboard/server/dao/model/ModelConstants.java

@ -368,6 +368,12 @@ public class ModelConstants {
public static final String EDGE_TYPE_PROPERTY = "type"; public static final String EDGE_TYPE_PROPERTY = "type";
public static final String EDGE_CONFIGURATION_PROPERTY = "configuration"; public static final String EDGE_CONFIGURATION_PROPERTY = "configuration";
public static final String EDGE_ADDITIONAL_INFO_PROPERTY = ADDITIONAL_INFO_PROPERTY; public static final String EDGE_ADDITIONAL_INFO_PROPERTY = ADDITIONAL_INFO_PROPERTY;
public static final String EDGE_BY_TENANT_AND_SEARCH_TEXT_COLUMN_FAMILY_NAME = "edge_by_tenant_and_search_text";
public static final String EDGE_BY_TENANT_BY_TYPE_AND_SEARCH_TEXT_COLUMN_FAMILY_NAME = "edge_by_tenant_by_type_and_search_text";
public static final String EDGE_BY_CUSTOMER_AND_SEARCH_TEXT_COLUMN_FAMILY_NAME = "edge_by_customer_and_search_text";
public static final String EDGE_BY_CUSTOMER_BY_TYPE_AND_SEARCH_TEXT_COLUMN_FAMILY_NAME = "edge_by_customer_by_type_and_search_text";
public static final String EDGE_BY_TENANT_AND_NAME_VIEW_NAME = "edge_by_tenant_and_name";
public static final String EDGE_BY_TENANT_AND_ROUTING_KEY_VIEW_NAME = "edge_by_tenant_and_routing_key";
public static final String EDGE_ROUTING_KEY_PROPERTY = "routing_key"; public static final String EDGE_ROUTING_KEY_PROPERTY = "routing_key";
public static final String EDGE_SECRET_PROPERTY = "secret"; public static final String EDGE_SECRET_PROPERTY = "secret";
@ -380,8 +386,11 @@ public class ModelConstants {
public static final String EDGE_EVENT_EDGE_ID_PROPERTY = "edge_id"; 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_TYPE_PROPERTY = "edge_event_type";
public static final String EDGE_EVENT_ACTION_PROPERTY = "edge_event_action"; public static final String EDGE_EVENT_ACTION_PROPERTY = "edge_event_action";
public static final String EDGE_EVENT_UID_PROPERTY = "edge_event_uid";
public static final String EDGE_EVENT_ENTITY_ID_PROPERTY = "entity_id"; public static final String EDGE_EVENT_ENTITY_ID_PROPERTY = "entity_id";
public static final String EDGE_EVENT_ENTITY_BODY_PROPERTY = "entity_body"; public static final String EDGE_EVENT_BODY_PROPERTY = "body";
public static final String EDGE_EVENT_BY_ID_VIEW_NAME = "edge_event_by_id";
/** /**
* Cassandra attributes and timeseries constants. * Cassandra attributes and timeseries constants.

10
dao/src/main/java/org/thingsboard/server/dao/model/nosql/EdgeEntity.java

@ -32,6 +32,9 @@ import org.thingsboard.server.dao.model.type.JsonCodec;
import java.util.UUID; import java.util.UUID;
import static org.thingsboard.server.dao.model.ModelConstants.DEVICE_CUSTOMER_ID_PROPERTY;
import static org.thingsboard.server.dao.model.ModelConstants.DEVICE_TENANT_ID_PROPERTY;
import static org.thingsboard.server.dao.model.ModelConstants.DEVICE_TYPE_PROPERTY;
import static org.thingsboard.server.dao.model.ModelConstants.EDGE_ADDITIONAL_INFO_PROPERTY; import static org.thingsboard.server.dao.model.ModelConstants.EDGE_ADDITIONAL_INFO_PROPERTY;
import static org.thingsboard.server.dao.model.ModelConstants.EDGE_COLUMN_FAMILY_NAME; import static org.thingsboard.server.dao.model.ModelConstants.EDGE_COLUMN_FAMILY_NAME;
import static org.thingsboard.server.dao.model.ModelConstants.EDGE_CONFIGURATION_PROPERTY; import static org.thingsboard.server.dao.model.ModelConstants.EDGE_CONFIGURATION_PROPERTY;
@ -50,21 +53,22 @@ import static org.thingsboard.server.dao.model.ModelConstants.SEARCH_TEXT_PROPER
@Table(name = EDGE_COLUMN_FAMILY_NAME) @Table(name = EDGE_COLUMN_FAMILY_NAME)
public class EdgeEntity implements SearchTextEntity<Edge> { public class EdgeEntity implements SearchTextEntity<Edge> {
@PartitionKey @PartitionKey(value = 0)
@Column(name = ID_PROPERTY) @Column(name = ID_PROPERTY)
private UUID id; private UUID id;
@ClusteringColumn @PartitionKey(value = 1)
@Column(name = EDGE_TENANT_ID_PROPERTY) @Column(name = EDGE_TENANT_ID_PROPERTY)
private UUID tenantId; private UUID tenantId;
@ClusteringColumn @PartitionKey(value = 2)
@Column(name = EDGE_CUSTOMER_ID_PROPERTY) @Column(name = EDGE_CUSTOMER_ID_PROPERTY)
private UUID customerId; private UUID customerId;
@Column(name = EDGE_ROOT_RULE_CHAIN_ID_PROPERTY) @Column(name = EDGE_ROOT_RULE_CHAIN_ID_PROPERTY)
private UUID rootRuleChainId; private UUID rootRuleChainId;
@PartitionKey(value = 3)
@Column(name = EDGE_TYPE_PROPERTY) @Column(name = EDGE_TYPE_PROPERTY)
private String type; private String type;

64
dao/src/main/java/org/thingsboard/server/dao/model/nosql/EdgeEventEntity.java

@ -23,18 +23,13 @@ import com.datastax.driver.mapping.annotations.Table;
import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.JsonNode;
import lombok.Data; import lombok.Data;
import lombok.NoArgsConstructor; 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.EdgeEvent;
import org.thingsboard.server.common.data.edge.EdgeEventType; import org.thingsboard.server.common.data.edge.EdgeEventType;
import org.thingsboard.server.common.data.id.EdgeEventId; import org.thingsboard.server.common.data.id.EdgeEventId;
import org.thingsboard.server.common.data.id.EdgeId; 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.common.data.id.TenantId;
import org.thingsboard.server.dao.model.BaseEntity; import org.thingsboard.server.dao.model.BaseEntity;
import org.thingsboard.server.dao.model.type.EdgeEventTypeCodec; 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 org.thingsboard.server.dao.model.type.JsonCodec;
import java.util.UUID; import java.util.UUID;
@ -42,17 +37,11 @@ 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_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_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_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_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_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_TENANT_ID_PROPERTY;
import static org.thingsboard.server.dao.model.ModelConstants.EDGE_EVENT_TYPE_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.EDGE_EVENT_UID_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; import static org.thingsboard.server.dao.model.ModelConstants.ID_PROPERTY;
@Data @Data
@ -71,25 +60,23 @@ public class EdgeEventEntity implements BaseEntity<EdgeEvent> {
@Column(name = EDGE_EVENT_EDGE_ID_PROPERTY) @Column(name = EDGE_EVENT_EDGE_ID_PROPERTY)
private UUID edgeId; private UUID edgeId;
@PartitionKey(value = 2) @ClusteringColumn()
@Column(name = EDGE_EVENT_TYPE_PROPERTY, codec = EdgeEventTypeCodec.class) @Column(name = EDGE_EVENT_TYPE_PROPERTY, codec = EdgeEventTypeCodec.class)
private EdgeEventType edgeEventType; private EdgeEventType edgeEventType;
@PartitionKey(value = 3) @ClusteringColumn(value = 1)
@Column(name = EDGE_EVENT_ENTITY_ID_PROPERTY)
private UUID entityId;
@ClusteringColumn()
@Column(name = EDGE_EVENT_ACTION_PROPERTY) @Column(name = EDGE_EVENT_ACTION_PROPERTY)
private String edgeEventAction; private String edgeEventAction;
// TODO @ClusteringColumn(value = 2)
@ClusteringColumn(value = 1) @Column(name = EDGE_EVENT_UID_PROPERTY)
@Column(name = EVENT_UID_PROPERTY) private String edgeEventUid;
private String eventUid;
@Column(name = EDGE_EVENT_ENTITY_ID_PROPERTY)
private UUID entityId;
@Column(name = EDGE_EVENT_ENTITY_BODY_PROPERTY, codec = JsonCodec.class) @Column(name = EDGE_EVENT_BODY_PROPERTY, codec = JsonCodec.class)
private JsonNode entityBody; private JsonNode body;
public EdgeEventEntity(EdgeEvent edgeEvent) { public EdgeEventEntity(EdgeEvent edgeEvent) {
if (edgeEvent.getId() != null) { if (edgeEvent.getId() != null) {
@ -101,13 +88,11 @@ public class EdgeEventEntity implements BaseEntity<EdgeEvent> {
if (edgeEvent.getEdgeId() != null) { if (edgeEvent.getEdgeId() != null) {
this.edgeId = edgeEvent.getEdgeId().getId(); this.edgeId = edgeEvent.getEdgeId().getId();
} }
// if (event.getEntityId() != null) { this.entityId = edgeEvent.getEntityId();
// this.entityType = event.getEntityId().getEntityType(); this.edgeEventType = edgeEvent.getType();
// this.entityId = event.getEntityId().getId(); this.edgeEventAction = edgeEvent.getAction();
// } this.edgeEventUid = edgeEvent.getUid();
// this.edgeEventType = edgeEvent.getEdgeEventType(); this.body = edgeEvent.getBody();
// this.edgeEventAction = edgeEvent.getEdgeEventAction();
// this.entityBody = edgeEvent.getEntityBody();
} }
@Override @Override
@ -123,13 +108,14 @@ public class EdgeEventEntity implements BaseEntity<EdgeEvent> {
@Override @Override
public EdgeEvent toData() { public EdgeEvent toData() {
EdgeEvent edgeEvent = new EdgeEvent(new EdgeEventId(id)); EdgeEvent edgeEvent = new EdgeEvent(new EdgeEventId(id));
// edgeEvent.setCreatedTime(UUIDs.unixTimestamp(id)); edgeEvent.setCreatedTime(UUIDs.unixTimestamp(id));
// edgeEvent.setTenantId(new TenantId(tenantId)); edgeEvent.setTenantId(new TenantId(tenantId));
// edgeEvent.setEdgeId(new EdgeId(edgeId)); edgeEvent.setEdgeId(new EdgeId(edgeId));
// edgeEvent.setEntityId(entityId); edgeEvent.setEntityId(entityId);
// event.setBody(body); edgeEvent.setType(edgeEventType);
// event.setType(eventType); edgeEvent.setAction(edgeEventAction);
// event.setUid(eventUid); edgeEvent.setBody(body);
edgeEvent.setUid(edgeEventUid);
return edgeEvent; return edgeEvent;
} }
} }

23
dao/src/main/java/org/thingsboard/server/dao/model/sql/EdgeEventEntity.java

@ -41,11 +41,13 @@ 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_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_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_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_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_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_TENANT_ID_PROPERTY;
import static org.thingsboard.server.dao.model.ModelConstants.EDGE_EVENT_TYPE_PROPERTY; import static org.thingsboard.server.dao.model.ModelConstants.EDGE_EVENT_TYPE_PROPERTY;
import static org.thingsboard.server.dao.model.ModelConstants.EDGE_EVENT_UID_PROPERTY;
import static org.thingsboard.server.dao.model.ModelConstants.EPOCH_DIFF; import static org.thingsboard.server.dao.model.ModelConstants.EPOCH_DIFF;
import static org.thingsboard.server.dao.model.ModelConstants.EVENT_UID_PROPERTY;
import static org.thingsboard.server.dao.model.ModelConstants.TS_COLUMN; import static org.thingsboard.server.dao.model.ModelConstants.TS_COLUMN;
@Data @Data
@ -73,9 +75,12 @@ public class EdgeEventEntity extends BaseSqlEntity<EdgeEvent> implements BaseEnt
private String edgeEventAction; private String edgeEventAction;
@Type(type = "json") @Type(type = "json")
@Column(name = EDGE_EVENT_ENTITY_BODY_PROPERTY) @Column(name = EDGE_EVENT_BODY_PROPERTY)
private JsonNode entityBody; private JsonNode entityBody;
@Column(name = EDGE_EVENT_UID_PROPERTY)
private String edgeEventUid;
@Column(name = TS_COLUMN) @Column(name = TS_COLUMN)
private long ts; private long ts;
@ -95,9 +100,10 @@ public class EdgeEventEntity extends BaseSqlEntity<EdgeEvent> implements BaseEnt
if (edgeEvent.getEntityId() != null) { if (edgeEvent.getEntityId() != null) {
this.entityId = toString(edgeEvent.getEntityId()); this.entityId = toString(edgeEvent.getEntityId());
} }
this.edgeEventType = edgeEvent.getEdgeEventType(); this.edgeEventType = edgeEvent.getType();
this.edgeEventAction = edgeEvent.getEdgeEventAction(); this.edgeEventAction = edgeEvent.getAction();
this.entityBody = edgeEvent.getEntityBody(); this.entityBody = edgeEvent.getBody();
this.edgeEventUid = edgeEvent.getUid();
} }
@Override @Override
@ -109,9 +115,10 @@ public class EdgeEventEntity extends BaseSqlEntity<EdgeEvent> implements BaseEnt
if (entityId != null) { if (entityId != null) {
edgeEvent.setEntityId(toUUID(entityId)); edgeEvent.setEntityId(toUUID(entityId));
} }
edgeEvent.setEdgeEventType(edgeEventType); edgeEvent.setType(edgeEventType);
edgeEvent.setEdgeEventAction(edgeEventAction); edgeEvent.setAction(edgeEventAction);
edgeEvent.setEntityBody(entityBody); edgeEvent.setBody(entityBody);
edgeEvent.setUid(edgeEventUid);
return edgeEvent; return edgeEvent;
} }

4
dao/src/main/java/org/thingsboard/server/dao/nosql/CassandraAbstractDao.java

@ -35,8 +35,10 @@ import org.thingsboard.server.dao.model.type.ComponentLifecycleStateCodec;
import org.thingsboard.server.dao.model.type.ComponentScopeCodec; import org.thingsboard.server.dao.model.type.ComponentScopeCodec;
import org.thingsboard.server.dao.model.type.ComponentTypeCodec; import org.thingsboard.server.dao.model.type.ComponentTypeCodec;
import org.thingsboard.server.dao.model.type.DeviceCredentialsTypeCodec; import org.thingsboard.server.dao.model.type.DeviceCredentialsTypeCodec;
import org.thingsboard.server.dao.model.type.EdgeEventTypeCodec;
import org.thingsboard.server.dao.model.type.EntityTypeCodec; import org.thingsboard.server.dao.model.type.EntityTypeCodec;
import org.thingsboard.server.dao.model.type.JsonCodec; import org.thingsboard.server.dao.model.type.JsonCodec;
import org.thingsboard.server.dao.model.type.RuleChainTypeCodec;
import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap; import java.util.concurrent.ConcurrentMap;
@ -71,6 +73,8 @@ public abstract class CassandraAbstractDao {
registerCodecIfNotFound(registry, new ComponentTypeCodec()); registerCodecIfNotFound(registry, new ComponentTypeCodec());
registerCodecIfNotFound(registry, new ComponentScopeCodec()); registerCodecIfNotFound(registry, new ComponentScopeCodec());
registerCodecIfNotFound(registry, new EntityTypeCodec()); registerCodecIfNotFound(registry, new EntityTypeCodec());
registerCodecIfNotFound(registry, new EdgeEventTypeCodec());
registerCodecIfNotFound(registry, new RuleChainTypeCodec());
} }
return session; return session;
} }

6
dao/src/main/java/org/thingsboard/server/dao/rule/BaseRuleChainService.java

@ -19,14 +19,12 @@ import com.google.common.base.Function;
import com.google.common.util.concurrent.Futures; import com.google.common.util.concurrent.Futures;
import com.google.common.util.concurrent.ListenableFuture; import com.google.common.util.concurrent.ListenableFuture;
import com.google.common.util.concurrent.MoreExecutors; import com.google.common.util.concurrent.MoreExecutors;
import jnr.ffi.annotations.In;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.thingsboard.server.common.data.BaseData; import org.thingsboard.server.common.data.BaseData;
import org.thingsboard.server.common.data.EntityType; import org.thingsboard.server.common.data.EntityType;
import org.thingsboard.server.common.data.ShortEdgeInfo;
import org.thingsboard.server.common.data.Tenant; import org.thingsboard.server.common.data.Tenant;
import org.thingsboard.server.common.data.edge.Edge; import org.thingsboard.server.common.data.edge.Edge;
import org.thingsboard.server.common.data.id.EdgeId; import org.thingsboard.server.common.data.id.EdgeId;
@ -46,14 +44,11 @@ import org.thingsboard.server.common.data.rule.RuleChainConnectionInfo;
import org.thingsboard.server.common.data.rule.RuleChainMetaData; import org.thingsboard.server.common.data.rule.RuleChainMetaData;
import org.thingsboard.server.common.data.rule.RuleChainType; import org.thingsboard.server.common.data.rule.RuleChainType;
import org.thingsboard.server.common.data.rule.RuleNode; import org.thingsboard.server.common.data.rule.RuleNode;
import org.thingsboard.server.dao.edge.EdgeDao;
import org.thingsboard.server.dao.edge.EdgeService; import org.thingsboard.server.dao.edge.EdgeService;
import org.thingsboard.server.dao.entity.AbstractEntityService; import org.thingsboard.server.dao.entity.AbstractEntityService;
import org.thingsboard.server.dao.exception.DataValidationException; import org.thingsboard.server.dao.exception.DataValidationException;
import org.thingsboard.server.dao.relation.RelationDao;
import org.thingsboard.server.dao.service.DataValidator; import org.thingsboard.server.dao.service.DataValidator;
import org.thingsboard.server.dao.service.PaginatedRemover; import org.thingsboard.server.dao.service.PaginatedRemover;
import org.thingsboard.server.dao.service.TimePaginatedRemover;
import org.thingsboard.server.dao.service.Validator; import org.thingsboard.server.dao.service.Validator;
import org.thingsboard.server.dao.tenant.TenantDao; import org.thingsboard.server.dao.tenant.TenantDao;
@ -65,7 +60,6 @@ import java.util.Map;
import java.util.concurrent.ExecutionException; import java.util.concurrent.ExecutionException;
import static org.thingsboard.server.dao.service.Validator.validateId; import static org.thingsboard.server.dao.service.Validator.validateId;
import static org.thingsboard.server.dao.service.Validator.validateString;
/** /**
* Created by igor on 3/12/18. * Created by igor on 3/12/18.

33
dao/src/main/resources/cassandra/schema-entities.cql

@ -730,9 +730,13 @@ CREATE TABLE IF NOT EXISTS thingsboard.edge (
id timeuuid, id timeuuid,
tenant_id timeuuid, tenant_id timeuuid,
customer_id timeuuid, customer_id timeuuid,
name text, root_rule_chain_id timeuuid,
type text, type text,
name text,
label text,
search_text text, search_text text,
routing_key text,
secret text,
configuration text, configuration text,
additional_info text, additional_info text,
PRIMARY KEY (id, tenant_id, customer_id, type) PRIMARY KEY (id, tenant_id, customer_id, type)
@ -745,6 +749,13 @@ CREATE MATERIALIZED VIEW IF NOT EXISTS thingsboard.edge_by_tenant_and_name AS
PRIMARY KEY ( tenant_id, name, id, customer_id, type) PRIMARY KEY ( tenant_id, name, id, customer_id, type)
WITH CLUSTERING ORDER BY ( name ASC, id DESC, customer_id DESC); WITH CLUSTERING ORDER BY ( name ASC, id DESC, customer_id DESC);
CREATE MATERIALIZED VIEW IF NOT EXISTS thingsboard.edge_by_tenant_and_routing_key AS
SELECT *
from thingsboard.edge
WHERE tenant_id IS NOT NULL AND customer_id IS NOT NULL AND type IS NOT NULL AND routing_key IS NOT NULL AND id IS NOT NULL
PRIMARY KEY ( tenant_id, routing_key, id, customer_id, type)
WITH CLUSTERING ORDER BY ( routing_key ASC, id DESC, customer_id DESC);
CREATE MATERIALIZED VIEW IF NOT EXISTS thingsboard.edge_by_tenant_and_search_text AS CREATE MATERIALIZED VIEW IF NOT EXISTS thingsboard.edge_by_tenant_and_search_text AS
SELECT * SELECT *
from thingsboard.edge from thingsboard.edge
@ -772,3 +783,23 @@ CREATE MATERIALIZED VIEW IF NOT EXISTS thingsboard.edge_by_customer_by_type_and_
WHERE tenant_id IS NOT NULL AND customer_id IS NOT NULL AND type IS NOT NULL AND search_text IS NOT NULL AND id IS NOT NULL WHERE tenant_id IS NOT NULL AND customer_id IS NOT NULL AND type IS NOT NULL AND search_text IS NOT NULL AND id IS NOT NULL
PRIMARY KEY ( customer_id, tenant_id, type, search_text, id ) PRIMARY KEY ( customer_id, tenant_id, type, search_text, id )
WITH CLUSTERING ORDER BY ( tenant_id DESC, type ASC, search_text ASC, id DESC ); WITH CLUSTERING ORDER BY ( tenant_id DESC, type ASC, search_text ASC, id DESC );
CREATE TABLE IF NOT EXISTS thingsboard.edge_event (
id timeuuid,
tenant_id timeuuid,
edge_id timeuuid,
edge_event_type text,
edge_event_action text,
edge_event_uid text,
entity_id timeuuid,
body text,
PRIMARY KEY ((tenant_id, edge_id), edge_event_type, edge_event_uid)
);
CREATE MATERIALIZED VIEW IF NOT EXISTS thingsboard.edge_event_by_id AS
SELECT *
FROM thingsboard.edge_event
WHERE tenant_id IS NOT NULL AND edge_id IS NOT NULL AND edge_event_type IS NOT NULL
AND id IS NOT NULL AND edge_event_uid IS NOT NULL
PRIMARY KEY ((tenant_id, edge_id), id, edge_event_type, edge_event_uid)
WITH CLUSTERING ORDER BY (id ASC);

5
dao/src/main/resources/sql/schema-entities-hsql.sql

@ -275,9 +275,10 @@ CREATE TABLE IF NOT EXISTS edge_event (
id varchar(31) NOT NULL CONSTRAINT edge_event_pkey PRIMARY KEY, id varchar(31) NOT NULL CONSTRAINT edge_event_pkey PRIMARY KEY,
edge_id varchar(31), edge_id varchar(31),
edge_event_type varchar(255), edge_event_type varchar(255),
edge_event_uid varchar(255),
entity_id varchar(31), entity_id varchar(31),
edge_event_action varchar(255), edge_event_action varchar(255),
entity_body varchar(10000000), body varchar(10000000),
tenant_id varchar(31), tenant_id varchar(31),
ts bigint NOT NULL ts bigint NOT NULL
); );

4
dao/src/main/resources/sql/schema-entities.sql

@ -275,14 +275,16 @@ CREATE TABLE IF NOT EXISTS edge_event (
id varchar(31) NOT NULL CONSTRAINT edge_event_pkey PRIMARY KEY, id varchar(31) NOT NULL CONSTRAINT edge_event_pkey PRIMARY KEY,
edge_id varchar(31), edge_id varchar(31),
edge_event_type varchar(255), edge_event_type varchar(255),
edge_event_uid varchar(255),
entity_id varchar(31), entity_id varchar(31),
edge_event_action varchar(255), edge_event_action varchar(255),
entity_body varchar(10000000), body varchar(10000000),
tenant_id varchar(31), tenant_id varchar(31),
ts bigint NOT NULL ts bigint NOT NULL
); );
CREATE OR REPLACE PROCEDURE cleanup_events_by_ttl(IN ttl bigint, IN debug_ttl bigint, INOUT deleted bigint) CREATE OR REPLACE PROCEDURE cleanup_events_by_ttl(IN ttl bigint, IN debug_ttl bigint, INOUT deleted bigint)
LANGUAGE plpgsql AS LANGUAGE plpgsql AS
$$ $$

3
dao/src/test/java/org/thingsboard/server/dao/NoSqlDaoServiceTestSuite.java

@ -25,8 +25,7 @@ import java.util.Arrays;
@RunWith(ClasspathSuite.class) @RunWith(ClasspathSuite.class)
@ClassnameFilters({ @ClassnameFilters({
// TODO: voba - fix before final test on cassandra "org.thingsboard.server.dao.service.nosql.*ServiceNoSqlTest"
"org.thingsboard.server.dao.service.*VOBA_FIX_BEFORE_FINAL_TESTServiceNoSqlTest"
}) })
public class NoSqlDaoServiceTestSuite { public class NoSqlDaoServiceTestSuite {

14
dao/src/test/java/org/thingsboard/server/dao/service/BaseEdgeEventServiceTest.java

@ -46,9 +46,9 @@ public abstract class BaseEdgeEventServiceTest extends AbstractServiceTest {
Assert.assertEquals(saved.getTenantId(), edgeEvent.getTenantId()); Assert.assertEquals(saved.getTenantId(), edgeEvent.getTenantId());
Assert.assertEquals(saved.getEdgeId(), edgeEvent.getEdgeId()); Assert.assertEquals(saved.getEdgeId(), edgeEvent.getEdgeId());
Assert.assertEquals(saved.getEntityId(), edgeEvent.getEntityId()); Assert.assertEquals(saved.getEntityId(), edgeEvent.getEntityId());
Assert.assertEquals(saved.getEdgeEventType(), edgeEvent.getEdgeEventType()); Assert.assertEquals(saved.getType(), edgeEvent.getType());
Assert.assertEquals(saved.getEdgeEventAction(), edgeEvent.getEdgeEventAction()); Assert.assertEquals(saved.getAction(), edgeEvent.getAction());
Assert.assertEquals(saved.getEntityBody(), edgeEvent.getEntityBody()); Assert.assertEquals(saved.getBody(), edgeEvent.getBody());
} }
protected EdgeEvent generateEdgeEvent(TenantId tenantId, EdgeId edgeId, EntityId entityId, String edgeEventAction) throws IOException { protected EdgeEvent generateEdgeEvent(TenantId tenantId, EdgeId edgeId, EntityId entityId, String edgeEventAction) throws IOException {
@ -59,9 +59,9 @@ public abstract class BaseEdgeEventServiceTest extends AbstractServiceTest {
edgeEvent.setTenantId(tenantId); edgeEvent.setTenantId(tenantId);
edgeEvent.setEdgeId(edgeId); edgeEvent.setEdgeId(edgeId);
edgeEvent.setEntityId(entityId.getId()); edgeEvent.setEntityId(entityId.getId());
edgeEvent.setEdgeEventType(EdgeEventType.DEVICE); edgeEvent.setType(EdgeEventType.DEVICE);
edgeEvent.setEdgeEventAction(edgeEventAction); edgeEvent.setAction(edgeEventAction);
edgeEvent.setEntityBody(readFromResource("TestJsonData.json")); edgeEvent.setBody(readFromResource("TestJsonData.json"));
return edgeEvent; return edgeEvent;
} }
@ -109,7 +109,7 @@ public abstract class BaseEdgeEventServiceTest extends AbstractServiceTest {
TimePageLink pageLink = new TimePageLink(1); TimePageLink pageLink = new TimePageLink(1);
EdgeEvent edgeEventWithTsUpdate = generateEdgeEvent(tenantId, edgeId, deviceId, ActionType.TIMESERIES_UPDATED.name()); EdgeEvent edgeEventWithTsUpdate = generateEdgeEvent(tenantId, edgeId, deviceId, ActionType.TIMESERIES_UPDATED.name());
edgeEventService.saveAsync(edgeEventWithTsUpdate); edgeEventService.saveAsync(edgeEventWithTsUpdate).get();
TimePageData<EdgeEvent> allEdgeEvents = edgeEventService.findEdgeEvents(tenantId, edgeId, pageLink, true); TimePageData<EdgeEvent> allEdgeEvents = edgeEventService.findEdgeEvents(tenantId, edgeId, pageLink, true);
TimePageData<EdgeEvent> edgeEventsWithoutTsUpdate = edgeEventService.findEdgeEvents(tenantId, edgeId, pageLink, false); TimePageData<EdgeEvent> edgeEventsWithoutTsUpdate = edgeEventService.findEdgeEvents(tenantId, edgeId, pageLink, false);

2
dao/src/test/resources/application-test.properties

@ -45,3 +45,5 @@ security.claim.duration=60000
database.ts_max_intervals=700 database.ts_max_intervals=700
sql.remove_null_chars=true sql.remove_null_chars=true
edges.rpc.enabled=true

11
rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/action/TbAssignToCustomerNode.java

@ -22,9 +22,13 @@ import org.thingsboard.rule.engine.api.TbNodeConfiguration;
import org.thingsboard.rule.engine.api.TbNodeException; import org.thingsboard.rule.engine.api.TbNodeException;
import org.thingsboard.rule.engine.api.util.TbNodeUtils; import org.thingsboard.rule.engine.api.util.TbNodeUtils;
import org.thingsboard.server.common.data.EntityType; import org.thingsboard.server.common.data.EntityType;
import org.thingsboard.server.common.data.id.*; import org.thingsboard.server.common.data.id.AssetId;
import org.thingsboard.server.common.data.id.CustomerId;
import org.thingsboard.server.common.data.id.DashboardId;
import org.thingsboard.server.common.data.id.DeviceId;
import org.thingsboard.server.common.data.id.EdgeId;
import org.thingsboard.server.common.data.id.EntityViewId;
import org.thingsboard.server.common.data.plugin.ComponentType; import org.thingsboard.server.common.data.plugin.ComponentType;
import org.thingsboard.server.common.data.rule.RuleChainType;
import org.thingsboard.server.common.msg.TbMsg; import org.thingsboard.server.common.msg.TbMsg;
@Slf4j @Slf4j
@ -37,7 +41,8 @@ import org.thingsboard.server.common.msg.TbMsg;
"Will create new Customer if it doesn't exists and 'Create new Customer if not exists' is set to true.", "Will create new Customer if it doesn't exists and 'Create new Customer if not exists' is set to true.",
uiResources = {"static/rulenode/rulenode-core-config.js"}, uiResources = {"static/rulenode/rulenode-core-config.js"},
configDirective = "tbActionNodeAssignToCustomerConfig", configDirective = "tbActionNodeAssignToCustomerConfig",
icon = "add_circle") icon = "add_circle"
)
public class TbAssignToCustomerNode extends TbAbstractCustomerActionNode<TbAssignToCustomerNodeConfiguration> { public class TbAssignToCustomerNode extends TbAbstractCustomerActionNode<TbAssignToCustomerNodeConfiguration> {
@Override @Override

4
rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/action/TbClearAlarmNode.java

@ -29,7 +29,6 @@ import org.thingsboard.server.common.data.alarm.Alarm;
import org.thingsboard.server.common.data.alarm.AlarmStatus; import org.thingsboard.server.common.data.alarm.AlarmStatus;
import org.thingsboard.server.common.data.id.AlarmId; import org.thingsboard.server.common.data.id.AlarmId;
import org.thingsboard.server.common.data.plugin.ComponentType; import org.thingsboard.server.common.data.plugin.ComponentType;
import org.thingsboard.server.common.data.rule.RuleChainType;
import org.thingsboard.server.common.msg.TbMsg; import org.thingsboard.server.common.msg.TbMsg;
@Slf4j @Slf4j
@ -46,7 +45,8 @@ import org.thingsboard.server.common.msg.TbMsg;
"Message metadata can be accessed via <code>metadata</code> property. For example <code>'name = ' + metadata.customerName;</code>.", "Message metadata can be accessed via <code>metadata</code> property. For example <code>'name = ' + metadata.customerName;</code>.",
uiResources = {"static/rulenode/rulenode-core-config.js"}, uiResources = {"static/rulenode/rulenode-core-config.js"},
configDirective = "tbActionNodeClearAlarmConfig", configDirective = "tbActionNodeClearAlarmConfig",
icon = "notifications_off") icon = "notifications_off"
)
public class TbClearAlarmNode extends TbAbstractAlarmNode<TbClearAlarmNodeConfiguration> { public class TbClearAlarmNode extends TbAbstractAlarmNode<TbClearAlarmNodeConfiguration> {
@Override @Override

6
rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/action/TbCopyAttributesToEntityViewNode.java

@ -21,19 +21,18 @@ import com.google.gson.JsonElement;
import com.google.gson.JsonParser; import com.google.gson.JsonParser;
import com.google.gson.JsonPrimitive; import com.google.gson.JsonPrimitive;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.thingsboard.common.util.DonAsynchron;
import org.thingsboard.rule.engine.api.EmptyNodeConfiguration; import org.thingsboard.rule.engine.api.EmptyNodeConfiguration;
import org.thingsboard.rule.engine.api.RuleNode; import org.thingsboard.rule.engine.api.RuleNode;
import org.thingsboard.rule.engine.api.TbContext; import org.thingsboard.rule.engine.api.TbContext;
import org.thingsboard.rule.engine.api.TbNode; import org.thingsboard.rule.engine.api.TbNode;
import org.thingsboard.rule.engine.api.TbNodeConfiguration; import org.thingsboard.rule.engine.api.TbNodeConfiguration;
import org.thingsboard.rule.engine.api.TbNodeException; import org.thingsboard.rule.engine.api.TbNodeException;
import org.thingsboard.common.util.DonAsynchron;
import org.thingsboard.rule.engine.api.util.TbNodeUtils; import org.thingsboard.rule.engine.api.util.TbNodeUtils;
import org.thingsboard.server.common.data.DataConstants; import org.thingsboard.server.common.data.DataConstants;
import org.thingsboard.server.common.data.EntityView; import org.thingsboard.server.common.data.EntityView;
import org.thingsboard.server.common.data.kv.AttributeKvEntry; import org.thingsboard.server.common.data.kv.AttributeKvEntry;
import org.thingsboard.server.common.data.plugin.ComponentType; import org.thingsboard.server.common.data.plugin.ComponentType;
import org.thingsboard.server.common.data.rule.RuleChainType;
import org.thingsboard.server.common.msg.TbMsg; import org.thingsboard.server.common.msg.TbMsg;
import org.thingsboard.server.common.msg.session.SessionMsgType; import org.thingsboard.server.common.msg.session.SessionMsgType;
import org.thingsboard.server.common.transport.adaptor.JsonConverter; import org.thingsboard.server.common.transport.adaptor.JsonConverter;
@ -57,7 +56,8 @@ import static org.thingsboard.rule.engine.api.TbRelationTypes.SUCCESS;
"Changes message originator to related entity view and produces new messages according to count of updated entity views", "Changes message originator to related entity view and produces new messages according to count of updated entity views",
uiResources = {"static/rulenode/rulenode-core-config.js"}, uiResources = {"static/rulenode/rulenode-core-config.js"},
configDirective = "tbNodeEmptyConfig", configDirective = "tbNodeEmptyConfig",
icon = "content_copy") icon = "content_copy"
)
public class TbCopyAttributesToEntityViewNode implements TbNode { public class TbCopyAttributesToEntityViewNode implements TbNode {
EmptyNodeConfiguration config; EmptyNodeConfiguration config;

4
rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/action/TbCreateAlarmNode.java

@ -31,7 +31,6 @@ import org.thingsboard.server.common.data.alarm.Alarm;
import org.thingsboard.server.common.data.alarm.AlarmStatus; import org.thingsboard.server.common.data.alarm.AlarmStatus;
import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.common.data.id.TenantId;
import org.thingsboard.server.common.data.plugin.ComponentType; import org.thingsboard.server.common.data.plugin.ComponentType;
import org.thingsboard.server.common.data.rule.RuleChainType;
import org.thingsboard.server.common.msg.TbMsg; import org.thingsboard.server.common.msg.TbMsg;
import java.io.IOException; import java.io.IOException;
@ -51,7 +50,8 @@ import java.util.List;
"Message metadata can be accessed via <code>metadata</code> property. For example <code>'name = ' + metadata.customerName;</code>.", "Message metadata can be accessed via <code>metadata</code> property. For example <code>'name = ' + metadata.customerName;</code>.",
uiResources = {"static/rulenode/rulenode-core-config.js"}, uiResources = {"static/rulenode/rulenode-core-config.js"},
configDirective = "tbActionNodeCreateAlarmConfig", configDirective = "tbActionNodeCreateAlarmConfig",
icon = "notifications_active") icon = "notifications_active"
)
public class TbCreateAlarmNode extends TbAbstractAlarmNode<TbCreateAlarmNodeConfiguration> { public class TbCreateAlarmNode extends TbAbstractAlarmNode<TbCreateAlarmNodeConfiguration> {
private static ObjectMapper mapper = new ObjectMapper(); private static ObjectMapper mapper = new ObjectMapper();

4
rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/action/TbCreateRelationNode.java

@ -34,7 +34,6 @@ import org.thingsboard.server.common.data.id.TenantId;
import org.thingsboard.server.common.data.plugin.ComponentType; import org.thingsboard.server.common.data.plugin.ComponentType;
import org.thingsboard.server.common.data.relation.EntityRelation; import org.thingsboard.server.common.data.relation.EntityRelation;
import org.thingsboard.server.common.data.relation.RelationTypeGroup; import org.thingsboard.server.common.data.relation.RelationTypeGroup;
import org.thingsboard.server.common.data.rule.RuleChainType;
import org.thingsboard.server.common.msg.TbMsg; import org.thingsboard.server.common.msg.TbMsg;
import java.util.ArrayList; import java.util.ArrayList;
@ -54,7 +53,8 @@ import java.util.List;
nodeDetails = "If the relation already exists or successfully created - Message send via <b>Success</b> chain, otherwise <b>Failure</b> chain will be used.", nodeDetails = "If the relation already exists or successfully created - Message send via <b>Success</b> chain, otherwise <b>Failure</b> chain will be used.",
uiResources = {"static/rulenode/rulenode-core-config.js"}, uiResources = {"static/rulenode/rulenode-core-config.js"},
configDirective = "tbActionNodeCreateRelationConfig", configDirective = "tbActionNodeCreateRelationConfig",
icon = "add_circle") icon = "add_circle"
)
public class TbCreateRelationNode extends TbAbstractRelationActionNode<TbCreateRelationNodeConfiguration> { public class TbCreateRelationNode extends TbAbstractRelationActionNode<TbCreateRelationNodeConfiguration> {
@Override @Override

4
rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/action/TbDeleteRelationNode.java

@ -27,7 +27,6 @@ import org.thingsboard.rule.engine.util.EntityContainer;
import org.thingsboard.server.common.data.plugin.ComponentType; import org.thingsboard.server.common.data.plugin.ComponentType;
import org.thingsboard.server.common.data.relation.EntityRelation; import org.thingsboard.server.common.data.relation.EntityRelation;
import org.thingsboard.server.common.data.relation.RelationTypeGroup; import org.thingsboard.server.common.data.relation.RelationTypeGroup;
import org.thingsboard.server.common.data.rule.RuleChainType;
import org.thingsboard.server.common.msg.TbMsg; import org.thingsboard.server.common.msg.TbMsg;
import java.util.ArrayList; import java.util.ArrayList;
@ -44,7 +43,8 @@ import java.util.List;
nodeDetails = "If the relation(s) successfully deleted - Message send via <b>Success</b> chain, otherwise <b>Failure</b> chain will be used.", nodeDetails = "If the relation(s) successfully deleted - Message send via <b>Success</b> chain, otherwise <b>Failure</b> chain will be used.",
uiResources = {"static/rulenode/rulenode-core-config.js"}, uiResources = {"static/rulenode/rulenode-core-config.js"},
configDirective = "tbActionNodeDeleteRelationConfig", configDirective = "tbActionNodeDeleteRelationConfig",
icon = "remove_circle") icon = "remove_circle"
)
public class TbDeleteRelationNode extends TbAbstractRelationActionNode<TbDeleteRelationNodeConfiguration> { public class TbDeleteRelationNode extends TbAbstractRelationActionNode<TbDeleteRelationNodeConfiguration> {
@Override @Override

12
rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/action/TbLogNode.java

@ -17,14 +17,17 @@ package org.thingsboard.rule.engine.action;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.thingsboard.common.util.ListeningExecutor; import org.thingsboard.common.util.ListeningExecutor;
import org.thingsboard.rule.engine.api.RuleNode;
import org.thingsboard.rule.engine.api.ScriptEngine;
import org.thingsboard.rule.engine.api.TbContext;
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.rule.engine.api.util.TbNodeUtils;
import org.thingsboard.rule.engine.api.*;
import org.thingsboard.server.common.data.plugin.ComponentType; import org.thingsboard.server.common.data.plugin.ComponentType;
import org.thingsboard.server.common.data.rule.RuleChainType;
import org.thingsboard.server.common.msg.TbMsg; import org.thingsboard.server.common.msg.TbMsg;
import static org.thingsboard.common.util.DonAsynchron.withCallback; import static org.thingsboard.common.util.DonAsynchron.withCallback;
import static org.thingsboard.rule.engine.api.TbRelationTypes.SUCCESS;
@Slf4j @Slf4j
@RuleNode( @RuleNode(
@ -37,7 +40,8 @@ import static org.thingsboard.rule.engine.api.TbRelationTypes.SUCCESS;
"Message metadata can be accessed via <code>metadata</code> property. For example <code>'name = ' + metadata.customerName;</code>.", "Message metadata can be accessed via <code>metadata</code> property. For example <code>'name = ' + metadata.customerName;</code>.",
uiResources = {"static/rulenode/rulenode-core-config.js"}, uiResources = {"static/rulenode/rulenode-core-config.js"},
configDirective = "tbActionNodeLogConfig", configDirective = "tbActionNodeLogConfig",
icon = "menu") icon = "menu"
)
public class TbLogNode implements TbNode { public class TbLogNode implements TbNode {
private TbLogNodeConfiguration config; private TbLogNodeConfiguration config;

12
rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/action/TbMsgCountNode.java

@ -15,16 +15,17 @@
*/ */
package org.thingsboard.rule.engine.action; package org.thingsboard.rule.engine.action;
import com.datastax.driver.core.utils.UUIDs;
import com.google.gson.Gson; import com.google.gson.Gson;
import com.google.gson.JsonObject; import com.google.gson.JsonObject;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.thingsboard.rule.engine.api.*; import org.thingsboard.rule.engine.api.RuleNode;
import org.thingsboard.rule.engine.api.TbContext;
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.rule.engine.api.util.TbNodeUtils;
import org.thingsboard.server.common.data.plugin.ComponentType; import org.thingsboard.server.common.data.plugin.ComponentType;
import org.thingsboard.server.common.data.rule.RuleChainType;
import org.thingsboard.server.common.msg.TbMsg; 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.TbMsgMetaData;
import org.thingsboard.server.common.msg.queue.ServiceQueue; import org.thingsboard.server.common.msg.queue.ServiceQueue;
import org.thingsboard.server.common.msg.session.SessionMsgType; import org.thingsboard.server.common.msg.session.SessionMsgType;
@ -44,7 +45,8 @@ import static org.thingsboard.rule.engine.api.TbRelationTypes.SUCCESS;
nodeDetails = "Count incoming messages for specified interval and produces POST_TELEMETRY_REQUEST msg with messages count", nodeDetails = "Count incoming messages for specified interval and produces POST_TELEMETRY_REQUEST msg with messages count",
icon = "functions", icon = "functions",
uiResources = {"static/rulenode/rulenode-core-config.js"}, uiResources = {"static/rulenode/rulenode-core-config.js"},
configDirective = "tbActionNodeMsgCountConfig") configDirective = "tbActionNodeMsgCountConfig"
)
public class TbMsgCountNode implements TbNode { public class TbMsgCountNode implements TbNode {
private static final String TB_MSG_COUNT_NODE_MSG = "TbMsgCountNodeMsg"; private static final String TB_MSG_COUNT_NODE_MSG = "TbMsgCountNodeMsg";

4
rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/action/TbSaveToCustomCassandraTableNode.java

@ -48,8 +48,10 @@ import org.thingsboard.server.dao.model.type.ComponentLifecycleStateCodec;
import org.thingsboard.server.dao.model.type.ComponentScopeCodec; import org.thingsboard.server.dao.model.type.ComponentScopeCodec;
import org.thingsboard.server.dao.model.type.ComponentTypeCodec; import org.thingsboard.server.dao.model.type.ComponentTypeCodec;
import org.thingsboard.server.dao.model.type.DeviceCredentialsTypeCodec; import org.thingsboard.server.dao.model.type.DeviceCredentialsTypeCodec;
import org.thingsboard.server.dao.model.type.EdgeEventTypeCodec;
import org.thingsboard.server.dao.model.type.EntityTypeCodec; import org.thingsboard.server.dao.model.type.EntityTypeCodec;
import org.thingsboard.server.dao.model.type.JsonCodec; import org.thingsboard.server.dao.model.type.JsonCodec;
import org.thingsboard.server.dao.model.type.RuleChainTypeCodec;
import org.thingsboard.server.dao.nosql.CassandraStatementTask; import org.thingsboard.server.dao.nosql.CassandraStatementTask;
import javax.annotation.Nullable; import javax.annotation.Nullable;
@ -144,6 +146,8 @@ public class TbSaveToCustomCassandraTableNode implements TbNode {
registerCodecIfNotFound(registry, new ComponentTypeCodec()); registerCodecIfNotFound(registry, new ComponentTypeCodec());
registerCodecIfNotFound(registry, new ComponentScopeCodec()); registerCodecIfNotFound(registry, new ComponentScopeCodec());
registerCodecIfNotFound(registry, new EntityTypeCodec()); registerCodecIfNotFound(registry, new EntityTypeCodec());
registerCodecIfNotFound(registry, new EdgeEventTypeCodec());
registerCodecIfNotFound(registry, new RuleChainTypeCodec());
} }
return session; return session;
} }

7
rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/aws/sns/TbSnsNode.java

@ -24,10 +24,13 @@ import com.amazonaws.services.sns.model.PublishRequest;
import com.amazonaws.services.sns.model.PublishResult; import com.amazonaws.services.sns.model.PublishResult;
import com.google.common.util.concurrent.ListenableFuture; import com.google.common.util.concurrent.ListenableFuture;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.thingsboard.rule.engine.api.RuleNode;
import org.thingsboard.rule.engine.api.TbContext;
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.rule.engine.api.util.TbNodeUtils;
import org.thingsboard.rule.engine.api.*;
import org.thingsboard.server.common.data.plugin.ComponentType; import org.thingsboard.server.common.data.plugin.ComponentType;
import org.thingsboard.server.common.data.rule.RuleChainType;
import org.thingsboard.server.common.msg.TbMsg; import org.thingsboard.server.common.msg.TbMsg;
import org.thingsboard.server.common.msg.TbMsgMetaData; import org.thingsboard.server.common.msg.TbMsgMetaData;

8
rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/aws/sqs/TbSqsNode.java

@ -26,16 +26,18 @@ import com.amazonaws.services.sqs.model.SendMessageResult;
import com.google.common.util.concurrent.ListenableFuture; import com.google.common.util.concurrent.ListenableFuture;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import org.thingsboard.rule.engine.api.RuleNode;
import org.thingsboard.rule.engine.api.TbContext;
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.rule.engine.api.util.TbNodeUtils;
import org.thingsboard.rule.engine.api.*;
import org.thingsboard.server.common.data.plugin.ComponentType; import org.thingsboard.server.common.data.plugin.ComponentType;
import org.thingsboard.server.common.data.rule.RuleChainType;
import org.thingsboard.server.common.msg.TbMsg; import org.thingsboard.server.common.msg.TbMsg;
import org.thingsboard.server.common.msg.TbMsgMetaData; import org.thingsboard.server.common.msg.TbMsgMetaData;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
import java.util.concurrent.ExecutionException;
import static org.thingsboard.common.util.DonAsynchron.withCallback; import static org.thingsboard.common.util.DonAsynchron.withCallback;

8
rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/debug/TbMsgGeneratorNode.java

@ -18,12 +18,16 @@ package org.thingsboard.rule.engine.debug;
import com.google.common.util.concurrent.ListenableFuture; import com.google.common.util.concurrent.ListenableFuture;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.springframework.util.StringUtils; import org.springframework.util.StringUtils;
import org.thingsboard.rule.engine.api.RuleNode;
import org.thingsboard.rule.engine.api.ScriptEngine;
import org.thingsboard.rule.engine.api.TbContext;
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.rule.engine.api.util.TbNodeUtils;
import org.thingsboard.rule.engine.api.*;
import org.thingsboard.server.common.data.id.EntityId; import org.thingsboard.server.common.data.id.EntityId;
import org.thingsboard.server.common.data.id.EntityIdFactory; import org.thingsboard.server.common.data.id.EntityIdFactory;
import org.thingsboard.server.common.data.plugin.ComponentType; import org.thingsboard.server.common.data.plugin.ComponentType;
import org.thingsboard.server.common.data.rule.RuleChainType;
import org.thingsboard.server.common.msg.TbMsg; import org.thingsboard.server.common.msg.TbMsg;
import org.thingsboard.server.common.msg.TbMsgMetaData; import org.thingsboard.server.common.msg.TbMsgMetaData;
import org.thingsboard.server.common.msg.queue.PartitionChangeMsg; import org.thingsboard.server.common.msg.queue.PartitionChangeMsg;

2
rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/delay/TbMsgDelayNode.java

@ -24,7 +24,6 @@ import org.thingsboard.rule.engine.api.TbNodeConfiguration;
import org.thingsboard.rule.engine.api.TbNodeException; import org.thingsboard.rule.engine.api.TbNodeException;
import org.thingsboard.rule.engine.api.util.TbNodeUtils; import org.thingsboard.rule.engine.api.util.TbNodeUtils;
import org.thingsboard.server.common.data.plugin.ComponentType; import org.thingsboard.server.common.data.plugin.ComponentType;
import org.thingsboard.server.common.data.rule.RuleChainType;
import org.thingsboard.server.common.msg.TbMsg; import org.thingsboard.server.common.msg.TbMsg;
import org.thingsboard.server.common.msg.TbMsgMetaData; import org.thingsboard.server.common.msg.TbMsgMetaData;
import org.thingsboard.server.common.msg.queue.ServiceQueue; import org.thingsboard.server.common.msg.queue.ServiceQueue;
@ -34,7 +33,6 @@ import java.util.Map;
import java.util.UUID; import java.util.UUID;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
import static org.thingsboard.rule.engine.api.TbRelationTypes.FAILURE;
import static org.thingsboard.rule.engine.api.TbRelationTypes.SUCCESS; import static org.thingsboard.rule.engine.api.TbRelationTypes.SUCCESS;
@Slf4j @Slf4j

6
rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/edge/TbMsgPushToEdgeNode.java

@ -154,10 +154,10 @@ public class TbMsgPushToEdgeNode implements TbNode {
private EdgeEvent buildEdgeEvent(TenantId tenantId, ActionType edgeEventAction, UUID entityId, EdgeEventType edgeEventType, JsonNode entityBody) { private EdgeEvent buildEdgeEvent(TenantId tenantId, ActionType edgeEventAction, UUID entityId, EdgeEventType edgeEventType, JsonNode entityBody) {
EdgeEvent edgeEvent = new EdgeEvent(); EdgeEvent edgeEvent = new EdgeEvent();
edgeEvent.setTenantId(tenantId); edgeEvent.setTenantId(tenantId);
edgeEvent.setEdgeEventAction(edgeEventAction.name()); edgeEvent.setAction(edgeEventAction.name());
edgeEvent.setEntityId(entityId); edgeEvent.setEntityId(entityId);
edgeEvent.setEdgeEventType(edgeEventType); edgeEvent.setType(edgeEventType);
edgeEvent.setEntityBody(entityBody); edgeEvent.setBody(entityBody);
return edgeEvent; return edgeEvent;
} }

4
rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/filter/TbCheckMessageNode.java

@ -24,7 +24,6 @@ import org.thingsboard.rule.engine.api.TbNodeConfiguration;
import org.thingsboard.rule.engine.api.TbNodeException; import org.thingsboard.rule.engine.api.TbNodeException;
import org.thingsboard.rule.engine.api.util.TbNodeUtils; import org.thingsboard.rule.engine.api.util.TbNodeUtils;
import org.thingsboard.server.common.data.plugin.ComponentType; import org.thingsboard.server.common.data.plugin.ComponentType;
import org.thingsboard.server.common.data.rule.RuleChainType;
import org.thingsboard.server.common.msg.TbMsg; import org.thingsboard.server.common.msg.TbMsg;
import java.util.List; import java.util.List;
@ -40,8 +39,7 @@ import java.util.Map;
nodeDetails = "If selected checkbox 'Check that all selected keys are present'\" and all keys in message data and metadata are exist - send Message via <b>True</b> chain, otherwise <b>False</b> chain is used.\n" + nodeDetails = "If selected checkbox 'Check that all selected keys are present'\" and all keys in message data and metadata are exist - send Message via <b>True</b> chain, otherwise <b>False</b> chain is used.\n" +
"Else if the checkbox is not selected, and at least one of the keys from data or metadata of the message exists - send Message via <b>True</b> chain, otherwise, <b>False</b> chain is used. ", "Else if the checkbox is not selected, and at least one of the keys from data or metadata of the message exists - send Message via <b>True</b> chain, otherwise, <b>False</b> chain is used. ",
uiResources = {"static/rulenode/rulenode-core-config.js"}, uiResources = {"static/rulenode/rulenode-core-config.js"},
configDirective = "tbFilterNodeCheckMessageConfig" configDirective = "tbFilterNodeCheckMessageConfig")
)
public class TbCheckMessageNode implements TbNode { public class TbCheckMessageNode implements TbNode {
private static final Gson gson = new Gson(); private static final Gson gson = new Gson();

4
rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/filter/TbCheckRelationNode.java

@ -31,7 +31,6 @@ import org.thingsboard.server.common.data.plugin.ComponentType;
import org.thingsboard.server.common.data.relation.EntityRelation; import org.thingsboard.server.common.data.relation.EntityRelation;
import org.thingsboard.server.common.data.relation.EntitySearchDirection; import org.thingsboard.server.common.data.relation.EntitySearchDirection;
import org.thingsboard.server.common.data.relation.RelationTypeGroup; import org.thingsboard.server.common.data.relation.RelationTypeGroup;
import org.thingsboard.server.common.data.rule.RuleChainType;
import org.thingsboard.server.common.msg.TbMsg; import org.thingsboard.server.common.msg.TbMsg;
import java.util.List; import java.util.List;
@ -52,8 +51,7 @@ import static org.thingsboard.common.util.DonAsynchron.withCallback;
" any relation to the originator of the message by type and direction.", " any relation to the originator of the message by type and direction.",
nodeDetails = "If at least one relation exists - send Message via <b>True</b> chain, otherwise <b>False</b> chain is used.", nodeDetails = "If at least one relation exists - send Message via <b>True</b> chain, otherwise <b>False</b> chain is used.",
uiResources = {"static/rulenode/rulenode-core-config.js"}, uiResources = {"static/rulenode/rulenode-core-config.js"},
configDirective = "tbFilterNodeCheckRelationConfig" configDirective = "tbFilterNodeCheckRelationConfig")
)
public class TbCheckRelationNode implements TbNode { public class TbCheckRelationNode implements TbNode {
private TbCheckRelationNodeConfiguration config; private TbCheckRelationNodeConfiguration config;

12
rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/filter/TbJsFilterNode.java

@ -16,11 +16,14 @@
package org.thingsboard.rule.engine.filter; package org.thingsboard.rule.engine.filter;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.thingsboard.common.util.ListeningExecutor; import org.thingsboard.rule.engine.api.RuleNode;
import org.thingsboard.rule.engine.api.ScriptEngine;
import org.thingsboard.rule.engine.api.TbContext;
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.rule.engine.api.util.TbNodeUtils;
import org.thingsboard.rule.engine.api.*;
import org.thingsboard.server.common.data.plugin.ComponentType; import org.thingsboard.server.common.data.plugin.ComponentType;
import org.thingsboard.server.common.data.rule.RuleChainType;
import org.thingsboard.server.common.msg.TbMsg; import org.thingsboard.server.common.msg.TbMsg;
import static org.thingsboard.common.util.DonAsynchron.withCallback; import static org.thingsboard.common.util.DonAsynchron.withCallback;
@ -37,8 +40,7 @@ import static org.thingsboard.common.util.DonAsynchron.withCallback;
"Message metadata can be accessed via <code>metadata</code> property. For example <code>metadata.customerName === 'John';</code><br/>" + "Message metadata can be accessed via <code>metadata</code> property. For example <code>metadata.customerName === 'John';</code><br/>" +
"Message type can be accessed via <code>msgType</code> property.", "Message type can be accessed via <code>msgType</code> property.",
uiResources = {"static/rulenode/rulenode-core-config.js"}, uiResources = {"static/rulenode/rulenode-core-config.js"},
configDirective = "tbFilterNodeScriptConfig" configDirective = "tbFilterNodeScriptConfig")
)
public class TbJsFilterNode implements TbNode { public class TbJsFilterNode implements TbNode {

11
rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/filter/TbJsSwitchNode.java

@ -17,10 +17,14 @@ package org.thingsboard.rule.engine.filter;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.thingsboard.common.util.ListeningExecutor; import org.thingsboard.common.util.ListeningExecutor;
import org.thingsboard.rule.engine.api.RuleNode;
import org.thingsboard.rule.engine.api.ScriptEngine;
import org.thingsboard.rule.engine.api.TbContext;
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.rule.engine.api.util.TbNodeUtils;
import org.thingsboard.rule.engine.api.*;
import org.thingsboard.server.common.data.plugin.ComponentType; import org.thingsboard.server.common.data.plugin.ComponentType;
import org.thingsboard.server.common.data.rule.RuleChainType;
import org.thingsboard.server.common.msg.TbMsg; import org.thingsboard.server.common.msg.TbMsg;
import java.util.Set; import java.util.Set;
@ -40,8 +44,7 @@ import static org.thingsboard.common.util.DonAsynchron.withCallback;
"Message metadata can be accessed via <code>metadata</code> property. For example <code>metadata.customerName === 'John';</code><br/>" + "Message metadata can be accessed via <code>metadata</code> property. For example <code>metadata.customerName === 'John';</code><br/>" +
"Message type can be accessed via <code>msgType</code> property.", "Message type can be accessed via <code>msgType</code> property.",
uiResources = {"static/rulenode/rulenode-core-config.js"}, uiResources = {"static/rulenode/rulenode-core-config.js"},
configDirective = "tbFilterNodeSwitchConfig" configDirective = "tbFilterNodeSwitchConfig")
)
public class TbJsSwitchNode implements TbNode { public class TbJsSwitchNode implements TbNode {
private TbJsSwitchNodeConfiguration config; private TbJsSwitchNodeConfiguration config;

10
rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/filter/TbMsgTypeFilterNode.java

@ -16,10 +16,13 @@
package org.thingsboard.rule.engine.filter; package org.thingsboard.rule.engine.filter;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.thingsboard.rule.engine.api.RuleNode;
import org.thingsboard.rule.engine.api.TbContext;
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.rule.engine.api.util.TbNodeUtils;
import org.thingsboard.rule.engine.api.*;
import org.thingsboard.server.common.data.plugin.ComponentType; import org.thingsboard.server.common.data.plugin.ComponentType;
import org.thingsboard.server.common.data.rule.RuleChainType;
import org.thingsboard.server.common.msg.TbMsg; import org.thingsboard.server.common.msg.TbMsg;
/** /**
@ -34,8 +37,7 @@ import org.thingsboard.server.common.msg.TbMsg;
nodeDescription = "Filter incoming messages by Message Type", nodeDescription = "Filter incoming messages by Message Type",
nodeDetails = "If incoming MessageType is expected - send Message via <b>True</b> chain, otherwise <b>False</b> chain is used.", nodeDetails = "If incoming MessageType is expected - send Message via <b>True</b> chain, otherwise <b>False</b> chain is used.",
uiResources = {"static/rulenode/rulenode-core-config.js", "static/rulenode/rulenode-core-config.css"}, uiResources = {"static/rulenode/rulenode-core-config.js", "static/rulenode/rulenode-core-config.css"},
configDirective = "tbFilterNodeMessageTypeConfig" configDirective = "tbFilterNodeMessageTypeConfig")
)
public class TbMsgTypeFilterNode implements TbNode { public class TbMsgTypeFilterNode implements TbNode {
TbMsgTypeFilterNodeConfiguration config; TbMsgTypeFilterNodeConfiguration config;

4
rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/filter/TbMsgTypeSwitchNode.java

@ -25,7 +25,6 @@ import org.thingsboard.rule.engine.api.TbNodeException;
import org.thingsboard.rule.engine.api.util.TbNodeUtils; import org.thingsboard.rule.engine.api.util.TbNodeUtils;
import org.thingsboard.server.common.data.DataConstants; import org.thingsboard.server.common.data.DataConstants;
import org.thingsboard.server.common.data.plugin.ComponentType; import org.thingsboard.server.common.data.plugin.ComponentType;
import org.thingsboard.server.common.data.rule.RuleChainType;
import org.thingsboard.server.common.msg.TbMsg; import org.thingsboard.server.common.msg.TbMsg;
import org.thingsboard.server.common.msg.session.SessionMsgType; import org.thingsboard.server.common.msg.session.SessionMsgType;
@ -40,8 +39,7 @@ import org.thingsboard.server.common.msg.session.SessionMsgType;
nodeDescription = "Route incoming messages by Message Type", nodeDescription = "Route incoming messages by Message Type",
nodeDetails = "Sends messages with message types <b>\"Post attributes\", \"Post telemetry\", \"RPC Request\"</b> etc. via corresponding chain, otherwise <b>Other</b> chain is used.", nodeDetails = "Sends messages with message types <b>\"Post attributes\", \"Post telemetry\", \"RPC Request\"</b> etc. via corresponding chain, otherwise <b>Other</b> chain is used.",
uiResources = {"static/rulenode/rulenode-core-config.js"}, uiResources = {"static/rulenode/rulenode-core-config.js"},
configDirective = "tbNodeEmptyConfig" configDirective = "tbNodeEmptyConfig")
)
public class TbMsgTypeSwitchNode implements TbNode { public class TbMsgTypeSwitchNode implements TbNode {
EmptyNodeConfiguration config; EmptyNodeConfiguration config;

10
rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/filter/TbOriginatorTypeFilterNode.java

@ -16,11 +16,14 @@
package org.thingsboard.rule.engine.filter; package org.thingsboard.rule.engine.filter;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.thingsboard.rule.engine.api.RuleNode;
import org.thingsboard.rule.engine.api.TbContext;
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.rule.engine.api.util.TbNodeUtils;
import org.thingsboard.rule.engine.api.*;
import org.thingsboard.server.common.data.EntityType; import org.thingsboard.server.common.data.EntityType;
import org.thingsboard.server.common.data.plugin.ComponentType; import org.thingsboard.server.common.data.plugin.ComponentType;
import org.thingsboard.server.common.data.rule.RuleChainType;
import org.thingsboard.server.common.msg.TbMsg; import org.thingsboard.server.common.msg.TbMsg;
@Slf4j @Slf4j
@ -32,8 +35,7 @@ import org.thingsboard.server.common.msg.TbMsg;
nodeDescription = "Filter incoming messages by message Originator Type", nodeDescription = "Filter incoming messages by message Originator Type",
nodeDetails = "If Originator Type of incoming message is expected - send Message via <b>True</b> chain, otherwise <b>False</b> chain is used.", nodeDetails = "If Originator Type of incoming message is expected - send Message via <b>True</b> chain, otherwise <b>False</b> chain is used.",
uiResources = {"static/rulenode/rulenode-core-config.js", "static/rulenode/rulenode-core-config.css"}, uiResources = {"static/rulenode/rulenode-core-config.js", "static/rulenode/rulenode-core-config.css"},
configDirective = "tbFilterNodeOriginatorTypeConfig" configDirective = "tbFilterNodeOriginatorTypeConfig")
)
public class TbOriginatorTypeFilterNode implements TbNode { public class TbOriginatorTypeFilterNode implements TbNode {
TbOriginatorTypeFilterNodeConfiguration config; TbOriginatorTypeFilterNodeConfiguration config;

11
rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/filter/TbOriginatorTypeSwitchNode.java

@ -16,11 +16,15 @@
package org.thingsboard.rule.engine.filter; package org.thingsboard.rule.engine.filter;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.thingsboard.rule.engine.api.EmptyNodeConfiguration;
import org.thingsboard.rule.engine.api.RuleNode;
import org.thingsboard.rule.engine.api.TbContext;
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.rule.engine.api.util.TbNodeUtils;
import org.thingsboard.rule.engine.api.*;
import org.thingsboard.server.common.data.EntityType; import org.thingsboard.server.common.data.EntityType;
import org.thingsboard.server.common.data.plugin.ComponentType; import org.thingsboard.server.common.data.plugin.ComponentType;
import org.thingsboard.server.common.data.rule.RuleChainType;
import org.thingsboard.server.common.msg.TbMsg; import org.thingsboard.server.common.msg.TbMsg;
@Slf4j @Slf4j
@ -32,8 +36,7 @@ import org.thingsboard.server.common.msg.TbMsg;
nodeDescription = "Route incoming messages by Message Originator Type", nodeDescription = "Route incoming messages by Message Originator Type",
nodeDetails = "Routes messages to chain according to the originator type ('Device', 'Asset', etc.).", nodeDetails = "Routes messages to chain according to the originator type ('Device', 'Asset', etc.).",
uiResources = {"static/rulenode/rulenode-core-config.js"}, uiResources = {"static/rulenode/rulenode-core-config.js"},
configDirective = "tbNodeEmptyConfig" configDirective = "tbNodeEmptyConfig")
)
public class TbOriginatorTypeSwitchNode implements TbNode { public class TbOriginatorTypeSwitchNode implements TbNode {
EmptyNodeConfiguration config; EmptyNodeConfiguration config;

9
rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/gcp/pubsub/TbPubSubNode.java

@ -26,10 +26,13 @@ import com.google.protobuf.ByteString;
import com.google.pubsub.v1.ProjectTopicName; import com.google.pubsub.v1.ProjectTopicName;
import com.google.pubsub.v1.PubsubMessage; import com.google.pubsub.v1.PubsubMessage;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.thingsboard.rule.engine.api.*; import org.thingsboard.rule.engine.api.RuleNode;
import org.thingsboard.rule.engine.api.TbContext;
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.rule.engine.api.util.TbNodeUtils;
import org.thingsboard.server.common.data.plugin.ComponentType; import org.thingsboard.server.common.data.plugin.ComponentType;
import org.thingsboard.server.common.data.rule.RuleChainType;
import org.thingsboard.server.common.msg.TbMsg; import org.thingsboard.server.common.msg.TbMsg;
import org.thingsboard.server.common.msg.TbMsgMetaData; import org.thingsboard.server.common.msg.TbMsgMetaData;
@ -37,8 +40,6 @@ import java.io.ByteArrayInputStream;
import java.io.IOException; import java.io.IOException;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
import static org.thingsboard.common.util.DonAsynchron.withCallback;
@Slf4j @Slf4j
@RuleNode( @RuleNode(
type = ComponentType.EXTERNAL, type = ComponentType.EXTERNAL,

1
rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/geo/TbGpsGeofencingActionNode.java

@ -28,7 +28,6 @@ import org.thingsboard.server.common.data.kv.AttributeKvEntry;
import org.thingsboard.server.common.data.kv.BaseAttributeKvEntry; import org.thingsboard.server.common.data.kv.BaseAttributeKvEntry;
import org.thingsboard.server.common.data.kv.StringDataEntry; import org.thingsboard.server.common.data.kv.StringDataEntry;
import org.thingsboard.server.common.data.plugin.ComponentType; import org.thingsboard.server.common.data.plugin.ComponentType;
import org.thingsboard.server.common.data.rule.RuleChainType;
import org.thingsboard.server.common.msg.TbMsg; import org.thingsboard.server.common.msg.TbMsg;
import java.util.Collections; import java.util.Collections;

22
rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/geo/TbGpsGeofencingFilterNode.java

@ -15,32 +15,13 @@
*/ */
package org.thingsboard.rule.engine.geo; package org.thingsboard.rule.engine.geo;
import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.locationtech.spatial4j.context.jts.JtsSpatialContext;
import org.locationtech.spatial4j.context.jts.JtsSpatialContextFactory;
import org.locationtech.spatial4j.shape.Point;
import org.locationtech.spatial4j.shape.Shape;
import org.locationtech.spatial4j.shape.ShapeFactory;
import org.locationtech.spatial4j.shape.SpatialRelation;
import org.springframework.util.StringUtils;
import org.thingsboard.rule.engine.api.RuleNode; import org.thingsboard.rule.engine.api.RuleNode;
import org.thingsboard.rule.engine.api.TbContext; import org.thingsboard.rule.engine.api.TbContext;
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.TbNodeException;
import org.thingsboard.rule.engine.api.util.TbNodeUtils;
import org.thingsboard.rule.engine.filter.TbMsgTypeFilterNodeConfiguration;
import org.thingsboard.server.common.data.plugin.ComponentType; import org.thingsboard.server.common.data.plugin.ComponentType;
import org.thingsboard.server.common.data.rule.RuleChainType;
import org.thingsboard.server.common.msg.TbMsg; import org.thingsboard.server.common.msg.TbMsg;
import java.util.Collections;
import java.util.List;
/** /**
* Created by ashvayka on 19.01.18. * Created by ashvayka on 19.01.18.
*/ */
@ -53,8 +34,7 @@ import java.util.List;
nodeDescription = "Filter incoming messages by GPS based geofencing", nodeDescription = "Filter incoming messages by GPS based geofencing",
nodeDetails = "Extracts latitude and longitude parameters from incoming message and returns 'True' if they are inside configured perimeters, 'False' otherwise.", 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"}, uiResources = {"static/rulenode/rulenode-core-config.js"},
configDirective = "tbFilterNodeGpsGeofencingConfig" configDirective = "tbFilterNodeGpsGeofencingConfig")
)
public class TbGpsGeofencingFilterNode extends AbstractGeofencingNode<TbGpsGeofencingFilterNodeConfiguration> { public class TbGpsGeofencingFilterNode extends AbstractGeofencingNode<TbGpsGeofencingFilterNodeConfiguration> {
@Override @Override

1
rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/kafka/TbKafkaNode.java

@ -33,7 +33,6 @@ import org.thingsboard.rule.engine.api.TbNodeException;
import org.thingsboard.rule.engine.api.TbRelationTypes; import org.thingsboard.rule.engine.api.TbRelationTypes;
import org.thingsboard.rule.engine.api.util.TbNodeUtils; import org.thingsboard.rule.engine.api.util.TbNodeUtils;
import org.thingsboard.server.common.data.plugin.ComponentType; import org.thingsboard.server.common.data.plugin.ComponentType;
import org.thingsboard.server.common.data.rule.RuleChainType;
import org.thingsboard.server.common.msg.TbMsg; import org.thingsboard.server.common.msg.TbMsg;
import org.thingsboard.server.common.msg.TbMsgMetaData; import org.thingsboard.server.common.msg.TbMsgMetaData;

7
rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/mail/TbMsgToEmailNode.java

@ -19,10 +19,13 @@ import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.springframework.util.StringUtils; import org.springframework.util.StringUtils;
import org.thingsboard.rule.engine.api.RuleNode;
import org.thingsboard.rule.engine.api.TbContext;
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.rule.engine.api.util.TbNodeUtils;
import org.thingsboard.rule.engine.api.*;
import org.thingsboard.server.common.data.plugin.ComponentType; import org.thingsboard.server.common.data.plugin.ComponentType;
import org.thingsboard.server.common.data.rule.RuleChainType;
import org.thingsboard.server.common.msg.TbMsg; import org.thingsboard.server.common.msg.TbMsg;
import org.thingsboard.server.common.msg.TbMsgMetaData; import org.thingsboard.server.common.msg.TbMsgMetaData;

1
rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/mail/TbSendEmailNode.java

@ -27,7 +27,6 @@ import org.thingsboard.rule.engine.api.TbNodeConfiguration;
import org.thingsboard.rule.engine.api.TbNodeException; import org.thingsboard.rule.engine.api.TbNodeException;
import org.thingsboard.rule.engine.api.util.TbNodeUtils; import org.thingsboard.rule.engine.api.util.TbNodeUtils;
import org.thingsboard.server.common.data.plugin.ComponentType; import org.thingsboard.server.common.data.plugin.ComponentType;
import org.thingsboard.server.common.data.rule.RuleChainType;
import org.thingsboard.server.common.msg.TbMsg; import org.thingsboard.server.common.msg.TbMsg;
import javax.mail.internet.MimeMessage; import javax.mail.internet.MimeMessage;

6
rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetAttributesNode.java

@ -18,14 +18,13 @@ package org.thingsboard.rule.engine.metadata;
import com.google.common.util.concurrent.Futures; import com.google.common.util.concurrent.Futures;
import com.google.common.util.concurrent.ListenableFuture; import com.google.common.util.concurrent.ListenableFuture;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.thingsboard.rule.engine.api.util.TbNodeUtils;
import org.thingsboard.rule.engine.api.RuleNode; import org.thingsboard.rule.engine.api.RuleNode;
import org.thingsboard.rule.engine.api.TbContext; import org.thingsboard.rule.engine.api.TbContext;
import org.thingsboard.rule.engine.api.TbNodeConfiguration; import org.thingsboard.rule.engine.api.TbNodeConfiguration;
import org.thingsboard.rule.engine.api.TbNodeException; import org.thingsboard.rule.engine.api.TbNodeException;
import org.thingsboard.rule.engine.api.util.TbNodeUtils;
import org.thingsboard.server.common.data.id.EntityId; import org.thingsboard.server.common.data.id.EntityId;
import org.thingsboard.server.common.data.plugin.ComponentType; import org.thingsboard.server.common.data.plugin.ComponentType;
import org.thingsboard.server.common.data.rule.RuleChainType;
import org.thingsboard.server.common.msg.TbMsg; import org.thingsboard.server.common.msg.TbMsg;
/** /**
@ -41,8 +40,7 @@ import org.thingsboard.server.common.msg.TbMsg;
"To access those attributes in other nodes this template can be used " + "To access those attributes in other nodes this template can be used " +
"<code>metadata.cs_temperature</code> or <code>metadata.shared_limit</code> ", "<code>metadata.cs_temperature</code> or <code>metadata.shared_limit</code> ",
uiResources = {"static/rulenode/rulenode-core-config.js"}, uiResources = {"static/rulenode/rulenode-core-config.js"},
configDirective = "tbEnrichmentNodeOriginatorAttributesConfig" configDirective = "tbEnrichmentNodeOriginatorAttributesConfig")
)
public class TbGetAttributesNode extends TbAbstractGetAttributesNode<TbGetAttributesNodeConfiguration, EntityId> { public class TbGetAttributesNode extends TbAbstractGetAttributesNode<TbGetAttributesNodeConfiguration, EntityId> {
@Override @Override

4
rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetCustomerAttributeNode.java

@ -22,7 +22,6 @@ import org.thingsboard.rule.engine.util.EntitiesCustomerIdAsyncLoader;
import org.thingsboard.server.common.data.id.CustomerId; import org.thingsboard.server.common.data.id.CustomerId;
import org.thingsboard.server.common.data.id.EntityId; import org.thingsboard.server.common.data.id.EntityId;
import org.thingsboard.server.common.data.plugin.ComponentType; import org.thingsboard.server.common.data.plugin.ComponentType;
import org.thingsboard.server.common.data.rule.RuleChainType;
@RuleNode( @RuleNode(
type = ComponentType.ENRICHMENT, type = ComponentType.ENRICHMENT,
@ -34,8 +33,7 @@ import org.thingsboard.server.common.data.rule.RuleChainType;
"To access those attributes in other nodes this template can be used " + "To access those attributes in other nodes this template can be used " +
"<code>metadata.temperature</code>.", "<code>metadata.temperature</code>.",
uiResources = {"static/rulenode/rulenode-core-config.js", "static/rulenode/rulenode-core-config.css"}, uiResources = {"static/rulenode/rulenode-core-config.js", "static/rulenode/rulenode-core-config.css"},
configDirective = "tbEnrichmentNodeCustomerAttributesConfig" configDirective = "tbEnrichmentNodeCustomerAttributesConfig")
)
public class TbGetCustomerAttributeNode extends TbEntityGetAttrNode<CustomerId> { public class TbGetCustomerAttributeNode extends TbEntityGetAttrNode<CustomerId> {
@Override @Override

4
rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetCustomerDetailsNode.java

@ -31,7 +31,6 @@ import org.thingsboard.server.common.data.id.DeviceId;
import org.thingsboard.server.common.data.id.EdgeId; import org.thingsboard.server.common.data.id.EdgeId;
import org.thingsboard.server.common.data.id.EntityViewId; import org.thingsboard.server.common.data.id.EntityViewId;
import org.thingsboard.server.common.data.plugin.ComponentType; import org.thingsboard.server.common.data.plugin.ComponentType;
import org.thingsboard.server.common.data.rule.RuleChainType;
import org.thingsboard.server.common.msg.TbMsg; import org.thingsboard.server.common.msg.TbMsg;
@Slf4j @Slf4j
@ -43,8 +42,7 @@ import org.thingsboard.server.common.msg.TbMsg;
"<b>Note:</b> only Device, Asset, and Entity View type are allowed.<br><br>" + "<b>Note:</b> only Device, Asset, and Entity View type are allowed.<br><br>" +
"If the originator of the message is not assigned to Customer, or originator type is not supported - Message will be forwarded to <b>Failure</b> chain, otherwise, <b>Success</b> chain will be used.", "If the originator of the message is not assigned to Customer, or originator type is not supported - Message will be forwarded to <b>Failure</b> chain, otherwise, <b>Success</b> chain will be used.",
uiResources = {"static/rulenode/rulenode-core-config.js"}, uiResources = {"static/rulenode/rulenode-core-config.js"},
configDirective = "tbEnrichmentNodeEntityDetailsConfig" configDirective = "tbEnrichmentNodeEntityDetailsConfig")
)
public class TbGetCustomerDetailsNode extends TbAbstractGetEntityDetailsNode<TbGetCustomerDetailsNodeConfiguration> { public class TbGetCustomerDetailsNode extends TbAbstractGetEntityDetailsNode<TbGetCustomerDetailsNodeConfiguration> {
private static final String CUSTOMER_PREFIX = "customer_"; private static final String CUSTOMER_PREFIX = "customer_";

7
rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetDeviceAttrNode.java

@ -17,16 +17,14 @@ package org.thingsboard.rule.engine.metadata;
import com.google.common.util.concurrent.ListenableFuture; import com.google.common.util.concurrent.ListenableFuture;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.thingsboard.rule.engine.api.util.TbNodeUtils;
import org.thingsboard.rule.engine.api.RuleNode; import org.thingsboard.rule.engine.api.RuleNode;
import org.thingsboard.rule.engine.api.TbContext; import org.thingsboard.rule.engine.api.TbContext;
import org.thingsboard.rule.engine.api.TbNodeConfiguration; import org.thingsboard.rule.engine.api.TbNodeConfiguration;
import org.thingsboard.rule.engine.api.TbNodeException; import org.thingsboard.rule.engine.api.TbNodeException;
import org.thingsboard.rule.engine.api.util.TbNodeUtils;
import org.thingsboard.rule.engine.util.EntitiesRelatedDeviceIdAsyncLoader; import org.thingsboard.rule.engine.util.EntitiesRelatedDeviceIdAsyncLoader;
import org.thingsboard.server.common.data.id.DeviceId; import org.thingsboard.server.common.data.id.DeviceId;
import org.thingsboard.server.common.data.id.EntityId;
import org.thingsboard.server.common.data.plugin.ComponentType; import org.thingsboard.server.common.data.plugin.ComponentType;
import org.thingsboard.server.common.data.rule.RuleChainType;
import org.thingsboard.server.common.msg.TbMsg; import org.thingsboard.server.common.msg.TbMsg;
@Slf4j @Slf4j
@ -39,8 +37,7 @@ import org.thingsboard.server.common.msg.TbMsg;
"To access those attributes in other nodes this template can be used " + "To access those attributes in other nodes this template can be used " +
"<code>metadata.cs_temperature</code> or <code>metadata.shared_limit</code> ", "<code>metadata.cs_temperature</code> or <code>metadata.shared_limit</code> ",
uiResources = {"static/rulenode/rulenode-core-config.js"}, uiResources = {"static/rulenode/rulenode-core-config.js"},
configDirective = "tbEnrichmentNodeDeviceAttributesConfig" configDirective = "tbEnrichmentNodeDeviceAttributesConfig")
)
public class TbGetDeviceAttrNode extends TbAbstractGetAttributesNode<TbGetDeviceAttrNodeConfiguration, DeviceId> { public class TbGetDeviceAttrNode extends TbAbstractGetAttributesNode<TbGetDeviceAttrNodeConfiguration, DeviceId> {
@Override @Override

5
rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetOriginatorFieldsNode.java

@ -28,11 +28,9 @@ import org.thingsboard.rule.engine.api.util.TbNodeUtils;
import org.thingsboard.rule.engine.util.EntitiesFieldsAsyncLoader; import org.thingsboard.rule.engine.util.EntitiesFieldsAsyncLoader;
import org.thingsboard.server.common.data.id.EntityId; import org.thingsboard.server.common.data.id.EntityId;
import org.thingsboard.server.common.data.plugin.ComponentType; import org.thingsboard.server.common.data.plugin.ComponentType;
import org.thingsboard.server.common.data.rule.RuleChainType;
import org.thingsboard.server.common.msg.TbMsg; import org.thingsboard.server.common.msg.TbMsg;
import static org.thingsboard.common.util.DonAsynchron.withCallback; import static org.thingsboard.common.util.DonAsynchron.withCallback;
import static org.thingsboard.rule.engine.api.TbRelationTypes.SUCCESS;
/** /**
* Created by ashvayka on 19.01.18. * Created by ashvayka on 19.01.18.
@ -44,8 +42,7 @@ import static org.thingsboard.rule.engine.api.TbRelationTypes.SUCCESS;
nodeDescription = "Add Message Originator fields values into Message Metadata", nodeDescription = "Add Message Originator fields values into Message Metadata",
nodeDetails = "Will fetch fields values specified in mapping. If specified field is not part of originator fields it will be ignored.", 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"}, uiResources = {"static/rulenode/rulenode-core-config.js"},
configDirective = "tbEnrichmentNodeOriginatorFieldsConfig" configDirective = "tbEnrichmentNodeOriginatorFieldsConfig")
)
public class TbGetOriginatorFieldsNode implements TbNode { public class TbGetOriginatorFieldsNode implements TbNode {
private TbGetOriginatorFieldsConfiguration config; private TbGetOriginatorFieldsConfiguration config;

10
rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetRelatedAttributeNode.java

@ -16,13 +16,14 @@
package org.thingsboard.rule.engine.metadata; package org.thingsboard.rule.engine.metadata;
import com.google.common.util.concurrent.ListenableFuture; import com.google.common.util.concurrent.ListenableFuture;
import org.thingsboard.rule.engine.api.RuleNode;
import org.thingsboard.rule.engine.api.TbContext;
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.rule.engine.api.util.TbNodeUtils;
import org.thingsboard.rule.engine.api.*;
import org.thingsboard.rule.engine.util.EntitiesRelatedEntityIdAsyncLoader; import org.thingsboard.rule.engine.util.EntitiesRelatedEntityIdAsyncLoader;
import org.thingsboard.server.common.data.id.EntityId; import org.thingsboard.server.common.data.id.EntityId;
import org.thingsboard.server.common.data.plugin.ComponentType; import org.thingsboard.server.common.data.plugin.ComponentType;
import org.thingsboard.server.common.data.rule.RuleChainType;
@RuleNode( @RuleNode(
type = ComponentType.ENRICHMENT, type = ComponentType.ENRICHMENT,
@ -36,8 +37,7 @@ import org.thingsboard.server.common.data.rule.RuleChainType;
"To access those attributes in other nodes this template can be used " + "To access those attributes in other nodes this template can be used " +
"<code>metadata.temperature</code>.", "<code>metadata.temperature</code>.",
uiResources = {"static/rulenode/rulenode-core-config.js", "static/rulenode/rulenode-core-config.css"}, uiResources = {"static/rulenode/rulenode-core-config.js", "static/rulenode/rulenode-core-config.css"},
configDirective = "tbEnrichmentNodeRelatedAttributesConfig" configDirective = "tbEnrichmentNodeRelatedAttributesConfig")
)
public class TbGetRelatedAttributeNode extends TbEntityGetAttrNode<EntityId> { public class TbGetRelatedAttributeNode extends TbEntityGetAttrNode<EntityId> {

5
rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetTelemetryNode.java

@ -38,7 +38,6 @@ import org.thingsboard.server.common.data.kv.BaseReadTsKvQuery;
import org.thingsboard.server.common.data.kv.ReadTsKvQuery; import org.thingsboard.server.common.data.kv.ReadTsKvQuery;
import org.thingsboard.server.common.data.kv.TsKvEntry; import org.thingsboard.server.common.data.kv.TsKvEntry;
import org.thingsboard.server.common.data.plugin.ComponentType; import org.thingsboard.server.common.data.plugin.ComponentType;
import org.thingsboard.server.common.data.rule.RuleChainType;
import org.thingsboard.server.common.msg.TbMsg; import org.thingsboard.server.common.msg.TbMsg;
import java.io.IOException; import java.io.IOException;
@ -47,7 +46,6 @@ import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import static org.thingsboard.rule.engine.api.TbRelationTypes.SUCCESS;
import static org.thingsboard.rule.engine.metadata.TbGetTelemetryNodeConfiguration.FETCH_MODE_ALL; import static org.thingsboard.rule.engine.metadata.TbGetTelemetryNodeConfiguration.FETCH_MODE_ALL;
import static org.thingsboard.rule.engine.metadata.TbGetTelemetryNodeConfiguration.FETCH_MODE_FIRST; import static org.thingsboard.rule.engine.metadata.TbGetTelemetryNodeConfiguration.FETCH_MODE_FIRST;
import static org.thingsboard.rule.engine.metadata.TbGetTelemetryNodeConfiguration.MAX_FETCH_SIZE; import static org.thingsboard.rule.engine.metadata.TbGetTelemetryNodeConfiguration.MAX_FETCH_SIZE;
@ -67,8 +65,7 @@ import static org.thingsboard.server.common.data.kv.Aggregation.NONE;
"Also, the rule node allows you to select telemetry sampling order: <b>ASC</b> or <b>DESC</b>. </br>" + "Also, the rule node allows you to select telemetry sampling order: <b>ASC</b> or <b>DESC</b>. </br>" +
"<b>Note</b>: The maximum size of the fetched array is 1000 records.\n ", "<b>Note</b>: The maximum size of the fetched array is 1000 records.\n ",
uiResources = {"static/rulenode/rulenode-core-config.js"}, uiResources = {"static/rulenode/rulenode-core-config.js"},
configDirective = "tbEnrichmentNodeGetTelemetryFromDatabase" configDirective = "tbEnrichmentNodeGetTelemetryFromDatabase")
)
public class TbGetTelemetryNode implements TbNode { public class TbGetTelemetryNode implements TbNode {
private static final String DESC_ORDER = "DESC"; private static final String DESC_ORDER = "DESC";

4
rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetTenantAttributeNode.java

@ -23,7 +23,6 @@ import org.thingsboard.rule.engine.util.EntitiesTenantIdAsyncLoader;
import org.thingsboard.server.common.data.id.EntityId; import org.thingsboard.server.common.data.id.EntityId;
import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.common.data.id.TenantId;
import org.thingsboard.server.common.data.plugin.ComponentType; import org.thingsboard.server.common.data.plugin.ComponentType;
import org.thingsboard.server.common.data.rule.RuleChainType;
@Slf4j @Slf4j
@RuleNode( @RuleNode(
@ -36,8 +35,7 @@ import org.thingsboard.server.common.data.rule.RuleChainType;
"To access those attributes in other nodes this template can be used " + "To access those attributes in other nodes this template can be used " +
"<code>metadata.temperature</code>.", "<code>metadata.temperature</code>.",
uiResources = {"static/rulenode/rulenode-core-config.js", "static/rulenode/rulenode-core-config.css"}, uiResources = {"static/rulenode/rulenode-core-config.js", "static/rulenode/rulenode-core-config.css"},
configDirective = "tbEnrichmentNodeTenantAttributesConfig" configDirective = "tbEnrichmentNodeTenantAttributesConfig")
)
public class TbGetTenantAttributeNode extends TbEntityGetAttrNode<TenantId> { public class TbGetTenantAttributeNode extends TbEntityGetAttrNode<TenantId> {
@Override @Override

4
rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetTenantDetailsNode.java

@ -26,7 +26,6 @@ import org.thingsboard.rule.engine.api.TbNodeException;
import org.thingsboard.rule.engine.api.util.TbNodeUtils; import org.thingsboard.rule.engine.api.util.TbNodeUtils;
import org.thingsboard.server.common.data.ContactBased; import org.thingsboard.server.common.data.ContactBased;
import org.thingsboard.server.common.data.plugin.ComponentType; import org.thingsboard.server.common.data.plugin.ComponentType;
import org.thingsboard.server.common.data.rule.RuleChainType;
import org.thingsboard.server.common.msg.TbMsg; import org.thingsboard.server.common.msg.TbMsg;
@Slf4j @Slf4j
@ -38,8 +37,7 @@ import org.thingsboard.server.common.msg.TbMsg;
"<b>Note:</b> only Device, Asset, and Entity View type are allowed.<br><br>" + "<b>Note:</b> only Device, Asset, and Entity View type are allowed.<br><br>" +
"If the originator of the message is not assigned to Tenant, or originator type is not supported - Message will be forwarded to <b>Failure</b> chain, otherwise, <b>Success</b> chain will be used.", "If the originator of the message is not assigned to Tenant, or originator type is not supported - Message will be forwarded to <b>Failure</b> chain, otherwise, <b>Success</b> chain will be used.",
uiResources = {"static/rulenode/rulenode-core-config.js"}, uiResources = {"static/rulenode/rulenode-core-config.js"},
configDirective = "tbEnrichmentNodeEntityDetailsConfig" configDirective = "tbEnrichmentNodeEntityDetailsConfig")
)
public class TbGetTenantDetailsNode extends TbAbstractGetEntityDetailsNode<TbGetTenantDetailsNodeConfiguration> { public class TbGetTenantDetailsNode extends TbAbstractGetEntityDetailsNode<TbGetTenantDetailsNodeConfiguration> {
private static final String TENANT_PREFIX = "tenant_"; private static final String TENANT_PREFIX = "tenant_";

9
rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/mqtt/TbMqttNode.java

@ -21,14 +21,17 @@ import io.netty.handler.ssl.SslContext;
import io.netty.handler.ssl.SslContextBuilder; import io.netty.handler.ssl.SslContextBuilder;
import io.netty.util.concurrent.Future; import io.netty.util.concurrent.Future;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.springframework.util.StringUtils;
import org.thingsboard.mqtt.MqttClient; import org.thingsboard.mqtt.MqttClient;
import org.thingsboard.mqtt.MqttClientConfig; import org.thingsboard.mqtt.MqttClientConfig;
import org.thingsboard.mqtt.MqttConnectResult; import org.thingsboard.mqtt.MqttConnectResult;
import org.springframework.util.StringUtils; import org.thingsboard.rule.engine.api.RuleNode;
import org.thingsboard.rule.engine.api.TbContext;
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.rule.engine.api.util.TbNodeUtils;
import org.thingsboard.rule.engine.api.*;
import org.thingsboard.server.common.data.plugin.ComponentType; import org.thingsboard.server.common.data.plugin.ComponentType;
import org.thingsboard.server.common.data.rule.RuleChainType;
import org.thingsboard.server.common.msg.TbMsg; import org.thingsboard.server.common.msg.TbMsg;
import org.thingsboard.server.common.msg.TbMsgMetaData; import org.thingsboard.server.common.msg.TbMsgMetaData;

14
rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/rabbitmq/TbRabbitMqNode.java

@ -16,18 +16,24 @@
package org.thingsboard.rule.engine.rabbitmq; package org.thingsboard.rule.engine.rabbitmq;
import com.google.common.util.concurrent.ListenableFuture; import com.google.common.util.concurrent.ListenableFuture;
import com.rabbitmq.client.*; import com.rabbitmq.client.AMQP;
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.ConnectionFactory;
import com.rabbitmq.client.MessageProperties;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import org.thingsboard.rule.engine.api.RuleNode;
import org.thingsboard.rule.engine.api.TbContext;
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.rule.engine.api.util.TbNodeUtils;
import org.thingsboard.rule.engine.api.*;
import org.thingsboard.server.common.data.plugin.ComponentType; import org.thingsboard.server.common.data.plugin.ComponentType;
import org.thingsboard.server.common.data.rule.RuleChainType;
import org.thingsboard.server.common.msg.TbMsg; import org.thingsboard.server.common.msg.TbMsg;
import org.thingsboard.server.common.msg.TbMsgMetaData; import org.thingsboard.server.common.msg.TbMsgMetaData;
import java.nio.charset.Charset; import java.nio.charset.Charset;
import java.util.concurrent.ExecutionException;
import static org.thingsboard.common.util.DonAsynchron.withCallback; import static org.thingsboard.common.util.DonAsynchron.withCallback;

1
rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/rest/TbRestApiCallNode.java

@ -23,7 +23,6 @@ import org.thingsboard.rule.engine.api.TbNodeConfiguration;
import org.thingsboard.rule.engine.api.TbNodeException; import org.thingsboard.rule.engine.api.TbNodeException;
import org.thingsboard.rule.engine.api.util.TbNodeUtils; import org.thingsboard.rule.engine.api.util.TbNodeUtils;
import org.thingsboard.server.common.data.plugin.ComponentType; import org.thingsboard.server.common.data.plugin.ComponentType;
import org.thingsboard.server.common.data.rule.RuleChainType;
import org.thingsboard.server.common.msg.TbMsg; import org.thingsboard.server.common.msg.TbMsg;
@Slf4j @Slf4j

4
rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/rpc/TbSendRPCReplyNode.java

@ -17,16 +17,14 @@ package org.thingsboard.rule.engine.rpc;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.springframework.util.StringUtils; import org.springframework.util.StringUtils;
import org.thingsboard.rule.engine.api.util.TbNodeUtils;
import org.thingsboard.rule.engine.api.RuleNode; import org.thingsboard.rule.engine.api.RuleNode;
import org.thingsboard.rule.engine.api.TbContext; import org.thingsboard.rule.engine.api.TbContext;
import org.thingsboard.rule.engine.api.TbNode; import org.thingsboard.rule.engine.api.TbNode;
import org.thingsboard.rule.engine.api.TbNodeConfiguration; import org.thingsboard.rule.engine.api.TbNodeConfiguration;
import org.thingsboard.rule.engine.api.TbNodeException; import org.thingsboard.rule.engine.api.TbNodeException;
import org.thingsboard.rule.engine.api.util.TbNodeUtils;
import org.thingsboard.server.common.data.EntityType; import org.thingsboard.server.common.data.EntityType;
import org.thingsboard.server.common.data.id.DeviceId;
import org.thingsboard.server.common.data.plugin.ComponentType; import org.thingsboard.server.common.data.plugin.ComponentType;
import org.thingsboard.server.common.data.rule.RuleChainType;
import org.thingsboard.server.common.msg.TbMsg; import org.thingsboard.server.common.msg.TbMsg;
import java.util.UUID; import java.util.UUID;

14
rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/rpc/TbSendRPCRequestNode.java

@ -145,19 +145,21 @@ public class TbSendRPCRequestNode implements TbNode {
List<EntityRelation> result = List<EntityRelation> result =
ctx.getRelationService().findByToAndType(ctx.getTenantId(), msg.getOriginator(), EntityRelation.EDGE_TYPE, RelationTypeGroup.COMMON); ctx.getRelationService().findByToAndType(ctx.getTenantId(), msg.getOriginator(), EntityRelation.EDGE_TYPE, RelationTypeGroup.COMMON);
if (result != null && result.size() > 0) { if (result != null && result.size() > 0) {
return new EdgeId(result.get(0).getFrom().getId()); EntityRelation relationToEdge = result.get(0);
} else { if (relationToEdge.getFrom() != null && relationToEdge.getFrom().getId() != null) {
return null; return new EdgeId(relationToEdge.getFrom().getId());
}
} }
return null;
} }
private void sendRpcRequestToEdgeDevice(TbContext ctx, TbMsg msg, EdgeId edgeId, RuleEngineDeviceRpcRequest request) { private void sendRpcRequestToEdgeDevice(TbContext ctx, TbMsg msg, EdgeId edgeId, RuleEngineDeviceRpcRequest request) {
EdgeEvent edgeEvent = new EdgeEvent(); EdgeEvent edgeEvent = new EdgeEvent();
edgeEvent.setTenantId(ctx.getTenantId()); edgeEvent.setTenantId(ctx.getTenantId());
edgeEvent.setEdgeEventAction(ActionType.RPC_CALL.name()); edgeEvent.setAction(ActionType.RPC_CALL.name());
edgeEvent.setEntityId(request.getDeviceId().getId()); edgeEvent.setEntityId(request.getDeviceId().getId());
edgeEvent.setEdgeEventType(EdgeEventType.DEVICE); edgeEvent.setType(EdgeEventType.DEVICE);
edgeEvent.setEntityBody(json.valueToTree(request)); edgeEvent.setBody(json.valueToTree(request));
edgeEvent.setEdgeId(edgeId); edgeEvent.setEdgeId(edgeId);
ListenableFuture<EdgeEvent> saveFuture = ctx.getEdgeEventService().saveAsync(edgeEvent); ListenableFuture<EdgeEvent> saveFuture = ctx.getEdgeEventService().saveAsync(edgeEvent);
Futures.addCallback(saveFuture, new FutureCallback<EdgeEvent>() { Futures.addCallback(saveFuture, new FutureCallback<EdgeEvent>() {

13
rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/telemetry/TbMsgAttributesNode.java

@ -24,12 +24,8 @@ import org.thingsboard.rule.engine.api.TbNode;
import org.thingsboard.rule.engine.api.TbNodeConfiguration; import org.thingsboard.rule.engine.api.TbNodeConfiguration;
import org.thingsboard.rule.engine.api.TbNodeException; import org.thingsboard.rule.engine.api.TbNodeException;
import org.thingsboard.rule.engine.api.util.TbNodeUtils; 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.id.DeviceId;
import org.thingsboard.server.common.data.kv.AttributeKvEntry; import org.thingsboard.server.common.data.kv.AttributeKvEntry;
import org.thingsboard.server.common.data.plugin.ComponentType; import org.thingsboard.server.common.data.plugin.ComponentType;
import org.thingsboard.server.common.data.rule.RuleChainType;
import org.thingsboard.server.common.msg.TbMsg; import org.thingsboard.server.common.msg.TbMsg;
import org.thingsboard.server.common.msg.session.SessionMsgType; import org.thingsboard.server.common.msg.session.SessionMsgType;
import org.thingsboard.server.common.transport.adaptor.JsonConverter; import org.thingsboard.server.common.transport.adaptor.JsonConverter;
@ -67,12 +63,11 @@ public class TbMsgAttributesNode implements TbNode {
} }
String src = msg.getData(); String src = msg.getData();
Set<AttributeKvEntry> attributes = JsonConverter.convertToAttributes(new JsonParser().parse(src)); Set<AttributeKvEntry> attributes = JsonConverter.convertToAttributes(new JsonParser().parse(src));
String scope = msg.getMetaData().getValue(SCOPE); if (StringUtils.isEmpty(msg.getMetaData().getValue(SCOPE))) {
if (StringUtils.isEmpty(scope)) { msg.getMetaData().putValue(SCOPE, config.getScope());
scope = config.getScope();
msg.getMetaData().putValue("scope", scope);
} }
ctx.getTelemetryService().saveAndNotify(ctx.getTenantId(), msg.getOriginator(), scope, new ArrayList<>(attributes), new TelemetryNodeCallback(ctx, msg)); ctx.getTelemetryService().saveAndNotify(ctx.getTenantId(), msg.getOriginator(), config.getScope(),
new ArrayList<>(attributes), new TelemetryNodeCallback(ctx, msg));
} }
@Override @Override

3
rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/telemetry/TbMsgTimeseriesNode.java

@ -18,17 +18,16 @@ package org.thingsboard.rule.engine.telemetry;
import com.google.gson.JsonParser; import com.google.gson.JsonParser;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.springframework.util.StringUtils; import org.springframework.util.StringUtils;
import org.thingsboard.rule.engine.api.util.TbNodeUtils;
import org.thingsboard.rule.engine.api.RuleNode; import org.thingsboard.rule.engine.api.RuleNode;
import org.thingsboard.rule.engine.api.TbContext; import org.thingsboard.rule.engine.api.TbContext;
import org.thingsboard.rule.engine.api.TbNode; import org.thingsboard.rule.engine.api.TbNode;
import org.thingsboard.rule.engine.api.TbNodeConfiguration; import org.thingsboard.rule.engine.api.TbNodeConfiguration;
import org.thingsboard.rule.engine.api.TbNodeException; import org.thingsboard.rule.engine.api.TbNodeException;
import org.thingsboard.rule.engine.api.util.TbNodeUtils;
import org.thingsboard.server.common.data.kv.BasicTsKvEntry; import org.thingsboard.server.common.data.kv.BasicTsKvEntry;
import org.thingsboard.server.common.data.kv.KvEntry; import org.thingsboard.server.common.data.kv.KvEntry;
import org.thingsboard.server.common.data.kv.TsKvEntry; import org.thingsboard.server.common.data.kv.TsKvEntry;
import org.thingsboard.server.common.data.plugin.ComponentType; import org.thingsboard.server.common.data.plugin.ComponentType;
import org.thingsboard.server.common.data.rule.RuleChainType;
import org.thingsboard.server.common.msg.TbMsg; import org.thingsboard.server.common.msg.TbMsg;
import org.thingsboard.server.common.msg.session.SessionMsgType; import org.thingsboard.server.common.msg.session.SessionMsgType;
import org.thingsboard.server.common.transport.adaptor.JsonConverter; import org.thingsboard.server.common.transport.adaptor.JsonConverter;

7
rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/transaction/TbSynchronizationBeginNode.java

@ -22,13 +22,9 @@ import org.thingsboard.rule.engine.api.TbContext;
import org.thingsboard.rule.engine.api.TbNode; import org.thingsboard.rule.engine.api.TbNode;
import org.thingsboard.rule.engine.api.TbNodeConfiguration; import org.thingsboard.rule.engine.api.TbNodeConfiguration;
import org.thingsboard.rule.engine.api.TbNodeException; import org.thingsboard.rule.engine.api.TbNodeException;
import org.thingsboard.rule.engine.api.util.TbNodeUtils;
import org.thingsboard.server.common.data.plugin.ComponentType; import org.thingsboard.server.common.data.plugin.ComponentType;
import org.thingsboard.server.common.data.rule.RuleChainType;
import org.thingsboard.server.common.msg.TbMsg; import org.thingsboard.server.common.msg.TbMsg;
import static org.thingsboard.rule.engine.api.TbRelationTypes.SUCCESS;
@Slf4j @Slf4j
@RuleNode( @RuleNode(
type = ComponentType.ACTION, type = ComponentType.ACTION,
@ -39,8 +35,7 @@ import static org.thingsboard.rule.engine.api.TbRelationTypes.SUCCESS;
"Subsequent messages will not be processed until the previous message processing is completed or timeout event occurs.\n" + "Subsequent messages will not be processed until the previous message processing is completed or timeout event occurs.\n" +
"Size of the queue per originator and timeout values are configurable on a system level", "Size of the queue per originator and timeout values are configurable on a system level",
uiResources = {"static/rulenode/rulenode-core-config.js"}, uiResources = {"static/rulenode/rulenode-core-config.js"},
configDirective = "tbNodeEmptyConfig" configDirective = "tbNodeEmptyConfig")
)
@Deprecated @Deprecated
public class TbSynchronizationBeginNode implements TbNode { public class TbSynchronizationBeginNode implements TbNode {

6
rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/transaction/TbSynchronizationEndNode.java

@ -22,15 +22,9 @@ import org.thingsboard.rule.engine.api.TbContext;
import org.thingsboard.rule.engine.api.TbNode; import org.thingsboard.rule.engine.api.TbNode;
import org.thingsboard.rule.engine.api.TbNodeConfiguration; import org.thingsboard.rule.engine.api.TbNodeConfiguration;
import org.thingsboard.rule.engine.api.TbNodeException; import org.thingsboard.rule.engine.api.TbNodeException;
import org.thingsboard.rule.engine.api.util.TbNodeUtils;
import org.thingsboard.server.common.data.plugin.ComponentType; import org.thingsboard.server.common.data.plugin.ComponentType;
import org.thingsboard.server.common.data.rule.RuleChainType;
import org.thingsboard.server.common.msg.TbMsg; import org.thingsboard.server.common.msg.TbMsg;
import java.util.concurrent.ExecutionException;
import static org.thingsboard.rule.engine.api.TbRelationTypes.SUCCESS;
@Slf4j @Slf4j
@RuleNode( @RuleNode(
type = ComponentType.ACTION, type = ComponentType.ACTION,

3
rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/transform/TbChangeOriginatorNode.java

@ -20,18 +20,17 @@ import com.google.common.collect.Sets;
import com.google.common.util.concurrent.Futures; import com.google.common.util.concurrent.Futures;
import com.google.common.util.concurrent.ListenableFuture; import com.google.common.util.concurrent.ListenableFuture;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.thingsboard.rule.engine.api.util.TbNodeUtils;
import org.thingsboard.rule.engine.api.RuleNode; import org.thingsboard.rule.engine.api.RuleNode;
import org.thingsboard.rule.engine.api.TbContext; import org.thingsboard.rule.engine.api.TbContext;
import org.thingsboard.rule.engine.api.TbNodeConfiguration; import org.thingsboard.rule.engine.api.TbNodeConfiguration;
import org.thingsboard.rule.engine.api.TbNodeException; import org.thingsboard.rule.engine.api.TbNodeException;
import org.thingsboard.rule.engine.api.util.TbNodeUtils;
import org.thingsboard.rule.engine.util.EntitiesAlarmOriginatorIdAsyncLoader; import org.thingsboard.rule.engine.util.EntitiesAlarmOriginatorIdAsyncLoader;
import org.thingsboard.rule.engine.util.EntitiesCustomerIdAsyncLoader; import org.thingsboard.rule.engine.util.EntitiesCustomerIdAsyncLoader;
import org.thingsboard.rule.engine.util.EntitiesRelatedEntityIdAsyncLoader; import org.thingsboard.rule.engine.util.EntitiesRelatedEntityIdAsyncLoader;
import org.thingsboard.rule.engine.util.EntitiesTenantIdAsyncLoader; import org.thingsboard.rule.engine.util.EntitiesTenantIdAsyncLoader;
import org.thingsboard.server.common.data.id.EntityId; import org.thingsboard.server.common.data.id.EntityId;
import org.thingsboard.server.common.data.plugin.ComponentType; import org.thingsboard.server.common.data.plugin.ComponentType;
import org.thingsboard.server.common.data.rule.RuleChainType;
import org.thingsboard.server.common.msg.TbMsg; import org.thingsboard.server.common.msg.TbMsg;
import java.util.HashSet; import java.util.HashSet;

13
rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/transform/TbTransformMsgNode.java

@ -16,15 +16,15 @@
package org.thingsboard.rule.engine.transform; package org.thingsboard.rule.engine.transform;
import com.google.common.util.concurrent.ListenableFuture; import com.google.common.util.concurrent.ListenableFuture;
import org.thingsboard.rule.engine.api.RuleNode;
import org.thingsboard.rule.engine.api.ScriptEngine;
import org.thingsboard.rule.engine.api.TbContext;
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.rule.engine.api.util.TbNodeUtils;
import org.thingsboard.rule.engine.api.*;
import org.thingsboard.server.common.data.plugin.ComponentType; import org.thingsboard.server.common.data.plugin.ComponentType;
import org.thingsboard.server.common.data.rule.RuleChainType;
import org.thingsboard.server.common.msg.TbMsg; import org.thingsboard.server.common.msg.TbMsg;
import static org.thingsboard.rule.engine.api.TbRelationTypes.FAILURE;
import static org.thingsboard.rule.engine.api.TbRelationTypes.SUCCESS;
@RuleNode( @RuleNode(
type = ComponentType.TRANSFORMATION, type = ComponentType.TRANSFORMATION,
name = "script", name = "script",
@ -38,8 +38,7 @@ import static org.thingsboard.rule.engine.api.TbRelationTypes.SUCCESS;
"<code>{ msg: <i style=\"color: #666;\">new payload</i>,<br/>&nbsp&nbsp&nbspmetadata: <i style=\"color: #666;\">new metadata</i>,<br/>&nbsp&nbsp&nbspmsgType: <i style=\"color: #666;\">new msgType</i> }</code><br/>" + "<code>{ msg: <i style=\"color: #666;\">new payload</i>,<br/>&nbsp&nbsp&nbspmetadata: <i style=\"color: #666;\">new metadata</i>,<br/>&nbsp&nbsp&nbspmsgType: <i style=\"color: #666;\">new msgType</i> }</code><br/>" +
"All fields in resulting object are optional and will be taken from original message if not specified.", "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"}, uiResources = {"static/rulenode/rulenode-core-config.js", "static/rulenode/rulenode-core-config.css"},
configDirective = "tbTransformationNodeScriptConfig" configDirective = "tbTransformationNodeScriptConfig")
)
public class TbTransformMsgNode extends TbAbstractTransformNode { public class TbTransformMsgNode extends TbAbstractTransformNode {
private TbTransformMsgNodeConfiguration config; private TbTransformMsgNodeConfiguration config;

Loading…
Cancel
Save