Ver Fonte

优化动态脚本执行

zhouhao há 7 anos atrás
pai
commit
8fc01a51a6

+ 38 - 6
hsweb-system/hsweb-system-script/hsweb-system-script-controller/src/main/java/org/hswebframework/web/controller/script/ScriptController.java

@@ -3,15 +3,19 @@ package org.hswebframework.web.controller.script;
 import org.hswebframework.web.authorization.annotation.Authorize;
 import org.hswebframework.web.commons.entity.param.QueryParamEntity;
 import org.hswebframework.web.controller.SimpleGenericEntityController;
+import org.hswebframework.web.controller.message.ResponseMessage;
 import org.hswebframework.web.entity.script.ScriptEntity;
 import org.hswebframework.web.logging.AccessLogger;
-import  org.hswebframework.web.service.script.ScriptService;
+import org.hswebframework.web.service.script.ScriptExecutorService;
+import org.hswebframework.web.service.script.ScriptService;
 import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.web.bind.annotation.RequestMapping;
-import org.springframework.web.bind.annotation.RestController;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.HashMap;
+import java.util.Map;
 
 /**
- *  动态脚本
+ * 动态脚本
  *
  * @author hsweb-generator-online
  */
@@ -22,14 +26,42 @@ import org.springframework.web.bind.annotation.RestController;
 public class ScriptController implements SimpleGenericEntityController<ScriptEntity, String, QueryParamEntity> {
 
     private ScriptService scriptService;
-  
+
+    private ScriptExecutorService scriptExecutorService;
+
     @Autowired
     public void setScriptService(ScriptService scriptService) {
         this.scriptService = scriptService;
     }
-  
+
+    @Autowired
+    public void setScriptExecutorService(ScriptExecutorService scriptExecutorService) {
+        this.scriptExecutorService = scriptExecutorService;
+    }
+
     @Override
     public ScriptService getService() {
         return scriptService;
     }
+
+
+    @GetMapping("/{id}/execute")
+    @AccessLogger("执行脚本")
+    @Authorize(action = "execute")
+    public ResponseMessage<Object> executeForGet(@PathVariable String id, @RequestParam(required = false) Map<String, Object> parameters) throws Exception {
+        if (parameters == null) {
+            parameters = new HashMap<>();
+        }
+        Object result = scriptExecutorService.execute(id, parameters);
+        return ResponseMessage.ok(result);
+    }
+
+
+    @RequestMapping(value = "/{id}/execute", method = {RequestMethod.POST, RequestMethod.PUT})
+    @AccessLogger("执行脚本")
+    @Authorize(action = "execute")
+    public ResponseMessage<Object> executeFotPostAndPut(@PathVariable String id,
+                                                        @RequestBody(required = false) Map<String, Object> parameters) throws Exception {
+        return ResponseMessage.ok(executeForGet(id, parameters));
+    }
 }

+ 12 - 0
hsweb-system/hsweb-system-script/hsweb-system-script-service/hsweb-system-script-service-api/src/main/java/org/hswebframework/web/service/script/ScriptExecutorService.java

@@ -0,0 +1,12 @@
+package org.hswebframework.web.service.script;
+
+import java.util.Map;
+
+/**
+ * TODO 完成注释
+ *
+ * @author zhouhao
+ */
+public interface ScriptExecutorService {
+    Object execute(String id, Map<String, Object> parameters) throws Exception;
+}

+ 43 - 0
hsweb-system/hsweb-system-script/hsweb-system-script-service/hsweb-system-script-service-simple/src/main/java/org/hswebframework/web/service/script/simple/DefaultScriptExecutorService.java

