Browse Source

[Improvement][UI] Support to view the process variables on the page of DAG. (#12609)

3.2.0-release
calvin 2 years ago committed by GitHub
parent
commit
d84f1ef269
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 24
      dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/controller/ProcessDefinitionController.java
  2. 3
      dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/enums/Status.java
  3. 9
      dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/service/ProcessDefinitionService.java
  4. 91
      dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/service/impl/ProcessDefinitionServiceImpl.java
  5. 14
      dolphinscheduler-api/src/test/java/org/apache/dolphinscheduler/api/controller/ProcessDefinitionControllerTest.java
  6. 22
      dolphinscheduler-api/src/test/java/org/apache/dolphinscheduler/api/service/ProcessDefinitionServiceTest.java
  7. 8
      dolphinscheduler-ui/src/service/modules/process-definition/index.ts
  8. 1
      dolphinscheduler-ui/src/service/modules/process-instances/index.ts
  9. 20
      dolphinscheduler-ui/src/views/projects/workflow/components/dag/dag-toolbar.tsx
  10. 15
      dolphinscheduler-ui/src/views/projects/workflow/instance/components/variables-view.tsx

24
dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/controller/ProcessDefinitionController.java

@ -27,6 +27,7 @@ import static org.apache.dolphinscheduler.api.enums.Status.ENCAPSULATION_TREEVIE
import static org.apache.dolphinscheduler.api.enums.Status.GET_TASKS_LIST_BY_PROCESS_DEFINITION_ID_ERROR; import static org.apache.dolphinscheduler.api.enums.Status.GET_TASKS_LIST_BY_PROCESS_DEFINITION_ID_ERROR;
import static org.apache.dolphinscheduler.api.enums.Status.IMPORT_PROCESS_DEFINE_ERROR; import static org.apache.dolphinscheduler.api.enums.Status.IMPORT_PROCESS_DEFINE_ERROR;
import static org.apache.dolphinscheduler.api.enums.Status.QUERY_DETAIL_OF_PROCESS_DEFINITION_ERROR; import static org.apache.dolphinscheduler.api.enums.Status.QUERY_DETAIL_OF_PROCESS_DEFINITION_ERROR;
import static org.apache.dolphinscheduler.api.enums.Status.QUERY_PROCESS_DEFINITION_ALL_VARIABLES_ERROR;
import static org.apache.dolphinscheduler.api.enums.Status.QUERY_PROCESS_DEFINITION_LIST; import static org.apache.dolphinscheduler.api.enums.Status.QUERY_PROCESS_DEFINITION_LIST;
import static org.apache.dolphinscheduler.api.enums.Status.QUERY_PROCESS_DEFINITION_LIST_PAGING_ERROR; import static org.apache.dolphinscheduler.api.enums.Status.QUERY_PROCESS_DEFINITION_LIST_PAGING_ERROR;
import static org.apache.dolphinscheduler.api.enums.Status.QUERY_PROCESS_DEFINITION_VERSIONS_ERROR; import static org.apache.dolphinscheduler.api.enums.Status.QUERY_PROCESS_DEFINITION_VERSIONS_ERROR;
@ -872,4 +873,27 @@ public class ProcessDefinitionController extends BaseController {
return returnDataList( return returnDataList(
processDefinitionService.releaseWorkflowAndSchedule(loginUser, projectCode, code, releaseState)); processDefinitionService.releaseWorkflowAndSchedule(loginUser, projectCode, code, releaseState));
} }
/**
* query process definition global variables and local variables
*
* @param loginUser login user
* @param code process definition code
* @return variables data
*/
@Operation(summary = "viewVariables", description = "QUERY_PROCESS_DEFINITION_GLOBAL_VARIABLES_AND_LOCAL_VARIABLES_NOTES")
@Parameters({
@Parameter(name = "code", description = "PROCESS_DEFINITION_CODE", required = true, schema = @Schema(implementation = long.class, example = "100"))
})
@GetMapping(value = "/{code}/view-variables")
@ResponseStatus(HttpStatus.OK)
@ApiException(QUERY_PROCESS_DEFINITION_ALL_VARIABLES_ERROR)
@AccessLogAnnotation
public Result viewVariables(@Parameter(hidden = true) @RequestAttribute(value = Constants.SESSION_USER) User loginUser,
@Parameter(name = "projectCode", description = "PROJECT_CODE", required = true) @PathVariable long projectCode,
@PathVariable("code") Long code) {
Map<String, Object> result = processDefinitionService.viewVariables(loginUser, projectCode, code);
return returnDataList(result);
}
} }

