zhaohai666 opened a new pull request, #10826:
URL: https://github.com/apache/rocketmq/pull/10826

   # [RIP-2] Implement Proxy Admin Standardized Management Interface on the 
Proxy
   
   ## Summary
   
   This PR implements **RIP-2: Proxy Admin Standardized Management Interface** 
— a
   dedicated, independent gRPC Admin service on the RocketMQ Proxy, isolated 
from the
   data-plane `MessagingService`, with a stable backward-compatible proto 
contract and
   fine-grained ACL 2.0 authorization.
   
   It closes the observability gap introduced by RocketMQ 5.0's stateless Proxy
   architecture: gRPC clients attached to a Proxy were previously invisible to
   operations tools that rely on broker-side `ConsumerManager` and Remoting-era 
admin
   commands. RIP-2 gives the control plane a standard server-side interface to 
query
   online clients, subscriptions, runtime config, connection control, 
diagnostics,
   route topology, and broker-facing ops — all served from the Proxy itself.
   
   ### Motivation
   
   - **RIP-1** (Control Plane 5.0 dashboard, requirement `CLIENT-01`) depends 
on a
     standard server-side interface to read complete gRPC client data.
   - Operators currently cannot answer *"which SDK clients are online, what do 
they
     subscribe to, are they healthy?"* without indirect metrics heuristics.
   - There is no least-privilege authorization model for admin operations on the
     Proxy, and no cluster-wide client view.
   
   ## What This PR Adds
   
   ### 1. Dedicated Admin gRPC Server (D1)
   
   A second gRPC server started by `ProxyStartup`, on its own port
   (`adminGrpcPort`, default **8083**), with its own interceptor chain
   (metrics → auth → standard pipeline). It reuses the data plane's
   `GrpcChannelManager` / `GrpcClientSettingsManager` so online clients are 
visible.
   The admin server intentionally does NOT expose channelz or proto reflection
   (control-plane attack surface kept minimal). A global kill switch
   `proxyAdminEnabled` disables the whole surface.
   
   ### 2. Two gRPC Services
   
   **`ProxyAdminServiceGrpcService`** (extends `ProxyAdminServiceGrpc`) — the 
complete
   `ProxyAdminService` surface:
   
   | Milestone | RPCs |
   |-----------|------|
   | M1 — online client query | `ListClients`, `DescribeClient`, 
`ListClientsByGroup`, `ListClientsByTopic` |
   | M2 — runtime config & connection control | `DescribeProxyConfig`, 
`UpdateProxyConfig`, `KickClient`, `DisconnectChannel` |
   | M2 — quota visualization | `DescribeQuota`, `UpdateQuota` |
   | M3/M4 — diagnostics | `DescribePopReceiptHandles`, 
`DescribeBatchConsumeDiagnostics` |
   | Route observation | `SubscribeRouteEvents` (server-streaming), 
`DescribeRouteTopology` |
   
   **`ProxyAdminGrpcService`** (extends `AdminGrpc`) — broker-facing operations 
served
   through the Proxy's own managed broker client (`AdminService` gateway), never
   opening a direct link to the broker:
   
   `GetProxyRuntimeStats`, `DescribeTopicStatus`, `QueryMessage`, 
`QueryTimeSpan`,
   `GetConsumerRunningInfo`, `ListConsumerConnection`, `ListSubscription`,
   `DescribeSubscription`, `DescribeGroupAccumulation`, `ResetGroupOffset`,
   `DeleteSubscription`, `AdminSendMessage`, `PrintThreadStackTrace`,
   `VerifyMessage`, `ChangeLogLevel`, `GetTopicRoute`.
   
   ### 3. Dedicated `proxy.admin.*` ACL 2.0 Authorization (D2)
   
   `ProxyAdminAuthInterceptor` maps every RPC to exactly one `(resource, 
action)`
   pair across six resources:
   
   - `proxy.admin.client` — online client query & diagnostics (`Get`/`List`)
   - `proxy.admin.config` — runtime config query & hot update (`Get`/`Update`)
   - `proxy.admin.connection` — kick/disconnect, telemetry (`Update`, high 
privilege)
   - `proxy.admin.quota` — quota query & adjustment (`Get`/`Update`, high 
privilege)
   - `proxy.admin.route` — route topology & event stream (`Get`/`List`)
   - `proxy.admin.ops` — broker-facing ops (`Get`/`List` for queries;
     `Update`/`Delete`/`Pub` for mutations)
   
   High-privilege RPCs (`KickClient`, `DisconnectChannel`, `ResetGroupOffset`,
   `DeleteSubscription`, `AdminSendMessage`) can **never** be authorized by a
   read-only grant. A fail-closed `proxyAdminRequireAuth` mode rejects requests
   without verifiable credentials even when cluster-wide auth is off. Every 
