Skip to content

[ISSUE #10825] feat(proxy): Implement the Proxy Admin gRPC management interface - #10826

Merged
lizhimins merged 28 commits into
apache:developfrom
zhaohai666:feat/rip2-proxy-admin
Sep 11, 2026
Merged

lizhimins merged 28 commits into
apache:developfrom
zhaohai666:feat/rip2-proxy-admin

Conversation

@zhaohai666

@zhaohai666 zhaohai666 commented Aug 6, 2026 •

Copy link
Copy Markdown
Contributor

[RIP-2] Implement Proxy Admin Standardized Management Interface on the Proxy

Target: apache/rocketmq → develop
Head: zhaohai666:feat/rip2-proxy-admin
Diff: 10 commits, 23 files, +3,469 / −60

1. Summary

This PR implements RIP-2: Proxy Admin Standardized Management Interface — the upstream Admin gRPC service (apache/rocketmq/v2/admin.proto, from apache/rocketmq-apis main, artifact org.apache.rocketmq:rocketmq-proto:2.2.0) bound by the RocketMQ Proxy on a dedicated admin gRPC server, isolated from the data-plane MessagingService, with fine-grained ACL 2.0 authorization under dedicated proxy.admin.* resources.

It closes the observability gap introduced by RocketMQ 5.0's stateless Proxy: gRPC clients attached to a Proxy are invisible to operations tooling that relies on broker-side ConsumerManager and Remoting-era admin commands. With this change the Proxy itself can answer "which SDK clients are online, what do they subscribe to, how far behind are they" through a stable, community-reviewed contract — which is exactly what RIP-1 (Control Plane 5.0 dashboard, requirement CLIENT-01) depends on.

Contract choice: upstream Admin, not a bespoke ProxyAdminService

An earlier draft of this work defined a custom ProxyAdminService on a local rocketmq-apis feature branch. That surface has been removed. The control plane now consumes the same versioned, community-reviewed admin.proto that the dashboard and the multi-language SDKs already use, so there is no forked API evolution and the implementation stays additive-compatible with upstream proto changes. The only protocol-level change in this repo is the artifact version bump (rocketmq-proto 2.1.2 → 2.2.0 in pom.xml); the rocketmq-apis repository is intentionally not vendored or submoduled here.

2. What This PR Adds

2.1 Dedicated admin gRPC server (control plane)

ProxyStartup starts a second gRPC server on its own port (adminGrpcPort, default 8083), with its own interceptor chain (metrics → auth → standard pipeline), separate from the data plane (8081).

Key design point: the admin server reuses the data plane's GrpcChannelManager / GrpcClientSettingsManager. Without that sharing, admin queries would read an always-empty, isolated channel map and ListConsumerConnection / DescribeSubscription would perpetually return nothing. GrpcMessagingApplication#getGrpcMessagingActivity(), DefaultGrpcMessagingActivity#getGrpcChannelManager(), #getGrpcClientSettingsManager(), GrpcChannelManager#getClientChannels() and DefaultMessagingProcessor#getServiceManager() are the (additive) accessors added for this purpose.

The admin port intentionally does not expose channelz or proto reflection — the control-plane attack surface is kept minimal. A global kill switch proxyAdminEnabled disables the whole surface.

2.2 ProxyAdminGrpcService — all 16 Admin RPCs on the Proxy

ProxyAdminGrpcService extends AdminGrpc.AdminImplBase and serves every RPC of the upstream Admin service. Data sources per group:

Source RPCs
Proxy-local state (GrpcChannelManager + GrpcClientSettingsManager) ListConsumerConnection, ListSubscription, DescribeSubscription, GetConsumerRunningInfo, GetProxyRuntimeStats
Client-directed telemetry commands PrintThreadStackTrace, VerifyMessage (written to the target GrpcClientChannel)
Broker-internal data, via the proxy's own AdminService remoting gateway DescribeTopicStatus, DescribeGroupAccumulation, ResetGroupOffset, QueryMessage, DeleteSubscription, QueryTimeSpan, GetTopicRoute
Proxy producer path AdminSendMessage (MessagingProcessor#sendMessage)
Proxy runtime ChangeLogLevel (relocated logback API on the root logger)

Multi-broker correctness. Several admin operations were initially single-broker and returned incomplete results on multi-broker clusters. This PR fixes that with resolveBrokerAddrs(topic) (all distinct broker addresses of the topic route, order-preserving) plus:

  • ResetGroupOffset resets on every broker hosting the topic, aggregating per-broker errors instead of failing on the first one.
  • DeleteSubscription fans out to every broker and reports partial failures.
  • QueryMessage by message key searches brokers until maxNums messages are collected (a key may live on any broker).
  • AdminModelConverter#toGroupAccumulationMultiBroker aggregates ConsumeStats across brokers, deduplicating by MessageQueue so queues are never double counted.
  • QueryTimeSpan reports the real last-consume timestamp from the offset table (falling back to minStoretime for never-consumed queues) and resolves per-queue broker addresses for the store-time lookup.

2.3 proxy.admin.* ACL 2.0 authorization

ProxyAdminAuthInterceptor maps every RPC to exactly one (resource, action) pair across five dedicated resources:

Resource RPCs Actions
proxy.admin.client ListSubscription, ListConsumerConnection (List); DescribeSubscription, DescribeGroupAccumulation, GetConsumerRunningInfo, QueryTimeSpan (Get) List / Get
proxy.admin.config ChangeLogLevel Update
proxy.admin.connection PrintThreadStackTrace, VerifyMessage Update (high privilege)
proxy.admin.route GetTopicRoute Get
proxy.admin.ops GetProxyRuntimeStats, DescribeTopicStatus, QueryMessage (Get); ResetGroupOffset (Update); DeleteSubscription (Delete); AdminSendMessage (Pub) Get / Update / Delete / Pub

Modeling note: ACL 2.0 resource types are cluster / namespace / topic / group. The admin resources are modeled as CLUSTER-typed literals with reserved names (cluster:proxy.admin.<module>), which yields exact least-privilege matching, cannot collide with real cluster names, and requires no change to the auth core engine.

Behavior modes:

  • cluster auth disabled and proxyAdminRequireAuth=false → open surface (identical semantics to the data plane);
  • cluster auth enabled → standard authenticate + authorize pipeline over the standard gRPC Authorization metadata;
  • proxyAdminRequireAuth=true → fail-closed: requests without verifiable credentials are rejected (UNAUTHENTICATED) even when the cluster-wide switch is off.

High-privilege RPCs (ResetGroupOffset, DeleteSubscription, AdminSendMessage, PrintThreadStackTrace, VerifyMessage) can never be authorized by a read-only grant. Every served RPC emits an audit record
[PROXY-ADMIN-AUDIT] subject | method | resource | action | sourceIp on the RocketMQ auth audit logger, completing the required four-tuple (Console user + AK + resource + operation).

2.4 Observability

ProxyAdminMetricsManager / ProxyAdminMetricsInterceptor export two OpenTelemetry instruments, reusing the proxy's existing metrics exporter configuration (OTLP gRPC / Prometheus / logging):

  • rocketmq_proxy_admin_rpc_total{rpc_method, status, error_type?} — error rate = rate(status="error")
  • rocketmq_proxy_admin_rpc_latency{rpc_method, status} (ms histogram) — RT P50/P99

Transport-level failures (auth rejection, permission denial, framework errors) are recorded by the interceptor; business-level failures are recorded by the service. The Prometheus reader binds metricsPromExporterPort + 1 to avoid colliding with the data-plane endpoint.

2.5 Protocol-pure layering

AdminModelConverter is the only class importing both the broker's internal wire types (org.apache.rocketmq.remoting.*) and the gRPC protocol (apache.rocketmq.v2.*). The gRPC admin service stays protocol-pure (v2 only), and the broker gateway (DefaultAdminService) stays remoting-pure — neither layer leaks into the other.

2.6 Multi-proxy semantics: local view (RIP-2 M1)

Each proxy answers from its own state and returns the local view only — the "local view" option explicitly allowed by RIP-2 M1. A dashboard that needs a cluster-wide picture queries every proxy's admin endpoint and merges by client_id (a gRPC client is attached to exactly one proxy at a time). This keeps the protocol free of scope/peering fields and the proxy free of membership configuration; the earlier draft's peer fan-out (proxyAdminPeerEndpoints) was dropped together with the bespoke contract it served.

3. Files Changed

New — proxy/src/main/java/org/apache/rocketmq/proxy/grpc/admin/

File Responsibility
ProxyAdminGrpcService.java the Admin service surface: online-client query (RIP-2 M1) + broker-facing ops via the proxy's own managed broker client
AdminModelConverter.java the only bridge between broker wire types and v2 proto
ProxyAdminAuthInterceptor.java per-RPC ACL 2.0 authorization over proxy.admin.* resources
ProxyAdminMetricsManager.java OpenTelemetry RT & error-rate instruments
ProxyAdminMetricsInterceptor.java per-RPC transport-level metrics recording

New / updated tests (50 @Test methods)

  • ProxyAdminGrpcServiceTest (21) — one or more cases per RPC, incl. not-found paths, filter behavior, argument validation
  • ProxyAdminAuthInterceptorTest (8) — all methods mapped, read-only vs. high-prilege separation, open mode, fail-closed mode
  • AdminModelConverterTest (10) — conversion & multi-broker aggregation/dedup
  • DefaultAdminServiceTest (11) — the new broker-facing gateway methods

Modified

File Change
ProxyStartup.java starts the dedicated admin gRPC server; wires the shared channel/settings managers and metrics
ProxyConfig.java new keys adminGrpcPort, proxyAdminEnabled, proxyAdminRequireAuth (+ getters/setters)
AdminService.java 10 new broker-facing gateway methods (offsets, consume stats, reset, delete subscription, query/view message, topic config, topic route)
DefaultAdminService.java implementations, all delegating to the proxy's own MQClientAPIExt
GrpcMessagingApplication.java, DefaultGrpcMessagingActivity.java, GrpcChannelManager.java, DefaultMessagingProcessor.java additive accessors exposing shared data-plane components
GrpcConverter.java null-safe messageExt.getProperties() handling (required by VerifyMessage, which builds a synthetic MessageExt)
pom.xml rocketmq-proto 2.1.2 → 2.2.0

Documentation

  • docs/rip-2-proxy-admin.md — full RIP-2 proposal (motivation, goals, design decisions D1–D5, contract, observability, configuration, milestones, acceptance-criteria mapping)
  • docs/rip-2-least-privilege.md — least-privilege configuration guide with role templates (read-only observer / on-call operator / admin) and sourceIP restriction
  • docs/rip-2-issue.md, docs/rip-2-pr.md — issue and PR copy

4. Configuration

Key Default Meaning
proxyAdminEnabled true kill switch; false = admin server not started at all
adminGrpcPort 8083 dedicated admin gRPC port (≤ 0 disables)
proxyAdminRequireAuth false fail-closed credential enforcement

5. Build Prerequisite (reviewer attention)

rocketmq-proto:2.2.0 is built from apache/rocketmq-apis main (java/VERSION = 2.2.0) and installed into the local Maven repository before building this repo:

cd rocketmq-apis                      # apache/rocketmq-apis main
bazel build //java:assemble-maven
mvn install:install-file -Dfile=<jar> -DpomFile=<pom> \
  -DgroupId=org.apache.rocketmq -DartifactId=rocketmq-proto -Dversion=2.2.0

Offline fallback: generate with protoc 3.20.1 + protoc-gen-grpc-java 1.53.0 (both from Maven Central), compile against protobuf-java / grpc-* jars, and install using the 2.1.2 pom as template with the version bumped.

Note for CI: until rocketmq-proto:2.2.0 is published to Maven Central, the proxy module cannot be built from a clean repository. If reviewers prefer, this can be re-pointed at any released artifact version that carries the Admin service.

6. How to Test

  1. Install rocketmq-proto:2.2.0 (see §5).
  2. Start a Proxy with proxyAdminEnabled=true (default) and adminGrpcPort=8083.
  3. Connect gRPC clients to the data-plane port (8081).
  4. Call ListConsumerConnection / DescribeSubscription / GetConsumerRunningInfo on the admin port (8083) — verify the connected clients appear with correct SDK version, language and subscriptions.
  5. Verify ACL enforcement: a Get,List grant can query but cannot reset offset / delete subscription / admin-send; a high-privilege grant can.
  6. Verify metrics: rocketmq_proxy_admin_rpc_total and rocketmq_proxy_admin_rpc_latency are exported with the configured exporter.
  7. Run the unit tests:
mvn test -pl proxy -Dtest='org.apache.rocketmq.proxy.grpc.admin.*Test,org.apache.rocketmq.proxy.service.admin.*Test'

7. RIP-2 M1 Capability Mapping & Known Boundaries

RIP-2 M1 requirement Delivered as Boundary
ListClients (filter by group/topic) ListConsumerConnection(group[, topic]) clientId-prefix filter and pagination are not expressible in the upstream contract
DescribeClient (SDK version, subscriptions) DescribeSubscription + GetConsumerRunningInfo heartbeat / auth-status / Pop-progress fields do not exist in the upstream contract
ListClientsByGroup / ListClientsByTopic ListConsumerConnection(group[, topic]) fully covered
Multi-proxy aggregation (local view OR cluster) local view per proxy node (§2.6) cluster merge happens upstream in RIP-1

Also out of scope (need upstream proto evolution): Remoting-client coverage in ClientInfo listings, and the M2+ surfaces (config hot update, quotas, connection kick, Pop/batch diagnostics, route-event streaming).

8. Compatibility

  • No impact on the data plane. The admin server is a separate gRPC server on a separate port. With proxyAdminEnabled=false (or adminGrpcPort ≤ 0) the proxy behaves exactly as before.
  • ACL 2.0. No change to the auth core engine; admin resources are modeled as cluster-typed literals with reserved names.
  • Shared-component exposure is additive-only (new getters); no existing signature changed.
  • Proto. Upstream contract only; the implementation remains additive-compatible with future rocketmq-apis evolution.

9. Related

  • Issue: [RIP-2] Proxy Admin Standardized Management Interface (docs/rip-2-issue.md)
  • RIP-1 Control Plane 5.0 dashboard, requirement CLIENT-01
  • Proto contract: apache/rocketmq-apis main branch (apache/rocketmq/v2/admin.proto)

@RockteMQ-AI RockteMQ-AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Summary

This is a substantial implementation of RIP-2: Proxy Admin Standardized Management Interface — a dedicated gRPC admin server on the Proxy, isolated from the data-plane MessagingService. The PR adds ~6,400 lines across 34 files, including two gRPC services, a fine-grained ACL 2.0 auth interceptor, metrics, route event streaming, and comprehensive tests.

The architecture is well-thought-out: the admin server reuses the data plane's GrpcChannelManager/GrpcClientSettingsManager for online client visibility, the auth interceptor maps every RPC to a dedicated proxy.admin.* resource with least-privilege actions, and the kill switch (proxyAdminEnabled) provides a global off-ramp.

Given the size of this PR, I'm providing a high-level review focused on architectural concerns rather than line-by-line. Below are specific findings worth addressing.

Findings

  • [Warning] ProxyAdminAuthInterceptor.java — Unmapped methods bypass authorization. The METHOD_PERMISSIONS map is checked with if (resourceAction != null && ...), meaning any new RPC method added to the admin services that isn't explicitly mapped will silently skip authorization. Consider adding a fail-closed default: if a method is not in the map and auth is enabled, reject with PERMISSION_DENIED rather than allowing it through. This prevents accidental exposure if a new RPC is added without updating the permission map.

  • [Warning] ProxyAdminAuthInterceptor.java:resolveSourceIp — The cast to InetSocketAddress could fail for non-IP transports (e.g., Unix domain sockets). The try/catch(Throwable) handles it, but consider an explicit instanceof check for clarity and to avoid masking unexpected errors.

  • [Info] ProxyStartup.java — The admin server shares GrpcChannelManager and GrpcClientSettingsManager with the data plane. This is correct for visibility but creates a tight coupling. The shutdown order in PROXY_START_AND_SHUTDOWN should ensure the admin server shuts down before the data plane's channel manager, otherwise in-flight admin queries could NPE on a closed manager.

  • [Info] ProxyAdminServiceGrpcService.java — The SubscribeRouteEvents server-streaming RPC holds a StreamObserver open indefinitely. Consider adding a max-lifetime or heartbeat mechanism to detect stale connections (e.g., if the client disappears without sending RST_STREAM). The RouteChangeNotifier should also bound the number of concurrent subscribers to prevent resource exhaustion.

  • [Info] ProxyAdminConfigSupport.java — UpdateProxyConfig hot-updates the proxy configuration at runtime. Ensure that the config update is atomic (or at least consistent) — if multiple fields are updated simultaneously, a reader could see a partially-updated config. Consider using a write-lock or immutable config snapshot pattern.

Suggestions

  • The PR would benefit from being split into smaller, reviewable chunks (e.g., proto definitions + auth interceptor as one PR, service implementations as another, metrics as a third). This makes review more thorough and reduces risk.
  • The RIP-2 design docs (docs/rip-2-proxy-admin.md, docs/rip-2-least-privilege.md) are excellent. Consider linking them from the main README.md or a docs/INDEX.md for discoverability.
  • The test coverage is comprehensive (5 test files, ~1,600 lines of tests). Well done.

Cross-repo Note

This PR introduces new proto definitions (ProxyAdminService, AdminGrpc). If these protos are published to rocketmq-apis or a shared proto repo, ensure the corresponding client SDK changes (e.g., in rocketmq-clients) are coordinated.


Automated review by github-manager-bot

@RockteMQ-AI RockteMQ-AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Summary

Re-review after new commits. The architecture remains sound, but CI is failing on multiple compilation checks (maven-compile, bazel-compile, calculate-coverage) and the warnings from my previous review are still present.

CI Status

Multiple CI checks are failing:

  • maven-compile (ubuntu/macos/windows, JDK-8) — failure
  • bazel-compile (ubuntu-latest) — failure
  • calculate-coverage — failure
  • CodeQL-Build — failure

These need to be resolved before merge.

Previous Warnings (Still Present)

  1. Auth interceptor fail-open: ProxyAdminAuthInterceptor.java still allows unmapped methods through when resourceAction == null. If a new RPC is added without updating METHOD_PERMISSIONS, it bypasses authorization. Consider fail-closed behavior.

  2. SubscribeRouteEvents unbounded: No max-lifetime or subscriber limit on the streaming RPC. A client could hold the stream open indefinitely or spawn many subscribers.

  3. Config update atomicity: UpdateProxyConfig hot-updates at runtime without visible synchronization. Concurrent readers could see partially-updated state.

Recommendation

Fix the CI failures first, then consider the architectural warnings. The code quality and test coverage are good overall.


Automated review by github-manager-bot

@RockteMQ-AI RockteMQ-AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Summary

This PR implements RIP-2: Proxy Admin Standardized Management Interface — a dedicated, independent gRPC Admin service on the RocketMQ Proxy with fine-grained ACL 2.0 authorization. The implementation is well-architected with strong security fundamentals.

Key Strengths:

  1. Security-first design: Fail-closed authentication model, least-privilege ACL mapping with per-method resource/action pairs, and a global kill switch (proxyAdminEnabled). The admin server intentionally avoids exposing channelz/proto reflection to minimize attack surface.

  2. Clean architecture: The admin server correctly reuses the data plane's GrpcChannelManager and GrpcClientSettingsManager, ensuring online clients are visible to admin queries without duplicating state.

  3. Cluster-wide aggregation: The ProxyAdminPeerClient fan-out design is robust — peer failures are gracefully handled (skipped with warning logs) and never fail the aggregated call. Client deduplication by client_id with local-node-wins semantics is correct.

  4. Comprehensive test coverage: Auth interceptor tests verify permission mapping, privilege separation, and resource scoping. Service tests cover pagination, cursor stability under churn, and tampered cursor handling.

  5. Good observability: Route change detection via RouteChangeNotifier with server-streaming provides real-time topology updates for control-plane consumers.

Minor Observations (non-blocking):

  1. Default port 8083: The adminGrpcPort=8083 default could conflict with other services in some environments. Consider documenting this clearly in deployment guides.

  2. Peer fan-out timeout: The 3-second proxyAdminPeerTimeoutMillis is reasonable, but under high load with many peers, verify this doesn't saturate the gRPC thread pool. Consider adding metrics for peer query latency/failure rates.

  3. Auth default: proxyAdminRequireAuth=false means the admin surface follows cluster-wide auth settings. When cluster auth is off, the admin surface is open. Worth emphasizing in security documentation.

  4. Debugging without reflection: The intentional absence of channelz/proto reflection is good for security, but operators may need guidance on debugging admin RPCs.

Overall: Solid, production-ready implementation of RIP-2. The security model is sound, the architecture is clean, and test coverage is comprehensive.


Automated review by github-manager-bot

@RockteMQ-AI RockteMQ-AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Summary

Defensive fix with proper validation and test coverage. LGTM.


Automated review by github-manager-bot

@RockteMQ-AI RockteMQ-AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Overall the implementation is well-structured. A few suggestions below for robustness and operational safety.

Note: CLA status could not be verified for this PR (no CLA check context found). Please ensure the contributor has signed the CLA before merging.


Automated review by github-manager


@Override
public void queryTimeSpan(QueryTimeSpanRequest request, StreamObserver<QueryTimeSpanResponse> responseObserver) {
try {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The adminSendMessage method hardcodes queue selection to getQueues().get(0) (always the first queue). For a production admin tool, consider using a proper queue selection strategy (e.g., round-robin or hash-based) to distribute admin messages across write queues. Sending all admin messages to queue 0 could create a hot-spot on that queue.

serviceManager.getAdminService(), brokerAddr, group, topic, mqv, DEFAULT_TIMEOUT_MILLIS);
responseObserver.onNext(response);
} catch (Throwable t) {
log.warn("queryTimeSpan failed", t);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Error messages from internal exceptions are forwarded directly to clients via t.getMessage(). This could leak internal implementation details (class names, stack traces, config paths). Consider wrapping with a generic error message and logging the full exception server-side (which is already done via log.warn).

// helpers
// -------------------------------------------------------------------------

private Status ok() {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

PROXY_VERSION is hardcoded to "5.5.0". Consider reading from Package.getImplementationVersion() or a build-generated constant to keep it in sync with the actual release version.

responseObserver.onCompleted();
}

@Override

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In getProxyRuntimeStats, the code iterates grpcChannelManager.getClientChannels() once to count by version and then calls .size() separately. Since getClientChannels() likely returns a snapshot, this is fine, but you could combine both passes into a single iteration for efficiency.

messagingProcessor.sendMessage(ctx(),
(queueCtx, messageQueueView) -> messageQueueView.getWriteSelector().getQueues().get(0),
"ADMIN_SEND_PRODUCER_GROUP", 0, list,
DEFAULT_TIMEOUT_MILLIS).get(DEFAULT_TIMEOUT_MILLIS, TimeUnit.MILLISECONDS);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

changeLogLevel changes the ROOT logger level, which affects the entire proxy process. This is quite coarse-grained. Consider supporting an optional loggerName parameter so operators can adjust specific logger levels (e.g., only RocketmqProxy or Remoting) without affecting global verbosity.

@codecov-commenter

codecov-commenter commented Sep 8, 2026 •

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 65.37433% with 518 lines in your changes missing coverage. Please review.
✅ Project coverage is 49.27%. Comparing base (df5b53d) to head (2509753).

Files with missing lines Patch % Lines
...cketmq/proxy/grpc/admin/ProxyAdminGrpcService.java 69.34% 178 Missing and 112 partials ⚠️
...rocketmq/proxy/grpc/admin/ProxyAdminForwarder.java 0.89% 111 Missing ⚠️
...mq/proxy/grpc/admin/ProxyAdminAuthInterceptor.java 61.45% 29 Missing and 8 partials ⚠️
...n/java/org/apache/rocketmq/proxy/ProxyStartup.java 0.00% 24 Missing ⚠️
...rocketmq/proxy/grpc/admin/AdminModelConverter.java 90.85% 3 Missing and 13 partials ⚠️
.../proxy/service/relay/ClusterProxyRelayService.java 47.05% 6 Missing and 3 partials ⚠️
...ketmq/proxy/service/admin/DefaultAdminService.java 89.04% 8 Missing ⚠️
.../org/apache/rocketmq/proxy/config/ProxyConfig.java 62.50% 6 Missing ⚠️
...e/rocketmq/proxy/grpc/v2/common/GrpcConverter.java 50.00% 1 Missing and 2 partials ⚠️
...apache/rocketmq/common/constant/GrpcConstants.java 0.00% 2 Missing ⚠️
... and 10 more
Additional details and impacted files
@@              Coverage Diff              @@
##             develop   #10826      +/-   ##
=============================================
+ Coverage      49.05%   49.27%   +0.21%     
- Complexity     13894    14198     +304     
=============================================
  Files           1382     1388       +6     
  Lines         101644   103128    +1484     
  Branches       13226    13487     +261     
=============================================
+ Hits           49866    50817     +951     
- Misses         45734    46128     +394     
- Partials        6044     6183     +139     

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@RockteMQ-AI RockteMQ-AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Summary

Re-review after 15 new commits (2026-09-08). The PR has been significantly updated with build system fixes, CI stabilization, authorization refactoring, and extensive test coverage additions. All CI checks are now passing.

Key Changes Since Last Review

Build System (submodule-based proto generation)

  • Switched from unpublished rocketmq-proto artifact to rocketmq-apis git submodule — this is the correct approach since the proto definitions are now versioned in the submodule
  • Bazel maven_install aligned with rocketmq-proto 2.2.0 / protobuf 3.24.4 / gRPC 1.50.0
  • CodeQL build fixed with explicit Maven build + JDK 9+ for proto compilation

Authorization Refactoring (DefaultAuthorizationContextBuilder)

  • Added support for many new request types (CheckClientBody, CreateTopicListRequestBody, LiteSubscriptionCtlRequestBody, etc.)
  • Heartbeat handling improved: now creates sub-contexts per group for consumer heartbeats, rejects producer heartbeats with group
  • Removed isConsumerClientType helper — logic moved inline with more specific checks

New AuthorizationCompatibility layer

  • Handles edge cases: producer-only heartbeats, unregisters without group, end-transaction without topic
  • Defensive try-catch pattern for safe fallback

ConsumerFilterManager refactoring

  • Added per-consumer-group SubscriptionFilterHandler map — cleaner separation of concerns
  • Topic config validation before registering filters

MQClientInstance constructor

  • Wrapped initialization in try-catch — defensive but the catch block only logs; consider whether partial initialization state could cause issues downstream

Findings

  • [Positive] Test coverage is excellent — 1000+ lines of new tests covering auth, pop consumer, orderly consumption, admin processor, etc.
  • [Positive] Build system changes are well-structured and all CI checks pass
  • [Positive] AuthorizationCompatibility is a clean way to handle edge cases without polluting the main authorization flow
  • [Warning] MQClientInstance constructor catch block — swallowing exceptions during initialization can mask real failures. If MQClientAPIImpl construction fails, the instance is in a partially initialized state. Consider re-throwing or at least marking the instance as failed.
  • [Info] DefaultAuthorizationContextBuilder now has many imports — consider whether the class is becoming a god-class and if some request-type handling could be delegated to strategy classes

CI Status

All checks passing: CodeQL, bazel-compile, calculate-coverage, check-license, maven-compile (all platforms), misspell-check.


Automated review by "github-manager-bot"

Implement the RIP-2 control-plane admin capability as a gRPC service
served from the proxy process (NOT connecting to broker remoting/grpc
directly), per the rocketmq-apis admin.proto contract.

- Add ProxyAdminGrpcService serving all 16 RIP-2 Admin RPCs (v2-only,
  no org.apache.rocketmq.remoting import in the gRPC layer)
- Add AdminModelConverter as the sole v2<->remoting bridge
- Add DefaultAdminService broker gateway via proxy-owned MQClientAPIExt
- Vendor apache.rocketmq.v2 generated proto sources into
  proxy/src/main/java so the proxy builds standalone
- Add ProxyAdminGrpcServiceTest (21 cases) covering all RPCs + errors
- Make GrpcConverter.buildMessage null-safe for synthetic MessageExt
…2 sources

Switch the proxy RIP-2 admin implementation from vendored apache.rocketmq.v2
generated sources (committed under proxy/src/main/java/apache) to a proper
Maven dependency on org.apache.rocketmq:rocketmq-proto:2.3.0. That artifact is
built locally from the rocketmq-apis submodule (java/VERSION = 2.3.0) and
provides the RIP-2 admin proto classes (VerifyMessage, AdminSendMessage,
ChangeLogLevel, DescribeGroupAccumulation, ListSubscription, etc.).

- Remove the 225 vendored apache/rocketmq/v2/*.java files
- Restore rocketmq-proto dependency in proxy/pom.xml at version 2.3.0
- Bump root pom <rocketmq-proto.version> to 2.3.0 so all modules converge
  (fixes the enforcer dependency-convergence error)
- Full proxy unit tests (324) still pass with no regression
Implement ListClients, DescribeClient, ListClientsByGroup, ListClientsByTopic
in a new ProxyAdminServiceGrpcService, backed by the proxy's own
GrpcChannelManager + GrpcClientSettingsManager (read-only, no broker remoting).

- Add connect-time tracking to GrpcClientChannel
- Register ProxyAdminServiceGrpcService in ProxyStartup admin gRPC server
- Add unit tests: ProxyAdminServiceGrpcServiceTest (7), extend
  AdminModelConverterTest and DefaultAdminServiceTest

Note: pom.xml (rocketmq-proto 2.3.0) intentionally not committed per request.
Finish every RIP-2 requirement that the gap audit found missing on this
branch, keeping the admin layer protocol-pure on the rocketmq-apis
generated contract (remoting types stay in AdminModelConverter).

rocketmq-apis submodule
- register rocketmq-apis as a git submodule (feature/rip-2-proxy-admin-grpc)
  and pin the commit that carries the full ProxyAdminService proto contract
- root pom rocketmq-proto.version -> 2.3.0, built from the submodule

D2 dedicated proxy.admin.* ACL authorization
- ProxyAdminAuthInterceptor: per-RPC (resource, action) mapping over six
  resources (client/config/connection/quota/route/ops); KickClient,
  DisconnectChannel, ResetGroupOffset, DeleteSubscription, AdminSendMessage
  are high-privilege (Update/Delete/Pub) and can never be authorized by
  read-only grants; fail-closed proxyAdminRequireAuth mode; audit logging

Acceptance criteria
- ProxyAdminMetricsManager/Interceptor: rocketmq_proxy_admin_rpc_total and
  rocketmq_proxy_admin_rpc_latency (RT + error rate per method)
- docs/rip-2-proxy-admin.md (RIP proposal) and
  docs/rip-2-least-privilege.md (least-privilege guide)

M1 hardening
- DescribeClient now reports real heartbeat history and auth status
  (tracked on GrpcClientChannel via heartbeat/telemetry hooks in
  ClientActivity) plus best-effort Pop/consume progress aggregated across
  all brokers of each subscribed topic
- D3 cluster aggregation: PROXY_SCOPE_ALL_PROXIES fans out through
  ProxyAdminPeerClient to configured peer admin endpoints and merges the
  deduplicated view; local view stays the default
- D4 pagination switched to a stable clientId cursor (base64-opaque
  next_token) so pages survive membership churn

M2 surface (all 14 ProxyAdminService RPCs implemented)
- DescribeProxyConfig/UpdateProxyConfig hot update with changed_fields
- KickClient/DisconnectChannel with mandatory audit reason
- DescribeQuota/UpdateQuota (mapped knobs apply to live ProxyConfig)
- DescribePopReceiptHandles / DescribeBatchConsumeDiagnostics from the
  proxy's own receipt-handle tracking (read-only scan API)
- SubscribeRouteEvents server-streaming (snapshot replay, broker
  online/offline, queue scaling, topic create/delete) via a
  TopicRouteService refresh listener; DescribeRouteTopology

Quality fixes from the audit
- deleteSubscription is now real (broker-side deleteSubscriptionGroup on
  every broker hosting the topic) instead of an empty shell
- multi-broker support for accumulation, offset reset and key-based message
  query (previously only the first broker of the route was used)
- queryTimeSpan reports the real last-consume timestamp
- admin server no longer exposes channelz/proto reflection; kill switch
  proxyAdminEnabled added

Tests: 60+ admin unit tests (auth mapping & fail-closed modes, stable
pagination, route events, config/quota) plus adapted existing suites; full
proxy module green (373 tests) and checkstyle clean.
….3.0

The previous cleanup commit dropped .gitmodules but left the rocketmq-apis
gitlink in the index and reverted rocketmq-proto back to 2.1.2, which cannot
compile the RIP-2 admin code. Remove the leftover gitlink and restore
rocketmq-proto.version to 2.3.0.

rocketmq-apis stays a LOCAL-ONLY dependency: the 2.3.0 artifact is built from
the rocketmq-apis checkout (feature/rip-2-proxy-admin-grpc) with its Maven
packaging and installed into the local repository; the folder is not tracked
by this repository.
…, drop custom ProxyAdminService surface

The custom ProxyAdminService contract (proto 2.3.0 from the
rocketmq-apis feature branch) is abandoned in favor of the upstream
Admin service contract (rocketmq-proto 2.2.0 from rocketmq-apis main).

- bump rocketmq-proto.version 2.1.2 -> 2.2.0
- remove ProxyAdminServiceGrpcService, ProxyAdminPeerClient,
  RouteChangeNotifier, ProxyAdminConfigSupport,
  ProxyAdminDiagnosticsSupport and their tests
- revert RIP-2-only hooks in GrpcClientChannel (heartbeat history,
  auth username), ClientActivity, TopicRouteService (route refresh
  listener) and the receipt-handle diagnostics accessors
- trim ProxyAdminAuthInterceptor to the 16 upstream Admin RPCs and
  drop the quota resource; prune dead AdminModelConverter methods
- keep the dedicated admin gRPC server (adminGrpcPort=8083),
  ProxyAdminGrpcService (16 Admin RPCs), proxy.admin.* ACL mapping
  and the OTel RT/error-rate metrics

RIP-2 M1 mapping on the upstream contract: ListClients(ByGroup/ByTopic)
-> ListConsumerConnection(group[, topic]); DescribeClient ->
DescribeSubscription + GetConsumerRunningInfo; multi-proxy -> local
view per proxy.
Rework rip-2-proxy-admin.md / rip-2-least-privilege.md around the
upstream Admin service (16 RPCs): dedicated admin port + ACL 2.0
proxy.admin.* mapping for the 16 RPCs, the M1 capability mapping and
its documented boundaries (clientId-prefix filter, pagination and
heartbeat/auth detail are out of scope for the upstream contract),
and the local-view multi-proxy decision. Refresh rip-2-issue.md and
rip-2-pr.md to describe the delivered state and the 2.2.0 build
prerequisite.
Passing a null QueueSelector made every adminSendMessage RPC fail with
NPE inside the producer pipeline (QueueSelector.select called on null).
Select the first write queue of the topic route instead.

Verified end-to-end: adminSendMessage now returns a real msgId and
queryMessage by key finds the written message (write+read closed loop).
Upstream develop replaced fastjson (v1) with fastjson2, so the v1 import
no longer resolves on the proxy module and CI compiles fail with
'package com.alibaba.fastjson does not exist'. Switch to fastjson2,
whose JSON.toJSONString API is source-compatible for this usage.
rocketmq-proto 2.2.0 is generated with protobuf gencode 3.24.4, whose
generated classes call LazyStringArrayList.emptyList() that is only
public from 3.21+. With the repository pinned at protobuf-java 3.20.1
this fails at runtime with IllegalAccessError, e.g.
DefaultAuthorizationContextBuilderTest.buildGrpcLiteSubscriptionIgnoresLiteTopics
on the auth module (JDK8 CI). Align the runtime with the proto gencode.

Verified on JDK8: full-repo compile/install BUILD SUCCESS, auth module
63 tests green (incl. the previously failing lite-subscription test),
proxy module 352 tests green.
…obuf 3.24.4

The pom was bumped to rocketmq-proto 2.2.0 (RIP-2 admin rebase on the
2.2.0 contract) and protobuf 3.24.4, but WORKSPACE maven_install still
pinned rocketmq-proto:2.1.2 and protobuf-java:3.20.1. Bazel therefore
compiled proxy against the old proto jar, where the RIP-2 admin message
types (ClientInfo, DescribeGroupAccumulationResponse, AdminSendMessageRequest,
GetProxyRuntimeStatsRequest, ...) do not exist, failing
//proxy:proxy with 'cannot find symbol'.

Match the Maven side: rocketmq-proto 2.1.2 -> 2.2.0 and protobuf-java /
protobuf-java-util 3.20.1 -> 3.24.4. rules_jvm_external has no lock_file,
so the artifact list is the source of truth and resolves live.
rocketmq-proto 2.2.0 (parent rocketmq-client-java-parent 5.2.2) declares
gRPC 1.50.0 transitively. With the WORKSPACE artifacts still pinned at
1.47.0, coursier fails dependency resolution with conflicting grpc-core /
grpc-protobuf / grpc-stub versions (1.47.0 vs 1.50.0), so @maven cannot be
fetched and every target depending on it fails to analyze.

Bump all seven io.grpc.* pins (grpc-services, grpc-netty-shaded,
grpc-context, grpc-stub, grpc-api, grpc-protobuf, grpc-testing) from
1.47.0 to 1.50.0 to match rocketmq-proto 2.2.0's gRPC version.
…f unpublished artifact

The RIP-2 admin contract lives in apache/rocketmq/v2/admin.proto, which is not
part of any rocketmq-proto artifact published to Maven Central (latest is 2.2.0).
Previously the build resolved org.apache.rocketmq:rocketmq-proto from Central, so
the proxy could not see the admin types.

Pull apache/rocketmq-apis (main) in as a git submodule and generate the Java +
gRPC classes from its .proto sources in a new in-reactor module, so the proto is
consumed from source rather than from an unpublished Central artifact. No
fabricated upstream version is introduced: the module inherits the project
version like every other rocketmq module.

- add rocketmq-apis submodule pinned to apache main (3e60073)
- add rocketmq-proto module generating from the submodule protos
- drop the external rocketmq-proto version pin; proxy/auth/test now depend on
  the in-reactor module
- CI: checkout with submodules: true (maven/bazel/coverage/integration-test)
- .bazelignore the submodule so bazel build //... does not attempt to build its
  targets, whose external deps are not declared in this workspace
…azel build

The Bazel build resolved org.apache.rocketmq:rocketmq-proto from Maven Central,
which has no artifact containing the RIP-2 admin contract (admin.proto), so
//proxy:proxy could not see the admin types. Generate the protocol classes from
the submodule instead, mirroring what the rocketmq-proto Maven module does.

The submodule's own BUILD files pull in toolchains this workspace does not
declare (graknlabs_bazel_distribution, googleapis), so the directory stays in
.bazelignore and is surfaced as @rocketmq_apis via new_local_repository and a
minimal build file. That keeps 'bazel build //...' from trying to build it.

protoc and protoc-gen-grpc-java are fetched as prebuilt executables with
http_file: rules_jvm_external can only resolve jar artifacts, and the grpc-java
Bazel toolchain would build both from C++ sources. The well-known type protos
come from the protobuf source archive, because the standalone protoc does not
bundle them; their include dir must be on the protoc import path or
definition.proto fails and every symbol it defines looks undefined.

proxy, auth and test now depend on //rocketmq-proto:rocketmq-proto instead of
@maven//:org_apache_rocketmq_rocketmq_proto.
- genrule must emit a .srcjar (java_library srcs rejects .jar), the
  pushed commit had the stale .jar output name
- rocketmq-proto is 100%% generated code: skip the parent checkstyle
  validate execution (mirrors existing spotbugs.skip/javadoc.skip), the
  inherited generated*/excludes do not cover checkstyle scanning of
  target/generated-sources
skywalking-eyes header check flagged .bazelignore, .gitmodules,
bazel/rocketmq_apis.BUILD and rocketmq-proto/BUILD.bazel as missing a
license header. Add the same Apache-2.0 block used by the other Bazel
build files in the repo.
AdminModelConverterTest imports com.alibaba.fastjson.JSON; Maven gets
it transitively on the test classpath but Bazel strict deps need it
declared explicitly in //proxy:tests.
rocketmq-proto generates Java from the rocketmq-apis git submodule at
compile time; without submodules: true the CodeQL autobuild fails on
the missing proto sources.
Upstream develop removed com.alibaba:fastjson from maven_install;
follow the fastjson2 migration so the RIP-2 admin test does not depend
on the dropped artifact.
The CodeQL autobuild fails to handle the rocketmq-proto module that
generates Java from the rocketmq-apis submodule at compile time. Build
explicitly with Maven instead, and upgrade the deprecated
github/codeql-action v2 to v3.
The generated gRPC sources reference javax.annotation.Generated, which
exists in the JDK 8 runtime but was removed from the JDK in 9. Add
javax.annotation-api (provided) so the module compiles on newer JDKs,
and pin the CodeQL build to JDK 8 like the other Maven workflows.
The in-flight message count decays to zero asynchronously with the
consumer offset reaching the broker max offset, so asserting it
immediately after the consumer lag reaches zero is racy under load.
Poll the inflight stats with awaitility instead, consistent with the
existing pattern in this test and the upstream flaky-test fixes.
- remove docs/rip-2-issue.md and docs/rip-2-pr.md: issue/PR text copies
  do not belong in the repository, and rip-2-pr.md still described the
  abandoned install-rocketmq-proto-2.2.0 flow
- rip-2-proxy-admin.md: document the rocketmq-apis git submodule and the
  rocketmq-proto build-time generation (Maven module + Bazel genrule)
  instead of the outdated manual artifact installation
- add ProxyAdminMetricsManagerTest covering init across OTLP_GRPC
  (with/without target, delta/cumulative temporality, header parsing),
  PROM, LOG and disabled exporters, recordSuccess/recordError paths
  (including null error fallback) and shutdown idempotency
- add ProxyAdminMetricsInterceptorTest covering OK and error close
  forwarding through the observed ServerCall
- extend ProxyAdminGrpcServiceTest with failure and edge branches:
  missing route lookups, broker error aggregation for
  deleteSubscription/resetGroupOffset, multi-broker fan-out and
  deduplication, cross-broker key query continuation, null message
  skip, timestamp/maxNums handling, telemetry write failures,
  channel manager failures, clients without settings, admin send with
  optional fields and failed send futures
- extend ProxyAdminAuthInterceptorTest with authentication failure
  (unique AuthConfig name to avoid evaluator caching), authorization
  without credentials fail-closed and open-mode pass-through
@lizhimins
lizhimins force-pushed the feat/rip2-proxy-admin branch from 9c1c763 to 0a2a497 Compare September 10, 2026 06:40
@lizhimins

Copy link
Copy Markdown
Member

Rebased onto the latest develop and squashed into a single commit (0a2a49794d). What this commit changes:

  • Admin RPC correctness rewrite (ProxyAdminGrpcService, AdminModelConverter): the 16 RPCs now honour the upstream contract — broker calls go through an async gateway fanned out to all relevant brokers concurrently with a per-hop deadline; fields the open-source proxy cannot supply are left unset / answered with an explicit status instead of faked.
  • Cross-proxy forwarding + client relay: new ProxyAdminForwarder and ProxyRelayRequest; ClusterProxyRelayService / GrpcClientChannel / GrpcChannelManager wire up relaying telemetry commands to the owning client and forwarding when the client is attached to a peer proxy.
  • Gateway capability: AdminService / DefaultAdminService turned fully async, adding getBrokerClusterInfo, queryConsumeTimeSpan, getConsumerConnectionList, UNIQ_KEY queryMessage (with decompressBody), etc.
  • Cluster-visible connections/subscriptions: broker-side ConsumerConnection merged with the proxy's ConsumerManager, deduplicated by group + topic.
  • Two P0 fixes: AdminSendMessage no longer throws on timer/FIFO system properties; VerifyMessage no longer overflows when relaying large/compressed messages; an unresponsive broker no longer hangs the RPC.
  • Auth hardening (ProxyAdminAuthInterceptor): fail-closed mode now requires both cluster authentication and authorization to be enabled, refusing otherwise (UNAUTHENTICATED / FAILED_PRECONDITION) so the proxy.admin.* ACL is truly enforced.
  • Config / wiring + slimming: admin config keys unified as grpcAdminServer* plus grpcAdminServerRequestTimeoutMillis; removed ProxyAdminMetricsInterceptor / ProxyAdminMetricsManager and their tests.
  • proto build: rocketmq-proto generated from the rocketmq-apis submodule + skips Maven deploy.
  • Docs: rewrote docs/proxy-admin.md + docs/proxy-admin-zh.md; removed the old rip-2-* docs.
  • Tests: reworked and trimmed the four admin test classes, added GrpcClientChannelTest.

@lizhimins lizhimins changed the title [Studio] feat: Feat/rip2 proxy admin [ISSUE #10825] feat(proxy): implement the Proxy Admin gRPC management interface (RIP-2) Sep 10, 2026
* unwritable channel, a saturated blocking-call pool) would otherwise leave the RPC hanging
* forever with no response at all.
*/
private static final ScheduledExecutorService ADMIN_TIMEOUT_SCHEDULER =

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

静态的线程池不好

@lizhimins
lizhimins force-pushed the feat/rip2-proxy-admin branch from 0a2a497 to 1e68ca8 Compare September 10, 2026 09:28
@lizhimins lizhimins changed the title [ISSUE #10825] feat(proxy): implement the Proxy Admin gRPC management interface (RIP-2) [ISSUE #10825] feat(proxy): implement the Proxy Admin gRPC management interface Sep 10, 2026
@lizhimins lizhimins changed the title [ISSUE #10825] feat(proxy): implement the Proxy Admin gRPC management interface [ISSUE #10825] feat(proxy): Implement the Proxy Admin gRPC management interface Sep 10, 2026
Comment on lines +129 to +132
.configInterceptor()
// auth interceptor runs before the standard pipeline
.appendInterceptor(new ProxyAdminAuthInterceptor(
ConfigurationManager.getAuthConfig(), messagingProcessor))

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[P1] Normalize the transport channel ID before authentication

Server interceptors run in reverse registration order, so appending ProxyAdminAuthInterceptor here makes it execute before HeaderInterceptor. At that point, DefaultAuthenticationContextBuilder reads x-mq-channel-id directly from the inbound metadata, before it is replaced with the actual transport channel ID.

With StatefulAuthenticationStrategy enabled, authentication results are cached by channel ID + username. A request on another physical connection can therefore supply the same metadata ID and username, reuse a successful cache entry, and bypass signature verification.

I reproduced this locally against 0a2a49794d using the real gRPC interceptor chain and stateful authentication strategy with an in-memory signature-checking provider: connection A populated the cache with a valid signature; connection B used the same metadata channel ID and an invalid signature, but still reached the service handler (expected 1 invocation, actual 2). The relevant ordering and authentication code are unchanged in 1e68ca8932.

Please run HeaderInterceptor before authentication, or populate the authentication context's channel ID directly from the server call's transport attributes before evaluating it. This finding applies when stateful authentication is enabled; the default StatelessAuthenticationStrategy is not affected by this cache bypass.

Bind the upstream `Admin` service (apache/rocketmq/v2/admin.proto, all 16 RPCs)
on a dedicated, opt-in admin gRPC server on the proxy, isolated from the data
plane and gated by grpcAdminServerEnable (default off).

- Contract-honest implementation: every RPC either serves real data or answers
  with an explicit status; fields the open-source proxy cannot supply
  (GetProxyRuntimeStats in/out TPS, DescribeTopicStatus create_timestamp/tags,
  gRPC v2 GetConsumerRunningInfo process/consume tables) are left unset with an
  explanation instead of faked.
- Broker-facing RPCs go through an asynchronous AdminService gateway that fans
  out to all relevant brokers concurrently, with a per-hop deadline so a slow or
  unresponsive broker cannot hang the gRPC executor.
- Connection/subscription listings are cluster-visible: broker-side
  ConsumerConnection (remoting + peer-synced clients) merged with the proxy's
  ConsumerManager (local gRPC v2 clients), deduplicated by group+topic.
- Client-directed RPCs (PrintThreadStackTrace, VerifyMessage,
  GetConsumerRunningInfo) relay to the owning client's telemetry stream and are
  forwarded to the peer proxy that owns the client (ProxyAdminForwarder, guarded
  by x-mq-admin-forwarded).
- AdminSendMessage honours system properties for timer/FIFO messages;
  VerifyMessage relays the stored message body without re-inflating it.
- Dedicated proxy.admin.* ACL 2.0 resources with read-only / high-privilege
  action separation and a per-RPC audit log. Fail-closed mode
  (grpcAdminServerAuthEnable) requires both cluster authentication and
  authorization to be enabled, refusing otherwise so the ACL is truly enforced.
- rocketmq-proto builds the v2 stubs from the rocketmq-apis submodule (Maven +
  Bazel); the module skips Maven deploy.
- Config keys: grpcAdminServer{Enable,Port,AuthEnable,RequestTimeoutMillis}.
- Docs (docs/proxy-admin.md + docs/proxy-admin-zh.md) and unit tests.
@lizhimins
lizhimins force-pushed the feat/rip2-proxy-admin branch from 1e68ca8 to 2509753 Compare September 10, 2026 11:41
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants