diff --git a/application/src/main/java/org/thingsboard/server/service/housekeeper/processor/AlarmsDeletionTaskProcessor.java b/application/src/main/java/org/thingsboard/server/service/housekeeper/processor/AlarmsDeletionTaskProcessor.java index 09fa0977d5..cc6cb9bbab 100644 --- a/application/src/main/java/org/thingsboard/server/service/housekeeper/processor/AlarmsDeletionTaskProcessor.java +++ b/application/src/main/java/org/thingsboard/server/service/housekeeper/processor/AlarmsDeletionTaskProcessor.java @@ -24,12 +24,11 @@ import org.thingsboard.server.common.data.housekeeper.HousekeeperTaskType; import org.thingsboard.server.common.data.id.AlarmId; import org.thingsboard.server.common.data.id.EntityId; import org.thingsboard.server.common.data.id.TenantId; -import org.thingsboard.server.common.data.id.UUIDBased; +import org.thingsboard.server.common.data.util.TbPair; import org.thingsboard.server.dao.alarm.AlarmService; import java.util.List; import java.util.UUID; -import java.util.stream.Collectors; @Component @RequiredArgsConstructor @@ -46,16 +45,19 @@ public class AlarmsDeletionTaskProcessor extends HousekeeperTaskProcessor alarms = alarmService.findAlarmIdsByOriginatorIdAndIdOffset(tenantId, entityId, last, 128); + List> alarms = alarmService.findAlarmIdsByOriginatorId(tenantId, entityId, lastCreatedTime, lastId, 128); if (alarms.isEmpty()) { break; } - housekeeperClient.submitTask(new AlarmsDeletionHousekeeperTask(tenantId, entityId, alarms.stream() - .map(UUIDBased::getId).collect(Collectors.toList()))); - last = alarms.get(alarms.size() - 1); + housekeeperClient.submitTask(new AlarmsDeletionHousekeeperTask(tenantId, entityId, alarms.stream().map(TbPair::getFirst).toList())); + + TbPair last = alarms.get(alarms.size() - 1); + lastId = new AlarmId(last.getFirst()); + lastCreatedTime = last.getSecond(); log.debug("[{}][{}][{}] Submitted task for deleting {} alarms", tenantId, entityType, entityId, alarms.size()); } } else { diff --git a/application/src/main/java/org/thingsboard/server/service/housekeeper/processor/EntitiesDeletionTaskProcessor.java b/application/src/main/java/org/thingsboard/server/service/housekeeper/processor/EntitiesDeletionTaskProcessor.java index 00c8a7cc61..186a290528 100644 --- a/application/src/main/java/org/thingsboard/server/service/housekeeper/processor/EntitiesDeletionTaskProcessor.java +++ b/application/src/main/java/org/thingsboard/server/service/housekeeper/processor/EntitiesDeletionTaskProcessor.java @@ -24,12 +24,9 @@ import org.thingsboard.server.common.data.housekeeper.HousekeeperTaskType; import org.thingsboard.server.common.data.id.EntityId; import org.thingsboard.server.common.data.id.EntityIdFactory; import org.thingsboard.server.common.data.id.TenantId; -import org.thingsboard.server.dao.Dao; -import org.thingsboard.server.dao.entity.EntityDaoRegistry; import org.thingsboard.server.dao.entity.EntityDaoService; import org.thingsboard.server.dao.entity.EntityServiceRegistry; -import java.util.List; import java.util.UUID; @Component @@ -37,35 +34,19 @@ import java.util.UUID; @Slf4j public class EntitiesDeletionTaskProcessor extends HousekeeperTaskProcessor { - private final EntityDaoRegistry entityDaoRegistry; private final EntityServiceRegistry entityServiceRegistry; @Override public void process(EntitiesDeletionHousekeeperTask task) throws Exception { EntityType entityType = task.getEntityType(); TenantId tenantId = task.getTenantId(); - Dao entityDao = entityDaoRegistry.getDao(entityType); EntityDaoService entityService = entityServiceRegistry.getServiceByEntityType(entityType); - if (task.getEntities() == null) { - UUID last = null; - while (true) { - List entities = entityDao.findIdsByTenantIdAndIdOffset(tenantId, last, 128); - if (entities.isEmpty()) { - break; - } - - housekeeperClient.submitTask(new EntitiesDeletionHousekeeperTask(tenantId, entityType, entities)); - last = entities.get(entities.size() - 1); - log.debug("[{}] Submitted task for deleting {} {}s", tenantId, entities.size(), entityType.getNormalName().toLowerCase()); - } - } else { - for (UUID entityUuid : task.getEntities()) { - EntityId entityId = EntityIdFactory.getByTypeAndUuid(entityType, entityUuid); - entityService.deleteEntity(tenantId, entityId, true); - } - log.debug("[{}] Deleted {} {}s", tenantId, task.getEntities().size(), entityType.getNormalName().toLowerCase()); + for (UUID entityUuid : task.getEntities()) { + EntityId entityId = EntityIdFactory.getByTypeAndUuid(entityType, entityUuid); + entityService.deleteEntity(tenantId, entityId, true); } + log.debug("[{}] Deleted {} {}s", tenantId, task.getEntities().size(), entityType.getNormalName().toLowerCase()); } @Override diff --git a/application/src/main/java/org/thingsboard/server/service/housekeeper/processor/TenantEntitiesDeletionTaskProcessor.java b/application/src/main/java/org/thingsboard/server/service/housekeeper/processor/TenantEntitiesDeletionTaskProcessor.java new file mode 100644 index 0000000000..386afb1517 --- /dev/null +++ b/application/src/main/java/org/thingsboard/server/service/housekeeper/processor/TenantEntitiesDeletionTaskProcessor.java @@ -0,0 +1,63 @@ +/** + * Copyright © 2016-2024 The Thingsboard Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.thingsboard.server.service.housekeeper.processor; + +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Component; +import org.thingsboard.server.common.data.EntityType; +import org.thingsboard.server.common.data.housekeeper.EntitiesDeletionHousekeeperTask; +import org.thingsboard.server.common.data.housekeeper.HousekeeperTaskType; +import org.thingsboard.server.common.data.housekeeper.TenantEntitiesDeletionHousekeeperTask; +import org.thingsboard.server.common.data.id.TenantId; +import org.thingsboard.server.dao.Dao; +import org.thingsboard.server.dao.entity.EntityDaoRegistry; + +import java.util.List; +import java.util.UUID; + +@Component +@RequiredArgsConstructor +@Slf4j +public class TenantEntitiesDeletionTaskProcessor extends HousekeeperTaskProcessor { + + private final EntityDaoRegistry entityDaoRegistry; + + @Override + public void process(TenantEntitiesDeletionHousekeeperTask task) throws Exception { + EntityType entityType = task.getEntityType(); + TenantId tenantId = task.getTenantId(); + Dao entityDao = entityDaoRegistry.getDao(entityType); + + UUID last = null; + while (true) { + List entities = entityDao.findIdsByTenantIdAndIdOffset(tenantId, last, 128); + if (entities.isEmpty()) { + break; + } + + housekeeperClient.submitTask(new EntitiesDeletionHousekeeperTask(tenantId, entityType, entities)); + last = entities.get(entities.size() - 1); + log.debug("[{}] Submitted task for deleting {} {}s", tenantId, entities.size(), entityType.getNormalName().toLowerCase()); + } + } + + @Override + public HousekeeperTaskType getTaskType() { + return HousekeeperTaskType.DELETE_TENANT_ENTITIES; + } + +} diff --git a/application/src/test/java/org/thingsboard/server/service/housekeeper/HousekeeperServiceTest.java b/application/src/test/java/org/thingsboard/server/service/housekeeper/HousekeeperServiceTest.java index e66d3ed86a..e8f1a43ad1 100644 --- a/application/src/test/java/org/thingsboard/server/service/housekeeper/HousekeeperServiceTest.java +++ b/application/src/test/java/org/thingsboard/server/service/housekeeper/HousekeeperServiceTest.java @@ -360,7 +360,7 @@ public class HousekeeperServiceTest extends AbstractControllerTest { } private void verifyNoAlarms(EntityId entityId) { - assertThat(alarmService.findAlarmIdsByOriginatorIdAndIdOffset(tenantId, entityId, null, 10)).isEmpty(); + assertThat(alarmService.findAlarmIdsByOriginatorId(tenantId, entityId, 0, null, 10)).isEmpty(); } private void createAttribute(EntityId entityId, AttributeScope scope, String key) throws Exception { @@ -402,7 +402,7 @@ public class HousekeeperServiceTest extends AbstractControllerTest { List entityAlarms = alarmDao.findEntityAlarmRecords(tenantId, alarm.getId()); assertThat(entityAlarms).anyMatch(entityAlarm -> entityAlarm.getEntityId().equals(deviceId) && entityAlarm.getAlarmType().equals(alarm.getType())); assertThat(entityAlarms).anyMatch(entityAlarm -> entityAlarm.getEntityId().equals(propagatedEntityId) && entityAlarm.getAlarmType().equals(alarm.getType())); - assertThat(alarmService.findAlarmIdsByOriginatorIdAndIdOffset(tenantId, deviceId, null, 10)).isNotEmpty(); + assertThat(alarmService.findAlarmIdsByOriginatorId(tenantId, deviceId, 0, null, 10)).isNotEmpty(); } private void createAlarm(DeviceId deviceId) { @@ -412,7 +412,7 @@ public class HousekeeperServiceTest extends AbstractControllerTest { .severity(AlarmSeverity.CRITICAL) .type("test alarm for " + deviceId + " " + RandomStringUtils.randomAlphabetic(10)) .build(), Alarm.class); - assertThat(alarmService.findAlarmIdsByOriginatorIdAndIdOffset(tenantId, deviceId, null, 10)).isNotEmpty(); + assertThat(alarmService.findAlarmIdsByOriginatorId(tenantId, deviceId, 0, null, 10)).isNotEmpty(); } private TsKvEntry getLatestTelemetry(EntityId entityId) throws Exception { diff --git a/common/dao-api/src/main/java/org/thingsboard/server/dao/alarm/AlarmService.java b/common/dao-api/src/main/java/org/thingsboard/server/dao/alarm/AlarmService.java index ee584ff856..5bf6b95853 100644 --- a/common/dao-api/src/main/java/org/thingsboard/server/dao/alarm/AlarmService.java +++ b/common/dao-api/src/main/java/org/thingsboard/server/dao/alarm/AlarmService.java @@ -38,11 +38,13 @@ import org.thingsboard.server.common.data.page.PageLink; import org.thingsboard.server.common.data.query.AlarmCountQuery; import org.thingsboard.server.common.data.query.AlarmData; import org.thingsboard.server.common.data.query.AlarmDataQuery; +import org.thingsboard.server.common.data.util.TbPair; import org.thingsboard.server.dao.entity.EntityDaoService; import java.util.Collection; import java.util.List; import java.util.Set; +import java.util.UUID; public interface AlarmService extends EntityDaoService { @@ -107,7 +109,7 @@ public interface AlarmService extends EntityDaoService { PageData findAlarmIdsByAssigneeId(TenantId tenantId, UserId userId, PageLink pageLink); - List findAlarmIdsByOriginatorIdAndIdOffset(TenantId tenantId, EntityId originatorId, AlarmId idOffset, int limit); + List> findAlarmIdsByOriginatorId(TenantId tenantId, EntityId originatorId, long createdTimeOffset, AlarmId idOffset, int limit); int deleteEntityAlarmRecords(TenantId tenantId, EntityId entityId); diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/housekeeper/EntitiesDeletionHousekeeperTask.java b/common/data/src/main/java/org/thingsboard/server/common/data/housekeeper/EntitiesDeletionHousekeeperTask.java index d90fa6de94..b98af48d42 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/housekeeper/EntitiesDeletionHousekeeperTask.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/housekeeper/EntitiesDeletionHousekeeperTask.java @@ -16,7 +16,6 @@ package org.thingsboard.server.common.data.housekeeper; import com.fasterxml.jackson.annotation.JsonIgnore; -import lombok.AccessLevel; import lombok.Data; import lombok.EqualsAndHashCode; import lombok.NoArgsConstructor; @@ -30,16 +29,12 @@ import java.util.UUID; @Data @ToString(callSuper = true) @EqualsAndHashCode(callSuper = true) -@NoArgsConstructor(access = AccessLevel.PROTECTED) +@NoArgsConstructor public class EntitiesDeletionHousekeeperTask extends HousekeeperTask { private EntityType entityType; private List entities; - protected EntitiesDeletionHousekeeperTask(TenantId tenantId, EntityType entityType) { - this(tenantId, entityType, null); - } - public EntitiesDeletionHousekeeperTask(TenantId tenantId, EntityType entityType, List entities) { super(tenantId, tenantId, HousekeeperTaskType.DELETE_ENTITIES); this.entityType = entityType; @@ -49,7 +44,7 @@ public class EntitiesDeletionHousekeeperTask extends HousekeeperTask { @JsonIgnore @Override public String getDescription() { - return entityType.getNormalName().toLowerCase() + "s deletion" + (entities != null ? " (" + entities + ")" : ""); + return entityType.getNormalName().toLowerCase() + "s deletion (" + entities + ")"; } } diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/housekeeper/HousekeeperTask.java b/common/data/src/main/java/org/thingsboard/server/common/data/housekeeper/HousekeeperTask.java index 8354b2b861..8757b1121e 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/housekeeper/HousekeeperTask.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/housekeeper/HousekeeperTask.java @@ -36,6 +36,7 @@ import java.io.Serializable; @JsonSubTypes({ @Type(name = "DELETE_TS_HISTORY", value = TsHistoryDeletionHousekeeperTask.class), @Type(name = "DELETE_LATEST_TS", value = LatestTsDeletionHousekeeperTask.class), + @Type(name = "DELETE_TENANT_ENTITIES", value = TenantEntitiesDeletionHousekeeperTask.class), @Type(name = "DELETE_ENTITIES", value = EntitiesDeletionHousekeeperTask.class), @Type(name = "DELETE_ALARMS", value = AlarmsDeletionHousekeeperTask.class), @Type(name = "UNASSIGN_ALARMS", value = AlarmsUnassignHousekeeperTask.class) @@ -76,8 +77,8 @@ public class HousekeeperTask implements Serializable { return new AlarmsDeletionHousekeeperTask(tenantId, entityId); } - public static HousekeeperTask deleteEntities(TenantId tenantId, EntityType entityType) { - return new EntitiesDeletionHousekeeperTask(tenantId, entityType); + public static HousekeeperTask deleteTenantEntities(TenantId tenantId, EntityType entityType) { + return new TenantEntitiesDeletionHousekeeperTask(tenantId, entityType); } @JsonIgnore diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/housekeeper/HousekeeperTaskType.java b/common/data/src/main/java/org/thingsboard/server/common/data/housekeeper/HousekeeperTaskType.java index 572e85f2cf..edd13b3d5d 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/housekeeper/HousekeeperTaskType.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/housekeeper/HousekeeperTaskType.java @@ -22,14 +22,15 @@ import lombok.RequiredArgsConstructor; @Getter public enum HousekeeperTaskType { - DELETE_ENTITIES("entities deletion"), DELETE_ATTRIBUTES("attributes deletion"), DELETE_TELEMETRY("telemetry deletion"), DELETE_LATEST_TS("latest telemetry deletion"), DELETE_TS_HISTORY("timeseries history deletion"), DELETE_EVENTS("events deletion"), DELETE_ALARMS("alarms deletion"), - UNASSIGN_ALARMS("alarms unassigning"); + UNASSIGN_ALARMS("alarms unassigning"), + DELETE_TENANT_ENTITIES("tenant entities deletion"), + DELETE_ENTITIES("entities deletion"); private final String description; diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/housekeeper/TenantEntitiesDeletionHousekeeperTask.java b/common/data/src/main/java/org/thingsboard/server/common/data/housekeeper/TenantEntitiesDeletionHousekeeperTask.java new file mode 100644 index 0000000000..f6c6d5030c --- /dev/null +++ b/common/data/src/main/java/org/thingsboard/server/common/data/housekeeper/TenantEntitiesDeletionHousekeeperTask.java @@ -0,0 +1,45 @@ +/** + * Copyright © 2016-2024 The Thingsboard Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.thingsboard.server.common.data.housekeeper; + +import com.fasterxml.jackson.annotation.JsonIgnore; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.NoArgsConstructor; +import lombok.ToString; +import org.thingsboard.server.common.data.EntityType; +import org.thingsboard.server.common.data.id.TenantId; + +@Data +@ToString(callSuper = true) +@EqualsAndHashCode(callSuper = true) +@NoArgsConstructor +public class TenantEntitiesDeletionHousekeeperTask extends HousekeeperTask { + + private EntityType entityType; + + public TenantEntitiesDeletionHousekeeperTask(TenantId tenantId, EntityType entityType) { + super(tenantId, tenantId, HousekeeperTaskType.DELETE_TENANT_ENTITIES); + this.entityType = entityType; + } + + @JsonIgnore + @Override + public String getDescription() { + return entityType.getNormalName().toLowerCase() + "s deletion"; + } + +} diff --git a/dao/src/main/java/org/thingsboard/server/dao/alarm/AlarmDao.java b/dao/src/main/java/org/thingsboard/server/dao/alarm/AlarmDao.java index 03038b3bfe..570256e98c 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/alarm/AlarmDao.java +++ b/dao/src/main/java/org/thingsboard/server/dao/alarm/AlarmDao.java @@ -38,6 +38,7 @@ import org.thingsboard.server.common.data.page.PageLink; import org.thingsboard.server.common.data.query.AlarmCountQuery; import org.thingsboard.server.common.data.query.AlarmData; import org.thingsboard.server.common.data.query.AlarmDataQuery; +import org.thingsboard.server.common.data.util.TbPair; import org.thingsboard.server.dao.Dao; import java.util.Collection; @@ -80,7 +81,7 @@ public interface AlarmDao extends Dao { PageData findAlarmIdsByAssigneeId(TenantId tenantId, UUID userId, PageLink pageLink); - PageData findAlarmIdsByOriginatorId(TenantId tenantId, EntityId originatorId, AlarmId idOffset, PageLink pageLink); + PageData> findAlarmIdsByOriginatorId(TenantId tenantId, EntityId originatorId, long createdTimeOffset, AlarmId idOffset, int limit); void createEntityAlarmRecord(EntityAlarm entityAlarm); 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 9d0940a605..f0fc18c827 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 @@ -58,6 +58,7 @@ import org.thingsboard.server.common.data.relation.EntityRelation; import org.thingsboard.server.common.data.relation.EntityRelationsQuery; import org.thingsboard.server.common.data.relation.EntitySearchDirection; import org.thingsboard.server.common.data.relation.RelationsSearchParameters; +import org.thingsboard.server.common.data.util.TbPair; import org.thingsboard.server.dao.entity.AbstractCachedEntityService; import org.thingsboard.server.dao.entity.EntityService; import org.thingsboard.server.dao.eventsourcing.ActionEntityEvent; @@ -75,6 +76,7 @@ import java.util.LinkedHashSet; import java.util.List; import java.util.Optional; import java.util.Set; +import java.util.UUID; import java.util.concurrent.ExecutionException; import java.util.stream.Collectors; import java.util.stream.Stream; @@ -313,9 +315,9 @@ public class BaseAlarmService extends AbstractCachedEntityService findAlarmIdsByOriginatorIdAndIdOffset(TenantId tenantId, EntityId originatorId, AlarmId idOffset, int limit) { + public List> findAlarmIdsByOriginatorId(TenantId tenantId, EntityId originatorId, long createdTimeOffset, AlarmId idOffset, int limit) { log.trace("[{}] Executing findAlarmIdsByOriginatorIdAndIdOffset [{}][{}]", tenantId, originatorId, idOffset); - return alarmDao.findAlarmIdsByOriginatorId(tenantId, originatorId, idOffset, new PageLink(limit)).getData(); + return alarmDao.findAlarmIdsByOriginatorId(tenantId, originatorId, createdTimeOffset, idOffset, limit).getData(); } @Override diff --git a/dao/src/main/java/org/thingsboard/server/dao/housekeeper/CleanUpService.java b/dao/src/main/java/org/thingsboard/server/dao/housekeeper/CleanUpService.java index 48531aab90..082a60f44a 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/housekeeper/CleanUpService.java +++ b/dao/src/main/java/org/thingsboard/server/dao/housekeeper/CleanUpService.java @@ -77,7 +77,7 @@ public class CleanUpService { public void removeTenantEntities(TenantId tenantId, EntityType... entityTypes) { for (EntityType entityType : entityTypes) { - housekeeperClient.submitTask(HousekeeperTask.deleteEntities(tenantId, entityType)); + housekeeperClient.submitTask(HousekeeperTask.deleteTenantEntities(tenantId, entityType)); } } diff --git a/dao/src/main/java/org/thingsboard/server/dao/sql/alarm/AlarmRepository.java b/dao/src/main/java/org/thingsboard/server/dao/sql/alarm/AlarmRepository.java index ff9a2ed7d6..7bb16a9798 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/sql/alarm/AlarmRepository.java +++ b/dao/src/main/java/org/thingsboard/server/dao/sql/alarm/AlarmRepository.java @@ -24,6 +24,7 @@ import org.springframework.data.jpa.repository.Query; import org.springframework.data.repository.query.Param; import org.springframework.transaction.annotation.Transactional; import org.thingsboard.server.common.data.alarm.AlarmSeverity; +import org.thingsboard.server.common.data.util.TbPair; import org.thingsboard.server.dao.model.sql.AlarmEntity; import org.thingsboard.server.dao.model.sql.AlarmInfoEntity; @@ -334,12 +335,20 @@ public interface AlarmRepository extends JpaRepository { Page findAlarmIdsByAssigneeId(@Param("tenantId") UUID tenantId, @Param("assigneeId") UUID assigneeId, Pageable pageable); // using Slice so that count query is not executed - @Query(value = "SELECT id FROM alarm WHERE tenant_id = :tenantId AND originator_id = :originatorId " + - "AND (cast(:idOffset as uuid) IS NULL OR id > cast(:idOffset as uuid))", nativeQuery = true) - Slice findAlarmIdsByOriginatorId(@Param("tenantId") UUID tenantId, - @Param("originatorId") UUID originatorId, - @Param("idOffset") UUID idOffset, - Pageable pageable); + @Query("SELECT new org.thingsboard.server.common.data.util.TbPair(a.id, a.createdTime) " + + "FROM AlarmEntity a WHERE a.originatorId = :originatorId " + + "AND (a.createdTime > :createdTimeOffset OR " + + "(a.createdTime = :createdTimeOffset AND a.id > :idOffset))") + Slice> findAlarmIdsByOriginatorId(@Param("originatorId") UUID originatorId, + @Param("createdTimeOffset") long createdTimeOffset, + @Param("idOffset") UUID idOffset, + Pageable pageable); + + // using Slice so that count query is not executed + @Query("SELECT new org.thingsboard.server.common.data.util.TbPair(a.id, a.createdTime) " + + "FROM AlarmEntity a WHERE a.originatorId = :originatorId") + Slice> findAlarmIdsByOriginatorId(@Param("originatorId") UUID originatorId, + Pageable pageable); @Query(value = "SELECT create_or_update_active_alarm(:t_id, :c_id, :a_id, :a_created_ts, :a_o_id, :a_o_type, :a_type, :a_severity, " + ":a_start_ts, :a_end_ts, :a_details, :a_propagate, :a_propagate_to_owner, " + diff --git a/dao/src/main/java/org/thingsboard/server/dao/sql/alarm/JpaAlarmDao.java b/dao/src/main/java/org/thingsboard/server/dao/sql/alarm/JpaAlarmDao.java index da603a6c6f..c3e6e123f5 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/sql/alarm/JpaAlarmDao.java +++ b/dao/src/main/java/org/thingsboard/server/dao/sql/alarm/JpaAlarmDao.java @@ -21,6 +21,8 @@ import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.domain.Page; import org.springframework.data.domain.PageRequest; +import org.springframework.data.domain.Pageable; +import org.springframework.data.domain.Slice; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.stereotype.Component; import org.springframework.util.CollectionUtils; @@ -48,9 +50,11 @@ import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.common.data.id.UserId; import org.thingsboard.server.common.data.page.PageData; import org.thingsboard.server.common.data.page.PageLink; +import org.thingsboard.server.common.data.page.SortOrder; import org.thingsboard.server.common.data.query.AlarmCountQuery; import org.thingsboard.server.common.data.query.AlarmData; import org.thingsboard.server.common.data.query.AlarmDataQuery; +import org.thingsboard.server.common.data.util.TbPair; import org.thingsboard.server.dao.DaoUtil; import org.thingsboard.server.dao.alarm.AlarmDao; import org.thingsboard.server.dao.model.ModelConstants; @@ -69,6 +73,7 @@ import java.util.Optional; import java.util.Set; import java.util.UUID; +import static org.thingsboard.server.common.data.page.SortOrder.Direction.ASC; import static org.thingsboard.server.dao.DaoUtil.convertTenantEntityTypesToDto; import static org.thingsboard.server.dao.DaoUtil.toPageable; @@ -297,9 +302,15 @@ public class JpaAlarmDao extends JpaAbstractDao implements A } @Override - public PageData findAlarmIdsByOriginatorId(TenantId tenantId, EntityId originatorId, AlarmId idOffset, PageLink pageLink) { - return DaoUtil.pageToPageData(alarmRepository.findAlarmIdsByOriginatorId(tenantId.getId(), originatorId.getId(), idOffset != null ? idOffset.getId() : null, DaoUtil.toPageable(pageLink))) - .mapData(AlarmId::new); + public PageData> findAlarmIdsByOriginatorId(TenantId tenantId, EntityId originatorId, long createdTimeOffset, AlarmId idOffset, int limit) { + Slice> result; + Pageable pageRequest = toPageable(new PageLink(limit), List.of(SortOrder.of("createdTime", ASC), SortOrder.of("id", ASC))); + if (idOffset == null) { + result = alarmRepository.findAlarmIdsByOriginatorId(originatorId.getId(), pageRequest); + } else { + result = alarmRepository.findAlarmIdsByOriginatorId(originatorId.getId(), createdTimeOffset, idOffset.getId(), pageRequest); + } + return DaoUtil.pageToPageData(result); } @Override diff --git a/dao/src/test/java/org/thingsboard/server/dao/service/AbstractServiceTest.java b/dao/src/test/java/org/thingsboard/server/dao/service/AbstractServiceTest.java index f1e1fd0e76..6127a4192a 100644 --- a/dao/src/test/java/org/thingsboard/server/dao/service/AbstractServiceTest.java +++ b/dao/src/test/java/org/thingsboard/server/dao/service/AbstractServiceTest.java @@ -42,7 +42,7 @@ import org.thingsboard.server.common.data.device.profile.DefaultDeviceProfileTra import org.thingsboard.server.common.data.device.profile.DeviceProfileData; import org.thingsboard.server.common.data.edge.Edge; import org.thingsboard.server.common.data.event.RuleNodeDebugEvent; -import org.thingsboard.server.common.data.housekeeper.EntitiesDeletionHousekeeperTask; +import org.thingsboard.server.common.data.housekeeper.TenantEntitiesDeletionHousekeeperTask; import org.thingsboard.server.common.data.housekeeper.HousekeeperTaskType; import org.thingsboard.server.common.data.id.DeviceProfileId; import org.thingsboard.server.common.data.id.EntityId; @@ -142,8 +142,8 @@ public abstract class AbstractServiceTest { @Bean public HousekeeperClient housekeeperClient() { return task -> { - if (task.getTaskType() == HousekeeperTaskType.DELETE_ENTITIES) { - EntityDaoService entityService = entityServiceRegistry.getServiceByEntityType(((EntitiesDeletionHousekeeperTask) task).getEntityType()); + if (task.getTaskType() == HousekeeperTaskType.DELETE_TENANT_ENTITIES) { + EntityDaoService entityService = entityServiceRegistry.getServiceByEntityType(((TenantEntitiesDeletionHousekeeperTask) task).getEntityType()); entityService.deleteByTenantId(task.getTenantId()); } };