This is an automated email from the ASF dual-hosted git repository. liujun pushed a commit to branch poc-idl in repository https://gitbox.apache.org/repos/asf/dubbo-rust.git
commit 3a8b693202320650fe138aed80bc656677b635ab Author: johankoi <[email protected]> AuthorDate: Wed Jun 15 00:47:16 2022 +0800 feat: protobuf example Signed-off-by: johankoi <[email protected]> --- Cargo.toml | 1 + examples/protobuf/client/Cargo.toml | 3 ++ examples/protobuf/client/src/main.rs | 19 +++++++++-- .../protobuf/{client => pb_message}/Cargo.toml | 8 +++-- examples/protobuf/pb_message/build.rs | 18 +++++++++++ examples/protobuf/pb_message/pb/greeter.proto | 14 ++++++++ examples/protobuf/pb_message/pb/person.proto | 26 +++++++++++++++ examples/protobuf/pb_message/src/lib.rs | 37 ++++++++++++++++++++++ examples/protobuf/pb_message/src/pb/greeter.rs | 10 ++++++ examples/protobuf/pb_message/src/pb/mod.rs | 5 +++ examples/protobuf/pb_message/src/pb/person.rs | 35 ++++++++++++++++++++ xds/src/client/client.rs | 11 ++++--- xds/src/lib.rs | 2 +- xds/src/server/server.rs | 5 +-- 14 files changed, 181 insertions(+), 13 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index f73b8c4..0fe1fd2 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -8,4 +8,5 @@ members = [ "config", "examples/protobuf/client", "examples/protobuf/server", + "examples/protobuf/pb_message", ] \ No newline at end of file diff --git a/examples/protobuf/client/Cargo.toml b/examples/protobuf/client/Cargo.toml index b0bbc6e..e4c426c 100644 --- a/examples/protobuf/client/Cargo.toml +++ b/examples/protobuf/client/Cargo.toml @@ -8,4 +8,7 @@ edition = "2021" [dependencies] xds = { version = "0.1.0", path = "../../../xds" } tokio = {version = "1.9.0", features = ["full"]} +pb_message = { version = "0.1.0", path = "../pb_message" } +prost = "0.10.4" +hyper = { version = "0.14", features = ["full"] } diff --git a/examples/protobuf/client/src/main.rs b/examples/protobuf/client/src/main.rs index 0ae5d6a..bd6507f 100644 --- a/examples/protobuf/client/src/main.rs +++ b/examples/protobuf/client/src/main.rs @@ -1,16 +1,31 @@ use std::collections::hash_map::HashMap; use xds::{ client::RpcClient }; +use pb_message::pb::person::Person; +use prost::Message; +use hyper::body::Buf; #[tokio::main] async fn main() { let task = tokio::spawn(async move { let mut client = RpcClient::new(String::from("http://127.0.0.1:8972")); - println!("client call begin"); let service_path = String::from("helloworld"); let service_method = String::from("hello"); let metadata = HashMap::new(); - client.call(service_path, service_method, &metadata).await; + + let mut person = Person::default(); + person.name = "guomiwu".to_string(); + let pbData = person.encode_to_vec(); + + let callResult = client.call(service_path, service_method, &metadata, pbData).await; + let resp = callResult.unwrap(); + + // asynchronously aggregate the chunks of the body + let body = hyper::body::aggregate(resp).await; + let data = body.unwrap().chunk().to_vec(); + + let resPerson = Person::decode(data.as_ref()).unwrap(); + println!("resPerson={:?}", resPerson.name); }); task.await.unwrap(); diff --git a/examples/protobuf/client/Cargo.toml b/examples/protobuf/pb_message/Cargo.toml similarity index 57% copy from examples/protobuf/client/Cargo.toml copy to examples/protobuf/pb_message/Cargo.toml index b0bbc6e..f4a97cd 100644 --- a/examples/protobuf/client/Cargo.toml +++ b/examples/protobuf/pb_message/Cargo.toml @@ -1,11 +1,13 @@ [package] -name = "protobuf" +name = "pb_message" version = "0.1.0" edition = "2021" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] -xds = { version = "0.1.0", path = "../../../xds" } -tokio = {version = "1.9.0", features = ["full"]} +prost = "0.10.4" +prost-types = "0.10.1" +[build-dependencies] +prost-build = "0.10.4" \ No newline at end of file diff --git a/examples/protobuf/pb_message/build.rs b/examples/protobuf/pb_message/build.rs new file mode 100644 index 0000000..a198077 --- /dev/null +++ b/examples/protobuf/pb_message/build.rs @@ -0,0 +1,18 @@ +use std::io::Result; +use prost_build::Config; + +fn main() -> Result<()> { + + Config::new() + .out_dir("src/pb") + .compile_protos(&["pb/person.proto"], &["pb/"])?; + + // println!("cargo:rerun-if-changed=pb/greeter_rpc.pb"); + // println!("cargo:rerun-if-changed=pb/build.rs"); + + Config::new() + .out_dir("src/pb") + .compile_protos(&["pb/greeter.proto"], &["pb/"])?; + + Ok(()) +} \ No newline at end of file diff --git a/examples/protobuf/pb_message/pb/greeter.proto b/examples/protobuf/pb_message/pb/greeter.proto new file mode 100644 index 0000000..0d7f9fc --- /dev/null +++ b/examples/protobuf/pb_message/pb/greeter.proto @@ -0,0 +1,14 @@ +syntax = "proto3"; +package greeter; + +message HelloRequest { + string name = 1; +} + +message HelloResponse { + string message = 1; +} + +service Greeter { + rpc SayHello (HelloRequest) returns (HelloResponse); +} \ No newline at end of file diff --git a/examples/protobuf/pb_message/pb/person.proto b/examples/protobuf/pb_message/pb/person.proto new file mode 100644 index 0000000..d322c14 --- /dev/null +++ b/examples/protobuf/pb_message/pb/person.proto @@ -0,0 +1,26 @@ +syntax = "proto3"; +package person; + +message Person { + string name = 1; + int32 id = 2; // Unique ID number for this person. + string email = 3; + + enum PhoneType { + MOBILE = 0; + HOME = 1; + WORK = 2; + } + + message PhoneNumber { + string number = 1; + PhoneType type = 2; + } + + repeated PhoneNumber phones = 4; +} + +// Our address book file is just one of these. +message AddressBook { + repeated Person people = 1; +} \ No newline at end of file diff --git a/examples/protobuf/pb_message/src/lib.rs b/examples/protobuf/pb_message/src/lib.rs new file mode 100644 index 0000000..3a90aed --- /dev/null +++ b/examples/protobuf/pb_message/src/lib.rs @@ -0,0 +1,37 @@ + +pub mod pb; + +#[cfg(test)] +mod tests { + use crate::pb::Person; + use crate::pb::greeter; + + use std::io::Cursor; + use prost::Message; + + pub fn create_hello_request(name: String) -> greeter::HelloRequest { + let mut hello_request = greeter::HelloRequest::default(); + hello_request.name = name; + hello_request + } + + pub fn serialize_greeter(hello: &greeter::HelloRequest) -> Vec<u8> { + let mut buf = Vec::new(); + buf.reserve(hello.encoded_len()); + + hello.encode(&mut buf).unwrap(); + buf + } + + + // pub fn deserialize_greeter(buf: &[u8]) -> Result<greeter::HelloRequest, prost::DecodeError> { + // greeter::HelloRequest::decode(&mut Cursor::new(buf)) + // } + + #[test] + fn it_works() { + let person = Person::default(); + person.encode_to_vec(); + println!("{person:?}"); + } +} diff --git a/examples/protobuf/pb_message/src/pb/greeter.rs b/examples/protobuf/pb_message/src/pb/greeter.rs new file mode 100644 index 0000000..36aa34d --- /dev/null +++ b/examples/protobuf/pb_message/src/pb/greeter.rs @@ -0,0 +1,10 @@ +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct HelloRequest { + #[prost(string, tag="1")] + pub name: ::prost::alloc::string::String, +} +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct HelloResponse { + #[prost(string, tag="1")] + pub message: ::prost::alloc::string::String, +} diff --git a/examples/protobuf/pb_message/src/pb/mod.rs b/examples/protobuf/pb_message/src/pb/mod.rs new file mode 100644 index 0000000..8c11e43 --- /dev/null +++ b/examples/protobuf/pb_message/src/pb/mod.rs @@ -0,0 +1,5 @@ +pub mod person; +pub mod greeter; + +pub use person::*; +pub use greeter::*; \ No newline at end of file diff --git a/examples/protobuf/pb_message/src/pb/person.rs b/examples/protobuf/pb_message/src/pb/person.rs new file mode 100644 index 0000000..c45d257 --- /dev/null +++ b/examples/protobuf/pb_message/src/pb/person.rs @@ -0,0 +1,35 @@ +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct Person { + #[prost(string, tag="1")] + pub name: ::prost::alloc::string::String, + /// Unique ID number for this person. + #[prost(int32, tag="2")] + pub id: i32, + #[prost(string, tag="3")] + pub email: ::prost::alloc::string::String, + #[prost(message, repeated, tag="4")] + pub phones: ::prost::alloc::vec::Vec<person::PhoneNumber>, +} +/// Nested message and enum types in `Person`. +pub mod person { + #[derive(Clone, PartialEq, ::prost::Message)] + pub struct PhoneNumber { + #[prost(string, tag="1")] + pub number: ::prost::alloc::string::String, + #[prost(enumeration="PhoneType", tag="2")] + pub r#type: i32, + } + #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, ::prost::Enumeration)] + #[repr(i32)] + pub enum PhoneType { + Mobile = 0, + Home = 1, + Work = 2, + } +} +/// Our address book file is just one of these. +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct AddressBook { + #[prost(message, repeated, tag="1")] + pub people: ::prost::alloc::vec::Vec<Person>, +} diff --git a/xds/src/client/client.rs b/xds/src/client/client.rs index 4cad8f3..1387e36 100644 --- a/xds/src/client/client.rs +++ b/xds/src/client/client.rs @@ -19,7 +19,7 @@ use hyper::client::conn::Builder; use hyper::client::connect::HttpConnector; use hyper::client::service::Connect; use hyper::service::Service; -use hyper::{Body, Request}; +use hyper::{Body, Request, Response}; use crate::protocol::message::*; use std::collections::HashMap; @@ -40,8 +40,9 @@ impl RpcClient { &mut self, service_path: String, service_method: String, - metadata: &Metadata - ) -> std::result::Result<(), Box<dyn std::error::Error + Send + Sync>> + metadata: &Metadata, + payload: Vec<u8> + ) -> std::result::Result<Response<Body>, Box<dyn std::error::Error + Send + Sync>> { let mut req = Message::new(); req.set_version(0); @@ -50,6 +51,7 @@ impl RpcClient { req.set_compress_type(CompressType::Gzip); req.service_path = service_path; req.service_method = service_method; + req.payload = payload; let mut new_metadata = HashMap::with_capacity(metadata.len()); for (k, v) in metadata { @@ -67,9 +69,8 @@ impl RpcClient { let body = Body::from(body_data); let req = Request::get(uri.clone()).body(body)?; let res = svc.call(req).await?; - println!("RESPONSE={:?}", res.body()); - Ok(()) + Ok(res) } } diff --git a/xds/src/lib.rs b/xds/src/lib.rs index 736d111..4f818f9 100644 --- a/xds/src/lib.rs +++ b/xds/src/lib.rs @@ -17,7 +17,7 @@ pub mod client; pub mod server; -mod protocol; +pub mod protocol; #[cfg(test)] mod tests { diff --git a/xds/src/server/server.rs b/xds/src/server/server.rs index be343fb..dd8930a 100644 --- a/xds/src/server/server.rs +++ b/xds/src/server/server.rs @@ -70,22 +70,23 @@ impl Service<Request<Body>> for RPCHandler { fn call(&mut self, req: Request<Body>) -> Self::Future { Box::pin(async move { let whole_body = hyper::body::to_bytes(req.into_body()).await.unwrap(); - let mut msg = Message::new(); let mut data = &whole_body[..]; + let mut resp = ready(Ok(Response::new(Body::from("hello world with tower service! \n")))).await; match msg.decode(&mut data) { Ok(()) => { let service_path = &msg.service_path; let service_method = &msg.service_method; let key = format!("{}.{}", service_path, service_method); + println!("{:?}", msg.payload); println!("recieved request success, and body message decode key is: {:?}", key); + resp = ready(Ok(Response::new(Body::from(msg.payload)))).await; } Err(err) => { eprintln!("failed to read: {}", err.to_string()); } } - let resp = ready(Ok(Response::new(Body::from("hello world with tower service! \n")))).await; resp }) }