served
   RPC writes a `[PROXY-ADMIN-AUDIT]` log (subject / method / resource / action 
/
   sourceIp).
   
   ### 4. Multi-Proxy Cluster Aggregation (D3)
   
   `ProxyAdminPeerClient` fans `PROXY_SCOPE_ALL_PROXIES` queries out to 
configured
   peer admin endpoints in parallel, merges per-node local views, and 
deduplicates by
   `client_id` (local view wins on duplicates). Every result is tagged with
   `proxy_endpoint` + monotonic `epoch` for attribution. Peer failures degrade
   gracefully — an unreachable peer is skipped with a warning.
   
   ### 5. Stable Cursor Pagination (D4)
   
   Client listings use cursor-based `next_token` (base64-opaque, clientId-sorted
   position of the last element) so page boundaries stay stable while clients
   connect/disconnect between calls. Diagnostic snapshots use offset pagination
   (`page_num`/`page_size`, max 100) because they are bounded, point-in-time 
views.
   
   ### 6. Observability (Acceptance Criteria #4)
   
   `ProxyAdminMetricsManager` / `ProxyAdminMetricsInterceptor` export two
   OpenTelemetry instruments honoring the proxy's metrics exporter 
configuration:
   
   - `rocketmq_proxy_admin_rpc_total{rpc_method, status, error_type?}` — error 
rate
   - `rocketmq_proxy_admin_rpc_latency{rpc_method, status}` (ms histogram) — RT 
P50/P99
   
   ### 7. Route Change Streaming
   
   `RouteChangeNotifier` detects route changes from the proxy's topic route 
cache
   refreshes and streams them to admin subscribers. Event types: 
`ROUTE_SNAPSHOT`
   (replayed on subscribe), `TOPIC_CREATE`, `TOPIC_DELETE`, `QUEUE_SCALE`,
   `BROKER_ONLINE`, `BROKER_OFFLINE`.
   
   ### 8. Protocol-Pure Architecture
   
   `AdminModelConverter` is the **only** class that imports both the broker's
   internal wire types (`org.apache.rocketmq.remoting.*`) and the RIP-2 gRPC
   protocol (`apache.rocketmq.v2.*`). The gRPC admin services stay protocol-pure
   (v2 only); the broker gateway (`DefaultAdminService`) stays remoting-pure.
   
   ## Files Changed
   
   **34 files changed, +6,453 / −61 lines** (8 commits over `develop`).
   
   ### New Documentation
   - `docs/rip-2-proxy-admin.md` — full RIP-2 proposal (motivation, goals, 
design decisions, proto contract, observability, configuration, milestones, 
acceptance criteria)
   - `docs/rip-2-least-privilege.md` — least-privilege configuration guide with 
role templates (read-only observer, on-call operator, admin)
   
   ### New Source — `proxy/grpc/admin/` (11 files)
   | File | Lines | Responsibility |
   |------|-------|----------------|
   | `ProxyAdminServiceGrpcService.java` | 862 | `ProxyAdminService` surface: 
M1 client query, M2 config/connection/quota, M3/M4 diagnostics, route 
observation |
   | `ProxyAdminGrpcService.java` | 716 | `AdminService` surface: broker-facing 
ops via the Proxy's managed client |
   | `AdminModelConverter.java` | 332 | Bridge between broker wire types and v2 
