diff --git a/application/src/main/java/org/thingsboard/server/actors/ruleChain/DefaultTbContext.java b/application/src/main/java/org/thingsboard/server/actors/ruleChain/DefaultTbContext.java
index 06286532ab..edea142084 100644
--- a/application/src/main/java/org/thingsboard/server/actors/ruleChain/DefaultTbContext.java
+++ b/application/src/main/java/org/thingsboard/server/actors/ruleChain/DefaultTbContext.java
@@ -19,6 +19,7 @@ import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import io.netty.channel.EventLoopGroup;
import lombok.extern.slf4j.Slf4j;
+import org.bouncycastle.util.Arrays;
import org.thingsboard.common.util.ListeningExecutor;
import org.thingsboard.rule.engine.api.MailService;
import org.thingsboard.rule.engine.api.RuleEngineAlarmService;
@@ -443,19 +444,41 @@ class DefaultTbContext implements TbContext {
return mainCtx.getExternalCallExecutorService();
}
+ @Deprecated
@Override
public ScriptEngine createJsScriptEngine(String script, String... argNames) {
return new RuleNodeJsScriptEngine(getTenantId(), mainCtx.getJsInvokeService(), script, argNames);
}
- @Override
- public ScriptEngine createMvelScriptEngine(String script, String... argNames) {
+ private ScriptEngine createMvelScriptEngine(String script, String... argNames) {
if (mainCtx.getMvelInvokeService() == null) {
throw new RuntimeException("MVEL execution is disabled!");
}
return new RuleNodeMvelScriptEngine(getTenantId(), mainCtx.getMvelInvokeService(), script, argNames);
}
+ @Override
+ public ScriptEngine createScriptEngine(ScriptLanguage scriptLang, String script, String... argNames) {
+ if (scriptLang == null) {
+ scriptLang = ScriptLanguage.JS;
+ }
+ if (StringUtils.isBlank(script)) {
+ throw new RuntimeException(scriptLang.name() + " script is blank!");
+ }
+ switch (scriptLang) {
+ case JS:
+ return createJsScriptEngine(script, argNames);
+ case MVEL:
+ if (Arrays.isNullOrEmpty(argNames)) {
+ return createMvelScriptEngine(script, "msg", "metadata", "msgType");
+ } else {
+ return createMvelScriptEngine(script, argNames);
+ }
+ default:
+ throw new RuntimeException("Unsupported script language: " + scriptLang.name());
+ }
+ }
+
@Override
public void logJsEvalRequest() {
if (mainCtx.isStatisticsEnabled()) {
@@ -708,24 +731,6 @@ class DefaultTbContext implements TbContext {
return mainCtx.getTenantProfileCache().get(getTenantId());
}
- @Override
- public ScriptEngine createScriptEngine(ScriptLanguage scriptLang, String script) {
- if (scriptLang == null) {
- scriptLang = ScriptLanguage.JS;
- }
- if (StringUtils.isBlank(script)) {
- throw new RuntimeException(scriptLang.name() + " script is blank!");
- }
- switch (scriptLang) {
- case JS:
- return createJsScriptEngine(script);
- case MVEL:
- return createMvelScriptEngine(script, "msg", "metadata", "msgType");
- default:
- throw new RuntimeException("Unsupported script language: " + scriptLang.name());
- }
- }
-
private TbMsgMetaData getActionMetaData(RuleNodeId ruleNodeId) {
TbMsgMetaData metaData = new TbMsgMetaData();
metaData.putValue("ruleNodeId", ruleNodeId.toString());
diff --git a/rule-engine/rule-engine-api/src/main/java/org/thingsboard/rule/engine/api/TbContext.java b/rule-engine/rule-engine-api/src/main/java/org/thingsboard/rule/engine/api/TbContext.java
index 19607d2b00..c7b6ba377e 100644
--- a/rule-engine/rule-engine-api/src/main/java/org/thingsboard/rule/engine/api/TbContext.java
+++ b/rule-engine/rule-engine-api/src/main/java/org/thingsboard/rule/engine/api/TbContext.java
@@ -262,9 +262,15 @@ public interface TbContext {
SmsSenderFactory getSmsSenderFactory();
+ /**
+ * Creates JS Script Engine
+ * @deprecated
+ *
Use {@link #createScriptEngine} instead.
+ *
+ */
ScriptEngine createJsScriptEngine(String script, String... argNames);
- ScriptEngine createMvelScriptEngine(String script, String... argNames);
+ ScriptEngine createScriptEngine(ScriptLanguage scriptLang, String script, String... argNames);
void logJsEvalRequest();
@@ -302,5 +308,4 @@ public interface TbContext {
TenantProfile getTenantProfile();
- ScriptEngine createScriptEngine(ScriptLanguage scriptLang, String s);
}
diff --git a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/action/TbLogNode.java b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/action/TbLogNode.java
index 431d63a674..8ae88a57bf 100644
--- a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/action/TbLogNode.java
+++ b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/action/TbLogNode.java
@@ -29,6 +29,7 @@ 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.plugin.ComponentType;
+import org.thingsboard.server.common.data.script.ScriptLanguage;
import org.thingsboard.server.common.msg.TbMsg;
@Slf4j
@@ -47,14 +48,15 @@ import org.thingsboard.server.common.msg.TbMsg;
public class TbLogNode implements TbNode {
private TbLogNodeConfiguration config;
- private ScriptEngine jsEngine;
+ private ScriptEngine scriptEngine;
private boolean standard;
@Override
public void init(TbContext ctx, TbNodeConfiguration configuration) throws TbNodeException {
this.config = TbNodeUtils.convert(configuration, TbLogNodeConfiguration.class);
this.standard = new TbLogNodeConfiguration().defaultConfiguration().getJsScript().equals(config.getJsScript());
- this.jsEngine = this.standard ? null : ctx.createJsScriptEngine(config.getJsScript());
+ this.scriptEngine = this.standard ? null : ctx.createScriptEngine(config.getScriptLang(),
+ ScriptLanguage.MVEL.equals(config.getScriptLang()) ? config.getMvelScript() : config.getJsScript());
}
@Override
@@ -65,7 +67,7 @@ public class TbLogNode implements TbNode {
}
ctx.logJsEvalRequest();
- Futures.addCallback(jsEngine.executeToStringAsync(msg), new FutureCallback() {
+ Futures.addCallback(scriptEngine.executeToStringAsync(msg), new FutureCallback() {
@Override
public void onSuccess(@Nullable String result) {
ctx.logJsEvalResponse();
@@ -94,8 +96,8 @@ public class TbLogNode implements TbNode {
@Override
public void destroy() {
- if (jsEngine != null) {
- jsEngine.destroy();
+ if (scriptEngine != null) {
+ scriptEngine.destroy();
}
}
}
diff --git a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/action/TbLogNodeConfiguration.java b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/action/TbLogNodeConfiguration.java
index 453ade72a7..85eb3b8e04 100644
--- a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/action/TbLogNodeConfiguration.java
+++ b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/action/TbLogNodeConfiguration.java
@@ -17,16 +17,21 @@ package org.thingsboard.rule.engine.action;
import lombok.Data;
import org.thingsboard.rule.engine.api.NodeConfiguration;
+import org.thingsboard.server.common.data.script.ScriptLanguage;
@Data
public class TbLogNodeConfiguration implements NodeConfiguration {
+ private ScriptLanguage scriptLang;
private String jsScript;
+ private String mvelScript;
@Override
public TbLogNodeConfiguration defaultConfiguration() {
TbLogNodeConfiguration configuration = new TbLogNodeConfiguration();
+ configuration.setScriptLang(ScriptLanguage.MVEL);
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);");
return configuration;
}
}
diff --git a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/debug/TbMsgGeneratorNode.java b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/debug/TbMsgGeneratorNode.java
index 32ec34ef39..33ee9b497c 100644
--- a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/debug/TbMsgGeneratorNode.java
+++ b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/debug/TbMsgGeneratorNode.java
@@ -31,6 +31,7 @@ import org.thingsboard.rule.engine.api.util.TbNodeUtils;
import org.thingsboard.server.common.data.id.EntityId;
import org.thingsboard.server.common.data.id.EntityIdFactory;
import org.thingsboard.server.common.data.plugin.ComponentType;
+import org.thingsboard.server.common.data.script.ScriptLanguage;
import org.thingsboard.server.common.msg.TbMsg;
import org.thingsboard.server.common.msg.TbMsgMetaData;
import org.thingsboard.server.common.msg.queue.PartitionChangeMsg;
@@ -60,7 +61,7 @@ public class TbMsgGeneratorNode implements TbNode {
private static final String TB_MSG_GENERATOR_NODE_MSG = "TbMsgGeneratorNodeMsg";
private TbMsgGeneratorNodeConfiguration config;
- private ScriptEngine jsEngine;
+ private ScriptEngine scriptEngine;
private long delay;
private long lastScheduledTs;
private int currentMsgCount;
@@ -93,7 +94,8 @@ public class TbMsgGeneratorNode implements TbNode {
log.trace("updateGeneratorState, config {}", config);
if (ctx.isLocalEntity(originatorId)) {
if (initialized.compareAndSet(false, true)) {
- this.jsEngine = ctx.createJsScriptEngine(config.getJsScript(), "prevMsg", "prevMetadata", "prevMsgType");
+ this.scriptEngine = ctx.createScriptEngine(config.getScriptLang(),
+ ScriptLanguage.MVEL.equals(config.getScriptLang()) ? config.getMvelScript() : config.getJsScript(), "prevMsg", "prevMetadata", "prevMsgType");
scheduleTickMsg(ctx);
}
} else if (initialized.compareAndSet(true, false)) {
@@ -146,7 +148,7 @@ public class TbMsgGeneratorNode implements TbNode {
}
if (initialized.get()) {
ctx.logJsEvalRequest();
- return Futures.transformAsync(jsEngine.executeGenerateAsync(prevMsg), generated -> {
+ return Futures.transformAsync(scriptEngine.executeGenerateAsync(prevMsg), generated -> {
log.trace("generate process response, generated {}, config {}", generated, config);
ctx.logJsEvalResponse();
prevMsg = ctx.newMsg(null, generated.getType(), originatorId, msg.getCustomerId(), generated.getMetaData(), generated.getData());
@@ -161,9 +163,9 @@ public class TbMsgGeneratorNode implements TbNode {
public void destroy() {
log.trace("destroy, config {}", config);
prevMsg = null;
- if (jsEngine != null) {
- jsEngine.destroy();
- jsEngine = null;
+ if (scriptEngine != null) {
+ scriptEngine.destroy();
+ scriptEngine = null;
}
}
}
diff --git a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/debug/TbMsgGeneratorNodeConfiguration.java b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/debug/TbMsgGeneratorNodeConfiguration.java
index 540a3cc01d..9b037c9478 100644
--- a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/debug/TbMsgGeneratorNodeConfiguration.java
+++ b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/debug/TbMsgGeneratorNodeConfiguration.java
@@ -18,27 +18,33 @@ package org.thingsboard.rule.engine.debug;
import lombok.Data;
import org.thingsboard.rule.engine.api.NodeConfiguration;
import org.thingsboard.server.common.data.EntityType;
+import org.thingsboard.server.common.data.script.ScriptLanguage;
@Data
public class TbMsgGeneratorNodeConfiguration implements NodeConfiguration {
public static final int UNLIMITED_MSG_COUNT = 0;
+ public static final String DEFAULT_SCRIPT = "var msg = { temp: 42, humidity: 77 };\n" +
+ "var metadata = { data: 40 };\n" +
+ "var msgType = \"POST_TELEMETRY_REQUEST\";\n\n" +
+ "return { msg: msg, metadata: metadata, msgType: msgType };";
private int msgCount;
private int periodInSeconds;
private String originatorId;
private EntityType originatorType;
+ private ScriptLanguage scriptLang;
private String jsScript;
+ private String mvelScript;
@Override
public TbMsgGeneratorNodeConfiguration defaultConfiguration() {
TbMsgGeneratorNodeConfiguration configuration = new TbMsgGeneratorNodeConfiguration();
configuration.setMsgCount(UNLIMITED_MSG_COUNT);
configuration.setPeriodInSeconds(1);
- configuration.setJsScript("var msg = { temp: 42, humidity: 77 };\n" +
- "var metadata = { data: 40 };\n" +
- "var msgType = \"POST_TELEMETRY_REQUEST\";\n\n" +
- "return { msg: msg, metadata: metadata, msgType: msgType };");
+ configuration.setScriptLang(ScriptLanguage.MVEL);
+ configuration.setJsScript(DEFAULT_SCRIPT);
+ configuration.setMvelScript(DEFAULT_SCRIPT);
return configuration;
}
}
diff --git a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/filter/TbJsSwitchNode.java b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/filter/TbJsSwitchNode.java
index d35a383a0d..9fddb5ca8f 100644
--- a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/filter/TbJsSwitchNode.java
+++ b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/filter/TbJsSwitchNode.java
@@ -20,7 +20,6 @@ import com.google.common.util.concurrent.Futures;
import com.google.common.util.concurrent.MoreExecutors;
import lombok.extern.slf4j.Slf4j;
import org.checkerframework.checker.nullness.qual.Nullable;
-import org.thingsboard.common.util.ListeningExecutor;
import org.thingsboard.rule.engine.api.RuleNode;
import org.thingsboard.rule.engine.api.ScriptEngine;
import org.thingsboard.rule.engine.api.TbContext;
@@ -29,6 +28,7 @@ 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.plugin.ComponentType;
+import org.thingsboard.server.common.data.script.ScriptLanguage;
import org.thingsboard.server.common.msg.TbMsg;
import java.util.Set;
@@ -50,18 +50,19 @@ import java.util.Set;
public class TbJsSwitchNode implements TbNode {
private TbJsSwitchNodeConfiguration config;
- private ScriptEngine jsEngine;
+ private ScriptEngine scriptEngine;
@Override
public void init(TbContext ctx, TbNodeConfiguration configuration) throws TbNodeException {
this.config = TbNodeUtils.convert(configuration, TbJsSwitchNodeConfiguration.class);
- this.jsEngine = ctx.createJsScriptEngine(config.getJsScript());
+ this.scriptEngine = ctx.createScriptEngine(config.getScriptLang(),
+ ScriptLanguage.MVEL.equals(config.getScriptLang()) ? config.getMvelScript() : config.getJsScript());
}
@Override
public void onMsg(TbContext ctx, TbMsg msg) {
ctx.logJsEvalRequest();
- Futures.addCallback(jsEngine.executeSwitchAsync(msg), new FutureCallback>() {
+ Futures.addCallback(scriptEngine.executeSwitchAsync(msg), new FutureCallback<>() {
@Override
public void onSuccess(@Nullable Set result) {
ctx.logJsEvalResponse();
@@ -82,8 +83,8 @@ public class TbJsSwitchNode implements TbNode {
@Override
public void destroy() {
- if (jsEngine != null) {
- jsEngine.destroy();
+ if (scriptEngine != null) {
+ scriptEngine.destroy();
}
}
}
diff --git a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/filter/TbJsSwitchNodeConfiguration.java b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/filter/TbJsSwitchNodeConfiguration.java
index ab5d978b1c..c9f3ca224d 100644
--- a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/filter/TbJsSwitchNodeConfiguration.java
+++ b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/filter/TbJsSwitchNodeConfiguration.java
@@ -18,24 +18,31 @@ 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 {
+ private static final String DEFAULT_SCRIPT = "function nextRelation(metadata, msg) {\n" +
+ " return ['one','nine'];\n" +
+ "}\n" +
+ "if(msgType === 'POST_TELEMETRY_REQUEST') {\n" +
+ " return ['two'];\n" +
+ "}\n" +
+ "return nextRelation(metadata, msg);";
+
+ private ScriptLanguage scriptLang;
private String jsScript;
+ private String mvelScript;
@Override
public TbJsSwitchNodeConfiguration defaultConfiguration() {
TbJsSwitchNodeConfiguration configuration = new TbJsSwitchNodeConfiguration();
- configuration.setJsScript("function nextRelation(metadata, msg) {\n" +
- " return ['one','nine'];\n" +
- "}\n" +
- "if(msgType === 'POST_TELEMETRY_REQUEST') {\n" +
- " return ['two'];\n" +
- "}\n" +
- "return nextRelation(metadata, msg);");
+ configuration.setScriptLang(ScriptLanguage.MVEL);
+ configuration.setJsScript(DEFAULT_SCRIPT);
+ configuration.setMvelScript(DEFAULT_SCRIPT);
return configuration;
}
}
diff --git a/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/filter/TbJsSwitchNodeTest.java b/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/filter/TbJsSwitchNodeTest.java
index 62770d466c..5cd3ef632a 100644
--- a/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/filter/TbJsSwitchNodeTest.java
+++ b/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/filter/TbJsSwitchNodeTest.java
@@ -34,6 +34,7 @@ import org.thingsboard.rule.engine.api.TbNodeConfiguration;
import org.thingsboard.rule.engine.api.TbNodeException;
import org.thingsboard.server.common.data.id.RuleChainId;
import org.thingsboard.server.common.data.id.RuleNodeId;
+import org.thingsboard.server.common.data.script.ScriptLanguage;
import org.thingsboard.server.common.msg.TbMsg;
import org.thingsboard.server.common.msg.TbMsgDataType;
import org.thingsboard.server.common.msg.TbMsgMetaData;
@@ -56,8 +57,6 @@ public class TbJsSwitchNodeTest {
@Mock
private TbContext ctx;
@Mock
- private ListeningExecutor executor;
- @Mock
private ScriptEngine scriptEngine;
private RuleChainId ruleChainId = new RuleChainId(Uuids.timeBased());
@@ -80,22 +79,14 @@ public class TbJsSwitchNodeTest {
private void initWithScript() throws TbNodeException {
TbJsSwitchNodeConfiguration config = new TbJsSwitchNodeConfiguration();
+ config.setScriptLang(ScriptLanguage.JS);
config.setJsScript("scr");
ObjectMapper mapper = new ObjectMapper();
TbNodeConfiguration nodeConfiguration = new TbNodeConfiguration(mapper.valueToTree(config));
- when(ctx.createJsScriptEngine("scr")).thenReturn(scriptEngine);
+ when(ctx.createScriptEngine(ScriptLanguage.JS, "scr")).thenReturn(scriptEngine);
node = new TbJsSwitchNode();
node.init(ctx, nodeConfiguration);
}
-
- private void verifyError(TbMsg msg, String message, Class expectedClass) {
- ArgumentCaptor captor = ArgumentCaptor.forClass(Throwable.class);
- verify(ctx).tellFailure(same(msg), captor.capture());
-
- Throwable value = captor.getValue();
- assertEquals(expectedClass, value.getClass());
- assertEquals(message, value.getMessage());
- }
}