unbridled-41 opened a new pull request, #5426:
URL: https://github.com/apache/rocketmq-dashboard/pull/5426

   Supersedes #4737, which was auto-closed as stale after review; the review 
follow-ups from that thread (preview/execute alignment, narrowed properties 
guard) are included here, rebased on current `rocketmq-studio`.
   
   ## Problem / Evidence
   
   The AI redelivery tool publishes the *display projection* of the source 
message as if it were the stored record, so redelivering a large or binary 
message silently stores different bytes.
   
   - `instance/topic/MetadataService.java` `redeliverMessage` loads the source 
with `findMessageForRedelivery` — the message explorer query — and copies 
`original.getBody()` into the `SendMessageDTO`. Nothing checks the projection 
flags.
   - The projection is lossy by construction: 
`provider/apache/RocketMQMessageProvider.java:89` caps the body at 
`MAX_BODY_DISPLAY_BYTES` (64 KiB) and sets `bodyTruncated`; a non-UTF-8 body is 
replaced by Base64 text with `bodyEncoding = "BASE64"`; 
`MessagePropertyDisplay.limitProperties` caps and abbreviates the property map 
and sets `propertiesTruncated`.
   - Call path: AI tool `rmq.message.redelivery` → 
`MessageRedeliveryToolHandler.execute` → `MetadataService.redeliverMessage` → 
`sendMessage`.
   - Trigger: redeliver an existing message whose body exceeds 64 KiB, is 
binary, or whose properties were abbreviated. The published message is a 
silently rewritten copy — no error, no marker.
   
   ## Root cause / Fix
   
   The redelivery path treated a display projection as an exact record. It now 
refuses a source it cannot republish exactly with `409` and a reason:
   
   ```
   Source message body is truncated for display and cannot be redelivered 
exactly
   Source message body is binary and cannot be redelivered exactly
   Source message properties are truncated for display and cannot be 
redelivered exactly
   ```
   
   The property check is deliberately narrow: `propertiesTruncated` is computed 
over the raw map including broker system keys, but `redeliveryProperties` 
discards those keys anyway, so the guard refuses only when a visible *user* 
property value was abbreviated (`MessagePropertyDisplay` exposes the marker so 
the check cannot drift from the projection). 
`MessageRedeliveryToolHandler.preview()` runs the same guard as `execute()`, so 
the agent cannot present a plan whose publish execution would refuse.
   
   ## Priority & scoring
   
   PRIORITY 80 = 影响 32 (silent data corruption: the redelivered message is not 
the original) + 波及 12 (redelivery path + AI tool contract) + 可复现 20 
(deterministic for a >64 KiB or binary body) + 维护价值 16 (refusal is the only 
correct outcome without a raw-body read path).
   
   FIX_CONFIDENCE 80: additive guard with refusal semantics, covered by 
regressions for each lossy case and for the narrowed property rule.
   
   ## Tests
   
   ```
   cd server && mvn -o test 
-Dtest='MetadataServiceTest,MessageRedeliveryToolHandlerTest,MessagePropertyDisplayTest'
   ```
   
   - Green: `Tests run: 72, Failures: 0, Errors: 0, Skipped: 0`.
   - Red with the guard neutralised (method body short-circuited, so the tests 
still compile): `MetadataServiceTest` → `Tests run: 64, Failures: 3` — exactly 
the new refusal regressions.
   - New regressions cover: truncated body refused, Base64 body refused, 
abbreviated user property refused, a system-key-only truncated flag stays 
redeliverable, an intact user set beyond the display cap stays redeliverable, a 
legitimate `...` value without the flag is not refused, and preview refuses 
with the same guard as execute.
   - Broader sweep (`instance.topic`, `instance.message`, `ops.ai.tool`): 333 
tests, 0 failures; the single error is `QueryHistoryServiceIntegrationTest` 
failing to load its Spring context with `Communications link failure` — it 
needs the MySQL datasource CI provisions, unrelated to this change.
   - `mvn -o checkstyle:check` passes.
   
   ## Risk
   
   Low. The guard only turns a previously silent corruption into a 4xx refusal; 
sources that are stored exactly as displayed (the common case) redeliver 
unchanged.


-- 
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]

Reply via email to