@@ -0,0 +1,43 @@
+package org.hswebframework.web.service.script.simple;
+
+import org.apache.commons.codec.digest.DigestUtils;
+import org.hswebframework.expands.script.engine.DynamicScriptEngine;
+import org.hswebframework.expands.script.engine.DynamicScriptEngineFactory;
+import org.hswebframework.expands.script.engine.ScriptContext;
+import org.hswebframework.web.entity.script.ScriptEntity;
+import org.hswebframework.web.service.script.ScriptExecutorService;
+import org.hswebframework.web.service.script.ScriptService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+import java.util.Map;
+
+/**
+ * @author zhouhao
+ */
+@Service("scriptExecutorService")
+public class DefaultScriptExecutorService implements ScriptExecutorService {
+
+    @Autowired
+    private ScriptService scriptService;
+
+    @Override
+    @Transactional(rollbackFor = Throwable.class)
+    public Object execute(String id, Map<String, Object> parameters) throws Exception {
+        ScriptEntity scriptEntity = scriptService.selectByPk(id);
+
+        DynamicScriptEngine engine = DynamicScriptEngineFactory.getEngine(scriptEntity.getLanguage());
+
+        String scriptId = "dynamicScript-" + id;
+        String scriptMd5 = DigestUtils.md5Hex(scriptEntity.getScript());
+
+        ScriptContext context = engine.getContext(scriptId);
+
+        if (context == null || !context.getMd5().equals(scriptMd5)) {
+            engine.compile(scriptId, scriptEntity.getScript());
+        }
+
+        return engine.execute(scriptId, parameters).getIfSuccess();
+    }
+}

+ 4 - 1
hsweb-system/hsweb-system-script/hsweb-system-script-service/hsweb-system-script-service-simple/src/main/java/org/hswebframework/web/service/script/simple/SimpleScriptService.java

@@ -2,10 +2,12 @@ package org.hswebframework.web.service.script.simple;
 
 import org.hswebframework.web.dao.script.ScriptDao;
 import org.hswebframework.web.entity.script.ScriptEntity;
+import org.hswebframework.web.service.EnableCacheGenericEntityService;
 import org.hswebframework.web.service.GenericEntityService;
 import org.hswebframework.web.id.IDGenerator;
 import org.hswebframework.web.service.script.ScriptService;
 import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.cache.annotation.CacheConfig;
 import org.springframework.stereotype.Service;
 
 /**
@@ -14,7 +16,8 @@ import org.springframework.stereotype.Service;
  * @author hsweb-generator-online
  */
 @Service("scriptService")
-public class SimpleScriptService extends GenericEntityService<ScriptEntity, String>
+@CacheConfig(cacheNames = "dynamic-script")
+public class SimpleScriptService extends EnableCacheGenericEntityService<ScriptEntity, String>
         implements ScriptService {
     @Autowired
     private ScriptDao scriptDao;

+ 33 - 0
hsweb-system/hsweb-system-script/hsweb-system-script-starter/src/test/java/org/hswebframework/web/workflow/flowable/ControllerTest.java

@@ -0,0 +1,33 @@
+package org.hswebframework.web.workflow.flowable;
+
+
+import com.alibaba.fastjson.JSONObject;
+import org.hswebframework.web.tests.SimpleWebApplicationTests;
+import org.junit.Assert;
+import org.junit.Test;
+import org.springframework.http.MediaType;
+
+import java.util.concurrent.atomic.AtomicInteger;
+
+/**
+ * TODO 完善rest测试
+ *
+ * @Author wangwei
+ * @Date 2017/8/1.
+ */
+public class ControllerTest extends SimpleWebApplicationTests {
+
+    @Test
+    public void testRest() throws Exception {
+        JSONObject res = testPost("/script").setUp(setup -> {
+            setup.contentType(MediaType.APPLICATION_JSON);
+            setup.content("{\"id\":\"test\",\"name\":\"test\",\"language\":\"js\",\"script\":\"return 'success';\"}");
+        }).exec().resultAsJson();
+
+        JSONObject jsonObject = testGet("/script/test/execute")
+                .exec().resultAsJson();
+        System.out.println(jsonObject);
+        Assert.assertEquals(jsonObject.get("result"), "success");
+    }
+
+}

+ 21 - 0
hsweb-system/hsweb-system-script/hsweb-system-script-starter/src/test/resources/application.yml

@@ -0,0 +1,21 @@
+spring:
+    aop:
+        auto: true
+        proxy-target-class: true
+    datasource:
+       url : jdbc:h2:file:./target/script-test
+       username : sa
+       password :
+       type: com.alibaba.druid.pool.DruidDataSource
+    cache:
+       type: simple
+
+logging:
+  level:
+      org.flowable: debug
+      org.hswebframework.web: debug
+#      org.activiti: debug
+mybatis:
+  dynamic-datasource: false
+server:
+  port: 8088