From 3932993b5891e940cdb5fc4cf5c601e4228ad564 Mon Sep 17 00:00:00 2001 From: Andrii Shvaika Date: Wed, 15 Feb 2023 17:19:04 +0200 Subject: [PATCH] Alarm assignment improvements --- .../main/data/upgrade/3.4.4/schema_update.sql | 2 + .../server/dao/entity/EntityService.java | 1 + .../server/common/data/HasEmail.java | 2 +- .../server/common/data/HasLabel.java | 2 +- .../server/common/data/HasTitle.java | 2 +- .../server/common/data/alarm/Alarm.java | 4 +- .../server/common/data/alarm/AlarmInfo.java | 27 +----- .../server/dao/alarm/BaseAlarmService.java | 2 +- .../server/dao/entity/BaseEntityService.java | 84 ++++++++++--------- .../resources/sql/schema-entities-idx.sql | 2 + 10 files changed, 57 insertions(+), 71 deletions(-) diff --git a/application/src/main/data/upgrade/3.4.4/schema_update.sql b/application/src/main/data/upgrade/3.4.4/schema_update.sql index a36d619cb3..8b809b84c3 100644 --- a/application/src/main/data/upgrade/3.4.4/schema_update.sql +++ b/application/src/main/data/upgrade/3.4.4/schema_update.sql @@ -20,6 +20,8 @@ ALTER TABLE alarm ADD COLUMN IF NOT EXISTS assign_ts BIGINT; ALTER TABLE alarm ADD COLUMN IF NOT EXISTS assignee_id UUID; +CREATE INDEX IF NOT EXISTS idx_alarm_tenant_assignee_created_time ON alarm(tenant_id, assignee_id, created_time DESC); + -- ALARM ASSIGN TO USER END CREATE TABLE IF NOT EXISTS alarm_comment ( diff --git a/common/dao-api/src/main/java/org/thingsboard/server/dao/entity/EntityService.java b/common/dao-api/src/main/java/org/thingsboard/server/dao/entity/EntityService.java index 04b6a05685..b5bee419f5 100644 --- a/common/dao-api/src/main/java/org/thingsboard/server/dao/entity/EntityService.java +++ b/common/dao-api/src/main/java/org/thingsboard/server/dao/entity/EntityService.java @@ -15,6 +15,7 @@ */ package org.thingsboard.server.dao.entity; +import org.springframework.data.util.Pair; import org.thingsboard.server.common.data.id.CustomerId; import org.thingsboard.server.common.data.id.EntityId; import org.thingsboard.server.common.data.id.TenantId; diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/HasEmail.java b/common/data/src/main/java/org/thingsboard/server/common/data/HasEmail.java index 7f413075f8..fd7fbf19fd 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/HasEmail.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/HasEmail.java @@ -1,5 +1,5 @@ /** - * Copyright © 2016-2022 The Thingsboard Authors + * 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. diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/HasLabel.java b/common/data/src/main/java/org/thingsboard/server/common/data/HasLabel.java index d9c3c9b98c..fe4f46c9de 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/HasLabel.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/HasLabel.java @@ -1,5 +1,5 @@ /** - * Copyright © 2016-2022 The Thingsboard Authors + * 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. diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/HasTitle.java b/common/data/src/main/java/org/thingsboard/server/common/data/HasTitle.java index 886cef5fb1..aab1c6c346 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/HasTitle.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/HasTitle.java @@ -1,5 +1,5 @@ /** - * Copyright © 2016-2022 The Thingsboard Authors + * 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. diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/alarm/Alarm.java b/common/data/src/main/java/org/thingsboard/server/common/data/alarm/Alarm.java index f16920ed39..e8329bce37 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/alarm/Alarm.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/alarm/Alarm.java @@ -22,6 +22,7 @@ import io.swagger.annotations.ApiModelProperty; import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Data; +import lombok.EqualsAndHashCode; import org.thingsboard.server.common.data.BaseData; import org.thingsboard.server.common.data.HasCustomerId; import org.thingsboard.server.common.data.HasName; @@ -41,6 +42,7 @@ import java.util.List; */ @ApiModel @Data +@EqualsAndHashCode(callSuper = true) @Builder @AllArgsConstructor public class Alarm extends BaseData implements HasName, HasTenantId, HasCustomerId { @@ -71,7 +73,7 @@ public class Alarm extends BaseData implements HasName, HasTenantId, Ha private long ackTs; @ApiModelProperty(position = 14, value = "Timestamp of the alarm clearing, in milliseconds", example = "1634114528465") private long clearTs; - @ApiModelProperty(position = 15, value = "Timestamp of the alarm assigning0, in milliseconds", example = "1634115928465") + @ApiModelProperty(position = 15, value = "Timestamp of the alarm assignment, in milliseconds", example = "1634115928465") private long assignTs; @ApiModelProperty(position = 16, value = "JSON object with alarm details") private transient JsonNode details; diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/alarm/AlarmInfo.java b/common/data/src/main/java/org/thingsboard/server/common/data/alarm/AlarmInfo.java index ea5f2c20b0..9d3d1a6083 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/alarm/AlarmInfo.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/alarm/AlarmInfo.java @@ -17,12 +17,14 @@ package org.thingsboard.server.common.data.alarm; import io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiModelProperty; +import lombok.EqualsAndHashCode; import lombok.Getter; import lombok.Setter; import org.thingsboard.server.common.data.User; import java.util.Objects; +@EqualsAndHashCode(callSuper = true) @ApiModel public class AlarmInfo extends Alarm { @@ -79,29 +81,4 @@ public class AlarmInfo extends Alarm { this.assigneeEmail = assigneeEmail; } - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - if (!super.equals(o)) return false; - - AlarmInfo alarmInfo = (AlarmInfo) o; - - return (Objects.equals(originatorName, alarmInfo.originatorName)) && - (Objects.equals(originatorLabel, alarmInfo.originatorLabel)) && - (Objects.equals(assigneeFirstName, alarmInfo.assigneeFirstName)) && - (Objects.equals(assigneeLastName, alarmInfo.assigneeLastName)) && - (Objects.equals(assigneeEmail, alarmInfo.assigneeEmail)); - } - - @Override - public int hashCode() { - int result = super.hashCode(); - result = 31 * result + (originatorName != null ? originatorName.hashCode() : 0) - + (originatorLabel != null ? originatorLabel.hashCode() : 0) - + (assigneeFirstName != null ? assigneeFirstName.hashCode() : 0) - + (assigneeLastName != null ? assigneeLastName.hashCode() : 0) - + (assigneeEmail != null ? assigneeEmail.hashCode() : 0); - return result; - } } diff --git a/dao/src/main/java/org/thingsboard/server/dao/alarm/BaseAlarmService.java b/dao/src/main/java/org/thingsboard/server/dao/alarm/BaseAlarmService.java index ef2526a81d..6e501fb6fb 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/alarm/BaseAlarmService.java +++ b/dao/src/main/java/org/thingsboard/server/dao/alarm/BaseAlarmService.java @@ -122,7 +122,7 @@ public class BaseAlarmService extends AbstractEntityService implements AlarmServ if (alarm.getEndTs() == 0L) { alarm.setEndTs(alarm.getStartTs()); } - alarm.setCustomerId(entityService.fetchEntityCustomerId(alarm.getTenantId(), alarm.getOriginator()).orElse(null)); + alarm.setCustomerId(entityService.fetchEntityCustomerId(alarm.getTenantId(), alarm.getOriginator()).get()); if (alarm.getId() == null) { Alarm existing = alarmDao.findLatestByOriginatorAndType(alarm.getTenantId(), alarm.getOriginator(), alarm.getType()); if (existing == null || existing.getStatus().isCleared()) { diff --git a/dao/src/main/java/org/thingsboard/server/dao/entity/BaseEntityService.java b/dao/src/main/java/org/thingsboard/server/dao/entity/BaseEntityService.java index dfa4cf3d7d..4d0b454b22 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/entity/BaseEntityService.java +++ b/dao/src/main/java/org/thingsboard/server/dao/entity/BaseEntityService.java @@ -5,7 +5,7 @@ * 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 + * 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, @@ -16,7 +16,9 @@ package org.thingsboard.server.dao.entity; import lombok.extern.slf4j.Slf4j; +import org.jetbrains.annotations.Nullable; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.data.util.Pair; import org.springframework.stereotype.Service; import org.springframework.util.CollectionUtils; import org.thingsboard.server.common.data.HasCustomerId; @@ -37,6 +39,7 @@ import org.thingsboard.server.common.data.query.RelationsQueryFilter; import org.thingsboard.server.dao.exception.IncorrectParameterException; import java.util.Optional; +import java.util.function.Function; import static org.thingsboard.server.common.data.id.EntityId.NULL_UUID; import static org.thingsboard.server.dao.service.Validator.validateEntityDataPageLink; @@ -80,59 +83,58 @@ public class BaseEntityService extends AbstractEntityService implements EntitySe @Override public Optional fetchEntityName(TenantId tenantId, EntityId entityId) { log.trace("Executing fetchEntityName [{}]", entityId); - EntityDaoService entityDaoService = entityServiceRegistry.getServiceByEntityType(entityId.getEntityType()); - Optional> hasIdOpt = entityDaoService.findEntity(tenantId, entityId); - if (hasIdOpt.isPresent()) { - HasId hasId = hasIdOpt.get(); - if (hasId instanceof HasName) { - HasName hasName = (HasName) hasId; - return Optional.ofNullable(hasName.getName()); - } - } - return Optional.empty(); + return fetchAndConvert(tenantId, entityId, this::getName); } @Override public Optional fetchEntityLabel(TenantId tenantId, EntityId entityId) { log.trace("Executing fetchEntityLabel [{}]", entityId); - EntityDaoService entityDaoService = entityServiceRegistry.getServiceByEntityType(entityId.getEntityType()); - Optional> entityOpt = entityDaoService.findEntity(tenantId, entityId); - String entityLabel = null; - if (entityOpt.isPresent()) { - HasId entity = entityOpt.get(); - if (entity instanceof HasTitle) { - entityLabel = ((HasTitle) entity).getTitle(); - } - if (entity instanceof HasLabel && entityLabel == null) { - entityLabel = ((HasLabel) entity).getLabel(); - } - if (entity instanceof HasEmail && entityLabel == null) { - entityLabel = ((HasEmail) entity).getEmail(); - } - if (entity instanceof HasName && entityLabel == null) { - entityLabel = ((HasName) entity).getName(); - } - } - return Optional.ofNullable(entityLabel); + return fetchAndConvert(tenantId, entityId, this::getLabel); } @Override public Optional fetchEntityCustomerId(TenantId tenantId, EntityId entityId) { log.trace("Executing fetchEntityCustomerId [{}]", entityId); + return fetchAndConvert(tenantId, entityId, this::getCustomerId); + } + + private Optional fetchAndConvert(TenantId tenantId, EntityId entityId, Function, T> converter) { EntityDaoService entityDaoService = entityServiceRegistry.getServiceByEntityType(entityId.getEntityType()); - Optional> hasIdOpt = entityDaoService.findEntity(tenantId, entityId); - if (hasIdOpt.isPresent()) { - HasId hasId = hasIdOpt.get(); - if (hasId instanceof HasCustomerId) { - HasCustomerId hasCustomerId = (HasCustomerId) hasId; - CustomerId customerId = hasCustomerId.getCustomerId(); - if (customerId == null) { - customerId = NULL_CUSTOMER_ID; - } - return Optional.of(customerId); + Optional> entityOpt = entityDaoService.findEntity(tenantId, entityId); + return entityOpt.map(converter); + } + + private String getName(HasId entity) { + return entity instanceof HasName ? ((HasName) entity).getName() : null; + } + + private String getLabel(HasId entity) { + String entityLabel = null; + if (entity instanceof HasTitle) { + entityLabel = ((HasTitle) entity).getTitle(); + } + if (entity instanceof HasLabel && entityLabel == null) { + entityLabel = ((HasLabel) entity).getLabel(); + } + if (entity instanceof HasEmail && entityLabel == null) { + entityLabel = ((HasEmail) entity).getEmail(); + } + if (entity instanceof HasName && entityLabel == null) { + entityLabel = ((HasName) entity).getName(); + } + return entityLabel; + } + + private CustomerId getCustomerId(HasId hasId) { + if (hasId instanceof HasCustomerId) { + HasCustomerId hasCustomerId = (HasCustomerId) hasId; + CustomerId customerId = hasCustomerId.getCustomerId(); + if (customerId == null) { + customerId = NULL_CUSTOMER_ID; } + return customerId; } - return Optional.of(NULL_CUSTOMER_ID); + return NULL_CUSTOMER_ID; } private static void validateEntityCountQuery(EntityCountQuery query) { diff --git a/dao/src/main/resources/sql/schema-entities-idx.sql b/dao/src/main/resources/sql/schema-entities-idx.sql index a5b1261d40..3671b4ed34 100644 --- a/dao/src/main/resources/sql/schema-entities-idx.sql +++ b/dao/src/main/resources/sql/schema-entities-idx.sql @@ -24,6 +24,8 @@ CREATE INDEX IF NOT EXISTS idx_alarm_tenant_status_created_time ON alarm(tenant_ CREATE INDEX IF NOT EXISTS idx_alarm_tenant_alarm_type_created_time ON alarm(tenant_id, type, created_time DESC); +CREATE INDEX IF NOT EXISTS idx_alarm_tenant_assignee_created_time ON alarm(tenant_id, assignee_id, created_time DESC); + CREATE INDEX IF NOT EXISTS idx_entity_alarm_created_time ON entity_alarm(tenant_id, entity_id, created_time DESC); CREATE INDEX IF NOT EXISTS idx_entity_alarm_alarm_id ON entity_alarm(alarm_id);