You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@dolphinscheduler.apache.org by ji...@apache.org on 2022/10/10 08:29:26 UTC

[dolphinscheduler] branch 2.0.7-prepare updated: fix: check cycle when save process task relation in interface ProcessTaskRelationController#createProcessTaskRelation (#12294)

This is an automated email from the ASF dual-hosted git repository.

jinyleechina pushed a commit to branch 2.0.7-prepare
in repository https://gitbox.apache.org/repos/asf/dolphinscheduler.git


The following commit(s) were added to refs/heads/2.0.7-prepare by this push:
     new 284c5e21c7 fix: check cycle when save process task relation in interface ProcessTaskRelationController#createProcessTaskRelation (#12294)
284c5e21c7 is described below

commit 284c5e21c722ee7a43f7c3f58a1b8e5d7ccfdb56
Author: EdwardYang <ya...@126.com>
AuthorDate: Mon Oct 10 16:29:19 2022 +0800

    fix: check cycle when save process task relation in interface ProcessTaskRelationController#createProcessTaskRelation (#12294)
    
    Co-authored-by: 熠然 <ya...@cai-inc.com>
---
 .../service/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<TaskNode> taskNodeResponseList) {
-        DAG<String, TaskNode, String> 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<String> 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<TaskNode> 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<TaskNode> taskNodeResponseList) {
+        DAG<String, TaskNode, String> 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<String> 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) {