From 6013e19e545080daf10385ca59126092c7451a14 Mon Sep 17 00:00:00 2001 From: ViacheslavKlimov Date: Mon, 24 Apr 2023 18:15:18 +0300 Subject: [PATCH] Fix entity action notification --- .../service/action/EntityActionService.java | 25 ++++-- .../AlarmAssignmentTriggerProcessor.java | 5 +- .../trigger/AlarmCommentTriggerProcessor.java | 5 +- .../rule/trigger/AlarmTriggerProcessor.java | 8 +- .../ApiUsageLimitTriggerProcessor.java | 6 +- .../trigger/EntityActionTriggerProcessor.java | 77 +++++-------------- .../info/EntityActionNotificationInfo.java | 3 +- .../common/data/util/CollectionsUtil.java | 8 +- .../trigger/EntityActionTrigger.java | 47 +++++++++++ 9 files changed, 106 insertions(+), 78 deletions(-) create mode 100644 common/message/src/main/java/org/thingsboard/server/common/msg/notification/trigger/EntityActionTrigger.java diff --git a/application/src/main/java/org/thingsboard/server/service/action/EntityActionService.java b/application/src/main/java/org/thingsboard/server/service/action/EntityActionService.java index 619df15e14..011c1d2d68 100644 --- a/application/src/main/java/org/thingsboard/server/service/action/EntityActionService.java +++ b/application/src/main/java/org/thingsboard/server/service/action/EntityActionService.java @@ -42,6 +42,7 @@ import org.thingsboard.server.common.msg.TbMsg; import org.thingsboard.server.common.msg.TbMsgDataType; import org.thingsboard.server.common.msg.TbMsgMetaData; import org.thingsboard.server.common.msg.notification.trigger.EntitiesLimitTrigger; +import org.thingsboard.server.common.msg.notification.trigger.EntityActionTrigger; import org.thingsboard.server.dao.audit.AuditLogService; import org.thingsboard.server.queue.notification.NotificationRuleProcessor; @@ -190,12 +191,6 @@ public class EntityActionService { AlarmComment comment = extractParameter(AlarmComment.class, 0, additionalInfo); metaData.putValue("comment", json.writeValueAsString(comment)); } - if (actionType == ActionType.ADDED && !tenantId.isSysTenantId()) { - notificationRuleProcessor.process(EntitiesLimitTrigger.builder() - .tenantId(tenantId) - .entityType(entityId.getEntityType()) - .build()); - } ObjectNode entityNode; if (entity != null) { entityNode = json.valueToTree(entity); @@ -242,12 +237,28 @@ public class EntityActionService { entityNode = json.valueToTree(extractParameter(EntityRelation.class, 0, additionalInfo)); } } - TbMsg tbMsg = TbMsg.newMsg(msgType, entityId, customerId, metaData, TbMsgDataType.JSON, json.writeValueAsString(entityNode)); + if (tenantId == null || tenantId.isNullUid()) { if (entity instanceof HasTenantId) { tenantId = ((HasTenantId) entity).getTenantId(); } } + if (tenantId != null && !tenantId.isSysTenantId()) { + if (actionType == ActionType.ADDED) { + notificationRuleProcessor.process(EntitiesLimitTrigger.builder() + .tenantId(tenantId) + .entityType(entityId.getEntityType()) + .build()); + } + notificationRuleProcessor.process(EntityActionTrigger.builder() + .tenantId(tenantId) + .entityId(entityId) + .entity(entity) + .actionType(actionType) + .user(user) + .build()); + } + TbMsg tbMsg = TbMsg.newMsg(msgType, entityId, customerId, metaData, TbMsgDataType.JSON, json.writeValueAsString(entityNode)); tbClusterService.pushMsgToRuleEngine(tenantId, entityId, tbMsg, null); } catch (Exception e) { log.warn("[{}] Failed to push entity action to rule engine: {}", entityId, actionType, e); diff --git a/application/src/main/java/org/thingsboard/server/service/notification/rule/trigger/AlarmAssignmentTriggerProcessor.java b/application/src/main/java/org/thingsboard/server/service/notification/rule/trigger/AlarmAssignmentTriggerProcessor.java index 54c53a54d2..a7aa2ba4b6 100644 --- a/application/src/main/java/org/thingsboard/server/service/notification/rule/trigger/AlarmAssignmentTriggerProcessor.java +++ b/application/src/main/java/org/thingsboard/server/service/notification/rule/trigger/AlarmAssignmentTriggerProcessor.java @@ -32,6 +32,7 @@ import org.thingsboard.server.common.msg.notification.trigger.RuleEngineMsgTrigg import java.util.Set; import static org.apache.commons.collections.CollectionUtils.isEmpty; +import static org.thingsboard.server.common.data.util.CollectionsUtil.emptyOrContains; @Service public class AlarmAssignmentTriggerProcessor implements RuleEngineMsgNotificationRuleTriggerProcessor { @@ -43,8 +44,8 @@ public class AlarmAssignmentTriggerProcessor implements RuleEngineMsgNotificatio return false; } Alarm alarm = JacksonUtil.fromString(trigger.getMsg().getData(), Alarm.class); - return (isEmpty(triggerConfig.getAlarmTypes()) || triggerConfig.getAlarmTypes().contains(alarm.getType())) && - (isEmpty(triggerConfig.getAlarmSeverities()) || triggerConfig.getAlarmSeverities().contains(alarm.getSeverity())) && + return emptyOrContains(triggerConfig.getAlarmTypes(), alarm.getType()) && + emptyOrContains(triggerConfig.getAlarmSeverities(), alarm.getSeverity()) && (isEmpty(triggerConfig.getAlarmStatuses()) || AlarmStatusFilter.from(triggerConfig.getAlarmStatuses()).matches(alarm)); } 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 4378b9b017..cf71718f83 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 @@ -33,6 +33,7 @@ import org.thingsboard.server.common.msg.notification.trigger.RuleEngineMsgTrigg import java.util.Set; import static org.apache.commons.collections.CollectionUtils.isEmpty; +import static org.thingsboard.server.common.data.util.CollectionsUtil.emptyOrContains; @Service public class AlarmCommentTriggerProcessor implements RuleEngineMsgNotificationRuleTriggerProcessor { @@ -53,8 +54,8 @@ public class AlarmCommentTriggerProcessor implements RuleEngineMsgNotificationRu } } Alarm alarm = JacksonUtil.fromString(msg.getData(), Alarm.class); - return (isEmpty(triggerConfig.getAlarmTypes()) || triggerConfig.getAlarmTypes().contains(alarm.getType())) && - (isEmpty(triggerConfig.getAlarmSeverities()) || triggerConfig.getAlarmSeverities().contains(alarm.getSeverity())) && + return emptyOrContains(triggerConfig.getAlarmTypes(), alarm.getType()) && + emptyOrContains(triggerConfig.getAlarmSeverities(), alarm.getSeverity()) && (isEmpty(triggerConfig.getAlarmStatuses()) || AlarmStatusFilter.from(triggerConfig.getAlarmStatuses()).matches(alarm)); } 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 c8ebf73304..c32ed26854 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,6 +17,7 @@ package org.thingsboard.server.service.notification.rule.trigger; import org.springframework.stereotype.Service; import org.thingsboard.server.common.data.alarm.Alarm; +import org.thingsboard.server.common.data.alarm.AlarmApiCallResult; import org.thingsboard.server.common.data.alarm.AlarmInfo; import org.thingsboard.server.common.data.alarm.AlarmStatusFilter; import org.thingsboard.server.common.data.notification.info.AlarmNotificationInfo; @@ -25,11 +26,10 @@ import org.thingsboard.server.common.data.notification.rule.trigger.AlarmNotific import org.thingsboard.server.common.data.notification.rule.trigger.AlarmNotificationRuleTriggerConfig.AlarmAction; import org.thingsboard.server.common.data.notification.rule.trigger.AlarmNotificationRuleTriggerConfig.ClearRule; import org.thingsboard.server.common.data.notification.rule.trigger.NotificationRuleTriggerType; -import org.thingsboard.server.common.data.alarm.AlarmApiCallResult; import org.thingsboard.server.common.msg.notification.trigger.AlarmTrigger; -import static org.apache.commons.collections.CollectionUtils.isEmpty; import static org.apache.commons.collections.CollectionUtils.isNotEmpty; +import static org.thingsboard.server.common.data.util.CollectionsUtil.emptyOrContains; @Service public class AlarmTriggerProcessor implements NotificationRuleTriggerProcessor { @@ -85,11 +85,11 @@ public class AlarmTriggerProcessor implements NotificationRuleTriggerProcessor { +public class EntityActionTriggerProcessor implements NotificationRuleTriggerProcessor { @Override - public boolean matchesFilter(RuleEngineMsgTrigger trigger, EntityActionNotificationRuleTriggerConfig triggerConfig) { - String msgType = trigger.getMsg().getType(); - if (msgType.equals(DataConstants.ENTITY_CREATED)) { - if (!triggerConfig.isCreated()) { - return false; - } - } else if (msgType.equals(DataConstants.ENTITY_UPDATED)) { - if (!triggerConfig.isUpdated()) { - return false; - } - } else if (msgType.equals(DataConstants.ENTITY_DELETED)) { - if (!triggerConfig.isDeleted()) { - return false; - } - } else { - return false; - } - return isEmpty(triggerConfig.getEntityTypes()) || triggerConfig.getEntityTypes().contains(getEntityType(trigger.getMsg())); + public boolean matchesFilter(EntityActionTrigger trigger, EntityActionNotificationRuleTriggerConfig triggerConfig) { + return ((trigger.getActionType() == ActionType.ADDED && triggerConfig.isCreated()) + || (trigger.getActionType() == ActionType.UPDATED && triggerConfig.isUpdated()) + || (trigger.getActionType() == ActionType.DELETED && triggerConfig.isDeleted())) + && emptyOrContains(triggerConfig.getEntityTypes(), trigger.getEntityId().getEntityType()); } @Override - public RuleOriginatedNotificationInfo constructNotificationInfo(RuleEngineMsgTrigger trigger) { - TbMsg msg = trigger.getMsg(); - String msgType = msg.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; - TbMsgMetaData metaData = msg.getMetaData(); + public RuleOriginatedNotificationInfo constructNotificationInfo(EntityActionTrigger trigger) { return EntityActionNotificationInfo.builder() - .entityId(msg.getOriginator()) - .entityName(metaData.getValue("entityName")) - .actionType(actionType) - .userId(UUID.fromString(metaData.getValue("userId"))) - .userEmail(metaData.getValue("userEmail")) - .userFirstName(metaData.getValue("userFirstName")) - .userLastName(metaData.getValue("userLastName")) - .entityCustomerId(Optional.ofNullable(metaData.getValue("customerId")) - .map(UUID::fromString).map(CustomerId::new).orElse(null)) + .entityId(trigger.getEntityId()) + .entityName(trigger.getEntity().getName()) + .actionType(trigger.getActionType()) + .userId(trigger.getUser().getUuidId()) + .userTitle(trigger.getUser().getTitle()) + .userEmail(trigger.getUser().getEmail()) + .userFirstName(trigger.getUser().getFirstName()) + .userLastName(trigger.getUser().getLastName()) + .entityCustomerId(trigger.getEntity() instanceof HasCustomerId ? + ((HasCustomerId) trigger.getEntity()).getCustomerId() : + trigger.getUser().getCustomerId()) .build(); } - private static EntityType getEntityType(TbMsg msg) { - return Optional.ofNullable(msg.getMetaData().getValue("entityType")) - .map(EntityType::valueOf).orElse(null); - } - @Override public NotificationRuleTriggerType getTriggerType() { return NotificationRuleTriggerType.ENTITY_ACTION; } - @Override - public Set getSupportedMsgTypes() { - return Set.of(DataConstants.ENTITY_CREATED, DataConstants.ENTITY_UPDATED, DataConstants.ENTITY_DELETED); - } - } 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 3cb3a0a739..c4501d828e 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 @@ -41,6 +41,7 @@ public class EntityActionNotificationInfo implements RuleOriginatedNotificationI private CustomerId entityCustomerId; private UUID userId; + private String userTitle; private String userEmail; private String userFirstName; private String userLastName; @@ -53,7 +54,7 @@ public class EntityActionNotificationInfo implements RuleOriginatedNotificationI "entityName", entityName, "actionType", actionType.name().toLowerCase(), "userId", userId.toString(), - "userTitle", User.getTitle(userEmail, userFirstName, userLastName), + "userTitle", userTitle, "userEmail", userEmail, "userFirstName", userFirstName, "userLastName", userLastName diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/util/CollectionsUtil.java b/common/data/src/main/java/org/thingsboard/server/common/data/util/CollectionsUtil.java index 85d5621ec4..d8d17613de 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/util/CollectionsUtil.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/util/CollectionsUtil.java @@ -15,8 +15,6 @@ */ package org.thingsboard.server.common.data.util; -import com.google.common.collect.ImmutableMap; - import java.util.Collection; import java.util.Collections; import java.util.HashMap; @@ -63,8 +61,12 @@ public class CollectionsUtil { return map; } - public static Map unmodifiableMapOf(Object... kvs) { + public static Map unmodifiableMapOf(Object... kvs) { return Collections.unmodifiableMap(mapOf(kvs)); } + public static boolean emptyOrContains(Collection collection, V element) { + return isEmpty(collection) || collection.contains(element); + } + } diff --git a/common/message/src/main/java/org/thingsboard/server/common/msg/notification/trigger/EntityActionTrigger.java b/common/message/src/main/java/org/thingsboard/server/common/msg/notification/trigger/EntityActionTrigger.java new file mode 100644 index 0000000000..47d1789fec --- /dev/null +++ b/common/message/src/main/java/org/thingsboard/server/common/msg/notification/trigger/EntityActionTrigger.java @@ -0,0 +1,47 @@ +/** + * Copyright © 2016-2023 The Thingsboard Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.thingsboard.server.common.msg.notification.trigger; + +import lombok.Builder; +import lombok.Data; +import org.thingsboard.server.common.data.HasName; +import org.thingsboard.server.common.data.User; +import org.thingsboard.server.common.data.audit.ActionType; +import org.thingsboard.server.common.data.id.EntityId; +import org.thingsboard.server.common.data.id.TenantId; +import org.thingsboard.server.common.data.notification.rule.trigger.NotificationRuleTriggerType; + +@Data +@Builder +public class EntityActionTrigger implements NotificationRuleTrigger { + + private final TenantId tenantId; + private final EntityId entityId; + private final HasName entity; + private final ActionType actionType; + private final User user; + + @Override + public NotificationRuleTriggerType getType() { + return NotificationRuleTriggerType.ENTITY_ACTION; + } + + @Override + public EntityId getOriginatorEntityId() { + return entityId; + } + +}