Commit 3afbb1de authored by wenmo's avatar wenmo

StudioFlinkJobs

parent 36a5d11e
......@@ -106,4 +106,13 @@ public class StudioController {
public Result listSession() {
return Result.succeed(studioService.listSession("admin"),"获取成功");
}
/**
* 获取session列表
*/
@GetMapping("/listJobs")
public Result listJobs(@RequestParam Integer clusterId) {
List<JsonNode> jobs = studioService.listJobs(clusterId);
return Result.succeed(jobs.toArray(),"获取成功");
}
}
......@@ -8,8 +8,8 @@ import com.dlink.explainer.ca.TableCANode;
import com.dlink.job.JobResult;
import com.dlink.result.IResult;
import com.dlink.result.SelectResult;
import com.dlink.session.ExecutorEntity;
import com.dlink.session.SessionInfo;
import com.fasterxml.jackson.databind.JsonNode;
import java.util.List;
......@@ -38,4 +38,6 @@ public interface StudioService {
List<TableCANode> getOneTableColumnCAByStatement(String statement);
List<ColumnCANode> getColumnCAByStatement(String statement);
List<JsonNode> listJobs(Integer clusterId);
}
package com.dlink.service.impl;
import com.dlink.api.FlinkAPI;
import com.dlink.assertion.Asserts;
import com.dlink.dto.SessionDTO;
import com.dlink.dto.StudioDDLDTO;
import com.dlink.dto.StudioExecuteDTO;
......@@ -15,11 +17,11 @@ import com.dlink.result.IResult;
import com.dlink.result.SelectResult;
import com.dlink.service.ClusterService;
import com.dlink.service.StudioService;
import com.dlink.session.ExecutorEntity;
import com.dlink.session.SessionConfig;
import com.dlink.session.SessionInfo;
import com.dlink.session.SessionPool;
import com.dlink.trans.Operations;
import com.fasterxml.jackson.databind.JsonNode;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
......@@ -121,4 +123,11 @@ public class StudioServiceImpl implements StudioService {
return new ArrayList<>();
}
}
@Override
public List<JsonNode> listJobs(Integer clusterId) {
Cluster cluster = clusterService.getById(clusterId);
Asserts.checkNotNull(cluster,"该集群不存在");
return FlinkAPI.build(cluster.getJobManagerHost()).listJobs();
}
}
......@@ -23,6 +23,14 @@
<groupId>com.dlink</groupId>
<artifactId>dlink-common</artifactId>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-annotations</artifactId>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
</dependency>
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
......
......@@ -3,9 +3,9 @@ package com.dlink.api;
import cn.hutool.http.HttpUtil;
import com.dlink.constant.FlinkRestAPIConstant;
import com.dlink.constant.NetConstant;
import org.apache.flink.shaded.jackson2.com.fasterxml.jackson.core.JsonProcessingException;
import org.apache.flink.shaded.jackson2.com.fasterxml.jackson.databind.JsonNode;
import org.apache.flink.shaded.jackson2.com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import java.util.ArrayList;
import java.util.List;
......
package com.dlink.core;
import com.dlink.api.FlinkAPI;
import org.apache.flink.shaded.jackson2.com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.JsonNode;
import org.junit.Test;
import java.util.List;
......@@ -14,7 +14,7 @@ import java.util.List;
**/
public class FlinkRestAPITest {
private String address = "127.0.0.1:8081";
private String address = "192.168.123.157:8081";
@Test
public void selectTest(){
List<JsonNode> jobs = FlinkAPI.build(address).listJobs();
......
import {Input, Tag, Divider, Empty, message, Select} from "antd";
import {StateType} from "@/pages/FlinkSqlStudio/model";
import {connect} from "umi";
import {useState} from "react";
import { SearchOutlined } from '@ant-design/icons';
import ProTable from '@ant-design/pro-table';
import {showFlinkJobs} from "../../StudioEvent/DDL";
const { Option } = Select;
const StudioProcess = (props:any) => {
const {cluster} = props;
const [jobsData, setJobsData] = useState<any>({});
const getColumns=()=>{
let columns: any = [{
title: "JobId",
dataIndex: "id",
key: "id",
sorter: true,
},{
title: "status",
dataIndex: "status",
sorter: true,
}, {
title: '操作',
dataIndex: 'option',
valueType: 'option',
render: (_, record) => [
<a
onClick={() => {
message.success('敬请期待');
}}
>
详情
</a>, <Divider type="vertical"/>, <a
onClick={() => {
message.success('敬请期待');
}}
>
停止
</a>
],
},];
return columns;
};
const getClusterOptions = ()=>{
let itemList = [];
for(let item of cluster){
let tag =(<><Tag color={item.enabled?"processing":"error"}>{item.type}</Tag>{item.alias}</>);
itemList.push(<Option value={item.id} label={tag}>
{tag}
</Option>)
}
return itemList;
};
const onChangeCluster= (value:number)=>{
let res = showFlinkJobs(value);
res.then((result) => {
setJobsData(result.datas);
});
};
return (
<div style={{width: '100%'}}>
<Select
style={{ width: '100%' }}
placeholder="选择Flink集群"
optionLabelProp="label"
onChange={onChangeCluster}
>
{getClusterOptions()}
</Select>
{jobsData.length>0?
(<ProTable dataSource={jobsData} columns={getColumns()} search={false}
/>):(<Empty image={Empty.PRESENTED_IMAGE_SIMPLE} />)}
</div>
);
};
export default connect(({ Studio }: { Studio: StateType }) => ({
cluster: Studio.cluster,
}))(StudioProcess);
......@@ -9,6 +9,7 @@ import StudioTable from "./StudioTable";
import StudioHistory from "./StudioHistory";
import StudioFX from "./StudioFX";
import StudioCA from "./StudioCA";
import StudioProcess from "./StudioProcess";
const { TabPane } = Tabs;
......@@ -71,7 +72,7 @@ const StudioConsole = (props:any) => {
}
key="StudioProcess"
>
<Empty image={Empty.PRESENTED_IMAGE_SIMPLE} />
<StudioProcess />
</TabPane>
<TabPane
tab={
......
......@@ -120,3 +120,7 @@ export function showDataBase(dispatch: any) {
});
});
}
/*--- 刷新 Flink Jobs ---*/
export function showFlinkJobs(clusterId:number) {
return getData('api/studio/listJobs',{clusterId:clusterId});
}
import {
message, Button, Table, Empty, Divider,
Tooltip
} from "antd";
import {StateType} from "@/pages/FlinkSqlStudio/model";
import {connect} from "umi";
import {useState} from "react";
import styles from "./index.less";
import {
ReloadOutlined,
PlusOutlined
} from '@ant-design/icons';
import React from "react";
import {showCluster} from "../../StudioEvent/DDL";
const StudioCluster = (props: any) => {
const {cluster, dispatch} = props;
const getColumns = () => {
let columns: any = [{
title: "集群名",
dataIndex: "alias",
key: "alias",
sorter: true,
}, {
title: '操作',
dataIndex: 'option',
valueType: 'option',
render: (_, record) => [
<a
onClick={() => {
message.success('敬请期待');
}}
>
详情
</a>, <Divider type="vertical"/>, <a
onClick={() => {
message.success('敬请期待');
}}
>
管理
</a>
],
},];
return columns;
};
const onRefreshCluster = () => {
showCluster(dispatch);
};
const onCreateCluster = () => {
};
return (
<>
<Tooltip title="新建 Flink 集群">
<Button
type="text"
icon={<PlusOutlined/>}
onClick={onCreateCluster}
/>
</Tooltip>
<div style={{float: "right"}}>
<Tooltip title="刷新 Flink 集群">
<Button
type="text"
icon={<ReloadOutlined />}
onClick={onRefreshCluster}
/>
</Tooltip>
</div>
{cluster.length > 0 ? (
<Table dataSource={cluster} columns={getColumns()} size="small"/>) : (
<Empty image={Empty.PRESENTED_IMAGE_SIMPLE}/>)}
</>
);
};
export default connect(({Studio}: { Studio: StateType }) => ({
cluster: Studio.cluster,
}))(StudioCluster);
......@@ -7,7 +7,7 @@ import {connect} from "umi";
import {useState} from "react";
import styles from "./index.less";
import {
SearchOutlined,
ReloadOutlined,
DownOutlined,
DeleteOutlined,
CommentOutlined,
......@@ -282,7 +282,7 @@ const StudioConnector = (props: any) => {
<Tooltip title="刷新连接器">
<Button
type="text"
icon={<SearchOutlined/>}
icon={<ReloadOutlined/>}
onClick={getTables}
/>
</Tooltip>
......
import {
message, Input, Button, Space, Table, Dropdown, Menu, Empty, Divider,
message, Button,Table, Empty, Divider,
Tooltip
} from "antd";
import {StateType} from "@/pages/FlinkSqlStudio/model";
......@@ -7,11 +7,7 @@ import {connect} from "umi";
import {useState} from "react";
import styles from "./index.less";
import {
SearchOutlined,
DownOutlined,
DeleteOutlined,
CommentOutlined,
PoweroffOutlined,
ReloadOutlined,
PlusOutlined
} from '@ant-design/icons';
import React from "react";
......@@ -26,7 +22,7 @@ const StudioDataBase = (props: any) => {
const getColumns = () => {
let columns: any = [{
title: "名称",
title: "数据源名",
dataIndex: "alias",
key: "alias",
sorter: true,
......@@ -75,7 +71,7 @@ const StudioDataBase = (props: any) => {
<Tooltip title="刷新数据源">
<Button
type="text"
icon={<SearchOutlined/>}
icon={<ReloadOutlined/>}
onClick={onRefreshDataBase}
/>
</Tooltip>
......
import {Table, Tag, Divider, Empty, message, Select} from "antd";
import {StateType} from "@/pages/FlinkSqlStudio/model";
import {connect} from "umi";
import {useState} from "react";
import { SearchOutlined } from '@ant-design/icons';
import {showFlinkJobs} from "../../StudioEvent/DDL";
const { Option } = Select;
const StudioJobs = (props:any) => {
const {cluster} = props;
const [jobsData, setJobsData] = useState<any>({});
const getColumns=()=>{
let columns: any = [{
title: "JobId",
dataIndex: "id",
key: "id",
sorter: true,
},{
title: "status",
dataIndex: "status",
sorter: true,
}, {
title: '操作',
dataIndex: 'option',
valueType: 'option',
render: (_, record) => [
<a
onClick={() => {
message.success('敬请期待');
}}
>
详情
</a>, <Divider type="vertical"/>, <a
onClick={() => {
message.success('敬请期待');
}}
>
停止
</a>
],
},];
return columns;
};
const getClusterOptions = ()=>{
let itemList = [];
for(let item of cluster){
let tag =(<><Tag color={item.enabled?"processing":"error"}>{item.type}</Tag>{item.alias}</>);
itemList.push(<Option value={item.id} label={tag}>
{tag}
</Option>)
}
return itemList;
};
const onChangeCluster= (value:number)=>{
let res = showFlinkJobs(value);
res.then((result) => {
setJobsData(result.datas);
});
};
return (
<>
<Select
style={{ width: '100%' }}
placeholder="选择Flink集群"
optionLabelProp="label"
onChange={onChangeCluster}
>
{getClusterOptions()}
</Select>
{jobsData.length>0?
(<Table dataSource={jobsData} columns={getColumns()}
/>):(<Empty image={Empty.PRESENTED_IMAGE_SIMPLE} />)}
</>
);
};
export default connect(({ Studio }: { Studio: StateType }) => ({
cluster: Studio.cluster,
}))(StudioJobs);
......@@ -7,6 +7,8 @@ import StudioTree from "../StudioTree";
import StudioConnector from "./StudioConnector";
import React from "react";
import StudioDataBase from "./StudioDataBase";
import StudioCluster from "./StudioCluster";
import StudioJobs from "./StudioJobs";
const { TabPane } = Tabs;
......@@ -24,7 +26,7 @@ const StudioLeftTool = (props:any) => {
<StudioConnector />
</TabPane>
<TabPane tab={<span><ClusterOutlined /> 集群</span>} key="Cluster" >
<Empty image={Empty.PRESENTED_IMAGE_SIMPLE} />
<StudioCluster />
</TabPane>
<TabPane tab={<span><DatabaseOutlined /> 数据源</span>} key="DataSource" >
<StudioDataBase />
......@@ -33,7 +35,7 @@ const StudioLeftTool = (props:any) => {
<Empty image={Empty.PRESENTED_IMAGE_SIMPLE} />
</TabPane>
<TabPane tab={<span><FireOutlined /> 任务</span>} key="FlinkTask" >
<Empty image={Empty.PRESENTED_IMAGE_SIMPLE} />
<StudioJobs />
</TabPane>
<TabPane tab={<span><FunctionOutlined /> 函数</span>} key="Function" >
<Empty image={Empty.PRESENTED_IMAGE_SIMPLE} />
......
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