Browse Source

Fix conflicts

pull/9337/head
Igor Kulikov 3 years ago
parent
commit
215fddc957
  1. 5
      application/src/main/data/upgrade/3.6.0/schema_update.sql
  2. 5
      application/src/main/java/org/thingsboard/server/controller/BaseController.java
  3. 5
      application/src/main/java/org/thingsboard/server/service/apiusage/BaseApiUsageState.java
  4. 6
      application/src/main/java/org/thingsboard/server/service/install/SqlDatabaseUpgradeService.java
  5. 4
      application/src/main/java/org/thingsboard/server/service/mail/DefaultMailService.java
  6. 3
      application/src/test/java/org/thingsboard/server/controller/HomePageApiTest.java
  7. 1
      common/data/src/main/java/org/thingsboard/server/common/data/ApiFeature.java
  8. 4
      common/data/src/main/java/org/thingsboard/server/common/data/ApiUsageRecordKey.java
  9. 6
      common/data/src/main/java/org/thingsboard/server/common/data/ApiUsageState.java
  10. 2
      common/data/src/main/java/org/thingsboard/server/common/data/UsageInfo.java
  11. 3
      common/data/src/main/java/org/thingsboard/server/common/data/tenant/profile/DefaultTenantProfileConfiguration.java
  12. 20
      common/script/script-api/src/main/java/org/thingsboard/script/api/AbstractScriptInvokeService.java
  13. 17
      common/script/script-api/src/main/java/org/thingsboard/script/api/js/AbstractJsInvokeService.java
  14. 17
      common/script/script-api/src/main/java/org/thingsboard/script/api/tbel/DefaultTbelInvokeService.java
  15. 1
      dao/src/main/java/org/thingsboard/server/dao/model/ModelConstants.java
  16. 5
      dao/src/main/java/org/thingsboard/server/dao/model/sql/ApiUsageStateEntity.java
  17. 3
      dao/src/main/java/org/thingsboard/server/dao/usage/BasicUsageInfoService.java
  18. 3
      dao/src/main/java/org/thingsboard/server/dao/usagerecord/ApiUsageStateServiceImpl.java
  19. 1
      dao/src/main/resources/sql/schema-entities.sql
  20. 25
      ui-ngx/src/styles.scss

5
application/src/main/data/upgrade/3.6.0/schema_update.sql

@ -15,4 +15,7 @@
-- --
ALTER TABLE widget_type ALTER TABLE widget_type
ADD COLUMN IF NOT EXISTS tags text[]; ADD COLUMN IF NOT EXISTS tags text[];
ALTER TABLE api_usage_state ADD COLUMN IF NOT EXISTS tbel_exec varchar(32);
UPDATE api_usage_state SET tbel_exec = js_exec WHERE tbel_exec IS NULL;

5
application/src/main/java/org/thingsboard/server/controller/BaseController.java

