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,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),
@@ -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);