Commit 5465703d2d8d8ba57b4a7db706fe4a72e7b70c8a

Authored by Viacheslav Klimov
Committed by Andrew Shvayka
1 parent 8c9213cf

Handle tenant and customer deletion for TbApiUsageStateService

... ... @@ -38,6 +38,7 @@ import org.thingsboard.server.common.data.id.EdgeId;
38 38 import org.thingsboard.server.common.data.id.TenantId;
39 39 import org.thingsboard.server.common.data.page.PageData;
40 40 import org.thingsboard.server.common.data.page.PageLink;
  41 +import org.thingsboard.server.common.data.plugin.ComponentLifecycleEvent;
41 42 import org.thingsboard.server.queue.util.TbCoreComponent;
42 43 import org.thingsboard.server.service.security.permission.Operation;
43 44 import org.thingsboard.server.service.security.permission.Resource;
... ... @@ -148,6 +149,7 @@ public class CustomerController extends BaseController {
148 149 ActionType.DELETED, null, strCustomerId);
149 150
150 151 sendDeleteNotificationMsg(getTenantId(), customerId, relatedEdgeIds);
  152 + tbClusterService.onEntityStateChange(getTenantId(), customerId, ComponentLifecycleEvent.DELETED);
151 153 } catch (Exception e) {
152 154
153 155 logEntityAction(emptyId(EntityType.CUSTOMER),
... ...
... ... @@ -111,11 +111,13 @@ public class DefaultTbApiUsageStateService extends TbApplicationEventListener<Pa
111 111 @Autowired
112 112 private InternalTelemetryService tsWsService;
113 113
114   - // Tenants that should be processed on this server
  114 + // Entities that should be processed on this server
115 115 private final Map<EntityId, BaseApiUsageState> myUsageStates = new ConcurrentHashMap<>();
116   - // Tenants that should be processed on other servers
  116 + // Entities that should be processed on other servers
117 117 private final Map<EntityId, ApiUsageState> otherUsageStates = new ConcurrentHashMap<>();
118 118
  119 + private final Set<EntityId> deletedEntities = Collections.newSetFromMap(new ConcurrentHashMap<>());
  120 +
119 121 @Value("${usage.stats.report.enabled:true}")
120 122 private boolean enabled;
121 123
... ... @@ -173,6 +175,8 @@ public class DefaultTbApiUsageStateService extends TbApplicationEventListener<Pa
173 175 }
174 176
175 177 private void processEntityUsageStats(TenantId tenantId, EntityId entityId, List<UsageStatsKVProto> values) {
  178 + if (deletedEntities.contains(entityId)) return;
  179 +
176 180 BaseApiUsageState usageState;
177 181 List<TsKvEntry> updatedEntries;
178 182 Map<ApiFeature, ApiUsageStateValue> result;
... ... @@ -321,6 +325,18 @@ public class DefaultTbApiUsageStateService extends TbApplicationEventListener<Pa
321 325 }
322 326 }
323 327
  328 + public void onTenantDelete(TenantId tenantId) {
  329 + deletedEntities.add(tenantId);
  330 + myUsageStates.remove(tenantId);
  331 + otherUsageStates.remove(tenantId);
  332 + }
  333 +
  334 + @Override
  335 + public void onCustomerDelete(CustomerId customerId) {
  336 + deletedEntities.add(customerId);
  337 + myUsageStates.remove(customerId);
  338 + }
  339 +
