diff options
| author | mo khan <mo@mokhan.ca> | 2025-07-14 16:29:33 -0600 |
|---|---|---|
| committer | mo khan <mo@mokhan.ca> | 2025-07-14 16:29:33 -0600 |
| commit | 0432cfbbb07f234dd2cd294cfe7dfa065b113182 (patch) | |
| tree | cab9f759b7d656dab92eab48694e5924c54b9644 /vendor/tonic-health/src | |
| parent | 5a74d3988d8a029f1c879da709db623611aa545a (diff) | |
| parent | e0b38f6ca22b28a0c4fe4192d642fceb48030737 (diff) | |
Merge branch 'the-spice-must-flow' into 'main'
Add SpiceDB Integration with Service-based Routing
See merge request gitlab-org/software-supply-chain-security/authorization/authzd!9
Diffstat (limited to 'vendor/tonic-health/src')
| -rw-r--r-- | vendor/tonic-health/src/generated/grpc_health_v1.rs | 459 | ||||
| -rw-r--r-- | vendor/tonic-health/src/generated/grpc_health_v1_fds.rs | 63 | ||||
| -rw-r--r-- | vendor/tonic-health/src/lib.rs | 76 | ||||
| -rw-r--r-- | vendor/tonic-health/src/server.rs | 353 |
4 files changed, 0 insertions, 951 deletions
diff --git a/vendor/tonic-health/src/generated/grpc_health_v1.rs b/vendor/tonic-health/src/generated/grpc_health_v1.rs deleted file mode 100644 index 67ec57c9..00000000 --- a/vendor/tonic-health/src/generated/grpc_health_v1.rs +++ /dev/null @@ -1,459 +0,0 @@ -// This file is @generated by prost-build. -#[derive(Clone, PartialEq, ::prost::Message)] -pub struct HealthCheckRequest { - #[prost(string, tag = "1")] - pub service: ::prost::alloc::string::String, -} -#[derive(Clone, Copy, PartialEq, ::prost::Message)] -pub struct HealthCheckResponse { - #[prost(enumeration = "health_check_response::ServingStatus", tag = "1")] - pub status: i32, -} -/// Nested message and enum types in `HealthCheckResponse`. -pub mod health_check_response { - #[derive( - Clone, - Copy, - Debug, - PartialEq, - Eq, - Hash, - PartialOrd, - Ord, - ::prost::Enumeration - )] - #[repr(i32)] - pub enum ServingStatus { - Unknown = 0, - Serving = 1, - NotServing = 2, - /// Used only by the Watch method. - ServiceUnknown = 3, - } - impl ServingStatus { - /// String value of the enum field names used in the ProtoBuf definition. - /// - /// The values are not transformed in any way and thus are considered stable - /// (if the ProtoBuf definition does not change) and safe for programmatic use. - pub fn as_str_name(&self) -> &'static str { - match self { - Self::Unknown => "UNKNOWN", - Self::Serving => "SERVING", - Self::NotServing => "NOT_SERVING", - Self::ServiceUnknown => "SERVICE_UNKNOWN", - } - } - /// Creates an enum from field names used in the ProtoBuf definition. - pub fn from_str_name(value: &str) -> ::core::option::Option<Self> { - match value { - "UNKNOWN" => Some(Self::Unknown), - "SERVING" => Some(Self::Serving), - "NOT_SERVING" => Some(Self::NotServing), - "SERVICE_UNKNOWN" => Some(Self::ServiceUnknown), - _ => None, - } - } - } -} -/// Generated client implementations. -pub mod health_client { - #![allow( - unused_variables, - dead_code, - missing_docs, - clippy::wildcard_imports, - clippy::let_unit_value, - )] - use tonic::codegen::*; - use tonic::codegen::http::Uri; - #[derive(Debug, Clone)] - pub struct HealthClient<T> { - inner: tonic::client::Grpc<T>, - } - impl<T> HealthClient<T> - where - T: tonic::client::GrpcService<tonic::body::Body>, - T::Error: Into<StdError>, - T::ResponseBody: Body<Data = Bytes> + std::marker::Send + 'static, - <T::ResponseBody as Body>::Error: Into<StdError> + std::marker::Send, - { - pub fn new(inner: T) -> Self { - let inner = tonic::client::Grpc::new(inner); - Self { inner } - } - pub fn with_origin(inner: T, origin: Uri) -> Self { - let inner = tonic::client::Grpc::with_origin(inner, origin); - Self { inner } - } - pub fn with_interceptor<F>( - inner: T, - interceptor: F, - ) -> HealthClient<InterceptedService<T, F>> - where - F: tonic::service::Interceptor, - T::ResponseBody: Default, - T: tonic::codegen::Service< - http::Request<tonic::body::Body>, - Response = http::Response< - <T as tonic::client::GrpcService<tonic::body::Body>>::ResponseBody, - >, - >, - <T as tonic::codegen::Service< - http::Request<tonic::body::Body>, - >>::Error: Into<StdError> + std::marker::Send + std::marker::Sync, - { - HealthClient::new(InterceptedService::new(inner, interceptor)) - } - /// Compress requests with the given encoding. - /// - /// This requires the server to support it otherwise it might respond with an - /// error. - #[must_use] - pub fn send_compressed(mut self, encoding: CompressionEncoding) -> Self { - self.inner = self.inner.send_compressed(encoding); - self - } - /// Enable decompressing responses. - #[must_use] - pub fn accept_compressed(mut self, encoding: CompressionEncoding) -> Self { - self.inner = self.inner.accept_compressed(encoding); - self - } - /// Limits the maximum size of a decoded message. - /// - /// Default: `4MB` - #[must_use] - pub fn max_decoding_message_size(mut self, limit: usize) -> Self { - self.inner = self.inner.max_decoding_message_size(limit); - self - } - /// Limits the maximum size of an encoded message. - /// - /// Default: `usize::MAX` - #[must_use] - pub fn max_encoding_message_size(mut self, limit: usize) -> Self { - self.inner = self.inner.max_encoding_message_size(limit); - self - } - /// If the requested service is unknown, the call will fail with status - /// NOT_FOUND. - pub async fn check( - &mut self, - request: impl tonic::IntoRequest<super::HealthCheckRequest>, - ) -> std::result::Result< - tonic::Response<super::HealthCheckResponse>, - tonic::Status, - > { - self.inner - .ready() - .await - .map_err(|e| { - tonic::Status::unknown( - format!("Service was not ready: {}", e.into()), - ) - })?; - let codec = tonic::codec::ProstCodec::default(); - let path = http::uri::PathAndQuery::from_static( - "/grpc.health.v1.Health/Check", - ); - let mut req = request.into_request(); - req.extensions_mut() - .insert(GrpcMethod::new("grpc.health.v1.Health", "Check")); - self.inner.unary(req, path, codec).await - } - /// Performs a watch for the serving status of the requested service. - /// The server will immediately send back a message indicating the current - /// serving status. It will then subsequently send a new message whenever - /// the service's serving status changes. - /// - /// If the requested service is unknown when the call is received, the - /// server will send a message setting the serving status to - /// SERVICE_UNKNOWN but will *not* terminate the call. If at some - /// future point, the serving status of the service becomes known, the - /// server will send a new message with the service's serving status. - /// - /// If the call terminates with status UNIMPLEMENTED, then clients - /// should assume this method is not supported and should not retry the - /// call. If the call terminates with any other status (including OK), - /// clients should retry the call with appropriate exponential backoff. - pub async fn watch( - &mut self, - request: impl tonic::IntoRequest<super::HealthCheckRequest>, - ) -> std::result::Result< - tonic::Response<tonic::codec::Streaming<super::HealthCheckResponse>>, - tonic::Status, - > { - self.inner - .ready() - .await - .map_err(|e| { - tonic::Status::unknown( - format!("Service was not ready: {}", e.into()), - ) - })?; - let codec = tonic::codec::ProstCodec::default(); - let path = http::uri::PathAndQuery::from_static( - "/grpc.health.v1.Health/Watch", - ); - let mut req = request.into_request(); - req.extensions_mut() - .insert(GrpcMethod::new("grpc.health.v1.Health", "Watch")); - self.inner.server_streaming(req, path, codec).await - } - } -} -/// Generated server implementations. -pub mod health_server { - #![allow( - unused_variables, - dead_code, - missing_docs, - clippy::wildcard_imports, - clippy::let_unit_value, - )] - use tonic::codegen::*; - /// Generated trait containing gRPC methods that should be implemented for use with HealthServer. - #[async_trait] - pub trait Health: std::marker::Send + std::marker::Sync + 'static { - /// If the requested service is unknown, the call will fail with status - /// NOT_FOUND. - async fn check( - &self, - request: tonic::Request<super::HealthCheckRequest>, - ) -> std::result::Result< - tonic::Response<super::HealthCheckResponse>, - tonic::Status, - >; - /// Server streaming response type for the Watch method. - type WatchStream: tonic::codegen::tokio_stream::Stream< - Item = std::result::Result<super::HealthCheckResponse, tonic::Status>, - > - + std::marker::Send - + 'static; - /// Performs a watch for the serving status of the requested service. - /// The server will immediately send back a message indicating the current - /// serving status. It will then subsequently send a new message whenever - /// the service's serving status changes. - /// - /// If the requested service is unknown when the call is received, the - /// server will send a message setting the serving status to - /// SERVICE_UNKNOWN but will *not* terminate the call. If at some - /// future point, the serving status of the service becomes known, the - /// server will send a new message with the service's serving status. - /// - /// If the call terminates with status UNIMPLEMENTED, then clients - /// should assume this method is not supported and should not retry the - /// call. If the call terminates with any other status (including OK), - /// clients should retry the call with appropriate exponential backoff. - async fn watch( - &self, - request: tonic::Request<super::HealthCheckRequest>, - ) -> std::result::Result<tonic::Response<Self::WatchStream>, tonic::Status>; - } - #[derive(Debug)] - pub struct HealthServer<T> { - inner: Arc<T>, - accept_compression_encodings: EnabledCompressionEncodings, - send_compression_encodings: EnabledCompressionEncodings, - max_decoding_message_size: Option<usize>, - max_encoding_message_size: Option<usize>, - } - impl<T> HealthServer<T> { - pub fn new(inner: T) -> Self { - Self::from_arc(Arc::new(inner)) - } - pub fn from_arc(inner: Arc<T>) -> Self { - Self { - inner, - accept_compression_encodings: Default::default(), - send_compression_encodings: Default::default(), - max_decoding_message_size: None, - max_encoding_message_size: None, - } - } - pub fn with_interceptor<F>( - inner: T, - interceptor: F, - ) -> InterceptedService<Self, F> - where - F: tonic::service::Interceptor, - { - InterceptedService::new(Self::new(inner), interceptor) - } - /// Enable decompressing requests with the given encoding. - #[must_use] - pub fn accept_compressed(mut self, encoding: CompressionEncoding) -> Self { - self.accept_compression_encodings.enable(encoding); - self - } - /// Compress responses with the given encoding, if the client supports it. - #[must_use] - pub fn send_compressed(mut self, encoding: CompressionEncoding) -> Self { - self.send_compression_encodings.enable(encoding); - self - } - /// Limits the maximum size of a decoded message. - /// - /// Default: `4MB` - #[must_use] - pub fn max_decoding_message_size(mut self, limit: usize) -> Self { - self.max_decoding_message_size = Some(limit); - self - } - /// Limits the maximum size of an encoded message. - /// - /// Default: `usize::MAX` - #[must_use] - pub fn max_encoding_message_size(mut self, limit: usize) -> Self { - self.max_encoding_message_size = Some(limit); - self - } - } - impl<T, B> tonic::codegen::Service<http::Request<B>> for HealthServer<T> - where - T: Health, - B: Body + std::marker::Send + 'static, - B::Error: Into<StdError> + std::marker::Send + 'static, - { - type Response = http::Response<tonic::body::Body>; - type Error = std::convert::Infallible; - type Future = BoxFuture<Self::Response, Self::Error>; - fn poll_ready( - &mut self, - _cx: &mut Context<'_>, - ) -> Poll<std::result::Result<(), Self::Error>> { - Poll::Ready(Ok(())) - } - fn call(&mut self, req: http::Request<B>) -> Self::Future { - match req.uri().path() { - "/grpc.health.v1.Health/Check" => { - #[allow(non_camel_case_types)] - struct CheckSvc<T: Health>(pub Arc<T>); - impl< - T: Health, - > tonic::server::UnaryService<super::HealthCheckRequest> - for CheckSvc<T> { - type Response = super::HealthCheckResponse; - type Future = BoxFuture< - tonic::Response<Self::Response>, - tonic::Status, - >; - fn call( - &mut self, - request: tonic::Request<super::HealthCheckRequest>, - ) -> Self::Future { - let inner = Arc::clone(&self.0); - let fut = async move { - <T as Health>::check(&inner, request).await - }; - Box::pin(fut) - } - } - let accept_compression_encodings = self.accept_compression_encodings; - let send_compression_encodings = self.send_compression_encodings; - let max_decoding_message_size = self.max_decoding_message_size; - let max_encoding_message_size = self.max_encoding_message_size; - let inner = self.inner.clone(); - let fut = async move { - let method = CheckSvc(inner); - let codec = tonic::codec::ProstCodec::default(); - let mut grpc = tonic::server::Grpc::new(codec) - .apply_compression_config( - accept_compression_encodings, - send_compression_encodings, - ) - .apply_max_message_size_config( - max_decoding_message_size, - max_encoding_message_size, - ); - let res = grpc.unary(method, req).await; - Ok(res) - }; - Box::pin(fut) - } - "/grpc.health.v1.Health/Watch" => { - #[allow(non_camel_case_types)] - struct WatchSvc<T: Health>(pub Arc<T>); - impl< - T: Health, - > tonic::server::ServerStreamingService<super::HealthCheckRequest> - for WatchSvc<T> { - type Response = super::HealthCheckResponse; - type ResponseStream = T::WatchStream; - type Future = BoxFuture< - tonic::Response<Self::ResponseStream>, - tonic::Status, - >; - fn call( - &mut self, - request: tonic::Request<super::HealthCheckRequest>, - ) -> Self::Future { - let inner = Arc::clone(&self.0); - let fut = async move { - <T as Health>::watch(&inner, request).await - }; - Box::pin(fut) - } - } - let accept_compression_encodings = self.accept_compression_encodings; - let send_compression_encodings = self.send_compression_encodings; - let max_decoding_message_size = self.max_decoding_message_size; - let max_encoding_message_size = self.max_encoding_message_size; - let inner = self.inner.clone(); - let fut = async move { - let method = WatchSvc(inner); - let codec = tonic::codec::ProstCodec::default(); - let mut grpc = tonic::server::Grpc::new(codec) - .apply_compression_config( - accept_compression_encodings, - send_compression_encodings, - ) - .apply_max_message_size_config( - max_decoding_message_size, - max_encoding_message_size, - ); - let res = grpc.server_streaming(method, req).await; - Ok(res) - }; - Box::pin(fut) - } - _ => { - Box::pin(async move { - let mut response = http::Response::new( - tonic::body::Body::default(), - ); - let headers = response.headers_mut(); - headers - .insert( - tonic::Status::GRPC_STATUS, - (tonic::Code::Unimplemented as i32).into(), - ); - headers - .insert( - http::header::CONTENT_TYPE, - tonic::metadata::GRPC_CONTENT_TYPE, - ); - Ok(response) - }) - } - } - } - } - impl<T> Clone for HealthServer<T> { - fn clone(&self) -> Self { - let inner = self.inner.clone(); - Self { - inner, - accept_compression_encodings: self.accept_compression_encodings, - send_compression_encodings: self.send_compression_encodings, - max_decoding_message_size: self.max_decoding_message_size, - max_encoding_message_size: self.max_encoding_message_size, - } - } - } - /// Generated gRPC service name - pub const SERVICE_NAME: &str = "grpc.health.v1.Health"; - impl<T> tonic::server::NamedService for HealthServer<T> { - const NAME: &'static str = SERVICE_NAME; - } -} diff --git a/vendor/tonic-health/src/generated/grpc_health_v1_fds.rs b/vendor/tonic-health/src/generated/grpc_health_v1_fds.rs deleted file mode 100644 index 45cc00bf..00000000 --- a/vendor/tonic-health/src/generated/grpc_health_v1_fds.rs +++ /dev/null @@ -1,63 +0,0 @@ -// This file is @generated by codegen. -// Copyright 2015 The gRPC Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// The canonical version of this proto can be found at -// https://github.com/grpc/grpc-proto/blob/master/grpc/health/v1/health.proto -// -/// Byte encoded FILE_DESCRIPTOR_SET. -pub const FILE_DESCRIPTOR_SET: &[u8] = &[ - 10u8, 158u8, 4u8, 10u8, 12u8, 104u8, 101u8, 97u8, 108u8, 116u8, 104u8, 46u8, 112u8, - 114u8, 111u8, 116u8, 111u8, 18u8, 14u8, 103u8, 114u8, 112u8, 99u8, 46u8, 104u8, - 101u8, 97u8, 108u8, 116u8, 104u8, 46u8, 118u8, 49u8, 34u8, 46u8, 10u8, 18u8, 72u8, - 101u8, 97u8, 108u8, 116u8, 104u8, 67u8, 104u8, 101u8, 99u8, 107u8, 82u8, 101u8, - 113u8, 117u8, 101u8, 115u8, 116u8, 18u8, 24u8, 10u8, 7u8, 115u8, 101u8, 114u8, 118u8, - 105u8, 99u8, 101u8, 24u8, 1u8, 32u8, 1u8, 40u8, 9u8, 82u8, 7u8, 115u8, 101u8, 114u8, - 118u8, 105u8, 99u8, 101u8, 34u8, 177u8, 1u8, 10u8, 19u8, 72u8, 101u8, 97u8, 108u8, - 116u8, 104u8, 67u8, 104u8, 101u8, 99u8, 107u8, 82u8, 101u8, 115u8, 112u8, 111u8, - 110u8, 115u8, 101u8, 18u8, 73u8, 10u8, 6u8, 115u8, 116u8, 97u8, 116u8, 117u8, 115u8, - 24u8, 1u8, 32u8, 1u8, 40u8, 14u8, 50u8, 49u8, 46u8, 103u8, 114u8, 112u8, 99u8, 46u8, - 104u8, 101u8, 97u8, 108u8, 116u8, 104u8, 46u8, 118u8, 49u8, 46u8, 72u8, 101u8, 97u8, - 108u8, 116u8, 104u8, 67u8, 104u8, 101u8, 99u8, 107u8, 82u8, 101u8, 115u8, 112u8, - 111u8, 110u8, 115u8, 101u8, 46u8, 83u8, 101u8, 114u8, 118u8, 105u8, 110u8, 103u8, - 83u8, 116u8, 97u8, 116u8, 117u8, 115u8, 82u8, 6u8, 115u8, 116u8, 97u8, 116u8, 117u8, - 115u8, 34u8, 79u8, 10u8, 13u8, 83u8, 101u8, 114u8, 118u8, 105u8, 110u8, 103u8, 83u8, - 116u8, 97u8, 116u8, 117u8, 115u8, 18u8, 11u8, 10u8, 7u8, 85u8, 78u8, 75u8, 78u8, - 79u8, 87u8, 78u8, 16u8, 0u8, 18u8, 11u8, 10u8, 7u8, 83u8, 69u8, 82u8, 86u8, 73u8, - 78u8, 71u8, 16u8, 1u8, 18u8, 15u8, 10u8, 11u8, 78u8, 79u8, 84u8, 95u8, 83u8, 69u8, - 82u8, 86u8, 73u8, 78u8, 71u8, 16u8, 2u8, 18u8, 19u8, 10u8, 15u8, 83u8, 69u8, 82u8, - 86u8, 73u8, 67u8, 69u8, 95u8, 85u8, 78u8, 75u8, 78u8, 79u8, 87u8, 78u8, 16u8, 3u8, - 50u8, 174u8, 1u8, 10u8, 6u8, 72u8, 101u8, 97u8, 108u8, 116u8, 104u8, 18u8, 80u8, - 10u8, 5u8, 67u8, 104u8, 101u8, 99u8, 107u8, 18u8, 34u8, 46u8, 103u8, 114u8, 112u8, - 99u8, 46u8, 104u8, 101u8, 97u8, 108u8, 116u8, 104u8, 46u8, 118u8, 49u8, 46u8, 72u8, - 101u8, 97u8, 108u8, 116u8, 104u8, 67u8, 104u8, 101u8, 99u8, 107u8, 82u8, 101u8, - 113u8, 117u8, 101u8, 115u8, 116u8, 26u8, 35u8, 46u8, 103u8, 114u8, 112u8, 99u8, 46u8, - 104u8, 101u8, 97u8, 108u8, 116u8, 104u8, 46u8, 118u8, 49u8, 46u8, 72u8, 101u8, 97u8, - 108u8, 116u8, 104u8, 67u8, 104u8, 101u8, 99u8, 107u8, 82u8, 101u8, 115u8, 112u8, - 111u8, 110u8, 115u8, 101u8, 18u8, 82u8, 10u8, 5u8, 87u8, 97u8, 116u8, 99u8, 104u8, - 18u8, 34u8, 46u8, 103u8, 114u8, 112u8, 99u8, 46u8, 104u8, 101u8, 97u8, 108u8, 116u8, - 104u8, 46u8, 118u8, 49u8, 46u8, 72u8, 101u8, 97u8, 108u8, 116u8, 104u8, 67u8, 104u8, - 101u8, 99u8, 107u8, 82u8, 101u8, 113u8, 117u8, 101u8, 115u8, 116u8, 26u8, 35u8, 46u8, - 103u8, 114u8, 112u8, 99u8, 46u8, 104u8, 101u8, 97u8, 108u8, 116u8, 104u8, 46u8, - 118u8, 49u8, 46u8, 72u8, 101u8, 97u8, 108u8, 116u8, 104u8, 67u8, 104u8, 101u8, 99u8, - 107u8, 82u8, 101u8, 115u8, 112u8, 111u8, 110u8, 115u8, 101u8, 48u8, 1u8, 66u8, 97u8, - 10u8, 17u8, 105u8, 111u8, 46u8, 103u8, 114u8, 112u8, 99u8, 46u8, 104u8, 101u8, 97u8, - 108u8, 116u8, 104u8, 46u8, 118u8, 49u8, 66u8, 11u8, 72u8, 101u8, 97u8, 108u8, 116u8, - 104u8, 80u8, 114u8, 111u8, 116u8, 111u8, 80u8, 1u8, 90u8, 44u8, 103u8, 111u8, 111u8, - 103u8, 108u8, 101u8, 46u8, 103u8, 111u8, 108u8, 97u8, 110u8, 103u8, 46u8, 111u8, - 114u8, 103u8, 47u8, 103u8, 114u8, 112u8, 99u8, 47u8, 104u8, 101u8, 97u8, 108u8, - 116u8, 104u8, 47u8, 103u8, 114u8, 112u8, 99u8, 95u8, 104u8, 101u8, 97u8, 108u8, - 116u8, 104u8, 95u8, 118u8, 49u8, 170u8, 2u8, 14u8, 71u8, 114u8, 112u8, 99u8, 46u8, - 72u8, 101u8, 97u8, 108u8, 116u8, 104u8, 46u8, 86u8, 49u8, 98u8, 6u8, 112u8, 114u8, - 111u8, 116u8, 111u8, 51u8, -]; diff --git a/vendor/tonic-health/src/lib.rs b/vendor/tonic-health/src/lib.rs deleted file mode 100644 index 5884fd82..00000000 --- a/vendor/tonic-health/src/lib.rs +++ /dev/null @@ -1,76 +0,0 @@ -//! A `tonic` based gRPC healthcheck implementation. -//! -//! # Example -//! -//! An example can be found [here]. -//! -//! [here]: https://github.com/hyperium/tonic/blob/master/examples/src/health/server.rs - -#![doc( - html_logo_url = "https://raw.githubusercontent.com/tokio-rs/website/master/public/img/icons/tonic.svg" -)] -#![doc(issue_tracker_base_url = "https://github.com/hyperium/tonic/issues/")] -#![doc(test(no_crate_inject, attr(deny(rust_2018_idioms))))] -#![cfg_attr(docsrs, feature(doc_auto_cfg))] - -use std::fmt::{Display, Formatter}; - -mod generated { - #![allow(unreachable_pub)] - #![allow(missing_docs)] - #[rustfmt::skip] - pub mod grpc_health_v1; - #[rustfmt::skip] - pub mod grpc_health_v1_fds; - - pub use grpc_health_v1_fds::FILE_DESCRIPTOR_SET; - - #[cfg(test)] - mod tests { - use super::FILE_DESCRIPTOR_SET; - use prost::Message as _; - - #[test] - fn file_descriptor_set_is_valid() { - prost_types::FileDescriptorSet::decode(FILE_DESCRIPTOR_SET).unwrap(); - } - } -} - -/// Generated protobuf types from the `grpc.health.v1` package. -pub mod pb { - pub use crate::generated::{grpc_health_v1::*, FILE_DESCRIPTOR_SET}; -} - -pub mod server; - -/// An enumeration of values representing gRPC service health. -#[derive(Copy, Clone, Debug, PartialEq, Eq)] -pub enum ServingStatus { - /// Unknown status - Unknown, - /// The service is currently up and serving requests. - Serving, - /// The service is currently down and not serving requests. - NotServing, -} - -impl Display for ServingStatus { - fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { - match self { - ServingStatus::Unknown => f.write_str("Unknown"), - ServingStatus::Serving => f.write_str("Serving"), - ServingStatus::NotServing => f.write_str("NotServing"), - } - } -} - -impl From<ServingStatus> for pb::health_check_response::ServingStatus { - fn from(s: ServingStatus) -> Self { - match s { - ServingStatus::Unknown => pb::health_check_response::ServingStatus::Unknown, - ServingStatus::Serving => pb::health_check_response::ServingStatus::Serving, - ServingStatus::NotServing => pb::health_check_response::ServingStatus::NotServing, - } - } -} diff --git a/vendor/tonic-health/src/server.rs b/vendor/tonic-health/src/server.rs deleted file mode 100644 index 1a4d73e7..00000000 --- a/vendor/tonic-health/src/server.rs +++ /dev/null @@ -1,353 +0,0 @@ -//! Contains all healthcheck based server utilities. - -use crate::pb::health_server::{Health, HealthServer}; -use crate::pb::{HealthCheckRequest, HealthCheckResponse}; -use crate::ServingStatus; -use std::collections::HashMap; -use std::fmt; -use std::sync::Arc; -use tokio::sync::{watch, RwLock}; -use tokio_stream::Stream; -use tonic::{server::NamedService, Request, Response, Status}; - -/// Creates a `HealthReporter` and a linked `HealthServer` pair. Together, -/// these types can be used to serve the gRPC Health Checking service. -/// -/// A `HealthReporter` is used to update the state of gRPC services. -/// -/// A `HealthServer` is a Tonic gRPC server for the `grpc.health.v1.Health`, -/// which can be added to a Tonic runtime using `add_service` on the runtime -/// builder. -pub fn health_reporter() -> (HealthReporter, HealthServer<impl Health>) { - let reporter = HealthReporter::new(); - let service = HealthService::new(reporter.statuses.clone()); - let server = HealthServer::new(service); - - (reporter, server) -} - -type StatusPair = (watch::Sender<ServingStatus>, watch::Receiver<ServingStatus>); - -/// A handle providing methods to update the health status of gRPC services. A -/// `HealthReporter` is connected to a `HealthServer` which serves the statuses -/// over the `grpc.health.v1.Health` service. -#[derive(Clone, Debug)] -pub struct HealthReporter { - statuses: Arc<RwLock<HashMap<String, StatusPair>>>, -} - -impl HealthReporter { - /// Create a new HealthReporter with an initial service (named ""), corresponding to overall server health - pub fn new() -> Self { - // According to the gRPC Health Check specification, the empty service "" corresponds to the overall server health - let server_status = ("".to_string(), watch::channel(ServingStatus::Serving)); - - let statuses = Arc::new(RwLock::new(HashMap::from([server_status]))); - - HealthReporter { statuses } - } - - /// Sets the status of the service implemented by `S` to `Serving`. This notifies any watchers - /// if there is a change in status. - pub async fn set_serving<S>(&self) - where - S: NamedService, - { - let service_name = <S as NamedService>::NAME; - self.set_service_status(service_name, ServingStatus::Serving) - .await; - } - - /// Sets the status of the service implemented by `S` to `NotServing`. This notifies any watchers - /// if there is a change in status. - pub async fn set_not_serving<S>(&self) - where - S: NamedService, - { - let service_name = <S as NamedService>::NAME; - self.set_service_status(service_name, ServingStatus::NotServing) - .await; - } - - /// Sets the status of the service with `service_name` to `status`. This notifies any watchers - /// if there is a change in status. - pub async fn set_service_status<S>(&self, service_name: S, status: ServingStatus) - where - S: AsRef<str>, - { - let service_name = service_name.as_ref(); - let mut writer = self.statuses.write().await; - match writer.get(service_name) { - Some((tx, _)) => { - // We only ever hand out clones of the receiver, so the originally-created - // receiver should always be present, only being dropped when clearing the - // service status. Consequently, `tx.send` should not fail, making use - // of `expect` here safe. - tx.send(status).expect("channel should not be closed"); - } - None => { - writer.insert(service_name.to_string(), watch::channel(status)); - } - }; - } - - /// Clear the status of the given service. - pub async fn clear_service_status(&mut self, service_name: &str) { - let mut writer = self.statuses.write().await; - let _ = writer.remove(service_name); - } -} - -impl Default for HealthReporter { - fn default() -> Self { - Self::new() - } -} - -/// A service providing implementations of gRPC health checking protocol. -#[derive(Debug)] -pub struct HealthService { - statuses: Arc<RwLock<HashMap<String, StatusPair>>>, -} - -impl HealthService { - fn new(services: Arc<RwLock<HashMap<String, StatusPair>>>) -> Self { - HealthService { statuses: services } - } - - /// Create a HealthService, carrying across the statuses from an existing HealthReporter - pub fn from_health_reporter(health_reporter: HealthReporter) -> Self { - Self::new(health_reporter.statuses) - } - - async fn service_health(&self, service_name: &str) -> Option<ServingStatus> { - let reader = self.statuses.read().await; - reader.get(service_name).map(|p| *p.1.borrow()) - } -} - -#[tonic::async_trait] -impl Health for HealthService { - async fn check( - &self, - request: Request<HealthCheckRequest>, - ) -> Result<Response<HealthCheckResponse>, Status> { - let service_name = request.get_ref().service.as_str(); - let Some(status) = self.service_health(service_name).await else { - return Err(Status::not_found("service not registered")); - }; - - Ok(Response::new(HealthCheckResponse::new(status))) - } - - type WatchStream = WatchStream; - - async fn watch( - &self, - request: Request<HealthCheckRequest>, - ) -> Result<Response<Self::WatchStream>, Status> { - let service_name = request.get_ref().service.as_str(); - let status_rx = match self.statuses.read().await.get(service_name) { - Some((_tx, rx)) => rx.clone(), - None => return Err(Status::not_found("service not registered")), - }; - - Ok(Response::new(WatchStream::new(status_rx))) - } -} - -/// A watch stream for the health service. -pub struct WatchStream { - inner: tokio_stream::wrappers::WatchStream<ServingStatus>, -} - -impl WatchStream { - fn new(status_rx: watch::Receiver<ServingStatus>) -> Self { - let inner = tokio_stream::wrappers::WatchStream::new(status_rx); - Self { inner } - } -} - -impl Stream for WatchStream { - type Item = Result<HealthCheckResponse, Status>; - - fn poll_next( - mut self: std::pin::Pin<&mut Self>, - cx: &mut std::task::Context<'_>, - ) -> std::task::Poll<Option<Self::Item>> { - std::pin::Pin::new(&mut self.inner) - .poll_next(cx) - .map(|opt| opt.map(|status| Ok(HealthCheckResponse::new(status)))) - } -} - -impl fmt::Debug for WatchStream { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - f.debug_struct("WatchStream").finish() - } -} - -impl HealthCheckResponse { - fn new(status: ServingStatus) -> Self { - let status = crate::pb::health_check_response::ServingStatus::from(status) as i32; - Self { status } - } -} - -#[cfg(test)] -mod tests { - use crate::pb::health_server::Health; - use crate::pb::HealthCheckRequest; - use crate::server::{HealthReporter, HealthService}; - use crate::ServingStatus; - use tokio::sync::watch; - use tokio_stream::StreamExt; - use tonic::{Code, Request, Status}; - - fn assert_serving_status(wire: i32, expected: ServingStatus) { - let expected = crate::pb::health_check_response::ServingStatus::from(expected) as i32; - assert_eq!(wire, expected); - } - - fn assert_grpc_status(wire: Option<Status>, expected: Code) { - let wire = wire.expect("status is not None").code(); - assert_eq!(wire, expected); - } - - async fn make_test_service() -> (HealthReporter, HealthService) { - let health_reporter = HealthReporter::new(); - - // insert test value - { - let mut statuses = health_reporter.statuses.write().await; - statuses.insert( - "TestService".to_string(), - watch::channel(ServingStatus::Unknown), - ); - } - - let health_service = HealthService::new(health_reporter.statuses.clone()); - (health_reporter, health_service) - } - - #[tokio::test] - async fn test_service_check() { - let (reporter, service) = make_test_service().await; - - // Overall server health - let resp = service - .check(Request::new(HealthCheckRequest { - service: "".to_string(), - })) - .await; - assert!(resp.is_ok()); - let resp = resp.unwrap().into_inner(); - assert_serving_status(resp.status, ServingStatus::Serving); - - // Unregistered service - let resp = service - .check(Request::new(HealthCheckRequest { - service: "Unregistered".to_string(), - })) - .await; - assert!(resp.is_err()); - assert_grpc_status(resp.err(), Code::NotFound); - - // Registered service - initial state - let resp = service - .check(Request::new(HealthCheckRequest { - service: "TestService".to_string(), - })) - .await; - assert!(resp.is_ok()); - let resp = resp.unwrap().into_inner(); - assert_serving_status(resp.status, ServingStatus::Unknown); - - // Registered service - updated state - reporter - .set_service_status("TestService", ServingStatus::Serving) - .await; - let resp = service - .check(Request::new(HealthCheckRequest { - service: "TestService".to_string(), - })) - .await; - assert!(resp.is_ok()); - let resp = resp.unwrap().into_inner(); - assert_serving_status(resp.status, ServingStatus::Serving); - } - - #[tokio::test] - async fn test_service_watch() { - let (mut reporter, service) = make_test_service().await; - - // Overall server health - let resp = service - .watch(Request::new(HealthCheckRequest { - service: "".to_string(), - })) - .await; - assert!(resp.is_ok()); - let mut resp = resp.unwrap().into_inner(); - let item = resp - .next() - .await - .expect("streamed response is Some") - .expect("response is ok"); - assert_serving_status(item.status, ServingStatus::Serving); - - // Unregistered service - let resp = service - .watch(Request::new(HealthCheckRequest { - service: "Unregistered".to_string(), - })) - .await; - assert!(resp.is_err()); - assert_grpc_status(resp.err(), Code::NotFound); - - // Registered service - let resp = service - .watch(Request::new(HealthCheckRequest { - service: "TestService".to_string(), - })) - .await; - assert!(resp.is_ok()); - let mut resp = resp.unwrap().into_inner(); - - // Registered service - initial state - let item = resp - .next() - .await - .expect("streamed response is Some") - .expect("response is ok"); - assert_serving_status(item.status, ServingStatus::Unknown); - - // Registered service - updated state - reporter - .set_service_status("TestService", ServingStatus::NotServing) - .await; - - let item = resp - .next() - .await - .expect("streamed response is Some") - .expect("response is ok"); - assert_serving_status(item.status, ServingStatus::NotServing); - - // Registered service - updated state - reporter - .set_service_status("TestService", ServingStatus::Serving) - .await; - let item = resp - .next() - .await - .expect("streamed response is Some") - .expect("response is ok"); - assert_serving_status(item.status, ServingStatus::Serving); - - // De-registered service - reporter.clear_service_status("TestService").await; - let item = resp.next().await; - assert!(item.is_none()); - } -} |
