unbridled-41 opened a new issue, #4966: URL: https://github.com/apache/rocketmq-dashboard/issues/4966
### Before Creating the Bug Report - [x] I have searched the [open issues](https://github.com/apache/rocketmq-dashboard/issues) of this repository and believe that this is not a duplicate. Searched for `heartbeat healthy consumer group`, `lastHeartbeat`, `online instance heartbeat`, `心跳`, `protocol tag consumer` and `客户端未上报`. The nearest are #4742 (closed: the protocol tags' *colour*, because `PROTOCOL_MAP` was keyed by values the API does not send — a different symptom, and that mapping is already fixed) and #4763 (open: test fixtures that use values the backend never sends). - [x] This is a defect in RocketMQ Studio, not a usage question and not a defect in another Apache RocketMQ repository. - [x] I can reproduce this on the current `master` branch, or I have stated the exact version I am running below. ### Studio Version branch: `rocketmq-studio` git commit id: `1ef5d860` (the revision this was written against; the fix is in PR #4951, branched from that commit) deployed as: not required for the reproduction — see Runtime Environment. ### Runtime Environment Reproduced with the frontend unit tests (`cd web && npx vitest run src/pages/instance/__tests__/ConsumerPage.test.tsx`), which need no browser and no cluster. The provider behaviour that decides the outcome is asserted by the backend test suite on the same commit. ### Connected RocketMQ Cluster An Apache RocketMQ instance reached through the standard metadata path, i.e. the deployment where `ConsumerConnections.toInstances` builds the online instances. No specific cluster version is needed: the fields are absent because the broker's `Connection` body has no such values, not because of a broker version. ### Describe the Bug The consumer group detail modal reports **心跳状态正常** ("the heartbeat is fine") from data that never arrives, and the online-instance table renders a protocol tag with no text in it. Every online instance is built by `ConsumerConnections.toInstances` (`server/src/main/java/org/apache/rocketmq/studio/provider/apache/ConsumerConnections.java:33-43`), which copies a client id and an address: ```java .map(conn -> ConsumerInstanceVO.builder() .clientId(conn.getClientId()) .address(conn.getClientAddr()) .build()) ``` `ConsumerInstanceVO` (`:33-40`) declares `protocol` and `lastHeartbeat`, so both serialise as absent, and `grep -rn "setLastHeartbeat\|setProtocol(" server/src/main/java` finds no writer for this VO (the two `protocol(...)` hits are `RocketMQClientProvider.java:331,413`, which build the clients-page VO). The broker's `Connection` carries `clientId`/`clientAddr`/`language`/`version` — there is no heartbeat timestamp to send. The page then draws two conclusions from that absence in `web/src/pages/instance/consumer.tsx`: 1. **The health card** (`:2008-2013`) has three branches: 客户端连接信息不可用, `${n} 个心跳过期`, and otherwise 心跳状态正常. The second branch can only be reached from a `STALE_HEARTBEAT` issue, and those require a non-null age: `consumerGroupDiagnostics.ts:135-138` returns `null` for a missing `lastHeartbeat`, `:324` tests `age !== null`, and `:431-432` therefore yields `maxHeartbeatAgeSeconds: null` and `staleClientCount: 0`. The third branch is the only reachable one, and it asserts a verdict the page cannot know. 2. **The protocol column** (`:1181-1184`) builds its label from the missing value — `PROTOCOL_MAP[protocol] || { labelKey: protocol, … }` gives `labelKey = null`, and `t(null)` returns the key itself (`LangContext.tsx:39`, `translations[key]?.[lang] ?? key`) — so the cell is a coloured `<Tag>` containing nothing. The client type hid it: `web/src/api/metadata.ts:115-122` declares `protocol: string` and `lastHeartbeat: string` as non-optional, so every consumer compiled as if the values were always there. ### Steps to Reproduce 1. `cd web && npx vitest run src/pages/instance/__tests__/ConsumerPage.test.tsx -t "does not call a group healthy when the API reports no client heartbeat"` on `1ef5d860`. 2. The test renders the consumer page for a group with two online instances that carry exactly what the provider sends — a client id and an address — opens 详情 and then the 健康诊断 tab. 3. The run fails on both halves: the 协议 cell has no 不可用, and the card never shows 客户端未上报心跳时间. In a running console: open any Apache instance's consumer group whose detail modal lists online instances; the 协议 cells are empty pills, the 最后心跳 column shows `-` for every row, and the health tab prints 心跳状态正常. ### What Did You Expect to See? A value that was not reported must not be presented as one. The protocol cell should show that the protocol is unknown rather than an empty tag, and the health card should say that no heartbeat time was reported instead of grading the client healthy — matching what the AI tool contract already does for the same field, where `rmq.group.detail`'s `protocol` enum includes `UNKNOWN`. ### What Did You See Instead? The protocol column renders an empty tag for every instance, and the health card asserts 心跳状态正常 for a group whose heartbeat time was never sent. ### Additional Context Code at `1ef5d860`: `ConsumerConnections.java:33-43`, `ConsumerInstanceVO.java:33-40`, `consumer.tsx:1177,1181-1184,2008-2013`, `consumerGroupDiagnostics.ts:135-138,324,431-432`, `constants/theme.ts:66-69`, `metadata.ts:115-122`. The 最后心跳 column is deliberately left as it is: `formatDateTime` renders `-` for a missing value, which is this application's marker for "no value" and does not assert one. Corresponding pull request: #4951 (`fix(consumer): stop grading a group healthy without a client heartbeat`), which renders the unavailable label in the protocol cell, adds the not-reported state to the card, and makes the two fields optional in the client type so the next consumer of either has to handle their absence. ### Are You Willing to Submit a Pull Request? - [x] Yes, I am willing to submit a pull request. -- 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]
