Browse Source

Merge branch 'feature/usage-records'

pull/3695/head
Andrii Shvaika 6 years ago
parent
commit
3088e6be6f
  1. 26
      application/src/main/java/org/thingsboard/server/service/apiusage/DefaultTbApiUsageStateService.java
  2. 135
      application/src/main/java/org/thingsboard/server/service/apiusage/TenantApiUsageState.java
  3. 24
      application/src/main/java/org/thingsboard/server/service/install/SqlDatabaseUpgradeService.java
  4. 8
      common/data/src/main/java/org/thingsboard/server/common/data/ApiFeature.java
  5. 34
      common/data/src/main/java/org/thingsboard/server/common/data/ApiUsageRecordKey.java
  6. 32
      common/data/src/main/java/org/thingsboard/server/common/data/ApiUsageState.java
  7. 26
      common/data/src/main/java/org/thingsboard/server/common/data/ApiUsageStateValue.java
  8. 6
      common/data/src/main/java/org/thingsboard/server/common/data/tenant/profile/DefaultTenantProfileConfiguration.java
  9. 3
      common/data/src/main/java/org/thingsboard/server/common/data/tenant/profile/TenantProfileConfiguration.java
  10. 2
      common/queue/src/main/java/org/thingsboard/server/queue/settings/TbQueueCoreSettings.java
  11. 8
      dao/src/main/java/org/thingsboard/server/dao/model/ModelConstants.java
  12. 44
      dao/src/main/java/org/thingsboard/server/dao/model/sql/ApiUsageStateEntity.java
  13. 5
      dao/src/main/java/org/thingsboard/server/dao/usagerecord/ApiUsageStateServiceImpl.java
  14. 8
      dao/src/main/resources/sql/schema-entities-hsql.sql
  15. 8
      dao/src/main/resources/sql/schema-entities.sql
  16. 3
      dao/src/test/java/org/thingsboard/server/dao/service/BaseApiUsageStateServiceTest.java
  17. 1
      transport/coap/src/main/resources/tb-coap-transport.yml
  18. 1
      transport/http/src/main/resources/tb-http-transport.yml
  19. 1
      transport/mqtt/src/main/resources/tb-mqtt-transport.yml

26
application/src/main/java/org/thingsboard/server/service/apiusage/DefaultTbApiUsageStateService.java

