mirror of
https://gitee.com/dolphinscheduler/DolphinScheduler.git
synced 2024-12-02 12:17:43 +08:00
[Improvement][UI] Support to view the process variables on the page of DAG. (#12609)
This commit is contained in:
parent
064fec88b0
commit
d84f1ef269
@ -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.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_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_PAGING_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(
|
||||
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);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -504,6 +504,9 @@ public enum Status {
|
||||
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_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.", "当前用户无此权限"),
|
||||
FUNCTION_DISABLED(1400002, "The current feature is disabled.", "当前功能已被禁用"),
|
||||
SCHEDULE_TIME_NUMBER(1400003, "The number of complement dates exceed 100.", "补数日期个数超过100"),
|
||||
|
@ -522,4 +522,13 @@ public interface ProcessDefinitionService {
|
||||
* @return Json String
|
||||
*/
|
||||
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);
|
||||
}
|
||||
|
@ -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_TREE_VIEW;
|
||||
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.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.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.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 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.plugin.task.api.enums.SqlType;
|
||||
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.SqlParameters;
|
||||
import org.apache.dolphinscheduler.service.model.TaskNode;
|
||||
@ -133,6 +140,7 @@ import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.Optional;
|
||||
import java.util.Set;
|
||||
import java.util.TreeSet;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.function.Function;
|
||||
import java.util.stream.Collectors;
|
||||
@ -2896,6 +2904,89 @@ public class ProcessDefinitionServiceImpl extends BaseServiceImpl implements Pro
|
||||
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
|
||||
* @param project
|
||||
|
@ -431,4 +431,18 @@ public class ProcessDefinitionControllerTest {
|
||||
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());
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -1060,6 +1060,28 @@ public class ProcessDefinitionServiceTest extends BaseServiceTestTool {
|
||||
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
|
||||
*
|
||||
|
@ -247,3 +247,11 @@ export function viewTree(
|
||||
params
|
||||
})
|
||||
}
|
||||
|
||||
export function viewProcessDefinitionVariables(code: number, processCode: number): any {
|
||||
return axios({
|
||||
url: `/projects/${code}/process-definition/${processCode}/view-variables`,
|
||||
method: 'get'
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -130,3 +130,4 @@ export function viewVariables(id: number, code: number): any {
|
||||
method: 'get'
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -215,6 +215,41 @@ export default defineComponent({
|
||||
}}
|
||||
></NTooltip>
|
||||
)}
|
||||
{props.definition?.processDefinition?.name && (
|
||||
<NTooltip
|
||||
v-slots={{
|
||||
trigger: () => (
|
||||
<NPopover
|
||||
placement='bottom'
|
||||
trigger='click'
|
||||
scrollable
|
||||
style={{ maxWidth: '50vw', maxHeight: '70vh' }}
|
||||
>
|
||||
{{
|
||||
trigger: () => (
|
||||
<NButton
|
||||
quaternary
|
||||
circle
|
||||
class={Styles['toolbar-btn']}
|
||||
>
|
||||
<NIcon>
|
||||
<FundViewOutlined />
|
||||
</NIcon>
|
||||
</NButton>
|
||||
),
|
||||
header: () => (
|
||||
<NText strong depth={1}>
|
||||
{t('project.workflow.parameters_variables')}
|
||||
</NText>
|
||||
),
|
||||
default: () => <VariablesView onCopy={copy} />
|
||||
}}
|
||||
</NPopover>
|
||||
),
|
||||
default: () => t('project.dag.view_variables')
|
||||
}}
|
||||
></NTooltip>
|
||||
)}
|
||||
<div class={Styles['toolbar-left-part']}>
|
||||
{route.name !== 'workflow-instance-detail' &&
|
||||
props.definition?.processDefinition?.releaseState === 'ONLINE' && (
|
||||
@ -224,39 +259,6 @@ export default defineComponent({
|
||||
)}
|
||||
{route.name === 'workflow-instance-detail' && (
|
||||
<>
|
||||
<NTooltip
|
||||
v-slots={{
|
||||
trigger: () => (
|
||||
<NPopover
|
||||
placement='bottom'
|
||||
trigger='click'
|
||||
scrollable
|
||||
style={{ maxWidth: '50vw', maxHeight: '70vh' }}
|
||||
>
|
||||
{{
|
||||
trigger: () => (
|
||||
<NButton
|
||||
quaternary
|
||||
circle
|
||||
class={Styles['toolbar-btn']}
|
||||
>
|
||||
<NIcon>
|
||||
<FundViewOutlined />
|
||||
</NIcon>
|
||||
</NButton>
|
||||
),
|
||||
header: () => (
|
||||
<NText strong depth={1}>
|
||||
{t('project.workflow.parameters_variables')}
|
||||
</NText>
|
||||
),
|
||||
default: () => <VariablesView onCopy={copy} />
|
||||
}}
|
||||
</NPopover>
|
||||
),
|
||||
default: () => t('project.dag.view_variables')
|
||||
}}
|
||||
></NTooltip>
|
||||
<NTooltip
|
||||
v-slots={{
|
||||
trigger: () => (
|
||||
|
@ -19,9 +19,11 @@ import { useRoute } from 'vue-router'
|
||||
import { defineComponent, onMounted, ref, computed } from 'vue'
|
||||
import { useI18n } from 'vue-i18n'
|
||||
import { viewVariables } from '@/service/modules/process-instances'
|
||||
import { viewProcessDefinitionVariables } from "@/service/modules/process-definition";
|
||||
import styles from './variables.module.scss'
|
||||
import { NButton } from 'naive-ui'
|
||||
|
||||
|
||||
export default defineComponent({
|
||||
name: 'variables-view',
|
||||
emits: ['copy'],
|
||||
@ -30,20 +32,29 @@ export default defineComponent({
|
||||
const route = useRoute()
|
||||
|
||||
const projectCode = Number(route.params.projectCode)
|
||||
|
||||
const instanceId = Number(route.params.id)
|
||||
|
||||
const processCode = Number(route.params.code)
|
||||
|
||||
const globalParams = computed(() => {
|
||||
return paramsRef.value ? paramsRef.value.globalParams : []
|
||||
return paramsRef.value && paramsRef.value.globalParams ? paramsRef.value.globalParams : []
|
||||
})
|
||||
|
||||
const localParams = computed(() => {
|
||||
return paramsRef.value ? paramsRef.value.localParams : {}
|
||||
return paramsRef.value && paramsRef.value.localParams ? paramsRef.value.localParams : {}
|
||||
})
|
||||
|
||||
const getViewVariables = () => {
|
||||
viewVariables(instanceId, projectCode).then((res: any) => {
|
||||
paramsRef.value = res
|
||||
})
|
||||
if (Number.isNaN(instanceId)) {
|
||||
viewProcessDefinitionVariables(projectCode, processCode).then((res: any) => {
|
||||
paramsRef.value = res
|
||||
})
|
||||
} else {
|
||||
viewVariables(instanceId, projectCode).then((res: any) => {
|
||||
paramsRef.value = res
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
const handleCopy = (text: string) => {
|
||||
|
Loading…
Reference in New Issue
Block a user