Browse Source

Merge PR#9968

pull/10000/head
Andrii Shvaika 3 years ago
parent
commit
a3471c367a
  1. 5
      application/src/main/java/org/thingsboard/server/actors/device/DeviceActorMessageProcessor.java
  2. 6
      application/src/main/java/org/thingsboard/server/actors/ruleChain/DefaultTbContext.java
  3. 4
      application/src/main/java/org/thingsboard/server/controller/BaseController.java
  4. 8
      application/src/main/java/org/thingsboard/server/controller/DashboardController.java
  5. 5
      application/src/main/java/org/thingsboard/server/controller/DeviceController.java
  6. 8
      application/src/main/java/org/thingsboard/server/controller/NotificationRuleController.java
  7. 9
      application/src/main/java/org/thingsboard/server/controller/RuleChainController.java
  8. 12
      application/src/main/java/org/thingsboard/server/controller/TelemetryController.java
  9. 7
      application/src/main/java/org/thingsboard/server/service/apiusage/DefaultTbApiUsageStateService.java
  10. 4
      application/src/main/java/org/thingsboard/server/service/device/ClaimDevicesServiceImpl.java
  11. 7
      application/src/main/java/org/thingsboard/server/service/device/DeviceProvisionServiceImpl.java
  12. 79
      application/src/main/java/org/thingsboard/server/service/edge/EdgeEventSourcingListener.java
  13. 9
      application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/BaseEdgeProcessor.java
  14. 2
      application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/asset/profile/BaseAssetProfileProcessor.java
  15. 1
      application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/device/BaseDeviceProcessor.java
  16. 2
      application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/device/profile/BaseDeviceProfileProcessor.java
  17. 6
      application/src/main/java/org/thingsboard/server/service/edge/rpc/sync/DefaultEdgeRequestsService.java
  18. 2
      application/src/main/java/org/thingsboard/server/service/entitiy/AbstractTbEntityService.java
  19. 79
      application/src/main/java/org/thingsboard/server/service/entitiy/DefaultTbLogEntityActionService.java
  20. 212
      application/src/main/java/org/thingsboard/server/service/entitiy/DefaultTbNotificationEntityService.java
  21. 266
      application/src/main/java/org/thingsboard/server/service/entitiy/EntityStateSourcingListener.java
  22. 28
      application/src/main/java/org/thingsboard/server/service/entitiy/TbLogEntityActionService.java
  23. 6
      application/src/main/java/org/thingsboard/server/service/entitiy/alarm/DefaultTbAlarmCommentService.java
  24. 16
      application/src/main/java/org/thingsboard/server/service/entitiy/alarm/DefaultTbAlarmService.java
  25. 32
      application/src/main/java/org/thingsboard/server/service/entitiy/asset/DefaultTbAssetService.java
  26. 21
      application/src/main/java/org/thingsboard/server/service/entitiy/asset/profile/DefaultTbAssetProfileService.java
  27. 9
      application/src/main/java/org/thingsboard/server/service/entitiy/customer/DefaultTbCustomerService.java
  28. 46
      application/src/main/java/org/thingsboard/server/service/entitiy/dashboard/DefaultTbDashboardService.java
  29. 71
      application/src/main/java/org/thingsboard/server/service/entitiy/device/DefaultTbDeviceService.java
  30. 2
      application/src/main/java/org/thingsboard/server/service/entitiy/device/TbDeviceService.java
  31. 38
      application/src/main/java/org/thingsboard/server/service/entitiy/device/profile/DefaultTbDeviceProfileService.java
  32. 32
      application/src/main/java/org/thingsboard/server/service/entitiy/edge/DefaultTbEdgeService.java
  33. 12
      application/src/main/java/org/thingsboard/server/service/entitiy/entity/relation/DefaultTbEntityRelationService.java
  34. 39
      application/src/main/java/org/thingsboard/server/service/entitiy/entityview/DefaultTbEntityViewService.java
  35. 12
      application/src/main/java/org/thingsboard/server/service/entitiy/ota/DefaultTbOtaPackageService.java
  36. 13
      application/src/main/java/org/thingsboard/server/service/entitiy/tenant/DefaultTbTenantService.java
  37. 5
      application/src/main/java/org/thingsboard/server/service/entitiy/tenant/profile/DefaultTbTenantProfileService.java
  38. 8
      application/src/main/java/org/thingsboard/server/service/entitiy/user/DefaultUserService.java
  39. 1
      application/src/main/java/org/thingsboard/server/service/entitiy/user/TbUserService.java
  40. 8
      application/src/main/java/org/thingsboard/server/service/entitiy/widgets/bundle/DefaultWidgetsBundleService.java
  41. 8
      application/src/main/java/org/thingsboard/server/service/entitiy/widgets/type/DefaultWidgetTypeService.java
  42. 8
      application/src/main/java/org/thingsboard/server/service/install/InstallScripts.java
  43. 6
      application/src/main/java/org/thingsboard/server/service/install/SqlDatabaseUpgradeService.java
  44. 6
      application/src/main/java/org/thingsboard/server/service/notification/DefaultNotificationCenter.java
  45. 20
      application/src/main/java/org/thingsboard/server/service/queue/DefaultTbClusterService.java
  46. 12
      application/src/main/java/org/thingsboard/server/service/resource/DefaultTbImageService.java
  47. 13
      application/src/main/java/org/thingsboard/server/service/resource/DefaultTbResourceService.java
  48. 83
      application/src/main/java/org/thingsboard/server/service/rule/DefaultTbRuleChainService.java
  49. 13
      application/src/main/java/org/thingsboard/server/service/security/auth/oauth2/AbstractOAuth2ClientMapper.java
  50. 6
      application/src/main/java/org/thingsboard/server/service/sync/ie/DefaultEntitiesExportImportService.java
  51. 6
      application/src/main/java/org/thingsboard/server/service/sync/ie/importing/impl/AssetProfileImportService.java
  52. 8
      application/src/main/java/org/thingsboard/server/service/sync/ie/importing/impl/BaseEntityImportService.java
  53. 9
      application/src/main/java/org/thingsboard/server/service/sync/ie/importing/impl/DeviceImportService.java
  54. 16
      application/src/main/java/org/thingsboard/server/service/sync/ie/importing/impl/DeviceProfileImportService.java
  55. 2
      application/src/main/java/org/thingsboard/server/service/sync/ie/importing/impl/EntityViewImportService.java
  56. 6
      application/src/main/java/org/thingsboard/server/service/sync/ie/importing/impl/NotificationRuleImportService.java
  57. 4
      application/src/main/java/org/thingsboard/server/service/sync/ie/importing/impl/RuleChainImportService.java
  58. 10
      application/src/main/java/org/thingsboard/server/service/sync/vc/DefaultEntitiesVersionControlService.java
  59. 10
      application/src/main/java/org/thingsboard/server/service/transport/DefaultTransportApiService.java
  60. 26
      application/src/test/java/org/thingsboard/server/controller/AbstractNotifyEntityTest.java
  61. 12
      application/src/test/java/org/thingsboard/server/controller/EdgeControllerTest.java
  62. 10
      application/src/test/java/org/thingsboard/server/controller/EntityViewControllerTest.java
  63. 1
      application/src/test/java/org/thingsboard/server/edge/DeviceEdgeTest.java
  64. 7
      application/src/test/java/org/thingsboard/server/edge/TelemetryEdgeTest.java
  65. 4
      application/src/test/java/org/thingsboard/server/service/edge/rpc/processor/BaseEdgeProcessorTest.java
  66. 12
      application/src/test/java/org/thingsboard/server/service/entitiy/alarm/DefaultTbAlarmServiceTest.java
  67. 8
      application/src/test/java/org/thingsboard/server/service/entitiy/alarmComment/DefaultTbAlarmCommentServiceTest.java
  68. 3
      application/src/test/java/org/thingsboard/server/service/sync/ie/ExportImportServiceSqlTest.java
  69. 7
      common/cluster-api/src/main/java/org/thingsboard/server/cluster/TbClusterService.java
  70. 1
      common/cluster-api/src/main/java/org/thingsboard/server/queue/TbQueueClusterService.java
  71. 4
      common/dao-api/src/main/java/org/thingsboard/server/dao/asset/AssetProfileService.java
  72. 4
      common/dao-api/src/main/java/org/thingsboard/server/dao/device/DeviceProfileService.java
  73. 4
      common/dao-api/src/main/java/org/thingsboard/server/dao/device/DeviceService.java
  74. 2
      common/dao-api/src/main/java/org/thingsboard/server/dao/notification/NotificationRequestService.java
  75. 4
      common/dao-api/src/main/java/org/thingsboard/server/dao/rule/RuleChainService.java
  76. 2
      common/dao-api/src/main/java/org/thingsboard/server/dao/tenant/TenantService.java
  77. 13
      common/data/src/main/java/org/thingsboard/server/common/data/EdgeUtils.java
  78. 54
      common/data/src/main/java/org/thingsboard/server/common/data/edge/EdgeEventActionType.java
  79. 24
      dao/src/main/java/org/thingsboard/server/dao/asset/AssetProfileServiceImpl.java
  80. 10
      dao/src/main/java/org/thingsboard/server/dao/asset/BaseAssetService.java
  81. 10
      dao/src/main/java/org/thingsboard/server/dao/dashboard/DashboardServiceImpl.java
  82. 2
      dao/src/main/java/org/thingsboard/server/dao/device/DeviceCredentialsServiceImpl.java
  83. 26
      dao/src/main/java/org/thingsboard/server/dao/device/DeviceProfileServiceImpl.java
  84. 35
      dao/src/main/java/org/thingsboard/server/dao/device/DeviceServiceImpl.java
  85. 47
      dao/src/main/java/org/thingsboard/server/dao/edge/BaseEdgeEventService.java
  86. 13
      dao/src/main/java/org/thingsboard/server/dao/edge/EdgeServiceImpl.java
  87. 10
      dao/src/main/java/org/thingsboard/server/dao/entityview/EntityViewServiceImpl.java
  88. 5
      dao/src/main/java/org/thingsboard/server/dao/eventsourcing/ActionEntityEvent.java
  89. 1
      dao/src/main/java/org/thingsboard/server/dao/eventsourcing/DeleteEntityEvent.java
  90. 12
      dao/src/main/java/org/thingsboard/server/dao/notification/DefaultNotificationRequestService.java
  91. 8
      dao/src/main/java/org/thingsboard/server/dao/notification/DefaultNotificationRuleService.java
  92. 5
      dao/src/main/java/org/thingsboard/server/dao/queue/BaseQueueService.java
  93. 10
      dao/src/main/java/org/thingsboard/server/dao/resource/BaseResourceService.java
  94. 70
      dao/src/main/java/org/thingsboard/server/dao/rule/BaseRuleChainService.java
  95. 11
      dao/src/main/java/org/thingsboard/server/dao/tenant/TenantProfileServiceImpl.java
  96. 15
      dao/src/main/java/org/thingsboard/server/dao/tenant/TenantServiceImpl.java
  97. 6
      dao/src/main/java/org/thingsboard/server/dao/usagerecord/ApiUsageStateServiceImpl.java
  98. 24
      dao/src/test/java/org/thingsboard/server/dao/service/DashboardServiceTest.java
  99. 13
      dao/src/test/java/org/thingsboard/server/dao/service/timeseries/BaseTimeseriesServiceTest.java
  100. 3
      rule-engine/rule-engine-api/src/main/java/org/thingsboard/rule/engine/api/TbContext.java

5
application/src/main/java/org/thingsboard/server/actors/device/DeviceActorMessageProcessor.java

@ -920,10 +920,7 @@ public class DeviceActorMessageProcessor extends AbstractContextAwareMsgProcesso
EdgeEvent edgeEvent = EdgeUtils.constructEdgeEvent(tenantId, edgeId, EdgeEventType.DEVICE, EdgeEventActionType.RPC_CALL, deviceId, body); EdgeEvent edgeEvent = EdgeUtils.constructEdgeEvent(tenantId, edgeId, EdgeEventType.DEVICE, EdgeEventActionType.RPC_CALL, deviceId, body);
return Futures.transform(systemContext.getEdgeEventService().saveAsync(edgeEvent), unused -> { return systemContext.getEdgeEventService().saveAsync(edgeEvent);
systemContext.getClusterService().onEdgeEventUpdate(tenantId, edgeId);
return null;
}, systemContext.getDbCallbackExecutor());
} }
private KeyValueProto toKeyValueProto(KvEntry kvEntry) { private KeyValueProto toKeyValueProto(KvEntry kvEntry) {

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

@ -53,7 +53,6 @@ import org.thingsboard.server.common.data.asset.AssetProfile;
import org.thingsboard.server.common.data.id.AssetId; import org.thingsboard.server.common.data.id.AssetId;
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.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.RuleNodeId; import org.thingsboard.server.common.data.id.RuleNodeId;
@ -448,11 +447,6 @@ class DefaultTbContext implements TbContext {
return entityActionMsg(originator, tbMsgMetaData, msgData, actionMsgType, profile); return entityActionMsg(originator, tbMsgMetaData, msgData, actionMsgType, profile);
} }
@Override
public void onEdgeEventUpdate(TenantId tenantId, EdgeId edgeId) {
mainCtx.getClusterService().onEdgeEventUpdate(tenantId, edgeId);
}
public <E, I extends EntityId> TbMsg entityActionMsg(E entity, I id, RuleNodeId ruleNodeId, TbMsgType actionMsgType) { public <E, I extends EntityId> TbMsg entityActionMsg(E entity, I id, RuleNodeId ruleNodeId, TbMsgType actionMsgType) {
return entityActionMsg(entity, id, ruleNodeId, actionMsgType, null); return entityActionMsg(entity, id, ruleNodeId, actionMsgType, null);
} }

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

@ -145,7 +145,7 @@ 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.entitiy.TbNotificationEntityService; import org.thingsboard.server.service.entitiy.TbLogEntityActionService;
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;
import org.thingsboard.server.service.profile.TbAssetProfileCache; import org.thingsboard.server.service.profile.TbAssetProfileCache;
@ -300,7 +300,7 @@ public abstract class BaseController {
protected EdgeService edgeService; protected EdgeService edgeService;
@Autowired @Autowired
protected TbNotificationEntityService notificationEntityService; protected TbLogEntityActionService logEntityActionService;
@Autowired @Autowired
protected EntityActionService entityActionService; protected EntityActionService entityActionService;

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

@ -532,7 +532,7 @@ public class DashboardController extends BaseController {
} }
Tenant tenant = tenantService.findTenantById(getTenantId()); Tenant tenant = tenantService.findTenantById(getTenantId());
JsonNode additionalInfo = tenant.getAdditionalInfo(); JsonNode additionalInfo = tenant.getAdditionalInfo();
if (additionalInfo == null || !(additionalInfo instanceof ObjectNode)) { if (!(additionalInfo instanceof ObjectNode)) {
additionalInfo = JacksonUtil.newObjectNode(); additionalInfo = JacksonUtil.newObjectNode();
} }
if (homeDashboardInfo.getDashboardId() != null) { if (homeDashboardInfo.getDashboardId() != null) {
@ -558,8 +558,7 @@ public class DashboardController extends BaseController {
} }
return new HomeDashboardInfo(dashboardId, hideDashboardToolbar); return new HomeDashboardInfo(dashboardId, hideDashboardToolbar);
} }
} catch (Exception e) { } catch (Exception ignored) {}
}
return null; return null;
} }
@ -575,8 +574,7 @@ public class DashboardController extends BaseController {
} }
return new HomeDashboard(dashboard, hideDashboardToolbar); return new HomeDashboard(dashboard, hideDashboardToolbar);
} }
} catch (Exception e) { } catch (Exception ignored) {}
}
return null; return null;
} }

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

@ -181,13 +181,12 @@ public class DeviceController extends BaseController {
@Parameter(description = "Optional value of the device credentials to be used during device creation. " + @Parameter(description = "Optional value of the device credentials to be used during device creation. " +
"If omitted, access token will be auto-generated.") @RequestParam(name = "accessToken", required = false) String accessToken) throws Exception { "If omitted, access token will be auto-generated.") @RequestParam(name = "accessToken", required = false) String accessToken) throws Exception {
device.setTenantId(getCurrentUser().getTenantId()); device.setTenantId(getCurrentUser().getTenantId());
Device oldDevice = null;
if (device.getId() != null) { if (device.getId() != null) {
oldDevice = checkDeviceId(device.getId(), Operation.WRITE); checkDeviceId(device.getId(), Operation.WRITE);
} else { } else {
checkEntity(null, device, Resource.DEVICE); checkEntity(null, device, Resource.DEVICE);
} }
return tbDeviceService.save(device, oldDevice, accessToken, getCurrentUser()); return tbDeviceService.save(device, accessToken, getCurrentUser());
} }
@ApiOperation(value = "Create Device (saveDevice) with credentials ", @ApiOperation(value = "Create Device (saveDevice) with credentials ",

8
application/src/main/java/org/thingsboard/server/controller/NotificationRuleController.java

@ -37,7 +37,6 @@ import org.thingsboard.server.common.data.notification.rule.NotificationRuleInfo
import org.thingsboard.server.common.data.notification.rule.trigger.config.NotificationRuleTriggerType; import org.thingsboard.server.common.data.notification.rule.trigger.config.NotificationRuleTriggerType;
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.plugin.ComponentLifecycleEvent;
import org.thingsboard.server.config.annotations.ApiOperation; import org.thingsboard.server.config.annotations.ApiOperation;
import org.thingsboard.server.dao.notification.NotificationRuleService; import org.thingsboard.server.dao.notification.NotificationRuleService;
import org.thingsboard.server.queue.util.TbCoreComponent; import org.thingsboard.server.queue.util.TbCoreComponent;
@ -125,11 +124,7 @@ public class NotificationRuleController extends BaseController {
throw new IllegalArgumentException("Trigger type " + triggerType + " is not available"); throw new IllegalArgumentException("Trigger type " + triggerType + " is not available");
} }
boolean created = notificationRule.getId() == null; return doSaveAndLog(EntityType.NOTIFICATION_RULE, notificationRule, notificationRuleService::saveNotificationRule);
notificationRule = doSaveAndLog(EntityType.NOTIFICATION_RULE, notificationRule, notificationRuleService::saveNotificationRule);
tbClusterService.broadcastEntityStateChangeEvent(user.getTenantId(), notificationRule.getId(), created ?
ComponentLifecycleEvent.CREATED : ComponentLifecycleEvent.UPDATED);
return notificationRule;
} }
@ApiOperation(value = "Get notification rule by id (getNotificationRuleById)", @ApiOperation(value = "Get notification rule by id (getNotificationRuleById)",
@ -177,7 +172,6 @@ public class NotificationRuleController extends BaseController {
NotificationRuleId notificationRuleId = new NotificationRuleId(id); NotificationRuleId notificationRuleId = new NotificationRuleId(id);
NotificationRule notificationRule = checkEntityId(notificationRuleId, notificationRuleService::findNotificationRuleById, Operation.DELETE); NotificationRule notificationRule = checkEntityId(notificationRuleId, notificationRuleService::findNotificationRuleById, Operation.DELETE);
doDeleteAndLog(EntityType.NOTIFICATION_RULE, notificationRule, notificationRuleService::deleteNotificationRuleById); doDeleteAndLog(EntityType.NOTIFICATION_RULE, notificationRule, notificationRuleService::deleteNotificationRuleById);
tbClusterService.broadcastEntityStateChangeEvent(user.getTenantId(), notificationRuleId, ComponentLifecycleEvent.DELETED);
} }
} }

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

@ -460,14 +460,7 @@ public class RuleChainController extends BaseController {
@Parameter(description = "Enables overwrite for existing rule chains with the same name.") @Parameter(description = "Enables overwrite for existing rule chains with the same name.")
@RequestParam(required = false, defaultValue = "false") boolean overwrite) throws ThingsboardException { @RequestParam(required = false, defaultValue = "false") boolean overwrite) throws ThingsboardException {
TenantId tenantId = getCurrentUser().getTenantId(); TenantId tenantId = getCurrentUser().getTenantId();
List<RuleChainImportResult> importResults = ruleChainService.importTenantRuleChains(tenantId, ruleChainData, overwrite, tbRuleChainService::updateRuleNodeConfiguration); return ruleChainService.importTenantRuleChains(tenantId, ruleChainData, overwrite, tbRuleChainService::updateRuleNodeConfiguration);
for (RuleChainImportResult importResult : importResults) {
if (importResult.getError() == null) {
tbClusterService.broadcastEntityStateChangeEvent(importResult.getTenantId(), importResult.getRuleChainId(),
importResult.isUpdated() ? ComponentLifecycleEvent.UPDATED : ComponentLifecycleEvent.CREATED);
}
}
return importResults;
} }
private String msgToOutput(TbMsg msg) throws Exception { private String msgToOutput(TbMsg msg) throws Exception {

12
application/src/main/java/org/thingsboard/server/controller/TelemetryController.java

@ -81,7 +81,7 @@ import org.thingsboard.server.common.data.kv.ReadTsKvQuery;
import org.thingsboard.server.common.data.kv.StringDataEntry; import org.thingsboard.server.common.data.kv.StringDataEntry;
import org.thingsboard.server.common.data.kv.TsKvEntry; import org.thingsboard.server.common.data.kv.TsKvEntry;
import org.thingsboard.server.common.data.tenant.profile.DefaultTenantProfileConfiguration; import org.thingsboard.server.common.data.tenant.profile.DefaultTenantProfileConfiguration;
import org.thingsboard.server.common.adaptor.JsonConverter; import org.thingsboard.server.common.msg.rule.engine.DeviceAttributesEventNotificationMsg;
import org.thingsboard.server.config.annotations.ApiOperation; import org.thingsboard.server.config.annotations.ApiOperation;
import org.thingsboard.server.dao.timeseries.TimeseriesService; import org.thingsboard.server.dao.timeseries.TimeseriesService;
import org.thingsboard.server.exception.InvalidParametersException; import org.thingsboard.server.exception.InvalidParametersException;
@ -832,28 +832,28 @@ public class TelemetryController extends BaseController {
} }
private void logTimeseriesDeleted(SecurityUser user, EntityId entityId, List<String> keys, long startTs, long endTs, Throwable e) { private void logTimeseriesDeleted(SecurityUser user, EntityId entityId, List<String> keys, long startTs, long endTs, Throwable e) {
notificationEntityService.logEntityAction(user.getTenantId(), entityId, ActionType.TIMESERIES_DELETED, user, logEntityActionService.logEntityAction(user.getTenantId(), entityId, ActionType.TIMESERIES_DELETED, user,
toException(e), keys, startTs, endTs); toException(e), keys, startTs, endTs);
} }
private void logTelemetryUpdated(SecurityUser user, EntityId entityId, List<TsKvEntry> telemetry, Throwable e) { private void logTelemetryUpdated(SecurityUser user, EntityId entityId, List<TsKvEntry> telemetry, Throwable e) {
notificationEntityService.logEntityAction(user.getTenantId(), entityId, ActionType.TIMESERIES_UPDATED, user, logEntityActionService.logEntityAction(user.getTenantId(), entityId, ActionType.TIMESERIES_UPDATED, user,
toException(e), telemetry); toException(e), telemetry);
} }
private void logAttributesDeleted(SecurityUser user, EntityId entityId, AttributeScope scope, List<String> keys, Throwable e) { private void logAttributesDeleted(SecurityUser user, EntityId entityId, AttributeScope scope, List<String> keys, Throwable e) {
notificationEntityService.logEntityAction(user.getTenantId(), (UUIDBased & EntityId) entityId, logEntityActionService.logEntityAction(user.getTenantId(), (UUIDBased & EntityId) entityId,
ActionType.ATTRIBUTES_DELETED, user, toException(e), scope, keys); ActionType.ATTRIBUTES_DELETED, user, toException(e), scope, keys);
} }
private void logAttributesUpdated(SecurityUser user, EntityId entityId, AttributeScope scope, List<AttributeKvEntry> attributes, Throwable e) { private void logAttributesUpdated(SecurityUser user, EntityId entityId, AttributeScope scope, List<AttributeKvEntry> attributes, Throwable e) {
notificationEntityService.logEntityAction(user.getTenantId(), entityId, ActionType.ATTRIBUTES_UPDATED, user, logEntityActionService.logEntityAction(user.getTenantId(), entityId, ActionType.ATTRIBUTES_UPDATED, user,
toException(e), scope, attributes); toException(e), scope, attributes);
} }
private void logAttributesRead(SecurityUser user, EntityId entityId, AttributeScope scope, List<String> keys, Throwable e) { private void logAttributesRead(SecurityUser user, EntityId entityId, AttributeScope scope, List<String> keys, Throwable e) {
notificationEntityService.logEntityAction(user.getTenantId(), entityId, ActionType.ATTRIBUTES_READ, user, logEntityActionService.logEntityAction(user.getTenantId(), entityId, ActionType.ATTRIBUTES_READ, user,
toException(e), scope, keys); toException(e), scope, keys);
} }

7
application/src/main/java/org/thingsboard/server/service/apiusage/DefaultTbApiUsageStateService.java

@ -25,7 +25,6 @@ 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.rule.engine.api.MailService; import org.thingsboard.rule.engine.api.MailService;
import org.thingsboard.server.cluster.TbClusterService;
import org.thingsboard.server.common.data.ApiFeature; import org.thingsboard.server.common.data.ApiFeature;
import org.thingsboard.server.common.data.ApiUsageRecordKey; import org.thingsboard.server.common.data.ApiUsageRecordKey;
import org.thingsboard.server.common.data.ApiUsageRecordState; import org.thingsboard.server.common.data.ApiUsageRecordState;
@ -45,10 +44,11 @@ import org.thingsboard.server.common.data.kv.BasicTsKvEntry;
import org.thingsboard.server.common.data.kv.LongDataEntry; import org.thingsboard.server.common.data.kv.LongDataEntry;
import org.thingsboard.server.common.data.kv.StringDataEntry; import org.thingsboard.server.common.data.kv.StringDataEntry;
import org.thingsboard.server.common.data.kv.TsKvEntry; import org.thingsboard.server.common.data.kv.TsKvEntry;
import org.thingsboard.server.common.data.notification.rule.trigger.ApiUsageLimitTrigger;
import org.thingsboard.server.common.data.page.PageDataIterable; import org.thingsboard.server.common.data.page.PageDataIterable;
import org.thingsboard.server.common.data.tenant.profile.TenantProfileConfiguration; import org.thingsboard.server.common.data.tenant.profile.TenantProfileConfiguration;
import org.thingsboard.server.common.data.tenant.profile.TenantProfileData; import org.thingsboard.server.common.data.tenant.profile.TenantProfileData;
import org.thingsboard.server.common.data.notification.rule.trigger.ApiUsageLimitTrigger; 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.queue.TopicPartitionInfo; import org.thingsboard.server.common.msg.queue.TopicPartitionInfo;
@ -61,7 +61,6 @@ import org.thingsboard.server.gen.transport.TransportProtos.ToUsageStatsServiceM
import org.thingsboard.server.gen.transport.TransportProtos.UsageStatsKVProto; import org.thingsboard.server.gen.transport.TransportProtos.UsageStatsKVProto;
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.common.msg.notification.NotificationRuleProcessor;
import org.thingsboard.server.service.apiusage.BaseApiUsageState.StatsCalculationResult; import org.thingsboard.server.service.apiusage.BaseApiUsageState.StatsCalculationResult;
import org.thingsboard.server.service.executors.DbCallbackExecutorService; import org.thingsboard.server.service.executors.DbCallbackExecutorService;
import org.thingsboard.server.service.mail.MailExecutorService; import org.thingsboard.server.service.mail.MailExecutorService;
@ -101,7 +100,6 @@ public class DefaultTbApiUsageStateService extends AbstractPartitionBasedService
public void onFailure(Throwable t) { public void onFailure(Throwable t) {
} }
}; };
private final TbClusterService clusterService;
private final PartitionService partitionService; private final PartitionService partitionService;
private final TenantService tenantService; private final TenantService tenantService;
private final TimeseriesService tsService; private final TimeseriesService tsService;
@ -343,7 +341,6 @@ public class DefaultTbApiUsageStateService extends AbstractPartitionBasedService
private void persistAndNotify(BaseApiUsageState state, Map<ApiFeature, ApiUsageStateValue> result) { private void persistAndNotify(BaseApiUsageState state, Map<ApiFeature, ApiUsageStateValue> result) {
log.info("[{}] Detected update of the API state for {}: {}", state.getEntityId(), state.getEntityType(), result); log.info("[{}] Detected update of the API state for {}: {}", state.getEntityId(), state.getEntityType(), result);
apiUsageStateService.update(state.getApiUsageState()); apiUsageStateService.update(state.getApiUsageState());
clusterService.onApiStateChange(state.getApiUsageState(), null);
long ts = System.currentTimeMillis(); long ts = System.currentTimeMillis();
List<TsKvEntry> stateTelemetry = new ArrayList<>(); List<TsKvEntry> stateTelemetry = new ArrayList<>();
result.forEach((apiFeature, aState) -> stateTelemetry.add(new BasicTsKvEntry(ts, new StringDataEntry(apiFeature.getApiStateKey(), aState.name())))); result.forEach((apiFeature, aState) -> stateTelemetry.add(new BasicTsKvEntry(ts, new StringDataEntry(apiFeature.getApiStateKey(), aState.name()))));

4
application/src/main/java/org/thingsboard/server/service/device/ClaimDevicesServiceImpl.java

@ -67,8 +67,6 @@ public class ClaimDevicesServiceImpl implements ClaimDevicesService {
private static final String CLAIM_ATTRIBUTE_NAME = "claimingAllowed"; private static final String CLAIM_ATTRIBUTE_NAME = "claimingAllowed";
private static final String CLAIM_DATA_ATTRIBUTE_NAME = "claimingData"; private static final String CLAIM_DATA_ATTRIBUTE_NAME = "claimingData";
@Autowired
private TbClusterService clusterService;
@Autowired @Autowired
private DeviceService deviceService; private DeviceService deviceService;
@Autowired @Autowired
@ -153,7 +151,6 @@ public class ClaimDevicesServiceImpl implements ClaimDevicesService {
if (device.getCustomerId().getId().equals(ModelConstants.NULL_UUID)) { if (device.getCustomerId().getId().equals(ModelConstants.NULL_UUID)) {
device.setCustomerId(customerId); device.setCustomerId(customerId);
Device savedDevice = deviceService.saveDevice(device); Device savedDevice = deviceService.saveDevice(device);
clusterService.onDeviceUpdated(savedDevice, device);
return Futures.transform(removeClaimingSavedData(cache, claimData, device), result -> new ClaimResult(savedDevice, ClaimResponse.SUCCESS), MoreExecutors.directExecutor()); return Futures.transform(removeClaimingSavedData(cache, claimData, device), result -> new ClaimResult(savedDevice, ClaimResponse.SUCCESS), MoreExecutors.directExecutor());
} }
return Futures.transform(removeClaimingSavedData(cache, claimData, device), result -> new ClaimResult(null, ClaimResponse.CLAIMED), MoreExecutors.directExecutor()); return Futures.transform(removeClaimingSavedData(cache, claimData, device), result -> new ClaimResult(null, ClaimResponse.CLAIMED), MoreExecutors.directExecutor());
@ -180,7 +177,6 @@ public class ClaimDevicesServiceImpl implements ClaimDevicesService {
Customer unassignedCustomer = customerService.findCustomerById(tenantId, device.getCustomerId()); Customer unassignedCustomer = customerService.findCustomerById(tenantId, device.getCustomerId());
device.setCustomerId(null); device.setCustomerId(null);
Device savedDevice = deviceService.saveDevice(device); Device savedDevice = deviceService.saveDevice(device);
clusterService.onDeviceUpdated(savedDevice, device);
if (isAllowedClaimingByDefault) { if (isAllowedClaimingByDefault) {
return Futures.immediateFuture(new ReclaimResult(unassignedCustomer)); return Futures.immediateFuture(new ReclaimResult(unassignedCustomer));
} }

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

@ -22,9 +22,7 @@ import com.google.common.util.concurrent.ListenableFuture;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
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.server.cluster.TbClusterService;
import org.thingsboard.server.common.data.AttributeScope; import org.thingsboard.server.common.data.AttributeScope;
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.DeviceProfileProvisionType; import org.thingsboard.server.common.data.DeviceProfileProvisionType;
@ -82,7 +80,6 @@ public class DeviceProvisionServiceImpl implements DeviceProvisionService {
private static final String DEVICE_PROVISION_STATE = "provisionState"; private static final String DEVICE_PROVISION_STATE = "provisionState";
private static final String PROVISIONED_STATE = "provisioned"; private static final String PROVISIONED_STATE = "provisioned";
private final TbClusterService clusterService;
private final DeviceProfileService deviceProfileService; private final DeviceProfileService deviceProfileService;
private final DeviceService deviceService; private final DeviceService deviceService;
private final DeviceCredentialsService deviceCredentialsService; private final DeviceCredentialsService deviceCredentialsService;
@ -90,9 +87,8 @@ public class DeviceProvisionServiceImpl implements DeviceProvisionService {
private final AuditLogService auditLogService; private final AuditLogService auditLogService;
private final PartitionService partitionService; private final PartitionService partitionService;
public DeviceProvisionServiceImpl(TbQueueProducerProvider producerProvider, TbClusterService clusterService, DeviceProfileService deviceProfileService, DeviceService deviceService, DeviceCredentialsService deviceCredentialsService, AttributesService attributesService, AuditLogService auditLogService, PartitionService partitionService) { public DeviceProvisionServiceImpl(TbQueueProducerProvider producerProvider, DeviceProfileService deviceProfileService, DeviceService deviceService, DeviceCredentialsService deviceCredentialsService, AttributesService attributesService, AuditLogService auditLogService, PartitionService partitionService) {
ruleEngineMsgProducer = producerProvider.getRuleEngineMsgProducer(); ruleEngineMsgProducer = producerProvider.getRuleEngineMsgProducer();
this.clusterService = clusterService;
this.deviceProfileService = deviceProfileService; this.deviceProfileService = deviceProfileService;
this.deviceService = deviceService; this.deviceService = deviceService;
this.deviceCredentialsService = deviceCredentialsService; this.deviceCredentialsService = deviceCredentialsService;
@ -221,7 +217,6 @@ public class DeviceProvisionServiceImpl implements DeviceProvisionService {
provisionRequest.setDeviceName(newDeviceName); provisionRequest.setDeviceName(newDeviceName);
} }
Device savedDevice = deviceService.saveDevice(provisionRequest, profile); Device savedDevice = deviceService.saveDevice(provisionRequest, profile);
clusterService.onDeviceUpdated(savedDevice, null);
saveProvisionStateAttribute(savedDevice).get(); saveProvisionStateAttribute(savedDevice).get();
pushDeviceCreatedEventToRuleEngine(savedDevice); pushDeviceCreatedEventToRuleEngine(savedDevice);
notify(savedDevice, provisionRequest, TbMsgType.PROVISION_SUCCESS, true); notify(savedDevice, provisionRequest, TbMsgType.PROVISION_SUCCESS, true);

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

@ -23,10 +23,13 @@ import org.springframework.stereotype.Component;
import org.springframework.transaction.event.TransactionalEventListener; import org.springframework.transaction.event.TransactionalEventListener;
import org.thingsboard.common.util.JacksonUtil; import org.thingsboard.common.util.JacksonUtil;
import org.thingsboard.server.cluster.TbClusterService; import org.thingsboard.server.cluster.TbClusterService;
import org.thingsboard.server.common.data.EdgeUtils;
import org.thingsboard.server.common.data.EntityType;
import org.thingsboard.server.common.data.OtaPackageInfo; import org.thingsboard.server.common.data.OtaPackageInfo;
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.AlarmApiCallResult; import org.thingsboard.server.common.data.alarm.AlarmApiCallResult;
import org.thingsboard.server.common.data.audit.ActionType;
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.relation.EntityRelation; import org.thingsboard.server.common.data.relation.EntityRelation;
@ -43,8 +46,6 @@ import org.thingsboard.server.dao.user.UserServiceImpl;
import javax.annotation.PostConstruct; 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 * 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 * Another possible approach is to implement a special annotation and a bunch of classes similar to TransactionalApplicationListener
@ -75,7 +76,7 @@ public class EdgeEventSourcingListener {
@TransactionalEventListener(fallbackExecution = true) @TransactionalEventListener(fallbackExecution = true)
public void handleEvent(SaveEntityEvent<?> event) { public void handleEvent(SaveEntityEvent<?> event) {
try { try {
if (!isValidSaveEntityEventForEdgeProcessing(event.getEntity(), event.getOldEntity())) { if (!isValidSaveEntityEventForEdgeProcessing(event)) {
return; return;
} }
log.trace("[{}] SaveEntityEvent called: {}", event.getTenantId(), event); log.trace("[{}] SaveEntityEvent called: {}", event.getTenantId(), event);
@ -89,7 +90,11 @@ public class EdgeEventSourcingListener {
@TransactionalEventListener(fallbackExecution = true) @TransactionalEventListener(fallbackExecution = true)
public void handleEvent(DeleteEntityEvent<?> event) { public void handleEvent(DeleteEntityEvent<?> event) {
EntityType entityType = event.getEntityId().getEntityType();
try { try {
if (EntityType.EDGE.equals(entityType) || EntityType.TENANT.equals(entityType)) {
return;
}
log.trace("[{}] DeleteEntityEvent called: {}", event.getTenantId(), event); log.trace("[{}] DeleteEntityEvent called: {}", event.getTenantId(), event);
tbClusterService.sendNotificationMsgToEdge(event.getTenantId(), null, event.getEntityId(), tbClusterService.sendNotificationMsgToEdge(event.getTenantId(), null, event.getEntityId(),
JacksonUtil.toString(event.getEntity()), null, EdgeEventActionType.DELETED, JacksonUtil.toString(event.getEntity()), null, EdgeEventActionType.DELETED,
@ -100,11 +105,15 @@ public class EdgeEventSourcingListener {
} }
@TransactionalEventListener(fallbackExecution = true) @TransactionalEventListener(fallbackExecution = true)
public void handleEvent(ActionEntityEvent event) { public void handleEvent(ActionEntityEvent<?> event) {
if (EntityType.DEVICE.equals(event.getEntityId().getEntityType())
&& ActionType.ASSIGNED_TO_TENANT.equals(event.getActionType())) {
return;
}
try { try {
log.trace("[{}] ActionEntityEvent called: {}", event.getTenantId(), event); log.trace("[{}] ActionEntityEvent called: {}", event.getTenantId(), event);
tbClusterService.sendNotificationMsgToEdge(event.getTenantId(), event.getEdgeId(), event.getEntityId(), tbClusterService.sendNotificationMsgToEdge(event.getTenantId(), event.getEdgeId(), event.getEntityId(),
event.getBody(), null, edgeTypeByActionType(event.getActionType()), event.getBody(), null, EdgeUtils.getEdgeEventActionTypeByActionType(event.getActionType()),
edgeSynchronizationManager.getEdgeId().get()); edgeSynchronizationManager.getEdgeId().get());
} catch (Exception e) { } catch (Exception e) {
log.error("[{}] failed to process ActionEntityEvent: {}", event.getTenantId(), event, e); log.error("[{}] failed to process ActionEntityEvent: {}", event.getTenantId(), event, e);
@ -125,33 +134,53 @@ public class EdgeEventSourcingListener {
} }
log.trace("[{}] RelationActionEvent called: {}", event.getTenantId(), event); log.trace("[{}] RelationActionEvent called: {}", event.getTenantId(), event);
tbClusterService.sendNotificationMsgToEdge(event.getTenantId(), null, null, tbClusterService.sendNotificationMsgToEdge(event.getTenantId(), null, null,
JacksonUtil.toString(relation), EdgeEventType.RELATION, edgeTypeByActionType(event.getActionType()), JacksonUtil.toString(relation), EdgeEventType.RELATION, EdgeUtils.getEdgeEventActionTypeByActionType(event.getActionType()),
edgeSynchronizationManager.getEdgeId().get()); edgeSynchronizationManager.getEdgeId().get());
} catch (Exception e) { } catch (Exception e) {
log.error("[{}] failed to process RelationActionEvent: {}", event.getTenantId(), event, e); log.error("[{}] failed to process RelationActionEvent: {}", event.getTenantId(), event, e);
} }
} }
private boolean isValidSaveEntityEventForEdgeProcessing(Object entity, Object oldEntity) { private boolean isValidSaveEntityEventForEdgeProcessing(SaveEntityEvent<?> event) {
if (entity instanceof OtaPackageInfo) { Object entity = event.getEntity();
OtaPackageInfo otaPackageInfo = (OtaPackageInfo) entity; Object oldEntity = event.getOldEntity();
return otaPackageInfo.hasUrl() || otaPackageInfo.isHasData(); switch (event.getEntityId().getEntityType()) {
} else if (entity instanceof RuleChain) { case RULE_CHAIN:
RuleChain ruleChain = (RuleChain) entity; if (entity instanceof RuleChain) {
return RuleChainType.EDGE.equals(ruleChain.getType()); RuleChain ruleChain = (RuleChain) entity;
} else if (entity instanceof User) { return RuleChainType.EDGE.equals(ruleChain.getType());
User user = (User) entity; }
if (Authority.SYS_ADMIN.equals(user.getAuthority())) { break;
case USER:
if (entity instanceof User) {
User user = (User) entity;
if (Authority.SYS_ADMIN.equals(user.getAuthority())) {
return false;
}
if (oldEntity != null) {
User oldUser = (User) oldEntity;
cleanUpUserAdditionalInfo(oldUser);
cleanUpUserAdditionalInfo(user);
return !user.equals(oldUser);
}
}
break;
case OTA_PACKAGE:
if (entity instanceof OtaPackageInfo) {
OtaPackageInfo otaPackageInfo = (OtaPackageInfo) entity;
return otaPackageInfo.hasUrl() || otaPackageInfo.isHasData();
}
break;
case ALARM:
if (entity instanceof AlarmApiCallResult || entity instanceof Alarm) {
return false;
}
break;
case TENANT:
return !event.getAdded();
case API_USAGE_STATE:
case EDGE:
return false; return false;
}
if (oldEntity != null) {
User oldUser = (User) oldEntity;
cleanUpUserAdditionalInfo(oldUser);
cleanUpUserAdditionalInfo(user);
return !user.equals(oldUser);
}
} else if (entity instanceof AlarmApiCallResult || entity instanceof Alarm) {
return false;
} }
// Default: If the entity doesn't match any of the conditions, consider it as valid. // Default: If the entity doesn't match any of the conditions, consider it as valid.
return true; return true;

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

@ -91,6 +91,7 @@ import org.thingsboard.server.queue.TbQueueCallback;
import org.thingsboard.server.queue.TbQueueMsgMetadata; import org.thingsboard.server.queue.TbQueueMsgMetadata;
import org.thingsboard.server.queue.discovery.PartitionService; import org.thingsboard.server.queue.discovery.PartitionService;
import org.thingsboard.server.queue.provider.TbQueueProducerProvider; import org.thingsboard.server.queue.provider.TbQueueProducerProvider;
import org.thingsboard.server.service.entitiy.TbLogEntityActionService;
import org.thingsboard.server.service.edge.rpc.constructor.alarm.AlarmMsgConstructorFactory; import org.thingsboard.server.service.edge.rpc.constructor.alarm.AlarmMsgConstructorFactory;
import org.thingsboard.server.service.edge.rpc.constructor.asset.AssetMsgConstructorFactory; import org.thingsboard.server.service.edge.rpc.constructor.asset.AssetMsgConstructorFactory;
import org.thingsboard.server.service.edge.rpc.constructor.customer.CustomerMsgConstructorFactory; import org.thingsboard.server.service.edge.rpc.constructor.customer.CustomerMsgConstructorFactory;
@ -111,7 +112,6 @@ import org.thingsboard.server.service.edge.rpc.constructor.widget.WidgetMsgConst
import org.thingsboard.server.service.edge.rpc.processor.alarm.AlarmEdgeProcessorFactory; import org.thingsboard.server.service.edge.rpc.processor.alarm.AlarmEdgeProcessorFactory;
import org.thingsboard.server.service.edge.rpc.processor.asset.AssetEdgeProcessorFactory; import org.thingsboard.server.service.edge.rpc.processor.asset.AssetEdgeProcessorFactory;
import org.thingsboard.server.service.edge.rpc.processor.entityview.EntityViewProcessorFactory; import org.thingsboard.server.service.edge.rpc.processor.entityview.EntityViewProcessorFactory;
import org.thingsboard.server.service.entitiy.TbNotificationEntityService;
import org.thingsboard.server.service.executors.DbCallbackExecutorService; import org.thingsboard.server.service.executors.DbCallbackExecutorService;
import org.thingsboard.server.service.profile.TbAssetProfileCache; import org.thingsboard.server.service.profile.TbAssetProfileCache;
import org.thingsboard.server.service.profile.TbDeviceProfileCache; import org.thingsboard.server.service.profile.TbDeviceProfileCache;
@ -138,7 +138,7 @@ public abstract class BaseEdgeProcessor {
protected TelemetrySubscriptionService tsSubService; protected TelemetrySubscriptionService tsSubService;
@Autowired @Autowired
protected TbNotificationEntityService notificationEntityService; protected TbLogEntityActionService logEntityActionService;
@Autowired @Autowired
protected RuleChainService ruleChainService; protected RuleChainService ruleChainService;
@ -379,10 +379,7 @@ public abstract class BaseEdgeProcessor {
EdgeEvent edgeEvent = EdgeUtils.constructEdgeEvent(tenantId, edgeId, type, action, entityId, body); EdgeEvent edgeEvent = EdgeUtils.constructEdgeEvent(tenantId, edgeId, type, action, entityId, body);
return Futures.transform(edgeEventService.saveAsync(edgeEvent), unused -> { return edgeEventService.saveAsync(edgeEvent);
tbClusterService.onEdgeEventUpdate(tenantId, edgeId);
return null;
}, dbCallbackExecutorService);
} }
protected ListenableFuture<Void> processActionForAllEdges(TenantId tenantId, EdgeEventType type, protected ListenableFuture<Void> processActionForAllEdges(TenantId tenantId, EdgeEventType type,

2
application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/asset/profile/BaseAssetProfileProcessor.java

@ -67,7 +67,7 @@ public abstract class BaseAssetProfileProcessor extends BaseEdgeProcessor {
if (created) { if (created) {
assetProfile.setId(assetProfileId); assetProfile.setId(assetProfileId);
} }
assetProfileService.saveAssetProfile(assetProfile, false); assetProfileService.saveAssetProfile(assetProfile, false, true);
} catch (Exception e) { } catch (Exception e) {
log.error("[{}] Failed to process asset profile update msg [{}]", tenantId, assetProfileUpdateMsg, e); log.error("[{}] Failed to process asset profile update msg [{}]", tenantId, assetProfileUpdateMsg, e);
throw e; throw e;

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

@ -70,7 +70,6 @@ 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);
} catch (Exception e) { } catch (Exception e) {
log.error("[{}] Failed to process device update msg [{}]", tenantId, deviceUpdateMsg, e); log.error("[{}] Failed to process device update msg [{}]", tenantId, deviceUpdateMsg, e);
throw e; throw e;

2
application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/device/profile/BaseDeviceProfileProcessor.java

@ -66,7 +66,7 @@ public abstract class BaseDeviceProfileProcessor extends BaseEdgeProcessor {
if (created) { if (created) {
deviceProfile.setId(deviceProfileId); deviceProfile.setId(deviceProfileId);
} }
deviceProfileService.saveDeviceProfile(deviceProfile, false); deviceProfileService.saveDeviceProfile(deviceProfile, false, true);
} catch (Exception e) { } catch (Exception e) {
log.error("[{}] Failed to process device profile update msg [{}]", tenantId, deviceProfileUpdateMsg, e); log.error("[{}] Failed to process device profile update msg [{}]", tenantId, deviceProfileUpdateMsg, e);
throw e; throw e;

6
application/src/main/java/org/thingsboard/server/service/edge/rpc/sync/DefaultEdgeRequestsService.java

@ -400,11 +400,7 @@ public class DefaultEdgeRequestsService implements EdgeRequestsService {
tenantId, edgeId, type, action, entityId, body); tenantId, edgeId, type, action, entityId, body);
EdgeEvent edgeEvent = EdgeUtils.constructEdgeEvent(tenantId, edgeId, type, action, entityId, body); EdgeEvent edgeEvent = EdgeUtils.constructEdgeEvent(tenantId, edgeId, type, action, entityId, body);
return edgeEventService.saveAsync(edgeEvent);
return Futures.transform(edgeEventService.saveAsync(edgeEvent), unused -> {
tbClusterService.onEdgeEventUpdate(tenantId, edgeId);
return null;
}, dbCallbackExecutorService);
} }
} }

2
application/src/main/java/org/thingsboard/server/service/entitiy/AbstractTbEntityService.java

@ -56,7 +56,7 @@ public abstract class AbstractTbEntityService {
@Autowired @Autowired
protected DbCallbackExecutorService dbExecutor; protected DbCallbackExecutorService dbExecutor;
@Autowired(required = false) @Autowired(required = false)
protected TbNotificationEntityService notificationEntityService; protected TbLogEntityActionService logEntityActionService;
@Autowired(required = false) @Autowired(required = false)
protected EdgeService edgeService; protected EdgeService edgeService;
@Autowired @Autowired

79
application/src/main/java/org/thingsboard/server/service/entitiy/DefaultTbLogEntityActionService.java

@ -0,0 +1,79 @@
/**
* Copyright © 2016-2024 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.entitiy;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.thingsboard.server.common.data.HasName;
import org.thingsboard.server.common.data.User;
import org.thingsboard.server.common.data.audit.ActionType;
import org.thingsboard.server.common.data.id.CustomerId;
import org.thingsboard.server.common.data.id.EntityId;
import org.thingsboard.server.common.data.id.TenantId;
import org.thingsboard.server.common.data.relation.EntityRelation;
import org.thingsboard.server.service.action.EntityActionService;
@Slf4j
@Service
@RequiredArgsConstructor
public class DefaultTbLogEntityActionService implements TbLogEntityActionService {
private final EntityActionService entityActionService;
@Override
public <I extends EntityId> void logEntityAction(TenantId tenantId, I entityId, ActionType actionType,
User user, Exception e, Object... additionalInfo) {
logEntityAction(tenantId, entityId, null, null, actionType, user, e, additionalInfo);
}
@Override
public <E extends HasName, I extends EntityId> void logEntityAction(TenantId tenantId, I entityId, E entity,
ActionType actionType, User user, Object... additionalInfo) {
logEntityAction(tenantId, entityId, entity, null, actionType, user, null, additionalInfo);
}
@Override
public <E extends HasName, I extends EntityId> void logEntityAction(TenantId tenantId, I entityId, E entity,
ActionType actionType, User user, Exception e,
Object... additionalInfo) {
logEntityAction(tenantId, entityId, entity, null, actionType, user, e, additionalInfo);
}
@Override
public <E extends HasName, I extends EntityId> void logEntityAction(TenantId tenantId, I entityId, E entity, CustomerId customerId,
ActionType actionType, User user, Object... additionalInfo) {
logEntityAction(tenantId, entityId, entity, customerId, actionType, user, null, additionalInfo);
}
@Override
public <E extends HasName, I extends EntityId> void logEntityAction(TenantId tenantId, I entityId, E entity,
CustomerId customerId, ActionType actionType,
User user, Exception e, Object... additionalInfo) {
if (user != null) {
entityActionService.logEntityAction(user, entityId, entity, customerId, actionType, e, additionalInfo);
} else if (e == null) {
entityActionService.pushEntityActionToRuleEngine(entityId, entity, tenantId, customerId, actionType, null, additionalInfo);
}
}
@Override
public void logEntityRelationAction(TenantId tenantId, CustomerId customerId, EntityRelation relation, User user,
ActionType actionType, Exception e, Object... additionalInfo) {
logEntityAction(tenantId, relation.getFrom(), null, customerId, actionType, user, e, additionalInfo);
logEntityAction(tenantId, relation.getTo(), null, customerId, actionType, user, e, additionalInfo);
}
}

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

@ -1,212 +0,0 @@
/**
* Copyright © 2016-2024 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.entitiy;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.thingsboard.common.util.JacksonUtil;
import org.thingsboard.server.common.msg.rule.engine.DeviceCredentialsUpdateNotificationMsg;
import org.thingsboard.server.cluster.TbClusterService;
import org.thingsboard.server.common.data.Device;
import org.thingsboard.server.common.data.HasName;
import org.thingsboard.server.common.data.Tenant;
import org.thingsboard.server.common.data.User;
import org.thingsboard.server.common.data.audit.ActionType;
import org.thingsboard.server.common.data.edge.Edge;
import org.thingsboard.server.common.data.edge.EdgeEventActionType;
import org.thingsboard.server.common.data.id.CustomerId;
import org.thingsboard.server.common.data.id.DeviceId;
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.msg.TbMsgType;
import org.thingsboard.server.common.data.plugin.ComponentLifecycleEvent;
import org.thingsboard.server.common.data.relation.EntityRelation;
import org.thingsboard.server.common.data.security.DeviceCredentials;
import org.thingsboard.server.common.msg.TbMsg;
import org.thingsboard.server.common.msg.TbMsgDataType;
import org.thingsboard.server.common.msg.TbMsgMetaData;
import org.thingsboard.server.service.action.EntityActionService;
import org.thingsboard.server.service.gateway_device.GatewayNotificationsService;
@Slf4j
@Service
@RequiredArgsConstructor
public class DefaultTbNotificationEntityService implements TbNotificationEntityService {
private final EntityActionService entityActionService;
private final TbClusterService tbClusterService;
private final GatewayNotificationsService gatewayNotificationsService;
@Override
public <I extends EntityId> void logEntityAction(TenantId tenantId, I entityId, ActionType actionType,
User user, Exception e, Object... additionalInfo) {
logEntityAction(tenantId, entityId, null, null, actionType, user, e, additionalInfo);
}
@Override
public <E extends HasName, I extends EntityId> void logEntityAction(TenantId tenantId, I entityId, E entity,
ActionType actionType, User user, Object... additionalInfo) {
logEntityAction(tenantId, entityId, entity, null, actionType, user, null, additionalInfo);
}
@Override
public <E extends HasName, I extends EntityId> void logEntityAction(TenantId tenantId, I entityId, E entity,
ActionType actionType, User user, Exception e,
Object... additionalInfo) {
logEntityAction(tenantId, entityId, entity, null, actionType, user, e, additionalInfo);
}
@Override
public <E extends HasName, I extends EntityId> void logEntityAction(TenantId tenantId, I entityId, E entity, CustomerId customerId,
ActionType actionType, User user, Object... additionalInfo) {
logEntityAction(tenantId, entityId, entity, customerId, actionType, user, null, additionalInfo);
}
@Override
public <E extends HasName, I extends EntityId> void logEntityAction(TenantId tenantId, I entityId, E entity,
CustomerId customerId, ActionType actionType,
User user, Exception e, Object... additionalInfo) {
if (user != null) {
entityActionService.logEntityAction(user, entityId, entity, customerId, actionType, e, additionalInfo);
} else if (e == null) {
entityActionService.pushEntityActionToRuleEngine(entityId, entity, tenantId, customerId, actionType, null, additionalInfo);
}
}
@Override
public void notifyCreateOrUpdateTenant(Tenant tenant, ComponentLifecycleEvent event) {
tbClusterService.onTenantChange(tenant, null);
tbClusterService.broadcastEntityStateChangeEvent(tenant.getId(), tenant.getId(), event);
}
@Override
public void notifyDeleteTenant(Tenant tenant) {
tbClusterService.onTenantDelete(tenant, null);
tbClusterService.broadcastEntityStateChangeEvent(tenant.getId(), tenant.getId(), ComponentLifecycleEvent.DELETED);
}
@Override
public void notifyCreateOrUpdateDevice(TenantId tenantId, DeviceId deviceId, CustomerId customerId,
Device device, Device oldDevice, ActionType actionType,
User user, Object... additionalInfo) {
tbClusterService.onDeviceUpdated(device, oldDevice);
logEntityAction(tenantId, deviceId, device, customerId, actionType, user, additionalInfo);
}
@Override
public void notifyDeleteDevice(TenantId tenantId, DeviceId deviceId, CustomerId customerId, Device device,
User user, Object... additionalInfo) {
gatewayNotificationsService.onDeviceDeleted(device);
tbClusterService.onDeviceDeleted(tenantId, device, null);
logEntityAction(tenantId, deviceId, device, customerId, ActionType.DELETED, user, additionalInfo);
}
@Override
public void notifyUpdateDeviceCredentials(TenantId tenantId, DeviceId deviceId, CustomerId customerId, Device device,
DeviceCredentials deviceCredentials, User user) {
tbClusterService.pushMsgToCore(new DeviceCredentialsUpdateNotificationMsg(tenantId, deviceCredentials.getDeviceId(), deviceCredentials), null);
logEntityAction(tenantId, deviceId, device, customerId, ActionType.CREDENTIALS_UPDATED, user, deviceCredentials);
}
@Override
public void notifyAssignDeviceToTenant(TenantId tenantId, TenantId newTenantId, DeviceId deviceId, CustomerId customerId,
Device device, Tenant tenant, User user, Object... additionalInfo) {
tbClusterService.onDeviceAssignedToTenant(tenantId, device);
logEntityAction(tenantId, deviceId, device, customerId, ActionType.ASSIGNED_TO_TENANT, user, additionalInfo);
pushAssignedFromNotification(tenant, newTenantId, device);
}
@Override
public void notifyCreateOrUpdateOrDeleteEdge(TenantId tenantId, EdgeId edgeId, CustomerId customerId, Edge edge,
ActionType actionType, User user, Object... additionalInfo) {
ComponentLifecycleEvent lifecycleEvent;
switch (actionType) {
case ADDED:
lifecycleEvent = ComponentLifecycleEvent.CREATED;
break;
case UPDATED:
lifecycleEvent = ComponentLifecycleEvent.UPDATED;
break;
case DELETED:
lifecycleEvent = ComponentLifecycleEvent.DELETED;
break;
default:
throw new IllegalArgumentException("Unknown actionType: " + actionType);
}
tbClusterService.broadcastEntityStateChangeEvent(tenantId, edgeId, lifecycleEvent);
logEntityAction(tenantId, edgeId, edge, customerId, actionType, user, additionalInfo);
}
@Override
public void logEntityRelationAction(TenantId tenantId, CustomerId customerId, EntityRelation relation, User user,
ActionType actionType, Exception e, Object... additionalInfo) {
logEntityAction(tenantId, relation.getFrom(), null, customerId, actionType, user, e, additionalInfo);
logEntityAction(tenantId, relation.getTo(), null, customerId, actionType, user, e, additionalInfo);
}
private void pushAssignedFromNotification(Tenant currentTenant, TenantId newTenantId, Device assignedDevice) {
String data = JacksonUtil.toString(JacksonUtil.valueToTree(assignedDevice));
if (data != null) {
TbMsg tbMsg = TbMsg.newMsg(TbMsgType.ENTITY_ASSIGNED_FROM_TENANT, assignedDevice.getId(),
assignedDevice.getCustomerId(), getMetaDataForAssignedFrom(currentTenant), TbMsgDataType.JSON, data);
tbClusterService.pushMsgToRuleEngine(newTenantId, assignedDevice.getId(), tbMsg, null);
}
}
private TbMsgMetaData getMetaDataForAssignedFrom(Tenant tenant) {
TbMsgMetaData metaData = new TbMsgMetaData();
metaData.putValue("assignedFromTenantId", tenant.getId().getId().toString());
metaData.putValue("assignedFromTenantName", tenant.getName());
return metaData;
}
public static EdgeEventActionType edgeTypeByActionType(ActionType actionType) {
switch (actionType) {
case ADDED:
return EdgeEventActionType.ADDED;
case UPDATED:
return EdgeEventActionType.UPDATED;
case ALARM_ACK:
return EdgeEventActionType.ALARM_ACK;
case ALARM_CLEAR:
return EdgeEventActionType.ALARM_CLEAR;
case ALARM_ASSIGNED:
return EdgeEventActionType.ALARM_ASSIGNED;
case ALARM_UNASSIGNED:
return EdgeEventActionType.ALARM_UNASSIGNED;
case DELETED:
return EdgeEventActionType.DELETED;
case RELATION_ADD_OR_UPDATE:
return EdgeEventActionType.RELATION_ADD_OR_UPDATE;
case RELATION_DELETED:
return EdgeEventActionType.RELATION_DELETED;
case ASSIGNED_TO_CUSTOMER:
return EdgeEventActionType.ASSIGNED_TO_CUSTOMER;
case UNASSIGNED_FROM_CUSTOMER:
return EdgeEventActionType.UNASSIGNED_FROM_CUSTOMER;
case ASSIGNED_TO_EDGE:
return EdgeEventActionType.ASSIGNED_TO_EDGE;
case UNASSIGNED_FROM_EDGE:
return EdgeEventActionType.UNASSIGNED_FROM_EDGE;
case CREDENTIALS_UPDATED:
return EdgeEventActionType.CREDENTIALS_UPDATED;
default:
return null;
}
}
}

266
application/src/main/java/org/thingsboard/server/service/entitiy/EntityStateSourcingListener.java

@ -0,0 +1,266 @@
/**
* Copyright © 2016-2024 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.entitiy;
import com.fasterxml.jackson.core.type.TypeReference;
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.ApiUsageState;
import org.thingsboard.server.common.data.Device;
import org.thingsboard.server.common.data.DeviceProfile;
import org.thingsboard.server.common.data.EntityType;
import org.thingsboard.server.common.data.TbResource;
import org.thingsboard.server.common.data.TbResourceInfo;
import org.thingsboard.server.common.data.Tenant;
import org.thingsboard.server.common.data.TenantProfile;
import org.thingsboard.server.common.data.audit.ActionType;
import org.thingsboard.server.common.data.edge.Edge;
import org.thingsboard.server.common.data.edge.EdgeEvent;
import org.thingsboard.server.common.data.id.DeviceId;
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.TenantId;
import org.thingsboard.server.common.data.msg.TbMsgType;
import org.thingsboard.server.common.data.notification.NotificationRequest;
import org.thingsboard.server.common.data.plugin.ComponentLifecycleEvent;
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.msg.TbMsg;
import org.thingsboard.server.common.msg.TbMsgDataType;
import org.thingsboard.server.common.msg.TbMsgMetaData;
import org.thingsboard.server.common.msg.rule.engine.DeviceCredentialsUpdateNotificationMsg;
import org.thingsboard.server.dao.eventsourcing.ActionEntityEvent;
import org.thingsboard.server.dao.eventsourcing.DeleteEntityEvent;
import org.thingsboard.server.dao.eventsourcing.SaveEntityEvent;
import javax.annotation.PostConstruct;
import java.util.Set;
@Component
@RequiredArgsConstructor
@Slf4j
public class EntityStateSourcingListener {
private final TbClusterService tbClusterService;
@PostConstruct
public void init() {
log.info("EntityStateSourcingListener initiated");
}
@TransactionalEventListener(fallbackExecution = true)
public void handleEvent(SaveEntityEvent<?> event) {
log.trace("[{}] SaveEntityEvent called: {}", event.getTenantId(), event);
TenantId tenantId = event.getTenantId();
EntityId entityId = event.getEntityId();
EntityType entityType = entityId.getEntityType();
boolean isCreated = event.getAdded() != null && event.getAdded();
ComponentLifecycleEvent lifecycleEvent = isCreated ? ComponentLifecycleEvent.CREATED : ComponentLifecycleEvent.UPDATED;
switch (entityType) {
case ASSET:
case ASSET_PROFILE:
case ENTITY_VIEW:
case NOTIFICATION_RULE:
tbClusterService.broadcastEntityStateChangeEvent(tenantId, entityId, lifecycleEvent);
break;
case RULE_CHAIN:
RuleChain ruleChain = (RuleChain) event.getEntity();
if (RuleChainType.CORE.equals(ruleChain.getType())) {
tbClusterService.broadcastEntityStateChangeEvent(ruleChain.getTenantId(), ruleChain.getId(), lifecycleEvent);
}
break;
case TENANT:
Tenant tenant = (Tenant) event.getEntity();
onTenantUpdate(tenant, lifecycleEvent);
break;
case TENANT_PROFILE:
TenantProfile tenantProfile = (TenantProfile) event.getEntity();
onTenantProfileUpdate(tenantProfile, lifecycleEvent);
break;
case DEVICE:
onDeviceUpdate(event.getEntity(), event.getOldEntity());
break;
case DEVICE_PROFILE:
DeviceProfile deviceProfile = (DeviceProfile) event.getEntity();
onDeviceProfileUpdate(deviceProfile, event.getOldEntity(), isCreated);
break;
case EDGE:
handleEdgeEvent(tenantId, entityId, event.getEntity(), lifecycleEvent);
break;
case TB_RESOURCE:
TbResource tbResource = (TbResource) event.getEntity();
tbClusterService.onResourceChange(tbResource, null);
break;
case API_USAGE_STATE:
ApiUsageState apiUsageState = (ApiUsageState) event.getEntity();
tbClusterService.onApiStateChange(apiUsageState, null);
break;
default:
break;
}
}
@TransactionalEventListener(fallbackExecution = true)
public void handleEvent(DeleteEntityEvent<?> event) {
log.trace("[{}] DeleteEntityEvent called: {}", event.getTenantId(), event);
TenantId tenantId = event.getTenantId();
EntityId entityId = event.getEntityId();
EntityType entityType = entityId.getEntityType();
switch (entityType) {
case ASSET:
case ASSET_PROFILE:
case ENTITY_VIEW:
case CUSTOMER:
case EDGE:
case NOTIFICATION_RULE:
tbClusterService.broadcastEntityStateChangeEvent(tenantId, entityId, ComponentLifecycleEvent.DELETED);
break;
case NOTIFICATION_REQUEST:
NotificationRequest request = (NotificationRequest) event.getEntity();
if (request.isScheduled()) {
tbClusterService.broadcastEntityStateChangeEvent(tenantId, entityId, ComponentLifecycleEvent.DELETED);
}
break;
case RULE_CHAIN:
RuleChain ruleChain = (RuleChain) event.getEntity();
if (RuleChainType.CORE.equals(ruleChain.getType())) {
Set<RuleChainId> referencingRuleChainIds = JacksonUtil.fromString(event.getBody(), new TypeReference<>() {});
if (referencingRuleChainIds != null) {
referencingRuleChainIds.forEach(referencingRuleChainId ->
tbClusterService.broadcastEntityStateChangeEvent(tenantId, referencingRuleChainId, ComponentLifecycleEvent.UPDATED));
}
tbClusterService.broadcastEntityStateChangeEvent(tenantId, ruleChain.getId(), ComponentLifecycleEvent.DELETED);
}
break;
case TENANT:
Tenant tenant = (Tenant) event.getEntity();
onTenantDeleted(tenant);
break;
case TENANT_PROFILE:
TenantProfile tenantProfile = (TenantProfile) event.getEntity();
tbClusterService.onTenantProfileDelete(tenantProfile, null);
break;
case DEVICE:
Device device = (Device) event.getEntity();
tbClusterService.onDeviceDeleted(tenantId, device, null);
break;
case DEVICE_PROFILE:
DeviceProfile deviceProfile = (DeviceProfile) event.getEntity();
onDeviceProfileDelete(event.getTenantId(), event.getEntityId(), deviceProfile);
break;
case TB_RESOURCE:
TbResourceInfo tbResource = (TbResourceInfo) event.getEntity();
tbClusterService.onResourceDeleted(tbResource, null);
break;
default:
break;
}
}
@TransactionalEventListener(fallbackExecution = true)
public void handleEvent(ActionEntityEvent<?> event) {
log.trace("[{}] ActionEntityEvent called: {}", event.getTenantId(), event);
if (ActionType.CREDENTIALS_UPDATED.equals(event.getActionType()) &&
EntityType.DEVICE.equals(event.getEntityId().getEntityType())
&& event.getEntity() instanceof DeviceCredentials) {
tbClusterService.pushMsgToCore(new DeviceCredentialsUpdateNotificationMsg(event.getTenantId(),
(DeviceId) event.getEntityId(), (DeviceCredentials) event.getEntity()), null);
} else if (ActionType.ASSIGNED_TO_TENANT.equals(event.getActionType()) && event.getEntity() instanceof Device) {
Device device = (Device) event.getEntity();
Tenant tenant = JacksonUtil.fromString(event.getBody(), Tenant.class);
if (tenant != null) {
tbClusterService.onDeviceAssignedToTenant(tenant.getId(), device);
}
pushAssignedFromNotification(tenant, event.getTenantId(), device);
}
}
private void onTenantUpdate(Tenant tenant, ComponentLifecycleEvent lifecycleEvent) {
tbClusterService.onTenantChange(tenant, null);
tbClusterService.broadcastEntityStateChangeEvent(tenant.getId(), tenant.getId(), lifecycleEvent);
}
private void onTenantDeleted(Tenant tenant) {
tbClusterService.onTenantDelete(tenant, null);
tbClusterService.broadcastEntityStateChangeEvent(tenant.getId(), tenant.getId(), ComponentLifecycleEvent.DELETED);
}
private void onTenantProfileUpdate(TenantProfile tenantProfile, ComponentLifecycleEvent lifecycleEvent) {
tbClusterService.onTenantProfileChange(tenantProfile, null);
tbClusterService.broadcastEntityStateChangeEvent(TenantId.SYS_TENANT_ID, tenantProfile.getId(), lifecycleEvent);
}
private void onDeviceProfileUpdate(DeviceProfile deviceProfile, Object oldEntity, boolean isCreated) {
DeviceProfile oldDeviceProfile = null;
if (!isCreated) {
oldDeviceProfile = getOldDeviceProfile(oldEntity);
}
tbClusterService.onDeviceProfileChange(deviceProfile, oldDeviceProfile, null);
}
private DeviceProfile getOldDeviceProfile(Object oldEntity) {
if (oldEntity instanceof DeviceProfile) {
return (DeviceProfile) oldEntity;
}
return null;
}
private void onDeviceProfileDelete(TenantId tenantId, EntityId entityId, DeviceProfile deviceProfile) {
tbClusterService.onDeviceProfileDelete(deviceProfile, null);
tbClusterService.broadcastEntityStateChangeEvent(tenantId, entityId, ComponentLifecycleEvent.DELETED);
}
private void onDeviceUpdate(Object entity, Object oldEntity) {
Device device = (Device) entity;
Device oldDevice = null;
if (oldEntity instanceof Device) {
oldDevice = (Device) oldEntity;
}
tbClusterService.onDeviceUpdated(device, oldDevice);
}
private void handleEdgeEvent(TenantId tenantId, EntityId entityId, Object entity, ComponentLifecycleEvent lifecycleEvent) {
if (entity instanceof Edge) {
tbClusterService.broadcastEntityStateChangeEvent(tenantId, entityId, lifecycleEvent);
} else if (entity instanceof EdgeEvent) {
tbClusterService.onEdgeEventUpdate(tenantId, (EdgeId) entityId);
}
}
private void pushAssignedFromNotification(Tenant currentTenant, TenantId newTenantId, Device assignedDevice) {
String data = JacksonUtil.toString(JacksonUtil.valueToTree(assignedDevice));
if (data != null) {
TbMsg tbMsg = TbMsg.newMsg(TbMsgType.ENTITY_ASSIGNED_FROM_TENANT, assignedDevice.getId(),
assignedDevice.getCustomerId(), getMetaDataForAssignedFrom(currentTenant), TbMsgDataType.JSON, data);
tbClusterService.pushMsgToRuleEngine(newTenantId, assignedDevice.getId(), tbMsg, null);
}
}
private TbMsgMetaData getMetaDataForAssignedFrom(Tenant tenant) {
TbMsgMetaData metaData = new TbMsgMetaData();
metaData.putValue("assignedFromTenantId", tenant.getId().getId().toString());
metaData.putValue("assignedFromTenantName", tenant.getName());
return metaData;
}
}

28
application/src/main/java/org/thingsboard/server/service/entitiy/TbNotificationEntityService.java → application/src/main/java/org/thingsboard/server/service/entitiy/TbLogEntityActionService.java

@ -15,22 +15,15 @@
*/ */
package org.thingsboard.server.service.entitiy; package org.thingsboard.server.service.entitiy;
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.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.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.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.plugin.ComponentLifecycleEvent;
import org.thingsboard.server.common.data.relation.EntityRelation; import org.thingsboard.server.common.data.relation.EntityRelation;
import org.thingsboard.server.common.data.security.DeviceCredentials;
public interface TbNotificationEntityService { public interface TbLogEntityActionService {
<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,
Exception e, Object... additionalInfo); Exception e, Object... additionalInfo);
@ -48,25 +41,6 @@ public interface TbNotificationEntityService {
ActionType actionType, User user, Exception e, ActionType actionType, User user, Exception e,
Object... additionalInfo); Object... additionalInfo);
void notifyCreateOrUpdateTenant(Tenant tenant, ComponentLifecycleEvent event);
void notifyDeleteTenant(Tenant tenant);
void notifyCreateOrUpdateDevice(TenantId tenantId, DeviceId deviceId, CustomerId customerId, Device device,
Device oldDevice, ActionType actionType, User user, Object... additionalInfo);
void notifyDeleteDevice(TenantId tenantId, DeviceId deviceId, CustomerId customerId, Device device,
User user, Object... additionalInfo);
void notifyUpdateDeviceCredentials(TenantId tenantId, DeviceId deviceId, CustomerId customerId, Device device,
DeviceCredentials deviceCredentials, User user);
void notifyAssignDeviceToTenant(TenantId tenantId, TenantId newTenantId, DeviceId deviceId, CustomerId customerId,
Device device, Tenant tenant, User user, Object... additionalInfo);
void notifyCreateOrUpdateOrDeleteEdge(TenantId tenantId, EdgeId edgeId, CustomerId customerId, Edge edge, ActionType actionType,
User user, Object... additionalInfo);
void logEntityRelationAction(TenantId tenantId, CustomerId customerId, EntityRelation relation, User user, void logEntityRelationAction(TenantId tenantId, CustomerId customerId, EntityRelation relation, User user,
ActionType actionType, Exception e, Object... additionalInfo); ActionType actionType, Exception e, Object... additionalInfo);
} }

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

@ -45,11 +45,11 @@ 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.logEntityAction(alarm.getTenantId(), alarm.getId(), alarm, alarm.getCustomerId(), actionType, user, savedAlarmComment); logEntityActionService.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); logEntityActionService.logEntityAction(alarm.getTenantId(), emptyId(EntityType.ALARM), alarm, actionType, user, e, alarmComment);
throw e; throw e;
} }
} }
@ -63,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.logEntityAction(alarm.getTenantId(), alarm.getId(), alarm, alarm.getCustomerId(), ActionType.DELETED_COMMENT, user, savedAlarmComment); logEntityActionService.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);
} }

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

@ -82,12 +82,12 @@ public class DefaultTbAlarmService extends AbstractTbEntityService implements Tb
resultAlarm = unassign(alarm, alarm.getAssignTs(), user); resultAlarm = unassign(alarm, alarm.getAssignTs(), user);
} }
if (result.isModified()) { if (result.isModified()) {
notificationEntityService.logEntityAction(tenantId, alarm.getOriginator(), resultAlarm, logEntityActionService.logEntityAction(tenantId, alarm.getOriginator(), resultAlarm,
resultAlarm.getCustomerId(), actionType, user); 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); logEntityActionService.logEntityAction(tenantId, emptyId(EntityType.ALARM), alarm, actionType, user, e);
throw e; throw e;
} }
} }
@ -107,7 +107,7 @@ public class DefaultTbAlarmService extends AbstractTbEntityService implements Tb
if (result.isModified()) { if (result.isModified()) {
String systemComment = String.format("Alarm was acknowledged by user %s", user.getTitle()); String systemComment = String.format("Alarm was acknowledged by user %s", user.getTitle());
addSystemAlarmComment(alarmInfo, user, "ACK", systemComment); addSystemAlarmComment(alarmInfo, user, "ACK", systemComment);
notificationEntityService.logEntityAction(alarm.getTenantId(), alarm.getOriginator(), alarmInfo, logEntityActionService.logEntityAction(alarm.getTenantId(), alarm.getOriginator(), alarmInfo,
alarmInfo.getCustomerId(), ActionType.ALARM_ACK, user); 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);
@ -130,7 +130,7 @@ public class DefaultTbAlarmService extends AbstractTbEntityService implements Tb
if (result.isCleared()) { if (result.isCleared()) {
String systemComment = String.format("Alarm was cleared by user %s", user.getTitle()); String systemComment = String.format("Alarm was cleared by user %s", user.getTitle());
addSystemAlarmComment(alarmInfo, user, "CLEAR", systemComment); addSystemAlarmComment(alarmInfo, user, "CLEAR", systemComment);
notificationEntityService.logEntityAction(alarm.getTenantId(), alarm.getOriginator(), alarmInfo, logEntityActionService.logEntityAction(alarm.getTenantId(), alarm.getOriginator(), alarmInfo,
alarmInfo.getCustomerId(), ActionType.ALARM_CLEAR, user); 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);
@ -149,7 +149,7 @@ public class DefaultTbAlarmService extends AbstractTbEntityService implements Tb
AlarmAssignee assignee = alarmInfo.getAssignee(); AlarmAssignee assignee = alarmInfo.getAssignee();
String systemComment = String.format("Alarm was assigned by user %s to user %s", user.getTitle(), assignee.getTitle()); String systemComment = String.format("Alarm was assigned by user %s to user %s", user.getTitle(), assignee.getTitle());
addSystemAlarmComment(alarmInfo, user, "ASSIGN", systemComment, assignee.getId()); addSystemAlarmComment(alarmInfo, user, "ASSIGN", systemComment, assignee.getId());
notificationEntityService.logEntityAction(alarm.getTenantId(), alarm.getOriginator(), alarmInfo, logEntityActionService.logEntityAction(alarm.getTenantId(), alarm.getOriginator(), alarmInfo,
alarmInfo.getCustomerId(), ActionType.ALARM_ASSIGNED, user); 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);
@ -167,7 +167,7 @@ public class DefaultTbAlarmService extends AbstractTbEntityService implements Tb
if (result.isModified()) { if (result.isModified()) {
String systemComment = String.format("Alarm was unassigned by user %s", user.getTitle()); String systemComment = String.format("Alarm was unassigned by user %s", user.getTitle());
addSystemAlarmComment(alarmInfo, user, "ASSIGN", systemComment); addSystemAlarmComment(alarmInfo, user, "ASSIGN", systemComment);
notificationEntityService.logEntityAction(alarm.getTenantId(), alarm.getOriginator(), alarmInfo, logEntityActionService.logEntityAction(alarm.getTenantId(), alarm.getOriginator(), alarmInfo,
alarmInfo.getCustomerId(), ActionType.ALARM_UNASSIGNED, user); 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);
@ -195,7 +195,7 @@ public class DefaultTbAlarmService extends AbstractTbEntityService implements Tb
@Override @Override
public Boolean delete(Alarm alarm, User user) { public Boolean delete(Alarm alarm, User user) {
TenantId tenantId = alarm.getTenantId(); TenantId tenantId = alarm.getTenantId();
notificationEntityService.logEntityAction(tenantId, alarm.getOriginator(), alarm, alarm.getCustomerId(), logEntityActionService.logEntityAction(tenantId, alarm.getOriginator(), alarm, alarm.getCustomerId(),
ActionType.DELETED, user); ActionType.DELETED, user);
return alarmSubscriptionService.deleteAlarm(tenantId, alarm.getId()); return alarmSubscriptionService.deleteAlarm(tenantId, alarm.getId());
} }
@ -215,7 +215,7 @@ public class DefaultTbAlarmService extends AbstractTbEntityService implements Tb
if (result.isModified()) { if (result.isModified()) {
String comment = String.format("Alarm was unassigned because user %s - was deleted", user.getTitle()); String comment = String.format("Alarm was unassigned because user %s - was deleted", user.getTitle());
addSystemAlarmComment(result.getAlarm(), null, "ASSIGN", comment); addSystemAlarmComment(result.getAlarm(), null, "ASSIGN", comment);
notificationEntityService.logEntityAction(result.getAlarm().getTenantId(), result.getAlarm().getOriginator(), result.getAlarm(), result.getAlarm().getCustomerId(), ActionType.ALARM_UNASSIGNED, null); logEntityActionService.logEntityAction(result.getAlarm().getTenantId(), result.getAlarm().getOriginator(), result.getAlarm(), result.getAlarm().getCustomerId(), ActionType.ALARM_UNASSIGNED, null);
} }
} }
} }

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

@ -31,7 +31,6 @@ import org.thingsboard.server.common.data.id.AssetId;
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.id.TenantId;
import org.thingsboard.server.common.data.plugin.ComponentLifecycleEvent;
import org.thingsboard.server.dao.asset.AssetService; 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;
@ -60,13 +59,11 @@ 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.logEntityAction(tenantId, savedAsset.getId(), savedAsset, asset.getCustomerId(), logEntityActionService.logEntityAction(tenantId, savedAsset.getId(), savedAsset, asset.getCustomerId(),
actionType, user); actionType, user);
tbClusterService.broadcastEntityStateChangeEvent(tenantId, savedAsset.getId(),
asset.getId() == null ? ComponentLifecycleEvent.CREATED : ComponentLifecycleEvent.UPDATED);
return savedAsset; return savedAsset;
} catch (Exception e) { } catch (Exception e) {
notificationEntityService.logEntityAction(tenantId, emptyId(EntityType.ASSET), asset, actionType, user, e); logEntityActionService.logEntityAction(tenantId, emptyId(EntityType.ASSET), asset, actionType, user, e);
throw e; throw e;
} }
} }
@ -80,10 +77,9 @@ public class DefaultTbAssetService extends AbstractTbEntityService implements Tb
try { try {
removeAlarmsByEntityId(tenantId, assetId); removeAlarmsByEntityId(tenantId, assetId);
assetService.deleteAsset(tenantId, assetId); assetService.deleteAsset(tenantId, assetId);
notificationEntityService.logEntityAction(tenantId, assetId, asset, asset.getCustomerId(), actionType, user, assetId.toString()); logEntityActionService.logEntityAction(tenantId, assetId, asset, asset.getCustomerId(), actionType, user, assetId.toString());
tbClusterService.broadcastEntityStateChangeEvent(tenantId, assetId, ComponentLifecycleEvent.DELETED);
} catch (Exception e) { } catch (Exception e) {
notificationEntityService.logEntityAction(tenantId, emptyId(EntityType.ASSET), actionType, user, e, logEntityActionService.logEntityAction(tenantId, emptyId(EntityType.ASSET), actionType, user, e,
assetId.toString()); assetId.toString());
throw e; throw e;
} }
@ -95,12 +91,12 @@ 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.logEntityAction(tenantId, assetId, savedAsset, customerId, actionType, user, logEntityActionService.logEntityAction(tenantId, assetId, savedAsset, customerId, actionType, user,
assetId.toString(), customerId.toString(), customer.getName()); assetId.toString(), customerId.toString(), customer.getName());
return savedAsset; return savedAsset;
} catch (Exception e) { } catch (Exception e) {
notificationEntityService.logEntityAction(tenantId, emptyId(EntityType.ASSET), actionType, user, e, logEntityActionService.logEntityAction(tenantId, emptyId(EntityType.ASSET), actionType, user, e,
assetId.toString(), customerId.toString()); assetId.toString(), customerId.toString());
throw e; throw e;
} }
@ -112,12 +108,12 @@ 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.logEntityAction(tenantId, assetId, savedAsset, customerId, actionType, user, logEntityActionService.logEntityAction(tenantId, assetId, savedAsset, customerId, actionType, user,
assetId.toString(), customerId.toString(), customer.getName()); assetId.toString(), customerId.toString(), customer.getName());
return savedAsset; return savedAsset;
} catch (Exception e) { } catch (Exception e) {
notificationEntityService.logEntityAction(tenantId, emptyId(EntityType.ASSET), actionType, user, e, assetId.toString()); logEntityActionService.logEntityAction(tenantId, emptyId(EntityType.ASSET), actionType, user, e, assetId.toString());
throw e; throw e;
} }
} }
@ -129,12 +125,12 @@ public class DefaultTbAssetService extends AbstractTbEntityService implements Tb
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()));
CustomerId customerId = publicCustomer.getId(); CustomerId customerId = publicCustomer.getId();
notificationEntityService.logEntityAction(tenantId, assetId, savedAsset, customerId, actionType, user, logEntityActionService.logEntityAction(tenantId, assetId, savedAsset, customerId, actionType, user,
assetId.toString(), customerId.toString(), publicCustomer.getName()); assetId.toString(), customerId.toString(), publicCustomer.getName());
return savedAsset; return savedAsset;
} catch (Exception e) { } catch (Exception e) {
notificationEntityService.logEntityAction(tenantId, emptyId(EntityType.ASSET), actionType, user, e, assetId.toString()); logEntityActionService.logEntityAction(tenantId, emptyId(EntityType.ASSET), actionType, user, e, assetId.toString());
throw e; throw e;
} }
} }
@ -145,11 +141,11 @@ 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.logEntityAction(tenantId, assetId, savedAsset, savedAsset.getCustomerId(), logEntityActionService.logEntityAction(tenantId, assetId, savedAsset, savedAsset.getCustomerId(),
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, logEntityActionService.logEntityAction(tenantId, emptyId(EntityType.ASSET), actionType,
user, e, assetId.toString(), edgeId.toString()); user, e, assetId.toString(), edgeId.toString());
throw e; throw e;
} }
@ -162,12 +158,12 @@ 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(), logEntityActionService.logEntityAction(tenantId, assetId, asset, asset.getCustomerId(),
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, logEntityActionService.logEntityAction(tenantId, emptyId(EntityType.ASSET), actionType,
user, e, assetId.toString(), edgeId.toString()); user, e, assetId.toString(), edgeId.toString());
throw e; throw e;
} }

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

@ -26,7 +26,6 @@ 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.AssetProfileId; import org.thingsboard.server.common.data.id.AssetProfileId;
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.dao.asset.AssetProfileService; import org.thingsboard.server.dao.asset.AssetProfileService;
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;
@ -56,14 +55,11 @@ public class DefaultTbAssetProfileService extends AbstractTbEntityService implem
} }
AssetProfile savedAssetProfile = checkNotNull(assetProfileService.saveAssetProfile(assetProfile)); AssetProfile savedAssetProfile = checkNotNull(assetProfileService.saveAssetProfile(assetProfile));
autoCommit(user, savedAssetProfile.getId()); autoCommit(user, savedAssetProfile.getId());
tbClusterService.broadcastEntityStateChangeEvent(tenantId, savedAssetProfile.getId(), logEntityActionService.logEntityAction(tenantId, savedAssetProfile.getId(), savedAssetProfile,
actionType.equals(ActionType.ADDED) ? ComponentLifecycleEvent.CREATED : ComponentLifecycleEvent.UPDATED);
notificationEntityService.logEntityAction(tenantId, savedAssetProfile.getId(), savedAssetProfile,
null, actionType, user); null, actionType, user);
return savedAssetProfile; return savedAssetProfile;
} catch (Exception e) { } catch (Exception e) {
notificationEntityService.logEntityAction(tenantId, emptyId(EntityType.ASSET_PROFILE), assetProfile, actionType, user, e); logEntityActionService.logEntityAction(tenantId, emptyId(EntityType.ASSET_PROFILE), assetProfile, actionType, user, e);
throw e; throw e;
} }
} }
@ -75,12 +71,10 @@ public class DefaultTbAssetProfileService extends AbstractTbEntityService implem
TenantId tenantId = assetProfile.getTenantId(); TenantId tenantId = assetProfile.getTenantId();
try { try {
assetProfileService.deleteAssetProfile(tenantId, assetProfileId); assetProfileService.deleteAssetProfile(tenantId, assetProfileId);
logEntityActionService.logEntityAction(tenantId, assetProfileId, assetProfile, null,
tbClusterService.broadcastEntityStateChangeEvent(tenantId, assetProfileId, ComponentLifecycleEvent.DELETED);
notificationEntityService.logEntityAction(tenantId, assetProfileId, assetProfile, null,
actionType, user, assetProfileId.toString()); actionType, user, assetProfileId.toString());
} catch (Exception e) { } catch (Exception e) {
notificationEntityService.logEntityAction(tenantId, emptyId(EntityType.ASSET_PROFILE), actionType, logEntityActionService.logEntityAction(tenantId, emptyId(EntityType.ASSET_PROFILE), actionType,
user, e, assetProfileId.toString()); user, e, assetProfileId.toString());
throw e; throw e;
} }
@ -94,16 +88,15 @@ public class DefaultTbAssetProfileService extends AbstractTbEntityService implem
if (assetProfileService.setDefaultAssetProfile(tenantId, assetProfileId)) { if (assetProfileService.setDefaultAssetProfile(tenantId, assetProfileId)) {
if (previousDefaultAssetProfile != null) { if (previousDefaultAssetProfile != null) {
previousDefaultAssetProfile = assetProfileService.findAssetProfileById(tenantId, previousDefaultAssetProfile.getId()); previousDefaultAssetProfile = assetProfileService.findAssetProfileById(tenantId, previousDefaultAssetProfile.getId());
notificationEntityService.logEntityAction(tenantId, previousDefaultAssetProfile.getId(), previousDefaultAssetProfile, logEntityActionService.logEntityAction(tenantId, previousDefaultAssetProfile.getId(), previousDefaultAssetProfile,
ActionType.UPDATED, user); ActionType.UPDATED, user);
} }
assetProfile = assetProfileService.findAssetProfileById(tenantId, assetProfileId); assetProfile = assetProfileService.findAssetProfileById(tenantId, assetProfileId);
logEntityActionService.logEntityAction(tenantId, assetProfileId, assetProfile, ActionType.UPDATED, user);
notificationEntityService.logEntityAction(tenantId, assetProfileId, assetProfile, ActionType.UPDATED, user);
} }
return assetProfile; return assetProfile;
} catch (Exception e) { } catch (Exception e) {
notificationEntityService.logEntityAction(tenantId, emptyId(EntityType.ASSET_PROFILE), ActionType.UPDATED, logEntityActionService.logEntityAction(tenantId, emptyId(EntityType.ASSET_PROFILE), ActionType.UPDATED,
user, e, assetProfileId.toString()); user, e, assetProfileId.toString());
throw e; throw e;
} }

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

@ -37,10 +37,10 @@ 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.logEntityAction(tenantId, savedCustomer.getId(), savedCustomer, null, actionType, user); logEntityActionService.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); logEntityActionService.logEntityAction(tenantId, emptyId(EntityType.CUSTOMER), customer, actionType, user, e);
throw e; throw e;
} }
} }
@ -52,11 +52,10 @@ public class DefaultTbCustomerService extends AbstractTbEntityService implements
CustomerId customerId = customer.getId(); CustomerId customerId = customer.getId();
try { try {
customerService.deleteCustomer(tenantId, customerId); customerService.deleteCustomer(tenantId, customerId);
notificationEntityService.logEntityAction(tenantId, customer.getId(), customer, customerId, actionType, logEntityActionService.logEntityAction(tenantId, customer.getId(), customer, customerId, actionType,
user, customerId.toString()); user, customerId.toString());
tbClusterService.broadcastEntityStateChangeEvent(tenantId, customer.getId(), ComponentLifecycleEvent.DELETED);
} catch (Exception e) { } catch (Exception e) {
notificationEntityService.logEntityAction(tenantId, emptyId(EntityType.CUSTOMER), actionType, user, logEntityActionService.logEntityAction(tenantId, emptyId(EntityType.CUSTOMER), actionType, user,
e, customerId.toString()); e, customerId.toString());
throw e; throw e;
} }

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

@ -51,11 +51,11 @@ 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.logEntityAction(tenantId, savedDashboard.getId(), savedDashboard, null, logEntityActionService.logEntityAction(tenantId, savedDashboard.getId(), savedDashboard, 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); logEntityActionService.logEntityAction(tenantId, emptyId(EntityType.DASHBOARD), dashboard, actionType, user, e);
throw e; throw e;
} }
} }
@ -67,9 +67,9 @@ public class DefaultTbDashboardService extends AbstractTbEntityService implement
TenantId tenantId = dashboard.getTenantId(); TenantId tenantId = dashboard.getTenantId();
try { try {
dashboardService.deleteDashboard(tenantId, dashboardId); dashboardService.deleteDashboard(tenantId, dashboardId);
notificationEntityService.logEntityAction(tenantId, dashboardId, dashboard, null, actionType, user, dashboardId.toString()); logEntityActionService.logEntityAction(tenantId, dashboardId, dashboard, null, actionType, user, dashboardId.toString());
} catch (Exception e) { } catch (Exception e) {
notificationEntityService.logEntityAction(tenantId, emptyId(EntityType.DASHBOARD), actionType, user, e, dashboardId.toString()); logEntityActionService.logEntityAction(tenantId, emptyId(EntityType.DASHBOARD), actionType, user, e, dashboardId.toString());
throw e; throw e;
} }
} }
@ -82,11 +82,11 @@ 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.logEntityAction(tenantId, dashboardId, savedDashboard, customerId, actionType, logEntityActionService.logEntityAction(tenantId, dashboardId, savedDashboard, customerId, 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, logEntityActionService.logEntityAction(tenantId, emptyId(EntityType.DASHBOARD), actionType,
user, e, dashboardId.toString(), customerId.toString()); user, e, dashboardId.toString(), customerId.toString());
throw e; throw e;
} }
@ -100,11 +100,11 @@ 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.logEntityAction(tenantId, dashboardId, savedDashboard, publicCustomer.getId(), logEntityActionService.logEntityAction(tenantId, dashboardId, savedDashboard, publicCustomer.getId(),
actionType, user, dashboardId.toString(), publicCustomer.getId().toString(), publicCustomer.getName()); actionType, user, dashboardId.toString(), 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()); logEntityActionService.logEntityAction(tenantId, emptyId(EntityType.DASHBOARD), actionType, user, e, dashboardId.toString());
throw e; throw e;
} }
} }
@ -117,11 +117,11 @@ 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.logEntityAction(tenantId, dashboardId, dashboard, publicCustomer.getId(), actionType, logEntityActionService.logEntityAction(tenantId, dashboardId, dashboard, publicCustomer.getId(), actionType,
user, dashboardId.toString(), publicCustomer.getId().toString(), publicCustomer.getName()); user, dashboardId.toString(), 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()); logEntityActionService.logEntityAction(tenantId, emptyId(EntityType.DASHBOARD), actionType, user, e, dashboardId.toString());
throw e; throw e;
} }
} }
@ -156,20 +156,20 @@ 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.logEntityAction(tenantId, savedDashboard.getId(), savedDashboard, customerId, logEntityActionService.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.logEntityAction(tenantId, savedDashboard.getId(), savedDashboard, customerId, logEntityActionService.logEntityAction(tenantId, savedDashboard.getId(), savedDashboard, customerId,
actionType, user, dashboardId.toString(), customerId.toString(), customerInfo.getTitle()); actionType, user, dashboardId.toString(), customerId.toString(), customerInfo.getTitle());
} }
return savedDashboard; return savedDashboard;
} }
} catch (Exception e) { } catch (Exception e) {
notificationEntityService.logEntityAction(tenantId, emptyId(EntityType.DASHBOARD), actionType, user, e, dashboardId.toString()); logEntityActionService.logEntityAction(tenantId, emptyId(EntityType.DASHBOARD), actionType, user, e, dashboardId.toString());
throw e; throw e;
} }
} }
@ -193,13 +193,13 @@ 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.logEntityAction(tenantId, dashboardId, savedDashboard, customerId, logEntityActionService.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;
} }
} catch (Exception e) { } catch (Exception e) {
notificationEntityService.logEntityAction(tenantId, emptyId(EntityType.DASHBOARD), actionType, user, e, dashboardId.toString()); logEntityActionService.logEntityAction(tenantId, emptyId(EntityType.DASHBOARD), actionType, user, e, dashboardId.toString());
throw e; throw e;
} }
} }
@ -223,13 +223,13 @@ 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.logEntityAction(tenantId, dashboardId, savedDashboard, customerId, logEntityActionService.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;
} }
} catch (Exception e) { } catch (Exception e) {
notificationEntityService.logEntityAction(tenantId, emptyId(EntityType.DASHBOARD), actionType, user, e, dashboardId.toString()); logEntityActionService.logEntityAction(tenantId, emptyId(EntityType.DASHBOARD), actionType, user, e, dashboardId.toString());
throw e; throw e;
} }
} }
@ -240,11 +240,11 @@ 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.logEntityAction(tenantId, dashboardId, savedDashboard, null, actionType, logEntityActionService.logEntityAction(tenantId, dashboardId, savedDashboard, null, actionType,
user, dashboardId.toString(), edgeId.toString(), edge.getName()); user, dashboardId.toString(), edgeId.toString(), edge.getName());
return savedDashboard; return savedDashboard;
} catch (Exception e) { } catch (Exception e) {
notificationEntityService.logEntityAction(tenantId, emptyId(EntityType.DEVICE), logEntityActionService.logEntityAction(tenantId, emptyId(EntityType.DEVICE),
actionType, user, e, dashboardId.toString(), edgeId); actionType, user, e, dashboardId.toString(), edgeId);
throw e; throw e;
} }
@ -258,11 +258,11 @@ 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, logEntityActionService.logEntityAction(tenantId, dashboardId, dashboard, null, actionType,
user, dashboardId.toString(), edgeId.toString(), edge.getName()); 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, logEntityActionService.logEntityAction(tenantId, emptyId(EntityType.DASHBOARD), actionType, user, e,
dashboardId.toString(), edgeId.toString()); dashboardId.toString(), edgeId.toString());
throw e; throw e;
} }
@ -275,11 +275,11 @@ 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.logEntityAction(tenantId, dashboardId, savedDashboard, customer.getId(), logEntityActionService.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) {
notificationEntityService.logEntityAction(tenantId, emptyId(EntityType.DASHBOARD), actionType, user, e, dashboardId.toString()); logEntityActionService.logEntityAction(tenantId, emptyId(EntityType.DASHBOARD), actionType, user, e, dashboardId.toString());
throw e; throw e;
} }
} }

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

@ -41,7 +41,6 @@ import org.thingsboard.server.dao.device.DeviceService;
import org.thingsboard.server.dao.device.claim.ClaimResponse; import org.thingsboard.server.dao.device.claim.ClaimResponse;
import org.thingsboard.server.dao.device.claim.ClaimResult; import org.thingsboard.server.dao.device.claim.ClaimResult;
import org.thingsboard.server.dao.device.claim.ReclaimResult; import org.thingsboard.server.dao.device.claim.ReclaimResult;
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;
@ -54,39 +53,36 @@ public class DefaultTbDeviceService extends AbstractTbEntityService implements T
private final DeviceService deviceService; private final DeviceService deviceService;
private final DeviceCredentialsService deviceCredentialsService; private final DeviceCredentialsService deviceCredentialsService;
private final ClaimDevicesService claimDevicesService; private final ClaimDevicesService claimDevicesService;
private final TenantService tenantService;
@Override @Override
public Device save(Device device, Device oldDevice, String accessToken, User user) throws Exception { public Device save(Device device, String accessToken, User user) throws Exception {
ActionType actionType = device.getId() == null ? ActionType.ADDED : ActionType.UPDATED; ActionType actionType = device.getId() == null ? ActionType.ADDED : ActionType.UPDATED;
TenantId tenantId = device.getTenantId(); TenantId tenantId = device.getTenantId();
try { try {
Device savedDevice = checkNotNull(deviceService.saveDeviceWithAccessToken(device, accessToken)); Device savedDevice = checkNotNull(deviceService.saveDeviceWithAccessToken(device, accessToken));
autoCommit(user, savedDevice.getId()); autoCommit(user, savedDevice.getId());
notificationEntityService.notifyCreateOrUpdateDevice(tenantId, savedDevice.getId(), savedDevice.getCustomerId(), logEntityActionService.logEntityAction(tenantId, savedDevice.getId(), savedDevice, savedDevice.getCustomerId(),
savedDevice, oldDevice, actionType, user); actionType, user);
return savedDevice; return savedDevice;
} catch (Exception e) { } catch (Exception e) {
notificationEntityService.logEntityAction(tenantId, emptyId(EntityType.DEVICE), device, actionType, user, e); logEntityActionService.logEntityAction(tenantId, emptyId(EntityType.DEVICE), device, actionType, user, e);
throw e; throw e;
} }
} }
@Override @Override
public Device saveDeviceWithCredentials(Device device, DeviceCredentials credentials, User user) throws ThingsboardException { public Device saveDeviceWithCredentials(Device device, DeviceCredentials credentials, User user) throws ThingsboardException {
boolean isCreate = device.getId() == null; ActionType actionType = device.getId() == null ? ActionType.ADDED : ActionType.UPDATED;
ActionType actionType = isCreate ? ActionType.ADDED : ActionType.UPDATED;
TenantId tenantId = device.getTenantId(); TenantId tenantId = device.getTenantId();
try { try {
Device oldDevice = isCreate ? null : deviceService.findDeviceById(tenantId, device.getId());
Device savedDevice = checkNotNull(deviceService.saveDeviceWithCredentials(device, credentials)); Device savedDevice = checkNotNull(deviceService.saveDeviceWithCredentials(device, credentials));
notificationEntityService.notifyCreateOrUpdateDevice(tenantId, savedDevice.getId(), savedDevice.getCustomerId(), logEntityActionService.logEntityAction(tenantId, savedDevice.getId(), savedDevice, savedDevice.getCustomerId(),
savedDevice, oldDevice, actionType, user); actionType, user);
return savedDevice; return savedDevice;
} catch (Exception e) { } catch (Exception e) {
notificationEntityService.logEntityAction(tenantId, emptyId(EntityType.DEVICE), device, actionType, user, e); logEntityActionService.logEntityAction(tenantId, emptyId(EntityType.DEVICE), device, actionType, user, e);
throw e; throw e;
} }
} }
@ -94,15 +90,16 @@ public class DefaultTbDeviceService extends AbstractTbEntityService implements T
@Override @Override
@Transactional @Transactional
public void delete(Device device, User user) { public void delete(Device device, User user) {
ActionType actionType = ActionType.DELETED;
TenantId tenantId = device.getTenantId(); TenantId tenantId = device.getTenantId();
DeviceId deviceId = device.getId(); DeviceId deviceId = device.getId();
try { try {
removeAlarmsByEntityId(tenantId, deviceId); removeAlarmsByEntityId(tenantId, deviceId);
deviceService.deleteDevice(tenantId, deviceId); deviceService.deleteDevice(tenantId, deviceId);
notificationEntityService.notifyDeleteDevice(tenantId, deviceId, device.getCustomerId(), device, logEntityActionService.logEntityAction(tenantId, deviceId, device, device.getCustomerId(), actionType,
user, deviceId.toString()); user, deviceId.toString());
} catch (Exception e) { } catch (Exception e) {
notificationEntityService.logEntityAction(tenantId, emptyId(EntityType.DEVICE), ActionType.DELETED, logEntityActionService.logEntityAction(tenantId, emptyId(EntityType.DEVICE), actionType,
user, e, deviceId.toString()); user, e, deviceId.toString());
throw e; throw e;
} }
@ -114,12 +111,12 @@ 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.logEntityAction(tenantId, deviceId, savedDevice, customerId, actionType, user, logEntityActionService.logEntityAction(tenantId, deviceId, savedDevice, customerId, actionType, user,
deviceId.toString(), customerId.toString(), customer.getName()); deviceId.toString(), customerId.toString(), customer.getName());
return savedDevice; return savedDevice;
} catch (Exception e) { } catch (Exception e) {
notificationEntityService.logEntityAction(tenantId, emptyId(EntityType.DEVICE), actionType, user, logEntityActionService.logEntityAction(tenantId, emptyId(EntityType.DEVICE), actionType, user,
e, deviceId.toString(), customerId.toString()); e, deviceId.toString(), customerId.toString());
throw e; throw e;
} }
@ -134,12 +131,12 @@ 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.logEntityAction(tenantId, deviceId, savedDevice, customerId, actionType, user, logEntityActionService.logEntityAction(tenantId, deviceId, savedDevice, customerId, actionType, user,
deviceId.toString(), customerId.toString(), customer.getName()); deviceId.toString(), customerId.toString(), customer.getName());
return savedDevice; return savedDevice;
} catch (Exception e) { } catch (Exception e) {
notificationEntityService.logEntityAction(tenantId, emptyId(EntityType.DEVICE), actionType, logEntityActionService.logEntityAction(tenantId, emptyId(EntityType.DEVICE), actionType,
user, e, deviceId.toString()); user, e, deviceId.toString());
throw e; throw e;
} }
@ -152,12 +149,12 @@ 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.logEntityAction(tenantId, deviceId, savedDevice, savedDevice.getCustomerId(), logEntityActionService.logEntityAction(tenantId, deviceId, savedDevice, savedDevice.getCustomerId(),
actionType, user, deviceId.toString(), publicCustomer.getId().toString(), publicCustomer.getName()); actionType, user, deviceId.toString(), publicCustomer.getId().toString(), publicCustomer.getName());
return savedDevice; return savedDevice;
} catch (Exception e) { } catch (Exception e) {
notificationEntityService.logEntityAction(tenantId, emptyId(EntityType.DEVICE), actionType, logEntityActionService.logEntityAction(tenantId, emptyId(EntityType.DEVICE), actionType,
user, e, deviceId.toString()); user, e, deviceId.toString());
throw e; throw e;
} }
@ -169,11 +166,11 @@ public class DefaultTbDeviceService extends AbstractTbEntityService implements T
DeviceId deviceId = device.getId(); DeviceId deviceId = device.getId();
try { try {
DeviceCredentials deviceCredentials = checkNotNull(deviceCredentialsService.findDeviceCredentialsByDeviceId(tenantId, deviceId)); DeviceCredentials deviceCredentials = checkNotNull(deviceCredentialsService.findDeviceCredentialsByDeviceId(tenantId, deviceId));
notificationEntityService.logEntityAction(tenantId, deviceId, device, device.getCustomerId(), logEntityActionService.logEntityAction(tenantId, deviceId, device, device.getCustomerId(),
ActionType.CREDENTIALS_READ, user, deviceId.toString()); ActionType.CREDENTIALS_READ, user, deviceId.toString());
return deviceCredentials; return deviceCredentials;
} catch (Exception e) { } catch (Exception e) {
notificationEntityService.logEntityAction(tenantId, emptyId(EntityType.DEVICE), logEntityActionService.logEntityAction(tenantId, emptyId(EntityType.DEVICE),
ActionType.CREDENTIALS_READ, user, e, deviceId.toString()); ActionType.CREDENTIALS_READ, user, e, deviceId.toString());
throw e; throw e;
} }
@ -181,15 +178,17 @@ public class DefaultTbDeviceService extends AbstractTbEntityService implements T
@Override @Override
public DeviceCredentials updateDeviceCredentials(Device device, DeviceCredentials deviceCredentials, User user) throws ThingsboardException { public DeviceCredentials updateDeviceCredentials(Device device, DeviceCredentials deviceCredentials, User user) throws ThingsboardException {
ActionType actionType = ActionType.CREDENTIALS_UPDATED;
TenantId tenantId = device.getTenantId(); TenantId tenantId = device.getTenantId();
DeviceId deviceId = device.getId(); DeviceId deviceId = device.getId();
try { try {
DeviceCredentials result = checkNotNull(deviceCredentialsService.updateDeviceCredentials(tenantId, deviceCredentials)); DeviceCredentials result = checkNotNull(deviceCredentialsService.updateDeviceCredentials(tenantId, deviceCredentials));
notificationEntityService.notifyUpdateDeviceCredentials(tenantId, deviceId, device.getCustomerId(), device, result, user); logEntityActionService.logEntityAction(tenantId, deviceId, device, device.getCustomerId(),
actionType, user, deviceCredentials);
return result; return result;
} catch (Exception e) { } catch (Exception e) {
notificationEntityService.logEntityAction(tenantId, emptyId(EntityType.DEVICE), logEntityActionService.logEntityAction(tenantId, emptyId(EntityType.DEVICE),
ActionType.CREDENTIALS_UPDATED, user, e, deviceCredentials); actionType, user, e, deviceCredentials);
throw e; throw e;
} }
} }
@ -200,7 +199,7 @@ public class DefaultTbDeviceService extends AbstractTbEntityService implements T
return Futures.transform(future, result -> { return Futures.transform(future, result -> {
if (result != null && result.getResponse().equals(ClaimResponse.SUCCESS)) { if (result != null && result.getResponse().equals(ClaimResponse.SUCCESS)) {
notificationEntityService.logEntityAction(tenantId, device.getId(), result.getDevice(), customerId, logEntityActionService.logEntityAction(tenantId, device.getId(), result.getDevice(), customerId,
ActionType.ASSIGNED_TO_CUSTOMER, user, device.getId().toString(), customerId.toString(), ActionType.ASSIGNED_TO_CUSTOMER, user, device.getId().toString(), customerId.toString(),
customerService.findCustomerById(tenantId, customerId).getName()); customerService.findCustomerById(tenantId, customerId).getName());
} }
@ -215,7 +214,7 @@ public class DefaultTbDeviceService extends AbstractTbEntityService implements T
return Futures.transform(future, result -> { return Futures.transform(future, result -> {
Customer unassignedCustomer = result.getUnassignedCustomer(); Customer unassignedCustomer = result.getUnassignedCustomer();
if (unassignedCustomer != null) { if (unassignedCustomer != null) {
notificationEntityService.logEntityAction(tenantId, device.getId(), device, device.getCustomerId(), logEntityActionService.logEntityAction(tenantId, device.getId(), device, device.getCustomerId(),
ActionType.UNASSIGNED_FROM_CUSTOMER, user, device.getId().toString(), ActionType.UNASSIGNED_FROM_CUSTOMER, user, device.getId().toString(),
unassignedCustomer.getId().toString(), unassignedCustomer.getName()); unassignedCustomer.getId().toString(), unassignedCustomer.getName());
} }
@ -225,20 +224,20 @@ public class DefaultTbDeviceService extends AbstractTbEntityService implements T
@Override @Override
public Device assignDeviceToTenant(Device device, Tenant newTenant, User user) { public Device assignDeviceToTenant(Device device, Tenant newTenant, User user) {
ActionType actionType = ActionType.ASSIGNED_TO_TENANT;
TenantId tenantId = device.getTenantId(); TenantId tenantId = device.getTenantId();
TenantId newTenantId = newTenant.getId(); TenantId newTenantId = newTenant.getId();
DeviceId deviceId = device.getId(); DeviceId deviceId = device.getId();
try { try {
Tenant tenant = tenantService.findTenantById(tenantId);
Device assignedDevice = deviceService.assignDeviceToTenant(newTenantId, device); Device assignedDevice = deviceService.assignDeviceToTenant(newTenantId, device);
notificationEntityService.notifyAssignDeviceToTenant(tenantId, newTenantId, deviceId, logEntityActionService.logEntityAction(tenantId, deviceId, assignedDevice, assignedDevice.getCustomerId(),
assignedDevice.getCustomerId(), assignedDevice, tenant, user, newTenantId.toString(), newTenant.getName()); actionType, user, newTenantId.toString(), newTenant.getName());
return assignedDevice; return assignedDevice;
} catch (Exception e) { } catch (Exception e) {
notificationEntityService.logEntityAction(tenantId, emptyId(EntityType.DEVICE), logEntityActionService.logEntityAction(tenantId, emptyId(EntityType.DEVICE),
ActionType.ASSIGNED_TO_TENANT, user, e, deviceId.toString()); actionType, user, e, deviceId.toString());
throw e; throw e;
} }
} }
@ -249,12 +248,12 @@ 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.logEntityAction(tenantId, deviceId, savedDevice, savedDevice.getCustomerId(), logEntityActionService.logEntityAction(tenantId, deviceId, savedDevice, savedDevice.getCustomerId(),
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), logEntityActionService.logEntityAction(tenantId, emptyId(EntityType.DEVICE),
actionType, user, e, deviceId.toString(), edgeId.toString()); actionType, user, e, deviceId.toString(), edgeId.toString());
throw e; throw e;
} }
@ -268,12 +267,12 @@ public class DefaultTbDeviceService extends AbstractTbEntityService implements T
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(), logEntityActionService.logEntityAction(tenantId, deviceId, savedDevice, savedDevice.getCustomerId(),
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), logEntityActionService.logEntityAction(tenantId, emptyId(EntityType.DEVICE),
actionType, user, e, deviceId.toString(), edgeId.toString()); actionType, user, e, deviceId.toString(), edgeId.toString());
throw e; throw e;
} }

2
application/src/main/java/org/thingsboard/server/service/entitiy/device/TbDeviceService.java

@ -31,7 +31,7 @@ import org.thingsboard.server.dao.device.claim.ReclaimResult;
public interface TbDeviceService { public interface TbDeviceService {
Device save(Device device, Device oldDevice, String accessToken, User user) throws Exception; Device save(Device device, String accessToken, User user) throws Exception;
Device saveDeviceWithCredentials(Device device, DeviceCredentials deviceCredentials, User user) throws ThingsboardException; Device saveDeviceWithCredentials(Device device, DeviceCredentials deviceCredentials, User user) throws ThingsboardException;

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

@ -25,13 +25,9 @@ import org.thingsboard.server.common.data.audit.ActionType;
import org.thingsboard.server.common.data.exception.ThingsboardException; import org.thingsboard.server.common.data.exception.ThingsboardException;
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.common.data.id.TenantId;
import org.thingsboard.server.common.data.plugin.ComponentLifecycleEvent;
import org.thingsboard.server.dao.device.DeviceProfileService; import org.thingsboard.server.dao.device.DeviceProfileService;
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 org.thingsboard.server.service.ota.OtaPackageStateService;
import java.util.Objects;
@Service @Service
@TbCoreComponent @TbCoreComponent
@ -40,38 +36,20 @@ import java.util.Objects;
public class DefaultTbDeviceProfileService extends AbstractTbEntityService implements TbDeviceProfileService { public class DefaultTbDeviceProfileService extends AbstractTbEntityService implements TbDeviceProfileService {
private final DeviceProfileService deviceProfileService; private final DeviceProfileService deviceProfileService;
private final OtaPackageStateService otaPackageStateService;
@Override @Override
public DeviceProfile save(DeviceProfile deviceProfile, User user) throws Exception { public DeviceProfile save(DeviceProfile deviceProfile, User user) throws Exception {
ActionType actionType = deviceProfile.getId() == null ? ActionType.ADDED : ActionType.UPDATED; ActionType actionType = deviceProfile.getId() == null ? ActionType.ADDED : ActionType.UPDATED;
TenantId tenantId = deviceProfile.getTenantId(); TenantId tenantId = deviceProfile.getTenantId();
try { try {
boolean isFirmwareChanged = false;
boolean isSoftwareChanged = false;
if (actionType.equals(ActionType.UPDATED)) {
DeviceProfile oldDeviceProfile = deviceProfileService.findDeviceProfileById(tenantId, deviceProfile.getId());
if (!Objects.equals(deviceProfile.getFirmwareId(), oldDeviceProfile.getFirmwareId())) {
isFirmwareChanged = true;
}
if (!Objects.equals(deviceProfile.getSoftwareId(), oldDeviceProfile.getSoftwareId())) {
isSoftwareChanged = true;
}
}
DeviceProfile savedDeviceProfile = checkNotNull(deviceProfileService.saveDeviceProfile(deviceProfile)); DeviceProfile savedDeviceProfile = checkNotNull(deviceProfileService.saveDeviceProfile(deviceProfile));
autoCommit(user, savedDeviceProfile.getId()); autoCommit(user, savedDeviceProfile.getId());
tbClusterService.onDeviceProfileChange(savedDeviceProfile, null);
tbClusterService.broadcastEntityStateChangeEvent(tenantId, savedDeviceProfile.getId(),
actionType.equals(ActionType.ADDED) ? ComponentLifecycleEvent.CREATED : ComponentLifecycleEvent.UPDATED);
otaPackageStateService.update(savedDeviceProfile, isFirmwareChanged, isSoftwareChanged);
notificationEntityService.logEntityAction(tenantId, savedDeviceProfile.getId(), savedDeviceProfile, logEntityActionService.logEntityAction(tenantId, savedDeviceProfile.getId(), savedDeviceProfile,
null, actionType, user); null, actionType, user);
return savedDeviceProfile; return savedDeviceProfile;
} catch (Exception e) { } catch (Exception e) {
notificationEntityService.logEntityAction(tenantId, emptyId(EntityType.DEVICE_PROFILE), deviceProfile, actionType, user, e); logEntityActionService.logEntityAction(tenantId, emptyId(EntityType.DEVICE_PROFILE), deviceProfile, actionType, user, e);
throw e; throw e;
} }
} }
@ -84,12 +62,10 @@ public class DefaultTbDeviceProfileService extends AbstractTbEntityService imple
try { try {
deviceProfileService.deleteDeviceProfile(tenantId, deviceProfileId); deviceProfileService.deleteDeviceProfile(tenantId, deviceProfileId);
tbClusterService.onDeviceProfileDelete(deviceProfile, null); logEntityActionService.logEntityAction(tenantId, deviceProfileId, deviceProfile, null,
tbClusterService.broadcastEntityStateChangeEvent(tenantId, deviceProfileId, ComponentLifecycleEvent.DELETED);
notificationEntityService.logEntityAction(tenantId, deviceProfileId, deviceProfile, null,
actionType, user, deviceProfileId.toString()); actionType, user, deviceProfileId.toString());
} catch (Exception e) { } catch (Exception e) {
notificationEntityService.logEntityAction(tenantId, emptyId(EntityType.DEVICE_PROFILE), actionType, logEntityActionService.logEntityAction(tenantId, emptyId(EntityType.DEVICE_PROFILE), actionType,
user, e, deviceProfileId.toString()); user, e, deviceProfileId.toString());
throw e; throw e;
} }
@ -103,16 +79,16 @@ public class DefaultTbDeviceProfileService extends AbstractTbEntityService imple
if (deviceProfileService.setDefaultDeviceProfile(tenantId, deviceProfileId)) { if (deviceProfileService.setDefaultDeviceProfile(tenantId, deviceProfileId)) {
if (previousDefaultDeviceProfile != null) { if (previousDefaultDeviceProfile != null) {
previousDefaultDeviceProfile = deviceProfileService.findDeviceProfileById(tenantId, previousDefaultDeviceProfile.getId()); previousDefaultDeviceProfile = deviceProfileService.findDeviceProfileById(tenantId, previousDefaultDeviceProfile.getId());
notificationEntityService.logEntityAction(tenantId, previousDefaultDeviceProfile.getId(), previousDefaultDeviceProfile, logEntityActionService.logEntityAction(tenantId, previousDefaultDeviceProfile.getId(), previousDefaultDeviceProfile,
ActionType.UPDATED, user); ActionType.UPDATED, user);
} }
deviceProfile = deviceProfileService.findDeviceProfileById(tenantId, deviceProfileId); deviceProfile = deviceProfileService.findDeviceProfileById(tenantId, deviceProfileId);
notificationEntityService.logEntityAction(tenantId, deviceProfileId, deviceProfile, ActionType.UPDATED, user); logEntityActionService.logEntityAction(tenantId, deviceProfileId, deviceProfile, ActionType.UPDATED, user);
} }
return deviceProfile; return deviceProfile;
} catch (Exception e) { } catch (Exception e) {
notificationEntityService.logEntityAction(tenantId, emptyId(EntityType.DEVICE_PROFILE), ActionType.UPDATED, logEntityActionService.logEntityAction(tenantId, emptyId(EntityType.DEVICE_PROFILE), ActionType.UPDATED,
user, e, deviceProfileId.toString()); user, e, deviceProfileId.toString());
throw e; throw e;
} }

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

@ -48,36 +48,37 @@ public class DefaultTbEdgeService extends AbstractTbEntityService implements TbE
ActionType actionType = edge.getId() == null ? ActionType.ADDED : ActionType.UPDATED; ActionType actionType = edge.getId() == null ? ActionType.ADDED : ActionType.UPDATED;
TenantId tenantId = edge.getTenantId(); TenantId tenantId = edge.getTenantId();
try { try {
if (actionType == ActionType.ADDED && edge.getRootRuleChainId() == null) { if (ActionType.ADDED.equals(actionType) && edge.getRootRuleChainId() == null) {
edge.setRootRuleChainId(edgeTemplateRootRuleChain.getId()); edge.setRootRuleChainId(edgeTemplateRootRuleChain.getId());
} }
Edge savedEdge = checkNotNull(edgeService.saveEdge(edge)); Edge savedEdge = checkNotNull(edgeService.saveEdge(edge));
EdgeId edgeId = savedEdge.getId(); EdgeId edgeId = savedEdge.getId();
if (actionType == ActionType.ADDED) { if (ActionType.ADDED.equals(actionType)) {
ruleChainService.assignRuleChainToEdge(tenantId, edgeTemplateRootRuleChain.getId(), edgeId); ruleChainService.assignRuleChainToEdge(tenantId, edgeTemplateRootRuleChain.getId(), edgeId);
edgeNotificationService.setEdgeRootRuleChain(tenantId, savedEdge, edgeTemplateRootRuleChain.getId()); edgeNotificationService.setEdgeRootRuleChain(tenantId, savedEdge, edgeTemplateRootRuleChain.getId());
edgeService.assignDefaultRuleChainsToEdge(tenantId, edgeId); edgeService.assignDefaultRuleChainsToEdge(tenantId, edgeId);
} }
notificationEntityService.notifyCreateOrUpdateOrDeleteEdge(tenantId, edgeId, savedEdge.getCustomerId(), savedEdge, actionType, user); logEntityActionService.logEntityAction(tenantId, edgeId, savedEdge, savedEdge.getCustomerId(), actionType, user);
return savedEdge; return savedEdge;
} catch (Exception e) { } catch (Exception e) {
notificationEntityService.logEntityAction(tenantId, emptyId(EntityType.EDGE), edge, actionType, user, e); logEntityActionService.logEntityAction(tenantId, emptyId(EntityType.EDGE), edge, actionType, user, e);
throw e; throw e;
} }
} }
@Override @Override
public void delete(Edge edge, User user) { public void delete(Edge edge, User user) {
ActionType actionType = ActionType.DELETED;
EdgeId edgeId = edge.getId(); EdgeId edgeId = edge.getId();
TenantId tenantId = edge.getTenantId(); TenantId tenantId = edge.getTenantId();
try { try {
edgeService.deleteEdge(tenantId, edgeId); edgeService.deleteEdge(tenantId, edgeId);
notificationEntityService.notifyCreateOrUpdateOrDeleteEdge(tenantId, edgeId, edge.getCustomerId(), edge, ActionType.DELETED, user, edgeId.toString()); logEntityActionService.logEntityAction(tenantId, edgeId, edge, edge.getCustomerId(), actionType, user, edgeId.toString());
} catch (Exception e) { } catch (Exception e) {
notificationEntityService.logEntityAction(tenantId, emptyId(EntityType.EDGE), ActionType.DELETED, logEntityActionService.logEntityAction(tenantId, emptyId(EntityType.EDGE), actionType,
user, e, edgeId.toString()); user, e, edgeId.toString());
throw e; throw e;
} }
@ -89,12 +90,12 @@ 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.logEntityAction(tenantId, edgeId, savedEdge, customerId, actionType, logEntityActionService.logEntityAction(tenantId, edgeId, savedEdge, customerId, 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), logEntityActionService.logEntityAction(tenantId, emptyId(EntityType.EDGE),
ActionType.ASSIGNED_TO_CUSTOMER, user, e, edgeId.toString(), customerId.toString()); ActionType.ASSIGNED_TO_CUSTOMER, user, e, edgeId.toString(), customerId.toString());
throw e; throw e;
} }
@ -108,11 +109,11 @@ 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.logEntityAction(tenantId, edgeId, savedEdge, customerId, actionType, logEntityActionService.logEntityAction(tenantId, edgeId, savedEdge, customerId, 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), logEntityActionService.logEntityAction(tenantId, emptyId(EntityType.EDGE),
ActionType.UNASSIGNED_FROM_CUSTOMER, user, e, edgeId.toString()); ActionType.UNASSIGNED_FROM_CUSTOMER, user, e, edgeId.toString());
throw e; throw e;
} }
@ -120,18 +121,19 @@ public class DefaultTbEdgeService extends AbstractTbEntityService implements TbE
@Override @Override
public Edge assignEdgeToPublicCustomer(TenantId tenantId, EdgeId edgeId, User user) throws ThingsboardException { public Edge assignEdgeToPublicCustomer(TenantId tenantId, EdgeId edgeId, User user) throws ThingsboardException {
ActionType actionType = ActionType.ASSIGNED_TO_CUSTOMER;
Customer publicCustomer = customerService.findOrCreatePublicCustomer(tenantId); Customer publicCustomer = customerService.findOrCreatePublicCustomer(tenantId);
CustomerId customerId = publicCustomer.getId(); CustomerId customerId = publicCustomer.getId();
try { try {
Edge savedEdge = checkNotNull(edgeService.assignEdgeToCustomer(tenantId, edgeId, customerId)); Edge savedEdge = checkNotNull(edgeService.assignEdgeToCustomer(tenantId, edgeId, customerId));
notificationEntityService.notifyCreateOrUpdateOrDeleteEdge(tenantId, edgeId, customerId, savedEdge, ActionType.ASSIGNED_TO_CUSTOMER, user, logEntityActionService.logEntityAction(tenantId, edgeId, savedEdge, customerId, actionType, user,
edgeId.toString(), customerId.toString(), publicCustomer.getName()); edgeId.toString(), customerId.toString(), publicCustomer.getName());
return savedEdge; return savedEdge;
} catch (Exception e) { } catch (Exception e) {
notificationEntityService.logEntityAction(tenantId, emptyId(EntityType.EDGE), logEntityActionService.logEntityAction(tenantId, emptyId(EntityType.EDGE),
ActionType.ASSIGNED_TO_CUSTOMER, user, e, edgeId.toString()); actionType, user, e, edgeId.toString());
throw e; throw e;
} }
} }
@ -142,10 +144,10 @@ public class DefaultTbEdgeService extends AbstractTbEntityService implements TbE
EdgeId edgeId = edge.getId(); EdgeId edgeId = edge.getId();
try { try {
Edge updatedEdge = edgeNotificationService.setEdgeRootRuleChain(tenantId, edge, ruleChainId); Edge updatedEdge = edgeNotificationService.setEdgeRootRuleChain(tenantId, edge, ruleChainId);
notificationEntityService.logEntityAction(tenantId, edgeId, edge, null, ActionType.UPDATED, user); logEntityActionService.logEntityAction(tenantId, edgeId, edge, null, ActionType.UPDATED, user);
return updatedEdge; return updatedEdge;
} catch (Exception e) { } catch (Exception e) {
notificationEntityService.logEntityAction(tenantId, emptyId(EntityType.EDGE), logEntityActionService.logEntityAction(tenantId, emptyId(EntityType.EDGE),
ActionType.UPDATED, user, e, edgeId.toString()); ActionType.UPDATED, user, e, edgeId.toString());
throw e; throw e;
} }

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

@ -43,10 +43,10 @@ public class DefaultTbEntityRelationService extends AbstractTbEntityService impl
ActionType actionType = ActionType.RELATION_ADD_OR_UPDATE; ActionType actionType = ActionType.RELATION_ADD_OR_UPDATE;
try { try {
relationService.saveRelation(tenantId, relation); relationService.saveRelation(tenantId, relation);
notificationEntityService.logEntityRelationAction(tenantId, customerId, logEntityActionService.logEntityRelationAction(tenantId, customerId,
relation, user, actionType, null, relation); relation, user, actionType, null, relation);
} catch (Exception e) { } catch (Exception e) {
notificationEntityService.logEntityRelationAction(tenantId, customerId, logEntityActionService.logEntityRelationAction(tenantId, customerId,
relation, user, actionType, e, relation); relation, user, actionType, e, relation);
throw e; throw e;
} }
@ -60,9 +60,9 @@ public class DefaultTbEntityRelationService extends AbstractTbEntityService impl
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.logEntityRelationAction(tenantId, customerId, relation, user, actionType, null, relation); logEntityActionService.logEntityRelationAction(tenantId, customerId, relation, user, actionType, null, relation);
} catch (Exception e) { } catch (Exception e) {
notificationEntityService.logEntityRelationAction(tenantId, customerId, logEntityActionService.logEntityRelationAction(tenantId, customerId,
relation, user, actionType, e, relation); relation, user, actionType, e, relation);
throw e; throw e;
} }
@ -72,9 +72,9 @@ public class DefaultTbEntityRelationService extends AbstractTbEntityService impl
public void deleteCommonRelations(TenantId tenantId, CustomerId customerId, EntityId entityId, User user) throws ThingsboardException { public void deleteCommonRelations(TenantId tenantId, CustomerId customerId, EntityId entityId, User user) throws ThingsboardException {
try { try {
relationService.deleteEntityCommonRelations(tenantId, entityId); relationService.deleteEntityCommonRelations(tenantId, entityId);
notificationEntityService.logEntityAction(tenantId, entityId, null, customerId, ActionType.RELATIONS_DELETED, user); logEntityActionService.logEntityAction(tenantId, entityId, null, customerId, ActionType.RELATIONS_DELETED, user);
} catch (Exception e) { } catch (Exception e) {
notificationEntityService.logEntityAction(tenantId, entityId, null, customerId, logEntityActionService.logEntityAction(tenantId, entityId, null, customerId,
ActionType.RELATIONS_DELETED, user, e); ActionType.RELATIONS_DELETED, user, e);
throw e; throw e;
} }

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

@ -20,6 +20,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.MoreExecutors; import com.google.common.util.concurrent.MoreExecutors;
import com.google.common.util.concurrent.SettableFuture; import com.google.common.util.concurrent.SettableFuture;
import jakarta.annotation.Nullable;
import lombok.AllArgsConstructor; import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
@ -49,7 +50,6 @@ import org.thingsboard.server.dao.timeseries.TimeseriesService;
import org.thingsboard.server.service.entitiy.AbstractTbEntityService; import org.thingsboard.server.service.entitiy.AbstractTbEntityService;
import org.thingsboard.server.service.telemetry.TelemetrySubscriptionService; import org.thingsboard.server.service.telemetry.TelemetrySubscriptionService;
import jakarta.annotation.Nullable;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collection; import java.util.Collection;
import java.util.Collections; import java.util.Collections;
@ -81,14 +81,12 @@ 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.logEntityAction(savedEntityView.getTenantId(), savedEntityView.getId(), savedEntityView, logEntityActionService.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(),
entityView.getId() == null ? ComponentLifecycleEvent.CREATED : ComponentLifecycleEvent.UPDATED);
return savedEntityView; return savedEntityView;
} catch (Exception e) { } catch (Exception e) {
notificationEntityService.logEntityAction(user.getTenantId(), emptyId(EntityType.ENTITY_VIEW), entityView, actionType, user, e); logEntityActionService.logEntityAction(user.getTenantId(), emptyId(EntityType.ENTITY_VIEW), entityView, actionType, user, e);
throw e; throw e;
} }
} }
@ -130,13 +128,12 @@ public class DefaultTbEntityViewService extends AbstractTbEntityService implemen
EntityViewId entityViewId = entityView.getId(); EntityViewId entityViewId = entityView.getId();
try { try {
entityViewService.deleteEntityView(tenantId, entityViewId); entityViewService.deleteEntityView(tenantId, entityViewId);
notificationEntityService.logEntityAction(tenantId, entityViewId, entityView, entityView.getCustomerId(), logEntityActionService.logEntityAction(tenantId, entityViewId, entityView, entityView.getCustomerId(),
ActionType.DELETED, 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);
} catch (Exception e) { } catch (Exception e) {
notificationEntityService.logEntityAction(tenantId, emptyId(EntityType.ENTITY_VIEW), logEntityActionService.logEntityAction(tenantId, emptyId(EntityType.ENTITY_VIEW),
ActionType.DELETED, user, e, entityViewId.toString()); ActionType.DELETED, user, e, entityViewId.toString());
throw e; throw e;
} }
@ -148,11 +145,11 @@ public class DefaultTbEntityViewService extends AbstractTbEntityService implemen
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.logEntityAction(tenantId, entityViewId, savedEntityView, savedEntityView.getCustomerId(), logEntityActionService.logEntityAction(tenantId, entityViewId, savedEntityView, savedEntityView.getCustomerId(),
actionType, user, entityViewId.toString(), customerId.toString(), customer.getName()); actionType, user, entityViewId.toString(), customerId.toString(), customer.getName());
return savedEntityView; return savedEntityView;
} catch (Exception e) { } catch (Exception e) {
notificationEntityService.logEntityAction(tenantId, emptyId(EntityType.ENTITY_VIEW), logEntityActionService.logEntityAction(tenantId, emptyId(EntityType.ENTITY_VIEW),
actionType, user, e, entityViewId.toString(), customerId.toString()); actionType, user, e, entityViewId.toString(), customerId.toString());
throw e; throw e;
} }
@ -163,11 +160,11 @@ public class DefaultTbEntityViewService extends AbstractTbEntityService implemen
ActionType actionType = ActionType.UNASSIGNED_FROM_CUSTOMER; ActionType actionType = ActionType.UNASSIGNED_FROM_CUSTOMER;
try { try {
EntityView savedEntityView = checkNotNull(entityViewService.unassignEntityViewFromCustomer(tenantId, entityViewId)); EntityView savedEntityView = checkNotNull(entityViewService.unassignEntityViewFromCustomer(tenantId, entityViewId));
notificationEntityService.logEntityAction(tenantId, entityViewId, savedEntityView, customer.getId(), logEntityActionService.logEntityAction(tenantId, entityViewId, savedEntityView, customer.getId(),
actionType, user, savedEntityView.getId().toString(), customer.getId().toString(), customer.getName()); 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), logEntityActionService.logEntityAction(tenantId, emptyId(EntityType.ENTITY_VIEW),
actionType, user, e, entityViewId.toString()); actionType, user, e, entityViewId.toString());
throw e; throw e;
} }
@ -180,11 +177,11 @@ 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.logEntityAction(tenantId, entityViewId, savedEntityView, savedEntityView.getCustomerId(), logEntityActionService.logEntityAction(tenantId, entityViewId, savedEntityView, savedEntityView.getCustomerId(),
actionType, user, savedEntityView.getId().toString(), publicCustomer.getId().toString(), publicCustomer.getName()); actionType, user, savedEntityView.getId().toString(), publicCustomer.getId().toString(), publicCustomer.getName());
return savedEntityView; return savedEntityView;
} catch (Exception e) { } catch (Exception e) {
notificationEntityService.logEntityAction(tenantId, emptyId(EntityType.ENTITY_VIEW), logEntityActionService.logEntityAction(tenantId, emptyId(EntityType.ENTITY_VIEW),
actionType, user, e, entityViewId.toString()); actionType, user, e, entityViewId.toString());
throw e; throw e;
} }
@ -196,11 +193,11 @@ public class DefaultTbEntityViewService extends AbstractTbEntityService implemen
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.logEntityAction(tenantId, entityViewId, savedEntityView, customerId, actionType, logEntityActionService.logEntityAction(tenantId, entityViewId, savedEntityView, customerId, actionType,
user, savedEntityView.getEntityId().toString(), edgeId.toString(), edge.getName()); user, savedEntityView.getEntityId().toString(), edgeId.toString(), edge.getName());
return savedEntityView; return savedEntityView;
} catch (Exception e) { } catch (Exception e) {
notificationEntityService.logEntityAction(tenantId, emptyId(EntityType.ENTITY_VIEW), logEntityActionService.logEntityAction(tenantId, emptyId(EntityType.ENTITY_VIEW),
actionType, user, e, entityViewId.toString(), edgeId.toString()); actionType, user, e, entityViewId.toString(), edgeId.toString());
throw e; throw e;
} }
@ -214,11 +211,11 @@ public class DefaultTbEntityViewService extends AbstractTbEntityService implemen
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.logEntityAction(tenantId, entityViewId, savedEntityView, customerId, actionType, logEntityActionService.logEntityAction(tenantId, entityViewId, savedEntityView, customerId, actionType,
user, entityViewId.toString(), edgeId.toString(), edge.getName()); user, entityViewId.toString(), edgeId.toString(), edge.getName());
return savedEntityView; return savedEntityView;
} catch (Exception e) { } catch (Exception e) {
notificationEntityService.logEntityAction(tenantId, emptyId(EntityType.ENTITY_VIEW), logEntityActionService.logEntityAction(tenantId, emptyId(EntityType.ENTITY_VIEW),
actionType, user, e, entityViewId.toString(), edgeId.toString()); actionType, user, e, entityViewId.toString(), edgeId.toString());
throw e; throw e;
} }
@ -434,15 +431,15 @@ public class DefaultTbEntityViewService extends AbstractTbEntityService implemen
} }
private void logAttributesUpdated(TenantId tenantId, User user, EntityId entityId, AttributeScope scope, List<AttributeKvEntry> attributes, Throwable e) throws ThingsboardException { private void logAttributesUpdated(TenantId tenantId, User user, EntityId entityId, AttributeScope scope, List<AttributeKvEntry> attributes, Throwable e) throws ThingsboardException {
notificationEntityService.logEntityAction(tenantId, entityId, ActionType.ATTRIBUTES_UPDATED, user, toException(e), scope, attributes); logEntityActionService.logEntityAction(tenantId, entityId, ActionType.ATTRIBUTES_UPDATED, user, toException(e), scope, attributes);
} }
private void logAttributesDeleted(TenantId tenantId, User user, EntityId entityId, AttributeScope scope, List<String> keys, Throwable e) throws ThingsboardException { private void logAttributesDeleted(TenantId tenantId, User user, EntityId entityId, AttributeScope scope, List<String> keys, Throwable e) throws ThingsboardException {
notificationEntityService.logEntityAction(tenantId, entityId, ActionType.ATTRIBUTES_DELETED, user, toException(e), scope, keys); logEntityActionService.logEntityAction(tenantId, entityId, ActionType.ATTRIBUTES_DELETED, user, toException(e), scope, keys);
} }
private void logTimeseriesDeleted(TenantId tenantId, User user, EntityId entityId, List<String> keys, Throwable e) throws ThingsboardException { private void logTimeseriesDeleted(TenantId tenantId, User user, EntityId entityId, List<String> keys, Throwable e) throws ThingsboardException {
notificationEntityService.logEntityAction(tenantId, entityId, ActionType.TIMESERIES_DELETED, user, toException(e), keys); logEntityActionService.logEntityAction(tenantId, entityId, ActionType.TIMESERIES_DELETED, user, toException(e), keys);
} }
public static Exception toException(Throwable error) { public static Exception toException(Throwable error) {

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

@ -50,12 +50,12 @@ 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());
notificationEntityService.logEntityAction(tenantId, savedOtaPackageInfo.getId(), savedOtaPackageInfo, logEntityActionService.logEntityAction(tenantId, savedOtaPackageInfo.getId(), savedOtaPackageInfo,
null, actionType, user); null, actionType, user);
return savedOtaPackageInfo; return savedOtaPackageInfo;
} catch (Exception e) { } catch (Exception e) {
notificationEntityService.logEntityAction(tenantId, emptyId(EntityType.OTA_PACKAGE), saveOtaPackageInfoRequest, logEntityActionService.logEntityAction(tenantId, emptyId(EntityType.OTA_PACKAGE), saveOtaPackageInfoRequest,
actionType, user, e); actionType, user, e);
throw e; throw e;
} }
@ -87,10 +87,10 @@ 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.logEntityAction(tenantId, savedOtaPackage.getId(), savedOtaPackage, null, actionType, user); logEntityActionService.logEntityAction(tenantId, savedOtaPackage.getId(), savedOtaPackage, null, actionType, user);
return savedOtaPackage; return savedOtaPackage;
} catch (Exception e) { } catch (Exception e) {
notificationEntityService.logEntityAction(tenantId, emptyId(EntityType.OTA_PACKAGE), actionType, user, e, otaPackageId.toString()); logEntityActionService.logEntityAction(tenantId, emptyId(EntityType.OTA_PACKAGE), actionType, user, e, otaPackageId.toString());
throw e; throw e;
} }
} }
@ -102,10 +102,10 @@ public class DefaultTbOtaPackageService extends AbstractTbEntityService implemen
OtaPackageId otaPackageId = otaPackageInfo.getId(); OtaPackageId otaPackageId = otaPackageInfo.getId();
try { try {
otaPackageService.deleteOtaPackage(tenantId, otaPackageId); otaPackageService.deleteOtaPackage(tenantId, otaPackageId);
notificationEntityService.logEntityAction(tenantId, otaPackageId, otaPackageInfo, null, logEntityActionService.logEntityAction(tenantId, otaPackageId, otaPackageInfo, null,
actionType, user, otaPackageInfo.getId().toString()); actionType, user, otaPackageInfo.getId().toString());
} catch (Exception e) { } catch (Exception e) {
notificationEntityService.logEntityAction(tenantId, emptyId(EntityType.OTA_PACKAGE), logEntityActionService.logEntityAction(tenantId, emptyId(EntityType.OTA_PACKAGE),
actionType, user, e, otaPackageId.toString()); actionType, user, e, otaPackageId.toString());
throw e; throw e;
} }

13
application/src/main/java/org/thingsboard/server/service/entitiy/tenant/DefaultTbTenantService.java

@ -16,11 +16,12 @@
package org.thingsboard.server.service.entitiy.tenant; package org.thingsboard.server.service.entitiy.tenant;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
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.id.TenantId; import org.thingsboard.server.common.data.id.TenantId;
import org.thingsboard.server.common.data.plugin.ComponentLifecycleEvent; import org.thingsboard.server.dao.eventsourcing.SaveEntityEvent;
import org.thingsboard.server.dao.tenant.TbTenantProfileCache; import org.thingsboard.server.dao.tenant.TbTenantProfileCache;
import org.thingsboard.server.dao.tenant.TenantProfileService; import org.thingsboard.server.dao.tenant.TenantProfileService;
import org.thingsboard.server.dao.tenant.TenantService; import org.thingsboard.server.dao.tenant.TenantService;
@ -44,21 +45,24 @@ public class DefaultTbTenantService extends AbstractTbEntityService implements T
private final TbQueueService tbQueueService; private final TbQueueService tbQueueService;
private final TenantProfileService tenantProfileService; private final TenantProfileService tenantProfileService;
private final EntitiesVersionControlService versionControlService; private final EntitiesVersionControlService versionControlService;
private final ApplicationEventPublisher eventPublisher;
@Override @Override
public Tenant save(Tenant tenant) throws Exception { public Tenant save(Tenant tenant) throws Exception {
boolean created = tenant.getId() == null; boolean created = tenant.getId() == null;
Tenant oldTenant = !created ? tenantService.findTenantById(tenant.getId()) : null; Tenant oldTenant = !created ? tenantService.findTenantById(tenant.getId()) : null;
Tenant savedTenant = checkNotNull(tenantService.saveTenant(tenant)); Tenant savedTenant = checkNotNull(tenantService.saveTenant(tenant, !created));
if (created) { if (created) {
installScripts.createDefaultRuleChains(savedTenant.getId()); installScripts.createDefaultRuleChains(savedTenant.getId());
installScripts.createDefaultEdgeRuleChains(savedTenant.getId()); installScripts.createDefaultEdgeRuleChains(savedTenant.getId());
installScripts.createDefaultTenantDashboards(savedTenant.getId(), null); installScripts.createDefaultTenantDashboards(savedTenant.getId(), null);
} }
tenantProfileCache.evict(savedTenant.getId()); tenantProfileCache.evict(savedTenant.getId());
notificationEntityService.notifyCreateOrUpdateTenant(savedTenant, created ?
ComponentLifecycleEvent.CREATED : ComponentLifecycleEvent.UPDATED); if (created) {
eventPublisher.publishEvent(SaveEntityEvent.builder().tenantId(TenantId.SYS_TENANT_ID).entityId(savedTenant.getId()).entity(savedTenant).added(true).build());
}
TenantProfile oldTenantProfile = oldTenant != null ? tenantProfileService.findTenantProfileById(TenantId.SYS_TENANT_ID, oldTenant.getTenantProfileId()) : null; TenantProfile oldTenantProfile = oldTenant != null ? tenantProfileService.findTenantProfileById(TenantId.SYS_TENANT_ID, oldTenant.getTenantProfileId()) : null;
TenantProfile newTenantProfile = tenantProfileService.findTenantProfileById(TenantId.SYS_TENANT_ID, savedTenant.getTenantProfileId()); TenantProfile newTenantProfile = tenantProfileService.findTenantProfileById(TenantId.SYS_TENANT_ID, savedTenant.getTenantProfileId());
@ -71,7 +75,6 @@ public class DefaultTbTenantService extends AbstractTbEntityService implements T
TenantId tenantId = tenant.getId(); TenantId tenantId = tenant.getId();
tenantService.deleteTenant(tenantId); tenantService.deleteTenant(tenantId);
tenantProfileCache.evict(tenantId); tenantProfileCache.evict(tenantId);
notificationEntityService.notifyDeleteTenant(tenant);
versionControlService.deleteVersionControlSettings(tenantId).get(1, TimeUnit.MINUTES); versionControlService.deleteVersionControlSettings(tenantId).get(1, TimeUnit.MINUTES);
} }
} }

5
application/src/main/java/org/thingsboard/server/service/entitiy/tenant/profile/DefaultTbTenantProfileService.java

@ -21,7 +21,6 @@ import org.springframework.stereotype.Service;
import org.thingsboard.server.common.data.TenantProfile; import org.thingsboard.server.common.data.TenantProfile;
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.plugin.ComponentLifecycleEvent;
import org.thingsboard.server.dao.tenant.TbTenantProfileCache; import org.thingsboard.server.dao.tenant.TbTenantProfileCache;
import org.thingsboard.server.dao.tenant.TenantProfileService; import org.thingsboard.server.dao.tenant.TenantProfileService;
import org.thingsboard.server.dao.tenant.TenantService; import org.thingsboard.server.dao.tenant.TenantService;
@ -45,9 +44,6 @@ public class DefaultTbTenantProfileService extends AbstractTbEntityService imple
public TenantProfile save(TenantId tenantId, TenantProfile tenantProfile, TenantProfile oldTenantProfile) throws ThingsboardException { public TenantProfile save(TenantId tenantId, TenantProfile tenantProfile, TenantProfile oldTenantProfile) throws ThingsboardException {
TenantProfile savedTenantProfile = checkNotNull(tenantProfileService.saveTenantProfile(tenantId, tenantProfile)); TenantProfile savedTenantProfile = checkNotNull(tenantProfileService.saveTenantProfile(tenantId, tenantProfile));
tenantProfileCache.put(savedTenantProfile); tenantProfileCache.put(savedTenantProfile);
tbClusterService.onTenantProfileChange(savedTenantProfile, null);
tbClusterService.broadcastEntityStateChangeEvent(TenantId.SYS_TENANT_ID, savedTenantProfile.getId(),
tenantProfile.getId() == null ? ComponentLifecycleEvent.CREATED : ComponentLifecycleEvent.UPDATED);
List<TenantId> tenantIds = tenantService.findTenantIdsByTenantProfileId(savedTenantProfile.getId()); List<TenantId> tenantIds = tenantService.findTenantIdsByTenantProfileId(savedTenantProfile.getId());
tbQueueService.updateQueuesByTenants(tenantIds, savedTenantProfile, oldTenantProfile); tbQueueService.updateQueuesByTenants(tenantIds, savedTenantProfile, oldTenantProfile);
@ -58,6 +54,5 @@ public class DefaultTbTenantProfileService extends AbstractTbEntityService imple
@Override @Override
public void delete(TenantId tenantId, TenantProfile tenantProfile) throws ThingsboardException { public void delete(TenantId tenantId, TenantProfile tenantProfile) throws ThingsboardException {
tenantProfileService.deleteTenantProfile(tenantId, tenantProfile.getId()); tenantProfileService.deleteTenantProfile(tenantId, tenantProfile.getId());
tbClusterService.onTenantProfileDelete(tenantProfile, null);
} }
} }

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

@ -66,10 +66,10 @@ public class DefaultUserService extends AbstractTbEntityService implements TbUse
throw e; throw e;
} }
} }
notificationEntityService.logEntityAction(tenantId, savedUser.getId(), savedUser, customerId, actionType, user); logEntityActionService.logEntityAction(tenantId, savedUser.getId(), savedUser, customerId, actionType, user);
return savedUser; return savedUser;
} catch (Exception e) { } catch (Exception e) {
notificationEntityService.logEntityAction(tenantId, emptyId(EntityType.USER), tbUser, actionType, user, e); logEntityActionService.logEntityAction(tenantId, emptyId(EntityType.USER), tbUser, actionType, user, e);
throw e; throw e;
} }
} }
@ -81,9 +81,9 @@ public class DefaultUserService extends AbstractTbEntityService implements TbUse
try { try {
userService.deleteUser(tenantId, user); userService.deleteUser(tenantId, user);
notificationEntityService.logEntityAction(tenantId, userId, user, customerId, actionType, responsibleUser, customerId.toString()); logEntityActionService.logEntityAction(tenantId, userId, user, customerId, actionType, responsibleUser, customerId.toString());
} catch (Exception e) { } catch (Exception e) {
notificationEntityService.logEntityAction(tenantId, emptyId(EntityType.USER), logEntityActionService.logEntityAction(tenantId, emptyId(EntityType.USER),
actionType, responsibleUser, e, userId.toString()); actionType, responsibleUser, e, userId.toString());
throw e; throw e;
} }

1
application/src/main/java/org/thingsboard/server/service/entitiy/user/TbUserService.java

@ -23,6 +23,7 @@ import org.thingsboard.server.common.data.id.TenantId;
import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletRequest;
public interface TbUserService { public interface TbUserService {
User save(TenantId tenantId, CustomerId customerId, User tbUser, boolean sendActivationMail, HttpServletRequest request, User user) throws ThingsboardException; User save(TenantId tenantId, CustomerId customerId, User tbUser, boolean sendActivationMail, HttpServletRequest request, User user) throws ThingsboardException;
void delete(TenantId tenantId, CustomerId customerId, User user, User responsibleUser) throws ThingsboardException; void delete(TenantId tenantId, CustomerId customerId, User user, User responsibleUser) throws ThingsboardException;

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

@ -46,11 +46,11 @@ 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.logEntityAction(tenantId, savedWidgetsBundle.getId(), savedWidgetsBundle, logEntityActionService.logEntityAction(tenantId, savedWidgetsBundle.getId(), savedWidgetsBundle,
null, actionType, user); null, actionType, user);
return savedWidgetsBundle; return savedWidgetsBundle;
} catch (Exception e) { } catch (Exception e) {
notificationEntityService.logEntityAction(tenantId, emptyId(EntityType.WIDGETS_BUNDLE), widgetsBundle, actionType, user, e); logEntityActionService.logEntityAction(tenantId, emptyId(EntityType.WIDGETS_BUNDLE), widgetsBundle, actionType, user, e);
throw e; throw e;
} }
} }
@ -61,9 +61,9 @@ public class DefaultWidgetsBundleService extends AbstractTbEntityService impleme
TenantId tenantId = widgetsBundle.getTenantId(); TenantId tenantId = widgetsBundle.getTenantId();
try { try {
widgetsBundleService.deleteWidgetsBundle(widgetsBundle.getTenantId(), widgetsBundle.getId()); widgetsBundleService.deleteWidgetsBundle(widgetsBundle.getTenantId(), widgetsBundle.getId());
notificationEntityService.logEntityAction(tenantId, widgetsBundle.getId(), widgetsBundle, null, actionType, user); logEntityActionService.logEntityAction(tenantId, widgetsBundle.getId(), widgetsBundle, null, actionType, user);
} catch (Exception e) { } catch (Exception e) {
notificationEntityService.logEntityAction(tenantId, emptyId(EntityType.WIDGETS_BUNDLE), actionType, user, e, widgetsBundle.getId()); logEntityActionService.logEntityAction(tenantId, emptyId(EntityType.WIDGETS_BUNDLE), actionType, user, e, widgetsBundle.getId());
throw e; throw e;
} }
} }

8
application/src/main/java/org/thingsboard/server/service/entitiy/widgets/type/DefaultWidgetTypeService.java

@ -56,11 +56,11 @@ public class DefaultWidgetTypeService extends AbstractTbEntityService implements
try { try {
WidgetTypeDetails savedWidgetTypeDetails = checkNotNull(widgetTypeService.saveWidgetType(widgetTypeDetails)); WidgetTypeDetails savedWidgetTypeDetails = checkNotNull(widgetTypeService.saveWidgetType(widgetTypeDetails));
autoCommit(user, savedWidgetTypeDetails.getId()); autoCommit(user, savedWidgetTypeDetails.getId());
notificationEntityService.logEntityAction(tenantId, savedWidgetTypeDetails.getId(), savedWidgetTypeDetails, logEntityActionService.logEntityAction(tenantId, savedWidgetTypeDetails.getId(), savedWidgetTypeDetails,
null, actionType, user); null, actionType, user);
return savedWidgetTypeDetails; return savedWidgetTypeDetails;
} catch (Exception e) { } catch (Exception e) {
notificationEntityService.logEntityAction(tenantId, emptyId(EntityType.WIDGET_TYPE), widgetTypeDetails, actionType, user, e); logEntityActionService.logEntityAction(tenantId, emptyId(EntityType.WIDGET_TYPE), widgetTypeDetails, actionType, user, e);
throw e; throw e;
} }
} }
@ -71,9 +71,9 @@ public class DefaultWidgetTypeService extends AbstractTbEntityService implements
TenantId tenantId = widgetTypeDetails.getTenantId(); TenantId tenantId = widgetTypeDetails.getTenantId();
try { try {
widgetTypeService.deleteWidgetType(widgetTypeDetails.getTenantId(), widgetTypeDetails.getId()); widgetTypeService.deleteWidgetType(widgetTypeDetails.getTenantId(), widgetTypeDetails.getId());
notificationEntityService.logEntityAction(tenantId, widgetTypeDetails.getId(), widgetTypeDetails, null, actionType, user); logEntityActionService.logEntityAction(tenantId, widgetTypeDetails.getId(), widgetTypeDetails, null, actionType, user);
} catch (Exception e) { } catch (Exception e) {
notificationEntityService.logEntityAction(tenantId, emptyId(EntityType.WIDGET_TYPE), actionType, user, e, widgetTypeDetails.getId()); logEntityActionService.logEntityAction(tenantId, emptyId(EntityType.WIDGET_TYPE), actionType, user, e, widgetTypeDetails.getId());
throw e; throw e;
} }
} }

8
application/src/main/java/org/thingsboard/server/service/install/InstallScripts.java

@ -180,11 +180,11 @@ public class InstallScripts {
return paths; return paths;
} }
public RuleChain createDefaultRuleChain(TenantId tenantId, String ruleChainName) throws IOException { public RuleChain createDefaultRuleChain(TenantId tenantId, String ruleChainName) {
return createRuleChainFromFile(tenantId, getDeviceProfileDefaultRuleChainTemplateFilePath(), ruleChainName); return createRuleChainFromFile(tenantId, getDeviceProfileDefaultRuleChainTemplateFilePath(), ruleChainName);
} }
public RuleChain createRuleChainFromFile(TenantId tenantId, Path templateFilePath, String newRuleChainName) throws IOException { public RuleChain createRuleChainFromFile(TenantId tenantId, Path templateFilePath, String newRuleChainName) {
JsonNode ruleChainJson = JacksonUtil.toJsonNode(templateFilePath.toFile()); JsonNode ruleChainJson = JacksonUtil.toJsonNode(templateFilePath.toFile());
RuleChain ruleChain = JacksonUtil.treeToValue(ruleChainJson.get("ruleChain"), RuleChain.class); RuleChain ruleChain = JacksonUtil.treeToValue(ruleChainJson.get("ruleChain"), RuleChain.class);
RuleChainMetaData ruleChainMetaData = JacksonUtil.treeToValue(ruleChainJson.get("metadata"), RuleChainMetaData.class); RuleChainMetaData ruleChainMetaData = JacksonUtil.treeToValue(ruleChainJson.get("metadata"), RuleChainMetaData.class);
@ -193,10 +193,10 @@ public class InstallScripts {
if (!StringUtils.isEmpty(newRuleChainName)) { if (!StringUtils.isEmpty(newRuleChainName)) {
ruleChain.setName(newRuleChainName); ruleChain.setName(newRuleChainName);
} }
ruleChain = ruleChainService.saveRuleChain(ruleChain); ruleChain = ruleChainService.saveRuleChain(ruleChain, false);
ruleChainMetaData.setRuleChainId(ruleChain.getId()); ruleChainMetaData.setRuleChainId(ruleChain.getId());
ruleChainService.saveRuleChainMetaData(TenantId.SYS_TENANT_ID, ruleChainMetaData, Function.identity()); ruleChainService.saveRuleChainMetaData(TenantId.SYS_TENANT_ID, ruleChainMetaData, Function.identity(), false);
return ruleChain; return ruleChain;
} }

6
application/src/main/java/org/thingsboard/server/service/install/SqlDatabaseUpgradeService.java

@ -19,14 +19,12 @@ import com.google.common.util.concurrent.Futures;
import com.google.common.util.concurrent.ListenableFuture; import com.google.common.util.concurrent.ListenableFuture;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils; import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.SystemUtils;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value; import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Lazy; import org.springframework.context.annotation.Lazy;
import org.springframework.context.annotation.Profile; import org.springframework.context.annotation.Profile;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.thingsboard.server.common.data.EntitySubtype; import org.thingsboard.server.common.data.EntitySubtype;
import org.thingsboard.server.common.data.StringUtils;
import org.thingsboard.server.common.data.Tenant; import org.thingsboard.server.common.data.Tenant;
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;
@ -50,8 +48,6 @@ import org.thingsboard.server.queue.settings.TbRuleEngineQueueConfiguration;
import org.thingsboard.server.service.install.sql.SqlDbHelper; import org.thingsboard.server.service.install.sql.SqlDbHelper;
import org.thingsboard.server.service.install.update.DefaultDataUpdateService; import org.thingsboard.server.service.install.update.DefaultDataUpdateService;
import java.io.File;
import java.io.IOException;
import java.nio.charset.Charset; import java.nio.charset.Charset;
import java.nio.file.Files; import java.nio.file.Files;
import java.nio.file.Path; import java.nio.file.Path;
@ -69,8 +65,6 @@ import java.util.UUID;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
import java.util.function.Consumer; import java.util.function.Consumer;
import static org.thingsboard.server.service.install.AbstractSqlTsDatabaseUpgradeService.PATH_TO_USERS_PUBLIC_FOLDER;
import static org.thingsboard.server.service.install.AbstractSqlTsDatabaseUpgradeService.THINGSBOARD_WINDOWS_UPGRADE_DIR;
import static org.thingsboard.server.service.install.DatabaseHelper.ADDITIONAL_INFO; import static org.thingsboard.server.service.install.DatabaseHelper.ADDITIONAL_INFO;
import static org.thingsboard.server.service.install.DatabaseHelper.ASSIGNED_CUSTOMERS; import static org.thingsboard.server.service.install.DatabaseHelper.ASSIGNED_CUSTOMERS;
import static org.thingsboard.server.service.install.DatabaseHelper.CONFIGURATION; import static org.thingsboard.server.service.install.DatabaseHelper.CONFIGURATION;

6
application/src/main/java/org/thingsboard/server/service/notification/DefaultNotificationCenter.java

@ -52,7 +52,6 @@ import org.thingsboard.server.common.data.notification.template.DeliveryMethodNo
import org.thingsboard.server.common.data.notification.template.NotificationTemplate; import org.thingsboard.server.common.data.notification.template.NotificationTemplate;
import org.thingsboard.server.common.data.notification.template.WebDeliveryMethodNotificationTemplate; import org.thingsboard.server.common.data.notification.template.WebDeliveryMethodNotificationTemplate;
import org.thingsboard.server.common.data.page.PageDataIterable; import org.thingsboard.server.common.data.page.PageDataIterable;
import org.thingsboard.server.common.data.plugin.ComponentLifecycleEvent;
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;
@ -397,7 +396,7 @@ public class DefaultNotificationCenter extends AbstractSubscriptionService imple
public void deleteNotificationRequest(TenantId tenantId, NotificationRequestId notificationRequestId) { public void deleteNotificationRequest(TenantId tenantId, NotificationRequestId notificationRequestId) {
log.debug("Deleting notification request {}", notificationRequestId); log.debug("Deleting notification request {}", notificationRequestId);
NotificationRequest notificationRequest = notificationRequestService.findNotificationRequestById(tenantId, notificationRequestId); NotificationRequest notificationRequest = notificationRequestService.findNotificationRequestById(tenantId, notificationRequestId);
notificationRequestService.deleteNotificationRequest(tenantId, notificationRequestId); notificationRequestService.deleteNotificationRequest(tenantId, notificationRequest);
if (notificationRequest.isSent()) { if (notificationRequest.isSent()) {
// TODO: no need to send request update for other than PLATFORM_USERS target type // TODO: no need to send request update for other than PLATFORM_USERS target type
@ -405,9 +404,6 @@ public class DefaultNotificationCenter extends AbstractSubscriptionService imple
.notificationRequestId(notificationRequestId) .notificationRequestId(notificationRequestId)
.deleted(true) .deleted(true)
.build()); .build());
} else if (notificationRequest.isScheduled()) {
// TODO: just forward to scheduler service
clusterService.broadcastEntityStateChangeEvent(tenantId, notificationRequestId, ComponentLifecycleEvent.DELETED);
} }
} }

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

@ -31,6 +31,7 @@ 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.HasRuleEngineProfile;
import org.thingsboard.server.common.data.TbResource; import org.thingsboard.server.common.data.TbResource;
import org.thingsboard.server.common.data.TbResourceInfo;
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.edge.EdgeEventActionType; import org.thingsboard.server.common.data.edge.EdgeEventActionType;
@ -79,6 +80,7 @@ import org.thingsboard.server.service.ota.OtaPackageStateService;
import org.thingsboard.server.service.profile.TbAssetProfileCache; import org.thingsboard.server.service.profile.TbAssetProfileCache;
import org.thingsboard.server.service.profile.TbDeviceProfileCache; import org.thingsboard.server.service.profile.TbDeviceProfileCache;
import java.util.Objects;
import java.util.Optional; import java.util.Optional;
import java.util.Set; import java.util.Set;
import java.util.UUID; import java.util.UUID;
@ -275,8 +277,17 @@ public class DefaultTbClusterService implements TbClusterService {
} }
@Override @Override
public void onDeviceProfileChange(DeviceProfile deviceProfile, TbQueueCallback callback) { public void onDeviceProfileChange(DeviceProfile deviceProfile, DeviceProfile oldDeviceProfile, TbQueueCallback callback) {
boolean isFirmwareChanged = false;
boolean isSoftwareChanged = false;
if (oldDeviceProfile != null) {
isFirmwareChanged = !Objects.equals(deviceProfile.getFirmwareId(), oldDeviceProfile.getFirmwareId());
isSoftwareChanged = !Objects.equals(deviceProfile.getSoftwareId(), oldDeviceProfile.getSoftwareId());
}
broadcastEntityChangeToTransport(deviceProfile.getTenantId(), deviceProfile.getId(), deviceProfile, callback); broadcastEntityChangeToTransport(deviceProfile.getTenantId(), deviceProfile.getId(), deviceProfile, callback);
broadcastEntityStateChangeEvent(deviceProfile.getTenantId(), deviceProfile.getId(),
oldDeviceProfile == null ? ComponentLifecycleEvent.CREATED : ComponentLifecycleEvent.UPDATED);
otaPackageStateService.update(deviceProfile, isFirmwareChanged, isSoftwareChanged);
} }
@Override @Override
@ -313,6 +324,7 @@ public class DefaultTbClusterService implements TbClusterService {
@Override @Override
public void onDeviceDeleted(TenantId tenantId, Device device, TbQueueCallback callback) { public void onDeviceDeleted(TenantId tenantId, Device device, TbQueueCallback callback) {
DeviceId deviceId = device.getId(); DeviceId deviceId = device.getId();
gatewayNotificationsService.onDeviceDeleted(device);
broadcastEntityDeleteToTransport(tenantId, deviceId, device.getName(), callback); broadcastEntityDeleteToTransport(tenantId, deviceId, device.getName(), callback);
sendDeviceStateServiceEvent(tenantId, deviceId, false, false, true); sendDeviceStateServiceEvent(tenantId, deviceId, false, false, true);
broadcastEntityStateChangeEvent(tenantId, deviceId, ComponentLifecycleEvent.DELETED); broadcastEntityStateChangeEvent(tenantId, deviceId, ComponentLifecycleEvent.DELETED);
@ -325,7 +337,7 @@ public class DefaultTbClusterService implements TbClusterService {
} }
@Override @Override
public void onResourceChange(TbResource resource, TbQueueCallback callback) { public void onResourceChange(TbResourceInfo resource, TbQueueCallback callback) {
TenantId tenantId = resource.getTenantId(); TenantId tenantId = resource.getTenantId();
log.trace("[{}][{}][{}] Processing change resource", tenantId, resource.getResourceType(), resource.getResourceKey()); log.trace("[{}][{}][{}] Processing change resource", tenantId, resource.getResourceType(), resource.getResourceKey());
TransportProtos.ResourceUpdateMsg resourceUpdateMsg = TransportProtos.ResourceUpdateMsg.newBuilder() TransportProtos.ResourceUpdateMsg resourceUpdateMsg = TransportProtos.ResourceUpdateMsg.newBuilder()
@ -339,7 +351,7 @@ public class DefaultTbClusterService implements TbClusterService {
} }
@Override @Override
public void onResourceDeleted(TbResource resource, TbQueueCallback callback) { public void onResourceDeleted(TbResourceInfo resource, TbQueueCallback callback) {
log.trace("[{}] Processing delete resource", resource); log.trace("[{}] Processing delete resource", resource);
TransportProtos.ResourceDeleteMsg resourceUpdateMsg = TransportProtos.ResourceDeleteMsg.newBuilder() TransportProtos.ResourceDeleteMsg resourceUpdateMsg = TransportProtos.ResourceDeleteMsg.newBuilder()
.setTenantIdMSB(resource.getTenantId().getId().getMostSignificantBits()) .setTenantIdMSB(resource.getTenantId().getId().getMostSignificantBits())
@ -351,7 +363,7 @@ public class DefaultTbClusterService implements TbClusterService {
broadcast(transportMsg, callback); broadcast(transportMsg, callback);
} }
public <T> void broadcastEntityChangeToTransport(TenantId tenantId, EntityId entityid, T entity, TbQueueCallback callback) { private <T> void broadcastEntityChangeToTransport(TenantId tenantId, EntityId entityid, T entity, TbQueueCallback callback) {
String entityName = (entity instanceof HasName) ? ((HasName) entity).getName() : entity.getClass().getName(); String entityName = (entity instanceof HasName) ? ((HasName) entity).getName() : entity.getClass().getName();
log.trace("[{}][{}][{}] Processing [{}] change event", tenantId, entityid.getEntityType(), entityid.getId(), entityName); log.trace("[{}][{}][{}] Processing [{}] change event", tenantId, entityid.getEntityType(), entityid.getId(), entityName);
ToTransportMsg transportMsg = ToTransportMsg.newBuilder().setEntityUpdateMsg(ProtoUtils.toEntityUpdateProto(entity)).build(); ToTransportMsg transportMsg = ToTransportMsg.newBuilder().setEntityUpdateMsg(ProtoUtils.toEntityUpdateProto(entity)).build();

12
application/src/main/java/org/thingsboard/server/service/resource/DefaultTbImageService.java

@ -96,7 +96,7 @@ public class DefaultTbImageService extends AbstractTbEntityService implements Tb
} }
} }
TbResourceInfo savedImage = imageService.saveImage(image); TbResourceInfo savedImage = imageService.saveImage(image);
notificationEntityService.logEntityAction(tenantId, savedImage.getId(), savedImage, actionType, user); logEntityActionService.logEntityAction(tenantId, savedImage.getId(), savedImage, actionType, user);
List<ImageCacheKey> toEvict = new ArrayList<>(); List<ImageCacheKey> toEvict = new ArrayList<>();
if (oldEtag.isPresent()) { if (oldEtag.isPresent()) {
@ -117,7 +117,7 @@ public class DefaultTbImageService extends AbstractTbEntityService implements Tb
return savedImage; return savedImage;
} catch (Exception e) { } catch (Exception e) {
image.setData(null); image.setData(null);
notificationEntityService.logEntityAction(tenantId, emptyId(EntityType.TB_RESOURCE), image, actionType, user, e); logEntityActionService.logEntityAction(tenantId, emptyId(EntityType.TB_RESOURCE), image, actionType, user, e);
throw e; throw e;
} }
} }
@ -139,14 +139,14 @@ public class DefaultTbImageService extends AbstractTbEntityService implements Tb
TbResourceId imageId = imageInfo.getId(); TbResourceId imageId = imageInfo.getId();
try { try {
imageInfo = imageService.saveImageInfo(imageInfo); imageInfo = imageService.saveImageInfo(imageInfo);
notificationEntityService.logEntityAction(tenantId, imageId, imageInfo, ActionType.UPDATED, user); logEntityActionService.logEntityAction(tenantId, imageId, imageInfo, ActionType.UPDATED, user);
if (imageInfo.isPublic() != oldImageInfo.isPublic()) { if (imageInfo.isPublic() != oldImageInfo.isPublic()) {
evictFromCache(tenantId, List.of(ImageCacheKey.forPublicImage(imageInfo.getPublicResourceKey()))); evictFromCache(tenantId, List.of(ImageCacheKey.forPublicImage(imageInfo.getPublicResourceKey())));
} }
return imageInfo; return imageInfo;
} catch (Exception e) { } catch (Exception e) {
notificationEntityService.logEntityAction(tenantId, imageId, imageInfo, ActionType.UPDATED, user, e); logEntityActionService.logEntityAction(tenantId, imageId, imageInfo, ActionType.UPDATED, user, e);
throw e; throw e;
} }
} }
@ -158,7 +158,7 @@ public class DefaultTbImageService extends AbstractTbEntityService implements Tb
try { try {
TbImageDeleteResult result = imageService.deleteImage(imageInfo, force); TbImageDeleteResult result = imageService.deleteImage(imageInfo, force);
if (result.isSuccess()) { if (result.isSuccess()) {
notificationEntityService.logEntityAction(tenantId, imageId, imageInfo, ActionType.DELETED, user, imageId.toString()); logEntityActionService.logEntityAction(tenantId, imageId, imageInfo, ActionType.DELETED, user, imageId.toString());
List<ImageCacheKey> toEvict = new ArrayList<>(); List<ImageCacheKey> toEvict = new ArrayList<>();
toEvict.add(ImageCacheKey.forImage(tenantId, imageInfo.getResourceKey())); toEvict.add(ImageCacheKey.forImage(tenantId, imageInfo.getResourceKey()));
@ -169,7 +169,7 @@ public class DefaultTbImageService extends AbstractTbEntityService implements Tb
} }
return result; return result;
} catch (Exception e) { } catch (Exception e) {
notificationEntityService.logEntityAction(tenantId, imageId, ActionType.DELETED, user, e, imageId.toString()); logEntityActionService.logEntityAction(tenantId, imageId, ActionType.DELETED, user, e, imageId.toString());
throw e; throw e;
} }
} }

13
application/src/main/java/org/thingsboard/server/service/resource/DefaultTbResourceService.java

@ -65,11 +65,10 @@ public class DefaultTbResourceService extends AbstractTbEntityService implements
resource.setResourceKey(resource.getFileName()); resource.setResourceKey(resource.getFileName());
} }
TbResource savedResource = resourceService.saveResource(resource); TbResource savedResource = resourceService.saveResource(resource);
tbClusterService.onResourceChange(savedResource, null); logEntityActionService.logEntityAction(tenantId, savedResource.getId(), savedResource, actionType, user);
notificationEntityService.logEntityAction(tenantId, savedResource.getId(), savedResource, actionType, user);
return savedResource; return savedResource;
} catch (Exception e) { } catch (Exception e) {
notificationEntityService.logEntityAction(tenantId, emptyId(EntityType.TB_RESOURCE), logEntityActionService.logEntityAction(tenantId, emptyId(EntityType.TB_RESOURCE),
resource, actionType, user, e); resource, actionType, user, e);
throw e; throw e;
} }
@ -80,15 +79,15 @@ public class DefaultTbResourceService extends AbstractTbEntityService implements
if (tbResource.getResourceType() == ResourceType.IMAGE) { if (tbResource.getResourceType() == ResourceType.IMAGE) {
throw new IllegalArgumentException("Image resource type is not supported"); throw new IllegalArgumentException("Image resource type is not supported");
} }
ActionType actionType = ActionType.DELETED;
TbResourceId resourceId = tbResource.getId(); TbResourceId resourceId = tbResource.getId();
TenantId tenantId = tbResource.getTenantId(); TenantId tenantId = tbResource.getTenantId();
try { try {
resourceService.deleteResource(tenantId, resourceId); resourceService.deleteResource(tenantId, resourceId);
tbClusterService.onResourceDeleted(tbResource, null); logEntityActionService.logEntityAction(tenantId, resourceId, tbResource, actionType, user, resourceId.toString());
notificationEntityService.logEntityAction(tenantId, resourceId, tbResource, ActionType.DELETED, user, resourceId.toString());
} catch (Exception e) { } catch (Exception e) {
notificationEntityService.logEntityAction(tenantId, emptyId(EntityType.TB_RESOURCE), logEntityActionService.logEntityAction(tenantId, emptyId(EntityType.TB_RESOURCE),
ActionType.DELETED, user, e, resourceId.toString()); actionType, user, e, resourceId.toString());
throw e; throw e;
} }
} }

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

@ -171,20 +171,15 @@ public class DefaultTbRuleChainService extends AbstractTbEntityService implement
@Override @Override
public RuleChain save(RuleChain ruleChain, User user) throws Exception { public RuleChain save(RuleChain ruleChain, User user) throws Exception {
TenantId tenantId = ruleChain.getTenantId();
ActionType actionType = ruleChain.getId() == null ? ActionType.ADDED : ActionType.UPDATED; ActionType actionType = ruleChain.getId() == null ? ActionType.ADDED : ActionType.UPDATED;
TenantId tenantId = ruleChain.getTenantId();
try { try {
RuleChain savedRuleChain = checkNotNull(ruleChainService.saveRuleChain(ruleChain)); RuleChain savedRuleChain = checkNotNull(ruleChainService.saveRuleChain(ruleChain));
autoCommit(user, savedRuleChain.getId()); autoCommit(user, savedRuleChain.getId());
logEntityActionService.logEntityAction(tenantId, savedRuleChain.getId(), savedRuleChain, null, actionType, user);
if (RuleChainType.CORE.equals(savedRuleChain.getType())) {
tbClusterService.broadcastEntityStateChangeEvent(tenantId, savedRuleChain.getId(),
actionType.equals(ActionType.ADDED) ? ComponentLifecycleEvent.CREATED : ComponentLifecycleEvent.UPDATED);
}
notificationEntityService.logEntityAction(tenantId, savedRuleChain.getId(), savedRuleChain, null, actionType, user);
return savedRuleChain; return savedRuleChain;
} catch (Exception e) { } catch (Exception e) {
notificationEntityService.logEntityAction(tenantId, emptyId(EntityType.RULE_CHAIN), ruleChain, actionType, user, e); logEntityActionService.logEntityAction(tenantId, emptyId(EntityType.RULE_CHAIN), ruleChain, actionType, user, e);
throw e; throw e;
} }
} }
@ -194,24 +189,10 @@ public class DefaultTbRuleChainService extends AbstractTbEntityService implement
TenantId tenantId = ruleChain.getTenantId(); TenantId tenantId = ruleChain.getTenantId();
RuleChainId ruleChainId = ruleChain.getId(); RuleChainId ruleChainId = ruleChain.getId();
try { try {
List<RuleNode> referencingRuleNodes = ruleChainService.getReferencingRuleChainNodes(tenantId, ruleChainId);
Set<RuleChainId> referencingRuleChainIds = referencingRuleNodes.stream().map(RuleNode::getRuleChainId).collect(Collectors.toSet());
ruleChainService.deleteRuleChainById(tenantId, ruleChainId); ruleChainService.deleteRuleChainById(tenantId, ruleChainId);
logEntityActionService.logEntityAction(tenantId, ruleChainId, ruleChain, null, ActionType.DELETED, user, ruleChainId.toString());
referencingRuleChainIds.remove(ruleChain.getId());
if (RuleChainType.CORE.equals(ruleChain.getType())) {
referencingRuleChainIds.forEach(referencingRuleChainId ->
tbClusterService.broadcastEntityStateChangeEvent(tenantId, referencingRuleChainId, ComponentLifecycleEvent.UPDATED));
tbClusterService.broadcastEntityStateChangeEvent(tenantId, ruleChain.getId(), ComponentLifecycleEvent.DELETED);
}
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, logEntityActionService.logEntityAction(tenantId, emptyId(EntityType.RULE_CHAIN), ActionType.DELETED,
user, e, ruleChainId.toString()); user, e, ruleChainId.toString());
throw e; throw e;
} }
@ -222,42 +203,34 @@ public class DefaultTbRuleChainService extends AbstractTbEntityService implement
try { try {
RuleChain savedRuleChain = installScripts.createDefaultRuleChain(tenantId, request.getName()); RuleChain savedRuleChain = installScripts.createDefaultRuleChain(tenantId, request.getName());
autoCommit(user, savedRuleChain.getId()); autoCommit(user, savedRuleChain.getId());
tbClusterService.broadcastEntityStateChangeEvent(tenantId, savedRuleChain.getId(), ComponentLifecycleEvent.CREATED); logEntityActionService.logEntityAction(tenantId, savedRuleChain.getId(), savedRuleChain, ActionType.ADDED, user);
notificationEntityService.logEntityAction(tenantId, savedRuleChain.getId(), savedRuleChain, ActionType.ADDED, user);
return savedRuleChain; return savedRuleChain;
} catch (Exception e) { } catch (Exception e) {
RuleChain ruleChain = new RuleChain(); RuleChain ruleChain = new RuleChain();
ruleChain.setName(request.getName()); ruleChain.setName(request.getName());
notificationEntityService.logEntityAction(tenantId, emptyId(EntityType.RULE_CHAIN), ruleChain, logEntityActionService.logEntityAction(tenantId, emptyId(EntityType.RULE_CHAIN), ruleChain,
ActionType.ADDED, user, e); ActionType.ADDED, user, e);
throw e; throw e;
} }
} }
@Override @Override
public RuleChain setRootRuleChain(TenantId tenantId, RuleChain ruleChain, User user) throws ThingsboardException { public RuleChain setRootRuleChain(TenantId tenantId, RuleChain ruleChain, User user) {
RuleChainId ruleChainId = ruleChain.getId(); RuleChainId ruleChainId = ruleChain.getId();
try { try {
RuleChain previousRootRuleChain = ruleChainService.getRootTenantRuleChain(tenantId); RuleChain previousRootRuleChain = ruleChainService.getRootTenantRuleChain(tenantId);
if (ruleChainService.setRootRuleChain(tenantId, ruleChainId)) { if (ruleChainService.setRootRuleChain(tenantId, ruleChainId)) {
if (previousRootRuleChain != null) { if (previousRootRuleChain != null) {
RuleChainId previousRootRuleChainId = previousRootRuleChain.getId(); previousRootRuleChain = ruleChainService.findRuleChainById(tenantId, previousRootRuleChain.getId());
previousRootRuleChain = ruleChainService.findRuleChainById(tenantId, previousRootRuleChainId); logEntityActionService.logEntityAction(tenantId, previousRootRuleChain.getId(), previousRootRuleChain,
tbClusterService.broadcastEntityStateChangeEvent(tenantId, previousRootRuleChainId,
ComponentLifecycleEvent.UPDATED);
notificationEntityService.logEntityAction(tenantId, previousRootRuleChainId, previousRootRuleChain,
ActionType.UPDATED, user); ActionType.UPDATED, user);
} }
ruleChain = ruleChainService.findRuleChainById(tenantId, ruleChainId); ruleChain = ruleChainService.findRuleChainById(tenantId, ruleChainId);
logEntityActionService.logEntityAction(tenantId, ruleChainId, ruleChain, ActionType.UPDATED, user);
tbClusterService.broadcastEntityStateChangeEvent(tenantId, ruleChainId,
ComponentLifecycleEvent.UPDATED);
notificationEntityService.logEntityAction(tenantId, ruleChainId, ruleChain, ActionType.UPDATED, user);
} }
return ruleChain; return ruleChain;
} catch (Exception e) { } catch (Exception e) {
notificationEntityService.logEntityAction(tenantId, emptyId(EntityType.RULE_CHAIN), ActionType.UPDATED, logEntityActionService.logEntityAction(tenantId, emptyId(EntityType.RULE_CHAIN), ActionType.UPDATED,
user, e, ruleChainId.toString()); user, e, ruleChainId.toString());
throw e; throw e;
} }
@ -291,24 +264,22 @@ public class DefaultTbRuleChainService extends AbstractTbEntityService implement
RuleChainMetaData savedRuleChainMetaData = checkNotNull(ruleChainService.loadRuleChainMetaData(tenantId, ruleChainMetaDataId)); RuleChainMetaData savedRuleChainMetaData = checkNotNull(ruleChainService.loadRuleChainMetaData(tenantId, ruleChainMetaDataId));
if (RuleChainType.CORE.equals(ruleChain.getType())) { if (RuleChainType.CORE.equals(ruleChain.getType())) {
tbClusterService.broadcastEntityStateChangeEvent(tenantId, ruleChainId, ComponentLifecycleEvent.UPDATED); updatedRuleChains.forEach(updatedRuleChain ->
updatedRuleChains.forEach(updatedRuleChain -> { tbClusterService.broadcastEntityStateChangeEvent(tenantId, updatedRuleChain.getId(), ComponentLifecycleEvent.UPDATED));
tbClusterService.broadcastEntityStateChangeEvent(tenantId, updatedRuleChain.getId(), ComponentLifecycleEvent.UPDATED);
});
} }
notificationEntityService.logEntityAction(tenantId, ruleChainId, ruleChain, ActionType.UPDATED, user, ruleChainMetaData); logEntityActionService.logEntityAction(tenantId, ruleChainId, ruleChain, ActionType.UPDATED, user, ruleChainMetaData);
for (RuleChain updatedRuleChain : updatedRuleChains) { for (RuleChain updatedRuleChain : updatedRuleChains) {
if (RuleChainType.CORE.equals(ruleChain.getType())) { if (RuleChainType.CORE.equals(ruleChain.getType())) {
RuleChainMetaData updatedRuleChainMetaData = checkNotNull(ruleChainService.loadRuleChainMetaData(tenantId, updatedRuleChain.getId())); RuleChainMetaData updatedRuleChainMetaData = checkNotNull(ruleChainService.loadRuleChainMetaData(tenantId, updatedRuleChain.getId()));
notificationEntityService.logEntityAction(tenantId, updatedRuleChain.getId(), updatedRuleChain, logEntityActionService.logEntityAction(tenantId, updatedRuleChain.getId(), updatedRuleChain,
ActionType.UPDATED, user, updatedRuleChainMetaData); ActionType.UPDATED, user, updatedRuleChainMetaData);
} }
} }
return savedRuleChainMetaData; return savedRuleChainMetaData;
} catch (Exception e) { } catch (Exception e) {
notificationEntityService.logEntityAction(tenantId, emptyId(EntityType.RULE_CHAIN), ActionType.ADDED, logEntityActionService.logEntityAction(tenantId, emptyId(EntityType.RULE_CHAIN), ActionType.ADDED,
user, e, ruleChainMetaData); user, e, ruleChainMetaData);
throw e; throw e;
} }
@ -321,11 +292,11 @@ public class DefaultTbRuleChainService extends AbstractTbEntityService implement
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.logEntityAction(tenantId, ruleChainId, savedRuleChain, null, actionType, logEntityActionService.logEntityAction(tenantId, ruleChainId, savedRuleChain, null, actionType,
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), logEntityActionService.logEntityAction(tenantId, emptyId(EntityType.RULE_CHAIN),
actionType, user, e, ruleChainId.toString(), edgeId.toString()); actionType, user, e, ruleChainId.toString(), edgeId.toString());
throw e; throw e;
} }
@ -338,11 +309,11 @@ public class DefaultTbRuleChainService extends AbstractTbEntityService implement
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.logEntityAction(tenantId, ruleChainId, savedRuleChain, null, actionType, logEntityActionService.logEntityAction(tenantId, ruleChainId, savedRuleChain, null, actionType,
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), logEntityActionService.logEntityAction(tenantId, emptyId(EntityType.RULE_CHAIN),
actionType, user, e, ruleChainId, edgeId); actionType, user, e, ruleChainId, edgeId);
throw e; throw e;
} }
@ -353,10 +324,10 @@ public class DefaultTbRuleChainService extends AbstractTbEntityService implement
RuleChainId ruleChainId = ruleChain.getId(); RuleChainId ruleChainId = ruleChain.getId();
try { try {
ruleChainService.setEdgeTemplateRootRuleChain(tenantId, ruleChainId); ruleChainService.setEdgeTemplateRootRuleChain(tenantId, ruleChainId);
notificationEntityService.logEntityAction(tenantId, ruleChainId, ruleChain, ActionType.UPDATED, user); logEntityActionService.logEntityAction(tenantId, ruleChainId, ruleChain, ActionType.UPDATED, user);
return ruleChain; return ruleChain;
} catch (Exception e) { } catch (Exception e) {
notificationEntityService.logEntityAction(tenantId, emptyId(EntityType.RULE_CHAIN), ActionType.UPDATED, logEntityActionService.logEntityAction(tenantId, emptyId(EntityType.RULE_CHAIN), ActionType.UPDATED,
user, e, ruleChainId.toString()); user, e, ruleChainId.toString());
throw e; throw e;
} }
@ -367,10 +338,10 @@ public class DefaultTbRuleChainService extends AbstractTbEntityService implement
RuleChainId ruleChainId = ruleChain.getId(); RuleChainId ruleChainId = ruleChain.getId();
try { try {
ruleChainService.setAutoAssignToEdgeRuleChain(tenantId, ruleChainId); ruleChainService.setAutoAssignToEdgeRuleChain(tenantId, ruleChainId);
notificationEntityService.logEntityAction(tenantId, ruleChainId, ruleChain, ActionType.UPDATED, user); logEntityActionService.logEntityAction(tenantId, ruleChainId, ruleChain, ActionType.UPDATED, user);
return ruleChain; return ruleChain;
} catch (Exception e) { } catch (Exception e) {
notificationEntityService.logEntityAction(tenantId, emptyId(EntityType.RULE_CHAIN), ActionType.UPDATED, logEntityActionService.logEntityAction(tenantId, emptyId(EntityType.RULE_CHAIN), ActionType.UPDATED,
user, e, ruleChainId.toString()); user, e, ruleChainId.toString());
throw e; throw e;
} }
@ -381,10 +352,10 @@ public class DefaultTbRuleChainService extends AbstractTbEntityService implement
RuleChainId ruleChainId = ruleChain.getId(); RuleChainId ruleChainId = ruleChain.getId();
try { try {
ruleChainService.unsetAutoAssignToEdgeRuleChain(tenantId, ruleChainId); ruleChainService.unsetAutoAssignToEdgeRuleChain(tenantId, ruleChainId);
notificationEntityService.logEntityAction(tenantId, ruleChainId, ruleChain, ActionType.UPDATED, user); logEntityActionService.logEntityAction(tenantId, ruleChainId, ruleChain, ActionType.UPDATED, user);
return ruleChain; return ruleChain;
} catch (Exception e) { } catch (Exception e) {
notificationEntityService.logEntityAction(tenantId, emptyId(EntityType.RULE_CHAIN), ActionType.UPDATED, logEntityActionService.logEntityAction(tenantId, emptyId(EntityType.RULE_CHAIN), ActionType.UPDATED,
user, e, ruleChainId.toString()); user, e, ruleChainId.toString());
throw e; throw e;
} }

13
application/src/main/java/org/thingsboard/server/service/security/auth/oauth2/AbstractOAuth2ClientMapper.java

@ -20,11 +20,11 @@ import lombok.Getter;
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.beans.factory.annotation.Value; import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.userdetails.UsernameNotFoundException; import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.thingsboard.common.util.JacksonUtil; import org.thingsboard.common.util.JacksonUtil;
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.DashboardInfo; import org.thingsboard.server.common.data.DashboardInfo;
import org.thingsboard.server.common.data.StringUtils; import org.thingsboard.server.common.data.StringUtils;
@ -38,11 +38,11 @@ import org.thingsboard.server.common.data.oauth2.OAuth2MapperConfig;
import org.thingsboard.server.common.data.oauth2.OAuth2Registration; import org.thingsboard.server.common.data.oauth2.OAuth2Registration;
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.plugin.ComponentLifecycleEvent;
import org.thingsboard.server.common.data.security.Authority; import org.thingsboard.server.common.data.security.Authority;
import org.thingsboard.server.common.data.security.UserCredentials; import org.thingsboard.server.common.data.security.UserCredentials;
import org.thingsboard.server.dao.customer.CustomerService; import org.thingsboard.server.dao.customer.CustomerService;
import org.thingsboard.server.dao.dashboard.DashboardService; import org.thingsboard.server.dao.dashboard.DashboardService;
import org.thingsboard.server.dao.eventsourcing.SaveEntityEvent;
import org.thingsboard.server.dao.oauth2.OAuth2User; import org.thingsboard.server.dao.oauth2.OAuth2User;
import org.thingsboard.server.dao.tenant.TbTenantProfileCache; import org.thingsboard.server.dao.tenant.TbTenantProfileCache;
import org.thingsboard.server.dao.tenant.TenantService; import org.thingsboard.server.dao.tenant.TenantService;
@ -87,12 +87,12 @@ public abstract class AbstractOAuth2ClientMapper {
protected TbTenantProfileCache tenantProfileCache; protected TbTenantProfileCache tenantProfileCache;
@Autowired @Autowired
protected TbClusterService tbClusterService; private ApplicationEventPublisher eventPublisher;
@Value("${edges.enabled}") @Value("${edges.enabled}")
@Getter @Getter
private boolean edgesEnabled; private boolean edgesEnabled;
private final Lock userCreationLock = new ReentrantLock(); private final Lock userCreationLock = new ReentrantLock();
protected SecurityUser getOrCreateSecurityUserFromOAuth2User(OAuth2User oauth2User, OAuth2Registration registration) { protected SecurityUser getOrCreateSecurityUserFromOAuth2User(OAuth2User oauth2User, OAuth2Registration registration) {
@ -181,9 +181,8 @@ public abstract class AbstractOAuth2ClientMapper {
installScripts.createDefaultRuleChains(tenant.getId()); installScripts.createDefaultRuleChains(tenant.getId());
installScripts.createDefaultEdgeRuleChains(tenant.getId()); installScripts.createDefaultEdgeRuleChains(tenant.getId());
tenantProfileCache.evict(tenant.getId()); tenantProfileCache.evict(tenant.getId());
tbClusterService.onTenantChange(tenant, null);
tbClusterService.broadcastEntityStateChangeEvent(tenant.getId(), tenant.getId(), eventPublisher.publishEvent(SaveEntityEvent.builder().tenantId(TenantId.SYS_TENANT_ID).entityId(tenant.getId()).entity(tenant).added(true).build());
ComponentLifecycleEvent.CREATED);
} else { } else {
tenant = tenants.get(0); tenant = tenants.get(0);
} }

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

@ -34,7 +34,7 @@ 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.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.entitiy.TbNotificationEntityService; import org.thingsboard.server.service.entitiy.TbLogEntityActionService;
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;
import org.thingsboard.server.service.sync.ie.exporting.impl.DefaultEntityExportService; import org.thingsboard.server.service.sync.ie.exporting.impl.DefaultEntityExportService;
@ -62,7 +62,7 @@ public class DefaultEntitiesExportImportService implements EntitiesExportImportS
private final RelationService relationService; private final RelationService relationService;
private final RateLimitService rateLimitService; private final RateLimitService rateLimitService;
private final TbNotificationEntityService entityNotificationService; private final TbLogEntityActionService logEntityActionService;
protected static final List<EntityType> SUPPORTED_ENTITY_TYPES = List.of( protected static final List<EntityType> SUPPORTED_ENTITY_TYPES = List.of(
EntityType.CUSTOMER, EntityType.RULE_CHAIN, EntityType.TB_RESOURCE, EntityType.CUSTOMER, EntityType.RULE_CHAIN, EntityType.TB_RESOURCE,
@ -120,7 +120,7 @@ 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.logEntityRelationAction(ctx.getTenantId(), null, logEntityActionService.logEntityRelationAction(ctx.getTenantId(), null,
relation, ctx.getUser(), ActionType.RELATION_ADD_OR_UPDATE, null, relation); relation, ctx.getUser(), ActionType.RELATION_ADD_OR_UPDATE, null, relation);
} }
} }

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

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

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

@ -50,7 +50,7 @@ import org.thingsboard.server.common.data.sync.ie.EntityImportResult;
import org.thingsboard.server.dao.relation.RelationDao; import org.thingsboard.server.dao.relation.RelationDao;
import org.thingsboard.server.dao.relation.RelationService; import org.thingsboard.server.dao.relation.RelationService;
import org.thingsboard.server.service.action.EntityActionService; import org.thingsboard.server.service.action.EntityActionService;
import org.thingsboard.server.service.entitiy.TbNotificationEntityService; import org.thingsboard.server.service.entitiy.TbLogEntityActionService;
import org.thingsboard.server.service.sync.ie.exporting.ExportableEntitiesService; import org.thingsboard.server.service.sync.ie.exporting.ExportableEntitiesService;
import org.thingsboard.server.service.sync.ie.importing.EntityImportService; import org.thingsboard.server.service.sync.ie.importing.EntityImportService;
import org.thingsboard.server.service.sync.vc.data.EntitiesImportCtx; import org.thingsboard.server.service.sync.vc.data.EntitiesImportCtx;
@ -85,7 +85,7 @@ public abstract class BaseEntityImportService<I extends EntityId, E extends Expo
@Autowired @Autowired
protected TbClusterService clusterService; protected TbClusterService clusterService;
@Autowired @Autowired
protected TbNotificationEntityService entityNotificationService; protected TbLogEntityActionService logEntityActionService;
@Override @Override
public EntityImportResult<E> importEntity(EntitiesImportCtx ctx, D exportData) throws ThingsboardException { public EntityImportResult<E> importEntity(EntitiesImportCtx ctx, D exportData) throws ThingsboardException {
@ -212,7 +212,7 @@ 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.logEntityRelationAction(tenantId, null, logEntityActionService.logEntityRelationAction(tenantId, null,
existingRelation, ctx.getUser(), ActionType.RELATION_DELETED, null, 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())) {
@ -267,7 +267,7 @@ 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.logEntityAction(user.getTenantId(), savedEntity.getId(), savedEntity, null, logEntityActionService.logEntityAction(user.getTenantId(), savedEntity.getId(), savedEntity, null,
oldEntity == null ? ActionType.ADDED : ActionType.UPDATED, user); oldEntity == null ? ActionType.ADDED : ActionType.UPDATED, user);
} }

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

@ -19,9 +19,6 @@ import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
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.EntityType;
import org.thingsboard.server.common.data.User;
import org.thingsboard.server.common.data.audit.ActionType;
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.TenantId; import org.thingsboard.server.common.data.id.TenantId;
import org.thingsboard.server.common.data.sync.ie.DeviceExportData; import org.thingsboard.server.common.data.sync.ie.DeviceExportData;
@ -92,12 +89,6 @@ public class DeviceImportService extends BaseEntityImportService<DeviceId, Devic
return updated; return updated;
} }
@Override
protected void onEntitySaved(User user, Device savedDevice, Device oldDevice) throws ThingsboardException {
entityNotificationService.notifyCreateOrUpdateDevice(user.getTenantId(), savedDevice.getId(), savedDevice.getCustomerId(),
savedDevice, oldDevice, oldDevice == null ? ActionType.ADDED : ActionType.UPDATED, user);
}
@Override @Override
public EntityType getEntityType() { public EntityType getEntityType() {
return EntityType.DEVICE; return EntityType.DEVICE;

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

@ -21,25 +21,19 @@ import org.thingsboard.server.common.data.DeviceProfile;
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.exception.ThingsboardException;
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.common.data.id.TenantId;
import org.thingsboard.server.common.data.plugin.ComponentLifecycleEvent;
import org.thingsboard.server.common.data.sync.ie.EntityExportData; import org.thingsboard.server.common.data.sync.ie.EntityExportData;
import org.thingsboard.server.dao.device.DeviceProfileService; import org.thingsboard.server.dao.device.DeviceProfileService;
import org.thingsboard.server.queue.util.TbCoreComponent; import org.thingsboard.server.queue.util.TbCoreComponent;
import org.thingsboard.server.service.ota.OtaPackageStateService;
import org.thingsboard.server.service.sync.vc.data.EntitiesImportCtx; import org.thingsboard.server.service.sync.vc.data.EntitiesImportCtx;
import java.util.Objects;
@Service @Service
@TbCoreComponent @TbCoreComponent
@RequiredArgsConstructor @RequiredArgsConstructor
public class DeviceProfileImportService extends BaseEntityImportService<DeviceProfileId, DeviceProfile, EntityExportData<DeviceProfile>> { public class DeviceProfileImportService extends BaseEntityImportService<DeviceProfileId, DeviceProfile, EntityExportData<DeviceProfile>> {
private final DeviceProfileService deviceProfileService; private final DeviceProfileService deviceProfileService;
private final OtaPackageStateService otaPackageStateService;
@Override @Override
protected void setOwner(TenantId tenantId, DeviceProfile deviceProfile, IdProvider idProvider) { protected void setOwner(TenantId tenantId, DeviceProfile deviceProfile, IdProvider idProvider) {
@ -62,14 +56,8 @@ public class DeviceProfileImportService extends BaseEntityImportService<DevicePr
} }
@Override @Override
protected void onEntitySaved(User user, DeviceProfile savedDeviceProfile, DeviceProfile oldDeviceProfile) throws ThingsboardException { protected void onEntitySaved(User user, DeviceProfile savedDeviceProfile, DeviceProfile oldDeviceProfile) {
clusterService.onDeviceProfileChange(savedDeviceProfile, null); logEntityActionService.logEntityAction(savedDeviceProfile.getTenantId(), savedDeviceProfile.getId(), savedDeviceProfile,
clusterService.broadcastEntityStateChangeEvent(user.getTenantId(), savedDeviceProfile.getId(),
oldDeviceProfile == null ? ComponentLifecycleEvent.CREATED : ComponentLifecycleEvent.UPDATED);
otaPackageStateService.update(savedDeviceProfile,
oldDeviceProfile != null && !Objects.equals(oldDeviceProfile.getFirmwareId(), savedDeviceProfile.getFirmwareId()),
oldDeviceProfile != null && !Objects.equals(oldDeviceProfile.getSoftwareId(), savedDeviceProfile.getSoftwareId()));
entityNotificationService.logEntityAction(savedDeviceProfile.getTenantId(), savedDeviceProfile.getId(), savedDeviceProfile,
null, oldDeviceProfile == null ? ActionType.ADDED : ActionType.UPDATED, user); null, oldDeviceProfile == null ? ActionType.ADDED : ActionType.UPDATED, user);
} }

2
application/src/main/java/org/thingsboard/server/service/sync/ie/importing/impl/EntityViewImportService.java

@ -64,8 +64,6 @@ public class EntityViewImportService extends BaseEntityImportService<EntityViewI
protected void onEntitySaved(User user, EntityView savedEntityView, EntityView oldEntityView) throws ThingsboardException { protected void onEntitySaved(User user, EntityView savedEntityView, EntityView oldEntityView) throws ThingsboardException {
tbEntityViewService.updateEntityViewAttributes(user.getTenantId(), savedEntityView, oldEntityView, user); tbEntityViewService.updateEntityViewAttributes(user.getTenantId(), savedEntityView, oldEntityView, user);
super.onEntitySaved(user, savedEntityView, oldEntityView); super.onEntitySaved(user, savedEntityView, oldEntityView);
clusterService.broadcastEntityStateChangeEvent(savedEntityView.getTenantId(), savedEntityView.getId(),
oldEntityView == null ? ComponentLifecycleEvent.CREATED : ComponentLifecycleEvent.UPDATED);
} }
@Override @Override

6
application/src/main/java/org/thingsboard/server/service/sync/ie/importing/impl/NotificationRuleImportService.java

@ -20,7 +20,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.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.DeviceProfileId; import org.thingsboard.server.common.data.id.DeviceProfileId;
import org.thingsboard.server.common.data.id.NotificationRuleId; import org.thingsboard.server.common.data.id.NotificationRuleId;
@ -36,7 +35,6 @@ import org.thingsboard.server.common.data.notification.rule.trigger.config.Devic
import org.thingsboard.server.common.data.notification.rule.trigger.config.NotificationRuleTriggerConfig; import org.thingsboard.server.common.data.notification.rule.trigger.config.NotificationRuleTriggerConfig;
import org.thingsboard.server.common.data.notification.rule.trigger.config.NotificationRuleTriggerType; import org.thingsboard.server.common.data.notification.rule.trigger.config.NotificationRuleTriggerType;
import org.thingsboard.server.common.data.notification.rule.trigger.config.RuleEngineComponentLifecycleEventNotificationRuleTriggerConfig; import org.thingsboard.server.common.data.notification.rule.trigger.config.RuleEngineComponentLifecycleEventNotificationRuleTriggerConfig;
import org.thingsboard.server.common.data.plugin.ComponentLifecycleEvent;
import org.thingsboard.server.common.data.sync.ie.EntityExportData; import org.thingsboard.server.common.data.sync.ie.EntityExportData;
import org.thingsboard.server.dao.notification.NotificationRuleService; import org.thingsboard.server.dao.notification.NotificationRuleService;
import org.thingsboard.server.dao.service.ConstraintValidator; import org.thingsboard.server.dao.service.ConstraintValidator;
@ -130,11 +128,9 @@ public class NotificationRuleImportService extends BaseEntityImportService<Notif
} }
@Override @Override
protected void onEntitySaved(User user, NotificationRule savedEntity, NotificationRule oldEntity) throws ThingsboardException { protected void onEntitySaved(User user, NotificationRule savedEntity, NotificationRule oldEntity) {
entityActionService.logEntityAction(user, savedEntity.getId(), savedEntity, null, entityActionService.logEntityAction(user, savedEntity.getId(), savedEntity, null,
oldEntity == null ? ActionType.ADDED : ActionType.UPDATED, null); oldEntity == null ? ActionType.ADDED : ActionType.UPDATED, null);
clusterService.broadcastEntityStateChangeEvent(user.getTenantId(), savedEntity.getId(),
oldEntity == null ? ComponentLifecycleEvent.CREATED : ComponentLifecycleEvent.UPDATED);
} }
@Override @Override

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

@ -132,10 +132,6 @@ public class RuleChainImportService extends BaseEntityImportService<RuleChainId,
protected void onEntitySaved(User user, RuleChain savedRuleChain, RuleChain oldRuleChain) { 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) {
clusterService.broadcastEntityStateChangeEvent(user.getTenantId(), savedRuleChain.getId(),
oldRuleChain == null ? ComponentLifecycleEvent.CREATED : ComponentLifecycleEvent.UPDATED);
}
} }
@Override @Override

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

@ -68,7 +68,7 @@ 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.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.TbLogEntityActionService;
import org.thingsboard.server.service.executors.VersionControlExecutor; import org.thingsboard.server.service.executors.VersionControlExecutor;
import org.thingsboard.server.service.sync.ie.EntitiesExportImportService; import org.thingsboard.server.service.sync.ie.EntitiesExportImportService;
import org.thingsboard.server.service.sync.ie.exporting.ExportableEntitiesService; import org.thingsboard.server.service.sync.ie.exporting.ExportableEntitiesService;
@ -108,7 +108,7 @@ public class DefaultEntitiesVersionControlService implements EntitiesVersionCont
private final GitVersionControlQueueService gitServiceQueue; private final GitVersionControlQueueService gitServiceQueue;
private final EntitiesExportImportService exportImportService; private final EntitiesExportImportService exportImportService;
private final ExportableEntitiesService exportableEntitiesService; private final ExportableEntitiesService exportableEntitiesService;
private final TbNotificationEntityService entityNotificationService; private final TbLogEntityActionService logEntityActionService;
private final TransactionTemplate transactionTemplate; private final TransactionTemplate transactionTemplate;
private final TbTransactionalCache<UUID, VersionControlTaskCacheEntry> taskCache; private final TbTransactionalCache<UUID, VersionControlTaskCacheEntry> taskCache;
private final VersionControlExecutor executor; private final VersionControlExecutor executor;
@ -419,10 +419,8 @@ public class DefaultEntitiesVersionControlService implements EntitiesVersionCont
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())) {
exportableEntitiesService.removeById(ctx.getTenantId(), entity.getId()); exportableEntitiesService.removeById(ctx.getTenantId(), entity.getId());
ctx.addEventCallback(() -> { ctx.addEventCallback(() -> logEntityActionService.logEntityAction(ctx.getTenantId(), entity.getId(), entity, null,
entityNotificationService.logEntityAction(ctx.getTenantId(), entity.getId(), entity, null, ActionType.DELETED, ctx.getUser()));
ActionType.DELETED, ctx.getUser());
});
ctx.registerDeleted(entityType); ctx.registerDeleted(entityType);
} }
}); });

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

@ -351,9 +351,7 @@ public class DefaultTransportApiService implements TransportApiService {
ObjectNode additionalInfo = JacksonUtil.newObjectNode(); ObjectNode additionalInfo = JacksonUtil.newObjectNode();
additionalInfo.put(DataConstants.LAST_CONNECTED_GATEWAY, gatewayId.toString()); additionalInfo.put(DataConstants.LAST_CONNECTED_GATEWAY, gatewayId.toString());
device.setAdditionalInfo(additionalInfo); device.setAdditionalInfo(additionalInfo);
Device savedDevice = deviceService.saveDevice(device); device = deviceService.saveDevice(device);
tbClusterService.onDeviceUpdated(savedDevice, null);
device = savedDevice;
relationService.saveRelation(TenantId.SYS_TENANT_ID, new EntityRelation(gateway.getId(), device.getId(), "Created")); relationService.saveRelation(TenantId.SYS_TENANT_ID, new EntityRelation(gateway.getId(), device.getId(), "Created"));
@ -378,8 +376,7 @@ public class DefaultTransportApiService implements TransportApiService {
|| !gatewayId.toString().equals(deviceAdditionalInfo.get(DataConstants.LAST_CONNECTED_GATEWAY).asText()))) { || !gatewayId.toString().equals(deviceAdditionalInfo.get(DataConstants.LAST_CONNECTED_GATEWAY).asText()))) {
ObjectNode newDeviceAdditionalInfo = (ObjectNode) deviceAdditionalInfo; ObjectNode newDeviceAdditionalInfo = (ObjectNode) deviceAdditionalInfo;
newDeviceAdditionalInfo.put(DataConstants.LAST_CONNECTED_GATEWAY, gatewayId.toString()); newDeviceAdditionalInfo.put(DataConstants.LAST_CONNECTED_GATEWAY, gatewayId.toString());
Device savedDevice = deviceService.saveDevice(device); deviceService.saveDevice(device);
tbClusterService.onDeviceUpdated(savedDevice, device);
} }
} }
GetOrCreateDeviceFromGatewayResponseMsg.Builder builder = GetOrCreateDeviceFromGatewayResponseMsg.newBuilder() GetOrCreateDeviceFromGatewayResponseMsg.Builder builder = GetOrCreateDeviceFromGatewayResponseMsg.newBuilder()
@ -409,7 +406,7 @@ public class DefaultTransportApiService implements TransportApiService {
} }
private ListenableFuture<TransportApiResponseMsg> handle(ProvisionDeviceRequestMsg requestMsg) { private ListenableFuture<TransportApiResponseMsg> handle(ProvisionDeviceRequestMsg requestMsg) {
ListenableFuture<ProvisionResponse> provisionResponseFuture = null; ListenableFuture<ProvisionResponse> provisionResponseFuture;
try { try {
provisionResponseFuture = Futures.immediateFuture(deviceProvisionService.provisionDevice( provisionResponseFuture = Futures.immediateFuture(deviceProvisionService.provisionDevice(
new ProvisionRequest( new ProvisionRequest(
@ -649,7 +646,6 @@ public class DefaultTransportApiService implements TransportApiService {
device.setName(deviceName); device.setName(deviceName);
device.setType("LwM2M"); device.setType("LwM2M");
device = deviceService.saveDevice(device); device = deviceService.saveDevice(device);
tbClusterService.onDeviceUpdated(device, null);
} }
TransportProtos.LwM2MRegistrationResponseMsg registrationResponseMsg = TransportProtos.LwM2MRegistrationResponseMsg registrationResponseMsg =
TransportProtos.LwM2MRegistrationResponseMsg.newBuilder() TransportProtos.LwM2MRegistrationResponseMsg.newBuilder()

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

@ -20,6 +20,7 @@ import org.mockito.ArgumentMatcher;
import org.mockito.Mockito; import org.mockito.Mockito;
import org.springframework.boot.test.mock.mockito.SpyBean; import org.springframework.boot.test.mock.mockito.SpyBean;
import org.thingsboard.server.cluster.TbClusterService; import org.thingsboard.server.cluster.TbClusterService;
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.HasTenantId; import org.thingsboard.server.common.data.HasTenantId;
@ -47,7 +48,6 @@ import java.util.stream.Collectors;
import static org.mockito.Mockito.never; import static org.mockito.Mockito.never;
import static org.mockito.Mockito.times; import static org.mockito.Mockito.times;
import static org.thingsboard.server.service.entitiy.DefaultTbNotificationEntityService.edgeTypeByActionType;
@Slf4j @Slf4j
public abstract class AbstractNotifyEntityTest extends AbstractWebTest { public abstract class AbstractNotifyEntityTest extends AbstractWebTest {
@ -91,7 +91,7 @@ public abstract class AbstractNotifyEntityTest extends AbstractWebTest {
int cntTime = 1; int cntTime = 1;
Mockito.verify(tbClusterService, times(cntTime)).sendNotificationMsgToEdge(Mockito.eq(tenantId), Mockito.verify(tbClusterService, times(cntTime)).sendNotificationMsgToEdge(Mockito.eq(tenantId),
Mockito.isNull(), Mockito.isNull(), Mockito.any(), Mockito.eq(EdgeEventType.RELATION), Mockito.isNull(), Mockito.isNull(), Mockito.any(), Mockito.eq(EdgeEventType.RELATION),
Mockito.eq(edgeTypeByActionType(actionType)), Mockito.any()); Mockito.eq(EdgeUtils.getEdgeEventActionTypeByActionType(actionType)), Mockito.any());
ArgumentMatcher<EntityId> matcherOriginatorId = argument -> argument.equals(relation.getTo()); ArgumentMatcher<EntityId> matcherOriginatorId = argument -> argument.equals(relation.getTo());
ArgumentMatcher<HasName> matcherEntityClassEquals = Objects::isNull; ArgumentMatcher<HasName> matcherEntityClassEquals = Objects::isNull;
ArgumentMatcher<CustomerId> matcherCustomerId = customerId == null ? ArgumentMatcher<CustomerId> matcherCustomerId = customerId == null ?
@ -111,7 +111,7 @@ public abstract class AbstractNotifyEntityTest extends AbstractWebTest {
ActionType actionType, int cntTime) { ActionType actionType, int cntTime) {
Mockito.verify(tbClusterService, times(cntTime)).sendNotificationMsgToEdge(Mockito.eq(tenantId), Mockito.verify(tbClusterService, times(cntTime)).sendNotificationMsgToEdge(Mockito.eq(tenantId),
Mockito.isNull(), Mockito.isNull(), Mockito.any(), Mockito.eq(EdgeEventType.RELATION), Mockito.isNull(), Mockito.isNull(), Mockito.any(), Mockito.eq(EdgeEventType.RELATION),
Mockito.eq(edgeTypeByActionType(actionType)), Mockito.any()); Mockito.eq(EdgeUtils.getEdgeEventActionTypeByActionType(actionType)), Mockito.any());
ArgumentMatcher<EntityId> matcherOriginatorId = argument -> argument.getClass().equals(relation.getFrom().getClass()); ArgumentMatcher<EntityId> matcherOriginatorId = argument -> argument.getClass().equals(relation.getFrom().getClass());
ArgumentMatcher<HasName> matcherEntityClassEquals = Objects::isNull; ArgumentMatcher<HasName> matcherEntityClassEquals = Objects::isNull;
ArgumentMatcher<CustomerId> matcherCustomerId = customerId == null ? ArgumentMatcher<CustomerId> matcherCustomerId = customerId == null ?
@ -236,15 +236,15 @@ public abstract class AbstractNotifyEntityTest extends AbstractWebTest {
Mockito.reset(tbClusterService, auditLogService); Mockito.reset(tbClusterService, auditLogService);
} }
protected void testNotifyEntityBroadcastEntityStateChangeEventOneTimeMsgToEdgeServiceNever(HasName entity, EntityId entityId, EntityId originatorId, protected void testNotifyEntityBroadcastEntityStateChangeEventManyTimeMsgToEdgeServiceNever(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, int cntTimeBroadcast, Object... additionalInfo) {
int cntTime = 1; int cntTime = 1;
testNotificationMsgToEdgeServiceNeverWithActionType(entityId, actionType); testNotificationMsgToEdgeServiceNeverWithActionType(entityId, actionType);
testLogEntityAction(entity, originatorId, tenantId, customerId, userId, userName, actionType, cntTime, additionalInfo); testLogEntityAction(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);
testBroadcastEntityStateChangeEventTime(entityId, tenantId, cntTime); testBroadcastEntityStateChangeEventTime(entityId, tenantId, cntTimeBroadcast);
Mockito.reset(tbClusterService, auditLogService); Mockito.reset(tbClusterService, auditLogService);
} }
@ -266,7 +266,7 @@ public abstract class AbstractNotifyEntityTest extends AbstractWebTest {
testLogEntityActionAdditionalInfoAny(matcherEntityClassEquals, matcherOriginatorId, tenantId, matcherCustomerId, matcherUserId, userName, actionType, cntTime, testLogEntityActionAdditionalInfoAny(matcherEntityClassEquals, matcherOriginatorId, tenantId, matcherCustomerId, matcherUserId, userName, actionType, cntTime,
cntAdditionalInfo); cntAdditionalInfo);
testPushMsgToRuleEngineTime(matcherOriginatorId, tenantId, entity, cntTimeRuleEngine); testPushMsgToRuleEngineTime(matcherOriginatorId, tenantId, entity, cntTimeRuleEngine);
testBroadcastEntityStateChangeEventTime(entityId, tenantId, cntTime); testBroadcastEntityStateChangeEventTime(entityId, tenantId, cntTime * 2);
} }
protected void testNotifyEntityMsgToEdgePushMsgToCoreOneTime(HasName entity, EntityId entityId, EntityId originatorId, protected void testNotifyEntityMsgToEdgePushMsgToCoreOneTime(HasName entity, EntityId entityId, EntityId originatorId,
@ -317,9 +317,9 @@ public abstract class AbstractNotifyEntityTest extends AbstractWebTest {
private void testNotificationMsgToEdgeServiceNeverWithActionType(EntityId entityId, ActionType actionType) { private void testNotificationMsgToEdgeServiceNeverWithActionType(EntityId entityId, ActionType actionType) {
EdgeEventActionType edgeEventActionType = ActionType.CREDENTIALS_UPDATED.equals(actionType) ? EdgeEventActionType edgeEventActionType = ActionType.CREDENTIALS_UPDATED.equals(actionType) ?
EdgeEventActionType.CREDENTIALS_UPDATED : edgeTypeByActionType(actionType); EdgeEventActionType.CREDENTIALS_UPDATED : EdgeUtils.getEdgeEventActionTypeByActionType(actionType);
Mockito.verify(tbClusterService, never()).sendNotificationMsgToEdge(Mockito.any(), Mockito.any(), Mockito.verify(tbClusterService, never()).sendNotificationMsgToEdge(Mockito.any(),
Mockito.any(entityId.getClass()), Mockito.any(), Mockito.any(), Mockito.eq(edgeEventActionType), Mockito.any()); Mockito.any(), Mockito.any(entityId.getClass()), Mockito.any(), Mockito.any(), Mockito.eq(edgeEventActionType), Mockito.any());
} }
private void testNotificationMsgToEdgeServiceNever(EntityId entityId) { private void testNotificationMsgToEdgeServiceNever(EntityId entityId) {
@ -353,7 +353,7 @@ public abstract class AbstractNotifyEntityTest extends AbstractWebTest {
private void testNotificationMsgToEdgeServiceTime(EntityId entityId, TenantId tenantId, ActionType actionType, int cntTime) { private void testNotificationMsgToEdgeServiceTime(EntityId entityId, TenantId tenantId, ActionType actionType, int cntTime) {
EdgeEventActionType edgeEventActionType = ActionType.CREDENTIALS_UPDATED.equals(actionType) ? EdgeEventActionType edgeEventActionType = ActionType.CREDENTIALS_UPDATED.equals(actionType) ?
EdgeEventActionType.CREDENTIALS_UPDATED : edgeTypeByActionType(actionType); EdgeEventActionType.CREDENTIALS_UPDATED : EdgeUtils.getEdgeEventActionTypeByActionType(actionType);
ArgumentMatcher<EntityId> matcherEntityId = cntTime == 1 ? argument -> argument.equals(entityId) : ArgumentMatcher<EntityId> matcherEntityId = cntTime == 1 ? argument -> argument.equals(entityId) :
argument -> argument.getClass().equals(entityId.getClass()); argument -> argument.getClass().equals(entityId.getClass());
Mockito.verify(tbClusterService, times(cntTime)).sendNotificationMsgToEdge(Mockito.eq(tenantId), Mockito.verify(tbClusterService, times(cntTime)).sendNotificationMsgToEdge(Mockito.eq(tenantId),
@ -364,7 +364,7 @@ public abstract class AbstractNotifyEntityTest extends AbstractWebTest {
private void testSendNotificationMsgToEdgeServiceTimeEntityEqAny(TenantId tenantId, ActionType actionType, int cntTime) { private void testSendNotificationMsgToEdgeServiceTimeEntityEqAny(TenantId tenantId, ActionType actionType, int cntTime) {
Mockito.verify(tbClusterService, times(cntTime)).sendNotificationMsgToEdge(Mockito.eq(tenantId), Mockito.verify(tbClusterService, times(cntTime)).sendNotificationMsgToEdge(Mockito.eq(tenantId),
Mockito.any(), Mockito.any(EntityId.class), Mockito.any(), Mockito.isNull(), Mockito.any(), Mockito.any(EntityId.class), Mockito.any(), Mockito.isNull(),
Mockito.eq(edgeTypeByActionType(actionType)), Mockito.any()); Mockito.eq(EdgeUtils.getEdgeEventActionTypeByActionType(actionType)), Mockito.any());
} }
protected void testBroadcastEntityStateChangeEventTime(EntityId entityId, TenantId tenantId, int cntTime) { protected void testBroadcastEntityStateChangeEventTime(EntityId entityId, TenantId tenantId, int cntTime) {

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

@ -157,9 +157,9 @@ public class EdgeControllerTest extends AbstractControllerTest {
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(), testNotifyEntityBroadcastEntityStateChangeEventManyTimeMsgToEdgeServiceNever(savedEdge, savedEdge.getId(), savedEdge.getId(),
tenantId, tenantAdminUser.getCustomerId(), tenantAdminUser.getId(), tenantAdminUser.getEmail(), tenantId, tenantAdminUser.getCustomerId(), tenantAdminUser.getId(), tenantAdminUser.getEmail(),
ActionType.ADDED); ActionType.ADDED, 2);
savedEdge.setName("My new edge"); savedEdge.setName("My new edge");
doPost("/api/edge", savedEdge, Edge.class); doPost("/api/edge", savedEdge, Edge.class);
@ -167,9 +167,9 @@ public class EdgeControllerTest extends AbstractControllerTest {
Edge foundEdge = doGet("/api/edge/" + savedEdge.getId().getId().toString(), Edge.class); Edge foundEdge = doGet("/api/edge/" + savedEdge.getId().getId().toString(), Edge.class);
Assert.assertEquals(foundEdge.getName(), savedEdge.getName()); Assert.assertEquals(foundEdge.getName(), savedEdge.getName());
testNotifyEntityBroadcastEntityStateChangeEventOneTimeMsgToEdgeServiceNever(foundEdge, foundEdge.getId(), foundEdge.getId(), testNotifyEntityBroadcastEntityStateChangeEventManyTimeMsgToEdgeServiceNever(foundEdge, foundEdge.getId(), foundEdge.getId(),
tenantId, tenantAdminUser.getCustomerId(), tenantAdminUser.getId(), tenantAdminUser.getEmail(), tenantId, tenantAdminUser.getCustomerId(), tenantAdminUser.getId(), tenantAdminUser.getEmail(),
ActionType.UPDATED); ActionType.UPDATED, 1);
} }
@Test @Test
@ -262,9 +262,9 @@ public class EdgeControllerTest extends AbstractControllerTest {
doDelete("/api/edge/" + savedEdge.getId().getId().toString()) doDelete("/api/edge/" + savedEdge.getId().getId().toString())
.andExpect(status().isOk()); .andExpect(status().isOk());
testNotifyEntityBroadcastEntityStateChangeEventOneTimeMsgToEdgeServiceNever(savedEdge, savedEdge.getId(), savedEdge.getId(), testNotifyEntityBroadcastEntityStateChangeEventManyTimeMsgToEdgeServiceNever(savedEdge, savedEdge.getId(), savedEdge.getId(),
tenantId, tenantAdminUser.getCustomerId(), tenantAdminUser.getId(), tenantAdminUser.getEmail(), tenantId, tenantAdminUser.getCustomerId(), tenantAdminUser.getId(), tenantAdminUser.getEmail(),
ActionType.DELETED, savedEdge.getId().getId().toString()); ActionType.DELETED, 1, savedEdge.getId().getId().toString());
doGet("/api/edge/" + savedEdge.getId().getId().toString()) doGet("/api/edge/" + savedEdge.getId().getId().toString())
.andExpect(status().isNotFound()) .andExpect(status().isNotFound())

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

@ -298,7 +298,7 @@ public class EntityViewControllerTest extends AbstractControllerTest {
EntityView foundView = doGet("/api/entityView/" + savedView.getId().getId().toString(), EntityView.class); EntityView foundView = doGet("/api/entityView/" + savedView.getId().getId().toString(), EntityView.class);
assertEquals(savedCustomer.getId(), foundView.getCustomerId()); assertEquals(savedCustomer.getId(), foundView.getCustomerId());
testBroadcastEntityStateChangeEventNever(foundView.getId()); testBroadcastEntityStateChangeEventTime(foundView.getId(), foundView.getTenantId(), 1);
testNotifyAssignUnassignEntityAllOneTime(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.UPDATED, ActionType.ASSIGNED_TO_CUSTOMER, ActionType.UPDATED,
@ -310,7 +310,7 @@ public class EntityViewControllerTest extends AbstractControllerTest {
foundView = doGet("/api/entityView/" + savedView.getId().getId().toString(), EntityView.class); foundView = doGet("/api/entityView/" + savedView.getId().getId().toString(), EntityView.class);
assertEquals(ModelConstants.NULL_UUID, foundView.getCustomerId().getId()); assertEquals(ModelConstants.NULL_UUID, foundView.getCustomerId().getId());
testBroadcastEntityStateChangeEventNever(foundView.getId()); testBroadcastEntityStateChangeEventTime(foundView.getId(), foundView.getTenantId(), 1);
testNotifyAssignUnassignEntityAllOneTime(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.UPDATED, ActionType.UNASSIGNED_FROM_CUSTOMER, ActionType.UPDATED,
@ -328,7 +328,7 @@ public class EntityViewControllerTest extends AbstractControllerTest {
Customer publicCustomer = doGet("/api/customer/" + assignedView.getCustomerId(), Customer.class); Customer publicCustomer = doGet("/api/customer/" + assignedView.getCustomerId(), Customer.class);
Assert.assertTrue(publicCustomer.isPublic()); Assert.assertTrue(publicCustomer.isPublic());
testBroadcastEntityStateChangeEventNever(assignedView.getId()); testBroadcastEntityStateChangeEventTime(assignedView.getId(), assignedView.getTenantId(), 1);
testNotifyAssignUnassignEntityAllOneTime(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.UPDATED, ActionType.ASSIGNED_TO_CUSTOMER, ActionType.UPDATED,
@ -343,7 +343,7 @@ public class EntityViewControllerTest extends AbstractControllerTest {
foundView = doGet("/api/entityView/" + savedView.getId().getId().toString(), EntityView.class); foundView = doGet("/api/entityView/" + savedView.getId().getId().toString(), EntityView.class);
assertEquals(ModelConstants.NULL_UUID, foundView.getCustomerId().getId()); assertEquals(ModelConstants.NULL_UUID, foundView.getCustomerId().getId());
testBroadcastEntityStateChangeEventNever(foundView.getId()); testBroadcastEntityStateChangeEventTime(assignedView.getId(), assignedView.getTenantId(), 1);
testNotifyAssignUnassignEntityAllOneTime(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.UPDATED, ActionType.UNASSIGNED_FROM_CUSTOMER, ActionType.UPDATED,
@ -462,7 +462,7 @@ public class EntityViewControllerTest extends AbstractControllerTest {
} }
Futures.allAsList(deleteFutures).get(TIMEOUT, SECONDS); Futures.allAsList(deleteFutures).get(TIMEOUT, SECONDS);
testBroadcastEntityStateChangeEventNever(loadedNamesOfView1.get(0).getId()); testBroadcastEntityStateChangeEventTime(loadedNamesOfView1.get(0).getId(), loadedNamesOfView1.get(0).getTenantId(), cntEntity);
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.UPDATED, cntEntity, cntEntity, 3); ActionType.UNASSIGNED_FROM_CUSTOMER, ActionType.UPDATED, cntEntity, cntEntity, 3);

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

@ -591,7 +591,6 @@ public class DeviceEdgeTest extends AbstractEdgeTest {
device.getId().getId(), EdgeEventType.DEVICE, body); device.getId().getId(), EdgeEventType.DEVICE, body);
edgeImitator.expectMessageAmount(1); edgeImitator.expectMessageAmount(1);
edgeEventService.saveAsync(edgeEvent).get(); edgeEventService.saveAsync(edgeEvent).get();
clusterService.onEdgeEventUpdate(tenantId, edge.getId());
Assert.assertTrue(edgeImitator.waitForMessages()); Assert.assertTrue(edgeImitator.waitForMessages());
AbstractMessage latestMessage = edgeImitator.getLatestMessage(); AbstractMessage latestMessage = edgeImitator.getLatestMessage();

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

@ -59,7 +59,6 @@ public class TelemetryEdgeTest extends AbstractEdgeTest {
EdgeEvent edgeEvent = constructEdgeEvent(tenantId, edge.getId(), EdgeEventActionType.TIMESERIES_UPDATED, EdgeEvent edgeEvent = constructEdgeEvent(tenantId, edge.getId(), EdgeEventActionType.TIMESERIES_UPDATED,
device.getId().getId(), EdgeEventType.DEVICE, timeseriesEntityData); device.getId().getId(), EdgeEventType.DEVICE, timeseriesEntityData);
edgeEventService.saveAsync(edgeEvent).get(); edgeEventService.saveAsync(edgeEvent).get();
clusterService.onEdgeEventUpdate(tenantId, edge.getId());
} }
Assert.assertTrue(edgeImitator.waitForMessages(120)); Assert.assertTrue(edgeImitator.waitForMessages(120));
@ -89,7 +88,6 @@ public class TelemetryEdgeTest extends AbstractEdgeTest {
EdgeEvent edgeEvent = constructEdgeEvent(tenantId, edge.getId(), EdgeEventActionType.POST_ATTRIBUTES, device.getId().getId(), EdgeEventType.DEVICE, postAttributesEntityData); EdgeEvent edgeEvent = constructEdgeEvent(tenantId, edge.getId(), EdgeEventActionType.POST_ATTRIBUTES, device.getId().getId(), EdgeEventType.DEVICE, postAttributesEntityData);
edgeImitator.expectMessageAmount(1); edgeImitator.expectMessageAmount(1);
edgeEventService.saveAsync(edgeEvent).get(); edgeEventService.saveAsync(edgeEvent).get();
clusterService.onEdgeEventUpdate(tenantId, edge.getId());
Assert.assertTrue(edgeImitator.waitForMessages()); Assert.assertTrue(edgeImitator.waitForMessages());
AbstractMessage latestMessage = edgeImitator.getLatestMessage(); AbstractMessage latestMessage = edgeImitator.getLatestMessage();
@ -114,7 +112,6 @@ public class TelemetryEdgeTest extends AbstractEdgeTest {
EdgeEvent edgeEvent = constructEdgeEvent(tenantId, edge.getId(), EdgeEventActionType.ATTRIBUTES_DELETED, device.getId().getId(), EdgeEventType.DEVICE, deleteAttributesEntityData); EdgeEvent edgeEvent = constructEdgeEvent(tenantId, edge.getId(), EdgeEventActionType.ATTRIBUTES_DELETED, device.getId().getId(), EdgeEventType.DEVICE, deleteAttributesEntityData);
edgeImitator.expectMessageAmount(1); edgeImitator.expectMessageAmount(1);
edgeEventService.saveAsync(edgeEvent).get(); edgeEventService.saveAsync(edgeEvent).get();
clusterService.onEdgeEventUpdate(tenantId, edge.getId());
Assert.assertTrue(edgeImitator.waitForMessages()); Assert.assertTrue(edgeImitator.waitForMessages());
AbstractMessage latestMessage = edgeImitator.getLatestMessage(); AbstractMessage latestMessage = edgeImitator.getLatestMessage();
@ -142,7 +139,6 @@ public class TelemetryEdgeTest extends AbstractEdgeTest {
edgeImitator.expectMessageAmount(1); edgeImitator.expectMessageAmount(1);
EdgeEvent edgeEvent = constructEdgeEvent(tenantId, edge.getId(), EdgeEventActionType.TIMESERIES_UPDATED, device.getId().getId(), EdgeEventType.DEVICE, timeseriesEntityData); EdgeEvent edgeEvent = constructEdgeEvent(tenantId, edge.getId(), EdgeEventActionType.TIMESERIES_UPDATED, device.getId().getId(), EdgeEventType.DEVICE, timeseriesEntityData);
edgeEventService.saveAsync(edgeEvent).get(); edgeEventService.saveAsync(edgeEvent).get();
clusterService.onEdgeEventUpdate(tenantId, edge.getId());
Assert.assertTrue(edgeImitator.waitForMessages()); Assert.assertTrue(edgeImitator.waitForMessages());
AbstractMessage latestMessage = edgeImitator.getLatestMessage(); AbstractMessage latestMessage = edgeImitator.getLatestMessage();
@ -198,8 +194,6 @@ public class TelemetryEdgeTest extends AbstractEdgeTest {
EdgeEvent successEdgeEvent = constructEdgeEvent(tenantId, edge.getId(), EdgeEventActionType.UPDATED, EdgeEvent successEdgeEvent = constructEdgeEvent(tenantId, edge.getId(), EdgeEventActionType.UPDATED,
device.getId().getId(), EdgeEventType.DEVICE, null); device.getId().getId(), EdgeEventType.DEVICE, null);
edgeEventService.saveAsync(successEdgeEvent).get(); edgeEventService.saveAsync(successEdgeEvent).get();
clusterService.onEdgeEventUpdate(tenantId, edge.getId());
} }
Assert.assertTrue(edgeImitator.waitForMessages(120)); Assert.assertTrue(edgeImitator.waitForMessages(120));
@ -224,7 +218,6 @@ public class TelemetryEdgeTest extends AbstractEdgeTest {
EdgeEvent edgeEvent1 = constructEdgeEvent(tenantId, edge.getId(), EdgeEventActionType.ATTRIBUTES_UPDATED, entityId.getId(), EdgeEventType.valueOf(entityId.getEntityType().name()), attributesEntityData); EdgeEvent edgeEvent1 = constructEdgeEvent(tenantId, edge.getId(), EdgeEventActionType.ATTRIBUTES_UPDATED, entityId.getId(), EdgeEventType.valueOf(entityId.getEntityType().name()), attributesEntityData);
edgeImitator.expectMessageAmount(1); edgeImitator.expectMessageAmount(1);
edgeEventService.saveAsync(edgeEvent1).get(); edgeEventService.saveAsync(edgeEvent1).get();
clusterService.onEdgeEventUpdate(tenantId, edge.getId());
Assert.assertTrue(edgeImitator.waitForMessages()); Assert.assertTrue(edgeImitator.waitForMessages());
AbstractMessage latestMessage = edgeImitator.getLatestMessage(); AbstractMessage latestMessage = edgeImitator.getLatestMessage();

4
application/src/test/java/org/thingsboard/server/service/edge/rpc/processor/BaseEdgeProcessorTest.java

@ -132,7 +132,7 @@ import org.thingsboard.server.service.edge.rpc.processor.relation.RelationEdgePr
import org.thingsboard.server.service.edge.rpc.processor.resource.ResourceEdgeProcessorFactory; import org.thingsboard.server.service.edge.rpc.processor.resource.ResourceEdgeProcessorFactory;
import org.thingsboard.server.service.edge.rpc.processor.resource.ResourceEdgeProcessorV1; import org.thingsboard.server.service.edge.rpc.processor.resource.ResourceEdgeProcessorV1;
import org.thingsboard.server.service.edge.rpc.processor.resource.ResourceEdgeProcessorV2; import org.thingsboard.server.service.edge.rpc.processor.resource.ResourceEdgeProcessorV2;
import org.thingsboard.server.service.entitiy.TbNotificationEntityService; import org.thingsboard.server.service.entitiy.TbLogEntityActionService;
import org.thingsboard.server.service.executors.DbCallbackExecutorService; import org.thingsboard.server.service.executors.DbCallbackExecutorService;
import org.thingsboard.server.service.profile.TbAssetProfileCache; import org.thingsboard.server.service.profile.TbAssetProfileCache;
import org.thingsboard.server.service.profile.TbDeviceProfileCache; import org.thingsboard.server.service.profile.TbDeviceProfileCache;
@ -148,7 +148,7 @@ public abstract class BaseEdgeProcessorTest {
protected TelemetrySubscriptionService tsSubService; protected TelemetrySubscriptionService tsSubService;
@MockBean @MockBean
protected TbNotificationEntityService notificationEntityService; protected TbLogEntityActionService logEntityActionService;
@MockBean @MockBean
protected RuleChainService ruleChainService; protected RuleChainService ruleChainService;

12
application/src/test/java/org/thingsboard/server/service/entitiy/alarm/DefaultTbAlarmServiceTest.java

@ -41,7 +41,7 @@ import org.thingsboard.server.common.data.page.PageData;
import org.thingsboard.server.dao.alarm.AlarmService; import org.thingsboard.server.dao.alarm.AlarmService;
import org.thingsboard.server.dao.customer.CustomerService; import org.thingsboard.server.dao.customer.CustomerService;
import org.thingsboard.server.dao.edge.EdgeService; import org.thingsboard.server.dao.edge.EdgeService;
import org.thingsboard.server.service.entitiy.TbNotificationEntityService; import org.thingsboard.server.service.entitiy.TbLogEntityActionService;
import org.thingsboard.server.service.executors.DbCallbackExecutorService; import org.thingsboard.server.service.executors.DbCallbackExecutorService;
import org.thingsboard.server.service.sync.vc.EntitiesVersionControlService; import org.thingsboard.server.service.sync.vc.EntitiesVersionControlService;
import org.thingsboard.server.service.telemetry.AlarmSubscriptionService; import org.thingsboard.server.service.telemetry.AlarmSubscriptionService;
@ -68,7 +68,7 @@ public class DefaultTbAlarmServiceTest {
@MockBean @MockBean
protected DbCallbackExecutorService dbExecutor; protected DbCallbackExecutorService dbExecutor;
@MockBean @MockBean
protected TbNotificationEntityService notificationEntityService; protected TbLogEntityActionService logEntityActionService;
@MockBean @MockBean
protected EdgeService edgeService; protected EdgeService edgeService;
@MockBean @MockBean
@ -96,7 +96,7 @@ public class DefaultTbAlarmServiceTest {
.build()); .build());
service.save(alarm, new User()); service.save(alarm, new User());
verify(notificationEntityService, times(1)).logEntityAction(any(), any(), any(), any(), eq(ActionType.ADDED), any()); verify(logEntityActionService, times(1)).logEntityAction(any(), any(), any(), any(), eq(ActionType.ADDED), any());
verify(alarmSubscriptionService, times(1)).createAlarm(any()); verify(alarmSubscriptionService, times(1)).createAlarm(any());
} }
@ -108,7 +108,7 @@ public class DefaultTbAlarmServiceTest {
service.ack(alarm, new User(new UserId(UUID.randomUUID()))); service.ack(alarm, new User(new UserId(UUID.randomUUID())));
verify(alarmCommentService, times(1)).saveAlarmComment(any(), any(), any()); verify(alarmCommentService, times(1)).saveAlarmComment(any(), any(), any());
verify(notificationEntityService, times(1)).logEntityAction(any(), any(), any(), any(), eq(ActionType.ALARM_ACK), any()); verify(logEntityActionService, times(1)).logEntityAction(any(), any(), any(), any(), eq(ActionType.ALARM_ACK), any());
verify(alarmSubscriptionService, times(1)).acknowledgeAlarm(any(), any(), anyLong()); verify(alarmSubscriptionService, times(1)).acknowledgeAlarm(any(), any(), anyLong());
} }
@ -121,7 +121,7 @@ public class DefaultTbAlarmServiceTest {
service.clear(alarm, new User(new UserId(UUID.randomUUID()))); service.clear(alarm, new User(new UserId(UUID.randomUUID())));
verify(alarmCommentService, times(1)).saveAlarmComment(any(), any(), any()); verify(alarmCommentService, times(1)).saveAlarmComment(any(), any(), any());
verify(notificationEntityService, times(1)).logEntityAction(any(), any(), any(), any(), eq(ActionType.ALARM_CLEAR), any()); verify(logEntityActionService, times(1)).logEntityAction(any(), any(), any(), any(), eq(ActionType.ALARM_CLEAR), any());
verify(alarmSubscriptionService, times(1)).clearAlarm(any(), any(), anyLong(), any()); verify(alarmSubscriptionService, times(1)).clearAlarm(any(), any(), anyLong(), any());
} }
@ -129,7 +129,7 @@ public class DefaultTbAlarmServiceTest {
public void testDelete() { public void testDelete() {
service.delete(new Alarm(), new User()); service.delete(new Alarm(), new User());
verify(notificationEntityService, times(1)).logEntityAction(any(), any(), any(), any(), eq(ActionType.DELETED), any()); verify(logEntityActionService, times(1)).logEntityAction(any(), any(), any(), any(), eq(ActionType.DELETED), any());
verify(alarmSubscriptionService, times(1)).deleteAlarm(any(), any()); verify(alarmSubscriptionService, times(1)).deleteAlarm(any(), any());
} }

8
application/src/test/java/org/thingsboard/server/service/entitiy/alarmComment/DefaultTbAlarmCommentServiceTest.java

@ -36,7 +36,7 @@ import org.thingsboard.server.common.data.id.UserId;
import org.thingsboard.server.dao.alarm.AlarmCommentService; import org.thingsboard.server.dao.alarm.AlarmCommentService;
import org.thingsboard.server.dao.alarm.AlarmService; import org.thingsboard.server.dao.alarm.AlarmService;
import org.thingsboard.server.dao.customer.CustomerService; import org.thingsboard.server.dao.customer.CustomerService;
import org.thingsboard.server.service.entitiy.TbNotificationEntityService; import org.thingsboard.server.service.entitiy.TbLogEntityActionService;
import org.thingsboard.server.service.entitiy.alarm.DefaultTbAlarmCommentService; import org.thingsboard.server.service.entitiy.alarm.DefaultTbAlarmCommentService;
import org.thingsboard.server.service.executors.DbCallbackExecutorService; import org.thingsboard.server.service.executors.DbCallbackExecutorService;
import org.thingsboard.server.service.telemetry.AlarmSubscriptionService; import org.thingsboard.server.service.telemetry.AlarmSubscriptionService;
@ -61,7 +61,7 @@ public class DefaultTbAlarmCommentServiceTest {
@MockBean @MockBean
protected DbCallbackExecutorService dbExecutor; protected DbCallbackExecutorService dbExecutor;
@MockBean @MockBean
protected TbNotificationEntityService notificationEntityService; protected TbLogEntityActionService logEntityActionService;
@MockBean @MockBean
protected AlarmService alarmService; protected AlarmService alarmService;
@MockBean @MockBean
@ -82,7 +82,7 @@ public class DefaultTbAlarmCommentServiceTest {
when(alarmCommentService.createOrUpdateAlarmComment(Mockito.any(), eq(alarmComment))).thenReturn(alarmComment); when(alarmCommentService.createOrUpdateAlarmComment(Mockito.any(), eq(alarmComment))).thenReturn(alarmComment);
service.saveAlarmComment(alarm, alarmComment, new User()); service.saveAlarmComment(alarm, alarmComment, new User());
verify(notificationEntityService, times(1)).logEntityAction(any(), any(), any(), any(), eq(ActionType.ADDED_COMMENT), any(), any()); verify(logEntityActionService, times(1)).logEntityAction(any(), any(), any(), any(), eq(ActionType.ADDED_COMMENT), any(), any());
} }
@Test @Test
@ -96,7 +96,7 @@ public class DefaultTbAlarmCommentServiceTest {
when(alarmCommentService.saveAlarmComment(Mockito.any(), eq(alarmComment))).thenReturn(alarmComment); when(alarmCommentService.saveAlarmComment(Mockito.any(), eq(alarmComment))).thenReturn(alarmComment);
service.deleteAlarmComment(new Alarm(alarmId), alarmComment, new User()); service.deleteAlarmComment(new Alarm(alarmId), alarmComment, new User());
verify(notificationEntityService, times(1)).logEntityAction(any(), any(), any(), any(), eq(ActionType.DELETED_COMMENT), any(), any()); verify(logEntityActionService, times(1)).logEntityAction(any(), any(), any(), any(), eq(ActionType.DELETED_COMMENT), any(), any());
} }
@Test @Test

3
application/src/test/java/org/thingsboard/server/service/sync/ie/ExportImportServiceSqlTest.java

@ -630,8 +630,7 @@ public class ExportImportServiceSqlTest extends BaseExportImportServiceTest {
DeviceProfile importedDeviceProfile = (DeviceProfile) importEntity(tenantAdmin2, getAndClone(entitiesExportData, EntityType.DEVICE_PROFILE)).getSavedEntity(); DeviceProfile importedDeviceProfile = (DeviceProfile) importEntity(tenantAdmin2, getAndClone(entitiesExportData, EntityType.DEVICE_PROFILE)).getSavedEntity();
verify(entityActionService).logEntityAction(any(), eq(importedDeviceProfile.getId()), eq(importedDeviceProfile), verify(entityActionService).logEntityAction(any(), eq(importedDeviceProfile.getId()), eq(importedDeviceProfile),
any(), eq(ActionType.ADDED), isNull()); any(), eq(ActionType.ADDED), isNull());
verify(tbClusterService).onDeviceProfileChange(eq(importedDeviceProfile), any()); verify(tbClusterService).onDeviceProfileChange(eq(importedDeviceProfile), any(), any());
verify(tbClusterService).broadcastEntityStateChangeEvent(any(), eq(importedDeviceProfile.getId()), eq(ComponentLifecycleEvent.CREATED));
verify(tbClusterService).sendNotificationMsgToEdge(any(), any(), eq(importedDeviceProfile.getId()), any(), any(), eq(EdgeEventActionType.ADDED), any()); verify(tbClusterService).sendNotificationMsgToEdge(any(), any(), eq(importedDeviceProfile.getId()), any(), any(), eq(EdgeEventActionType.ADDED), any());
verify(otaPackageStateService).update(eq(importedDeviceProfile), eq(false), eq(false)); verify(otaPackageStateService).update(eq(importedDeviceProfile), eq(false), eq(false));

7
common/cluster-api/src/main/java/org/thingsboard/server/cluster/TbClusterService.java

@ -19,6 +19,7 @@ import org.thingsboard.server.common.data.ApiUsageState;
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.TbResource; import org.thingsboard.server.common.data.TbResource;
import org.thingsboard.server.common.data.TbResourceInfo;
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.edge.EdgeEventActionType; import org.thingsboard.server.common.data.edge.EdgeEventActionType;
@ -67,7 +68,7 @@ public interface TbClusterService extends TbQueueClusterService {
void broadcastEntityStateChangeEvent(TenantId tenantId, EntityId entityId, ComponentLifecycleEvent state); void broadcastEntityStateChangeEvent(TenantId tenantId, EntityId entityId, ComponentLifecycleEvent state);
void onDeviceProfileChange(DeviceProfile deviceProfile, TbQueueCallback callback); void onDeviceProfileChange(DeviceProfile deviceProfile, DeviceProfile oldDeviceProfile, TbQueueCallback callback);
void onDeviceProfileDelete(DeviceProfile deviceProfile, TbQueueCallback callback); void onDeviceProfileDelete(DeviceProfile deviceProfile, TbQueueCallback callback);
@ -87,9 +88,9 @@ public interface TbClusterService extends TbQueueClusterService {
void onDeviceAssignedToTenant(TenantId oldTenantId, Device device); void onDeviceAssignedToTenant(TenantId oldTenantId, Device device);
void onResourceChange(TbResource resource, TbQueueCallback callback); void onResourceChange(TbResourceInfo resource, TbQueueCallback callback);
void onResourceDeleted(TbResource resource, TbQueueCallback callback); void onResourceDeleted(TbResourceInfo resource, TbQueueCallback callback);
void onEdgeEventUpdate(TenantId tenantId, EdgeId edgeId); void onEdgeEventUpdate(TenantId tenantId, EdgeId edgeId);

1
common/cluster-api/src/main/java/org/thingsboard/server/queue/TbQueueClusterService.java

@ -18,6 +18,7 @@ package org.thingsboard.server.queue;
import org.thingsboard.server.common.data.queue.Queue; import org.thingsboard.server.common.data.queue.Queue;
public interface TbQueueClusterService { public interface TbQueueClusterService {
void onQueueChange(Queue queue); void onQueueChange(Queue queue);
void onQueueDelete(Queue queue); void onQueueDelete(Queue queue);

4
common/dao-api/src/main/java/org/thingsboard/server/dao/asset/AssetProfileService.java

@ -38,10 +38,10 @@ public interface AssetProfileService extends EntityDaoService {
AssetProfileInfo findAssetProfileInfoById(TenantId tenantId, AssetProfileId assetProfileId); AssetProfileInfo findAssetProfileInfoById(TenantId tenantId, AssetProfileId assetProfileId);
AssetProfile saveAssetProfile(AssetProfile assetProfile, boolean doValidate);
AssetProfile saveAssetProfile(AssetProfile assetProfile); AssetProfile saveAssetProfile(AssetProfile assetProfile);
AssetProfile saveAssetProfile(AssetProfile assetProfile, boolean doValidate, boolean publishSaveEvent);
void deleteAssetProfile(TenantId tenantId, AssetProfileId assetProfileId); void deleteAssetProfile(TenantId tenantId, AssetProfileId assetProfileId);
PageData<AssetProfile> findAssetProfiles(TenantId tenantId, PageLink pageLink); PageData<AssetProfile> findAssetProfiles(TenantId tenantId, PageLink pageLink);

4
common/dao-api/src/main/java/org/thingsboard/server/dao/device/DeviceProfileService.java

@ -38,10 +38,10 @@ public interface DeviceProfileService extends EntityDaoService {
DeviceProfileInfo findDeviceProfileInfoById(TenantId tenantId, DeviceProfileId deviceProfileId); DeviceProfileInfo findDeviceProfileInfoById(TenantId tenantId, DeviceProfileId deviceProfileId);
DeviceProfile saveDeviceProfile(DeviceProfile deviceProfile, boolean doValidate);
DeviceProfile saveDeviceProfile(DeviceProfile deviceProfile); DeviceProfile saveDeviceProfile(DeviceProfile deviceProfile);
DeviceProfile saveDeviceProfile(DeviceProfile deviceProfile, boolean doValidate, boolean publishSaveEvent);
void deleteDeviceProfile(TenantId tenantId, DeviceProfileId deviceProfileId); void deleteDeviceProfile(TenantId tenantId, DeviceProfileId deviceProfileId);
PageData<DeviceProfile> findDeviceProfiles(TenantId tenantId, PageLink pageLink); PageData<DeviceProfile> findDeviceProfiles(TenantId tenantId, PageLink pageLink);

4
common/dao-api/src/main/java/org/thingsboard/server/dao/device/DeviceService.java

@ -49,10 +49,10 @@ public interface DeviceService extends EntityDaoService {
Device findDeviceByTenantIdAndName(TenantId tenantId, String name); Device findDeviceByTenantIdAndName(TenantId tenantId, String name);
Device saveDevice(Device device, boolean doValidate);
Device saveDevice(Device device); Device saveDevice(Device device);
Device saveDevice(Device device, boolean doValidate);
Device saveDeviceWithAccessToken(Device device, String accessToken); Device saveDeviceWithAccessToken(Device device, String accessToken);
Device saveDeviceWithCredentials(Device device, DeviceCredentials deviceCredentials); Device saveDeviceWithCredentials(Device device, DeviceCredentials deviceCredentials);

2
common/dao-api/src/main/java/org/thingsboard/server/dao/notification/NotificationRequestService.java

@ -45,7 +45,7 @@ public interface NotificationRequestService {
List<NotificationRequest> findNotificationRequestsByRuleIdAndOriginatorEntityId(TenantId tenantId, NotificationRuleId ruleId, EntityId originatorEntityId); List<NotificationRequest> findNotificationRequestsByRuleIdAndOriginatorEntityId(TenantId tenantId, NotificationRuleId ruleId, EntityId originatorEntityId);
void deleteNotificationRequest(TenantId tenantId, NotificationRequestId requestId); void deleteNotificationRequest(TenantId tenantId, NotificationRequest request);
PageData<NotificationRequest> findScheduledNotificationRequests(PageLink pageLink); PageData<NotificationRequest> findScheduledNotificationRequests(PageLink pageLink);

4
common/dao-api/src/main/java/org/thingsboard/server/dao/rule/RuleChainService.java

@ -44,10 +44,14 @@ public interface RuleChainService extends EntityDaoService {
RuleChain saveRuleChain(RuleChain ruleChain); RuleChain saveRuleChain(RuleChain ruleChain);
RuleChain saveRuleChain(RuleChain ruleChain, boolean publishSaveEvent);
boolean setRootRuleChain(TenantId tenantId, RuleChainId ruleChainId); boolean setRootRuleChain(TenantId tenantId, RuleChainId ruleChainId);
RuleChainUpdateResult saveRuleChainMetaData(TenantId tenantId, RuleChainMetaData ruleChainMetaData, Function<RuleNode, RuleNode> ruleNodeUpdater); RuleChainUpdateResult saveRuleChainMetaData(TenantId tenantId, RuleChainMetaData ruleChainMetaData, Function<RuleNode, RuleNode> ruleNodeUpdater);
RuleChainUpdateResult saveRuleChainMetaData(TenantId tenantId, RuleChainMetaData ruleChainMetaData, Function<RuleNode, RuleNode> ruleNodeUpdater, boolean publishSaveEvent);
RuleChainMetaData loadRuleChainMetaData(TenantId tenantId, RuleChainId ruleChainId); RuleChainMetaData loadRuleChainMetaData(TenantId tenantId, RuleChainId ruleChainId);
RuleChain findRuleChainById(TenantId tenantId, RuleChainId ruleChainId); RuleChain findRuleChainById(TenantId tenantId, RuleChainId ruleChainId);

2
common/dao-api/src/main/java/org/thingsboard/server/dao/tenant/TenantService.java

@ -36,6 +36,8 @@ public interface TenantService extends EntityDaoService {
Tenant saveTenant(Tenant tenant); Tenant saveTenant(Tenant tenant);
Tenant saveTenant(Tenant tenant, boolean publishSaveEvent);
boolean tenantExists(TenantId tenantId); boolean tenantExists(TenantId tenantId);
void deleteTenant(TenantId tenantId); void deleteTenant(TenantId tenantId);

13
common/data/src/main/java/org/thingsboard/server/common/data/EdgeUtils.java

@ -18,6 +18,7 @@ package org.thingsboard.server.common.data;
import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.JsonNode;
import com.google.common.base.Throwables; import com.google.common.base.Throwables;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.thingsboard.server.common.data.audit.ActionType;
import org.thingsboard.server.common.data.edge.EdgeEvent; import org.thingsboard.server.common.data.edge.EdgeEvent;
import org.thingsboard.server.common.data.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;
@ -32,6 +33,7 @@ import java.util.concurrent.ThreadLocalRandom;
public final class EdgeUtils { public final class EdgeUtils {
private static final EnumMap<EntityType, EdgeEventType> entityTypeEdgeEventTypeEnumMap; private static final EnumMap<EntityType, EdgeEventType> entityTypeEdgeEventTypeEnumMap;
private static final EnumMap<ActionType, EdgeEventActionType> actionTypeEdgeEventActionTypeEnumMap;
static { static {
entityTypeEdgeEventTypeEnumMap = new EnumMap<>(EntityType.class); entityTypeEdgeEventTypeEnumMap = new EnumMap<>(EntityType.class);
@ -40,6 +42,13 @@ public final class EdgeUtils {
entityTypeEdgeEventTypeEnumMap.put(edgeEventType.getEntityType(), edgeEventType); entityTypeEdgeEventTypeEnumMap.put(edgeEventType.getEntityType(), edgeEventType);
} }
} }
actionTypeEdgeEventActionTypeEnumMap = new EnumMap<>(ActionType.class);
for (EdgeEventActionType edgeEventActionType : EdgeEventActionType.values()) {
if (edgeEventActionType.getActionType() != null) {
actionTypeEdgeEventActionTypeEnumMap.put(edgeEventActionType.getActionType(), edgeEventActionType);
}
}
} }
private static final int STACK_TRACE_LIMIT = 10; private static final int STACK_TRACE_LIMIT = 10;
@ -54,6 +63,10 @@ public final class EdgeUtils {
return entityTypeEdgeEventTypeEnumMap.get(entityType); return entityTypeEdgeEventTypeEnumMap.get(entityType);
} }
public static EdgeEventActionType getEdgeEventActionTypeByActionType(ActionType actionType) {
return actionTypeEdgeEventActionTypeEnumMap.get(actionType);
}
public static EdgeEvent constructEdgeEvent(TenantId tenantId, public static EdgeEvent constructEdgeEvent(TenantId tenantId,
EdgeId edgeId, EdgeId edgeId,
EdgeEventType type, EdgeEventType type,

54
common/data/src/main/java/org/thingsboard/server/common/data/edge/EdgeEventActionType.java

@ -15,26 +15,36 @@
*/ */
package org.thingsboard.server.common.data.edge; package org.thingsboard.server.common.data.edge;
import lombok.Getter;
import org.thingsboard.server.common.data.audit.ActionType;
@Getter
public enum EdgeEventActionType { public enum EdgeEventActionType {
ADDED, ADDED(ActionType.ADDED),
DELETED, UPDATED(ActionType.UPDATED),
UPDATED, DELETED(ActionType.DELETED),
POST_ATTRIBUTES, POST_ATTRIBUTES(null),
ATTRIBUTES_UPDATED, ATTRIBUTES_UPDATED(ActionType.ATTRIBUTES_UPDATED),
ATTRIBUTES_DELETED, ATTRIBUTES_DELETED(ActionType.ATTRIBUTES_DELETED),
TIMESERIES_UPDATED, TIMESERIES_UPDATED(ActionType.TIMESERIES_UPDATED),
CREDENTIALS_UPDATED, CREDENTIALS_UPDATED(ActionType.CREDENTIALS_UPDATED),
ASSIGNED_TO_CUSTOMER, ASSIGNED_TO_CUSTOMER(ActionType.ASSIGNED_TO_CUSTOMER),
UNASSIGNED_FROM_CUSTOMER, UNASSIGNED_FROM_CUSTOMER(ActionType.UNASSIGNED_FROM_CUSTOMER),
RELATION_ADD_OR_UPDATE, RELATION_ADD_OR_UPDATE(ActionType.RELATION_ADD_OR_UPDATE),
RELATION_DELETED, RELATION_DELETED(ActionType.RELATION_DELETED),
RPC_CALL, RPC_CALL(ActionType.RPC_CALL),
ALARM_ACK, ALARM_ACK(ActionType.ALARM_ACK),
ALARM_CLEAR, ALARM_CLEAR(ActionType.ALARM_CLEAR),
ALARM_ASSIGNED, ALARM_ASSIGNED(ActionType.ALARM_ASSIGNED),
ALARM_UNASSIGNED, ALARM_UNASSIGNED(ActionType.ALARM_UNASSIGNED),
ASSIGNED_TO_EDGE, ASSIGNED_TO_EDGE(ActionType.ASSIGNED_TO_EDGE),
UNASSIGNED_FROM_EDGE, UNASSIGNED_FROM_EDGE(ActionType.UNASSIGNED_FROM_EDGE),
CREDENTIALS_REQUEST, CREDENTIALS_REQUEST(null),
ENTITY_MERGE_REQUEST // deprecated ENTITY_MERGE_REQUEST(null); // deprecated
}
private final ActionType actionType;
EdgeEventActionType(ActionType actionType) {
this.actionType = actionType;
}
}

24
dao/src/main/java/org/thingsboard/server/dao/asset/AssetProfileServiceImpl.java

@ -128,17 +128,13 @@ public class AssetProfileServiceImpl extends AbstractCachedEntityService<AssetPr
return toAssetProfileInfo(findAssetProfileById(tenantId, assetProfileId)); return toAssetProfileInfo(findAssetProfileById(tenantId, assetProfileId));
} }
@Override
public AssetProfile saveAssetProfile(AssetProfile assetProfile, boolean doValidate) {
return doSaveAssetProfile(assetProfile, doValidate);
}
@Override @Override
public AssetProfile saveAssetProfile(AssetProfile assetProfile) { public AssetProfile saveAssetProfile(AssetProfile assetProfile) {
return doSaveAssetProfile(assetProfile, true); return saveAssetProfile(assetProfile, true, true);
} }
private AssetProfile doSaveAssetProfile(AssetProfile assetProfile, boolean doValidate) { @Override
public AssetProfile saveAssetProfile(AssetProfile assetProfile, boolean doValidate, boolean publishSaveEvent) {
log.trace("Executing saveAssetProfile [{}]", assetProfile); log.trace("Executing saveAssetProfile [{}]", assetProfile);
AssetProfile oldAssetProfile = null; AssetProfile oldAssetProfile = null;
if (doValidate) { if (doValidate) {
@ -152,8 +148,10 @@ public class AssetProfileServiceImpl extends AbstractCachedEntityService<AssetPr
savedAssetProfile = assetProfileDao.saveAndFlush(assetProfile.getTenantId(), assetProfile); savedAssetProfile = assetProfileDao.saveAndFlush(assetProfile.getTenantId(), assetProfile);
publishEvictEvent(new AssetProfileEvictEvent(savedAssetProfile.getTenantId(), savedAssetProfile.getName(), publishEvictEvent(new AssetProfileEvictEvent(savedAssetProfile.getTenantId(), savedAssetProfile.getName(),
oldAssetProfile != null ? oldAssetProfile.getName() : null, savedAssetProfile.getId(), savedAssetProfile.isDefault())); oldAssetProfile != null ? oldAssetProfile.getName() : null, savedAssetProfile.getId(), savedAssetProfile.isDefault()));
eventPublisher.publishEvent(SaveEntityEvent.builder().tenantId(savedAssetProfile.getTenantId()).entityId(savedAssetProfile.getId()) if (publishSaveEvent) {
.added(oldAssetProfile == null).build()); eventPublisher.publishEvent(SaveEntityEvent.builder().tenantId(savedAssetProfile.getTenantId()).entity(savedAssetProfile)
.entityId(savedAssetProfile.getId()).added(oldAssetProfile == null).build());
}
} catch (Exception t) { } catch (Exception t) {
handleEvictEvent(new AssetProfileEvictEvent(assetProfile.getTenantId(), assetProfile.getName(), handleEvictEvent(new AssetProfileEvictEvent(assetProfile.getTenantId(), assetProfile.getName(),
oldAssetProfile != null ? oldAssetProfile.getName() : null, null, assetProfile.isDefault())); oldAssetProfile != null ? oldAssetProfile.getName() : null, null, assetProfile.isDefault()));
@ -229,7 +227,7 @@ public class AssetProfileServiceImpl extends AbstractCachedEntityService<AssetPr
AssetProfile assetProfile = findAssetProfileByName(tenantId, name, false); AssetProfile assetProfile = findAssetProfileByName(tenantId, name, false);
if (assetProfile == null) { if (assetProfile == null) {
try { try {
assetProfile = this.doCreateDefaultAssetProfile(tenantId, name, name.equals("default")); assetProfile = this.doCreateDefaultAssetProfile(tenantId, name, name.equals("default"), true);
} catch (DataValidationException e) { } catch (DataValidationException e) {
if (ASSET_PROFILE_WITH_SUCH_NAME_ALREADY_EXISTS.equals(e.getMessage())) { if (ASSET_PROFILE_WITH_SUCH_NAME_ALREADY_EXISTS.equals(e.getMessage())) {
assetProfile = findAssetProfileByName(tenantId, name, false); assetProfile = findAssetProfileByName(tenantId, name, false);
@ -244,17 +242,17 @@ public class AssetProfileServiceImpl extends AbstractCachedEntityService<AssetPr
@Override @Override
public AssetProfile createDefaultAssetProfile(TenantId tenantId) { public AssetProfile createDefaultAssetProfile(TenantId tenantId) {
log.trace("Executing createDefaultAssetProfile tenantId [{}]", tenantId); log.trace("Executing createDefaultAssetProfile tenantId [{}]", tenantId);
return doCreateDefaultAssetProfile(tenantId, "default", true); return doCreateDefaultAssetProfile(tenantId, "default", true, false);
} }
private AssetProfile doCreateDefaultAssetProfile(TenantId tenantId, String profileName, boolean defaultProfile) { private AssetProfile doCreateDefaultAssetProfile(TenantId tenantId, String profileName, boolean defaultProfile, boolean publishSaveEvent) {
validateId(tenantId, INCORRECT_TENANT_ID + tenantId); validateId(tenantId, INCORRECT_TENANT_ID + tenantId);
AssetProfile assetProfile = new AssetProfile(); AssetProfile assetProfile = new AssetProfile();
assetProfile.setTenantId(tenantId); assetProfile.setTenantId(tenantId);
assetProfile.setDefault(defaultProfile); assetProfile.setDefault(defaultProfile);
assetProfile.setName(profileName); assetProfile.setName(profileName);
assetProfile.setDescription("Default asset profile"); assetProfile.setDescription("Default asset profile");
return saveAssetProfile(assetProfile); return saveAssetProfile(assetProfile, true, publishSaveEvent);
} }
@Override @Override

10
dao/src/main/java/org/thingsboard/server/dao/asset/BaseAssetService.java

@ -130,17 +130,13 @@ public class BaseAssetService extends AbstractCachedEntityService<AssetCacheKey,
.orElse(null), true); .orElse(null), true);
} }
@Override
public Asset saveAsset(Asset asset, boolean doValidate) {
return doSaveAsset(asset, doValidate);
}
@Override @Override
public Asset saveAsset(Asset asset) { public Asset saveAsset(Asset asset) {
return doSaveAsset(asset, true); return saveAsset(asset, true);
} }
private Asset doSaveAsset(Asset asset, boolean doValidate) { @Override
public Asset saveAsset(Asset asset, boolean doValidate) {
log.trace("Executing saveAsset [{}]", asset); log.trace("Executing saveAsset [{}]", asset);
Asset oldAsset = null; Asset oldAsset = null;
if (doValidate) { if (doValidate) {

10
dao/src/main/java/org/thingsboard/server/dao/dashboard/DashboardServiceImpl.java

@ -141,17 +141,13 @@ public class DashboardServiceImpl extends AbstractEntityService implements Dashb
return dashboardInfoDao.findByIdAsync(tenantId, dashboardId.getId()); return dashboardInfoDao.findByIdAsync(tenantId, dashboardId.getId());
} }
@Override
public Dashboard saveDashboard(Dashboard dashboard, boolean doValidate) {
return doSaveDashboard(dashboard, doValidate);
}
@Override @Override
public Dashboard saveDashboard(Dashboard dashboard) { public Dashboard saveDashboard(Dashboard dashboard) {
return doSaveDashboard(dashboard, true); return saveDashboard(dashboard, true);
} }
private Dashboard doSaveDashboard(Dashboard dashboard, boolean doValidate) { @Override
public Dashboard saveDashboard(Dashboard dashboard, boolean doValidate) {
log.trace("Executing saveDashboard [{}]", dashboard); log.trace("Executing saveDashboard [{}]", dashboard);
if (doValidate) { if (doValidate) {
dashboardValidator.validate(dashboard, DashboardInfo::getTenantId); dashboardValidator.validate(dashboard, DashboardInfo::getTenantId);

2
dao/src/main/java/org/thingsboard/server/dao/device/DeviceCredentialsServiceImpl.java

@ -110,7 +110,7 @@ public class DeviceCredentialsServiceImpl extends AbstractCachedEntityService<St
var value = deviceCredentialsDao.saveAndFlush(tenantId, deviceCredentials); var value = deviceCredentialsDao.saveAndFlush(tenantId, deviceCredentials);
publishEvictEvent(new DeviceCredentialsEvictEvent(value.getCredentialsId(), oldDeviceCredentials != null ? oldDeviceCredentials.getCredentialsId() : null)); publishEvictEvent(new DeviceCredentialsEvictEvent(value.getCredentialsId(), oldDeviceCredentials != null ? oldDeviceCredentials.getCredentialsId() : null));
if (oldDeviceCredentials != null) { if (oldDeviceCredentials != null) {
eventPublisher.publishEvent(ActionEntityEvent.builder().tenantId(tenantId).entityId(value.getDeviceId()).actionType(ActionType.CREDENTIALS_UPDATED).build()); eventPublisher.publishEvent(ActionEntityEvent.builder().tenantId(tenantId).entity(value).entityId(value.getDeviceId()).actionType(ActionType.CREDENTIALS_UPDATED).build());
} }
return value; return value;
} catch (Exception t) { } catch (Exception t) {

26
dao/src/main/java/org/thingsboard/server/dao/device/DeviceProfileServiceImpl.java

@ -159,17 +159,13 @@ public class DeviceProfileServiceImpl extends AbstractCachedEntityService<Device
return toDeviceProfileInfo(findDeviceProfileById(tenantId, deviceProfileId)); return toDeviceProfileInfo(findDeviceProfileById(tenantId, deviceProfileId));
} }
@Override
public DeviceProfile saveDeviceProfile(DeviceProfile deviceProfile, boolean doValidate) {
return doSaveDeviceProfile(deviceProfile, doValidate);
}
@Override @Override
public DeviceProfile saveDeviceProfile(DeviceProfile deviceProfile) { public DeviceProfile saveDeviceProfile(DeviceProfile deviceProfile) {
return doSaveDeviceProfile(deviceProfile, true); return saveDeviceProfile(deviceProfile, true, true);
} }
private DeviceProfile doSaveDeviceProfile(DeviceProfile deviceProfile, boolean doValidate) { @Override
public DeviceProfile saveDeviceProfile(DeviceProfile deviceProfile, boolean doValidate, boolean publishSaveEvent) {
log.trace("Executing saveDeviceProfile [{}]", deviceProfile); log.trace("Executing saveDeviceProfile [{}]", deviceProfile);
if (deviceProfile.getProfileData() != null && deviceProfile.getProfileData().getProvisionConfiguration() instanceof X509CertificateChainProvisionConfiguration) { if (deviceProfile.getProfileData() != null && deviceProfile.getProfileData().getProvisionConfiguration() instanceof X509CertificateChainProvisionConfiguration) {
X509CertificateChainProvisionConfiguration x509Configuration = (X509CertificateChainProvisionConfiguration) deviceProfile.getProfileData().getProvisionConfiguration(); X509CertificateChainProvisionConfiguration x509Configuration = (X509CertificateChainProvisionConfiguration) deviceProfile.getProfileData().getProvisionConfiguration();
@ -190,8 +186,10 @@ public class DeviceProfileServiceImpl extends AbstractCachedEntityService<Device
publishEvictEvent(new DeviceProfileEvictEvent(savedDeviceProfile.getTenantId(), savedDeviceProfile.getName(), publishEvictEvent(new DeviceProfileEvictEvent(savedDeviceProfile.getTenantId(), savedDeviceProfile.getName(),
oldDeviceProfile != null ? oldDeviceProfile.getName() : null, savedDeviceProfile.getId(), savedDeviceProfile.isDefault(), oldDeviceProfile != null ? oldDeviceProfile.getName() : null, savedDeviceProfile.getId(), savedDeviceProfile.isDefault(),
oldDeviceProfile != null ? oldDeviceProfile.getProvisionDeviceKey() : null)); oldDeviceProfile != null ? oldDeviceProfile.getProvisionDeviceKey() : null));
eventPublisher.publishEvent(SaveEntityEvent.builder().tenantId(savedDeviceProfile.getTenantId()) if (publishSaveEvent) {
.entityId(savedDeviceProfile.getId()).added(oldDeviceProfile == null).build()); eventPublisher.publishEvent(SaveEntityEvent.builder().tenantId(savedDeviceProfile.getTenantId()).entityId(savedDeviceProfile.getId())
.entity(savedDeviceProfile).oldEntity(oldDeviceProfile).added(oldDeviceProfile == null).build());
}
} catch (Exception t) { } catch (Exception t) {
handleEvictEvent(new DeviceProfileEvictEvent(deviceProfile.getTenantId(), deviceProfile.getName(), handleEvictEvent(new DeviceProfileEvictEvent(deviceProfile.getTenantId(), deviceProfile.getName(),
oldDeviceProfile != null ? oldDeviceProfile.getName() : null, null, deviceProfile.isDefault(), oldDeviceProfile != null ? oldDeviceProfile.getName() : null, null, deviceProfile.isDefault(),
@ -240,7 +238,7 @@ public class DeviceProfileServiceImpl extends AbstractCachedEntityService<Device
publishEvictEvent(new DeviceProfileEvictEvent(deviceProfile.getTenantId(), deviceProfile.getName(), publishEvictEvent(new DeviceProfileEvictEvent(deviceProfile.getTenantId(), deviceProfile.getName(),
null, deviceProfile.getId(), deviceProfile.isDefault(), null, deviceProfile.getId(), deviceProfile.isDefault(),
deviceProfile.getProvisionDeviceKey())); deviceProfile.getProvisionDeviceKey()));
eventPublisher.publishEvent(DeleteEntityEvent.builder().tenantId(tenantId).entityId(deviceProfileId).build()); eventPublisher.publishEvent(DeleteEntityEvent.builder().tenantId(tenantId).entityId(deviceProfileId).entity(deviceProfile).build());
} catch (Exception t) { } catch (Exception t) {
ConstraintViolationException e = extractConstraintViolationException(t).orElse(null); ConstraintViolationException e = extractConstraintViolationException(t).orElse(null);
if (e != null && e.getConstraintName() != null && e.getConstraintName().equalsIgnoreCase("fk_device_profile")) { if (e != null && e.getConstraintName() != null && e.getConstraintName().equalsIgnoreCase("fk_device_profile")) {
@ -273,7 +271,7 @@ public class DeviceProfileServiceImpl extends AbstractCachedEntityService<Device
DeviceProfile deviceProfile = findDeviceProfileByName(tenantId, name, false); DeviceProfile deviceProfile = findDeviceProfileByName(tenantId, name, false);
if (deviceProfile == null) { if (deviceProfile == null) {
try { try {
deviceProfile = this.doCreateDefaultDeviceProfile(tenantId, name, name.equals("default")); deviceProfile = this.doCreateDefaultDeviceProfile(tenantId, name, name.equals("default"), true);
} catch (DataValidationException e) { } catch (DataValidationException e) {
if (DEVICE_PROFILE_WITH_SUCH_NAME_ALREADY_EXISTS.equals(e.getMessage())) { if (DEVICE_PROFILE_WITH_SUCH_NAME_ALREADY_EXISTS.equals(e.getMessage())) {
deviceProfile = findDeviceProfileByName(tenantId, name, false); deviceProfile = findDeviceProfileByName(tenantId, name, false);
@ -288,10 +286,10 @@ public class DeviceProfileServiceImpl extends AbstractCachedEntityService<Device
@Override @Override
public DeviceProfile createDefaultDeviceProfile(TenantId tenantId) { public DeviceProfile createDefaultDeviceProfile(TenantId tenantId) {
log.trace("Executing createDefaultDeviceProfile tenantId [{}]", tenantId); log.trace("Executing createDefaultDeviceProfile tenantId [{}]", tenantId);
return doCreateDefaultDeviceProfile(tenantId, "default", true); return doCreateDefaultDeviceProfile(tenantId, "default", true, false);
} }
private DeviceProfile doCreateDefaultDeviceProfile(TenantId tenantId, String profileName, boolean defaultProfile) { private DeviceProfile doCreateDefaultDeviceProfile(TenantId tenantId, String profileName, boolean defaultProfile, boolean publishSaveEvent) {
validateId(tenantId, INCORRECT_TENANT_ID + tenantId); validateId(tenantId, INCORRECT_TENANT_ID + tenantId);
DeviceProfile deviceProfile = new DeviceProfile(); DeviceProfile deviceProfile = new DeviceProfile();
deviceProfile.setTenantId(tenantId); deviceProfile.setTenantId(tenantId);
@ -309,7 +307,7 @@ public class DeviceProfileServiceImpl extends AbstractCachedEntityService<Device
deviceProfileData.setTransportConfiguration(transportConfiguration); deviceProfileData.setTransportConfiguration(transportConfiguration);
deviceProfileData.setProvisionConfiguration(provisionConfiguration); deviceProfileData.setProvisionConfiguration(provisionConfiguration);
deviceProfile.setProfileData(deviceProfileData); deviceProfile.setProfileData(deviceProfileData);
return saveDeviceProfile(deviceProfile); return saveDeviceProfile(deviceProfile, true, publishSaveEvent);
} }
@Override @Override

35
dao/src/main/java/org/thingsboard/server/dao/device/DeviceServiceImpl.java

@ -38,6 +38,7 @@ import org.thingsboard.server.common.data.EntitySubtype;
import org.thingsboard.server.common.data.EntityType; 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.StringUtils; import org.thingsboard.server.common.data.StringUtils;
import org.thingsboard.server.common.data.Tenant;
import org.thingsboard.server.common.data.audit.ActionType; import org.thingsboard.server.common.data.audit.ActionType;
import org.thingsboard.server.common.data.device.DeviceSearchQuery; import org.thingsboard.server.common.data.device.DeviceSearchQuery;
import org.thingsboard.server.common.data.device.credentials.BasicMqttCredentials; import org.thingsboard.server.common.data.device.credentials.BasicMqttCredentials;
@ -77,9 +78,9 @@ import org.thingsboard.server.dao.exception.DataValidationException;
import org.thingsboard.server.dao.exception.IncorrectParameterException; import org.thingsboard.server.dao.exception.IncorrectParameterException;
import org.thingsboard.server.dao.service.DataValidator; import org.thingsboard.server.dao.service.DataValidator;
import org.thingsboard.server.dao.service.PaginatedRemover; import org.thingsboard.server.dao.service.PaginatedRemover;
import org.thingsboard.server.dao.tenant.TenantService;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Comparator;
import java.util.List; import java.util.List;
import java.util.Optional; import java.util.Optional;
import java.util.UUID; import java.util.UUID;
@ -113,6 +114,9 @@ public class DeviceServiceImpl extends AbstractCachedEntityService<DeviceCacheKe
@Autowired @Autowired
private EventService eventService; private EventService eventService;
@Autowired
private TenantService tenantService;
@Autowired @Autowired
private DataValidator<Device> deviceValidator; private DataValidator<Device> deviceValidator;
@ -233,14 +237,14 @@ public class DeviceServiceImpl extends AbstractCachedEntityService<DeviceCacheKe
} }
device.setType(deviceProfile.getName()); device.setType(deviceProfile.getName());
device.setDeviceData(syncDeviceData(deviceProfile, device.getDeviceData())); device.setDeviceData(syncDeviceData(deviceProfile, device.getDeviceData()));
Device result = deviceDao.saveAndFlush(device.getTenantId(), device); Device savedDevice = deviceDao.saveAndFlush(device.getTenantId(), device);
publishEvictEvent(deviceCacheEvictEvent); publishEvictEvent(deviceCacheEvictEvent);
if (device.getId() == null) { if (device.getId() == null) {
countService.publishCountEntityEvictEvent(result.getTenantId(), EntityType.DEVICE); countService.publishCountEntityEvictEvent(savedDevice.getTenantId(), EntityType.DEVICE);
} }
eventPublisher.publishEvent(SaveEntityEvent.builder().tenantId(result.getTenantId()) eventPublisher.publishEvent(SaveEntityEvent.builder().tenantId(savedDevice.getTenantId()).entityId(savedDevice.getId())
.entityId(result.getId()).added(device.getId() == null).build()); .entity(savedDevice).oldEntity(oldDevice).added(device.getId() == null).build());
return result; return savedDevice;
} catch (Exception t) { } catch (Exception t) {
handleEvictEvent(deviceCacheEvictEvent); handleEvictEvent(deviceCacheEvictEvent);
checkConstraintViolation(t, checkConstraintViolation(t,
@ -335,7 +339,7 @@ public class DeviceServiceImpl extends AbstractCachedEntityService<DeviceCacheKe
DeviceCacheEvictEvent deviceCacheEvictEvent = new DeviceCacheEvictEvent(device.getTenantId(), device.getId(), device.getName(), null); DeviceCacheEvictEvent deviceCacheEvictEvent = new DeviceCacheEvictEvent(device.getTenantId(), device.getId(), device.getName(), null);
publishEvictEvent(deviceCacheEvictEvent); publishEvictEvent(deviceCacheEvictEvent);
countService.publishCountEntityEvictEvent(tenantId, EntityType.DEVICE); countService.publishCountEntityEvictEvent(tenantId, EntityType.DEVICE);
eventPublisher.publishEvent(DeleteEntityEvent.builder().tenantId(tenantId).entityId(device.getId()).build()); eventPublisher.publishEvent(DeleteEntityEvent.builder().tenantId(tenantId).entityId(device.getId()).entity(device).build());
} }
@Override @Override
@ -460,7 +464,7 @@ public class DeviceServiceImpl extends AbstractCachedEntityService<DeviceCacheKe
log.trace("Executing unassignCustomerDevices, tenantId [{}], customerId [{}]", tenantId, customerId); log.trace("Executing unassignCustomerDevices, tenantId [{}], customerId [{}]", tenantId, customerId);
validateId(tenantId, INCORRECT_TENANT_ID + tenantId); validateId(tenantId, INCORRECT_TENANT_ID + tenantId);
validateId(customerId, INCORRECT_CUSTOMER_ID + customerId); validateId(customerId, INCORRECT_CUSTOMER_ID + customerId);
customerDeviceUnasigner.removeEntities(tenantId, customerId); customerDevicesRemover.removeEntities(tenantId, customerId);
} }
@Override @Override
@ -493,16 +497,16 @@ public class DeviceServiceImpl extends AbstractCachedEntityService<DeviceCacheKe
@Override @Override
public Device assignDeviceToTenant(TenantId tenantId, Device device) { public Device assignDeviceToTenant(TenantId tenantId, Device device) {
log.trace("Executing assignDeviceToTenant [{}][{}]", tenantId, device); log.trace("Executing assignDeviceToTenant [{}][{}]", tenantId, device);
List<EntityView> entityViews = entityViewService.findEntityViewsByTenantIdAndEntityId(device.getTenantId(), device.getId()); TenantId oldTenantId = device.getTenantId();
Tenant oldTenant = tenantService.findTenantById(oldTenantId);
List<EntityView> entityViews = entityViewService.findEntityViewsByTenantIdAndEntityId(oldTenantId, device.getId());
if (!CollectionUtils.isEmpty(entityViews)) { if (!CollectionUtils.isEmpty(entityViews)) {
throw new DataValidationException("Can't assign device that has entity views to another tenant!"); throw new DataValidationException("Can't assign device that has entity views to another tenant!");
} }
eventService.removeEvents(device.getTenantId(), device.getId()); eventService.removeEvents(oldTenantId, device.getId());
relationService.removeRelations(device.getTenantId(), device.getId()); relationService.removeRelations(oldTenantId, device.getId());
TenantId oldTenantId = device.getTenantId();
device.setTenantId(tenantId); device.setTenantId(tenantId);
device.setCustomerId(null); device.setCustomerId(null);
@ -517,6 +521,9 @@ public class DeviceServiceImpl extends AbstractCachedEntityService<DeviceCacheKe
publishEvictEvent(oldTenantEvent); publishEvictEvent(oldTenantEvent);
publishEvictEvent(newTenantEvent); publishEvictEvent(newTenantEvent);
eventPublisher.publishEvent(ActionEntityEvent.builder().tenantId(tenantId).entity(savedDevice)
.entityId(savedDevice.getId()).body(JacksonUtil.toString(oldTenant)).actionType(ActionType.ASSIGNED_TO_TENANT).build());
return savedDevice; return savedDevice;
} }
@ -658,7 +665,7 @@ public class DeviceServiceImpl extends AbstractCachedEntityService<DeviceCacheKe
} }
}; };
private final PaginatedRemover<CustomerId, Device> customerDeviceUnasigner = new PaginatedRemover<CustomerId, Device>() { private final PaginatedRemover<CustomerId, Device> customerDevicesRemover = new PaginatedRemover<>() {
@Override @Override
protected PageData<Device> findEntities(TenantId tenantId, CustomerId id, PageLink pageLink) { protected PageData<Device> findEntities(TenantId tenantId, CustomerId id, PageLink pageLink) {

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

@ -15,30 +15,71 @@
*/ */
package org.thingsboard.server.dao.edge; package org.thingsboard.server.dao.edge;
import com.google.common.util.concurrent.FutureCallback;
import com.google.common.util.concurrent.Futures;
import com.google.common.util.concurrent.ListenableFuture; import com.google.common.util.concurrent.ListenableFuture;
import lombok.AllArgsConstructor; import jakarta.annotation.PostConstruct;
import jakarta.annotation.PreDestroy;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.jetbrains.annotations.NotNull;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.thingsboard.common.util.ThingsBoardThreadFactory;
import org.thingsboard.server.common.data.edge.EdgeEvent; import org.thingsboard.server.common.data.edge.EdgeEvent;
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.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.TimePageLink; import org.thingsboard.server.common.data.page.TimePageLink;
import org.thingsboard.server.dao.eventsourcing.SaveEntityEvent;
import org.thingsboard.server.dao.service.DataValidator; import org.thingsboard.server.dao.service.DataValidator;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
@Service @Service
@Slf4j @Slf4j
@AllArgsConstructor @RequiredArgsConstructor
public class BaseEdgeEventService implements EdgeEventService { public class BaseEdgeEventService implements EdgeEventService {
private final EdgeEventDao edgeEventDao; private final EdgeEventDao edgeEventDao;
private final DataValidator<EdgeEvent> edgeEventValidator; private final DataValidator<EdgeEvent> edgeEventValidator;
private final ApplicationEventPublisher eventPublisher;
private ExecutorService edgeEventExecutor;
@PostConstruct
public void initExecutor() {
edgeEventExecutor = Executors.newSingleThreadExecutor(ThingsBoardThreadFactory.forName("edge-event-service"));
}
@PreDestroy
public void shutdownExecutor() {
if (edgeEventExecutor != null) {
edgeEventExecutor.shutdown();
}
}
@Override @Override
public ListenableFuture<Void> saveAsync(EdgeEvent edgeEvent) { public ListenableFuture<Void> saveAsync(EdgeEvent edgeEvent) {
edgeEventValidator.validate(edgeEvent, EdgeEvent::getTenantId); edgeEventValidator.validate(edgeEvent, EdgeEvent::getTenantId);
return edgeEventDao.saveAsync(edgeEvent);
ListenableFuture<Void> saveFuture = edgeEventDao.saveAsync(edgeEvent);
Futures.addCallback(saveFuture, new FutureCallback<>() {
@Override
public void onSuccess(Void result) {
eventPublisher.publishEvent(SaveEntityEvent.builder().tenantId(edgeEvent.getTenantId())
.entity(edgeEvent).entityId(edgeEvent.getEdgeId()).build());
}
@Override
public void onFailure(@NotNull Throwable throwable) {}
}, edgeEventExecutor);
return saveFuture;
} }
@Override @Override

13
dao/src/main/java/org/thingsboard/server/dao/edge/EdgeServiceImpl.java

@ -33,7 +33,6 @@ import org.thingsboard.common.util.JacksonUtil;
import org.thingsboard.server.common.data.EntitySubtype; import org.thingsboard.server.common.data.EntitySubtype;
import org.thingsboard.server.common.data.EntityType; import org.thingsboard.server.common.data.EntityType;
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.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;
@ -49,7 +48,6 @@ import org.thingsboard.server.common.data.id.TenantId;
import org.thingsboard.server.common.data.id.TenantProfileId; import org.thingsboard.server.common.data.id.TenantProfileId;
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;
import org.thingsboard.server.common.data.page.PageDataIterable;
import org.thingsboard.server.common.data.page.PageDataIterableByTenantIdEntityId; import org.thingsboard.server.common.data.page.PageDataIterableByTenantIdEntityId;
import org.thingsboard.server.common.data.page.PageLink; import org.thingsboard.server.common.data.page.PageLink;
import org.thingsboard.server.common.data.relation.EntityRelation; import org.thingsboard.server.common.data.relation.EntityRelation;
@ -58,13 +56,14 @@ import org.thingsboard.server.common.data.rule.RuleChain;
import org.thingsboard.server.common.data.rule.RuleNode; import org.thingsboard.server.common.data.rule.RuleNode;
import org.thingsboard.server.dao.entity.AbstractCachedEntityService; import org.thingsboard.server.dao.entity.AbstractCachedEntityService;
import org.thingsboard.server.dao.eventsourcing.ActionEntityEvent; import org.thingsboard.server.dao.eventsourcing.ActionEntityEvent;
import org.thingsboard.server.dao.eventsourcing.DeleteEntityEvent;
import org.thingsboard.server.dao.eventsourcing.SaveEntityEvent;
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.dao.rule.RuleChainService; import org.thingsboard.server.dao.rule.RuleChainService;
import org.thingsboard.server.dao.service.DataValidator; import org.thingsboard.server.dao.service.DataValidator;
import org.thingsboard.server.dao.service.PaginatedRemover; import org.thingsboard.server.dao.service.PaginatedRemover;
import org.thingsboard.server.dao.service.Validator; import org.thingsboard.server.dao.service.Validator;
import org.thingsboard.server.dao.tenant.TenantService;
import org.thingsboard.server.dao.user.UserService; import org.thingsboard.server.dao.user.UserService;
import jakarta.annotation.Nullable; import jakarta.annotation.Nullable;
@ -104,9 +103,6 @@ public class EdgeServiceImpl extends AbstractCachedEntityService<EdgeCacheKey, E
@Autowired @Autowired
private RelationService relationService; private RelationService relationService;
@Autowired
private TenantService tenantService;
@Autowired @Autowired
private DataValidator<Edge> edgeValidator; private DataValidator<Edge> edgeValidator;
@ -168,8 +164,10 @@ public class EdgeServiceImpl extends AbstractCachedEntityService<EdgeCacheKey, E
Edge oldEdge = edgeValidator.validate(edge, Edge::getTenantId); Edge oldEdge = edgeValidator.validate(edge, Edge::getTenantId);
EdgeCacheEvictEvent evictEvent = new EdgeCacheEvictEvent(edge.getTenantId(), edge.getName(), oldEdge != null ? oldEdge.getName() : null); EdgeCacheEvictEvent evictEvent = new EdgeCacheEvictEvent(edge.getTenantId(), edge.getName(), oldEdge != null ? oldEdge.getName() : null);
try { try {
var savedEdge = edgeDao.save(edge.getTenantId(), edge); Edge savedEdge = edgeDao.save(edge.getTenantId(), edge);
publishEvictEvent(evictEvent); publishEvictEvent(evictEvent);
eventPublisher.publishEvent(SaveEntityEvent.builder().tenantId(savedEdge.getTenantId())
.entityId(savedEdge.getId()).entity(savedEdge).added(edge.getId() == null).build());
return savedEdge; return savedEdge;
} catch (Exception t) { } catch (Exception t) {
handleEvictEvent(evictEvent); handleEvictEvent(evictEvent);
@ -217,6 +215,7 @@ public class EdgeServiceImpl extends AbstractCachedEntityService<EdgeCacheKey, E
edgeDao.removeById(tenantId, edgeId.getId()); edgeDao.removeById(tenantId, edgeId.getId());
eventPublisher.publishEvent(DeleteEntityEvent.builder().tenantId(tenantId).entityId(edgeId).build());
publishEvictEvent(new EdgeCacheEvictEvent(edge.getTenantId(), edge.getName(), null)); publishEvictEvent(new EdgeCacheEvictEvent(edge.getTenantId(), edge.getName(), null));
} }

10
dao/src/main/java/org/thingsboard/server/dao/entityview/EntityViewServiceImpl.java

@ -101,17 +101,13 @@ public class EntityViewServiceImpl extends AbstractCachedEntityService<EntityVie
cache.evict(keys); cache.evict(keys);
} }
@Override
public EntityView saveEntityView(EntityView entityView, boolean doValidate) {
return doSaveEntityView(entityView, doValidate);
}
@Override @Override
public EntityView saveEntityView(EntityView entityView) { public EntityView saveEntityView(EntityView entityView) {
return doSaveEntityView(entityView, true); return saveEntityView(entityView, true);
} }
private EntityView doSaveEntityView(EntityView entityView, boolean doValidate) { @Override
public EntityView saveEntityView(EntityView entityView, boolean doValidate) {
log.trace("Executing save entity view [{}]", entityView); log.trace("Executing save entity view [{}]", entityView);
EntityView old = null; EntityView old = null;
if (doValidate) { if (doValidate) {

5
dao/src/main/java/org/thingsboard/server/dao/eventsourcing/ActionEntityEvent.java

@ -24,10 +24,11 @@ import org.thingsboard.server.common.data.id.TenantId;
@Data @Data
@Builder @Builder
public class ActionEntityEvent { public class ActionEntityEvent<T> {
private final TenantId tenantId; private final TenantId tenantId;
private final EdgeId edgeId; private final T entity;
private final EntityId entityId; private final EntityId entityId;
private final EdgeId edgeId;
private final String body; private final String body;
private final ActionType actionType; private final ActionType actionType;
} }

1
dao/src/main/java/org/thingsboard/server/dao/eventsourcing/DeleteEntityEvent.java

@ -27,6 +27,7 @@ public class DeleteEntityEvent<T> {
private final TenantId tenantId; private final TenantId tenantId;
private final EntityId entityId; private final EntityId entityId;
private final T entity; private final T entity;
private final String body;
@Builder.Default @Builder.Default
private final long ts = System.currentTimeMillis(); private final long ts = System.currentTimeMillis();

12
dao/src/main/java/org/thingsboard/server/dao/notification/DefaultNotificationRequestService.java

@ -17,6 +17,7 @@ package org.thingsboard.server.dao.notification;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.springframework.context.ApplicationEventPublisher;
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.id.EntityId; import org.thingsboard.server.common.data.id.EntityId;
@ -31,6 +32,7 @@ import org.thingsboard.server.common.data.notification.NotificationRequestStatus
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.dao.entity.EntityDaoService; import org.thingsboard.server.dao.entity.EntityDaoService;
import org.thingsboard.server.dao.eventsourcing.DeleteEntityEvent;
import org.thingsboard.server.dao.service.DataValidator; import org.thingsboard.server.dao.service.DataValidator;
import java.util.List; import java.util.List;
@ -44,6 +46,8 @@ public class DefaultNotificationRequestService implements NotificationRequestSer
private final NotificationRequestDao notificationRequestDao; private final NotificationRequestDao notificationRequestDao;
private final NotificationDao notificationDao; private final NotificationDao notificationDao;
private final ApplicationEventPublisher eventPublisher;
private final NotificationRequestValidator notificationRequestValidator = new NotificationRequestValidator(); private final NotificationRequestValidator notificationRequestValidator = new NotificationRequestValidator();
@Override @Override
@ -83,9 +87,10 @@ public class DefaultNotificationRequestService implements NotificationRequestSer
} }
@Override @Override
public void deleteNotificationRequest(TenantId tenantId, NotificationRequestId requestId) { public void deleteNotificationRequest(TenantId tenantId, NotificationRequest request) {
notificationRequestDao.removeById(tenantId, requestId.getId()); notificationRequestDao.removeById(tenantId, request.getUuidId());
notificationDao.deleteByRequestId(tenantId, requestId); notificationDao.deleteByRequestId(tenantId, request.getId());
eventPublisher.publishEvent(DeleteEntityEvent.builder().tenantId(tenantId).entity(request).entityId(request.getId()).build());
} }
@Override @Override
@ -114,7 +119,6 @@ public class DefaultNotificationRequestService implements NotificationRequestSer
return EntityType.NOTIFICATION_REQUEST; return EntityType.NOTIFICATION_REQUEST;
} }
private static class NotificationRequestValidator extends DataValidator<NotificationRequest> { private static class NotificationRequestValidator extends DataValidator<NotificationRequest> {
} }

8
dao/src/main/java/org/thingsboard/server/dao/notification/DefaultNotificationRuleService.java

@ -29,6 +29,8 @@ 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.dao.entity.AbstractEntityService; import org.thingsboard.server.dao.entity.AbstractEntityService;
import org.thingsboard.server.dao.entity.EntityDaoService; import org.thingsboard.server.dao.entity.EntityDaoService;
import org.thingsboard.server.dao.eventsourcing.DeleteEntityEvent;
import org.thingsboard.server.dao.eventsourcing.SaveEntityEvent;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
@ -49,7 +51,10 @@ public class DefaultNotificationRuleService extends AbstractEntityService implem
} }
} }
try { try {
return notificationRuleDao.saveAndFlush(tenantId, notificationRule); NotificationRule savedRule = notificationRuleDao.saveAndFlush(tenantId, notificationRule);
eventPublisher.publishEvent(SaveEntityEvent.builder().tenantId(tenantId).entityId(savedRule.getId())
.added(notificationRule.getId() == null).build());
return savedRule;
} catch (Exception e) { } catch (Exception e) {
checkConstraintViolation(e, Map.of( checkConstraintViolation(e, Map.of(
"uq_notification_rule_name", "Notification rule with such name already exists" "uq_notification_rule_name", "Notification rule with such name already exists"
@ -86,6 +91,7 @@ public class DefaultNotificationRuleService extends AbstractEntityService implem
@Override @Override
public void deleteNotificationRuleById(TenantId tenantId, NotificationRuleId id) { public void deleteNotificationRuleById(TenantId tenantId, NotificationRuleId id) {
notificationRuleDao.removeById(tenantId, id.getId()); notificationRuleDao.removeById(tenantId, id.getId());
eventPublisher.publishEvent(DeleteEntityEvent.builder().tenantId(tenantId).entityId(id).build());
} }
@Override @Override

5
dao/src/main/java/org/thingsboard/server/dao/queue/BaseQueueService.java

@ -57,16 +57,13 @@ public class BaseQueueService extends AbstractEntityService implements QueueServ
@Autowired @Autowired
private DataValidator<Queue> queueValidator; private DataValidator<Queue> queueValidator;
// @Autowired
// private QueueStatsService queueStatsService;
@Override @Override
public Queue saveQueue(Queue queue) { public Queue saveQueue(Queue queue) {
log.trace("Executing createOrUpdateQueue [{}]", queue); log.trace("Executing createOrUpdateQueue [{}]", queue);
queueValidator.validate(queue, Queue::getTenantId); queueValidator.validate(queue, Queue::getTenantId);
Queue savedQueue = queueDao.save(queue.getTenantId(), queue); Queue savedQueue = queueDao.save(queue.getTenantId(), queue);
eventPublisher.publishEvent(SaveEntityEvent.builder().tenantId(savedQueue.getTenantId()) eventPublisher.publishEvent(SaveEntityEvent.builder().tenantId(savedQueue.getTenantId())
.entityId(savedQueue.getId()).added(queue.getId() == null).build()); .entityId(savedQueue.getId()).entity(savedQueue).added(queue.getId() == null).build());
return savedQueue; return savedQueue;
} }

10
dao/src/main/java/org/thingsboard/server/dao/resource/BaseResourceService.java

@ -89,8 +89,8 @@ public class BaseResourceService extends AbstractCachedEntityService<ResourceInf
saved = new TbResource(resourceInfo); saved = new TbResource(resourceInfo);
} }
publishEvictEvent(new ResourceInfoEvictEvent(tenantId, resource.getId())); publishEvictEvent(new ResourceInfoEvictEvent(tenantId, resource.getId()));
eventPublisher.publishEvent(SaveEntityEvent.builder().tenantId(saved.getTenantId()) eventPublisher.publishEvent(SaveEntityEvent.builder().tenantId(saved.getTenantId()).entityId(saved.getId())
.entityId(saved.getId()).added(resource.getId() == null).build()); .entity(saved).added(resource.getId() == null).build());
return saved; return saved;
} catch (Exception t) { } catch (Exception t) {
publishEvictEvent(new ResourceInfoEvictEvent(tenantId, resource.getId())); publishEvictEvent(new ResourceInfoEvictEvent(tenantId, resource.getId()));
@ -154,11 +154,11 @@ public class BaseResourceService extends AbstractCachedEntityService<ResourceInf
if (!force) { if (!force) {
resourceValidator.validateDelete(tenantId, resourceId); resourceValidator.validateDelete(tenantId, resourceId);
} }
TbResource resource = findResourceById(tenantId, resourceId);
resourceDao.removeById(tenantId, resourceId.getId()); resourceDao.removeById(tenantId, resourceId.getId());
eventPublisher.publishEvent(DeleteEntityEvent.builder().tenantId(tenantId).entityId(resourceId).build()); eventPublisher.publishEvent(DeleteEntityEvent.builder().tenantId(tenantId).entity(resource).entityId(resourceId).build());
} }
@Override @Override
public PageData<TbResourceInfo> findAllTenantResourcesByTenantId(TbResourceInfoFilter filter, PageLink pageLink) { public PageData<TbResourceInfo> findAllTenantResourcesByTenantId(TbResourceInfoFilter filter, PageLink pageLink) {
TenantId tenantId = filter.getTenantId(); TenantId tenantId = filter.getTenantId();
@ -237,7 +237,7 @@ public class BaseResourceService extends AbstractCachedEntityService<ResourceInf
@Override @Override
protected void removeEntity(TenantId tenantId, TbResource entity) { protected void removeEntity(TenantId tenantId, TbResource entity) {
deleteResource(tenantId, new TbResourceId(entity.getUuidId())); deleteResource(tenantId, entity.getId());
} }
}; };

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

@ -38,6 +38,7 @@ 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.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.PageLink; import org.thingsboard.server.common.data.page.PageLink;
import org.thingsboard.server.common.data.plugin.ComponentClusteringMode; import org.thingsboard.server.common.data.plugin.ComponentClusteringMode;
import org.thingsboard.server.common.data.relation.EntityRelation; import org.thingsboard.server.common.data.relation.EntityRelation;
@ -73,6 +74,7 @@ import java.util.Iterator;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Optional; import java.util.Optional;
import java.util.Set;
import java.util.function.Function; import java.util.function.Function;
import java.util.stream.Collectors; import java.util.stream.Collectors;
@ -109,14 +111,22 @@ public class BaseRuleChainService extends AbstractEntityService implements RuleC
@Override @Override
@Transactional @Transactional
public RuleChain saveRuleChain(RuleChain ruleChain) { public RuleChain saveRuleChain(RuleChain ruleChain) {
return saveRuleChain(ruleChain, true);
}
@Override
@Transactional
public RuleChain saveRuleChain(RuleChain ruleChain, boolean publishSaveEvent) {
ruleChainValidator.validate(ruleChain, RuleChain::getTenantId); ruleChainValidator.validate(ruleChain, RuleChain::getTenantId);
try { try {
RuleChain savedRuleChain = ruleChainDao.save(ruleChain.getTenantId(), ruleChain); RuleChain savedRuleChain = ruleChainDao.save(ruleChain.getTenantId(), ruleChain);
if (ruleChain.getId() == null) { if (ruleChain.getId() == null) {
entityCountService.publishCountEntityEvictEvent(ruleChain.getTenantId(), EntityType.RULE_CHAIN); entityCountService.publishCountEntityEvictEvent(ruleChain.getTenantId(), EntityType.RULE_CHAIN);
} }
eventPublisher.publishEvent(SaveEntityEvent.builder().tenantId(savedRuleChain.getTenantId()) if (publishSaveEvent) {
.entity(savedRuleChain).entityId(savedRuleChain.getId()).added(ruleChain.getId() == null).build()); eventPublisher.publishEvent(SaveEntityEvent.builder().tenantId(savedRuleChain.getTenantId())
.entity(savedRuleChain).entityId(savedRuleChain.getId()).added(ruleChain.getId() == null).build());
}
return savedRuleChain; return savedRuleChain;
} catch (Exception e) { } catch (Exception e) {
checkConstraintViolation(e, "rule_chain_external_id_unq_key", "Rule Chain with such external id already exists!"); checkConstraintViolation(e, "rule_chain_external_id_unq_key", "Rule Chain with such external id already exists!");
@ -136,6 +146,8 @@ public class BaseRuleChainService extends AbstractEntityService implements RuleC
} else if (!previousRootRuleChain.getId().equals(ruleChain.getId())) { } else if (!previousRootRuleChain.getId().equals(ruleChain.getId())) {
previousRootRuleChain.setRoot(false); previousRootRuleChain.setRoot(false);
ruleChainDao.save(tenantId, previousRootRuleChain); ruleChainDao.save(tenantId, previousRootRuleChain);
eventPublisher.publishEvent(SaveEntityEvent.builder().tenantId(tenantId)
.entityId(previousRootRuleChain.getId()).entity(previousRootRuleChain).added(false).build());
setRootAndSave(tenantId, ruleChain); setRootAndSave(tenantId, ruleChain);
return true; return true;
} }
@ -146,10 +158,17 @@ public class BaseRuleChainService extends AbstractEntityService implements RuleC
private void setRootAndSave(TenantId tenantId, RuleChain ruleChain) { private void setRootAndSave(TenantId tenantId, RuleChain ruleChain) {
ruleChain.setRoot(true); ruleChain.setRoot(true);
ruleChainDao.save(tenantId, ruleChain); ruleChainDao.save(tenantId, ruleChain);
eventPublisher.publishEvent(SaveEntityEvent.builder().tenantId(tenantId).entityId(ruleChain.getId()).entity(ruleChain).added(false).build());
} }
@Override @Override
public RuleChainUpdateResult saveRuleChainMetaData(TenantId tenantId, RuleChainMetaData ruleChainMetaData, Function<RuleNode, RuleNode> ruleNodeUpdater) { public RuleChainUpdateResult saveRuleChainMetaData(TenantId tenantId, RuleChainMetaData ruleChainMetaData, Function<RuleNode, RuleNode> ruleNodeUpdater) {
return saveRuleChainMetaData(tenantId, ruleChainMetaData, ruleNodeUpdater, true);
}
@Override
public RuleChainUpdateResult saveRuleChainMetaData(TenantId tenantId, RuleChainMetaData ruleChainMetaData, Function<RuleNode, RuleNode> ruleNodeUpdater, boolean publishSaveEvent) {
Validator.validateId(ruleChainMetaData.getRuleChainId(), "Incorrect rule chain id."); Validator.validateId(ruleChainMetaData.getRuleChainId(), "Incorrect rule chain id.");
RuleChain ruleChain = findRuleChainById(tenantId, ruleChainMetaData.getRuleChainId()); RuleChain ruleChain = findRuleChainById(tenantId, ruleChainMetaData.getRuleChainId());
if (ruleChain == null) { if (ruleChain == null) {
@ -263,8 +282,9 @@ public class BaseRuleChainService extends AbstractEntityService implements RuleC
if (!relations.isEmpty()) { if (!relations.isEmpty()) {
relationService.saveRelations(tenantId, relations); relationService.saveRelations(tenantId, relations);
} }
eventPublisher.publishEvent(SaveEntityEvent.builder().tenantId(tenantId).entity(ruleChain).entityId(ruleChain.getId()).build()); if (publishSaveEvent) {
eventPublisher.publishEvent(SaveEntityEvent.builder().tenantId(tenantId).entity(ruleChain).entityId(ruleChain.getId()).build());
}
return RuleChainUpdateResult.successful(updatedRuleNodes); return RuleChainUpdateResult.successful(updatedRuleNodes);
} }
@ -292,11 +312,11 @@ public class BaseRuleChainService extends AbstractEntityService implements RuleC
List<EntityRelation> nodeRelations = getRuleNodeRelations(tenantId, node.getId()); List<EntityRelation> nodeRelations = getRuleNodeRelations(tenantId, node.getId());
for (EntityRelation nodeRelation : nodeRelations) { for (EntityRelation nodeRelation : nodeRelations) {
String type = nodeRelation.getType(); String type = nodeRelation.getType();
if (nodeRelation.getTo().getEntityType() == EntityType.RULE_NODE) { if (EntityType.RULE_NODE.equals(nodeRelation.getTo().getEntityType())) {
RuleNodeId toNodeId = new RuleNodeId(nodeRelation.getTo().getId()); RuleNodeId toNodeId = new RuleNodeId(nodeRelation.getTo().getId());
int toIndex = ruleNodeIndexMap.get(toNodeId); int toIndex = ruleNodeIndexMap.get(toNodeId);
ruleChainMetaData.addConnectionInfo(fromIndex, toIndex, type); ruleChainMetaData.addConnectionInfo(fromIndex, toIndex, type);
} else if (nodeRelation.getTo().getEntityType() == EntityType.RULE_CHAIN) { } else if (EntityType.RULE_CHAIN.equals(nodeRelation.getTo().getEntityType())) {
log.warn("[{}][{}] Unsupported node relation: {}", tenantId, ruleChainId, nodeRelation.getTo()); log.warn("[{}][{}] Unsupported node relation: {}", tenantId, ruleChainId, nodeRelation.getTo());
} }
} }
@ -412,29 +432,23 @@ public class BaseRuleChainService extends AbstractEntityService implements RuleC
public void deleteRuleChainById(TenantId tenantId, RuleChainId ruleChainId) { public void deleteRuleChainById(TenantId tenantId, RuleChainId ruleChainId) {
Validator.validateId(ruleChainId, "Incorrect rule chain id for delete request."); Validator.validateId(ruleChainId, "Incorrect rule chain id for delete request.");
RuleChain ruleChain = ruleChainDao.findById(tenantId, ruleChainId.getId()); RuleChain ruleChain = ruleChainDao.findById(tenantId, ruleChainId.getId());
List<RuleNode> referencingRuleNodes = getReferencingRuleChainNodes(tenantId, ruleChainId);
Set<RuleChainId> referencingRuleChainIds = referencingRuleNodes.stream().map(RuleNode::getRuleChainId).collect(Collectors.toSet());
if (ruleChain != null) { if (ruleChain != null) {
if (ruleChain.isRoot()) { if (ruleChain.isRoot()) {
throw new DataValidationException("Deletion of Root Tenant Rule Chain is prohibited!"); throw new DataValidationException("Deletion of Root Tenant Rule Chain is prohibited!");
} }
if (RuleChainType.EDGE.equals(ruleChain.getType())) { if (RuleChainType.EDGE.equals(ruleChain.getType())) {
PageLink pageLink = new PageLink(DEFAULT_PAGE_SIZE); for (Edge edge : new PageDataIterable<>(link -> edgeService.findEdgesByTenantIdAndEntityId(tenantId, ruleChainId, link), DEFAULT_PAGE_SIZE)) {
PageData<Edge> pageData; if (edge.getRootRuleChainId() != null && edge.getRootRuleChainId().equals(ruleChainId)) {
do { throw new DataValidationException("Can't delete rule chain that is root for edge [" + edge.getName() + "]. Please assign another root rule chain first to the edge!");
pageData = edgeService.findEdgesByTenantIdAndEntityId(tenantId, ruleChainId, pageLink);
if (pageData != null && pageData.getData() != null && !pageData.getData().isEmpty()) {
for (Edge edge : pageData.getData()) {
if (edge.getRootRuleChainId() != null && edge.getRootRuleChainId().equals(ruleChainId)) {
throw new DataValidationException("Can't delete rule chain that is root for edge [" + edge.getName() + "]. Please assign another root rule chain first to the edge!");
}
}
if (pageData.hasNext()) {
pageLink = pageLink.nextPageLink();
}
} }
} while (pageData != null && pageData.hasNext()); }
} }
} }
checkRuleNodesAndDelete(tenantId, ruleChainId); checkRuleNodesAndDelete(tenantId, ruleChain, referencingRuleChainIds);
} }
@Override @Override
@ -750,11 +764,15 @@ public class BaseRuleChainService extends AbstractEntityService implements RuleC
return ruleNodeDao.save(tenantId, ruleNode); return ruleNodeDao.save(tenantId, ruleNode);
} }
private void checkRuleNodesAndDelete(TenantId tenantId, RuleChainId ruleChainId) { private void checkRuleNodesAndDelete(TenantId tenantId, RuleChain ruleChain, Set<RuleChainId> referencingRuleChainIds) {
try { try {
entityCountService.publishCountEntityEvictEvent(tenantId, EntityType.RULE_CHAIN); entityCountService.publishCountEntityEvictEvent(tenantId, EntityType.RULE_CHAIN);
ruleChainDao.removeById(tenantId, ruleChainId.getId()); ruleChainDao.removeById(tenantId, ruleChain.getUuidId());
eventPublisher.publishEvent(DeleteEntityEvent.builder().tenantId(tenantId).entityId(ruleChainId).build());
if (referencingRuleChainIds != null) {
referencingRuleChainIds.remove(ruleChain.getId());
}
eventPublisher.publishEvent(DeleteEntityEvent.builder().tenantId(tenantId).entityId(ruleChain.getId()).entity(ruleChain).body(JacksonUtil.toString(referencingRuleChainIds)).build());
} catch (Exception t) { } catch (Exception t) {
ConstraintViolationException e = extractConstraintViolationException(t).orElse(null); ConstraintViolationException e = extractConstraintViolationException(t).orElse(null);
if (e != null && e.getConstraintName() != null && e.getConstraintName().equalsIgnoreCase("fk_default_rule_chain_device_profile")) { if (e != null && e.getConstraintName() != null && e.getConstraintName().equalsIgnoreCase("fk_default_rule_chain_device_profile")) {
@ -765,7 +783,7 @@ public class BaseRuleChainService extends AbstractEntityService implements RuleC
throw t; throw t;
} }
} }
deleteRuleNodes(tenantId, ruleChainId); deleteRuleNodes(tenantId, ruleChain.getId());
} }
private void deleteRuleNodes(TenantId tenantId, List<RuleNode> ruleNodes) { private void deleteRuleNodes(TenantId tenantId, List<RuleNode> ruleNodes) {
@ -834,7 +852,7 @@ public class BaseRuleChainService extends AbstractEntityService implements RuleC
@Override @Override
protected void removeEntity(TenantId tenantId, RuleChain entity) { protected void removeEntity(TenantId tenantId, RuleChain entity) {
checkRuleNodesAndDelete(tenantId, entity.getId()); checkRuleNodesAndDelete(tenantId, entity, null);
} }
}; };

11
dao/src/main/java/org/thingsboard/server/dao/tenant/TenantProfileServiceImpl.java

@ -94,7 +94,7 @@ public class TenantProfileServiceImpl extends AbstractCachedEntityService<Tenant
try { try {
savedTenantProfile = tenantProfileDao.save(tenantId, tenantProfile); savedTenantProfile = tenantProfileDao.save(tenantId, tenantProfile);
publishEvictEvent(new TenantProfileEvictEvent(savedTenantProfile.getId(), savedTenantProfile.isDefault())); publishEvictEvent(new TenantProfileEvictEvent(savedTenantProfile.getId(), savedTenantProfile.isDefault()));
eventPublisher.publishEvent(SaveEntityEvent.builder().tenantId(tenantId) eventPublisher.publishEvent(SaveEntityEvent.builder().tenantId(tenantId).entity(savedTenantProfile)
.entityId(savedTenantProfile.getId()).added(tenantProfile.getId() == null).build()); .entityId(savedTenantProfile.getId()).added(tenantProfile.getId() == null).build());
} catch (Exception t) { } catch (Exception t) {
handleEvictEvent(new TenantProfileEvictEvent(null, tenantProfile.isDefault())); handleEvictEvent(new TenantProfileEvictEvent(null, tenantProfile.isDefault()));
@ -116,10 +116,11 @@ public class TenantProfileServiceImpl extends AbstractCachedEntityService<Tenant
if (tenantProfile != null && tenantProfile.isDefault()) { if (tenantProfile != null && tenantProfile.isDefault()) {
throw new DataValidationException("Deletion of Default Tenant Profile is prohibited!"); throw new DataValidationException("Deletion of Default Tenant Profile is prohibited!");
} }
this.removeTenantProfile(tenantId, tenantProfileId, false); this.removeTenantProfile(tenantId, tenantProfile, false);
} }
private void removeTenantProfile(TenantId tenantId, TenantProfileId tenantProfileId, boolean isDefault) { private void removeTenantProfile(TenantId tenantId, TenantProfile tenantProfile, boolean isDefault) {
TenantProfileId tenantProfileId = tenantProfile.getId();
try { try {
tenantProfileDao.removeById(tenantId, tenantProfileId.getId()); tenantProfileDao.removeById(tenantId, tenantProfileId.getId());
} catch (Exception t) { } catch (Exception t) {
@ -132,7 +133,7 @@ public class TenantProfileServiceImpl extends AbstractCachedEntityService<Tenant
} }
deleteEntityRelations(tenantId, tenantProfileId); deleteEntityRelations(tenantId, tenantProfileId);
publishEvictEvent(new TenantProfileEvictEvent(tenantProfileId, isDefault)); publishEvictEvent(new TenantProfileEvictEvent(tenantProfileId, isDefault));
eventPublisher.publishEvent(DeleteEntityEvent.builder().tenantId(tenantId).entityId(tenantProfileId).build()); eventPublisher.publishEvent(DeleteEntityEvent.builder().tenantId(tenantId).entity(tenantProfile).entityId(tenantProfileId).build());
} }
@Override @Override
@ -239,7 +240,7 @@ public class TenantProfileServiceImpl extends AbstractCachedEntityService<Tenant
@Override @Override
protected void removeEntity(TenantId tenantId, TenantProfile entity) { protected void removeEntity(TenantId tenantId, TenantProfile entity) {
removeTenantProfile(tenantId, entity.getId(), entity.isDefault()); removeTenantProfile(tenantId, entity, entity.isDefault());
} }
}; };

15
dao/src/main/java/org/thingsboard/server/dao/tenant/TenantServiceImpl.java

@ -187,6 +187,12 @@ public class TenantServiceImpl extends AbstractCachedEntityService<TenantId, Ten
@Override @Override
@Transactional @Transactional
public Tenant saveTenant(Tenant tenant) { public Tenant saveTenant(Tenant tenant) {
return saveTenant(tenant, true);
}
@Override
@Transactional
public Tenant saveTenant(Tenant tenant, boolean publishSaveEvent) {
log.trace("Executing saveTenant [{}]", tenant); log.trace("Executing saveTenant [{}]", tenant);
tenant.setRegion(DEFAULT_TENANT_REGION); tenant.setRegion(DEFAULT_TENANT_REGION);
if (tenant.getTenantProfileId() == null) { if (tenant.getTenantProfileId() == null) {
@ -197,7 +203,10 @@ public class TenantServiceImpl extends AbstractCachedEntityService<TenantId, Ten
boolean create = tenant.getId() == null; boolean create = tenant.getId() == null;
Tenant savedTenant = tenantDao.save(tenant.getId(), tenant); Tenant savedTenant = tenantDao.save(tenant.getId(), tenant);
publishEvictEvent(new TenantEvictEvent(savedTenant.getId(), create)); publishEvictEvent(new TenantEvictEvent(savedTenant.getId(), create));
eventPublisher.publishEvent(SaveEntityEvent.builder().tenantId(savedTenant.getId()).entityId(savedTenant.getId()).added(create).build()); if (publishSaveEvent) {
eventPublisher.publishEvent(SaveEntityEvent.builder().tenantId(savedTenant.getId())
.entityId(savedTenant.getId()).entity(savedTenant).added(create).build());
}
if (tenant.getId() == null) { if (tenant.getId() == null) {
deviceProfileService.createDefaultDeviceProfile(savedTenant.getId()); deviceProfileService.createDefaultDeviceProfile(savedTenant.getId());
assetProfileService.createDefaultAssetProfile(savedTenant.getId()); assetProfileService.createDefaultAssetProfile(savedTenant.getId());
@ -219,6 +228,7 @@ public class TenantServiceImpl extends AbstractCachedEntityService<TenantId, Ten
@Override @Override
public void deleteTenant(TenantId tenantId) { public void deleteTenant(TenantId tenantId) {
log.trace("Executing deleteTenant [{}]", tenantId); log.trace("Executing deleteTenant [{}]", tenantId);
Tenant tenant = findTenantById(tenantId);
Validator.validateId(tenantId, INCORRECT_TENANT_ID + tenantId); Validator.validateId(tenantId, INCORRECT_TENANT_ID + tenantId);
entityViewService.deleteEntityViewsByTenantId(tenantId); entityViewService.deleteEntityViewsByTenantId(tenantId);
widgetsBundleService.deleteWidgetsBundlesByTenantId(tenantId); widgetsBundleService.deleteWidgetsBundlesByTenantId(tenantId);
@ -244,7 +254,8 @@ public class TenantServiceImpl extends AbstractCachedEntityService<TenantId, Ten
adminSettingsService.deleteAdminSettingsByTenantId(tenantId); adminSettingsService.deleteAdminSettingsByTenantId(tenantId);
tenantDao.removeById(tenantId, tenantId.getId()); tenantDao.removeById(tenantId, tenantId.getId());
publishEvictEvent(new TenantEvictEvent(tenantId, true)); publishEvictEvent(new TenantEvictEvent(tenantId, true));
eventPublisher.publishEvent(DeleteEntityEvent.builder().tenantId(tenantId).entityId(tenantId).build()); eventPublisher.publishEvent(DeleteEntityEvent.builder().tenantId(tenantId)
.entity(tenant).entityId(tenantId).build());
relationService.deleteEntityRelations(tenantId, tenantId); relationService.deleteEntityRelations(tenantId, tenantId);
alarmService.deleteEntityAlarmRecordsByTenantId(tenantId); alarmService.deleteEntityAlarmRecordsByTenantId(tenantId);
} }

6
dao/src/main/java/org/thingsboard/server/dao/usagerecord/ApiUsageStateServiceImpl.java

@ -35,6 +35,7 @@ import org.thingsboard.server.common.data.kv.StringDataEntry;
import org.thingsboard.server.common.data.kv.TsKvEntry; import org.thingsboard.server.common.data.kv.TsKvEntry;
import org.thingsboard.server.common.data.tenant.profile.TenantProfileConfiguration; import org.thingsboard.server.common.data.tenant.profile.TenantProfileConfiguration;
import org.thingsboard.server.dao.entity.AbstractEntityService; import org.thingsboard.server.dao.entity.AbstractEntityService;
import org.thingsboard.server.dao.eventsourcing.SaveEntityEvent;
import org.thingsboard.server.dao.service.DataValidator; import org.thingsboard.server.dao.service.DataValidator;
import org.thingsboard.server.dao.tenant.TenantProfileDao; import org.thingsboard.server.dao.tenant.TenantProfileDao;
import org.thingsboard.server.dao.tenant.TenantService; import org.thingsboard.server.dao.tenant.TenantService;
@ -143,7 +144,10 @@ public class ApiUsageStateServiceImpl extends AbstractEntityService implements A
log.trace("Executing save [{}]", apiUsageState.getTenantId()); log.trace("Executing save [{}]", apiUsageState.getTenantId());
validateId(apiUsageState.getTenantId(), INCORRECT_TENANT_ID + apiUsageState.getTenantId()); validateId(apiUsageState.getTenantId(), INCORRECT_TENANT_ID + apiUsageState.getTenantId());
validateId(apiUsageState.getId(), "Can't save new usage state. Only update is allowed!"); validateId(apiUsageState.getId(), "Can't save new usage state. Only update is allowed!");
return apiUsageStateDao.save(apiUsageState.getTenantId(), apiUsageState); ApiUsageState savedState = apiUsageStateDao.save(apiUsageState.getTenantId(), apiUsageState);
eventPublisher.publishEvent(SaveEntityEvent.builder().tenantId(savedState.getTenantId()).entityId(savedState.getId())
.entity(savedState).build());
return savedState;
} }
@Override @Override

24
dao/src/test/java/org/thingsboard/server/dao/service/DashboardServiceTest.java

@ -90,9 +90,8 @@ public class DashboardServiceTest extends AbstractServiceTest {
public void testSaveDashboardWithEmptyTenant() { public void testSaveDashboardWithEmptyTenant() {
Dashboard dashboard = new Dashboard(); Dashboard dashboard = new Dashboard();
dashboard.setTitle("My dashboard"); dashboard.setTitle("My dashboard");
Assertions.assertThrows(DataValidationException.class, () -> { Assertions.assertThrows(DataValidationException.class, () ->
dashboardService.saveDashboard(dashboard); dashboardService.saveDashboard(dashboard));
});
} }
@Test @Test
@ -100,9 +99,8 @@ public class DashboardServiceTest extends AbstractServiceTest {
Dashboard dashboard = new Dashboard(); Dashboard dashboard = new Dashboard();
dashboard.setTitle("My dashboard"); dashboard.setTitle("My dashboard");
dashboard.setTenantId(TenantId.fromUUID(Uuids.timeBased())); dashboard.setTenantId(TenantId.fromUUID(Uuids.timeBased()));
Assertions.assertThrows(DataValidationException.class, () -> { Assertions.assertThrows(DataValidationException.class, () ->
dashboardService.saveDashboard(dashboard); dashboardService.saveDashboard(dashboard));
});
} }
@Test @Test
@ -112,9 +110,8 @@ public class DashboardServiceTest extends AbstractServiceTest {
dashboard.setTenantId(tenantId); dashboard.setTenantId(tenantId);
Dashboard savedDashboard = dashboardService.saveDashboard(dashboard); Dashboard savedDashboard = dashboardService.saveDashboard(dashboard);
try { try {
Assertions.assertThrows(DataValidationException.class, () -> { Assertions.assertThrows(DataValidationException.class, () ->
dashboardService.assignDashboardToCustomer(tenantId, savedDashboard.getId(), new CustomerId(Uuids.timeBased())); dashboardService.assignDashboardToCustomer(tenantId, savedDashboard.getId(), new CustomerId(Uuids.timeBased())));
});
} finally { } finally {
dashboardService.deleteDashboard(tenantId, savedDashboard.getId()); dashboardService.deleteDashboard(tenantId, savedDashboard.getId());
} }
@ -221,7 +218,7 @@ public class DashboardServiceTest extends AbstractServiceTest {
List<DashboardInfo> loadedMobileDashboards = new ArrayList<>(); List<DashboardInfo> loadedMobileDashboards = new ArrayList<>();
PageLink pageLink = new PageLink(16, 0, null, new SortOrder("title", SortOrder.Direction.ASC)); PageLink pageLink = new PageLink(16, 0, null, new SortOrder("title", SortOrder.Direction.ASC));
PageData<DashboardInfo> pageData = null; PageData<DashboardInfo> pageData;
do { do {
pageData = dashboardService.findMobileDashboardsByTenantId(tenantId, pageLink); pageData = dashboardService.findMobileDashboardsByTenantId(tenantId, pageLink);
loadedMobileDashboards.addAll(pageData.getData()); loadedMobileDashboards.addAll(pageData.getData());
@ -235,7 +232,7 @@ public class DashboardServiceTest extends AbstractServiceTest {
Integer order2 = o2.getMobileOrder(); Integer order2 = o2.getMobileOrder();
if (order1 == null && order2 == null) { if (order1 == null && order2 == null) {
return o1.getTitle().compareTo(o2.getTitle()); return o1.getTitle().compareTo(o2.getTitle());
} else if (order1 == null && order2 != null) { } else if (order1 == null) {
return 1; return 1;
} else if (order2 == null) { } else if (order2 == null) {
return -1; return -1;
@ -403,9 +400,8 @@ public class DashboardServiceTest extends AbstractServiceTest {
edge.setRoutingKey(StringUtils.randomAlphanumeric(20)); edge.setRoutingKey(StringUtils.randomAlphanumeric(20));
Edge savedEdge = edgeService.saveEdge(edge); Edge savedEdge = edgeService.saveEdge(edge);
try { try {
Assertions.assertThrows(DataValidationException.class, () -> { Assertions.assertThrows(DataValidationException.class, () ->
dashboardService.assignDashboardToEdge(tenantId, savedDashboard.getId(), savedEdge.getId()); dashboardService.assignDashboardToEdge(tenantId, savedDashboard.getId(), savedEdge.getId()));
});
} finally { } finally {
dashboardService.deleteDashboard(tenantId, savedDashboard.getId()); dashboardService.deleteDashboard(tenantId, savedDashboard.getId());
tenantService.deleteTenant(tenant.getId()); tenantService.deleteTenant(tenant.getId());

13
dao/src/test/java/org/thingsboard/server/dao/service/timeseries/BaseTimeseriesServiceTest.java

@ -47,6 +47,7 @@ import org.thingsboard.server.dao.timeseries.TimeseriesService;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.Collections; import java.util.Collections;
import java.util.Comparator;
import java.util.List; import java.util.List;
import java.util.concurrent.ExecutionException; import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
@ -116,18 +117,18 @@ public abstract class BaseTimeseriesServiceTest extends AbstractServiceTest {
assertNotNull(tsList); assertNotNull(tsList);
assertEquals(4, tsList.size()); assertEquals(4, tsList.size());
for (int i = 0; i < tsList.size(); i++) { for (TsKvEntry entry : tsList) {
assertEquals(TS, tsList.get(i).getTs()); assertEquals(TS, entry.getTs());
} }
Collections.sort(tsList, (o1, o2) -> o1.getKey().compareTo(o2.getKey())); Collections.sort(tsList, Comparator.comparing(KvEntry::getKey));
List<TsKvEntry> expected = Arrays.asList( List<TsKvEntry> expected = Arrays.asList(
toTsEntry(TS, stringKvEntry), toTsEntry(TS, stringKvEntry),
toTsEntry(TS, longKvEntry), toTsEntry(TS, longKvEntry),
toTsEntry(TS, doubleKvEntry), toTsEntry(TS, doubleKvEntry),
toTsEntry(TS, booleanKvEntry)); toTsEntry(TS, booleanKvEntry));
Collections.sort(expected, (o1, o2) -> o1.getKey().compareTo(o2.getKey())); Collections.sort(expected, Comparator.comparing(KvEntry::getKey));
assertEquals(expected, tsList); assertEquals(expected, tsList);
} }
@ -187,7 +188,7 @@ public abstract class BaseTimeseriesServiceTest extends AbstractServiceTest {
Assert.assertEquals(toTsEntry(TS - 2, stringKvEntry), entries.get(1)); Assert.assertEquals(toTsEntry(TS - 2, stringKvEntry), entries.get(1));
Assert.assertEquals(toTsEntry(TS - 1, stringKvEntry), entries.get(2)); Assert.assertEquals(toTsEntry(TS - 1, stringKvEntry), entries.get(2));
EntityView entityView = saveAndCreateEntityView(deviceId, Arrays.asList(STRING_KEY)); EntityView entityView = saveAndCreateEntityView(deviceId, List.of(STRING_KEY));
entries = tsService.findAll(tenantId, entityView.getId(), queries).get(MAX_TIMEOUT, TimeUnit.SECONDS); entries = tsService.findAll(tenantId, entityView.getId(), queries).get(MAX_TIMEOUT, TimeUnit.SECONDS);
Assert.assertEquals(3, entries.size()); Assert.assertEquals(3, entries.size());
@ -347,7 +348,7 @@ public abstract class BaseTimeseriesServiceTest extends AbstractServiceTest {
Assert.assertEquals(toTsEntry(TS - 2, stringKvEntry), entries.get(1)); Assert.assertEquals(toTsEntry(TS - 2, stringKvEntry), entries.get(1));
Assert.assertEquals(toTsEntry(TS - 3, stringKvEntry), entries.get(2)); Assert.assertEquals(toTsEntry(TS - 3, stringKvEntry), entries.get(2));
EntityView entityView = saveAndCreateEntityView(deviceId, Arrays.asList(STRING_KEY)); EntityView entityView = saveAndCreateEntityView(deviceId, List.of(STRING_KEY));
entries = tsService.findAll(tenantId, entityView.getId(), queries).get(MAX_TIMEOUT, TimeUnit.SECONDS); entries = tsService.findAll(tenantId, entityView.getId(), queries).get(MAX_TIMEOUT, TimeUnit.SECONDS);
Assert.assertEquals(3, entries.size()); Assert.assertEquals(3, entries.size());

3
rule-engine/rule-engine-api/src/main/java/org/thingsboard/rule/engine/api/TbContext.java

@ -31,7 +31,6 @@ import org.thingsboard.server.common.data.asset.AssetProfile;
import org.thingsboard.server.common.data.id.AssetId; import org.thingsboard.server.common.data.id.AssetId;
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.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.RuleNodeId; import org.thingsboard.server.common.data.id.RuleNodeId;
@ -236,8 +235,6 @@ public interface TbContext {
TbMsg attributesDeletedActionMsg(EntityId originator, RuleNodeId ruleNodeId, String scope, List<String> keys); TbMsg attributesDeletedActionMsg(EntityId originator, RuleNodeId ruleNodeId, String scope, List<String> keys);
void onEdgeEventUpdate(TenantId tenantId, EdgeId edgeId);
/* /*
* *
* METHODS TO PROCESS THE MESSAGES * METHODS TO PROCESS THE MESSAGES

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

Loading…
Cancel
Save