fix: check cycle when save process task relation in interface ProcessTaskRelationController#createProcessTaskRelation (#12294)
Co-authored-by: 熠然 <yangjianhua@cai-inc.com>
This commit is contained in:
parent
d0366082e6
commit
284c5e21c7
|
|
@ -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
|
||||
*
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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) {
|
||||
|
|
|
|||
Loading…
Reference in New Issue