可正常启动,工作流可以正常运行,增加了其他节点,但是还没运行过,编译无错。
This commit is contained in:
parent
6a9b0f36b0
commit
ed0309f45c
@ -2,7 +2,7 @@ package com.qqchen.deploy.backend.workflow.dto;
|
||||
|
||||
import com.qqchen.deploy.backend.framework.dto.BaseDTO;
|
||||
import com.qqchen.deploy.backend.workflow.engine.definition.TaskExecutorDefinition;
|
||||
import com.qqchen.deploy.backend.workflow.enums.NodeCategory;
|
||||
import com.qqchen.deploy.backend.workflow.enums.NodeCategoryEnum;
|
||||
import jakarta.validation.Valid;
|
||||
import jakarta.validation.constraints.NotBlank;
|
||||
import jakarta.validation.constraints.NotNull;
|
||||
@ -39,7 +39,7 @@ public class NodeTypeDTO extends BaseDTO {
|
||||
* 节点类型分类
|
||||
*/
|
||||
@NotNull(message = "节点类型分类不能为空")
|
||||
private NodeCategory category;
|
||||
private NodeCategoryEnum category;
|
||||
|
||||
/**
|
||||
* 节点图标
|
||||
|
||||
@ -3,7 +3,7 @@ package com.qqchen.deploy.backend.workflow.dto.query;
|
||||
import com.qqchen.deploy.backend.framework.annotation.QueryField;
|
||||
import com.qqchen.deploy.backend.framework.enums.QueryType;
|
||||
import com.qqchen.deploy.backend.framework.query.BaseQuery;
|
||||
import com.qqchen.deploy.backend.workflow.enums.NodeCategory;
|
||||
import com.qqchen.deploy.backend.workflow.enums.NodeCategoryEnum;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
|
||||
@ -30,5 +30,5 @@ public class NodeTypeQuery extends BaseQuery {
|
||||
* 节点类型分类
|
||||
*/
|
||||
@QueryField(field = "category")
|
||||
private NodeCategory category;
|
||||
private NodeCategoryEnum category;
|
||||
}
|
||||
@ -6,7 +6,7 @@ import com.qqchen.deploy.backend.framework.enums.ResponseCode;
|
||||
import com.qqchen.deploy.backend.workflow.engine.context.DefaultWorkflowContext;
|
||||
import com.qqchen.deploy.backend.workflow.engine.context.WorkflowContextOperations;
|
||||
import com.qqchen.deploy.backend.workflow.engine.exception.WorkflowEngineException;
|
||||
import com.qqchen.deploy.backend.workflow.engine.executor.NodeExecutor;
|
||||
import com.qqchen.deploy.backend.workflow.engine.executor.node.NodeExecutor;
|
||||
import com.qqchen.deploy.backend.workflow.engine.parser.WorkflowDefinitionParser;
|
||||
import com.qqchen.deploy.backend.workflow.entity.NodeConfig;
|
||||
import com.qqchen.deploy.backend.workflow.entity.NodeInstance;
|
||||
@ -27,8 +27,6 @@ import org.springframework.stereotype.Component;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
package com.qqchen.deploy.backend.workflow.engine.config;
|
||||
|
||||
import com.qqchen.deploy.backend.workflow.engine.executor.NodeExecutor;
|
||||
import com.qqchen.deploy.backend.workflow.engine.executor.node.NodeExecutor;
|
||||
import com.qqchen.deploy.backend.workflow.engine.executor.task.TaskExecutor;
|
||||
import com.qqchen.deploy.backend.workflow.enums.NodeTypeEnum;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
|
||||
@ -1,22 +0,0 @@
|
||||
package com.qqchen.deploy.backend.workflow.engine.executor;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
public class GatewayCondition {
|
||||
|
||||
/**
|
||||
* 条件表达式(SpEL表达式)
|
||||
*/
|
||||
private String expression;
|
||||
|
||||
/**
|
||||
* 下一个节点ID
|
||||
*/
|
||||
private String nextNodeId;
|
||||
|
||||
/**
|
||||
* 条件描述
|
||||
*/
|
||||
private String description;
|
||||
}
|
||||
@ -1,38 +0,0 @@
|
||||
package com.qqchen.deploy.backend.workflow.engine.executor;
|
||||
|
||||
import lombok.Data;
|
||||
import java.util.List;
|
||||
|
||||
@Data
|
||||
public class GatewayConfig {
|
||||
|
||||
/**
|
||||
* 网关类型
|
||||
*/
|
||||
private GatewayType type;
|
||||
|
||||
/**
|
||||
* 网关名称
|
||||
*/
|
||||
private String name;
|
||||
|
||||
/**
|
||||
* 网关描述
|
||||
*/
|
||||
private String description;
|
||||
|
||||
/**
|
||||
* 条件列表(排他网关和包容网关使用)
|
||||
*/
|
||||
private List<GatewayCondition> conditions;
|
||||
|
||||
/**
|
||||
* 默认节点ID(排他网关使用)
|
||||
*/
|
||||
private String defaultNodeId;
|
||||
|
||||
/**
|
||||
* 并行节点ID列表(并行网关使用)
|
||||
*/
|
||||
private List<String> parallelNodeIds;
|
||||
}
|
||||
@ -1,158 +0,0 @@
|
||||
package com.qqchen.deploy.backend.workflow.engine.executor;
|
||||
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.qqchen.deploy.backend.framework.enums.ResponseCode;
|
||||
import com.qqchen.deploy.backend.workflow.engine.context.WorkflowContextOperations;
|
||||
import com.qqchen.deploy.backend.workflow.engine.exception.WorkflowEngineException;
|
||||
import com.qqchen.deploy.backend.workflow.entity.NodeInstance;
|
||||
import com.qqchen.deploy.backend.workflow.enums.NodeTypeEnum;
|
||||
import lombok.Data;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.expression.Expression;
|
||||
import org.springframework.expression.ExpressionParser;
|
||||
import org.springframework.expression.spel.standard.SpelExpressionParser;
|
||||
import org.springframework.expression.spel.support.StandardEvaluationContext;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
|
||||
@Slf4j
|
||||
@Component
|
||||
public class GatewayNodeExecutor implements NodeExecutor {
|
||||
|
||||
private final ObjectMapper objectMapper = new ObjectMapper();
|
||||
private final ExpressionParser expressionParser = new SpelExpressionParser();
|
||||
|
||||
@Override
|
||||
public NodeTypeEnum getNodeType() {
|
||||
return NodeTypeEnum.GATEWAY;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(NodeInstance nodeInstance, WorkflowContextOperations context) {
|
||||
try {
|
||||
GatewayConfig config = objectMapper.readValue(nodeInstance.getConfig(), GatewayConfig.class);
|
||||
|
||||
if (config.getType() == null) {
|
||||
throw new WorkflowEngineException(ResponseCode.WORKFLOW_NODE_CONFIG_ERROR);
|
||||
}
|
||||
|
||||
switch (config.getType()) {
|
||||
case PARALLEL:
|
||||
handleParallelGateway(nodeInstance, context, config);
|
||||
break;
|
||||
case EXCLUSIVE:
|
||||
handleExclusiveGateway(nodeInstance, context, config);
|
||||
break;
|
||||
case INCLUSIVE:
|
||||
handleInclusiveGateway(nodeInstance, context, config);
|
||||
break;
|
||||
default:
|
||||
throw new WorkflowEngineException(ResponseCode.WORKFLOW_NODE_CONFIG_ERROR);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
throw new WorkflowEngineException(ResponseCode.WORKFLOW_NODE_EXECUTION_FAILED, e);
|
||||
}
|
||||
}
|
||||
|
||||
private void handleExclusiveGateway(NodeInstance nodeInstance, WorkflowContextOperations context, GatewayConfig config) {
|
||||
try {
|
||||
for (GatewayCondition condition : config.getConditions()) {
|
||||
if (evaluateCondition(condition.getExpression(), context)) {
|
||||
nodeInstance.setOutput(objectMapper.createObjectNode()
|
||||
.put("nextNodeId", condition.getNextNodeId())
|
||||
.toString());
|
||||
return;
|
||||
}
|
||||
}
|
||||
throw new WorkflowEngineException(ResponseCode.WORKFLOW_NODE_EXECUTION_FAILED);
|
||||
} catch (Exception e) {
|
||||
throw new WorkflowEngineException(ResponseCode.WORKFLOW_NODE_EXECUTION_FAILED, e);
|
||||
}
|
||||
}
|
||||
|
||||
private void handleParallelGateway(NodeInstance nodeInstance, WorkflowContextOperations context, GatewayConfig config) {
|
||||
try {
|
||||
List<String> nextNodeIds = new ArrayList<>();
|
||||
for (GatewayCondition condition : config.getConditions()) {
|
||||
nextNodeIds.add(condition.getNextNodeId());
|
||||
}
|
||||
nodeInstance.setOutput(objectMapper.createObjectNode()
|
||||
.put("nextNodeIds", String.join(",", nextNodeIds))
|
||||
.toString());
|
||||
} catch (Exception e) {
|
||||
throw new WorkflowEngineException(ResponseCode.WORKFLOW_NODE_EXECUTION_FAILED, e);
|
||||
}
|
||||
}
|
||||
|
||||
private void handleInclusiveGateway(NodeInstance nodeInstance, WorkflowContextOperations context, GatewayConfig config) {
|
||||
try {
|
||||
List<String> nextNodeIds = new ArrayList<>();
|
||||
for (GatewayCondition condition : config.getConditions()) {
|
||||
if (evaluateCondition(condition.getExpression(), context)) {
|
||||
nextNodeIds.add(condition.getNextNodeId());
|
||||
}
|
||||
}
|
||||
if (nextNodeIds.isEmpty()) {
|
||||
throw new WorkflowEngineException(ResponseCode.WORKFLOW_NODE_EXECUTION_FAILED);
|
||||
}
|
||||
nodeInstance.setOutput(objectMapper.createObjectNode()
|
||||
.put("nextNodeIds", String.join(",", nextNodeIds))
|
||||
.toString());
|
||||
} catch (Exception e) {
|
||||
throw new WorkflowEngineException(ResponseCode.WORKFLOW_NODE_EXECUTION_FAILED, e);
|
||||
}
|
||||
}
|
||||
|
||||
private boolean evaluateCondition(String expression, WorkflowContextOperations context) {
|
||||
try {
|
||||
StandardEvaluationContext evaluationContext = new StandardEvaluationContext();
|
||||
evaluationContext.setVariables(context.getVariables());
|
||||
Expression exp = expressionParser.parseExpression(expression);
|
||||
return exp.getValue(evaluationContext, Boolean.class);
|
||||
} catch (Exception e) {
|
||||
throw new WorkflowEngineException(ResponseCode.WORKFLOW_NODE_EXECUTION_FAILED, e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void validate(String config) {
|
||||
try {
|
||||
GatewayConfig gatewayConfig = objectMapper.readValue(config, GatewayConfig.class);
|
||||
if (gatewayConfig.getType() == null) {
|
||||
throw new WorkflowEngineException(ResponseCode.WORKFLOW_NODE_CONFIG_ERROR);
|
||||
}
|
||||
// 验证条件表达式
|
||||
if (gatewayConfig.getConditions() != null) {
|
||||
for (GatewayCondition condition : gatewayConfig.getConditions()) {
|
||||
try {
|
||||
expressionParser.parseExpression(condition.getExpression());
|
||||
} catch (Exception e) {
|
||||
throw new WorkflowEngineException(ResponseCode.WORKFLOW_NODE_CONFIG_ERROR);
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
throw new WorkflowEngineException(ResponseCode.WORKFLOW_NODE_CONFIG_ERROR);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void terminate(NodeInstance nodeInstance, WorkflowContextOperations context) {
|
||||
// Gateway nodes are instant operations, no need to terminate
|
||||
}
|
||||
|
||||
@Data
|
||||
public static class GatewayConfig {
|
||||
private GatewayType type; // 网关类型:PARALLEL, EXCLUSIVE, INCLUSIVE
|
||||
private List<GatewayCondition> conditions; // 网关条件
|
||||
}
|
||||
|
||||
@Data
|
||||
public static class GatewayCondition {
|
||||
private String expression; // 条件表达式
|
||||
private String nextNodeId; // 下一个节点ID
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,35 @@
|
||||
package com.qqchen.deploy.backend.workflow.engine.executor.gateway;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* 分支汇聚配置
|
||||
*/
|
||||
@Data
|
||||
public class BranchConvergeConfig {
|
||||
/**
|
||||
* 汇聚策略
|
||||
*/
|
||||
private ConvergeStrategy strategy;
|
||||
|
||||
/**
|
||||
* 需要完成的分支数量(N个完成时使用)
|
||||
*/
|
||||
private Integer requiredCount;
|
||||
|
||||
public enum ConvergeStrategy {
|
||||
ALL("全部完成"),
|
||||
ANY("任一完成"),
|
||||
N("N个完成");
|
||||
|
||||
private final String description;
|
||||
|
||||
ConvergeStrategy(String description) {
|
||||
this.description = description;
|
||||
}
|
||||
|
||||
public String getDescription() {
|
||||
return description;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,46 @@
|
||||
package com.qqchen.deploy.backend.workflow.engine.executor.gateway;
|
||||
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 基于条件的网关配置基类
|
||||
*/
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
public abstract class ConditionalGatewayConfig extends GatewayConfig {
|
||||
/**
|
||||
* 条件分支列表
|
||||
*/
|
||||
private List<ConditionalBranch> branches;
|
||||
|
||||
/**
|
||||
* 默认分支节点ID
|
||||
*/
|
||||
private String defaultNodeId;
|
||||
|
||||
@Data
|
||||
public static class ConditionalBranch {
|
||||
/**
|
||||
* 分支名称
|
||||
*/
|
||||
private String name;
|
||||
|
||||
/**
|
||||
* 条件表达式
|
||||
*/
|
||||
private String condition;
|
||||
|
||||
/**
|
||||
* 目标节点ID
|
||||
*/
|
||||
private String targetNodeId;
|
||||
|
||||
/**
|
||||
* 分支描述
|
||||
*/
|
||||
private String description;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,41 @@
|
||||
package com.qqchen.deploy.backend.workflow.engine.executor.gateway;
|
||||
|
||||
import com.qqchen.deploy.backend.workflow.engine.context.WorkflowContextOperations;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import org.springframework.expression.ExpressionParser;
|
||||
import org.springframework.expression.spel.standard.SpelExpressionParser;
|
||||
import org.springframework.expression.spel.support.StandardEvaluationContext;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 排他网关配置
|
||||
*/
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
public class ExclusiveGatewayConfig extends ConditionalGatewayConfig {
|
||||
private final ExpressionParser expressionParser = new SpelExpressionParser();
|
||||
|
||||
@Override
|
||||
public List<String> getNextNodeIds(WorkflowContextOperations context) {
|
||||
// 返回第一个满足条件的分支的targetNodeId
|
||||
for (ConditionalBranch branch : getBranches()) {
|
||||
if (evaluateCondition(branch.getCondition(), context)) {
|
||||
return Collections.singletonList(branch.getTargetNodeId());
|
||||
}
|
||||
}
|
||||
return Collections.singletonList(getDefaultNodeId());
|
||||
}
|
||||
|
||||
private boolean evaluateCondition(String condition, WorkflowContextOperations context) {
|
||||
try {
|
||||
StandardEvaluationContext evaluationContext = new StandardEvaluationContext(context);
|
||||
return Boolean.TRUE.equals(expressionParser.parseExpression(condition)
|
||||
.getValue(evaluationContext, Boolean.class));
|
||||
} catch (Exception e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,41 @@
|
||||
package com.qqchen.deploy.backend.workflow.engine.executor.gateway;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonSubTypes;
|
||||
import com.fasterxml.jackson.annotation.JsonTypeInfo;
|
||||
import com.qqchen.deploy.backend.workflow.engine.context.WorkflowContextOperations;
|
||||
import com.qqchen.deploy.backend.workflow.enums.GatewayTypeEnum;
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 网关配置基类
|
||||
*/
|
||||
@Data
|
||||
@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, property = "type")
|
||||
@JsonSubTypes({
|
||||
@JsonSubTypes.Type(value = ExclusiveGatewayConfig.class, name = "EXCLUSIVE"),
|
||||
@JsonSubTypes.Type(value = ParallelGatewayConfig.class, name = "PARALLEL"),
|
||||
@JsonSubTypes.Type(value = InclusiveGatewayConfig.class, name = "INCLUSIVE")
|
||||
})
|
||||
public abstract class GatewayConfig {
|
||||
/**
|
||||
* 网关类型
|
||||
*/
|
||||
private GatewayTypeEnum type;
|
||||
|
||||
/**
|
||||
* 网关名称
|
||||
*/
|
||||
private String name;
|
||||
|
||||
/**
|
||||
* 网关描述
|
||||
*/
|
||||
private String description;
|
||||
|
||||
/**
|
||||
* 获取下一个节点IDs
|
||||
*/
|
||||
public abstract List<String> getNextNodeIds(WorkflowContextOperations context);
|
||||
}
|
||||
@ -0,0 +1,59 @@
|
||||
package com.qqchen.deploy.backend.workflow.engine.executor.gateway;
|
||||
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.qqchen.deploy.backend.framework.enums.ResponseCode;
|
||||
import com.qqchen.deploy.backend.workflow.engine.context.WorkflowContextOperations;
|
||||
import com.qqchen.deploy.backend.workflow.engine.exception.WorkflowEngineException;
|
||||
import com.qqchen.deploy.backend.workflow.engine.executor.node.NodeExecutor;
|
||||
import com.qqchen.deploy.backend.workflow.entity.NodeInstance;
|
||||
import com.qqchen.deploy.backend.workflow.enums.NodeTypeEnum;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Slf4j
|
||||
@Component
|
||||
public class GatewayNodeExecutor implements NodeExecutor {
|
||||
|
||||
private final ObjectMapper objectMapper = new ObjectMapper();
|
||||
|
||||
@Override
|
||||
public NodeTypeEnum getNodeType() {
|
||||
return NodeTypeEnum.GATEWAY;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(NodeInstance nodeInstance, WorkflowContextOperations context) {
|
||||
try {
|
||||
// 解析网关配置
|
||||
GatewayConfig config = objectMapper.readValue(nodeInstance.getConfig(), GatewayConfig.class);
|
||||
|
||||
// 获取下一个节点IDs
|
||||
List<String> nextNodeIds = config.getNextNodeIds(context);
|
||||
|
||||
// 设置输出
|
||||
nodeInstance.setOutput(objectMapper.createObjectNode()
|
||||
.put("nextNodeIds", String.join(",", nextNodeIds))
|
||||
.toString());
|
||||
|
||||
} catch (Exception e) {
|
||||
log.error("Gateway node execution failed", e);
|
||||
throw new WorkflowEngineException(ResponseCode.WORKFLOW_NODE_EXECUTION_FAILED, e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void validate(String config) {
|
||||
try {
|
||||
objectMapper.readValue(config, GatewayConfig.class);
|
||||
} catch (Exception e) {
|
||||
throw new WorkflowEngineException(ResponseCode.WORKFLOW_NODE_CONFIG_ERROR);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void terminate(NodeInstance nodeInstance, WorkflowContextOperations context) {
|
||||
// Gateway nodes are instant operations, no need to terminate
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,51 @@
|
||||
package com.qqchen.deploy.backend.workflow.engine.executor.gateway;
|
||||
|
||||
import com.qqchen.deploy.backend.workflow.engine.context.WorkflowContextOperations;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import org.springframework.expression.ExpressionParser;
|
||||
import org.springframework.expression.spel.standard.SpelExpressionParser;
|
||||
import org.springframework.expression.spel.support.StandardEvaluationContext;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* 包容网关配置
|
||||
*/
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
public class InclusiveGatewayConfig extends ConditionalGatewayConfig {
|
||||
/**
|
||||
* 汇聚配置
|
||||
*/
|
||||
private BranchConvergeConfig convergeConfig;
|
||||
|
||||
private final ExpressionParser expressionParser = new SpelExpressionParser();
|
||||
|
||||
@Override
|
||||
public List<String> getNextNodeIds(WorkflowContextOperations context) {
|
||||
// 返回所有满足条件的分支的targetNodeId
|
||||
List<String> nextNodeIds = getBranches().stream()
|
||||
.filter(branch -> evaluateCondition(branch.getCondition(), context))
|
||||
.map(ConditionalBranch::getTargetNodeId)
|
||||
.collect(Collectors.toList());
|
||||
|
||||
// 如果没有满足条件的分支,使用默认分支
|
||||
if (nextNodeIds.isEmpty() && getDefaultNodeId() != null) {
|
||||
nextNodeIds.add(getDefaultNodeId());
|
||||
}
|
||||
|
||||
return nextNodeIds;
|
||||
}
|
||||
|
||||
private boolean evaluateCondition(String condition, WorkflowContextOperations context) {
|
||||
try {
|
||||
StandardEvaluationContext evaluationContext = new StandardEvaluationContext(context);
|
||||
return Boolean.TRUE.equals(expressionParser.parseExpression(condition)
|
||||
.getValue(evaluationContext, Boolean.class));
|
||||
} catch (Exception e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,51 @@
|
||||
package com.qqchen.deploy.backend.workflow.engine.executor.gateway;
|
||||
|
||||
import com.qqchen.deploy.backend.workflow.engine.context.WorkflowContextOperations;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* 并行网关配置
|
||||
*/
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
public class ParallelGatewayConfig extends GatewayConfig {
|
||||
/**
|
||||
* 并行分支列表
|
||||
*/
|
||||
private List<ParallelBranch> branches;
|
||||
|
||||
/**
|
||||
* 汇聚配置
|
||||
*/
|
||||
private BranchConvergeConfig convergeConfig;
|
||||
|
||||
@Data
|
||||
public static class ParallelBranch {
|
||||
/**
|
||||
* 分支名称
|
||||
*/
|
||||
private String name;
|
||||
|
||||
/**
|
||||
* 目标节点ID
|
||||
*/
|
||||
private String targetNodeId;
|
||||
|
||||
/**
|
||||
* 分支描述
|
||||
*/
|
||||
private String description;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> getNextNodeIds(WorkflowContextOperations context) {
|
||||
// 返回所有分支的targetNodeId
|
||||
return branches.stream()
|
||||
.map(ParallelBranch::getTargetNodeId)
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
}
|
||||
@ -1,10 +1,9 @@
|
||||
package com.qqchen.deploy.backend.workflow.engine.node;
|
||||
package com.qqchen.deploy.backend.workflow.engine.executor.node;
|
||||
|
||||
import com.qqchen.deploy.backend.framework.enums.ResponseCode;
|
||||
import com.qqchen.deploy.backend.system.enums.LogLevelEnum;
|
||||
import com.qqchen.deploy.backend.workflow.engine.context.WorkflowContextOperations;
|
||||
import com.qqchen.deploy.backend.workflow.engine.exception.WorkflowEngineException;
|
||||
import com.qqchen.deploy.backend.workflow.engine.executor.NodeExecutor;
|
||||
import com.qqchen.deploy.backend.workflow.entity.NodeInstance;
|
||||
import com.qqchen.deploy.backend.workflow.enums.NodeStatusEnum;
|
||||
import com.qqchen.deploy.backend.workflow.repository.INodeInstanceRepository;
|
||||
@ -1,8 +1,7 @@
|
||||
package com.qqchen.deploy.backend.workflow.engine.node.executor;
|
||||
package com.qqchen.deploy.backend.workflow.engine.executor.node;
|
||||
|
||||
import com.qqchen.deploy.backend.system.enums.LogLevelEnum;
|
||||
import com.qqchen.deploy.backend.workflow.engine.context.WorkflowContextOperations;
|
||||
import com.qqchen.deploy.backend.workflow.engine.node.AbstractNodeExecutor;
|
||||
import com.qqchen.deploy.backend.workflow.entity.NodeInstance;
|
||||
import com.qqchen.deploy.backend.workflow.entity.WorkflowInstance;
|
||||
import com.qqchen.deploy.backend.workflow.enums.NodeTypeEnum;
|
||||
@ -1,4 +1,4 @@
|
||||
package com.qqchen.deploy.backend.workflow.engine.executor;
|
||||
package com.qqchen.deploy.backend.workflow.engine.executor.node;
|
||||
|
||||
import com.qqchen.deploy.backend.workflow.engine.context.WorkflowContextOperations;
|
||||
import com.qqchen.deploy.backend.workflow.entity.NodeInstance;
|
||||
@ -1,12 +1,11 @@
|
||||
package com.qqchen.deploy.backend.workflow.engine.node.executor;
|
||||
package com.qqchen.deploy.backend.workflow.engine.executor.node;
|
||||
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.qqchen.deploy.backend.system.enums.LogLevelEnum;
|
||||
import com.qqchen.deploy.backend.framework.enums.ResponseCode;
|
||||
import com.qqchen.deploy.backend.workflow.engine.exception.WorkflowEngineException;
|
||||
import com.qqchen.deploy.backend.workflow.engine.context.WorkflowContextOperations;
|
||||
import com.qqchen.deploy.backend.workflow.engine.node.AbstractNodeExecutor;
|
||||
import com.qqchen.deploy.backend.workflow.engine.node.ScriptNodeConfig;
|
||||
import com.qqchen.deploy.backend.workflow.engine.executor.node.config.ScriptNodeConfig;
|
||||
import com.qqchen.deploy.backend.workflow.entity.NodeInstance;
|
||||
import com.qqchen.deploy.backend.workflow.enums.NodeTypeEnum;
|
||||
import com.qqchen.deploy.backend.workflow.service.WorkflowVariableOperations;
|
||||
@ -1,12 +1,11 @@
|
||||
package com.qqchen.deploy.backend.workflow.engine.node.executor;
|
||||
package com.qqchen.deploy.backend.workflow.engine.executor.node;
|
||||
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.qqchen.deploy.backend.system.enums.LogLevelEnum;
|
||||
import com.qqchen.deploy.backend.framework.enums.ResponseCode;
|
||||
import com.qqchen.deploy.backend.workflow.engine.exception.WorkflowEngineException;
|
||||
import com.qqchen.deploy.backend.workflow.engine.context.WorkflowContextOperations;
|
||||
import com.qqchen.deploy.backend.workflow.engine.node.AbstractNodeExecutor;
|
||||
import com.qqchen.deploy.backend.workflow.engine.node.ShellNodeConfig;
|
||||
import com.qqchen.deploy.backend.workflow.engine.executor.node.config.ShellNodeConfig;
|
||||
import com.qqchen.deploy.backend.workflow.entity.NodeInstance;
|
||||
import com.qqchen.deploy.backend.workflow.enums.NodeTypeEnum;
|
||||
import com.qqchen.deploy.backend.workflow.service.WorkflowVariableOperations;
|
||||
@ -1,8 +1,7 @@
|
||||
package com.qqchen.deploy.backend.workflow.engine.node.executor;
|
||||
package com.qqchen.deploy.backend.workflow.engine.executor.node;
|
||||
|
||||
import com.qqchen.deploy.backend.system.enums.LogLevelEnum;
|
||||
import com.qqchen.deploy.backend.workflow.engine.context.WorkflowContextOperations;
|
||||
import com.qqchen.deploy.backend.workflow.engine.node.AbstractNodeExecutor;
|
||||
import com.qqchen.deploy.backend.workflow.entity.NodeInstance;
|
||||
import com.qqchen.deploy.backend.workflow.entity.WorkflowInstance;
|
||||
import com.qqchen.deploy.backend.workflow.enums.NodeTypeEnum;
|
||||
@ -1,10 +1,11 @@
|
||||
package com.qqchen.deploy.backend.workflow.engine.executor;
|
||||
package com.qqchen.deploy.backend.workflow.engine.executor.node;
|
||||
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.qqchen.deploy.backend.system.enums.LogLevelEnum;
|
||||
import com.qqchen.deploy.backend.framework.enums.ResponseCode;
|
||||
import com.qqchen.deploy.backend.workflow.engine.context.WorkflowContextOperations;
|
||||
import com.qqchen.deploy.backend.workflow.engine.exception.WorkflowEngineException;
|
||||
import com.qqchen.deploy.backend.workflow.engine.executor.task.TaskConfig;
|
||||
import com.qqchen.deploy.backend.workflow.entity.NodeInstance;
|
||||
import com.qqchen.deploy.backend.workflow.enums.NodeStatusEnum;
|
||||
import com.qqchen.deploy.backend.workflow.enums.NodeTypeEnum;
|
||||
@ -1,4 +1,4 @@
|
||||
package com.qqchen.deploy.backend.workflow.engine.node;
|
||||
package com.qqchen.deploy.backend.workflow.engine.executor.node.config;
|
||||
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
@ -1,4 +1,4 @@
|
||||
package com.qqchen.deploy.backend.workflow.engine.node;
|
||||
package com.qqchen.deploy.backend.workflow.engine.executor.node.config;
|
||||
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
@ -1,4 +1,4 @@
|
||||
package com.qqchen.deploy.backend.workflow.engine.node;
|
||||
package com.qqchen.deploy.backend.workflow.engine.executor.node.config;
|
||||
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
@ -1,4 +1,4 @@
|
||||
package com.qqchen.deploy.backend.workflow.engine.node;
|
||||
package com.qqchen.deploy.backend.workflow.engine.executor.node.config;
|
||||
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
@ -1,4 +1,4 @@
|
||||
package com.qqchen.deploy.backend.workflow.engine.node;
|
||||
package com.qqchen.deploy.backend.workflow.engine.executor.node.config;
|
||||
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
@ -1,4 +1,4 @@
|
||||
package com.qqchen.deploy.backend.workflow.engine.node;
|
||||
package com.qqchen.deploy.backend.workflow.engine.executor.node.config;
|
||||
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
@ -1,7 +1,8 @@
|
||||
package com.qqchen.deploy.backend.workflow.engine.node;
|
||||
package com.qqchen.deploy.backend.workflow.engine.executor.node.config;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonSubTypes;
|
||||
import com.fasterxml.jackson.annotation.JsonTypeInfo;
|
||||
import com.qqchen.deploy.backend.workflow.enums.NodeTypeEnum;
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
@ -36,7 +37,7 @@ public abstract class NodeConfig {
|
||||
/**
|
||||
* 节点类型
|
||||
*/
|
||||
private NodeType type;
|
||||
private NodeTypeEnum type;
|
||||
|
||||
/**
|
||||
* 超时时间(分钟)
|
||||
@ -1,4 +1,4 @@
|
||||
package com.qqchen.deploy.backend.workflow.engine.node;
|
||||
package com.qqchen.deploy.backend.workflow.engine.executor.node.config;
|
||||
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
@ -1,4 +1,4 @@
|
||||
package com.qqchen.deploy.backend.workflow.engine.node;
|
||||
package com.qqchen.deploy.backend.workflow.engine.executor.node.config;
|
||||
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
@ -1,4 +1,4 @@
|
||||
package com.qqchen.deploy.backend.workflow.engine.node;
|
||||
package com.qqchen.deploy.backend.workflow.engine.executor.node.config;
|
||||
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
@ -1,4 +1,4 @@
|
||||
package com.qqchen.deploy.backend.workflow.engine.node;
|
||||
package com.qqchen.deploy.backend.workflow.engine.executor.node.config;
|
||||
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
@ -1,5 +1,6 @@
|
||||
package com.qqchen.deploy.backend.workflow.engine.executor;
|
||||
package com.qqchen.deploy.backend.workflow.engine.executor.task;
|
||||
|
||||
import com.qqchen.deploy.backend.workflow.enums.TaskTypeEnum;
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.Map;
|
||||
@ -10,7 +11,7 @@ public class TaskConfig {
|
||||
/**
|
||||
* 任务类型
|
||||
*/
|
||||
private TaskType type;
|
||||
private TaskTypeEnum type;
|
||||
|
||||
/**
|
||||
* 任务名称
|
||||
@ -1,27 +0,0 @@
|
||||
package com.qqchen.deploy.backend.workflow.engine.node;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
|
||||
/**
|
||||
* 节点类型枚举
|
||||
*/
|
||||
@Getter
|
||||
@AllArgsConstructor
|
||||
public enum NodeType {
|
||||
|
||||
START("START", "开始节点"),
|
||||
END("END", "结束节点"),
|
||||
APPROVAL("APPROVAL", "审批节点"),
|
||||
SCRIPT("SCRIPT", "脚本节点"),
|
||||
JENKINS("JENKINS", "Jenkins构建节点"),
|
||||
GIT("GIT", "Git操作节点"),
|
||||
CONDITION("CONDITION", "条件节点"),
|
||||
PARALLEL("PARALLEL", "并行节点"),
|
||||
NACOS("NACOS", "Nacos配置节点"),
|
||||
HTTP("HTTP", "HTTP请求节点"),
|
||||
NOTIFY("NOTIFY", "通知节点");
|
||||
|
||||
private final String code;
|
||||
private final String description;
|
||||
}
|
||||
@ -2,7 +2,7 @@ package com.qqchen.deploy.backend.workflow.entity;
|
||||
|
||||
import com.qqchen.deploy.backend.framework.annotation.LogicDelete;
|
||||
import com.qqchen.deploy.backend.framework.domain.Entity;
|
||||
import com.qqchen.deploy.backend.workflow.enums.NodeCategory;
|
||||
import com.qqchen.deploy.backend.workflow.enums.NodeCategoryEnum;
|
||||
import jakarta.persistence.Column;
|
||||
import jakarta.persistence.EnumType;
|
||||
import jakarta.persistence.Enumerated;
|
||||
@ -43,7 +43,7 @@ public class NodeType extends Entity<Long> {
|
||||
*/
|
||||
@Enumerated(EnumType.STRING)
|
||||
@Column(nullable = false)
|
||||
private NodeCategory category;
|
||||
private NodeCategoryEnum category;
|
||||
|
||||
/**
|
||||
* 节点图标
|
||||
|
||||
@ -1,11 +1,11 @@
|
||||
package com.qqchen.deploy.backend.workflow.engine.executor;
|
||||
package com.qqchen.deploy.backend.workflow.enums;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
|
||||
@Getter
|
||||
@AllArgsConstructor
|
||||
public enum GatewayType {
|
||||
public enum GatewayTypeEnum {
|
||||
|
||||
EXCLUSIVE("EXCLUSIVE", "排他网关"),
|
||||
PARALLEL("PARALLEL", "并行网关"),
|
||||
@ -6,7 +6,7 @@ import lombok.Getter;
|
||||
* 节点分类枚举
|
||||
*/
|
||||
@Getter
|
||||
public enum NodeCategory {
|
||||
public enum NodeCategoryEnum {
|
||||
/**
|
||||
* 基础节点(如开始、结束节点)
|
||||
*/
|
||||
@ -32,7 +32,7 @@ public enum NodeCategory {
|
||||
*/
|
||||
private final String name;
|
||||
|
||||
NodeCategory(String name) {
|
||||
NodeCategoryEnum(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
}
|
||||
@ -19,7 +19,12 @@ public enum NodeTypeEnum {
|
||||
SCRIPT(6, "SCRIPT", "脚本节点"),
|
||||
APPROVAL(7, "APPROVAL", "审批节点"),
|
||||
JENKINS(8, "JENKINS", "Jenkins任务节点"),
|
||||
GIT(9, "GIT", "Git操作节点");
|
||||
GIT(9, "GIT", "Git操作节点"),
|
||||
CONDITION(10, "CONDITION", "条件节点"),
|
||||
PARALLEL(11, "PARALLEL", "并行节点"),
|
||||
NACOS(12, "NACOS", "Nacos配置节点"),
|
||||
HTTP(13, "HTTP", "HTTP请求节点"),
|
||||
NOTIFY(14, "NOTIFY", "通知节点");
|
||||
|
||||
private final int value;
|
||||
private final String code;
|
||||
|
||||
@ -1,11 +1,11 @@
|
||||
package com.qqchen.deploy.backend.workflow.engine.executor;
|
||||
package com.qqchen.deploy.backend.workflow.enums;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
|
||||
@Getter
|
||||
@AllArgsConstructor
|
||||
public enum TaskType {
|
||||
public enum TaskTypeEnum {
|
||||
|
||||
HTTP("HTTP", "HTTP请求"),
|
||||
JAVA("JAVA", "Java方法");
|
||||
@ -4,6 +4,7 @@ import com.qqchen.deploy.backend.framework.repository.IBaseRepository;
|
||||
import com.qqchen.deploy.backend.workflow.entity.WorkflowInstance;
|
||||
import com.qqchen.deploy.backend.workflow.entity.WorkflowVariable;
|
||||
import com.qqchen.deploy.backend.workflow.enums.VariableScopeEnum;
|
||||
import org.springframework.data.jpa.repository.Modifying;
|
||||
import org.springframework.data.jpa.repository.Query;
|
||||
import org.springframework.data.repository.query.Param;
|
||||
import org.springframework.stereotype.Repository;
|
||||
@ -79,10 +80,18 @@ public interface IWorkflowVariableRepository extends IBaseRepository<WorkflowVar
|
||||
@Param("scope") VariableScopeEnum scope);
|
||||
|
||||
/**
|
||||
* 根据工作流实例ID删除所有变量(软删除)
|
||||
* 删除工作流实例变量
|
||||
*
|
||||
* @param workflowInstanceId 工作流实例ID
|
||||
*/
|
||||
@Modifying
|
||||
@Query("DELETE FROM WorkflowVariable v WHERE v.workflowInstance.id = :workflowInstanceId")
|
||||
void deleteWorkflowInstanceVariable(@Param("workflowInstanceId") Long workflowInstanceId);
|
||||
|
||||
/**
|
||||
* 删除工作流实例的所有变量(逻辑删除)
|
||||
*/
|
||||
@Modifying
|
||||
@Query("UPDATE WorkflowVariable v SET v.deleted = true, v.updateTime = CURRENT_TIMESTAMP WHERE v.workflowInstance.id = :workflowInstanceId AND v.deleted = false")
|
||||
void deleteByWorkflowInstanceId(@Param("workflowInstanceId") Long workflowInstanceId);
|
||||
}
|
||||
@ -8,7 +8,7 @@ import com.qqchen.deploy.backend.workflow.converter.NodeTypeConverter;
|
||||
import com.qqchen.deploy.backend.workflow.dto.NodeTypeDTO;
|
||||
import com.qqchen.deploy.backend.workflow.engine.definition.TaskExecutorDefinition;
|
||||
import com.qqchen.deploy.backend.workflow.entity.NodeType;
|
||||
import com.qqchen.deploy.backend.workflow.enums.NodeCategory;
|
||||
import com.qqchen.deploy.backend.workflow.enums.NodeCategoryEnum;
|
||||
import com.qqchen.deploy.backend.workflow.repository.INodeTypeRepository;
|
||||
import com.qqchen.deploy.backend.workflow.service.INodeTypeService;
|
||||
import jakarta.annotation.Resource;
|
||||
@ -47,7 +47,7 @@ public class NodeTypeServiceImpl extends BaseServiceImpl<NodeType, NodeTypeDTO,
|
||||
.orElseThrow(() -> new BusinessException(ResponseCode.WORKFLOW_NODE_TYPE_NOT_FOUND));
|
||||
|
||||
// 2. 检查节点类型是否为任务节点
|
||||
if (!NodeCategory.TASK.equals(nodeType.getCategory())) {
|
||||
if (!NodeCategoryEnum.TASK.equals(nodeType.getCategory())) {
|
||||
// 非任务节点没有执行器列表
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
@ -4,7 +4,7 @@ import com.qqchen.deploy.backend.framework.enums.ResponseCode;
|
||||
import com.qqchen.deploy.backend.workflow.engine.context.DefaultWorkflowContext;
|
||||
import com.qqchen.deploy.backend.workflow.engine.context.WorkflowContext;
|
||||
import com.qqchen.deploy.backend.workflow.engine.exception.WorkflowEngineException;
|
||||
import com.qqchen.deploy.backend.workflow.engine.executor.NodeExecutor;
|
||||
import com.qqchen.deploy.backend.workflow.engine.executor.node.NodeExecutor;
|
||||
import com.qqchen.deploy.backend.workflow.entity.NodeInstance;
|
||||
import com.qqchen.deploy.backend.workflow.entity.WorkflowDefinition;
|
||||
import com.qqchen.deploy.backend.workflow.entity.WorkflowInstance;
|
||||
@ -21,9 +21,7 @@ import org.mockito.InjectMocks;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.MockitoAnnotations;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
|
||||
@ -2,6 +2,7 @@ package com.qqchen.deploy.backend.workflow.engine.executor;
|
||||
|
||||
import com.qqchen.deploy.backend.system.enums.LogLevelEnum;
|
||||
import com.qqchen.deploy.backend.workflow.engine.context.WorkflowContext;
|
||||
import com.qqchen.deploy.backend.workflow.engine.executor.node.StartNodeExecutor;
|
||||
import com.qqchen.deploy.backend.workflow.entity.NodeInstance;
|
||||
import com.qqchen.deploy.backend.workflow.enums.NodeStatusEnum;
|
||||
import com.qqchen.deploy.backend.workflow.enums.NodeTypeEnum;
|
||||
|
||||
Loading…
Reference in New Issue
Block a user