Commit 0ae893272bf64f187fe8f9fb33205decfe27aafa

Authored by 安浩浩
1 parent a9dc654b

【功能优化】IoT: 重构脚本服务实现,启用脚本执行和测试逻辑,更新日志记录方式

yudao-module-iot/yudao-module-iot-biz/pom.xml
@@ -70,11 +70,11 @@ @@ -70,11 +70,11 @@
70 </dependency> 70 </dependency>
71 71
72 <!-- 脚本插件相关 --> 72 <!-- 脚本插件相关 -->
73 - <!--<dependency> 73 + <dependency>
74 <groupId>cn.iocoder.boot</groupId> 74 <groupId>cn.iocoder.boot</groupId>
75 <artifactId>yudao-module-iot-plugin-script</artifactId> 75 <artifactId>yudao-module-iot-plugin-script</artifactId>
76 <version>${revision}</version> 76 <version>${revision}</version>
77 - </dependency>--> 77 + </dependency>
78 78
79 <!-- 消息队列相关 --> 79 <!-- 消息队列相关 -->
80 <dependency> 80 <dependency>
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/product/IotProductScriptServiceImpl.java
@@ -9,6 +9,8 @@ import cn.iocoder.yudao.module.iot.controller.admin.product.vo.script.IotProduct @@ -9,6 +9,8 @@ import cn.iocoder.yudao.module.iot.controller.admin.product.vo.script.IotProduct
9 import cn.iocoder.yudao.module.iot.dal.dataobject.product.IotProductDO; 9 import cn.iocoder.yudao.module.iot.dal.dataobject.product.IotProductDO;
10 import cn.iocoder.yudao.module.iot.dal.dataobject.product.IotProductScriptDO; 10 import cn.iocoder.yudao.module.iot.dal.dataobject.product.IotProductScriptDO;
11 import cn.iocoder.yudao.module.iot.dal.mysql.product.IotProductScriptMapper; 11 import cn.iocoder.yudao.module.iot.dal.mysql.product.IotProductScriptMapper;
  12 +import cn.iocoder.yudao.module.iot.plugin.script.context.PluginScriptContext;
  13 +import cn.iocoder.yudao.module.iot.plugin.script.service.ScriptService;