proto (only class importing both worlds) |
   | `ProxyAdminConfigSupport.java` | 344 | Runtime config hot update + quota 
registry |
   | `ProxyAdminDiagnosticsSupport.java` | 296 | POP receipt-handle & 
batch-consume diagnostics from proxy state |
   | `RouteChangeNotifier.java` | 332 | Route change detection & 
server-streaming notification |
   | `ProxyAdminAuthInterceptor.java` | 280 | Per-RPC ACL 2.0 authorization 
over `proxy.admin.*` resources |
   | `ProxyAdminPeerClient.java` | 264 | D3 cluster-wide fan-out & merge |
   | `ProxyAdminMetricsManager.java` | 252 | OpenTelemetry RT & error-rate 
metrics |
   | `ProxyAdminMetricsInterceptor.java` | 52 | Per-RPC metrics recording |
   | `ProxyAdminConfigSupport.java` | 344 | (listed above) |
   
   ### New Tests — 7 files, ~1,840 lines
   - `AdminModelConverterTest.java`, `ProxyAdminAuthInterceptorTest.java`,
     `ProxyAdminConfigSupportTest.java`, `ProxyAdminGrpcServiceTest.java`,
     `ProxyAdminServiceGrpcServiceTest.java`, `RouteChangeNotifierTest.java`,
     `DefaultAdminServiceTest.java` (enhanced)
   
   ### Modified Source
   - `ProxyStartup.java` — starts the dedicated admin gRPC server, wires shared 
channel/settings managers, peer client, route notifier, metrics
   - `ProxyConfig.java` — 6 new config keys (`adminGrpcPort`, 
`proxyAdminEnabled`, `proxyAdminRequireAuth`, `proxyAdminPeerEndpoints`, 
`proxyAdminPeerTimeoutMillis`, `proxyAdminHeartbeatHistorySize`)
   - `AdminService.java` / `DefaultAdminService.java` — broker-facing gateway 
methods (offsets, consume stats, reset, delete subscription, query message, 
topic config/route)
   - `TopicRouteService.java` — route refresh listener hook for 
`RouteChangeNotifier`
   - `GrpcClientChannel.java` — heartbeat history & auth-status tracking
   - `ClientActivity.java` — heartbeat/telemetry hooks feeding `DescribeClient`
   - `ReceiptHandleManager.java` / `DefaultReceiptHandleManager.java` — 
diagnostic accessors for POP handle inspection
   - `GrpcConverter.java`, `GrpcChannelManager.java`, 
`GrpcMessagingApplication.java`, `DefaultGrpcMessagingActivity.java`, 
`DefaultMessagingProcessor.java`, `ReceiptHandleProcessor.java` — 
shared-component exposure
   
   ## Configuration
   
   | Key | Default | Meaning |
   |-----|---------|---------|
   | `proxyAdminEnabled` | `true` | Kill switch; `false` = admin server not 
started |
   | `adminGrpcPort` | `8083` | Dedicated admin gRPC port (`≤0` disables) |
   | `proxyAdminRequireAuth` | `false` | Fail-closed credential enforcement |
   | `proxyAdminPeerEndpoints` | `[]` | Peer admin endpoints for ALL_PROXIES 
fan-out |
   | `proxyAdminPeerTimeoutMillis` | `3000` | Per-peer fan-out timeout (ms) |
   | `proxyAdminHeartbeatHistorySize` | `16` | Heartbeat records kept per 
client |
   
   ## Build Prerequisite
   
   > ⚠️ **The `rocketmq-apis` 2.3.0 artifact is consumed as a local development
   > dependency.** The proto contract (`ProxyAdminService` + `AdminService` in
   > `admin.proto`) lives in the 
