Browse Source

Merge branch 'develop/3.5.2' of https://github.com/thingsboard/thingsboard into customer-removing-alarm-unassign

pull/9035/head
imbeacon 3 years ago
parent
commit
d4fcd4f814
  1. 31
      application/src/main/data/upgrade/3.5.1/schema_update.sql
  2. 3
      application/src/main/java/org/thingsboard/server/actors/ActorSystemContext.java
  3. 120
      application/src/main/java/org/thingsboard/server/actors/ruleChain/DefaultTbContext.java
  4. 4
      application/src/main/java/org/thingsboard/server/actors/ruleChain/RuleChainActorMessageProcessor.java
  5. 2
      application/src/main/java/org/thingsboard/server/actors/ruleChain/RuleEngineComponentActor.java
  6. 4
      application/src/main/java/org/thingsboard/server/config/RateLimitProcessingFilter.java
  7. 9
      application/src/main/java/org/thingsboard/server/controller/AuthController.java
  8. 22
      application/src/main/java/org/thingsboard/server/controller/BaseController.java
  9. 22
      application/src/main/java/org/thingsboard/server/controller/EdgeController.java
  10. 4
      application/src/main/java/org/thingsboard/server/controller/RpcV2Controller.java
  11. 6
      application/src/main/java/org/thingsboard/server/controller/WidgetTypeController.java
  12. 2
      application/src/main/java/org/thingsboard/server/controller/plugin/TbWebSocketHandler.java
  13. 1
      application/src/main/java/org/thingsboard/server/exception/ThingsboardErrorResponseHandler.java
  14. 98
      application/src/main/java/org/thingsboard/server/service/action/EntityActionService.java
  15. 25
      application/src/main/java/org/thingsboard/server/service/component/AnnotationComponentDiscoveryService.java
  16. 19
      application/src/main/java/org/thingsboard/server/service/device/DeviceProvisionServiceImpl.java
  17. 66
      application/src/main/java/org/thingsboard/server/service/edge/DefaultEdgeNotificationService.java
  18. 158
      application/src/main/java/org/thingsboard/server/service/edge/EdgeEventSourcingListener.java
  19. 15
      application/src/main/java/org/thingsboard/server/service/edge/rpc/EdgeGrpcService.java
  20. 88
      application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/BaseEdgeProcessor.java
  21. 49
      application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/alarm/AlarmEdgeProcessor.java
  22. 12
      application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/alarm/BaseAlarmProcessor.java
  23. 7
      application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/asset/AssetEdgeProcessor.java
  24. 8
      application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/asset/AssetProfileEdgeProcessor.java
  25. 7
      application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/dashboard/DashboardEdgeProcessor.java
  26. 6
      application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/device/BaseDeviceProcessor.java
  27. 17
      application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/device/DeviceEdgeProcessor.java
  28. 7
      application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/device/DeviceProfileEdgeProcessor.java
  29. 7
      application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/entityview/EntityViewEdgeProcessor.java
  30. 7
      application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/ota/OtaPackageEdgeProcessor.java
  31. 6
      application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/queue/QueueEdgeProcessor.java
  32. 16
      application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/relation/BaseRelationProcessor.java
  33. 7
      application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/rule/RuleChainEdgeProcessor.java
  34. 8
      application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/telemetry/BaseTelemetryProcessor.java
  35. 7
      application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/user/UserEdgeProcessor.java
  36. 7
      application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/widget/WidgetBundleEdgeProcessor.java
  37. 6
      application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/widget/WidgetTypeEdgeProcessor.java
  38. 143
      application/src/main/java/org/thingsboard/server/service/entitiy/DefaultTbNotificationEntityService.java
  39. 50
      application/src/main/java/org/thingsboard/server/service/entitiy/TbNotificationEntityService.java
  40. 5
      application/src/main/java/org/thingsboard/server/service/entitiy/alarm/DefaultTbAlarmCommentService.java
  41. 64
      application/src/main/java/org/thingsboard/server/service/entitiy/alarm/DefaultTbAlarmService.java
  42. 36
      application/src/main/java/org/thingsboard/server/service/entitiy/asset/DefaultTbAssetService.java
  43. 11
      application/src/main/java/org/thingsboard/server/service/entitiy/asset/profile/DefaultTbAssetProfileService.java
  44. 15
      application/src/main/java/org/thingsboard/server/service/entitiy/customer/DefaultTbCustomerService.java
  45. 49
      application/src/main/java/org/thingsboard/server/service/entitiy/dashboard/DefaultTbDashboardService.java
  46. 32
      application/src/main/java/org/thingsboard/server/service/entitiy/device/DefaultTbDeviceService.java
  47. 11
      application/src/main/java/org/thingsboard/server/service/entitiy/device/profile/DefaultTbDeviceProfileService.java
  48. 8
      application/src/main/java/org/thingsboard/server/service/entitiy/edge/DefaultTbEdgeService.java
  49. 21
      application/src/main/java/org/thingsboard/server/service/entitiy/entity/relation/DefaultTbEntityRelationService.java
  50. 67
      application/src/main/java/org/thingsboard/server/service/entitiy/entityview/DefaultTbEntityViewService.java
  51. 19
      application/src/main/java/org/thingsboard/server/service/entitiy/ota/DefaultTbOtaPackageService.java
  52. 5
      application/src/main/java/org/thingsboard/server/service/entitiy/queue/DefaultTbQueueService.java
  53. 11
      application/src/main/java/org/thingsboard/server/service/entitiy/user/DefaultUserService.java
  54. 11
      application/src/main/java/org/thingsboard/server/service/entitiy/widgets/bundle/DefaultWidgetsBundleService.java
  55. 5
      application/src/main/java/org/thingsboard/server/service/install/DefaultSystemDataLoaderService.java
  56. 3
      application/src/main/java/org/thingsboard/server/service/install/update/DefaultDataUpdateService.java
  57. 1
      application/src/main/java/org/thingsboard/server/service/mail/DefaultMailService.java
  58. 74
      application/src/main/java/org/thingsboard/server/service/queue/DefaultTbClusterService.java
  59. 4
      application/src/main/java/org/thingsboard/server/service/queue/DefaultTbCoreConsumerService.java
  60. 4
      application/src/main/java/org/thingsboard/server/service/rpc/DefaultTbCoreDeviceRpcService.java
  61. 3
      application/src/main/java/org/thingsboard/server/service/rpc/TbRpcService.java
  62. 32
      application/src/main/java/org/thingsboard/server/service/rule/DefaultTbRuleChainService.java
  63. 27
      application/src/main/java/org/thingsboard/server/service/state/DefaultDeviceStateService.java
  64. 8
      application/src/main/java/org/thingsboard/server/service/sync/ie/DefaultEntitiesExportImportService.java
  65. 4
      application/src/main/java/org/thingsboard/server/service/sync/ie/importing/impl/AssetProfileImportService.java
  66. 8
      application/src/main/java/org/thingsboard/server/service/sync/ie/importing/impl/BaseEntityImportService.java
  67. 4
      application/src/main/java/org/thingsboard/server/service/sync/ie/importing/impl/DeviceProfileImportService.java
  68. 5
      application/src/main/java/org/thingsboard/server/service/sync/ie/importing/impl/RuleChainImportService.java
  69. 9
      application/src/main/java/org/thingsboard/server/service/sync/ie/importing/impl/WidgetsBundleImportService.java
  70. 8
      application/src/main/java/org/thingsboard/server/service/sync/vc/DefaultEntitiesVersionControlService.java
  71. 4
      application/src/main/java/org/thingsboard/server/service/telemetry/DefaultAlarmSubscriptionService.java
  72. 6
      application/src/main/java/org/thingsboard/server/service/telemetry/DefaultTelemetrySubscriptionService.java
  73. 3
      application/src/main/java/org/thingsboard/server/service/transport/DefaultTransportApiService.java
  74. 2
      application/src/main/java/org/thingsboard/server/utils/LwM2mObjectModelUtils.java
  75. 2
      application/src/main/resources/thingsboard.yml
  76. 19
      application/src/test/java/org/thingsboard/server/controller/AbstractNotifyEntityTest.java
  77. 6
      application/src/test/java/org/thingsboard/server/controller/AbstractRuleEngineControllerTest.java
  78. 18
      application/src/test/java/org/thingsboard/server/controller/AbstractWebTest.java
  79. 29
      application/src/test/java/org/thingsboard/server/controller/AlarmControllerTest.java
  80. 91
      application/src/test/java/org/thingsboard/server/controller/AssetControllerTest.java
  81. 4
      application/src/test/java/org/thingsboard/server/controller/AssetProfileControllerTest.java
  82. 12
      application/src/test/java/org/thingsboard/server/controller/CustomerControllerTest.java
  83. 37
      application/src/test/java/org/thingsboard/server/controller/DashboardControllerTest.java
  84. 47
      application/src/test/java/org/thingsboard/server/controller/DeviceControllerTest.java
  85. 4
      application/src/test/java/org/thingsboard/server/controller/DeviceProfileControllerTest.java
  86. 294
      application/src/test/java/org/thingsboard/server/controller/EdgeControllerTest.java
  87. 64
      application/src/test/java/org/thingsboard/server/controller/EdgeEventControllerTest.java
  88. 33
      application/src/test/java/org/thingsboard/server/controller/EntityViewControllerTest.java
  89. 2
      application/src/test/java/org/thingsboard/server/controller/OtaPackageControllerTest.java
  90. 20
      application/src/test/java/org/thingsboard/server/controller/RuleChainControllerTest.java
  91. 17
      application/src/test/java/org/thingsboard/server/controller/TelemetryControllerTest.java
  92. 8
      application/src/test/java/org/thingsboard/server/controller/UserControllerTest.java
  93. 109
      application/src/test/java/org/thingsboard/server/edge/AbstractEdgeTest.java
  94. 5
      application/src/test/java/org/thingsboard/server/edge/AssetEdgeTest.java
  95. 17
      application/src/test/java/org/thingsboard/server/edge/CustomerEdgeTest.java
  96. 4
      application/src/test/java/org/thingsboard/server/edge/DashboardEdgeTest.java
  97. 16
      application/src/test/java/org/thingsboard/server/edge/DeviceEdgeTest.java
  98. 4
      application/src/test/java/org/thingsboard/server/edge/EntityViewEdgeTest.java
  99. 31
      application/src/test/java/org/thingsboard/server/edge/RuleChainEdgeTest.java
  100. 2
      application/src/test/java/org/thingsboard/server/edge/TelemetryEdgeTest.java

31
application/src/main/data/upgrade/3.5.1/schema_update.sql

@ -99,19 +99,22 @@ DECLARE
p RECORD; p RECORD;
partition_end_ts BIGINT; partition_end_ts BIGINT;
BEGIN BEGIN
FOR p IN SELECT DISTINCT (created_time - created_time % partition_size_ms) AS partition_ts FROM old_edge_event IF (SELECT exists(SELECT FROM pg_tables WHERE tablename = 'old_edge_event')) THEN
WHERE created_time >= start_time_ms AND created_time < end_time_ms FOR p IN SELECT DISTINCT (created_time - created_time % partition_size_ms) AS partition_ts FROM old_edge_event
LOOP WHERE created_time >= start_time_ms AND created_time < end_time_ms
partition_end_ts = p.partition_ts + partition_size_ms; LOOP
RAISE NOTICE '[edge_event] Partition to create : [%-%]', p.partition_ts, partition_end_ts; partition_end_ts = p.partition_ts + partition_size_ms;
EXECUTE format('CREATE TABLE IF NOT EXISTS edge_event_%s PARTITION OF edge_event ' || RAISE NOTICE '[edge_event] Partition to create : [%-%]', p.partition_ts, partition_end_ts;
'FOR VALUES FROM ( %s ) TO ( %s )', p.partition_ts, p.partition_ts, partition_end_ts); EXECUTE format('CREATE TABLE IF NOT EXISTS edge_event_%s PARTITION OF edge_event ' ||
END LOOP; 'FOR VALUES FROM ( %s ) TO ( %s )', p.partition_ts, p.partition_ts, partition_end_ts);
END LOOP;
INSERT INTO edge_event (id, created_time, edge_id, edge_event_type, edge_event_uid, entity_id, edge_event_action, body, tenant_id, ts) INSERT INTO edge_event (id, created_time, edge_id, edge_event_type, edge_event_uid, entity_id, edge_event_action, body, tenant_id, ts)
SELECT id, created_time, edge_id, edge_event_type, edge_event_uid, entity_id, edge_event_action, body, tenant_id, ts SELECT id, created_time, edge_id, edge_event_type, edge_event_uid, entity_id, edge_event_action, body, tenant_id, ts
FROM old_edge_event FROM old_edge_event
WHERE created_time >= start_time_ms AND created_time < end_time_ms; WHERE created_time >= start_time_ms AND created_time < end_time_ms;
ELSE
RAISE NOTICE 'Table old_edge_event does not exists, skipping migration';
END IF;
END; END;
$$; $$;
-- EDGE EVENTS MIGRATION END -- EDGE EVENTS MIGRATION END
@ -122,3 +125,5 @@ ALTER TABLE resource
UPDATE resource UPDATE resource
SET etag = encode(sha256(decode(resource.data, 'base64')),'hex') WHERE resource.data is not null; SET etag = encode(sha256(decode(resource.data, 'base64')),'hex') WHERE resource.data is not null;
ALTER TABLE notification_request ALTER COLUMN info SET DATA TYPE varchar(1000000);

3
application/src/main/java/org/thingsboard/server/actors/ActorSystemContext.java

@ -48,6 +48,7 @@ import org.thingsboard.server.common.data.id.TenantId;
import org.thingsboard.server.common.data.plugin.ComponentLifecycleEvent; import org.thingsboard.server.common.data.plugin.ComponentLifecycleEvent;
import org.thingsboard.server.common.msg.TbActorMsg; import org.thingsboard.server.common.msg.TbActorMsg;
import org.thingsboard.server.common.msg.TbMsg; import org.thingsboard.server.common.msg.TbMsg;
import org.thingsboard.server.common.msg.notification.NotificationRuleProcessor;
import org.thingsboard.server.common.msg.queue.ServiceType; import org.thingsboard.server.common.msg.queue.ServiceType;
import org.thingsboard.server.common.msg.queue.TopicPartitionInfo; import org.thingsboard.server.common.msg.queue.TopicPartitionInfo;
import org.thingsboard.server.common.msg.tools.TbRateLimits; import org.thingsboard.server.common.msg.tools.TbRateLimits;
@ -90,7 +91,6 @@ import org.thingsboard.server.dao.widget.WidgetsBundleService;
import org.thingsboard.server.queue.discovery.DiscoveryService; import org.thingsboard.server.queue.discovery.DiscoveryService;
import org.thingsboard.server.queue.discovery.PartitionService; import org.thingsboard.server.queue.discovery.PartitionService;
import org.thingsboard.server.queue.discovery.TbServiceInfoProvider; import org.thingsboard.server.queue.discovery.TbServiceInfoProvider;
import org.thingsboard.server.common.msg.notification.NotificationRuleProcessor;
import org.thingsboard.server.queue.util.DataDecodingEncodingService; import org.thingsboard.server.queue.util.DataDecodingEncodingService;
import org.thingsboard.server.service.apiusage.TbApiUsageStateService; import org.thingsboard.server.service.apiusage.TbApiUsageStateService;
import org.thingsboard.server.service.component.ComponentDiscoveryService; import org.thingsboard.server.service.component.ComponentDiscoveryService;
@ -115,7 +115,6 @@ import org.thingsboard.server.service.transport.TbCoreToTransportService;
import javax.annotation.Nullable; import javax.annotation.Nullable;
import javax.annotation.PostConstruct; import javax.annotation.PostConstruct;
import java.io.IOException;
import java.io.PrintWriter; import java.io.PrintWriter;
import java.io.StringWriter; import java.io.StringWriter;
import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentHashMap;

120
application/src/main/java/org/thingsboard/server/actors/ruleChain/DefaultTbContext.java

@ -15,7 +15,6 @@
*/ */
package org.thingsboard.server.actors.ruleChain; package org.thingsboard.server.actors.ruleChain;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.node.ArrayNode; import com.fasterxml.jackson.databind.node.ArrayNode;
import com.fasterxml.jackson.databind.node.ObjectNode; import com.fasterxml.jackson.databind.node.ObjectNode;
import io.netty.channel.EventLoopGroup; import io.netty.channel.EventLoopGroup;
@ -35,7 +34,6 @@ import org.thingsboard.rule.engine.api.ScriptEngine;
import org.thingsboard.rule.engine.api.SmsService; import org.thingsboard.rule.engine.api.SmsService;
import org.thingsboard.rule.engine.api.TbContext; import org.thingsboard.rule.engine.api.TbContext;
import org.thingsboard.rule.engine.api.TbNodeException; import org.thingsboard.rule.engine.api.TbNodeException;
import org.thingsboard.rule.engine.api.TbRelationTypes;
import org.thingsboard.rule.engine.api.slack.SlackService; import org.thingsboard.rule.engine.api.slack.SlackService;
import org.thingsboard.rule.engine.api.sms.SmsSenderFactory; import org.thingsboard.rule.engine.api.sms.SmsSenderFactory;
import org.thingsboard.rule.engine.util.TenantIdLoader; import org.thingsboard.rule.engine.util.TenantIdLoader;
@ -43,7 +41,6 @@ import org.thingsboard.server.actors.ActorSystemContext;
import org.thingsboard.server.actors.TbActorRef; import org.thingsboard.server.actors.TbActorRef;
import org.thingsboard.server.cluster.TbClusterService; import org.thingsboard.server.cluster.TbClusterService;
import org.thingsboard.server.common.data.Customer; import org.thingsboard.server.common.data.Customer;
import org.thingsboard.server.common.data.DataConstants;
import org.thingsboard.server.common.data.Device; import org.thingsboard.server.common.data.Device;
import org.thingsboard.server.common.data.DeviceProfile; import org.thingsboard.server.common.data.DeviceProfile;
import org.thingsboard.server.common.data.EntityType; import org.thingsboard.server.common.data.EntityType;
@ -62,6 +59,8 @@ 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 org.thingsboard.server.common.data.kv.AttributeKvEntry; import org.thingsboard.server.common.data.kv.AttributeKvEntry;
import org.thingsboard.server.common.data.msg.TbMsgType;
import org.thingsboard.server.common.data.msg.TbNodeConnectionType;
import org.thingsboard.server.common.data.page.PageData; import org.thingsboard.server.common.data.page.PageData;
import org.thingsboard.server.common.data.page.PageLink; import org.thingsboard.server.common.data.page.PageLink;
import org.thingsboard.server.common.data.rule.RuleNode; import org.thingsboard.server.common.data.rule.RuleNode;
@ -115,6 +114,10 @@ import java.util.concurrent.TimeUnit;
import java.util.function.BiConsumer; import java.util.function.BiConsumer;
import java.util.function.Consumer; import java.util.function.Consumer;
import static org.thingsboard.server.common.data.msg.TbMsgType.ATTRIBUTES_DELETED;
import static org.thingsboard.server.common.data.msg.TbMsgType.ATTRIBUTES_UPDATED;
import static org.thingsboard.server.common.data.msg.TbMsgType.ENTITY_CREATED;
/** /**
* Created by ashvayka on 19.03.18. * Created by ashvayka on 19.03.18.
*/ */
@ -133,7 +136,7 @@ class DefaultTbContext implements TbContext {
@Override @Override
public void tellSuccess(TbMsg msg) { public void tellSuccess(TbMsg msg) {
tellNext(msg, Collections.singleton(TbRelationTypes.SUCCESS), null); tellNext(msg, Collections.singleton(TbNodeConnectionType.SUCCESS), null);
} }
@Override @Override
@ -212,13 +215,13 @@ class DefaultTbContext implements TbContext {
@Override @Override
public void enqueueForTellFailure(TbMsg tbMsg, String failureMessage) { public void enqueueForTellFailure(TbMsg tbMsg, String failureMessage) {
TopicPartitionInfo tpi = resolvePartition(tbMsg); TopicPartitionInfo tpi = resolvePartition(tbMsg);
enqueueForTellNext(tpi, tbMsg, Collections.singleton(TbRelationTypes.FAILURE), failureMessage, null, null); enqueueForTellNext(tpi, tbMsg, Collections.singleton(TbNodeConnectionType.FAILURE), failureMessage, null, null);
} }
@Override @Override
public void enqueueForTellFailure(TbMsg tbMsg, Throwable th) { public void enqueueForTellFailure(TbMsg tbMsg, Throwable th) {
TopicPartitionInfo tpi = resolvePartition(tbMsg); TopicPartitionInfo tpi = resolvePartition(tbMsg);
enqueueForTellNext(tpi, tbMsg, Collections.singleton(TbRelationTypes.FAILURE), getFailureMessage(th), null, null); enqueueForTellNext(tpi, tbMsg, Collections.singleton(TbNodeConnectionType.FAILURE), getFailureMessage(th), null, null);
} }
@Override @Override
@ -316,11 +319,11 @@ class DefaultTbContext implements TbContext {
@Override @Override
public void tellFailure(TbMsg msg, Throwable th) { public void tellFailure(TbMsg msg, Throwable th) {
if (nodeCtx.getSelf().isDebugMode()) { if (nodeCtx.getSelf().isDebugMode()) {
mainCtx.persistDebugOutput(nodeCtx.getTenantId(), nodeCtx.getSelf().getId(), msg, TbRelationTypes.FAILURE, th); mainCtx.persistDebugOutput(nodeCtx.getTenantId(), nodeCtx.getSelf().getId(), msg, TbNodeConnectionType.FAILURE, th);
} }
String failureMessage = getFailureMessage(th); String failureMessage = getFailureMessage(th);
nodeCtx.getChainActor().tell(new RuleNodeToRuleChainTellNextMsg(nodeCtx.getSelf().getRuleChainId(), nodeCtx.getChainActor().tell(new RuleNodeToRuleChainTellNextMsg(nodeCtx.getSelf().getRuleChainId(),
nodeCtx.getSelf().getId(), Collections.singleton(TbRelationTypes.FAILURE), nodeCtx.getSelf().getId(), Collections.singleton(TbNodeConnectionType.FAILURE),
msg, failureMessage)); msg, failureMessage));
} }
@ -343,67 +346,104 @@ class DefaultTbContext implements TbContext {
return TbMsg.transformMsg(origMsg, type, originator, metaData, data); return TbMsg.transformMsg(origMsg, type, originator, metaData, data);
} }
@Override
public TbMsg newMsg(String queueName, TbMsgType type, EntityId originator, TbMsgMetaData metaData, String data) {
return newMsg(queueName, type, originator, null, metaData, data);
}
@Override
public TbMsg newMsg(String queueName, TbMsgType type, EntityId originator, CustomerId customerId, TbMsgMetaData metaData, String data) {
return TbMsg.newMsg(queueName, type, originator, customerId, metaData, data, nodeCtx.getSelf().getRuleChainId(), nodeCtx.getSelf().getId());
}
@Override
public TbMsg transformMsg(TbMsg origMsg, TbMsgType type, EntityId originator, TbMsgMetaData metaData, String data) {
return TbMsg.transformMsg(origMsg, type, originator, metaData, data);
}
@Override
public TbMsg transformMsg(TbMsg origMsg, TbMsgMetaData metaData, String data) {
return TbMsg.transformMsg(origMsg, metaData, data);
}
@Override
public TbMsg transformMsgOriginator(TbMsg origMsg, EntityId originator) {
return TbMsg.transformMsgOriginator(origMsg, originator);
}
@Override
public TbMsg customerCreatedMsg(Customer customer, RuleNodeId ruleNodeId) { public TbMsg customerCreatedMsg(Customer customer, RuleNodeId ruleNodeId) {
return entityActionMsg(customer, customer.getId(), ruleNodeId, DataConstants.ENTITY_CREATED); return entityActionMsg(customer, customer.getId(), ruleNodeId, ENTITY_CREATED);
} }
@Override
public TbMsg deviceCreatedMsg(Device device, RuleNodeId ruleNodeId) { public TbMsg deviceCreatedMsg(Device device, RuleNodeId ruleNodeId) {
DeviceProfile deviceProfile = null; DeviceProfile deviceProfile = null;
if (device.getDeviceProfileId() != null) { if (device.getDeviceProfileId() != null) {
deviceProfile = mainCtx.getDeviceProfileCache().find(device.getDeviceProfileId()); deviceProfile = mainCtx.getDeviceProfileCache().find(device.getDeviceProfileId());
} }
return entityActionMsg(device, device.getId(), ruleNodeId, DataConstants.ENTITY_CREATED, deviceProfile); return entityActionMsg(device, device.getId(), ruleNodeId, ENTITY_CREATED, deviceProfile);
} }
@Override
public TbMsg assetCreatedMsg(Asset asset, RuleNodeId ruleNodeId) { public TbMsg assetCreatedMsg(Asset asset, RuleNodeId ruleNodeId) {
AssetProfile assetProfile = null; AssetProfile assetProfile = null;
if (asset.getAssetProfileId() != null) { if (asset.getAssetProfileId() != null) {
assetProfile = mainCtx.getAssetProfileCache().find(asset.getAssetProfileId()); assetProfile = mainCtx.getAssetProfileCache().find(asset.getAssetProfileId());
} }
return entityActionMsg(asset, asset.getId(), ruleNodeId, DataConstants.ENTITY_CREATED, assetProfile); return entityActionMsg(asset, asset.getId(), ruleNodeId, ENTITY_CREATED, assetProfile);
} }
@Override
public TbMsg alarmActionMsg(Alarm alarm, RuleNodeId ruleNodeId, String action) { public TbMsg alarmActionMsg(Alarm alarm, RuleNodeId ruleNodeId, String action) {
EntityId originator = alarm.getOriginator();
HasRuleEngineProfile profile = getRuleEngineProfile(originator);
return entityActionMsg(alarm, originator, ruleNodeId, action, profile);
}
@Override
public TbMsg alarmActionMsg(Alarm alarm, RuleNodeId ruleNodeId, TbMsgType actionMsgType) {
EntityId originator = alarm.getOriginator();
HasRuleEngineProfile profile = getRuleEngineProfile(originator);
return entityActionMsg(alarm, originator, ruleNodeId, actionMsgType, profile);
}
private HasRuleEngineProfile getRuleEngineProfile(EntityId originator) {
HasRuleEngineProfile profile = null; HasRuleEngineProfile profile = null;
if (EntityType.DEVICE.equals(alarm.getOriginator().getEntityType())) { if (EntityType.DEVICE.equals(originator.getEntityType())) {
DeviceId deviceId = new DeviceId(alarm.getOriginator().getId()); DeviceId deviceId = new DeviceId(originator.getId());
profile = mainCtx.getDeviceProfileCache().get(getTenantId(), deviceId); profile = mainCtx.getDeviceProfileCache().get(getTenantId(), deviceId);
} else if (EntityType.ASSET.equals(alarm.getOriginator().getEntityType())) { } else if (EntityType.ASSET.equals(originator.getEntityType())) {
AssetId assetId = new AssetId(alarm.getOriginator().getId()); AssetId assetId = new AssetId(originator.getId());
profile = mainCtx.getAssetProfileCache().get(getTenantId(), assetId); profile = mainCtx.getAssetProfileCache().get(getTenantId(), assetId);
} }
return entityActionMsg(alarm, alarm.getOriginator(), ruleNodeId, action, profile); return profile;
} }
@Override
public TbMsg attributesUpdatedActionMsg(EntityId originator, RuleNodeId ruleNodeId, String scope, List<AttributeKvEntry> attributes) { public TbMsg attributesUpdatedActionMsg(EntityId originator, RuleNodeId ruleNodeId, String scope, List<AttributeKvEntry> attributes) {
ObjectNode entityNode = JacksonUtil.newObjectNode(); ObjectNode entityNode = JacksonUtil.newObjectNode();
if (attributes != null) { if (attributes != null) {
attributes.forEach(attributeKvEntry -> JacksonUtil.addKvEntry(entityNode, attributeKvEntry)); attributes.forEach(attributeKvEntry -> JacksonUtil.addKvEntry(entityNode, attributeKvEntry));
} }
return attributesActionMsg(originator, ruleNodeId, scope, DataConstants.ATTRIBUTES_UPDATED, JacksonUtil.toString(entityNode)); return attributesActionMsg(originator, ruleNodeId, scope, ATTRIBUTES_UPDATED, JacksonUtil.toString(entityNode));
} }
@Override
public TbMsg attributesDeletedActionMsg(EntityId originator, RuleNodeId ruleNodeId, String scope, List<String> keys) { public TbMsg attributesDeletedActionMsg(EntityId originator, RuleNodeId ruleNodeId, String scope, List<String> keys) {
ObjectNode entityNode = JacksonUtil.newObjectNode(); ObjectNode entityNode = JacksonUtil.newObjectNode();
ArrayNode attrsArrayNode = entityNode.putArray("attributes"); ArrayNode attrsArrayNode = entityNode.putArray("attributes");
if (keys != null) { if (keys != null) {
keys.forEach(attrsArrayNode::add); keys.forEach(attrsArrayNode::add);
} }
return attributesActionMsg(originator, ruleNodeId, scope, DataConstants.ATTRIBUTES_DELETED, JacksonUtil.toString(entityNode)); return attributesActionMsg(originator, ruleNodeId, scope, ATTRIBUTES_DELETED, JacksonUtil.toString(entityNode));
} }
private TbMsg attributesActionMsg(EntityId originator, RuleNodeId ruleNodeId, String scope, String action, String msgData) { private TbMsg attributesActionMsg(EntityId originator, RuleNodeId ruleNodeId, String scope, TbMsgType actionMsgType, String msgData) {
TbMsgMetaData tbMsgMetaData = getActionMetaData(ruleNodeId); TbMsgMetaData tbMsgMetaData = getActionMetaData(ruleNodeId);
tbMsgMetaData.putValue("scope", scope); tbMsgMetaData.putValue("scope", scope);
HasRuleEngineProfile profile = null; HasRuleEngineProfile profile = getRuleEngineProfile(originator);
if (EntityType.DEVICE.equals(originator.getEntityType())) { return entityActionMsg(originator, tbMsgMetaData, msgData, actionMsgType, profile);
DeviceId deviceId = new DeviceId(originator.getId());
profile = mainCtx.getDeviceProfileCache().get(getTenantId(), deviceId);
} else if (EntityType.ASSET.equals(originator.getEntityType())) {
AssetId assetId = new AssetId(originator.getId());
profile = mainCtx.getAssetProfileCache().get(getTenantId(), assetId);
}
return entityActionMsg(originator, tbMsgMetaData, msgData, action, profile);
} }
@Override @Override
@ -411,10 +451,11 @@ class DefaultTbContext implements TbContext {
mainCtx.getClusterService().onEdgeEventUpdate(tenantId, edgeId); mainCtx.getClusterService().onEdgeEventUpdate(tenantId, edgeId);
} }
public <E, I extends EntityId> TbMsg entityActionMsg(E entity, I id, RuleNodeId ruleNodeId, String action) { public <E, I extends EntityId> TbMsg entityActionMsg(E entity, I id, RuleNodeId ruleNodeId, TbMsgType actionMsgType) {
return entityActionMsg(entity, id, ruleNodeId, action, null); return entityActionMsg(entity, id, ruleNodeId, actionMsgType, null);
} }
@Deprecated(since = "3.5.2", forRemoval = true)
public <E, I extends EntityId, K extends HasRuleEngineProfile> TbMsg entityActionMsg(E entity, I id, RuleNodeId ruleNodeId, String action, K profile) { public <E, I extends EntityId, K extends HasRuleEngineProfile> TbMsg entityActionMsg(E entity, I id, RuleNodeId ruleNodeId, String action, K profile) {
try { try {
return entityActionMsg(id, getActionMetaData(ruleNodeId), JacksonUtil.toString(JacksonUtil.valueToTree(entity)), action, profile); return entityActionMsg(id, getActionMetaData(ruleNodeId), JacksonUtil.toString(JacksonUtil.valueToTree(entity)), action, profile);
@ -423,6 +464,7 @@ class DefaultTbContext implements TbContext {
} }
} }
@Deprecated(since = "3.5.2", forRemoval = true)
private <I extends EntityId, K extends HasRuleEngineProfile> TbMsg entityActionMsg(I id, TbMsgMetaData msgMetaData, String msgData, String action, K profile) { private <I extends EntityId, K extends HasRuleEngineProfile> TbMsg entityActionMsg(I id, TbMsgMetaData msgMetaData, String msgData, String action, K profile) {
String defaultQueueName = null; String defaultQueueName = null;
RuleChainId defaultRuleChainId = null; RuleChainId defaultRuleChainId = null;
@ -433,6 +475,24 @@ class DefaultTbContext implements TbContext {
return TbMsg.newMsg(defaultQueueName, action, id, msgMetaData, msgData, defaultRuleChainId, null); return TbMsg.newMsg(defaultQueueName, action, id, msgMetaData, msgData, defaultRuleChainId, null);
} }
public <E, I extends EntityId, K extends HasRuleEngineProfile> TbMsg entityActionMsg(E entity, I id, RuleNodeId ruleNodeId, TbMsgType actionMsgType, K profile) {
try {
return entityActionMsg(id, getActionMetaData(ruleNodeId), JacksonUtil.toString(JacksonUtil.valueToTree(entity)), actionMsgType, profile);
} catch (IllegalArgumentException e) {
throw new RuntimeException("Failed to process " + id.getEntityType().name().toLowerCase() + " " + actionMsgType.name() + " msg: " + e);
}
}
private <I extends EntityId, K extends HasRuleEngineProfile> TbMsg entityActionMsg(I id, TbMsgMetaData msgMetaData, String msgData, TbMsgType actionMsgType, K profile) {
String defaultQueueName = null;
RuleChainId defaultRuleChainId = null;
if (profile != null) {
defaultQueueName = profile.getDefaultQueueName();
defaultRuleChainId = profile.getDefaultRuleChainId();
}
return TbMsg.newMsg(defaultQueueName, actionMsgType, id, msgMetaData, msgData, defaultRuleChainId, null);
}
@Override @Override
public RuleNodeId getSelfId() { public RuleNodeId getSelfId() {
return nodeCtx.getSelf().getId(); return nodeCtx.getSelf().getId();

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

@ -16,7 +16,7 @@
package org.thingsboard.server.actors.ruleChain; package org.thingsboard.server.actors.ruleChain;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.thingsboard.rule.engine.api.TbRelationTypes; import org.thingsboard.server.common.data.msg.TbNodeConnectionType;
import org.thingsboard.server.actors.ActorSystemContext; import org.thingsboard.server.actors.ActorSystemContext;
import org.thingsboard.server.actors.TbActorCtx; import org.thingsboard.server.actors.TbActorCtx;
import org.thingsboard.server.actors.TbActorRef; import org.thingsboard.server.actors.TbActorRef;
@ -307,7 +307,7 @@ public class RuleChainActorMessageProcessor extends ComponentMsgProcessor<RuleCh
int relationsCount = relationsByTypes.size(); int relationsCount = relationsByTypes.size();
if (relationsCount == 0) { if (relationsCount == 0) {
log.trace("[{}][{}][{}] No outbound relations to process", tenantId, entityId, msg.getId()); log.trace("[{}][{}][{}] No outbound relations to process", tenantId, entityId, msg.getId());
if (relationTypes.contains(TbRelationTypes.FAILURE)) { if (relationTypes.contains(TbNodeConnectionType.FAILURE)) {
RuleNodeCtx ruleNodeCtx = nodeActors.get(originatorNodeId); RuleNodeCtx ruleNodeCtx = nodeActors.get(originatorNodeId);
if (ruleNodeCtx != null) { if (ruleNodeCtx != null) {
msg.getCallback().onFailure(new RuleNodeException(failureMessage, ruleChainName, ruleNodeCtx.getSelf())); msg.getCallback().onFailure(new RuleNodeException(failureMessage, ruleChainName, ruleNodeCtx.getSelf()));

2
application/src/main/java/org/thingsboard/server/actors/ruleChain/RuleEngineComponentActor.java

@ -22,9 +22,9 @@ import org.thingsboard.server.actors.shared.ComponentMsgProcessor;
import org.thingsboard.server.common.data.id.EntityId; import org.thingsboard.server.common.data.id.EntityId;
import org.thingsboard.server.common.data.id.RuleChainId; import org.thingsboard.server.common.data.id.RuleChainId;
import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.common.data.id.TenantId;
import org.thingsboard.server.common.data.notification.rule.trigger.RuleEngineComponentLifecycleEventTrigger;
import org.thingsboard.server.common.data.plugin.ComponentLifecycleEvent; import org.thingsboard.server.common.data.plugin.ComponentLifecycleEvent;
import org.thingsboard.server.common.msg.TbActorStopReason; import org.thingsboard.server.common.msg.TbActorStopReason;
import org.thingsboard.server.common.data.notification.rule.trigger.RuleEngineComponentLifecycleEventTrigger;
public abstract class RuleEngineComponentActor<T extends EntityId, P extends ComponentMsgProcessor<T>> extends ComponentActor<T, P> { public abstract class RuleEngineComponentActor<T extends EntityId, P extends ComponentMsgProcessor<T>> extends ComponentActor<T, P> {

4
application/src/main/java/org/thingsboard/server/config/RateLimitProcessingFilter.java

@ -24,10 +24,10 @@ import org.springframework.stereotype.Component;
import org.springframework.web.filter.OncePerRequestFilter; import org.springframework.web.filter.OncePerRequestFilter;
import org.thingsboard.server.common.data.EntityType; import org.thingsboard.server.common.data.EntityType;
import org.thingsboard.server.common.data.exception.TenantProfileNotFoundException; import org.thingsboard.server.common.data.exception.TenantProfileNotFoundException;
import org.thingsboard.server.common.msg.tools.TbRateLimitsException;
import org.thingsboard.server.exception.ThingsboardErrorResponseHandler;
import org.thingsboard.server.common.data.limit.LimitedApi; import org.thingsboard.server.common.data.limit.LimitedApi;
import org.thingsboard.server.common.msg.tools.TbRateLimitsException;
import org.thingsboard.server.dao.util.limits.RateLimitService; import org.thingsboard.server.dao.util.limits.RateLimitService;
import org.thingsboard.server.exception.ThingsboardErrorResponseHandler;
import org.thingsboard.server.service.security.model.SecurityUser; import org.thingsboard.server.service.security.model.SecurityUser;
import javax.servlet.FilterChain; import javax.servlet.FilterChain;

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

@ -38,19 +38,18 @@ import org.thingsboard.common.util.JacksonUtil;
import org.thingsboard.rule.engine.api.MailService; import org.thingsboard.rule.engine.api.MailService;
import org.thingsboard.server.common.data.User; import org.thingsboard.server.common.data.User;
import org.thingsboard.server.common.data.audit.ActionType; import org.thingsboard.server.common.data.audit.ActionType;
import org.thingsboard.server.common.data.edge.EdgeEventActionType;
import org.thingsboard.server.common.data.exception.ThingsboardErrorCode; import org.thingsboard.server.common.data.exception.ThingsboardErrorCode;
import org.thingsboard.server.common.data.exception.ThingsboardException; import org.thingsboard.server.common.data.exception.ThingsboardException;
import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.common.data.id.TenantId;
import org.thingsboard.server.common.data.limit.LimitedApi;
import org.thingsboard.server.common.data.security.UserCredentials; import org.thingsboard.server.common.data.security.UserCredentials;
import org.thingsboard.server.common.data.security.event.UserCredentialsInvalidationEvent; import org.thingsboard.server.common.data.security.event.UserCredentialsInvalidationEvent;
import org.thingsboard.server.common.data.security.event.UserSessionInvalidationEvent; import org.thingsboard.server.common.data.security.event.UserSessionInvalidationEvent;
import org.thingsboard.server.common.data.security.model.JwtPair; import org.thingsboard.server.common.data.security.model.JwtPair;
import org.thingsboard.server.common.data.security.model.SecuritySettings; import org.thingsboard.server.common.data.security.model.SecuritySettings;
import org.thingsboard.server.common.data.security.model.UserPasswordPolicy; import org.thingsboard.server.common.data.security.model.UserPasswordPolicy;
import org.thingsboard.server.queue.util.TbCoreComponent;
import org.thingsboard.server.common.data.limit.LimitedApi;
import org.thingsboard.server.dao.util.limits.RateLimitService; import org.thingsboard.server.dao.util.limits.RateLimitService;
import org.thingsboard.server.queue.util.TbCoreComponent;
import org.thingsboard.server.service.security.auth.rest.RestAuthenticationDetails; import org.thingsboard.server.service.security.auth.rest.RestAuthenticationDetails;
import org.thingsboard.server.service.security.model.ActivateUserRequest; import org.thingsboard.server.service.security.model.ActivateUserRequest;
import org.thingsboard.server.service.security.model.ChangePasswordRequest; import org.thingsboard.server.service.security.model.ChangePasswordRequest;
@ -123,8 +122,6 @@ public class AuthController extends BaseController {
userCredentials.setPassword(passwordEncoder.encode(newPassword)); userCredentials.setPassword(passwordEncoder.encode(newPassword));
userService.replaceUserCredentials(securityUser.getTenantId(), userCredentials); userService.replaceUserCredentials(securityUser.getTenantId(), userCredentials);
sendEntityNotificationMsg(getTenantId(), userCredentials.getUserId(), EdgeEventActionType.CREDENTIALS_UPDATED);
eventPublisher.publishEvent(new UserCredentialsInvalidationEvent(securityUser.getId())); eventPublisher.publishEvent(new UserCredentialsInvalidationEvent(securityUser.getId()));
ObjectNode response = JacksonUtil.newObjectNode(); ObjectNode response = JacksonUtil.newObjectNode();
response.put("token", tokenFactory.createAccessJwtToken(securityUser).getToken()); response.put("token", tokenFactory.createAccessJwtToken(securityUser).getToken());
@ -259,8 +256,6 @@ public class AuthController extends BaseController {
} }
} }
sendEntityNotificationMsg(user.getTenantId(), user.getId(), EdgeEventActionType.CREDENTIALS_UPDATED);
return tokenFactory.createTokenPair(securityUser); return tokenFactory.createTokenPair(securityUser);
} }

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

@ -60,8 +60,6 @@ import org.thingsboard.server.common.data.asset.AssetInfo;
import org.thingsboard.server.common.data.asset.AssetProfile; import org.thingsboard.server.common.data.asset.AssetProfile;
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.EdgeEventActionType;
import org.thingsboard.server.common.data.edge.EdgeEventType;
import org.thingsboard.server.common.data.edge.EdgeInfo; import org.thingsboard.server.common.data.edge.EdgeInfo;
import org.thingsboard.server.common.data.exception.ThingsboardErrorCode; import org.thingsboard.server.common.data.exception.ThingsboardErrorCode;
import org.thingsboard.server.common.data.exception.ThingsboardException; import org.thingsboard.server.common.data.exception.ThingsboardException;
@ -142,8 +140,6 @@ import org.thingsboard.server.queue.provider.TbQueueProducerProvider;
import org.thingsboard.server.queue.util.TbCoreComponent; import org.thingsboard.server.queue.util.TbCoreComponent;
import org.thingsboard.server.service.action.EntityActionService; import org.thingsboard.server.service.action.EntityActionService;
import org.thingsboard.server.service.component.ComponentDiscoveryService; import org.thingsboard.server.service.component.ComponentDiscoveryService;
import org.thingsboard.server.service.edge.instructions.EdgeInstallService;
import org.thingsboard.server.service.edge.rpc.EdgeRpcService;
import org.thingsboard.server.service.entitiy.TbNotificationEntityService; import org.thingsboard.server.service.entitiy.TbNotificationEntityService;
import org.thingsboard.server.service.entitiy.user.TbUserSettingsService; import org.thingsboard.server.service.entitiy.user.TbUserSettingsService;
import org.thingsboard.server.service.ota.OtaPackageStateService; import org.thingsboard.server.service.ota.OtaPackageStateService;
@ -301,12 +297,6 @@ public abstract class BaseController {
@Autowired(required = false) @Autowired(required = false)
protected EdgeService edgeService; protected EdgeService edgeService;
@Autowired(required = false)
protected EdgeRpcService edgeRpcService;
@Autowired(required = false)
protected EdgeInstallService edgeInstallService;
@Autowired @Autowired
protected TbNotificationEntityService notificationEntityService; protected TbNotificationEntityService notificationEntityService;
@ -824,18 +814,6 @@ public abstract class BaseController {
} }
} }
protected void sendEntityNotificationMsg(TenantId tenantId, EntityId entityId, EdgeEventActionType action) {
sendNotificationMsgToEdge(tenantId, null, entityId, null, null, action);
}
protected void sendEntityAssignToEdgeNotificationMsg(TenantId tenantId, EdgeId edgeId, EntityId entityId, EdgeEventActionType action) {
sendNotificationMsgToEdge(tenantId, edgeId, entityId, null, null, action);
}
private void sendNotificationMsgToEdge(TenantId tenantId, EdgeId edgeId, EntityId entityId, String body, EdgeEventType type, EdgeEventActionType action) {
tbClusterService.sendNotificationMsgToEdge(tenantId, edgeId, entityId, body, type, action);
}
protected void processDashboardIdFromAdditionalInfo(ObjectNode additionalInfo, String requiredFields) throws ThingsboardException { protected void processDashboardIdFromAdditionalInfo(ObjectNode additionalInfo, String requiredFields) throws ThingsboardException {
String dashboardId = additionalInfo.has(requiredFields) ? additionalInfo.get(requiredFields).asText() : null; String dashboardId = additionalInfo.has(requiredFields) ? additionalInfo.get(requiredFields).asText() : null;
if (dashboardId != null && !dashboardId.equals("null")) { if (dashboardId != null && !dashboardId.equals("null")) {

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

@ -59,6 +59,8 @@ import org.thingsboard.server.dao.exception.IncorrectParameterException;
import org.thingsboard.server.dao.model.ModelConstants; import org.thingsboard.server.dao.model.ModelConstants;
import org.thingsboard.server.queue.util.TbCoreComponent; import org.thingsboard.server.queue.util.TbCoreComponent;
import org.thingsboard.server.service.edge.EdgeBulkImportService; import org.thingsboard.server.service.edge.EdgeBulkImportService;
import org.thingsboard.server.service.edge.instructions.EdgeInstallService;
import org.thingsboard.server.service.edge.rpc.EdgeRpcService;
import org.thingsboard.server.service.entitiy.edge.TbEdgeService; import org.thingsboard.server.service.entitiy.edge.TbEdgeService;
import org.thingsboard.server.service.security.model.SecurityUser; import org.thingsboard.server.service.security.model.SecurityUser;
import org.thingsboard.server.service.security.permission.Operation; import org.thingsboard.server.service.security.permission.Operation;
@ -67,6 +69,7 @@ import org.thingsboard.server.service.security.permission.Resource;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.Optional;
import java.util.UUID; import java.util.UUID;
import java.util.concurrent.ExecutionException; import java.util.concurrent.ExecutionException;
import java.util.stream.Collectors; import java.util.stream.Collectors;
@ -94,8 +97,11 @@ import static org.thingsboard.server.controller.ControllerConstants.UUID_WIKI_LI
@RequestMapping("/api") @RequestMapping("/api")
@RequiredArgsConstructor @RequiredArgsConstructor
public class EdgeController extends BaseController { public class EdgeController extends BaseController {
private final EdgeBulkImportService edgeBulkImportService; private final EdgeBulkImportService edgeBulkImportService;
private final TbEdgeService tbEdgeService; private final TbEdgeService tbEdgeService;
private final Optional<EdgeRpcService> edgeRpcServiceOpt;
private final Optional<EdgeInstallService> edgeInstallServiceOpt;
public static final String EDGE_ID = "edgeId"; public static final String EDGE_ID = "edgeId";
public static final String EDGE_SECURITY_CHECK = "If the user has the authority of 'Tenant Administrator', the server checks that the edge is owned by the same tenant. " + public static final String EDGE_SECURITY_CHECK = "If the user has the authority of 'Tenant Administrator', the server checks that the edge is owned by the same tenant. " +
@ -497,13 +503,13 @@ public class EdgeController extends BaseController {
@PathVariable("edgeId") String strEdgeId) throws ThingsboardException { @PathVariable("edgeId") String strEdgeId) throws ThingsboardException {
checkParameter("edgeId", strEdgeId); checkParameter("edgeId", strEdgeId);
final DeferredResult<ResponseEntity> response = new DeferredResult<>(); final DeferredResult<ResponseEntity> response = new DeferredResult<>();
if (isEdgesEnabled()) { if (isEdgesEnabled() && edgeRpcServiceOpt.isPresent()) {
EdgeId edgeId = new EdgeId(toUUID(strEdgeId)); EdgeId edgeId = new EdgeId(toUUID(strEdgeId));
edgeId = checkNotNull(edgeId); edgeId = checkNotNull(edgeId);
SecurityUser user = getCurrentUser(); SecurityUser user = getCurrentUser();
TenantId tenantId = user.getTenantId(); TenantId tenantId = user.getTenantId();
ToEdgeSyncRequest request = new ToEdgeSyncRequest(UUID.randomUUID(), tenantId, edgeId); ToEdgeSyncRequest request = new ToEdgeSyncRequest(UUID.randomUUID(), tenantId, edgeId);
edgeRpcService.processSyncRequest(request, fromEdgeSyncResponse -> reply(response, fromEdgeSyncResponse)); edgeRpcServiceOpt.get().processSyncRequest(request, fromEdgeSyncResponse -> reply(response, fromEdgeSyncResponse));
} else { } else {
throw new ThingsboardException("Edges support disabled", ThingsboardErrorCode.GENERAL); throw new ThingsboardException("Edges support disabled", ThingsboardErrorCode.GENERAL);
} }
@ -557,9 +563,13 @@ public class EdgeController extends BaseController {
@ApiParam(value = EDGE_ID_PARAM_DESCRIPTION, required = true) @ApiParam(value = EDGE_ID_PARAM_DESCRIPTION, required = true)
@PathVariable("edgeId") String strEdgeId, @PathVariable("edgeId") String strEdgeId,
HttpServletRequest request) throws ThingsboardException { HttpServletRequest request) throws ThingsboardException {
EdgeId edgeId = new EdgeId(toUUID(strEdgeId)); if (isEdgesEnabled() && edgeInstallServiceOpt.isPresent()) {
edgeId = checkNotNull(edgeId); EdgeId edgeId = new EdgeId(toUUID(strEdgeId));
Edge edge = checkEdgeId(edgeId, Operation.READ); edgeId = checkNotNull(edgeId);
return checkNotNull(edgeInstallService.getDockerInstallInstructions(getTenantId(), edge, request)); Edge edge = checkEdgeId(edgeId, Operation.READ);
return checkNotNull(edgeInstallServiceOpt.get().getDockerInstallInstructions(getTenantId(), edge, request));
} else {
throw new ThingsboardException("Edges support disabled", ThingsboardErrorCode.GENERAL);
}
} }
} }

4
application/src/main/java/org/thingsboard/server/controller/RpcV2Controller.java

@ -38,6 +38,7 @@ import org.thingsboard.server.common.data.exception.ThingsboardException;
import org.thingsboard.server.common.data.id.DeviceId; import org.thingsboard.server.common.data.id.DeviceId;
import org.thingsboard.server.common.data.id.RpcId; import org.thingsboard.server.common.data.id.RpcId;
import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.common.data.id.TenantId;
import org.thingsboard.server.common.data.msg.TbMsgType;
import org.thingsboard.server.common.data.page.PageData; import org.thingsboard.server.common.data.page.PageData;
import org.thingsboard.server.common.data.page.PageLink; import org.thingsboard.server.common.data.page.PageLink;
import org.thingsboard.server.common.data.rpc.Rpc; import org.thingsboard.server.common.data.rpc.Rpc;
@ -52,7 +53,6 @@ import org.thingsboard.server.service.security.permission.Operation;
import javax.annotation.Nullable; import javax.annotation.Nullable;
import java.util.UUID; import java.util.UUID;
import static org.thingsboard.server.common.data.DataConstants.RPC_DELETED;
import static org.thingsboard.server.controller.ControllerConstants.DEVICE_ID; import static org.thingsboard.server.controller.ControllerConstants.DEVICE_ID;
import static org.thingsboard.server.controller.ControllerConstants.DEVICE_ID_PARAM_DESCRIPTION; import static org.thingsboard.server.controller.ControllerConstants.DEVICE_ID_PARAM_DESCRIPTION;
import static org.thingsboard.server.controller.ControllerConstants.MARKDOWN_CODE_BLOCK_END; import static org.thingsboard.server.controller.ControllerConstants.MARKDOWN_CODE_BLOCK_END;
@ -239,7 +239,7 @@ public class RpcV2Controller extends AbstractRpcController {
rpcService.deleteRpc(getTenantId(), rpcId); rpcService.deleteRpc(getTenantId(), rpcId);
rpc.setStatus(RpcStatus.DELETED); rpc.setStatus(RpcStatus.DELETED);
TbMsg msg = TbMsg.newMsg(RPC_DELETED, rpc.getDeviceId(), TbMsgMetaData.EMPTY, JacksonUtil.toString(rpc)); TbMsg msg = TbMsg.newMsg(TbMsgType.RPC_DELETED, rpc.getDeviceId(), TbMsgMetaData.EMPTY, JacksonUtil.toString(rpc));
tbClusterService.pushMsgToRuleEngine(getTenantId(), rpc.getDeviceId(), msg, null); tbClusterService.pushMsgToRuleEngine(getTenantId(), rpc.getDeviceId(), msg, null);
} }
} }

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

@ -28,7 +28,6 @@ import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody; import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.ResponseStatus; import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.bind.annotation.RestController; import org.springframework.web.bind.annotation.RestController;
import org.thingsboard.server.common.data.edge.EdgeEventActionType;
import org.thingsboard.server.common.data.exception.ThingsboardException; import org.thingsboard.server.common.data.exception.ThingsboardException;
import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.common.data.id.TenantId;
import org.thingsboard.server.common.data.id.WidgetTypeId; import org.thingsboard.server.common.data.id.WidgetTypeId;
@ -107,9 +106,6 @@ public class WidgetTypeController extends AutoCommitController {
} }
} }
sendEntityNotificationMsg(getTenantId(), savedWidgetTypeDetails.getId(),
widgetTypeDetails.getId() == null ? EdgeEventActionType.ADDED : EdgeEventActionType.UPDATED);
return checkNotNull(savedWidgetTypeDetails); return checkNotNull(savedWidgetTypeDetails);
} }
@ -133,8 +129,6 @@ public class WidgetTypeController extends AutoCommitController {
autoCommit(currentUser, widgetsBundle.getId()); autoCommit(currentUser, widgetsBundle.getId());
} }
} }
sendEntityNotificationMsg(getTenantId(), widgetTypeId, EdgeEventActionType.DELETED);
} }
@ApiOperation(value = "Get all Widget types for specified Bundle (getBundleWidgetTypes)", @ApiOperation(value = "Get all Widget types for specified Bundle (getBundleWidgetTypes)",

2
application/src/main/java/org/thingsboard/server/controller/plugin/TbWebSocketHandler.java

@ -33,10 +33,10 @@ import org.thingsboard.server.common.data.exception.ThingsboardErrorCode;
import org.thingsboard.server.common.data.id.CustomerId; import org.thingsboard.server.common.data.id.CustomerId;
import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.common.data.id.TenantId;
import org.thingsboard.server.common.data.id.UserId; import org.thingsboard.server.common.data.id.UserId;
import org.thingsboard.server.common.data.limit.LimitedApi;
import org.thingsboard.server.common.data.tenant.profile.DefaultTenantProfileConfiguration; import org.thingsboard.server.common.data.tenant.profile.DefaultTenantProfileConfiguration;
import org.thingsboard.server.config.WebSocketConfiguration; import org.thingsboard.server.config.WebSocketConfiguration;
import org.thingsboard.server.dao.tenant.TbTenantProfileCache; import org.thingsboard.server.dao.tenant.TbTenantProfileCache;
import org.thingsboard.server.common.data.limit.LimitedApi;
import org.thingsboard.server.dao.util.limits.RateLimitService; import org.thingsboard.server.dao.util.limits.RateLimitService;
import org.thingsboard.server.queue.util.TbCoreComponent; import org.thingsboard.server.queue.util.TbCoreComponent;
import org.thingsboard.server.service.security.model.SecurityUser; import org.thingsboard.server.service.security.model.SecurityUser;

1
application/src/main/java/org/thingsboard/server/exception/ThingsboardErrorResponseHandler.java

@ -16,7 +16,6 @@
package org.thingsboard.server.exception; package org.thingsboard.server.exception;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpHeaders; import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus; import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType; import org.springframework.http.MediaType;

98
application/src/main/java/org/thingsboard/server/service/action/EntityActionService.java

@ -26,7 +26,6 @@ import org.thingsboard.server.common.data.DataConstants;
import org.thingsboard.server.common.data.EntityType; import org.thingsboard.server.common.data.EntityType;
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.StringUtils;
import org.thingsboard.server.common.data.User; import org.thingsboard.server.common.data.User;
import org.thingsboard.server.common.data.alarm.Alarm; import org.thingsboard.server.common.data.alarm.Alarm;
import org.thingsboard.server.common.data.alarm.AlarmComment; import org.thingsboard.server.common.data.alarm.AlarmComment;
@ -38,19 +37,21 @@ 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.kv.AttributeKvEntry; import org.thingsboard.server.common.data.kv.AttributeKvEntry;
import org.thingsboard.server.common.data.kv.TsKvEntry; import org.thingsboard.server.common.data.kv.TsKvEntry;
import org.thingsboard.server.common.data.msg.TbMsgType;
import org.thingsboard.server.common.data.notification.rule.trigger.AlarmAssignmentTrigger;
import org.thingsboard.server.common.data.notification.rule.trigger.AlarmCommentTrigger;
import org.thingsboard.server.common.data.notification.rule.trigger.EntitiesLimitTrigger;
import org.thingsboard.server.common.data.notification.rule.trigger.EntityActionTrigger;
import org.thingsboard.server.common.data.relation.EntityRelation; import org.thingsboard.server.common.data.relation.EntityRelation;
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.TbMsgDataType;
import org.thingsboard.server.common.msg.TbMsgMetaData; import org.thingsboard.server.common.msg.TbMsgMetaData;
import org.thingsboard.server.common.msg.notification.NotificationRuleProcessor; import org.thingsboard.server.common.msg.notification.NotificationRuleProcessor;
import org.thingsboard.server.common.data.notification.rule.trigger.AlarmAssignmentTrigger;
import org.thingsboard.server.common.data.notification.rule.trigger.AlarmCommentTrigger;
import org.thingsboard.server.common.data.notification.rule.trigger.EntitiesLimitTrigger;
import org.thingsboard.server.common.data.notification.rule.trigger.EntityActionTrigger;
import org.thingsboard.server.dao.audit.AuditLogService; import org.thingsboard.server.dao.audit.AuditLogService;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Optional;
import java.util.stream.Collectors; import java.util.stream.Collectors;
@Service @Service
@ -63,85 +64,8 @@ public class EntityActionService {
public void pushEntityActionToRuleEngine(EntityId entityId, HasName entity, TenantId tenantId, CustomerId customerId, public void pushEntityActionToRuleEngine(EntityId entityId, HasName entity, TenantId tenantId, CustomerId customerId,
ActionType actionType, User user, Object... additionalInfo) { ActionType actionType, User user, Object... additionalInfo) {
String msgType = null; Optional<TbMsgType> msgType = actionType.getRuleEngineMsgType();
switch (actionType) { if (msgType.isPresent()) {
case ADDED:
msgType = DataConstants.ENTITY_CREATED;
break;
case DELETED:
msgType = DataConstants.ENTITY_DELETED;
break;
case UPDATED:
msgType = DataConstants.ENTITY_UPDATED;
break;
case ASSIGNED_TO_CUSTOMER:
msgType = DataConstants.ENTITY_ASSIGNED;
break;
case UNASSIGNED_FROM_CUSTOMER:
msgType = DataConstants.ENTITY_UNASSIGNED;
break;
case ATTRIBUTES_UPDATED:
msgType = DataConstants.ATTRIBUTES_UPDATED;
break;
case ATTRIBUTES_DELETED:
msgType = DataConstants.ATTRIBUTES_DELETED;
break;
case ALARM_ACK:
msgType = DataConstants.ALARM_ACK;
break;
case ALARM_CLEAR:
msgType = DataConstants.ALARM_CLEAR;
break;
case ALARM_ASSIGNED:
msgType = DataConstants.ALARM_ASSIGNED;
break;
case ALARM_UNASSIGNED:
msgType = DataConstants.ALARM_UNASSIGNED;
break;
case ALARM_DELETE:
msgType = DataConstants.ALARM_DELETE;
break;
case ADDED_COMMENT:
msgType = DataConstants.COMMENT_CREATED;
break;
case UPDATED_COMMENT:
msgType = DataConstants.COMMENT_UPDATED;
break;
case ASSIGNED_FROM_TENANT:
msgType = DataConstants.ENTITY_ASSIGNED_FROM_TENANT;
break;
case ASSIGNED_TO_TENANT:
msgType = DataConstants.ENTITY_ASSIGNED_TO_TENANT;
break;
case PROVISION_SUCCESS:
msgType = DataConstants.PROVISION_SUCCESS;
break;
case PROVISION_FAILURE:
msgType = DataConstants.PROVISION_FAILURE;
break;
case TIMESERIES_UPDATED:
msgType = DataConstants.TIMESERIES_UPDATED;
break;
case TIMESERIES_DELETED:
msgType = DataConstants.TIMESERIES_DELETED;
break;
case ASSIGNED_TO_EDGE:
msgType = DataConstants.ENTITY_ASSIGNED_TO_EDGE;
break;
case UNASSIGNED_FROM_EDGE:
msgType = DataConstants.ENTITY_UNASSIGNED_FROM_EDGE;
break;
case RELATION_ADD_OR_UPDATE:
msgType = DataConstants.RELATION_ADD_OR_UPDATE;
break;
case RELATION_DELETED:
msgType = DataConstants.RELATION_DELETED;
break;
case RELATIONS_DELETED:
msgType = DataConstants.RELATIONS_DELETED;
break;
}
if (!StringUtils.isEmpty(msgType)) {
try { try {
TbMsgMetaData metaData = new TbMsgMetaData(); TbMsgMetaData metaData = new TbMsgMetaData();
if (user != null) { if (user != null) {
@ -247,7 +171,7 @@ public class EntityActionService {
if (tenantId != null && !tenantId.isSysTenantId()) { if (tenantId != null && !tenantId.isSysTenantId()) {
processNotificationRules(tenantId, entityId, entity, actionType, user, additionalInfo); processNotificationRules(tenantId, entityId, entity, actionType, user, additionalInfo);
} }
TbMsg tbMsg = TbMsg.newMsg(msgType, entityId, customerId, metaData, TbMsgDataType.JSON, JacksonUtil.toString(entityNode)); TbMsg tbMsg = TbMsg.newMsg(msgType.get(), entityId, customerId, metaData, TbMsgDataType.JSON, JacksonUtil.toString(entityNode));
tbClusterService.pushMsgToRuleEngine(tenantId, entityId, tbMsg, null); tbClusterService.pushMsgToRuleEngine(tenantId, entityId, tbMsg, null);
} catch (Exception e) { } catch (Exception e) {
log.warn("[{}] Failed to push entity action to rule engine: {}", entityId, actionType, e); log.warn("[{}] Failed to push entity action to rule engine: {}", entityId, actionType, e);
@ -313,10 +237,6 @@ public class EntityActionService {
auditLogService.logEntityAction(user.getTenantId(), customerId, user.getId(), user.getName(), entityId, entity, actionType, e, additionalInfo); auditLogService.logEntityAction(user.getTenantId(), customerId, user.getId(), user.getName(), entityId, entity, actionType, e, additionalInfo);
} }
public void sendEntityNotificationMsgToEdge(TenantId tenantId, EntityId entityId, EdgeEventActionType action) {
tbClusterService.sendNotificationMsgToEdge(tenantId, null, entityId, null, null, action);
}
private <T> T extractParameter(Class<T> clazz, int index, Object... additionalInfo) { private <T> T extractParameter(Class<T> clazz, int index, Object... additionalInfo) {
T result = null; T result = null;
if (additionalInfo != null && additionalInfo.length > index) { if (additionalInfo != null && additionalInfo.length > index) {

25
application/src/main/java/org/thingsboard/server/service/component/AnnotationComponentDiscoveryService.java

@ -30,8 +30,12 @@ import org.thingsboard.common.util.JacksonUtil;
import org.thingsboard.rule.engine.api.NodeConfiguration; import org.thingsboard.rule.engine.api.NodeConfiguration;
import org.thingsboard.rule.engine.api.NodeDefinition; import org.thingsboard.rule.engine.api.NodeDefinition;
import org.thingsboard.rule.engine.api.RuleNode; import org.thingsboard.rule.engine.api.RuleNode;
import org.thingsboard.rule.engine.api.TbRelationTypes; import org.thingsboard.server.common.data.msg.TbMsgType;
import org.thingsboard.server.common.data.msg.TbNodeConnectionType;
import org.thingsboard.rule.engine.api.TbVersionedNode; import org.thingsboard.rule.engine.api.TbVersionedNode;
import org.thingsboard.rule.engine.filter.TbMsgTypeSwitchNode;
import org.thingsboard.rule.engine.filter.TbOriginatorTypeSwitchNode;
import org.thingsboard.server.common.data.EntityType;
import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.common.data.id.TenantId;
import org.thingsboard.server.common.data.plugin.ComponentDescriptor; import org.thingsboard.server.common.data.plugin.ComponentDescriptor;
import org.thingsboard.server.common.data.plugin.ComponentType; import org.thingsboard.server.common.data.plugin.ComponentType;
@ -194,7 +198,7 @@ public class AnnotationComponentDiscoveryService implements ComponentDiscoverySe
scannedComponent.setName(ruleNodeAnnotation.name()); scannedComponent.setName(ruleNodeAnnotation.name());
scannedComponent.setScope(ruleNodeAnnotation.scope()); scannedComponent.setScope(ruleNodeAnnotation.scope());
scannedComponent.setClusteringMode(ruleNodeAnnotation.clusteringMode()); scannedComponent.setClusteringMode(ruleNodeAnnotation.clusteringMode());
NodeDefinition nodeDefinition = prepareNodeDefinition(ruleNodeAnnotation); NodeDefinition nodeDefinition = prepareNodeDefinition(clazz, ruleNodeAnnotation);
ObjectNode configurationDescriptor = JacksonUtil.newObjectNode(); ObjectNode configurationDescriptor = JacksonUtil.newObjectNode();
JsonNode node = JacksonUtil.valueToTree(nodeDefinition); JsonNode node = JacksonUtil.valueToTree(nodeDefinition);
configurationDescriptor.set("nodeDefinition", node); configurationDescriptor.set("nodeDefinition", node);
@ -221,13 +225,13 @@ public class AnnotationComponentDiscoveryService implements ComponentDiscoverySe
return scannedComponent; return scannedComponent;
} }
private NodeDefinition prepareNodeDefinition(RuleNode nodeAnnotation) throws Exception { private NodeDefinition prepareNodeDefinition(Class<?> clazz, RuleNode nodeAnnotation) throws Exception {
NodeDefinition nodeDefinition = new NodeDefinition(); NodeDefinition nodeDefinition = new NodeDefinition();
nodeDefinition.setDetails(nodeAnnotation.nodeDetails()); nodeDefinition.setDetails(nodeAnnotation.nodeDetails());
nodeDefinition.setDescription(nodeAnnotation.nodeDescription()); nodeDefinition.setDescription(nodeAnnotation.nodeDescription());
nodeDefinition.setInEnabled(nodeAnnotation.inEnabled()); nodeDefinition.setInEnabled(nodeAnnotation.inEnabled());
nodeDefinition.setOutEnabled(nodeAnnotation.outEnabled()); nodeDefinition.setOutEnabled(nodeAnnotation.outEnabled());
nodeDefinition.setRelationTypes(getRelationTypesWithFailureRelation(nodeAnnotation)); nodeDefinition.setRelationTypes(getRelationTypesWithFailureRelation(clazz, nodeAnnotation));
nodeDefinition.setCustomRelations(nodeAnnotation.customRelations()); nodeDefinition.setCustomRelations(nodeAnnotation.customRelations());
nodeDefinition.setRuleChainNode(nodeAnnotation.ruleChainNode()); nodeDefinition.setRuleChainNode(nodeAnnotation.ruleChainNode());
Class<? extends NodeConfiguration> configClazz = nodeAnnotation.configClazz(); Class<? extends NodeConfiguration> configClazz = nodeAnnotation.configClazz();
@ -242,10 +246,17 @@ public class AnnotationComponentDiscoveryService implements ComponentDiscoverySe
return nodeDefinition; return nodeDefinition;
} }
private String[] getRelationTypesWithFailureRelation(RuleNode nodeAnnotation) { private String[] getRelationTypesWithFailureRelation(Class<?> clazz, RuleNode nodeAnnotation) {
List<String> relationTypes = new ArrayList<>(Arrays.asList(nodeAnnotation.relationTypes())); List<String> relationTypes = new ArrayList<>(Arrays.asList(nodeAnnotation.relationTypes()));
if (!relationTypes.contains(TbRelationTypes.FAILURE)) { if (TbOriginatorTypeSwitchNode.class.equals(clazz)) {
relationTypes.add(TbRelationTypes.FAILURE); relationTypes.addAll(EntityType.NORMAL_NAMES);
}
if (TbMsgTypeSwitchNode.class.equals(clazz)) {
relationTypes.addAll(TbMsgType.NODE_CONNECTIONS);
relationTypes.add(TbNodeConnectionType.OTHER);
}
if (!relationTypes.contains(TbNodeConnectionType.FAILURE)) {
relationTypes.add(TbNodeConnectionType.FAILURE);
} }
return relationTypes.toArray(new String[relationTypes.size()]); return relationTypes.toArray(new String[relationTypes.size()]);
} }

19
application/src/main/java/org/thingsboard/server/service/device/DeviceProvisionServiceImpl.java

@ -36,6 +36,7 @@ import org.thingsboard.server.common.data.id.UserId;
import org.thingsboard.server.common.data.kv.AttributeKvEntry; 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.msg.TbMsgType;
import org.thingsboard.server.common.data.security.DeviceCredentials; import org.thingsboard.server.common.data.security.DeviceCredentials;
import org.thingsboard.server.common.data.security.DeviceCredentialsType; import org.thingsboard.server.common.data.security.DeviceCredentialsType;
import org.thingsboard.server.common.msg.TbMsg; import org.thingsboard.server.common.msg.TbMsg;
@ -162,7 +163,7 @@ public class DeviceProvisionServiceImpl implements DeviceProvisionService {
if (targetProfile.getProfileData().getProvisionConfiguration().getProvisionDeviceSecret().equals(provisionRequestSecret)) { if (targetProfile.getProfileData().getProvisionConfiguration().getProvisionDeviceSecret().equals(provisionRequestSecret)) {
if (targetDevice != null) { if (targetDevice != null) {
log.warn("[{}] The device is present and could not be provisioned once more!", targetDevice.getName()); log.warn("[{}] The device is present and could not be provisioned once more!", targetDevice.getName());
notify(targetDevice, provisionRequest, DataConstants.PROVISION_FAILURE, false); notify(targetDevice, provisionRequest, TbMsgType.PROVISION_FAILURE, false);
throw new ProvisionFailedException(ProvisionResponseStatus.FAILURE.name()); throw new ProvisionFailedException(ProvisionResponseStatus.FAILURE.name());
} else { } else {
return createDevice(provisionRequest, targetProfile); return createDevice(provisionRequest, targetProfile);
@ -190,11 +191,11 @@ public class DeviceProvisionServiceImpl implements DeviceProvisionService {
Optional<AttributeKvEntry> provisionState = attributesService.find(device.getTenantId(), device.getId(), Optional<AttributeKvEntry> provisionState = attributesService.find(device.getTenantId(), device.getId(),
DataConstants.SERVER_SCOPE, DEVICE_PROVISION_STATE).get(); DataConstants.SERVER_SCOPE, DEVICE_PROVISION_STATE).get();
if (provisionState != null && provisionState.isPresent() && !provisionState.get().getValueAsString().equals(PROVISIONED_STATE)) { if (provisionState != null && provisionState.isPresent() && !provisionState.get().getValueAsString().equals(PROVISIONED_STATE)) {
notify(device, provisionRequest, DataConstants.PROVISION_FAILURE, false); notify(device, provisionRequest, TbMsgType.PROVISION_FAILURE, false);
throw new ProvisionFailedException(ProvisionResponseStatus.FAILURE.name()); throw new ProvisionFailedException(ProvisionResponseStatus.FAILURE.name());
} else { } else {
saveProvisionStateAttribute(device).get(); saveProvisionStateAttribute(device).get();
notify(device, provisionRequest, DataConstants.PROVISION_SUCCESS, true); notify(device, provisionRequest, TbMsgType.PROVISION_SUCCESS, true);
} }
} catch (InterruptedException | ExecutionException e) { } catch (InterruptedException | ExecutionException e) {
throw new ProvisionFailedException(ProvisionResponseStatus.FAILURE.name()); throw new ProvisionFailedException(ProvisionResponseStatus.FAILURE.name());
@ -206,7 +207,7 @@ public class DeviceProvisionServiceImpl implements DeviceProvisionService {
return processCreateDevice(provisionRequest, profile); return processCreateDevice(provisionRequest, profile);
} }
private void notify(Device device, ProvisionRequest provisionRequest, String type, boolean success) { private void notify(Device device, ProvisionRequest provisionRequest, TbMsgType type, boolean success) {
pushProvisionEventToRuleEngine(provisionRequest, device, type); pushProvisionEventToRuleEngine(provisionRequest, device, type);
logAction(device.getTenantId(), device.getCustomerId(), device, success, provisionRequest); logAction(device.getTenantId(), device.getCustomerId(), device, success, provisionRequest);
} }
@ -222,14 +223,14 @@ public class DeviceProvisionServiceImpl implements DeviceProvisionService {
clusterService.onDeviceUpdated(savedDevice, null); clusterService.onDeviceUpdated(savedDevice, null);
saveProvisionStateAttribute(savedDevice).get(); saveProvisionStateAttribute(savedDevice).get();
pushDeviceCreatedEventToRuleEngine(savedDevice); pushDeviceCreatedEventToRuleEngine(savedDevice);
notify(savedDevice, provisionRequest, DataConstants.PROVISION_SUCCESS, true); notify(savedDevice, provisionRequest, TbMsgType.PROVISION_SUCCESS, true);
return new ProvisionResponse(getDeviceCredentials(savedDevice), ProvisionResponseStatus.SUCCESS); return new ProvisionResponse(getDeviceCredentials(savedDevice), ProvisionResponseStatus.SUCCESS);
} catch (Exception e) { } catch (Exception e) {
log.warn("[{}] Error during device creation from provision request: [{}]", provisionRequest.getDeviceName(), provisionRequest, e); log.warn("[{}] Error during device creation from provision request: [{}]", provisionRequest.getDeviceName(), provisionRequest, e);
Device device = deviceService.findDeviceByTenantIdAndName(profile.getTenantId(), provisionRequest.getDeviceName()); Device device = deviceService.findDeviceByTenantIdAndName(profile.getTenantId(), provisionRequest.getDeviceName());
if (device != null) { if (device != null) {
notify(device, provisionRequest, DataConstants.PROVISION_FAILURE, false); notify(device, provisionRequest, TbMsgType.PROVISION_FAILURE, false);
} }
throw new ProvisionFailedException(ProvisionResponseStatus.FAILURE.name()); throw new ProvisionFailedException(ProvisionResponseStatus.FAILURE.name());
} }
@ -253,7 +254,7 @@ public class DeviceProvisionServiceImpl implements DeviceProvisionService {
return deviceCredentialsService.findDeviceCredentialsByDeviceId(device.getTenantId(), device.getId()); return deviceCredentialsService.findDeviceCredentialsByDeviceId(device.getTenantId(), device.getId());
} }
private void pushProvisionEventToRuleEngine(ProvisionRequest request, Device device, String type) { private void pushProvisionEventToRuleEngine(ProvisionRequest request, Device device, TbMsgType type) {
try { try {
JsonNode entityNode = JacksonUtil.valueToTree(request); JsonNode entityNode = JacksonUtil.valueToTree(request);
TbMsg msg = TbMsg.newMsg(type, device.getId(), device.getCustomerId(), createTbMsgMetaData(device), JacksonUtil.toString(entityNode)); TbMsg msg = TbMsg.newMsg(type, device.getId(), device.getCustomerId(), createTbMsgMetaData(device), JacksonUtil.toString(entityNode));
@ -266,10 +267,10 @@ public class DeviceProvisionServiceImpl implements DeviceProvisionService {
private void pushDeviceCreatedEventToRuleEngine(Device device) { private void pushDeviceCreatedEventToRuleEngine(Device device) {
try { try {
ObjectNode entityNode = JacksonUtil.OBJECT_MAPPER.valueToTree(device); ObjectNode entityNode = JacksonUtil.OBJECT_MAPPER.valueToTree(device);
TbMsg msg = TbMsg.newMsg(DataConstants.ENTITY_CREATED, device.getId(), device.getCustomerId(), createTbMsgMetaData(device), JacksonUtil.OBJECT_MAPPER.writeValueAsString(entityNode)); TbMsg msg = TbMsg.newMsg(TbMsgType.ENTITY_CREATED, device.getId(), device.getCustomerId(), createTbMsgMetaData(device), JacksonUtil.OBJECT_MAPPER.writeValueAsString(entityNode));
sendToRuleEngine(device.getTenantId(), msg, null); sendToRuleEngine(device.getTenantId(), msg, null);
} catch (JsonProcessingException | IllegalArgumentException e) { } catch (JsonProcessingException | IllegalArgumentException e) {
log.warn("[{}] Failed to push device action to rule engine: {}", device.getId(), DataConstants.ENTITY_CREATED, e); log.warn("[{}] Failed to push device action to rule engine: {}", device.getId(), TbMsgType.ENTITY_CREATED.name(), e);
} }
} }

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

@ -15,7 +15,6 @@
*/ */
package org.thingsboard.server.service.edge; package org.thingsboard.server.service.edge;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.node.ObjectNode; import com.fasterxml.jackson.databind.node.ObjectNode;
import com.google.common.util.concurrent.FutureCallback; import com.google.common.util.concurrent.FutureCallback;
import com.google.common.util.concurrent.Futures; import com.google.common.util.concurrent.Futures;
@ -23,22 +22,18 @@ import com.google.common.util.concurrent.ListenableFuture;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.checkerframework.checker.nullness.qual.Nullable; import org.checkerframework.checker.nullness.qual.Nullable;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.thingsboard.common.util.JacksonUtil; import org.thingsboard.common.util.JacksonUtil;
import org.thingsboard.common.util.ThingsBoardThreadFactory; import org.thingsboard.common.util.ThingsBoardThreadFactory;
import org.thingsboard.server.cluster.TbClusterService; import org.thingsboard.server.common.data.audit.ActionType;
import org.thingsboard.server.common.data.EdgeUtils;
import org.thingsboard.server.common.data.edge.Edge; import org.thingsboard.server.common.data.edge.Edge;
import org.thingsboard.server.common.data.edge.EdgeEvent;
import org.thingsboard.server.common.data.edge.EdgeEventActionType;
import org.thingsboard.server.common.data.edge.EdgeEventType; import org.thingsboard.server.common.data.edge.EdgeEventType;
import org.thingsboard.server.common.data.id.EdgeId;
import org.thingsboard.server.common.data.id.EntityId;
import org.thingsboard.server.common.data.id.RuleChainId; import org.thingsboard.server.common.data.id.RuleChainId;
import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.common.data.id.TenantId;
import org.thingsboard.server.common.msg.queue.TbCallback; import org.thingsboard.server.common.msg.queue.TbCallback;
import org.thingsboard.server.dao.edge.EdgeEventService;
import org.thingsboard.server.dao.edge.EdgeService; import org.thingsboard.server.dao.edge.EdgeService;
import org.thingsboard.server.dao.eventsourcing.ActionEntityEvent;
import org.thingsboard.server.gen.transport.TransportProtos; import org.thingsboard.server.gen.transport.TransportProtos;
import org.thingsboard.server.queue.util.TbCoreComponent; import org.thingsboard.server.queue.util.TbCoreComponent;
import org.thingsboard.server.service.edge.rpc.processor.alarm.AlarmEdgeProcessor; import org.thingsboard.server.service.edge.rpc.processor.alarm.AlarmEdgeProcessor;
@ -74,12 +69,6 @@ public class DefaultEdgeNotificationService implements EdgeNotificationService {
@Autowired @Autowired
private EdgeService edgeService; private EdgeService edgeService;
@Autowired
private EdgeEventService edgeEventService;
@Autowired
private TbClusterService clusterService;
@Autowired @Autowired
private EdgeProcessor edgeProcessor; private EdgeProcessor edgeProcessor;
@ -128,6 +117,9 @@ public class DefaultEdgeNotificationService implements EdgeNotificationService {
@Autowired @Autowired
private RelationEdgeProcessor relationProcessor; private RelationEdgeProcessor relationProcessor;
@Autowired
protected ApplicationEventPublisher eventPublisher;
private ExecutorService dbCallBackExecutor; private ExecutorService dbCallBackExecutor;
@PostConstruct @PostConstruct
@ -143,32 +135,16 @@ public class DefaultEdgeNotificationService implements EdgeNotificationService {
} }
@Override @Override
public Edge setEdgeRootRuleChain(TenantId tenantId, Edge edge, RuleChainId ruleChainId) throws Exception { public Edge setEdgeRootRuleChain(TenantId tenantId, Edge edge, RuleChainId ruleChainId) {
edge.setRootRuleChainId(ruleChainId); edge.setRootRuleChainId(ruleChainId);
Edge savedEdge = edgeService.saveEdge(edge); Edge savedEdge = edgeService.saveEdge(edge);
ObjectNode isRootBody = JacksonUtil.newObjectNode(); ObjectNode isRootBody = JacksonUtil.newObjectNode();
isRootBody.put(EDGE_IS_ROOT_BODY_KEY, Boolean.TRUE); isRootBody.put(EDGE_IS_ROOT_BODY_KEY, Boolean.TRUE);
saveEdgeEvent(tenantId, edge.getId(), EdgeEventType.RULE_CHAIN, EdgeEventActionType.UPDATED, ruleChainId, isRootBody).get(); eventPublisher.publishEvent(ActionEntityEvent.builder().tenantId(tenantId).edgeId(edge.getId()).entityId(ruleChainId)
.body(JacksonUtil.toString(isRootBody)).actionType(ActionType.UPDATED).build());
return savedEdge; return savedEdge;
} }
private ListenableFuture<Void> saveEdgeEvent(TenantId tenantId,
EdgeId edgeId,
EdgeEventType type,
EdgeEventActionType action,
EntityId entityId,
JsonNode body) {
log.debug("Pushing edge event to edge queue. tenantId [{}], edgeId [{}], type [{}], action[{}], entityId [{}], body [{}]",
tenantId, edgeId, type, action, entityId, body);
EdgeEvent edgeEvent = EdgeUtils.constructEdgeEvent(tenantId, edgeId, type, action, entityId, body);
return Futures.transform(edgeEventService.saveAsync(edgeEvent), unused -> {
clusterService.onEdgeEventUpdate(tenantId, edgeId);
return null;
}, dbCallBackExecutor);
}
@Override @Override
public void pushNotificationToEdge(TransportProtos.EdgeNotificationMsgProto edgeNotificationMsg, TbCallback callback) { public void pushNotificationToEdge(TransportProtos.EdgeNotificationMsgProto edgeNotificationMsg, TbCallback callback) {
log.debug("Pushing notification to edge {}", edgeNotificationMsg); log.debug("Pushing notification to edge {}", edgeNotificationMsg);
@ -181,43 +157,43 @@ public class DefaultEdgeNotificationService implements EdgeNotificationService {
future = edgeProcessor.processEdgeNotification(tenantId, edgeNotificationMsg); future = edgeProcessor.processEdgeNotification(tenantId, edgeNotificationMsg);
break; break;
case ASSET: case ASSET:
future = assetProcessor.processAssetNotification(tenantId, edgeNotificationMsg); future = assetProcessor.processEntityNotification(tenantId, edgeNotificationMsg);
break; break;
case DEVICE: case DEVICE:
future = deviceProcessor.processDeviceNotification(tenantId, edgeNotificationMsg); future = deviceProcessor.processEntityNotification(tenantId, edgeNotificationMsg);
break; break;
case ENTITY_VIEW: case ENTITY_VIEW:
future = entityViewProcessor.processEntityViewNotification(tenantId, edgeNotificationMsg); future = entityViewProcessor.processEntityNotification(tenantId, edgeNotificationMsg);
break; break;
case DASHBOARD: case DASHBOARD:
future = dashboardProcessor.processDashboardNotification(tenantId, edgeNotificationMsg); future = dashboardProcessor.processEntityNotification(tenantId, edgeNotificationMsg);
break; break;
case RULE_CHAIN: case RULE_CHAIN:
future = ruleChainProcessor.processRuleChainNotification(tenantId, edgeNotificationMsg); future = ruleChainProcessor.processEntityNotification(tenantId, edgeNotificationMsg);
break; break;
case USER: case USER:
future = userProcessor.processUserNotification(tenantId, edgeNotificationMsg); future = userProcessor.processEntityNotification(tenantId, edgeNotificationMsg);
break; break;
case CUSTOMER: case CUSTOMER:
future = customerProcessor.processCustomerNotification(tenantId, edgeNotificationMsg); future = customerProcessor.processCustomerNotification(tenantId, edgeNotificationMsg);
break; break;
case DEVICE_PROFILE: case DEVICE_PROFILE:
future = deviceProfileProcessor.processDeviceProfileNotification(tenantId, edgeNotificationMsg); future = deviceProfileProcessor.processEntityNotification(tenantId, edgeNotificationMsg);
break; break;
case ASSET_PROFILE: case ASSET_PROFILE:
future = assetProfileProcessor.processAssetProfileNotification(tenantId, edgeNotificationMsg); future = assetProfileProcessor.processEntityNotification(tenantId, edgeNotificationMsg);
break; break;
case OTA_PACKAGE: case OTA_PACKAGE:
future = otaPackageProcessor.processOtaPackageNotification(tenantId, edgeNotificationMsg); future = otaPackageProcessor.processEntityNotification(tenantId, edgeNotificationMsg);
break; break;
case WIDGETS_BUNDLE: case WIDGETS_BUNDLE:
future = widgetBundleProcessor.processWidgetsBundleNotification(tenantId, edgeNotificationMsg); future = widgetBundleProcessor.processEntityNotification(tenantId, edgeNotificationMsg);
break; break;
case WIDGET_TYPE: case WIDGET_TYPE:
future = widgetTypeProcessor.processWidgetTypeNotification(tenantId, edgeNotificationMsg); future = widgetTypeProcessor.processEntityNotification(tenantId, edgeNotificationMsg);
break; break;
case QUEUE: case QUEUE:
future = queueProcessor.processQueueNotification(tenantId, edgeNotificationMsg); future = queueProcessor.processEntityNotification(tenantId, edgeNotificationMsg);
break; break;
case ALARM: case ALARM:
future = alarmProcessor.processAlarmNotification(tenantId, edgeNotificationMsg); future = alarmProcessor.processAlarmNotification(tenantId, edgeNotificationMsg);

158
application/src/main/java/org/thingsboard/server/service/edge/EdgeEventSourcingListener.java

@ -0,0 +1,158 @@
/**
* Copyright © 2016-2023 The Thingsboard Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.thingsboard.server.service.edge;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import org.springframework.transaction.event.TransactionalEventListener;
import org.thingsboard.common.util.JacksonUtil;
import org.thingsboard.server.cluster.TbClusterService;
import org.thingsboard.server.common.data.OtaPackageInfo;
import org.thingsboard.server.common.data.User;
import org.thingsboard.server.common.data.alarm.AlarmApiCallResult;
import org.thingsboard.server.common.data.edge.EdgeEventActionType;
import org.thingsboard.server.common.data.edge.EdgeEventType;
import org.thingsboard.server.common.data.relation.EntityRelation;
import org.thingsboard.server.common.data.relation.RelationTypeGroup;
import org.thingsboard.server.common.data.rule.RuleChain;
import org.thingsboard.server.common.data.rule.RuleChainType;
import org.thingsboard.server.common.data.security.Authority;
import org.thingsboard.server.dao.edge.EdgeSynchronizationManager;
import org.thingsboard.server.dao.eventsourcing.ActionEntityEvent;
import org.thingsboard.server.dao.eventsourcing.DeleteEntityEvent;
import org.thingsboard.server.dao.eventsourcing.RelationActionEvent;
import org.thingsboard.server.dao.eventsourcing.SaveEntityEvent;
import javax.annotation.PostConstruct;
import static org.thingsboard.server.service.entitiy.DefaultTbNotificationEntityService.edgeTypeByActionType;
/**
* This event listener does not support async event processing because relay on ThreadLocal
* Another possible approach is to implement a special annotation and a bunch of classes similar to TransactionalApplicationListener
* This class is the simplest approach to maintain edge synchronization within the single class.
* <p>
* For async event publishers, you have to decide whether publish event on creating async task in the same thread where dao method called
* @Autowired
* EdgeEventSynchronizationManager edgeSynchronizationManager
* ...
* //some async write action make future
* if (!edgeSynchronizationManager.isSync()) {
* future.addCallback(eventPublisher.publishEvent(...))
* }
* */
@Component
@RequiredArgsConstructor
@Slf4j
public class EdgeEventSourcingListener {
private final TbClusterService tbClusterService;
private final EdgeSynchronizationManager edgeSynchronizationManager;
@PostConstruct
public void init() {
log.info("EdgeEventSourcingListener initiated");
}
@TransactionalEventListener(fallbackExecution = true)
public void handleEvent(SaveEntityEvent<?> event) {
if (edgeSynchronizationManager.isSync()) {
return;
}
try {
if (!isValidEdgeEventEntity(event.getEntity())) {
return;
}
log.trace("[{}] SaveEntityEvent called: {}", event.getTenantId(), event);
EdgeEventActionType action = Boolean.TRUE.equals(event.getAdded()) ? EdgeEventActionType.ADDED : EdgeEventActionType.UPDATED;
tbClusterService.sendNotificationMsgToEdge(event.getTenantId(), null, event.getEntityId(),
null, null, action);
} catch (Exception e) {
log.error("[{}] failed to process SaveEntityEvent: {}", event.getTenantId(), event);
}
}
@TransactionalEventListener(fallbackExecution = true)
public void handleEvent(DeleteEntityEvent<?> event) {
if (edgeSynchronizationManager.isSync()) {
return;
}
try {
log.trace("[{}] DeleteEntityEvent called: {}", event.getTenantId(), event);
tbClusterService.sendNotificationMsgToEdge(event.getTenantId(), event.getEdgeId(), event.getEntityId(),
JacksonUtil.toString(event.getEntity()), null, EdgeEventActionType.DELETED);
} catch (Exception e) {
log.error("[{}] failed to process DeleteEntityEvent: {}", event.getTenantId(), event);
}
}
@TransactionalEventListener(fallbackExecution = true)
public void handleEvent(ActionEntityEvent event) {
if (edgeSynchronizationManager.isSync()) {
return;
}
try {
log.trace("[{}] ActionEntityEvent called: {}", event.getTenantId(), event);
tbClusterService.sendNotificationMsgToEdge(event.getTenantId(), event.getEdgeId(), event.getEntityId(),
event.getBody(), null, edgeTypeByActionType(event.getActionType()));
} catch (Exception e) {
log.error("[{}] failed to process ActionEntityEvent: {}", event.getTenantId(), event);
}
}
@TransactionalEventListener(fallbackExecution = true)
public void handleEvent(RelationActionEvent event) {
if (edgeSynchronizationManager.isSync()) {
return;
}
try {
EntityRelation relation = event.getRelation();
if (relation == null) {
log.trace("[{}] skipping RelationActionEvent event in case relation is null: {}", event.getTenantId(), event);
return;
}
if (!RelationTypeGroup.COMMON.equals(relation.getTypeGroup())) {
log.trace("[{}] skipping RelationActionEvent event in case NOT COMMON relation type group: {}", event.getTenantId(), event);
return;
}
log.trace("[{}] RelationActionEvent called: {}", event.getTenantId(), event);
tbClusterService.sendNotificationMsgToEdge(event.getTenantId(), null, null,
JacksonUtil.toString(relation), EdgeEventType.RELATION, edgeTypeByActionType(event.getActionType()));
} catch (Exception e) {
log.error("[{}] failed to process RelationActionEvent: {}", event.getTenantId(), event);
}
}
private boolean isValidEdgeEventEntity(Object entity) {
if (entity instanceof OtaPackageInfo) {
OtaPackageInfo otaPackageInfo = (OtaPackageInfo) entity;
return otaPackageInfo.hasUrl() || otaPackageInfo.isHasData();
} else if (entity instanceof RuleChain) {
RuleChain ruleChain = (RuleChain) entity;
return RuleChainType.EDGE.equals(ruleChain.getType());
} else if (entity instanceof User) {
User user = (User) entity;
return !Authority.SYS_ADMIN.equals(user.getAuthority());
} else if (entity instanceof AlarmApiCallResult) {
AlarmApiCallResult alarmApiCallResult = (AlarmApiCallResult) entity;
return alarmApiCallResult.isModified();
}
// Default: If the entity doesn't match any of the conditions, consider it as valid.
return true;
}
}

15
application/src/main/java/org/thingsboard/server/service/edge/rpc/EdgeGrpcService.java

@ -37,6 +37,7 @@ import org.thingsboard.server.common.data.id.TenantId;
import org.thingsboard.server.common.data.kv.BasicTsKvEntry; import org.thingsboard.server.common.data.kv.BasicTsKvEntry;
import org.thingsboard.server.common.data.kv.BooleanDataEntry; import org.thingsboard.server.common.data.kv.BooleanDataEntry;
import org.thingsboard.server.common.data.kv.LongDataEntry; import org.thingsboard.server.common.data.kv.LongDataEntry;
import org.thingsboard.server.common.data.msg.TbMsgType;
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.TbMsgDataType;
import org.thingsboard.server.common.msg.TbMsgMetaData; import org.thingsboard.server.common.msg.TbMsgMetaData;
@ -71,10 +72,6 @@ import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock; import java.util.concurrent.locks.ReentrantLock;
import java.util.function.Consumer; import java.util.function.Consumer;
import static org.thingsboard.server.common.data.DataConstants.CONNECT_EVENT;
import static org.thingsboard.server.common.data.DataConstants.DISCONNECT_EVENT;
import static org.thingsboard.server.common.data.DataConstants.SERVER_SCOPE;
@Service @Service
@Slf4j @Slf4j
@ConditionalOnProperty(prefix = "edges", value = "enabled", havingValue = "true") @ConditionalOnProperty(prefix = "edges", value = "enabled", havingValue = "true")
@ -278,7 +275,7 @@ public class EdgeGrpcService extends EdgeRpcServiceGrpc.EdgeRpcServiceImplBase i
save(edgeId, DefaultDeviceStateService.ACTIVITY_STATE, true); save(edgeId, DefaultDeviceStateService.ACTIVITY_STATE, true);
long lastConnectTs = System.currentTimeMillis(); long lastConnectTs = System.currentTimeMillis();
save(edgeId, DefaultDeviceStateService.LAST_CONNECT_TIME, lastConnectTs); save(edgeId, DefaultDeviceStateService.LAST_CONNECT_TIME, lastConnectTs);
pushRuleEngineMessage(edgeGrpcSession.getEdge().getTenantId(), edgeId, lastConnectTs, CONNECT_EVENT); pushRuleEngineMessage(edgeGrpcSession.getEdge().getTenantId(), edgeId, lastConnectTs, TbMsgType.CONNECT_EVENT);
cancelScheduleEdgeEventsCheck(edgeId); cancelScheduleEdgeEventsCheck(edgeId);
scheduleEdgeEventsCheck(edgeGrpcSession); scheduleEdgeEventsCheck(edgeGrpcSession);
} }
@ -398,7 +395,7 @@ public class EdgeGrpcService extends EdgeRpcServiceGrpc.EdgeRpcServiceImplBase i
save(edgeId, DefaultDeviceStateService.ACTIVITY_STATE, false); save(edgeId, DefaultDeviceStateService.ACTIVITY_STATE, false);
long lastDisconnectTs = System.currentTimeMillis(); long lastDisconnectTs = System.currentTimeMillis();
save(edgeId, DefaultDeviceStateService.LAST_DISCONNECT_TIME, lastDisconnectTs); save(edgeId, DefaultDeviceStateService.LAST_DISCONNECT_TIME, lastDisconnectTs);
pushRuleEngineMessage(toRemove.getEdge().getTenantId(), edgeId, lastDisconnectTs, DISCONNECT_EVENT); pushRuleEngineMessage(toRemove.getEdge().getTenantId(), edgeId, lastDisconnectTs, TbMsgType.DISCONNECT_EVENT);
cancelScheduleEdgeEventsCheck(edgeId); cancelScheduleEdgeEventsCheck(edgeId);
} else { } else {
log.debug("[{}] edge session [{}] is not available anymore, nothing to remove. most probably this session is already outdated!", edgeId, sessionId); log.debug("[{}] edge session [{}] is not available anymore, nothing to remove. most probably this session is already outdated!", edgeId, sessionId);
@ -451,10 +448,10 @@ public class EdgeGrpcService extends EdgeRpcServiceGrpc.EdgeRpcServiceImplBase i
} }
} }
private void pushRuleEngineMessage(TenantId tenantId, EdgeId edgeId, long ts, String msgType) { private void pushRuleEngineMessage(TenantId tenantId, EdgeId edgeId, long ts, TbMsgType msgType) {
try { try {
ObjectNode edgeState = JacksonUtil.newObjectNode(); ObjectNode edgeState = JacksonUtil.newObjectNode();
if (msgType.equals(CONNECT_EVENT)) { if (msgType.equals(TbMsgType.CONNECT_EVENT)) {
edgeState.put(DefaultDeviceStateService.ACTIVITY_STATE, true); edgeState.put(DefaultDeviceStateService.ACTIVITY_STATE, true);
edgeState.put(DefaultDeviceStateService.LAST_CONNECT_TIME, ts); edgeState.put(DefaultDeviceStateService.LAST_CONNECT_TIME, ts);
} else { } else {
@ -464,7 +461,7 @@ public class EdgeGrpcService extends EdgeRpcServiceGrpc.EdgeRpcServiceImplBase i
String data = JacksonUtil.toString(edgeState); String data = JacksonUtil.toString(edgeState);
TbMsgMetaData md = new TbMsgMetaData(); TbMsgMetaData md = new TbMsgMetaData();
if (!persistToTelemetry) { if (!persistToTelemetry) {
md.putValue(DataConstants.SCOPE, SERVER_SCOPE); md.putValue(DataConstants.SCOPE, DataConstants.SERVER_SCOPE);
} }
TbMsg tbMsg = TbMsg.newMsg(msgType, edgeId, md, TbMsgDataType.JSON, data); TbMsg tbMsg = TbMsg.newMsg(msgType, edgeId, md, TbMsgDataType.JSON, data);
clusterService.pushMsgToRuleEngine(tenantId, edgeId, tbMsg, null); clusterService.pushMsgToRuleEngine(tenantId, edgeId, tbMsg, null);

88
application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/BaseEdgeProcessor.java

@ -21,6 +21,7 @@ import com.google.common.util.concurrent.ListenableFuture;
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.context.annotation.Lazy; import org.springframework.context.annotation.Lazy;
import org.thingsboard.common.util.JacksonUtil;
import org.thingsboard.server.cluster.TbClusterService; import org.thingsboard.server.cluster.TbClusterService;
import org.thingsboard.server.common.data.Device; import org.thingsboard.server.common.data.Device;
import org.thingsboard.server.common.data.EdgeUtils; import org.thingsboard.server.common.data.EdgeUtils;
@ -55,6 +56,7 @@ import org.thingsboard.server.dao.device.DeviceProfileService;
import org.thingsboard.server.dao.device.DeviceService; import org.thingsboard.server.dao.device.DeviceService;
import org.thingsboard.server.dao.edge.EdgeEventService; import org.thingsboard.server.dao.edge.EdgeEventService;
import org.thingsboard.server.dao.edge.EdgeService; import org.thingsboard.server.dao.edge.EdgeService;
import org.thingsboard.server.dao.edge.EdgeSynchronizationManager;
import org.thingsboard.server.dao.entityview.EntityViewService; import org.thingsboard.server.dao.entityview.EntityViewService;
import org.thingsboard.server.dao.ota.OtaPackageService; import org.thingsboard.server.dao.ota.OtaPackageService;
import org.thingsboard.server.dao.queue.QueueService; import org.thingsboard.server.dao.queue.QueueService;
@ -249,15 +251,18 @@ public abstract class BaseEdgeProcessor {
@Autowired @Autowired
protected QueueMsgConstructor queueMsgConstructor; protected QueueMsgConstructor queueMsgConstructor;
@Autowired
protected EdgeSynchronizationManager edgeSynchronizationManager;
@Autowired @Autowired
protected DbCallbackExecutorService dbCallbackExecutorService; protected DbCallbackExecutorService dbCallbackExecutorService;
protected ListenableFuture<Void> saveEdgeEvent(TenantId tenantId, protected ListenableFuture<Void> saveEdgeEvent(TenantId tenantId,
EdgeId edgeId, EdgeId edgeId,
EdgeEventType type, EdgeEventType type,
EdgeEventActionType action, EdgeEventActionType action,
EntityId entityId, EntityId entityId,
JsonNode body) { JsonNode body) {
log.debug("Pushing event to edge queue. tenantId [{}], edgeId [{}], type[{}], " + log.debug("Pushing event to edge queue. tenantId [{}], edgeId [{}], type[{}], " +
"action [{}], entityId [{}], body [{}]", "action [{}], entityId [{}], body [{}]",
tenantId, edgeId, type, action, entityId, body); tenantId, edgeId, type, action, entityId, body);
@ -288,7 +293,7 @@ public abstract class BaseEdgeProcessor {
return Futures.transform(Futures.allAsList(futures), voids -> null, dbCallbackExecutorService); return Futures.transform(Futures.allAsList(futures), voids -> null, dbCallbackExecutorService);
} }
protected List<ListenableFuture<Void>> processActionForAllEdgesByTenantId(TenantId tenantId, private List<ListenableFuture<Void>> processActionForAllEdgesByTenantId(TenantId tenantId,
EdgeEventType type, EdgeEventType type,
EdgeEventActionType actionType, EdgeEventActionType actionType,
EntityId entityId, EntityId entityId,
@ -340,36 +345,46 @@ public abstract class BaseEdgeProcessor {
} }
} }
protected ListenableFuture<Void> processEntityNotification(TenantId tenantId, TransportProtos.EdgeNotificationMsgProto edgeNotificationMsg) { public ListenableFuture<Void> processEntityNotification(TenantId tenantId, TransportProtos.EdgeNotificationMsgProto edgeNotificationMsg) {
EdgeEventActionType actionType = EdgeEventActionType.valueOf(edgeNotificationMsg.getAction());
EdgeEventType type = EdgeEventType.valueOf(edgeNotificationMsg.getType()); EdgeEventType type = EdgeEventType.valueOf(edgeNotificationMsg.getType());
EntityId entityId = EntityIdFactory.getByEdgeEventTypeAndUuid(type, EdgeEventActionType actionType = EdgeEventActionType.valueOf(edgeNotificationMsg.getAction());
new UUID(edgeNotificationMsg.getEntityIdMSB(), edgeNotificationMsg.getEntityIdLSB())); EntityId entityId = EntityIdFactory.getByEdgeEventTypeAndUuid(type, new UUID(edgeNotificationMsg.getEntityIdMSB(), edgeNotificationMsg.getEntityIdLSB()));
EdgeId edgeId = safeGetEdgeId(edgeNotificationMsg); if (type.isAllEdgesRelated()) {
switch (actionType) { return processEntityNotificationForAllEdges(tenantId, type, actionType, entityId);
case ADDED: } else {
case UPDATED: JsonNode body = JacksonUtil.toJsonNode(edgeNotificationMsg.getBody());
case CREDENTIALS_UPDATED: EdgeId edgeId = safeGetEdgeId(edgeNotificationMsg);
case ASSIGNED_TO_CUSTOMER: switch (actionType) {
case UNASSIGNED_FROM_CUSTOMER: case UPDATED:
case DELETED: case CREDENTIALS_UPDATED:
if (edgeId != null) { case ASSIGNED_TO_CUSTOMER:
return saveEdgeEvent(tenantId, edgeId, type, actionType, entityId, null); case UNASSIGNED_FROM_CUSTOMER:
} else { if (edgeId != null) {
return pushNotificationToAllRelatedEdges(tenantId, entityId, type, actionType); return saveEdgeEvent(tenantId, edgeId, type, actionType, entityId, body);
}
case ASSIGNED_TO_EDGE:
case UNASSIGNED_FROM_EDGE:
ListenableFuture<Void> future = saveEdgeEvent(tenantId, edgeId, type, actionType, entityId, null);
return Futures.transformAsync(future, unused -> {
if (type.equals(EdgeEventType.RULE_CHAIN)) {
return updateDependentRuleChains(tenantId, new RuleChainId(entityId.getId()), edgeId);
} else { } else {
return Futures.immediateFuture(null); return processNotificationToRelatedEdges(tenantId, entityId, type, actionType);
} }
}, dbCallbackExecutorService); case DELETED:
default: EdgeEventActionType deleted = EdgeEventActionType.DELETED;
return Futures.immediateFuture(null); if (edgeId != null) {
return saveEdgeEvent(tenantId, edgeId, type, deleted, entityId, body);
} else {
return Futures.transform(Futures.allAsList(processActionForAllEdgesByTenantId(tenantId, type, deleted, entityId, body)),
voids -> null, dbCallbackExecutorService);
}
case ASSIGNED_TO_EDGE:
case UNASSIGNED_FROM_EDGE:
ListenableFuture<Void> future = saveEdgeEvent(tenantId, edgeId, type, actionType, entityId, body);
return Futures.transformAsync(future, unused -> {
if (type.equals(EdgeEventType.RULE_CHAIN)) {
return updateDependentRuleChains(tenantId, new RuleChainId(entityId.getId()), edgeId);
} else {
return Futures.immediateFuture(null);
}
}, dbCallbackExecutorService);
default:
return Futures.immediateFuture(null);
}
} }
} }
@ -381,7 +396,7 @@ public abstract class BaseEdgeProcessor {
} }
} }
private ListenableFuture<Void> pushNotificationToAllRelatedEdges(TenantId tenantId, EntityId entityId, EdgeEventType type, EdgeEventActionType actionType) { private ListenableFuture<Void> processNotificationToRelatedEdges(TenantId tenantId, EntityId entityId, EdgeEventType type, EdgeEventActionType actionType) {
PageLink pageLink = new PageLink(DEFAULT_PAGE_SIZE); PageLink pageLink = new PageLink(DEFAULT_PAGE_SIZE);
PageData<EdgeId> pageData; PageData<EdgeId> pageData;
List<ListenableFuture<Void>> futures = new ArrayList<>(); List<ListenableFuture<Void>> futures = new ArrayList<>();
@ -432,10 +447,7 @@ public abstract class BaseEdgeProcessor {
return Futures.transform(Futures.allAsList(futures), voids -> null, dbCallbackExecutorService); return Futures.transform(Futures.allAsList(futures), voids -> null, dbCallbackExecutorService);
} }
protected ListenableFuture<Void> processEntityNotificationForAllEdges(TenantId tenantId, TransportProtos.EdgeNotificationMsgProto edgeNotificationMsg) { private ListenableFuture<Void> processEntityNotificationForAllEdges(TenantId tenantId, EdgeEventType type, EdgeEventActionType actionType, EntityId entityId) {
EdgeEventActionType actionType = EdgeEventActionType.valueOf(edgeNotificationMsg.getAction());
EdgeEventType type = EdgeEventType.valueOf(edgeNotificationMsg.getType());
EntityId entityId = EntityIdFactory.getByEdgeEventTypeAndUuid(type, new UUID(edgeNotificationMsg.getEntityIdMSB(), edgeNotificationMsg.getEntityIdLSB()));
switch (actionType) { switch (actionType) {
case ADDED: case ADDED:
case UPDATED: case UPDATED:

49
application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/alarm/AlarmEdgeProcessor.java

@ -16,6 +16,7 @@
package org.thingsboard.server.service.edge.rpc.processor.alarm; package org.thingsboard.server.service.edge.rpc.processor.alarm;
import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonNode;
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;
@ -28,6 +29,7 @@ import org.thingsboard.server.common.data.edge.EdgeEventActionType;
import org.thingsboard.server.common.data.edge.EdgeEventType; import org.thingsboard.server.common.data.edge.EdgeEventType;
import org.thingsboard.server.common.data.id.AlarmId; import org.thingsboard.server.common.data.id.AlarmId;
import org.thingsboard.server.common.data.id.EdgeId; import org.thingsboard.server.common.data.id.EdgeId;
import org.thingsboard.server.common.data.id.EntityId;
import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.common.data.id.TenantId;
import org.thingsboard.server.common.data.page.PageData; import org.thingsboard.server.common.data.page.PageData;
import org.thingsboard.server.common.data.page.PageLink; import org.thingsboard.server.common.data.page.PageLink;
@ -62,9 +64,9 @@ public class AlarmEdgeProcessor extends BaseAlarmProcessor {
AlarmId alarmId = new AlarmId(new UUID(edgeNotificationMsg.getEntityIdMSB(), edgeNotificationMsg.getEntityIdLSB())); AlarmId alarmId = new AlarmId(new UUID(edgeNotificationMsg.getEntityIdMSB(), edgeNotificationMsg.getEntityIdLSB()));
switch (actionType) { switch (actionType) {
case DELETED: case DELETED:
EdgeId edgeId = new EdgeId(new UUID(edgeNotificationMsg.getEdgeIdMSB(), edgeNotificationMsg.getEdgeIdLSB()));
Alarm deletedAlarm = JacksonUtil.OBJECT_MAPPER.readValue(edgeNotificationMsg.getBody(), Alarm.class); Alarm deletedAlarm = JacksonUtil.OBJECT_MAPPER.readValue(edgeNotificationMsg.getBody(), Alarm.class);
return saveEdgeEvent(tenantId, edgeId, EdgeEventType.ALARM, actionType, alarmId, JacksonUtil.OBJECT_MAPPER.valueToTree(deletedAlarm)); List<ListenableFuture<Void>> delFutures = pushEventToAllRelatedEdges(tenantId, deletedAlarm.getOriginator(), alarmId, actionType, JacksonUtil.OBJECT_MAPPER.valueToTree(deletedAlarm));
return Futures.transform(Futures.allAsList(delFutures), voids -> null, dbCallbackExecutorService);
default: default:
ListenableFuture<Alarm> alarmFuture = alarmService.findAlarmByIdAsync(tenantId, alarmId); ListenableFuture<Alarm> alarmFuture = alarmService.findAlarmByIdAsync(tenantId, alarmId);
return Futures.transformAsync(alarmFuture, alarm -> { return Futures.transformAsync(alarmFuture, alarm -> {
@ -75,28 +77,33 @@ public class AlarmEdgeProcessor extends BaseAlarmProcessor {
if (type == null) { if (type == null) {
return Futures.immediateFuture(null); return Futures.immediateFuture(null);
} }
PageLink pageLink = new PageLink(DEFAULT_PAGE_SIZE); List<ListenableFuture<Void>> futures = pushEventToAllRelatedEdges(tenantId, alarm.getOriginator(), alarmId, actionType, null);
PageData<EdgeId> pageData;
List<ListenableFuture<Void>> futures = new ArrayList<>();
do {
pageData = edgeService.findRelatedEdgeIdsByEntityId(tenantId, alarm.getOriginator(), pageLink);
if (pageData != null && pageData.getData() != null && !pageData.getData().isEmpty()) {
for (EdgeId relatedEdgeId : pageData.getData()) {
futures.add(saveEdgeEvent(tenantId,
relatedEdgeId,
EdgeEventType.ALARM,
EdgeEventActionType.valueOf(edgeNotificationMsg.getAction()),
alarmId,
null));
}
if (pageData.hasNext()) {
pageLink = pageLink.nextPageLink();
}
}
} while (pageData != null && pageData.hasNext());
return Futures.transform(Futures.allAsList(futures), voids -> null, dbCallbackExecutorService); return Futures.transform(Futures.allAsList(futures), voids -> null, dbCallbackExecutorService);
}, dbCallbackExecutorService); }, dbCallbackExecutorService);
} }
} }
private List<ListenableFuture<Void>> pushEventToAllRelatedEdges(TenantId tenantId, EntityId originatorId, AlarmId alarmId, EdgeEventActionType actionType, JsonNode body) {
PageLink pageLink = new PageLink(DEFAULT_PAGE_SIZE);
PageData<EdgeId> pageData;
List<ListenableFuture<Void>> futures = new ArrayList<>();
do {
pageData = edgeService.findRelatedEdgeIdsByEntityId(tenantId, originatorId, pageLink);
if (pageData != null && pageData.getData() != null && !pageData.getData().isEmpty()) {
for (EdgeId relatedEdgeId : pageData.getData()) {
futures.add(saveEdgeEvent(tenantId,
relatedEdgeId,
EdgeEventType.ALARM,
actionType,
alarmId,
body));
}
if (pageData.hasNext()) {
pageLink = pageLink.nextPageLink();
}
}
} while (pageData != null && pageData.hasNext());
return futures;
}
} }

12
application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/alarm/BaseAlarmProcessor.java

@ -49,6 +49,7 @@ public abstract class BaseAlarmProcessor extends BaseEdgeProcessor {
return Futures.immediateFuture(null); return Futures.immediateFuture(null);
} }
try { try {
edgeSynchronizationManager.getSync().set(true);
switch (alarmUpdateMsg.getMsgType()) { switch (alarmUpdateMsg.getMsgType()) {
case ENTITY_CREATED_RPC_MESSAGE: case ENTITY_CREATED_RPC_MESSAGE:
case ENTITY_UPDATED_RPC_MESSAGE: case ENTITY_UPDATED_RPC_MESSAGE:
@ -72,26 +73,26 @@ public abstract class BaseAlarmProcessor extends BaseEdgeProcessor {
} else { } else {
alarmService.updateAlarm(AlarmUpdateRequest.fromAlarm(alarm)); alarmService.updateAlarm(AlarmUpdateRequest.fromAlarm(alarm));
} }
return Futures.immediateFuture(null); break;
case ALARM_ACK_RPC_MESSAGE: case ALARM_ACK_RPC_MESSAGE:
Alarm alarmToAck = alarmService.findAlarmById(tenantId, alarmId); Alarm alarmToAck = alarmService.findAlarmById(tenantId, alarmId);
if (alarmToAck != null) { if (alarmToAck != null) {
alarmService.acknowledgeAlarm(tenantId, alarmId, alarmUpdateMsg.getAckTs()); alarmService.acknowledgeAlarm(tenantId, alarmId, alarmUpdateMsg.getAckTs());
} }
return Futures.immediateFuture(null); break;
case ALARM_CLEAR_RPC_MESSAGE: case ALARM_CLEAR_RPC_MESSAGE:
Alarm alarmToClear = alarmService.findAlarmById(tenantId, alarmId); Alarm alarmToClear = alarmService.findAlarmById(tenantId, alarmId);
if (alarmToClear != null) { if (alarmToClear != null) {
alarmService.clearAlarm(tenantId, alarmId, alarmUpdateMsg.getClearTs(), alarmService.clearAlarm(tenantId, alarmId, alarmUpdateMsg.getClearTs(),
JacksonUtil.OBJECT_MAPPER.readTree(alarmUpdateMsg.getDetails())); JacksonUtil.OBJECT_MAPPER.readTree(alarmUpdateMsg.getDetails()));
} }
return Futures.immediateFuture(null); break;
case ENTITY_DELETED_RPC_MESSAGE: case ENTITY_DELETED_RPC_MESSAGE:
Alarm alarmToDelete = alarmService.findAlarmById(tenantId, alarmId); Alarm alarmToDelete = alarmService.findAlarmById(tenantId, alarmId);
if (alarmToDelete != null) { if (alarmToDelete != null) {
alarmService.delAlarm(tenantId, alarmId); alarmService.delAlarm(tenantId, alarmId);
} }
return Futures.immediateFuture(null); break;
case UNRECOGNIZED: case UNRECOGNIZED:
default: default:
return handleUnsupportedMsgType(alarmUpdateMsg.getMsgType()); return handleUnsupportedMsgType(alarmUpdateMsg.getMsgType());
@ -99,7 +100,10 @@ public abstract class BaseAlarmProcessor extends BaseEdgeProcessor {
} catch (Exception e) { } catch (Exception e) {
log.error("[{}] Failed to process alarm update msg [{}]", tenantId, alarmUpdateMsg, e); log.error("[{}] Failed to process alarm update msg [{}]", tenantId, alarmUpdateMsg, e);
return Futures.immediateFailedFuture(e); return Futures.immediateFailedFuture(e);
} finally {
edgeSynchronizationManager.getSync().remove();
} }
return Futures.immediateFuture(null);
} }
private EntityId getAlarmOriginator(TenantId tenantId, String entityName, EntityType entityType) { private EntityId getAlarmOriginator(TenantId tenantId, String entityName, EntityType entityType) {

7
application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/asset/AssetEdgeProcessor.java

@ -15,7 +15,6 @@
*/ */
package org.thingsboard.server.service.edge.rpc.processor.asset; package org.thingsboard.server.service.edge.rpc.processor.asset;
import com.google.common.util.concurrent.ListenableFuture;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import org.thingsboard.server.common.data.EdgeUtils; import org.thingsboard.server.common.data.EdgeUtils;
@ -23,11 +22,9 @@ import org.thingsboard.server.common.data.asset.Asset;
import org.thingsboard.server.common.data.asset.AssetProfile; import org.thingsboard.server.common.data.asset.AssetProfile;
import org.thingsboard.server.common.data.edge.EdgeEvent; import org.thingsboard.server.common.data.edge.EdgeEvent;
import org.thingsboard.server.common.data.id.AssetId; import org.thingsboard.server.common.data.id.AssetId;
import org.thingsboard.server.common.data.id.TenantId;
import org.thingsboard.server.gen.edge.v1.AssetUpdateMsg; import org.thingsboard.server.gen.edge.v1.AssetUpdateMsg;
import org.thingsboard.server.gen.edge.v1.DownlinkMsg; import org.thingsboard.server.gen.edge.v1.DownlinkMsg;
import org.thingsboard.server.gen.edge.v1.UpdateMsgType; import org.thingsboard.server.gen.edge.v1.UpdateMsgType;
import org.thingsboard.server.gen.transport.TransportProtos;
import org.thingsboard.server.queue.util.TbCoreComponent; import org.thingsboard.server.queue.util.TbCoreComponent;
import org.thingsboard.server.service.edge.rpc.processor.BaseEdgeProcessor; import org.thingsboard.server.service.edge.rpc.processor.BaseEdgeProcessor;
@ -72,8 +69,4 @@ public class AssetEdgeProcessor extends BaseEdgeProcessor {
} }
return downlinkMsg; return downlinkMsg;
} }
public ListenableFuture<Void> processAssetNotification(TenantId tenantId, TransportProtos.EdgeNotificationMsgProto edgeNotificationMsg) {
return processEntityNotification(tenantId, edgeNotificationMsg);
}
} }

8
application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/asset/AssetProfileEdgeProcessor.java

@ -15,18 +15,15 @@
*/ */
package org.thingsboard.server.service.edge.rpc.processor.asset; package org.thingsboard.server.service.edge.rpc.processor.asset;
import com.google.common.util.concurrent.ListenableFuture;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import org.thingsboard.server.common.data.EdgeUtils; import org.thingsboard.server.common.data.EdgeUtils;
import org.thingsboard.server.common.data.asset.AssetProfile; import org.thingsboard.server.common.data.asset.AssetProfile;
import org.thingsboard.server.common.data.edge.EdgeEvent; import org.thingsboard.server.common.data.edge.EdgeEvent;
import org.thingsboard.server.common.data.id.AssetProfileId; import org.thingsboard.server.common.data.id.AssetProfileId;
import org.thingsboard.server.common.data.id.TenantId;
import org.thingsboard.server.gen.edge.v1.AssetProfileUpdateMsg; import org.thingsboard.server.gen.edge.v1.AssetProfileUpdateMsg;
import org.thingsboard.server.gen.edge.v1.DownlinkMsg; import org.thingsboard.server.gen.edge.v1.DownlinkMsg;
import org.thingsboard.server.gen.edge.v1.UpdateMsgType; import org.thingsboard.server.gen.edge.v1.UpdateMsgType;
import org.thingsboard.server.gen.transport.TransportProtos;
import org.thingsboard.server.queue.util.TbCoreComponent; import org.thingsboard.server.queue.util.TbCoreComponent;
import org.thingsboard.server.service.edge.rpc.processor.BaseEdgeProcessor; import org.thingsboard.server.service.edge.rpc.processor.BaseEdgeProcessor;
@ -63,9 +60,4 @@ public class AssetProfileEdgeProcessor extends BaseEdgeProcessor {
} }
return downlinkMsg; return downlinkMsg;
} }
public ListenableFuture<Void> processAssetProfileNotification(TenantId tenantId, TransportProtos.EdgeNotificationMsgProto edgeNotificationMsg) {
return processEntityNotificationForAllEdges(tenantId, edgeNotificationMsg);
}
} }

7
application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/dashboard/DashboardEdgeProcessor.java

@ -15,18 +15,15 @@
*/ */
package org.thingsboard.server.service.edge.rpc.processor.dashboard; package org.thingsboard.server.service.edge.rpc.processor.dashboard;
import com.google.common.util.concurrent.ListenableFuture;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import org.thingsboard.server.common.data.Dashboard; import org.thingsboard.server.common.data.Dashboard;
import org.thingsboard.server.common.data.EdgeUtils; import org.thingsboard.server.common.data.EdgeUtils;
import org.thingsboard.server.common.data.edge.EdgeEvent; import org.thingsboard.server.common.data.edge.EdgeEvent;
import org.thingsboard.server.common.data.id.DashboardId; import org.thingsboard.server.common.data.id.DashboardId;
import org.thingsboard.server.common.data.id.TenantId;
import org.thingsboard.server.gen.edge.v1.DashboardUpdateMsg; import org.thingsboard.server.gen.edge.v1.DashboardUpdateMsg;
import org.thingsboard.server.gen.edge.v1.DownlinkMsg; import org.thingsboard.server.gen.edge.v1.DownlinkMsg;
import org.thingsboard.server.gen.edge.v1.UpdateMsgType; import org.thingsboard.server.gen.edge.v1.UpdateMsgType;
import org.thingsboard.server.gen.transport.TransportProtos;
import org.thingsboard.server.queue.util.TbCoreComponent; import org.thingsboard.server.queue.util.TbCoreComponent;
import org.thingsboard.server.service.edge.rpc.processor.BaseEdgeProcessor; import org.thingsboard.server.service.edge.rpc.processor.BaseEdgeProcessor;
@ -67,8 +64,4 @@ public class DashboardEdgeProcessor extends BaseEdgeProcessor {
} }
return downlinkMsg; return downlinkMsg;
} }
public ListenableFuture<Void> processDashboardNotification(TenantId tenantId, TransportProtos.EdgeNotificationMsgProto edgeNotificationMsg) {
return processEntityNotification(tenantId, edgeNotificationMsg);
}
} }

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

@ -97,7 +97,7 @@ public abstract class BaseDeviceProcessor extends BaseEdgeProcessor {
deviceCredentials.setCredentialsId(StringUtils.randomAlphanumeric(20)); deviceCredentials.setCredentialsId(StringUtils.randomAlphanumeric(20));
deviceCredentialsService.createDeviceCredentials(device.getTenantId(), deviceCredentials); deviceCredentialsService.createDeviceCredentials(device.getTenantId(), deviceCredentials);
} }
tbClusterService.onDeviceUpdated(savedDevice, created ? null : device, false); tbClusterService.onDeviceUpdated(savedDevice, created ? null : device);
} finally { } finally {
deviceCreationLock.unlock(); deviceCreationLock.unlock();
} }
@ -113,6 +113,8 @@ public abstract class BaseDeviceProcessor extends BaseEdgeProcessor {
log.debug("Updating device credentials for device [{}]. New device credentials Id [{}], value [{}]", log.debug("Updating device credentials for device [{}]. New device credentials Id [{}], value [{}]",
device.getName(), deviceCredentialsUpdateMsg.getCredentialsId(), deviceCredentialsUpdateMsg.getCredentialsValue()); device.getName(), deviceCredentialsUpdateMsg.getCredentialsId(), deviceCredentialsUpdateMsg.getCredentialsValue());
try { try {
edgeSynchronizationManager.getSync().set(true);
DeviceCredentials deviceCredentials = deviceCredentialsService.findDeviceCredentialsByDeviceId(tenantId, device.getId()); DeviceCredentials deviceCredentials = deviceCredentialsService.findDeviceCredentialsByDeviceId(tenantId, device.getId());
deviceCredentials.setCredentialsType(DeviceCredentialsType.valueOf(deviceCredentialsUpdateMsg.getCredentialsType())); deviceCredentials.setCredentialsType(DeviceCredentialsType.valueOf(deviceCredentialsUpdateMsg.getCredentialsType()));
deviceCredentials.setCredentialsId(deviceCredentialsUpdateMsg.getCredentialsId()); deviceCredentials.setCredentialsId(deviceCredentialsUpdateMsg.getCredentialsId());
@ -123,6 +125,8 @@ public abstract class BaseDeviceProcessor extends BaseEdgeProcessor {
log.error("Can't update device credentials for device [{}], deviceCredentialsUpdateMsg [{}]", log.error("Can't update device credentials for device [{}], deviceCredentialsUpdateMsg [{}]",
device.getName(), deviceCredentialsUpdateMsg, e); device.getName(), deviceCredentialsUpdateMsg, e);
throw new RuntimeException(e); throw new RuntimeException(e);
} finally {
edgeSynchronizationManager.getSync().remove();
} }
} else { } else {
log.warn("Can't find device by id [{}], deviceCredentialsUpdateMsg [{}]", deviceId, deviceCredentialsUpdateMsg); log.warn("Can't find device by id [{}], deviceCredentialsUpdateMsg [{}]", deviceId, deviceCredentialsUpdateMsg);

17
application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/device/DeviceEdgeProcessor.java

@ -38,6 +38,7 @@ 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.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.msg.TbMsgType;
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.rpc.RpcError; import org.thingsboard.server.common.data.rpc.RpcError;
@ -46,7 +47,6 @@ import org.thingsboard.server.common.msg.TbMsg;
import org.thingsboard.server.common.msg.TbMsgDataType; 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.rpc.FromDeviceRpcResponse; import org.thingsboard.server.common.msg.rpc.FromDeviceRpcResponse;
import org.thingsboard.server.common.msg.session.SessionMsgType;
import org.thingsboard.server.dao.exception.DataValidationException; import org.thingsboard.server.dao.exception.DataValidationException;
import org.thingsboard.server.gen.edge.v1.DeviceCredentialsRequestMsg; import org.thingsboard.server.gen.edge.v1.DeviceCredentialsRequestMsg;
import org.thingsboard.server.gen.edge.v1.DeviceCredentialsUpdateMsg; import org.thingsboard.server.gen.edge.v1.DeviceCredentialsUpdateMsg;
@ -54,7 +54,6 @@ import org.thingsboard.server.gen.edge.v1.DeviceRpcCallMsg;
import org.thingsboard.server.gen.edge.v1.DeviceUpdateMsg; import org.thingsboard.server.gen.edge.v1.DeviceUpdateMsg;
import org.thingsboard.server.gen.edge.v1.DownlinkMsg; import org.thingsboard.server.gen.edge.v1.DownlinkMsg;
import org.thingsboard.server.gen.edge.v1.UpdateMsgType; import org.thingsboard.server.gen.edge.v1.UpdateMsgType;
import org.thingsboard.server.gen.transport.TransportProtos;
import org.thingsboard.server.queue.TbQueueCallback; import org.thingsboard.server.queue.TbQueueCallback;
import org.thingsboard.server.queue.TbQueueMsgMetadata; import org.thingsboard.server.queue.TbQueueMsgMetadata;
import org.thingsboard.server.queue.util.TbCoreComponent; import org.thingsboard.server.queue.util.TbCoreComponent;
@ -71,6 +70,8 @@ public class DeviceEdgeProcessor extends BaseDeviceProcessor {
log.trace("[{}] executing processDeviceMsgFromEdge [{}] from edge [{}]", tenantId, deviceUpdateMsg, edge.getName()); log.trace("[{}] executing processDeviceMsgFromEdge [{}] from edge [{}]", tenantId, deviceUpdateMsg, edge.getName());
DeviceId deviceId = new DeviceId(new UUID(deviceUpdateMsg.getIdMSB(), deviceUpdateMsg.getIdLSB())); DeviceId deviceId = new DeviceId(new UUID(deviceUpdateMsg.getIdMSB(), deviceUpdateMsg.getIdLSB()));
try { try {
edgeSynchronizationManager.getSync().set(true);
switch (deviceUpdateMsg.getMsgType()) { switch (deviceUpdateMsg.getMsgType()) {
case ENTITY_CREATED_RPC_MESSAGE: case ENTITY_CREATED_RPC_MESSAGE:
case ENTITY_UPDATED_RPC_MESSAGE: case ENTITY_UPDATED_RPC_MESSAGE:
@ -93,6 +94,8 @@ public class DeviceEdgeProcessor extends BaseDeviceProcessor {
} else { } else {
return Futures.immediateFailedFuture(e); return Futures.immediateFailedFuture(e);
} }
} finally {
edgeSynchronizationManager.getSync().remove();
} }
} }
@ -124,7 +127,7 @@ public class DeviceEdgeProcessor extends BaseDeviceProcessor {
try { try {
Device device = deviceService.findDeviceById(tenantId, deviceId); Device device = deviceService.findDeviceById(tenantId, deviceId);
ObjectNode entityNode = JacksonUtil.OBJECT_MAPPER.valueToTree(device); ObjectNode entityNode = JacksonUtil.OBJECT_MAPPER.valueToTree(device);
TbMsg tbMsg = TbMsg.newMsg(DataConstants.ENTITY_CREATED, deviceId, device.getCustomerId(), TbMsg tbMsg = TbMsg.newMsg(TbMsgType.ENTITY_CREATED, deviceId, device.getCustomerId(),
getActionTbMsgMetaData(edge, device.getCustomerId()), TbMsgDataType.JSON, JacksonUtil.OBJECT_MAPPER.writeValueAsString(entityNode)); getActionTbMsgMetaData(edge, device.getCustomerId()), TbMsgDataType.JSON, JacksonUtil.OBJECT_MAPPER.writeValueAsString(entityNode));
tbClusterService.pushMsgToRuleEngine(tenantId, deviceId, tbMsg, new TbQueueCallback() { tbClusterService.pushMsgToRuleEngine(tenantId, deviceId, tbMsg, new TbQueueCallback() {
@Override @Override
@ -138,7 +141,7 @@ public class DeviceEdgeProcessor extends BaseDeviceProcessor {
} }
}); });
} catch (JsonProcessingException | IllegalArgumentException e) { } catch (JsonProcessingException | IllegalArgumentException e) {
log.warn("[{}] Failed to push device action to rule engine: {}", deviceId, DataConstants.ENTITY_CREATED, e); log.warn("[{}] Failed to push device action to rule engine: {}", deviceId, TbMsgType.ENTITY_CREATED.name(), e);
} }
} }
@ -216,7 +219,7 @@ public class DeviceEdgeProcessor extends BaseDeviceProcessor {
ObjectNode data = JacksonUtil.newObjectNode(); ObjectNode data = JacksonUtil.newObjectNode();
data.put("method", deviceRpcCallMsg.getRequestMsg().getMethod()); data.put("method", deviceRpcCallMsg.getRequestMsg().getMethod());
data.put("params", deviceRpcCallMsg.getRequestMsg().getParams()); data.put("params", deviceRpcCallMsg.getRequestMsg().getParams());
TbMsg tbMsg = TbMsg.newMsg(SessionMsgType.TO_SERVER_RPC_REQUEST.name(), deviceId, null, metaData, TbMsg tbMsg = TbMsg.newMsg(TbMsgType.TO_SERVER_RPC_REQUEST, deviceId, null, metaData,
TbMsgDataType.JSON, JacksonUtil.OBJECT_MAPPER.writeValueAsString(data)); TbMsgDataType.JSON, JacksonUtil.OBJECT_MAPPER.writeValueAsString(data));
tbClusterService.pushMsgToRuleEngine(tenantId, deviceId, tbMsg, new TbQueueCallback() { tbClusterService.pushMsgToRuleEngine(tenantId, deviceId, tbMsg, new TbQueueCallback() {
@Override @Override
@ -308,8 +311,4 @@ public class DeviceEdgeProcessor extends BaseDeviceProcessor {
.addDeviceCredentialsRequestMsg(deviceCredentialsRequestMsg); .addDeviceCredentialsRequestMsg(deviceCredentialsRequestMsg);
return builder.build(); return builder.build();
} }
public ListenableFuture<Void> processDeviceNotification(TenantId tenantId, TransportProtos.EdgeNotificationMsgProto edgeNotificationMsg) {
return processEntityNotification(tenantId, edgeNotificationMsg);
}
} }

7
application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/device/DeviceProfileEdgeProcessor.java

@ -15,18 +15,15 @@
*/ */
package org.thingsboard.server.service.edge.rpc.processor.device; package org.thingsboard.server.service.edge.rpc.processor.device;
import com.google.common.util.concurrent.ListenableFuture;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import org.thingsboard.server.common.data.DeviceProfile; import org.thingsboard.server.common.data.DeviceProfile;
import org.thingsboard.server.common.data.EdgeUtils; import org.thingsboard.server.common.data.EdgeUtils;
import org.thingsboard.server.common.data.edge.EdgeEvent; import org.thingsboard.server.common.data.edge.EdgeEvent;
import org.thingsboard.server.common.data.id.DeviceProfileId; import org.thingsboard.server.common.data.id.DeviceProfileId;
import org.thingsboard.server.common.data.id.TenantId;
import org.thingsboard.server.gen.edge.v1.DeviceProfileUpdateMsg; import org.thingsboard.server.gen.edge.v1.DeviceProfileUpdateMsg;
import org.thingsboard.server.gen.edge.v1.DownlinkMsg; import org.thingsboard.server.gen.edge.v1.DownlinkMsg;
import org.thingsboard.server.gen.edge.v1.UpdateMsgType; import org.thingsboard.server.gen.edge.v1.UpdateMsgType;
import org.thingsboard.server.gen.transport.TransportProtos;
import org.thingsboard.server.queue.util.TbCoreComponent; import org.thingsboard.server.queue.util.TbCoreComponent;
import org.thingsboard.server.service.edge.rpc.processor.BaseEdgeProcessor; import org.thingsboard.server.service.edge.rpc.processor.BaseEdgeProcessor;
@ -63,8 +60,4 @@ public class DeviceProfileEdgeProcessor extends BaseEdgeProcessor {
} }
return downlinkMsg; return downlinkMsg;
} }
public ListenableFuture<Void> processDeviceProfileNotification(TenantId tenantId, TransportProtos.EdgeNotificationMsgProto edgeNotificationMsg) {
return processEntityNotificationForAllEdges(tenantId, edgeNotificationMsg);
}
} }

7
application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/entityview/EntityViewEdgeProcessor.java

@ -15,18 +15,15 @@
*/ */
package org.thingsboard.server.service.edge.rpc.processor.entityview; package org.thingsboard.server.service.edge.rpc.processor.entityview;
import com.google.common.util.concurrent.ListenableFuture;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import org.thingsboard.server.common.data.EdgeUtils; import org.thingsboard.server.common.data.EdgeUtils;
import org.thingsboard.server.common.data.EntityView; import org.thingsboard.server.common.data.EntityView;
import org.thingsboard.server.common.data.edge.EdgeEvent; import org.thingsboard.server.common.data.edge.EdgeEvent;
import org.thingsboard.server.common.data.id.EntityViewId; import org.thingsboard.server.common.data.id.EntityViewId;
import org.thingsboard.server.common.data.id.TenantId;
import org.thingsboard.server.gen.edge.v1.DownlinkMsg; import org.thingsboard.server.gen.edge.v1.DownlinkMsg;
import org.thingsboard.server.gen.edge.v1.EntityViewUpdateMsg; import org.thingsboard.server.gen.edge.v1.EntityViewUpdateMsg;
import org.thingsboard.server.gen.edge.v1.UpdateMsgType; import org.thingsboard.server.gen.edge.v1.UpdateMsgType;
import org.thingsboard.server.gen.transport.TransportProtos;
import org.thingsboard.server.queue.util.TbCoreComponent; import org.thingsboard.server.queue.util.TbCoreComponent;
import org.thingsboard.server.service.edge.rpc.processor.BaseEdgeProcessor; import org.thingsboard.server.service.edge.rpc.processor.BaseEdgeProcessor;
@ -67,8 +64,4 @@ public class EntityViewEdgeProcessor extends BaseEdgeProcessor {
} }
return downlinkMsg; return downlinkMsg;
} }
public ListenableFuture<Void> processEntityViewNotification(TenantId tenantId, TransportProtos.EdgeNotificationMsgProto edgeNotificationMsg) {
return processEntityNotification(tenantId, edgeNotificationMsg);
}
} }

7
application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/ota/OtaPackageEdgeProcessor.java

@ -15,18 +15,15 @@
*/ */
package org.thingsboard.server.service.edge.rpc.processor.ota; package org.thingsboard.server.service.edge.rpc.processor.ota;
import com.google.common.util.concurrent.ListenableFuture;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import org.thingsboard.server.common.data.EdgeUtils; import org.thingsboard.server.common.data.EdgeUtils;
import org.thingsboard.server.common.data.OtaPackage; import org.thingsboard.server.common.data.OtaPackage;
import org.thingsboard.server.common.data.edge.EdgeEvent; import org.thingsboard.server.common.data.edge.EdgeEvent;
import org.thingsboard.server.common.data.id.OtaPackageId; import org.thingsboard.server.common.data.id.OtaPackageId;
import org.thingsboard.server.common.data.id.TenantId;
import org.thingsboard.server.gen.edge.v1.DownlinkMsg; import org.thingsboard.server.gen.edge.v1.DownlinkMsg;
import org.thingsboard.server.gen.edge.v1.OtaPackageUpdateMsg; import org.thingsboard.server.gen.edge.v1.OtaPackageUpdateMsg;
import org.thingsboard.server.gen.edge.v1.UpdateMsgType; import org.thingsboard.server.gen.edge.v1.UpdateMsgType;
import org.thingsboard.server.gen.transport.TransportProtos;
import org.thingsboard.server.queue.util.TbCoreComponent; import org.thingsboard.server.queue.util.TbCoreComponent;
import org.thingsboard.server.service.edge.rpc.processor.BaseEdgeProcessor; import org.thingsboard.server.service.edge.rpc.processor.BaseEdgeProcessor;
@ -63,8 +60,4 @@ public class OtaPackageEdgeProcessor extends BaseEdgeProcessor {
} }
return downlinkMsg; return downlinkMsg;
} }
public ListenableFuture<Void> processOtaPackageNotification(TenantId tenantId, TransportProtos.EdgeNotificationMsgProto edgeNotificationMsg) {
return processEntityNotificationForAllEdges(tenantId, edgeNotificationMsg);
}
} }

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

@ -15,18 +15,15 @@
*/ */
package org.thingsboard.server.service.edge.rpc.processor.queue; package org.thingsboard.server.service.edge.rpc.processor.queue;
import com.google.common.util.concurrent.ListenableFuture;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import org.thingsboard.server.common.data.EdgeUtils; import org.thingsboard.server.common.data.EdgeUtils;
import org.thingsboard.server.common.data.edge.EdgeEvent; import org.thingsboard.server.common.data.edge.EdgeEvent;
import org.thingsboard.server.common.data.id.QueueId; import org.thingsboard.server.common.data.id.QueueId;
import org.thingsboard.server.common.data.id.TenantId;
import org.thingsboard.server.common.data.queue.Queue; import org.thingsboard.server.common.data.queue.Queue;
import org.thingsboard.server.gen.edge.v1.DownlinkMsg; import org.thingsboard.server.gen.edge.v1.DownlinkMsg;
import org.thingsboard.server.gen.edge.v1.QueueUpdateMsg; import org.thingsboard.server.gen.edge.v1.QueueUpdateMsg;
import org.thingsboard.server.gen.edge.v1.UpdateMsgType; import org.thingsboard.server.gen.edge.v1.UpdateMsgType;
import org.thingsboard.server.gen.transport.TransportProtos;
import org.thingsboard.server.queue.util.TbCoreComponent; import org.thingsboard.server.queue.util.TbCoreComponent;
import org.thingsboard.server.service.edge.rpc.processor.BaseEdgeProcessor; import org.thingsboard.server.service.edge.rpc.processor.BaseEdgeProcessor;
@ -64,7 +61,4 @@ public class QueueEdgeProcessor extends BaseEdgeProcessor {
return downlinkMsg; return downlinkMsg;
} }
public ListenableFuture<Void> processQueueNotification(TenantId tenantId, TransportProtos.EdgeNotificationMsgProto edgeNotificationMsg) {
return processEntityNotificationForAllEdges(tenantId, edgeNotificationMsg);
}
} }

16
application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/relation/BaseRelationProcessor.java

@ -34,8 +34,9 @@ import java.util.UUID;
public abstract class BaseRelationProcessor extends BaseEdgeProcessor { public abstract class BaseRelationProcessor extends BaseEdgeProcessor {
public ListenableFuture<Void> processRelationMsg(TenantId tenantId, RelationUpdateMsg relationUpdateMsg) { public ListenableFuture<Void> processRelationMsg(TenantId tenantId, RelationUpdateMsg relationUpdateMsg) {
log.trace("[{}] processRelationFromEdge [{}]", tenantId, relationUpdateMsg); log.trace("[{}] processRelationMsg [{}]", tenantId, relationUpdateMsg);
try { try {
edgeSynchronizationManager.getSync().set(true);
EntityRelation entityRelation = new EntityRelation(); EntityRelation entityRelation = new EntityRelation();
UUID fromUUID = new UUID(relationUpdateMsg.getFromIdMSB(), relationUpdateMsg.getFromIdLSB()); UUID fromUUID = new UUID(relationUpdateMsg.getFromIdMSB(), relationUpdateMsg.getFromIdLSB());
@ -55,15 +56,15 @@ public abstract class BaseRelationProcessor extends BaseEdgeProcessor {
case ENTITY_UPDATED_RPC_MESSAGE: case ENTITY_UPDATED_RPC_MESSAGE:
if (isEntityExists(tenantId, entityRelation.getTo()) if (isEntityExists(tenantId, entityRelation.getTo())
&& isEntityExists(tenantId, entityRelation.getFrom())) { && isEntityExists(tenantId, entityRelation.getFrom())) {
return Futures.transform(relationService.saveRelationAsync(tenantId, entityRelation), relationService.saveRelation(tenantId, entityRelation);
(result) -> null, dbCallbackExecutorService); break;
} else { } else {
log.warn("Skipping relating update msg because from/to entity doesn't exists on edge, {}", relationUpdateMsg); log.warn("Skipping relating update msg because from/to entity doesn't exists on edge, {}", relationUpdateMsg);
return Futures.immediateFuture(null); break;
} }
case ENTITY_DELETED_RPC_MESSAGE: case ENTITY_DELETED_RPC_MESSAGE:
return Futures.transform(relationService.deleteRelationAsync(tenantId, entityRelation), relationService.deleteRelation(tenantId, entityRelation);
(result) -> null, dbCallbackExecutorService); break;
case UNRECOGNIZED: case UNRECOGNIZED:
default: default:
return handleUnsupportedMsgType(relationUpdateMsg.getMsgType()); return handleUnsupportedMsgType(relationUpdateMsg.getMsgType());
@ -71,6 +72,9 @@ public abstract class BaseRelationProcessor extends BaseEdgeProcessor {
} catch (Exception e) { } catch (Exception e) {
log.error("[{}] Failed to process relation update msg [{}]", tenantId, relationUpdateMsg, e); log.error("[{}] Failed to process relation update msg [{}]", tenantId, relationUpdateMsg, e);
return Futures.immediateFailedFuture(e); return Futures.immediateFailedFuture(e);
} finally {
edgeSynchronizationManager.getSync().remove();
} }
return Futures.immediateFuture(null);
} }
} }

7
application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/rule/RuleChainEdgeProcessor.java

@ -15,13 +15,11 @@
*/ */
package org.thingsboard.server.service.edge.rpc.processor.rule; package org.thingsboard.server.service.edge.rpc.processor.rule;
import com.google.common.util.concurrent.ListenableFuture;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import org.thingsboard.server.common.data.EdgeUtils; import org.thingsboard.server.common.data.EdgeUtils;
import org.thingsboard.server.common.data.edge.EdgeEvent; import org.thingsboard.server.common.data.edge.EdgeEvent;
import org.thingsboard.server.common.data.id.RuleChainId; import org.thingsboard.server.common.data.id.RuleChainId;
import org.thingsboard.server.common.data.id.TenantId;
import org.thingsboard.server.common.data.rule.RuleChain; import org.thingsboard.server.common.data.rule.RuleChain;
import org.thingsboard.server.common.data.rule.RuleChainMetaData; import org.thingsboard.server.common.data.rule.RuleChainMetaData;
import org.thingsboard.server.gen.edge.v1.DownlinkMsg; import org.thingsboard.server.gen.edge.v1.DownlinkMsg;
@ -29,7 +27,6 @@ import org.thingsboard.server.gen.edge.v1.EdgeVersion;
import org.thingsboard.server.gen.edge.v1.RuleChainMetadataUpdateMsg; import org.thingsboard.server.gen.edge.v1.RuleChainMetadataUpdateMsg;
import org.thingsboard.server.gen.edge.v1.RuleChainUpdateMsg; import org.thingsboard.server.gen.edge.v1.RuleChainUpdateMsg;
import org.thingsboard.server.gen.edge.v1.UpdateMsgType; import org.thingsboard.server.gen.edge.v1.UpdateMsgType;
import org.thingsboard.server.gen.transport.TransportProtos;
import org.thingsboard.server.queue.util.TbCoreComponent; import org.thingsboard.server.queue.util.TbCoreComponent;
import org.thingsboard.server.service.edge.rpc.processor.BaseEdgeProcessor; import org.thingsboard.server.service.edge.rpc.processor.BaseEdgeProcessor;
@ -93,8 +90,4 @@ public class RuleChainEdgeProcessor extends BaseEdgeProcessor {
} }
return downlinkMsg; return downlinkMsg;
} }
public ListenableFuture<Void> processRuleChainNotification(TenantId tenantId, TransportProtos.EdgeNotificationMsgProto edgeNotificationMsg) {
return processEntityNotification(tenantId, edgeNotificationMsg);
}
} }

8
application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/telemetry/BaseTelemetryProcessor.java

@ -50,11 +50,11 @@ import org.thingsboard.server.common.data.id.RuleChainId;
import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.common.data.id.TenantId;
import org.thingsboard.server.common.data.id.UserId; import org.thingsboard.server.common.data.id.UserId;
import org.thingsboard.server.common.data.kv.AttributeKvEntry; import org.thingsboard.server.common.data.kv.AttributeKvEntry;
import org.thingsboard.server.common.data.msg.TbMsgType;
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.ServiceType; import org.thingsboard.server.common.msg.queue.ServiceType;
import org.thingsboard.server.common.msg.queue.TopicPartitionInfo; import org.thingsboard.server.common.msg.queue.TopicPartitionInfo;
import org.thingsboard.server.common.msg.session.SessionMsgType;
import org.thingsboard.server.common.transport.adaptor.JsonConverter; import org.thingsboard.server.common.transport.adaptor.JsonConverter;
import org.thingsboard.server.common.transport.util.JsonUtils; import org.thingsboard.server.common.transport.util.JsonUtils;
import org.thingsboard.server.dao.model.ModelConstants; import org.thingsboard.server.dao.model.ModelConstants;
@ -184,7 +184,7 @@ public abstract class BaseTelemetryProcessor extends BaseEdgeProcessor {
JsonObject json = JsonUtils.getJsonObject(tsKv.getKvList()); JsonObject json = JsonUtils.getJsonObject(tsKv.getKvList());
metaData.putValue("ts", tsKv.getTs() + ""); metaData.putValue("ts", tsKv.getTs() + "");
var defaultQueueAndRuleChain = getDefaultQueueNameAndRuleChainId(tenantId, entityId); var defaultQueueAndRuleChain = getDefaultQueueNameAndRuleChainId(tenantId, entityId);
TbMsg tbMsg = TbMsg.newMsg(defaultQueueAndRuleChain.getKey(), SessionMsgType.POST_TELEMETRY_REQUEST.name(), entityId, customerId, metaData, gson.toJson(json), defaultQueueAndRuleChain.getValue(), null); TbMsg tbMsg = TbMsg.newMsg(defaultQueueAndRuleChain.getKey(), TbMsgType.POST_TELEMETRY_REQUEST, entityId, customerId, metaData, gson.toJson(json), defaultQueueAndRuleChain.getValue(), null);
tbClusterService.pushMsgToRuleEngine(tenantId, tbMsg.getOriginator(), tbMsg, new TbQueueCallback() { tbClusterService.pushMsgToRuleEngine(tenantId, tbMsg.getOriginator(), tbMsg, new TbQueueCallback() {
@Override @Override
public void onSuccess(TbQueueMsgMetadata metadata) { public void onSuccess(TbQueueMsgMetadata metadata) {
@ -228,7 +228,7 @@ public abstract class BaseTelemetryProcessor extends BaseEdgeProcessor {
SettableFuture<Void> futureToSet = SettableFuture.create(); SettableFuture<Void> futureToSet = SettableFuture.create();
JsonObject json = JsonUtils.getJsonObject(msg.getKvList()); JsonObject json = JsonUtils.getJsonObject(msg.getKvList());
var defaultQueueAndRuleChain = getDefaultQueueNameAndRuleChainId(tenantId, entityId); var defaultQueueAndRuleChain = getDefaultQueueNameAndRuleChainId(tenantId, entityId);
TbMsg tbMsg = TbMsg.newMsg(defaultQueueAndRuleChain.getKey(), SessionMsgType.POST_ATTRIBUTES_REQUEST.name(), entityId, customerId, metaData, gson.toJson(json), defaultQueueAndRuleChain.getValue(), null); TbMsg tbMsg = TbMsg.newMsg(defaultQueueAndRuleChain.getKey(), TbMsgType.POST_ATTRIBUTES_REQUEST, entityId, customerId, metaData, gson.toJson(json), defaultQueueAndRuleChain.getValue(), null);
tbClusterService.pushMsgToRuleEngine(tenantId, tbMsg.getOriginator(), tbMsg, new TbQueueCallback() { tbClusterService.pushMsgToRuleEngine(tenantId, tbMsg.getOriginator(), tbMsg, new TbQueueCallback() {
@Override @Override
public void onSuccess(TbQueueMsgMetadata metadata) { public void onSuccess(TbQueueMsgMetadata metadata) {
@ -257,7 +257,7 @@ public abstract class BaseTelemetryProcessor extends BaseEdgeProcessor {
@Override @Override
public void onSuccess(@Nullable Void tmp) { public void onSuccess(@Nullable Void tmp) {
var defaultQueueAndRuleChain = getDefaultQueueNameAndRuleChainId(tenantId, entityId); var defaultQueueAndRuleChain = getDefaultQueueNameAndRuleChainId(tenantId, entityId);
TbMsg tbMsg = TbMsg.newMsg(defaultQueueAndRuleChain.getKey(), DataConstants.ATTRIBUTES_UPDATED, entityId, TbMsg tbMsg = TbMsg.newMsg(defaultQueueAndRuleChain.getKey(), TbMsgType.ATTRIBUTES_UPDATED, entityId,
customerId, metaData, gson.toJson(json), defaultQueueAndRuleChain.getValue(), null); customerId, metaData, gson.toJson(json), defaultQueueAndRuleChain.getValue(), null);
tbClusterService.pushMsgToRuleEngine(tenantId, tbMsg.getOriginator(), tbMsg, new TbQueueCallback() { tbClusterService.pushMsgToRuleEngine(tenantId, tbMsg.getOriginator(), tbMsg, new TbQueueCallback() {
@Override @Override

7
application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/user/UserEdgeProcessor.java

@ -15,19 +15,16 @@
*/ */
package org.thingsboard.server.service.edge.rpc.processor.user; package org.thingsboard.server.service.edge.rpc.processor.user;
import com.google.common.util.concurrent.ListenableFuture;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import org.thingsboard.server.common.data.EdgeUtils; import org.thingsboard.server.common.data.EdgeUtils;
import org.thingsboard.server.common.data.User; import org.thingsboard.server.common.data.User;
import org.thingsboard.server.common.data.edge.EdgeEvent; import org.thingsboard.server.common.data.edge.EdgeEvent;
import org.thingsboard.server.common.data.id.TenantId;
import org.thingsboard.server.common.data.id.UserId; import org.thingsboard.server.common.data.id.UserId;
import org.thingsboard.server.common.data.security.UserCredentials; import org.thingsboard.server.common.data.security.UserCredentials;
import org.thingsboard.server.gen.edge.v1.DownlinkMsg; import org.thingsboard.server.gen.edge.v1.DownlinkMsg;
import org.thingsboard.server.gen.edge.v1.UpdateMsgType; import org.thingsboard.server.gen.edge.v1.UpdateMsgType;
import org.thingsboard.server.gen.edge.v1.UserCredentialsUpdateMsg; import org.thingsboard.server.gen.edge.v1.UserCredentialsUpdateMsg;
import org.thingsboard.server.gen.transport.TransportProtos;
import org.thingsboard.server.queue.util.TbCoreComponent; import org.thingsboard.server.queue.util.TbCoreComponent;
import org.thingsboard.server.service.edge.rpc.processor.BaseEdgeProcessor; import org.thingsboard.server.service.edge.rpc.processor.BaseEdgeProcessor;
@ -67,11 +64,9 @@ public class UserEdgeProcessor extends BaseEdgeProcessor {
.addUserCredentialsUpdateMsg(userCredentialsUpdateMsg) .addUserCredentialsUpdateMsg(userCredentialsUpdateMsg)
.build(); .build();
} }
break;
} }
return downlinkMsg; return downlinkMsg;
} }
public ListenableFuture<Void> processUserNotification(TenantId tenantId, TransportProtos.EdgeNotificationMsgProto edgeNotificationMsg) {
return processEntityNotificationForAllEdges(tenantId, edgeNotificationMsg);
}
} }

7
application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/widget/WidgetBundleEdgeProcessor.java

@ -15,18 +15,15 @@
*/ */
package org.thingsboard.server.service.edge.rpc.processor.widget; package org.thingsboard.server.service.edge.rpc.processor.widget;
import com.google.common.util.concurrent.ListenableFuture;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import org.thingsboard.server.common.data.EdgeUtils; import org.thingsboard.server.common.data.EdgeUtils;
import org.thingsboard.server.common.data.edge.EdgeEvent; import org.thingsboard.server.common.data.edge.EdgeEvent;
import org.thingsboard.server.common.data.id.TenantId;
import org.thingsboard.server.common.data.id.WidgetsBundleId; import org.thingsboard.server.common.data.id.WidgetsBundleId;
import org.thingsboard.server.common.data.widget.WidgetsBundle; import org.thingsboard.server.common.data.widget.WidgetsBundle;
import org.thingsboard.server.gen.edge.v1.DownlinkMsg; import org.thingsboard.server.gen.edge.v1.DownlinkMsg;
import org.thingsboard.server.gen.edge.v1.UpdateMsgType; import org.thingsboard.server.gen.edge.v1.UpdateMsgType;
import org.thingsboard.server.gen.edge.v1.WidgetsBundleUpdateMsg; import org.thingsboard.server.gen.edge.v1.WidgetsBundleUpdateMsg;
import org.thingsboard.server.gen.transport.TransportProtos;
import org.thingsboard.server.queue.util.TbCoreComponent; import org.thingsboard.server.queue.util.TbCoreComponent;
import org.thingsboard.server.service.edge.rpc.processor.BaseEdgeProcessor; import org.thingsboard.server.service.edge.rpc.processor.BaseEdgeProcessor;
@ -63,8 +60,4 @@ public class WidgetBundleEdgeProcessor extends BaseEdgeProcessor {
} }
return downlinkMsg; return downlinkMsg;
} }
public ListenableFuture<Void> processWidgetsBundleNotification(TenantId tenantId, TransportProtos.EdgeNotificationMsgProto edgeNotificationMsg) {
return processEntityNotificationForAllEdges(tenantId, edgeNotificationMsg);
}
} }

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

@ -15,18 +15,15 @@
*/ */
package org.thingsboard.server.service.edge.rpc.processor.widget; package org.thingsboard.server.service.edge.rpc.processor.widget;
import com.google.common.util.concurrent.ListenableFuture;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import org.thingsboard.server.common.data.EdgeUtils; import org.thingsboard.server.common.data.EdgeUtils;
import org.thingsboard.server.common.data.edge.EdgeEvent; import org.thingsboard.server.common.data.edge.EdgeEvent;
import org.thingsboard.server.common.data.id.TenantId;
import org.thingsboard.server.common.data.id.WidgetTypeId; import org.thingsboard.server.common.data.id.WidgetTypeId;
import org.thingsboard.server.common.data.widget.WidgetTypeDetails; import org.thingsboard.server.common.data.widget.WidgetTypeDetails;
import org.thingsboard.server.gen.edge.v1.DownlinkMsg; import org.thingsboard.server.gen.edge.v1.DownlinkMsg;
import org.thingsboard.server.gen.edge.v1.UpdateMsgType; import org.thingsboard.server.gen.edge.v1.UpdateMsgType;
import org.thingsboard.server.gen.edge.v1.WidgetTypeUpdateMsg; import org.thingsboard.server.gen.edge.v1.WidgetTypeUpdateMsg;
import org.thingsboard.server.gen.transport.TransportProtos;
import org.thingsboard.server.queue.util.TbCoreComponent; import org.thingsboard.server.queue.util.TbCoreComponent;
import org.thingsboard.server.service.edge.rpc.processor.BaseEdgeProcessor; import org.thingsboard.server.service.edge.rpc.processor.BaseEdgeProcessor;
@ -64,7 +61,4 @@ public class WidgetTypeEdgeProcessor extends BaseEdgeProcessor {
return downlinkMsg; return downlinkMsg;
} }
public ListenableFuture<Void> processWidgetTypeNotification(TenantId tenantId, TransportProtos.EdgeNotificationMsgProto edgeNotificationMsg) {
return processEntityNotificationForAllEdges(tenantId, edgeNotificationMsg);
}
} }

143
application/src/main/java/org/thingsboard/server/service/entitiy/DefaultTbNotificationEntityService.java

@ -21,29 +21,21 @@ import org.springframework.stereotype.Service;
import org.thingsboard.common.util.JacksonUtil; import org.thingsboard.common.util.JacksonUtil;
import org.thingsboard.rule.engine.api.msg.DeviceCredentialsUpdateNotificationMsg; import org.thingsboard.rule.engine.api.msg.DeviceCredentialsUpdateNotificationMsg;
import org.thingsboard.server.cluster.TbClusterService; import org.thingsboard.server.cluster.TbClusterService;
import org.thingsboard.server.common.data.DataConstants;
import org.thingsboard.server.common.data.Device; import org.thingsboard.server.common.data.Device;
import org.thingsboard.server.common.data.EntityType;
import org.thingsboard.server.common.data.HasName; import org.thingsboard.server.common.data.HasName;
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.alarm.Alarm;
import org.thingsboard.server.common.data.alarm.AlarmComment;
import org.thingsboard.server.common.data.alarm.AlarmInfo;
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.EdgeEventActionType; import org.thingsboard.server.common.data.edge.EdgeEventActionType;
import org.thingsboard.server.common.data.edge.EdgeEventType;
import org.thingsboard.server.common.data.id.CustomerId; import org.thingsboard.server.common.data.id.CustomerId;
import org.thingsboard.server.common.data.id.DeviceId; 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.EntityId; import org.thingsboard.server.common.data.id.EntityId;
import org.thingsboard.server.common.data.id.RuleChainId;
import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.common.data.id.TenantId;
import org.thingsboard.server.common.data.msg.TbMsgType;
import org.thingsboard.server.common.data.plugin.ComponentLifecycleEvent; import org.thingsboard.server.common.data.plugin.ComponentLifecycleEvent;
import org.thingsboard.server.common.data.relation.EntityRelation; import org.thingsboard.server.common.data.relation.EntityRelation;
import org.thingsboard.server.common.data.rule.RuleChain;
import org.thingsboard.server.common.data.rule.RuleChainType;
import org.thingsboard.server.common.data.security.DeviceCredentials; import org.thingsboard.server.common.data.security.DeviceCredentials;
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.TbMsgDataType;
@ -51,8 +43,6 @@ import org.thingsboard.server.common.msg.TbMsgMetaData;
import org.thingsboard.server.service.action.EntityActionService; import org.thingsboard.server.service.action.EntityActionService;
import org.thingsboard.server.service.gateway_device.GatewayNotificationsService; import org.thingsboard.server.service.gateway_device.GatewayNotificationsService;
import java.util.List;
@Slf4j @Slf4j
@Service @Service
@RequiredArgsConstructor @RequiredArgsConstructor
@ -98,54 +88,6 @@ public class DefaultTbNotificationEntityService implements TbNotificationEntityS
} }
} }
@Override
public <E extends HasName, I extends EntityId> void notifyDeleteEntity(TenantId tenantId, I entityId, E entity,
CustomerId customerId, ActionType actionType,
List<EdgeId> relatedEdgeIds,
User user, Object... additionalInfo) {
logEntityAction(tenantId, entityId, entity, customerId, actionType, user, additionalInfo);
sendDeleteNotificationMsg(tenantId, entityId, relatedEdgeIds, null);
}
@Override
public void notifyDeleteAlarm(TenantId tenantId, Alarm alarm, EntityId originatorId, CustomerId customerId,
List<EdgeId> relatedEdgeIds, User user, String body, Object... additionalInfo) {
logEntityAction(tenantId, originatorId, alarm, customerId, ActionType.DELETED, user, additionalInfo);
sendAlarmDeleteNotificationMsg(tenantId, alarm, relatedEdgeIds, body);
}
@Override
public void notifyDeleteRuleChain(TenantId tenantId, RuleChain ruleChain, List<EdgeId> relatedEdgeIds, User user) {
RuleChainId ruleChainId = ruleChain.getId();
logEntityAction(tenantId, ruleChainId, ruleChain, null, ActionType.DELETED, user, null, ruleChainId.toString());
if (RuleChainType.EDGE.equals(ruleChain.getType())) {
sendDeleteNotificationMsg(tenantId, ruleChainId, relatedEdgeIds, null);
}
}
@Override
public <I extends EntityId> void notifySendMsgToEdgeService(TenantId tenantId, I entityId, EdgeEventActionType edgeEventActionType) {
sendEntityNotificationMsg(tenantId, entityId, edgeEventActionType);
}
@Override
public <E extends HasName, I extends EntityId> void notifyAssignOrUnassignEntityToCustomer(TenantId tenantId, I entityId,
CustomerId customerId, E entity,
ActionType actionType,
User user, Object... additionalInfo) {
logEntityAction(tenantId, entityId, entity, customerId, actionType, user, additionalInfo);
sendEntityNotificationMsg(tenantId, entityId, edgeTypeByActionType(actionType), JacksonUtil.toString(customerId));
}
@Override
public <E extends HasName, I extends EntityId> void notifyAssignOrUnassignEntityToEdge(TenantId tenantId, I entityId,
CustomerId customerId, EdgeId edgeId,
E entity, ActionType actionType,
User user, Object... additionalInfo) {
logEntityAction(tenantId, entityId, entity, customerId, actionType, user, additionalInfo);
sendEntityAssignToEdgeNotificationMsg(tenantId, edgeId, entityId, edgeTypeByActionType(actionType));
}
@Override @Override
public void notifyCreateOrUpdateTenant(Tenant tenant, ComponentLifecycleEvent event) { public void notifyCreateOrUpdateTenant(Tenant tenant, ComponentLifecycleEvent event) {
tbClusterService.onTenantChange(tenant, null); tbClusterService.onTenantChange(tenant, null);
@ -168,18 +110,16 @@ public class DefaultTbNotificationEntityService implements TbNotificationEntityS
@Override @Override
public void notifyDeleteDevice(TenantId tenantId, DeviceId deviceId, CustomerId customerId, Device device, public void notifyDeleteDevice(TenantId tenantId, DeviceId deviceId, CustomerId customerId, Device device,
List<EdgeId> relatedEdgeIds, User user, Object... additionalInfo) { User user, Object... additionalInfo) {
gatewayNotificationsService.onDeviceDeleted(device); gatewayNotificationsService.onDeviceDeleted(device);
tbClusterService.onDeviceDeleted(device, null); tbClusterService.onDeviceDeleted(device, null);
logEntityAction(tenantId, deviceId, device, customerId, ActionType.DELETED, user, additionalInfo);
notifyDeleteEntity(tenantId, deviceId, device, customerId, ActionType.DELETED, relatedEdgeIds, user, additionalInfo);
} }
@Override @Override
public void notifyUpdateDeviceCredentials(TenantId tenantId, DeviceId deviceId, CustomerId customerId, Device device, public void notifyUpdateDeviceCredentials(TenantId tenantId, DeviceId deviceId, CustomerId customerId, Device device,
DeviceCredentials deviceCredentials, User user) { DeviceCredentials deviceCredentials, User user) {
tbClusterService.pushMsgToCore(new DeviceCredentialsUpdateNotificationMsg(tenantId, deviceCredentials.getDeviceId(), deviceCredentials), null); tbClusterService.pushMsgToCore(new DeviceCredentialsUpdateNotificationMsg(tenantId, deviceCredentials.getDeviceId(), deviceCredentials), null);
sendEntityNotificationMsg(tenantId, deviceId, EdgeEventActionType.CREDENTIALS_UPDATED);
logEntityAction(tenantId, deviceId, device, customerId, ActionType.CREDENTIALS_UPDATED, user, deviceCredentials); logEntityAction(tenantId, deviceId, device, customerId, ActionType.CREDENTIALS_UPDATED, user, deviceCredentials);
} }
@ -190,16 +130,6 @@ public class DefaultTbNotificationEntityService implements TbNotificationEntityS
pushAssignedFromNotification(tenant, newTenantId, device); pushAssignedFromNotification(tenant, newTenantId, device);
} }
@Override
public <E extends HasName, I extends EntityId> void notifyCreateOrUpdateEntity(TenantId tenantId, I entityId, E entity,
CustomerId customerId, ActionType actionType,
User user, Object... additionalInfo) {
logEntityAction(tenantId, entityId, entity, customerId, actionType, user, additionalInfo);
if (actionType == ActionType.UPDATED) {
sendEntityNotificationMsg(tenantId, entityId, EdgeEventActionType.UPDATED);
}
}
@Override @Override
public void notifyCreateOrUpdateOrDeleteEdge(TenantId tenantId, EdgeId edgeId, CustomerId customerId, Edge edge, public void notifyCreateOrUpdateOrDeleteEdge(TenantId tenantId, EdgeId edgeId, CustomerId customerId, Edge edge,
ActionType actionType, User user, Object... additionalInfo) { ActionType actionType, User user, Object... additionalInfo) {
@ -222,71 +152,16 @@ public class DefaultTbNotificationEntityService implements TbNotificationEntityS
} }
@Override @Override
public void notifyCreateOrUpdateAlarm(AlarmInfo alarm, ActionType actionType, User user, Object... additionalInfo) { public void logEntityRelationAction(TenantId tenantId, CustomerId customerId, EntityRelation relation, User user,
logEntityAction(alarm.getTenantId(), alarm.getOriginator(), alarm, alarm.getCustomerId(), actionType, user, additionalInfo); ActionType actionType, Exception e, Object... additionalInfo) {
sendEntityNotificationMsg(alarm.getTenantId(), alarm.getId(), edgeTypeByActionType(actionType)); logEntityAction(tenantId, relation.getFrom(), null, customerId, actionType, user, e, additionalInfo);
} logEntityAction(tenantId, relation.getTo(), null, customerId, actionType, user, e, additionalInfo);
@Override
public void notifyAlarmComment(Alarm alarm, AlarmComment alarmComment, ActionType actionType, User user) {
logEntityAction(alarm.getTenantId(), alarm.getId(), alarm, alarm.getCustomerId(), actionType, user, alarmComment);
}
@Override
public <E extends HasName, I extends EntityId> void notifyCreateOrUpdateOrDelete(TenantId tenantId, CustomerId customerId,
I entityId, E entity, User user,
ActionType actionType, boolean sendNotifyMsgToEdge, Exception e,
Object... additionalInfo) {
logEntityAction(tenantId, entityId, entity, customerId, actionType, user, e, additionalInfo);
if (sendNotifyMsgToEdge) {
sendEntityNotificationMsg(tenantId, entityId, edgeTypeByActionType(actionType));
}
}
@Override
public void notifyRelation(TenantId tenantId, CustomerId customerId, EntityRelation relation, User user,
ActionType actionType, Object... additionalInfo) {
logEntityAction(tenantId, relation.getFrom(), null, customerId, actionType, user, additionalInfo);
logEntityAction(tenantId, relation.getTo(), null, customerId, actionType, user, additionalInfo);
if (!EntityType.EDGE.equals(relation.getFrom().getEntityType()) && !EntityType.EDGE.equals(relation.getTo().getEntityType())) {
sendNotificationMsgToEdge(tenantId, null, null, JacksonUtil.toString(relation),
EdgeEventType.RELATION, edgeTypeByActionType(actionType));
}
}
private void sendEntityNotificationMsg(TenantId tenantId, EntityId entityId, EdgeEventActionType action) {
sendEntityNotificationMsg(tenantId, entityId, action, null);
}
private void sendEntityNotificationMsg(TenantId tenantId, EntityId entityId, EdgeEventActionType action, String body) {
sendNotificationMsgToEdge(tenantId, null, entityId, body, null, action);
}
private void sendAlarmDeleteNotificationMsg(TenantId tenantId, Alarm alarm, List<EdgeId> edgeIds, String body) {
sendDeleteNotificationMsg(tenantId, alarm.getId(), edgeIds, body);
}
private void sendDeleteNotificationMsg(TenantId tenantId, EntityId entityId, List<EdgeId> edgeIds, String body) {
if (edgeIds != null && !edgeIds.isEmpty()) {
for (EdgeId edgeId : edgeIds) {
sendNotificationMsgToEdge(tenantId, edgeId, entityId, body, null, EdgeEventActionType.DELETED);
}
}
}
private void sendEntityAssignToEdgeNotificationMsg(TenantId tenantId, EdgeId edgeId, EntityId entityId, EdgeEventActionType action) {
sendNotificationMsgToEdge(tenantId, edgeId, entityId, null, null, action);
}
private void sendNotificationMsgToEdge(TenantId tenantId, EdgeId edgeId, EntityId entityId, String body,
EdgeEventType type, EdgeEventActionType action) {
tbClusterService.sendNotificationMsgToEdge(tenantId, edgeId, entityId, body, type, action);
} }
private void pushAssignedFromNotification(Tenant currentTenant, TenantId newTenantId, Device assignedDevice) { private void pushAssignedFromNotification(Tenant currentTenant, TenantId newTenantId, Device assignedDevice) {
String data = JacksonUtil.toString(JacksonUtil.valueToTree(assignedDevice)); String data = JacksonUtil.toString(JacksonUtil.valueToTree(assignedDevice));
if (data != null) { if (data != null) {
TbMsg tbMsg = TbMsg.newMsg(DataConstants.ENTITY_ASSIGNED_FROM_TENANT, assignedDevice.getId(), TbMsg tbMsg = TbMsg.newMsg(TbMsgType.ENTITY_ASSIGNED_FROM_TENANT, assignedDevice.getId(),
assignedDevice.getCustomerId(), getMetaDataForAssignedFrom(currentTenant), TbMsgDataType.JSON, data); assignedDevice.getCustomerId(), getMetaDataForAssignedFrom(currentTenant), TbMsgDataType.JSON, data);
tbClusterService.pushMsgToRuleEngine(newTenantId, assignedDevice.getId(), tbMsg, null); tbClusterService.pushMsgToRuleEngine(newTenantId, assignedDevice.getId(), tbMsg, null);
} }
@ -327,6 +202,8 @@ public class DefaultTbNotificationEntityService implements TbNotificationEntityS
return EdgeEventActionType.ASSIGNED_TO_EDGE; return EdgeEventActionType.ASSIGNED_TO_EDGE;
case UNASSIGNED_FROM_EDGE: case UNASSIGNED_FROM_EDGE:
return EdgeEventActionType.UNASSIGNED_FROM_EDGE; return EdgeEventActionType.UNASSIGNED_FROM_EDGE;
case CREDENTIALS_UPDATED:
return EdgeEventActionType.CREDENTIALS_UPDATED;
default: default:
return null; return null;
} }

50
application/src/main/java/org/thingsboard/server/service/entitiy/TbNotificationEntityService.java

@ -19,12 +19,8 @@ import org.thingsboard.server.common.data.Device;
import org.thingsboard.server.common.data.HasName; import org.thingsboard.server.common.data.HasName;
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.alarm.Alarm;
import org.thingsboard.server.common.data.alarm.AlarmComment;
import org.thingsboard.server.common.data.alarm.AlarmInfo;
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.EdgeEventActionType;
import org.thingsboard.server.common.data.id.CustomerId; import org.thingsboard.server.common.data.id.CustomerId;
import org.thingsboard.server.common.data.id.DeviceId; import org.thingsboard.server.common.data.id.DeviceId;
import org.thingsboard.server.common.data.id.EdgeId; import org.thingsboard.server.common.data.id.EdgeId;
@ -32,11 +28,8 @@ 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.ComponentLifecycleEvent; import org.thingsboard.server.common.data.plugin.ComponentLifecycleEvent;
import org.thingsboard.server.common.data.relation.EntityRelation; import org.thingsboard.server.common.data.relation.EntityRelation;
import org.thingsboard.server.common.data.rule.RuleChain;
import org.thingsboard.server.common.data.security.DeviceCredentials; import org.thingsboard.server.common.data.security.DeviceCredentials;
import java.util.List;
public interface TbNotificationEntityService { public interface TbNotificationEntityService {
<I extends EntityId> void logEntityAction(TenantId tenantId, I entityId, ActionType actionType, User user, <I extends EntityId> void logEntityAction(TenantId tenantId, I entityId, ActionType actionType, User user,
@ -55,33 +48,6 @@ public interface TbNotificationEntityService {
ActionType actionType, User user, Exception e, ActionType actionType, User user, Exception e,
Object... additionalInfo); Object... additionalInfo);
<E extends HasName, I extends EntityId> void notifyCreateOrUpdateEntity(TenantId tenantId, I entityId, E entity,
CustomerId customerId, ActionType actionType,
User user, Object... additionalInfo);
<E extends HasName, I extends EntityId> void notifyDeleteEntity(TenantId tenantId, I entityId, E entity,
CustomerId customerId, ActionType actionType,
List<EdgeId> relatedEdgeIds,
User user, Object... additionalInfo);
void notifyDeleteAlarm(TenantId tenantId, Alarm alarm, EntityId originatorId, CustomerId customerId,
List<EdgeId> relatedEdgeIds, User user, String body, Object... additionalInfo);
void notifyDeleteRuleChain(TenantId tenantId, RuleChain ruleChain,
List<EdgeId> relatedEdgeIds, User user);
<I extends EntityId> void notifySendMsgToEdgeService(TenantId tenantId, I entityId, EdgeEventActionType edgeEventActionType);
<E extends HasName, I extends EntityId> void notifyAssignOrUnassignEntityToCustomer(TenantId tenantId, I entityId,
CustomerId customerId, E entity,
ActionType actionType,
User user, Object... additionalInfo);
<E extends HasName, I extends EntityId> void notifyAssignOrUnassignEntityToEdge(TenantId tenantId, I entityId,
CustomerId customerId, EdgeId edgeId,
E entity, ActionType actionType,
User user, Object... additionalInfo);
void notifyCreateOrUpdateTenant(Tenant tenant, ComponentLifecycleEvent event); void notifyCreateOrUpdateTenant(Tenant tenant, ComponentLifecycleEvent event);
void notifyDeleteTenant(Tenant tenant); void notifyDeleteTenant(Tenant tenant);
@ -90,7 +56,7 @@ public interface TbNotificationEntityService {
Device oldDevice, ActionType actionType, User user, Object... additionalInfo); Device oldDevice, ActionType actionType, User user, Object... additionalInfo);
void notifyDeleteDevice(TenantId tenantId, DeviceId deviceId, CustomerId customerId, Device device, void notifyDeleteDevice(TenantId tenantId, DeviceId deviceId, CustomerId customerId, Device device,
List<EdgeId> relatedEdgeIds, User user, Object... additionalInfo); User user, Object... additionalInfo);
void notifyUpdateDeviceCredentials(TenantId tenantId, DeviceId deviceId, CustomerId customerId, Device device, void notifyUpdateDeviceCredentials(TenantId tenantId, DeviceId deviceId, CustomerId customerId, Device device,
DeviceCredentials deviceCredentials, User user); DeviceCredentials deviceCredentials, User user);
@ -101,16 +67,6 @@ public interface TbNotificationEntityService {
void notifyCreateOrUpdateOrDeleteEdge(TenantId tenantId, EdgeId edgeId, CustomerId customerId, Edge edge, ActionType actionType, void notifyCreateOrUpdateOrDeleteEdge(TenantId tenantId, EdgeId edgeId, CustomerId customerId, Edge edge, ActionType actionType,
User user, Object... additionalInfo); User user, Object... additionalInfo);
void notifyCreateOrUpdateAlarm(AlarmInfo alarm, ActionType actionType, User user, Object... additionalInfo); void logEntityRelationAction(TenantId tenantId, CustomerId customerId, EntityRelation relation, User user,
ActionType actionType, Exception e, Object... additionalInfo);
void notifyAlarmComment(Alarm alarm, AlarmComment alarmComment, ActionType actionType, User user);
<E extends HasName, I extends EntityId> void notifyCreateOrUpdateOrDelete(TenantId tenantId, CustomerId customerId,
I entityId, E entity, User user,
ActionType actionType, boolean sendNotifyMsgToEdge,
Exception e, Object... additionalInfo);
void notifyRelation(TenantId tenantId, CustomerId customerId, EntityRelation relation, User user,
ActionType actionType, Object... additionalInfo);
} }

5
application/src/main/java/org/thingsboard/server/service/entitiy/alarm/DefaultTbAlarmCommentService.java

@ -45,7 +45,8 @@ public class DefaultTbAlarmCommentService extends AbstractTbEntityService implem
} }
try { try {
AlarmComment savedAlarmComment = checkNotNull(alarmCommentService.createOrUpdateAlarmComment(alarm.getTenantId(), alarmComment)); AlarmComment savedAlarmComment = checkNotNull(alarmCommentService.createOrUpdateAlarmComment(alarm.getTenantId(), alarmComment));
notificationEntityService.notifyAlarmComment(alarm, savedAlarmComment, actionType, user); notificationEntityService.logEntityAction(alarm.getTenantId(), alarm.getId(), alarm, alarm.getCustomerId(), actionType, user, savedAlarmComment);
return savedAlarmComment; return savedAlarmComment;
} catch (Exception e) { } catch (Exception e) {
notificationEntityService.logEntityAction(alarm.getTenantId(), emptyId(EntityType.ALARM), alarm, actionType, user, e, alarmComment); notificationEntityService.logEntityAction(alarm.getTenantId(), emptyId(EntityType.ALARM), alarm, actionType, user, e, alarmComment);
@ -62,7 +63,7 @@ public class DefaultTbAlarmCommentService extends AbstractTbEntityService implem
String.format("User %s deleted his comment", String.format("User %s deleted his comment",
(user.getFirstName() == null || user.getLastName() == null) ? user.getName() : user.getFirstName() + " " + user.getLastName()))); (user.getFirstName() == null || user.getLastName() == null) ? user.getName() : user.getFirstName() + " " + user.getLastName())));
AlarmComment savedAlarmComment = checkNotNull(alarmCommentService.saveAlarmComment(alarm.getTenantId(), alarmComment)); AlarmComment savedAlarmComment = checkNotNull(alarmCommentService.saveAlarmComment(alarm.getTenantId(), alarmComment));
notificationEntityService.notifyAlarmComment(alarm, savedAlarmComment, ActionType.DELETED_COMMENT, user); notificationEntityService.logEntityAction(alarm.getTenantId(), alarm.getId(), alarm, alarm.getCustomerId(), ActionType.DELETED_COMMENT, user, savedAlarmComment);
} else { } else {
throw new ThingsboardException("System comment could not be deleted", ThingsboardErrorCode.BAD_REQUEST_PARAMS); throw new ThingsboardException("System comment could not be deleted", ThingsboardErrorCode.BAD_REQUEST_PARAMS);
} }

64
application/src/main/java/org/thingsboard/server/service/entitiy/alarm/DefaultTbAlarmService.java

@ -62,10 +62,6 @@ public class DefaultTbAlarmService extends AbstractTbEntityService implements Tb
if (!result.isSuccessful()) { if (!result.isSuccessful()) {
throw new ThingsboardException(ThingsboardErrorCode.ITEM_NOT_FOUND); throw new ThingsboardException(ThingsboardErrorCode.ITEM_NOT_FOUND);
} }
actionType = result.isCreated() ? ActionType.ADDED : ActionType.UPDATED;
if (result.isModified()) {
notificationEntityService.notifyCreateOrUpdateAlarm(result.getAlarm(), actionType, user);
}
AlarmInfo resultAlarm = result.getAlarm(); AlarmInfo resultAlarm = result.getAlarm();
if (alarm.isAcknowledged() && !resultAlarm.isAcknowledged()) { if (alarm.isAcknowledged() && !resultAlarm.isAcknowledged()) {
resultAlarm = ack(resultAlarm, alarm.getAckTs(), user); resultAlarm = ack(resultAlarm, alarm.getAckTs(), user);
@ -80,6 +76,10 @@ public class DefaultTbAlarmService extends AbstractTbEntityService implements Tb
} else if (newAssignee == null && curAssignee != null) { } else if (newAssignee == null && curAssignee != null) {
resultAlarm = unassign(alarm, alarm.getAssignTs(), user); resultAlarm = unassign(alarm, alarm.getAssignTs(), user);
} }
if (result.isModified()) {
notificationEntityService.logEntityAction(tenantId, alarm.getOriginator(), resultAlarm,
resultAlarm.getCustomerId(), actionType, user);
}
return new Alarm(resultAlarm); return new Alarm(resultAlarm);
} catch (Exception e) { } catch (Exception e) {
notificationEntityService.logEntityAction(tenantId, emptyId(EntityType.ALARM), alarm, actionType, user, e); notificationEntityService.logEntityAction(tenantId, emptyId(EntityType.ALARM), alarm, actionType, user, e);
@ -98,6 +98,7 @@ public class DefaultTbAlarmService extends AbstractTbEntityService implements Tb
if (!result.isSuccessful()) { if (!result.isSuccessful()) {
throw new ThingsboardException(ThingsboardErrorCode.ITEM_NOT_FOUND); throw new ThingsboardException(ThingsboardErrorCode.ITEM_NOT_FOUND);
} }
AlarmInfo alarmInfo = result.getAlarm();
if (result.isModified()) { if (result.isModified()) {
AlarmComment alarmComment = AlarmComment.builder() AlarmComment alarmComment = AlarmComment.builder()
.alarmId(alarm.getId()) .alarmId(alarm.getId())
@ -112,11 +113,12 @@ public class DefaultTbAlarmService extends AbstractTbEntityService implements Tb
} catch (ThingsboardException e) { } catch (ThingsboardException e) {
log.error("Failed to save alarm comment", e); log.error("Failed to save alarm comment", e);
} }
notificationEntityService.notifyCreateOrUpdateAlarm(result.getAlarm(), ActionType.ALARM_ACK, user); notificationEntityService.logEntityAction(alarm.getTenantId(), alarm.getOriginator(), alarmInfo,
alarmInfo.getCustomerId(), ActionType.ALARM_ACK, user);
} else { } else {
throw new ThingsboardException("Alarm was already acknowledged!", ThingsboardErrorCode.BAD_REQUEST_PARAMS); throw new ThingsboardException("Alarm was already acknowledged!", ThingsboardErrorCode.BAD_REQUEST_PARAMS);
} }
return result.getAlarm(); return alarmInfo;
} }
@Override @Override
@ -130,6 +132,7 @@ public class DefaultTbAlarmService extends AbstractTbEntityService implements Tb
if (!result.isSuccessful()) { if (!result.isSuccessful()) {
throw new ThingsboardException(ThingsboardErrorCode.ITEM_NOT_FOUND); throw new ThingsboardException(ThingsboardErrorCode.ITEM_NOT_FOUND);
} }
AlarmInfo alarmInfo = result.getAlarm();
if (result.isCleared()) { if (result.isCleared()) {
AlarmComment alarmComment = AlarmComment.builder() AlarmComment alarmComment = AlarmComment.builder()
.alarmId(alarm.getId()) .alarmId(alarm.getId())
@ -144,11 +147,12 @@ public class DefaultTbAlarmService extends AbstractTbEntityService implements Tb
} catch (ThingsboardException e) { } catch (ThingsboardException e) {
log.error("Failed to save alarm comment", e); log.error("Failed to save alarm comment", e);
} }
notificationEntityService.notifyCreateOrUpdateAlarm(result.getAlarm(), ActionType.ALARM_CLEAR, user); notificationEntityService.logEntityAction(alarm.getTenantId(), alarm.getOriginator(), alarmInfo,
alarmInfo.getCustomerId(), ActionType.ALARM_CLEAR, user);
} else { } else {
throw new ThingsboardException("Alarm was already cleared!", ThingsboardErrorCode.BAD_REQUEST_PARAMS); throw new ThingsboardException("Alarm was already cleared!", ThingsboardErrorCode.BAD_REQUEST_PARAMS);
} }
return result.getAlarm(); return alarmInfo;
} }
@Override @Override
@ -175,7 +179,8 @@ public class DefaultTbAlarmService extends AbstractTbEntityService implements Tb
} catch (ThingsboardException e) { } catch (ThingsboardException e) {
log.error("Failed to save alarm comment", e); log.error("Failed to save alarm comment", e);
} }
notificationEntityService.notifyCreateOrUpdateAlarm(result.getAlarm(), ActionType.ALARM_ASSIGNED, user); notificationEntityService.logEntityAction(alarm.getTenantId(), alarm.getOriginator(), alarmInfo,
alarmInfo.getCustomerId(), ActionType.ALARM_ASSIGNED, user);
} else { } else {
throw new ThingsboardException("Alarm was already assigned to this user!", ThingsboardErrorCode.BAD_REQUEST_PARAMS); throw new ThingsboardException("Alarm was already assigned to this user!", ThingsboardErrorCode.BAD_REQUEST_PARAMS);
} }
@ -203,20 +208,53 @@ public class DefaultTbAlarmService extends AbstractTbEntityService implements Tb
} catch (ThingsboardException e) { } catch (ThingsboardException e) {
log.error("Failed to save alarm comment", e); log.error("Failed to save alarm comment", e);
} }
notificationEntityService.notifyCreateOrUpdateAlarm(result.getAlarm(), ActionType.ALARM_UNASSIGNED, user); notificationEntityService.logEntityAction(alarm.getTenantId(), alarm.getOriginator(), alarmInfo,
alarmInfo.getCustomerId(), ActionType.ALARM_UNASSIGNED, user);
} else { } else {
throw new ThingsboardException("Alarm was already unassigned!", ThingsboardErrorCode.BAD_REQUEST_PARAMS); throw new ThingsboardException("Alarm was already unassigned!", ThingsboardErrorCode.BAD_REQUEST_PARAMS);
} }
return alarmInfo; return alarmInfo;
} }
@Override
public void unassignUserAlarms(TenantId tenantId, User user, long unassignTs) {
AlarmQueryV2 alarmQuery = AlarmQueryV2.builder().assigneeId(user.getId()).pageLink(new TimePageLink(Integer.MAX_VALUE)).build();
try {
List<AlarmInfo> alarms = alarmService.findAlarmsV2(tenantId, alarmQuery).get(30, TimeUnit.SECONDS).getData();
for (AlarmInfo alarm : alarms) {
AlarmApiCallResult result = alarmSubscriptionService.unassignAlarm(tenantId, alarm.getId(), getOrDefault(unassignTs));
if (!result.isSuccessful()) {
continue;
}
if (result.isModified()) {
AlarmComment alarmComment = AlarmComment.builder()
.alarmId(alarm.getId())
.type(AlarmCommentType.SYSTEM)
.comment(JacksonUtil.newObjectNode().put("text", String.format("Alarm was unassigned because user %s - was deleted",
(user.getFirstName() == null || user.getLastName() == null) ? user.getName() : user.getFirstName() + " " + user.getLastName()))
.put("userId", user.getId().toString())
.put("subtype", "ASSIGN"))
.build();
try {
alarmCommentService.saveAlarmComment(alarm, alarmComment, user);
} catch (ThingsboardException e) {
log.error("Failed to save alarm comment", e);
}
notificationEntityService.logEntityAction(alarm.getTenantId(), alarm.getOriginator(), result.getAlarm(),
alarm.getCustomerId(), ActionType.ALARM_UNASSIGNED, user);
}
}
} catch (InterruptedException | ExecutionException | TimeoutException e) {
throw new RuntimeException(e);
}
}
@Override @Override
public Boolean delete(Alarm alarm, User user) { public Boolean delete(Alarm alarm, User user) {
TenantId tenantId = alarm.getTenantId(); TenantId tenantId = alarm.getTenantId();
List<EdgeId> relatedEdgeIds = edgeService.findAllRelatedEdgeIds(tenantId, alarm.getOriginator()); notificationEntityService.logEntityAction(tenantId, alarm.getOriginator(), alarm, alarm.getCustomerId(),
notificationEntityService.notifyDeleteAlarm(tenantId, alarm, alarm.getOriginator(), alarm.getCustomerId(), ActionType.DELETED, user);
relatedEdgeIds, user, JacksonUtil.toString(alarm));
return alarmSubscriptionService.deleteAlarm(tenantId, alarm.getId()); return alarmSubscriptionService.deleteAlarm(tenantId, alarm.getId());
} }

36
application/src/main/java/org/thingsboard/server/service/entitiy/asset/DefaultTbAssetService.java

@ -36,8 +36,6 @@ import org.thingsboard.server.dao.asset.AssetService;
import org.thingsboard.server.service.entitiy.AbstractTbEntityService; import org.thingsboard.server.service.entitiy.AbstractTbEntityService;
import org.thingsboard.server.service.profile.TbAssetProfileCache; import org.thingsboard.server.service.profile.TbAssetProfileCache;
import java.util.List;
import static org.thingsboard.server.dao.asset.BaseAssetService.TB_SERVICE_QUEUE; import static org.thingsboard.server.dao.asset.BaseAssetService.TB_SERVICE_QUEUE;
@Service @Service
@ -62,8 +60,8 @@ public class DefaultTbAssetService extends AbstractTbEntityService implements Tb
} }
Asset savedAsset = checkNotNull(assetService.saveAsset(asset)); Asset savedAsset = checkNotNull(assetService.saveAsset(asset));
autoCommit(user, savedAsset.getId()); autoCommit(user, savedAsset.getId());
notificationEntityService.notifyCreateOrUpdateEntity(tenantId, savedAsset.getId(), savedAsset, notificationEntityService.logEntityAction(tenantId, savedAsset.getId(), savedAsset, asset.getCustomerId(),
asset.getCustomerId(), actionType, user); actionType, user);
tbClusterService.broadcastEntityStateChangeEvent(tenantId, savedAsset.getId(), tbClusterService.broadcastEntityStateChangeEvent(tenantId, savedAsset.getId(),
asset.getId() == null ? ComponentLifecycleEvent.CREATED : ComponentLifecycleEvent.UPDATED); asset.getId() == null ? ComponentLifecycleEvent.CREATED : ComponentLifecycleEvent.UPDATED);
return savedAsset; return savedAsset;
@ -75,17 +73,16 @@ public class DefaultTbAssetService extends AbstractTbEntityService implements Tb
@Override @Override
public ListenableFuture<Void> delete(Asset asset, User user) { public ListenableFuture<Void> delete(Asset asset, User user) {
ActionType actionType = ActionType.DELETED;
TenantId tenantId = asset.getTenantId(); TenantId tenantId = asset.getTenantId();
AssetId assetId = asset.getId(); AssetId assetId = asset.getId();
try { try {
List<EdgeId> relatedEdgeIds = edgeService.findAllRelatedEdgeIds(tenantId, assetId);
assetService.deleteAsset(tenantId, assetId); assetService.deleteAsset(tenantId, assetId);
notificationEntityService.notifyDeleteEntity(tenantId, assetId, asset, asset.getCustomerId(), notificationEntityService.logEntityAction(tenantId, assetId, asset, asset.getCustomerId(), actionType, user, assetId.toString());
ActionType.DELETED, relatedEdgeIds, user, assetId.toString());
tbClusterService.broadcastEntityStateChangeEvent(tenantId, assetId, ComponentLifecycleEvent.DELETED); tbClusterService.broadcastEntityStateChangeEvent(tenantId, assetId, ComponentLifecycleEvent.DELETED);
return removeAlarmsByEntityId(tenantId, assetId); return removeAlarmsByEntityId(tenantId, assetId);
} catch (Exception e) { } catch (Exception e) {
notificationEntityService.logEntityAction(tenantId, emptyId(EntityType.ASSET), ActionType.DELETED, user, e, notificationEntityService.logEntityAction(tenantId, emptyId(EntityType.ASSET), actionType, user, e,
assetId.toString()); assetId.toString());
throw e; throw e;
} }
@ -97,8 +94,8 @@ public class DefaultTbAssetService extends AbstractTbEntityService implements Tb
CustomerId customerId = customer.getId(); CustomerId customerId = customer.getId();
try { try {
Asset savedAsset = checkNotNull(assetService.assignAssetToCustomer(tenantId, assetId, customerId)); Asset savedAsset = checkNotNull(assetService.assignAssetToCustomer(tenantId, assetId, customerId));
notificationEntityService.notifyAssignOrUnassignEntityToCustomer(tenantId, assetId, customerId, savedAsset, notificationEntityService.logEntityAction(tenantId, assetId, savedAsset, customerId, actionType, user,
actionType, user, assetId.toString(), customerId.toString(), customer.getName()); assetId.toString(), customerId.toString(), customer.getName());
return savedAsset; return savedAsset;
} catch (Exception e) { } catch (Exception e) {
@ -114,8 +111,8 @@ public class DefaultTbAssetService extends AbstractTbEntityService implements Tb
try { try {
Asset savedAsset = checkNotNull(assetService.unassignAssetFromCustomer(tenantId, assetId)); Asset savedAsset = checkNotNull(assetService.unassignAssetFromCustomer(tenantId, assetId));
CustomerId customerId = customer.getId(); CustomerId customerId = customer.getId();
notificationEntityService.notifyAssignOrUnassignEntityToCustomer(tenantId, assetId, customerId, savedAsset, notificationEntityService.logEntityAction(tenantId, assetId, savedAsset, customerId, actionType, user,
actionType, user, assetId.toString(), customerId.toString(), customer.getName()); assetId.toString(), customerId.toString(), customer.getName());
return savedAsset; return savedAsset;
} catch (Exception e) { } catch (Exception e) {
@ -130,8 +127,9 @@ public class DefaultTbAssetService extends AbstractTbEntityService implements Tb
try { try {
Customer publicCustomer = customerService.findOrCreatePublicCustomer(tenantId); Customer publicCustomer = customerService.findOrCreatePublicCustomer(tenantId);
Asset savedAsset = checkNotNull(assetService.assignAssetToCustomer(tenantId, assetId, publicCustomer.getId())); Asset savedAsset = checkNotNull(assetService.assignAssetToCustomer(tenantId, assetId, publicCustomer.getId()));
notificationEntityService.notifyAssignOrUnassignEntityToCustomer(tenantId, assetId, savedAsset.getCustomerId(), savedAsset, CustomerId customerId = publicCustomer.getId();
actionType, user, assetId.toString(), publicCustomer.getId().toString(), publicCustomer.getName()); notificationEntityService.logEntityAction(tenantId, assetId, savedAsset, customerId, actionType, user,
assetId.toString(), customerId.toString(), publicCustomer.getName());
return savedAsset; return savedAsset;
} catch (Exception e) { } catch (Exception e) {
@ -146,9 +144,8 @@ public class DefaultTbAssetService extends AbstractTbEntityService implements Tb
EdgeId edgeId = edge.getId(); EdgeId edgeId = edge.getId();
try { try {
Asset savedAsset = checkNotNull(assetService.assignAssetToEdge(tenantId, assetId, edgeId)); Asset savedAsset = checkNotNull(assetService.assignAssetToEdge(tenantId, assetId, edgeId));
notificationEntityService.notifyAssignOrUnassignEntityToEdge(tenantId, assetId, savedAsset.getCustomerId(), notificationEntityService.logEntityAction(tenantId, assetId, savedAsset, savedAsset.getCustomerId(),
edgeId, savedAsset, actionType, user, assetId.toString(), edgeId.toString(), edge.getName()); actionType, user, assetId.toString(), edgeId.toString(), edge.getName());
return savedAsset; return savedAsset;
} catch (Exception e) { } catch (Exception e) {
notificationEntityService.logEntityAction(tenantId, emptyId(EntityType.ASSET), actionType, notificationEntityService.logEntityAction(tenantId, emptyId(EntityType.ASSET), actionType,
@ -164,9 +161,8 @@ public class DefaultTbAssetService extends AbstractTbEntityService implements Tb
EdgeId edgeId = edge.getId(); EdgeId edgeId = edge.getId();
try { try {
Asset savedAsset = checkNotNull(assetService.unassignAssetFromEdge(tenantId, assetId, edgeId)); Asset savedAsset = checkNotNull(assetService.unassignAssetFromEdge(tenantId, assetId, edgeId));
notificationEntityService.logEntityAction(tenantId, assetId, asset, asset.getCustomerId(),
notificationEntityService.notifyAssignOrUnassignEntityToEdge(tenantId, assetId, asset.getCustomerId(), actionType, user, assetId.toString(), edgeId.toString(), edge.getName());
edgeId, asset, actionType, user, assetId.toString(), edgeId.toString(), edge.getName());
return savedAsset; return savedAsset;
} catch (Exception e) { } catch (Exception e) {

11
application/src/main/java/org/thingsboard/server/service/entitiy/asset/profile/DefaultTbAssetProfileService.java

@ -59,8 +59,8 @@ public class DefaultTbAssetProfileService extends AbstractTbEntityService implem
tbClusterService.broadcastEntityStateChangeEvent(tenantId, savedAssetProfile.getId(), tbClusterService.broadcastEntityStateChangeEvent(tenantId, savedAssetProfile.getId(),
actionType.equals(ActionType.ADDED) ? ComponentLifecycleEvent.CREATED : ComponentLifecycleEvent.UPDATED); actionType.equals(ActionType.ADDED) ? ComponentLifecycleEvent.CREATED : ComponentLifecycleEvent.UPDATED);
notificationEntityService.notifyCreateOrUpdateOrDelete(tenantId, null, savedAssetProfile.getId(), notificationEntityService.logEntityAction(tenantId, savedAssetProfile.getId(), savedAssetProfile,
savedAssetProfile, user, actionType, true, null); null, actionType, user);
return savedAssetProfile; return savedAssetProfile;
} catch (Exception e) { } catch (Exception e) {
notificationEntityService.logEntityAction(tenantId, emptyId(EntityType.ASSET_PROFILE), assetProfile, actionType, user, e); notificationEntityService.logEntityAction(tenantId, emptyId(EntityType.ASSET_PROFILE), assetProfile, actionType, user, e);
@ -70,16 +70,17 @@ public class DefaultTbAssetProfileService extends AbstractTbEntityService implem
@Override @Override
public void delete(AssetProfile assetProfile, User user) { public void delete(AssetProfile assetProfile, User user) {
ActionType actionType = ActionType.DELETED;
AssetProfileId assetProfileId = assetProfile.getId(); AssetProfileId assetProfileId = assetProfile.getId();
TenantId tenantId = assetProfile.getTenantId(); TenantId tenantId = assetProfile.getTenantId();
try { try {
assetProfileService.deleteAssetProfile(tenantId, assetProfileId); assetProfileService.deleteAssetProfile(tenantId, assetProfileId);
tbClusterService.broadcastEntityStateChangeEvent(tenantId, assetProfileId, ComponentLifecycleEvent.DELETED); tbClusterService.broadcastEntityStateChangeEvent(tenantId, assetProfileId, ComponentLifecycleEvent.DELETED);
notificationEntityService.notifyCreateOrUpdateOrDelete(tenantId, null, assetProfileId, assetProfile, notificationEntityService.logEntityAction(tenantId, assetProfileId, assetProfile, null,
user, ActionType.DELETED, true, null, assetProfileId.toString()); actionType, user, assetProfileId.toString());
} catch (Exception e) { } catch (Exception e) {
notificationEntityService.logEntityAction(tenantId, emptyId(EntityType.ASSET_PROFILE), ActionType.DELETED, notificationEntityService.logEntityAction(tenantId, emptyId(EntityType.ASSET_PROFILE), actionType,
user, e, assetProfileId.toString()); user, e, assetProfileId.toString());
throw e; throw e;
} }

15
application/src/main/java/org/thingsboard/server/service/entitiy/customer/DefaultTbCustomerService.java

@ -22,13 +22,10 @@ import org.thingsboard.server.common.data.EntityType;
import org.thingsboard.server.common.data.User; import org.thingsboard.server.common.data.User;
import org.thingsboard.server.common.data.audit.ActionType; import org.thingsboard.server.common.data.audit.ActionType;
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.TenantId; import org.thingsboard.server.common.data.id.TenantId;
import org.thingsboard.server.common.data.plugin.ComponentLifecycleEvent; import org.thingsboard.server.common.data.plugin.ComponentLifecycleEvent;
import org.thingsboard.server.service.entitiy.AbstractTbEntityService; import org.thingsboard.server.service.entitiy.AbstractTbEntityService;
import java.util.List;
@Service @Service
@AllArgsConstructor @AllArgsConstructor
public class DefaultTbCustomerService extends AbstractTbEntityService implements TbCustomerService { public class DefaultTbCustomerService extends AbstractTbEntityService implements TbCustomerService {
@ -40,7 +37,7 @@ public class DefaultTbCustomerService extends AbstractTbEntityService implements
try { try {
Customer savedCustomer = checkNotNull(customerService.saveCustomer(customer)); Customer savedCustomer = checkNotNull(customerService.saveCustomer(customer));
autoCommit(user, savedCustomer.getId()); autoCommit(user, savedCustomer.getId());
notificationEntityService.notifyCreateOrUpdateEntity(tenantId, savedCustomer.getId(), savedCustomer, null, actionType, user); notificationEntityService.logEntityAction(tenantId, savedCustomer.getId(), savedCustomer, null, actionType, user);
return savedCustomer; return savedCustomer;
} catch (Exception e) { } catch (Exception e) {
notificationEntityService.logEntityAction(tenantId, emptyId(EntityType.CUSTOMER), customer, actionType, user, e); notificationEntityService.logEntityAction(tenantId, emptyId(EntityType.CUSTOMER), customer, actionType, user, e);
@ -50,17 +47,17 @@ public class DefaultTbCustomerService extends AbstractTbEntityService implements
@Override @Override
public void delete(Customer customer, User user) { public void delete(Customer customer, User user) {
ActionType actionType = ActionType.DELETED;
TenantId tenantId = customer.getTenantId(); TenantId tenantId = customer.getTenantId();
CustomerId customerId = customer.getId(); CustomerId customerId = customer.getId();
try { try {
List<EdgeId> relatedEdgeIds = edgeService.findAllRelatedEdgeIds(tenantId, customer.getId());
customerService.deleteCustomer(tenantId, customerId); customerService.deleteCustomer(tenantId, customerId);
notificationEntityService.notifyDeleteEntity(tenantId, customer.getId(), customer, customerId, notificationEntityService.logEntityAction(tenantId, customer.getId(), customer, customerId, actionType,
ActionType.DELETED, relatedEdgeIds, user, customerId.toString()); user, customerId.toString());
tbClusterService.broadcastEntityStateChangeEvent(tenantId, customer.getId(), ComponentLifecycleEvent.DELETED); tbClusterService.broadcastEntityStateChangeEvent(tenantId, customer.getId(), ComponentLifecycleEvent.DELETED);
} catch (Exception e) { } catch (Exception e) {
notificationEntityService.logEntityAction(tenantId, emptyId(EntityType.CUSTOMER), ActionType.DELETED, notificationEntityService.logEntityAction(tenantId, emptyId(EntityType.CUSTOMER), actionType, user,
user, e, customerId.toString()); e, customerId.toString());
throw e; throw e;
} }
} }

49
application/src/main/java/org/thingsboard/server/service/entitiy/dashboard/DefaultTbDashboardService.java

@ -34,7 +34,6 @@ import org.thingsboard.server.queue.util.TbCoreComponent;
import org.thingsboard.server.service.entitiy.AbstractTbEntityService; import org.thingsboard.server.service.entitiy.AbstractTbEntityService;
import java.util.HashSet; import java.util.HashSet;
import java.util.List;
import java.util.Set; import java.util.Set;
@Service @Service
@ -51,8 +50,8 @@ public class DefaultTbDashboardService extends AbstractTbEntityService implement
try { try {
Dashboard savedDashboard = checkNotNull(dashboardService.saveDashboard(dashboard)); Dashboard savedDashboard = checkNotNull(dashboardService.saveDashboard(dashboard));
autoCommit(user, savedDashboard.getId()); autoCommit(user, savedDashboard.getId());
notificationEntityService.notifyCreateOrUpdateEntity(tenantId, savedDashboard.getId(), savedDashboard, notificationEntityService.logEntityAction(tenantId, savedDashboard.getId(), savedDashboard, null,
null, actionType, user); actionType, user);
return savedDashboard; return savedDashboard;
} catch (Exception e) { } catch (Exception e) {
notificationEntityService.logEntityAction(tenantId, emptyId(EntityType.DASHBOARD), dashboard, actionType, user, e); notificationEntityService.logEntityAction(tenantId, emptyId(EntityType.DASHBOARD), dashboard, actionType, user, e);
@ -62,15 +61,14 @@ public class DefaultTbDashboardService extends AbstractTbEntityService implement
@Override @Override
public void delete(Dashboard dashboard, User user) { public void delete(Dashboard dashboard, User user) {
ActionType actionType = ActionType.DELETED;
DashboardId dashboardId = dashboard.getId(); DashboardId dashboardId = dashboard.getId();
TenantId tenantId = dashboard.getTenantId(); TenantId tenantId = dashboard.getTenantId();
try { try {
List<EdgeId> relatedEdgeIds = edgeService.findAllRelatedEdgeIds(tenantId, dashboardId);
dashboardService.deleteDashboard(tenantId, dashboardId); dashboardService.deleteDashboard(tenantId, dashboardId);
notificationEntityService.notifyDeleteEntity(tenantId, dashboardId, dashboard, null, notificationEntityService.logEntityAction(tenantId, dashboardId, dashboard, null, actionType, user, dashboardId.toString());
ActionType.DELETED, relatedEdgeIds, user, dashboardId.toString());
} catch (Exception e) { } catch (Exception e) {
notificationEntityService.logEntityAction(tenantId, emptyId(EntityType.DASHBOARD), ActionType.DELETED, user, e, dashboardId.toString()); notificationEntityService.logEntityAction(tenantId, emptyId(EntityType.DASHBOARD), actionType, user, e, dashboardId.toString());
throw e; throw e;
} }
} }
@ -83,8 +81,8 @@ public class DefaultTbDashboardService extends AbstractTbEntityService implement
DashboardId dashboardId = dashboard.getId(); DashboardId dashboardId = dashboard.getId();
try { try {
Dashboard savedDashboard = checkNotNull(dashboardService.assignDashboardToCustomer(tenantId, dashboardId, customerId)); Dashboard savedDashboard = checkNotNull(dashboardService.assignDashboardToCustomer(tenantId, dashboardId, customerId));
notificationEntityService.notifyAssignOrUnassignEntityToCustomer(tenantId, dashboardId, customerId, savedDashboard, notificationEntityService.logEntityAction(tenantId, dashboardId, savedDashboard, customerId, actionType,
actionType, user, dashboardId.toString(), customerId.toString(), customer.getName()); user, dashboardId.toString(), customerId.toString(), customer.getName());
return savedDashboard; return savedDashboard;
} catch (Exception e) { } catch (Exception e) {
notificationEntityService.logEntityAction(tenantId, emptyId(EntityType.DASHBOARD), actionType, notificationEntityService.logEntityAction(tenantId, emptyId(EntityType.DASHBOARD), actionType,
@ -101,9 +99,8 @@ public class DefaultTbDashboardService extends AbstractTbEntityService implement
try { try {
Customer publicCustomer = customerService.findOrCreatePublicCustomer(tenantId); Customer publicCustomer = customerService.findOrCreatePublicCustomer(tenantId);
Dashboard savedDashboard = checkNotNull(dashboardService.assignDashboardToCustomer(tenantId, dashboardId, publicCustomer.getId())); Dashboard savedDashboard = checkNotNull(dashboardService.assignDashboardToCustomer(tenantId, dashboardId, publicCustomer.getId()));
notificationEntityService.notifyAssignOrUnassignEntityToCustomer(tenantId, dashboardId, publicCustomer.getId(), savedDashboard, notificationEntityService.logEntityAction(tenantId, dashboardId, savedDashboard, publicCustomer.getId(),
actionType, user, dashboardId.toString(), actionType, user, dashboardId.toString(), publicCustomer.getId().toString(), publicCustomer.getName());
publicCustomer.getId().toString(), publicCustomer.getName());
return savedDashboard; return savedDashboard;
} catch (Exception e) { } catch (Exception e) {
notificationEntityService.logEntityAction(tenantId, emptyId(EntityType.DASHBOARD), actionType, user, e, dashboardId.toString()); notificationEntityService.logEntityAction(tenantId, emptyId(EntityType.DASHBOARD), actionType, user, e, dashboardId.toString());
@ -119,9 +116,8 @@ public class DefaultTbDashboardService extends AbstractTbEntityService implement
try { try {
Customer publicCustomer = customerService.findOrCreatePublicCustomer(tenantId); Customer publicCustomer = customerService.findOrCreatePublicCustomer(tenantId);
Dashboard savedDashboard = checkNotNull(dashboardService.unassignDashboardFromCustomer(tenantId, dashboardId, publicCustomer.getId())); Dashboard savedDashboard = checkNotNull(dashboardService.unassignDashboardFromCustomer(tenantId, dashboardId, publicCustomer.getId()));
notificationEntityService.notifyAssignOrUnassignEntityToCustomer(tenantId, dashboardId, publicCustomer.getId(), dashboard, notificationEntityService.logEntityAction(tenantId, dashboardId, dashboard, publicCustomer.getId(), actionType,
actionType, user, dashboardId.toString(), user, dashboardId.toString(), publicCustomer.getId().toString(), publicCustomer.getName());
publicCustomer.getId().toString(), publicCustomer.getName());
return savedDashboard; return savedDashboard;
} catch (Exception e) { } catch (Exception e) {
notificationEntityService.logEntityAction(tenantId, emptyId(EntityType.DASHBOARD), actionType, user, e, dashboardId.toString()); notificationEntityService.logEntityAction(tenantId, emptyId(EntityType.DASHBOARD), actionType, user, e, dashboardId.toString());
@ -159,15 +155,15 @@ public class DefaultTbDashboardService extends AbstractTbEntityService implement
for (CustomerId customerId : addedCustomerIds) { for (CustomerId customerId : addedCustomerIds) {
savedDashboard = checkNotNull(dashboardService.assignDashboardToCustomer(tenantId, dashboardId, customerId)); savedDashboard = checkNotNull(dashboardService.assignDashboardToCustomer(tenantId, dashboardId, customerId));
ShortCustomerInfo customerInfo = savedDashboard.getAssignedCustomerInfo(customerId); ShortCustomerInfo customerInfo = savedDashboard.getAssignedCustomerInfo(customerId);
notificationEntityService.notifyAssignOrUnassignEntityToCustomer(tenantId, savedDashboard.getId(), customerId, savedDashboard, notificationEntityService.logEntityAction(tenantId, savedDashboard.getId(), savedDashboard, customerId,
actionType, user, dashboardId.toString(), customerId.toString(), customerInfo.getTitle()); actionType, user, dashboardId.toString(), customerId.toString(), customerInfo.getTitle());
} }
actionType = ActionType.UNASSIGNED_FROM_CUSTOMER; actionType = ActionType.UNASSIGNED_FROM_CUSTOMER;
for (CustomerId customerId : removedCustomerIds) { for (CustomerId customerId : removedCustomerIds) {
ShortCustomerInfo customerInfo = dashboard.getAssignedCustomerInfo(customerId); ShortCustomerInfo customerInfo = dashboard.getAssignedCustomerInfo(customerId);
savedDashboard = checkNotNull(dashboardService.unassignDashboardFromCustomer(tenantId, dashboardId, customerId)); savedDashboard = checkNotNull(dashboardService.unassignDashboardFromCustomer(tenantId, dashboardId, customerId));
notificationEntityService.notifyAssignOrUnassignEntityToCustomer(tenantId, savedDashboard.getId(), customerId, savedDashboard, notificationEntityService.logEntityAction(tenantId, savedDashboard.getId(), savedDashboard, customerId,
ActionType.UNASSIGNED_FROM_CUSTOMER, user, dashboardId.toString(), customerId.toString(), customerInfo.getTitle()); actionType, user, dashboardId.toString(), customerId.toString(), customerInfo.getTitle());
} }
return savedDashboard; return savedDashboard;
} }
@ -196,7 +192,7 @@ public class DefaultTbDashboardService extends AbstractTbEntityService implement
for (CustomerId customerId : addedCustomerIds) { for (CustomerId customerId : addedCustomerIds) {
savedDashboard = checkNotNull(dashboardService.assignDashboardToCustomer(tenantId, dashboardId, customerId)); savedDashboard = checkNotNull(dashboardService.assignDashboardToCustomer(tenantId, dashboardId, customerId));
ShortCustomerInfo customerInfo = savedDashboard.getAssignedCustomerInfo(customerId); ShortCustomerInfo customerInfo = savedDashboard.getAssignedCustomerInfo(customerId);
notificationEntityService.notifyAssignOrUnassignEntityToCustomer(tenantId, dashboardId, customerId, savedDashboard, notificationEntityService.logEntityAction(tenantId, dashboardId, savedDashboard, customerId,
actionType, user, dashboardId.toString(), customerId.toString(), customerInfo.getTitle()); actionType, user, dashboardId.toString(), customerId.toString(), customerInfo.getTitle());
} }
return savedDashboard; return savedDashboard;
@ -226,7 +222,7 @@ public class DefaultTbDashboardService extends AbstractTbEntityService implement
for (CustomerId customerId : removedCustomerIds) { for (CustomerId customerId : removedCustomerIds) {
ShortCustomerInfo customerInfo = dashboard.getAssignedCustomerInfo(customerId); ShortCustomerInfo customerInfo = dashboard.getAssignedCustomerInfo(customerId);
savedDashboard = checkNotNull(dashboardService.unassignDashboardFromCustomer(tenantId, dashboardId, customerId)); savedDashboard = checkNotNull(dashboardService.unassignDashboardFromCustomer(tenantId, dashboardId, customerId));
notificationEntityService.notifyAssignOrUnassignEntityToCustomer(tenantId, dashboardId, customerId, savedDashboard, notificationEntityService.logEntityAction(tenantId, dashboardId, savedDashboard, customerId,
actionType, user, dashboardId.toString(), customerId.toString(), customerInfo.getTitle()); actionType, user, dashboardId.toString(), customerId.toString(), customerInfo.getTitle());
} }
return savedDashboard; return savedDashboard;
@ -243,9 +239,8 @@ public class DefaultTbDashboardService extends AbstractTbEntityService implement
EdgeId edgeId = edge.getId(); EdgeId edgeId = edge.getId();
try { try {
Dashboard savedDashboard = checkNotNull(dashboardService.assignDashboardToEdge(tenantId, dashboardId, edgeId)); Dashboard savedDashboard = checkNotNull(dashboardService.assignDashboardToEdge(tenantId, dashboardId, edgeId));
notificationEntityService.notifyAssignOrUnassignEntityToEdge(tenantId, dashboardId, null, notificationEntityService.logEntityAction(tenantId, dashboardId, savedDashboard, null, actionType,
edgeId, savedDashboard, actionType, user, dashboardId.toString(), user, dashboardId.toString(), edgeId.toString(), edge.getName());
edgeId.toString(), edge.getName());
return savedDashboard; return savedDashboard;
} catch (Exception e) { } catch (Exception e) {
notificationEntityService.logEntityAction(tenantId, emptyId(EntityType.DEVICE), notificationEntityService.logEntityAction(tenantId, emptyId(EntityType.DEVICE),
@ -262,10 +257,8 @@ public class DefaultTbDashboardService extends AbstractTbEntityService implement
EdgeId edgeId = edge.getId(); EdgeId edgeId = edge.getId();
try { try {
Dashboard savedDevice = checkNotNull(dashboardService.unassignDashboardFromEdge(tenantId, dashboardId, edgeId)); Dashboard savedDevice = checkNotNull(dashboardService.unassignDashboardFromEdge(tenantId, dashboardId, edgeId));
notificationEntityService.logEntityAction(tenantId, dashboardId, dashboard, null, actionType,
notificationEntityService.notifyAssignOrUnassignEntityToEdge(tenantId, dashboardId, null, user, dashboardId.toString(), edgeId.toString(), edge.getName());
edgeId, dashboard, actionType, user, dashboardId.toString(),
edgeId.toString(), edge.getName());
return savedDevice; return savedDevice;
} catch (Exception e) { } catch (Exception e) {
notificationEntityService.logEntityAction(tenantId, emptyId(EntityType.DASHBOARD), actionType, user, e, notificationEntityService.logEntityAction(tenantId, emptyId(EntityType.DASHBOARD), actionType, user, e,
@ -281,7 +274,7 @@ public class DefaultTbDashboardService extends AbstractTbEntityService implement
DashboardId dashboardId = dashboard.getId(); DashboardId dashboardId = dashboard.getId();
try { try {
Dashboard savedDashboard = checkNotNull(dashboardService.unassignDashboardFromCustomer(tenantId, dashboardId, customer.getId())); Dashboard savedDashboard = checkNotNull(dashboardService.unassignDashboardFromCustomer(tenantId, dashboardId, customer.getId()));
notificationEntityService.notifyAssignOrUnassignEntityToCustomer(tenantId, dashboardId, customer.getId(), savedDashboard, notificationEntityService.logEntityAction(tenantId, dashboardId, savedDashboard, customer.getId(),
actionType, user, dashboardId.toString(), customer.getId().toString(), customer.getName()); actionType, user, dashboardId.toString(), customer.getId().toString(), customer.getName());
return savedDashboard; return savedDashboard;
} catch (Exception e) { } catch (Exception e) {

32
application/src/main/java/org/thingsboard/server/service/entitiy/device/DefaultTbDeviceService.java

@ -44,8 +44,6 @@ import org.thingsboard.server.dao.tenant.TenantService;
import org.thingsboard.server.queue.util.TbCoreComponent; import org.thingsboard.server.queue.util.TbCoreComponent;
import org.thingsboard.server.service.entitiy.AbstractTbEntityService; import org.thingsboard.server.service.entitiy.AbstractTbEntityService;
import java.util.List;
@AllArgsConstructor @AllArgsConstructor
@TbCoreComponent @TbCoreComponent
@Service @Service
@ -97,10 +95,9 @@ public class DefaultTbDeviceService extends AbstractTbEntityService implements T
TenantId tenantId = device.getTenantId(); TenantId tenantId = device.getTenantId();
DeviceId deviceId = device.getId(); DeviceId deviceId = device.getId();
try { try {
List<EdgeId> relatedEdgeIds = edgeService.findAllRelatedEdgeIds(tenantId, deviceId);
deviceService.deleteDevice(tenantId, deviceId); deviceService.deleteDevice(tenantId, deviceId);
notificationEntityService.notifyDeleteDevice(tenantId, deviceId, device.getCustomerId(), device, notificationEntityService.notifyDeleteDevice(tenantId, deviceId, device.getCustomerId(), device,
relatedEdgeIds, user, deviceId.toString()); user, deviceId.toString());
return removeAlarmsByEntityId(tenantId, deviceId); return removeAlarmsByEntityId(tenantId, deviceId);
} catch (Exception e) { } catch (Exception e) {
@ -116,8 +113,8 @@ public class DefaultTbDeviceService extends AbstractTbEntityService implements T
CustomerId customerId = customer.getId(); CustomerId customerId = customer.getId();
try { try {
Device savedDevice = checkNotNull(deviceService.assignDeviceToCustomer(tenantId, deviceId, customerId)); Device savedDevice = checkNotNull(deviceService.assignDeviceToCustomer(tenantId, deviceId, customerId));
notificationEntityService.notifyAssignOrUnassignEntityToCustomer(tenantId, deviceId, customerId, savedDevice, notificationEntityService.logEntityAction(tenantId, deviceId, savedDevice, customerId, actionType, user,
actionType, user, deviceId.toString(), customerId.toString(), customer.getName()); deviceId.toString(), customerId.toString(), customer.getName());
return savedDevice; return savedDevice;
} catch (Exception e) { } catch (Exception e) {
@ -136,8 +133,8 @@ public class DefaultTbDeviceService extends AbstractTbEntityService implements T
Device savedDevice = checkNotNull(deviceService.unassignDeviceFromCustomer(tenantId, deviceId)); Device savedDevice = checkNotNull(deviceService.unassignDeviceFromCustomer(tenantId, deviceId));
CustomerId customerId = customer.getId(); CustomerId customerId = customer.getId();
notificationEntityService.notifyAssignOrUnassignEntityToCustomer(tenantId, deviceId, customerId, savedDevice, notificationEntityService.logEntityAction(tenantId, deviceId, savedDevice, customerId, actionType, user,
actionType, user, deviceId.toString(), customerId.toString(), customer.getName()); deviceId.toString(), customerId.toString(), customer.getName());
return savedDevice; return savedDevice;
} catch (Exception e) { } catch (Exception e) {
@ -154,9 +151,8 @@ public class DefaultTbDeviceService extends AbstractTbEntityService implements T
try { try {
Device savedDevice = checkNotNull(deviceService.assignDeviceToCustomer(tenantId, deviceId, publicCustomer.getId())); Device savedDevice = checkNotNull(deviceService.assignDeviceToCustomer(tenantId, deviceId, publicCustomer.getId()));
notificationEntityService.notifyAssignOrUnassignEntityToCustomer(tenantId, deviceId, savedDevice.getCustomerId(), savedDevice, notificationEntityService.logEntityAction(tenantId, deviceId, savedDevice, savedDevice.getCustomerId(),
actionType, user, deviceId.toString(), actionType, user, deviceId.toString(), publicCustomer.getId().toString(), publicCustomer.getName());
publicCustomer.getId().toString(), publicCustomer.getName());
return savedDevice; return savedDevice;
} catch (Exception e) { } catch (Exception e) {
@ -252,30 +248,32 @@ public class DefaultTbDeviceService extends AbstractTbEntityService implements T
EdgeId edgeId = edge.getId(); EdgeId edgeId = edge.getId();
try { try {
Device savedDevice = checkNotNull(deviceService.assignDeviceToEdge(tenantId, deviceId, edgeId)); Device savedDevice = checkNotNull(deviceService.assignDeviceToEdge(tenantId, deviceId, edgeId));
notificationEntityService.notifyAssignOrUnassignEntityToEdge(tenantId, deviceId, savedDevice.getCustomerId(), notificationEntityService.logEntityAction(tenantId, deviceId, savedDevice, savedDevice.getCustomerId(),
edgeId, savedDevice, actionType, user, deviceId.toString(), edgeId.toString(), edge.getName()); actionType, user, deviceId.toString(), edgeId.toString(), edge.getName());
return savedDevice; return savedDevice;
} catch (Exception e) { } catch (Exception e) {
notificationEntityService.logEntityAction(tenantId, emptyId(EntityType.DEVICE), notificationEntityService.logEntityAction(tenantId, emptyId(EntityType.DEVICE),
ActionType.ASSIGNED_TO_EDGE, user, e, deviceId.toString(), edgeId.toString()); actionType, user, e, deviceId.toString(), edgeId.toString());
throw e; throw e;
} }
} }
@Override @Override
public Device unassignDeviceFromEdge(Device device, Edge edge, User user) throws ThingsboardException { public Device unassignDeviceFromEdge(Device device, Edge edge, User user) throws ThingsboardException {
ActionType actionType = ActionType.UNASSIGNED_FROM_EDGE;
TenantId tenantId = device.getTenantId(); TenantId tenantId = device.getTenantId();
DeviceId deviceId = device.getId(); DeviceId deviceId = device.getId();
EdgeId edgeId = edge.getId(); EdgeId edgeId = edge.getId();
try { try {
Device savedDevice = checkNotNull(deviceService.unassignDeviceFromEdge(tenantId, deviceId, edgeId)); Device savedDevice = checkNotNull(deviceService.unassignDeviceFromEdge(tenantId, deviceId, edgeId));
notificationEntityService.logEntityAction(tenantId, deviceId, savedDevice, savedDevice.getCustomerId(),
actionType, user, deviceId.toString(), edgeId.toString(), edge.getName());
notificationEntityService.notifyAssignOrUnassignEntityToEdge(tenantId, deviceId, device.getCustomerId(),
edgeId, device, ActionType.UNASSIGNED_FROM_EDGE, user, deviceId.toString(), edgeId.toString(), edge.getName());
return savedDevice; return savedDevice;
} catch (Exception e) { } catch (Exception e) {
notificationEntityService.logEntityAction(tenantId, emptyId(EntityType.DEVICE), notificationEntityService.logEntityAction(tenantId, emptyId(EntityType.DEVICE),
ActionType.UNASSIGNED_FROM_EDGE, user, e, deviceId.toString(), edgeId.toString()); actionType, user, e, deviceId.toString(), edgeId.toString());
throw e; throw e;
} }
} }

11
application/src/main/java/org/thingsboard/server/service/entitiy/device/profile/DefaultTbDeviceProfileService.java

@ -67,8 +67,8 @@ public class DefaultTbDeviceProfileService extends AbstractTbEntityService imple
otaPackageStateService.update(savedDeviceProfile, isFirmwareChanged, isSoftwareChanged); otaPackageStateService.update(savedDeviceProfile, isFirmwareChanged, isSoftwareChanged);
notificationEntityService.notifyCreateOrUpdateOrDelete(tenantId, null, savedDeviceProfile.getId(), notificationEntityService.logEntityAction(tenantId, savedDeviceProfile.getId(), savedDeviceProfile,
savedDeviceProfile, user, actionType, true, null); null, actionType, user);
return savedDeviceProfile; return savedDeviceProfile;
} catch (Exception e) { } catch (Exception e) {
notificationEntityService.logEntityAction(tenantId, emptyId(EntityType.DEVICE_PROFILE), deviceProfile, actionType, user, e); notificationEntityService.logEntityAction(tenantId, emptyId(EntityType.DEVICE_PROFILE), deviceProfile, actionType, user, e);
@ -78,6 +78,7 @@ public class DefaultTbDeviceProfileService extends AbstractTbEntityService imple
@Override @Override
public void delete(DeviceProfile deviceProfile, User user) { public void delete(DeviceProfile deviceProfile, User user) {
ActionType actionType = ActionType.DELETED;
DeviceProfileId deviceProfileId = deviceProfile.getId(); DeviceProfileId deviceProfileId = deviceProfile.getId();
TenantId tenantId = deviceProfile.getTenantId(); TenantId tenantId = deviceProfile.getTenantId();
try { try {
@ -85,10 +86,10 @@ public class DefaultTbDeviceProfileService extends AbstractTbEntityService imple
tbClusterService.onDeviceProfileDelete(deviceProfile, null); tbClusterService.onDeviceProfileDelete(deviceProfile, null);
tbClusterService.broadcastEntityStateChangeEvent(tenantId, deviceProfileId, ComponentLifecycleEvent.DELETED); tbClusterService.broadcastEntityStateChangeEvent(tenantId, deviceProfileId, ComponentLifecycleEvent.DELETED);
notificationEntityService.notifyCreateOrUpdateOrDelete(tenantId, null, deviceProfileId, deviceProfile, notificationEntityService.logEntityAction(tenantId, deviceProfileId, deviceProfile, null,
user, ActionType.DELETED, true, null, deviceProfileId.toString()); actionType, user, deviceProfileId.toString());
} catch (Exception e) { } catch (Exception e) {
notificationEntityService.logEntityAction(tenantId, emptyId(EntityType.DEVICE_PROFILE), ActionType.DELETED, notificationEntityService.logEntityAction(tenantId, emptyId(EntityType.DEVICE_PROFILE), actionType,
user, e, deviceProfileId.toString()); user, e, deviceProfileId.toString());
throw e; throw e;
} }

8
application/src/main/java/org/thingsboard/server/service/entitiy/edge/DefaultTbEdgeService.java

@ -89,8 +89,8 @@ public class DefaultTbEdgeService extends AbstractTbEntityService implements TbE
CustomerId customerId = customer.getId(); CustomerId customerId = customer.getId();
try { try {
Edge savedEdge = checkNotNull(edgeService.assignEdgeToCustomer(tenantId, edgeId, customerId)); Edge savedEdge = checkNotNull(edgeService.assignEdgeToCustomer(tenantId, edgeId, customerId));
notificationEntityService.notifyAssignOrUnassignEntityToCustomer(tenantId, edgeId, customerId, savedEdge, notificationEntityService.logEntityAction(tenantId, edgeId, savedEdge, customerId, actionType,
actionType, user, edgeId.toString(), customerId.toString(), customer.getName()); user, edgeId.toString(), customerId.toString(), customer.getName());
return savedEdge; return savedEdge;
} catch (Exception e) { } catch (Exception e) {
@ -108,8 +108,8 @@ public class DefaultTbEdgeService extends AbstractTbEntityService implements TbE
CustomerId customerId = customer.getId(); CustomerId customerId = customer.getId();
try { try {
Edge savedEdge = checkNotNull(edgeService.unassignEdgeFromCustomer(tenantId, edgeId)); Edge savedEdge = checkNotNull(edgeService.unassignEdgeFromCustomer(tenantId, edgeId));
notificationEntityService.notifyAssignOrUnassignEntityToCustomer(tenantId, edgeId, customerId, savedEdge, notificationEntityService.logEntityAction(tenantId, edgeId, savedEdge, customerId, actionType,
actionType, user, edgeId.toString(), customerId.toString(), customer.getName()); user, edgeId.toString(), customerId.toString(), customer.getName());
return savedEdge; return savedEdge;
} catch (Exception e) { } catch (Exception e) {
notificationEntityService.logEntityAction(tenantId, emptyId(EntityType.EDGE), notificationEntityService.logEntityAction(tenantId, emptyId(EntityType.EDGE),

21
application/src/main/java/org/thingsboard/server/service/entitiy/entity/relation/DefaultTbEntityRelationService.java

@ -40,33 +40,30 @@ public class DefaultTbEntityRelationService extends AbstractTbEntityService impl
@Override @Override
public void save(TenantId tenantId, CustomerId customerId, EntityRelation relation, User user) throws ThingsboardException { public void save(TenantId tenantId, CustomerId customerId, EntityRelation relation, User user) throws ThingsboardException {
ActionType actionType = ActionType.RELATION_ADD_OR_UPDATE;
try { try {
relationService.saveRelation(tenantId, relation); relationService.saveRelation(tenantId, relation);
notificationEntityService.notifyRelation(tenantId, customerId, notificationEntityService.logEntityRelationAction(tenantId, customerId,
relation, user, ActionType.RELATION_ADD_OR_UPDATE, relation); relation, user, actionType, null, relation);
} catch (Exception e) { } catch (Exception e) {
notificationEntityService.logEntityAction(tenantId, relation.getFrom(), null, customerId, notificationEntityService.logEntityRelationAction(tenantId, customerId,
ActionType.RELATION_ADD_OR_UPDATE, user, e, relation); relation, user, actionType, e, relation);
notificationEntityService.logEntityAction(tenantId, relation.getTo(), null, customerId,
ActionType.RELATION_ADD_OR_UPDATE, user, e, relation);
throw e; throw e;
} }
} }
@Override @Override
public void delete(TenantId tenantId, CustomerId customerId, EntityRelation relation, User user) throws ThingsboardException { public void delete(TenantId tenantId, CustomerId customerId, EntityRelation relation, User user) throws ThingsboardException {
ActionType actionType = ActionType.RELATION_DELETED;
try { try {
boolean found = relationService.deleteRelation(tenantId, relation.getFrom(), relation.getTo(), relation.getType(), relation.getTypeGroup()); boolean found = relationService.deleteRelation(tenantId, relation.getFrom(), relation.getTo(), relation.getType(), relation.getTypeGroup());
if (!found) { if (!found) {
throw new ThingsboardException("Requested item wasn't found!", ThingsboardErrorCode.ITEM_NOT_FOUND); throw new ThingsboardException("Requested item wasn't found!", ThingsboardErrorCode.ITEM_NOT_FOUND);
} }
notificationEntityService.notifyRelation(tenantId, customerId, notificationEntityService.logEntityRelationAction(tenantId, customerId, relation, user, actionType, null, relation);
relation, user, ActionType.RELATION_DELETED, relation);
} catch (Exception e) { } catch (Exception e) {
notificationEntityService.logEntityAction(tenantId, relation.getFrom(), null, customerId, notificationEntityService.logEntityRelationAction(tenantId, customerId,
ActionType.RELATION_DELETED, user, e, relation); relation, user, actionType, e, relation);
notificationEntityService.logEntityAction(tenantId, relation.getTo(), null, customerId,
ActionType.RELATION_DELETED, user, e, relation);
throw e; throw e;
} }
} }

67
application/src/main/java/org/thingsboard/server/service/entitiy/entityview/DefaultTbEntityViewService.java

@ -81,7 +81,7 @@ public class DefaultTbEntityViewService extends AbstractTbEntityService implemen
EntityView savedEntityView = checkNotNull(entityViewService.saveEntityView(entityView)); EntityView savedEntityView = checkNotNull(entityViewService.saveEntityView(entityView));
this.updateEntityViewAttributes(tenantId, savedEntityView, existingEntityView, user); this.updateEntityViewAttributes(tenantId, savedEntityView, existingEntityView, user);
autoCommit(user, savedEntityView.getId()); autoCommit(user, savedEntityView.getId());
notificationEntityService.notifyCreateOrUpdateEntity(savedEntityView.getTenantId(), savedEntityView.getId(), savedEntityView, notificationEntityService.logEntityAction(savedEntityView.getTenantId(), savedEntityView.getId(), savedEntityView,
null, actionType, user); null, actionType, user);
localCache.computeIfAbsent(savedEntityView.getTenantId(), (k) -> new ConcurrentReferenceHashMap<>()).clear(); localCache.computeIfAbsent(savedEntityView.getTenantId(), (k) -> new ConcurrentReferenceHashMap<>()).clear();
tbClusterService.broadcastEntityStateChangeEvent(savedEntityView.getTenantId(), savedEntityView.getId(), tbClusterService.broadcastEntityStateChangeEvent(savedEntityView.getTenantId(), savedEntityView.getId(),
@ -129,10 +129,9 @@ public class DefaultTbEntityViewService extends AbstractTbEntityService implemen
TenantId tenantId = entityView.getTenantId(); TenantId tenantId = entityView.getTenantId();
EntityViewId entityViewId = entityView.getId(); EntityViewId entityViewId = entityView.getId();
try { try {
List<EdgeId> relatedEdgeIds = edgeService.findAllRelatedEdgeIds(tenantId, entityViewId);
entityViewService.deleteEntityView(tenantId, entityViewId); entityViewService.deleteEntityView(tenantId, entityViewId);
notificationEntityService.notifyDeleteEntity(tenantId, entityViewId, entityView, entityView.getCustomerId(), ActionType.DELETED, notificationEntityService.logEntityAction(tenantId, entityViewId, entityView, entityView.getCustomerId(),
relatedEdgeIds, user, entityViewId.toString()); ActionType.DELETED, user, entityViewId.toString());
localCache.computeIfAbsent(tenantId, (k) -> new ConcurrentReferenceHashMap<>()).clear(); localCache.computeIfAbsent(tenantId, (k) -> new ConcurrentReferenceHashMap<>()).clear();
tbClusterService.broadcastEntityStateChangeEvent(tenantId, entityViewId, ComponentLifecycleEvent.DELETED); tbClusterService.broadcastEntityStateChangeEvent(tenantId, entityViewId, ComponentLifecycleEvent.DELETED);
@ -145,15 +144,31 @@ public class DefaultTbEntityViewService extends AbstractTbEntityService implemen
@Override @Override
public EntityView assignEntityViewToCustomer(TenantId tenantId, EntityViewId entityViewId, Customer customer, User user) throws ThingsboardException { public EntityView assignEntityViewToCustomer(TenantId tenantId, EntityViewId entityViewId, Customer customer, User user) throws ThingsboardException {
ActionType actionType = ActionType.ASSIGNED_TO_CUSTOMER;
CustomerId customerId = customer.getId(); CustomerId customerId = customer.getId();
try { try {
EntityView savedEntityView = checkNotNull(entityViewService.assignEntityViewToCustomer(tenantId, entityViewId, customerId)); EntityView savedEntityView = checkNotNull(entityViewService.assignEntityViewToCustomer(tenantId, entityViewId, customerId));
notificationEntityService.notifyAssignOrUnassignEntityToCustomer(tenantId, entityViewId, customerId, savedEntityView, notificationEntityService.logEntityAction(tenantId, entityViewId, savedEntityView, savedEntityView.getCustomerId(),
ActionType.ASSIGNED_TO_CUSTOMER, user, entityViewId.toString(), customerId.toString(), customer.getName()); actionType, user, entityViewId.toString(), customerId.toString(), customer.getName());
return savedEntityView;
} catch (Exception e) {
notificationEntityService.logEntityAction(tenantId, emptyId(EntityType.ENTITY_VIEW),
actionType, user, e, entityViewId.toString(), customerId.toString());
throw e;
}
}
@Override
public EntityView unassignEntityViewFromCustomer(TenantId tenantId, EntityViewId entityViewId, Customer customer, User user) throws ThingsboardException {
ActionType actionType = ActionType.UNASSIGNED_FROM_CUSTOMER;
try {
EntityView savedEntityView = checkNotNull(entityViewService.unassignEntityViewFromCustomer(tenantId, entityViewId));
notificationEntityService.logEntityAction(tenantId, entityViewId, savedEntityView, customer.getId(),
actionType, user, savedEntityView.getId().toString(), customer.getId().toString(), customer.getName());
return savedEntityView; return savedEntityView;
} catch (Exception e) { } catch (Exception e) {
notificationEntityService.logEntityAction(tenantId, emptyId(EntityType.ENTITY_VIEW), notificationEntityService.logEntityAction(tenantId, emptyId(EntityType.ENTITY_VIEW),
ActionType.ASSIGNED_TO_CUSTOMER, user, e, entityViewId.toString(), customerId.toString()); actionType, user, e, entityViewId.toString());
throw e; throw e;
} }
} }
@ -165,9 +180,8 @@ public class DefaultTbEntityViewService extends AbstractTbEntityService implemen
try { try {
EntityView savedEntityView = checkNotNull(entityViewService.assignEntityViewToCustomer(tenantId, EntityView savedEntityView = checkNotNull(entityViewService.assignEntityViewToCustomer(tenantId,
entityViewId, publicCustomer.getId())); entityViewId, publicCustomer.getId()));
notificationEntityService.notifyAssignOrUnassignEntityToCustomer(tenantId, entityViewId, savedEntityView.getCustomerId(), savedEntityView, notificationEntityService.logEntityAction(tenantId, entityViewId, savedEntityView, savedEntityView.getCustomerId(),
actionType, user, savedEntityView.getId().toString(), actionType, user, savedEntityView.getId().toString(), publicCustomer.getId().toString(), publicCustomer.getName());
publicCustomer.getId().toString(), publicCustomer.getName());
return savedEntityView; return savedEntityView;
} catch (Exception e) { } catch (Exception e) {
notificationEntityService.logEntityAction(tenantId, emptyId(EntityType.ENTITY_VIEW), notificationEntityService.logEntityAction(tenantId, emptyId(EntityType.ENTITY_VIEW),
@ -178,16 +192,16 @@ public class DefaultTbEntityViewService extends AbstractTbEntityService implemen
@Override @Override
public EntityView assignEntityViewToEdge(TenantId tenantId, CustomerId customerId, EntityViewId entityViewId, Edge edge, User user) throws ThingsboardException { public EntityView assignEntityViewToEdge(TenantId tenantId, CustomerId customerId, EntityViewId entityViewId, Edge edge, User user) throws ThingsboardException {
ActionType actionType = ActionType.ASSIGNED_TO_EDGE;
EdgeId edgeId = edge.getId(); EdgeId edgeId = edge.getId();
try { try {
EntityView savedEntityView = checkNotNull(entityViewService.assignEntityViewToEdge(tenantId, entityViewId, edgeId)); EntityView savedEntityView = checkNotNull(entityViewService.assignEntityViewToEdge(tenantId, entityViewId, edgeId));
notificationEntityService.notifyAssignOrUnassignEntityToEdge(tenantId, entityViewId, customerId, notificationEntityService.logEntityAction(tenantId, entityViewId, savedEntityView, customerId, actionType,
edgeId, savedEntityView, ActionType.ASSIGNED_TO_EDGE, user, savedEntityView.getEntityId().toString(), user, savedEntityView.getEntityId().toString(), edgeId.toString(), edge.getName());
edgeId.toString(), edge.getName());
return savedEntityView; return savedEntityView;
} catch (Exception e) { } catch (Exception e) {
notificationEntityService.logEntityAction(tenantId, emptyId(EntityType.ENTITY_VIEW), notificationEntityService.logEntityAction(tenantId, emptyId(EntityType.ENTITY_VIEW),
ActionType.ASSIGNED_TO_EDGE, user, e, entityViewId.toString(), edgeId.toString()); actionType, user, e, entityViewId.toString(), edgeId.toString());
throw e; throw e;
} }
} }
@ -195,34 +209,17 @@ public class DefaultTbEntityViewService extends AbstractTbEntityService implemen
@Override @Override
public EntityView unassignEntityViewFromEdge(TenantId tenantId, CustomerId customerId, EntityView entityView, public EntityView unassignEntityViewFromEdge(TenantId tenantId, CustomerId customerId, EntityView entityView,
Edge edge, User user) throws ThingsboardException { Edge edge, User user) throws ThingsboardException {
ActionType actionType = ActionType.UNASSIGNED_FROM_EDGE;
EntityViewId entityViewId = entityView.getId(); EntityViewId entityViewId = entityView.getId();
EdgeId edgeId = edge.getId(); EdgeId edgeId = edge.getId();
try { try {
EntityView savedEntityView = checkNotNull(entityViewService.unassignEntityViewFromEdge(tenantId, entityViewId, edgeId)); EntityView savedEntityView = checkNotNull(entityViewService.unassignEntityViewFromEdge(tenantId, entityViewId, edgeId));
notificationEntityService.notifyAssignOrUnassignEntityToEdge(tenantId, entityViewId, customerId, notificationEntityService.logEntityAction(tenantId, entityViewId, savedEntityView, customerId, actionType,
edgeId, entityView, ActionType.UNASSIGNED_FROM_EDGE, user, entityViewId.toString(), user, entityViewId.toString(), edgeId.toString(), edge.getName());
edgeId.toString(), edge.getName());
return savedEntityView; return savedEntityView;
} catch (Exception e) { } catch (Exception e) {
notificationEntityService.logEntityAction(tenantId, emptyId(EntityType.ENTITY_VIEW), notificationEntityService.logEntityAction(tenantId, emptyId(EntityType.ENTITY_VIEW),
ActionType.UNASSIGNED_FROM_EDGE, user, e, entityViewId.toString(), edgeId.toString()); actionType, user, e, entityViewId.toString(), edgeId.toString());
throw e;
}
}
@Override
public EntityView unassignEntityViewFromCustomer(TenantId tenantId, EntityViewId entityViewId, Customer customer, User user) throws ThingsboardException {
ActionType actionType = ActionType.UNASSIGNED_FROM_CUSTOMER;
try {
EntityView savedEntityView = checkNotNull(entityViewService.unassignEntityViewFromCustomer(tenantId, entityViewId));
notificationEntityService.notifyAssignOrUnassignEntityToCustomer(tenantId, entityViewId, customer.getId(), savedEntityView,
actionType, user, savedEntityView.getId().toString(), customer.getId().toString(), customer.getName());
return savedEntityView;
} catch (Exception e) {
notificationEntityService.logEntityAction(tenantId, emptyId(EntityType.ENTITY_VIEW),
actionType, user, e, entityViewId.toString());
throw e; throw e;
} }
} }

19
application/src/main/java/org/thingsboard/server/service/entitiy/ota/DefaultTbOtaPackageService.java

@ -50,9 +50,8 @@ public class DefaultTbOtaPackageService extends AbstractTbEntityService implemen
try { try {
OtaPackageInfo savedOtaPackageInfo = otaPackageService.saveOtaPackageInfo(new OtaPackageInfo(saveOtaPackageInfoRequest), saveOtaPackageInfoRequest.isUsesUrl()); OtaPackageInfo savedOtaPackageInfo = otaPackageService.saveOtaPackageInfo(new OtaPackageInfo(saveOtaPackageInfoRequest), saveOtaPackageInfoRequest.isUsesUrl());
boolean sendMsgToEdge = savedOtaPackageInfo.hasUrl() || savedOtaPackageInfo.isHasData(); notificationEntityService.logEntityAction(tenantId, savedOtaPackageInfo.getId(), savedOtaPackageInfo,
notificationEntityService.notifyCreateOrUpdateOrDelete(tenantId, null, savedOtaPackageInfo.getId(), null, actionType, user);
savedOtaPackageInfo, user, actionType, sendMsgToEdge, null);
return savedOtaPackageInfo; return savedOtaPackageInfo;
} catch (Exception e) { } catch (Exception e) {
@ -65,6 +64,7 @@ public class DefaultTbOtaPackageService extends AbstractTbEntityService implemen
@Override @Override
public OtaPackageInfo saveOtaPackageData(OtaPackageInfo otaPackageInfo, String checksum, ChecksumAlgorithm checksumAlgorithm, public OtaPackageInfo saveOtaPackageData(OtaPackageInfo otaPackageInfo, String checksum, ChecksumAlgorithm checksumAlgorithm,
byte[] data, String filename, String contentType, User user) throws ThingsboardException { byte[] data, String filename, String contentType, User user) throws ThingsboardException {
ActionType actionType = ActionType.UPDATED;
TenantId tenantId = otaPackageInfo.getTenantId(); TenantId tenantId = otaPackageInfo.getTenantId();
OtaPackageId otaPackageId = otaPackageInfo.getId(); OtaPackageId otaPackageId = otaPackageInfo.getId();
try { try {
@ -87,27 +87,26 @@ public class DefaultTbOtaPackageService extends AbstractTbEntityService implemen
otaPackage.setData(ByteBuffer.wrap(data)); otaPackage.setData(ByteBuffer.wrap(data));
otaPackage.setDataSize((long) data.length); otaPackage.setDataSize((long) data.length);
OtaPackageInfo savedOtaPackage = otaPackageService.saveOtaPackage(otaPackage); OtaPackageInfo savedOtaPackage = otaPackageService.saveOtaPackage(otaPackage);
notificationEntityService.notifyCreateOrUpdateOrDelete(tenantId, null, savedOtaPackage.getId(), notificationEntityService.logEntityAction(tenantId, savedOtaPackage.getId(), savedOtaPackage, null, actionType, user);
savedOtaPackage, user, ActionType.UPDATED, true, null);
return savedOtaPackage; return savedOtaPackage;
} catch (Exception e) { } catch (Exception e) {
notificationEntityService.logEntityAction(tenantId, emptyId(EntityType.OTA_PACKAGE), ActionType.UPDATED, notificationEntityService.logEntityAction(tenantId, emptyId(EntityType.OTA_PACKAGE), actionType, user, e, otaPackageId.toString());
user, e, otaPackageId.toString());
throw e; throw e;
} }
} }
@Override @Override
public void delete(OtaPackageInfo otaPackageInfo, User user) throws ThingsboardException { public void delete(OtaPackageInfo otaPackageInfo, User user) throws ThingsboardException {
ActionType actionType = ActionType.DELETED;
TenantId tenantId = otaPackageInfo.getTenantId(); TenantId tenantId = otaPackageInfo.getTenantId();
OtaPackageId otaPackageId = otaPackageInfo.getId(); OtaPackageId otaPackageId = otaPackageInfo.getId();
try { try {
otaPackageService.deleteOtaPackage(tenantId, otaPackageId); otaPackageService.deleteOtaPackage(tenantId, otaPackageId);
notificationEntityService.notifyCreateOrUpdateOrDelete(tenantId, null, otaPackageId, otaPackageInfo, notificationEntityService.logEntityAction(tenantId, otaPackageId, otaPackageInfo, null,
user, ActionType.DELETED, true, null, otaPackageInfo.getId().toString()); actionType, user, otaPackageInfo.getId().toString());
} catch (Exception e) { } catch (Exception e) {
notificationEntityService.logEntityAction(tenantId, emptyId(EntityType.OTA_PACKAGE), notificationEntityService.logEntityAction(tenantId, emptyId(EntityType.OTA_PACKAGE),
ActionType.DELETED, user, e, otaPackageId.toString()); actionType, user, e, otaPackageId.toString());
throw e; throw e;
} }
} }

5
application/src/main/java/org/thingsboard/server/service/entitiy/queue/DefaultTbQueueService.java

@ -20,7 +20,6 @@ import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.thingsboard.server.cluster.TbClusterService; import org.thingsboard.server.cluster.TbClusterService;
import org.thingsboard.server.common.data.TenantProfile; import org.thingsboard.server.common.data.TenantProfile;
import org.thingsboard.server.common.data.edge.EdgeEventActionType;
import org.thingsboard.server.common.data.id.QueueId; import org.thingsboard.server.common.data.id.QueueId;
import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.common.data.id.TenantId;
import org.thingsboard.server.common.data.queue.Queue; import org.thingsboard.server.common.data.queue.Queue;
@ -71,8 +70,6 @@ public class DefaultTbQueueService extends AbstractTbEntityService implements Tb
onQueueUpdated(savedQueue, oldQueue); onQueueUpdated(savedQueue, oldQueue);
} }
notificationEntityService.notifySendMsgToEdgeService(queue.getTenantId(), savedQueue.getId(), create ? EdgeEventActionType.ADDED : EdgeEventActionType.UPDATED);
return savedQueue; return savedQueue;
} }
@ -145,8 +142,6 @@ public class DefaultTbQueueService extends AbstractTbEntityService implements Tb
} }
} }
}, DELETE_DELAY, TimeUnit.SECONDS); }, DELETE_DELAY, TimeUnit.SECONDS);
notificationEntityService.notifySendMsgToEdgeService(queue.getTenantId(), queue.getId(), EdgeEventActionType.DELETED);
} }
@Override @Override

11
application/src/main/java/org/thingsboard/server/service/entitiy/user/DefaultUserService.java

@ -54,7 +54,7 @@ public class DefaultUserService extends AbstractTbEntityService implements TbUse
ActionType actionType = tbUser.getId() == null ? ActionType.ADDED : ActionType.UPDATED; ActionType actionType = tbUser.getId() == null ? ActionType.ADDED : ActionType.UPDATED;
try { try {
boolean sendEmail = tbUser.getId() == null && sendActivationMail; boolean sendEmail = tbUser.getId() == null && sendActivationMail;
User savedUser = checkNotNull(userService.saveUser(tbUser)); User savedUser = checkNotNull(userService.saveUser(tenantId, tbUser));
if (sendEmail) { if (sendEmail) {
UserCredentials userCredentials = userService.findUserCredentialsByUserId(tenantId, savedUser.getId()); UserCredentials userCredentials = userService.findUserCredentialsByUserId(tenantId, savedUser.getId());
String baseUrl = systemSecurityService.getBaseUrl(tenantId, customerId, request); String baseUrl = systemSecurityService.getBaseUrl(tenantId, customerId, request);
@ -68,8 +68,7 @@ public class DefaultUserService extends AbstractTbEntityService implements TbUse
throw e; throw e;
} }
} }
notificationEntityService.notifyCreateOrUpdateOrDelete(tenantId, customerId, savedUser.getId(), notificationEntityService.logEntityAction(tenantId, savedUser.getId(), savedUser, customerId, actionType, user);
savedUser, user, actionType, true, null);
return savedUser; return savedUser;
} catch (Exception e) { } catch (Exception e) {
notificationEntityService.logEntityAction(tenantId, emptyId(EntityType.USER), tbUser, actionType, user, e); notificationEntityService.logEntityAction(tenantId, emptyId(EntityType.USER), tbUser, actionType, user, e);
@ -79,15 +78,15 @@ public class DefaultUserService extends AbstractTbEntityService implements TbUse
@Override @Override
public void delete(TenantId tenantId, CustomerId customerId, User tbUser, User user) throws ThingsboardException { public void delete(TenantId tenantId, CustomerId customerId, User tbUser, User user) throws ThingsboardException {
ActionType actionType = ActionType.DELETED;
UserId userId = tbUser.getId(); UserId userId = tbUser.getId();
try { try {
userService.deleteUser(tenantId, userId); userService.deleteUser(tenantId, userId);
notificationEntityService.notifyCreateOrUpdateOrDelete(tenantId, customerId, userId, tbUser, notificationEntityService.logEntityAction(tenantId, userId, tbUser, customerId, actionType, user, customerId.toString());
user, ActionType.DELETED, true, null, customerId.toString());
} catch (Exception e) { } catch (Exception e) {
notificationEntityService.logEntityAction(tenantId, emptyId(EntityType.USER), notificationEntityService.logEntityAction(tenantId, emptyId(EntityType.USER),
ActionType.DELETED, user, e, userId.toString()); actionType, user, e, userId.toString());
throw e; throw e;
} }
} }

11
application/src/main/java/org/thingsboard/server/service/entitiy/widgets/bundle/DefaultWidgetsBundleService.java

@ -40,8 +40,8 @@ public class DefaultWidgetsBundleService extends AbstractTbEntityService impleme
try { try {
WidgetsBundle savedWidgetsBundle = checkNotNull(widgetsBundleService.saveWidgetsBundle(widgetsBundle)); WidgetsBundle savedWidgetsBundle = checkNotNull(widgetsBundleService.saveWidgetsBundle(widgetsBundle));
autoCommit(user, savedWidgetsBundle.getId()); autoCommit(user, savedWidgetsBundle.getId());
notificationEntityService.notifyCreateOrUpdateOrDelete(tenantId, null, savedWidgetsBundle.getId(), notificationEntityService.logEntityAction(tenantId, savedWidgetsBundle.getId(), savedWidgetsBundle,
savedWidgetsBundle, user, actionType, true, null); null, actionType, user);
return savedWidgetsBundle; return savedWidgetsBundle;
} catch (Exception e) { } catch (Exception e) {
notificationEntityService.logEntityAction(tenantId, emptyId(EntityType.WIDGETS_BUNDLE), widgetsBundle, actionType, user, e); notificationEntityService.logEntityAction(tenantId, emptyId(EntityType.WIDGETS_BUNDLE), widgetsBundle, actionType, user, e);
@ -51,14 +51,13 @@ public class DefaultWidgetsBundleService extends AbstractTbEntityService impleme
@Override @Override
public void delete(WidgetsBundle widgetsBundle, User user) { public void delete(WidgetsBundle widgetsBundle, User user) {
ActionType actionType = ActionType.DELETED;
TenantId tenantId = widgetsBundle.getTenantId(); TenantId tenantId = widgetsBundle.getTenantId();
try { try {
widgetsBundleService.deleteWidgetsBundle(widgetsBundle.getTenantId(), widgetsBundle.getId()); widgetsBundleService.deleteWidgetsBundle(widgetsBundle.getTenantId(), widgetsBundle.getId());
notificationEntityService.notifyCreateOrUpdateOrDelete(tenantId, null, widgetsBundle.getId(), widgetsBundle, notificationEntityService.logEntityAction(tenantId, widgetsBundle.getId(), widgetsBundle, null, actionType, user);
user, ActionType.DELETED, true, null);
} catch (Exception e) { } catch (Exception e) {
notificationEntityService.logEntityAction(tenantId, emptyId(EntityType.WIDGETS_BUNDLE), notificationEntityService.logEntityAction(tenantId, emptyId(EntityType.WIDGETS_BUNDLE), actionType, user, e, widgetsBundle.getId());
ActionType.DELETED, user, e, widgetsBundle.getId());
throw e; throw e;
} }
} }

5
application/src/main/java/org/thingsboard/server/service/install/DefaultSystemDataLoaderService.java

@ -114,13 +114,14 @@ import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.atomic.AtomicInteger;
import static org.thingsboard.server.common.data.DataConstants.DEFAULT_DEVICE_TYPE;
@Service @Service
@Profile("install") @Profile("install")
@Slf4j @Slf4j
public class DefaultSystemDataLoaderService implements SystemDataLoaderService { public class DefaultSystemDataLoaderService implements SystemDataLoaderService {
public static final String CUSTOMER_CRED = "customer"; public static final String CUSTOMER_CRED = "customer";
public static final String DEFAULT_DEVICE_TYPE = "default";
public static final String ACTIVITY_STATE = "active"; public static final String ACTIVITY_STATE = "active";
@Autowired @Autowired
@ -524,7 +525,7 @@ public class DefaultSystemDataLoaderService implements SystemDataLoaderService {
user.setEmail(email); user.setEmail(email);
user.setTenantId(tenantId); user.setTenantId(tenantId);
user.setCustomerId(customerId); user.setCustomerId(customerId);
user = userService.saveUser(user); user = userService.saveUser(tenantId, user);
UserCredentials userCredentials = userService.findUserCredentialsByUserId(TenantId.SYS_TENANT_ID, user.getId()); UserCredentials userCredentials = userService.findUserCredentialsByUserId(TenantId.SYS_TENANT_ID, user.getId());
userCredentials.setPassword(passwordEncoder.encode(password)); userCredentials.setPassword(passwordEncoder.encode(password));
userCredentials.setEnabled(true); userCredentials.setEnabled(true);

3
application/src/main/java/org/thingsboard/server/service/install/update/DefaultDataUpdateService.java

@ -47,6 +47,7 @@ import org.thingsboard.server.common.data.id.TenantId;
import org.thingsboard.server.common.data.kv.BaseReadTsKvQuery; 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.msg.TbNodeConnectionType;
import org.thingsboard.server.common.data.page.PageData; import org.thingsboard.server.common.data.page.PageData;
import org.thingsboard.server.common.data.page.PageDataIterable; import org.thingsboard.server.common.data.page.PageDataIterable;
import org.thingsboard.server.common.data.page.PageLink; import org.thingsboard.server.common.data.page.PageLink;
@ -502,7 +503,7 @@ public class DefaultDataUpdateService implements DataUpdateService {
md.getNodes().add(ruleNode); md.getNodes().add(ruleNode);
md.setFirstNodeIndex(newIdx); md.setFirstNodeIndex(newIdx);
md.addConnectionInfo(newIdx, oldIdx, "Success"); md.addConnectionInfo(newIdx, oldIdx, TbNodeConnectionType.SUCCESS);
ruleChainService.saveRuleChainMetaData(tenant.getId(), md, Function.identity()); ruleChainService.saveRuleChainMetaData(tenant.getId(), md, Function.identity());
} }
} catch (Exception e) { } catch (Exception e) {

1
application/src/main/java/org/thingsboard/server/service/mail/DefaultMailService.java

@ -16,7 +16,6 @@
package org.thingsboard.server.service.mail; package org.thingsboard.server.service.mail;
import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.JsonNode;
import freemarker.template.Configuration; import freemarker.template.Configuration;
import freemarker.template.Template; import freemarker.template.Template;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;

74
application/src/main/java/org/thingsboard/server/service/queue/DefaultTbClusterService.java

@ -32,10 +32,10 @@ import org.thingsboard.server.common.data.DeviceProfile;
import org.thingsboard.server.common.data.EdgeUtils; import org.thingsboard.server.common.data.EdgeUtils;
import org.thingsboard.server.common.data.EntityType; import org.thingsboard.server.common.data.EntityType;
import org.thingsboard.server.common.data.HasName; import org.thingsboard.server.common.data.HasName;
import org.thingsboard.server.common.data.HasRuleEngineProfile;
import org.thingsboard.server.common.data.TbResource; import org.thingsboard.server.common.data.TbResource;
import org.thingsboard.server.common.data.Tenant; import org.thingsboard.server.common.data.Tenant;
import org.thingsboard.server.common.data.TenantProfile; import org.thingsboard.server.common.data.TenantProfile;
import org.thingsboard.server.common.data.asset.AssetProfile;
import org.thingsboard.server.common.data.edge.EdgeEventActionType; import org.thingsboard.server.common.data.edge.EdgeEventActionType;
import org.thingsboard.server.common.data.edge.EdgeEventType; import org.thingsboard.server.common.data.edge.EdgeEventType;
import org.thingsboard.server.common.data.id.AssetId; import org.thingsboard.server.common.data.id.AssetId;
@ -178,15 +178,8 @@ public class DefaultTbClusterService implements TbClusterService {
return; return;
} }
} else { } else {
if (entityId.getEntityType().equals(EntityType.DEVICE)) { HasRuleEngineProfile ruleEngineProfile = getRuleEngineProfileForEntityOrElseNull(tenantId, entityId);
tbMsg = transformMsg(tbMsg, deviceProfileCache.get(tenantId, new DeviceId(entityId.getId()))); tbMsg = transformMsg(tbMsg, ruleEngineProfile);
} else if (entityId.getEntityType().equals(EntityType.DEVICE_PROFILE)) {
tbMsg = transformMsg(tbMsg, deviceProfileCache.get(tenantId, new DeviceProfileId(entityId.getId())));
} else if (entityId.getEntityType().equals(EntityType.ASSET)) {
tbMsg = transformMsg(tbMsg, assetProfileCache.get(tenantId, new AssetId(entityId.getId())));
} else if (entityId.getEntityType().equals(EntityType.ASSET_PROFILE)) {
tbMsg = transformMsg(tbMsg, assetProfileCache.get(tenantId, new AssetProfileId(entityId.getId())));
}
} }
TopicPartitionInfo tpi = partitionService.resolve(ServiceType.TB_RULE_ENGINE, tbMsg.getQueueName(), tenantId, entityId); TopicPartitionInfo tpi = partitionService.resolve(ServiceType.TB_RULE_ENGINE, tbMsg.getQueueName(), tenantId, entityId);
log.trace("PUSHING msg: {} to:{}", tbMsg, tpi); log.trace("PUSHING msg: {} to:{}", tbMsg, tpi);
@ -198,34 +191,33 @@ public class DefaultTbClusterService implements TbClusterService {
toRuleEngineMsgs.incrementAndGet(); toRuleEngineMsgs.incrementAndGet();
} }
private TbMsg transformMsg(TbMsg tbMsg, DeviceProfile deviceProfile) { private HasRuleEngineProfile getRuleEngineProfileForEntityOrElseNull(TenantId tenantId, EntityId entityId) {
if (deviceProfile != null) { if (entityId.getEntityType().equals(EntityType.DEVICE)) {
RuleChainId targetRuleChainId = deviceProfile.getDefaultRuleChainId(); return deviceProfileCache.get(tenantId, new DeviceId(entityId.getId()));
String targetQueueName = deviceProfile.getDefaultQueueName(); } else if (entityId.getEntityType().equals(EntityType.DEVICE_PROFILE)) {
tbMsg = transformMsg(tbMsg, targetRuleChainId, targetQueueName); return deviceProfileCache.get(tenantId, new DeviceProfileId(entityId.getId()));
} else if (entityId.getEntityType().equals(EntityType.ASSET)) {
return assetProfileCache.get(tenantId, new AssetId(entityId.getId()));
} else if (entityId.getEntityType().equals(EntityType.ASSET_PROFILE)) {
return assetProfileCache.get(tenantId, new AssetProfileId(entityId.getId()));
} }
return tbMsg; return null;
} }
private TbMsg transformMsg(TbMsg tbMsg, HasRuleEngineProfile ruleEngineProfile) {
private TbMsg transformMsg(TbMsg tbMsg, AssetProfile assetProfile) { if (ruleEngineProfile != null) {
if (assetProfile != null) { RuleChainId targetRuleChainId = ruleEngineProfile.getDefaultRuleChainId();
RuleChainId targetRuleChainId = assetProfile.getDefaultRuleChainId(); String targetQueueName = ruleEngineProfile.getDefaultQueueName();
String targetQueueName = assetProfile.getDefaultQueueName();
tbMsg = transformMsg(tbMsg, targetRuleChainId, targetQueueName); boolean isRuleChainTransform = targetRuleChainId != null && !targetRuleChainId.equals(tbMsg.getRuleChainId());
} boolean isQueueTransform = targetQueueName != null && !targetQueueName.equals(tbMsg.getQueueName());
return tbMsg;
} if (isRuleChainTransform && isQueueTransform) {
tbMsg = TbMsg.transformMsg(tbMsg, targetRuleChainId, targetQueueName);
private TbMsg transformMsg(TbMsg tbMsg, RuleChainId targetRuleChainId, String targetQueueName) { } else if (isRuleChainTransform) {
boolean isRuleChainTransform = targetRuleChainId != null && !targetRuleChainId.equals(tbMsg.getRuleChainId()); tbMsg = TbMsg.transformMsgRuleChainId(tbMsg, targetRuleChainId);
boolean isQueueTransform = targetQueueName != null && !targetQueueName.equals(tbMsg.getQueueName()); } else if (isQueueTransform) {
tbMsg = TbMsg.transformMsgQueueName(tbMsg, targetQueueName);
if (isRuleChainTransform && isQueueTransform) { }
tbMsg = TbMsg.transformMsg(tbMsg, targetRuleChainId, targetQueueName);
} else if (isRuleChainTransform) {
tbMsg = TbMsg.transformMsg(tbMsg, targetRuleChainId);
} else if (isQueueTransform) {
tbMsg = TbMsg.transformMsg(tbMsg, targetQueueName);
} }
return tbMsg; return tbMsg;
} }
@ -466,11 +458,6 @@ public class DefaultTbClusterService implements TbClusterService {
@Override @Override
public void onDeviceUpdated(Device device, Device old) { public void onDeviceUpdated(Device device, Device old) {
onDeviceUpdated(device, old, true);
}
@Override
public void onDeviceUpdated(Device device, Device old, boolean notifyEdge) {
var created = old == null; var created = old == null;
broadcastEntityChangeToTransport(device.getTenantId(), device.getId(), device, null); broadcastEntityChangeToTransport(device.getTenantId(), device.getId(), device, null);
if (old != null) { if (old != null) {
@ -485,9 +472,6 @@ public class DefaultTbClusterService implements TbClusterService {
broadcastEntityStateChangeEvent(device.getTenantId(), device.getId(), created ? ComponentLifecycleEvent.CREATED : ComponentLifecycleEvent.UPDATED); broadcastEntityStateChangeEvent(device.getTenantId(), device.getId(), created ? ComponentLifecycleEvent.CREATED : ComponentLifecycleEvent.UPDATED);
sendDeviceStateServiceEvent(device.getTenantId(), device.getId(), created, !created, false); sendDeviceStateServiceEvent(device.getTenantId(), device.getId(), created, !created, false);
otaPackageStateService.update(device, old); otaPackageStateService.update(device, old);
if (!created && notifyEdge) {
sendNotificationMsgToEdge(device.getTenantId(), null, device.getId(), null, null, EdgeEventActionType.UPDATED);
}
} }
@Override @Override

4
application/src/main/java/org/thingsboard/server/service/queue/DefaultTbCoreConsumerService.java

@ -32,10 +32,11 @@ import org.thingsboard.server.common.data.id.DeviceId;
import org.thingsboard.server.common.data.id.NotificationRequestId; import org.thingsboard.server.common.data.id.NotificationRequestId;
import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.common.data.id.TenantId;
import org.thingsboard.server.common.data.id.UserId; import org.thingsboard.server.common.data.id.UserId;
import org.thingsboard.server.common.data.notification.rule.trigger.NotificationRuleTrigger;
import org.thingsboard.server.common.data.rpc.RpcError; import org.thingsboard.server.common.data.rpc.RpcError;
import org.thingsboard.server.common.msg.MsgType; import org.thingsboard.server.common.msg.MsgType;
import org.thingsboard.server.common.msg.TbActorMsg; import org.thingsboard.server.common.msg.TbActorMsg;
import org.thingsboard.server.common.data.notification.rule.trigger.NotificationRuleTrigger; import org.thingsboard.server.common.msg.notification.NotificationRuleProcessor;
import org.thingsboard.server.common.msg.queue.ServiceType; import org.thingsboard.server.common.msg.queue.ServiceType;
import org.thingsboard.server.common.msg.queue.TbCallback; import org.thingsboard.server.common.msg.queue.TbCallback;
import org.thingsboard.server.common.msg.rpc.FromDeviceRpcResponse; import org.thingsboard.server.common.msg.rpc.FromDeviceRpcResponse;
@ -63,7 +64,6 @@ import org.thingsboard.server.queue.TbQueueConsumer;
import org.thingsboard.server.queue.common.TbProtoQueueMsg; import org.thingsboard.server.queue.common.TbProtoQueueMsg;
import org.thingsboard.server.queue.discovery.PartitionService; import org.thingsboard.server.queue.discovery.PartitionService;
import org.thingsboard.server.queue.discovery.event.PartitionChangeEvent; import org.thingsboard.server.queue.discovery.event.PartitionChangeEvent;
import org.thingsboard.server.common.msg.notification.NotificationRuleProcessor;
import org.thingsboard.server.queue.provider.TbCoreQueueFactory; import org.thingsboard.server.queue.provider.TbCoreQueueFactory;
import org.thingsboard.server.queue.util.AfterStartUp; import org.thingsboard.server.queue.util.AfterStartUp;
import org.thingsboard.server.queue.util.DataDecodingEncodingService; import org.thingsboard.server.queue.util.DataDecodingEncodingService;

4
application/src/main/java/org/thingsboard/server/service/rpc/DefaultTbCoreDeviceRpcService.java

@ -15,7 +15,6 @@
*/ */
package org.thingsboard.server.service.rpc; package org.thingsboard.server.service.rpc;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.node.ObjectNode; import com.fasterxml.jackson.databind.node.ObjectNode;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
@ -27,6 +26,7 @@ import org.thingsboard.server.cluster.TbClusterService;
import org.thingsboard.server.common.data.DataConstants; import org.thingsboard.server.common.data.DataConstants;
import org.thingsboard.server.common.data.Device; import org.thingsboard.server.common.data.Device;
import org.thingsboard.server.common.data.User; import org.thingsboard.server.common.data.User;
import org.thingsboard.server.common.data.msg.TbMsgType;
import org.thingsboard.server.common.data.rpc.RpcError; import org.thingsboard.server.common.data.rpc.RpcError;
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.TbMsgDataType;
@ -182,7 +182,7 @@ public class DefaultTbCoreDeviceRpcService implements TbCoreDeviceRpcService {
entityNode.put(DataConstants.ADDITIONAL_INFO, msg.getAdditionalInfo()); entityNode.put(DataConstants.ADDITIONAL_INFO, msg.getAdditionalInfo());
try { try {
TbMsg tbMsg = TbMsg.newMsg(DataConstants.RPC_CALL_FROM_SERVER_TO_DEVICE, msg.getDeviceId(), Optional.ofNullable(currentUser).map(User::getCustomerId).orElse(null), metaData, TbMsgDataType.JSON, JacksonUtil.toString(entityNode)); TbMsg tbMsg = TbMsg.newMsg(TbMsgType.RPC_CALL_FROM_SERVER_TO_DEVICE, msg.getDeviceId(), Optional.ofNullable(currentUser).map(User::getCustomerId).orElse(null), metaData, TbMsgDataType.JSON, JacksonUtil.toString(entityNode));
clusterService.pushMsgToRuleEngine(msg.getTenantId(), msg.getDeviceId(), tbMsg, null); clusterService.pushMsgToRuleEngine(msg.getTenantId(), msg.getDeviceId(), tbMsg, null);
} catch (IllegalArgumentException e) { } catch (IllegalArgumentException e) {
throw new RuntimeException(e); throw new RuntimeException(e);

3
application/src/main/java/org/thingsboard/server/service/rpc/TbRpcService.java

@ -24,6 +24,7 @@ import org.thingsboard.server.cluster.TbClusterService;
import org.thingsboard.server.common.data.id.DeviceId; import org.thingsboard.server.common.data.id.DeviceId;
import org.thingsboard.server.common.data.id.RpcId; import org.thingsboard.server.common.data.id.RpcId;
import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.common.data.id.TenantId;
import org.thingsboard.server.common.data.msg.TbMsgType;
import org.thingsboard.server.common.data.page.PageData; import org.thingsboard.server.common.data.page.PageData;
import org.thingsboard.server.common.data.page.PageLink; import org.thingsboard.server.common.data.page.PageLink;
import org.thingsboard.server.common.data.rpc.Rpc; import org.thingsboard.server.common.data.rpc.Rpc;
@ -62,7 +63,7 @@ public class TbRpcService {
} }
private void pushRpcMsgToRuleEngine(TenantId tenantId, Rpc rpc) { private void pushRpcMsgToRuleEngine(TenantId tenantId, Rpc rpc) {
TbMsg msg = TbMsg.newMsg("RPC_" + rpc.getStatus().name(), rpc.getDeviceId(), TbMsgMetaData.EMPTY, JacksonUtil.toString(rpc)); TbMsg msg = TbMsg.newMsg(TbMsgType.valueOf("RPC_" + rpc.getStatus().name()), rpc.getDeviceId(), TbMsgMetaData.EMPTY, JacksonUtil.toString(rpc));
tbClusterService.pushMsgToRuleEngine(tenantId, rpc.getDeviceId(), msg, null); tbClusterService.pushMsgToRuleEngine(tenantId, rpc.getDeviceId(), msg, null);
} }

32
application/src/main/java/org/thingsboard/server/service/rule/DefaultTbRuleChainService.java

@ -29,7 +29,6 @@ import org.thingsboard.server.common.data.EntityType;
import org.thingsboard.server.common.data.User; import org.thingsboard.server.common.data.User;
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.EdgeEventActionType;
import org.thingsboard.server.common.data.exception.ThingsboardException; import org.thingsboard.server.common.data.exception.ThingsboardException;
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;
@ -185,9 +184,7 @@ public class DefaultTbRuleChainService extends AbstractTbEntityService implement
tbClusterService.broadcastEntityStateChangeEvent(tenantId, savedRuleChain.getId(), tbClusterService.broadcastEntityStateChangeEvent(tenantId, savedRuleChain.getId(),
actionType.equals(ActionType.ADDED) ? ComponentLifecycleEvent.CREATED : ComponentLifecycleEvent.UPDATED); actionType.equals(ActionType.ADDED) ? ComponentLifecycleEvent.CREATED : ComponentLifecycleEvent.UPDATED);
} }
boolean sendMsgToEdge = RuleChainType.EDGE.equals(savedRuleChain.getType()) && actionType.equals(ActionType.UPDATED); notificationEntityService.logEntityAction(tenantId, savedRuleChain.getId(), savedRuleChain, null, actionType, user);
notificationEntityService.notifyCreateOrUpdateOrDelete(tenantId, null, savedRuleChain.getId(),
savedRuleChain, user, actionType, sendMsgToEdge, null);
return savedRuleChain; return savedRuleChain;
} catch (Exception e) { } catch (Exception e) {
notificationEntityService.logEntityAction(tenantId, emptyId(EntityType.RULE_CHAIN), ruleChain, actionType, user, e); notificationEntityService.logEntityAction(tenantId, emptyId(EntityType.RULE_CHAIN), ruleChain, actionType, user, e);
@ -204,11 +201,6 @@ public class DefaultTbRuleChainService extends AbstractTbEntityService implement
Set<RuleChainId> referencingRuleChainIds = referencingRuleNodes.stream().map(RuleNode::getRuleChainId).collect(Collectors.toSet()); Set<RuleChainId> referencingRuleChainIds = referencingRuleNodes.stream().map(RuleNode::getRuleChainId).collect(Collectors.toSet());
List<EdgeId> relatedEdgeIds = null;
if (RuleChainType.EDGE.equals(ruleChain.getType())) {
relatedEdgeIds = edgeService.findAllRelatedEdgeIds(tenantId, ruleChainId);
}
ruleChainService.deleteRuleChainById(tenantId, ruleChainId); ruleChainService.deleteRuleChainById(tenantId, ruleChainId);
referencingRuleChainIds.remove(ruleChain.getId()); referencingRuleChainIds.remove(ruleChain.getId());
@ -220,7 +212,7 @@ public class DefaultTbRuleChainService extends AbstractTbEntityService implement
tbClusterService.broadcastEntityStateChangeEvent(tenantId, ruleChain.getId(), ComponentLifecycleEvent.DELETED); tbClusterService.broadcastEntityStateChangeEvent(tenantId, ruleChain.getId(), ComponentLifecycleEvent.DELETED);
} }
notificationEntityService.notifyDeleteRuleChain(tenantId, ruleChain, relatedEdgeIds, user); notificationEntityService.logEntityAction(tenantId, ruleChainId, ruleChain, null, ActionType.DELETED, user, ruleChainId.toString());
} catch (Exception e) { } catch (Exception e) {
notificationEntityService.logEntityAction(tenantId, emptyId(EntityType.RULE_CHAIN), ActionType.DELETED, notificationEntityService.logEntityAction(tenantId, emptyId(EntityType.RULE_CHAIN), ActionType.DELETED,
user, e, ruleChainId.toString()); user, e, ruleChainId.toString());
@ -310,14 +302,8 @@ public class DefaultTbRuleChainService extends AbstractTbEntityService implement
notificationEntityService.logEntityAction(tenantId, ruleChainId, ruleChain, ActionType.UPDATED, user, ruleChainMetaData); notificationEntityService.logEntityAction(tenantId, ruleChainId, ruleChain, ActionType.UPDATED, user, ruleChainMetaData);
if (RuleChainType.EDGE.equals(ruleChain.getType())) {
notificationEntityService.notifySendMsgToEdgeService(tenantId, ruleChain.getId(), EdgeEventActionType.UPDATED);
}
for (RuleChain updatedRuleChain : updatedRuleChains) { for (RuleChain updatedRuleChain : updatedRuleChains) {
if (RuleChainType.EDGE.equals(ruleChain.getType())) { if (RuleChainType.CORE.equals(ruleChain.getType())) {
notificationEntityService.notifySendMsgToEdgeService(tenantId, updatedRuleChain.getId(), EdgeEventActionType.UPDATED);
} else {
RuleChainMetaData updatedRuleChainMetaData = checkNotNull(ruleChainService.loadRuleChainMetaData(tenantId, updatedRuleChain.getId())); RuleChainMetaData updatedRuleChainMetaData = checkNotNull(ruleChainService.loadRuleChainMetaData(tenantId, updatedRuleChain.getId()));
notificationEntityService.logEntityAction(tenantId, updatedRuleChain.getId(), updatedRuleChain, notificationEntityService.logEntityAction(tenantId, updatedRuleChain.getId(), updatedRuleChain,
ActionType.UPDATED, user, updatedRuleChainMetaData); ActionType.UPDATED, user, updatedRuleChainMetaData);
@ -333,34 +319,34 @@ public class DefaultTbRuleChainService extends AbstractTbEntityService implement
@Override @Override
public RuleChain assignRuleChainToEdge(TenantId tenantId, RuleChain ruleChain, Edge edge, User user) throws ThingsboardException { public RuleChain assignRuleChainToEdge(TenantId tenantId, RuleChain ruleChain, Edge edge, User user) throws ThingsboardException {
ActionType actionType = ActionType.ASSIGNED_TO_EDGE;
RuleChainId ruleChainId = ruleChain.getId(); RuleChainId ruleChainId = ruleChain.getId();
EdgeId edgeId = edge.getId(); EdgeId edgeId = edge.getId();
try { try {
RuleChain savedRuleChain = checkNotNull(ruleChainService.assignRuleChainToEdge(tenantId, ruleChainId, edgeId)); RuleChain savedRuleChain = checkNotNull(ruleChainService.assignRuleChainToEdge(tenantId, ruleChainId, edgeId));
notificationEntityService.notifyAssignOrUnassignEntityToEdge(tenantId, ruleChainId, notificationEntityService.logEntityAction(tenantId, ruleChainId, savedRuleChain, null, actionType,
null, edgeId, savedRuleChain, ActionType.ASSIGNED_TO_EDGE,
user, ruleChainId.toString(), edgeId.toString(), edge.getName()); user, ruleChainId.toString(), edgeId.toString(), edge.getName());
return savedRuleChain; return savedRuleChain;
} catch (Exception e) { } catch (Exception e) {
notificationEntityService.logEntityAction(tenantId, emptyId(EntityType.RULE_CHAIN), notificationEntityService.logEntityAction(tenantId, emptyId(EntityType.RULE_CHAIN),
ActionType.ASSIGNED_TO_EDGE, user, e, ruleChainId.toString(), edgeId.toString()); actionType, user, e, ruleChainId.toString(), edgeId.toString());
throw e; throw e;
} }
} }
@Override @Override
public RuleChain unassignRuleChainFromEdge(TenantId tenantId, RuleChain ruleChain, Edge edge, User user) throws ThingsboardException { public RuleChain unassignRuleChainFromEdge(TenantId tenantId, RuleChain ruleChain, Edge edge, User user) throws ThingsboardException {
ActionType actionType = ActionType.UNASSIGNED_FROM_EDGE;
RuleChainId ruleChainId = ruleChain.getId(); RuleChainId ruleChainId = ruleChain.getId();
EdgeId edgeId = edge.getId(); EdgeId edgeId = edge.getId();
try { try {
RuleChain savedRuleChain = checkNotNull(ruleChainService.unassignRuleChainFromEdge(tenantId, ruleChainId, edgeId, false)); RuleChain savedRuleChain = checkNotNull(ruleChainService.unassignRuleChainFromEdge(tenantId, ruleChainId, edgeId, false));
notificationEntityService.notifyAssignOrUnassignEntityToEdge(tenantId, ruleChainId, notificationEntityService.logEntityAction(tenantId, ruleChainId, savedRuleChain, null, actionType,
null, edgeId, savedRuleChain, ActionType.UNASSIGNED_FROM_EDGE,
user, ruleChainId.toString(), edgeId.toString(), edge.getName()); user, ruleChainId.toString(), edgeId.toString(), edge.getName());
return savedRuleChain; return savedRuleChain;
} catch (Exception e) { } catch (Exception e) {
notificationEntityService.logEntityAction(tenantId, emptyId(EntityType.RULE_CHAIN), notificationEntityService.logEntityAction(tenantId, emptyId(EntityType.RULE_CHAIN),
ActionType.UNASSIGNED_FROM_EDGE, user, e, ruleChainId, edgeId); actionType, user, e, ruleChainId, edgeId);
throw e; throw e;
} }
} }

27
application/src/main/java/org/thingsboard/server/service/state/DefaultDeviceStateService.java

@ -36,7 +36,6 @@ import org.thingsboard.common.util.JacksonUtil;
import org.thingsboard.common.util.ThingsBoardExecutors; import org.thingsboard.common.util.ThingsBoardExecutors;
import org.thingsboard.server.cluster.TbClusterService; import org.thingsboard.server.cluster.TbClusterService;
import org.thingsboard.server.common.data.ApiUsageRecordKey; import org.thingsboard.server.common.data.ApiUsageRecordKey;
import org.thingsboard.server.common.data.DataConstants;
import org.thingsboard.server.common.data.Device; import org.thingsboard.server.common.data.Device;
import org.thingsboard.server.common.data.DeviceIdInfo; import org.thingsboard.server.common.data.DeviceIdInfo;
import org.thingsboard.server.common.data.EntityType; import org.thingsboard.server.common.data.EntityType;
@ -51,6 +50,8 @@ import org.thingsboard.server.common.data.kv.BooleanDataEntry;
import org.thingsboard.server.common.data.kv.KvEntry; import org.thingsboard.server.common.data.kv.KvEntry;
import org.thingsboard.server.common.data.kv.LongDataEntry; import org.thingsboard.server.common.data.kv.LongDataEntry;
import org.thingsboard.server.common.data.kv.TsKvEntry; import org.thingsboard.server.common.data.kv.TsKvEntry;
import org.thingsboard.server.common.data.msg.TbMsgType;
import org.thingsboard.server.common.data.notification.rule.trigger.DeviceActivityTrigger;
import org.thingsboard.server.common.data.page.PageData; import org.thingsboard.server.common.data.page.PageData;
import org.thingsboard.server.common.data.page.PageDataIterable; import org.thingsboard.server.common.data.page.PageDataIterable;
import org.thingsboard.server.common.data.query.EntityData; import org.thingsboard.server.common.data.query.EntityData;
@ -63,7 +64,6 @@ import org.thingsboard.server.common.msg.TbMsg;
import org.thingsboard.server.common.msg.TbMsgDataType; 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.notification.NotificationRuleProcessor; import org.thingsboard.server.common.msg.notification.NotificationRuleProcessor;
import org.thingsboard.server.common.data.notification.rule.trigger.DeviceActivityTrigger;
import org.thingsboard.server.common.msg.queue.ServiceType; import org.thingsboard.server.common.msg.queue.ServiceType;
import org.thingsboard.server.common.msg.queue.TbCallback; import org.thingsboard.server.common.msg.queue.TbCallback;
import org.thingsboard.server.common.msg.queue.TopicPartitionInfo; import org.thingsboard.server.common.msg.queue.TopicPartitionInfo;
@ -102,10 +102,7 @@ import java.util.concurrent.TimeoutException;
import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.atomic.AtomicInteger;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import static org.thingsboard.server.common.data.DataConstants.ACTIVITY_EVENT; import static org.thingsboard.server.common.data.DataConstants.SCOPE;
import static org.thingsboard.server.common.data.DataConstants.CONNECT_EVENT;
import static org.thingsboard.server.common.data.DataConstants.DISCONNECT_EVENT;
import static org.thingsboard.server.common.data.DataConstants.INACTIVITY_EVENT;
import static org.thingsboard.server.common.data.DataConstants.SERVER_SCOPE; import static org.thingsboard.server.common.data.DataConstants.SERVER_SCOPE;
/** /**
@ -229,7 +226,7 @@ public class DefaultDeviceStateService extends AbstractPartitionBasedService<Dev
long ts = System.currentTimeMillis(); long ts = System.currentTimeMillis();
stateData.getState().setLastConnectTime(ts); stateData.getState().setLastConnectTime(ts);
save(deviceId, LAST_CONNECT_TIME, ts); save(deviceId, LAST_CONNECT_TIME, ts);
pushRuleEngineMessage(stateData, CONNECT_EVENT); pushRuleEngineMessage(stateData, TbMsgType.CONNECT_EVENT);
checkAndUpdateState(deviceId, stateData); checkAndUpdateState(deviceId, stateData);
} }
@ -271,7 +268,7 @@ public class DefaultDeviceStateService extends AbstractPartitionBasedService<Dev
long ts = System.currentTimeMillis(); long ts = System.currentTimeMillis();
stateData.getState().setLastDisconnectTime(ts); stateData.getState().setLastDisconnectTime(ts);
save(deviceId, LAST_DISCONNECT_TIME, ts); save(deviceId, LAST_DISCONNECT_TIME, ts);
pushRuleEngineMessage(stateData, DISCONNECT_EVENT); pushRuleEngineMessage(stateData, TbMsgType.DISCONNECT_EVENT);
} }
@Override @Override
@ -533,7 +530,7 @@ public class DefaultDeviceStateService extends AbstractPartitionBasedService<Dev
private void onDeviceActivityStatusChange(DeviceId deviceId, boolean active, DeviceStateData stateData) { private void onDeviceActivityStatusChange(DeviceId deviceId, boolean active, DeviceStateData stateData) {
save(deviceId, ACTIVITY_STATE, active); save(deviceId, ACTIVITY_STATE, active);
pushRuleEngineMessage(stateData, active ? ACTIVITY_EVENT : INACTIVITY_EVENT); pushRuleEngineMessage(stateData, active ? TbMsgType.ACTIVITY_EVENT : TbMsgType.INACTIVITY_EVENT);
TbMsgMetaData metaData = stateData.getMetaData(); TbMsgMetaData metaData = stateData.getMetaData();
notificationRuleProcessor.process(DeviceActivityTrigger.builder() notificationRuleProcessor.process(DeviceActivityTrigger.builder()
.tenantId(stateData.getTenantId()).customerId(stateData.getCustomerId()) .tenantId(stateData.getTenantId()).customerId(stateData.getCustomerId())
@ -580,7 +577,7 @@ public class DefaultDeviceStateService extends AbstractPartitionBasedService<Dev
ListenableFuture<List<TsKvEntry>> tsData = tsService.findLatest(TenantId.SYS_TENANT_ID, device.getId(), PERSISTENT_ATTRIBUTES); ListenableFuture<List<TsKvEntry>> tsData = tsService.findLatest(TenantId.SYS_TENANT_ID, device.getId(), PERSISTENT_ATTRIBUTES);
future = Futures.transform(tsData, extractDeviceStateData(device), deviceStateExecutor); future = Futures.transform(tsData, extractDeviceStateData(device), deviceStateExecutor);
} else { } else {
ListenableFuture<List<AttributeKvEntry>> attrData = attributesService.find(TenantId.SYS_TENANT_ID, device.getId(), DataConstants.SERVER_SCOPE, PERSISTENT_ATTRIBUTES); ListenableFuture<List<AttributeKvEntry>> attrData = attributesService.find(TenantId.SYS_TENANT_ID, device.getId(), SERVER_SCOPE, PERSISTENT_ATTRIBUTES);
future = Futures.transform(attrData, extractDeviceStateData(device), deviceStateExecutor); future = Futures.transform(attrData, extractDeviceStateData(device), deviceStateExecutor);
} }
return transformInactivityTimeout(future); return transformInactivityTimeout(future);
@ -771,11 +768,11 @@ public class DefaultDeviceStateService extends AbstractPartitionBasedService<Dev
return defaultValue; return defaultValue;
} }
private void pushRuleEngineMessage(DeviceStateData stateData, String msgType) { private void pushRuleEngineMessage(DeviceStateData stateData, TbMsgType msgType) {
DeviceState state = stateData.getState(); DeviceState state = stateData.getState();
try { try {
String data; String data;
if (msgType.equals(CONNECT_EVENT)) { if (msgType.equals(TbMsgType.CONNECT_EVENT)) {
ObjectNode stateNode = JacksonUtil.convertValue(state, ObjectNode.class); ObjectNode stateNode = JacksonUtil.convertValue(state, ObjectNode.class);
stateNode.remove(ACTIVITY_STATE); stateNode.remove(ACTIVITY_STATE);
data = JacksonUtil.toString(stateNode); data = JacksonUtil.toString(stateNode);
@ -784,7 +781,7 @@ public class DefaultDeviceStateService extends AbstractPartitionBasedService<Dev
} }
TbMsgMetaData md = stateData.getMetaData().copy(); TbMsgMetaData md = stateData.getMetaData().copy();
if (!persistToTelemetry) { if (!persistToTelemetry) {
md.putValue(DataConstants.SCOPE, SERVER_SCOPE); md.putValue(SCOPE, SERVER_SCOPE);
} }
TbMsg tbMsg = TbMsg.newMsg(msgType, stateData.getDeviceId(), stateData.getCustomerId(), md, TbMsgDataType.JSON, data); TbMsg tbMsg = TbMsg.newMsg(msgType, stateData.getDeviceId(), stateData.getCustomerId(), md, TbMsgDataType.JSON, data);
clusterService.pushMsgToRuleEngine(stateData.getTenantId(), stateData.getDeviceId(), tbMsg, null); clusterService.pushMsgToRuleEngine(stateData.getTenantId(), stateData.getDeviceId(), tbMsg, null);
@ -800,7 +797,7 @@ public class DefaultDeviceStateService extends AbstractPartitionBasedService<Dev
Collections.singletonList(new BasicTsKvEntry(System.currentTimeMillis(), new LongDataEntry(key, value))), Collections.singletonList(new BasicTsKvEntry(System.currentTimeMillis(), new LongDataEntry(key, value))),
new TelemetrySaveCallback<>(deviceId, key, value)); new TelemetrySaveCallback<>(deviceId, key, value));
} else { } else {
tsSubService.saveAttrAndNotify(TenantId.SYS_TENANT_ID, deviceId, DataConstants.SERVER_SCOPE, key, value, new TelemetrySaveCallback<>(deviceId, key, value)); tsSubService.saveAttrAndNotify(TenantId.SYS_TENANT_ID, deviceId, SERVER_SCOPE, key, value, new TelemetrySaveCallback<>(deviceId, key, value));
} }
} }
@ -811,7 +808,7 @@ public class DefaultDeviceStateService extends AbstractPartitionBasedService<Dev
Collections.singletonList(new BasicTsKvEntry(System.currentTimeMillis(), new BooleanDataEntry(key, value))), Collections.singletonList(new BasicTsKvEntry(System.currentTimeMillis(), new BooleanDataEntry(key, value))),
new TelemetrySaveCallback<>(deviceId, key, value)); new TelemetrySaveCallback<>(deviceId, key, value));
} else { } else {
tsSubService.saveAttrAndNotify(TenantId.SYS_TENANT_ID, deviceId, DataConstants.SERVER_SCOPE, key, value, new TelemetrySaveCallback<>(deviceId, key, value)); tsSubService.saveAttrAndNotify(TenantId.SYS_TENANT_ID, deviceId, SERVER_SCOPE, key, value, new TelemetrySaveCallback<>(deviceId, key, value));
} }
} }

8
application/src/main/java/org/thingsboard/server/service/sync/ie/DefaultEntitiesExportImportService.java

@ -25,15 +25,15 @@ import org.thingsboard.server.common.data.audit.ActionType;
import org.thingsboard.server.common.data.exception.ThingsboardErrorCode; import org.thingsboard.server.common.data.exception.ThingsboardErrorCode;
import org.thingsboard.server.common.data.exception.ThingsboardException; import org.thingsboard.server.common.data.exception.ThingsboardException;
import org.thingsboard.server.common.data.id.EntityId; import org.thingsboard.server.common.data.id.EntityId;
import org.thingsboard.server.common.data.limit.LimitedApi;
import org.thingsboard.server.common.data.relation.EntityRelation; import org.thingsboard.server.common.data.relation.EntityRelation;
import org.thingsboard.server.common.data.sync.ie.EntityExportData; import org.thingsboard.server.common.data.sync.ie.EntityExportData;
import org.thingsboard.server.common.data.sync.ie.EntityImportResult; import org.thingsboard.server.common.data.sync.ie.EntityImportResult;
import org.thingsboard.server.common.data.util.ThrowingRunnable; import org.thingsboard.server.common.data.util.ThrowingRunnable;
import org.thingsboard.server.dao.exception.DataValidationException; import org.thingsboard.server.dao.exception.DataValidationException;
import org.thingsboard.server.dao.relation.RelationService; import org.thingsboard.server.dao.relation.RelationService;
import org.thingsboard.server.queue.util.TbCoreComponent;
import org.thingsboard.server.common.data.limit.LimitedApi;
import org.thingsboard.server.dao.util.limits.RateLimitService; import org.thingsboard.server.dao.util.limits.RateLimitService;
import org.thingsboard.server.queue.util.TbCoreComponent;
import org.thingsboard.server.service.entitiy.TbNotificationEntityService; import org.thingsboard.server.service.entitiy.TbNotificationEntityService;
import org.thingsboard.server.service.sync.ie.exporting.EntityExportService; import org.thingsboard.server.service.sync.ie.exporting.EntityExportService;
import org.thingsboard.server.service.sync.ie.exporting.impl.BaseEntityExportService; import org.thingsboard.server.service.sync.ie.exporting.impl.BaseEntityExportService;
@ -119,8 +119,8 @@ public class DefaultEntitiesExportImportService implements EntitiesExportImportS
relationService.saveRelations(ctx.getTenantId(), new ArrayList<>(ctx.getRelations())); relationService.saveRelations(ctx.getTenantId(), new ArrayList<>(ctx.getRelations()));
for (EntityRelation relation : ctx.getRelations()) { for (EntityRelation relation : ctx.getRelations()) {
entityNotificationService.notifyRelation(ctx.getTenantId(), null, entityNotificationService.logEntityRelationAction(ctx.getTenantId(), null,
relation, ctx.getUser(), ActionType.RELATION_ADD_OR_UPDATE, relation); relation, ctx.getUser(), ActionType.RELATION_ADD_OR_UPDATE, null, relation);
} }
} }

4
application/src/main/java/org/thingsboard/server/service/sync/ie/importing/impl/AssetProfileImportService.java

@ -58,8 +58,8 @@ public class AssetProfileImportService extends BaseEntityImportService<AssetProf
protected void onEntitySaved(User user, AssetProfile savedAssetProfile, AssetProfile oldAssetProfile) throws ThingsboardException { protected void onEntitySaved(User user, AssetProfile savedAssetProfile, AssetProfile oldAssetProfile) throws ThingsboardException {
clusterService.broadcastEntityStateChangeEvent(user.getTenantId(), savedAssetProfile.getId(), clusterService.broadcastEntityStateChangeEvent(user.getTenantId(), savedAssetProfile.getId(),
oldAssetProfile == null ? ComponentLifecycleEvent.CREATED : ComponentLifecycleEvent.UPDATED); oldAssetProfile == null ? ComponentLifecycleEvent.CREATED : ComponentLifecycleEvent.UPDATED);
entityNotificationService.notifyCreateOrUpdateOrDelete(savedAssetProfile.getTenantId(), null, entityNotificationService.logEntityAction(savedAssetProfile.getTenantId(), savedAssetProfile.getId(),
savedAssetProfile.getId(), savedAssetProfile, user, oldAssetProfile == null ? ActionType.ADDED : ActionType.UPDATED, true, null); savedAssetProfile, null, oldAssetProfile == null ? ActionType.ADDED : ActionType.UPDATED, user);
} }
@Override @Override

8
application/src/main/java/org/thingsboard/server/service/sync/ie/importing/impl/BaseEntityImportService.java

@ -211,8 +211,8 @@ public abstract class BaseEntityImportService<I extends EntityId, E extends Expo
importResult.setUpdatedRelatedEntities(true); importResult.setUpdatedRelatedEntities(true);
relationService.deleteRelation(ctx.getTenantId(), existingRelation.getFrom(), existingRelation.getTo(), existingRelation.getType(), existingRelation.getTypeGroup()); relationService.deleteRelation(ctx.getTenantId(), existingRelation.getFrom(), existingRelation.getTo(), existingRelation.getType(), existingRelation.getTypeGroup());
importResult.addSendEventsCallback(() -> { importResult.addSendEventsCallback(() -> {
entityNotificationService.notifyRelation(tenantId, null, entityNotificationService.logEntityRelationAction(tenantId, null,
existingRelation, ctx.getUser(), ActionType.RELATION_DELETED, existingRelation); existingRelation, ctx.getUser(), ActionType.RELATION_DELETED, null, existingRelation);
}); });
} else if (Objects.equal(relation.getAdditionalInfo(), existingRelation.getAdditionalInfo())) { } else if (Objects.equal(relation.getAdditionalInfo(), existingRelation.getAdditionalInfo())) {
relationsMap.remove(relation); relationsMap.remove(relation);
@ -266,8 +266,8 @@ public abstract class BaseEntityImportService<I extends EntityId, E extends Expo
} }
protected void onEntitySaved(User user, E savedEntity, E oldEntity) throws ThingsboardException { protected void onEntitySaved(User user, E savedEntity, E oldEntity) throws ThingsboardException {
entityNotificationService.notifyCreateOrUpdateEntity(user.getTenantId(), savedEntity.getId(), savedEntity, entityNotificationService.logEntityAction(user.getTenantId(), savedEntity.getId(), savedEntity, null,
null, oldEntity == null ? ActionType.ADDED : ActionType.UPDATED, user); oldEntity == null ? ActionType.ADDED : ActionType.UPDATED, user);
} }

4
application/src/main/java/org/thingsboard/server/service/sync/ie/importing/impl/DeviceProfileImportService.java

@ -68,8 +68,8 @@ public class DeviceProfileImportService extends BaseEntityImportService<DevicePr
otaPackageStateService.update(savedDeviceProfile, otaPackageStateService.update(savedDeviceProfile,
oldDeviceProfile != null && !Objects.equals(oldDeviceProfile.getFirmwareId(), savedDeviceProfile.getFirmwareId()), oldDeviceProfile != null && !Objects.equals(oldDeviceProfile.getFirmwareId(), savedDeviceProfile.getFirmwareId()),
oldDeviceProfile != null && !Objects.equals(oldDeviceProfile.getSoftwareId(), savedDeviceProfile.getSoftwareId())); oldDeviceProfile != null && !Objects.equals(oldDeviceProfile.getSoftwareId(), savedDeviceProfile.getSoftwareId()));
entityNotificationService.notifyCreateOrUpdateOrDelete(savedDeviceProfile.getTenantId(), null, entityNotificationService.logEntityAction(savedDeviceProfile.getTenantId(), savedDeviceProfile.getId(), savedDeviceProfile,
savedDeviceProfile.getId(), savedDeviceProfile, user, oldDeviceProfile == null ? ActionType.ADDED : ActionType.UPDATED, true, null); null, oldDeviceProfile == null ? ActionType.ADDED : ActionType.UPDATED, user);
} }
@Override @Override

5
application/src/main/java/org/thingsboard/server/service/sync/ie/importing/impl/RuleChainImportService.java

@ -21,7 +21,6 @@ import org.springframework.stereotype.Service;
import org.thingsboard.server.common.data.EntityType; import org.thingsboard.server.common.data.EntityType;
import org.thingsboard.server.common.data.User; import org.thingsboard.server.common.data.User;
import org.thingsboard.server.common.data.audit.ActionType; import org.thingsboard.server.common.data.audit.ActionType;
import org.thingsboard.server.common.data.edge.EdgeEventActionType;
import org.thingsboard.server.common.data.exception.ThingsboardException; import org.thingsboard.server.common.data.exception.ThingsboardException;
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;
@ -128,14 +127,12 @@ public class RuleChainImportService extends BaseEntityImportService<RuleChainId,
} }
@Override @Override
protected void onEntitySaved(User user, RuleChain savedRuleChain, RuleChain oldRuleChain) throws ThingsboardException { protected void onEntitySaved(User user, RuleChain savedRuleChain, RuleChain oldRuleChain) {
entityActionService.logEntityAction(user, savedRuleChain.getId(), savedRuleChain, null, entityActionService.logEntityAction(user, savedRuleChain.getId(), savedRuleChain, null,
oldRuleChain == null ? ActionType.ADDED : ActionType.UPDATED, null); oldRuleChain == null ? ActionType.ADDED : ActionType.UPDATED, null);
if (savedRuleChain.getType() == RuleChainType.CORE) { if (savedRuleChain.getType() == RuleChainType.CORE) {
clusterService.broadcastEntityStateChangeEvent(user.getTenantId(), savedRuleChain.getId(), clusterService.broadcastEntityStateChangeEvent(user.getTenantId(), savedRuleChain.getId(),
oldRuleChain == null ? ComponentLifecycleEvent.CREATED : ComponentLifecycleEvent.UPDATED); oldRuleChain == null ? ComponentLifecycleEvent.CREATED : ComponentLifecycleEvent.UPDATED);
} else if (savedRuleChain.getType() == RuleChainType.EDGE && oldRuleChain != null) {
entityActionService.sendEntityNotificationMsgToEdge(user.getTenantId(), savedRuleChain.getId(), EdgeEventActionType.UPDATED);
} }
} }

9
application/src/main/java/org/thingsboard/server/service/sync/ie/importing/impl/WidgetsBundleImportService.java

@ -18,9 +18,6 @@ package org.thingsboard.server.service.sync.ie.importing.impl;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.thingsboard.server.common.data.EntityType; import org.thingsboard.server.common.data.EntityType;
import org.thingsboard.server.common.data.User;
import org.thingsboard.server.common.data.edge.EdgeEventActionType;
import org.thingsboard.server.common.data.exception.ThingsboardException;
import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.common.data.id.TenantId;
import org.thingsboard.server.common.data.id.WidgetsBundleId; import org.thingsboard.server.common.data.id.WidgetsBundleId;
import org.thingsboard.server.common.data.sync.ie.WidgetsBundleExportData; import org.thingsboard.server.common.data.sync.ie.WidgetsBundleExportData;
@ -91,12 +88,6 @@ public class WidgetsBundleImportService extends BaseEntityImportService<WidgetsB
return true; return true;
} }
@Override
protected void onEntitySaved(User user, WidgetsBundle savedWidgetsBundle, WidgetsBundle oldWidgetsBundle) throws ThingsboardException {
entityNotificationService.notifySendMsgToEdgeService(user.getTenantId(), savedWidgetsBundle.getId(),
oldWidgetsBundle == null ? EdgeEventActionType.ADDED : EdgeEventActionType.UPDATED);
}
@Override @Override
protected WidgetsBundle deepCopy(WidgetsBundle widgetsBundle) { protected WidgetsBundle deepCopy(WidgetsBundle widgetsBundle) {
return new WidgetsBundle(widgetsBundle); return new WidgetsBundle(widgetsBundle);

8
application/src/main/java/org/thingsboard/server/service/sync/vc/DefaultEntitiesVersionControlService.java

@ -37,7 +37,6 @@ import org.thingsboard.server.common.data.User;
import org.thingsboard.server.common.data.audit.ActionType; import org.thingsboard.server.common.data.audit.ActionType;
import org.thingsboard.server.common.data.exception.ThingsboardErrorCode; import org.thingsboard.server.common.data.exception.ThingsboardErrorCode;
import org.thingsboard.server.common.data.exception.ThingsboardException; import org.thingsboard.server.common.data.exception.ThingsboardException;
import org.thingsboard.server.common.data.id.EdgeId;
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.id.HasId; import org.thingsboard.server.common.data.id.HasId;
@ -70,7 +69,6 @@ import org.thingsboard.server.common.data.sync.vc.request.load.VersionLoadConfig
import org.thingsboard.server.common.data.sync.vc.request.load.VersionLoadRequest; import org.thingsboard.server.common.data.sync.vc.request.load.VersionLoadRequest;
import org.thingsboard.server.common.data.util.ThrowingRunnable; import org.thingsboard.server.common.data.util.ThrowingRunnable;
import org.thingsboard.server.dao.DaoUtil; import org.thingsboard.server.dao.DaoUtil;
import org.thingsboard.server.dao.edge.EdgeService;
import org.thingsboard.server.dao.exception.DeviceCredentialsValidationException; import org.thingsboard.server.dao.exception.DeviceCredentialsValidationException;
import org.thingsboard.server.queue.util.TbCoreComponent; import org.thingsboard.server.queue.util.TbCoreComponent;
import org.thingsboard.server.service.entitiy.TbNotificationEntityService; import org.thingsboard.server.service.entitiy.TbNotificationEntityService;
@ -115,7 +113,6 @@ public class DefaultEntitiesVersionControlService implements EntitiesVersionCont
private final EntitiesExportImportService exportImportService; private final EntitiesExportImportService exportImportService;
private final ExportableEntitiesService exportableEntitiesService; private final ExportableEntitiesService exportableEntitiesService;
private final TbNotificationEntityService entityNotificationService; private final TbNotificationEntityService entityNotificationService;
private final EdgeService edgeService;
private final TransactionTemplate transactionTemplate; private final TransactionTemplate transactionTemplate;
private final TbTransactionalCache<UUID, VersionControlTaskCacheEntry> taskCache; private final TbTransactionalCache<UUID, VersionControlTaskCacheEntry> taskCache;
@ -432,12 +429,11 @@ public class DefaultEntitiesVersionControlService implements EntitiesVersionCont
return exportableEntitiesService.findEntitiesByTenantId(ctx.getTenantId(), entityType, pageLink); return exportableEntitiesService.findEntitiesByTenantId(ctx.getTenantId(), entityType, pageLink);
}, 100, entity -> { }, 100, entity -> {
if (ctx.getImportedEntities().get(entityType) == null || !ctx.getImportedEntities().get(entityType).contains(entity.getId())) { if (ctx.getImportedEntities().get(entityType) == null || !ctx.getImportedEntities().get(entityType).contains(entity.getId())) {
List<EdgeId> relatedEdgeIds = edgeService.findAllRelatedEdgeIds(ctx.getTenantId(), entity.getId());
exportableEntitiesService.removeById(ctx.getTenantId(), entity.getId()); exportableEntitiesService.removeById(ctx.getTenantId(), entity.getId());
ctx.addEventCallback(() -> { ctx.addEventCallback(() -> {
entityNotificationService.notifyDeleteEntity(ctx.getTenantId(), entity.getId(), entityNotificationService.logEntityAction(ctx.getTenantId(), entity.getId(), entity, null,
entity, null, ActionType.DELETED, relatedEdgeIds, ctx.getUser()); ActionType.DELETED, ctx.getUser());
}); });
ctx.registerDeleted(entityType); ctx.registerDeleted(entityType);
} }

4
application/src/main/java/org/thingsboard/server/service/telemetry/DefaultAlarmSubscriptionService.java

@ -44,15 +44,15 @@ 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.id.TenantId; import org.thingsboard.server.common.data.id.TenantId;
import org.thingsboard.server.common.data.id.UserId; import org.thingsboard.server.common.data.id.UserId;
import org.thingsboard.server.common.data.notification.rule.trigger.AlarmTrigger;
import org.thingsboard.server.common.data.page.PageData; import org.thingsboard.server.common.data.page.PageData;
import org.thingsboard.server.common.data.query.AlarmData; import org.thingsboard.server.common.data.query.AlarmData;
import org.thingsboard.server.common.data.query.AlarmDataQuery; import org.thingsboard.server.common.data.query.AlarmDataQuery;
import org.thingsboard.server.common.data.notification.rule.trigger.AlarmTrigger; import org.thingsboard.server.common.msg.notification.NotificationRuleProcessor;
import org.thingsboard.server.common.msg.queue.TbCallback; import org.thingsboard.server.common.msg.queue.TbCallback;
import org.thingsboard.server.common.stats.TbApiUsageReportClient; import org.thingsboard.server.common.stats.TbApiUsageReportClient;
import org.thingsboard.server.dao.alarm.AlarmOperationResult; import org.thingsboard.server.dao.alarm.AlarmOperationResult;
import org.thingsboard.server.dao.alarm.AlarmService; import org.thingsboard.server.dao.alarm.AlarmService;
import org.thingsboard.server.common.msg.notification.NotificationRuleProcessor;
import org.thingsboard.server.service.apiusage.TbApiUsageStateService; import org.thingsboard.server.service.apiusage.TbApiUsageStateService;
import org.thingsboard.server.service.entitiy.alarm.TbAlarmCommentService; import org.thingsboard.server.service.entitiy.alarm.TbAlarmCommentService;
import org.thingsboard.server.service.subscription.TbSubscriptionUtils; import org.thingsboard.server.service.subscription.TbSubscriptionUtils;

6
application/src/main/java/org/thingsboard/server/service/telemetry/DefaultTelemetrySubscriptionService.java

@ -21,6 +21,7 @@ import com.google.common.util.concurrent.ListenableFuture;
import com.google.common.util.concurrent.MoreExecutors; import com.google.common.util.concurrent.MoreExecutors;
import com.google.common.util.concurrent.SettableFuture; import com.google.common.util.concurrent.SettableFuture;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Lazy; import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.thingsboard.common.util.ThingsBoardThreadFactory; import org.thingsboard.common.util.ThingsBoardThreadFactory;
@ -78,6 +79,9 @@ public class DefaultTelemetrySubscriptionService extends AbstractSubscriptionSer
private ExecutorService tsCallBackExecutor; private ExecutorService tsCallBackExecutor;
@Value("${sql.ts.value_no_xss_validation:false}")
private boolean valueNoXssValidation;
public DefaultTelemetrySubscriptionService(AttributesService attrService, public DefaultTelemetrySubscriptionService(AttributesService attrService,
TimeseriesService tsService, TimeseriesService tsService,
@Lazy TbEntityViewService tbEntityViewService, @Lazy TbEntityViewService tbEntityViewService,
@ -135,7 +139,7 @@ public class DefaultTelemetrySubscriptionService extends AbstractSubscriptionSer
checkInternalEntity(entityId); checkInternalEntity(entityId);
boolean sysTenant = TenantId.SYS_TENANT_ID.equals(tenantId) || tenantId == null; boolean sysTenant = TenantId.SYS_TENANT_ID.equals(tenantId) || tenantId == null;
if (sysTenant || apiUsageStateService.getApiUsageState(tenantId).isDbStorageEnabled()) { if (sysTenant || apiUsageStateService.getApiUsageState(tenantId).isDbStorageEnabled()) {
KvUtils.validate(ts); KvUtils.validate(ts, valueNoXssValidation);
if (saveLatest) { if (saveLatest) {
saveAndNotifyInternal(tenantId, entityId, ts, ttl, getCallback(tenantId, customerId, sysTenant, callback)); saveAndNotifyInternal(tenantId, entityId, ts, ttl, getCallback(tenantId, customerId, sysTenant, callback));
} else { } else {

3
application/src/main/java/org/thingsboard/server/service/transport/DefaultTransportApiService.java

@ -53,6 +53,7 @@ import org.thingsboard.server.common.data.id.DeviceId;
import org.thingsboard.server.common.data.id.DeviceProfileId; import org.thingsboard.server.common.data.id.DeviceProfileId;
import org.thingsboard.server.common.data.id.OtaPackageId; import org.thingsboard.server.common.data.id.OtaPackageId;
import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.common.data.id.TenantId;
import org.thingsboard.server.common.data.msg.TbMsgType;
import org.thingsboard.server.common.data.ota.OtaPackageType; import org.thingsboard.server.common.data.ota.OtaPackageType;
import org.thingsboard.server.common.data.ota.OtaPackageUtil; import org.thingsboard.server.common.data.ota.OtaPackageUtil;
import org.thingsboard.server.common.data.page.PageData; import org.thingsboard.server.common.data.page.PageData;
@ -346,7 +347,7 @@ public class DefaultTransportApiService implements TransportApiService {
DeviceId deviceId = device.getId(); DeviceId deviceId = device.getId();
JsonNode entityNode = JacksonUtil.valueToTree(device); JsonNode entityNode = JacksonUtil.valueToTree(device);
TbMsg tbMsg = TbMsg.newMsg(DataConstants.ENTITY_CREATED, deviceId, customerId, metaData, TbMsgDataType.JSON, JacksonUtil.toString(entityNode)); TbMsg tbMsg = TbMsg.newMsg(TbMsgType.ENTITY_CREATED, deviceId, customerId, metaData, TbMsgDataType.JSON, JacksonUtil.toString(entityNode));
tbClusterService.pushMsgToRuleEngine(tenantId, deviceId, tbMsg, null); tbClusterService.pushMsgToRuleEngine(tenantId, deviceId, tbMsg, null);
} else { } else {
JsonNode deviceAdditionalInfo = device.getAdditionalInfo(); JsonNode deviceAdditionalInfo = device.getAdditionalInfo();

2
application/src/main/java/org/thingsboard/server/utils/LwM2mObjectModelUtils.java

@ -16,8 +16,6 @@
package org.thingsboard.server.utils; package org.thingsboard.server.utils;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.eclipse.leshan.core.model.DDFFileParser;
import org.eclipse.leshan.core.model.DefaultDDFFileValidator;
import org.eclipse.leshan.core.model.InvalidDDFFileException; import org.eclipse.leshan.core.model.InvalidDDFFileException;
import org.eclipse.leshan.core.model.ObjectModel; import org.eclipse.leshan.core.model.ObjectModel;
import org.thingsboard.server.common.data.ResourceType; import org.thingsboard.server.common.data.ResourceType;

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

@ -269,11 +269,13 @@ sql:
batch_max_delay: "${SQL_ATTRIBUTES_BATCH_MAX_DELAY_MS:100}" batch_max_delay: "${SQL_ATTRIBUTES_BATCH_MAX_DELAY_MS:100}"
stats_print_interval_ms: "${SQL_ATTRIBUTES_BATCH_STATS_PRINT_MS:10000}" stats_print_interval_ms: "${SQL_ATTRIBUTES_BATCH_STATS_PRINT_MS:10000}"
batch_threads: "${SQL_ATTRIBUTES_BATCH_THREADS:3}" # batch thread count have to be a prime number like 3 or 5 to gain perfect hash distribution batch_threads: "${SQL_ATTRIBUTES_BATCH_THREADS:3}" # batch thread count have to be a prime number like 3 or 5 to gain perfect hash distribution
value_no_xss_validation: "${SQL_ATTRIBUTES_VALUE_NO_XSS_VALIDATION:false}"
ts: ts:
batch_size: "${SQL_TS_BATCH_SIZE:10000}" batch_size: "${SQL_TS_BATCH_SIZE:10000}"
batch_max_delay: "${SQL_TS_BATCH_MAX_DELAY_MS:100}" batch_max_delay: "${SQL_TS_BATCH_MAX_DELAY_MS:100}"
stats_print_interval_ms: "${SQL_TS_BATCH_STATS_PRINT_MS:10000}" stats_print_interval_ms: "${SQL_TS_BATCH_STATS_PRINT_MS:10000}"
batch_threads: "${SQL_TS_BATCH_THREADS:3}" # batch thread count have to be a prime number like 3 or 5 to gain perfect hash distribution batch_threads: "${SQL_TS_BATCH_THREADS:3}" # batch thread count have to be a prime number like 3 or 5 to gain perfect hash distribution
value_no_xss_validation: "${SQL_TS_VALUE_NO_XSS_VALIDATION:false}"
ts_latest: ts_latest:
batch_size: "${SQL_TS_LATEST_BATCH_SIZE:10000}" batch_size: "${SQL_TS_LATEST_BATCH_SIZE:10000}"
batch_max_delay: "${SQL_TS_LATEST_BATCH_MAX_DELAY_MS:100}" batch_max_delay: "${SQL_TS_LATEST_BATCH_MAX_DELAY_MS:100}"

19
application/src/test/java/org/thingsboard/server/controller/AbstractNotifyEntityTest.java

@ -74,6 +74,17 @@ public abstract class AbstractNotifyEntityTest extends AbstractWebTest {
Mockito.reset(tbClusterService, auditLogService); Mockito.reset(tbClusterService, auditLogService);
} }
protected void testNotifyAssignUnassignEntityAllOneTime(HasName entity, EntityId entityId, EntityId originatorId,
TenantId tenantId, CustomerId customerId, UserId userId, String userName,
ActionType actionType, ActionType actionTypeEdge, Object... additionalInfo) {
int cntTime = 1;
testNotificationMsgToEdgeServiceTime(entityId, tenantId, actionTypeEdge, cntTime);
testLogEntityAction(entity, originatorId, tenantId, customerId, userId, userName, actionType, cntTime, additionalInfo);
ArgumentMatcher<EntityId> matcherOriginatorId = argument -> argument.equals(originatorId);
testPushMsgToRuleEngineTime(matcherOriginatorId, tenantId, entity, cntTime);
Mockito.reset(tbClusterService, auditLogService);
}
protected void testNotifyEntityAllOneTimeRelation(EntityRelation relation, protected void testNotifyEntityAllOneTimeRelation(EntityRelation relation,
TenantId tenantId, CustomerId customerId, UserId userId, String userName, TenantId tenantId, CustomerId customerId, UserId userId, String userName,
ActionType actionType, Object... additionalInfo) { ActionType actionType, Object... additionalInfo) {
@ -115,9 +126,9 @@ public abstract class AbstractNotifyEntityTest extends AbstractWebTest {
protected void testNotifyEntityAllOneTimeLogEntityActionEntityEqClass(HasName entity, EntityId entityId, EntityId originatorId, protected void testNotifyEntityAllOneTimeLogEntityActionEntityEqClass(HasName entity, EntityId entityId, EntityId originatorId,
TenantId tenantId, CustomerId customerId, UserId userId, String userName, TenantId tenantId, CustomerId customerId, UserId userId, String userName,
ActionType actionType, Object... additionalInfo) { ActionType actionType, ActionType actionTypeEdge, Object... additionalInfo) {
int cntTime = 1; int cntTime = 1;
testNotificationMsgToEdgeServiceTime(entityId, tenantId, actionType, cntTime); testNotificationMsgToEdgeServiceTime(entityId, tenantId, actionTypeEdge, cntTime);
testLogEntityActionEntityEqClass(entity, originatorId, tenantId, customerId, userId, userName, actionType, cntTime, additionalInfo); testLogEntityActionEntityEqClass(entity, originatorId, tenantId, customerId, userId, userName, actionType, cntTime, additionalInfo);
ArgumentMatcher<EntityId> matcherOriginatorId = argument -> argument.equals(originatorId); ArgumentMatcher<EntityId> matcherOriginatorId = argument -> argument.equals(originatorId);
testPushMsgToRuleEngineTime(matcherOriginatorId, tenantId, entity, cntTime); testPushMsgToRuleEngineTime(matcherOriginatorId, tenantId, entity, cntTime);
@ -163,10 +174,10 @@ public abstract class AbstractNotifyEntityTest extends AbstractWebTest {
protected void testNotifyManyEntityManyTimeMsgToEdgeServiceEntityEqAny(HasName entity, HasName originator, protected void testNotifyManyEntityManyTimeMsgToEdgeServiceEntityEqAny(HasName entity, HasName originator,
TenantId tenantId, CustomerId customerId, UserId userId, String userName, TenantId tenantId, CustomerId customerId, UserId userId, String userName,
ActionType actionType, ActionType actionTypeEdge, ActionType actionType,
int cntTime, int cntTimeEdge, int cntTimeRuleEngine, Object... additionalInfo) { int cntTime, int cntTimeEdge, int cntTimeRuleEngine, Object... additionalInfo) {
EntityId originatorId = createEntityId_NULL_UUID(originator); EntityId originatorId = createEntityId_NULL_UUID(originator);
testSendNotificationMsgToEdgeServiceTimeEntityEqAny(tenantId, actionTypeEdge, cntTimeEdge); testSendNotificationMsgToEdgeServiceTimeEntityEqAny(tenantId, actionType, cntTimeEdge);
ArgumentMatcher<HasName> matcherEntityClassEquals = argument -> argument.getClass().equals(entity.getClass()); ArgumentMatcher<HasName> matcherEntityClassEquals = argument -> argument.getClass().equals(entity.getClass());
ArgumentMatcher<EntityId> matcherOriginatorId = argument -> argument.getClass().equals(originatorId.getClass()); ArgumentMatcher<EntityId> matcherOriginatorId = argument -> argument.getClass().equals(originatorId.getClass());
ArgumentMatcher<CustomerId> matcherCustomerId = customerId == null ? ArgumentMatcher<CustomerId> matcherCustomerId = customerId == null ?

6
application/src/test/java/org/thingsboard/server/controller/AbstractRuleEngineControllerTest.java

@ -25,13 +25,13 @@ import org.thingsboard.server.common.data.event.EventType;
import org.thingsboard.server.common.data.id.EntityId; import org.thingsboard.server.common.data.id.EntityId;
import org.thingsboard.server.common.data.id.RuleChainId; import org.thingsboard.server.common.data.id.RuleChainId;
import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.common.data.id.TenantId;
import org.thingsboard.server.common.data.msg.TbMsgType;
import org.thingsboard.server.common.data.page.PageData; import org.thingsboard.server.common.data.page.PageData;
import org.thingsboard.server.common.data.page.TimePageLink; import org.thingsboard.server.common.data.page.TimePageLink;
import org.thingsboard.server.common.data.rule.RuleChain; import org.thingsboard.server.common.data.rule.RuleChain;
import org.thingsboard.server.common.data.rule.RuleChainMetaData; import org.thingsboard.server.common.data.rule.RuleChainMetaData;
import org.thingsboard.server.dao.rule.RuleChainService; import org.thingsboard.server.dao.rule.RuleChainService;
import java.io.IOException;
import java.util.function.Predicate; import java.util.function.Predicate;
/** /**
@ -82,8 +82,8 @@ public abstract class AbstractRuleEngineControllerTest extends AbstractControlle
} }
} }
protected Predicate<EventInfo> filterByCustomEvent() { protected Predicate<EventInfo> filterByPostTelemetryEventType() {
return event -> event.getBody().get("msgType").textValue().equals("CUSTOM"); return event -> event.getBody().get("msgType").textValue().equals(TbMsgType.POST_TELEMETRY_REQUEST.name());
} }
} }

18
application/src/test/java/org/thingsboard/server/controller/AbstractWebTest.java

@ -95,6 +95,7 @@ import org.thingsboard.server.common.data.id.DeviceId;
import org.thingsboard.server.common.data.id.EntityId; import org.thingsboard.server.common.data.id.EntityId;
import org.thingsboard.server.common.data.id.HasId; import org.thingsboard.server.common.data.id.HasId;
import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.common.data.id.TenantId;
import org.thingsboard.server.common.data.id.TenantProfileId;
import org.thingsboard.server.common.data.id.UUIDBased; import org.thingsboard.server.common.data.id.UUIDBased;
import org.thingsboard.server.common.data.id.UserId; import org.thingsboard.server.common.data.id.UserId;
import org.thingsboard.server.common.data.page.PageData; import org.thingsboard.server.common.data.page.PageData;
@ -188,7 +189,9 @@ public abstract class AbstractWebTest extends AbstractInMemoryStorageTest {
protected String username; protected String username;
protected TenantId tenantId; protected TenantId tenantId;
protected TenantProfileId tenantProfileId;
protected UserId tenantAdminUserId; protected UserId tenantAdminUserId;
protected User tenantAdminUser;
protected CustomerId tenantAdminCustomerId; protected CustomerId tenantAdminCustomerId;
protected CustomerId customerId; protected CustomerId customerId;
protected TenantId differentTenantId; protected TenantId differentTenantId;
@ -269,15 +272,16 @@ public abstract class AbstractWebTest extends AbstractInMemoryStorageTest {
Tenant savedTenant = doPost("/api/tenant", tenant, Tenant.class); Tenant savedTenant = doPost("/api/tenant", tenant, Tenant.class);
Assert.assertNotNull(savedTenant); Assert.assertNotNull(savedTenant);
tenantId = savedTenant.getId(); tenantId = savedTenant.getId();
tenantProfileId = savedTenant.getTenantProfileId();
User tenantAdmin = new User(); tenantAdminUser = new User();
tenantAdmin.setAuthority(Authority.TENANT_ADMIN); tenantAdminUser.setAuthority(Authority.TENANT_ADMIN);
tenantAdmin.setTenantId(tenantId); tenantAdminUser.setTenantId(tenantId);
tenantAdmin.setEmail(TENANT_ADMIN_EMAIL); tenantAdminUser.setEmail(TENANT_ADMIN_EMAIL);
tenantAdmin = createUserAndLogin(tenantAdmin, TENANT_ADMIN_PASSWORD); tenantAdminUser = createUserAndLogin(tenantAdminUser, TENANT_ADMIN_PASSWORD);
tenantAdminUserId = tenantAdmin.getId(); tenantAdminUserId = tenantAdminUser.getId();
tenantAdminCustomerId = tenantAdmin.getCustomerId(); tenantAdminCustomerId = tenantAdminUser.getCustomerId();
Customer customer = new Customer(); Customer customer = new Customer();
customer.setTitle("Customer"); customer.setTitle("Customer");

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

@ -158,8 +158,10 @@ public class AlarmControllerTest extends AbstractControllerTest {
Assert.assertEquals(alarm.getAckTs(), updatedAlarm.getAckTs()); Assert.assertEquals(alarm.getAckTs(), updatedAlarm.getAckTs());
foundAlarm = doGet("/api/alarm/info/" + updatedAlarm.getId(), AlarmInfo.class); foundAlarm = doGet("/api/alarm/info/" + updatedAlarm.getId(), AlarmInfo.class);
testNotifyEntityAllOneTime(foundAlarm, foundAlarm.getId(), foundAlarm.getOriginator(),
tenantId, customerId, tenantAdminUserId, TENANT_ADMIN_EMAIL, ActionType.ALARM_ACK); testNotifyManyEntityManyTimeMsgToEdgeServiceEntityEqAny(foundAlarm, customerDevice, tenantId,
customerId, tenantAdminUserId, TENANT_ADMIN_EMAIL, ActionType.ALARM_ACK, 1, 1, 1);
Mockito.reset(tbClusterService, auditLogService);
alarm = updatedAlarm; alarm = updatedAlarm;
alarm.setCleared(true); alarm.setCleared(true);
@ -170,8 +172,10 @@ public class AlarmControllerTest extends AbstractControllerTest {
Assert.assertEquals(alarm.getClearTs(), updatedAlarm.getClearTs()); Assert.assertEquals(alarm.getClearTs(), updatedAlarm.getClearTs());
foundAlarm = doGet("/api/alarm/info/" + updatedAlarm.getId(), AlarmInfo.class); foundAlarm = doGet("/api/alarm/info/" + updatedAlarm.getId(), AlarmInfo.class);
testNotifyEntityAllOneTime(foundAlarm, foundAlarm.getId(), foundAlarm.getOriginator(),
tenantId, customerId, tenantAdminUserId, TENANT_ADMIN_EMAIL, ActionType.ALARM_CLEAR); testNotifyManyEntityManyTimeMsgToEdgeServiceEntityEqAny(foundAlarm, customerDevice, tenantId,
customerId, tenantAdminUserId, TENANT_ADMIN_EMAIL, ActionType.ALARM_CLEAR, 1, 1, 1);
Mockito.reset(tbClusterService, auditLogService);
alarm = updatedAlarm; alarm = updatedAlarm;
alarm.setAssigneeId(tenantAdminUserId); alarm.setAssigneeId(tenantAdminUserId);
@ -182,8 +186,10 @@ public class AlarmControllerTest extends AbstractControllerTest {
Assert.assertEquals(alarm.getAssignTs(), updatedAlarm.getAssignTs()); Assert.assertEquals(alarm.getAssignTs(), updatedAlarm.getAssignTs());
foundAlarm = doGet("/api/alarm/info/" + updatedAlarm.getId(), AlarmInfo.class); foundAlarm = doGet("/api/alarm/info/" + updatedAlarm.getId(), AlarmInfo.class);
testNotifyEntityAllOneTime(foundAlarm, foundAlarm.getId(), foundAlarm.getOriginator(),
tenantId, customerId, tenantAdminUserId, TENANT_ADMIN_EMAIL, ActionType.ALARM_ASSIGNED); testNotifyManyEntityManyTimeMsgToEdgeServiceEntityEqAny(foundAlarm, customerDevice, tenantId,
customerId, tenantAdminUserId, TENANT_ADMIN_EMAIL, ActionType.ALARM_ASSIGNED, 1, 1, 1);
Mockito.reset(tbClusterService, auditLogService);
alarm = updatedAlarm; alarm = updatedAlarm;
alarm.setAssigneeId(null); alarm.setAssigneeId(null);
@ -194,8 +200,11 @@ public class AlarmControllerTest extends AbstractControllerTest {
Assert.assertEquals(alarm.getAssignTs(), updatedAlarm.getAssignTs()); Assert.assertEquals(alarm.getAssignTs(), updatedAlarm.getAssignTs());
foundAlarm = doGet("/api/alarm/info/" + updatedAlarm.getId(), AlarmInfo.class); foundAlarm = doGet("/api/alarm/info/" + updatedAlarm.getId(), AlarmInfo.class);
testNotifyEntityAllOneTime(foundAlarm, foundAlarm.getId(), foundAlarm.getOriginator(),
tenantId, customerId, tenantAdminUserId, TENANT_ADMIN_EMAIL, ActionType.ALARM_UNASSIGNED); testNotifyManyEntityManyTimeMsgToEdgeServiceEntityEqAny(foundAlarm, customerDevice, tenantId,
customerId, tenantAdminUserId, TENANT_ADMIN_EMAIL, ActionType.ALARM_UNASSIGNED, 1, 1, 1);
Mockito.reset(tbClusterService, auditLogService);
} }
@Test @Test
@ -241,7 +250,7 @@ public class AlarmControllerTest extends AbstractControllerTest {
doDelete("/api/alarm/" + alarm.getId()).andExpect(status().isOk()); doDelete("/api/alarm/" + alarm.getId()).andExpect(status().isOk());
testNotifyEntityOneTimeMsgToEdgeServiceNever(new Alarm(alarm), alarm.getId(), alarm.getOriginator(), testNotifyEntityAllOneTime(new Alarm(alarm), alarm.getId(), alarm.getOriginator(),
tenantId, customerId, customerUserId, CUSTOMER_USER_EMAIL, ActionType.DELETED); tenantId, customerId, customerUserId, CUSTOMER_USER_EMAIL, ActionType.DELETED);
} }
@ -254,7 +263,7 @@ public class AlarmControllerTest extends AbstractControllerTest {
doDelete("/api/alarm/" + alarm.getId()).andExpect(status().isOk()); doDelete("/api/alarm/" + alarm.getId()).andExpect(status().isOk());
testNotifyEntityOneTimeMsgToEdgeServiceNever(new Alarm(alarm), alarm.getId(), alarm.getOriginator(), testNotifyEntityAllOneTime(new Alarm(alarm), alarm.getId(), alarm.getOriginator(),
tenantId, customerId, tenantAdminUserId, TENANT_ADMIN_EMAIL, ActionType.DELETED); tenantId, customerId, tenantAdminUserId, TENANT_ADMIN_EMAIL, ActionType.DELETED);
} }

91
application/src/test/java/org/thingsboard/server/controller/AssetControllerTest.java

@ -50,7 +50,6 @@ import org.thingsboard.server.dao.service.DaoSqlTest;
import org.thingsboard.server.service.stats.DefaultRuleEngineStatisticsService; import org.thingsboard.server.service.stats.DefaultRuleEngineStatisticsService;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections;
import java.util.List; import java.util.List;
import static org.hamcrest.Matchers.containsString; import static org.hamcrest.Matchers.containsString;
@ -114,8 +113,8 @@ public class AssetControllerTest extends AbstractControllerTest {
Asset savedAsset = doPost("/api/asset", asset, Asset.class); Asset savedAsset = doPost("/api/asset", asset, Asset.class);
testNotifyEntityOneTimeMsgToEdgeServiceNever(savedAsset, savedAsset.getId(), savedAsset.getId(), testNotifyEntityAllOneTime(savedAsset, savedAsset.getId(), savedAsset.getId(), savedTenant.getId(),
savedTenant.getId(), tenantAdmin.getCustomerId(), tenantAdmin.getId(), tenantAdmin.getEmail(), ActionType.ADDED); tenantAdmin.getCustomerId(), tenantAdmin.getId(), tenantAdmin.getEmail(), ActionType.ADDED);
Assert.assertNotNull(savedAsset); Assert.assertNotNull(savedAsset);
Assert.assertNotNull(savedAsset.getId()); Assert.assertNotNull(savedAsset.getId());
@ -130,8 +129,8 @@ public class AssetControllerTest extends AbstractControllerTest {
savedAsset.setName("My new asset"); savedAsset.setName("My new asset");
doPost("/api/asset", savedAsset, Asset.class); doPost("/api/asset", savedAsset, Asset.class);
testNotifyEntityAllOneTime(savedAsset, savedAsset.getId(), savedAsset.getId(), testNotifyEntityAllOneTime(savedAsset, savedAsset.getId(), savedAsset.getId(), savedTenant.getId(),
savedTenant.getId(), tenantAdmin.getCustomerId(), tenantAdmin.getId(), tenantAdmin.getEmail(), ActionType.UPDATED); tenantAdmin.getCustomerId(), tenantAdmin.getId(), tenantAdmin.getEmail(), ActionType.UPDATED);
Asset foundAsset = doGet("/api/asset/" + savedAsset.getId().getId().toString(), Asset.class); Asset foundAsset = doGet("/api/asset/" + savedAsset.getId().getId().toString(), Asset.class);
Assert.assertEquals(foundAsset.getName(), savedAsset.getName()); Assert.assertEquals(foundAsset.getName(), savedAsset.getName());
@ -229,7 +228,8 @@ public class AssetControllerTest extends AbstractControllerTest {
@Test @Test
public void testFindAssetTypesByTenantId() throws Exception { public void testFindAssetTypesByTenantId() throws Exception {
List<Asset> assets = new ArrayList<>(); AssetProfile assetProfile = createAssetProfile("typeB");
assetProfile = doPost("/api/assetProfile", assetProfile, AssetProfile.class);
Mockito.reset(tbClusterService, auditLogService); Mockito.reset(tbClusterService, auditLogService);
@ -238,24 +238,25 @@ public class AssetControllerTest extends AbstractControllerTest {
Asset asset = new Asset(); Asset asset = new Asset();
asset.setName("My asset B" + i); asset.setName("My asset B" + i);
asset.setType("typeB"); asset.setType("typeB");
assets.add(doPost("/api/asset", asset, Asset.class)); asset.setAssetProfileId(assetProfile.getId());
doPost("/api/asset", asset, Asset.class);
} }
testNotifyManyEntityManyTimeMsgToEdgeServiceNever(new Asset(), new Asset(), testNotifyManyEntityManyTimeMsgToEdgeServiceEntityEqAny(new Asset(), new Asset(),
savedTenant.getId(), tenantAdmin.getCustomerId(), tenantAdmin.getId(), tenantAdmin.getEmail(), savedTenant.getId(), tenantAdmin.getCustomerId(), tenantAdmin.getId(), tenantAdmin.getEmail(),
ActionType.ADDED, cntTime); ActionType.ADDED, cntTime, cntTime, cntTime);
for (int i = 0; i < 7; i++) { for (int i = 0; i < 7; i++) {
Asset asset = new Asset(); Asset asset = new Asset();
asset.setName("My asset C" + i); asset.setName("My asset C" + i);
asset.setType("typeC"); asset.setType("typeC");
assets.add(doPost("/api/asset", asset, Asset.class)); doPost("/api/asset", asset, Asset.class);
} }
for (int i = 0; i < 9; i++) { for (int i = 0; i < 9; i++) {
Asset asset = new Asset(); Asset asset = new Asset();
asset.setName("My asset A" + i); asset.setName("My asset A" + i);
asset.setType("typeA"); asset.setType("typeA");
assets.add(doPost("/api/asset", asset, Asset.class)); doPost("/api/asset", asset, Asset.class);
} }
List<EntitySubtype> assetTypes = doGetTyped("/api/asset/types", List<EntitySubtype> assetTypes = doGetTyped("/api/asset/types",
new TypeReference<List<EntitySubtype>>() { new TypeReference<List<EntitySubtype>>() {
@ -280,7 +281,7 @@ public class AssetControllerTest extends AbstractControllerTest {
doDelete("/api/asset/" + savedAsset.getId().getId().toString()) doDelete("/api/asset/" + savedAsset.getId().getId().toString())
.andExpect(status().isOk()); .andExpect(status().isOk());
testNotifyEntityOneTimeMsgToEdgeServiceNever(savedAsset, savedAsset.getId(), savedAsset.getId(), testNotifyEntityAllOneTime(savedAsset, savedAsset.getId(), savedAsset.getId(),
savedTenant.getId(), tenantAdmin.getCustomerId(), tenantAdmin.getId(), tenantAdmin.getEmail(), savedTenant.getId(), tenantAdmin.getCustomerId(), tenantAdmin.getId(), tenantAdmin.getEmail(),
ActionType.DELETED, savedAsset.getId().getId().toString()); ActionType.DELETED, savedAsset.getId().getId().toString());
@ -342,7 +343,7 @@ public class AssetControllerTest extends AbstractControllerTest {
Asset savedAsset = doPost("/api/asset", asset, Asset.class); Asset savedAsset = doPost("/api/asset", asset, Asset.class);
Assert.assertEquals("default", savedAsset.getType()); Assert.assertEquals("default", savedAsset.getType());
testNotifyEntityOneTimeMsgToEdgeServiceNever(savedAsset, savedAsset.getId(), savedAsset.getId(), testNotifyEntityAllOneTime(savedAsset, savedAsset.getId(), savedAsset.getId(),
savedTenant.getId(), tenantAdmin.getCustomerId(), tenantAdmin.getId(), tenantAdmin.getEmail(), savedTenant.getId(), tenantAdmin.getCustomerId(), tenantAdmin.getId(), tenantAdmin.getEmail(),
ActionType.ADDED); ActionType.ADDED);
} }
@ -380,9 +381,9 @@ public class AssetControllerTest extends AbstractControllerTest {
+ "/asset/" + savedAsset.getId().getId().toString(), Asset.class); + "/asset/" + savedAsset.getId().getId().toString(), Asset.class);
Assert.assertEquals(savedCustomer.getId(), assignedAsset.getCustomerId()); Assert.assertEquals(savedCustomer.getId(), assignedAsset.getCustomerId());
testNotifyEntityAllOneTime(assignedAsset, assignedAsset.getId(), assignedAsset.getId(), testNotifyAssignUnassignEntityAllOneTime(assignedAsset, assignedAsset.getId(), assignedAsset.getId(),
savedTenant.getId(), savedCustomer.getId(), tenantAdmin.getId(), tenantAdmin.getEmail(), savedTenant.getId(), savedCustomer.getId(), tenantAdmin.getId(), tenantAdmin.getEmail(),
ActionType.ASSIGNED_TO_CUSTOMER, assignedAsset.getId().toString(), savedCustomer.getId().toString(), savedCustomer.getTitle()); ActionType.ASSIGNED_TO_CUSTOMER, ActionType.UPDATED, assignedAsset.getId().toString(), savedCustomer.getId().toString(), savedCustomer.getTitle());
Asset foundAsset = doGet("/api/asset/" + savedAsset.getId().getId().toString(), Asset.class); Asset foundAsset = doGet("/api/asset/" + savedAsset.getId().getId().toString(), Asset.class);
Assert.assertEquals(savedCustomer.getId(), foundAsset.getCustomerId()); Assert.assertEquals(savedCustomer.getId(), foundAsset.getCustomerId());
@ -393,9 +394,9 @@ public class AssetControllerTest extends AbstractControllerTest {
doDelete("/api/customer/asset/" + savedAsset.getId().getId().toString(), Asset.class); doDelete("/api/customer/asset/" + savedAsset.getId().getId().toString(), Asset.class);
Assert.assertEquals(ModelConstants.NULL_UUID, unassignedAsset.getCustomerId().getId()); Assert.assertEquals(ModelConstants.NULL_UUID, unassignedAsset.getCustomerId().getId());
testNotifyEntityAllOneTime(savedAsset, savedAsset.getId(), savedAsset.getId(), testNotifyAssignUnassignEntityAllOneTime(savedAsset, savedAsset.getId(), savedAsset.getId(),
savedTenant.getId(), savedCustomer.getId(), tenantAdmin.getId(), tenantAdmin.getEmail(), savedTenant.getId(), savedCustomer.getId(), tenantAdmin.getId(), tenantAdmin.getEmail(),
ActionType.UNASSIGNED_FROM_CUSTOMER, savedAsset.getId().toString(), savedCustomer.getId().toString(), savedCustomer.getTitle()); ActionType.UNASSIGNED_FROM_CUSTOMER, ActionType.UPDATED, savedAsset.getId().toString(), savedCustomer.getId().toString(), savedCustomer.getTitle());
foundAsset = doGet("/api/asset/" + savedAsset.getId().getId().toString(), Asset.class); foundAsset = doGet("/api/asset/" + savedAsset.getId().getId().toString(), Asset.class);
Assert.assertEquals(ModelConstants.NULL_UUID, foundAsset.getCustomerId().getId()); Assert.assertEquals(ModelConstants.NULL_UUID, foundAsset.getCustomerId().getId());
@ -415,9 +416,10 @@ public class AssetControllerTest extends AbstractControllerTest {
Customer publicCustomer = doGet("/api/customer/" + assignedAsset.getCustomerId(), Customer.class); Customer publicCustomer = doGet("/api/customer/" + assignedAsset.getCustomerId(), Customer.class);
Assert.assertTrue(publicCustomer.isPublic()); Assert.assertTrue(publicCustomer.isPublic());
testNotifyEntityAllOneTime(assignedAsset, assignedAsset.getId(), assignedAsset.getId(), testNotifyAssignUnassignEntityAllOneTime(assignedAsset, assignedAsset.getId(), assignedAsset.getId(),
savedTenant.getId(), publicCustomer.getId(), tenantAdmin.getId(), tenantAdmin.getEmail(), savedTenant.getId(), publicCustomer.getId(), tenantAdmin.getId(), tenantAdmin.getEmail(),
ActionType.ASSIGNED_TO_CUSTOMER, assignedAsset.getId().toString(), publicCustomer.getId().toString(), publicCustomer.getTitle()); ActionType.ASSIGNED_TO_CUSTOMER, ActionType.UPDATED, assignedAsset.getId().toString(),
publicCustomer.getId().toString(), publicCustomer.getTitle());
Asset foundAsset = doGet("/api/asset/" + savedAsset.getId().getId().toString(), Asset.class); Asset foundAsset = doGet("/api/asset/" + savedAsset.getId().getId().toString(), Asset.class);
Assert.assertEquals(publicCustomer.getId(), foundAsset.getCustomerId()); Assert.assertEquals(publicCustomer.getId(), foundAsset.getCustomerId());
@ -428,9 +430,10 @@ public class AssetControllerTest extends AbstractControllerTest {
doDelete("/api/customer/asset/" + savedAsset.getId().getId().toString(), Asset.class); doDelete("/api/customer/asset/" + savedAsset.getId().getId().toString(), Asset.class);
Assert.assertEquals(ModelConstants.NULL_UUID, unassignedAsset.getCustomerId().getId()); Assert.assertEquals(ModelConstants.NULL_UUID, unassignedAsset.getCustomerId().getId());
testNotifyEntityAllOneTime(savedAsset, savedAsset.getId(), savedAsset.getId(), testNotifyAssignUnassignEntityAllOneTime(savedAsset, savedAsset.getId(), savedAsset.getId(),
savedTenant.getId(), publicCustomer.getId(), tenantAdmin.getId(), tenantAdmin.getEmail(), savedTenant.getId(), publicCustomer.getId(), tenantAdmin.getId(), tenantAdmin.getEmail(),
ActionType.UNASSIGNED_FROM_CUSTOMER, savedAsset.getId().toString(), publicCustomer.getId().toString(), publicCustomer.getTitle()); ActionType.UNASSIGNED_FROM_CUSTOMER, ActionType.UPDATED, savedAsset.getId().toString(),
publicCustomer.getId().toString(), publicCustomer.getTitle());
foundAsset = doGet("/api/asset/" + savedAsset.getId().getId().toString(), Asset.class); foundAsset = doGet("/api/asset/" + savedAsset.getId().getId().toString(), Asset.class);
Assert.assertEquals(ModelConstants.NULL_UUID, foundAsset.getCustomerId().getId()); Assert.assertEquals(ModelConstants.NULL_UUID, foundAsset.getCustomerId().getId());
@ -513,7 +516,7 @@ public class AssetControllerTest extends AbstractControllerTest {
} }
List<Asset> loadedAssets = new ArrayList<>(); List<Asset> loadedAssets = new ArrayList<>();
PageLink pageLink = new PageLink(23); PageLink pageLink = new PageLink(23);
PageData<Asset> pageData = null; PageData<Asset> pageData;
do { do {
pageData = doGetTypedWithPageLink("/api/tenant/assets?", pageData = doGetTypedWithPageLink("/api/tenant/assets?",
new TypeReference<PageData<Asset>>() { new TypeReference<PageData<Asset>>() {
@ -524,14 +527,14 @@ public class AssetControllerTest extends AbstractControllerTest {
} }
} while (pageData.hasNext()); } while (pageData.hasNext());
testNotifyManyEntityManyTimeMsgToEdgeServiceNever(new Asset(), new Asset(), testNotifyManyEntityManyTimeMsgToEdgeServiceEntityEqAny(new Asset(), new Asset(),
savedTenant.getId(), tenantAdmin.getCustomerId(), tenantAdmin.getId(), tenantAdmin.getEmail(), savedTenant.getId(), tenantAdmin.getCustomerId(), tenantAdmin.getId(), tenantAdmin.getEmail(),
ActionType.ADDED, cntEntity); ActionType.ADDED, cntEntity, cntEntity, cntEntity);
loadedAssets.removeIf(asset -> asset.getType().equals(DefaultRuleEngineStatisticsService.TB_SERVICE_QUEUE)); loadedAssets.removeIf(asset -> asset.getType().equals(DefaultRuleEngineStatisticsService.TB_SERVICE_QUEUE));
Collections.sort(assets, idComparator); assets.sort(idComparator);
Collections.sort(loadedAssets, idComparator); loadedAssets.sort(idComparator);
Assert.assertEquals(assets, loadedAssets); Assert.assertEquals(assets, loadedAssets);
} }
@ -574,8 +577,8 @@ public class AssetControllerTest extends AbstractControllerTest {
} }
} while (pageData.hasNext()); } while (pageData.hasNext());
Collections.sort(assetsTitle1, idComparator); assetsTitle1.sort(idComparator);
Collections.sort(loadedAssetsTitle1, idComparator); loadedAssetsTitle1.sort(idComparator);
Assert.assertEquals(assetsTitle1, loadedAssetsTitle1); Assert.assertEquals(assetsTitle1, loadedAssetsTitle1);
@ -591,8 +594,8 @@ public class AssetControllerTest extends AbstractControllerTest {
} }
} while (pageData.hasNext()); } while (pageData.hasNext());
Collections.sort(assetsTitle2, idComparator); assetsTitle2.sort(idComparator);
Collections.sort(loadedAssetsTitle2, idComparator); loadedAssetsTitle2.sort(idComparator);
Assert.assertEquals(assetsTitle2, loadedAssetsTitle2); Assert.assertEquals(assetsTitle2, loadedAssetsTitle2);
@ -661,8 +664,8 @@ public class AssetControllerTest extends AbstractControllerTest {
} }
} while (pageData.hasNext()); } while (pageData.hasNext());
Collections.sort(assetsType1, idComparator); assetsType1.sort(idComparator);
Collections.sort(loadedAssetsType1, idComparator); loadedAssetsType1.sort(idComparator);
Assert.assertEquals(assetsType1, loadedAssetsType1); Assert.assertEquals(assetsType1, loadedAssetsType1);
@ -678,8 +681,8 @@ public class AssetControllerTest extends AbstractControllerTest {
} }
} while (pageData.hasNext()); } while (pageData.hasNext());
Collections.sort(assetsType2, idComparator); assetsType2.sort(idComparator);
Collections.sort(loadedAssetsType2, idComparator); loadedAssetsType2.sort(idComparator);
Assert.assertEquals(assetsType2, loadedAssetsType2); Assert.assertEquals(assetsType2, loadedAssetsType2);
@ -738,8 +741,8 @@ public class AssetControllerTest extends AbstractControllerTest {
} }
} while (pageData.hasNext()); } while (pageData.hasNext());
Collections.sort(assets, idComparator); assets.sort(idComparator);
Collections.sort(loadedAssets, idComparator); loadedAssets.sort(idComparator);
Assert.assertEquals(assets, loadedAssets); Assert.assertEquals(assets, loadedAssets);
} }
@ -791,8 +794,8 @@ public class AssetControllerTest extends AbstractControllerTest {
} }
} while (pageData.hasNext()); } while (pageData.hasNext());
Collections.sort(assetsTitle1, idComparator); assetsTitle1.sort(idComparator);
Collections.sort(loadedAssetsTitle1, idComparator); loadedAssetsTitle1.sort(idComparator);
Assert.assertEquals(assetsTitle1, loadedAssetsTitle1); Assert.assertEquals(assetsTitle1, loadedAssetsTitle1);
@ -808,8 +811,8 @@ public class AssetControllerTest extends AbstractControllerTest {
} }
} while (pageData.hasNext()); } while (pageData.hasNext());
Collections.sort(assetsTitle2, idComparator); assetsTitle2.sort(idComparator);
Collections.sort(loadedAssetsTitle2, idComparator); loadedAssetsTitle2.sort(idComparator);
Assert.assertEquals(assetsTitle2, loadedAssetsTitle2); Assert.assertEquals(assetsTitle2, loadedAssetsTitle2);
@ -887,8 +890,8 @@ public class AssetControllerTest extends AbstractControllerTest {
} }
} while (pageData.hasNext()); } while (pageData.hasNext());
Collections.sort(assetsType1, idComparator); assetsType1.sort(idComparator);
Collections.sort(loadedAssetsType1, idComparator); loadedAssetsType1.sort(idComparator);
Assert.assertEquals(assetsType1, loadedAssetsType1); Assert.assertEquals(assetsType1, loadedAssetsType1);
@ -904,8 +907,8 @@ public class AssetControllerTest extends AbstractControllerTest {
} }
} while (pageData.hasNext()); } while (pageData.hasNext());
Collections.sort(assetsType2, idComparator); assetsType2.sort(idComparator);
Collections.sort(loadedAssetsType2, idComparator); loadedAssetsType2.sort(idComparator);
Assert.assertEquals(assetsType2, loadedAssetsType2); Assert.assertEquals(assetsType2, loadedAssetsType2);

4
application/src/test/java/org/thingsboard/server/controller/AssetProfileControllerTest.java

@ -355,7 +355,7 @@ public class AssetProfileControllerTest extends AbstractControllerTest {
testNotifyManyEntityManyTimeMsgToEdgeServiceEntityEqAny(new AssetProfile(), new AssetProfile(), testNotifyManyEntityManyTimeMsgToEdgeServiceEntityEqAny(new AssetProfile(), new AssetProfile(),
savedTenant.getId(), tenantAdmin.getCustomerId(), tenantAdmin.getId(), tenantAdmin.getEmail(), savedTenant.getId(), tenantAdmin.getCustomerId(), tenantAdmin.getId(), tenantAdmin.getEmail(),
ActionType.ADDED, ActionType.ADDED, cntEntity, cntEntity, cntEntity); ActionType.ADDED, cntEntity, cntEntity, cntEntity);
Mockito.reset(tbClusterService, auditLogService); Mockito.reset(tbClusterService, auditLogService);
List<AssetProfile> loadedAssetProfiles = new ArrayList<>(); List<AssetProfile> loadedAssetProfiles = new ArrayList<>();
@ -384,7 +384,7 @@ public class AssetProfileControllerTest extends AbstractControllerTest {
testNotifyManyEntityManyTimeMsgToEdgeServiceEntityEqAny(loadedAssetProfiles.get(0), loadedAssetProfiles.get(0), testNotifyManyEntityManyTimeMsgToEdgeServiceEntityEqAny(loadedAssetProfiles.get(0), loadedAssetProfiles.get(0),
savedTenant.getId(), tenantAdmin.getCustomerId(), tenantAdmin.getId(), tenantAdmin.getEmail(), savedTenant.getId(), tenantAdmin.getCustomerId(), tenantAdmin.getId(), tenantAdmin.getEmail(),
ActionType.DELETED, ActionType.DELETED, cntEntity, cntEntity, cntEntity, loadedAssetProfiles.get(0).getId().getId().toString()); ActionType.DELETED, cntEntity, cntEntity, cntEntity, loadedAssetProfiles.get(0).getId().getId().toString());
pageLink = new PageLink(17); pageLink = new PageLink(17);
pageData = doGetTypedWithPageLink("/api/assetProfiles?", pageData = doGetTypedWithPageLink("/api/assetProfiles?",

12
application/src/test/java/org/thingsboard/server/controller/CustomerControllerTest.java

@ -117,8 +117,8 @@ public class CustomerControllerTest extends AbstractControllerTest {
Customer savedCustomer = doPost("/api/customer", customer, Customer.class); Customer savedCustomer = doPost("/api/customer", customer, Customer.class);
testNotifyEntityOneTimeMsgToEdgeServiceNever(savedCustomer, savedCustomer.getId(), savedCustomer.getId(), testNotifyEntityAllOneTime(savedCustomer, savedCustomer.getId(), savedCustomer.getId(), savedCustomer.getTenantId(),
savedCustomer.getTenantId(), tenantAdmin.getCustomerId(), tenantAdmin.getId(), tenantAdmin.getEmail(), new CustomerId(CustomerId.NULL_UUID), tenantAdmin.getId(), tenantAdmin.getEmail(),
ActionType.ADDED); ActionType.ADDED);
Assert.assertNotNull(savedCustomer); Assert.assertNotNull(savedCustomer);
@ -242,7 +242,7 @@ public class CustomerControllerTest extends AbstractControllerTest {
doDelete("/api/customer/" + savedCustomer.getId().getId().toString()) doDelete("/api/customer/" + savedCustomer.getId().getId().toString())
.andExpect(status().isOk()); .andExpect(status().isOk());
testNotifyEntityBroadcastEntityStateChangeEventOneTimeMsgToEdgeServiceNever(savedCustomer, savedCustomer.getId(), testNotifyEntityBroadcastEntityStateChangeEventOneTime(savedCustomer, savedCustomer.getId(),
savedCustomer.getId(), savedCustomer.getTenantId(), savedCustomer.getId(), tenantAdmin.getId(), savedCustomer.getId(), savedCustomer.getTenantId(), savedCustomer.getId(), tenantAdmin.getId(),
tenantAdmin.getEmail(), ActionType.DELETED, savedCustomer.getId().getId().toString()); tenantAdmin.getEmail(), ActionType.DELETED, savedCustomer.getId().getId().toString());
} }
@ -272,7 +272,7 @@ public class CustomerControllerTest extends AbstractControllerTest {
doDelete("/api/customer/" + savedCustomer.getId().getId().toString()) doDelete("/api/customer/" + savedCustomer.getId().getId().toString())
.andExpect(status().isOk()); .andExpect(status().isOk());
testNotifyEntityBroadcastEntityStateChangeEventOneTimeMsgToEdgeServiceNever(savedCustomer, savedCustomer.getId(), testNotifyEntityBroadcastEntityStateChangeEventOneTime(savedCustomer, savedCustomer.getId(),
savedCustomer.getId(), savedCustomer.getTenantId(), savedCustomer.getId(), tenantAdmin.getId(), savedCustomer.getId(), savedCustomer.getTenantId(), savedCustomer.getId(), tenantAdmin.getId(),
tenantAdmin.getEmail(), ActionType.DELETED, savedCustomer.getId().getId().toString()); tenantAdmin.getEmail(), ActionType.DELETED, savedCustomer.getId().getId().toString());
@ -332,9 +332,9 @@ public class CustomerControllerTest extends AbstractControllerTest {
} }
List<Customer> customers = Futures.allAsList(futures).get(TIMEOUT, TimeUnit.SECONDS); List<Customer> customers = Futures.allAsList(futures).get(TIMEOUT, TimeUnit.SECONDS);
testNotifyManyEntityManyTimeMsgToEdgeServiceNever(new Customer(), new Customer(), testNotifyManyEntityManyTimeMsgToEdgeServiceEntityEqAny(new Customer(), new Customer(),
tenantId, tenantAdmin.getCustomerId(), tenantAdmin.getId(), tenantAdmin.getEmail(), tenantId, tenantAdmin.getCustomerId(), tenantAdmin.getId(), tenantAdmin.getEmail(),
ActionType.ADDED, cntEntity); ActionType.ADDED, cntEntity, cntEntity, cntEntity);
List<Customer> loadedCustomers = new ArrayList<>(135); List<Customer> loadedCustomers = new ArrayList<>(135);
PageLink pageLink = new PageLink(23); PageLink pageLink = new PageLink(23);

37
application/src/test/java/org/thingsboard/server/controller/DashboardControllerTest.java

@ -46,7 +46,6 @@ import org.thingsboard.server.dao.exception.DataValidationException;
import org.thingsboard.server.dao.service.DaoSqlTest; import org.thingsboard.server.dao.service.DaoSqlTest;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections;
import java.util.List; import java.util.List;
import static org.hamcrest.Matchers.containsString; import static org.hamcrest.Matchers.containsString;
@ -154,7 +153,7 @@ public class DashboardControllerTest extends AbstractControllerTest {
doDelete("/api/dashboard/" + savedDashboard.getId().getId().toString()).andExpect(status().isOk()); doDelete("/api/dashboard/" + savedDashboard.getId().getId().toString()).andExpect(status().isOk());
testNotifyEntityOneTimeMsgToEdgeServiceNever(savedDashboard, savedDashboard.getId(), savedDashboard.getId(), testNotifyEntityAllOneTime(savedDashboard, savedDashboard.getId(), savedDashboard.getId(),
savedDashboard.getTenantId(), tenantAdmin.getCustomerId(), tenantAdmin.getId(), tenantAdmin.getEmail(), ActionType.DELETED, savedDashboard.getTenantId(), tenantAdmin.getCustomerId(), tenantAdmin.getId(), tenantAdmin.getEmail(), ActionType.DELETED,
savedDashboard.getId().getId().toString()); savedDashboard.getId().getId().toString());
@ -198,7 +197,7 @@ public class DashboardControllerTest extends AbstractControllerTest {
testNotifyEntityAllOneTimeLogEntityActionEntityEqClass(assignedDashboard, assignedDashboard.getId(), assignedDashboard.getId(), testNotifyEntityAllOneTimeLogEntityActionEntityEqClass(assignedDashboard, assignedDashboard.getId(), assignedDashboard.getId(),
savedTenant.getId(), savedCustomer.getId(), tenantAdmin.getId(), tenantAdmin.getEmail(), ActionType.ASSIGNED_TO_CUSTOMER, savedTenant.getId(), savedCustomer.getId(), tenantAdmin.getId(), tenantAdmin.getEmail(), ActionType.ASSIGNED_TO_CUSTOMER,
assignedDashboard .getId().getId().toString(), savedCustomer.getId().getId().toString(), savedCustomer.getTitle()); ActionType.UPDATED, assignedDashboard.getId().getId().toString(), savedCustomer.getId().getId().toString(), savedCustomer.getTitle());
Dashboard foundDashboard = doGet("/api/dashboard/" + savedDashboard.getId().getId().toString(), Dashboard.class); Dashboard foundDashboard = doGet("/api/dashboard/" + savedDashboard.getId().getId().toString(), Dashboard.class);
Assert.assertTrue(foundDashboard.getAssignedCustomers().contains(savedCustomer.toShortCustomerInfo())); Assert.assertTrue(foundDashboard.getAssignedCustomers().contains(savedCustomer.toShortCustomerInfo()));
@ -210,7 +209,7 @@ public class DashboardControllerTest extends AbstractControllerTest {
testNotifyEntityAllOneTimeLogEntityActionEntityEqClass(assignedDashboard, assignedDashboard.getId(), assignedDashboard.getId(), testNotifyEntityAllOneTimeLogEntityActionEntityEqClass(assignedDashboard, assignedDashboard.getId(), assignedDashboard.getId(),
savedTenant.getId(), savedCustomer.getId(), tenantAdmin.getId(), tenantAdmin.getEmail(), ActionType.UNASSIGNED_FROM_CUSTOMER, savedTenant.getId(), savedCustomer.getId(), tenantAdmin.getId(), tenantAdmin.getEmail(), ActionType.UNASSIGNED_FROM_CUSTOMER,
unassignedDashboard.getId().getId().toString(), savedCustomer.getId().getId().toString(), savedCustomer.getTitle()); ActionType.UPDATED, unassignedDashboard.getId().getId().toString(), savedCustomer.getId().getId().toString(), savedCustomer.getTitle());
Assert.assertTrue(unassignedDashboard.getAssignedCustomers() == null || unassignedDashboard.getAssignedCustomers().isEmpty()); Assert.assertTrue(unassignedDashboard.getAssignedCustomers() == null || unassignedDashboard.getAssignedCustomers().isEmpty());
@ -241,7 +240,7 @@ public class DashboardControllerTest extends AbstractControllerTest {
testNotifyEntityAllOneTimeLogEntityActionEntityEqClass(assignedDashboard, assignedDashboard.getId(), assignedDashboard.getId(), testNotifyEntityAllOneTimeLogEntityActionEntityEqClass(assignedDashboard, assignedDashboard.getId(), assignedDashboard.getId(),
savedTenant.getId(), publicCustomer.getId(), tenantAdmin.getId(), tenantAdmin.getEmail(), ActionType.ASSIGNED_TO_CUSTOMER, savedTenant.getId(), publicCustomer.getId(), tenantAdmin.getId(), tenantAdmin.getEmail(), ActionType.ASSIGNED_TO_CUSTOMER,
assignedDashboard .getId().getId().toString(), publicCustomer.getId().getId().toString(), publicCustomer.getTitle()); ActionType.UPDATED, assignedDashboard .getId().getId().toString(), publicCustomer.getId().getId().toString(), publicCustomer.getTitle());
Dashboard foundDashboard = doGet("/api/dashboard/" + savedDashboard.getId().getId().toString(), Dashboard.class); Dashboard foundDashboard = doGet("/api/dashboard/" + savedDashboard.getId().getId().toString(), Dashboard.class);
Assert.assertTrue(foundDashboard.getAssignedCustomers().contains(publicCustomer.toShortCustomerInfo())); Assert.assertTrue(foundDashboard.getAssignedCustomers().contains(publicCustomer.toShortCustomerInfo()));
@ -253,7 +252,7 @@ public class DashboardControllerTest extends AbstractControllerTest {
testNotifyEntityAllOneTimeLogEntityActionEntityEqClass(assignedDashboard, assignedDashboard.getId(), assignedDashboard.getId(), testNotifyEntityAllOneTimeLogEntityActionEntityEqClass(assignedDashboard, assignedDashboard.getId(), assignedDashboard.getId(),
savedTenant.getId(), publicCustomer.getId(), tenantAdmin.getId(), tenantAdmin.getEmail(), ActionType.UNASSIGNED_FROM_CUSTOMER, savedTenant.getId(), publicCustomer.getId(), tenantAdmin.getId(), tenantAdmin.getEmail(), ActionType.UNASSIGNED_FROM_CUSTOMER,
unassignedDashboard.getId().getId().toString(), publicCustomer.getId().getId().toString(), publicCustomer.getTitle()); ActionType.UPDATED, unassignedDashboard.getId().getId().toString(), publicCustomer.getId().getId().toString(), publicCustomer.getTitle());
Assert.assertTrue(unassignedDashboard.getAssignedCustomers() == null || unassignedDashboard.getAssignedCustomers().isEmpty()); Assert.assertTrue(unassignedDashboard.getAssignedCustomers() == null || unassignedDashboard.getAssignedCustomers().isEmpty());
@ -339,9 +338,9 @@ public class DashboardControllerTest extends AbstractControllerTest {
dashboards.add(new DashboardInfo(doPost("/api/dashboard", dashboard, Dashboard.class))); dashboards.add(new DashboardInfo(doPost("/api/dashboard", dashboard, Dashboard.class)));
} }
testNotifyManyEntityManyTimeMsgToEdgeServiceNever(new Dashboard(), new Dashboard(), testNotifyManyEntityManyTimeMsgToEdgeServiceEntityEqAny(new Dashboard(), new Dashboard(),
savedTenant.getId(), tenantAdmin.getCustomerId(), tenantAdmin.getId(), tenantAdmin.getEmail(), savedTenant.getId(), tenantAdmin.getCustomerId(), tenantAdmin.getId(), tenantAdmin.getEmail(),
ActionType.ADDED, cntEntity); ActionType.ADDED, cntEntity, cntEntity, cntEntity);
List<DashboardInfo> loadedDashboards = new ArrayList<>(); List<DashboardInfo> loadedDashboards = new ArrayList<>();
PageLink pageLink = new PageLink(24); PageLink pageLink = new PageLink(24);
@ -356,8 +355,8 @@ public class DashboardControllerTest extends AbstractControllerTest {
} }
} while (pageData.hasNext()); } while (pageData.hasNext());
Collections.sort(dashboards, idComparator); dashboards.sort(idComparator);
Collections.sort(loadedDashboards, idComparator); loadedDashboards.sort(idComparator);
Assert.assertEquals(dashboards, loadedDashboards); Assert.assertEquals(dashboards, loadedDashboards);
} }
@ -400,8 +399,8 @@ public class DashboardControllerTest extends AbstractControllerTest {
} }
} while (pageData.hasNext()); } while (pageData.hasNext());
Collections.sort(dashboardsTitle1, idComparator); dashboardsTitle1.sort(idComparator);
Collections.sort(loadedDashboardsTitle1, idComparator); loadedDashboardsTitle1.sort(idComparator);
Assert.assertEquals(dashboardsTitle1, loadedDashboardsTitle1); Assert.assertEquals(dashboardsTitle1, loadedDashboardsTitle1);
@ -417,8 +416,8 @@ public class DashboardControllerTest extends AbstractControllerTest {
} }
} while (pageData.hasNext()); } while (pageData.hasNext());
Collections.sort(dashboardsTitle2, idComparator); dashboardsTitle2.sort(idComparator);
Collections.sort(loadedDashboardsTitle2, idComparator); loadedDashboardsTitle2.sort(idComparator);
Assert.assertEquals(dashboardsTitle2, loadedDashboardsTitle2); Assert.assertEquals(dashboardsTitle2, loadedDashboardsTitle2);
@ -429,9 +428,9 @@ public class DashboardControllerTest extends AbstractControllerTest {
.andExpect(status().isOk()); .andExpect(status().isOk());
} }
testNotifyManyEntityManyTimeMsgToEdgeServiceNeverAdditionalInfoAny(new Dashboard(), new Dashboard(), testNotifyManyEntityManyTimeMsgToEdgeServiceEntityEqAnyAdditionalInfoAny(new Dashboard(), new Dashboard(),
savedTenant.getId(), tenantAdmin.getCustomerId(), tenantAdmin.getId(), tenantAdmin.getEmail(), savedTenant.getId(), tenantAdmin.getCustomerId(), tenantAdmin.getId(), tenantAdmin.getEmail(),
ActionType.DELETED, cntEntity, 1); ActionType.DELETED, ActionType.DELETED, cntEntity, cntEntity, 1);
pageLink = new PageLink(4, 0, title1); pageLink = new PageLink(4, 0, title1);
pageData = doGetTypedWithPageLink("/api/tenant/dashboards?", pageData = doGetTypedWithPageLink("/api/tenant/dashboards?",
@ -474,7 +473,7 @@ public class DashboardControllerTest extends AbstractControllerTest {
testNotifyManyEntityManyTimeMsgToEdgeServiceEntityEqAny(new Dashboard(), new Dashboard(), testNotifyManyEntityManyTimeMsgToEdgeServiceEntityEqAny(new Dashboard(), new Dashboard(),
savedTenant.getId(), tenantAdmin.getCustomerId(), tenantAdmin.getId(), tenantAdmin.getEmail(), savedTenant.getId(), tenantAdmin.getCustomerId(), tenantAdmin.getId(), tenantAdmin.getEmail(),
ActionType.ADDED, ActionType.ASSIGNED_TO_CUSTOMER, cntEntity, cntEntity, cntEntity*2); ActionType.ADDED, cntEntity, cntEntity, cntEntity*2);
List<DashboardInfo> loadedDashboards = new ArrayList<>(); List<DashboardInfo> loadedDashboards = new ArrayList<>();
PageLink pageLink = new PageLink(21); PageLink pageLink = new PageLink(21);
@ -489,8 +488,8 @@ public class DashboardControllerTest extends AbstractControllerTest {
} }
} while (pageData.hasNext()); } while (pageData.hasNext());
Collections.sort(dashboards, idComparator); dashboards.sort(idComparator);
Collections.sort(loadedDashboards, idComparator); loadedDashboards.sort(idComparator);
Assert.assertEquals(dashboards, loadedDashboards); Assert.assertEquals(dashboards, loadedDashboards);
} }

47
application/src/test/java/org/thingsboard/server/controller/DeviceControllerTest.java

@ -156,9 +156,8 @@ public class DeviceControllerTest extends AbstractControllerTest {
Device oldDevice = new Device(savedDevice); Device oldDevice = new Device(savedDevice);
testNotifyEntityOneTimeMsgToEdgeServiceNever(savedDevice, savedDevice.getId(), savedDevice.getId(), testNotifyEntityAllOneTime(savedDevice, savedDevice.getId(), savedDevice.getId(), savedTenant.getId(),
savedTenant.getId(), tenantAdmin.getCustomerId(), tenantAdmin.getId(), tenantAdmin.getEmail(), tenantAdmin.getCustomerId(), tenantAdmin.getId(), tenantAdmin.getEmail(), ActionType.ADDED);
ActionType.ADDED);
testNotificationUpdateGatewayNever(); testNotificationUpdateGatewayNever();
Assert.assertNotNull(savedDevice); Assert.assertNotNull(savedDevice);
@ -212,7 +211,7 @@ public class DeviceControllerTest extends AbstractControllerTest {
Device oldDevice = new Device(savedDevice); Device oldDevice = new Device(savedDevice);
testNotifyEntityOneTimeMsgToEdgeServiceNever(savedDevice, savedDevice.getId(), savedDevice.getId(), testNotifyEntityAllOneTime(savedDevice, savedDevice.getId(), savedDevice.getId(),
savedTenant.getId(), tenantAdmin.getCustomerId(), tenantAdmin.getId(), tenantAdmin.getEmail(), savedTenant.getId(), tenantAdmin.getCustomerId(), tenantAdmin.getId(), tenantAdmin.getEmail(),
ActionType.ADDED); ActionType.ADDED);
testNotificationUpdateGatewayNever(); testNotificationUpdateGatewayNever();
@ -436,6 +435,9 @@ public class DeviceControllerTest extends AbstractControllerTest {
@Test @Test
public void testFindDeviceTypesByTenantId() throws Exception { public void testFindDeviceTypesByTenantId() throws Exception {
DeviceProfile deviceProfile = createDeviceProfile("typeB");
deviceProfile = doPost("/api/deviceProfile", deviceProfile, DeviceProfile.class);
List<Device> devices = new ArrayList<>(); List<Device> devices = new ArrayList<>();
int cntEntity = 3; int cntEntity = 3;
@ -446,12 +448,13 @@ public class DeviceControllerTest extends AbstractControllerTest {
Device device = new Device(); Device device = new Device();
device.setName("My device B" + i); device.setName("My device B" + i);
device.setType("typeB"); device.setType("typeB");
device.setDeviceProfileId(deviceProfile.getId());
devices.add(doPost("/api/device", device, Device.class)); devices.add(doPost("/api/device", device, Device.class));
} }
testNotifyManyEntityManyTimeMsgToEdgeServiceNever(new Device(), new Device(), testNotifyManyEntityManyTimeMsgToEdgeServiceEntityEqAny(new Device(), new Device(),
savedTenant.getId(), tenantAdmin.getCustomerId(), tenantAdmin.getId(), tenantAdmin.getEmail(), savedTenant.getId(), tenantAdmin.getCustomerId(), tenantAdmin.getId(), tenantAdmin.getEmail(),
ActionType.ADDED, cntEntity); ActionType.ADDED, cntEntity, cntEntity, cntEntity);
testNotificationUpdateGatewayNever(); testNotificationUpdateGatewayNever();
for (int i = 0; i < 7; i++) { for (int i = 0; i < 7; i++) {
@ -491,7 +494,7 @@ public class DeviceControllerTest extends AbstractControllerTest {
doDelete("/api/device/" + savedDevice.getId().getId()) doDelete("/api/device/" + savedDevice.getId().getId())
.andExpect(status().isOk()); .andExpect(status().isOk());
testNotifyEntityOneTimeMsgToEdgeServiceNever(savedDevice, savedDevice.getId(), savedDevice.getId(), savedTenant.getId(), testNotifyEntityAllOneTime(savedDevice, savedDevice.getId(), savedDevice.getId(), savedTenant.getId(),
tenantAdmin.getCustomerId(), tenantAdmin.getId(), tenantAdmin.getEmail(), ActionType.DELETED, savedDevice.getId().getId().toString()); tenantAdmin.getCustomerId(), tenantAdmin.getId(), tenantAdmin.getEmail(), ActionType.DELETED, savedDevice.getId().getId().toString());
testNotificationDeleteGatewayOneTime(savedDevice); testNotificationDeleteGatewayOneTime(savedDevice);
@ -511,7 +514,7 @@ public class DeviceControllerTest extends AbstractControllerTest {
Device savedDevice = doPost("/api/device", device, Device.class); Device savedDevice = doPost("/api/device", device, Device.class);
Assert.assertEquals("default", savedDevice.getType()); Assert.assertEquals("default", savedDevice.getType());
testNotifyEntityOneTimeMsgToEdgeServiceNever(savedDevice, savedDevice.getId(), savedDevice.getId(), testNotifyEntityAllOneTime(savedDevice, savedDevice.getId(), savedDevice.getId(),
savedTenant.getId(), tenantAdmin.getCustomerId(), tenantAdmin.getId(), tenantAdmin.getEmail(), savedTenant.getId(), tenantAdmin.getCustomerId(), tenantAdmin.getId(), tenantAdmin.getEmail(),
ActionType.ADDED); ActionType.ADDED);
testNotificationUpdateGatewayNever(); testNotificationUpdateGatewayNever();
@ -551,9 +554,9 @@ public class DeviceControllerTest extends AbstractControllerTest {
+ "/device/" + savedDevice.getId().getId(), Device.class); + "/device/" + savedDevice.getId().getId(), Device.class);
Assert.assertEquals(savedCustomer.getId(), assignedDevice.getCustomerId()); Assert.assertEquals(savedCustomer.getId(), assignedDevice.getCustomerId());
testNotifyEntityAllOneTime(assignedDevice, assignedDevice.getId(), assignedDevice.getId(), savedTenant.getId(), testNotifyAssignUnassignEntityAllOneTime(assignedDevice, assignedDevice.getId(), assignedDevice.getId(), savedTenant.getId(),
savedCustomer.getId(), tenantAdmin.getId(), tenantAdmin.getEmail(), ActionType.ASSIGNED_TO_CUSTOMER, savedCustomer.getId(), tenantAdmin.getId(), tenantAdmin.getEmail(), ActionType.ASSIGNED_TO_CUSTOMER,
assignedDevice.getId().getId().toString(), savedCustomer.getId().getId().toString(), ActionType.UPDATED, assignedDevice.getId().getId().toString(), savedCustomer.getId().getId().toString(),
savedCustomer.getTitle()); savedCustomer.getTitle());
testNotificationUpdateGatewayNever(); testNotificationUpdateGatewayNever();
@ -566,9 +569,9 @@ public class DeviceControllerTest extends AbstractControllerTest {
doDelete("/api/customer/device/" + savedDevice.getId().getId(), Device.class); doDelete("/api/customer/device/" + savedDevice.getId().getId(), Device.class);
Assert.assertEquals(ModelConstants.NULL_UUID, unassignedDevice.getCustomerId().getId()); Assert.assertEquals(ModelConstants.NULL_UUID, unassignedDevice.getCustomerId().getId());
testNotifyEntityAllOneTime(unassignedDevice, unassignedDevice.getId(), unassignedDevice.getId(), savedTenant.getId(), testNotifyAssignUnassignEntityAllOneTime(unassignedDevice, unassignedDevice.getId(), unassignedDevice.getId(), savedTenant.getId(),
savedCustomer.getId(), tenantAdmin.getId(), tenantAdmin.getEmail(), ActionType.UNASSIGNED_FROM_CUSTOMER, savedCustomer.getId(), tenantAdmin.getId(), tenantAdmin.getEmail(), ActionType.UNASSIGNED_FROM_CUSTOMER,
unassignedDevice.getId().getId().toString(), savedCustomer.getId().getId().toString(), ActionType.UPDATED, unassignedDevice.getId().getId().toString(), savedCustomer.getId().getId().toString(),
savedCustomer.getTitle()); savedCustomer.getTitle());
testNotificationDeleteGatewayNever(); testNotificationDeleteGatewayNever();
@ -590,9 +593,9 @@ public class DeviceControllerTest extends AbstractControllerTest {
Customer publicCustomer = doGet("/api/customer/" + assignedDevice.getCustomerId(), Customer.class); Customer publicCustomer = doGet("/api/customer/" + assignedDevice.getCustomerId(), Customer.class);
Assert.assertTrue(publicCustomer.isPublic()); Assert.assertTrue(publicCustomer.isPublic());
testNotifyEntityAllOneTime(assignedDevice, assignedDevice.getId(), assignedDevice.getId(), savedTenant.getId(), testNotifyAssignUnassignEntityAllOneTime(assignedDevice, assignedDevice.getId(), assignedDevice.getId(), savedTenant.getId(),
publicCustomer.getId(), tenantAdmin.getId(), tenantAdmin.getEmail(), ActionType.ASSIGNED_TO_CUSTOMER, publicCustomer.getId(), tenantAdmin.getId(), tenantAdmin.getEmail(), ActionType.ASSIGNED_TO_CUSTOMER,
assignedDevice.getId().getId().toString(), publicCustomer.getId().getId().toString(), ActionType.UPDATED, assignedDevice.getId().getId().toString(), publicCustomer.getId().getId().toString(),
publicCustomer.getTitle()); publicCustomer.getTitle());
testNotificationUpdateGatewayNever(); testNotificationUpdateGatewayNever();
@ -605,9 +608,9 @@ public class DeviceControllerTest extends AbstractControllerTest {
doDelete("/api/customer/device/" + savedDevice.getId().getId(), Device.class); doDelete("/api/customer/device/" + savedDevice.getId().getId(), Device.class);
Assert.assertEquals(ModelConstants.NULL_UUID, unassignedDevice.getCustomerId().getId()); Assert.assertEquals(ModelConstants.NULL_UUID, unassignedDevice.getCustomerId().getId());
testNotifyEntityAllOneTime(unassignedDevice, unassignedDevice.getId(), unassignedDevice.getId(), savedTenant.getId(), testNotifyAssignUnassignEntityAllOneTime(unassignedDevice, unassignedDevice.getId(), unassignedDevice.getId(), savedTenant.getId(),
publicCustomer.getId(), tenantAdmin.getId(), tenantAdmin.getEmail(), ActionType.UNASSIGNED_FROM_CUSTOMER, publicCustomer.getId(), tenantAdmin.getId(), tenantAdmin.getEmail(), ActionType.UNASSIGNED_FROM_CUSTOMER,
unassignedDevice.getId().getId().toString(), publicCustomer.getId().getId().toString(), ActionType.UPDATED, unassignedDevice.getId().getId().toString(), publicCustomer.getId().getId().toString(),
publicCustomer.getTitle()); publicCustomer.getTitle());
testNotificationDeleteGatewayNever(); testNotificationDeleteGatewayNever();
@ -842,9 +845,9 @@ public class DeviceControllerTest extends AbstractControllerTest {
List<Device> devices = Futures.allAsList(futures).get(TIMEOUT, TimeUnit.SECONDS); List<Device> devices = Futures.allAsList(futures).get(TIMEOUT, TimeUnit.SECONDS);
testNotifyManyEntityManyTimeMsgToEdgeServiceNever(new Device(), new Device(), testNotifyManyEntityManyTimeMsgToEdgeServiceEntityEqAny(new Device(), new Device(),
savedTenant.getId(), tenantAdmin.getCustomerId(), tenantAdmin.getId(), tenantAdmin.getEmail(), savedTenant.getId(), tenantAdmin.getCustomerId(), tenantAdmin.getId(), tenantAdmin.getEmail(),
ActionType.ADDED, cntEntity); ActionType.ADDED, cntEntity, cntEntity, cntEntity);
testNotificationUpdateGatewayNever(); testNotificationUpdateGatewayNever();
List<Device> loadedDevices = new ArrayList<>(cntEntity); List<Device> loadedDevices = new ArrayList<>(cntEntity);
@ -865,9 +868,9 @@ public class DeviceControllerTest extends AbstractControllerTest {
deleteEntitiesAsync("/api/device/", loadedDevices, executor).get(TIMEOUT, TimeUnit.SECONDS); deleteEntitiesAsync("/api/device/", loadedDevices, executor).get(TIMEOUT, TimeUnit.SECONDS);
testNotifyManyEntityManyTimeMsgToEdgeServiceNeverAdditionalInfoAny(new Device(), new Device(), testNotifyManyEntityManyTimeMsgToEdgeServiceEntityEqAnyAdditionalInfoAny(new Device(), new Device(),
savedTenant.getId(), tenantAdmin.getCustomerId(), tenantAdmin.getId(), tenantAdmin.getEmail(), savedTenant.getId(), tenantAdmin.getCustomerId(), tenantAdmin.getId(), tenantAdmin.getEmail(),
ActionType.DELETED, cntEntity, 1); ActionType.DELETED, ActionType.DELETED, cntEntity, cntEntity,1);
testNotificationUpdateGatewayNever(); testNotificationUpdateGatewayNever();
} }
@ -1052,7 +1055,7 @@ public class DeviceControllerTest extends AbstractControllerTest {
testNotifyManyEntityManyTimeMsgToEdgeServiceEntityEqAny(new Device(), new Device(), testNotifyManyEntityManyTimeMsgToEdgeServiceEntityEqAny(new Device(), new Device(),
savedTenant.getId(), tenantAdmin.getCustomerId(), tenantAdmin.getId(), tenantAdmin.getEmail(), savedTenant.getId(), tenantAdmin.getCustomerId(), tenantAdmin.getId(), tenantAdmin.getEmail(),
ActionType.ADDED, ActionType.ASSIGNED_TO_CUSTOMER, cntEntity, cntEntity, cntEntity * 2); ActionType.ADDED, cntEntity, cntEntity, cntEntity * 2);
Mockito.reset(tbClusterService, auditLogService, gatewayNotificationsService); Mockito.reset(tbClusterService, auditLogService, gatewayNotificationsService);
testNotificationUpdateGatewayNever(); testNotificationUpdateGatewayNever();
Mockito.reset(tbClusterService, auditLogService, gatewayNotificationsService); Mockito.reset(tbClusterService, auditLogService, gatewayNotificationsService);
@ -1074,7 +1077,7 @@ public class DeviceControllerTest extends AbstractControllerTest {
testNotifyManyEntityManyTimeMsgToEdgeServiceEntityEqAnyAdditionalInfoAny(new Device(), new Device(), testNotifyManyEntityManyTimeMsgToEdgeServiceEntityEqAnyAdditionalInfoAny(new Device(), new Device(),
savedTenant.getId(), customerId, tenantAdmin.getId(), tenantAdmin.getEmail(), savedTenant.getId(), customerId, tenantAdmin.getId(), tenantAdmin.getEmail(),
ActionType.UNASSIGNED_FROM_CUSTOMER, ActionType.UNASSIGNED_FROM_CUSTOMER, cntEntity, cntEntity, 3); ActionType.UNASSIGNED_FROM_CUSTOMER, ActionType.UPDATED, cntEntity, cntEntity, 3);
testNotificationUpdateGatewayNever(); testNotificationUpdateGatewayNever();
} }

4
application/src/test/java/org/thingsboard/server/controller/DeviceProfileControllerTest.java

@ -498,7 +498,7 @@ public class DeviceProfileControllerTest extends AbstractControllerTest {
testNotifyManyEntityManyTimeMsgToEdgeServiceEntityEqAny(new DeviceProfile(), new DeviceProfile(), testNotifyManyEntityManyTimeMsgToEdgeServiceEntityEqAny(new DeviceProfile(), new DeviceProfile(),
savedTenant.getId(), tenantAdmin.getCustomerId(), tenantAdmin.getId(), tenantAdmin.getEmail(), savedTenant.getId(), tenantAdmin.getCustomerId(), tenantAdmin.getId(), tenantAdmin.getEmail(),
ActionType.ADDED, ActionType.ADDED, cntEntity, cntEntity, cntEntity); ActionType.ADDED, cntEntity, cntEntity, cntEntity);
Mockito.reset(tbClusterService, auditLogService); Mockito.reset(tbClusterService, auditLogService);
List<DeviceProfile> loadedDeviceProfiles = new ArrayList<>(); List<DeviceProfile> loadedDeviceProfiles = new ArrayList<>();
@ -527,7 +527,7 @@ public class DeviceProfileControllerTest extends AbstractControllerTest {
testNotifyManyEntityManyTimeMsgToEdgeServiceEntityEqAny(loadedDeviceProfiles.get(0), loadedDeviceProfiles.get(0), testNotifyManyEntityManyTimeMsgToEdgeServiceEntityEqAny(loadedDeviceProfiles.get(0), loadedDeviceProfiles.get(0),
savedTenant.getId(), tenantAdmin.getCustomerId(), tenantAdmin.getId(), tenantAdmin.getEmail(), savedTenant.getId(), tenantAdmin.getCustomerId(), tenantAdmin.getId(), tenantAdmin.getEmail(),
ActionType.DELETED, ActionType.DELETED, cntEntity, cntEntity, cntEntity, loadedDeviceProfiles.get(0).getId().getId().toString()); ActionType.DELETED, cntEntity, cntEntity, cntEntity, loadedDeviceProfiles.get(0).getId().getId().toString());
pageLink = new PageLink(17); pageLink = new PageLink(17);
pageData = doGetTypedWithPageLink("/api/deviceProfiles?", pageData = doGetTypedWithPageLink("/api/deviceProfiles?",

294
application/src/test/java/org/thingsboard/server/controller/EdgeControllerTest.java

@ -21,6 +21,7 @@ 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.ListeningExecutorService; import com.google.common.util.concurrent.ListeningExecutorService;
import com.google.common.util.concurrent.MoreExecutors; import com.google.common.util.concurrent.MoreExecutors;
import com.google.protobuf.AbstractMessage;
import org.junit.After; import org.junit.After;
import org.junit.Assert; import org.junit.Assert;
import org.junit.Before; import org.junit.Before;
@ -45,7 +46,6 @@ 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.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.TenantId;
import org.thingsboard.server.common.data.page.PageData; import org.thingsboard.server.common.data.page.PageData;
import org.thingsboard.server.common.data.page.PageLink; import org.thingsboard.server.common.data.page.PageLink;
import org.thingsboard.server.common.data.security.Authority; import org.thingsboard.server.common.data.security.Authority;
@ -62,6 +62,8 @@ import org.thingsboard.server.gen.edge.v1.DeviceProfileUpdateMsg;
import org.thingsboard.server.gen.edge.v1.DeviceUpdateMsg; import org.thingsboard.server.gen.edge.v1.DeviceUpdateMsg;
import org.thingsboard.server.gen.edge.v1.QueueUpdateMsg; import org.thingsboard.server.gen.edge.v1.QueueUpdateMsg;
import org.thingsboard.server.gen.edge.v1.RuleChainUpdateMsg; import org.thingsboard.server.gen.edge.v1.RuleChainUpdateMsg;
import org.thingsboard.server.gen.edge.v1.SyncCompletedMsg;
import org.thingsboard.server.gen.edge.v1.UpdateMsgType;
import org.thingsboard.server.gen.edge.v1.UserCredentialsUpdateMsg; import org.thingsboard.server.gen.edge.v1.UserCredentialsUpdateMsg;
import org.thingsboard.server.gen.edge.v1.UserUpdateMsg; import org.thingsboard.server.gen.edge.v1.UserUpdateMsg;
@ -77,6 +79,7 @@ import static org.thingsboard.server.dao.model.ModelConstants.NULL_UUID;
@TestPropertySource(properties = { @TestPropertySource(properties = {
"edges.enabled=true", "edges.enabled=true",
"queue.rule-engine.stats.enabled=false"
}) })
@ContextConfiguration(classes = {EdgeControllerTest.Config.class}) @ContextConfiguration(classes = {EdgeControllerTest.Config.class})
@DaoSqlTest @DaoSqlTest
@ -87,10 +90,6 @@ public class EdgeControllerTest extends AbstractControllerTest {
private IdComparator<Edge> idComparator = new IdComparator<>(); private IdComparator<Edge> idComparator = new IdComparator<>();
private Tenant savedTenant;
private TenantId tenantId;
private User tenantAdmin;
ListeningExecutorService executor; ListeningExecutorService executor;
List<ListenableFuture<Edge>> futures; List<ListenableFuture<Edge>> futures;
@ -107,35 +106,14 @@ public class EdgeControllerTest extends AbstractControllerTest {
} }
@Before @Before
public void beforeTest() throws Exception { public void setupEdgeTest() throws Exception {
executor = MoreExecutors.listeningDecorator(ThingsBoardExecutors.newWorkStealingPool(8, getClass())); executor = MoreExecutors.listeningDecorator(ThingsBoardExecutors.newWorkStealingPool(8, getClass()));
loginTenantAdmin();
loginSysAdmin();
Tenant tenant = new Tenant();
tenant.setTitle("My tenant for Edge");
savedTenant = doPost("/api/tenant", tenant, Tenant.class);
tenantId = savedTenant.getId();
Assert.assertNotNull(savedTenant);
tenantAdmin = new User();
tenantAdmin.setAuthority(Authority.TENANT_ADMIN);
tenantAdmin.setTenantId(savedTenant.getId());
tenantAdmin.setEmail("tenant2@thingsboard.org");
tenantAdmin.setFirstName("Joe");
tenantAdmin.setLastName("Downs");
tenantAdmin = createUserAndLogin(tenantAdmin, "testPassword1");
} }
@After @After
public void afterTest() throws Exception { public void teardownEdgeTest() throws Exception {
executor.shutdownNow(); executor.shutdownNow();
loginSysAdmin();
doDelete("/api/tenant/" + savedTenant.getId().getId().toString())
.andExpect(status().isOk());
} }
@Test @Test
@ -149,13 +127,13 @@ public class EdgeControllerTest extends AbstractControllerTest {
Assert.assertNotNull(savedEdge); Assert.assertNotNull(savedEdge);
Assert.assertNotNull(savedEdge.getId()); Assert.assertNotNull(savedEdge.getId());
Assert.assertTrue(savedEdge.getCreatedTime() > 0); Assert.assertTrue(savedEdge.getCreatedTime() > 0);
Assert.assertEquals(savedTenant.getId(), savedEdge.getTenantId()); Assert.assertEquals(tenantId, savedEdge.getTenantId());
Assert.assertNotNull(savedEdge.getCustomerId()); Assert.assertNotNull(savedEdge.getCustomerId());
Assert.assertEquals(NULL_UUID, savedEdge.getCustomerId().getId()); Assert.assertEquals(NULL_UUID, savedEdge.getCustomerId().getId());
Assert.assertEquals(edge.getName(), savedEdge.getName()); Assert.assertEquals(edge.getName(), savedEdge.getName());
testNotifyEntityBroadcastEntityStateChangeEventOneTimeMsgToEdgeServiceNever(savedEdge, savedEdge.getId(), savedEdge.getId(), testNotifyEntityBroadcastEntityStateChangeEventOneTimeMsgToEdgeServiceNever(savedEdge, savedEdge.getId(), savedEdge.getId(),
savedTenant.getId(), tenantAdmin.getCustomerId(), tenantAdmin.getId(), tenantAdmin.getEmail(), tenantId, tenantAdminUser.getCustomerId(), tenantAdminUser.getId(), tenantAdminUser.getEmail(),
ActionType.ADDED); ActionType.ADDED);
savedEdge.setName("My new edge"); savedEdge.setName("My new edge");
@ -165,7 +143,7 @@ public class EdgeControllerTest extends AbstractControllerTest {
Assert.assertEquals(foundEdge.getName(), savedEdge.getName()); Assert.assertEquals(foundEdge.getName(), savedEdge.getName());
testNotifyEntityBroadcastEntityStateChangeEventOneTimeMsgToEdgeServiceNever(foundEdge, foundEdge.getId(), foundEdge.getId(), testNotifyEntityBroadcastEntityStateChangeEventOneTimeMsgToEdgeServiceNever(foundEdge, foundEdge.getId(), foundEdge.getId(),
savedTenant.getId(), tenantAdmin.getCustomerId(), tenantAdmin.getId(), tenantAdmin.getEmail(), tenantId, tenantAdminUser.getCustomerId(), tenantAdminUser.getId(), tenantAdminUser.getEmail(),
ActionType.UPDATED); ActionType.UPDATED);
} }
@ -180,8 +158,8 @@ public class EdgeControllerTest extends AbstractControllerTest {
.andExpect(status().isBadRequest()) .andExpect(status().isBadRequest())
.andExpect(statusReason(containsString(msgError))); .andExpect(statusReason(containsString(msgError)));
testNotifyEntityEqualsOneTimeServiceNeverError(edge, savedTenant.getId(), testNotifyEntityEqualsOneTimeServiceNeverError(edge, tenantId,
tenantAdmin.getId(), tenantAdmin.getEmail(), ActionType.ADDED, new DataValidationException(msgError)); tenantAdminUser.getId(), tenantAdminUser.getEmail(), ActionType.ADDED, new DataValidationException(msgError));
Mockito.reset(tbClusterService, auditLogService); Mockito.reset(tbClusterService, auditLogService);
msgError = msgErrorFieldLength("type"); msgError = msgErrorFieldLength("type");
@ -191,8 +169,8 @@ public class EdgeControllerTest extends AbstractControllerTest {
.andExpect(status().isBadRequest()) .andExpect(status().isBadRequest())
.andExpect(statusReason(containsString(msgError))); .andExpect(statusReason(containsString(msgError)));
testNotifyEntityEqualsOneTimeServiceNeverError(edge, savedTenant.getId(), testNotifyEntityEqualsOneTimeServiceNeverError(edge, tenantId,
tenantAdmin.getId(), tenantAdmin.getEmail(), ActionType.ADDED, new DataValidationException(msgError)); tenantAdminUser.getId(), tenantAdminUser.getEmail(), ActionType.ADDED, new DataValidationException(msgError));
Mockito.reset(tbClusterService, auditLogService); Mockito.reset(tbClusterService, auditLogService);
msgError = msgErrorFieldLength("label"); msgError = msgErrorFieldLength("label");
@ -202,8 +180,8 @@ public class EdgeControllerTest extends AbstractControllerTest {
.andExpect(status().isBadRequest()) .andExpect(status().isBadRequest())
.andExpect(statusReason(containsString(msgError))); .andExpect(statusReason(containsString(msgError)));
testNotifyEntityEqualsOneTimeServiceNeverError(edge, savedTenant.getId(), testNotifyEntityEqualsOneTimeServiceNeverError(edge, tenantId,
tenantAdmin.getId(), tenantAdmin.getEmail(), ActionType.ADDED, new DataValidationException(msgError)); tenantAdminUser.getId(), tenantAdminUser.getEmail(), ActionType.ADDED, new DataValidationException(msgError));
} }
@Test @Test
@ -229,7 +207,7 @@ public class EdgeControllerTest extends AbstractControllerTest {
} }
testNotifyManyEntityManyTimeMsgToEdgeServiceNeverAdditionalInfoAny(new Edge(), new Edge(), testNotifyManyEntityManyTimeMsgToEdgeServiceNeverAdditionalInfoAny(new Edge(), new Edge(),
savedTenant.getId(), tenantAdmin.getCustomerId(), tenantAdmin.getId(), tenantAdmin.getEmail(), tenantId, tenantAdminUser.getCustomerId(), tenantAdminUser.getId(), tenantAdminUser.getEmail(),
ActionType.ADDED, cntEntity, 0); ActionType.ADDED, cntEntity, 0);
for (int i = 0; i < 7; i++) { for (int i = 0; i < 7; i++) {
@ -262,7 +240,7 @@ public class EdgeControllerTest extends AbstractControllerTest {
.andExpect(status().isOk()); .andExpect(status().isOk());
testNotifyEntityBroadcastEntityStateChangeEventOneTimeMsgToEdgeServiceNever(savedEdge, savedEdge.getId(), savedEdge.getId(), testNotifyEntityBroadcastEntityStateChangeEventOneTimeMsgToEdgeServiceNever(savedEdge, savedEdge.getId(), savedEdge.getId(),
savedTenant.getId(), tenantAdmin.getCustomerId(), tenantAdmin.getId(), tenantAdmin.getEmail(), tenantId, tenantAdminUser.getCustomerId(), tenantAdminUser.getId(), tenantAdminUser.getEmail(),
ActionType.DELETED, savedEdge.getId().getId().toString()); ActionType.DELETED, savedEdge.getId().getId().toString());
doGet("/api/edge/" + savedEdge.getId().getId().toString()) doGet("/api/edge/" + savedEdge.getId().getId().toString())
@ -281,8 +259,8 @@ public class EdgeControllerTest extends AbstractControllerTest {
.andExpect(status().isBadRequest()) .andExpect(status().isBadRequest())
.andExpect(statusReason(containsString(msgError))); .andExpect(statusReason(containsString(msgError)));
testNotifyEntityEqualsOneTimeServiceNeverError(edge, savedTenant.getId(), testNotifyEntityEqualsOneTimeServiceNeverError(edge, tenantId,
tenantAdmin.getId(), tenantAdmin.getEmail(), ActionType.ADDED, new DataValidationException(msgError)); tenantAdminUser.getId(), tenantAdminUser.getEmail(), ActionType.ADDED, new DataValidationException(msgError));
} }
@Test @Test
@ -296,8 +274,8 @@ public class EdgeControllerTest extends AbstractControllerTest {
.andExpect(status().isBadRequest()) .andExpect(status().isBadRequest())
.andExpect(statusReason(containsString(msgError))); .andExpect(statusReason(containsString(msgError)));
testNotifyEntityEqualsOneTimeServiceNeverError(edge, savedTenant.getId(), testNotifyEntityEqualsOneTimeServiceNeverError(edge, tenantId,
tenantAdmin.getId(), tenantAdmin.getEmail(), ActionType.ADDED, new DataValidationException(msgError)); tenantAdminUser.getId(), tenantAdminUser.getEmail(), ActionType.ADDED, new DataValidationException(msgError));
} }
@Test @Test
@ -316,8 +294,8 @@ public class EdgeControllerTest extends AbstractControllerTest {
Assert.assertEquals(savedCustomer.getId(), assignedEdge.getCustomerId()); Assert.assertEquals(savedCustomer.getId(), assignedEdge.getCustomerId());
testNotifyEntityAllOneTimeLogEntityActionEntityEqClass(assignedEdge, assignedEdge.getId(), assignedEdge.getId(), testNotifyEntityAllOneTimeLogEntityActionEntityEqClass(assignedEdge, assignedEdge.getId(), assignedEdge.getId(),
savedTenant.getId(), savedCustomer.getId(), tenantAdmin.getId(), tenantAdmin.getEmail(), ActionType.ASSIGNED_TO_CUSTOMER, tenantId, savedCustomer.getId(), tenantAdminUser.getId(), tenantAdminUser.getEmail(), ActionType.ASSIGNED_TO_CUSTOMER,
assignedEdge.getId().getId().toString(), savedCustomer.getId().getId().toString(), savedCustomer.getTitle()); ActionType.ASSIGNED_TO_CUSTOMER, assignedEdge.getId().getId().toString(), savedCustomer.getId().getId().toString(), savedCustomer.getTitle());
Edge foundEdge = doGet("/api/edge/" + savedEdge.getId().getId().toString(), Edge.class); Edge foundEdge = doGet("/api/edge/" + savedEdge.getId().getId().toString(), Edge.class);
Assert.assertEquals(savedCustomer.getId(), foundEdge.getCustomerId()); Assert.assertEquals(savedCustomer.getId(), foundEdge.getCustomerId());
@ -327,8 +305,8 @@ public class EdgeControllerTest extends AbstractControllerTest {
Assert.assertEquals(ModelConstants.NULL_UUID, unassignedEdge.getCustomerId().getId()); Assert.assertEquals(ModelConstants.NULL_UUID, unassignedEdge.getCustomerId().getId());
testNotifyEntityAllOneTimeLogEntityActionEntityEqClass(unassignedEdge, unassignedEdge.getId(), unassignedEdge.getId(), testNotifyEntityAllOneTimeLogEntityActionEntityEqClass(unassignedEdge, unassignedEdge.getId(), unassignedEdge.getId(),
savedTenant.getId(), savedCustomer.getId(), tenantAdmin.getId(), tenantAdmin.getEmail(), ActionType.UNASSIGNED_FROM_CUSTOMER, tenantId, savedCustomer.getId(), tenantAdminUser.getId(), tenantAdminUser.getEmail(), ActionType.UNASSIGNED_FROM_CUSTOMER,
unassignedEdge.getId().getId().toString(), savedCustomer.getId().getId().toString(), savedCustomer.getTitle()); ActionType.UNASSIGNED_FROM_CUSTOMER, unassignedEdge.getId().getId().toString(), savedCustomer.getId().getId().toString(), savedCustomer.getTitle());
foundEdge = doGet("/api/edge/" + savedEdge.getId().getId().toString(), Edge.class); foundEdge = doGet("/api/edge/" + savedEdge.getId().getId().toString(), Edge.class);
Assert.assertEquals(ModelConstants.NULL_UUID, foundEdge.getCustomerId().getId()); Assert.assertEquals(ModelConstants.NULL_UUID, foundEdge.getCustomerId().getId());
@ -375,7 +353,7 @@ public class EdgeControllerTest extends AbstractControllerTest {
customer.setTitle("Different customer"); customer.setTitle("Different customer");
Customer savedCustomer = doPost("/api/customer", customer, Customer.class); Customer savedCustomer = doPost("/api/customer", customer, Customer.class);
login(tenantAdmin.getEmail(), "testPassword1"); loginTenantAdmin();
Edge edge = constructEdge("My edge", "default"); Edge edge = constructEdge("My edge", "default");
Edge savedEdge = doPost("/api/edge", edge, Edge.class); Edge savedEdge = doPost("/api/edge", edge, Edge.class);
@ -625,8 +603,8 @@ public class EdgeControllerTest extends AbstractControllerTest {
List<Edge> edges = new ArrayList<>(Futures.allAsList(futures).get(TIMEOUT, TimeUnit.SECONDS)); List<Edge> edges = new ArrayList<>(Futures.allAsList(futures).get(TIMEOUT, TimeUnit.SECONDS));
testNotifyManyEntityManyTimeMsgToEdgeServiceEntityEqAny(new Edge(), new Edge(), testNotifyManyEntityManyTimeMsgToEdgeServiceEntityEqAny(new Edge(), new Edge(),
savedTenant.getId(), customerId, tenantAdmin.getId(), tenantAdmin.getEmail(), tenantId, customerId, tenantAdminUser.getId(), tenantAdminUser.getEmail(),
ActionType.ASSIGNED_TO_CUSTOMER, ActionType.ASSIGNED_TO_CUSTOMER, cntEntity, cntEntity, cntEntity * 2, ActionType.ASSIGNED_TO_CUSTOMER, cntEntity, cntEntity, cntEntity * 2,
new String(), new String(), new String()); new String(), new String(), new String());
List<Edge> loadedEdges = new ArrayList<>(); List<Edge> loadedEdges = new ArrayList<>();
@ -731,7 +709,7 @@ public class EdgeControllerTest extends AbstractControllerTest {
cntEntity = loadedEdgesTitle1.size(); cntEntity = loadedEdgesTitle1.size();
testNotifyManyEntityManyTimeMsgToEdgeServiceEntityEqAnyAdditionalInfoAny(new Edge(), new Edge(), testNotifyManyEntityManyTimeMsgToEdgeServiceEntityEqAnyAdditionalInfoAny(new Edge(), new Edge(),
savedTenant.getId(), customerId, tenantAdmin.getId(), tenantAdmin.getEmail(), tenantId, customerId, tenantAdminUser.getId(), tenantAdminUser.getEmail(),
ActionType.UNASSIGNED_FROM_CUSTOMER, ActionType.UNASSIGNED_FROM_CUSTOMER, cntEntity, cntEntity, 3); ActionType.UNASSIGNED_FROM_CUSTOMER, ActionType.UNASSIGNED_FROM_CUSTOMER, cntEntity, cntEntity, 3);
pageLink = new PageLink(4, 0, title1); pageLink = new PageLink(4, 0, title1);
@ -857,56 +835,45 @@ public class EdgeControllerTest extends AbstractControllerTest {
@Test @Test
public void testSyncEdge() throws Exception { public void testSyncEdge() throws Exception {
Edge edge = doPost("/api/edge", constructEdge("Test Sync Edge", "test"), Edge.class); Asset asset = new Asset();
asset.setName("Test Sync Edge Asset 1");
asset.setType("test");
Asset savedAsset = doPost("/api/asset", asset, Asset.class);
Device device = new Device(); Device device = new Device();
device.setName("Test Sync Edge Device 1"); device.setName("Test Sync Edge Device 1");
device.setType("default"); device.setType("default");
Device savedDevice = doPost("/api/device", device, Device.class); Device savedDevice = doPost("/api/device", device, Device.class);
Edge edge = doPost("/api/edge", constructEdge("Test Sync Edge", "test"), Edge.class);
doPost("/api/edge/" + edge.getId().getId().toString() doPost("/api/edge/" + edge.getId().getId().toString()
+ "/device/" + savedDevice.getId().getId().toString(), Device.class); + "/device/" + savedDevice.getId().getId().toString(), Device.class);
Asset asset = new Asset();
asset.setName("Test Sync Edge Asset 1");
asset.setType("test");
Asset savedAsset = doPost("/api/asset", asset, Asset.class);
doPost("/api/edge/" + edge.getId().getId().toString() doPost("/api/edge/" + edge.getId().getId().toString()
+ "/asset/" + savedAsset.getId().getId().toString(), Asset.class); + "/asset/" + savedAsset.getId().getId().toString(), Asset.class);
EdgeImitator edgeImitator = new EdgeImitator(EDGE_HOST, EDGE_PORT, edge.getRoutingKey(), edge.getSecret()); EdgeImitator edgeImitator = new EdgeImitator(EDGE_HOST, EDGE_PORT, edge.getRoutingKey(), edge.getSecret());
edgeImitator.ignoreType(UserCredentialsUpdateMsg.class); edgeImitator.ignoreType(UserCredentialsUpdateMsg.class);
edgeImitator.expectMessageAmount(20); edgeImitator.expectMessageAmount(21);
edgeImitator.connect(); edgeImitator.connect();
assertThat(edgeImitator.waitForMessages()).as("await for messages on first connect").isTrue(); assertThat(edgeImitator.waitForMessages()).as("await for messages on first connect").isTrue();
assertThat(edgeImitator.findAllMessagesByType(QueueUpdateMsg.class)).as("one msg during sync process").hasSize(1); verifyFetchersMsgs(edgeImitator);
List<RuleChainUpdateMsg> ruleChainUpdateMsgs = edgeImitator.findAllMessagesByType(RuleChainUpdateMsg.class); // verify queue msgs
assertThat(ruleChainUpdateMsgs).as("one msg during sync process, another from edge creation").hasSize(2); Assert.assertTrue(popRuleChainMsg(edgeImitator.getDownlinkMsgs(), UpdateMsgType.ENTITY_UPDATED_RPC_MESSAGE, "Edge Root Rule Chain"));
assertThat(edgeImitator.findAllMessagesByType(DeviceProfileUpdateMsg.class)).as("one msg during sync process for 'default' device profile").hasSize(3); Assert.assertTrue(popDeviceProfileMsg(edgeImitator.getDownlinkMsgs(), UpdateMsgType.ENTITY_CREATED_RPC_MESSAGE, "default"));
assertThat(edgeImitator.findAllMessagesByType(DeviceUpdateMsg.class)).as("one msg once device assigned to edge").hasSize(2); Assert.assertTrue(popDeviceMsg(edgeImitator.getDownlinkMsgs(), UpdateMsgType.ENTITY_CREATED_RPC_MESSAGE, "Test Sync Edge Device 1"));
assertThat(edgeImitator.findAllMessagesByType(AssetProfileUpdateMsg.class)).as("two msgs during sync process for 'default' and 'test' asset profiles").hasSize(4); Assert.assertTrue(popAssetProfileMsg(edgeImitator.getDownlinkMsgs(), UpdateMsgType.ENTITY_CREATED_RPC_MESSAGE, "test"));
assertThat(edgeImitator.findAllMessagesByType(AssetUpdateMsg.class)).as("two msgs - one during sync process, and one more once asset assigned to edge").hasSize(2); Assert.assertTrue(popAssetMsg(edgeImitator.getDownlinkMsgs(), UpdateMsgType.ENTITY_CREATED_RPC_MESSAGE, "Test Sync Edge Asset 1"));
assertThat(edgeImitator.findAllMessagesByType(UserUpdateMsg.class)).as("one msg during sync process for tenant admin user").hasSize(1); Assert.assertTrue(edgeImitator.getDownlinkMsgs().isEmpty());
assertThat(edgeImitator.findAllMessagesByType(AdminSettingsUpdateMsg.class)).as("admin setting update").hasSize(4);
assertThat(edgeImitator.findAllMessagesByType(CustomerUpdateMsg.class)).as("one msg during sync process for 'Public' customer").hasSize(1); edgeImitator.expectMessageAmount(16);
verifyRuleChainMsgsAreRoot(ruleChainUpdateMsgs);
edgeImitator.expectMessageAmount(15);
doPost("/api/edge/sync/" + edge.getId()); doPost("/api/edge/sync/" + edge.getId());
assertThat(edgeImitator.waitForMessages()).as("await for messages after edge sync rest api call").isTrue(); assertThat(edgeImitator.waitForMessages()).as("await for messages after edge sync rest api call").isTrue();
assertThat(edgeImitator.findAllMessagesByType(QueueUpdateMsg.class)).as("queue msg").hasSize(1); verifyFetchersMsgs(edgeImitator);
ruleChainUpdateMsgs = edgeImitator.findAllMessagesByType(RuleChainUpdateMsg.class); Assert.assertTrue(edgeImitator.getDownlinkMsgs().isEmpty());
assertThat(ruleChainUpdateMsgs).as("rule chain msg").hasSize(1);
assertThat(edgeImitator.findAllMessagesByType(DeviceProfileUpdateMsg.class)).as("device profile msg").hasSize(2);
assertThat(edgeImitator.findAllMessagesByType(AssetProfileUpdateMsg.class)).as("asset profile msg").hasSize(3);
assertThat(edgeImitator.findAllMessagesByType(AssetUpdateMsg.class)).as("asset update msg").hasSize(1);
assertThat(edgeImitator.findAllMessagesByType(UserUpdateMsg.class)).as("user update msg").hasSize(1);
assertThat(edgeImitator.findAllMessagesByType(AdminSettingsUpdateMsg.class)).as("admin setting update msg").hasSize(4);
assertThat(edgeImitator.findAllMessagesByType(DeviceUpdateMsg.class)).as("asset update msg").hasSize(1);
assertThat(edgeImitator.findAllMessagesByType(CustomerUpdateMsg.class)).as("one msg during sync process for 'Public' customer").hasSize(1);
verifyRuleChainMsgsAreRoot(ruleChainUpdateMsgs);
edgeImitator.allowIgnoredTypes(); edgeImitator.allowIgnoredTypes();
try { try {
@ -922,23 +889,174 @@ public class EdgeControllerTest extends AbstractControllerTest {
.andExpect(status().isOk()); .andExpect(status().isOk());
} }
private void verifyRuleChainMsgsAreRoot(List<RuleChainUpdateMsg> ruleChainUpdateMsgs) { private void verifyFetchersMsgs(EdgeImitator edgeImitator) {
for (RuleChainUpdateMsg ruleChainUpdateMsg : ruleChainUpdateMsgs) { Assert.assertTrue(popQueueMsg(edgeImitator.getDownlinkMsgs(), UpdateMsgType.ENTITY_CREATED_RPC_MESSAGE, "Main"));
Assert.assertTrue(ruleChainUpdateMsg.getRoot()); Assert.assertTrue(popRuleChainMsg(edgeImitator.getDownlinkMsgs(), UpdateMsgType.ENTITY_CREATED_RPC_MESSAGE, "Edge Root Rule Chain"));
Assert.assertTrue(popAdminSettingsMsg(edgeImitator.getDownlinkMsgs(), "mail", true));
Assert.assertTrue(popAdminSettingsMsg(edgeImitator.getDownlinkMsgs(), "mail", false));
Assert.assertTrue(popAdminSettingsMsg(edgeImitator.getDownlinkMsgs(), "mailTemplates", true));
Assert.assertTrue(popAdminSettingsMsg(edgeImitator.getDownlinkMsgs(), "mailTemplates", false));
Assert.assertTrue(popDeviceProfileMsg(edgeImitator.getDownlinkMsgs(), UpdateMsgType.ENTITY_CREATED_RPC_MESSAGE, "default"));
Assert.assertTrue(popAssetProfileMsg(edgeImitator.getDownlinkMsgs(), UpdateMsgType.ENTITY_CREATED_RPC_MESSAGE, "default"));
Assert.assertTrue(popAssetProfileMsg(edgeImitator.getDownlinkMsgs(), UpdateMsgType.ENTITY_CREATED_RPC_MESSAGE, "test"));
Assert.assertTrue(popUserMsg(edgeImitator.getDownlinkMsgs(), UpdateMsgType.ENTITY_CREATED_RPC_MESSAGE, TENANT_ADMIN_EMAIL, Authority.TENANT_ADMIN));
Assert.assertTrue(popCustomerMsg(edgeImitator.getDownlinkMsgs(), UpdateMsgType.ENTITY_CREATED_RPC_MESSAGE, "Public"));
Assert.assertTrue(popDeviceProfileMsg(edgeImitator.getDownlinkMsgs(), UpdateMsgType.ENTITY_CREATED_RPC_MESSAGE, "default"));
Assert.assertTrue(popDeviceMsg(edgeImitator.getDownlinkMsgs(), UpdateMsgType.ENTITY_CREATED_RPC_MESSAGE, "Test Sync Edge Device 1"));
Assert.assertTrue(popAssetProfileMsg(edgeImitator.getDownlinkMsgs(), UpdateMsgType.ENTITY_CREATED_RPC_MESSAGE, "test"));
Assert.assertTrue(popAssetMsg(edgeImitator.getDownlinkMsgs(), UpdateMsgType.ENTITY_CREATED_RPC_MESSAGE, "Test Sync Edge Asset 1"));
Assert.assertTrue(popSyncCompletedMsg(edgeImitator.getDownlinkMsgs()));
}
private boolean popQueueMsg(List<AbstractMessage> messages, UpdateMsgType msgType, String name) {
for (AbstractMessage message : messages) {
if (message instanceof QueueUpdateMsg) {
QueueUpdateMsg queueUpdateMsg = (QueueUpdateMsg) message;
if (msgType.equals(queueUpdateMsg.getMsgType())
&& name.equals(queueUpdateMsg.getName())) {
messages.remove(message);
return true;
}
}
}
return false;
}
private boolean popRuleChainMsg(List<AbstractMessage> messages, UpdateMsgType msgType, String name) {
for (AbstractMessage message : messages) {
if (message instanceof RuleChainUpdateMsg) {
RuleChainUpdateMsg ruleChainUpdateMsg = (RuleChainUpdateMsg) message;
if (msgType.equals(ruleChainUpdateMsg.getMsgType())
&& name.equals(ruleChainUpdateMsg.getName())
&& ruleChainUpdateMsg.getRoot()) {
messages.remove(message);
return true;
}
}
}
return false;
}
private boolean popAdminSettingsMsg(List<AbstractMessage> messages, String key, boolean isSystem) {
for (AbstractMessage message : messages) {
if (message instanceof AdminSettingsUpdateMsg) {
AdminSettingsUpdateMsg adminSettingsUpdateMsg = (AdminSettingsUpdateMsg) message;
if (key.equals(adminSettingsUpdateMsg.getKey())
&& isSystem == adminSettingsUpdateMsg.getIsSystem()) {
messages.remove(message);
return true;
}
}
}
return false;
}
private boolean popDeviceProfileMsg(List<AbstractMessage> messages, UpdateMsgType msgType, String name) {
for (AbstractMessage message : messages) {
if (message instanceof DeviceProfileUpdateMsg) {
DeviceProfileUpdateMsg deviceProfileUpdateMsg = (DeviceProfileUpdateMsg) message;
if (msgType.equals(deviceProfileUpdateMsg.getMsgType())
&& name.equals(deviceProfileUpdateMsg.getName())) {
messages.remove(message);
return true;
}
}
}
return false;
}
private boolean popDeviceMsg(List<AbstractMessage> messages, UpdateMsgType msgType, String name) {
for (AbstractMessage message : messages) {
if (message instanceof DeviceUpdateMsg) {
DeviceUpdateMsg deviceUpdateMsg = (DeviceUpdateMsg) message;
if (msgType.equals(deviceUpdateMsg.getMsgType())
&& name.equals(deviceUpdateMsg.getName())) {
messages.remove(message);
return true;
}
}
}
return false;
}
private boolean popAssetProfileMsg(List<AbstractMessage> messages, UpdateMsgType msgType, String name) {
for (AbstractMessage message : messages) {
if (message instanceof AssetProfileUpdateMsg) {
AssetProfileUpdateMsg assetProfileUpdateMsg = (AssetProfileUpdateMsg) message;
if (msgType.equals(assetProfileUpdateMsg.getMsgType())
&& name.equals(assetProfileUpdateMsg.getName())) {
messages.remove(message);
return true;
}
}
}
return false;
}
private boolean popAssetMsg(List<AbstractMessage> messages, UpdateMsgType msgType, String name) {
for (AbstractMessage message : messages) {
if (message instanceof AssetUpdateMsg) {
AssetUpdateMsg assetUpdateMsg = (AssetUpdateMsg) message;
if (msgType.equals(assetUpdateMsg.getMsgType())
&& name.equals(assetUpdateMsg.getName())) {
messages.remove(message);
return true;
}
}
}
return false;
}
private boolean popUserMsg(List<AbstractMessage> messages, UpdateMsgType msgType, String email, Authority authority) {
for (AbstractMessage message : messages) {
if (message instanceof UserUpdateMsg) {
UserUpdateMsg userUpdateMsg = (UserUpdateMsg) message;
if (msgType.equals(userUpdateMsg.getMsgType())
&& email.equals(userUpdateMsg.getEmail())
&& authority.name().equals(userUpdateMsg.getAuthority())) {
messages.remove(message);
return true;
}
}
}
return false;
}
private boolean popCustomerMsg(List<AbstractMessage> messages, UpdateMsgType msgType, String title) {
for (AbstractMessage message : messages) {
if (message instanceof CustomerUpdateMsg) {
CustomerUpdateMsg customerUpdateMsg = (CustomerUpdateMsg) message;
if (msgType.equals(customerUpdateMsg.getMsgType())
&& title.equals(customerUpdateMsg.getTitle())) {
messages.remove(message);
return true;
}
}
}
return false;
}
private boolean popSyncCompletedMsg(List<AbstractMessage> messages) {
for (AbstractMessage message : messages) {
if (message instanceof SyncCompletedMsg) {
messages.remove(message);
return true;
}
} }
return false;
} }
@Test @Test
public void testDeleteEdgeWithDeleteRelationsOk() throws Exception { public void testDeleteEdgeWithDeleteRelationsOk() throws Exception {
EdgeId edgeId = savedEdge("Edge for Test WithRelationsOk").getId(); EdgeId edgeId = savedEdge("Edge for Test WithRelationsOk").getId();
testEntityDaoWithRelationsOk(savedTenant.getId(), edgeId, "/api/edge/" + edgeId); testEntityDaoWithRelationsOk(tenantId, edgeId, "/api/edge/" + edgeId);
} }
@Ignore @Ignore
@Test @Test
public void testDeleteEdgeExceptionWithRelationsTransactional() throws Exception { public void testDeleteEdgeExceptionWithRelationsTransactional() throws Exception {
EdgeId edgeId = savedEdge("Edge for Test WithRelations Transactional Exception").getId(); EdgeId edgeId = savedEdge("Edge for Test WithRelations Transactional Exception").getId();
testEntityDaoWithRelationsTransactionalException(edgeDao, savedTenant.getId(), edgeId, "/api/edge/" + edgeId); testEntityDaoWithRelationsTransactionalException(edgeDao, tenantId, edgeId, "/api/edge/" + edgeId);
} }
private Edge savedEdge(String name) { private Edge savedEdge(String name) {

64
application/src/test/java/org/thingsboard/server/controller/EdgeEventControllerTest.java

@ -27,8 +27,6 @@ import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.test.mock.mockito.SpyBean; import org.springframework.boot.test.mock.mockito.SpyBean;
import org.springframework.test.context.TestPropertySource; import org.springframework.test.context.TestPropertySource;
import org.thingsboard.server.common.data.Device; import org.thingsboard.server.common.data.Device;
import org.thingsboard.server.common.data.Tenant;
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.edge.Edge;
import org.thingsboard.server.common.data.edge.EdgeEvent; import org.thingsboard.server.common.data.edge.EdgeEvent;
@ -38,7 +36,6 @@ import org.thingsboard.server.common.data.id.EdgeId;
import org.thingsboard.server.common.data.page.PageData; import org.thingsboard.server.common.data.page.PageData;
import org.thingsboard.server.common.data.page.TimePageLink; import org.thingsboard.server.common.data.page.TimePageLink;
import org.thingsboard.server.common.data.relation.EntityRelation; import org.thingsboard.server.common.data.relation.EntityRelation;
import org.thingsboard.server.common.data.security.Authority;
import org.thingsboard.server.dao.edge.EdgeEventDao; import org.thingsboard.server.dao.edge.EdgeEventDao;
import org.thingsboard.server.dao.service.DaoSqlTest; import org.thingsboard.server.dao.service.DaoSqlTest;
import org.thingsboard.server.dao.sqlts.insert.sql.SqlPartitioningRepository; import org.thingsboard.server.dao.sqlts.insert.sql.SqlPartitioningRepository;
@ -54,18 +51,15 @@ import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.ArgumentMatchers.eq; import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.reset; import static org.mockito.Mockito.reset;
import static org.mockito.Mockito.verify; import static org.mockito.Mockito.verify;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
@TestPropertySource(properties = { @TestPropertySource(properties = {
"edges.enabled=true", "edges.enabled=true",
"queue.rule-engine.stats.enabled=false"
}) })
@Slf4j @Slf4j
@DaoSqlTest @DaoSqlTest
public class EdgeEventControllerTest extends AbstractControllerTest { public class EdgeEventControllerTest extends AbstractControllerTest {
private Tenant savedTenant;
private User tenantAdmin;
@Autowired @Autowired
private EdgeEventDao edgeEventDao; private EdgeEventDao edgeEventDao;
@SpyBean @SpyBean
@ -80,33 +74,11 @@ public class EdgeEventControllerTest extends AbstractControllerTest {
@Before @Before
public void beforeTest() throws Exception { public void beforeTest() throws Exception {
loginSysAdmin(); loginTenantAdmin();
Tenant tenant = new Tenant();
tenant.setTitle("My tenant");
savedTenant = doPost("/api/tenant", tenant, Tenant.class);
Assert.assertNotNull(savedTenant);
tenantAdmin = new User();
tenantAdmin.setAuthority(Authority.TENANT_ADMIN);
tenantAdmin.setTenantId(savedTenant.getId());
tenantAdmin.setEmail("tenant2@thingsboard.org");
tenantAdmin.setFirstName("Joe");
tenantAdmin.setLastName("Downs");
tenantAdmin = createUserAndLogin(tenantAdmin, "testPassword1");
// sleep 1 seconds to avoid CREDENTIALS updated message for the user
// user credentials is going to be stored and updated event pushed to edge notification service
// while service will be processing this event edge could be already added and additional message will be pushed
Thread.sleep(1000);
} }
@After @After
public void afterTest() throws Exception { public void afterTest() throws Exception {
loginSysAdmin();
doDelete("/api/tenant/" + savedTenant.getId().getId().toString())
.andExpect(status().isOk());
} }
@Test @Test
@ -127,19 +99,37 @@ public class EdgeEventControllerTest extends AbstractControllerTest {
EntityRelation relation = new EntityRelation(savedAsset.getId(), savedDevice.getId(), EntityRelation.CONTAINS_TYPE); EntityRelation relation = new EntityRelation(savedAsset.getId(), savedDevice.getId(), EntityRelation.CONTAINS_TYPE);
awaitForNumberOfEdgeEvents(edgeId, 3);
doPost("/api/relation", relation); doPost("/api/relation", relation);
awaitForNumberOfEdgeEvents(edgeId, 4);
List<EdgeEvent> edgeEvents = findEdgeEvents(edgeId);
Assert.assertTrue(popEdgeEvent(edgeEvents, EdgeEventType.RULE_CHAIN)); // root rule chain
Assert.assertTrue(popEdgeEvent(edgeEvents, EdgeEventType.DEVICE)); // TestDevice
Assert.assertTrue(popEdgeEvent(edgeEvents, EdgeEventType.ASSET)); // TestAsset
Assert.assertTrue(popEdgeEvent(edgeEvents, EdgeEventType.RELATION));
Assert.assertTrue(edgeEvents.isEmpty());
}
private boolean popEdgeEvent(List<EdgeEvent> edgeEvents, EdgeEventType edgeEventType) {
for (EdgeEvent edgeEvent : edgeEvents) {
if (edgeEventType.equals(edgeEvent.getType())) {
edgeEvents.remove(edgeEvent);
return true;
}
}
return false;
}
private void awaitForNumberOfEdgeEvents(EdgeId edgeId, int expectedNumber) {
Awaitility.await() Awaitility.await()
.atMost(30, TimeUnit.SECONDS) .atMost(30, TimeUnit.SECONDS)
.until(() -> { .until(() -> {
List<EdgeEvent> edgeEvents = findEdgeEvents(edgeId); List<EdgeEvent> edgeEvents = findEdgeEvents(edgeId);
return edgeEvents.size() == 4; return edgeEvents.size() == expectedNumber;
}); });
List<EdgeEvent> edgeEvents = findEdgeEvents(edgeId);
Assert.assertTrue(edgeEvents.stream().anyMatch(ee -> EdgeEventType.RULE_CHAIN.equals(ee.getType())));
Assert.assertTrue(edgeEvents.stream().anyMatch(ee -> EdgeEventType.DEVICE.equals(ee.getType())));
Assert.assertTrue(edgeEvents.stream().anyMatch(ee -> EdgeEventType.ASSET.equals(ee.getType())));
Assert.assertTrue(edgeEvents.stream().anyMatch(ee -> EdgeEventType.RELATION.equals(ee.getType())));
} }
@Test @Test
@ -195,7 +185,7 @@ public class EdgeEventControllerTest extends AbstractControllerTest {
edgeEvent.setCreatedTime(System.currentTimeMillis()); edgeEvent.setCreatedTime(System.currentTimeMillis());
edgeEvent.setTenantId(tenantId); edgeEvent.setTenantId(tenantId);
edgeEvent.setAction(EdgeEventActionType.ADDED); edgeEvent.setAction(EdgeEventActionType.ADDED);
edgeEvent.setEntityId(tenantAdmin.getUuidId()); edgeEvent.setEntityId(tenantAdminUser.getUuidId());
edgeEvent.setType(EdgeEventType.ALARM); edgeEvent.setType(EdgeEventType.ALARM);
try { try {
edgeEventDao.saveAsync(edgeEvent).get(); edgeEventDao.saveAsync(edgeEvent).get();

33
application/src/test/java/org/thingsboard/server/controller/EntityViewControllerTest.java

@ -43,6 +43,7 @@ import org.springframework.test.web.servlet.ResultActions;
import org.thingsboard.common.util.ThingsBoardExecutors; import org.thingsboard.common.util.ThingsBoardExecutors;
import org.thingsboard.server.common.data.Customer; import org.thingsboard.server.common.data.Customer;
import org.thingsboard.server.common.data.Device; import org.thingsboard.server.common.data.Device;
import org.thingsboard.server.common.data.EntityType;
import org.thingsboard.server.common.data.EntityView; import org.thingsboard.server.common.data.EntityView;
import org.thingsboard.server.common.data.EntityViewInfo; import org.thingsboard.server.common.data.EntityViewInfo;
import org.thingsboard.server.common.data.StringUtils; import org.thingsboard.server.common.data.StringUtils;
@ -170,7 +171,7 @@ public class EntityViewControllerTest extends AbstractControllerTest {
testBroadcastEntityStateChangeEventTime(foundEntityView.getId(), tenantId, 1); testBroadcastEntityStateChangeEventTime(foundEntityView.getId(), tenantId, 1);
testNotifyManyEntityManyTimeMsgToEdgeServiceEntityEqAny(foundEntityView, foundEntityView, testNotifyManyEntityManyTimeMsgToEdgeServiceEntityEqAny(foundEntityView, foundEntityView,
tenantId, tenantAdminCustomerId, tenantAdminUserId, TENANT_ADMIN_EMAIL, tenantId, tenantAdminCustomerId, tenantAdminUserId, TENANT_ADMIN_EMAIL,
ActionType.ADDED, ActionType.ADDED, 1, 0, 1); ActionType.ADDED, 1, 1, 1);
Mockito.reset(tbClusterService, auditLogService); Mockito.reset(tbClusterService, auditLogService);
savedView.setName("New test entity view"); savedView.setName("New test entity view");
@ -183,7 +184,7 @@ public class EntityViewControllerTest extends AbstractControllerTest {
testBroadcastEntityStateChangeEventTime(foundEntityView.getId(), tenantId, 1); testBroadcastEntityStateChangeEventTime(foundEntityView.getId(), tenantId, 1);
testNotifyManyEntityManyTimeMsgToEdgeServiceEntityEqAny(foundEntityView, foundEntityView, testNotifyManyEntityManyTimeMsgToEdgeServiceEntityEqAny(foundEntityView, foundEntityView,
tenantId, tenantAdminCustomerId, tenantAdminUserId, TENANT_ADMIN_EMAIL, tenantId, tenantAdminCustomerId, tenantAdminUserId, TENANT_ADMIN_EMAIL,
ActionType.UPDATED, ActionType.UPDATED, 1, 1, 5); ActionType.UPDATED, 1, 1, 5);
doGet("/api/tenant/entityViews?entityViewName=" + name) doGet("/api/tenant/entityViews?entityViewName=" + name)
.andExpect(status().isNotFound()) .andExpect(status().isNotFound())
@ -247,13 +248,13 @@ public class EntityViewControllerTest extends AbstractControllerTest {
doDelete("/api/entityView/" + entityIdStr) doDelete("/api/entityView/" + entityIdStr)
.andExpect(status().isOk()); .andExpect(status().isOk());
testNotifyEntityBroadcastEntityStateChangeEventOneTimeMsgToEdgeServiceNever(savedView, savedView.getId(), savedView.getId(), testNotifyEntityBroadcastEntityStateChangeEventOneTime(savedView, savedView.getId(), savedView.getId(),
tenantId, view.getCustomerId(), tenantAdminUserId, TENANT_ADMIN_EMAIL, tenantId, view.getCustomerId(), tenantAdminUserId, TENANT_ADMIN_EMAIL,
ActionType.DELETED, entityIdStr); ActionType.DELETED, entityIdStr);
doGet("/api/entityView/" + entityIdStr) doGet("/api/entityView/" + entityIdStr)
.andExpect(status().isNotFound()) .andExpect(status().isNotFound())
.andExpect(statusReason(containsString(msgErrorNoFound("Entity view",entityIdStr)))); .andExpect(statusReason(containsString(msgErrorNoFound(EntityType.ENTITY_VIEW.getNormalName(), entityIdStr))));
} }
@Test @Test
@ -286,7 +287,7 @@ public class EntityViewControllerTest extends AbstractControllerTest {
testBroadcastEntityStateChangeEventTime(savedView.getId(), tenantId, 1); testBroadcastEntityStateChangeEventTime(savedView.getId(), tenantId, 1);
testNotifyManyEntityManyTimeMsgToEdgeServiceEntityEqAny(savedView, savedView, testNotifyManyEntityManyTimeMsgToEdgeServiceEntityEqAny(savedView, savedView,
tenantId, tenantAdminCustomerId, tenantAdminUserId, TENANT_ADMIN_EMAIL, tenantId, tenantAdminCustomerId, tenantAdminUserId, TENANT_ADMIN_EMAIL,
ActionType.UPDATED, ActionType.UPDATED, 1, 1, 5); ActionType.UPDATED, 1, 1, 5);
Mockito.reset(tbClusterService, auditLogService); Mockito.reset(tbClusterService, auditLogService);
EntityView assignedView = doPost( EntityView assignedView = doPost(
@ -298,9 +299,9 @@ public class EntityViewControllerTest extends AbstractControllerTest {
assertEquals(savedCustomer.getId(), foundView.getCustomerId()); assertEquals(savedCustomer.getId(), foundView.getCustomerId());
testBroadcastEntityStateChangeEventNever(foundView.getId()); testBroadcastEntityStateChangeEventNever(foundView.getId());
testNotifyEntityAllOneTime(foundView, foundView.getId(), foundView.getId(), testNotifyAssignUnassignEntityAllOneTime(foundView, foundView.getId(), foundView.getId(),
tenantId, foundView.getCustomerId(), tenantAdminUserId, TENANT_ADMIN_EMAIL, tenantId, foundView.getCustomerId(), tenantAdminUserId, TENANT_ADMIN_EMAIL,
ActionType.ASSIGNED_TO_CUSTOMER, ActionType.ASSIGNED_TO_CUSTOMER, ActionType.UPDATED,
foundView.getId().getId().toString(), foundView.getCustomerId().getId().toString(), savedCustomer.getTitle()); foundView.getId().getId().toString(), foundView.getCustomerId().getId().toString(), savedCustomer.getTitle());
EntityView unAssignedView = doDelete("/api/customer/entityView/" + savedView.getId().getId().toString(), EntityView.class); EntityView unAssignedView = doDelete("/api/customer/entityView/" + savedView.getId().getId().toString(), EntityView.class);
@ -310,9 +311,9 @@ public class EntityViewControllerTest extends AbstractControllerTest {
assertEquals(ModelConstants.NULL_UUID, foundView.getCustomerId().getId()); assertEquals(ModelConstants.NULL_UUID, foundView.getCustomerId().getId());
testBroadcastEntityStateChangeEventNever(foundView.getId()); testBroadcastEntityStateChangeEventNever(foundView.getId());
testNotifyEntityAllOneTime(unAssignedView, savedView.getId(), savedView.getId(), testNotifyAssignUnassignEntityAllOneTime(unAssignedView, savedView.getId(), savedView.getId(),
tenantId, savedView.getCustomerId(), tenantAdminUserId, TENANT_ADMIN_EMAIL, tenantId, savedView.getCustomerId(), tenantAdminUserId, TENANT_ADMIN_EMAIL,
ActionType.UNASSIGNED_FROM_CUSTOMER, ActionType.UNASSIGNED_FROM_CUSTOMER, ActionType.UPDATED,
assignedView.getId().getId().toString(), savedView.getCustomerId().getId().toString(), savedCustomer.getTitle()); assignedView.getId().getId().toString(), savedView.getCustomerId().getId().toString(), savedCustomer.getTitle());
} }
@ -328,9 +329,9 @@ public class EntityViewControllerTest extends AbstractControllerTest {
Assert.assertTrue(publicCustomer.isPublic()); Assert.assertTrue(publicCustomer.isPublic());
testBroadcastEntityStateChangeEventNever(assignedView.getId()); testBroadcastEntityStateChangeEventNever(assignedView.getId());
testNotifyEntityAllOneTime(assignedView, assignedView.getId(), assignedView.getId(), testNotifyAssignUnassignEntityAllOneTime(assignedView, assignedView.getId(), assignedView.getId(),
tenantId, assignedView.getCustomerId(), tenantAdminUserId, TENANT_ADMIN_EMAIL, tenantId, assignedView.getCustomerId(), tenantAdminUserId, TENANT_ADMIN_EMAIL,
ActionType.ASSIGNED_TO_CUSTOMER, ActionType.ASSIGNED_TO_CUSTOMER, ActionType.UPDATED,
assignedView.getId().getId().toString(), assignedView.getCustomerId().getId().toString(), publicCustomer.getTitle()); assignedView.getId().getId().toString(), assignedView.getCustomerId().getId().toString(), publicCustomer.getTitle());
EntityView foundView = doGet("/api/entityView/" + savedView.getId().getId().toString(), EntityView.class); EntityView foundView = doGet("/api/entityView/" + savedView.getId().getId().toString(), EntityView.class);
@ -343,9 +344,9 @@ public class EntityViewControllerTest extends AbstractControllerTest {
assertEquals(ModelConstants.NULL_UUID, foundView.getCustomerId().getId()); assertEquals(ModelConstants.NULL_UUID, foundView.getCustomerId().getId());
testBroadcastEntityStateChangeEventNever(foundView.getId()); testBroadcastEntityStateChangeEventNever(foundView.getId());
testNotifyEntityAllOneTime(unAssignedView, unAssignedView.getId(), unAssignedView.getId(), testNotifyAssignUnassignEntityAllOneTime(unAssignedView, unAssignedView.getId(), unAssignedView.getId(),
tenantId, publicCustomer.getId(), tenantAdminUserId, TENANT_ADMIN_EMAIL, tenantId, publicCustomer.getId(), tenantAdminUserId, TENANT_ADMIN_EMAIL,
ActionType.UNASSIGNED_FROM_CUSTOMER, ActionType.UNASSIGNED_FROM_CUSTOMER, ActionType.UPDATED,
unAssignedView.getId().getId().toString(), publicCustomer.getId().getId().toString(), publicCustomer.getTitle()); unAssignedView.getId().getId().toString(), publicCustomer.getId().getId().toString(), publicCustomer.getTitle());
} }
@ -425,11 +426,11 @@ public class EntityViewControllerTest extends AbstractControllerTest {
testNotifyEntityBroadcastEntityStateChangeEventMany(new EntityView(), new EntityView(), testNotifyEntityBroadcastEntityStateChangeEventMany(new EntityView(), new EntityView(),
tenantId, tenantAdminCustomerId, tenantAdminUserId, TENANT_ADMIN_EMAIL, tenantId, tenantAdminCustomerId, tenantAdminUserId, TENANT_ADMIN_EMAIL,
ActionType.ADDED, ActionType.ADDED, cntEntity, 0, cntEntity*2, 0); ActionType.ADDED, ActionType.ADDED, cntEntity, cntEntity, cntEntity * 2, 0);
testNotifyEntityBroadcastEntityStateChangeEventMany(new EntityView(), new EntityView(), testNotifyEntityBroadcastEntityStateChangeEventMany(new EntityView(), new EntityView(),
tenantId, customerId, tenantAdminUserId, TENANT_ADMIN_EMAIL, tenantId, customerId, tenantAdminUserId, TENANT_ADMIN_EMAIL,
ActionType.ASSIGNED_TO_CUSTOMER, ActionType.ASSIGNED_TO_CUSTOMER, cntEntity, cntEntity, ActionType.ASSIGNED_TO_CUSTOMER, ActionType.UPDATED, cntEntity, cntEntity,
cntEntity*2, 3); cntEntity*2, 3);
} }
@ -464,7 +465,7 @@ public class EntityViewControllerTest extends AbstractControllerTest {
testBroadcastEntityStateChangeEventNever(loadedNamesOfView1.get(0).getId()); testBroadcastEntityStateChangeEventNever(loadedNamesOfView1.get(0).getId());
testNotifyManyEntityManyTimeMsgToEdgeServiceEntityEqAnyAdditionalInfoAny(new EntityView(), new EntityView(), testNotifyManyEntityManyTimeMsgToEdgeServiceEntityEqAnyAdditionalInfoAny(new EntityView(), new EntityView(),
tenantId, customerId, tenantAdminUserId, TENANT_ADMIN_EMAIL, tenantId, customerId, tenantAdminUserId, TENANT_ADMIN_EMAIL,
ActionType.UNASSIGNED_FROM_CUSTOMER, ActionType.UNASSIGNED_FROM_CUSTOMER, cntEntity, cntEntity, 3); ActionType.UNASSIGNED_FROM_CUSTOMER, ActionType.UPDATED, cntEntity, cntEntity, 3);
PageData<EntityView> pageData = doGetTypedWithPageLink(urlTemplate, PAGE_DATA_ENTITY_VIEW_TYPE_REF, PageData<EntityView> pageData = doGetTypedWithPageLink(urlTemplate, PAGE_DATA_ENTITY_VIEW_TYPE_REF,
new PageLink(4, 0, name1)); new PageLink(4, 0, name1));

2
application/src/test/java/org/thingsboard/server/controller/OtaPackageControllerTest.java

@ -339,7 +339,7 @@ public class OtaPackageControllerTest extends AbstractControllerTest {
testNotifyManyEntityManyTimeMsgToEdgeServiceEntityEqAny(new OtaPackageInfo(), new OtaPackageInfo(), testNotifyManyEntityManyTimeMsgToEdgeServiceEntityEqAny(new OtaPackageInfo(), new OtaPackageInfo(),
savedTenant.getId(), tenantAdmin.getCustomerId(), tenantAdmin.getId(), tenantAdmin.getEmail(), savedTenant.getId(), tenantAdmin.getCustomerId(), tenantAdmin.getId(), tenantAdmin.getEmail(),
ActionType.ADDED, ActionType.ADDED, cntEntity, 0, (cntEntity*2 - startIndexSaveData)); ActionType.ADDED, cntEntity, 0, (cntEntity*2 - startIndexSaveData));
List<OtaPackageInfo> loadedFirmwares = new ArrayList<>(); List<OtaPackageInfo> loadedFirmwares = new ArrayList<>();
PageLink pageLink = new PageLink(24); PageLink pageLink = new PageLink(24);

20
application/src/test/java/org/thingsboard/server/controller/RuleChainControllerTest.java

@ -21,7 +21,6 @@ import org.junit.Assert;
import org.junit.Before; import org.junit.Before;
import org.junit.Ignore; import org.junit.Ignore;
import org.junit.Test; import org.junit.Test;
import org.junit.jupiter.api.Assertions;
import org.mockito.AdditionalAnswers; import org.mockito.AdditionalAnswers;
import org.mockito.Mockito; import org.mockito.Mockito;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
@ -31,7 +30,6 @@ import org.springframework.test.context.ContextConfiguration;
import org.thingsboard.common.util.JacksonUtil; import org.thingsboard.common.util.JacksonUtil;
import org.thingsboard.rule.engine.action.TbCreateAlarmNode; import org.thingsboard.rule.engine.action.TbCreateAlarmNode;
import org.thingsboard.rule.engine.action.TbCreateAlarmNodeConfiguration; import org.thingsboard.rule.engine.action.TbCreateAlarmNodeConfiguration;
import org.thingsboard.rule.engine.api.TbVersionedNode;
import org.thingsboard.rule.engine.metadata.TbGetRelatedAttributeNode; import org.thingsboard.rule.engine.metadata.TbGetRelatedAttributeNode;
import org.thingsboard.rule.engine.metadata.TbGetRelatedDataNodeConfiguration; import org.thingsboard.rule.engine.metadata.TbGetRelatedDataNodeConfiguration;
import org.thingsboard.server.common.data.StringUtils; import org.thingsboard.server.common.data.StringUtils;
@ -52,7 +50,6 @@ import org.thingsboard.server.dao.rule.RuleChainDao;
import org.thingsboard.server.dao.service.DaoSqlTest; import org.thingsboard.server.dao.service.DaoSqlTest;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections;
import java.util.List; import java.util.List;
import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThat;
@ -63,7 +60,7 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.
@DaoSqlTest @DaoSqlTest
public class RuleChainControllerTest extends AbstractControllerTest { public class RuleChainControllerTest extends AbstractControllerTest {
private IdComparator<RuleChain> idComparator = new IdComparator<>(); private final IdComparator<RuleChain> idComparator = new IdComparator<>();
private Tenant savedTenant; private Tenant savedTenant;
private User tenantAdmin; private User tenantAdmin;
@ -245,7 +242,7 @@ public class RuleChainControllerTest extends AbstractControllerTest {
doDelete("/api/ruleChain/" + savedRuleChain.getId().getId().toString()) doDelete("/api/ruleChain/" + savedRuleChain.getId().getId().toString())
.andExpect(status().isOk()); .andExpect(status().isOk());
testNotifyEntityBroadcastEntityStateChangeEventOneTimeMsgToEdgeServiceNever(savedRuleChain, savedRuleChain.getId(), savedRuleChain.getId(), testNotifyEntityBroadcastEntityStateChangeEventOneTime(savedRuleChain, savedRuleChain.getId(), savedRuleChain.getId(),
savedTenant.getId(), tenantAdmin.getCustomerId(), tenantAdmin.getId(), tenantAdmin.getEmail(), savedTenant.getId(), tenantAdmin.getCustomerId(), tenantAdmin.getId(), tenantAdmin.getEmail(),
ActionType.DELETED, savedRuleChain.getId().getId().toString()); ActionType.DELETED, savedRuleChain.getId().getId().toString());
@ -260,14 +257,13 @@ public class RuleChainControllerTest extends AbstractControllerTest {
Edge savedEdge = doPost("/api/edge", edge, Edge.class); Edge savedEdge = doPost("/api/edge", edge, Edge.class);
List<RuleChain> edgeRuleChains = new ArrayList<>();
PageLink pageLink = new PageLink(17); PageLink pageLink = new PageLink(17);
PageData<RuleChain> pageData = doGetTypedWithPageLink("/api/edge/" + savedEdge.getId().getId() + "/ruleChains?", PageData<RuleChain> pageData = doGetTypedWithPageLink("/api/edge/" + savedEdge.getId().getId() + "/ruleChains?",
new TypeReference<>() { new TypeReference<>() {
}, pageLink); }, pageLink);
Assert.assertFalse(pageData.hasNext()); Assert.assertFalse(pageData.hasNext());
Assert.assertEquals(1, pageData.getTotalElements()); Assert.assertEquals(1, pageData.getTotalElements());
edgeRuleChains.addAll(pageData.getData()); List<RuleChain> edgeRuleChains = new ArrayList<>(pageData.getData());
Mockito.reset(tbClusterService, auditLogService); Mockito.reset(tbClusterService, auditLogService);
@ -284,11 +280,7 @@ public class RuleChainControllerTest extends AbstractControllerTest {
testNotifyManyEntityManyTimeMsgToEdgeServiceEntityEqAny(new RuleChain(), new RuleChain(), testNotifyManyEntityManyTimeMsgToEdgeServiceEntityEqAny(new RuleChain(), new RuleChain(),
savedTenant.getId(), tenantAdmin.getCustomerId(), tenantAdmin.getId(), tenantAdmin.getEmail(), savedTenant.getId(), tenantAdmin.getCustomerId(), tenantAdmin.getId(), tenantAdmin.getEmail(),
ActionType.ADDED, ActionType.ADDED, cntEntity, 0, cntEntity * 2); ActionType.ADDED, cntEntity, cntEntity, cntEntity * 2);
testNotifyManyEntityManyTimeMsgToEdgeServiceEntityEqAny(new RuleChain(), new RuleChain(),
savedTenant.getId(), tenantAdmin.getCustomerId(), tenantAdmin.getId(), tenantAdmin.getEmail(),
ActionType.ASSIGNED_TO_EDGE, ActionType.ASSIGNED_TO_EDGE, cntEntity, cntEntity, cntEntity * 2,
new String(), new String(), new String());
Mockito.reset(tbClusterService, auditLogService); Mockito.reset(tbClusterService, auditLogService);
List<RuleChain> loadedEdgeRuleChains = new ArrayList<>(); List<RuleChain> loadedEdgeRuleChains = new ArrayList<>();
@ -303,8 +295,8 @@ public class RuleChainControllerTest extends AbstractControllerTest {
} }
} while (pageData.hasNext()); } while (pageData.hasNext());
Collections.sort(edgeRuleChains, idComparator); edgeRuleChains.sort(idComparator);
Collections.sort(loadedEdgeRuleChains, idComparator); loadedEdgeRuleChains.sort(idComparator);
Assert.assertEquals(edgeRuleChains, loadedEdgeRuleChains); Assert.assertEquals(edgeRuleChains, loadedEdgeRuleChains);

17
application/src/test/java/org/thingsboard/server/controller/TelemetryControllerTest.java

@ -16,6 +16,7 @@
package org.thingsboard.server.controller; package org.thingsboard.server.controller;
import org.junit.Test; import org.junit.Test;
import org.springframework.test.context.TestPropertySource;
import org.thingsboard.server.common.data.Device; import org.thingsboard.server.common.data.Device;
import org.thingsboard.server.common.data.SaveDeviceWithCredentialsRequest; import org.thingsboard.server.common.data.SaveDeviceWithCredentialsRequest;
import org.thingsboard.server.common.data.security.DeviceCredentials; import org.thingsboard.server.common.data.security.DeviceCredentials;
@ -25,6 +26,10 @@ import org.thingsboard.server.dao.service.DaoSqlTest;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
@DaoSqlTest @DaoSqlTest
@TestPropertySource(properties = {
"sql.attributes.value_no_xss_validation=true",
"sql.ts.value_no_xss_validation=true"
})
public class TelemetryControllerTest extends AbstractControllerTest { public class TelemetryControllerTest extends AbstractControllerTest {
@Test @Test
@ -39,6 +44,18 @@ public class TelemetryControllerTest extends AbstractControllerTest {
doPostAsync("/api/plugins/telemetry/DEVICE/" + device.getId() + "/timeseries/smth", invalidRequestBody, String.class, status().isBadRequest()); doPostAsync("/api/plugins/telemetry/DEVICE/" + device.getId() + "/timeseries/smth", invalidRequestBody, String.class, status().isBadRequest());
} }
@Test
public void testValueConstraintValidator() throws Exception {
loginTenantAdmin();
Device device = createDevice();
String correctRequestBody = "{\"data\": \"value\"}";
doPostAsync("/api/plugins/telemetry/" + device.getId() + "/SHARED_SCOPE", correctRequestBody, String.class, status().isOk());
doPostAsync("/api/plugins/telemetry/DEVICE/" + device.getId() + "/timeseries/smth", correctRequestBody, String.class, status().isOk());
String invalidRequestBody = "{\"data\": \"<object data=\\\"data:text/html,<script>alert(document)</script>\\\"></object>\"}";
doPostAsync("/api/plugins/telemetry/" + device.getId() + "/SHARED_SCOPE", invalidRequestBody, String.class, status().isBadRequest());
doPostAsync("/api/plugins/telemetry/DEVICE/" + device.getId() + "/timeseries/smth", invalidRequestBody, String.class, status().isBadRequest());
}
private Device createDevice() throws Exception { private Device createDevice() throws Exception {
String testToken = "TEST_TOKEN"; String testToken = "TEST_TOKEN";

8
application/src/test/java/org/thingsboard/server/controller/UserControllerTest.java

@ -113,7 +113,7 @@ public class UserControllerTest extends AbstractControllerTest {
testNotifyManyEntityManyTimeMsgToEdgeServiceEntityEqAny(foundUser, foundUser, testNotifyManyEntityManyTimeMsgToEdgeServiceEntityEqAny(foundUser, foundUser,
SYSTEM_TENANT, customerNUULId, null, SYS_ADMIN_EMAIL, SYSTEM_TENANT, customerNUULId, null, SYS_ADMIN_EMAIL,
ActionType.ADDED, ActionType.ADDED, 1, 1, 1); ActionType.ADDED, 1, 1, 1);
Mockito.reset(tbClusterService, auditLogService); Mockito.reset(tbClusterService, auditLogService);
resetTokens(); resetTokens();
@ -152,7 +152,7 @@ public class UserControllerTest extends AbstractControllerTest {
testNotifyEntityAllOneTimeLogEntityActionEntityEqClass(foundUser, foundUser.getId(), foundUser.getId(), testNotifyEntityAllOneTimeLogEntityActionEntityEqClass(foundUser, foundUser.getId(), foundUser.getId(),
SYSTEM_TENANT, customerNUULId, null, SYS_ADMIN_EMAIL, SYSTEM_TENANT, customerNUULId, null, SYS_ADMIN_EMAIL,
ActionType.DELETED, SYSTEM_TENANT.getId().toString()); ActionType.DELETED, ActionType.DELETED, SYSTEM_TENANT.getId().toString());
} }
@Test @Test
@ -397,7 +397,7 @@ public class UserControllerTest extends AbstractControllerTest {
testManyUser.setTenantId(tenantId); testManyUser.setTenantId(tenantId);
testNotifyManyEntityManyTimeMsgToEdgeServiceEntityEqAny(testManyUser, testManyUser, testNotifyManyEntityManyTimeMsgToEdgeServiceEntityEqAny(testManyUser, testManyUser,
SYSTEM_TENANT, customerNUULId, null, SYS_ADMIN_EMAIL, SYSTEM_TENANT, customerNUULId, null, SYS_ADMIN_EMAIL,
ActionType.ADDED, ActionType.ADDED, cntEntity, cntEntity, cntEntity); ActionType.ADDED, cntEntity, cntEntity, cntEntity);
List<User> loadedTenantAdmins = new ArrayList<>(); List<User> loadedTenantAdmins = new ArrayList<>();
PageLink pageLink = new PageLink(33); PageLink pageLink = new PageLink(33);
@ -510,7 +510,7 @@ public class UserControllerTest extends AbstractControllerTest {
testManyUser.setTenantId(tenantId); testManyUser.setTenantId(tenantId);
testNotifyManyEntityManyTimeMsgToEdgeServiceEntityEqAny(testManyUser, testManyUser, testNotifyManyEntityManyTimeMsgToEdgeServiceEntityEqAny(testManyUser, testManyUser,
SYSTEM_TENANT, customerNUULId, null, SYS_ADMIN_EMAIL, SYSTEM_TENANT, customerNUULId, null, SYS_ADMIN_EMAIL,
ActionType.DELETED, ActionType.DELETED, cntEntity, NUMBER_OF_USERS, cntEntity, new String()); ActionType.DELETED, cntEntity, NUMBER_OF_USERS, cntEntity, "");
pageLink = new PageLink(4, 0, email1); pageLink = new PageLink(4, 0, email1);
pageData = doGetTypedWithPageLink("/api/tenant/" + tenantId.getId().toString() + "/users?", pageData = doGetTypedWithPageLink("/api/tenant/" + tenantId.getId().toString() + "/users?",

109
application/src/test/java/org/thingsboard/server/edge/AbstractEdgeTest.java

@ -36,7 +36,6 @@ import org.thingsboard.server.common.data.DeviceProfile;
import org.thingsboard.server.common.data.OtaPackageInfo; import org.thingsboard.server.common.data.OtaPackageInfo;
import org.thingsboard.server.common.data.SaveOtaPackageInfoRequest; import org.thingsboard.server.common.data.SaveOtaPackageInfoRequest;
import org.thingsboard.server.common.data.StringUtils; import org.thingsboard.server.common.data.StringUtils;
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.alarm.AlarmSeverity; import org.thingsboard.server.common.data.alarm.AlarmSeverity;
import org.thingsboard.server.common.data.asset.Asset; import org.thingsboard.server.common.data.asset.Asset;
@ -70,7 +69,6 @@ import org.thingsboard.server.common.data.query.NumericFilterPredicate;
import org.thingsboard.server.common.data.queue.Queue; import org.thingsboard.server.common.data.queue.Queue;
import org.thingsboard.server.common.data.rule.RuleChain; import org.thingsboard.server.common.data.rule.RuleChain;
import org.thingsboard.server.common.data.rule.RuleChainType; import org.thingsboard.server.common.data.rule.RuleChainType;
import org.thingsboard.server.common.data.security.Authority;
import org.thingsboard.server.controller.AbstractControllerTest; import org.thingsboard.server.controller.AbstractControllerTest;
import org.thingsboard.server.dao.edge.EdgeEventService; import org.thingsboard.server.dao.edge.EdgeEventService;
import org.thingsboard.server.edge.imitator.EdgeImitator; import org.thingsboard.server.edge.imitator.EdgeImitator;
@ -85,6 +83,7 @@ import org.thingsboard.server.gen.edge.v1.QueueUpdateMsg;
import org.thingsboard.server.gen.edge.v1.RuleChainMetadataRequestMsg; import org.thingsboard.server.gen.edge.v1.RuleChainMetadataRequestMsg;
import org.thingsboard.server.gen.edge.v1.RuleChainMetadataUpdateMsg; import org.thingsboard.server.gen.edge.v1.RuleChainMetadataUpdateMsg;
import org.thingsboard.server.gen.edge.v1.RuleChainUpdateMsg; import org.thingsboard.server.gen.edge.v1.RuleChainUpdateMsg;
import org.thingsboard.server.gen.edge.v1.SyncCompletedMsg;
import org.thingsboard.server.gen.edge.v1.UpdateMsgType; import org.thingsboard.server.gen.edge.v1.UpdateMsgType;
import org.thingsboard.server.gen.edge.v1.UplinkMsg; import org.thingsboard.server.gen.edge.v1.UplinkMsg;
import org.thingsboard.server.gen.edge.v1.UserUpdateMsg; import org.thingsboard.server.gen.edge.v1.UserUpdateMsg;
@ -100,16 +99,12 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.
@TestPropertySource(properties = { @TestPropertySource(properties = {
"edges.enabled=true", "edges.enabled=true",
"queue.rule-engine.stats.enabled=false", "queue.rule-engine.stats.enabled=false"
}) })
abstract public class AbstractEdgeTest extends AbstractControllerTest { abstract public class AbstractEdgeTest extends AbstractControllerTest {
private static final String THERMOSTAT_DEVICE_PROFILE_NAME = "Thermostat"; private static final String THERMOSTAT_DEVICE_PROFILE_NAME = "Thermostat";
protected Tenant savedTenant;
protected TenantId tenantId;
protected User tenantAdmin;
protected DeviceProfile thermostatDeviceProfile; protected DeviceProfile thermostatDeviceProfile;
protected EdgeImitator edgeImitator; protected EdgeImitator edgeImitator;
@ -125,27 +120,8 @@ abstract public class AbstractEdgeTest extends AbstractControllerTest {
protected TbClusterService clusterService; protected TbClusterService clusterService;
@Before @Before
public void beforeTest() throws Exception { public void setupEdgeTest() throws Exception {
loginSysAdmin(); loginTenantAdmin();
Tenant tenant = new Tenant();
tenant.setTitle("My tenant");
savedTenant = doPost("/api/tenant", tenant, Tenant.class);
tenantId = savedTenant.getId();
Assert.assertNotNull(savedTenant);
tenantAdmin = new User();
tenantAdmin.setAuthority(Authority.TENANT_ADMIN);
tenantAdmin.setTenantId(savedTenant.getId());
tenantAdmin.setEmail("tenant2@thingsboard.org");
tenantAdmin.setFirstName("Joe");
tenantAdmin.setLastName("Downs");
tenantAdmin = createUserAndLogin(tenantAdmin, "testPassword1");
// sleep 0.5 second to avoid CREDENTIALS updated message for the user
// user credentials is going to be stored and updated event pushed to edge notification service
// while service will be processing this event edge could be already added and additional message will be pushed
Thread.sleep(500);
installation(); installation();
@ -181,31 +157,32 @@ abstract public class AbstractEdgeTest extends AbstractControllerTest {
} }
@After @After
public void afterTest() throws Exception { public void teardownEdgeTest() {
try { try {
edgeImitator.disconnect(); edgeImitator.expectMessageAmount(2);
} catch (Exception ignored){} loginTenantAdmin();
Assert.assertTrue(edgeImitator.waitForMessages());
loginSysAdmin();
doDelete("/api/tenant/" + savedTenant.getUuidId()) doDelete("/api/edge/" + edge.getId().toString())
.andExpect(status().isOk()); .andExpect(status().isOk());
edgeImitator.disconnect();
} catch (Exception ignored) {}
} }
private void installation() { private void installation() {
edge = doPost("/api/edge", constructEdge("Test Edge", "test"), Edge.class);
thermostatDeviceProfile = this.createDeviceProfile(THERMOSTAT_DEVICE_PROFILE_NAME, thermostatDeviceProfile = this.createDeviceProfile(THERMOSTAT_DEVICE_PROFILE_NAME,
createMqttDeviceProfileTransportConfiguration(new JsonTransportPayloadConfiguration(), false)); createMqttDeviceProfileTransportConfiguration(new JsonTransportPayloadConfiguration(), false));
extendDeviceProfileData(thermostatDeviceProfile); extendDeviceProfileData(thermostatDeviceProfile);
thermostatDeviceProfile = doPost("/api/deviceProfile", thermostatDeviceProfile, DeviceProfile.class); thermostatDeviceProfile = doPost("/api/deviceProfile", thermostatDeviceProfile, DeviceProfile.class);
Device savedDevice = saveDevice("Edge Device 1", THERMOSTAT_DEVICE_PROFILE_NAME); Device savedDevice = saveDevice("Edge Device 1", THERMOSTAT_DEVICE_PROFILE_NAME);
doPost("/api/edge/" + edge.getUuidId()
+ "/device/" + savedDevice.getUuidId(), Device.class);
Asset savedAsset = saveAsset("Edge Asset 1"); Asset savedAsset = saveAsset("Edge Asset 1");
edge = doPost("/api/edge", constructEdge("Test Edge", "test"), Edge.class);
doPost("/api/edge/" + edge.getUuidId()
+ "/device/" + savedDevice.getUuidId(), Device.class);
doPost("/api/edge/" + edge.getUuidId() doPost("/api/edge/" + edge.getUuidId()
+ "/asset/" + savedAsset.getUuidId(), Asset.class); + "/asset/" + savedAsset.getUuidId(), Asset.class);
} }
@ -244,18 +221,8 @@ abstract public class AbstractEdgeTest extends AbstractControllerTest {
validateEdgeConfiguration(); validateEdgeConfiguration();
// 5 messages // 1 message from queue fetcher
// - 2 from device profile fetcher (default and thermostat) validateQueues();
// - 1 from device fetcher
// - 1 from device profile controller (thermostat)
// - 1 from device controller (thermostat)
validateDeviceProfiles();
// 2 messages - 1 from device fetcher and 1 from device controller
validateDevices();
// 2 messages - 1 from asset fetcher and 1 from asset controller
validateAssets();
// 2 messages - 1 from rule chain fetcher and 1 from rule chain controller // 2 messages - 1 from rule chain fetcher and 1 from rule chain controller
UUID ruleChainUUID = validateRuleChains(); UUID ruleChainUUID = validateRuleChains();
@ -266,20 +233,32 @@ abstract public class AbstractEdgeTest extends AbstractControllerTest {
// 4 messages - 4 messages from fetcher - 2 from system level ('mail', 'mailTemplates') and 2 from admin level ('mail', 'mailTemplates') // 4 messages - 4 messages from fetcher - 2 from system level ('mail', 'mailTemplates') and 2 from admin level ('mail', 'mailTemplates')
validateAdminSettings(); validateAdminSettings();
// 4 messages
// - 2 from device profile fetcher (default and thermostat)
// - 1 from device fetcher
// - 1 from device controller (thermostat)
validateDeviceProfiles();
// 3 messages // 3 messages
// - 1 message from asset profile fetcher // - 1 message from asset profile fetcher
// - 1 message from asset fetcher // - 1 message from asset fetcher
// - 1 message from asset controller // - 1 message from asset controller
validateAssetProfiles(); validateAssetProfiles();
// 1 message from queue fetcher // 2 messages - 1 from device fetcher and 1 from device controller
validateQueues(); validateDevices();
// 1 message from user fetcher // 2 messages - 1 from asset fetcher and 1 from asset controller
validateUsers(); validateAssets();
// 1 message from public customer fetcher // 1 message from public customer fetcher
validatePublicCustomer(); validatePublicCustomer();
// 1 message from user fetcher
validateUsers();
// 1 message sync completed
validateSyncCompleted();
} }
private void validateEdgeConfiguration() throws Exception { private void validateEdgeConfiguration() throws Exception {
@ -290,12 +269,11 @@ abstract public class AbstractEdgeTest extends AbstractControllerTest {
private void validateDeviceProfiles() throws Exception { private void validateDeviceProfiles() throws Exception {
List<DeviceProfileUpdateMsg> deviceProfileUpdateMsgList = edgeImitator.findAllMessagesByType(DeviceProfileUpdateMsg.class); List<DeviceProfileUpdateMsg> deviceProfileUpdateMsgList = edgeImitator.findAllMessagesByType(DeviceProfileUpdateMsg.class);
// default msg // default msg device profile from fetcher
// thermostat msg from fetcher // thermostat msg from device profile fetcher
// thermostat msg from device fetcher // thermostat msg from device fetcher
// thermostat msg from controller
// thermostat msg from creation of device // thermostat msg from creation of device
Assert.assertEquals(5, deviceProfileUpdateMsgList.size()); Assert.assertEquals(4, deviceProfileUpdateMsgList.size());
Optional<DeviceProfileUpdateMsg> thermostatProfileUpdateMsgOpt = Optional<DeviceProfileUpdateMsg> thermostatProfileUpdateMsgOpt =
deviceProfileUpdateMsgList.stream().filter(dfum -> THERMOSTAT_DEVICE_PROFILE_NAME.equals(dfum.getName())).findAny(); deviceProfileUpdateMsgList.stream().filter(dfum -> THERMOSTAT_DEVICE_PROFILE_NAME.equals(dfum.getName())).findAny();
Assert.assertTrue(thermostatProfileUpdateMsgOpt.isPresent()); Assert.assertTrue(thermostatProfileUpdateMsgOpt.isPresent());
@ -394,7 +372,7 @@ abstract public class AbstractEdgeTest extends AbstractControllerTest {
} }
} }
private void validateMailAdminSettings(AdminSettingsUpdateMsg adminSettingsUpdateMsg) throws JsonProcessingException { private void validateMailAdminSettings(AdminSettingsUpdateMsg adminSettingsUpdateMsg) {
JsonNode jsonNode = JacksonUtil.toJsonNode(adminSettingsUpdateMsg.getJsonValue()); JsonNode jsonNode = JacksonUtil.toJsonNode(adminSettingsUpdateMsg.getJsonValue());
Assert.assertNotNull(jsonNode.get("mailFrom")); Assert.assertNotNull(jsonNode.get("mailFrom"));
Assert.assertNotNull(jsonNode.get("smtpProtocol")); Assert.assertNotNull(jsonNode.get("smtpProtocol"));
@ -403,7 +381,7 @@ abstract public class AbstractEdgeTest extends AbstractControllerTest {
Assert.assertNotNull(jsonNode.get("timeout")); Assert.assertNotNull(jsonNode.get("timeout"));
} }
private void validateMailTemplatesAdminSettings(AdminSettingsUpdateMsg adminSettingsUpdateMsg) throws JsonProcessingException { private void validateMailTemplatesAdminSettings(AdminSettingsUpdateMsg adminSettingsUpdateMsg) {
JsonNode jsonNode = JacksonUtil.toJsonNode(adminSettingsUpdateMsg.getJsonValue()); JsonNode jsonNode = JacksonUtil.toJsonNode(adminSettingsUpdateMsg.getJsonValue());
Assert.assertNotNull(jsonNode.get("accountActivated")); Assert.assertNotNull(jsonNode.get("accountActivated"));
Assert.assertNotNull(jsonNode.get("accountLockout")); Assert.assertNotNull(jsonNode.get("accountLockout"));
@ -449,7 +427,7 @@ abstract public class AbstractEdgeTest extends AbstractControllerTest {
UUID userUUID = new UUID(userUpdateMsg.getIdMSB(), userUpdateMsg.getIdLSB()); UUID userUUID = new UUID(userUpdateMsg.getIdMSB(), userUpdateMsg.getIdLSB());
User user = doGet("/api/user/" + userUUID, User.class); User user = doGet("/api/user/" + userUUID, User.class);
Assert.assertNotNull(user); Assert.assertNotNull(user);
Assert.assertEquals("tenant2@thingsboard.org", userUpdateMsg.getEmail()); Assert.assertEquals("testtenant@thingsboard.org", userUpdateMsg.getEmail());
testAutoGeneratedCodeByProtobuf(userUpdateMsg); testAutoGeneratedCodeByProtobuf(userUpdateMsg);
} }
@ -464,6 +442,11 @@ abstract public class AbstractEdgeTest extends AbstractControllerTest {
Assert.assertTrue(customer.isPublic()); Assert.assertTrue(customer.isPublic());
} }
private void validateSyncCompleted() {
Optional<SyncCompletedMsg> syncCompletedMsgOpt = edgeImitator.findMessageByType(SyncCompletedMsg.class);
Assert.assertTrue(syncCompletedMsgOpt.isPresent());
}
protected Device saveDeviceOnCloudAndVerifyDeliveryToEdge() throws Exception { protected Device saveDeviceOnCloudAndVerifyDeliveryToEdge() throws Exception {
// create device and assign to edge // create device and assign to edge
Device savedDevice = saveDevice(StringUtils.randomAlphanumeric(15), thermostatDeviceProfile.getName()); Device savedDevice = saveDevice(StringUtils.randomAlphanumeric(15), thermostatDeviceProfile.getName());

5
application/src/test/java/org/thingsboard/server/edge/AssetEdgeTest.java

@ -82,11 +82,11 @@ public class AssetEdgeTest extends AbstractEdgeTest {
Assert.assertEquals(savedAsset.getUuidId().getMostSignificantBits(), assetUpdateMsg.getIdMSB()); Assert.assertEquals(savedAsset.getUuidId().getMostSignificantBits(), assetUpdateMsg.getIdMSB());
Assert.assertEquals(savedAsset.getUuidId().getLeastSignificantBits(), assetUpdateMsg.getIdLSB()); Assert.assertEquals(savedAsset.getUuidId().getLeastSignificantBits(), assetUpdateMsg.getIdLSB());
// delete asset - no messages expected // delete asset - message expected, it was sent to all edges
edgeImitator.expectMessageAmount(1); edgeImitator.expectMessageAmount(1);
doDelete("/api/asset/" + savedAsset.getUuidId()) doDelete("/api/asset/" + savedAsset.getUuidId())
.andExpect(status().isOk()); .andExpect(status().isOk());
Assert.assertFalse(edgeImitator.waitForMessages(1)); Assert.assertTrue(edgeImitator.waitForMessages(1));
// create asset #2 and assign to edge // create asset #2 and assign to edge
edgeImitator.expectMessageAmount(2); edgeImitator.expectMessageAmount(2);
@ -94,7 +94,6 @@ public class AssetEdgeTest extends AbstractEdgeTest {
doPost("/api/edge/" + edge.getUuidId() doPost("/api/edge/" + edge.getUuidId()
+ "/asset/" + savedAsset.getUuidId(), Asset.class); + "/asset/" + savedAsset.getUuidId(), Asset.class);
Assert.assertTrue(edgeImitator.waitForMessages()); Assert.assertTrue(edgeImitator.waitForMessages());
latestMessage = edgeImitator.getLatestMessage();
assetUpdateMsgOpt = edgeImitator.findMessageByType(AssetUpdateMsg.class); assetUpdateMsgOpt = edgeImitator.findMessageByType(AssetUpdateMsg.class);
Assert.assertTrue(assetUpdateMsgOpt.isPresent()); Assert.assertTrue(assetUpdateMsgOpt.isPresent());
assetUpdateMsg = assetUpdateMsgOpt.get(); assetUpdateMsg = assetUpdateMsgOpt.get();

17
application/src/test/java/org/thingsboard/server/edge/CustomerEdgeTest.java

@ -20,12 +20,15 @@ import org.junit.Assert;
import org.junit.Test; import org.junit.Test;
import org.thingsboard.server.common.data.Customer; import org.thingsboard.server.common.data.Customer;
import org.thingsboard.server.common.data.edge.Edge; import org.thingsboard.server.common.data.edge.Edge;
import org.thingsboard.server.common.data.id.CustomerId;
import org.thingsboard.server.common.data.id.EntityId;
import org.thingsboard.server.dao.service.DaoSqlTest; import org.thingsboard.server.dao.service.DaoSqlTest;
import org.thingsboard.server.gen.edge.v1.CustomerUpdateMsg; import org.thingsboard.server.gen.edge.v1.CustomerUpdateMsg;
import org.thingsboard.server.gen.edge.v1.EdgeConfiguration; import org.thingsboard.server.gen.edge.v1.EdgeConfiguration;
import org.thingsboard.server.gen.edge.v1.UpdateMsgType; import org.thingsboard.server.gen.edge.v1.UpdateMsgType;
import java.util.Optional; import java.util.Optional;
import java.util.UUID;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
@ -74,13 +77,19 @@ public class CustomerEdgeTest extends AbstractEdgeTest {
Assert.assertEquals(savedCustomer.getTitle(), customerUpdateMsg.getTitle()); Assert.assertEquals(savedCustomer.getTitle(), customerUpdateMsg.getTitle());
// delete customer // delete customer
edgeImitator.expectMessageAmount(1); edgeImitator.expectMessageAmount(2);
doDelete("/api/customer/" + savedCustomer.getUuidId()) doDelete("/api/customer/" + savedCustomer.getUuidId())
.andExpect(status().isOk()); .andExpect(status().isOk());
Assert.assertTrue(edgeImitator.waitForMessages()); Assert.assertTrue(edgeImitator.waitForMessages());
latestMessage = edgeImitator.getLatestMessage(); edgeConfigurationOpt = edgeImitator.findMessageByType(EdgeConfiguration.class);
Assert.assertTrue(latestMessage instanceof CustomerUpdateMsg); Assert.assertTrue(edgeConfigurationOpt.isPresent());
customerUpdateMsg = (CustomerUpdateMsg) latestMessage; edgeConfiguration = edgeConfigurationOpt.get();
Assert.assertEquals(
new CustomerId(EntityId.NULL_UUID),
new CustomerId(new UUID(edgeConfiguration.getCustomerIdMSB(), edgeConfiguration.getCustomerIdLSB())));
customerUpdateOpt = edgeImitator.findMessageByType(CustomerUpdateMsg.class);
Assert.assertTrue(customerUpdateOpt.isPresent());
customerUpdateMsg = customerUpdateOpt.get();
Assert.assertEquals(UpdateMsgType.ENTITY_DELETED_RPC_MESSAGE, customerUpdateMsg.getMsgType()); Assert.assertEquals(UpdateMsgType.ENTITY_DELETED_RPC_MESSAGE, customerUpdateMsg.getMsgType());
Assert.assertEquals(customerUpdateMsg.getIdMSB(), savedCustomer.getUuidId().getMostSignificantBits()); Assert.assertEquals(customerUpdateMsg.getIdMSB(), savedCustomer.getUuidId().getMostSignificantBits());
Assert.assertEquals(customerUpdateMsg.getIdLSB(), savedCustomer.getUuidId().getLeastSignificantBits()); Assert.assertEquals(customerUpdateMsg.getIdLSB(), savedCustomer.getUuidId().getLeastSignificantBits());

4
application/src/test/java/org/thingsboard/server/edge/DashboardEdgeTest.java

@ -77,11 +77,11 @@ public class DashboardEdgeTest extends AbstractEdgeTest {
Assert.assertEquals(savedDashboard.getUuidId().getMostSignificantBits(), dashboardUpdateMsg.getIdMSB()); Assert.assertEquals(savedDashboard.getUuidId().getMostSignificantBits(), dashboardUpdateMsg.getIdMSB());
Assert.assertEquals(savedDashboard.getUuidId().getLeastSignificantBits(), dashboardUpdateMsg.getIdLSB()); Assert.assertEquals(savedDashboard.getUuidId().getLeastSignificantBits(), dashboardUpdateMsg.getIdLSB());
// delete dashboard - no messages expected // delete dashboard - message expected, it was sent to all edges
edgeImitator.expectMessageAmount(1); edgeImitator.expectMessageAmount(1);
doDelete("/api/dashboard/" + savedDashboard.getUuidId()) doDelete("/api/dashboard/" + savedDashboard.getUuidId())
.andExpect(status().isOk()); .andExpect(status().isOk());
Assert.assertFalse(edgeImitator.waitForMessages(1)); Assert.assertTrue(edgeImitator.waitForMessages(1));
// create dashboard #2 and assign to edge // create dashboard #2 and assign to edge
edgeImitator.expectMessageAmount(1); edgeImitator.expectMessageAmount(1);

16
application/src/test/java/org/thingsboard/server/edge/DeviceEdgeTest.java

@ -83,6 +83,8 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.
@DaoSqlTest @DaoSqlTest
public class DeviceEdgeTest extends AbstractEdgeTest { public class DeviceEdgeTest extends AbstractEdgeTest {
private static final String DEFAULT_DEVICE_TYPE = "default";
@Test @Test
public void testDevices() throws Exception { public void testDevices() throws Exception {
// create device and assign to edge; update device // create device and assign to edge; update device
@ -100,15 +102,15 @@ public class DeviceEdgeTest extends AbstractEdgeTest {
Assert.assertEquals(savedDevice.getUuidId().getMostSignificantBits(), deviceUpdateMsg.getIdMSB()); Assert.assertEquals(savedDevice.getUuidId().getMostSignificantBits(), deviceUpdateMsg.getIdMSB());
Assert.assertEquals(savedDevice.getUuidId().getLeastSignificantBits(), deviceUpdateMsg.getIdLSB()); Assert.assertEquals(savedDevice.getUuidId().getLeastSignificantBits(), deviceUpdateMsg.getIdLSB());
// delete device - no messages expected // delete device - message expected, message send to all edges
edgeImitator.expectMessageAmount(1); edgeImitator.expectMessageAmount(1);
doDelete("/api/device/" + savedDevice.getUuidId()) doDelete("/api/device/" + savedDevice.getUuidId())
.andExpect(status().isOk()); .andExpect(status().isOk());
Assert.assertFalse(edgeImitator.waitForMessages(1)); Assert.assertTrue(edgeImitator.waitForMessages(1));
// create device #2 and assign to edge // create device #2 and assign to edge
edgeImitator.expectMessageAmount(2); edgeImitator.expectMessageAmount(2);
savedDevice = saveDevice("Edge Device 3", "Default"); savedDevice = saveDevice("Edge Device 3", DEFAULT_DEVICE_TYPE);
doPost("/api/edge/" + edge.getUuidId() doPost("/api/edge/" + edge.getUuidId()
+ "/device/" + savedDevice.getUuidId(), Device.class); + "/device/" + savedDevice.getUuidId(), Device.class);
Assert.assertTrue(edgeImitator.waitForMessages()); Assert.assertTrue(edgeImitator.waitForMessages());
@ -265,14 +267,16 @@ public class DeviceEdgeTest extends AbstractEdgeTest {
public void testDeviceReachedMaximumAllowedOnCloud() throws Exception { public void testDeviceReachedMaximumAllowedOnCloud() throws Exception {
// update tenant profile configuration // update tenant profile configuration
loginSysAdmin(); loginSysAdmin();
TenantProfile tenantProfile = doGet("/api/tenantProfile/" + savedTenant.getTenantProfileId().getId(), TenantProfile.class); TenantProfile tenantProfile = doGet("/api/tenantProfile/" + tenantProfileId.getId(), TenantProfile.class);
DefaultTenantProfileConfiguration profileConfiguration = DefaultTenantProfileConfiguration profileConfiguration =
(DefaultTenantProfileConfiguration) tenantProfile.getProfileData().getConfiguration(); (DefaultTenantProfileConfiguration) tenantProfile.getProfileData().getConfiguration();
profileConfiguration.setMaxDevices(1); profileConfiguration.setMaxDevices(1);
tenantProfile.getProfileData().setConfiguration(profileConfiguration); tenantProfile.getProfileData().setConfiguration(profileConfiguration);
doPost("/api/tenantProfile/", tenantProfile, TenantProfile.class); doPost("/api/tenantProfile/", tenantProfile, TenantProfile.class);
edgeImitator.expectMessageAmount(2);
loginTenantAdmin(); loginTenantAdmin();
Assert.assertTrue(edgeImitator.waitForMessages());
UUID uuid = Uuids.timeBased(); UUID uuid = Uuids.timeBased();
@ -281,7 +285,7 @@ public class DeviceEdgeTest extends AbstractEdgeTest {
deviceUpdateMsgBuilder.setIdMSB(uuid.getMostSignificantBits()); deviceUpdateMsgBuilder.setIdMSB(uuid.getMostSignificantBits());
deviceUpdateMsgBuilder.setIdLSB(uuid.getLeastSignificantBits()); deviceUpdateMsgBuilder.setIdLSB(uuid.getLeastSignificantBits());
deviceUpdateMsgBuilder.setName("Edge Device"); deviceUpdateMsgBuilder.setName("Edge Device");
deviceUpdateMsgBuilder.setType("default"); deviceUpdateMsgBuilder.setType(DEFAULT_DEVICE_TYPE);
deviceUpdateMsgBuilder.setMsgType(UpdateMsgType.ENTITY_CREATED_RPC_MESSAGE); deviceUpdateMsgBuilder.setMsgType(UpdateMsgType.ENTITY_CREATED_RPC_MESSAGE);
uplinkMsgBuilder.addDeviceUpdateMsg(deviceUpdateMsgBuilder.build()); uplinkMsgBuilder.addDeviceUpdateMsg(deviceUpdateMsgBuilder.build());
@ -479,7 +483,7 @@ public class DeviceEdgeTest extends AbstractEdgeTest {
@Test @Test
public void testSendDeviceToCloudWithNameThatAlreadyExistsOnCloud() throws Exception { public void testSendDeviceToCloudWithNameThatAlreadyExistsOnCloud() throws Exception {
String deviceOnCloudName = StringUtils.randomAlphanumeric(15); String deviceOnCloudName = StringUtils.randomAlphanumeric(15);
Device deviceOnCloud = saveDevice(deviceOnCloudName, "Default"); Device deviceOnCloud = saveDevice(deviceOnCloudName, DEFAULT_DEVICE_TYPE);
UUID uuid = Uuids.timeBased(); UUID uuid = Uuids.timeBased();

4
application/src/test/java/org/thingsboard/server/edge/EntityViewEdgeTest.java

@ -94,11 +94,11 @@ public class EntityViewEdgeTest extends AbstractEdgeTest {
Assert.assertEquals(entityViewUpdateMsg.getIdMSB(), savedEntityView.getUuidId().getMostSignificantBits()); Assert.assertEquals(entityViewUpdateMsg.getIdMSB(), savedEntityView.getUuidId().getMostSignificantBits());
Assert.assertEquals(entityViewUpdateMsg.getIdLSB(), savedEntityView.getUuidId().getLeastSignificantBits()); Assert.assertEquals(entityViewUpdateMsg.getIdLSB(), savedEntityView.getUuidId().getLeastSignificantBits());
// delete entity view - no messages expected // delete entity view - message expected, it was sent to all edges
edgeImitator.expectMessageAmount(1); edgeImitator.expectMessageAmount(1);
doDelete("/api/entityView/" + savedEntityView.getUuidId()) doDelete("/api/entityView/" + savedEntityView.getUuidId())
.andExpect(status().isOk()); .andExpect(status().isOk());
Assert.assertFalse(edgeImitator.waitForMessages(1)); Assert.assertTrue(edgeImitator.waitForMessages(1));
// create entity view #2 and assign to edge // create entity view #2 and assign to edge
edgeImitator.expectMessageAmount(1); edgeImitator.expectMessageAmount(1);

31
application/src/test/java/org/thingsboard/server/edge/RuleChainEdgeTest.java

@ -19,6 +19,9 @@ import com.google.protobuf.AbstractMessage;
import org.junit.Assert; import org.junit.Assert;
import org.junit.Test; import org.junit.Test;
import org.thingsboard.common.util.JacksonUtil; import org.thingsboard.common.util.JacksonUtil;
import org.thingsboard.rule.engine.metadata.TbGetAttributesNode;
import org.thingsboard.rule.engine.metadata.TbGetAttributesNodeConfiguration;
import org.thingsboard.rule.engine.util.TbMsgSource;
import org.thingsboard.server.common.data.edge.Edge; import org.thingsboard.server.common.data.edge.Edge;
import org.thingsboard.server.common.data.id.RuleChainId; import org.thingsboard.server.common.data.id.RuleChainId;
import org.thingsboard.server.common.data.rule.RuleChain; import org.thingsboard.server.common.data.rule.RuleChain;
@ -33,6 +36,7 @@ import org.thingsboard.server.gen.edge.v1.UpdateMsgType;
import org.thingsboard.server.gen.edge.v1.UplinkMsg; import org.thingsboard.server.gen.edge.v1.UplinkMsg;
import java.util.ArrayList; import java.util.ArrayList;
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;
@ -81,7 +85,7 @@ public class RuleChainEdgeTest extends AbstractEdgeTest {
edgeImitator.expectMessageAmount(1); edgeImitator.expectMessageAmount(1);
doDelete("/api/ruleChain/" + savedRuleChain.getUuidId()) doDelete("/api/ruleChain/" + savedRuleChain.getUuidId())
.andExpect(status().isOk()); .andExpect(status().isOk());
Assert.assertFalse(edgeImitator.waitForMessages(1)); Assert.assertTrue(edgeImitator.waitForMessages(5));
} }
@Test @Test
@ -136,24 +140,30 @@ public class RuleChainEdgeTest extends AbstractEdgeTest {
Assert.assertEquals(ruleChainId, receivedRuleChainId); Assert.assertEquals(ruleChainId, receivedRuleChainId);
} }
private void createRuleChainMetadata(RuleChain ruleChain) throws Exception { private void createRuleChainMetadata(RuleChain ruleChain) {
RuleChainMetaData ruleChainMetaData = new RuleChainMetaData(); RuleChainMetaData ruleChainMetaData = new RuleChainMetaData();
ruleChainMetaData.setRuleChainId(ruleChain.getId()); ruleChainMetaData.setRuleChainId(ruleChain.getId());
RuleNode ruleNode1 = new RuleNode(); RuleNode ruleNode1 = new RuleNode();
ruleNode1.setName("name1"); ruleNode1.setName("name1");
ruleNode1.setType("type1"); ruleNode1.setType(org.thingsboard.rule.engine.metadata.TbGetAttributesNode.class.getName());
ruleNode1.setConfiguration(JacksonUtil.toJsonNode("\"key1\": \"val1\"")); ruleNode1.setConfigurationVersion(TbGetAttributesNode.class.getAnnotation(org.thingsboard.rule.engine.api.RuleNode.class).version());
TbGetAttributesNodeConfiguration configuration = new TbGetAttributesNodeConfiguration();
configuration.setFetchTo(TbMsgSource.METADATA);
configuration.setServerAttributeNames(Collections.singletonList("serverAttributeKey2"));
ruleNode1.setConfiguration(JacksonUtil.valueToTree(configuration));
RuleNode ruleNode2 = new RuleNode(); RuleNode ruleNode2 = new RuleNode();
ruleNode2.setName("name2"); ruleNode2.setName("name2");
ruleNode2.setType("type2"); ruleNode2.setType(org.thingsboard.rule.engine.metadata.TbGetAttributesNode.class.getName());
ruleNode2.setConfiguration(JacksonUtil.toJsonNode("\"key2\": \"val2\"")); ruleNode2.setConfigurationVersion(TbGetAttributesNode.class.getAnnotation(org.thingsboard.rule.engine.api.RuleNode.class).version());
ruleNode2.setConfiguration(JacksonUtil.valueToTree(configuration));
RuleNode ruleNode3 = new RuleNode(); RuleNode ruleNode3 = new RuleNode();
ruleNode3.setName("name3"); ruleNode3.setName("name3");
ruleNode3.setType("type3"); ruleNode3.setType(org.thingsboard.rule.engine.metadata.TbGetAttributesNode.class.getName());
ruleNode3.setConfiguration(JacksonUtil.toJsonNode("\"key3\": \"val3\"")); ruleNode3.setConfigurationVersion(TbGetAttributesNode.class.getAnnotation(org.thingsboard.rule.engine.api.RuleNode.class).version());
ruleNode3.setConfiguration(JacksonUtil.valueToTree(configuration));
List<RuleNode> ruleNodes = new ArrayList<>(); List<RuleNode> ruleNodes = new ArrayList<>();
ruleNodes.add(ruleNode1); ruleNodes.add(ruleNode1);
@ -172,11 +182,12 @@ public class RuleChainEdgeTest extends AbstractEdgeTest {
@Test @Test
public void testSetRootRuleChain() throws Exception { public void testSetRootRuleChain() throws Exception {
// create rule chain // create rule chain
edgeImitator.expectMessageAmount(1);
RuleChain ruleChain = new RuleChain(); RuleChain ruleChain = new RuleChain();
ruleChain.setName("Edge New Root Rule Chain"); ruleChain.setName("Edge New Root Rule Chain");
ruleChain.setType(RuleChainType.EDGE); ruleChain.setType(RuleChainType.EDGE);
RuleChain savedRuleChain = doPost("/api/ruleChain", ruleChain, RuleChain.class); RuleChain savedRuleChain = doPost("/api/ruleChain", ruleChain, RuleChain.class);
edgeImitator.expectMessageAmount(1);
doPost("/api/edge/" + edge.getUuidId() doPost("/api/edge/" + edge.getUuidId()
+ "/ruleChain/" + savedRuleChain.getUuidId(), RuleChain.class); + "/ruleChain/" + savedRuleChain.getUuidId(), RuleChain.class);
Assert.assertTrue(edgeImitator.waitForMessages()); Assert.assertTrue(edgeImitator.waitForMessages());
@ -211,6 +222,6 @@ public class RuleChainEdgeTest extends AbstractEdgeTest {
edgeImitator.expectMessageAmount(1); edgeImitator.expectMessageAmount(1);
doDelete("/api/ruleChain/" + savedRuleChain.getUuidId()) doDelete("/api/ruleChain/" + savedRuleChain.getUuidId())
.andExpect(status().isOk()); .andExpect(status().isOk());
Assert.assertFalse(edgeImitator.waitForMessages(1)); Assert.assertTrue(edgeImitator.waitForMessages(1));
} }
} }

2
application/src/test/java/org/thingsboard/server/edge/TelemetryEdgeTest.java

@ -215,7 +215,7 @@ public class TelemetryEdgeTest extends AbstractEdgeTest {
@Test @Test
public void testAttributesUpdatedMsg_userEntity() throws Exception { public void testAttributesUpdatedMsg_userEntity() throws Exception {
testAttributesUpdatedMsg(tenantAdmin.getId()); testAttributesUpdatedMsg(tenantAdminUserId);
} }
private void testAttributesUpdatedMsg(EntityId entityId) throws Exception { private void testAttributesUpdatedMsg(EntityId entityId) throws Exception {

Some files were not shown because too many files changed in this diff

Loading…
Cancel
Save