Test script controller and test fixes
This commit is contained in:
parent
d3f06bd3a4
commit
42832aab8c
@ -38,6 +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.server.actors.ActorSystemContext;
|
||||
import org.thingsboard.server.actors.tenant.DebugTbRateLimits;
|
||||
import org.thingsboard.server.common.data.EventInfo;
|
||||
@ -60,6 +61,7 @@ import org.thingsboard.server.common.data.rule.RuleChainImportResult;
|
||||
import org.thingsboard.server.common.data.rule.RuleChainMetaData;
|
||||
import org.thingsboard.server.common.data.rule.RuleChainOutputLabelsUsage;
|
||||
import org.thingsboard.server.common.data.rule.RuleChainType;
|
||||
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;
|
||||
@ -67,6 +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.security.permission.Operation;
|
||||
import org.thingsboard.server.service.security.permission.Resource;
|
||||
|
||||
@ -117,10 +120,10 @@ public class RuleChainController extends BaseController {
|
||||
private static final String RULE_CHAIN_DESCRIPTION = "The rule chain object is lightweight and contains general information about the rule chain. " +
|
||||
"List of rule nodes and their connection is stored in a separate 'metadata' object.";
|
||||
private static final String RULE_CHAIN_METADATA_DESCRIPTION = "The metadata object contains information about the rule nodes and their connections.";
|
||||
private static final String TEST_JS_FUNCTION = "Execute the JavaScript function and return the result. The format of request: \n\n"
|
||||
private static final String TEST_SCRIPT_FUNCTION = "Execute the Script function and return the result. The format of request: \n\n"
|
||||
+ MARKDOWN_CODE_BLOCK_START
|
||||
+ "{\n" +
|
||||
" \"script\": \"Your JS Function as String\",\n" +
|
||||
" \"script\": \"Your Function as String\",\n" +
|
||||
" \"scriptType\": \"One of: update, generate, filter, switch, json, string\",\n" +
|
||||
" \"argNames\": [\"msg\", \"metadata\", \"type\"],\n" +
|
||||
" \"msg\": \"{\\\"temperature\\\": 42}\", \n" +
|
||||
@ -140,7 +143,10 @@ public class RuleChainController extends BaseController {
|
||||
private EventService eventService;
|
||||
|
||||
@Autowired
|
||||
private JsInvokeService scriptInvokeService;
|
||||
private JsInvokeService jsInvokeService;
|
||||
|
||||
@Autowired(required = false)
|
||||
private MvelInvokeService mvelInvokeService;
|
||||
|
||||
@Autowired(required = false)
|
||||
private ActorSystemContext actorContext;
|
||||
@ -148,6 +154,9 @@ 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;
|
||||
|
||||
@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)
|
||||
@PreAuthorize("hasAnyAuthority('TENANT_ADMIN')")
|
||||
@ -369,13 +378,23 @@ 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)
|
||||
@PreAuthorize("hasAuthority('TENANT_ADMIN')")
|
||||
@RequestMapping(value = "/ruleChain/mvelEnabled", method = RequestMethod.GET)
|
||||
@ResponseBody
|
||||
public Boolean isMvelEnabled() {
|
||||
return mvelEnabled;
|
||||
}
|
||||
|
||||
@ApiOperation(value = "Test JavaScript function",
|
||||
notes = TEST_JS_FUNCTION + TENANT_AUTHORITY_PARAGRAPH)
|
||||
@ApiOperation(value = "Test Script function",
|
||||
notes = TEST_SCRIPT_FUNCTION + TENANT_AUTHORITY_PARAGRAPH)
|
||||
@PreAuthorize("hasAuthority('TENANT_ADMIN')")
|
||||
@RequestMapping(value = "/ruleChain/testScript", method = RequestMethod.POST)
|
||||
@ResponseBody
|
||||
public JsonNode testScript(
|
||||
@ApiParam(value = "Script language: JS or MVEL")
|
||||
@RequestParam(required = false) ScriptLanguage scriptLang,
|
||||
@ApiParam(value = "Test JS request. See API call description above.")
|
||||
@RequestBody JsonNode inputParams) throws ThingsboardException {
|
||||
try {
|
||||
@ -393,7 +412,17 @@ public class RuleChainController extends BaseController {
|
||||
String errorText = "";
|
||||
ScriptEngine engine = null;
|
||||
try {
|
||||
engine = new RuleNodeJsScriptEngine(getTenantId(), scriptInvokeService, script, argNames);
|
||||
if (scriptLang == null) {
|
||||
scriptLang = ScriptLanguage.JS;
|
||||
}
|
||||
if (ScriptLanguage.JS.equals(scriptLang)) {
|
||||
engine = new RuleNodeJsScriptEngine(getTenantId(), jsInvokeService, script, argNames);
|
||||
} else {
|
||||
if (mvelInvokeService == null) {
|
||||
throw new IllegalArgumentException("MVEL script engine is disabled!");
|
||||
}
|
||||
engine = new RuleNodeMvelScriptEngine(getTenantId(), mvelInvokeService, script, argNames);
|
||||
}
|
||||
TbMsg inMsg = TbMsg.newMsg(msgType, null, new TbMsgMetaData(metadata), TbMsgDataType.JSON, data);
|
||||
switch (scriptType) {
|
||||
case "update":
|
||||
|
||||
@ -40,9 +40,9 @@ import static org.thingsboard.common.util.DonAsynchron.withCallback;
|
||||
"If <b>True</b> - send Message via <b>True</b> chain, otherwise <b>False</b> chain is used." +
|
||||
"Message payload can be accessed via <code>msg</code> property. For example <code>msg.temperature < 10;</code><br/>" +
|
||||
"Message metadata can be accessed via <code>metadata</code> property. For example <code>metadata.customerName === 'John';</code><br/>" +
|
||||
"Message type can be accessed via <code>msgType</code> property."
|
||||
// uiResources = {"static/rulenode/rulenode-core-config.js"},
|
||||
// configDirective = "tbFilterNodeScriptConfig")
|
||||
"Message type can be accessed via <code>msgType</code> property.",
|
||||
uiResources = {"static/rulenode/rulenode-core-config.js"},
|
||||
configDirective = "tbFilterNodeScriptConfig"
|
||||
)
|
||||
public class TbJsFilterNode implements TbNode {
|
||||
|
||||
|
||||
@ -40,9 +40,9 @@ import java.util.List;
|
||||
"<code>msgType</code> - is a Message type.<br/>" +
|
||||
"Should return the following structure:<br/>" +
|
||||
"<code>{ msg: <i style=\"color: #666;\">new payload</i>,<br/>   metadata: <i style=\"color: #666;\">new metadata</i>,<br/>   msgType: <i style=\"color: #666;\">new msgType</i> }</code><br/>" +
|
||||
"All fields in resulting object are optional and will be taken from original message if not specified."
|
||||
// uiResources = {"static/rulenode/rulenode-core-config.js"},
|
||||
// configDirective = "tbTransformationNodeScriptConfig"
|
||||
"All fields in resulting object are optional and will be taken from original message if not specified.",
|
||||
uiResources = {"static/rulenode/rulenode-core-config.js"},
|
||||
configDirective = "tbTransformationNodeScriptConfig"
|
||||
)
|
||||
public class TbTransformMsgNode extends TbAbstractTransformNode {
|
||||
|
||||
|
||||
@ -42,6 +42,7 @@ import org.thingsboard.server.common.data.id.EntityId;
|
||||
import org.thingsboard.server.common.data.id.RuleChainId;
|
||||
import org.thingsboard.server.common.data.id.RuleNodeId;
|
||||
import org.thingsboard.server.common.data.id.TenantId;
|
||||
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;
|
||||
@ -180,7 +181,7 @@ public class TbAlarmNodeTest {
|
||||
|
||||
verifyError(msg, "message", NotImplementedException.class);
|
||||
|
||||
verify(ctx).createJsScriptEngine("DETAILS");
|
||||
verify(ctx).createScriptEngine(ScriptLanguage.JS, "DETAILS");
|
||||
verify(ctx).getAlarmService();
|
||||
verify(ctx, times(3)).getDbCallbackExecutor();
|
||||
verify(ctx).logJsEvalRequest();
|
||||
@ -395,12 +396,13 @@ public class TbAlarmNodeTest {
|
||||
config.setPropagate(true);
|
||||
config.setSeverity("$[alarmSeverity]");
|
||||
config.setAlarmType("SomeType");
|
||||
config.setScriptLang(ScriptLanguage.JS);
|
||||
config.setAlarmDetailsBuildJs("DETAILS");
|
||||
config.setDynamicSeverity(true);
|
||||
ObjectMapper mapper = new ObjectMapper();
|
||||
TbNodeConfiguration nodeConfiguration = new TbNodeConfiguration(mapper.valueToTree(config));
|
||||
|
||||
when(ctx.createJsScriptEngine("DETAILS")).thenReturn(detailsJs);
|
||||
when(ctx.createScriptEngine(ScriptLanguage.JS, "DETAILS")).thenReturn(detailsJs);
|
||||
|
||||
when(ctx.getTenantId()).thenReturn(tenantId);
|
||||
when(ctx.getAlarmService()).thenReturn(alarmService);
|
||||
@ -456,6 +458,7 @@ public class TbAlarmNodeTest {
|
||||
public void testCreateAlarmWithDynamicSeverityFromMetadata() throws Exception {
|
||||
TbCreateAlarmNodeConfiguration config = new TbCreateAlarmNodeConfiguration();
|
||||
config.setPropagate(true);
|
||||
config.setScriptLang(ScriptLanguage.JS);
|
||||
config.setSeverity("${alarmSeverity}");
|
||||
config.setAlarmType("SomeType");
|
||||
config.setAlarmDetailsBuildJs("DETAILS");
|
||||
@ -463,7 +466,7 @@ public class TbAlarmNodeTest {
|
||||
ObjectMapper mapper = new ObjectMapper();
|
||||
TbNodeConfiguration nodeConfiguration = new TbNodeConfiguration(mapper.valueToTree(config));
|
||||
|
||||
when(ctx.createJsScriptEngine("DETAILS")).thenReturn(detailsJs);
|
||||
when(ctx.createScriptEngine(ScriptLanguage.JS, "DETAILS")).thenReturn(detailsJs);
|
||||
|
||||
when(ctx.getTenantId()).thenReturn(tenantId);
|
||||
when(ctx.getAlarmService()).thenReturn(alarmService);
|
||||
@ -521,12 +524,13 @@ public class TbAlarmNodeTest {
|
||||
config.setPropagateToTenant(true);
|
||||
config.setSeverity(CRITICAL.name());
|
||||
config.setAlarmType("SomeType" + i);
|
||||
config.setScriptLang(ScriptLanguage.JS);
|
||||
config.setAlarmDetailsBuildJs("DETAILS");
|
||||
config.setDynamicSeverity(true);
|
||||
ObjectMapper mapper = new ObjectMapper();
|
||||
TbNodeConfiguration nodeConfiguration = new TbNodeConfiguration(mapper.valueToTree(config));
|
||||
|
||||
when(ctx.createJsScriptEngine("DETAILS")).thenReturn(detailsJs);
|
||||
when(ctx.createScriptEngine(ScriptLanguage.JS, "DETAILS")).thenReturn(detailsJs);
|
||||
|
||||
when(ctx.getTenantId()).thenReturn(tenantId);
|
||||
when(ctx.getAlarmService()).thenReturn(alarmService);
|
||||
@ -584,11 +588,12 @@ public class TbAlarmNodeTest {
|
||||
config.setPropagate(true);
|
||||
config.setSeverity(CRITICAL.name());
|
||||
config.setAlarmType("SomeType");
|
||||
config.setScriptLang(ScriptLanguage.JS);
|
||||
config.setAlarmDetailsBuildJs("DETAILS");
|
||||
ObjectMapper mapper = new ObjectMapper();
|
||||
TbNodeConfiguration nodeConfiguration = new TbNodeConfiguration(mapper.valueToTree(config));
|
||||
|
||||
when(ctx.createJsScriptEngine("DETAILS")).thenReturn(detailsJs);
|
||||
when(ctx.createScriptEngine(ScriptLanguage.JS, "DETAILS")).thenReturn(detailsJs);
|
||||
|
||||
when(ctx.getTenantId()).thenReturn(tenantId);
|
||||
when(ctx.getAlarmService()).thenReturn(alarmService);
|
||||
@ -605,11 +610,12 @@ public class TbAlarmNodeTest {
|
||||
try {
|
||||
TbClearAlarmNodeConfiguration config = new TbClearAlarmNodeConfiguration();
|
||||
config.setAlarmType("SomeType");
|
||||
config.setScriptLang(ScriptLanguage.JS);
|
||||
config.setAlarmDetailsBuildJs("DETAILS");
|
||||
ObjectMapper mapper = new ObjectMapper();
|
||||
TbNodeConfiguration nodeConfiguration = new TbNodeConfiguration(mapper.valueToTree(config));
|
||||
|
||||
when(ctx.createJsScriptEngine("DETAILS")).thenReturn(detailsJs);
|
||||
when(ctx.createScriptEngine(ScriptLanguage.JS, "DETAILS")).thenReturn(detailsJs);
|
||||
|
||||
when(ctx.getTenantId()).thenReturn(tenantId);
|
||||
when(ctx.getAlarmService()).thenReturn(alarmService);
|
||||
|
||||
@ -33,6 +33,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;
|
||||
@ -54,8 +55,6 @@ public class TbJsFilterNodeTest {
|
||||
@Mock
|
||||
private TbContext ctx;
|
||||
@Mock
|
||||
private ListeningExecutor executor;
|
||||
@Mock
|
||||
private ScriptEngine scriptEngine;
|
||||
|
||||
private RuleChainId ruleChainId = new RuleChainId(Uuids.timeBased());
|
||||
@ -73,7 +72,7 @@ public class TbJsFilterNodeTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void exceptionInJsThrowsException() throws TbNodeException, ScriptException {
|
||||
public void exceptionInJsThrowsException() throws TbNodeException {
|
||||
initWithScript();
|
||||
TbMsgMetaData metaData = new TbMsgMetaData();
|
||||
TbMsg msg = TbMsg.newMsg("USER", null, metaData, TbMsgDataType.JSON, "{}", ruleChainId, ruleNodeId);
|
||||
@ -85,7 +84,7 @@ public class TbJsFilterNodeTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void metadataConditionCanBeTrue() throws TbNodeException, ScriptException {
|
||||
public void metadataConditionCanBeTrue() throws TbNodeException {
|
||||
initWithScript();
|
||||
TbMsgMetaData metaData = new TbMsgMetaData();
|
||||
TbMsg msg = TbMsg.newMsg("USER", null, metaData, TbMsgDataType.JSON, "{}", ruleChainId, ruleNodeId);
|
||||
@ -98,11 +97,12 @@ public class TbJsFilterNodeTest {
|
||||
|
||||
private void initWithScript() throws TbNodeException {
|
||||
TbJsFilterNodeConfiguration config = new TbJsFilterNodeConfiguration();
|
||||
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 TbJsFilterNode();
|
||||
node.init(ctx, nodeConfiguration);
|
||||
|
||||
@ -33,6 +33,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;
|
||||
@ -55,12 +56,10 @@ public class TbTransformMsgNodeTest {
|
||||
@Mock
|
||||
private TbContext ctx;
|
||||
@Mock
|
||||
private ListeningExecutor executor;
|
||||
@Mock
|
||||
private ScriptEngine scriptEngine;
|
||||
|
||||
@Test
|
||||
public void metadataCanBeUpdated() throws TbNodeException, ScriptException {
|
||||
public void metadataCanBeUpdated() throws TbNodeException {
|
||||
initWithScript();
|
||||
TbMsgMetaData metaData = new TbMsgMetaData();
|
||||
metaData.putValue("temp", "7");
|
||||
@ -80,7 +79,7 @@ public class TbTransformMsgNodeTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void exceptionHandledCorrectly() throws TbNodeException, ScriptException {
|
||||
public void exceptionHandledCorrectly() throws TbNodeException {
|
||||
initWithScript();
|
||||
TbMsgMetaData metaData = new TbMsgMetaData();
|
||||
metaData.putValue("temp", "7");
|
||||
@ -97,11 +96,12 @@ public class TbTransformMsgNodeTest {
|
||||
|
||||
private void initWithScript() throws TbNodeException {
|
||||
TbTransformMsgNodeConfiguration config = new TbTransformMsgNodeConfiguration();
|
||||
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 TbTransformMsgNode();
|
||||
node.init(ctx, nodeConfiguration);
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user