Browse Source

Add new notification types; WS api docs

pull/7980/head
ViacheslavKlimov 4 years ago
parent
commit
376c4c95d1
  1. 49
      application/src/main/java/org/thingsboard/server/controller/NotificationController.java
  2. 8
      application/src/main/java/org/thingsboard/server/controller/NotificationTemplateController.java
  3. 39
      application/src/main/java/org/thingsboard/server/service/notification/rule/DefaultNotificationRuleProcessingService.java
  4. 14
      application/src/main/java/org/thingsboard/server/service/notification/rule/trigger/AlarmNotificationRuleTriggerProcessor.java
  5. 11
      application/src/main/java/org/thingsboard/server/service/notification/rule/trigger/DeviceInactivityNotificationRuleTriggerProcessor.java
  6. 24
      application/src/main/java/org/thingsboard/server/service/notification/rule/trigger/EntityActionNotificationRuleTriggerProcessor.java
  7. 3
      application/src/main/java/org/thingsboard/server/service/notification/rule/trigger/NotificationRuleTriggerProcessor.java
  8. 17
      application/src/test/java/org/thingsboard/server/service/notification/NotificationRuleApiTest.java
  9. 38
      application/src/test/java/org/thingsboard/server/service/notification/NotificationTemplateApiTest.java
  10. 5
      common/dao-api/src/main/java/org/thingsboard/server/dao/notification/NotificationTemplateService.java
  11. 4
      common/data/src/main/java/org/thingsboard/server/common/data/notification/NotificationProcessingContext.java
  12. 13
      common/data/src/main/java/org/thingsboard/server/common/data/notification/NotificationType.java
  13. 6
      common/data/src/main/java/org/thingsboard/server/common/data/notification/info/AlarmNotificationInfo.java
  14. 51
      common/data/src/main/java/org/thingsboard/server/common/data/notification/info/DeviceInactivityNotificationInfo.java
  15. 57
      common/data/src/main/java/org/thingsboard/server/common/data/notification/info/EntityActionNotificationInfo.java
  16. 12
      common/data/src/main/java/org/thingsboard/server/common/data/notification/info/NotificationInfo.java
  17. 2
      common/data/src/main/java/org/thingsboard/server/common/data/notification/info/UserOriginatedNotificationInfo.java
  18. 2
      common/data/src/main/java/org/thingsboard/server/common/data/notification/targets/NotificationTargetConfig.java
  19. 6
      dao/src/main/java/org/thingsboard/server/dao/notification/DefaultNotificationTemplateService.java
  20. 5
      dao/src/main/java/org/thingsboard/server/dao/notification/NotificationTemplateDao.java
  21. 8
      dao/src/main/java/org/thingsboard/server/dao/sql/notification/JpaNotificationTemplateDao.java
  22. 10
      dao/src/main/java/org/thingsboard/server/dao/sql/notification/NotificationTemplateRepository.java
  23. 8
      rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/notification/TbNotificationNode.java

49
application/src/main/java/org/thingsboard/server/controller/NotificationController.java

@ -15,6 +15,7 @@
*/ */
package org.thingsboard.server.controller; package org.thingsboard.server.controller;
import io.swagger.annotations.ApiOperation;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.security.access.prepost.PreAuthorize;
@ -77,6 +78,54 @@ public class NotificationController extends BaseController {
private final NotificationCenter notificationCenter; private final NotificationCenter notificationCenter;
private final NotificationSettingsService notificationSettingsService; private final NotificationSettingsService notificationSettingsService;
@ApiOperation(value = "Get notifications (getNotifications)",
notes = "**WebSocket API**:\n\n" +
"There are 2 types of subscriptions: one for unread notifications count, another for unread notifications themselves.\n\n" +
"The URI for opening WS session for notifications: `/api/ws/plugins/notifications`.\n\n" +
"Subscription command for unread notifications count:\n" +
"```\n{\n \"unreadCountSubCmd\": {\n \"cmdId\": 1234\n }\n}\n```\n" +
"To subscribe for latest unread notifications:\n" +
"```\n{\n \"unreadSubCmd\": {\n \"cmdId\": 1234,\n \"limit\": 10\n }\n}\n```\n" +
"To unsubscribe from any subscription:\n" +
"```\n{\n \"unsubCmd\": {\n \"cmdId\": 1234\n }\n}\n```\n" +
"To mark certain notifications as read, use following command:\n" +
"```\n{\n \"markAsReadCmd\": {\n \"cmdId\": 1234,\n \"notifications\": [\n \"6f860330-7fc2-11ed-b855-7dd3b7d2faa9\",\n \"5b6dfee0-8d0d-11ed-b61f-35a57b03dade\"\n ]\n }\n}\n\n```\n" +
"\n\n" +
"Update structure for unread **notifications count subscription**:\n" +
"```\n{\n \"cmdId\": 1234,\n \"totalUnreadCount\": 55\n}\n```\n" +
"For **notifications subscription**:\n" +
"- full update of latest unread notifications:\n" +
"```\n{\n" +
" \"cmdId\": 1234,\n" +
" \"notifications\": [\n" +
" {\n" +
" \"id\": {\n" +
" \"entityType\": \"NOTIFICATION\",\n" +
" \"id\": \"6f860330-7fc2-11ed-b855-7dd3b7d2faa9\"\n" +
" },\n" +
" ...\n" +
" }\n" +
" ],\n" +
" \"totalUnreadCount\": 1\n" +
"}\n```\n" +
"- when new notification arrives or shown notification is updated:\n" +
"```\n{\n" +
" \"cmdId\": 1234,\n" +
" \"update\": {\n" +
" \"id\": {\n" +
" \"entityType\": \"NOTIFICATION\",\n" +
" \"id\": \"6f860330-7fc2-11ed-b855-7dd3b7d2faa9\"\n" +
" },\n" +
" # updated notification info, text, subject etc.\n" +
" ...\n" +
" },\n" +
" \"totalUnreadCount\": 2\n" +
"}\n```\n" +
"- when unread notifications count changes:\n" +
"```\n{\n" +
" \"cmdId\": 1234,\n" +
" \"totalUnreadCount\": 5\n" +
"}\n```" )
@GetMapping("/notifications") @GetMapping("/notifications")
@PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN', 'CUSTOMER_USER')") @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN', 'CUSTOMER_USER')")
public PageData<Notification> getNotifications(@RequestParam int pageSize, public PageData<Notification> getNotifications(@RequestParam int pageSize,

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

@ -32,6 +32,7 @@ import org.thingsboard.server.common.data.EntityType;
import org.thingsboard.server.common.data.exception.ThingsboardException; import org.thingsboard.server.common.data.exception.ThingsboardException;
import org.thingsboard.server.common.data.id.NotificationTemplateId; import org.thingsboard.server.common.data.id.NotificationTemplateId;
import org.thingsboard.server.common.data.notification.NotificationDeliveryMethod; import org.thingsboard.server.common.data.notification.NotificationDeliveryMethod;
import org.thingsboard.server.common.data.notification.NotificationType;
import org.thingsboard.server.common.data.notification.settings.NotificationSettings; import org.thingsboard.server.common.data.notification.settings.NotificationSettings;
import org.thingsboard.server.common.data.notification.settings.SlackNotificationDeliveryMethodConfig; import org.thingsboard.server.common.data.notification.settings.SlackNotificationDeliveryMethodConfig;
import org.thingsboard.server.common.data.notification.template.NotificationTemplate; import org.thingsboard.server.common.data.notification.template.NotificationTemplate;
@ -104,9 +105,14 @@ public class NotificationTemplateController extends BaseController {
@RequestParam(required = false) String textSearch, @RequestParam(required = false) String textSearch,
@RequestParam(required = false) String sortProperty, @RequestParam(required = false) String sortProperty,
@RequestParam(required = false) String sortOrder, @RequestParam(required = false) String sortOrder,
@RequestParam(required = false) NotificationType[] notificationTypes,
@AuthenticationPrincipal SecurityUser user) throws ThingsboardException { @AuthenticationPrincipal SecurityUser user) throws ThingsboardException {
PageLink pageLink = createPageLink(pageSize, page, textSearch, sortProperty, sortOrder); PageLink pageLink = createPageLink(pageSize, page, textSearch, sortProperty, sortOrder);
return notificationTemplateService.findNotificationTemplatesByTenantId(user.getTenantId(), pageLink); if (notificationTypes == null || notificationTypes.length == 0) {
notificationTypes = NotificationType.values();
}
return notificationTemplateService.findNotificationTemplatesByTenantIdAndNotificationTypes(user.getTenantId(),
List.of(notificationTypes), pageLink);
} }
@ApiOperation(value = "Delete notification template by id (deleteNotificationTemplateById", @ApiOperation(value = "Delete notification template by id (deleteNotificationTemplateById",

39
application/src/main/java/org/thingsboard/server/service/notification/rule/DefaultNotificationRuleProcessingService.java

@ -34,9 +34,7 @@ import org.thingsboard.server.common.data.id.TenantId;
import org.thingsboard.server.common.data.notification.NotificationRequest; import org.thingsboard.server.common.data.notification.NotificationRequest;
import org.thingsboard.server.common.data.notification.NotificationRequestConfig; import org.thingsboard.server.common.data.notification.NotificationRequestConfig;
import org.thingsboard.server.common.data.notification.NotificationRequestStatus; import org.thingsboard.server.common.data.notification.NotificationRequestStatus;
import org.thingsboard.server.common.data.notification.info.AlarmOriginatedNotificationInfo;
import org.thingsboard.server.common.data.notification.info.NotificationInfo; import org.thingsboard.server.common.data.notification.info.NotificationInfo;
import org.thingsboard.server.common.data.notification.info.RuleEngineOriginatedNotificationInfo;
import org.thingsboard.server.common.data.notification.rule.NotificationRule; import org.thingsboard.server.common.data.notification.rule.NotificationRule;
import org.thingsboard.server.common.data.notification.rule.trigger.NotificationRuleTriggerConfig; import org.thingsboard.server.common.data.notification.rule.trigger.NotificationRuleTriggerConfig;
import org.thingsboard.server.common.data.notification.rule.trigger.NotificationRuleTriggerType; import org.thingsboard.server.common.data.notification.rule.trigger.NotificationRuleTriggerType;
@ -53,7 +51,6 @@ import java.util.Collection;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.UUID; import java.util.UUID;
import java.util.function.Supplier;
import java.util.stream.Collectors; import java.util.stream.Collectors;
@Service @Service
@ -85,48 +82,30 @@ public class DefaultNotificationRuleProcessingService implements NotificationRul
return; return;
} }
processTrigger(tenantId, triggerType, ruleEngineMsg.getOriginator(), ruleEngineMsg, false, () -> { processTrigger(tenantId, triggerType, ruleEngineMsg.getOriginator(), ruleEngineMsg, false);
return RuleEngineOriginatedNotificationInfo.builder()
.msgOriginator(ruleEngineMsg.getOriginator())
.msgType(ruleEngineMsg.getType())
.msgMetadata(ruleEngineMsg.getMetaData().getData())
.build();
});
} }
@Override @Override
public void process(TenantId tenantId, Alarm alarm, boolean deleted) { public void process(TenantId tenantId, Alarm alarm, boolean deleted) {
processTrigger(tenantId, NotificationRuleTriggerType.ALARM, alarm.getId(), alarm, deleted, () -> { processTrigger(tenantId, NotificationRuleTriggerType.ALARM, alarm.getId(), alarm, deleted);
// TODO: add info about assignee
return AlarmOriginatedNotificationInfo.builder()
.alarmId(alarm.getId())
.alarmType(alarm.getType())
.alarmOriginator(alarm.getOriginator())
.alarmSeverity(alarm.getSeverity())
.alarmStatus(alarm.getStatus())
.customerId(alarm.getCustomerId())
.build();
});
} }
private void processTrigger(TenantId tenantId, NotificationRuleTriggerType triggerType, EntityId originatorEntityId, private void processTrigger(TenantId tenantId, NotificationRuleTriggerType triggerType, EntityId originatorEntityId,
Object triggerObject, boolean triggerRemoved, Object triggerObject, boolean triggerRemoved) {
Supplier<NotificationInfo> notificationInfoProvider) {
ListenableFuture<List<NotificationRule>> rulesFuture = dbCallbackExecutor.submit(() -> { ListenableFuture<List<NotificationRule>> rulesFuture = dbCallbackExecutor.submit(() -> {
return notificationRuleService.findNotificationRulesByTenantIdAndTriggerType(tenantId, triggerType); return notificationRuleService.findNotificationRulesByTenantIdAndTriggerType(tenantId, triggerType);
}); });
DonAsynchron.withCallback(rulesFuture, rules -> { DonAsynchron.withCallback(rulesFuture, rules -> {
for (NotificationRule rule : rules) { for (NotificationRule rule : rules) {
notificationExecutor.submit(() -> { notificationExecutor.submit(() -> {
processNotificationRule(rule, originatorEntityId, triggerObject, triggerRemoved, notificationInfoProvider); processNotificationRule(rule, originatorEntityId, triggerObject, triggerRemoved);
}); });
} }
}, e -> {}); }, e -> {});
} }
private <T> void processNotificationRule(NotificationRule rule, EntityId originatorEntityId, private <T> void processNotificationRule(NotificationRule rule, EntityId originatorEntityId,
T triggerObject, boolean triggerRemoved, T triggerObject, boolean triggerRemoved) {
Supplier<NotificationInfo> notificationInfoProvider) {
NotificationRuleTriggerConfig triggerConfig = rule.getTriggerConfig(); NotificationRuleTriggerConfig triggerConfig = rule.getTriggerConfig();
log.debug("Processing notification rule '{}' for trigger type {}", rule.getName(), rule.getTriggerType()); log.debug("Processing notification rule '{}' for trigger type {}", rule.getName(), rule.getTriggerType());
@ -149,7 +128,7 @@ public class DefaultNotificationRuleProcessingService implements NotificationRul
// not returning because we need to update notifications if any // not returning because we need to update notifications if any
} }
NotificationInfo notificationInfo = notificationInfoProvider.get(); NotificationInfo notificationInfo = constructNotificationInfo(triggerObject, triggerConfig);
for (NotificationRequest notificationRequest : notificationRequests) { for (NotificationRequest notificationRequest : notificationRequests) {
NotificationInfo previousNotificationInfo = notificationRequest.getInfo(); NotificationInfo previousNotificationInfo = notificationRequest.getInfo();
if (!notificationInfo.equals(previousNotificationInfo)) { if (!notificationInfo.equals(previousNotificationInfo)) {
@ -168,7 +147,7 @@ public class DefaultNotificationRuleProcessingService implements NotificationRul
return; return;
} }
NotificationInfo notificationInfo = notificationInfoProvider.get(); NotificationInfo notificationInfo = constructNotificationInfo(triggerObject, triggerConfig);
rule.getRecipientsConfig().getTargetsTable().forEach((delay, targets) -> { rule.getRecipientsConfig().getTargetsTable().forEach((delay, targets) -> {
notificationExecutor.submit(() -> { notificationExecutor.submit(() -> {
try { try {
@ -189,6 +168,10 @@ public class DefaultNotificationRuleProcessingService implements NotificationRul
return triggerProcessors.get(triggerConfig.getTriggerType()).matchesClearRule(triggerObject, triggerConfig); return triggerProcessors.get(triggerConfig.getTriggerType()).matchesClearRule(triggerObject, triggerConfig);
} }
private NotificationInfo constructNotificationInfo(Object triggerObject, NotificationRuleTriggerConfig triggerConfig) {
return triggerProcessors.get(triggerConfig.getTriggerType()).constructNotificationInfo(triggerObject, triggerConfig);
}
private void submitNotificationRequest(List<UUID> targets, NotificationRule rule, private void submitNotificationRequest(List<UUID> targets, NotificationRule rule,
EntityId originatorEntityId, NotificationInfo notificationInfo, int delayInSec) { EntityId originatorEntityId, NotificationInfo notificationInfo, int delayInSec) {
NotificationRequestConfig config = new NotificationRequestConfig(); NotificationRequestConfig config = new NotificationRequestConfig();

14
application/src/main/java/org/thingsboard/server/service/notification/rule/trigger/AlarmNotificationRuleTriggerProcessor.java

@ -18,6 +18,8 @@ package org.thingsboard.server.service.notification.rule.trigger;
import org.apache.commons.collections.CollectionUtils; import org.apache.commons.collections.CollectionUtils;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.thingsboard.server.common.data.alarm.Alarm; import org.thingsboard.server.common.data.alarm.Alarm;
import org.thingsboard.server.common.data.notification.info.AlarmNotificationInfo;
import org.thingsboard.server.common.data.notification.info.NotificationInfo;
import org.thingsboard.server.common.data.notification.rule.trigger.AlarmNotificationRuleTriggerConfig; import org.thingsboard.server.common.data.notification.rule.trigger.AlarmNotificationRuleTriggerConfig;
import org.thingsboard.server.common.data.notification.rule.trigger.NotificationRuleTriggerType; import org.thingsboard.server.common.data.notification.rule.trigger.NotificationRuleTriggerType;
@ -41,6 +43,18 @@ public class AlarmNotificationRuleTriggerProcessor implements NotificationRuleTr
return false; return false;
} }
@Override
public NotificationInfo constructNotificationInfo(Alarm alarm, AlarmNotificationRuleTriggerConfig triggerConfig) {
return AlarmNotificationInfo.builder()
.alarmId(alarm.getUuidId())
.alarmType(alarm.getType())
.alarmOriginator(alarm.getOriginator())
.alarmSeverity(alarm.getSeverity())
.alarmStatus(alarm.getStatus())
.customerId(alarm.getCustomerId())
.build();
}
@Override @Override
public NotificationRuleTriggerType getTriggerType() { public NotificationRuleTriggerType getTriggerType() {
return NotificationRuleTriggerType.ALARM; return NotificationRuleTriggerType.ALARM;

11
application/src/main/java/org/thingsboard/server/service/notification/rule/trigger/DeviceInactivityNotificationRuleTriggerProcessor.java

@ -21,6 +21,8 @@ import org.springframework.stereotype.Service;
import org.thingsboard.server.common.data.DeviceProfile; import org.thingsboard.server.common.data.DeviceProfile;
import org.thingsboard.server.common.data.id.DeviceId; import org.thingsboard.server.common.data.id.DeviceId;
import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.common.data.id.TenantId;
import org.thingsboard.server.common.data.notification.info.DeviceInactivityNotificationInfo;
import org.thingsboard.server.common.data.notification.info.NotificationInfo;
import org.thingsboard.server.common.data.notification.rule.trigger.DeviceInactivityNotificationRuleTriggerConfig; import org.thingsboard.server.common.data.notification.rule.trigger.DeviceInactivityNotificationRuleTriggerConfig;
import org.thingsboard.server.common.data.notification.rule.trigger.NotificationRuleTriggerType; import org.thingsboard.server.common.data.notification.rule.trigger.NotificationRuleTriggerType;
import org.thingsboard.server.common.msg.TbMsg; import org.thingsboard.server.common.msg.TbMsg;
@ -45,6 +47,15 @@ public class DeviceInactivityNotificationRuleTriggerProcessor implements Notific
} }
} }
@Override
public NotificationInfo constructNotificationInfo(TbMsg ruleEngineMsg, DeviceInactivityNotificationRuleTriggerConfig triggerConfig) {
return DeviceInactivityNotificationInfo.builder()
.deviceId(ruleEngineMsg.getOriginator().getId())
.deviceName(ruleEngineMsg.getMetaData().getValue("deviceName"))
.deviceType(ruleEngineMsg.getMetaData().getValue("deviceType"))
.build();
}
@Override @Override
public NotificationRuleTriggerType getTriggerType() { public NotificationRuleTriggerType getTriggerType() {
return NotificationRuleTriggerType.DEVICE_INACTIVITY; return NotificationRuleTriggerType.DEVICE_INACTIVITY;

24
application/src/main/java/org/thingsboard/server/service/notification/rule/trigger/EntityActionNotificationRuleTriggerProcessor.java

@ -17,10 +17,16 @@ package org.thingsboard.server.service.notification.rule.trigger;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.thingsboard.server.common.data.DataConstants; import org.thingsboard.server.common.data.DataConstants;
import org.thingsboard.server.common.data.audit.ActionType;
import org.thingsboard.server.common.data.id.EntityId;
import org.thingsboard.server.common.data.notification.info.EntityActionNotificationInfo;
import org.thingsboard.server.common.data.notification.info.NotificationInfo;
import org.thingsboard.server.common.data.notification.rule.trigger.EntityActionNotificationRuleTriggerConfig; import org.thingsboard.server.common.data.notification.rule.trigger.EntityActionNotificationRuleTriggerConfig;
import org.thingsboard.server.common.data.notification.rule.trigger.NotificationRuleTriggerType; import org.thingsboard.server.common.data.notification.rule.trigger.NotificationRuleTriggerType;
import org.thingsboard.server.common.msg.TbMsg; import org.thingsboard.server.common.msg.TbMsg;
import java.util.UUID;
@Service @Service
public class EntityActionNotificationRuleTriggerProcessor implements NotificationRuleTriggerProcessor<TbMsg, EntityActionNotificationRuleTriggerConfig> { public class EntityActionNotificationRuleTriggerProcessor implements NotificationRuleTriggerProcessor<TbMsg, EntityActionNotificationRuleTriggerConfig> {
@ -35,7 +41,7 @@ public class EntityActionNotificationRuleTriggerProcessor implements Notificatio
if (!triggerConfig.isUpdated()) { if (!triggerConfig.isUpdated()) {
return false; return false;
} }
} else if (msgType.equals(DataConstants.ENTITY_DELETED)){ } else if (msgType.equals(DataConstants.ENTITY_DELETED)) {
if (!triggerConfig.isDeleted()) { if (!triggerConfig.isDeleted()) {
return false; return false;
} }
@ -45,6 +51,22 @@ public class EntityActionNotificationRuleTriggerProcessor implements Notificatio
return triggerConfig.getEntityType() == null || ruleEngineMsg.getOriginator().getEntityType() == triggerConfig.getEntityType(); return triggerConfig.getEntityType() == null || ruleEngineMsg.getOriginator().getEntityType() == triggerConfig.getEntityType();
} }
@Override
public NotificationInfo constructNotificationInfo(TbMsg ruleEngineMsg, EntityActionNotificationRuleTriggerConfig triggerConfig) {
EntityId entityId = ruleEngineMsg.getOriginator();
String msgType = ruleEngineMsg.getType();
ActionType actionType = msgType.equals(DataConstants.ENTITY_CREATED) ? ActionType.ADDED :
msgType.equals(DataConstants.ENTITY_UPDATED) ? ActionType.UPDATED :
msgType.equals(DataConstants.ENTITY_DELETED) ? ActionType.DELETED : null;
return EntityActionNotificationInfo.builder()
.entityType(entityId.getEntityType())
.entityId(entityId.getId())
.actionType(actionType)
.userId(UUID.fromString(ruleEngineMsg.getMetaData().getValue("userId")))
.userName(ruleEngineMsg.getMetaData().getValue("userName"))
.build();
}
@Override @Override
public NotificationRuleTriggerType getTriggerType() { public NotificationRuleTriggerType getTriggerType() {
return NotificationRuleTriggerType.ENTITY_ACTION; return NotificationRuleTriggerType.ENTITY_ACTION;

3
application/src/main/java/org/thingsboard/server/service/notification/rule/trigger/NotificationRuleTriggerProcessor.java

@ -15,6 +15,7 @@
*/ */
package org.thingsboard.server.service.notification.rule.trigger; package org.thingsboard.server.service.notification.rule.trigger;
import org.thingsboard.server.common.data.notification.info.NotificationInfo;
import org.thingsboard.server.common.data.notification.rule.trigger.NotificationRuleTriggerConfig; import org.thingsboard.server.common.data.notification.rule.trigger.NotificationRuleTriggerConfig;
import org.thingsboard.server.common.data.notification.rule.trigger.NotificationRuleTriggerType; import org.thingsboard.server.common.data.notification.rule.trigger.NotificationRuleTriggerType;
@ -26,6 +27,8 @@ public interface NotificationRuleTriggerProcessor<T, C extends NotificationRuleT
return false; return false;
} }
NotificationInfo constructNotificationInfo(T triggerObject, C triggerConfig);
NotificationRuleTriggerType getTriggerType(); NotificationRuleTriggerType getTriggerType();
} }

17
application/src/test/java/org/thingsboard/server/service/notification/NotificationRuleApiTest.java

@ -41,7 +41,7 @@ import org.thingsboard.server.common.data.id.NotificationRuleId;
import org.thingsboard.server.common.data.notification.Notification; import org.thingsboard.server.common.data.notification.Notification;
import org.thingsboard.server.common.data.notification.NotificationDeliveryMethod; import org.thingsboard.server.common.data.notification.NotificationDeliveryMethod;
import org.thingsboard.server.common.data.notification.NotificationType; import org.thingsboard.server.common.data.notification.NotificationType;
import org.thingsboard.server.common.data.notification.info.AlarmOriginatedNotificationInfo; import org.thingsboard.server.common.data.notification.info.AlarmNotificationInfo;
import org.thingsboard.server.common.data.notification.rule.DefaultNotificationRuleRecipientsConfig; import org.thingsboard.server.common.data.notification.rule.DefaultNotificationRuleRecipientsConfig;
import org.thingsboard.server.common.data.notification.rule.EscalatedNotificationRuleRecipientsConfig; 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.NotificationRule;
@ -86,7 +86,7 @@ public class NotificationRuleApiTest extends AbstractNotificationApiTest {
@Test @Test
public void testNotificationRuleProcessing_entityActionTrigger() throws Exception { public void testNotificationRuleProcessing_entityActionTrigger() throws Exception {
String notificationSubject = "${msgType}: ${originatorType} [${originatorId}]"; String notificationSubject = "${actionType}: ${entityType} [${entityId}]";
String notificationText = "User: ${userName}"; String notificationText = "User: ${userName}";
NotificationTemplate notificationTemplate = createNotificationTemplate(NotificationType.GENERAL, notificationSubject, notificationText, NotificationDeliveryMethod.PUSH); NotificationTemplate notificationTemplate = createNotificationTemplate(NotificationType.GENERAL, notificationSubject, notificationText, NotificationDeliveryMethod.PUSH);
@ -117,7 +117,7 @@ public class NotificationRuleApiTest extends AbstractNotificationApiTest {
getWsClient().waitForUpdate(true); getWsClient().waitForUpdate(true);
Notification notification = getWsClient().getLastDataUpdate().getUpdate(); Notification notification = getWsClient().getLastDataUpdate().getUpdate();
assertThat(notification.getSubject()).isEqualTo("ENTITY_CREATED: DEVICE [" + device.getId() + "]"); assertThat(notification.getSubject()).isEqualTo("ADDED: DEVICE [" + device.getId() + "]");
assertThat(notification.getText()).isEqualTo("User: " + TENANT_ADMIN_EMAIL); assertThat(notification.getText()).isEqualTo("User: " + TENANT_ADMIN_EMAIL);
@ -127,7 +127,7 @@ public class NotificationRuleApiTest extends AbstractNotificationApiTest {
getWsClient().waitForUpdate(true); getWsClient().waitForUpdate(true);
notification = getWsClient().getLastDataUpdate().getUpdate(); notification = getWsClient().getLastDataUpdate().getUpdate();
assertThat(notification.getSubject()).isEqualTo("ENTITY_UPDATED: DEVICE [" + device.getId() + "]"); assertThat(notification.getSubject()).isEqualTo("UPDATED: DEVICE [" + device.getId() + "]");
getWsClient().registerWaitForUpdate(); getWsClient().registerWaitForUpdate();
@ -135,8 +135,7 @@ public class NotificationRuleApiTest extends AbstractNotificationApiTest {
getWsClient().waitForUpdate(true); getWsClient().waitForUpdate(true);
notification = getWsClient().getLastDataUpdate().getUpdate(); notification = getWsClient().getLastDataUpdate().getUpdate();
assertThat(notification.getSubject()).isEqualTo("ENTITY_DELETED: DEVICE [" + device.getId() + "]"); assertThat(notification.getSubject()).isEqualTo("DELETED: DEVICE [" + device.getId() + "]");
System.err.println(notification);
} }
@Test @Test
@ -203,9 +202,9 @@ public class NotificationRuleApiTest extends AbstractNotificationApiTest {
assertThat(notification.getText()).isEqualTo("Status: " + expectedStatus + ", severity: " + expectedSeverity); assertThat(notification.getText()).isEqualTo("Status: " + expectedStatus + ", severity: " + expectedSeverity);
assertThat(notification.getType()).isEqualTo(NotificationType.ALARM); assertThat(notification.getType()).isEqualTo(NotificationType.ALARM);
assertThat(notification.getInfo()).isInstanceOf(AlarmOriginatedNotificationInfo.class); assertThat(notification.getInfo()).isInstanceOf(AlarmNotificationInfo.class);
AlarmOriginatedNotificationInfo info = (AlarmOriginatedNotificationInfo) notification.getInfo(); AlarmNotificationInfo info = (AlarmNotificationInfo) notification.getInfo();
assertThat(info.getAlarmId()).isEqualTo(alarm.getId()); assertThat(info.getAlarmId()).isEqualTo(alarm.getUuidId());
assertThat(info.getAlarmType()).isEqualTo(alarmType); assertThat(info.getAlarmType()).isEqualTo(alarmType);
assertThat(info.getAlarmSeverity()).isEqualTo(expectedSeverity); assertThat(info.getAlarmSeverity()).isEqualTo(expectedSeverity);
assertThat(info.getAlarmStatus()).isEqualTo(expectedStatus); assertThat(info.getAlarmStatus()).isEqualTo(expectedStatus);

38
application/src/test/java/org/thingsboard/server/service/notification/NotificationTemplateApiTest.java

@ -15,24 +15,30 @@
*/ */
package org.thingsboard.server.service.notification; package org.thingsboard.server.service.notification;
import com.fasterxml.jackson.core.type.TypeReference;
import org.apache.commons.lang3.StringUtils;
import org.junit.Before; import org.junit.Before;
import org.junit.Test; import org.junit.Test;
import org.springframework.test.web.servlet.ResultActions; import org.springframework.test.web.servlet.ResultActions;
import org.springframework.test.web.servlet.ResultMatcher; import org.springframework.test.web.servlet.ResultMatcher;
import org.thingsboard.server.common.data.id.IdBased;
import org.thingsboard.server.common.data.notification.NotificationDeliveryMethod; import org.thingsboard.server.common.data.notification.NotificationDeliveryMethod;
import org.thingsboard.server.common.data.notification.NotificationType;
import org.thingsboard.server.common.data.notification.template.EmailDeliveryMethodNotificationTemplate; import org.thingsboard.server.common.data.notification.template.EmailDeliveryMethodNotificationTemplate;
import org.thingsboard.server.common.data.notification.template.NotificationTemplate; import org.thingsboard.server.common.data.notification.template.NotificationTemplate;
import org.thingsboard.server.common.data.notification.template.NotificationTemplateConfig; import org.thingsboard.server.common.data.notification.template.NotificationTemplateConfig;
import org.thingsboard.server.controller.AbstractControllerTest; import org.thingsboard.server.common.data.page.PageData;
import org.thingsboard.server.common.data.page.PageLink;
import org.thingsboard.server.dao.service.DaoSqlTest; import org.thingsboard.server.dao.service.DaoSqlTest;
import java.util.List;
import java.util.Map; import java.util.Map;
import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThat;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
@DaoSqlTest @DaoSqlTest
public class NotificationTemplateApiTest extends AbstractControllerTest { public class NotificationTemplateApiTest extends AbstractNotificationApiTest {
@Before @Before
public void beforeEach() throws Exception { public void beforeEach() throws Exception {
@ -78,6 +84,28 @@ public class NotificationTemplateApiTest extends AbstractControllerTest {
.contains("defaultTextTemplate").contains("must be specified"); .contains("defaultTextTemplate").contains("must be specified");
} }
@Test
public void testTemplatesSearch() throws Exception {
NotificationTemplate alarmNotificationTemplate = createNotificationTemplate(NotificationType.ALARM, "Alarm", "Alarm", NotificationDeliveryMethod.PUSH);
NotificationTemplate generalNotificationTemplate = createNotificationTemplate(NotificationType.GENERAL, "General", "General", NotificationDeliveryMethod.PUSH);
NotificationTemplate entityActionNotificationTemplate = createNotificationTemplate(NotificationType.ENTITY_ACTION, "Entity action", "Entity action", NotificationDeliveryMethod.PUSH);
assertThat(findTemplates(NotificationType.ALARM)).extracting(IdBased::getId)
.containsOnly(alarmNotificationTemplate.getId());
assertThat(findTemplates(NotificationType.ENTITY_ACTION)).extracting(IdBased::getId)
.containsOnly(entityActionNotificationTemplate.getId());
assertThat(findTemplates(NotificationType.GENERAL)).extracting(IdBased::getId)
.containsOnly(generalNotificationTemplate.getId());
assertThat(findTemplates(NotificationType.GENERAL, NotificationType.ALARM)).extracting(IdBased::getId)
.containsOnly(generalNotificationTemplate.getId(), alarmNotificationTemplate.getId());
assertThat(findTemplates(NotificationType.GENERAL, NotificationType.ENTITY_ACTION)).extracting(IdBased::getId)
.containsOnly(generalNotificationTemplate.getId(), entityActionNotificationTemplate.getId());
assertThat(findTemplates()).extracting(IdBased::getId)
.containsOnly(generalNotificationTemplate.getId(), alarmNotificationTemplate.getId(), entityActionNotificationTemplate.getId());
}
private String saveAndGetError(NotificationTemplate notificationTemplate, ResultMatcher statusMatcher) throws Exception { private String saveAndGetError(NotificationTemplate notificationTemplate, ResultMatcher statusMatcher) throws Exception {
return getErrorMessage(save(notificationTemplate, statusMatcher)); return getErrorMessage(save(notificationTemplate, statusMatcher));
} }
@ -87,4 +115,10 @@ public class NotificationTemplateApiTest extends AbstractControllerTest {
.andExpect(statusMatcher); .andExpect(statusMatcher);
} }
private List<NotificationTemplate> findTemplates(NotificationType... notificationTypes) throws Exception {
PageLink pageLink = new PageLink(100, 0);
return doGetTypedWithPageLink("/api/notification/templates?notificationTypes=" + StringUtils.join(notificationTypes, ",") + "&",
new TypeReference<PageData<NotificationTemplate>>() {}, pageLink).getData();
}
} }

5
common/dao-api/src/main/java/org/thingsboard/server/dao/notification/NotificationTemplateService.java

@ -17,17 +17,20 @@ package org.thingsboard.server.dao.notification;
import org.thingsboard.server.common.data.id.NotificationTemplateId; import org.thingsboard.server.common.data.id.NotificationTemplateId;
import org.thingsboard.server.common.data.id.TenantId; 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.notification.template.NotificationTemplate;
import org.thingsboard.server.common.data.page.PageData; import org.thingsboard.server.common.data.page.PageData;
import org.thingsboard.server.common.data.page.PageLink; import org.thingsboard.server.common.data.page.PageLink;
import java.util.List;
public interface NotificationTemplateService { public interface NotificationTemplateService {
NotificationTemplate findNotificationTemplateById(TenantId tenantId, NotificationTemplateId id); NotificationTemplate findNotificationTemplateById(TenantId tenantId, NotificationTemplateId id);
NotificationTemplate saveNotificationTemplate(TenantId tenantId, NotificationTemplate notificationTemplate); NotificationTemplate saveNotificationTemplate(TenantId tenantId, NotificationTemplate notificationTemplate);
PageData<NotificationTemplate> findNotificationTemplatesByTenantId(TenantId tenantId, PageLink pageLink); PageData<NotificationTemplate> findNotificationTemplatesByTenantIdAndNotificationTypes(TenantId tenantId, List<NotificationType> notificationTypes, PageLink pageLink);
void deleteNotificationTemplateById(TenantId tenantId, NotificationTemplateId id); void deleteNotificationTemplateById(TenantId tenantId, NotificationTemplateId id);

4
common/data/src/main/java/org/thingsboard/server/common/data/notification/NotificationProcessingContext.java

@ -22,7 +22,7 @@ import org.apache.commons.lang3.StringUtils;
import org.thingsboard.server.common.data.User; import org.thingsboard.server.common.data.User;
import org.thingsboard.server.common.data.id.CustomerId; import org.thingsboard.server.common.data.id.CustomerId;
import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.common.data.id.TenantId;
import org.thingsboard.server.common.data.notification.info.AlarmOriginatedNotificationInfo; import org.thingsboard.server.common.data.notification.info.AlarmNotificationInfo;
import org.thingsboard.server.common.data.notification.info.NotificationInfo; import org.thingsboard.server.common.data.notification.info.NotificationInfo;
import org.thingsboard.server.common.data.notification.settings.NotificationDeliveryMethodConfig; import org.thingsboard.server.common.data.notification.settings.NotificationDeliveryMethodConfig;
import org.thingsboard.server.common.data.notification.settings.NotificationSettings; import org.thingsboard.server.common.data.notification.settings.NotificationSettings;
@ -129,7 +129,7 @@ public class NotificationProcessingContext {
CustomerId customerId; CustomerId customerId;
switch (request.getOriginatorEntityId().getEntityType()) { switch (request.getOriginatorEntityId().getEntityType()) {
case ALARM: case ALARM:
customerId = ((AlarmOriginatedNotificationInfo) request.getInfo()).getCustomerId(); customerId = ((AlarmNotificationInfo) request.getInfo()).getCustomerId();
break; break;
default: default:
customerId = null; customerId = null;

13
common/data/src/main/java/org/thingsboard/server/common/data/notification/NotificationType.java

@ -15,16 +15,11 @@
*/ */
package org.thingsboard.server.common.data.notification; package org.thingsboard.server.common.data.notification;
import lombok.Getter;
import lombok.RequiredArgsConstructor;
@RequiredArgsConstructor
@Getter
public enum NotificationType { public enum NotificationType {
GENERAL("General"), GENERAL,
ALARM("Alarm"); ALARM,
DEVICE_INACTIVITY,
private final String name; ENTITY_ACTION;
} }

6
common/data/src/main/java/org/thingsboard/server/common/data/notification/info/AlarmOriginatedNotificationInfo.java → common/data/src/main/java/org/thingsboard/server/common/data/notification/info/AlarmNotificationInfo.java

@ -22,20 +22,20 @@ import lombok.NoArgsConstructor;
import org.thingsboard.server.common.data.EntityType; import org.thingsboard.server.common.data.EntityType;
import org.thingsboard.server.common.data.alarm.AlarmSeverity; import org.thingsboard.server.common.data.alarm.AlarmSeverity;
import org.thingsboard.server.common.data.alarm.AlarmStatus; import org.thingsboard.server.common.data.alarm.AlarmStatus;
import org.thingsboard.server.common.data.id.AlarmId;
import org.thingsboard.server.common.data.id.CustomerId; import org.thingsboard.server.common.data.id.CustomerId;
import org.thingsboard.server.common.data.id.EntityId; import org.thingsboard.server.common.data.id.EntityId;
import java.util.Map; import java.util.Map;
import java.util.UUID;
@Data @Data
@NoArgsConstructor @NoArgsConstructor
@AllArgsConstructor @AllArgsConstructor
@Builder @Builder
public class AlarmOriginatedNotificationInfo implements NotificationInfo { public class AlarmNotificationInfo implements NotificationInfo {
private AlarmId alarmId;
private String alarmType; private String alarmType;
private UUID alarmId;
private EntityId alarmOriginator; private EntityId alarmOriginator;
private AlarmSeverity alarmSeverity; private AlarmSeverity alarmSeverity;
private AlarmStatus alarmStatus; private AlarmStatus alarmStatus;

51
common/data/src/main/java/org/thingsboard/server/common/data/notification/info/DeviceInactivityNotificationInfo.java

@ -0,0 +1,51 @@
/**
* Copyright © 2016-2022 The Thingsboard Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.thingsboard.server.common.data.notification.info;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.thingsboard.server.common.data.EntityType;
import java.util.Map;
import java.util.UUID;
@Data
@NoArgsConstructor
@AllArgsConstructor
@Builder
public class DeviceInactivityNotificationInfo implements NotificationInfo {
private UUID deviceId;
private String deviceName;
private String deviceType;
@Override
public EntityType getOriginatorType() {
return EntityType.DEVICE;
}
@Override
public Map<String, String> getTemplateData() {
return Map.of(
"deviceId", deviceId.toString(),
"deviceName", deviceName,
"deviceType", deviceType
);
}
}

57
common/data/src/main/java/org/thingsboard/server/common/data/notification/info/EntityActionNotificationInfo.java

@ -0,0 +1,57 @@
/**
* Copyright © 2016-2022 The Thingsboard Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.thingsboard.server.common.data.notification.info;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.thingsboard.server.common.data.EntityType;
import org.thingsboard.server.common.data.audit.ActionType;
import java.util.Map;
import java.util.UUID;
@Data
@NoArgsConstructor
@AllArgsConstructor
@Builder
public class EntityActionNotificationInfo implements NotificationInfo {
private EntityType entityType;
private UUID entityId;
private ActionType actionType;
private UUID userId;
private String userName;
// maybe add entityName and other info (from TbMsg data)
@Override
public EntityType getOriginatorType() {
return EntityType.TENANT;
}
@Override
public Map<String, String> getTemplateData() {
return Map.of(
"entityType", entityType.name(),
"entityId", entityId.toString(),
"actionType", actionType.name(),
"userId", userId.toString(),
"userName", userName
);
}
}

12
common/data/src/main/java/org/thingsboard/server/common/data/notification/info/NotificationInfo.java

@ -21,19 +21,25 @@ import com.fasterxml.jackson.annotation.JsonSubTypes;
import com.fasterxml.jackson.annotation.JsonSubTypes.Type; import com.fasterxml.jackson.annotation.JsonSubTypes.Type;
import com.fasterxml.jackson.annotation.JsonTypeInfo; import com.fasterxml.jackson.annotation.JsonTypeInfo;
import org.thingsboard.server.common.data.EntityType; import org.thingsboard.server.common.data.EntityType;
import org.thingsboard.server.common.data.id.UserId;
import java.util.Collections;
import java.util.List;
import java.util.Map; import java.util.Map;
@JsonIgnoreProperties(ignoreUnknown = true) @JsonIgnoreProperties(ignoreUnknown = true)
@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, property = "originatorType") @JsonTypeInfo(use = JsonTypeInfo.Id.NAME, property = "originatorType")
@JsonSubTypes({ @JsonSubTypes({
@Type(name = "USER", value = UserOriginatedNotificationInfo.class), @Type(name = "USER", value = UserOriginatedNotificationInfo.class),
@Type(name = "ALARM", value = AlarmOriginatedNotificationInfo.class), @Type(name = "ALARM", value = AlarmNotificationInfo.class),
@Type(name = "RULE_CHAIN", value = RuleEngineOriginatedNotificationInfo.class) @Type(name = "RULE_CHAIN", value = RuleEngineOriginatedNotificationInfo.class),
@Type(name = "DEVICE", value = DeviceInactivityNotificationInfo.class),
@Type(name = "TENANT", value = EntityActionNotificationInfo.class)
}) })
public interface NotificationInfo { public interface NotificationInfo {
EntityType getOriginatorType(); @JsonIgnore
EntityType getOriginatorType(); // FIXME: originatorType is bad identifier, might have 2 types of info related to device
@JsonIgnore @JsonIgnore
Map<String, String> getTemplateData(); Map<String, String> getTemplateData();

2
common/data/src/main/java/org/thingsboard/server/common/data/notification/info/UserOriginatedNotificationInfo.java

@ -17,7 +17,6 @@ package org.thingsboard.server.common.data.notification.info;
import lombok.Data; import lombok.Data;
import org.thingsboard.server.common.data.EntityType; import org.thingsboard.server.common.data.EntityType;
import org.thingsboard.server.common.data.id.DashboardId;
import java.util.Collections; import java.util.Collections;
import java.util.Map; import java.util.Map;
@ -26,7 +25,6 @@ import java.util.Map;
public class UserOriginatedNotificationInfo implements NotificationInfo { public class UserOriginatedNotificationInfo implements NotificationInfo {
private String description; private String description;
private DashboardId dashboardId;
@Override @Override
public EntityType getOriginatorType() { public EntityType getOriginatorType() {

2
common/data/src/main/java/org/thingsboard/server/common/data/notification/targets/NotificationTargetConfig.java

@ -15,6 +15,7 @@
*/ */
package org.thingsboard.server.common.data.notification.targets; package org.thingsboard.server.common.data.notification.targets;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonSubTypes; import com.fasterxml.jackson.annotation.JsonSubTypes;
import com.fasterxml.jackson.annotation.JsonSubTypes.Type; import com.fasterxml.jackson.annotation.JsonSubTypes.Type;
@ -33,6 +34,7 @@ public abstract class NotificationTargetConfig {
private String description; private String description;
@JsonIgnore
public abstract NotificationTargetConfigType getType(); public abstract NotificationTargetConfigType getType();
} }

6
dao/src/main/java/org/thingsboard/server/dao/notification/DefaultNotificationTemplateService.java

@ -20,11 +20,13 @@ import org.springframework.stereotype.Service;
import org.thingsboard.server.common.data.id.NotificationTemplateId; import org.thingsboard.server.common.data.id.NotificationTemplateId;
import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.common.data.id.TenantId;
import org.thingsboard.server.common.data.notification.NotificationRequestStatus; import org.thingsboard.server.common.data.notification.NotificationRequestStatus;
import org.thingsboard.server.common.data.notification.NotificationType;
import org.thingsboard.server.common.data.notification.template.NotificationTemplate; import org.thingsboard.server.common.data.notification.template.NotificationTemplate;
import org.thingsboard.server.common.data.page.PageData; import org.thingsboard.server.common.data.page.PageData;
import org.thingsboard.server.common.data.page.PageLink; import org.thingsboard.server.common.data.page.PageLink;
import org.thingsboard.server.dao.entity.AbstractEntityService; import org.thingsboard.server.dao.entity.AbstractEntityService;
import java.util.List;
import java.util.Map; import java.util.Map;
@Service @Service
@ -45,8 +47,8 @@ public class DefaultNotificationTemplateService extends AbstractEntityService im
} }
@Override @Override
public PageData<NotificationTemplate> findNotificationTemplatesByTenantId(TenantId tenantId, PageLink pageLink) { public PageData<NotificationTemplate> findNotificationTemplatesByTenantIdAndNotificationTypes(TenantId tenantId, List<NotificationType> notificationTypes, PageLink pageLink) {
return notificationTemplateDao.findByTenantIdAndPageLink(tenantId, pageLink); return notificationTemplateDao.findByTenantIdAndNotificationTypesAndPageLink(tenantId, notificationTypes, pageLink);
} }
@Override @Override

5
dao/src/main/java/org/thingsboard/server/dao/notification/NotificationTemplateDao.java

@ -16,13 +16,16 @@
package org.thingsboard.server.dao.notification; package org.thingsboard.server.dao.notification;
import org.thingsboard.server.common.data.id.TenantId; 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.notification.template.NotificationTemplate;
import org.thingsboard.server.common.data.page.PageData; import org.thingsboard.server.common.data.page.PageData;
import org.thingsboard.server.common.data.page.PageLink; import org.thingsboard.server.common.data.page.PageLink;
import org.thingsboard.server.dao.Dao; import org.thingsboard.server.dao.Dao;
import java.util.List;
public interface NotificationTemplateDao extends Dao<NotificationTemplate> { public interface NotificationTemplateDao extends Dao<NotificationTemplate> {
PageData<NotificationTemplate> findByTenantIdAndPageLink(TenantId tenantId, PageLink pageLink); PageData<NotificationTemplate> findByTenantIdAndNotificationTypesAndPageLink(TenantId tenantId, List<NotificationType> notificationTypes, PageLink pageLink);
} }

8
dao/src/main/java/org/thingsboard/server/dao/sql/notification/JpaNotificationTemplateDao.java

@ -21,6 +21,7 @@ import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import org.thingsboard.server.common.data.EntityType; import org.thingsboard.server.common.data.EntityType;
import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.common.data.id.TenantId;
import org.thingsboard.server.common.data.notification.NotificationType;
import org.thingsboard.server.common.data.notification.template.NotificationTemplate; import org.thingsboard.server.common.data.notification.template.NotificationTemplate;
import org.thingsboard.server.common.data.page.PageData; import org.thingsboard.server.common.data.page.PageData;
import org.thingsboard.server.common.data.page.PageLink; import org.thingsboard.server.common.data.page.PageLink;
@ -30,6 +31,7 @@ import org.thingsboard.server.dao.notification.NotificationTemplateDao;
import org.thingsboard.server.dao.sql.JpaAbstractDao; import org.thingsboard.server.dao.sql.JpaAbstractDao;
import org.thingsboard.server.dao.util.SqlDao; import org.thingsboard.server.dao.util.SqlDao;
import java.util.List;
import java.util.UUID; import java.util.UUID;
import static org.thingsboard.server.dao.DaoUtil.getId; import static org.thingsboard.server.dao.DaoUtil.getId;
@ -47,9 +49,9 @@ public class JpaNotificationTemplateDao extends JpaAbstractDao<NotificationTempl
} }
@Override @Override
public PageData<NotificationTemplate> findByTenantIdAndPageLink(TenantId tenantId, PageLink pageLink) { public PageData<NotificationTemplate> findByTenantIdAndNotificationTypesAndPageLink(TenantId tenantId, List<NotificationType> notificationTypes, PageLink pageLink) {
return DaoUtil.toPageData(notificationTemplateRepository.findByTenantIdAndSearchText(getId(tenantId, true), return DaoUtil.toPageData(notificationTemplateRepository.findByTenantIdAndNotificationTypesAndSearchText(getId(tenantId, true),
Strings.nullToEmpty(pageLink.getTextSearch()), DaoUtil.toPageable(pageLink))); notificationTypes, Strings.nullToEmpty(pageLink.getTextSearch()), DaoUtil.toPageable(pageLink)));
} }
@Override @Override

10
dao/src/main/java/org/thingsboard/server/dao/sql/notification/NotificationTemplateRepository.java

@ -21,18 +21,22 @@ import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query; import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param; import org.springframework.data.repository.query.Param;
import org.springframework.stereotype.Repository; import org.springframework.stereotype.Repository;
import org.thingsboard.server.common.data.notification.NotificationType;
import org.thingsboard.server.dao.model.sql.NotificationTemplateEntity; import org.thingsboard.server.dao.model.sql.NotificationTemplateEntity;
import java.util.List;
import java.util.UUID; import java.util.UUID;
@Repository @Repository
public interface NotificationTemplateRepository extends JpaRepository<NotificationTemplateEntity, UUID> { public interface NotificationTemplateRepository extends JpaRepository<NotificationTemplateEntity, UUID> {
@Query("SELECT t FROM NotificationTemplateEntity t WHERE t.tenantId = :tenantId AND " + @Query("SELECT t FROM NotificationTemplateEntity t WHERE t.tenantId = :tenantId AND " +
"t.notificationType IN :notificationTypes AND " +
"(lower(t.name) LIKE lower(concat('%', :searchText, '%')) OR " + "(lower(t.name) LIKE lower(concat('%', :searchText, '%')) OR " +
"lower(t.notificationType) LIKE lower(concat('%', :searchText, '%')))") "lower(t.notificationType) LIKE lower(concat('%', :searchText, '%')))")
Page<NotificationTemplateEntity> findByTenantIdAndSearchText(@Param("tenantId") UUID tenantId, Page<NotificationTemplateEntity> findByTenantIdAndNotificationTypesAndSearchText(@Param("tenantId") UUID tenantId,
@Param("searchText") String searchText, @Param("notificationTypes") List<NotificationType> notificationTypes,
Pageable pageable); @Param("searchText") String searchText,
Pageable pageable);
} }

8
rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/notification/TbNotificationNode.java

@ -50,9 +50,11 @@ public class TbNotificationNode implements TbNode {
@Override @Override
public void onMsg(TbContext ctx, TbMsg msg) throws ExecutionException, InterruptedException, TbNodeException { public void onMsg(TbContext ctx, TbMsg msg) throws ExecutionException, InterruptedException, TbNodeException {
RuleEngineOriginatedNotificationInfo notificationInfo = new RuleEngineOriginatedNotificationInfo(); RuleEngineOriginatedNotificationInfo notificationInfo = RuleEngineOriginatedNotificationInfo.builder()
notificationInfo.setMsgOriginator(msg.getOriginator()); .msgOriginator(msg.getOriginator())
notificationInfo.setMsgMetadata(msg.getMetaData().getData()); .msgMetadata(msg.getMetaData().getData())
.msgType(msg.getType())
.build();
NotificationRequest notificationRequest = NotificationRequest.builder() NotificationRequest notificationRequest = NotificationRequest.builder()
.tenantId(ctx.getTenantId()) .tenantId(ctx.getTenantId())

Loading…
Cancel
Save