init
This commit is contained in:
commit
d86369b30c
|
@ -0,0 +1,83 @@
|
|||
# Compiled source #
|
||||
###################
|
||||
*.com
|
||||
*.class
|
||||
*.dll
|
||||
*.exe
|
||||
*.o
|
||||
*.so
|
||||
|
||||
|
||||
# Packages #
|
||||
############
|
||||
# it's better to unpack these files and commit the raw source
|
||||
# git has its own built in compression methods
|
||||
*.7z
|
||||
*.dmg
|
||||
*.gz
|
||||
*.iso
|
||||
*.jar
|
||||
*.rar
|
||||
*.tar
|
||||
*.zip
|
||||
*.war
|
||||
*.del
|
||||
*.pmd
|
||||
.tern-project
|
||||
|
||||
|
||||
# Logs and databases #
|
||||
######################
|
||||
*.log
|
||||
*.log.*
|
||||
# OS generated files #
|
||||
######################
|
||||
.DS_Store*
|
||||
ehthumbs.db
|
||||
Icon?
|
||||
Thumbs.db
|
||||
|
||||
|
||||
# Editor Files #
|
||||
################
|
||||
*~
|
||||
*.swp
|
||||
|
||||
|
||||
# Gradle Files #
|
||||
################
|
||||
.gradle
|
||||
|
||||
|
||||
# Build output directies
|
||||
/target
|
||||
*/target
|
||||
/build
|
||||
*/build
|
||||
|
||||
|
||||
# IntelliJ specific files/directories
|
||||
out
|
||||
.idea
|
||||
*.ipr
|
||||
*.iws
|
||||
*.iml
|
||||
atlassian-ide-plugin.xml
|
||||
|
||||
|
||||
# Eclipse specific files/directories
|
||||
.classpath
|
||||
.project
|
||||
.settings
|
||||
.metadata
|
||||
.myeclipse
|
||||
|
||||
|
||||
# NetBeans specific files/directories
|
||||
.nbattrs
|
||||
|
||||
*.mymetadata
|
||||
/logs
|
||||
*/logs
|
||||
|
||||
/payClear-timer/.tern-project
|
|
@ -0,0 +1,86 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" 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">
|
||||
<groupId>com.thebeastshop.liteflow</groupId>
|
||||
<artifactId>liteflow</artifactId>
|
||||
<packaging>jar</packaging>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<version>1.0.0</version>
|
||||
|
||||
<properties>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
<java.version>1.7</java.version>
|
||||
<commons.lang3.version>3.4</commons.lang3.version>
|
||||
<commons-collections.version>4.1</commons-collections.version>
|
||||
<spring.version>4.1.7.RELEASE</spring.version>
|
||||
<org.slf4j.version>1.7.21</org.slf4j.version>
|
||||
<log4j.version>1.2.17</log4j.version>
|
||||
<log4j-slf4j.version>1.7.5</log4j-slf4j.version>
|
||||
<slf4j.version>1.7.13</slf4j.version>
|
||||
<fastjson.version>1.2.7</fastjson.version>
|
||||
<classfinder.version>1.0</classfinder.version>
|
||||
<dom4j.version>1.6.1</dom4j.version>
|
||||
</properties>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.apache.commons</groupId>
|
||||
<artifactId>commons-lang3</artifactId>
|
||||
<version>${commons.lang3.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.commons</groupId>
|
||||
<artifactId>commons-collections4</artifactId>
|
||||
<version>4.1</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-jdbc</artifactId>
|
||||
<version>${spring.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>log4j</groupId>
|
||||
<artifactId>log4j</artifactId>
|
||||
<version>${log4j.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.slf4j</groupId>
|
||||
<artifactId>slf4j-api</artifactId>
|
||||
<version>${org.slf4j.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.slf4j</groupId>
|
||||
<artifactId>slf4j-log4j12</artifactId>
|
||||
<version>${log4j-slf4j.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.alibaba</groupId>
|
||||
<artifactId>fastjson</artifactId>
|
||||
<version>${fastjson.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.poolik</groupId>
|
||||
<artifactId>classfinder</artifactId>
|
||||
<version>${classfinder.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>dom4j</groupId>
|
||||
<artifactId>dom4j</artifactId>
|
||||
<version>${dom4j.version}</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
<configuration>
|
||||
<encoding>UTF-8</encoding>
|
||||
<source>${java.version}</source>
|
||||
<target>${java.version}</target>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</project>
|
|
@ -0,0 +1,78 @@
|
|||
/**
|
||||
* <p>Title: liteFlow</p>
|
||||
* <p>Description: 轻量级的组件式流程框架</p>
|
||||
* <p>Copyright: Copyright (c) 2017</p>
|
||||
* @author Bryan.Zhang
|
||||
* @email weenyc31@163.com
|
||||
* @Date 2017-7-28
|
||||
* @version 1.0
|
||||
*/
|
||||
package com.thebeastshop.liteflow.core;
|
||||
|
||||
import org.apache.commons.lang3.time.StopWatch;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import com.thebeastshop.liteflow.entity.data.DataBus;
|
||||
import com.thebeastshop.liteflow.entity.data.Slot;
|
||||
import com.thebeastshop.liteflow.entity.monitor.CompStatistics;
|
||||
import com.thebeastshop.liteflow.monitor.MonitorBus;
|
||||
|
||||
public abstract class Component {
|
||||
|
||||
private static final Logger LOG = LoggerFactory.getLogger(Component.class);
|
||||
|
||||
private InheritableThreadLocal<Integer> slotIndexTL = new InheritableThreadLocal<Integer>();
|
||||
|
||||
private String nodeId;
|
||||
|
||||
private boolean continueOnError;
|
||||
|
||||
public void execute() throws Exception{
|
||||
StopWatch stopWatch = new StopWatch();
|
||||
stopWatch.start();
|
||||
long initm=Runtime.getRuntime().freeMemory();
|
||||
|
||||
process();
|
||||
stopWatch.stop();
|
||||
long timeSpent = stopWatch.getTime();
|
||||
long endm=Runtime.getRuntime().freeMemory();
|
||||
|
||||
this.getSlot().addStep(nodeId);
|
||||
|
||||
//性能统计
|
||||
CompStatistics statistics = new CompStatistics();
|
||||
statistics.setComponentClazzName(this.getClass().getSimpleName());
|
||||
statistics.setTimeSpent(timeSpent);
|
||||
statistics.setMemorySpent(initm-endm);
|
||||
MonitorBus.addStatistics(statistics);
|
||||
|
||||
LOG.debug("componnet[{}] finished in {} milliseconds",this.getClass().getSimpleName(),timeSpent);
|
||||
}
|
||||
|
||||
protected abstract void process() throws Exception;
|
||||
|
||||
public boolean isContinueOnError() {
|
||||
return continueOnError;
|
||||
}
|
||||
|
||||
public void setContinueOnError(boolean continueOnError) {
|
||||
this.continueOnError = continueOnError;
|
||||
}
|
||||
|
||||
public Component setSlotIndex(Integer slotIndex) {
|
||||
this.slotIndexTL.set(slotIndex);
|
||||
return this;
|
||||
}
|
||||
|
||||
public Slot getSlot(){
|
||||
return DataBus.getSlot(this.slotIndexTL.get());
|
||||
}
|
||||
|
||||
public String getNodeId() {
|
||||
return nodeId;
|
||||
}
|
||||
|
||||
public void setNodeId(String nodeId) {
|
||||
this.nodeId = nodeId;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,136 @@
|
|||
/**
|
||||
* <p>Title: liteFlow</p>
|
||||
* <p>Description: 轻量级的组件式流程框架</p>
|
||||
* <p>Copyright: Copyright (c) 2017</p>
|
||||
* @author Bryan.Zhang
|
||||
* @email weenyc31@163.com
|
||||
* @Date 2017-7-31
|
||||
* @version 1.0
|
||||
*/
|
||||
package com.thebeastshop.liteflow.core;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.concurrent.CountDownLatch;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import com.thebeastshop.liteflow.entity.config.Chain;
|
||||
import com.thebeastshop.liteflow.entity.config.Condition;
|
||||
import com.thebeastshop.liteflow.entity.config.Node;
|
||||
import com.thebeastshop.liteflow.entity.config.ThenCondition;
|
||||
import com.thebeastshop.liteflow.entity.config.WhenCondition;
|
||||
import com.thebeastshop.liteflow.entity.data.DataBus;
|
||||
import com.thebeastshop.liteflow.flow.FlowBus;
|
||||
import com.thebeastshop.liteflow.parser.FlowParser;
|
||||
|
||||
public class FlowExecutor {
|
||||
|
||||
private static final Logger LOG = LoggerFactory.getLogger(FlowExecutor.class);
|
||||
|
||||
private List<String> rulePath;
|
||||
|
||||
public void init() {
|
||||
for(String path : rulePath){
|
||||
try {
|
||||
FlowParser.parseLocal(path);
|
||||
} catch (Exception e) {
|
||||
LOG.error("init flow executor cause error,cannot parse rule file{}", path, e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void reloadRule(){
|
||||
init();
|
||||
}
|
||||
|
||||
public <T> T execute(String chainId,Object param){
|
||||
int slotIndex = -1;
|
||||
try{
|
||||
Chain chain = FlowBus.getChain(chainId);
|
||||
|
||||
if(chain == null){
|
||||
LOG.error("couldn't find chain with the id[{}]",chainId);
|
||||
}
|
||||
|
||||
slotIndex = DataBus.offerSlot();
|
||||
LOG.info("slot[{}] offered",slotIndex);
|
||||
if(slotIndex == -1){
|
||||
throw new Exception("there is no available slot");
|
||||
}
|
||||
|
||||
DataBus.getSlot(slotIndex).setRequestData(param);
|
||||
|
||||
List<Condition> conditionList = chain.getConditionList();
|
||||
|
||||
List<Node> nodeList = null;
|
||||
Component component = null;
|
||||
for(Condition condition : conditionList){
|
||||
nodeList = condition.getNodeList();
|
||||
|
||||
if(condition instanceof ThenCondition){
|
||||
for(Node node : nodeList){
|
||||
component = node.getInstance();
|
||||
try{
|
||||
component.setSlotIndex(slotIndex).execute();
|
||||
}catch(Throwable t){
|
||||
if(component.isContinueOnError()){
|
||||
LOG.error("component[{}] cause error,but flow is still go on",t,component.getClass().getSimpleName());
|
||||
}else{
|
||||
throw new Exception(t);
|
||||
}
|
||||
}
|
||||
}
|
||||
}else if(condition instanceof WhenCondition){
|
||||
final CountDownLatch latch = new CountDownLatch(nodeList.size());
|
||||
for(Node node : nodeList){
|
||||
new WhenConditionThread(node,slotIndex,latch).start();
|
||||
}
|
||||
latch.await(15, TimeUnit.SECONDS);
|
||||
}
|
||||
}
|
||||
DataBus.getSlot(slotIndex).printStep();
|
||||
return DataBus.getSlot(slotIndex).getResponseData();
|
||||
}catch(Exception e){
|
||||
LOG.error("executor cause error",e);
|
||||
return null;
|
||||
}finally{
|
||||
DataBus.releaseSlot(slotIndex);
|
||||
}
|
||||
}
|
||||
|
||||
private class WhenConditionThread extends Thread{
|
||||
|
||||
private Node node;
|
||||
|
||||
private Integer slotIndex;
|
||||
|
||||
private CountDownLatch latch;
|
||||
|
||||
public WhenConditionThread(Node node,Integer slotIndex,CountDownLatch latch){
|
||||
this.node = node;
|
||||
this.slotIndex = slotIndex;
|
||||
this.latch = latch;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
try{
|
||||
node.getInstance().setSlotIndex(slotIndex).execute();
|
||||
}catch(Exception e){
|
||||
LOG.error("component [{}] execute cause error",node.getClazz(),e);
|
||||
}finally{
|
||||
latch.countDown();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public List<String> getRulePath() {
|
||||
return rulePath;
|
||||
}
|
||||
|
||||
public void setRulePath(List<String> rulePath) {
|
||||
this.rulePath = rulePath;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,29 @@
|
|||
/**
|
||||
* <p>Title: liteFlow</p>
|
||||
* <p>Description: 轻量级的组件式流程框架</p>
|
||||
* <p>Copyright: Copyright (c) 2017</p>
|
||||
* @author Bryan.Zhang
|
||||
* @email weenyc31@163.com
|
||||
* @Date 2017-7-28
|
||||
* @version 1.0
|
||||
*/
|
||||
package com.thebeastshop.liteflow.entity.config;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class Chain {
|
||||
|
||||
private List<Condition> conditionList;
|
||||
|
||||
public Chain(List<Condition> conditionList) {
|
||||
this.conditionList = conditionList;
|
||||
}
|
||||
|
||||
public List<Condition> getConditionList() {
|
||||
return conditionList;
|
||||
}
|
||||
|
||||
public void setConditionList(List<Condition> conditionList) {
|
||||
this.conditionList = conditionList;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,29 @@
|
|||
/**
|
||||
* <p>Title: liteFlow</p>
|
||||
* <p>Description: 轻量级的组件式流程框架</p>
|
||||
* <p>Copyright: Copyright (c) 2017</p>
|
||||
* @author Bryan.Zhang
|
||||
* @email weenyc31@163.com
|
||||
* @Date 2017-7-28
|
||||
* @version 1.0
|
||||
*/
|
||||
package com.thebeastshop.liteflow.entity.config;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class Condition {
|
||||
|
||||
private List<Node> nodeList;
|
||||
|
||||
public Condition(List<Node> nodeList) {
|
||||
this.nodeList = nodeList;
|
||||
}
|
||||
|
||||
public List<Node> getNodeList() {
|
||||
return nodeList;
|
||||
}
|
||||
|
||||
public void setNodeList(List<Node> nodeList) {
|
||||
this.nodeList = nodeList;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,45 @@
|
|||
/**
|
||||
* <p>Title: liteFlow</p>
|
||||
* <p>Description: 轻量级的组件式流程框架</p>
|
||||
* <p>Copyright: Copyright (c) 2017</p>
|
||||
* @author Bryan.Zhang
|
||||
* @email weenyc31@163.com
|
||||
* @Date 2017-7-28
|
||||
* @version 1.0
|
||||
*/
|
||||
package com.thebeastshop.liteflow.entity.config;
|
||||
|
||||
import com.thebeastshop.liteflow.core.Component;
|
||||
|
||||
public class Node {
|
||||
|
||||
private String id;
|
||||
|
||||
private String clazz;
|
||||
|
||||
private Component instance;
|
||||
|
||||
public String getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(String id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public String getClazz() {
|
||||
return clazz;
|
||||
}
|
||||
|
||||
public void setClazz(String clazz) {
|
||||
this.clazz = clazz;
|
||||
}
|
||||
|
||||
public Component getInstance() {
|
||||
return instance;
|
||||
}
|
||||
|
||||
public void setInstance(Component instance) {
|
||||
this.instance = instance;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,20 @@
|
|||
/**
|
||||
* <p>Title: liteFlow</p>
|
||||
* <p>Description: 轻量级的组件式流程框架</p>
|
||||
* <p>Copyright: Copyright (c) 2017</p>
|
||||
* @author Bryan.Zhang
|
||||
* @email weenyc31@163.com
|
||||
* @Date 2017-7-28
|
||||
* @version 1.0
|
||||
*/
|
||||
package com.thebeastshop.liteflow.entity.config;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class ThenCondition extends Condition {
|
||||
|
||||
public ThenCondition(List<Node> nodeList) {
|
||||
super(nodeList);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,20 @@
|
|||
/**
|
||||
* <p>Title: liteFlow</p>
|
||||
* <p>Description: 轻量级的组件式流程框架</p>
|
||||
* <p>Copyright: Copyright (c) 2017</p>
|
||||
* @author Bryan.Zhang
|
||||
* @email weenyc31@163.com
|
||||
* @Date 2017-7-28
|
||||
* @version 1.0
|
||||
*/
|
||||
package com.thebeastshop.liteflow.entity.config;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class WhenCondition extends Condition{
|
||||
|
||||
public WhenCondition(List<Node> nodeList) {
|
||||
super(nodeList);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,50 @@
|
|||
/**
|
||||
* <p>Title: liteFlow</p>
|
||||
* <p>Description: 轻量级的组件式流程框架</p>
|
||||
* <p>Copyright: Copyright (c) 2017</p>
|
||||
* @author Bryan.Zhang
|
||||
* @email weenyc31@163.com
|
||||
* @Date 2017-8-1
|
||||
* @version 1.0
|
||||
*/
|
||||
package com.thebeastshop.liteflow.entity.data;
|
||||
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
public class DataBus {
|
||||
|
||||
private static final Logger LOG = LoggerFactory.getLogger(DataBus.class);
|
||||
|
||||
public static final int SLOT_SIZE = 1024;
|
||||
|
||||
public static AtomicInteger OCCUPY_COUNT = new AtomicInteger(0);
|
||||
|
||||
private static Slot[] slots = new Slot[SLOT_SIZE];
|
||||
|
||||
public synchronized static int offerSlot(){
|
||||
for(int i = 0; i < slots.length; i++){
|
||||
if(slots[i] == null){
|
||||
slots[i] = new Slot();
|
||||
OCCUPY_COUNT.incrementAndGet();
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
public static Slot getSlot(int slotIndex){
|
||||
return slots[slotIndex];
|
||||
}
|
||||
|
||||
public static void releaseSlot(int slotIndex){
|
||||
if(slots[slotIndex] != null){
|
||||
slots[slotIndex] = null;
|
||||
OCCUPY_COUNT.decrementAndGet();
|
||||
}else{
|
||||
LOG.warn("the slot[{}] has been released",slotIndex);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,90 @@
|
|||
/**
|
||||
* <p>Title: liteFlow</p>
|
||||
* <p>Description: 轻量级的组件式流程框架</p>
|
||||
* <p>Copyright: Copyright (c) 2017</p>
|
||||
* @author Bryan.Zhang
|
||||
* @email weenyc31@163.com
|
||||
* @Date 2017-8-3
|
||||
* @version 1.0
|
||||
*/
|
||||
package com.thebeastshop.liteflow.entity.data;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public class Slot {
|
||||
|
||||
private static final Logger LOG = LoggerFactory.getLogger(Slot.class);
|
||||
|
||||
private final String REQUEST = "request";
|
||||
|
||||
private final String RESPONSE = "response";
|
||||
|
||||
private final String NODE_INPUT_PREFIX = "input_";
|
||||
|
||||
private final String NODE_OUTPUT_PREFIX = "output_";
|
||||
|
||||
private List<String> executeSteps = new ArrayList<String>();
|
||||
|
||||
private ConcurrentHashMap<String, Object> dataMap = new ConcurrentHashMap<String, Object>();
|
||||
|
||||
public <T> T getInput(String nodeId){
|
||||
return (T)dataMap.get(NODE_INPUT_PREFIX + nodeId);
|
||||
}
|
||||
|
||||
public <T> T getOutput(String nodeId){
|
||||
return (T)dataMap.get(NODE_OUTPUT_PREFIX + nodeId);
|
||||
}
|
||||
|
||||
public <T> void setInput(String nodeId,T t){
|
||||
dataMap.put(NODE_INPUT_PREFIX + nodeId, t);
|
||||
}
|
||||
|
||||
public <T> void setOutput(String nodeId,T t){
|
||||
dataMap.put(NODE_OUTPUT_PREFIX + nodeId, t);
|
||||
}
|
||||
|
||||
public <T> T getRequestData(){
|
||||
return (T)dataMap.get(REQUEST);
|
||||
}
|
||||
|
||||
public <T> void setRequestData(T t){
|
||||
dataMap.put(REQUEST, t);
|
||||
}
|
||||
|
||||
public <T> T getResponseData(){
|
||||
return (T)dataMap.get(RESPONSE);
|
||||
}
|
||||
|
||||
public <T> void setResponseData(T t){
|
||||
dataMap.put(RESPONSE, t);
|
||||
}
|
||||
|
||||
public <T> T getData(String key){
|
||||
return (T)dataMap.get(key);
|
||||
}
|
||||
|
||||
public <T> void setData(String key, T t){
|
||||
dataMap.put(key, t);
|
||||
}
|
||||
|
||||
public void addStep(String nodeId){
|
||||
this.executeSteps.add(nodeId);
|
||||
}
|
||||
|
||||
public void printStep(){
|
||||
StringBuffer str = new StringBuffer();
|
||||
for(int i = 0; i < this.executeSteps.size(); i++){
|
||||
str.append(executeSteps.get(i));
|
||||
if(i < this.executeSteps.size()-1){
|
||||
str.append("==>");
|
||||
}
|
||||
}
|
||||
LOG.info(str.toString());
|
||||
}
|
||||
}
|
|
@ -0,0 +1,43 @@
|
|||
/**
|
||||
* <p>Title: liteFlow</p>
|
||||
* <p>Description: 轻量级的组件式流程框架</p>
|
||||
* <p>Copyright: Copyright (c) 2017</p>
|
||||
* @author Bryan.Zhang
|
||||
* @email weenyc31@163.com
|
||||
* @Date 2017-8-4
|
||||
* @version 1.0
|
||||
*/
|
||||
package com.thebeastshop.liteflow.entity.monitor;
|
||||
|
||||
public class CompStatistics {
|
||||
|
||||
private String componentClazzName;
|
||||
|
||||
private long timeSpent;
|
||||
|
||||
private long memorySpent;
|
||||
|
||||
public String getComponentClazzName() {
|
||||
return componentClazzName;
|
||||
}
|
||||
|
||||
public void setComponentClazzName(String componentClazzName) {
|
||||
this.componentClazzName = componentClazzName;
|
||||
}
|
||||
|
||||
public long getTimeSpent() {
|
||||
return timeSpent;
|
||||
}
|
||||
|
||||
public void setTimeSpent(long timeSpent) {
|
||||
this.timeSpent = timeSpent;
|
||||
}
|
||||
|
||||
public long getMemorySpent() {
|
||||
return memorySpent;
|
||||
}
|
||||
|
||||
public void setMemorySpent(long memorySpent) {
|
||||
this.memorySpent = memorySpent;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,34 @@
|
|||
/**
|
||||
* <p>Title: liteFlow</p>
|
||||
* <p>Description: 轻量级的组件式流程框架</p>
|
||||
* <p>Copyright: Copyright (c) 2017</p>
|
||||
* @author Bryan.Zhang
|
||||
* @email weenyc31@163.com
|
||||
* @Date 2017-7-28
|
||||
* @version 1.0
|
||||
*/
|
||||
package com.thebeastshop.liteflow.flow;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import com.thebeastshop.liteflow.entity.config.Chain;
|
||||
|
||||
public class FlowBus {
|
||||
|
||||
private static Map<String, Chain> chainMap;
|
||||
|
||||
public static Chain getChain(String id) throws Exception{
|
||||
if(chainMap == null || chainMap.isEmpty()){
|
||||
throw new Exception("please config the rule first");
|
||||
}
|
||||
return chainMap.get(id);
|
||||
}
|
||||
|
||||
public static void addChain(String name,Chain chain){
|
||||
if(chainMap == null){
|
||||
chainMap = new HashMap<String, Chain>();
|
||||
}
|
||||
chainMap.put(name, chain);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,81 @@
|
|||
/**
|
||||
* <p>Title: liteFlow</p>
|
||||
* <p>Description: 轻量级的组件式流程框架</p>
|
||||
* <p>Copyright: Copyright (c) 2017</p>
|
||||
* @author Bryan.Zhang
|
||||
* @email weenyc31@163.com
|
||||
* @Date 2017-8-4
|
||||
* @version 1.0
|
||||
*/
|
||||
package com.thebeastshop.liteflow.monitor;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.math.RoundingMode;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.TimerTask;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.Timer;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import com.thebeastshop.liteflow.entity.data.DataBus;
|
||||
import com.thebeastshop.liteflow.entity.monitor.CompStatistics;
|
||||
import com.thebeastshop.liteflow.util.LimitQueue;
|
||||
|
||||
public class MonitorBus {
|
||||
|
||||
private static final int QUEUE_LIMIT_SIZE = 200;
|
||||
|
||||
private static ConcurrentHashMap<String, LimitQueue<CompStatistics>> statisticsMap = new ConcurrentHashMap<String, LimitQueue<CompStatistics>>();
|
||||
|
||||
static{
|
||||
Timer timer = new Timer();
|
||||
timer.schedule(new TimerTask() {
|
||||
public void run() {
|
||||
MonitorBus.printStatistics();
|
||||
}
|
||||
}, 30*1000L, 10*60*1000L);
|
||||
}
|
||||
|
||||
public static void addStatistics(CompStatistics statistics){
|
||||
if(statisticsMap.containsKey(statistics.getComponentClazzName())){
|
||||
statisticsMap.get(statistics.getComponentClazzName()).add(statistics);
|
||||
}else{
|
||||
LimitQueue<CompStatistics> queue = new LimitQueue<CompStatistics>(QUEUE_LIMIT_SIZE);
|
||||
queue.add(statistics);
|
||||
statisticsMap.put(statistics.getComponentClazzName(), queue);
|
||||
}
|
||||
}
|
||||
|
||||
public static void printStatistics(){
|
||||
Map<String, Long> compAverageTimeSpent = new HashMap<String, Long>();
|
||||
Map<String, Long> compAverageMemorySpent = new HashMap<String, Long>();
|
||||
|
||||
long totalTimeSpent = 0;
|
||||
long totalMemorySpent = 0;
|
||||
|
||||
for(Entry<String, LimitQueue<CompStatistics>> entry : statisticsMap.entrySet()){
|
||||
for(CompStatistics statistics : entry.getValue()){
|
||||
totalTimeSpent += statistics.getTimeSpent();
|
||||
totalMemorySpent += statistics.getMemorySpent();
|
||||
}
|
||||
compAverageTimeSpent.put(entry.getKey(), new BigDecimal(totalTimeSpent).divide(new BigDecimal(entry.getValue().size()), 2, RoundingMode.HALF_UP).longValue());
|
||||
compAverageMemorySpent.put(entry.getKey(), new BigDecimal(totalMemorySpent).divide(new BigDecimal(entry.getValue().size()), 2, RoundingMode.HALF_UP).longValue());
|
||||
}
|
||||
System.out.println("======================================================================================");
|
||||
System.out.println("===================================SLOT INFO==========================================");
|
||||
System.out.println("SLOT TOTAL SIZE : "+DataBus.SLOT_SIZE);
|
||||
System.out.println("SLOT OCCUPY COUNT : "+DataBus.OCCUPY_COUNT);
|
||||
System.out.println("===============================TIME AVERAGE SPENT=====================================");
|
||||
for(Entry<String, Long> entry : compAverageTimeSpent.entrySet()){
|
||||
System.out.println("COMPONENT["+entry.getKey()+"] AVERAGE TIME SPENT : " + entry.getValue());
|
||||
}
|
||||
System.out.println("==============================MEMORY AVERAGE SPENT====================================");
|
||||
for(Entry<String, Long> entry : compAverageMemorySpent.entrySet()){
|
||||
System.out.println("COMPONENT["+entry.getKey()+"] AVERAGE MEMORY SPENT : "+ new BigDecimal(entry.getValue()).divide(new BigDecimal(1024), 2, RoundingMode.HALF_UP) + "K");
|
||||
}
|
||||
System.out.println("======================================================================================");
|
||||
}
|
||||
}
|
|
@ -0,0 +1,122 @@
|
|||
/**
|
||||
* <p>Title: liteFlow</p>
|
||||
* <p>Description: 轻量级的组件式流程框架</p>
|
||||
* <p>Copyright: Copyright (c) 2017</p>
|
||||
* @author Bryan.Zhang
|
||||
* @email weenyc31@163.com
|
||||
* @Date 2017-7-28
|
||||
* @version 1.0
|
||||
*/
|
||||
package com.thebeastshop.liteflow.parser;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.apache.commons.lang3.ClassUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.dom4j.Document;
|
||||
import org.dom4j.Element;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import com.poolik.classfinder.ClassFinder;
|
||||
import com.poolik.classfinder.filter.Subclass;
|
||||
import com.poolik.classfinder.info.ClassInfo;
|
||||
import com.thebeastshop.liteflow.core.Component;
|
||||
import com.thebeastshop.liteflow.entity.config.Chain;
|
||||
import com.thebeastshop.liteflow.entity.config.Condition;
|
||||
import com.thebeastshop.liteflow.entity.config.Node;
|
||||
import com.thebeastshop.liteflow.entity.config.ThenCondition;
|
||||
import com.thebeastshop.liteflow.entity.config.WhenCondition;
|
||||
import com.thebeastshop.liteflow.flow.FlowBus;
|
||||
import com.thebeastshop.liteflow.util.Dom4JReader;
|
||||
import com.thebeastshop.liteflow.util.IOUtil;
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public class FlowParser {
|
||||
|
||||
private static final Logger LOG = LoggerFactory.getLogger(FlowParser.class);
|
||||
|
||||
private static final String ENCODING_FORMAT = "UTF-8";
|
||||
|
||||
public static void parseLocal(String rulePath) throws Exception{
|
||||
String ruleContent = IOUtil.read(rulePath, ENCODING_FORMAT);
|
||||
parse(ruleContent);
|
||||
}
|
||||
|
||||
public static void parse(String content) throws Exception{
|
||||
Document document = Dom4JReader.getFormatDocument(content);
|
||||
parse(document);
|
||||
}
|
||||
|
||||
public static void parse(Document document) throws Exception{
|
||||
Element rootElement = document.getRootElement();
|
||||
|
||||
//find所有的组件实现类并实例化
|
||||
Map<String, Component> compInstanceMap = new HashMap<String, Component>();
|
||||
ClassFinder finder = new ClassFinder().addClasspath();
|
||||
Collection<ClassInfo> classList = finder.findClasses(Subclass.of(Component.class));
|
||||
Component component = null;
|
||||
for(ClassInfo classInfo : classList){
|
||||
LOG.info("component [{}] has been registered to flow parse manager",classInfo.getClassName());
|
||||
component = (Component)ClassUtils.getClass(classInfo.getClassName()).newInstance();
|
||||
compInstanceMap.put(classInfo.getClassName(), component);
|
||||
}
|
||||
|
||||
//解析node节点
|
||||
List<Element> nodeList = rootElement.element("nodes").elements("node");
|
||||
String id = null;
|
||||
String clazz = null;
|
||||
Node node = null;
|
||||
Map<String, Node> nodeMap = new HashMap<String, Node>();
|
||||
for(Element e : nodeList){
|
||||
node = new Node();
|
||||
id = e.attributeValue("id");
|
||||
clazz = e.attributeValue("class");
|
||||
node.setId(id);
|
||||
node.setClazz(clazz);
|
||||
if(!compInstanceMap.containsKey(clazz)){
|
||||
LOG.error("couldn't find [{}] in registered component map",clazz);
|
||||
}
|
||||
component = compInstanceMap.get(clazz);
|
||||
component.setNodeId(id);
|
||||
node.setInstance(component);
|
||||
nodeMap.put(id, node);
|
||||
}
|
||||
|
||||
//解析chain节点
|
||||
String chainName = null;
|
||||
String condArrayStr = null;
|
||||
String[] condArray = null;
|
||||
List<Node> chainNodeList = null;
|
||||
List<Condition> conditionList = null;
|
||||
|
||||
List<Element> chainList = rootElement.elements("chain");
|
||||
for(Element e : chainList){
|
||||
chainName = e.attributeValue("name");
|
||||
conditionList = new ArrayList<Condition>();
|
||||
for (Iterator<Element> it = e.elementIterator(); it.hasNext();) {
|
||||
Element condE = it.next();
|
||||
condArrayStr = condE.attributeValue("value");
|
||||
if(StringUtils.isBlank(condArrayStr)){
|
||||
continue;
|
||||
}
|
||||
chainNodeList = new ArrayList<Node>();
|
||||
condArray = condArrayStr.split(",");
|
||||
for (int i = 0; i < condArray.length; i++) {
|
||||
chainNodeList.add(nodeMap.get(condArray[i]));
|
||||
}
|
||||
if(condE.getName().equals("then")){
|
||||
conditionList.add(new ThenCondition(chainNodeList));
|
||||
}else if(condE.getName().equals("when")){
|
||||
conditionList.add(new WhenCondition(chainNodeList));
|
||||
}
|
||||
}
|
||||
FlowBus.addChain(chainName, new Chain(conditionList));
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,117 @@
|
|||
package com.thebeastshop.liteflow.util;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.io.Reader;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.net.URL;
|
||||
|
||||
import org.dom4j.Document;
|
||||
import org.dom4j.DocumentException;
|
||||
import org.dom4j.DocumentHelper;
|
||||
import org.dom4j.io.SAXReader;
|
||||
import org.xml.sax.InputSource;
|
||||
|
||||
public class Dom4JReader {
|
||||
|
||||
private static final String ENCODING_FORMAT = "UTF-8";
|
||||
|
||||
public static Document getDocument(String text) throws DocumentException {
|
||||
return DocumentHelper.parseText(text);
|
||||
}
|
||||
|
||||
public static Document getFormatDocument(String text) throws DocumentException, UnsupportedEncodingException {
|
||||
return getFormatDocument(text, ENCODING_FORMAT);
|
||||
}
|
||||
|
||||
public static Document getFormatDocument(String text, String charset) throws DocumentException, UnsupportedEncodingException {
|
||||
String formatText = new String(text.getBytes("ISO-8859-1"), ENCODING_FORMAT);
|
||||
|
||||
return getDocument(formatText);
|
||||
}
|
||||
|
||||
public static Document getDocument(File file) throws DocumentException, IOException {
|
||||
InputStream inputStream = new FileInputStream(file);
|
||||
|
||||
return getDocument(inputStream);
|
||||
}
|
||||
|
||||
public static Document getFormatDocument(File file) throws DocumentException, IOException, UnsupportedEncodingException {
|
||||
return getFormatDocument(file, ENCODING_FORMAT);
|
||||
}
|
||||
|
||||
public static Document getFormatDocument(File file, String charset) throws DocumentException, IOException, UnsupportedEncodingException {
|
||||
InputStream inputStream = new FileInputStream(file);
|
||||
|
||||
return getFormatDocument(inputStream, charset);
|
||||
}
|
||||
|
||||
public static Document getDocument(InputSource inputSource) throws DocumentException {
|
||||
SAXReader saxReader = new SAXReader();
|
||||
|
||||
return saxReader.read(inputSource);
|
||||
}
|
||||
|
||||
public static Document getFormatDocument(InputSource inputSource) throws DocumentException {
|
||||
return getFormatDocument(inputSource, ENCODING_FORMAT);
|
||||
}
|
||||
|
||||
public static Document getFormatDocument(InputSource inputSource, String charset) throws DocumentException {
|
||||
inputSource.setEncoding(charset);
|
||||
|
||||
return getDocument(inputSource);
|
||||
}
|
||||
|
||||
public static Document getDocument(InputStream inputStream) throws DocumentException, IOException {
|
||||
SAXReader saxReader = new SAXReader();
|
||||
|
||||
Document document = null;
|
||||
try {
|
||||
document = saxReader.read(inputStream);
|
||||
} catch (DocumentException e) {
|
||||
throw e;
|
||||
} finally {
|
||||
if (inputStream != null) {
|
||||
inputStream.close();
|
||||
}
|
||||
}
|
||||
|
||||
return document;
|
||||
}
|
||||
|
||||
public static Document getFormatDocument(InputStream inputStream) throws DocumentException, IOException, UnsupportedEncodingException {
|
||||
return getFormatDocument(inputStream, ENCODING_FORMAT);
|
||||
}
|
||||
|
||||
public static Document getFormatDocument(InputStream inputStream, String charset) throws DocumentException, IOException, UnsupportedEncodingException {
|
||||
Reader inputStreamReader = new InputStreamReader(inputStream, charset);
|
||||
|
||||
return getDocument(inputStreamReader);
|
||||
}
|
||||
|
||||
public static Document getDocument(Reader reader) throws DocumentException, IOException {
|
||||
SAXReader saxReader = new SAXReader();
|
||||
|
||||
Document document = null;
|
||||
try {
|
||||
document = saxReader.read(reader);
|
||||
} catch (DocumentException e) {
|
||||
throw e;
|
||||
} finally {
|
||||
if (reader != null) {
|
||||
reader.close();
|
||||
}
|
||||
}
|
||||
|
||||
return document;
|
||||
}
|
||||
|
||||
public static Document getDocument(URL url) throws DocumentException {
|
||||
SAXReader saxReader = new SAXReader();
|
||||
|
||||
return saxReader.read(url);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,29 @@
|
|||
package com.thebeastshop.liteflow.util;
|
||||
|
||||
import java.io.FileInputStream;
|
||||
import java.io.InputStream;
|
||||
|
||||
import org.apache.commons.io.IOUtils;
|
||||
|
||||
public class IOUtil {
|
||||
public static String read(String path, String encoding) throws Exception {
|
||||
String content = null;
|
||||
|
||||
InputStream inputStream = null;
|
||||
try {
|
||||
// 从Resource路径获取
|
||||
inputStream = IOUtil.class.getClassLoader().getResourceAsStream(path);
|
||||
if (inputStream == null) {
|
||||
// 从文件路径获取
|
||||
inputStream = new FileInputStream(path);
|
||||
}
|
||||
content = IOUtils.toString(inputStream, encoding);
|
||||
} finally {
|
||||
if (inputStream != null) {
|
||||
IOUtils.closeQuietly(inputStream);
|
||||
}
|
||||
}
|
||||
|
||||
return content;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,151 @@
|
|||
/**
|
||||
* <p>Title: liteFlow</p>
|
||||
* <p>Description: 轻量级的组件式流程框架</p>
|
||||
* <p>Copyright: Copyright (c) 2017</p>
|
||||
* @author Bryan.Zhang
|
||||
* @email weenyc31@163.com
|
||||
* @Date 2017-8-4
|
||||
* @version 1.0
|
||||
*/
|
||||
package com.thebeastshop.liteflow.util;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Iterator;
|
||||
import java.util.LinkedList;
|
||||
import java.util.Queue;
|
||||
|
||||
public class LimitQueue<E> implements Queue<E> {
|
||||
|
||||
/**
|
||||
* 队列长度,实例化类的时候指定
|
||||
*/
|
||||
private int limit;
|
||||
|
||||
Queue<E> queue = new LinkedList<E>();
|
||||
|
||||
public LimitQueue(int limit) {
|
||||
this.limit = limit;
|
||||
}
|
||||
|
||||
/**
|
||||
* 入队
|
||||
*/
|
||||
@Override
|
||||
public boolean offer(E e) {
|
||||
if (queue.size() >= limit) {
|
||||
// 如果超出长度,入队时,先出队
|
||||
queue.poll();
|
||||
}
|
||||
return queue.offer(e);
|
||||
}
|
||||
|
||||
/**
|
||||
* 出队
|
||||
*/
|
||||
@Override
|
||||
public E poll() {
|
||||
return queue.poll();
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取队列
|
||||
*
|
||||
* @return
|
||||
* @author SHANHY
|
||||
* @date 2015年11月9日
|
||||
*/
|
||||
public Queue<E> getQueue() {
|
||||
return queue;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取限制大小
|
||||
*
|
||||
* @return
|
||||
* @author SHANHY
|
||||
* @date 2015年11月9日
|
||||
*/
|
||||
public int getLimit() {
|
||||
return limit;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean add(E e) {
|
||||
return queue.add(e);
|
||||
}
|
||||
|
||||
@Override
|
||||
public E element() {
|
||||
return queue.element();
|
||||
}
|
||||
|
||||
@Override
|
||||
public E peek() {
|
||||
return queue.peek();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isEmpty() {
|
||||
return queue.size() == 0 ? true : false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int size() {
|
||||
return queue.size();
|
||||
}
|
||||
|
||||
@Override
|
||||
public E remove() {
|
||||
return queue.remove();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean addAll(Collection<? extends E> c) {
|
||||
return queue.addAll(c);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clear() {
|
||||
queue.clear();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean contains(Object o) {
|
||||
return queue.contains(o);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean containsAll(Collection<?> c) {
|
||||
return queue.containsAll(c);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterator<E> iterator() {
|
||||
return queue.iterator();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean remove(Object o) {
|
||||
return queue.remove(o);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean removeAll(Collection<?> c) {
|
||||
return queue.removeAll(c);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean retainAll(Collection<?> c) {
|
||||
return queue.retainAll(c);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object[] toArray() {
|
||||
return queue.toArray();
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> T[] toArray(T[] a) {
|
||||
return queue.toArray(a);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,32 @@
|
|||
/**
|
||||
* <p>Title: liteFlow</p>
|
||||
* <p>Description: 轻量级的组件式流程框架</p>
|
||||
* <p>Copyright: Copyright (c) 2017</p>
|
||||
* @author Bryan.Zhang
|
||||
* @email weenyc31@163.com
|
||||
* @Date 2017-7-27
|
||||
* @version 1.0
|
||||
*/
|
||||
package com.thebeastshop.liteflow.test;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
import com.thebeastshop.liteflow.core.FlowExecutor;
|
||||
import com.thebeastshop.liteflow.parser.FlowParser;
|
||||
|
||||
public class TestMain {
|
||||
public static void main(String[] args) throws Exception {
|
||||
final FlowExecutor executor = new FlowExecutor();
|
||||
executor.setRulePath(Arrays.asList(new String[]{"flow.xml"}));
|
||||
executor.init();
|
||||
|
||||
for(int i=0;i<200;i++){
|
||||
String response = executor.execute("chain2", "it's a request");
|
||||
System.out.println(response);
|
||||
}
|
||||
|
||||
|
||||
System.in.read();
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,25 @@
|
|||
/**
|
||||
* <p>Title: liteFlow</p>
|
||||
* <p>Description: 轻量级的组件式流程框架</p>
|
||||
* <p>Copyright: Copyright (c) 2017</p>
|
||||
* @author Bryan.Zhang
|
||||
* @email weenyc31@163.com
|
||||
* @Date 2017-8-1
|
||||
* @version 1.0
|
||||
*/
|
||||
package com.thebeastshop.liteflow.test.component;
|
||||
|
||||
import com.thebeastshop.liteflow.core.Component;
|
||||
|
||||
public class AComponent extends Component {
|
||||
|
||||
@Override
|
||||
public void process() {
|
||||
String str = this.getSlot().getRequestData();
|
||||
System.out.println(str);
|
||||
System.out.println("Acomponent executed!");
|
||||
|
||||
this.getSlot().setOutput(this.getNodeId(), "A component output");
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,31 @@
|
|||
/**
|
||||
* <p>Title: liteFlow</p>
|
||||
* <p>Description: 轻量级的组件式流程框架</p>
|
||||
* <p>Copyright: Copyright (c) 2017</p>
|
||||
* @author Bryan.Zhang
|
||||
* @email weenyc31@163.com
|
||||
* @Date 2017-8-1
|
||||
* @version 1.0
|
||||
*/
|
||||
package com.thebeastshop.liteflow.test.component;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import com.thebeastshop.liteflow.core.Component;
|
||||
|
||||
public class BComponent extends Component {
|
||||
|
||||
@Override
|
||||
public void process() {
|
||||
try {
|
||||
Thread.sleep(400L);
|
||||
String[] temp = new String[1000];
|
||||
} catch (InterruptedException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
System.out.println("Bcomponent executed!");
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,28 @@
|
|||
/**
|
||||
* <p>Title: liteFlow</p>
|
||||
* <p>Description: 轻量级的组件式流程框架</p>
|
||||
* <p>Copyright: Copyright (c) 2017</p>
|
||||
* @author Bryan.Zhang
|
||||
* @email weenyc31@163.com
|
||||
* @Date 2017-8-1
|
||||
* @version 1.0
|
||||
*/
|
||||
package com.thebeastshop.liteflow.test.component;
|
||||
|
||||
import com.thebeastshop.liteflow.core.Component;
|
||||
|
||||
public class CComponent extends Component {
|
||||
|
||||
@Override
|
||||
public void process() {
|
||||
try {
|
||||
String[] temp = new String[4000];
|
||||
Thread.sleep(300L);
|
||||
} catch (InterruptedException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
System.out.println("Ccomponent executed!");
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,36 @@
|
|||
/**
|
||||
* <p>Title: liteFlow</p>
|
||||
* <p>Description: 轻量级的组件式流程框架</p>
|
||||
* <p>Copyright: Copyright (c) 2017</p>
|
||||
* @author Bryan.Zhang
|
||||
* @email weenyc31@163.com
|
||||
* @Date 2017-8-1
|
||||
* @version 1.0
|
||||
*/
|
||||
package com.thebeastshop.liteflow.test.component;
|
||||
|
||||
import com.thebeastshop.liteflow.core.Component;
|
||||
import com.thebeastshop.liteflow.entity.data.Slot;
|
||||
|
||||
public class DComponent extends Component {
|
||||
|
||||
@Override
|
||||
public void process() {
|
||||
try {
|
||||
Slot slot = this.getSlot();
|
||||
String e = slot.getOutput("e");
|
||||
if(e == null){
|
||||
System.out.println(slot);
|
||||
}
|
||||
System.out.println("D:" + slot.getOutput("e"));
|
||||
|
||||
String[] temp = new String[1400];
|
||||
Thread.sleep(450L);
|
||||
} catch (InterruptedException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
System.out.println("Dcomponent executed!");
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,29 @@
|
|||
/**
|
||||
* <p>Title: liteFlow</p>
|
||||
* <p>Description: 轻量级的组件式流程框架</p>
|
||||
* <p>Copyright: Copyright (c) 2017</p>
|
||||
* @author Bryan.Zhang
|
||||
* @email weenyc31@163.com
|
||||
* @Date 2017-8-1
|
||||
* @version 1.0
|
||||
*/
|
||||
package com.thebeastshop.liteflow.test.component;
|
||||
|
||||
import com.thebeastshop.liteflow.core.Component;
|
||||
|
||||
public class EComponent extends Component {
|
||||
|
||||
@Override
|
||||
public void process() {
|
||||
try {
|
||||
Thread.sleep(120L);
|
||||
System.out.println("E:" + this.getSlot().getOutput("a"));
|
||||
this.getSlot().setOutput(this.getNodeId(), "E component output");
|
||||
} catch (InterruptedException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
System.out.println("Eomponent executed!");
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,28 @@
|
|||
/**
|
||||
* <p>Title: liteFlow</p>
|
||||
* <p>Description: 轻量级的组件式流程框架</p>
|
||||
* <p>Copyright: Copyright (c) 2017</p>
|
||||
* @author Bryan.Zhang
|
||||
* @email weenyc31@163.com
|
||||
* @Date 2017-8-1
|
||||
* @version 1.0
|
||||
*/
|
||||
package com.thebeastshop.liteflow.test.component;
|
||||
|
||||
import com.thebeastshop.liteflow.core.Component;
|
||||
|
||||
public class FComponent extends Component {
|
||||
|
||||
@Override
|
||||
public void process() {
|
||||
try {
|
||||
String[] temp = new String[400];
|
||||
Thread.sleep(40L);
|
||||
} catch (InterruptedException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
System.out.println("Fcomponent executed!");
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,22 @@
|
|||
/**
|
||||
* <p>Title: liteFlow</p>
|
||||
* <p>Description: 轻量级的组件式流程框架</p>
|
||||
* <p>Copyright: Copyright (c) 2017</p>
|
||||
* @author Bryan.Zhang
|
||||
* @email weenyc31@163.com
|
||||
* @Date 2017-8-1
|
||||
* @version 1.0
|
||||
*/
|
||||
package com.thebeastshop.liteflow.test.component;
|
||||
|
||||
import com.thebeastshop.liteflow.core.Component;
|
||||
|
||||
public class GComponent extends Component {
|
||||
|
||||
@Override
|
||||
public void process() {
|
||||
System.out.println("Gcomponent executed!");
|
||||
this.getSlot().setResponseData("i am a response");
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,24 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<flow>
|
||||
<nodes>
|
||||
<node id="a" class="com.thebeastshop.liteflow.test.component.AComponent"/>
|
||||
<node id="b" class="com.thebeastshop.liteflow.test.component.BComponent"/>
|
||||
<node id="c" class="com.thebeastshop.liteflow.test.component.CComponent"/>
|
||||
<node id="d" class="com.thebeastshop.liteflow.test.component.DComponent"/>
|
||||
<node id="e" class="com.thebeastshop.liteflow.test.component.EComponent"/>
|
||||
<node id="f" class="com.thebeastshop.liteflow.test.component.FComponent"/>
|
||||
<node id="g" class="com.thebeastshop.liteflow.test.component.GComponent"/>
|
||||
</nodes>
|
||||
|
||||
<chain name="chain1">
|
||||
<then value="a,c"/>
|
||||
<when value="b,d"/>
|
||||
<then value="e,f,g"/>
|
||||
</chain>
|
||||
|
||||
<chain name="chain2">
|
||||
<then value="a,c,g"/>
|
||||
<when value="b,e"/>
|
||||
<then value="d,f"/>
|
||||
</chain>
|
||||
</flow>
|
|
@ -0,0 +1,28 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">
|
||||
<log4j:configuration>
|
||||
<appender name="stdout" class="org.apache.log4j.ConsoleAppender">
|
||||
<layout class="org.apache.log4j.PatternLayout">
|
||||
<param name="ConversionPattern" value="%d{yyyy-MM-dd HH:mm:ss,SSS} [%p] %m >> %c:%L%n"/>
|
||||
</layout>
|
||||
</appender>
|
||||
<appender name="fileout" class="org.apache.log4j.DailyRollingFileAppender">
|
||||
<param name="File" value="./logs/commdata.log"/>
|
||||
<layout class="org.apache.log4j.PatternLayout">
|
||||
<param name="ConversionPattern" value="%d{yyyy-MM-dd HH:mm:ss,SSS} [%p] %m >> %c:%L%n"/>
|
||||
</layout>
|
||||
</appender>
|
||||
<appender name="asyncStdout" class="org.apache.log4j.AsyncAppender">
|
||||
<param name="BufferSize" value="8192"/>
|
||||
<appender-ref ref="stdout"/>
|
||||
</appender>
|
||||
<appender name="asyncFileout" class="org.apache.log4j.AsyncAppender">
|
||||
<param name="BufferSize" value="8192"/>
|
||||
<appender-ref ref="fileout"/>
|
||||
</appender>
|
||||
<root>
|
||||
<priority value="info" />
|
||||
<appender-ref ref="asyncStdout"/>
|
||||
<appender-ref ref="asyncFileout"/>
|
||||
</root>
|
||||
</log4j:configuration>
|
Loading…
Reference in New Issue