From 38dbc5f67f3dfbf501fb289f12f193bdec54ff6d Mon Sep 17 00:00:00 2001 From: Erik Grinaker Date: Mon, 19 May 2025 13:17:45 +0200 Subject: [PATCH] pageserver/page_api: add binary Protobuf descriptor (#11968) ## Problem A binary Protobuf schema descriptor can be used to expose an API reflection service, which in turn allows convenient usage of e.g. `grpcurl` against the gRPC server. Touches #11728. ## Summary of changes * Generate a binary schema descriptor as `pageserver_page_api::proto::FILE_DESCRIPTOR_SET`. * Opportunistically rename the Protobuf package from `page_service` to `page_api`. --- pageserver/page_api/build.rs | 8 +++++++- pageserver/page_api/proto/page_service.proto | 15 ++++++++++++++- pageserver/page_api/src/lib.rs | 7 ++++++- 3 files changed, 27 insertions(+), 3 deletions(-) diff --git a/pageserver/page_api/build.rs b/pageserver/page_api/build.rs index ce3c49ed82..e96297f10e 100644 --- a/pageserver/page_api/build.rs +++ b/pageserver/page_api/build.rs @@ -1,7 +1,13 @@ +use std::env; +use std::path::PathBuf; + +/// Generates Rust code from .proto Protobuf schemas, along with a binary file +/// descriptor set for Protobuf schema reflection. fn main() -> Result<(), Box> { - // Generates Rust code from .proto Protobuf schemas. + let out_dir = PathBuf::from(env::var("OUT_DIR")?); tonic_build::configure() .bytes(["."]) + .file_descriptor_set_path(out_dir.join("page_api_descriptor.bin")) .compile_protos(&["proto/page_service.proto"], &["proto"]) .map_err(|err| err.into()) } diff --git a/pageserver/page_api/proto/page_service.proto b/pageserver/page_api/proto/page_service.proto index 12e4d2f9db..f6acb3eeeb 100644 --- a/pageserver/page_api/proto/page_service.proto +++ b/pageserver/page_api/proto/page_service.proto @@ -11,6 +11,19 @@ // - neon-shard-id: shard ID, as in hex ("0b10" = shard 11 of 16, 0-based) // - neon-timeline-id: timeline ID ("f08c4e9a2d5f76b1e3a7c2d8910f4b3e") // +// The service can be accessed via e.g. grpcurl: +// +// ``` +// grpcurl \ +// -plaintext \ +// -H "neon-tenant-id: 7c4a1f9e3bd6470c8f3e21a65bd2e980" \ +// -H "neon-shard-id: 0b10" \ +// -H "neon-timeline-id: f08c4e9a2d5f76b1e3a7c2d8910f4b3e" \ +// -H "authorization: Bearer $JWT" \ +// -d '{"read_lsn": {"request_lsn": 1234567890}, "rel": {"spc_oid": 1663, "db_oid": 1234, "rel_number": 5678, "fork_number": 0}}' +// localhost:51051 page_api.PageService/CheckRelExists +// ``` +// // TODO: consider adding neon-compute-mode ("primary", "static", "replica"). // However, this will require reconnecting when changing modes. // @@ -20,7 +33,7 @@ // - Compression syntax = "proto3"; -package page_service; +package page_api; service PageService { // Returns whether a relation exists. diff --git a/pageserver/page_api/src/lib.rs b/pageserver/page_api/src/lib.rs index 0226d594cb..0b68d03aaa 100644 --- a/pageserver/page_api/src/lib.rs +++ b/pageserver/page_api/src/lib.rs @@ -7,7 +7,12 @@ // Code generated by protobuf. pub mod proto { - tonic::include_proto!("page_service"); + tonic::include_proto!("page_api"); + + /// File descriptor set for Protobuf schema reflection. This allows using + /// e.g. grpcurl with the API. + pub const FILE_DESCRIPTOR_SET: &[u8] = + tonic::include_file_descriptor_set!("page_api_descriptor"); pub use page_service_client::PageServiceClient; pub use page_service_server::{PageService, PageServiceServer};