zjncs opened a new pull request, #3310:
URL: https://github.com/apache/rocketmq-dashboard/pull/3310
## Problem
`RocketMQAdminClientImpl.resetOffset` applied consumer-group offset resets
with `admin.resetOffsetByTimestamp(cluster, topic, group, timestamp, false)` —
the non-forcing variant. On the broker (RocketMQ 5.5.0
`Broker2Client.resetOffset`, the default path while
`useServerSideResetOffset=false`) that flag has two effects the Studio UI does
not expect:
1. **Offline groups cannot be reset at all.** The non-forcing path only
pushes `RESET_CONSUMER_CLIENT_OFFSET` to consumers that are currently connected
and answers `CONSUMER_NOT_ONLINE` otherwise (`invokeBrokerToResetOffset` turns
that into an `MQClientException`), so the endpoint always fails for an offline
group — yet offline groups are the primary scenario for timestamp-based resets,
and Studio's own preview handles them fine: `examineConsumeStats` reads
persisted broker-side offsets, so the preview computes real per-queue targets
and returns `allowReset=true`, then the apply 500s with "Failed to reset
offset: Consumer not online...".
2. **Forward resets silently no-op.** Without `force` the broker caps each
pushed offset at the group's current offset (`if (isForce || timeStampOffset <
consumerOffset)`), so a timestamp ahead of the current position — which the
preview explicitly supports, showing "Skips N unconsumed message(s)" and only a
warning — is converted per queue into a reset to the *current* offset, i.e.
nothing happens.
## Fix
Route the apply through `admin.resetOffsetNew(name, topic, timestamp)` — the
same API the classic rocketmq-console uses for this operation.
`DefaultMQAdminExtImpl.resetOffsetNew` (5.5.0) forces the searched offset onto
the reset request (`resetOffsetByTimestamp(topic, group, timestamp, true)`) and
falls back to `resetOffsetByTimestampOld(group, topic, timestamp, true)` —
direct `UPDATE_CONSUMER_OFFSET` writes per queue — when the broker answers
`CONSUMER_NOT_ONLINE`, so both cases above now behave the way the preview
promises. Both call sites (instance-scoped and legacy global) use it; no
signature or controller changes.
## Verification
Base SHA: 36126024 (rocketmq-studio)
Fail-before / pass-after on the two new tests in
`RocketMQAdminClientImplTest`:
- `resetOffsetShouldApplyPreviewedTargetsAndSupportOfflineGroups` — failed
showing the actual invocation `resetOffsetByTimestamp("DefaultCluster",
"orders", "cg-orders", 1784246400000L, false)`; passes after the fix
(`resetOffsetNew` invoked, non-forcing variant never called).
- `resetOffsetWithoutInstanceShouldUseForceAndOfflineFallbackSemantics` —
same for the legacy global path.
Full run after the fix:
- `RocketMQAdminClientImplTest`: 43/43 pass (41 pre-existing + 2 new)
- whole `org.apache.rocketmq.studio.provider.apache` package: 256/256 pass
Broker-side semantics quoted from the `rocketmq-all-5.5.0` sources of
`AdminBrokerProcessor.resetOffset`, `Broker2Client.resetOffset`,
`MQClientAPIImpl.invokeBrokerToResetOffset` and
`DefaultMQAdminExtImpl.resetOffsetNew`.
**AI disclosure:** This change was prepared with AI assistance (GitHub
Copilot/Claude-style tooling guided by a human contributor).
--
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]