From c4c99361df6e45c6e728519196ddc425029977e8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=8B=8F=E4=B9=89=E8=B6=85?= Date: Fri, 13 Mar 2026 17:21:16 +0800 Subject: [PATCH 1/3] update globalParams replace and test --- .../impl/WorkflowInstanceServiceImpl.java | 28 ++++--- .../service/WorkflowInstanceServiceTest.java | 84 +++++++++++++++++++ 2 files changed, 99 insertions(+), 13 deletions(-) diff --git a/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/service/impl/WorkflowInstanceServiceImpl.java b/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/service/impl/WorkflowInstanceServiceImpl.java index 3fe84523afc2..16e250738347 100644 --- a/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/service/impl/WorkflowInstanceServiceImpl.java +++ b/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/service/impl/WorkflowInstanceServiceImpl.java @@ -819,27 +819,29 @@ public Map viewVariables(long projectCode, Integer workflowInsta Map timeParams = BusinessTimeUtils .getBusinessTime(workflowInstance.getCmdTypeIfComplement(), workflowInstance.getScheduleTime(), timezone); - String userDefinedParams = workflowInstance.getGlobalParams(); + // global params - List globalParams = new ArrayList<>(); - - // global param string - String globalParamStr = - ParameterUtils.convertParameterPlaceholders(JSONUtils.toJsonString(globalParams), timeParams); - globalParams = JSONUtils.toList(globalParamStr, Property.class); - for (Property property : globalParams) { - timeParams.put(property.getProp(), property.getValue()); - } + String globalParamsJson = workflowInstance.getGlobalParams(); + List finalGlobalParams = new ArrayList<>(); + + if (StringUtils.isNotEmpty(globalParamsJson)) { + String replacedJsonStr = ParameterUtils.convertParameterPlaceholders(globalParamsJson, timeParams); + finalGlobalParams = JSONUtils.toList(replacedJsonStr, Property.class); - if (userDefinedParams != null && userDefinedParams.length() > 0) { - globalParams = JSONUtils.toList(userDefinedParams, Property.class); + if (finalGlobalParams != null) { + for (Property property : finalGlobalParams) { + if (property.getProp() != null && property.getValue() != null) { + timeParams.put(property.getProp(), property.getValue()); + } + } + } } Map> localUserDefParams = getLocalParams(workflowInstance, timeParams); Map resultMap = new HashMap<>(); - resultMap.put(GLOBAL_PARAMS, globalParams); + resultMap.put(GLOBAL_PARAMS, finalGlobalParams); resultMap.put(LOCAL_PARAMS, localUserDefParams); result.put(DATA_LIST, resultMap); diff --git a/dolphinscheduler-api/src/test/java/org/apache/dolphinscheduler/api/service/WorkflowInstanceServiceTest.java b/dolphinscheduler-api/src/test/java/org/apache/dolphinscheduler/api/service/WorkflowInstanceServiceTest.java index 592231fffc57..45c0c9b3ac2a 100644 --- a/dolphinscheduler-api/src/test/java/org/apache/dolphinscheduler/api/service/WorkflowInstanceServiceTest.java +++ b/dolphinscheduler-api/src/test/java/org/apache/dolphinscheduler/api/service/WorkflowInstanceServiceTest.java @@ -81,6 +81,7 @@ import java.io.IOException; import java.text.MessageFormat; import java.util.ArrayList; +import java.util.Calendar; import java.util.Date; import java.util.HashMap; import java.util.List; @@ -790,6 +791,89 @@ public void testViewVariables() { Assertions.assertEquals(Status.WORKFLOW_INSTANCE_NOT_EXIST, processNotExist.get(Constants.STATUS)); } + @Test + public void testViewVariables_WithTimePlaceholders() { + String globalParamsJson = "[{\"prop\":\"biz_date\",\"value\":\"$[yyyyMMdd]\",\"type\":\"VARCHAR\"}," + + "{\"prop\":\"env\",\"value\":\"${ENV_TYPE}\",\"type\":\"VARCHAR\"}]"; + + WorkflowInstance workflowInstance = getProcessInstance(); + workflowInstance.setId(1); + workflowInstance.setCommandType(CommandType.SCHEDULER); + + Calendar calendar = Calendar.getInstance(); + calendar.set(2026, Calendar.MARCH, 13, 10, 0, 0); + workflowInstance.setScheduleTime(calendar.getTime()); + workflowInstance.setGlobalParams(globalParamsJson); + workflowInstance.setWorkflowDefinitionCode(100L); + + when(workflowInstanceMapper.queryDetailById(1)).thenReturn(workflowInstance); + + WorkflowDefinition workflowDefinition = new WorkflowDefinition(); + workflowDefinition.setCode(100L); + workflowDefinition.setProjectCode(1L); + when(workflowDefinitionMapper.queryByCode(100L)).thenReturn(workflowDefinition); + + Map result = workflowInstanceService.viewVariables(1L, 1); + + Assertions.assertEquals(Status.SUCCESS, result.get(Constants.STATUS)); + + Map dataList = (Map) result.get(Constants.DATA_LIST); + Assertions.assertNotNull(dataList); + + List globalParams = (List) dataList.get(Constants.GLOBAL_PARAMS); + Assertions.assertNotNull(globalParams); + Assertions.assertEquals(2, globalParams.size()); + + Property dateParam = globalParams.stream() + .filter(p -> "biz_date".equals(p.getProp())) + .findFirst() + .orElse(null); + Assertions.assertNotNull(dateParam); + Assertions.assertEquals("20260313", dateParam.getValue(), + "Time placeholder $[yyyyMMdd] should be replaced with schedule time"); + + Property envParam = globalParams.stream() + .filter(p -> "env".equals(p.getProp())) + .findFirst() + .orElse(null); + Assertions.assertNotNull(envParam); + } + + @Test + public void testViewVariables_InstanceNotFound() { + when(workflowInstanceMapper.queryDetailById(999)).thenReturn(null); + + Map result = workflowInstanceService.viewVariables(1L, 999); + + Assertions.assertEquals(Status.WORKFLOW_INSTANCE_NOT_EXIST, result.get(Constants.STATUS)); + Assertions.assertNull(result.get(Constants.DATA_LIST)); + } + + @Test + public void testViewVariables_EmptyGlobalParams() { + WorkflowInstance workflowInstance = getProcessInstance(); + workflowInstance.setId(2); + workflowInstance.setCommandType(CommandType.START_PROCESS); + workflowInstance.setScheduleTime(new Date()); + workflowInstance.setGlobalParams(""); + workflowInstance.setWorkflowDefinitionCode(101L); + + when(workflowInstanceMapper.queryDetailById(2)).thenReturn(workflowInstance); + + WorkflowDefinition workflowDefinition = new WorkflowDefinition(); + workflowDefinition.setCode(101L); + workflowDefinition.setProjectCode(1L); + when(workflowDefinitionMapper.queryByCode(101L)).thenReturn(workflowDefinition); + + Map result = workflowInstanceService.viewVariables(1L, 2); + + Assertions.assertEquals(Status.SUCCESS, result.get(Constants.STATUS)); + + Map dataList = (Map) result.get(Constants.DATA_LIST); + List globalParams = (List) dataList.get(Constants.GLOBAL_PARAMS); + Assertions.assertTrue(globalParams.isEmpty(), "Global params list should be empty when input is empty string"); + } + @Test public void testViewGantt() throws Exception { WorkflowInstance workflowInstance = getProcessInstance(); From 81fc9a88a318d1ef6cf2dd7c048c5126cc099a21 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=8B=8F=E4=B9=89=E8=B6=85?= Date: Wed, 18 Mar 2026 15:20:50 +0800 Subject: [PATCH 2/3] resolve conflicts --- .../service/impl/WorkflowInstanceServiceImpl.java | 13 +------------ 1 file changed, 1 insertion(+), 12 deletions(-) diff --git a/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/service/impl/WorkflowInstanceServiceImpl.java b/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/service/impl/WorkflowInstanceServiceImpl.java index cfef0349378a..8c4f7746ecf3 100644 --- a/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/service/impl/WorkflowInstanceServiceImpl.java +++ b/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/service/impl/WorkflowInstanceServiceImpl.java @@ -825,20 +825,9 @@ public Map viewVariables(long projectCode, Integer workflowInsta String globalParamsJson = workflowInstance.getGlobalParams(); List finalGlobalParams = new ArrayList<>(); - // global param string - String globalParamStr = - ParameterUtils.convertParameterPlaceholders(GlobalParameterUtils.serializeGlobalParameter(globalParams), - timeParams); - globalParams = GlobalParameterUtils.deserializeGlobalParameter(globalParamStr); - for (Property property : globalParams) { - timeParams.put(property.getProp(), property.getValue()); - } - - if (userDefinedParams != null && userDefinedParams.length() > 0) { - globalParams = GlobalParameterUtils.deserializeGlobalParameter(userDefinedParams); if (StringUtils.isNotEmpty(globalParamsJson)) { String replacedJsonStr = ParameterUtils.convertParameterPlaceholders(globalParamsJson, timeParams); - finalGlobalParams = JSONUtils.toList(replacedJsonStr, Property.class); + finalGlobalParams = GlobalParameterUtils.deserializeGlobalParameter(replacedJsonStr); if (finalGlobalParams != null) { for (Property property : finalGlobalParams) { From b91f8bc73d62fa6570d1cd86e9ce7be188248147 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=8B=8F=E4=B9=89=E8=B6=85?= Date: Thu, 9 Apr 2026 17:18:12 +0800 Subject: [PATCH 3/3] add processGlobalParams --- .../impl/WorkflowInstanceServiceImpl.java | 64 +++++++++++++------ .../service/WorkflowInstanceServiceTest.java | 19 ++++++ 2 files changed, 63 insertions(+), 20 deletions(-) diff --git a/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/service/impl/WorkflowInstanceServiceImpl.java b/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/service/impl/WorkflowInstanceServiceImpl.java index 7b79a22eda03..af44786055b9 100644 --- a/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/service/impl/WorkflowInstanceServiceImpl.java +++ b/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/service/impl/WorkflowInstanceServiceImpl.java @@ -784,59 +784,83 @@ public Map viewVariables(long projectCode, Integer workflowInsta timezone = commandParam.getTimeZone(); } - Map timeParams = BusinessTimeUtils + Map parameterMap = BusinessTimeUtils .getBusinessTime(workflowInstance.getCmdTypeIfComplement(), workflowInstance.getScheduleTime(), timezone); - // global params - String globalParamsJson = workflowInstance.getGlobalParams(); + // finalGlobalParams + List finalGlobalParams = processGlobalParams(workflowInstance, parameterMap); + + // localUserDefParams + Map> localUserDefParams = processLocalParams(workflowInstance, parameterMap); + + Map resultMap = new HashMap<>(); + resultMap.put(GLOBAL_PARAMS, finalGlobalParams); + resultMap.put(LOCAL_PARAMS, localUserDefParams); + + result.put(DATA_LIST, resultMap); + putMsg(result, Status.SUCCESS); + return result; + } + + /** + * Process global parameters: resolve placeholders and merge into context. + * + * @param workflowInstance The workflow instance. + * @param parameterMap Context parameters for placeholder replacement and merging + * @return Deserialized global properties list + */ + private List processGlobalParams(WorkflowInstance workflowInstance, Map parameterMap) { List finalGlobalParams = new ArrayList<>(); + String globalParamsJson = workflowInstance.getGlobalParams(); if (StringUtils.isNotEmpty(globalParamsJson)) { - String replacedJsonStr = ParameterUtils.convertParameterPlaceholders(globalParamsJson, timeParams); + // Replace placeholders + String replacedJsonStr = ParameterUtils.convertParameterPlaceholders(globalParamsJson, parameterMap); finalGlobalParams = GlobalParameterUtils.deserializeGlobalParameter(replacedJsonStr); + // Merge into context map if (finalGlobalParams != null) { for (Property property : finalGlobalParams) { if (property.getProp() != null && property.getValue() != null) { - timeParams.put(property.getProp(), property.getValue()); + parameterMap.put(property.getProp(), property.getValue()); } } } } - - Map> localUserDefParams = getLocalParams(workflowInstance, timeParams); - - Map resultMap = new HashMap<>(); - - resultMap.put(GLOBAL_PARAMS, finalGlobalParams); - resultMap.put(LOCAL_PARAMS, localUserDefParams); - - result.put(DATA_LIST, resultMap); - putMsg(result, Status.SUCCESS); - return result; + return finalGlobalParams; } /** - * get local params + * Process local parameters for tasks within a workflow instance. + * + * @param workflowInstance The workflow instance. + * @param parameterMap Context parameters for placeholder replacement. + * @return Map of task name to its local parameters and type. */ - private Map> getLocalParams(WorkflowInstance workflowInstance, - Map timeParams) { + private Map> processLocalParams(WorkflowInstance workflowInstance, + Map parameterMap) { Map> localUserDefParams = new HashMap<>(); + + // Fetch valid task instances for the workflow List taskInstanceList = taskInstanceMapper.findValidTaskListByWorkflowInstanceId(workflowInstance.getId(), Flag.YES); + for (TaskInstance taskInstance : taskInstanceList) { TaskDefinitionLog taskDefinitionLog = taskDefinitionLogMapper.queryByDefinitionCodeAndVersion( taskInstance.getTaskCode(), taskInstance.getTaskDefinitionVersion()); String localParams = JSONUtils.getNodeString(taskDefinitionLog.getTaskParams(), LOCAL_PARAMS); + if (!StringUtils.isEmpty(localParams)) { - localParams = ParameterUtils.convertParameterPlaceholders(localParams, timeParams); + // Replace placeholders and deserialize + localParams = ParameterUtils.convertParameterPlaceholders(localParams, parameterMap); List localParamsList = JSONUtils.toList(localParams, Property.class); Map localParamsMap = new HashMap<>(); localParamsMap.put(TASK_TYPE, taskDefinitionLog.getTaskType()); localParamsMap.put(LOCAL_PARAMS_LIST, localParamsList); + if (CollectionUtils.isNotEmpty(localParamsList)) { localUserDefParams.put(taskDefinitionLog.getName(), localParamsMap); } diff --git a/dolphinscheduler-api/src/test/java/org/apache/dolphinscheduler/api/service/WorkflowInstanceServiceTest.java b/dolphinscheduler-api/src/test/java/org/apache/dolphinscheduler/api/service/WorkflowInstanceServiceTest.java index af478cbf2cb3..37b2d3740369 100644 --- a/dolphinscheduler-api/src/test/java/org/apache/dolphinscheduler/api/service/WorkflowInstanceServiceTest.java +++ b/dolphinscheduler-api/src/test/java/org/apache/dolphinscheduler/api/service/WorkflowInstanceServiceTest.java @@ -42,6 +42,7 @@ import org.apache.dolphinscheduler.common.model.TaskNodeRelation; import org.apache.dolphinscheduler.common.utils.DateUtils; import org.apache.dolphinscheduler.common.utils.JSONUtils; +import org.apache.dolphinscheduler.dao.AlertDao; import org.apache.dolphinscheduler.dao.entity.DependentResultTaskInstanceContext; import org.apache.dolphinscheduler.dao.entity.Project; import org.apache.dolphinscheduler.dao.entity.TaskDefinition; @@ -56,6 +57,7 @@ import org.apache.dolphinscheduler.dao.entity.WorkflowInstance; import org.apache.dolphinscheduler.dao.mapper.ProjectMapper; 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.mapper.WorkflowDefinitionLogMapper; import org.apache.dolphinscheduler.dao.mapper.WorkflowDefinitionMapper; @@ -63,6 +65,7 @@ import org.apache.dolphinscheduler.dao.repository.TaskInstanceContextDao; import org.apache.dolphinscheduler.dao.repository.TaskInstanceDao; import org.apache.dolphinscheduler.dao.repository.WorkflowInstanceDao; +import org.apache.dolphinscheduler.dao.repository.WorkflowInstanceMapDao; import org.apache.dolphinscheduler.extract.master.command.RunWorkflowCommandParam; import org.apache.dolphinscheduler.plugin.task.api.TaskPluginManager; import org.apache.dolphinscheduler.plugin.task.api.enums.DataType; @@ -70,6 +73,7 @@ import org.apache.dolphinscheduler.plugin.task.api.enums.Direct; import org.apache.dolphinscheduler.plugin.task.api.enums.TaskExecutionStatus; import org.apache.dolphinscheduler.plugin.task.api.model.Property; +import org.apache.dolphinscheduler.service.expand.CuringParamsService; import org.apache.dolphinscheduler.service.model.TaskNode; import org.apache.dolphinscheduler.service.process.ProcessService; @@ -146,6 +150,21 @@ public class WorkflowInstanceServiceTest { @Mock private TaskInstanceContextDao taskInstanceContextDao; + @Mock + TaskInstanceMapper taskInstanceMapper; + + @Mock + CuringParamsService curingGlobalParamsService; + + @Mock + TaskInstanceService taskInstanceService; + + @Mock + WorkflowInstanceMapDao workflowInstanceMapDao; + + @Mock + AlertDao alertDao; + private String shellJson = "[{\"name\":\"\",\"preTaskCode\":0,\"preTaskVersion\":0,\"postTaskCode\":123456789," + "\"postTaskVersion\":1,\"conditionType\":0,\"conditionParams\":\"{}\"},{\"name\":\"\",\"preTaskCode\":123456789," + "\"preTaskVersion\":1,\"postTaskCode\":123451234,\"postTaskVersion\":1,\"conditionType\":0,\"conditionParams\":\"{}\"}]";