12 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; 14 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
13 import jakarta.annotation.Resource; 15 import jakarta.annotation.Resource;
14 import lombok.extern.slf4j.Slf4j; 16 import lombok.extern.slf4j.Slf4j;
@@ -40,8 +42,8 @@ public class IotProductScriptServiceImpl implements IotProductScriptService { @@ -40,8 +42,8 @@ public class IotProductScriptServiceImpl implements IotProductScriptService {
40 @Resource 42 @Resource
41 private IotProductService productService; 43 private IotProductService productService;
42 44
43 -// @Resource  
44 -// private ScriptService scriptService; 45 + @Resource
  46 + private ScriptService scriptService;
45 47
46 @Override 48 @Override
47 public Long createProductScript(IotProductScriptSaveReqVO createReqVO) { 49 public Long createProductScript(IotProductScriptSaveReqVO createReqVO) {
@@ -118,90 +120,89 @@ public class IotProductScriptServiceImpl implements IotProductScriptService { @@ -118,90 +120,89 @@ public class IotProductScriptServiceImpl implements IotProductScriptService {
118 120
119 @Override 121 @Override
120 public IotProductScriptTestRespVO testProductScript(IotProductScriptTestReqVO testReqVO) { 122 public IotProductScriptTestRespVO testProductScript(IotProductScriptTestReqVO testReqVO) {
121 -// long startTime = System.currentTimeMillis();  
122 -//  
123 -// try {  
124 -// // 验证产品是否存在  
125 -// validateProductExists(testReqVO.getProductId());  
126 -//  
127 -// // 根据ID获取已保存的脚本(如果有)  
128 -// IotProductScriptDO existingScript = null;  
129 -// if (testReqVO.getId() != null) {  
130 -// existingScript = getProductScript(testReqVO.getId());  
131 -// }  
132 -//  
133 -// // 创建测试上下文  
134 -// PluginScriptContext context = new PluginScriptContext();  
135 -// IotProductDO product = productService.getProduct(testReqVO.getProductId());  
136 -//  
137 -// // 设置设备上下文(使用产品信息,没有具体设备)  
138 -// context.withDeviceContext(product.getProductKey(), null);  
139 -//  
140 -// // 设置输入参数  
141 -// Map<String, Object> params = new HashMap<>();  
142 -// params.put("input", testReqVO.getTestInput());  
143 -// params.put("productKey", product.getProductKey());  
144 -// params.put("scriptType", testReqVO.getScriptType());  
145 -//  
146 -// // 根据脚本类型设置特定参数  
147 -// switch (testReqVO.getScriptType()) {  
148 -// case 1: // PROPERTY_PARSER  
149 -// params.put("method", "property");  
150 -// break;  
151 -// case 2: // EVENT_PARSER  
152 -// params.put("method", "event");  
153 -// params.put("identifier", "default");  
154 -// break;  
155 -// case 3: // COMMAND_ENCODER  
156 -// params.put("method", "command");  
157 -// break;  
158 -// default:  
159 -// // 默认不添加额外参数  
160 -// }  
161 -//  
162 -// // 添加所有参数到上下文  
163 -// for (Map.Entry<String, Object> entry : params.entrySet()) {  
164 -// context.setParameter(entry.getKey(), entry.getValue());  
165 -// }  
166 -//  
167 -// // 执行脚本  
168 -// Object result = scriptService.executeScript(  
169 -// testReqVO.getScriptLanguage(),  
170 -// testReqVO.getScriptContent(),  
171 -// context);  
172 -//  
173 -// // 更新测试结果(如果是已保存的脚本)  
174 -// if (existingScript != null) {  
175 -// IotProductScriptDO updateObj = new IotProductScriptDO();  
176 -// updateObj.setId(existingScript.getId());  
177 -// updateObj.setLastTestTime(LocalDateTime.now());  
178 -// updateObj.setLastTestResult(1); // 1表示成功  
179 -// productScriptMapper.updateById(updateObj);  
180 -// }  
181 -//  
182 -// long executionTime = System.currentTimeMillis() - startTime;  
183 -// return IotProductScriptTestRespVO.success(result, executionTime);  
184 -//  
185 -// } catch (Exception e) {  
186 -// log.error("[testProductScript][测试脚本异常]", e);  
187 -//  
188 -// // 如果是已保存的脚本,更新测试失败状态  
189 -// if (testReqVO.getId() != null) {  
190 -// try {  
191 -// IotProductScriptDO updateObj = new IotProductScriptDO();  
192 -// updateObj.setId(testReqVO.getId());  
193 -// updateObj.setLastTestTime(LocalDateTime.now());  
194 -// updateObj.setLastTestResult(0); // 0表示失败  
195 -// productScriptMapper.updateById(updateObj);  
196 -// } catch (Exception ex) {  
197 -// log.error("[testProductScript][更新脚本测试结果异常]", ex);  
198 -// }  
199 -// }  
200 -//  
201 -// long executionTime = System.currentTimeMillis() - startTime;  
202 -// return IotProductScriptTestRespVO.error(e.getMessage(), executionTime);  
203 -// }  
204 - return null; 123 + long startTime = System.currentTimeMillis();
  124 +
  125 + try {
  126 + // 验证产品是否存在
  127 + validateProductExists(testReqVO.getProductId());
  128 +
  129 + // 根据ID获取已保存的脚本(如果有)
  130 + IotProductScriptDO existingScript = null;
  131 + if (testReqVO.getId() != null) {
  132 + existingScript = getProductScript(testReqVO.getId());
  133 + }
  134 +
  135 + // 创建测试上下文
  136 + PluginScriptContext context = new PluginScriptContext();
  137 + IotProductDO product = productService.getProduct(testReqVO.getProductId());
  138 +
  139 + // 设置设备上下文(使用产品信息,没有具体设备)
  140 + context.withDeviceContext(product.getProductKey(), null);
  141 +
  142 + // 设置输入参数
  143 + Map<String, Object> params = new HashMap<>();
  144 + params.put("input", testReqVO.getTestInput());
  145 + params.put("productKey", product.getProductKey());
  146 + params.put("scriptType", testReqVO.getScriptType());
  147 +
  148 + // 根据脚本类型设置特定参数
  149 + switch (testReqVO.getScriptType()) {
  150 + case 1: // PROPERTY_PARSER
  151 + params.put("method", "property");
  152 + break;
  153 + case 2: // EVENT_PARSER
  154 + params.put("method", "event");
  155 + params.put("identifier", "default");
  156 + break;
  157 + case 3: // COMMAND_ENCODER
  158 + params.put("method", "command");
  159 + break;
  160 + default:
  161 + // 默认不添加额外参数
  162 + }
  163 +
  164 + // 添加所有参数到上下文
  165 + for (Map.Entry<String, Object> entry : params.entrySet()) {
  166 + context.setParameter(entry.getKey(), entry.getValue());
  167 + }
  168 +
  169 + // 执行脚本
  170 + Object result = scriptService.executeScript(
  171 + testReqVO.getScriptLanguage(),
  172 + testReqVO.getScriptContent(),
  173 + context);
  174 +
  175 + // 更新测试结果(如果是已保存的脚本)
  176 + if (existingScript != null) {
  177 + IotProductScriptDO updateObj = new IotProductScriptDO();
  178 + updateObj.setId(existingScript.getId());
  179 + updateObj.setLastTestTime(LocalDateTime.now());
  180 + updateObj.setLastTestResult(1); // 1表示成功
  181 + productScriptMapper.updateById(updateObj);
  182 + }
  183 +
  184 + long executionTime = System.currentTimeMillis() - startTime;
  185 + return IotProductScriptTestRespVO.success(result, executionTime);
  186 +
  187 + } catch (Exception e) {
  188 + log.error("[testProductScript][测试脚本异常]", e);
  189 +
  190 + // 如果是已保存的脚本,更新测试失败状态
  191 + if (testReqVO.getId() != null) {
  192 + try {
  193 + IotProductScriptDO updateObj = new IotProductScriptDO();
  194 + updateObj.setId(testReqVO.getId());
  195 + updateObj.setLastTestTime(LocalDateTime.now());
  196 + updateObj.setLastTestResult(0); // 0表示失败
  197 + productScriptMapper.updateById(updateObj);
  198 + } catch (Exception ex) {
  199 + log.error("[testProductScript][更新脚本测试结果异常]", ex);
  200 + }
  201 + }
  202 +
  203 + long executionTime = System.currentTimeMillis() - startTime;
  204 + return IotProductScriptTestRespVO.error(e.getMessage(), executionTime);
  205 + }
205 } 206 }
206 207
207 @Override 208 @Override
yudao-module-iot/yudao-module-iot-plugins/yudao-module-iot-plugin-script/pom.xml
@@ -19,7 +19,7 @@ @@ -19,7 +19,7 @@
19 <!-- 引入公共模块 --> 19 <!-- 引入公共模块 -->
20 <dependency> 20 <dependency>
21 <groupId>cn.iocoder.boot</groupId> 21 <groupId>cn.iocoder.boot</groupId>
22 - <artifactId>yudao-module-iot-plugin-common</artifactId> 22 + <artifactId>yudao-module-iot-api</artifactId>
23 <version>${revision}</version> 23 <version>${revision}</version>
24 </dependency> 24 </dependency>
25 25
yudao-module-iot/yudao-module-iot-plugins/yudao-module-iot-plugin-script/src/main/java/cn/iocoder/yudao/module/iot/plugin/script/ScriptExample.java
@@ -2,8 +2,7 @@ package cn.iocoder.yudao.module.iot.plugin.script; @@ -2,8 +2,7 @@ package cn.iocoder.yudao.module.iot.plugin.script;
2 2
3 import cn.iocoder.yudao.module.iot.plugin.script.context.PluginScriptContext; 3 import cn.iocoder.yudao.module.iot.plugin.script.context.PluginScriptContext;
4 import cn.iocoder.yudao.module.iot.plugin.script.service.ScriptService; 4 import cn.iocoder.yudao.module.iot.plugin.script.service.ScriptService;
5 -import org.slf4j.Logger;  
6 -import org.slf4j.LoggerFactory; 5 +import lombok.extern.slf4j.Slf4j;
7 import org.springframework.beans.factory.annotation.Autowired; 6 import org.springframework.beans.factory.annotation.Autowired;
8 import org.springframework.stereotype.Component; 7 import org.springframework.stereotype.Component;
9 8
@@ -14,8 +13,8 @@ import java.util.Map; @@ -14,8 +13,8 @@ import java.util.Map;
14 * 脚本使用示例类 13 * 脚本使用示例类
15 */ 14 */
16 @Component 15 @Component
  16 +@Slf4j
17 public class ScriptExample { 17 public class ScriptExample {
18 - private static final Logger logger = LoggerFactory.getLogger(ScriptExample.class);  
19 18
20 @Autowired 19 @Autowired
21 private ScriptService scriptService; 20 private ScriptService scriptService;
@@ -31,7 +30,7 @@ public class ScriptExample { @@ -31,7 +30,7 @@ public class ScriptExample {
31 params.put("b", 20); 30 params.put("b", 20);
32 31
33 Object result = scriptService.executeJavaScript(script, params); 32 Object result = scriptService.executeJavaScript(script, params);
34 - logger.info("脚本执行结果: {}", result); 33 + log.info("脚本执行结果: {}", result);
35 } 34 }
36 35
37 /** 36 /**
@@ -73,17 +72,17 @@ public class ScriptExample { @@ -73,17 +72,17 @@ public class ScriptExample {
73 Object result = scriptService.executeJavaScript(script, context); 72 Object result = scriptService.executeJavaScript(script, context);
74 if (result != null) { 73 if (result != null) {
75 // 处理结果 74 // 处理结果
76 - logger.info("设备数据处理结果: {}", result); 75 + log.info("设备数据处理结果: {}", result);
77 76
78 // 安全地将结果转换为Map 77 // 安全地将结果转换为Map
79 if (result instanceof Map) { 78 if (result instanceof Map) {
80 return (Map<String, Object>) result; 79 return (Map<String, Object>) result;
81 } else { 80 } else {
82 - logger.warn("脚本返回结果类型不是Map: {}", result.getClass().getName()); 81 + log.warn("脚本返回结果类型不是Map: {}", result.getClass().getName());
83 } 82 }
84 } 83 }
85 } catch (Exception e) { 84 } catch (Exception e) {
86 - logger.error("处理设备数据失败: {}", e.getMessage()); 85 + log.error("处理设备数据失败: {}", e.getMessage());
87 } 86 }
88 87
89 return new HashMap<>(); 88 return new HashMap<>();
@@ -121,10 +120,10 @@ public class ScriptExample { @@ -121,10 +120,10 @@ public class ScriptExample {
121 if (result instanceof String) { 120 if (result instanceof String) {
122 return (String) result; 121 return (String) result;
123 } else if (result != null) { 122 } else if (result != null) {
124 - logger.warn("脚本返回结果类型不是String: {}", result.getClass().getName()); 123 + log.warn("脚本返回结果类型不是String: {}", result.getClass().getName());
125 } 124 }
126 } catch (Exception e) { 125 } catch (Exception e) {
127 - logger.error("生成设备命令失败: {}", e.getMessage()); 126 + log.error("生成设备命令失败: {}", e.getMessage());
128 } 127 }
129 128
130 return null; 129 return null;
yudao-module-iot/yudao-module-iot-plugins/yudao-module-iot-plugin-script/src/main/java/cn/iocoder/yudao/module/iot/plugin/script/engine/JsScriptEngine.java
@@ -4,8 +4,7 @@ import cn.hutool.core.map.MapUtil; @@ -4,8 +4,7 @@ import cn.hutool.core.map.MapUtil;
4 import cn.iocoder.yudao.module.iot.plugin.script.context.ScriptContext; 4 import cn.iocoder.yudao.module.iot.plugin.script.context.ScriptContext;
5 import cn.iocoder.yudao.module.iot.plugin.script.sandbox.JsSandbox; 5 import cn.iocoder.yudao.module.iot.plugin.script.sandbox.JsSandbox;
6 import cn.iocoder.yudao.module.iot.plugin.script.util.ScriptUtils; 6 import cn.iocoder.yudao.module.iot.plugin.script.util.ScriptUtils;
7 -import org.slf4j.Logger;  
8 -import org.slf4j.LoggerFactory; 7 +import lombok.extern.slf4j.Slf4j;
9 8
10 import javax.script.*; 9 import javax.script.*;
11 import java.util.Map; 10 import java.util.Map;
@@ -16,8 +15,8 @@ import java.util.concurrent.ConcurrentHashMap; @@ -16,8 +15,8 @@ import java.util.concurrent.ConcurrentHashMap;
16 * JavaScript脚本引擎实现 15 * JavaScript脚本引擎实现
17 * 使用JSR-223 Nashorn脚本引擎 16 * 使用JSR-223 Nashorn脚本引擎
18 */ 17 */
  18 +@Slf4j
19 public class JsScriptEngine extends AbstractScriptEngine { 19 public class JsScriptEngine extends AbstractScriptEngine {
20 - private static final Logger logger = LoggerFactory.getLogger(JsScriptEngine.class);  
21 20
22 /** 21 /**
23 * 默认脚本执行超时时间(毫秒) 22 * 默认脚本执行超时时间(毫秒)
@@ -46,7 +45,7 @@ public class JsScriptEngine extends AbstractScriptEngine { @@ -46,7 +45,7 @@ public class JsScriptEngine extends AbstractScriptEngine {
46 45
47 @Override 46 @Override
48 public void init() { 47 public void init() {
49 - logger.info("初始化JavaScript脚本引擎"); 48 + log.info("初始化JavaScript脚本引擎");
50 49
51 // 创建脚本引擎管理器 50 // 创建脚本引擎管理器
52 engineManager = new ScriptEngineManager(); 51 engineManager = new ScriptEngineManager();
@@ -54,7 +53,7 @@ public class JsScriptEngine extends AbstractScriptEngine { @@ -54,7 +53,7 @@ public class JsScriptEngine extends AbstractScriptEngine {
54 // 获取JavaScript引擎 53 // 获取JavaScript引擎
55 engine = engineManager.getEngineByName(JS_ENGINE_NAME); 54 engine = engineManager.getEngineByName(JS_ENGINE_NAME);
56 if (engine == null) { 55 if (engine == null) {
57 - logger.error("无法创建JavaScript引擎,尝试使用JavaScript名称获取"); 56 + log.error("无法创建JavaScript引擎,尝试使用JavaScript名称获取");
58 engine = engineManager.getEngineByName("JavaScript"); 57 engine = engineManager.getEngineByName("JavaScript");
59 } 58 }
60 59
@@ -62,7 +61,7 @@ public class JsScriptEngine extends AbstractScriptEngine { @@ -62,7 +61,7 @@ public class JsScriptEngine extends AbstractScriptEngine {
62 throw new IllegalStateException("无法创建JavaScript引擎,请检查环境配置"); 61 throw new IllegalStateException("无法创建JavaScript引擎,请检查环境配置");
63 } 62 }
64 63
65 - logger.info("成功创建JavaScript引擎: {}", engine.getClass().getName()); 64 + log.info("成功创建JavaScript引擎: {}", engine.getClass().getName());
66 65
67 // 默认使用JS沙箱 66 // 默认使用JS沙箱
68 if (sandbox == null) { 67 if (sandbox == null) {
@@ -100,7 +99,7 @@ public class JsScriptEngine extends AbstractScriptEngine { @@ -100,7 +99,7 @@ public class JsScriptEngine extends AbstractScriptEngine {
100 // 执行脚本 99 // 执行脚本
101 return engine.eval(script, bindings); 100 return engine.eval(script, bindings);
102 } catch (ScriptException e) { 101 } catch (ScriptException e) {
103 - logger.error("执行JavaScript脚本异常: {}", e.getMessage()); 102 + log.error("执行JavaScript脚本异常: {}", e.getMessage());
104 throw new RuntimeException("脚本执行异常: " + e.getMessage(), e); 103 throw new RuntimeException("脚本执行异常: " + e.getMessage(), e);
105 } 104 }
106 }; 105 };
@@ -109,7 +108,7 @@ public class JsScriptEngine extends AbstractScriptEngine { @@ -109,7 +108,7 @@ public class JsScriptEngine extends AbstractScriptEngine {
109 // 使用超时执行器执行脚本 108 // 使用超时执行器执行脚本
110 return ScriptUtils.executeWithTimeout(task, DEFAULT_TIMEOUT_MS); 109 return ScriptUtils.executeWithTimeout(task, DEFAULT_TIMEOUT_MS);
111 } catch (Exception e) { 110 } catch (Exception e) {
112 - logger.error("执行JavaScript脚本错误: {}", e.getMessage()); 111 + log.error("执行JavaScript脚本错误: {}", e.getMessage());
113 throw new RuntimeException("脚本执行失败: " + e.getMessage(), e); 112 throw new RuntimeException("脚本执行失败: " + e.getMessage(), e);
114 } 113 }
115 } 114 }
@@ -137,7 +136,7 @@ public class JsScriptEngine extends AbstractScriptEngine { @@ -137,7 +136,7 @@ public class JsScriptEngine extends AbstractScriptEngine {
137 // 执行脚本 136 // 执行脚本
138 return engine.eval(script, bindings); 137 return engine.eval(script, bindings);
139 } catch (ScriptException e) { 138 } catch (ScriptException e) {
140 - logger.error("执行JavaScript脚本异常: {}", e.getMessage()); 139 + log.error("执行JavaScript脚本异常: {}", e.getMessage());
141 throw new RuntimeException("脚本执行异常: " + e.getMessage(), e); 140 throw new RuntimeException("脚本执行异常: " + e.getMessage(), e);
142 } 141 }
143 }; 142 };
@@ -146,14 +145,14 @@ public class JsScriptEngine extends AbstractScriptEngine { @@ -146,14 +145,14 @@ public class JsScriptEngine extends AbstractScriptEngine {
146 // 使用超时执行器执行脚本 145 // 使用超时执行器执行脚本
147 return ScriptUtils.executeWithTimeout(task, DEFAULT_TIMEOUT_MS); 146 return ScriptUtils.executeWithTimeout(task, DEFAULT_TIMEOUT_MS);
148 } catch (Exception e) { 147 } catch (Exception e) {
149 - logger.error("执行JavaScript脚本错误: {}", e.getMessage()); 148 + log.error("执行JavaScript脚本错误: {}", e.getMessage());
150 throw new RuntimeException("脚本执行失败: " + e.getMessage(), e); 149 throw new RuntimeException("脚本执行失败: " + e.getMessage(), e);
151 } 150 }
152 } 151 }
153 152
154 @Override 153 @Override
155 public void destroy() { 154 public void destroy() {
156 - logger.info("销毁JavaScript脚本引擎"); 155 + log.info("销毁JavaScript脚本引擎");
157 cachedScripts.clear(); 156 cachedScripts.clear();
158 engine = null; 157 engine = null;
159 engineManager = null; 158 engineManager = null;
yudao-module-iot/yudao-module-iot-plugins/yudao-module-iot-plugin-script/src/main/java/cn/iocoder/yudao/module/iot/plugin/script/engine/ScriptEngineFactory.java
1 package cn.iocoder.yudao.module.iot.plugin.script.engine; 1 package cn.iocoder.yudao.module.iot.plugin.script.engine;
2 2
3 -import org.slf4j.Logger;  
4 -import org.slf4j.LoggerFactory; 3 +import lombok.extern.slf4j.Slf4j;
5 import org.springframework.stereotype.Component; 4 import org.springframework.stereotype.Component;
6 5
7 /** 6 /**
8 * 脚本引擎工厂,用于创建不同类型的脚本引擎 7 * 脚本引擎工厂,用于创建不同类型的脚本引擎
9 */ 8 */
10 @Component 9 @Component
  10 +@Slf4j
11 public class ScriptEngineFactory { 11 public class ScriptEngineFactory {
12 - private static final Logger logger = LoggerFactory.getLogger(ScriptEngineFactory.class);  
13 12
14 /** 13 /**
15 * 创建JavaScript脚本引擎 14 * 创建JavaScript脚本引擎
@@ -17,7 +16,7 @@ public class ScriptEngineFactory { @@ -17,7 +16,7 @@ public class ScriptEngineFactory {
17 * @return JavaScript脚本引擎 16 * @return JavaScript脚本引擎
18 */ 17 */
19 public JsScriptEngine createJsEngine() { 18 public JsScriptEngine createJsEngine() {
20 - logger.debug("创建JavaScript脚本引擎"); 19 + log.debug("创建JavaScript脚本引擎");
21 return new JsScriptEngine(); 20 return new JsScriptEngine();
22 } 21 }
23 22
yudao-module-iot/yudao-module-iot-plugins/yudao-module-iot-plugin-script/src/main/java/cn/iocoder/yudao/module/iot/plugin/script/sandbox/JsSandbox.java
1 package cn.iocoder.yudao.module.iot.plugin.script.sandbox; 1 package cn.iocoder.yudao.module.iot.plugin.script.sandbox;
2 2
3 -import org.slf4j.Logger;  
4 -import org.slf4j.LoggerFactory; 3 +import lombok.extern.slf4j.Slf4j;
5 4
6 import javax.script.ScriptEngine; 5 import javax.script.ScriptEngine;
7 import java.util.Arrays; 6 import java.util.Arrays;
@@ -12,8 +11,8 @@ import java.util.regex.Pattern; @@ -12,8 +11,8 @@ import java.util.regex.Pattern;
12 /** 11 /**
13 * JavaScript脚本沙箱,限制脚本的执行权限 12 * JavaScript脚本沙箱,限制脚本的执行权限
14 */ 13 */
  14 +@Slf4j
15 public class JsSandbox implements ScriptSandbox { 15 public class JsSandbox implements ScriptSandbox {
16 - private static final Logger logger = LoggerFactory.getLogger(JsSandbox.class);  
17 16
18 /** 17 /**
19 * 禁止使用的关键字 18 * 禁止使用的关键字
@@ -59,10 +58,10 @@ public class JsSandbox implements ScriptSandbox { @@ -59,10 +58,10 @@ public class JsSandbox implements ScriptSandbox {
59 engine.eval("var Packages = undefined;"); 58 engine.eval("var Packages = undefined;");
60 59
61 // 增强安全控制可以在这里添加 60 // 增强安全控制可以在这里添加
62 - logger.debug("已应用JavaScript安全沙箱限制"); 61 + log.debug("已应用JavaScript安全沙箱限制");
63 62
64 } catch (Exception e) { 63 } catch (Exception e) {
65 - logger.warn("应用JavaScript沙箱限制失败: {}", e.getMessage()); 64 + log.warn("应用JavaScript沙箱限制失败: {}", e.getMessage());
66 } 65 }
67 } 66 }
68 67
@@ -75,20 +74,20 @@ public class JsSandbox implements ScriptSandbox { @@ -75,20 +74,20 @@ public class JsSandbox implements ScriptSandbox {
75 // 检查禁止的关键字 74 // 检查禁止的关键字
76 for (String keyword : FORBIDDEN_KEYWORDS) { 75 for (String keyword : FORBIDDEN_KEYWORDS) {
77 if (script.contains(keyword)) { 76 if (script.contains(keyword)) {
78 - logger.warn("脚本包含禁止使用的关键字: {}", keyword); 77 + log.warn("脚本包含禁止使用的关键字: {}", keyword);
79 return false; 78 return false;
80 } 79 }
81 } 80 }
82 81
83 // 使用正则表达式检查更复杂的模式 82 // 使用正则表达式检查更复杂的模式
84 if (FORBIDDEN_PATTERN.matcher(script).find()) { 83 if (FORBIDDEN_PATTERN.matcher(script).find()) {
85 - logger.warn("脚本包含禁止使用的模式"); 84 + log.warn("脚本包含禁止使用的模式");
86 return false; 85 return false;
87 } 86 }
88 87
89 // 脚本长度限制 88 // 脚本长度限制
90 if (script.length() > 1024 * 100) { // 限制100KB 89 if (script.length() > 1024 * 100) { // 限制100KB
91 - logger.warn("脚本太大,超过了限制"); 90 + log.warn("脚本太大,超过了限制");
92 return false; 91 return false;
93 } 92 }
94 93
yudao-module-iot/yudao-module-iot-plugins/yudao-module-iot-plugin-script/src/main/java/cn/iocoder/yudao/module/iot/plugin/script/service/ScriptServiceImpl.java
@@ -6,13 +6,12 @@ import cn.iocoder.yudao.module.iot.plugin.script.engine.AbstractScriptEngine; @@ -6,13 +6,12 @@ import cn.iocoder.yudao.module.iot.plugin.script.engine.AbstractScriptEngine;
6 import cn.iocoder.yudao.module.iot.plugin.script.engine.ScriptEngineFactory; 6 import cn.iocoder.yudao.module.iot.plugin.script.engine.ScriptEngineFactory;
7 import cn.iocoder.yudao.module.iot.plugin.script.sandbox.JsSandbox; 7 import cn.iocoder.yudao.module.iot.plugin.script.sandbox.JsSandbox;
8 import cn.iocoder.yudao.module.iot.plugin.script.sandbox.ScriptSandbox; 8 import cn.iocoder.yudao.module.iot.plugin.script.sandbox.ScriptSandbox;
9 -import org.slf4j.Logger;  
10 -import org.slf4j.LoggerFactory;  
11 -import org.springframework.beans.factory.annotation.Autowired; 9 +import lombok.extern.slf4j.Slf4j;
12 import org.springframework.stereotype.Service; 10 import org.springframework.stereotype.Service;
13 11
14 import javax.annotation.PostConstruct; 12 import javax.annotation.PostConstruct;
15 import javax.annotation.PreDestroy; 13 import javax.annotation.PreDestroy;
  14 +import javax.annotation.Resource;
16 import java.util.Map; 15 import java.util.Map;
17 import java.util.concurrent.ConcurrentHashMap; 16 import java.util.concurrent.ConcurrentHashMap;
18 17
@@ -20,10 +19,10 @@ import java.util.concurrent.ConcurrentHashMap; @@ -20,10 +19,10 @@ import java.util.concurrent.ConcurrentHashMap;
20 * 脚本服务实现类 19 * 脚本服务实现类
21 */ 20 */
22 @Service 21 @Service
  22 +@Slf4j
23 public class ScriptServiceImpl implements ScriptService { 23 public class ScriptServiceImpl implements ScriptService {
24 - private static final Logger logger = LoggerFactory.getLogger(ScriptServiceImpl.class);  
25 24
26 - @Autowired 25 + @Resource
27 private ScriptEngineFactory engineFactory; 26 private ScriptEngineFactory engineFactory;
28 27
29 /** 28 /**
@@ -50,7 +49,7 @@ public class ScriptServiceImpl implements ScriptService { @@ -50,7 +49,7 @@ public class ScriptServiceImpl implements ScriptService {
50 try { 49 try {
51 engine.destroy(); 50 engine.destroy();
52 } catch (Exception e) { 51 } catch (Exception e) {
53 - logger.error("销毁脚本引擎失败", e); 52 + log.error("销毁脚本引擎失败", e);
54 } 53 }
55 } 54 }
56 engineCache.clear(); 55 engineCache.clear();
@@ -75,7 +74,7 @@ public class ScriptServiceImpl implements ScriptService { @@ -75,7 +74,7 @@ public class ScriptServiceImpl implements ScriptService {
75 // 执行脚本 74 // 执行脚本
76 return engine.execute(script, context); 75 return engine.execute(script, context);
77 } catch (Exception e) { 76 } catch (Exception e) {
78 - logger.error("执行脚本失败: {}", e.getMessage()); 77 + log.error("执行脚本失败: {}", e.getMessage());
79 throw new RuntimeException("执行脚本失败: " + e.getMessage(), e); 78 throw new RuntimeException("执行脚本失败: " + e.getMessage(), e);
80 } 79 }
81 } 80 }
@@ -101,7 +100,7 @@ public class ScriptServiceImpl implements ScriptService { @@ -101,7 +100,7 @@ public class ScriptServiceImpl implements ScriptService {
101 public boolean validateScript(String scriptType, String script) { 100 public boolean validateScript(String scriptType, String script) {
102 ScriptSandbox sandbox = sandboxCache.get(scriptType.toLowerCase()); 101 ScriptSandbox sandbox = sandboxCache.get(scriptType.toLowerCase());
103 if (sandbox == null) { 102 if (sandbox == null) {
104 - logger.warn("找不到脚本类型[{}]对应的沙箱,使用默认JS沙箱", scriptType); 103 + log.warn("找不到脚本类型[{}]对应的沙箱,使用默认JS沙箱", scriptType);
105 sandbox = new JsSandbox(); 104 sandbox = new JsSandbox();
106 sandboxCache.put(scriptType.toLowerCase(), sandbox); 105 sandboxCache.put(scriptType.toLowerCase(), sandbox);
107 } 106 }
yudao-module-iot/yudao-module-iot-plugins/yudao-module-iot-plugin-script/src/main/java/cn/iocoder/yudao/module/iot/plugin/script/util/ScriptUtils.java
1 package cn.iocoder.yudao.module.iot.plugin.script.util; 1 package cn.iocoder.yudao.module.iot.plugin.script.util;
2 2
3 import cn.hutool.json.JSONUtil; 3 import cn.hutool.json.JSONUtil;
4 -import org.slf4j.Logger;  
5 -import org.slf4j.LoggerFactory; 4 +import lombok.extern.slf4j.Slf4j;
6 5
7 import java.util.Map; 6 import java.util.Map;
8 import java.util.concurrent.*; 7 import java.util.concurrent.*;
@@ -10,8 +9,8 @@ import java.util.concurrent.*; @@ -10,8 +9,8 @@ import java.util.concurrent.*;
10 /** 9 /**
11 * 脚本工具类,提供执行脚本的辅助方法 10 * 脚本工具类,提供执行脚本的辅助方法
12 */ 11 */
  12 +@Slf4j
13 public class ScriptUtils { 13 public class ScriptUtils {
14 - private static final Logger logger = LoggerFactory.getLogger(ScriptUtils.class);  
15 14
16 /** 15 /**
17 * 默认脚本执行超时时间(毫秒) 16 * 默认脚本执行超时时间(毫秒)
@@ -90,7 +89,7 @@ public class ScriptUtils { @@ -90,7 +89,7 @@ public class ScriptUtils {
90 // 使用hutool的JSONUtil工具类解析JSON 89 // 使用hutool的JSONUtil工具类解析JSON
91 return JSONUtil.toBean(json, Map.class); 90 return JSONUtil.toBean(json, Map.class);
92 } catch (Exception e) { 91 } catch (Exception e) {
93 - logger.error("解析JSON失败: {}", e.getMessage()); 92 + log.error("解析JSON失败: {}", e.getMessage());
94 return null; 93 return null;
95 } 94 }
96 } 95 }
@@ -114,12 +113,12 @@ public class ScriptUtils { @@ -114,12 +113,12 @@ public class ScriptUtils {
114 try { 113 try {
115 return Integer.parseInt((String) obj); 114 return Integer.parseInt((String) obj);
116 } catch (NumberFormatException e) { 115 } catch (NumberFormatException e) {
117 - logger.debug("无法将字符串转换为整数: {}", obj); 116 + log.debug("无法将字符串转换为整数: {}", obj);
118 return null; 117 return null;
119 } 118 }
120 } 119 }
121 120
122 - logger.debug("无法将对象转换为整数: {}", obj.getClass().getName()); 121 + log.debug("无法将对象转换为整数: {}", obj.getClass().getName());
123 return null; 122 return null;
124 } 123 }
125 124
@@ -142,12 +141,12 @@ public class ScriptUtils { @@ -142,12 +141,12 @@ public class ScriptUtils {
142 try { 141 try {
143 return Double.parseDouble((String) obj); 142 return Double.parseDouble((String) obj);
144 } catch (NumberFormatException e) { 143 } catch (NumberFormatException e) {
145 - logger.debug("无法将字符串转换为双精度浮点数: {}", obj); 144 + log.debug("无法将字符串转换为双精度浮点数: {}", obj);
146 return null; 145 return null;
147 } 146 }
148 } 147 }
149 148
150 - logger.debug("无法将对象转换为双精度浮点数: {}", obj.getClass().getName()); 149 + log.debug("无法将对象转换为双精度浮点数: {}", obj.getClass().getName());
151 return null; 150 return null;
152 } 151 }
153 152