mirror of
https://codeberg.org/JasterV/granc.git
synced 2026-04-26 18:40:05 +00:00
refactor: decouple ReflectionClient to possibly publish in a separate crate
This commit is contained in:
parent
5f6ffaa3ab
commit
27674a03ab
3 changed files with 44 additions and 25 deletions
|
|
@ -72,10 +72,9 @@ pub async fn run(input: Input) -> Result<Output, CoreError> {
|
|||
Some(path) => DescriptorRegistry::from_file(path)?,
|
||||
// If no proto-set file is passed, we'll try to reach the server reflection service
|
||||
None => {
|
||||
let mut service = ReflectionClient::connect(input.url.clone()).await?;
|
||||
service
|
||||
.resolve_service_descriptor_registry(&input.service)
|
||||
.await?
|
||||
let mut client = ReflectionClient::connect(input.url.clone()).await?;
|
||||
let fd_set = client.file_descriptor_set_by_symbol(&input.service).await?;
|
||||
DescriptorRegistry::from_file_descriptor_set(fd_set)?
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -19,7 +19,6 @@ use super::generated::reflection_v1::{
|
|||
server_reflection_response::MessageResponse,
|
||||
};
|
||||
use crate::core::BoxError;
|
||||
use crate::core::reflection::DescriptorRegistry;
|
||||
use http_body::Body as HttpBody;
|
||||
use prost::Message;
|
||||
use prost_types::{FileDescriptorProto, FileDescriptorSet};
|
||||
|
|
@ -64,9 +63,6 @@ pub enum ReflectionResolveError {
|
|||
|
||||
#[error("Failed to decode FileDescriptorProto: {0}")]
|
||||
DecodeError(#[from] prost::DecodeError),
|
||||
|
||||
#[error("Failed to build DescriptorRegistry: {0}")]
|
||||
RegistryError(#[from] crate::core::reflection::registry::DescriptorError),
|
||||
}
|
||||
|
||||
/// A generic client for the gRPC Server Reflection Protocol.
|
||||
|
|
@ -99,10 +95,21 @@ where
|
|||
T::ResponseBody: HttpBody<Data = tonic::codegen::Bytes> + Send + 'static,
|
||||
<T::ResponseBody as HttpBody>::Error: Into<BoxError> + Send,
|
||||
{
|
||||
pub async fn resolve_service_descriptor_registry(
|
||||
/// Asks the reflection service for the file containing the requested symbol (e.g., `my.package.MyService`).
|
||||
///
|
||||
/// **Recursive Resolution**:
|
||||
/// - The server returns a `FileDescriptorProto`.
|
||||
/// - The client inspects the imports (dependencies) of that file.
|
||||
/// - It recursively requests any missing dependencies until the full `FileDescriptorSet` is built.
|
||||
///
|
||||
/// # Returns
|
||||
///
|
||||
/// * `Ok(fd_set)` - Successful reflection requests execution.
|
||||
/// * `Err(ReflectionResolveError)` - Failed to request file descriptors to the reflection service.
|
||||
pub async fn file_descriptor_set_by_symbol(
|
||||
&mut self,
|
||||
service_name: &str,
|
||||
) -> Result<DescriptorRegistry, ReflectionResolveError> {
|
||||
) -> Result<FileDescriptorSet, ReflectionResolveError> {
|
||||
// Initialize Stream
|
||||
let (tx, rx) = mpsc::channel(100);
|
||||
|
||||
|
|
@ -133,7 +140,7 @@ where
|
|||
file: file_map.into_values().collect(),
|
||||
};
|
||||
|
||||
Ok(DescriptorRegistry::from_file_descriptor_set(fd_set)?)
|
||||
Ok(fd_set)
|
||||
}
|
||||
|
||||
async fn collect_descriptors(
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
use crate::core::reflection::{
|
||||
DescriptorRegistry,
|
||||
client::{
|
||||
ReflectionClient, ReflectionResolveError, integration_test::dummy_service::DummyEchoService,
|
||||
},
|
||||
|
|
@ -28,10 +29,13 @@ fn setup_reflection_client()
|
|||
async fn test_reflection_client_fetches_unary_echo() {
|
||||
let mut client = setup_reflection_client();
|
||||
|
||||
let registry = client
|
||||
.resolve_service_descriptor_registry("echo.EchoService")
|
||||
let fd_set = client
|
||||
.file_descriptor_set_by_symbol("echo.EchoService")
|
||||
.await
|
||||
.expect("Failed to resolve service descriptor registry");
|
||||
.expect("Failed to fetch file descriptor set by symbol");
|
||||
|
||||
let registry = DescriptorRegistry::from_file_descriptor_set(fd_set)
|
||||
.expect("Failed to build descriptor registry");
|
||||
|
||||
let method = registry
|
||||
.get_method_descriptor("echo.EchoService", "UnaryEcho")
|
||||
|
|
@ -56,10 +60,13 @@ async fn test_reflection_client_fetches_unary_echo() {
|
|||
async fn test_reflection_client_fetches_server_streaming_echo() {
|
||||
let mut client = setup_reflection_client();
|
||||
|
||||
let registry = client
|
||||
.resolve_service_descriptor_registry("echo.EchoService")
|
||||
let fd_set = client
|
||||
.file_descriptor_set_by_symbol("echo.EchoService")
|
||||
.await
|
||||
.expect("Failed to resolve service descriptor registry");
|
||||
.expect("Failed to fetch file descriptor set by symbol");
|
||||
|
||||
let registry = DescriptorRegistry::from_file_descriptor_set(fd_set)
|
||||
.expect("Failed to build descriptor registry");
|
||||
|
||||
let method = registry
|
||||
.get_method_descriptor("echo.EchoService", "ServerStreamingEcho")
|
||||
|
|
@ -84,10 +91,13 @@ async fn test_reflection_client_fetches_server_streaming_echo() {
|
|||
async fn test_reflection_client_fetches_client_streaming_echo() {
|
||||
let mut client = setup_reflection_client();
|
||||
|
||||
let registry = client
|
||||
.resolve_service_descriptor_registry("echo.EchoService")
|
||||
let fd_set = client
|
||||
.file_descriptor_set_by_symbol("echo.EchoService")
|
||||
.await
|
||||
.expect("Failed to resolve service descriptor registry");
|
||||
.expect("Failed to fetch file descriptor set by symbol");
|
||||
|
||||
let registry = DescriptorRegistry::from_file_descriptor_set(fd_set)
|
||||
.expect("Failed to build descriptor registry");
|
||||
|
||||
let method = registry
|
||||
.get_method_descriptor("echo.EchoService", "ClientStreamingEcho")
|
||||
|
|
@ -112,10 +122,13 @@ async fn test_reflection_client_fetches_client_streaming_echo() {
|
|||
async fn test_reflection_client_fetches_bidirectional_echo() {
|
||||
let mut client = setup_reflection_client();
|
||||
|
||||
let registry = client
|
||||
.resolve_service_descriptor_registry("echo.EchoService")
|
||||
let fd_set = client
|
||||
.file_descriptor_set_by_symbol("echo.EchoService")
|
||||
.await
|
||||
.expect("Failed to resolve service descriptor registry");
|
||||
.expect("Failed to fetch file descriptor set by symbol");
|
||||
|
||||
let registry = DescriptorRegistry::from_file_descriptor_set(fd_set)
|
||||
.expect("Failed to build descriptor registry");
|
||||
|
||||
let method = registry
|
||||
.get_method_descriptor("echo.EchoService", "BidirectionalEcho")
|
||||
|
|
@ -139,7 +152,7 @@ async fn test_reflection_service_not_found_error() {
|
|||
let mut client = setup_reflection_client();
|
||||
|
||||
let result: Result<_, _> = client
|
||||
.resolve_service_descriptor_registry("non.existent.Service")
|
||||
.file_descriptor_set_by_symbol("non.existent.Service")
|
||||
.await;
|
||||
|
||||
assert!(matches!(
|
||||
|
|
@ -161,7 +174,7 @@ async fn test_server_does_not_support_reflection() {
|
|||
|
||||
// The client will attempt to call `/grpc.reflection.v1.ServerReflection/ServerReflectionInfo` on this service.
|
||||
let result = client
|
||||
.resolve_service_descriptor_registry("echo.EchoService")
|
||||
.file_descriptor_set_by_symbol("echo.EchoService")
|
||||
.await;
|
||||
|
||||
match result {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue