mirror of
https://github.com/apache/rocketmq-dashboard.git
synced 2025-09-10 19:48:29 +08:00
@@ -6,19 +6,14 @@ This project was bootstrapped with [Create React App](https://github.com/faceboo
|
|||||||
|
|
||||||
In the project directory, you can run:
|
In the project directory, you can run:
|
||||||
|
|
||||||
### `npm start`
|
### `npm run start`
|
||||||
|
|
||||||
Runs the app in the development mode.\
|
Runs the app in the development mode.\
|
||||||
Open [http://localhost:3000](http://localhost:3000) to view it in your browser.
|
Open [http://localhost:3003](http://localhost:3000) to view it in your browser.
|
||||||
|
|
||||||
The page will reload when you make changes.\
|
The page will reload when you make changes.\
|
||||||
You may also see any lint errors in the console.
|
You may also see any lint errors in the console.
|
||||||
|
|
||||||
### `npm test`
|
|
||||||
|
|
||||||
Launches the test runner in the interactive watch mode.\
|
|
||||||
See the section about [running tests](https://facebook.github.io/create-react-app/docs/running-tests) for more information.
|
|
||||||
|
|
||||||
### `npm run build`
|
### `npm run build`
|
||||||
|
|
||||||
Builds the app for production to the `build` folder.\
|
Builds the app for production to the `build` folder.\
|
||||||
|
@@ -18,13 +18,13 @@
|
|||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html lang="en">
|
<html lang="en">
|
||||||
<head>
|
<head>
|
||||||
<meta charset="UTF-8" />
|
<meta charset="UTF-8"/>
|
||||||
<link rel="shortcut icon" href="./favicon.ico" type="image/x-icon" />
|
<link rel="shortcut icon" href="./favicon.ico" type="image/x-icon"/>
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
|
||||||
<meta name="description" content="" />
|
<meta name="description" content=""/>
|
||||||
<meta name="keywords" content="" />
|
<meta name="keywords" content=""/>
|
||||||
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
|
<meta http-equiv="X-UA-Compatible" content="IE=edge"/>
|
||||||
<title>RocketMQ Dashboard</title>
|
<title>RocketMQ Dashboard</title>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<noscript>You need to enable JavaScript to run this app.</noscript>
|
<noscript>You need to enable JavaScript to run this app.</noscript>
|
||||||
|
@@ -17,19 +17,19 @@
|
|||||||
|
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import AppRouter from './router'; // 你 router/index.jsx 导出的组件
|
import AppRouter from './router'; // 你 router/index.jsx 导出的组件
|
||||||
import { ToastContainer } from 'react-toastify';
|
import {ToastContainer} from 'react-toastify';
|
||||||
import 'react-toastify/dist/ReactToastify.css';
|
import 'react-toastify/dist/ReactToastify.css';
|
||||||
import {ConfigProvider} from "antd";
|
import {ConfigProvider} from "antd";
|
||||||
import {useTheme} from "./store/context/ThemeContext";
|
import {useTheme} from "./store/context/ThemeContext";
|
||||||
|
|
||||||
function App() {
|
function App() {
|
||||||
const {currentTheme} = useTheme();
|
const {currentTheme} = useTheme();
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<ConfigProvider theme={currentTheme}>
|
<ConfigProvider theme={currentTheme}>
|
||||||
<ToastContainer />
|
<ToastContainer/>
|
||||||
<AppRouter />
|
<AppRouter/>
|
||||||
</ConfigProvider>
|
</ConfigProvider>
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
|
@@ -15,11 +15,11 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { render, screen } from '@testing-library/react';
|
import {render, screen} from '@testing-library/react';
|
||||||
import App from './App';
|
import App from './App';
|
||||||
|
|
||||||
test('renders learn react link', () => {
|
test('renders learn react link', () => {
|
||||||
render(<App />);
|
render(<App/>);
|
||||||
const linkElement = screen.getByText(/learn react/i);
|
const linkElement = screen.getByText(/learn react/i);
|
||||||
expect(linkElement).toBeInTheDocument();
|
expect(linkElement).toBeInTheDocument();
|
||||||
});
|
});
|
||||||
|
@@ -16,20 +16,20 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { Form, Input, Typography, Modal } from 'antd';
|
import {Form, Input, Typography} from 'antd';
|
||||||
import moment from 'moment';
|
import moment from 'moment';
|
||||||
import { useLanguage } from '../i18n/LanguageContext'; // 根据实际路径调整
|
import {useLanguage} from '../i18n/LanguageContext'; // 根据实际路径调整
|
||||||
|
|
||||||
const { Text } = Typography;
|
const {Text} = Typography;
|
||||||
|
|
||||||
const DlqMessageDetailViewDialog = ({ ngDialogData }) => {
|
const DlqMessageDetailViewDialog = ({ngDialogData}) => {
|
||||||
const { t } = useLanguage();
|
const {t} = useLanguage();
|
||||||
|
|
||||||
const messageView = ngDialogData?.messageView || {};
|
const messageView = ngDialogData?.messageView || {};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div style={{ padding: '20px' }}>
|
<div style={{padding: '20px'}}>
|
||||||
<Form layout="horizontal" labelCol={{ span: 4 }} wrapperCol={{ span: 20 }}>
|
<Form layout="horizontal" labelCol={{span: 4}} wrapperCol={{span: 20}}>
|
||||||
<Form.Item label="Message ID:">
|
<Form.Item label="Message ID:">
|
||||||
<Text strong>{messageView.msgId}</Text>
|
<Text strong>{messageView.msgId}</Text>
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
@@ -39,7 +39,7 @@ const DlqMessageDetailViewDialog = ({ ngDialogData }) => {
|
|||||||
<Form.Item label="Properties:">
|
<Form.Item label="Properties:">
|
||||||
<Input.TextArea
|
<Input.TextArea
|
||||||
value={typeof messageView.properties === 'object' ? JSON.stringify(messageView.properties, null, 2) : messageView.properties}
|
value={typeof messageView.properties === 'object' ? JSON.stringify(messageView.properties, null, 2) : messageView.properties}
|
||||||
style={{ minHeight: 100, resize: 'none' }}
|
style={{minHeight: 100, resize: 'none'}}
|
||||||
readOnly
|
readOnly
|
||||||
/>
|
/>
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
@@ -61,7 +61,7 @@ const DlqMessageDetailViewDialog = ({ ngDialogData }) => {
|
|||||||
<Form.Item label="Message body:">
|
<Form.Item label="Message body:">
|
||||||
<Input.TextArea
|
<Input.TextArea
|
||||||
value={messageView.messageBody}
|
value={messageView.messageBody}
|
||||||
style={{ minHeight: 100, resize: 'none' }}
|
style={{minHeight: 100, resize: 'none'}}
|
||||||
readOnly
|
readOnly
|
||||||
/>
|
/>
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
|
@@ -16,16 +16,16 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { Modal, Button, Typography, Descriptions, Tag, Spin, notification } from 'antd';
|
import {Button, Descriptions, Modal, notification, Spin, Tag, Typography} from 'antd';
|
||||||
import moment from 'moment';
|
import moment from 'moment';
|
||||||
import { ExclamationCircleOutlined, SyncOutlined } from '@ant-design/icons';
|
import {SyncOutlined} from '@ant-design/icons';
|
||||||
import { useLanguage } from '../i18n/LanguageContext';
|
import {useLanguage} from '../i18n/LanguageContext';
|
||||||
import { remoteApi } from '../api/remoteApi/remoteApi'; // 确保这个路径正确
|
import {remoteApi} from '../api/remoteApi/remoteApi'; // 确保这个路径正确
|
||||||
|
|
||||||
const { Text, Paragraph } = Typography;
|
const {Text, Paragraph} = Typography;
|
||||||
|
|
||||||
const MessageDetailViewDialog = ({ visible, onCancel, messageId, topic, onResendMessage }) => {
|
const MessageDetailViewDialog = ({visible, onCancel, messageId, topic, onResendMessage}) => {
|
||||||
const { t } = useLanguage();
|
const {t} = useLanguage();
|
||||||
const [loading, setLoading] = React.useState(true);
|
const [loading, setLoading] = React.useState(true);
|
||||||
const [messageDetail, setMessageDetail] = React.useState(null);
|
const [messageDetail, setMessageDetail] = React.useState(null);
|
||||||
const [error, setError] = React.useState(null);
|
const [error, setError] = React.useState(null);
|
||||||
@@ -89,17 +89,21 @@ const MessageDetailViewDialog = ({ visible, onCancel, messageId, topic, onResend
|
|||||||
>
|
>
|
||||||
<Spin spinning={loading} tip={t.LOADING}>
|
<Spin spinning={loading} tip={t.LOADING}>
|
||||||
{error && (
|
{error && (
|
||||||
<Paragraph type="danger" style={{ textAlign: 'center' }}>
|
<Paragraph type="danger" style={{textAlign: 'center'}}>
|
||||||
{error}
|
{error}
|
||||||
</Paragraph>
|
</Paragraph>
|
||||||
)}
|
)}
|
||||||
{messageDetail ? ( // 确保 messageDetail 存在时才渲染内容
|
{messageDetail ? ( // 确保 messageDetail 存在时才渲染内容
|
||||||
<>
|
<>
|
||||||
{/* 消息信息部分 */}
|
{/* 消息信息部分 */}
|
||||||
<Descriptions title={<Text strong>{t.MESSAGE_INFO}</Text>} bordered column={2} size="small" style={{ marginBottom: 20 }}>
|
<Descriptions title={<Text strong>{t.MESSAGE_INFO}</Text>} bordered column={2} size="small"
|
||||||
<Descriptions.Item label="Topic" span={2}><Text copyable>{messageDetail.messageView.topic}</Text></Descriptions.Item>
|
style={{marginBottom: 20}}>
|
||||||
<Descriptions.Item label="Message ID" span={2}><Text copyable>{messageDetail.messageView.msgId}</Text></Descriptions.Item>
|
<Descriptions.Item label="Topic" span={2}><Text
|
||||||
<Descriptions.Item label="StoreHost">{messageDetail.messageView.storeHost}</Descriptions.Item>
|
copyable>{messageDetail.messageView.topic}</Text></Descriptions.Item>
|
||||||
|
<Descriptions.Item label="Message ID" span={2}><Text
|
||||||
|
copyable>{messageDetail.messageView.msgId}</Text></Descriptions.Item>
|
||||||
|
<Descriptions.Item
|
||||||
|
label="StoreHost">{messageDetail.messageView.storeHost}</Descriptions.Item>
|
||||||
<Descriptions.Item label="BornHost">{messageDetail.messageView.bornHost}</Descriptions.Item>
|
<Descriptions.Item label="BornHost">{messageDetail.messageView.bornHost}</Descriptions.Item>
|
||||||
<Descriptions.Item label="StoreTime">
|
<Descriptions.Item label="StoreTime">
|
||||||
{moment(messageDetail.messageView.storeTimestamp).format("YYYY-MM-DD HH:mm:ss")}
|
{moment(messageDetail.messageView.storeTimestamp).format("YYYY-MM-DD HH:mm:ss")}
|
||||||
@@ -108,26 +112,33 @@ const MessageDetailViewDialog = ({ visible, onCancel, messageId, topic, onResend
|
|||||||
{moment(messageDetail.messageView.bornTimestamp).format("YYYY-MM-DD HH:mm:ss")}
|
{moment(messageDetail.messageView.bornTimestamp).format("YYYY-MM-DD HH:mm:ss")}
|
||||||
</Descriptions.Item>
|
</Descriptions.Item>
|
||||||
<Descriptions.Item label="Queue ID">{messageDetail.messageView.queueId}</Descriptions.Item>
|
<Descriptions.Item label="Queue ID">{messageDetail.messageView.queueId}</Descriptions.Item>
|
||||||
<Descriptions.Item label="Queue Offset">{messageDetail.messageView.queueOffset}</Descriptions.Item>
|
<Descriptions.Item
|
||||||
<Descriptions.Item label="StoreSize">{messageDetail.messageView.storeSize} bytes</Descriptions.Item>
|
label="Queue Offset">{messageDetail.messageView.queueOffset}</Descriptions.Item>
|
||||||
<Descriptions.Item label="ReconsumeTimes">{messageDetail.messageView.reconsumeTimes}</Descriptions.Item>
|
<Descriptions.Item
|
||||||
|
label="StoreSize">{messageDetail.messageView.storeSize} bytes</Descriptions.Item>
|
||||||
|
<Descriptions.Item
|
||||||
|
label="ReconsumeTimes">{messageDetail.messageView.reconsumeTimes}</Descriptions.Item>
|
||||||
<Descriptions.Item label="BodyCRC">{messageDetail.messageView.bodyCRC}</Descriptions.Item>
|
<Descriptions.Item label="BodyCRC">{messageDetail.messageView.bodyCRC}</Descriptions.Item>
|
||||||
<Descriptions.Item label="SysFlag">{messageDetail.messageView.sysFlag}</Descriptions.Item>
|
<Descriptions.Item label="SysFlag">{messageDetail.messageView.sysFlag}</Descriptions.Item>
|
||||||
<Descriptions.Item label="Flag">{messageDetail.messageView.flag}</Descriptions.Item>
|
<Descriptions.Item label="Flag">{messageDetail.messageView.flag}</Descriptions.Item>
|
||||||
<Descriptions.Item label="PreparedTransactionOffset">{messageDetail.messageView.preparedTransactionOffset}</Descriptions.Item>
|
<Descriptions.Item
|
||||||
|
label="PreparedTransactionOffset">{messageDetail.messageView.preparedTransactionOffset}</Descriptions.Item>
|
||||||
</Descriptions>
|
</Descriptions>
|
||||||
|
|
||||||
{/* 消息属性部分 */}
|
{/* 消息属性部分 */}
|
||||||
{Object.keys(messageDetail.messageView.properties).length > 0 && (
|
{Object.keys(messageDetail.messageView.properties).length > 0 && (
|
||||||
<Descriptions title={<Text strong>{t.MESSAGE_PROPERTIES}</Text>} bordered column={1} size="small" style={{ marginBottom: 20 }}>
|
<Descriptions title={<Text strong>{t.MESSAGE_PROPERTIES}</Text>} bordered column={1}
|
||||||
|
size="small" style={{marginBottom: 20}}>
|
||||||
{Object.entries(messageDetail.messageView.properties).map(([key, value]) => (
|
{Object.entries(messageDetail.messageView.properties).map(([key, value]) => (
|
||||||
<Descriptions.Item label={key} key={key}><Text copyable>{value}</Text></Descriptions.Item>
|
<Descriptions.Item label={key} key={key}><Text
|
||||||
|
copyable>{value}</Text></Descriptions.Item>
|
||||||
))}
|
))}
|
||||||
</Descriptions>
|
</Descriptions>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
{/* 消息体部分 */}
|
{/* 消息体部分 */}
|
||||||
<Descriptions title={<Text strong>{t.MESSAGE_BODY}</Text>} bordered column={1} size="small" style={{ marginBottom: 20 }}>
|
<Descriptions title={<Text strong>{t.MESSAGE_BODY}</Text>} bordered column={1} size="small"
|
||||||
|
style={{marginBottom: 20}}>
|
||||||
<Descriptions.Item>
|
<Descriptions.Item>
|
||||||
<Paragraph
|
<Paragraph
|
||||||
copyable
|
copyable
|
||||||
@@ -146,9 +157,10 @@ const MessageDetailViewDialog = ({ visible, onCancel, messageId, topic, onResend
|
|||||||
{messageDetail.messageTrackList && messageDetail.messageTrackList.length > 0 ? (
|
{messageDetail.messageTrackList && messageDetail.messageTrackList.length > 0 ? (
|
||||||
<>
|
<>
|
||||||
<Text strong>{t.MESSAGE_TRACKING}</Text>
|
<Text strong>{t.MESSAGE_TRACKING}</Text>
|
||||||
<div style={{ marginTop: 10 }}>
|
<div style={{marginTop: 10}}>
|
||||||
{messageDetail.messageTrackList.map((track, index) => (
|
{messageDetail.messageTrackList.map((track, index) => (
|
||||||
<Descriptions bordered column={1} size="small" key={index} style={{ marginBottom: 15 }}>
|
<Descriptions bordered column={1} size="small" key={index}
|
||||||
|
style={{marginBottom: 15}}>
|
||||||
<Descriptions.Item label={t.CONSUMER_GROUP}>
|
<Descriptions.Item label={t.CONSUMER_GROUP}>
|
||||||
{track.consumerGroup}
|
{track.consumerGroup}
|
||||||
</Descriptions.Item>
|
</Descriptions.Item>
|
||||||
@@ -165,10 +177,10 @@ const MessageDetailViewDialog = ({ visible, onCancel, messageId, topic, onResend
|
|||||||
</Descriptions.Item>
|
</Descriptions.Item>
|
||||||
<Descriptions.Item label={t.OPERATION}>
|
<Descriptions.Item label={t.OPERATION}>
|
||||||
<Button
|
<Button
|
||||||
icon={<SyncOutlined />}
|
icon={<SyncOutlined/>}
|
||||||
onClick={() => onResendMessage(messageDetail.messageView, track.consumerGroup)}
|
onClick={() => onResendMessage(messageDetail.messageView, track.consumerGroup)}
|
||||||
size="small"
|
size="small"
|
||||||
style={{ marginRight: 8 }}
|
style={{marginRight: 8}}
|
||||||
>
|
>
|
||||||
{t.RESEND_MESSAGE}
|
{t.RESEND_MESSAGE}
|
||||||
</Button>
|
</Button>
|
||||||
@@ -181,7 +193,10 @@ const MessageDetailViewDialog = ({ visible, onCancel, messageId, topic, onResend
|
|||||||
ellipsis={{
|
ellipsis={{
|
||||||
rows: 2, // 默认显示2行
|
rows: 2, // 默认显示2行
|
||||||
expandable: true,
|
expandable: true,
|
||||||
symbol: <Text style={{ color: '#1890ff', cursor: 'pointer' }}>{t.READ_MORE}</Text>, // 蓝色展开文本
|
symbol: <Text style={{
|
||||||
|
color: '#1890ff',
|
||||||
|
cursor: 'pointer'
|
||||||
|
}}>{t.READ_MORE}</Text>, // 蓝色展开文本
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{track.exceptionDesc}
|
{track.exceptionDesc}
|
||||||
@@ -198,7 +213,8 @@ const MessageDetailViewDialog = ({ visible, onCancel, messageId, topic, onResend
|
|||||||
</>
|
</>
|
||||||
) : (
|
) : (
|
||||||
// 当 messageDetail 为 null 时,可以显示一个占位符或者不显示内容
|
// 当 messageDetail 为 null 时,可以显示一个占位符或者不显示内容
|
||||||
!loading && !error && <Paragraph style={{ textAlign: 'center' }}>{t.NO_MESSAGE_DETAIL_AVAILABLE}</Paragraph>
|
!loading && !error &&
|
||||||
|
<Paragraph style={{textAlign: 'center'}}>{t.NO_MESSAGE_DETAIL_AVAILABLE}</Paragraph>
|
||||||
)}
|
)}
|
||||||
</Spin>
|
</Spin>
|
||||||
</Modal>
|
</Modal>
|
||||||
|
@@ -15,15 +15,15 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import React, { useEffect, useRef } from 'react';
|
import React, {useEffect, useRef} from 'react';
|
||||||
import { Form, Input, Typography, Collapse, Table, Tag } from 'antd';
|
import {Collapse, Form, Input, Table, Tag, Typography} from 'antd';
|
||||||
import moment from 'moment';
|
import moment from 'moment';
|
||||||
import { useLanguage } from '../i18n/LanguageContext';
|
import {useLanguage} from '../i18n/LanguageContext';
|
||||||
import Paragraph from "antd/es/skeleton/Paragraph";
|
import Paragraph from "antd/es/skeleton/Paragraph";
|
||||||
import * as echarts from 'echarts'; // Import ECharts
|
import * as echarts from 'echarts'; // Import ECharts
|
||||||
|
|
||||||
const { Text } = Typography;
|
const {Text} = Typography;
|
||||||
const { Panel } = Collapse;
|
const {Panel} = Collapse;
|
||||||
|
|
||||||
// Constants for styling and formatting, derived from the example
|
// Constants for styling and formatting, derived from the example
|
||||||
const SUCCESS_COLOR = '#75d874';
|
const SUCCESS_COLOR = '#75d874';
|
||||||
@@ -36,8 +36,8 @@ const TIME_FORMAT_PATTERN = "YYYY-MM-DD HH:mm:ss.SSS";
|
|||||||
const DEFAULT_DISPLAY_DURATION = 10 * 1000;
|
const DEFAULT_DISPLAY_DURATION = 10 * 1000;
|
||||||
const TRANSACTION_CHECK_COST_TIME = 50; // transactionTraceNode do not have costTime, assume it cost 50ms
|
const TRANSACTION_CHECK_COST_TIME = 50; // transactionTraceNode do not have costTime, assume it cost 50ms
|
||||||
|
|
||||||
const MessageTraceDetailViewDialog = ({ ngDialogData }) => {
|
const MessageTraceDetailViewDialog = ({ngDialogData}) => {
|
||||||
const { t } = useLanguage();
|
const {t} = useLanguage();
|
||||||
const messageTraceGraphRef = useRef(null);
|
const messageTraceGraphRef = useRef(null);
|
||||||
|
|
||||||
const producerNode = ngDialogData?.producerNode;
|
const producerNode = ngDialogData?.producerNode;
|
||||||
@@ -125,6 +125,7 @@ const MessageTraceDetailViewDialog = ({ ngDialogData }) => {
|
|||||||
}
|
}
|
||||||
return `Cost Time: ${formatCostTimeStr(costTime)}<br/>`
|
return `Cost Time: ${formatCostTimeStr(costTime)}<br/>`
|
||||||
}
|
}
|
||||||
|
|
||||||
function buildTimeStamp(timestamp) {
|
function buildTimeStamp(timestamp) {
|
||||||
if (timestamp < 0) {
|
if (timestamp < 0) {
|
||||||
return 'N/A';
|
return 'N/A';
|
||||||
@@ -323,94 +324,181 @@ const MessageTraceDetailViewDialog = ({ ngDialogData }) => {
|
|||||||
|
|
||||||
// ... (rest of your existing component code)
|
// ... (rest of your existing component code)
|
||||||
const transactionColumns = [
|
const transactionColumns = [
|
||||||
{ title: t.TIMESTAMP, dataIndex: 'beginTimestamp', key: 'beginTimestamp', align: 'center', render: (text) => moment(text).format('YYYY-MM-DD HH:mm:ss.SSS') },
|
{
|
||||||
{ title: t.TRANSACTION_STATE, dataIndex: 'transactionState', key: 'transactionState', align: 'center', render: (text) => <Tag color={text === 'COMMIT_MESSAGE' ? 'green' : (text === 'ROLLBACK_MESSAGE' ? 'red' : 'default')}>{text}</Tag> },
|
title: t.TIMESTAMP,
|
||||||
{ title: t.FROM_TRANSACTION_CHECK, dataIndex: 'fromTransactionCheck', key: 'fromTransactionCheck', align: 'center', render: (text) => (text ? <Tag color="blue">{t.YES}</Tag> : <Tag color="purple">{t.NO}</Tag>) },
|
dataIndex: 'beginTimestamp',
|
||||||
{ title: t.CLIENT_HOST, dataIndex: 'clientHost', key: 'clientHost', align: 'center' },
|
key: 'beginTimestamp',
|
||||||
{ title: t.STORE_HOST, dataIndex: 'storeHost', key: 'storeHost', align: 'center' },
|
align: 'center',
|
||||||
|
render: (text) => moment(text).format('YYYY-MM-DD HH:mm:ss.SSS')
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: t.TRANSACTION_STATE,
|
||||||
|
dataIndex: 'transactionState',
|
||||||
|
key: 'transactionState',
|
||||||
|
align: 'center',
|
||||||
|
render: (text) => <Tag
|
||||||
|
color={text === 'COMMIT_MESSAGE' ? 'green' : (text === 'ROLLBACK_MESSAGE' ? 'red' : 'default')}>{text}</Tag>
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: t.FROM_TRANSACTION_CHECK,
|
||||||
|
dataIndex: 'fromTransactionCheck',
|
||||||
|
key: 'fromTransactionCheck',
|
||||||
|
align: 'center',
|
||||||
|
render: (text) => (text ? <Tag color="blue">{t.YES}</Tag> : <Tag color="purple">{t.NO}</Tag>)
|
||||||
|
},
|
||||||
|
{title: t.CLIENT_HOST, dataIndex: 'clientHost', key: 'clientHost', align: 'center'},
|
||||||
|
{title: t.STORE_HOST, dataIndex: 'storeHost', key: 'storeHost', align: 'center'},
|
||||||
];
|
];
|
||||||
|
|
||||||
const consumeColumns = [
|
const consumeColumns = [
|
||||||
{ title: t.BEGIN_TIMESTAMP, dataIndex: 'beginTimestamp', key: 'beginTimestamp', align: 'center', render: (text) => text < 0 ? 'N/A' : moment(text).format('YYYY-MM-DD HH:mm:ss.SSS') },
|
{
|
||||||
{ title: t.END_TIMESTAMP, dataIndex: 'endTimestamp', key: 'endTimestamp', align: 'center', render: (text) => text < 0 ? 'N/A' : moment(text).format('YYYY-MM-DD HH:mm:ss.SSS') },
|
title: t.BEGIN_TIMESTAMP,
|
||||||
{ title: t.COST_TIME, dataIndex: 'costTime', key: 'costTime', align: 'center', render: (text) => text < 0 ? 'N/A' : `${text === 0 ? '<1' : text}ms` },
|
dataIndex: 'beginTimestamp',
|
||||||
{ title: t.STATUS, dataIndex: 'status', key: 'status', align: 'center', render: (text) => <Tag color={text === 'SUCCESS' ? 'green' : (text === 'FAILED' ? 'red' : 'default')}>{text}</Tag> },
|
key: 'beginTimestamp',
|
||||||
{ title: t.RETRY_TIMES, dataIndex: 'retryTimes', key: 'retryTimes', align: 'center', render: (text) => text < 0 ? 'N/A' : text },
|
align: 'center',
|
||||||
{ title: t.CLIENT_HOST, dataIndex: 'clientHost', key: 'clientHost', align: 'center' },
|
render: (text) => text < 0 ? 'N/A' : moment(text).format('YYYY-MM-DD HH:mm:ss.SSS')
|
||||||
{ title: t.STORE_HOST, dataIndex: 'storeHost', key: 'storeHost', align: 'center' },
|
},
|
||||||
|
{
|
||||||
|
title: t.END_TIMESTAMP,
|
||||||
|
dataIndex: 'endTimestamp',
|
||||||
|
key: 'endTimestamp',
|
||||||
|
align: 'center',
|
||||||
|
render: (text) => text < 0 ? 'N/A' : moment(text).format('YYYY-MM-DD HH:mm:ss.SSS')
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: t.COST_TIME,
|
||||||
|
dataIndex: 'costTime',
|
||||||
|
key: 'costTime',
|
||||||
|
align: 'center',
|
||||||
|
render: (text) => text < 0 ? 'N/A' : `${text === 0 ? '<1' : text}ms`
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: t.STATUS,
|
||||||
|
dataIndex: 'status',
|
||||||
|
key: 'status',
|
||||||
|
align: 'center',
|
||||||
|
render: (text) => <Tag
|
||||||
|
color={text === 'SUCCESS' ? 'green' : (text === 'FAILED' ? 'red' : 'default')}>{text}</Tag>
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: t.RETRY_TIMES,
|
||||||
|
dataIndex: 'retryTimes',
|
||||||
|
key: 'retryTimes',
|
||||||
|
align: 'center',
|
||||||
|
render: (text) => text < 0 ? 'N/A' : text
|
||||||
|
},
|
||||||
|
{title: t.CLIENT_HOST, dataIndex: 'clientHost', key: 'clientHost', align: 'center'},
|
||||||
|
{title: t.STORE_HOST, dataIndex: 'storeHost', key: 'storeHost', align: 'center'},
|
||||||
];
|
];
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div style={{ padding: '20px', backgroundColor: '#f0f2f5' }}>
|
<div style={{padding: '20px', backgroundColor: '#f0f2f5'}}>
|
||||||
<div style={{ marginBottom: '20px', borderRadius: '8px', overflow: 'hidden', boxShadow: '0 4px 12px rgba(0, 0, 0, 0.08)' }}>
|
<div style={{
|
||||||
|
marginBottom: '20px',
|
||||||
|
borderRadius: '8px',
|
||||||
|
overflow: 'hidden',
|
||||||
|
boxShadow: '0 4px 12px rgba(0, 0, 0, 0.08)'
|
||||||
|
}}>
|
||||||
<Collapse defaultActiveKey={['messageTraceGraph']} expandIconPosition="right">
|
<Collapse defaultActiveKey={['messageTraceGraph']} expandIconPosition="right">
|
||||||
<Panel header={<Typography.Title level={3} style={{ margin: 0, color: '#333' }}>{t.MESSAGE_TRACE_GRAPH}</Typography.Title>} key="messageTraceGraph">
|
<Panel header={<Typography.Title level={3} style={{
|
||||||
<div ref={messageTraceGraphRef} style={{ height: 500, width: '100%', backgroundColor: '#fff', padding: '10px' }}>
|
margin: 0,
|
||||||
|
color: '#333'
|
||||||
|
}}>{t.MESSAGE_TRACE_GRAPH}</Typography.Title>} key="messageTraceGraph">
|
||||||
|
<div ref={messageTraceGraphRef}
|
||||||
|
style={{height: 500, width: '100%', backgroundColor: '#fff', padding: '10px'}}>
|
||||||
{/* ECharts message trace graph will be rendered here */}
|
{/* ECharts message trace graph will be rendered here */}
|
||||||
{(!producerNode && subscriptionNodeList.length === 0) && (
|
{(!producerNode && subscriptionNodeList.length === 0) && (
|
||||||
<Text type="secondary" style={{ display: 'block', textAlign: 'center', marginTop: '150px' }}>{t.TRACE_GRAPH_PLACEHOLDER}</Text>
|
<Text type="secondary" style={{
|
||||||
|
display: 'block',
|
||||||
|
textAlign: 'center',
|
||||||
|
marginTop: '150px'
|
||||||
|
}}>{t.TRACE_GRAPH_PLACEHOLDER}</Text>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
</Panel>
|
</Panel>
|
||||||
</Collapse>
|
</Collapse>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div style={{ marginBottom: '20px', borderRadius: '8px', overflow: 'hidden', boxShadow: '0 4px 12px rgba(0, 0, 0, 0.08)' }}>
|
<div style={{
|
||||||
|
marginBottom: '20px',
|
||||||
|
borderRadius: '8px',
|
||||||
|
overflow: 'hidden',
|
||||||
|
boxShadow: '0 4px 12px rgba(0, 0, 0, 0.08)'
|
||||||
|
}}>
|
||||||
<Collapse defaultActiveKey={['sendMessageTrace']} expandIconPosition="right">
|
<Collapse defaultActiveKey={['sendMessageTrace']} expandIconPosition="right">
|
||||||
<Panel header={<Typography.Title level={3} style={{ margin: 0, color: '#333' }}>{t.SEND_MESSAGE_TRACE}</Typography.Title>} key="sendMessageTrace">
|
<Panel header={<Typography.Title level={3} style={{
|
||||||
|
margin: 0,
|
||||||
|
color: '#333'
|
||||||
|
}}>{t.SEND_MESSAGE_TRACE}</Typography.Title>} key="sendMessageTrace">
|
||||||
{!producerNode ? (
|
{!producerNode ? (
|
||||||
<Paragraph style={{ padding: '16px', textAlign: 'center', color: '#666' }}>{t.NO_PRODUCER_TRACE_DATA}</Paragraph>
|
<Paragraph style={{
|
||||||
|
padding: '16px',
|
||||||
|
textAlign: 'center',
|
||||||
|
color: '#666'
|
||||||
|
}}>{t.NO_PRODUCER_TRACE_DATA}</Paragraph>
|
||||||
) : (
|
) : (
|
||||||
<div style={{ padding: '16px', backgroundColor: '#fff' }}>
|
<div style={{padding: '16px', backgroundColor: '#fff'}}>
|
||||||
<Typography.Title level={4} style={{ marginBottom: '20px' }}>
|
<Typography.Title level={4} style={{marginBottom: '20px'}}>
|
||||||
{t.SEND_MESSAGE_INFO} : ( {t.MESSAGE_ID} <Text strong copyable>{producerNode.msgId}</Text> )
|
{t.SEND_MESSAGE_INFO} : ( {t.MESSAGE_ID} <Text strong
|
||||||
|
copyable>{producerNode.msgId}</Text> )
|
||||||
</Typography.Title>
|
</Typography.Title>
|
||||||
<Form layout="vertical" colon={false}>
|
<Form layout="vertical" colon={false}>
|
||||||
<div style={{ display: 'grid', gridTemplateColumns: 'repeat(auto-fill, minmax(280px, 1fr))', gap: '16px' }}>
|
<div style={{
|
||||||
|
display: 'grid',
|
||||||
|
gridTemplateColumns: 'repeat(auto-fill, minmax(280px, 1fr))',
|
||||||
|
gap: '16px'
|
||||||
|
}}>
|
||||||
<Form.Item label={<Text strong>{t.TOPIC}</Text>}>
|
<Form.Item label={<Text strong>{t.TOPIC}</Text>}>
|
||||||
<Input value={producerNode.topic} readOnly />
|
<Input value={producerNode.topic} readOnly/>
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
<Form.Item label={<Text strong>{t.PRODUCER_GROUP}</Text>}>
|
<Form.Item label={<Text strong>{t.PRODUCER_GROUP}</Text>}>
|
||||||
<Input value={producerNode.groupName} readOnly />
|
<Input value={producerNode.groupName} readOnly/>
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
<Form.Item label={<Text strong>{t.MESSAGE_KEY}</Text>}>
|
<Form.Item label={<Text strong>{t.MESSAGE_KEY}</Text>}>
|
||||||
<Input value={producerNode.keys} readOnly />
|
<Input value={producerNode.keys} readOnly/>
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
<Form.Item label={<Text strong>{t.TAG}</Text>}>
|
<Form.Item label={<Text strong>{t.TAG}</Text>}>
|
||||||
<Input value={producerNode.tags} readOnly />
|
<Input value={producerNode.tags} readOnly/>
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
|
|
||||||
<Form.Item label={<Text strong>{t.BEGIN_TIMESTAMP}</Text>}>
|
<Form.Item label={<Text strong>{t.BEGIN_TIMESTAMP}</Text>}>
|
||||||
<Input value={moment(producerNode.traceNode.beginTimestamp).format('YYYY-MM-DD HH:mm:ss.SSS')} readOnly />
|
<Input
|
||||||
|
value={moment(producerNode.traceNode.beginTimestamp).format('YYYY-MM-DD HH:mm:ss.SSS')}
|
||||||
|
readOnly/>
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
<Form.Item label={<Text strong>{t.END_TIMESTAMP}</Text>}>
|
<Form.Item label={<Text strong>{t.END_TIMESTAMP}</Text>}>
|
||||||
<Input value={moment(producerNode.traceNode.endTimestamp).format('YYYY-MM-DD HH:mm:ss.SSS')} readOnly />
|
<Input
|
||||||
|
value={moment(producerNode.traceNode.endTimestamp).format('YYYY-MM-DD HH:mm:ss.SSS')}
|
||||||
|
readOnly/>
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
<Form.Item label={<Text strong>{t.COST_TIME}</Text>}>
|
<Form.Item label={<Text strong>{t.COST_TIME}</Text>}>
|
||||||
<Input value={`${producerNode.traceNode.costTime === 0 ? '<1' : producerNode.traceNode.costTime}ms`} readOnly />
|
<Input
|
||||||
|
value={`${producerNode.traceNode.costTime === 0 ? '<1' : producerNode.traceNode.costTime}ms`}
|
||||||
|
readOnly/>
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
<Form.Item label={<Text strong>{t.MSG_TYPE}</Text>}>
|
<Form.Item label={<Text strong>{t.MSG_TYPE}</Text>}>
|
||||||
<Input value={producerNode.traceNode.msgType} readOnly />
|
<Input value={producerNode.traceNode.msgType} readOnly/>
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
|
|
||||||
<Form.Item label={<Text strong>{t.CLIENT_HOST}</Text>}>
|
<Form.Item label={<Text strong>{t.CLIENT_HOST}</Text>}>
|
||||||
<Input value={producerNode.traceNode.clientHost} readOnly />
|
<Input value={producerNode.traceNode.clientHost} readOnly/>
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
<Form.Item label={<Text strong>{t.STORE_HOST}</Text>}>
|
<Form.Item label={<Text strong>{t.STORE_HOST}</Text>}>
|
||||||
<Input value={producerNode.traceNode.storeHost} readOnly />
|
<Input value={producerNode.traceNode.storeHost} readOnly/>
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
<Form.Item label={<Text strong>{t.RETRY_TIMES}</Text>}>
|
<Form.Item label={<Text strong>{t.RETRY_TIMES}</Text>}>
|
||||||
<Input value={producerNode.traceNode.retryTimes} readOnly />
|
<Input value={producerNode.traceNode.retryTimes} readOnly/>
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
<Form.Item label={<Text strong>{t.OFFSET_MSG_ID}</Text>}>
|
<Form.Item label={<Text strong>{t.OFFSET_MSG_ID}</Text>}>
|
||||||
<Input value={producerNode.offSetMsgId} readOnly />
|
<Input value={producerNode.offSetMsgId} readOnly/>
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
</div>
|
</div>
|
||||||
</Form>
|
</Form>
|
||||||
|
|
||||||
{producerNode.transactionNodeList && producerNode.transactionNodeList.length > 0 && (
|
{producerNode.transactionNodeList && producerNode.transactionNodeList.length > 0 && (
|
||||||
<div style={{ marginTop: '30px' }}>
|
<div style={{marginTop: '30px'}}>
|
||||||
<Typography.Title level={4} style={{ marginBottom: '15px' }}>{t.CHECK_TRANSACTION_INFO}:</Typography.Title>
|
<Typography.Title level={4}
|
||||||
|
style={{marginBottom: '15px'}}>{t.CHECK_TRANSACTION_INFO}:</Typography.Title>
|
||||||
<Table
|
<Table
|
||||||
columns={transactionColumns}
|
columns={transactionColumns}
|
||||||
dataSource={producerNode.transactionNodeList}
|
dataSource={producerNode.transactionNodeList}
|
||||||
@@ -418,7 +506,7 @@ const MessageTraceDetailViewDialog = ({ ngDialogData }) => {
|
|||||||
bordered
|
bordered
|
||||||
pagination={false}
|
pagination={false}
|
||||||
size="middle"
|
size="middle"
|
||||||
scroll={{ x: 'max-content' }}
|
scroll={{x: 'max-content'}}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
@@ -428,22 +516,31 @@ const MessageTraceDetailViewDialog = ({ ngDialogData }) => {
|
|||||||
</Collapse>
|
</Collapse>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div style={{ borderRadius: '8px', overflow: 'hidden', boxShadow: '0 4px 12px rgba(0, 0, 0, 0.08)' }}>
|
<div style={{borderRadius: '8px', overflow: 'hidden', boxShadow: '0 4px 12px rgba(0, 0, 0, 0.08)'}}>
|
||||||
<Collapse defaultActiveKey={['consumeMessageTrace']} expandIconPosition="right">
|
<Collapse defaultActiveKey={['consumeMessageTrace']} expandIconPosition="right">
|
||||||
<Panel header={<Typography.Title level={3} style={{ margin: 0, color: '#333' }}>{t.CONSUME_MESSAGE_TRACE}</Typography.Title>} key="consumeMessageTrace">
|
<Panel header={<Typography.Title level={3} style={{
|
||||||
|
margin: 0,
|
||||||
|
color: '#333'
|
||||||
|
}}>{t.CONSUME_MESSAGE_TRACE}</Typography.Title>} key="consumeMessageTrace">
|
||||||
{subscriptionNodeList.length === 0 ? (
|
{subscriptionNodeList.length === 0 ? (
|
||||||
<Paragraph style={{ padding: '16px', textAlign: 'center', color: '#666' }}>{t.NO_CONSUMER_TRACE_DATA}</Paragraph>
|
<Paragraph style={{
|
||||||
|
padding: '16px',
|
||||||
|
textAlign: 'center',
|
||||||
|
color: '#666'
|
||||||
|
}}>{t.NO_CONSUMER_TRACE_DATA}</Paragraph>
|
||||||
) : (
|
) : (
|
||||||
<div style={{ padding: '16px', backgroundColor: '#fff' }}>
|
<div style={{padding: '16px', backgroundColor: '#fff'}}>
|
||||||
{subscriptionNodeList.map(subscriptionNode => (
|
{subscriptionNodeList.map(subscriptionNode => (
|
||||||
<Collapse
|
<Collapse
|
||||||
key={subscriptionNode.subscriptionGroup}
|
key={subscriptionNode.subscriptionGroup}
|
||||||
style={{ marginBottom: '10px', border: '1px solid #e0e0e0', borderRadius: '4px' }}
|
style={{marginBottom: '10px', border: '1px solid #e0e0e0', borderRadius: '4px'}}
|
||||||
defaultActiveKey={[subscriptionNode.subscriptionGroup]}
|
defaultActiveKey={[subscriptionNode.subscriptionGroup]}
|
||||||
ghost
|
ghost
|
||||||
>
|
>
|
||||||
<Panel
|
<Panel
|
||||||
header={<Typography.Title level={4} style={{ margin: 0 }}>{t.SUBSCRIPTION_GROUP}: <Text strong>{subscriptionNode.subscriptionGroup}</Text></Typography.Title>}
|
header={<Typography.Title level={4}
|
||||||
|
style={{margin: 0}}>{t.SUBSCRIPTION_GROUP}: <Text
|
||||||
|
strong>{subscriptionNode.subscriptionGroup}</Text></Typography.Title>}
|
||||||
key={subscriptionNode.subscriptionGroup}
|
key={subscriptionNode.subscriptionGroup}
|
||||||
>
|
>
|
||||||
<Table
|
<Table
|
||||||
@@ -453,7 +550,7 @@ const MessageTraceDetailViewDialog = ({ ngDialogData }) => {
|
|||||||
bordered
|
bordered
|
||||||
pagination={false}
|
pagination={false}
|
||||||
size="middle"
|
size="middle"
|
||||||
scroll={{ x: 'max-content' }}
|
scroll={{x: 'max-content'}}
|
||||||
/>
|
/>
|
||||||
</Panel>
|
</Panel>
|
||||||
</Collapse>
|
</Collapse>
|
||||||
|
@@ -16,29 +16,29 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
import React, {useEffect, useState} from 'react';
|
import React, {useEffect, useState} from 'react';
|
||||||
import { Layout, Menu, Dropdown, Button, Drawer, Grid, Space } from 'antd';
|
import {Button, Drawer, Dropdown, Grid, Layout, Menu, Space} from 'antd';
|
||||||
import {GlobalOutlined, DownOutlined, UserOutlined, MenuOutlined, BgColorsOutlined} from '@ant-design/icons';
|
import {BgColorsOutlined, DownOutlined, GlobalOutlined, MenuOutlined, UserOutlined} from '@ant-design/icons';
|
||||||
import { useLocation, useNavigate } from 'react-router-dom';
|
import {useLocation, useNavigate} from 'react-router-dom';
|
||||||
import { useLanguage } from '../i18n/LanguageContext';
|
import {useLanguage} from '../i18n/LanguageContext';
|
||||||
import {useTheme} from "../store/context/ThemeContext";
|
import {useTheme} from "../store/context/ThemeContext";
|
||||||
import {remoteApi} from "../api/remoteApi/remoteApi";
|
import {remoteApi} from "../api/remoteApi/remoteApi";
|
||||||
|
|
||||||
const { Header } = Layout;
|
const {Header} = Layout;
|
||||||
const { useBreakpoint } = Grid; // Used to determine screen breakpoints
|
const {useBreakpoint} = Grid; // Used to determine screen breakpoints
|
||||||
|
|
||||||
const Navbar = ({ rmqVersion = true, showAcl = true}) => {
|
const Navbar = ({rmqVersion = true, showAcl = true}) => {
|
||||||
const location = useLocation();
|
const location = useLocation();
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
const { lang, setLang, t } = useLanguage();
|
const {lang, setLang, t} = useLanguage();
|
||||||
const screens = useBreakpoint(); // Get current screen size breakpoints
|
const screens = useBreakpoint(); // Get current screen size breakpoints
|
||||||
const { currentThemeName, setCurrentThemeName } = useTheme();
|
const {currentThemeName, setCurrentThemeName} = useTheme();
|
||||||
const [userName, setUserName] = useState(null);
|
const [userName, setUserName] = useState(null);
|
||||||
const [drawerVisible, setDrawerVisible] = useState(false); // Controls drawer visibility
|
const [drawerVisible, setDrawerVisible] = useState(false); // Controls drawer visibility
|
||||||
|
|
||||||
// Get selected menu item key based on current route path
|
// Get selected menu item key based on current route path
|
||||||
const getPath = () => location.pathname.replace('/', '');
|
const getPath = () => location.pathname.replace('/', '');
|
||||||
|
|
||||||
const handleMenuClick = ({ key }) => {
|
const handleMenuClick = ({key}) => {
|
||||||
navigate(`/${key}`);
|
navigate(`/${key}`);
|
||||||
setDrawerVisible(false); // Close drawer after clicking a menu item
|
setDrawerVisible(false); // Close drawer after clicking a menu item
|
||||||
};
|
};
|
||||||
@@ -63,13 +63,13 @@ const Navbar = ({ rmqVersion = true, showAcl = true}) => {
|
|||||||
const storedUsername = window.localStorage.getItem("username");
|
const storedUsername = window.localStorage.getItem("username");
|
||||||
if (storedUsername) {
|
if (storedUsername) {
|
||||||
setUserName(storedUsername);
|
setUserName(storedUsername);
|
||||||
}else {
|
} else {
|
||||||
setUserName(null);
|
setUserName(null);
|
||||||
}
|
}
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
const langMenu = (
|
const langMenu = (
|
||||||
<Menu onClick={({ key }) => setLang(key)}>
|
<Menu onClick={({key}) => setLang(key)}>
|
||||||
<Menu.Item key="en">{t.ENGLISH}</Menu.Item>
|
<Menu.Item key="en">{t.ENGLISH}</Menu.Item>
|
||||||
<Menu.Item key="zh">{t.CHINESE}</Menu.Item>
|
<Menu.Item key="zh">{t.CHINESE}</Menu.Item>
|
||||||
</Menu>
|
</Menu>
|
||||||
@@ -82,7 +82,7 @@ const Navbar = ({ rmqVersion = true, showAcl = true}) => {
|
|||||||
);
|
);
|
||||||
|
|
||||||
const themeMenu = (
|
const themeMenu = (
|
||||||
<Menu onClick={({ key }) => setCurrentThemeName(key)}>
|
<Menu onClick={({key}) => setCurrentThemeName(key)}>
|
||||||
<Menu.Item key="default">{t.BLUE} ({t.DEFAULT})</Menu.Item>
|
<Menu.Item key="default">{t.BLUE} ({t.DEFAULT})</Menu.Item>
|
||||||
<Menu.Item key="pink">{t.PINK}</Menu.Item>
|
<Menu.Item key="pink">{t.PINK}</Menu.Item>
|
||||||
<Menu.Item key="green">{t.GREEN}</Menu.Item>
|
<Menu.Item key="green">{t.GREEN}</Menu.Item>
|
||||||
@@ -92,17 +92,17 @@ const Navbar = ({ rmqVersion = true, showAcl = true}) => {
|
|||||||
|
|
||||||
// Menu item configuration
|
// Menu item configuration
|
||||||
const menuItems = [
|
const menuItems = [
|
||||||
{ key: 'ops', label: t.OPS },
|
{key: 'ops', label: t.OPS},
|
||||||
...(rmqVersion ? [{ key: 'proxy', label: t.PROXY }] : []),
|
...(rmqVersion ? [{key: 'proxy', label: t.PROXY}] : []),
|
||||||
{ key: '', label: t.DASHBOARD }, // Dashboard corresponds to root path
|
{key: '', label: t.DASHBOARD}, // Dashboard corresponds to root path
|
||||||
{ key: 'cluster', label: t.CLUSTER },
|
{key: 'cluster', label: t.CLUSTER},
|
||||||
{ key: 'topic', label: t.TOPIC },
|
{key: 'topic', label: t.TOPIC},
|
||||||
{ key: 'consumer', label: t.CONSUMER },
|
{key: 'consumer', label: t.CONSUMER},
|
||||||
{ key: 'producer', label: t.PRODUCER },
|
{key: 'producer', label: t.PRODUCER},
|
||||||
{ key: 'message', label: t.MESSAGE },
|
{key: 'message', label: t.MESSAGE},
|
||||||
{ key: 'dlqMessage', label: t.DLQ_MESSAGE },
|
{key: 'dlqMessage', label: t.DLQ_MESSAGE},
|
||||||
{ key: 'messageTrace', label: t.MESSAGETRACE },
|
{key: 'messageTrace', label: t.MESSAGETRACE},
|
||||||
...(showAcl ? [{ key: 'acl', label: t.WHITE_LIST }] : []),
|
...(showAcl ? [{key: 'acl', label: t.ACL_MANAGEMENT}] : []),
|
||||||
];
|
];
|
||||||
|
|
||||||
// Determine if it's a small screen (e.g., less than md)
|
// Determine if it's a small screen (e.g., less than md)
|
||||||
@@ -120,7 +120,7 @@ const Navbar = ({ rmqVersion = true, showAcl = true}) => {
|
|||||||
padding: isExtraSmallScreen ? '0 16px' : '0 24px', // Smaller padding on extra small screens
|
padding: isExtraSmallScreen ? '0 16px' : '0 24px', // Smaller padding on extra small screens
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<div className="navbar-left" style={{ display: 'flex', alignItems: 'center' }}>
|
<div className="navbar-left" style={{display: 'flex', alignItems: 'center'}}>
|
||||||
<div
|
<div
|
||||||
style={{
|
style={{
|
||||||
fontWeight: 'bold',
|
fontWeight: 'bold',
|
||||||
@@ -141,33 +141,33 @@ const Navbar = ({ rmqVersion = true, showAcl = true}) => {
|
|||||||
mode="horizontal"
|
mode="horizontal"
|
||||||
items={menuItems}
|
items={menuItems}
|
||||||
theme="dark" // Use dark theme to match Header background
|
theme="dark" // Use dark theme to match Header background
|
||||||
style={{ flex: 1, minWidth: 0 }} // Allow menu items to adapt width
|
style={{flex: 1, minWidth: 0}} // Allow menu items to adapt width
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<Space size={isExtraSmallScreen ? 8 : 16} > {/* Adjust spacing for buttons */}
|
<Space size={isExtraSmallScreen ? 8 : 16}> {/* Adjust spacing for buttons */}
|
||||||
{/* Theme switch button */}
|
{/* Theme switch button */}
|
||||||
<Dropdown overlay={themeMenu}>
|
<Dropdown overlay={themeMenu}>
|
||||||
<Button icon={<BgColorsOutlined />} size="small">
|
<Button icon={<BgColorsOutlined/>} size="small">
|
||||||
{!isExtraSmallScreen && `${t.TOPIC}: ${currentThemeName}`}
|
{!isExtraSmallScreen && `${t.TOPIC}: ${currentThemeName}`}
|
||||||
<DownOutlined />
|
<DownOutlined/>
|
||||||
</Button>
|
</Button>
|
||||||
</Dropdown>
|
</Dropdown>
|
||||||
<Dropdown overlay={langMenu}>
|
<Dropdown overlay={langMenu}>
|
||||||
<Button icon={<GlobalOutlined />} size="small">
|
<Button icon={<GlobalOutlined/>} size="small">
|
||||||
{!isExtraSmallScreen && t.CHANGE_LANG} {/* Hide text on extra small screens */}
|
{!isExtraSmallScreen && t.CHANGE_LANG} {/* Hide text on extra small screens */}
|
||||||
<DownOutlined />
|
<DownOutlined/>
|
||||||
</Button>
|
</Button>
|
||||||
</Dropdown>
|
</Dropdown>
|
||||||
|
|
||||||
{userName && (
|
{userName && (
|
||||||
<Dropdown overlay={userMenu}>
|
<Dropdown overlay={userMenu}>
|
||||||
{/* 使用一个可点击的元素作为 Dropdown 的唯一子元素 */}
|
{/* 使用一个可点击的元素作为 Dropdown 的唯一子元素 */}
|
||||||
<a onClick={e => e.preventDefault()} style={{ display: 'flex', alignItems: 'center' }}>
|
<a onClick={e => e.preventDefault()} style={{display: 'flex', alignItems: 'center'}}>
|
||||||
<UserOutlined style={{ marginRight: 8 }} /> {/* 添加一些间距 */}
|
<UserOutlined style={{marginRight: 8}}/> {/* 添加一些间距 */}
|
||||||
{userName}
|
{userName}
|
||||||
<DownOutlined style={{ marginLeft: 8 }} />
|
<DownOutlined style={{marginLeft: 8}}/>
|
||||||
</a>
|
</a>
|
||||||
</Dropdown>
|
</Dropdown>
|
||||||
)}
|
)}
|
||||||
@@ -175,9 +175,9 @@ const Navbar = ({ rmqVersion = true, showAcl = true}) => {
|
|||||||
{isSmallScreen && ( // Display hamburger icon on small screens
|
{isSmallScreen && ( // Display hamburger icon on small screens
|
||||||
<Button
|
<Button
|
||||||
type="primary"
|
type="primary"
|
||||||
icon={<MenuOutlined />}
|
icon={<MenuOutlined/>}
|
||||||
onClick={() => setDrawerVisible(true)}
|
onClick={() => setDrawerVisible(true)}
|
||||||
style={{ marginLeft: isExtraSmallScreen ? 8 : 16 }} // Adjust margin for hamburger icon
|
style={{marginLeft: isExtraSmallScreen ? 8 : 16}} // Adjust margin for hamburger icon
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
</Space>
|
</Space>
|
||||||
@@ -192,7 +192,7 @@ const Navbar = ({ rmqVersion = true, showAcl = true}) => {
|
|||||||
open={drawerVisible}
|
open={drawerVisible}
|
||||||
// If you want the Drawer's background to match the Menu's background color, you can set bodyStyle like this
|
// If you want the Drawer's background to match the Menu's background color, you can set bodyStyle like this
|
||||||
// or set components.Drawer.colorBgElevated in theme.js, etc.
|
// or set components.Drawer.colorBgElevated in theme.js, etc.
|
||||||
bodyStyle={{ padding: 0, backgroundColor: '#1c324a' }} // Set Drawer body background to dark
|
bodyStyle={{padding: 0, backgroundColor: '#1c324a'}} // Set Drawer body background to dark
|
||||||
width={200} // Set drawer width
|
width={200} // Set drawer width
|
||||||
>
|
>
|
||||||
<Menu
|
<Menu
|
||||||
@@ -201,7 +201,7 @@ const Navbar = ({ rmqVersion = true, showAcl = true}) => {
|
|||||||
mode="inline" // Use vertical menu in drawer
|
mode="inline" // Use vertical menu in drawer
|
||||||
items={menuItems}
|
items={menuItems}
|
||||||
theme="dark"
|
theme="dark"
|
||||||
style={{ height: '100%', borderRight: 0 }} // Ensure menu fills the drawer
|
style={{height: '100%', borderRight: 0}} // Ensure menu fills the drawer
|
||||||
/>
|
/>
|
||||||
</Drawer>
|
</Drawer>
|
||||||
</Header>
|
</Header>
|
||||||
|
@@ -15,23 +15,23 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { Input, Select, Tag, Space } from 'antd';
|
import {Input, Select, Space, Tag} from 'antd';
|
||||||
import { PlusOutlined } from '@ant-design/icons';
|
import {PlusOutlined} from '@ant-design/icons';
|
||||||
import React, { useState } from 'react';
|
import React, {useState} from 'react';
|
||||||
|
|
||||||
const { Option } = Select;
|
const {Option} = Select;
|
||||||
|
|
||||||
// 资源类型枚举
|
// 资源类型枚举
|
||||||
const resourceTypes = [
|
const resourceTypes = [
|
||||||
{ value: 0, label: 'Unknown', prefix: 'UNKNOWN' },
|
{value: 0, label: 'Unknown', prefix: 'UNKNOWN'},
|
||||||
{ value: 1, label: 'Any', prefix: 'ANY' },
|
{value: 1, label: 'Any', prefix: 'ANY'},
|
||||||
{ value: 2, label: 'Cluster', prefix: 'CLUSTER' },
|
{value: 2, label: 'Cluster', prefix: 'CLUSTER'},
|
||||||
{ value: 3, label: 'Namespace', prefix: 'NAMESPACE' },
|
{value: 3, label: 'Namespace', prefix: 'NAMESPACE'},
|
||||||
{ value: 4, label: 'Topic', prefix: 'TOPIC' },
|
{value: 4, label: 'Topic', prefix: 'TOPIC'},
|
||||||
{ value: 5, label: 'Group', prefix: 'GROUP' },
|
{value: 5, label: 'Group', prefix: 'GROUP'},
|
||||||
];
|
];
|
||||||
|
|
||||||
const ResourceInput = ({ value = [], onChange }) => {
|
const ResourceInput = ({value = [], onChange}) => {
|
||||||
// 确保 value 始终是数组
|
// 确保 value 始终是数组
|
||||||
const safeValue = Array.isArray(value) ? value : [];
|
const safeValue = Array.isArray(value) ? value : [];
|
||||||
|
|
||||||
@@ -96,7 +96,7 @@ const ResourceInput = ({ value = [], onChange }) => {
|
|||||||
<Space>
|
<Space>
|
||||||
<Select
|
<Select
|
||||||
value={selectedType}
|
value={selectedType}
|
||||||
style={{ width: 120 }}
|
style={{width: 120}}
|
||||||
onChange={handleTypeChange}
|
onChange={handleTypeChange}
|
||||||
>
|
>
|
||||||
{resourceTypes.map(type => (
|
{resourceTypes.map(type => (
|
||||||
@@ -107,7 +107,7 @@ const ResourceInput = ({ value = [], onChange }) => {
|
|||||||
</Select>
|
</Select>
|
||||||
<Input
|
<Input
|
||||||
ref={inputRef}
|
ref={inputRef}
|
||||||
style={{ width: 180 }}
|
style={{width: 180}}
|
||||||
value={resourceName}
|
value={resourceName}
|
||||||
onChange={handleNameChange}
|
onChange={handleNameChange}
|
||||||
onPressEnter={handleAddResource}
|
onPressEnter={handleAddResource}
|
||||||
@@ -116,8 +116,8 @@ const ResourceInput = ({ value = [], onChange }) => {
|
|||||||
/>
|
/>
|
||||||
</Space>
|
</Space>
|
||||||
) : (
|
) : (
|
||||||
<Tag onClick={showInput} style={{ background: '#fff', borderStyle: 'dashed' }}>
|
<Tag onClick={showInput} style={{background: '#fff', borderStyle: 'dashed'}}>
|
||||||
<PlusOutlined /> 添加资源
|
<PlusOutlined/> 添加资源
|
||||||
</Tag>
|
</Tag>
|
||||||
)}
|
)}
|
||||||
</Space>
|
</Space>
|
||||||
|
@@ -15,27 +15,27 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { Input, Select } from 'antd';
|
import {Input, Select} from 'antd';
|
||||||
import React, { useState, useEffect } from 'react';
|
import React, {useEffect, useState} from 'react';
|
||||||
|
|
||||||
const { Option } = Select;
|
const {Option} = Select;
|
||||||
|
|
||||||
// Subject 类型枚举
|
// Subject 类型枚举
|
||||||
const subjectTypes = [
|
const subjectTypes = [
|
||||||
{ value: 'User', label: 'User' },
|
{value: 'User', label: 'User'},
|
||||||
];
|
];
|
||||||
|
|
||||||
const SubjectInput = ({ value, onChange, disabled }) => {
|
const SubjectInput = ({value, onChange, disabled}) => {
|
||||||
// 解析传入的 value,将其拆分为 type 和 name
|
// 解析传入的 value,将其拆分为 type 和 name
|
||||||
const parseValue = (val) => {
|
const parseValue = (val) => {
|
||||||
if (!val || typeof val !== 'string') {
|
if (!val || typeof val !== 'string') {
|
||||||
return { type: subjectTypes[0].value, name: '' }; // 默认值
|
return {type: subjectTypes[0].value, name: ''}; // 默认值
|
||||||
}
|
}
|
||||||
const parts = val.split(':');
|
const parts = val.split(':');
|
||||||
if (parts.length === 2 && subjectTypes.some(t => t.value === parts[0])) {
|
if (parts.length === 2 && subjectTypes.some(t => t.value === parts[0])) {
|
||||||
return { type: parts[0], name: parts[1] };
|
return {type: parts[0], name: parts[1]};
|
||||||
}
|
}
|
||||||
return { type: subjectTypes[0].value, name: val }; // 如果格式不匹配,将整个值作为 name,类型设为默认
|
return {type: subjectTypes[0].value, name: val}; // 如果格式不匹配,将整个值作为 name,类型设为默认
|
||||||
};
|
};
|
||||||
|
|
||||||
const [currentType, setCurrentType] = useState(() => parseValue(value).type);
|
const [currentType, setCurrentType] = useState(() => parseValue(value).type);
|
||||||
@@ -76,7 +76,7 @@ const SubjectInput = ({ value, onChange, disabled }) => {
|
|||||||
return (
|
return (
|
||||||
<Input.Group compact>
|
<Input.Group compact>
|
||||||
<Select
|
<Select
|
||||||
style={{ width: '30%' }}
|
style={{width: '30%'}}
|
||||||
value={currentType}
|
value={currentType}
|
||||||
onChange={onTypeChange}
|
onChange={onTypeChange}
|
||||||
disabled={disabled}
|
disabled={disabled}
|
||||||
@@ -88,7 +88,7 @@ const SubjectInput = ({ value, onChange, disabled }) => {
|
|||||||
))}
|
))}
|
||||||
</Select>
|
</Select>
|
||||||
<Input
|
<Input
|
||||||
style={{ width: '70%' }}
|
style={{width: '70%'}}
|
||||||
value={currentName}
|
value={currentName}
|
||||||
onChange={onNameChange}
|
onChange={onNameChange}
|
||||||
placeholder="请输入名称 (例如: yourUsername)"
|
placeholder="请输入名称 (例如: yourUsername)"
|
||||||
|
@@ -15,13 +15,13 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import React, { useState, useEffect } from 'react';
|
import React, {useEffect, useState} from 'react';
|
||||||
import { Modal, Table, Spin } from 'antd';
|
import {Modal, Spin, Table} from 'antd';
|
||||||
import { remoteApi } from '../../api/remoteApi/remoteApi';
|
import {remoteApi} from '../../api/remoteApi/remoteApi';
|
||||||
import { useLanguage } from '../../i18n/LanguageContext';
|
import {useLanguage} from '../../i18n/LanguageContext';
|
||||||
|
|
||||||
const ClientInfoModal = ({ visible, group, address, onCancel }) => {
|
const ClientInfoModal = ({visible, group, address, onCancel}) => {
|
||||||
const { t } = useLanguage();
|
const {t} = useLanguage();
|
||||||
const [loading, setLoading] = useState(false);
|
const [loading, setLoading] = useState(false);
|
||||||
const [connectionData, setConnectionData] = useState(null);
|
const [connectionData, setConnectionData] = useState(null);
|
||||||
const [subscriptionData, setSubscriptionData] = useState(null);
|
const [subscriptionData, setSubscriptionData] = useState(null);
|
||||||
@@ -46,15 +46,15 @@ const ClientInfoModal = ({ visible, group, address, onCancel }) => {
|
|||||||
}, [visible, group, address]);
|
}, [visible, group, address]);
|
||||||
|
|
||||||
const connectionColumns = [
|
const connectionColumns = [
|
||||||
{ title: 'ClientId', dataIndex: 'clientId' },
|
{title: 'ClientId', dataIndex: 'clientId'},
|
||||||
{ title: 'ClientAddr', dataIndex: 'clientAddr' },
|
{title: 'ClientAddr', dataIndex: 'clientAddr'},
|
||||||
{ title: 'Language', dataIndex: 'language' },
|
{title: 'Language', dataIndex: 'language'},
|
||||||
{ title: 'Version', dataIndex: 'versionDesc' },
|
{title: 'Version', dataIndex: 'versionDesc'},
|
||||||
];
|
];
|
||||||
|
|
||||||
const subscriptionColumns = [
|
const subscriptionColumns = [
|
||||||
{ title: 'Topic', dataIndex: 'topic' },
|
{title: 'Topic', dataIndex: 'topic'},
|
||||||
{ title: 'SubExpression', dataIndex: 'subString' },
|
{title: 'SubExpression', dataIndex: 'subString'},
|
||||||
];
|
];
|
||||||
|
|
||||||
return (
|
return (
|
||||||
@@ -88,7 +88,7 @@ const ClientInfoModal = ({ visible, group, address, onCancel }) => {
|
|||||||
rowKey="topic"
|
rowKey="topic"
|
||||||
pagination={false}
|
pagination={false}
|
||||||
locale={{
|
locale={{
|
||||||
emptyText: loading ? <Spin size="small" /> : t.NO_DATA
|
emptyText: loading ? <Spin size="small"/> : t.NO_DATA
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
<p>ConsumeType: {connectionData.consumeType}</p>
|
<p>ConsumeType: {connectionData.consumeType}</p>
|
||||||
|
@@ -15,13 +15,23 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import React, { useEffect, useState } from 'react';
|
import React, {useEffect, useState} from 'react';
|
||||||
import { Button, Descriptions, Form, Input, Select, Switch, message } from 'antd';
|
import {Button, Descriptions, Form, Input, message, Select, Switch} from 'antd';
|
||||||
import { remoteApi } from '../../api/remoteApi/remoteApi'; // 确保路径正确
|
import {remoteApi} from '../../api/remoteApi/remoteApi'; // 确保路径正确
|
||||||
|
|
||||||
const { Option } = Select;
|
const {Option} = Select;
|
||||||
|
|
||||||
const ConsumerConfigItem = ({ initialConfig, isAddConfig, group, brokerName, allBrokerList, allClusterNames,onCancel, onSuccess, t }) => {
|
const ConsumerConfigItem = ({
|
||||||
|
initialConfig,
|
||||||
|
isAddConfig,
|
||||||
|
group,
|
||||||
|
brokerName,
|
||||||
|
allBrokerList,
|
||||||
|
allClusterNames,
|
||||||
|
onCancel,
|
||||||
|
onSuccess,
|
||||||
|
t
|
||||||
|
}) => {
|
||||||
const [form] = Form.useForm();
|
const [form] = Form.useForm();
|
||||||
const [currentBrokerName, setCurrentBrokerName] = useState(brokerName);
|
const [currentBrokerName, setCurrentBrokerName] = useState(brokerName);
|
||||||
|
|
||||||
|
@@ -34,7 +34,7 @@ const ConsumerConfigModal = ({visible, isAddConfig, group, onCancel, setIsAddCon
|
|||||||
setLoading(true);
|
setLoading(true);
|
||||||
try {
|
try {
|
||||||
// Fetch cluster list for broker names and cluster names
|
// Fetch cluster list for broker names and cluster names
|
||||||
if(isAddConfig) {
|
if (isAddConfig) {
|
||||||
const clusterResponse = await remoteApi.getClusterList();
|
const clusterResponse = await remoteApi.getClusterList();
|
||||||
if (clusterResponse.status === 0 && clusterResponse.data) {
|
if (clusterResponse.status === 0 && clusterResponse.data) {
|
||||||
const clusterInfo = clusterResponse.data.clusterInfo;
|
const clusterInfo = clusterResponse.data.clusterInfo;
|
||||||
|
@@ -15,13 +15,13 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import React, { useState, useEffect } from 'react';
|
import React, {useEffect, useState} from 'react';
|
||||||
import { Modal, Table, Spin } from 'antd';
|
import {Modal, Spin, Table} from 'antd';
|
||||||
import { remoteApi } from '../../api/remoteApi/remoteApi';
|
import {remoteApi} from '../../api/remoteApi/remoteApi';
|
||||||
import { useLanguage } from '../../i18n/LanguageContext';
|
import {useLanguage} from '../../i18n/LanguageContext';
|
||||||
|
|
||||||
const ConsumerDetailModal = ({ visible, group, address, onCancel }) => {
|
const ConsumerDetailModal = ({visible, group, address, onCancel}) => {
|
||||||
const { t } = useLanguage();
|
const {t} = useLanguage();
|
||||||
const [loading, setLoading] = useState(false);
|
const [loading, setLoading] = useState(false);
|
||||||
const [details, setDetails] = useState([]);
|
const [details, setDetails] = useState([]);
|
||||||
|
|
||||||
@@ -44,12 +44,12 @@ const ConsumerDetailModal = ({ visible, group, address, onCancel }) => {
|
|||||||
}, [visible, group, address]);
|
}, [visible, group, address]);
|
||||||
|
|
||||||
const queueColumns = [
|
const queueColumns = [
|
||||||
{ title: 'Broker', dataIndex: 'brokerName' },
|
{title: 'Broker', dataIndex: 'brokerName'},
|
||||||
{ title: 'Queue', dataIndex: 'queueId' },
|
{title: 'Queue', dataIndex: 'queueId'},
|
||||||
{ title: 'BrokerOffset', dataIndex: 'brokerOffset' },
|
{title: 'BrokerOffset', dataIndex: 'brokerOffset'},
|
||||||
{ title: 'ConsumerOffset', dataIndex: 'consumerOffset' },
|
{title: 'ConsumerOffset', dataIndex: 'consumerOffset'},
|
||||||
{ title: 'DiffTotal', dataIndex: 'diffTotal' },
|
{title: 'DiffTotal', dataIndex: 'diffTotal'},
|
||||||
{ title: 'LastTimestamp', dataIndex: 'lastTimestamp' },
|
{title: 'LastTimestamp', dataIndex: 'lastTimestamp'},
|
||||||
];
|
];
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
@@ -15,13 +15,13 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import React, { useState, useEffect } from 'react';
|
import React, {useEffect, useState} from 'react';
|
||||||
import { Modal, Spin, Checkbox, Button, notification } from 'antd';
|
import {Button, Checkbox, Modal, notification, Spin} from 'antd';
|
||||||
import { remoteApi } from '../../api/remoteApi/remoteApi';
|
import {remoteApi} from '../../api/remoteApi/remoteApi';
|
||||||
import { useLanguage } from '../../i18n/LanguageContext';
|
import {useLanguage} from '../../i18n/LanguageContext';
|
||||||
|
|
||||||
const DeleteConsumerModal = ({ visible, group, onCancel, onSuccess }) => {
|
const DeleteConsumerModal = ({visible, group, onCancel, onSuccess}) => {
|
||||||
const { t } = useLanguage();
|
const {t} = useLanguage();
|
||||||
const [brokerList, setBrokerList] = useState([]);
|
const [brokerList, setBrokerList] = useState([]);
|
||||||
const [selectedBrokers, setSelectedBrokers] = useState([]);
|
const [selectedBrokers, setSelectedBrokers] = useState([]);
|
||||||
const [loading, setLoading] = useState(false);
|
const [loading, setLoading] = useState(false);
|
||||||
@@ -48,7 +48,7 @@ const DeleteConsumerModal = ({ visible, group, onCancel, onSuccess }) => {
|
|||||||
// 处理删除提交
|
// 处理删除提交
|
||||||
const handleDelete = async () => {
|
const handleDelete = async () => {
|
||||||
if (selectedBrokers.length === 0) {
|
if (selectedBrokers.length === 0) {
|
||||||
notification.warning({ message: t.PLEASE_SELECT_BROKER });
|
notification.warning({message: t.PLEASE_SELECT_BROKER});
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -60,7 +60,7 @@ const DeleteConsumerModal = ({ visible, group, onCancel, onSuccess }) => {
|
|||||||
);
|
);
|
||||||
|
|
||||||
if (response.status === 0) {
|
if (response.status === 0) {
|
||||||
notification.success({ message: t.DELETE_SUCCESS });
|
notification.success({message: t.DELETE_SUCCESS});
|
||||||
onSuccess();
|
onSuccess();
|
||||||
onCancel();
|
onCancel();
|
||||||
}
|
}
|
||||||
@@ -90,9 +90,9 @@ const DeleteConsumerModal = ({ visible, group, onCancel, onSuccess }) => {
|
|||||||
]}
|
]}
|
||||||
>
|
>
|
||||||
<Spin spinning={loading}>
|
<Spin spinning={loading}>
|
||||||
<div style={{ marginBottom: 16 }}>{t.SELECT_DELETE_BROKERS}:</div>
|
<div style={{marginBottom: 16}}>{t.SELECT_DELETE_BROKERS}:</div>
|
||||||
<Checkbox.Group
|
<Checkbox.Group
|
||||||
style={{ width: '100%' }}
|
style={{width: '100%'}}
|
||||||
value={selectedBrokers}
|
value={selectedBrokers}
|
||||||
onChange={values => setSelectedBrokers(values)}
|
onChange={values => setSelectedBrokers(values)}
|
||||||
>
|
>
|
||||||
|
@@ -15,10 +15,10 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { Button, DatePicker, Form, Modal, Select } from "antd";
|
import {Button, DatePicker, Form, Modal, Select} from "antd";
|
||||||
import React, { useEffect, useState } from "react";
|
import React, {useEffect, useState} from "react";
|
||||||
|
|
||||||
const ConsumerResetOffsetDialog = ({ visible, onClose, topic, allConsumerGroupList, handleResetOffset, t }) => {
|
const ConsumerResetOffsetDialog = ({visible, onClose, topic, allConsumerGroupList, handleResetOffset, t}) => {
|
||||||
const [form] = Form.useForm();
|
const [form] = Form.useForm();
|
||||||
const [selectedConsumerGroup, setSelectedConsumerGroup] = useState([]);
|
const [selectedConsumerGroup, setSelectedConsumerGroup] = useState([]);
|
||||||
const [selectedTime, setSelectedTime] = useState(null);
|
const [selectedTime, setSelectedTime] = useState(null);
|
||||||
@@ -49,14 +49,14 @@ const ConsumerResetOffsetDialog = ({ visible, onClose, topic, allConsumerGroupLi
|
|||||||
</Button>,
|
</Button>,
|
||||||
]}
|
]}
|
||||||
>
|
>
|
||||||
<Form form={form} layout="horizontal" labelCol={{ span: 6 }} wrapperCol={{ span: 18 }}>
|
<Form form={form} layout="horizontal" labelCol={{span: 6}} wrapperCol={{span: 18}}>
|
||||||
<Form.Item label={t.SUBSCRIPTION_GROUP} required>
|
<Form.Item label={t.SUBSCRIPTION_GROUP} required>
|
||||||
<Select
|
<Select
|
||||||
mode="multiple"
|
mode="multiple"
|
||||||
placeholder={t.SELECT_CONSUMER_GROUP}
|
placeholder={t.SELECT_CONSUMER_GROUP}
|
||||||
value={selectedConsumerGroup}
|
value={selectedConsumerGroup}
|
||||||
onChange={setSelectedConsumerGroup}
|
onChange={setSelectedConsumerGroup}
|
||||||
options={allConsumerGroupList.map(group => ({ value: group, label: group }))}
|
options={allConsumerGroupList.map(group => ({value: group, label: group}))}
|
||||||
/>
|
/>
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
<Form.Item label={t.TIME} required>
|
<Form.Item label={t.TIME} required>
|
||||||
@@ -65,7 +65,7 @@ const ConsumerResetOffsetDialog = ({ visible, onClose, topic, allConsumerGroupLi
|
|||||||
format="YYYY-MM-DD HH:mm:ss"
|
format="YYYY-MM-DD HH:mm:ss"
|
||||||
value={selectedTime}
|
value={selectedTime}
|
||||||
onChange={setSelectedTime}
|
onChange={setSelectedTime}
|
||||||
style={{ width: '100%' }}
|
style={{width: '100%'}}
|
||||||
/>
|
/>
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
</Form>
|
</Form>
|
||||||
|
@@ -19,13 +19,13 @@ import moment from "moment/moment";
|
|||||||
import {Button, Modal, Table} from "antd";
|
import {Button, Modal, Table} from "antd";
|
||||||
import React from "react";
|
import React from "react";
|
||||||
|
|
||||||
const ConsumerViewDialog = ({ visible, onClose, topic, consumerData, consumerGroupCount, t }) => {
|
const ConsumerViewDialog = ({visible, onClose, topic, consumerData, consumerGroupCount, t}) => {
|
||||||
const columns = [
|
const columns = [
|
||||||
{ title: t.BROKER, dataIndex: 'brokerName', key: 'brokerName', align: 'center' },
|
{title: t.BROKER, dataIndex: 'brokerName', key: 'brokerName', align: 'center'},
|
||||||
{ title: t.QUEUE, dataIndex: 'queueId', key: 'queueId', align: 'center' },
|
{title: t.QUEUE, dataIndex: 'queueId', key: 'queueId', align: 'center'},
|
||||||
{ title: t.CONSUMER_CLIENT, dataIndex: 'clientInfo', key: 'clientInfo', align: 'center' },
|
{title: t.CONSUMER_CLIENT, dataIndex: 'clientInfo', key: 'clientInfo', align: 'center'},
|
||||||
{ title: t.BROKER_OFFSET, dataIndex: 'brokerOffset', key: 'brokerOffset', align: 'center' },
|
{title: t.BROKER_OFFSET, dataIndex: 'brokerOffset', key: 'brokerOffset', align: 'center'},
|
||||||
{ title: t.CONSUMER_OFFSET, dataIndex: 'consumerOffset', key: 'consumerOffset', align: 'center' },
|
{title: t.CONSUMER_OFFSET, dataIndex: 'consumerOffset', key: 'consumerOffset', align: 'center'},
|
||||||
{
|
{
|
||||||
title: t.DIFF_TOTAL,
|
title: t.DIFF_TOTAL,
|
||||||
dataIndex: 'diffTotal',
|
dataIndex: 'diffTotal',
|
||||||
@@ -58,15 +58,19 @@ const ConsumerViewDialog = ({ visible, onClose, topic, consumerData, consumerGro
|
|||||||
<div>{t.NO_DATA} {t.SUBSCRIPTION_GROUP}</div>
|
<div>{t.NO_DATA} {t.SUBSCRIPTION_GROUP}</div>
|
||||||
) : (
|
) : (
|
||||||
consumerData && Object.entries(consumerData).map(([consumerGroup, consumeDetail]) => (
|
consumerData && Object.entries(consumerData).map(([consumerGroup, consumeDetail]) => (
|
||||||
<div key={consumerGroup} style={{ marginBottom: '24px' }}>
|
<div key={consumerGroup} style={{marginBottom: '24px'}}>
|
||||||
<Table
|
<Table
|
||||||
bordered
|
bordered
|
||||||
pagination={false}
|
pagination={false}
|
||||||
showHeader={false}
|
showHeader={false}
|
||||||
dataSource={[{ consumerGroup, diffTotal: consumeDetail.diffTotal, lastTimestamp: consumeDetail.lastTimestamp }]}
|
dataSource={[{
|
||||||
|
consumerGroup,
|
||||||
|
diffTotal: consumeDetail.diffTotal,
|
||||||
|
lastTimestamp: consumeDetail.lastTimestamp
|
||||||
|
}]}
|
||||||
columns={[
|
columns={[
|
||||||
{ title: t.SUBSCRIPTION_GROUP, dataIndex: 'consumerGroup', key: 'consumerGroup' },
|
{title: t.SUBSCRIPTION_GROUP, dataIndex: 'consumerGroup', key: 'consumerGroup'},
|
||||||
{ title: t.DELAY, dataIndex: 'diffTotal', key: 'diffTotal' },
|
{title: t.DELAY, dataIndex: 'diffTotal', key: 'diffTotal'},
|
||||||
{
|
{
|
||||||
title: t.LAST_CONSUME_TIME,
|
title: t.LAST_CONSUME_TIME,
|
||||||
dataIndex: 'lastTimestamp',
|
dataIndex: 'lastTimestamp',
|
||||||
@@ -76,7 +80,7 @@ const ConsumerViewDialog = ({ visible, onClose, topic, consumerData, consumerGro
|
|||||||
]}
|
]}
|
||||||
rowKey="consumerGroup"
|
rowKey="consumerGroup"
|
||||||
size="small"
|
size="small"
|
||||||
style={{ marginBottom: '12px' }}
|
style={{marginBottom: '12px'}}
|
||||||
/>
|
/>
|
||||||
<Table
|
<Table
|
||||||
bordered
|
bordered
|
||||||
|
@@ -18,7 +18,7 @@
|
|||||||
import {Button, Modal, Table} from "antd";
|
import {Button, Modal, Table} from "antd";
|
||||||
import React from "react";
|
import React from "react";
|
||||||
|
|
||||||
const ResetOffsetResultDialog = ({ visible, onClose, result, t }) => {
|
const ResetOffsetResultDialog = ({visible, onClose, result, t}) => {
|
||||||
return (
|
return (
|
||||||
<Modal
|
<Modal
|
||||||
title="ResetResult"
|
title="ResetResult"
|
||||||
@@ -31,12 +31,12 @@ const ResetOffsetResultDialog = ({ visible, onClose, result, t }) => {
|
|||||||
]}
|
]}
|
||||||
>
|
>
|
||||||
{result && Object.entries(result).map(([groupName, groupData]) => (
|
{result && Object.entries(result).map(([groupName, groupData]) => (
|
||||||
<div key={groupName} style={{ marginBottom: '16px', border: '1px solid #f0f0f0', padding: '10px' }}>
|
<div key={groupName} style={{marginBottom: '16px', border: '1px solid #f0f0f0', padding: '10px'}}>
|
||||||
<Table
|
<Table
|
||||||
dataSource={[{ groupName, status: groupData.status }]}
|
dataSource={[{groupName, status: groupData.status}]}
|
||||||
columns={[
|
columns={[
|
||||||
{ title: 'GroupName', dataIndex: 'groupName', key: 'groupName' },
|
{title: 'GroupName', dataIndex: 'groupName', key: 'groupName'},
|
||||||
{ title: 'State', dataIndex: 'status', key: 'status' },
|
{title: 'State', dataIndex: 'status', key: 'status'},
|
||||||
]}
|
]}
|
||||||
pagination={false}
|
pagination={false}
|
||||||
rowKey="groupName"
|
rowKey="groupName"
|
||||||
@@ -47,8 +47,8 @@ const ResetOffsetResultDialog = ({ visible, onClose, result, t }) => {
|
|||||||
<div>You Should Check It Yourself</div>
|
<div>You Should Check It Yourself</div>
|
||||||
) : (
|
) : (
|
||||||
<Table
|
<Table
|
||||||
dataSource={groupData.rollbackStatsList.map((item, index) => ({ key: index, item }))}
|
dataSource={groupData.rollbackStatsList.map((item, index) => ({key: index, item}))}
|
||||||
columns={[{ dataIndex: 'item', key: 'item' }]}
|
columns={[{dataIndex: 'item', key: 'item'}]}
|
||||||
pagination={false}
|
pagination={false}
|
||||||
rowKey="key"
|
rowKey="key"
|
||||||
size="small"
|
size="small"
|
||||||
|
@@ -15,10 +15,10 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { Button, Modal, Table } from "antd";
|
import {Button, Modal, Table} from "antd";
|
||||||
import React from "react";
|
import React from "react";
|
||||||
|
|
||||||
const RouterViewDialog = ({ visible, onClose, topic, routeData, t }) => {
|
const RouterViewDialog = ({visible, onClose, topic, routeData, t}) => {
|
||||||
const brokerColumns = [
|
const brokerColumns = [
|
||||||
{
|
{
|
||||||
title: 'Broker',
|
title: 'Broker',
|
||||||
@@ -30,10 +30,14 @@ const RouterViewDialog = ({ visible, onClose, topic, routeData, t }) => {
|
|||||||
key: 'brokerAddrs',
|
key: 'brokerAddrs',
|
||||||
render: (_, record) => (
|
render: (_, record) => (
|
||||||
<Table
|
<Table
|
||||||
dataSource={Object.entries(record.brokerAddrs || []).map(([key, value]) => ({ key, idx: key, address: value }))}
|
dataSource={Object.entries(record.brokerAddrs || []).map(([key, value]) => ({
|
||||||
|
key,
|
||||||
|
idx: key,
|
||||||
|
address: value
|
||||||
|
}))}
|
||||||
columns={[
|
columns={[
|
||||||
{ title: 'Index', dataIndex: 'idx', key: 'idx' },
|
{title: 'Index', dataIndex: 'idx', key: 'idx'},
|
||||||
{ title: 'Address', dataIndex: 'address', key: 'address' },
|
{title: 'Address', dataIndex: 'address', key: 'address'},
|
||||||
]}
|
]}
|
||||||
pagination={false}
|
pagination={false}
|
||||||
bordered
|
bordered
|
||||||
@@ -82,7 +86,7 @@ const RouterViewDialog = ({ visible, onClose, topic, routeData, t }) => {
|
|||||||
<div>
|
<div>
|
||||||
<h3>Broker Datas:</h3>
|
<h3>Broker Datas:</h3>
|
||||||
{routeData?.brokerDatas?.map((item, index) => (
|
{routeData?.brokerDatas?.map((item, index) => (
|
||||||
<div key={index} style={{ marginBottom: '15px', border: '1px solid #d9d9d9', padding: '10px' }}>
|
<div key={index} style={{marginBottom: '15px', border: '1px solid #d9d9d9', padding: '10px'}}>
|
||||||
<Table
|
<Table
|
||||||
dataSource={[item]}
|
dataSource={[item]}
|
||||||
columns={brokerColumns}
|
columns={brokerColumns}
|
||||||
@@ -93,7 +97,7 @@ const RouterViewDialog = ({ visible, onClose, topic, routeData, t }) => {
|
|||||||
</div>
|
</div>
|
||||||
))}
|
))}
|
||||||
</div>
|
</div>
|
||||||
<div style={{ marginTop: '20px' }}>
|
<div style={{marginTop: '20px'}}>
|
||||||
<h3>{t.QUEUE_DATAS}:</h3>
|
<h3>{t.QUEUE_DATAS}:</h3>
|
||||||
<Table
|
<Table
|
||||||
dataSource={routeData?.queueDatas || []}
|
dataSource={routeData?.queueDatas || []}
|
||||||
|
@@ -18,7 +18,7 @@
|
|||||||
import {Button, Form, Modal, Table} from "antd";
|
import {Button, Form, Modal, Table} from "antd";
|
||||||
import React from "react";
|
import React from "react";
|
||||||
|
|
||||||
const SendResultDialog = ({ visible, onClose, result, t }) => {
|
const SendResultDialog = ({visible, onClose, result, t}) => {
|
||||||
return (
|
return (
|
||||||
<Modal
|
<Modal
|
||||||
title="SendResult"
|
title="SendResult"
|
||||||
@@ -43,11 +43,11 @@ const SendResultDialog = ({ visible, onClose, result, t }) => {
|
|||||||
: []
|
: []
|
||||||
}
|
}
|
||||||
columns={[
|
columns={[
|
||||||
{ dataIndex: 'label', key: 'label' },
|
{dataIndex: 'label', key: 'label'},
|
||||||
{
|
{
|
||||||
dataIndex: 'value',
|
dataIndex: 'value',
|
||||||
key: 'value',
|
key: 'value',
|
||||||
render: (text) => <pre style={{ whiteSpace: 'pre-wrap', margin: 0 }}>{text}</pre>,
|
render: (text) => <pre style={{whiteSpace: 'pre-wrap', margin: 0}}>{text}</pre>,
|
||||||
},
|
},
|
||||||
]}
|
]}
|
||||||
pagination={false}
|
pagination={false}
|
||||||
@@ -61,5 +61,4 @@ const SendResultDialog = ({ visible, onClose, result, t }) => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
export default SendResultDialog;
|
export default SendResultDialog;
|
||||||
|
@@ -76,24 +76,24 @@ const SendTopicMessageDialog = ({
|
|||||||
</Button>,
|
</Button>,
|
||||||
]}
|
]}
|
||||||
>
|
>
|
||||||
<Form form={form} layout="horizontal" labelCol={{ span: 6 }} wrapperCol={{ span: 18 }}>
|
<Form form={form} layout="horizontal" labelCol={{span: 6}} wrapperCol={{span: 18}}>
|
||||||
<Form.Item label={t.TOPIC} name="topic">
|
<Form.Item label={t.TOPIC} name="topic">
|
||||||
<Input disabled />
|
<Input disabled/>
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
<Form.Item label={t.TAG} name="tag">
|
<Form.Item label={t.TAG} name="tag">
|
||||||
<Input />
|
<Input/>
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
<Form.Item label={t.KEY} name="key">
|
<Form.Item label={t.KEY} name="key">
|
||||||
<Input />
|
<Input/>
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
<Form.Item label={t.MESSAGE_BODY} name="messageBody" rules={[{ required: true, message: t.REQUIRED }]}>
|
<Form.Item label={t.MESSAGE_BODY} name="messageBody" rules={[{required: true, message: t.REQUIRED}]}>
|
||||||
<Input.TextArea
|
<Input.TextArea
|
||||||
style={{ maxHeight: '200px', minHeight: '200px', resize: 'none' }}
|
style={{maxHeight: '200px', minHeight: '200px', resize: 'none'}}
|
||||||
rows={8}
|
rows={8}
|
||||||
/>
|
/>
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
<Form.Item label={t.ENABLE_MESSAGE_TRACE} name="traceEnabled" valuePropName="checked">
|
<Form.Item label={t.ENABLE_MESSAGE_TRACE} name="traceEnabled" valuePropName="checked">
|
||||||
<Checkbox />
|
<Checkbox/>
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
</Form>
|
</Form>
|
||||||
</Modal>
|
</Modal>
|
||||||
|
@@ -15,10 +15,17 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { Button, Form, message, Modal, Select } from "antd";
|
import {Button, Form, message, Modal, Select} from "antd";
|
||||||
import React, { useEffect, useState } from "react";
|
import React, {useEffect, useState} from "react";
|
||||||
|
|
||||||
const SkipMessageAccumulateDialog = ({ visible, onClose, topic, allConsumerGroupList, handleSkipMessageAccumulate, t }) => {
|
const SkipMessageAccumulateDialog = ({
|
||||||
|
visible,
|
||||||
|
onClose,
|
||||||
|
topic,
|
||||||
|
allConsumerGroupList,
|
||||||
|
handleSkipMessageAccumulate,
|
||||||
|
t
|
||||||
|
}) => {
|
||||||
const [form] = Form.useForm();
|
const [form] = Form.useForm();
|
||||||
const [selectedConsumerGroup, setSelectedConsumerGroup] = useState([]);
|
const [selectedConsumerGroup, setSelectedConsumerGroup] = useState([]);
|
||||||
|
|
||||||
@@ -52,14 +59,14 @@ const SkipMessageAccumulateDialog = ({ visible, onClose, topic, allConsumerGroup
|
|||||||
</Button>,
|
</Button>,
|
||||||
]}
|
]}
|
||||||
>
|
>
|
||||||
<Form form={form} layout="horizontal" labelCol={{ span: 6 }} wrapperCol={{ span: 18 }}>
|
<Form form={form} layout="horizontal" labelCol={{span: 6}} wrapperCol={{span: 18}}>
|
||||||
<Form.Item label={t.SUBSCRIPTION_GROUP} required>
|
<Form.Item label={t.SUBSCRIPTION_GROUP} required>
|
||||||
<Select
|
<Select
|
||||||
mode="multiple"
|
mode="multiple"
|
||||||
placeholder={t.SELECT_CONSUMER_GROUP}
|
placeholder={t.SELECT_CONSUMER_GROUP}
|
||||||
value={selectedConsumerGroup}
|
value={selectedConsumerGroup}
|
||||||
onChange={setSelectedConsumerGroup}
|
onChange={setSelectedConsumerGroup}
|
||||||
options={allConsumerGroupList.map(group => ({ value: group, label: group }))}
|
options={allConsumerGroupList.map(group => ({value: group, label: group}))}
|
||||||
/>
|
/>
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
</Form>
|
</Form>
|
||||||
|
@@ -19,11 +19,11 @@ import moment from "moment/moment";
|
|||||||
import {Button, Modal, Table} from "antd";
|
import {Button, Modal, Table} from "antd";
|
||||||
import React from "react";
|
import React from "react";
|
||||||
|
|
||||||
const StatsViewDialog = ({ visible, onClose, topic, statsData, t }) => {
|
const StatsViewDialog = ({visible, onClose, topic, statsData, t}) => {
|
||||||
const columns = [
|
const columns = [
|
||||||
{ title: t.QUEUE, dataIndex: 'queue', key: 'queue', align: 'center' },
|
{title: t.QUEUE, dataIndex: 'queue', key: 'queue', align: 'center'},
|
||||||
{ title: t.MIN_OFFSET, dataIndex: 'minOffset', key: 'minOffset', align: 'center' },
|
{title: t.MIN_OFFSET, dataIndex: 'minOffset', key: 'minOffset', align: 'center'},
|
||||||
{ title: t.MAX_OFFSET, dataIndex: 'maxOffset', key: 'maxOffset', align: 'center' },
|
{title: t.MAX_OFFSET, dataIndex: 'maxOffset', key: 'maxOffset', align: 'center'},
|
||||||
{
|
{
|
||||||
title: t.LAST_UPDATE_TIME_STAMP,
|
title: t.LAST_UPDATE_TIME_STAMP,
|
||||||
dataIndex: 'lastUpdateTimestamp',
|
dataIndex: 'lastUpdateTimestamp',
|
||||||
|
@@ -16,7 +16,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
// TopicModifyDialog.js
|
// TopicModifyDialog.js
|
||||||
import { Button, Modal } from "antd";
|
import {Button, Modal} from "antd";
|
||||||
import React from "react";
|
import React from "react";
|
||||||
import TopicSingleModifyForm from './TopicSingleModifyForm';
|
import TopicSingleModifyForm from './TopicSingleModifyForm';
|
||||||
|
|
||||||
@@ -43,7 +43,7 @@ const TopicModifyDialog = ({
|
|||||||
{t.CLOSE}
|
{t.CLOSE}
|
||||||
</Button>,
|
</Button>,
|
||||||
]}
|
]}
|
||||||
Style={{ maxHeight: '70vh', overflowY: 'auto' }}
|
Style={{maxHeight: '70vh', overflowY: 'auto'}}
|
||||||
>
|
>
|
||||||
{initialData.map((data, index) => (
|
{initialData.map((data, index) => (
|
||||||
<TopicSingleModifyForm
|
<TopicSingleModifyForm
|
||||||
|
@@ -16,8 +16,8 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
// TopicSingleModifyForm.js
|
// TopicSingleModifyForm.js
|
||||||
import React, { useEffect } from "react";
|
import React, {useEffect} from "react";
|
||||||
import {Button, Form, Input, Select, Divider, Row, Col} from "antd";
|
import {Button, Col, Divider, Form, Input, Row, Select} from "antd";
|
||||||
|
|
||||||
const TopicSingleModifyForm = ({
|
const TopicSingleModifyForm = ({
|
||||||
initialData,
|
initialData,
|
||||||
@@ -42,9 +42,9 @@ const TopicSingleModifyForm = ({
|
|||||||
const handleFormSubmit = () => {
|
const handleFormSubmit = () => {
|
||||||
form.validateFields()
|
form.validateFields()
|
||||||
.then(values => {
|
.then(values => {
|
||||||
const updatedValues = { ...values };
|
const updatedValues = {...values};
|
||||||
// 提交时,如果 clusterNameList 或 brokerNameList 为空,则填充所有可用的名称
|
// 提交时,如果 clusterNameList 或 brokerNameList 为空,则填充所有可用的名称
|
||||||
if(!bIsUpdate){
|
if (!bIsUpdate) {
|
||||||
if (!updatedValues.clusterNameList || updatedValues.clusterNameList.length === 0) {
|
if (!updatedValues.clusterNameList || updatedValues.clusterNameList.length === 0) {
|
||||||
updatedValues.clusterNameList = allClusterNameList;
|
updatedValues.clusterNameList = allClusterNameList;
|
||||||
}
|
}
|
||||||
@@ -60,84 +60,85 @@ const TopicSingleModifyForm = ({
|
|||||||
};
|
};
|
||||||
|
|
||||||
const messageTypeOptions = [
|
const messageTypeOptions = [
|
||||||
{ value: 'TRANSACTION', label: 'TRANSACTION' },
|
{value: 'TRANSACTION', label: 'TRANSACTION'},
|
||||||
{ value: 'FIFO', label: 'FIFO' },
|
{value: 'FIFO', label: 'FIFO'},
|
||||||
{ value: 'DELAY', label: 'DELAY' },
|
{value: 'DELAY', label: 'DELAY'},
|
||||||
{ value: 'NORMAL', label: 'NORMAL' },
|
{value: 'NORMAL', label: 'NORMAL'},
|
||||||
];
|
];
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div style={{ paddingBottom: 24 }}>
|
<div style={{paddingBottom: 24}}>
|
||||||
{bIsUpdate && <Divider orientation="left">{`${t.TOPIC_CONFIG} - ${initialData.brokerNameList ? initialData.brokerNameList.join(', ') : t.UNKNOWN_BROKER}`}</Divider>}
|
{bIsUpdate && <Divider
|
||||||
<Row justify="center"> {/* 使用 Row 居中内容 */}
|
orientation="left">{`${t.TOPIC_CONFIG} - ${initialData.brokerNameList ? initialData.brokerNameList.join(', ') : t.UNKNOWN_BROKER}`}</Divider>}
|
||||||
<Col span={16}> {/* 表单内容占据 12 栅格宽度,并自动居中 */}
|
<Row justify="center"> {/* 使用 Row 居中内容 */}
|
||||||
<Form
|
<Col span={16}> {/* 表单内容占据 12 栅格宽度,并自动居中 */}
|
||||||
form={form}
|
<Form
|
||||||
layout="horizontal"
|
form={form}
|
||||||
labelCol={{ span: 8 }}
|
layout="horizontal"
|
||||||
wrapperCol={{ span: 16 }}
|
labelCol={{span: 8}}
|
||||||
|
wrapperCol={{span: 16}}
|
||||||
|
>
|
||||||
|
<Form.Item label={t.CLUSTER_NAME} name="clusterNameList">
|
||||||
|
<Select
|
||||||
|
mode="multiple"
|
||||||
|
disabled={bIsUpdate}
|
||||||
|
placeholder={t.SELECT_CLUSTER_NAME}
|
||||||
|
options={allClusterNameList.map(name => ({value: name, label: name}))}
|
||||||
|
/>
|
||||||
|
</Form.Item>
|
||||||
|
<Form.Item label="BROKER_NAME" name="brokerNameList">
|
||||||
|
<Select
|
||||||
|
mode="multiple"
|
||||||
|
disabled={bIsUpdate}
|
||||||
|
placeholder={t.SELECT_BROKER_NAME}
|
||||||
|
options={allBrokerNameList.map(name => ({value: name, label: name}))}
|
||||||
|
/>
|
||||||
|
</Form.Item>
|
||||||
|
<Form.Item
|
||||||
|
label={t.TOPIC_NAME}
|
||||||
|
name="topicName"
|
||||||
|
rules={[{required: true, message: `${t.TOPIC_NAME}${t.CANNOT_BE_EMPTY}`}]}
|
||||||
>
|
>
|
||||||
<Form.Item label={t.CLUSTER_NAME} name="clusterNameList">
|
<Input disabled={bIsUpdate}/>
|
||||||
<Select
|
</Form.Item>
|
||||||
mode="multiple"
|
<Form.Item label={t.MESSAGE_TYPE} name="messageType">
|
||||||
disabled={bIsUpdate}
|
<Select
|
||||||
placeholder={t.SELECT_CLUSTER_NAME}
|
disabled={bIsUpdate}
|
||||||
options={allClusterNameList.map(name => ({ value: name, label: name }))}
|
options={messageTypeOptions}
|
||||||
/>
|
/>
|
||||||
|
</Form.Item>
|
||||||
|
<Form.Item
|
||||||
|
label={t.WRITE_QUEUE_NUMS}
|
||||||
|
name="writeQueueNums"
|
||||||
|
rules={[{required: true, message: `${t.WRITE_QUEUE_NUMS}${t.CANNOT_BE_EMPTY}`}]}
|
||||||
|
>
|
||||||
|
<Input disabled={!writeOperationEnabled}/>
|
||||||
|
</Form.Item>
|
||||||
|
<Form.Item
|
||||||
|
label={t.READ_QUEUE_NUMS}
|
||||||
|
name="readQueueNums"
|
||||||
|
rules={[{required: true, message: `${t.READ_QUEUE_NUMS}${t.CANNOT_BE_EMPTY}`}]}
|
||||||
|
>
|
||||||
|
<Input disabled={!writeOperationEnabled}/>
|
||||||
|
</Form.Item>
|
||||||
|
<Form.Item
|
||||||
|
label={t.PERM}
|
||||||
|
name="perm"
|
||||||
|
rules={[{required: true, message: `${t.PERM}${t.CANNOT_BE_EMPTY}`}]}
|
||||||
|
>
|
||||||
|
<Input disabled={!writeOperationEnabled}/>
|
||||||
|
</Form.Item>
|
||||||
|
{!initialData.sysFlag && writeOperationEnabled && (
|
||||||
|
<Form.Item wrapperCol={{offset: 8, span: 16}}>
|
||||||
|
<Button type="primary" onClick={handleFormSubmit}>
|
||||||
|
{t.COMMIT}
|
||||||
|
</Button>
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
<Form.Item label="BROKER_NAME" name="brokerNameList">
|
)}
|
||||||
<Select
|
</Form>
|
||||||
mode="multiple"
|
</Col>
|
||||||
disabled={bIsUpdate}
|
</Row>
|
||||||
placeholder={t.SELECT_BROKER_NAME}
|
</div>
|
||||||
options={allBrokerNameList.map(name => ({ value: name, label: name }))}
|
|
||||||
/>
|
|
||||||
</Form.Item>
|
|
||||||
<Form.Item
|
|
||||||
label={t.TOPIC_NAME}
|
|
||||||
name="topicName"
|
|
||||||
rules={[{ required: true, message: `${t.TOPIC_NAME}${t.CANNOT_BE_EMPTY}` }]}
|
|
||||||
>
|
|
||||||
<Input disabled={bIsUpdate} />
|
|
||||||
</Form.Item>
|
|
||||||
<Form.Item label={t.MESSAGE_TYPE} name="messageType">
|
|
||||||
<Select
|
|
||||||
disabled={bIsUpdate}
|
|
||||||
options={messageTypeOptions}
|
|
||||||
/>
|
|
||||||
</Form.Item>
|
|
||||||
<Form.Item
|
|
||||||
label={t.WRITE_QUEUE_NUMS}
|
|
||||||
name="writeQueueNums"
|
|
||||||
rules={[{ required: true, message: `${t.WRITE_QUEUE_NUMS}${t.CANNOT_BE_EMPTY}` }]}
|
|
||||||
>
|
|
||||||
<Input disabled={!writeOperationEnabled} />
|
|
||||||
</Form.Item>
|
|
||||||
<Form.Item
|
|
||||||
label={t.READ_QUEUE_NUMS}
|
|
||||||
name="readQueueNums"
|
|
||||||
rules={[{ required: true, message: `${t.READ_QUEUE_NUMS}${t.CANNOT_BE_EMPTY}` }]}
|
|
||||||
>
|
|
||||||
<Input disabled={!writeOperationEnabled} />
|
|
||||||
</Form.Item>
|
|
||||||
<Form.Item
|
|
||||||
label={t.PERM}
|
|
||||||
name="perm"
|
|
||||||
rules={[{ required: true, message: `${t.PERM}${t.CANNOT_BE_EMPTY}` }]}
|
|
||||||
>
|
|
||||||
<Input disabled={!writeOperationEnabled} />
|
|
||||||
</Form.Item>
|
|
||||||
{!initialData.sysFlag && writeOperationEnabled && (
|
|
||||||
<Form.Item wrapperCol={{ offset: 8, span: 16 }}>
|
|
||||||
<Button type="primary" onClick={handleFormSubmit}>
|
|
||||||
{t.COMMIT}
|
|
||||||
</Button>
|
|
||||||
</Form.Item>
|
|
||||||
)}
|
|
||||||
</Form>
|
|
||||||
</Col>
|
|
||||||
</Row>
|
|
||||||
</div>
|
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@@ -15,20 +15,21 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import React, { createContext, useState, useContext } from 'react';
|
import React, {createContext, useContext, useState} from 'react';
|
||||||
import { translations } from '../i18n';
|
import {translations} from '../i18n';
|
||||||
|
|
||||||
const LanguageContext = createContext({
|
const LanguageContext = createContext({
|
||||||
lang: 'en',
|
lang: 'en',
|
||||||
setLang: () => {},
|
setLang: () => {
|
||||||
|
},
|
||||||
t: translations['en'], // 当前语言的文本资源
|
t: translations['en'], // 当前语言的文本资源
|
||||||
});
|
});
|
||||||
|
|
||||||
export const LanguageProvider = ({ children }) => {
|
export const LanguageProvider = ({children}) => {
|
||||||
const [lang, setLang] = useState('en');
|
const [lang, setLang] = useState('en');
|
||||||
const t = translations[lang] || translations['en'];
|
const t = translations[lang] || translations['en'];
|
||||||
return (
|
return (
|
||||||
<LanguageContext.Provider value={{ lang, setLang, t }}>
|
<LanguageContext.Provider value={{lang, setLang, t}}>
|
||||||
{children}
|
{children}
|
||||||
</LanguageContext.Provider>
|
</LanguageContext.Provider>
|
||||||
);
|
);
|
||||||
|
@@ -47,10 +47,10 @@ export const translations = {
|
|||||||
"FETCH_TOPIC_FAILED": "获取主题列表失败",
|
"FETCH_TOPIC_FAILED": "获取主题列表失败",
|
||||||
"CONFIRM_DELETE": "确认删除",
|
"CONFIRM_DELETE": "确认删除",
|
||||||
"CANCEL": "取消",
|
"CANCEL": "取消",
|
||||||
"SELECT_DELETE_BROKERS":"请选择在哪个Broker删除消费者组",
|
"SELECT_DELETE_BROKERS": "请选择在哪个Broker删除消费者组",
|
||||||
"DELETE_CONSUMER_GROUP":"删除消费者组",
|
"DELETE_CONSUMER_GROUP": "删除消费者组",
|
||||||
"ENGLISH": "英文",
|
"ENGLISH": "英文",
|
||||||
"ADD_CONSUMER":"添加消费者",
|
"ADD_CONSUMER": "添加消费者",
|
||||||
"CHINESE": "简体中文",
|
"CHINESE": "简体中文",
|
||||||
"CANNOT_BE_EMPTY": "不能为空",
|
"CANNOT_BE_EMPTY": "不能为空",
|
||||||
"TITLE": "RocketMQ仪表板",
|
"TITLE": "RocketMQ仪表板",
|
||||||
@@ -70,16 +70,16 @@ export const translations = {
|
|||||||
"CLUSTER_DETAIL": "集群详情",
|
"CLUSTER_DETAIL": "集群详情",
|
||||||
"COMMIT": "提交",
|
"COMMIT": "提交",
|
||||||
"TOPIC": "主题",
|
"TOPIC": "主题",
|
||||||
"SUBSCRIPTION_GROUP":"订阅组",
|
"SUBSCRIPTION_GROUP": "订阅组",
|
||||||
"PRODUCER_GROUP":"生产组",
|
"PRODUCER_GROUP": "生产组",
|
||||||
"CONSUMER":"消费者",
|
"CONSUMER": "消费者",
|
||||||
"PRODUCER":"生产者",
|
"PRODUCER": "生产者",
|
||||||
"MESSAGE":"消息",
|
"MESSAGE": "消息",
|
||||||
"MESSAGE_DETAIL":"消息详情",
|
"MESSAGE_DETAIL": "消息详情",
|
||||||
"RESEND_MESSAGE":"重新发送",
|
"RESEND_MESSAGE": "重新发送",
|
||||||
"VIEW_EXCEPTION":"查看异常",
|
"VIEW_EXCEPTION": "查看异常",
|
||||||
"DLQ_MESSAGE":"死信消息",
|
"DLQ_MESSAGE": "死信消息",
|
||||||
"MESSAGETRACE":"消息轨迹",
|
"MESSAGETRACE": "消息轨迹",
|
||||||
"OPERATION": "操作",
|
"OPERATION": "操作",
|
||||||
"ADD": "新增",
|
"ADD": "新增",
|
||||||
"UPDATE": "更新",
|
"UPDATE": "更新",
|
||||||
@@ -89,7 +89,7 @@ export const translations = {
|
|||||||
"CONFIG": "配置",
|
"CONFIG": "配置",
|
||||||
"SEND_MSG": "发送消息",
|
"SEND_MSG": "发送消息",
|
||||||
"RESET_CUS_OFFSET": "重置消费位点",
|
"RESET_CUS_OFFSET": "重置消费位点",
|
||||||
"SKIP_MESSAGE_ACCUMULATE":"跳过堆积",
|
"SKIP_MESSAGE_ACCUMULATE": "跳过堆积",
|
||||||
"DELETE": "删除",
|
"DELETE": "删除",
|
||||||
"CHANGE_LANG": "更换语言",
|
"CHANGE_LANG": "更换语言",
|
||||||
"CHANGE_VERSION": "更换版本",
|
"CHANGE_VERSION": "更换版本",
|
||||||
@@ -100,73 +100,72 @@ export const translations = {
|
|||||||
"TRANSACTION": "事务",
|
"TRANSACTION": "事务",
|
||||||
"UNSPECIFIED": "未指定",
|
"UNSPECIFIED": "未指定",
|
||||||
"DLQ": "死信",
|
"DLQ": "死信",
|
||||||
"QUANTITY":"数量",
|
"QUANTITY": "数量",
|
||||||
"TYPE":"类型",
|
"TYPE": "类型",
|
||||||
"MODE":"模式",
|
"MODE": "模式",
|
||||||
"DELAY":"延迟",
|
"DELAY": "延迟",
|
||||||
"DASHBOARD":"驾驶舱",
|
"DASHBOARD": "驾驶舱",
|
||||||
"CONSUME_DETAIL":"消费详情",
|
"CONSUME_DETAIL": "消费详情",
|
||||||
"CLIENT":"终端",
|
"CLIENT": "终端",
|
||||||
"LAST_CONSUME_TIME":"最后消费时间",
|
"LAST_CONSUME_TIME": "最后消费时间",
|
||||||
"TIME":"时间点",
|
"TIME": "时间点",
|
||||||
"RESET":"重置",
|
"RESET": "重置",
|
||||||
"DATE":"日期",
|
"DATE": "日期",
|
||||||
"NO_DATA":"暂无数据",
|
"NO_DATA": "暂无数据",
|
||||||
"SEARCH":"搜索",
|
"SEARCH": "搜索",
|
||||||
"BEGIN":"开始",
|
"BEGIN": "开始",
|
||||||
"END":"结束",
|
"END": "结束",
|
||||||
"TOPIC_CHANGE":"修改主题",
|
"TOPIC_CHANGE": "修改主题",
|
||||||
"SEND":"发送",
|
"SEND": "发送",
|
||||||
"SUBSCRIPTION_CHANGE":"修改订阅",
|
"SUBSCRIPTION_CHANGE": "修改订阅",
|
||||||
"QUEUE":"队列",
|
"QUEUE": "队列",
|
||||||
"MIN_OFFSET":"最小位点",
|
"MIN_OFFSET": "最小位点",
|
||||||
"MAX_OFFSET":"最大位点",
|
"MAX_OFFSET": "最大位点",
|
||||||
"LAST_UPDATE_TIME_STAMP":"上次更新时间",
|
"LAST_UPDATE_TIME_STAMP": "上次更新时间",
|
||||||
"QUEUE_DATAS":"队列信息",
|
"QUEUE_DATAS": "队列信息",
|
||||||
"READ_QUEUE_NUMS":"读队列数量",
|
"READ_QUEUE_NUMS": "读队列数量",
|
||||||
"WRITE_QUEUE_NUMS":"写队列数量",
|
"WRITE_QUEUE_NUMS": "写队列数量",
|
||||||
"PERM":"perm",
|
"PERM": "perm",
|
||||||
"TAG":"标签",
|
"TAG": "标签",
|
||||||
"KEY":"值",
|
"KEY": "值",
|
||||||
"MESSAGE_BODY":"消息主体",
|
"MESSAGE_BODY": "消息主体",
|
||||||
"TOPIC_NAME":"主题名",
|
"TOPIC_NAME": "主题名",
|
||||||
"ORDER":"顺序",
|
"ORDER": "顺序",
|
||||||
"CONSUMER_CLIENT":"消费者终端",
|
"CONSUMER_CLIENT": "消费者终端",
|
||||||
"BROKER_OFFSET":"代理者位点",
|
"BROKER_OFFSET": "代理者位点",
|
||||||
"CONSUMER_OFFSET":"消费者位点",
|
"CONSUMER_OFFSET": "消费者位点",
|
||||||
"DIFF_TOTAL":"差值",
|
"DIFF_TOTAL": "差值",
|
||||||
"LAST_TIME_STAMP":"上次时间",
|
"LAST_TIME_STAMP": "上次时间",
|
||||||
"RESET_OFFSET":"重置位点",
|
"RESET_OFFSET": "重置位点",
|
||||||
"CLUSTER_NAME":"集群名",
|
"CLUSTER_NAME": "集群名",
|
||||||
"OPS":"运维",
|
"OPS": "运维",
|
||||||
"PROXY":"代理",
|
"PROXY": "代理",
|
||||||
"AUTO_REFRESH":"自动刷新",
|
"AUTO_REFRESH": "自动刷新",
|
||||||
"REFRESH":"刷新",
|
"REFRESH": "刷新",
|
||||||
"LOGOUT":"退出",
|
"LOGOUT": "退出",
|
||||||
"LOGIN":"登录",
|
"LOGIN": "登录",
|
||||||
"USER_NAME":"用户名",
|
"USER_NAME": "用户名",
|
||||||
"PASSWORD":"密码",
|
"PASSWORD": "密码",
|
||||||
"SYSTEM":"系统",
|
"SYSTEM": "系统",
|
||||||
"WELCOME":"您好,欢迎使用RocketMQ仪表盘",
|
"WELCOME": "您好,欢迎使用RocketMQ仪表盘",
|
||||||
"ENABLE_MESSAGE_TRACE":"开启消息轨迹",
|
"ENABLE_MESSAGE_TRACE": "开启消息轨迹",
|
||||||
"MESSAGE_TRACE_DETAIL":"消息轨迹详情",
|
"MESSAGE_TRACE_DETAIL": "消息轨迹详情",
|
||||||
"TRACE_TOPIC":"消息轨迹主题",
|
"TRACE_TOPIC": "消息轨迹主题",
|
||||||
"SELECT_TRACE_TOPIC":"选择消息轨迹主题",
|
"SELECT_TRACE_TOPIC": "选择消息轨迹主题",
|
||||||
"EXPORT": "导出",
|
"EXPORT": "导出",
|
||||||
"NO_MATCH_RESULT": "没有查到符合条件的结果",
|
"NO_MATCH_RESULT": "没有查到符合条件的结果",
|
||||||
"BATCH_RESEND": "批量重发",
|
"BATCH_RESEND": "批量重发",
|
||||||
"BATCH_EXPORT": "批量导出",
|
"BATCH_EXPORT": "批量导出",
|
||||||
"WHITE_LIST":"白名单",
|
"ACCOUNT_INFO": "账户信息",
|
||||||
"ACCOUNT_INFO":"账户信息",
|
"IS_ADMIN": "是否管理员",
|
||||||
"IS_ADMIN":"是否管理员",
|
"DEFAULT_TOPIC_PERM": "topic默认权限",
|
||||||
"DEFAULT_TOPIC_PERM":"topic默认权限",
|
"DEFAULT_GROUP_PERM": "消费组默认权限",
|
||||||
"DEFAULT_GROUP_PERM":"消费组默认权限",
|
"TOPIC_PERM": "topic权限",
|
||||||
"TOPIC_PERM":"topic权限",
|
"GROUP_PERM": "消费组权限",
|
||||||
"GROUP_PERM":"消费组权限",
|
"SYNCHRONIZE": "同步",
|
||||||
"SYNCHRONIZE":"同步",
|
"SHOW": "显示",
|
||||||
"SHOW":"显示",
|
"HIDE": "隐藏",
|
||||||
"HIDE":"隐藏",
|
"MESSAGE_TYPE": "消息类型",
|
||||||
"MESSAGE_TYPE":"消息类型",
|
|
||||||
"MESSAGE_TYPE_UNSPECIFIED": "未指定,为普通消息",
|
"MESSAGE_TYPE_UNSPECIFIED": "未指定,为普通消息",
|
||||||
"MESSAGE_TYPE_NORMAL": "普通消息",
|
"MESSAGE_TYPE_NORMAL": "普通消息",
|
||||||
"MESSAGE_TYPE_FIFO": "顺序消息",
|
"MESSAGE_TYPE_FIFO": "顺序消息",
|
||||||
@@ -294,7 +293,7 @@ export const translations = {
|
|||||||
"SELECT_TOPIC_PLACEHOLDER": "Please select topic",
|
"SELECT_TOPIC_PLACEHOLDER": "Please select topic",
|
||||||
"MESSAGE_ID_TOPIC_HINT": "Message ID Topic",
|
"MESSAGE_ID_TOPIC_HINT": "Message ID Topic",
|
||||||
"TOPIC_ADD": "Add Topic",
|
"TOPIC_ADD": "Add Topic",
|
||||||
"SKIP_MESSAGE_ACCUMULATE":"Skip Message Accumulate",
|
"SKIP_MESSAGE_ACCUMULATE": "Skip Message Accumulate",
|
||||||
"OPERATION_FAILED": "Operation Failed",
|
"OPERATION_FAILED": "Operation Failed",
|
||||||
"FORM_VALIDATION_FAILED": "Form Validation Failed",
|
"FORM_VALIDATION_FAILED": "Form Validation Failed",
|
||||||
"ADD_CONSUMER": "Add Consumer",
|
"ADD_CONSUMER": "Add Consumer",
|
||||||
@@ -325,7 +324,7 @@ export const translations = {
|
|||||||
"ADDRESS": "Address",
|
"ADDRESS": "Address",
|
||||||
"VERSION": "Version",
|
"VERSION": "Version",
|
||||||
"PRO_MSG_TPS": "Produce Message TPS",
|
"PRO_MSG_TPS": "Produce Message TPS",
|
||||||
"CUS_MSG_TPS": "Consume Message TPS",
|
"CUS_MSG_TPS": "Consumer Message TPS",
|
||||||
"YESTERDAY_PRO_COUNT": "Yesterday Produce Count",
|
"YESTERDAY_PRO_COUNT": "Yesterday Produce Count",
|
||||||
"YESTERDAY_CUS_COUNT": "Yesterday Consume Count",
|
"YESTERDAY_CUS_COUNT": "Yesterday Consume Count",
|
||||||
"TODAY_PRO_COUNT": "Today Produce Count",
|
"TODAY_PRO_COUNT": "Today Produce Count",
|
||||||
@@ -335,16 +334,16 @@ export const translations = {
|
|||||||
"CLUSTER": "Cluster",
|
"CLUSTER": "Cluster",
|
||||||
"CLUSTER_DETAIL": "Cluster Detail",
|
"CLUSTER_DETAIL": "Cluster Detail",
|
||||||
"TOPIC": "Topic",
|
"TOPIC": "Topic",
|
||||||
"SUBSCRIPTION_GROUP":"SubscriptionGroup",
|
"SUBSCRIPTION_GROUP": "SubscriptionGroup",
|
||||||
"PRODUCER_GROUP":"ProducerGroup",
|
"PRODUCER_GROUP": "ProducerGroup",
|
||||||
"CONSUMER":"Consumer",
|
"CONSUMER": "Consumer",
|
||||||
"PRODUCER":"Producer",
|
"PRODUCER": "Producer",
|
||||||
"MESSAGE":"Message",
|
"MESSAGE": "Message",
|
||||||
"MESSAGE_DETAIL":"Message Detail",
|
"MESSAGE_DETAIL": "Message Detail",
|
||||||
"RESEND_MESSAGE":"Resend Message",
|
"RESEND_MESSAGE": "Resend Message",
|
||||||
"VIEW_EXCEPTION":"View Exception",
|
"VIEW_EXCEPTION": "View Exception",
|
||||||
"MESSAGETRACE":"MessageTrace",
|
"MESSAGETRACE": "MessageTrace",
|
||||||
"DLQ_MESSAGE":"DLQMessage",
|
"DLQ_MESSAGE": "DLQMessage",
|
||||||
"COMMIT": "Commit",
|
"COMMIT": "Commit",
|
||||||
"OPERATION": "Operation",
|
"OPERATION": "Operation",
|
||||||
"ADD": "Add",
|
"ADD": "Add",
|
||||||
@@ -365,73 +364,72 @@ export const translations = {
|
|||||||
"TRANSACTION": "TRANSACTION",
|
"TRANSACTION": "TRANSACTION",
|
||||||
"UNSPECIFIED": "UNSPECIFIED",
|
"UNSPECIFIED": "UNSPECIFIED",
|
||||||
"DLQ": "DLQ",
|
"DLQ": "DLQ",
|
||||||
"QUANTITY":"Quantity",
|
"QUANTITY": "Quantity",
|
||||||
"TYPE":"Type",
|
"TYPE": "Type",
|
||||||
"MODE":"Mode",
|
"MODE": "Mode",
|
||||||
"DELAY":"Delay",
|
"DELAY": "Delay",
|
||||||
"DASHBOARD":"Dashboard",
|
"DASHBOARD": "Dashboard",
|
||||||
"CONSUME_DETAIL":"CONSUME DETAIL",
|
"CONSUME_DETAIL": "CONSUME DETAIL",
|
||||||
"CLIENT":"CLIENT",
|
"CLIENT": "CLIENT",
|
||||||
"LAST_CONSUME_TIME":"LastConsumeTime",
|
"LAST_CONSUME_TIME": "LastConsumeTime",
|
||||||
"TIME":"Time",
|
"TIME": "Time",
|
||||||
"RESET":"RESET",
|
"RESET": "RESET",
|
||||||
"DATE":"Date",
|
"DATE": "Date",
|
||||||
"NO_DATA":"NO DATA",
|
"NO_DATA": "NO DATA",
|
||||||
"SEARCH":"Search",
|
"SEARCH": "Search",
|
||||||
"BEGIN":"Begin",
|
"BEGIN": "Begin",
|
||||||
"END":"End",
|
"END": "End",
|
||||||
"TOPIC_CHANGE":"Topic Change",
|
"TOPIC_CHANGE": "Topic Change",
|
||||||
"SEND":"Send",
|
"SEND": "Send",
|
||||||
"SUBSCRIPTION_CHANGE":"Subscription Change",
|
"SUBSCRIPTION_CHANGE": "Subscription Change",
|
||||||
"QUEUE":"Queue",
|
"QUEUE": "Queue",
|
||||||
"MIN_OFFSET":"minOffset",
|
"MIN_OFFSET": "minOffset",
|
||||||
"MAX_OFFSET":"maxOffset",
|
"MAX_OFFSET": "maxOffset",
|
||||||
"LAST_UPDATE_TIME_STAMP":"lastUpdateTimeStamp",
|
"LAST_UPDATE_TIME_STAMP": "lastUpdateTimeStamp",
|
||||||
"QUEUE_DATAS":"queueDatas",
|
"QUEUE_DATAS": "queueDatas",
|
||||||
"READ_QUEUE_NUMS":"readQueueNums",
|
"READ_QUEUE_NUMS": "readQueueNums",
|
||||||
"WRITE_QUEUE_NUMS":"writeQueueNums",
|
"WRITE_QUEUE_NUMS": "writeQueueNums",
|
||||||
"PERM":"perm",
|
"PERM": "perm",
|
||||||
"TAG":"Tag",
|
"TAG": "Tag",
|
||||||
"KEY":"Key",
|
"KEY": "Key",
|
||||||
"MESSAGE_BODY":"Message Body",
|
"MESSAGE_BODY": "Message Body",
|
||||||
"TOPIC_NAME":"topicName",
|
"TOPIC_NAME": "topicName",
|
||||||
"ORDER":"order",
|
"ORDER": "order",
|
||||||
"CONSUMER_CLIENT":"consumerClient",
|
"CONSUMER_CLIENT": "consumerClient",
|
||||||
"BROKER_OFFSET":"brokerOffset",
|
"BROKER_OFFSET": "brokerOffset",
|
||||||
"CONSUMER_OFFSET":"consumerOffset",
|
"CONSUMER_OFFSET": "consumerOffset",
|
||||||
"DIFF_TOTAL":"diffTotal",
|
"DIFF_TOTAL": "diffTotal",
|
||||||
"LAST_TIME_STAMP":"lastTimeStamp",
|
"LAST_TIME_STAMP": "lastTimeStamp",
|
||||||
"RESET_OFFSET":"resetOffset",
|
"RESET_OFFSET": "resetOffset",
|
||||||
"CLUSTER_NAME":"clusterName",
|
"CLUSTER_NAME": "clusterName",
|
||||||
"OPS":"OPS",
|
"OPS": "OPS",
|
||||||
"PROXY":"Proxy",
|
"PROXY": "Proxy",
|
||||||
"AUTO_REFRESH":"AUTO_REFRESH",
|
"AUTO_REFRESH": "AUTO_REFRESH",
|
||||||
"REFRESH":"REFRESH",
|
"REFRESH": "REFRESH",
|
||||||
"LOGOUT":"Logout",
|
"LOGOUT": "Logout",
|
||||||
"LOGIN":"Login",
|
"LOGIN": "Login",
|
||||||
"USER_NAME":"Username",
|
"USER_NAME": "Username",
|
||||||
"PASSWORD":"Password",
|
"PASSWORD": "Password",
|
||||||
"SYSTEM":"SYSTEM",
|
"SYSTEM": "SYSTEM",
|
||||||
"WELCOME":"Hi, welcome using RocketMQ Dashboard",
|
"WELCOME": "Hi, welcome using RocketMQ Dashboard",
|
||||||
"ENABLE_MESSAGE_TRACE":"Enable Message Trace",
|
"ENABLE_MESSAGE_TRACE": "Enable Message Trace",
|
||||||
"MESSAGE_TRACE_DETAIL":"Message Trace Detail",
|
"MESSAGE_TRACE_DETAIL": "Message Trace Detail",
|
||||||
"TRACE_TOPIC":"TraceTopic",
|
"TRACE_TOPIC": "TraceTopic",
|
||||||
"SELECT_TRACE_TOPIC":"selectTraceTopic",
|
"SELECT_TRACE_TOPIC": "selectTraceTopic",
|
||||||
"EXPORT": "export",
|
"EXPORT": "export",
|
||||||
"NO_MATCH_RESULT": "no match result",
|
"NO_MATCH_RESULT": "no match result",
|
||||||
"BATCH_RESEND": "batchReSend",
|
"BATCH_RESEND": "batchReSend",
|
||||||
"BATCH_EXPORT": "batchExport",
|
"BATCH_EXPORT": "batchExport",
|
||||||
"WHITE_LIST":"White List",
|
"ACCOUNT_INFO": "Account Info",
|
||||||
"ACCOUNT_INFO":"Account Info",
|
"IS_ADMIN": "Is Admin",
|
||||||
"IS_ADMIN":"Is Admin",
|
"DEFAULT_TOPIC_PERM": "Default Topic Permission",
|
||||||
"DEFAULT_TOPIC_PERM":"Default Topic Permission",
|
"DEFAULT_GROUP_PERM": "Default Group Permission",
|
||||||
"DEFAULT_GROUP_PERM":"Default Group Permission",
|
"TOPIC_PERM": "Topic Permission",
|
||||||
"TOPIC_PERM":"Topic Permission",
|
"GROUP_PERM": "Group Permission",
|
||||||
"GROUP_PERM":"Group Permission",
|
"SYNCHRONIZE": "Synchronize Data",
|
||||||
"SYNCHRONIZE":"Synchronize Data",
|
"SHOW": "Show",
|
||||||
"SHOW":"Show",
|
"HIDE": "Hide",
|
||||||
"HIDE":"Hide",
|
"MESSAGE_TYPE": "messageType",
|
||||||
"MESSAGE_TYPE":"messageType",
|
|
||||||
"MESSAGE_TYPE_UNSPECIFIED": "UNSPECIFIED, is NORMAL",
|
"MESSAGE_TYPE_UNSPECIFIED": "UNSPECIFIED, is NORMAL",
|
||||||
"MESSAGE_TYPE_NORMAL": "NORMAL",
|
"MESSAGE_TYPE_NORMAL": "NORMAL",
|
||||||
"MESSAGE_TYPE_FIFO": "FIFO",
|
"MESSAGE_TYPE_FIFO": "FIFO",
|
||||||
|
@@ -16,15 +16,15 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
body {
|
body {
|
||||||
margin: 0;
|
margin: 0;
|
||||||
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen',
|
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen',
|
||||||
'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue',
|
'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue',
|
||||||
sans-serif;
|
sans-serif;
|
||||||
-webkit-font-smoothing: antialiased;
|
-webkit-font-smoothing: antialiased;
|
||||||
-moz-osx-font-smoothing: grayscale;
|
-moz-osx-font-smoothing: grayscale;
|
||||||
}
|
}
|
||||||
|
|
||||||
code {
|
code {
|
||||||
font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New',
|
font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New',
|
||||||
monospace;
|
monospace;
|
||||||
}
|
}
|
||||||
|
@@ -19,7 +19,7 @@ import React from 'react';
|
|||||||
import ReactDOM from 'react-dom/client';
|
import ReactDOM from 'react-dom/client';
|
||||||
import './index.css';
|
import './index.css';
|
||||||
import App from './App';
|
import App from './App';
|
||||||
import { App as AntdApp } from 'antd';
|
import {App as AntdApp} from 'antd';
|
||||||
import reportWebVitals from './reportWebVitals';
|
import reportWebVitals from './reportWebVitals';
|
||||||
import {LanguageProvider} from "./i18n/LanguageContext";
|
import {LanguageProvider} from "./i18n/LanguageContext";
|
||||||
import {Provider} from "react-redux";
|
import {Provider} from "react-redux";
|
||||||
@@ -27,17 +27,15 @@ import store from './store';
|
|||||||
|
|
||||||
const root = ReactDOM.createRoot(document.getElementById('root'));
|
const root = ReactDOM.createRoot(document.getElementById('root'));
|
||||||
root.render(
|
root.render(
|
||||||
|
|
||||||
<LanguageProvider>
|
<LanguageProvider>
|
||||||
<React.StrictMode>
|
<React.StrictMode>
|
||||||
<AntdApp>
|
<AntdApp>
|
||||||
<Provider store={store}>
|
<Provider store={store}>
|
||||||
<App/>
|
<App/>
|
||||||
</Provider>
|
</Provider>
|
||||||
</AntdApp>
|
</AntdApp>
|
||||||
</React.StrictMode>
|
</React.StrictMode>
|
||||||
</LanguageProvider>
|
</LanguageProvider>
|
||||||
|
|
||||||
);
|
);
|
||||||
|
|
||||||
// If you want to start measuring performance in your app, pass a function
|
// If you want to start measuring performance in your app, pass a function
|
||||||
|
@@ -44,7 +44,7 @@ const ConsumerGroupList = () => {
|
|||||||
const [isAddConfig, setIsAddConfig] = useState(false);
|
const [isAddConfig, setIsAddConfig] = useState(false);
|
||||||
const [showDeleteModal, setShowDeleteModal] = useState(false);
|
const [showDeleteModal, setShowDeleteModal] = useState(false);
|
||||||
const [messageApi, msgContextHolder] = message.useMessage();
|
const [messageApi, msgContextHolder] = message.useMessage();
|
||||||
const [notificationApi,notificationContextHolder] = notification.useNotification();
|
const [notificationApi, notificationContextHolder] = notification.useNotification();
|
||||||
|
|
||||||
const [paginationConf, setPaginationConf] = useState({
|
const [paginationConf, setPaginationConf] = useState({
|
||||||
current: 1,
|
current: 1,
|
||||||
@@ -63,9 +63,9 @@ const ConsumerGroupList = () => {
|
|||||||
const response = await remoteApi.queryConsumerGroupList(false);
|
const response = await remoteApi.queryConsumerGroupList(false);
|
||||||
if (response.status === 0) {
|
if (response.status === 0) {
|
||||||
setAllConsumerGroupList(response.data);
|
setAllConsumerGroupList(response.data);
|
||||||
if(currentPage!=null){
|
if (currentPage != null) {
|
||||||
filterList(currentPage, response.data);
|
filterList(currentPage, response.data);
|
||||||
}else{
|
} else {
|
||||||
filterList(1, response.data);
|
filterList(1, response.data);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@@ -380,7 +380,7 @@ const ConsumerGroupList = () => {
|
|||||||
filterList(pagination.current, allConsumerGroupList);
|
filterList(pagination.current, allConsumerGroupList);
|
||||||
};
|
};
|
||||||
|
|
||||||
const closeConfigModal = () =>{
|
const closeConfigModal = () => {
|
||||||
setShowConfig(false);
|
setShowConfig(false);
|
||||||
setIsAddConfig(false);
|
setIsAddConfig(false);
|
||||||
}
|
}
|
||||||
|
@@ -16,17 +16,17 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { Form, Input, Button, message, Typography } from 'antd';
|
import {Button, Form, Input, message, Typography} from 'antd';
|
||||||
import {remoteApi} from "../../api/remoteApi/remoteApi";
|
import {remoteApi} from "../../api/remoteApi/remoteApi";
|
||||||
|
|
||||||
const { Title } = Typography;
|
const {Title} = Typography;
|
||||||
|
|
||||||
const Login = () => {
|
const Login = () => {
|
||||||
const [form] = Form.useForm();
|
const [form] = Form.useForm();
|
||||||
const [messageApi, msgContextHolder] = message.useMessage();
|
const [messageApi, msgContextHolder] = message.useMessage();
|
||||||
|
|
||||||
const onFinish = async (values) => {
|
const onFinish = async (values) => {
|
||||||
const { username, password } = values;
|
const {username, password} = values;
|
||||||
remoteApi.login(username, password).then((res) => {
|
remoteApi.login(username, password).then((res) => {
|
||||||
if (res.status === 0) {
|
if (res.status === 0) {
|
||||||
messageApi.success('登录成功');
|
messageApi.success('登录成功');
|
||||||
|
@@ -15,12 +15,12 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import React, { useState, useEffect } from 'react';
|
import React, {useEffect, useState} from 'react';
|
||||||
import { Select, Button, Switch, Input, Typography, Space, message } from 'antd';
|
import {Button, Input, message, Select, Space, Switch, Typography} from 'antd';
|
||||||
import {remoteApi} from '../../api/remoteApi/remoteApi';
|
import {remoteApi} from '../../api/remoteApi/remoteApi';
|
||||||
|
|
||||||
const { Title } = Typography;
|
const {Title} = Typography;
|
||||||
const { Option } = Select;
|
const {Option} = Select;
|
||||||
|
|
||||||
const Ops = () => {
|
const Ops = () => {
|
||||||
const [namesrvAddrList, setNamesrvAddrList] = useState([]);
|
const [namesrvAddrList, setNamesrvAddrList] = useState([]);
|
||||||
|
@@ -15,16 +15,16 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import React, { useState, useEffect } from 'react';
|
import React, {useEffect, useState} from 'react';
|
||||||
import { Modal, Button, Select, Input, Card, Row, Col, notification, Spin } from 'antd';
|
import {Button, Card, Col, Input, Modal, notification, Row, Select, Spin} from 'antd';
|
||||||
import { useLanguage } from '../../i18n/LanguageContext';
|
import {useLanguage} from '../../i18n/LanguageContext';
|
||||||
import { remoteApi } from "../../api/remoteApi/remoteApi";
|
import {remoteApi} from "../../api/remoteApi/remoteApi";
|
||||||
|
|
||||||
|
|
||||||
const { Option } = Select;
|
const {Option} = Select;
|
||||||
|
|
||||||
const ProxyManager = () => {
|
const ProxyManager = () => {
|
||||||
const { t } = useLanguage();
|
const {t} = useLanguage();
|
||||||
|
|
||||||
const [loading, setLoading] = useState(false);
|
const [loading, setLoading] = useState(false);
|
||||||
const [proxyAddrList, setProxyAddrList] = useState([]);
|
const [proxyAddrList, setProxyAddrList] = useState([]);
|
||||||
@@ -47,7 +47,7 @@ const ProxyManager = () => {
|
|||||||
remoteApi.queryProxyHomePage((resp) => {
|
remoteApi.queryProxyHomePage((resp) => {
|
||||||
setLoading(false);
|
setLoading(false);
|
||||||
if (resp.status === 0) {
|
if (resp.status === 0) {
|
||||||
const { proxyAddrList, currentProxyAddr } = resp.data;
|
const {proxyAddrList, currentProxyAddr} = resp.data;
|
||||||
setProxyAddrList(proxyAddrList || []);
|
setProxyAddrList(proxyAddrList || []);
|
||||||
setSelectedProxy(currentProxyAddr || (proxyAddrList && proxyAddrList.length > 0 ? proxyAddrList[0] : ''));
|
setSelectedProxy(currentProxyAddr || (proxyAddrList && proxyAddrList.length > 0 ? proxyAddrList[0] : ''));
|
||||||
|
|
||||||
@@ -58,7 +58,7 @@ const ProxyManager = () => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
notificationApi.error({ message: resp.errMsg || t.FETCH_PROXY_LIST_FAILED, duration: 2 });
|
notificationApi.error({message: resp.errMsg || t.FETCH_PROXY_LIST_FAILED, duration: 2});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}, [t]);
|
}, [t]);
|
||||||
@@ -71,7 +71,10 @@ const ProxyManager = () => {
|
|||||||
|
|
||||||
const handleAddProxyAddr = () => {
|
const handleAddProxyAddr = () => {
|
||||||
if (!newProxyAddr.trim()) {
|
if (!newProxyAddr.trim()) {
|
||||||
notificationApi.warning({ message: t.INPUT_PROXY_ADDR_REQUIRED || "Please input a new proxy address.", duration: 2 });
|
notificationApi.warning({
|
||||||
|
message: t.INPUT_PROXY_ADDR_REQUIRED || "Please input a new proxy address.",
|
||||||
|
duration: 2
|
||||||
|
});
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
setLoading(true);
|
setLoading(true);
|
||||||
@@ -82,28 +85,28 @@ const ProxyManager = () => {
|
|||||||
setProxyAddrList(prevList => [...prevList, newProxyAddr.trim()]);
|
setProxyAddrList(prevList => [...prevList, newProxyAddr.trim()]);
|
||||||
}
|
}
|
||||||
setNewProxyAddr('');
|
setNewProxyAddr('');
|
||||||
notificationApi.info({ message: t.SUCCESS || "SUCCESS", duration: 2 });
|
notificationApi.info({message: t.SUCCESS || "SUCCESS", duration: 2});
|
||||||
} else {
|
} else {
|
||||||
notificationApi.error({ message: resp.errMsg || t.ADD_PROXY_FAILED, duration: 2 });
|
notificationApi.error({message: resp.errMsg || t.ADD_PROXY_FAILED, duration: 2});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Spin spinning={loading} tip={t.LOADING}>
|
<Spin spinning={loading} tip={t.LOADING}>
|
||||||
<div className="container-fluid" style={{ padding: '24px' }} id="deployHistoryList">
|
<div className="container-fluid" style={{padding: '24px'}} id="deployHistoryList">
|
||||||
<Card
|
<Card
|
||||||
title={
|
title={
|
||||||
<div style={{ fontSize: '20px', fontWeight: 'bold' }}>
|
<div style={{fontSize: '20px', fontWeight: 'bold'}}>
|
||||||
ProxyServerAddressList
|
ProxyServerAddressList
|
||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
bordered={false}
|
bordered={false}
|
||||||
>
|
>
|
||||||
<Row gutter={[16, 16]} align="middle">
|
<Row gutter={[16, 16]} align="middle">
|
||||||
<Col flex="auto" style={{ minWidth: 300, maxWidth: 500 }}>
|
<Col flex="auto" style={{minWidth: 300, maxWidth: 500}}>
|
||||||
<Select
|
<Select
|
||||||
style={{ width: '100%' }}
|
style={{width: '100%'}}
|
||||||
value={selectedProxy}
|
value={selectedProxy}
|
||||||
onChange={handleSelectChange}
|
onChange={handleSelectChange}
|
||||||
placeholder={t.SELECT}
|
placeholder={t.SELECT}
|
||||||
@@ -122,14 +125,14 @@ const ProxyManager = () => {
|
|||||||
</Row>
|
</Row>
|
||||||
|
|
||||||
{writeOperationEnabled && (
|
{writeOperationEnabled && (
|
||||||
<Row gutter={[16, 16]} align="middle" style={{ marginTop: 16 }}>
|
<Row gutter={[16, 16]} align="middle" style={{marginTop: 16}}>
|
||||||
<Col>
|
<Col>
|
||||||
<label htmlFor="newProxyAddrInput">ProxyAddr:</label>
|
<label htmlFor="newProxyAddrInput">ProxyAddr:</label>
|
||||||
</Col>
|
</Col>
|
||||||
<Col>
|
<Col>
|
||||||
<Input
|
<Input
|
||||||
id="newProxyAddrInput"
|
id="newProxyAddrInput"
|
||||||
style={{ width: 300 }}
|
style={{width: 300}}
|
||||||
value={newProxyAddr}
|
value={newProxyAddr}
|
||||||
onChange={(e) => setNewProxyAddr(e.target.value)}
|
onChange={(e) => setNewProxyAddr(e.target.value)}
|
||||||
placeholder={t.INPUT_PROXY_ADDR}
|
placeholder={t.INPUT_PROXY_ADDR}
|
||||||
@@ -149,25 +152,26 @@ const ProxyManager = () => {
|
|||||||
onCancel={() => setShowModal(false)}
|
onCancel={() => setShowModal(false)}
|
||||||
title={`${t.PROXY_CONFIG} [${selectedProxy}]`}
|
title={`${t.PROXY_CONFIG} [${selectedProxy}]`}
|
||||||
footer={
|
footer={
|
||||||
<div style={{ textAlign: 'center' }}>
|
<div style={{textAlign: 'center'}}>
|
||||||
<Button onClick={() => setShowModal(false)}>{t.CLOSE}</Button>
|
<Button onClick={() => setShowModal(false)}>{t.CLOSE}</Button>
|
||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
width={800}
|
width={800}
|
||||||
bodyStyle={{ maxHeight: '60vh', overflowY: 'auto' }}
|
bodyStyle={{maxHeight: '60vh', overflowY: 'auto'}}
|
||||||
>
|
>
|
||||||
<table className="table table-bordered" style={{ width: '100%' }}>
|
<table className="table table-bordered" style={{width: '100%'}}>
|
||||||
<tbody>
|
<tbody>
|
||||||
{Object.entries(allProxyConfig).length > 0 ? (
|
{Object.entries(allProxyConfig).length > 0 ? (
|
||||||
Object.entries(allProxyConfig).map(([key, value]) => (
|
Object.entries(allProxyConfig).map(([key, value]) => (
|
||||||
<tr key={key}>
|
<tr key={key}>
|
||||||
<td style={{ fontWeight: 500, width: '30%' }}>{key}</td>
|
<td style={{fontWeight: 500, width: '30%'}}>{key}</td>
|
||||||
<td>{value}</td>
|
<td>{value}</td>
|
||||||
</tr>
|
</tr>
|
||||||
))
|
))
|
||||||
) : (
|
) : (
|
||||||
<tr>
|
<tr>
|
||||||
<td colSpan="2" style={{ textAlign: 'center' }}>{t.NO_CONFIG_DATA || "No configuration data available."}</td>
|
<td colSpan="2"
|
||||||
|
style={{textAlign: 'center'}}>{t.NO_CONFIG_DATA || "No configuration data available."}</td>
|
||||||
</tr>
|
</tr>
|
||||||
)}
|
)}
|
||||||
</tbody>
|
</tbody>
|
||||||
|
@@ -173,7 +173,6 @@ const DeployHistoryList = () => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
const filterList = (currentPage) => {
|
const filterList = (currentPage) => {
|
||||||
const lowExceptStr = filterStr.toLowerCase();
|
const lowExceptStr = filterStr.toLowerCase();
|
||||||
const canShowList = allTopicList.filter((topic, index) => {
|
const canShowList = allTopicList.filter((topic, index) => {
|
||||||
@@ -223,7 +222,7 @@ const DeployHistoryList = () => {
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
if (isUpdate) {
|
if (isUpdate) {
|
||||||
// topic 已经是字符串
|
// topic 已经是字符串
|
||||||
const configResult = await remoteApi.getTopicConfig(topic);
|
const configResult = await remoteApi.getTopicConfig(topic);
|
||||||
if (configResult.status === 0) {
|
if (configResult.status === 0) {
|
||||||
const dataToSet = Array.isArray(configResult.data) ? configResult.data : [configResult.data];
|
const dataToSet = Array.isArray(configResult.data) ? configResult.data : [configResult.data];
|
||||||
@@ -257,7 +256,7 @@ const DeployHistoryList = () => {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!isUpdate){
|
if (!isUpdate) {
|
||||||
const clusterResult = await remoteApi.getClusterList();
|
const clusterResult = await remoteApi.getClusterList();
|
||||||
if (clusterResult.status === 0) {
|
if (clusterResult.status === 0) {
|
||||||
setAllClusterNameList(Object.keys(clusterResult.data.clusterInfo.clusterAddrTable));
|
setAllClusterNameList(Object.keys(clusterResult.data.clusterInfo.clusterAddrTable));
|
||||||
@@ -276,7 +275,7 @@ const DeployHistoryList = () => {
|
|||||||
if (result.status === 0) {
|
if (result.status === 0) {
|
||||||
messageApi.success(t.TOPIC_OPERATION_SUCCESS);
|
messageApi.success(t.TOPIC_OPERATION_SUCCESS);
|
||||||
closeAddUpdateDialog();
|
closeAddUpdateDialog();
|
||||||
if(!isUpdateMode) {
|
if (!isUpdateMode) {
|
||||||
await getTopicList()
|
await getTopicList()
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@@ -16,15 +16,15 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
const reportWebVitals = onPerfEntry => {
|
const reportWebVitals = onPerfEntry => {
|
||||||
if (onPerfEntry && onPerfEntry instanceof Function) {
|
if (onPerfEntry && onPerfEntry instanceof Function) {
|
||||||
import('web-vitals').then(({ getCLS, getFID, getFCP, getLCP, getTTFB }) => {
|
import('web-vitals').then(({getCLS, getFID, getFCP, getLCP, getTTFB}) => {
|
||||||
getCLS(onPerfEntry);
|
getCLS(onPerfEntry);
|
||||||
getFID(onPerfEntry);
|
getFID(onPerfEntry);
|
||||||
getFCP(onPerfEntry);
|
getFCP(onPerfEntry);
|
||||||
getLCP(onPerfEntry);
|
getLCP(onPerfEntry);
|
||||||
getTTFB(onPerfEntry);
|
getTTFB(onPerfEntry);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
export default reportWebVitals;
|
export default reportWebVitals;
|
||||||
|
@@ -64,7 +64,7 @@ const AppRouter = () => {
|
|||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
remoteApi.setRedirectHandler(() => {
|
remoteApi.setRedirectHandler(() => {
|
||||||
navigate('/login', { replace: true });
|
navigate('/login', {replace: true});
|
||||||
});
|
});
|
||||||
}, [navigate]);
|
}, [navigate]);
|
||||||
|
|
||||||
|
@@ -14,10 +14,10 @@
|
|||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
import { useEffect } from 'react';
|
import {useEffect} from 'react';
|
||||||
import { useSelector, useDispatch } from 'react-redux';
|
import {useDispatch, useSelector} from 'react-redux';
|
||||||
import { themes, defaultTheme } from '../../assets/styles/theme';
|
import {defaultTheme, themes} from '../../assets/styles/theme';
|
||||||
import { setTheme } from '../actions/themeActions';
|
import {setTheme} from '../actions/themeActions';
|
||||||
|
|
||||||
export const useTheme = () => {
|
export const useTheme = () => {
|
||||||
// 从 Redux store 中取出 currentThemeName
|
// 从 Redux store 中取出 currentThemeName
|
||||||
|
@@ -14,7 +14,7 @@
|
|||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
import { createStore,combineReducers } from 'redux';
|
import {combineReducers, createStore} from 'redux';
|
||||||
import themeReducer from './reducers/themeReducer';
|
import themeReducer from './reducers/themeReducer';
|
||||||
|
|
||||||
// 组合所有的 reducers
|
// 组合所有的 reducers
|
||||||
|
@@ -15,7 +15,7 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { SET_THEME } from '../actions/themeActions';
|
import {SET_THEME} from '../actions/themeActions';
|
||||||
|
|
||||||
const getInitialTheme = () => {
|
const getInitialTheme = () => {
|
||||||
return localStorage.getItem('appTheme') || 'default';
|
return localStorage.getItem('appTheme') || 'default';
|
||||||
|
7
pom.xml
7
pom.xml
@@ -16,7 +16,8 @@
|
|||||||
~ limitations under the License.
|
~ limitations under the License.
|
||||||
-->
|
-->
|
||||||
|
|
||||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||||
|
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>org.apache</groupId>
|
<groupId>org.apache</groupId>
|
||||||
@@ -432,7 +433,7 @@
|
|||||||
</configuration>
|
</configuration>
|
||||||
<executions>
|
<executions>
|
||||||
<execution>
|
<execution>
|
||||||
<id>install node </id>
|
<id>install node</id>
|
||||||
<goals>
|
<goals>
|
||||||
<goal>install-node-and-npm</goal>
|
<goal>install-node-and-npm</goal>
|
||||||
</goals>
|
</goals>
|
||||||
@@ -469,7 +470,7 @@
|
|||||||
<configuration>
|
<configuration>
|
||||||
<target>
|
<target>
|
||||||
<copy todir="${project.build.directory}/classes/public">
|
<copy todir="${project.build.directory}/classes/public">
|
||||||
<fileset dir="${project.basedir}/frontend-new/build" />
|
<fileset dir="${project.basedir}/frontend-new/build"/>
|
||||||
</copy>
|
</copy>
|
||||||
</target>
|
</target>
|
||||||
</configuration>
|
</configuration>
|
||||||
|
@@ -1,25 +0,0 @@
|
|||||||
/*
|
|
||||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
|
||||||
* contributor license agreements. See the NOTICE file distributed with
|
|
||||||
* this work for additional information regarding copyright ownership.
|
|
||||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
|
||||||
* (the "License"); you may not use this file except in compliance with
|
|
||||||
* the License. You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package org.apache.rocketmq.dashboard.admin;
|
|
||||||
|
|
||||||
import org.apache.rocketmq.tools.admin.MQAdminExt;
|
|
||||||
|
|
||||||
@FunctionalInterface
|
|
||||||
public interface MQAdminExtCallback<T> {
|
|
||||||
T doInMQAdminExt(MQAdminExt mqAdminExt) throws Exception;
|
|
||||||
}
|
|
@@ -32,7 +32,7 @@ public class MQAdminPooledObjectFactory implements PooledObjectFactory<MQAdminEx
|
|||||||
@Override
|
@Override
|
||||||
public PooledObject<MQAdminExt> makeObject() throws Exception {
|
public PooledObject<MQAdminExt> makeObject() throws Exception {
|
||||||
DefaultPooledObject<MQAdminExt> pooledObject = new DefaultPooledObject<>(
|
DefaultPooledObject<MQAdminExt> pooledObject = new DefaultPooledObject<>(
|
||||||
mqAdminFactory.getInstance());
|
mqAdminFactory.getInstance());
|
||||||
return pooledObject;
|
return pooledObject;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -40,8 +40,8 @@ public class MqAdminExtObjectPool {
|
|||||||
MQAdminFactory mqAdminFactory = new MQAdminFactory(rmqConfigure);
|
MQAdminFactory mqAdminFactory = new MQAdminFactory(rmqConfigure);
|
||||||
mqAdminPooledObjectFactory.setMqAdminFactory(mqAdminFactory);
|
mqAdminPooledObjectFactory.setMqAdminFactory(mqAdminFactory);
|
||||||
GenericObjectPool<MQAdminExt> genericObjectPool = new GenericObjectPool<MQAdminExt>(
|
GenericObjectPool<MQAdminExt> genericObjectPool = new GenericObjectPool<MQAdminExt>(
|
||||||
mqAdminPooledObjectFactory,
|
mqAdminPooledObjectFactory,
|
||||||
genericObjectPoolConfig);
|
genericObjectPoolConfig);
|
||||||
return genericObjectPool;
|
return genericObjectPool;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -41,20 +41,20 @@ public class CollectExecutorConfig {
|
|||||||
@Bean(name = "collectExecutor")
|
@Bean(name = "collectExecutor")
|
||||||
public ExecutorService collectExecutor(CollectExecutorConfig collectExecutorConfig) {
|
public ExecutorService collectExecutor(CollectExecutorConfig collectExecutorConfig) {
|
||||||
ExecutorService collectExecutor = new ThreadPoolExecutor(
|
ExecutorService collectExecutor = new ThreadPoolExecutor(
|
||||||
collectExecutorConfig.getCoreSize(),
|
collectExecutorConfig.getCoreSize(),
|
||||||
collectExecutorConfig.getMaxSize(),
|
collectExecutorConfig.getMaxSize(),
|
||||||
collectExecutorConfig.getKeepAliveTime(),
|
collectExecutorConfig.getKeepAliveTime(),
|
||||||
TimeUnit.MILLISECONDS,
|
TimeUnit.MILLISECONDS,
|
||||||
new LinkedBlockingDeque<>(collectExecutorConfig.getQueueSize()),
|
new LinkedBlockingDeque<>(collectExecutorConfig.getQueueSize()),
|
||||||
new ThreadFactory() {
|
new ThreadFactory() {
|
||||||
private final AtomicLong threadIndex = new AtomicLong(0);
|
private final AtomicLong threadIndex = new AtomicLong(0);
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Thread newThread(Runnable r) {
|
public Thread newThread(Runnable r) {
|
||||||
return new Thread(r, "collectTopicThread_" + this.threadIndex.incrementAndGet());
|
return new Thread(r, "collectTopicThread_" + this.threadIndex.incrementAndGet());
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
new ThreadPoolExecutor.DiscardOldestPolicy()
|
new ThreadPoolExecutor.DiscardOldestPolicy()
|
||||||
);
|
);
|
||||||
return collectExecutor;
|
return collectExecutor;
|
||||||
}
|
}
|
||||||
|
@@ -91,6 +91,10 @@ public class RMQConfigure {
|
|||||||
@Getter
|
@Getter
|
||||||
private Integer clientCallbackExecutorThreads = 4;
|
private Integer clientCallbackExecutorThreads = 4;
|
||||||
|
|
||||||
|
@Setter
|
||||||
|
@Getter
|
||||||
|
private String authMode = "file";
|
||||||
|
|
||||||
public void setProxyAddrs(List<String> proxyAddrs) {
|
public void setProxyAddrs(List<String> proxyAddrs) {
|
||||||
this.proxyAddrs = proxyAddrs;
|
this.proxyAddrs = proxyAddrs;
|
||||||
if (CollectionUtils.isNotEmpty(proxyAddrs)) {
|
if (CollectionUtils.isNotEmpty(proxyAddrs)) {
|
||||||
@@ -112,10 +116,12 @@ public class RMQConfigure {
|
|||||||
logger.info("setNameSrvAddrByProperty nameSrvAddr={}", namesrvAddr);
|
logger.info("setNameSrvAddrByProperty nameSrvAddr={}", namesrvAddr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isACLEnabled() {
|
public boolean isACLEnabled() {
|
||||||
return !(StringUtils.isAnyBlank(this.accessKey, this.secretKey) ||
|
return !(StringUtils.isAnyBlank(this.accessKey, this.secretKey) ||
|
||||||
StringUtils.isAnyEmpty(this.accessKey, this.secretKey));
|
StringUtils.isAnyEmpty(this.accessKey, this.secretKey));
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getRocketMqDashboardDataPath() {
|
public String getRocketMqDashboardDataPath() {
|
||||||
return dataPath;
|
return dataPath;
|
||||||
}
|
}
|
||||||
|
@@ -54,7 +54,7 @@ public class ConsumerController {
|
|||||||
@RequestMapping(value = "/group.refresh")
|
@RequestMapping(value = "/group.refresh")
|
||||||
@ResponseBody
|
@ResponseBody
|
||||||
public Object refresh(String address,
|
public Object refresh(String address,
|
||||||
String consumerGroup) {
|
String consumerGroup) {
|
||||||
return consumerService.refreshGroup(address, consumerGroup);
|
return consumerService.refreshGroup(address, consumerGroup);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -100,7 +100,7 @@ public class ConsumerController {
|
|||||||
@ResponseBody
|
@ResponseBody
|
||||||
public Object consumerCreateOrUpdateRequest(@RequestBody ConsumerConfigInfo consumerConfigInfo) {
|
public Object consumerCreateOrUpdateRequest(@RequestBody ConsumerConfigInfo consumerConfigInfo) {
|
||||||
Preconditions.checkArgument(CollectionUtils.isNotEmpty(consumerConfigInfo.getBrokerNameList()) || CollectionUtils.isNotEmpty(consumerConfigInfo.getClusterNameList()),
|
Preconditions.checkArgument(CollectionUtils.isNotEmpty(consumerConfigInfo.getBrokerNameList()) || CollectionUtils.isNotEmpty(consumerConfigInfo.getClusterNameList()),
|
||||||
"clusterName or brokerName can not be all blank");
|
"clusterName or brokerName can not be all blank");
|
||||||
return consumerService.createAndUpdateSubscriptionGroupConfig(consumerConfigInfo);
|
return consumerService.createAndUpdateSubscriptionGroupConfig(consumerConfigInfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -127,7 +127,7 @@ public class ConsumerController {
|
|||||||
@RequestMapping(value = "/consumerRunningInfo.query")
|
@RequestMapping(value = "/consumerRunningInfo.query")
|
||||||
@ResponseBody
|
@ResponseBody
|
||||||
public Object getConsumerRunningInfo(@RequestParam String consumerGroup, @RequestParam String clientId,
|
public Object getConsumerRunningInfo(@RequestParam String consumerGroup, @RequestParam String clientId,
|
||||||
@RequestParam boolean jstack) {
|
@RequestParam boolean jstack) {
|
||||||
return consumerService.getConsumerRunningInfo(consumerGroup, clientId, jstack);
|
return consumerService.getConsumerRunningInfo(consumerGroup, clientId, jstack);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -47,7 +47,7 @@ public class DashboardController {
|
|||||||
if (Strings.isNullOrEmpty(topicName)) {
|
if (Strings.isNullOrEmpty(topicName)) {
|
||||||
return dashboardService.queryTopicData(date);
|
return dashboardService.queryTopicData(date);
|
||||||
}
|
}
|
||||||
return dashboardService.queryTopicData(date,topicName);
|
return dashboardService.queryTopicData(date, topicName);
|
||||||
}
|
}
|
||||||
|
|
||||||
@RequestMapping(value = "/topicCurrent.query", method = RequestMethod.GET)
|
@RequestMapping(value = "/topicCurrent.query", method = RequestMethod.GET)
|
||||||
|
@@ -64,7 +64,7 @@ public class MessageTraceController {
|
|||||||
@RequestMapping(value = "/viewMessageTraceGraph.query", method = RequestMethod.GET)
|
@RequestMapping(value = "/viewMessageTraceGraph.query", method = RequestMethod.GET)
|
||||||
@ResponseBody
|
@ResponseBody
|
||||||
public MessageTraceGraph viewMessageTraceGraph(@RequestParam String msgId,
|
public MessageTraceGraph viewMessageTraceGraph(@RequestParam String msgId,
|
||||||
@RequestParam(required = false) String traceTopic) {
|
@RequestParam(required = false) String traceTopic) {
|
||||||
return messageTraceService.queryMessageTraceGraph(msgId, traceTopic);
|
return messageTraceService.queryMessageTraceGraph(msgId, traceTopic);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -40,7 +40,7 @@ public class MonitorController {
|
|||||||
@RequestMapping(value = "/createOrUpdateConsumerMonitor.do", method = {RequestMethod.POST})
|
@RequestMapping(value = "/createOrUpdateConsumerMonitor.do", method = {RequestMethod.POST})
|
||||||
@ResponseBody
|
@ResponseBody
|
||||||
public Object createOrUpdateConsumerMonitor(@RequestParam String consumeGroupName, @RequestParam int minCount,
|
public Object createOrUpdateConsumerMonitor(@RequestParam String consumeGroupName, @RequestParam int minCount,
|
||||||
@RequestParam int maxDiffTotal) {
|
@RequestParam int maxDiffTotal) {
|
||||||
return monitorService.createOrUpdateConsumerMonitor(consumeGroupName, new ConsumerMonitorConfig(minCount, maxDiffTotal));
|
return monitorService.createOrUpdateConsumerMonitor(consumeGroupName, new ConsumerMonitorConfig(minCount, maxDiffTotal));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -52,7 +52,7 @@ public class OpsController {
|
|||||||
@ResponseBody
|
@ResponseBody
|
||||||
public Object addNameSvrAddr(@RequestParam String newNamesrvAddr) {
|
public Object addNameSvrAddr(@RequestParam String newNamesrvAddr) {
|
||||||
Preconditions.checkArgument(StringUtils.isNotEmpty(newNamesrvAddr),
|
Preconditions.checkArgument(StringUtils.isNotEmpty(newNamesrvAddr),
|
||||||
"namesrvAddr can not be blank");
|
"namesrvAddr can not be blank");
|
||||||
opsService.addNameSvrAddr(newNamesrvAddr);
|
opsService.addNameSvrAddr(newNamesrvAddr);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@@ -31,6 +31,7 @@ import org.springframework.web.bind.annotation.ResponseBody;
|
|||||||
public class ProxyController {
|
public class ProxyController {
|
||||||
@Resource
|
@Resource
|
||||||
private ProxyService proxyService;
|
private ProxyService proxyService;
|
||||||
|
|
||||||
@RequestMapping(value = "/homePage.query", method = RequestMethod.GET)
|
@RequestMapping(value = "/homePage.query", method = RequestMethod.GET)
|
||||||
@ResponseBody
|
@ResponseBody
|
||||||
public Object homePage() {
|
public Object homePage() {
|
||||||
|
@@ -59,7 +59,7 @@ public class TestController {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ConsumeConcurrentlyStatus consumeMessage(List<MessageExt> msgs,
|
public ConsumeConcurrentlyStatus consumeMessage(List<MessageExt> msgs,
|
||||||
ConsumeConcurrentlyContext context) {
|
ConsumeConcurrentlyContext context) {
|
||||||
logger.info("receiveMessage msgSize={}", msgs.size());
|
logger.info("receiveMessage msgSize={}", msgs.size());
|
||||||
return ConsumeConcurrentlyStatus.CONSUME_SUCCESS;
|
return ConsumeConcurrentlyStatus.CONSUME_SUCCESS;
|
||||||
}
|
}
|
||||||
@@ -72,26 +72,25 @@ public class TestController {
|
|||||||
|
|
||||||
new Thread(new Runnable() {
|
new Thread(new Runnable() {
|
||||||
|
|
||||||
@Override public void run() {
|
@Override
|
||||||
|
public void run() {
|
||||||
|
|
||||||
int i = 0;
|
int i = 0;
|
||||||
while (true) {
|
while (true) {
|
||||||
try {
|
try {
|
||||||
Message msg = new Message(testTopic,
|
Message msg = new Message(testTopic,
|
||||||
"TagA" + i,
|
"TagA" + i,
|
||||||
"KEYS" + i,
|
"KEYS" + i,
|
||||||
("Hello RocketMQ " + i).getBytes()
|
("Hello RocketMQ " + i).getBytes()
|
||||||
);
|
);
|
||||||
Thread.sleep(1000L);
|
Thread.sleep(1000L);
|
||||||
SendResult sendResult = producer.send(msg);
|
SendResult sendResult = producer.send(msg);
|
||||||
logger.info("sendMessage={}", JsonUtil.obj2String(sendResult));
|
logger.info("sendMessage={}", JsonUtil.obj2String(sendResult));
|
||||||
}
|
} catch (Exception e) {
|
||||||
catch (Exception e) {
|
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
try {
|
try {
|
||||||
Thread.sleep(1000);
|
Thread.sleep(1000);
|
||||||
}
|
} catch (Exception ignore) {
|
||||||
catch (Exception ignore) {
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -51,7 +51,7 @@ public class TopicController {
|
|||||||
@RequestMapping(value = "/list.query", method = RequestMethod.GET)
|
@RequestMapping(value = "/list.query", method = RequestMethod.GET)
|
||||||
@ResponseBody
|
@ResponseBody
|
||||||
public Object list(@RequestParam(value = "skipSysProcess", required = false) boolean skipSysProcess,
|
public Object list(@RequestParam(value = "skipSysProcess", required = false) boolean skipSysProcess,
|
||||||
@RequestParam(value = "skipRetryAndDlq", required = false) boolean skipRetryAndDlq) {
|
@RequestParam(value = "skipRetryAndDlq", required = false) boolean skipRetryAndDlq) {
|
||||||
return topicService.fetchAllTopicList(skipSysProcess, skipRetryAndDlq);
|
return topicService.fetchAllTopicList(skipSysProcess, skipRetryAndDlq);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -75,11 +75,11 @@ public class TopicController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@RequestMapping(value = "/createOrUpdate.do", method = { RequestMethod.POST})
|
@RequestMapping(value = "/createOrUpdate.do", method = {RequestMethod.POST})
|
||||||
@ResponseBody
|
@ResponseBody
|
||||||
public Object topicCreateOrUpdateRequest(@RequestBody TopicConfigInfo topicCreateOrUpdateRequest) {
|
public Object topicCreateOrUpdateRequest(@RequestBody TopicConfigInfo topicCreateOrUpdateRequest) {
|
||||||
Preconditions.checkArgument(CollectionUtils.isNotEmpty(topicCreateOrUpdateRequest.getBrokerNameList()) || CollectionUtils.isNotEmpty(topicCreateOrUpdateRequest.getClusterNameList()),
|
Preconditions.checkArgument(CollectionUtils.isNotEmpty(topicCreateOrUpdateRequest.getBrokerNameList()) || CollectionUtils.isNotEmpty(topicCreateOrUpdateRequest.getClusterNameList()),
|
||||||
"clusterName or brokerName can not be all blank");
|
"clusterName or brokerName can not be all blank");
|
||||||
logger.info("op=look topicCreateOrUpdateRequest={}", JsonUtil.obj2String(topicCreateOrUpdateRequest));
|
logger.info("op=look topicCreateOrUpdateRequest={}", JsonUtil.obj2String(topicCreateOrUpdateRequest));
|
||||||
topicService.createOrUpdate(topicCreateOrUpdateRequest);
|
topicService.createOrUpdate(topicCreateOrUpdateRequest);
|
||||||
return true;
|
return true;
|
||||||
@@ -100,14 +100,14 @@ public class TopicController {
|
|||||||
@RequestMapping(value = "/examineTopicConfig.query")
|
@RequestMapping(value = "/examineTopicConfig.query")
|
||||||
@ResponseBody
|
@ResponseBody
|
||||||
public Object examineTopicConfig(@RequestParam String topic,
|
public Object examineTopicConfig(@RequestParam String topic,
|
||||||
@RequestParam(required = false) String brokerName) throws RemotingException, MQClientException, InterruptedException {
|
@RequestParam(required = false) String brokerName) throws RemotingException, MQClientException, InterruptedException {
|
||||||
return topicService.examineTopicConfig(topic);
|
return topicService.examineTopicConfig(topic);
|
||||||
}
|
}
|
||||||
|
|
||||||
@RequestMapping(value = "/sendTopicMessage.do", method = {RequestMethod.POST})
|
@RequestMapping(value = "/sendTopicMessage.do", method = {RequestMethod.POST})
|
||||||
@ResponseBody
|
@ResponseBody
|
||||||
public Object sendTopicMessage(
|
public Object sendTopicMessage(
|
||||||
@RequestBody SendTopicMessageRequest sendTopicMessageRequest) throws RemotingException, MQClientException, InterruptedException {
|
@RequestBody SendTopicMessageRequest sendTopicMessageRequest) throws RemotingException, MQClientException, InterruptedException {
|
||||||
return topicService.sendTopicMessageRequest(sendTopicMessageRequest);
|
return topicService.sendTopicMessageRequest(sendTopicMessageRequest);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -29,7 +29,6 @@ import jakarta.servlet.http.HttpServletResponse;
|
|||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@WebFilter(urlPatterns = "/*", filterName = "httpBasicAuthorizedFilter")
|
@WebFilter(urlPatterns = "/*", filterName = "httpBasicAuthorizedFilter")
|
||||||
public class HttpBasicAuthorizedFilter implements Filter {
|
public class HttpBasicAuthorizedFilter implements Filter {
|
||||||
|
|
||||||
|
@@ -25,7 +25,9 @@ import java.util.Map;
|
|||||||
|
|
||||||
public class MessageView {
|
public class MessageView {
|
||||||
|
|
||||||
/** from MessageExt **/
|
/**
|
||||||
|
* from MessageExt
|
||||||
|
**/
|
||||||
private int queueId;
|
private int queueId;
|
||||||
private int storeSize;
|
private int storeSize;
|
||||||
private long queueOffset;
|
private long queueOffset;
|
||||||
@@ -41,13 +43,17 @@ public class MessageView {
|
|||||||
private long preparedTransactionOffset;
|
private long preparedTransactionOffset;
|
||||||
/**from MessageExt**/
|
/**from MessageExt**/
|
||||||
|
|
||||||
/** from Message **/
|
/**
|
||||||
|
* from Message
|
||||||
|
**/
|
||||||
private String topic;
|
private String topic;
|
||||||
private int flag;
|
private int flag;
|
||||||
private Map<String, String> properties;
|
private Map<String, String> properties;
|
||||||
private String messageBody; // body
|
private String messageBody; // body
|
||||||
|
|
||||||
/** from Message **/
|
/**
|
||||||
|
* from Message
|
||||||
|
**/
|
||||||
|
|
||||||
public static MessageView fromMessageExt(MessageExt messageExt) {
|
public static MessageView fromMessageExt(MessageExt messageExt) {
|
||||||
MessageView messageView = new MessageView();
|
MessageView messageView = new MessageView();
|
||||||
|
@@ -15,6 +15,7 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
package org.apache.rocketmq.dashboard.model.request;
|
package org.apache.rocketmq.dashboard.model.request;
|
||||||
|
|
||||||
import com.google.common.base.Objects;
|
import com.google.common.base.Objects;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@@ -24,7 +25,9 @@ public class TopicConfigInfo {
|
|||||||
private List<String> clusterNameList;
|
private List<String> clusterNameList;
|
||||||
private List<String> brokerNameList;
|
private List<String> brokerNameList;
|
||||||
|
|
||||||
/** topicConfig */
|
/**
|
||||||
|
* topicConfig
|
||||||
|
*/
|
||||||
private String topicName;
|
private String topicName;
|
||||||
private int writeQueueNums;
|
private int writeQueueNums;
|
||||||
private int readQueueNums;
|
private int readQueueNums;
|
||||||
@@ -32,6 +35,7 @@ public class TopicConfigInfo {
|
|||||||
private boolean order;
|
private boolean order;
|
||||||
|
|
||||||
private String messageType;
|
private String messageType;
|
||||||
|
|
||||||
public List<String> getClusterNameList() {
|
public List<String> getClusterNameList() {
|
||||||
return clusterNameList;
|
return clusterNameList;
|
||||||
}
|
}
|
||||||
@@ -40,8 +44,9 @@ public class TopicConfigInfo {
|
|||||||
this.clusterNameList = clusterNameList;
|
this.clusterNameList = clusterNameList;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** topicConfig */
|
/**
|
||||||
|
* topicConfig
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
public List<String> getBrokerNameList() {
|
public List<String> getBrokerNameList() {
|
||||||
@@ -102,8 +107,6 @@ public class TopicConfigInfo {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean equals(Object o) {
|
public boolean equals(Object o) {
|
||||||
if (this == o)
|
if (this == o)
|
||||||
@@ -112,16 +115,16 @@ public class TopicConfigInfo {
|
|||||||
return false;
|
return false;
|
||||||
TopicConfigInfo that = (TopicConfigInfo) o;
|
TopicConfigInfo that = (TopicConfigInfo) o;
|
||||||
return writeQueueNums == that.writeQueueNums &&
|
return writeQueueNums == that.writeQueueNums &&
|
||||||
readQueueNums == that.readQueueNums &&
|
readQueueNums == that.readQueueNums &&
|
||||||
perm == that.perm &&
|
perm == that.perm &&
|
||||||
order == that.order &&
|
order == that.order &&
|
||||||
Objects.equal(topicName, that.topicName) &&
|
Objects.equal(topicName, that.topicName) &&
|
||||||
Objects.equal(messageType, that.messageType);
|
Objects.equal(messageType, that.messageType);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int hashCode() {
|
public int hashCode() {
|
||||||
return Objects.hashCode(topicName, writeQueueNums, readQueueNums, perm, order,messageType);
|
return Objects.hashCode(topicName, writeQueueNums, readQueueNums, perm, order, messageType);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@@ -29,16 +29,16 @@ import java.util.Set;
|
|||||||
public abstract class AbstractCommonService {
|
public abstract class AbstractCommonService {
|
||||||
@Resource
|
@Resource
|
||||||
protected MQAdminExt mqAdminExt;
|
protected MQAdminExt mqAdminExt;
|
||||||
|
|
||||||
protected final Set<String> changeToBrokerNameSet(Map<String, Set<String>> clusterAddrTable,
|
protected final Set<String> changeToBrokerNameSet(Map<String, Set<String>> clusterAddrTable,
|
||||||
List<String> clusterNameList, List<String> brokerNameList) {
|
List<String> clusterNameList, List<String> brokerNameList) {
|
||||||
Set<String> finalBrokerNameList = Sets.newHashSet();
|
Set<String> finalBrokerNameList = Sets.newHashSet();
|
||||||
if (CollectionUtils.isNotEmpty(clusterNameList)) {
|
if (CollectionUtils.isNotEmpty(clusterNameList)) {
|
||||||
try {
|
try {
|
||||||
for (String clusterName : clusterNameList) {
|
for (String clusterName : clusterNameList) {
|
||||||
finalBrokerNameList.addAll(clusterAddrTable.get(clusterName));
|
finalBrokerNameList.addAll(clusterAddrTable.get(clusterName));
|
||||||
}
|
}
|
||||||
}
|
} catch (Exception e) {
|
||||||
catch (Exception e) {
|
|
||||||
Throwables.throwIfUnchecked(e);
|
Throwables.throwIfUnchecked(e);
|
||||||
throw new RuntimeException(e);
|
throw new RuntimeException(e);
|
||||||
}
|
}
|
||||||
|
@@ -39,5 +39,5 @@ public interface AclService {
|
|||||||
|
|
||||||
void deleteAcl(String brokerAddress, String subject, String resource);
|
void deleteAcl(String brokerAddress, String subject, String resource);
|
||||||
|
|
||||||
void updateAcl(PolicyRequest policyRequest);
|
void updateAcl(PolicyRequest policyRequest);
|
||||||
}
|
}
|
||||||
|
@@ -31,7 +31,7 @@ import java.util.Map;
|
|||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
public interface ConsumerService {
|
public interface ConsumerService {
|
||||||
List<GroupConsumeInfo> queryGroupList(boolean skipSysGroup,String address);
|
List<GroupConsumeInfo> queryGroupList(boolean skipSysGroup, String address);
|
||||||
|
|
||||||
GroupConsumeInfo queryGroup(String consumerGroup, String address);
|
GroupConsumeInfo queryGroup(String consumerGroup, String address);
|
||||||
|
|
||||||
|
@@ -32,7 +32,7 @@ public interface DashboardService {
|
|||||||
Map<String, List<String>> queryTopicData(String date);
|
Map<String, List<String>> queryTopicData(String date);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param date format yyyy-MM-dd
|
* @param date format yyyy-MM-dd
|
||||||
* @param topicName
|
* @param topicName
|
||||||
*/
|
*/
|
||||||
List<String> queryTopicData(String date, String topicName);
|
List<String> queryTopicData(String date, String topicName);
|
||||||
|
@@ -39,21 +39,18 @@ public interface MessageService {
|
|||||||
/**
|
/**
|
||||||
* @param topic
|
* @param topic
|
||||||
* @param begin
|
* @param begin
|
||||||
* @param end
|
* @param end org.apache.rocketmq.tools.command.message.PrintMessageSubCommand
|
||||||
* org.apache.rocketmq.tools.command.message.PrintMessageSubCommand
|
|
||||||
*/
|
*/
|
||||||
List<MessageView> queryMessageByTopic(final String topic, final long begin,
|
List<MessageView> queryMessageByTopic(final String topic, final long begin,
|
||||||
final long end);
|
final long end);
|
||||||
|
|
||||||
List<MessageTrack> messageTrackDetail(MessageExt msg);
|
List<MessageTrack> messageTrackDetail(MessageExt msg);
|
||||||
|
|
||||||
ConsumeMessageDirectlyResult consumeMessageDirectly(String topic, String msgId, String consumerGroup,
|
ConsumeMessageDirectlyResult consumeMessageDirectly(String topic, String msgId, String consumerGroup,
|
||||||
String clientId);
|
String clientId);
|
||||||
|
|
||||||
|
|
||||||
MessagePage queryMessageByPage(MessageQuery query);
|
MessagePage queryMessageByPage(MessageQuery query);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@@ -27,7 +27,7 @@ public interface OpsService {
|
|||||||
|
|
||||||
String getNameSvrList();
|
String getNameSvrList();
|
||||||
|
|
||||||
Map<CheckerType,Object> rocketMqStatusCheck();
|
Map<CheckerType, Object> rocketMqStatusCheck();
|
||||||
|
|
||||||
boolean updateIsVIPChannel(String useVIPChannel);
|
boolean updateIsVIPChannel(String useVIPChannel);
|
||||||
|
|
||||||
|
@@ -24,5 +24,5 @@ public interface ProxyService {
|
|||||||
|
|
||||||
void updateProxyAddrList(String proxyAddr);
|
void updateProxyAddrList(String proxyAddr);
|
||||||
|
|
||||||
Map<String, Object> getProxyHomePage();
|
Map<String, Object> getProxyHomePage();
|
||||||
}
|
}
|
||||||
|
@@ -94,19 +94,20 @@ public class MQAdminExtImpl implements MQAdminExt {
|
|||||||
private Logger logger = LoggerFactory.getLogger(MQAdminExtImpl.class);
|
private Logger logger = LoggerFactory.getLogger(MQAdminExtImpl.class);
|
||||||
|
|
||||||
|
|
||||||
public MQAdminExtImpl() {}
|
public MQAdminExtImpl() {
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void updateBrokerConfig(String brokerAddr, Properties properties)
|
public void updateBrokerConfig(String brokerAddr, Properties properties)
|
||||||
throws RemotingConnectException, RemotingSendRequestException, RemotingTimeoutException,
|
throws RemotingConnectException, RemotingSendRequestException, RemotingTimeoutException,
|
||||||
UnsupportedEncodingException, InterruptedException, MQBrokerException, MQClientException {
|
UnsupportedEncodingException, InterruptedException, MQBrokerException, MQClientException {
|
||||||
MQAdminInstance.threadLocalMQAdminExt().updateBrokerConfig(brokerAddr, properties);
|
MQAdminInstance.threadLocalMQAdminExt().updateBrokerConfig(brokerAddr, properties);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void createAndUpdateTopicConfig(String addr, TopicConfig config)
|
public void createAndUpdateTopicConfig(String addr, TopicConfig config)
|
||||||
throws RemotingException, MQBrokerException, InterruptedException, MQClientException {
|
throws RemotingException, MQBrokerException, InterruptedException, MQClientException {
|
||||||
MQAdminInstance.threadLocalMQAdminExt().createAndUpdateTopicConfig(addr, config);
|
MQAdminInstance.threadLocalMQAdminExt().createAndUpdateTopicConfig(addr, config);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -118,7 +119,7 @@ public class MQAdminExtImpl implements MQAdminExt {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void createAndUpdateSubscriptionGroupConfig(String addr, SubscriptionGroupConfig config)
|
public void createAndUpdateSubscriptionGroupConfig(String addr, SubscriptionGroupConfig config)
|
||||||
throws RemotingException, MQBrokerException, InterruptedException, MQClientException {
|
throws RemotingException, MQBrokerException, InterruptedException, MQClientException {
|
||||||
MQAdminInstance.threadLocalMQAdminExt().createAndUpdateSubscriptionGroupConfig(addr, config);
|
MQAdminInstance.threadLocalMQAdminExt().createAndUpdateSubscriptionGroupConfig(addr, config);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -134,8 +135,7 @@ public class MQAdminExtImpl implements MQAdminExt {
|
|||||||
RemotingCommand response = null;
|
RemotingCommand response = null;
|
||||||
try {
|
try {
|
||||||
response = remotingClient.invokeSync(addr, request, 8000);
|
response = remotingClient.invokeSync(addr, request, 8000);
|
||||||
}
|
} catch (Exception err) {
|
||||||
catch (Exception err) {
|
|
||||||
Throwables.throwIfUnchecked(err);
|
Throwables.throwIfUnchecked(err);
|
||||||
throw new RuntimeException(err);
|
throw new RuntimeException(err);
|
||||||
}
|
}
|
||||||
@@ -178,7 +178,7 @@ public class MQAdminExtImpl implements MQAdminExt {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public TopicStatsTable examineTopicStats(String topic)
|
public TopicStatsTable examineTopicStats(String topic)
|
||||||
throws RemotingException, MQClientException, InterruptedException, MQBrokerException {
|
throws RemotingException, MQClientException, InterruptedException, MQBrokerException {
|
||||||
return MQAdminInstance.threadLocalMQAdminExt().examineTopicStats(topic);
|
return MQAdminInstance.threadLocalMQAdminExt().examineTopicStats(topic);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -191,14 +191,14 @@ public class MQAdminExtImpl implements MQAdminExt {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public KVTable fetchBrokerRuntimeStats(String brokerAddr)
|
public KVTable fetchBrokerRuntimeStats(String brokerAddr)
|
||||||
throws RemotingConnectException, RemotingSendRequestException, RemotingTimeoutException,
|
throws RemotingConnectException, RemotingSendRequestException, RemotingTimeoutException,
|
||||||
InterruptedException, MQBrokerException {
|
InterruptedException, MQBrokerException {
|
||||||
return MQAdminInstance.threadLocalMQAdminExt().fetchBrokerRuntimeStats(brokerAddr);
|
return MQAdminInstance.threadLocalMQAdminExt().fetchBrokerRuntimeStats(brokerAddr);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ConsumeStats examineConsumeStats(String consumerGroup)
|
public ConsumeStats examineConsumeStats(String consumerGroup)
|
||||||
throws RemotingException, MQClientException, InterruptedException, MQBrokerException {
|
throws RemotingException, MQClientException, InterruptedException, MQBrokerException {
|
||||||
return MQAdminInstance.threadLocalMQAdminExt().examineConsumeStats(consumerGroup);
|
return MQAdminInstance.threadLocalMQAdminExt().examineConsumeStats(consumerGroup);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -209,7 +209,7 @@ public class MQAdminExtImpl implements MQAdminExt {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ConsumeStats examineConsumeStats(String consumerGroup, String topic)
|
public ConsumeStats examineConsumeStats(String consumerGroup, String topic)
|
||||||
throws RemotingException, MQClientException, InterruptedException, MQBrokerException {
|
throws RemotingException, MQClientException, InterruptedException, MQBrokerException {
|
||||||
return MQAdminInstance.threadLocalMQAdminExt().examineConsumeStats(consumerGroup, topic);
|
return MQAdminInstance.threadLocalMQAdminExt().examineConsumeStats(consumerGroup, topic);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -220,27 +220,27 @@ public class MQAdminExtImpl implements MQAdminExt {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ClusterInfo examineBrokerClusterInfo()
|
public ClusterInfo examineBrokerClusterInfo()
|
||||||
throws InterruptedException, MQBrokerException, RemotingTimeoutException, RemotingSendRequestException,
|
throws InterruptedException, MQBrokerException, RemotingTimeoutException, RemotingSendRequestException,
|
||||||
RemotingConnectException {
|
RemotingConnectException {
|
||||||
return MQAdminInstance.threadLocalMQAdminExt().examineBrokerClusterInfo();
|
return MQAdminInstance.threadLocalMQAdminExt().examineBrokerClusterInfo();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public TopicRouteData examineTopicRouteInfo(String topic)
|
public TopicRouteData examineTopicRouteInfo(String topic)
|
||||||
throws RemotingException, MQClientException, InterruptedException {
|
throws RemotingException, MQClientException, InterruptedException {
|
||||||
return MQAdminInstance.threadLocalMQAdminExt().examineTopicRouteInfo(topic);
|
return MQAdminInstance.threadLocalMQAdminExt().examineTopicRouteInfo(topic);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ConsumerConnection examineConsumerConnectionInfo(String consumerGroup)
|
public ConsumerConnection examineConsumerConnectionInfo(String consumerGroup)
|
||||||
throws RemotingConnectException, RemotingSendRequestException, RemotingTimeoutException,
|
throws RemotingConnectException, RemotingSendRequestException, RemotingTimeoutException,
|
||||||
InterruptedException, MQBrokerException, RemotingException, MQClientException {
|
InterruptedException, MQBrokerException, RemotingException, MQClientException {
|
||||||
return MQAdminInstance.threadLocalMQAdminExt().examineConsumerConnectionInfo(consumerGroup);
|
return MQAdminInstance.threadLocalMQAdminExt().examineConsumerConnectionInfo(consumerGroup);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ProducerConnection examineProducerConnectionInfo(String producerGroup, String topic)
|
public ProducerConnection examineProducerConnectionInfo(String producerGroup, String topic)
|
||||||
throws RemotingException, MQClientException, InterruptedException, MQBrokerException {
|
throws RemotingException, MQClientException, InterruptedException, MQBrokerException {
|
||||||
return MQAdminInstance.threadLocalMQAdminExt().examineProducerConnectionInfo(producerGroup, topic);
|
return MQAdminInstance.threadLocalMQAdminExt().examineProducerConnectionInfo(producerGroup, topic);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -251,14 +251,14 @@ public class MQAdminExtImpl implements MQAdminExt {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int wipeWritePermOfBroker(String namesrvAddr, String brokerName)
|
public int wipeWritePermOfBroker(String namesrvAddr, String brokerName)
|
||||||
throws RemotingCommandException, RemotingConnectException, RemotingSendRequestException,
|
throws RemotingCommandException, RemotingConnectException, RemotingSendRequestException,
|
||||||
RemotingTimeoutException, InterruptedException, MQClientException {
|
RemotingTimeoutException, InterruptedException, MQClientException {
|
||||||
return MQAdminInstance.threadLocalMQAdminExt().wipeWritePermOfBroker(namesrvAddr, brokerName);
|
return MQAdminInstance.threadLocalMQAdminExt().wipeWritePermOfBroker(namesrvAddr, brokerName);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int addWritePermOfBroker(String namesrvAddr,
|
public int addWritePermOfBroker(String namesrvAddr,
|
||||||
String brokerName) throws RemotingCommandException, RemotingConnectException, RemotingSendRequestException, RemotingTimeoutException, InterruptedException, MQClientException {
|
String brokerName) throws RemotingCommandException, RemotingConnectException, RemotingSendRequestException, RemotingTimeoutException, InterruptedException, MQClientException {
|
||||||
return MQAdminInstance.threadLocalMQAdminExt().addWritePermOfBroker(namesrvAddr, brokerName);
|
return MQAdminInstance.threadLocalMQAdminExt().addWritePermOfBroker(namesrvAddr, brokerName);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -269,62 +269,62 @@ public class MQAdminExtImpl implements MQAdminExt {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getKVConfig(String namespace, String key)
|
public String getKVConfig(String namespace, String key)
|
||||||
throws RemotingException, MQClientException, InterruptedException {
|
throws RemotingException, MQClientException, InterruptedException {
|
||||||
return MQAdminInstance.threadLocalMQAdminExt().getKVConfig(namespace, key);
|
return MQAdminInstance.threadLocalMQAdminExt().getKVConfig(namespace, key);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public KVTable getKVListByNamespace(String namespace)
|
public KVTable getKVListByNamespace(String namespace)
|
||||||
throws RemotingException, MQClientException, InterruptedException {
|
throws RemotingException, MQClientException, InterruptedException {
|
||||||
return MQAdminInstance.threadLocalMQAdminExt().getKVListByNamespace(namespace);
|
return MQAdminInstance.threadLocalMQAdminExt().getKVListByNamespace(namespace);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void deleteTopicInBroker(Set<String> addrs, String topic)
|
public void deleteTopicInBroker(Set<String> addrs, String topic)
|
||||||
throws RemotingException, MQBrokerException, InterruptedException, MQClientException {
|
throws RemotingException, MQBrokerException, InterruptedException, MQClientException {
|
||||||
logger.info("addrs={} topic={}", JsonUtil.obj2String(addrs), topic);
|
logger.info("addrs={} topic={}", JsonUtil.obj2String(addrs), topic);
|
||||||
MQAdminInstance.threadLocalMQAdminExt().deleteTopicInBroker(addrs, topic);
|
MQAdminInstance.threadLocalMQAdminExt().deleteTopicInBroker(addrs, topic);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void deleteTopicInNameServer(Set<String> addrs, String topic)
|
public void deleteTopicInNameServer(Set<String> addrs, String topic)
|
||||||
throws RemotingException, MQBrokerException, InterruptedException, MQClientException {
|
throws RemotingException, MQBrokerException, InterruptedException, MQClientException {
|
||||||
MQAdminInstance.threadLocalMQAdminExt().deleteTopicInNameServer(addrs, topic);
|
MQAdminInstance.threadLocalMQAdminExt().deleteTopicInNameServer(addrs, topic);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void deleteSubscriptionGroup(String addr, String groupName)
|
public void deleteSubscriptionGroup(String addr, String groupName)
|
||||||
throws RemotingException, MQBrokerException, InterruptedException, MQClientException {
|
throws RemotingException, MQBrokerException, InterruptedException, MQClientException {
|
||||||
MQAdminInstance.threadLocalMQAdminExt().deleteSubscriptionGroup(addr, groupName);
|
MQAdminInstance.threadLocalMQAdminExt().deleteSubscriptionGroup(addr, groupName);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void deleteSubscriptionGroup(String addr, String groupName, boolean removeOffset)
|
public void deleteSubscriptionGroup(String addr, String groupName, boolean removeOffset)
|
||||||
throws RemotingException, MQBrokerException, InterruptedException, MQClientException {
|
throws RemotingException, MQBrokerException, InterruptedException, MQClientException {
|
||||||
MQAdminInstance.threadLocalMQAdminExt().deleteSubscriptionGroup(addr, groupName, removeOffset);
|
MQAdminInstance.threadLocalMQAdminExt().deleteSubscriptionGroup(addr, groupName, removeOffset);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void createAndUpdateKvConfig(String namespace, String key, String value)
|
public void createAndUpdateKvConfig(String namespace, String key, String value)
|
||||||
throws RemotingException, MQBrokerException, InterruptedException, MQClientException {
|
throws RemotingException, MQBrokerException, InterruptedException, MQClientException {
|
||||||
MQAdminInstance.threadLocalMQAdminExt().createAndUpdateKvConfig(namespace, key, value);
|
MQAdminInstance.threadLocalMQAdminExt().createAndUpdateKvConfig(namespace, key, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void deleteKvConfig(String namespace, String key)
|
public void deleteKvConfig(String namespace, String key)
|
||||||
throws RemotingException, MQBrokerException, InterruptedException, MQClientException {
|
throws RemotingException, MQBrokerException, InterruptedException, MQClientException {
|
||||||
MQAdminInstance.threadLocalMQAdminExt().deleteKvConfig(namespace, key);
|
MQAdminInstance.threadLocalMQAdminExt().deleteKvConfig(namespace, key);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<RollbackStats> resetOffsetByTimestampOld(String consumerGroup, String topic, long timestamp,
|
public List<RollbackStats> resetOffsetByTimestampOld(String consumerGroup, String topic, long timestamp,
|
||||||
boolean force) throws RemotingException, MQBrokerException, InterruptedException, MQClientException {
|
boolean force) throws RemotingException, MQBrokerException, InterruptedException, MQClientException {
|
||||||
return MQAdminInstance.threadLocalMQAdminExt().resetOffsetByTimestampOld(consumerGroup, topic, timestamp, force);
|
return MQAdminInstance.threadLocalMQAdminExt().resetOffsetByTimestampOld(consumerGroup, topic, timestamp, force);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Map<MessageQueue, Long> resetOffsetByTimestamp(String topic, String group, long timestamp,
|
public Map<MessageQueue, Long> resetOffsetByTimestamp(String topic, String group, long timestamp,
|
||||||
boolean isForce) throws RemotingException, MQBrokerException, InterruptedException, MQClientException {
|
boolean isForce) throws RemotingException, MQBrokerException, InterruptedException, MQClientException {
|
||||||
return MQAdminInstance.threadLocalMQAdminExt().resetOffsetByTimestamp(topic, group, timestamp, isForce);
|
return MQAdminInstance.threadLocalMQAdminExt().resetOffsetByTimestamp(topic, group, timestamp, isForce);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -335,59 +335,59 @@ public class MQAdminExtImpl implements MQAdminExt {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void resetOffsetNew(String consumerGroup, String topic, long timestamp)
|
public void resetOffsetNew(String consumerGroup, String topic, long timestamp)
|
||||||
throws RemotingException, MQBrokerException, InterruptedException, MQClientException {
|
throws RemotingException, MQBrokerException, InterruptedException, MQClientException {
|
||||||
MQAdminInstance.threadLocalMQAdminExt().resetOffsetNew(consumerGroup, topic, timestamp);
|
MQAdminInstance.threadLocalMQAdminExt().resetOffsetNew(consumerGroup, topic, timestamp);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Map<String, Map<MessageQueue, Long>> getConsumeStatus(String topic, String group,
|
public Map<String, Map<MessageQueue, Long>> getConsumeStatus(String topic, String group,
|
||||||
String clientAddr) throws RemotingException, MQBrokerException, InterruptedException, MQClientException {
|
String clientAddr) throws RemotingException, MQBrokerException, InterruptedException, MQClientException {
|
||||||
return MQAdminInstance.threadLocalMQAdminExt().getConsumeStatus(topic, group, clientAddr);
|
return MQAdminInstance.threadLocalMQAdminExt().getConsumeStatus(topic, group, clientAddr);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void createOrUpdateOrderConf(String key, String value, boolean isCluster)
|
public void createOrUpdateOrderConf(String key, String value, boolean isCluster)
|
||||||
throws RemotingException, MQBrokerException, InterruptedException, MQClientException {
|
throws RemotingException, MQBrokerException, InterruptedException, MQClientException {
|
||||||
MQAdminInstance.threadLocalMQAdminExt().createOrUpdateOrderConf(key, value, isCluster);
|
MQAdminInstance.threadLocalMQAdminExt().createOrUpdateOrderConf(key, value, isCluster);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public GroupList queryTopicConsumeByWho(String topic)
|
public GroupList queryTopicConsumeByWho(String topic)
|
||||||
throws RemotingConnectException, RemotingSendRequestException, RemotingTimeoutException,
|
throws RemotingConnectException, RemotingSendRequestException, RemotingTimeoutException,
|
||||||
InterruptedException, MQBrokerException, RemotingException, MQClientException {
|
InterruptedException, MQBrokerException, RemotingException, MQClientException {
|
||||||
return MQAdminInstance.threadLocalMQAdminExt().queryTopicConsumeByWho(topic);
|
return MQAdminInstance.threadLocalMQAdminExt().queryTopicConsumeByWho(topic);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean cleanExpiredConsumerQueue(String cluster)
|
public boolean cleanExpiredConsumerQueue(String cluster)
|
||||||
throws RemotingConnectException, RemotingSendRequestException, RemotingTimeoutException, MQClientException,
|
throws RemotingConnectException, RemotingSendRequestException, RemotingTimeoutException, MQClientException,
|
||||||
InterruptedException {
|
InterruptedException {
|
||||||
return MQAdminInstance.threadLocalMQAdminExt().cleanExpiredConsumerQueue(cluster);
|
return MQAdminInstance.threadLocalMQAdminExt().cleanExpiredConsumerQueue(cluster);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean cleanExpiredConsumerQueueByAddr(String addr)
|
public boolean cleanExpiredConsumerQueueByAddr(String addr)
|
||||||
throws RemotingConnectException, RemotingSendRequestException, RemotingTimeoutException, MQClientException,
|
throws RemotingConnectException, RemotingSendRequestException, RemotingTimeoutException, MQClientException,
|
||||||
InterruptedException {
|
InterruptedException {
|
||||||
return MQAdminInstance.threadLocalMQAdminExt().cleanExpiredConsumerQueueByAddr(addr);
|
return MQAdminInstance.threadLocalMQAdminExt().cleanExpiredConsumerQueueByAddr(addr);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ConsumerRunningInfo getConsumerRunningInfo(String consumerGroup, String clientId, boolean jstack)
|
public ConsumerRunningInfo getConsumerRunningInfo(String consumerGroup, String clientId, boolean jstack)
|
||||||
throws RemotingException, MQClientException, InterruptedException {
|
throws RemotingException, MQClientException, InterruptedException {
|
||||||
return MQAdminInstance.threadLocalMQAdminExt().getConsumerRunningInfo(consumerGroup, clientId, jstack);
|
return MQAdminInstance.threadLocalMQAdminExt().getConsumerRunningInfo(consumerGroup, clientId, jstack);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<MessageTrack> messageTrackDetail(MessageExt msg)
|
public List<MessageTrack> messageTrackDetail(MessageExt msg)
|
||||||
throws RemotingException, MQClientException, InterruptedException, MQBrokerException {
|
throws RemotingException, MQClientException, InterruptedException, MQBrokerException {
|
||||||
return MQAdminInstance.threadLocalMQAdminExt().messageTrackDetail(msg);
|
return MQAdminInstance.threadLocalMQAdminExt().messageTrackDetail(msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void cloneGroupOffset(String srcGroup, String destGroup, String topic, boolean isOffline)
|
public void cloneGroupOffset(String srcGroup, String destGroup, String topic, boolean isOffline)
|
||||||
throws RemotingException, MQClientException, InterruptedException, MQBrokerException {
|
throws RemotingException, MQClientException, InterruptedException, MQBrokerException {
|
||||||
MQAdminInstance.threadLocalMQAdminExt().cloneGroupOffset(srcGroup, destGroup, topic, isOffline);
|
MQAdminInstance.threadLocalMQAdminExt().cloneGroupOffset(srcGroup, destGroup, topic, isOffline);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -398,7 +398,7 @@ public class MQAdminExtImpl implements MQAdminExt {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void createTopic(String key, String newTopic, int queueNum, int topicSysFlag, Map<String, String> attributes)
|
public void createTopic(String key, String newTopic, int queueNum, int topicSysFlag, Map<String, String> attributes)
|
||||||
throws MQClientException {
|
throws MQClientException {
|
||||||
MQAdminInstance.threadLocalMQAdminExt().createTopic(key, newTopic, queueNum, topicSysFlag, attributes);
|
MQAdminInstance.threadLocalMQAdminExt().createTopic(key, newTopic, queueNum, topicSysFlag, attributes);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -424,7 +424,7 @@ public class MQAdminExtImpl implements MQAdminExt {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public QueryResult queryMessage(String topic, String key, int maxNum, long begin, long end)
|
public QueryResult queryMessage(String topic, String key, int maxNum, long begin, long end)
|
||||||
throws MQClientException, InterruptedException {
|
throws MQClientException, InterruptedException {
|
||||||
return MQAdminInstance.threadLocalMQAdminExt().queryMessage(topic, key, maxNum, begin, end);
|
return MQAdminInstance.threadLocalMQAdminExt().queryMessage(topic, key, maxNum, begin, end);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -444,7 +444,7 @@ public class MQAdminExtImpl implements MQAdminExt {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<QueueTimeSpan> queryConsumeTimeSpan(String topic,
|
public List<QueueTimeSpan> queryConsumeTimeSpan(String topic,
|
||||||
String group) throws InterruptedException, MQBrokerException, RemotingException, MQClientException {
|
String group) throws InterruptedException, MQBrokerException, RemotingException, MQClientException {
|
||||||
return MQAdminInstance.threadLocalMQAdminExt().queryConsumeTimeSpan(topic, group);
|
return MQAdminInstance.threadLocalMQAdminExt().queryConsumeTimeSpan(topic, group);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -454,7 +454,7 @@ public class MQAdminExtImpl implements MQAdminExt {
|
|||||||
//https://github.com/apache/incubator-rocketmq/pull/69
|
//https://github.com/apache/incubator-rocketmq/pull/69
|
||||||
@Override
|
@Override
|
||||||
public MessageExt viewMessage(String topic,
|
public MessageExt viewMessage(String topic,
|
||||||
String msgId) throws RemotingException, MQBrokerException, InterruptedException, MQClientException {
|
String msgId) throws RemotingException, MQBrokerException, InterruptedException, MQClientException {
|
||||||
logger.info("MessageClientIDSetter.getNearlyTimeFromID(msgId)={} msgId={}", MessageClientIDSetter.getNearlyTimeFromID(msgId), msgId);
|
logger.info("MessageClientIDSetter.getNearlyTimeFromID(msgId)={} msgId={}", MessageClientIDSetter.getNearlyTimeFromID(msgId), msgId);
|
||||||
MQAdminImpl mqAdminImpl = MQAdminInstance.threadLocalMqClientInstance().getMQAdminImpl();
|
MQAdminImpl mqAdminImpl = MQAdminInstance.threadLocalMqClientInstance().getMQAdminImpl();
|
||||||
Set<String> clusterList = MQAdminInstance.threadLocalMQAdminExt().getTopicClusterList(topic);
|
Set<String> clusterList = MQAdminInstance.threadLocalMQAdminExt().getTopicClusterList(topic);
|
||||||
@@ -478,7 +478,7 @@ public class MQAdminExtImpl implements MQAdminExt {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ConsumeMessageDirectlyResult consumeMessageDirectly(String consumerGroup, String clientId, String topic,
|
public ConsumeMessageDirectlyResult consumeMessageDirectly(String consumerGroup, String clientId, String topic,
|
||||||
String msgId) throws RemotingException, MQClientException, InterruptedException, MQBrokerException {
|
String msgId) throws RemotingException, MQClientException, InterruptedException, MQBrokerException {
|
||||||
return MQAdminInstance.threadLocalMQAdminExt().consumeMessageDirectly(consumerGroup, clientId, topic, msgId);
|
return MQAdminInstance.threadLocalMQAdminExt().consumeMessageDirectly(consumerGroup, clientId, topic, msgId);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -489,96 +489,99 @@ public class MQAdminExtImpl implements MQAdminExt {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Properties getBrokerConfig(
|
public Properties getBrokerConfig(
|
||||||
String brokerAddr) throws RemotingConnectException, RemotingSendRequestException, RemotingTimeoutException, UnsupportedEncodingException, InterruptedException, MQBrokerException {
|
String brokerAddr) throws RemotingConnectException, RemotingSendRequestException, RemotingTimeoutException, UnsupportedEncodingException, InterruptedException, MQBrokerException {
|
||||||
return MQAdminInstance.threadLocalMQAdminExt().getBrokerConfig(brokerAddr);
|
return MQAdminInstance.threadLocalMQAdminExt().getBrokerConfig(brokerAddr);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public TopicList fetchTopicsByCLuster(
|
public TopicList fetchTopicsByCLuster(
|
||||||
String clusterName) throws RemotingException, MQClientException, InterruptedException {
|
String clusterName) throws RemotingException, MQClientException, InterruptedException {
|
||||||
return MQAdminInstance.threadLocalMQAdminExt().fetchTopicsByCLuster(clusterName);
|
return MQAdminInstance.threadLocalMQAdminExt().fetchTopicsByCLuster(clusterName);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean cleanUnusedTopic(
|
public boolean cleanUnusedTopic(
|
||||||
String cluster) throws RemotingConnectException, RemotingSendRequestException, RemotingTimeoutException, MQClientException, InterruptedException {
|
String cluster) throws RemotingConnectException, RemotingSendRequestException, RemotingTimeoutException, MQClientException, InterruptedException {
|
||||||
return MQAdminInstance.threadLocalMQAdminExt().cleanUnusedTopic(cluster);
|
return MQAdminInstance.threadLocalMQAdminExt().cleanUnusedTopic(cluster);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean cleanUnusedTopicByAddr(
|
public boolean cleanUnusedTopicByAddr(
|
||||||
String addr) throws RemotingConnectException, RemotingSendRequestException, RemotingTimeoutException, MQClientException, InterruptedException {
|
String addr) throws RemotingConnectException, RemotingSendRequestException, RemotingTimeoutException, MQClientException, InterruptedException {
|
||||||
return MQAdminInstance.threadLocalMQAdminExt().cleanUnusedTopicByAddr(addr);
|
return MQAdminInstance.threadLocalMQAdminExt().cleanUnusedTopicByAddr(addr);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public BrokerStatsData viewBrokerStatsData(String brokerAddr, String statsName,
|
public BrokerStatsData viewBrokerStatsData(String brokerAddr, String statsName,
|
||||||
String statsKey) throws RemotingConnectException, RemotingSendRequestException, RemotingTimeoutException, MQClientException, InterruptedException {
|
String statsKey) throws RemotingConnectException, RemotingSendRequestException, RemotingTimeoutException, MQClientException, InterruptedException {
|
||||||
return MQAdminInstance.threadLocalMQAdminExt().viewBrokerStatsData(brokerAddr, statsName, statsKey);
|
return MQAdminInstance.threadLocalMQAdminExt().viewBrokerStatsData(brokerAddr, statsName, statsKey);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Set<String> getClusterList(
|
public Set<String> getClusterList(
|
||||||
String topic) throws RemotingConnectException, RemotingSendRequestException, RemotingTimeoutException, MQClientException, InterruptedException {
|
String topic) throws RemotingConnectException, RemotingSendRequestException, RemotingTimeoutException, MQClientException, InterruptedException {
|
||||||
return MQAdminInstance.threadLocalMQAdminExt().getClusterList(topic);
|
return MQAdminInstance.threadLocalMQAdminExt().getClusterList(topic);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ConsumeStatsList fetchConsumeStatsInBroker(String brokerAddr, boolean isOrder,
|
public ConsumeStatsList fetchConsumeStatsInBroker(String brokerAddr, boolean isOrder,
|
||||||
long timeoutMillis) throws RemotingConnectException, RemotingSendRequestException, RemotingTimeoutException, MQClientException, InterruptedException {
|
long timeoutMillis) throws RemotingConnectException, RemotingSendRequestException, RemotingTimeoutException, MQClientException, InterruptedException {
|
||||||
return MQAdminInstance.threadLocalMQAdminExt().fetchConsumeStatsInBroker(brokerAddr, isOrder, timeoutMillis);
|
return MQAdminInstance.threadLocalMQAdminExt().fetchConsumeStatsInBroker(brokerAddr, isOrder, timeoutMillis);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Set<String> getTopicClusterList(
|
public Set<String> getTopicClusterList(
|
||||||
String topic) throws InterruptedException, MQBrokerException, MQClientException, RemotingException {
|
String topic) throws InterruptedException, MQBrokerException, MQClientException, RemotingException {
|
||||||
return MQAdminInstance.threadLocalMQAdminExt().getTopicClusterList(topic);
|
return MQAdminInstance.threadLocalMQAdminExt().getTopicClusterList(topic);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public SubscriptionGroupWrapper getAllSubscriptionGroup(String brokerAddr,
|
public SubscriptionGroupWrapper getAllSubscriptionGroup(String brokerAddr,
|
||||||
long timeoutMillis) throws InterruptedException, RemotingTimeoutException, RemotingSendRequestException, RemotingConnectException, MQBrokerException {
|
long timeoutMillis) throws InterruptedException, RemotingTimeoutException, RemotingSendRequestException, RemotingConnectException, MQBrokerException {
|
||||||
return MQAdminInstance.threadLocalMQAdminExt().getAllSubscriptionGroup(brokerAddr, timeoutMillis);
|
return MQAdminInstance.threadLocalMQAdminExt().getAllSubscriptionGroup(brokerAddr, timeoutMillis);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public SubscriptionGroupWrapper getUserSubscriptionGroup(String brokerAddr,
|
public SubscriptionGroupWrapper getUserSubscriptionGroup(String brokerAddr,
|
||||||
long timeoutMillis) throws InterruptedException, RemotingTimeoutException, RemotingSendRequestException, RemotingConnectException, MQBrokerException {
|
long timeoutMillis) throws InterruptedException, RemotingTimeoutException, RemotingSendRequestException, RemotingConnectException, MQBrokerException {
|
||||||
return MQAdminInstance.threadLocalMQAdminExt().getUserSubscriptionGroup(brokerAddr, timeoutMillis);
|
return MQAdminInstance.threadLocalMQAdminExt().getUserSubscriptionGroup(brokerAddr, timeoutMillis);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public TopicConfigSerializeWrapper getAllTopicConfig(String brokerAddr,
|
public TopicConfigSerializeWrapper getAllTopicConfig(String brokerAddr,
|
||||||
long timeoutMillis) throws InterruptedException, RemotingTimeoutException, RemotingSendRequestException, RemotingConnectException, MQBrokerException {
|
long timeoutMillis) throws InterruptedException, RemotingTimeoutException, RemotingSendRequestException, RemotingConnectException, MQBrokerException {
|
||||||
return MQAdminInstance.threadLocalMQAdminExt().getAllTopicConfig(brokerAddr, timeoutMillis);
|
return MQAdminInstance.threadLocalMQAdminExt().getAllTopicConfig(brokerAddr, timeoutMillis);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public TopicConfigSerializeWrapper getUserTopicConfig(String brokerAddr, boolean specialTopic,
|
public TopicConfigSerializeWrapper getUserTopicConfig(String brokerAddr, boolean specialTopic,
|
||||||
long timeoutMillis) throws InterruptedException, RemotingException, MQBrokerException, MQClientException {
|
long timeoutMillis) throws InterruptedException, RemotingException, MQBrokerException, MQClientException {
|
||||||
return MQAdminInstance.threadLocalMQAdminExt().getUserTopicConfig(brokerAddr, specialTopic, timeoutMillis);
|
return MQAdminInstance.threadLocalMQAdminExt().getUserTopicConfig(brokerAddr, specialTopic, timeoutMillis);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void updateConsumeOffset(String brokerAddr, String consumeGroup, MessageQueue mq,
|
public void updateConsumeOffset(String brokerAddr, String consumeGroup, MessageQueue mq,
|
||||||
long offset) throws RemotingException, InterruptedException, MQBrokerException {
|
long offset) throws RemotingException, InterruptedException, MQBrokerException {
|
||||||
MQAdminInstance.threadLocalMQAdminExt().updateConsumeOffset(brokerAddr, consumeGroup, mq, offset);
|
MQAdminInstance.threadLocalMQAdminExt().updateConsumeOffset(brokerAddr, consumeGroup, mq, offset);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 4.0.0 added
|
// 4.0.0 added
|
||||||
@Override public void updateNameServerConfig(Properties properties,
|
@Override
|
||||||
List<String> list) throws InterruptedException, RemotingConnectException, UnsupportedEncodingException, RemotingSendRequestException, RemotingTimeoutException, MQClientException, MQBrokerException {
|
public void updateNameServerConfig(Properties properties,
|
||||||
|
List<String> list) throws InterruptedException, RemotingConnectException, UnsupportedEncodingException, RemotingSendRequestException, RemotingTimeoutException, MQClientException, MQBrokerException {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override public Map<String, Properties> getNameServerConfig(
|
@Override
|
||||||
List<String> list) throws InterruptedException, RemotingTimeoutException, RemotingSendRequestException, RemotingConnectException, MQClientException, UnsupportedEncodingException {
|
public Map<String, Properties> getNameServerConfig(
|
||||||
|
List<String> list) throws InterruptedException, RemotingTimeoutException, RemotingSendRequestException, RemotingConnectException, MQClientException, UnsupportedEncodingException {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override public QueryConsumeQueueResponseBody queryConsumeQueue(String brokerAddr, String topic,
|
@Override
|
||||||
int queueId, long index, int count,
|
public QueryConsumeQueueResponseBody queryConsumeQueue(String brokerAddr, String topic,
|
||||||
String consumerGroup) throws InterruptedException, RemotingTimeoutException, RemotingSendRequestException, RemotingConnectException, MQClientException {
|
int queueId, long index, int count,
|
||||||
|
String consumerGroup) throws InterruptedException, RemotingTimeoutException, RemotingSendRequestException, RemotingConnectException, MQClientException {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -588,8 +591,9 @@ public class MQAdminExtImpl implements MQAdminExt {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override public boolean resumeCheckHalfMessage(String topic,
|
@Override
|
||||||
String msgId) throws RemotingException, MQClientException, InterruptedException, MQBrokerException {
|
public boolean resumeCheckHalfMessage(String topic,
|
||||||
|
String msgId) throws RemotingException, MQClientException, InterruptedException, MQBrokerException {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -602,7 +606,7 @@ public class MQAdminExtImpl implements MQAdminExt {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void removeBrokerFromContainer(String brokerContainerAddr, String clusterName, String brokerName,
|
public void removeBrokerFromContainer(String brokerContainerAddr, String clusterName, String brokerName,
|
||||||
long brokerId) throws InterruptedException, MQBrokerException, RemotingTimeoutException,
|
long brokerId) throws InterruptedException, MQBrokerException, RemotingTimeoutException,
|
||||||
RemotingSendRequestException, RemotingConnectException {
|
RemotingSendRequestException, RemotingConnectException {
|
||||||
// TODO Auto-generated method stub
|
// TODO Auto-generated method stub
|
||||||
throw new UnsupportedOperationException("Unimplemented method 'removeBrokerFromContainer'");
|
throw new UnsupportedOperationException("Unimplemented method 'removeBrokerFromContainer'");
|
||||||
@@ -624,7 +628,7 @@ public class MQAdminExtImpl implements MQAdminExt {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ConsumeStats examineConsumeStats(String brokerAddr, String consumerGroup, String topicName,
|
public ConsumeStats examineConsumeStats(String brokerAddr, String consumerGroup, String topicName,
|
||||||
long timeoutMillis) throws InterruptedException, RemotingTimeoutException, RemotingSendRequestException,
|
long timeoutMillis) throws InterruptedException, RemotingTimeoutException, RemotingSendRequestException,
|
||||||
RemotingConnectException, MQBrokerException {
|
RemotingConnectException, MQBrokerException {
|
||||||
// TODO Auto-generated method stub
|
// TODO Auto-generated method stub
|
||||||
return MQAdminInstance.threadLocalMQAdminExt().examineConsumeStats(brokerAddr, consumerGroup, topicName, timeoutMillis);
|
return MQAdminInstance.threadLocalMQAdminExt().examineConsumeStats(brokerAddr, consumerGroup, topicName, timeoutMillis);
|
||||||
@@ -717,7 +721,7 @@ public class MQAdminExtImpl implements MQAdminExt {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ConsumerRunningInfo getConsumerRunningInfo(String consumerGroup, String clientId, boolean jstack,
|
public ConsumerRunningInfo getConsumerRunningInfo(String consumerGroup, String clientId, boolean jstack,
|
||||||
boolean metrics) throws RemotingException, MQClientException, InterruptedException {
|
boolean metrics) throws RemotingException, MQClientException, InterruptedException {
|
||||||
// TODO Auto-generated method stub
|
// TODO Auto-generated method stub
|
||||||
throw new UnsupportedOperationException("Unimplemented method 'getConsumerRunningInfo'");
|
throw new UnsupportedOperationException("Unimplemented method 'getConsumerRunningInfo'");
|
||||||
}
|
}
|
||||||
@@ -731,7 +735,7 @@ public class MQAdminExtImpl implements MQAdminExt {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setMessageRequestMode(String brokerAddr, String topic, String consumerGroup, MessageRequestMode mode,
|
public void setMessageRequestMode(String brokerAddr, String topic, String consumerGroup, MessageRequestMode mode,
|
||||||
int popWorkGroupSize, long timeoutMillis) throws InterruptedException, RemotingTimeoutException,
|
int popWorkGroupSize, long timeoutMillis) throws InterruptedException, RemotingTimeoutException,
|
||||||
RemotingSendRequestException, RemotingConnectException, MQClientException {
|
RemotingSendRequestException, RemotingConnectException, MQClientException {
|
||||||
// TODO Auto-generated method stub
|
// TODO Auto-generated method stub
|
||||||
throw new UnsupportedOperationException("Unimplemented method 'setMessageRequestMode'");
|
throw new UnsupportedOperationException("Unimplemented method 'setMessageRequestMode'");
|
||||||
@@ -746,14 +750,14 @@ public class MQAdminExtImpl implements MQAdminExt {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void resetOffsetByQueueId(String brokerAddr, String consumerGroup, String topicName, int queueId,
|
public void resetOffsetByQueueId(String brokerAddr, String consumerGroup, String topicName, int queueId,
|
||||||
long resetOffset) throws RemotingException, InterruptedException, MQBrokerException {
|
long resetOffset) throws RemotingException, InterruptedException, MQBrokerException {
|
||||||
// TODO Auto-generated method stub
|
// TODO Auto-generated method stub
|
||||||
throw new UnsupportedOperationException("Unimplemented method 'resetOffsetByQueueId'");
|
throw new UnsupportedOperationException("Unimplemented method 'resetOffsetByQueueId'");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void createStaticTopic(String addr, String defaultTopic, TopicConfig topicConfig,
|
public void createStaticTopic(String addr, String defaultTopic, TopicConfig topicConfig,
|
||||||
TopicQueueMappingDetail mappingDetail, boolean force)
|
TopicQueueMappingDetail mappingDetail, boolean force)
|
||||||
throws RemotingException, InterruptedException, MQBrokerException {
|
throws RemotingException, InterruptedException, MQBrokerException {
|
||||||
// TODO Auto-generated method stub
|
// TODO Auto-generated method stub
|
||||||
throw new UnsupportedOperationException("Unimplemented method 'createStaticTopic'");
|
throw new UnsupportedOperationException("Unimplemented method 'createStaticTopic'");
|
||||||
@@ -761,7 +765,7 @@ public class MQAdminExtImpl implements MQAdminExt {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public GroupForbidden updateAndGetGroupReadForbidden(String brokerAddr, String groupName, String topicName,
|
public GroupForbidden updateAndGetGroupReadForbidden(String brokerAddr, String groupName, String topicName,
|
||||||
Boolean readable) throws RemotingException, InterruptedException, MQBrokerException {
|
Boolean readable) throws RemotingException, InterruptedException, MQBrokerException {
|
||||||
// TODO Auto-generated method stub
|
// TODO Auto-generated method stub
|
||||||
throw new UnsupportedOperationException("Unimplemented method 'updateAndGetGroupReadForbidden'");
|
throw new UnsupportedOperationException("Unimplemented method 'updateAndGetGroupReadForbidden'");
|
||||||
}
|
}
|
||||||
@@ -831,7 +835,7 @@ public class MQAdminExtImpl implements MQAdminExt {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void cleanControllerBrokerData(String controllerAddr, String clusterName, String brokerName,
|
public void cleanControllerBrokerData(String controllerAddr, String clusterName, String brokerName,
|
||||||
String brokerAddr, boolean isCleanLivingBroker)
|
String brokerAddr, boolean isCleanLivingBroker)
|
||||||
throws RemotingException, InterruptedException, MQBrokerException {
|
throws RemotingException, InterruptedException, MQBrokerException {
|
||||||
// TODO Auto-generated method stub
|
// TODO Auto-generated method stub
|
||||||
throw new UnsupportedOperationException("Unimplemented method 'cleanControllerBrokerData'");
|
throw new UnsupportedOperationException("Unimplemented method 'cleanControllerBrokerData'");
|
||||||
|
@@ -212,7 +212,6 @@ public class ConsumerServiceImpl extends AbstractCommonService implements Consum
|
|||||||
} else {
|
} else {
|
||||||
consumeInfo.setSubGroupType(subscriptionGroupTable.get(consumerGroup).isConsumeMessageOrderly() ? "FIFO" : "NORMAL");
|
consumeInfo.setSubGroupType(subscriptionGroupTable.get(consumerGroup).isConsumeMessageOrderly() ? "FIFO" : "NORMAL");
|
||||||
}
|
}
|
||||||
consumeInfo.setGroup(consumerGroup);
|
|
||||||
consumeInfo.setUpdateTime(new Date());
|
consumeInfo.setUpdateTime(new Date());
|
||||||
groupConsumeInfoList.add(consumeInfo);
|
groupConsumeInfoList.add(consumeInfo);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
@@ -270,6 +269,7 @@ public class ConsumerServiceImpl extends AbstractCommonService implements Consum
|
|||||||
logger.warn("examineConsumeStats or examineConsumerConnectionInfo exception, "
|
logger.warn("examineConsumeStats or examineConsumerConnectionInfo exception, "
|
||||||
+ consumerGroup, e);
|
+ consumerGroup, e);
|
||||||
}
|
}
|
||||||
|
groupConsumeInfo.setGroup(consumerGroup);
|
||||||
return groupConsumeInfo;
|
return groupConsumeInfo;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -51,51 +51,52 @@ public class DashboardCollectServiceImpl implements DashboardCollectService {
|
|||||||
private final static Logger log = LoggerFactory.getLogger(DashboardCollectServiceImpl.class);
|
private final static Logger log = LoggerFactory.getLogger(DashboardCollectServiceImpl.class);
|
||||||
|
|
||||||
private LoadingCache<String, List<String>> brokerMap = CacheBuilder.newBuilder()
|
private LoadingCache<String, List<String>> brokerMap = CacheBuilder.newBuilder()
|
||||||
.maximumSize(1000)
|
.maximumSize(1000)
|
||||||
.concurrencyLevel(10)
|
.concurrencyLevel(10)
|
||||||
.recordStats()
|
.recordStats()
|
||||||
.ticker(Ticker.systemTicker())
|
.ticker(Ticker.systemTicker())
|
||||||
.removalListener(new RemovalListener<Object, Object>() {
|
.removalListener(new RemovalListener<Object, Object>() {
|
||||||
@Override
|
|
||||||
public void onRemoval(RemovalNotification<Object, Object> notification) {
|
|
||||||
log.debug(notification.getKey() + " was removed, cause is " + notification.getCause());
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.build(
|
|
||||||
new CacheLoader<String, List<String>>() {
|
|
||||||
@Override
|
@Override
|
||||||
public List<String> load(String key) {
|
public void onRemoval(RemovalNotification<Object, Object> notification) {
|
||||||
List<String> list = Lists.newArrayList();
|
log.debug(notification.getKey() + " was removed, cause is " + notification.getCause());
|
||||||
return list;
|
|
||||||
}
|
}
|
||||||
}
|
})
|
||||||
);
|
.build(
|
||||||
|
new CacheLoader<String, List<String>>() {
|
||||||
|
@Override
|
||||||
|
public List<String> load(String key) {
|
||||||
|
List<String> list = Lists.newArrayList();
|
||||||
|
return list;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
private LoadingCache<String, List<String>> topicMap = CacheBuilder.newBuilder()
|
private LoadingCache<String, List<String>> topicMap = CacheBuilder.newBuilder()
|
||||||
.maximumSize(1000)
|
.maximumSize(1000)
|
||||||
.concurrencyLevel(10)
|
.concurrencyLevel(10)
|
||||||
.recordStats()
|
.recordStats()
|
||||||
.ticker(Ticker.systemTicker())
|
.ticker(Ticker.systemTicker())
|
||||||
.removalListener(new RemovalListener<Object, Object>() {
|
.removalListener(new RemovalListener<Object, Object>() {
|
||||||
@Override
|
|
||||||
public void onRemoval(RemovalNotification<Object, Object> notification) {
|
|
||||||
log.debug(notification.getKey() + " was removed, cause is " + notification.getCause());
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.build(
|
|
||||||
new CacheLoader<String, List<String>>() {
|
|
||||||
@Override
|
@Override
|
||||||
public List<String> load(String key) {
|
public void onRemoval(RemovalNotification<Object, Object> notification) {
|
||||||
List<String> list = Lists.newArrayList();
|
log.debug(notification.getKey() + " was removed, cause is " + notification.getCause());
|
||||||
return list;
|
|
||||||
}
|
}
|
||||||
}
|
})
|
||||||
);
|
.build(
|
||||||
|
new CacheLoader<String, List<String>>() {
|
||||||
|
@Override
|
||||||
|
public List<String> load(String key) {
|
||||||
|
List<String> list = Lists.newArrayList();
|
||||||
|
return list;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public LoadingCache<String, List<String>> getBrokerMap() {
|
public LoadingCache<String, List<String>> getBrokerMap() {
|
||||||
return brokerMap;
|
return brokerMap;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public LoadingCache<String, List<String>> getTopicMap() {
|
public LoadingCache<String, List<String>> getTopicMap() {
|
||||||
return topicMap;
|
return topicMap;
|
||||||
@@ -106,8 +107,7 @@ public class DashboardCollectServiceImpl implements DashboardCollectService {
|
|||||||
List<String> strings;
|
List<String> strings;
|
||||||
try {
|
try {
|
||||||
strings = Files.readLines(file, Charsets.UTF_8);
|
strings = Files.readLines(file, Charsets.UTF_8);
|
||||||
}
|
} catch (IOException e) {
|
||||||
catch (IOException e) {
|
|
||||||
Throwables.throwIfUnchecked(e);
|
Throwables.throwIfUnchecked(e);
|
||||||
throw new RuntimeException(e);
|
throw new RuntimeException(e);
|
||||||
}
|
}
|
||||||
|
@@ -34,6 +34,7 @@ public class DashboardServiceImpl implements DashboardService {
|
|||||||
|
|
||||||
@Resource
|
@Resource
|
||||||
private DashboardCollectService dashboardCollectService;
|
private DashboardCollectService dashboardCollectService;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param date format yyyy-MM-dd
|
* @param date format yyyy-MM-dd
|
||||||
*/
|
*/
|
||||||
@@ -48,7 +49,7 @@ public class DashboardServiceImpl implements DashboardService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param date format yyyy-MM-dd
|
* @param date format yyyy-MM-dd
|
||||||
* @param topicName
|
* @param topicName
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
|
@@ -60,7 +60,7 @@ public class DlqMessageServiceImpl implements DlqMessageService {
|
|||||||
} catch (MQClientException e) {
|
} catch (MQClientException e) {
|
||||||
// If the %DLQ%Group does not exist, the message returns null
|
// If the %DLQ%Group does not exist, the message returns null
|
||||||
if (topic.startsWith(MixAll.DLQ_GROUP_TOPIC_PREFIX)
|
if (topic.startsWith(MixAll.DLQ_GROUP_TOPIC_PREFIX)
|
||||||
&& e.getResponseCode() == ResponseCode.TOPIC_NOT_EXIST) {
|
&& e.getResponseCode() == ResponseCode.TOPIC_NOT_EXIST) {
|
||||||
return new MessagePage(new PageImpl<>(messageViews, page, 0), query.getTaskId());
|
return new MessagePage(new PageImpl<>(messageViews, page, 0), query.getTaskId());
|
||||||
} else {
|
} else {
|
||||||
Throwables.throwIfUnchecked(e);
|
Throwables.throwIfUnchecked(e);
|
||||||
@@ -78,8 +78,8 @@ public class DlqMessageServiceImpl implements DlqMessageService {
|
|||||||
List<DlqMessageResendResult> batchResendResults = new LinkedList<>();
|
List<DlqMessageResendResult> batchResendResults = new LinkedList<>();
|
||||||
for (DlqMessageRequest dlqMessage : dlqMessages) {
|
for (DlqMessageRequest dlqMessage : dlqMessages) {
|
||||||
ConsumeMessageDirectlyResult result = messageService.consumeMessageDirectly(dlqMessage.getTopicName(),
|
ConsumeMessageDirectlyResult result = messageService.consumeMessageDirectly(dlqMessage.getTopicName(),
|
||||||
dlqMessage.getMsgId(), dlqMessage.getConsumerGroup(),
|
dlqMessage.getMsgId(), dlqMessage.getConsumerGroup(),
|
||||||
dlqMessage.getClientId());
|
dlqMessage.getClientId());
|
||||||
DlqMessageResendResult resendResult = new DlqMessageResendResult(result, dlqMessage.getMsgId());
|
DlqMessageResendResult resendResult = new DlqMessageResendResult(result, dlqMessage.getMsgId());
|
||||||
batchResendResults.add(resendResult);
|
batchResendResults.add(resendResult);
|
||||||
}
|
}
|
||||||
|
@@ -33,7 +33,6 @@ import org.apache.rocketmq.client.consumer.DefaultMQPullConsumer;
|
|||||||
import org.apache.rocketmq.client.consumer.PullResult;
|
import org.apache.rocketmq.client.consumer.PullResult;
|
||||||
import org.apache.rocketmq.client.consumer.PullStatus;
|
import org.apache.rocketmq.client.consumer.PullStatus;
|
||||||
import org.apache.rocketmq.client.exception.MQClientException;
|
import org.apache.rocketmq.client.exception.MQClientException;
|
||||||
import org.apache.rocketmq.common.MixAll;
|
|
||||||
import org.apache.rocketmq.common.Pair;
|
import org.apache.rocketmq.common.Pair;
|
||||||
import org.apache.rocketmq.common.message.MessageClientIDSetter;
|
import org.apache.rocketmq.common.message.MessageClientIDSetter;
|
||||||
import org.apache.rocketmq.common.message.MessageExt;
|
import org.apache.rocketmq.common.message.MessageExt;
|
||||||
@@ -74,6 +73,9 @@ import java.util.stream.Collectors;
|
|||||||
@Service
|
@Service
|
||||||
public class MessageServiceImpl implements MessageService {
|
public class MessageServiceImpl implements MessageService {
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
private AutoCloseConsumerWrapper autoCloseConsumerWrapper;
|
||||||
|
|
||||||
private Logger logger = LoggerFactory.getLogger(MessageServiceImpl.class);
|
private Logger logger = LoggerFactory.getLogger(MessageServiceImpl.class);
|
||||||
|
|
||||||
private static final Cache<String, List<QueueOffsetInfo>> CACHE = CacheBuilder.newBuilder()
|
private static final Cache<String, List<QueueOffsetInfo>> CACHE = CacheBuilder.newBuilder()
|
||||||
@@ -128,8 +130,8 @@ public class MessageServiceImpl implements MessageService {
|
|||||||
if (isEnableAcl) {
|
if (isEnableAcl) {
|
||||||
rpcHook = new AclClientRPCHook(new SessionCredentials(configure.getAccessKey(), configure.getSecretKey()));
|
rpcHook = new AclClientRPCHook(new SessionCredentials(configure.getAccessKey(), configure.getSecretKey()));
|
||||||
}
|
}
|
||||||
AutoCloseConsumerWrapper consumerWrapper = new AutoCloseConsumerWrapper();
|
|
||||||
DefaultMQPullConsumer consumer = consumerWrapper.getConsumer(rpcHook, configure.isUseTLS());
|
DefaultMQPullConsumer consumer = autoCloseConsumerWrapper.getConsumer(rpcHook, configure.isUseTLS());
|
||||||
List<MessageView> messageViewList = Lists.newArrayList();
|
List<MessageView> messageViewList = Lists.newArrayList();
|
||||||
try {
|
try {
|
||||||
String subExpression = "*";
|
String subExpression = "*";
|
||||||
@@ -262,8 +264,8 @@ public class MessageServiceImpl implements MessageService {
|
|||||||
if (isEnableAcl) {
|
if (isEnableAcl) {
|
||||||
rpcHook = new AclClientRPCHook(new SessionCredentials(configure.getAccessKey(), configure.getSecretKey()));
|
rpcHook = new AclClientRPCHook(new SessionCredentials(configure.getAccessKey(), configure.getSecretKey()));
|
||||||
}
|
}
|
||||||
AutoCloseConsumerWrapper consumerWrapper = new AutoCloseConsumerWrapper();
|
|
||||||
DefaultMQPullConsumer consumer = consumerWrapper.getConsumer(rpcHook, configure.isUseTLS());
|
DefaultMQPullConsumer consumer = autoCloseConsumerWrapper.getConsumer(rpcHook, configure.isUseTLS());
|
||||||
|
|
||||||
long total = 0;
|
long total = 0;
|
||||||
List<QueueOffsetInfo> queueOffsetInfos = new ArrayList<>();
|
List<QueueOffsetInfo> queueOffsetInfos = new ArrayList<>();
|
||||||
@@ -402,8 +404,8 @@ public class MessageServiceImpl implements MessageService {
|
|||||||
if (isEnableAcl) {
|
if (isEnableAcl) {
|
||||||
rpcHook = new AclClientRPCHook(new SessionCredentials(configure.getAccessKey(), configure.getSecretKey()));
|
rpcHook = new AclClientRPCHook(new SessionCredentials(configure.getAccessKey(), configure.getSecretKey()));
|
||||||
}
|
}
|
||||||
AutoCloseConsumerWrapper consumerWrapper = new AutoCloseConsumerWrapper();
|
|
||||||
DefaultMQPullConsumer consumer = consumerWrapper.getConsumer(rpcHook, configure.isUseTLS());
|
DefaultMQPullConsumer consumer = autoCloseConsumerWrapper.getConsumer(rpcHook, configure.isUseTLS());
|
||||||
List<MessageView> messageViews = new ArrayList<>();
|
List<MessageView> messageViews = new ArrayList<>();
|
||||||
|
|
||||||
long offset = query.getPageNum() * query.getPageSize();
|
long offset = query.getPageNum() * query.getPageSize();
|
||||||
@@ -541,9 +543,9 @@ public class MessageServiceImpl implements MessageService {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public DefaultMQPullConsumer buildDefaultMQPullConsumer(RPCHook rpcHook, boolean useTLS) {
|
// public DefaultMQPullConsumer buildDefaultMQPullConsumer(RPCHook rpcHook, boolean useTLS) {
|
||||||
DefaultMQPullConsumer consumer = new DefaultMQPullConsumer(MixAll.TOOLS_CONSUMER_GROUP, rpcHook);
|
// DefaultMQPullConsumer consumer = new DefaultMQPullConsumer(MixAll.TOOLS_CONSUMER_GROUP, rpcHook);
|
||||||
consumer.setUseTLS(useTLS);
|
// consumer.setUseTLS(useTLS);
|
||||||
return consumer;
|
// return consumer;
|
||||||
}
|
// }
|
||||||
}
|
}
|
||||||
|
@@ -133,21 +133,21 @@ public class MessageTraceServiceImpl implements MessageTraceService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private List<SubscriptionNode> buildSubscriptionNodeList(
|
private List<SubscriptionNode> buildSubscriptionNodeList(
|
||||||
Map<String, Pair<MessageTraceView, MessageTraceView>> requestIdTracePairMap) {
|
Map<String, Pair<MessageTraceView, MessageTraceView>> requestIdTracePairMap) {
|
||||||
Map<String, List<TraceNode>> subscriptionTraceNodeMap = Maps.newHashMap();
|
Map<String, List<TraceNode>> subscriptionTraceNodeMap = Maps.newHashMap();
|
||||||
for (Pair<MessageTraceView, MessageTraceView> traceNodePair : requestIdTracePairMap.values()) {
|
for (Pair<MessageTraceView, MessageTraceView> traceNodePair : requestIdTracePairMap.values()) {
|
||||||
List<TraceNode> traceNodeList = subscriptionTraceNodeMap
|
List<TraceNode> traceNodeList = subscriptionTraceNodeMap
|
||||||
.computeIfAbsent(buildGroupName(traceNodePair), (o) -> Lists.newArrayList());
|
.computeIfAbsent(buildGroupName(traceNodePair), (o) -> Lists.newArrayList());
|
||||||
traceNodeList.add(buildConsumeMessageTraceNode(traceNodePair));
|
traceNodeList.add(buildConsumeMessageTraceNode(traceNodePair));
|
||||||
}
|
}
|
||||||
return subscriptionTraceNodeMap.entrySet().stream()
|
return subscriptionTraceNodeMap.entrySet().stream()
|
||||||
.map((Function<Map.Entry<String, List<TraceNode>>, SubscriptionNode>) subscriptionEntry -> {
|
.map((Function<Map.Entry<String, List<TraceNode>>, SubscriptionNode>) subscriptionEntry -> {
|
||||||
List<TraceNode> traceNodeList = subscriptionEntry.getValue();
|
List<TraceNode> traceNodeList = subscriptionEntry.getValue();
|
||||||
SubscriptionNode subscriptionNode = new SubscriptionNode();
|
SubscriptionNode subscriptionNode = new SubscriptionNode();
|
||||||
subscriptionNode.setSubscriptionGroup(subscriptionEntry.getKey());
|
subscriptionNode.setSubscriptionGroup(subscriptionEntry.getKey());
|
||||||
subscriptionNode.setConsumeNodeList(sortTraceNodeListByBeginTimestamp(traceNodeList));
|
subscriptionNode.setConsumeNodeList(sortTraceNodeListByBeginTimestamp(traceNodeList));
|
||||||
return subscriptionNode;
|
return subscriptionNode;
|
||||||
}).collect(Collectors.toList());
|
}).collect(Collectors.toList());
|
||||||
}
|
}
|
||||||
|
|
||||||
private <E> E getTraceValue(Pair<MessageTraceView, MessageTraceView> traceNodePair, Function<MessageTraceView, E> function) {
|
private <E> E getTraceValue(Pair<MessageTraceView, MessageTraceView> traceNodePair, Function<MessageTraceView, E> function) {
|
||||||
@@ -206,7 +206,7 @@ public class MessageTraceServiceImpl implements MessageTraceService {
|
|||||||
private void putIntoMessageTraceViewGroupMap(MessageTraceView messageTraceView,
|
private void putIntoMessageTraceViewGroupMap(MessageTraceView messageTraceView,
|
||||||
Map<String, Pair<MessageTraceView, MessageTraceView>> messageTraceViewGroupMap) {
|
Map<String, Pair<MessageTraceView, MessageTraceView>> messageTraceViewGroupMap) {
|
||||||
Pair<MessageTraceView, MessageTraceView> messageTracePair = messageTraceViewGroupMap
|
Pair<MessageTraceView, MessageTraceView> messageTracePair = messageTraceViewGroupMap
|
||||||
.computeIfAbsent(messageTraceView.getRequestId(), (o) -> new Pair<>(null, null));
|
.computeIfAbsent(messageTraceView.getRequestId(), (o) -> new Pair<>(null, null));
|
||||||
switch (TraceType.valueOf(messageTraceView.getTraceType())) {
|
switch (TraceType.valueOf(messageTraceView.getTraceType())) {
|
||||||
case SubBefore:
|
case SubBefore:
|
||||||
messageTracePair.setObject1(messageTraceView);
|
messageTracePair.setObject1(messageTraceView);
|
||||||
|
@@ -81,8 +81,7 @@ public class MonitorServiceImpl implements MonitorService {
|
|||||||
private void writeDataJsonToFile(String path, String dataStr) {
|
private void writeDataJsonToFile(String path, String dataStr) {
|
||||||
try {
|
try {
|
||||||
MixAll.string2File(dataStr, path);
|
MixAll.string2File(dataStr, path);
|
||||||
}
|
} catch (Exception e) {
|
||||||
catch (Exception e) {
|
|
||||||
Throwables.throwIfUnchecked(e);
|
Throwables.throwIfUnchecked(e);
|
||||||
throw new RuntimeException(e);
|
throw new RuntimeException(e);
|
||||||
}
|
}
|
||||||
|
@@ -33,8 +33,7 @@ public class ProducerServiceImpl implements ProducerService {
|
|||||||
public ProducerConnection getProducerConnection(String producerGroup, String topic) {
|
public ProducerConnection getProducerConnection(String producerGroup, String topic) {
|
||||||
try {
|
try {
|
||||||
return mqAdminExt.examineProducerConnectionInfo(producerGroup, topic);
|
return mqAdminExt.examineProducerConnectionInfo(producerGroup, topic);
|
||||||
}
|
} catch (Exception e) {
|
||||||
catch (Exception e) {
|
|
||||||
Throwables.throwIfUnchecked(e);
|
Throwables.throwIfUnchecked(e);
|
||||||
throw new RuntimeException(e);
|
throw new RuntimeException(e);
|
||||||
}
|
}
|
||||||
|
@@ -127,7 +127,7 @@ public class TopicServiceImpl extends AbstractCommonService implements TopicServ
|
|||||||
try {
|
try {
|
||||||
TopicConfigSerializeWrapper topicConfigSerializeWrapper = mqAdminExt.getAllTopicConfig(brokerAddr.getBrokerAddrs().get(0L), 10000L);
|
TopicConfigSerializeWrapper topicConfigSerializeWrapper = mqAdminExt.getAllTopicConfig(brokerAddr.getBrokerAddrs().get(0L), 10000L);
|
||||||
for (TopicConfig topicConfig : topicConfigSerializeWrapper.getTopicConfigTable().values()) {
|
for (TopicConfig topicConfig : topicConfigSerializeWrapper.getTopicConfigTable().values()) {
|
||||||
TopicTypeMeta topicType = classifyTopicType(topicConfig.getTopicName(), topicConfigSerializeWrapper.getTopicConfigTable().get(topicConfig.getTopicName()).getAttributes(),sysTopics.getTopicList());
|
TopicTypeMeta topicType = classifyTopicType(topicConfig.getTopicName(), topicConfigSerializeWrapper.getTopicConfigTable().get(topicConfig.getTopicName()).getAttributes(), sysTopics.getTopicList());
|
||||||
if (names.contains(topicType.getTopicName())) {
|
if (names.contains(topicType.getTopicName())) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@@ -149,7 +149,7 @@ public class TopicServiceImpl extends AbstractCommonService implements TopicServ
|
|||||||
return new TopicTypeList(names, messageTypes);
|
return new TopicTypeList(names, messageTypes);
|
||||||
}
|
}
|
||||||
|
|
||||||
private TopicTypeMeta classifyTopicType(String topicName, Map<String,String> attributes, Set<String> sysTopics) {
|
private TopicTypeMeta classifyTopicType(String topicName, Map<String, String> attributes, Set<String> sysTopics) {
|
||||||
TopicTypeMeta topicType = new TopicTypeMeta();
|
TopicTypeMeta topicType = new TopicTypeMeta();
|
||||||
topicType.setTopicName(topicName);
|
topicType.setTopicName(topicName);
|
||||||
|
|
||||||
|
@@ -17,29 +17,26 @@
|
|||||||
|
|
||||||
package org.apache.rocketmq.dashboard.service.impl;
|
package org.apache.rocketmq.dashboard.service.impl;
|
||||||
|
|
||||||
import jakarta.annotation.Resource;
|
|
||||||
import org.apache.rocketmq.auth.authentication.enums.UserType;
|
import org.apache.rocketmq.auth.authentication.enums.UserType;
|
||||||
import org.apache.rocketmq.dashboard.admin.UserMQAdminPoolManager;
|
import org.apache.rocketmq.dashboard.admin.UserMQAdminPoolManager;
|
||||||
import org.apache.rocketmq.dashboard.config.RMQConfigure;
|
|
||||||
import org.apache.rocketmq.dashboard.model.User;
|
import org.apache.rocketmq.dashboard.model.User;
|
||||||
import org.apache.rocketmq.dashboard.service.UserService;
|
import org.apache.rocketmq.dashboard.service.UserService;
|
||||||
import org.apache.rocketmq.dashboard.service.provider.UserInfoProvider;
|
import org.apache.rocketmq.dashboard.service.strategy.UserContext;
|
||||||
import org.apache.rocketmq.remoting.protocol.body.UserInfo;
|
import org.apache.rocketmq.remoting.protocol.body.UserInfo;
|
||||||
import org.apache.rocketmq.tools.admin.MQAdminExt;
|
import org.apache.rocketmq.tools.admin.MQAdminExt;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
|
||||||
import org.springframework.stereotype.Service;
|
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
@Service
|
@Service
|
||||||
public class UserServiceImpl implements UserService {
|
public class UserServiceImpl implements UserService {
|
||||||
|
|
||||||
private static final Logger log = LoggerFactory.getLogger(UserServiceImpl.class);
|
private static final Logger log = LoggerFactory.getLogger(UserServiceImpl.class);
|
||||||
|
|
||||||
@Resource
|
|
||||||
private RMQConfigure configure;
|
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
private UserInfoProvider userInfoProvider;
|
private UserContext userContext;
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
private UserMQAdminPoolManager userMQAdminPoolManager;
|
private UserMQAdminPoolManager userMQAdminPoolManager;
|
||||||
@@ -47,7 +44,7 @@ public class UserServiceImpl implements UserService {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public User queryByName(String name) {
|
public User queryByName(String name) {
|
||||||
UserInfo userInfo = userInfoProvider.getUserInfoByUsername(name);
|
UserInfo userInfo = userContext.queryByUsername(name);
|
||||||
if (userInfo == null) {
|
if (userInfo == null) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
@@ -23,6 +23,7 @@ import org.apache.rocketmq.common.MixAll;
|
|||||||
import org.apache.rocketmq.remoting.RPCHook;
|
import org.apache.rocketmq.remoting.RPCHook;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
import java.time.Duration;
|
import java.time.Duration;
|
||||||
import java.time.Instant;
|
import java.time.Instant;
|
||||||
@@ -32,9 +33,10 @@ import java.util.concurrent.TimeUnit;
|
|||||||
import java.util.concurrent.atomic.AtomicBoolean;
|
import java.util.concurrent.atomic.AtomicBoolean;
|
||||||
import java.util.concurrent.atomic.AtomicReference;
|
import java.util.concurrent.atomic.AtomicReference;
|
||||||
|
|
||||||
|
@Component
|
||||||
public class AutoCloseConsumerWrapper {
|
public class AutoCloseConsumerWrapper {
|
||||||
|
|
||||||
private final Logger logger = LoggerFactory.getLogger(GlobalRestfulResponseBodyAdvice.class);
|
private final Logger logger = LoggerFactory.getLogger(AutoCloseConsumerWrapper.class);
|
||||||
|
|
||||||
private static final AtomicReference<DefaultMQPullConsumer> CONSUMER_REF = new AtomicReference<>();
|
private static final AtomicReference<DefaultMQPullConsumer> CONSUMER_REF = new AtomicReference<>();
|
||||||
private final AtomicBoolean isTaskScheduled = new AtomicBoolean(false);
|
private final AtomicBoolean isTaskScheduled = new AtomicBoolean(false);
|
||||||
@@ -77,7 +79,10 @@ public class AutoCloseConsumerWrapper {
|
|||||||
|
|
||||||
protected DefaultMQPullConsumer createNewConsumer(RPCHook rpcHook, Boolean useTLS) {
|
protected DefaultMQPullConsumer createNewConsumer(RPCHook rpcHook, Boolean useTLS) {
|
||||||
return new DefaultMQPullConsumer(MixAll.TOOLS_CONSUMER_GROUP, rpcHook) {
|
return new DefaultMQPullConsumer(MixAll.TOOLS_CONSUMER_GROUP, rpcHook) {
|
||||||
{ setUseTLS(useTLS); } };
|
{
|
||||||
|
setUseTLS(useTLS);
|
||||||
|
}
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
private void startIdleCheckTask() {
|
private void startIdleCheckTask() {
|
||||||
|
@@ -37,8 +37,7 @@ public class GlobalExceptionHandler {
|
|||||||
if (ex instanceof ServiceException) {
|
if (ex instanceof ServiceException) {
|
||||||
logger.error("Occur service exception: {}", ex.getMessage());
|
logger.error("Occur service exception: {}", ex.getMessage());
|
||||||
value = new JsonResult<Object>(((ServiceException) ex).getCode(), ex.getMessage());
|
value = new JsonResult<Object>(((ServiceException) ex).getCode(), ex.getMessage());
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
logger.error("op=global_exception_handler_print_error", ex);
|
logger.error("op=global_exception_handler_print_error", ex);
|
||||||
value = new JsonResult<Object>(-1, ex.getMessage() == null ? ex.toString() : ex.getMessage());
|
value = new JsonResult<Object>(-1, ex.getMessage() == null ? ex.toString() : ex.getMessage());
|
||||||
}
|
}
|
||||||
|
@@ -37,18 +37,17 @@ public class GlobalRestfulResponseBodyAdvice implements ResponseBodyAdvice<Objec
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Object beforeBodyWrite(
|
public Object beforeBodyWrite(
|
||||||
Object obj, MethodParameter methodParameter, MediaType mediaType,
|
Object obj, MethodParameter methodParameter, MediaType mediaType,
|
||||||
Class<? extends HttpMessageConverter<?>> converterType,
|
Class<? extends HttpMessageConverter<?>> converterType,
|
||||||
ServerHttpRequest serverHttpRequest, ServerHttpResponse serverHttpResponse) {
|
ServerHttpRequest serverHttpRequest, ServerHttpResponse serverHttpResponse) {
|
||||||
Annotation originalControllerReturnValue = methodParameter.getMethodAnnotation(OriginalControllerReturnValue.class);
|
Annotation originalControllerReturnValue = methodParameter.getMethodAnnotation(OriginalControllerReturnValue.class);
|
||||||
if (originalControllerReturnValue != null) {
|
if (originalControllerReturnValue != null) {
|
||||||
return obj;
|
return obj;
|
||||||
}
|
}
|
||||||
JsonResult value;
|
JsonResult value;
|
||||||
if (obj instanceof JsonResult) {
|
if (obj instanceof JsonResult) {
|
||||||
value = (JsonResult)obj;
|
value = (JsonResult) obj;
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
value = new JsonResult(obj);
|
value = new JsonResult(obj);
|
||||||
}
|
}
|
||||||
return value;
|
return value;
|
||||||
|
@@ -44,7 +44,7 @@ public class CollectTaskRunnble implements Runnable {
|
|||||||
private DashboardCollectService dashboardCollectService;
|
private DashboardCollectService dashboardCollectService;
|
||||||
|
|
||||||
public CollectTaskRunnble(String topic, MQAdminExt mqAdminExt,
|
public CollectTaskRunnble(String topic, MQAdminExt mqAdminExt,
|
||||||
DashboardCollectService dashboardCollectService) {
|
DashboardCollectService dashboardCollectService) {
|
||||||
this.topic = topic;
|
this.topic = topic;
|
||||||
this.mqAdminExt = mqAdminExt;
|
this.mqAdminExt = mqAdminExt;
|
||||||
this.dashboardCollectService = dashboardCollectService;
|
this.dashboardCollectService = dashboardCollectService;
|
||||||
|
@@ -80,15 +80,14 @@ public class DashboardCollectTask {
|
|||||||
this.addSystemTopic();
|
this.addSystemTopic();
|
||||||
for (String topic : topicSet) {
|
for (String topic : topicSet) {
|
||||||
if (topic.startsWith(MixAll.RETRY_GROUP_TOPIC_PREFIX)
|
if (topic.startsWith(MixAll.RETRY_GROUP_TOPIC_PREFIX)
|
||||||
|| topic.startsWith(MixAll.DLQ_GROUP_TOPIC_PREFIX)
|
|| topic.startsWith(MixAll.DLQ_GROUP_TOPIC_PREFIX)
|
||||||
|| TopicValidator.isSystemTopic(topic)) {
|
|| TopicValidator.isSystemTopic(topic)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
CollectTaskRunnble collectTask = new CollectTaskRunnble(topic, mqAdminExt, dashboardCollectService);
|
CollectTaskRunnble collectTask = new CollectTaskRunnble(topic, mqAdminExt, dashboardCollectService);
|
||||||
collectExecutor.submit(collectTask);
|
collectExecutor.submit(collectTask);
|
||||||
}
|
}
|
||||||
}
|
} catch (Exception err) {
|
||||||
catch (Exception err) {
|
|
||||||
Throwables.throwIfUnchecked(err);
|
Throwables.throwIfUnchecked(err);
|
||||||
throw new RuntimeException(err);
|
throw new RuntimeException(err);
|
||||||
}
|
}
|
||||||
@@ -100,7 +99,6 @@ public class DashboardCollectTask {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@Scheduled(cron = "0 0/1 * * * ?")
|
@Scheduled(cron = "0 0/1 * * * ?")
|
||||||
public void collectBroker() {
|
public void collectBroker() {
|
||||||
if (!rmqConfigure.isEnableDashBoardCollect()) {
|
if (!rmqConfigure.isEnableDashBoardCollect()) {
|
||||||
@@ -139,8 +137,7 @@ public class DashboardCollectTask {
|
|||||||
dashboardCollectService.getBrokerMap().put(entry.getValue(), list);
|
dashboardCollectService.getBrokerMap().put(entry.getValue(), list);
|
||||||
}
|
}
|
||||||
log.debug("Broker Collected Data in memory = {}" + JsonUtil.obj2String(dashboardCollectService.getBrokerMap().asMap()));
|
log.debug("Broker Collected Data in memory = {}" + JsonUtil.obj2String(dashboardCollectService.getBrokerMap().asMap()));
|
||||||
}
|
} catch (Exception e) {
|
||||||
catch (Exception e) {
|
|
||||||
Throwables.throwIfUnchecked(e);
|
Throwables.throwIfUnchecked(e);
|
||||||
throw new RuntimeException(e);
|
throw new RuntimeException(e);
|
||||||
}
|
}
|
||||||
@@ -152,12 +149,10 @@ public class DashboardCollectTask {
|
|||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
return mqAdminExt.fetchBrokerRuntimeStats(brokerAddr);
|
return mqAdminExt.fetchBrokerRuntimeStats(brokerAddr);
|
||||||
}
|
} catch (Exception e) {
|
||||||
catch (Exception e) {
|
|
||||||
try {
|
try {
|
||||||
Thread.sleep(1000);
|
Thread.sleep(1000);
|
||||||
}
|
} catch (InterruptedException e1) {
|
||||||
catch (InterruptedException e1) {
|
|
||||||
Throwables.throwIfUnchecked(e1);
|
Throwables.throwIfUnchecked(e1);
|
||||||
throw new RuntimeException(e1);
|
throw new RuntimeException(e1);
|
||||||
}
|
}
|
||||||
@@ -189,16 +184,14 @@ public class DashboardCollectTask {
|
|||||||
Map<String, List<String>> topicFileMap;
|
Map<String, List<String>> topicFileMap;
|
||||||
if (brokerFile.exists()) {
|
if (brokerFile.exists()) {
|
||||||
brokerFileMap = dashboardCollectService.jsonDataFile2map(brokerFile);
|
brokerFileMap = dashboardCollectService.jsonDataFile2map(brokerFile);
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
brokerFileMap = Maps.newHashMap();
|
brokerFileMap = Maps.newHashMap();
|
||||||
Files.createParentDirs(brokerFile);
|
Files.createParentDirs(brokerFile);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (topicFile.exists()) {
|
if (topicFile.exists()) {
|
||||||
topicFileMap = dashboardCollectService.jsonDataFile2map(topicFile);
|
topicFileMap = dashboardCollectService.jsonDataFile2map(topicFile);
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
topicFileMap = Maps.newHashMap();
|
topicFileMap = Maps.newHashMap();
|
||||||
Files.createParentDirs(topicFile);
|
Files.createParentDirs(topicFile);
|
||||||
}
|
}
|
||||||
@@ -211,21 +204,19 @@ public class DashboardCollectTask {
|
|||||||
log.debug("Broker Collected Data in memory = {}" + JsonUtil.obj2String(dashboardCollectService.getBrokerMap().asMap()));
|
log.debug("Broker Collected Data in memory = {}" + JsonUtil.obj2String(dashboardCollectService.getBrokerMap().asMap()));
|
||||||
log.debug("Topic Collected Data in memory = {}" + JsonUtil.obj2String(dashboardCollectService.getTopicMap().asMap()));
|
log.debug("Topic Collected Data in memory = {}" + JsonUtil.obj2String(dashboardCollectService.getTopicMap().asMap()));
|
||||||
|
|
||||||
}
|
} catch (IOException e) {
|
||||||
catch (IOException e) {
|
|
||||||
Throwables.throwIfUnchecked(e);
|
Throwables.throwIfUnchecked(e);
|
||||||
throw new RuntimeException(e);
|
throw new RuntimeException(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void writeFile(LoadingCache<String, List<String>> map, Map<String, List<String>> fileMap,
|
private void writeFile(LoadingCache<String, List<String>> map, Map<String, List<String>> fileMap,
|
||||||
File file) throws IOException {
|
File file) throws IOException {
|
||||||
Map<String, List<String>> newMap = map.asMap();
|
Map<String, List<String>> newMap = map.asMap();
|
||||||
Map<String, List<String>> resultMap = Maps.newHashMap();
|
Map<String, List<String>> resultMap = Maps.newHashMap();
|
||||||
if (fileMap.size() == 0) {
|
if (fileMap.size() == 0) {
|
||||||
resultMap = newMap;
|
resultMap = newMap;
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
for (Map.Entry<String, List<String>> entry : fileMap.entrySet()) {
|
for (Map.Entry<String, List<String>> entry : fileMap.entrySet()) {
|
||||||
List<String> oldList = entry.getValue();
|
List<String> oldList = entry.getValue();
|
||||||
List<String> newList = newMap.get(entry.getKey());
|
List<String> newList = newMap.get(entry.getKey());
|
||||||
|
@@ -38,7 +38,7 @@ public class MonitorTask {
|
|||||||
@Resource
|
@Resource
|
||||||
private ConsumerService consumerService;
|
private ConsumerService consumerService;
|
||||||
|
|
||||||
// @Scheduled(cron = "* * * * * ?")
|
// @Scheduled(cron = "* * * * * ?")
|
||||||
public void scanProblemConsumeGroup() {
|
public void scanProblemConsumeGroup() {
|
||||||
for (Map.Entry<String, ConsumerMonitorConfig> configEntry : monitorService.queryConsumerMonitorConfig().entrySet()) {
|
for (Map.Entry<String, ConsumerMonitorConfig> configEntry : monitorService.queryConsumerMonitorConfig().entrySet()) {
|
||||||
GroupConsumeInfo consumeInfo = consumerService.queryGroup(configEntry.getKey(), null);
|
GroupConsumeInfo consumeInfo = consumerService.queryGroup(configEntry.getKey(), null);
|
||||||
|
@@ -31,10 +31,10 @@ import java.util.List;
|
|||||||
public class ExcelUtil {
|
public class ExcelUtil {
|
||||||
|
|
||||||
public static void writeExcel(HttpServletResponse response, List<? extends Object> data, String fileName,
|
public static void writeExcel(HttpServletResponse response, List<? extends Object> data, String fileName,
|
||||||
String sheetName, Class clazz) throws Exception {
|
String sheetName, Class clazz) throws Exception {
|
||||||
WriteCellStyle headWriteCellStyle = new WriteCellStyle();
|
WriteCellStyle headWriteCellStyle = new WriteCellStyle();
|
||||||
WriteFont writeFont = new WriteFont();
|
WriteFont writeFont = new WriteFont();
|
||||||
writeFont.setFontHeightInPoints((short)12);
|
writeFont.setFontHeightInPoints((short) 12);
|
||||||
writeFont.setFontName("Microsoft YaHei UI");
|
writeFont.setFontName("Microsoft YaHei UI");
|
||||||
headWriteCellStyle.setWriteFont(writeFont);
|
headWriteCellStyle.setWriteFont(writeFont);
|
||||||
headWriteCellStyle.setHorizontalAlignment(HorizontalAlignment.CENTER);
|
headWriteCellStyle.setHorizontalAlignment(HorizontalAlignment.CENTER);
|
||||||
@@ -44,7 +44,7 @@ public class ExcelUtil {
|
|||||||
contentWriteCellStyle.setHorizontalAlignment(HorizontalAlignment.CENTER);
|
contentWriteCellStyle.setHorizontalAlignment(HorizontalAlignment.CENTER);
|
||||||
HorizontalCellStyleStrategy horizontalCellStyleStrategy = new HorizontalCellStyleStrategy(headWriteCellStyle, contentWriteCellStyle);
|
HorizontalCellStyleStrategy horizontalCellStyleStrategy = new HorizontalCellStyleStrategy(headWriteCellStyle, contentWriteCellStyle);
|
||||||
EasyExcel.write(getOutputStream(fileName, response), clazz)
|
EasyExcel.write(getOutputStream(fileName, response), clazz)
|
||||||
.excelType(ExcelTypeEnum.XLSX).sheet(sheetName).registerWriteHandler(horizontalCellStyleStrategy).doWrite(data);
|
.excelType(ExcelTypeEnum.XLSX).sheet(sheetName).registerWriteHandler(horizontalCellStyleStrategy).doWrite(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static OutputStream getOutputStream(String fileName, HttpServletResponse response) throws Exception {
|
private static OutputStream getOutputStream(String fileName, HttpServletResponse response) throws Exception {
|
||||||
|
@@ -55,8 +55,7 @@ public class JsonUtil {
|
|||||||
public static void writeValue(Writer writer, Object obj) {
|
public static void writeValue(Writer writer, Object obj) {
|
||||||
try {
|
try {
|
||||||
objectMapper.writeValue(writer, obj);
|
objectMapper.writeValue(writer, obj);
|
||||||
}
|
} catch (IOException e) {
|
||||||
catch (IOException e) {
|
|
||||||
Throwables.propagateIfPossible(e);
|
Throwables.propagateIfPossible(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -67,9 +66,8 @@ public class JsonUtil {
|
|||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
return src instanceof String ? (String)src : objectMapper.writeValueAsString(src);
|
return src instanceof String ? (String) src : objectMapper.writeValueAsString(src);
|
||||||
}
|
} catch (Exception e) {
|
||||||
catch (Exception e) {
|
|
||||||
logger.error("Parse Object to String error src=" + src, e);
|
logger.error("Parse Object to String error src=" + src, e);
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@@ -81,9 +79,8 @@ public class JsonUtil {
|
|||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
return src instanceof byte[] ? (byte[])src : objectMapper.writeValueAsBytes(src);
|
return src instanceof byte[] ? (byte[]) src : objectMapper.writeValueAsBytes(src);
|
||||||
}
|
} catch (Exception e) {
|
||||||
catch (Exception e) {
|
|
||||||
logger.error("Parse Object to byte[] error", e);
|
logger.error("Parse Object to byte[] error", e);
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@@ -95,9 +92,8 @@ public class JsonUtil {
|
|||||||
}
|
}
|
||||||
str = escapesSpecialChar(str);
|
str = escapesSpecialChar(str);
|
||||||
try {
|
try {
|
||||||
return clazz.equals(String.class) ? (T)str : objectMapper.readValue(str, clazz);
|
return clazz.equals(String.class) ? (T) str : objectMapper.readValue(str, clazz);
|
||||||
}
|
} catch (Exception e) {
|
||||||
catch (Exception e) {
|
|
||||||
logger.error("Parse String to Object error\nString: {}\nClass<T>: {}\nError: {}", str, clazz.getName(), e);
|
logger.error("Parse String to Object error\nString: {}\nClass<T>: {}\nError: {}", str, clazz.getName(), e);
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@@ -108,9 +104,8 @@ public class JsonUtil {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
return clazz.equals(byte[].class) ? (T)bytes : objectMapper.readValue(bytes, clazz);
|
return clazz.equals(byte[].class) ? (T) bytes : objectMapper.readValue(bytes, clazz);
|
||||||
}
|
} catch (Exception e) {
|
||||||
catch (Exception e) {
|
|
||||||
logger.error("Parse byte[] to Object error\nbyte[]: {}\nClass<T>: {}\nError: {}", bytes, clazz.getName(), e);
|
logger.error("Parse byte[] to Object error\nbyte[]: {}\nClass<T>: {}\nError: {}", bytes, clazz.getName(), e);
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@@ -122,11 +117,10 @@ public class JsonUtil {
|
|||||||
}
|
}
|
||||||
str = escapesSpecialChar(str);
|
str = escapesSpecialChar(str);
|
||||||
try {
|
try {
|
||||||
return (T)(typeReference.getType().equals(String.class) ? str : objectMapper.readValue(str, typeReference));
|
return (T) (typeReference.getType().equals(String.class) ? str : objectMapper.readValue(str, typeReference));
|
||||||
}
|
} catch (Exception e) {
|
||||||
catch (Exception e) {
|
|
||||||
logger.error("Parse String to Object error\nString: {}\nTypeReference<T>: {}\nError: {}", str,
|
logger.error("Parse String to Object error\nString: {}\nTypeReference<T>: {}\nError: {}", str,
|
||||||
typeReference.getType(), e);
|
typeReference.getType(), e);
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -136,12 +130,11 @@ public class JsonUtil {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
return (T)(typeReference.getType().equals(byte[].class) ? bytes : objectMapper.readValue(bytes,
|
return (T) (typeReference.getType().equals(byte[].class) ? bytes : objectMapper.readValue(bytes,
|
||||||
typeReference));
|
typeReference));
|
||||||
}
|
} catch (Exception e) {
|
||||||
catch (Exception e) {
|
|
||||||
logger.error("Parse byte[] to Object error\nbyte[]: {}\nTypeReference<T>: {}\nError: {}", bytes,
|
logger.error("Parse byte[] to Object error\nbyte[]: {}\nTypeReference<T>: {}\nError: {}", bytes,
|
||||||
typeReference.getType(), e);
|
typeReference.getType(), e);
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -107,7 +107,7 @@ public class WebUtil {
|
|||||||
HttpSession session = request.getSession(false);
|
HttpSession session = request.getSession(false);
|
||||||
|
|
||||||
if (session != null) {
|
if (session != null) {
|
||||||
return session.getAttribute(key);
|
return session.getAttribute(key);
|
||||||
}
|
}
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
|
@@ -17,34 +17,34 @@
|
|||||||
-->
|
-->
|
||||||
|
|
||||||
<configuration>
|
<configuration>
|
||||||
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
|
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
|
||||||
<encoder charset="UTF-8">
|
<encoder charset="UTF-8">
|
||||||
<pattern>[%d{yyyy-MM-dd HH:mm:ss.SSS}] %p %t - %m%n</pattern>
|
|
||||||
</encoder>
|
|
||||||
</appender>
|
|
||||||
|
|
||||||
<appender name="FILE"
|
|
||||||
class="ch.qos.logback.core.rolling.RollingFileAppender">
|
|
||||||
<file>${user.home}/logs/dashboardlogs/rocketmq-dashboard.log</file>
|
|
||||||
<append>true</append>
|
|
||||||
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
|
|
||||||
<fileNamePattern>${user.home}/logs/dashboardlogs/rocketmq-dashboard-%d{yyyy-MM-dd}.%i.log
|
|
||||||
</fileNamePattern>
|
|
||||||
<timeBasedFileNamingAndTriggeringPolicy
|
|
||||||
class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
|
|
||||||
<maxFileSize>104857600</maxFileSize>
|
|
||||||
</timeBasedFileNamingAndTriggeringPolicy>
|
|
||||||
<MaxHistory>10</MaxHistory>
|
|
||||||
</rollingPolicy>
|
|
||||||
<encoder>
|
|
||||||
<pattern>[%d{yyyy-MM-dd HH:mm:ss.SSS}] %p %t - %m%n</pattern>
|
<pattern>[%d{yyyy-MM-dd HH:mm:ss.SSS}] %p %t - %m%n</pattern>
|
||||||
<charset class="java.nio.charset.Charset">UTF-8</charset>
|
</encoder>
|
||||||
</encoder>
|
</appender>
|
||||||
</appender>
|
|
||||||
|
|
||||||
<root level="INFO">
|
<appender name="FILE"
|
||||||
<appender-ref ref="STDOUT" />
|
class="ch.qos.logback.core.rolling.RollingFileAppender">
|
||||||
<appender-ref ref="FILE" />
|
<file>${user.home}/logs/dashboardlogs/rocketmq-dashboard.log</file>
|
||||||
</root>
|
<append>true</append>
|
||||||
|
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
|
||||||
|
<fileNamePattern>${user.home}/logs/dashboardlogs/rocketmq-dashboard-%d{yyyy-MM-dd}.%i.log
|
||||||
|
</fileNamePattern>
|
||||||
|
<timeBasedFileNamingAndTriggeringPolicy
|
||||||
|
class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
|
||||||
|
<maxFileSize>104857600</maxFileSize>
|
||||||
|
</timeBasedFileNamingAndTriggeringPolicy>
|
||||||
|
<MaxHistory>10</MaxHistory>
|
||||||
|
</rollingPolicy>
|
||||||
|
<encoder>
|
||||||
|
<pattern>[%d{yyyy-MM-dd HH:mm:ss.SSS}] %p %t - %m%n</pattern>
|
||||||
|
<charset class="java.nio.charset.Charset">UTF-8</charset>
|
||||||
|
</encoder>
|
||||||
|
</appender>
|
||||||
|
|
||||||
</configuration>
|
<root level="INFO">
|
||||||
|
<appender-ref ref="STDOUT"/>
|
||||||
|
<appender-ref ref="FILE"/>
|
||||||
|
</root>
|
||||||
|
|
||||||
|
</configuration>
|
||||||
|
@@ -14,13 +14,10 @@
|
|||||||
# See the License for the specific language governing permissions and
|
# See the License for the specific language governing permissions and
|
||||||
# limitations under the License.
|
# limitations under the License.
|
||||||
#
|
#
|
||||||
|
|
||||||
# This file supports hot change, any change will be auto-reloaded without Dashboard restarting.
|
# This file supports hot change, any change will be auto-reloaded without Dashboard restarting.
|
||||||
# Format: a user per line, username=password[,N] #N is optional, 0 (Normal User); 1 (Admin)
|
# Format: a user per line, username=password[,N] #N is optional, 0 (Normal User); 1 (Admin)
|
||||||
|
|
||||||
# Define Admin
|
# Define Admin
|
||||||
admin=admin,1
|
super=admin,1
|
||||||
|
|
||||||
# Define Users
|
# Define Users
|
||||||
user1=user1
|
user1=user
|
||||||
user2=user2
|
user2=user
|
||||||
|
Reference in New Issue
Block a user