From 8d6c637b3785db329400809b70e0cdcd9ba3cb89 Mon Sep 17 00:00:00 2001 From: lanyuanxiaoyao Date: Wed, 10 Jan 2024 16:15:32 +0800 Subject: [PATCH] =?UTF-8?q?feat(web):=20=E5=A2=9E=E5=8A=A0=E7=A6=BB?= =?UTF-8?q?=E7=BA=BF=E6=A3=80=E7=B4=A2=E9=A1=B5=E9=9D=A2=E5=92=8C=E4=BB=BB?= =?UTF-8?q?=E5=8A=A1=E6=9F=A5=E7=9C=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../web/controller/TaskController.java | 56 +++++++++++ .../service/web/entity/YarnApplicationVO.java | 27 ++++++ .../resources/static/components/common.js | 36 ++++++- .../resources/static/components/task-tab.js | 96 +++++++++++++++++++ .../src/main/resources/static/index.html | 2 + 5 files changed, 216 insertions(+), 1 deletion(-) create mode 100644 service-web/src/main/java/com/lanyuanxiaoyao/service/web/controller/TaskController.java create mode 100644 service-web/src/main/resources/static/components/task-tab.js diff --git a/service-web/src/main/java/com/lanyuanxiaoyao/service/web/controller/TaskController.java b/service-web/src/main/java/com/lanyuanxiaoyao/service/web/controller/TaskController.java new file mode 100644 index 0000000..c5d1a34 --- /dev/null +++ b/service-web/src/main/java/com/lanyuanxiaoyao/service/web/controller/TaskController.java @@ -0,0 +1,56 @@ +package com.lanyuanxiaoyao.service.web.controller; + +import cn.hutool.core.util.StrUtil; +import com.lanyuanxiaoyao.service.configuration.ExecutorProvider; +import com.lanyuanxiaoyao.service.forest.service.TaskService; +import com.lanyuanxiaoyao.service.web.controller.base.AmisMapResponse; +import com.lanyuanxiaoyao.service.web.controller.base.AmisResponse; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; + +/** + * 任务提交 + * + * @author lanyuanxiaoyao + * @date 2024-01-10 + */ +@SuppressWarnings("SpringJavaInjectionPointsAutowiringInspection") +@RestController +@RequestMapping("task") +public class TaskController { + private static final Logger logger = LoggerFactory.getLogger(TaskController.class); + + private final TaskService taskService; + + public TaskController(TaskService taskService) { + this.taskService = taskService; + } + + @GetMapping("scan") + public AmisResponse scan( + @RequestParam("hdfs") String hdfs, + @RequestParam("key") String key, + @RequestParam(value = "mode", defaultValue = "") String mode + ) { + if (StrUtil.isBlank(hdfs) || StrUtil.isBlank(key)) { + throw new RuntimeException("Argument cannot be blank"); + } + ExecutorProvider.EXECUTORS.submit(() -> { + boolean scanLog = StrUtil.contains(mode, "log"); + boolean scanData = StrUtil.contains(mode, "data"); + String applicationId = taskService.scan(hdfs, key, scanLog, scanData); + logger.info("Task: {}", applicationId); + }); + return AmisResponse.responseSuccess(); + } + + @GetMapping("results") + public AmisMapResponse results(@RequestParam("task_id") String taskId) { + return AmisResponse.responseMapData() + .setData("text", taskService.results(taskId).makeString("\n")); + } +} diff --git a/service-web/src/main/java/com/lanyuanxiaoyao/service/web/entity/YarnApplicationVO.java b/service-web/src/main/java/com/lanyuanxiaoyao/service/web/entity/YarnApplicationVO.java index ac11d13..98e13ee 100644 --- a/service-web/src/main/java/com/lanyuanxiaoyao/service/web/entity/YarnApplicationVO.java +++ b/service-web/src/main/java/com/lanyuanxiaoyao/service/web/entity/YarnApplicationVO.java @@ -7,6 +7,8 @@ import com.fasterxml.jackson.annotation.JsonIgnore; import com.lanyuanxiaoyao.service.configuration.entity.yarn.YarnApplication; import com.lanyuanxiaoyao.service.configuration.utils.DatetimeUtil; import java.time.Instant; +import java.util.regex.Matcher; +import java.util.regex.Pattern; /** * YarnApplication 展示类 @@ -15,12 +17,15 @@ import java.time.Instant; * @date 2023-04-21 */ public class YarnApplicationVO { + private static final Pattern TASK_REGEX = Pattern.compile("^Service_Task_(.+)_(.{8})$"); + @JsonIgnore private final YarnApplication yarnApplication; private final Boolean isHudiApplication; private final Boolean isSyncApplication; private final Boolean isCompactionApplication; + private final Boolean isTaskApplication; private String startTimeFromNow; private String finishTimeFromNow; @@ -28,6 +33,9 @@ public class YarnApplicationVO { private String flinkJobName; private String alias; + private String taskName; + private String taskId; + private Double compactionCompletionRatio = 0.0; public YarnApplicationVO(YarnApplication yarnApplication) { @@ -37,6 +45,13 @@ public class YarnApplicationVO { isCompactionApplication = NameHelper.isCompactionJob(yarnApplication.getName()); isHudiApplication = isSyncApplication || isCompactionApplication; + Matcher matcher = TASK_REGEX.matcher(yarnApplication.getName()); + isTaskApplication = matcher.matches(); + if (isTaskApplication && matcher.groupCount() == 2) { + taskName = matcher.group(1); + taskId = matcher.group(2); + } + long now = Instant.now().toEpochMilli(); if (ObjectUtil.isNotNull(yarnApplication.getStartedTime()) && yarnApplication.getStartedTime() != 0) { startTimeFromNow = DatetimeUtil.fromNow(now, yarnApplication.getStartedTime()); @@ -147,6 +162,10 @@ public class YarnApplicationVO { return isHudiApplication; } + public Boolean getTaskApplication() { + return isTaskApplication; + } + public String getStartTimeFromNow() { return startTimeFromNow; } @@ -167,6 +186,14 @@ public class YarnApplicationVO { return alias; } + public String getTaskName() { + return taskName; + } + + public String getTaskId() { + return taskId; + } + public Double getCompactionCompletionRatio() { return compactionCompletionRatio; } diff --git a/service-web/src/main/resources/static/components/common.js b/service-web/src/main/resources/static/components/common.js index 3d577c2..27eb3d0 100644 --- a/service-web/src/main/resources/static/components/common.js +++ b/service-web/src/main/resources/static/components/common.js @@ -238,7 +238,7 @@ function yarnCrudColumns() { label: '名称', className: 'nowrap', type: 'tpl', - tpl: "${IF(syncApplication, 'S', IF(compactionApplication, 'C', ''))}${IF(hudiApplication, '', '')}${IF(syncApplication, flinkJobName, IF(compactionApplication, alias, name))}", + tpl: "${IF(syncApplication, 'S', IF(compactionApplication, 'C', IF(taskApplication, 'T', '')))}${IF(hudiApplication || taskApplication, '', '')}${IF(syncApplication, flinkJobName, IF(compactionApplication, alias, IF(taskApplication, taskName, name)))}", // tpl: '${name}', backgroundScale: { min: 0.001, @@ -399,6 +399,40 @@ function yarnCrudColumns() { level: 'link', tooltip: '${alias}' }, + { + disabledOn: '${finalStatus != \'SUCCEEDED\' || state != \'FINISHED\'}', + disabledTip: '无结果', + visibleOn: 'taskId', + label: '结果', + level: 'link', + type: 'action', + actionType: 'dialog', + dialog: { + title: '结果', + ...readOnlyDialogOptions(), + size: 'xl', + body: [ + { + type: 'service', + api: { + method: 'get', + url: '${base}/task/results', + data: { + task_id: '${taskId|default:undefined}' + } + }, + body: { + type: 'editor', + disabled: true, + name: 'text', + options: { + wordWrap: 'on' + } + } + } + ], + }, + }, { label: 'ID', type: 'action', diff --git a/service-web/src/main/resources/static/components/task-tab.js b/service-web/src/main/resources/static/components/task-tab.js new file mode 100644 index 0000000..f647a8a --- /dev/null +++ b/service-web/src/main/resources/static/components/task-tab.js @@ -0,0 +1,96 @@ +function taskTab() { + return { + title: `离线检索`, + tab: [ + { + type: 'form', + title: '检索文件', + actions: [ + { + type: 'submit', + label: '提交任务', + actionType: 'ajax', + api: { + method: 'get', + url: '${base}/task/scan', + data: { + hdfs: '${hdfs|default:undefined}', + key: '${key|default:undefined}', + mode: '${scan_mode|default:undefined}', + } + } + }, + ], + body: [ + { + name: 'scan_mode', + type: 'checkboxes', + label: '检索范围', + checkAll: true, + required: true, + value: 'log', + options: [ + {label: '日志文件', value: 'log'}, + {label: '数据文件', value: 'data'}, + ] + }, + { + type: 'group', + body: [ + { + type: 'input-text', + name: 'key', + label: '检索字段', + required: true, + clearable: true, + description: '检索带有该字符的记录', + columnRatio: 4, + }, + { + type: 'input-text', + name: 'hdfs', + label: 'HDFS路经', + required: true, + clearable: true, + description: '输入表HDFS路径', + autoComplete: '${base}/table/all_hdfs?key=$term', + columnRatio: 8, + }, + ] + } + ] + }, + { + type: 'crud', + api: { + method: 'get', + url: `\${base}/yarn/job_list`, + data: { + clusters: `b12`, + page: '${page|default:undefined}', + count: '${perPage|default:undefined}', + order: '${orderBy|default:undefined}', + direction: '${orderDir|default:undefined}', + filter_state: '${state|default:undefined}', + filter_final_status: '${finalStatus|default:undefined}', + search_id: '${id|default:undefined}', + search_name: 'Service_Task', + precise: false, + } + }, + affixHeader: false, + interval: 10000, + syncLocation: false, + silentPolling: true, + resizable: false, + perPage: 10, + headerToolbar: [ + "reload", + paginationCommonOptions(), + ], + footerToolbar: [], + columns: yarnCrudColumns(), + } + ] + } +} \ No newline at end of file diff --git a/service-web/src/main/resources/static/index.html b/service-web/src/main/resources/static/index.html index 10cfdb6..fba7ad7 100644 --- a/service-web/src/main/resources/static/index.html +++ b/service-web/src/main/resources/static/index.html @@ -49,6 +49,7 @@ +