Commit 3afbb1de authored by wenmo's avatar wenmo

StudioFlinkJobs

parent 36a5d11e
...@@ -106,4 +106,13 @@ public class StudioController { ...@@ -106,4 +106,13 @@ public class StudioController {
public Result listSession() { public Result listSession() {
return Result.succeed(studioService.listSession("admin"),"获取成功"); 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; ...@@ -8,8 +8,8 @@ import com.dlink.explainer.ca.TableCANode;
import com.dlink.job.JobResult; import com.dlink.job.JobResult;
import com.dlink.result.IResult; import com.dlink.result.IResult;
import com.dlink.result.SelectResult; import com.dlink.result.SelectResult;
import com.dlink.session.ExecutorEntity;
import com.dlink.session.SessionInfo; import com.dlink.session.SessionInfo;
import com.fasterxml.jackson.databind.JsonNode;
import java.util.List; import java.util.List;
...@@ -38,4 +38,6 @@ public interface StudioService { ...@@ -38,4 +38,6 @@ public interface StudioService {
List<TableCANode> getOneTableColumnCAByStatement(String statement); List<TableCANode> getOneTableColumnCAByStatement(String statement);
List<ColumnCANode> getColumnCAByStatement(String statement); List<ColumnCANode> getColumnCAByStatement(String statement);
List<JsonNode> listJobs(Integer clusterId);
} }
package com.dlink.service.impl; package com.dlink.service.impl;
import com.dlink.api.FlinkAPI;
import com.dlink.assertion.Asserts;
import com.dlink.dto.SessionDTO; import com.dlink.dto.SessionDTO;
import com.dlink.dto.StudioDDLDTO; import com.dlink.dto.StudioDDLDTO;
import com.dlink.dto.StudioExecuteDTO; import com.dlink.dto.StudioExecuteDTO;
...@@ -15,11 +17,11 @@ import com.dlink.result.IResult; ...@@ -15,11 +17,11 @@ import com.dlink.result.IResult;
import com.dlink.result.SelectResult; import com.dlink.result.SelectResult;
import com.dlink.service.ClusterService; import com.dlink.service.ClusterService;
import com.dlink.service.StudioService; import com.dlink.service.StudioService;
import com.dlink.session.ExecutorEntity;
import com.dlink.session.SessionConfig; import com.dlink.session.SessionConfig;
import com.dlink.session.SessionInfo; import com.dlink.session.SessionInfo;
import com.dlink.session.SessionPool; import com.dlink.session.SessionPool;
import com.dlink.trans.Operations; import com.dlink.trans.Operations;
import com.fasterxml.jackson.databind.JsonNode;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
...@@ -121,4 +123,11 @@ public class StudioServiceImpl implements StudioService { ...@@ -121,4 +123,11 @@ public class StudioServiceImpl implements StudioService {
return new ArrayList<>(); 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 @@ ...@@ -23,6 +23,14 @@
<groupId>com.dlink</groupId> <groupId>com.dlink</groupId>
<artifactId>dlink-common</artifactId> <artifactId>dlink-common</artifactId>
</dependency> </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> <dependency>
<groupId>cn.hutool</groupId> <groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId> <artifactId>hutool-all</artifactId>
......
...@@ -3,9 +3,9 @@ package com.dlink.api; ...@@ -3,9 +3,9 @@ package com.dlink.api;
import cn.hutool.http.HttpUtil; import cn.hutool.http.HttpUtil;
import com.dlink.constant.FlinkRestAPIConstant; import com.dlink.constant.FlinkRestAPIConstant;
import com.dlink.constant.NetConstant; import com.dlink.constant.NetConstant;
import org.apache.flink.shaded.jackson2.com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.core.JsonProcessingException;
import org.apache.flink.shaded.jackson2.com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.JsonNode;
import org.apache.flink.shaded.jackson2.com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.ObjectMapper;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
......
package com.dlink.core; package com.dlink.core;
import com.dlink.api.FlinkAPI; 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 org.junit.Test;
import java.util.List; import java.util.List;
...@@ -14,7 +14,7 @@ import java.util.List; ...@@ -14,7 +14,7 @@ import java.util.List;
**/ **/
public class FlinkRestAPITest { public class FlinkRestAPITest {
private String address = "127.0.0.1:8081"; private String address = "192.168.123.157:8081";
@Test @Test
public void selectTest(){ public void selectTest(){
List<JsonNode> jobs = FlinkAPI.build(address).listJobs(); 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"; ...@@ -9,6 +9,7 @@ import StudioTable from "./StudioTable";
import StudioHistory from "./StudioHistory"; import StudioHistory from "./StudioHistory";
import StudioFX from "./StudioFX"; import StudioFX from "./StudioFX";
import StudioCA from "./StudioCA"; import StudioCA from "./StudioCA";
import StudioProcess from "./StudioProcess";
const { TabPane } = Tabs; const { TabPane } = Tabs;
...@@ -71,7 +72,7 @@ const StudioConsole = (props:any) => { ...@@ -71,7 +72,7 @@ const StudioConsole = (props:any) => {
} }
key="StudioProcess" key="StudioProcess"
> >
<Empty image={Empty.PRESENTED_IMAGE_SIMPLE} /> <StudioProcess />
</TabPane> </TabPane>
<TabPane <TabPane
tab={ tab={
......
...@@ -120,3 +120,7 @@ export function showDataBase(dispatch: any) { ...@@ -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"; ...@@ -7,7 +7,7 @@ import {connect} from "umi";
import {useState} from "react"; import {useState} from "react";
import styles from "./index.less"; import styles from "./index.less";
import { import {
SearchOutlined, ReloadOutlined,
DownOutlined, DownOutlined,
DeleteOutlined, DeleteOutlined,
CommentOutlined, CommentOutlined,
...@@ -282,7 +282,7 @@ const StudioConnector = (props: any) => { ...@@ -282,7 +282,7 @@ const StudioConnector = (props: any) => {
<Tooltip title="刷新连接器"> <Tooltip title="刷新连接器">
<Button <Button
type="text" type="text"
icon={<SearchOutlined/>} icon={<ReloadOutlined/>}
onClick={getTables} onClick={getTables}
/> />
</Tooltip> </Tooltip>
......
import { import {
message, Input, Button, Space, Table, Dropdown, Menu, Empty, Divider, message, Button,Table, Empty, Divider,
Tooltip Tooltip
} from "antd"; } from "antd";
import {StateType} from "@/pages/FlinkSqlStudio/model"; import {StateType} from "@/pages/FlinkSqlStudio/model";
...@@ -7,11 +7,7 @@ import {connect} from "umi"; ...@@ -7,11 +7,7 @@ import {connect} from "umi";
import {useState} from "react"; import {useState} from "react";
import styles from "./index.less"; import styles from "./index.less";
import { import {
SearchOutlined, ReloadOutlined,
DownOutlined,
DeleteOutlined,
CommentOutlined,
PoweroffOutlined,
PlusOutlined PlusOutlined
} from '@ant-design/icons'; } from '@ant-design/icons';
import React from "react"; import React from "react";
...@@ -26,7 +22,7 @@ const StudioDataBase = (props: any) => { ...@@ -26,7 +22,7 @@ const StudioDataBase = (props: any) => {
const getColumns = () => { const getColumns = () => {
let columns: any = [{ let columns: any = [{
title: "名称", title: "数据源名",
dataIndex: "alias", dataIndex: "alias",
key: "alias", key: "alias",
sorter: true, sorter: true,
...@@ -75,7 +71,7 @@ const StudioDataBase = (props: any) => { ...@@ -75,7 +71,7 @@ const StudioDataBase = (props: any) => {
<Tooltip title="刷新数据源"> <Tooltip title="刷新数据源">
<Button <Button
type="text" type="text"
icon={<SearchOutlined/>} icon={<ReloadOutlined/>}
onClick={onRefreshDataBase} onClick={onRefreshDataBase}
/> />
</Tooltip> </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"; ...@@ -7,6 +7,8 @@ import StudioTree from "../StudioTree";
import StudioConnector from "./StudioConnector"; import StudioConnector from "./StudioConnector";
import React from "react"; import React from "react";
import StudioDataBase from "./StudioDataBase"; import StudioDataBase from "./StudioDataBase";
import StudioCluster from "./StudioCluster";
import StudioJobs from "./StudioJobs";
const { TabPane } = Tabs; const { TabPane } = Tabs;
...@@ -24,7 +26,7 @@ const StudioLeftTool = (props:any) => { ...@@ -24,7 +26,7 @@ const StudioLeftTool = (props:any) => {
<StudioConnector /> <StudioConnector />
</TabPane> </TabPane>
<TabPane tab={<span><ClusterOutlined /> 集群</span>} key="Cluster" > <TabPane tab={<span><ClusterOutlined /> 集群</span>} key="Cluster" >
<Empty image={Empty.PRESENTED_IMAGE_SIMPLE} /> <StudioCluster />
</TabPane> </TabPane>
<TabPane tab={<span><DatabaseOutlined /> 数据源</span>} key="DataSource" > <TabPane tab={<span><DatabaseOutlined /> 数据源</span>} key="DataSource" >
<StudioDataBase /> <StudioDataBase />
...@@ -33,7 +35,7 @@ const StudioLeftTool = (props:any) => { ...@@ -33,7 +35,7 @@ const StudioLeftTool = (props:any) => {
<Empty image={Empty.PRESENTED_IMAGE_SIMPLE} /> <Empty image={Empty.PRESENTED_IMAGE_SIMPLE} />
</TabPane> </TabPane>
<TabPane tab={<span><FireOutlined /> 任务</span>} key="FlinkTask" > <TabPane tab={<span><FireOutlined /> 任务</span>} key="FlinkTask" >
<Empty image={Empty.PRESENTED_IMAGE_SIMPLE} /> <StudioJobs />
</TabPane> </TabPane>
<TabPane tab={<span><FunctionOutlined /> 函数</span>} key="Function" > <TabPane tab={<span><FunctionOutlined /> 函数</span>} key="Function" >
<Empty image={Empty.PRESENTED_IMAGE_SIMPLE} /> <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