diff --git a/pom.xml b/pom.xml index 72fef308ed4438899d71b9c2531a24967df12bb3..ffed0a3b221ad2a4fb8a7475315882a775b53fc9 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ org.smartboot.flow smart-flow-parent - 1.0.4 + 1.0.5 4.0.0 pom smart-flow @@ -17,6 +17,7 @@ smart-flow-manager smart-flow-script-condition smart-flow-springboot-starter + smart-flow-helper https://gitee.com/smartboot/smart-flow diff --git a/smart-flow-core/pom.xml b/smart-flow-core/pom.xml index 9cfc49bbcdf047d66bdb6fe1fc27bea4fc8a5874..80d45ac3675b8e7819f6ef9356afebbe3857d193 100644 --- a/smart-flow-core/pom.xml +++ b/smart-flow-core/pom.xml @@ -5,7 +5,7 @@ org.smartboot.flow smart-flow-parent - 1.0.4 + 1.0.5 4.0.0 diff --git a/smart-flow-core/src/main/java/org/smartboot/flow/core/Condition.java b/smart-flow-core/src/main/java/org/smartboot/flow/core/Condition.java index 24c956b803f00f4406ac3a8905638efc61037b32..34daf2d74ff154d8e6a98c1f850e36b224499025 100644 --- a/smart-flow-core/src/main/java/org/smartboot/flow/core/Condition.java +++ b/smart-flow-core/src/main/java/org/smartboot/flow/core/Condition.java @@ -1,5 +1,7 @@ package org.smartboot.flow.core; +import org.smartboot.flow.core.visitor.ConditionVisitor; + /** * @author qinluo * @date 2022-11-12 21:34:30 @@ -19,4 +21,11 @@ public abstract class Condition implements Describable { public String describe() { return this.getClass().getName(); } + + /** + * Visit condition's structure + */ + public void visit(ConditionVisitor visitor) { + visitor.visitSource(this); + } } diff --git a/smart-flow-core/src/main/java/org/smartboot/flow/core/DefaultIdentifierManager.java b/smart-flow-core/src/main/java/org/smartboot/flow/core/DefaultIdentifierManager.java index 92a75c491050e022e1e51449746f7dcd08225a39..f15a6329e10a3dca6b6f67a6d98df555f8573555 100644 --- a/smart-flow-core/src/main/java/org/smartboot/flow/core/DefaultIdentifierManager.java +++ b/smart-flow-core/src/main/java/org/smartboot/flow/core/DefaultIdentifierManager.java @@ -1,6 +1,6 @@ package org.smartboot.flow.core; -import org.smartboot.flow.core.util.ContactUtils; +import org.smartboot.flow.core.util.AuxiliaryUtils; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; @@ -21,11 +21,11 @@ public class DefaultIdentifierManager implements IdentifierManager { @Override public String generateIdentifier(String prefix) { - String identifier = ContactUtils.contact(prefix, sequence.getAndAdd(1)); + String identifier = AuxiliaryUtils.contact(prefix, sequence.getAndAdd(1)); // Ensure identifier is unique. while (identifiers.containsKey(identifier) || identifiers.put(identifier, 1) != null) { - identifier = ContactUtils.contact(prefix, sequence.getAndAdd(1)); + identifier = AuxiliaryUtils.contact(prefix, sequence.getAndAdd(1)); } return identifier; diff --git a/smart-flow-core/src/main/java/org/smartboot/flow/core/DegradeCallback.java b/smart-flow-core/src/main/java/org/smartboot/flow/core/DegradeCallback.java index cbc0aacb9d3bdf3ec771bdc262f8ca24c7378c17..02f9a8ee2c9df9b38b8ecd9400a535a85c950183 100644 --- a/smart-flow-core/src/main/java/org/smartboot/flow/core/DegradeCallback.java +++ b/smart-flow-core/src/main/java/org/smartboot/flow/core/DegradeCallback.java @@ -7,10 +7,21 @@ package org.smartboot.flow.core; */ public interface DegradeCallback extends Describable { + /** + * 降级回调通知 + * + * @param context 执行上下文 + * @param e 当前组件出现的异常 + */ default void doWithDegrade(EngineContext context, Throwable e) { } + /** + * 降级回调描述 + * + * @return 默认为classname + */ @Override default String describe() { return this.getClass().getName(); diff --git a/smart-flow-core/src/main/java/org/smartboot/flow/core/EngineConstants.java b/smart-flow-core/src/main/java/org/smartboot/flow/core/EngineConstants.java new file mode 100644 index 0000000000000000000000000000000000000000..54b59ce815bf1053881ef2e3777fde837f4eca87 --- /dev/null +++ b/smart-flow-core/src/main/java/org/smartboot/flow/core/EngineConstants.java @@ -0,0 +1,16 @@ +package org.smartboot.flow.core; + +/** + * @author qinluo + * @date 2023/2/1 21:52 + * @since 1.0.0 + */ +public interface EngineConstants { + + /** + * 匿名Pipeline前缀 + */ + String ANONYMOUS_PREFIX = "anonymous-pipeline"; + + int TAB_SIZE = 4; +} diff --git a/smart-flow-core/src/main/java/org/smartboot/flow/core/FlowEngine.java b/smart-flow-core/src/main/java/org/smartboot/flow/core/FlowEngine.java index 6b2e71bf517be5df738ea630718da99f75927503..42be7b2233fd10c486d4e19fc9bb03c8544f11bd 100644 --- a/smart-flow-core/src/main/java/org/smartboot/flow/core/FlowEngine.java +++ b/smart-flow-core/src/main/java/org/smartboot/flow/core/FlowEngine.java @@ -25,7 +25,14 @@ public class FlowEngine implements Describable, Validator, Measurable { private String name; private volatile boolean validateCalled = false; - /* Used in async invoking */ + /** + * Start timestamp + * + * @since 1.0.5 + */ + private final long startedAt = System.currentTimeMillis(); + + /** Used in async invoking */ private ExecutorService executor; public EngineContext execute(T t) { @@ -86,8 +93,6 @@ public class FlowEngine implements Describable, Validator, Measurable { context.listener.completed(context); } - - protected void initContext(EngineContext context) { context.clear(); context.setHandler(exceptionHandler); @@ -129,6 +134,16 @@ public class FlowEngine implements Describable, Validator, Measurable { this.executor = executor; } + /** + * Return flow-engine created timestamp. + * + * @return timestamp + * @since 1.0.5 + */ + public long getStartedAt() { + return startedAt; + } + @Override public String describe() { return "flow-engine##" + name; diff --git a/smart-flow-core/src/main/java/org/smartboot/flow/core/Pipeline.java b/smart-flow-core/src/main/java/org/smartboot/flow/core/Pipeline.java index 9ca9da774d5c9b690db468e51946ed48da152d6b..8f9ae29aa482c1d85b4f792e8235d9a352756173 100644 --- a/smart-flow-core/src/main/java/org/smartboot/flow/core/Pipeline.java +++ b/smart-flow-core/src/main/java/org/smartboot/flow/core/Pipeline.java @@ -10,9 +10,7 @@ import org.smartboot.flow.core.visitor.ComponentVisitor; import org.smartboot.flow.core.visitor.PipelineVisitor; import java.util.ArrayList; -import java.util.Collections; import java.util.List; -import java.util.concurrent.Future; /** * @author qinluo diff --git a/smart-flow-core/src/main/java/org/smartboot/flow/core/attribute/AttributeHolder.java b/smart-flow-core/src/main/java/org/smartboot/flow/core/attribute/AttributeHolder.java index c7f7b02e985adce4d501ee890b67e10b84257477..727bb78bd6346aaa2b4c5c37a0d107432ba1ec35 100644 --- a/smart-flow-core/src/main/java/org/smartboot/flow/core/attribute/AttributeHolder.java +++ b/smart-flow-core/src/main/java/org/smartboot/flow/core/attribute/AttributeHolder.java @@ -10,7 +10,7 @@ public class AttributeHolder { private final Attributes attribute; private Object value; - public AttributeHolder(Attributes attribute, Object value) { + private AttributeHolder(Attributes attribute, Object value) { this.attribute = attribute; this.value = value; } diff --git a/smart-flow-core/src/main/java/org/smartboot/flow/core/attribute/AttributeValueResolver.java b/smart-flow-core/src/main/java/org/smartboot/flow/core/attribute/AttributeValueResolver.java index 9c53a80454ec8a4ebb71442a427716fbe346a7c8..b7c50377826d0adda16bfa63dfa57bfad99cb476 100644 --- a/smart-flow-core/src/main/java/org/smartboot/flow/core/attribute/AttributeValueResolver.java +++ b/smart-flow-core/src/main/java/org/smartboot/flow/core/attribute/AttributeValueResolver.java @@ -100,7 +100,7 @@ public class AttributeValueResolver { // for classname. try { - return objectCreator.create(strValue, true); + return objectCreator.create(strValue, attribute.accept,true); } catch (Exception ignored) { // Maybe not a class. } diff --git a/smart-flow-core/src/main/java/org/smartboot/flow/core/attribute/Attributes.java b/smart-flow-core/src/main/java/org/smartboot/flow/core/attribute/Attributes.java index 835078e9967b93f716375cef0e69fb814cbff48f..19d485a78e92e3efd41d35fc338c12d3d5e95b13 100644 --- a/smart-flow-core/src/main/java/org/smartboot/flow/core/attribute/Attributes.java +++ b/smart-flow-core/src/main/java/org/smartboot/flow/core/attribute/Attributes.java @@ -15,6 +15,9 @@ import java.util.List; @SuppressWarnings("unchecked") public enum Attributes { + /** + * name + */ NAME("name", String.class) { @Override public void apply(Component component, Object value) { diff --git a/smart-flow-core/src/main/java/org/smartboot/flow/core/builder/AdapterBuilder.java b/smart-flow-core/src/main/java/org/smartboot/flow/core/builder/AdapterBuilder.java index af380278e0c59f1de933d1f77e3f1f483646afc9..143804e444b23f6e6c527a3cd782f77c803a088a 100644 --- a/smart-flow-core/src/main/java/org/smartboot/flow/core/builder/AdapterBuilder.java +++ b/smart-flow-core/src/main/java/org/smartboot/flow/core/builder/AdapterBuilder.java @@ -31,6 +31,7 @@ public class AdapterBuilder extends ExecutableBuilder { /** * Resolve return type. */ + @Override public AdapterBuilder apply(Attributes attributes, Object value) { super.apply(attributes, value); return this; diff --git a/smart-flow-core/src/main/java/org/smartboot/flow/core/builder/ChooseBuilder.java b/smart-flow-core/src/main/java/org/smartboot/flow/core/builder/ChooseBuilder.java index fab6a2111e3deb8ccda834a6830b510f0e327976..cccbf559f31ff2b54dd0f2a4c55789069888d2c3 100644 --- a/smart-flow-core/src/main/java/org/smartboot/flow/core/builder/ChooseBuilder.java +++ b/smart-flow-core/src/main/java/org/smartboot/flow/core/builder/ChooseBuilder.java @@ -77,6 +77,7 @@ public class ChooseBuilder extends ExecutableBuilder { return pipelineBuilder.next(chooseComponent); } + @Override public ChooseBuilder apply(Attributes attributes, Object value) { super.apply(attributes, value); return this; diff --git a/smart-flow-core/src/main/java/org/smartboot/flow/core/builder/ExecutableBuilder.java b/smart-flow-core/src/main/java/org/smartboot/flow/core/builder/ExecutableBuilder.java index db2e27e0c86338a8d3eac00bce7771595b96ac8b..122c43641e55a49d5751118570923ede305f1ee2 100644 --- a/smart-flow-core/src/main/java/org/smartboot/flow/core/builder/ExecutableBuilder.java +++ b/smart-flow-core/src/main/java/org/smartboot/flow/core/builder/ExecutableBuilder.java @@ -29,6 +29,7 @@ public class ExecutableBuilder extends AbstractComponentBuilder { return new ExecutableAdapter<>(executable); } + @Override public ExecutableBuilder apply(Attributes attributes, Object value) { super.apply(attributes, value); return this; diff --git a/smart-flow-core/src/main/java/org/smartboot/flow/core/builder/IfComponentBuilder.java b/smart-flow-core/src/main/java/org/smartboot/flow/core/builder/IfComponentBuilder.java index f38b26697977a0829646a559bfa3fc01234b4486..cd085444e914e75d603c571ea14b77ee462c53b4 100644 --- a/smart-flow-core/src/main/java/org/smartboot/flow/core/builder/IfComponentBuilder.java +++ b/smart-flow-core/src/main/java/org/smartboot/flow/core/builder/IfComponentBuilder.java @@ -35,6 +35,7 @@ public class IfComponentBuilder extends ExecutableBuilder{ this.condition = condition; } + @Override public IfComponentBuilder apply(Attributes attributes, Object value) { super.apply(attributes, value); return this; diff --git a/smart-flow-core/src/main/java/org/smartboot/flow/core/common/ComponentType.java b/smart-flow-core/src/main/java/org/smartboot/flow/core/common/ComponentType.java index 942b9f279e443bb48a7840e37b162dbc20610ff8..8a279987ac242378603662dc655f12850533ca91 100644 --- a/smart-flow-core/src/main/java/org/smartboot/flow/core/common/ComponentType.java +++ b/smart-flow-core/src/main/java/org/smartboot/flow/core/common/ComponentType.java @@ -1,15 +1,36 @@ package org.smartboot.flow.core.common; /** + * 组件类型 + * * @author yamikaze * @date 2022/11/14 */ public enum ComponentType { + /** + * 基本组件 + */ BASIC, + + /** + * IF分支选择组件 + */ IF, + + /** + * CHOOSE分支选择组件 + */ CHOOSE, + + /** + * 子流程组件 + */ PIPELINE, + + /** + * 适配器组件 + */ ADAPTER, } diff --git a/smart-flow-core/src/main/java/org/smartboot/flow/core/component/AdapterComponent.java b/smart-flow-core/src/main/java/org/smartboot/flow/core/component/AdapterComponent.java index c2258a1c1d8adb60a8d6e568be9e53e464de4ee2..c14e65e377c7c637eac2ab933d59887209331527 100644 --- a/smart-flow-core/src/main/java/org/smartboot/flow/core/component/AdapterComponent.java +++ b/smart-flow-core/src/main/java/org/smartboot/flow/core/component/AdapterComponent.java @@ -93,6 +93,9 @@ public class AdapterComponent extends Component { @Override public void visit(ComponentVisitor visitor) { + visitor.visitAttributes(attributes); + visitor.visitSource(this); + visitor.visitExecutable(adapter.describe()); ComponentVisitor componentVisitor = visitor.visitComponent(component.getType(), component.getName(), component.describe()); if (componentVisitor != null) { component.visit(componentVisitor); diff --git a/smart-flow-core/src/main/java/org/smartboot/flow/core/component/ChooseComponent.java b/smart-flow-core/src/main/java/org/smartboot/flow/core/component/ChooseComponent.java index f11520b4fc4a473a62c83583c6bc102939c7a30a..dd8734e3581b03b8455ae44a7d74495fde86893f 100644 --- a/smart-flow-core/src/main/java/org/smartboot/flow/core/component/ChooseComponent.java +++ b/smart-flow-core/src/main/java/org/smartboot/flow/core/component/ChooseComponent.java @@ -7,6 +7,7 @@ import org.smartboot.flow.core.Key; import org.smartboot.flow.core.common.ComponentType; import org.smartboot.flow.core.util.AssertUtil; import org.smartboot.flow.core.visitor.ComponentVisitor; +import org.smartboot.flow.core.visitor.ConditionVisitor; import java.util.Map; @@ -112,7 +113,10 @@ public class ChooseComponent extends Component { @Override public void visit(ComponentVisitor visitor) { visitor.visitAttributes(attributes); - visitor.visitCondition(condition.describe()); + ConditionVisitor conditionVisitor = visitor.visitCondition(condition.describe()); + if (conditionVisitor != null) { + condition.visit(conditionVisitor); + } visitor.visitSource(this); branches.forEach((k, v) -> { diff --git a/smart-flow-core/src/main/java/org/smartboot/flow/core/component/Component.java b/smart-flow-core/src/main/java/org/smartboot/flow/core/component/Component.java index f874be307a46e047fb24515a84bb0b5b6deaacd6..0493f12610012cdd42861f0381bfa77efa3e601b 100644 --- a/smart-flow-core/src/main/java/org/smartboot/flow/core/component/Component.java +++ b/smart-flow-core/src/main/java/org/smartboot/flow/core/component/Component.java @@ -132,9 +132,9 @@ public abstract class Component implements Rollback, Describable, Va } - /* Visit component's structure */ + /** Visit component's structure */ public abstract void visit(ComponentVisitor visitor); - /* Returns component's type */ + /** Returns component's type */ public abstract ComponentType getType(); } diff --git a/smart-flow-core/src/main/java/org/smartboot/flow/core/component/IfComponent.java b/smart-flow-core/src/main/java/org/smartboot/flow/core/component/IfComponent.java index a06ed12b408d8c96c88def7fabff4e007b064c51..f495930137caf64548585af387db54a54dc33dc9 100644 --- a/smart-flow-core/src/main/java/org/smartboot/flow/core/component/IfComponent.java +++ b/smart-flow-core/src/main/java/org/smartboot/flow/core/component/IfComponent.java @@ -7,6 +7,7 @@ import org.smartboot.flow.core.Key; import org.smartboot.flow.core.common.ComponentType; import org.smartboot.flow.core.util.AssertUtil; import org.smartboot.flow.core.visitor.ComponentVisitor; +import org.smartboot.flow.core.visitor.ConditionVisitor; /** * @author qinluo @@ -93,7 +94,11 @@ public class IfComponent extends Component{ @Override public void visit(ComponentVisitor visitor) { visitor.visitAttributes(attributes); - visitor.visitCondition(condition.describe()); + ConditionVisitor conditionVisitor = visitor.visitCondition(condition.describe()); + if (conditionVisitor != null) { + condition.visit(conditionVisitor); + } + visitor.visitSource(this); ComponentVisitor thenVisitor = visitor.visitComponent(thenComponent.getType(), thenComponent.getName(), thenComponent.describe()); if (thenVisitor != null) { diff --git a/smart-flow-core/src/main/java/org/smartboot/flow/core/exception/ExceptionHandler.java b/smart-flow-core/src/main/java/org/smartboot/flow/core/exception/ExceptionHandler.java index 7e9b5684c1e2b0d14b93794ad65e95d62fe8c1c8..47f640355d1d2ae01fb03266b960debbccf548d5 100644 --- a/smart-flow-core/src/main/java/org/smartboot/flow/core/exception/ExceptionHandler.java +++ b/smart-flow-core/src/main/java/org/smartboot/flow/core/exception/ExceptionHandler.java @@ -9,5 +9,13 @@ import org.smartboot.flow.core.EngineContext; */ public interface ExceptionHandler { + /** + * 处理异常 + * + * @param context 执行上下文 + * @param e 抛出的异常 + * @param 入参泛型 + * @param 出参泛型 + */ void handle(EngineContext context, Throwable e); } diff --git a/smart-flow-core/src/main/java/org/smartboot/flow/core/executable/AbstractExecutable.java b/smart-flow-core/src/main/java/org/smartboot/flow/core/executable/AbstractExecutable.java index 9e3f8b760e1fb9e0eb36e666681d3bd73f81d26a..94007aa8e1911d62072fa71dfff0f85354763633 100644 --- a/smart-flow-core/src/main/java/org/smartboot/flow/core/executable/AbstractExecutable.java +++ b/smart-flow-core/src/main/java/org/smartboot/flow/core/executable/AbstractExecutable.java @@ -12,6 +12,7 @@ import org.smartboot.flow.core.EngineContext; */ public abstract class AbstractExecutable implements Executable { + @Override public void execute(EngineContext context) { this.execute(context.getReq(), context.getResult()); } diff --git a/smart-flow-core/src/main/java/org/smartboot/flow/core/executable/Executable.java b/smart-flow-core/src/main/java/org/smartboot/flow/core/executable/Executable.java index 3ee6800a5351f162326c868acacf9123e024c0be..046121c4ddbeff87b1b6846024358f9fde5c3fd1 100644 --- a/smart-flow-core/src/main/java/org/smartboot/flow/core/executable/Executable.java +++ b/smart-flow-core/src/main/java/org/smartboot/flow/core/executable/Executable.java @@ -14,5 +14,10 @@ import org.smartboot.flow.core.Rollback; */ public interface Executable extends Rollback, Describable { + /** + * 业务逻辑执行 + * + * @param context 执行上下文 + */ void execute(EngineContext context); } diff --git a/smart-flow-core/src/main/java/org/smartboot/flow/core/executable/ExecutableAdapter.java b/smart-flow-core/src/main/java/org/smartboot/flow/core/executable/ExecutableAdapter.java index b22dc9c84d1939afa96ec13eb3b4f5fbd6788e88..e11d123b28aa732a52e88efcdfb6db7e0d39e14e 100644 --- a/smart-flow-core/src/main/java/org/smartboot/flow/core/executable/ExecutableAdapter.java +++ b/smart-flow-core/src/main/java/org/smartboot/flow/core/executable/ExecutableAdapter.java @@ -30,6 +30,7 @@ public class ExecutableAdapter extends Component implements Rollback< this.executable = executable; } + @Override public int invoke(EngineContext context) { context.enter(this); diff --git a/smart-flow-core/src/main/java/org/smartboot/flow/core/invoker/InvokeListener.java b/smart-flow-core/src/main/java/org/smartboot/flow/core/invoker/InvokeListener.java index 545f461b34b984367b03e94162ba9a071ea436d8..408c1da315d3b88d52d35544bb08471474d30696 100644 --- a/smart-flow-core/src/main/java/org/smartboot/flow/core/invoker/InvokeListener.java +++ b/smart-flow-core/src/main/java/org/smartboot/flow/core/invoker/InvokeListener.java @@ -10,5 +10,13 @@ import org.smartboot.flow.core.component.Component; */ public interface InvokeListener { + /** + * 执行完毕后通知处理 + * + * @param component 执行的组件 + * @param context 执行上下文 + * @param 入参泛型 + * @param 出参泛型 + */ void onCompleted(Component component, EngineContext context); } diff --git a/smart-flow-core/src/main/java/org/smartboot/flow/core/manager/ComponentModel.java b/smart-flow-core/src/main/java/org/smartboot/flow/core/manager/ComponentModel.java index fc5f7b738840a34105ab97323faecc24e7dd4784..d5de986cf0dfbbea100d2adeb8c78c1fd05522da 100644 --- a/smart-flow-core/src/main/java/org/smartboot/flow/core/manager/ComponentModel.java +++ b/smart-flow-core/src/main/java/org/smartboot/flow/core/manager/ComponentModel.java @@ -27,9 +27,7 @@ public class ComponentModel extends Uniqueness { private final Map components = new ConcurrentHashMap<>(); String executable; - // basic, if, choose, pipeline; ComponentType type; - // Used with type pipeline. PipelineModel pipeline; String condition; private String branch; @@ -84,11 +82,11 @@ public class ComponentModel extends Uniqueness { collected.put(this.identifier, this); return collected; } else if (type == ComponentType.BASIC) { - Map temp = new HashMap<>(); + Map temp = new HashMap<>(4); temp.put(this.identifier, this); return temp; } else { - Map temp = new HashMap<>(); + Map temp = new HashMap<>(8); this.components.forEach((k, v) -> temp.putAll(v.collect())); temp.put(this.identifier, this); return temp; diff --git a/smart-flow-core/src/main/java/org/smartboot/flow/core/manager/RegisterEngineVisitor.java b/smart-flow-core/src/main/java/org/smartboot/flow/core/manager/RegisterEngineVisitor.java index 66da81bc641c14236b4fdadc97ffd944f114bbe0..a69ccc7336c612b3f1c1062acf6ca37093f6abd0 100644 --- a/smart-flow-core/src/main/java/org/smartboot/flow/core/manager/RegisterEngineVisitor.java +++ b/smart-flow-core/src/main/java/org/smartboot/flow/core/manager/RegisterEngineVisitor.java @@ -1,7 +1,7 @@ package org.smartboot.flow.core.manager; import org.smartboot.flow.core.FlowEngine; -import org.smartboot.flow.core.util.ContactUtils; +import org.smartboot.flow.core.util.AuxiliaryUtils; import org.smartboot.flow.core.visitor.EngineVisitor; import org.smartboot.flow.core.visitor.PipelineVisitor; @@ -33,7 +33,7 @@ public class RegisterEngineVisitor extends EngineVisitor { @Override public PipelineVisitor visitPipeline(String pipeline) { - PipelineModel pipelineModel = new PipelineModel(pipeline, ContactUtils.contact(this.model.getIdentifier(), pipeline)); + PipelineModel pipelineModel = new PipelineModel(pipeline, AuxiliaryUtils.contact(this.model.getIdentifier(), pipeline)); this.model.setPipeline(pipelineModel); return new RegisteredPipelineVisitor(pipelineModel, visited); } diff --git a/smart-flow-core/src/main/java/org/smartboot/flow/core/manager/RegisteredComponentVisitor.java b/smart-flow-core/src/main/java/org/smartboot/flow/core/manager/RegisteredComponentVisitor.java index 68f43760a2b1663c9eea520da320f690cfba3dc6..d664ac45be38f0558cae6ae32454b5ebaf838e65 100644 --- a/smart-flow-core/src/main/java/org/smartboot/flow/core/manager/RegisteredComponentVisitor.java +++ b/smart-flow-core/src/main/java/org/smartboot/flow/core/manager/RegisteredComponentVisitor.java @@ -4,8 +4,8 @@ import org.smartboot.flow.core.common.ComponentType; import org.smartboot.flow.core.attribute.AttributeHolder; import org.smartboot.flow.core.component.Component; import org.smartboot.flow.core.util.AuxiliaryUtils; -import org.smartboot.flow.core.util.ContactUtils; import org.smartboot.flow.core.visitor.ComponentVisitor; +import org.smartboot.flow.core.visitor.ConditionVisitor; import org.smartboot.flow.core.visitor.PipelineVisitor; import java.util.List; @@ -28,7 +28,7 @@ public class RegisteredComponentVisitor extends ComponentVisitor { @Override public PipelineVisitor visitPipeline(String pipeline) { - PipelineModel pipelineModel = new PipelineModel(pipeline, ContactUtils.contact(model.getIdentifier(), pipeline)); + PipelineModel pipelineModel = new PipelineModel(pipeline, AuxiliaryUtils.contact(model.getIdentifier(), pipeline)); this.model.pipeline = pipelineModel; return new RegisteredPipelineVisitor(pipelineModel, visited); } @@ -39,16 +39,17 @@ public class RegisteredComponentVisitor extends ComponentVisitor { } @Override - public void visitCondition(String condition) { + public ConditionVisitor visitCondition(String condition) { this.model.condition = (condition); + return null; } @Override public ComponentVisitor visitComponent(ComponentType type, String name, String describe) { - String identifier = ContactUtils.contact(model.getIdentifier(), AuxiliaryUtils.or(name, describe)); + String identifier = AuxiliaryUtils.contact(model.getIdentifier(), AuxiliaryUtils.or(name, describe)); String branch = null; if (this.model.type == ComponentType.CHOOSE) { - identifier = ContactUtils.contact(model.getIdentifier(), "default"); + identifier = AuxiliaryUtils.contact(model.getIdentifier(), "default"); branch = "default"; } @@ -65,7 +66,7 @@ public class RegisteredComponentVisitor extends ComponentVisitor { @Override public ComponentVisitor visitBranch(Object branch, ComponentType type, String name, String describe) { - ComponentModel model = new ComponentModel(type, ContactUtils.contact(this.model.getIdentifier(), "branch", String.valueOf(branch))); + ComponentModel model = new ComponentModel(type, AuxiliaryUtils.contact(this.model.getIdentifier(), "branch", String.valueOf(branch))); model.setBranch((String.valueOf(branch))); this.model.addComponent(model); return new RegisteredComponentVisitor(model, visited); diff --git a/smart-flow-core/src/main/java/org/smartboot/flow/core/manager/RegisteredPipelineVisitor.java b/smart-flow-core/src/main/java/org/smartboot/flow/core/manager/RegisteredPipelineVisitor.java index d2e25ee4df9e337d645646d8e0d9407a5b07385c..6572effeaf00f3f20ba63d60574c8ca5d402af81 100644 --- a/smart-flow-core/src/main/java/org/smartboot/flow/core/manager/RegisteredPipelineVisitor.java +++ b/smart-flow-core/src/main/java/org/smartboot/flow/core/manager/RegisteredPipelineVisitor.java @@ -3,7 +3,6 @@ package org.smartboot.flow.core.manager; import org.smartboot.flow.core.Pipeline; import org.smartboot.flow.core.common.ComponentType; import org.smartboot.flow.core.util.AuxiliaryUtils; -import org.smartboot.flow.core.util.ContactUtils; import org.smartboot.flow.core.visitor.ComponentVisitor; import org.smartboot.flow.core.visitor.PipelineVisitor; @@ -38,7 +37,7 @@ public class RegisteredPipelineVisitor extends PipelineVisitor { return null; } - ComponentModel comp = new ComponentModel(type, ContactUtils.contact(this.pipelineModel.getIdentifier(), AuxiliaryUtils.or(name, describe))); + ComponentModel comp = new ComponentModel(type, AuxiliaryUtils.contact(this.pipelineModel.getIdentifier(), AuxiliaryUtils.or(name, describe))); this.pipelineModel.addComponent(comp); return new RegisteredComponentVisitor(comp, visited); } diff --git a/smart-flow-core/src/main/java/org/smartboot/flow/core/metrics/MetricExecutionListener.java b/smart-flow-core/src/main/java/org/smartboot/flow/core/metrics/MetricExecutionListener.java index 550acc40aa41b2ec39f821b4476ba1d77a1f6c5b..8eb1fd528b2a22194af1f3de7f6f6c8896a4c26a 100644 --- a/smart-flow-core/src/main/java/org/smartboot/flow/core/metrics/MetricExecutionListener.java +++ b/smart-flow-core/src/main/java/org/smartboot/flow/core/metrics/MetricExecutionListener.java @@ -36,7 +36,7 @@ public class MetricExecutionListener extends ExecutionListenerSupport { Map escaped = context.getExt(Key.of(this)); if (escaped == null) { - escaped = new ConcurrentHashMap<>(); + escaped = new ConcurrentHashMap<>(32); context.putExt(Key.of(this), escaped); } diff --git a/smart-flow-core/src/main/java/org/smartboot/flow/core/metrics/MetricKind.java b/smart-flow-core/src/main/java/org/smartboot/flow/core/metrics/MetricKind.java index c2f80b8cf2bd45ef7a55174cb7a10f9c1db38782..921b0161c9ef53218df5a301735d62c2821289bd 100644 --- a/smart-flow-core/src/main/java/org/smartboot/flow/core/metrics/MetricKind.java +++ b/smart-flow-core/src/main/java/org/smartboot/flow/core/metrics/MetricKind.java @@ -7,7 +7,13 @@ package org.smartboot.flow.core.metrics; */ public enum MetricKind { + /** + * 累加 + */ ACCUMULATE, + /** + * 最大 + */ MAX, } diff --git a/smart-flow-core/src/main/java/org/smartboot/flow/core/parser/BuilderDefinitionVisitor.java b/smart-flow-core/src/main/java/org/smartboot/flow/core/parser/BuilderDefinitionVisitor.java index 1ee33c134c4ede72b0a41bb77a0082bae515086b..7cb1386c028c85c464b610cbcc1bdf9bb80a4461 100644 --- a/smart-flow-core/src/main/java/org/smartboot/flow/core/parser/BuilderDefinitionVisitor.java +++ b/smart-flow-core/src/main/java/org/smartboot/flow/core/parser/BuilderDefinitionVisitor.java @@ -61,9 +61,9 @@ public class BuilderDefinitionVisitor implements DefinitionVisitor { Class javaType = sed.getJavaType(); ScriptCondition condition; if (javaType != null) { - condition = objectCreator.create(javaType.getName(), true); + condition = objectCreator.create(javaType.getName(), ScriptCondition.class, true); } else { - condition = objectCreator.create(sed.getType(), true); + condition = objectCreator.create(sed.getType(), ScriptCondition.class, true); } condition.setName(sed.getName()); @@ -155,16 +155,12 @@ public class BuilderDefinitionVisitor implements DefinitionVisitor { // resolve value type. builder.apply(p.getAttribute(), p.getValue()); }); - Component component = builder.newAdapter((Executable) newInstance(ed.getExecute())); + Component component = builder.newAdapter(newInstance(ed.getExecute(), Executable.class)); namedComponents.put(ed.getIdentifier(), component); } - private Object newInstance(String type) { - try { - return objectCreator.create(type, useCache); - } catch (Exception e) { - throw new IllegalStateException(type, e); - } + private T newInstance(String type, Class expectType) { + return objectCreator.create(type, expectType, useCache); } @Override @@ -172,11 +168,11 @@ public class BuilderDefinitionVisitor implements DefinitionVisitor { String test = ed.getTest(); Condition condition; if (AuxiliaryUtils.isType(test)) { - condition = (Condition) newInstance(test); + condition = newInstance(test, Condition.class); } else if (ed.getContext().getRegistered(test) != null) { condition = getInternalObject(test, ed.getContext()); } else { - condition = (Condition) newInstance(test); + condition = newInstance(test, Condition.class); } AssertUtil.notNull(condition, "can't find condition for if-element, test = " + test); @@ -212,11 +208,11 @@ public class BuilderDefinitionVisitor implements DefinitionVisitor { String test = ed.getTest(); Condition condition; if (AuxiliaryUtils.isType(test)) { - condition = (Condition) newInstance(test); + condition = newInstance(test, Condition.class); } else if (ed.getContext().getRegistered(test) != null) { condition = getInternalObject(test, ed.getContext()); } else { - condition = (Condition) newInstance(test); + condition = newInstance(test, Condition.class); } AssertUtil.notNull(condition, "can't find condition for choose-element, test = " + test); @@ -254,18 +250,13 @@ public class BuilderDefinitionVisitor implements DefinitionVisitor { @Override public void visit(AdapterDefinition ed) { String execute = ed.getExecute(); - Object adapter; - if (AuxiliaryUtils.isType(execute)) { - adapter = newInstance(execute); - } else { - adapter = ed.getContext().getRegistered(execute); - } + Adapter adapter = newInstance(execute, Adapter.class); AssertUtil.notNull(adapter, "can't find adapter , execute=" + execute); ed.getPipelineElement().visit(this); Component component = namedComponents.get(ed.getPipelineElement().getIdentifier()); - AdapterBuilder adapterBuilder = new AdapterBuilder((Adapter) adapter, component); + AdapterBuilder adapterBuilder = new AdapterBuilder(adapter, component); ed.getAttributes().forEach(p -> { // resolve value type. adapterBuilder.apply(p.getAttribute(), p.getValue()); @@ -284,9 +275,16 @@ public class BuilderDefinitionVisitor implements DefinitionVisitor { return new ArrayList<>(namedEngines.keySet()); } - @SuppressWarnings("unchecked") public FlowEngine getEngine(String name) { EngineBuilder engineBuilder = namedEngines.get(name); return (FlowEngine)engineBuilder.build(); } + + /** + * Pipeline组装后置通知 + */ + public interface PipelineEndCallBack { + + void execute(Pipeline pipeline); + } } diff --git a/smart-flow-core/src/main/java/org/smartboot/flow/core/parser/DefaultObjectCreator.java b/smart-flow-core/src/main/java/org/smartboot/flow/core/parser/DefaultObjectCreator.java index 66df9a7aca647fa1f5767364f0530c734989881a..e5247d1123be611ac25134912206794277f8ab5c 100644 --- a/smart-flow-core/src/main/java/org/smartboot/flow/core/parser/DefaultObjectCreator.java +++ b/smart-flow-core/src/main/java/org/smartboot/flow/core/parser/DefaultObjectCreator.java @@ -30,7 +30,7 @@ public class DefaultObjectCreator implements ObjectCreator { } @Override - public T create(String typename, boolean useCache) { + public T create(String typename, Class expectType, boolean useCache) { AssertUtil.notBlank(typename, "type must not be blank!"); Class type = check(typename); AssertUtil.notNull(type, "typename " + typename + " is not class"); diff --git a/smart-flow-core/src/main/java/org/smartboot/flow/core/parser/DefaultParser.java b/smart-flow-core/src/main/java/org/smartboot/flow/core/parser/DefaultParser.java index f13acfa780f1fe56a0d6724492dcc83c4ad52404..dbdfdf077aeda4171cff5256f5f3cdf5de8d80de 100644 --- a/smart-flow-core/src/main/java/org/smartboot/flow/core/parser/DefaultParser.java +++ b/smart-flow-core/src/main/java/org/smartboot/flow/core/parser/DefaultParser.java @@ -126,7 +126,7 @@ public class DefaultParser implements Parser { public Map> getEngines() { List engineNames = visitor.getEngineNames(); - Map> engines = new HashMap<>(); + Map> engines = new HashMap<>(engineNames.size()); for (String name : engineNames) { engines.put(name, getEngine(name)); } diff --git a/smart-flow-core/src/main/java/org/smartboot/flow/core/parser/ObjectCreator.java b/smart-flow-core/src/main/java/org/smartboot/flow/core/parser/ObjectCreator.java index a2a837b0ad4aef4b5037f1c61aa12d2c5402928e..c2dea2c8c6a04a913ec417e1bbdf2f1b7168dfe6 100644 --- a/smart-flow-core/src/main/java/org/smartboot/flow/core/parser/ObjectCreator.java +++ b/smart-flow-core/src/main/java/org/smartboot/flow/core/parser/ObjectCreator.java @@ -10,9 +10,11 @@ public interface ObjectCreator { /** * Create an instance with specific type. * - * @param type type - * @param useCache useCache - * @return instance. + * @since 1.0.5 + * @param type type + * @param expectType expect java type. + * @param useCache useCache + * @return instance. */ - T create(String type, boolean useCache); + T create(String type, Class expectType, boolean useCache); } diff --git a/smart-flow-core/src/main/java/org/smartboot/flow/core/parser/ParserContext.java b/smart-flow-core/src/main/java/org/smartboot/flow/core/parser/ParserContext.java index d15e1edb46933fa2990af11c1f73dd9bb05cb881..6c219e448a10be705fd146e90417aee5041e276c 100644 --- a/smart-flow-core/src/main/java/org/smartboot/flow/core/parser/ParserContext.java +++ b/smart-flow-core/src/main/java/org/smartboot/flow/core/parser/ParserContext.java @@ -34,7 +34,7 @@ public class ParserContext { */ private final ElementParserRegistry parserRegistry = ElementParserRegistry.getInstance(); - /* Registered Element definitions */ + /** Registered Element definitions */ private final Map registered = new ConcurrentHashMap<>(); private final Map generatedIdentifiers = new ConcurrentHashMap<>(); private IdentifierManager identifierManager = new DefaultIdentifierManager(); diff --git a/smart-flow-core/src/main/java/org/smartboot/flow/core/parser/PipelineEndCallBack.java b/smart-flow-core/src/main/java/org/smartboot/flow/core/parser/PipelineEndCallBack.java deleted file mode 100644 index f663127c11c21ece02f0e8646cf62126f9c31e7e..0000000000000000000000000000000000000000 --- a/smart-flow-core/src/main/java/org/smartboot/flow/core/parser/PipelineEndCallBack.java +++ /dev/null @@ -1,13 +0,0 @@ -package org.smartboot.flow.core.parser; - -import org.smartboot.flow.core.Pipeline; - -/** - * @author qinluo - * @date 2022-11-16 17:19:03 - * @since 1.0.0 - */ -public interface PipelineEndCallBack { - - void execute(Pipeline pipeline); -} diff --git a/smart-flow-core/src/main/java/org/smartboot/flow/core/script/ScriptCondition.java b/smart-flow-core/src/main/java/org/smartboot/flow/core/script/ScriptCondition.java index 8ef1d8b8cb1a1d81d83ad3130c0c87760ddc3e35..f18908ef2bb9a29509cdfd1b42d1980ef6eb2a0e 100644 --- a/smart-flow-core/src/main/java/org/smartboot/flow/core/script/ScriptCondition.java +++ b/smart-flow-core/src/main/java/org/smartboot/flow/core/script/ScriptCondition.java @@ -2,6 +2,9 @@ package org.smartboot.flow.core.script; import org.smartboot.flow.core.EngineContext; import org.smartboot.flow.core.NamedCondition; +import org.smartboot.flow.core.visitor.ConditionVisitor; + +import java.util.Map; /** * @author qinluo @@ -38,11 +41,35 @@ public abstract class ScriptCondition extends NamedCondition { return null; } + /** + * 执行条件表达式 + * + * @param context 当前执行上下文 + * @return 执行结果 + */ @Override public abstract Object test(EngineContext context); + /** + * 允许用户在脚本上下文中绑定自定义的变量,用于执行脚本。 + * 其中key为脚本中用到的变量名,内置变量名参考 {@link org.smartboot.flow.core.script.ScriptConstants} + * + * @since 1.0.5 + * @param context engine ctx. + * @return bound keys. + */ + protected Map bindCustomized(EngineContext context) { + return ScriptVariableManager.getRegistered(context.getEngineName()); + } + @Override public String describe() { return "script-" + getType() + "-" + super.describe(); } + + @Override + public void visit(ConditionVisitor visitor) { + visitor.visitScript(script); + super.visit(visitor); + } } diff --git a/smart-flow-core/src/main/java/org/smartboot/flow/core/script/ScriptConstants.java b/smart-flow-core/src/main/java/org/smartboot/flow/core/script/ScriptConstants.java index 8d20f40c910493e4192090ed48106195143a0a21..01222030e8525d7bd64e0650b6a15e61031ec639 100644 --- a/smart-flow-core/src/main/java/org/smartboot/flow/core/script/ScriptConstants.java +++ b/smart-flow-core/src/main/java/org/smartboot/flow/core/script/ScriptConstants.java @@ -23,4 +23,11 @@ public interface ScriptConstants { * Flow engine execution context. */ String CONTEXT = "context"; + + /** + * Alias for context. + * + * @since 1.0.5 + */ + String CTX = "ctx"; } diff --git a/smart-flow-core/src/main/java/org/smartboot/flow/core/script/ScriptVariableManager.java b/smart-flow-core/src/main/java/org/smartboot/flow/core/script/ScriptVariableManager.java new file mode 100644 index 0000000000000000000000000000000000000000..dc8d62839971000503dcfca32681644888fd3154 --- /dev/null +++ b/smart-flow-core/src/main/java/org/smartboot/flow/core/script/ScriptVariableManager.java @@ -0,0 +1,60 @@ +package org.smartboot.flow.core.script; + +import java.util.HashMap; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; + +/** + *

