Browse Source

Clean up api usage state data on deletion

pull/10201/head
ViacheslavKlimov 3 years ago
parent
commit
1ed95b24a6
  1. 22
      application/src/test/java/org/thingsboard/server/service/housekeeper/HousekeeperServiceTest.java
  2. 2
      common/dao-api/src/main/java/org/thingsboard/server/dao/usagerecord/ApiUsageStateService.java
  3. 1
      dao/src/main/java/org/thingsboard/server/dao/attributes/BaseAttributesService.java
  4. 1
      dao/src/main/java/org/thingsboard/server/dao/rule/BaseRuleChainService.java
  5. 3
      dao/src/main/java/org/thingsboard/server/dao/tenant/TenantServiceImpl.java
  6. 19
      dao/src/main/java/org/thingsboard/server/dao/usagerecord/ApiUsageStateServiceImpl.java

22
application/src/test/java/org/thingsboard/server/service/housekeeper/HousekeeperServiceTest.java

@ -28,6 +28,7 @@ import org.springframework.test.context.TestPropertySource;
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.DataConstants;
import org.thingsboard.server.common.data.Device;
import org.thingsboard.server.common.data.EventInfo;
@ -48,7 +49,6 @@ import org.thingsboard.server.common.data.id.RuleChainId;
import org.thingsboard.server.common.data.id.RuleNodeId;
import org.thingsboard.server.common.data.id.TenantId;
import org.thingsboard.server.common.data.id.UserId;
import org.thingsboard.server.common.data.kv.AttributeKvEntry;
import org.thingsboard.server.common.data.kv.BaseAttributeKvEntry;
import org.thingsboard.server.common.data.kv.BaseReadTsKvQuery;
import org.thingsboard.server.common.data.kv.BasicTsKvEntry;
@ -68,11 +68,13 @@ import org.thingsboard.server.controller.AbstractControllerTest;
import org.thingsboard.server.dao.alarm.AlarmDao;
import org.thingsboard.server.dao.alarm.AlarmService;
import org.thingsboard.server.dao.attributes.AttributesService;
import org.thingsboard.server.dao.entity.EntityServiceRegistry;
import org.thingsboard.server.dao.event.EventService;
import org.thingsboard.server.dao.relation.RelationService;
import org.thingsboard.server.dao.rule.RuleChainService;
import org.thingsboard.server.dao.service.DaoSqlTest;
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;
@ -127,6 +129,10 @@ public class HousekeeperServiceTest extends AbstractControllerTest {
private AlarmDao alarmDao;
@Autowired
private RelationService relationService;
@Autowired
private ApiUsageStateDao apiUsageStateDao;
@Autowired
private EntityServiceRegistry entityServiceRegistry;
@SpyBean
private TelemetryDeletionTaskProcessor telemetryDeletionTaskProcessor;
@ -208,6 +214,9 @@ public class HousekeeperServiceTest extends AbstractControllerTest {
tenantId = differentTenantId;
createRelatedData(tenantId);
createDifferentTenantCustomer();
createRelatedData(differentTenantCustomerId);
loginDifferentTenant();
Device device = createDevice("oi324rujoi", "oi324rujoi");
createRelatedData(device.getId());
@ -228,6 +237,8 @@ public class HousekeeperServiceTest extends AbstractControllerTest {
UserId userId = savedDifferentTenantUser.getId();
createRelatedData(userId);
ApiUsageState tenantApiUsageState = apiUsageStateDao.findApiUsageStateByEntityId(differentTenantId);
loginSysAdmin();
deleteDifferentTenant();
@ -238,6 +249,8 @@ public class HousekeeperServiceTest extends AbstractControllerTest {
verifyNoRelatedData(ruleNode2Id);
verifyNoRelatedData(ruleChainId);
verifyNoRelatedData(userId);
verifyNoRelatedData(differentTenantCustomerId);
verifyNoRelatedData(tenantApiUsageState.getId());
verifyNoRelatedData(tenantId);
});
}
@ -323,11 +336,12 @@ public class HousekeeperServiceTest extends AbstractControllerTest {
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)) {
assertThat(getAttribute(entityId, scope, scope + ATTRIBUTE_KEY)).isNull();
assertThat(attributesService.findAll(tenantId, entityId, scope).get()).isEmpty();
}
assertThat(getEvents(entityId)).isEmpty();
assertThat(alarmDao.findEntityAlarmRecordsByEntityId(tenantId, entityId)).isEmpty();
@ -388,10 +402,6 @@ public class HousekeeperServiceTest extends AbstractControllerTest {
return timeseriesService.findAll(tenantId, entityId, List.of(new BaseReadTsKvQuery(HousekeeperServiceTest.TELEMETRY_KEY, 0, System.currentTimeMillis(), 10, "DESC"))).get();
}
private AttributeKvEntry getAttribute(EntityId entityId, String scope, String key) throws Exception {
return attributesService.find(tenantId, entityId, scope, key).get().orElse(null);
}
private List<EventInfo> getEvents(EntityId entityId) {
return eventService.findEvents(tenantId, entityId, EventType.LC_EVENT, new TimePageLink(100)).getData()
.stream().filter(event -> Optional.ofNullable(event.getBody()).map(body -> body.get("event"))

2
common/dao-api/src/main/java/org/thingsboard/server/dao/usagerecord/ApiUsageStateService.java

@ -31,8 +31,6 @@ public interface ApiUsageStateService extends EntityDaoService {
ApiUsageState findApiUsageStateByEntityId(EntityId entityId);
void deleteApiUsageStateByTenantId(TenantId tenantId);
void deleteApiUsageStateByEntityId(EntityId entityId);
ApiUsageState findApiUsageStateById(TenantId tenantId, ApiUsageStateId id);

1
dao/src/main/java/org/thingsboard/server/dao/attributes/BaseAttributesService.java

@ -118,7 +118,6 @@ public class BaseAttributesService implements AttributesService {
@Override
public int removeAllByEntityId(TenantId tenantId, EntityId entityId) {
List<Pair<String, String>> deleted = attributesDao.removeAllByEntityId(tenantId, entityId);
// todo: probably better to retrieve by scope in case there are too many attributes
return deleted.size();
}

1
dao/src/main/java/org/thingsboard/server/dao/rule/BaseRuleChainService.java

@ -178,7 +178,6 @@ public class BaseRuleChainService extends AbstractEntityService implements RuleC
List<RuleNodeUpdateResult> updatedRuleNodes = new ArrayList<>();
List<RuleNode> existingRuleNodes = getRuleChainNodes(tenantId, ruleChainMetaData.getRuleChainId());
for (RuleNode existingNode : existingRuleNodes) {
cleanUpService.cleanUpRelatedData(tenantId, existingNode.getId()); // fixme: for sure?
Integer index = ruleNodeIndexMap.get(existingNode.getId());
RuleNode newRuleNode = null;
if (index != null) {

3
dao/src/main/java/org/thingsboard/server/dao/tenant/TenantServiceImpl.java

@ -16,7 +16,6 @@
package org.thingsboard.server.dao.tenant;
import com.google.common.util.concurrent.ListenableFuture;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
@ -54,7 +53,6 @@ import static org.thingsboard.server.dao.service.Validator.validateId;
@Service("TenantDaoService")
@Slf4j
@RequiredArgsConstructor
public class TenantServiceImpl extends AbstractCachedEntityService<TenantId, Tenant, TenantEvictEvent> implements TenantService {
private static final String DEFAULT_TENANT_REGION = "Global";
@ -153,7 +151,6 @@ public class TenantServiceImpl extends AbstractCachedEntityService<TenantId, Ten
notificationSettingsService.deleteNotificationSettings(tenantId);
tenantDao.removeById(tenantId, tenantId.getId());
// fixme: we should publish to housekeeper when a transaction is committed (or better after msg was broadcasted): move this to cleanup-service
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,

19
dao/src/main/java/org/thingsboard/server/dao/usagerecord/ApiUsageStateServiceImpl.java

@ -18,6 +18,7 @@ package org.thingsboard.server.dao.usagerecord;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.thingsboard.server.common.data.ApiFeature;
import org.thingsboard.server.common.data.ApiUsageRecordKey;
import org.thingsboard.server.common.data.ApiUsageState;
@ -35,6 +36,7 @@ import org.thingsboard.server.common.data.kv.StringDataEntry;
import org.thingsboard.server.common.data.kv.TsKvEntry;
import org.thingsboard.server.common.data.tenant.profile.TenantProfileConfiguration;
import org.thingsboard.server.dao.entity.AbstractEntityService;
import org.thingsboard.server.dao.eventsourcing.DeleteEntityEvent;
import org.thingsboard.server.dao.service.DataValidator;
import org.thingsboard.server.dao.tenant.TenantProfileDao;
import org.thingsboard.server.dao.tenant.TenantService;
@ -68,18 +70,16 @@ public class ApiUsageStateServiceImpl extends AbstractEntityService implements A
this.apiUsageStateValidator = apiUsageStateValidator;
}
@Override
public void deleteApiUsageStateByTenantId(TenantId tenantId) {
log.trace("Executing deleteUsageRecordsByTenantId [{}]", tenantId);
validateId(tenantId, INCORRECT_TENANT_ID + tenantId);
apiUsageStateDao.deleteApiUsageStateByTenantId(tenantId);
}
@Transactional
@Override
public void deleteApiUsageStateByEntityId(EntityId entityId) {
log.trace("Executing deleteApiUsageStateByEntityId [{}]", entityId);
validateId(entityId.getId(), "Invalid entity id");
apiUsageStateDao.deleteApiUsageStateByEntityId(entityId);
ApiUsageState apiUsageState = findApiUsageStateByEntityId(entityId);
if (apiUsageState != null) {
apiUsageStateDao.removeById(apiUsageState.getTenantId(), apiUsageState.getUuidId());
eventPublisher.publishEvent(DeleteEntityEvent.builder().tenantId(apiUsageState.getTenantId()).entityId(apiUsageState.getId()).build());
}
}
@Override
@ -172,9 +172,10 @@ public class ApiUsageStateServiceImpl extends AbstractEntityService implements A
return Optional.ofNullable(findApiUsageStateById(tenantId, new ApiUsageStateId(entityId.getId())));
}
@Transactional
@Override
public void deleteByTenantId(TenantId tenantId) {
deleteApiUsageStateByTenantId(tenantId);
deleteApiUsageStateByEntityId(tenantId);
}
@Override

Loading…
Cancel
Save