unbridled-41 opened a new pull request, #5120:
URL: https://github.com/apache/rocketmq-dashboard/pull/5120
### Issue linkage
No existing issue or open PR covers this gap. `gh search prs/issues --repo
apache/rocketmq-dashboard "executeWithAudit"` returns nothing, and a full scan
of the 211 open PR bodies and 217 open issues for `executeWithAudit` /
`SEND_MESSAGE` / `cloud send audit` finds only PRs about topic send policies
(#4847), the redelivery payload (#4737) and the DLQ resend outcome (#4592). The
open cloud-audit items #4656/#4660 are about import audit grading.
### Problem / Evidence
`MetadataService` wraps every cloud-capable mutation in `executeWithAudit`
(`MetadataService.java:866-888`), which deliberately skips Apache because the
Apache admin client records the row itself. `sendMessage` is the one write that
never used the wrapper:
```java
public SendMessageVO sendMessage(SendMessageDTO request) {
requireSendMessageRequest(request);
request.setTopic(requireName(request.getTopic(), "topicName"));
request.setInstanceId(requireWriteInstance(request.getInstanceId(),
ownershipGuard.topicResource(request.getTopic()), true));
return resolve(request.getInstanceId()).sendMessage(request); // <- no
audit
}
```
- Apache: `RocketMQAdminClientImpl.sendMessage` records `SEND_MESSAGE` for
both outcomes (`:563`, `:575`, `:578`, `:588`, resource type `MESSAGE`).
- Aliyun / Tencent: `AliyunInstanceProvider.sendMessage` (`:478-499`) and
`TencentInstanceProvider.sendMessage` (`:590-611`) contain no audit call at all.
- Sibling writes (`createTopic`, `updateTopic`, `deleteTopic`, group
create/update/delete, `resetOffset`, both import loops) all route through the
wrapper, so this is the one hole in the same mechanism.
Call path: `TopicController.sendMessage:125-129` ->
`MetadataService.sendMessage:293` -> `resolve(instanceId).sendMessage(request)`
-> cloud provider. The same method also serves the AI tool
(`MessageSendToolHandler` -> `metadataService.sendMessage`) and message
redelivery (`redeliverMessage:341`).
Observed **before** the fix — the two new tests, run against the pre-fix
revision of `MetadataService` (the constants and tests kept in place):
```text
Wanted but not invoked:
operationAuditService.record("SEND_MESSAGE", "MESSAGE", "orders",
"cloud-instance", ..., "SUCCESS", null);
Actually, there were zero interactions with this mock.
Tests run: 2, Failures: 2, Errors: 0
```
So a test message sent to a Tencent/Aliyun instance — and the same send
performed by the `rmq.message.send` AI tool or by message redelivery on a cloud
instance — left no trace in `/api/audit`, neither on success nor on failure,
while the identical action on an Apache instance is recorded twice (never: the
Apache path records once, and the wrapper skips it).
Observed **after** the fix: both tests pass; the row is written with the
same operation (`SEND_MESSAGE`), resource type (`MESSAGE`) and resource name
(the topic) the Apache path uses, `SUCCESS` on completion and `FAILED` with the
failure message otherwise.
### Root cause / Fix
The send path was never migrated to the shared audit wrapper when the cloud
providers landed. Route it through `executeWithAudit` like its siblings, which
needs the two audit-vocabulary constants (`Operation.SEND_MESSAGE`,
`ResourceType.MESSAGE`) the Apache path writes as literals.
### Priority / fix confidence
- PRIORITY = **64** — impact 26/40 (a mutating operation on a cloud instance
leaves no audit trail at all, on a console whose audit log is a first-class
feature), scope 16/20 (every cloud send, including the AI tool and cloud
redelivery), reproducibility 16/20 (deterministic unit test), maintenance value
6/20 (closes the one hole in an existing mechanism).
- FIX_CONFIDENCE = **86** — the wrapper, its Apache skip and the exact
operation/resource vocabulary already exist and are pinned by
`apacheTopicWriteOperationsShouldNotDuplicateProviderAudit`.
### Tests
| Command | Result |
|---|---|
| `mvn -o -q test -Dtest=MetadataServiceTest` | 52 tests, 0 failures |
| `mvn -o -q test
-Dtest='MetadataServiceTest,TopicControllerTest,MessageSendToolHandlerTest,MessageRedeliveryToolHandlerTest,org.apache.rocketmq.studio.audit.**'`
| 93 tests, 0 failures, 0 errors |
| `mvn -o test` (whole suite) | Tests run: 3289, Failures: 0, Errors: 17 |
| `mvn -o checkstyle:check` | clean |
The 17 whole-suite errors are the MySQL-backed integration tests that cannot
load a Spring context in this environment; the errored set is identical to the
one measured on the untouched base revision `4ee173ad`.
New tests:
`MetadataServiceTest#cloudSendShouldBeAuditedLikeTheApachePathTest` and
`#failedCloudSendShouldBeAuditedWithItsReasonTest` (both fail pre-fix as shown
above). `apacheTopicWriteOperationsShouldNotDuplicateProviderAudit` (which also
sends a message) still pins that the Apache path writes no second row.
### Risk
Cloud sends now write one audit row per attempt, including attempts made
through `redeliverMessage` (the AI `rmq.message.redeliver` tool and the message
page's redelivery action) and failures. That is the behaviour the Apache path
already has, but it does add rows to existing cloud deployments' audit feeds. A
`redeliverMessage` on a cloud instance is recorded as `SEND_MESSAGE` (its
destination topic) because no separate redelivery operation exists in this
path; if the maintainers want it distinguished, that is a follow-up rather than
part of this fix.
--
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]