diff --git a/application/src/main/java/org/thingsboard/server/service/notification/rule/trigger/AlarmCommentTriggerProcessor.java b/application/src/main/java/org/thingsboard/server/service/notification/rule/trigger/AlarmCommentTriggerProcessor.java index 7a1ef3949b..28a03830bf 100644 --- a/application/src/main/java/org/thingsboard/server/service/notification/rule/trigger/AlarmCommentTriggerProcessor.java +++ b/application/src/main/java/org/thingsboard/server/service/notification/rule/trigger/AlarmCommentTriggerProcessor.java @@ -19,18 +19,27 @@ import org.springframework.stereotype.Service; import org.thingsboard.common.util.JacksonUtil; import org.thingsboard.server.common.data.alarm.Alarm; import org.thingsboard.server.common.data.alarm.AlarmComment; +import org.thingsboard.server.common.data.alarm.AlarmStatusFilter; import org.thingsboard.server.common.data.notification.info.AlarmCommentNotificationInfo; import org.thingsboard.server.common.data.notification.info.NotificationInfo; import org.thingsboard.server.common.data.notification.rule.trigger.AlarmCommentNotificationRuleTriggerConfig; import org.thingsboard.server.common.data.notification.rule.trigger.NotificationRuleTriggerType; import org.thingsboard.server.common.msg.TbMsg; +import static org.apache.commons.collections.CollectionUtils.isEmpty; + @Service public class AlarmCommentTriggerProcessor implements NotificationRuleTriggerProcessor { @Override public boolean matchesFilter(TbMsg ruleEngineMsg, AlarmCommentNotificationRuleTriggerConfig triggerConfig) { - return ruleEngineMsg.getMetaData().getValue("comment") != null; + if (ruleEngineMsg.getMetaData().getValue("comment") == null) { + return false; + } + Alarm alarm = JacksonUtil.fromString(ruleEngineMsg.getData(), Alarm.class); + return (isEmpty(triggerConfig.getAlarmTypes()) || triggerConfig.getAlarmTypes().contains(alarm.getType())) && + (isEmpty(triggerConfig.getAlarmSeverities()) || triggerConfig.getAlarmSeverities().contains(alarm.getSeverity())) && + (isEmpty(triggerConfig.getAlarmStatuses()) || AlarmStatusFilter.from(triggerConfig.getAlarmStatuses()).matches(alarm)); } @Override @@ -39,8 +48,11 @@ public class AlarmCommentTriggerProcessor implements NotificationRuleTriggerProc Alarm alarm = JacksonUtil.fromString(ruleEngineMsg.getData(), Alarm.class); return AlarmCommentNotificationInfo.builder() .comment(comment.getComment().get("text").asText()) + .alarmId(alarm.getUuidId()) .alarmType(alarm.getType()) - .alarmId(comment.getAlarmId().getId()) + .alarmOriginator(alarm.getOriginator()) + .alarmSeverity(alarm.getSeverity()) + .alarmStatus(alarm.getStatus()) .build(); } diff --git a/application/src/main/java/org/thingsboard/server/service/notification/rule/trigger/AlarmTriggerProcessor.java b/application/src/main/java/org/thingsboard/server/service/notification/rule/trigger/AlarmTriggerProcessor.java index d5e3660782..9f226ca352 100644 --- a/application/src/main/java/org/thingsboard/server/service/notification/rule/trigger/AlarmTriggerProcessor.java +++ b/application/src/main/java/org/thingsboard/server/service/notification/rule/trigger/AlarmTriggerProcessor.java @@ -17,9 +17,9 @@ package org.thingsboard.server.service.notification.rule.trigger; import lombok.Builder; import lombok.Data; -import org.apache.commons.collections.CollectionUtils; import org.springframework.stereotype.Service; import org.thingsboard.server.common.data.alarm.Alarm; +import org.thingsboard.server.common.data.alarm.AlarmStatusFilter; 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; @@ -27,14 +27,17 @@ import org.thingsboard.server.common.data.notification.rule.trigger.AlarmNotific import org.thingsboard.server.common.data.notification.rule.trigger.NotificationRuleTriggerType; import org.thingsboard.server.service.notification.rule.trigger.AlarmTriggerProcessor.AlarmTriggerObject; +import static org.apache.commons.collections.CollectionUtils.isEmpty; +import static org.apache.commons.collections.CollectionUtils.isNotEmpty; + @Service public class AlarmTriggerProcessor implements NotificationRuleTriggerProcessor { @Override public boolean matchesFilter(AlarmTriggerObject triggerObject, AlarmNotificationRuleTriggerConfig triggerConfig) { Alarm alarm = triggerObject.getAlarm(); - return (CollectionUtils.isEmpty(triggerConfig.getAlarmTypes()) || triggerConfig.getAlarmTypes().contains(alarm.getType())) && - (CollectionUtils.isEmpty(triggerConfig.getAlarmSeverities()) || triggerConfig.getAlarmSeverities().contains(alarm.getSeverity())); + return (isEmpty(triggerConfig.getAlarmTypes()) || triggerConfig.getAlarmTypes().contains(alarm.getType())) && + (isEmpty(triggerConfig.getAlarmSeverities()) || triggerConfig.getAlarmSeverities().contains(alarm.getSeverity())); } @Override @@ -45,8 +48,8 @@ public class AlarmTriggerProcessor implements NotificationRuleTriggerProcessor wsClient.registerWaitForUpdate()); - alarmSubscriptionService.ackAlarm(tenantId, alarm.getId(), System.currentTimeMillis()); + alarmSubscriptionService.acknowledgeAlarm(tenantId, alarm.getId(), System.currentTimeMillis()); AlarmStatus expectedStatus = AlarmStatus.ACTIVE_ACK; AlarmSeverity expectedSeverity = AlarmSeverity.CRITICAL; clients.values().forEach(wsClient -> { @@ -270,7 +271,7 @@ public class NotificationRuleApiTest extends AbstractNotificationApiTest { triggerConfig.setAlarmSeverities(null); AlarmNotificationRuleTriggerConfig.ClearRule clearRule = new AlarmNotificationRuleTriggerConfig.ClearRule(); - clearRule.setAlarmStatus(AlarmStatus.CLEARED_UNACK); + clearRule.setAlarmStatuses(Set.of(AlarmSearchStatus.CLEARED, AlarmSearchStatus.UNACK)); triggerConfig.setClearRule(clearRule); notificationRule.setTriggerConfig(triggerConfig); @@ -308,7 +309,7 @@ public class NotificationRuleApiTest extends AbstractNotificationApiTest { assertThat(scheduledNotificationRequest).extracting(NotificationRequest::getInfo).isEqualTo(notification.getInfo()); getWsClient().registerWaitForUpdate(); - alarmSubscriptionService.clearAlarm(tenantId, alarm.getId(), null, System.currentTimeMillis()); + alarmSubscriptionService.clearAlarm(tenantId, alarm.getId(), System.currentTimeMillis(), null); getWsClient().waitForUpdate(true); notification = getWsClient().getLastDataUpdate().getNotifications().iterator().next(); assertThat(notification.getSubject()).isEqualTo("CRITICAL alarm '" + alarmType + "' is CLEARED_UNACK"); diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/alarm/AlarmStatusFilter.java b/common/data/src/main/java/org/thingsboard/server/common/data/alarm/AlarmStatusFilter.java index c8f40fa048..50b02327cb 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/alarm/AlarmStatusFilter.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/alarm/AlarmStatusFilter.java @@ -15,7 +15,7 @@ */ package org.thingsboard.server.common.data.alarm; -import java.util.List; +import java.util.Collection; import java.util.Optional; public class AlarmStatusFilter { @@ -94,19 +94,19 @@ public class AlarmStatusFilter { } - public static AlarmStatusFilter fromList(List list) { - if (list == null || list.isEmpty() || list.contains(AlarmSearchStatus.ANY)) { + public static AlarmStatusFilter from(Collection statuses) { + if (statuses == null || statuses.isEmpty() || statuses.contains(AlarmSearchStatus.ANY)) { return EMPTY; } - boolean clearFilter = list.contains(AlarmSearchStatus.CLEARED); - boolean activeFilter = list.contains(AlarmSearchStatus.ACTIVE); + boolean clearFilter = statuses.contains(AlarmSearchStatus.CLEARED); + boolean activeFilter = statuses.contains(AlarmSearchStatus.ACTIVE); Optional clear = Optional.empty(); if (clearFilter && !activeFilter || !clearFilter && activeFilter) { clear = Optional.of(clearFilter); } - boolean ackFilter = list.contains(AlarmSearchStatus.ACK); - boolean unackFilter = list.contains(AlarmSearchStatus.UNACK); + boolean ackFilter = statuses.contains(AlarmSearchStatus.ACK); + boolean unackFilter = statuses.contains(AlarmSearchStatus.UNACK); Optional ack = Optional.empty(); if (ackFilter && !unackFilter || !ackFilter && unackFilter) { ack = Optional.of(ackFilter); @@ -114,5 +114,9 @@ public class AlarmStatusFilter { return new AlarmStatusFilter(clear, ack); } + public boolean matches(Alarm alarm) { + return ackFilter.map(ackFilter -> ackFilter.equals(alarm.isAcknowledged())).orElse(true) && + clearFilter.map(clearedFilter -> clearedFilter.equals(alarm.isCleared())).orElse(true); + } } diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/notification/info/AlarmCommentNotificationInfo.java b/common/data/src/main/java/org/thingsboard/server/common/data/notification/info/AlarmCommentNotificationInfo.java index 0a8b97ba64..20764f56f4 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/notification/info/AlarmCommentNotificationInfo.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/notification/info/AlarmCommentNotificationInfo.java @@ -19,6 +19,9 @@ import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Data; import lombok.NoArgsConstructor; +import org.thingsboard.server.common.data.alarm.AlarmSeverity; +import org.thingsboard.server.common.data.alarm.AlarmStatus; +import org.thingsboard.server.common.data.id.EntityId; import java.util.Map; import java.util.UUID; @@ -32,14 +35,26 @@ public class AlarmCommentNotificationInfo implements NotificationInfo { private String comment; private String alarmType; private UUID alarmId; + private EntityId alarmOriginator; + private AlarmSeverity alarmSeverity; + private AlarmStatus alarmStatus; @Override public Map getTemplateData() { return Map.of( "comment", comment, "alarmType", alarmType, - "alarmId", alarmId.toString() + "alarmId", alarmId.toString(), + "alarmSeverity", alarmSeverity.toString(), + "alarmStatus", alarmStatus.toString(), + "alarmOriginatorEntityType", alarmOriginator.getEntityType().toString(), + "alarmOriginatorId", alarmOriginator.getId().toString() ); } + @Override + public EntityId getStateEntityId() { + return alarmOriginator; + } + } diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/notification/info/AlarmNotificationInfo.java b/common/data/src/main/java/org/thingsboard/server/common/data/notification/info/AlarmNotificationInfo.java index 73785c2af6..4f387e3d86 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/notification/info/AlarmNotificationInfo.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/notification/info/AlarmNotificationInfo.java @@ -57,4 +57,9 @@ public class AlarmNotificationInfo implements RuleOriginatedNotificationInfo { ); } + @Override + public EntityId getStateEntityId() { + return alarmOriginator; + } + } diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/notification/info/DeviceInactivityNotificationInfo.java b/common/data/src/main/java/org/thingsboard/server/common/data/notification/info/DeviceInactivityNotificationInfo.java index 7ad3e14896..8a2d6941a0 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/notification/info/DeviceInactivityNotificationInfo.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/notification/info/DeviceInactivityNotificationInfo.java @@ -20,6 +20,8 @@ import lombok.Builder; import lombok.Data; import lombok.NoArgsConstructor; import org.thingsboard.server.common.data.id.CustomerId; +import org.thingsboard.server.common.data.id.DeviceId; +import org.thingsboard.server.common.data.id.EntityId; import java.util.Map; import java.util.UUID; @@ -49,4 +51,9 @@ public class DeviceInactivityNotificationInfo implements RuleOriginatedNotificat ); } + @Override + public EntityId getStateEntityId() { + return new DeviceId(deviceId); + } + } diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/notification/info/EntityActionNotificationInfo.java b/common/data/src/main/java/org/thingsboard/server/common/data/notification/info/EntityActionNotificationInfo.java index 77a906c35f..60061d3a78 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/notification/info/EntityActionNotificationInfo.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/notification/info/EntityActionNotificationInfo.java @@ -19,9 +19,9 @@ 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 org.thingsboard.server.common.data.id.CustomerId; +import org.thingsboard.server.common.data.id.EntityId; import java.util.Map; import java.util.UUID; @@ -32,8 +32,7 @@ import java.util.UUID; @Builder public class EntityActionNotificationInfo implements RuleOriginatedNotificationInfo { - private EntityType entityType; - private UUID entityId; + private EntityId entityId; private String entityName; private ActionType actionType; private UUID originatorUserId; @@ -48,7 +47,7 @@ public class EntityActionNotificationInfo implements RuleOriginatedNotificationI @Override public Map getTemplateData() { return Map.of( - "entityType", entityType.name(), + "entityType", entityId.getEntityType().name(), "entityId", entityId.toString(), "entityName", entityName, "actionType", actionType.name().toLowerCase(), @@ -57,4 +56,9 @@ public class EntityActionNotificationInfo implements RuleOriginatedNotificationI ); } + @Override + public EntityId getStateEntityId() { + return entityId; + } + } diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/notification/info/NotificationInfo.java b/common/data/src/main/java/org/thingsboard/server/common/data/notification/info/NotificationInfo.java index 6877ba1bc9..44bdcbe52a 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/notification/info/NotificationInfo.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/notification/info/NotificationInfo.java @@ -18,6 +18,7 @@ package org.thingsboard.server.common.data.notification.info; import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonTypeInfo; +import org.thingsboard.server.common.data.id.EntityId; import java.util.Map; @@ -28,4 +29,8 @@ public interface NotificationInfo { @JsonIgnore Map getTemplateData(); + default EntityId getStateEntityId() { + return null; + } + } diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/notification/info/RuleEngineComponentLifecycleEventNotificationInfo.java b/common/data/src/main/java/org/thingsboard/server/common/data/notification/info/RuleEngineComponentLifecycleEventNotificationInfo.java index 971ee1cdee..0dc942c588 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/notification/info/RuleEngineComponentLifecycleEventNotificationInfo.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/notification/info/RuleEngineComponentLifecycleEventNotificationInfo.java @@ -53,4 +53,9 @@ public class RuleEngineComponentLifecycleEventNotificationInfo implements Notifi ); } + @Override + public EntityId getStateEntityId() { + return ruleChainId; + } + } diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/notification/info/RuleEngineOriginatedNotificationInfo.java b/common/data/src/main/java/org/thingsboard/server/common/data/notification/info/RuleEngineOriginatedNotificationInfo.java index 05f4dbb49b..924028da36 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/notification/info/RuleEngineOriginatedNotificationInfo.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/notification/info/RuleEngineOriginatedNotificationInfo.java @@ -43,4 +43,9 @@ public class RuleEngineOriginatedNotificationInfo implements NotificationInfo { return templateData; } + @Override + public EntityId getStateEntityId() { + return msgOriginator; + } + } diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/notification/rule/trigger/AlarmCommentNotificationRuleTriggerConfig.java b/common/data/src/main/java/org/thingsboard/server/common/data/notification/rule/trigger/AlarmCommentNotificationRuleTriggerConfig.java index 2560aee733..f8cae97c0e 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/notification/rule/trigger/AlarmCommentNotificationRuleTriggerConfig.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/notification/rule/trigger/AlarmCommentNotificationRuleTriggerConfig.java @@ -16,10 +16,18 @@ package org.thingsboard.server.common.data.notification.rule.trigger; import lombok.Data; +import org.thingsboard.server.common.data.alarm.AlarmSearchStatus; +import org.thingsboard.server.common.data.alarm.AlarmSeverity; + +import java.util.Set; @Data public class AlarmCommentNotificationRuleTriggerConfig implements NotificationRuleTriggerConfig { + private Set alarmTypes; + private Set alarmSeverities; + private Set alarmStatuses; + @Override public NotificationRuleTriggerType getTriggerType() { return NotificationRuleTriggerType.ALARM_COMMENT; diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/notification/rule/trigger/AlarmNotificationRuleTriggerConfig.java b/common/data/src/main/java/org/thingsboard/server/common/data/notification/rule/trigger/AlarmNotificationRuleTriggerConfig.java index f502bd6932..70d986cdf7 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/notification/rule/trigger/AlarmNotificationRuleTriggerConfig.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/notification/rule/trigger/AlarmNotificationRuleTriggerConfig.java @@ -16,8 +16,8 @@ package org.thingsboard.server.common.data.notification.rule.trigger; import lombok.Data; +import org.thingsboard.server.common.data.alarm.AlarmSearchStatus; import org.thingsboard.server.common.data.alarm.AlarmSeverity; -import org.thingsboard.server.common.data.alarm.AlarmStatus; import java.util.Set; @@ -35,7 +35,7 @@ public class AlarmNotificationRuleTriggerConfig implements NotificationRuleTrigg @Data public static class ClearRule { - private AlarmStatus alarmStatus; + private Set alarmStatuses; } } diff --git a/dao/src/main/java/org/thingsboard/server/dao/sql/query/DefaultAlarmQueryRepository.java b/dao/src/main/java/org/thingsboard/server/dao/sql/query/DefaultAlarmQueryRepository.java index ecf9c1c95f..4d6f39a546 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/sql/query/DefaultAlarmQueryRepository.java +++ b/dao/src/main/java/org/thingsboard/server/dao/sql/query/DefaultAlarmQueryRepository.java @@ -19,12 +19,9 @@ import lombok.extern.slf4j.Slf4j; import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate; import org.springframework.stereotype.Repository; import org.springframework.transaction.support.TransactionTemplate; -import org.thingsboard.server.common.data.DataConstants; import org.thingsboard.server.common.data.EntityType; import org.thingsboard.server.common.data.StringUtils; -import org.thingsboard.server.common.data.alarm.AlarmSearchStatus; import org.thingsboard.server.common.data.alarm.AlarmSeverity; -import org.thingsboard.server.common.data.alarm.AlarmStatus; import org.thingsboard.server.common.data.alarm.AlarmStatusFilter; import org.thingsboard.server.common.data.id.EntityId; import org.thingsboard.server.common.data.id.TenantId; @@ -41,11 +38,9 @@ import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.HashMap; -import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Objects; -import java.util.Set; import java.util.stream.Collectors; @Repository @@ -248,7 +243,7 @@ public class DefaultAlarmQueryRepository implements AlarmQueryRepository { wherePart.append("a.severity in (:alarmSeverities)"); } - AlarmStatusFilter asf = AlarmStatusFilter.fromList(pageLink.getStatusList()); + AlarmStatusFilter asf = AlarmStatusFilter.from(pageLink.getStatusList()); if (asf.hasAnyFilter()) { if (asf.hasAckFilter()) { addAndIfNeeded(wherePart, addAnd);