Commit e09cc2e9 by huangfusuper

【解决冲突】

parents b1ff7739 6e3322fc
package com.byit.api;
import com.byit.job.dto.plugin.PluginFlow;
import com.byit.job.dto.plugin.PluginFlowDepend;
import com.byit.service.ApiFlowService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource;
/**
* @description: 工作流操作的API接口
* @author: gml
* @create: 2019-12-30 14:20
*/
@Api(tags = "工作流api")
@RestController
@RequestMapping("api/flow")
public class ApiFlowController {
@Resource
private ApiFlowService apiFlowService;
@PostMapping("add")
@ApiOperation("新建工作流,默认开始调度")
public String addFlow(@RequestBody PluginFlow flow){
apiFlowService.addFlow(flow);
return "SUCCESS";
}
@PostMapping("update")
@ApiOperation("更新工作流,默认开始调度")
public String updateFlow(@RequestBody PluginFlow flow){
apiFlowService.updateFlow(flow);
return "SUCCESS";
}
@PostMapping("delete")
@ApiOperation("删除工作流,若当前工作流被依赖则删除失败,只允许删除不被依赖的工作流,当前工作流依赖其他工作流不影响")
public String deleteFlow(String flowName, String workspaceName){
apiFlowService.deleteFlow(flowName);
return "SUCCESS";
}
@PostMapping("addDepend")
@ApiOperation("添加工作流依赖,只是添加一个依赖")
public String addDepend(String flowName, String dependFlowName, String workspaceName){
apiFlowService.addDepend(flowName, dependFlowName, workspaceName);
return "SUCCESS";
}
@PostMapping("resetDepend")
@ApiOperation("重置工作流依赖,将工作流的所有依赖重置为依赖工作流名称集合中的工作流")
public String resetDepend(@RequestBody PluginFlowDepend flowDepend){
apiFlowService.resetDepend(flowDepend);
return "SUCCESS";
}
@PostMapping("deleteDepend")
@ApiOperation("删除工作流依赖,只是删除一个依赖关系")
public String deleteDepend(String flowName, String dependFlowName, String workspaceName){
apiFlowService.deleteDepend(flowName, dependFlowName, workspaceName);
return "SUCCESS";
}
@PostMapping("start")
@ApiOperation("开始工作流的调度,将工作流启用调度")
public String start(String flowName, String workspaceName){
apiFlowService.start(flowName, workspaceName);
return "SUCCESS";
}
@PostMapping("repealSchedule")
@ApiOperation("撤销工作流调度,")
public String repealSchedule(String flowName, String workspaceName){
apiFlowService.repealSchedule(flowName, workspaceName);
return "SUCCESS";
}
@PostMapping("killSchedule")
@ApiOperation("杀死本次调度")
public String killSchedule(String flowName, String workspaceName){
apiFlowService.killSchedule(flowName, workspaceName);
return "SUCCESS";
}
@PostMapping("stopSchedule")
@ApiOperation("暂停本次调度")
public String stopSchedule(String flowName, String workspaceName){
String runId = apiFlowService.stopSchedule(flowName, workspaceName);
return runId;
}
@PostMapping("reStartSchedule")
@ApiOperation("重新开始某次调度")
public String reStartSchedule(String runId){
apiFlowService.reStartSchedule(runId);
return "SUCCESS";
}
}
package com.byit.api;
import com.byit.job.dto.plugin.PluginFlow;
import com.byit.service.ApiWorkspaceService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource;
/**
* @description: 工作空间操作的API接口
* @author: gml
* @create: 2019-12-31 11:19
*/
@Api(tags = "工作空间api")
@RestController
@RequestMapping("api/workspace")
public class ApiWorkspaceController {
@Resource
private ApiWorkspaceService workspaceService;
@PostMapping("add")
@ApiOperation("新建工作空间")
public String add(String workspaceName){
workspaceService.add(workspaceName);
return "SUCCESS";
}
}
package com.byit.service;
import com.byit.job.dto.plugin.PluginFlow;
import com.byit.job.dto.plugin.PluginFlowDepend;
/**
* @description: 工作流的api请求业务处理接口
* @author: gml
* @create: 2019-12-30 14:34
*/
public interface ApiFlowService {
void addFlow(PluginFlow flow);
void updateFlow(PluginFlow flow);
void deleteFlow(String flowName);
void addDepend(String flowName, String dependFlowName, String workspaceName);
void resetDepend(PluginFlowDepend flowDepend);
void deleteDepend(String flowName, String dependFlowName, String workspaceName);
void start(String flowName, String workspaceName);
void repealSchedule(String flowName, String workspaceName);
void killSchedule(String flowName, String workspaceName);
String stopSchedule(String flowName, String workspaceName);
void reStartSchedule(String runId);
}
package com.byit.service;
/**
* @description: 工作空间操作API的业务逻辑处理接口
* @author: gml
* @create: 2019-12-31 11:21
*/
public interface ApiWorkspaceService {
void add(String workspaceName);
}
package com.byit.service.impl;
import com.byit.job.dto.plugin.PluginFlow;
import com.byit.job.dto.plugin.PluginFlowDepend;
import com.byit.mapper.FlowMapper;
import com.byit.mapper.WorkspaceMapper;
import com.byit.service.ApiFlowService;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import javax.annotation.Resource;
/**
* @description: 工作流的Api请求业务处理实现类
* @author: gml
* @create: 2019-12-30 14:37
*/
@Service
@Transactional(rollbackFor = Exception.class)
public class ApiFlowServiceImpl implements ApiFlowService {
@Resource
private FlowMapper flowMapper;
@Resource
private WorkspaceMapper workspaceMapper;
@Override
public void addFlow(PluginFlow flow) {
}
@Override
public void updateFlow(PluginFlow flow) {
}
@Override
public void deleteFlow(String flowName) {
}
@Override
public void addDepend(String flowName, String dependFlowName, String workspaceName) {
}
@Override
public void resetDepend(PluginFlowDepend flowDepend) {
}
@Override
public void deleteDepend(String flowName, String dependFlowName, String workspaceName) {
}
@Override
public void start(String flowName, String workspaceName) {
}
@Override
public void repealSchedule(String flowName, String workspaceName) {
}
@Override
public void killSchedule(String flowName, String workspaceName) {
}
@Override
public String stopSchedule(String flowName, String workspaceName) {
return null;
}
@Override
public void reStartSchedule(String runId) {
}
}
package com.byit.service.impl;
import com.byit.service.ApiWorkspaceService;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
/**
* @description: 工作空间操作API的业务逻辑处理实现类
* @author: gml
* @create: 2019-12-31 11:22
*/
@Service
@Transactional(rollbackFor = Exception.class)
public class ApiWorkspaceServiceImpl implements ApiWorkspaceService {
}
package com.byit.enums;
/**
* @description: 工作流属性的枚举类
* @author: gml
* @create: 2019-12-26 15:17
*/
public enum FlowPropertyEnum {
HAVE_DEPEND("0", "有下游依赖"),
NO_HAVE_DEPEND("1", "没有下游依赖"),
IS_INNER("0", "是内嵌工作流"),
ISNOT_INNER("1", "不是内嵌工作流"),
IS_TOP("0", "是顶级工作流"),
ISNOT_TOP("1", "不是顶级工作流"),
IS_START("0", "启动"),
NO_START("1", "未启动"),
;
private String code;
private String name;
private FlowPropertyEnum(String code, String name){
this.code = code;
this.name = name;
}
public String getCode(){
return this.code;
}
public String getName(){
return this.name;
}
}
package com.byit.enums;
/**
* @description: 节点属性枚举
* @author: gml
* @create: 2019-12-26 15:36
*/
public enum NodePropertyEnum {
IS_VIRTUAL("0", "是虚节点"),
ISNOT_VIRTUAL("1", "不是虚节点"),
ON_FORK("0", "在工作流调度中"),
OFF_FORK("1", "不在工作流调度中"),
;
private String code;
private String name;
private NodePropertyEnum(String code, String name){
this.code = code;
this.name = name;
}
public String getCode(){
return this.code;
}
public String getName(){
return this.name;
}
}
......@@ -2,9 +2,10 @@ package com.byit.model;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.io.Serializable;
import java.util.Date;
import lombok.Data;
/**
*
......
......@@ -2,6 +2,7 @@ package com.byit.service;
import com.byit.model.Flow;
import com.byit.model.vo.FlowVo;
import com.byit.model.vo.NodeVo;
/**
* @description: 工作流业务逻辑接口
......@@ -48,4 +49,20 @@ public interface FlowService {
* @return
*/
Boolean startFlow(FlowVo flowVo);
/**
* 判断是否允许依赖这个工作流
* @param flowVo 当前工作流
* @param dependFlowId 要依赖的工作流
* @return
*/
Boolean dependFlow(FlowVo flowVo, Integer dependFlowId);
/**
* 判断是否可以包含这个工作流
* @param flowVo 当前工作流
* @param nodeVo
* @return
*/
Boolean includeFlow(FlowVo flowVo, NodeVo nodeVo);
}
/*
package com.byit.service.impl;
import com.byit.enums.FlowPropertyEnum;
import com.byit.enums.NodePropertyEnum;
import com.byit.job.utils.CronExpression;
import com.byit.mapper.FlowDependentMapper;
import com.byit.mapper.FlowMapper;
......@@ -65,7 +67,7 @@ public class FlowServiceImpl implements FlowService {
BeanUtils.copyProperties(flowVo, flow);
//只要修改就设置为未启动
flow.setStartUp("0");
flow.setStartUp(FlowPropertyEnum.NO_START.getCode());
//设置在工作流上的节点数目
flow.setFlowNodeCount(nodeVoList.size());
......@@ -98,8 +100,9 @@ public class FlowServiceImpl implements FlowService {
for (Node node : virtualNodeList) {
Flow virtualFlow = new Flow();
virtualFlow.setFlowId(node.getMapFlowId());
virtualFlow.setIsInner("0");
//将内嵌的工作流设置为不是内嵌
virtualFlow.setIsInner(FlowPropertyEnum.ISNOT_INNER.getCode());
flowMapper.updateByIdSelective(virtualFlow);
}
}
......@@ -109,22 +112,10 @@ public class FlowServiceImpl implements FlowService {
//将对应的节点更改为在调度上
log.info("给工作流【{}】添加节点调度调度", flowVo.getFlowName());
for (NodeVo nodeVo : nodeVoList) {
if (StringUtils.isNotEmpty(nodeVo.getIsVirtual()) && "1".equals(nodeVo.getIsVirtual())){
//如果是虚拟节点就根据节点的id查找工作流的id
Flow virtualFlow = flowMapper.getById(nodeVo.getNodeId());
Node virtualNode = new Node();
virtualNode.setMapFlowId(nodeVo.getNodeId());
virtualNode.setIsVirtual("0");
virtualNode.setAuthor(virtualFlow.getAuthor());
virtualNode.setAddTime(new Date());
virtualNode.setOnFork("0");
virtualNode.setVersionName(virtualFlow.getVersionName());
Integer virtualNodeId = nodeMapper.insertSelective(virtualNode);
//将虚拟节点真实节点改为nodeid
nodeVo.setNodeId(virtualNode.getNodeId());
//将映射的工作流改为是内嵌工作流
virtualFlow.setIsInner("1");
flowMapper.updateByIdSelective(virtualFlow);
//判断是否是虚节点
if (StringUtils.isNotEmpty(nodeVo.getIsVirtual()) && NodePropertyEnum.IS_VIRTUAL.getCode().equals(nodeVo.getIsVirtual())){
includeFlow(flowVo, nodeVo);
}else {
nodeMapper.updateOnforkUp(nodeVo.getNodeId());
}
......@@ -151,7 +142,7 @@ public class FlowServiceImpl implements FlowService {
log.info("将【{}】工作流上游工作流设置为没有下游工作流", flowVo.getFlowName());
for (FlowDependentKey flowDependentKey: flowDependentKeyList) {
Flow flow = flowMapper.getById(flowDependentKey.getDependFlowId());
flow.setIsHaveDepend("0");
flow.setIsHaveDepend(FlowPropertyEnum.NO_HAVE_DEPEND.getCode());
flowMapper.updateByIdSelective(flow);
}
log.info("删除【{}】工作流的依赖关系", flowVo.getFlowName());
......@@ -163,12 +154,13 @@ public class FlowServiceImpl implements FlowService {
List<Integer> flowDependList = flowVo.getFlowDepend();
for (Integer flowDependId : flowDependList){
Flow flow = flowMapper.getById(flowDependId);
flow.setIsHaveDepend("1");
flow.setIsHaveDepend(FlowPropertyEnum.HAVE_DEPEND.getCode());
flowMapper.updateByIdSelective(flow);
flowDependentMapper.insert(flowVo.getFlowId(), flowDependId);
}
flowVo.setIsTop(FlowPropertyEnum.ISNOT_TOP.getCode());
}else {
flowVo.setIsTop("1");
flowVo.setIsTop(FlowPropertyEnum.IS_TOP.getCode());
}
}
......@@ -187,7 +179,7 @@ public class FlowServiceImpl implements FlowService {
//新建的设置版本为V1
flow.setVersionName("V.1");
//新建的工作流设置为不启动
flow.setStartUp("0");
flow.setStartUp(FlowPropertyEnum.NO_START.getCode());
if(flow.getRemainingCount() != null && flow.getRemainingCount() > 0){
flow.setRepeatCount(flow.getRemainingCount());
}
......@@ -253,5 +245,46 @@ public class FlowServiceImpl implements FlowService {
}
return null;
}
/**
* 判断是否允许依赖这个工作流
* @param flowVo 当前工作流
* @param dependFlowId 要依赖的工作流
* @return
*/
@Override
public Boolean dependFlow(FlowVo flowVo, Integer dependFlowId) {
return null;
}
/**
* 判断是否可以包含这个工作流
* @param flowVo 当前工作流
* @param nodeVo
* @return
*/
@Override
public Boolean includeFlow(FlowVo flowVo, NodeVo nodeVo) {
//
//如果是虚拟节点就根据节点的id查找工作流的id
Flow virtualFlow = flowMapper.getById(nodeVo.getNodeId());
//判断是否允许包含这个工作流
Node virtualNode = new Node();
virtualNode.setMapFlowId(nodeVo.getNodeId());
virtualNode.setIsVirtual(NodePropertyEnum.IS_VIRTUAL.getCode());
virtualNode.setAuthor(virtualFlow.getAuthor());
virtualNode.setAddTime(new Date());
virtualNode.setOnFork(NodePropertyEnum.ON_FORK.getCode());
virtualNode.setVersionName(virtualFlow.getVersionName());
Integer virtualNodeId = nodeMapper.insertSelective(virtualNode);
//将虚拟节点真实节点改为nodeid
nodeVo.setNodeId(virtualNode.getNodeId());
//将映射的工作流改为是内嵌工作流
virtualFlow.setIsInner(FlowPropertyEnum.IS_INNER.getCode());
flowMapper.updateByIdSelective(virtualFlow);
return null;
}
}
*/
package com.byit.util;
import com.byit.job.dto.plugin.PluginFlow;
import com.byit.utils.ValidationUtil;
import java.util.*;
/**
* @description: Api请求的工作流进行环路校验
* @author: gml
* @create: 2019-12-30 16:34
*/
public class ApiFlowDagCheck {
//节点个数
private int flowNum;
//连线个数
private int lineNum;
//节点入度
private Map<Integer, Integer> importNum = new HashMap<>();
//入口集合
private Set<String> fromSet = new HashSet<>();
//出口集合
private Set<String> toSet = new HashSet<>();
//节点集合
private Set<String> flowSet = new HashSet<>();
//用队列保存拓扑序列
private Queue<Integer> queue = new LinkedList<>();
//存储连线信息
private Map<String, Integer> graph = new HashMap<>();
//依赖的节点
private Set<String> dependSet = new HashSet<>();
public void init(List<PluginFlow> flowList){
for (PluginFlow pluginFlow : flowList){
if (!flowSet.add(pluginFlow.getFlowName())){
ValidationUtil.dataNotNull(null, "工作流名称不允许重复!");
}
}
}
}
......@@ -27,9 +27,9 @@
</delete>
<insert id="insert" parameterType="com.byit.model.Workspace">
<!-- generated @mbg.generated date: 2019-12-31 -->
insert into workspace (workspace_id, workspace_name, author,
insert into workspace (workspace_id, workspace_name, author,
add_time, remove_mark)
values (#{workspaceId,jdbcType=INTEGER}, #{workspaceName,jdbcType=VARCHAR}, #{author,jdbcType=VARCHAR},
values (#{workspaceId,jdbcType=INTEGER}, #{workspaceName,jdbcType=VARCHAR}, #{author,jdbcType=VARCHAR},
#{addTime,jdbcType=TIMESTAMP}, #{removeMark,jdbcType=CHAR})
</insert>
<insert id="insertSelective" parameterType="com.byit.model.Workspace">
......
package com.byit.job.dto.plugin;
import lombok.Data;
import java.io.Serializable;
/**
* @description: 基础Node
* @author: gml
* @create: 2019-12-30 10:45
*/
@Data
public class PluginBaseNode implements Serializable {
/**
* 名称
*/
private String nodeName;
/**
* 任务描述
*/
private String nodeDesc;
/**
* 类型 节点:node, 内嵌工作流:innerFlow
*/
private String type;
/**
* 创建人
*/
private String author;
private static final long serialVersionUID = 1L;
}
package com.byit.job.dto.plugin;
import lombok.Data;
import java.io.Serializable;
import java.util.List;
/**
* @description: 插件端工作流
* @author: gml
* @create: 2019-12-30 10:44
*/
@Data
public class PluginFlow implements Serializable {
/**
* 当前工作流的介绍
*/
private String flowDesc;
/**
* 当前版本工作流名字
*/
private String flowName;
/**
* 创建人
*/
private String author;
/**
* 责任人
*/
private String principal;
/**
* 是否是重新发布 true 是,false 否
*/
private Boolean rePublish;
/**
* 下属任务节点集合
*/
private List<PluginBaseNode> nodeList;
/**
* 依赖的工作流名称集合
*/
private List<String> dependFlowNameList;
/**
* 工作流的配置项
*/
private PluginFlowConfig config;
private static final long serialVersionUID = 1L;
}
package com.byit.job.dto.plugin;
import lombok.Data;
/**
* @description: 插件端工作流的配置
* @author: gml
* @create: 2019-12-30 11:16
*/
@Data
public class PluginFlowConfig {
/**
* 当前工作流版本的告警的时机(0 不告警, 1 完成时告警, 2 失败时告警, 3 成功时告警)
*/
private String alarmlAction;
/**
* 当前工作流版本的报警邮箱,多个邮箱以","分割
*/
private String alarmEmail;
/**
* 执行类型 1 周期执行 2 手动执行
*/
private String execType;
/**
* 任务流的cron表达式
*/
private String flowCron;
/**
* 设置任务的优先级,1最低(默认) 2最高
*/
private String priority;
/**
* 工作流重复次数
*/
private Integer repeatCount;
/**
* 节点是否跟随任务流,1跟随(默认) 2不跟随
*/
private String scheduleFollow;
}
package com.byit.job.dto.plugin;
import lombok.Data;
import java.util.List;
/**
* @description: 工作流的依赖关系
* @author: gml
* @create: 2019-12-31 11:04
*/
@Data
public class PluginFlowDepend {
/**
* 工作流名称
*/
private String flowName;
/**
* 工作空间的名称
*/
private String workspaceName;
/**
* 工作流依赖的工作流名称
*/
private List<String> dependFlowNameList;
}
package com.byit.job.dto.plugin;
import lombok.Data;
import java.util.List;
/**
* @description: 内嵌工作流
* @author: gml
* @create: 2019-12-30 10:46
*/
@Data
public class PluginInnerFlow extends PluginBaseNode {
/**
* 责任人
*/
private String principal;
/**
* 工作流的配置项
*/
private PluginFlowConfig config;
/**
* 是否是重新发布 true 是,false 否
*/
private Boolean rePublish;
/**
* 依赖的任务节点名称集合,只能是节点的名称
*/
private List<String> dependNodeNameList;
/**
* 下属任务节点集合
*/
private List<PluginNode> nodeList;
}
package com.byit.job.dto.plugin;
import lombok.Data;
import java.util.List;
/**
* @description: 插件端的任务节点
* @author: gml
* @create: 2019-12-30 10:45
*/
@Data
public class PluginNode extends PluginBaseNode {
/**
* 当前任务的类型 JAVA PYTHON SHELL SQL SCRIPT
*/
private String jobType;
/**
* 本地节点(插件方) 的节点的名字
*/
private String handlerName;
/**
* 源码
*/
private String runSource;
/**
* 节点的参数
*/
private String runParam;
/**
* 源码备注
*/
private String runSourceDesc;
/**
* 运行命令
*/
private String runCommand;
/**
* 脚本的文件服务器路径集
*/
private String scriptUrls;
/**
* 源码负责人
*/
private String sourcePrincipal;
/**
* 节点的配置
*/
private PluginNodeConfig config;
/**
* 依赖节点的名称集合
*/
private List<String> dependNodeNameList;
}
package com.byit.job.dto.plugin;
import lombok.Data;
/**
* @description: 插件端任务节点配置
* @author: gml
* @create: 2019-12-30 11:41
*/
@Data
public class PluginNodeConfig {
/**
* 阻塞策略
*/
private String blockStrategy;
/**
* 插件端网关令牌
*/
private String pluginToken;
/**
* 插件端请求调度中心的令牌
*/
private String gatewayToken;
/**
* 当前节点的失败重试次数
*/
private Integer failedRetryCount;
/**
* 失败重试的间隔(毫秒)
*/
private Long failedRetryInterval;
/**
* 这个在设置节点执行时间跟随任务流的时候,他是没用的,但是设置不跟随的时候,节点的执行按照他自己的时间执行
*/
private String nodeCron;
/**
* 节点的超时时间 -1不超时
*/
private Long nodeTimeout;
/**
* 插件端的url集合
*/
private String pluginUrls;
/**
* 设置任务的优先级,1最低 2最高
*/
private String priority;
/**
* 路由策略
*/
private String routingStrategy;
/**
* 节点可执行次数
*/
private Integer repeatCount;
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment