Commit 0ae893272bf64f187fe8f9fb33205decfe27aafa
1 parent
a9dc654b
【功能优化】IoT: 重构脚本服务实现,启用脚本执行和测试逻辑,更新日志记录方式
Showing
9 changed files
with
132 additions
and
137 deletions
yudao-module-iot/yudao-module-iot-biz/pom.xml
| ... | ... | @@ -70,11 +70,11 @@ |
| 70 | 70 | </dependency> |
| 71 | 71 | |
| 72 | 72 | <!-- 脚本插件相关 --> |
| 73 | - <!--<dependency> | |
| 73 | + <dependency> | |
| 74 | 74 | <groupId>cn.iocoder.boot</groupId> |
| 75 | 75 | <artifactId>yudao-module-iot-plugin-script</artifactId> |
| 76 | 76 | <version>${revision}</version> |
| 77 | - </dependency>--> | |
| 77 | + </dependency> | |
| 78 | 78 | |
| 79 | 79 | <!-- 消息队列相关 --> |
| 80 | 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 | 9 | import cn.iocoder.yudao.module.iot.dal.dataobject.product.IotProductDO; |
| 10 | 10 | import cn.iocoder.yudao.module.iot.dal.dataobject.product.IotProductScriptDO; |
| 11 | 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 | 14 | import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; |
| 13 | 15 | import jakarta.annotation.Resource; |
| 14 | 16 | import lombok.extern.slf4j.Slf4j; |
| ... | ... | @@ -40,8 +42,8 @@ public class IotProductScriptServiceImpl implements IotProductScriptService { |
| 40 | 42 | @Resource |
| 41 | 43 | private IotProductService productService; |
| 42 | 44 | |
| 43 | -// @Resource | |
| 44 | -// private ScriptService scriptService; | |
| 45 | + @Resource | |
| 46 | + private ScriptService scriptService; | |
| 45 | 47 | |
| 46 | 48 | @Override |
| 47 | 49 | public Long createProductScript(IotProductScriptSaveReqVO createReqVO) { |
| ... | ... | @@ -118,90 +120,89 @@ public class IotProductScriptServiceImpl implements IotProductScriptService { |
| 118 | 120 | |
| 119 | 121 | @Override |
| 120 | 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 | 208 | @Override | ... | ... |
yudao-module-iot/yudao-module-iot-plugins/yudao-module-iot-plugin-script/pom.xml
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 | 2 | |
| 3 | 3 | import cn.iocoder.yudao.module.iot.plugin.script.context.PluginScriptContext; |
| 4 | 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 | 6 | import org.springframework.beans.factory.annotation.Autowired; |
| 8 | 7 | import org.springframework.stereotype.Component; |
| 9 | 8 | |
| ... | ... | @@ -14,8 +13,8 @@ import java.util.Map; |
| 14 | 13 | * 脚本使用示例类 |
| 15 | 14 | */ |
| 16 | 15 | @Component |
| 16 | +@Slf4j | |
| 17 | 17 | public class ScriptExample { |
| 18 | - private static final Logger logger = LoggerFactory.getLogger(ScriptExample.class); | |
| 19 | 18 | |
| 20 | 19 | @Autowired |
| 21 | 20 | private ScriptService scriptService; |
| ... | ... | @@ -31,7 +30,7 @@ public class ScriptExample { |
| 31 | 30 | params.put("b", 20); |
| 32 | 31 | |
| 33 | 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 | 72 | Object result = scriptService.executeJavaScript(script, context); |
| 74 | 73 | if (result != null) { |
| 75 | 74 | // 处理结果 |
| 76 | - logger.info("设备数据处理结果: {}", result); | |
| 75 | + log.info("设备数据处理结果: {}", result); | |
| 77 | 76 | |
| 78 | 77 | // 安全地将结果转换为Map |
| 79 | 78 | if (result instanceof Map) { |
| 80 | 79 | return (Map<String, Object>) result; |
| 81 | 80 | } else { |
| 82 | - logger.warn("脚本返回结果类型不是Map: {}", result.getClass().getName()); | |
| 81 | + log.warn("脚本返回结果类型不是Map: {}", result.getClass().getName()); | |
| 83 | 82 | } |
| 84 | 83 | } |
| 85 | 84 | } catch (Exception e) { |
| 86 | - logger.error("处理设备数据失败: {}", e.getMessage()); | |
| 85 | + log.error("处理设备数据失败: {}", e.getMessage()); | |
| 87 | 86 | } |
| 88 | 87 | |
| 89 | 88 | return new HashMap<>(); |
| ... | ... | @@ -121,10 +120,10 @@ public class ScriptExample { |
| 121 | 120 | if (result instanceof String) { |
| 122 | 121 | return (String) result; |
| 123 | 122 | } else if (result != null) { |
| 124 | - logger.warn("脚本返回结果类型不是String: {}", result.getClass().getName()); | |
| 123 | + log.warn("脚本返回结果类型不是String: {}", result.getClass().getName()); | |
| 125 | 124 | } |
| 126 | 125 | } catch (Exception e) { |
| 127 | - logger.error("生成设备命令失败: {}", e.getMessage()); | |
| 126 | + log.error("生成设备命令失败: {}", e.getMessage()); | |
| 128 | 127 | } |
| 129 | 128 | |
| 130 | 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 | 4 | import cn.iocoder.yudao.module.iot.plugin.script.context.ScriptContext; |
| 5 | 5 | import cn.iocoder.yudao.module.iot.plugin.script.sandbox.JsSandbox; |
| 6 | 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 | 9 | import javax.script.*; |
| 11 | 10 | import java.util.Map; |
| ... | ... | @@ -16,8 +15,8 @@ import java.util.concurrent.ConcurrentHashMap; |
| 16 | 15 | * JavaScript脚本引擎实现 |
| 17 | 16 | * 使用JSR-223 Nashorn脚本引擎 |
| 18 | 17 | */ |
| 18 | +@Slf4j | |
| 19 | 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 | 45 | |
| 47 | 46 | @Override |
| 48 | 47 | public void init() { |
| 49 | - logger.info("初始化JavaScript脚本引擎"); | |
| 48 | + log.info("初始化JavaScript脚本引擎"); | |
| 50 | 49 | |
| 51 | 50 | // 创建脚本引擎管理器 |
| 52 | 51 | engineManager = new ScriptEngineManager(); |
| ... | ... | @@ -54,7 +53,7 @@ public class JsScriptEngine extends AbstractScriptEngine { |
| 54 | 53 | // 获取JavaScript引擎 |
| 55 | 54 | engine = engineManager.getEngineByName(JS_ENGINE_NAME); |
| 56 | 55 | if (engine == null) { |
| 57 | - logger.error("无法创建JavaScript引擎,尝试使用JavaScript名称获取"); | |
| 56 | + log.error("无法创建JavaScript引擎,尝试使用JavaScript名称获取"); | |
| 58 | 57 | engine = engineManager.getEngineByName("JavaScript"); |
| 59 | 58 | } |
| 60 | 59 | |
| ... | ... | @@ -62,7 +61,7 @@ public class JsScriptEngine extends AbstractScriptEngine { |
| 62 | 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 | 66 | // 默认使用JS沙箱 |
| 68 | 67 | if (sandbox == null) { |
| ... | ... | @@ -100,7 +99,7 @@ public class JsScriptEngine extends AbstractScriptEngine { |
| 100 | 99 | // 执行脚本 |
| 101 | 100 | return engine.eval(script, bindings); |
| 102 | 101 | } catch (ScriptException e) { |
| 103 | - logger.error("执行JavaScript脚本异常: {}", e.getMessage()); | |
| 102 | + log.error("执行JavaScript脚本异常: {}", e.getMessage()); | |
| 104 | 103 | throw new RuntimeException("脚本执行异常: " + e.getMessage(), e); |
| 105 | 104 | } |
| 106 | 105 | }; |
| ... | ... | @@ -109,7 +108,7 @@ public class JsScriptEngine extends AbstractScriptEngine { |
| 109 | 108 | // 使用超时执行器执行脚本 |
| 110 | 109 | return ScriptUtils.executeWithTimeout(task, DEFAULT_TIMEOUT_MS); |
| 111 | 110 | } catch (Exception e) { |
| 112 | - logger.error("执行JavaScript脚本错误: {}", e.getMessage()); | |
| 111 | + log.error("执行JavaScript脚本错误: {}", e.getMessage()); | |
| 113 | 112 | throw new RuntimeException("脚本执行失败: " + e.getMessage(), e); |
| 114 | 113 | } |
| 115 | 114 | } |
| ... | ... | @@ -137,7 +136,7 @@ public class JsScriptEngine extends AbstractScriptEngine { |
| 137 | 136 | // 执行脚本 |
| 138 | 137 | return engine.eval(script, bindings); |
| 139 | 138 | } catch (ScriptException e) { |
| 140 | - logger.error("执行JavaScript脚本异常: {}", e.getMessage()); | |
| 139 | + log.error("执行JavaScript脚本异常: {}", e.getMessage()); | |
| 141 | 140 | throw new RuntimeException("脚本执行异常: " + e.getMessage(), e); |
| 142 | 141 | } |
| 143 | 142 | }; |
| ... | ... | @@ -146,14 +145,14 @@ public class JsScriptEngine extends AbstractScriptEngine { |
| 146 | 145 | // 使用超时执行器执行脚本 |
| 147 | 146 | return ScriptUtils.executeWithTimeout(task, DEFAULT_TIMEOUT_MS); |
| 148 | 147 | } catch (Exception e) { |
| 149 | - logger.error("执行JavaScript脚本错误: {}", e.getMessage()); | |
| 148 | + log.error("执行JavaScript脚本错误: {}", e.getMessage()); | |
| 150 | 149 | throw new RuntimeException("脚本执行失败: " + e.getMessage(), e); |
| 151 | 150 | } |
| 152 | 151 | } |
| 153 | 152 | |
| 154 | 153 | @Override |
| 155 | 154 | public void destroy() { |
| 156 | - logger.info("销毁JavaScript脚本引擎"); | |
| 155 | + log.info("销毁JavaScript脚本引擎"); | |
| 157 | 156 | cachedScripts.clear(); |
| 158 | 157 | engine = null; |
| 159 | 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 | 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 | 4 | import org.springframework.stereotype.Component; |
| 6 | 5 | |
| 7 | 6 | /** |
| 8 | 7 | * 脚本引擎工厂,用于创建不同类型的脚本引擎 |
| 9 | 8 | */ |
| 10 | 9 | @Component |
| 10 | +@Slf4j | |
| 11 | 11 | public class ScriptEngineFactory { |
| 12 | - private static final Logger logger = LoggerFactory.getLogger(ScriptEngineFactory.class); | |
| 13 | 12 | |
| 14 | 13 | /** |
| 15 | 14 | * 创建JavaScript脚本引擎 |
| ... | ... | @@ -17,7 +16,7 @@ public class ScriptEngineFactory { |
| 17 | 16 | * @return JavaScript脚本引擎 |
| 18 | 17 | */ |
| 19 | 18 | public JsScriptEngine createJsEngine() { |
| 20 | - logger.debug("创建JavaScript脚本引擎"); | |
| 19 | + log.debug("创建JavaScript脚本引擎"); | |
| 21 | 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 | 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 | 5 | import javax.script.ScriptEngine; |
| 7 | 6 | import java.util.Arrays; |
| ... | ... | @@ -12,8 +11,8 @@ import java.util.regex.Pattern; |
| 12 | 11 | /** |
| 13 | 12 | * JavaScript脚本沙箱,限制脚本的执行权限 |
| 14 | 13 | */ |
| 14 | +@Slf4j | |
| 15 | 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 | 58 | engine.eval("var Packages = undefined;"); |
| 60 | 59 | |
| 61 | 60 | // 增强安全控制可以在这里添加 |
| 62 | - logger.debug("已应用JavaScript安全沙箱限制"); | |
| 61 | + log.debug("已应用JavaScript安全沙箱限制"); | |
| 63 | 62 | |
| 64 | 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 | 74 | // 检查禁止的关键字 |
| 76 | 75 | for (String keyword : FORBIDDEN_KEYWORDS) { |
| 77 | 76 | if (script.contains(keyword)) { |
| 78 | - logger.warn("脚本包含禁止使用的关键字: {}", keyword); | |
| 77 | + log.warn("脚本包含禁止使用的关键字: {}", keyword); | |
| 79 | 78 | return false; |
| 80 | 79 | } |
| 81 | 80 | } |
| 82 | 81 | |
| 83 | 82 | // 使用正则表达式检查更复杂的模式 |
| 84 | 83 | if (FORBIDDEN_PATTERN.matcher(script).find()) { |
| 85 | - logger.warn("脚本包含禁止使用的模式"); | |
| 84 | + log.warn("脚本包含禁止使用的模式"); | |
| 86 | 85 | return false; |
| 87 | 86 | } |
| 88 | 87 | |
| 89 | 88 | // 脚本长度限制 |
| 90 | 89 | if (script.length() > 1024 * 100) { // 限制100KB |
| 91 | - logger.warn("脚本太大,超过了限制"); | |
| 90 | + log.warn("脚本太大,超过了限制"); | |
| 92 | 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 | 6 | import cn.iocoder.yudao.module.iot.plugin.script.engine.ScriptEngineFactory; |
| 7 | 7 | import cn.iocoder.yudao.module.iot.plugin.script.sandbox.JsSandbox; |
| 8 | 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 | 10 | import org.springframework.stereotype.Service; |
| 13 | 11 | |
| 14 | 12 | import javax.annotation.PostConstruct; |
| 15 | 13 | import javax.annotation.PreDestroy; |
| 14 | +import javax.annotation.Resource; | |
| 16 | 15 | import java.util.Map; |
| 17 | 16 | import java.util.concurrent.ConcurrentHashMap; |
| 18 | 17 | |
| ... | ... | @@ -20,10 +19,10 @@ import java.util.concurrent.ConcurrentHashMap; |
| 20 | 19 | * 脚本服务实现类 |
| 21 | 20 | */ |
| 22 | 21 | @Service |
| 22 | +@Slf4j | |
| 23 | 23 | public class ScriptServiceImpl implements ScriptService { |
| 24 | - private static final Logger logger = LoggerFactory.getLogger(ScriptServiceImpl.class); | |
| 25 | 24 | |
| 26 | - @Autowired | |
| 25 | + @Resource | |
| 27 | 26 | private ScriptEngineFactory engineFactory; |
| 28 | 27 | |
| 29 | 28 | /** |
| ... | ... | @@ -50,7 +49,7 @@ public class ScriptServiceImpl implements ScriptService { |
| 50 | 49 | try { |
| 51 | 50 | engine.destroy(); |
| 52 | 51 | } catch (Exception e) { |
| 53 | - logger.error("销毁脚本引擎失败", e); | |
| 52 | + log.error("销毁脚本引擎失败", e); | |
| 54 | 53 | } |
| 55 | 54 | } |
| 56 | 55 | engineCache.clear(); |
| ... | ... | @@ -75,7 +74,7 @@ public class ScriptServiceImpl implements ScriptService { |
| 75 | 74 | // 执行脚本 |
| 76 | 75 | return engine.execute(script, context); |
| 77 | 76 | } catch (Exception e) { |
| 78 | - logger.error("执行脚本失败: {}", e.getMessage()); | |
| 77 | + log.error("执行脚本失败: {}", e.getMessage()); | |
| 79 | 78 | throw new RuntimeException("执行脚本失败: " + e.getMessage(), e); |
| 80 | 79 | } |
| 81 | 80 | } |
| ... | ... | @@ -101,7 +100,7 @@ public class ScriptServiceImpl implements ScriptService { |
| 101 | 100 | public boolean validateScript(String scriptType, String script) { |
| 102 | 101 | ScriptSandbox sandbox = sandboxCache.get(scriptType.toLowerCase()); |
| 103 | 102 | if (sandbox == null) { |
| 104 | - logger.warn("找不到脚本类型[{}]对应的沙箱,使用默认JS沙箱", scriptType); | |
| 103 | + log.warn("找不到脚本类型[{}]对应的沙箱,使用默认JS沙箱", scriptType); | |
| 105 | 104 | sandbox = new JsSandbox(); |
| 106 | 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 | 1 | package cn.iocoder.yudao.module.iot.plugin.script.util; |
| 2 | 2 | |
| 3 | 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 | 6 | import java.util.Map; |
| 8 | 7 | import java.util.concurrent.*; |
| ... | ... | @@ -10,8 +9,8 @@ import java.util.concurrent.*; |
| 10 | 9 | /** |
| 11 | 10 | * 脚本工具类,提供执行脚本的辅助方法 |
| 12 | 11 | */ |
| 12 | +@Slf4j | |
| 13 | 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 | 89 | // 使用hutool的JSONUtil工具类解析JSON |
| 91 | 90 | return JSONUtil.toBean(json, Map.class); |
| 92 | 91 | } catch (Exception e) { |
| 93 | - logger.error("解析JSON失败: {}", e.getMessage()); | |
| 92 | + log.error("解析JSON失败: {}", e.getMessage()); | |
| 94 | 93 | return null; |
| 95 | 94 | } |
| 96 | 95 | } |
| ... | ... | @@ -114,12 +113,12 @@ public class ScriptUtils { |
| 114 | 113 | try { |
| 115 | 114 | return Integer.parseInt((String) obj); |
| 116 | 115 | } catch (NumberFormatException e) { |
| 117 | - logger.debug("无法将字符串转换为整数: {}", obj); | |
| 116 | + log.debug("无法将字符串转换为整数: {}", obj); | |
| 118 | 117 | return null; |
| 119 | 118 | } |
| 120 | 119 | } |
| 121 | 120 | |
| 122 | - logger.debug("无法将对象转换为整数: {}", obj.getClass().getName()); | |
| 121 | + log.debug("无法将对象转换为整数: {}", obj.getClass().getName()); | |
| 123 | 122 | return null; |
| 124 | 123 | } |
| 125 | 124 | |
| ... | ... | @@ -142,12 +141,12 @@ public class ScriptUtils { |
| 142 | 141 | try { |
| 143 | 142 | return Double.parseDouble((String) obj); |
| 144 | 143 | } catch (NumberFormatException e) { |
| 145 | - logger.debug("无法将字符串转换为双精度浮点数: {}", obj); | |
| 144 | + log.debug("无法将字符串转换为双精度浮点数: {}", obj); | |
| 146 | 145 | return null; |
| 147 | 146 | } |
| 148 | 147 | } |
| 149 | 148 | |
| 150 | - logger.debug("无法将对象转换为双精度浮点数: {}", obj.getClass().getName()); | |
| 149 | + log.debug("无法将对象转换为双精度浮点数: {}", obj.getClass().getName()); | |
| 151 | 150 | return null; |
| 152 | 151 | } |
| 153 | 152 | ... | ... |