3
dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/enums/Status.java

@ -504,6 +504,9 @@ public enum Status {
USER_PASSWORD_LENGTH_ERROR(1300017, "user's password length error", "用户密码长度错误"), USER_PASSWORD_LENGTH_ERROR(1300017, "user's password length error", "用户密码长度错误"),
QUERY_CAN_USE_K8S_NAMESPACE_ERROR(1300018, "login user query can used namespace list error", "查询可用命名空间错误"), QUERY_CAN_USE_K8S_NAMESPACE_ERROR(1300018, "login user query can used namespace list error", "查询可用命名空间错误"),
QUERY_PROCESS_DEFINITION_ALL_VARIABLES_ERROR(1300100, "query process definition all variables error",
"查询工作流自定义变量信息错误"),
NO_CURRENT_OPERATING_PERMISSION(1400001, "The current user does not have this permission.", "当前用户无此权限"), NO_CURRENT_OPERATING_PERMISSION(1400001, "The current user does not have this permission.", "当前用户无此权限"),
FUNCTION_DISABLED(1400002, "The current feature is disabled.", "当前功能已被禁用"), FUNCTION_DISABLED(1400002, "The current feature is disabled.", "当前功能已被禁用"),
SCHEDULE_TIME_NUMBER(1400003, "The number of complement dates exceed 100.", "补数日期个数超过100"), SCHEDULE_TIME_NUMBER(1400003, "The number of complement dates exceed 100.", "补数日期个数超过100"),

9
dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/service/ProcessDefinitionService.java

@ -522,4 +522,13 @@ public interface ProcessDefinitionService {
* @return Json String * @return Json String
*/ */
String doOtherOperateProcess(User loginUser, ProcessDefinition processDefinition); String doOtherOperateProcess(User loginUser, ProcessDefinition processDefinition);
/**
* view process variables
* @param loginUser login user
* @param projectCode project code
* @param code process definition code
* @return variables data
*/
Map<String, Object> viewVariables(User loginUser, long projectCode, long code);
} }

91
dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/service/impl/ProcessDefinitionServiceImpl.java

