组件脚本-添加脚本类型js,graaljs
parent
26f8570ea7
commit
b84d4789c8
|
@ -0,0 +1,20 @@
|
|||
package cc.iotkit.converter;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
public class DefaultScriptConvertFactory implements IScriptConvertFactory{
|
||||
|
||||
@Override
|
||||
public IConverter getCovert(String name) {
|
||||
if(StringUtils.isNotBlank(name)){
|
||||
if (name.endsWith("graaljs")){
|
||||
return new GraalJsScriptConverter();
|
||||
}
|
||||
}
|
||||
|
||||
// 默认是NashornScript js实现方式
|
||||
return new ScriptConverter();
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -1,16 +0,0 @@
|
|||
package cc.iotkit.converter;
|
||||
|
||||
public class ScriptConvertFactory implements IScriptConvertFactory{
|
||||
|
||||
@Override
|
||||
public IConverter getCovert(String name) {
|
||||
if (name.endsWith("graaljs")){
|
||||
return new GraalJsScriptConverter();
|
||||
}
|
||||
|
||||
// 默认是NashornScript js实现方式
|
||||
return new ScriptConverter();
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -25,6 +25,9 @@ import cc.iotkit.data.IDeviceInfoData;
|
|||
import cc.iotkit.data.IProductData;
|
||||
import cc.iotkit.data.IProtocolComponentData;
|
||||
import cc.iotkit.data.IProtocolConverterData;
|
||||
import cc.iotkit.engine.IScriptEngine;
|
||||
import cc.iotkit.engine.IScriptEngineFactory;
|
||||
import cc.iotkit.engine.JsNashornScriptEngine;
|
||||
import cc.iotkit.model.device.DeviceInfo;
|
||||
import cc.iotkit.model.device.message.ThingModelMessage;
|
||||
import cc.iotkit.model.product.Product;
|
||||
|
@ -75,8 +78,14 @@ public class DeviceComponentManager {
|
|||
|
||||
private final IScriptConvertFactory scriptConverterFactory;
|
||||
|
||||
public DeviceComponentManager(IScriptConvertFactory scriptConverterFactory) {
|
||||
private final IScriptEngineFactory scriptEngineFactory;
|
||||
|
||||
private IScriptEngine scriptEngine;
|
||||
|
||||
public DeviceComponentManager(IScriptConvertFactory scriptConverterFactory,
|
||||
IScriptEngineFactory scriptEngineFactory ) {
|
||||
this.scriptConverterFactory = scriptConverterFactory;
|
||||
this.scriptEngineFactory = scriptEngineFactory;
|
||||
}
|
||||
|
||||
@PostConstruct
|
||||
|
@ -112,10 +121,11 @@ public class DeviceComponentManager {
|
|||
try {
|
||||
setScriptConvert(component, componentInstance);
|
||||
|
||||
scriptEngine = scriptEngineFactory.getScriptEngine(component.getScriptTyp());
|
||||
|
||||
String componentScript = FileUtils.readFileToString(path.
|
||||
resolve(ProtocolComponent.SCRIPT_FILE_NAME).toFile(), "UTF-8");
|
||||
componentInstance.setScript(componentScript);
|
||||
|
||||
register(id, componentInstance);
|
||||
} catch (IOException e) {
|
||||
throw new BizException("get device component script error", e);
|
||||
|
@ -126,12 +136,12 @@ public class DeviceComponentManager {
|
|||
ProtocolConverter protocolConvert = protocolConverterData.findById(component.getConverter());
|
||||
|
||||
IConverter scriptConverter = scriptConverterFactory.getCovert(protocolConvert.getTyp());
|
||||
|
||||
// 从文件方式内容
|
||||
Path converterPath = componentConfig.getConverterFilePath(component.getConverter());
|
||||
String converterScript = FileUtils.readFileToString(converterPath.
|
||||
resolve(ProtocolConverter.SCRIPT_FILE_NAME).toFile(), "UTF-8");
|
||||
|
||||
// scriptConverter.setScript(protocolConvert.getScript());
|
||||
// scriptConverter.setScript(protocolConvert.getScript()); // 从数据库加载,以后可以加版本号
|
||||
scriptConverter.setScript(converterScript);
|
||||
scriptConverter.putScriptEnv("component", componentInstance);
|
||||
componentInstance.setConverter(scriptConverter);
|
||||
|
@ -157,8 +167,12 @@ public class DeviceComponentManager {
|
|||
if (component == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
|
||||
DeviceMessageHandler messageHandler = new DeviceMessageHandler(
|
||||
this, component,
|
||||
scriptEngine,
|
||||
component.getScript(), component.getConverter(),
|
||||
deviceBehaviourService, deviceRouter);
|
||||
messageHandler.putScriptEnv("apiTool", new ApiTool());
|
||||
|
|
|
@ -60,6 +60,7 @@ public class DeviceMessageHandler implements IMessageHandler {
|
|||
@SneakyThrows
|
||||
public DeviceMessageHandler(DeviceComponentManager deviceComponentManager,
|
||||
IDeviceComponent component,
|
||||
IScriptEngine scriptEngine,
|
||||
String script, IConverter converter,
|
||||
DeviceBehaviourService deviceBehaviourService,
|
||||
DeviceRouter deviceRouter
|
||||
|
@ -69,7 +70,7 @@ public class DeviceMessageHandler implements IMessageHandler {
|
|||
this.converter = converter;
|
||||
this.deviceBehaviourService = deviceBehaviourService;
|
||||
this.deviceRouter = deviceRouter;
|
||||
this.scriptEngine = new JsNashornScriptEngine();
|
||||
this.scriptEngine = scriptEngine;
|
||||
scriptEngine.putScriptEnv("component", component);
|
||||
scriptEngine.setScript(script);
|
||||
}
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
package cc.iotkit.comps.config;
|
||||
|
||||
import cc.iotkit.converter.GraalJsScriptConverter;
|
||||
import cc.iotkit.converter.IConverter;
|
||||
import cc.iotkit.converter.IScriptConvertFactory;
|
||||
import cc.iotkit.converter.ScriptConvertFactory;
|
||||
import cc.iotkit.converter.DefaultScriptConvertFactory;
|
||||
import cc.iotkit.engine.DefaultScriptEngineFactory;
|
||||
import cc.iotkit.engine.IScriptEngineFactory;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.fasterxml.jackson.databind.SerializationFeature;
|
||||
import lombok.Data;
|
||||
|
@ -42,7 +42,11 @@ public class ComponentConfig {
|
|||
|
||||
@Bean
|
||||
public IScriptConvertFactory scriptConverterFactory(){
|
||||
return new ScriptConvertFactory();
|
||||
return new DefaultScriptConvertFactory();
|
||||
}
|
||||
|
||||
@Bean
|
||||
public IScriptEngineFactory scriptEngineFactory(){
|
||||
return new DefaultScriptEngineFactory();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -33,6 +33,10 @@
|
|||
<artifactId>js-scriptengine</artifactId>
|
||||
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.commons</groupId>
|
||||
<artifactId>commons-lang3</artifactId>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
</project>
|
|
@ -0,0 +1,17 @@
|
|||
package cc.iotkit.engine;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
public class DefaultScriptEngineFactory implements IScriptEngineFactory{
|
||||
@Override
|
||||
public IScriptEngine getScriptEngine(String name) {
|
||||
if(StringUtils.isNotBlank(name)){
|
||||
if (name.endsWith("graaljs")){
|
||||
return new JsGraalJsScriptEngine();
|
||||
}
|
||||
}
|
||||
|
||||
// 默认是NashornScript js实现方式
|
||||
return new JsNashornScriptEngine();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,6 @@
|
|||
package cc.iotkit.engine;
|
||||
|
||||
public interface IScriptEngineFactory {
|
||||
|
||||
IScriptEngine getScriptEngine(String name);
|
||||
}
|
|
@ -0,0 +1,178 @@
|
|||
|
||||
var mid=1;
|
||||
|
||||
function getMid(){
|
||||
mid++;
|
||||
if(mid>10000){
|
||||
mid=1;
|
||||
}
|
||||
return mid+"";
|
||||
}
|
||||
|
||||
this.decode = function (msg) {
|
||||
|
||||
//对msg进行解析,并返回物模型数据
|
||||
console.log("msg", msg);
|
||||
var content= msg.getContent();
|
||||
console.log("content",content);
|
||||
var topic = content.topic;
|
||||
console.log("topic",topic);
|
||||
var payload = content.get("payload");
|
||||
console.log("payload",payload);
|
||||
var identifier = topic.substring(topic.lastIndexOf("/") + 1);
|
||||
|
||||
//透传上报
|
||||
if(topic.endsWith("/event/rawReport")){
|
||||
var rst= component.transparentDecode(payload.params);
|
||||
if(!rst){
|
||||
return null;
|
||||
}
|
||||
rst.occured=new Date().getTime();
|
||||
rst.time=new Date().getTime();
|
||||
return rst;
|
||||
}
|
||||
|
||||
if (topic.endsWith("/property/post")) {
|
||||
//属性上报
|
||||
return {
|
||||
"mid": msg.getMid(),
|
||||
"productKey": msg.getProductKey(),
|
||||
"deviceName": msg.getDeviceName(),
|
||||
"type":"property",
|
||||
"identifier": "report", //属性上报
|
||||
"occured": new Date().getTime(), //时间戳,设备上的事件或数据产生的本地时间
|
||||
"time": new Date().getTime(), //时间戳,消息上报时间
|
||||
data: payload,
|
||||
};
|
||||
} else if (topic.indexOf("/event/") > 0) {
|
||||
//事件上报
|
||||
return {
|
||||
mid: msg.getMid(),
|
||||
productKey: msg.getProductKey(),
|
||||
deviceName: msg.getDeviceName(),
|
||||
type:"event",
|
||||
identifier: identifier,
|
||||
occured: new Date().getTime(),
|
||||
time: new Date().getTime(),
|
||||
data: payload.params,
|
||||
};
|
||||
}else if(topic.endsWith("/service/property/set_reply")){
|
||||
//属性设置回复
|
||||
return {
|
||||
mid: msg.getMid(),
|
||||
productKey: msg.getProductKey(),
|
||||
deviceName: msg.getDeviceName(),
|
||||
type:"property",
|
||||
identifier: identifier,
|
||||
occured: new Date().getTime(),
|
||||
time: new Date().getTime(),
|
||||
code: payload.code
|
||||
};
|
||||
}else if(topic.endsWith("/config/set_reply")){
|
||||
//设备配置设置回复
|
||||
return {
|
||||
mid: msg.getMid(),
|
||||
productKey: msg.getProductKey(),
|
||||
deviceName: msg.getDeviceName(),
|
||||
type:"config",
|
||||
identifier: "set_reply",
|
||||
occured: new Date().getTime(),
|
||||
time: new Date().getTime(),
|
||||
code: payload.code
|
||||
};
|
||||
}else if(topic.endsWith("/config/get")){
|
||||
//设备配置获取
|
||||
return {
|
||||
mid: msg.getMid(),
|
||||
productKey: msg.getProductKey(),
|
||||
deviceName: msg.getDeviceName(),
|
||||
type:"config",
|
||||
identifier: "get",
|
||||
occured: new Date().getTime(),
|
||||
time: new Date().getTime(),
|
||||
data: {},
|
||||
};
|
||||
} else if (topic.endsWith("_reply")) {
|
||||
//服务回复
|
||||
return {
|
||||
mid: msg.getMid(),
|
||||
productKey: msg.getProductKey(),
|
||||
deviceName: msg.getDeviceName(),
|
||||
type:"service",
|
||||
identifier: identifier,
|
||||
occured: new Date().getTime(),
|
||||
time: new Date().getTime(),
|
||||
code: payload.code,
|
||||
data: payload.data,
|
||||
};
|
||||
}
|
||||
return null;
|
||||
};
|
||||
|
||||
this.encode = function (service,device) {
|
||||
var deviceMid=getMid();
|
||||
var method="thing.service.";
|
||||
var topic="/sys/"+service.getProductKey()+"/"+service.getDeviceName()+"/c/service/";
|
||||
var params={};
|
||||
|
||||
//透传下发
|
||||
if(device.isTransparent()){
|
||||
var rst=component.transparentEncode(service,device);
|
||||
topic="/sys/"+rst.productKey+"/"+rst.deviceName+"/c/service/rawSend";
|
||||
params.model=rst.content.model;
|
||||
params.deviceName=rst.content.deviceName;
|
||||
params.data=rst.content.data;
|
||||
|
||||
return {
|
||||
productKey:rst.productKey,
|
||||
deviceName:rst.deviceName,
|
||||
mid:rst.mid,
|
||||
content:{
|
||||
topic:topic,
|
||||
payload:JSON.stringify({
|
||||
id:rst.mid,
|
||||
method:method+"rawSend",
|
||||
params:params
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
var type=service.getType();
|
||||
var identifier=service.getIdentifier();
|
||||
|
||||
if(type=="property"){
|
||||
method+="property."+identifier;
|
||||
topic+="property/"+identifier;
|
||||
}else if(type=="service"){
|
||||
method+=identifier;
|
||||
topic+=identifier;
|
||||
}else if(type=="config"){
|
||||
//设备配置下发
|
||||
method+=identifier;
|
||||
topic="/sys/"+service.getProductKey()+"/"+service.getDeviceName()+"/c/config/"+identifier;
|
||||
}else if(type="lifetime"){
|
||||
//子设备注销下发
|
||||
method+=identifier;
|
||||
topic="/sys/"+service.getProductKey()+"/"+service.getDeviceName()+"/c/deregister";
|
||||
}
|
||||
|
||||
for(var p in service.getParams()){
|
||||
params[p]=service.getParams()[p];
|
||||
}
|
||||
|
||||
return {
|
||||
productKey:service.getProductKey(),
|
||||
deviceName:service.getDeviceName(),
|
||||
mid:deviceMid,
|
||||
content:{
|
||||
topic:topic,
|
||||
payload:JSON.stringify({
|
||||
id:deviceMid,
|
||||
method:method,
|
||||
params:params
|
||||
})
|
||||
}
|
||||
}
|
||||
};
|
|
@ -45,4 +45,8 @@ public class ProtocolComponent implements Owned<String> {
|
|||
|
||||
private Long createAt;
|
||||
|
||||
private String scriptTyp;
|
||||
|
||||
private String script;
|
||||
|
||||
}
|
||||
|
|
|
@ -36,4 +36,10 @@ public class TbProtocolComponent {
|
|||
private String state;
|
||||
|
||||
private Long createAt;
|
||||
|
||||
private String scriptTyp;
|
||||
|
||||
@Column(columnDefinition = "text")//设置映射为text类型
|
||||
private String script;
|
||||
|
||||
}
|
||||
|
|
|
@ -40,6 +40,7 @@ public class TbProtocolConverter {
|
|||
private String typ;
|
||||
|
||||
// 脚本内容
|
||||
@Column(columnDefinition = "text")//设置映射为text类型
|
||||
private String script;
|
||||
|
||||
}
|
||||
|
|
|
@ -131,26 +131,41 @@ public class ProtocolController {
|
|||
}
|
||||
|
||||
@GetMapping("/getComponentScript/{id}")
|
||||
public String getComponentScript(@PathVariable("id") String id) {
|
||||
getAndCheckComponent(id);
|
||||
try {
|
||||
File file = getComponentScriptFile(id);
|
||||
return FileUtils.readFileToString(file, "UTF-8");
|
||||
} catch (Throwable e) {
|
||||
log.error("read component script file error", e);
|
||||
return "";
|
||||
public ProtocolComponent getComponentScript(@PathVariable("id") String id) {
|
||||
ProtocolComponent component = getAndCheckComponent(id);
|
||||
|
||||
String script = component.getScript();
|
||||
// 如果数据库里不存在,则从文件中读取脚本
|
||||
if(!StringUtils.hasText(script)){
|
||||
try {
|
||||
File file = getComponentScriptFile(id);
|
||||
script = FileUtils.readFileToString(file, "UTF-8");
|
||||
} catch (Throwable e) {
|
||||
log.error("read converter script file error", e);
|
||||
script = "";
|
||||
}
|
||||
component.setScript(script);
|
||||
}
|
||||
return component;
|
||||
|
||||
}
|
||||
|
||||
@PostMapping("/saveComponentScript/{id}")
|
||||
public void saveComponentScript(
|
||||
@PathVariable("id") String id,
|
||||
@RequestBody String script) {
|
||||
getAndCheckComponent(id);
|
||||
@RequestBody ProtocolComponent upReq) {
|
||||
ProtocolComponent old = getAndCheckComponent(id);
|
||||
try {
|
||||
// 保存到文件
|
||||
File file = getComponentScriptFile(id);
|
||||
script = JsonUtil.parse(script, String.class);
|
||||
String script = upReq.getScript();
|
||||
FileUtils.writeStringToFile(file, script, "UTF-8", false);
|
||||
|
||||
// 保存到数据库,后续加版本号
|
||||
old.setScript(upReq.getScript());
|
||||
old.setScriptTyp(upReq.getScriptTyp());
|
||||
protocolComponentData.save(old);
|
||||
|
||||
componentManager.deRegister(id);
|
||||
} catch (Throwable e) {
|
||||
throw new BizException("save protocol component script error", e);
|
||||
|
@ -252,7 +267,7 @@ public class ProtocolController {
|
|||
ProtocolConverter converter = getAndCheckConverter(id);
|
||||
String script = converter.getScript();
|
||||
// 如果数据库里不存在,则从文件中读取脚本
|
||||
if(StringUtils.hasText(script)){
|
||||
if(!StringUtils.hasText(script)){
|
||||
try {
|
||||
Path path = componentConfig.getConverterFilePath(id);
|
||||
File file = path.resolve(ProtocolConverter.SCRIPT_FILE_NAME).toFile();
|
||||
|
|
Loading…
Reference in New Issue