diff --git a/hsweb-system/hsweb-system-script/hsweb-system-script-entity/src/main/java/org/hswebframework/web/entity/script/ScriptEntity.java b/hsweb-system/hsweb-system-script/hsweb-system-script-entity/src/main/java/org/hswebframework/web/entity/script/ScriptEntity.java index 71746b02a..1884d3bb2 100644 --- a/hsweb-system/hsweb-system-script/hsweb-system-script-entity/src/main/java/org/hswebframework/web/entity/script/ScriptEntity.java +++ b/hsweb-system/hsweb-system-script/hsweb-system-script-entity/src/main/java/org/hswebframework/web/entity/script/ScriptEntity.java @@ -1,105 +1,113 @@ package org.hswebframework.web.entity.script; + import org.hswebframework.web.commons.entity.GenericEntity; /** -* 动态脚本 实体 -* @author hsweb-generator-online -*/ -public interface ScriptEntity extends GenericEntity{ + * 动态脚本 实体 + * + * @author hsweb-generator-online + */ +public interface ScriptEntity extends GenericEntity { /*------------------------------------------- | 属性名常量 | ===========================================*/ - /** + /** * 脚本名称 */ - String name="name"; - /** + String name = "name"; + /** * 类型 */ - String type="type"; - /** + String type = "type"; + /** * 脚本内容 */ - String script="script"; - /** + String script = "script"; + /** * 脚本语言 */ - String language="language"; - /** + String language = "language"; + /** * 备注 */ - String remark="remark"; - /** + String remark = "remark"; + /** * 状态 */ - String status="status"; - /** + String status = "status"; + /** * 脚本标签 */ - String tag="tag"; - - /** - * @return 脚本名称 - */ - String getName(); + String tag = "tag"; - /** - * @param name 脚本名称 - */ - void setName(String name); - /** - * @return 类型 - */ - String getType(); + /** + * @return 脚本名称 + */ + String getName(); - /** - * @param type 类型 - */ - void setType(String type); - /** - * @return 脚本内容 - */ - String getScript(); + /** + * @param name 脚本名称 + */ + void setName(String name); - /** - * @param script 脚本内容 - */ - void setScript(String script); - /** - * @return 脚本语言 - */ - String getLanguage(); + /** + * @return 类型 + */ + String getType(); - /** - * @param language 脚本语言 - */ - void setLanguage(String language); - /** - * @return 备注 - */ - String getRemark(); + /** + * @param type 类型 + */ + void setType(String type); - /** - * @param remark 备注 - */ - void setRemark(String remark); - /** - * @return 状态 - */ - Long getStatus(); + /** + * @return 脚本内容 + */ + String getScript(); - /** - * @param status 状态 - */ - void setStatus(Long status); - /** - * @return 脚本标签 - */ - String getTag(); + /** + * @param script 脚本内容 + */ + void setScript(String script); + + /** + * @return 脚本语言 + */ + String getLanguage(); + + /** + * @param language 脚本语言 + */ + void setLanguage(String language); + + /** + * @return 备注 + */ + String getRemark(); + + /** + * @param remark 备注 + */ + void setRemark(String remark); + + /** + * @return 状态 + */ + Long getStatus(); + + /** + * @param status 状态 + */ + void setStatus(Long status); + + /** + * @return 脚本标签 + */ + String getTag(); + + /** + * @param tag 脚本标签 + */ + void setTag(String tag); - /** - * @param tag 脚本标签 - */ - void setTag(String tag); - } \ No newline at end of file diff --git a/hsweb-system/hsweb-system-script/hsweb-system-script-service/hsweb-system-script-service-api/src/main/java/org/hswebframework/web/service/script/ScriptExecutorService.java b/hsweb-system/hsweb-system-script/hsweb-system-script-service/hsweb-system-script-service-api/src/main/java/org/hswebframework/web/service/script/ScriptExecutorService.java index 4dfe18d47..f8fb75cee 100644 --- a/hsweb-system/hsweb-system-script/hsweb-system-script-service/hsweb-system-script-service-api/src/main/java/org/hswebframework/web/service/script/ScriptExecutorService.java +++ b/hsweb-system/hsweb-system-script/hsweb-system-script-service/hsweb-system-script-service-api/src/main/java/org/hswebframework/web/service/script/ScriptExecutorService.java @@ -3,7 +3,6 @@ package org.hswebframework.web.service.script; import java.util.Map; /** - * TODO 完成注释 * * @author zhouhao */ diff --git a/hsweb-system/hsweb-system-script/hsweb-system-script-service/hsweb-system-script-service-simple/pom.xml b/hsweb-system/hsweb-system-script/hsweb-system-script-service/hsweb-system-script-service-simple/pom.xml index 64c043ce8..3e108774f 100644 --- a/hsweb-system/hsweb-system-script/hsweb-system-script-service/hsweb-system-script-service-simple/pom.xml +++ b/hsweb-system/hsweb-system-script/hsweb-system-script-service/hsweb-system-script-service-simple/pom.xml @@ -22,5 +22,11 @@ hsweb-system-script-service-api ${project.version} + + org.hswebframework.web + hsweb-message-api + ${project.version} + true + \ No newline at end of file diff --git a/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 b/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 index 9aa0a516c..37631c343 100644 --- a/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 +++ b/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 @@ -16,17 +16,22 @@ import java.util.Map; /** * @author zhouhao */ -@Service("scriptExecutorService") public class DefaultScriptExecutorService implements ScriptExecutorService { @Autowired private ScriptService scriptService; + public void setScriptService(ScriptService scriptService) { + this.scriptService = scriptService; + } + @Override @Transactional(rollbackFor = Throwable.class) public Object execute(String id, Map parameters) throws Exception { ScriptEntity scriptEntity = scriptService.selectByPk(id); - + if (scriptEntity==null){ + return null; + } DynamicScriptEngine engine = DynamicScriptEngineFactory.getEngine(scriptEntity.getLanguage()); String scriptId = "dynamicScript-" + id; diff --git a/hsweb-system/hsweb-system-script/hsweb-system-script-service/hsweb-system-script-service-simple/src/main/java/org/hswebframework/web/service/script/simple/MessagerScriptExecutorService.java b/hsweb-system/hsweb-system-script/hsweb-system-script-service/hsweb-system-script-service-simple/src/main/java/org/hswebframework/web/service/script/simple/MessagerScriptExecutorService.java new file mode 100644 index 000000000..9ebe19fbb --- /dev/null +++ b/hsweb-system/hsweb-system-script/hsweb-system-script-service/hsweb-system-script-service-simple/src/main/java/org/hswebframework/web/service/script/simple/MessagerScriptExecutorService.java @@ -0,0 +1,139 @@ +package org.hswebframework.web.service.script.simple; + +import lombok.extern.slf4j.Slf4j; +import org.hswebframework.web.entity.script.ScriptEntity; +import org.hswebframework.web.id.IDGenerator; +import org.hswebframework.web.message.MessageSubscribe; +import org.hswebframework.web.message.Messager; +import org.hswebframework.web.message.builder.StaticMessageSubjectBuilder; +import org.hswebframework.web.service.script.ScriptExecutorService; +import org.hswebframework.web.service.script.ScriptService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.ApplicationContext; +import org.springframework.transaction.annotation.Transactional; +import org.springframework.util.StringUtils; + +import javax.annotation.PostConstruct; +import java.util.Map; +import java.util.Random; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.TimeUnit; + +import static org.hswebframework.web.message.builder.StaticMessageSubjectBuilder.*; +import static org.springframework.beans.factory.wiring.BeanWiringInfo.AUTOWIRE_BY_TYPE; + +/** + * @author zhouhao + * @since 3.0 + */ +@Slf4j +public class MessagerScriptExecutorService implements ScriptExecutorService { + + @Autowired + private Messager messager; + + private String tag; + + private String all = "all"; + + private ScriptExecutorService defaultScriptExecutorService; + + @Autowired + private ScriptService scriptService; + + @Autowired + private ApplicationContext applicationContext; + + @Autowired + public void setScriptService(ScriptService scriptService) { + this.scriptService = scriptService; + } + + public void setTag(String tag) { + this.tag = tag; + } + + private void initSubscribe(String topic) { + messager.subscribe(queue(topic)) + .onMessage(message -> { + ScriptExecutorMessage msg = ((ScriptExecutorMessage) message); + Object result; + try { + result = execute(msg.getScriptId(), msg.getParameter()); + + } catch (Exception e) { + e.printStackTrace(); + log.error("execute script {} error", msg, e); + result = e.getMessage(); + } + messager.publish(ScriptExecutorResultMessage.builder().result(result).build()) + .to(queue(topic + msg.getCallback())) + .send(); + }); + } + + @PostConstruct + public void subscribe() { + defaultScriptExecutorService = (DefaultScriptExecutorService) applicationContext.getAutowireCapableBeanFactory() + .autowire(DefaultScriptExecutorService.class, AUTOWIRE_BY_TYPE, false); + + if (tag != null) { + String[] tags = tag.split(","); + for (String tag : tags) { + initSubscribe(tag); + } + } else { + initSubscribe(all); + } + } + + public Object doExecute(String id, Map parameters) throws Exception { + return defaultScriptExecutorService.execute(id, parameters); + } + + @Override + @Transactional(rollbackFor = Throwable.class) + public Object execute(String id, Map parameters) throws Exception { + ScriptEntity scriptEntity = scriptService.selectByPk(id); + if (scriptEntity == null) { + return null; + } + String configTag = scriptEntity.getTag(); + String callBack = IDGenerator.MD5.generate(); + + String topic; + + if (StringUtils.isEmpty(configTag)) { + topic = all; + } else { + String[] tags = configTag.split(","); + topic = tags[new Random().nextInt(tags.length)]; + } + Object[] result = new Object[1]; + CountDownLatch latch = new CountDownLatch(1); + + MessageSubscribe subscribe = + messager.subscribe(queue(topic + callBack)) + .onMessage(msg -> { + result[0] = msg.getResult(); + latch.countDown(); + }); + + messager.publish(ScriptExecutorMessage.builder() + .callback(callBack) + .parameter(parameters) + .scriptId(id) + .build()) + .to(queue(topic)).send(); + + boolean success = latch.await(30, TimeUnit.SECONDS); + if (!success) { + log.error("await script execute error"); + } + subscribe.cancel(); + + return result[1]; + } + + +} diff --git a/hsweb-system/hsweb-system-script/hsweb-system-script-service/hsweb-system-script-service-simple/src/main/java/org/hswebframework/web/service/script/simple/ScriptExecutorMessage.java b/hsweb-system/hsweb-system-script/hsweb-system-script-service/hsweb-system-script-service-simple/src/main/java/org/hswebframework/web/service/script/simple/ScriptExecutorMessage.java new file mode 100644 index 000000000..b91376065 --- /dev/null +++ b/hsweb-system/hsweb-system-script/hsweb-system-script-service/hsweb-system-script-service-simple/src/main/java/org/hswebframework/web/service/script/simple/ScriptExecutorMessage.java @@ -0,0 +1,25 @@ +package org.hswebframework.web.service.script.simple; + +import lombok.*; +import org.hswebframework.web.message.Message; + +import java.util.Map; + +/** + * + * @author zhouhao + * @since 3.0 + */ +@Getter +@Setter +@Builder +@NoArgsConstructor +@AllArgsConstructor +@ToString +public class ScriptExecutorMessage implements Message{ + private String scriptId; + + private Map parameter; + + private String callback; +} diff --git a/hsweb-system/hsweb-system-script/hsweb-system-script-service/hsweb-system-script-service-simple/src/main/java/org/hswebframework/web/service/script/simple/ScriptExecutorResultMessage.java b/hsweb-system/hsweb-system-script/hsweb-system-script-service/hsweb-system-script-service-simple/src/main/java/org/hswebframework/web/service/script/simple/ScriptExecutorResultMessage.java new file mode 100644 index 000000000..77cfbbdcd --- /dev/null +++ b/hsweb-system/hsweb-system-script/hsweb-system-script-service/hsweb-system-script-service-simple/src/main/java/org/hswebframework/web/service/script/simple/ScriptExecutorResultMessage.java @@ -0,0 +1,17 @@ +package org.hswebframework.web.service.script.simple; + +import lombok.*; +import org.hswebframework.web.message.Message; + +/** + * @author zhouhao + * @since 3.0 + */ +@Getter +@Setter +@Builder +@NoArgsConstructor +@AllArgsConstructor +public class ScriptExecutorResultMessage implements Message{ + private Object result; +} diff --git a/hsweb-system/hsweb-system-script/hsweb-system-script-starter/pom.xml b/hsweb-system/hsweb-system-script/hsweb-system-script-starter/pom.xml index 246913847..d6ffb6d8b 100644 --- a/hsweb-system/hsweb-system-script/hsweb-system-script-starter/pom.xml +++ b/hsweb-system/hsweb-system-script/hsweb-system-script-starter/pom.xml @@ -73,6 +73,13 @@ 2.5 test + + + org.hswebframework.web + hsweb-message-api + ${project.version} + true + \ No newline at end of file diff --git a/hsweb-system/hsweb-system-script/hsweb-system-script-starter/src/main/java/org/hswebframework/web/service/dynamic/script/DynamicScriptAutoConfiguration.java b/hsweb-system/hsweb-system-script/hsweb-system-script-starter/src/main/java/org/hswebframework/web/service/dynamic/script/DynamicScriptAutoConfiguration.java new file mode 100644 index 000000000..f5787c989 --- /dev/null +++ b/hsweb-system/hsweb-system-script/hsweb-system-script-starter/src/main/java/org/hswebframework/web/service/dynamic/script/DynamicScriptAutoConfiguration.java @@ -0,0 +1,23 @@ +package org.hswebframework.web.service.dynamic.script; + +import org.hswebframework.web.service.script.simple.DefaultScriptExecutorService; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.ComponentScan; +import org.springframework.context.annotation.Configuration; + +/** + * @author zhouhao + * @since 3.0 + */ +@Configuration +@ComponentScan({ + "org.hswebframework.web.service.script", + "org.hswebframework.web.controller.script" +}) +public class DynamicScriptAutoConfiguration { + + @Bean + public DefaultScriptExecutorService defaultScriptExecutorService() { + return new DefaultScriptExecutorService(); + } +} diff --git a/hsweb-system/hsweb-system-script/hsweb-system-script-starter/src/main/resources/META-INF/spring.factories b/hsweb-system/hsweb-system-script/hsweb-system-script-starter/src/main/resources/META-INF/spring.factories new file mode 100644 index 000000000..ac1acd0fd --- /dev/null +++ b/hsweb-system/hsweb-system-script/hsweb-system-script-starter/src/main/resources/META-INF/spring.factories @@ -0,0 +1,3 @@ +# Auto Configure +org.springframework.boot.autoconfigure.EnableAutoConfiguration=\ +org.hswebframework.web.service.dynamic.script.DynamicScriptAutoConfiguration \ No newline at end of file diff --git a/hsweb-system/hsweb-system-script/hsweb-system-script-starter/src/test/java/org/hswebframework/web/workflow/flowable/ControllerTest.java b/hsweb-system/hsweb-system-script/hsweb-system-script-starter/src/test/java/org/hswebframework/web/workflow/flowable/ControllerTest.java index c6aece79a..9e612020e 100644 --- a/hsweb-system/hsweb-system-script/hsweb-system-script-starter/src/test/java/org/hswebframework/web/workflow/flowable/ControllerTest.java +++ b/hsweb-system/hsweb-system-script/hsweb-system-script-starter/src/test/java/org/hswebframework/web/workflow/flowable/ControllerTest.java @@ -30,4 +30,5 @@ public class ControllerTest extends SimpleWebApplicationTests { Assert.assertEquals(jsonObject.get("result"), "success"); } + }