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,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 |