+ * 1、提供全局脚本变量注册 + * 2、提供基于引擎维度的脚本变量注册 + *

+ * + * @author qinluo + * @date 2023-01-17 19:41 + * @since 1.0.5 + */ +public class ScriptVariableManager { + + /** + * 全局脚本变量注册 + */ + private static final Map GLOBAL = new ConcurrentHashMap<>(); + + /** + * 引擎维度脚本变量注册 + */ + private static final Map> ENGINE_VARIABLES = new ConcurrentHashMap<>(); + + public static void register(String key, Object variable) { + GLOBAL.put(key, variable); + } + + public static Object remove(String key) { + return GLOBAL.remove(key); + } + + public synchronized static void register(String engine, String key, Object variable) { + Map variables = ENGINE_VARIABLES.getOrDefault(engine, new ConcurrentHashMap<>(4)); + variables.put(key, variable); + ENGINE_VARIABLES.put(engine, variables); + } + + public static Object remove(String engine, String key) { + Map variables = ENGINE_VARIABLES.get(engine); + if (variables != null) { + return variables.remove(key); + } + + return null; + } + + public static Map getRegistered(String engine) { + Map allRegistered = new HashMap<>(GLOBAL); + Map variables = ENGINE_VARIABLES.get(engine); + if (variables != null) { + allRegistered.putAll(variables); + } + return allRegistered; + } +} diff --git a/smart-flow-core/src/main/java/org/smartboot/flow/core/trace/Node.java b/smart-flow-core/src/main/java/org/smartboot/flow/core/trace/Node.java index 243deb20c19e273860d94cc80bfa04957dbdf913..031c837d20e872b028a8c3435b5020bc6b46252c 100644 --- a/smart-flow-core/src/main/java/org/smartboot/flow/core/trace/Node.java +++ b/smart-flow-core/src/main/java/org/smartboot/flow/core/trace/Node.java @@ -1,5 +1,7 @@ package org.smartboot.flow.core.trace; +import org.smartboot.flow.core.EngineConstants; + import java.util.ArrayList; import java.util.Comparator; import java.util.List; @@ -119,7 +121,7 @@ public class Node { return "|---"; } - if (prefix.length() == 4) { + if (prefix.length() == EngineConstants.TAB_SIZE) { return (hasNext ? "|" : " ") + " |" + (async ? "~~~" : "---"); } diff --git a/smart-flow-core/src/main/java/org/smartboot/flow/core/util/AuxiliaryUtils.java b/smart-flow-core/src/main/java/org/smartboot/flow/core/util/AuxiliaryUtils.java index ed890c377cd59e2c0864d28992ac148dec42de99..8ba3a4becbb15210de0501b8509e2fd17ab03af0 100644 --- a/smart-flow-core/src/main/java/org/smartboot/flow/core/util/AuxiliaryUtils.java +++ b/smart-flow-core/src/main/java/org/smartboot/flow/core/util/AuxiliaryUtils.java @@ -39,4 +39,21 @@ public final class AuxiliaryUtils { return null; } } + + public static void appendTab(StringBuilder sb, int numbersOfTab) { + for (int i = 0; i < numbersOfTab; i++) { + sb.append("\t"); + } + } + + public static String contact(String p, Object ...s) { + StringBuilder sb = new StringBuilder(); + sb.append(p); + + for (Object suffix : s) { + sb.append("-").append(suffix); + } + + return sb.toString(); + } } diff --git a/smart-flow-core/src/main/java/org/smartboot/flow/core/util/ContactUtils.java b/smart-flow-core/src/main/java/org/smartboot/flow/core/util/ContactUtils.java deleted file mode 100644 index e1979185df85c8fbff103958d3bb14b7e7c023eb..0000000000000000000000000000000000000000 --- a/smart-flow-core/src/main/java/org/smartboot/flow/core/util/ContactUtils.java +++ /dev/null @@ -1,20 +0,0 @@ -package org.smartboot.flow.core.util; - -/** - * @author qinluo - * @date 2022/11/20 22:10 - * @since 1.0.0 - */ -public final class ContactUtils { - - public static String contact(String p, Object ...s) { - StringBuilder sb = new StringBuilder(); - sb.append(p); - - for (Object suffix : s) { - sb.append("-").append(suffix); - } - - return sb.toString(); - } -} diff --git a/smart-flow-core/src/main/java/org/smartboot/flow/core/visitor/ComponentVisitor.java b/smart-flow-core/src/main/java/org/smartboot/flow/core/visitor/ComponentVisitor.java index 77ff49359c894f3f843e39031d3c382c7fb3eb3b..3abce81dc2cecbfede71e0fbf2849a882c245af3 100644 --- a/smart-flow-core/src/main/java/org/smartboot/flow/core/visitor/ComponentVisitor.java +++ b/smart-flow-core/src/main/java/org/smartboot/flow/core/visitor/ComponentVisitor.java @@ -37,10 +37,11 @@ public class ComponentVisitor { } } - public void visitCondition(String condition) { + public ConditionVisitor visitCondition(String condition) { if (delegate != null) { - delegate.visitCondition(condition); + return delegate.visitCondition(condition); } + return null; } /** diff --git a/smart-flow-core/src/main/java/org/smartboot/flow/core/visitor/ConditionVisitor.java b/smart-flow-core/src/main/java/org/smartboot/flow/core/visitor/ConditionVisitor.java new file mode 100644 index 0000000000000000000000000000000000000000..7ba836bc4a7007b27518d08a101b97ed73ce328a --- /dev/null +++ b/smart-flow-core/src/main/java/org/smartboot/flow/core/visitor/ConditionVisitor.java @@ -0,0 +1,39 @@ +package org.smartboot.flow.core.visitor; + +import org.smartboot.flow.core.Condition; + +/** + * @author qinluo + * @date 2022-11-13 22:34:58 + * @since 1.0.5 + */ +public class ConditionVisitor { + + protected ConditionVisitor delegate; + + public ConditionVisitor() { + this(null); + } + + public ConditionVisitor(ConditionVisitor delegate) { + this.delegate = delegate; + } + + /** + * Visit condition source. + */ + public void visitSource(Condition condition) { + if (delegate != null) { + delegate.visitSource(condition); + } + } + + /** + * Visit script. + */ + public void visitScript(String script) { + if (delegate != null) { + delegate.visitScript(script); + } + } +} diff --git a/smart-flow-helper/pom.xml b/smart-flow-helper/pom.xml new file mode 100644 index 0000000000000000000000000000000000000000..c13f06e685677842c4039e487ecbd8e4cac3aff5 --- /dev/null +++ b/smart-flow-helper/pom.xml @@ -0,0 +1,27 @@ + + + + smart-flow-parent + org.smartboot.flow + 1.0.5 + + 4.0.0 + + smart-flow-helper + + + 8 + 8 + + + + + org.smartboot.flow + smart-flow-core + 1.0.5 + + + + \ No newline at end of file diff --git a/smart-flow-helper/src/main/java/org/smartboot/flow/helper/mock/FakeAdapter.java b/smart-flow-helper/src/main/java/org/smartboot/flow/helper/mock/FakeAdapter.java new file mode 100644 index 0000000000000000000000000000000000000000..a127e0bb460d8aa7d4d2c65d6f69b9242f2cb959 --- /dev/null +++ b/smart-flow-helper/src/main/java/org/smartboot/flow/helper/mock/FakeAdapter.java @@ -0,0 +1,36 @@ +package org.smartboot.flow.helper.mock; + +import org.smartboot.flow.core.Adapter; +import org.smartboot.flow.core.EngineContext; +import org.smartboot.flow.core.common.Pair; + +/** + * Fake Class, do-nothing + * + * @author qinluo + * @date 2023/1/27 12:35 + * @since 1.0.0 + */ +public class FakeAdapter implements Adapter { + + private final String type; + + public FakeAdapter(String type) { + this.type = type; + } + + @Override + public Pair before(EngineContext context) { + return Pair.of(context.getReq(), context.getResult()); + } + + @Override + public void after(EngineContext origin, EngineContext newContext) { + + } + + @Override + public String describe() { + return type; + } +} diff --git a/smart-flow-helper/src/main/java/org/smartboot/flow/helper/mock/FakeCondition.java b/smart-flow-helper/src/main/java/org/smartboot/flow/helper/mock/FakeCondition.java new file mode 100644 index 0000000000000000000000000000000000000000..25e0fca320b7d78fcf69e4aec41f0867ad7d0556 --- /dev/null +++ b/smart-flow-helper/src/main/java/org/smartboot/flow/helper/mock/FakeCondition.java @@ -0,0 +1,24 @@ +package org.smartboot.flow.helper.mock; + +import org.smartboot.flow.core.Condition; + +/** + * Fake Class, do-nothing + * + * @author qinluo + * @date 2023/1/27 12:35 + * @since 1.0.0 + */ +public class FakeCondition extends Condition { + + private final String type; + + public FakeCondition(String type) { + this.type = type; + } + + @Override + public String describe() { + return type; + } +} diff --git a/smart-flow-helper/src/main/java/org/smartboot/flow/helper/mock/FakeDegradeCallback.java b/smart-flow-helper/src/main/java/org/smartboot/flow/helper/mock/FakeDegradeCallback.java new file mode 100644 index 0000000000000000000000000000000000000000..ecc23d7eeb6f441e9c97a8c392f71fc0b730245d --- /dev/null +++ b/smart-flow-helper/src/main/java/org/smartboot/flow/helper/mock/FakeDegradeCallback.java @@ -0,0 +1,26 @@ + +package org.smartboot.flow.helper.mock; + +import org.smartboot.flow.core.DegradeCallback; + +/** + * Fake Class, do-nothing + * + * @author qinluo + * @date 2023/1/27 12:35 + * @since 1.0.0 + */ +public class FakeDegradeCallback implements DegradeCallback { + + private final String type; + + public FakeDegradeCallback(String type) { + this.type = type; + } + + + @Override + public String describe() { + return type; + } +} diff --git a/smart-flow-helper/src/main/java/org/smartboot/flow/helper/mock/FakeExecutable.java b/smart-flow-helper/src/main/java/org/smartboot/flow/helper/mock/FakeExecutable.java new file mode 100644 index 0000000000000000000000000000000000000000..2fec968412bc908a398aaf224641eb3267c00802 --- /dev/null +++ b/smart-flow-helper/src/main/java/org/smartboot/flow/helper/mock/FakeExecutable.java @@ -0,0 +1,24 @@ +package org.smartboot.flow.helper.mock; + +import org.smartboot.flow.core.executable.AbstractExecutable; + +/** + * Fake Class, do-nothing + * + * @author qinluo + * @date 2023/1/27 12:35 + * @since 1.0.0 + */ +public class FakeExecutable extends AbstractExecutable { + + private final String type; + + public FakeExecutable(String type) { + this.type = type; + } + + @Override + public String describe() { + return type; + } +} diff --git a/smart-flow-helper/src/main/java/org/smartboot/flow/helper/mock/FakeObjectCreator.java b/smart-flow-helper/src/main/java/org/smartboot/flow/helper/mock/FakeObjectCreator.java new file mode 100644 index 0000000000000000000000000000000000000000..d367eeedf5a9301093e2a031996a288cbc032d95 --- /dev/null +++ b/smart-flow-helper/src/main/java/org/smartboot/flow/helper/mock/FakeObjectCreator.java @@ -0,0 +1,42 @@ +package org.smartboot.flow.helper.mock; + +import org.smartboot.flow.core.Adapter; +import org.smartboot.flow.core.Condition; +import org.smartboot.flow.core.DegradeCallback; +import org.smartboot.flow.core.executable.Executable; +import org.smartboot.flow.core.parser.DefaultObjectCreator; +import org.smartboot.flow.core.parser.ObjectCreator; +import org.smartboot.flow.core.script.ScriptCondition; + +/** + * Fake object creator, Return prepared fake object. + * + * @author qinluo + * @date 2023/1/27 12:20 + * @since 1.0.5 + */ +public class FakeObjectCreator implements ObjectCreator { + + @Override + public T create(String type, Class expectType, boolean useCache) { + // Created by DefaultObjectCreator. + if (expectType == null) { + return DefaultObjectCreator.getInstance().create(type, null, useCache); + } + + if (expectType == Condition.class) { + return (T)new FakeCondition(type); + } else if (expectType == ScriptCondition.class) { + return (T)new FakeScriptCondition(type); + } else if (expectType == Executable.class) { + return (T)new FakeExecutable(type); + } else if (expectType == Adapter.class) { + return (T)new FakeAdapter(type); + } else if (expectType == DegradeCallback.class) { + return (T)new FakeDegradeCallback(type); + } + + // Default Created by DefaultObjectCreator. + return DefaultObjectCreator.getInstance().create(type, expectType, useCache); + } +} diff --git a/smart-flow-helper/src/main/java/org/smartboot/flow/helper/mock/FakeScriptCondition.java b/smart-flow-helper/src/main/java/org/smartboot/flow/helper/mock/FakeScriptCondition.java new file mode 100644 index 0000000000000000000000000000000000000000..8eb10455991706aa49b123e67afe05e5d97634e8 --- /dev/null +++ b/smart-flow-helper/src/main/java/org/smartboot/flow/helper/mock/FakeScriptCondition.java @@ -0,0 +1,36 @@ +package org.smartboot.flow.helper.mock; + +import org.smartboot.flow.core.EngineContext; +import org.smartboot.flow.core.script.ScriptCondition; + +/** + * Fake Class, do-nothing + * + * @author qinluo + * @date 2023/1/27 12:35 + * @since 1.0.0 + */ +public class FakeScriptCondition extends ScriptCondition { + + private final String type; + + public FakeScriptCondition(String type) { + this.type = type; + } + + @Override + public String getType() { + return type; + } + + @Override + public Object test(EngineContext context) { + // do-noting + return null; + } + + @Override + public String describe() { + return type; + } +} diff --git a/smart-flow-core/src/main/java/org/smartboot/flow/core/useful/AbstractEngineQuery.java b/smart-flow-helper/src/main/java/org/smartboot/flow/helper/useful/AbstractEngineQuery.java similarity index 90% rename from smart-flow-core/src/main/java/org/smartboot/flow/core/useful/AbstractEngineQuery.java rename to smart-flow-helper/src/main/java/org/smartboot/flow/helper/useful/AbstractEngineQuery.java index b7bdbd6b4132887c84912b50f04b1df49ce44957..bbf164599e4f38882cbb6ad37dab34074dae3c1c 100644 --- a/smart-flow-core/src/main/java/org/smartboot/flow/core/useful/AbstractEngineQuery.java +++ b/smart-flow-helper/src/main/java/org/smartboot/flow/helper/useful/AbstractEngineQuery.java @@ -1,4 +1,4 @@ -package org.smartboot.flow.core.useful; +package org.smartboot.flow.helper.useful; import java.io.Serializable; diff --git a/smart-flow-core/src/main/java/org/smartboot/flow/core/useful/AbstractExecutorSelector.java b/smart-flow-helper/src/main/java/org/smartboot/flow/helper/useful/AbstractExecutorSelector.java similarity index 96% rename from smart-flow-core/src/main/java/org/smartboot/flow/core/useful/AbstractExecutorSelector.java rename to smart-flow-helper/src/main/java/org/smartboot/flow/helper/useful/AbstractExecutorSelector.java index eae0904a7e5edd8149d22c2f72cb033da7b81269..857824e4e1eda7a060114cb8393b74e8569438f9 100644 --- a/smart-flow-core/src/main/java/org/smartboot/flow/core/useful/AbstractExecutorSelector.java +++ b/smart-flow-helper/src/main/java/org/smartboot/flow/helper/useful/AbstractExecutorSelector.java @@ -1,4 +1,4 @@ -package org.smartboot.flow.core.useful; +package org.smartboot.flow.helper.useful; import org.smartboot.flow.core.FlowEngine; diff --git a/smart-flow-core/src/main/java/org/smartboot/flow/core/useful/DefaultEngineQuery.java b/smart-flow-helper/src/main/java/org/smartboot/flow/helper/useful/DefaultEngineQuery.java similarity index 91% rename from smart-flow-core/src/main/java/org/smartboot/flow/core/useful/DefaultEngineQuery.java rename to smart-flow-helper/src/main/java/org/smartboot/flow/helper/useful/DefaultEngineQuery.java index 4c9cca2eb1fc84e420e4febc16d4c18905613884..9e382e1138dbd4c48a58b1624446a343dd4f9db3 100644 --- a/smart-flow-core/src/main/java/org/smartboot/flow/core/useful/DefaultEngineQuery.java +++ b/smart-flow-helper/src/main/java/org/smartboot/flow/helper/useful/DefaultEngineQuery.java @@ -1,4 +1,4 @@ -package org.smartboot.flow.core.useful; +package org.smartboot.flow.helper.useful; /** * 通过engineName查询engine diff --git a/smart-flow-core/src/main/java/org/smartboot/flow/core/useful/DefaultExecutorSelector.java b/smart-flow-helper/src/main/java/org/smartboot/flow/helper/useful/DefaultExecutorSelector.java similarity index 93% rename from smart-flow-core/src/main/java/org/smartboot/flow/core/useful/DefaultExecutorSelector.java rename to smart-flow-helper/src/main/java/org/smartboot/flow/helper/useful/DefaultExecutorSelector.java index db681dcaf21de1991ed00357f59f6b8fd7dfa0cb..0b1c2e231edd261af26cd3453e3b6f696b158ba1 100644 --- a/smart-flow-core/src/main/java/org/smartboot/flow/core/useful/DefaultExecutorSelector.java +++ b/smart-flow-helper/src/main/java/org/smartboot/flow/helper/useful/DefaultExecutorSelector.java @@ -1,4 +1,4 @@ -package org.smartboot.flow.core.useful; +package org.smartboot.flow.helper.useful; import org.smartboot.flow.core.FlowEngine; diff --git a/smart-flow-core/src/main/java/org/smartboot/flow/core/useful/EngineExecutorManager.java b/smart-flow-helper/src/main/java/org/smartboot/flow/helper/useful/EngineExecutorManager.java similarity index 98% rename from smart-flow-core/src/main/java/org/smartboot/flow/core/useful/EngineExecutorManager.java rename to smart-flow-helper/src/main/java/org/smartboot/flow/helper/useful/EngineExecutorManager.java index 4a269340399e28046c54c5b063be5297ea061c7e..4ee6b0b4c0c7bc8b4b300b5e1a7200d92cb2ac53 100644 --- a/smart-flow-core/src/main/java/org/smartboot/flow/core/useful/EngineExecutorManager.java +++ b/smart-flow-helper/src/main/java/org/smartboot/flow/helper/useful/EngineExecutorManager.java @@ -1,4 +1,4 @@ -package org.smartboot.flow.core.useful; +package org.smartboot.flow.helper.useful; diff --git a/smart-flow-core/src/main/java/org/smartboot/flow/core/useful/ExecutorSelector.java b/smart-flow-helper/src/main/java/org/smartboot/flow/helper/useful/ExecutorSelector.java similarity index 92% rename from smart-flow-core/src/main/java/org/smartboot/flow/core/useful/ExecutorSelector.java rename to smart-flow-helper/src/main/java/org/smartboot/flow/helper/useful/ExecutorSelector.java index 7236ff8de4ac966db48c9ede832dde13341af847..7415f400084bf3046dd50211069893d3fb88c67a 100644 --- a/smart-flow-core/src/main/java/org/smartboot/flow/core/useful/ExecutorSelector.java +++ b/smart-flow-helper/src/main/java/org/smartboot/flow/helper/useful/ExecutorSelector.java @@ -1,4 +1,4 @@ -package org.smartboot.flow.core.useful; +package org.smartboot.flow.helper.useful; import org.smartboot.flow.core.FlowEngine; diff --git a/smart-flow-core/src/main/java/org/smartboot/flow/core/view/plantuml/Color.java b/smart-flow-helper/src/main/java/org/smartboot/flow/helper/view/Color.java similarity index 94% rename from smart-flow-core/src/main/java/org/smartboot/flow/core/view/plantuml/Color.java rename to smart-flow-helper/src/main/java/org/smartboot/flow/helper/view/Color.java index f028cf5967ab6c4cbcc6aa419697782c3031e884..22b728573c9f24eec5f8add6e877ffbbba87dea0 100644 --- a/smart-flow-core/src/main/java/org/smartboot/flow/core/view/plantuml/Color.java +++ b/smart-flow-helper/src/main/java/org/smartboot/flow/helper/view/Color.java @@ -1,4 +1,4 @@ -package org.smartboot.flow.core.view.plantuml; +package org.smartboot.flow.helper.view; /** * @author qinluo diff --git a/smart-flow-core/src/main/java/org/smartboot/flow/core/view/plantuml/PlantumlComponent.java b/smart-flow-helper/src/main/java/org/smartboot/flow/helper/view/PlantumlComponent.java similarity index 97% rename from smart-flow-core/src/main/java/org/smartboot/flow/core/view/plantuml/PlantumlComponent.java rename to smart-flow-helper/src/main/java/org/smartboot/flow/helper/view/PlantumlComponent.java index cc81ab4f09bfcc55add81f0565d2a137dae6d06b..1e2c069f1b1ffa8fc49ab224de863c612c564a86 100644 --- a/smart-flow-core/src/main/java/org/smartboot/flow/core/view/plantuml/PlantumlComponent.java +++ b/smart-flow-helper/src/main/java/org/smartboot/flow/helper/view/PlantumlComponent.java @@ -1,10 +1,11 @@ -package org.smartboot.flow.core.view.plantuml; +package org.smartboot.flow.helper.view; import org.smartboot.flow.core.common.ComponentType; import org.smartboot.flow.core.attribute.AttributeHolder; import org.smartboot.flow.core.attribute.Attributes; import org.smartboot.flow.core.util.AuxiliaryUtils; import org.smartboot.flow.core.visitor.ComponentVisitor; +import org.smartboot.flow.core.visitor.ConditionVisitor; import org.smartboot.flow.core.visitor.PipelineVisitor; import java.util.ArrayList; @@ -20,9 +21,7 @@ public class PlantumlComponent extends ComponentVisitor { private final List attributes = new ArrayList<>(); private final String name; private final String describe; - // basic, if, choose, pipeline; private final ComponentType type; - // Used with type pipeline. private PlantumlPipeline pipeline; private String condition; private String branch; @@ -47,8 +46,9 @@ public class PlantumlComponent extends ComponentVisitor { } @Override - public void visitCondition(String condition) { + public ConditionVisitor visitCondition(String condition) { this.condition = condition; + return null; } @Override @@ -93,7 +93,7 @@ public class PlantumlComponent extends ComponentVisitor { } content.append("if (").append(condition).append(") then (true)\n"); components.get(0).generate(content); - if (components.size() >= 2) { + if (components.size() > 1) { content.append("else (false)\n"); components.get(1).generate(content); } diff --git a/smart-flow-core/src/main/java/org/smartboot/flow/core/view/plantuml/PlantumlEngineVisitor.java b/smart-flow-helper/src/main/java/org/smartboot/flow/helper/view/PlantumlEngineVisitor.java similarity index 97% rename from smart-flow-core/src/main/java/org/smartboot/flow/core/view/plantuml/PlantumlEngineVisitor.java rename to smart-flow-helper/src/main/java/org/smartboot/flow/helper/view/PlantumlEngineVisitor.java index 5413c8a87696202038c30f4aeb07819b408198be..ebb55e1323694767f8af230c7e0d00a77b537fc8 100644 --- a/smart-flow-core/src/main/java/org/smartboot/flow/core/view/plantuml/PlantumlEngineVisitor.java +++ b/smart-flow-helper/src/main/java/org/smartboot/flow/helper/view/PlantumlEngineVisitor.java @@ -1,4 +1,4 @@ -package org.smartboot.flow.core.view.plantuml; +package org.smartboot.flow.helper.view; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -27,7 +27,7 @@ public class PlantumlEngineVisitor extends EngineVisitor { private static final String END = "@enduml"; private static final String SUFFIX = ".puml"; - // plantuml file dest. + /** plantuml file dest. */ private final String dest; /** * engine name. diff --git a/smart-flow-core/src/main/java/org/smartboot/flow/core/view/plantuml/PlantumlPipeline.java b/smart-flow-helper/src/main/java/org/smartboot/flow/helper/view/PlantumlPipeline.java similarity index 97% rename from smart-flow-core/src/main/java/org/smartboot/flow/core/view/plantuml/PlantumlPipeline.java rename to smart-flow-helper/src/main/java/org/smartboot/flow/helper/view/PlantumlPipeline.java index 76dced6d22e868299ba2788b58f5d9a06bc44369..193cf8bad5bec6d1deaa98197c5e57fa56154d6d 100644 --- a/smart-flow-core/src/main/java/org/smartboot/flow/core/view/plantuml/PlantumlPipeline.java +++ b/smart-flow-helper/src/main/java/org/smartboot/flow/helper/view/PlantumlPipeline.java @@ -1,4 +1,4 @@ -package org.smartboot.flow.core.view.plantuml; +package org.smartboot.flow.helper.view; import org.smartboot.flow.core.Pipeline; import org.smartboot.flow.core.common.ComponentType; diff --git a/smart-flow-helper/src/main/java/org/smartboot/flow/helper/view/ScriptCollector.java b/smart-flow-helper/src/main/java/org/smartboot/flow/helper/view/ScriptCollector.java new file mode 100644 index 0000000000000000000000000000000000000000..501a045edbfc21f08422c0140b37495e177fde63 --- /dev/null +++ b/smart-flow-helper/src/main/java/org/smartboot/flow/helper/view/ScriptCollector.java @@ -0,0 +1,38 @@ +package org.smartboot.flow.helper.view; + +import java.util.HashMap; +import java.util.Map; + +/** + * Collect scripts in engine. + * + * @author qinluo + * @date 2023-01-29 10:47:46 + * @since 1.0.5 + */ +public class ScriptCollector { + + private static final ThreadLocal HOLDER = new ThreadLocal<>(); + private final Map scripts = new HashMap<>(); + + public static void start() { + HOLDER.set(new ScriptCollector()); + } + + public static void collect(String condition, String script) { + ScriptCollector collector = HOLDER.get(); + if (collector != null) { + collector.scripts.put(condition, script); + } + } + + public static Map end() { + ScriptCollector collector = HOLDER.get(); + if (collector != null) { + HOLDER.remove(); + return collector.scripts; + } + + return null; + } +} diff --git a/smart-flow-helper/src/main/java/org/smartboot/flow/helper/view/XmlComponentVisitor.java b/smart-flow-helper/src/main/java/org/smartboot/flow/helper/view/XmlComponentVisitor.java new file mode 100644 index 0000000000000000000000000000000000000000..9d1d4af9e2d3c2364b719c94c6ad98b4e364226f --- /dev/null +++ b/smart-flow-helper/src/main/java/org/smartboot/flow/helper/view/XmlComponentVisitor.java @@ -0,0 +1,169 @@ +package org.smartboot.flow.helper.view; + +import org.smartboot.flow.core.attribute.AttributeHolder; +import org.smartboot.flow.core.common.ComponentType; +import org.smartboot.flow.core.util.AuxiliaryUtils; +import org.smartboot.flow.core.visitor.ComponentVisitor; +import org.smartboot.flow.core.visitor.ConditionVisitor; +import org.smartboot.flow.core.visitor.PipelineVisitor; + +import java.util.ArrayList; +import java.util.List; +import java.util.Set; + +/** + * @author yamikaze + * @date 2022/11/14 + * @since 1.0.5 + */ +public class XmlComponentVisitor extends ComponentVisitor { + + private final List attributes = new ArrayList<>(); + private final ComponentType type; + private XmlPipelineVisitor pipeline; + private String condition; + private String branch; + private final List components = new ArrayList<>(); + /** + * 记录访问过的对象 + */ + private final Set visited; + private String executable; + private String script; + + public XmlComponentVisitor(ComponentType type, String name, String describe, Set visited) { + this.type = type; + this.visited = visited; + } + + @Override + public void visitExecutable(String executable) { + this.executable = executable; + } + + @Override + public PipelineVisitor visitPipeline(String pipeline) { + this.pipeline = new XmlPipelineVisitor(pipeline, visited); + return this.pipeline; + } + + @Override + public ConditionVisitor visitCondition(String condition) { + this.condition = condition; + return new XmlConditionVisitor(); + } + + @Override + public ComponentVisitor visitComponent(ComponentType type, String name, String describe) { + XmlComponentVisitor component = new XmlComponentVisitor(type, name, describe, visited); + this.components.add(component); + return component; + } + + @Override + public void visitAttributes(List attributes) { + this.attributes.addAll(attributes); + } + + @Override + public ComponentVisitor visitBranch(Object branch, ComponentType type, String name, String describe) { + XmlComponentVisitor component = new XmlComponentVisitor(type, name, describe, visited); + component.branch = (String.valueOf(branch)); + this.components.add(component); + return component; + } + + private void appendAttributes(StringBuilder content) { + for (AttributeHolder ah : attributes) { + content.append(ah.getAttribute().getName()).append("=\"").append(ah.getValue().toString()).append("\" "); + } + } + + public void generate(StringBuilder content, int numbersOfTab) { + ComponentType type = this.type; + + if (script != null) { + ScriptCollector.collect(condition, script); + } + + if (type == ComponentType.BASIC) { + AuxiliaryUtils.appendTab(content, numbersOfTab); + content.append("\n"); + } else if (type == ComponentType.IF) { + AuxiliaryUtils.appendTab(content, numbersOfTab); + content.append("\n"); + + AuxiliaryUtils.appendTab(content, numbersOfTab + 1); + content.append("\n"); + components.get(0).generate(content, numbersOfTab + 2); + AuxiliaryUtils.appendTab(content, numbersOfTab + 1); + content.append("\n"); + + if (components.size() > 1) { + AuxiliaryUtils.appendTab(content, numbersOfTab + 1); + content.append("\n"); + components.get(1).generate(content, numbersOfTab + 2); + AuxiliaryUtils.appendTab(content, numbersOfTab + 1); + content.append("\n"); + } + AuxiliaryUtils.appendTab(content, numbersOfTab); + content.append("\n"); + } else if (type == ComponentType.CHOOSE) { + AuxiliaryUtils.appendTab(content, numbersOfTab); + content.append("\n"); + + for (XmlComponentVisitor component : components) { + if (component.branch != null) { + AuxiliaryUtils.appendTab(content, numbersOfTab + 1); + content.append("\n"); + component.generate(content, numbersOfTab + 2); + AuxiliaryUtils.appendTab(content, numbersOfTab + 1); + content.append("\n"); + } else { + AuxiliaryUtils.appendTab(content, numbersOfTab + 1); + content.append("\n"); + component.generate(content, numbersOfTab + 2); + AuxiliaryUtils.appendTab(content, numbersOfTab + 1); + content.append("\n"); + } + } + AuxiliaryUtils.appendTab(content, numbersOfTab); + content.append("\n"); + + } else if (type == ComponentType.PIPELINE) { + if (pipeline.isCycle()) { + AuxiliaryUtils.appendTab(content, numbersOfTab); + content.append("\n"); + return; + } + + pipeline.generate(content, numbersOfTab); + } else if (type == ComponentType.ADAPTER) { + AuxiliaryUtils.appendTab(content, numbersOfTab); + content.append("\n"); + XmlComponentVisitor pipeline = components.get(0); + pipeline.pipeline.generate(content, numbersOfTab + 1); + AuxiliaryUtils.appendTab(content, numbersOfTab); + content.append("\n"); + } + } + + private class XmlConditionVisitor extends ConditionVisitor { + + @Override + public void visitScript(String script) { + XmlComponentVisitor.this.script = script; + } + } +} diff --git a/smart-flow-helper/src/main/java/org/smartboot/flow/helper/view/XmlEngineVisitor.java b/smart-flow-helper/src/main/java/org/smartboot/flow/helper/view/XmlEngineVisitor.java new file mode 100644 index 0000000000000000000000000000000000000000..b91be98c96cb2dc7452f27c160b017dede4ce1d9 --- /dev/null +++ b/smart-flow-helper/src/main/java/org/smartboot/flow/helper/view/XmlEngineVisitor.java @@ -0,0 +1,86 @@ +package org.smartboot.flow.helper.view; + +import org.smartboot.flow.core.FlowEngine; +import org.smartboot.flow.core.visitor.EngineVisitor; +import org.smartboot.flow.core.visitor.PipelineVisitor; + +import java.util.HashSet; +import java.util.Map; +import java.util.Set; +import java.util.concurrent.Executor; + +/** + * @author qinluo + * @date 2022-11-14 19:48:14 + * @since 1.0.5 + */ +public class XmlEngineVisitor extends EngineVisitor { + + private static final String START = "\n\n" + + ""; + + private static final String END = ""; + + /** + * engine name. + */ + private String name; + private XmlPipelineVisitor pipeline; + + /** + * Xml content. + */ + private String content; + + /** + * 记录访问过的对象 + */ + private final Set visited = new HashSet<>(); + + public String getContent() { + return content; + } + + public void visit(FlowEngine engine) { + engine.visit(this); + } + + @Override + public void visitEnd() { + ScriptCollector.start(); + + StringBuilder content = new StringBuilder(); + content.append(START).append("\n"); + // + content.append("\t\n"); + + // Pipeline + this.pipeline.generate(content, 1); + + Map scripts = ScriptCollector.end(); + if (scripts != null && scripts.size() > 0) { + scripts.forEach((k, v) -> { + content.append("\n\t"); + }); + } + + content.append("\n").append(END).append("\n"); + + this.content = content.toString(); + } + + @Override + public void visit(String engine, Executor executor) { + this.name = engine; + } + + @Override + public PipelineVisitor visitPipeline(String pipeline) { + this.pipeline = new XmlPipelineVisitor(pipeline, visited); + return this.pipeline; + } +} diff --git a/smart-flow-helper/src/main/java/org/smartboot/flow/helper/view/XmlPipelineVisitor.java b/smart-flow-helper/src/main/java/org/smartboot/flow/helper/view/XmlPipelineVisitor.java new file mode 100644 index 0000000000000000000000000000000000000000..c44021ae2c1cb2dd08f2dbf00d3a967548187e03 --- /dev/null +++ b/smart-flow-helper/src/main/java/org/smartboot/flow/helper/view/XmlPipelineVisitor.java @@ -0,0 +1,78 @@ +package org.smartboot.flow.helper.view; + +import org.smartboot.flow.core.EngineConstants; +import org.smartboot.flow.core.Pipeline; +import org.smartboot.flow.core.common.ComponentType; +import org.smartboot.flow.core.util.AuxiliaryUtils; +import org.smartboot.flow.core.visitor.ComponentVisitor; +import org.smartboot.flow.core.visitor.PipelineVisitor; + +import java.util.ArrayList; +import java.util.List; +import java.util.Set; + +/** + * @author yamikaze + * @date 2022/11/14 + * @since 1.0.5 + */ +public class XmlPipelineVisitor extends PipelineVisitor { + + private final String name; + private final List components = new ArrayList<>(); + /** + * 记录访问过的对象 + */ + private final Set visited; + private boolean cycle; + + public String getName() { + return name; + } + + public boolean isCycle() { + return cycle; + } + + public XmlPipelineVisitor(String name, Set visited) { + this.name = name; + this.visited = visited; + } + + @Override + public void visitSource(Pipeline pipeline) { + this.cycle = !visited.add(pipeline); + } + + @Override + public ComponentVisitor visitComponent(ComponentType type, String name, String describe) { + if (this.isCycle()) { + return null; + } + + XmlComponentVisitor component = new XmlComponentVisitor(type, name, describe, visited); + this.components.add(component); + return component; + } + + public void generate(StringBuilder content, int numbersOfTab) { + // for anonymous-pipeline + boolean incrementTab = false; + // + if (name != null && !name.contains(EngineConstants.ANONYMOUS_PREFIX)) { + incrementTab = true; + AuxiliaryUtils.appendTab(content, numbersOfTab); + content.append("\n"); + } + + for (XmlComponentVisitor component : components) { + component.generate(content, incrementTab ? numbersOfTab + 1 : numbersOfTab); + } + + if (name != null && !name.contains(EngineConstants.ANONYMOUS_PREFIX)) { + AuxiliaryUtils.appendTab(content, numbersOfTab); + content.append("\n"); + } + + } +} diff --git a/smart-flow-manager/pom.xml b/smart-flow-manager/pom.xml index 307564ea5ef8e1dadc0bfc5c5a105b8bc0da87b9..a46b1c052012cba3bbac0de74a5714e4def0fc33 100644 --- a/smart-flow-manager/pom.xml +++ b/smart-flow-manager/pom.xml @@ -5,7 +5,7 @@ smart-flow-parent org.smartboot.flow - 1.0.4 + 1.0.5 4.0.0 @@ -20,14 +20,13 @@ org.smartboot.flow smart-flow-core - 1.0.4 + 1.0.5 org.smartboot.flow - smart-flow-spring-extension - 1.0.4 - true + smart-flow-helper + 1.0.5 @@ -39,7 +38,7 @@ com.alibaba fastjson - 2.0.20.graal + 2.0.22 diff --git a/smart-flow-manager/src/main/java/org/smartboot/flow/manager/ManagerConstants.java b/smart-flow-manager/src/main/java/org/smartboot/flow/manager/ManagerConstants.java new file mode 100644 index 0000000000000000000000000000000000000000..7bed422d724c8ca61d0d0d4e21c4725ca9fb29b4 --- /dev/null +++ b/smart-flow-manager/src/main/java/org/smartboot/flow/manager/ManagerConstants.java @@ -0,0 +1,14 @@ +package org.smartboot.flow.manager; + +/** + * @author qinluo + * @date 2023/2/1 21:56 + * @since 1.0.0 + */ +public interface ManagerConstants { + + /** + * Http success code. + */ + int SUCCESS = 200; +} diff --git a/smart-flow-manager/src/main/java/org/smartboot/flow/manager/ManagerExecutionListener.java b/smart-flow-manager/src/main/java/org/smartboot/flow/manager/ManagerExecutionListener.java new file mode 100644 index 0000000000000000000000000000000000000000..eb496b41305d0d8eaf75082177011d560d8ad44b --- /dev/null +++ b/smart-flow-manager/src/main/java/org/smartboot/flow/manager/ManagerExecutionListener.java @@ -0,0 +1,31 @@ +package org.smartboot.flow.manager; + +import org.smartboot.flow.core.EngineContext; +import org.smartboot.flow.core.ExecutionListenerSupport; + +/** + * 由管理模块进行Listener的注册 + * + * @author qinluo + * @date 2023/1/30 22:42 + * @since 1.0.0 + */ +public class ManagerExecutionListener extends ExecutionListenerSupport { + + @Override + public void start(EngineContext context) { + TraceIdGenerator generator = TraceIdGenerator.getTraceIdGenerator(); + if (generator != null) { + context.putExt(ManagerKeys.TRACE_ID, generator.getTraceId(context)); + } + + // 暂时init个object + context.putExt(ManagerKeys.TRACES, new Object()); + + } + + @Override + public void completed(EngineContext context) { + // 将执行采集到的数据进行上报 + } +} diff --git a/smart-flow-manager/src/main/java/org/smartboot/flow/manager/ManagerKeys.java b/smart-flow-manager/src/main/java/org/smartboot/flow/manager/ManagerKeys.java new file mode 100644 index 0000000000000000000000000000000000000000..c36e68965cfd5d11b4b1aa9f24bcb9c91c5484a6 --- /dev/null +++ b/smart-flow-manager/src/main/java/org/smartboot/flow/manager/ManagerKeys.java @@ -0,0 +1,24 @@ +package org.smartboot.flow.manager; + +import org.smartboot.flow.core.Key; + +/** + * @author qinluo + * @date 2023/1/30 22:43 + * @since 1.0.0 + */ +public interface ManagerKeys { + + /** + * TraceId key in engine ctx. + */ + Key TRACE_ID = Key.of("traceId"); + + /** + * Invoke trace in engine invoking. + * + */ + Key TRACES = Key.of("traces"); + + +} diff --git a/smart-flow-manager/src/main/java/org/smartboot/flow/manager/TraceIdGenerator.java b/smart-flow-manager/src/main/java/org/smartboot/flow/manager/TraceIdGenerator.java new file mode 100644 index 0000000000000000000000000000000000000000..054e1d5bf23e49dfb07714b07d2921676ddd0ad0 --- /dev/null +++ b/smart-flow-manager/src/main/java/org/smartboot/flow/manager/TraceIdGenerator.java @@ -0,0 +1,28 @@ +package org.smartboot.flow.manager; + +import org.smartboot.flow.core.EngineContext; + +import java.util.UUID; + +/** + * @author qinluo + * @date 2023/1/30 22:37 + * @since 1.0.0 + */ +public class TraceIdGenerator { + + private static TraceIdGenerator traceIdGenerator = new TraceIdGenerator(); + + public String getTraceId(EngineContext ctx) { + // 默认UUID实现 + return UUID.randomUUID().toString().replace("-", ""); + } + + public static TraceIdGenerator getTraceIdGenerator() { + return traceIdGenerator; + } + + public static void setTraceIdGenerator(TraceIdGenerator generator) { + traceIdGenerator = generator; + } +} diff --git a/smart-flow-manager/src/main/java/org/smartboot/flow/manager/change/HttpManager.java b/smart-flow-manager/src/main/java/org/smartboot/flow/manager/change/HttpManager.java index 609fbf997cab645894e25a219d9346bb7f57c568..7b3b5cb1611cd8e4c34047c120adf9d6586da429 100644 --- a/smart-flow-manager/src/main/java/org/smartboot/flow/manager/change/HttpManager.java +++ b/smart-flow-manager/src/main/java/org/smartboot/flow/manager/change/HttpManager.java @@ -7,6 +7,7 @@ import org.smartboot.flow.core.attribute.AttributeHolder; import org.smartboot.flow.core.attribute.Attributes; import org.smartboot.flow.core.manager.DefaultEngineManager; import org.smartboot.flow.core.util.AssertUtil; +import org.smartboot.flow.manager.ManagerConstants; import org.smartboot.flow.manager.NamedThreadFactory; import org.smartboot.flow.manager.reload.Reloader; import org.smartboot.flow.manager.report.HostUtils; @@ -93,7 +94,7 @@ public class HttpManager { post.bodyStream().write(bytes, 0, bytes.length); post.bodyStream().flush(); post.onSuccess(httpResponse -> { - if (httpResponse.getStatus() != 200) { + if (httpResponse.getStatus() != ManagerConstants.SUCCESS) { LOGGER.info("request remote address failed {}, code = {}", url, httpResponse.getStatus()); return; } diff --git a/smart-flow-manager/src/main/java/org/smartboot/flow/manager/reload/ReloadListener.java b/smart-flow-manager/src/main/java/org/smartboot/flow/manager/reload/ReloadListener.java index e41ada274f6d5a400812c93e7ea9d17bd31c536f..65882991d65b6908556df8f4e798ea306e73ebed 100644 --- a/smart-flow-manager/src/main/java/org/smartboot/flow/manager/reload/ReloadListener.java +++ b/smart-flow-manager/src/main/java/org/smartboot/flow/manager/reload/ReloadListener.java @@ -7,8 +7,21 @@ package org.smartboot.flow.manager.reload; */ public interface ReloadListener { - void onload(String engineName); + /** + * 引擎reload开始通知 + * + * @param engineName 引擎名称 + */ + default void onload(String engineName) { + + } + /** + * 引擎reload完成通知 + * + * @param engineName 引擎名称 + * @param e 异常信息,若成功,则为null + */ void loadCompleted(String engineName, Throwable e); /** diff --git a/smart-flow-manager/src/main/java/org/smartboot/flow/manager/reload/SqlXmlSelector.java b/smart-flow-manager/src/main/java/org/smartboot/flow/manager/reload/SqlXmlSelector.java index ca3f44b51319ab2a7aad1baeb3674a5105627357..2d30d12c36e95b2ddba6ad0a240ea9ae50ab10b3 100644 --- a/smart-flow-manager/src/main/java/org/smartboot/flow/manager/reload/SqlXmlSelector.java +++ b/smart-flow-manager/src/main/java/org/smartboot/flow/manager/reload/SqlXmlSelector.java @@ -19,7 +19,7 @@ public class SqlXmlSelector implements XmlSelector { /** * classpath*:/resources/init.sql */ - private final static String SELECT_SQL = "select content from engine_table where engine_name = ? limit 1"; + private final static String SELECT_SQL = "select content from engine_table where engine_name = ? and status = 0 limit 1"; private String url; private String username; private String password; diff --git a/smart-flow-manager/src/main/resources/init.sql b/smart-flow-manager/src/main/resources/init.sql deleted file mode 100644 index 5cba42cfea1d60d2aa0e681984ba1523da93f7a2..0000000000000000000000000000000000000000 --- a/smart-flow-manager/src/main/resources/init.sql +++ /dev/null @@ -1,8 +0,0 @@ -CREATE TABLE `engine_table` ( - `id` bigint NOT NULL AUTO_INCREMENT, - `engine_name` varchar(256) NOT NULL COMMENT '引擎名称,唯一', - `content` text COMMENT '引擎配置内容,必须是xml形式', - `status` int NOT NULL DEFAULT '0' COMMENT '状态 0-正常 1-删除', - PRIMARY KEY (`id`), - UNIQUE KEY `engine_table_engine_name_uindex` (`engine_name`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci COMMENT='引擎配置表' \ No newline at end of file diff --git a/smart-flow-script-condition/pom.xml b/smart-flow-script-condition/pom.xml index 210a90a924d77f73748f6169436097876940eba5..61a52f255c08f672979ec89da01e5b15281c9428 100644 --- a/smart-flow-script-condition/pom.xml +++ b/smart-flow-script-condition/pom.xml @@ -5,7 +5,7 @@ smart-flow-parent org.smartboot.flow - 1.0.4 + 1.0.5 4.0.0 pom @@ -27,7 +27,7 @@ org.smartboot.flow smart-flow-core - 1.0.4 + 1.0.5 diff --git a/smart-flow-script-condition/smart-flow-script-groovy/pom.xml b/smart-flow-script-condition/smart-flow-script-groovy/pom.xml index 572064d0e7d5430add8d27215814c0609745ab2c..28e2a8686ef203c0346e76afe323e43aaff6588e 100644 --- a/smart-flow-script-condition/smart-flow-script-groovy/pom.xml +++ b/smart-flow-script-condition/smart-flow-script-groovy/pom.xml @@ -5,7 +5,7 @@ smart-flow-script-condition org.smartboot.flow - 1.0.4 + 1.0.5 4.0.0 diff --git a/smart-flow-script-condition/smart-flow-script-groovy/src/main/java/org/smartboot/flow/condition/extension/groovy/GroovyScriptCondition.java b/smart-flow-script-condition/smart-flow-script-groovy/src/main/java/org/smartboot/flow/condition/extension/groovy/GroovyScriptCondition.java index b464d08727e097412b804c6dd84d7395fae7815a..cf3967cb077e7556ed0ecb462f8285c08c5dc04f 100644 --- a/smart-flow-script-condition/smart-flow-script-groovy/src/main/java/org/smartboot/flow/condition/extension/groovy/GroovyScriptCondition.java +++ b/smart-flow-script-condition/smart-flow-script-groovy/src/main/java/org/smartboot/flow/condition/extension/groovy/GroovyScriptCondition.java @@ -10,6 +10,7 @@ import org.smartboot.flow.core.script.ScriptConstants; import javax.script.Bindings; import javax.script.ScriptEngine; import javax.script.ScriptEngineManager; +import java.util.Map; /** * @author qinluo @@ -19,7 +20,7 @@ import javax.script.ScriptEngineManager; public class GroovyScriptCondition extends ScriptCondition { private static final Logger LOGGER = LoggerFactory.getLogger(GroovyScriptCondition.class); - private static final ScriptEngineManager engineManager = new ScriptEngineManager(); + private static final ScriptEngineManager MANAGER = new ScriptEngineManager(); protected String getScriptLang() { return "groovy"; @@ -28,11 +29,17 @@ public class GroovyScriptCondition extends ScriptCondition { @Override public Object test(EngineContext engineContext) { try { - ScriptEngine engine = engineManager.getEngineByName(getScriptLang()); + ScriptEngine engine = MANAGER.getEngineByName(getScriptLang()); Bindings data = engine.createBindings(); data.put(ScriptConstants.REQ, engineContext.getReq()); data.put(ScriptConstants.RESULT, engineContext.getResult()); data.put(ScriptConstants.CONTEXT, engineContext); + data.put(ScriptConstants.CTX, engineContext); + + Map variables = super.bindCustomized(engineContext); + if (variables != null) { + data.putAll(variables); + } Object value = engine.eval(script, data); if (LOGGER.isDebugEnabled()) { diff --git a/smart-flow-script-condition/smart-flow-script-groovy/src/main/java/org/smartboot/flow/condition/extension/groovy/JavaScriptCondition.java b/smart-flow-script-condition/smart-flow-script-groovy/src/main/java/org/smartboot/flow/condition/extension/groovy/JavaScriptCondition.java index e8dfccd0265454823a93cc7d0931f1d7baba8809..a21e89be6226f42086d7f26b9f5298feb86a789d 100644 --- a/smart-flow-script-condition/smart-flow-script-groovy/src/main/java/org/smartboot/flow/condition/extension/groovy/JavaScriptCondition.java +++ b/smart-flow-script-condition/smart-flow-script-groovy/src/main/java/org/smartboot/flow/condition/extension/groovy/JavaScriptCondition.java @@ -7,6 +7,7 @@ package org.smartboot.flow.condition.extension.groovy; */ public class JavaScriptCondition extends GroovyScriptCondition { + @Override protected String getScriptLang() { return "javascript"; } diff --git a/smart-flow-script-condition/smart-flow-script-ognl/pom.xml b/smart-flow-script-condition/smart-flow-script-ognl/pom.xml index 139a2eae4d511fd6e3967c9544e83b963f217702..6191fa78b0bcecf9fbf9b79e0c8632cec186d6dc 100644 --- a/smart-flow-script-condition/smart-flow-script-ognl/pom.xml +++ b/smart-flow-script-condition/smart-flow-script-ognl/pom.xml @@ -5,7 +5,7 @@ smart-flow-script-condition org.smartboot.flow - 1.0.4 + 1.0.5 4.0.0 diff --git a/smart-flow-script-condition/smart-flow-script-ognl/src/main/java/org/smartboot/flow/condition/extension/ognl/OgnlScriptCondition.java b/smart-flow-script-condition/smart-flow-script-ognl/src/main/java/org/smartboot/flow/condition/extension/ognl/OgnlScriptCondition.java index e930fcc7a3b6213acfa5d6cbbacb1a911fe59460..55dded9cf6baeaa67bd2edb6588fbb2d3feda97a 100644 --- a/smart-flow-script-condition/smart-flow-script-ognl/src/main/java/org/smartboot/flow/condition/extension/ognl/OgnlScriptCondition.java +++ b/smart-flow-script-condition/smart-flow-script-ognl/src/main/java/org/smartboot/flow/condition/extension/ognl/OgnlScriptCondition.java @@ -23,10 +23,16 @@ public class OgnlScriptCondition extends ScriptCondition { @Override public Object test(EngineContext engineContext) { try { - Map context = new HashMap<>(); + Map context = new HashMap<>(8); context.put(ScriptConstants.REQ, engineContext.getReq()); context.put(ScriptConstants.RESULT, engineContext.getResult()); context.put(ScriptConstants.CONTEXT, engineContext); + context.put(ScriptConstants.CTX, engineContext); + + Map variables = super.bindCustomized(engineContext); + if (variables != null) { + context.putAll(variables); + } Object value = Ognl.getValue(script, context); if (LOGGER.isDebugEnabled()) { diff --git a/smart-flow-script-condition/smart-flow-script-qlexpress/pom.xml b/smart-flow-script-condition/smart-flow-script-qlexpress/pom.xml index 2aec95a467aa6236e0a578759d85b47b95e889dd..434f206d8e66454d49f61a249d030d9859226075 100644 --- a/smart-flow-script-condition/smart-flow-script-qlexpress/pom.xml +++ b/smart-flow-script-condition/smart-flow-script-qlexpress/pom.xml @@ -5,7 +5,7 @@ smart-flow-script-condition org.smartboot.flow - 1.0.4 + 1.0.5 4.0.0 diff --git a/smart-flow-script-condition/smart-flow-script-qlexpress/src/main/java/org/smartboot/flow/condition/extension/qlexpress/QlExpressScriptCondition.java b/smart-flow-script-condition/smart-flow-script-qlexpress/src/main/java/org/smartboot/flow/condition/extension/qlexpress/QlExpressScriptCondition.java index 4623cc47781905b03ecc08d614afb0acfb976c32..a3bff74b7b5fb9ac236a9da484d579cf410036ac 100644 --- a/smart-flow-script-condition/smart-flow-script-qlexpress/src/main/java/org/smartboot/flow/condition/extension/qlexpress/QlExpressScriptCondition.java +++ b/smart-flow-script-condition/smart-flow-script-qlexpress/src/main/java/org/smartboot/flow/condition/extension/qlexpress/QlExpressScriptCondition.java @@ -9,6 +9,8 @@ import org.smartboot.flow.core.exception.FlowException; import org.smartboot.flow.core.script.ScriptCondition; import org.smartboot.flow.core.script.ScriptConstants; +import java.util.Map; + /** * @author qinluo * @date 2022/11/29 21:01 @@ -26,6 +28,12 @@ public class QlExpressScriptCondition extends ScriptCondition { qlContext.put(ScriptConstants.REQ, engineContext.getReq()); qlContext.put(ScriptConstants.RESULT, engineContext.getResult()); qlContext.put(ScriptConstants.CONTEXT, engineContext); + qlContext.put(ScriptConstants.CTX, engineContext); + + Map variables = super.bindCustomized(engineContext); + if (variables != null) { + qlContext.putAll(variables); + } ExpressRunner runner = new ExpressRunner(); Object value = runner.execute(script, qlContext, null, true, false); diff --git a/smart-flow-spring-extension/pom.xml b/smart-flow-spring-extension/pom.xml index ceef2f01a16f1534660b677cf376f1abab9284b8..e5cb0f62f1dd438f706530590f66b91e78ce03d1 100644 --- a/smart-flow-spring-extension/pom.xml +++ b/smart-flow-spring-extension/pom.xml @@ -5,7 +5,7 @@ smart-flow-parent org.smartboot.flow - 1.0.4 + 1.0.5 4.0.0 @@ -18,10 +18,11 @@ + org.smartboot.flow - smart-flow-core - 1.0.4 + smart-flow-manager + 1.0.5 @@ -37,43 +38,10 @@ ${spring.version} - - org.springframework - spring-orm - ${spring.version} - - - - org.springframework - spring-aop - ${spring.version} - - org.springframework spring-beans ${spring.version} - - org.springframework - spring-test - 5.2.4.RELEASE - test - - - - - org.junit.jupiter - junit-jupiter-api - 5.9.1 - test - - - - org.junit.jupiter - junit-jupiter-engine - 5.9.1 - test - \ No newline at end of file diff --git a/smart-flow-spring-extension/src/main/java/org/smartboot/flow/spring/extension/BeanDefinitionRegister.java b/smart-flow-spring-extension/src/main/java/org/smartboot/flow/spring/extension/BeanDefinitionRegister.java index ae844947150706ca07d02d6653c96497e326cdbb..fa0b792560c3cff14a4525475da8c48f9b2a4ca8 100644 --- a/smart-flow-spring-extension/src/main/java/org/smartboot/flow/spring/extension/BeanDefinitionRegister.java +++ b/smart-flow-spring-extension/src/main/java/org/smartboot/flow/spring/extension/BeanDefinitionRegister.java @@ -40,8 +40,4 @@ public class BeanDefinitionRegister { registered.put(identifier, def); } } - - public boolean containsBeanDefinition(String identifier) { - return registered.containsKey(identifier) || registry.containsBeanDefinition(identifier); - } } diff --git a/smart-flow-spring-extension/src/main/java/org/smartboot/flow/spring/extension/EnableReloadNotify.java b/smart-flow-spring-extension/src/main/java/org/smartboot/flow/spring/extension/EnableReloadNotify.java new file mode 100644 index 0000000000000000000000000000000000000000..1b8ea79a729a66379bec6dc21207b5fb9405b712 --- /dev/null +++ b/smart-flow-spring-extension/src/main/java/org/smartboot/flow/spring/extension/EnableReloadNotify.java @@ -0,0 +1,21 @@ +package org.smartboot.flow.spring.extension; + +import org.springframework.context.annotation.Import; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * 开启引擎reload通知 + * + * @author qinluo + * @date 2023/1/31 22:16 + * @since 1.0.0 + */ +@Target(ElementType.TYPE) +@Retention(RetentionPolicy.RUNTIME) +@Import(SmartFlowRegistrar.class) +public @interface EnableReloadNotify { +} diff --git a/smart-flow-spring-extension/src/main/java/org/smartboot/flow/spring/extension/NameAwareCondition.java b/smart-flow-spring-extension/src/main/java/org/smartboot/flow/spring/extension/NameAwareCondition.java index 6f753bfa4fa9e1f680d1f3b4f3a30c834f6e3c99..802c24f50391a59bf7d552c9f5f854791f44f15f 100644 --- a/smart-flow-spring-extension/src/main/java/org/smartboot/flow/spring/extension/NameAwareCondition.java +++ b/smart-flow-spring-extension/src/main/java/org/smartboot/flow/spring/extension/NameAwareCondition.java @@ -10,7 +10,6 @@ import org.springframework.beans.factory.BeanNameAware; */ public abstract class NameAwareCondition extends NamedCondition implements BeanNameAware { - @SuppressWarnings("NullableProblems") @Override public void setBeanName(String name) { super.setName(name); diff --git a/smart-flow-spring-extension/src/main/java/org/smartboot/flow/spring/extension/NamedAbstractExecutable.java b/smart-flow-spring-extension/src/main/java/org/smartboot/flow/spring/extension/NamedAbstractExecutable.java index 17783f5ebf6dcdfac2cdc57e99e87f9b9496ea5e..9f140de00b8848112d310e3e9caa6f46597aaba6 100644 --- a/smart-flow-spring-extension/src/main/java/org/smartboot/flow/spring/extension/NamedAbstractExecutable.java +++ b/smart-flow-spring-extension/src/main/java/org/smartboot/flow/spring/extension/NamedAbstractExecutable.java @@ -12,7 +12,6 @@ public abstract class NamedAbstractExecutable extends AbstractExecutable { + field.setAccessible(true); + ReloadNotify conf = field.getAnnotation(ReloadNotify.class); + if (FlowEngine.class.isAssignableFrom(field.getType())) { + String engineName = AuxiliaryUtils.or(conf.value()[0], field.getName()); + notifier.addNotifyField(field, bean, Collections.singletonList(engineName)); + } else if (Map.class.isAssignableFrom(field.getType())) { + notifier.addNotifyField(field, bean, Arrays.asList(conf.value())); + } + + }, field -> field.isAnnotationPresent(ReloadNotify.class)); + } catch (Exception e) { + LOGGER.error("process bean failed, bean = {}", beanName, e); + } + } + + @Override + public void setBeanFactory(BeanFactory beanFactory) throws BeansException { + if (beanFactory instanceof DefaultListableBeanFactory) { + ((DefaultListableBeanFactory)beanFactory).setAllowBeanDefinitionOverriding(true); + notifier = new ReflectionNotifier(beanFactory); + notifier.register(); + } + + } +} diff --git a/smart-flow-spring-extension/src/main/java/org/smartboot/flow/spring/extension/ProxyParser.java b/smart-flow-spring-extension/src/main/java/org/smartboot/flow/spring/extension/ProxyParser.java index e151da6d69a51d1c5218cf9a6e7c6a02a512b86a..4e6d94eb00b7ffae63d7d2fc10c161d618243897 100644 --- a/smart-flow-spring-extension/src/main/java/org/smartboot/flow/spring/extension/ProxyParser.java +++ b/smart-flow-spring-extension/src/main/java/org/smartboot/flow/spring/extension/ProxyParser.java @@ -18,6 +18,7 @@ public class ProxyParser implements BeanDefinitionParser { @Override public BeanDefinition parse(Element element, ParserContext parserContext) { + SmartFlowRegistrar.registerAll(parserContext.getRegistry()); org.smartboot.flow.core.parser.ParserContext context = new org.smartboot.flow.core.parser.ParserContext(); // Ensure identifier in spring scope is unique. context.setIdentifierManager(new SpringIdentifierManager(parserContext.getRegistry())); diff --git a/smart-flow-spring-extension/src/main/java/org/smartboot/flow/spring/extension/ReflectionNotifier.java b/smart-flow-spring-extension/src/main/java/org/smartboot/flow/spring/extension/ReflectionNotifier.java new file mode 100644 index 0000000000000000000000000000000000000000..a703f3a6ce8a477f619c451a41e1792380d14c4f --- /dev/null +++ b/smart-flow-spring-extension/src/main/java/org/smartboot/flow/spring/extension/ReflectionNotifier.java @@ -0,0 +1,117 @@ +package org.smartboot.flow.spring.extension; + +import org.smartboot.flow.core.FlowEngine; +import org.smartboot.flow.core.manager.DefaultEngineManager; +import org.smartboot.flow.core.manager.EngineModel; +import org.smartboot.flow.core.util.AuxiliaryUtils; +import org.smartboot.flow.manager.reload.ReloadListener; +import org.springframework.beans.factory.BeanFactory; +import org.springframework.util.ReflectionUtils; + +import java.lang.reflect.Field; +import java.util.List; +import java.util.Map; +import java.util.Objects; +import java.util.concurrent.CopyOnWriteArrayList; + +/** + * @author qinluo + * @date 2023/1/31 23:17 + * @since 1.0.0 + */ +public class ReflectionNotifier implements ReloadListener { + + private final BeanFactory factory; + private final List notifiers = new CopyOnWriteArrayList<>(); + + public ReflectionNotifier(BeanFactory factory) { + this.factory = factory; + } + + @Override + public void onload(String engineName) { + + } + + @Override + public void loadCompleted(String engineName, Throwable e) { + if (e != null) { + return; + } + + FlowEngine engineInstance = null; + FlowEngine springEngine = null; + FlowEngine managerEngine = null; + try { + springEngine = (FlowEngine)factory.getBean(engineName); + } catch (Exception ex) { + // do-nothing + } + + EngineModel engineModel = DefaultEngineManager.getDefaultManager().getEngineModel(engineName); + if (engineModel != null) { + managerEngine = engineModel.getSource(); + } + + if (springEngine == null ^ managerEngine == null) { + engineInstance = AuxiliaryUtils.or(springEngine, managerEngine); + } else if (springEngine != null) { + if (springEngine.getStartedAt() > managerEngine.getStartedAt()) { + engineInstance = springEngine; + } else if(springEngine.getStartedAt() < managerEngine.getStartedAt()){ + engineInstance = managerEngine; + } + } + + // Cannot find engine instance. + if (engineInstance == null) { + return; + } + + for (NotifyConf conf : notifiers) { + conf.notify(engineName, engineInstance); + } + + } + + public void addNotifyField(Field field, Object bean, List accepted) { + notifiers.add(new NotifyConf(field, bean, accepted)); + } + + private static class NotifyConf { + private final Field f; + private final Object bean; + private final List accepted; + private final boolean acceptAny; + + public NotifyConf(Field f, Object bean, List accepted) { + this.f = f; + this.bean = bean; + this.accepted = accepted; + this.acceptAny = accepted.size() == 1 && Objects.equals(accepted.get(0), ""); + } + + public void notify(String engineName, FlowEngine engineInstance) { + if (!acceptAny && !accepted.contains(engineName)) { + return; + } + + if (FlowEngine.class.isAssignableFrom(f.getType())) { + ReflectionUtils.setField(f, bean, engineInstance); + } else if ((Map.class.isAssignableFrom(f.getType()))) { + Map engines = (Map)ReflectionUtils.getField(f, bean); + if (engines == null) { + return; + } + + Object o = engines.get(engineName); + if (o instanceof FlowEngine) { + engines.put(engineName, engineInstance); + } + + } + + + } + } +} diff --git a/smart-flow-spring-extension/src/main/java/org/smartboot/flow/spring/extension/ReloadNotify.java b/smart-flow-spring-extension/src/main/java/org/smartboot/flow/spring/extension/ReloadNotify.java new file mode 100644 index 0000000000000000000000000000000000000000..1b101571994cf02ec0e6ccea5a9e96e7ee813044 --- /dev/null +++ b/smart-flow-spring-extension/src/main/java/org/smartboot/flow/spring/extension/ReloadNotify.java @@ -0,0 +1,28 @@ +package org.smartboot.flow.spring.extension; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * 标注引擎更新 + * + * @author qinluo + * @date 2023/1/31 21:53 + * @since 1.0.0 + */ +@Target(ElementType.FIELD) +@Retention(RetentionPolicy.RUNTIME) +public @interface ReloadNotify { + + /** + * 需要通知的引擎名称列表 + * 当修饰单个引擎字段时,value值为引擎名称,不指定则属性字段名为引擎名称 + * 当修饰map时,可以指定引擎名称列表,如果不指定则默认所有引擎都会注册到map中 + * + * + * @return 引擎名称 + */ + String[] value() default ""; +} diff --git a/smart-flow-spring-extension/src/main/java/org/smartboot/flow/spring/extension/SmartFlowRegistrar.java b/smart-flow-spring-extension/src/main/java/org/smartboot/flow/spring/extension/SmartFlowRegistrar.java new file mode 100644 index 0000000000000000000000000000000000000000..cc3818e16ba4da25efdbaad42b7f91d218b875ff --- /dev/null +++ b/smart-flow-spring-extension/src/main/java/org/smartboot/flow/spring/extension/SmartFlowRegistrar.java @@ -0,0 +1,37 @@ +package org.smartboot.flow.spring.extension; + +import org.springframework.beans.factory.support.BeanDefinitionRegistry; +import org.springframework.beans.factory.support.BeanNameGenerator; +import org.springframework.beans.factory.support.RootBeanDefinition; +import org.springframework.context.annotation.ImportBeanDefinitionRegistrar; +import org.springframework.core.type.AnnotationMetadata; + +/** + * @author qinluo + * @date 2023/1/31 22:15 + * @since 1.0.0 + */ +public class SmartFlowRegistrar implements ImportBeanDefinitionRegistrar { + + private static volatile boolean registered = false; + private static final String NOTIFIER_PROCESS = "smart-flow-notifer-processor"; + + @Override + public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry, BeanNameGenerator importBeanNameGenerator) { + registerAll(registry); + } + + public static void registerAll(BeanDefinitionRegistry registry) { + registerNotifier(registry); + } + + private static void registerNotifier(BeanDefinitionRegistry registry) { + if (registered) { + return; + } + registered = true; + RootBeanDefinition definition = new RootBeanDefinition(); + definition.setBeanClass(NotifierProcessor.class); + registry.registerBeanDefinition(NOTIFIER_PROCESS, definition); + } +} diff --git a/smart-flow-spring-extension/src/main/java/org/smartboot/flow/spring/extension/SpringObjectCreator.java b/smart-flow-spring-extension/src/main/java/org/smartboot/flow/spring/extension/SpringObjectCreator.java index 1f75d8dfc64e529cf36405ddc7cd664a68ec5118..242e1e354a2aeecf01bb3f65a3bb35475c4d36c2 100644 --- a/smart-flow-spring-extension/src/main/java/org/smartboot/flow/spring/extension/SpringObjectCreator.java +++ b/smart-flow-spring-extension/src/main/java/org/smartboot/flow/spring/extension/SpringObjectCreator.java @@ -17,14 +17,14 @@ public class SpringObjectCreator implements ObjectCreator, ApplicationContextAwa @Override @SuppressWarnings("unchecked") - public T create(String type, boolean useCache) { + public T create(String type, Class expectType, boolean useCache) { Object obj; try { // type as bean name. obj = ctx.getBean(type); } catch (BeansException ignored) { - obj = DefaultObjectCreator.getInstance().create(type, useCache); + obj = DefaultObjectCreator.getInstance().create(type, expectType, useCache); } return (T)obj; diff --git a/smart-flow-springboot-starter/pom.xml b/smart-flow-springboot-starter/pom.xml index aa357a519591f1ddd5c3b7a209b0528b21d5e681..dcc77cc59e9c065c2ff5c94a25c15b1514f2a154 100644 --- a/smart-flow-springboot-starter/pom.xml +++ b/smart-flow-springboot-starter/pom.xml @@ -5,7 +5,7 @@ smart-flow-parent org.smartboot.flow - 1.0.4 + 1.0.5 4.0.0 @@ -25,12 +25,7 @@ org.smartboot.flow smart-flow-spring-extension - 1.0.4 - - - org.smartboot.flow - smart-flow-manager - 1.0.4 + 1.0.5