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