tju-yxq opened a new issue, #1428:
URL: https://github.com/apache/rocketmq-dashboard/issues/1428

   ## Bug Report
   
   ### Before Creating the Bug Report
   
   - [x] I found a bug, not just asking a question, which should be created in 
[GitHub Discussions](https://github.com/apache/rocketmq/discussions).
   - [x] I have searched the [GitHub 
Issues](https://github.com/apache/rocketmq/issues) and [GitHub 
Discussions](https://github.com/apache/rocketmq/discussions) of this repository 
and believe that this is not a duplicate.
   - [x] I have confirmed that this bug belongs to the current repository, not 
other repositories of RocketMQ.
   
   ### Runtime platform environment
   
   OS: Ubuntu 20.04 / Any OS running RocketMQ Studio
   
   ### RocketMQ version
   
   branch: rocketmq-studio
   version: 5.3.2+
   Git commit id: f727341
   
   ### JDK Version
   
   OpenJDK 21
   
   ### Describe the Bug
   
   `RocketMQAdminClientImpl.getAllMasterBrokerAddrs()` returns **all** master 
broker addresses from the entire NameServer topology, regardless of which 
cluster they belong to. When `createTopic`, `updateTopic`, or 
`createConsumerGroup` call this method, the topic/group config is pushed to 
**every broker across all clusters**, not just the target cluster.
   
   ```java
   private Set<String> getAllMasterBrokerAddrs(MQAdminExt admin) throws 
Exception {
       Set<String> addrs = new HashSet<>();
       ClusterInfo clusterInfo = admin.examineBrokerClusterInfo();
       // ... iterates ALL brokers in brokerAddrTable, not filtered by cluster
       for (BrokerData brokerData : clusterInfo.getBrokerAddrTable().values()) {
           String masterAddr = brokerData.getBrokerAddrs().get(0L);
           if (masterAddr != null) {
               addrs.add(masterAddr);
           }
       }
       return addrs;
   }
   ```
   
   Meanwhile, `getClusterName()` returns only the **first** cluster name from 
`clusterAddrTable.keySet().iterator().next()`, so the DB record is associated 
with just one cluster while the broker-side config is spread to all clusters.
   
   ### Impact
   
   In a NameServer managing multiple clusters (e.g., `DefaultCluster` and 
`BatchCluster`):
   1. Creating a topic for `DefaultCluster` also creates it on `BatchCluster`'s 
brokers.
   2. Creating a consumer group for `DefaultCluster` also registers it on 
`BatchCluster`'s brokers.
   3. Deleting a topic calls `deleteTopicInBroker` with all broker addresses, 
removing it from all clusters.
   4. The DB record only tracks the first cluster, so the UI shows the 
topic/group for only one cluster while it actually exists on all.
   
   ### Steps to Reproduce
   
   1. Configure a RocketMQ NameServer managing two clusters: `clusterA` 
(brokers: `broker-a1`, `broker-a2`) and `clusterB` (brokers: `broker-b1`, 
`broker-b2`).
   2. In RocketMQ Studio, create a topic `test-topic` targeting `clusterA`.
   3. Check `clusterB`'s brokers: `mqadmin topicList -b broker-b1:10911` - 
`test-topic` is present even though it was only meant for `clusterA`.
   4. The Studio DB record associates `test-topic` with `clusterA` (the first 
cluster returned by `getClusterName`).
   
   ### What Did You Expect to See?
   
   Topic and consumer group operations should only target brokers belonging to 
the specified cluster, using the `clusterAddrTable` to map cluster name to 
broker names and then to broker addresses.
   
   ### What Did You See Instead?
   
   Topics and groups are created on all brokers across all clusters managed by 
the NameServer.
   
   ### Additional Context
   
   **Affected file**: 
`server/src/main/java/org/apache/rocketmq/studio/provider/apache/RocketMQAdminClientImpl.java`,
 method `getAllMasterBrokerAddrs()` at approximately line 500.
   
   **Related issues**: #1167, #1243, #1131 address instance routing (which 
NameServer to connect to), but this bug is different: even when connected to 
the correct NameServer, the code pushes config to all clusters instead of the 
target cluster.
   
   **Fix approach**:
   
   Add an overload that filters brokers by cluster name:
   
   ```java
   private Set<String> getMasterBrokerAddrsForCluster(MQAdminExt admin, String 
clusterName) throws Exception {
       Set<String> addrs = new HashSet<>();
       ClusterInfo clusterInfo = admin.examineBrokerClusterInfo();
       if (clusterInfo == null || clusterInfo.getClusterAddrTable() == null) {
           return addrs;
       }
       Set<String> brokerNames = 
clusterInfo.getClusterAddrTable().get(clusterName);
       if (brokerNames == null || clusterInfo.getBrokerAddrTable() == null) {
           return addrs;
       }
       for (String brokerName : brokerNames) {
           BrokerData brokerData = 
clusterInfo.getBrokerAddrTable().get(brokerName);
           if (brokerData != null && brokerData.getBrokerAddrs() != null) {
               String masterAddr = brokerData.getBrokerAddrs().get(0L);
               if (masterAddr == null && 
!brokerData.getBrokerAddrs().isEmpty()) {
                   masterAddr = 
brokerData.getBrokerAddrs().values().iterator().next();
               }
               if (masterAddr != null) {
                   addrs.add(masterAddr);
               }
           }
       }
       return addrs;
   }
   ```
   
   Then update `createTopic`, `updateTopic`, `createConsumerGroup`, 
`deleteConsumerGroup`, and `deleteTopic` to use the cluster-scoped method with 
the cluster name from `getClusterName()`. The existing 
`getAllMasterBrokerAddrs` can be kept as a fallback for single-cluster 
deployments.
   
   This adds approximately 25 lines (the new method) and modifies 4-5 call 
sites, totaling ~35 lines of changes.
   


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to