Skip to content

[client] Add Admin API to describe buckets - #4029

Open
fhan688 wants to merge 2 commits into
apache:mainfrom
fhan688:issue-3436-describe-buckets-admin-api
Open

[client] Add Admin API to describe buckets#4029
fhan688 wants to merge 2 commits into
apache:mainfrom
fhan688:issue-3436-describe-buckets-admin-api

Conversation

@fhan688

@fhan688 fhan688 commented Aug 18, 2026

Copy link
Copy Markdown
Contributor

Purpose

Linked issue: #3436

Fluss currently does not provide a public Admin API for retrieving bucket-level metadata, including replica placement and leader/ISR state. This information is required by administrative tools and by the planned Flink sys.describe_buckets procedure.

This is the first of two PRs planned for #3436. It introduces the core Admin API, RPC contract, and server-side implementation. A follow-up PR will add the Flink procedure and close the issue.

Brief change log

  • Add the public BucketInfo result type, exposing the table path and ID, optional partition ID and name, bucket ID, optional leader and leader epoch, replicas, and ISR.
  • Add Admin#describeBuckets(TablePath) and Admin#describeBuckets(TablePath, PartitionSpec).
  • Add the dedicated public DESCRIBE_BUCKETS RPC (API key 1065), including request/response messages, gateway wiring, and client-side conversion.
  • Support non-partitioned tables, all partitions of a partitioned table, and complete or partial partition-spec filtering.
  • Enforce the table-level DESCRIBE permission and preserve table/partition validation exceptions at the Admin API boundary.
  • Batch ZooKeeper reads for partition registrations and bucket metadata, exclude the historical partition, and return results deterministically by partition name and bucket ID.
  • Add unit, integration, authorization, RPC conversion, and ZooKeeper coverage.

The Flink sys.describe_buckets procedure is intentionally excluded from this PR and will be added in the follow-up PR.

Tests

  • BucketInfoTest
  • ClientRpcMessageUtilsTest
  • ApiKeysTest
  • ApiManagerTest
  • ZooKeeperClientTest#testPartition
  • DescribeBucketsITCase
    • non-partitioned table bucket metadata
    • partitioned table queries, complete/partial partition filters, validation errors, deterministic ordering, and ISR metadata
  • FlussAuthorizationITCase#testDescribeTableOperation
  • fluss-flink-common test compilation for Admin interface compatibility
  • Spotless, RAT, Checkstyle, and git diff --check

API and Format

  • Public Java API: Yes. This PR adds the @PublicEvolving BucketInfo class and two new methods to Admin.
  • RPC protocol: Yes. This PR adds the public DESCRIBE_BUCKETS API (key 1065) and its protobuf messages.
  • Storage format: No.
  • The existing PbBucketMetadata wire message is unchanged, avoiding overlap with the separate ISR metadata work in feat: shell tool #3360.

Documentation

Public API Javadocs are included for BucketInfo and the new Admin methods.

No user-facing Flink procedure documentation is added in this PR because the procedure is outside this PR's scope. The follow-up PR will add the procedure, integration tests, and corresponding documentation.

@morazow morazow 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.

Hello @fhan688 👋

Thanks for the PR!

I have left some comments please have a look 🤝


message PbBucketInfo {
required PbTablePath table_path = 1;
required int64 table_id = 2;

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.

I think we should move out the two table_path and table_id from here into the above DescribeBucketsResponse.

message DescribeBucketsResponse {
  required PbTablePath table_path = 1;
  required int64 table_id = 2;
  repeated PbBucketInfo bucket_info = 3;
}

The DescribeBucketsResponse answers for one table (it carries table_path), but this PbBucketInfo repeats table_path message and the table_id.

Given a table with many partitions the same two strings are serialized once per bucket (e.g., 1000 partitions x 16 buckets = 16k copies).

}

return partitions;
List<String> matchedPartitionNames =

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.

Was there any reason for these change?

I think we have behaviour change here, the processGetDataResponses only logs warning for Zookeeper decode errors. The previous getPartition / getOrEmpty methods rethrows ZK errors (except for NoNode).

So if one znode read fails for a transient reason, the caller now gets back a partition list that looks complete but isn't, instead of an error. For an admin describe call I'd rather fail the request than silently omit partitions.

This also isn't limited to the new API: the refactor changes the existing listPartitionInfos RPC too.

return zookeeperClient.getPartitionRegistrations(
tablePath, tableInfo.getPartitionKeys(), partitionFilter);
}
} catch (ApiException e) {

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.

Why this change is needed?

TablePath tablePath = toTablePath(request.getTablePath());
authorizeTable(OperationType.DESCRIBE, tablePath);

TableInfo tableInfo = metadataManager.getTable(tablePath);

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.

Maybe we can do some refactoring here.

The metadataManager.getTable(tablePath) is again called in the listPartitions / listPartitionInfos methods. Maybe good idea to pass already obtained TableInfo 🤝

"Failed to list partitions of table fluss.partitioned_t1 in test-catalog, by partitionSpec CatalogPartitionSpec{{second=}}");
.isInstanceOf(PartitionSpecInvalidException.class)
.hasMessageContaining(
"PartitionSpec CatalogPartitionSpec{{second=}} does not match");

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.

It is unclear to me why we are changing the existing tests, I think this is related to the new throw in MetadataManager below, but hard to understand why it was required.

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.

2 participants