Browse Source

Merge pull request #10548 from AndriiLandiak/feature/edge-notification

Edge - notification support
pull/10579/head
Volodymyr Babak 2 years ago
committed by GitHub
parent
commit
63c100b4bb
No known key found for this signature in database GPG Key ID: B5690EEEBB952194
  1. 98
      application/src/main/java/org/thingsboard/server/service/edge/DefaultEdgeNotificationService.java
  2. 16
      application/src/main/java/org/thingsboard/server/service/edge/EdgeContextComponent.java
  3. 6
      application/src/main/java/org/thingsboard/server/service/edge/rpc/EdgeGrpcSession.java
  4. 7
      application/src/main/java/org/thingsboard/server/service/edge/rpc/EdgeSyncCursor.java
  5. 1
      application/src/main/java/org/thingsboard/server/service/edge/rpc/constructor/dashboard/BaseDashboardMsgConstructor.java
  6. 1
      application/src/main/java/org/thingsboard/server/service/edge/rpc/constructor/dashboard/DashboardMsgConstructor.java
  7. 1
      application/src/main/java/org/thingsboard/server/service/edge/rpc/constructor/dashboard/DashboardMsgConstructorV2.java
  8. 1
      application/src/main/java/org/thingsboard/server/service/edge/rpc/constructor/device/DeviceMsgConstructor.java
  9. 1
      application/src/main/java/org/thingsboard/server/service/edge/rpc/constructor/device/DeviceMsgConstructorV2.java
  10. 1
      application/src/main/java/org/thingsboard/server/service/edge/rpc/constructor/edge/EdgeMsgConstructor.java
  11. 1
      application/src/main/java/org/thingsboard/server/service/edge/rpc/constructor/entityview/BaseEntityViewMsgConstructor.java
  12. 1
      application/src/main/java/org/thingsboard/server/service/edge/rpc/constructor/entityview/EntityViewMsgConstructor.java
  13. 14
      application/src/main/java/org/thingsboard/server/service/edge/rpc/constructor/entityview/EntityViewMsgConstructorV1.java
  14. 1
      application/src/main/java/org/thingsboard/server/service/edge/rpc/constructor/entityview/EntityViewMsgConstructorV2.java
  15. 43
      application/src/main/java/org/thingsboard/server/service/edge/rpc/constructor/notification/NotificationMsgConstructor.java
  16. 75
      application/src/main/java/org/thingsboard/server/service/edge/rpc/constructor/notification/NotificationMsgConstructorImpl.java
  17. 1
      application/src/main/java/org/thingsboard/server/service/edge/rpc/fetch/AdminSettingsEdgeEventFetcher.java
  18. 3
      application/src/main/java/org/thingsboard/server/service/edge/rpc/fetch/AssetProfilesEdgeEventFetcher.java
  19. 2
      application/src/main/java/org/thingsboard/server/service/edge/rpc/fetch/AssetsEdgeEventFetcher.java
  20. 11
      application/src/main/java/org/thingsboard/server/service/edge/rpc/fetch/BasePageableEdgeEventFetcher.java
  21. 3
      application/src/main/java/org/thingsboard/server/service/edge/rpc/fetch/BaseUsersEdgeEventFetcher.java
  22. 6
      application/src/main/java/org/thingsboard/server/service/edge/rpc/fetch/BaseWidgetTypesEdgeEventFetcher.java
  23. 3
      application/src/main/java/org/thingsboard/server/service/edge/rpc/fetch/BaseWidgetsBundlesEdgeEventFetcher.java
  24. 1
      application/src/main/java/org/thingsboard/server/service/edge/rpc/fetch/CustomerEdgeEventFetcher.java
  25. 1
      application/src/main/java/org/thingsboard/server/service/edge/rpc/fetch/CustomerUsersEdgeEventFetcher.java
  26. 3
      application/src/main/java/org/thingsboard/server/service/edge/rpc/fetch/DashboardsEdgeEventFetcher.java
  27. 3
      application/src/main/java/org/thingsboard/server/service/edge/rpc/fetch/DefaultProfilesEdgeEventFetcher.java
  28. 3
      application/src/main/java/org/thingsboard/server/service/edge/rpc/fetch/DeviceProfilesEdgeEventFetcher.java
  29. 3
      application/src/main/java/org/thingsboard/server/service/edge/rpc/fetch/DevicesEdgeEventFetcher.java
  30. 1
      application/src/main/java/org/thingsboard/server/service/edge/rpc/fetch/EdgeEventFetcher.java
  31. 3
      application/src/main/java/org/thingsboard/server/service/edge/rpc/fetch/EntityViewsEdgeEventFetcher.java
  32. 1
      application/src/main/java/org/thingsboard/server/service/edge/rpc/fetch/GeneralEdgeEventFetcher.java
  33. 48
      application/src/main/java/org/thingsboard/server/service/edge/rpc/fetch/NotificationRuleEdgeEventFetcher.java
  34. 48
      application/src/main/java/org/thingsboard/server/service/edge/rpc/fetch/NotificationTargetEdgeEventFetcher.java
  35. 51
      application/src/main/java/org/thingsboard/server/service/edge/rpc/fetch/NotificationTemplateEdgeEventFetcher.java
  36. 3
      application/src/main/java/org/thingsboard/server/service/edge/rpc/fetch/OtaPackagesEdgeEventFetcher.java
  37. 3
      application/src/main/java/org/thingsboard/server/service/edge/rpc/fetch/QueuesEdgeEventFetcher.java
  38. 3
      application/src/main/java/org/thingsboard/server/service/edge/rpc/fetch/RuleChainsEdgeEventFetcher.java
  39. 3
      application/src/main/java/org/thingsboard/server/service/edge/rpc/fetch/TenantEdgeEventFetcher.java
  40. 3
      application/src/main/java/org/thingsboard/server/service/edge/rpc/fetch/TenantResourcesEdgeEventFetcher.java
  41. 62
      application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/BaseEdgeProcessor.java
  42. 16
      application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/BaseEdgeProcessorFactory.java
  43. 1
      application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/alarm/AlarmEdgeProcessor.java
  44. 17
      application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/alarm/AlarmEdgeProcessorV1.java
  45. 1
      application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/alarm/AlarmEdgeProcessorV2.java
  46. 1
      application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/alarm/AlarmProcessor.java
  47. 24
      application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/alarm/BaseAlarmProcessor.java
  48. 14
      application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/asset/AssetEdgeProcessor.java
  49. 1
      application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/asset/AssetEdgeProcessorV1.java
  50. 1
      application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/asset/AssetEdgeProcessorV2.java
  51. 1
      application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/asset/AssetProcessor.java
  52. 1
      application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/asset/BaseAssetProcessor.java
  53. 10
      application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/asset/profile/AssetProfileEdgeProcessor.java
  54. 10
      application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/customer/CustomerEdgeProcessor.java
  55. 14
      application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/dashboard/DashboardEdgeProcessor.java
  56. 1
      application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/device/DeviceEdgeProcessor.java
  57. 10
      application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/device/profile/DeviceProfileEdgeProcessor.java
  58. 6
      application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/edge/EdgeProcessor.java
  59. 1
      application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/entityview/BaseEntityViewProcessor.java
  60. 14
      application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/entityview/EntityViewEdgeProcessor.java
  61. 1
      application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/entityview/EntityViewProcessor.java
  62. 1
      application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/entityview/EntityViewProcessorV1.java
  63. 1
      application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/entityview/EntityViewProcessorV2.java
  64. 119
      application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/notification/NotificationEdgeProcessor.java
  65. 10
      application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/ota/OtaPackageEdgeProcessor.java
  66. 10
      application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/queue/QueueEdgeProcessor.java
  67. 1
      application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/relation/BaseRelationProcessor.java
  68. 1
      application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/relation/RelationEdgeProcessor.java
  69. 1
      application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/relation/RelationEdgeProcessorV1.java
  70. 1
      application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/relation/RelationEdgeProcessorV2.java
  71. 1
      application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/relation/RelationProcessor.java
  72. 1
      application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/resource/BaseResourceProcessor.java
  73. 10
      application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/resource/ResourceEdgeProcessor.java
  74. 1
      application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/resource/ResourceEdgeProcessorV1.java
  75. 1
      application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/resource/ResourceEdgeProcessorV2.java
  76. 1
      application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/resource/ResourceProcessor.java
  77. 23
      application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/rule/RuleChainEdgeProcessor.java
  78. 1
      application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/settings/AdminSettingsEdgeProcessor.java
  79. 20
      application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/telemetry/BaseTelemetryProcessor.java
  80. 1
      application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/tenant/TenantProfileEdgeProcessor.java
  81. 20
      application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/user/UserEdgeProcessor.java
  82. 10
      application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/widget/WidgetBundleEdgeProcessor.java
  83. 10
      application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/widget/WidgetTypeEdgeProcessor.java
  84. 7
      application/src/main/java/org/thingsboard/server/service/edge/rpc/sync/DefaultEdgeRequestsService.java
  85. 13
      application/src/main/java/org/thingsboard/server/service/notification/DefaultNotificationCenter.java
  86. 290
      application/src/test/java/org/thingsboard/server/edge/NotificationEdgeTest.java
  87. 28
      application/src/test/java/org/thingsboard/server/edge/imitator/EdgeImitator.java
  88. 20
      application/src/test/java/org/thingsboard/server/service/edge/rpc/processor/BaseEdgeProcessorTest.java
  89. 3
      common/data/src/main/java/org/thingsboard/server/common/data/edge/EdgeEventType.java
  90. 6
      common/data/src/main/java/org/thingsboard/server/common/data/id/EntityIdFactory.java
  91. 24
      common/edge-api/src/main/proto/edge.proto
  92. 21
      dao/src/main/java/org/thingsboard/server/dao/notification/DefaultNotificationTargetService.java
  93. 8
      dao/src/main/java/org/thingsboard/server/dao/notification/DefaultNotificationTemplateService.java

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

@ -16,6 +16,8 @@
package org.thingsboard.server.service.edge;
import com.fasterxml.jackson.databind.node.ObjectNode;
import jakarta.annotation.PostConstruct;
import jakarta.annotation.PreDestroy;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
@ -42,6 +44,7 @@ import org.thingsboard.server.service.edge.rpc.processor.device.DeviceEdgeProces
import org.thingsboard.server.service.edge.rpc.processor.device.profile.DeviceProfileEdgeProcessor;
import org.thingsboard.server.service.edge.rpc.processor.edge.EdgeProcessor;
import org.thingsboard.server.service.edge.rpc.processor.entityview.EntityViewEdgeProcessor;
import org.thingsboard.server.service.edge.rpc.processor.notification.NotificationEdgeProcessor;
import org.thingsboard.server.service.edge.rpc.processor.oauth2.OAuth2EdgeProcessor;
import org.thingsboard.server.service.edge.rpc.processor.ota.OtaPackageEdgeProcessor;
import org.thingsboard.server.service.edge.rpc.processor.queue.QueueEdgeProcessor;
@ -54,8 +57,6 @@ import org.thingsboard.server.service.edge.rpc.processor.user.UserEdgeProcessor;
import org.thingsboard.server.service.edge.rpc.processor.widget.WidgetBundleEdgeProcessor;
import org.thingsboard.server.service.edge.rpc.processor.widget.WidgetTypeEdgeProcessor;
import jakarta.annotation.PostConstruct;
import jakarta.annotation.PreDestroy;
import java.util.UUID;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.TimeUnit;
@ -127,6 +128,9 @@ public class DefaultEdgeNotificationService implements EdgeNotificationService {
@Autowired
private ResourceEdgeProcessor resourceEdgeProcessor;
@Autowired
private NotificationEdgeProcessor notificationEdgeProcessor;
@Autowired
private OAuth2EdgeProcessor oAuth2EdgeProcessor;
@ -175,71 +179,30 @@ public class DefaultEdgeNotificationService implements EdgeNotificationService {
}
EdgeEventType type = EdgeEventType.valueOf(edgeNotificationMsg.getType());
switch (type) {
case EDGE:
edgeProcessor.processEdgeNotification(tenantId, edgeNotificationMsg);
break;
case ASSET:
assetProcessor.processEntityNotification(tenantId, edgeNotificationMsg);
break;
case ASSET_PROFILE:
assetProfileEdgeProcessor.processEntityNotification(tenantId, edgeNotificationMsg);
break;
case DEVICE:
deviceProcessor.processEntityNotification(tenantId, edgeNotificationMsg);
break;
case DEVICE_PROFILE:
deviceProfileEdgeProcessor.processEntityNotification(tenantId, edgeNotificationMsg);
break;
case ENTITY_VIEW:
entityViewProcessor.processEntityNotification(tenantId, edgeNotificationMsg);
break;
case DASHBOARD:
dashboardProcessor.processEntityNotification(tenantId, edgeNotificationMsg);
break;
case RULE_CHAIN:
ruleChainProcessor.processEntityNotification(tenantId, edgeNotificationMsg);
break;
case USER:
userProcessor.processEntityNotification(tenantId, edgeNotificationMsg);
break;
case CUSTOMER:
customerProcessor.processCustomerNotification(tenantId, edgeNotificationMsg);
break;
case OTA_PACKAGE:
otaPackageProcessor.processEntityNotification(tenantId, edgeNotificationMsg);
break;
case WIDGETS_BUNDLE:
widgetBundleProcessor.processEntityNotification(tenantId, edgeNotificationMsg);
break;
case WIDGET_TYPE:
widgetTypeProcessor.processEntityNotification(tenantId, edgeNotificationMsg);
break;
case QUEUE:
queueProcessor.processEntityNotification(tenantId, edgeNotificationMsg);
break;
case ALARM:
alarmProcessor.processAlarmNotification(tenantId, edgeNotificationMsg);
break;
case ALARM_COMMENT:
alarmProcessor.processAlarmCommentNotification(tenantId, edgeNotificationMsg);
break;
case RELATION:
relationProcessor.processRelationNotification(tenantId, edgeNotificationMsg);
break;
case TENANT:
tenantEdgeProcessor.processEntityNotification(tenantId, edgeNotificationMsg);
break;
case TENANT_PROFILE:
tenantProfileEdgeProcessor.processEntityNotification(tenantId, edgeNotificationMsg);
break;
case TB_RESOURCE:
resourceEdgeProcessor.processEntityNotification(tenantId, edgeNotificationMsg);
break;
case OAUTH2:
oAuth2EdgeProcessor.processOAuth2Notification(tenantId, edgeNotificationMsg);
break;
default:
log.warn("[{}] Edge event type [{}] is not designed to be pushed to edge", tenantId, type);
case EDGE -> edgeProcessor.processEdgeNotification(tenantId, edgeNotificationMsg);
case ASSET -> assetProcessor.processEntityNotification(tenantId, edgeNotificationMsg);
case ASSET_PROFILE -> assetProfileEdgeProcessor.processEntityNotification(tenantId, edgeNotificationMsg);
case DEVICE -> deviceProcessor.processEntityNotification(tenantId, edgeNotificationMsg);
case DEVICE_PROFILE -> deviceProfileEdgeProcessor.processEntityNotification(tenantId, edgeNotificationMsg);
case ENTITY_VIEW -> entityViewProcessor.processEntityNotification(tenantId, edgeNotificationMsg);
case DASHBOARD -> dashboardProcessor.processEntityNotification(tenantId, edgeNotificationMsg);
case RULE_CHAIN -> ruleChainProcessor.processEntityNotification(tenantId, edgeNotificationMsg);
case USER -> userProcessor.processEntityNotification(tenantId, edgeNotificationMsg);
case CUSTOMER -> customerProcessor.processCustomerNotification(tenantId, edgeNotificationMsg);
case OTA_PACKAGE -> otaPackageProcessor.processEntityNotification(tenantId, edgeNotificationMsg);
case WIDGETS_BUNDLE -> widgetBundleProcessor.processEntityNotification(tenantId, edgeNotificationMsg);
case WIDGET_TYPE -> widgetTypeProcessor.processEntityNotification(tenantId, edgeNotificationMsg);
case QUEUE -> queueProcessor.processEntityNotification(tenantId, edgeNotificationMsg);
case ALARM -> alarmProcessor.processAlarmNotification(tenantId, edgeNotificationMsg);
case ALARM_COMMENT -> alarmProcessor.processAlarmCommentNotification(tenantId, edgeNotificationMsg);
case RELATION -> relationProcessor.processRelationNotification(tenantId, edgeNotificationMsg);
case TENANT -> tenantEdgeProcessor.processEntityNotification(tenantId, edgeNotificationMsg);
case TENANT_PROFILE -> tenantProfileEdgeProcessor.processEntityNotification(tenantId, edgeNotificationMsg);
case NOTIFICATION_RULE, NOTIFICATION_TARGET, NOTIFICATION_TEMPLATE ->
notificationEdgeProcessor.processEntityNotification(tenantId, edgeNotificationMsg);
case TB_RESOURCE -> resourceEdgeProcessor.processEntityNotification(tenantId, edgeNotificationMsg);
case OAUTH2 -> oAuth2EdgeProcessor.processOAuth2Notification(tenantId, edgeNotificationMsg);
default -> log.warn("[{}] Edge event type [{}] is not designed to be pushed to edge", tenantId, type);
}
} catch (Exception e) {
callBackFailure(tenantId, edgeNotificationMsg, callback, e);
@ -255,4 +218,5 @@ public class DefaultEdgeNotificationService implements EdgeNotificationService {
log.error("[{}] Can't push to edge updates, edgeNotificationMsg [{}]", tenantId, edgeNotificationMsg, throwable);
callback.onFailure(throwable);
}
}