@ -21,7 +21,7 @@ import com.google.common.util.concurrent.Futures;
import com.google.common.util.concurrent.ListenableFuture; import com.google.common.util.concurrent.ListenableFuture;
import com.google.common.util.concurrent.MoreExecutors; import com.google.common.util.concurrent.MoreExecutors;
import lombok.Getter; import lombok.Getter;
import lombok.extern.slf4j.Slf4j; import org.slf4j.Logger;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value; import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.MediaType; import org.springframework.http.MediaType;
@ -174,10 +174,11 @@ import static org.thingsboard.server.common.data.query.EntityKeyType.ENTITY_FIEL
import static org.thingsboard.server.controller.UserController.YOU_DON_T_HAVE_PERMISSION_TO_PERFORM_THIS_OPERATION; import static org.thingsboard.server.controller.UserController.YOU_DON_T_HAVE_PERMISSION_TO_PERFORM_THIS_OPERATION;
import static org.thingsboard.server.dao.service.Validator.validateId; import static org.thingsboard.server.dao.service.Validator.validateId;
@Slf4j
@TbCoreComponent @TbCoreComponent
public abstract class BaseController { public abstract class BaseController {
private final Logger log = org.slf4j.LoggerFactory.getLogger(getClass());
/*Swagger UI description*/ /*Swagger UI description*/
@Autowired @Autowired

5
application/src/main/java/org/thingsboard/server/service/apiusage/BaseApiUsageState.java

@ -145,6 +145,8 @@ public abstract class BaseApiUsageState {
return apiUsageState.getDbStorageState(); return apiUsageState.getDbStorageState();
case JS: case JS:
return apiUsageState.getJsExecState(); return apiUsageState.getJsExecState();
case TBEL:
return apiUsageState.getTbelExecState();
case EMAIL: case EMAIL:
return apiUsageState.getEmailExecState(); return apiUsageState.getEmailExecState();
case SMS: case SMS:
@ -171,6 +173,9 @@ public abstract class BaseApiUsageState {
case JS: case JS:
apiUsageState.setJsExecState(value); apiUsageState.setJsExecState(value);
break; break;
case TBEL:
apiUsageState.setTbelExecState(value);
break;
case EMAIL: case EMAIL:
apiUsageState.setEmailExecState(value); apiUsageState.setEmailExecState(value);
break; break;

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

@ -779,13 +779,15 @@ public class SqlDatabaseUpgradeService implements DatabaseEntitiesUpgradeService
break; break;
case "3.6.0": case "3.6.0":
try (Connection conn = DriverManager.getConnection(dbUrl, dbUserName, dbPassword)) { try (Connection conn = DriverManager.getConnection(dbUrl, dbUserName, dbPassword)) {
log.info("Updating schema ...");
if (isOldSchema(conn, 3006000)) { if (isOldSchema(conn, 3006000)) {
log.info("Updating schema ...");
schemaUpdateFile = Paths.get(installScripts.getDataDir(), "upgrade", "3.6.0", SCHEMA_UPDATE_SQL); schemaUpdateFile = Paths.get(installScripts.getDataDir(), "upgrade", "3.6.0", SCHEMA_UPDATE_SQL);
loadSql(schemaUpdateFile, conn); loadSql(schemaUpdateFile, conn);
conn.createStatement().execute("UPDATE tb_schema_settings SET schema_version = 3006001;"); conn.createStatement().execute("UPDATE tb_schema_settings SET schema_version = 3006001;");
log.info("Schema updated to version 3.6.1.");
} else {
log.info("Skip schema re-update to version 3.6.1. Use env flag 'SKIP_SCHEMA_VERSION_CHECK' to force the re-update.");
} }
log.info("Schema updated.");
} catch (Exception e) { } catch (Exception e) {
log.error("Failed updating schema!!!", e); log.error("Failed updating schema!!!", e);
} }

4
application/src/main/java/org/thingsboard/server/service/mail/DefaultMailService.java

@ -362,6 +362,8 @@ public class DefaultMailService implements MailService {
return valueInM + " out of " + thresholdInM + " allowed messages"; return valueInM + " out of " + thresholdInM + " allowed messages";
case JS_EXEC_COUNT: case JS_EXEC_COUNT:
return valueInM + " out of " + thresholdInM + " allowed JavaScript functions"; return valueInM + " out of " + thresholdInM + " allowed JavaScript functions";
case TBEL_EXEC_COUNT:
return valueInM + " out of " + thresholdInM + " allowed Tbel functions";
case RE_EXEC_COUNT: case RE_EXEC_COUNT:
return valueInM + " out of " + thresholdInM + " allowed Rule Engine messages"; return valueInM + " out of " + thresholdInM + " allowed Rule Engine messages";
case EMAIL_EXEC_COUNT: case EMAIL_EXEC_COUNT:
@ -382,6 +384,8 @@ public class DefaultMailService implements MailService {
return recordState.getValueAsString() + " messages"; return recordState.getValueAsString() + " messages";
case JS_EXEC_COUNT: case JS_EXEC_COUNT:
return "JavaScript functions " + recordState.getValueAsString() + " times"; return "JavaScript functions " + recordState.getValueAsString() + " times";
case TBEL_EXEC_COUNT:
return "TBEL functions " + recordState.getValueAsString() + " times";
case RE_EXEC_COUNT: case RE_EXEC_COUNT:
return recordState.getValueAsString() + " Rule Engine messages"; return recordState.getValueAsString() + " Rule Engine messages";
case EMAIL_EXEC_COUNT: case EMAIL_EXEC_COUNT:

3
application/src/test/java/org/thingsboard/server/controller/HomePageApiTest.java

@ -417,6 +417,9 @@ public class HomePageApiTest extends AbstractControllerTest {
Assert.assertEquals(0, usageInfo.getJsExecutions()); Assert.assertEquals(0, usageInfo.getJsExecutions());
Assert.assertEquals(configuration.getMaxJSExecutions(), usageInfo.getMaxJsExecutions()); Assert.assertEquals(configuration.getMaxJSExecutions(), usageInfo.getMaxJsExecutions());
Assert.assertEquals(0, usageInfo.getTbelExecutions());
Assert.assertEquals(configuration.getMaxTbelExecutions(), usageInfo.getMaxTbelExecutions());
Assert.assertEquals(0, usageInfo.getEmails()); Assert.assertEquals(0, usageInfo.getEmails());
Assert.assertEquals(configuration.getMaxEmails(), usageInfo.getMaxEmails()); Assert.assertEquals(configuration.getMaxEmails(), usageInfo.getMaxEmails());

1
common/data/src/main/java/org/thingsboard/server/common/data/ApiFeature.java

@ -22,6 +22,7 @@ public enum ApiFeature {
DB("dbApiState", "Telemetry persistence"), DB("dbApiState", "Telemetry persistence"),
RE("ruleEngineApiState", "Rule Engine execution"), RE("ruleEngineApiState", "Rule Engine execution"),
JS("jsExecutionApiState", "JavaScript functions execution"), JS("jsExecutionApiState", "JavaScript functions execution"),
TBEL("tbelExecutionApiState", "Tbel functions execution"),
EMAIL("emailApiState", "Email messages"), EMAIL("emailApiState", "Email messages"),
SMS("smsApiState", "SMS messages"), SMS("smsApiState", "SMS messages"),
ALARM("alarmApiState", "Alarms"); ALARM("alarmApiState", "Alarms");

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

@ -24,6 +24,7 @@ public enum ApiUsageRecordKey {
STORAGE_DP_COUNT(ApiFeature.DB, "storageDataPointsCount", "storageDataPointsLimit", "data point"), STORAGE_DP_COUNT(ApiFeature.DB, "storageDataPointsCount", "storageDataPointsLimit", "data point"),
RE_EXEC_COUNT(ApiFeature.RE, "ruleEngineExecutionCount", "ruleEngineExecutionLimit", "Rule Engine execution"), RE_EXEC_COUNT(ApiFeature.RE, "ruleEngineExecutionCount", "ruleEngineExecutionLimit", "Rule Engine execution"),
JS_EXEC_COUNT(ApiFeature.JS, "jsExecutionCount", "jsExecutionLimit", "JavaScript execution"), JS_EXEC_COUNT(ApiFeature.JS, "jsExecutionCount", "jsExecutionLimit", "JavaScript execution"),
TBEL_EXEC_COUNT(ApiFeature.TBEL, "tbelExecutionCount", "tbelExecutionLimit", "Tbel execution"),
EMAIL_EXEC_COUNT(ApiFeature.EMAIL, "emailCount", "emailLimit", "email message"), EMAIL_EXEC_COUNT(ApiFeature.EMAIL, "emailCount", "emailLimit", "email message"),
SMS_EXEC_COUNT(ApiFeature.SMS, "smsCount", "smsLimit", "SMS message"), SMS_EXEC_COUNT(ApiFeature.SMS, "smsCount", "smsLimit", "SMS message"),
CREATED_ALARMS_COUNT(ApiFeature.ALARM, "createdAlarmsCount", "createdAlarmsLimit", "alarm"), CREATED_ALARMS_COUNT(ApiFeature.ALARM, "createdAlarmsCount", "createdAlarmsLimit", "alarm"),
@ -31,6 +32,7 @@ public enum ApiUsageRecordKey {
INACTIVE_DEVICES("inactiveDevicesCount"); INACTIVE_DEVICES("inactiveDevicesCount");
private static final ApiUsageRecordKey[] JS_RECORD_KEYS = {JS_EXEC_COUNT}; private static final ApiUsageRecordKey[] JS_RECORD_KEYS = {JS_EXEC_COUNT};
private static final ApiUsageRecordKey[] TBEL_RECORD_KEYS = {TBEL_EXEC_COUNT};
private static final ApiUsageRecordKey[] RE_RECORD_KEYS = {RE_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[] DB_RECORD_KEYS = {STORAGE_DP_COUNT};
private static final ApiUsageRecordKey[] TRANSPORT_RECORD_KEYS = {TRANSPORT_MSG_COUNT, TRANSPORT_DP_COUNT}; private static final ApiUsageRecordKey[] TRANSPORT_RECORD_KEYS = {TRANSPORT_MSG_COUNT, TRANSPORT_DP_COUNT};
@ -75,6 +77,8 @@ public enum ApiUsageRecordKey {
return RE_RECORD_KEYS; return RE_RECORD_KEYS;
case JS: case JS:
return JS_RECORD_KEYS; return JS_RECORD_KEYS;
case TBEL:
return TBEL_RECORD_KEYS;
case EMAIL: case EMAIL:
return EMAIL_RECORD_KEYS; return EMAIL_RECORD_KEYS;
case SMS: case SMS:

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

@ -37,6 +37,7 @@ public class ApiUsageState extends BaseData<ApiUsageStateId> implements HasTenan
private ApiUsageStateValue dbStorageState; private ApiUsageStateValue dbStorageState;
private ApiUsageStateValue reExecState; private ApiUsageStateValue reExecState;
private ApiUsageStateValue jsExecState; private ApiUsageStateValue jsExecState;
private ApiUsageStateValue tbelExecState;
private ApiUsageStateValue emailExecState; private ApiUsageStateValue emailExecState;
private ApiUsageStateValue smsExecState; private ApiUsageStateValue smsExecState;
private ApiUsageStateValue alarmExecState; private ApiUsageStateValue alarmExecState;
@ -57,6 +58,7 @@ public class ApiUsageState extends BaseData<ApiUsageStateId> implements HasTenan
this.dbStorageState = ur.getDbStorageState(); this.dbStorageState = ur.getDbStorageState();
this.reExecState = ur.getReExecState(); this.reExecState = ur.getReExecState();
this.jsExecState = ur.getJsExecState(); this.jsExecState = ur.getJsExecState();
this.tbelExecState = ur.getTbelExecState();
this.emailExecState = ur.getEmailExecState(); this.emailExecState = ur.getEmailExecState();
this.smsExecState = ur.getSmsExecState(); this.smsExecState = ur.getSmsExecState();
this.alarmExecState = ur.getAlarmExecState(); this.alarmExecState = ur.getAlarmExecState();
@ -78,6 +80,10 @@ public class ApiUsageState extends BaseData<ApiUsageStateId> implements HasTenan
return !ApiUsageStateValue.DISABLED.equals(jsExecState); return !ApiUsageStateValue.DISABLED.equals(jsExecState);
} }
public boolean isTbelExecEnabled() {
return !ApiUsageStateValue.DISABLED.equals(tbelExecState);
}
public boolean isEmailSendEnabled(){ public boolean isEmailSendEnabled(){
return !ApiUsageStateValue.DISABLED.equals(emailExecState); return !ApiUsageStateValue.DISABLED.equals(emailExecState);
} }

2
common/data/src/main/java/org/thingsboard/server/common/data/UsageInfo.java

@ -33,7 +33,9 @@ public class UsageInfo {
private long transportMessages; private long transportMessages;
private long maxTransportMessages; private long maxTransportMessages;
private long jsExecutions; private long jsExecutions;
private long tbelExecutions;
private long maxJsExecutions; private long maxJsExecutions;
private long maxTbelExecutions;
private long emails; private long emails;
private long maxEmails; private long maxEmails;
private long sms; private long sms;

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

@ -56,6 +56,7 @@ public class DefaultTenantProfileConfiguration implements TenantProfileConfigura
private long maxTransportDataPoints; private long maxTransportDataPoints;
private long maxREExecutions; private long maxREExecutions;
private long maxJSExecutions; private long maxJSExecutions;
private long maxTbelExecutions;
private long maxDPStorageDays; private long maxDPStorageDays;
private int maxRuleNodeExecutionsPerMessage; private int maxRuleNodeExecutionsPerMessage;
private long maxEmails; private long maxEmails;
@ -94,6 +95,8 @@ public class DefaultTenantProfileConfiguration implements TenantProfileConfigura
return maxTransportDataPoints; return maxTransportDataPoints;
case JS_EXEC_COUNT: case JS_EXEC_COUNT:
return maxJSExecutions; return maxJSExecutions;
case TBEL_EXEC_COUNT:
return maxTbelExecutions;
case RE_EXEC_COUNT: case RE_EXEC_COUNT:
return maxREExecutions; return maxREExecutions;
case STORAGE_DP_COUNT: case STORAGE_DP_COUNT:

20
common/script/script-api/src/main/java/org/thingsboard/script/api/AbstractScriptInvokeService.java

@ -25,11 +25,8 @@ import org.thingsboard.common.util.ThingsBoardThreadFactory;
import org.thingsboard.server.common.data.ApiUsageRecordKey; import org.thingsboard.server.common.data.ApiUsageRecordKey;
import org.thingsboard.server.common.data.id.CustomerId; import org.thingsboard.server.common.data.id.CustomerId;
import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.common.data.id.TenantId;
import org.thingsboard.server.common.stats.TbApiUsageReportClient;
import org.thingsboard.server.common.stats.TbApiUsageStateClient;
import java.util.Map; import java.util.Map;
import java.util.Optional;
import java.util.UUID; import java.util.UUID;
import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.Executor; import java.util.concurrent.Executor;
@ -45,9 +42,6 @@ import static java.lang.String.format;
public abstract class AbstractScriptInvokeService implements ScriptInvokeService { public abstract class AbstractScriptInvokeService implements ScriptInvokeService {
protected final Map<UUID, BlockedScriptInfo> disabledScripts = new ConcurrentHashMap<>(); protected final Map<UUID, BlockedScriptInfo> disabledScripts = new ConcurrentHashMap<>();
private final Optional<TbApiUsageStateClient> apiUsageStateClient;
private final Optional<TbApiUsageReportClient> apiUsageReportClient;
private final AtomicInteger pushedMsgs = new AtomicInteger(0); private final AtomicInteger pushedMsgs = new AtomicInteger(0);
private final AtomicInteger invokeMsgs = new AtomicInteger(0); private final AtomicInteger invokeMsgs = new AtomicInteger(0);
private final AtomicInteger evalMsgs = new AtomicInteger(0); private final AtomicInteger evalMsgs = new AtomicInteger(0);
@ -59,11 +53,6 @@ public abstract class AbstractScriptInvokeService implements ScriptInvokeService
protected ScheduledExecutorService timeoutExecutorService; protected ScheduledExecutorService timeoutExecutorService;
protected AbstractScriptInvokeService(Optional<TbApiUsageStateClient> apiUsageStateClient, Optional<TbApiUsageReportClient> apiUsageReportClient) {
this.apiUsageStateClient = apiUsageStateClient;
this.apiUsageReportClient = apiUsageReportClient;
}
protected long getMaxEvalRequestsTimeout() { protected long getMaxEvalRequestsTimeout() {
return getMaxInvokeRequestsTimeout(); return getMaxInvokeRequestsTimeout();
} }
@ -88,6 +77,9 @@ public abstract class AbstractScriptInvokeService implements ScriptInvokeService
protected abstract boolean isScriptPresent(UUID scriptId); protected abstract boolean isScriptPresent(UUID scriptId);
protected abstract boolean isExecEnabled(TenantId tenantId);
protected abstract void reportExecution(TenantId tenantId, CustomerId customerId);
protected abstract ListenableFuture<UUID> doEvalScript(TenantId tenantId, ScriptType scriptType, String scriptBody, UUID scriptId, String[] argNames); protected abstract ListenableFuture<UUID> doEvalScript(TenantId tenantId, ScriptType scriptType, String scriptBody, UUID scriptId, String[] argNames);
protected abstract TbScriptExecutionTask doInvokeFunction(UUID scriptId, Object[] args); protected abstract TbScriptExecutionTask doInvokeFunction(UUID scriptId, Object[] args);
@ -122,7 +114,7 @@ public abstract class AbstractScriptInvokeService implements ScriptInvokeService
@Override @Override
public ListenableFuture<UUID> eval(TenantId tenantId, ScriptType scriptType, String scriptBody, String... argNames) { public ListenableFuture<UUID> eval(TenantId tenantId, ScriptType scriptType, String scriptBody, String... argNames) {
if (!apiUsageStateClient.isPresent() || apiUsageStateClient.get().getApiUsageState(tenantId).isJsExecEnabled()) { if (isExecEnabled(tenantId)) {
if (scriptBodySizeExceeded(scriptBody)) { if (scriptBodySizeExceeded(scriptBody)) {
return error(format("Script body exceeds maximum allowed size of %s symbols", getMaxScriptBodySize())); return error(format("Script body exceeds maximum allowed size of %s symbols", getMaxScriptBodySize()));
} }
@ -137,7 +129,7 @@ public abstract class AbstractScriptInvokeService implements ScriptInvokeService
@Override @Override
public ListenableFuture<Object> invokeScript(TenantId tenantId, CustomerId customerId, UUID scriptId, Object... args) { public ListenableFuture<Object> invokeScript(TenantId tenantId, CustomerId customerId, UUID scriptId, Object... args) {
if (!apiUsageStateClient.isPresent() || apiUsageStateClient.get().getApiUsageState(tenantId).isJsExecEnabled()) { if (isExecEnabled(tenantId)) {
if (!isScriptPresent(scriptId)) { if (!isScriptPresent(scriptId)) {
return error("No compiled script found for scriptId: [" + scriptId + "]!"); return error("No compiled script found for scriptId: [" + scriptId + "]!");
} }
@ -148,7 +140,7 @@ public abstract class AbstractScriptInvokeService implements ScriptInvokeService
)); ));
return Futures.immediateFailedFuture(handleScriptException(scriptId, null, t)); return Futures.immediateFailedFuture(handleScriptException(scriptId, null, t));
} }
apiUsageReportClient.ifPresent(client -> client.report(tenantId, customerId, ApiUsageRecordKey.JS_EXEC_COUNT, 1)); reportExecution(tenantId, customerId);
pushedMsgs.incrementAndGet(); pushedMsgs.incrementAndGet();
log.trace("[{}] InvokeScript uuid {} with timeout {}ms", tenantId, scriptId, getMaxInvokeRequestsTimeout()); log.trace("[{}] InvokeScript uuid {} with timeout {}ms", tenantId, scriptId, getMaxInvokeRequestsTimeout());
var task = doInvokeFunction(scriptId, args); var task = doInvokeFunction(scriptId, args);

17
common/script/script-api/src/main/java/org/thingsboard/script/api/js/AbstractJsInvokeService.java

@ -23,6 +23,8 @@ import org.springframework.beans.factory.annotation.Value;
import org.thingsboard.script.api.AbstractScriptInvokeService; import org.thingsboard.script.api.AbstractScriptInvokeService;
import org.thingsboard.script.api.RuleNodeScriptFactory; import org.thingsboard.script.api.RuleNodeScriptFactory;
import org.thingsboard.script.api.ScriptType; import org.thingsboard.script.api.ScriptType;
import org.thingsboard.server.common.data.ApiUsageRecordKey;
import org.thingsboard.server.common.data.id.CustomerId;
import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.common.data.id.TenantId;
import org.thingsboard.server.common.stats.TbApiUsageReportClient; import org.thingsboard.server.common.stats.TbApiUsageReportClient;
import org.thingsboard.server.common.stats.TbApiUsageStateClient; import org.thingsboard.server.common.stats.TbApiUsageStateClient;
@ -39,6 +41,8 @@ import java.util.concurrent.ConcurrentHashMap;
public abstract class AbstractJsInvokeService extends AbstractScriptInvokeService implements JsInvokeService { public abstract class AbstractJsInvokeService extends AbstractScriptInvokeService implements JsInvokeService {
protected final Map<UUID, JsScriptInfo> scriptInfoMap = new ConcurrentHashMap<>(); protected final Map<UUID, JsScriptInfo> scriptInfoMap = new ConcurrentHashMap<>();
private final Optional<TbApiUsageStateClient> apiUsageStateClient;
private final Optional<TbApiUsageReportClient> apiUsageReportClient;
@Getter @Getter
@Value("${js.max_total_args_size:100000}") @Value("${js.max_total_args_size:100000}")
@ -51,7 +55,8 @@ public abstract class AbstractJsInvokeService extends AbstractScriptInvokeServic
private long maxScriptBodySize; private long maxScriptBodySize;
protected AbstractJsInvokeService(Optional<TbApiUsageStateClient> apiUsageStateClient, Optional<TbApiUsageReportClient> apiUsageReportClient) { protected AbstractJsInvokeService(Optional<TbApiUsageStateClient> apiUsageStateClient, Optional<TbApiUsageReportClient> apiUsageReportClient) {
super(apiUsageStateClient, apiUsageReportClient); this.apiUsageStateClient = apiUsageStateClient;
this.apiUsageReportClient = apiUsageReportClient;
} }
@Override @Override
@ -59,6 +64,16 @@ public abstract class AbstractJsInvokeService extends AbstractScriptInvokeServic
return scriptInfoMap.containsKey(scriptId); return scriptInfoMap.containsKey(scriptId);
} }
@Override
protected boolean isExecEnabled(TenantId tenantId) {
return !apiUsageStateClient.isPresent() || apiUsageStateClient.get().getApiUsageState(tenantId).isJsExecEnabled();
}
@Override
protected void reportExecution(TenantId tenantId, CustomerId customerId) {
apiUsageReportClient.ifPresent(client -> client.report(tenantId, customerId, ApiUsageRecordKey.JS_EXEC_COUNT, 1));
}
@Override @Override
protected JsScriptExecutionTask doInvokeFunction(UUID scriptId, Object[] args) { protected JsScriptExecutionTask doInvokeFunction(UUID scriptId, Object[] args) {
return new JsScriptExecutionTask(doInvokeFunction(scriptId, scriptInfoMap.get(scriptId), args)); return new JsScriptExecutionTask(doInvokeFunction(scriptId, scriptInfoMap.get(scriptId), args));

17
common/script/script-api/src/main/java/org/thingsboard/script/api/tbel/DefaultTbelInvokeService.java

@ -40,6 +40,8 @@ import org.thingsboard.common.util.ThingsBoardExecutors;
import org.thingsboard.script.api.AbstractScriptInvokeService; import org.thingsboard.script.api.AbstractScriptInvokeService;
import org.thingsboard.script.api.ScriptType; import org.thingsboard.script.api.ScriptType;
import org.thingsboard.script.api.TbScriptException; import org.thingsboard.script.api.TbScriptException;
import org.thingsboard.server.common.data.ApiUsageRecordKey;
import org.thingsboard.server.common.data.id.CustomerId;
import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.common.data.id.TenantId;
import org.thingsboard.server.common.stats.TbApiUsageReportClient; import org.thingsboard.server.common.stats.TbApiUsageReportClient;
import org.thingsboard.server.common.stats.TbApiUsageStateClient; import org.thingsboard.server.common.stats.TbApiUsageStateClient;
@ -69,6 +71,8 @@ public class DefaultTbelInvokeService extends AbstractScriptInvokeService implem
protected Cache<String, Serializable> compiledScriptsCache; protected Cache<String, Serializable> compiledScriptsCache;
private SandboxedParserConfiguration parserConfig; private SandboxedParserConfiguration parserConfig;
private final Optional<TbApiUsageStateClient> apiUsageStateClient;
private final Optional<TbApiUsageReportClient> apiUsageReportClient;
@Getter @Getter
@Value("${tbel.max_total_args_size:100000}") @Value("${tbel.max_total_args_size:100000}")
@ -110,7 +114,8 @@ public class DefaultTbelInvokeService extends AbstractScriptInvokeService implem
private final Lock lock = new ReentrantLock(); private final Lock lock = new ReentrantLock();
protected DefaultTbelInvokeService(Optional<TbApiUsageStateClient> apiUsageStateClient, Optional<TbApiUsageReportClient> apiUsageReportClient) { protected DefaultTbelInvokeService(Optional<TbApiUsageStateClient> apiUsageStateClient, Optional<TbApiUsageReportClient> apiUsageReportClient) {
super(apiUsageStateClient, apiUsageReportClient); this.apiUsageStateClient = apiUsageStateClient;
this.apiUsageReportClient = apiUsageReportClient;
} }
@Scheduled(fixedDelayString = "${tbel.stats.print_interval_ms:10000}") @Scheduled(fixedDelayString = "${tbel.stats.print_interval_ms:10000}")
@ -167,6 +172,16 @@ public class DefaultTbelInvokeService extends AbstractScriptInvokeService implem
return scriptIdToHash.containsKey(scriptId); return scriptIdToHash.containsKey(scriptId);
} }
@Override
protected boolean isExecEnabled(TenantId tenantId) {
return !apiUsageStateClient.isPresent() || apiUsageStateClient.get().getApiUsageState(tenantId).isTbelExecEnabled();
}
@Override
protected void reportExecution(TenantId tenantId, CustomerId customerId) {
apiUsageReportClient.ifPresent(client -> client.report(tenantId, customerId, ApiUsageRecordKey.TBEL_EXEC_COUNT, 1));
}
@Override @Override
protected ListenableFuture<UUID> doEvalScript(TenantId tenantId, ScriptType scriptType, String scriptBody, UUID scriptId, String[] argNames) { protected ListenableFuture<UUID> doEvalScript(TenantId tenantId, ScriptType scriptType, String scriptBody, UUID scriptId, String[] argNames) {
return executor.submit(() -> { return executor.submit(() -> {

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

@ -482,6 +482,7 @@ public class ModelConstants {
public static final String API_USAGE_STATE_DB_STORAGE_COLUMN = "db_storage"; 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_RE_EXEC_COLUMN = "re_exec";
public static final String API_USAGE_STATE_JS_EXEC_COLUMN = "js_exec"; public static final String API_USAGE_STATE_JS_EXEC_COLUMN = "js_exec";
public static final String API_USAGE_STATE_TBEL_EXEC_COLUMN = "tbel_exec";
public static final String API_USAGE_STATE_EMAIL_EXEC_COLUMN = "email_exec"; public static final String API_USAGE_STATE_EMAIL_EXEC_COLUMN = "email_exec";
public static final String API_USAGE_STATE_SMS_EXEC_COLUMN = "sms_exec"; public static final String API_USAGE_STATE_SMS_EXEC_COLUMN = "sms_exec";
public static final String API_USAGE_STATE_ALARM_EXEC_COLUMN = "alarm_exec"; public static final String API_USAGE_STATE_ALARM_EXEC_COLUMN = "alarm_exec";

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

@ -64,6 +64,9 @@ public class ApiUsageStateEntity extends BaseSqlEntity<ApiUsageState> implements
@Column(name = ModelConstants.API_USAGE_STATE_JS_EXEC_COLUMN) @Column(name = ModelConstants.API_USAGE_STATE_JS_EXEC_COLUMN)
private ApiUsageStateValue jsExecState = ApiUsageStateValue.ENABLED; private ApiUsageStateValue jsExecState = ApiUsageStateValue.ENABLED;
@Enumerated(EnumType.STRING) @Enumerated(EnumType.STRING)
@Column(name = ModelConstants.API_USAGE_STATE_TBEL_EXEC_COLUMN)
private ApiUsageStateValue tbelExecState = ApiUsageStateValue.ENABLED;
@Enumerated(EnumType.STRING)
@Column(name = ModelConstants.API_USAGE_STATE_EMAIL_EXEC_COLUMN) @Column(name = ModelConstants.API_USAGE_STATE_EMAIL_EXEC_COLUMN)
private ApiUsageStateValue emailExecState = ApiUsageStateValue.ENABLED; private ApiUsageStateValue emailExecState = ApiUsageStateValue.ENABLED;
@Enumerated(EnumType.STRING) @Enumerated(EnumType.STRING)
@ -92,6 +95,7 @@ public class ApiUsageStateEntity extends BaseSqlEntity<ApiUsageState> implements
this.dbStorageState = ur.getDbStorageState(); this.dbStorageState = ur.getDbStorageState();
this.reExecState = ur.getReExecState(); this.reExecState = ur.getReExecState();
this.jsExecState = ur.getJsExecState(); this.jsExecState = ur.getJsExecState();
this.tbelExecState = ur.getTbelExecState();
this.emailExecState = ur.getEmailExecState(); this.emailExecState = ur.getEmailExecState();
this.smsExecState = ur.getSmsExecState(); this.smsExecState = ur.getSmsExecState();
this.alarmExecState = ur.getAlarmExecState(); this.alarmExecState = ur.getAlarmExecState();
@ -111,6 +115,7 @@ public class ApiUsageStateEntity extends BaseSqlEntity<ApiUsageState> implements
ur.setDbStorageState(dbStorageState); ur.setDbStorageState(dbStorageState);
ur.setReExecState(reExecState); ur.setReExecState(reExecState);
ur.setJsExecState(jsExecState); ur.setJsExecState(jsExecState);
ur.setTbelExecState(tbelExecState);
ur.setEmailExecState(emailExecState); ur.setEmailExecState(emailExecState);
ur.setSmsExecState(smsExecState); ur.setSmsExecState(smsExecState);
ur.setAlarmExecState(alarmExecState); ur.setAlarmExecState(alarmExecState);

3
dao/src/main/java/org/thingsboard/server/dao/usage/BasicUsageInfoService.java

@ -67,6 +67,7 @@ public class BasicUsageInfoService implements UsageInfoService {
usageInfo.setMaxAlarms(profileConfiguration.getMaxCreatedAlarms()); usageInfo.setMaxAlarms(profileConfiguration.getMaxCreatedAlarms());
usageInfo.setMaxTransportMessages(profileConfiguration.getMaxTransportMessages()); usageInfo.setMaxTransportMessages(profileConfiguration.getMaxTransportMessages());
usageInfo.setMaxJsExecutions(profileConfiguration.getMaxJSExecutions()); usageInfo.setMaxJsExecutions(profileConfiguration.getMaxJSExecutions());
usageInfo.setMaxTbelExecutions(profileConfiguration.getMaxTbelExecutions());
usageInfo.setMaxEmails(profileConfiguration.getMaxEmails()); usageInfo.setMaxEmails(profileConfiguration.getMaxEmails());
usageInfo.setMaxSms(profileConfiguration.getMaxSms()); usageInfo.setMaxSms(profileConfiguration.getMaxSms());
usageInfo.setSmsEnabled(profileConfiguration.getSmsEnabled()); usageInfo.setSmsEnabled(profileConfiguration.getSmsEnabled());
@ -75,6 +76,7 @@ public class BasicUsageInfoService implements UsageInfoService {
Collection<String> keys = Arrays.asList( Collection<String> keys = Arrays.asList(
ApiUsageRecordKey.TRANSPORT_MSG_COUNT.getApiCountKey(), ApiUsageRecordKey.TRANSPORT_MSG_COUNT.getApiCountKey(),
ApiUsageRecordKey.JS_EXEC_COUNT.getApiCountKey(), ApiUsageRecordKey.JS_EXEC_COUNT.getApiCountKey(),
ApiUsageRecordKey.TBEL_EXEC_COUNT.getApiCountKey(),
ApiUsageRecordKey.EMAIL_EXEC_COUNT.getApiCountKey(), ApiUsageRecordKey.EMAIL_EXEC_COUNT.getApiCountKey(),
ApiUsageRecordKey.SMS_EXEC_COUNT.getApiCountKey(), ApiUsageRecordKey.SMS_EXEC_COUNT.getApiCountKey(),
ApiUsageRecordKey.CREATED_ALARMS_COUNT.getApiCountKey()); ApiUsageRecordKey.CREATED_ALARMS_COUNT.getApiCountKey());
@ -82,6 +84,7 @@ public class BasicUsageInfoService implements UsageInfoService {
List<TsKvEntry> entries = tsService.findLatest(tenantId, apiUsageState.getId(), keys).get(); List<TsKvEntry> entries = tsService.findLatest(tenantId, apiUsageState.getId(), keys).get();
usageInfo.setTransportMessages(getLongValueFromTsEntries(entries, ApiUsageRecordKey.TRANSPORT_MSG_COUNT.getApiCountKey())); usageInfo.setTransportMessages(getLongValueFromTsEntries(entries, ApiUsageRecordKey.TRANSPORT_MSG_COUNT.getApiCountKey()));
usageInfo.setJsExecutions(getLongValueFromTsEntries(entries, ApiUsageRecordKey.JS_EXEC_COUNT.getApiCountKey())); usageInfo.setJsExecutions(getLongValueFromTsEntries(entries, ApiUsageRecordKey.JS_EXEC_COUNT.getApiCountKey()));
usageInfo.setTbelExecutions(getLongValueFromTsEntries(entries, ApiUsageRecordKey.TBEL_EXEC_COUNT.getApiCountKey()));
usageInfo.setEmails(getLongValueFromTsEntries(entries, ApiUsageRecordKey.EMAIL_EXEC_COUNT.getApiCountKey())); usageInfo.setEmails(getLongValueFromTsEntries(entries, ApiUsageRecordKey.EMAIL_EXEC_COUNT.getApiCountKey()));
usageInfo.setSms(getLongValueFromTsEntries(entries, ApiUsageRecordKey.SMS_EXEC_COUNT.getApiCountKey())); usageInfo.setSms(getLongValueFromTsEntries(entries, ApiUsageRecordKey.SMS_EXEC_COUNT.getApiCountKey()));
usageInfo.setAlarms(getLongValueFromTsEntries(entries, ApiUsageRecordKey.CREATED_ALARMS_COUNT.getApiCountKey())); usageInfo.setAlarms(getLongValueFromTsEntries(entries, ApiUsageRecordKey.CREATED_ALARMS_COUNT.getApiCountKey()));

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

@ -93,6 +93,7 @@ public class ApiUsageStateServiceImpl extends AbstractEntityService implements A
apiUsageState.setTransportState(ApiUsageStateValue.ENABLED); apiUsageState.setTransportState(ApiUsageStateValue.ENABLED);
apiUsageState.setReExecState(ApiUsageStateValue.ENABLED); apiUsageState.setReExecState(ApiUsageStateValue.ENABLED);
apiUsageState.setJsExecState(ApiUsageStateValue.ENABLED); apiUsageState.setJsExecState(ApiUsageStateValue.ENABLED);
apiUsageState.setTbelExecState(ApiUsageStateValue.ENABLED);
apiUsageState.setDbStorageState(ApiUsageStateValue.ENABLED); apiUsageState.setDbStorageState(ApiUsageStateValue.ENABLED);
apiUsageState.setSmsExecState(ApiUsageStateValue.ENABLED); apiUsageState.setSmsExecState(ApiUsageStateValue.ENABLED);
apiUsageState.setEmailExecState(ApiUsageStateValue.ENABLED); apiUsageState.setEmailExecState(ApiUsageStateValue.ENABLED);
@ -110,6 +111,8 @@ public class ApiUsageStateServiceImpl extends AbstractEntityService implements A
new StringDataEntry(ApiFeature.RE.getApiStateKey(), ApiUsageStateValue.ENABLED.name()))); new StringDataEntry(ApiFeature.RE.getApiStateKey(), ApiUsageStateValue.ENABLED.name())));
apiUsageStates.add(new BasicTsKvEntry(saved.getCreatedTime(), apiUsageStates.add(new BasicTsKvEntry(saved.getCreatedTime(),
new StringDataEntry(ApiFeature.JS.getApiStateKey(), ApiUsageStateValue.ENABLED.name()))); new StringDataEntry(ApiFeature.JS.getApiStateKey(), ApiUsageStateValue.ENABLED.name())));
apiUsageStates.add(new BasicTsKvEntry(saved.getCreatedTime(),
new StringDataEntry(ApiFeature.TBEL.getApiStateKey(), ApiUsageStateValue.ENABLED.name())));
apiUsageStates.add(new BasicTsKvEntry(saved.getCreatedTime(), apiUsageStates.add(new BasicTsKvEntry(saved.getCreatedTime(),
new StringDataEntry(ApiFeature.EMAIL.getApiStateKey(), ApiUsageStateValue.ENABLED.name()))); new StringDataEntry(ApiFeature.EMAIL.getApiStateKey(), ApiUsageStateValue.ENABLED.name())));
apiUsageStates.add(new BasicTsKvEntry(saved.getCreatedTime(), apiUsageStates.add(new BasicTsKvEntry(saved.getCreatedTime(),

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

@ -697,6 +697,7 @@ CREATE TABLE IF NOT EXISTS api_usage_state (
db_storage varchar(32), db_storage varchar(32),
re_exec varchar(32), re_exec varchar(32),
js_exec varchar(32), js_exec varchar(32),
tbel_exec varchar(32),
email_exec varchar(32), email_exec varchar(32),
sms_exec varchar(32), sms_exec varchar(32),
alarm_exec varchar(32), alarm_exec varchar(32),

25
ui-ngx/src/styles.scss

@ -738,16 +738,21 @@ mat-label {
} }
} }
.mat-mdc-row { .mat-mdc-table {
transition: background-color .2s; .mat-mdc-row {
&:hover:not(.tb-current-entity) { transition: background-color .2s;
background-color: #f4f4f4;
} &:hover:not(.tb-current-entity) {
&.tb-current-entity { background-color: #f4f4f4;
background-color: #e9e9e9; }
}
&.tb-pointer { &.tb-current-entity {
cursor: pointer; background-color: #e9e9e9;
}
&.tb-pointer {
cursor: pointer;
}
} }
} }

Loading…
Cancel
Save