diff --git a/pom.xml b/pom.xml
index 53b03fa356a1f4951228f1f23a857a2456e971f7..6290330b3457f92ffba26d2a92e23f1959f789b9 100644
--- a/pom.xml
+++ b/pom.xml
@@ -5,7 +5,7 @@
org.smartboot.flow
smart-flow-parent
- 1.1.2
+ 1.1.3
4.0.0
pom
smart-flow
@@ -13,17 +13,16 @@
smart-flow-core
- smart-flow-spring-extension
smart-flow-manager
smart-flow-script
- smart-flow-springboot-starter
smart-flow-helper
smart-flow-admin
smart-flow-plugin
+ smart-flow-integration
- 1.1.2
+ 1.1.3
https://gitee.com/smartboot/smart-flow
diff --git a/smart-flow-admin/pom.xml b/smart-flow-admin/pom.xml
index 85828cc18769b85ea2b9b805160e539fd49d57e7..023f141bf9789ddf452f9551c719dad16232ddb0 100644
--- a/smart-flow-admin/pom.xml
+++ b/smart-flow-admin/pom.xml
@@ -5,16 +5,17 @@
smart-flow-parent
org.smartboot.flow
- 1.1.2
+ 1.1.3
4.0.0
- 1.1.2
+ 1.1.3
smart-flow-admin
8
8
+ UTF-8
diff --git a/smart-flow-admin/src/main/java/org/smartboot/smart/flow/admin/controller/WebUtils.java b/smart-flow-admin/src/main/java/org/smartboot/smart/flow/admin/controller/WebUtils.java
index 01fc33c3eae65a494cc716019ef6097926784715..0809d91c4ec573634c5eeba4526da55d8c559ead 100644
--- a/smart-flow-admin/src/main/java/org/smartboot/smart/flow/admin/controller/WebUtils.java
+++ b/smart-flow-admin/src/main/java/org/smartboot/smart/flow/admin/controller/WebUtils.java
@@ -5,6 +5,7 @@ import org.smartboot.flow.core.exception.FlowException;
import org.smartboot.flow.core.parser.DefaultParser;
import org.smartboot.flow.core.util.AssertUtil;
import org.smartboot.flow.helper.mock.FakeObjectCreator;
+import org.smartboot.flow.helper.mock.FakeValueResolver;
import java.io.ByteArrayInputStream;
import java.net.URLDecoder;
@@ -21,6 +22,7 @@ public final class WebUtils {
public static FlowEngine, ?> parseValidate(String content, boolean decodeIfNecessary) {
DefaultParser parser = new DefaultParser();
parser.setObjectCreator(new FakeObjectCreator());
+ parser.setAttributeValueResolver(new FakeValueResolver());
try {
if (decodeIfNecessary) {
diff --git a/smart-flow-core/pom.xml b/smart-flow-core/pom.xml
index 35b721c8dd621b7d3114c5b53dcfe1f2ba432155..f7cf83182d592189382c28187bb2a9f0cfe71ff9 100644
--- a/smart-flow-core/pom.xml
+++ b/smart-flow-core/pom.xml
@@ -5,7 +5,7 @@
org.smartboot.flow
smart-flow-parent
- 1.1.2
+ 1.1.3
4.0.0
diff --git a/smart-flow-core/src/main/java/org/smartboot/flow/core/EngineContextHelper.java b/smart-flow-core/src/main/java/org/smartboot/flow/core/EngineContextHelper.java
new file mode 100644
index 0000000000000000000000000000000000000000..fb3864b2ce5285f3e2d84b31cfa4d41bf913a1c8
--- /dev/null
+++ b/smart-flow-core/src/main/java/org/smartboot/flow/core/EngineContextHelper.java
@@ -0,0 +1,39 @@
+package org.smartboot.flow.core;
+
+/**
+ * @author qinluo
+ * @date 2023-07-27 14:55:42
+ * @since 1.1.3
+ */
+@SuppressWarnings("rawtypes")
+public class EngineContextHelper {
+
+ private static final ThreadLocal HOLDER = new ThreadLocal<>();
+
+ public static void set(EngineContext ctx) {
+ HOLDER.set(ctx);
+ }
+
+ public static EngineContext get() {
+ return HOLDER.get();
+ }
+
+ public static void remove() {
+ HOLDER.remove();
+ }
+
+ public static void broken() {
+ EngineContext ctx = get();
+ if (ctx != null) {
+ ctx.broken(true);
+ }
+ }
+
+ public static void brokenAll() {
+ EngineContext ctx = get();
+ if (ctx != null) {
+ ctx.brokenAll(true);
+ }
+ }
+
+}
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 5ee4d81a4f794b7cf16b405bc57dfa6db4bbf54f..530660e76cf1cb79cc8e8e73117a21c7e50775b7 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
@@ -85,6 +85,7 @@ public class FlowEngine implements Describable, Validator, Measurable {
}
private void start(EngineContext context) {
+ EngineContextHelper.set(context);
context.executedAt = System.currentTimeMillis();
context.listener.start(context);
}
@@ -92,6 +93,7 @@ public class FlowEngine implements Describable, Validator, Measurable {
private void complete(EngineContext context) {
context.completedAt = System.currentTimeMillis();
context.listener.completed(context);
+ EngineContextHelper.remove();
}
protected void initContext(EngineContext context) {
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 ad293f74a0f53358f199860eeaff9db1e9309ba1..0290bdc7b50cd0a3d05436e602b0fe32c2cef3c8 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
@@ -21,7 +21,6 @@ public enum Attributes {
NAME("name", "组件名称", String.class) {
@Override
public void apply(Component component, Object value) {
- super.apply(component, value);
component.setName((String) value);
}
},
@@ -29,7 +28,6 @@ public enum Attributes {
ROLLBACK("rollback", "是否开启回滚", Boolean.class) {
@Override
public void apply(Component component, Object value) {
- super.apply(component, value);
component.setRollback((Boolean) value);
}
},
@@ -37,7 +35,6 @@ public enum Attributes {
DEGRADABLE("degradable", "是否开启降级", Boolean.class) {
@Override
public void apply(Component component, Object value) {
- super.apply(component, value);
component.setDegradable((Boolean) value);
}
},
@@ -45,7 +42,6 @@ public enum Attributes {
ASYNC("async", "是否开启异步", Boolean.class) {
@Override
public void apply(Component component, Object value) {
- super.apply(component, value);
component.setAsync((Boolean) value);
}
},
@@ -53,7 +49,6 @@ public enum Attributes {
TIMEOUT("timeout", "异步超时时间", Long.class) {
@Override
public void apply(Component component, Object value) {
- super.apply(component, value);
component.setTimeout(((Number) value).longValue());
}
},
@@ -61,7 +56,6 @@ public enum Attributes {
DEPENDS_ON("dependsOn", "依赖的异步组件", List.class) {
@Override
public void apply(Component component, Object value) {
- super.apply(component, value);
//noinspection unchecked
component.setDependsOn((List)value);
}
@@ -75,7 +69,6 @@ public enum Attributes {
ENABLED("enabled", "启用开关", Boolean.class) {
@Override
public void apply(Component component, Object value) {
- super.apply(component, value);
component.setEnabled((Boolean) value);
}
},
@@ -88,7 +81,6 @@ public enum Attributes {
DEGRADE_CALLBACK("degrade-callback", "降级回调", DegradeCallback.class) {
@Override
public void apply(Component component, Object value) {
- super.apply(component, value);
component.setDegradeCallback((DegradeCallback) value);
}
},
@@ -140,12 +132,16 @@ public enum Attributes {
return name;
}
+ public Class> getAccept() {
+ return accept;
+ }
+
public boolean accept(Object value) {
return accept.isInstance(value);
}
public void apply(Component component, Object value) {
- component.addAttribute(AttributeHolder.of(this, value));
+
}
public boolean isVisible() {
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 0b7cffd03772e0dea5400222dff14cae2b1958d3..02384ac92daae6c7dd6520dcd88ef47095ab9d59 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
@@ -3,6 +3,7 @@ package org.smartboot.flow.core.executable;
import org.smartboot.flow.core.Describable;
import org.smartboot.flow.core.EngineContext;
+import org.smartboot.flow.core.EngineContextHelper;
import org.smartboot.flow.core.Rollback;
import org.smartboot.flow.core.visitor.ExecutableVisitor;
@@ -30,4 +31,23 @@ public interface Executable extends Rollback, Describable {
default void visit(ExecutableVisitor visitor) {
visitor.visitSource(this);
}
+
+
+ /**
+ * Broken current subprocess.
+ *
+ * @since 1.1.3
+ */
+ default void broken() {
+ EngineContextHelper.broken();
+ }
+
+ /**
+ * Broken whole process.
+ *
+ * @since 1.1.3
+ */
+ default void brokenAll() {
+ EngineContextHelper.brokenAll();
+ }
}
diff --git a/smart-flow-core/src/main/java/org/smartboot/flow/core/invoker/AsyncRunner.java b/smart-flow-core/src/main/java/org/smartboot/flow/core/invoker/AsyncRunner.java
index 842ce479951e339d10273e326aa4c491e3d24fa4..c02a484f2e256ac8530903a9835566eeb92e3d14 100644
--- a/smart-flow-core/src/main/java/org/smartboot/flow/core/invoker/AsyncRunner.java
+++ b/smart-flow-core/src/main/java/org/smartboot/flow/core/invoker/AsyncRunner.java
@@ -1,5 +1,7 @@
package org.smartboot.flow.core.invoker;
+import org.smartboot.flow.core.EngineContext;
+import org.smartboot.flow.core.EngineContextHelper;
import org.smartboot.flow.core.trace.Node;
import org.smartboot.flow.core.trace.Tracer;
@@ -10,15 +12,18 @@ import java.util.concurrent.Callable;
* @date 2022-12-07 21:57:39
* @since 1.0.0
*/
+@SuppressWarnings("rawtypes")
public class AsyncRunner implements Callable {
private final Callable task;
private final Node root;
private final long threadId;
+ private final EngineContext ctx;
public AsyncRunner(Callable task) {
this.task = task;
this.root = Tracer.get();
+ this.ctx = EngineContextHelper.get();
this.threadId = Thread.currentThread().getId();
}
@@ -38,6 +43,7 @@ public class AsyncRunner implements Callable {
if (tid != threadId) {
Tracer.setNode(root);
}
+ EngineContextHelper.set(ctx);
}
protected void doAfterRun() {
@@ -45,5 +51,6 @@ public class AsyncRunner implements Callable {
if (tid != threadId) {
Tracer.remove();
}
+ EngineContextHelper.remove();
}
}
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 34cf89bdfced562bf765c08234f3366aaf4c2f48..8aef0c242217bfc7a427e241db75554e2f5030c8 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
@@ -6,6 +6,7 @@ import org.smartboot.flow.core.common.Uniqueness;
import org.smartboot.flow.core.attribute.AttributeHolder;
import org.smartboot.flow.core.component.Component;
+import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@@ -24,6 +25,7 @@ public class ComponentModel extends Uniqueness {
private final Map components = new ConcurrentHashMap<>();
private final ComponentType type;
PipelineModel pipeline;
+ private List holders = new ArrayList<>();
ComponentModel(ComponentType type, String name) {
this.name = name;
@@ -31,6 +33,10 @@ public class ComponentModel extends Uniqueness {
this.identifier = name;
}
+ public void setHolders(List holders) {
+ this.holders = holders;
+ }
+
Map collect() {
this.component.setName(name);
if (type == ComponentType.SUBPROCESS) {
@@ -57,13 +63,22 @@ public class ComponentModel extends Uniqueness {
@SuppressWarnings("unchecked")
public void changeAttributes(List holders) {
AttributeValueResolver valueResolver = AttributeValueResolver.getInstance();
+ List backup = new ArrayList<>(this.holders);
+
try {
holders.forEach(p -> {
Object resolvedValue = valueResolver.resolve(p.getAttribute(), p.getValue());
p.getAttribute().apply(component, resolvedValue);
+ // Remove and add new.
+ backup.removeIf(o -> p.getAttribute() == o.getAttribute());
+ backup.add(p);
});
+
} catch (Exception ignored) {
+ } finally {
+ this.holders.clear();
+ this.holders.addAll(backup);
}
}
diff --git a/smart-flow-core/src/main/java/org/smartboot/flow/core/manager/DefaultEngineManager.java b/smart-flow-core/src/main/java/org/smartboot/flow/core/manager/DefaultEngineManager.java
index d13f34aeef83a63016115549a48ca6a0c947a86e..49e7fa64d24c16279cb0bcb46419babcf6c9d69a 100644
--- a/smart-flow-core/src/main/java/org/smartboot/flow/core/manager/DefaultEngineManager.java
+++ b/smart-flow-core/src/main/java/org/smartboot/flow/core/manager/DefaultEngineManager.java
@@ -23,17 +23,6 @@ public class DefaultEngineManager implements EngineManager {
private final Map registeredEngines = new ConcurrentHashMap<>();
- /**
- * Return singleton instance.
- * Will remove at 1.1.0, please use {@link EngineManager#defaultManager()}.
- *
- * @return singleton instance.
- */
- @Deprecated
- public static EngineManager getDefaultManager() {
- return INSTANCE;
- }
-
/**
* Rename getDefaultManager to getInstance.
*
diff --git a/smart-flow-core/src/main/java/org/smartboot/flow/core/manager/EngineManager.java b/smart-flow-core/src/main/java/org/smartboot/flow/core/manager/EngineManager.java
index ec449bf292aa9c7f1a6e12ed69accbf7c74ce1e6..bd826c049cbd29977262e92456047813328f5873 100644
--- a/smart-flow-core/src/main/java/org/smartboot/flow/core/manager/EngineManager.java
+++ b/smart-flow-core/src/main/java/org/smartboot/flow/core/manager/EngineManager.java
@@ -83,4 +83,22 @@ public interface EngineManager {
static EngineManager defaultManager() {
return DefaultEngineManager.getInstance();
}
+
+ /* Static delegate methods */
+
+ /**
+ * @since 1.1.3
+ *
+ * @param name engine name.
+ * @param request generic type
+ * @param response generic type
+ * @return engine
+ */
+ static FlowEngine getEngine(String name) {
+ EngineModel model = DefaultEngineManager.getInstance().getEngineModel(name);
+ if (model != null) {
+ return model.getSource();
+ }
+ return null;
+ }
}
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 2a9418b9ff0755d0f6bae240b8cb259d3144f373..ec5f85295a7faf8ec00f94b1fa627272dff28876 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
@@ -1,11 +1,13 @@
package org.smartboot.flow.core.manager;
+import org.smartboot.flow.core.attribute.AttributeHolder;
import org.smartboot.flow.core.common.ComponentType;
import org.smartboot.flow.core.component.Component;
import org.smartboot.flow.core.util.AuxiliaryUtils;
import org.smartboot.flow.core.visitor.ComponentVisitor;
import org.smartboot.flow.core.visitor.PipelineVisitor;
+import java.util.List;
import java.util.Set;
/**
@@ -66,4 +68,9 @@ public class RegisteredComponentVisitor extends ComponentVisitor {
this.model.addComponent(model);
return new RegisteredComponentVisitor(model, visited, allocator);
}
+
+ @Override
+ public void visitAttributes(List attributes) {
+ this.model.setHolders(attributes);
+ }
}
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 7a3f899c1e80ca0bd01ef64afcb0127352b4facf..a78492c408e1544ece00e3bb7113ec4f7f2e394a 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
@@ -149,6 +149,7 @@ public class BuilderDefinitionVisitor implements DefinitionVisitor {
this.collect(ed.getPipeline(), (pipelineComponent::setPipeline));
}
pipelineComponent.setAttributeMap(ed.getAttributeMap());
+ pipelineComponent.setAttributes(ed.getAttributes());
this.namedComponents.put(engineName, pipelineComponent);
}
@@ -192,6 +193,7 @@ public class BuilderDefinitionVisitor implements DefinitionVisitor {
.withResolver(valueResolver)
.apply(ed.getAttributes())
.build();
+ component.setAttributes(ed.getAttributes());
component.setAttributeMap(ed.getAttributeMap());
namedComponents.put(ed.getIdentifier(), component);
}
@@ -252,6 +254,7 @@ public class BuilderDefinitionVisitor implements DefinitionVisitor {
Component, ?> build = Builders.newIf().test(condition).withResolver(valueResolver)
.apply(ed.getAttributes()).then(then).otherwise(elseBranch).build();
build.setAttributeMap(ed.getAttributeMap());
+ build.setAttributes(ed.getAttributes());
this.namedComponents.put(ed.getIdentifier(), build);
}
@@ -310,6 +313,7 @@ public class BuilderDefinitionVisitor implements DefinitionVisitor {
ChooseComponent, ?> build = chooseBuilder.build();
build.setAllBranchWasString(true);
build.setAttributeMap(ed.getAttributeMap());
+ build.setAttributes(ed.getAttributes());
this.namedComponents.put(ed.getIdentifier(), build);
}
@@ -331,6 +335,7 @@ public class BuilderDefinitionVisitor implements DefinitionVisitor {
AdapterComponent adapterComponent = adapterBuilder.build();
adapterComponent.setAttributeMap(ed.getAttributeMap());
+ adapterComponent.setAttributes(ed.getAttributes());
this.namedComponents.put(ed.getIdentifier(), adapterComponent);
}
diff --git a/smart-flow-core/src/main/java/org/smartboot/flow/core/parser/ThreadPoolCreator.java b/smart-flow-core/src/main/java/org/smartboot/flow/core/parser/ThreadPoolCreator.java
index 078d97bce3b4d74af53c44a18b9e63c0e5cc488f..3ac153f9d67d22e3775d960e8ebb212867540881 100644
--- a/smart-flow-core/src/main/java/org/smartboot/flow/core/parser/ThreadPoolCreator.java
+++ b/smart-flow-core/src/main/java/org/smartboot/flow/core/parser/ThreadPoolCreator.java
@@ -43,7 +43,7 @@ public class ThreadPoolCreator {
executor.setThreadFactory(new NamedThreadFactory(attr.getValue()));
break;
case "prestartAllCoreThreads":
- prestartAllCoreThreads = true;
+ prestartAllCoreThreads = Boolean.parseBoolean(attr.getValue());
break;
}
}
diff --git a/smart-flow-core/src/main/java/org/smartboot/flow/core/util/BeanContext.java b/smart-flow-core/src/main/java/org/smartboot/flow/core/util/BeanContext.java
new file mode 100644
index 0000000000000000000000000000000000000000..84f616f7ff917a8d0ca6e04ed0fd580dff979868
--- /dev/null
+++ b/smart-flow-core/src/main/java/org/smartboot/flow/core/util/BeanContext.java
@@ -0,0 +1,27 @@
+package org.smartboot.flow.core.util;
+
+import java.util.List;
+
+/**
+ * @author qinluo
+ * @date 2023-08-09 11:39:16
+ * @since 1.1.3
+ */
+public interface BeanContext {
+
+ default T getBean(String name) {
+ throw new UnsupportedOperationException();
+ }
+
+ default T getBean(String name, Class type) {
+ throw new UnsupportedOperationException();
+ }
+
+ default List getBean(Class type) {
+ throw new UnsupportedOperationException();
+ }
+
+ default void init() {
+ BeanUtils.init(this);
+ }
+}
diff --git a/smart-flow-core/src/main/java/org/smartboot/flow/core/util/BeanUtils.java b/smart-flow-core/src/main/java/org/smartboot/flow/core/util/BeanUtils.java
new file mode 100644
index 0000000000000000000000000000000000000000..0b8b6a9347d5f64a3ad18925f7f98cdf3f995f6f
--- /dev/null
+++ b/smart-flow-core/src/main/java/org/smartboot/flow/core/util/BeanUtils.java
@@ -0,0 +1,31 @@
+package org.smartboot.flow.core.util;
+
+import java.util.List;
+
+/**
+ * @author qinluo
+ * @date 2023-08-09 11:36:35
+ * @since 1.1.3
+ */
+public class BeanUtils {
+
+ private static BeanContext instance = null;
+
+ public static T getBean(String name) {
+ return instance.getBean(name);
+ }
+
+ public static T getBean(String name, Class type) {
+ return instance.getBean(name, type);
+ }
+
+ public static T getBean(Class type) {
+ List beans = instance.getBean(type);
+ return beans != null && beans.size() > 0 ? beans.get(0) : null;
+ }
+
+ static void init(BeanContext ctx) {
+ instance = ctx;
+ }
+
+}
diff --git a/smart-flow-helper/pom.xml b/smart-flow-helper/pom.xml
index 3d8489ef2c784b0ffe84509ce22156fb5f4a1bef..23c8f4e1c760b4dd74fa06001f50470ec9d8f56c 100644
--- a/smart-flow-helper/pom.xml
+++ b/smart-flow-helper/pom.xml
@@ -5,7 +5,7 @@
smart-flow-parent
org.smartboot.flow
- 1.1.2
+ 1.1.3
4.0.0
diff --git a/smart-flow-helper/src/main/java/org/smartboot/flow/helper/mock/FakeValueResolver.java b/smart-flow-helper/src/main/java/org/smartboot/flow/helper/mock/FakeValueResolver.java
new file mode 100644
index 0000000000000000000000000000000000000000..9e3f61541f54537ff5344bc262ade24fa8e4c6f9
--- /dev/null
+++ b/smart-flow-helper/src/main/java/org/smartboot/flow/helper/mock/FakeValueResolver.java
@@ -0,0 +1,39 @@
+package org.smartboot.flow.helper.mock;
+
+import org.smartboot.flow.core.attribute.AttributeValueResolver;
+import org.smartboot.flow.core.attribute.Attributes;
+
+/**
+ * Fake value resolver
+ *
+ * @author qinluo
+ * @date 2023/1/27 12:35
+ * @since 1.1.3
+ */
+public class FakeValueResolver extends AttributeValueResolver {
+
+ public FakeValueResolver() {
+ this.setObjectCreator(new FakeObjectCreator());
+ }
+
+ @Override
+ public Object resolve(Attributes attribute, Object value) {
+ try {
+ return super.resolve(attribute, value);
+ } catch (Exception ignored) {
+
+ }
+
+ // Miss parsed, as default value.
+ Class> accepted = attribute.getAccept();
+ if (accepted == String.class) {
+ return String.valueOf(value);
+ } else if (accepted == Long.class) {
+ return 0L;
+ } else if (accepted == Boolean.class) {
+ return false;
+ } else {
+ return null;
+ }
+ }
+}
diff --git a/smart-flow-integration/pom.xml b/smart-flow-integration/pom.xml
new file mode 100644
index 0000000000000000000000000000000000000000..4b1f46d90d0b929d53fb3c16c03138d54ff71454
--- /dev/null
+++ b/smart-flow-integration/pom.xml
@@ -0,0 +1,26 @@
+
+
+
+ smart-flow-parent
+ org.smartboot.flow
+ 1.1.3
+
+ 4.0.0
+
+ smart-flow-integration
+ pom
+
+ smart-flow-integration-nacos
+ smart-flow-spring-extension
+ smart-flow-springboot-starter
+
+
+
+ 8
+ 8
+ UTF-8
+
+
+
\ No newline at end of file
diff --git a/smart-flow-integration/smart-flow-integration-nacos/pom.xml b/smart-flow-integration/smart-flow-integration-nacos/pom.xml
new file mode 100644
index 0000000000000000000000000000000000000000..aca264249e1dbfd88b7a77d242eb263518b3ad78
--- /dev/null
+++ b/smart-flow-integration/smart-flow-integration-nacos/pom.xml
@@ -0,0 +1,41 @@
+
+
+
+ smart-flow-integration
+ org.smartboot.flow
+ 1.1.3
+
+ 4.0.0
+
+ smart-flow-integration-nacos
+
+
+ 8
+ 8
+ UTF-8
+
+
+
+
+ org.smartboot.flow
+ smart-flow-manager
+ ${smart-flow.version}
+
+
+
+ com.alibaba.nacos
+ nacos-client
+ 2.1.1
+
+
+
+ com.alibaba.nacos
+ nacos-spring-context
+ 1.1.1
+ provided
+
+
+
+
\ No newline at end of file
diff --git a/smart-flow-integration/smart-flow-integration-nacos/src/main/java/org/smartboot/flow/integration/nacos/NacosConfiguration.java b/smart-flow-integration/smart-flow-integration-nacos/src/main/java/org/smartboot/flow/integration/nacos/NacosConfiguration.java
new file mode 100644
index 0000000000000000000000000000000000000000..c8a4b27e873e8e35179f2e0f8546d71151f2ebce
--- /dev/null
+++ b/smart-flow-integration/smart-flow-integration-nacos/src/main/java/org/smartboot/flow/integration/nacos/NacosConfiguration.java
@@ -0,0 +1,61 @@
+package org.smartboot.flow.integration.nacos;
+
+import com.alibaba.nacos.api.config.ConfigService;
+
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * @author qinluo
+ * @date 2023-08-09 10:44:55
+ * @since 1.1.3
+ */
+public class NacosConfiguration {
+
+ protected ConfigService configService;
+
+ protected String dataId;
+ protected String engine;
+ protected String groupId = "DEFAULT_GROUP";
+ protected Map nacosProperties = new HashMap<>();
+
+ public String getDataId() {
+ return dataId;
+ }
+
+ public void setDataId(String dataId) {
+ this.dataId = dataId;
+ }
+
+ public String getEngine() {
+ return engine;
+ }
+
+ public void setEngine(String engine) {
+ this.engine = engine;
+ }
+
+ public String getGroupId() {
+ return groupId;
+ }
+
+ public void setGroupId(String groupId) {
+ this.groupId = groupId;
+ }
+
+ public Map getNacosProperties() {
+ return nacosProperties;
+ }
+
+ public void setNacosProperties(Map nacosProperties) {
+ this.nacosProperties = nacosProperties;
+ }
+
+ public ConfigService getConfigService() {
+ return configService;
+ }
+
+ public void setConfigService(ConfigService configService) {
+ this.configService = configService;
+ }
+}
diff --git a/smart-flow-integration/smart-flow-integration-nacos/src/main/java/org/smartboot/flow/integration/nacos/NacosFlowUtil.java b/smart-flow-integration/smart-flow-integration-nacos/src/main/java/org/smartboot/flow/integration/nacos/NacosFlowUtil.java
new file mode 100644
index 0000000000000000000000000000000000000000..d79610da4030c530878f8aca4c91cc84e2c99ca7
--- /dev/null
+++ b/smart-flow-integration/smart-flow-integration-nacos/src/main/java/org/smartboot/flow/integration/nacos/NacosFlowUtil.java
@@ -0,0 +1,51 @@
+package org.smartboot.flow.integration.nacos;
+
+import com.alibaba.nacos.api.NacosFactory;
+import com.alibaba.nacos.api.config.ConfigService;
+import com.alibaba.nacos.spring.beans.factory.annotation.ConfigServiceBeanBuilder;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.smartboot.flow.core.util.BeanUtils;
+
+import java.util.Map;
+import java.util.Properties;
+
+/**
+ * @author qinluo
+ * @date 2023-08-09 14:09:03
+ * @since 1.1.3
+ */
+class NacosFlowUtil {
+
+ private static final Logger LOGGER = LoggerFactory.getLogger(NacosFlowUtil.class);
+
+ static ConfigService createCfgService(Map properties) {
+ // 检查从bean上下文中是否能获取到configServiceFactory.
+ ConfigService cfgService = createWithBeanCtx(properties);
+
+ try {
+ if (cfgService == null) {
+ Properties prop = new Properties();
+ prop.putAll(properties);
+ return NacosFactory.createConfigService(prop);
+ }
+ } catch (Exception e) {
+ LOGGER.error("create nacos config service failed, properties = {}", properties, e);
+ }
+
+ return cfgService;
+ }
+
+
+ private static ConfigService createWithBeanCtx(Map properties) {
+
+ try {
+ ConfigServiceBeanBuilder beanBuilder = BeanUtils.getBean(ConfigServiceBeanBuilder.BEAN_NAME);
+ return beanBuilder.build(properties);
+ } catch (Throwable ignored) {
+
+ }
+
+ return null;
+ }
+}
diff --git a/smart-flow-integration/smart-flow-integration-nacos/src/main/java/org/smartboot/flow/integration/nacos/NacosWatcher.java b/smart-flow-integration/smart-flow-integration-nacos/src/main/java/org/smartboot/flow/integration/nacos/NacosWatcher.java
new file mode 100644
index 0000000000000000000000000000000000000000..a7d522847768642938deb35f450b0ec12f392f80
--- /dev/null
+++ b/smart-flow-integration/smart-flow-integration-nacos/src/main/java/org/smartboot/flow/integration/nacos/NacosWatcher.java
@@ -0,0 +1,85 @@
+package org.smartboot.flow.integration.nacos;
+
+import com.alibaba.nacos.api.config.listener.AbstractListener;
+import com.alibaba.nacos.api.exception.NacosException;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.smartboot.flow.core.util.AssertUtil;
+import org.smartboot.flow.core.util.BeanUtils;
+import org.smartboot.flow.manager.reload.MemoryXmlSelector;
+import org.smartboot.flow.manager.reload.ReloadWatcher;
+import org.smartboot.flow.manager.reload.Reloader;
+import org.smartboot.flow.manager.reload.XmlParseReloader;
+
+import javax.annotation.PostConstruct;
+
+/**
+ * @author qinluo
+ * @date 2023-08-09 10:44:55
+ * @since 1.1.3
+ */
+public class NacosWatcher extends NacosConfiguration implements ReloadWatcher {
+
+ private static final Logger LOGGER = LoggerFactory.getLogger(NacosWatcher.class);
+
+ private Reloader reloader = new XmlParseReloader();
+
+ private NacosXmlSelector notifier;
+
+ /**
+ * For reflection.
+ */
+ public NacosWatcher() {
+ }
+
+ public NacosWatcher(NacosXmlSelector notifier) {
+ this.notifier = notifier;
+ }
+
+ private void init() {
+ if (configService == null) {
+ configService = NacosFlowUtil.createCfgService(nacosProperties);
+ AssertUtil.notNull(configService, "nacos config service must not be null!");
+ }
+
+ if (reloader == null) {
+ reloader = BeanUtils.getBean(Reloader.class);
+ }
+
+ if (reloader == null) {
+ XmlParseReloader r = new XmlParseReloader();
+ r.setAssemble(true);
+ reloader = r;
+ }
+ }
+
+ @PostConstruct
+ public void start() {
+ init();
+
+ try {
+ configService.addListener(dataId, groupId, new AbstractListener() {
+ @Override
+ public void receiveConfigInfo(String configInfo) {
+ if (notifier != null) {
+ notifier.notifyContentReceived();
+ }
+
+ MemoryXmlSelector.updateContent(engine, configInfo);
+ reloader.reload(engine);
+ }
+ });
+ } catch (NacosException e) {
+ LOGGER.error("add nacos watcher failed, groupId = {}, dataId = {}, engine = {}", groupId, dataId, engine, e);
+ }
+
+ }
+
+ public Reloader getReloader() {
+ return reloader;
+ }
+
+ public void setReloader(Reloader reloader) {
+ this.reloader = reloader;
+ }
+}
diff --git a/smart-flow-integration/smart-flow-integration-nacos/src/main/java/org/smartboot/flow/integration/nacos/NacosXmlSelector.java b/smart-flow-integration/smart-flow-integration-nacos/src/main/java/org/smartboot/flow/integration/nacos/NacosXmlSelector.java
new file mode 100644
index 0000000000000000000000000000000000000000..e25329570421f62ee7b45ca3717a39ce7455293c
--- /dev/null
+++ b/smart-flow-integration/smart-flow-integration-nacos/src/main/java/org/smartboot/flow/integration/nacos/NacosXmlSelector.java
@@ -0,0 +1,74 @@
+package org.smartboot.flow.integration.nacos;
+
+import org.smartboot.flow.core.util.AssertUtil;
+import org.smartboot.flow.manager.reload.ReloadWatcher;
+import org.smartboot.flow.manager.reload.XmlSelector;
+
+import javax.annotation.PostConstruct;
+
+/**
+ * @author qinluo
+ * @date 2023-08-09 10:44:55
+ * @since 1.1.3
+ */
+public class NacosXmlSelector extends NacosConfiguration implements XmlSelector, ReloadWatcher {
+
+ private boolean enableWatcher;
+ private boolean fetch = true;
+ private volatile boolean initialized = false;
+ private final NacosWatcher watcher = new NacosWatcher(this);
+ private volatile boolean enabledWatcher = false;
+
+ @PostConstruct
+ public synchronized void init() {
+ if (initialized) {
+ return;
+ }
+
+ if (configService == null) {
+ configService = NacosFlowUtil.createCfgService(nacosProperties);
+ AssertUtil.notNull(configService, "nacos config service must not be null!");
+ }
+
+ watcher.setConfigService(configService);
+ watcher.setEngine(engine);
+ watcher.setGroupId(groupId);
+ watcher.setNacosProperties(nacosProperties);
+ watcher.setDataId(dataId);
+
+ initialized = true;
+ }
+
+ @Override
+ public String select(String engineName) {
+ init();
+
+ String content = null;
+
+ try {
+ if (fetch) {
+ content = configService.getConfig(dataId, groupId, 1000);
+ }
+
+ if (enableWatcher && !enabledWatcher) {
+ watcher.start();
+ enabledWatcher = true;
+ }
+ } catch (Exception ignored) {
+
+ }
+ return content;
+ }
+
+ public boolean getEnableWatcher() {
+ return enableWatcher;
+ }
+
+ public void setEnableWatcher(boolean enableWatcher) {
+ this.enableWatcher = enableWatcher;
+ }
+
+ void notifyContentReceived() {
+ this.fetch = false;
+ }
+}
diff --git a/smart-flow-spring-extension/pom.xml b/smart-flow-integration/smart-flow-spring-extension/pom.xml
similarity index 90%
rename from smart-flow-spring-extension/pom.xml
rename to smart-flow-integration/smart-flow-spring-extension/pom.xml
index 14ad1b038395ccc208d24039aa64681f2aa8e121..fb1a35e713cf17272a45522ee9621efb61b663d8 100644
--- a/smart-flow-spring-extension/pom.xml
+++ b/smart-flow-integration/smart-flow-spring-extension/pom.xml
@@ -3,9 +3,9 @@
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
- smart-flow-parent
+ smart-flow-integration
org.smartboot.flow
- 1.1.2
+ 1.1.3
4.0.0
@@ -15,6 +15,7 @@
8
8
5.3.23
+ UTF-8
diff --git a/smart-flow-spring-extension/src/main/java/org/smartboot/flow/spring/extension/BeanDefinitionRegister.java b/smart-flow-integration/smart-flow-spring-extension/src/main/java/org/smartboot/flow/spring/extension/BeanDefinitionRegister.java
similarity index 100%
rename from smart-flow-spring-extension/src/main/java/org/smartboot/flow/spring/extension/BeanDefinitionRegister.java
rename to smart-flow-integration/smart-flow-spring-extension/src/main/java/org/smartboot/flow/spring/extension/BeanDefinitionRegister.java
diff --git a/smart-flow-spring-extension/src/main/java/org/smartboot/flow/spring/extension/BeanDefinitionVisitor.java b/smart-flow-integration/smart-flow-spring-extension/src/main/java/org/smartboot/flow/spring/extension/BeanDefinitionVisitor.java
similarity index 98%
rename from smart-flow-spring-extension/src/main/java/org/smartboot/flow/spring/extension/BeanDefinitionVisitor.java
rename to smart-flow-integration/smart-flow-spring-extension/src/main/java/org/smartboot/flow/spring/extension/BeanDefinitionVisitor.java
index 1b305152ef82df5ba9d0b68bd38cf8cbf03d7371..f1d9b80fdc2a0fcffdd7cbcde719388156b1b5b1 100644
--- a/smart-flow-spring-extension/src/main/java/org/smartboot/flow/spring/extension/BeanDefinitionVisitor.java
+++ b/smart-flow-integration/smart-flow-spring-extension/src/main/java/org/smartboot/flow/spring/extension/BeanDefinitionVisitor.java
@@ -1,7 +1,6 @@
package org.smartboot.flow.spring.extension;
import org.smartboot.flow.core.attribute.AttributeHolder;
-import org.smartboot.flow.core.attribute.AttributeValueResolver;
import org.smartboot.flow.core.attribute.Attributes;
import org.smartboot.flow.core.executable.DecorateExecutable;
import org.smartboot.flow.core.parser.DefinitionVisitor;
@@ -47,6 +46,8 @@ import java.util.stream.Collectors;
*/
public class BeanDefinitionVisitor implements DefinitionVisitor, BeanFactoryAware {
+ public static final String NAME = BeanDefinitionVisitor.class.getName();
+
private ParserContext context;
/**
@@ -167,23 +168,15 @@ public class BeanDefinitionVisitor implements DefinitionVisitor, BeanFactoryAwar
private void appendAttributes(ComponentDefinition ed, RootBeanDefinition definition) {
List attributes = ed.getAttributes();
- AttributeValueResolver resolver = AttributeValueResolver.getInstance();
for (AttributeHolder holder : attributes) {
Attributes attribute = holder.getAttribute();
-
- try {
- Object resolved = resolver.resolve(attribute, holder.getValue());
- holder.setValue(resolved);
- } catch (Exception ignored) {
-
- }
-
if (attribute == Attributes.NAME
|| attribute == Attributes.DEGRADE_CALLBACK
|| !attribute.isVisible()) {
continue;
}
+
PropertyValue value = new PropertyValue(attribute.getName(), holder.getValue());
definition.getPropertyValues().addPropertyValue(value);
}
diff --git a/smart-flow-spring-extension/src/main/java/org/smartboot/flow/spring/extension/EnableReloadNotify.java b/smart-flow-integration/smart-flow-spring-extension/src/main/java/org/smartboot/flow/spring/extension/EasySmartFlow.java
similarity index 92%
rename from smart-flow-spring-extension/src/main/java/org/smartboot/flow/spring/extension/EnableReloadNotify.java
rename to smart-flow-integration/smart-flow-spring-extension/src/main/java/org/smartboot/flow/spring/extension/EasySmartFlow.java
index 1b8ea79a729a66379bec6dc21207b5fb9405b712..f2b47a6720448e0860233245cd58a284ef849b63 100644
--- a/smart-flow-spring-extension/src/main/java/org/smartboot/flow/spring/extension/EnableReloadNotify.java
+++ b/smart-flow-integration/smart-flow-spring-extension/src/main/java/org/smartboot/flow/spring/extension/EasySmartFlow.java
@@ -17,5 +17,5 @@ import java.lang.annotation.Target;
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Import(SmartFlowRegistrar.class)
-public @interface EnableReloadNotify {
+public @interface EasySmartFlow {
}
diff --git a/smart-flow-spring-extension/src/main/java/org/smartboot/flow/spring/extension/EngineInitializer.java b/smart-flow-integration/smart-flow-spring-extension/src/main/java/org/smartboot/flow/spring/extension/EngineInitializer.java
similarity index 97%
rename from smart-flow-spring-extension/src/main/java/org/smartboot/flow/spring/extension/EngineInitializer.java
rename to smart-flow-integration/smart-flow-spring-extension/src/main/java/org/smartboot/flow/spring/extension/EngineInitializer.java
index 1cc239be58183a9a3190c04ef498fda04f6188d1..a10dbebe5b363f5bbf4a4ea89dcffaa1e53bb567 100644
--- a/smart-flow-spring-extension/src/main/java/org/smartboot/flow/spring/extension/EngineInitializer.java
+++ b/smart-flow-integration/smart-flow-spring-extension/src/main/java/org/smartboot/flow/spring/extension/EngineInitializer.java
@@ -6,6 +6,7 @@ import org.smartboot.flow.manager.NullReloader;
import org.smartboot.flow.manager.reload.Reloader;
import org.springframework.beans.factory.config.BeanPostProcessor;
+import javax.annotation.PostConstruct;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
@@ -27,6 +28,7 @@ public class EngineInitializer implements BeanPostProcessor {
*/
private Reloader defaultReloader = NullReloader.NULL;
+ @PostConstruct
public void start() {
for (Map.Entry entry : engines.entrySet()) {
Reloader reloader = entry.getValue();
diff --git a/smart-flow-spring-extension/src/main/java/org/smartboot/flow/spring/extension/NameAwareCondition.java b/smart-flow-integration/smart-flow-spring-extension/src/main/java/org/smartboot/flow/spring/extension/NameAwareCondition.java
similarity index 100%
rename from smart-flow-spring-extension/src/main/java/org/smartboot/flow/spring/extension/NameAwareCondition.java
rename to smart-flow-integration/smart-flow-spring-extension/src/main/java/org/smartboot/flow/spring/extension/NameAwareCondition.java
diff --git a/smart-flow-spring-extension/src/main/java/org/smartboot/flow/spring/extension/NamedAbstractExecutable.java b/smart-flow-integration/smart-flow-spring-extension/src/main/java/org/smartboot/flow/spring/extension/NamedAbstractExecutable.java
similarity index 100%
rename from smart-flow-spring-extension/src/main/java/org/smartboot/flow/spring/extension/NamedAbstractExecutable.java
rename to smart-flow-integration/smart-flow-spring-extension/src/main/java/org/smartboot/flow/spring/extension/NamedAbstractExecutable.java
diff --git a/smart-flow-spring-extension/src/main/java/org/smartboot/flow/spring/extension/NotifierProcessor.java b/smart-flow-integration/smart-flow-spring-extension/src/main/java/org/smartboot/flow/spring/extension/NotifierProcessor.java
similarity index 85%
rename from smart-flow-spring-extension/src/main/java/org/smartboot/flow/spring/extension/NotifierProcessor.java
rename to smart-flow-integration/smart-flow-spring-extension/src/main/java/org/smartboot/flow/spring/extension/NotifierProcessor.java
index bbd464e51f7d36ca3ccd8e2ba8bd968d24782fad..0904b2d49c18a931ff830981571b9005992da161 100644
--- a/smart-flow-spring-extension/src/main/java/org/smartboot/flow/spring/extension/NotifierProcessor.java
+++ b/smart-flow-integration/smart-flow-spring-extension/src/main/java/org/smartboot/flow/spring/extension/NotifierProcessor.java
@@ -8,7 +8,6 @@ import org.springframework.beans.BeansException;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.BeanFactoryAware;
import org.springframework.beans.factory.config.BeanPostProcessor;
-import org.springframework.beans.factory.support.DefaultListableBeanFactory;
import org.springframework.util.ReflectionUtils;
import java.util.Arrays;
@@ -23,6 +22,7 @@ import java.util.Map;
public class NotifierProcessor implements BeanPostProcessor, BeanFactoryAware {
private static final Logger LOGGER = LoggerFactory.getLogger(NotifierProcessor.class);
+ public static final String NAME = SmartFlowBeanFactoryRegistry.class.getName();
private ReflectionNotifier notifier;
@@ -53,11 +53,7 @@ public class NotifierProcessor implements BeanPostProcessor, BeanFactoryAware {
@Override
public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
- if (beanFactory instanceof DefaultListableBeanFactory) {
- ((DefaultListableBeanFactory)beanFactory).setAllowBeanDefinitionOverriding(true);
- notifier = new ReflectionNotifier(beanFactory);
- notifier.register();
- }
-
+ 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-integration/smart-flow-spring-extension/src/main/java/org/smartboot/flow/spring/extension/ProxyParser.java
similarity index 100%
rename from smart-flow-spring-extension/src/main/java/org/smartboot/flow/spring/extension/ProxyParser.java
rename to smart-flow-integration/smart-flow-spring-extension/src/main/java/org/smartboot/flow/spring/extension/ProxyParser.java
diff --git a/smart-flow-spring-extension/src/main/java/org/smartboot/flow/spring/extension/ReflectionNotifier.java b/smart-flow-integration/smart-flow-spring-extension/src/main/java/org/smartboot/flow/spring/extension/ReflectionNotifier.java
similarity index 78%
rename from smart-flow-spring-extension/src/main/java/org/smartboot/flow/spring/extension/ReflectionNotifier.java
rename to smart-flow-integration/smart-flow-spring-extension/src/main/java/org/smartboot/flow/spring/extension/ReflectionNotifier.java
index 4af2547386ce2e3b8cb77d02a9c10abdd24a0019..4e452895c5f3bc34b68f1e2965bfc467e31eca65 100644
--- a/smart-flow-spring-extension/src/main/java/org/smartboot/flow/spring/extension/ReflectionNotifier.java
+++ b/smart-flow-integration/smart-flow-spring-extension/src/main/java/org/smartboot/flow/spring/extension/ReflectionNotifier.java
@@ -1,8 +1,9 @@
package org.smartboot.flow.spring.extension;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
import org.smartboot.flow.core.FlowEngine;
import org.smartboot.flow.core.manager.EngineManager;
-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;
@@ -21,6 +22,8 @@ import java.util.concurrent.CopyOnWriteArrayList;
*/
public class ReflectionNotifier implements ReloadListener {
+ private static final Logger LOGGER = LoggerFactory.getLogger(ReflectionNotifier.class);
+
private final BeanFactory factory;
private final List notifiers = new CopyOnWriteArrayList<>();
@@ -41,22 +44,17 @@ public class ReflectionNotifier implements ReloadListener {
FlowEngine, ?> engineInstance = null;
FlowEngine, ?> springEngine = null;
- FlowEngine, ?> managerEngine = null;
+ FlowEngine, ?> managerEngine = EngineManager.getEngine(engineName);
try {
springEngine = (FlowEngine, ?>)factory.getBean(engineName);
} catch (Exception ex) {
// do-nothing
}
- EngineModel engineModel = EngineManager.defaultManager().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()) {
+ if (springEngine.getStartedAt() >= managerEngine.getStartedAt()) {
engineInstance = springEngine;
} else if(springEngine.getStartedAt() < managerEngine.getStartedAt()){
engineInstance = managerEngine;
@@ -98,6 +96,8 @@ public class ReflectionNotifier implements ReloadListener {
if (FlowEngine.class.isAssignableFrom(f.getType())) {
ReflectionUtils.setField(f, bean, engineInstance);
+ LOGGER.info("reload-notify engine {}({}) to field {}#{}",
+ engineName, engineInstance.getStartedAt(), f.getDeclaringClass().getSimpleName(), f.getName());
} else if ((Map.class.isAssignableFrom(f.getType()))) {
Map engines = (Map)ReflectionUtils.getField(f, bean);
if (engines == null) {
@@ -107,6 +107,9 @@ public class ReflectionNotifier implements ReloadListener {
Object o = engines.get(engineName);
if (o instanceof FlowEngine) {
engines.put(engineName, engineInstance);
+
+ LOGGER.info("reload-notify engine {}({}) to field {}#{}",
+ engineName, engineInstance.getStartedAt(), f.getDeclaringClass().getSimpleName(), f.getName());
}
}
@@ -114,4 +117,14 @@ public class ReflectionNotifier implements ReloadListener {
}
}
+
+ @Override
+ public boolean equals(Object obj) {
+ return obj instanceof ReflectionNotifier;
+ }
+
+ @Override
+ public int hashCode() {
+ return ReflectionNotifier.class.hashCode();
+ }
}
diff --git a/smart-flow-spring-extension/src/main/java/org/smartboot/flow/spring/extension/ReloadNotify.java b/smart-flow-integration/smart-flow-spring-extension/src/main/java/org/smartboot/flow/spring/extension/ReloadNotify.java
similarity index 100%
rename from smart-flow-spring-extension/src/main/java/org/smartboot/flow/spring/extension/ReloadNotify.java
rename to smart-flow-integration/smart-flow-spring-extension/src/main/java/org/smartboot/flow/spring/extension/ReloadNotify.java
diff --git a/smart-flow-spring-extension/src/main/java/org/smartboot/flow/spring/extension/SmartFlowBeanFactoryRegistry.java b/smart-flow-integration/smart-flow-spring-extension/src/main/java/org/smartboot/flow/spring/extension/SmartFlowBeanFactoryRegistry.java
similarity index 45%
rename from smart-flow-spring-extension/src/main/java/org/smartboot/flow/spring/extension/SmartFlowBeanFactoryRegistry.java
rename to smart-flow-integration/smart-flow-spring-extension/src/main/java/org/smartboot/flow/spring/extension/SmartFlowBeanFactoryRegistry.java
index 559dfd833e23ad51b4653a554f6fc996a5c8d643..2ab733f24458025e5895e26daea7a4dd70896a19 100644
--- a/smart-flow-spring-extension/src/main/java/org/smartboot/flow/spring/extension/SmartFlowBeanFactoryRegistry.java
+++ b/smart-flow-integration/smart-flow-spring-extension/src/main/java/org/smartboot/flow/spring/extension/SmartFlowBeanFactoryRegistry.java
@@ -1,10 +1,18 @@
package org.smartboot.flow.spring.extension;
import org.smartboot.flow.core.parser.ParserContext;
+import org.smartboot.flow.core.util.AuxiliaryUtils;
+import org.smartboot.flow.manager.reload.XmlParseReloader;
import org.springframework.beans.BeansException;
+import org.springframework.beans.PropertyValue;
+import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
+import org.springframework.beans.factory.config.RuntimeBeanReference;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.beans.factory.support.BeanDefinitionRegistryPostProcessor;
+import org.springframework.beans.factory.support.DefaultListableBeanFactory;
+
+import java.util.stream.Stream;
/**
* @author qinluo
@@ -14,14 +22,33 @@ import org.springframework.beans.factory.support.BeanDefinitionRegistryPostProce
public class SmartFlowBeanFactoryRegistry implements BeanDefinitionRegistryPostProcessor {
private BeanDefinitionRegistry registry;
+ public static final String NAME = SmartFlowBeanFactoryRegistry.class.getName();
@Override
public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {
this.registry = registry;
+ SmartFlowRegistrar.registerAll(registry, NAME);
}
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
+ String[] beanNames = beanFactory.getBeanDefinitionNames();
+ Stream.of(beanNames).forEach(p -> {
+ BeanDefinition beanDefinition = beanFactory.getBeanDefinition(p);
+ Class> type = AuxiliaryUtils.asClass(beanDefinition.getBeanClassName());
+ if (type != null && XmlParseReloader.class.isAssignableFrom(type)) {
+ PropertyValue visitor = beanDefinition.getPropertyValues().getPropertyValue("visitor");
+ if (visitor == null) {
+ beanDefinition.getPropertyValues().addPropertyValue("visitor", new RuntimeBeanReference(BeanDefinitionVisitor.NAME));
+ }
+
+ PropertyValue creator = beanDefinition.getPropertyValues().getPropertyValue("objectCreator");
+ if (creator == null) {
+ beanDefinition.getPropertyValues().addPropertyValue("objectCreator", new RuntimeBeanReference(SpringObjectCreator.NAME));
+ }
+ }
+ });
+
try {
// Touch visit all parsed elements after all bean definition loaded.
ParserContext ctx = ProxyParser.getInstance().getContext();
@@ -34,5 +61,9 @@ public class SmartFlowBeanFactoryRegistry implements BeanDefinitionRegistryPostP
} finally {
ProxyParser.getInstance().reset();
}
+
+ if (beanFactory instanceof DefaultListableBeanFactory) {
+ ((DefaultListableBeanFactory)beanFactory).setAllowBeanDefinitionOverriding(true);
+ }
}
}
diff --git a/smart-flow-integration/smart-flow-spring-extension/src/main/java/org/smartboot/flow/spring/extension/SmartFlowRegistrar.java b/smart-flow-integration/smart-flow-spring-extension/src/main/java/org/smartboot/flow/spring/extension/SmartFlowRegistrar.java
new file mode 100644
index 0000000000000000000000000000000000000000..58d17240732cb05b9e59c91250a2e5f4569482f1
--- /dev/null
+++ b/smart-flow-integration/smart-flow-spring-extension/src/main/java/org/smartboot/flow/spring/extension/SmartFlowRegistrar.java
@@ -0,0 +1,55 @@
+package org.smartboot.flow.spring.extension;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.smartboot.flow.manager.reload.XmlParseReloader;
+import org.springframework.beans.factory.support.BeanDefinitionRegistry;
+import org.springframework.beans.factory.support.RootBeanDefinition;
+import org.springframework.context.annotation.ImportBeanDefinitionRegistrar;
+import org.springframework.core.type.AnnotationMetadata;
+
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * @author qinluo
+ * @date 2023/1/31 22:15
+ * @since 1.0.0
+ */
+public class SmartFlowRegistrar implements ImportBeanDefinitionRegistrar {
+
+ private static final Logger LOGGER = LoggerFactory.getLogger(SmartFlowRegistrar.class);
+
+ private static final Map> registeredClasses = new HashMap<>();
+
+ static {
+ registeredClasses.put(NotifierProcessor.NAME, NotifierProcessor.class);
+ registeredClasses.put(SmartFlowBeanFactoryRegistry.NAME, SmartFlowBeanFactoryRegistry.class);
+ registeredClasses.put(BeanDefinitionVisitor.NAME, BeanDefinitionVisitor.class);
+ registeredClasses.put(SpringObjectCreator.NAME, SpringObjectCreator.class);
+ registeredClasses.put(SpringBeanContextAdapter.NAME, SpringBeanContextAdapter.class);
+ registeredClasses.put(XmlParseReloader.class.getName(), XmlParseReloader.class);
+ }
+
+ @Override
+ public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
+ registerAll(registry);
+ }
+
+ public static void registerAll(BeanDefinitionRegistry registry, String ...excludes) {
+ List excludeBeans = excludes != null ? Arrays.asList(excludes) : Collections.emptyList();
+
+ registeredClasses.forEach((k, v) -> {
+ if (registry.containsBeanDefinition(k) || excludeBeans.contains(k)) {
+ return;
+ }
+ RootBeanDefinition definition = new RootBeanDefinition();
+ definition.setBeanClass(v);
+ registry.registerBeanDefinition(k, definition);
+ LOGGER.info("register to spring container [{}]", k);
+ });
+ }
+}
diff --git a/smart-flow-integration/smart-flow-spring-extension/src/main/java/org/smartboot/flow/spring/extension/SpringBeanContextAdapter.java b/smart-flow-integration/smart-flow-spring-extension/src/main/java/org/smartboot/flow/spring/extension/SpringBeanContextAdapter.java
new file mode 100644
index 0000000000000000000000000000000000000000..43526eb6ede599c7031e276646d610c50190a406
--- /dev/null
+++ b/smart-flow-integration/smart-flow-spring-extension/src/main/java/org/smartboot/flow/spring/extension/SpringBeanContextAdapter.java
@@ -0,0 +1,55 @@
+package org.smartboot.flow.spring.extension;
+
+import org.smartboot.flow.core.util.BeanContext;
+import org.springframework.beans.BeansException;
+import org.springframework.beans.factory.config.BeanPostProcessor;
+import org.springframework.context.ApplicationContext;
+import org.springframework.context.ApplicationContextAware;
+import org.springframework.core.Ordered;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * @author qinluo
+ * @date 2022-12-21 14:22:23
+ * @since 1.1.3
+ */
+public class SpringBeanContextAdapter implements BeanContext, ApplicationContextAware, BeanPostProcessor, Ordered {
+
+ public static final String NAME = SpringBeanContextAdapter.class.getName();
+
+ private ApplicationContext ctx;
+
+ @Override
+ public T getBean(String name) {
+ return (T)ctx.getBean(name);
+ }
+
+ @Override
+ public T getBean(String name, Class type) {
+ return ctx.getBean(name, type);
+ }
+
+ @Override
+ public List getBean(Class type) {
+ String[] beanNamesForType = ctx.getBeanNamesForType(type);
+ List objects = new ArrayList<>();
+ for (String name : beanNamesForType) {
+ objects.add(ctx.getBean(name, type));
+ }
+
+ return objects;
+ }
+
+ @Override
+ public void setApplicationContext(ApplicationContext ctx) throws BeansException {
+ this.ctx = ctx;
+ this.init();
+ }
+
+ @Override
+ public int getOrder() {
+ return 0;
+ }
+}
diff --git a/smart-flow-spring-extension/src/main/java/org/smartboot/flow/spring/extension/SpringIdentifierManager.java b/smart-flow-integration/smart-flow-spring-extension/src/main/java/org/smartboot/flow/spring/extension/SpringIdentifierManager.java
similarity index 100%
rename from smart-flow-spring-extension/src/main/java/org/smartboot/flow/spring/extension/SpringIdentifierManager.java
rename to smart-flow-integration/smart-flow-spring-extension/src/main/java/org/smartboot/flow/spring/extension/SpringIdentifierManager.java
diff --git a/smart-flow-spring-extension/src/main/java/org/smartboot/flow/spring/extension/SpringNamespaceHandler.java b/smart-flow-integration/smart-flow-spring-extension/src/main/java/org/smartboot/flow/spring/extension/SpringNamespaceHandler.java
similarity index 100%
rename from smart-flow-spring-extension/src/main/java/org/smartboot/flow/spring/extension/SpringNamespaceHandler.java
rename to smart-flow-integration/smart-flow-spring-extension/src/main/java/org/smartboot/flow/spring/extension/SpringNamespaceHandler.java
diff --git a/smart-flow-spring-extension/src/main/java/org/smartboot/flow/spring/extension/SpringObjectCreator.java b/smart-flow-integration/smart-flow-spring-extension/src/main/java/org/smartboot/flow/spring/extension/SpringObjectCreator.java
similarity index 93%
rename from smart-flow-spring-extension/src/main/java/org/smartboot/flow/spring/extension/SpringObjectCreator.java
rename to smart-flow-integration/smart-flow-spring-extension/src/main/java/org/smartboot/flow/spring/extension/SpringObjectCreator.java
index 242e1e354a2aeecf01bb3f65a3bb35475c4d36c2..ac0d3e067b0c286195df8a24d57b975824996277 100644
--- a/smart-flow-spring-extension/src/main/java/org/smartboot/flow/spring/extension/SpringObjectCreator.java
+++ b/smart-flow-integration/smart-flow-spring-extension/src/main/java/org/smartboot/flow/spring/extension/SpringObjectCreator.java
@@ -13,6 +13,8 @@ import org.springframework.context.ApplicationContextAware;
*/
public class SpringObjectCreator implements ObjectCreator, ApplicationContextAware {
+ public static final String NAME = SpringObjectCreator.class.getName();
+
private ApplicationContext ctx;
@Override
diff --git a/smart-flow-spring-extension/src/main/resources/META-INF/spring.handlers b/smart-flow-integration/smart-flow-spring-extension/src/main/resources/META-INF/spring.handlers
similarity index 100%
rename from smart-flow-spring-extension/src/main/resources/META-INF/spring.handlers
rename to smart-flow-integration/smart-flow-spring-extension/src/main/resources/META-INF/spring.handlers
diff --git a/smart-flow-spring-extension/src/main/resources/META-INF/spring.schemas b/smart-flow-integration/smart-flow-spring-extension/src/main/resources/META-INF/spring.schemas
similarity index 100%
rename from smart-flow-spring-extension/src/main/resources/META-INF/spring.schemas
rename to smart-flow-integration/smart-flow-spring-extension/src/main/resources/META-INF/spring.schemas
diff --git a/smart-flow-springboot-starter/pom.xml b/smart-flow-integration/smart-flow-springboot-starter/pom.xml
similarity index 86%
rename from smart-flow-springboot-starter/pom.xml
rename to smart-flow-integration/smart-flow-springboot-starter/pom.xml
index e90b4f57e05151d46a898d3a80be750e3835c392..767f59a7d8a96d65ef996b0aadbfa7c26b41aba1 100644
--- a/smart-flow-springboot-starter/pom.xml
+++ b/smart-flow-integration/smart-flow-springboot-starter/pom.xml
@@ -3,9 +3,9 @@
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
- smart-flow-parent
+ smart-flow-integration
org.smartboot.flow
- 1.1.2
+ 1.1.3
4.0.0
@@ -14,6 +14,7 @@
8
8
+ UTF-8
diff --git a/smart-flow-springboot-starter/src/main/java/org/smartboot/flow/springboot/extension/FlowReloadConfiguration.java b/smart-flow-integration/smart-flow-springboot-starter/src/main/java/org/smartboot/flow/springboot/extension/FlowDatabaseXmlSelectorConfiguration.java
similarity index 45%
rename from smart-flow-springboot-starter/src/main/java/org/smartboot/flow/springboot/extension/FlowReloadConfiguration.java
rename to smart-flow-integration/smart-flow-springboot-starter/src/main/java/org/smartboot/flow/springboot/extension/FlowDatabaseXmlSelectorConfiguration.java
index fad3f1a86e686090e1c8e2d52c4840cde1584bdf..459710e534a42e5f7736d451fe907075b294f224 100644
--- a/smart-flow-springboot-starter/src/main/java/org/smartboot/flow/springboot/extension/FlowReloadConfiguration.java
+++ b/smart-flow-integration/smart-flow-springboot-starter/src/main/java/org/smartboot/flow/springboot/extension/FlowDatabaseXmlSelectorConfiguration.java
@@ -1,17 +1,9 @@
package org.smartboot.flow.springboot.extension;
-import org.smartboot.flow.core.parser.ObjectCreator;
-import org.smartboot.flow.manager.reload.Reloader;
import org.smartboot.flow.manager.reload.SqlXmlSelector;
-import org.smartboot.flow.manager.reload.XmlParseReloader;
import org.smartboot.flow.manager.reload.XmlSelector;
-import org.smartboot.flow.spring.extension.BeanDefinitionVisitor;
-import org.smartboot.flow.spring.extension.SpringObjectCreator;
-import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
-import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.ConfigurationProperties;
-import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@@ -22,15 +14,9 @@ import org.springframework.context.annotation.Configuration;
* @since 2022/12/15 16:32
*/
@Configuration
-@ConfigurationProperties(prefix = "smart.flow.manage.reload")
-@ConditionalOnProperty(name = "smart.flow.manage.reload.enable", havingValue = "true")
-public class FlowReloadConfiguration {
-
-
- /**
- * Assemble engine after reload.
- */
- private boolean assemble;
+@ConfigurationProperties(prefix = "smart.flow.selector")
+@ConditionalOnProperty(name = "smart.flow.selector.datasource.url")
+public class FlowDatabaseXmlSelectorConfiguration {
/**
* Selector datasource config.
@@ -83,26 +69,7 @@ public class FlowReloadConfiguration {
}
}
-
- @ConditionalOnProperty(name = "smart.flow.manage.reload.spring-object-creator", havingValue = "true")
- @ConditionalOnMissingBean(ObjectCreator.class)
- @Bean("springObjectCreator")
- public ObjectCreator getSpringObjectCreator(ApplicationContext ctx) {
- SpringObjectCreator soc = new SpringObjectCreator();
- soc.setApplicationContext(ctx);
- return soc;
- }
-
- @ConditionalOnMissingBean(BeanDefinitionVisitor.class)
- @Bean("beanDefVisitor")
- public BeanDefinitionVisitor getVisitor(ApplicationContext ctx) {
- BeanDefinitionVisitor visitor = new BeanDefinitionVisitor();
- visitor.setBeanFactory(ctx);
- return visitor;
- }
-
- @ConditionalOnProperty(name = "smart.flow.manage.reload.datasource.url")
- @Bean("xmlSelector")
+ @Bean("databaseXmlSelector")
public XmlSelector getXmlSelector() {
SqlXmlSelector selector = new SqlXmlSelector();
@@ -116,40 +83,6 @@ public class FlowReloadConfiguration {
return selector;
}
- @Bean
- @ConditionalOnBean(XmlSelector.class)
- public Reloader getReloader(ApplicationContext ctx) {
- XmlParseReloader reloader = new XmlParseReloader();
- reloader.setAssemble(assemble);
-
- try {
- ObjectCreator creator = ctx.getBean(ObjectCreator.class);
- reloader.setObjectCreator(creator);
- } catch (Exception ignored) {
-
- }
-
- try {
- XmlSelector selector = ctx.getBean(XmlSelector.class);
- reloader.setXmlSelector(selector);
- } catch (Exception ignored) {
-
- }
-
- try {
- BeanDefinitionVisitor visitor = ctx.getBean(BeanDefinitionVisitor.class);
- reloader.setVisitor(visitor);
- } catch (Exception ignored) {
-
- }
-
- return reloader;
- }
-
- public void setAssemble(boolean assemble) {
- this.assemble = assemble;
- }
-
public void setDatasource(DataSource dataSource) {
this.datasource = dataSource;
}
diff --git a/smart-flow-springboot-starter/src/main/java/org/smartboot/flow/springboot/extension/FlowHttpManageConfiguration.java b/smart-flow-integration/smart-flow-springboot-starter/src/main/java/org/smartboot/flow/springboot/extension/FlowHttpManagerConfiguration.java
similarity index 32%
rename from smart-flow-springboot-starter/src/main/java/org/smartboot/flow/springboot/extension/FlowHttpManageConfiguration.java
rename to smart-flow-integration/smart-flow-springboot-starter/src/main/java/org/smartboot/flow/springboot/extension/FlowHttpManagerConfiguration.java
index c0198cd1d6f1d17028f3d19751a6559a613ada9d..b5a1a4e4de7e7280dd3181c49fa1ccbfa07ffb5e 100644
--- a/smart-flow-springboot-starter/src/main/java/org/smartboot/flow/springboot/extension/FlowHttpManageConfiguration.java
+++ b/smart-flow-integration/smart-flow-springboot-starter/src/main/java/org/smartboot/flow/springboot/extension/FlowHttpManagerConfiguration.java
@@ -1,79 +1,123 @@
package org.smartboot.flow.springboot.extension;
+import org.smartboot.flow.core.util.AuxiliaryUtils;
import org.smartboot.flow.manager.change.HttpManager;
import org.smartboot.flow.manager.reload.Reloader;
-import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
-import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
+import org.smartboot.flow.manager.reload.XmlParseReloader;
+import org.smartboot.flow.manager.report.HttpReporter;
+import org.smartboot.flow.manager.trace.HttpTraceReporter;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.ConfigurationProperties;
+import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
+import java.util.Map;
+
/**
* @author huqiang
* @since 2022/12/14 19:15
*/
@Configuration
-@ConfigurationProperties(prefix = "smart.flow.manage.http")
-@ConditionalOnProperty(name = "smart.flow.manage.http.url")
-public class FlowHttpManageConfiguration {
+@ConfigurationProperties(prefix = "smart.flow.manager")
+@ConditionalOnProperty(name = "smart.flow.manager.server")
+public class FlowHttpManagerConfiguration {
+ /* Common Server Configuration start */
/**
* Connect timeout in microseconds.
*/
private long timeout;
/**
- * Manage request url.
+ * manager server address.
*/
- private String url;
+ private String server;
/**
* request idle in microseconds.
*/
- private long idle;
+ private long idle = 5000L;
/**
* First delay in microseconds.
*/
private long delayAtFirst;
+ private Map headers;
+
+ /* Common Server Configuration end */
+
+
+ /* Management Configuration */
+
/**
- * Configuration http manager without reloader.
+ * Management reloader's bean name.
*/
- @Bean(value = "smart-flow-http-manager", initMethod = "start")
- @ConditionalOnMissingBean(Reloader.class)
- public HttpManager getHttpManager(){
- HttpManager httpManager = new HttpManager();
- httpManager.setTimeout(timeout);
- httpManager.setUrl(url);
- httpManager.setIdle(idle);
- httpManager.setDelayAtFirst(delayAtFirst);
- return httpManager;
+ private String reloader;
+
+ /* Manager bean definition start */
+
+ /**
+ * Configuration httpReporter.
+ *
+ * @return httpReporter definition.
+ */
+ @ConditionalOnProperty(value = "smart.flow.manager.statistic.report", havingValue = "true")
+ @Bean(value = "smart-flow-http-reporter", initMethod = "start")
+ public HttpReporter getHttpReporter() {
+ HttpReporter reporter = new HttpReporter();
+ reporter.setTimeout(this.timeout);
+ reporter.setServerAddress(this.server);
+ reporter.setIdle(this.idle);
+ reporter.setHeaders(headers);
+ return reporter;
}
/**
- * Configuration http manager with reloader.
+ * Configuration http manager。
*/
+ @ConditionalOnProperty(value = "smart.flow.manager.management.enabled", havingValue = "true")
@Bean(value = "smart-flow-http-manager", initMethod = "start")
- @ConditionalOnBean(Reloader.class)
- public HttpManager getHttpManager(Reloader reloader){
+ public HttpManager getHttpManager(ApplicationContext ctx){
HttpManager httpManager = new HttpManager();
httpManager.setTimeout(timeout);
- httpManager.setUrl(url);
+ httpManager.setUrl(server);
httpManager.setIdle(idle);
httpManager.setDelayAtFirst(delayAtFirst);
- httpManager.setReloader(reloader);
+ httpManager.setHeaders(headers);
+
+ if (AuxiliaryUtils.isBlank(reloader)) {
+ // not configured, use default reloader.
+ reloader = XmlParseReloader.class.getName();
+ }
+
+ Reloader reloaderBean = ctx.getBean(reloader, Reloader.class);
+ httpManager.setReloader(reloaderBean);
return httpManager;
}
+ /**
+ * Configuration httpTraceReporter.
+ */
+ @ConditionalOnProperty(value = "smart.flow.manager.trace.http-report", havingValue = "true")
+ @Bean(value = "httpTraceReporter", initMethod = "init")
+ public HttpTraceReporter getHttpTraceReporter() {
+ HttpTraceReporter reporter = new HttpTraceReporter();
+ reporter.setTimeout(this.timeout);
+ reporter.setServerAddress(this.server);
+ reporter.setHeaders(headers);
+ return reporter;
+ }
+
+ /* Manager bean definition end */
public void setTimeout(long timeout) {
this.timeout = timeout;
}
- public void setUrl(String url) {
- this.url = url;
+ public void setServer(String server) {
+ this.server = server;
}
public void setIdle(long idle) {
@@ -83,4 +127,12 @@ public class FlowHttpManageConfiguration {
public void setDelayAtFirst(long delayAtFirst) {
this.delayAtFirst = delayAtFirst;
}
+
+ public void setReloader(String reloader) {
+ this.reloader = reloader;
+ }
+
+ public void setHeaders(Map headers) {
+ this.headers = headers;
+ }
}
diff --git a/smart-flow-springboot-starter/src/main/java/org/smartboot/flow/springboot/extension/FlowInitializerConfiguration.java b/smart-flow-integration/smart-flow-springboot-starter/src/main/java/org/smartboot/flow/springboot/extension/FlowInitializerConfiguration.java
similarity index 45%
rename from smart-flow-springboot-starter/src/main/java/org/smartboot/flow/springboot/extension/FlowInitializerConfiguration.java
rename to smart-flow-integration/smart-flow-springboot-starter/src/main/java/org/smartboot/flow/springboot/extension/FlowInitializerConfiguration.java
index 1f31f6584ed4fc5e88eda07d8fed7c59e946952c..bc51bfb4d7e60dcdee7750934624e87fb3145599 100644
--- a/smart-flow-springboot-starter/src/main/java/org/smartboot/flow/springboot/extension/FlowInitializerConfiguration.java
+++ b/smart-flow-integration/smart-flow-springboot-starter/src/main/java/org/smartboot/flow/springboot/extension/FlowInitializerConfiguration.java
@@ -1,12 +1,15 @@
package org.smartboot.flow.springboot.extension;
+import org.smartboot.flow.core.util.AuxiliaryUtils;
+import org.smartboot.flow.manager.reload.XmlParseReloader;
+import org.smartboot.flow.manager.reload.XmlSelector;
import org.smartboot.flow.spring.extension.EngineInitializer;
import org.smartboot.flow.manager.reload.Reloader;
-import org.springframework.boot.autoconfigure.AutoConfigureAfter;
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.ConfigurationProperties;
+import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@@ -19,22 +22,49 @@ import java.util.Arrays;
* @since 2022/12/15 16:32
*/
@Configuration
-@ConfigurationProperties(prefix = "smart.flow.initialize")
-@ConditionalOnProperty(name = "smart.flow.initialize.engines")
-@AutoConfigureAfter(FlowReloadConfiguration.class)
+@ConfigurationProperties(prefix = "smart.flow.initializer")
+@ConditionalOnProperty(name = "smart.flow.initializer.engines")
public class FlowInitializerConfiguration {
/**
* Initializer engines, multiple engine name split with ,
*/
private String engines;
+ private String xmlSelector;
+ private String reloader;
@Bean(value = "springboot-engine-initializer", initMethod = "start")
@ConditionalOnBean(Reloader.class)
@ConditionalOnMissingBean(EngineInitializer.class)
- public EngineInitializer getInitializer(Reloader reloader) {
+ public EngineInitializer getInitializer(ApplicationContext ctx) {
+ boolean withSelector = false;
+ if (AuxiliaryUtils.isBlank(reloader)) {
+ // not configured, use default reloader.
+ reloader = XmlParseReloader.class.getName();
+ withSelector = true;
+ }
+
+ Reloader reloaderBean = ctx.getBean(reloader, Reloader.class);
+
+ if (withSelector) {
+ XmlSelector selector = null;
+
+ if (AuxiliaryUtils.isNotBlank(xmlSelector)) {
+ selector = ctx.getBean(xmlSelector, XmlSelector.class);
+ }
+ // DatabaseXmlSelector has configured
+ else if (ctx.containsBean("databaseXmlSelector")) {
+ selector = ctx.getBean("databaseXmlSelector", XmlSelector.class);
+ }
+
+ if (selector != null) {
+ ((XmlParseReloader)reloaderBean).setXmlSelector(selector);
+ }
+ }
+
+
EngineInitializer initializer = new EngineInitializer();
- initializer.setReloader(reloader);
+ initializer.setReloader(reloaderBean);
initializer.setEngines(Arrays.asList(engines.split(",")));
return initializer;
}
@@ -43,4 +73,12 @@ public class FlowInitializerConfiguration {
public void setEngines(String engines) {
this.engines = engines;
}
+
+ public void setXmlSelector(String xmlSelector) {
+ this.xmlSelector = xmlSelector;
+ }
+
+ public void setReloader(String reloader) {
+ this.reloader = reloader;
+ }
}
diff --git a/smart-flow-integration/smart-flow-springboot-starter/src/main/java/org/smartboot/flow/springboot/extension/FlowTraceConfiguration.java b/smart-flow-integration/smart-flow-springboot-starter/src/main/java/org/smartboot/flow/springboot/extension/FlowTraceConfiguration.java
new file mode 100644
index 0000000000000000000000000000000000000000..27b83b0c3d21fe4e9396c6bb3fcc48b948c39459
--- /dev/null
+++ b/smart-flow-integration/smart-flow-springboot-starter/src/main/java/org/smartboot/flow/springboot/extension/FlowTraceConfiguration.java
@@ -0,0 +1,94 @@
+package org.smartboot.flow.springboot.extension;
+
+import org.smartboot.flow.core.parser.DefaultObjectCreator;
+import org.smartboot.flow.core.util.AuxiliaryUtils;
+import org.smartboot.flow.manager.trace.DefaultTraceCollector;
+import org.smartboot.flow.manager.trace.LogTraceReporter;
+import org.smartboot.flow.manager.trace.TraceReporter;
+import org.smartboot.flow.manager.trace.TraceSampleStrategy;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
+import org.springframework.boot.context.properties.ConfigurationProperties;
+import org.springframework.context.ApplicationContext;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+
+import java.util.stream.Stream;
+
+/**
+ * @author huqiang
+ * @since 2022/12/14 19:15
+ */
+@Configuration
+@ConfigurationProperties(prefix = "smart.flow.manager.trace")
+@ConditionalOnProperty(value = "smart.flow.manager.trace.enabled", havingValue = "true")
+public class FlowTraceConfiguration {
+
+ /**
+ * request idle in microseconds.
+ */
+ private long idle = 5000L;
+
+ /* Trace Collector and Reporter */
+
+ /**
+ * Trace radio.
+ */
+ private double radio;
+
+ /**
+ * sampleStrategy bean name.
+ */
+ private String sampleStrategy;
+
+ /**
+ * sampleStrategy class name.
+ */
+ private String sampleStrategyClass;
+
+
+ @ConditionalOnProperty(value = "smart.flow.manager.trace.log-report", havingValue = "true")
+ @Bean(value = "logTraceReporter")
+ public LogTraceReporter getLogTraceReporter() {
+ return new LogTraceReporter();
+ }
+
+ @ConditionalOnProperty(value = "smart.flow.manager.trace.enabled", havingValue = "true")
+ @Bean(value = "defaultTraceCollector", initMethod = "start")
+ public DefaultTraceCollector getTraceCollector(ApplicationContext ctx){
+ DefaultTraceCollector collector = new DefaultTraceCollector();
+ collector.setIdle(idle);
+ collector.setRadio(radio);
+
+ String[] traceReporterNames = ctx.getBeanNamesForType(TraceReporter.class);
+ Stream.of(traceReporterNames).forEach(p -> collector.addReporter(ctx.getBean(p, TraceReporter.class)));
+
+ if (AuxiliaryUtils.isNotBlank(sampleStrategy)) {
+ collector.setSampleStrategy(ctx.getBean(sampleStrategy, TraceSampleStrategy.class));
+ }
+ // Create strategy with classname.
+ else if (AuxiliaryUtils.asClass(sampleStrategyClass) != null) {
+ TraceSampleStrategy strategy = DefaultObjectCreator.getInstance().create(sampleStrategyClass, TraceSampleStrategy.class, false);
+ collector.setSampleStrategy(strategy);
+ }
+
+ return collector;
+ }
+
+ /* Manager bean definition end */
+
+ public void setIdle(long idle) {
+ this.idle = idle;
+ }
+
+ public void setRadio(double radio) {
+ this.radio = radio;
+ }
+
+ public void setSampleStrategy(String sampleStrategy) {
+ this.sampleStrategy = sampleStrategy;
+ }
+
+ public void setSampleStrategyClass(String sampleStrategyClass) {
+ this.sampleStrategyClass = sampleStrategyClass;
+ }
+}
diff --git a/smart-flow-springboot-starter/src/main/resources/META-INF/spring.factories b/smart-flow-integration/smart-flow-springboot-starter/src/main/resources/META-INF/spring.factories
similarity index 37%
rename from smart-flow-springboot-starter/src/main/resources/META-INF/spring.factories
rename to smart-flow-integration/smart-flow-springboot-starter/src/main/resources/META-INF/spring.factories
index 0fe6437f29294d9aba75644c80d0e2aac6a72eae..3ffcb6d1ecf6bf576bcdb3f9278acc755d055512 100644
--- a/smart-flow-springboot-starter/src/main/resources/META-INF/spring.factories
+++ b/smart-flow-integration/smart-flow-springboot-starter/src/main/resources/META-INF/spring.factories
@@ -1,5 +1,5 @@
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
- org.smartboot.flow.springboot.extension.FlowHttpManageConfiguration,\
- org.smartboot.flow.springboot.extension.FlowHttpReportConfiguration,\
- org.smartboot.flow.springboot.extension.FlowReloadConfiguration,\
+ org.smartboot.flow.springboot.extension.FlowHttpManagerConfiguration,\
+ org.smartboot.flow.springboot.extension.FlowDatabaseXmlSelectorConfiguration,\
+ org.smartboot.flow.springboot.extension.FlowTraceConfiguration,\
org.smartboot.flow.springboot.extension.FlowInitializerConfiguration
\ No newline at end of file
diff --git a/smart-flow-manager/pom.xml b/smart-flow-manager/pom.xml
index db7aa9c4e811218a50b31a5ce4cc49c3d2e454f6..1247b5d0a48bc692733cfb1ea781ccc9e02e91ad 100644
--- a/smart-flow-manager/pom.xml
+++ b/smart-flow-manager/pom.xml
@@ -5,7 +5,7 @@
smart-flow-parent
org.smartboot.flow
- 1.1.2
+ 1.1.3
4.0.0
@@ -14,6 +14,7 @@
8
8
+ UTF-8
diff --git a/smart-flow-manager/src/main/java/org/smartboot/flow/manager/reload/MemoryXmlSelector.java b/smart-flow-manager/src/main/java/org/smartboot/flow/manager/reload/MemoryXmlSelector.java
new file mode 100644
index 0000000000000000000000000000000000000000..b509c6431fd52260ca00161480ffecdb5d57b9dc
--- /dev/null
+++ b/smart-flow-manager/src/main/java/org/smartboot/flow/manager/reload/MemoryXmlSelector.java
@@ -0,0 +1,35 @@
+package org.smartboot.flow.manager.reload;
+
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+
+/**
+ * @author qinluo
+ * @date 2022-12-21 16:36:25
+ * @since 1.1.3
+ */
+public class MemoryXmlSelector implements XmlSelector {
+
+ private static final Map contentMap = new ConcurrentHashMap<>();
+ static XmlSelector INSTANCE = new MemoryXmlSelector();
+
+ private MemoryXmlSelector() {
+
+ }
+
+ @Override
+ public String select(String engineName) {
+ return contentMap.get(engineName);
+ }
+
+ /*
+ Static methods.
+ */
+ public static void updateContent(String engine, String content) {
+ contentMap.put(engine, content);
+ }
+
+ public static String remove(String engine) {
+ return contentMap.remove(engine);
+ }
+}
diff --git a/smart-flow-manager/src/main/java/org/smartboot/flow/manager/reload/ReloadWatcher.java b/smart-flow-manager/src/main/java/org/smartboot/flow/manager/reload/ReloadWatcher.java
new file mode 100644
index 0000000000000000000000000000000000000000..3e9a47f5cee701c318c84641b9c9be3ea81922e3
--- /dev/null
+++ b/smart-flow-manager/src/main/java/org/smartboot/flow/manager/reload/ReloadWatcher.java
@@ -0,0 +1,11 @@
+package org.smartboot.flow.manager.reload;
+
+/**
+ * ReloadWatcher Mark interface.
+ *
+ * @author qinluo
+ * @date 2023-08-09 18:17:34
+ * @since 1.1.3
+ */
+public interface ReloadWatcher {
+}
diff --git a/smart-flow-manager/src/main/java/org/smartboot/flow/manager/reload/XmlParseReloader.java b/smart-flow-manager/src/main/java/org/smartboot/flow/manager/reload/XmlParseReloader.java
index b04a40434d2382df9f6365b8feb5122627b80718..44a75037f4bbe43455a3d01c85804888c2f0592d 100644
--- a/smart-flow-manager/src/main/java/org/smartboot/flow/manager/reload/XmlParseReloader.java
+++ b/smart-flow-manager/src/main/java/org/smartboot/flow/manager/reload/XmlParseReloader.java
@@ -7,6 +7,7 @@ import org.smartboot.flow.core.parser.DefaultParser;
import org.smartboot.flow.core.parser.DefinitionVisitor;
import org.smartboot.flow.core.parser.ObjectCreator;
import org.smartboot.flow.core.parser.ParserContext;
+import org.smartboot.flow.core.util.AssertUtil;
import java.io.ByteArrayInputStream;
import java.io.InputStream;
@@ -24,6 +25,7 @@ public class XmlParseReloader extends AbstractReloader {
protected boolean assemble;
protected DefinitionVisitor visitor;
private XmlSelector xmlSelector;
+ private final XmlSelector memoryXmlSelector = MemoryXmlSelector.INSTANCE;
public void setXmlSelector(XmlSelector xmlSelector) {
this.xmlSelector = xmlSelector;
@@ -43,8 +45,19 @@ public class XmlParseReloader extends AbstractReloader {
@Override
public void doReload(String engineName) {
+ XmlSelector selector = xmlSelector;
+ if (selector == null) {
+ selector = memoryXmlSelector;
+ }
+
+ AssertUtil.notNull(selector, "selector must not be null!");
+
// select config.
- String xml = xmlSelector.select(engineName);
+ String xml = selector.select(engineName);
+ if (xml == null || xml.trim().length() == 0) {
+ xml = memoryXmlSelector.select(engineName);
+ }
+
if (xml == null || xml.trim().length() == 0) {
throw new FlowException("load config " + engineName + " is empty");
}
diff --git a/smart-flow-manager/src/main/java/org/smartboot/flow/manager/trace/DefaultTraceCollector.java b/smart-flow-manager/src/main/java/org/smartboot/flow/manager/trace/DefaultTraceCollector.java
new file mode 100644
index 0000000000000000000000000000000000000000..d33eed95bca5606172d1c23a2a59077d647f7fbc
--- /dev/null
+++ b/smart-flow-manager/src/main/java/org/smartboot/flow/manager/trace/DefaultTraceCollector.java
@@ -0,0 +1,124 @@
+package org.smartboot.flow.manager.trace;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.smartboot.flow.core.ExecutionListenerRegistry;
+import org.smartboot.flow.core.util.AssertUtil;
+import org.smartboot.flow.manager.NamedThreadFactory;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.concurrent.ArrayBlockingQueue;
+import java.util.concurrent.BlockingQueue;
+import java.util.concurrent.ScheduledThreadPoolExecutor;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * @author qinluo
+ * @date 2023-02-07
+ * @since 1.0.7
+ */
+public class DefaultTraceCollector implements TraceCollector {
+
+ private static final Logger LOGGER = LoggerFactory.getLogger(DefaultTraceCollector.class);
+ private final ScheduledThreadPoolExecutor executorService = new ScheduledThreadPoolExecutor(1, new NamedThreadFactory("export-trace"));
+
+ /**
+ * Report idle in mills.
+ */
+ protected long idle = 5000L;
+ private Double radio;
+ private TraceSampleStrategy sampleStrategy;
+ private ManagerExecutionListener executionListener;
+
+ private final BlockingQueue traceQueue = new ArrayBlockingQueue<>(20000);
+ private final List reporters = new ArrayList<>(8);
+
+ public long getIdle() {
+ return idle;
+ }
+
+ public void setIdle(long idle) {
+ AssertUtil.isTrue(idle > 0, "idle must great than zero");
+ this.idle = idle;
+ }
+
+ public void addReporter(TraceReporter reporter) {
+ reporters.add(reporter);
+ }
+
+ public void removeReporter(TraceReporter reporter) {
+ reporters.remove(reporter);
+ }
+
+ public void removeAll() {
+ reporters.clear();
+ }
+
+ public void setReporters(List reporters) {
+ this.reporters.addAll(reporters);
+ }
+
+ public void export() {
+ try {
+ this.doExport();
+ } catch (Throwable ex){
+ LOGGER.error("report trace failed", ex);
+ }
+ }
+
+ public void doExport() {
+ List traces = new ArrayList<>();
+ if (traceQueue.drainTo(traces) < 0) {
+ return;
+ }
+
+ for (TraceData trace : traces) {
+ for (TraceReporter reporter : reporters) {
+ reporter.report(trace);
+ }
+
+ }
+ }
+
+ public void start() {
+ // Register listener.
+ if (sampleStrategy == null && radio != null && radio > 0 && radio <= 1) {
+ sampleStrategy = new TraceSampleStrategy();
+ sampleStrategy.setRadio(radio);
+ }
+
+ executionListener = new ManagerExecutionListener(this, sampleStrategy);
+ ExecutionListenerRegistry.register(executionListener);
+ executorService.setMaximumPoolSize(1);
+ executorService.scheduleAtFixedRate(this::export, idle, idle, TimeUnit.MILLISECONDS);
+ }
+
+ @Override
+ public void submit(TraceData item) {
+ //noinspection ResultOfMethodCallIgnored
+ traceQueue.offer(item);
+ }
+
+ public Double getRadio() {
+ return radio;
+ }
+
+ public void setRadio(Double radio) {
+ this.radio = radio;
+ if (sampleStrategy != null && radio != null && radio > 0 && radio <= 1) {
+ sampleStrategy.setRadio(radio);
+ }
+ }
+
+ public TraceSampleStrategy getSampleStrategy() {
+ return sampleStrategy;
+ }
+
+ public void setSampleStrategy(TraceSampleStrategy sampleStrategy) {
+ this.sampleStrategy = sampleStrategy;
+ if (this.executionListener != null) {
+ this.executionListener.setSampleStrategy(this.sampleStrategy);
+ }
+ }
+}
diff --git a/smart-flow-manager/src/main/java/org/smartboot/flow/manager/trace/HttpTraceReporter.java b/smart-flow-manager/src/main/java/org/smartboot/flow/manager/trace/HttpTraceReporter.java
new file mode 100644
index 0000000000000000000000000000000000000000..7dad8b2bdf73c9418bb8737f546f2026c88988ab
--- /dev/null
+++ b/smart-flow-manager/src/main/java/org/smartboot/flow/manager/trace/HttpTraceReporter.java
@@ -0,0 +1,107 @@
+package org.smartboot.flow.manager.trace;
+
+import com.alibaba.fastjson.JSON;
+import com.alibaba.fastjson.serializer.SerializerFeature;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.smartboot.flow.core.FlowEngine;
+import org.smartboot.flow.core.manager.EngineManager;
+import org.smartboot.flow.manager.ManagerConstants;
+import org.smartboot.flow.manager.UpdateContentTask;
+import org.smartboot.http.client.HttpClient;
+import org.smartboot.http.client.HttpPost;
+import org.smartboot.http.common.enums.HeaderNameEnum;
+
+import java.net.URL;
+import java.nio.charset.StandardCharsets;
+import java.util.Map;
+
+/**
+ * @author qinluo
+ * @date 2023-02-07
+ * @since 1.1.3
+ */
+public class HttpTraceReporter implements TraceReporter {
+
+ private static final Logger LOGGER = LoggerFactory.getLogger(HttpTraceReporter.class);
+
+ /**
+ * 服务端地址
+ */
+ private String serverAddress;
+
+ /**
+ * 超时时间
+ */
+ private long timeout;
+ private String host;
+ private int port;
+
+ private Map headers;
+
+ @Override
+ public void report(TraceData trace) {
+ EngineManager defaultManager = EngineManager.defaultManager();
+
+ HttpClient httpClient = new HttpClient(host, port);
+ httpClient.configuration().connectTimeout((int) timeout);
+ HttpPost post = httpClient.post(ManagerConstants.REPORT_TRACE);
+
+ if (headers != null) {
+ headers.forEach((key, value) -> post.header().add(key, value));
+ }
+
+ FlowEngine