[ISSUES #315]: Add acl2.0 cluster support

This commit is contained in:
Crazylychee
2025-06-16 14:31:18 +08:00
committed by GitHub
parent bc1a05d16c
commit e81dceb6ae
3 changed files with 217 additions and 77 deletions

View File

@@ -0,0 +1,35 @@
<!--
~ 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.
-->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<link rel="shortcut icon" href="./favicon.ico" type="image/x-icon" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta name="description" content="" />
<meta name="keywords" content="" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<title>RocketMQ Dashboard</title>
</head>
<body>
<noscript>You need to enable JavaScript to run this app.</noscript>
<!-- React App will mount here -->
<div id="root"></div>
</body>
</html>

View File

@@ -65,7 +65,110 @@ const Acl = () => {
const ipRegex = const ipRegex =
/^(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$|^((?:[0-9A-Fa-f]{1,4}:){7}[0-9A-Fa-f]{1,4}|(?:[0-9A-Fa-f]{1,4}:){6}[0-9A-Fa-f]{1,4}(?::[0-9A-Fa-f]{1,4}){0,1}|(?:[0-9A-Fa-f]{1,4}:){5}[0-9A-Fa-f]{1,4}(?::[0-9A-Fa-f]{1,4}){0,2}|(?:[0-9A-Fa-f]{1,4}:){4}[0-9A-Fa-f]{1,4}(?::[0-9A-Fa-f]{1,4}){0,3}|(?:[0-9A-Fa-f]{1,4}:){3}[0-9A-Fa-f]{1,4}(?::[0-9A-Fa-f]{1,4}){0,4}|(?:[0-9A-Fa-f]{1,4}:){2}[0-9A-Fa-f]{1,4}(?::[0-9A-Fa-f]{1,4}){0,5}|(?:[0-9A-Fa-f]{1,4}:){1}[0-9A-Fa-f]{1,4}(?::[0-9A-Fa-f]{1,4}){0,6}|(?::(?::[0-9A-Fa-f]{1,4}){1,7}|::))(\/(?:12[0-7]|1[0-1][0-9]|[1-9]?[0-9]))?$/; /^(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$|^((?:[0-9A-Fa-f]{1,4}:){7}[0-9A-Fa-f]{1,4}|(?:[0-9A-Fa-f]{1,4}:){6}[0-9A-Fa-f]{1,4}(?::[0-9A-Fa-f]{1,4}){0,1}|(?:[0-9A-Fa-f]{1,4}:){5}[0-9A-Fa-f]{1,4}(?::[0-9A-Fa-f]{1,4}){0,2}|(?:[0-9A-Fa-f]{1,4}:){4}[0-9A-Fa-f]{1,4}(?::[0-9A-Fa-f]{1,4}){0,3}|(?:[0-9A-Fa-f]{1,4}:){3}[0-9A-Fa-f]{1,4}(?::[0-9A-Fa-f]{1,4}){0,4}|(?:[0-9A-Fa-f]{1,4}:){2}[0-9A-Fa-f]{1,4}(?::[0-9A-Fa-f]{1,4}){0,5}|(?:[0-9A-Fa-f]{1,4}:){1}[0-9A-Fa-f]{1,4}(?::[0-9A-Fa-f]{1,4}){0,6}|(?::(?::[0-9A-Fa-f]{1,4}){1,7}|::))(\/(?:12[0-7]|1[0-1][0-9]|[1-9]?[0-9]))?$/;
// 支持 IPv4 和 IPv6包括 CIDR 表示法 // 支持 IPv4 和 IPv6包括 CIDR 表示法
// State to store the entire clusterInfo object for easy access
const [clusterData, setClusterData] = useState(null);
// State for the list of available cluster names for the dropdown
const [clusterNamesOptions, setClusterNamesOptions] = useState([]);
// State for the currently selected cluster name
const [selectedCluster, setSelectedCluster] = useState(undefined);
// State for the list of available broker names for the dropdown (depends on selectedCluster)
const [brokerNamesOptions, setBrokerNamesOptions] = useState([]);
// State for the currently selected broker name
const [selectedBroker, setSelectedBroker] = useState(undefined);
// State for the address of the selected broker
const [brokerAddress, setBrokerAddress] = useState(undefined);
// --- Data Fetching and Initial Setup ---
useEffect(() => {
const fetchData = async () => {
const clusterResponse = await remoteApi.getClusterList();
if (clusterResponse.status === 0 && clusterResponse.data) {
const { clusterInfo } = clusterResponse.data;
setClusterData(clusterInfo); // Store the entire clusterInfo
// Populate cluster names for the first dropdown
const clusterNames = Object.keys(clusterInfo?.clusterAddrTable || {});
setClusterNamesOptions(clusterNames.map(name => ({ label: name, value: name })));
// Set initial selections if clusters are available
if (clusterNames.length > 0) {
const defaultCluster = clusterNames[0];
setSelectedCluster(defaultCluster);
// Manually trigger broker list update for the default cluster
updateBrokerOptions(defaultCluster, clusterInfo);
// Set default broker and its address if available
const brokersInDefaultCluster = clusterInfo.clusterAddrTable[defaultCluster] || [];
if (brokersInDefaultCluster.length > 0) {
const defaultBroker = brokersInDefaultCluster[0];
setSelectedBroker(defaultBroker);
// Get the address from brokerAddrTable using the defaultBroker name
const addr = clusterInfo.brokerAddrTable?.[defaultBroker]?.brokerAddrs?.["0"];
setBrokerAddress(addr);
}
}
} else {
console.error('Failed to fetch cluster list:', clusterResponse.errMsg);
}
};
if(!clusterData){
fetchData();
}
if(brokerAddress){
// Call fetchUsers or fetchAcls based on activeTab initially
if (activeTab === 'users') {
fetchUsers();
} else {
fetchAcls();
}
}
}, [activeTab]); // Dependencies for useEffect
// --- Helper function to update broker options based on selected cluster ---
const updateBrokerOptions = (clusterName, info = clusterData) => {
if (!info || !info.clusterAddrTable) {
setBrokerNamesOptions([]);
return;
}
const brokersInCluster = info.clusterAddrTable[clusterName] || [];
setBrokerNamesOptions(brokersInCluster.map(broker => ({ label: broker, value: broker })));
};
// --- Event Handlers ---
const handleClusterChange = (value) => {
setSelectedCluster(value);
setSelectedBroker(undefined); // Reset broker selection
setBrokerAddress(undefined); // Reset broker address
// Update the broker options based on the newly selected cluster
updateBrokerOptions(value);
};
const handleBrokerChange = (value) => {
setSelectedBroker(value);
// Find the corresponding broker address from clusterData
if (clusterData && clusterData.brokerAddrTable && clusterData.brokerAddrTable[value]) {
const addr = clusterData.brokerAddrTable[value].brokerAddrs?.["0"];
setBrokerAddress(addr);
} else {
setBrokerAddress(undefined);
}
};
// --- Log selected values for debugging (optional) ---
useEffect(() => {
console.log('Selected Cluster:', selectedCluster);
console.log('Selected Broker:', selectedBroker);
console.log('Broker Address:', brokerAddress);
}, [selectedCluster, selectedBroker, brokerAddress]);
const handleIpChange = value => { const handleIpChange = value => {
// 过滤掉重复的IP地址 // 过滤掉重复的IP地址
const uniqueIps = Array.from(new Set(value)); const uniqueIps = Array.from(new Set(value));
@@ -92,7 +195,7 @@ const Acl = () => {
const fetchUsers = async () => { const fetchUsers = async () => {
setLoading(true); setLoading(true);
try { try {
const result = await remoteApi.listUsers(); const result = await remoteApi.listUsers(brokerAddress);
if (result && result.status === 0 && result.data) { if (result && result.status === 0 && result.data) {
const formattedUsers = result.data.map(user => ({ const formattedUsers = result.data.map(user => ({
...user, ...user,
@@ -114,7 +217,7 @@ const Acl = () => {
const fetchAcls = async (value) => { const fetchAcls = async (value) => {
setLoading(true); setLoading(true);
try { try {
const result = await remoteApi.listAcls(null, value); const result = await remoteApi.listAcls(brokerAddress, value);
if (result && result.status === 0) { if (result && result.status === 0) {
const formattedAcls = []; const formattedAcls = [];
@@ -162,13 +265,6 @@ const Acl = () => {
} }
}; };
useEffect(() => {
if (activeTab === 'users') {
fetchUsers();
} else {
fetchAcls();
}
}, [activeTab]);
// --- User Management Logic --- // --- User Management Logic ---
@@ -194,10 +290,10 @@ const Acl = () => {
const handleDeleteUser = async (username) => { const handleDeleteUser = async (username) => {
setLoading(true); setLoading(true);
try { try {
const result = await remoteApi.deleteUser(null, username); const result = await remoteApi.deleteUser(brokerAddress, username);
if (result.status === 0) { if (result.status === 0) {
messageApi.success(t.USER_DELETE_SUCCESS); messageApi.success(t.USER_DELETE_SUCCESS);
fetchUsers(); fetchUsers(brokerAddress);
} else { } else {
messageApi.error(t.USER_DELETE_FAILED + result.errMsg); messageApi.error(t.USER_DELETE_FAILED + result.errMsg);
} }
@@ -223,14 +319,14 @@ const Acl = () => {
}; };
if (currentUser) { if (currentUser) {
result = await remoteApi.updateUser(null, userInfoParam); result = await remoteApi.updateUser(brokerAddress, userInfoParam);
if (result.status === 0) { if (result.status === 0) {
messageApi.success(t.USER_UPDATE_SUCCESS); messageApi.success(t.USER_UPDATE_SUCCESS);
} else { } else {
messageApi.error(result.errMsg); messageApi.error(result.errMsg);
} }
} else { } else {
result = await remoteApi.createUser(null, userInfoParam); result = await remoteApi.createUser(brokerAddress, userInfoParam);
if (result.status === 0) { if (result.status === 0) {
messageApi.success(t.USER_CREATE_SUCCESS); messageApi.success(t.USER_CREATE_SUCCESS);
} else { } else {
@@ -272,7 +368,7 @@ const Acl = () => {
const handleDeleteAcl = async (subject, resource) => { const handleDeleteAcl = async (subject, resource) => {
setLoading(true); setLoading(true);
try { try {
const result = await remoteApi.deleteAcl(null, subject, resource); const result = await remoteApi.deleteAcl(brokerAddress, subject, resource);
if (result.status === 0) { if (result.status === 0) {
messageApi.success(t.ACL_DELETE_SUCCESS); messageApi.success(t.ACL_DELETE_SUCCESS);
fetchAcls(); fetchAcls();
@@ -308,22 +404,22 @@ const Acl = () => {
]; ];
if (isUpdate) { // This condition seems reversed for update/create based on the current logic. if (isUpdate) { // This condition seems reversed for update/create based on the current logic.
result = await remoteApi.updateAcl(null, values.subject, policiesParam); result = await remoteApi.updateAcl(brokerAddress, values.subject, policiesParam);
if (result.status === 0) { if (result.status === 0) {
messageApi.success(t.ACL_UPDATE_SUCCESS); messageApi.success(t.ACL_UPDATE_SUCCESS);
setIsAclModalVisible(false); setIsAclModalVisible(false);
fetchAcls(); fetchAcls(brokerAddress);
} else { } else {
messageApi.error(t.ACL_UPDATE_FAILED+result.errMsg); messageApi.error(t.ACL_UPDATE_FAILED+result.errMsg);
} }
setIsUpdate(false) setIsUpdate(false)
} else { } else {
result = await remoteApi.createAcl(null, values.subject, policiesParam); result = await remoteApi.createAcl(brokerAddress, values.subject, policiesParam);
console.log(result) console.log(result)
if (result.status === 0) { if (result.status === 0) {
messageApi.success(t.ACL_CREATE_SUCCESS); messageApi.success(t.ACL_CREATE_SUCCESS);
setIsAclModalVisible(false); setIsAclModalVisible(false);
fetchAcls(); fetchAcls(brokerAddress);
} else { } else {
messageApi.error(t.ACL_CREATE_FAILED+result.errMsg); messageApi.error(t.ACL_CREATE_FAILED+result.errMsg);
} }
@@ -474,14 +570,40 @@ const Acl = () => {
return ( return (
<> <>
{msgContextHolder} {msgContextHolder}
<div style={{ padding: 24 }}> <div style={{padding: 24}}>
<h2>{t.ACL_MANAGEMENT}</h2> <h2>{t.ACL_MANAGEMENT}</h2>
<div style={{ marginBottom: 16, display: 'flex', gap: 16 }}>
<Form.Item label={t.PLEASE_SELECT_CLUSTER} style={{ marginBottom: 0 }}>
<Select
placeholder={t.PLEASE_SELECT_CLUSTER}
style={{ width: 200 }}
onChange={handleClusterChange}
value={selectedCluster}
options={clusterNamesOptions}
/>
</Form.Item>
<Form.Item label={t.PLEASE_SELECT_BROKER} style={{ marginBottom: 0 }}>
<Select
placeholder={t.PLEASE_SELECT_BROKER}
style={{ width: 200 }}
onChange={handleBrokerChange}
value={selectedBroker}
options={brokerNamesOptions} // Now dynamically updated
disabled={!selectedCluster} // Disable broker selection if no cluster is chosen
/>
</Form.Item>
<Button type="primary" onClick={activeTab === 'users' ? fetchUsers : fetchAcls}>
{t.CONFIRM}
</Button>
</div>
<Tabs activeKey={activeTab} onChange={setActiveTab}> <Tabs activeKey={activeTab} onChange={setActiveTab}>
<TabPane tab={t.ACL_USERS} key="users" /> <TabPane tab={t.ACL_USERS} key="users"/>
<TabPane tab={t.ACL_PERMISSIONS} key="acls" /> <TabPane tab={t.ACL_PERMISSIONS} key="acls"/>
</Tabs> </Tabs>
<div style={{ marginBottom: 16, display: 'flex', justifyContent: 'space-between' }}> <div style={{marginBottom: 16, display: 'flex', justifyContent: 'space-between'}}>
<Button type="primary" onClick={activeTab === 'users' ? handleAddUser : handleAddAcl}> <Button type="primary" onClick={activeTab === 'users' ? handleAddUser : handleAddAcl}>
{activeTab === 'users' ? t.ADD_USER : t.ADD_ACL_PERMISSION} {activeTab === 'users' ? t.ADD_USER : t.ADD_ACL_PERMISSION}
</Button> </Button>
@@ -489,7 +611,7 @@ return (
placeholder={t.SEARCH_PLACEHOLDER} placeholder={t.SEARCH_PLACEHOLDER}
allowClear allowClear
onSearch={handleSearch} onSearch={handleSearch}
style={{ width: 300 }} style={{width: 300}}
/> />
</div> </div>
@@ -498,7 +620,7 @@ return (
columns={userColumns} columns={userColumns}
dataSource={userListData} dataSource={userListData}
loading={loading} loading={loading}
pagination={{ pageSize: 10 }} pagination={{pageSize: 10}}
rowKey="username" rowKey="username"
/> />
)} )}
@@ -508,7 +630,7 @@ return (
columns={aclColumns} columns={aclColumns}
dataSource={aclListData} dataSource={aclListData}
loading={loading} loading={loading}
pagination={{ pageSize: 10 }} pagination={{pageSize: 10}}
rowKey="key" rowKey="key"
/> />
)} )}
@@ -533,31 +655,31 @@ return (
form={userForm} form={userForm}
layout="vertical" layout="vertical"
name="user_form" name="user_form"
initialValues={{ userStatus: 'enable' }} initialValues={{userStatus: 'enable'}}
> >
<Form.Item <Form.Item
name="username" name="username"
label={t.USERNAME} label={t.USERNAME}
rules={[{ required: true, message: t.PLEASE_ENTER_USERNAME }]} rules={[{required: true, message: t.PLEASE_ENTER_USERNAME}]}
> >
<Input disabled={!!currentUser} /> <Input disabled={!!currentUser}/>
</Form.Item> </Form.Item>
<Form.Item <Form.Item
name="password" name="password"
label={t.PASSWORD} label={t.PASSWORD}
rules={[{ required: !currentUser, message: t.PLEASE_ENTER_PASSWORD }]} rules={[{required: !currentUser, message: t.PLEASE_ENTER_PASSWORD}]}
> >
<Input.Password <Input.Password
placeholder={t.PASSWORD} placeholder={t.PASSWORD}
iconRender={visible => (visible ? <EyeOutlined /> : <EyeInvisibleOutlined />)} iconRender={visible => (visible ? <EyeOutlined/> : <EyeInvisibleOutlined/>)}
/> />
</Form.Item> </Form.Item>
<Form.Item <Form.Item
name="userType" name="userType"
label={t.USER_TYPE} label={t.USER_TYPE}
rules={[{ required: true, message: t.PLEASE_SELECT_USER_TYPE }]} rules={[{required: true, message: t.PLEASE_SELECT_USER_TYPE}]}
> >
<Select mode="single" placeholder="Super, Normal" style={{ width: '100%' }}> <Select mode="single" placeholder="Super, Normal" style={{width: '100%'}}>
<Select.Option value="Super">Super</Select.Option> <Select.Option value="Super">Super</Select.Option>
<Select.Option value="Normal">Normal</Select.Option> <Select.Option value="Normal">Normal</Select.Option>
</Select> </Select>
@@ -565,9 +687,9 @@ return (
<Form.Item <Form.Item
name="userStatus" name="userStatus"
label={t.USER_STATUS} label={t.USER_STATUS}
rules={[{ required: true, message: t.PLEASE_SELECT_USER_STATUS }]} rules={[{required: true, message: t.PLEASE_SELECT_USER_STATUS}]}
> >
<Select mode="single" placeholder="enable, disable" style={{ width: '100%' }}> <Select mode="single" placeholder="enable, disable" style={{width: '100%'}}>
<Select.Option value="enable">enable</Select.Option> <Select.Option value="enable">enable</Select.Option>
<Select.Option value="disable">disable</Select.Option> <Select.Option value="disable">disable</Select.Option>
</Select> </Select>
@@ -591,17 +713,17 @@ return (
<Form.Item <Form.Item
name="subject" name="subject"
label={t.SUBJECT_LABEL} label={t.SUBJECT_LABEL}
rules={[{ required: true, message: t.PLEASE_ENTER_SUBJECT }]} rules={[{required: true, message: t.PLEASE_ENTER_SUBJECT}]}
> >
<SubjectInput disabled={!!currentAcl} /> <SubjectInput disabled={!!currentAcl}/>
</Form.Item> </Form.Item>
<Form.Item <Form.Item
name="policyType" name="policyType"
label={t.POLICY_TYPE} label={t.POLICY_TYPE}
rules={[{ required: true, message: t.PLEASE_ENTER_POLICY_TYPE }]} rules={[{required: true, message: t.PLEASE_ENTER_POLICY_TYPE}]}
> >
<Select mode="single" disabled={isUpdate} placeholder="policyType" style={{ width: '100%' }}> <Select mode="single" disabled={isUpdate} placeholder="policyType" style={{width: '100%'}}>
<Select.Option value="Custom">Custom</Select.Option> <Select.Option value="Custom">Custom</Select.Option>
<Select.Option value="Default">Default</Select.Option> <Select.Option value="Default">Default</Select.Option>
</Select> </Select>
@@ -610,12 +732,12 @@ return (
<Form.Item <Form.Item
name="resource" name="resource"
label={t.RESOURCE} label={t.RESOURCE}
rules={[{ required: true, message: t.PLEASE_ADD_RESOURCE }]} rules={[{required: true, message: t.PLEASE_ADD_RESOURCE}]}
> >
{isUpdate ? ( {isUpdate ? (
<Input disabled={isUpdate} /> <Input disabled={isUpdate}/>
) : ( ) : (
<ResourceInput /> <ResourceInput/>
)} )}
</Form.Item> </Form.Item>
@@ -623,7 +745,7 @@ return (
name="actions" name="actions"
label={t.OPERATION_TYPE} label={t.OPERATION_TYPE}
> >
<Select mode="multiple" placeholder="action" style={{ width: '100%' }}> <Select mode="multiple" placeholder="action" style={{width: '100%'}}>
<Select.Option value="All">All</Select.Option> <Select.Option value="All">All</Select.Option>
<Select.Option value="Pub">Pub</Select.Option> <Select.Option value="Pub">Pub</Select.Option>
<Select.Option value="Sub">Sub</Select.Option> <Select.Option value="Sub">Sub</Select.Option>
@@ -645,7 +767,7 @@ return (
> >
<Select <Select
mode="tags" mode="tags"
style={{ width: '100%' }} style={{width: '100%'}}
placeholder={t.ENTER_IP_HINT} placeholder={t.ENTER_IP_HINT}
onChange={handleIpChange} onChange={handleIpChange}
onDeselect={handleIpDeselect} onDeselect={handleIpDeselect}
@@ -660,9 +782,9 @@ return (
<Form.Item <Form.Item
name="decision" name="decision"
label={t.DECISION} label={t.DECISION}
rules={[{ required: true, message: t.PLEASE_ENTER_DECISION }]} rules={[{required: true, message: t.PLEASE_ENTER_DECISION}]}
> >
<Select mode="single" placeholder="Allow, Deny" style={{ width: '100%' }}> <Select mode="single" placeholder="Allow, Deny" style={{width: '100%'}}>
<Select.Option value="Allow">Allow</Select.Option> <Select.Option value="Allow">Allow</Select.Option>
<Select.Option value="Deny">Deny</Select.Option> <Select.Option value="Deny">Deny</Select.Option>
</Select> </Select>
@@ -671,6 +793,7 @@ return (
</Modal> </Modal>
</div> </div>
</> </>
);} );
}
export default Acl; export default Acl;

View File

@@ -18,13 +18,11 @@
package org.apache.rocketmq.dashboard.service.impl; package org.apache.rocketmq.dashboard.service.impl;
import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.ObjectMapper;
import org.apache.rocketmq.dashboard.config.RMQConfigure;
import org.apache.rocketmq.dashboard.model.Entry; import org.apache.rocketmq.dashboard.model.Entry;
import org.apache.rocketmq.dashboard.model.Policy; import org.apache.rocketmq.dashboard.model.Policy;
import org.apache.rocketmq.dashboard.model.PolicyRequest; import org.apache.rocketmq.dashboard.model.PolicyRequest;
import org.apache.rocketmq.dashboard.model.request.UserInfoParam; import org.apache.rocketmq.dashboard.model.request.UserInfoParam;
import org.apache.rocketmq.dashboard.service.AclService; import org.apache.rocketmq.dashboard.service.AclService;
import org.apache.rocketmq.dashboard.service.ClusterInfoService;
import org.apache.rocketmq.remoting.protocol.body.AclInfo; import org.apache.rocketmq.remoting.protocol.body.AclInfo;
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;
@@ -47,20 +45,12 @@ public class AclServiceImpl implements AclService {
@Autowired @Autowired
private MQAdminExt mqAdminExt; private MQAdminExt mqAdminExt;
@Autowired
private RMQConfigure rmqConfigure;
@Autowired
private ClusterInfoService clusterInfoService;
private static final String DEFAULT_BROKER_ADDRESS = "localhost:10911";
@Override @Override
public List<UserInfo> listUsers(String brokerAddress) { public List<UserInfo> listUsers(String brokerAddress) {
List<UserInfo> userList; List<UserInfo> userList;
try { try {
String address = brokerAddress != null && !brokerAddress.isEmpty() ? brokerAddress : DEFAULT_BROKER_ADDRESS; userList = mqAdminExt.listUser(brokerAddress, "");
userList = mqAdminExt.listUser(address, "");
} catch (Exception ex) { } catch (Exception ex) {
logger.error("Failed to list users from broker: {}", brokerAddress, ex); logger.error("Failed to list users from broker: {}", brokerAddress, ex);
throw new RuntimeException("Failed to list users", ex); throw new RuntimeException("Failed to list users", ex);
@@ -76,14 +66,13 @@ public class AclServiceImpl implements AclService {
public Object listAcls(String brokerAddress, String searchParam) { public Object listAcls(String brokerAddress, String searchParam) {
List<AclInfo> aclList; List<AclInfo> aclList;
try { try {
String address = brokerAddress != null && !brokerAddress.isEmpty() ? brokerAddress : DEFAULT_BROKER_ADDRESS;
String user = searchParam != null ? searchParam : ""; String user = searchParam != null ? searchParam : "";
String res = searchParam != null ? searchParam : ""; String res = searchParam != null ? searchParam : "";
aclList = mqAdminExt.listAcl(address, user, ""); aclList = mqAdminExt.listAcl(brokerAddress, user, "");
if (aclList == null) { if (aclList == null) {
aclList = new ArrayList<>(); aclList = new ArrayList<>();
} }
List<AclInfo> resAclList = mqAdminExt.listAcl(address, "", res); List<AclInfo> resAclList = mqAdminExt.listAcl(brokerAddress, "", res);
if (resAclList != null) { if (resAclList != null) {
aclList.addAll(resAclList); aclList.addAll(resAclList);
} }
@@ -117,8 +106,6 @@ public class AclServiceImpl implements AclService {
return successfulResources; return successfulResources;
} }
String brokerAddress = policyRequest.getBrokerAddress() != null && !policyRequest.getBrokerAddress().isEmpty() ?
policyRequest.getBrokerAddress() : DEFAULT_BROKER_ADDRESS;
String subject = policyRequest.getSubject(); String subject = policyRequest.getSubject();
if (subject == null || subject.isEmpty()) { if (subject == null || subject.isEmpty()) {
@@ -150,12 +137,12 @@ public class AclServiceImpl implements AclService {
aclInfo.setSubject(subject); aclInfo.setSubject(subject);
try { try {
logger.info("Attempting to create ACL for subject: {}, resource: {} on broker: {}", subject, resource, brokerAddress); logger.info("Attempting to create ACL for subject: {}, resource: {} on broker: {}", subject, resource, policyRequest.getBrokerAddress());
mqAdminExt.createAcl(brokerAddress, aclInfo); mqAdminExt.createAcl(policyRequest.getBrokerAddress(), aclInfo);
successfulResources.add(resource); successfulResources.add(resource);
logger.info("Successfully created ACL for subject: {}, resource: {}", subject, resource); logger.info("Successfully created ACL for subject: {}, resource: {}", subject, resource);
} catch (Exception ex) { } catch (Exception ex) {
logger.error("Failed to create ACL for subject: {}, resource: {} on broker: {}", subject, resource, brokerAddress, ex); logger.error("Failed to create ACL for subject: {}, resource: {} on broker: {}", subject, resource, policyRequest.getBrokerAddress(), ex);
throw new RuntimeException("Failed to create ACL", ex); throw new RuntimeException("Failed to create ACL", ex);
} }
} }
@@ -169,8 +156,7 @@ public class AclServiceImpl implements AclService {
@Override @Override
public void deleteUser(String brokerAddress, String username) { public void deleteUser(String brokerAddress, String username) {
try { try {
String address = brokerAddress != null && !brokerAddress.isEmpty() ? brokerAddress : DEFAULT_BROKER_ADDRESS; mqAdminExt.deleteUser(brokerAddress, username);
mqAdminExt.deleteUser(address, username);
} catch (Exception ex) { } catch (Exception ex) {
logger.error("Failed to delete user: {} from broker: {}", username, brokerAddress, ex); logger.error("Failed to delete user: {} from broker: {}", username, brokerAddress, ex);
throw new RuntimeException("Failed to delete user", ex); throw new RuntimeException("Failed to delete user", ex);
@@ -186,8 +172,7 @@ public class AclServiceImpl implements AclService {
user.setUserType(userParam.getUserType()); user.setUserType(userParam.getUserType());
try { try {
String address = brokerAddress != null && !brokerAddress.isEmpty() ? brokerAddress : DEFAULT_BROKER_ADDRESS; mqAdminExt.updateUser(brokerAddress, user);
mqAdminExt.updateUser(address, user);
} catch (Exception ex) { } catch (Exception ex) {
logger.error("Failed to update user: {} on broker: {}", userParam.getUsername(), brokerAddress, ex); logger.error("Failed to update user: {} on broker: {}", userParam.getUsername(), brokerAddress, ex);
throw new RuntimeException("Failed to update user", ex); throw new RuntimeException("Failed to update user", ex);
@@ -202,8 +187,7 @@ public class AclServiceImpl implements AclService {
user.setUserStatus(userParam.getUserStatus()); user.setUserStatus(userParam.getUserStatus());
user.setUserType(userParam.getUserType()); user.setUserType(userParam.getUserType());
try { try {
String address = brokerAddress != null && !brokerAddress.isEmpty() ? brokerAddress : DEFAULT_BROKER_ADDRESS; mqAdminExt.createUser(brokerAddress, user);
mqAdminExt.createUser(address, user);
} catch (Exception ex) { } catch (Exception ex) {
logger.error("Failed to create user: {} on broker: {}", userParam.getUsername(), brokerAddress, ex); logger.error("Failed to create user: {} on broker: {}", userParam.getUsername(), brokerAddress, ex);
throw new RuntimeException("Failed to create user", ex); throw new RuntimeException("Failed to create user", ex);
@@ -213,9 +197,8 @@ public class AclServiceImpl implements AclService {
@Override @Override
public void deleteAcl(String brokerAddress, String subject, String resource) { public void deleteAcl(String brokerAddress, String subject, String resource) {
try { try {
String address = brokerAddress != null && !brokerAddress.isEmpty() ? brokerAddress : DEFAULT_BROKER_ADDRESS;
String res = resource != null ? resource : ""; String res = resource != null ? resource : "";
mqAdminExt.deleteAcl(address, subject, res); mqAdminExt.deleteAcl(brokerAddress, subject, res);
} catch (Exception ex) { } catch (Exception ex) {
logger.error("Failed to delete ACL for subject: {} and resource: {} on broker: {}", subject, resource, brokerAddress, ex); logger.error("Failed to delete ACL for subject: {} and resource: {} on broker: {}", subject, resource, brokerAddress, ex);
throw new RuntimeException("Failed to delete ACL", ex); throw new RuntimeException("Failed to delete ACL", ex);
@@ -229,8 +212,8 @@ public class AclServiceImpl implements AclService {
logger.warn("Policy request is null or policies list is empty. No ACLs to update."); logger.warn("Policy request is null or policies list is empty. No ACLs to update.");
} }
String brokerAddress = policyRequest.getBrokerAddress() != null && !policyRequest.getBrokerAddress().isEmpty() ? assert policyRequest != null;
policyRequest.getBrokerAddress() : DEFAULT_BROKER_ADDRESS; String brokerAddress = policyRequest.getBrokerAddress();
String subject = policyRequest.getSubject(); String subject = policyRequest.getSubject();
if (subject == null || subject.isEmpty()) { if (subject == null || subject.isEmpty()) {
@@ -262,8 +245,7 @@ public class AclServiceImpl implements AclService {
aclInfo.setSubject(subject); aclInfo.setSubject(subject);
try { try {
String address = brokerAddress != null && !brokerAddress.isEmpty() ? brokerAddress : DEFAULT_BROKER_ADDRESS; mqAdminExt.updateAcl(brokerAddress, aclInfo);
mqAdminExt.updateAcl(address, aclInfo);
} catch (Exception ex) { } catch (Exception ex) {
logger.error("Failed to update ACL for subject: {} on broker: {}", subject, brokerAddress, ex); logger.error("Failed to update ACL for subject: {} on broker: {}", subject, brokerAddress, ex);
throw new RuntimeException("Failed to update ACL", ex); throw new RuntimeException("Failed to update ACL", ex);