Submit cleanup tasks on DeleteEntityEvent

This commit is contained in:
ViacheslavKlimov 2024-02-07 16:12:11 +02:00
parent e5311984bb
commit 1d5b35a5aa
18 changed files with 84 additions and 38 deletions

View File

@ -0,0 +1,40 @@
/**
* 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 org.springframework.stereotype.Component;
import org.thingsboard.server.dao.alarm.AlarmService;
import org.thingsboard.server.dao.housekeeper.data.HousekeeperTask;
import org.thingsboard.server.dao.housekeeper.data.HousekeeperTaskType;
@Component
@RequiredArgsConstructor
public class EntityAlarmsDeletionTaskProcessor implements HousekeeperTaskProcessor {
private final AlarmService alarmService;
@Override
public void process(HousekeeperTask task) throws Exception {
alarmService.deleteEntityAlarmRecords(task.getTenantId(), task.getEntityId());
}
@Override
public HousekeeperTaskType getTaskType() {
return HousekeeperTaskType.DELETE_ENTITY_ALARMS;
}
}

View File

@ -106,7 +106,7 @@ public interface AlarmService extends EntityDaoService {
PageData<AlarmId> findAlarmIdsByAssigneeId(TenantId tenantId, UserId userId, PageLink pageLink);
void deleteEntityAlarmRelations(TenantId tenantId, EntityId entityId);
void deleteEntityAlarmRecords(TenantId tenantId, EntityId entityId);
void deleteEntityAlarmRecordsByTenantId(TenantId tenantId);

View File

@ -189,7 +189,6 @@ public class BaseAlarmService extends AbstractCachedEntityService<TenantId, Page
return AlarmApiCallResult.builder().successful(false).build();
} else {
var propagationIds = getPropagationEntityIdsList(alarm);
deleteEntityRelations(tenantId, alarm.getId());
alarmDao.removeById(tenantId, alarm.getUuidId());
eventPublisher.publishEvent(DeleteEntityEvent.builder().tenantId(tenantId)
.entityId(alarmId).entity(alarm).build());
@ -323,7 +322,7 @@ public class BaseAlarmService extends AbstractCachedEntityService<TenantId, Page
}
@Override
public void deleteEntityAlarmRelations(TenantId tenantId, EntityId entityId) {
public void deleteEntityAlarmRecords(TenantId tenantId, EntityId entityId) {
log.trace("Executing deleteEntityAlarms [{}]", entityId);
alarmDao.deleteEntityAlarmRecords(tenantId, entityId);
}

View File

@ -192,7 +192,6 @@ public class AssetProfileServiceImpl extends AbstractCachedEntityService<AssetPr
private void removeAssetProfile(TenantId tenantId, AssetProfile assetProfile) {
AssetProfileId assetProfileId = assetProfile.getId();
try {
deleteEntityRelations(tenantId, assetProfileId);
assetProfileDao.removeById(tenantId, assetProfileId.getId());
publishEvictEvent(new AssetProfileEvictEvent(assetProfile.getTenantId(), assetProfile.getName(),
null, assetProfile.getId(), assetProfile.isDefault()));

View File

@ -209,14 +209,11 @@ public class BaseAssetService extends AbstractCachedEntityService<AssetCacheKey,
}
Asset asset = assetDao.findById(tenantId, assetId.getId());
alarmService.deleteEntityAlarmRelations(tenantId, assetId);
deleteAsset(tenantId, asset);
}
private void deleteAsset(TenantId tenantId, Asset asset) {
log.trace("Executing deleteAsset [{}]", asset.getId());
relationService.deleteEntityRelations(tenantId, asset.getId());
assetDao.removeById(tenantId, asset.getUuidId());
publishEvictEvent(new AssetCacheEvictEvent(asset.getTenantId(), asset.getName(), null));

View File

@ -137,7 +137,6 @@ public class CustomerServiceImpl extends AbstractEntityService implements Custom
deviceService.unassignCustomerDevices(customer.getTenantId(), customerId);
edgeService.unassignCustomerEdges(customer.getTenantId(), customerId);
userService.deleteCustomerUsers(customer.getTenantId(), customerId);
deleteEntityRelations(tenantId, customerId);
apiUsageStateService.deleteApiUsageStateByEntityId(customerId);
customerDao.removeById(tenantId, customerId.getId());
countService.publishCountEntityEvictEvent(tenantId, EntityType.CUSTOMER);

View File

@ -234,7 +234,6 @@ public class DashboardServiceImpl extends AbstractEntityService implements Dashb
public void deleteDashboard(TenantId tenantId, DashboardId dashboardId) {
log.trace("Executing deleteDashboard [{}]", dashboardId);
Validator.validateId(dashboardId, INCORRECT_DASHBOARD_ID + dashboardId);
deleteEntityRelations(tenantId, dashboardId);
try {
dashboardDao.removeById(tenantId, dashboardId.getId());
publishEvictEvent(new DashboardTitleEvictEvent(dashboardId));

View File

@ -235,7 +235,6 @@ public class DeviceProfileServiceImpl extends AbstractCachedEntityService<Device
private void removeDeviceProfile(TenantId tenantId, DeviceProfile deviceProfile) {
DeviceProfileId deviceProfileId = deviceProfile.getId();
try {
deleteEntityRelations(tenantId, deviceProfileId);
deviceProfileDao.removeById(tenantId, deviceProfileId.getId());
publishEvictEvent(new DeviceProfileEvictEvent(deviceProfile.getTenantId(), deviceProfile.getName(),
null, deviceProfile.getId(), deviceProfile.isDefault(),

View File

@ -75,7 +75,6 @@ import org.thingsboard.server.dao.eventsourcing.DeleteEntityEvent;
import org.thingsboard.server.dao.eventsourcing.SaveEntityEvent;
import org.thingsboard.server.dao.exception.DataValidationException;
import org.thingsboard.server.dao.exception.IncorrectParameterException;
import org.thingsboard.server.dao.housekeeper.data.HousekeeperTask;
import org.thingsboard.server.dao.service.DataValidator;
import org.thingsboard.server.dao.service.PaginatedRemover;
@ -321,19 +320,12 @@ public class DeviceServiceImpl extends AbstractCachedEntityService<DeviceCacheKe
}
Device device = deviceDao.findById(tenantId, deviceId.getId());
alarmService.deleteEntityAlarmRelations(tenantId, deviceId);
deleteDevice(tenantId, device);
}
private void deleteDevice(TenantId tenantId, Device device) {
log.trace("Executing deleteDevice [{}]", device.getId());
deviceCredentialsService.deleteDeviceCredentialsByDeviceId(tenantId, device.getId());
relationService.deleteEntityRelations(tenantId, device.getId());
housekeeperService.submitTask(HousekeeperTask.deleteAttributes(tenantId, device.getId()));
housekeeperService.submitTask(HousekeeperTask.deleteTelemetry(tenantId, device.getId()));
housekeeperService.submitTask(HousekeeperTask.deleteEvents(tenantId, device.getId()));
// todo: extract to cleanUpRelatedData
deviceDao.removeById(tenantId, device.getUuidId());
DeviceCacheEvictEvent deviceCacheEvictEvent = new DeviceCacheEvictEvent(device.getTenantId(), device.getId(), device.getName(), null);

View File

@ -33,7 +33,6 @@ import org.thingsboard.common.util.JacksonUtil;
import org.thingsboard.server.common.data.EntitySubtype;
import org.thingsboard.server.common.data.EntityType;
import org.thingsboard.server.common.data.StringUtils;
import org.thingsboard.server.common.data.Tenant;
import org.thingsboard.server.common.data.User;
import org.thingsboard.server.common.data.audit.ActionType;
import org.thingsboard.server.common.data.edge.Edge;
@ -49,7 +48,6 @@ import org.thingsboard.server.common.data.id.TenantId;
import org.thingsboard.server.common.data.id.TenantProfileId;
import org.thingsboard.server.common.data.id.UserId;
import org.thingsboard.server.common.data.page.PageData;
import org.thingsboard.server.common.data.page.PageDataIterable;
import org.thingsboard.server.common.data.page.PageDataIterableByTenantIdEntityId;
import org.thingsboard.server.common.data.page.PageLink;
import org.thingsboard.server.common.data.relation.EntityRelation;
@ -58,6 +56,7 @@ import org.thingsboard.server.common.data.rule.RuleChain;
import org.thingsboard.server.common.data.rule.RuleNode;
import org.thingsboard.server.dao.entity.AbstractCachedEntityService;
import org.thingsboard.server.dao.eventsourcing.ActionEntityEvent;
import org.thingsboard.server.dao.eventsourcing.DeleteEntityEvent;
import org.thingsboard.server.dao.exception.DataValidationException;
import org.thingsboard.server.dao.relation.RelationService;
import org.thingsboard.server.dao.rule.RuleChainService;
@ -212,12 +211,10 @@ public class EdgeServiceImpl extends AbstractCachedEntityService<EdgeCacheKey, E
validateId(edgeId, INCORRECT_EDGE_ID + edgeId);
Edge edge = edgeDao.findById(tenantId, edgeId.getId());
deleteEntityRelations(tenantId, edgeId);
edgeDao.removeById(tenantId, edgeId.getId());
publishEvictEvent(new EdgeCacheEvictEvent(edge.getTenantId(), edge.getName(), null));
eventPublisher.publishEvent(DeleteEntityEvent.builder().tenantId(tenantId).entityId(edgeId).build());
}
@Override

View File

@ -20,6 +20,8 @@ import org.hibernate.exception.ConstraintViolationException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.context.annotation.Lazy;
import org.springframework.transaction.event.TransactionalEventListener;
import org.thingsboard.server.common.data.EntityType;
import org.thingsboard.server.common.data.EntityView;
import org.thingsboard.server.common.data.StringUtils;
import org.thingsboard.server.common.data.id.EdgeId;
@ -30,8 +32,8 @@ import org.thingsboard.server.common.data.relation.RelationTypeGroup;
import org.thingsboard.server.dao.alarm.AlarmService;
import org.thingsboard.server.dao.edge.EdgeService;
import org.thingsboard.server.dao.entityview.EntityViewService;
import org.thingsboard.server.dao.eventsourcing.DeleteEntityEvent;
import org.thingsboard.server.dao.exception.DataValidationException;
import org.thingsboard.server.dao.housekeeper.HouseKeeperService;
import org.thingsboard.server.dao.housekeeper.HousekeeperService;
import org.thingsboard.server.dao.housekeeper.data.HousekeeperTask;
import org.thingsboard.server.dao.relation.RelationService;
@ -69,6 +71,28 @@ public abstract class AbstractEntityService {
@Autowired
protected HousekeeperService housekeeperService;
@TransactionalEventListener(fallbackExecution = true) // todo: consider moving this to HousekeeperService
public void onEntityDeleted(DeleteEntityEvent<?> event) {
TenantId tenantId = event.getTenantId();
EntityId entityId = event.getEntityId();
log.trace("[{}] DeleteEntityEvent handler: {}", tenantId, event);
cleanUpRelatedData(tenantId, entityId);
if (EntityType.USER.equals(entityId.getEntityType())) {
// housekeeperService.submitTask(HousekeeperTask.unassignAlarms(tenantId, entityId));
// unassignDeletedUserAlarms(tenantId, (User) event.getEntity(), event.getTs());
}
}
protected void cleanUpRelatedData(TenantId tenantId, EntityId entityId) {
// todo: skipped entities list
relationService.deleteEntityRelations(tenantId, entityId);
housekeeperService.submitTask(HousekeeperTask.deleteAttributes(tenantId, entityId));
housekeeperService.submitTask(HousekeeperTask.deleteTelemetry(tenantId, entityId));
housekeeperService.submitTask(HousekeeperTask.deleteEvents(tenantId, entityId));
housekeeperService.submitTask(HousekeeperTask.deleteEntityAlarms(tenantId, entityId));
}
protected void createRelation(TenantId tenantId, EntityRelation relation) {
log.debug("Creating relation: {}", relation);
relationService.saveRelation(tenantId, relation);
@ -79,11 +103,6 @@ public abstract class AbstractEntityService {
relationService.deleteRelation(tenantId, relation);
}
protected void deleteEntityRelations(TenantId tenantId, EntityId entityId) {
relationService.deleteEntityRelations(tenantId, entityId);
alarmService.deleteEntityAlarmRelations(tenantId, entityId);
}
protected static Optional<ConstraintViolationException> extractConstraintViolationException(Exception t) {
if (t instanceof ConstraintViolationException) {
return Optional.of((ConstraintViolationException) t);

View File

@ -331,7 +331,6 @@ public class EntityViewServiceImpl extends AbstractCachedEntityService<EntityVie
public void deleteEntityView(TenantId tenantId, EntityViewId entityViewId) {
log.trace("Executing deleteEntityView [{}]", entityViewId);
validateId(entityViewId, INCORRECT_ENTITY_VIEW_ID + entityViewId);
deleteEntityRelations(tenantId, entityViewId);
EntityView entityView = entityViewDao.findById(tenantId, entityViewId.getId());
entityViewDao.removeById(tenantId, entityViewId.getId());
publishEvictEvent(new EntityViewEvictEvent(entityView.getTenantId(), entityView.getId(), entityView.getEntityId(), null, entityView.getName(), null));

View File

@ -18,6 +18,7 @@ package org.thingsboard.server.dao.housekeeper.data;
import lombok.Data;
import org.thingsboard.server.common.data.id.EntityId;
import org.thingsboard.server.common.data.id.TenantId;
import org.thingsboard.server.common.data.id.UserId;
import java.io.Serializable;
@ -48,4 +49,12 @@ public class HousekeeperTask implements Serializable {
return new HousekeeperTask(tenantId, entityId, HousekeeperTaskType.DELETE_EVENTS);
}
public static HousekeeperTask unassignAlarms(TenantId tenantId, UserId userId) {
return new HousekeeperTask(tenantId, userId, HousekeeperTaskType.UNASSIGN_ALARMS);
}
public static HousekeeperTask deleteEntityAlarms(TenantId tenantId, EntityId entityId) {
return new HousekeeperTask(tenantId, entityId, HousekeeperTaskType.DELETE_ENTITY_ALARMS);
}
}

View File

@ -19,5 +19,7 @@ public enum HousekeeperTaskType {
DELETE_ENTITY,
DELETE_ATTRIBUTES,
DELETE_TELEMETRY, // maybe divide into latest and ts kv history?
DELETE_EVENTS
DELETE_EVENTS,
UNASSIGN_ALARMS,
DELETE_ENTITY_ALARMS
}

View File

@ -177,7 +177,7 @@ public class BaseRuleChainService extends AbstractEntityService implements RuleC
List<RuleNodeUpdateResult> updatedRuleNodes = new ArrayList<>();
List<RuleNode> existingRuleNodes = getRuleChainNodes(tenantId, ruleChainMetaData.getRuleChainId());
for (RuleNode existingNode : existingRuleNodes) {
deleteEntityRelations(tenantId, existingNode.getId());
cleanUpRelatedData(tenantId, existingNode.getId()); // fixme: for sure?
Integer index = ruleNodeIndexMap.get(existingNode.getId());
RuleNode newRuleNode = null;
if (index != null) {
@ -771,7 +771,7 @@ public class BaseRuleChainService extends AbstractEntityService implements RuleC
private void deleteRuleNodes(TenantId tenantId, List<RuleNode> ruleNodes) {
List<RuleNodeId> ruleNodeIds = ruleNodes.stream().map(RuleNode::getId).collect(Collectors.toList());
for (var node : ruleNodes) {
deleteEntityRelations(tenantId, node.getId());
cleanUpRelatedData(tenantId, node.getId());
}
ruleNodeDao.deleteByIdIn(ruleNodeIds);
}
@ -783,7 +783,6 @@ public class BaseRuleChainService extends AbstractEntityService implements RuleC
for (EntityRelation relation : nodeRelations) {
deleteRuleNode(tenantId, relation.getTo());
}
deleteEntityRelations(tenantId, ruleChainId);
}
@ -820,8 +819,8 @@ public class BaseRuleChainService extends AbstractEntityService implements RuleC
}
private void deleteRuleNode(TenantId tenantId, EntityId entityId) {
deleteEntityRelations(tenantId, entityId);
ruleNodeDao.removeById(tenantId, entityId.getId());
cleanUpRelatedData(tenantId, entityId);
}
private final PaginatedRemover<TenantId, RuleChain> tenantRuleChainsRemover =

View File

@ -130,7 +130,6 @@ public class TenantProfileServiceImpl extends AbstractCachedEntityService<Tenant
throw t;
}
}
deleteEntityRelations(tenantId, tenantProfileId);
publishEvictEvent(new TenantProfileEvictEvent(tenantProfileId, isDefault));
eventPublisher.publishEvent(DeleteEntityEvent.builder().tenantId(tenantId).entityId(tenantProfileId).build());
}

View File

@ -245,7 +245,6 @@ public class TenantServiceImpl extends AbstractCachedEntityService<TenantId, Ten
tenantDao.removeById(tenantId, tenantId.getId());
publishEvictEvent(new TenantEvictEvent(tenantId, true));
eventPublisher.publishEvent(DeleteEntityEvent.builder().tenantId(tenantId).entityId(tenantId).build());
relationService.deleteEntityRelations(tenantId, tenantId);
alarmService.deleteEntityAlarmRecordsByTenantId(tenantId);
}

View File

@ -255,7 +255,6 @@ public class UserServiceImpl extends AbstractEntityService implements UserServic
validateId(userId, INCORRECT_USER_ID + userId);
userCredentialsDao.removeByUserId(tenantId, userId);
userAuthSettingsDao.removeByUserId(userId);
deleteEntityRelations(tenantId, userId);
userDao.removeById(tenantId, userId.getId());
eventPublisher.publishEvent(new UserCredentialsInvalidationEvent(userId));