[ISSUE #10446] Support batch deletion of topics and subscription groups in broker#10448
Conversation
There was a problem hiding this comment.
Pull request overview
Note
Copilot was unable to run its full agentic suite in this review.
Adds broker/admin support for batch deletion of topics and subscription groups via new remoting request codes and request bodies, plus client APIs and broker-side handling.
Changes:
- Introduce new request bodies and request codes for batch-delete operations.
- Implement broker processor logic to delete topic/group lists (including dedup + optional cleanup behaviors).
- Add persistence helpers for batch config deletion and tests covering the new admin paths.
Reviewed changes
Copilot reviewed 8 out of 8 changed files in this pull request and generated 5 comments.
Show a summary per file
| File | Description |
|---|---|
| remoting/src/main/java/org/apache/rocketmq/remoting/protocol/body/DeleteTopicListRequestBody.java | Adds request body for batch topic deletion. |
| remoting/src/main/java/org/apache/rocketmq/remoting/protocol/body/DeleteSubscriptionGroupListRequestBody.java | Adds request body for batch subscription-group deletion (with cleanOffset flag). |
| remoting/src/main/java/org/apache/rocketmq/remoting/protocol/RequestCode.java | Adds new request codes for batch delete operations. |
| client/src/main/java/org/apache/rocketmq/client/impl/MQClientAPIImpl.java | Adds client APIs to invoke the new batch delete broker requests. |
| broker/src/test/java/org/apache/rocketmq/broker/processor/AdminBrokerProcessorTest.java | Adds unit tests for batch deletion request handling and persistence behavior. |
| broker/src/main/java/org/apache/rocketmq/broker/topic/TopicConfigManager.java | Adds batch topic-config deletion with single persist/update. |
| broker/src/main/java/org/apache/rocketmq/broker/subscription/SubscriptionGroupManager.java | Adds batch subscription-group deletion with single persist/update. |
| broker/src/main/java/org/apache/rocketmq/broker/processor/AdminBrokerProcessor.java | Routes new request codes and implements batch delete handlers; refactors pop retry topic collection. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
oss-sentinel-ai
left a comment
There was a problem hiding this comment.
Review by github-manager-bot
Summary
This PR addresses two related performance issues in AdminBrokerProcessor:
- Removes
synchronizedfromdeleteTopicsincetopicConfigTableis already aConcurrentHashMap - Adds batch deletion APIs (
DELETE_TOPIC_IN_BROKER_LISTandDELETE_SUBSCRIPTIONGROUP_LIST) to reduce network round-trips
Findings
- [Good] AdminBrokerProcessor.java:769 — Removed
synchronizedfromdeleteTopic. The underlyingtopicConfigTableis aConcurrentHashMap, so per-keyremoveis atomic. This eliminates unnecessary serialization of concurrent admin delete requests. - [Good] AdminBrokerProcessor.java — Added
deleteTopicList()anddeleteSubscriptionGroupList()handlers following the existing*_LISTconvention (consistent withUPDATE_AND_CREATE_TOPIC_LIST). - [Good] DeleteTopicListRequestBody.java / DeleteSubscriptionGroupListRequestBody.java — Clean request body classes extending
RemotingSerializable, following existing patterns. - [Good] MQClientAPIImpl.java:2202-2220 / 2281-2301 — Client-side batch deletion methods properly implemented with timeout handling.
- [Good] RequestCode.java — Added
DELETE_TOPIC_IN_BROKER_LISTandDELETE_SUBSCRIPTIONGROUP_LISTrequest codes. - [Good] TopicConfigManager.java / SubscriptionGroupManager.java — Added
deleteTopicList()anddeleteSubscriptionGroupList()batch methods. - [Good] AdminBrokerProcessorTest.java — Comprehensive test coverage including:
- Empty list validation (returns INVALID_PARAMETER)
- System topic rejection in batch
- Happy path with multiple topics
- Duplicate handling in batch
- Batch persist verification
Analysis
The implementation is well-structured:
- Backward compatibility: Existing single-item deletion APIs remain unchanged
- Consistent patterns: Follows the
*_LISTconvention established byCreateTopicListRequestBody - Proper validation: Empty lists and system topics are rejected
- Test coverage: Edge cases are well covered
Suggestions
- Consider adding a maximum batch size limit to prevent excessive memory usage or long-running operations.
- The batch persist test verifies deduplication — good attention to edge cases.
Verdict
✅ Approved — Well-designed performance optimization with proper validation and comprehensive test coverage.
Automated review by github-manager-bot
b3e851d to
75ae0ef
Compare
75ae0ef to
53cda76
Compare
2ac8039 to
9afd46f
Compare
Codecov Report❌ Patch coverage is Additional details and impacted files@@ Coverage Diff @@
## develop #10448 +/- ##
=============================================
- Coverage 48.26% 48.21% -0.05%
- Complexity 13427 13445 +18
=============================================
Files 1378 1380 +2
Lines 100822 100987 +165
Branches 13036 13069 +33
=============================================
+ Hits 48658 48692 +34
- Misses 46217 46318 +101
- Partials 5947 5977 +30 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
RockteMQ-AI
left a comment
There was a problem hiding this comment.
Review by github-manager-bot
Summary
Adds batch deletion APIs for topics (DELETE_TOPIC_IN_BROKER_LIST) and subscription groups (DELETE_SUBSCRIPTIONGROUP_LIST), with proper per-resource authorization, input validation, and atomic-all-or-nothing semantics.
Findings
- [Info] Authorization — Correctly emits one
DELETEcontext per resource in the batch, preventing bypass when the body carries the target list instead of the header. This is a security-critical detail handled well. - [Info] Error handling — Returns a structured error response with the list of failed items and the first exception. Good for debugging partial failures.
- [Info] Dedup — Uses
LinkedHashSetto preserve insertion order while deduplicating. Reasonable choice. - [Info] Refactoring — Extracts
collectPopRetryTopics()from inline code indeleteTopic(). Good cleanup that avoids duplication. - [Info] Cleanup order — Deletes client config and subscription first, then topic config last. Allows retry after partial failure.
- [Warning]
AdminBrokerProcessor.deleteTopicInBrokerList()— TheRemotingCommand responseis created once at the top and reused. IfdeleteTopicInBrokerinternally sets response fields, ensure there's no state leakage between the success and error paths. - [Warning]
MQClientAPIImpl.deleteTopicInBrokerList()— The method creates the request body and sends it. Consider adding a timeout or batch size limit to prevent excessively large requests.
Suggestions
- Consider adding a max batch size constant (e.g., 100) to prevent abuse or accidental large requests.
- The
DeleteTopicListRequestBodyandDeleteSubscriptionGroupListRequestBodyclasses are clean. Consider adding@AllArgsConstructorfor convenience if not already present. - Cross-repo: If batch deletion is exposed in the dashboard or CLI, ensure those clients are updated to use the new APIs.
Overall: Well-structured feature with proper authorization and error handling. A few minor suggestions but nothing blocking.
Automated review by github-manager-bot
9afd46f to
267bec0
Compare
RockteMQ-AI
left a comment
There was a problem hiding this comment.
Review by github-manager-bot
Summary
Adds two new batch admin APIs — DELETE_TOPIC_IN_BROKER_LIST and DELETE_SUBSCRIPTIONGROUP_LIST — to AdminBrokerProcessor, following the existing *_LIST convention (e.g. UPDATE_AND_CREATE_TOPIC_LIST). Includes proper authorization context building for body-driven batch requests, new request body DTOs, and test coverage.
Findings
- [Info] Authorization handling for body-driven batch APIs is correctly implemented — the
DefaultAuthorizationContextBuilderdecodes the request body and emits oneDELETEcontext per item, preventing the annotation-based path from producing an empty context list (which would bypass permission checks). - [Info] Good test coverage in
DefaultAuthorizationContextBuilderTest— verifies blank entries are filtered, correct resource types, and per-item DELETE action. - [Warning] The batch deletion is not atomic — if one topic/group fails to delete (e.g. still in use), the remaining items in the list may still be deleted. Consider documenting this partial-failure behavior in the API response, or adding a
failFastflag. - [Info]
LinkedHashSetfor deduplication while preserving insertion order is a good choice for predictable behavior. - [Info] New
DeleteTopicListRequestBodyandDeleteSubscriptionGroupListRequestBodyfollow the existing pattern ofCreateTopicListRequestBody.
Suggestions
- Consider adding a response summary that reports per-item success/failure status (similar to how batch operations in other systems report partial results). This would help callers understand which items succeeded when partial failure occurs.
- Add a brief comment in
AdminBrokerProcessordocumenting the non-atomic semantics of batch deletion.
No blocking issues. Well-structured addition that follows existing conventions.
Automated review by github-manager-bot
Server Benchmark Results (2026-06-22)Environment: 8C30G broker, Dragonwell JDK 21, 1KB msg, 128 queues, sync mode, 256 threads, 20s warmup + 30s collect Producer-only (steady state, lines 3-5)
This is a feature PR (batch delete Topic/SubscriptionGroup), not a performance optimization. Benchmark confirms no regression. |
|
For That keeps the batch API aligned with the current single-delete semantics and avoids a large batch request creating a sudden cleanup burst on the broker. It would also be good to add a regression test covering the throttled batch path and invalid-entry handling before the loop starts. |
267bec0 to
4f0ab43
Compare
Review by github-manager-bot (Re-review after new commit
|
RockteMQ-AI
left a comment
There was a problem hiding this comment.
Review by github-manager-bot
Summary
Updated review for the latest push (4f0ab43). This PR adds batch deletion APIs (DELETE_TOPIC_IN_BROKER_LIST, DELETE_SUBSCRIPTIONGROUP_LIST) to AdminBrokerProcessor, following the existing *_LIST convention. Includes per-resource authorization context building, new request body DTOs, client helpers, and test coverage.
What Changed Since Last Review
- Single commit (4f0ab43) rebased/updated on 2026-06-24.
- A new reviewer suggestion from @fuyou001 proposes reusing the single-topic delete path with a
RateLimiterinstead of a separate batch cleanup sequence.
Findings
- [Info] Authorization —
DefaultAuthorizationContextBuildercorrectly decodes the request body and emits oneDELETEcontext per resource. This prevents the annotation-based path from producing an empty context list (which would bypass permission checks). Well handled. - [Info] Dedup + ordering —
LinkedHashSetpreserves insertion order while deduplicating inputs. Good choice for predictable behavior. - [Info] Refactoring —
collectPopRetryTopics(...)is extracted from inline code indeleteTopic(), now shared by both single and batch paths. Reduces duplication. - [Info] Batch persist —
TopicConfigManager.deleteTopicConfigList()andSubscriptionGroupManager.deleteSubscriptionGroupConfigList()aggregatepersist()once per batch instead of N times. Significant efficiency gain for large batches. - [Info] Error reporting — Returns structured error with the list of failed items and the first exception. Good for debugging partial failures.
- [Warning] No batch size limit — Neither
deleteTopicListnordeleteSubscriptionGroupListcaps the input list size. A caller could send thousands of items in a single RPC, causing a long-running synchronized block and a largemessageStore.deleteTopics(...)call. Consider adding a max batch size constant (e.g., 100 or 200) and returningREQUEST_CODE_NOT_SUPPORTEDor a validation error when exceeded. - [Warning] Rate limiting concern (raised by @fuyou001) — The current batch path does a burst of all deletes in one shot. If the reviewer suggestion is adopted (iterate +
RateLimiter), it would smooth out the cleanup burst. If not adopted, at minimum document why a burst is acceptable for the expected use cases (tenant decommissioning, retention purge). - [Warning]
synchronizedscope — BothdeleteTopicListanddeleteSubscriptionGroupListaresynchronized, consistent with existing single-item methods. However, the batch path holds the lock for the entire batch duration. For large batches this could block other admin operations. This is acknowledged as out-of-scope (#9997/#9998) but worth noting for reviewers. - [Info] Client null-check —
MQClientAPIImpl.deleteTopicInBrokerList()anddeleteSubscriptionGroupList()use explicit null checks on the response (instead ofassert), producing a deterministicMQClientException(SYSTEM_ERROR, ...). Good defensive coding. - [Info] Backward compatibility — New
*_LISTrequest codes are additive; older brokers will returnREQUEST_CODE_NOT_SUPPORTEDviagetUnknownCmdResponse. No breaking changes.
Suggestions
- Add a max batch size guard — e.g.,
if (topicList.size() > MAX_BATCH_SIZE) { return error response; }. This is a low-cost safety measure. - Address @fuyou001 feedback — Either adopt the RateLimiter approach or explain why the current burst behavior is acceptable for the target use cases.
- Consider adding a timeout parameter — The client methods accept
timeoutMillisbut the broker-side processing has no internal timeout. For very large batches, the broker could log a warning if processing exceeds a threshold.
Overall: Solid implementation with proper authorization, error handling, and test coverage. The main concern is the lack of batch size limits and the reviewer suggestion about rate limiting. Nothing blocking, but worth addressing before merge.
Automated review by github-manager-bot
4f0ab43 to
930d6e6
Compare
|
@fuyou001 Thanks for the suggestion!
We ran a broker-side A/B experiment comparing both approaches with the same batch RPC (only the broker JAR differs):
Server benchmark results (50 topics/groups, Producer+Consumer running at ~180k TPS):
The key bottleneck is Both variants have zero impact on concurrent Producer/Consumer TPS and P99 RT because the delete operation completes in under 1 second either way. The difference is in the delete operation latency itself — important for admin tools that wait for the response. Regarding code reuse concern: The batch path only diverges at the Would appreciate your feedback! |
RockteMQ-AI
left a comment
There was a problem hiding this comment.
Review by github-manager-bot (Re-review)
Summary
Re-review after rebase. PR adds batch deletion APIs (DELETE_TOPIC_IN_BROKER_LIST, DELETE_SUBSCRIPTIONGROUP_LIST) following the existing *_LIST convention. The rebase preserves the previous design: body-driven batch requests, per-item authorization contexts, single-persist batching, and structured partial-failure responses.
Findings
- [Info] Authorization — Body-driven batch APIs correctly emit one
DELETEcontext per resource inDefaultAuthorizationContextBuilder, preventing the annotation-based path from producing an empty context list. Verified for both topic and subscription group batch codes. - [Info] Batch persist —
TopicConfigManager#deleteTopicConfigListandSubscriptionGroupManager#deleteSubscriptionGroupConfigListaggregate into a singlepersist()call per batch, avoiding N writes. Good. - [Info] Dedup —
LinkedHashSetpreserves insertion order while deduplicating input. Consistent with existing*_LISTpatterns. - [Info] Refactoring —
collectPopRetryTopics()extraction is clean and shared between single and batch delete paths, reducing duplication. - [Info] Client null-check —
MQClientAPIImplmethods use explicitresponse == nullcheck (instead ofassert) and throwMQClientException(SYSTEM_ERROR, ...). Deterministic behavior. - [Info] Request codes —
5002/5003are additive; older brokers returngetUnknownCmdResponsefor unknown codes. No backward compatibility risk. - [Warning]
AdminBrokerProcessor#deleteTopicList— TheRemotingCommand responseis created once at the top. On the success path,response.setCode(ResponseCode.SUCCESS)andresponse.setRemark(null)are set explicitly. On the error path, aDeleteTopicListResponseBodyis serialized into the response body. This is correct, but verify that no intermediate code path mutatesresponsefields between the two branches (e.g., a logging interceptor that callsresponse.setRemark()). - [Warning] No max batch size — Neither the server-side handler nor the client method enforces a maximum batch size. A caller could send thousands of topics in a single RPC, causing a long
synchronizedhold on the broker. Consider adding a server-side guard (e.g., reject iftopicList.size() > 1000) to prevent accidental or malicious abuse.
Suggestions
- Consider adding a
MAX_BATCH_SIZEconstant (e.g., 1000) and rejecting oversized requests early indeleteTopicList()/deleteSubscriptionGroupList()with a clear error message. - The
DeleteSubscriptionGroupListRequestBodyhas a 2-arg constructor(groupNameList, cleanOffset)and a 1-arg constructor(groupNameList). The 1-arg constructor could delegate to the 2-arg one (this(groupNameList, false)) to reduce duplication.
Verdict
Rebase looks clean — previous findings still hold. No new issues introduced. The two warnings above are non-blocking suggestions for future hardening.
Automated review by github-manager-bot
42a2df2 to
780abc8
Compare
RockteMQ-AI
left a comment
There was a problem hiding this comment.
Review by github-manager-bot (Re-review)
Summary
Re-review after new commit (2026-06-26). The new commit adds rate limiting to deleteTopicList via a configurable batchDeleteTopicMaxRate in BrokerConfig, addressing the previous "no max batch size" warning.
Findings
- [Info] Rate limiting added —
BrokerConfig#batchDeleteTopicMaxRate(default 10.0) + GuavaRateLimiterindeleteTopicList(). This throttles per-topic deletion speed, partially addressing the previous batch-size concern. Good improvement. - [Warning] Rate limiter only in
deleteTopicList, not indeleteSubscriptionGroupList— The subscription group batch delete has no equivalent rate limiting. If the goal is to prevent longsynchronizedholds, both methods should be consistent. Consider adding the same pattern todeleteSubscriptionGroupList. - [Warning] Rate limiter inside
synchronizedmethod —deleteTopicList()issynchronized. With rate limiting at 10/s, a batch of 1000 topics would hold the lock for ~100 seconds. This could block other admin operations. Consider:- Moving rate-limited work outside the
synchronizedblock (e.g., validate + prepare under lock, then rate-limited delete outside), or - Adding a max batch size guard (e.g., reject if
topicList.size() > 1000) in addition to rate limiting.
- Moving rate-limited work outside the
- [Info]
LiteMetadataUtil.isLiteMessageType()andgetLiteLifecycleManager().cleanByParentTopic()are called inside the rate-limited loop. Verify these are lightweight operations; if they involve RPC or heavy I/O, the rate limiter may not be sufficient to prevent long holds. - [Info] Previous findings (authorization, batch persist, dedup, refactoring, client null-check, request codes) remain valid and unchanged.
Suggestions
- Add the same rate limiting pattern to
deleteSubscriptionGroupListfor consistency. - Consider adding a
MAX_BATCH_SIZEconstant as a hard upper bound, with rate limiting as a secondary throttle. - Document
batchDeleteTopicMaxRatein the config description (e.g., "Max topics deleted per second in batch delete API. 0 means no limit.").
Verdict
New rate limiting is a positive step. The two warnings above (inconsistency with subscription group path, synchronized + rate limiter interaction) are non-blocking but worth addressing before merge.
Automated review by github-manager-bot
780abc8 to
a258b0e
Compare
RockteMQ-AI
left a comment
There was a problem hiding this comment.
Review by github-manager-bot (Re-review #2)
Summary
Re-review after new commit a258b0e (2026-06-26). This PR adds batch deletion APIs (DELETE_TOPIC_IN_BROKER_LIST, DELETE_SUBSCRIPTIONGROUP_LIST) to AdminBrokerProcessor, along with auth context integration, rate limiting, and client helpers.
Findings
-
[Critical]
AdminBrokerProcessor.java—deleteTopicList()does not callmessageStore.deleteTopics(topicsToClean). The single-itemdeleteTopic()callsthis.brokerController.getMessageStore().deleteTopics(topicsToClean)to clean CommitLog/ConsumeQueue data, but the batch path only callsdeleteTopicInBroker(topic)per topic (which deletes config + queue mapping, not message store data). This will orphan message store data on disk. The batch path must include themessageStore.deleteTopics()call before or after the per-topic loop. -
[Warning]
TopicConfigManager.java:629/SubscriptionGroupManager.java:399—deleteTopicConfigList()anddeleteSubscriptionGroupConfigList()are defined but never called anywhere in this PR.deleteTopicList()callsdeleteTopicInBroker()→deleteTopicConfig()one-by-one. Either these batch methods should be used (to aggregatepersist()as the PR description claims), or they should be removed to avoid dead code. -
[Warning]
AdminBrokerProcessor.java— The PR description states "aggregatepersist()once per batch" and "one-shot persist", but the current implementation callsdeleteTopicInBroker(topic)per topic, which internally callsdeleteTopicConfig(topic)— each of which likely triggers its ownpersist(). If batch persist is a goal, thedeleteTopicConfigList()method should override the loop to persist once at the end, anddeleteTopicList()should call it. -
[Info]
DefaultAuthorizationContextBuilder.java:324-362— Auth context integration looks correct. Body-driven batch requests properly emit oneDELETEcontext per topic/group, with blank entries filtered. Good that the annotation-based path gap was identified and handled explicitly. -
[Info]
AdminBrokerProcessor.java:815-820—collectPopRetryTopics()refactoring is clean and correctly shared between single and batch paths. Thenew ArrayList<>(topicsToClean)snapshot before mutating the set in the batch path is a good defensive copy. -
[Info]
BrokerConfig.java:382—batchDeleteTopicMaxRatedefault of10.0permits/sec is conservative and sensible. ThemaxRate > 0guard to disable the rate limiter is clean. -
[Info]
RequestCode.java:314-315— Codes5002/5003are sequential afterSWITCH_TIMER_ENGINE = 5001. No conflicts detected.
Suggestions
- Must fix: Add
messageStore.deleteTopics()call indeleteTopicList(). Suggested placement — before the per-topicdeleteTopicInBrokerloop, matching the single-item flow:
// After collecting topicsToClean (including pop retry topics):
try {
if (this.brokerController.getMessageStore() != null) {
this.brokerController.getMessageStore().deleteTopics(topicsToClean);
}
} catch (Throwable t) {
return buildErrorResponse(ResponseCode.SYSTEM_ERROR, t.getMessage());
}
// Then the existing rate-limited deleteTopicInBroker loop-
Should fix: Either wire
deleteTopicConfigList()/deleteSubscriptionGroupConfigList()into the batch path (with single-persist optimization), or remove them. -
Nit:
deleteSubscriptionGroupList()reusesbatchDeleteTopicMaxRatefor group deletion rate limiting. Consider renaming tobatchDeleteMaxRatefor clarity, or adding a separate config for group deletion.
Automated review by github-manager-bot
77e76c4 to
3c0cd1b
Compare
…n groups in broker - Add DELETE_TOPIC_IN_BROKER_LIST and DELETE_SUBSCRIPTIONGROUP_LIST request codes with corresponding RequestBody types - Implement deleteTopicList / deleteSubscriptionGroupList in AdminBrokerProcessor with deduplication and one-shot persist - Add deleteTopicConfigList / deleteSubscriptionGroupConfigList in TopicConfigManager / SubscriptionGroupManager (single persist per batch) - Add MQClientAPIImpl#deleteTopicInBrokerList / deleteSubscriptionGroupList client APIs - Cover changes with unit tests in AdminBrokerProcessorTest
3c0cd1b to
1038b33
Compare
RockteMQ-AI
left a comment
There was a problem hiding this comment.
Review by github-manager-bot (Re-review #3)
Summary
Re-review after new commit 1038b335 (2026-06-26). This PR adds batch deletion APIs (DELETE_TOPIC_IN_BROKER_LIST, DELETE_SUBSCRIPTIONGROUP_LIST) to AdminBrokerProcessor, with auth context integration, rate limiting, and client helpers.
Changes Since Last Review
The latest commit appears to be a rebase/squash. The overall structure remains the same as the previous review.
Findings
-
[Critical]
AdminBrokerProcessor.java—deleteTopicList()does not callthis.messageStore.deleteTopics(topicsToClean). The single-itemdeleteTopic()calls it after the per-topic loop to clean up actual message data in the store. Without this call, batch topic deletion removes broker-side metadata (topic config, queue mapping, etc.) but leaves orphaned message data on disk. This is the same issue flagged in the previous two reviews and remains unresolved.Suggested fix — add the store cleanup after the loop in
deleteTopicList():for (String topic : topicsToClean) { if (rateLimiter != null) { rateLimiter.acquire(); } if (LiteMetadataUtil.isLiteMessageType(topic, brokerController)) { brokerController.getLiteLifecycleManager().cleanByParentTopic(topic); } deleteTopicInBroker(topic); } // ── add this ── this.messageStore.deleteTopics(topicsToClean);
-
[Warning]
AdminBrokerProcessor.java:deleteTopicList()— The method issynchronized, same asdeleteTopic(). For a batch operation that may delete many topics with rate-limiting delays, holding the broker-wide lock for the entire duration could block other admin operations. Consider whether the critical section can be narrowed (e.g., validate first under the lock, then delete outside it). -
[Info]
SubscriptionGroupManager.deleteSubscriptionGroupConfigList()andTopicConfigManager.deleteTopicConfigList()— These new batch methods simply loop over the single-item methods. They are not currently called bydeleteTopicList()/deleteSubscriptionGroupList()(which call the single-item methods directly viadeleteTopicInBroker()/deleteSubscriptionGroupInBroker()). If these batch methods are not used elsewhere, consider removing them to avoid dead code. If they are intended for future use, a brief Javadoc explaining the intended caller would help. -
[Info]
RequestCode.java— New codes5002/5003are registered. No conflicts detected with existing codes. Good.
What Looks Good
- Clean extraction of
collectPopRetryTopics()from the single-item path — reduces duplication. deleteSubscriptionGroupInBroker()correctly checksisLiteGroupTypebefore deleting the group config (avoids auto-recreation whenautoCreateSubscriptionGroup=true).- Auth context builder correctly emits per-resource DELETE actions for the batch request codes.
- Rate limiting via Guava
RateLimiterwith configurable max rate is a good safety measure. - Comprehensive test coverage: empty/blank/system-topic validation, dedup, rate limiting, pop-retry-topic collection.
Automated review by github-manager-bot
Which Issue(s) This PR Fixes
Fixes #10446
Brief Description
Adds two new batch admin APIs to
AdminBrokerProcessorwhose names follow the existing*_LISTconvention (e.g.UPDATE_AND_CREATE_TOPIC_LIST,UPDATE_AND_CREATE_SUBSCRIPTIONGROUP_LIST):DELETE_TOPIC_IN_BROKER_LISTDELETE_SUBSCRIPTIONGROUP_LISTBulk metadata cleanup (e.g. tenant decommissioning, retention purge, cluster migration) currently requires N round-trips to delete N items and triggers N
persist()calls on the broker config files. These new APIs allow doing the same in 1 RPC + 1 persist + 1messageStore.deleteTopics(Set)call.Changes
RequestCode: addDELETE_TOPIC_IN_BROKER_LISTandDELETE_SUBSCRIPTIONGROUP_LIST.DeleteTopicListRequestBody { List<String> topicList }DeleteSubscriptionGroupListRequestBody { List<String> groupNameList; boolean cleanOffset }TopicConfigManager#deleteTopicConfigList(List<String>)andSubscriptionGroupManager#deleteSubscriptionGroupConfigList(List<String>): aggregatepersist()once per batch.AdminBrokerProcessor:collectPopRetryTopics(...)shared helper used by both single and batch paths.deleteTopicList(...)anddeleteSubscriptionGroupList(...)(bothsynchronized, consistent with existing single APIs) with input dedup (preserving order), system-topic / blank validation, one-shot persist, and one-shotmessageStore.deleteTopics(...)call.MQClientAPIImpl: adddeleteTopicInBrokerList(...)anddeleteSubscriptionGroupList(...)client helpers; both use an explicit null check (instead ofassert) so callers get a deterministicMQClientException(SYSTEM_ERROR, ...)wheninvokeSyncreturns null.Compatibility
DELETE_TOPIC_IN_BROKER/DELETE_SUBSCRIPTIONGROUPrequest codes and methods are unchanged; existing clients are not affected.*_LISTrequest codes are additive; older brokers will fall through togetUnknownCmdResponse, so older clients/brokers continue to work as today.How Did You Test This Change?
New unit tests added in
AdminBrokerProcessorTest:testDeleteTopicListInBroker— covers empty input, system-topic rejection, and the success path.testDeleteTopicListBatchPersist— verifies that:deleteTopicConfigListis invoked once (sopersist()runs once for the whole batch),deleteTopicConfigis not called on the batch path,messageStore.deleteTopics(...)is invoked once with the batched set,testDeleteSubscriptionGroupList— covers empty input and the success path withcleanOffset=true.Local verification: