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 abe12af0d fix(message): preserve empty offset results from registered 
providers (#6662)
abe12af0d is described below

commit abe12af0d5bf7017fa38fb02c815611df78c1fe0
Author: 健康宝 <[email protected]>
AuthorDate: Thu Oct 15 18:17:52 2026 +0800

    fix(message): preserve empty offset results from registered providers 
(#6662)
---
 .../studio/instance/message/MessageService.java    | 14 +++++---
 .../instance/message/MessageServiceTest.java       | 37 ++++++++++++++++++++++
 2 files changed, 47 insertions(+), 4 deletions(-)

diff --git 
a/server/src/main/java/org/apache/rocketmq/studio/instance/message/MessageService.java
 
b/server/src/main/java/org/apache/rocketmq/studio/instance/message/MessageService.java
index f997a32e8..557363601 100644
--- 
a/server/src/main/java/org/apache/rocketmq/studio/instance/message/MessageService.java
+++ 
b/server/src/main/java/org/apache/rocketmq/studio/instance/message/MessageService.java
@@ -149,10 +149,16 @@ public class MessageService {
         if (offset < 0) {
             throw new BusinessException(400, "offset must not be negative");
         }
-        return providerRegistry.byInstanceId(instanceId)
-                .map(provider -> provider.pullMessageAtOffset(instanceId, 
topic, brokerName, queueId, offset))
-                .orElseGet(() -> messageProvider.pullMessageAtOffset(
-                        instanceId, topic, brokerName, queueId, offset));
+        // The registered provider's null is a legitimate "no message at this
+        // offset" answer; Optional.map would turn it into an empty Optional
+        // and the fallback below would issue a second, identical pull whose
+        // failure would surface as an error on a query that already succeeded
+        // once. The fallback is only for instances without a provider.
+        InstanceProvider provider = 
providerRegistry.byInstanceId(instanceId).orElse(null);
+        if (provider != null) {
+            return provider.pullMessageAtOffset(instanceId, topic, brokerName, 
queueId, offset);
+        }
+        return messageProvider.pullMessageAtOffset(instanceId, topic, 
brokerName, queueId, offset);
     }
 
     public DirectConsumeMessageResultVO 
consumeMessageDirectly(DirectConsumeMessageDTO request) {
diff --git 
a/server/src/test/java/org/apache/rocketmq/studio/instance/message/MessageServiceTest.java
 
b/server/src/test/java/org/apache/rocketmq/studio/instance/message/MessageServiceTest.java
index 55a0021b0..04c961dee 100644
--- 
a/server/src/test/java/org/apache/rocketmq/studio/instance/message/MessageServiceTest.java
+++ 
b/server/src/test/java/org/apache/rocketmq/studio/instance/message/MessageServiceTest.java
@@ -697,4 +697,41 @@ class MessageServiceTest {
 
         verifyNoInteractions(fallback);
     }
+
+    @Test
+    void pullMessageAtOffsetKeepsTheRegisteredProviderNullResultTest() {
+        MessageProvider fallback = mock(MessageProvider.class);
+        InstanceProvider provider = mock(InstanceProvider.class);
+        InstanceProviderRegistry registry = 
mock(InstanceProviderRegistry.class);
+        MessageService service = new MessageService(fallback, registry, 
mock(QueryHistoryService.class),
+                mock(OperationAuditService.class), ownershipGuard());
+        
when(registry.byInstanceId("cloud-instance")).thenReturn(Optional.of(provider));
+        when(provider.pullMessageAtOffset("cloud-instance", "TopicA", 
"broker-a", 0, 7L))
+                .thenReturn(null);
+
+        // A registered provider's null is the documented "no message at this
+        // offset" answer: it must not trigger the fallback (a second,
+        // identical pull whose failure would surface as an error here).
+        assertThat(service.pullMessageAtOffset("cloud-instance", "TopicA", 
"broker-a", 0, 7L))
+                .isNull();
+
+        verify(provider, org.mockito.Mockito.times(1))
+                .pullMessageAtOffset("cloud-instance", "TopicA", "broker-a", 
0, 7L);
+        verifyNoInteractions(fallback);
+    }
+
+    @Test
+    void pullMessageAtOffsetStillFallsBackWithoutAProviderTest() {
+        MessageProvider fallback = mock(MessageProvider.class);
+        MessageRecordVO record = 
MessageRecordVO.builder().msgId("msg-1").build();
+        InstanceProviderRegistry registry = 
mock(InstanceProviderRegistry.class);
+        MessageService service = new MessageService(fallback, registry, 
mock(QueryHistoryService.class),
+                mock(OperationAuditService.class), ownershipGuard());
+        
when(registry.byInstanceId("apache-instance")).thenReturn(Optional.empty());
+        when(fallback.pullMessageAtOffset("apache-instance", "TopicA", 
"broker-a", 0, 7L))
+                .thenReturn(record);
+
+        assertThat(service.pullMessageAtOffset("apache-instance", "TopicA", 
"broker-a", 0, 7L))
+                .isSameAs(record);
+    }
 }

Reply via email to