From 21291b34cb0717eb8d3a50ba9c39f0582ddddf18 Mon Sep 17 00:00:00 2001 From: Echo009 Date: Tue, 2 Mar 2021 18:56:49 +0800 Subject: [PATCH] feat: copy workflow API --- .../powerjob/common/OpenAPIConstant.java | 1 + .../service/workflow/WorkflowService.java | 68 +++++++++++++++++-- .../web/controller/OpenAPIController.java | 6 ++ .../web/controller/WorkflowController.java | 11 ++- 4 files changed, 79 insertions(+), 7 deletions(-) diff --git a/powerjob-common/src/main/java/com/github/kfcfans/powerjob/common/OpenAPIConstant.java b/powerjob-common/src/main/java/com/github/kfcfans/powerjob/common/OpenAPIConstant.java index 4ba58842..7a491eec 100644 --- a/powerjob-common/src/main/java/com/github/kfcfans/powerjob/common/OpenAPIConstant.java +++ b/powerjob-common/src/main/java/com/github/kfcfans/powerjob/common/OpenAPIConstant.java @@ -39,6 +39,7 @@ public class OpenAPIConstant { /* ************* Workflow 区 ************* */ public static final String SAVE_WORKFLOW = "/saveWorkflow"; + public static final String COPY_WORKFLOW = "/copyWorkflow"; public static final String FETCH_WORKFLOW = "/fetchWorkflow"; public static final String DISABLE_WORKFLOW = "/disableWorkflow"; public static final String ENABLE_WORKFLOW = "/enableWorkflow"; diff --git a/powerjob-server/src/main/java/com/github/kfcfans/powerjob/server/service/workflow/WorkflowService.java b/powerjob-server/src/main/java/com/github/kfcfans/powerjob/server/service/workflow/WorkflowService.java index 280c0341..107fd156 100644 --- a/powerjob-server/src/main/java/com/github/kfcfans/powerjob/server/service/workflow/WorkflowService.java +++ b/powerjob-server/src/main/java/com/github/kfcfans/powerjob/server/service/workflow/WorkflowService.java @@ -32,10 +32,7 @@ import org.springframework.util.StringUtils; import javax.annotation.Resource; import javax.transaction.Transactional; import java.text.ParseException; -import java.util.ArrayList; -import java.util.Date; -import java.util.HashMap; -import java.util.List; +import java.util.*; /** * Workflow 服务 @@ -102,6 +99,69 @@ public class WorkflowService { return newEntity.getId(); } + /** + * 深度复制工作流 + * + * @param wfId 工作流 ID + * @param appId APP ID + * @return 生成的工作流 ID + */ + @Transactional(rollbackOn = Exception.class) + public long copyWorkflow(Long wfId, Long appId) { + + WorkflowInfoDO originWorkflow = permissionCheck(wfId, appId); + if (originWorkflow.getStatus() == SwitchableStatus.DELETED.getV()) { + throw new IllegalStateException("can't copy the workflow which has been deleted!"); + } + // 拷贝基础信息 + WorkflowInfoDO copyWorkflow = new WorkflowInfoDO(); + BeanUtils.copyProperties(originWorkflow, copyWorkflow); + copyWorkflow.setId(null); + copyWorkflow.setGmtCreate(new Date()); + copyWorkflow.setGmtModified(new Date()); + copyWorkflow.setWfName(copyWorkflow.getWfName() + "_COPY"); + // 先 save 获取 id + copyWorkflow = workflowInfoRepository.saveAndFlush(copyWorkflow); + + if (StringUtils.isEmpty(copyWorkflow.getPeDAG())) { + return copyWorkflow.getId(); + } + + PEWorkflowDAG dag = JSON.parseObject(copyWorkflow.getPeDAG(), PEWorkflowDAG.class); + + // 拷贝节点信息,并且更新 DAG 中的节点信息 + if (!CollectionUtils.isEmpty(dag.getNodes())) { + // originNodeId => copyNodeId + HashMap nodeIdMap = new HashMap<>(dag.getNodes().size(), 1); + // 校正 节点信息 + for (PEWorkflowDAG.Node node : dag.getNodes()) { + + WorkflowNodeInfoDO originNode = workflowNodeInfoRepository.findById(node.getNodeId()).orElseThrow(() -> new IllegalArgumentException("can't find workflow Node by id: " + node.getNodeId())); + + WorkflowNodeInfoDO copyNode = new WorkflowNodeInfoDO(); + BeanUtils.copyProperties(originNode, copyNode); + copyNode.setId(null); + copyNode.setWorkflowId(copyWorkflow.getId()); + copyNode.setGmtCreate(new Date()); + copyNode.setGmtModified(new Date()); + + copyNode = workflowNodeInfoRepository.saveAndFlush(copyNode); + nodeIdMap.put(originNode.getId(), copyNode.getId()); + + node.setNodeId(copyNode.getId()); + } + // 校正 边信息 + for (PEWorkflowDAG.Edge edge : dag.getEdges()) { + edge.setFrom(nodeIdMap.get(edge.getFrom())); + edge.setTo(nodeIdMap.get(edge.getTo())); + } + } + copyWorkflow.setPeDAG(JSON.toJSONString(dag)); + workflowInfoRepository.saveAndFlush(copyWorkflow); + return copyWorkflow.getId(); + } + + /** * 获取工作流元信息,这里获取到的 DAG 包含节点的完整信息(是否启用、是否允许失败跳过) * diff --git a/powerjob-server/src/main/java/com/github/kfcfans/powerjob/server/web/controller/OpenAPIController.java b/powerjob-server/src/main/java/com/github/kfcfans/powerjob/server/web/controller/OpenAPIController.java index d810e62b..b2afbc35 100644 --- a/powerjob-server/src/main/java/com/github/kfcfans/powerjob/server/web/controller/OpenAPIController.java +++ b/powerjob-server/src/main/java/com/github/kfcfans/powerjob/server/web/controller/OpenAPIController.java @@ -151,6 +151,12 @@ public class OpenAPIController { return ResultDTO.success(workflowService.saveWorkflow(request)); } + @PostMapping(OpenAPIConstant.COPY_WORKFLOW) + public ResultDTO copy(Long workflowId, Long appId) { + return ResultDTO.success(workflowService.copyWorkflow(workflowId,appId)); + } + + @PostMapping(OpenAPIConstant.FETCH_WORKFLOW) public ResultDTO fetchWorkflow(Long workflowId, Long appId) { return ResultDTO.success(workflowService.fetchWorkflow(workflowId, appId)); diff --git a/powerjob-server/src/main/java/com/github/kfcfans/powerjob/server/web/controller/WorkflowController.java b/powerjob-server/src/main/java/com/github/kfcfans/powerjob/server/web/controller/WorkflowController.java index 52a9ef47..0a11e5d7 100644 --- a/powerjob-server/src/main/java/com/github/kfcfans/powerjob/server/web/controller/WorkflowController.java +++ b/powerjob-server/src/main/java/com/github/kfcfans/powerjob/server/web/controller/WorkflowController.java @@ -1,5 +1,8 @@ package com.github.kfcfans.powerjob.server.web.controller; +import com.github.kfcfans.powerjob.common.request.http.AddWorkflowNodeRequest; +import com.github.kfcfans.powerjob.common.request.http.ModifyWorkflowNodeRequest; +import com.github.kfcfans.powerjob.common.request.http.SaveWorkflowDAGRequest; import com.github.kfcfans.powerjob.common.request.http.SaveWorkflowRequest; import com.github.kfcfans.powerjob.common.response.ResultDTO; import com.github.kfcfans.powerjob.server.common.constans.SwitchableStatus; @@ -8,10 +11,7 @@ import com.github.kfcfans.powerjob.server.persistence.core.model.WorkflowInfoDO; import com.github.kfcfans.powerjob.server.persistence.core.model.WorkflowNodeInfoDO; import com.github.kfcfans.powerjob.server.persistence.core.repository.WorkflowInfoRepository; import com.github.kfcfans.powerjob.server.service.workflow.WorkflowService; -import com.github.kfcfans.powerjob.common.request.http.AddWorkflowNodeRequest; -import com.github.kfcfans.powerjob.common.request.http.ModifyWorkflowNodeRequest; import com.github.kfcfans.powerjob.server.web.request.QueryWorkflowInfoRequest; -import com.github.kfcfans.powerjob.common.request.http.SaveWorkflowDAGRequest; import com.github.kfcfans.powerjob.server.web.response.WorkflowInfoVO; import org.springframework.data.domain.Page; import org.springframework.data.domain.PageRequest; @@ -45,6 +45,11 @@ public class WorkflowController { return ResultDTO.success(workflowService.saveWorkflow(req)); } + @PostMapping("/copy") + public ResultDTO copy(Long workflowId, Long appId) { + return ResultDTO.success(workflowService.copyWorkflow(workflowId,appId)); + } + @GetMapping("/disable") public ResultDTO disableWorkflow(Long workflowId, Long appId) { workflowService.disableWorkflow(workflowId, appId);