Skip to content

[client][rpc][server] Add getClusterVersion API to expose the server version - #4037

Open
morazow wants to merge 1 commit into
apache:mainfrom
morazow:oss-3966-human-readable-version
Open

[client][rpc][server] Add getClusterVersion API to expose the server version#4037
morazow wants to merge 1 commit into
apache:mainfrom
morazow:oss-3966-human-readable-version

Conversation

@morazow

@morazow morazow commented Aug 18, 2026

Copy link
Copy Markdown
Contributor

PR description generated-by: Claude Code (Opus 5), following the guidelines

Purpose

Linked issue: close #3966

Clients can learn a cluster's protocol surface from apiVersions() (api_key / min / max version
numbers), but there is no way to ask a cluster for its human-readable release version, e.g.
0.10.0. Anything that needs to branch on the deployed version - upgrade checks, support
diagnostics, compatibility gates in downstream connectors - has nothing to read.

This adds a GET_CLUSTER_VERSION RPC and surfaces it as Admin#getClusterVersion().

It also closes the version half of the ServerConnection TODO that hardcoded the client's own
reported software version as "0.1.0". client_software_name remains hardcoded and is still
marked TODO.

Brief change log

  • VersionInfo (fluss-common) reads the version from a build-time-filtered
    fluss-version.properties resource, falling back to "unknown" when the resource is missing
    or unreadable. This is the pattern Kafka's AppInfoParser and Flink's
    EnvironmentInformation use, including reading it once into a static rather than per call.
    The resource lives at org/apache/fluss/utils/ and is read with a package-relative name, so
    two Fluss jars of different versions on one classpath cannot resolve each other's copy, and
    the lookup follows the class if a downstream shade relocates org.apache.fluss.
    A manifest-based lookup was rejected: it breaks under re-shading and NPEs under classloaders
    that skip definePackage.
  • GET_CLUSTER_VERSION RPC (api key 1065), implemented once in RpcServiceBase behind a
    DESCRIBE-on-cluster authorization check, so both server types answer it without a forwarding
    hop.
  • Admin#getClusterVersion() returning CompletableFuture<String>. FlussAdmin routes it
    to the Coordinator, so the answer does not depend on which server a rolling upgrade happens
    to route the client to.
  • ServerConnection now reports the real client version in ApiVersionsRequest.

Tests

  • VersionInfoTest#testGetVersionReadsTheFilteredProjectVersion - asserts the resolved project
    version rather than the "unknown" fallback. This also guards the resource path and the
    Maven filtering config: a wrong path yields "unknown", and unfiltered resources yield the
    literal ${project.version}.
  • VersionInfoTest#testGetVersionIsReadOnceAndCached - guards the caching. Properties.load
    returns a fresh String per read, so this fails if the resource is re-read per call.
  • FlussAdminITCase#testGetClusterVersion - end-to-end round trip through the RPC.
  • FlussAuthorizationITCase#testGetClusterVersion - the unauthorized call fails with the
    DESCRIBE-on-cluster message, then succeeds once the ACL is granted.

Both ITCases additionally assert the version is not "unknown" and matches ^\d+\.\d+.*, so
they cannot pass vacuously when the server and client share a classpath where resource
filtering never ran.

API and Format

Yes, this adds public API:

  • new PUBLIC api key GET_CLUSTER_VERSION (1065), with GetClusterVersionRequest /
    GetClusterVersionResponse messages
  • new Admin#getClusterVersion()

Wire-compatible: the api key is new, so servers that predate it complete the client's future
exceptionally with UnsupportedVersionException. No existing message changed, and there is no
storage format change.

Documentation

website/docs/security/authorization.md gains the GET_CLUSTER_VERSION | DESCRIBE | Cluster
row alongside the other cluster-scoped DESCRIBE protocols.

@morazow
morazow force-pushed the oss-3966-human-readable-version branch from 04d8bbf to 98af26a Compare August 18, 2026 14:05
@morazow
morazow marked this pull request as ready for review August 18, 2026 14:07
@morazow
morazow force-pushed the oss-3966-human-readable-version branch 2 times, most recently from fc17e0e to f80d468 Compare August 18, 2026 18:40
… server version

Fluss clients today learn the protocol api_key/min/max numbers from
apiVersions() but have no way to ask a cluster for its human-readable
version (e.g. "0.10.0"). Adds:

- VersionInfo (fluss-common): reads the version from a build-filtered
  fluss-version.properties resource (the Kafka AppInfoParser / Flink
  EnvironmentInformation pattern), falling back to "unknown" when the
  resource is missing or unreadable. A manifest-based lookup was
  rejected: it breaks under re-shading and NPEs under classloaders
  that skip definePackage.
- GET_CLUSTER_VERSION RPC (api key 1065), implemented once in
  RpcServiceBase behind a DESCRIBE-on-cluster check, so both server
  types answer without a forwarding hop.
- Admin#getClusterVersion(): CompletableFuture<String>. FlussAdmin
  routes it to the Coordinator, so the answer does not depend on which
  server a rolling upgrade happens to route the client to; servers
  that predate this API surface UnsupportedVersionException.
- Closes the version half of the ServerConnection TODO that hardcoded
  the client's own reported software version as "0.1.0"
  (client_software_name remains hardcoded, still marked TODO).

Fixes apache#3966.
@morazow
morazow force-pushed the oss-3966-human-readable-version branch from f80d468 to 2ddf9dd Compare August 18, 2026 18:43
@morazow morazow changed the title [client][rpc][server] Introduce Admin#getClusterVersion to expose the server version [client][rpc][server] Add getClusterVersion API to expose the server version Aug 20, 2026
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.

Expose a human-readable Fluss server version via the client API

1 participant