Refactor alarms deletion; separate tenant entities deletion task
This commit is contained in:
parent
07d144fb08
commit
3803081b57
@ -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.AlarmId;
|
||||||
import org.thingsboard.server.common.data.id.EntityId;
|
import org.thingsboard.server.common.data.id.EntityId;
|
||||||
import org.thingsboard.server.common.data.id.TenantId;
|
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 org.thingsboard.server.dao.alarm.AlarmService;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
import java.util.stream.Collectors;
|
|
||||||
|
|
||||||
@Component
|
@Component
|
||||||
@RequiredArgsConstructor
|
@RequiredArgsConstructor
|
||||||
@ -46,16 +45,19 @@ public class AlarmsDeletionTaskProcessor extends HousekeeperTaskProcessor<Alarms
|
|||||||
|
|
||||||
if (entityType == EntityType.DEVICE || entityType == EntityType.ASSET) {
|
if (entityType == EntityType.DEVICE || entityType == EntityType.ASSET) {
|
||||||
if (task.getAlarms() == null) {
|
if (task.getAlarms() == null) {
|
||||||
AlarmId last = null;
|
AlarmId lastId = null;
|
||||||
|
long lastCreatedTime = 0;
|
||||||
while (true) {
|
while (true) {
|
||||||
List<AlarmId> alarms = alarmService.findAlarmIdsByOriginatorIdAndIdOffset(tenantId, entityId, last, 128);
|
List<TbPair<UUID, Long>> alarms = alarmService.findAlarmIdsByOriginatorId(tenantId, entityId, lastCreatedTime, lastId, 128);
|
||||||
if (alarms.isEmpty()) {
|
if (alarms.isEmpty()) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
housekeeperClient.submitTask(new AlarmsDeletionHousekeeperTask(tenantId, entityId, alarms.stream()
|
housekeeperClient.submitTask(new AlarmsDeletionHousekeeperTask(tenantId, entityId, alarms.stream().map(TbPair::getFirst).toList()));
|
||||||
.map(UUIDBased::getId).collect(Collectors.toList())));
|
|
||||||
last = alarms.get(alarms.size() - 1);
|
TbPair<UUID, Long> 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());
|
log.debug("[{}][{}][{}] Submitted task for deleting {} alarms", tenantId, entityType, entityId, alarms.size());
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@ -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.EntityId;
|
||||||
import org.thingsboard.server.common.data.id.EntityIdFactory;
|
import org.thingsboard.server.common.data.id.EntityIdFactory;
|
||||||
import org.thingsboard.server.common.data.id.TenantId;
|
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.EntityDaoService;
|
||||||
import org.thingsboard.server.dao.entity.EntityServiceRegistry;
|
import org.thingsboard.server.dao.entity.EntityServiceRegistry;
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
|
||||||
@Component
|
@Component
|
||||||
@ -37,35 +34,19 @@ import java.util.UUID;
|
|||||||
@Slf4j
|
@Slf4j
|
||||||
public class EntitiesDeletionTaskProcessor extends HousekeeperTaskProcessor<EntitiesDeletionHousekeeperTask> {
|
public class EntitiesDeletionTaskProcessor extends HousekeeperTaskProcessor<EntitiesDeletionHousekeeperTask> {
|
||||||
|
|
||||||
private final EntityDaoRegistry entityDaoRegistry;
|
|
||||||
private final EntityServiceRegistry entityServiceRegistry;
|
private final EntityServiceRegistry entityServiceRegistry;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void process(EntitiesDeletionHousekeeperTask task) throws Exception {
|
public void process(EntitiesDeletionHousekeeperTask task) throws Exception {
|
||||||
EntityType entityType = task.getEntityType();
|
EntityType entityType = task.getEntityType();
|
||||||
TenantId tenantId = task.getTenantId();
|
TenantId tenantId = task.getTenantId();
|
||||||
Dao<?> entityDao = entityDaoRegistry.getDao(entityType);
|
|
||||||
EntityDaoService entityService = entityServiceRegistry.getServiceByEntityType(entityType);
|
EntityDaoService entityService = entityServiceRegistry.getServiceByEntityType(entityType);
|
||||||
|
|
||||||
if (task.getEntities() == null) {
|
for (UUID entityUuid : task.getEntities()) {
|
||||||
UUID last = null;
|
EntityId entityId = EntityIdFactory.getByTypeAndUuid(entityType, entityUuid);
|
||||||
while (true) {
|
entityService.deleteEntity(tenantId, entityId, true);
|
||||||
List<UUID> 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());
|
|
||||||
}
|
}
|
||||||
|
log.debug("[{}] Deleted {} {}s", tenantId, task.getEntities().size(), entityType.getNormalName().toLowerCase());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@ -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<TenantEntitiesDeletionHousekeeperTask> {
|
||||||
|
|
||||||
|
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<UUID> 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;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@ -360,7 +360,7 @@ public class HousekeeperServiceTest extends AbstractControllerTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void verifyNoAlarms(EntityId entityId) {
|
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 {
|
private void createAttribute(EntityId entityId, AttributeScope scope, String key) throws Exception {
|
||||||
@ -402,7 +402,7 @@ public class HousekeeperServiceTest extends AbstractControllerTest {
|
|||||||
List<EntityAlarm> entityAlarms = alarmDao.findEntityAlarmRecords(tenantId, alarm.getId());
|
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(deviceId) && entityAlarm.getAlarmType().equals(alarm.getType()));
|
||||||
assertThat(entityAlarms).anyMatch(entityAlarm -> entityAlarm.getEntityId().equals(propagatedEntityId) && 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) {
|
private void createAlarm(DeviceId deviceId) {
|
||||||
@ -412,7 +412,7 @@ public class HousekeeperServiceTest extends AbstractControllerTest {
|
|||||||
.severity(AlarmSeverity.CRITICAL)
|
.severity(AlarmSeverity.CRITICAL)
|
||||||
.type("test alarm for " + deviceId + " " + RandomStringUtils.randomAlphabetic(10))
|
.type("test alarm for " + deviceId + " " + RandomStringUtils.randomAlphabetic(10))
|
||||||
.build(), Alarm.class);
|
.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 {
|
private TsKvEntry getLatestTelemetry(EntityId entityId) throws Exception {
|
||||||
|
|||||||
@ -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.AlarmCountQuery;
|
||||||
import org.thingsboard.server.common.data.query.AlarmData;
|
import org.thingsboard.server.common.data.query.AlarmData;
|
||||||
import org.thingsboard.server.common.data.query.AlarmDataQuery;
|
import org.thingsboard.server.common.data.query.AlarmDataQuery;
|
||||||
|
import org.thingsboard.server.common.data.util.TbPair;
|
||||||
import org.thingsboard.server.dao.entity.EntityDaoService;
|
import org.thingsboard.server.dao.entity.EntityDaoService;
|
||||||
|
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
|
||||||
public interface AlarmService extends EntityDaoService {
|
public interface AlarmService extends EntityDaoService {
|
||||||
@ -107,7 +109,7 @@ public interface AlarmService extends EntityDaoService {
|
|||||||
|
|
||||||
PageData<AlarmId> findAlarmIdsByAssigneeId(TenantId tenantId, UserId userId, PageLink pageLink);
|
PageData<AlarmId> findAlarmIdsByAssigneeId(TenantId tenantId, UserId userId, PageLink pageLink);
|
||||||
|
|
||||||
List<AlarmId> findAlarmIdsByOriginatorIdAndIdOffset(TenantId tenantId, EntityId originatorId, AlarmId idOffset, int limit);
|
List<TbPair<UUID, Long>> findAlarmIdsByOriginatorId(TenantId tenantId, EntityId originatorId, long createdTimeOffset, AlarmId idOffset, int limit);
|
||||||
|
|
||||||
int deleteEntityAlarmRecords(TenantId tenantId, EntityId entityId);
|
int deleteEntityAlarmRecords(TenantId tenantId, EntityId entityId);
|
||||||
|
|
||||||
|
|||||||
@ -16,7 +16,6 @@
|
|||||||
package org.thingsboard.server.common.data.housekeeper;
|
package org.thingsboard.server.common.data.housekeeper;
|
||||||
|
|
||||||
import com.fasterxml.jackson.annotation.JsonIgnore;
|
import com.fasterxml.jackson.annotation.JsonIgnore;
|
||||||
import lombok.AccessLevel;
|
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
import lombok.EqualsAndHashCode;
|
import lombok.EqualsAndHashCode;
|
||||||
import lombok.NoArgsConstructor;
|
import lombok.NoArgsConstructor;
|
||||||
@ -30,16 +29,12 @@ import java.util.UUID;
|
|||||||
@Data
|
@Data
|
||||||
@ToString(callSuper = true)
|
@ToString(callSuper = true)
|
||||||
@EqualsAndHashCode(callSuper = true)
|
@EqualsAndHashCode(callSuper = true)
|
||||||
@NoArgsConstructor(access = AccessLevel.PROTECTED)
|
@NoArgsConstructor
|
||||||
public class EntitiesDeletionHousekeeperTask extends HousekeeperTask {
|
public class EntitiesDeletionHousekeeperTask extends HousekeeperTask {
|
||||||
|
|
||||||
private EntityType entityType;
|
private EntityType entityType;
|
||||||
private List<UUID> entities;
|
private List<UUID> entities;
|
||||||
|
|
||||||
protected EntitiesDeletionHousekeeperTask(TenantId tenantId, EntityType entityType) {
|
|
||||||
this(tenantId, entityType, null);
|
|
||||||
}
|
|
||||||
|
|
||||||
public EntitiesDeletionHousekeeperTask(TenantId tenantId, EntityType entityType, List<UUID> entities) {
|
public EntitiesDeletionHousekeeperTask(TenantId tenantId, EntityType entityType, List<UUID> entities) {
|
||||||
super(tenantId, tenantId, HousekeeperTaskType.DELETE_ENTITIES);
|
super(tenantId, tenantId, HousekeeperTaskType.DELETE_ENTITIES);
|
||||||
this.entityType = entityType;
|
this.entityType = entityType;
|
||||||
@ -49,7 +44,7 @@ public class EntitiesDeletionHousekeeperTask extends HousekeeperTask {
|
|||||||
@JsonIgnore
|
@JsonIgnore
|
||||||
@Override
|
@Override
|
||||||
public String getDescription() {
|
public String getDescription() {
|
||||||
return entityType.getNormalName().toLowerCase() + "s deletion" + (entities != null ? " (" + entities + ")" : "");
|
return entityType.getNormalName().toLowerCase() + "s deletion (" + entities + ")";
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -36,6 +36,7 @@ import java.io.Serializable;
|
|||||||
@JsonSubTypes({
|
@JsonSubTypes({
|
||||||
@Type(name = "DELETE_TS_HISTORY", value = TsHistoryDeletionHousekeeperTask.class),
|
@Type(name = "DELETE_TS_HISTORY", value = TsHistoryDeletionHousekeeperTask.class),
|
||||||
@Type(name = "DELETE_LATEST_TS", value = LatestTsDeletionHousekeeperTask.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_ENTITIES", value = EntitiesDeletionHousekeeperTask.class),
|
||||||
@Type(name = "DELETE_ALARMS", value = AlarmsDeletionHousekeeperTask.class),
|
@Type(name = "DELETE_ALARMS", value = AlarmsDeletionHousekeeperTask.class),
|
||||||
@Type(name = "UNASSIGN_ALARMS", value = AlarmsUnassignHousekeeperTask.class)
|
@Type(name = "UNASSIGN_ALARMS", value = AlarmsUnassignHousekeeperTask.class)
|
||||||
@ -76,8 +77,8 @@ public class HousekeeperTask implements Serializable {
|
|||||||
return new AlarmsDeletionHousekeeperTask(tenantId, entityId);
|
return new AlarmsDeletionHousekeeperTask(tenantId, entityId);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static HousekeeperTask deleteEntities(TenantId tenantId, EntityType entityType) {
|
public static HousekeeperTask deleteTenantEntities(TenantId tenantId, EntityType entityType) {
|
||||||
return new EntitiesDeletionHousekeeperTask(tenantId, entityType);
|
return new TenantEntitiesDeletionHousekeeperTask(tenantId, entityType);
|
||||||
}
|
}
|
||||||
|
|
||||||
@JsonIgnore
|
@JsonIgnore
|
||||||
|
|||||||
@ -22,14 +22,15 @@ import lombok.RequiredArgsConstructor;
|
|||||||
@Getter
|
@Getter
|
||||||
public enum HousekeeperTaskType {
|
public enum HousekeeperTaskType {
|
||||||
|
|
||||||
DELETE_ENTITIES("entities deletion"),
|
|
||||||
DELETE_ATTRIBUTES("attributes deletion"),
|
DELETE_ATTRIBUTES("attributes deletion"),
|
||||||
DELETE_TELEMETRY("telemetry deletion"),
|
DELETE_TELEMETRY("telemetry deletion"),
|
||||||
DELETE_LATEST_TS("latest telemetry deletion"),
|
DELETE_LATEST_TS("latest telemetry deletion"),
|
||||||
DELETE_TS_HISTORY("timeseries history deletion"),
|
DELETE_TS_HISTORY("timeseries history deletion"),
|
||||||
DELETE_EVENTS("events deletion"),
|
DELETE_EVENTS("events deletion"),
|
||||||
DELETE_ALARMS("alarms 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;
|
private final String description;
|
||||||
|
|
||||||
|
|||||||
@ -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";
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@ -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.AlarmCountQuery;
|
||||||
import org.thingsboard.server.common.data.query.AlarmData;
|
import org.thingsboard.server.common.data.query.AlarmData;
|
||||||
import org.thingsboard.server.common.data.query.AlarmDataQuery;
|
import org.thingsboard.server.common.data.query.AlarmDataQuery;
|
||||||
|
import org.thingsboard.server.common.data.util.TbPair;
|
||||||
import org.thingsboard.server.dao.Dao;
|
import org.thingsboard.server.dao.Dao;
|
||||||
|
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
@ -80,7 +81,7 @@ public interface AlarmDao extends Dao<Alarm> {
|
|||||||
|
|
||||||
PageData<AlarmId> findAlarmIdsByAssigneeId(TenantId tenantId, UUID userId, PageLink pageLink);
|
PageData<AlarmId> findAlarmIdsByAssigneeId(TenantId tenantId, UUID userId, PageLink pageLink);
|
||||||
|
|
||||||
PageData<AlarmId> findAlarmIdsByOriginatorId(TenantId tenantId, EntityId originatorId, AlarmId idOffset, PageLink pageLink);
|
PageData<TbPair<UUID, Long>> findAlarmIdsByOriginatorId(TenantId tenantId, EntityId originatorId, long createdTimeOffset, AlarmId idOffset, int limit);
|
||||||
|
|
||||||
void createEntityAlarmRecord(EntityAlarm entityAlarm);
|
void createEntityAlarmRecord(EntityAlarm entityAlarm);
|
||||||
|
|
||||||
|
|||||||
@ -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.EntityRelationsQuery;
|
||||||
import org.thingsboard.server.common.data.relation.EntitySearchDirection;
|
import org.thingsboard.server.common.data.relation.EntitySearchDirection;
|
||||||
import org.thingsboard.server.common.data.relation.RelationsSearchParameters;
|
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.AbstractCachedEntityService;
|
||||||
import org.thingsboard.server.dao.entity.EntityService;
|
import org.thingsboard.server.dao.entity.EntityService;
|
||||||
import org.thingsboard.server.dao.eventsourcing.ActionEntityEvent;
|
import org.thingsboard.server.dao.eventsourcing.ActionEntityEvent;
|
||||||
@ -75,6 +76,7 @@ import java.util.LinkedHashSet;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
import java.util.UUID;
|
||||||
import java.util.concurrent.ExecutionException;
|
import java.util.concurrent.ExecutionException;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
import java.util.stream.Stream;
|
import java.util.stream.Stream;
|
||||||
@ -313,9 +315,9 @@ public class BaseAlarmService extends AbstractCachedEntityService<TenantId, Page
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<AlarmId> findAlarmIdsByOriginatorIdAndIdOffset(TenantId tenantId, EntityId originatorId, AlarmId idOffset, int limit) {
|
public List<TbPair<UUID, Long>> findAlarmIdsByOriginatorId(TenantId tenantId, EntityId originatorId, long createdTimeOffset, AlarmId idOffset, int limit) {
|
||||||
log.trace("[{}] Executing findAlarmIdsByOriginatorIdAndIdOffset [{}][{}]", tenantId, originatorId, idOffset);
|
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
|
@Override
|
||||||
|
|||||||
@ -77,7 +77,7 @@ public class CleanUpService {
|
|||||||
|
|
||||||
public void removeTenantEntities(TenantId tenantId, EntityType... entityTypes) {
|
public void removeTenantEntities(TenantId tenantId, EntityType... entityTypes) {
|
||||||
for (EntityType entityType : entityTypes) {
|
for (EntityType entityType : entityTypes) {
|
||||||
housekeeperClient.submitTask(HousekeeperTask.deleteEntities(tenantId, entityType));
|
housekeeperClient.submitTask(HousekeeperTask.deleteTenantEntities(tenantId, entityType));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -24,6 +24,7 @@ import org.springframework.data.jpa.repository.Query;
|
|||||||
import org.springframework.data.repository.query.Param;
|
import org.springframework.data.repository.query.Param;
|
||||||
import org.springframework.transaction.annotation.Transactional;
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
import org.thingsboard.server.common.data.alarm.AlarmSeverity;
|
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.AlarmEntity;
|
||||||
import org.thingsboard.server.dao.model.sql.AlarmInfoEntity;
|
import org.thingsboard.server.dao.model.sql.AlarmInfoEntity;
|
||||||
|
|
||||||
@ -334,12 +335,20 @@ public interface AlarmRepository extends JpaRepository<AlarmEntity, UUID> {
|
|||||||
Page<UUID> findAlarmIdsByAssigneeId(@Param("tenantId") UUID tenantId, @Param("assigneeId") UUID assigneeId, Pageable pageable);
|
Page<UUID> findAlarmIdsByAssigneeId(@Param("tenantId") UUID tenantId, @Param("assigneeId") UUID assigneeId, Pageable pageable);
|
||||||
|
|
||||||
// using Slice so that count query is not executed
|
// using Slice so that count query is not executed
|
||||||
@Query(value = "SELECT id FROM alarm WHERE tenant_id = :tenantId AND originator_id = :originatorId " +
|
@Query("SELECT new org.thingsboard.server.common.data.util.TbPair(a.id, a.createdTime) " +
|
||||||
"AND (cast(:idOffset as uuid) IS NULL OR id > cast(:idOffset as uuid))", nativeQuery = true)
|
"FROM AlarmEntity a WHERE a.originatorId = :originatorId " +
|
||||||
Slice<UUID> findAlarmIdsByOriginatorId(@Param("tenantId") UUID tenantId,
|
"AND (a.createdTime > :createdTimeOffset OR " +
|
||||||
@Param("originatorId") UUID originatorId,
|
"(a.createdTime = :createdTimeOffset AND a.id > :idOffset))")
|
||||||
@Param("idOffset") UUID idOffset,
|
Slice<TbPair<UUID, Long>> findAlarmIdsByOriginatorId(@Param("originatorId") UUID originatorId,
|
||||||
Pageable pageable);
|
@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<TbPair<UUID, Long>> 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, " +
|
@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, " +
|
":a_start_ts, :a_end_ts, :a_details, :a_propagate, :a_propagate_to_owner, " +
|
||||||
|
|||||||
@ -21,6 +21,8 @@ import lombok.extern.slf4j.Slf4j;
|
|||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.data.domain.Page;
|
import org.springframework.data.domain.Page;
|
||||||
import org.springframework.data.domain.PageRequest;
|
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.data.jpa.repository.JpaRepository;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
import org.springframework.util.CollectionUtils;
|
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.id.UserId;
|
||||||
import org.thingsboard.server.common.data.page.PageData;
|
import org.thingsboard.server.common.data.page.PageData;
|
||||||
import org.thingsboard.server.common.data.page.PageLink;
|
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.AlarmCountQuery;
|
||||||
import org.thingsboard.server.common.data.query.AlarmData;
|
import org.thingsboard.server.common.data.query.AlarmData;
|
||||||
import org.thingsboard.server.common.data.query.AlarmDataQuery;
|
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.DaoUtil;
|
||||||
import org.thingsboard.server.dao.alarm.AlarmDao;
|
import org.thingsboard.server.dao.alarm.AlarmDao;
|
||||||
import org.thingsboard.server.dao.model.ModelConstants;
|
import org.thingsboard.server.dao.model.ModelConstants;
|
||||||
@ -69,6 +73,7 @@ import java.util.Optional;
|
|||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.UUID;
|
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.convertTenantEntityTypesToDto;
|
||||||
import static org.thingsboard.server.dao.DaoUtil.toPageable;
|
import static org.thingsboard.server.dao.DaoUtil.toPageable;
|
||||||
|
|
||||||
@ -297,9 +302,15 @@ public class JpaAlarmDao extends JpaAbstractDao<AlarmEntity, Alarm> implements A
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public PageData<AlarmId> findAlarmIdsByOriginatorId(TenantId tenantId, EntityId originatorId, AlarmId idOffset, PageLink pageLink) {
|
public PageData<TbPair<UUID, Long>> findAlarmIdsByOriginatorId(TenantId tenantId, EntityId originatorId, long createdTimeOffset, AlarmId idOffset, int limit) {
|
||||||
return DaoUtil.pageToPageData(alarmRepository.findAlarmIdsByOriginatorId(tenantId.getId(), originatorId.getId(), idOffset != null ? idOffset.getId() : null, DaoUtil.toPageable(pageLink)))
|
Slice<TbPair<UUID, Long>> result;
|
||||||
.mapData(AlarmId::new);
|
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
|
@Override
|
||||||
|
|||||||
@ -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.device.profile.DeviceProfileData;
|
||||||
import org.thingsboard.server.common.data.edge.Edge;
|
import org.thingsboard.server.common.data.edge.Edge;
|
||||||
import org.thingsboard.server.common.data.event.RuleNodeDebugEvent;
|
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.housekeeper.HousekeeperTaskType;
|
||||||
import org.thingsboard.server.common.data.id.DeviceProfileId;
|
import org.thingsboard.server.common.data.id.DeviceProfileId;
|
||||||
import org.thingsboard.server.common.data.id.EntityId;
|
import org.thingsboard.server.common.data.id.EntityId;
|
||||||
@ -142,8 +142,8 @@ public abstract class AbstractServiceTest {
|
|||||||
@Bean
|
@Bean
|
||||||
public HousekeeperClient housekeeperClient() {
|
public HousekeeperClient housekeeperClient() {
|
||||||
return task -> {
|
return task -> {
|
||||||
if (task.getTaskType() == HousekeeperTaskType.DELETE_ENTITIES) {
|
if (task.getTaskType() == HousekeeperTaskType.DELETE_TENANT_ENTITIES) {
|
||||||
EntityDaoService entityService = entityServiceRegistry.getServiceByEntityType(((EntitiesDeletionHousekeeperTask) task).getEntityType());
|
EntityDaoService entityService = entityServiceRegistry.getServiceByEntityType(((TenantEntitiesDeletionHousekeeperTask) task).getEntityType());
|
||||||
entityService.deleteByTenantId(task.getTenantId());
|
entityService.deleteByTenantId(task.getTenantId());
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user