Commit 5465703d2d8d8ba57b4a7db706fe4a72e7b70c8a
Committed by
Andrew Shvayka
1 parent
8c9213cf
Handle tenant and customer deletion for TbApiUsageStateService
Showing
10 changed files
with
60 additions
and
4 deletions
... | ... | @@ -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), | ... | ... |
application/src/main/java/org/thingsboard/server/service/apiusage/DefaultTbApiUsageStateService.java
... | ... | @@ -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 | } | ... | ... |
... | ... | @@ -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); | ... | ... |