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 c44dd9ced fix(message): preserve unknown queue metadata in query
history (#5143)
c44dd9ced is described below
commit c44dd9ced2e857bf3b8cc2a289a7a6f7425634e5
Author: Wang1rrr <[email protected]>
AuthorDate: Thu Oct 1 17:31:16 2026 +0800
fix(message): preserve unknown queue metadata in query history (#5143)
* fix(message): preserve unknown queue metadata in query history
* fix(web): align saved message queue metadata with nullable API values
---
.../instance/message/QueryHistoryService.java | 4 +-
.../instance/message/QueryHistoryServiceTest.java | 47 ++++++++++++++++++++++
web/src/api/messageHistory.test.ts | 30 ++++++++++++++
web/src/api/messageHistory.ts | 4 +-
4 files changed, 81 insertions(+), 4 deletions(-)
diff --git
a/server/src/main/java/org/apache/rocketmq/studio/instance/message/QueryHistoryService.java
b/server/src/main/java/org/apache/rocketmq/studio/instance/message/QueryHistoryService.java
index 98055144c..b7c18fa7c 100644
---
a/server/src/main/java/org/apache/rocketmq/studio/instance/message/QueryHistoryService.java
+++
b/server/src/main/java/org/apache/rocketmq/studio/instance/message/QueryHistoryService.java
@@ -114,8 +114,8 @@ public class QueryHistoryService {
m.put("tag", r.getTag() == null ? "" : r.getTag());
m.put("key", r.getKey() == null ? "" : r.getKey());
m.put("brokerName", r.getBrokerName() == null ? "" :
r.getBrokerName());
- m.put("queueId", r.getQueueId() == null ? 0 : r.getQueueId());
- m.put("queueOffset", r.getQueueOffset() == null ? 0L :
r.getQueueOffset());
+ m.put("queueId", r.getQueueId());
+ m.put("queueOffset", r.getQueueOffset());
m.put("storeTime", r.getStoreTime());
m.put("bornHost", r.getBornHost() == null ? "" :
r.getBornHost());
m.put("storeHost", r.getStoreHost() == null ? "" :
r.getStoreHost());
diff --git
a/server/src/test/java/org/apache/rocketmq/studio/instance/message/QueryHistoryServiceTest.java
b/server/src/test/java/org/apache/rocketmq/studio/instance/message/QueryHistoryServiceTest.java
index 3d52d789d..9213fda28 100644
---
a/server/src/test/java/org/apache/rocketmq/studio/instance/message/QueryHistoryServiceTest.java
+++
b/server/src/test/java/org/apache/rocketmq/studio/instance/message/QueryHistoryServiceTest.java
@@ -36,6 +36,7 @@ import java.time.Instant;
import java.time.LocalDateTime;
import java.time.ZoneOffset;
import java.util.List;
+import java.util.Map;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatThrownBy;
@@ -244,6 +245,50 @@ class QueryHistoryServiceTest {
assertThat(queryCaptor.getValue().getCustomSqlSegment()).contains("queried_by");
}
+ @Test
+ void savedMessageSnapshotsPreserveNullableQueueMetadataTest() {
+ AuthenticatedUserContext.setUsername("alice");
+ List<MessageRecordVO> messages = List.of(
+
MessageRecordVO.builder().msgId("cloud-message").topic("orders").build(),
+
MessageRecordVO.builder().msgId("first-message").topic("orders")
+ .queueId(0).queueOffset(0L).build(),
+
MessageRecordVO.builder().msgId("later-message").topic("orders")
+ .queueId(7).queueOffset(12345678901L).build());
+ RmqMessageQuery entity = new RmqMessageQuery();
+ entity.setId(9L);
+ entity.setQueriedBy("alice");
+ entity.setResultSnapshot(service.buildResultSnapshot(messages));
+ when(messageQueryMapper.selectOne(any())).thenReturn(entity);
+
+ List<MessageRecordVO> restored = service.getMessageQueryResults(9L);
+
+ assertThat(restored).hasSize(messages.size());
+ for (int index = 0; index < messages.size(); index++) {
+ assertThat(restored.get(index).getQueueId())
+ .as("queue ID for %s", messages.get(index).getMsgId())
+ .isEqualTo(messages.get(index).getQueueId());
+ assertThat(restored.get(index).getQueueOffset())
+ .as("queue offset for %s", messages.get(index).getMsgId())
+ .isEqualTo(messages.get(index).getQueueOffset());
+ }
+ }
+
+ @Test
+ void savedMessageSnapshotsExcludeBodiesAndUserPropertiesTest() throws
Exception {
+ MessageRecordVO message = MessageRecordVO.builder()
+ .msgId("message-with-payload").topic("orders")
+ .body("private message body")
+ .properties(Map.of("private-property", "private value"))
+ .build();
+
+ String snapshot = service.buildResultSnapshot(List.of(message));
+
+ var savedMessage = new ObjectMapper().readTree(snapshot).get(0);
+
assertThat(savedMessage.path("msgId").asText()).isEqualTo("message-with-payload");
+ assertThat(savedMessage.has("body")).isFalse();
+ assertThat(savedMessage.has("properties")).isFalse();
+ }
+
@Test
void loadsResultSnapshotOnlyForTheAuthenticatedOperatorTest() {
AuthenticatedUserContext.setUsername("alice");
@@ -258,6 +303,8 @@ class QueryHistoryServiceTest {
assertThat(results).singleElement().satisfies(result -> {
assertThat(result.getMsgId()).isEqualTo("msg-9");
assertThat(result.getTopic()).isEqualTo("orders");
+ assertThat(result.getQueueId()).isNull();
+ assertThat(result.getQueueOffset()).isNull();
});
ArgumentCaptor<QueryWrapper<RmqMessageQuery>> queryCaptor =
ArgumentCaptor.forClass(QueryWrapper.class);
verify(messageQueryMapper).selectOne(queryCaptor.capture());
diff --git a/web/src/api/messageHistory.test.ts
b/web/src/api/messageHistory.test.ts
index 540c7b0c4..7391685a9 100644
--- a/web/src/api/messageHistory.test.ts
+++ b/web/src/api/messageHistory.test.ts
@@ -8,9 +8,11 @@ import MockAdapter from 'axios-mock-adapter';
import { afterEach, beforeEach, describe, expect, it } from 'vitest';
import client from './client';
import {
+ getMessageQueryResults,
getQueryHistorySummary,
listMessageQueryHistory,
listTraceQueryHistory,
+ type MessageResultSnapshot,
} from './messageHistory';
const mock = new MockAdapter(client);
@@ -19,6 +21,34 @@ describe('message query history API', () => {
beforeEach(() => mock.reset());
afterEach(() => mock.reset());
+ it('preserves unknown and zero queue positions in saved message results',
async () => {
+ const unknown: MessageResultSnapshot = {
+ msgId: 'cloud-message',
+ topic: 'orders',
+ tag: '',
+ key: '',
+ brokerName: '',
+ queueId: null,
+ queueOffset: null,
+ storeTime: 1,
+ bornHost: '',
+ storeHost: '',
+ size: 1,
+ };
+ const firstMessage: MessageResultSnapshot = {
+ ...unknown,
+ msgId: 'first-message',
+ queueId: 0,
+ queueOffset: 0,
+ };
+ mock.onGet('/query-history/messages/9/results').reply(200, {
+ code: 200,
+ data: [unknown, firstMessage],
+ });
+
+ await expect(getMessageQueryResults(9)).resolves.toEqual([unknown,
firstMessage]);
+ });
+
it('forwards filters and pagination for message history', async () => {
mock.onGet('/query-history/messages').reply((config) => {
expect(config.params).toEqual({
diff --git a/web/src/api/messageHistory.ts b/web/src/api/messageHistory.ts
index 2c63a1063..5bad05bfe 100644
--- a/web/src/api/messageHistory.ts
+++ b/web/src/api/messageHistory.ts
@@ -87,8 +87,8 @@ export interface MessageResultSnapshot {
tag: string;
key: string;
brokerName: string;
- queueId: number;
- queueOffset: number;
+ queueId: number | null;
+ queueOffset: number | null;
storeTime: number;
bornHost: string;
storeHost: string;