Unverified Commit 019eb858 authored by xiaoguaiguai's avatar xiaoguaiguai Committed by GitHub

Merge branch 'DataLinkDC:dev' into dev

parents 16eff581 841296da
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.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.StudioService;
import com.dlink.service.TaskService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
/**
* APIController
......@@ -27,7 +39,7 @@ public class APIController {
@Autowired
private TaskService taskService;
@GetMapping(value = "/submitTask")
@GetMapping("/submitTask")
public Result submitTask(@RequestParam Integer id) {
return Result.succeed(taskService.submitTask(id), "执行成功");
}
......@@ -74,7 +86,38 @@ public class APIController {
@PostMapping("/savepointTask")
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;
import com.dlink.assertion.Asserts;
import com.dlink.common.result.Result;
import com.dlink.dto.SessionDTO;
import com.dlink.dto.StudioCADTO;
import com.dlink.dto.StudioDDLDTO;
import com.dlink.dto.StudioExecuteDTO;
import com.dlink.explainer.lineage.LineageResult;
import com.dlink.job.JobResult;
import com.dlink.result.IResult;
import com.dlink.service.StudioService;
......
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.Result;
import com.dlink.job.JobResult;
import com.dlink.model.Task;
import com.dlink.service.TaskService;
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 java.util.List;
import lombok.extern.slf4j.Slf4j;
/**
* 任务 Controller
......@@ -180,5 +189,13 @@ public class TaskController {
return Result.succeed(taskService.restartTask(id), "重启成功");
}
}
/**
* 获取当前的 API 的地址
*/
@GetMapping(value = "/getTaskAPIAddress")
public Result getTaskAPIAddress() {
return Result.succeed(taskService.getTaskAPIAddress(), "重启成功");
}
}
......@@ -15,4 +15,5 @@ public class StudioCADTO extends AbstractStatementDTO {
// It's useless for the time being
private Boolean statementSet;
private Integer type;
private String dialect;
}
package com.dlink.service;
import java.util.List;
import com.dlink.common.result.Result;
import com.dlink.db.service.ISuperService;
import com.dlink.job.JobResult;
......@@ -9,8 +11,6 @@ import com.dlink.model.JobInstance;
import com.dlink.model.Task;
import com.dlink.result.SqlExplainResult;
import java.util.List;
/**
* 作业 服务类
*
......@@ -56,4 +56,6 @@ public interface TaskService extends ISuperService<Task> {
JobInstance refreshJobInstance(Integer id, boolean isCoercive);
JobInfoDetail refreshJobInfoDetail(Integer id);
String getTaskAPIAddress();
}
......@@ -256,8 +256,16 @@ public class StudioServiceImpl implements StudioService {
@Override
public LineageResult getLineage(StudioCADTO studioCADTO) {
addFlinkSQLEnv(studioCADTO);
return LineageBuilder.getLineage(studioCADTO.getStatement(), studioCADTO.getStatementSet());
if (Asserts.isNotNullString(studioCADTO.getDialect()) && !studioCADTO.getDialect().equalsIgnoreCase("flinksql")) {
if(studioCADTO.getDialect().equalsIgnoreCase("doris")){
return com.dlink.explainer.sqlLineage.LineageBuilder.getSqlLineage(studioCADTO.getStatement(),"mysql");
} else {
return com.dlink.explainer.sqlLineage.LineageBuilder.getSqlLineage(studioCADTO.getStatement(),studioCADTO.getDialect().toLowerCase());
}
} else {
addFlinkSQLEnv(studioCADTO);
return LineageBuilder.getLineage(studioCADTO.getStatement(), studioCADTO.getStatementSet());
}
}
@Override
......
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.dlink.alert.Alert;
import com.dlink.alert.AlertConfig;
......@@ -11,6 +23,7 @@ import com.dlink.assertion.Tips;
import com.dlink.common.result.Result;
import com.dlink.config.Dialect;
import com.dlink.constant.FlinkRestResultConstant;
import com.dlink.constant.NetConstant;
import com.dlink.daemon.task.DaemonFactory;
import com.dlink.daemon.task.DaemonTaskConfig;
import com.dlink.db.service.impl.SuperServiceImpl;
......@@ -21,26 +34,44 @@ import com.dlink.gateway.config.SavePointStrategy;
import com.dlink.gateway.config.SavePointType;
import com.dlink.gateway.model.JobInfo;
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.metadata.driver.Driver;
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.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.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
private String username;
@Value("${spring.datasource.password}")
private String password;
@Value("${server.port}")
private String serverPort;
private String buildParas(Integer id) {
return "--id " + id + " --driver " + driver + " --url " + url + " --username " + username + " --password " + password;
......@@ -226,7 +259,7 @@ public class TaskServiceImpl extends SuperServiceImpl<TaskMapper, Task> implemen
JobInstance jobInstance = jobInstanceService.getJobInstanceByTaskId(id);
if (Asserts.isNotNull(jobInstance) && !JobStatus.isDone(jobInstance.getStatus())) {
task.setJobInstanceId(jobInstance.getId());
}else {
} else {
task.setJobInstanceId(0);
}
}
......@@ -588,6 +621,19 @@ public class TaskServiceImpl extends SuperServiceImpl<TaskMapper, Task> implemen
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) {
if (Asserts.isNull(jobInstance.getTaskId())) {
return;
......
......@@ -147,5 +147,10 @@
<scope>${scope.runtime}</scope>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-starter</artifactId>
</dependency>
</dependencies>
</project>
\ No newline at end of file
</project>
package com.dlink.explainer.sqlLineage;
import com.dlink.assertion.Asserts;
import lombok.Data;
@Data
public class LineageColumn implements Comparable<LineageColumn> {
public String getTargetColumnName() {
return targetColumnName;
}
public void setTargetColumnName(String targetColumnName) {
this.targetColumnName = targetColumnName;
}
private String targetColumnName;
private String sourceDbName;
public String getSourceDbName() {
return sourceDbName;
}
public void setSourceDbName(String sourceDbName) {
this.sourceDbName = sourceDbName;
}
public String getSourceTableName() {
return sourceTableName;
}
public String getSourceColumnName() {
return sourceColumnName;
}
public void setSourceColumnName(String sourceColumnName) {
this.sourceColumnName = sourceColumnName;
}
private String sourceTableName;
private String sourceColumnName;
public String getExpression() {
return expression;
}
public void setExpression(String expression) {
this.expression = expression;
}
private String expression;
public Boolean getIsEnd() {
return isEnd;
}
public void setIsEnd(Boolean end) {
isEnd = end;
}
private Boolean isEnd = false;
public void setSourceTableName(String sourceTableName) {
sourceTableName = Asserts.isNotNullString(sourceTableName) ? sourceTableName.replace("`",
"") : sourceTableName;
if(sourceTableName.contains(" ")){
sourceTableName = sourceTableName.substring(0,sourceTableName.indexOf(" "));
}
if (sourceTableName.contains(".")) {
if(Asserts.isNullString(this.sourceDbName)){
this.sourceDbName = sourceTableName.substring(0, sourceTableName.indexOf("."));
}
// this.sourceDbName = sourceTableName.substring(0, sourceTableName.indexOf("."));
this.sourceTableName = sourceTableName.substring(sourceTableName.indexOf(".") + 1);
} else {
this.sourceTableName = sourceTableName;
}
}
public int compareTo(LineageColumn o) {
if(Asserts.isNotNullString(this.getSourceDbName())&& Asserts.isNotNullString(this.getSourceTableName())){
if(this.getSourceDbName().equals(o.getSourceDbName())&&this.getSourceTableName().equals(o.getSourceTableName())&&this.getTargetColumnName().equals(o.getTargetColumnName())){
return 0;
}
} else if(Asserts.isNotNullString(this.getSourceTableName())){
if(this.getSourceTableName().equals(o.getSourceTableName())&&this.getTargetColumnName().equals(o.getTargetColumnName())){
return 0;
}
} else {
if (this.getTargetColumnName().equals(o.getTargetColumnName())) {
return 0;
}
}
return -1;
}
@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass()) {
return false;
}
LineageColumn myColumn = (LineageColumn) o;
if (!this.getTargetColumnName().equals(myColumn.getTargetColumnName())) {
return false;
}
if (Asserts.isNotNullString(sourceTableName) && !sourceTableName.equals(myColumn.sourceTableName)) {
return false;
}
if (Asserts.isNotNullString(sourceColumnName)) {
return sourceColumnName.equals(myColumn.sourceColumnName);
}
return true;
}
@Override
public int hashCode() {
int result = getTargetColumnName().hashCode();
if (Asserts.isNotNullString(sourceTableName)) {
result = 31 * result + sourceTableName.hashCode();
}
if (Asserts.isNotNullString(sourceColumnName)) {
result = 31 * result + sourceColumnName.hashCode();
}
if (Asserts.isNotNullString(sourceDbName)) {
result = 31 * result + sourceDbName.hashCode();
}
return result;
}
}
package com.dlink.explainer.sqlLineage;
import java.util.*;
public class TreeNode<T> implements Iterable<TreeNode<T>> {
/**
* 树节点
*/
public T data;
/**
* 父节点,根没有父节点
*/
public TreeNode<T> parent;
/**
* 子节点,叶子节点没有子节点
*/
public List<TreeNode<T>> children;
/**
* 保存了当前节点及其所有子节点,方便查询
*/
private List<TreeNode<T>> elementsIndex;
/**
* 构造函数
*
* @param data
*/
public TreeNode(T data) {
this.data = data;
this.children = new LinkedList<TreeNode<T>>();
this.elementsIndex = new LinkedList<TreeNode<T>>();
this.elementsIndex.add(this);
}
public T getData() {
return data;
}
public List<TreeNode<T>> getChildren() {
return children;
}
/**
* 判断是否为根:根没有父节点
*
* @return
*/
public boolean isRoot() {
return parent == null;
}
/**
* 判断是否为叶子节点:子节点没有子节点
*
* @return
*/
public boolean isLeaf() {
return children.size() == 0;
}
/**
* 添加一个子节点
*
* @param child
* @return
*/
public TreeNode<T> addChild(T child) {
TreeNode<T> childNode = new TreeNode<T>(child);
childNode.parent = this;
this.children.add(childNode);
this.registerChildForSearch(childNode);
return childNode;
}
public TreeNode<T> addChild(TreeNode childNode) {
childNode.parent = this;
this.children.add(childNode);
this.registerChildForSearch(childNode);
return childNode;
}
/**
* 获取当前节点的层
*
* @return
*/
public int getLevel() {
if (this.isRoot()) {
return 0;
} else {
return parent.getLevel() + 1;
}
}
/**
* 递归为当前节点以及当前节点的所有父节点增加新的节点
*
* @param node
*/
private void registerChildForSearch(TreeNode<T> node) {
elementsIndex.add(node);
if (parent != null) {
parent.registerChildForSearch(node);
}
}
/**
* 从当前节点及其所有子节点中搜索某节点
*
* @param cmp
* @return
*/
public TreeNode<T> findTreeNode(Comparable<T> cmp) {
for (TreeNode<T> element : this.elementsIndex) {
T elData = element.data;
if (cmp.compareTo(elData) == 0) {
return element;
}
}
return null;
}
public TreeNode<T> findChildNode(Comparable<T> cmp) {
for (TreeNode<T> element : this.getChildren()) {
T elData = element.data;
if (cmp.compareTo(elData) == 0) {
return element;
}
}
return null;
}
/**
* 获取当前节点的迭代器
*
* @return
*/
public Iterator<TreeNode<T>> iterator() {
TreeNodeIterator<T> iterator = new TreeNodeIterator<T>(this);
return iterator;
}
@Override
public String toString() {
return data != null ? data.toString() : "[tree data null]";
}
/**
* 获取所有叶子节点的数据
*
* @return
*/
public Set<TreeNode<T>> getAllLeafs() {
Set<TreeNode<T>> leafNodes = new HashSet<TreeNode<T>>();
if (this.children.isEmpty()) {
leafNodes.add(this);
} else {
for (TreeNode<T> child : this.children) {
leafNodes.addAll(child.getAllLeafs());
}
}
return leafNodes;
}
/**
* 获取所有叶子节点的数据
*
* @return
*/
public Set<T> getAllLeafData() {
Set<T> leafNodes = new HashSet<T>();
if (this.children.isEmpty()) {
leafNodes.add(this.data);
} else {
for (TreeNode<T> child : this.children) {
leafNodes.addAll(child.getAllLeafData());
}
}
return leafNodes;
}
}
package com.dlink.explainer.sqlLineage;
import java.util.Iterator;
public class TreeNodeIterator<T> implements Iterator<TreeNode<T>> {
private ProcessStages doNext;
private TreeNode<T> next;
private Iterator<TreeNode<T>> childrenCurNodeIter;
private Iterator<TreeNode<T>> childrenSubNodeIter;
private TreeNode<T> treeNode;
public TreeNodeIterator(TreeNode<T> treeNode) {
this.treeNode = treeNode;
this.doNext = ProcessStages.ProcessParent;
this.childrenCurNodeIter = treeNode.children.iterator();
}
public boolean hasNext() {
if (this.doNext == ProcessStages.ProcessParent) {
this.next = this.treeNode;
this.doNext = ProcessStages.ProcessChildCurNode;
return true;
}
if (this.doNext == ProcessStages.ProcessChildCurNode) {
if (childrenCurNodeIter.hasNext()) {
TreeNode<T> childDirect = childrenCurNodeIter.next();
childrenSubNodeIter = childDirect.iterator();
this.doNext = ProcessStages.ProcessChildSubNode;
return hasNext();
} else {
this.doNext = null;
return false;
}
}
if (this.doNext == ProcessStages.ProcessChildSubNode) {
if (childrenSubNodeIter.hasNext()) {
this.next = childrenSubNodeIter.next();
return true;
} else {
this.next = null;
this.doNext = ProcessStages.ProcessChildCurNode;
return hasNext();
}
}
return false;
}
public TreeNode<T> next() {
return this.next;
}
/**
* 目前不支持删除节点
*/
public void remove() {
throw new UnsupportedOperationException();
}
enum ProcessStages {
ProcessParent, ProcessChildCurNode, ProcessChildSubNode
}
}
......@@ -25,7 +25,6 @@ const Lineage = (props: any) => {
tables: [],
relations: []
};
debugger;
allData.relations.forEach(relation => {
if (relation.srcTableId !== tableId) {
return;
......
import { Tabs,Tooltip,Button } from "antd";
import {SearchOutlined} from "@ant-design/icons";
import {Tabs, Tooltip, Button, Modal, message} from "antd";
import {SearchOutlined, SnippetsOutlined} from "@ant-design/icons";
import {StateType} from "@/pages/DataStudio/model";
import {connect} from "umi";
import styles from "./index.less";
import {getLineage} from "@/pages/DataStudio/service";
import {getLineage, getStreamGraph} from "@/pages/DataStudio/service";
import {useState} from "react";
import Lineage, {getInit} from "@/components/Lineage";
import CodeShow from "@/components/Common/CodeShow";
const { TabPane } = Tabs;
......@@ -17,24 +18,61 @@ const StudioCA = (props: any) => {
const res = getLineage({
statement:current.value,
statementSet:current.task.statementSet,
dialect:current.task.dialect,
type: 1,
});
res.then((result)=>{
setData(result.datas);
if(result.datas){
setData(result.datas);
}else {
message.error(`获取作业血缘失败,原因:\n${result.msg}`);
}
})
};
const handleExportStreamGraphPlan=()=>{
const res = getStreamGraph({
...current.task,
configJson: JSON.stringify(current.task.config),
statement: current.value,
});
res.then((result)=>{
Modal.info({
title: current.task.alias + '的 StreamGraphPlan',
width: 1000,
content: (
<CodeShow code={JSON.stringify((result.datas?result.datas:result.msg), null, "\t")} language='json'
height='500px' theme="vs-dark"/>
),
onOk() {
},
});
})
};
return (<>
<Tabs defaultActiveKey="Lineage" size="small" tabPosition="top" style={{border: "1px solid #f0f0f0"}}
tabBarExtraContent={<Tooltip title="重新计算血缘">
<Button
type="text"
icon={<SearchOutlined />}
onClick={handleLineage}
>
计算血缘
</Button>
</Tooltip>}
tabBarExtraContent={
<>
<Tooltip title="重新计算血缘">
<Button
type="text"
icon={<SearchOutlined />}
onClick={handleLineage}
>
计算血缘
</Button>
</Tooltip>
<Tooltip title="导出 StreamGraphPlan">
<Button
type="text"
icon={<SnippetsOutlined />}
onClick={handleExportStreamGraphPlan}
>
StreamGraphPlan
</Button>
</Tooltip>
</>}
>
<TabPane tab={<span>血缘分析</span>} key="Lineage">
<Lineage datas={data}/>
......
......@@ -47,4 +47,5 @@ export type CAParam = {
statement: string,
statementSet: boolean,
type: number,
dialect?: string,
}
import {Typography, Divider, Badge, Empty} from "antd";
import {Typography} from "antd";
const { Title, Paragraph, Text, Link } = Typography;
const { Title, Paragraph, Link } = Typography;
const StudioMsg = () => {
return (
<Typography>
<Title level={3}>基本概念与使用</Title>
<Title level={3}>欢迎大家加入 Dinky 的官方社区,共建共赢~ </Title>
<Paragraph>
介绍了 0.2.1 版本 Flink 集群、共享会话、同步执行、异步提交的概念及使用。
<ul>
<li>
<Link href="https://github.com/DataLinkDC/dlink" target="_blank">GitHub:https://github.com/DataLinkDC/dlink</Link>
</li>
<li>
<Link href="https://gitee.com/DataLinkDC/Dinky" target="_blank">Gitee: https://gitee.com/DataLinkDC/Dinky</Link>
</li>
<li>
公众号:DataLink数据中台
</li>
<li>
<Link href="http://www.dlink.top" target="_blank">官网文档:http://www.dlink.top</Link>
</li>
<li>
<Link href="https://space.bilibili.com/366484959/video" target="_blank">B站视频:是文末呀</Link>
</li>
<li>
微信用户社区群:推荐,添加微信号 wenmo_ai 邀请进群 (申请备注 Dinky + 企业名 + 职位,不写不批)
</li>
<li>
QQ用户社区群:543709668 (申请备注 Dinky + 企业名 + 职位,不写不批)
</li>
</ul>
</Paragraph>
<Title level={4}>Flink 集群</Title>
<Title level={4}>社区守则</Title>
<Paragraph>
<p>Flink 集群主要有两种,LOCAL 和 REMOTE,通过集群中心进行新集群的注册,注册成功后,点击心跳刷新状态,需要重新进入Studio后新集群才会被加载到下拉框。</p>
<p>LOCAL 模式为通过 dlink 自身环境和内存进行 FlinkSql 的执行。</p>
<p>REMOTE 模式会将 FlinkSql 进行解析处理后提交到目标集群进行执行。</p>
</Paragraph>
<Title level={4}>共享会话</Title>
<Paragraph>
<p>FlinkSql 执行过程所有创建的 Table 等都被存储到了共享会话的 Catalogue 中,不同集群间的 Catalogue 不共享。</p>
</Paragraph>
<Title level={4}>同步执行</Title>
<Paragraph>
<p>同步执行当前选项卡的 FlinkSql 在选中的集群上执行,执行完成后将数据结果展示在前端。</p>
</Paragraph>
<Title level={4}>异步提交</Title>
<Paragraph>
<p>异步提交当前选项卡或右键的树节点的 FlinkSql 在选中的集群上异步执行,无返回值,不记录历史。</p>
<p>1.禁止发布或讨论与本群主旨无关或不良的内容,一经发现立马被踢。</p>
<p>2.关于 Bug 反馈与功能改进或提议请通过 issue 进行,请阅读 issue 文档要求。</p>
<p>3.部署和使用前请先仔细阅读 Readme、公众号文章、官网文档、B站视频。</p>
<p>4.群提问题请礼貌并且说明【版本、执行模式、操作描述、截图】。</p>
<p>5.Issue 登记谁在使用 Dlink,可进入企业用户群提供技术支持。</p>
</Paragraph>
</Typography>
);
......
......@@ -4,7 +4,7 @@ import {
PauseCircleTwoTone, CarryOutTwoTone, DeleteTwoTone, PlayCircleTwoTone, CameraTwoTone, SnippetsTwoTone,
FileAddTwoTone, FolderOpenTwoTone, SafetyCertificateTwoTone, SaveTwoTone, FlagTwoTone, CodeTwoTone,
EnvironmentOutlined, SmileOutlined, RocketTwoTone, QuestionCircleTwoTone, MessageOutlined, ClusterOutlined
, EditTwoTone, RestTwoTone, ShrinkOutlined
, EditTwoTone, RestTwoTone, ShrinkOutlined, ApiTwoTone
} from "@ant-design/icons";
import Space from "antd/es/space";
import Divider from "antd/es/divider";
......@@ -14,6 +14,7 @@ import {StateType} from "@/pages/DataStudio/model";
import {connect} from "umi";
import {CODE, postDataArray} from "@/components/Common/crud";
import {executeSql, getJobPlan} from "@/pages/DataStudio/service";
import TaskAPI from "@/pages/API/TaskAPI";
import StudioHelp from "./StudioHelp";
import StudioGraph from "./StudioGraph";
import {
......@@ -456,6 +457,18 @@ const StudioMenu = (props: any) => {
return itemList;
};
const showAPI = () => {
Modal.info({
title: current.task.alias + ' API 手册',
width: 1000,
content: (
<TaskAPI task={current.task}/>
),
onOk() {
},
});
};
const showHelp = () => {
Modal.info({
title: '使用帮助',
......@@ -499,14 +512,12 @@ const StudioMenu = (props: any) => {
<Divider className={styles["ant-divider-horizontal-0"]}/>
<Col span={24}>
<Row>
<Col span={4}>
<Col span={16}>
<Breadcrumb className={styles["dw-path"]}>
<EnvironmentOutlined/>
<Divider type="vertical"/>
{getPathItem(currentPath)}
</Breadcrumb>
</Col>
<Col span={12}>
{currentSession.session &&
(
<Breadcrumb className={styles["dw-path"]}>
......@@ -645,6 +656,13 @@ const StudioMenu = (props: any) => {
/>
</Tooltip> : undefined
}
<Tooltip title="查看 API">
<Button
type="text"
icon={<ApiTwoTone />}
onClick={showAPI}
/>
</Tooltip>
<Tooltip title="查看使用帮助">
<Button
type="text"
......@@ -652,7 +670,13 @@ const StudioMenu = (props: any) => {
onClick={showHelp}
/>
</Tooltip>
</Col> : undefined}
</Col> : <Col span={8}><Tooltip title="查看使用帮助">
<Button
type="text"
icon={<QuestionCircleTwoTone/>}
onClick={showHelp}
/>
</Tooltip></Col>}
</Row>
</Col>
<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");
}
......@@ -378,6 +378,7 @@ const Model: ModelType = {
};
},
changeActiveKey(state, {payload}) {
payload = parseInt(payload);
const newTabs = state?.tabs;
let newCurrent = state?.current;
for (let i = 0; i < newTabs.panes.length; i++) {
......
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