From 284c5e21c722ee7a43f7c3f58a1b8e5d7ccfdb56 Mon Sep 17 00:00:00 2001 From: EdwardYang Date: Mon, 10 Oct 2022 16:29:19 +0800 Subject: [PATCH] fix: check cycle when save process task relation in interface ProcessTaskRelationController#createProcessTaskRelation (#12294) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: 熠然 --- .../impl/ProcessDefinitionServiceImpl.java | 30 ++----------------- .../impl/ProcessTaskRelationServiceImpl.java | 8 +++++ .../service/process/ProcessService.java | 26 ++++++++++++++++ 3 files changed, 36 insertions(+), 28 deletions(-) diff --git a/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/service/impl/ProcessDefinitionServiceImpl.java b/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/service/impl/ProcessDefinitionServiceImpl.java index cc7a437eff..23fee1bb0f 100644 --- a/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/service/impl/ProcessDefinitionServiceImpl.java +++ b/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/service/impl/ProcessDefinitionServiceImpl.java @@ -314,7 +314,7 @@ public class ProcessDefinitionServiceImpl extends BaseServiceImpl implements Pro return result; } } - if (graphHasCycle(taskNodeList)) { + if (processService.graphHasCycle(taskNodeList)) { logger.error("process DAG has cycle"); putMsg(result, Status.PROCESS_NODE_HAS_CYCLE); return result; @@ -1096,7 +1096,7 @@ public class ProcessDefinitionServiceImpl extends BaseServiceImpl implements Pro } // check has cycle - if (graphHasCycle(taskNodes)) { + if (processService.graphHasCycle(taskNodes)) { logger.error("process DAG has cycle"); putMsg(result, Status.PROCESS_NODE_HAS_CYCLE); return result; @@ -1348,32 +1348,6 @@ public class ProcessDefinitionServiceImpl extends BaseServiceImpl implements Pro return result; } - /** - * whether the graph has a ring - * - * @param taskNodeResponseList task node response list - * @return if graph has cycle flag - */ - private boolean graphHasCycle(List taskNodeResponseList) { - DAG graph = new DAG<>(); - // Fill the vertices - for (TaskNode taskNodeResponse : taskNodeResponseList) { - graph.addNode(Long.toString(taskNodeResponse.getCode()), taskNodeResponse); - } - // Fill edge relations - for (TaskNode taskNodeResponse : taskNodeResponseList) { - List preTasks = JSONUtils.toList(taskNodeResponse.getPreTasks(), String.class); - if (CollectionUtils.isNotEmpty(preTasks)) { - for (String preTask : preTasks) { - if (!graph.addEdge(preTask, Long.toString(taskNodeResponse.getCode()))) { - return true; - } - } - } - } - return graph.hasCycle(); - } - /** * batch copy process definition * diff --git a/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/service/impl/ProcessTaskRelationServiceImpl.java b/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/service/impl/ProcessTaskRelationServiceImpl.java index ed7b4d7e1f..b65a03ff1f 100644 --- a/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/service/impl/ProcessTaskRelationServiceImpl.java +++ b/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/service/impl/ProcessTaskRelationServiceImpl.java @@ -24,6 +24,7 @@ import org.apache.dolphinscheduler.api.service.ProjectService; import org.apache.dolphinscheduler.common.Constants; import org.apache.dolphinscheduler.common.enums.ConditionType; import org.apache.dolphinscheduler.common.enums.TaskType; +import org.apache.dolphinscheduler.common.model.TaskNode; import org.apache.dolphinscheduler.dao.entity.ProcessDefinition; import org.apache.dolphinscheduler.dao.entity.ProcessTaskRelation; import org.apache.dolphinscheduler.dao.entity.ProcessTaskRelationLog; @@ -147,6 +148,13 @@ public class ProcessTaskRelationServiceImpl extends BaseServiceImpl implements P processTaskRelation.setPreTaskVersion(0); } processTaskRelations.add(processTaskRelation); + + List taskNodeList = processService.transformTask(processTaskRelations, null); + if (processService.graphHasCycle(taskNodeList)) { + putMsg(result, Status.PROCESS_NODE_HAS_CYCLE); + return result; + } + updateRelation(loginUser, result, processDefinition, processTaskRelations); return result; } diff --git a/dolphinscheduler-service/src/main/java/org/apache/dolphinscheduler/service/process/ProcessService.java b/dolphinscheduler-service/src/main/java/org/apache/dolphinscheduler/service/process/ProcessService.java index ae71812b57..b79e31bee1 100644 --- a/dolphinscheduler-service/src/main/java/org/apache/dolphinscheduler/service/process/ProcessService.java +++ b/dolphinscheduler-service/src/main/java/org/apache/dolphinscheduler/service/process/ProcessService.java @@ -2587,6 +2587,32 @@ public class ProcessService { return processTaskMap; } + /** + * whether the graph has a ring + * + * @param taskNodeResponseList task node response list + * @return if graph has cycle flag + */ + public boolean graphHasCycle(List taskNodeResponseList) { + DAG graph = new DAG<>(); + // Fill the vertices + for (TaskNode taskNodeResponse : taskNodeResponseList) { + graph.addNode(Long.toString(taskNodeResponse.getCode()), taskNodeResponse); + } + // Fill edge relations + for (TaskNode taskNodeResponse : taskNodeResponseList) { + List preTasks = JSONUtils.toList(taskNodeResponse.getPreTasks(), String.class); + if (org.apache.commons.collections4.CollectionUtils.isNotEmpty(preTasks)) { + for (String preTask : preTasks) { + if (!graph.addEdge(preTask, Long.toString(taskNodeResponse.getCode()))) { + return true; + } + } + } + } + return graph.hasCycle(); + } + private void deleteCommandWithCheck(int commandId) { int delete = this.commandMapper.deleteById(commandId); if (delete != 1) {