Commit 9d14a38966c5351edd16c01b339a9ff3c19e88e7

Authored by Andrii Shvaika
1 parent 9ec4b776

Tenant Profile updates for ApiUsageStateService

@@ -40,8 +40,6 @@ import org.thingsboard.server.common.msg.plugin.ComponentLifecycleMsg; @@ -40,8 +40,6 @@ import org.thingsboard.server.common.msg.plugin.ComponentLifecycleMsg;
40 import org.thingsboard.server.common.msg.queue.QueueToRuleEngineMsg; 40 import org.thingsboard.server.common.msg.queue.QueueToRuleEngineMsg;
41 import org.thingsboard.server.common.msg.queue.RuleEngineException; 41 import org.thingsboard.server.common.msg.queue.RuleEngineException;
42 import org.thingsboard.server.common.msg.queue.ServiceType; 42 import org.thingsboard.server.common.msg.queue.ServiceType;
43 -import org.thingsboard.server.dao.model.ModelConstants;  
44 -import org.thingsboard.server.dao.tenant.TenantProfileService;  
45 import org.thingsboard.server.dao.tenant.TenantService; 43 import org.thingsboard.server.dao.tenant.TenantService;
46 import org.thingsboard.server.service.profile.TbTenantProfileCache; 44 import org.thingsboard.server.service.profile.TbTenantProfileCache;
47 import org.thingsboard.server.service.transport.msg.TransportToDeviceActorMsgWrapper; 45 import org.thingsboard.server.service.transport.msg.TransportToDeviceActorMsgWrapper;
@@ -150,15 +148,12 @@ public class AppActor extends ContextAwareActor { @@ -150,15 +148,12 @@ public class AppActor extends ContextAwareActor {
150 private void onComponentLifecycleMsg(ComponentLifecycleMsg msg) { 148 private void onComponentLifecycleMsg(ComponentLifecycleMsg msg) {
151 TbActorRef target = null; 149 TbActorRef target = null;
152 if (TenantId.SYS_TENANT_ID.equals(msg.getTenantId())) { 150 if (TenantId.SYS_TENANT_ID.equals(msg.getTenantId())) {
153 - if (msg.getEntityId().getEntityType() == EntityType.TENANT_PROFILE) {  
154 - tenantProfileCache.evict(new TenantProfileId(msg.getEntityId().getId()));  
155 - } else { 151 + if (!EntityType.TENANT_PROFILE.equals(msg.getEntityId().getEntityType())) {
156 log.warn("Message has system tenant id: {}", msg); 152 log.warn("Message has system tenant id: {}", msg);
157 } 153 }
158 } else { 154 } else {
159 - if (msg.getEntityId().getEntityType() == EntityType.TENANT) { 155 + if (EntityType.TENANT.equals(msg.getEntityId().getEntityType())) {
160 TenantId tenantId = new TenantId(msg.getEntityId().getId()); 156 TenantId tenantId = new TenantId(msg.getEntityId().getId());
161 - tenantProfileCache.evict(tenantId);  
162 if (msg.getEvent() == ComponentLifecycleEvent.DELETED) { 157 if (msg.getEvent() == ComponentLifecycleEvent.DELETED) {
163 log.info("[{}] Handling tenant deleted notification: {}", msg.getTenantId(), msg); 158 log.info("[{}] Handling tenant deleted notification: {}", msg.getTenantId(), msg);
164 deletedTenants.add(tenantId); 159 deletedTenants.add(tenantId);
@@ -22,6 +22,7 @@ import org.thingsboard.server.common.data.ApiUsageRecordKey; @@ -22,6 +22,7 @@ import org.thingsboard.server.common.data.ApiUsageRecordKey;
22 import org.thingsboard.server.common.data.ApiUsageState; 22 import org.thingsboard.server.common.data.ApiUsageState;
23 import org.thingsboard.server.common.data.TenantProfile; 23 import org.thingsboard.server.common.data.TenantProfile;
24 import org.thingsboard.server.common.data.id.TenantId; 24 import org.thingsboard.server.common.data.id.TenantId;
  25 +import org.thingsboard.server.common.data.id.TenantProfileId;
25 import org.thingsboard.server.common.data.kv.BasicTsKvEntry; 26 import org.thingsboard.server.common.data.kv.BasicTsKvEntry;
26 import org.thingsboard.server.common.data.kv.LongDataEntry; 27 import org.thingsboard.server.common.data.kv.LongDataEntry;
27 import org.thingsboard.server.common.data.kv.TsKvEntry; 28 import org.thingsboard.server.common.data.kv.TsKvEntry;
@@ -87,6 +88,7 @@ public class DefaultTbApiUsageStateService implements TbApiUsageStateService { @@ -87,6 +88,7 @@ public class DefaultTbApiUsageStateService implements TbApiUsageStateService {
87 TenantId tenantId = new TenantId(new UUID(statsMsg.getTenantIdMSB(), statsMsg.getTenantIdLSB())); 88 TenantId tenantId = new TenantId(new UUID(statsMsg.getTenantIdMSB(), statsMsg.getTenantIdLSB()));
88 TenantApiUsageState tenantState; 89 TenantApiUsageState tenantState;
89 List<TsKvEntry> updatedEntries; 90 List<TsKvEntry> updatedEntries;
  91 + boolean stateUpdated = false;
90 updateLock.lock(); 92 updateLock.lock();
91 try { 93 try {
92 tenantState = getOrFetchState(tenantId); 94 tenantState = getOrFetchState(tenantId);
@@ -101,13 +103,21 @@ public class DefaultTbApiUsageStateService implements TbApiUsageStateService { @@ -101,13 +103,21 @@ public class DefaultTbApiUsageStateService implements TbApiUsageStateService {
101 ApiUsageRecordKey recordKey = ApiUsageRecordKey.valueOf(kvProto.getKey()); 103 ApiUsageRecordKey recordKey = ApiUsageRecordKey.valueOf(kvProto.getKey());
102 long newValue = tenantState.add(recordKey, kvProto.getValue()); 104 long newValue = tenantState.add(recordKey, kvProto.getValue());
103 updatedEntries.add(new BasicTsKvEntry(ts, new LongDataEntry(recordKey.name(), newValue))); 105 updatedEntries.add(new BasicTsKvEntry(ts, new LongDataEntry(recordKey.name(), newValue)));
104 - newValue = tenantState.addToHourly(recordKey, kvProto.getValue());  
105 - updatedEntries.add(new BasicTsKvEntry(hourTs, new LongDataEntry(HOURLY + recordKey.name(), newValue))); 106 + long newHourlyValue = tenantState.addToHourly(recordKey, kvProto.getValue());
  107 + updatedEntries.add(new BasicTsKvEntry(hourTs, new LongDataEntry(HOURLY + recordKey.name(), newHourlyValue)));
  108 + stateUpdated |= tenantState.checkStateUpdatedDueToThreshold(recordKey);
106 } 109 }
107 } finally { 110 } finally {
108 updateLock.unlock(); 111 updateLock.unlock();
109 } 112 }
110 tsService.save(tenantId, tenantState.getEntityId(), updatedEntries, 0L); 113 tsService.save(tenantId, tenantState.getEntityId(), updatedEntries, 0L);
  114 + if (stateUpdated) {
  115 + // Save new state into the database;
  116 + apiUsageStateService.update(tenantState.getApiUsageState());
  117 + //TODO: clear cache on cluster repartition.
  118 + //TODO: update profiles on tenant and profile updates.
  119 + //TODO: broadcast to everyone notifications about enabled/disabled features.
  120 + }
111 } 121 }
112 122
113 @Override 123 @Override
@@ -116,12 +126,26 @@ public class DefaultTbApiUsageStateService implements TbApiUsageStateService { @@ -116,12 +126,26 @@ public class DefaultTbApiUsageStateService implements TbApiUsageStateService {
116 } 126 }
117 127
118 @Override 128 @Override
119 - public void onAddedToAllowList(TenantId tenantId) {  
120 - 129 + public void onTenantProfileUpdate(TenantProfileId tenantProfileId) {
  130 + TenantProfile tenantProfile = tenantProfileCache.get(tenantProfileId);
  131 + updateLock.lock();
  132 + try {
  133 + tenantStates.values().forEach(state -> {
  134 + if (tenantProfile.getId().equals(state.getTenantProfileId())) {
  135 + state.setTenantProfileData(tenantProfile.getProfileData());
  136 + if (state.checkStateUpdatedDueToThresholds()) {
  137 + apiUsageStateService.update(state.getApiUsageState());
  138 + //TODO: send notification to cluster;
  139 + }
  140 + }
  141 + });
  142 + } finally {
  143 + updateLock.unlock();
  144 + }
121 } 145 }
122 146
123 @Override 147 @Override
124 - public void onAddedToDenyList(TenantId tenantId) { 148 + public void onTenantUpdate(TenantId tenantId) {
125 149
126 } 150 }
127 151
@@ -150,7 +174,8 @@ public class DefaultTbApiUsageStateService implements TbApiUsageStateService { @@ -150,7 +174,8 @@ public class DefaultTbApiUsageStateService implements TbApiUsageStateService {
150 dbStateEntity = apiUsageStateService.findTenantApiUsageState(tenantId); 174 dbStateEntity = apiUsageStateService.findTenantApiUsageState(tenantId);
151 } 175 }
152 } 176 }
153 - tenantState = new TenantApiUsageState(dbStateEntity.getEntityId()); 177 + TenantProfile tenantProfile = tenantProfileCache.get(tenantId);
  178 + tenantState = new TenantApiUsageState(tenantProfile, dbStateEntity);
154 try { 179 try {
155 List<TsKvEntry> dbValues = tsService.findAllLatest(tenantId, dbStateEntity.getEntityId()).get(); 180 List<TsKvEntry> dbValues = tsService.findAllLatest(tenantId, dbStateEntity.getEntityId()).get();
156 for (ApiUsageRecordKey key : ApiUsageRecordKey.values()) { 181 for (ApiUsageRecordKey key : ApiUsageRecordKey.values()) {
@@ -16,6 +16,7 @@ @@ -16,6 +16,7 @@
16 package org.thingsboard.server.service.apiusage; 16 package org.thingsboard.server.service.apiusage;
17 17
18 import org.thingsboard.server.common.data.id.TenantId; 18 import org.thingsboard.server.common.data.id.TenantId;
  19 +import org.thingsboard.server.common.data.id.TenantProfileId;
19 import org.thingsboard.server.common.msg.queue.TbCallback; 20 import org.thingsboard.server.common.msg.queue.TbCallback;
20 import org.thingsboard.server.gen.transport.TransportProtos.ToUsageStatsServiceMsg; 21 import org.thingsboard.server.gen.transport.TransportProtos.ToUsageStatsServiceMsg;
21 import org.thingsboard.server.queue.common.TbProtoQueueMsg; 22 import org.thingsboard.server.queue.common.TbProtoQueueMsg;
@@ -26,8 +27,7 @@ public interface TbApiUsageStateService { @@ -26,8 +27,7 @@ public interface TbApiUsageStateService {
26 27
27 TenantApiUsageState getApiUsageState(TenantId tenantId); 28 TenantApiUsageState getApiUsageState(TenantId tenantId);
28 29
29 - void onAddedToAllowList(TenantId tenantId);  
30 -  
31 - void onAddedToDenyList(TenantId tenantId); 30 + void onTenantProfileUpdate(TenantProfileId tenantProfileId);
32 31
  32 + void onTenantUpdate(TenantId tenantId);
33 } 33 }
@@ -16,8 +16,13 @@ @@ -16,8 +16,13 @@
16 package org.thingsboard.server.service.apiusage; 16 package org.thingsboard.server.service.apiusage;
17 17
18 import lombok.Getter; 18 import lombok.Getter;
  19 +import lombok.Setter;
19 import org.thingsboard.server.common.data.ApiUsageRecordKey; 20 import org.thingsboard.server.common.data.ApiUsageRecordKey;
  21 +import org.thingsboard.server.common.data.ApiUsageState;
  22 +import org.thingsboard.server.common.data.TenantProfile;
  23 +import org.thingsboard.server.common.data.TenantProfileData;
20 import org.thingsboard.server.common.data.id.EntityId; 24 import org.thingsboard.server.common.data.id.EntityId;
  25 +import org.thingsboard.server.common.data.id.TenantProfileId;
21 import org.thingsboard.server.common.msg.tools.SchedulerUtils; 26 import org.thingsboard.server.common.msg.tools.SchedulerUtils;
22 27
23 import java.util.Map; 28 import java.util.Map;
@@ -29,7 +34,13 @@ public class TenantApiUsageState { @@ -29,7 +34,13 @@ public class TenantApiUsageState {
29 private final Map<ApiUsageRecordKey, Long> currentHourValues = new ConcurrentHashMap<>(); 34 private final Map<ApiUsageRecordKey, Long> currentHourValues = new ConcurrentHashMap<>();
30 35
31 @Getter 36 @Getter
32 - private final EntityId entityId; 37 + @Setter
  38 + private TenantProfileId tenantProfileId;
  39 + @Getter
  40 + @Setter
  41 + private TenantProfileData tenantProfileData;
  42 + @Getter
  43 + private final ApiUsageState apiUsageState;
33 @Getter 44 @Getter
34 private volatile long currentCycleTs; 45 private volatile long currentCycleTs;
35 @Getter 46 @Getter
@@ -37,8 +48,10 @@ public class TenantApiUsageState { @@ -37,8 +48,10 @@ public class TenantApiUsageState {
37 @Getter 48 @Getter
38 private volatile long currentHourTs; 49 private volatile long currentHourTs;
39 50
40 - public TenantApiUsageState(EntityId entityId) {  
41 - this.entityId = entityId; 51 + public TenantApiUsageState(TenantProfile tenantProfile, ApiUsageState apiUsageState) {
  52 + this.tenantProfileId = tenantProfile.getId();
  53 + this.tenantProfileData = tenantProfile.getProfileData();
  54 + this.apiUsageState = apiUsageState;
42 this.currentCycleTs = SchedulerUtils.getStartOfCurrentMonth(); 55 this.currentCycleTs = SchedulerUtils.getStartOfCurrentMonth();
43 this.nextCycleTs = SchedulerUtils.getStartOfNextMonth(); 56 this.nextCycleTs = SchedulerUtils.getStartOfNextMonth();
44 this.currentHourTs = SchedulerUtils.getStartOfCurrentHour(); 57 this.currentHourTs = SchedulerUtils.getStartOfCurrentHour();
@@ -58,6 +71,10 @@ public class TenantApiUsageState { @@ -58,6 +71,10 @@ public class TenantApiUsageState {
58 return result; 71 return result;
59 } 72 }
60 73
  74 + public long get(ApiUsageRecordKey key) {
  75 + return currentCycleValues.getOrDefault(key, 0L);
  76 + }
  77 +
61 public long addToHourly(ApiUsageRecordKey key, long value) { 78 public long addToHourly(ApiUsageRecordKey key, long value) {
62 long result = currentHourValues.getOrDefault(key, 0L) + value; 79 long result = currentHourValues.getOrDefault(key, 0L) + value;
63 currentHourValues.put(key, result); 80 currentHourValues.put(key, result);
@@ -79,4 +96,103 @@ public class TenantApiUsageState { @@ -79,4 +96,103 @@ public class TenantApiUsageState {
79 } 96 }
80 } 97 }
81 98
  99 + public long getProfileThreshold(ApiUsageRecordKey key) {
  100 + Object threshold = tenantProfileData.getProperties().get(key.name());
  101 + if (threshold != null) {
  102 + if (threshold instanceof String) {
  103 + return Long.parseLong((String) threshold);
  104 + } else if (threshold instanceof Long) {
  105 + return (Long) threshold;
  106 + }
  107 + }
  108 + return 0L;
  109 + }
  110 +
  111 + public EntityId getEntityId() {
  112 + return apiUsageState.getEntityId();
  113 + }
  114 +
  115 + public boolean isTransportEnabled() {
  116 + return apiUsageState.isTransportEnabled();
  117 + }
  118 +
  119 + public boolean isDbStorageEnabled() {
  120 + return apiUsageState.isDbStorageEnabled();
  121 + }
  122 +
  123 + public boolean isRuleEngineEnabled() {
  124 + return apiUsageState.isRuleEngineEnabled();
  125 + }
  126 +
  127 + public boolean isJsExecEnabled() {
  128 + return apiUsageState.isJsExecEnabled();
  129 + }
  130 +
  131 + public void setTransportEnabled(boolean transportEnabled) {
  132 + apiUsageState.setTransportEnabled(transportEnabled);
  133 + }
  134 +
  135 + public void setDbStorageEnabled(boolean dbStorageEnabled) {
  136 + apiUsageState.setDbStorageEnabled(dbStorageEnabled);
  137 + }
  138 +
  139 + public void setRuleEngineEnabled(boolean ruleEngineEnabled) {
  140 + apiUsageState.setRuleEngineEnabled(ruleEngineEnabled);
  141 + }
  142 +
  143 + public void setJsExecEnabled(boolean jsExecEnabled) {
  144 + apiUsageState.setJsExecEnabled(jsExecEnabled);
  145 + }
  146 +
  147 + public boolean isFeatureEnabled(ApiUsageRecordKey recordKey) {
  148 + switch (recordKey) {
  149 + case MSG_COUNT:
  150 + case MSG_BYTES_COUNT:
  151 + case DP_TRANSPORT_COUNT:
  152 + return isTransportEnabled();
  153 + case RE_EXEC_COUNT:
  154 + return isRuleEngineEnabled();
  155 + case DP_STORAGE_COUNT:
  156 + return isDbStorageEnabled();
  157 + case JS_EXEC_COUNT:
  158 + return isJsExecEnabled();
  159 + default:
  160 + return true;
  161 + }
  162 + }
  163 +
  164 + public boolean setFeatureValue(ApiUsageRecordKey recordKey, boolean value) {
  165 + boolean currentValue = isFeatureEnabled(recordKey);
  166 + switch (recordKey) {
  167 + case MSG_COUNT:
  168 + case MSG_BYTES_COUNT:
  169 + case DP_TRANSPORT_COUNT:
  170 + setTransportEnabled(value);
  171 + break;
  172 + case RE_EXEC_COUNT:
  173 + setRuleEngineEnabled(value);
  174 + break;
  175 + case DP_STORAGE_COUNT:
  176 + setDbStorageEnabled(value);
  177 + break;
  178 + case JS_EXEC_COUNT:
  179 + setJsExecEnabled(value);
  180 + break;
  181 + }
  182 + return currentValue == value;
  183 + }
  184 +
  185 + public boolean checkStateUpdatedDueToThresholds() {
  186 + boolean update = false;
  187 + for (ApiUsageRecordKey key : ApiUsageRecordKey.values()) {
  188 + update |= checkStateUpdatedDueToThreshold(key);
  189 + }
  190 + return update;
  191 + }
  192 +
  193 + public boolean checkStateUpdatedDueToThreshold(ApiUsageRecordKey recordKey) {
  194 + long value = get(recordKey);
  195 + long threshold = getProfileThreshold(recordKey);
  196 + return setFeatureValue(recordKey, threshold == 0 || value < threshold);
  197 + }
82 } 198 }
@@ -107,7 +107,7 @@ public class DefaultTbCoreConsumerService extends AbstractConsumerService<ToCore @@ -107,7 +107,7 @@ public class DefaultTbCoreConsumerService extends AbstractConsumerService<ToCore
107 SubscriptionManagerService subscriptionManagerService, DataDecodingEncodingService encodingService, 107 SubscriptionManagerService subscriptionManagerService, DataDecodingEncodingService encodingService,
108 TbCoreDeviceRpcService tbCoreDeviceRpcService, StatsFactory statsFactory, TbDeviceProfileCache deviceProfileCache, 108 TbCoreDeviceRpcService tbCoreDeviceRpcService, StatsFactory statsFactory, TbDeviceProfileCache deviceProfileCache,
109 TbApiUsageStateService statsService) { 109 TbApiUsageStateService statsService) {
110 - super(actorContext, encodingService, deviceProfileCache, tbCoreQueueFactory.createToCoreNotificationsMsgConsumer()); 110 + super(actorContext, encodingService, tenantProfileCache, deviceProfileCache, apiUsageStateService, tbCoreQueueFactory.createToCoreNotificationsMsgConsumer());
111 this.mainConsumer = tbCoreQueueFactory.createToCoreMsgConsumer(); 111 this.mainConsumer = tbCoreQueueFactory.createToCoreMsgConsumer();
112 this.usageStatsConsumer = tbCoreQueueFactory.createToUsageStatsServiceMsgConsumer(); 112 this.usageStatsConsumer = tbCoreQueueFactory.createToUsageStatsServiceMsgConsumer();
113 this.stateService = stateService; 113 this.stateService = stateService;
@@ -15,7 +15,6 @@ @@ -15,7 +15,6 @@
15 */ 15 */
16 package org.thingsboard.server.service.queue; 16 package org.thingsboard.server.service.queue;
17 17
18 -import com.google.protobuf.ByteString;  
19 import com.google.protobuf.ProtocolStringList; 18 import com.google.protobuf.ProtocolStringList;
20 import lombok.extern.slf4j.Slf4j; 19 import lombok.extern.slf4j.Slf4j;
21 import org.springframework.beans.factory.annotation.Value; 20 import org.springframework.beans.factory.annotation.Value;
@@ -24,7 +23,6 @@ import org.springframework.stereotype.Service; @@ -24,7 +23,6 @@ import org.springframework.stereotype.Service;
24 import org.thingsboard.rule.engine.api.RpcError; 23 import org.thingsboard.rule.engine.api.RpcError;
25 import org.thingsboard.server.actors.ActorSystemContext; 24 import org.thingsboard.server.actors.ActorSystemContext;
26 import org.thingsboard.server.common.data.id.TenantId; 25 import org.thingsboard.server.common.data.id.TenantId;
27 -import org.thingsboard.server.common.msg.TbActorMsg;  
28 import org.thingsboard.server.common.msg.TbMsg; 26 import org.thingsboard.server.common.msg.TbMsg;
29 import org.thingsboard.server.common.msg.queue.*; 27 import org.thingsboard.server.common.msg.queue.*;
30 import org.thingsboard.server.common.stats.StatsFactory; 28 import org.thingsboard.server.common.stats.StatsFactory;
@@ -83,7 +81,7 @@ public class DefaultTbRuleEngineConsumerService extends AbstractConsumerService< @@ -83,7 +81,7 @@ public class DefaultTbRuleEngineConsumerService extends AbstractConsumerService<
83 ActorSystemContext actorContext, DataDecodingEncodingService encodingService, 81 ActorSystemContext actorContext, DataDecodingEncodingService encodingService,
84 TbRuleEngineDeviceRpcService tbDeviceRpcService, 82 TbRuleEngineDeviceRpcService tbDeviceRpcService,
85 StatsFactory statsFactory, TbDeviceProfileCache deviceProfileCache) { 83 StatsFactory statsFactory, TbDeviceProfileCache deviceProfileCache) {
86 - super(actorContext, encodingService, deviceProfileCache, tbRuleEngineQueueFactory.createToRuleEngineNotificationsMsgConsumer()); 84 + super(actorContext, encodingService, tenantProfileCache, deviceProfileCache, apiUsageStateService, tbRuleEngineQueueFactory.createToRuleEngineNotificationsMsgConsumer());
87 this.statisticsService = statisticsService; 85 this.statisticsService = statisticsService;
88 this.ruleEngineSettings = ruleEngineSettings; 86 this.ruleEngineSettings = ruleEngineSettings;
89 this.tbRuleEngineQueueFactory = tbRuleEngineQueueFactory; 87 this.tbRuleEngineQueueFactory = tbRuleEngineQueueFactory;
@@ -25,6 +25,7 @@ import org.thingsboard.server.actors.ActorSystemContext; @@ -25,6 +25,7 @@ import org.thingsboard.server.actors.ActorSystemContext;
25 import org.thingsboard.server.common.data.EntityType; 25 import org.thingsboard.server.common.data.EntityType;
26 import org.thingsboard.server.common.data.id.DeviceId; 26 import org.thingsboard.server.common.data.id.DeviceId;
27 import org.thingsboard.server.common.data.id.DeviceProfileId; 27 import org.thingsboard.server.common.data.id.DeviceProfileId;
  28 +import org.thingsboard.server.common.data.id.TenantProfileId;
28 import org.thingsboard.server.common.msg.TbActorMsg; 29 import org.thingsboard.server.common.msg.TbActorMsg;
29 import org.thingsboard.server.common.msg.plugin.ComponentLifecycleMsg; 30 import org.thingsboard.server.common.msg.plugin.ComponentLifecycleMsg;
30 import org.thingsboard.server.common.msg.queue.ServiceType; 31 import org.thingsboard.server.common.msg.queue.ServiceType;
@@ -33,7 +34,9 @@ import org.thingsboard.server.queue.TbQueueConsumer; @@ -33,7 +34,9 @@ import org.thingsboard.server.queue.TbQueueConsumer;
33 import org.thingsboard.server.queue.common.TbProtoQueueMsg; 34 import org.thingsboard.server.queue.common.TbProtoQueueMsg;
34 import org.thingsboard.server.queue.discovery.PartitionChangeEvent; 35 import org.thingsboard.server.queue.discovery.PartitionChangeEvent;
35 import org.thingsboard.server.common.transport.util.DataDecodingEncodingService; 36 import org.thingsboard.server.common.transport.util.DataDecodingEncodingService;
  37 +import org.thingsboard.server.service.apiusage.TbApiUsageStateService;
36 import org.thingsboard.server.service.profile.TbDeviceProfileCache; 38 import org.thingsboard.server.service.profile.TbDeviceProfileCache;
  39 +import org.thingsboard.server.service.profile.TbTenantProfileCache;
37 import org.thingsboard.server.service.queue.TbPackCallback; 40 import org.thingsboard.server.service.queue.TbPackCallback;
38 import org.thingsboard.server.service.queue.TbPackProcessingContext; 41 import org.thingsboard.server.service.queue.TbPackProcessingContext;
39 42
@@ -59,15 +62,19 @@ public abstract class AbstractConsumerService<N extends com.google.protobuf.Gene @@ -59,15 +62,19 @@ public abstract class AbstractConsumerService<N extends com.google.protobuf.Gene
59 62
60 protected final ActorSystemContext actorContext; 63 protected final ActorSystemContext actorContext;
61 protected final DataDecodingEncodingService encodingService; 64 protected final DataDecodingEncodingService encodingService;
  65 + protected final TbTenantProfileCache tenantProfileCache;
62 protected final TbDeviceProfileCache deviceProfileCache; 66 protected final TbDeviceProfileCache deviceProfileCache;
  67 + protected final TbApiUsageStateService apiUsageStateService;
63 68
64 protected final TbQueueConsumer<TbProtoQueueMsg<N>> nfConsumer; 69 protected final TbQueueConsumer<TbProtoQueueMsg<N>> nfConsumer;
65 70
66 public AbstractConsumerService(ActorSystemContext actorContext, DataDecodingEncodingService encodingService, 71 public AbstractConsumerService(ActorSystemContext actorContext, DataDecodingEncodingService encodingService,
67 - TbDeviceProfileCache deviceProfileCache, TbQueueConsumer<TbProtoQueueMsg<N>> nfConsumer) { 72 + TbTenantProfileCache tenantProfileCache, TbDeviceProfileCache deviceProfileCache, TbApiUsageStateService apiUsageStateService, TbQueueConsumer<TbProtoQueueMsg<N>> nfConsumer) {
68 this.actorContext = actorContext; 73 this.actorContext = actorContext;
69 this.encodingService = encodingService; 74 this.encodingService = encodingService;
  75 + this.tenantProfileCache = tenantProfileCache;
70 this.deviceProfileCache = deviceProfileCache; 76 this.deviceProfileCache = deviceProfileCache;
  77 + this.apiUsageStateService = apiUsageStateService;
71 this.nfConsumer = nfConsumer; 78 this.nfConsumer = nfConsumer;
72 } 79 }
73 80
@@ -143,7 +150,14 @@ public abstract class AbstractConsumerService<N extends com.google.protobuf.Gene @@ -143,7 +150,14 @@ public abstract class AbstractConsumerService<N extends com.google.protobuf.Gene
143 TbActorMsg actorMsg = actorMsgOpt.get(); 150 TbActorMsg actorMsg = actorMsgOpt.get();
144 if (actorMsg instanceof ComponentLifecycleMsg) { 151 if (actorMsg instanceof ComponentLifecycleMsg) {
145 ComponentLifecycleMsg componentLifecycleMsg = (ComponentLifecycleMsg) actorMsg; 152 ComponentLifecycleMsg componentLifecycleMsg = (ComponentLifecycleMsg) actorMsg;
146 - if (EntityType.DEVICE_PROFILE.equals(componentLifecycleMsg.getEntityId().getEntityType())) { 153 + if (EntityType.TENANT_PROFILE.equals(componentLifecycleMsg.getEntityId().getEntityType())) {
  154 + TenantProfileId tenantProfileId = new TenantProfileId(componentLifecycleMsg.getEntityId().getId());
  155 + tenantProfileCache.evict(tenantProfileId);
  156 + apiUsageStateService.onTenantProfileUpdate(tenantProfileId);
  157 + } else if (EntityType.TENANT.equals(componentLifecycleMsg.getEntityId().getEntityType())) {
  158 + tenantProfileCache.evict(componentLifecycleMsg.getTenantId());
  159 + apiUsageStateService.onTenantUpdate(componentLifecycleMsg.getTenantId());
  160 + } else if (EntityType.DEVICE_PROFILE.equals(componentLifecycleMsg.getEntityId().getEntityType())) {
147 deviceProfileCache.evict(componentLifecycleMsg.getTenantId(), new DeviceProfileId(componentLifecycleMsg.getEntityId().getId())); 161 deviceProfileCache.evict(componentLifecycleMsg.getTenantId(), new DeviceProfileId(componentLifecycleMsg.getEntityId().getId()));
148 } else if (EntityType.DEVICE.equals(componentLifecycleMsg.getEntityId().getEntityType())) { 162 } else if (EntityType.DEVICE.equals(componentLifecycleMsg.getEntityId().getEntityType())) {
149 deviceProfileCache.evict(new DeviceId(componentLifecycleMsg.getEntityId().getId())); 163 deviceProfileCache.evict(new DeviceId(componentLifecycleMsg.getEntityId().getId()));
@@ -20,9 +20,12 @@ import org.thingsboard.server.common.data.id.TenantId; @@ -20,9 +20,12 @@ import org.thingsboard.server.common.data.id.TenantId;
20 20
21 public interface ApiUsageStateService { 21 public interface ApiUsageStateService {
22 22
  23 + ApiUsageState createDefaultApiUsageState(TenantId id);
  24 +
  25 + ApiUsageState update(ApiUsageState apiUsageState);
  26 +
23 ApiUsageState findTenantApiUsageState(TenantId tenantId); 27 ApiUsageState findTenantApiUsageState(TenantId tenantId);
24 28
25 void deleteApiUsageStateByTenantId(TenantId tenantId); 29 void deleteApiUsageStateByTenantId(TenantId tenantId);
26 30
27 - ApiUsageState createDefaultApiUsageState(TenantId id);  
28 } 31 }
@@ -16,6 +16,8 @@ @@ -16,6 +16,8 @@
16 package org.thingsboard.server.common.data; 16 package org.thingsboard.server.common.data;
17 17
18 import lombok.EqualsAndHashCode; 18 import lombok.EqualsAndHashCode;
  19 +import lombok.Getter;
  20 +import lombok.Setter;
19 import lombok.ToString; 21 import lombok.ToString;
20 import org.thingsboard.server.common.data.id.EntityId; 22 import org.thingsboard.server.common.data.id.EntityId;
21 import org.thingsboard.server.common.data.id.TenantId; 23 import org.thingsboard.server.common.data.id.TenantId;
@@ -27,8 +29,18 @@ public class ApiUsageState extends BaseData<ApiUsageStateId> implements HasTenan @@ -27,8 +29,18 @@ public class ApiUsageState extends BaseData<ApiUsageStateId> implements HasTenan
27 29
28 private static final long serialVersionUID = 8250339805336035966L; 30 private static final long serialVersionUID = 8250339805336035966L;
29 31
  32 + @Getter @Setter
30 private TenantId tenantId; 33 private TenantId tenantId;
  34 + @Getter @Setter
31 private EntityId entityId; 35 private EntityId entityId;
  36 + @Getter @Setter
  37 + private boolean transportEnabled;
  38 + @Getter @Setter
  39 + private boolean dbStorageEnabled;
  40 + @Getter @Setter
  41 + private boolean ruleEngineEnabled;
  42 + @Getter @Setter
  43 + private boolean jsExecEnabled;
32 44
33 public ApiUsageState() { 45 public ApiUsageState() {
34 super(); 46 super();
@@ -43,22 +55,4 @@ public class ApiUsageState extends BaseData<ApiUsageStateId> implements HasTenan @@ -43,22 +55,4 @@ public class ApiUsageState extends BaseData<ApiUsageStateId> implements HasTenan
43 this.tenantId = ur.getTenantId(); 55 this.tenantId = ur.getTenantId();
44 this.entityId = ur.getEntityId(); 56 this.entityId = ur.getEntityId();
45 } 57 }
46 -  
47 - @Override  
48 - public TenantId getTenantId() {  
49 - return tenantId;  
50 - }  
51 -  
52 - public void setTenantId(TenantId tenantId) {  
53 - this.tenantId = tenantId;  
54 - }  
55 -  
56 - public EntityId getEntityId() {  
57 - return entityId;  
58 - }  
59 -  
60 - public void setEntityId(EntityId entityId) {  
61 - this.entityId = entityId;  
62 - }  
63 -  
64 } 58 }
@@ -60,6 +60,14 @@ public class ApiApiUsageStateServiceImpl extends AbstractEntityService implement @@ -60,6 +60,14 @@ public class ApiApiUsageStateServiceImpl extends AbstractEntityService implement
60 } 60 }
61 61
62 @Override 62 @Override
  63 + public ApiUsageState update(ApiUsageState apiUsageState) {
  64 + log.trace("Executing save [{}]", apiUsageState.getTenantId());
  65 + validateId(apiUsageState.getTenantId(), INCORRECT_TENANT_ID + apiUsageState.getTenantId());
  66 + validateId(apiUsageState.getId(), "Can't save new usage state. Only update is allowed!");
  67 + return apiUsageStateDao.save(apiUsageState.getTenantId(), apiUsageState);
  68 + }
  69 +
  70 + @Override
63 public ApiUsageState findTenantApiUsageState(TenantId tenantId) { 71 public ApiUsageState findTenantApiUsageState(TenantId tenantId) {
64 log.trace("Executing findTenantUsageRecord, tenantId [{}]", tenantId); 72 log.trace("Executing findTenantUsageRecord, tenantId [{}]", tenantId);
65 validateId(tenantId, INCORRECT_TENANT_ID + tenantId); 73 validateId(tenantId, INCORRECT_TENANT_ID + tenantId);