@ -23,16 +23,18 @@ import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Lazy;
import org.springframework.data.util.Pair;
import org.springframework.stereotype.Service;
import org.thingsboard.server.common.data.ApiFeature;
import org.thingsboard.server.common.data.ApiUsageRecordKey;
import org.thingsboard.server.common.data.ApiUsageState;
import org.thingsboard.server.common.data.ApiUsageStateValue;
import org.thingsboard.server.common.data.Tenant;
import org.thingsboard.server.common.data.TenantProfile;
import org.thingsboard.server.common.data.id.ApiUsageStateId;
import org.thingsboard.server.common.data.id.TenantId;
import org.thingsboard.server.common.data.id.TenantProfileId;
import org.thingsboard.server.common.data.kv.BasicTsKvEntry;
import org.thingsboard.server.common.data.kv.BooleanDataEntry;
import org.thingsboard.server.common.data.kv.LongDataEntry;
import org.thingsboard.server.common.data.kv.StringDataEntry;
import org.thingsboard.server.common.data.kv.TsKvEntry;
import org.thingsboard.server.common.data.page.PageDataIterable;
import org.thingsboard.server.common.data.tenant.profile.TenantProfileConfiguration;
@ -57,8 +59,10 @@ import org.thingsboard.server.service.telemetry.InternalTelemetryService;
import javax.annotation.PostConstruct;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.UUID;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ExecutionException;
@ -137,7 +141,7 @@ public class DefaultTbApiUsageStateService implements TbApiUsageStateService {
TenantId tenantId = new TenantId(new UUID(statsMsg.getTenantIdMSB(), statsMsg.getTenantIdLSB()));
TenantApiUsageState tenantState;
List<TsKvEntry> updatedEntries;
Map<ApiFeature, Boolean> result = new HashMap<>();
Map<ApiFeature, ApiUsageStateValue> result;
updateLock.lock();
try {
tenantState = getOrFetchState(tenantId);
@ -148,17 +152,16 @@ public class DefaultTbApiUsageStateService implements TbApiUsageStateService {
tenantState.setHour(newHourTs);
}
updatedEntries = new ArrayList<>(ApiUsageRecordKey.values().length);
Set<ApiFeature> apiFeatures = new HashSet<>();
for (UsageStatsKVProto kvProto : statsMsg.getValuesList()) {
ApiUsageRecordKey recordKey = ApiUsageRecordKey.valueOf(kvProto.getKey());
long newValue = tenantState.add(recordKey, kvProto.getValue());
updatedEntries.add(new BasicTsKvEntry(ts, new LongDataEntry(recordKey.getApiCountKey(), newValue)));
long newHourlyValue = tenantState.addToHourly(recordKey, kvProto.getValue());
updatedEntries.add(new BasicTsKvEntry(hourTs, new LongDataEntry(recordKey.getApiCountKey() + HOURLY, newHourlyValue)));
Pair<ApiFeature, Boolean> update = tenantState.checkStateUpdatedDueToThreshold(recordKey);
if (update != null) {
result.put(update.getFirst(), update.getSecond());
}
apiFeatures.add(recordKey.getApiFeature());
}
result = tenantState.checkStateUpdatedDueToThreshold(apiFeatures);
} finally {
updateLock.unlock();
}
@ -196,7 +199,9 @@ public class DefaultTbApiUsageStateService implements TbApiUsageStateService {
state = otherTenantStates.get(tenantId);
if (state == null) {
state = apiUsageStateService.findTenantApiUsageState(tenantId);
otherTenantStates.put(tenantId, state);
if (state != null) {
otherTenantStates.put(tenantId, state);
}
}
} finally {
updateLock.unlock();
@ -245,7 +250,7 @@ public class DefaultTbApiUsageStateService implements TbApiUsageStateService {
TenantProfileData oldProfileData = state.getTenantProfileData();
state.setTenantProfileId(tenantProfile.getId());
state.setTenantProfileData(tenantProfile.getProfileData());
Map<ApiFeature, Boolean> result = state.checkStateUpdatedDueToThresholds();
Map<ApiFeature, ApiUsageStateValue> result = state.checkStateUpdatedDueToThresholds();
if (!result.isEmpty()) {
persistAndNotify(state, result);
}
@ -269,14 +274,15 @@ public class DefaultTbApiUsageStateService implements TbApiUsageStateService {
}
}
private void persistAndNotify(TenantApiUsageState state, Map<ApiFeature, Boolean> result) {
private void persistAndNotify(TenantApiUsageState state, Map<ApiFeature, ApiUsageStateValue> result) {
log.info("[{}] Detected update of the API state: {}", state.getTenantId(), result);
apiUsageStateService.update(state.getApiUsageState());
clusterService.onApiStateChange(state.getApiUsageState(), null);
long ts = System.currentTimeMillis();
List<TsKvEntry> stateTelemetry = new ArrayList<>();
result.forEach(((apiFeature, aState) -> stateTelemetry.add(new BasicTsKvEntry(ts, new BooleanDataEntry(apiFeature.getApiStateKey(), aState)))));
result.forEach(((apiFeature, aState) -> stateTelemetry.add(new BasicTsKvEntry(ts, new StringDataEntry(apiFeature.getApiStateKey(), aState.name())))));
tsWsService.saveAndNotifyInternal(state.getTenantId(), state.getApiUsageState().getId(), stateTelemetry, VOID_CALLBACK);
//TODO: notify tenant admin via email!
}
private void checkStartOfNextCycle() {

135
application/src/main/java/org/thingsboard/server/service/apiusage/TenantApiUsageState.java

@ -18,17 +18,21 @@ package org.thingsboard.server.service.apiusage;
import lombok.Getter;
import lombok.Setter;
import org.springframework.data.util.Pair;
import org.thingsboard.server.common.data.ApiFeature;
import org.thingsboard.server.common.data.ApiUsageRecordKey;
import org.thingsboard.server.common.data.ApiUsageState;
import org.thingsboard.server.common.data.ApiUsageStateValue;
import org.thingsboard.server.common.data.TenantProfile;
import org.thingsboard.server.common.data.id.TenantId;
import org.thingsboard.server.common.data.id.TenantProfileId;
import org.thingsboard.server.common.data.tenant.profile.DefaultTenantProfileConfiguration;
import org.thingsboard.server.common.data.tenant.profile.TenantProfileData;
import org.thingsboard.server.common.msg.tools.SchedulerUtils;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
public class TenantApiUsageState {
@ -103,99 +107,80 @@ public class TenantApiUsageState {
return tenantProfileData.getConfiguration().getProfileThreshold(key);
}
public TenantId getTenantId() {
return apiUsageState.getTenantId();
}
public boolean isTransportEnabled() {
return apiUsageState.isTransportEnabled();
}
public boolean isDbStorageEnabled() {
return apiUsageState.isDbStorageEnabled();
}
public boolean isRuleEngineEnabled() {
return apiUsageState.isReExecEnabled();
}
public boolean isJsExecEnabled() {
return apiUsageState.isJsExecEnabled();
}
public void setTransportEnabled(boolean transportEnabled) {
apiUsageState.setTransportEnabled(transportEnabled);
public long getProfileWarnThreshold(ApiUsageRecordKey key) {
return tenantProfileData.getConfiguration().getWarnThreshold(key);
}
public void setDbStorageEnabled(boolean dbStorageEnabled) {
apiUsageState.setDbStorageEnabled(dbStorageEnabled);
}
public void setRuleEngineEnabled(boolean ruleEngineEnabled) {
apiUsageState.setReExecEnabled(ruleEngineEnabled);
}
public void setJsExecEnabled(boolean jsExecEnabled) {
apiUsageState.setJsExecEnabled(jsExecEnabled);
public TenantId getTenantId() {
return apiUsageState.getTenantId();
}
public boolean isFeatureEnabled(ApiUsageRecordKey recordKey) {
switch (recordKey) {
case TRANSPORT_MSG_COUNT:
case TRANSPORT_DP_COUNT:
return isTransportEnabled();
case RE_EXEC_COUNT:
return isRuleEngineEnabled();
case STORAGE_DP_COUNT:
return isDbStorageEnabled();
case JS_EXEC_COUNT:
return isJsExecEnabled();
public ApiUsageStateValue getFeatureValue(ApiFeature feature) {
switch (feature) {
case TRANSPORT:
return apiUsageState.getTransportState();
case RE:
return apiUsageState.getReExecState();
case DB:
return apiUsageState.getDbStorageState();
case JS:
return apiUsageState.getJsExecState();
default:
return true;
return ApiUsageStateValue.ENABLED;
}
}
public ApiFeature setFeatureValue(ApiUsageRecordKey recordKey, boolean value) {
ApiFeature feature = null;
boolean currentValue = isFeatureEnabled(recordKey);
switch (recordKey) {
case TRANSPORT_MSG_COUNT:
case TRANSPORT_DP_COUNT:
feature = ApiFeature.TRANSPORT;
setTransportEnabled(value);
public boolean setFeatureValue(ApiFeature feature, ApiUsageStateValue value) {
ApiUsageStateValue currentValue = getFeatureValue(feature);
switch (feature) {
case TRANSPORT:
apiUsageState.setTransportState(value);
break;
case RE_EXEC_COUNT:
feature = ApiFeature.RE;
setRuleEngineEnabled(value);
case RE:
apiUsageState.setReExecState(value);
break;
case STORAGE_DP_COUNT:
feature = ApiFeature.DB;
setDbStorageEnabled(value);
case DB:
apiUsageState.setDbStorageState(value);
break;
case JS_EXEC_COUNT:
feature = ApiFeature.JS;
setJsExecEnabled(value);
case JS:
apiUsageState.setJsExecState(value);
break;
}
return currentValue == value ? null : feature;
return !currentValue.equals(value);
}
public Map<ApiFeature, Boolean> checkStateUpdatedDueToThresholds() {
Map<ApiFeature, Boolean> result = new HashMap<>();
for (ApiUsageRecordKey key : ApiUsageRecordKey.values()) {
Pair<ApiFeature, Boolean> featureUpdate = checkStateUpdatedDueToThreshold(key);
if (featureUpdate != null) {
result.put(featureUpdate.getFirst(), featureUpdate.getSecond());
public Map<ApiFeature, ApiUsageStateValue> checkStateUpdatedDueToThresholds() {
return checkStateUpdatedDueToThreshold(new HashSet<>(Arrays.asList(ApiFeature.values())));
}
public Map<ApiFeature, ApiUsageStateValue> checkStateUpdatedDueToThreshold(Set<ApiFeature> features) {
Map<ApiFeature, ApiUsageStateValue> result = new HashMap<>();
for (ApiFeature feature : features) {
Pair<ApiFeature, ApiUsageStateValue> tmp = checkStateUpdatedDueToThreshold(feature);
if (tmp != null) {
result.put(tmp.getFirst(), tmp.getSecond());
}
}
return result;
}
public Pair<ApiFeature, Boolean> checkStateUpdatedDueToThreshold(ApiUsageRecordKey recordKey) {
long value = get(recordKey);
long threshold = getProfileThreshold(recordKey);
boolean featureValue = threshold == 0 || value < threshold;
ApiFeature feature = setFeatureValue(recordKey, featureValue);
return feature != null ? Pair.of(feature, featureValue) : null;
public Pair<ApiFeature, ApiUsageStateValue> checkStateUpdatedDueToThreshold(ApiFeature feature) {
ApiUsageStateValue featureValue = ApiUsageStateValue.ENABLED;
for (ApiUsageRecordKey recordKey : ApiUsageRecordKey.getKeys(feature)) {
long value = get(recordKey);
long threshold = getProfileThreshold(recordKey);
long warnThreshold = getProfileWarnThreshold(recordKey);
ApiUsageStateValue tmpValue;
if (threshold == 0 || value < warnThreshold) {
tmpValue = ApiUsageStateValue.ENABLED;
} else if (value < threshold) {
tmpValue = ApiUsageStateValue.WARNING;
} else {
tmpValue = ApiUsageStateValue.DISABLED;
}
featureValue = ApiUsageStateValue.toMoreRestricted(featureValue, tmpValue);
}
return setFeatureValue(feature, featureValue) ? Pair.of(feature, featureValue) : null;
}
}

24
application/src/main/java/org/thingsboard/server/service/install/SqlDatabaseUpgradeService.java

@ -28,6 +28,7 @@ import org.thingsboard.server.dao.dashboard.DashboardService;
import org.thingsboard.server.dao.device.DeviceProfileService;
import org.thingsboard.server.dao.device.DeviceService;
import org.thingsboard.server.dao.tenant.TenantService;
import org.thingsboard.server.dao.usagerecord.ApiUsageStateService;
import org.thingsboard.server.service.install.sql.SqlDbHelper;
import java.nio.charset.Charset;
@ -96,6 +97,9 @@ public class SqlDatabaseUpgradeService implements DatabaseEntitiesUpgradeService
@Autowired
private DeviceProfileService deviceProfileService;
@Autowired
private ApiUsageStateService apiUsageStateService;
@Override
public void upgradeDatabase(String fromVersion) throws Exception {
@ -352,6 +356,22 @@ public class SqlDatabaseUpgradeService implements DatabaseEntitiesUpgradeService
} catch (Exception e) {
}
try {
conn.createStatement().execute("CREATE TABLE IF NOT EXISTS api_usage_state (" +
" id uuid NOT NULL CONSTRAINT usage_record_pkey PRIMARY KEY," +
" created_time bigint NOT NULL," +
" tenant_id uuid," +
" entity_type varchar(32)," +
" entity_id uuid," +
" transport varchar(32)," +
" db_storage varchar(32)," +
" re_exec varchar(32)," +
" js_exec varchar(32)," +
" CONSTRAINT api_usage_state_unq_key UNIQUE (tenant_id, entity_id)\n" +
");");
} catch (Exception e) {
}
schemaUpdateFile = Paths.get(installScripts.getDataDir(), "upgrade", "3.1.1", "schema_update_before.sql");
loadSql(schemaUpdateFile, conn);
@ -367,6 +387,10 @@ public class SqlDatabaseUpgradeService implements DatabaseEntitiesUpgradeService
do {
pageData = tenantService.findTenants(pageLink);
for (Tenant tenant : pageData.getData()) {
try {
apiUsageStateService.createDefaultApiUsageState(tenant.getId());
} catch (Exception e) {
}
List<EntitySubtype> deviceTypes = deviceService.findDeviceTypesByTenantId(tenant.getId()).get();
try {
deviceProfileService.createDefaultDeviceProfile(tenant.getId());

8
application/src/main/java/org/thingsboard/server/service/apiusage/ApiFeature.java → common/data/src/main/java/org/thingsboard/server/common/data/ApiFeature.java

@ -13,12 +13,15 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.thingsboard.server.service.apiusage;
package org.thingsboard.server.common.data;
import lombok.Getter;
public enum ApiFeature {
TRANSPORT("transportApiState"), DB("dbApiState"), RE("ruleEngineApiState"), JS("jsExecutionApiState");
TRANSPORT("transportApiState"),
DB("dbApiState"),
RE("ruleEngineApiState"),
JS("jsExecutionApiState");
@Getter
private final String apiStateKey;
@ -26,4 +29,5 @@ public enum ApiFeature {
ApiFeature(String apiStateKey) {
this.apiStateKey = apiStateKey;
}
}

34
common/data/src/main/java/org/thingsboard/server/common/data/ApiUsageRecordKey.java

@ -19,20 +19,42 @@ import lombok.Getter;
public enum ApiUsageRecordKey {
TRANSPORT_MSG_COUNT("transportMsgCount", "transportMsgLimit"),
TRANSPORT_DP_COUNT("transportDataPointsCount", "transportDataPointsLimit"),
STORAGE_DP_COUNT("storageDataPointsCount", "storageDataPointsLimit"),
RE_EXEC_COUNT("ruleEngineExecutionCount", "ruleEngineExecutionLimit"),
JS_EXEC_COUNT("jsExecutionCount", "jsExecutionLimit");
TRANSPORT_MSG_COUNT(ApiFeature.TRANSPORT, "transportMsgCount", "transportMsgLimit"),
TRANSPORT_DP_COUNT(ApiFeature.TRANSPORT, "transportDataPointsCount", "transportDataPointsLimit"),
STORAGE_DP_COUNT(ApiFeature.DB, "storageDataPointsCount", "storageDataPointsLimit"),
RE_EXEC_COUNT(ApiFeature.RE, "ruleEngineExecutionCount", "ruleEngineExecutionLimit"),
JS_EXEC_COUNT(ApiFeature.JS, "jsExecutionCount", "jsExecutionLimit");
private static final ApiUsageRecordKey[] JS_RECORD_KEYS = {JS_EXEC_COUNT};
private static final ApiUsageRecordKey[] RE_RECORD_KEYS = {RE_EXEC_COUNT};
private static final ApiUsageRecordKey[] DB_RECORD_KEYS = {STORAGE_DP_COUNT};
private static final ApiUsageRecordKey[] TRANSPORT_RECORD_KEYS = {TRANSPORT_MSG_COUNT, TRANSPORT_DP_COUNT};
@Getter
private final ApiFeature apiFeature;
@Getter
private final String apiCountKey;
@Getter
private final String apiLimitKey;
ApiUsageRecordKey(String apiCountKey, String apiLimitKey) {
ApiUsageRecordKey(ApiFeature apiFeature, String apiCountKey, String apiLimitKey) {
this.apiFeature = apiFeature;
this.apiCountKey = apiCountKey;
this.apiLimitKey = apiLimitKey;
}
public static ApiUsageRecordKey[] getKeys(ApiFeature feature) {
switch (feature) {
case TRANSPORT:
return TRANSPORT_RECORD_KEYS;
case DB:
return DB_RECORD_KEYS;
case RE:
return RE_RECORD_KEYS;
case JS:
return JS_RECORD_KEYS;
default:
return new ApiUsageRecordKey[]{};
}
}
}

32
common/data/src/main/java/org/thingsboard/server/common/data/ApiUsageState.java

@ -37,16 +37,16 @@ public class ApiUsageState extends BaseData<ApiUsageStateId> implements HasTenan
private EntityId entityId;
@Getter
@Setter
private boolean transportEnabled = true;
private ApiUsageStateValue transportState;
@Getter
@Setter
private boolean dbStorageEnabled = true;
private ApiUsageStateValue dbStorageState;
@Getter
@Setter
private boolean reExecEnabled = true;
private ApiUsageStateValue reExecState;
@Getter
@Setter
private boolean jsExecEnabled = true;
private ApiUsageStateValue jsExecState;
public ApiUsageState() {
super();
@ -60,9 +60,25 @@ public class ApiUsageState extends BaseData<ApiUsageStateId> implements HasTenan
super(ur);
this.tenantId = ur.getTenantId();
this.entityId = ur.getEntityId();
this.transportEnabled = ur.isTransportEnabled();
this.dbStorageEnabled = ur.isDbStorageEnabled();
this.reExecEnabled = ur.isReExecEnabled();
this.jsExecEnabled = ur.isJsExecEnabled();
this.transportState = ur.getTransportState();
this.dbStorageState = ur.getDbStorageState();
this.reExecState = ur.getReExecState();
this.jsExecState = ur.getJsExecState();
}
public boolean isTransportEnabled() {
return !ApiUsageStateValue.DISABLED.equals(transportState);
}
public boolean isReExecEnabled() {
return !ApiUsageStateValue.DISABLED.equals(reExecState);
}
public boolean isDbStorageEnabled() {
return !ApiUsageStateValue.DISABLED.equals(dbStorageState);
}
public boolean isJsExecEnabled() {
return !ApiUsageStateValue.DISABLED.equals(jsExecState);
}
}

26
common/data/src/main/java/org/thingsboard/server/common/data/ApiUsageStateValue.java

@ -0,0 +1,26 @@
/**
* Copyright © 2016-2020 The Thingsboard Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.thingsboard.server.common.data;
public enum ApiUsageStateValue {
ENABLED, WARNING, DISABLED;
public static ApiUsageStateValue toMoreRestricted(ApiUsageStateValue a, ApiUsageStateValue b) {
return a.ordinal() > b.ordinal() ? a : b;
}
}

6
common/data/src/main/java/org/thingsboard/server/common/data/tenant/profile/DefaultTenantProfileConfiguration.java

@ -39,6 +39,8 @@ public class DefaultTenantProfileConfiguration implements TenantProfileConfigura
private long maxDPStorageDays;
private int maxRuleNodeExecutionsPerMessage;
private double warnThreshold;
@Override
public long getProfileThreshold(ApiUsageRecordKey key) {
switch (key) {
@ -56,6 +58,10 @@ public class DefaultTenantProfileConfiguration implements TenantProfileConfigura
return 0L;
}
@Override
public long getWarnThreshold(ApiUsageRecordKey key) {
return (long) (getProfileThreshold(key) * (warnThreshold > 0.0 ? warnThreshold : 0.8));
}
@Override
public TenantProfileType getType() {

3
common/data/src/main/java/org/thingsboard/server/common/data/tenant/profile/TenantProfileConfiguration.java

@ -37,6 +37,9 @@ public interface TenantProfileConfiguration {
@JsonIgnore
long getProfileThreshold(ApiUsageRecordKey key);
@JsonIgnore
long getWarnThreshold(ApiUsageRecordKey key);
@JsonIgnore
int getMaxRuleNodeExecsPerMessage();

2
common/queue/src/main/java/org/thingsboard/server/queue/settings/TbQueueCoreSettings.java

@ -26,7 +26,7 @@ public class TbQueueCoreSettings {
@Value("${queue.core.topic}")
private String topic;
@Value("${queue.core.usage-stats-topic}")
@Value("${queue.core.usage-stats-topic:tb_usage_stats}")
private String usageStatsTopic;
@Value("${queue.core.partitions}")

8
dao/src/main/java/org/thingsboard/server/dao/model/ModelConstants.java

@ -446,10 +446,10 @@ public class ModelConstants {
public static final String API_USAGE_STATE_TENANT_ID_COLUMN = TENANT_ID_PROPERTY;
public static final String API_USAGE_STATE_ENTITY_TYPE_COLUMN = ENTITY_TYPE_COLUMN;
public static final String API_USAGE_STATE_ENTITY_ID_COLUMN = ENTITY_ID_COLUMN;
public static final String API_USAGE_STATE_TRANSPORT_ENABLED_COLUMN = "transport_enabled";
public static final String API_USAGE_STATE_DB_STORAGE_ENABLED_COLUMN = "db_storage_enabled";
public static final String API_USAGE_STATE_RE_EXEC_ENABLED_COLUMN = "re_exec_enabled";
public static final String API_USAGE_STATE_JS_EXEC_ENABLED_COLUMN = "js_exec_enabled";
public static final String API_USAGE_STATE_TRANSPORT_COLUMN = "transport";
public static final String API_USAGE_STATE_DB_STORAGE_COLUMN = "db_storage";
public static final String API_USAGE_STATE_RE_EXEC_COLUMN = "re_exec";
public static final String API_USAGE_STATE_JS_EXEC_COLUMN = "js_exec";
/**
* Cassandra attributes and timeseries constants.

44
dao/src/main/java/org/thingsboard/server/dao/model/sql/ApiUsageStateEntity.java

@ -17,10 +17,9 @@ package org.thingsboard.server.dao.model.sql;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.Setter;
import org.hibernate.annotations.TypeDef;
import org.thingsboard.server.common.data.ApiUsageState;
import org.thingsboard.server.common.data.ApiUsageStateValue;
import org.thingsboard.server.common.data.id.EntityIdFactory;
import org.thingsboard.server.common.data.id.TenantId;
import org.thingsboard.server.common.data.id.ApiUsageStateId;
@ -31,6 +30,8 @@ import org.thingsboard.server.dao.util.mapping.JsonStringType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.EnumType;
import javax.persistence.Enumerated;
import javax.persistence.Table;
import java.util.UUID;
@ -46,21 +47,22 @@ public class ApiUsageStateEntity extends BaseSqlEntity<ApiUsageState> implements
@Column(name = ModelConstants.API_USAGE_STATE_TENANT_ID_COLUMN)
private UUID tenantId;
@Column(name = ModelConstants.API_USAGE_STATE_ENTITY_TYPE_COLUMN)
private String entityType;
@Column(name = ModelConstants.API_USAGE_STATE_ENTITY_ID_COLUMN)
private UUID entityId;
@Column(name = ModelConstants.API_USAGE_STATE_TRANSPORT_ENABLED_COLUMN)
private boolean transportEnabled = true;
@Column(name = ModelConstants.API_USAGE_STATE_DB_STORAGE_ENABLED_COLUMN)
private boolean dbStorageEnabled = true;
@Column(name = ModelConstants.API_USAGE_STATE_RE_EXEC_ENABLED_COLUMN)
private boolean reExecEnabled = true;
@Column(name = ModelConstants.API_USAGE_STATE_JS_EXEC_ENABLED_COLUMN)
private boolean jsExecEnabled = true;
@Enumerated(EnumType.STRING)
@Column(name = ModelConstants.API_USAGE_STATE_TRANSPORT_COLUMN)
private ApiUsageStateValue transportState = ApiUsageStateValue.ENABLED;
@Enumerated(EnumType.STRING)
@Column(name = ModelConstants.API_USAGE_STATE_DB_STORAGE_COLUMN)
private ApiUsageStateValue dbStorageState = ApiUsageStateValue.ENABLED;
@Enumerated(EnumType.STRING)
@Column(name = ModelConstants.API_USAGE_STATE_RE_EXEC_COLUMN)
private ApiUsageStateValue reExecState = ApiUsageStateValue.ENABLED;
@Enumerated(EnumType.STRING)
@Column(name = ModelConstants.API_USAGE_STATE_JS_EXEC_COLUMN)
private ApiUsageStateValue jsExecState = ApiUsageStateValue.ENABLED;
public ApiUsageStateEntity() {
}
@ -77,10 +79,10 @@ public class ApiUsageStateEntity extends BaseSqlEntity<ApiUsageState> implements
this.entityType = ur.getEntityId().getEntityType().name();
this.entityId = ur.getEntityId().getId();
}
this.transportEnabled = ur.isTransportEnabled();
this.dbStorageEnabled = ur.isDbStorageEnabled();
this.reExecEnabled = ur.isReExecEnabled();
this.jsExecEnabled = ur.isJsExecEnabled();
this.transportState = ur.getTransportState();
this.dbStorageState = ur.getDbStorageState();
this.reExecState = ur.getReExecState();
this.jsExecState = ur.getJsExecState();
}
@Override
@ -93,10 +95,10 @@ public class ApiUsageStateEntity extends BaseSqlEntity<ApiUsageState> implements
if (entityId != null) {
ur.setEntityId(EntityIdFactory.getByTypeAndUuid(entityType, entityId));
}
ur.setTransportEnabled(transportEnabled);
ur.setDbStorageEnabled(dbStorageEnabled);
ur.setReExecEnabled(reExecEnabled);
ur.setJsExecEnabled(jsExecEnabled);
ur.setTransportState(transportState);
ur.setDbStorageState(dbStorageState);
ur.setReExecState(reExecState);
ur.setJsExecState(jsExecState);
return ur;
}

5
dao/src/main/java/org/thingsboard/server/dao/usagerecord/ApiUsageStateServiceImpl.java

@ -19,6 +19,7 @@ import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.thingsboard.server.common.data.ApiUsageRecordKey;
import org.thingsboard.server.common.data.ApiUsageState;
import org.thingsboard.server.common.data.ApiUsageStateValue;
import org.thingsboard.server.common.data.EntityType;
import org.thingsboard.server.common.data.Tenant;
import org.thingsboard.server.common.data.TenantProfile;
@ -71,6 +72,10 @@ public class ApiUsageStateServiceImpl extends AbstractEntityService implements A
ApiUsageState apiUsageState = new ApiUsageState();
apiUsageState.setTenantId(tenantId);
apiUsageState.setEntityId(tenantId);
apiUsageState.setTransportState(ApiUsageStateValue.ENABLED);
apiUsageState.setReExecState(ApiUsageStateValue.ENABLED);
apiUsageState.setJsExecState(ApiUsageStateValue.ENABLED);
apiUsageState.setDbStorageState(ApiUsageStateValue.ENABLED);
apiUsageStateValidator.validate(apiUsageState, ApiUsageState::getTenantId);
ApiUsageState saved = apiUsageStateDao.save(apiUsageState.getTenantId(), apiUsageState);

8
dao/src/main/resources/sql/schema-entities-hsql.sql

@ -412,9 +412,9 @@ CREATE TABLE IF NOT EXISTS api_usage_state (
tenant_id uuid,
entity_type varchar(32),
entity_id uuid,
transport_enabled boolean,
db_storage_enabled boolean,
re_exec_enabled boolean,
js_exec_enabled boolean,
transport varchar(32),
db_storage varchar(32),
re_exec varchar(32),
js_exec varchar(32),
CONSTRAINT api_usage_state_unq_key UNIQUE (tenant_id, entity_id)
);

8
dao/src/main/resources/sql/schema-entities.sql

@ -438,10 +438,10 @@ CREATE TABLE IF NOT EXISTS api_usage_state (
tenant_id uuid,
entity_type varchar(32),
entity_id uuid,
transport_enabled boolean,
db_storage_enabled boolean,
re_exec_enabled boolean,
js_exec_enabled boolean,
transport varchar(32),
db_storage varchar(32),
re_exec varchar(32),
js_exec varchar(32),
CONSTRAINT api_usage_state_unq_key UNIQUE (tenant_id, entity_id)
);

3
dao/src/test/java/org/thingsboard/server/dao/service/BaseApiUsageStateServiceTest.java

@ -19,6 +19,7 @@ import org.junit.After;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import org.thingsboard.server.common.data.ApiUsageStateValue;
import org.thingsboard.server.common.data.Tenant;
import org.thingsboard.server.common.data.ApiUsageState;
import org.thingsboard.server.common.data.id.TenantId;
@ -53,7 +54,7 @@ public abstract class BaseApiUsageStateServiceTest extends AbstractServiceTest {
ApiUsageState apiUsageState = apiUsageStateService.findTenantApiUsageState(tenantId);
Assert.assertNotNull(apiUsageState);
Assert.assertTrue(apiUsageState.isTransportEnabled());
apiUsageState.setTransportEnabled(false);
apiUsageState.setTransportState(ApiUsageStateValue.DISABLED);
apiUsageState = apiUsageStateService.update(apiUsageState);
Assert.assertNotNull(apiUsageState);
apiUsageState = apiUsageStateService.findTenantApiUsageState(tenantId);

1
transport/coap/src/main/resources/tb-coap-transport.yml

@ -145,6 +145,7 @@ queue:
poll-interval: "${TB_QUEUE_CORE_POLL_INTERVAL_MS:25}"
partitions: "${TB_QUEUE_CORE_PARTITIONS:10}"
pack-processing-timeout: "${TB_QUEUE_CORE_PACK_PROCESSING_TIMEOUT_MS:60000}"
usage-stats-topic: "${TB_QUEUE_US_TOPIC:tb_usage_stats}"
stats:
enabled: "${TB_QUEUE_CORE_STATS_ENABLED:false}"
print-interval-ms: "${TB_QUEUE_CORE_STATS_PRINT_INTERVAL_MS:10000}"

1
transport/http/src/main/resources/tb-http-transport.yml

@ -138,6 +138,7 @@ queue:
poll-interval: "${TB_QUEUE_CORE_POLL_INTERVAL_MS:25}"
partitions: "${TB_QUEUE_CORE_PARTITIONS:10}"
pack-processing-timeout: "${TB_QUEUE_CORE_PACK_PROCESSING_TIMEOUT_MS:60000}"
usage-stats-topic: "${TB_QUEUE_US_TOPIC:tb_usage_stats}"
stats:
enabled: "${TB_QUEUE_CORE_STATS_ENABLED:false}"
print-interval-ms: "${TB_QUEUE_CORE_STATS_PRINT_INTERVAL_MS:10000}"

1
transport/mqtt/src/main/resources/tb-mqtt-transport.yml

@ -167,6 +167,7 @@ queue:
poll-interval: "${TB_QUEUE_CORE_POLL_INTERVAL_MS:25}"
partitions: "${TB_QUEUE_CORE_PARTITIONS:10}"
pack-processing-timeout: "${TB_QUEUE_CORE_PACK_PROCESSING_TIMEOUT_MS:60000}"
usage-stats-topic: "${TB_QUEUE_US_TOPIC:tb_usage_stats}"
stats:
enabled: "${TB_QUEUE_CORE_STATS_ENABLED:false}"
print-interval-ms: "${TB_QUEUE_CORE_STATS_PRINT_INTERVAL_MS:10000}"

Loading…
Cancel
Save