16
application/src/main/java/org/thingsboard/server/service/edge/EdgeContextComponent.java

@ -32,6 +32,9 @@ import org.thingsboard.server.dao.device.DeviceService;
import org.thingsboard.server.dao.edge.EdgeEventService;
import org.thingsboard.server.dao.edge.EdgeService;
import org.thingsboard.server.dao.entityview.EntityViewService;
import org.thingsboard.server.dao.notification.NotificationRuleService;
import org.thingsboard.server.dao.notification.NotificationTargetService;
import org.thingsboard.server.dao.notification.NotificationTemplateService;
import org.thingsboard.server.dao.oauth2.OAuth2Service;
import org.thingsboard.server.dao.ota.OtaPackageService;
import org.thingsboard.server.dao.queue.QueueService;
@ -62,6 +65,7 @@ import org.thingsboard.server.service.edge.rpc.processor.device.profile.DevicePr
import org.thingsboard.server.service.edge.rpc.processor.edge.EdgeProcessor;
import org.thingsboard.server.service.edge.rpc.processor.entityview.EntityViewEdgeProcessor;
import org.thingsboard.server.service.edge.rpc.processor.entityview.EntityViewProcessorFactory;
import org.thingsboard.server.service.edge.rpc.processor.notification.NotificationEdgeProcessor;
import org.thingsboard.server.service.edge.rpc.processor.oauth2.OAuth2EdgeProcessor;
import org.thingsboard.server.service.edge.rpc.processor.ota.OtaPackageEdgeProcessor;
import org.thingsboard.server.service.edge.rpc.processor.queue.QueueEdgeProcessor;
@ -153,6 +157,15 @@ public class EdgeContextComponent {
@Autowired
private ResourceService resourceService;
@Autowired
private NotificationRuleService notificationRuleService;
@Autowired
private NotificationTargetService notificationTargetService;
@Autowired
private NotificationTemplateService notificationTemplateService;
@Autowired
private OAuth2Service oAuth2Service;
@ -225,6 +238,9 @@ public class EdgeContextComponent {
@Autowired
private ResourceEdgeProcessor resourceEdgeProcessor;
@Autowired
private NotificationEdgeProcessor notificationEdgeProcessor;
@Autowired
private OAuth2EdgeProcessor oAuth2EdgeProcessor;

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

@ -683,6 +683,12 @@ public final class EdgeGrpcSession implements Closeable {
return ctx.getTenantEdgeProcessor().convertTenantEventToDownlink(edgeEvent, this.edgeVersion);
case TENANT_PROFILE:
return ctx.getTenantProfileEdgeProcessor().convertTenantProfileEventToDownlink(edgeEvent, this.edgeVersion);
case NOTIFICATION_RULE:
return ctx.getNotificationEdgeProcessor().convertNotificationRuleToDownlink(edgeEvent);
case NOTIFICATION_TARGET:
return ctx.getNotificationEdgeProcessor().convertNotificationTargetToDownlink(edgeEvent);
case NOTIFICATION_TEMPLATE:
return ctx.getNotificationEdgeProcessor().convertNotificationTemplateToDownlink(edgeEvent);
case OAUTH2:
return ctx.getOAuth2EdgeProcessor().convertOAuth2EventToDownlink(edgeEvent);
default:

7
application/src/main/java/org/thingsboard/server/service/edge/rpc/EdgeSyncCursor.java

@ -30,6 +30,9 @@ import org.thingsboard.server.service.edge.rpc.fetch.DeviceProfilesEdgeEventFetc
import org.thingsboard.server.service.edge.rpc.fetch.DevicesEdgeEventFetcher;
import org.thingsboard.server.service.edge.rpc.fetch.EdgeEventFetcher;
import org.thingsboard.server.service.edge.rpc.fetch.EntityViewsEdgeEventFetcher;
import org.thingsboard.server.service.edge.rpc.fetch.NotificationRuleEdgeEventFetcher;
import org.thingsboard.server.service.edge.rpc.fetch.NotificationTargetEdgeEventFetcher;
import org.thingsboard.server.service.edge.rpc.fetch.NotificationTemplateEdgeEventFetcher;
import org.thingsboard.server.service.edge.rpc.fetch.OAuth2EdgeEventFetcher;
import org.thingsboard.server.service.edge.rpc.fetch.OtaPackagesEdgeEventFetcher;
import org.thingsboard.server.service.edge.rpc.fetch.QueuesEdgeEventFetcher;
@ -74,6 +77,9 @@ public class EdgeSyncCursor {
fetchers.add(new AssetsEdgeEventFetcher(ctx.getAssetService()));
fetchers.add(new EntityViewsEdgeEventFetcher(ctx.getEntityViewService()));
if (fullSync) {
fetchers.add(new NotificationTemplateEdgeEventFetcher(ctx.getNotificationTemplateService()));
fetchers.add(new NotificationTargetEdgeEventFetcher(ctx.getNotificationTargetService()));
fetchers.add(new NotificationRuleEdgeEventFetcher(ctx.getNotificationRuleService()));
fetchers.add(new SystemWidgetTypesEdgeEventFetcher(ctx.getWidgetTypeService()));
fetchers.add(new TenantWidgetTypesEdgeEventFetcher(ctx.getWidgetTypeService()));
fetchers.add(new SystemWidgetsBundlesEdgeEventFetcher(ctx.getWidgetsBundleService()));
@ -100,4 +106,5 @@ public class EdgeSyncCursor {
public int getCurrentIdx() {
return currentIdx;
}
}

1
application/src/main/java/org/thingsboard/server/service/edge/rpc/constructor/dashboard/BaseDashboardMsgConstructor.java

@ -28,4 +28,5 @@ public abstract class BaseDashboardMsgConstructor implements DashboardMsgConstru
.setIdMSB(dashboardId.getId().getMostSignificantBits())
.setIdLSB(dashboardId.getId().getLeastSignificantBits()).build();
}
}

1
application/src/main/java/org/thingsboard/server/service/edge/rpc/constructor/dashboard/DashboardMsgConstructor.java

@ -26,4 +26,5 @@ public interface DashboardMsgConstructor extends MsgConstructor {
DashboardUpdateMsg constructDashboardUpdatedMsg(UpdateMsgType msgType, Dashboard dashboard);
DashboardUpdateMsg constructDashboardDeleteMsg(DashboardId dashboardId);
}

1
application/src/main/java/org/thingsboard/server/service/edge/rpc/constructor/dashboard/DashboardMsgConstructorV2.java

@ -32,4 +32,5 @@ public class DashboardMsgConstructorV2 extends BaseDashboardMsgConstructor {
.setIdMSB(dashboard.getId().getId().getMostSignificantBits())
.setIdLSB(dashboard.getId().getId().getLeastSignificantBits()).build();
}
}

1
application/src/main/java/org/thingsboard/server/service/edge/rpc/constructor/device/DeviceMsgConstructor.java

@ -43,4 +43,5 @@ public interface DeviceMsgConstructor extends MsgConstructor {
DeviceProfileUpdateMsg constructDeviceProfileDeleteMsg(DeviceProfileId deviceProfileId);
DeviceRpcCallMsg constructDeviceRpcCallMsg(UUID deviceId, JsonNode body);
}

1
application/src/main/java/org/thingsboard/server/service/edge/rpc/constructor/device/DeviceMsgConstructorV2.java

@ -48,4 +48,5 @@ public class DeviceMsgConstructorV2 extends BaseDeviceMsgConstructor {
.setIdMSB(deviceProfile.getId().getId().getMostSignificantBits())
.setIdLSB(deviceProfile.getId().getId().getLeastSignificantBits()).build();
}
}

1
application/src/main/java/org/thingsboard/server/service/edge/rpc/constructor/edge/EdgeMsgConstructor.java

@ -43,4 +43,5 @@ public class EdgeMsgConstructor {
}
return builder.build();
}
}

1
application/src/main/java/org/thingsboard/server/service/edge/rpc/constructor/entityview/BaseEntityViewMsgConstructor.java

@ -28,4 +28,5 @@ public abstract class BaseEntityViewMsgConstructor implements EntityViewMsgConst
.setIdMSB(entityViewId.getId().getMostSignificantBits())
.setIdLSB(entityViewId.getId().getLeastSignificantBits()).build();
}
}

1
application/src/main/java/org/thingsboard/server/service/edge/rpc/constructor/entityview/EntityViewMsgConstructor.java

@ -26,4 +26,5 @@ public interface EntityViewMsgConstructor extends MsgConstructor {
EntityViewUpdateMsg constructEntityViewUpdatedMsg(UpdateMsgType msgType, EntityView entityView);
EntityViewUpdateMsg constructEntityViewDeleteMsg(EntityViewId entityViewId);
}

14
application/src/main/java/org/thingsboard/server/service/edge/rpc/constructor/entityview/EntityViewMsgConstructorV1.java

@ -51,13 +51,11 @@ public class EntityViewMsgConstructorV1 extends BaseEntityViewMsgConstructor {
}
private EdgeEntityType checkEntityType(EntityType entityType) {
switch (entityType) {
case DEVICE:
return EdgeEntityType.DEVICE;
case ASSET:
return EdgeEntityType.ASSET;
default:
throw new RuntimeException("Unsupported entity type [" + entityType + "]");
}
return switch (entityType) {
case DEVICE -> EdgeEntityType.DEVICE;
case ASSET -> EdgeEntityType.ASSET;
default -> throw new RuntimeException("Unsupported entity type [" + entityType + "]");
};
}
}

1
application/src/main/java/org/thingsboard/server/service/edge/rpc/constructor/entityview/EntityViewMsgConstructorV2.java

@ -32,4 +32,5 @@ public class EntityViewMsgConstructorV2 extends BaseEntityViewMsgConstructor {
.setIdMSB(entityView.getId().getId().getMostSignificantBits())
.setIdLSB(entityView.getId().getId().getLeastSignificantBits()).build();
}
}

43
application/src/main/java/org/thingsboard/server/service/edge/rpc/constructor/notification/NotificationMsgConstructor.java