[rocketmq-apis](https://github.com/apache/rocketmq-apis)
   > repository, branch `feature/rip-2-proxy-admin-grpc`. Before building this 
branch,
   > install the artifact into your local Maven repository:
   >
   > ```bash
   > cd rocketmq-apis   # branch feature/rip-2-proxy-admin-grpc
   > mvn clean install
   > ```
   >
   > The `rocketmq-apis` folder is intentionally **not** vendored or submoduled 
into
   > this repository.
   
   ### Known Issue: `rocketmq-proto.version` property
   
   The last commit on this branch (`4945b82c`) reverted 
`rocketmq-proto.version` in
   the root `pom.xml` back from `2.3.0` to `2.1.2`. The RIP-2 admin code imports
   types (`ProxyAdminServiceGrpc`, `AdminGrpc`, etc.) that only exist in the 
**2.3.0**
   artifact. The pom property should be restored to `2.3.0` before merge, or the
   build will fail against the standard Maven Central artifact. This is tracked 
for
   follow-up.
   
   ## How to Test
   
   1. Install the rocketmq-apis 2.3.0 artifact locally (see Build Prerequisite 
above).
   2. Start a Proxy with `proxyAdminEnabled=true` (default) and 
`adminGrpcPort=8083`.
   3. Connect gRPC clients to the data-plane port (8081).
   4. Call `ListClients` / `DescribeClient` on the admin port (8083) — verify 
the
      connected clients appear with correct subscriptions, heartbeat history, 
and
      auth status.
   5. Test `PROXY_SCOPE_ALL_PROXIES` with `proxyAdminPeerEndpoints` configured 
across
      two proxies — verify the merged, deduplicated cluster view.
   6. Verify `proxy.admin.*` ACL enforcement: a read-only user can query but not
      kick; a high-privilege user can kick / reset offset / delete subscription.
   7. Verify metrics: `rocketmq_proxy_admin_rpc_total` and
      `rocketmq_proxy_admin_rpc_latency` are exported.
   8. Run the unit test suite:
      ```bash
      mvn test -pl proxy -Dtest='org.apache.rocketmq.proxy.grpc.admin.*Test'
      ```
   
   ## Acceptance Criteria Mapping
   
   | Criterion | Status |
   |-----------|--------|
   | RIP document + stable backward-compatible proto contract | 
`docs/rip-2-proxy-admin.md` + rocketmq-apis `admin.proto` |
   | Client query RPCs merged; pagination scales with connection churn | D4 
stable cursor; page cost O(pageSize) after sort |
   | Independent ACL control, read-only/high-risk separation, least-privilege 
doc | D2 resources/actions + `docs/rip-2-least-privilege.md` |
   | RPC RT & error-rate metrics | `ProxyAdminMetricsManager` instruments |
   | E2E with RIP-1 dashboard | Contract frozen for dashboard CLIENT-01 
integration (cross-repo) |
   
   ## Compatibility
   
   - **Backward compatible**: additive-only proto field evolution, all new 
fields
     optional, `ProxyScope` defaults to local, no field number reuse.
   - **No impact on data plane**: the admin server is a separate gRPC server on 
a
     separate port; if `proxyAdminEnabled=false` (or `adminGrpcPort≤0`), the 
proxy
     behaves exactly as before.
   - **ACL 2.0**: no changes to the auth core engine — admin resources are 
modeled as
     cluster-typed literals with reserved names.
   
   ## Commits
   
   | Hash | Message |
   |------|---------|
   | `59607fdb9` | feat(proxy): implement RIP-2 admin gRPC service on the proxy 
|
   | `5fa8c4bcf` | refactor(proxy): depend on rocketmq-proto 2.3.0 instead of 
vendored v2 sources |
   | `4c50b9a0b` | feat(proxy): implement RIP-2 ProxyAdminService M1 RPCs |
   | `e1e8fbfcd` | fix dedicated admin gRPC server (control plane), isolated 
from the data plane |
   | `d992dbd3d` | feat(proxy): complete RIP-2 ProxyAdminService surface per 
gap audit |
   | `d43fbc8e4` | remove submodule |
   | `99343ee02` | fix(build): finish removing the rocketmq-apis submodule, 
keep proto 2.3.0 |
   | `4945b82c4` | Fix signature-algorithm calibration |
   
   ## 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: [rocketmq-apis](https://github.com/apache/rocketmq-apis), 
branch `feature/rip-2-proxy-admin-grpc`
   


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