324 340 private void persistAndNotify(BaseApiUsageState state, Map<ApiFeature, ApiUsageStateValue> result) {
325 341 log.info("[{}] Detected update of the API state for {}: {}", state.getEntityId(), state.getEntityType(), result);
326 342 apiUsageStateService.update(state.getApiUsageState());
... ...
... ... @@ -17,6 +17,7 @@ package org.thingsboard.server.service.apiusage;
17 17
18 18 import org.springframework.context.ApplicationListener;
19 19 import org.thingsboard.server.common.data.ApiUsageState;
  20 +import org.thingsboard.server.common.data.id.CustomerId;
20 21 import org.thingsboard.server.common.data.id.TenantId;
21 22 import org.thingsboard.server.common.data.id.TenantProfileId;
22 23 import org.thingsboard.server.common.msg.queue.TbCallback;
... ... @@ -34,5 +35,9 @@ public interface TbApiUsageStateService extends ApplicationListener<PartitionCha
34 35
35 36 void onTenantUpdate(TenantId tenantId);
36 37
  38 + void onTenantDelete(TenantId tenantId);
  39 +
  40 + void onCustomerDelete(CustomerId customerId);
  41 +
37 42 void onApiUsageStateUpdate(TenantId tenantId);
38 43 }
... ...
... ... @@ -18,14 +18,15 @@ package org.thingsboard.server.service.queue.processing;
18 18 import com.google.protobuf.ByteString;
19 19 import lombok.extern.slf4j.Slf4j;
20 20 import org.springframework.boot.context.event.ApplicationReadyEvent;
21   -import org.springframework.context.ApplicationListener;
22 21 import org.springframework.context.event.EventListener;
23 22 import org.springframework.core.annotation.Order;
24 23 import org.thingsboard.common.util.ThingsBoardThreadFactory;
25 24 import org.thingsboard.server.actors.ActorSystemContext;
26 25 import org.thingsboard.server.common.data.EntityType;
  26 +import org.thingsboard.server.common.data.id.CustomerId;
27 27 import org.thingsboard.server.common.data.id.DeviceId;
28 28 import org.thingsboard.server.common.data.id.DeviceProfileId;
  29 +import org.thingsboard.server.common.data.id.TenantId;
29 30 import org.thingsboard.server.common.data.id.TenantProfileId;
30 31 import org.thingsboard.server.common.data.plugin.ComponentLifecycleEvent;
31 32 import org.thingsboard.server.common.msg.TbActorMsg;
... ... @@ -72,7 +73,8 @@ public abstract class AbstractConsumerService<N extends com.google.protobuf.Gene
72 73 protected final TbQueueConsumer<TbProtoQueueMsg<N>> nfConsumer;
73 74
74 75 public AbstractConsumerService(ActorSystemContext actorContext, DataDecodingEncodingService encodingService,
75   - TbTenantProfileCache tenantProfileCache, TbDeviceProfileCache deviceProfileCache, TbApiUsageStateService apiUsageStateService, TbQueueConsumer<TbProtoQueueMsg<N>> nfConsumer) {
  76 + TbTenantProfileCache tenantProfileCache, TbDeviceProfileCache deviceProfileCache,
  77 + TbApiUsageStateService apiUsageStateService, TbQueueConsumer<TbProtoQueueMsg<N>> nfConsumer) {
76 78 this.actorContext = actorContext;
77 79 this.encodingService = encodingService;
78 80 this.tenantProfileCache = tenantProfileCache;
... ... @@ -166,6 +168,8 @@ public abstract class AbstractConsumerService<N extends com.google.protobuf.Gene
166 168 tenantProfileCache.evict(componentLifecycleMsg.getTenantId());
167 169 if (componentLifecycleMsg.getEvent().equals(ComponentLifecycleEvent.UPDATED)) {
168 170 apiUsageStateService.onTenantUpdate(componentLifecycleMsg.getTenantId());
  171 + } else if (componentLifecycleMsg.getEvent().equals(ComponentLifecycleEvent.DELETED)) {
  172 + apiUsageStateService.onTenantDelete((TenantId) componentLifecycleMsg.getEntityId());
169 173 }
170 174 } else if (EntityType.DEVICE_PROFILE.equals(componentLifecycleMsg.getEntityId().getEntityType())) {
171 175 deviceProfileCache.evict(componentLifecycleMsg.getTenantId(), new DeviceProfileId(componentLifecycleMsg.getEntityId().getId()));
... ... @@ -173,6 +177,10 @@ public abstract class AbstractConsumerService<N extends com.google.protobuf.Gene
173 177 deviceProfileCache.evict(componentLifecycleMsg.getTenantId(), new DeviceId(componentLifecycleMsg.getEntityId().getId()));
174 178 } else if (EntityType.API_USAGE_STATE.equals(componentLifecycleMsg.getEntityId().getEntityType())) {
175 179 apiUsageStateService.onApiUsageStateUpdate(componentLifecycleMsg.getTenantId());
  180 + } else if (EntityType.CUSTOMER.equals(componentLifecycleMsg.getEntityId().getEntityType())) {
  181 + if (componentLifecycleMsg.getEvent() == ComponentLifecycleEvent.DELETED) {
  182 + apiUsageStateService.onCustomerDelete((CustomerId) componentLifecycleMsg.getEntityId());
  183 + }
176 184 }
177 185 }
178 186 log.trace("[{}] Forwarding message to App Actor {}", id, actorMsg);
... ...
... ... @@ -32,5 +32,7 @@ public interface ApiUsageStateService {
32 32
33 33 void deleteApiUsageStateByTenantId(TenantId tenantId);
34 34
  35 + void deleteApiUsageStateByEntityId(EntityId entityId);
  36 +
35 37 ApiUsageState findApiUsageStateById(TenantId tenantId, ApiUsageStateId id);
36 38 }
... ...
... ... @@ -43,6 +43,7 @@ import org.thingsboard.server.dao.service.PaginatedRemover;
43 43 import org.thingsboard.server.dao.service.Validator;
44 44 import org.thingsboard.server.dao.tenant.TbTenantProfileCache;
45 45 import org.thingsboard.server.dao.tenant.TenantDao;
  46 +import org.thingsboard.server.dao.usagerecord.ApiUsageStateService;
46 47 import org.thingsboard.server.dao.user.UserService;
47 48
48 49 import java.io.IOException;
... ... @@ -80,6 +81,9 @@ public class CustomerServiceImpl extends AbstractEntityService implements Custom
80 81 private DashboardService dashboardService;
81 82
82 83 @Autowired
  84 + private ApiUsageStateService apiUsageStateService;
  85 +
  86 + @Autowired
83 87 @Lazy
84 88 private TbTenantProfileCache tenantProfileCache;
85 89
... ... @@ -128,6 +132,7 @@ public class CustomerServiceImpl extends AbstractEntityService implements Custom
128 132 edgeService.unassignCustomerEdges(customer.getTenantId(), customerId);
129 133 userService.deleteCustomerUsers(customer.getTenantId(), customerId);
130 134 deleteEntityRelations(tenantId, customerId);
  135 + apiUsageStateService.deleteApiUsageStateByEntityId(customerId);
131 136 customerDao.removeById(tenantId, customerId.getId());
132 137 }
133 138
... ...
... ... @@ -39,4 +39,8 @@ public interface ApiUsageStateRepository extends CrudRepository<ApiUsageStateEnt
39 39 @Modifying
40 40 @Query("DELETE FROM ApiUsageStateEntity ur WHERE ur.tenantId = :tenantId")
41 41 void deleteApiUsageStateByTenantId(@Param("tenantId") UUID tenantId);
  42 +
  43 + @Transactional
  44 + @Modifying
  45 + void deleteByEntityIdAndEntityType(UUID entityId, String entityType);
42 46 }
... ...
... ... @@ -63,4 +63,9 @@ public class JpaApiUsageStateDao extends JpaAbstractDao<ApiUsageStateEntity, Api
63 63 public void deleteApiUsageStateByTenantId(TenantId tenantId) {
64 64 apiUsageStateRepository.deleteApiUsageStateByTenantId(tenantId.getId());
65 65 }
  66 +
  67 + @Override
  68 + public void deleteApiUsageStateByEntityId(EntityId entityId) {
  69 + apiUsageStateRepository.deleteByEntityIdAndEntityType(entityId.getId(), entityId.getEntityType().name());
  70 + }
66 71 }
... ...
... ... @@ -48,4 +48,6 @@ public interface ApiUsageStateDao extends Dao<ApiUsageState> {
48 48 * @param tenantId the tenantId
49 49 */
50 50 void deleteApiUsageStateByTenantId(TenantId tenantId);
  51 +
  52 + void deleteApiUsageStateByEntityId(EntityId entityId);
51 53 }
... ...
... ... @@ -70,6 +70,13 @@ public class ApiUsageStateServiceImpl extends AbstractEntityService implements A
70 70 }
71 71
72 72 @Override
  73 + public void deleteApiUsageStateByEntityId(EntityId entityId) {
  74 + log.trace("Executing deleteApiUsageStateByEntityId [{}]", entityId);
  75 + validateId(entityId.getId(), "Invalid entity id");
  76 + apiUsageStateDao.deleteApiUsageStateByEntityId(entityId);
  77 + }
  78 +
  79 + @Override
73 80 public ApiUsageState createDefaultApiUsageState(TenantId tenantId, EntityId entityId) {
74 81 entityId = Objects.requireNonNullElse(entityId, tenantId);
75 82 log.trace("Executing createDefaultUsageRecord [{}]", entityId);
... ...