Refactor MVEL -> TBEL

This commit is contained in:
Igor Kulikov 2022-11-22 16:38:01 +02:00
parent d8f87c45c8
commit d10f64c348
42 changed files with 252 additions and 173 deletions

View File

@ -57,9 +57,9 @@
"name": "Log RPC from Device",
"debugMode": false,
"configuration": {
"scriptLang": "MVEL",
"scriptLang": "TBEL",
"jsScript": "return '\\nIncoming message:\\n' + JSON.stringify(msg) + '\\nIncoming metadata:\\n' + JSON.stringify(metadata);",
"mvelScript": "return '\\nIncoming message:\\n' + JSON.stringify(msg) + '\\nIncoming metadata:\\n' + JSON.stringify(metadata);"
"tbelScript": "return '\\nIncoming message:\\n' + JSON.stringify(msg) + '\\nIncoming metadata:\\n' + JSON.stringify(metadata);"
}
},
{
@ -71,9 +71,9 @@
"name": "Log Other",
"debugMode": false,
"configuration": {
"scriptLang": "MVEL",
"scriptLang": "TBEL",
"jsScript": "return '\\nIncoming message:\\n' + JSON.stringify(msg) + '\\nIncoming metadata:\\n' + JSON.stringify(metadata);",
"mvelScript": "return '\\nIncoming message:\\n' + JSON.stringify(msg) + '\\nIncoming metadata:\\n' + JSON.stringify(metadata);"
"tbelScript": "return '\\nIncoming message:\\n' + JSON.stringify(msg) + '\\nIncoming metadata:\\n' + JSON.stringify(metadata);"
}
},
{

View File

@ -70,9 +70,9 @@
"name": "Log RPC from Device",
"debugMode": false,
"configuration": {
"scriptLang": "MVEL",
"scriptLang": "TBEL",
"jsScript": "return '\\nIncoming message:\\n' + JSON.stringify(msg) + '\\nIncoming metadata:\\n' + JSON.stringify(metadata);",
"mvelScript": "return '\\nIncoming message:\\n' + JSON.stringify(msg) + '\\nIncoming metadata:\\n' + JSON.stringify(metadata);"
"tbelScript": "return '\\nIncoming message:\\n' + JSON.stringify(msg) + '\\nIncoming metadata:\\n' + JSON.stringify(metadata);"
}
},
{
@ -84,9 +84,9 @@
"name": "Log Other",
"debugMode": false,
"configuration": {
"scriptLang": "MVEL",
"scriptLang": "TBEL",
"jsScript": "return '\\nIncoming message:\\n' + JSON.stringify(msg) + '\\nIncoming metadata:\\n' + JSON.stringify(metadata);",
"mvelScript": "return '\\nIncoming message:\\n' + JSON.stringify(msg) + '\\nIncoming metadata:\\n' + JSON.stringify(metadata);"
"tbelScript": "return '\\nIncoming message:\\n' + JSON.stringify(msg) + '\\nIncoming metadata:\\n' + JSON.stringify(metadata);"
}
},
{

View File

@ -57,9 +57,9 @@
"name": "Log RPC from Device",
"debugMode": false,
"configuration": {
"scriptLang": "MVEL",
"scriptLang": "TBEL",
"jsScript": "return '\\nIncoming message:\\n' + JSON.stringify(msg) + '\\nIncoming metadata:\\n' + JSON.stringify(metadata);",
"mvelScript": "return '\\nIncoming message:\\n' + JSON.stringify(msg) + '\\nIncoming metadata:\\n' + JSON.stringify(metadata);"
"tbelScript": "return '\\nIncoming message:\\n' + JSON.stringify(msg) + '\\nIncoming metadata:\\n' + JSON.stringify(metadata);"
}
},
{
@ -71,9 +71,9 @@
"name": "Log Other",
"debugMode": false,
"configuration": {
"scriptLang": "MVEL",
"scriptLang": "TBEL",
"jsScript": "return '\\nIncoming message:\\n' + JSON.stringify(msg) + '\\nIncoming metadata:\\n' + JSON.stringify(metadata);",
"mvelScript": "return '\\nIncoming message:\\n' + JSON.stringify(msg) + '\\nIncoming metadata:\\n' + JSON.stringify(metadata);"
"tbelScript": "return '\\nIncoming message:\\n' + JSON.stringify(msg) + '\\nIncoming metadata:\\n' + JSON.stringify(metadata);"
}
},
{

View File

@ -33,7 +33,7 @@ import org.thingsboard.rule.engine.api.MailService;
import org.thingsboard.rule.engine.api.SmsService;
import org.thingsboard.rule.engine.api.sms.SmsSenderFactory;
import org.thingsboard.script.api.js.JsInvokeService;
import org.thingsboard.script.api.mvel.MvelInvokeService;
import org.thingsboard.script.api.tbel.TbelInvokeService;
import org.thingsboard.server.actors.service.ActorService;
import org.thingsboard.server.actors.tenant.DebugTbRateLimits;
import org.thingsboard.server.cluster.TbClusterService;
@ -274,7 +274,7 @@ public class ActorSystemContext {
@Autowired(required = false)
@Getter
private MvelInvokeService mvelInvokeService;
private TbelInvokeService tbelInvokeService;
@Autowired
@Getter

View File

@ -97,7 +97,7 @@ import org.thingsboard.server.gen.transport.TransportProtos;
import org.thingsboard.server.queue.TbQueueCallback;
import org.thingsboard.server.queue.TbQueueMsgMetadata;
import org.thingsboard.server.service.script.RuleNodeJsScriptEngine;
import org.thingsboard.server.service.script.RuleNodeMvelScriptEngine;
import org.thingsboard.server.service.script.RuleNodeTbelScriptEngine;
import java.util.Collections;
import java.util.List;
@ -474,11 +474,11 @@ class DefaultTbContext implements TbContext {
return new RuleNodeJsScriptEngine(getTenantId(), mainCtx.getJsInvokeService(), script, argNames);
}
private ScriptEngine createMvelScriptEngine(String script, String... argNames) {
if (mainCtx.getMvelInvokeService() == null) {
throw new RuntimeException("MVEL execution is disabled!");
private ScriptEngine createTbelScriptEngine(String script, String... argNames) {
if (mainCtx.getTbelInvokeService() == null) {
throw new RuntimeException("TBEL execution is disabled!");
}
return new RuleNodeMvelScriptEngine(getTenantId(), mainCtx.getMvelInvokeService(), script, argNames);
return new RuleNodeTbelScriptEngine(getTenantId(), mainCtx.getTbelInvokeService(), script, argNames);
}
@Override
@ -492,11 +492,11 @@ class DefaultTbContext implements TbContext {
switch (scriptLang) {
case JS:
return createJsScriptEngine(script, argNames);
case MVEL:
case TBEL:
if (Arrays.isNullOrEmpty(argNames)) {
return createMvelScriptEngine(script, "msg", "metadata", "msgType");
return createTbelScriptEngine(script, "msg", "metadata", "msgType");
} else {
return createMvelScriptEngine(script, argNames);
return createTbelScriptEngine(script, argNames);
}
default:
throw new RuntimeException("Unsupported script language: " + scriptLang.name());

View File

@ -38,7 +38,7 @@ import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.bind.annotation.RestController;
import org.thingsboard.rule.engine.api.ScriptEngine;
import org.thingsboard.script.api.js.JsInvokeService;
import org.thingsboard.script.api.mvel.MvelInvokeService;
import org.thingsboard.script.api.tbel.TbelInvokeService;
import org.thingsboard.server.actors.ActorSystemContext;
import org.thingsboard.server.actors.tenant.DebugTbRateLimits;
import org.thingsboard.server.common.data.EventInfo;
@ -69,7 +69,7 @@ import org.thingsboard.server.dao.event.EventService;
import org.thingsboard.server.queue.util.TbCoreComponent;
import org.thingsboard.server.service.rule.TbRuleChainService;
import org.thingsboard.server.service.script.RuleNodeJsScriptEngine;
import org.thingsboard.server.service.script.RuleNodeMvelScriptEngine;
import org.thingsboard.server.service.script.RuleNodeTbelScriptEngine;
import org.thingsboard.server.service.security.permission.Operation;
import org.thingsboard.server.service.security.permission.Resource;
@ -146,7 +146,7 @@ public class RuleChainController extends BaseController {
private JsInvokeService jsInvokeService;
@Autowired(required = false)
private MvelInvokeService mvelInvokeService;
private TbelInvokeService tbelInvokeService;
@Autowired(required = false)
private ActorSystemContext actorContext;
@ -154,8 +154,8 @@ public class RuleChainController extends BaseController {
@Value("${actors.rule.chain.debug_mode_rate_limits_per_tenant.enabled}")
private boolean debugPerTenantEnabled;
@Value("${mvel.enabled:true}")
private boolean mvelEnabled;
@Value("${tbel.enabled:true}")
private boolean tbelEnabled;
@ApiOperation(value = "Get Rule Chain (getRuleChainById)",
notes = "Fetch the Rule Chain object based on the provided Rule Chain Id. " + RULE_CHAIN_DESCRIPTION + TENANT_AUTHORITY_PARAGRAPH)
@ -378,13 +378,13 @@ public class RuleChainController extends BaseController {
}
}
@ApiOperation(value = "Is MVEL script executor enabled",
notes = "Returns 'True' if the MVEL script execution is enabled" + TENANT_AUTHORITY_PARAGRAPH)
@ApiOperation(value = "Is TBEL script executor enabled",
notes = "Returns 'True' if the TBEL script execution is enabled" + TENANT_AUTHORITY_PARAGRAPH)
@PreAuthorize("hasAuthority('TENANT_ADMIN')")
@RequestMapping(value = "/ruleChain/mvelEnabled", method = RequestMethod.GET)
@RequestMapping(value = "/ruleChain/tbelEnabled", method = RequestMethod.GET)
@ResponseBody
public Boolean isMvelEnabled() {
return mvelEnabled;
public Boolean isTbelEnabled() {
return tbelEnabled;
}
@ApiOperation(value = "Test Script function",
@ -393,7 +393,7 @@ public class RuleChainController extends BaseController {
@RequestMapping(value = "/ruleChain/testScript", method = RequestMethod.POST)
@ResponseBody
public JsonNode testScript(
@ApiParam(value = "Script language: JS or MVEL")
@ApiParam(value = "Script language: JS or TBEL")
@RequestParam(required = false) ScriptLanguage scriptLang,
@ApiParam(value = "Test JS request. See API call description above.")
@RequestBody JsonNode inputParams) throws ThingsboardException {
@ -418,10 +418,10 @@ public class RuleChainController extends BaseController {
if (ScriptLanguage.JS.equals(scriptLang)) {
engine = new RuleNodeJsScriptEngine(getTenantId(), jsInvokeService, script, argNames);
} else {
if (mvelInvokeService == null) {
throw new IllegalArgumentException("MVEL script engine is disabled!");
if (tbelInvokeService == null) {
throw new IllegalArgumentException("TBEL script engine is disabled!");
}
engine = new RuleNodeMvelScriptEngine(getTenantId(), mvelInvokeService, script, argNames);
engine = new RuleNodeTbelScriptEngine(getTenantId(), tbelInvokeService, script, argNames);
}
TbMsg inMsg = TbMsg.newMsg(msgType, null, new TbMsgMetaData(metadata), TbMsgDataType.JSON, data);
switch (scriptType) {

View File

@ -23,7 +23,7 @@ import com.google.common.util.concurrent.MoreExecutors;
import lombok.extern.slf4j.Slf4j;
import org.thingsboard.common.util.JacksonUtil;
import org.thingsboard.script.api.RuleNodeScriptFactory;
import org.thingsboard.script.api.mvel.MvelInvokeService;
import org.thingsboard.script.api.tbel.TbelInvokeService;
import org.thingsboard.server.common.data.StringUtils;
import org.thingsboard.server.common.data.id.TenantId;
import org.thingsboard.server.common.msg.TbMsg;
@ -42,9 +42,9 @@ import java.util.stream.Collectors;
@Slf4j
public class RuleNodeMvelScriptEngine extends RuleNodeScriptEngine<MvelInvokeService, Object> {
public class RuleNodeTbelScriptEngine extends RuleNodeScriptEngine<TbelInvokeService, Object> {
public RuleNodeMvelScriptEngine(TenantId tenantId, MvelInvokeService scriptInvokeService, String script, String... argNames) {
public RuleNodeTbelScriptEngine(TenantId tenantId, TbelInvokeService scriptInvokeService, String script, String... argNames) {
super(tenantId, scriptInvokeService, script, argNames);
}

View File

@ -611,25 +611,25 @@ state:
defaultStateCheckIntervalInSec: "${DEFAULT_STATE_CHECK_INTERVAL:60}"
persistToTelemetry: "${PERSIST_STATE_TO_TELEMETRY:false}"
mvel:
enabled: "${MVEL_ENABLED:true}"
max_total_args_size: "${MVEL_MAX_TOTAL_ARGS_SIZE:100000}"
max_result_size: "${MVEL_MAX_RESULT_SIZE:300000}"
max_script_body_size: "${MVEL_MAX_SCRIPT_BODY_SIZE:50000}"
# Maximum allowed MVEL script execution memory
max_memory_limit_mb: "${MVEL_MAX_MEMORY_LIMIT_MB: 8}"
# Maximum allowed MVEL script execution errors before it will be blacklisted
max_errors: "${MVEL_MAX_ERRORS:3}"
# MVEL Eval max request timeout in milliseconds. 0 - no timeout
max_requests_timeout: "${MVEL_MAX_REQUEST_TIMEOUT:500}"
tbel:
enabled: "${TBEL_ENABLED:true}"
max_total_args_size: "${TBEL_MAX_TOTAL_ARGS_SIZE:100000}"
max_result_size: "${TBEL_MAX_RESULT_SIZE:300000}"
max_script_body_size: "${TBEL_MAX_SCRIPT_BODY_SIZE:50000}"
# Maximum allowed TBEL script execution memory
max_memory_limit_mb: "${TBEL_MAX_MEMORY_LIMIT_MB: 8}"
# Maximum allowed TBEL script execution errors before it will be blacklisted
max_errors: "${TBEL_MAX_ERRORS:3}"
# TBEL Eval max request timeout in milliseconds. 0 - no timeout
max_requests_timeout: "${TBEL_MAX_REQUEST_TIMEOUT:500}"
# Maximum time in seconds for black listed function to stay in the list.
max_black_list_duration_sec: "${MVEL_MAX_BLACKLIST_DURATION_SEC:60}"
max_black_list_duration_sec: "${TBEL_MAX_BLACKLIST_DURATION_SEC:60}"
# Specify thread pool size for javascript executor service
thread_pool_size: "${MVEL_THREAD_POOL_SIZE:50}"
compiled_scripts_cache_size: "${MVEL_COMPILED_SCRIPTS_CACHE_SIZE:1000}"
thread_pool_size: "${TBEL_THREAD_POOL_SIZE:50}"
compiled_scripts_cache_size: "${TBEL_COMPILED_SCRIPTS_CACHE_SIZE:1000}"
stats:
enabled: "${TB_MVEL_STATS_ENABLED:false}"
print_interval_ms: "${TB_MVEL_STATS_PRINT_INTERVAL_MS:10000}"
enabled: "${TB_TBEL_STATS_ENABLED:false}"
print_interval_ms: "${TB_TBEL_STATS_PRINT_INTERVAL_MS:10000}"
js:
evaluator: "${JS_EVALUATOR:local}" # local/remote

View File

@ -24,8 +24,8 @@ import org.springframework.beans.factory.annotation.Value;
import org.springframework.test.context.TestPropertySource;
import org.thingsboard.common.util.JacksonUtil;
import org.thingsboard.script.api.ScriptType;
import org.thingsboard.script.api.mvel.MvelInvokeService;
import org.thingsboard.script.api.mvel.MvelScript;
import org.thingsboard.script.api.tbel.TbelInvokeService;
import org.thingsboard.script.api.tbel.TbelScript;
import org.thingsboard.server.common.data.id.TenantId;
import org.thingsboard.server.controller.AbstractControllerTest;
import org.thingsboard.server.dao.service.DaoSqlTest;
@ -45,18 +45,18 @@ import static org.assertj.core.api.Assertions.assertThatThrownBy;
@DaoSqlTest
@TestPropertySource(properties = {
"mvel.max_script_body_size=100",
"mvel.max_total_args_size=50",
"mvel.max_result_size=50",
"mvel.max_errors=2",
"mvel.compiled_scripts_cache_size=100"
"tbel.max_script_body_size=100",
"tbel.max_total_args_size=50",
"tbel.max_result_size=50",
"tbel.max_errors=2",
"tbel.compiled_scripts_cache_size=100"
})
class MvelInvokeServiceTest extends AbstractControllerTest {
class TbelInvokeServiceTest extends AbstractControllerTest {
@Autowired
private MvelInvokeService invokeService;
private TbelInvokeService invokeService;
@Value("${mvel.max_errors}")
@Value("${tbel.max_errors}")
private int maxJsErrors;
@Test
@ -129,7 +129,7 @@ class MvelInvokeServiceTest extends AbstractControllerTest {
}
Map<UUID, String> scriptIdToHash = getFieldValue(invokeService, "scriptIdToHash");
Map<String, MvelScript> scriptMap = getFieldValue(invokeService, "scriptMap");
Map<String, TbelScript> scriptMap = getFieldValue(invokeService, "scriptMap");
Cache<String, Serializable> compiledScriptsCache = getFieldValue(invokeService, "compiledScriptsCache");
String scriptHash = scriptIdToHash.get(scriptsIds.get(0));
@ -149,7 +149,7 @@ class MvelInvokeServiceTest extends AbstractControllerTest {
}
Map<UUID, String> scriptIdToHash = getFieldValue(invokeService, "scriptIdToHash");
Map<String, MvelScript> scriptMap = getFieldValue(invokeService, "scriptMap");
Map<String, TbelScript> scriptMap = getFieldValue(invokeService, "scriptMap");
Cache<String, Serializable> compiledScriptsCache = getFieldValue(invokeService, "compiledScriptsCache");
String scriptHash = scriptIdToHash.get(scriptsIds.get(0));
@ -173,7 +173,7 @@ class MvelInvokeServiceTest extends AbstractControllerTest {
Cache<String, Serializable> compiledScriptsCache = getFieldValue(invokeService, "compiledScriptsCache");
List<UUID> scriptsIds = new ArrayList<>();
for (int i = 0; i < 110; i++) { // mvel.compiled_scripts_cache_size = 100
for (int i = 0; i < 110; i++) { // tbel.compiled_scripts_cache_size = 100
String script = "return msg.temperature > " + i;
UUID scriptId = evalScript(script);
scriptsIds.add(scriptId);

View File

@ -16,5 +16,5 @@
package org.thingsboard.server.common.data.script;
public enum ScriptLanguage {
JS, MVEL
JS, TBEL
}

View File

@ -90,7 +90,7 @@
</dependency>
<dependency>
<groupId>org.thingsboard</groupId>
<artifactId>mvel2</artifactId>
<artifactId>tbel</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>

View File

@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.thingsboard.script.api.mvel;
package org.thingsboard.script.api.tbel;
import com.github.benmanes.caffeine.cache.Cache;
import com.github.benmanes.caffeine.cache.Caffeine;
@ -58,12 +58,12 @@ import java.util.concurrent.locks.ReentrantLock;
import java.util.regex.Pattern;
@Slf4j
@ConditionalOnProperty(prefix = "mvel", value = "enabled", havingValue = "true", matchIfMissing = true)
@ConditionalOnProperty(prefix = "tbel", value = "enabled", havingValue = "true", matchIfMissing = true)
@Service
public class DefaultMvelInvokeService extends AbstractScriptInvokeService implements MvelInvokeService {
public class DefaultTbelInvokeService extends AbstractScriptInvokeService implements TbelInvokeService {
protected final Map<UUID, String> scriptIdToHash = new ConcurrentHashMap<>();
protected final Map<String, MvelScript> scriptMap = new ConcurrentHashMap<>();
protected final Map<String, TbelScript> scriptMap = new ConcurrentHashMap<>();
protected Cache<String, Serializable> compiledScriptsCache;
private SandboxedParserConfiguration parserConfig;
@ -71,49 +71,49 @@ public class DefaultMvelInvokeService extends AbstractScriptInvokeService implem
private static final Pattern NEW_KEYWORD_PATTERN = Pattern.compile("new\\s");
@Getter
@Value("${mvel.max_total_args_size:100000}")
@Value("${tbel.max_total_args_size:100000}")
private long maxTotalArgsSize;
@Getter
@Value("${mvel.max_result_size:300000}")
@Value("${tbel.max_result_size:300000}")
private long maxResultSize;
@Getter
@Value("${mvel.max_script_body_size:50000}")
@Value("${tbel.max_script_body_size:50000}")
private long maxScriptBodySize;
@Getter
@Value("${mvel.max_errors:3}")
@Value("${tbel.max_errors:3}")
private int maxErrors;
@Getter
@Value("${mvel.max_black_list_duration_sec:60}")
@Value("${tbel.max_black_list_duration_sec:60}")
private int maxBlackListDurationSec;
@Getter
@Value("${mvel.max_requests_timeout:0}")
@Value("${tbel.max_requests_timeout:0}")
private long maxInvokeRequestsTimeout;
@Getter
@Value("${mvel.stats.enabled:false}")
@Value("${tbel.stats.enabled:false}")
private boolean statsEnabled;
@Value("${mvel.thread_pool_size:50}")
@Value("${tbel.thread_pool_size:50}")
private int threadPoolSize;
@Value("${mvel.max_memory_limit_mb:8}")
@Value("${tbel.max_memory_limit_mb:8}")
private long maxMemoryLimitMb;
@Value("${mvel.compiled_scripts_cache_size:1000}")
@Value("${tbel.compiled_scripts_cache_size:1000}")
private int compiledScriptsCacheSize;
private ListeningExecutorService executor;
private final Lock lock = new ReentrantLock();
protected DefaultMvelInvokeService(Optional<TbApiUsageStateClient> apiUsageStateClient, Optional<TbApiUsageReportClient> apiUsageReportClient) {
protected DefaultTbelInvokeService(Optional<TbApiUsageStateClient> apiUsageStateClient, Optional<TbApiUsageReportClient> apiUsageReportClient) {
super(apiUsageStateClient, apiUsageReportClient);
}
@Scheduled(fixedDelayString = "${mvel.stats.print_interval_ms:10000}")
@Scheduled(fixedDelayString = "${tbel.stats.print_interval_ms:10000}")
public void printStats() {
super.printStats();
}
@ -127,9 +127,9 @@ public class DefaultMvelInvokeService extends AbstractScriptInvokeService implem
parserConfig.addImport("JSON", TbJson.class);
parserConfig.registerDataType("Date", TbDate.class, date -> 8L);
TbUtils.register(parserConfig);
executor = MoreExecutors.listeningDecorator(ThingsBoardExecutors.newWorkStealingPool(threadPoolSize, "mvel-executor"));
executor = MoreExecutors.listeningDecorator(ThingsBoardExecutors.newWorkStealingPool(threadPoolSize, "tbel-executor"));
try {
// Special command to warm up MVEL engine
// Special command to warm up TBEL engine
Serializable script = compileScript("var warmUp = {}; warmUp");
MVEL.executeTbExpression(script, new ExecutionContext(parserConfig), Collections.emptyMap());
} catch (Exception e) {
@ -149,7 +149,7 @@ public class DefaultMvelInvokeService extends AbstractScriptInvokeService implem
@Override
protected String getStatsName() {
return "MVEL Scripts Stats";
return "TBEL Scripts Stats";
}
@Override
@ -167,15 +167,11 @@ public class DefaultMvelInvokeService extends AbstractScriptInvokeService implem
return executor.submit(() -> {
try {
String scriptHash = hash(scriptBody, argNames);
compiledScriptsCache.get(scriptHash, k -> {
return compileScript(scriptBody);
});
compiledScriptsCache.get(scriptHash, k -> compileScript(scriptBody));
lock.lock();
try {
scriptIdToHash.put(scriptId, scriptHash);
scriptMap.computeIfAbsent(scriptHash, k -> {
return new MvelScript(scriptBody, argNames);
});
scriptMap.computeIfAbsent(scriptHash, k -> new TbelScript(scriptBody, argNames));
} finally {
lock.unlock();
}
@ -187,17 +183,15 @@ public class DefaultMvelInvokeService extends AbstractScriptInvokeService implem
}
@Override
protected MvelScriptExecutionTask doInvokeFunction(UUID scriptId, Object[] args) {
protected TbelScriptExecutionTask doInvokeFunction(UUID scriptId, Object[] args) {
ExecutionContext executionContext = new ExecutionContext(this.parserConfig, maxMemoryLimitMb * 1024 * 1024);
return new MvelScriptExecutionTask(executionContext, executor.submit(() -> {
return new TbelScriptExecutionTask(executionContext, executor.submit(() -> {
String scriptHash = scriptIdToHash.get(scriptId);
if (scriptHash == null) {
throw new TbScriptException(scriptId, TbScriptException.ErrorCode.OTHER, null, new RuntimeException("Script not found!"));
}
MvelScript script = scriptMap.get(scriptHash);
Serializable compiledScript = compiledScriptsCache.get(scriptHash, k -> {
return compileScript(script.getScriptBody());
});
TbelScript script = scriptMap.get(scriptHash);
Serializable compiledScript = compiledScriptsCache.get(scriptHash, k -> compileScript(script.getScriptBody()));
try {
return MVEL.executeTbExpression(compiledScript, executionContext, script.createVars(args));
} catch (ScriptMemoryOverflowException e) {
@ -209,7 +203,7 @@ public class DefaultMvelInvokeService extends AbstractScriptInvokeService implem
}
@Override
protected void doRelease(UUID scriptId) throws Exception {
protected void doRelease(UUID scriptId) {
String scriptHash = scriptIdToHash.remove(scriptId);
if (scriptHash != null) {
lock.lock();

View File

@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.thingsboard.script.api.mvel;
package org.thingsboard.script.api.tbel;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
@ -60,7 +60,7 @@ public class TbDate extends Date {
}
public String toISOString() {
DateFormat formatter = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.sssZ");
DateFormat formatter = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSZ");
return formatter.format(this);
}

View File

@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.thingsboard.script.api.mvel;
package org.thingsboard.script.api.tbel;
import com.fasterxml.jackson.databind.JsonNode;
import org.mvel2.ExecutionContext;

View File

@ -13,19 +13,25 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.thingsboard.script.api.mvel;
package org.thingsboard.script.api.tbel;
import org.mvel2.ExecutionContext;
import org.mvel2.ParserConfiguration;
import org.mvel2.execution.ExecutionArrayList;
import org.mvel2.util.MethodStub;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.nio.charset.StandardCharsets;
import java.util.Base64;
import java.util.List;
public class TbUtils {
private static final byte[] HEX_ARRAY = "0123456789ABCDEF".getBytes(StandardCharsets.US_ASCII);
public static void register(ParserConfiguration parserConfig) throws Exception {
parserConfig.addImport("btoa", new MethodStub(TbUtils.class.getMethod("btoa",
String.class)));
@ -35,6 +41,10 @@ public class TbUtils {
List.class)));
parserConfig.addImport("bytesToString", new MethodStub(TbUtils.class.getMethod("bytesToString",
List.class, String.class)));
parserConfig.addImport("decodeToString", new MethodStub(TbUtils.class.getMethod("bytesToString",
List.class)));
parserConfig.addImport("decodeToJson", new MethodStub(TbUtils.class.getMethod("decodeToJson",
ExecutionContext.class, List.class)));
parserConfig.addImport("stringToBytes", new MethodStub(TbUtils.class.getMethod("stringToBytes",
ExecutionContext.class, String.class)));
parserConfig.addImport("stringToBytes", new MethodStub(TbUtils.class.getMethod("stringToBytes",
@ -47,10 +57,24 @@ public class TbUtils {
String.class)));
parserConfig.addImport("parseDouble", new MethodStub(TbUtils.class.getMethod("parseDouble",
String.class)));
}
public static void main(String[] args) {
System.out.println(Integer.class == int.class);
parserConfig.addImport("parseLittleEndianHexToInt", new MethodStub(TbUtils.class.getMethod("parseLittleEndianHexToInt",
String.class)));
parserConfig.addImport("parseBigEndianHexToInt", new MethodStub(TbUtils.class.getMethod("parseBigEndianHexToInt",
String.class)));
parserConfig.addImport("parseHexToInt", new MethodStub(TbUtils.class.getMethod("parseHexToInt",
String.class)));
parserConfig.addImport("parseHexToInt", new MethodStub(TbUtils.class.getMethod("parseHexToInt",
String.class, boolean.class)));
parserConfig.addImport("toFixed", new MethodStub(TbUtils.class.getMethod("toFixed",
double.class, int.class)));
parserConfig.addImport("hexToBytes", new MethodStub(TbUtils.class.getMethod("hexToBytes",
ExecutionContext.class, String.class)));
parserConfig.addImport("base64ToHex", new MethodStub(TbUtils.class.getMethod("base64ToHex",
String.class)));
parserConfig.addImport("bytesToHex", new MethodStub(TbUtils.class.getMethod("bytesToHex",
byte[].class)));
parserConfig.addImport("bytesToHex", new MethodStub(TbUtils.class.getMethod("bytesToHex",
ExecutionArrayList.class)));
}
public static String btoa(String input) {
@ -61,6 +85,10 @@ public class TbUtils {
return new String(Base64.getDecoder().decode(encoded));
}
public static Object decodeToJson(ExecutionContext ctx, List<Byte> bytesList) throws IOException {
return TbJson.parse(ctx, bytesToString(bytesList));
}
public static String bytesToString(List<Byte> bytesList) {
byte[] bytes = bytesFromList(bytesList);
return new String(bytes);
@ -149,6 +177,72 @@ public class TbUtils {
return null;
}
public static int parseLittleEndianHexToInt(String hex) {
return parseHexToInt(hex, false);
}
public static int parseBigEndianHexToInt(String hex) {
return parseHexToInt(hex, true);
}
public static int parseHexToInt(String hex) {
return parseHexToInt(hex, true);
}
public static int parseHexToInt(String hex, boolean bigEndian) {
int length = hex.length();
if (length > 8) {
throw new IllegalArgumentException("Hex string is too large. Maximum 8 symbols allowed.");
}
if (bigEndian) {
return Integer.parseInt(hex, 16);
} else {
if (length < 8) {
hex = hex + "0".repeat(8 - length);
}
return Integer.reverseBytes(Integer.parseInt(hex, 16));
}
}
public static ExecutionArrayList<Integer> hexToBytes(ExecutionContext ctx, String hex) {
int len = hex.length();
if (len % 2 > 0) {
throw new IllegalArgumentException("Hex string must be even-length.");
}
ExecutionArrayList<Integer> data = new ExecutionArrayList<>(ctx);
for (int i = 0; i < len; i += 2) {
data.add((Character.digit(hex.charAt(i), 16) << 4)
+ Character.digit(hex.charAt(i+1), 16));
}
return data;
}
public static String base64ToHex(String base64) {
return bytesToHex(Base64.getDecoder().decode(base64));
}
public static String bytesToHex(ExecutionArrayList<?> bytesList) {
byte[] bytes = new byte[bytesList.size()];
for (int i = 0; i < bytesList.size(); i++) {
bytes[i] = Byte.parseByte(bytesList.get(i).toString());
}
return bytesToHex(bytes);
}
public static String bytesToHex(byte[] bytes) {
byte[] hexChars = new byte[bytes.length * 2];
for (int j = 0; j < bytes.length; j++) {
int v = bytes[j] & 0xFF;
hexChars[j * 2] = HEX_ARRAY[v >>> 4];
hexChars[j * 2 + 1] = HEX_ARRAY[v & 0x0F];
}
return new String(hexChars, StandardCharsets.UTF_8);
}
public static double toFixed(double value, int precision) {
return BigDecimal.valueOf(value).setScale(precision, RoundingMode.HALF_UP).doubleValue();
}
private static boolean isHexadecimal(String value) {
return value != null && (value.contains("0x") || value.contains("0X"));
}

View File

@ -13,16 +13,16 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.thingsboard.script.api.mvel;
package org.thingsboard.script.api.tbel;
import org.thingsboard.script.api.ScriptInvokeService;
import org.thingsboard.server.common.data.script.ScriptLanguage;
public interface MvelInvokeService extends ScriptInvokeService {
public interface TbelInvokeService extends ScriptInvokeService {
@Override
default ScriptLanguage getLanguage() {
return ScriptLanguage.MVEL;
return ScriptLanguage.TBEL;
}
}

View File

@ -13,16 +13,15 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.thingsboard.script.api.mvel;
package org.thingsboard.script.api.tbel;
import lombok.Data;
import java.io.Serializable;
import java.util.HashMap;
import java.util.Map;
@Data
public class MvelScript {
public class TbelScript {
private final String scriptBody;
private final String[] argNames;

View File

@ -13,20 +13,18 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.thingsboard.script.api.mvel;
package org.thingsboard.script.api.tbel;
import com.google.common.util.concurrent.ListenableFuture;
import lombok.Data;
import lombok.Getter;
import org.mvel2.ExecutionContext;
import org.thingsboard.script.api.TbScriptExecutionTask;
public class MvelScriptExecutionTask extends TbScriptExecutionTask {
public class TbelScriptExecutionTask extends TbScriptExecutionTask {
private final ExecutionContext context;
public MvelScriptExecutionTask(ExecutionContext context, ListenableFuture<Object> resultFuture) {
public TbelScriptExecutionTask(ExecutionContext context, ListenableFuture<Object> resultFuture) {
super(resultFuture);
this.context = context;
}

View File

@ -77,7 +77,7 @@
<zookeeper.version>3.5.5</zookeeper.version>
<protobuf.version>3.21.9</protobuf.version>
<grpc.version>1.42.1</grpc.version>
<mvel.version>2.4.25TB</mvel.version>
<tbel.version>1.0.0</tbel.version>
<lombok.version>1.18.18</lombok.version>
<paho.client.version>1.2.4</paho.client.version>
<netty.version>4.1.75.Final</netty.version>
@ -1575,8 +1575,8 @@
</dependency>
<dependency>
<groupId>org.thingsboard</groupId>
<artifactId>mvel2</artifactId>
<version>${mvel.version}</version>
<artifactId>tbel</artifactId>
<version>${tbel.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>

View File

@ -48,7 +48,7 @@ public abstract class TbAbstractAlarmNode<C extends TbAbstractAlarmNodeConfigura
public void init(TbContext ctx, TbNodeConfiguration configuration) throws TbNodeException {
this.config = loadAlarmNodeConfig(configuration);
scriptEngine = ctx.createScriptEngine(config.getScriptLang(),
ScriptLanguage.MVEL.equals(config.getScriptLang()) ? config.getAlarmDetailsBuildMvel() : config.getAlarmDetailsBuildJs());
ScriptLanguage.TBEL.equals(config.getScriptLang()) ? config.getAlarmDetailsBuildTbel() : config.getAlarmDetailsBuildJs());
}
protected abstract C loadAlarmNodeConfig(TbNodeConfiguration configuration) throws TbNodeException;

View File

@ -33,7 +33,7 @@ public abstract class TbAbstractAlarmNodeConfiguration {
"\n" +
"return details;";
static final String ALARM_DETAILS_BUILD_MVEL_TEMPLATE = "" +
static final String ALARM_DETAILS_BUILD_TBEL_TEMPLATE = "" +
"var details = {};\n" +
"if (metadata.prevAlarmDetails != null) {\n" +
" details = JSON.parse(metadata.prevAlarmDetails);\n" +
@ -49,6 +49,6 @@ public abstract class TbAbstractAlarmNodeConfiguration {
private String alarmType;
private ScriptLanguage scriptLang;
private String alarmDetailsBuildJs;
private String alarmDetailsBuildMvel;
private String alarmDetailsBuildTbel;
}

View File

@ -17,7 +17,6 @@ package org.thingsboard.rule.engine.action;
import lombok.Data;
import org.thingsboard.rule.engine.api.NodeConfiguration;
import org.thingsboard.server.common.data.alarm.AlarmSeverity;
import org.thingsboard.server.common.data.script.ScriptLanguage;
@Data
@ -26,9 +25,9 @@ public class TbClearAlarmNodeConfiguration extends TbAbstractAlarmNodeConfigurat
@Override
public TbClearAlarmNodeConfiguration defaultConfiguration() {
TbClearAlarmNodeConfiguration configuration = new TbClearAlarmNodeConfiguration();
configuration.setScriptLang(ScriptLanguage.MVEL);
configuration.setScriptLang(ScriptLanguage.TBEL);
configuration.setAlarmDetailsBuildJs(ALARM_DETAILS_BUILD_JS_TEMPLATE);
configuration.setAlarmDetailsBuildMvel(ALARM_DETAILS_BUILD_MVEL_TEMPLATE);
configuration.setAlarmDetailsBuildTbel(ALARM_DETAILS_BUILD_TBEL_TEMPLATE);
configuration.setAlarmType("General Alarm");
return configuration;
}

View File

@ -39,9 +39,9 @@ public class TbCreateAlarmNodeConfiguration extends TbAbstractAlarmNodeConfigura
@Override
public TbCreateAlarmNodeConfiguration defaultConfiguration() {
TbCreateAlarmNodeConfiguration configuration = new TbCreateAlarmNodeConfiguration();
configuration.setScriptLang(ScriptLanguage.MVEL);
configuration.setScriptLang(ScriptLanguage.TBEL);
configuration.setAlarmDetailsBuildJs(ALARM_DETAILS_BUILD_JS_TEMPLATE);
configuration.setAlarmDetailsBuildMvel(ALARM_DETAILS_BUILD_MVEL_TEMPLATE);
configuration.setAlarmDetailsBuildTbel(ALARM_DETAILS_BUILD_TBEL_TEMPLATE);
configuration.setAlarmType("General Alarm");
configuration.setSeverity(AlarmSeverity.CRITICAL.name());
configuration.setPropagate(false);

View File

@ -56,7 +56,7 @@ public class TbLogNode implements TbNode {
this.config = TbNodeUtils.convert(configuration, TbLogNodeConfiguration.class);
this.standard = new TbLogNodeConfiguration().defaultConfiguration().getJsScript().equals(config.getJsScript());
this.scriptEngine = this.standard ? null : ctx.createScriptEngine(config.getScriptLang(),
ScriptLanguage.MVEL.equals(config.getScriptLang()) ? config.getMvelScript() : config.getJsScript());
ScriptLanguage.TBEL.equals(config.getScriptLang()) ? config.getTbelScript() : config.getJsScript());
}
@Override

View File

@ -24,14 +24,14 @@ public class TbLogNodeConfiguration implements NodeConfiguration {
private ScriptLanguage scriptLang;
private String jsScript;
private String mvelScript;
private String tbelScript;
@Override
public TbLogNodeConfiguration defaultConfiguration() {
TbLogNodeConfiguration configuration = new TbLogNodeConfiguration();
configuration.setScriptLang(ScriptLanguage.MVEL);
configuration.setScriptLang(ScriptLanguage.TBEL);
configuration.setJsScript("return '\\nIncoming message:\\n' + JSON.stringify(msg) + '\\nIncoming metadata:\\n' + JSON.stringify(metadata);");
configuration.setMvelScript("return '\\nIncoming message:\\n' + JSON.stringify(msg) + '\\nIncoming metadata:\\n' + JSON.stringify(metadata);");
configuration.setTbelScript("return '\\nIncoming message:\\n' + JSON.stringify(msg) + '\\nIncoming metadata:\\n' + JSON.stringify(metadata);");
return configuration;
}
}

View File

@ -96,7 +96,7 @@ public class TbMsgGeneratorNode implements TbNode {
if (ctx.isLocalEntity(originatorId)) {
if (initialized.compareAndSet(false, true)) {
this.scriptEngine = ctx.createScriptEngine(config.getScriptLang(),
ScriptLanguage.MVEL.equals(config.getScriptLang()) ? config.getMvelScript() : config.getJsScript(), "prevMsg", "prevMetadata", "prevMsgType");
ScriptLanguage.TBEL.equals(config.getScriptLang()) ? config.getTbelScript() : config.getJsScript(), "prevMsg", "prevMetadata", "prevMsgType");
scheduleTickMsg(ctx);
}
} else if (initialized.compareAndSet(true, false)) {

View File

@ -35,16 +35,16 @@ public class TbMsgGeneratorNodeConfiguration implements NodeConfiguration<TbMsgG
private EntityType originatorType;
private ScriptLanguage scriptLang;
private String jsScript;
private String mvelScript;
private String tbelScript;
@Override
public TbMsgGeneratorNodeConfiguration defaultConfiguration() {
TbMsgGeneratorNodeConfiguration configuration = new TbMsgGeneratorNodeConfiguration();
configuration.setMsgCount(UNLIMITED_MSG_COUNT);
configuration.setPeriodInSeconds(1);
configuration.setScriptLang(ScriptLanguage.MVEL);
configuration.setScriptLang(ScriptLanguage.TBEL);
configuration.setJsScript(DEFAULT_SCRIPT);
configuration.setMvelScript(DEFAULT_SCRIPT);
configuration.setTbelScript(DEFAULT_SCRIPT);
return configuration;
}
}

View File

@ -23,7 +23,6 @@ import org.thingsboard.rule.engine.api.TbNode;
import org.thingsboard.rule.engine.api.TbNodeConfiguration;
import org.thingsboard.rule.engine.api.TbNodeException;
import org.thingsboard.rule.engine.api.util.TbNodeUtils;
import org.thingsboard.server.common.data.StringUtils;
import org.thingsboard.server.common.data.plugin.ComponentType;
import org.thingsboard.server.common.data.script.ScriptLanguage;
import org.thingsboard.server.common.msg.TbMsg;
@ -53,7 +52,7 @@ public class TbJsFilterNode implements TbNode {
public void init(TbContext ctx, TbNodeConfiguration configuration) throws TbNodeException {
this.config = TbNodeUtils.convert(configuration, TbJsFilterNodeConfiguration.class);
scriptEngine = ctx.createScriptEngine(config.getScriptLang(),
ScriptLanguage.MVEL.equals(config.getScriptLang()) ? config.getMvelScript() : config.getJsScript());
ScriptLanguage.TBEL.equals(config.getScriptLang()) ? config.getTbelScript() : config.getJsScript());
}
@Override

View File

@ -24,14 +24,14 @@ public class TbJsFilterNodeConfiguration implements NodeConfiguration<TbJsFilter
private ScriptLanguage scriptLang;
private String jsScript;
private String mvelScript;
private String tbelScript;
@Override
public TbJsFilterNodeConfiguration defaultConfiguration() {
TbJsFilterNodeConfiguration configuration = new TbJsFilterNodeConfiguration();
configuration.setScriptLang(ScriptLanguage.MVEL);
configuration.setScriptLang(ScriptLanguage.TBEL);
configuration.setJsScript("return msg.temperature > 20;");
configuration.setMvelScript("return msg.temperature > 20;");
configuration.setTbelScript("return msg.temperature > 20;");
return configuration;
}
}

View File

@ -56,7 +56,7 @@ public class TbJsSwitchNode implements TbNode {
public void init(TbContext ctx, TbNodeConfiguration configuration) throws TbNodeException {
this.config = TbNodeUtils.convert(configuration, TbJsSwitchNodeConfiguration.class);
this.scriptEngine = ctx.createScriptEngine(config.getScriptLang(),
ScriptLanguage.MVEL.equals(config.getScriptLang()) ? config.getMvelScript() : config.getJsScript());
ScriptLanguage.TBEL.equals(config.getScriptLang()) ? config.getTbelScript() : config.getJsScript());
}
@Override

View File

@ -15,13 +15,10 @@
*/
package org.thingsboard.rule.engine.filter;
import com.google.common.collect.Sets;
import lombok.Data;
import org.thingsboard.rule.engine.api.NodeConfiguration;
import org.thingsboard.server.common.data.script.ScriptLanguage;
import java.util.Set;
@Data
public class TbJsSwitchNodeConfiguration implements NodeConfiguration<TbJsSwitchNodeConfiguration> {
@ -33,7 +30,7 @@ public class TbJsSwitchNodeConfiguration implements NodeConfiguration<TbJsSwitch
"}\n" +
"return nextRelation(metadata, msg);";
private static final String DEFAULT_MVEL_SCRIPT = "function nextRelation(metadata, msg) {\n" +
private static final String DEFAULT_TBEL_SCRIPT = "function nextRelation(metadata, msg) {\n" +
" return ['one','nine'];\n" +
"}\n" +
"if(msgType == 'POST_TELEMETRY_REQUEST') {\n" +
@ -43,14 +40,14 @@ public class TbJsSwitchNodeConfiguration implements NodeConfiguration<TbJsSwitch
private ScriptLanguage scriptLang;
private String jsScript;
private String mvelScript;
private String tbelScript;
@Override
public TbJsSwitchNodeConfiguration defaultConfiguration() {
TbJsSwitchNodeConfiguration configuration = new TbJsSwitchNodeConfiguration();
configuration.setScriptLang(ScriptLanguage.MVEL);
configuration.setScriptLang(ScriptLanguage.TBEL);
configuration.setJsScript(DEFAULT_JS_SCRIPT);
configuration.setMvelScript(DEFAULT_MVEL_SCRIPT);
configuration.setTbelScript(DEFAULT_TBEL_SCRIPT);
return configuration;
}
}

View File

@ -22,7 +22,6 @@ import org.thingsboard.rule.engine.api.TbContext;
import org.thingsboard.rule.engine.api.TbNodeConfiguration;
import org.thingsboard.rule.engine.api.TbNodeException;
import org.thingsboard.rule.engine.api.util.TbNodeUtils;
import org.thingsboard.server.common.data.StringUtils;
import org.thingsboard.server.common.data.plugin.ComponentType;
import org.thingsboard.server.common.data.script.ScriptLanguage;
import org.thingsboard.server.common.msg.TbMsg;
@ -53,7 +52,7 @@ public class TbTransformMsgNode extends TbAbstractTransformNode {
public void init(TbContext ctx, TbNodeConfiguration configuration) throws TbNodeException {
this.config = TbNodeUtils.convert(configuration, TbTransformMsgNodeConfiguration.class);
scriptEngine = ctx.createScriptEngine(config.getScriptLang(),
ScriptLanguage.MVEL.equals(config.getScriptLang()) ? config.getMvelScript() : config.getJsScript());
ScriptLanguage.TBEL.equals(config.getScriptLang()) ? config.getTbelScript() : config.getJsScript());
setConfig(config);
}

View File

@ -24,14 +24,14 @@ public class TbTransformMsgNodeConfiguration extends TbTransformNodeConfiguratio
private ScriptLanguage scriptLang;
private String jsScript;
private String mvelScript;
private String tbelScript;
@Override
public TbTransformMsgNodeConfiguration defaultConfiguration() {
TbTransformMsgNodeConfiguration configuration = new TbTransformMsgNodeConfiguration();
configuration.setScriptLang(ScriptLanguage.MVEL);
configuration.setScriptLang(ScriptLanguage.TBEL);
configuration.setJsScript("return {msg: msg, metadata: metadata, msgType: msgType};");
configuration.setMvelScript("return {msg: msg, metadata: metadata, msgType: msgType};");
configuration.setTbelScript("return {msg: msg, metadata: metadata, msgType: msgType};");
return configuration;
}
}

View File

@ -21,7 +21,7 @@ export interface SysParamsState {
allowedDashboardIds: string[];
edgesSupportEnabled: boolean;
hasRepository: boolean;
mvelEnabled: boolean;
tbelEnabled: boolean;
}
export interface AuthPayload extends SysParamsState {

View File

@ -25,7 +25,7 @@ const emptyUserAuthState: AuthPayload = {
allowedDashboardIds: [],
edgesSupportEnabled: false,
hasRepository: false,
mvelEnabled: false
tbelEnabled: false
};
export const initialState: AuthState = {

View File

@ -60,9 +60,9 @@ export const selectHasRepository = createSelector(
(state: AuthState) => state.hasRepository
);
export const selectMvelEnabled = createSelector(
export const selectTbelEnabled = createSelector(
selectAuthState,
(state: AuthState) => state.mvelEnabled
(state: AuthState) => state.tbelEnabled
);
export function getCurrentAuthState(store: Store<AppState>): AuthState {

View File

@ -482,9 +482,9 @@ export class AuthService {
}
}
private loadMvelEnabled(authUser: AuthUser): Observable<boolean> {
private loadTbelEnabled(authUser: AuthUser): Observable<boolean> {
if (authUser.authority === Authority.TENANT_ADMIN) {
return this.http.get<boolean>('/api/ruleChain/mvelEnabled', defaultHttpOptions());
return this.http.get<boolean>('/api/ruleChain/tbelEnabled', defaultHttpOptions());
} else {
return of(false);
}
@ -495,7 +495,7 @@ export class AuthService {
this.fetchAllowedDashboardIds(authPayload),
this.loadIsEdgesSupportEnabled(),
this.loadHasRepository(authPayload.authUser),
this.loadMvelEnabled(authPayload.authUser),
this.loadTbelEnabled(authPayload.authUser),
this.timeService.loadMaxDatapointsLimit()];
return forkJoin(sources)
.pipe(map((data) => {
@ -503,8 +503,8 @@ export class AuthService {
const allowedDashboardIds: string[] = data[1] as string[];
const edgesSupportEnabled: boolean = data[2] as boolean;
const hasRepository: boolean = data[3] as boolean;
const mvelEnabled: boolean = data[4] as boolean;
return {userTokenAccessEnabled, allowedDashboardIds, edgesSupportEnabled, hasRepository, mvelEnabled};
const tbelEnabled: boolean = data[4] as boolean;
return {userTokenAccessEnabled, allowedDashboardIds, edgesSupportEnabled, hasRepository, tbelEnabled};
}, catchError((err) => {
return of({});
})));

View File

@ -18,7 +18,7 @@
<form class="tb-node-script-test-dialog"
[formGroup]="nodeScriptTestFormGroup" (ngSubmit)="save()">
<mat-toolbar fxLayout="row" color="primary">
<h2>{{ 'rulenode.test-script-function' | translate }} ({{ (scriptLang === scriptLanguage.JS ? 'rulenode.script-lang-java-script' : 'rulenode.script-lang-mvel') | translate }})</h2>
<h2>{{ 'rulenode.test-script-function' | translate }} ({{ (scriptLang === scriptLanguage.JS ? 'rulenode.script-lang-java-script' : 'rulenode.script-lang-tbel') | translate }})</h2>
<span fxFlex></span>
<button mat-button mat-icon-button
(click)="cancel()"
@ -77,7 +77,7 @@
functionName="{{ data.functionName }}"
[functionArgs]="data.argNames"
[validationArgs]="[data.msg, data.metadata, data.msgType]"
[disableUndefinedCheck]="scriptLang === scriptLanguage.MVEL"
[disableUndefinedCheck]="scriptLang === scriptLanguage.TBEL"
resultType="object"
[helpId]="data.helpId"
[fillHeight]="true">

View File

@ -19,7 +19,7 @@
<mat-button-toggle-group class="tb-script-lang-toggle-group"
style="width: 320px;"
formControlName="scriptLang" aria-label="Script language">
<mat-button-toggle fxFlex value="{{ scriptLanguage.MVEL }}">{{ 'rulenode.script-lang-mvel' | translate }}</mat-button-toggle>
<mat-button-toggle fxFlex value="{{ scriptLanguage.TBEL }}">{{ 'rulenode.script-lang-tbel' | translate }}</mat-button-toggle>
<mat-button-toggle fxFlex value="{{ scriptLanguage.JS }}">{{ 'rulenode.script-lang-java-script' | translate }}</mat-button-toggle>
</mat-button-toggle-group>
</div>

View File

@ -330,7 +330,7 @@ export interface FcRuleEdge extends FcEdge {
export enum ScriptLanguage {
JS = 'JS',
MVEL = 'MVEL'
TBEL = 'TBEL'
}
export interface TestScriptInputParams {

View File

@ -3013,7 +3013,7 @@
"invalid-target-rulechain": "Unable to resolve target rule chain!",
"test-script-function": "Test script function",
"script-lang-java-script": "Java Script",
"script-lang-mvel": "MVEL",
"script-lang-tbel": "TBEL",
"message": "Message",
"message-type": "Message type",
"select-message-type": "Select message type",