Tenant deletion with housekeeper
This commit is contained in:
parent
a1bede3cbb
commit
faa93de102
@ -128,8 +128,13 @@ public class DefaultHousekeeperService implements HousekeeperService {
|
||||
|
||||
@Override
|
||||
public void submitTask(HousekeeperTask task) {
|
||||
submitTask(UUID.randomUUID(), task);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void submitTask(UUID key, HousekeeperTask task) {
|
||||
TopicPartitionInfo tpi = TopicPartitionInfo.builder().topic(producer.getDefaultTopic()).build();
|
||||
producer.send(tpi, new TbProtoQueueMsg<>(UUID.randomUUID(), ToHousekeeperServiceMsg.newBuilder()
|
||||
producer.send(tpi, new TbProtoQueueMsg<>(key, ToHousekeeperServiceMsg.newBuilder()
|
||||
.setTask(HousekeeperTaskProto.newBuilder()
|
||||
.setValue(ByteString.copyFrom(dataDecodingEncodingService.encode(task)))
|
||||
.setTs(task.getTs())
|
||||
|
||||
@ -49,7 +49,7 @@ public class HousekeeperReprocessingService {
|
||||
@Value("${queue.core.housekeeper.poll-interval-ms:10000}")
|
||||
private int pollInterval;
|
||||
|
||||
private final long startTs = System.currentTimeMillis();
|
||||
private final long startTs = System.currentTimeMillis(); // fixme: some other tb-core might start earlier and submit for reprocessing
|
||||
private boolean stopped;
|
||||
// todo: stats
|
||||
|
||||
@ -114,12 +114,13 @@ public class HousekeeperReprocessingService {
|
||||
msg = msg.toBuilder()
|
||||
.setTask(task.toBuilder()
|
||||
.setAttempt(attempt)
|
||||
.setTs(System.currentTimeMillis())
|
||||
.setTs(System.currentTimeMillis()) // maybe set ts + 1 hour so that no-one reprocesses it immediately
|
||||
.build())
|
||||
.build();
|
||||
|
||||
var producer = producerProvider.getHousekeeperDelayedMsgProducer();
|
||||
TopicPartitionInfo tpi = TopicPartitionInfo.builder().topic(producer.getDefaultTopic()).build();
|
||||
// fixme submit with the same msg key, so that the messages goes to this consumer and will not be processed by anyone else
|
||||
producer.send(tpi, new TbProtoQueueMsg<>(UUID.randomUUID(), msg), null);
|
||||
}
|
||||
|
||||
|
||||
@ -17,21 +17,29 @@ package org.thingsboard.server.service.housekeeper.processor;
|
||||
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.thingsboard.server.dao.housekeeper.data.HousekeeperTask;
|
||||
import org.thingsboard.server.dao.entity.EntityDaoService;
|
||||
import org.thingsboard.server.dao.entity.EntityServiceRegistry;
|
||||
import org.thingsboard.server.dao.housekeeper.data.EntitiesDeletionHousekeeperTask;
|
||||
import org.thingsboard.server.dao.housekeeper.data.HousekeeperTaskType;
|
||||
|
||||
@Component
|
||||
@RequiredArgsConstructor
|
||||
public class EntityDeletionTaskProcessor implements HousekeeperTaskProcessor<HousekeeperTask> {
|
||||
public class EntitiesDeletionTaskProcessor implements HousekeeperTaskProcessor<EntitiesDeletionHousekeeperTask> {
|
||||
|
||||
private final EntityServiceRegistry entityServiceRegistry;
|
||||
|
||||
@Override
|
||||
public void process(HousekeeperTask task) throws Exception {
|
||||
|
||||
public void process(EntitiesDeletionHousekeeperTask task) throws Exception {
|
||||
EntityDaoService entityService = entityServiceRegistry.getServiceByEntityType(task.getEntityType());
|
||||
if (entityService == null) {
|
||||
throw new IllegalArgumentException("Unsupported entity type " + task.getEntityType());
|
||||
}
|
||||
entityService.deleteByTenantId(task.getTenantId());
|
||||
}
|
||||
|
||||
@Override
|
||||
public HousekeeperTaskType getTaskType() {
|
||||
return HousekeeperTaskType.DELETE_ENTITY;
|
||||
return HousekeeperTaskType.DELETE_ENTITIES;
|
||||
}
|
||||
|
||||
}
|
||||
@ -34,6 +34,10 @@ public interface EntityDaoService {
|
||||
throw new IllegalArgumentException(getEntityType().getNormalName() + " deletion not supported");
|
||||
}
|
||||
|
||||
default void deleteByTenantId(TenantId tenantId) {
|
||||
throw new IllegalArgumentException("Deletion by tenant id not supported for " + getEntityType().getNormalName());
|
||||
}
|
||||
|
||||
EntityType getEntityType();
|
||||
|
||||
}
|
||||
|
||||
@ -58,7 +58,8 @@ public enum EntityType {
|
||||
NOTIFICATION_TEMPLATE (30),
|
||||
NOTIFICATION_REQUEST (31),
|
||||
NOTIFICATION (32),
|
||||
NOTIFICATION_RULE (33);
|
||||
NOTIFICATION_RULE (33),
|
||||
ADMIN_SETTINGS(34);
|
||||
|
||||
@Getter
|
||||
private final int protoNumber; // Corresponds to EntityTypeProto
|
||||
|
||||
@ -304,6 +304,11 @@ public class AssetProfileServiceImpl extends AbstractCachedEntityService<AssetPr
|
||||
tenantAssetProfilesRemover.removeEntities(tenantId, tenantId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void deleteByTenantId(TenantId tenantId) {
|
||||
deleteAssetProfilesByTenantId(tenantId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Optional<HasId<?>> findEntity(TenantId tenantId, EntityId entityId) {
|
||||
return Optional.ofNullable(findAssetProfileById(tenantId, new AssetProfileId(entityId.getId())));
|
||||
|
||||
@ -279,6 +279,11 @@ public class BaseAssetService extends AbstractCachedEntityService<AssetCacheKey,
|
||||
tenantAssetsRemover.removeEntities(tenantId, tenantId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void deleteByTenantId(TenantId tenantId) {
|
||||
deleteAssetsByTenantId(tenantId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public PageData<Asset> findAssetsByTenantIdAndCustomerId(TenantId tenantId, CustomerId customerId, PageLink pageLink) {
|
||||
log.trace("Executing findAssetsByTenantIdAndCustomerId, tenantId [{}], customerId [{}], pageLink [{}]", tenantId, customerId, pageLink);
|
||||
|
||||
@ -180,6 +180,11 @@ public class CustomerServiceImpl extends AbstractEntityService implements Custom
|
||||
customersByTenantRemover.removeEntities(tenantId, tenantId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void deleteByTenantId(TenantId tenantId) {
|
||||
deleteCustomersByTenantId(tenantId);
|
||||
}
|
||||
|
||||
private PaginatedRemover<TenantId, Customer> customersByTenantRemover =
|
||||
new PaginatedRemover<TenantId, Customer>() {
|
||||
|
||||
|
||||
@ -272,6 +272,11 @@ public class DashboardServiceImpl extends AbstractEntityService implements Dashb
|
||||
tenantDashboardsRemover.removeEntities(tenantId, tenantId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void deleteByTenantId(TenantId tenantId) {
|
||||
deleteDashboardsByTenantId(tenantId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public PageData<DashboardInfo> findDashboardsByTenantIdAndCustomerId(TenantId tenantId, CustomerId customerId, PageLink pageLink) {
|
||||
log.trace("Executing findDashboardsByTenantIdAndCustomerId, tenantId [{}], customerId [{}], pageLink [{}]", tenantId, customerId, pageLink);
|
||||
|
||||
@ -359,6 +359,11 @@ public class DeviceProfileServiceImpl extends AbstractCachedEntityService<Device
|
||||
tenantDeviceProfilesRemover.removeEntities(tenantId, tenantId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void deleteByTenantId(TenantId tenantId) {
|
||||
deleteDeviceProfilesByTenantId(tenantId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Optional<HasId<?>> findEntity(TenantId tenantId, EntityId entityId) {
|
||||
return Optional.ofNullable(findDeviceProfileById(tenantId, new DeviceProfileId(entityId.getId())));
|
||||
|
||||
@ -422,6 +422,12 @@ public class DeviceServiceImpl extends AbstractCachedEntityService<DeviceCacheKe
|
||||
tenantDevicesRemover.removeEntities(tenantId, tenantId);
|
||||
}
|
||||
|
||||
@Transactional
|
||||
@Override
|
||||
public void deleteByTenantId(TenantId tenantId) {
|
||||
deleteDevicesByTenantId(tenantId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public PageData<Device> findDevicesByTenantIdAndCustomerId(TenantId tenantId, CustomerId customerId, PageLink pageLink) {
|
||||
log.trace("Executing findDevicesByTenantIdAndCustomerId, tenantId [{}], customerId [{}], pageLink [{}]", tenantId, customerId, pageLink);
|
||||
|
||||
@ -266,6 +266,11 @@ public class EdgeServiceImpl extends AbstractCachedEntityService<EdgeCacheKey, E
|
||||
tenantEdgesRemover.removeEntities(tenantId, tenantId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void deleteByTenantId(TenantId tenantId) {
|
||||
deleteEdgesByTenantId(tenantId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public PageData<Edge> findEdgesByTenantIdAndCustomerId(TenantId tenantId, CustomerId customerId, PageLink pageLink) {
|
||||
log.trace("Executing findEdgesByTenantIdAndCustomerId, tenantId [{}], customerId [{}], pageLink [{}]", tenantId, customerId, pageLink);
|
||||
|
||||
@ -344,6 +344,11 @@ public class EntityViewServiceImpl extends AbstractCachedEntityService<EntityVie
|
||||
tenantEntityViewRemover.removeEntities(tenantId, tenantId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void deleteByTenantId(TenantId tenantId) {
|
||||
deleteEntityViewsByTenantId(tenantId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ListenableFuture<List<EntitySubtype>> findEntityViewTypesByTenantId(TenantId tenantId) {
|
||||
log.trace("Executing findEntityViewTypesByTenantId, tenantId [{}]", tenantId);
|
||||
|
||||
@ -27,6 +27,8 @@ import org.thingsboard.server.dao.eventsourcing.DeleteEntityEvent;
|
||||
import org.thingsboard.server.dao.housekeeper.data.HousekeeperTask;
|
||||
import org.thingsboard.server.dao.relation.RelationService;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
@Component
|
||||
@RequiredArgsConstructor
|
||||
@Slf4j
|
||||
@ -57,4 +59,11 @@ public class CleanUpService {
|
||||
housekeeperService.submitTask(HousekeeperTask.deleteEntityAlarms(tenantId, entityId));
|
||||
}
|
||||
|
||||
public void removeTenantEntities(TenantId tenantId, EntityType... entityTypes) {
|
||||
UUID tasksKey = UUID.randomUUID(); // so that all tasks are processed synchronously from one partition
|
||||
for (EntityType entityType : entityTypes) {
|
||||
housekeeperService.submitTask(tasksKey, HousekeeperTask.deleteEntities(tenantId, entityType));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -17,8 +17,13 @@ package org.thingsboard.server.dao.housekeeper;
|
||||
|
||||
import org.thingsboard.server.dao.housekeeper.data.HousekeeperTask;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
public interface HousekeeperService {
|
||||
|
||||
void submitTask(HousekeeperTask task);
|
||||
|
||||
// tasks with the same key will be pushed to the same partition and thus processed synchronously
|
||||
void submitTask(UUID key, HousekeeperTask task);
|
||||
|
||||
}
|
||||
|
||||
@ -0,0 +1,32 @@
|
||||
/**
|
||||
* 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.dao.housekeeper.data;
|
||||
|
||||
import lombok.Getter;
|
||||
import org.thingsboard.server.common.data.EntityType;
|
||||
import org.thingsboard.server.common.data.id.TenantId;
|
||||
|
||||
@Getter
|
||||
public class EntitiesDeletionHousekeeperTask extends HousekeeperTask {
|
||||
|
||||
private final EntityType entityType;
|
||||
|
||||
protected EntitiesDeletionHousekeeperTask(TenantId tenantId, EntityType entityType) {
|
||||
super(tenantId, null, HousekeeperTaskType.DELETE_ENTITIES);
|
||||
this.entityType = entityType;
|
||||
}
|
||||
|
||||
}
|
||||
@ -16,6 +16,7 @@
|
||||
package org.thingsboard.server.dao.housekeeper.data;
|
||||
|
||||
import lombok.Data;
|
||||
import org.thingsboard.server.common.data.EntityType;
|
||||
import org.thingsboard.server.common.data.User;
|
||||
import org.thingsboard.server.common.data.id.EntityId;
|
||||
import org.thingsboard.server.common.data.id.TenantId;
|
||||
@ -57,4 +58,8 @@ public class HousekeeperTask implements Serializable {
|
||||
return new HousekeeperTask(tenantId, entityId, HousekeeperTaskType.DELETE_ENTITY_ALARMS);
|
||||
}
|
||||
|
||||
public static HousekeeperTask deleteEntities(TenantId tenantId, EntityType entityType) {
|
||||
return new EntitiesDeletionHousekeeperTask(tenantId, entityType);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -16,7 +16,7 @@
|
||||
package org.thingsboard.server.dao.housekeeper.data;
|
||||
|
||||
public enum HousekeeperTaskType {
|
||||
DELETE_ENTITY,
|
||||
DELETE_ENTITIES,
|
||||
DELETE_ATTRIBUTES,
|
||||
DELETE_TELEMETRY, // maybe divide into latest and ts kv history?
|
||||
DELETE_EVENTS,
|
||||
|
||||
@ -104,6 +104,11 @@ public class DefaultNotificationRequestService implements NotificationRequestSer
|
||||
notificationRequestDao.removeByTenantId(tenantId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void deleteByTenantId(TenantId tenantId) {
|
||||
deleteNotificationRequestsByTenantId(tenantId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Optional<HasId<?>> findEntity(TenantId tenantId, EntityId entityId) {
|
||||
return Optional.ofNullable(findNotificationRequestById(tenantId, new NotificationRequestId(entityId.getId())));
|
||||
|
||||
@ -93,6 +93,11 @@ public class DefaultNotificationRuleService extends AbstractEntityService implem
|
||||
notificationRuleDao.removeByTenantId(tenantId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void deleteByTenantId(TenantId tenantId) {
|
||||
deleteNotificationRulesByTenantId(tenantId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Optional<HasId<?>> findEntity(TenantId tenantId, EntityId entityId) {
|
||||
return Optional.ofNullable(findNotificationRuleById(tenantId, new NotificationRuleId(entityId.getId())));
|
||||
|
||||
@ -201,6 +201,11 @@ public class DefaultNotificationTargetService extends AbstractEntityService impl
|
||||
notificationTargetDao.removeByTenantId(tenantId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void deleteByTenantId(TenantId tenantId) {
|
||||
deleteNotificationTargetsByTenantId(tenantId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public long countNotificationTargetsByTenantId(TenantId tenantId) {
|
||||
return notificationTargetDao.countByTenantId(tenantId);
|
||||
|
||||
@ -89,6 +89,11 @@ public class DefaultNotificationTemplateService extends AbstractEntityService im
|
||||
notificationTemplateDao.removeByTenantId(tenantId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void deleteByTenantId(TenantId tenantId) {
|
||||
deleteNotificationTemplatesByTenantId(tenantId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Optional<HasId<?>> findEntity(TenantId tenantId, EntityId entityId) {
|
||||
return Optional.ofNullable(findNotificationTemplateById(tenantId, new NotificationTemplateId(entityId.getId())));
|
||||
|
||||
@ -230,6 +230,11 @@ public class BaseOtaPackageService extends AbstractCachedEntityService<OtaPackag
|
||||
tenantOtaPackageRemover.removeEntities(tenantId, tenantId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void deleteByTenantId(TenantId tenantId) {
|
||||
deleteOtaPackagesByTenantId(tenantId);
|
||||
}
|
||||
|
||||
private PaginatedRemover<TenantId, OtaPackageInfo> tenantOtaPackageRemover =
|
||||
new PaginatedRemover<>() {
|
||||
|
||||
|
||||
@ -129,6 +129,11 @@ public class BaseQueueService extends AbstractEntityService implements QueueServ
|
||||
tenantQueuesRemover.removeEntities(tenantId, tenantId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void deleteByTenantId(TenantId tenantId) {
|
||||
deleteQueuesByTenantId(tenantId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Optional<HasId<?>> findEntity(TenantId tenantId, EntityId entityId) {
|
||||
return Optional.ofNullable(findQueueById(tenantId, new QueueId(entityId.getId())));
|
||||
|
||||
@ -203,6 +203,11 @@ public class BaseResourceService extends AbstractCachedEntityService<ResourceInf
|
||||
tenantResourcesRemover.removeEntities(tenantId, tenantId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void deleteByTenantId(TenantId tenantId) {
|
||||
deleteResourcesByTenantId(tenantId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Optional<HasId<?>> findEntity(TenantId tenantId, EntityId entityId) {
|
||||
return Optional.ofNullable(findResourceInfoById(tenantId, new TbResourceId(entityId.getId())));
|
||||
|
||||
@ -66,6 +66,11 @@ public class BaseRpcService implements RpcService {
|
||||
tenantRpcRemover.removeEntities(tenantId, tenantId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void deleteByTenantId(TenantId tenantId) {
|
||||
deleteAllRpcByTenantId(tenantId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Rpc findById(TenantId tenantId, RpcId rpcId) {
|
||||
log.trace("Executing findById, tenantId [{}], rpcId [{}]", tenantId, rpcId);
|
||||
|
||||
@ -443,6 +443,11 @@ public class BaseRuleChainService extends AbstractEntityService implements RuleC
|
||||
tenantRuleChainsRemover.removeEntities(tenantId, tenantId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void deleteByTenantId(TenantId tenantId) {
|
||||
deleteRuleChainsByTenantId(tenantId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public RuleChainData exportTenantRuleChains(TenantId tenantId, PageLink pageLink) {
|
||||
Validator.validateId(tenantId, "Incorrect tenant id for search rule chain request.");
|
||||
|
||||
@ -21,14 +21,20 @@ import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.thingsboard.server.common.data.AdminSettings;
|
||||
import org.thingsboard.server.common.data.EntityType;
|
||||
import org.thingsboard.server.common.data.id.AdminSettingsId;
|
||||
import org.thingsboard.server.common.data.id.EntityId;
|
||||
import org.thingsboard.server.common.data.id.HasId;
|
||||
import org.thingsboard.server.common.data.id.TenantId;
|
||||
import org.thingsboard.server.dao.entity.EntityDaoService;
|
||||
import org.thingsboard.server.dao.service.DataValidator;
|
||||
import org.thingsboard.server.dao.service.Validator;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
@Service
|
||||
@Slf4j
|
||||
public class AdminSettingsServiceImpl implements AdminSettingsService {
|
||||
public class AdminSettingsServiceImpl implements AdminSettingsService, EntityDaoService {
|
||||
|
||||
@Autowired
|
||||
private AdminSettingsDao adminSettingsDao;
|
||||
@ -105,4 +111,19 @@ public class AdminSettingsServiceImpl implements AdminSettingsService {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void deleteByTenantId(TenantId tenantId) {
|
||||
deleteAdminSettingsByTenantId(tenantId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Optional<HasId<?>> findEntity(TenantId tenantId, EntityId entityId) {
|
||||
return Optional.empty();
|
||||
}
|
||||
|
||||
@Override
|
||||
public EntityType getEntityType() {
|
||||
return EntityType.ADMIN_SETTINGS;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -196,8 +196,8 @@ public class JpaAttributeDao extends JpaAbstractDaoListeningExecutorService impl
|
||||
public List<Pair<String, String>> removeAllByEntityId(TenantId tenantId, EntityId entityId) {
|
||||
return jdbcTemplate.queryForList("DELETE FROM attribute_kv WHERE entity_type = ? and entity_id = ? " +
|
||||
"RETURNING attribute_type, attribute_key", entityId.getEntityType().name(), entityId.getId()).stream()
|
||||
.map(deleted -> Pair.of((String) deleted.get(ModelConstants.ATTRIBUTE_TYPE_COLUMN),
|
||||
(String) deleted.get(ModelConstants.ATTRIBUTE_KEY_COLUMN)))
|
||||
.map(row -> Pair.of((String) row.get(ModelConstants.ATTRIBUTE_TYPE_COLUMN),
|
||||
(String) row.get(ModelConstants.ATTRIBUTE_KEY_COLUMN)))
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
|
||||
@ -19,6 +19,7 @@ import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.thingsboard.server.common.data.id.TenantId;
|
||||
import org.thingsboard.server.common.data.id.UserId;
|
||||
import org.thingsboard.server.common.data.settings.UserSettings;
|
||||
import org.thingsboard.server.common.data.settings.UserSettingsCompositeKey;
|
||||
import org.thingsboard.server.dao.DaoUtil;
|
||||
@ -50,4 +51,9 @@ public class JpaUserSettingsDao extends JpaAbstractDaoListeningExecutorService i
|
||||
userSettingsRepository.deleteById(id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeByUserId(TenantId tenantId, UserId userId) {
|
||||
userSettingsRepository.deleteByUserId(userId.getId());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -16,9 +16,20 @@
|
||||
package org.thingsboard.server.dao.sql.user;
|
||||
|
||||
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.settings.UserSettingsCompositeKey;
|
||||
import org.thingsboard.server.dao.model.sql.UserSettingsEntity;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
public interface UserSettingsRepository extends JpaRepository<UserSettingsEntity, UserSettingsCompositeKey> {
|
||||
|
||||
@Transactional
|
||||
@Modifying
|
||||
@Query("DELETE FROM UserSettingsEntity s WHERE s.userId = :userId")
|
||||
void deleteByUserId(@Param("userId") UUID userId);
|
||||
|
||||
}
|
||||
|
||||
@ -211,41 +211,26 @@ public class TenantServiceImpl extends AbstractCachedEntityService<TenantId, Ten
|
||||
return savedTenant;
|
||||
}
|
||||
|
||||
/**
|
||||
* We intentionally leave this method without "Transactional" annotation due to complexity of the method.
|
||||
* Ideally we should delete related entites without "paginatedRemover" logic. But in such a case we can't clear cache and send events.
|
||||
* We will create separate task to make "deleteTenant" transactional.
|
||||
*/
|
||||
@Transactional
|
||||
@Override
|
||||
public void deleteTenant(TenantId tenantId) {
|
||||
log.trace("Executing deleteTenant [{}]", tenantId);
|
||||
Validator.validateId(tenantId, INCORRECT_TENANT_ID + tenantId);
|
||||
entityViewService.deleteEntityViewsByTenantId(tenantId);
|
||||
widgetsBundleService.deleteWidgetsBundlesByTenantId(tenantId);
|
||||
widgetTypeService.deleteWidgetTypesByTenantId(tenantId);
|
||||
assetService.deleteAssetsByTenantId(tenantId);
|
||||
assetProfileService.deleteAssetProfilesByTenantId(tenantId);
|
||||
deviceService.deleteDevicesByTenantId(tenantId);
|
||||
deviceProfileService.deleteDeviceProfilesByTenantId(tenantId);
|
||||
dashboardService.deleteDashboardsByTenantId(tenantId);
|
||||
customerService.deleteCustomersByTenantId(tenantId);
|
||||
edgeService.deleteEdgesByTenantId(tenantId);
|
||||
userService.deleteTenantAdmins(tenantId);
|
||||
ruleChainService.deleteRuleChainsByTenantId(tenantId);
|
||||
apiUsageStateService.deleteApiUsageStateByTenantId(tenantId);
|
||||
resourceService.deleteResourcesByTenantId(tenantId);
|
||||
otaPackageService.deleteOtaPackagesByTenantId(tenantId);
|
||||
rpcService.deleteAllRpcByTenantId(tenantId);
|
||||
queueService.deleteQueuesByTenantId(tenantId);
|
||||
notificationRequestService.deleteNotificationRequestsByTenantId(tenantId);
|
||||
notificationRuleService.deleteNotificationRulesByTenantId(tenantId);
|
||||
notificationTemplateService.deleteNotificationTemplatesByTenantId(tenantId);
|
||||
notificationTargetService.deleteNotificationTargetsByTenantId(tenantId);
|
||||
adminSettingsService.deleteAdminSettingsByTenantId(tenantId);
|
||||
|
||||
userService.deleteByTenantId(tenantId);
|
||||
tenantDao.removeById(tenantId, tenantId.getId());
|
||||
|
||||
cleanUpService.removeTenantEntities(tenantId, // don't forget to implement deleteByTenantId from EntityDaoService when adding entity type to this list
|
||||
EntityType.ENTITY_VIEW, EntityType.WIDGETS_BUNDLE, EntityType.WIDGET_TYPE,
|
||||
EntityType.ASSET, EntityType.ASSET_PROFILE, EntityType.DEVICE, EntityType.DEVICE_PROFILE,
|
||||
EntityType.DASHBOARD, EntityType.CUSTOMER, EntityType.EDGE, EntityType.RULE_CHAIN,
|
||||
EntityType.API_USAGE_STATE, EntityType.TB_RESOURCE, EntityType.OTA_PACKAGE, EntityType.RPC,
|
||||
EntityType.QUEUE, EntityType.NOTIFICATION_REQUEST, EntityType.NOTIFICATION_RULE,
|
||||
EntityType.NOTIFICATION_TEMPLATE, EntityType.NOTIFICATION_TARGET, EntityType.ADMIN_SETTINGS
|
||||
);
|
||||
|
||||
publishEvictEvent(new TenantEvictEvent(tenantId, true));
|
||||
eventPublisher.publishEvent(DeleteEntityEvent.builder().tenantId(tenantId).entityId(tenantId).build());
|
||||
alarmService.deleteEntityAlarmRecordsByTenantId(tenantId);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@ -172,6 +172,11 @@ public class ApiUsageStateServiceImpl extends AbstractEntityService implements A
|
||||
return Optional.ofNullable(findApiUsageStateById(tenantId, new ApiUsageStateId(entityId.getId())));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void deleteByTenantId(TenantId tenantId) {
|
||||
deleteApiUsageStateByTenantId(tenantId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public EntityType getEntityType() {
|
||||
return EntityType.API_USAGE_STATE;
|
||||
|
||||
@ -85,6 +85,7 @@ public class UserServiceImpl extends AbstractEntityService implements UserServic
|
||||
private final UserDao userDao;
|
||||
private final UserCredentialsDao userCredentialsDao;
|
||||
private final UserAuthSettingsDao userAuthSettingsDao;
|
||||
private final UserSettingsDao userSettingsDao;
|
||||
private final DataValidator<User> userValidator;
|
||||
private final DataValidator<UserCredentials> userCredentialsValidator;
|
||||
private final ApplicationEventPublisher eventPublisher;
|
||||
@ -255,6 +256,7 @@ public class UserServiceImpl extends AbstractEntityService implements UserServic
|
||||
validateId(userId, INCORRECT_USER_ID + userId);
|
||||
userCredentialsDao.removeByUserId(tenantId, userId);
|
||||
userAuthSettingsDao.removeByUserId(userId);
|
||||
userSettingsDao.removeByUserId(tenantId, userId);
|
||||
|
||||
userDao.removeById(tenantId, userId.getId());
|
||||
eventPublisher.publishEvent(new UserCredentialsInvalidationEvent(userId));
|
||||
@ -313,6 +315,12 @@ public class UserServiceImpl extends AbstractEntityService implements UserServic
|
||||
tenantAdminsRemover.removeEntities(tenantId, tenantId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void deleteByTenantId(TenantId tenantId) {
|
||||
log.trace("Executing deleteByTenantId, tenantId [{}]", tenantId);
|
||||
usersRemover.removeEntities(tenantId, tenantId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public PageData<User> findCustomerUsers(TenantId tenantId, CustomerId customerId, PageLink pageLink) {
|
||||
log.trace("Executing findCustomerUsers, tenantId [{}], customerId [{}], pageLink [{}]", tenantId, customerId, pageLink);
|
||||
@ -464,6 +472,18 @@ public class UserServiceImpl extends AbstractEntityService implements UserServic
|
||||
}
|
||||
};
|
||||
|
||||
private final PaginatedRemover<TenantId, User> usersRemover = new PaginatedRemover<>() {
|
||||
@Override
|
||||
protected PageData<User> findEntities(TenantId tenantId, TenantId id, PageLink pageLink) {
|
||||
return findUsersByTenantId(tenantId, pageLink);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void removeEntity(TenantId tenantId, User user) {
|
||||
deleteUser(tenantId, user);
|
||||
}
|
||||
};
|
||||
|
||||
@Override
|
||||
public Optional<HasId<?>> findEntity(TenantId tenantId, EntityId entityId) {
|
||||
return Optional.ofNullable(findUserById(tenantId, new UserId(entityId.getId())));
|
||||
|
||||
@ -16,6 +16,7 @@
|
||||
package org.thingsboard.server.dao.user;
|
||||
|
||||
import org.thingsboard.server.common.data.id.TenantId;
|
||||
import org.thingsboard.server.common.data.id.UserId;
|
||||
import org.thingsboard.server.common.data.settings.UserSettings;
|
||||
import org.thingsboard.server.common.data.settings.UserSettingsCompositeKey;
|
||||
|
||||
@ -27,4 +28,6 @@ public interface UserSettingsDao {
|
||||
|
||||
void removeById(TenantId tenantId, UserSettingsCompositeKey key);
|
||||
|
||||
void removeByUserId(TenantId tenantId, UserId userId);
|
||||
|
||||
}
|
||||
|
||||
@ -226,6 +226,11 @@ public class WidgetTypeServiceImpl implements WidgetTypeService {
|
||||
tenantWidgetTypeRemover.removeEntities(tenantId, tenantId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void deleteByTenantId(TenantId tenantId) {
|
||||
deleteWidgetTypesByTenantId(tenantId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Optional<HasId<?>> findEntity(TenantId tenantId, EntityId entityId) {
|
||||
return Optional.ofNullable(findWidgetTypeById(tenantId, new WidgetTypeId(entityId.getId())));
|
||||
|
||||
@ -179,6 +179,11 @@ public class WidgetsBundleServiceImpl implements WidgetsBundleService {
|
||||
tenantWidgetsBundleRemover.removeEntities(tenantId, tenantId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void deleteByTenantId(TenantId tenantId) {
|
||||
deleteWidgetsBundlesByTenantId(tenantId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Optional<HasId<?>> findEntity(TenantId tenantId, EntityId entityId) {
|
||||
return Optional.ofNullable(findWidgetsBundleById(tenantId, new WidgetsBundleId(entityId.getId())));
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user