Commit a82923c7 authored by wenmo's avatar wenmo

任务监控的savepoint等操作

parent 6fd1a0fe
...@@ -153,7 +153,7 @@ public class StudioController { ...@@ -153,7 +153,7 @@ public class StudioController {
*/ */
@GetMapping("/savepoint") @GetMapping("/savepoint")
public Result savepoint(@RequestParam Integer clusterId,@RequestParam String jobId, public Result savepoint(@RequestParam Integer clusterId,@RequestParam String jobId,
@RequestParam String savePointType,@RequestParam String name) { @RequestParam String savePointType,@RequestParam String name,@RequestParam Integer taskId) {
return Result.succeed(studioService.savepoint(clusterId,jobId,savePointType,name),"savepoint 成功"); return Result.succeed(studioService.savepoint(taskId,clusterId,jobId,savePointType,name),"savepoint 成功");
} }
} }
...@@ -12,7 +12,6 @@ public class JobInfoDetail { ...@@ -12,7 +12,6 @@ public class JobInfoDetail {
private JobInstance instance; private JobInstance instance;
private Cluster cluster; private Cluster cluster;
private ClusterConfiguration clusterConfiguration; private ClusterConfiguration clusterConfiguration;
private Task task;
private History history; private History history;
private JobHistory jobHistory; private JobHistory jobHistory;
...@@ -52,14 +51,6 @@ public class JobInfoDetail { ...@@ -52,14 +51,6 @@ public class JobInfoDetail {
this.clusterConfiguration = clusterConfiguration; this.clusterConfiguration = clusterConfiguration;
} }
public Task getTask() {
return task;
}
public void setTask(Task task) {
this.task = task;
}
public History getHistory() { public History getHistory() {
return history; return history;
} }
......
...@@ -13,19 +13,17 @@ public class JobInstanceStatus { ...@@ -13,19 +13,17 @@ public class JobInstanceStatus {
private Integer finished = 0; private Integer finished = 0;
private Integer failed = 0; private Integer failed = 0;
private Integer canceled = 0; private Integer canceled = 0;
private Integer restarting = 0;
private Integer created = 0;
private Integer failing = 0;
private Integer cancelling = 0;
private Integer suspended = 0;
private Integer reconciling = 0;
private Integer unknown = 0;
public JobInstanceStatus() { public JobInstanceStatus() {
} }
public JobInstanceStatus(Integer all, Integer initializing, Integer running, Integer finished, Integer failed, Integer canceled) {
this.all = all;
this.initializing = initializing;
this.running = running;
this.finished = finished;
this.failed = failed;
this.canceled = canceled;
}
public Integer getAll() { public Integer getAll() {
return all; return all;
} }
...@@ -73,4 +71,60 @@ public class JobInstanceStatus { ...@@ -73,4 +71,60 @@ public class JobInstanceStatus {
public void setCanceled(Integer canceled) { public void setCanceled(Integer canceled) {
this.canceled = canceled; this.canceled = canceled;
} }
public Integer getRestarting() {
return restarting;
}
public void setRestarting(Integer restarting) {
this.restarting = restarting;
}
public Integer getCreated() {
return created;
}
public void setCreated(Integer created) {
this.created = created;
}
public Integer getFailing() {
return failing;
}
public void setFailing(Integer failing) {
this.failing = failing;
}
public Integer getCancelling() {
return cancelling;
}
public void setCancelling(Integer cancelling) {
this.cancelling = cancelling;
}
public Integer getSuspended() {
return suspended;
}
public void setSuspended(Integer suspended) {
this.suspended = suspended;
}
public Integer getReconciling() {
return reconciling;
}
public void setReconciling(Integer reconciling) {
this.reconciling = reconciling;
}
public Integer getUnknown() {
return unknown;
}
public void setUnknown(Integer unknown) {
this.unknown = unknown;
}
} }
...@@ -54,5 +54,5 @@ public interface StudioService { ...@@ -54,5 +54,5 @@ public interface StudioService {
boolean cancel(Integer clusterId,String jobId); boolean cancel(Integer clusterId,String jobId);
boolean savepoint(Integer clusterId,String jobId,String savePointType,String name); boolean savepoint(Integer taskId,Integer clusterId,String jobId,String savePointType,String name);
} }
...@@ -67,6 +67,27 @@ public class JobInstanceServiceImpl extends SuperServiceImpl<JobInstanceMapper, ...@@ -67,6 +67,27 @@ public class JobInstanceServiceImpl extends SuperServiceImpl<JobInstanceMapper,
break; break;
case CANCELED: case CANCELED:
jobInstanceStatus.setCanceled(counts); jobInstanceStatus.setCanceled(counts);
break;
case RESTARTING:
jobInstanceStatus.setRestarting(counts);
break;
case CREATED:
jobInstanceStatus.setCreated(counts);
break;
case FAILING:
jobInstanceStatus.setFailed(counts);
break;
case CANCELLING:
jobInstanceStatus.setCancelling(counts);
break;
case SUSPENDED:
jobInstanceStatus.setSuspended(counts);
break;
case RECONCILING:
jobInstanceStatus.setReconciling(counts);
break;
case UNKNOWN:
jobInstanceStatus.setUnknown(counts);
} }
} }
jobInstanceStatus.setAll(total); jobInstanceStatus.setAll(total);
...@@ -83,7 +104,6 @@ public class JobInstanceServiceImpl extends SuperServiceImpl<JobInstanceMapper, ...@@ -83,7 +104,6 @@ public class JobInstanceServiceImpl extends SuperServiceImpl<JobInstanceMapper,
Asserts.checkNull(jobInstance, "该任务实例不存在"); Asserts.checkNull(jobInstance, "该任务实例不存在");
JobInfoDetail jobInfoDetail = new JobInfoDetail(jobInstance.getId()); JobInfoDetail jobInfoDetail = new JobInfoDetail(jobInstance.getId());
jobInfoDetail.setInstance(jobInstance); jobInfoDetail.setInstance(jobInstance);
jobInfoDetail.setTask(taskService.getTaskInfoById(jobInstance.getTaskId()));
jobInfoDetail.setCluster(clusterService.getById(jobInstance.getClusterId())); jobInfoDetail.setCluster(clusterService.getById(jobInstance.getClusterId()));
jobInfoDetail.setJobHistory(jobHistoryService.getJobHistory(jobInstance.getId())); jobInfoDetail.setJobHistory(jobHistoryService.getJobHistory(jobInstance.getId()));
History history = historyService.getById(jobInstance.getHistoryId()); History history = historyService.getById(jobInstance.getHistoryId());
...@@ -105,6 +125,11 @@ public class JobInstanceServiceImpl extends SuperServiceImpl<JobInstanceMapper, ...@@ -105,6 +125,11 @@ public class JobInstanceServiceImpl extends SuperServiceImpl<JobInstanceMapper,
Cluster cluster = clusterService.getById(jobInstance.getClusterId()); Cluster cluster = clusterService.getById(jobInstance.getClusterId());
JobHistory jobHistoryJson = jobHistoryService.refreshJobHistory(id, cluster.getJobManagerHost(), jobInstance.getJid()); JobHistory jobHistoryJson = jobHistoryService.refreshJobHistory(id, cluster.getJobManagerHost(), jobInstance.getJid());
JobHistory jobHistory = jobHistoryService.getJobHistoryInfo(jobHistoryJson); JobHistory jobHistory = jobHistoryService.getJobHistoryInfo(jobHistoryJson);
if(jobHistory.getJob().has(FlinkRestResultConstant.ERRORS)){
jobInstance.setStatus(JobStatus.UNKNOWN.getValue());
updateById(jobInstance);
return jobInstance;
}
jobInstance.setDuration(jobHistory.getJob().get(FlinkRestResultConstant.JOB_DURATION).asLong()/1000); jobInstance.setDuration(jobHistory.getJob().get(FlinkRestResultConstant.JOB_DURATION).asLong()/1000);
jobInstance.setStatus(jobHistory.getJob().get(FlinkRestResultConstant.JOB_STATE).asText()); jobInstance.setStatus(jobHistory.getJob().get(FlinkRestResultConstant.JOB_STATE).asText());
updateById(jobInstance); updateById(jobInstance);
......
...@@ -295,9 +295,10 @@ public class StudioServiceImpl implements StudioService { ...@@ -295,9 +295,10 @@ public class StudioServiceImpl implements StudioService {
} }
@Override @Override
public boolean savepoint(Integer clusterId, String jobId, String savePointType, String name) { public boolean savepoint(Integer taskId, Integer clusterId, String jobId, String savePointType, String name) {
Cluster cluster = clusterService.getById(clusterId); Cluster cluster = clusterService.getById(clusterId);
Asserts.checkNotNull(cluster, "该集群不存在"); Asserts.checkNotNull(cluster, "该集群不存在");
boolean useGateway = false;
JobConfig jobConfig = new JobConfig(); JobConfig jobConfig = new JobConfig();
jobConfig.setAddress(cluster.getJobManagerHost()); jobConfig.setAddress(cluster.getJobManagerHost());
jobConfig.setType(cluster.getType()); jobConfig.setType(cluster.getType());
...@@ -306,18 +307,21 @@ public class StudioServiceImpl implements StudioService { ...@@ -306,18 +307,21 @@ public class StudioServiceImpl implements StudioService {
jobConfig.buildGatewayConfig(gatewayConfig); jobConfig.buildGatewayConfig(gatewayConfig);
jobConfig.getGatewayConfig().getClusterConfig().setAppId(cluster.getName()); jobConfig.getGatewayConfig().getClusterConfig().setAppId(cluster.getName());
jobConfig.setTaskId(cluster.getTaskId()); jobConfig.setTaskId(cluster.getTaskId());
useGateway = true;
}else {
jobConfig.setTaskId(taskId);
} }
JobManager jobManager = JobManager.build(jobConfig); JobManager jobManager = JobManager.build(jobConfig);
jobManager.setUseGateway(true); jobManager.setUseGateway(useGateway);
SavePointResult savePointResult = jobManager.savepoint(jobId, savePointType, null); SavePointResult savePointResult = jobManager.savepoint(jobId, savePointType, null);
if (Asserts.isNotNull(savePointResult)) { if (Asserts.isNotNull(savePointResult)) {
for (JobInfo item : savePointResult.getJobInfos()) { for (JobInfo item : savePointResult.getJobInfos()) {
if (Asserts.isEqualsIgnoreCase(jobId, item.getJobId())) { if (Asserts.isEqualsIgnoreCase(jobId, item.getJobId())&&Asserts.isNotNull(jobConfig.getTaskId())) {
Savepoints savepoints = new Savepoints(); Savepoints savepoints = new Savepoints();
savepoints.setName(name); savepoints.setName(name);
savepoints.setType(savePointType); savepoints.setType(savePointType);
savepoints.setPath(item.getSavePoint()); savepoints.setPath(item.getSavePoint());
savepoints.setTaskId(cluster.getTaskId()); savepoints.setTaskId(jobConfig.getTaskId());
savepointsService.save(savepoints); savepointsService.save(savepoints);
} }
} }
......
...@@ -3,6 +3,7 @@ package com.dlink.utils; ...@@ -3,6 +3,7 @@ package com.dlink.utils;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import java.io.IOException;
import java.io.PrintWriter; import java.io.PrintWriter;
import java.io.StringWriter; import java.io.StringWriter;
import java.time.LocalDateTime; import java.time.LocalDateTime;
...@@ -19,22 +20,32 @@ public class LogUtil { ...@@ -19,22 +20,32 @@ public class LogUtil {
public static String getError(Exception e){ public static String getError(Exception e){
// e.printStackTrace(); // e.printStackTrace();
StringWriter sw = new StringWriter(); String error = null;
PrintWriter pw = new PrintWriter(sw); try(StringWriter sw = new StringWriter();
e.printStackTrace(pw); PrintWriter pw = new PrintWriter(sw)){
String error = sw.toString(); e.printStackTrace(pw);
logger.error(sw.toString()); error = sw.toString();
return error; logger.error(error);
} catch (IOException ioe) {
ioe.printStackTrace();
}finally {
return error;
}
} }
public static String getError(String msg,Exception e){ public static String getError(String msg,Exception e){
// e.printStackTrace(); // e.printStackTrace();
StringWriter sw = new StringWriter(); String error = null;
PrintWriter pw = new PrintWriter(sw); try(StringWriter sw = new StringWriter();
e.printStackTrace(pw); PrintWriter pw = new PrintWriter(sw)){
LocalDateTime now = LocalDateTime.now(); e.printStackTrace(pw);
String error = now.toString() + ": " + msg + " \nError message:\n " + sw.toString(); LocalDateTime now = LocalDateTime.now();
logger.error(error); error = now.toString() + ": " + msg + " \nError message:\n " + sw.toString();
return error; logger.error(error);
} catch (IOException ioe) {
ioe.printStackTrace();
}finally {
return error;
}
} }
} }
...@@ -8,6 +8,7 @@ package com.dlink.constant; ...@@ -8,6 +8,7 @@ package com.dlink.constant;
**/ **/
public final class FlinkRestResultConstant { public final class FlinkRestResultConstant {
public static final String ERRORS = "errors";
public static final String JOB_DURATION = "duration"; public static final String JOB_DURATION = "duration";
public static final String JOB_STATE = "state"; public static final String JOB_STATE = "state";
......
...@@ -12,22 +12,51 @@ export type JobStatusFormProps = { ...@@ -12,22 +12,51 @@ export type JobStatusFormProps = {
status: string|undefined; status: string|undefined;
}; };
export const JOB_STATUS = {
FINISHED:'FINISHED',
RUNNING:'RUNNING',
FAILED:'FAILED',
CANCELED:'CANCELED',
INITIALIZING:'INITIALIZING',
RESTARTING:'RESTARTING',
CREATED:'CREATED',
FAILING:'FAILING',
SUSPENDED:'SUSPENDED',
CANCELLING:'CANCELLING',
UNKNOWN:'UNKNOWN',
};
export function isStatusDone(type: string){
if(!type){
return true;
}
switch (type) {
case JOB_STATUS.FAILED:
case JOB_STATUS.CANCELED:
case JOB_STATUS.FINISHED:
case JOB_STATUS.UNKNOWN:
return true;
default:
return false;
}
};
const JobStatus = (props: JobStatusFormProps) => { const JobStatus = (props: JobStatusFormProps) => {
const {status} = props; const {status} = props;
return (<> return (<>
{ (status === 'FINISHED') ? { (status === 'FINISHED') ?
(<Tag icon={<CheckCircleOutlined/>} color="success"> (<Tag icon={<CheckCircleOutlined/>} color="blue">
FINISHED FINISHED
</Tag>) : (status === 'RUNNING') ? </Tag>) : (status === 'RUNNING') ?
(<Tag icon={<SyncOutlined spin/>} color="processing"> (<Tag icon={<SyncOutlined spin/>} color="green">
RUNNING RUNNING
</Tag>) : (status === 'FAILED') ? </Tag>) : (status === 'FAILED') ?
(<Tag icon={<CloseCircleOutlined/>} color="error"> (<Tag icon={<CloseCircleOutlined/>} color="error">
FAILED FAILED
</Tag>) : (status === 'CANCELED') ? </Tag>) : (status === 'CANCELED') ?
(<Tag icon={<MinusCircleOutlined/>} color="default"> (<Tag icon={<MinusCircleOutlined/>} color="orange">
CANCELED CANCELED
</Tag>) : (status === 'INITIALIZING') ? </Tag>) : (status === 'INITIALIZING') ?
(<Tag icon={<ClockCircleOutlined/>} color="default"> (<Tag icon={<ClockCircleOutlined/>} color="default">
......
...@@ -187,8 +187,8 @@ export function cancelJob(clusterId:number,jobId:string) { ...@@ -187,8 +187,8 @@ export function cancelJob(clusterId:number,jobId:string) {
return getData('api/studio/cancel',{clusterId:clusterId,jobId:jobId}); return getData('api/studio/cancel',{clusterId:clusterId,jobId:jobId});
} }
/*--- 停止 SavePoint Jobs ---*/ /*--- 停止 SavePoint Jobs ---*/
export function savepointJob(clusterId:number,jobId:string,savePointType:string,name:string) { export function savepointJob(clusterId:number,jobId:string,savePointType:string,name:string,taskId:number) {
return getData('api/studio/savepoint',{clusterId,jobId,savePointType,name}); return getData('api/studio/savepoint',{clusterId,jobId,savePointType,name,taskId});
} }
/*--- 根据版本号获取所有自动补全的文档 ---*/ /*--- 根据版本号获取所有自动补全的文档 ---*/
export function getFillAllByVersion(version:string,dispatch: any) { export function getFillAllByVersion(version:string,dispatch: any) {
......
...@@ -3,7 +3,7 @@ import { ...@@ -3,7 +3,7 @@ import {
RocketOutlined RocketOutlined
} from '@ant-design/icons'; } from '@ant-design/icons';
const {Link} = Typography; const {Text, Link} = Typography;
const Config = (props: any) => { const Config = (props: any) => {
...@@ -28,10 +28,22 @@ const Config = (props: any) => { ...@@ -28,10 +28,22 @@ const Config = (props: any) => {
</Descriptions.Item> </Descriptions.Item>
<Descriptions.Item label="片段机制">{job?.history?.config.useSqlFragment?'启用':'禁用'}</Descriptions.Item> <Descriptions.Item label="片段机制">{job?.history?.config.useSqlFragment?'启用':'禁用'}</Descriptions.Item>
<Descriptions.Item label="语句集">{job?.history?.config.useStatementSet?'启用':'禁用'}</Descriptions.Item> <Descriptions.Item label="语句集">{job?.history?.config.useStatementSet?'启用':'禁用'}</Descriptions.Item>
<Descriptions.Item label="任务类型">{job?.history?.config.isJarTask?'Jar':'FlinkSQL'}</Descriptions.Item>
<Descriptions.Item label="批模式">{job?.history?.config.useBatchModel?'启用':'禁用'}</Descriptions.Item> <Descriptions.Item label="批模式">{job?.history?.config.useBatchModel?'启用':'禁用'}</Descriptions.Item>
<Descriptions.Item label="CheckPoint">{job?.history?.config.checkpoint}</Descriptions.Item>
<Descriptions.Item label="SavePoint机制"> <Descriptions.Item label="SavePoint机制">
{job?.history?.config.savePointStrategy?'启用':'禁用'} {job?.history?.config.savePointStrategy=='NONE'?'禁用':
job?.history?.config.savePointStrategy=='LATEST'?'最近一次':
job?.history?.config.savePointStrategy=='EARLIEST'?'最早一次':
job?.history?.config.savePointStrategy=='CUSTOM'?'指定一次':'禁用'}
</Descriptions.Item> </Descriptions.Item>
<Descriptions.Item label="SavePoint" span={2}>{job?.history?.config.savePointPath}</Descriptions.Item>
<Descriptions.Item label="Flink Configuration" span={3}><Text code>{JSON.stringify(job?.history?.config.config)}</Text></Descriptions.Item>
{job?.jar?<>
<Descriptions.Item label="Jar 路径">{job?.jar?.path}</Descriptions.Item>
<Descriptions.Item label="Jar 主类">{job?.jar?.mainClass}</Descriptions.Item>
<Descriptions.Item label="Jar 入参">{job?.jar?.paras}</Descriptions.Item>
</>:undefined}
</Descriptions> </Descriptions>
</>) </>)
}; };
......
...@@ -4,7 +4,7 @@ import { ...@@ -4,7 +4,7 @@ import {
EllipsisOutlined, RedoOutlined, EllipsisOutlined, RedoOutlined,
FireOutlined, ClusterOutlined, RocketOutlined FireOutlined, ClusterOutlined, RocketOutlined
} from '@ant-design/icons'; } from '@ant-design/icons';
import {Button, Dropdown, Menu, Tag, Space, Typography} from 'antd'; import {Button, Dropdown, Menu, Tag, Space, Typography, message, Modal} from 'antd';
import {PageContainer} from '@ant-design/pro-layout'; import {PageContainer} from '@ant-design/pro-layout';
import ProCard from '@ant-design/pro-card'; import ProCard from '@ant-design/pro-card';
import {JobInfoDetail} from "@/pages/DevOps/data"; import {JobInfoDetail} from "@/pages/DevOps/data";
...@@ -12,7 +12,8 @@ import {getJobInfoDetail, refreshJobInfoDetail} from "@/pages/DevOps/service"; ...@@ -12,7 +12,8 @@ import {getJobInfoDetail, refreshJobInfoDetail} from "@/pages/DevOps/service";
import moment from "moment"; import moment from "moment";
import BaseInfo from "@/pages/DevOps/JobInfo/BaseInfo"; import BaseInfo from "@/pages/DevOps/JobInfo/BaseInfo";
import Config from "@/pages/DevOps/JobInfo/Config"; import Config from "@/pages/DevOps/JobInfo/Config";
import JobStatus from "@/components/Common/JobStatus"; import JobStatus, {isStatusDone} from "@/components/Common/JobStatus";
import {cancelJob, savepointJob} from "@/components/Studio/StudioEvent/DDL";
const {Link} = Typography; const {Link} = Typography;
...@@ -53,36 +54,88 @@ const JobInfo = (props: any) => { ...@@ -53,36 +54,88 @@ const JobInfo = (props: any) => {
history.goBack(); history.goBack();
}; };
const handleSavepoint = (key: string) => {
if(key=='canceljob'){
Modal.confirm({
title: '停止任务',
content: `确定只停止该作业,不进行 SavePoint 操作吗?`,
okText: '确认',
cancelText: '取消',
onOk: async () => {
if (!job?.cluster?.id) return;
const res = cancelJob(job?.cluster?.id, job?.instance?.jid);
res.then((result) => {
if (result.datas == true) {
message.success(key+"成功");
handleGetJobInfoDetail();
} else {
message.error(key+"失败");
}
});
}
});
return;
}
Modal.confirm({
title: key+'任务',
content: `确定${key}该作业吗?`,
okText: '确认',
cancelText: '取消',
onOk: async () => {
if (!job?.cluster?.id) return;
const res = savepointJob(job?.cluster?.id, job?.instance?.jid,key,key,job?.instance?.taskId);
res.then((result) => {
if (result.datas == true) {
message.success(key+"成功");
handleGetJobInfoDetail();
} else {
message.error(key+"失败");
}
});
}
});
};
const getButtons = () => {
let buttons = [
<Button key="back" type="dashed" onClick={handleBack}>返回</Button>,
];
if(!isStatusDone(job?.instance?.status as string)){
buttons.push(<Button key="refresh" icon={<RedoOutlined/>} onClick={handleRefreshJobInfoDetail}/>);
buttons.push(<Button key="flinkwebui">
<Link href={`http://${job?.history?.jobManagerAddress}/#/job/${job?.instance?.jid}/overview`} target="_blank">
FlinkWebUI
</Link></Button>);
}
buttons.push(<Button key="autorestart" type="primary">智能重启</Button>);
if(!isStatusDone(job?.instance?.status as string)){
buttons.push(<Button key="autostop" type="primary" danger onClick={()=>{handleSavepoint('cancel')}}>智能停止</Button>);
buttons.push(<Dropdown
key="dropdown"
trigger={['click']}
overlay={
<Menu onClick={({key}) => handleSavepoint(key)}>
<Menu.Item key="trigger">SavePoint触发</Menu.Item>
<Menu.Item key="stop">SavePoint暂停</Menu.Item>
<Menu.Item key="cancel">SavePoint停止</Menu.Item>
<Menu.Item key="canceljob">普通停止</Menu.Item>
</Menu>
}
>
<Button key="4" style={{padding: '0 8px'}}>
<EllipsisOutlined/>
</Button>
</Dropdown>);
}
return buttons;
}
return ( return (
<PageContainer <PageContainer
header={{ header={{
title: `${job?.instance?.name}`, title: `${job?.instance?.name}`,
ghost: true, ghost: true,
extra: [ extra: getButtons(),
<Button key="back" type="dashed" onClick={handleBack}>返回</Button>,
<Button key="refresh" icon={<RedoOutlined/>} onClick={handleRefreshJobInfoDetail}/>,
<Button key="flinkwebui">
<Link href={`http://${job?.history?.jobManagerAddress}/#/job/${job?.instance?.jid}/overview`} target="_blank">
FlinkWebUI
</Link></Button>,
<Button key="autorestart" type="primary">智能重启</Button>,
<Button key="autostop" type="primary" danger>智能停止</Button>,
<Dropdown
key="dropdown"
trigger={['click']}
overlay={
<Menu>
<Menu.Item key="1">普通停止</Menu.Item>
<Menu.Item key="2">SavePoint停止</Menu.Item>
<Menu.Item key="3">SavePoint暂停</Menu.Item>
</Menu>
}
>
<Button key="4" style={{padding: '0 8px'}}>
<EllipsisOutlined/>
</Button>
</Dropdown>,
],
}} }}
content={<> content={<>
<Space size={0}> <Space size={0}>
......
...@@ -11,6 +11,7 @@ import ProTable from "@ant-design/pro-table"; ...@@ -11,6 +11,7 @@ import ProTable from "@ant-design/pro-table";
import {JobInstanceTableListItem} from "@/pages/DevOps/data"; import {JobInstanceTableListItem} from "@/pages/DevOps/data";
import moment from 'moment'; import moment from 'moment';
import {RUN_MODE} from "@/components/Studio/conf"; import {RUN_MODE} from "@/components/Studio/conf";
import JobStatus from "@/components/Common/JobStatus";
const url = '/api/jobInstance'; const url = '/api/jobInstance';
const JobInstanceTable = (props: any) => { const JobInstanceTable = (props: any) => {
...@@ -74,34 +75,7 @@ const JobInstanceTable = (props: any) => { ...@@ -74,34 +75,7 @@ const JobInstanceTable = (props: any) => {
hideInSearch: true, hideInSearch: true,
render: (_, row) => { render: (_, row) => {
return ( return (
<> <JobStatus status={row.status}/>)
{(row.status == 'FINISHED') ?
(<Tag icon={<CheckCircleOutlined />} color="success">
FINISHED
</Tag>) :
(row.status == 'RUNNING') ?
(<Tag icon={<SyncOutlined spin />} color="processing">
RUNNING
</Tag>) :
(row.status == 'FAILED') ?
(<Tag icon={<CloseCircleOutlined />} color="error">
FAILED
</Tag>) :
(row.status == 'CANCELED') ?
(<Tag icon={<MinusCircleOutlined />} color="default">
CANCELED
</Tag>) :
(row.status == 'INITIALIZING') ?
(<Tag icon={<ClockCircleOutlined />} color="default">
INITIALIZING
</Tag>) :(row.status == 'RESTARTING') ?
(<Tag icon={<ClockCircleOutlined />} color="default">
RESTARTING
</Tag>) :
(<Tag color="default">
UNKNOWEN
</Tag>)
}</>)
; ;
} }
}, { }, {
......
import {ClusterTableListItem} from "@/pages/Cluster/data"; import {ClusterTableListItem} from "@/pages/Cluster/data";
import {ClusterConfigurationTableListItem} from "@/pages/ClusterConfiguration/data"; import {ClusterConfigurationTableListItem} from "@/pages/ClusterConfiguration/data";
import {HistoryItem} from "@/components/Studio/StudioConsole/StudioHistory/data"; import {HistoryItem} from "@/components/Studio/StudioConsole/StudioHistory/data";
import {JarTableListItem} from "@/pages/Jar/data";
export type JobInstanceTableListItem = { export type JobInstanceTableListItem = {
id: number, id: number,
...@@ -28,6 +29,13 @@ export type StatusCount = { ...@@ -28,6 +29,13 @@ export type StatusCount = {
finished: number, finished: number,
failed: number, failed: number,
canceled: number, canceled: number,
restarting: number,
created: number,
failing: number,
cancelling: number,
suspended: number,
reconciling: number,
unknown: number,
} }
export type JobInfoDetail = { export type JobInfoDetail = {
...@@ -35,8 +43,8 @@ export type JobInfoDetail = { ...@@ -35,8 +43,8 @@ export type JobInfoDetail = {
instance: JobInstanceTableListItem, instance: JobInstanceTableListItem,
cluster: ClusterTableListItem, cluster: ClusterTableListItem,
clusterConfiguration: ClusterConfigurationTableListItem, clusterConfiguration: ClusterConfigurationTableListItem,
task: TaskTableListItem, history: HistoryItem,
history: HistoryItem jar: JarTableListItem
} }
export type VerticesTableListItem = { export type VerticesTableListItem = {
...@@ -47,5 +55,5 @@ export type VerticesTableListItem = { ...@@ -47,5 +55,5 @@ export type VerticesTableListItem = {
startTime: string, startTime: string,
duration: number, duration: number,
endTime: string, endTime: string,
tasks:any, tasks: any,
} }
...@@ -5,6 +5,7 @@ import JobInstanceTable from "./JobInstanceTable"; ...@@ -5,6 +5,7 @@ import JobInstanceTable from "./JobInstanceTable";
import {getStatusCount} from "@/pages/DevOps/service"; import {getStatusCount} from "@/pages/DevOps/service";
import {useEffect, useState} from "react"; import {useEffect, useState} from "react";
import {StatusCount} from "@/pages/DevOps/data"; import {StatusCount} from "@/pages/DevOps/data";
import {JOB_STATUS} from "@/components/Common/JobStatus";
const { Statistic } = StatisticCard; const { Statistic } = StatisticCard;
...@@ -13,11 +14,17 @@ const DevOps = (props:any) => { ...@@ -13,11 +14,17 @@ const DevOps = (props:any) => {
// const {current} = props; // const {current} = props;
const statusCountDefault = [ const statusCountDefault = [
{ key: '', title: '全部', value: 0, total: true }, { key: '', title: '全部', value: 0, total: true },
{ key: 'INITIALIZING', status: 'default', title: '初始化', value: 0 }, { key: JOB_STATUS.INITIALIZING, status: 'default', title: '初始化', value: 0 },
{ key: 'RUNNING', status: 'success', title: '运行中', value: 0 }, { key: JOB_STATUS.CREATED, status: 'default', title: '创建中', value: 0 },
{ key: 'FINISHED', status: 'processing', title: '已完成', value: 0 }, { key: JOB_STATUS.RUNNING, status: 'success', title: '运行中', value: 0 },
{ key: 'FAILED', status: 'error', title: '发生异常', value: 0 }, { key: JOB_STATUS.FINISHED, status: 'processing', title: '已完成', value: 0 },
{ key: 'CANCELED', status: 'warning', title: '停止', value: 0 }, { key: JOB_STATUS.FAILING, status: 'error', title: '异常中', value: 0 },
{ key: JOB_STATUS.FAILED, status: 'error', title: '已异常', value: 0 },
{ key: JOB_STATUS.SUSPENDED, status: 'warning', title: '已暂停', value: 0 },
{ key: JOB_STATUS.CANCELLING, status: 'warning', title: '停止中', value: 0 },
{ key: JOB_STATUS.CANCELED, status: 'warning', title: '已停止', value: 0 },
{ key: JOB_STATUS.RESTARTING, status: 'default', title: '重启中', value: 0 },
{ key: JOB_STATUS.UNKNOWN, status: 'default', title: '未知', value: 0 },
]; ];
const [statusCount, setStatusCount] = useState<any[]>(statusCountDefault); const [statusCount, setStatusCount] = useState<any[]>(statusCountDefault);
const [activeKey, setActiveKey] = useState<string>(''); const [activeKey, setActiveKey] = useState<string>('');
...@@ -28,11 +35,17 @@ const DevOps = (props:any) => { ...@@ -28,11 +35,17 @@ const DevOps = (props:any) => {
const statusCountData: StatusCount = result.datas; const statusCountData: StatusCount = result.datas;
const items: any = [ const items: any = [
{ key: '', title: '全部', value: statusCountData.all, total: true }, { key: '', title: '全部', value: statusCountData.all, total: true },
{ key: 'INITIALIZING', status: 'default', title: '初始化', value: statusCountData.initializing }, { key: JOB_STATUS.INITIALIZING, status: 'default', title: '初始化', value: statusCountData.initializing },
{ key: 'RUNNING', status: 'success', title: '运行中', value: statusCountData.running }, { key: JOB_STATUS.CREATED, status: 'default', title: '创建中', value: statusCountData.created },
{ key: 'FINISHED', status: 'processing', title: '已完成', value: statusCountData.finished }, { key: JOB_STATUS.RUNNING, status: 'success', title: '运行中', value: statusCountData.running },
{ key: 'FAILED', status: 'error', title: '发生异常', value: statusCountData.failed }, { key: JOB_STATUS.FINISHED, status: 'processing', title: '已完成', value: statusCountData.finished },
{ key: 'CANCELED', status: 'warning', title: '停止', value: statusCountData.canceled }, { key: JOB_STATUS.FAILING, status: 'error', title: '异常中', value: statusCountData.failing },
{ key: JOB_STATUS.FAILED, status: 'error', title: '已异常', value: statusCountData.failed },
{ key: JOB_STATUS.SUSPENDED, status: 'warning', title: '已暂停', value: statusCountData.suspended },
{ key: JOB_STATUS.CANCELLING, status: 'warning', title: '停止中', value: statusCountData.cancelling },
{ key: JOB_STATUS.CANCELED, status: 'warning', title: '停止', value: statusCountData.canceled },
{ key: JOB_STATUS.RESTARTING, status: 'default', title: '重启中', value: statusCountData.restarting },
{ key: JOB_STATUS.UNKNOWN, status: 'default', title: '未知', value: statusCountData.unknown },
]; ];
setStatusCount(items); setStatusCount(items);
}); });
...@@ -64,7 +77,7 @@ const DevOps = (props:any) => { ...@@ -64,7 +77,7 @@ const DevOps = (props:any) => {
title={item.title} title={item.title}
value={item.value} value={item.value}
status={item.status as StatisticProps['status']} status={item.status as StatisticProps['status']}
style={{ width: 120, borderRight: item.total ? '1px solid #f0f0f0' : undefined }} style={{ width: 80, borderRight: item.total ? '1px solid #f0f0f0' : undefined }}
/> />
} }
> >
......
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