This is an automated email from the ASF dual-hosted git repository.

lizhimins pushed a commit to branch rocketmq-studio
in repository https://gitbox.apache.org/repos/asf/rocketmq-dashboard.git


The following commit(s) were added to refs/heads/rocketmq-studio by this push:
     new f531fb8e6 fix(studio): preserve cluster filter in paginated metadata 
queries (#4551)
f531fb8e6 is described below

commit f531fb8e684e21b90df153af2a6b9d3558fd85d7
Author: Yexi Xiang <[email protected]>
AuthorDate: Mon Sep 21 17:33:36 2026 +0800

    fix(studio): preserve cluster filter in paginated metadata queries (#4551)
    
    MetadataService dropped the documented clusterId filter on the 
instance-scoped pagination paths: listTopicsPage / listConsumerGroupsPage 
forwarded only type/search, so a cluster filter was silently ignored. 
InstanceProvider gains clusterId-aware default overloads (falling back to the 
instance-wide query for providers without physical cluster scoping) and 
ApacheInstanceProvider passes the filter through to RocketMQMetadataProvider.
    
    Fixes #4549
---
 .../studio/instance/topic/MetadataService.java     |  8 ++---
 .../rocketmq/studio/provider/InstanceProvider.java | 18 +++++++++++
 .../provider/apache/ApacheInstanceProvider.java    | 12 ++++++++
 .../studio/instance/topic/MetadataServiceTest.java | 36 ++++++++++++++++++++--
 .../apache/ApacheInstanceProviderTest.java         | 24 +++++++++++++++
 5 files changed, 92 insertions(+), 6 deletions(-)

diff --git 
a/server/src/main/java/org/apache/rocketmq/studio/instance/topic/MetadataService.java
 
b/server/src/main/java/org/apache/rocketmq/studio/instance/topic/MetadataService.java
index e2c3e6394..2b551cd48 100644
--- 
a/server/src/main/java/org/apache/rocketmq/studio/instance/topic/MetadataService.java
+++ 
b/server/src/main/java/org/apache/rocketmq/studio/instance/topic/MetadataService.java
@@ -141,8 +141,8 @@ public class MetadataService {
             return metadataProvider.listTopicsPage(normalizeFilter(clusterId),
                     normalizeFilter(type), normalizeFilter(search), page, 
pageSize);
         }
-        return resolve(instanceId).listTopicsPage(instanceId, 
normalizeFilter(type),
-                normalizeFilter(search), page, pageSize);
+        return resolve(instanceId).listTopicsPage(instanceId, 
normalizeFilter(clusterId),
+                normalizeFilter(type), normalizeFilter(search), page, 
pageSize);
     }
 
 
@@ -373,8 +373,8 @@ public class MetadataService {
             return 
metadataProvider.listConsumerGroupsPage(normalizeFilter(clusterId),
                     normalizeFilter(search), page, pageSize);
         }
-        return resolve(instanceId).listConsumerGroupsPage(instanceId, 
normalizeFilter(search),
-                page, pageSize);
+        return resolve(instanceId).listConsumerGroupsPage(instanceId, 
normalizeFilter(clusterId),
+                normalizeFilter(search), page, pageSize);
     }
 
 
diff --git 
a/server/src/main/java/org/apache/rocketmq/studio/provider/InstanceProvider.java
 
b/server/src/main/java/org/apache/rocketmq/studio/provider/InstanceProvider.java
index fddd62c1f..d419ca7de 100644
--- 
a/server/src/main/java/org/apache/rocketmq/studio/provider/InstanceProvider.java
+++ 
b/server/src/main/java/org/apache/rocketmq/studio/provider/InstanceProvider.java
@@ -69,6 +69,15 @@ public interface InstanceProvider {
         return PageResult.of(topics.subList(from, to), total, page, pageSize);
     }
 
+    /**
+     * Instance-scoped topic pagination with an optional physical cluster 
filter. Providers that
+     * do not support physical cluster scoping retain the existing 
instance-wide fallback.
+     */
+    default PageResult<TopicVO> listTopicsPage(String instanceId, String 
clusterId, String type,
+            String search, int page, int pageSize) {
+        return listTopicsPage(instanceId, type, search, page, pageSize);
+    }
+
     TopicVO createTopic(String instanceId, TopicVO topic);
 
     TopicVO updateTopic(String instanceId, TopicVO topic);
@@ -103,6 +112,15 @@ public interface InstanceProvider {
         return PageResult.of(groups.subList(from, to), total, page, pageSize);
     }
 
+    /**
+     * Instance-scoped consumer-group pagination with an optional physical 
cluster filter.
+     * Providers without physical cluster scoping retain the existing 
instance-wide fallback.
+     */
+    default PageResult<ConsumerGroupVO> listConsumerGroupsPage(String 
instanceId, String clusterId,
+            String search, int page, int pageSize) {
+        return listConsumerGroupsPage(instanceId, search, page, pageSize);
+    }
+
     ConsumerGroupVO createConsumerGroup(String instanceId, ConsumerGroupVO 
group);
 
     default ConsumerGroupVO updateConsumerGroup(String instanceId, 
ConsumerGroupVO group) {
diff --git 
a/server/src/main/java/org/apache/rocketmq/studio/provider/apache/ApacheInstanceProvider.java
 
b/server/src/main/java/org/apache/rocketmq/studio/provider/apache/ApacheInstanceProvider.java
index abcd75d13..faea84e07 100644
--- 
a/server/src/main/java/org/apache/rocketmq/studio/provider/apache/ApacheInstanceProvider.java
+++ 
b/server/src/main/java/org/apache/rocketmq/studio/provider/apache/ApacheInstanceProvider.java
@@ -97,6 +97,12 @@ public class ApacheInstanceProvider implements 
InstanceProvider {
         return metadataProvider.listTopicsPage(instanceId, null, type, search, 
page, pageSize);
     }
 
+    @Override
+    public PageResult<TopicVO> listTopicsPage(String instanceId, String 
clusterId, String type,
+            String search, int page, int pageSize) {
+        return metadataProvider.listTopicsPage(instanceId, clusterId, type, 
search, page, pageSize);
+    }
+
     @Override
     public TopicVO createTopic(String instanceId, TopicVO topic) {
         return adminClient.createTopic(instanceId, topic);
@@ -133,6 +139,12 @@ public class ApacheInstanceProvider implements 
InstanceProvider {
         return metadataProvider.listConsumerGroupsPage(instanceId, null, 
search, page, pageSize);
     }
 
+    @Override
+    public PageResult<ConsumerGroupVO> listConsumerGroupsPage(String 
instanceId, String clusterId,
+            String search, int page, int pageSize) {
+        return metadataProvider.listConsumerGroupsPage(instanceId, clusterId, 
search, page, pageSize);
+    }
+
     @Override
     public ConsumerGroupVO createConsumerGroup(String instanceId, 
ConsumerGroupVO group) {
         return adminClient.createConsumerGroup(group);
diff --git 
a/server/src/test/java/org/apache/rocketmq/studio/instance/topic/MetadataServiceTest.java
 
b/server/src/test/java/org/apache/rocketmq/studio/instance/topic/MetadataServiceTest.java
index 65f28b5fb..b13b809bc 100644
--- 
a/server/src/test/java/org/apache/rocketmq/studio/instance/topic/MetadataServiceTest.java
+++ 
b/server/src/test/java/org/apache/rocketmq/studio/instance/topic/MetadataServiceTest.java
@@ -295,6 +295,22 @@ class MetadataServiceTest {
         verify(apacheProvider).listTopics(null, null, null);
     }
 
+    @Test
+    void listTopicsPageShouldApplyClusterFilterForInstanceScopedQueriesTest() {
+        TopicVO clusterATopic = new TopicVO();
+        clusterATopic.setName("orders-a");
+        clusterATopic.setClusterId("cluster-a");
+        when(apacheProvider.listTopicsPage("instance-a", "cluster-a", null, 
null, 1, 20))
+                .thenReturn(PageResult.of(List.of(clusterATopic), 1, 1, 20));
+
+        PageResult<TopicVO> result = metadataService.listTopicsPage(
+                "instance-a", "cluster-a", null, null, 1, 20);
+
+        assertThat(result.getItems()).containsExactly(clusterATopic);
+        assertThat(result.getTotal()).isEqualTo(1);
+        verify(apacheProvider).listTopicsPage("instance-a", "cluster-a", null, 
null, 1, 20);
+    }
+
     @Test
     void topicWriteOperationsShouldRejectNullRequest() {
         assertThatThrownBy(() -> metadataService.createTopic(null))
@@ -758,7 +774,7 @@ class MetadataServiceTest {
     void listConsumerGroupsPageShouldPaginateFromOneBasedIndexes() {
         ConsumerGroupVO third = new ConsumerGroupVO();
         third.setName("cg-c");
-        when(apacheProvider.listConsumerGroupsPage("instance-a", "order", 2, 
2))
+        when(apacheProvider.listConsumerGroupsPage("instance-a", null, 
"order", 2, 2))
                 .thenReturn(PageResult.of(List.of(third), 3, 2, 2));
 
         PageResult<ConsumerGroupVO> result =
@@ -768,10 +784,26 @@ class MetadataServiceTest {
         assertThat(result.getTotal()).isEqualTo(3);
         assertThat(result.getPage()).isEqualTo(2);
         assertThat(result.getSize()).isEqualTo(2);
-        verify(apacheProvider).listConsumerGroupsPage("instance-a", "order", 
2, 2);
+        verify(apacheProvider).listConsumerGroupsPage("instance-a", null, 
"order", 2, 2);
         verify(apacheProvider, 
org.mockito.Mockito.never()).listConsumerGroups("instance-a", "order");
     }
 
+    @Test
+    void 
listConsumerGroupsPageShouldApplyClusterFilterForInstanceScopedQueriesTest() {
+        ConsumerGroupVO clusterAGroup = new ConsumerGroupVO();
+        clusterAGroup.setName("group-a");
+        clusterAGroup.setClusterId("cluster-a");
+        when(apacheProvider.listConsumerGroupsPage("instance-a", "cluster-a", 
null, 1, 20))
+                .thenReturn(PageResult.of(List.of(clusterAGroup), 1, 1, 20));
+
+        PageResult<ConsumerGroupVO> result = 
metadataService.listConsumerGroupsPage(
+                "instance-a", "cluster-a", null, 1, 20);
+
+        assertThat(result.getItems()).containsExactly(clusterAGroup);
+        assertThat(result.getTotal()).isEqualTo(1);
+        verify(apacheProvider).listConsumerGroupsPage("instance-a", 
"cluster-a", null, 1, 20);
+    }
+
     @Test
     void 
listConsumerGroupsPageShouldReturnEmptyItemsWhenPageStartsPastFilteredTotal() {
         when(metadataProvider.listConsumerGroupsPage("cluster-1", "order", 2, 
1))
diff --git 
a/server/src/test/java/org/apache/rocketmq/studio/provider/apache/ApacheInstanceProviderTest.java
 
b/server/src/test/java/org/apache/rocketmq/studio/provider/apache/ApacheInstanceProviderTest.java
index 6968df8c5..49910eb3e 100644
--- 
a/server/src/test/java/org/apache/rocketmq/studio/provider/apache/ApacheInstanceProviderTest.java
+++ 
b/server/src/test/java/org/apache/rocketmq/studio/provider/apache/ApacheInstanceProviderTest.java
@@ -134,6 +134,18 @@ class ApacheInstanceProviderTest {
         verify(metadataProvider).listTopics("inst-1", null, "FIFO", "orders");
     }
 
+    @Test
+    void listTopicsPageShouldPassClusterToMetadataProviderTest() {
+        PageResult<TopicVO> page = PageResult.of(java.util.List.of(), 0, 1, 
20);
+        when(metadataProvider.listTopicsPage("inst-1", "cluster-a", "FIFO", 
"orders", 1, 20))
+                .thenReturn(page);
+
+        assertThat(provider.listTopicsPage("inst-1", "cluster-a", "FIFO", 
"orders", 1, 20))
+                .isSameAs(page);
+
+        verify(metadataProvider).listTopicsPage("inst-1", "cluster-a", "FIFO", 
"orders", 1, 20);
+    }
+
     @Test
     void listConsumerGroupsShouldPassTheSelectedInstanceToMetadataProvider() {
         when(metadataProvider.listConsumerGroups("inst-1", null, 
"orders")).thenReturn(java.util.List.of());
@@ -152,4 +164,16 @@ class ApacheInstanceProviderTest {
 
         verify(metadataProvider).listConsumerGroupsPage("inst-1", null, 
"orders", 1, 20);
     }
+
+    @Test
+    void listConsumerGroupsPageShouldPassClusterToMetadataProviderTest() {
+        PageResult<ConsumerGroupVO> page = PageResult.of(java.util.List.of(), 
0, 1, 20);
+        when(metadataProvider.listConsumerGroupsPage("inst-1", "cluster-a", 
"orders", 1, 20))
+                .thenReturn(page);
+
+        assertThat(provider.listConsumerGroupsPage("inst-1", "cluster-a", 
"orders", 1, 20))
+                .isSameAs(page);
+
+        verify(metadataProvider).listConsumerGroupsPage("inst-1", "cluster-a", 
"orders", 1, 20);
+    }
 }

Reply via email to