diff --git a/deploy.bat b/deploy.bat new file mode 100644 index 000000000..c382c102f --- /dev/null +++ b/deploy.bat @@ -0,0 +1 @@ +mvn clean install deploy \ No newline at end of file diff --git a/pom.xml b/pom.xml index eb833e15c..4ddc95628 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ liteflow jar 4.0.0 - 1.2.1 + 1.3.1 UTF-8 diff --git a/src/main/java/com/thebeastshop/liteflow/core/FlowExecutor.java b/src/main/java/com/thebeastshop/liteflow/core/FlowExecutor.java index 708fce999..87d73276b 100644 --- a/src/main/java/com/thebeastshop/liteflow/core/FlowExecutor.java +++ b/src/main/java/com/thebeastshop/liteflow/core/FlowExecutor.java @@ -9,6 +9,7 @@ */ package com.thebeastshop.liteflow.core; +import java.text.MessageFormat; import java.util.List; import java.util.concurrent.CountDownLatch; import java.util.concurrent.TimeUnit; @@ -23,6 +24,13 @@ 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.entity.data.DefaultSlot; +import com.thebeastshop.liteflow.entity.data.Slot; +import com.thebeastshop.liteflow.exception.ChainNotFoundException; +import com.thebeastshop.liteflow.exception.ComponentNotAccessException; +import com.thebeastshop.liteflow.exception.FlowExecutorNotInitException; +import com.thebeastshop.liteflow.exception.FlowSystemException; +import com.thebeastshop.liteflow.exception.NoAvailableSlotException; import com.thebeastshop.liteflow.flow.FlowBus; import com.thebeastshop.liteflow.parser.FlowParser; @@ -37,7 +45,8 @@ public class FlowExecutor { try { FlowParser.parseLocal(path); } catch (Exception e) { - LOG.error("init flow executor cause error,cannot parse rule file{}", path, e); + String errorMsg = MessageFormat.format("init flow executor cause error,cannot parse rule file{0}", path); + throw new FlowExecutorNotInitException(errorMsg); } } } @@ -46,22 +55,57 @@ public class FlowExecutor { init(); } - public T execute(String chainId,Object param){ - int slotIndex = -1; + public T execute(String chainId,Object param){ + return execute(chainId, param, DefaultSlot.class,null,false); + } + + public T execute(String chainId,Object param,Class slotClazz){ + return execute(chainId, param, slotClazz,null,false); + } + + public void invoke(String chainId,Object param,Class slotClazz,Integer slotIndex){ + execute(chainId, param, slotClazz,slotIndex,true); + } + + public T execute(String chainId,Object param,Class slotClazz,Integer slotIndex,boolean isInnerChain){ + Slot slot = null; try{ + if(FlowBus.needInit()) { + init(); + } + Chain chain = FlowBus.getChain(chainId); if(chain == null){ - LOG.error("couldn't find chain with the id[{}]",chainId); + String errorMsg = MessageFormat.format("couldn't find chain with the id[{0}]", chainId); + throw new ChainNotFoundException(errorMsg); + } + + if(!isInnerChain && slotIndex == null) { + slotIndex = DataBus.offerSlot(slotClazz); + LOG.info("slot[{}] offered",slotIndex); } - slotIndex = DataBus.offerSlot(); - LOG.info("slot[{}] offered",slotIndex); if(slotIndex == -1){ - throw new Exception("there is no available slot"); + throw new NoAvailableSlotException("there is no available slot"); } - DataBus.getSlot(slotIndex).setRequestData(param); + slot = DataBus.getSlot(slotIndex); + if(slot == null) { + throw new NoAvailableSlotException("the slot is not exist"); + } + + if(StringUtils.isBlank(slot.getRequestId())) { + slot.generateRequestId(); + LOG.info("requestId[{}] has generated",slot.getRequestId()); + } + + if(!isInnerChain) { + slot.setRequestData(param); + slot.setChainName(chainId); + }else { + slot.setChainReqData(chainId, param); + } List conditionList = chain.getConditionList(); @@ -77,32 +121,40 @@ public class FlowExecutor { component.setSlotIndex(slotIndex); if(component.isAccess()){ component.execute(); - }else{ - LOG.info("component[{}] do not gain access",component.getClass().getSimpleName()); + if(component.isEnd()) { + LOG.info("[{}]:component[{}] lead the chain to end",slot.getRequestId(),component.getClass().getSimpleName()); + break; + } + }else { + LOG.info("[{}]:[X]skip component[{}] execution",slot.getRequestId(),component.getClass().getSimpleName()); } - }catch(Throwable t){ + }catch(Exception t){ if(component.isContinueOnError()){ - LOG.error("component[{}] cause error,but flow is still go on",t,component.getClass().getSimpleName()); + String errorMsg = MessageFormat.format("[{0}]:component[{1}] cause error,but flow is still go on", slot.getRequestId(),component.getClass().getSimpleName()); + LOG.error(errorMsg,t); }else{ - throw new Exception(t); + String errorMsg = MessageFormat.format("[{0}]:executor cause error",slot.getRequestId()); + LOG.error(errorMsg,t); + throw t; } } } }else if(condition instanceof WhenCondition){ final CountDownLatch latch = new CountDownLatch(nodeList.size()); for(Node node : nodeList){ - new WhenConditionThread(node,slotIndex,latch).start(); + new WhenConditionThread(node,slotIndex,slot.getRequestId(),latch).start(); } latch.await(15, TimeUnit.SECONDS); } } - DataBus.getSlot(slotIndex).printStep(); - return DataBus.getSlot(slotIndex).getResponseData(); + return (T)slot; }catch(Exception e){ - LOG.error("executor cause error",e); - return null; + throw new FlowSystemException("executor cause error"); }finally{ - DataBus.releaseSlot(slotIndex); + if(!isInnerChain) { + slot.printStep(); + DataBus.releaseSlot(slotIndex); + } } } @@ -112,18 +164,26 @@ public class FlowExecutor { private Integer slotIndex; + private String requestId; + private CountDownLatch latch; - public WhenConditionThread(Node node,Integer slotIndex,CountDownLatch latch){ + public WhenConditionThread(Node node,Integer slotIndex,String requestId,CountDownLatch latch){ this.node = node; this.slotIndex = slotIndex; + this.requestId = requestId; this.latch = latch; } @Override public void run() { try{ - node.getInstance().setSlotIndex(slotIndex).execute(); + NodeComponent cmp = node.getInstance().setSlotIndex(slotIndex); + if(cmp.isAccess()) { + cmp.execute(); + }else { + LOG.info("[{}]:[X]skip component[{}] execution",requestId,cmp.getClass().getSimpleName()); + } }catch(Exception e){ LOG.error("component [{}] execute cause error",node.getClazz(),e); }finally{ diff --git a/src/main/java/com/thebeastshop/liteflow/core/NodeComponent.java b/src/main/java/com/thebeastshop/liteflow/core/NodeComponent.java index 781bf0c01..0f77eb276 100644 --- a/src/main/java/com/thebeastshop/liteflow/core/NodeComponent.java +++ b/src/main/java/com/thebeastshop/liteflow/core/NodeComponent.java @@ -15,6 +15,8 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.thebeastshop.liteflow.entity.config.Node; +import com.thebeastshop.liteflow.entity.data.CmpStep; +import com.thebeastshop.liteflow.entity.data.CmpStepType; import com.thebeastshop.liteflow.entity.data.DataBus; import com.thebeastshop.liteflow.entity.data.Slot; import com.thebeastshop.liteflow.entity.monitor.CompStatistics; @@ -29,9 +31,10 @@ public abstract class NodeComponent { private String nodeId; - private boolean continueOnError; - public void execute() throws Exception{ + Slot slot = this.getSlot(); + LOG.info("[{}]:[O]start component[{}] execution",slot.getRequestId(),this.getClass().getSimpleName()); + slot.addStep(new CmpStep(nodeId, CmpStepType.START)); StopWatch stopWatch = new StopWatch(); stopWatch.start(); long initm=Runtime.getRuntime().freeMemory(); @@ -41,18 +44,17 @@ public abstract class NodeComponent { long timeSpent = stopWatch.getTime(); long endm=Runtime.getRuntime().freeMemory(); - this.getSlot().addStep(nodeId); + slot.addStep(new CmpStep(nodeId, CmpStepType.END)); //性能统计 CompStatistics statistics = new CompStatistics(); statistics.setComponentClazzName(this.getClass().getSimpleName()); statistics.setTimeSpent(timeSpent); - statistics.setMemorySpent(initm-endm); MonitorBus.addStatistics(statistics); if(this instanceof NodeCondComponent){ - String condNodeId = this.getSlot().getCondResult(this.getClass().getName()); + String condNodeId = slot.getCondResult(this.getClass().getName()); if(StringUtils.isNotBlank(condNodeId)){ Node thisNode = FlowParser.getNode(nodeId); Node condNode = thisNode.getCondNode(condNodeId); @@ -64,21 +66,30 @@ public abstract class NodeComponent { } } - LOG.debug("componnet[{}] finished in {} milliseconds",this.getClass().getSimpleName(),timeSpent); + LOG.debug("[{}]:componnet[{}] finished in {} milliseconds",slot.getRequestId(),this.getClass().getSimpleName(),timeSpent); } protected abstract void process() throws Exception; + /** + * 是否进入该节点 + */ protected boolean isAccess(){ return true; } - public boolean isContinueOnError() { - return continueOnError; + /** + * 出错是否继续执行 + */ + protected boolean isContinueOnError() { + return false; } - - public void setContinueOnError(boolean continueOnError) { - this.continueOnError = continueOnError; + + /** + * 是否结束整个流程(不往下继续执行) + */ + protected boolean isEnd() { + return false; } public NodeComponent setSlotIndex(Integer slotIndex) { @@ -86,7 +97,11 @@ public abstract class NodeComponent { return this; } - public Slot getSlot(){ + public Integer getSlotIndex() { + return this.slotIndexTL.get(); + } + + public T getSlot(){ return DataBus.getSlot(this.slotIndexTL.get()); } diff --git a/src/main/java/com/thebeastshop/liteflow/core/NodeCondComponent.java b/src/main/java/com/thebeastshop/liteflow/core/NodeCondComponent.java index fa8472393..d91b7658d 100644 --- a/src/main/java/com/thebeastshop/liteflow/core/NodeCondComponent.java +++ b/src/main/java/com/thebeastshop/liteflow/core/NodeCondComponent.java @@ -1,21 +1,26 @@ /** - *

Title: litis

- *

Description: redis的全方位开发运维平台

+ *

Title: liteFlow

+ *

Description: 轻量级的组件式流程框架

*

Copyright: Copyright (c) 2017

* @author Bryan.Zhang - * @email 47483522@qq.com - * @Date 2017-11-28 + * @email weenyc31@163.com + * @Date 2017-7-28 + * @version 1.0 */ package com.thebeastshop.liteflow.core; +import org.springframework.stereotype.Component; + public abstract class NodeCondComponent extends NodeComponent { @Override protected void process() throws Exception { - String nodeId = this.processCond(); + Class clazz = this.processCond(); + Component component = clazz.getAnnotation(Component.class); + String nodeId = component.value(); this.getSlot().setCondResult(this.getClass().getName(), nodeId); } - protected abstract String processCond() throws Exception; + protected abstract Class processCond() throws Exception; } diff --git a/src/main/java/com/thebeastshop/liteflow/entity/config/Chain.java b/src/main/java/com/thebeastshop/liteflow/entity/config/Chain.java index 1c4f22a81..bd28dcf5f 100644 --- a/src/main/java/com/thebeastshop/liteflow/entity/config/Chain.java +++ b/src/main/java/com/thebeastshop/liteflow/entity/config/Chain.java @@ -13,9 +13,12 @@ import java.util.List; public class Chain { + private String chainName; + private List conditionList; - public Chain(List conditionList) { + public Chain(String chainName, List conditionList) { + this.chainName = chainName; this.conditionList = conditionList; } @@ -26,4 +29,12 @@ public class Chain { public void setConditionList(List conditionList) { this.conditionList = conditionList; } + + public String getChainName() { + return chainName; + } + + public void setChainName(String chainName) { + this.chainName = chainName; + } } diff --git a/src/main/java/com/thebeastshop/liteflow/entity/data/AbsSlot.java b/src/main/java/com/thebeastshop/liteflow/entity/data/AbsSlot.java new file mode 100644 index 000000000..b95c47321 --- /dev/null +++ b/src/main/java/com/thebeastshop/liteflow/entity/data/AbsSlot.java @@ -0,0 +1,146 @@ +/** + *

Title: liteFlow

+ *

Description: 轻量级的组件式流程框架

+ *

Copyright: Copyright (c) 2017

+ * @author Bryan.Zhang + * @email weenyc31@163.com + * @Date 2017-8-3 + * @version 1.0 + */ +package com.thebeastshop.liteflow.entity.data; + +import java.util.ArrayDeque; +import java.util.ArrayList; +import java.util.Deque; +import java.util.Iterator; +import java.util.List; +import java.util.concurrent.ConcurrentHashMap; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +@SuppressWarnings("unchecked") +public abstract class AbsSlot implements Slot{ + + private static final Logger LOG = LoggerFactory.getLogger(Slot.class); + + private final String REQUEST = "request"; + + private final String RESPONSE = "response"; + + private final String CHAINNAME = "chain_name"; + + private final String COND_NODE_PREFIX = "cond_"; + + private final String NODE_INPUT_PREFIX = "input_"; + + private final String NODE_OUTPUT_PREFIX = "output_"; + + private final String CHAIN_REQ_PREFIX = "chain_req_"; + + private final String REQUEST_ID = "req_id"; + + private Deque executeSteps = new ArrayDeque(); + + protected ConcurrentHashMap dataMap = new ConcurrentHashMap(); + + public T getInput(String nodeId){ + return (T)dataMap.get(NODE_INPUT_PREFIX + nodeId); + } + + public T getOutput(String nodeId){ + return (T)dataMap.get(NODE_OUTPUT_PREFIX + nodeId); + } + + public void setInput(String nodeId,T t){ + dataMap.put(NODE_INPUT_PREFIX + nodeId, t); + } + + public void setOutput(String nodeId,T t){ + dataMap.put(NODE_OUTPUT_PREFIX + nodeId, t); + } + + public T getRequestData(){ + return (T)dataMap.get(REQUEST); + } + + public void setRequestData(T t){ + dataMap.put(REQUEST, t); + } + + public T getResponseData(){ + return (T)dataMap.get(RESPONSE); + } + + public void setResponseData(T t){ + dataMap.put(RESPONSE, t); + } + + public T getChainReqData(String chainId) { + return (T)dataMap.get(CHAIN_REQ_PREFIX + chainId); + } + + public void setChainReqData(String chainId, T t) { + dataMap.put(CHAIN_REQ_PREFIX + chainId, t); + } + + public T getData(String key){ + return (T)dataMap.get(key); + } + + public void setData(String key, T t){ + dataMap.put(key, t); + } + + public void setCondResult(String key, T t){ + dataMap.put(COND_NODE_PREFIX + key, t); + } + + public T getCondResult(String key){ + return (T)dataMap.get(COND_NODE_PREFIX + key); + } + + public void setChainName(String chainName) { + dataMap.put(CHAINNAME, chainName); + } + + public String getChainName() { + return (String)dataMap.get(CHAINNAME); + } + + public void addStep(CmpStep step){ + CmpStep lastStep = this.executeSteps.peekLast(); + if(lastStep != null && lastStep.equals(step)) { + lastStep.setStepType(CmpStepType.SINGLE); + }else { + this.executeSteps.add(step); + } + } + + public void printStep(){ + StringBuffer str = new StringBuffer(); + CmpStep cmpStep = null; + for (Iterator it = executeSteps.iterator(); it.hasNext();) { + cmpStep = it.next(); + str.append(cmpStep); + if(it.hasNext()){ + str.append("==>"); + } + } + LOG.info("[{}]:CHAIN_NAME[{}]\n{}",getRequestId(),this.getChainName(),str.toString()); + } + + @Override + public void generateRequestId() { + dataMap.put(REQUEST_ID, new Long(System.nanoTime()).toString()); + } + + @Override + public String getRequestId() { + return (String)dataMap.get(REQUEST_ID); + } + + public Deque getExecuteSteps() { + return executeSteps; + } +} diff --git a/src/main/java/com/thebeastshop/liteflow/entity/data/CmpStep.java b/src/main/java/com/thebeastshop/liteflow/entity/data/CmpStep.java new file mode 100644 index 000000000..3076df018 --- /dev/null +++ b/src/main/java/com/thebeastshop/liteflow/entity/data/CmpStep.java @@ -0,0 +1,67 @@ +/** + *

Title: liteFlow

+ *

Description: 轻量级的组件式流程框架

+ *

Copyright: Copyright (c) 2017

+ * @author Bryan.Zhang + * @email weenyc31@163.com + * @Date 2017-12-8 + * @version 1.0 + */ +package com.thebeastshop.liteflow.entity.data; + +import java.text.MessageFormat; + +public class CmpStep { + private String nodeId; + + private CmpStepType stepType; + + public CmpStep(String nodeId, CmpStepType stepType) { + this.nodeId = nodeId; + this.stepType = stepType; + } + + public String getNodeId() { + return nodeId; + } + + public void setNodeId(String nodeId) { + this.nodeId = nodeId; + } + + public CmpStepType getStepType() { + return stepType; + } + + public void setStepType(CmpStepType stepType) { + this.stepType = stepType; + } + + @Override + public String toString() { + if(stepType.equals(CmpStepType.SINGLE)) { + return MessageFormat.format("{0}", nodeId); + }else { + return MessageFormat.format("{0}({1})", nodeId,stepType); + } + + + } + + @Override + public boolean equals(Object obj) { + if (obj == null) { + return false; + }else { + if(getClass() != obj.getClass()) { + return false; + }else { + if(((CmpStep)obj).getNodeId().equals(this.getNodeId())) { + return true; + }else { + return false; + } + } + } + } +} diff --git a/src/main/java/com/thebeastshop/liteflow/entity/data/CmpStepType.java b/src/main/java/com/thebeastshop/liteflow/entity/data/CmpStepType.java new file mode 100644 index 000000000..29e3b0524 --- /dev/null +++ b/src/main/java/com/thebeastshop/liteflow/entity/data/CmpStepType.java @@ -0,0 +1,16 @@ +/** + *

Title: liteFlow

+ *

Description: 轻量级的组件式流程框架

+ *

Copyright: Copyright (c) 2017

+ * @author Bryan.Zhang + * @email weenyc31@163.com + * @Date 2017-12-8 + * @version 1.0 + */ +package com.thebeastshop.liteflow.entity.data; + +public enum CmpStepType { + START, + END, + SINGLE; +} diff --git a/src/main/java/com/thebeastshop/liteflow/entity/data/DataBus.java b/src/main/java/com/thebeastshop/liteflow/entity/data/DataBus.java index dbbebe441..d0e483796 100644 --- a/src/main/java/com/thebeastshop/liteflow/entity/data/DataBus.java +++ b/src/main/java/com/thebeastshop/liteflow/entity/data/DataBus.java @@ -24,27 +24,34 @@ public class DataBus { 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; + public synchronized static int offerSlot(Class slotClazz){ + try{ + for(int i = 0; i < slots.length; i++){ + if(slots[i] == null){ + slots[i] = slotClazz.newInstance(); + OCCUPY_COUNT.incrementAndGet(); + return i; + } } + }catch(Exception e){ + LOG.error("offer slot error",e); + return -1; } return -1; } - public static Slot getSlot(int slotIndex){ - return slots[slotIndex]; + @SuppressWarnings("unchecked") + public static T getSlot(int slotIndex){ + return (T)slots[slotIndex]; } public static void releaseSlot(int slotIndex){ if(slots[slotIndex] != null){ + LOG.info("[{}]:slot[{}] released",slots[slotIndex].getRequestId(),slotIndex); slots[slotIndex] = null; OCCUPY_COUNT.decrementAndGet(); }else{ - LOG.warn("the slot[{}] has been released",slotIndex); + LOG.warn("slot[{}] already has been released",slotIndex); } } } diff --git a/src/main/java/com/thebeastshop/liteflow/entity/data/DefaultSlot.java b/src/main/java/com/thebeastshop/liteflow/entity/data/DefaultSlot.java new file mode 100644 index 000000000..2d30e8a10 --- /dev/null +++ b/src/main/java/com/thebeastshop/liteflow/entity/data/DefaultSlot.java @@ -0,0 +1,14 @@ +/** + *

Title: liteFlow

+ *

Description: 轻量级的组件式流程框架

+ *

Copyright: Copyright (c) 2017

+ * @author Bryan.Zhang + * @email weenyc31@163.com + * @Date 2017-12-4 + * @version 1.0 + */ +package com.thebeastshop.liteflow.entity.data; + +public class DefaultSlot extends AbsSlot { + +} diff --git a/src/main/java/com/thebeastshop/liteflow/entity/data/Slot.java b/src/main/java/com/thebeastshop/liteflow/entity/data/Slot.java index ce2f3a965..7b9913406 100644 --- a/src/main/java/com/thebeastshop/liteflow/entity/data/Slot.java +++ b/src/main/java/com/thebeastshop/liteflow/entity/data/Slot.java @@ -4,97 +4,49 @@ *

Copyright: Copyright (c) 2017

* @author Bryan.Zhang * @email weenyc31@163.com - * @Date 2017-8-3 + * @Date 2017-12-4 * @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 { +public interface Slot { + public T getInput(String nodeId); - private static final Logger LOG = LoggerFactory.getLogger(Slot.class); + public T getOutput(String nodeId); - private final String REQUEST = "request"; + public void setInput(String nodeId,T t); - private final String RESPONSE = "response"; + public void setOutput(String nodeId,T t); - private final String COND_NODE_PREFIX = "cond_"; + public T getRequestData(); - private final String NODE_INPUT_PREFIX = "input_"; + public void setRequestData(T t); - private final String NODE_OUTPUT_PREFIX = "output_"; + public T getResponseData(); - private List executeSteps = new ArrayList(); + public void setChainReqData(String chainId, T t); - private ConcurrentHashMap dataMap = new ConcurrentHashMap(); + public T getChainReqData(String chainId); - public T getInput(String nodeId){ - return (T)dataMap.get(NODE_INPUT_PREFIX + nodeId); - } + public void setResponseData(T t); - public T getOutput(String nodeId){ - return (T)dataMap.get(NODE_OUTPUT_PREFIX + nodeId); - } + public T getData(String key); - public void setInput(String nodeId,T t){ - dataMap.put(NODE_INPUT_PREFIX + nodeId, t); - } + public void setData(String key, T t); - public void setOutput(String nodeId,T t){ - dataMap.put(NODE_OUTPUT_PREFIX + nodeId, t); - } + public void setCondResult(String key, T t); - public T getRequestData(){ - return (T)dataMap.get(REQUEST); - } + public T getCondResult(String key); - public void setRequestData(T t){ - dataMap.put(REQUEST, t); - } + public void addStep(CmpStep step); - public T getResponseData(){ - return (T)dataMap.get(RESPONSE); - } + public void printStep(); - public void setResponseData(T t){ - dataMap.put(RESPONSE, t); - } + public void generateRequestId(); - public T getData(String key){ - return (T)dataMap.get(key); - } + public String getRequestId(); - public void setData(String key, T t){ - dataMap.put(key, t); - } + public void setChainName(String chainName); - public void setCondResult(String key, T t){ - dataMap.put(COND_NODE_PREFIX + key, t); - } - - public T getCondResult(String key){ - return (T)dataMap.get(COND_NODE_PREFIX + key); - } - - 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()); - } + public String getChainName(); } diff --git a/src/main/java/com/thebeastshop/liteflow/exception/ChainNotFoundException.java b/src/main/java/com/thebeastshop/liteflow/exception/ChainNotFoundException.java new file mode 100644 index 000000000..05ec01fb3 --- /dev/null +++ b/src/main/java/com/thebeastshop/liteflow/exception/ChainNotFoundException.java @@ -0,0 +1,21 @@ +package com.thebeastshop.liteflow.exception; + +public class ChainNotFoundException extends RuntimeException { + + private static final long serialVersionUID = 1L; + + /** 异常信息 */ + private String message; + + public ChainNotFoundException(String message) { + this.message = message; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } +} diff --git a/src/main/java/com/thebeastshop/liteflow/exception/ComponentNotAccessException.java b/src/main/java/com/thebeastshop/liteflow/exception/ComponentNotAccessException.java new file mode 100644 index 000000000..bcc118ee4 --- /dev/null +++ b/src/main/java/com/thebeastshop/liteflow/exception/ComponentNotAccessException.java @@ -0,0 +1,21 @@ +package com.thebeastshop.liteflow.exception; + +public class ComponentNotAccessException extends RuntimeException { + + private static final long serialVersionUID = 1L; + + /** 异常信息 */ + private String message; + + public ComponentNotAccessException(String message) { + this.message = message; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } +} diff --git a/src/main/java/com/thebeastshop/liteflow/exception/FlowExecutorNotInitException.java b/src/main/java/com/thebeastshop/liteflow/exception/FlowExecutorNotInitException.java new file mode 100644 index 000000000..40fb8d781 --- /dev/null +++ b/src/main/java/com/thebeastshop/liteflow/exception/FlowExecutorNotInitException.java @@ -0,0 +1,21 @@ +package com.thebeastshop.liteflow.exception; + +public class FlowExecutorNotInitException extends RuntimeException { + + private static final long serialVersionUID = 1L; + + /** 异常信息 */ + private String message; + + public FlowExecutorNotInitException(String message) { + this.message = message; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } +} diff --git a/src/main/java/com/thebeastshop/liteflow/exception/FlowSystemException.java b/src/main/java/com/thebeastshop/liteflow/exception/FlowSystemException.java new file mode 100644 index 000000000..6789c2c51 --- /dev/null +++ b/src/main/java/com/thebeastshop/liteflow/exception/FlowSystemException.java @@ -0,0 +1,21 @@ +package com.thebeastshop.liteflow.exception; + +public class FlowSystemException extends RuntimeException { + + private static final long serialVersionUID = 1L; + + /** 异常信息 */ + private String message; + + public FlowSystemException(String message) { + this.message = message; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } +} diff --git a/src/main/java/com/thebeastshop/liteflow/exception/NoAvailableSlotException.java b/src/main/java/com/thebeastshop/liteflow/exception/NoAvailableSlotException.java new file mode 100644 index 000000000..beda393da --- /dev/null +++ b/src/main/java/com/thebeastshop/liteflow/exception/NoAvailableSlotException.java @@ -0,0 +1,21 @@ +package com.thebeastshop.liteflow.exception; + +public class NoAvailableSlotException extends RuntimeException { + + private static final long serialVersionUID = 1L; + + /** 异常信息 */ + private String message; + + public NoAvailableSlotException(String message) { + this.message = message; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } +} diff --git a/src/main/java/com/thebeastshop/liteflow/flow/FlowBus.java b/src/main/java/com/thebeastshop/liteflow/flow/FlowBus.java index 72e142429..d8130c33f 100644 --- a/src/main/java/com/thebeastshop/liteflow/flow/FlowBus.java +++ b/src/main/java/com/thebeastshop/liteflow/flow/FlowBus.java @@ -12,6 +12,8 @@ package com.thebeastshop.liteflow.flow; import java.util.HashMap; import java.util.Map; +import org.apache.commons.collections4.MapUtils; + import com.thebeastshop.liteflow.entity.config.Chain; public class FlowBus { @@ -31,4 +33,8 @@ public class FlowBus { } chainMap.put(name, chain); } + + public static boolean needInit() { + return MapUtils.isEmpty(chainMap); + } } diff --git a/src/main/java/com/thebeastshop/liteflow/monitor/MonitorBus.java b/src/main/java/com/thebeastshop/liteflow/monitor/MonitorBus.java index 37007d587..c25973c5a 100644 --- a/src/main/java/com/thebeastshop/liteflow/monitor/MonitorBus.java +++ b/src/main/java/com/thebeastshop/liteflow/monitor/MonitorBus.java @@ -11,13 +11,19 @@ package com.thebeastshop.liteflow.monitor; import java.math.BigDecimal; import java.math.RoundingMode; +import java.text.MessageFormat; +import java.util.ArrayList; +import java.util.Collections; +import java.util.Comparator; import java.util.HashMap; +import java.util.List; import java.util.Map; import java.util.TimerTask; import java.util.Map.Entry; import java.util.Timer; import java.util.concurrent.ConcurrentHashMap; +import org.apache.commons.collections4.CollectionUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -39,48 +45,53 @@ public class MonitorBus { public void run() { MonitorBus.printStatistics(); } - }, 30*1000L, 1*60*1000L); + }, 5*60*1000L, 5*60*1000L); } public static void addStatistics(CompStatistics statistics){ if(statisticsMap.containsKey(statistics.getComponentClazzName())){ - statisticsMap.get(statistics.getComponentClazzName()).add(statistics); + statisticsMap.get(statistics.getComponentClazzName()).offer(statistics); }else{ LimitQueue queue = new LimitQueue(QUEUE_LIMIT_SIZE); - queue.add(statistics); + queue.offer(statistics); statisticsMap.put(statistics.getComponentClazzName(), queue); } } public static void printStatistics(){ try{ - Map compAverageTimeSpent = new HashMap(); - Map compAverageMemorySpent = new HashMap(); + Map compAverageTimeSpent = new HashMap(); long totalTimeSpent = 0; - long totalMemorySpent = 0; for(Entry> 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()); + compAverageTimeSpent.put(entry.getKey(), new BigDecimal(totalTimeSpent).divide(new BigDecimal(entry.getValue().size()), 2, RoundingMode.HALF_UP)); } - 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 entry : compAverageTimeSpent.entrySet()){ - System.out.println("COMPONENT["+entry.getKey()+"] AVERAGE TIME SPENT : " + entry.getValue()); + + List> compAverageTimeSpentEntryList = new ArrayList<>(compAverageTimeSpent.entrySet()); + + Collections.sort(compAverageTimeSpentEntryList,new Comparator>() { + @Override + public int compare(Entry o1, Entry o2) { + return o2.getValue().compareTo(o1.getValue()); + } + }); + + StringBuilder logStr = new StringBuilder(); + logStr.append("以下为LiteFlow中间件统计信息:\n"); + logStr.append("======================================================================================\n"); + logStr.append("===================================SLOT INFO==========================================\n"); + logStr.append(MessageFormat.format("SLOT TOTAL SIZE : {0}\n", DataBus.SLOT_SIZE)); + logStr.append(MessageFormat.format("SLOT OCCUPY COUNT : {0}\n", DataBus.OCCUPY_COUNT)); + logStr.append("===============================TIME AVERAGE SPENT=====================================\n"); + for(Entry entry : compAverageTimeSpentEntryList){ + logStr.append(MessageFormat.format("COMPONENT[{0}] AVERAGE TIME SPENT : {1}\n", entry.getKey(), entry.getValue())); } - System.out.println("==============================MEMORY AVERAGE SPENT===================================="); - for(Entry 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("======================================================================================"); + logStr.append("======================================================================================\n"); + LOG.info(logStr.toString()); }catch(Exception e){ LOG.error("print statistics cause error",e); } diff --git a/src/main/java/com/thebeastshop/liteflow/parser/FlowParser.java b/src/main/java/com/thebeastshop/liteflow/parser/FlowParser.java index 3fc4fb187..6537e376c 100644 --- a/src/main/java/com/thebeastshop/liteflow/parser/FlowParser.java +++ b/src/main/java/com/thebeastshop/liteflow/parser/FlowParser.java @@ -109,7 +109,7 @@ public class FlowParser { RegexEntity regexEntity = null; Node node = null; for (int i = 0; i < condArray.length; i++) { - regexEntity = parseNodeStr(condArray[i]); + regexEntity = parseNodeStr(condArray[i].trim()); node = nodeMap.get(regexEntity.getCondNode()); chainNodeList.add(node); if(regexEntity.getRealNodeArray() != null){ @@ -127,7 +127,7 @@ public class FlowParser { conditionList.add(new WhenCondition(chainNodeList)); } } - FlowBus.addChain(chainName, new Chain(conditionList)); + FlowBus.addChain(chainName, new Chain(chainName,conditionList)); } } catch (Exception e) { LOG.error("FlowParser parser exception: {}", e); @@ -176,14 +176,18 @@ public class FlowParser { list.add(m.group()); } RegexEntity regexEntity = new RegexEntity(); - regexEntity.setCondNode(list.get(0)); + regexEntity.setCondNode(list.get(0).trim()); if(list.size() > 1){ - regexEntity.setRealNodeArray(list.get(1).split("\\|")); + String[] realNodeArray = list.get(1).split("\\|"); + for (int i = 0; i < realNodeArray.length; i++) { + realNodeArray[i] = realNodeArray[i].trim(); + } + regexEntity.setRealNodeArray(realNodeArray); } return regexEntity; } public static void main(String[] args) { - System.out.println(parseNodeStr("aaaa(bbb(xxxx|yyyy)|yyyy)")); + System.out.println(parseNodeStr("aaaa ( xxxx | yyyy | vvvv )")); } } diff --git a/src/main/java/com/thebeastshop/liteflow/spring/ComponentScaner.java b/src/main/java/com/thebeastshop/liteflow/spring/ComponentScaner.java index 1249e21cf..81c74891a 100644 --- a/src/main/java/com/thebeastshop/liteflow/spring/ComponentScaner.java +++ b/src/main/java/com/thebeastshop/liteflow/spring/ComponentScaner.java @@ -31,6 +31,7 @@ public class ComponentScaner implements BeanPostProcessor, PriorityOrdered { return Ordered.LOWEST_PRECEDENCE; } + @SuppressWarnings("rawtypes") @Override public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException { Class clazz = bean.getClass(); diff --git a/src/test/java/com/thebeastshop/liteflow/test/TestMain.java b/src/test/java/com/thebeastshop/liteflow/test/TestMain.java index 0406f66ae..acf21a16d 100644 --- a/src/test/java/com/thebeastshop/liteflow/test/TestMain.java +++ b/src/test/java/com/thebeastshop/liteflow/test/TestMain.java @@ -12,17 +12,17 @@ package com.thebeastshop.liteflow.test; import java.util.Arrays; import com.thebeastshop.liteflow.core.FlowExecutor; -import com.thebeastshop.liteflow.parser.FlowParser; +import com.thebeastshop.liteflow.entity.data.Slot; 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.setRulePath(Arrays.asList(new String[]{"config/flow.xml"})); executor.init(); for(int i=0;i<1;i++){ - String response = executor.execute("chain1", "it's a request"); - System.out.println(response); + Slot slot = executor.execute("chain1", "it's a request"); + System.out.println(slot); } diff --git a/src/test/java/com/thebeastshop/liteflow/test/TestWithSpringMain.java b/src/test/java/com/thebeastshop/liteflow/test/TestWithSpringMain.java index 2a0c459ea..a5e7f777e 100644 --- a/src/test/java/com/thebeastshop/liteflow/test/TestWithSpringMain.java +++ b/src/test/java/com/thebeastshop/liteflow/test/TestWithSpringMain.java @@ -11,6 +11,7 @@ import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; import com.thebeastshop.liteflow.core.FlowExecutor; +import com.thebeastshop.liteflow.entity.data.Slot; @@ -29,12 +30,24 @@ public class TestWithSpringMain { executorService.submit(new Thread(){ @Override public void run() { - String response = flowExecutor.execute("chain2", "it's a request"); - System.out.println(response); + Slot slot = flowExecutor.execute("chain1", "it's a request"); + System.out.println(slot); } }); } System.out.println("done!"); System.in.read(); } + + @Test + public void test2() throws Exception { + try { + Slot slot = flowExecutor.execute("chain3", "it's a request"); + System.out.println(slot); + System.in.read(); + }catch(Exception e) { + e.printStackTrace(); + } + + } } diff --git a/src/test/java/com/thebeastshop/liteflow/test/component/BComponent.java b/src/test/java/com/thebeastshop/liteflow/test/component/BComponent.java index cac3113eb..be2b80c74 100644 --- a/src/test/java/com/thebeastshop/liteflow/test/component/BComponent.java +++ b/src/test/java/com/thebeastshop/liteflow/test/component/BComponent.java @@ -9,9 +9,6 @@ */ package com.thebeastshop.liteflow.test.component; -import java.util.ArrayList; -import java.util.List; - import org.springframework.stereotype.Component; import com.thebeastshop.liteflow.core.NodeComponent; diff --git a/src/test/java/com/thebeastshop/liteflow/test/component/CondComponent.java b/src/test/java/com/thebeastshop/liteflow/test/component/CondComponent.java index e742cf2db..1b39b1cf0 100644 --- a/src/test/java/com/thebeastshop/liteflow/test/component/CondComponent.java +++ b/src/test/java/com/thebeastshop/liteflow/test/component/CondComponent.java @@ -10,13 +10,14 @@ package com.thebeastshop.liteflow.test.component; import org.springframework.stereotype.Component; +import com.thebeastshop.liteflow.core.NodeComponent; import com.thebeastshop.liteflow.core.NodeCondComponent; @Component("cond") public class CondComponent extends NodeCondComponent { @Override - protected String processCond() throws Exception { - return "b"; + protected Class processCond() throws Exception { + return BComponent.class; } } diff --git a/src/test/java/com/thebeastshop/liteflow/test/component/HComponent.java b/src/test/java/com/thebeastshop/liteflow/test/component/HComponent.java new file mode 100644 index 000000000..a58eb4448 --- /dev/null +++ b/src/test/java/com/thebeastshop/liteflow/test/component/HComponent.java @@ -0,0 +1,32 @@ +/** + *

Title: liteFlow

+ *

Description: 轻量级的组件式流程框架

+ *

Copyright: Copyright (c) 2017

+ * @author Bryan.Zhang + * @email weenyc31@163.com + * @Date 2017-8-1 + * @version 1.0 + */ +package com.thebeastshop.liteflow.test.component; + +import javax.annotation.Resource; + +import org.springframework.stereotype.Component; + +import com.thebeastshop.liteflow.core.FlowExecutor; +import com.thebeastshop.liteflow.core.NodeComponent; +import com.thebeastshop.liteflow.entity.data.DefaultSlot; + +@Component("h") +public class HComponent extends NodeComponent { + + @Resource + private FlowExecutor flowExecutor; + + @Override + public void process() { + System.out.println("Hcomponent executed!"); + flowExecutor.invoke("strategy1",3, DefaultSlot.class, this.getSlotIndex()); + } + +} diff --git a/src/test/java/com/thebeastshop/liteflow/test/component/M1Component.java b/src/test/java/com/thebeastshop/liteflow/test/component/M1Component.java new file mode 100644 index 000000000..9efbb153f --- /dev/null +++ b/src/test/java/com/thebeastshop/liteflow/test/component/M1Component.java @@ -0,0 +1,30 @@ +/** + *

Title: liteFlow

+ *

Description: 轻量级的组件式流程框架

+ *

Copyright: Copyright (c) 2017

+ * @author Bryan.Zhang + * @email weenyc31@163.com + * @Date 2017-8-1 + * @version 1.0 + */ +package com.thebeastshop.liteflow.test.component; + +import javax.annotation.Resource; + +import org.springframework.stereotype.Component; + +import com.thebeastshop.liteflow.core.FlowExecutor; +import com.thebeastshop.liteflow.core.NodeComponent; + +@Component("m1") +public class M1Component extends NodeComponent { + + @Resource + private FlowExecutor flowExecutor; + + @Override + public void process() { + System.out.println("m1 component executed!"); + } + +} diff --git a/src/test/java/com/thebeastshop/liteflow/test/component/M2Component.java b/src/test/java/com/thebeastshop/liteflow/test/component/M2Component.java new file mode 100644 index 000000000..96a6bf906 --- /dev/null +++ b/src/test/java/com/thebeastshop/liteflow/test/component/M2Component.java @@ -0,0 +1,30 @@ +/** + *

Title: liteFlow

+ *

Description: 轻量级的组件式流程框架

+ *

Copyright: Copyright (c) 2017

+ * @author Bryan.Zhang + * @email weenyc31@163.com + * @Date 2017-8-1 + * @version 1.0 + */ +package com.thebeastshop.liteflow.test.component; + +import javax.annotation.Resource; + +import org.springframework.stereotype.Component; + +import com.thebeastshop.liteflow.core.FlowExecutor; +import com.thebeastshop.liteflow.core.NodeComponent; + +@Component("m2") +public class M2Component extends NodeComponent { + + @Resource + private FlowExecutor flowExecutor; + + @Override + public void process() { + System.out.println("m2 component executed!"); + } + +} diff --git a/src/test/java/com/thebeastshop/liteflow/test/component/M3Component.java b/src/test/java/com/thebeastshop/liteflow/test/component/M3Component.java new file mode 100644 index 000000000..13926b7ce --- /dev/null +++ b/src/test/java/com/thebeastshop/liteflow/test/component/M3Component.java @@ -0,0 +1,32 @@ +/** + *

Title: liteFlow

+ *

Description: 轻量级的组件式流程框架

+ *

Copyright: Copyright (c) 2017

+ * @author Bryan.Zhang + * @email weenyc31@163.com + * @Date 2017-8-1 + * @version 1.0 + */ +package com.thebeastshop.liteflow.test.component; + +import javax.annotation.Resource; + +import org.springframework.stereotype.Component; + +import com.thebeastshop.liteflow.core.FlowExecutor; +import com.thebeastshop.liteflow.core.NodeComponent; +import com.thebeastshop.liteflow.entity.data.DefaultSlot; + +@Component("m3") +public class M3Component extends NodeComponent { + + @Resource + private FlowExecutor flowExecutor; + + @Override + public void process() { + System.out.println("m3 component executed!"); + flowExecutor.invoke("strategy2",10, DefaultSlot.class, this.getSlotIndex()); + } + +} diff --git a/src/test/java/com/thebeastshop/liteflow/test/component/MComponent.java b/src/test/java/com/thebeastshop/liteflow/test/component/MComponent.java new file mode 100644 index 000000000..4846a4730 --- /dev/null +++ b/src/test/java/com/thebeastshop/liteflow/test/component/MComponent.java @@ -0,0 +1,40 @@ +/** + *

Title: liteFlow

+ *

Description: 轻量级的组件式流程框架

+ *

Copyright: Copyright (c) 2017

+ * @author Bryan.Zhang + * @email weenyc31@163.com + * @Date 2017-8-1 + * @version 1.0 + */ +package com.thebeastshop.liteflow.test.component; + +import javax.annotation.Resource; + +import org.springframework.stereotype.Component; + +import com.thebeastshop.liteflow.core.FlowExecutor; +import com.thebeastshop.liteflow.core.NodeComponent; +import com.thebeastshop.liteflow.core.NodeCondComponent; + +@Component("m") +public class MComponent extends NodeCondComponent { + + @Resource + private FlowExecutor flowExecutor; + + @Override + protected Class processCond() throws Exception { + System.out.println("m conponent executed"); + Integer flag = this.getSlot().getChainReqData("strategy1"); + if(flag == 1) { + return M1Component.class; + }else if(flag == 2){ + return M2Component.class; + }else { + return M3Component.class; + } + + } + +} diff --git a/src/test/java/com/thebeastshop/liteflow/test/component/P1Component.java b/src/test/java/com/thebeastshop/liteflow/test/component/P1Component.java new file mode 100644 index 000000000..c0f1a0c00 --- /dev/null +++ b/src/test/java/com/thebeastshop/liteflow/test/component/P1Component.java @@ -0,0 +1,30 @@ +/** + *

Title: liteFlow

+ *

Description: 轻量级的组件式流程框架

+ *

Copyright: Copyright (c) 2017

+ * @author Bryan.Zhang + * @email weenyc31@163.com + * @Date 2017-8-1 + * @version 1.0 + */ +package com.thebeastshop.liteflow.test.component; + +import javax.annotation.Resource; + +import org.springframework.stereotype.Component; + +import com.thebeastshop.liteflow.core.FlowExecutor; +import com.thebeastshop.liteflow.core.NodeComponent; + +@Component("p1") +public class P1Component extends NodeComponent { + + @Resource + private FlowExecutor flowExecutor; + + @Override + public void process() { + System.out.println("p1 component executed!"); + } + +} diff --git a/src/test/java/com/thebeastshop/liteflow/test/component/P2Component.java b/src/test/java/com/thebeastshop/liteflow/test/component/P2Component.java new file mode 100644 index 000000000..d60947c16 --- /dev/null +++ b/src/test/java/com/thebeastshop/liteflow/test/component/P2Component.java @@ -0,0 +1,30 @@ +/** + *

Title: liteFlow

+ *

Description: 轻量级的组件式流程框架

+ *

Copyright: Copyright (c) 2017

+ * @author Bryan.Zhang + * @email weenyc31@163.com + * @Date 2017-8-1 + * @version 1.0 + */ +package com.thebeastshop.liteflow.test.component; + +import javax.annotation.Resource; + +import org.springframework.stereotype.Component; + +import com.thebeastshop.liteflow.core.FlowExecutor; +import com.thebeastshop.liteflow.core.NodeComponent; + +@Component("p2") +public class P2Component extends NodeComponent { + + @Resource + private FlowExecutor flowExecutor; + + @Override + public void process() { + System.out.println("p2 component executed!"); + } + +} diff --git a/src/test/java/com/thebeastshop/liteflow/test/component/PComponent.java b/src/test/java/com/thebeastshop/liteflow/test/component/PComponent.java new file mode 100644 index 000000000..d4f962bff --- /dev/null +++ b/src/test/java/com/thebeastshop/liteflow/test/component/PComponent.java @@ -0,0 +1,38 @@ +/** + *

Title: liteFlow

+ *

Description: 轻量级的组件式流程框架

+ *

Copyright: Copyright (c) 2017

+ * @author Bryan.Zhang + * @email weenyc31@163.com + * @Date 2017-8-1 + * @version 1.0 + */ +package com.thebeastshop.liteflow.test.component; + +import javax.annotation.Resource; + +import org.springframework.stereotype.Component; + +import com.thebeastshop.liteflow.core.FlowExecutor; +import com.thebeastshop.liteflow.core.NodeComponent; +import com.thebeastshop.liteflow.core.NodeCondComponent; + +@Component("p") +public class PComponent extends NodeCondComponent { + + @Resource + private FlowExecutor flowExecutor; + + @Override + protected Class processCond() throws Exception { + System.out.println("p conponent executed"); + Integer flag = this.getSlot().getChainReqData("strategy2"); + if(flag == 10) { + return P1Component.class; + }else { + return P2Component.class; + } + + } + +} diff --git a/src/test/resources/flow.xml b/src/test/resources/config/flow.xml similarity index 69% rename from src/test/resources/flow.xml rename to src/test/resources/config/flow.xml index dfa1dc4bf..25f111ce6 100644 --- a/src/test/resources/flow.xml +++ b/src/test/resources/config/flow.xml @@ -13,19 +13,25 @@ - + - - + + - - - + + + + + + + + + \ No newline at end of file diff --git a/src/test/resources/spring-test.xml b/src/test/resources/spring-test.xml index 4caa5f00f..685098480 100644 --- a/src/test/resources/spring-test.xml +++ b/src/test/resources/spring-test.xml @@ -10,10 +10,10 @@ - + - flow.xml + config/flow.xml