diff --git a/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/service/impl/ProcessInstanceServiceImpl.java b/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/service/impl/ProcessInstanceServiceImpl.java index 62f8b4fe7d..5271d1488e 100644 --- a/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/service/impl/ProcessInstanceServiceImpl.java +++ b/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/service/impl/ProcessInstanceServiceImpl.java @@ -65,6 +65,7 @@ import org.apache.dolphinscheduler.dao.mapper.TaskDefinitionLogMapper; import org.apache.dolphinscheduler.dao.mapper.TaskDefinitionMapper; import org.apache.dolphinscheduler.dao.mapper.TaskInstanceMapper; import org.apache.dolphinscheduler.dao.mapper.TenantMapper; +import org.apache.dolphinscheduler.dao.utils.WorkflowUtils; import org.apache.dolphinscheduler.plugin.task.api.enums.DependResult; import org.apache.dolphinscheduler.plugin.task.api.enums.ExecutionStatus; import org.apache.dolphinscheduler.plugin.task.api.model.Property; @@ -291,7 +292,7 @@ public class ProcessInstanceServiceImpl extends BaseServiceImpl implements Proce } for (ProcessInstance processInstance : processInstances) { - processInstance.setDuration(DateUtils.format2Duration(processInstance.getStartTime(), processInstance.getEndTime())); + processInstance.setDuration(WorkflowUtils.getWorkflowInstanceDuration(processInstance)); User executor = idToUserMap.get(processInstance.getExecutorId()); if (null != executor) { processInstance.setExecutorName(executor.getUserName()); diff --git a/dolphinscheduler-api/src/test/java/org/apache/dolphinscheduler/api/service/ProcessInstanceServiceTest.java b/dolphinscheduler-api/src/test/java/org/apache/dolphinscheduler/api/service/ProcessInstanceServiceTest.java index eb7977d860..d7bd5c4637 100644 --- a/dolphinscheduler-api/src/test/java/org/apache/dolphinscheduler/api/service/ProcessInstanceServiceTest.java +++ b/dolphinscheduler-api/src/test/java/org/apache/dolphinscheduler/api/service/ProcessInstanceServiceTest.java @@ -297,6 +297,11 @@ public class ProcessInstanceServiceTest { WorkerGroup workerGroup = getWorkGroup(); Map workerExistRes = processInstanceService.queryProcessInstanceById(loginUser, projectCode, 1); Assert.assertEquals(Status.SUCCESS, workerExistRes.get(Constants.STATUS)); + + when(processService.findProcessDefinition(processInstance.getProcessDefinitionCode(), + processInstance.getProcessDefinitionVersion())).thenReturn(null);; + workerExistRes = processInstanceService.queryProcessInstanceById(loginUser, projectCode, 1); + Assert.assertEquals(Status.PROCESS_DEFINE_NOT_EXIST, workerExistRes.get(Constants.STATUS)); } @Test @@ -343,6 +348,11 @@ public class ProcessInstanceServiceTest { Map resultMap = processInstanceService.parseLogForDependentResult(logString); Assert.assertEquals(1, resultMap.size()); + + resultMap.clear(); + resultMap = processInstanceService.parseLogForDependentResult(""); + Assert.assertEquals(0, resultMap.size()); + } @Test @@ -379,6 +389,7 @@ public class ProcessInstanceServiceTest { Map notSubprocessRes = processInstanceService.querySubProcessInstanceByTaskId(loginUser, projectCode, 1); Assert.assertEquals(Status.TASK_INSTANCE_NOT_SUB_WORKFLOW_INSTANCE, notSubprocessRes.get(Constants.STATUS)); + //sub process not exist TaskInstance subTask = getTaskInstance(); subTask.setTaskType("SUB_PROCESS"); @@ -533,6 +544,11 @@ public class ProcessInstanceServiceTest { when(processInstanceMapper.queryDetailById(1)).thenReturn(processInstance); Map successRes = processInstanceService.viewVariables(1L,1); Assert.assertEquals(Status.SUCCESS, successRes.get(Constants.STATUS)); + + when(processInstanceMapper.queryDetailById(1)).thenReturn(null); + Map processNotExist = processInstanceService.viewVariables(1L, 1); + Assert.assertEquals(Status.PROCESS_INSTANCE_NOT_EXIST, processNotExist.get(Constants.STATUS)); + } @Test @@ -558,6 +574,10 @@ public class ProcessInstanceServiceTest { Map successRes = processInstanceService.viewGantt(0L, 1); Assert.assertEquals(Status.SUCCESS, successRes.get(Constants.STATUS)); + + when(processInstanceMapper.queryDetailById(1)).thenReturn(null); + Map processNotExist = processInstanceService.viewVariables(1L, 1); + Assert.assertEquals(Status.PROCESS_INSTANCE_NOT_EXIST, processNotExist.get(Constants.STATUS)); } /** diff --git a/dolphinscheduler-common/src/main/java/org/apache/dolphinscheduler/common/utils/DateUtils.java b/dolphinscheduler-common/src/main/java/org/apache/dolphinscheduler/common/utils/DateUtils.java index 392140e555..9fe469ff68 100644 --- a/dolphinscheduler-common/src/main/java/org/apache/dolphinscheduler/common/utils/DateUtils.java +++ b/dolphinscheduler-common/src/main/java/org/apache/dolphinscheduler/common/utils/DateUtils.java @@ -333,11 +333,19 @@ public final class DateUtils { * @param d2 d2 * @return format time */ - public static String format2Duration(Date d1, Date d2) { - if (d1 == null || d2 == null) { + public static String format2Duration(Date start, Date end) { + if (start == null) { return null; } - return format2Duration(differMs(d1, d2)); + + if (end == null) { + end = new Date(); + } + if (start.after(end)) { + logger.warn("start Time {} is later than end Time {}", start, end); + return null; + } + return format2Duration(differMs(start, end)); } /** diff --git a/dolphinscheduler-common/src/test/java/org/apache/dolphinscheduler/common/utils/DateUtilsTest.java b/dolphinscheduler-common/src/test/java/org/apache/dolphinscheduler/common/utils/DateUtilsTest.java index 2042fa2d80..4bc94238d4 100644 --- a/dolphinscheduler-common/src/test/java/org/apache/dolphinscheduler/common/utils/DateUtilsTest.java +++ b/dolphinscheduler-common/src/test/java/org/apache/dolphinscheduler/common/utils/DateUtilsTest.java @@ -176,6 +176,9 @@ public class DateUtilsTest { String duration = DateUtils.format2Duration(d2, d1); Assert.assertEquals("1d 1h 10m 10s", duration); + duration = DateUtils.format2Duration(d2, d1); + Assert.assertNull(duration); + // hours minutes seconds d1 = DateUtils.stringToDate("2020-01-20 11:00:00"); d2 = DateUtils.stringToDate("2020-01-20 12:10:10"); diff --git a/dolphinscheduler-dao/src/main/java/org/apache/dolphinscheduler/dao/utils/WorkflowUtils.java b/dolphinscheduler-dao/src/main/java/org/apache/dolphinscheduler/dao/utils/WorkflowUtils.java new file mode 100644 index 0000000000..e2c2ccb31c --- /dev/null +++ b/dolphinscheduler-dao/src/main/java/org/apache/dolphinscheduler/dao/utils/WorkflowUtils.java @@ -0,0 +1,43 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.dolphinscheduler.dao.utils; + +import java.util.Date; +import org.apache.dolphinscheduler.common.utils.DateUtils; +import org.apache.dolphinscheduler.dao.entity.ProcessInstance; + +/** + * workflow utils + */ +public class WorkflowUtils { + + /** + * get workflow duration + * if processInstance is running, the endTime will be the current time + * + * @param processInstance workflow instance + * @return workflow duration + */ + public static String getWorkflowInstanceDuration (ProcessInstance processInstance) { + return processInstance.getState() != null && processInstance.getState().isFinished() ? + DateUtils.format2Duration(processInstance.getStartTime(), processInstance.getEndTime()) : + DateUtils.format2Duration(processInstance.getStartTime(), new Date()); + } + +} + diff --git a/dolphinscheduler-dao/src/test/java/org/apache/dolphinscheduler/dao/utils/WorkflowUtilsTest.java b/dolphinscheduler-dao/src/test/java/org/apache/dolphinscheduler/dao/utils/WorkflowUtilsTest.java new file mode 100644 index 0000000000..985066cbdb --- /dev/null +++ b/dolphinscheduler-dao/src/test/java/org/apache/dolphinscheduler/dao/utils/WorkflowUtilsTest.java @@ -0,0 +1,51 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.dolphinscheduler.dao.utils; + +import java.util.Date; +import org.apache.dolphinscheduler.common.enums.WorkflowExecutionStatus; +import org.apache.dolphinscheduler.common.utils.DateUtils; +import org.apache.dolphinscheduler.dao.entity.ProcessInstance; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; + +class WorkflowUtilsTest { + + @Test + public void testGetWorkflowInstanceDuration() { + ProcessInstance processInstance = new ProcessInstance(); + processInstance.setId(1); + processInstance.setState(null); + Date start = DateUtils.stringToDate("2020-01-20 11:00:00"); + Date end = DateUtils.stringToDate("2020-01-21 12:10:10"); + processInstance.setStartTime(start); + processInstance.setEndTime(end); + + String noStateDuration = WorkflowUtils.getWorkflowInstanceDuration(processInstance); + System.currentTimeMillis(); + Assertions.assertNotEquals("1d 1h 10m 10s", noStateDuration); + + processInstance.setState(WorkflowExecutionStatus.RUNNING_EXECUTION); + String notFinishDuration = WorkflowUtils.getWorkflowInstanceDuration(processInstance); + Assertions.assertNotEquals("1d 1h 10m 10s", notFinishDuration); + + processInstance.setState(WorkflowExecutionStatus.SUCCESS); + String successDuration = WorkflowUtils.getWorkflowInstanceDuration(processInstance); + Assertions.assertEquals("1d 1h 10m 10s", successDuration); + } +} \ No newline at end of file