pilichoumao opened a new pull request, #5116:
URL: https://github.com/apache/rocketmq-dashboard/pull/5116

   ### Which Issue(s) This PR Fixes
   
   No tracking issue. Follow-up completing the LiteTopic tool domain added in 
#4771: the three read tools expose pattern state, session detail and the quota 
watermark, but the one operation the console offers on that data — extending 
the TTL of a registered Lite parent topic (`POST /api/liteTopic/extendTTL`) — 
had no tool, so an MCP/CLI operator could see a pattern approaching expiry and 
could not act on it.
   
   ### Brief Description
   
   Add `rmq.litetopic.extend_ttl` (`rmqctl litetopic extend-ttl`), an **L2 
mutation** over the existing `LiteTopicService.extendTTL` — no new endpoint, 
service, dependency or configuration.
   
   - **Standard two-phase mutation**: dry-run returns the plan + 
`confirm_token`; apply goes through `ToolMutationFilter` (token 
verification/consumption per the current trunk semantics). It is the LiteTopic 
domain's first mutation and deliberately the only one.
   - **Instance-scoped, ownership-guarded**: unlike the read tools 
(platform-level default cluster), this follows #5006 — `extendTTL(instanceId, 
…)` runs the `ResourceOwnershipGuard`, so the tool requires `instanceId` and 
inherits the guard's rejections (unregistered resource → 404, non-LITE parent → 
409) as honest apply failures, never silent successes.
   - **Drift-free preview by construction**: the plan is derived from the 
request alone — no broker state is read in `preview` — so what the caller 
confirms cannot change underneath them before apply (current pattern state is 
the read tools' job). `before` stays empty; `after` carries `{topicPattern, 
newTtlMillis}`.
   - **Deterministic broker-behavior warnings**: one-minute TTL granularity and 
the 30-day cap are surfaced as plan warnings computed from the input, so the 
caller sees the rounding/clamping before confirming instead of discovering it 
after.
   - Output reports the requested value (`{topicPattern, newTtlMillis}`); the 
catalog description documents the broker-side granularity/cap.
   
   ### How Did You Test This Change?
   
   - **Unit:** `LiteTopicExtendTtlToolHandlerTest` — preview derived from the 
request without touching the service/broker (`verifyNoInteractions`), 
summary/after shape, no warnings for a whole-minute value inside the cap, 
granularity warning for an unaligned value, cap warning above 30 days (and none 
at exactly 30 days), execute delegates `(instanceId, topicPattern, 
newTtlMillis)` to the guarded service and maps the output.
   - **Contract:** PLANNED + EXECUTED samples added to 
`ToolOutputSchemaContractTest`; the yaml entry validates against 
`rmq-tools.schema.json` on every catalog load; the rmqctl generator enforces 
the instanceId convention (`make catalog-verify` clean).
   - **Build:** Java 21, `mvn -B -ntp -Dspring.profiles.active=dev clean 
package` — **3,291 tests, 0 Checkstyle violations**; the single error is 
`ResourceOwnershipGuardTest#migrationConcurrentStartupIsIdempotentTest`, which 
fails identically on pristine trunk (H2 concurrent-startup race, documented in 
#4769's thread); `go test ./...`, `gofmt`, `go vet` clean. Packaging verified 
with `-Dmaven.antrun.skip=true` because #5007's `binary-license-gate` fails 
identically on pristine trunk in this environment.
   - **End-to-end against a real local Apache RocketMQ 5.5.0 
NameServer/Broker** with this branch's jar, a Studio-registered DIRECT 
instance, and the real tool HTTP API:
     - created a real LITE parent topic through the trunk `rmq.topic.update` 
tool (`type=LITE`, which also registers resource ownership), then `extend_ttl` 
dry-run → `200 PLANNED` (empty warnings for the aligned value) → apply with the 
token → **`200 EXECUTED`**, with the provider logging `Extended LiteTopic TTL 
to 3600000ms (60 min) for parent topic LiteParentSmoke2 on 1 broker(s)`;
     - unaligned `90000ms` preview carried the one-minute-granularity warning;
     - apply without a token → `400 INVALID_ARGUMENT` (mutation gate);
     - apply on a NORMAL-type topic → honest `404 Lite parent topic not found`; 
apply before ownership registration → honest `404 Resource ownership is not 
registered yet` (guard semantics of #5006 observed end to end);
     - all temporary JVMs were shut down afterwards.
   
   Not exercised: multi-master clusters (the provider's 
read-all-masters-before-write path has its own coverage), CLOUD instances, 
ACL/TLS, and token replay/single-use semantics (tracked by #4665, which this 
tool will inherit untouched).
   
   ### CI Status
   
   The repository's Actions policy still rejects action versions referenced by 
the existing workflow, so GitHub-hosted runs end in `startup_failure` before 
any job starts (same as #4550/#4665/#4771). This PR does not change the 
workflow; all results above are local.
   
   ### Checklist
   
   - [x] One coherent change; no unrelated modifications
   - [x] Conventional commit subject; regression tests use `...Test`
   - [x] Tool schema validates; PLANNED/EXECUTED contract samples included
   - [x] No invented metadata; guard rejections surface honestly; broker 
rounding/clamping disclosed in the plan
   - [x] Architecture and formatting checks pass (0 Checkstyle violations; 
gofmt/vet clean)
   - [x] rmqctl catalog regenerated and verified; no new dependency, port or 
configuration
   
   🤖 Generated with [Claude Code](https://claude.com/claude-code)
   


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