@ -0,0 +1,43 @@
/**
* 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.edge.rpc.constructor.notification;
import org.thingsboard.server.common.data.id.NotificationRuleId;
import org.thingsboard.server.common.data.id.NotificationTargetId;
import org.thingsboard.server.common.data.id.NotificationTemplateId;
import org.thingsboard.server.common.data.notification.rule.NotificationRule;
import org.thingsboard.server.common.data.notification.targets.NotificationTarget;
import org.thingsboard.server.common.data.notification.template.NotificationTemplate;
import org.thingsboard.server.gen.edge.v1.NotificationRuleUpdateMsg;
import org.thingsboard.server.gen.edge.v1.NotificationTargetUpdateMsg;
import org.thingsboard.server.gen.edge.v1.NotificationTemplateUpdateMsg;
import org.thingsboard.server.gen.edge.v1.UpdateMsgType;
public interface NotificationMsgConstructor {
NotificationRuleUpdateMsg constructNotificationRuleUpdateMsg(UpdateMsgType msgType, NotificationRule notificationRule);
NotificationRuleUpdateMsg constructNotificationRuleDeleteMsg(NotificationRuleId notificationRuleId);
NotificationTargetUpdateMsg constructNotificationTargetUpdateMsg(UpdateMsgType msgType, NotificationTarget notificationTarget);
NotificationTargetUpdateMsg constructNotificationTargetDeleteMsg(NotificationTargetId notificationTargetId);
NotificationTemplateUpdateMsg constructNotificationTemplateUpdateMsg(UpdateMsgType msgType, NotificationTemplate notificationTemplate);
NotificationTemplateUpdateMsg constructNotificationTemplateDeleteMsg(NotificationTemplateId notificationTemplateId);
}

75
application/src/main/java/org/thingsboard/server/service/edge/rpc/constructor/notification/NotificationMsgConstructorImpl.java

@ -0,0 +1,75 @@
/**
* 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.edge.rpc.constructor.notification;
import org.springframework.stereotype.Component;
import org.thingsboard.common.util.JacksonUtil;
import org.thingsboard.server.common.data.id.NotificationRuleId;
import org.thingsboard.server.common.data.id.NotificationTargetId;
import org.thingsboard.server.common.data.id.NotificationTemplateId;
import org.thingsboard.server.common.data.notification.rule.NotificationRule;
import org.thingsboard.server.common.data.notification.targets.NotificationTarget;
import org.thingsboard.server.common.data.notification.template.NotificationTemplate;
import org.thingsboard.server.gen.edge.v1.NotificationRuleUpdateMsg;
import org.thingsboard.server.gen.edge.v1.NotificationTargetUpdateMsg;
import org.thingsboard.server.gen.edge.v1.NotificationTemplateUpdateMsg;
import org.thingsboard.server.gen.edge.v1.UpdateMsgType;
import org.thingsboard.server.queue.util.TbCoreComponent;
@Component
@TbCoreComponent
public class NotificationMsgConstructorImpl implements NotificationMsgConstructor {
@Override
public NotificationRuleUpdateMsg constructNotificationRuleUpdateMsg(UpdateMsgType msgType, NotificationRule notificationRule) {
return NotificationRuleUpdateMsg.newBuilder().setMsgType(msgType).setEntity(JacksonUtil.toString(notificationRule)).build();
}
@Override
public NotificationRuleUpdateMsg constructNotificationRuleDeleteMsg(NotificationRuleId notificationRuleId) {
return NotificationRuleUpdateMsg.newBuilder()
.setMsgType(UpdateMsgType.ENTITY_DELETED_RPC_MESSAGE)
.setIdMSB(notificationRuleId.getId().getMostSignificantBits())
.setIdLSB(notificationRuleId.getId().getLeastSignificantBits()).build();
}
@Override
public NotificationTargetUpdateMsg constructNotificationTargetUpdateMsg(UpdateMsgType msgType, NotificationTarget notificationTarget) {
return NotificationTargetUpdateMsg.newBuilder().setMsgType(msgType).setEntity(JacksonUtil.toString(notificationTarget)).build();
}
@Override
public NotificationTargetUpdateMsg constructNotificationTargetDeleteMsg(NotificationTargetId notificationTargetId) {
return NotificationTargetUpdateMsg.newBuilder()
.setMsgType(UpdateMsgType.ENTITY_DELETED_RPC_MESSAGE)
.setIdMSB(notificationTargetId.getId().getMostSignificantBits())
.setIdLSB(notificationTargetId.getId().getLeastSignificantBits()).build();
}
@Override
public NotificationTemplateUpdateMsg constructNotificationTemplateUpdateMsg(UpdateMsgType msgType, NotificationTemplate notificationTemplate) {
return NotificationTemplateUpdateMsg.newBuilder().setMsgType(msgType).setEntity(JacksonUtil.toString(notificationTemplate)).build();
}
@Override
public NotificationTemplateUpdateMsg constructNotificationTemplateDeleteMsg(NotificationTemplateId notificationTemplateId) {
return NotificationTemplateUpdateMsg.newBuilder()
.setMsgType(UpdateMsgType.ENTITY_DELETED_RPC_MESSAGE)
.setIdMSB(notificationTemplateId.getId().getMostSignificantBits())
.setIdLSB(notificationTemplateId.getId().getLeastSignificantBits()).build();
}
}

1
application/src/main/java/org/thingsboard/server/service/edge/rpc/fetch/AdminSettingsEdgeEventFetcher.java

@ -62,4 +62,5 @@ public class AdminSettingsEdgeEventFetcher implements EdgeEventFetcher {
}
return result;
}
}

3
application/src/main/java/org/thingsboard/server/service/edge/rpc/fetch/AssetProfilesEdgeEventFetcher.java

@ -35,7 +35,7 @@ public class AssetProfilesEdgeEventFetcher extends BasePageableEdgeEventFetcher<
private final AssetProfileService assetProfileService;
@Override
PageData<AssetProfile> fetchPageData(TenantId tenantId, Edge edge, PageLink pageLink) {
PageData<AssetProfile> fetchEntities(TenantId tenantId, Edge edge, PageLink pageLink) {
return assetProfileService.findAssetProfiles(tenantId, pageLink);
}
@ -44,4 +44,5 @@ public class AssetProfilesEdgeEventFetcher extends BasePageableEdgeEventFetcher<
return EdgeUtils.constructEdgeEvent(tenantId, edge.getId(), EdgeEventType.ASSET_PROFILE,
EdgeEventActionType.ADDED, assetProfile.getId(), null);
}
}

2
application/src/main/java/org/thingsboard/server/service/edge/rpc/fetch/AssetsEdgeEventFetcher.java

@ -35,7 +35,7 @@ public class AssetsEdgeEventFetcher extends BasePageableEdgeEventFetcher<Asset>
private final AssetService assetService;
@Override
PageData<Asset> fetchPageData(TenantId tenantId, Edge edge, PageLink pageLink) {
PageData<Asset> fetchEntities(TenantId tenantId, Edge edge, PageLink pageLink) {
return assetService.findAssetsByTenantIdAndEdgeId(tenantId, edge.getId(), pageLink);
}

11
application/src/main/java/org/thingsboard/server/service/edge/rpc/fetch/BasePageableEdgeEventFetcher.java

@ -36,17 +36,18 @@ public abstract class BasePageableEdgeEventFetcher<T> implements EdgeEventFetche
@Override
public PageData<EdgeEvent> fetchEdgeEvents(TenantId tenantId, Edge edge, PageLink pageLink) {
log.trace("[{}] start fetching edge events [{}]", tenantId, edge.getId());
PageData<T> pageData = fetchPageData(tenantId, edge, pageLink);
PageData<T> entities = fetchEntities(tenantId, edge, pageLink);
List<EdgeEvent> result = new ArrayList<>();
if (!pageData.getData().isEmpty()) {
for (T entity : pageData.getData()) {
if (!entities.getData().isEmpty()) {
for (T entity : entities.getData()) {
result.add(constructEdgeEvent(tenantId, edge, entity));
}
}
return new PageData<>(result, pageData.getTotalPages(), pageData.getTotalElements(), pageData.hasNext());
return new PageData<>(result, entities.getTotalPages(), entities.getTotalElements(), entities.hasNext());
}
abstract PageData<T> fetchPageData(TenantId tenantId, Edge edge, PageLink pageLink);
abstract PageData<T> fetchEntities(TenantId tenantId, Edge edge, PageLink pageLink);
abstract EdgeEvent constructEdgeEvent(TenantId tenantId, Edge edge, T entity);
}

3
application/src/main/java/org/thingsboard/server/service/edge/rpc/fetch/BaseUsersEdgeEventFetcher.java

@ -35,7 +35,7 @@ public abstract class BaseUsersEdgeEventFetcher extends BasePageableEdgeEventFet
protected final UserService userService;
@Override
PageData<User> fetchPageData(TenantId tenantId, Edge edge, PageLink pageLink) {
PageData<User> fetchEntities(TenantId tenantId, Edge edge, PageLink pageLink) {
return findUsers(tenantId, pageLink);
}
@ -46,4 +46,5 @@ public abstract class BaseUsersEdgeEventFetcher extends BasePageableEdgeEventFet
}
protected abstract PageData<User> findUsers(TenantId tenantId, PageLink pageLink);
}

6
application/src/main/java/org/thingsboard/server/service/edge/rpc/fetch/BaseWidgetTypesEdgeEventFetcher.java

@ -25,11 +25,8 @@ import org.thingsboard.server.common.data.edge.EdgeEventType;
import org.thingsboard.server.common.data.id.TenantId;
import org.thingsboard.server.common.data.page.PageData;
import org.thingsboard.server.common.data.page.PageLink;
import org.thingsboard.server.common.data.widget.WidgetTypeDetails;
import org.thingsboard.server.common.data.widget.WidgetTypeInfo;
import org.thingsboard.server.common.data.widget.WidgetsBundle;
import org.thingsboard.server.dao.widget.WidgetTypeService;
import org.thingsboard.server.dao.widget.WidgetsBundleService;
@Slf4j
@AllArgsConstructor
@ -38,7 +35,7 @@ public abstract class BaseWidgetTypesEdgeEventFetcher extends BasePageableEdgeEv
protected final WidgetTypeService widgetTypeService;
@Override
PageData<WidgetTypeInfo> fetchPageData(TenantId tenantId, Edge edge, PageLink pageLink) {
PageData<WidgetTypeInfo> fetchEntities(TenantId tenantId, Edge edge, PageLink pageLink) {
return findWidgetTypes(tenantId, pageLink);
}
@ -49,4 +46,5 @@ public abstract class BaseWidgetTypesEdgeEventFetcher extends BasePageableEdgeEv
}
protected abstract PageData<WidgetTypeInfo> findWidgetTypes(TenantId tenantId, PageLink pageLink);
}

3
application/src/main/java/org/thingsboard/server/service/edge/rpc/fetch/BaseWidgetsBundlesEdgeEventFetcher.java

@ -35,7 +35,7 @@ public abstract class BaseWidgetsBundlesEdgeEventFetcher extends BasePageableEdg
protected final WidgetsBundleService widgetsBundleService;
@Override
PageData<WidgetsBundle> fetchPageData(TenantId tenantId, Edge edge, PageLink pageLink) {
PageData<WidgetsBundle> fetchEntities(TenantId tenantId, Edge edge, PageLink pageLink) {
return findWidgetsBundles(tenantId, pageLink);
}
@ -46,4 +46,5 @@ public abstract class BaseWidgetsBundlesEdgeEventFetcher extends BasePageableEdg
}
protected abstract PageData<WidgetsBundle> findWidgetsBundles(TenantId tenantId, PageLink pageLink);
}

1
application/src/main/java/org/thingsboard/server/service/edge/rpc/fetch/CustomerEdgeEventFetcher.java

@ -49,4 +49,5 @@ public class CustomerEdgeEventFetcher implements EdgeEventFetcher {
// returns PageData object to be in sync with other fetchers
return new PageData<>(result, 1, result.size(), false);
}
}

1
application/src/main/java/org/thingsboard/server/service/edge/rpc/fetch/CustomerUsersEdgeEventFetcher.java

@ -35,4 +35,5 @@ public class CustomerUsersEdgeEventFetcher extends BaseUsersEdgeEventFetcher {
protected PageData<User> findUsers(TenantId tenantId, PageLink pageLink) {
return userService.findCustomerUsers(tenantId, customerId, pageLink);
}
}

3
application/src/main/java/org/thingsboard/server/service/edge/rpc/fetch/DashboardsEdgeEventFetcher.java

@ -35,7 +35,7 @@ public class DashboardsEdgeEventFetcher extends BasePageableEdgeEventFetcher<Das
private final DashboardService dashboardService;
@Override
PageData<DashboardInfo> fetchPageData(TenantId tenantId, Edge edge, PageLink pageLink) {
PageData<DashboardInfo> fetchEntities(TenantId tenantId, Edge edge, PageLink pageLink) {
return dashboardService.findDashboardsByTenantIdAndEdgeId(tenantId, edge.getId(), pageLink);
}
@ -44,4 +44,5 @@ public class DashboardsEdgeEventFetcher extends BasePageableEdgeEventFetcher<Das
return EdgeUtils.constructEdgeEvent(tenantId, edge.getId(), EdgeEventType.DASHBOARD,
EdgeEventActionType.ADDED, dashboardInfo.getId(), null);
}
}

3
application/src/main/java/org/thingsboard/server/service/edge/rpc/fetch/DefaultProfilesEdgeEventFetcher.java

@ -59,4 +59,5 @@ public class DefaultProfilesEdgeEventFetcher implements EdgeEventFetcher {
return new PageData<>(result, 1, result.size(), false);
}
}
}

3
application/src/main/java/org/thingsboard/server/service/edge/rpc/fetch/DeviceProfilesEdgeEventFetcher.java

@ -35,7 +35,7 @@ public class DeviceProfilesEdgeEventFetcher extends BasePageableEdgeEventFetcher
private final DeviceProfileService deviceProfileService;
@Override
PageData<DeviceProfile> fetchPageData(TenantId tenantId, Edge edge, PageLink pageLink) {
PageData<DeviceProfile> fetchEntities(TenantId tenantId, Edge edge, PageLink pageLink) {
return deviceProfileService.findDeviceProfiles(tenantId, pageLink);
}
@ -44,4 +44,5 @@ public class DeviceProfilesEdgeEventFetcher extends BasePageableEdgeEventFetcher
return EdgeUtils.constructEdgeEvent(tenantId, edge.getId(), EdgeEventType.DEVICE_PROFILE,
EdgeEventActionType.ADDED, deviceProfile.getId(), null);
}
}

3
application/src/main/java/org/thingsboard/server/service/edge/rpc/fetch/DevicesEdgeEventFetcher.java

@ -35,7 +35,7 @@ public class DevicesEdgeEventFetcher extends BasePageableEdgeEventFetcher<Device
private final DeviceService deviceService;
@Override
PageData<Device> fetchPageData(TenantId tenantId, Edge edge, PageLink pageLink) {
PageData<Device> fetchEntities(TenantId tenantId, Edge edge, PageLink pageLink) {
return deviceService.findDevicesByTenantIdAndEdgeId(tenantId, edge.getId(), pageLink);
}
@ -44,4 +44,5 @@ public class DevicesEdgeEventFetcher extends BasePageableEdgeEventFetcher<Device
return EdgeUtils.constructEdgeEvent(tenantId, edge.getId(), EdgeEventType.DEVICE,
EdgeEventActionType.ADDED, device.getId(), null);
}
}

1
application/src/main/java/org/thingsboard/server/service/edge/rpc/fetch/EdgeEventFetcher.java

@ -26,4 +26,5 @@ public interface EdgeEventFetcher {
PageLink getPageLink(int pageSize);
PageData<EdgeEvent> fetchEdgeEvents(TenantId tenantId, Edge edge, PageLink pageLink) throws Exception;
}

3
application/src/main/java/org/thingsboard/server/service/edge/rpc/fetch/EntityViewsEdgeEventFetcher.java

@ -35,7 +35,7 @@ public class EntityViewsEdgeEventFetcher extends BasePageableEdgeEventFetcher<En
private final EntityViewService entityViewService;
@Override
PageData<EntityView> fetchPageData(TenantId tenantId, Edge edge, PageLink pageLink) {
PageData<EntityView> fetchEntities(TenantId tenantId, Edge edge, PageLink pageLink) {
return entityViewService.findEntityViewsByTenantIdAndEdgeId(tenantId, edge.getId(), pageLink);
}
@ -44,4 +44,5 @@ public class EntityViewsEdgeEventFetcher extends BasePageableEdgeEventFetcher<En
return EdgeUtils.constructEdgeEvent(tenantId, edge.getId(), EdgeEventType.ENTITY_VIEW,
EdgeEventActionType.ADDED, entityView.getId(), null);
}
}

1
application/src/main/java/org/thingsboard/server/service/edge/rpc/fetch/GeneralEdgeEventFetcher.java

@ -73,4 +73,5 @@ public class GeneralEdgeEventFetcher implements EdgeEventFetcher {
}
return new PageData<>();
}
}

48
application/src/main/java/org/thingsboard/server/service/edge/rpc/fetch/NotificationRuleEdgeEventFetcher.java

@ -0,0 +1,48 @@
/**
* 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.edge.rpc.fetch;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.thingsboard.server.common.data.EdgeUtils;
import org.thingsboard.server.common.data.edge.Edge;
import org.thingsboard.server.common.data.edge.EdgeEvent;
import org.thingsboard.server.common.data.edge.EdgeEventActionType;
import org.thingsboard.server.common.data.edge.EdgeEventType;
import org.thingsboard.server.common.data.id.TenantId;
import org.thingsboard.server.common.data.notification.rule.NotificationRule;
import org.thingsboard.server.common.data.page.PageData;
import org.thingsboard.server.common.data.page.PageLink;
import org.thingsboard.server.dao.notification.NotificationRuleService;
@AllArgsConstructor
@Slf4j
public class NotificationRuleEdgeEventFetcher extends BasePageableEdgeEventFetcher<NotificationRule>{
private NotificationRuleService notificationRuleService;
@Override
PageData<NotificationRule> fetchEntities(TenantId tenantId, Edge edge, PageLink pageLink) {
return notificationRuleService.findNotificationRulesByTenantId(tenantId, pageLink);
}
@Override
EdgeEvent constructEdgeEvent(TenantId tenantId, Edge edge, NotificationRule notificationRule) {
return EdgeUtils.constructEdgeEvent(tenantId, edge.getId(), EdgeEventType.NOTIFICATION_RULE,
EdgeEventActionType.ADDED, notificationRule.getId(), null);
}
}

48
application/src/main/java/org/thingsboard/server/service/edge/rpc/fetch/NotificationTargetEdgeEventFetcher.java

@ -0,0 +1,48 @@
/**
* 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.edge.rpc.fetch;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.thingsboard.server.common.data.EdgeUtils;
import org.thingsboard.server.common.data.edge.Edge;
import org.thingsboard.server.common.data.edge.EdgeEvent;
import org.thingsboard.server.common.data.edge.EdgeEventActionType;
import org.thingsboard.server.common.data.edge.EdgeEventType;
import org.thingsboard.server.common.data.id.TenantId;
import org.thingsboard.server.common.data.notification.targets.NotificationTarget;
import org.thingsboard.server.common.data.page.PageData;
import org.thingsboard.server.common.data.page.PageLink;
import org.thingsboard.server.dao.notification.NotificationTargetService;
@AllArgsConstructor
@Slf4j
public class NotificationTargetEdgeEventFetcher extends BasePageableEdgeEventFetcher<NotificationTarget> {
private NotificationTargetService notificationTargetService;
@Override
PageData<NotificationTarget> fetchEntities(TenantId tenantId, Edge edge, PageLink pageLink) {
return notificationTargetService.findNotificationTargetsByTenantId(tenantId, pageLink);
}
@Override
EdgeEvent constructEdgeEvent(TenantId tenantId, Edge edge, NotificationTarget notificationTarget) {
return EdgeUtils.constructEdgeEvent(tenantId, edge.getId(), EdgeEventType.NOTIFICATION_TARGET,
EdgeEventActionType.ADDED, notificationTarget.getId(), null);
}
}

51
application/src/main/java/org/thingsboard/server/service/edge/rpc/fetch/NotificationTemplateEdgeEventFetcher.java

@ -0,0 +1,51 @@
/**
* 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.edge.rpc.fetch;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.thingsboard.server.common.data.EdgeUtils;
import org.thingsboard.server.common.data.edge.Edge;
import org.thingsboard.server.common.data.edge.EdgeEvent;
import org.thingsboard.server.common.data.edge.EdgeEventActionType;
import org.thingsboard.server.common.data.edge.EdgeEventType;
import org.thingsboard.server.common.data.id.TenantId;
import org.thingsboard.server.common.data.notification.NotificationType;
import org.thingsboard.server.common.data.notification.template.NotificationTemplate;
import org.thingsboard.server.common.data.page.PageData;
import org.thingsboard.server.common.data.page.PageLink;
import org.thingsboard.server.dao.notification.NotificationTemplateService;
import java.util.List;
@AllArgsConstructor
@Slf4j
public class NotificationTemplateEdgeEventFetcher extends BasePageableEdgeEventFetcher<NotificationTemplate> {
private NotificationTemplateService notificationTemplateService;
@Override
PageData<NotificationTemplate> fetchEntities(TenantId tenantId, Edge edge, PageLink pageLink) {
return notificationTemplateService.findNotificationTemplatesByTenantIdAndNotificationTypes(tenantId, List.of(NotificationType.values()), pageLink);
}
@Override
EdgeEvent constructEdgeEvent(TenantId tenantId, Edge edge, NotificationTemplate notificationTemplate) {
return EdgeUtils.constructEdgeEvent(tenantId, edge.getId(), EdgeEventType.NOTIFICATION_TEMPLATE,
EdgeEventActionType.ADDED, notificationTemplate.getId(), null);
}
}

3
application/src/main/java/org/thingsboard/server/service/edge/rpc/fetch/OtaPackagesEdgeEventFetcher.java

@ -35,7 +35,7 @@ public class OtaPackagesEdgeEventFetcher extends BasePageableEdgeEventFetcher<Ot
private final OtaPackageService otaPackageService;
@Override
PageData<OtaPackageInfo> fetchPageData(TenantId tenantId, Edge edge, PageLink pageLink) {
PageData<OtaPackageInfo> fetchEntities(TenantId tenantId, Edge edge, PageLink pageLink) {
return otaPackageService.findTenantOtaPackagesByTenantId(tenantId, pageLink);
}
@ -44,4 +44,5 @@ public class OtaPackagesEdgeEventFetcher extends BasePageableEdgeEventFetcher<Ot
return EdgeUtils.constructEdgeEvent(tenantId, edge.getId(), EdgeEventType.OTA_PACKAGE,
EdgeEventActionType.ADDED, otaPackageInfo.getId(), null);
}
}

3
application/src/main/java/org/thingsboard/server/service/edge/rpc/fetch/QueuesEdgeEventFetcher.java

@ -35,7 +35,7 @@ public class QueuesEdgeEventFetcher extends BasePageableEdgeEventFetcher<Queue>
private final QueueService queueService;
@Override
PageData<Queue> fetchPageData(TenantId tenantId, Edge edge, PageLink pageLink) {
PageData<Queue> fetchEntities(TenantId tenantId, Edge edge, PageLink pageLink) {
return queueService.findQueuesByTenantId(tenantId, pageLink);
}
@ -44,4 +44,5 @@ public class QueuesEdgeEventFetcher extends BasePageableEdgeEventFetcher<Queue>
return EdgeUtils.constructEdgeEvent(tenantId, edge.getId(), EdgeEventType.QUEUE,
EdgeEventActionType.ADDED, queue.getId(), null);
}
}

3
application/src/main/java/org/thingsboard/server/service/edge/rpc/fetch/RuleChainsEdgeEventFetcher.java

@ -39,7 +39,7 @@ public class RuleChainsEdgeEventFetcher extends BasePageableEdgeEventFetcher<Rul
private final RuleChainService ruleChainService;
@Override
PageData<RuleChain> fetchPageData(TenantId tenantId, Edge edge, PageLink pageLink) {
PageData<RuleChain> fetchEntities(TenantId tenantId, Edge edge, PageLink pageLink) {
return ruleChainService.findRuleChainsByTenantIdAndEdgeId(tenantId, edge.getId(), pageLink);
}
@ -54,4 +54,5 @@ public class RuleChainsEdgeEventFetcher extends BasePageableEdgeEventFetcher<Rul
return EdgeUtils.constructEdgeEvent(tenantId, edge.getId(), EdgeEventType.RULE_CHAIN,
EdgeEventActionType.ADDED, ruleChain.getId(), isRootBody);
}
}

3
application/src/main/java/org/thingsboard/server/service/edge/rpc/fetch/TenantEdgeEventFetcher.java

@ -37,7 +37,7 @@ public class TenantEdgeEventFetcher extends BasePageableEdgeEventFetcher<Tenant>
private final TenantService tenantService;
@Override
PageData<Tenant> fetchPageData(TenantId tenantId, Edge edge, PageLink pageLink) {
PageData<Tenant> fetchEntities(TenantId tenantId, Edge edge, PageLink pageLink) {
Tenant tenant = tenantService.findTenantById(tenantId);
// returns PageData object to be in sync with other fetchers
return new PageData<>(List.of(tenant), 1, 1, false);
@ -48,4 +48,5 @@ public class TenantEdgeEventFetcher extends BasePageableEdgeEventFetcher<Tenant>
return EdgeUtils.constructEdgeEvent(tenantId, edge.getId(), EdgeEventType.TENANT,
EdgeEventActionType.UPDATED, entity.getId(), null);
}
}

3
application/src/main/java/org/thingsboard/server/service/edge/rpc/fetch/TenantResourcesEdgeEventFetcher.java

@ -35,7 +35,7 @@ public class TenantResourcesEdgeEventFetcher extends BasePageableEdgeEventFetche
private final ResourceService resourceService;
@Override
PageData<TbResource> fetchPageData(TenantId tenantId, Edge edge, PageLink pageLink) {
PageData<TbResource> fetchEntities(TenantId tenantId, Edge edge, PageLink pageLink) {
return resourceService.findAllTenantResources(tenantId, pageLink);
}
@ -44,4 +44,5 @@ public class TenantResourcesEdgeEventFetcher extends BasePageableEdgeEventFetche
return EdgeUtils.constructEdgeEvent(tenantId, edge.getId(), EdgeEventType.TB_RESOURCE,
EdgeEventActionType.ADDED, tbResource.getId(), null);
}
}

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

@ -73,6 +73,9 @@ import org.thingsboard.server.dao.edge.EdgeEventService;
import org.thingsboard.server.dao.edge.EdgeService;
import org.thingsboard.server.dao.edge.EdgeSynchronizationManager;
import org.thingsboard.server.dao.entityview.EntityViewService;
import org.thingsboard.server.dao.notification.NotificationRuleService;
import org.thingsboard.server.dao.notification.NotificationTargetService;
import org.thingsboard.server.dao.notification.NotificationTemplateService;
import org.thingsboard.server.dao.oauth2.OAuth2Service;
import org.thingsboard.server.dao.ota.OtaPackageService;
import org.thingsboard.server.dao.queue.QueueService;
@ -99,6 +102,7 @@ import org.thingsboard.server.service.edge.rpc.constructor.dashboard.DashboardMs
import org.thingsboard.server.service.edge.rpc.constructor.device.DeviceMsgConstructorFactory;
import org.thingsboard.server.service.edge.rpc.constructor.edge.EdgeMsgConstructor;
import org.thingsboard.server.service.edge.rpc.constructor.entityview.EntityViewMsgConstructorFactory;
import org.thingsboard.server.service.edge.rpc.constructor.notification.NotificationMsgConstructor;
import org.thingsboard.server.service.edge.rpc.constructor.oauth2.OAuth2MsgConstructor;
import org.thingsboard.server.service.edge.rpc.constructor.ota.OtaPackageMsgConstructorFactory;
import org.thingsboard.server.service.edge.rpc.constructor.queue.QueueMsgConstructorFactory;
@ -226,6 +230,15 @@ public abstract class BaseEdgeProcessor {
@Autowired
protected ResourceService resourceService;
@Autowired
protected NotificationRuleService notificationRuleService;
@Autowired
protected NotificationTargetService notificationTargetService;
@Autowired
protected NotificationTemplateService notificationTemplateService;
@Autowired
protected OAuth2Service oAuth2Service;
@ -260,9 +273,13 @@ public abstract class BaseEdgeProcessor {
@Autowired
protected EntityDataMsgConstructor entityDataMsgConstructor;
@Autowired
protected NotificationMsgConstructor notificationMsgConstructor;
@Autowired
protected OAuth2MsgConstructor oAuth2MsgConstructor;
@Autowired
protected RuleChainMsgConstructorFactory ruleChainMsgConstructorFactory;
@ -359,7 +376,8 @@ public abstract class BaseEdgeProcessor {
case TIMESERIES_UPDATED, ALARM_ACK, ALARM_CLEAR, ALARM_ASSIGNED, ALARM_UNASSIGNED, CREDENTIALS_REQUEST, ADDED_COMMENT, UPDATED_COMMENT ->
true;
default -> switch (type) {
case ALARM, ALARM_COMMENT, RULE_CHAIN, RULE_CHAIN_METADATA, USER, CUSTOMER, TENANT, TENANT_PROFILE, WIDGETS_BUNDLE, WIDGET_TYPE, ADMIN_SETTINGS, OTA_PACKAGE, QUEUE, RELATION ->
case ALARM, ALARM_COMMENT, RULE_CHAIN, RULE_CHAIN_METADATA, USER, CUSTOMER, TENANT, TENANT_PROFILE, WIDGETS_BUNDLE, WIDGET_TYPE,
ADMIN_SETTINGS, OTA_PACKAGE, QUEUE, RELATION, NOTIFICATION_TEMPLATE, NOTIFICATION_TARGET, NOTIFICATION_RULE ->
true;
default -> false;
};
@ -417,10 +435,8 @@ public abstract class BaseEdgeProcessor {
return switch (actionType) {
case UPDATED, CREDENTIALS_UPDATED, ASSIGNED_TO_CUSTOMER, UNASSIGNED_FROM_CUSTOMER, UPDATED_COMMENT ->
UpdateMsgType.ENTITY_UPDATED_RPC_MESSAGE;
case ADDED, ASSIGNED_TO_EDGE, RELATION_ADD_OR_UPDATE, ADDED_COMMENT ->
UpdateMsgType.ENTITY_CREATED_RPC_MESSAGE;
case DELETED, UNASSIGNED_FROM_EDGE, RELATION_DELETED, DELETED_COMMENT, ALARM_DELETE ->
UpdateMsgType.ENTITY_DELETED_RPC_MESSAGE;
case ADDED, ASSIGNED_TO_EDGE, RELATION_ADD_OR_UPDATE, ADDED_COMMENT -> UpdateMsgType.ENTITY_CREATED_RPC_MESSAGE;
case DELETED, UNASSIGNED_FROM_EDGE, RELATION_DELETED, DELETED_COMMENT, ALARM_DELETE -> UpdateMsgType.ENTITY_DELETED_RPC_MESSAGE;
case ALARM_ACK -> UpdateMsgType.ALARM_ACK_RPC_MESSAGE;
case ALARM_CLEAR -> UpdateMsgType.ALARM_CLEAR_RPC_MESSAGE;
default -> throw new RuntimeException("Unsupported actionType [" + actionType + "]");
@ -528,28 +544,21 @@ public abstract class BaseEdgeProcessor {
protected EntityId constructEntityId(String entityTypeStr, long entityIdMSB, long entityIdLSB) {
EntityType entityType = EntityType.valueOf(entityTypeStr);
switch (entityType) {
case DEVICE:
return new DeviceId(new UUID(entityIdMSB, entityIdLSB));
case ASSET:
return new AssetId(new UUID(entityIdMSB, entityIdLSB));
case ENTITY_VIEW:
return new EntityViewId(new UUID(entityIdMSB, entityIdLSB));
case DASHBOARD:
return new DashboardId(new UUID(entityIdMSB, entityIdLSB));
case TENANT:
return TenantId.fromUUID(new UUID(entityIdMSB, entityIdLSB));
case CUSTOMER:
return new CustomerId(new UUID(entityIdMSB, entityIdLSB));
case USER:
return new UserId(new UUID(entityIdMSB, entityIdLSB));
case EDGE:
return new EdgeId(new UUID(entityIdMSB, entityIdLSB));
default:
return switch (entityType) {
case DEVICE -> new DeviceId(new UUID(entityIdMSB, entityIdLSB));
case ASSET -> new AssetId(new UUID(entityIdMSB, entityIdLSB));
case ENTITY_VIEW -> new EntityViewId(new UUID(entityIdMSB, entityIdLSB));
case DASHBOARD -> new DashboardId(new UUID(entityIdMSB, entityIdLSB));
case TENANT -> TenantId.fromUUID(new UUID(entityIdMSB, entityIdLSB));
case CUSTOMER -> new CustomerId(new UUID(entityIdMSB, entityIdLSB));
case USER -> new UserId(new UUID(entityIdMSB, entityIdLSB));
case EDGE -> new EdgeId(new UUID(entityIdMSB, entityIdLSB));
default -> {
log.warn("Unsupported entity type [{}] during construct of entity id. entityIdMSB [{}], entityIdLSB [{}]",
entityTypeStr, entityIdMSB, entityIdLSB);
return null;
}
yield null;
}
};
}
protected UUID safeGetUUID(long mSB, long lSB) {
@ -570,8 +579,7 @@ public abstract class BaseEdgeProcessor {
case TENANT -> tenantService.findTenantById(tenantId) != null;
case DEVICE -> deviceService.findDeviceById(tenantId, new DeviceId(entityId.getId())) != null;
case ASSET -> assetService.findAssetById(tenantId, new AssetId(entityId.getId())) != null;
case ENTITY_VIEW ->
entityViewService.findEntityViewById(tenantId, new EntityViewId(entityId.getId())) != null;
case ENTITY_VIEW -> entityViewService.findEntityViewById(tenantId, new EntityViewId(entityId.getId())) != null;
case CUSTOMER -> customerService.findCustomerById(tenantId, new CustomerId(entityId.getId())) != null;
case USER -> userService.findUserById(tenantId, new UserId(entityId.getId())) != null;
case DASHBOARD -> dashboardService.findDashboardById(tenantId, new DashboardId(entityId.getId())) != null;

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

@ -31,16 +31,10 @@ public abstract class BaseEdgeProcessorFactory<T extends EdgeProcessor, U extend
protected U v2Processor;
public EdgeProcessor getProcessorByEdgeVersion(EdgeVersion edgeVersion) {
switch (edgeVersion) {
case V_3_3_0:
case V_3_3_3:
case V_3_4_0:
case V_3_6_0:
case V_3_6_1:
return v1Processor;
case V_3_6_2:
default:
return v2Processor;
}
return switch (edgeVersion) {
case V_3_3_0, V_3_3_3, V_3_4_0, V_3_6_0, V_3_6_1 -> v1Processor;
default -> v2Processor;
};
}
}

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

@ -156,4 +156,5 @@ public abstract class AlarmEdgeProcessor extends BaseAlarmProcessor implements A
}
return futures;
}
}

17
application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/alarm/AlarmEdgeProcessorV1.java

@ -58,15 +58,12 @@ public class AlarmEdgeProcessorV1 extends AlarmEdgeProcessor {
}
private EntityId getAlarmOriginator(TenantId tenantId, String entityName, EntityType entityType) {
switch (entityType) {
case DEVICE:
return deviceService.findDeviceByTenantIdAndName(tenantId, entityName).getId();
case ASSET:
return assetService.findAssetByTenantIdAndName(tenantId, entityName).getId();
case ENTITY_VIEW:
return entityViewService.findEntityViewByTenantIdAndName(tenantId, entityName).getId();
default:
return null;
}
return switch (entityType) {
case DEVICE -> deviceService.findDeviceByTenantIdAndName(tenantId, entityName).getId();
case ASSET -> assetService.findAssetByTenantIdAndName(tenantId, entityName).getId();
case ENTITY_VIEW -> entityViewService.findEntityViewByTenantIdAndName(tenantId, entityName).getId();
default -> null;
};
}
}

1
application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/alarm/AlarmEdgeProcessorV2.java

@ -40,4 +40,5 @@ public class AlarmEdgeProcessorV2 extends AlarmEdgeProcessor {
protected Alarm constructAlarmFromUpdateMsg(TenantId tenantId, AlarmId alarmId, EntityId originatorId, AlarmUpdateMsg alarmUpdateMsg) {
return JacksonUtil.fromString(alarmUpdateMsg.getEntity(), Alarm.class, true);
}
}

1
application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/alarm/AlarmProcessor.java

@ -34,4 +34,5 @@ public interface AlarmProcessor extends EdgeProcessor {
ListenableFuture<Void> processAlarmCommentMsgFromEdge(TenantId tenantId, EdgeId edgeId, AlarmCommentUpdateMsg alarmCommentUpdateMsg);
DownlinkMsg convertAlarmCommentEventToDownlink(EdgeEvent edgeEvent, EdgeVersion edgeVersion);
}

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

@ -144,23 +144,20 @@ public abstract class BaseAlarmProcessor extends BaseEdgeProcessor {
AlarmId alarmId = new AlarmId(entityId);
UpdateMsgType msgType = getUpdateMsgType(actionType);
switch (actionType) {
case ADDED:
case UPDATED:
case ALARM_ACK:
case ALARM_CLEAR:
case ADDED, UPDATED, ALARM_ACK, ALARM_CLEAR -> {
Alarm alarm = alarmService.findAlarmById(tenantId, alarmId);
if (alarm != null) {
return ((AlarmMsgConstructor) alarmMsgConstructorFactory.getMsgConstructorByEdgeVersion(edgeVersion))
.constructAlarmUpdatedMsg(msgType, alarm, findOriginatorEntityName(tenantId, alarm));
}
break;
case ALARM_DELETE:
case DELETED:
}
case ALARM_DELETE, DELETED -> {
Alarm deletedAlarm = JacksonUtil.convertValue(body, Alarm.class);
if (deletedAlarm != null) {
return ((AlarmMsgConstructor) alarmMsgConstructorFactory.getMsgConstructorByEdgeVersion(edgeVersion))
.constructAlarmUpdatedMsg(msgType, deletedAlarm, findOriginatorEntityName(tenantId, deletedAlarm));
}
}
}
return null;
}
@ -168,25 +165,26 @@ public abstract class BaseAlarmProcessor extends BaseEdgeProcessor {
private String findOriginatorEntityName(TenantId tenantId, Alarm alarm) {
String entityName = null;
switch (alarm.getOriginator().getEntityType()) {
case DEVICE:
case DEVICE -> {
Device deviceById = deviceService.findDeviceById(tenantId, new DeviceId(alarm.getOriginator().getId()));
if (deviceById != null) {
entityName = deviceById.getName();
}
break;
case ASSET:
}
case ASSET -> {
Asset assetById = assetService.findAssetById(tenantId, new AssetId(alarm.getOriginator().getId()));
if (assetById != null) {
entityName = assetById.getName();
}
break;
case ENTITY_VIEW:
}
case ENTITY_VIEW -> {
EntityView entityViewById = entityViewService.findEntityViewById(tenantId, new EntityViewId(alarm.getOriginator().getId()));
if (entityViewById != null) {
entityName = entityViewById.getName();
}
break;
}
}
return entityName;
}
}

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

@ -108,11 +108,7 @@ public abstract class AssetEdgeProcessor extends BaseAssetProcessor implements A
AssetId assetId = new AssetId(edgeEvent.getEntityId());
DownlinkMsg downlinkMsg = null;
switch (edgeEvent.getAction()) {
case ADDED:
case UPDATED:
case ASSIGNED_TO_EDGE:
case ASSIGNED_TO_CUSTOMER:
case UNASSIGNED_FROM_CUSTOMER:
case ADDED, UPDATED, ASSIGNED_TO_EDGE, ASSIGNED_TO_CUSTOMER, UNASSIGNED_FROM_CUSTOMER -> {
Asset asset = assetService.findAssetById(edgeEvent.getTenantId(), assetId);
if (asset != null) {
UpdateMsgType msgType = getUpdateMsgType(edgeEvent.getAction());
@ -129,17 +125,17 @@ public abstract class AssetEdgeProcessor extends BaseAssetProcessor implements A
}
downlinkMsg = builder.build();
}
break;
case DELETED:
case UNASSIGNED_FROM_EDGE:
}
case DELETED, UNASSIGNED_FROM_EDGE -> {
AssetUpdateMsg assetUpdateMsg = ((AssetMsgConstructor)
assetMsgConstructorFactory.getMsgConstructorByEdgeVersion(edgeVersion)).constructAssetDeleteMsg(assetId);
downlinkMsg = DownlinkMsg.newBuilder()
.setDownlinkMsgId(EdgeUtils.nextPositiveInt())
.addAssetUpdateMsg(assetUpdateMsg)
.build();
break;
}
}
return downlinkMsg;
}
}

1
application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/asset/AssetEdgeProcessorV1.java

@ -56,4 +56,5 @@ public class AssetEdgeProcessorV1 extends AssetEdgeProcessor {
CustomerId customerUUID = safeGetCustomerId(assetUpdateMsg.getCustomerIdMSB(), assetUpdateMsg.getCustomerIdLSB());
asset.setCustomerId(customerUUID != null ? customerUUID : customerId);
}
}

1
application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/asset/AssetEdgeProcessorV2.java

@ -40,4 +40,5 @@ public class AssetEdgeProcessorV2 extends AssetEdgeProcessor {
CustomerId customerUUID = asset.getCustomerId() != null ? asset.getCustomerId() : customerId;
asset.setCustomerId(customerUUID);
}
}

1
application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/asset/AssetProcessor.java

@ -30,4 +30,5 @@ public interface AssetProcessor extends EdgeProcessor {
ListenableFuture<Void> processAssetMsgFromEdge(TenantId tenantId, Edge edge, AssetUpdateMsg assetUpdateMsg);
DownlinkMsg convertAssetEventToDownlink(EdgeEvent edgeEvent, EdgeId edgeId, EdgeVersion edgeVersion);
}

1
application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/asset/BaseAssetProcessor.java

@ -72,4 +72,5 @@ public abstract class BaseAssetProcessor extends BaseEdgeProcessor {
protected abstract Asset constructAssetFromUpdateMsg(TenantId tenantId, AssetId assetId, AssetUpdateMsg assetUpdateMsg);
protected abstract void setCustomerId(TenantId tenantId, CustomerId customerId, Asset asset, AssetUpdateMsg assetUpdateMsg);
}

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

@ -97,8 +97,7 @@ public abstract class AssetProfileEdgeProcessor extends BaseAssetProfileProcesso
AssetProfileId assetProfileId = new AssetProfileId(edgeEvent.getEntityId());
DownlinkMsg downlinkMsg = null;
switch (edgeEvent.getAction()) {
case ADDED:
case UPDATED:
case ADDED, UPDATED -> {
AssetProfile assetProfile = assetProfileService.findAssetProfileById(edgeEvent.getTenantId(), assetProfileId);
if (assetProfile != null) {
UpdateMsgType msgType = getUpdateMsgType(edgeEvent.getAction());
@ -110,16 +109,17 @@ public abstract class AssetProfileEdgeProcessor extends BaseAssetProfileProcesso
.addAssetProfileUpdateMsg(assetProfileUpdateMsg)
.build();
}
break;
case DELETED:
}
case DELETED -> {
AssetProfileUpdateMsg assetProfileUpdateMsg = ((AssetMsgConstructor)
assetMsgConstructorFactory.getMsgConstructorByEdgeVersion(edgeVersion)).constructAssetProfileDeleteMsg(assetProfileId);
downlinkMsg = DownlinkMsg.newBuilder()
.setDownlinkMsgId(EdgeUtils.nextPositiveInt())
.addAssetProfileUpdateMsg(assetProfileUpdateMsg)
.build();
break;
}
}
return downlinkMsg;
}
}

10
application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/customer/CustomerEdgeProcessor.java

@ -52,8 +52,7 @@ public class CustomerEdgeProcessor extends BaseEdgeProcessor {
CustomerId customerId = new CustomerId(edgeEvent.getEntityId());
DownlinkMsg downlinkMsg = null;
switch (edgeEvent.getAction()) {
case ADDED:
case UPDATED:
case ADDED, UPDATED -> {
Customer customer = customerService.findCustomerById(edgeEvent.getTenantId(), customerId);
if (customer != null) {
UpdateMsgType msgType = getUpdateMsgType(edgeEvent.getAction());
@ -64,15 +63,15 @@ public class CustomerEdgeProcessor extends BaseEdgeProcessor {
.addCustomerUpdateMsg(customerUpdateMsg)
.build();
}
break;
case DELETED:
}
case DELETED -> {
CustomerUpdateMsg customerUpdateMsg = ((CustomerMsgConstructor)
customerMsgConstructorFactory.getMsgConstructorByEdgeVersion(edgeVersion)).constructCustomerDeleteMsg(customerId);
downlinkMsg = DownlinkMsg.newBuilder()
.setDownlinkMsgId(EdgeUtils.nextPositiveInt())
.addCustomerUpdateMsg(customerUpdateMsg)
.build();
break;
}
}
return downlinkMsg;
}
@ -97,4 +96,5 @@ public class CustomerEdgeProcessor extends BaseEdgeProcessor {
return Futures.immediateFuture(null);
}
}
}

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

@ -101,11 +101,7 @@ public abstract class DashboardEdgeProcessor extends BaseDashboardProcessor impl
DashboardId dashboardId = new DashboardId(edgeEvent.getEntityId());
DownlinkMsg downlinkMsg = null;
switch (edgeEvent.getAction()) {
case ADDED:
case UPDATED:
case ASSIGNED_TO_EDGE:
case ASSIGNED_TO_CUSTOMER:
case UNASSIGNED_FROM_CUSTOMER:
case ADDED, UPDATED, ASSIGNED_TO_EDGE, ASSIGNED_TO_CUSTOMER, UNASSIGNED_FROM_CUSTOMER -> {
Dashboard dashboard = dashboardService.findDashboardById(edgeEvent.getTenantId(), dashboardId);
if (dashboard != null) {
UpdateMsgType msgType = getUpdateMsgType(edgeEvent.getAction());
@ -116,16 +112,15 @@ public abstract class DashboardEdgeProcessor extends BaseDashboardProcessor impl
.addDashboardUpdateMsg(dashboardUpdateMsg)
.build();
}
break;
case DELETED:
case UNASSIGNED_FROM_EDGE:
}
case DELETED, UNASSIGNED_FROM_EDGE -> {
DashboardUpdateMsg dashboardUpdateMsg = ((DashboardMsgConstructor)
dashboardMsgConstructorFactory.getMsgConstructorByEdgeVersion(edgeVersion)).constructDashboardDeleteMsg(dashboardId);
downlinkMsg = DownlinkMsg.newBuilder()
.setDownlinkMsgId(EdgeUtils.nextPositiveInt())
.addDashboardUpdateMsg(dashboardUpdateMsg)
.build();
break;
}
}
return downlinkMsg;
}
@ -135,4 +130,5 @@ public abstract class DashboardEdgeProcessor extends BaseDashboardProcessor impl
// do nothing on cloud
return assignedCustomers;
}
}

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

@ -286,4 +286,5 @@ public abstract class DeviceEdgeProcessor extends BaseDeviceProcessor implements
.addDeviceCredentialsRequestMsg(deviceCredentialsRequestMsg);
return builder.build();
}
}

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

@ -97,8 +97,7 @@ public abstract class DeviceProfileEdgeProcessor extends BaseDeviceProfileProces
DeviceProfileId deviceProfileId = new DeviceProfileId(edgeEvent.getEntityId());
DownlinkMsg downlinkMsg = null;
switch (edgeEvent.getAction()) {
case ADDED:
case UPDATED:
case ADDED, UPDATED -> {
DeviceProfile deviceProfile = deviceProfileService.findDeviceProfileById(edgeEvent.getTenantId(), deviceProfileId);
if (deviceProfile != null) {
UpdateMsgType msgType = getUpdateMsgType(edgeEvent.getAction());
@ -110,16 +109,17 @@ public abstract class DeviceProfileEdgeProcessor extends BaseDeviceProfileProces
.addDeviceProfileUpdateMsg(deviceProfileUpdateMsg)
.build();
}
break;
case DELETED:
}
case DELETED -> {
DeviceProfileUpdateMsg deviceProfileUpdateMsg = ((DeviceMsgConstructor)
deviceMsgConstructorFactory.getMsgConstructorByEdgeVersion(edgeVersion)).constructDeviceProfileDeleteMsg(deviceProfileId);
downlinkMsg = DownlinkMsg.newBuilder()
.setDownlinkMsgId(EdgeUtils.nextPositiveInt())
.addDeviceProfileUpdateMsg(deviceProfileUpdateMsg)
.build();
break;
}
}
return downlinkMsg;
}
}

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

@ -50,8 +50,7 @@ public class EdgeProcessor extends BaseEdgeProcessor {
EdgeId edgeId = new EdgeId(edgeEvent.getEntityId());
DownlinkMsg downlinkMsg = null;
switch (edgeEvent.getAction()) {
case ASSIGNED_TO_CUSTOMER:
case UNASSIGNED_FROM_CUSTOMER:
case ASSIGNED_TO_CUSTOMER, UNASSIGNED_FROM_CUSTOMER -> {
Edge edge = edgeService.findEdgeById(edgeEvent.getTenantId(), edgeId);
if (edge != null) {
EdgeConfiguration edgeConfigMsg =
@ -61,7 +60,7 @@ public class EdgeProcessor extends BaseEdgeProcessor {
.setEdgeConfiguration(edgeConfigMsg)
.build();
}
break;
}
}
return downlinkMsg;
}
@ -112,4 +111,5 @@ public class EdgeProcessor extends BaseEdgeProcessor {
return Futures.immediateFailedFuture(e);
}
}
}

1
application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/entityview/BaseEntityViewProcessor.java

@ -64,4 +64,5 @@ public abstract class BaseEntityViewProcessor extends BaseEdgeProcessor {
protected abstract EntityView constructEntityViewFromUpdateMsg(TenantId tenantId, EntityViewId entityViewId, EntityViewUpdateMsg entityViewUpdateMsg);
protected abstract void setCustomerId(TenantId tenantId, CustomerId customerId, EntityView entityView, EntityViewUpdateMsg entityViewUpdateMsg);
}

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

@ -105,11 +105,7 @@ public abstract class EntityViewEdgeProcessor extends BaseEntityViewProcessor im
EntityViewId entityViewId = new EntityViewId(edgeEvent.getEntityId());
DownlinkMsg downlinkMsg = null;
switch (edgeEvent.getAction()) {
case ADDED:
case UPDATED:
case ASSIGNED_TO_EDGE:
case ASSIGNED_TO_CUSTOMER:
case UNASSIGNED_FROM_CUSTOMER:
case ADDED, UPDATED, ASSIGNED_TO_EDGE, ASSIGNED_TO_CUSTOMER, UNASSIGNED_FROM_CUSTOMER -> {
EntityView entityView = entityViewService.findEntityViewById(edgeEvent.getTenantId(), entityViewId);
if (entityView != null) {
UpdateMsgType msgType = getUpdateMsgType(edgeEvent.getAction());
@ -120,17 +116,17 @@ public abstract class EntityViewEdgeProcessor extends BaseEntityViewProcessor im
.addEntityViewUpdateMsg(entityViewUpdateMsg)
.build();
}
break;
case DELETED:
case UNASSIGNED_FROM_EDGE:
}
case DELETED, UNASSIGNED_FROM_EDGE -> {
EntityViewUpdateMsg entityViewUpdateMsg = ((EntityViewMsgConstructor)
entityViewMsgConstructorFactory.getMsgConstructorByEdgeVersion(edgeVersion)).constructEntityViewDeleteMsg(entityViewId);
downlinkMsg = DownlinkMsg.newBuilder()
.setDownlinkMsgId(EdgeUtils.nextPositiveInt())
.addEntityViewUpdateMsg(entityViewUpdateMsg)
.build();
break;
}
}
return downlinkMsg;
}
}

1
application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/entityview/EntityViewProcessor.java

@ -29,4 +29,5 @@ public interface EntityViewProcessor extends EdgeProcessor {
ListenableFuture<Void> processEntityViewMsgFromEdge(TenantId tenantId, Edge edge, EntityViewUpdateMsg entityViewUpdateMsg);
DownlinkMsg convertEntityViewEventToDownlink(EdgeEvent edgeEvent, EdgeVersion edgeVersion);
}

1
application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/entityview/EntityViewProcessorV1.java

@ -62,4 +62,5 @@ public class EntityViewProcessorV1 extends EntityViewEdgeProcessor {
CustomerId customerUUID = safeGetCustomerId(entityViewUpdateMsg.getCustomerIdMSB(), entityViewUpdateMsg.getCustomerIdLSB());
entityView.setCustomerId(customerUUID != null ? customerUUID : customerId);
}
}

1
application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/entityview/EntityViewProcessorV2.java

@ -40,4 +40,5 @@ public class EntityViewProcessorV2 extends EntityViewEdgeProcessor {
CustomerId customerUUID = entityView.getCustomerId() != null ? entityView.getCustomerId() : customerId;
entityView.setCustomerId(customerUUID);
}
}

119
application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/notification/NotificationEdgeProcessor.java

@ -0,0 +1,119 @@
/**
* 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.edge.rpc.processor.notification;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import org.thingsboard.server.common.data.EdgeUtils;
import org.thingsboard.server.common.data.edge.EdgeEvent;
import org.thingsboard.server.common.data.id.NotificationRuleId;
import org.thingsboard.server.common.data.id.NotificationTargetId;
import org.thingsboard.server.common.data.id.NotificationTemplateId;
import org.thingsboard.server.common.data.notification.rule.NotificationRule;
import org.thingsboard.server.common.data.notification.targets.NotificationTarget;
import org.thingsboard.server.common.data.notification.template.NotificationTemplate;
import org.thingsboard.server.gen.edge.v1.DownlinkMsg;
import org.thingsboard.server.gen.edge.v1.NotificationRuleUpdateMsg;
import org.thingsboard.server.gen.edge.v1.NotificationTargetUpdateMsg;
import org.thingsboard.server.gen.edge.v1.NotificationTemplateUpdateMsg;
import org.thingsboard.server.gen.edge.v1.UpdateMsgType;
import org.thingsboard.server.queue.util.TbCoreComponent;
import org.thingsboard.server.service.edge.rpc.processor.BaseEdgeProcessor;
@Slf4j
@Component
@TbCoreComponent
public class NotificationEdgeProcessor extends BaseEdgeProcessor {
public DownlinkMsg convertNotificationRuleToDownlink(EdgeEvent edgeEvent) {
NotificationRuleId notificationRuleId = new NotificationRuleId(edgeEvent.getEntityId());
DownlinkMsg downlinkMsg = null;
switch (edgeEvent.getAction()) {
case ADDED, UPDATED -> {
NotificationRule notificationRule = notificationRuleService.findNotificationRuleById(edgeEvent.getTenantId(), notificationRuleId);
if (notificationRule != null) {
UpdateMsgType msgType = getUpdateMsgType(edgeEvent.getAction());
NotificationRuleUpdateMsg notificationRuleUpdateMsg = notificationMsgConstructor.constructNotificationRuleUpdateMsg(msgType, notificationRule);
downlinkMsg = DownlinkMsg.newBuilder()
.setDownlinkMsgId(EdgeUtils.nextPositiveInt())
.addNotificationRuleUpdateMsg(notificationRuleUpdateMsg)
.build();
}
}
case DELETED -> {
NotificationRuleUpdateMsg notificationRuleUpdateMsg = notificationMsgConstructor.constructNotificationRuleDeleteMsg(notificationRuleId);
downlinkMsg = DownlinkMsg.newBuilder()
.setDownlinkMsgId(EdgeUtils.nextPositiveInt())
.addNotificationRuleUpdateMsg(notificationRuleUpdateMsg)
.build();
}
}
return downlinkMsg;
}
public DownlinkMsg convertNotificationTargetToDownlink(EdgeEvent edgeEvent) {
NotificationTargetId notificationTargetId = new NotificationTargetId(edgeEvent.getEntityId());
DownlinkMsg downlinkMsg = null;
switch (edgeEvent.getAction()) {
case ADDED, UPDATED -> {
NotificationTarget notificationTarget = notificationTargetService.findNotificationTargetById(edgeEvent.getTenantId(), notificationTargetId);
if (notificationTarget != null) {
UpdateMsgType msgType = getUpdateMsgType(edgeEvent.getAction());
NotificationTargetUpdateMsg notificationTargetUpdateMsg = notificationMsgConstructor.constructNotificationTargetUpdateMsg(msgType, notificationTarget);
downlinkMsg = DownlinkMsg.newBuilder()
.setDownlinkMsgId(EdgeUtils.nextPositiveInt())
.addNotificationTargetUpdateMsg(notificationTargetUpdateMsg)
.build();
}
}
case DELETED -> {
NotificationTargetUpdateMsg notificationTargetUpdateMsg = notificationMsgConstructor.constructNotificationTargetDeleteMsg(notificationTargetId);
downlinkMsg = DownlinkMsg.newBuilder()
.setDownlinkMsgId(EdgeUtils.nextPositiveInt())
.addNotificationTargetUpdateMsg(notificationTargetUpdateMsg)
.build();
}
}
return downlinkMsg;
}
public DownlinkMsg convertNotificationTemplateToDownlink(EdgeEvent edgeEvent) {
NotificationTemplateId notificationTemplateId = new NotificationTemplateId(edgeEvent.getEntityId());
DownlinkMsg downlinkMsg = null;
switch (edgeEvent.getAction()) {
case ADDED, UPDATED -> {
NotificationTemplate notificationTemplate = notificationTemplateService.findNotificationTemplateById(edgeEvent.getTenantId(), notificationTemplateId);
if (notificationTemplate != null) {
UpdateMsgType msgType = getUpdateMsgType(edgeEvent.getAction());
NotificationTemplateUpdateMsg notificationTemplateUpdateMsg = notificationMsgConstructor.constructNotificationTemplateUpdateMsg(msgType, notificationTemplate);
downlinkMsg = DownlinkMsg.newBuilder()
.setDownlinkMsgId(EdgeUtils.nextPositiveInt())
.addNotificationTemplateUpdateMsg(notificationTemplateUpdateMsg)
.build();
}
}
case DELETED -> {
NotificationTemplateUpdateMsg notificationTemplateUpdateMsg = notificationMsgConstructor.constructNotificationTemplateDeleteMsg(notificationTemplateId);
downlinkMsg = DownlinkMsg.newBuilder()
.setDownlinkMsgId(EdgeUtils.nextPositiveInt())
.addNotificationTemplateUpdateMsg(notificationTemplateUpdateMsg)
.build();
}
}
return downlinkMsg;
}
}

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

@ -38,8 +38,7 @@ public class OtaPackageEdgeProcessor extends BaseEdgeProcessor {
OtaPackageId otaPackageId = new OtaPackageId(edgeEvent.getEntityId());
DownlinkMsg downlinkMsg = null;
switch (edgeEvent.getAction()) {
case ADDED:
case UPDATED:
case ADDED, UPDATED -> {
OtaPackage otaPackage = otaPackageService.findOtaPackageById(edgeEvent.getTenantId(), otaPackageId);
if (otaPackage != null) {
UpdateMsgType msgType = getUpdateMsgType(edgeEvent.getAction());
@ -50,16 +49,17 @@ public class OtaPackageEdgeProcessor extends BaseEdgeProcessor {
.addOtaPackageUpdateMsg(otaPackageUpdateMsg)
.build();
}
break;
case DELETED:
}
case DELETED -> {
OtaPackageUpdateMsg otaPackageUpdateMsg = ((OtaPackageMsgConstructor)
otaPackageMsgConstructorFactory.getMsgConstructorByEdgeVersion(edgeVersion)).constructOtaPackageDeleteMsg(otaPackageId);
downlinkMsg = DownlinkMsg.newBuilder()
.setDownlinkMsgId(EdgeUtils.nextPositiveInt())
.addOtaPackageUpdateMsg(otaPackageUpdateMsg)
.build();
break;
}
}
return downlinkMsg;
}
}

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

@ -38,8 +38,7 @@ public class QueueEdgeProcessor extends BaseEdgeProcessor {
QueueId queueId = new QueueId(edgeEvent.getEntityId());
DownlinkMsg downlinkMsg = null;
switch (edgeEvent.getAction()) {
case ADDED:
case UPDATED:
case ADDED, UPDATED -> {
Queue queue = queueService.findQueueById(edgeEvent.getTenantId(), queueId);
if (queue != null) {
UpdateMsgType msgType = getUpdateMsgType(edgeEvent.getAction());
@ -50,16 +49,17 @@ public class QueueEdgeProcessor extends BaseEdgeProcessor {
.addQueueUpdateMsg(queueUpdateMsg)
.build();
}
break;
case DELETED:
}
case DELETED -> {
QueueUpdateMsg queueDeleteMsg = ((QueueMsgConstructor)
queueMsgConstructorFactory.getMsgConstructorByEdgeVersion(edgeVersion)).constructQueueDeleteMsg(queueId);
downlinkMsg = DownlinkMsg.newBuilder()
.setDownlinkMsgId(EdgeUtils.nextPositiveInt())
.addQueueUpdateMsg(queueDeleteMsg)
.build();
break;
}
}
return downlinkMsg;
}
}

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

@ -58,4 +58,5 @@ public abstract class BaseRelationProcessor extends BaseEdgeProcessor {
}
protected abstract EntityRelation constructEntityRelationFromUpdateMsg(RelationUpdateMsg relationUpdateMsg);
}

1
application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/relation/RelationEdgeProcessor.java

@ -91,4 +91,5 @@ public abstract class RelationEdgeProcessor extends BaseRelationProcessor implem
}
return Futures.transform(Futures.allAsList(futures), voids -> null, dbCallbackExecutorService);
}
}

1
application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/relation/RelationEdgeProcessorV1.java

@ -49,4 +49,5 @@ public class RelationEdgeProcessorV1 extends RelationEdgeProcessor {
entityRelation.setAdditionalInfo(JacksonUtil.toJsonNode(relationUpdateMsg.getAdditionalInfo()));
return entityRelation;
}
}

1
application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/relation/RelationEdgeProcessorV2.java

@ -31,4 +31,5 @@ public class RelationEdgeProcessorV2 extends RelationEdgeProcessor {
protected EntityRelation constructEntityRelationFromUpdateMsg(RelationUpdateMsg relationUpdateMsg) {
return JacksonUtil.fromString(relationUpdateMsg.getEntity(), EntityRelation.class, true);
}
}

1
application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/relation/RelationProcessor.java

@ -29,4 +29,5 @@ public interface RelationProcessor extends EdgeProcessor {
ListenableFuture<Void> processRelationMsgFromEdge(TenantId tenantId, Edge edge, RelationUpdateMsg relationUpdateMsg);
DownlinkMsg convertRelationEventToDownlink(EdgeEvent edgeEvent, EdgeVersion edgeVersion);
}

1
application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/resource/BaseResourceProcessor.java

@ -72,4 +72,5 @@ public abstract class BaseResourceProcessor extends BaseEdgeProcessor {
}
protected abstract TbResource constructResourceFromUpdateMsg(TenantId tenantId, TbResourceId tbResourceId, ResourceUpdateMsg resourceUpdateMsg);
}

10
application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/resource/ResourceEdgeProcessor.java

@ -74,8 +74,7 @@ public abstract class ResourceEdgeProcessor extends BaseResourceProcessor implem
TbResourceId tbResourceId = new TbResourceId(edgeEvent.getEntityId());
DownlinkMsg downlinkMsg = null;
switch (edgeEvent.getAction()) {
case ADDED:
case UPDATED:
case ADDED, UPDATED -> {
TbResource tbResource = resourceService.findResourceById(edgeEvent.getTenantId(), tbResourceId);
if (tbResource != null) {
UpdateMsgType msgType = getUpdateMsgType(edgeEvent.getAction());
@ -86,16 +85,17 @@ public abstract class ResourceEdgeProcessor extends BaseResourceProcessor implem
.addResourceUpdateMsg(resourceUpdateMsg)
.build() : null;
}
break;
case DELETED:
}
case DELETED -> {
ResourceUpdateMsg resourceUpdateMsg = ((ResourceMsgConstructor)
resourceMsgConstructorFactory.getMsgConstructorByEdgeVersion(edgeVersion)).constructResourceDeleteMsg(tbResourceId);
downlinkMsg = DownlinkMsg.newBuilder()
.setDownlinkMsgId(EdgeUtils.nextPositiveInt())
.addResourceUpdateMsg(resourceUpdateMsg)
.build();
break;
}
}
return downlinkMsg;
}
}

1
application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/resource/ResourceEdgeProcessorV1.java

@ -45,4 +45,5 @@ public class ResourceEdgeProcessorV1 extends ResourceEdgeProcessor {
resource.setEtag(resourceUpdateMsg.hasEtag() ? resourceUpdateMsg.getEtag() : null);
return resource;
}
}

1
application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/resource/ResourceEdgeProcessorV2.java

@ -33,4 +33,5 @@ public class ResourceEdgeProcessorV2 extends ResourceEdgeProcessor {
protected TbResource constructResourceFromUpdateMsg(TenantId tenantId, TbResourceId tbResourceId, ResourceUpdateMsg resourceUpdateMsg) {
return JacksonUtil.fromString(resourceUpdateMsg.getEntity(), TbResource.class, true);
}
}

1
application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/resource/ResourceProcessor.java

@ -29,4 +29,5 @@ public interface ResourceProcessor extends EdgeProcessor {
ListenableFuture<Void> processResourceMsgFromEdge(TenantId tenantId, Edge edge, ResourceUpdateMsg resourceUpdateMsg);
DownlinkMsg convertResourceEventToDownlink(EdgeEvent edgeEvent, EdgeVersion edgeVersion);
}

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

@ -43,16 +43,15 @@ public class RuleChainEdgeProcessor extends BaseEdgeProcessor {
RuleChainId ruleChainId = new RuleChainId(edgeEvent.getEntityId());
DownlinkMsg downlinkMsg = null;
switch (edgeEvent.getAction()) {
case ADDED:
case UPDATED:
case ASSIGNED_TO_EDGE:
case ADDED, UPDATED, ASSIGNED_TO_EDGE -> {
RuleChain ruleChain = ruleChainService.findRuleChainById(edgeEvent.getTenantId(), ruleChainId);
if (ruleChain != null) {
boolean isRoot = false;
if (edgeEvent.getBody() != null && edgeEvent.getBody().get(EDGE_IS_ROOT_BODY_KEY) != null) {
try {
isRoot = Boolean.parseBoolean(edgeEvent.getBody().get(EDGE_IS_ROOT_BODY_KEY).asText());
} catch (Exception ignored) {}
} catch (Exception ignored) {
}
}
if (!isRoot) {
Edge edge = edgeService.findEdgeById(edgeEvent.getTenantId(), edgeEvent.getEdgeId());
@ -67,15 +66,12 @@ public class RuleChainEdgeProcessor extends BaseEdgeProcessor {
.addRuleChainUpdateMsg(ruleChainUpdateMsg)
.build();
}
break;
case DELETED:
case UNASSIGNED_FROM_EDGE:
downlinkMsg = DownlinkMsg.newBuilder()
.setDownlinkMsgId(EdgeUtils.nextPositiveInt())
.addRuleChainUpdateMsg(((RuleChainMsgConstructor) ruleChainMsgConstructorFactory.getMsgConstructorByEdgeVersion(edgeVersion))
.constructRuleChainDeleteMsg(ruleChainId))
.build();
break;
}
case DELETED, UNASSIGNED_FROM_EDGE -> downlinkMsg = DownlinkMsg.newBuilder()
.setDownlinkMsgId(EdgeUtils.nextPositiveInt())
.addRuleChainUpdateMsg(((RuleChainMsgConstructor) ruleChainMsgConstructorFactory.getMsgConstructorByEdgeVersion(edgeVersion))
.constructRuleChainDeleteMsg(ruleChainId))
.build();
}
return downlinkMsg;
}
@ -99,4 +95,5 @@ public class RuleChainEdgeProcessor extends BaseEdgeProcessor {
}
return downlinkMsg;
}
}

1
application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/settings/AdminSettingsEdgeProcessor.java

@ -45,4 +45,5 @@ public class AdminSettingsEdgeProcessor extends BaseEdgeProcessor {
.addAdminSettingsUpdateMsg(adminSettingsUpdateMsg)
.build();
}
}

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

@ -138,41 +138,39 @@ public abstract class BaseTelemetryProcessor extends BaseEdgeProcessor {
TbMsgMetaData metaData = new TbMsgMetaData();
CustomerId customerId = null;
switch (entityId.getEntityType()) {
case DEVICE:
case DEVICE -> {
Device device = deviceService.findDeviceById(tenantId, new DeviceId(entityId.getId()));
if (device != null) {
customerId = device.getCustomerId();
metaData.putValue("deviceName", device.getName());
metaData.putValue("deviceType", device.getType());
}
break;
case ASSET:
}
case ASSET -> {
Asset asset = assetService.findAssetById(tenantId, new AssetId(entityId.getId()));
if (asset != null) {
customerId = asset.getCustomerId();
metaData.putValue("assetName", asset.getName());
metaData.putValue("assetType", asset.getType());
}
break;
case ENTITY_VIEW:
}
case ENTITY_VIEW -> {
EntityView entityView = entityViewService.findEntityViewById(tenantId, new EntityViewId(entityId.getId()));
if (entityView != null) {
customerId = entityView.getCustomerId();
metaData.putValue("entityViewName", entityView.getName());
metaData.putValue("entityViewType", entityView.getType());
}
break;
case EDGE:
}
case EDGE -> {
Edge edge = edgeService.findEdgeById(tenantId, new EdgeId(entityId.getId()));
if (edge != null) {
customerId = edge.getCustomerId();
metaData.putValue("edgeName", edge.getName());
metaData.putValue("edgeType", edge.getType());
}
break;
default:
log.debug("[{}] Using empty metadata for entityId [{}]", tenantId, entityId);
break;
}
default -> log.debug("[{}] Using empty metadata for entityId [{}]", tenantId, entityId);
}
return new ImmutablePair<>(metaData, customerId != null ? customerId : new CustomerId(ModelConstants.NULL_UUID));
}

1
application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/tenant/TenantProfileEdgeProcessor.java

@ -53,4 +53,5 @@ public class TenantProfileEdgeProcessor extends BaseEdgeProcessor {
}
return downlinkMsg;
}
}

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

@ -39,8 +39,7 @@ public class UserEdgeProcessor extends BaseEdgeProcessor {
UserId userId = new UserId(edgeEvent.getEntityId());
DownlinkMsg downlinkMsg = null;
switch (edgeEvent.getAction()) {
case ADDED:
case UPDATED:
case ADDED, UPDATED -> {
User user = userService.findUserById(edgeEvent.getTenantId(), userId);
if (user != null) {
UpdateMsgType msgType = getUpdateMsgType(edgeEvent.getAction());
@ -49,14 +48,12 @@ public class UserEdgeProcessor extends BaseEdgeProcessor {
.addUserUpdateMsg(((UserMsgConstructor) userMsgConstructorFactory.getMsgConstructorByEdgeVersion(edgeVersion)).constructUserUpdatedMsg(msgType, user))
.build();
}
break;
case DELETED:
downlinkMsg = DownlinkMsg.newBuilder()
.setDownlinkMsgId(EdgeUtils.nextPositiveInt())
.addUserUpdateMsg(((UserMsgConstructor) userMsgConstructorFactory.getMsgConstructorByEdgeVersion(edgeVersion)).constructUserDeleteMsg(userId))
.build();
break;
case CREDENTIALS_UPDATED:
}
case DELETED -> downlinkMsg = DownlinkMsg.newBuilder()
.setDownlinkMsgId(EdgeUtils.nextPositiveInt())
.addUserUpdateMsg(((UserMsgConstructor) userMsgConstructorFactory.getMsgConstructorByEdgeVersion(edgeVersion)).constructUserDeleteMsg(userId))
.build();
case CREDENTIALS_UPDATED -> {
UserCredentials userCredentialsByUserId = userService.findUserCredentialsByUserId(edgeEvent.getTenantId(), userId);
if (userCredentialsByUserId != null && userCredentialsByUserId.isEnabled()) {
UserCredentialsUpdateMsg userCredentialsUpdateMsg =
@ -66,8 +63,9 @@ public class UserEdgeProcessor extends BaseEdgeProcessor {
.addUserCredentialsUpdateMsg(userCredentialsUpdateMsg)
.build();
}
break;
}
}
return downlinkMsg;
}
}

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

@ -40,8 +40,7 @@ public class WidgetBundleEdgeProcessor extends BaseEdgeProcessor {
WidgetsBundleId widgetsBundleId = new WidgetsBundleId(edgeEvent.getEntityId());
DownlinkMsg downlinkMsg = null;
switch (edgeEvent.getAction()) {
case ADDED:
case UPDATED:
case ADDED, UPDATED -> {
WidgetsBundle widgetsBundle = widgetsBundleService.findWidgetsBundleById(edgeEvent.getTenantId(), widgetsBundleId);
if (widgetsBundle != null) {
List<String> widgets = widgetTypeService.findWidgetFqnsByWidgetsBundleId(edgeEvent.getTenantId(), widgetsBundleId);
@ -53,16 +52,17 @@ public class WidgetBundleEdgeProcessor extends BaseEdgeProcessor {
.addWidgetsBundleUpdateMsg(widgetsBundleUpdateMsg)
.build();
}
break;
case DELETED:
}
case DELETED -> {
WidgetsBundleUpdateMsg widgetsBundleUpdateMsg =
((WidgetMsgConstructor) widgetMsgConstructorFactory.getMsgConstructorByEdgeVersion(edgeVersion)).constructWidgetsBundleDeleteMsg(widgetsBundleId);
downlinkMsg = DownlinkMsg.newBuilder()
.setDownlinkMsgId(EdgeUtils.nextPositiveInt())
.addWidgetsBundleUpdateMsg(widgetsBundleUpdateMsg)
.build();
break;
}
}
return downlinkMsg;
}
}

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

@ -38,8 +38,7 @@ public class WidgetTypeEdgeProcessor extends BaseEdgeProcessor {
WidgetTypeId widgetTypeId = new WidgetTypeId(edgeEvent.getEntityId());
DownlinkMsg downlinkMsg = null;
switch (edgeEvent.getAction()) {
case ADDED:
case UPDATED:
case ADDED, UPDATED -> {
WidgetTypeDetails widgetTypeDetails = widgetTypeService.findWidgetTypeDetailsById(edgeEvent.getTenantId(), widgetTypeId);
if (widgetTypeDetails != null) {
UpdateMsgType msgType = getUpdateMsgType(edgeEvent.getAction());
@ -50,16 +49,17 @@ public class WidgetTypeEdgeProcessor extends BaseEdgeProcessor {
.addWidgetTypeUpdateMsg(widgetTypeUpdateMsg)
.build();
}
break;
case DELETED:
}
case DELETED -> {
WidgetTypeUpdateMsg widgetTypeUpdateMsg =
((WidgetMsgConstructor) widgetMsgConstructorFactory.getMsgConstructorByEdgeVersion(edgeVersion)).constructWidgetTypeDeleteMsg(widgetTypeId);
downlinkMsg = DownlinkMsg.newBuilder()
.setDownlinkMsgId(EdgeUtils.nextPositiveInt())
.addWidgetTypeUpdateMsg(widgetTypeUpdateMsg)
.build();
break;
}
}
return downlinkMsg;
}
}

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

@ -27,7 +27,6 @@ import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
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.EdgeUtils;
import org.thingsboard.server.common.data.EntityType;
@ -110,9 +109,6 @@ public class DefaultEdgeRequestsService implements EdgeRequestsService {
@Autowired
private DbCallbackExecutorService dbCallbackExecutorService;
@Autowired
private TbClusterService tbClusterService;
@Override
public ListenableFuture<Void> processRuleChainMetadataRequestMsg(TenantId tenantId, Edge edge, RuleChainMetadataRequestMsg ruleChainMetadataRequestMsg) {
log.trace("[{}] processRuleChainMetadataRequestMsg [{}][{}]", tenantId, edge.getName(), ruleChainMetadataRequestMsg);
@ -292,8 +288,7 @@ public class DefaultEdgeRequestsService implements EdgeRequestsService {
return futureToSet;
}
private ListenableFuture<List<EntityRelation>> findRelationByQuery(TenantId tenantId, Edge edge,
EntityId entityId, EntitySearchDirection direction) {
private ListenableFuture<List<EntityRelation>> findRelationByQuery(TenantId tenantId, Edge edge, EntityId entityId, EntitySearchDirection direction) {
EntityRelationsQuery query = new EntityRelationsQuery();
query.setParameters(new RelationsSearchParameters(entityId, direction, 1, false));
return relationService.findByQuery(tenantId, query);

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

@ -249,7 +249,7 @@ public class DefaultNotificationCenter extends AbstractSubscriptionService imple
private void processForTarget(NotificationTarget target, NotificationProcessingContext ctx) {
Iterable<? extends NotificationRecipient> recipients;
switch (target.getConfiguration().getType()) {
case PLATFORM_USERS: {
case PLATFORM_USERS -> {
PlatformUsersNotificationTargetConfig targetConfig = (PlatformUsersNotificationTargetConfig) target.getConfiguration();
if (targetConfig.getUsersFilter().getType().isForRules() && ctx.getRequest().getInfo() instanceof RuleOriginatedNotificationInfo) {
recipients = new PageDataIterable<>(pageLink -> {
@ -260,21 +260,16 @@ public class DefaultNotificationCenter extends AbstractSubscriptionService imple
return notificationTargetService.findRecipientsForNotificationTargetConfig(ctx.getTenantId(), targetConfig, pageLink);
}, 256);
}
break;
}
case SLACK: {
case SLACK -> {
SlackNotificationTargetConfig targetConfig = (SlackNotificationTargetConfig) target.getConfiguration();
recipients = List.of(targetConfig.getConversation());
break;
}
case MICROSOFT_TEAMS: {
case MICROSOFT_TEAMS -> {
MicrosoftTeamsNotificationTargetConfig targetConfig = (MicrosoftTeamsNotificationTargetConfig) target.getConfiguration();
recipients = List.of(targetConfig);
break;
}
default: {
recipients = Collections.emptyList();
}
default -> recipients = Collections.emptyList();
}
Set<NotificationDeliveryMethod> deliveryMethods = new HashSet<>(ctx.getDeliveryMethods());

290
application/src/test/java/org/thingsboard/server/edge/NotificationEdgeTest.java

@ -0,0 +1,290 @@
/**
* 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.edge;
import com.google.protobuf.AbstractMessage;
import org.junit.Assert;
import org.junit.Test;
import org.springframework.test.context.TestPropertySource;
import org.thingsboard.common.util.JacksonUtil;
import org.thingsboard.server.common.data.StringUtils;
import org.thingsboard.server.common.data.notification.NotificationDeliveryMethod;
import org.thingsboard.server.common.data.notification.NotificationType;
import org.thingsboard.server.common.data.notification.rule.EscalatedNotificationRuleRecipientsConfig;
import org.thingsboard.server.common.data.notification.rule.NotificationRule;
import org.thingsboard.server.common.data.notification.rule.trigger.config.AlarmNotificationRuleTriggerConfig;
import org.thingsboard.server.common.data.notification.rule.trigger.config.NotificationRuleTriggerType;
import org.thingsboard.server.common.data.notification.targets.NotificationTarget;
import org.thingsboard.server.common.data.notification.targets.platform.PlatformUsersNotificationTargetConfig;
import org.thingsboard.server.common.data.notification.targets.platform.TenantAdministratorsFilter;
import org.thingsboard.server.common.data.notification.template.DeliveryMethodNotificationTemplate;
import org.thingsboard.server.common.data.notification.template.EmailDeliveryMethodNotificationTemplate;
import org.thingsboard.server.common.data.notification.template.HasSubject;
import org.thingsboard.server.common.data.notification.template.MobileAppDeliveryMethodNotificationTemplate;
import org.thingsboard.server.common.data.notification.template.NotificationTemplate;
import org.thingsboard.server.common.data.notification.template.NotificationTemplateConfig;
import org.thingsboard.server.common.data.notification.template.SmsDeliveryMethodNotificationTemplate;
import org.thingsboard.server.common.data.notification.template.WebDeliveryMethodNotificationTemplate;
import org.thingsboard.server.dao.service.DaoSqlTest;
import org.thingsboard.server.gen.edge.v1.NotificationRuleUpdateMsg;
import org.thingsboard.server.gen.edge.v1.NotificationTargetUpdateMsg;
import org.thingsboard.server.gen.edge.v1.NotificationTemplateUpdateMsg;
import org.thingsboard.server.gen.edge.v1.UpdateMsgType;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.UUID;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
@DaoSqlTest
public class NotificationEdgeTest extends AbstractEdgeTest {
@Test
public void testNotificationTemplate() throws Exception {
// create notification template
edgeImitator.expectMessageAmount(1);
NotificationDeliveryMethod[] deliveryMethods = new NotificationDeliveryMethod[]{
NotificationDeliveryMethod.WEB
};
NotificationTemplate template = createNotificationTemplate(NotificationType.GENERAL, deliveryMethods);
Assert.assertTrue(edgeImitator.waitForMessages());
AbstractMessage latestMessage = edgeImitator.getLatestMessage();
Assert.assertTrue(latestMessage instanceof NotificationTemplateUpdateMsg);
NotificationTemplateUpdateMsg notificationTemplateUpdateMsg = (NotificationTemplateUpdateMsg) latestMessage;
Assert.assertEquals(UpdateMsgType.ENTITY_CREATED_RPC_MESSAGE, notificationTemplateUpdateMsg.getMsgType());
NotificationTemplate notificationTemplate = JacksonUtil.fromString(notificationTemplateUpdateMsg.getEntity(), NotificationTemplate.class, true);
Assert.assertNotNull(notificationTemplate);
Assert.assertEquals(template.getId(), notificationTemplate.getId());
Assert.assertEquals(template.getName(), notificationTemplate.getName());
Assert.assertEquals(template.getNotificationType(), notificationTemplate.getNotificationType());
// update notification template
edgeImitator.expectMessageAmount(1);
template.setName(StringUtils.randomAlphanumeric(15));
saveNotificationTemplate(template);
Assert.assertTrue(edgeImitator.waitForMessages());
latestMessage = edgeImitator.getLatestMessage();
Assert.assertTrue(latestMessage instanceof NotificationTemplateUpdateMsg);
notificationTemplateUpdateMsg = (NotificationTemplateUpdateMsg) latestMessage;
Assert.assertEquals(UpdateMsgType.ENTITY_UPDATED_RPC_MESSAGE, notificationTemplateUpdateMsg.getMsgType());
notificationTemplate = JacksonUtil.fromString(notificationTemplateUpdateMsg.getEntity(), NotificationTemplate.class, true);
Assert.assertNotNull(notificationTemplate);
Assert.assertEquals(template.getId(), notificationTemplate.getId());
Assert.assertEquals(template.getName(), notificationTemplate.getName());
Assert.assertEquals(template.getNotificationType(), notificationTemplate.getNotificationType());
// delete notification template
edgeImitator.expectMessageAmount(1);
doDelete("/api/notification/template/" + notificationTemplate.getUuidId())
.andExpect(status().isOk());
Assert.assertTrue(edgeImitator.waitForMessages());
latestMessage = edgeImitator.getLatestMessage();
Assert.assertTrue(latestMessage instanceof NotificationTemplateUpdateMsg);
notificationTemplateUpdateMsg = (NotificationTemplateUpdateMsg) latestMessage;
Assert.assertEquals(UpdateMsgType.ENTITY_DELETED_RPC_MESSAGE, notificationTemplateUpdateMsg.getMsgType());
Assert.assertEquals(notificationTemplate.getUuidId().getMostSignificantBits(), notificationTemplateUpdateMsg.getIdMSB());
Assert.assertEquals(notificationTemplate.getUuidId().getLeastSignificantBits(), notificationTemplateUpdateMsg.getIdLSB());
}
@Test
public void testNotificationTarget() throws Exception {
// create notification target
edgeImitator.expectMessageAmount(1);
NotificationTarget target = createNotificationTarget();
Assert.assertTrue(edgeImitator.waitForMessages());
AbstractMessage latestMessage = edgeImitator.getLatestMessage();
Assert.assertTrue(latestMessage instanceof NotificationTargetUpdateMsg);
NotificationTargetUpdateMsg notificationTargetUpdateMsg = (NotificationTargetUpdateMsg) latestMessage;
Assert.assertEquals(UpdateMsgType.ENTITY_CREATED_RPC_MESSAGE, notificationTargetUpdateMsg.getMsgType());
NotificationTarget notificationTarget = JacksonUtil.fromString(notificationTargetUpdateMsg.getEntity(), NotificationTarget.class, true);
Assert.assertNotNull(notificationTarget);
Assert.assertEquals(target, notificationTarget);
// update notification target
edgeImitator.expectMessageAmount(1);
target.setName(StringUtils.randomAlphanumeric(15));
target = saveNotificationTarget(target);
Assert.assertTrue(edgeImitator.waitForMessages());
latestMessage = edgeImitator.getLatestMessage();
Assert.assertTrue(latestMessage instanceof NotificationTargetUpdateMsg);
notificationTargetUpdateMsg = (NotificationTargetUpdateMsg) latestMessage;
Assert.assertEquals(UpdateMsgType.ENTITY_UPDATED_RPC_MESSAGE, notificationTargetUpdateMsg.getMsgType());
notificationTarget = JacksonUtil.fromString(notificationTargetUpdateMsg.getEntity(), NotificationTarget.class, true);
Assert.assertNotNull(notificationTarget);
Assert.assertEquals(target, notificationTarget);
// delete notification target
edgeImitator.expectMessageAmount(1);
doDelete("/api/notification/target/" + notificationTarget.getUuidId())
.andExpect(status().isOk());
Assert.assertTrue(edgeImitator.waitForMessages());
latestMessage = edgeImitator.getLatestMessage();
Assert.assertTrue(latestMessage instanceof NotificationTargetUpdateMsg);
notificationTargetUpdateMsg = (NotificationTargetUpdateMsg) latestMessage;
Assert.assertEquals(UpdateMsgType.ENTITY_DELETED_RPC_MESSAGE, notificationTargetUpdateMsg.getMsgType());
Assert.assertEquals(notificationTarget.getUuidId().getMostSignificantBits(), notificationTargetUpdateMsg.getIdMSB());
Assert.assertEquals(notificationTarget.getUuidId().getLeastSignificantBits(), notificationTargetUpdateMsg.getIdLSB());
}
@Test
public void testNotificationRule() throws Exception {
// create notification template for notification rule
edgeImitator.expectMessageAmount(1);
NotificationDeliveryMethod[] deliveryMethods = new NotificationDeliveryMethod[]{
NotificationDeliveryMethod.WEB, NotificationDeliveryMethod.EMAIL
};
NotificationTemplate template = createNotificationTemplate(NotificationType.EDGE_CONNECTION, deliveryMethods);
Assert.assertTrue(edgeImitator.waitForMessages());
AbstractMessage latestMessage = edgeImitator.getLatestMessage();
Assert.assertTrue(latestMessage instanceof NotificationTemplateUpdateMsg);
NotificationTemplateUpdateMsg notificationTemplateUpdateMsg = (NotificationTemplateUpdateMsg) latestMessage;
Assert.assertEquals(UpdateMsgType.ENTITY_CREATED_RPC_MESSAGE, notificationTemplateUpdateMsg.getMsgType());
NotificationTemplate notificationTemplate = JacksonUtil.fromString(notificationTemplateUpdateMsg.getEntity(), NotificationTemplate.class, true);
Assert.assertNotNull(notificationTemplate);
Assert.assertEquals(template.getId(), notificationTemplate.getId());
Assert.assertEquals(template.getName(), notificationTemplate.getName());
Assert.assertEquals(template.getNotificationType(), notificationTemplate.getNotificationType());
// create notification rule
edgeImitator.expectMessageAmount(1);
NotificationRule rule = createNotificationRule(template);
Assert.assertTrue(edgeImitator.waitForMessages());
latestMessage = edgeImitator.getLatestMessage();
Assert.assertTrue(latestMessage instanceof NotificationRuleUpdateMsg);
NotificationRuleUpdateMsg notificationRuleUpdateMsg = (NotificationRuleUpdateMsg) latestMessage;
Assert.assertEquals(UpdateMsgType.ENTITY_CREATED_RPC_MESSAGE, notificationRuleUpdateMsg.getMsgType());
NotificationRule notificationRule = JacksonUtil.fromString(notificationRuleUpdateMsg.getEntity(), NotificationRule.class, true);
Assert.assertNotNull(notificationRule);
Assert.assertEquals(rule, notificationRule);
// update notification rule
edgeImitator.expectMessageAmount(1);
rule.setEnabled(false);
rule = saveNotificationRule(rule);
Assert.assertTrue(edgeImitator.waitForMessages());
latestMessage = edgeImitator.getLatestMessage();
Assert.assertTrue(latestMessage instanceof NotificationRuleUpdateMsg);
notificationRuleUpdateMsg = (NotificationRuleUpdateMsg) latestMessage;
Assert.assertEquals(UpdateMsgType.ENTITY_UPDATED_RPC_MESSAGE, notificationRuleUpdateMsg.getMsgType());
notificationRule = JacksonUtil.fromString(notificationRuleUpdateMsg.getEntity(), NotificationRule.class, true);
Assert.assertNotNull(notificationRule);
Assert.assertEquals(rule, notificationRule);
// delete notification rule
edgeImitator.expectMessageAmount(1);
doDelete("/api/notification/rule/" + notificationRule.getUuidId())
.andExpect(status().isOk());
Assert.assertTrue(edgeImitator.waitForMessages());
latestMessage = edgeImitator.getLatestMessage();
Assert.assertTrue(latestMessage instanceof NotificationRuleUpdateMsg);
notificationRuleUpdateMsg = (NotificationRuleUpdateMsg) latestMessage;
Assert.assertEquals(UpdateMsgType.ENTITY_DELETED_RPC_MESSAGE, notificationRuleUpdateMsg.getMsgType());
Assert.assertEquals(notificationRule.getUuidId().getMostSignificantBits(), notificationRuleUpdateMsg.getIdMSB());
Assert.assertEquals(notificationRule.getUuidId().getLeastSignificantBits(), notificationRuleUpdateMsg.getIdLSB());
// delete notification template
edgeImitator.expectMessageAmount(1);
doDelete("/api/notification/template/" + notificationTemplate.getUuidId())
.andExpect(status().isOk());
Assert.assertTrue(edgeImitator.waitForMessages());
latestMessage = edgeImitator.getLatestMessage();
Assert.assertTrue(latestMessage instanceof NotificationTemplateUpdateMsg);
notificationTemplateUpdateMsg = (NotificationTemplateUpdateMsg) latestMessage;
Assert.assertEquals(UpdateMsgType.ENTITY_DELETED_RPC_MESSAGE, notificationTemplateUpdateMsg.getMsgType());
Assert.assertEquals(notificationTemplate.getUuidId().getMostSignificantBits(), notificationTemplateUpdateMsg.getIdMSB());
Assert.assertEquals(notificationTemplate.getUuidId().getLeastSignificantBits(), notificationTemplateUpdateMsg.getIdLSB());
}
private NotificationTemplate createNotificationTemplate(NotificationType notificationType, NotificationDeliveryMethod... deliveryMethods) {
NotificationTemplate notificationTemplate = new NotificationTemplate();
notificationTemplate.setTenantId(tenantId);
notificationTemplate.setName(StringUtils.randomAlphanumeric(15));
notificationTemplate.setNotificationType(notificationType);
NotificationTemplateConfig config = new NotificationTemplateConfig();
config.setDeliveryMethodsTemplates(new HashMap<>());
for (NotificationDeliveryMethod deliveryMethod : deliveryMethods) {
DeliveryMethodNotificationTemplate deliveryMethodNotificationTemplate;
switch (deliveryMethod) {
case WEB -> deliveryMethodNotificationTemplate = new WebDeliveryMethodNotificationTemplate();
case EMAIL -> deliveryMethodNotificationTemplate = new EmailDeliveryMethodNotificationTemplate();
case SMS -> deliveryMethodNotificationTemplate = new SmsDeliveryMethodNotificationTemplate();
case MOBILE_APP -> deliveryMethodNotificationTemplate = new MobileAppDeliveryMethodNotificationTemplate();
default -> throw new IllegalArgumentException("Unsupported delivery method " + deliveryMethod);
}
deliveryMethodNotificationTemplate.setEnabled(true);
deliveryMethodNotificationTemplate.setBody("Test text");
if (deliveryMethodNotificationTemplate instanceof HasSubject) {
((HasSubject) deliveryMethodNotificationTemplate).setSubject("Test subject");
}
config.getDeliveryMethodsTemplates().put(deliveryMethod, deliveryMethodNotificationTemplate);
}
notificationTemplate.setConfiguration(config);
return saveNotificationTemplate(notificationTemplate);
}
private NotificationTarget createNotificationTarget() {
NotificationTarget notificationTarget = new NotificationTarget();
notificationTarget.setTenantId(tenantId);
notificationTarget.setName("Test target");
PlatformUsersNotificationTargetConfig targetConfig = new PlatformUsersNotificationTargetConfig();
TenantAdministratorsFilter tenantAdministratorsFilter = new TenantAdministratorsFilter();
tenantAdministratorsFilter.setTenantsIds(Set.of());
tenantAdministratorsFilter.setTenantProfilesIds(Set.of());
targetConfig.setUsersFilter(tenantAdministratorsFilter);
notificationTarget.setConfiguration(targetConfig);
return saveNotificationTarget(notificationTarget);
}
private NotificationRule createNotificationRule(NotificationTemplate notificationTemplate) {
NotificationRule notificationRule = new NotificationRule();
notificationRule.setName("Web notification on any alarm");
notificationRule.setEnabled(true);
notificationRule.setTemplateId(notificationTemplate.getId());
notificationRule.setTriggerType(NotificationRuleTriggerType.ALARM);
AlarmNotificationRuleTriggerConfig triggerConfig = new AlarmNotificationRuleTriggerConfig();
triggerConfig.setAlarmTypes(null);
triggerConfig.setAlarmSeverities(null);
triggerConfig.setNotifyOn(Set.of(AlarmNotificationRuleTriggerConfig.AlarmAction.CREATED, AlarmNotificationRuleTriggerConfig.AlarmAction.SEVERITY_CHANGED, AlarmNotificationRuleTriggerConfig.AlarmAction.ACKNOWLEDGED, AlarmNotificationRuleTriggerConfig.AlarmAction.CLEARED));
notificationRule.setTriggerConfig(triggerConfig);
EscalatedNotificationRuleRecipientsConfig recipientsConfig = new EscalatedNotificationRuleRecipientsConfig();
recipientsConfig.setTriggerType(NotificationRuleTriggerType.ALARM);
Map<Integer, List<UUID>> escalationTable = new HashMap<>();
escalationTable.put(Integer.valueOf("1"), new ArrayList<>());
recipientsConfig.setEscalationTable(escalationTable);
notificationRule.setRecipientsConfig(recipientsConfig);
return saveNotificationRule(notificationRule);
}
private NotificationTemplate saveNotificationTemplate(NotificationTemplate notificationTemplate) {
return doPost("/api/notification/template", notificationTemplate, NotificationTemplate.class);
}
private NotificationTarget saveNotificationTarget(NotificationTarget notificationTarget) {
return doPost("/api/notification/target", notificationTarget, NotificationTarget.class);
}
private NotificationRule saveNotificationRule(NotificationRule notificationRule) {
return doPost("/api/notification/rule", notificationRule, NotificationRule.class);
}
}

28
application/src/test/java/org/thingsboard/server/edge/imitator/EdgeImitator.java

@ -44,6 +44,9 @@ import org.thingsboard.server.gen.edge.v1.DownlinkResponseMsg;
import org.thingsboard.server.gen.edge.v1.EdgeConfiguration;
import org.thingsboard.server.gen.edge.v1.EntityDataProto;
import org.thingsboard.server.gen.edge.v1.EntityViewUpdateMsg;
import org.thingsboard.server.gen.edge.v1.NotificationRuleUpdateMsg;
import org.thingsboard.server.gen.edge.v1.NotificationTargetUpdateMsg;
import org.thingsboard.server.gen.edge.v1.NotificationTemplateUpdateMsg;
import org.thingsboard.server.gen.edge.v1.OAuth2UpdateMsg;
import org.thingsboard.server.gen.edge.v1.OtaPackageUpdateMsg;
import org.thingsboard.server.gen.edge.v1.QueueUpdateMsg;
@ -74,16 +77,16 @@ import java.util.stream.Collectors;
@Slf4j
public class EdgeImitator {
private String routingKey;
private String routingSecret;
private final String routingKey;
private final String routingSecret;
private EdgeRpcClient edgeRpcClient;
private final EdgeRpcClient edgeRpcClient;
private final Lock lock = new ReentrantLock();
private CountDownLatch messagesLatch;
private CountDownLatch responsesLatch;
private List<Class<? extends AbstractMessage>> ignoredTypes;
private final List<Class<? extends AbstractMessage>> ignoredTypes;
@Setter
private boolean randomFailuresOnTimeseriesDownlink = false;
@ -93,7 +96,7 @@ public class EdgeImitator {
@Getter
private EdgeConfiguration configuration;
@Getter
private List<AbstractMessage> downlinkMsgs;
private final List<AbstractMessage> downlinkMsgs;
@Getter
private UplinkResponseMsg latestResponseMsg;
@ -320,6 +323,21 @@ public class EdgeImitator {
result.add(saveDownlinkMsg(oAuth2UpdateMsg));
}
}
if (downlinkMsg.getNotificationTemplateUpdateMsgCount() > 0) {
for (NotificationTemplateUpdateMsg notificationTemplateUpdateMsg : downlinkMsg.getNotificationTemplateUpdateMsgList()) {
result.add(saveDownlinkMsg(notificationTemplateUpdateMsg));
}
}
if (downlinkMsg.getNotificationRuleUpdateMsgCount() > 0) {
for (NotificationRuleUpdateMsg notificationRuleUpdateMsg : downlinkMsg.getNotificationRuleUpdateMsgList()) {
result.add(saveDownlinkMsg(notificationRuleUpdateMsg));
}
}
if (downlinkMsg.getNotificationTargetUpdateMsgCount() > 0) {
for (NotificationTargetUpdateMsg notificationTargetUpdateMsg : downlinkMsg.getNotificationTargetUpdateMsgList()) {
result.add(saveDownlinkMsg(notificationTargetUpdateMsg));
}
}
if (downlinkMsg.hasEdgeConfiguration()) {
result.add(saveDownlinkMsg(downlinkMsg.getEdgeConfiguration()));
}

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

@ -46,6 +46,9 @@ import org.thingsboard.server.dao.edge.EdgeEventService;
import org.thingsboard.server.dao.edge.EdgeService;
import org.thingsboard.server.dao.edge.EdgeSynchronizationManager;
import org.thingsboard.server.dao.entityview.EntityViewService;
import org.thingsboard.server.dao.notification.NotificationRuleService;
import org.thingsboard.server.dao.notification.NotificationTargetService;
import org.thingsboard.server.dao.notification.NotificationTemplateService;
import org.thingsboard.server.dao.oauth2.OAuth2Service;
import org.thingsboard.server.dao.ota.OtaPackageService;
import org.thingsboard.server.dao.queue.QueueService;
@ -82,6 +85,7 @@ import org.thingsboard.server.service.edge.rpc.constructor.edge.EdgeMsgConstruct
import org.thingsboard.server.service.edge.rpc.constructor.entityview.EntityViewMsgConstructorFactory;
import org.thingsboard.server.service.edge.rpc.constructor.entityview.EntityViewMsgConstructorV1;
import org.thingsboard.server.service.edge.rpc.constructor.entityview.EntityViewMsgConstructorV2;
import org.thingsboard.server.service.edge.rpc.constructor.notification.NotificationMsgConstructor;
import org.thingsboard.server.service.edge.rpc.constructor.oauth2.OAuth2MsgConstructor;
import org.thingsboard.server.service.edge.rpc.constructor.ota.OtaPackageMsgConstructorFactory;
import org.thingsboard.server.service.edge.rpc.constructor.ota.OtaPackageMsgConstructorV1;
@ -130,6 +134,7 @@ import org.thingsboard.server.service.edge.rpc.processor.device.profile.DevicePr
import org.thingsboard.server.service.edge.rpc.processor.entityview.EntityViewProcessorFactory;
import org.thingsboard.server.service.edge.rpc.processor.entityview.EntityViewProcessorV1;
import org.thingsboard.server.service.edge.rpc.processor.entityview.EntityViewProcessorV2;
import org.thingsboard.server.service.edge.rpc.processor.notification.NotificationEdgeProcessor;
import org.thingsboard.server.service.edge.rpc.processor.oauth2.OAuth2EdgeProcessor;
import org.thingsboard.server.service.edge.rpc.processor.relation.RelationEdgeProcessorFactory;
import org.thingsboard.server.service.edge.rpc.processor.relation.RelationEdgeProcessorV1;
@ -197,6 +202,15 @@ public abstract class BaseEdgeProcessorTest {
@MockBean
protected UserService userService;
@MockBean
protected NotificationRuleService notificationRuleService;
@MockBean
protected NotificationTargetService notificationTargetService;
@MockBean
protected NotificationTemplateService notificationTemplateService;
@MockBean
protected DeviceProfileService deviceProfileService;
@ -366,6 +380,9 @@ public abstract class BaseEdgeProcessorTest {
@MockBean
protected WidgetMsgConstructorV2 widgetMsgConstructorV2;
@MockBean
protected NotificationMsgConstructor notificationMsgConstructor;
@MockBean
protected OAuth2MsgConstructor oAuth2MsgConstructor;
@ -429,6 +446,9 @@ public abstract class BaseEdgeProcessorTest {
@MockBean
protected OAuth2EdgeProcessor oAuth2EdgeProcessor;
@MockBean
protected NotificationEdgeProcessor notificationEdgeProcessor;
@SpyBean
protected RuleChainMsgConstructorFactory ruleChainMsgConstructorFactory;

3
common/data/src/main/java/org/thingsboard/server/common/data/edge/EdgeEventType.java

@ -41,6 +41,9 @@ public enum EdgeEventType {
ADMIN_SETTINGS(true, null),
OTA_PACKAGE(true, EntityType.OTA_PACKAGE),
QUEUE(true, EntityType.QUEUE),
NOTIFICATION_RULE (true, EntityType.NOTIFICATION_RULE),
NOTIFICATION_TARGET (true, EntityType.NOTIFICATION_TARGET),
NOTIFICATION_TEMPLATE (true, EntityType.NOTIFICATION_TEMPLATE),
TB_RESOURCE(true, EntityType.TB_RESOURCE),
OAUTH2(true, null);

6
common/data/src/main/java/org/thingsboard/server/common/data/id/EntityIdFactory.java

@ -147,6 +147,12 @@ public class EntityIdFactory {
return new QueueId(uuid);
case TB_RESOURCE:
return new TbResourceId(uuid);
case NOTIFICATION_RULE:
return new NotificationRuleId(uuid);
case NOTIFICATION_TARGET:
return new NotificationTargetId(uuid);
case NOTIFICATION_TEMPLATE:
return new NotificationTemplateId(uuid);
}
throw new IllegalArgumentException("EdgeEventType " + edgeEventType + " is not supported!");
}

24
common/edge-api/src/main/proto/edge.proto

@ -473,6 +473,27 @@ message OAuth2UpdateMsg {
string entity = 1;
}
message NotificationRuleUpdateMsg {
UpdateMsgType msgType = 1;
optional int64 idMSB = 2;
optional int64 idLSB = 3;
optional string entity = 4;
}
message NotificationTargetUpdateMsg {
UpdateMsgType msgType = 1;
optional int64 idMSB = 2;
optional int64 idLSB = 3;
optional string entity = 4;
}
message NotificationTemplateUpdateMsg {
UpdateMsgType msgType = 1;
optional int64 idMSB = 2;
optional int64 idLSB = 3;
optional string entity = 4;
}
message RuleChainMetadataRequestMsg {
int64 ruleChainIdMSB = 1;
int64 ruleChainIdLSB = 2;
@ -675,5 +696,8 @@ message DownlinkMsg {
repeated ResourceUpdateMsg resourceUpdateMsg = 28;
repeated AlarmCommentUpdateMsg alarmCommentUpdateMsg = 29;
repeated OAuth2UpdateMsg oAuth2UpdateMsg = 30;
repeated NotificationRuleUpdateMsg notificationRuleUpdateMsg = 31;
repeated NotificationTargetUpdateMsg notificationTargetUpdateMsg = 32;
repeated NotificationTemplateUpdateMsg notificationTemplateUpdateMsg = 33;
}

21
dao/src/main/java/org/thingsboard/server/dao/notification/DefaultNotificationTargetService.java

@ -42,6 +42,8 @@ import org.thingsboard.server.common.data.page.PageData;
import org.thingsboard.server.common.data.page.PageLink;
import org.thingsboard.server.dao.entity.AbstractEntityService;
import org.thingsboard.server.dao.entity.EntityDaoService;
import org.thingsboard.server.dao.eventsourcing.DeleteEntityEvent;
import org.thingsboard.server.dao.eventsourcing.SaveEntityEvent;
import org.thingsboard.server.dao.user.UserService;
import java.util.List;
@ -65,7 +67,10 @@ public class DefaultNotificationTargetService extends AbstractEntityService impl
@Override
public NotificationTarget saveNotificationTarget(TenantId tenantId, NotificationTarget notificationTarget) {
try {
return notificationTargetDao.saveAndFlush(tenantId, notificationTarget);
NotificationTarget savedTarget = notificationTargetDao.saveAndFlush(tenantId, notificationTarget);
eventPublisher.publishEvent(SaveEntityEvent.builder().tenantId(tenantId).entityId(savedTarget.getId())
.created(notificationTarget.getId() == null).build());
return savedTarget;
} catch (Exception e) {
checkConstraintViolation(e, Map.of(
"uq_notification_target_name", "Recipients group with such name already exists"
@ -158,19 +163,21 @@ public class DefaultNotificationTargetService extends AbstractEntityService impl
@Override
public PageData<User> findRecipientsForRuleNotificationTargetConfig(TenantId tenantId, PlatformUsersNotificationTargetConfig targetConfig, RuleOriginatedNotificationInfo info, PageLink pageLink) {
switch (targetConfig.getUsersFilter().getType()) {
case ORIGINATOR_ENTITY_OWNER_USERS:
case ORIGINATOR_ENTITY_OWNER_USERS -> {
CustomerId customerId = info.getAffectedCustomerId();
if (customerId != null && !customerId.isNullUid()) {
return userService.findCustomerUsers(tenantId, customerId, pageLink);
} else {
return userService.findTenantAdmins(tenantId, pageLink);
}
case AFFECTED_USER:
}
case AFFECTED_USER -> {
UserId userId = info.getAffectedUserId();
if (userId != null) {
return new PageData<>(List.of(userService.findUserById(tenantId, userId)), 1, 1, false);
}
case AFFECTED_TENANT_ADMINISTRATORS:
}
case AFFECTED_TENANT_ADMINISTRATORS -> {
TenantId affectedTenantId = info.getAffectedTenantId();
if (affectedTenantId == null) {
affectedTenantId = tenantId;
@ -178,9 +185,8 @@ public class DefaultNotificationTargetService extends AbstractEntityService impl
if (!affectedTenantId.isNullUid()) {
return userService.findTenantAdmins(affectedTenantId, pageLink);
}
break;
default:
throw new IllegalArgumentException("Recipient type not supported");
}
default -> throw new IllegalArgumentException("Recipient type not supported");
}
return new PageData<>();
}
@ -194,6 +200,7 @@ public class DefaultNotificationTargetService extends AbstractEntityService impl
throw new IllegalArgumentException("Recipients group is being used in notification rule");
}
notificationTargetDao.removeById(tenantId, id.getId());
eventPublisher.publishEvent(DeleteEntityEvent.builder().tenantId(tenantId).entityId(id).build());
}
@Override

8
dao/src/main/java/org/thingsboard/server/dao/notification/DefaultNotificationTemplateService.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.dao.entity.AbstractEntityService;
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.Map;
@ -55,7 +57,10 @@ public class DefaultNotificationTemplateService extends AbstractEntityService im
}
}
try {
return notificationTemplateDao.saveAndFlush(tenantId, notificationTemplate);
NotificationTemplate savedTemplate = notificationTemplateDao.saveAndFlush(tenantId, notificationTemplate);
eventPublisher.publishEvent(SaveEntityEvent.builder().tenantId(tenantId).entityId(savedTemplate.getId())
.created(notificationTemplate.getId() == null).build());
return savedTemplate;
} catch (Exception e) {
checkConstraintViolation(e, Map.of(
"uq_notification_template_name", "Notification template with such name already exists"
@ -82,6 +87,7 @@ public class DefaultNotificationTemplateService extends AbstractEntityService im
));
throw e;
}
eventPublisher.publishEvent(DeleteEntityEvent.builder().tenantId(tenantId).entityId(id).build());
}
@Override

Loading…
Cancel
Save