Unverified Commit 27146eec authored by aiwenmo's avatar aiwenmo Committed by GitHub

[Feature-534][admin,web] Add task open API page

[Feature-534][admin,web] Add task open API page
parents 9df82dfc 6e735863
package com.dlink.controller; package com.dlink.controller;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import com.dlink.common.result.Result; import com.dlink.common.result.Result;
import com.dlink.dto.*; import com.dlink.dto.APICancelDTO;
import com.dlink.dto.APIExecuteJarDTO;
import com.dlink.dto.APIExecuteSqlDTO;
import com.dlink.dto.APIExplainSqlDTO;
import com.dlink.dto.APISavePointDTO;
import com.dlink.dto.APISavePointTaskDTO;
import com.dlink.service.APIService; import com.dlink.service.APIService;
import com.dlink.service.StudioService; import com.dlink.service.StudioService;
import com.dlink.service.TaskService; import com.dlink.service.TaskService;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
/** /**
* APIController * APIController
...@@ -27,7 +39,7 @@ public class APIController { ...@@ -27,7 +39,7 @@ public class APIController {
@Autowired @Autowired
private TaskService taskService; private TaskService taskService;
@GetMapping(value = "/submitTask") @GetMapping("/submitTask")
public Result submitTask(@RequestParam Integer id) { public Result submitTask(@RequestParam Integer id) {
return Result.succeed(taskService.submitTask(id), "执行成功"); return Result.succeed(taskService.submitTask(id), "执行成功");
} }
...@@ -74,7 +86,38 @@ public class APIController { ...@@ -74,7 +86,38 @@ public class APIController {
@PostMapping("/savepointTask") @PostMapping("/savepointTask")
public Result savepointTask(@RequestBody APISavePointTaskDTO apiSavePointTaskDTO) { public Result savepointTask(@RequestBody APISavePointTaskDTO apiSavePointTaskDTO) {
return Result.succeed(taskService.savepointTask(apiSavePointTaskDTO.getTaskId(),apiSavePointTaskDTO.getType()), "执行成功"); return Result.succeed(taskService.savepointTask(apiSavePointTaskDTO.getTaskId(), apiSavePointTaskDTO.getType()), "执行成功");
} }
/**
* 重启任务
*/
@GetMapping("/restartTask")
public Result restartTask(@RequestParam Integer id) {
return Result.succeed(taskService.restartTask(id), "重启成功");
}
/**
* 上线任务
*/
@GetMapping("/onLineTask")
public Result onLineTask(@RequestParam Integer id) {
return taskService.onLineTask(id);
}
/**
* 下线任务
*/
@GetMapping("/offLineTask")
public Result offLineTask(@RequestParam Integer id) {
return taskService.offLineTask(id, null);
}
/**
* 重新上线任务
*/
@GetMapping("/reOnLineTask")
public Result reOnLineTask(@RequestParam Integer id) {
return taskService.reOnLineTask(id);
}
} }
package com.dlink.controller; package com.dlink.controller;
import java.util.ArrayList;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import com.dlink.common.result.ProTableResult; import com.dlink.common.result.ProTableResult;
import com.dlink.common.result.Result; import com.dlink.common.result.Result;
import com.dlink.job.JobResult; import com.dlink.job.JobResult;
import com.dlink.model.Task; import com.dlink.model.Task;
import com.dlink.service.TaskService; import com.dlink.service.TaskService;
import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.JsonNode;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.util.ArrayList; import lombok.extern.slf4j.Slf4j;
import java.util.List;
/** /**
* 任务 Controller * 任务 Controller
...@@ -180,5 +189,13 @@ public class TaskController { ...@@ -180,5 +189,13 @@ public class TaskController {
return Result.succeed(taskService.restartTask(id), "重启成功"); return Result.succeed(taskService.restartTask(id), "重启成功");
} }
} }
/**
* 获取当前的 API 的地址
*/
@GetMapping(value = "/getTaskAPIAddress")
public Result getTaskAPIAddress() {
return Result.succeed(taskService.getTaskAPIAddress(), "重启成功");
}
} }
package com.dlink.service; package com.dlink.service;
import java.util.List;
import com.dlink.common.result.Result; import com.dlink.common.result.Result;
import com.dlink.db.service.ISuperService; import com.dlink.db.service.ISuperService;
import com.dlink.job.JobResult; import com.dlink.job.JobResult;
...@@ -9,8 +11,6 @@ import com.dlink.model.JobInstance; ...@@ -9,8 +11,6 @@ import com.dlink.model.JobInstance;
import com.dlink.model.Task; import com.dlink.model.Task;
import com.dlink.result.SqlExplainResult; import com.dlink.result.SqlExplainResult;
import java.util.List;
/** /**
* 作业 服务类 * 作业 服务类
* *
...@@ -56,4 +56,6 @@ public interface TaskService extends ISuperService<Task> { ...@@ -56,4 +56,6 @@ public interface TaskService extends ISuperService<Task> {
JobInstance refreshJobInstance(Integer id, boolean isCoercive); JobInstance refreshJobInstance(Integer id, boolean isCoercive);
JobInfoDetail refreshJobInfoDetail(Integer id); JobInfoDetail refreshJobInfoDetail(Integer id);
String getTaskAPIAddress();
} }
package com.dlink.service.impl; package com.dlink.service.impl;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.time.Duration;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.dlink.alert.Alert; import com.dlink.alert.Alert;
import com.dlink.alert.AlertConfig; import com.dlink.alert.AlertConfig;
...@@ -11,6 +23,7 @@ import com.dlink.assertion.Tips; ...@@ -11,6 +23,7 @@ import com.dlink.assertion.Tips;
import com.dlink.common.result.Result; import com.dlink.common.result.Result;
import com.dlink.config.Dialect; import com.dlink.config.Dialect;
import com.dlink.constant.FlinkRestResultConstant; import com.dlink.constant.FlinkRestResultConstant;
import com.dlink.constant.NetConstant;
import com.dlink.daemon.task.DaemonFactory; import com.dlink.daemon.task.DaemonFactory;
import com.dlink.daemon.task.DaemonTaskConfig; import com.dlink.daemon.task.DaemonTaskConfig;
import com.dlink.db.service.impl.SuperServiceImpl; import com.dlink.db.service.impl.SuperServiceImpl;
...@@ -21,26 +34,44 @@ import com.dlink.gateway.config.SavePointStrategy; ...@@ -21,26 +34,44 @@ import com.dlink.gateway.config.SavePointStrategy;
import com.dlink.gateway.config.SavePointType; import com.dlink.gateway.config.SavePointType;
import com.dlink.gateway.model.JobInfo; import com.dlink.gateway.model.JobInfo;
import com.dlink.gateway.result.SavePointResult; import com.dlink.gateway.result.SavePointResult;
import com.dlink.job.*; import com.dlink.job.FlinkJobTask;
import com.dlink.job.Job;
import com.dlink.job.JobConfig;
import com.dlink.job.JobManager;
import com.dlink.job.JobResult;
import com.dlink.mapper.TaskMapper; import com.dlink.mapper.TaskMapper;
import com.dlink.metadata.driver.Driver; import com.dlink.metadata.driver.Driver;
import com.dlink.metadata.result.JdbcSelectResult; import com.dlink.metadata.result.JdbcSelectResult;
import com.dlink.model.*; import com.dlink.model.AlertGroup;
import com.dlink.model.AlertHistory;
import com.dlink.model.AlertInstance;
import com.dlink.model.Cluster;
import com.dlink.model.DataBase;
import com.dlink.model.Jar;
import com.dlink.model.JobHistory;
import com.dlink.model.JobInfoDetail;
import com.dlink.model.JobInstance;
import com.dlink.model.JobLifeCycle;
import com.dlink.model.JobStatus;
import com.dlink.model.Savepoints;
import com.dlink.model.Statement;
import com.dlink.model.SystemConfiguration;
import com.dlink.model.Task;
import com.dlink.result.SqlExplainResult; import com.dlink.result.SqlExplainResult;
import com.dlink.service.*; import com.dlink.service.AlertGroupService;
import com.dlink.service.AlertHistoryService;
import com.dlink.service.ClusterConfigurationService;
import com.dlink.service.ClusterService;
import com.dlink.service.DataBaseService;
import com.dlink.service.JarService;
import com.dlink.service.JobHistoryService;
import com.dlink.service.JobInstanceService;
import com.dlink.service.SavepointsService;
import com.dlink.service.StatementService;
import com.dlink.service.TaskService;
import com.dlink.utils.CustomStringJavaCompiler; import com.dlink.utils.CustomStringJavaCompiler;
import com.dlink.utils.JSONUtil; import com.dlink.utils.JSONUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import java.time.Duration;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
/** /**
* 任务 服务实现类 * 任务 服务实现类
* *
...@@ -79,6 +110,8 @@ public class TaskServiceImpl extends SuperServiceImpl<TaskMapper, Task> implemen ...@@ -79,6 +110,8 @@ public class TaskServiceImpl extends SuperServiceImpl<TaskMapper, Task> implemen
private String username; private String username;
@Value("${spring.datasource.password}") @Value("${spring.datasource.password}")
private String password; private String password;
@Value("${server.port}")
private String serverPort;
private String buildParas(Integer id) { private String buildParas(Integer id) {
return "--id " + id + " --driver " + driver + " --url " + url + " --username " + username + " --password " + password; return "--id " + id + " --driver " + driver + " --url " + url + " --username " + username + " --password " + password;
...@@ -226,7 +259,7 @@ public class TaskServiceImpl extends SuperServiceImpl<TaskMapper, Task> implemen ...@@ -226,7 +259,7 @@ public class TaskServiceImpl extends SuperServiceImpl<TaskMapper, Task> implemen
JobInstance jobInstance = jobInstanceService.getJobInstanceByTaskId(id); JobInstance jobInstance = jobInstanceService.getJobInstanceByTaskId(id);
if (Asserts.isNotNull(jobInstance) && !JobStatus.isDone(jobInstance.getStatus())) { if (Asserts.isNotNull(jobInstance) && !JobStatus.isDone(jobInstance.getStatus())) {
task.setJobInstanceId(jobInstance.getId()); task.setJobInstanceId(jobInstance.getId());
}else { } else {
task.setJobInstanceId(0); task.setJobInstanceId(0);
} }
} }
...@@ -588,6 +621,19 @@ public class TaskServiceImpl extends SuperServiceImpl<TaskMapper, Task> implemen ...@@ -588,6 +621,19 @@ public class TaskServiceImpl extends SuperServiceImpl<TaskMapper, Task> implemen
return jobInstanceService.getJobInfoDetailInfo(refreshJobInstance(id, true)); return jobInstanceService.getJobInfoDetailInfo(refreshJobInstance(id, true));
} }
@Override
public String getTaskAPIAddress() {
try {
InetAddress inetAddress = InetAddress.getLocalHost();
if (inetAddress != null) {
return inetAddress.getHostAddress() + NetConstant.COLON + serverPort;
}
} catch (UnknownHostException e) {
e.printStackTrace();
}
return "127.0.0.1:" + serverPort;
}
private void handleJobDone(JobInstance jobInstance) { private void handleJobDone(JobInstance jobInstance) {
if (Asserts.isNull(jobInstance.getTaskId())) { if (Asserts.isNull(jobInstance.getTaskId())) {
return; return;
......
...@@ -4,7 +4,7 @@ import { ...@@ -4,7 +4,7 @@ import {
PauseCircleTwoTone, CarryOutTwoTone, DeleteTwoTone, PlayCircleTwoTone, CameraTwoTone, SnippetsTwoTone, PauseCircleTwoTone, CarryOutTwoTone, DeleteTwoTone, PlayCircleTwoTone, CameraTwoTone, SnippetsTwoTone,
FileAddTwoTone, FolderOpenTwoTone, SafetyCertificateTwoTone, SaveTwoTone, FlagTwoTone, CodeTwoTone, FileAddTwoTone, FolderOpenTwoTone, SafetyCertificateTwoTone, SaveTwoTone, FlagTwoTone, CodeTwoTone,
EnvironmentOutlined, SmileOutlined, RocketTwoTone, QuestionCircleTwoTone, MessageOutlined, ClusterOutlined EnvironmentOutlined, SmileOutlined, RocketTwoTone, QuestionCircleTwoTone, MessageOutlined, ClusterOutlined
, EditTwoTone, RestTwoTone, ShrinkOutlined , EditTwoTone, RestTwoTone, ShrinkOutlined, ApiTwoTone
} from "@ant-design/icons"; } from "@ant-design/icons";
import Space from "antd/es/space"; import Space from "antd/es/space";
import Divider from "antd/es/divider"; import Divider from "antd/es/divider";
...@@ -14,6 +14,7 @@ import {StateType} from "@/pages/DataStudio/model"; ...@@ -14,6 +14,7 @@ import {StateType} from "@/pages/DataStudio/model";
import {connect} from "umi"; import {connect} from "umi";
import {CODE, postDataArray} from "@/components/Common/crud"; import {CODE, postDataArray} from "@/components/Common/crud";
import {executeSql, getJobPlan} from "@/pages/DataStudio/service"; import {executeSql, getJobPlan} from "@/pages/DataStudio/service";
import TaskAPI from "@/pages/API/TaskAPI";
import StudioHelp from "./StudioHelp"; import StudioHelp from "./StudioHelp";
import StudioGraph from "./StudioGraph"; import StudioGraph from "./StudioGraph";
import { import {
...@@ -456,6 +457,18 @@ const StudioMenu = (props: any) => { ...@@ -456,6 +457,18 @@ const StudioMenu = (props: any) => {
return itemList; return itemList;
}; };
const showAPI = () => {
Modal.info({
title: current.task.alias + ' API 手册',
width: 1000,
content: (
<TaskAPI task={current.task}/>
),
onOk() {
},
});
};
const showHelp = () => { const showHelp = () => {
Modal.info({ Modal.info({
title: '使用帮助', title: '使用帮助',
...@@ -499,14 +512,12 @@ const StudioMenu = (props: any) => { ...@@ -499,14 +512,12 @@ const StudioMenu = (props: any) => {
<Divider className={styles["ant-divider-horizontal-0"]}/> <Divider className={styles["ant-divider-horizontal-0"]}/>
<Col span={24}> <Col span={24}>
<Row> <Row>
<Col span={4}> <Col span={16}>
<Breadcrumb className={styles["dw-path"]}> <Breadcrumb className={styles["dw-path"]}>
<EnvironmentOutlined/> <EnvironmentOutlined/>
<Divider type="vertical"/> <Divider type="vertical"/>
{getPathItem(currentPath)} {getPathItem(currentPath)}
</Breadcrumb> </Breadcrumb>
</Col>
<Col span={12}>
{currentSession.session && {currentSession.session &&
( (
<Breadcrumb className={styles["dw-path"]}> <Breadcrumb className={styles["dw-path"]}>
...@@ -645,6 +656,13 @@ const StudioMenu = (props: any) => { ...@@ -645,6 +656,13 @@ const StudioMenu = (props: any) => {
/> />
</Tooltip> : undefined </Tooltip> : undefined
} }
<Tooltip title="查看 API">
<Button
type="text"
icon={<ApiTwoTone />}
onClick={showAPI}
/>
</Tooltip>
<Tooltip title="查看使用帮助"> <Tooltip title="查看使用帮助">
<Button <Button
type="text" type="text"
...@@ -652,7 +670,13 @@ const StudioMenu = (props: any) => { ...@@ -652,7 +670,13 @@ const StudioMenu = (props: any) => {
onClick={showHelp} onClick={showHelp}
/> />
</Tooltip> </Tooltip>
</Col> : undefined} </Col> : <Col span={8}><Tooltip title="查看使用帮助">
<Button
type="text"
icon={<QuestionCircleTwoTone/>}
onClick={showHelp}
/>
</Tooltip></Col>}
</Row> </Row>
</Col> </Col>
<StudioExplain <StudioExplain
......
import {Typography, Tabs, Badge, Empty} from "antd";
import CodeShow from "@/components/Common/CodeShow";
import {useEffect, useState} from "react";
import {getTaskAPIAddress} from "@/pages/API/service";
const {Title, Paragraph, Text, Link} = Typography;
const {TabPane} = Tabs;
const TaskAPI = (props: any) => {
const {task} = props;
const [address, setAddress] = useState<string>('127.0.0.1:8888');
useEffect(() => {
getAddress();
}, []);
const getAddress = () => {
const res = getTaskAPIAddress();
res.then((result)=>{
if(result.datas){
setAddress(result.datas);
}
})
}
return (
<Tabs defaultActiveKey="tableInfo" size="small">
<TabPane
tab={
<span>
异步提交
</span>
}
key="submitTask"
>
<CodeShow code={`curl http://${address}/openapi/submitTask?id=${(task ? task.id : '1')}`} language='shell'
height='500px' theme="vs-dark"/>
</TabPane>
<TabPane
tab={
<span>
停止作业
</span>
}
key="cancelJob"
>
<CodeShow code={`curl --location --request POST 'http://${address}/openapi/savepointTask' \\
--header 'Content-Type: application/json' \\
--data-raw '{
"taskId":${(task ? task.id : '1')},
"type":"canceljob"
}'`} language='shell' height='500px' theme="vs-dark"/>
</TabPane>
<TabPane
tab={
<span>
重启作业
</span>
}
key="restartTask"
>
<CodeShow code={`curl http://${address}/openapi/restartTask?id=${(task ? task.id : '1')}`} language='shell'
height='500px' theme="vs-dark"/>
</TabPane>
<TabPane
tab={
<span>
SavePoint 触发
</span>
}
key="triggerSavePoint"
>
<CodeShow code={`curl --location --request POST 'http://${address}/openapi/savepointTask' \\
--header 'Content-Type: application/json' \\
--data-raw '{
"taskId":${(task ? task.id : '1')},
"type":"trigger"
}'`} language='shell' height='500px' theme="vs-dark"/>
</TabPane>
<TabPane
tab={
<span>
SavePoint 停止
</span>
}
key="cancelSavePoint"
>
<CodeShow code={`curl --location --request POST 'http://${address}/openapi/savepointTask' \\
--header 'Content-Type: application/json' \\
--data-raw '{
"taskId":${(task ? task.id : '1')},
"type":"cancel"
}'`} language='shell' height='500px' theme="vs-dark"/>
</TabPane>
<TabPane
tab={
<span>
上线作业
</span>
}
key="onLineTask"
>
<CodeShow code={`curl http://${address}/openapi/onLineTask?id=${(task ? task.id : '1')}`} language='shell'
height='500px' theme="vs-dark"/>
</TabPane>
<TabPane
tab={
<span>
下线作业
</span>
}
key="offLineTask"
>
<CodeShow code={`curl http://${address}/openapi/offLineTask?id=${(task ? task.id : '1')}`} language='shell'
height='500px' theme="vs-dark"/>
</TabPane>
<TabPane
tab={
<span>
重新上线作业
</span>
}
key="reOnLineTask"
>
<CodeShow code={`curl http://${address}/openapi/reOnLineTask?id=${(task ? task.id : '1')}`} language='shell'
height='500px' theme="vs-dark"/>
</TabPane>
</Tabs>
);
};
export default TaskAPI;
import {getData} from "@/components/Common/crud";
export function getTaskAPIAddress() {
return getData("api/task/getTaskAPIAddress");
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment