-
Notifications
You must be signed in to change notification settings - Fork 219
feat: volo grpc https rpc ep #553
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
ii64
wants to merge
17
commits into
cloudwego:main
Choose a base branch
from
ii64:feat/volo-grpc-rpc-ep
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from all commits
Commits
Show all changes
17 commits
Select commit
Hold shift + click to select a range
040b381
feat: volo-grpc transport uri extension
ii64 d61a79b
chore: code fmt
ii64 2126f96
Merge pull request #1 from ii64/feat/volo-grpc-uri-ext
ii64 efd7efc
chore: volo-grpc uri extension clone
ii64 046eee0
feat: volo-grpc transport support httpss schema
ii64 46d0c3f
feat: volo-grpc address slot cx passthrough
ii64 3260378
chore: code fmt
ii64 f28f500
chore: code fmt
ii64 b46da3a
feat: use task local to pass Address
ii64 bcc7cf8
feat: volo, volo-grpc tls client config alpn
ii64 5e97f3d
feat: volo-grpc example googleapis https lb rpc endpoint
ii64 173e0a2
chore: code fmt
ii64 863bd49
chore: code fmt
ii64 d817632
chore: code fmt
ii64 519a98e
chore: code fmt
ii64 3e58bf5
fix: required features for example
ii64 e473022
fix: test join path faststr
ii64 File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,61 @@ | ||
| syntax = "proto3"; | ||
|
|
||
| // Source: | ||
| // https://github.com/googleapis/googleapis/blob/df58085901d8fb80c2c021e405923bb2351a6f29/google/cloud/beyondcorp/appgateways/v1/app_gateways_service.proto#L48C9-L48C27 | ||
| // With modification | ||
|
|
||
| package google.cloud.beyondcorp.appgateways.v1; | ||
|
|
||
| service AppGatewaysService { | ||
| // Lists AppGateways in a given project and location. | ||
| rpc ListAppGateways(ListAppGatewaysRequest) | ||
| returns (ListAppGatewaysResponse) { | ||
| } | ||
| } | ||
|
|
||
| // Request message for BeyondCorp.ListAppGateways. | ||
| message ListAppGatewaysRequest { | ||
| // Required. The resource name of the AppGateway location using the form: | ||
| // `projects/{project_id}/locations/{location_id}` | ||
| string parent = 1; | ||
|
|
||
| // Optional. The maximum number of items to return. | ||
| // If not specified, a default value of 50 will be used by the service. | ||
| // Regardless of the page_size value, the response may include a partial list | ||
| // and a caller should only rely on response's | ||
| // [next_page_token][BeyondCorp.ListAppGatewaysResponse.next_page_token] to | ||
| // determine if there are more instances left to be queried. | ||
| int32 page_size = 2; | ||
|
|
||
| // Optional. The next_page_token value returned from a previous | ||
| // ListAppGatewaysRequest, if any. | ||
| string page_token = 3; | ||
|
|
||
| // Optional. A filter specifying constraints of a list operation. | ||
| string filter = 4; | ||
|
|
||
| // Optional. Specifies the ordering of results. See | ||
| // [Sorting | ||
| // order](https://cloud.google.com/apis/design/design_patterns#sorting_order) | ||
| // for more information. | ||
| string order_by = 5; | ||
| } | ||
|
|
||
| // Response message for BeyondCorp.ListAppGateways. | ||
| message ListAppGatewaysResponse { | ||
| // A list of BeyondCorp AppGateways in the project. | ||
| repeated AppGateway app_gateways = 1; | ||
|
|
||
| // A token to retrieve the next page of results, or empty if there are no more | ||
| // results in the list. | ||
| string next_page_token = 2; | ||
|
|
||
| // A list of locations that could not be reached. | ||
| repeated string unreachable = 3; | ||
| } | ||
|
|
||
| message AppGateway { | ||
| // Required. Unique resource name of the AppGateway. | ||
| // The name is ignored when creating an AppGateway. | ||
| string name = 1; | ||
| } |
26 changes: 26 additions & 0 deletions
26
examples/src/grpc/googleapis_beyondcorp_appgateways_v1/client.rs
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,26 @@ | ||
| use rpc_provider::RpcProvider; | ||
| use volo_gen::proto_gen::google::cloud::beyondcorp::appgateways::v1; | ||
|
|
||
| mod discover; | ||
| mod endpoint; | ||
| mod header; | ||
| mod rpc_provider; | ||
|
|
||
| #[volo::main] | ||
| async fn main() { | ||
| let provider = RpcProvider::new(); | ||
|
|
||
| let endpoint = "https://beyondcorp.googleapis.com:443/".parse().unwrap(); | ||
| let client = provider.app_gateway_service(endpoint); | ||
|
|
||
| let req = volo_grpc::Request::new(v1::ListAppGatewaysRequest { | ||
| parent: "".into(), | ||
| page_size: 20, | ||
| filter: "".into(), | ||
| order_by: "".into(), | ||
| page_token: "".into(), | ||
| }); | ||
|
|
||
| let resp = client.list_app_gateways(req).await; | ||
| println!("resp = {:#?}", resp); | ||
| } | ||
59 changes: 59 additions & 0 deletions
59
examples/src/grpc/googleapis_beyondcorp_appgateways_v1/discover/constant_dns.rs
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,59 @@ | ||
| use std::sync::Arc; | ||
|
|
||
| use anyhow::anyhow; | ||
| use async_broadcast::Receiver; | ||
| use volo::{ | ||
| context::Endpoint, | ||
| discovery::{Discover, Instance}, | ||
| loadbalance::error::LoadBalanceError, | ||
| }; | ||
| use volo_http::client::dns::DnsResolver; | ||
|
|
||
| #[derive(Clone)] | ||
| pub struct ConstantDnsDiscover { | ||
| resolver: DnsResolver, | ||
| service_name: String, | ||
| host: String, | ||
| port: u16, | ||
| } | ||
|
|
||
| impl ConstantDnsDiscover { | ||
| pub fn new(resolver: DnsResolver, service_name: String, host: String, port: u16) -> Self { | ||
| Self { | ||
| resolver, | ||
| service_name, | ||
| host, | ||
| port, | ||
| } | ||
| } | ||
| } | ||
|
|
||
| impl Discover for ConstantDnsDiscover { | ||
| type Key = (); | ||
| type Error = LoadBalanceError; | ||
|
|
||
| async fn discover<'s>( | ||
| &'s self, | ||
| _endpoint: &'s Endpoint, | ||
| ) -> Result<Vec<Arc<Instance>>, Self::Error> { | ||
| let mut endpoint = Endpoint::new(self.service_name.clone().into()); | ||
| let addr = self | ||
| .resolver | ||
| .resolve(&self.host, self.port) | ||
| .await | ||
| .ok_or_else(|| { | ||
| LoadBalanceError::Discover(anyhow!("unable to resolve: {}", &self.host).into()) | ||
| })?; | ||
| endpoint.set_address(addr); | ||
| self.resolver.discover(&endpoint).await | ||
| } | ||
|
|
||
| fn key(&self, _endpoint: &Endpoint) -> Self::Key {} | ||
|
|
||
| fn watch( | ||
| &self, | ||
| _keys: Option<&[Self::Key]>, | ||
| ) -> Option<Receiver<volo::discovery::Change<Self::Key>>> { | ||
| None | ||
| } | ||
| } |
86 changes: 86 additions & 0 deletions
86
examples/src/grpc/googleapis_beyondcorp_appgateways_v1/discover/mod.rs
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,86 @@ | ||
| use std::{ | ||
| net::{SocketAddr, SocketAddrV4, SocketAddrV6}, | ||
| sync::Arc, | ||
| }; | ||
|
|
||
| use constant_dns::ConstantDnsDiscover; | ||
| use url::Host; | ||
| use volo::{ | ||
| context::Endpoint, | ||
| discovery::{Discover, Instance, StaticDiscover}, | ||
| loadbalance::error::LoadBalanceError, | ||
| net::Address, | ||
| }; | ||
| use volo_http::client::dns::DnsResolver; | ||
|
|
||
| use super::endpoint::RpcEndpoint; | ||
|
|
||
| pub mod constant_dns; | ||
|
|
||
| struct LazyDiscoverInternal { | ||
| endpoint: RpcEndpoint, | ||
| resolver: DnsResolver, | ||
| } | ||
|
|
||
| #[derive(Clone)] | ||
| pub struct LazyDiscover { | ||
| inner: Arc<LazyDiscoverInternal>, | ||
| } | ||
|
|
||
| impl LazyDiscover { | ||
| pub fn new(endpoint: RpcEndpoint) -> Self { | ||
| let resolver = DnsResolver::default(); | ||
| Self { | ||
| inner: Arc::new(LazyDiscoverInternal { endpoint, resolver }), | ||
| } | ||
| } | ||
| } | ||
|
|
||
| impl Discover for LazyDiscover { | ||
| type Key = (); | ||
| type Error = LoadBalanceError; | ||
|
|
||
| async fn discover<'s>( | ||
| &'s self, | ||
| endpoint: &'s Endpoint, | ||
| ) -> Result<Vec<Arc<Instance>>, Self::Error> { | ||
| let ep = self.inner.endpoint.clone(); | ||
| match ep.host { | ||
| Host::Domain(domain) => { | ||
| ConstantDnsDiscover::new( | ||
| self.inner.resolver.clone(), | ||
| domain.clone(), | ||
| domain, | ||
| ep.port, | ||
| ) | ||
| .discover(endpoint) | ||
| .await | ||
| } | ||
| Host::Ipv4(ip) => StaticDiscover::new(vec![Arc::new(Instance { | ||
| address: Address::Ip(SocketAddr::V4(SocketAddrV4::new(ip, ep.port))), | ||
| weight: 1, | ||
| tags: Default::default(), | ||
| })]) | ||
| .discover(endpoint) | ||
| .await | ||
| .map_err(|_e| LoadBalanceError::Retry), | ||
| Host::Ipv6(ip) => StaticDiscover::new(vec![Arc::new(Instance { | ||
| address: Address::Ip(SocketAddr::V6(SocketAddrV6::new(ip, ep.port, 0, 0))), | ||
| weight: 1, | ||
| tags: Default::default(), | ||
| })]) | ||
| .discover(endpoint) | ||
| .await | ||
| .map_err(|_e| LoadBalanceError::Retry), | ||
| } | ||
| } | ||
|
|
||
| fn key(&self, _endpoint: &volo::context::Endpoint) -> Self::Key {} | ||
|
|
||
| fn watch( | ||
| &self, | ||
| _keys: Option<&[Self::Key]>, | ||
| ) -> Option<async_broadcast::Receiver<volo::discovery::Change<Self::Key>>> { | ||
| None | ||
| } | ||
| } |
63 changes: 63 additions & 0 deletions
63
examples/src/grpc/googleapis_beyondcorp_appgateways_v1/endpoint.rs
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,63 @@ | ||
| use std::str::FromStr; | ||
|
|
||
| use anyhow::anyhow; | ||
| use url::{Host, Url}; | ||
|
|
||
| #[derive(Clone, PartialEq, Eq, Debug)] | ||
| pub struct RpcEndpoint { | ||
| pub host: Host, | ||
| pub port: u16, | ||
| pub server_name: Option<String>, | ||
| pub tls: bool, | ||
| } | ||
|
|
||
| impl RpcEndpoint { | ||
| pub fn parse(s: &str) -> Result<RpcEndpoint, anyhow::Error> { | ||
| let u = Url::parse(s)?; | ||
| let host = match u.host().ok_or_else(|| anyhow!("missing host"))? { | ||
| Host::Domain(domain) => Host::Domain(domain.to_string()), | ||
| Host::Ipv4(ip) => Host::Ipv4(ip), | ||
| Host::Ipv6(ip) => Host::Ipv6(ip), | ||
| }; | ||
|
|
||
| let port = u | ||
| .port_or_known_default() | ||
| .ok_or_else(|| anyhow!("unknown schema for port"))?; | ||
| let server_name = if let Host::Domain(ref server_name) = host { | ||
| Some(server_name.clone()) | ||
| } else { | ||
| None | ||
| }; | ||
|
|
||
| let tls = ["https", "tls", "xds"].contains(&u.scheme()); | ||
|
|
||
| Ok(RpcEndpoint { | ||
| host, | ||
| port, | ||
| server_name, | ||
| tls, | ||
| }) | ||
| } | ||
|
|
||
| pub fn uri(&self) -> http::Uri { | ||
| let scheme = if self.tls { "https" } else { "http" }; | ||
| let authority = match (scheme, self.port) { | ||
| ("https", 443) | ("http", 80) => self.host.to_string(), | ||
| _ => format!("{}:{}", self.host.to_string(), self.port), | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. unnecessary to_string()? |
||
| }; | ||
| http::Uri::builder() | ||
| .scheme(scheme) | ||
| .authority(authority) | ||
| .path_and_query("/") | ||
| .build() | ||
| .expect("rpc endpoint uri build") | ||
| } | ||
| } | ||
|
|
||
| impl FromStr for RpcEndpoint { | ||
| type Err = anyhow::Error; | ||
|
|
||
| fn from_str(s: &str) -> Result<Self, Self::Err> { | ||
| Self::parse(s) | ||
| } | ||
| } | ||
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What output can we expect to verify?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This one expect a gRPC status application level error, unauthorized - but that passes the gRPC deserialization