unbridled-41 opened a new pull request, #4560:
URL: https://github.com/apache/rocketmq-dashboard/pull/4560
Fixes #4556.
## Problem / Evidence
Nine of the forty catalog tools are platform-level: addressed by a physical
`clusterName`, exempt from the mandatory `instanceId`
(`ToolCatalog.INSTANCE_ID_EXEMPT_TOOLS`), with input schemas that reject
`instanceId` (`additionalProperties: false`) — yet every one declares non-empty
`requiredCapabilities`. `ToolExecutionService.resolveTargetInstance` dispatches
them with a **null** context instanceId by design, and `ToolCapabilityFilter`
then calls `CapabilityResolver.resolve(null)` → `CAPABILITY_INSTANCE_REQUIRED`.
Every call fails on every transport (REST `POST /api/ai/tools/{name}/execute`
and MCP `tools/call`), while `ToolDiscoveryService` and `McpToolRegistrar`
advertise the tools. Affected: `rmq.cluster.list`, `rmq.dashboard.summary`,
`rmq.broker.list/describe/config`, `rmq.nameserver.list/config`,
`rmq.proxy.list/config`.
Reproduction (red test output): `ToolExecutionException: Capability lookup
requires a bound Instance` from a platform tool dispatched with `{}` input
through the full filter chain.
## Root cause / Fix
`ToolCapabilityFilter` assumed every capability-gated tool is
instance-scoped. The filter now proceeds when `context.instanceId()` is null
**and** the tool is instanceId-exempt (the exact combination
`resolveTargetInstance` produces for platform tools). Instance-scoped tools
keep the lookup unchanged; a null instanceId on a non-exempt tool remains
impossible (`TOOL_INSTANCE_REQUIRED` fires earlier).
## Priority & scoring
PRIORITY 82 = impact 32 (9 of 40 advertised tools dead, including the whole
platform-inspection surface) + reach 14 (AI page, rmqctl, MCP clients) + repro
20 (deterministic) + maintain 16 (unblocks #4306's flagship surface;
discovery/execution contract inconsistency). FIX_CONFIDENCE 90 (two-line guard
+ full-chain regression test).
## Tests
- New
`ToolPlatformCapabilityTest.platformToolWithoutInstanceExecutesThroughTheCapabilityFilterTest`
runs `rmq.cluster.list` through the real `ToolFilterChain` (AUDIT → VALIDATION
→ CAPABILITY → execution) with a null instanceId.
- Red (baseline): `Tests run: 1, Failures: 0, Errors: 1` —
`ToolExecutionException: Capability lookup requires a bound Instance`.
- Green: `Tests run: 1, Failures: 0, Errors: 0`.
- Related suites green after the change: ClusterListToolHandlerTest 2/2,
ToolCatalogTest 5/5, ToolInstanceRoutingTest 4/4, ToolGatewayServiceTest (12
total across the batch run, 0 failures).
- Full backend suite (`SPRING_PROFILES_ACTIVE=dev mvn clean test`): **2396
tests, 1 failure** — `AuthServiceSessionOverviewIntegrationTest` (a 59 s/60 s
wall-clock boundary assertion), unrelated to this change; the class passes 3/3
in isolation (re-run three times with the dev profile). Baseline for
`origin/master` under the same profile: 2395/0 (this branch adds the 1 new test
→ 2396).
## Risk
Low. The skipped capability check only applies to tools that by contract
have no instance context; per-instance gating for these tools already happens
in discovery, and their handlers resolve physical clusters themselves
(`PlatformClusterResolver`).
--
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]