JavaScript sandbox service.
This commit is contained in:
parent
02f24ca672
commit
04432ee73f
@ -256,6 +256,10 @@
|
|||||||
<groupId>org.hsqldb</groupId>
|
<groupId>org.hsqldb</groupId>
|
||||||
<artifactId>hsqldb</artifactId>
|
<artifactId>hsqldb</artifactId>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.javadelight</groupId>
|
||||||
|
<artifactId>delight-nashorn-sandbox</artifactId>
|
||||||
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|
||||||
<build>
|
<build>
|
||||||
|
|||||||
@ -62,6 +62,7 @@ import org.thingsboard.server.service.mail.MailExecutorService;
|
|||||||
import org.thingsboard.server.service.queue.MsgQueueService;
|
import org.thingsboard.server.service.queue.MsgQueueService;
|
||||||
import org.thingsboard.server.service.rpc.DeviceRpcService;
|
import org.thingsboard.server.service.rpc.DeviceRpcService;
|
||||||
import org.thingsboard.server.service.script.JsExecutorService;
|
import org.thingsboard.server.service.script.JsExecutorService;
|
||||||
|
import org.thingsboard.server.service.script.JsSandboxService;
|
||||||
import org.thingsboard.server.service.state.DeviceStateService;
|
import org.thingsboard.server.service.state.DeviceStateService;
|
||||||
import org.thingsboard.server.service.telemetry.TelemetrySubscriptionService;
|
import org.thingsboard.server.service.telemetry.TelemetrySubscriptionService;
|
||||||
|
|
||||||
@ -162,6 +163,10 @@ public class ActorSystemContext {
|
|||||||
@Getter
|
@Getter
|
||||||
private DeviceRpcService deviceRpcService;
|
private DeviceRpcService deviceRpcService;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
@Getter
|
||||||
|
private JsSandboxService jsSandbox;
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
@Getter
|
@Getter
|
||||||
private JsExecutorService jsExecutor;
|
private JsExecutorService jsExecutor;
|
||||||
|
|||||||
@ -44,7 +44,7 @@ import org.thingsboard.server.dao.relation.RelationService;
|
|||||||
import org.thingsboard.server.dao.rule.RuleChainService;
|
import org.thingsboard.server.dao.rule.RuleChainService;
|
||||||
import org.thingsboard.server.dao.timeseries.TimeseriesService;
|
import org.thingsboard.server.dao.timeseries.TimeseriesService;
|
||||||
import org.thingsboard.server.dao.user.UserService;
|
import org.thingsboard.server.dao.user.UserService;
|
||||||
import org.thingsboard.server.service.script.NashornJsEngine;
|
import org.thingsboard.server.service.script.JsScriptEngine;
|
||||||
import scala.concurrent.duration.Duration;
|
import scala.concurrent.duration.Duration;
|
||||||
|
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
@ -152,7 +152,7 @@ class DefaultTbContext implements TbContext {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ScriptEngine createJsScriptEngine(String script, String functionName, String... argNames) {
|
public ScriptEngine createJsScriptEngine(String script, String functionName, String... argNames) {
|
||||||
return new NashornJsEngine(script, functionName, argNames);
|
return new JsScriptEngine(mainCtx.getJsSandbox(), script, functionName, argNames);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@ -50,7 +50,9 @@ import org.thingsboard.server.common.data.rule.RuleChainMetaData;
|
|||||||
import org.thingsboard.server.common.msg.TbMsg;
|
import org.thingsboard.server.common.msg.TbMsg;
|
||||||
import org.thingsboard.server.common.msg.TbMsgMetaData;
|
import org.thingsboard.server.common.msg.TbMsgMetaData;
|
||||||
import org.thingsboard.server.dao.event.EventService;
|
import org.thingsboard.server.dao.event.EventService;
|
||||||
import org.thingsboard.server.service.script.NashornJsEngine;
|
import org.thingsboard.server.service.script.JsExecutorService;
|
||||||
|
import org.thingsboard.server.service.script.JsSandboxService;
|
||||||
|
import org.thingsboard.server.service.script.JsScriptEngine;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
@ -69,6 +71,9 @@ public class RuleChainController extends BaseController {
|
|||||||
@Autowired
|
@Autowired
|
||||||
private EventService eventService;
|
private EventService eventService;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private JsSandboxService jsSandboxService;
|
||||||
|
|
||||||
@PreAuthorize("hasAnyAuthority('TENANT_ADMIN')")
|
@PreAuthorize("hasAnyAuthority('TENANT_ADMIN')")
|
||||||
@RequestMapping(value = "/ruleChain/{ruleChainId}", method = RequestMethod.GET)
|
@RequestMapping(value = "/ruleChain/{ruleChainId}", method = RequestMethod.GET)
|
||||||
@ResponseBody
|
@ResponseBody
|
||||||
@ -273,7 +278,7 @@ public class RuleChainController extends BaseController {
|
|||||||
String errorText = "";
|
String errorText = "";
|
||||||
ScriptEngine engine = null;
|
ScriptEngine engine = null;
|
||||||
try {
|
try {
|
||||||
engine = new NashornJsEngine(script, functionName, argNames);
|
engine = new JsScriptEngine(jsSandboxService, script, functionName, argNames);
|
||||||
TbMsg inMsg = new TbMsg(UUIDs.timeBased(), msgType, null, new TbMsgMetaData(metadata), data, null, null, 0L);
|
TbMsg inMsg = new TbMsg(UUIDs.timeBased(), msgType, null, new TbMsgMetaData(metadata), data, null, null, 0L);
|
||||||
switch (scriptType) {
|
switch (scriptType) {
|
||||||
case "update":
|
case "update":
|
||||||
|
|||||||
@ -54,6 +54,10 @@ public abstract class AbstractListeningExecutor implements ListeningExecutor {
|
|||||||
service.execute(command);
|
service.execute(command);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public ListeningExecutorService executor() {
|
||||||
|
return service;
|
||||||
|
}
|
||||||
|
|
||||||
protected abstract int getThreadPollSize();
|
protected abstract int getThreadPollSize();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -0,0 +1,27 @@
|
|||||||
|
/**
|
||||||
|
* Copyright © 2016-2018 The Thingsboard Authors
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.thingsboard.server.service.script;
|
||||||
|
|
||||||
|
import javax.script.ScriptException;
|
||||||
|
|
||||||
|
public interface JsSandboxService {
|
||||||
|
|
||||||
|
Object eval(String js) throws ScriptException;
|
||||||
|
|
||||||
|
Object invokeFunction(String name, Object... args) throws ScriptException, NoSuchMethodException;
|
||||||
|
|
||||||
|
}
|
||||||
@ -19,14 +19,11 @@ import com.fasterxml.jackson.core.type.TypeReference;
|
|||||||
import com.fasterxml.jackson.databind.JsonNode;
|
import com.fasterxml.jackson.databind.JsonNode;
|
||||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
import com.google.common.collect.Sets;
|
import com.google.common.collect.Sets;
|
||||||
import jdk.nashorn.api.scripting.NashornScriptEngineFactory;
|
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
import org.thingsboard.server.common.msg.TbMsg;
|
import org.thingsboard.server.common.msg.TbMsg;
|
||||||
import org.thingsboard.server.common.msg.TbMsgMetaData;
|
import org.thingsboard.server.common.msg.TbMsgMetaData;
|
||||||
|
|
||||||
import javax.script.Invocable;
|
|
||||||
import javax.script.ScriptEngine;
|
|
||||||
import javax.script.ScriptException;
|
import javax.script.ScriptException;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
@ -34,7 +31,7 @@ import java.util.Set;
|
|||||||
|
|
||||||
|
|
||||||
@Slf4j
|
@Slf4j
|
||||||
public class NashornJsEngine implements org.thingsboard.rule.engine.api.ScriptEngine {
|
public class JsScriptEngine implements org.thingsboard.rule.engine.api.ScriptEngine {
|
||||||
|
|
||||||
public static final String MSG = "msg";
|
public static final String MSG = "msg";
|
||||||
public static final String METADATA = "metadata";
|
public static final String METADATA = "metadata";
|
||||||
@ -49,12 +46,14 @@ public class NashornJsEngine implements org.thingsboard.rule.engine.api.ScriptEn
|
|||||||
"\n}";
|
"\n}";
|
||||||
|
|
||||||
private static final ObjectMapper mapper = new ObjectMapper();
|
private static final ObjectMapper mapper = new ObjectMapper();
|
||||||
private static NashornScriptEngineFactory factory = new NashornScriptEngineFactory();
|
// private static NashornScriptEngineFactory factory = new NashornScriptEngineFactory();
|
||||||
private ScriptEngine engine = factory.getScriptEngine(new String[]{"--no-java"});
|
// private ScriptEngine engine = factory.getScriptEngine(new String[]{"--no-java"});
|
||||||
|
private final JsSandboxService sandboxService;
|
||||||
|
|
||||||
private final String invokeFunctionName;
|
private final String invokeFunctionName;
|
||||||
|
|
||||||
public NashornJsEngine(String script, String functionName, String... argNames) {
|
public JsScriptEngine(JsSandboxService sandboxService, String script, String functionName, String... argNames) {
|
||||||
|
this.sandboxService = sandboxService;
|
||||||
this.invokeFunctionName = "invokeInternal" + this.hashCode();
|
this.invokeFunctionName = "invokeInternal" + this.hashCode();
|
||||||
String msgArg;
|
String msgArg;
|
||||||
String metadataArg;
|
String metadataArg;
|
||||||
@ -75,7 +74,8 @@ public class NashornJsEngine implements org.thingsboard.rule.engine.api.ScriptEn
|
|||||||
|
|
||||||
private void compileScript(String script) {
|
private void compileScript(String script) {
|
||||||
try {
|
try {
|
||||||
engine.eval(script);
|
//engine.eval(script);
|
||||||
|
sandboxService.eval(script);
|
||||||
} catch (ScriptException e) {
|
} catch (ScriptException e) {
|
||||||
log.warn("Failed to compile JS script: {}", e.getMessage(), e);
|
log.warn("Failed to compile JS script: {}", e.getMessage(), e);
|
||||||
throw new IllegalArgumentException("Can't compile script: " + e.getMessage());
|
throw new IllegalArgumentException("Can't compile script: " + e.getMessage());
|
||||||
@ -195,7 +195,8 @@ public class NashornJsEngine implements org.thingsboard.rule.engine.api.ScriptEn
|
|||||||
private JsonNode executeScript(TbMsg msg) throws ScriptException {
|
private JsonNode executeScript(TbMsg msg) throws ScriptException {
|
||||||
try {
|
try {
|
||||||
String[] inArgs = prepareArgs(msg);
|
String[] inArgs = prepareArgs(msg);
|
||||||
String eval = ((Invocable)engine).invokeFunction(this.invokeFunctionName, inArgs[0], inArgs[1], inArgs[2]).toString();
|
//String eval = ((Invocable)engine).invokeFunction(this.invokeFunctionName, inArgs[0], inArgs[1], inArgs[2]).toString();
|
||||||
|
String eval = sandboxService.invokeFunction(this.invokeFunctionName, inArgs[0], inArgs[1], inArgs[2]).toString();
|
||||||
return mapper.readTree(eval);
|
return mapper.readTree(eval);
|
||||||
} catch (ScriptException | IllegalArgumentException th) {
|
} catch (ScriptException | IllegalArgumentException th) {
|
||||||
throw th;
|
throw th;
|
||||||
@ -206,6 +207,6 @@ public class NashornJsEngine implements org.thingsboard.rule.engine.api.ScriptEn
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void destroy() {
|
public void destroy() {
|
||||||
engine = null;
|
//engine = null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -0,0 +1,70 @@
|
|||||||
|
/**
|
||||||
|
* Copyright © 2016-2018 The Thingsboard Authors
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.thingsboard.server.service.script;
|
||||||
|
|
||||||
|
import delight.nashornsandbox.NashornSandbox;
|
||||||
|
import delight.nashornsandbox.NashornSandboxes;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.springframework.beans.factory.annotation.Value;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
|
import javax.annotation.PostConstruct;
|
||||||
|
import javax.annotation.PreDestroy;
|
||||||
|
import javax.script.ScriptException;
|
||||||
|
import java.util.concurrent.ExecutorService;
|
||||||
|
import java.util.concurrent.Executors;
|
||||||
|
|
||||||
|
@Slf4j
|
||||||
|
@Service
|
||||||
|
public class NashornJsSandboxService implements JsSandboxService {
|
||||||
|
|
||||||
|
@Value("${actors.rule.js_sandbox.monitor_thread_pool_size}")
|
||||||
|
private int monitorThreadPoolSize;
|
||||||
|
|
||||||
|
@Value("${actors.rule.js_sandbox.max_cpu_time}")
|
||||||
|
private long maxCpuTime;
|
||||||
|
|
||||||
|
private NashornSandbox sandbox = NashornSandboxes.create();
|
||||||
|
private ExecutorService monitorExecutorService;
|
||||||
|
|
||||||
|
@PostConstruct
|
||||||
|
public void init() {
|
||||||
|
monitorExecutorService = Executors.newFixedThreadPool(monitorThreadPoolSize);
|
||||||
|
sandbox.setExecutor(monitorExecutorService);
|
||||||
|
sandbox.setMaxCPUTime(maxCpuTime);
|
||||||
|
sandbox.allowNoBraces(false);
|
||||||
|
sandbox.setMaxPreparedStatements(30);
|
||||||
|
}
|
||||||
|
|
||||||
|
@PreDestroy
|
||||||
|
public void stop() {
|
||||||
|
if (monitorExecutorService != null) {
|
||||||
|
monitorExecutorService.shutdownNow();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Object eval(String js) throws ScriptException {
|
||||||
|
return sandbox.eval(js);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Object invokeFunction(String name, Object... args) throws ScriptException, NoSuchMethodException {
|
||||||
|
return sandbox.getSandboxedInvocable().invokeFunction(name, args);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@ -238,6 +238,11 @@ actors:
|
|||||||
mail_thread_pool_size: "${ACTORS_RULE_MAIL_THREAD_POOL_SIZE:10}"
|
mail_thread_pool_size: "${ACTORS_RULE_MAIL_THREAD_POOL_SIZE:10}"
|
||||||
# Specify thread pool size for external call service
|
# Specify thread pool size for external call service
|
||||||
external_call_thread_pool_size: "${ACTORS_RULE_EXTERNAL_CALL_THREAD_POOL_SIZE:10}"
|
external_call_thread_pool_size: "${ACTORS_RULE_EXTERNAL_CALL_THREAD_POOL_SIZE:10}"
|
||||||
|
js_sandbox:
|
||||||
|
# Specify thread pool size for JavaScript sandbox resource monitor
|
||||||
|
monitor_thread_pool_size: "${ACTORS_RULE_JS_SANDBOX_MONITOR_THREAD_POOL_SIZE:4}"
|
||||||
|
# Maximum CPU time in milliseconds allowed for script execution
|
||||||
|
max_cpu_time: "${ACTORS_RULE_JS_SANDBOX_MAX_CPU_TIME:100}"
|
||||||
chain:
|
chain:
|
||||||
# Errors for particular actor are persisted once per specified amount of milliseconds
|
# Errors for particular actor are persisted once per specified amount of milliseconds
|
||||||
error_persist_frequency: "${ACTORS_RULE_CHAIN_ERROR_FREQUENCY:3000}"
|
error_persist_frequency: "${ACTORS_RULE_CHAIN_ERROR_FREQUENCY:3000}"
|
||||||
|
|||||||
@ -17,6 +17,8 @@ package org.thingsboard.server.service.script;
|
|||||||
|
|
||||||
import com.datastax.driver.core.utils.UUIDs;
|
import com.datastax.driver.core.utils.UUIDs;
|
||||||
import com.google.common.collect.Sets;
|
import com.google.common.collect.Sets;
|
||||||
|
import org.junit.After;
|
||||||
|
import org.junit.Before;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import org.thingsboard.rule.engine.api.ScriptEngine;
|
import org.thingsboard.rule.engine.api.ScriptEngine;
|
||||||
import org.thingsboard.server.common.msg.TbMsg;
|
import org.thingsboard.server.common.msg.TbMsg;
|
||||||
@ -25,17 +27,30 @@ import org.thingsboard.server.common.msg.TbMsgMetaData;
|
|||||||
import javax.script.ScriptException;
|
import javax.script.ScriptException;
|
||||||
|
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
import java.util.concurrent.ExecutorService;
|
||||||
|
import java.util.concurrent.Executors;
|
||||||
|
|
||||||
import static org.junit.Assert.*;
|
import static org.junit.Assert.*;
|
||||||
|
|
||||||
public class NashornJsEngineTest {
|
public class JsScriptEngineTest {
|
||||||
|
|
||||||
private ScriptEngine scriptEngine;
|
private ScriptEngine scriptEngine;
|
||||||
|
private TestNashornJsSandboxService jsSandboxService;
|
||||||
|
|
||||||
|
@Before
|
||||||
|
public void beforeTest() throws Exception {
|
||||||
|
jsSandboxService = new TestNashornJsSandboxService(1, 100);
|
||||||
|
}
|
||||||
|
|
||||||
|
@After
|
||||||
|
public void afterTest() throws Exception {
|
||||||
|
jsSandboxService.destroy();
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void msgCanBeUpdated() throws ScriptException {
|
public void msgCanBeUpdated() throws ScriptException {
|
||||||
String function = "metadata.temp = metadata.temp * 10; return {metadata: metadata};";
|
String function = "metadata.temp = metadata.temp * 10; return {metadata: metadata};";
|
||||||
scriptEngine = new NashornJsEngine(function, "Transform");
|
scriptEngine = new JsScriptEngine(jsSandboxService, function, "Transform");
|
||||||
|
|
||||||
TbMsgMetaData metaData = new TbMsgMetaData();
|
TbMsgMetaData metaData = new TbMsgMetaData();
|
||||||
metaData.putValue("temp", "7");
|
metaData.putValue("temp", "7");
|
||||||
@ -51,7 +66,7 @@ public class NashornJsEngineTest {
|
|||||||
@Test
|
@Test
|
||||||
public void newAttributesCanBeAddedInMsg() throws ScriptException {
|
public void newAttributesCanBeAddedInMsg() throws ScriptException {
|
||||||
String function = "metadata.newAttr = metadata.humidity - msg.passed; return {metadata: metadata};";
|
String function = "metadata.newAttr = metadata.humidity - msg.passed; return {metadata: metadata};";
|
||||||
scriptEngine = new NashornJsEngine(function, "Transform");
|
scriptEngine = new JsScriptEngine(jsSandboxService, function, "Transform");
|
||||||
TbMsgMetaData metaData = new TbMsgMetaData();
|
TbMsgMetaData metaData = new TbMsgMetaData();
|
||||||
metaData.putValue("temp", "7");
|
metaData.putValue("temp", "7");
|
||||||
metaData.putValue("humidity", "99");
|
metaData.putValue("humidity", "99");
|
||||||
@ -66,7 +81,7 @@ public class NashornJsEngineTest {
|
|||||||
@Test
|
@Test
|
||||||
public void payloadCanBeUpdated() throws ScriptException {
|
public void payloadCanBeUpdated() throws ScriptException {
|
||||||
String function = "msg.passed = msg.passed * metadata.temp; msg.bigObj.newProp = 'Ukraine'; return {msg: msg};";
|
String function = "msg.passed = msg.passed * metadata.temp; msg.bigObj.newProp = 'Ukraine'; return {msg: msg};";
|
||||||
scriptEngine = new NashornJsEngine(function, "Transform");
|
scriptEngine = new JsScriptEngine(jsSandboxService, function, "Transform");
|
||||||
TbMsgMetaData metaData = new TbMsgMetaData();
|
TbMsgMetaData metaData = new TbMsgMetaData();
|
||||||
metaData.putValue("temp", "7");
|
metaData.putValue("temp", "7");
|
||||||
metaData.putValue("humidity", "99");
|
metaData.putValue("humidity", "99");
|
||||||
@ -83,7 +98,7 @@ public class NashornJsEngineTest {
|
|||||||
@Test
|
@Test
|
||||||
public void metadataAccessibleForFilter() throws ScriptException {
|
public void metadataAccessibleForFilter() throws ScriptException {
|
||||||
String function = "return metadata.humidity < 15;";
|
String function = "return metadata.humidity < 15;";
|
||||||
scriptEngine = new NashornJsEngine(function, "Filter");
|
scriptEngine = new JsScriptEngine(jsSandboxService, function, "Filter");
|
||||||
TbMsgMetaData metaData = new TbMsgMetaData();
|
TbMsgMetaData metaData = new TbMsgMetaData();
|
||||||
metaData.putValue("temp", "7");
|
metaData.putValue("temp", "7");
|
||||||
metaData.putValue("humidity", "99");
|
metaData.putValue("humidity", "99");
|
||||||
@ -96,7 +111,7 @@ public class NashornJsEngineTest {
|
|||||||
@Test
|
@Test
|
||||||
public void dataAccessibleForFilter() throws ScriptException {
|
public void dataAccessibleForFilter() throws ScriptException {
|
||||||
String function = "return msg.passed < 15 && msg.name === 'Vit' && metadata.temp == 7 && msg.bigObj.prop == 42;";
|
String function = "return msg.passed < 15 && msg.name === 'Vit' && metadata.temp == 7 && msg.bigObj.prop == 42;";
|
||||||
scriptEngine = new NashornJsEngine(function, "Filter");
|
scriptEngine = new JsScriptEngine(jsSandboxService, function, "Filter");
|
||||||
TbMsgMetaData metaData = new TbMsgMetaData();
|
TbMsgMetaData metaData = new TbMsgMetaData();
|
||||||
metaData.putValue("temp", "7");
|
metaData.putValue("temp", "7");
|
||||||
metaData.putValue("humidity", "99");
|
metaData.putValue("humidity", "99");
|
||||||
@ -116,7 +131,7 @@ public class NashornJsEngineTest {
|
|||||||
"};\n" +
|
"};\n" +
|
||||||
"\n" +
|
"\n" +
|
||||||
"return nextRelation(metadata, msg);";
|
"return nextRelation(metadata, msg);";
|
||||||
scriptEngine = new NashornJsEngine(jsCode, "Switch");
|
scriptEngine = new JsScriptEngine(jsSandboxService, jsCode, "Switch");
|
||||||
TbMsgMetaData metaData = new TbMsgMetaData();
|
TbMsgMetaData metaData = new TbMsgMetaData();
|
||||||
metaData.putValue("temp", "10");
|
metaData.putValue("temp", "10");
|
||||||
metaData.putValue("humidity", "99");
|
metaData.putValue("humidity", "99");
|
||||||
@ -137,7 +152,7 @@ public class NashornJsEngineTest {
|
|||||||
"};\n" +
|
"};\n" +
|
||||||
"\n" +
|
"\n" +
|
||||||
"return nextRelation(metadata, msg);";
|
"return nextRelation(metadata, msg);";
|
||||||
scriptEngine = new NashornJsEngine(jsCode, "Switch");
|
scriptEngine = new JsScriptEngine(jsSandboxService, jsCode, "Switch");
|
||||||
TbMsgMetaData metaData = new TbMsgMetaData();
|
TbMsgMetaData metaData = new TbMsgMetaData();
|
||||||
metaData.putValue("temp", "10");
|
metaData.putValue("temp", "10");
|
||||||
metaData.putValue("humidity", "99");
|
metaData.putValue("humidity", "99");
|
||||||
@ -0,0 +1,54 @@
|
|||||||
|
/**
|
||||||
|
* Copyright © 2016-2018 The Thingsboard Authors
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.thingsboard.server.service.script;
|
||||||
|
|
||||||
|
import delight.nashornsandbox.NashornSandbox;
|
||||||
|
import delight.nashornsandbox.NashornSandboxes;
|
||||||
|
|
||||||
|
import javax.script.ScriptException;
|
||||||
|
import java.util.concurrent.ExecutorService;
|
||||||
|
import java.util.concurrent.Executors;
|
||||||
|
|
||||||
|
public class TestNashornJsSandboxService implements JsSandboxService {
|
||||||
|
|
||||||
|
private NashornSandbox sandbox = NashornSandboxes.create();
|
||||||
|
private ExecutorService monitorExecutorService;
|
||||||
|
|
||||||
|
public TestNashornJsSandboxService(int monitorThreadPoolSize, long maxCpuTime) {
|
||||||
|
monitorExecutorService = Executors.newFixedThreadPool(monitorThreadPoolSize);
|
||||||
|
sandbox.setExecutor(monitorExecutorService);
|
||||||
|
sandbox.setMaxCPUTime(maxCpuTime);
|
||||||
|
sandbox.allowNoBraces(false);
|
||||||
|
sandbox.setMaxPreparedStatements(30);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Object eval(String js) throws ScriptException {
|
||||||
|
return sandbox.eval(js);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Object invokeFunction(String name, Object... args) throws ScriptException, NoSuchMethodException {
|
||||||
|
return sandbox.getSandboxedInvocable().invokeFunction(name, args);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void destroy() {
|
||||||
|
if (monitorExecutorService != null) {
|
||||||
|
monitorExecutorService.shutdownNow();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
6
pom.xml
6
pom.xml
@ -81,6 +81,7 @@
|
|||||||
org/thingsboard/server/extensions/core/plugin/telemetry/gen/**/*
|
org/thingsboard/server/extensions/core/plugin/telemetry/gen/**/*
|
||||||
</sonar.exclusions>
|
</sonar.exclusions>
|
||||||
<elasticsearch.version>5.0.2</elasticsearch.version>
|
<elasticsearch.version>5.0.2</elasticsearch.version>
|
||||||
|
<delight-nashorn-sandbox.version>0.1.14</delight-nashorn-sandbox.version>
|
||||||
</properties>
|
</properties>
|
||||||
|
|
||||||
<modules>
|
<modules>
|
||||||
@ -814,6 +815,11 @@
|
|||||||
<artifactId>rest</artifactId>
|
<artifactId>rest</artifactId>
|
||||||
<version>${elasticsearch.version}</version>
|
<version>${elasticsearch.version}</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.javadelight</groupId>
|
||||||
|
<artifactId>delight-nashorn-sandbox</artifactId>
|
||||||
|
<version>${delight-nashorn-sandbox.version}</version>
|
||||||
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
</dependencyManagement>
|
</dependencyManagement>
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user