Alarms deletion in batches with id offset
This commit is contained in:
parent
49a76cad5a
commit
feb629f2c2
@ -92,7 +92,7 @@ public class HousekeeperService {
|
||||
|
||||
private void processMsgs(List<TbProtoQueueMsg<ToHousekeeperServiceMsg>> msgs, TbQueueConsumer<TbProtoQueueMsg<ToHousekeeperServiceMsg>> consumer) {
|
||||
for (TbProtoQueueMsg<ToHousekeeperServiceMsg> msg : msgs) {
|
||||
log.trace("Processing task: {} attempt={}", msg, msg.getValue().getTask().getAttempt());
|
||||
log.trace("Processing task: {}", msg);
|
||||
try {
|
||||
processTask(msg.getValue());
|
||||
} catch (InterruptedException e) {
|
||||
|
||||
@ -19,26 +19,49 @@ 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.HousekeeperTask;
|
||||
import org.thingsboard.server.common.data.housekeeper.AlarmsDeletionHousekeeperTask;
|
||||
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.dao.DaoUtil;
|
||||
import org.thingsboard.server.dao.alarm.AlarmService;
|
||||
|
||||
import java.util.UUID;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@Component
|
||||
@RequiredArgsConstructor
|
||||
@Slf4j
|
||||
public class AlarmsDeletionTaskProcessor extends HousekeeperTaskProcessor<HousekeeperTask> {
|
||||
public class AlarmsDeletionTaskProcessor extends HousekeeperTaskProcessor<AlarmsDeletionHousekeeperTask> {
|
||||
|
||||
private final AlarmService alarmService;
|
||||
|
||||
@Override
|
||||
public void process(HousekeeperTask task) throws Exception {
|
||||
EntityType entityType = task.getEntityId().getEntityType();
|
||||
public void process(AlarmsDeletionHousekeeperTask task) throws Exception {
|
||||
EntityId entityId = task.getEntityId();
|
||||
EntityType entityType = entityId.getEntityType();
|
||||
TenantId tenantId = task.getTenantId();
|
||||
|
||||
if (entityType == EntityType.DEVICE || entityType == EntityType.ASSET) {
|
||||
int count = alarmService.deleteAlarmsByOriginatorId(task.getTenantId(), task.getEntityId());
|
||||
log.debug("[{}][{}][{}] Deleted {} alarms", task.getTenantId(), task.getEntityId().getEntityType(), task.getEntityId(), count);
|
||||
if (task.getAlarms() == null) {
|
||||
DaoUtil.iterateWithKeyOffset(pageLink -> {
|
||||
return alarmService.findAlarmIdsByOriginatorId(tenantId, entityId, pageLink);
|
||||
}, 128, alarms -> {
|
||||
housekeeperClient.submitTask(new AlarmsDeletionHousekeeperTask(tenantId, entityId, alarms.stream()
|
||||
.map(UUIDBased::getId).collect(Collectors.toList())));
|
||||
log.debug("[{}][{}][{}] Submitted task for deleting {} alarms", tenantId, entityType, entityId, alarms.size());
|
||||
});
|
||||
} else {
|
||||
int count = alarmService.deleteEntityAlarmRecords(task.getTenantId(), task.getEntityId());
|
||||
log.debug("[{}][{}][{}] Deleted {} entity alarms", task.getTenantId(), task.getEntityId().getEntityType(), task.getEntityId(), count);
|
||||
for (UUID alarmId : task.getAlarms()) {
|
||||
alarmService.delAlarm(tenantId, new AlarmId(alarmId));
|
||||
}
|
||||
log.debug("[{}][{}][{}] Deleted {} alarms", tenantId, entityType, entityId, task.getAlarms().size());
|
||||
}
|
||||
} else {
|
||||
int count = alarmService.deleteEntityAlarmRecords(tenantId, entityId);
|
||||
log.debug("[{}][{}][{}] Deleted {} entity alarms", tenantId, entityType, entityId, count);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -17,25 +17,24 @@ package org.thingsboard.server.service.housekeeper;
|
||||
|
||||
import com.fasterxml.jackson.databind.JsonNode;
|
||||
import com.fasterxml.jackson.databind.node.TextNode;
|
||||
import net.bytebuddy.implementation.bytecode.Throw;
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.junit.Ignore;
|
||||
import org.junit.Test;
|
||||
import org.mockito.ArgumentMatcher;
|
||||
import org.mockito.Mockito;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.test.mock.mockito.SpyBean;
|
||||
import org.springframework.test.context.TestPropertySource;
|
||||
import org.testcontainers.shaded.org.apache.commons.lang3.RandomStringUtils;
|
||||
import org.thingsboard.common.util.JacksonUtil;
|
||||
import org.thingsboard.rule.engine.metadata.TbGetAttributesNode;
|
||||
import org.thingsboard.rule.engine.metadata.TbGetAttributesNodeConfiguration;
|
||||
import org.thingsboard.server.common.data.ApiUsageState;
|
||||
import org.thingsboard.server.common.data.AttributeScope;
|
||||
import org.thingsboard.server.common.data.DataConstants;
|
||||
import org.thingsboard.server.common.data.Device;
|
||||
import org.thingsboard.server.common.data.EventInfo;
|
||||
import org.thingsboard.server.common.data.alarm.Alarm;
|
||||
import org.thingsboard.server.common.data.alarm.AlarmQuery;
|
||||
import org.thingsboard.server.common.data.alarm.AlarmSeverity;
|
||||
import org.thingsboard.server.common.data.alarm.EntityAlarm;
|
||||
import org.thingsboard.server.common.data.asset.Asset;
|
||||
@ -79,7 +78,6 @@ import org.thingsboard.server.dao.timeseries.TimeseriesService;
|
||||
import org.thingsboard.server.dao.usagerecord.ApiUsageStateDao;
|
||||
import org.thingsboard.server.gen.transport.TransportProtos.HousekeeperTaskProto;
|
||||
import org.thingsboard.server.gen.transport.TransportProtos.ToHousekeeperServiceMsg;
|
||||
import org.thingsboard.server.service.housekeeper.processor.TelemetryDeletionTaskProcessor;
|
||||
import org.thingsboard.server.service.housekeeper.processor.TsHistoryDeletionTaskProcessor;
|
||||
|
||||
import java.util.Arrays;
|
||||
@ -156,7 +154,7 @@ public class HousekeeperServiceTest extends AbstractControllerTest {
|
||||
|
||||
@Test
|
||||
public void whenDeviceIsDeleted_thenCleanUpRelatedData() throws Exception {
|
||||
Device device = createDevice("wekfwepf", "wekfwepf");
|
||||
Device device = createDevice("test", "test");
|
||||
createRelatedData(device.getId());
|
||||
|
||||
doDelete("/api/device/" + device.getId()).andExpect(status().isOk());
|
||||
@ -187,7 +185,7 @@ public class HousekeeperServiceTest extends AbstractControllerTest {
|
||||
|
||||
@Test
|
||||
public void whenUserIsDeleted_thenCleanUpRelatedData() throws Exception {
|
||||
Device device = createDevice("vneoruvhwe", "vneoruvhwe");
|
||||
Device device = createDevice("test", "test");
|
||||
UserId userId = customerUserId;
|
||||
createRelatedData(userId);
|
||||
Alarm alarm = Alarm.builder()
|
||||
@ -210,6 +208,20 @@ public class HousekeeperServiceTest extends AbstractControllerTest {
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenDeviceIsDeleted_thenDeleteAllAlarms() throws Exception {
|
||||
Device device = createDevice("test", "test");
|
||||
for (int i = 1; i <= 1000; i++) {
|
||||
createAlarm(device.getId());
|
||||
}
|
||||
|
||||
doDelete("/api/device/" + device.getId()).andExpect(status().isOk());
|
||||
|
||||
await().atMost(30, TimeUnit.SECONDS).untilAsserted(() -> {
|
||||
verifyNoAlarms(device.getId());
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenTenantIsDeleted_thenDeleteAllEntitiesAndCleanUpRelatedData() throws Exception {
|
||||
loginDifferentTenant();
|
||||
@ -220,7 +232,7 @@ public class HousekeeperServiceTest extends AbstractControllerTest {
|
||||
createRelatedData(differentTenantCustomerId);
|
||||
loginDifferentTenant();
|
||||
|
||||
Device device = createDevice("oi324rujoi", "oi324rujoi");
|
||||
Device device = createDevice("test", "test");
|
||||
createRelatedData(device.getId());
|
||||
|
||||
Asset asset = createAsset();
|
||||
@ -258,11 +270,12 @@ public class HousekeeperServiceTest extends AbstractControllerTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
@Ignore // FIXME !!!
|
||||
public void whenTaskProcessingFails_thenReprocess() throws Exception {
|
||||
TimeoutException error = new TimeoutException("Test timeout");
|
||||
doThrow(error).when(tsHistoryDeletionTaskProcessor).process(any());
|
||||
|
||||
Device device = createDevice("vep9ruv32", "vep9ruv32");
|
||||
Device device = createDevice("test", "test");
|
||||
createRelatedData(device.getId());
|
||||
|
||||
doDelete("/api/device/" + device.getId()).andExpect(status().isOk());
|
||||
@ -286,11 +299,12 @@ public class HousekeeperServiceTest extends AbstractControllerTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
@Ignore // FIXME !!!
|
||||
public void whenReprocessingAttemptsExceeded_thenReprocessOnNextStartUp() throws Exception {
|
||||
TimeoutException error = new TimeoutException("Test timeout");
|
||||
doThrow(error).when(tsHistoryDeletionTaskProcessor).process(any());
|
||||
|
||||
Device device = createDevice("woeifjiowejf", "woeifjiowejf");
|
||||
Device device = createDevice("test", "test");
|
||||
createRelatedData(device.getId());
|
||||
|
||||
doDelete("/api/device/" + device.getId()).andExpect(status().isOk());
|
||||
@ -332,32 +346,31 @@ public class HousekeeperServiceTest extends AbstractControllerTest {
|
||||
|
||||
private void createRelatedData(EntityId entityId) throws Exception {
|
||||
createTelemetry(entityId);
|
||||
for (AttributeScope scope : List.of(AttributeScope.SERVER_SCOPE, AttributeScope.SHARED_SCOPE, AttributeScope.CLIENT_SCOPE)) {
|
||||
for (AttributeScope scope : AttributeScope.values()) {
|
||||
createAttribute(entityId, scope, scope + ATTRIBUTE_KEY);
|
||||
}
|
||||
createEvent(entityId);
|
||||
}
|
||||
|
||||
private void verifyNoRelatedData(EntityId entityId) throws Exception {
|
||||
List<HousekeeperTaskType> expectedTaskTypes = List.of(HousekeeperTaskType.DELETE_TELEMETRY, HousekeeperTaskType.DELETE_ATTRIBUTES, HousekeeperTaskType.DELETE_EVENTS, HousekeeperTaskType.DELETE_ALARMS);
|
||||
for (HousekeeperTaskType taskType : expectedTaskTypes) {
|
||||
verify(housekeeperClient).submitTask(argThat(task -> task.getTaskType() == taskType && task.getEntityId().equals(entityId)));
|
||||
}
|
||||
assertThat(entityServiceRegistry.getServiceByEntityType(entityId.getEntityType()).findEntity(tenantId, entityId)).isEmpty();
|
||||
|
||||
assertThat(getLatestTelemetry(entityId)).isNull();
|
||||
assertThat(getTimeseriesHistory(entityId)).isEmpty();
|
||||
for (String scope : List.of(DataConstants.SERVER_SCOPE, DataConstants.SHARED_SCOPE, DataConstants.CLIENT_SCOPE)) {
|
||||
for (AttributeScope scope : AttributeScope.values()) {
|
||||
assertThat(attributesService.findAll(tenantId, entityId, scope).get()).isEmpty();
|
||||
}
|
||||
assertThat(getEvents(entityId)).isEmpty();
|
||||
assertThat(alarmDao.findEntityAlarmRecordsByEntityId(tenantId, entityId)).isEmpty();
|
||||
assertThat(alarmService.findAlarms(tenantId, AlarmQuery.builder().pageLink(new TimePageLink(100)).build()).getData())
|
||||
.filteredOn(alarm -> alarm.getOriginator().equals(entityId)).isEmpty();
|
||||
verifyNoAlarms(entityId);
|
||||
assertThat(relationService.findByTo(tenantId, entityId, RelationTypeGroup.COMMON)).isEmpty();
|
||||
assertThat(relationService.findByFrom(tenantId, entityId, RelationTypeGroup.COMMON)).isEmpty();
|
||||
}
|
||||
|
||||
private void verifyNoAlarms(EntityId entityId) {
|
||||
assertThat(alarmService.findAlarmIdsByOriginatorId(tenantId, entityId, new PageLink(1)).getData()).isEmpty();
|
||||
}
|
||||
|
||||
private void createAttribute(EntityId entityId, AttributeScope scope, String key) throws Exception {
|
||||
attributesService.save(tenantId, entityId, scope, new BaseAttributeKvEntry(System.currentTimeMillis(), new StringDataEntry(key, KV_VALUE))).get();
|
||||
}
|
||||
@ -397,8 +410,17 @@ public class HousekeeperServiceTest extends AbstractControllerTest {
|
||||
List<EntityAlarm> 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.findAlarms(tenantId, AlarmQuery.builder().pageLink(new TimePageLink(100)).build()).getData())
|
||||
.filteredOn(a -> a.getOriginator().equals(deviceId)).isNotEmpty();
|
||||
assertThat(alarmService.findAlarmIdsByOriginatorId(tenantId, deviceId, new PageLink(1)).getData()).isNotEmpty();
|
||||
}
|
||||
|
||||
private void createAlarm(DeviceId deviceId) {
|
||||
Alarm alarm = doPost("/api/alarm", Alarm.builder()
|
||||
.tenantId(tenantId)
|
||||
.originator(deviceId)
|
||||
.severity(AlarmSeverity.CRITICAL)
|
||||
.type("test alarm for " + deviceId + " " + RandomStringUtils.randomAlphabetic(10))
|
||||
.build(), Alarm.class);
|
||||
assertThat(alarmService.findAlarmIdsByOriginatorId(tenantId, deviceId, new PageLink(1)).getData()).isNotEmpty();
|
||||
}
|
||||
|
||||
private TsKvEntry getLatestTelemetry(EntityId entityId) throws Exception {
|
||||
|
||||
@ -81,8 +81,6 @@ public interface AlarmService extends EntityDaoService {
|
||||
|
||||
void delAlarmTypes(TenantId tenantId, Set<String> types);
|
||||
|
||||
int deleteAlarmsByOriginatorId(TenantId tenantId, EntityId entityId);
|
||||
|
||||
// Other API
|
||||
Alarm findAlarmById(TenantId tenantId, AlarmId alarmId);
|
||||
|
||||
|
||||
@ -0,0 +1,46 @@
|
||||
/**
|
||||
* 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 lombok.AccessLevel;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.NoArgsConstructor;
|
||||
import lombok.ToString;
|
||||
import org.thingsboard.server.common.data.id.EntityId;
|
||||
import org.thingsboard.server.common.data.id.TenantId;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
|
||||
@Data
|
||||
@ToString(callSuper = true)
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@NoArgsConstructor(access = AccessLevel.PROTECTED)
|
||||
public class AlarmsDeletionHousekeeperTask extends HousekeeperTask {
|
||||
|
||||
private List<UUID> alarms;
|
||||
|
||||
public AlarmsDeletionHousekeeperTask(TenantId tenantId, EntityId entityId, List<UUID> alarms) {
|
||||
super(tenantId, entityId, HousekeeperTaskType.DELETE_ALARMS);
|
||||
this.alarms = alarms;
|
||||
}
|
||||
|
||||
public AlarmsDeletionHousekeeperTask(TenantId tenantId, EntityId entityId) {
|
||||
super(tenantId, entityId, HousekeeperTaskType.DELETE_ALARMS);
|
||||
}
|
||||
|
||||
}
|
||||
@ -37,6 +37,7 @@ import java.io.Serializable;
|
||||
@Type(name = "DELETE_TS_HISTORY", value = TsHistoryDeletionHousekeeperTask.class),
|
||||
@Type(name = "DELETE_LATEST_TS", value = LatestTsDeletionHousekeeperTask.class),
|
||||
@Type(name = "DELETE_ENTITIES", value = EntitiesDeletionHousekeeperTask.class),
|
||||
@Type(name = "DELETE_ALARMS", value = AlarmsDeletionHousekeeperTask.class),
|
||||
@Type(name = "UNASSIGN_ALARMS", value = AlarmsUnassignHousekeeperTask.class)
|
||||
})
|
||||
@Data
|
||||
@ -81,7 +82,7 @@ public class HousekeeperTask implements Serializable {
|
||||
}
|
||||
|
||||
public static HousekeeperTask deleteAlarms(TenantId tenantId, EntityId entityId) {
|
||||
return new HousekeeperTask(tenantId, entityId, HousekeeperTaskType.DELETE_ALARMS);
|
||||
return new AlarmsDeletionHousekeeperTask(tenantId, entityId);
|
||||
}
|
||||
|
||||
public static HousekeeperTask deleteEntities(TenantId tenantId, EntityType entityType) {
|
||||
|
||||
@ -16,15 +16,20 @@
|
||||
package org.thingsboard.server.common.data.page;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonIgnore;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Builder;
|
||||
import lombok.Data;
|
||||
import org.springframework.data.domain.Sort;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@Data
|
||||
@AllArgsConstructor
|
||||
@Builder
|
||||
public class PageLink {
|
||||
|
||||
protected static final String DEFAULT_SORT_PROPERTY = "id";
|
||||
@ -34,6 +39,7 @@ public class PageLink {
|
||||
private final int pageSize;
|
||||
private final int page;
|
||||
private final SortOrder sortOrder;
|
||||
private UUID idOffset;
|
||||
|
||||
public PageLink(PageLink pageLink) {
|
||||
this.pageSize = pageLink.getPageSize();
|
||||
|
||||
@ -32,6 +32,10 @@ public class SortOrder {
|
||||
this.direction = direction;
|
||||
}
|
||||
|
||||
public static SortOrder of(String property, Direction direction) {
|
||||
return new SortOrder(property, direction);
|
||||
}
|
||||
|
||||
public static enum Direction {
|
||||
ASC, DESC
|
||||
}
|
||||
|
||||
@ -18,10 +18,12 @@ package org.thingsboard.server.dao;
|
||||
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.util.CollectionUtils;
|
||||
import org.thingsboard.server.common.data.EntityInfo;
|
||||
import org.thingsboard.server.common.data.EntitySubtype;
|
||||
import org.thingsboard.server.common.data.EntityType;
|
||||
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.page.PageData;
|
||||
@ -51,8 +53,17 @@ public abstract class DaoUtil {
|
||||
return new PageData<>(data, page.getTotalPages(), page.getTotalElements(), page.hasNext());
|
||||
}
|
||||
|
||||
public static <T> PageData<T> pageToPageData(Page<T> page) {
|
||||
return new PageData<>(page.getContent(), page.getTotalPages(), page.getTotalElements(), page.hasNext());
|
||||
public static <T> PageData<T> pageToPageData(Slice<T> slice) {
|
||||
int totalPages;
|
||||
long totalElements;
|
||||
if (slice instanceof Page<T> page) {
|
||||
totalPages = page.getTotalPages();
|
||||
totalElements = page.getTotalElements();
|
||||
} else {
|
||||
totalPages = 0;
|
||||
totalElements = 0;
|
||||
}
|
||||
return new PageData<>(slice.getContent(), totalPages, totalElements, slice.hasNext());
|
||||
}
|
||||
|
||||
public static Pageable toPageable(PageLink pageLink) {
|
||||
@ -158,6 +169,26 @@ public abstract class DaoUtil {
|
||||
} while (hasNextBatch);
|
||||
}
|
||||
|
||||
public static <T extends EntityId> void iterateWithKeyOffset(Function<PageLink, PageData<T>> findFunction, int pageSize, Consumer<List<T>> processor) {
|
||||
List<T> data;
|
||||
UUID last = null;
|
||||
while (true) {
|
||||
PageLink pageLink = PageLink.builder()
|
||||
.pageSize(pageSize)
|
||||
.sortOrder(SortOrder.of("id", SortOrder.Direction.ASC))
|
||||
.idOffset(last)
|
||||
.build();
|
||||
data = findFunction.apply(pageLink).getData();
|
||||
|
||||
if (!data.isEmpty()) {
|
||||
processor.accept(data);
|
||||
last = data.get(data.size() - 1).getId();
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static String getStringId(UUIDBased id) {
|
||||
if (id != null) {
|
||||
return id.toString();
|
||||
|
||||
@ -51,7 +51,6 @@ 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.page.TimePageLink;
|
||||
import org.thingsboard.server.common.data.query.AlarmCountQuery;
|
||||
import org.thingsboard.server.common.data.query.AlarmData;
|
||||
import org.thingsboard.server.common.data.query.AlarmDataQuery;
|
||||
@ -215,21 +214,6 @@ public class BaseAlarmService extends AbstractCachedEntityService<TenantId, Page
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int deleteAlarmsByOriginatorId(TenantId tenantId, EntityId entityId) {
|
||||
TimePageLink pageLink = new TimePageLink(256);
|
||||
PageData<AlarmId> alarms;
|
||||
int count = 0;
|
||||
do {
|
||||
alarms = alarmService.findAlarmIdsByOriginatorId(tenantId, entityId, pageLink);
|
||||
for (AlarmId alarmId : alarms.getData()) {
|
||||
delAlarm(tenantId, alarmId);
|
||||
count++;
|
||||
}
|
||||
} while (alarms.hasNext());
|
||||
return count;
|
||||
}
|
||||
|
||||
private List<EntityId> createEntityAlarmRecords(Alarm alarm) throws ExecutionException, InterruptedException {
|
||||
Set<EntityId> propagatedEntitiesSet = new LinkedHashSet<>();
|
||||
propagatedEntitiesSet.add(alarm.getOriginator());
|
||||
|
||||
@ -17,13 +17,13 @@ package org.thingsboard.server.dao.sql.alarm;
|
||||
|
||||
import org.springframework.data.domain.Page;
|
||||
import org.springframework.data.domain.Pageable;
|
||||
import org.springframework.data.domain.Slice;
|
||||
import org.springframework.data.jpa.repository.JpaRepository;
|
||||
import org.springframework.data.jpa.repository.Modifying;
|
||||
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.id.TenantId;
|
||||
import org.thingsboard.server.dao.model.sql.AlarmEntity;
|
||||
import org.thingsboard.server.dao.model.sql.AlarmInfoEntity;
|
||||
|
||||
@ -333,8 +333,13 @@ public interface AlarmRepository extends JpaRepository<AlarmEntity, UUID> {
|
||||
@Query("SELECT a.id FROM AlarmEntity a WHERE a.tenantId = :tenantId AND a.assigneeId = :assigneeId")
|
||||
Page<UUID> findAlarmIdsByAssigneeId(@Param("tenantId") UUID tenantId, @Param("assigneeId") UUID assigneeId, Pageable pageable);
|
||||
|
||||
@Query("SELECT a.id FROM AlarmEntity a WHERE a.tenantId = :tenantId AND a.originatorId = :originatorId")
|
||||
Page<UUID> findAlarmIdsByOriginatorId(@Param("tenantId") UUID tenantId, @Param("originatorId") UUID originatorId, 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<UUID> findAlarmIdsByOriginatorId(@Param("tenantId") UUID tenantId,
|
||||
@Param("originatorId") UUID originatorId,
|
||||
@Param("idOffset") UUID idOffset,
|
||||
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, " +
|
||||
|
||||
@ -298,7 +298,7 @@ public class JpaAlarmDao extends JpaAbstractDao<AlarmEntity, Alarm> implements A
|
||||
|
||||
@Override
|
||||
public PageData<AlarmId> findAlarmIdsByOriginatorId(TenantId tenantId, EntityId originatorId, PageLink pageLink) {
|
||||
return DaoUtil.pageToPageData(alarmRepository.findAlarmIdsByOriginatorId(tenantId.getId(), originatorId.getId(), DaoUtil.toPageable(pageLink)))
|
||||
return DaoUtil.pageToPageData(alarmRepository.findAlarmIdsByOriginatorId(tenantId.getId(), originatorId.getId(), pageLink.getIdOffset(), DaoUtil.toPageable(pageLink)))
|
||||
.mapData(AlarmId::new);
|
||||
}
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user