@ -31,11 +31,17 @@ import static org.apache.dolphinscheduler.api.constants.ApiFuncIdentificationCon
import static org.apache.dolphinscheduler.api.constants.ApiFuncIdentificationConstant.WORKFLOW_SWITCH_TO_THIS_VERSION; import static org.apache.dolphinscheduler.api.constants.ApiFuncIdentificationConstant.WORKFLOW_SWITCH_TO_THIS_VERSION;
import static org.apache.dolphinscheduler.api.constants.ApiFuncIdentificationConstant.WORKFLOW_TREE_VIEW; import static org.apache.dolphinscheduler.api.constants.ApiFuncIdentificationConstant.WORKFLOW_TREE_VIEW;
import static org.apache.dolphinscheduler.api.constants.ApiFuncIdentificationConstant.WORKFLOW_UPDATE; import static org.apache.dolphinscheduler.api.constants.ApiFuncIdentificationConstant.WORKFLOW_UPDATE;
import static org.apache.dolphinscheduler.api.enums.Status.PROCESS_DEFINE_NOT_EXIST;
import static org.apache.dolphinscheduler.common.constants.CommandKeyConstants.CMD_PARAM_SUB_PROCESS_DEFINE_CODE; import static org.apache.dolphinscheduler.common.constants.CommandKeyConstants.CMD_PARAM_SUB_PROCESS_DEFINE_CODE;
import static org.apache.dolphinscheduler.common.constants.Constants.COPY_SUFFIX; import static org.apache.dolphinscheduler.common.constants.Constants.COPY_SUFFIX;
import static org.apache.dolphinscheduler.common.constants.Constants.DATA_LIST;
import static org.apache.dolphinscheduler.common.constants.Constants.DEFAULT_WORKER_GROUP; import static org.apache.dolphinscheduler.common.constants.Constants.DEFAULT_WORKER_GROUP;
import static org.apache.dolphinscheduler.common.constants.Constants.EMPTY_STRING; import static org.apache.dolphinscheduler.common.constants.Constants.EMPTY_STRING;
import static org.apache.dolphinscheduler.common.constants.Constants.GLOBAL_PARAMS;
import static org.apache.dolphinscheduler.common.constants.Constants.IMPORT_SUFFIX; import static org.apache.dolphinscheduler.common.constants.Constants.IMPORT_SUFFIX;
import static org.apache.dolphinscheduler.common.constants.Constants.LOCAL_PARAMS;
import static org.apache.dolphinscheduler.plugin.task.api.TaskConstants.LOCAL_PARAMS_LIST;
import static org.apache.dolphinscheduler.plugin.task.api.TaskConstants.TASK_TYPE;
import static org.apache.dolphinscheduler.plugin.task.api.TaskConstants.TASK_TYPE_SQL; import static org.apache.dolphinscheduler.plugin.task.api.TaskConstants.TASK_TYPE_SQL;
import org.apache.dolphinscheduler.api.dto.DagDataSchedule; import org.apache.dolphinscheduler.api.dto.DagDataSchedule;
@ -106,6 +112,7 @@ import org.apache.dolphinscheduler.dao.repository.ProcessDefinitionDao;
import org.apache.dolphinscheduler.dao.repository.TaskDefinitionLogDao; import org.apache.dolphinscheduler.dao.repository.TaskDefinitionLogDao;
import org.apache.dolphinscheduler.plugin.task.api.enums.SqlType; import org.apache.dolphinscheduler.plugin.task.api.enums.SqlType;
import org.apache.dolphinscheduler.plugin.task.api.enums.TaskTimeoutStrategy; import org.apache.dolphinscheduler.plugin.task.api.enums.TaskTimeoutStrategy;
import org.apache.dolphinscheduler.plugin.task.api.model.Property;
import org.apache.dolphinscheduler.plugin.task.api.parameters.ParametersNode; import org.apache.dolphinscheduler.plugin.task.api.parameters.ParametersNode;
import org.apache.dolphinscheduler.plugin.task.api.parameters.SqlParameters; import org.apache.dolphinscheduler.plugin.task.api.parameters.SqlParameters;
import org.apache.dolphinscheduler.service.model.TaskNode; import org.apache.dolphinscheduler.service.model.TaskNode;
@ -133,6 +140,7 @@ import java.util.Map;
import java.util.Objects; import java.util.Objects;
import java.util.Optional; import java.util.Optional;
import java.util.Set; import java.util.Set;
import java.util.TreeSet;
import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentHashMap;
import java.util.function.Function; import java.util.function.Function;
import java.util.stream.Collectors; import java.util.stream.Collectors;
@ -2896,6 +2904,89 @@ public class ProcessDefinitionServiceImpl extends BaseServiceImpl implements Pro
return null; return null;
} }
/**
* view process variables
* @param loginUser login user
* @param projectCode project code
* @param code process definition code
* @return variables data
*/
@Override
public Map<String, Object> viewVariables(User loginUser, long projectCode, long code) {
Project project = projectMapper.queryByCode(projectCode);
// check user access for project
Map<String, Object> result =
projectService.checkProjectAndAuth(loginUser, project, projectCode, WORKFLOW_DEFINITION);
if (result.get(Constants.STATUS) != Status.SUCCESS) {
return result;
}
ProcessDefinition processDefinition = processDefinitionMapper.queryByCode(code);
if (Objects.isNull(processDefinition) || projectCode != processDefinition.getProjectCode()) {
logger.error("Process definition does not exist, projectCode:{}, processDefinitionCode:{}.", projectCode,
code);
putMsg(result, PROCESS_DEFINE_NOT_EXIST, code);
return result;
}
// global params
List<Property> globalParams = processDefinition.getGlobalParamList();
Map<String, Map<String, Object>> localUserDefParams = getLocalParams(processDefinition);
Map<String, Object> resultMap = new HashMap<>();
if (Objects.nonNull(globalParams)) {
resultMap.put(GLOBAL_PARAMS, globalParams);
}
if (Objects.nonNull(localUserDefParams)) {
resultMap.put(LOCAL_PARAMS, localUserDefParams);
}
result.put(DATA_LIST, resultMap);
putMsg(result, Status.SUCCESS);
return result;
}
/**
* get local params
*/
private Map<String, Map<String, Object>> getLocalParams(ProcessDefinition processDefinition) {
Map<String, Map<String, Object>> localUserDefParams = new HashMap<>();
Set<Long> taskCodeSet = new TreeSet<>();
processTaskRelationMapper.queryByProcessCode(processDefinition.getProjectCode(), processDefinition.getCode())
.forEach(processTaskRelation -> {
if (processTaskRelation.getPreTaskCode() > 0) {
taskCodeSet.add(processTaskRelation.getPreTaskCode());
}
if (processTaskRelation.getPostTaskCode() > 0) {
taskCodeSet.add(processTaskRelation.getPostTaskCode());
}
});
taskDefinitionMapper.queryByCodeList(taskCodeSet)
.stream().forEach(taskDefinition -> {
Map<String, Object> localParamsMap = new HashMap<>();
String localParams = JSONUtils.getNodeString(taskDefinition.getTaskParams(), LOCAL_PARAMS);
if (!StringUtils.isEmpty(localParams)) {
List<Property> localParamsList = JSONUtils.toList(localParams, Property.class);
localParamsMap.put(TASK_TYPE, taskDefinition.getTaskType());
localParamsMap.put(LOCAL_PARAMS_LIST, localParamsList);
if (CollectionUtils.isNotEmpty(localParamsList)) {
localUserDefParams.put(taskDefinition.getName(), localParamsMap);
}
}
});
return localUserDefParams;
}
/** /**
* delete other relation * delete other relation
* @param project * @param project

14
dolphinscheduler-api/src/test/java/org/apache/dolphinscheduler/api/controller/ProcessDefinitionControllerTest.java

@ -431,4 +431,18 @@ public class ProcessDefinitionControllerTest {
Assertions.assertEquals(Status.SUCCESS.getCode(), (int) result.getCode()); Assertions.assertEquals(Status.SUCCESS.getCode(), (int) result.getCode());
} }
@Test
public void testViewVariables() {
long projectCode = 1L;
Map<String, Object> resultMap = new HashMap<>();
putMsg(resultMap, Status.SUCCESS);
Mockito.when(processDefinitionService.viewVariables(user, projectCode, 1))
.thenReturn(resultMap);
Result result = processDefinitionController.viewVariables(user, projectCode, 1L);
Assertions.assertEquals(Status.SUCCESS.getCode(), result.getCode().intValue());
}
} }

22
dolphinscheduler-api/src/test/java/org/apache/dolphinscheduler/api/service/ProcessDefinitionServiceTest.java

@ -1060,6 +1060,28 @@ public class ProcessDefinitionServiceTest extends BaseServiceTestTool {
Assertions.assertEquals(processDefinition, processDefinitionUpdate); Assertions.assertEquals(processDefinition, processDefinitionUpdate);
} }
@Test
public void testViewVariables() {
Mockito.when(projectMapper.queryByCode(projectCode)).thenReturn(getProject(projectCode));
Project project = getProject(projectCode);
ProcessDefinition processDefinition = getProcessDefinition();
Map<String, Object> result = new HashMap<>();
putMsg(result, Status.PROJECT_NOT_FOUND, projectCode);
// project check auth fail
Mockito.when(projectService.checkProjectAndAuth(user, project, projectCode, WORKFLOW_DEFINITION))
.thenReturn(result);
Map<String, Object> map =
processDefinitionService.viewVariables(user, processDefinition.getProjectCode(),
processDefinition.getCode());
Assertions.assertEquals(Status.PROJECT_NOT_FOUND, map.get(Constants.STATUS));
}
/** /**
* get mock processDefinition * get mock processDefinition
* *

8
dolphinscheduler-ui/src/service/modules/process-definition/index.ts

@ -247,3 +247,11 @@ export function viewTree(
params params
}) })
} }
export function viewProcessDefinitionVariables(code: number, processCode: number): any {
return axios({
url: `/projects/${code}/process-definition/${processCode}/view-variables`,
method: 'get'
})
}

1
dolphinscheduler-ui/src/service/modules/process-instances/index.ts

@ -130,3 +130,4 @@ export function viewVariables(id: number, code: number): any {
method: 'get' method: 'get'
}) })
} }

20
dolphinscheduler-ui/src/views/projects/workflow/components/dag/dag-toolbar.tsx

@ -215,15 +215,7 @@ export default defineComponent({
}} }}
></NTooltip> ></NTooltip>
)} )}
<div class={Styles['toolbar-left-part']}> {props.definition?.processDefinition?.name && (
{route.name !== 'workflow-instance-detail' &&
props.definition?.processDefinition?.releaseState === 'ONLINE' && (
<NTag round size='small' type='info'>
{t('project.dag.online')}
</NTag>
)}
{route.name === 'workflow-instance-detail' && (
<>
<NTooltip <NTooltip
v-slots={{ v-slots={{
trigger: () => ( trigger: () => (
@ -257,6 +249,16 @@ export default defineComponent({
default: () => t('project.dag.view_variables') default: () => t('project.dag.view_variables')
}} }}
></NTooltip> ></NTooltip>
)}
<div class={Styles['toolbar-left-part']}>
{route.name !== 'workflow-instance-detail' &&
props.definition?.processDefinition?.releaseState === 'ONLINE' && (
<NTag round size='small' type='info'>
{t('project.dag.online')}
</NTag>
)}
{route.name === 'workflow-instance-detail' && (
<>
<NTooltip <NTooltip
v-slots={{ v-slots={{
trigger: () => ( trigger: () => (

15
dolphinscheduler-ui/src/views/projects/workflow/instance/components/variables-view.tsx

@ -19,9 +19,11 @@ import { useRoute } from 'vue-router'
import { defineComponent, onMounted, ref, computed } from 'vue' import { defineComponent, onMounted, ref, computed } from 'vue'
import { useI18n } from 'vue-i18n' import { useI18n } from 'vue-i18n'
import { viewVariables } from '@/service/modules/process-instances' import { viewVariables } from '@/service/modules/process-instances'
import { viewProcessDefinitionVariables } from "@/service/modules/process-definition";
import styles from './variables.module.scss' import styles from './variables.module.scss'
import { NButton } from 'naive-ui' import { NButton } from 'naive-ui'
export default defineComponent({ export default defineComponent({
name: 'variables-view', name: 'variables-view',
emits: ['copy'], emits: ['copy'],
@ -30,21 +32,30 @@ export default defineComponent({
const route = useRoute() const route = useRoute()
const projectCode = Number(route.params.projectCode) const projectCode = Number(route.params.projectCode)
const instanceId = Number(route.params.id) const instanceId = Number(route.params.id)
const processCode = Number(route.params.code)
const globalParams = computed(() => { const globalParams = computed(() => {
return paramsRef.value ? paramsRef.value.globalParams : [] return paramsRef.value && paramsRef.value.globalParams ? paramsRef.value.globalParams : []
}) })
const localParams = computed(() => { const localParams = computed(() => {
return paramsRef.value ? paramsRef.value.localParams : {} return paramsRef.value && paramsRef.value.localParams ? paramsRef.value.localParams : {}
}) })
const getViewVariables = () => { const getViewVariables = () => {
if (Number.isNaN(instanceId)) {
viewProcessDefinitionVariables(projectCode, processCode).then((res: any) => {
paramsRef.value = res
})
} else {
viewVariables(instanceId, projectCode).then((res: any) => { viewVariables(instanceId, projectCode).then((res: any) => {
paramsRef.value = res paramsRef.value = res
}) })
} }
}
const handleCopy = (text: string) => { const handleCopy = (text: string) => {
ctx.emit('copy', text) ctx.emit('copy', text)

Loading…
Cancel
Save