You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@dubbo.apache.org by li...@apache.org on 2022/07/23 14:44:02 UTC

[dubbo-rust] branch main updated (e71b961 -> fd2958a)

This is an automated email from the ASF dual-hosted git repository.

liujun pushed a change to branch main
in repository https://gitbox.apache.org/repos/asf/dubbo-rust.git


    from e71b961  Merge pull request #15 from apache/dependabot/cargo/dubbo/prost-types-0.8.0
     new fb37cf2  feat(triple): impl triple protocol based json serialization
     new 6337143  style: cargo check
     new b6e165f  refactor(triple): add prost codec, start server by config
     new 891b189  style: add license header
     new 5c0ff91  Merge branch 'apache:main' into main
     new 3f8a62a  chore: ignore some file: cargo.lock, target
     new fd2958a  Merge pull request #21 from yang20150702/main

The 38 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.


Summary of changes:
 .gitignore                                         |   4 +-
 Cargo.toml                                         |   3 +-
 config/src/config.rs                               | 107 +++
 config/src/lib.rs                                  |   6 +
 .../grpc_exporter.rs => config/src/protocol.rs     |  38 +-
 config/src/service.rs                              |  74 ++
 dubbo/Cargo.lock                                   | 914 ---------------------
 dubbo/Cargo.toml                                   |  11 +-
 dubbo/src/common/url.rs                            |   2 +-
 dubbo/src/echo/echo_client.rs                      |  73 ++
 dubbo/src/echo/echo_server.rs                      | 220 +++++
 dubbo/src/{helloworld => echo}/helloworld.rs       | 229 +++---
 dubbo/src/echo/mod.rs                              | 264 ++++++
 dubbo/src/lib.rs                                   |   7 +
 dubbo/src/main.rs                                  |   9 +
 dubbo/src/protocol/grpc/grpc_protocol.rs           |   2 +-
 dubbo/src/protocol/grpc/grpc_server.rs             |   2 +-
 dubbo/src/protocol/invocation.rs                   |  44 +
 dubbo/src/protocol/mod.rs                          |  11 +-
 .../src/protocol/{server_desc.rs => triple/mod.rs} |  35 +-
 .../grpc_exporter.rs => triple/triple_exporter.rs} |  36 +-
 .../grpc_exporter.rs => triple/triple_invoker.rs}  |  43 +-
 dubbo/src/protocol/triple/triple_protocol.rs       |  71 ++
 dubbo/src/protocol/triple/triple_server.rs         |  61 ++
 {dubbo => triple}/Cargo.toml                       |  20 +-
 triple/readme.md                                   |  15 +
 triple/src/client/grpc.rs                          | 205 +++++
 {dubbo/src/helloworld => triple/src/client}/mod.rs |   4 +-
 triple/src/codec/buffer.rs                         | 138 ++++
 triple/src/codec/mod.rs                            |  72 ++
 triple/src/codec/prost.rs                          | 253 ++++++
 triple/src/codec/serde_codec.rs                    |  89 ++
 triple/src/invocation.rs                           | 148 ++++
 dubbo/src/main.rs => triple/src/lib.rs             |  22 +-
 {dubbo => triple}/src/main.rs                      |  24 +-
 config/src/lib.rs => triple/src/server/consts.rs   |  15 +-
 triple/src/server/decode.rs                        | 165 ++++
 triple/src/server/encode.rs                        | 168 ++++
 dubbo/src/main.rs => triple/src/server/mod.rs      |  15 +-
 triple/src/server/server.rs                        | 112 +++
 triple/src/server/service.rs                       |  68 ++
 .../src/helloworld => triple/src/transport}/mod.rs |   4 +-
 triple/src/transport/service.rs                    | 183 +++++
 43 files changed, 2848 insertions(+), 1138 deletions(-)
 create mode 100644 config/src/config.rs
 copy dubbo/src/protocol/grpc/grpc_exporter.rs => config/src/protocol.rs (56%)
 create mode 100644 config/src/service.rs
 delete mode 100644 dubbo/Cargo.lock
 create mode 100644 dubbo/src/echo/echo_client.rs
 create mode 100644 dubbo/src/echo/echo_server.rs
 copy dubbo/src/{helloworld => echo}/helloworld.rs (51%)
 create mode 100644 dubbo/src/echo/mod.rs
 copy dubbo/src/protocol/{server_desc.rs => triple/mod.rs} (55%)
 copy dubbo/src/protocol/{grpc/grpc_exporter.rs => triple/triple_exporter.rs} (64%)
 copy dubbo/src/protocol/{grpc/grpc_exporter.rs => triple/triple_invoker.rs} (57%)
 create mode 100644 dubbo/src/protocol/triple/triple_protocol.rs
 create mode 100644 dubbo/src/protocol/triple/triple_server.rs
 copy {dubbo => triple}/Cargo.toml (60%)
 create mode 100644 triple/readme.md
 create mode 100644 triple/src/client/grpc.rs
 copy {dubbo/src/helloworld => triple/src/client}/mod.rs (94%)
 create mode 100644 triple/src/codec/buffer.rs
 create mode 100644 triple/src/codec/mod.rs
 create mode 100644 triple/src/codec/prost.rs
 create mode 100644 triple/src/codec/serde_codec.rs
 create mode 100644 triple/src/invocation.rs
 copy dubbo/src/main.rs => triple/src/lib.rs (67%)
 copy {dubbo => triple}/src/main.rs (65%)
 copy config/src/lib.rs => triple/src/server/consts.rs (80%)
 create mode 100644 triple/src/server/decode.rs
 create mode 100644 triple/src/server/encode.rs
 copy dubbo/src/main.rs => triple/src/server/mod.rs (84%)
 create mode 100644 triple/src/server/server.rs
 create mode 100644 triple/src/server/service.rs
 copy {dubbo/src/helloworld => triple/src/transport}/mod.rs (94%)
 create mode 100644 triple/src/transport/service.rs


[dubbo-rust] 37/38: chore: ignore some file: cargo.lock, target

Posted by li...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

liujun pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/dubbo-rust.git

commit 3f8a62ae5f63126b878a12d46c32b990bc3ab849
Author: yangyang <96...@qq.com>
AuthorDate: Thu Jul 21 22:01:41 2022 +0800

    chore: ignore some file: cargo.lock, target
---
 .gitignore       |   4 +-
 dubbo/Cargo.lock | 914 -------------------------------------------------------
 2 files changed, 2 insertions(+), 916 deletions(-)

diff --git a/.gitignore b/.gitignore
index 386dbf6..ee96157 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,5 +1,5 @@
-/target
-/Cargo.lock
+target
+Cargo.lock
 **/*.rs.bk
 .vscode/
 .idea/
diff --git a/dubbo/Cargo.lock b/dubbo/Cargo.lock
deleted file mode 100644
index 5c4a6d9..0000000
--- a/dubbo/Cargo.lock
+++ /dev/null
@@ -1,914 +0,0 @@
-# This file is automatically @generated by Cargo.
-# It is not intended for manual editing.
-version = 3
-
-[[package]]
-name = "adler"
-version = "1.0.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe"
-
-[[package]]
-name = "anyhow"
-version = "1.0.57"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "08f9b8508dccb7687a1d6c4ce66b2b0ecef467c94667de27d8d7fe1f8d2a9cdc"
-
-[[package]]
-name = "async-stream"
-version = "0.3.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "dad5c83079eae9969be7fadefe640a1c566901f05ff91ab221de4b6f68d9507e"
-dependencies = [
- "async-stream-impl",
- "futures-core",
-]
-
-[[package]]
-name = "async-stream-impl"
-version = "0.3.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "10f203db73a71dfa2fb6dd22763990fa26f3d2625a6da2da900d23b87d26be27"
-dependencies = [
- "proc-macro2",
- "quote",
- "syn",
-]
-
-[[package]]
-name = "async-trait"
-version = "0.1.56"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "96cf8829f67d2eab0b2dfa42c5d0ef737e0724e4a82b01b3e292456202b19716"
-dependencies = [
- "proc-macro2",
- "quote",
- "syn",
-]
-
-[[package]]
-name = "autocfg"
-version = "1.1.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa"
-
-[[package]]
-name = "axum"
-version = "0.5.7"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "dc47084705629d09d15060d70a8dbfce479c842303d05929ce29c74c995916ae"
-dependencies = [
- "async-trait",
- "axum-core",
- "bitflags",
- "bytes",
- "futures-util",
- "http",
- "http-body",
- "hyper",
- "itoa",
- "matchit",
- "memchr",
- "mime",
- "percent-encoding",
- "pin-project-lite",
- "serde",
- "sync_wrapper",
- "tokio",
- "tower",
- "tower-http",
- "tower-layer",
- "tower-service",
-]
-
-[[package]]
-name = "axum-core"
-version = "0.2.5"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c2efed1c501becea07ce48118786ebcf229531d0d3b28edf224a720020d9e106"
-dependencies = [
- "async-trait",
- "bytes",
- "futures-util",
- "http",
- "http-body",
- "mime",
-]
-
-[[package]]
-name = "base64"
-version = "0.13.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "904dfeac50f3cdaba28fc6f57fdcddb75f49ed61346676a78c4ffe55877802fd"
-
-[[package]]
-name = "bitflags"
-version = "1.3.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
-
-[[package]]
-name = "bytes"
-version = "1.1.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c4872d67bab6358e59559027aa3b9157c53d9358c51423c17554809a8858e0f8"
-
-[[package]]
-name = "cfg-if"
-version = "1.0.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
-
-[[package]]
-name = "crc32fast"
-version = "1.3.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b540bd8bc810d3885c6ea91e2018302f68baba2129ab3e88f32389ee9370880d"
-dependencies = [
- "cfg-if",
-]
-
-[[package]]
-name = "dubbo"
-version = "0.1.0"
-dependencies = [
- "async-trait",
- "futures-util",
- "h2",
- "http",
- "http-body",
- "hyper",
- "lazy_static",
- "prost 0.10.4",
- "prost-derive 0.10.1",
- "prost-types",
- "tokio",
- "tonic",
- "tower",
- "tower-layer",
- "tower-service",
-]
-
-[[package]]
-name = "either"
-version = "1.6.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e78d4f1cc4ae33bbfc157ed5d5a5ef3bc29227303d595861deb238fcec4e9457"
-
-[[package]]
-name = "flate2"
-version = "1.0.24"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f82b0f4c27ad9f8bfd1f3208d882da2b09c301bc1c828fd3a00d0216d2fbbff6"
-dependencies = [
- "crc32fast",
- "miniz_oxide",
-]
-
-[[package]]
-name = "fnv"
-version = "1.0.7"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1"
-
-[[package]]
-name = "futures-channel"
-version = "0.3.21"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c3083ce4b914124575708913bca19bfe887522d6e2e6d0952943f5eac4a74010"
-dependencies = [
- "futures-core",
-]
-
-[[package]]
-name = "futures-core"
-version = "0.3.21"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0c09fd04b7e4073ac7156a9539b57a484a8ea920f79c7c675d05d289ab6110d3"
-
-[[package]]
-name = "futures-sink"
-version = "0.3.21"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "21163e139fa306126e6eedaf49ecdb4588f939600f0b1e770f4205ee4b7fa868"
-
-[[package]]
-name = "futures-task"
-version = "0.3.21"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "57c66a976bf5909d801bbef33416c41372779507e7a6b3a5e25e4749c58f776a"
-
-[[package]]
-name = "futures-util"
-version = "0.3.21"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d8b7abd5d659d9b90c8cba917f6ec750a74e2dc23902ef9cd4cc8c8b22e6036a"
-dependencies = [
- "futures-core",
- "futures-task",
- "pin-project-lite",
- "pin-utils",
-]
-
-[[package]]
-name = "getrandom"
-version = "0.2.7"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4eb1a864a501629691edf6c15a593b7a51eebaa1e8468e9ddc623de7c9b58ec6"
-dependencies = [
- "cfg-if",
- "libc",
- "wasi",
-]
-
-[[package]]
-name = "h2"
-version = "0.3.13"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "37a82c6d637fc9515a4694bbf1cb2457b79d81ce52b3108bdeea58b07dd34a57"
-dependencies = [
- "bytes",
- "fnv",
- "futures-core",
- "futures-sink",
- "futures-util",
- "http",
- "indexmap",
- "slab",
- "tokio",
- "tokio-util",
- "tracing",
-]
-
-[[package]]
-name = "hashbrown"
-version = "0.11.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ab5ef0d4909ef3724cc8cce6ccc8572c5c817592e9285f5464f8e86f8bd3726e"
-
-[[package]]
-name = "hermit-abi"
-version = "0.1.19"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33"
-dependencies = [
- "libc",
-]
-
-[[package]]
-name = "http"
-version = "0.2.8"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "75f43d41e26995c17e71ee126451dd3941010b0514a81a9d11f3b341debc2399"
-dependencies = [
- "bytes",
- "fnv",
- "itoa",
-]
-
-[[package]]
-name = "http-body"
-version = "0.4.5"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d5f38f16d184e36f2408a55281cd658ecbd3ca05cce6d6510a176eca393e26d1"
-dependencies = [
- "bytes",
- "http",
- "pin-project-lite",
-]
-
-[[package]]
-name = "http-range-header"
-version = "0.3.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0bfe8eed0a9285ef776bb792479ea3834e8b94e13d615c2f66d03dd50a435a29"
-
-[[package]]
-name = "httparse"
-version = "1.7.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "496ce29bb5a52785b44e0f7ca2847ae0bb839c9bd28f69acac9b99d461c0c04c"
-
-[[package]]
-name = "httpdate"
-version = "1.0.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c4a1e36c821dbe04574f602848a19f742f4fb3c98d40449f11bcad18d6b17421"
-
-[[package]]
-name = "hyper"
-version = "0.14.19"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "42dc3c131584288d375f2d07f822b0cb012d8c6fb899a5b9fdb3cb7eb9b6004f"
-dependencies = [
- "bytes",
- "futures-channel",
- "futures-core",
- "futures-util",
- "h2",
- "http",
- "http-body",
- "httparse",
- "httpdate",
- "itoa",
- "pin-project-lite",
- "socket2",
- "tokio",
- "tower-service",
- "tracing",
- "want",
-]
-
-[[package]]
-name = "hyper-timeout"
-version = "0.4.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "bbb958482e8c7be4bc3cf272a766a2b0bf1a6755e7a6ae777f017a31d11b13b1"
-dependencies = [
- "hyper",
- "pin-project-lite",
- "tokio",
- "tokio-io-timeout",
-]
-
-[[package]]
-name = "indexmap"
-version = "1.8.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e6012d540c5baa3589337a98ce73408de9b5a25ec9fc2c6fd6be8f0d39e0ca5a"
-dependencies = [
- "autocfg",
- "hashbrown",
-]
-
-[[package]]
-name = "itertools"
-version = "0.10.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a9a9d19fa1e79b6215ff29b9d6880b706147f16e9b1dbb1e4e5947b5b02bc5e3"
-dependencies = [
- "either",
-]
-
-[[package]]
-name = "itoa"
-version = "1.0.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "112c678d4050afce233f4f2852bb2eb519230b3cf12f33585275537d7e41578d"
-
-[[package]]
-name = "lazy_static"
-version = "1.4.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
-
-[[package]]
-name = "libc"
-version = "0.2.126"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "349d5a591cd28b49e1d1037471617a32ddcda5731b99419008085f72d5a53836"
-
-[[package]]
-name = "log"
-version = "0.4.17"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "abb12e687cfb44aa40f41fc3978ef76448f9b6038cad6aef4259d3c095a2382e"
-dependencies = [
- "cfg-if",
-]
-
-[[package]]
-name = "matchit"
-version = "0.5.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "73cbba799671b762df5a175adf59ce145165747bb891505c43d09aefbbf38beb"
-
-[[package]]
-name = "memchr"
-version = "2.5.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d"
-
-[[package]]
-name = "mime"
-version = "0.3.16"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2a60c7ce501c71e03a9c9c0d35b861413ae925bd979cc7a4e30d060069aaac8d"
-
-[[package]]
-name = "miniz_oxide"
-version = "0.5.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6f5c75688da582b8ffc1f1799e9db273f32133c49e048f614d22ec3256773ccc"
-dependencies = [
- "adler",
-]
-
-[[package]]
-name = "mio"
-version = "0.8.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "713d550d9b44d89174e066b7a6217ae06234c10cb47819a88290d2b353c31799"
-dependencies = [
- "libc",
- "log",
- "wasi",
- "windows-sys",
-]
-
-[[package]]
-name = "num_cpus"
-version = "1.13.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "19e64526ebdee182341572e50e9ad03965aa510cd94427a4549448f285e957a1"
-dependencies = [
- "hermit-abi",
- "libc",
-]
-
-[[package]]
-name = "once_cell"
-version = "1.12.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7709cef83f0c1f58f666e746a08b21e0085f7440fa6a29cc194d68aac97a4225"
-
-[[package]]
-name = "percent-encoding"
-version = "2.1.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d4fd5641d01c8f18a23da7b6fe29298ff4b55afcccdf78973b24cf3175fee32e"
-
-[[package]]
-name = "pin-project"
-version = "1.0.10"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "58ad3879ad3baf4e44784bc6a718a8698867bb991f8ce24d1bcbe2cfb4c3a75e"
-dependencies = [
- "pin-project-internal",
-]
-
-[[package]]
-name = "pin-project-internal"
-version = "1.0.10"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "744b6f092ba29c3650faf274db506afd39944f48420f6c86b17cfe0ee1cb36bb"
-dependencies = [
- "proc-macro2",
- "quote",
- "syn",
-]
-
-[[package]]
-name = "pin-project-lite"
-version = "0.2.9"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e0a7ae3ac2f1173085d398531c705756c94a4c56843785df85a60c1a0afac116"
-
-[[package]]
-name = "pin-utils"
-version = "0.1.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184"
-
-[[package]]
-name = "ppv-lite86"
-version = "0.2.16"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "eb9f9e6e233e5c4a35559a617bf40a4ec447db2e84c20b55a6f83167b7e57872"
-
-[[package]]
-name = "proc-macro2"
-version = "1.0.39"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c54b25569025b7fc9651de43004ae593a75ad88543b17178aa5e1b9c4f15f56f"
-dependencies = [
- "unicode-ident",
-]
-
-[[package]]
-name = "prost"
-version = "0.8.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "de5e2533f59d08fcf364fd374ebda0692a70bd6d7e66ef97f306f45c6c5d8020"
-dependencies = [
- "bytes",
- "prost-derive 0.8.0",
-]
-
-[[package]]
-name = "prost"
-version = "0.10.4"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "71adf41db68aa0daaefc69bb30bcd68ded9b9abaad5d1fbb6304c4fb390e083e"
-dependencies = [
- "bytes",
- "prost-derive 0.10.1",
-]
-
-[[package]]
-name = "prost-derive"
-version = "0.8.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "600d2f334aa05acb02a755e217ef1ab6dea4d51b58b7846588b747edec04efba"
-dependencies = [
- "anyhow",
- "itertools",
- "proc-macro2",
- "quote",
- "syn",
-]
-
-[[package]]
-name = "prost-derive"
-version = "0.10.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7b670f45da57fb8542ebdbb6105a925fe571b67f9e7ed9f47a06a84e72b4e7cc"
-dependencies = [
- "anyhow",
- "itertools",
- "proc-macro2",
- "quote",
- "syn",
-]
-
-[[package]]
-name = "prost-types"
-version = "0.8.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "603bbd6394701d13f3f25aada59c7de9d35a6a5887cfc156181234a44002771b"
-dependencies = [
- "bytes",
- "prost 0.8.0",
-]
-
-[[package]]
-name = "quote"
-version = "1.0.18"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a1feb54ed693b93a84e14094943b84b7c4eae204c512b7ccb95ab0c66d278ad1"
-dependencies = [
- "proc-macro2",
-]
-
-[[package]]
-name = "rand"
-version = "0.8.5"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404"
-dependencies = [
- "libc",
- "rand_chacha",
- "rand_core",
-]
-
-[[package]]
-name = "rand_chacha"
-version = "0.3.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88"
-dependencies = [
- "ppv-lite86",
- "rand_core",
-]
-
-[[package]]
-name = "rand_core"
-version = "0.6.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d34f1408f55294453790c48b2f1ebbb1c5b4b7563eb1f418bcfcfdbb06ebb4e7"
-dependencies = [
- "getrandom",
-]
-
-[[package]]
-name = "serde"
-version = "1.0.137"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "61ea8d54c77f8315140a05f4c7237403bf38b72704d031543aa1d16abbf517d1"
-
-[[package]]
-name = "signal-hook-registry"
-version = "1.4.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e51e73328dc4ac0c7ccbda3a494dfa03df1de2f46018127f60c693f2648455b0"
-dependencies = [
- "libc",
-]
-
-[[package]]
-name = "slab"
-version = "0.4.6"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "eb703cfe953bccee95685111adeedb76fabe4e97549a58d16f03ea7b9367bb32"
-
-[[package]]
-name = "socket2"
-version = "0.4.4"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "66d72b759436ae32898a2af0a14218dbf55efde3feeb170eb623637db85ee1e0"
-dependencies = [
- "libc",
- "winapi",
-]
-
-[[package]]
-name = "syn"
-version = "1.0.96"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0748dd251e24453cb8717f0354206b91557e4ec8703673a4b30208f2abaf1ebf"
-dependencies = [
- "proc-macro2",
- "quote",
- "unicode-ident",
-]
-
-[[package]]
-name = "sync_wrapper"
-version = "0.1.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "20518fe4a4c9acf048008599e464deb21beeae3d3578418951a189c235a7a9a8"
-
-[[package]]
-name = "tokio"
-version = "1.19.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c51a52ed6686dd62c320f9b89299e9dfb46f730c7a48e635c19f21d116cb1439"
-dependencies = [
- "bytes",
- "libc",
- "memchr",
- "mio",
- "num_cpus",
- "once_cell",
- "pin-project-lite",
- "signal-hook-registry",
- "socket2",
- "tokio-macros",
- "winapi",
-]
-
-[[package]]
-name = "tokio-io-timeout"
-version = "1.2.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "30b74022ada614a1b4834de765f9bb43877f910cc8ce4be40e89042c9223a8bf"
-dependencies = [
- "pin-project-lite",
- "tokio",
-]
-
-[[package]]
-name = "tokio-macros"
-version = "1.8.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9724f9a975fb987ef7a3cd9be0350edcbe130698af5b8f7a631e23d42d052484"
-dependencies = [
- "proc-macro2",
- "quote",
- "syn",
-]
-
-[[package]]
-name = "tokio-stream"
-version = "0.1.9"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "df54d54117d6fdc4e4fea40fe1e4e566b3505700e148a6827e59b34b0d2600d9"
-dependencies = [
- "futures-core",
- "pin-project-lite",
- "tokio",
-]
-
-[[package]]
-name = "tokio-util"
-version = "0.7.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "cc463cd8deddc3770d20f9852143d50bf6094e640b485cb2e189a2099085ff45"
-dependencies = [
- "bytes",
- "futures-core",
- "futures-sink",
- "pin-project-lite",
- "tokio",
- "tracing",
-]
-
-[[package]]
-name = "tonic"
-version = "0.7.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5be9d60db39854b30b835107500cf0aca0b0d14d6e1c3de124217c23a29c2ddb"
-dependencies = [
- "async-stream",
- "async-trait",
- "axum",
- "base64",
- "bytes",
- "flate2",
- "futures-core",
- "futures-util",
- "h2",
- "http",
- "http-body",
- "hyper",
- "hyper-timeout",
- "percent-encoding",
- "pin-project",
- "prost 0.10.4",
- "prost-derive 0.10.1",
- "tokio",
- "tokio-stream",
- "tokio-util",
- "tower",
- "tower-layer",
- "tower-service",
- "tracing",
- "tracing-futures",
-]
-
-[[package]]
-name = "tower"
-version = "0.4.12"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9a89fd63ad6adf737582df5db40d286574513c69a11dac5214dc3b5603d6713e"
-dependencies = [
- "futures-core",
- "futures-util",
- "indexmap",
- "pin-project",
- "pin-project-lite",
- "rand",
- "slab",
- "tokio",
- "tokio-util",
- "tower-layer",
- "tower-service",
- "tracing",
-]
-
-[[package]]
-name = "tower-http"
-version = "0.3.4"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3c530c8675c1dbf98facee631536fa116b5fb6382d7dd6dc1b118d970eafe3ba"
-dependencies = [
- "bitflags",
- "bytes",
- "futures-core",
- "futures-util",
- "http",
- "http-body",
- "http-range-header",
- "pin-project-lite",
- "tower",
- "tower-layer",
- "tower-service",
-]
-
-[[package]]
-name = "tower-layer"
-version = "0.3.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "343bc9466d3fe6b0f960ef45960509f84480bf4fd96f92901afe7ff3df9d3a62"
-
-[[package]]
-name = "tower-service"
-version = "0.3.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "360dfd1d6d30e05fda32ace2c8c70e9c0a9da713275777f5a4dbb8a1893930c6"
-
-[[package]]
-name = "tracing"
-version = "0.1.35"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a400e31aa60b9d44a52a8ee0343b5b18566b03a8321e0d321f695cf56e940160"
-dependencies = [
- "cfg-if",
- "log",
- "pin-project-lite",
- "tracing-attributes",
- "tracing-core",
-]
-
-[[package]]
-name = "tracing-attributes"
-version = "0.1.21"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "cc6b8ad3567499f98a1db7a752b07a7c8c7c7c34c332ec00effb2b0027974b7c"
-dependencies = [
- "proc-macro2",
- "quote",
- "syn",
-]
-
-[[package]]
-name = "tracing-core"
-version = "0.1.27"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7709595b8878a4965ce5e87ebf880a7d39c9afc6837721b21a5a816a8117d921"
-dependencies = [
- "once_cell",
-]
-
-[[package]]
-name = "tracing-futures"
-version = "0.2.5"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "97d095ae15e245a057c8e8451bab9b3ee1e1f68e9ba2b4fbc18d0ac5237835f2"
-dependencies = [
- "pin-project",
- "tracing",
-]
-
-[[package]]
-name = "try-lock"
-version = "0.2.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "59547bce71d9c38b83d9c0e92b6066c4253371f15005def0c30d9657f50c7642"
-
-[[package]]
-name = "unicode-ident"
-version = "1.0.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5bd2fe26506023ed7b5e1e315add59d6f584c621d037f9368fea9cfb988f368c"
-
-[[package]]
-name = "want"
-version = "0.3.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1ce8a968cb1cd110d136ff8b819a556d6fb6d919363c61534f6860c7eb172ba0"
-dependencies = [
- "log",
- "try-lock",
-]
-
-[[package]]
-name = "wasi"
-version = "0.11.0+wasi-snapshot-preview1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423"
-
-[[package]]
-name = "winapi"
-version = "0.3.9"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419"
-dependencies = [
- "winapi-i686-pc-windows-gnu",
- "winapi-x86_64-pc-windows-gnu",
-]
-
-[[package]]
-name = "winapi-i686-pc-windows-gnu"
-version = "0.4.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
-
-[[package]]
-name = "winapi-x86_64-pc-windows-gnu"
-version = "0.4.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
-
-[[package]]
-name = "windows-sys"
-version = "0.36.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ea04155a16a59f9eab786fe12a4a450e75cdb175f9e0d80da1e17db09f55b8d2"
-dependencies = [
- "windows_aarch64_msvc",
- "windows_i686_gnu",
- "windows_i686_msvc",
- "windows_x86_64_gnu",
- "windows_x86_64_msvc",
-]
-
-[[package]]
-name = "windows_aarch64_msvc"
-version = "0.36.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9bb8c3fd39ade2d67e9874ac4f3db21f0d710bee00fe7cab16949ec184eeaa47"
-
-[[package]]
-name = "windows_i686_gnu"
-version = "0.36.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "180e6ccf01daf4c426b846dfc66db1fc518f074baa793aa7d9b9aaeffad6a3b6"
-
-[[package]]
-name = "windows_i686_msvc"
-version = "0.36.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e2e7917148b2812d1eeafaeb22a97e4813dfa60a3f8f78ebe204bcc88f12f024"
-
-[[package]]
-name = "windows_x86_64_gnu"
-version = "0.36.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4dcd171b8776c41b97521e5da127a2d86ad280114807d0b2ab1e462bc764d9e1"
-
-[[package]]
-name = "windows_x86_64_msvc"
-version = "0.36.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c811ca4a8c853ef420abd8592ba53ddbbac90410fab6903b3e79972a631f7680"


[dubbo-rust] 28/38: Merge pull request #13 from yang20150702/main

Posted by li...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

liujun pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/dubbo-rust.git

commit 0e35ae003417da3d36cb8303dfdf7c1d79d63951
Merge: 69249f0 9588657
Author: ken.lj <ke...@gmail.com>
AuthorDate: Wed Jul 6 17:40:07 2022 +0800

    Merge pull request #13 from yang20150702/main
    
    feat: API of protocol module

 Cargo.toml                                         |   4 +-
 docs/filter-design.md                              |   0
 docs/generic-protocol-design.md                    |  35 +
 docs/readme.md                                     |   3 +
 dubbo/Cargo.lock                                   | 929 +++++++++++++++++++++
 dubbo/Cargo.toml                                   |  28 +
 dubbo/readme.md                                    |   1 +
 protocol/src/lib.rs => dubbo/src/common/mod.rs     |   9 +-
 protocol/src/lib.rs => dubbo/src/common/url.rs     |  11 +-
 .../src/lib.rs => dubbo/src/helloworld/client.rs   |  29 +-
 dubbo/src/helloworld/helloworld.rs                 | 270 ++++++
 protocol/src/lib.rs => dubbo/src/helloworld/mod.rs |   9 +-
 .../src/lib.rs => dubbo/src/helloworld/server.rs   |   9 -
 {protocol => dubbo}/src/lib.rs                     |  12 +-
 protocol/src/lib.rs => dubbo/src/main.rs           |  15 +-
 .../src/protocol/grpc/grpc_exporter.rs             |  33 +-
 dubbo/src/protocol/grpc/grpc_invoker.rs            |  88 ++
 dubbo/src/protocol/grpc/grpc_protocol.rs           |  76 ++
 dubbo/src/protocol/grpc/grpc_server.rs             | 107 +++
 dubbo/src/protocol/grpc/mod.rs                     |  87 ++
 .../src/lib.rs => dubbo/src/protocol/invocation.rs |  45 +-
 dubbo/src/protocol/mod.rs                          |  55 ++
 .../lib.rs => dubbo/src/protocol/server_desc.rs    |  30 +-
 dubbo/src/utils/boxed.rs                           |  91 ++
 dubbo/src/utils/boxed_clone.rs                     | 110 +++
 protocol/src/lib.rs => dubbo/src/utils/mod.rs      |  10 +-
 protocol/Cargo.toml                                |   8 -
 27 files changed, 2014 insertions(+), 90 deletions(-)


[dubbo-rust] 12/38: Enable Github Actions CI workflow #6

Posted by li...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

liujun pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/dubbo-rust.git

commit 1f5fb8eebe11b0ad48e8e6e62acce969372a331f
Merge: 28eab63 2e73b00
Author: ken.lj <ke...@gmail.com>
AuthorDate: Fri May 6 11:02:36 2022 +0800

    Enable Github Actions CI workflow #6
    
    Fix edition and add workflow

 .github/workflows/CI.yml | 54 ++++++++++++++++++++++++++++++++++++++++++++++++
 common/Cargo.toml        |  2 +-
 config/Cargo.toml        |  2 +-
 metadata/Cargo.toml      |  2 +-
 protocol/Cargo.toml      |  2 +-
 registry/Cargo.toml      |  2 +-
 xds/Cargo.toml           |  2 +-
 7 files changed, 60 insertions(+), 6 deletions(-)


[dubbo-rust] 21/38: feat(dubbo): define the API of protocol module, provide simple impl of tonic(grpc)

Posted by li...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

liujun pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/dubbo-rust.git

commit e03e4cd915ba76d2b977a0b3f952ce6843e510b4
Author: yang <96...@qq.com>
AuthorDate: Sun Jun 26 22:51:01 2022 +0800

    feat(dubbo): define the API of protocol module, provide simple impl of tonic(grpc)
---
 Cargo.toml                              |   2 +-
 dubbo/Cargo.lock                        | 929 ++++++++++++++++++++++++++++++++
 dubbo/Cargo.toml                        |  28 +
 dubbo/readme.md                         |   1 +
 dubbo/src/common/mod.rs                 |   1 +
 dubbo/src/common/url.rs                 |   5 +
 dubbo/src/helloworld/client.rs          |  23 +
 dubbo/src/helloworld/helloworld.rs      | 272 ++++++++++
 dubbo/src/helloworld/mod.rs             |   1 +
 dubbo/src/helloworld/server.rs          |   0
 dubbo/src/lib.rs                        |   6 +
 dubbo/src/main.rs                       |  10 +
 dubbo/src/service/grpc/grpc_exporter.rs |  34 ++
 dubbo/src/service/grpc/grpc_invoker.rs  |  73 +++
 dubbo/src/service/grpc/grpc_protocol.rs |  60 +++
 dubbo/src/service/grpc/grpc_server.rs   | 116 ++++
 dubbo/src/service/grpc/mod.rs           |  59 ++
 dubbo/src/service/invocation.rs         |  45 ++
 dubbo/src/service/mod.rs                |   4 +
 dubbo/src/service/protocol.rs           |  31 ++
 dubbo/src/utils/boxed.rs                |  74 +++
 dubbo/src/utils/boxed_clone.rs          |  88 +++
 dubbo/src/utils/mod.rs                  |   2 +
 protocol/Cargo.toml                     |   8 -
 protocol/src/lib.rs                     |  25 -
 25 files changed, 1863 insertions(+), 34 deletions(-)

diff --git a/Cargo.toml b/Cargo.toml
index 3720b7d..8c2e58e 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -1,9 +1,9 @@
 [workspace]
 members = [
   "xds",
-  "protocol",
   "registry",
   "metadata",
   "common",
   "config",
+  "dubbo"
 ]
\ No newline at end of file
diff --git a/dubbo/Cargo.lock b/dubbo/Cargo.lock
new file mode 100644
index 0000000..a69c71b
--- /dev/null
+++ b/dubbo/Cargo.lock
@@ -0,0 +1,929 @@
+# This file is automatically @generated by Cargo.
+# It is not intended for manual editing.
+version = 3
+
+[[package]]
+name = "adler"
+version = "1.0.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe"
+
+[[package]]
+name = "anyhow"
+version = "1.0.57"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "08f9b8508dccb7687a1d6c4ce66b2b0ecef467c94667de27d8d7fe1f8d2a9cdc"
+
+[[package]]
+name = "async-stream"
+version = "0.3.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "dad5c83079eae9969be7fadefe640a1c566901f05ff91ab221de4b6f68d9507e"
+dependencies = [
+ "async-stream-impl",
+ "futures-core",
+]
+
+[[package]]
+name = "async-stream-impl"
+version = "0.3.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "10f203db73a71dfa2fb6dd22763990fa26f3d2625a6da2da900d23b87d26be27"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn",
+]
+
+[[package]]
+name = "async-trait"
+version = "0.1.56"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "96cf8829f67d2eab0b2dfa42c5d0ef737e0724e4a82b01b3e292456202b19716"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn",
+]
+
+[[package]]
+name = "autocfg"
+version = "1.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa"
+
+[[package]]
+name = "axum"
+version = "0.5.7"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "dc47084705629d09d15060d70a8dbfce479c842303d05929ce29c74c995916ae"
+dependencies = [
+ "async-trait",
+ "axum-core",
+ "bitflags",
+ "bytes 1.1.0",
+ "futures-util",
+ "http",
+ "http-body",
+ "hyper",
+ "itoa",
+ "matchit",
+ "memchr",
+ "mime",
+ "percent-encoding",
+ "pin-project-lite",
+ "serde",
+ "sync_wrapper",
+ "tokio",
+ "tower",
+ "tower-http",
+ "tower-layer",
+ "tower-service",
+]
+
+[[package]]
+name = "axum-core"
+version = "0.2.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c2efed1c501becea07ce48118786ebcf229531d0d3b28edf224a720020d9e106"
+dependencies = [
+ "async-trait",
+ "bytes 1.1.0",
+ "futures-util",
+ "http",
+ "http-body",
+ "mime",
+]
+
+[[package]]
+name = "base64"
+version = "0.13.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "904dfeac50f3cdaba28fc6f57fdcddb75f49ed61346676a78c4ffe55877802fd"
+
+[[package]]
+name = "bitflags"
+version = "1.3.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
+
+[[package]]
+name = "bytes"
+version = "0.5.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0e4cec68f03f32e44924783795810fa50a7035d8c8ebe78580ad7e6c703fba38"
+
+[[package]]
+name = "bytes"
+version = "1.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c4872d67bab6358e59559027aa3b9157c53d9358c51423c17554809a8858e0f8"
+
+[[package]]
+name = "cfg-if"
+version = "1.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
+
+[[package]]
+name = "crc32fast"
+version = "1.3.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b540bd8bc810d3885c6ea91e2018302f68baba2129ab3e88f32389ee9370880d"
+dependencies = [
+ "cfg-if",
+]
+
+[[package]]
+name = "dubbo"
+version = "0.1.0"
+dependencies = [
+ "async-trait",
+ "futures-util",
+ "h2",
+ "http",
+ "http-body",
+ "hyper",
+ "lazy_static",
+ "prost 0.10.4",
+ "prost-derive 0.10.1",
+ "prost-types",
+ "tokio",
+ "tonic",
+ "tower",
+ "tower-layer",
+ "tower-service",
+]
+
+[[package]]
+name = "either"
+version = "1.6.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e78d4f1cc4ae33bbfc157ed5d5a5ef3bc29227303d595861deb238fcec4e9457"
+
+[[package]]
+name = "flate2"
+version = "1.0.24"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f82b0f4c27ad9f8bfd1f3208d882da2b09c301bc1c828fd3a00d0216d2fbbff6"
+dependencies = [
+ "crc32fast",
+ "miniz_oxide",
+]
+
+[[package]]
+name = "fnv"
+version = "1.0.7"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1"
+
+[[package]]
+name = "futures-channel"
+version = "0.3.21"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c3083ce4b914124575708913bca19bfe887522d6e2e6d0952943f5eac4a74010"
+dependencies = [
+ "futures-core",
+]
+
+[[package]]
+name = "futures-core"
+version = "0.3.21"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0c09fd04b7e4073ac7156a9539b57a484a8ea920f79c7c675d05d289ab6110d3"
+
+[[package]]
+name = "futures-sink"
+version = "0.3.21"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "21163e139fa306126e6eedaf49ecdb4588f939600f0b1e770f4205ee4b7fa868"
+
+[[package]]
+name = "futures-task"
+version = "0.3.21"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "57c66a976bf5909d801bbef33416c41372779507e7a6b3a5e25e4749c58f776a"
+
+[[package]]
+name = "futures-util"
+version = "0.3.21"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d8b7abd5d659d9b90c8cba917f6ec750a74e2dc23902ef9cd4cc8c8b22e6036a"
+dependencies = [
+ "futures-core",
+ "futures-task",
+ "pin-project-lite",
+ "pin-utils",
+]
+
+[[package]]
+name = "getrandom"
+version = "0.2.7"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4eb1a864a501629691edf6c15a593b7a51eebaa1e8468e9ddc623de7c9b58ec6"
+dependencies = [
+ "cfg-if",
+ "libc",
+ "wasi",
+]
+
+[[package]]
+name = "h2"
+version = "0.3.13"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "37a82c6d637fc9515a4694bbf1cb2457b79d81ce52b3108bdeea58b07dd34a57"
+dependencies = [
+ "bytes 1.1.0",
+ "fnv",
+ "futures-core",
+ "futures-sink",
+ "futures-util",
+ "http",
+ "indexmap",
+ "slab",
+ "tokio",
+ "tokio-util",
+ "tracing",
+]
+
+[[package]]
+name = "hashbrown"
+version = "0.11.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ab5ef0d4909ef3724cc8cce6ccc8572c5c817592e9285f5464f8e86f8bd3726e"
+
+[[package]]
+name = "hermit-abi"
+version = "0.1.19"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33"
+dependencies = [
+ "libc",
+]
+
+[[package]]
+name = "http"
+version = "0.2.8"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "75f43d41e26995c17e71ee126451dd3941010b0514a81a9d11f3b341debc2399"
+dependencies = [
+ "bytes 1.1.0",
+ "fnv",
+ "itoa",
+]
+
+[[package]]
+name = "http-body"
+version = "0.4.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d5f38f16d184e36f2408a55281cd658ecbd3ca05cce6d6510a176eca393e26d1"
+dependencies = [
+ "bytes 1.1.0",
+ "http",
+ "pin-project-lite",
+]
+
+[[package]]
+name = "http-range-header"
+version = "0.3.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0bfe8eed0a9285ef776bb792479ea3834e8b94e13d615c2f66d03dd50a435a29"
+
+[[package]]
+name = "httparse"
+version = "1.7.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "496ce29bb5a52785b44e0f7ca2847ae0bb839c9bd28f69acac9b99d461c0c04c"
+
+[[package]]
+name = "httpdate"
+version = "1.0.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c4a1e36c821dbe04574f602848a19f742f4fb3c98d40449f11bcad18d6b17421"
+
+[[package]]
+name = "hyper"
+version = "0.14.19"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "42dc3c131584288d375f2d07f822b0cb012d8c6fb899a5b9fdb3cb7eb9b6004f"
+dependencies = [
+ "bytes 1.1.0",
+ "futures-channel",
+ "futures-core",
+ "futures-util",
+ "h2",
+ "http",
+ "http-body",
+ "httparse",
+ "httpdate",
+ "itoa",
+ "pin-project-lite",
+ "socket2",
+ "tokio",
+ "tower-service",
+ "tracing",
+ "want",
+]
+
+[[package]]
+name = "hyper-timeout"
+version = "0.4.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "bbb958482e8c7be4bc3cf272a766a2b0bf1a6755e7a6ae777f017a31d11b13b1"
+dependencies = [
+ "hyper",
+ "pin-project-lite",
+ "tokio",
+ "tokio-io-timeout",
+]
+
+[[package]]
+name = "indexmap"
+version = "1.8.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e6012d540c5baa3589337a98ce73408de9b5a25ec9fc2c6fd6be8f0d39e0ca5a"
+dependencies = [
+ "autocfg",
+ "hashbrown",
+]
+
+[[package]]
+name = "itertools"
+version = "0.8.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f56a2d0bc861f9165be4eb3442afd3c236d8a98afd426f65d92324ae1091a484"
+dependencies = [
+ "either",
+]
+
+[[package]]
+name = "itertools"
+version = "0.10.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a9a9d19fa1e79b6215ff29b9d6880b706147f16e9b1dbb1e4e5947b5b02bc5e3"
+dependencies = [
+ "either",
+]
+
+[[package]]
+name = "itoa"
+version = "1.0.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "112c678d4050afce233f4f2852bb2eb519230b3cf12f33585275537d7e41578d"
+
+[[package]]
+name = "lazy_static"
+version = "1.4.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
+
+[[package]]
+name = "libc"
+version = "0.2.126"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "349d5a591cd28b49e1d1037471617a32ddcda5731b99419008085f72d5a53836"
+
+[[package]]
+name = "log"
+version = "0.4.17"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "abb12e687cfb44aa40f41fc3978ef76448f9b6038cad6aef4259d3c095a2382e"
+dependencies = [
+ "cfg-if",
+]
+
+[[package]]
+name = "matchit"
+version = "0.5.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "73cbba799671b762df5a175adf59ce145165747bb891505c43d09aefbbf38beb"
+
+[[package]]
+name = "memchr"
+version = "2.5.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d"
+
+[[package]]
+name = "mime"
+version = "0.3.16"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "2a60c7ce501c71e03a9c9c0d35b861413ae925bd979cc7a4e30d060069aaac8d"
+
+[[package]]
+name = "miniz_oxide"
+version = "0.5.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6f5c75688da582b8ffc1f1799e9db273f32133c49e048f614d22ec3256773ccc"
+dependencies = [
+ "adler",
+]
+
+[[package]]
+name = "mio"
+version = "0.8.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "713d550d9b44d89174e066b7a6217ae06234c10cb47819a88290d2b353c31799"
+dependencies = [
+ "libc",
+ "log",
+ "wasi",
+ "windows-sys",
+]
+
+[[package]]
+name = "num_cpus"
+version = "1.13.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "19e64526ebdee182341572e50e9ad03965aa510cd94427a4549448f285e957a1"
+dependencies = [
+ "hermit-abi",
+ "libc",
+]
+
+[[package]]
+name = "once_cell"
+version = "1.12.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7709cef83f0c1f58f666e746a08b21e0085f7440fa6a29cc194d68aac97a4225"
+
+[[package]]
+name = "percent-encoding"
+version = "2.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d4fd5641d01c8f18a23da7b6fe29298ff4b55afcccdf78973b24cf3175fee32e"
+
+[[package]]
+name = "pin-project"
+version = "1.0.10"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "58ad3879ad3baf4e44784bc6a718a8698867bb991f8ce24d1bcbe2cfb4c3a75e"
+dependencies = [
+ "pin-project-internal",
+]
+
+[[package]]
+name = "pin-project-internal"
+version = "1.0.10"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "744b6f092ba29c3650faf274db506afd39944f48420f6c86b17cfe0ee1cb36bb"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn",
+]
+
+[[package]]
+name = "pin-project-lite"
+version = "0.2.9"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e0a7ae3ac2f1173085d398531c705756c94a4c56843785df85a60c1a0afac116"
+
+[[package]]
+name = "pin-utils"
+version = "0.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184"
+
+[[package]]
+name = "ppv-lite86"
+version = "0.2.16"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "eb9f9e6e233e5c4a35559a617bf40a4ec447db2e84c20b55a6f83167b7e57872"
+
+[[package]]
+name = "proc-macro2"
+version = "1.0.39"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c54b25569025b7fc9651de43004ae593a75ad88543b17178aa5e1b9c4f15f56f"
+dependencies = [
+ "unicode-ident",
+]
+
+[[package]]
+name = "prost"
+version = "0.6.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ce49aefe0a6144a45de32927c77bd2859a5f7677b55f220ae5b744e87389c212"
+dependencies = [
+ "bytes 0.5.6",
+ "prost-derive 0.6.1",
+]
+
+[[package]]
+name = "prost"
+version = "0.10.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "71adf41db68aa0daaefc69bb30bcd68ded9b9abaad5d1fbb6304c4fb390e083e"
+dependencies = [
+ "bytes 1.1.0",
+ "prost-derive 0.10.1",
+]
+
+[[package]]
+name = "prost-derive"
+version = "0.6.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "537aa19b95acde10a12fec4301466386f757403de4cd4e5b4fa78fb5ecb18f72"
+dependencies = [
+ "anyhow",
+ "itertools 0.8.2",
+ "proc-macro2",
+ "quote",
+ "syn",
+]
+
+[[package]]
+name = "prost-derive"
+version = "0.10.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7b670f45da57fb8542ebdbb6105a925fe571b67f9e7ed9f47a06a84e72b4e7cc"
+dependencies = [
+ "anyhow",
+ "itertools 0.10.3",
+ "proc-macro2",
+ "quote",
+ "syn",
+]
+
+[[package]]
+name = "prost-types"
+version = "0.6.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1834f67c0697c001304b75be76f67add9c89742eda3a085ad8ee0bb38c3417aa"
+dependencies = [
+ "bytes 0.5.6",
+ "prost 0.6.1",
+]
+
+[[package]]
+name = "quote"
+version = "1.0.18"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a1feb54ed693b93a84e14094943b84b7c4eae204c512b7ccb95ab0c66d278ad1"
+dependencies = [
+ "proc-macro2",
+]
+
+[[package]]
+name = "rand"
+version = "0.8.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404"
+dependencies = [
+ "libc",
+ "rand_chacha",
+ "rand_core",
+]
+
+[[package]]
+name = "rand_chacha"
+version = "0.3.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88"
+dependencies = [
+ "ppv-lite86",
+ "rand_core",
+]
+
+[[package]]
+name = "rand_core"
+version = "0.6.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d34f1408f55294453790c48b2f1ebbb1c5b4b7563eb1f418bcfcfdbb06ebb4e7"
+dependencies = [
+ "getrandom",
+]
+
+[[package]]
+name = "serde"
+version = "1.0.137"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "61ea8d54c77f8315140a05f4c7237403bf38b72704d031543aa1d16abbf517d1"
+
+[[package]]
+name = "signal-hook-registry"
+version = "1.4.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e51e73328dc4ac0c7ccbda3a494dfa03df1de2f46018127f60c693f2648455b0"
+dependencies = [
+ "libc",
+]
+
+[[package]]
+name = "slab"
+version = "0.4.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "eb703cfe953bccee95685111adeedb76fabe4e97549a58d16f03ea7b9367bb32"
+
+[[package]]
+name = "socket2"
+version = "0.4.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "66d72b759436ae32898a2af0a14218dbf55efde3feeb170eb623637db85ee1e0"
+dependencies = [
+ "libc",
+ "winapi",
+]
+
+[[package]]
+name = "syn"
+version = "1.0.96"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0748dd251e24453cb8717f0354206b91557e4ec8703673a4b30208f2abaf1ebf"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "unicode-ident",
+]
+
+[[package]]
+name = "sync_wrapper"
+version = "0.1.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "20518fe4a4c9acf048008599e464deb21beeae3d3578418951a189c235a7a9a8"
+
+[[package]]
+name = "tokio"
+version = "1.19.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c51a52ed6686dd62c320f9b89299e9dfb46f730c7a48e635c19f21d116cb1439"
+dependencies = [
+ "bytes 1.1.0",
+ "libc",
+ "memchr",
+ "mio",
+ "num_cpus",
+ "once_cell",
+ "pin-project-lite",
+ "signal-hook-registry",
+ "socket2",
+ "tokio-macros",
+ "winapi",
+]
+
+[[package]]
+name = "tokio-io-timeout"
+version = "1.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "30b74022ada614a1b4834de765f9bb43877f910cc8ce4be40e89042c9223a8bf"
+dependencies = [
+ "pin-project-lite",
+ "tokio",
+]
+
+[[package]]
+name = "tokio-macros"
+version = "1.8.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9724f9a975fb987ef7a3cd9be0350edcbe130698af5b8f7a631e23d42d052484"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn",
+]
+
+[[package]]
+name = "tokio-stream"
+version = "0.1.9"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "df54d54117d6fdc4e4fea40fe1e4e566b3505700e148a6827e59b34b0d2600d9"
+dependencies = [
+ "futures-core",
+ "pin-project-lite",
+ "tokio",
+]
+
+[[package]]
+name = "tokio-util"
+version = "0.7.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "cc463cd8deddc3770d20f9852143d50bf6094e640b485cb2e189a2099085ff45"
+dependencies = [
+ "bytes 1.1.0",
+ "futures-core",
+ "futures-sink",
+ "pin-project-lite",
+ "tokio",
+ "tracing",
+]
+
+[[package]]
+name = "tonic"
+version = "0.7.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5be9d60db39854b30b835107500cf0aca0b0d14d6e1c3de124217c23a29c2ddb"
+dependencies = [
+ "async-stream",
+ "async-trait",
+ "axum",
+ "base64",
+ "bytes 1.1.0",
+ "flate2",
+ "futures-core",
+ "futures-util",
+ "h2",
+ "http",
+ "http-body",
+ "hyper",
+ "hyper-timeout",
+ "percent-encoding",
+ "pin-project",
+ "prost 0.10.4",
+ "prost-derive 0.10.1",
+ "tokio",
+ "tokio-stream",
+ "tokio-util",
+ "tower",
+ "tower-layer",
+ "tower-service",
+ "tracing",
+ "tracing-futures",
+]
+
+[[package]]
+name = "tower"
+version = "0.4.12"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9a89fd63ad6adf737582df5db40d286574513c69a11dac5214dc3b5603d6713e"
+dependencies = [
+ "futures-core",
+ "futures-util",
+ "indexmap",
+ "pin-project",
+ "pin-project-lite",
+ "rand",
+ "slab",
+ "tokio",
+ "tokio-util",
+ "tower-layer",
+ "tower-service",
+ "tracing",
+]
+
+[[package]]
+name = "tower-http"
+version = "0.3.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3c530c8675c1dbf98facee631536fa116b5fb6382d7dd6dc1b118d970eafe3ba"
+dependencies = [
+ "bitflags",
+ "bytes 1.1.0",
+ "futures-core",
+ "futures-util",
+ "http",
+ "http-body",
+ "http-range-header",
+ "pin-project-lite",
+ "tower",
+ "tower-layer",
+ "tower-service",
+]
+
+[[package]]
+name = "tower-layer"
+version = "0.3.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "343bc9466d3fe6b0f960ef45960509f84480bf4fd96f92901afe7ff3df9d3a62"
+
+[[package]]
+name = "tower-service"
+version = "0.3.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "360dfd1d6d30e05fda32ace2c8c70e9c0a9da713275777f5a4dbb8a1893930c6"
+
+[[package]]
+name = "tracing"
+version = "0.1.35"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a400e31aa60b9d44a52a8ee0343b5b18566b03a8321e0d321f695cf56e940160"
+dependencies = [
+ "cfg-if",
+ "log",
+ "pin-project-lite",
+ "tracing-attributes",
+ "tracing-core",
+]
+
+[[package]]
+name = "tracing-attributes"
+version = "0.1.21"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "cc6b8ad3567499f98a1db7a752b07a7c8c7c7c34c332ec00effb2b0027974b7c"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn",
+]
+
+[[package]]
+name = "tracing-core"
+version = "0.1.27"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7709595b8878a4965ce5e87ebf880a7d39c9afc6837721b21a5a816a8117d921"
+dependencies = [
+ "once_cell",
+]
+
+[[package]]
+name = "tracing-futures"
+version = "0.2.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "97d095ae15e245a057c8e8451bab9b3ee1e1f68e9ba2b4fbc18d0ac5237835f2"
+dependencies = [
+ "pin-project",
+ "tracing",
+]
+
+[[package]]
+name = "try-lock"
+version = "0.2.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "59547bce71d9c38b83d9c0e92b6066c4253371f15005def0c30d9657f50c7642"
+
+[[package]]
+name = "unicode-ident"
+version = "1.0.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5bd2fe26506023ed7b5e1e315add59d6f584c621d037f9368fea9cfb988f368c"
+
+[[package]]
+name = "want"
+version = "0.3.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1ce8a968cb1cd110d136ff8b819a556d6fb6d919363c61534f6860c7eb172ba0"
+dependencies = [
+ "log",
+ "try-lock",
+]
+
+[[package]]
+name = "wasi"
+version = "0.11.0+wasi-snapshot-preview1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423"
+
+[[package]]
+name = "winapi"
+version = "0.3.9"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419"
+dependencies = [
+ "winapi-i686-pc-windows-gnu",
+ "winapi-x86_64-pc-windows-gnu",
+]
+
+[[package]]
+name = "winapi-i686-pc-windows-gnu"
+version = "0.4.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
+
+[[package]]
+name = "winapi-x86_64-pc-windows-gnu"
+version = "0.4.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
+
+[[package]]
+name = "windows-sys"
+version = "0.36.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ea04155a16a59f9eab786fe12a4a450e75cdb175f9e0d80da1e17db09f55b8d2"
+dependencies = [
+ "windows_aarch64_msvc",
+ "windows_i686_gnu",
+ "windows_i686_msvc",
+ "windows_x86_64_gnu",
+ "windows_x86_64_msvc",
+]
+
+[[package]]
+name = "windows_aarch64_msvc"
+version = "0.36.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9bb8c3fd39ade2d67e9874ac4f3db21f0d710bee00fe7cab16949ec184eeaa47"
+
+[[package]]
+name = "windows_i686_gnu"
+version = "0.36.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "180e6ccf01daf4c426b846dfc66db1fc518f074baa793aa7d9b9aaeffad6a3b6"
+
+[[package]]
+name = "windows_i686_msvc"
+version = "0.36.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e2e7917148b2812d1eeafaeb22a97e4813dfa60a3f8f78ebe204bcc88f12f024"
+
+[[package]]
+name = "windows_x86_64_gnu"
+version = "0.36.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4dcd171b8776c41b97521e5da127a2d86ad280114807d0b2ab1e462bc764d9e1"
+
+[[package]]
+name = "windows_x86_64_msvc"
+version = "0.36.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c811ca4a8c853ef420abd8592ba53ddbbac90410fab6903b3e79972a631f7680"
diff --git a/dubbo/Cargo.toml b/dubbo/Cargo.toml
new file mode 100644
index 0000000..7ce6865
--- /dev/null
+++ b/dubbo/Cargo.toml
@@ -0,0 +1,28 @@
+[package]
+name = "dubbo"
+version = "0.1.0"
+edition = "2021"
+
+# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
+
+[[bin]]
+name = "helloworld-client"
+path = "src/helloworld/client.rs"
+
+[dependencies]
+h2 = {version = "0.3", optional = true}
+hyper = "0.14.19"
+http = "0.2"
+tonic = {version ="0.7.2", features = ["compression",]}
+tower-service = "0.3.1"
+http-body = "0.4.4"
+tower = "0.4.12"
+futures-util = {version = "0.3", default-features = false}
+tokio = { version = "1.0", features = [ "rt-multi-thread", "time", "fs", "macros", "net", "signal"] }
+prost-derive = {version = "0.10", optional = true}
+prost = "0.10.4"
+prost-types = { version = "0.6", default-features = false }
+lazy_static = "1.3.0"
+async-trait = "0.1.56"
+tower-layer = "0.3"
+
diff --git a/dubbo/readme.md b/dubbo/readme.md
new file mode 100644
index 0000000..0adef95
--- /dev/null
+++ b/dubbo/readme.md
@@ -0,0 +1 @@
+# Introduce
\ No newline at end of file
diff --git a/dubbo/src/common/mod.rs b/dubbo/src/common/mod.rs
new file mode 100644
index 0000000..aff8e30
--- /dev/null
+++ b/dubbo/src/common/mod.rs
@@ -0,0 +1 @@
+pub mod url;
\ No newline at end of file
diff --git a/dubbo/src/common/url.rs b/dubbo/src/common/url.rs
new file mode 100644
index 0000000..879a1a0
--- /dev/null
+++ b/dubbo/src/common/url.rs
@@ -0,0 +1,5 @@
+#[derive(Debug, Clone)]
+pub struct Url {
+    pub url: String,
+    pub service_key: String
+}
\ No newline at end of file
diff --git a/dubbo/src/helloworld/client.rs b/dubbo/src/helloworld/client.rs
new file mode 100644
index 0000000..f4517b4
--- /dev/null
+++ b/dubbo/src/helloworld/client.rs
@@ -0,0 +1,23 @@
+use dubbo::helloworld::helloworld::greeter_client::GreeterClient;
+use dubbo::helloworld::helloworld::HelloRequest;
+
+// pub mod hello_world {
+//     tonic::include_proto!("helloworld");
+// }
+
+// cargo run --bin helloworld-client
+
+#[tokio::main]
+async fn main() -> Result<(), Box<dyn std::error::Error>> {
+    let mut client = GreeterClient::connect("http://[::1]:50051").await?;
+
+    let request = tonic::Request::new(HelloRequest {
+        name: "Tonic".into(),
+    });
+
+    let response = client.say_hello(request).await?;
+
+    println!("RESPONSE={:?}", response);
+
+    Ok(())
+}
\ No newline at end of file
diff --git a/dubbo/src/helloworld/helloworld.rs b/dubbo/src/helloworld/helloworld.rs
new file mode 100644
index 0000000..b951157
--- /dev/null
+++ b/dubbo/src/helloworld/helloworld.rs
@@ -0,0 +1,272 @@
+/// The request message containing the user's name.
+#[derive(Clone, PartialEq, ::prost::Message)]
+pub struct HelloRequest {
+    #[prost(string, tag="1")]
+    pub name: ::prost::alloc::string::String,
+}
+/// The response message containing the greetings
+#[derive(Clone, PartialEq, ::prost::Message)]
+pub struct HelloReply {
+    #[prost(string, tag="1")]
+    pub message: ::prost::alloc::string::String,
+}
+/// Generated client implementations.
+pub mod greeter_client {
+    #![allow(unused_variables, dead_code, missing_docs, clippy::let_unit_value)]
+    use tonic::codegen::*;
+    /// The greeting service definition.
+    #[derive(Debug, Clone)]
+    pub struct GreeterClient<T> {
+        inner: tonic::client::Grpc<T>,
+    }
+    impl GreeterClient<tonic::transport::Channel> {
+        /// Attempt to create a new client by connecting to a given endpoint.
+        pub async fn connect<D>(dst: D) -> Result<Self, tonic::transport::Error>
+        where
+            D: std::convert::TryInto<tonic::transport::Endpoint>,
+            D::Error: Into<StdError>,
+        {
+            let conn = tonic::transport::Endpoint::new(dst)?.connect().await?;
+            Ok(Self::new(conn))
+        }
+    }
+    impl<T> GreeterClient<T>
+    where
+        T: tonic::client::GrpcService<tonic::body::BoxBody>,
+        T::Error: Into<StdError>,
+        T::ResponseBody: Body<Data = Bytes> + Send + 'static,
+        <T::ResponseBody as Body>::Error: Into<StdError> + Send,
+    {
+        pub fn new(inner: T) -> Self {
+            let inner = tonic::client::Grpc::new(inner);
+            Self { inner }
+        }
+        pub fn with_interceptor<F>(
+            inner: T,
+            interceptor: F,
+        ) -> GreeterClient<InterceptedService<T, F>>
+        where
+            F: tonic::service::Interceptor,
+            T::ResponseBody: Default,
+            T: tonic::codegen::Service<
+                http::Request<tonic::body::BoxBody>,
+                Response = http::Response<
+                    <T as tonic::client::GrpcService<tonic::body::BoxBody>>::ResponseBody,
+                >,
+            >,
+            <T as tonic::codegen::Service<
+                http::Request<tonic::body::BoxBody>,
+            >>::Error: Into<StdError> + Send + Sync,
+        {
+            GreeterClient::new(InterceptedService::new(inner, interceptor))
+        }
+        /// Compress requests with `gzip`.
+        ///
+        /// This requires the server to support it otherwise it might respond with an
+        /// error.
+        #[must_use]
+        pub fn send_gzip(mut self) -> Self {
+            self.inner = self.inner.send_gzip();
+            self
+        }
+        /// Enable decompressing responses with `gzip`.
+        #[must_use]
+        pub fn accept_gzip(mut self) -> Self {
+            self.inner = self.inner.accept_gzip();
+            self
+        }
+        /// Sends a greeting
+        pub async fn say_hello(
+            &mut self,
+            request: impl tonic::IntoRequest<super::HelloRequest>,
+        ) -> Result<tonic::Response<super::HelloReply>, tonic::Status> {
+            self.inner
+                .ready()
+                .await
+                .map_err(|e| {
+                    tonic::Status::new(
+                        tonic::Code::Unknown,
+                        format!("Service was not ready: {}", e.into()),
+                    )
+                })?;
+            let codec = tonic::codec::ProstCodec::default();
+            let path = http::uri::PathAndQuery::from_static(
+                "/helloworld.Greeter/SayHello",
+            );
+            self.inner.unary(request.into_request(), path, codec).await
+        }
+    }
+}
+/// Generated server implementations.
+pub mod greeter_server {
+    #![allow(unused_variables, dead_code, missing_docs, clippy::let_unit_value)]
+
+    use tonic::codegen::*;
+    use crate::service::protocol::Invoker;
+    use crate::service::grpc::grpc_server::DubboGrpcService;
+    use crate::service::grpc::grpc_server::ServiceDesc;
+
+    ///Generated trait containing gRPC methods that should be implemented for use with GreeterServer.
+    #[async_trait]
+    pub trait Greeter: Send + Sync + 'static {
+        /// Sends a greeting
+        async fn say_hello(
+            &self,
+            request: tonic::Request<super::HelloRequest>,
+        ) -> Result<tonic::Response<super::HelloReply>, tonic::Status>;
+    }
+    /// The greeting service definition.
+    #[derive(Debug)]
+    pub struct GreeterServer<T: Greeter, I> {
+        inner: _Inner<T>,
+        invoker: Option<_Inner<I>>,
+        accept_compression_encodings: EnabledCompressionEncodings,
+        send_compression_encodings: EnabledCompressionEncodings,
+    }
+    struct _Inner<T>(Arc<T>);
+    impl<T: Greeter, I> GreeterServer<T, I> {
+        pub fn new(inner: T) -> Self {
+            Self::from_arc(Arc::new(inner))
+        }
+        pub fn from_arc(inner: Arc<T>) -> Self {
+            let inner = _Inner(inner);
+            Self {
+                inner,
+                invoker: None,
+                accept_compression_encodings: Default::default(),
+                send_compression_encodings: Default::default(),
+            }
+        }
+        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 `gzip`.
+        #[must_use]
+        pub fn accept_gzip(mut self) -> Self {
+            self.accept_compression_encodings.enable_gzip();
+            self
+        }
+        /// Compress responses with `gzip`, if the client supports it.
+        #[must_use]
+        pub fn send_gzip(mut self) -> Self {
+            self.send_compression_encodings.enable_gzip();
+            self
+        }
+    }
+    impl<T, B, I> tonic::codegen::Service<http::Request<B>> for GreeterServer<T, I>
+    where
+        T: Greeter,
+        B: Body + Send + 'static,
+        B::Error: Into<StdError> + Send + 'static,
+    {
+        type Response = http::Response<tonic::body::BoxBody>;
+        type Error = std::convert::Infallible;
+        type Future = BoxFuture<Self::Response, Self::Error>;
+        fn poll_ready(
+            &mut self,
+            _cx: &mut Context<'_>,
+        ) -> Poll<Result<(), Self::Error>> {
+            Poll::Ready(Ok(()))
+        }
+        fn call(&mut self, req: http::Request<B>) -> Self::Future {
+            let inner = self.inner.clone();
+            match req.uri().path() {
+                "/helloworld.Greeter/SayHello" => {
+                    #[allow(non_camel_case_types)]
+                    struct SayHelloSvc<T: Greeter>(pub Arc<T>);
+                    impl<T: Greeter> tonic::server::UnaryService<super::HelloRequest>
+                    for SayHelloSvc<T> {
+                        type Response = super::HelloReply;
+                        type Future = BoxFuture<
+                            tonic::Response<Self::Response>,
+                            tonic::Status,
+                        >;
+                        fn call(
+                            &mut self,
+                            request: tonic::Request<super::HelloRequest>,
+                        ) -> Self::Future {
+                            let inner = self.0.clone();
+                            let fut = async move { (*inner).say_hello(request).await };
+                            Box::pin(fut)
+                        }
+                    }
+                    let accept_compression_encodings = self.accept_compression_encodings;
+                    let send_compression_encodings = self.send_compression_encodings;
+                    let inner = self.inner.clone();
+                    let fut = async move {
+                        let inner = inner.0;
+                        let method = SayHelloSvc(inner);
+                        let codec = tonic::codec::ProstCodec::default();
+                        let mut grpc = tonic::server::Grpc::new(codec)
+                            .apply_compression_config(
+                                accept_compression_encodings,
+                                send_compression_encodings,
+                            );
+                        let res = grpc.unary(method, req).await;
+                        Ok(res)
+                    };
+                    Box::pin(fut)
+                }
+                _ => {
+                    Box::pin(async move {
+                        Ok(
+                            http::Response::builder()
+                                .status(200)
+                                .header("grpc-status", "12")
+                                .header("content-type", "application/grpc")
+                                .body(empty_body())
+                                .unwrap(),
+                        )
+                    })
+                }
+            }
+        }
+    }
+    impl<T: Greeter, I: Invoker+ Send+ Sync + 'static> Clone for GreeterServer<T, I> {
+        fn clone(&self) -> Self {
+            let inner = self.inner.clone();
+            Self {
+                inner,
+                invoker: None,
+                // invoker: if let Some(v) = self.invoker.borrow_mut() {
+                //     Some(v.clone())
+                // } else {
+                //     None
+                // },
+                accept_compression_encodings: self.accept_compression_encodings,
+                send_compression_encodings: self.send_compression_encodings,
+            }
+        }
+
+    }
+
+    impl<T: Greeter> Clone for _Inner<T> {
+        fn clone(&self) -> Self {
+            Self(self.0.clone())
+        }
+    }
+    impl<T: std::fmt::Debug> std::fmt::Debug for _Inner<T> {
+        fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
+            write!(f, "{:?}", self.0)
+        }
+    }
+    impl<T: Greeter, I: Invoker> DubboGrpcService<I> for GreeterServer<T, I> {
+        fn set_proxy_impl(&mut self, invoker: I) {
+            self.invoker = Some(_Inner(Arc::new(invoker)));
+        }
+
+        fn service_desc(&self) -> ServiceDesc {
+            ServiceDesc::new("helloworld.Greeter".to_string(), std::collections::HashMap::new())
+        }
+    }
+
+    impl<T: Greeter, I> tonic::transport::NamedService for GreeterServer<T, I> {
+        const NAME: &'static str = "helloworld.Greeter";
+    }
+}
diff --git a/dubbo/src/helloworld/mod.rs b/dubbo/src/helloworld/mod.rs
new file mode 100644
index 0000000..5f1509d
--- /dev/null
+++ b/dubbo/src/helloworld/mod.rs
@@ -0,0 +1 @@
+pub mod helloworld;
\ No newline at end of file
diff --git a/dubbo/src/helloworld/server.rs b/dubbo/src/helloworld/server.rs
new file mode 100644
index 0000000..e69de29
diff --git a/dubbo/src/lib.rs b/dubbo/src/lib.rs
new file mode 100644
index 0000000..7a10cf1
--- /dev/null
+++ b/dubbo/src/lib.rs
@@ -0,0 +1,6 @@
+pub mod helloworld;
+pub mod service;
+pub mod common;
+pub mod utils;
+
+pub(crate) type Error = Box<dyn std::error::Error + Send + Sync>;
\ No newline at end of file
diff --git a/dubbo/src/main.rs b/dubbo/src/main.rs
new file mode 100644
index 0000000..ecc7b56
--- /dev/null
+++ b/dubbo/src/main.rs
@@ -0,0 +1,10 @@
+pub mod service;
+pub mod common;
+pub mod utils;
+pub mod helloworld;
+
+#[tokio::main]
+async fn main() {
+    println!("hello, dubbo-rust~")
+}
+
diff --git a/dubbo/src/service/grpc/grpc_exporter.rs b/dubbo/src/service/grpc/grpc_exporter.rs
new file mode 100644
index 0000000..2940429
--- /dev/null
+++ b/dubbo/src/service/grpc/grpc_exporter.rs
@@ -0,0 +1,34 @@
+
+use crate::service::protocol::*;
+use crate::service::protocol::Invoker;    
+
+pub struct GrpcExporter<T> {
+    invoker: T
+}
+
+impl<T> GrpcExporter<T> {
+    pub fn new(key: String, invoker: T) -> GrpcExporter<T> {
+        Self { invoker }
+    }
+}
+
+impl<T: Invoker+Clone> Exporter for GrpcExporter<T>
+{
+    type InvokerType = T;
+
+    fn unexport(&self) {
+    }
+
+    fn get_invoker(&self) -> Self::InvokerType {
+        self.invoker.clone()
+    }
+
+}
+
+impl<T: Invoker+Clone> Clone for GrpcExporter<T> {
+    
+    fn clone(&self) -> Self {
+        Self { invoker: self.invoker.clone() }
+    }
+
+}
\ No newline at end of file
diff --git a/dubbo/src/service/grpc/grpc_invoker.rs b/dubbo/src/service/grpc/grpc_invoker.rs
new file mode 100644
index 0000000..fd48e73
--- /dev/null
+++ b/dubbo/src/service/grpc/grpc_invoker.rs
@@ -0,0 +1,73 @@
+use std::sync::Once;
+
+use tonic::client::Grpc;
+use tonic::transport::Channel;
+use tonic::transport::Endpoint;
+
+use crate::service::protocol::*;
+use crate::service::invocation;
+use crate::common::url::Url;
+
+pub struct GrpcInvoker {
+    client: Grpc<Channel>,
+    url: Url,
+    once: Once
+}
+
+
+
+impl GrpcInvoker {
+    pub fn new(url: Url) -> GrpcInvoker {
+
+        let endpoint = Endpoint::new(url.url.clone()).unwrap();
+        let conn = endpoint.connect_lazy();
+        Self {
+            url,
+            client: Grpc::new(conn),
+            once: Once::new()
+        }
+    }
+}
+
+impl Invoker for GrpcInvoker {
+
+    fn is_available(&self) -> bool {
+        true
+    }
+
+    fn destroy(&self) {
+        self.once.call_once(|| {
+            println!("destroy...")
+        })
+    }
+
+    fn get_url(&self) -> Url {
+        self.url.to_owned()
+    }
+
+    // 根据req中的数据发起req,由Client发起请求,获取响应
+   fn invoke<M1>(&self, req: invocation::Request<M1>) -> invocation::Response<String>
+    where
+        M1: Send + 'static,
+    {
+        let (metadata, _) = req.into_parts();
+
+        let resp = invocation::Response::new("string");
+        let (resp_meta, msg) = resp.into_parts();
+ 
+        invocation::Response::from_parts(metadata, msg.to_string())
+    }
+}
+
+impl<T> invocation::Request<T> {
+
+    pub(crate) fn to_tonic_req(self) -> tonic::Request<T> {
+        tonic::Request::new(self.message)
+    }
+}
+
+impl Clone for GrpcInvoker {
+    fn clone(&self) -> Self {
+        Self { client: self.client.clone(), url: self.url.clone(), once: Once::new() }
+    }
+}
\ No newline at end of file
diff --git a/dubbo/src/service/grpc/grpc_protocol.rs b/dubbo/src/service/grpc/grpc_protocol.rs
new file mode 100644
index 0000000..08fe921
--- /dev/null
+++ b/dubbo/src/service/grpc/grpc_protocol.rs
@@ -0,0 +1,60 @@
+
+use std::collections::HashMap;
+
+use super::grpc_invoker::GrpcInvoker;
+use super::grpc_exporter::GrpcExporter;
+use crate::common::url::Url;
+use crate::service::protocol::Protocol;
+use super::grpc_server::GrpcServer;
+
+pub struct GrpcProtocol {
+    server_map: HashMap<String, GrpcServer>,
+    export_map: HashMap<String, GrpcExporter<GrpcInvoker>>
+}
+
+impl GrpcProtocol {
+    pub fn new() -> Self {
+        Self {
+            server_map: HashMap::new(),
+            export_map: HashMap::new(),
+        }
+    }
+}
+
+impl Default for GrpcProtocol {
+    fn default() -> Self {
+        Self::new()
+    }
+}
+
+#[async_trait::async_trait]
+impl Protocol for GrpcProtocol
+{
+    type Invoker = GrpcInvoker;
+
+    type Exporter = GrpcExporter<Self::Invoker>;
+
+    fn destroy(&self) {
+        todo!()
+    }
+
+    async fn refer(&self, url: Url) -> Self::Invoker {
+        GrpcInvoker::new(url)
+    }
+
+    async fn export(self, url: Url) -> Self::Exporter {
+        let service_key = url.service_key.clone();
+
+        let exporter: GrpcExporter<GrpcInvoker> = GrpcExporter::new(service_key.clone(), GrpcInvoker::new(url.clone()));
+        let mut export = self.export_map;
+        export.insert(service_key.clone(), exporter.clone());
+
+        // 启动服务
+
+        let server = super::grpc_server::GrpcServer::new(service_key.clone());
+        let mut server_map = self.server_map;
+        server_map.insert(service_key.clone(), server.clone());
+        server.serve(url.clone()).await;
+        exporter
+    }
+}
\ No newline at end of file
diff --git a/dubbo/src/service/grpc/grpc_server.rs b/dubbo/src/service/grpc/grpc_server.rs
new file mode 100644
index 0000000..3a9c6a8
--- /dev/null
+++ b/dubbo/src/service/grpc/grpc_server.rs
@@ -0,0 +1,116 @@
+use std::collections::HashMap;
+use std::task::Context;
+use std::task::Poll;
+
+use tonic::transport;
+use tower::Service;
+use tonic::transport::NamedService;
+use tonic::codegen::BoxFuture;
+
+
+use crate::common::url::Url;
+use crate::helloworld::helloworld::greeter_server::GreeterServer;
+use super::grpc_invoker::GrpcInvoker;
+use crate::helloworld::helloworld::greeter_server::*;
+use crate::utils::boxed_clone::BoxCloneService;
+
+pub trait DubboGrpcService<T>
+{
+    fn set_proxy_impl(&mut self, invoker: T);
+    fn service_desc(&self) -> ServiceDesc;
+}
+
+//type ServiceDesc struct {
+//     ServiceName string
+//     // The pointer to the service interface. Used to check whether the user
+//     // provided implementation satisfies the interface requirements.
+//     HandlerType interface{}
+//     Methods     []MethodDesc
+//     Streams     []StreamDesc
+//     Metadata    interface{}
+// }
+
+pub struct ServiceDesc {
+    service_name: String,
+    methods: HashMap<String, String> // "/Greeter/hello": "unary"
+}
+
+impl  ServiceDesc {
+    pub fn new(service_name: String, methods: HashMap<String, String>) -> Self {
+        Self { service_name, methods }
+    }
+
+    pub fn get_service_name(&self) -> String {
+        self.service_name.clone()
+    }
+}
+
+// codegen
+pub fn register_greeter_server<T: Greeter>(server: T) -> (super::GrpcBoxCloneService, super::DubboGrpcBox) {
+    let hello = GreeterServer::<T, GrpcInvoker>::new(server);
+    (BoxCloneService::new(hello.clone()), Box::new(hello.clone()))
+}
+
+// 每个service对应一个Server
+#[derive(Clone)]
+pub struct GrpcServer {
+    inner: transport::Server,
+    name: String,
+}
+
+impl GrpcServer
+{
+    pub fn new(name: String) -> GrpcServer {
+        Self {
+            inner: transport::Server::builder(),
+            name
+        }
+    }
+
+    pub async fn serve(mut self, url: Url)
+    where
+    {
+        let addr = url.url.clone().parse().unwrap();
+        let svc = super::GRPC_SERVICES.read().unwrap().get(self.name.as_str()).unwrap().clone();
+        println!("server{:?} start...", url);
+        self.inner.add_service(MakeSvc::new(svc)).serve(
+            addr
+        ).await.unwrap();
+        println!("server{:?} start...", url);
+    }
+
+}
+
+struct MakeSvc<T, U, E> {
+    inner: BoxCloneService<T, U, E>
+}
+
+impl<T, U, E> MakeSvc<T, U, E> {
+    pub fn new(inner: BoxCloneService<T, U, E>) -> Self {
+        Self { inner}
+    }
+}
+
+impl<T, U, E> NamedService for MakeSvc<T, U, E> {
+    const NAME: &'static str = "helloworld.Greeter";
+}
+
+impl<T, U, E> Service<T> for MakeSvc<T, U, E> {
+    type Response = U;
+    type Error = E;
+    type Future = BoxFuture<U, E>;
+
+    fn poll_ready(&mut self, cx: &mut Context<'_>) -> Poll<Result<(), E>> {
+        self.inner.poll_ready(cx)
+    }
+
+    fn call(&mut self, request: T) -> BoxFuture<U, E> {
+        self.inner.call(request)
+    }
+}
+
+impl<T, U, E> Clone for MakeSvc<T, U, E> {
+    fn clone(&self) -> Self {
+        Self { inner: self.inner.clone() }
+    }
+}
\ No newline at end of file
diff --git a/dubbo/src/service/grpc/mod.rs b/dubbo/src/service/grpc/mod.rs
new file mode 100644
index 0000000..3350638
--- /dev/null
+++ b/dubbo/src/service/grpc/mod.rs
@@ -0,0 +1,59 @@
+pub mod grpc_protocol;
+pub mod grpc_invoker;
+pub mod grpc_exporter;
+pub mod grpc_server;
+
+use std::collections::HashMap;
+use std::sync::RwLock;
+use lazy_static::lazy_static;
+
+use grpc_server::DubboGrpcService;
+use grpc_invoker::GrpcInvoker;
+use crate::helloworld::helloworld::greeter_server::Greeter;
+use crate::utils::boxed_clone::BoxCloneService;
+use crate::helloworld::helloworld::{HelloRequest, HelloReply};
+
+pub type GrpcBoxCloneService = BoxCloneService<http::Request<hyper::Body>, http::Response<tonic::body::BoxBody>, std::convert::Infallible>;
+
+pub type DubboGrpcBox = Box<dyn DubboGrpcService<GrpcInvoker>+ Send + Sync + 'static>;
+
+lazy_static! {
+    pub static ref DUBBO_GRPC_SERVICES: RwLock<HashMap<String, Box<dyn DubboGrpcService<GrpcInvoker> + Send + Sync + 'static>>> = RwLock::new(HashMap::new());
+    pub static ref GRPC_SERVICES: RwLock<HashMap<String, GrpcBoxCloneService>> = RwLock::new(HashMap::new());
+}
+
+#[tokio::test]
+async fn test_hello() {
+    use grpc_server::register_greeter_server;
+    use crate::service::protocol::Protocol;
+    use crate::common::url::Url;
+    
+    let (svc, dubbo_svc) = register_greeter_server(MyGreeter{});
+    let svc_name = dubbo_svc.service_desc().get_service_name();
+    DUBBO_GRPC_SERVICES.write().unwrap().insert(svc_name.clone(), dubbo_svc);
+    GRPC_SERVICES.write().unwrap().insert(svc_name.clone(), svc);
+
+    // server start, api: 0.0.0.0:8888/helloworld.Greeter/SayHello
+    let pro = grpc_protocol::GrpcProtocol::new();
+    pro.export(Url{url: "[::1]:50051".to_string(), service_key: svc_name.clone()}).await;
+
+}
+
+
+#[derive(Default)]
+pub struct MyGreeter {}
+
+#[tonic::async_trait]
+impl Greeter for MyGreeter {
+    async fn say_hello(
+        &self,
+        request: tonic::Request<HelloRequest>,
+    ) -> Result<tonic::Response<HelloReply>, tonic::Status> {
+        println!("Got a request from {:?}", request.remote_addr());
+
+        let reply = HelloReply {
+            message: format!("Hello {}!", request.into_inner().name),
+        };
+        Ok(tonic::Response::new(reply))
+    }
+}
\ No newline at end of file
diff --git a/dubbo/src/service/invocation.rs b/dubbo/src/service/invocation.rs
new file mode 100644
index 0000000..dff46fa
--- /dev/null
+++ b/dubbo/src/service/invocation.rs
@@ -0,0 +1,45 @@
+use tonic::metadata::MetadataMap;
+
+pub struct Request<T> {
+    pub message: T,
+    pub metadata: MetadataMap,
+}
+
+
+impl<T> Request<T> {
+    pub fn new(message: T) -> Request<T> {
+        Self {
+            message,
+            metadata: MetadataMap::new()
+        }
+    }
+
+    pub fn into_parts(self) -> (MetadataMap, T) {
+        (self.metadata, self.message)
+    }
+}
+
+pub struct Response<T> {
+    message: T,
+    metadata: MetadataMap,
+}
+
+impl<T> Response<T> {
+    pub fn new(message: T) -> Response<T> {
+        Self {
+            message,
+            metadata: MetadataMap::new(),
+        }
+    }
+
+    pub fn from_parts(metadata: MetadataMap, message: T) -> Self {
+        Self {
+            message,
+            metadata,
+        }
+    }
+
+    pub fn into_parts(self) -> (MetadataMap, T) {
+        (self.metadata, self.message)
+    }
+}
\ No newline at end of file
diff --git a/dubbo/src/service/mod.rs b/dubbo/src/service/mod.rs
new file mode 100644
index 0000000..55bcb2f
--- /dev/null
+++ b/dubbo/src/service/mod.rs
@@ -0,0 +1,4 @@
+pub mod protocol;
+pub mod grpc;
+pub mod invocation;
+
diff --git a/dubbo/src/service/protocol.rs b/dubbo/src/service/protocol.rs
new file mode 100644
index 0000000..18d2d7b
--- /dev/null
+++ b/dubbo/src/service/protocol.rs
@@ -0,0 +1,31 @@
+use super::invocation;
+use crate::common::url::Url;
+
+use async_trait::async_trait;
+
+#[async_trait]
+pub trait Protocol {
+    type Invoker;
+    type Exporter;
+    
+    fn destroy(&self);
+    async fn export(self, url: Url) -> Self::Exporter;
+    async fn refer(&self, url: Url) -> Self::Invoker;
+}
+
+
+pub trait Exporter {
+    type InvokerType: Invoker;
+
+    fn unexport(&self);
+    fn get_invoker(&self) -> Self::InvokerType;
+}
+
+pub trait Invoker {
+    fn invoke<M1>(&self, req: invocation::Request<M1>) -> invocation::Response<String>
+    where
+        M1: Send + 'static;
+    fn is_available(&self) -> bool;
+    fn destroy(&self);
+    fn get_url(&self) -> Url;
+}
\ No newline at end of file
diff --git a/dubbo/src/utils/boxed.rs b/dubbo/src/utils/boxed.rs
new file mode 100644
index 0000000..63297e9
--- /dev/null
+++ b/dubbo/src/utils/boxed.rs
@@ -0,0 +1,74 @@
+use tower::ServiceExt;
+use tower_layer::{layer_fn, LayerFn};
+use tower_service::Service;
+
+use std::fmt;
+use std::{
+    future::Future,
+    pin::Pin,
+    task::{Context, Poll},
+};
+
+/// A boxed `Service + Send` trait object.
+///
+/// [`BoxService`] turns a service into a trait object, allowing the response
+/// future type to be dynamic. This type requires both the service and the
+/// response future to be [`Send`].
+///
+/// If you need a boxed [`Service`] that implements [`Clone`] consider using
+/// [`BoxCloneService`](crate::util::BoxCloneService).
+///
+/// See module level documentation for more details.
+pub struct BoxService<T, U, E> {
+    inner: Box<dyn Service<T, Response = U, Error = E, Future = BoxFuture<U, E>> + Send+ Sync+>,
+}
+
+/// A boxed `Future + Send` trait object.
+///
+/// This type alias represents a boxed future that is [`Send`] and can be moved
+/// across threads.
+type BoxFuture<T, E> = Pin<Box<dyn Future<Output = Result<T, E>> + Send>>;
+
+impl<T, U, E> BoxService<T, U, E> {
+    #[allow(missing_docs)]
+    pub fn new<S>(inner: S) -> Self
+    where
+        S: Service<T, Response = U, Error = E> + Send + Sync + 'static,
+        S::Future: Send + 'static,
+    {
+        let inner = Box::new(inner.map_future(|f: S::Future| Box::pin(f) as _));
+        BoxService { inner }
+    }
+
+    // /// Returns a [`Layer`] for wrapping a [`Service`] in a [`BoxService`]
+    // /// middleware.
+    // ///
+    // /// [`Layer`]: crate::Layer
+    pub fn layer<S>() -> LayerFn<fn(S) -> Self>
+    where
+        S: Service<T, Response = U, Error = E> + Send + Sync + 'static,
+        S::Future: Send + 'static,
+    {
+        layer_fn(Self::new)
+    }
+}
+
+impl<T, U, E> Service<T> for BoxService<T, U, E> {
+    type Response = U;
+    type Error = E;
+    type Future = BoxFuture<U, E>;
+
+    fn poll_ready(&mut self, cx: &mut Context<'_>) -> Poll<Result<(), E>> {
+        self.inner.poll_ready(cx)
+    }
+
+    fn call(&mut self, request: T) -> BoxFuture<U, E> {
+        self.inner.call(request)
+    }
+}
+
+impl<T, U, E> fmt::Debug for BoxService<T, U, E> {
+    fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
+        fmt.debug_struct("BoxService").finish()
+    }
+}
diff --git a/dubbo/src/utils/boxed_clone.rs b/dubbo/src/utils/boxed_clone.rs
new file mode 100644
index 0000000..0e5e6c3
--- /dev/null
+++ b/dubbo/src/utils/boxed_clone.rs
@@ -0,0 +1,88 @@
+use tower::ServiceExt;
+use futures_util::future::BoxFuture;
+use std::{
+    fmt,
+    task::{Context, Poll},
+};
+use tower_layer::{layer_fn, LayerFn};
+use tower_service::Service;
+
+pub struct BoxCloneService<T, U, E>(
+    Box<
+        dyn CloneService<T, Response = U, Error = E, Future = BoxFuture<'static, Result<U, E>>>
+            + Send+Sync,
+    >,
+);
+
+impl<T, U, E> BoxCloneService<T, U, E> {
+    /// Create a new `BoxCloneService`.
+    pub fn new<S>(inner: S) -> Self
+    where
+        S: Service<T, Response = U, Error = E> + Clone + Send + Sync + 'static,
+        S::Future: Send + 'static,
+    {
+        let inner = inner.map_future(|f| Box::pin(f) as _);
+        BoxCloneService(Box::new(inner))
+    }
+
+    /// Returns a [`Layer`] for wrapping a [`Service`] in a [`BoxCloneService`]
+    /// middleware.
+    ///
+    /// [`Layer`]: crate::Layer
+    pub fn layer<S>() -> LayerFn<fn(S) -> Self>
+    where
+        S: Service<T, Response = U, Error = E> + Clone + Send + Sync + 'static,
+        S::Future: Send + 'static,
+    {
+        layer_fn(Self::new)
+    }
+}
+
+impl<T, U, E> Service<T> for BoxCloneService<T, U, E> {
+    type Response = U;
+    type Error = E;
+    type Future = BoxFuture<'static, Result<U, E>>;
+
+    #[inline]
+    fn poll_ready(&mut self, cx: &mut Context<'_>) -> Poll<Result<(), E>> {
+        self.0.poll_ready(cx)
+    }
+
+    #[inline]
+    fn call(&mut self, request: T) -> Self::Future {
+        self.0.call(request)
+    }
+}
+
+impl<T, U, E> Clone for BoxCloneService<T, U, E> {
+    fn clone(&self) -> Self {
+        Self(self.0.clone_box())
+    }
+}
+
+trait CloneService<R>: Service<R> {
+    fn clone_box(
+        &self,
+    ) -> Box<
+        dyn CloneService<R, Response = Self::Response, Error = Self::Error, Future = Self::Future>
+            + Send + Sync,
+    >;
+}
+
+impl<R, T> CloneService<R> for T
+where
+    T: Service<R> + Send + Sync + Clone + 'static,
+{
+    fn clone_box(
+        &self,
+    ) -> Box<dyn CloneService<R, Response = T::Response, Error = T::Error, Future = T::Future> + Send + Sync>
+    {
+        Box::new(self.clone())
+    }
+}
+
+impl<T, U, E> fmt::Debug for BoxCloneService<T, U, E> {
+    fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
+        fmt.debug_struct("BoxCloneService").finish()
+    }
+}
diff --git a/dubbo/src/utils/mod.rs b/dubbo/src/utils/mod.rs
new file mode 100644
index 0000000..a3bbaaa
--- /dev/null
+++ b/dubbo/src/utils/mod.rs
@@ -0,0 +1,2 @@
+pub mod boxed;
+pub mod boxed_clone;
\ No newline at end of file
diff --git a/protocol/Cargo.toml b/protocol/Cargo.toml
deleted file mode 100644
index 77c8260..0000000
--- a/protocol/Cargo.toml
+++ /dev/null
@@ -1,8 +0,0 @@
-[package]
-name = "protocol"
-version = "0.1.0"
-edition = "2021"
-
-# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
-
-[dependencies]
diff --git a/protocol/src/lib.rs b/protocol/src/lib.rs
deleted file mode 100644
index 3e01853..0000000
--- a/protocol/src/lib.rs
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You 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.
- */
-
-#[cfg(test)]
-mod tests {
-    #[test]
-    fn it_works() {
-        let result = 2 + 2;
-        assert_eq!(result, 4);
-    }
-}


[dubbo-rust] 03/38: dubbo-rust begin with first commit

Posted by li...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

liujun pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/dubbo-rust.git

commit 7b5687b2ae8181f931748b204911b02e183a26a2
Author: hanxiaoqing <ha...@rongcloud.cn>
AuthorDate: Sun Apr 24 18:33:52 2022 +0800

    dubbo-rust begin with first commit
    
    Signed-off-by: hanxiaoqing <ha...@rongcloud.cn>
---
 .gitignore                                 |   2 +
 Cargo.toml                                 |   9 ++
 LICENSE                                    | 191 +++++++++++++++++++++++++++++
 README_CN.md                               |   0
 common/Cargo.toml                          |   8 ++
 common/src/lib.rs                          |   8 ++
 config/Cargo.toml                          |   8 ++
 config/src/lib.rs                          |   8 ++
 contributing.md                            |  31 +++++
 examples/Cargo.toml                        |  40 ++++++
 examples/LICENSE                           |  19 +++
 examples/README.md                         |   0
 examples/build.rs                          |   0
 examples/example-tutorial.md               |   0
 examples/proto/helloworld/helloworld.proto |  37 ++++++
 examples/src/grpc-web/client.rs            |   0
 examples/src/grpc-web/server.rs            |   0
 examples/src/helloworld/client.rs          |   0
 examples/src/helloworld/server.rs          |   0
 examples/src/helloworld/server_blocking.rs |   0
 metadata/Cargo.toml                        |   8 ++
 metadata/src/lib.rs                        |   8 ++
 protocol/Cargo.toml                        |   8 ++
 protocol/src/lib.rs                        |   8 ++
 registry/Cargo.toml                        |   8 ++
 registry/src/lib.rs                        |   8 ++
 xds/Cargo.toml                             |   8 ++
 xds/src/client/client.rs                   |   0
 xds/src/client/mod.rs                      |   0
 xds/src/lib.rs                             |   8 ++
 xds/src/server/mod.rs                      |   0
 xds/src/server/server.rs                   |   0
 32 files changed, 425 insertions(+)

diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..4fffb2f
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,2 @@
+/target
+/Cargo.lock
diff --git a/Cargo.toml b/Cargo.toml
new file mode 100644
index 0000000..3720b7d
--- /dev/null
+++ b/Cargo.toml
@@ -0,0 +1,9 @@
+[workspace]
+members = [
+  "xds",
+  "protocol",
+  "registry",
+  "metadata",
+  "common",
+  "config",
+]
\ No newline at end of file
diff --git a/LICENSE b/LICENSE
new file mode 100644
index 0000000..d80bbda
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,191 @@
+
+                                 Apache License
+                           Version 2.0, January 2004
+                        http://www.apache.org/licenses/
+
+   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+   1. Definitions.
+
+      "License" shall mean the terms and conditions for use, reproduction,
+      and distribution as defined by Sections 1 through 9 of this document.
+
+      "Licensor" shall mean the copyright owner or entity authorized by
+      the copyright owner that is granting the License.
+
+      "Legal Entity" shall mean the union of the acting entity and all
+      other entities that control, are controlled by, or are under common
+      control with that entity. For the purposes of this definition,
+      "control" means (i) the power, direct or indirect, to cause the
+      direction or management of such entity, whether by contract or
+      otherwise, or (ii) ownership of fifty percent (50%) or more of the
+      outstanding shares, or (iii) beneficial ownership of such entity.
+
+      "You" (or "Your") shall mean an individual or Legal Entity
+      exercising permissions granted by this License.
+
+      "Source" form shall mean the preferred form for making modifications,
+      including but not limited to software source code, documentation
+      source, and configuration files.
+
+      "Object" form shall mean any form resulting from mechanical
+      transformation or translation of a Source form, including but
+      not limited to compiled object code, generated documentation,
+      and conversions to other media types.
+
+      "Work" shall mean the work of authorship, whether in Source or
+      Object form, made available under the License, as indicated by a
+      copyright notice that is included in or attached to the work
+      (an example is provided in the Appendix below).
+
+      "Derivative Works" shall mean any work, whether in Source or Object
+      form, that is based on (or derived from) the Work and for which the
+      editorial revisions, annotations, elaborations, or other modifications
+      represent, as a whole, an original work of authorship. For the purposes
+      of this License, Derivative Works shall not include works that remain
+      separable from, or merely link (or bind by name) to the interfaces of,
+      the Work and Derivative Works thereof.
+
+      "Contribution" shall mean any work of authorship, including
+      the original version of the Work and any modifications or additions
+      to that Work or Derivative Works thereof, that is intentionally
+      submitted to Licensor for inclusion in the Work by the copyright owner
+      or by an individual or Legal Entity authorized to submit on behalf of
+      the copyright owner. For the purposes of this definition, "submitted"
+      means any form of electronic, verbal, or written communication sent
+      to the Licensor or its representatives, including but not limited to
+      communication on electronic mailing lists, source code control systems,
+      and issue tracking systems that are managed by, or on behalf of, the
+      Licensor for the purpose of discussing and improving the Work, but
+      excluding communication that is conspicuously marked or otherwise
+      designated in writing by the copyright owner as "Not a Contribution."
+
+      "Contributor" shall mean Licensor and any individual or Legal Entity
+      on behalf of whom a Contribution has been received by Licensor and
+      subsequently incorporated within the Work.
+
+   2. Grant of Copyright License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      copyright license to reproduce, prepare Derivative Works of,
+      publicly display, publicly perform, sublicense, and distribute the
+      Work and such Derivative Works in Source or Object form.
+
+   3. Grant of Patent License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      (except as stated in this section) patent license to make, have made,
+      use, offer to sell, sell, import, and otherwise transfer the Work,
+      where such license applies only to those patent claims licensable
+      by such Contributor that are necessarily infringed by their
+      Contribution(s) alone or by combination of their Contribution(s)
+      with the Work to which such Contribution(s) was submitted. If You
+      institute patent litigation against any entity (including a
+      cross-claim or counterclaim in a lawsuit) alleging that the Work
+      or a Contribution incorporated within the Work constitutes direct
+      or contributory patent infringement, then any patent licenses
+      granted to You under this License for that Work shall terminate
+      as of the date such litigation is filed.
+
+   4. Redistribution. You may reproduce and distribute copies of the
+      Work or Derivative Works thereof in any medium, with or without
+      modifications, and in Source or Object form, provided that You
+      meet the following conditions:
+
+      (a) You must give any other recipients of the Work or
+          Derivative Works a copy of this License; and
+
+      (b) You must cause any modified files to carry prominent notices
+          stating that You changed the files; and
+
+      (c) You must retain, in the Source form of any Derivative Works
+          that You distribute, all copyright, patent, trademark, and
+          attribution notices from the Source form of the Work,
+          excluding those notices that do not pertain to any part of
+          the Derivative Works; and
+
+      (d) If the Work includes a "NOTICE" text file as part of its
+          distribution, then any Derivative Works that You distribute must
+          include a readable copy of the attribution notices contained
+          within such NOTICE file, excluding those notices that do not
+          pertain to any part of the Derivative Works, in at least one
+          of the following places: within a NOTICE text file distributed
+          as part of the Derivative Works; within the Source form or
+          documentation, if provided along with the Derivative Works; or,
+          within a display generated by the Derivative Works, if and
+          wherever such third-party notices normally appear. The contents
+          of the NOTICE file are for informational purposes only and
+          do not modify the License. You may add Your own attribution
+          notices within Derivative Works that You distribute, alongside
+          or as an addendum to the NOTICE text from the Work, provided
+          that such additional attribution notices cannot be construed
+          as modifying the License.
+
+      You may add Your own copyright statement to Your modifications and
+      may provide additional or different license terms and conditions
+      for use, reproduction, or distribution of Your modifications, or
+      for any such Derivative Works as a whole, provided Your use,
+      reproduction, and distribution of the Work otherwise complies with
+      the conditions stated in this License.
+
+   5. Submission of Contributions. Unless You explicitly state otherwise,
+      any Contribution intentionally submitted for inclusion in the Work
+      by You to the Licensor shall be under the terms and conditions of
+      this License, without any additional terms or conditions.
+      Notwithstanding the above, nothing herein shall supersede or modify
+      the terms of any separate license agreement you may have executed
+      with Licensor regarding such Contributions.
+
+   6. Trademarks. This License does not grant permission to use the trade
+      names, trademarks, service marks, or product names of the Licensor,
+      except as required for reasonable and customary use in describing the
+      origin of the Work and reproducing the content of the NOTICE file.
+
+   7. Disclaimer of Warranty. Unless required by applicable law or
+      agreed to in writing, Licensor provides the Work (and each
+      Contributor provides its Contributions) on an "AS IS" BASIS,
+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+      implied, including, without limitation, any warranties or conditions
+      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+      PARTICULAR PURPOSE. You are solely responsible for determining the
+      appropriateness of using or redistributing the Work and assume any
+      risks associated with Your exercise of permissions under this License.
+
+   8. Limitation of Liability. In no event and under no legal theory,
+      whether in tort (including negligence), contract, or otherwise,
+      unless required by applicable law (such as deliberate and grossly
+      negligent acts) or agreed to in writing, shall any Contributor be
+      liable to You for damages, including any direct, indirect, special,
+      incidental, or consequential damages of any character arising as a
+      result of this License or out of the use or inability to use the
+      Work (including but not limited to damages for loss of goodwill,
+      work stoppage, computer failure or malfunction, or any and all
+      other commercial damages or losses), even if such Contributor
+      has been advised of the possibility of such damages.
+
+   9. Accepting Warranty or Additional Liability. While redistributing
+      the Work or Derivative Works thereof, You may choose to offer,
+      and charge a fee for, acceptance of support, warranty, indemnity,
+      or other liability obligations and/or rights consistent with this
+      License. However, in accepting such obligations, You may act only
+      on Your own behalf and on Your sole responsibility, not on behalf
+      of any other Contributor, and only if You agree to indemnify,
+      defend, and hold each Contributor harmless for any liability
+      incurred by, or claims asserted against, such Contributor by reason
+      of your accepting any such warranty or additional liability.
+
+   END OF TERMS AND CONDITIONS
+
+   Copyright (c) 2016 ~ 2018 Alex Stocks.
+
+   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.
diff --git a/README_CN.md b/README_CN.md
new file mode 100644
index 0000000..e69de29
diff --git a/common/Cargo.toml b/common/Cargo.toml
new file mode 100644
index 0000000..b7723d9
--- /dev/null
+++ b/common/Cargo.toml
@@ -0,0 +1,8 @@
+[package]
+name = "common"
+version = "0.1.0"
+edition = "2021"
+
+# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
+
+[dependencies]
diff --git a/common/src/lib.rs b/common/src/lib.rs
new file mode 100644
index 0000000..1b4a90c
--- /dev/null
+++ b/common/src/lib.rs
@@ -0,0 +1,8 @@
+#[cfg(test)]
+mod tests {
+    #[test]
+    fn it_works() {
+        let result = 2 + 2;
+        assert_eq!(result, 4);
+    }
+}
diff --git a/config/Cargo.toml b/config/Cargo.toml
new file mode 100644
index 0000000..b8afece
--- /dev/null
+++ b/config/Cargo.toml
@@ -0,0 +1,8 @@
+[package]
+name = "config"
+version = "0.1.0"
+edition = "2021"
+
+# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
+
+[dependencies]
diff --git a/config/src/lib.rs b/config/src/lib.rs
new file mode 100644
index 0000000..1b4a90c
--- /dev/null
+++ b/config/src/lib.rs
@@ -0,0 +1,8 @@
+#[cfg(test)]
+mod tests {
+    #[test]
+    fn it_works() {
+        let result = 2 + 2;
+        assert_eq!(result, 4);
+    }
+}
diff --git a/contributing.md b/contributing.md
new file mode 100644
index 0000000..b1265c2
--- /dev/null
+++ b/contributing.md
@@ -0,0 +1,31 @@
+Contributing to Dubbogo
+
+## 1. Branch
+
+  >- The name of branches `SHOULD` be in the format of `feature/xxx`.
+  >- You `SHOULD` checkout a new branch after a feature branch already being merged into upstream, `DO NOT` commit in the old branch.
+
+## 2. Pull Request
+
+### 2.1. Title Format
+
+The pr head format is `<head> <subject>`. The title should be simpler to show your intent.
+
+The title format of the pull request `MUST` follow the following rules:
+
+  >- Start with `Doc:` for adding/formatting/improving docs.
+  >- Start with `Mod:` for formatting codes or adding comment.
+  >- Start with `Fix:` for fixing bug, and its ending should be ` #issue-id` if being relevant to some issue.
+  >- Start with `Imp:` for improving performance.
+  >- Start with `Ftr:` for adding a new feature.
+  >- Start with `Add:` for adding struct function/member.
+  >- Start with `Rft:` for refactoring codes.
+  >- Start with `Tst:` for adding tests.
+  >- Start with `Dep:` for adding depending libs.
+  >- Start with `Rem:` for removing feature/struct/function/member/files.
+
+## 3. Code Style
+
+### 3.1 log
+
+> 1 when logging the function's input parameter, you should add '@' before input parameter name.
diff --git a/examples/Cargo.toml b/examples/Cargo.toml
new file mode 100644
index 0000000..3287f9c
--- /dev/null
+++ b/examples/Cargo.toml
@@ -0,0 +1,40 @@
+[package]
+authors = ["Johankio Smith <jo...@1991.com>"]
+edition = "2018"
+license = "MIT"
+name = "examples"
+publish = false
+version = "0.1.0"
+
+[[bin]]
+name = "helloworld-server"
+path = "src/helloworld/server.rs"
+
+[[bin]]
+name = "helloworld-client"
+path = "src/helloworld/client.rs"
+
+[[bin]]
+name = "grpc-web-server"
+path = "src/grpc-web/server.rs"
+
+[[bin]]
+name = "grpc-web-client"
+path = "src/grpc-web/client.rs"
+
+[dependencies]
+async-stream = "0.3"
+futures = { version = "0.3", default-features = false, features = ["alloc"] }
+prost = "0.10"
+tokio = { version = "1.0", features = [ "rt-multi-thread", "time", "fs", "macros", "net",] }
+tokio-stream = { version = "0.1", features = ["net"] }
+# Required for wellknown types
+prost-types = "0.10"
+# grpc-web example
+bytes = "1"
+tokio-rustls = "*"
+hyper-rustls = { version = "0.23", features = ["http2"] }
+rustls-pemfile = "*"
+tower-http = { version = "0.2", features = ["add-extension"] }
+
+[build-dependencies]
diff --git a/examples/LICENSE b/examples/LICENSE
new file mode 100644
index 0000000..3077098
--- /dev/null
+++ b/examples/LICENSE
@@ -0,0 +1,19 @@
+Copyright (c) 2020 Lucio Franco
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
diff --git a/examples/README.md b/examples/README.md
new file mode 100644
index 0000000..e69de29
diff --git a/examples/build.rs b/examples/build.rs
new file mode 100644
index 0000000..e69de29
diff --git a/examples/example-tutorial.md b/examples/example-tutorial.md
new file mode 100644
index 0000000..e69de29
diff --git a/examples/proto/helloworld/helloworld.proto b/examples/proto/helloworld/helloworld.proto
new file mode 100644
index 0000000..8de5d08
--- /dev/null
+++ b/examples/proto/helloworld/helloworld.proto
@@ -0,0 +1,37 @@
+// Copyright 2015 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.
+
+syntax = "proto3";
+
+option java_multiple_files = true;
+option java_package = "io.grpc.examples.helloworld";
+option java_outer_classname = "HelloWorldProto";
+
+package helloworld;
+
+// The greeting service definition.
+service Greeter {
+  // Sends a greeting
+  rpc SayHello (HelloRequest) returns (HelloReply) {}
+}
+
+// The request message containing the user's name.
+message HelloRequest {
+  string name = 1;
+}
+
+// The response message containing the greetings
+message HelloReply {
+  string message = 1;
+}
\ No newline at end of file
diff --git a/examples/src/grpc-web/client.rs b/examples/src/grpc-web/client.rs
new file mode 100644
index 0000000..e69de29
diff --git a/examples/src/grpc-web/server.rs b/examples/src/grpc-web/server.rs
new file mode 100644
index 0000000..e69de29
diff --git a/examples/src/helloworld/client.rs b/examples/src/helloworld/client.rs
new file mode 100644
index 0000000..e69de29
diff --git a/examples/src/helloworld/server.rs b/examples/src/helloworld/server.rs
new file mode 100644
index 0000000..e69de29
diff --git a/examples/src/helloworld/server_blocking.rs b/examples/src/helloworld/server_blocking.rs
new file mode 100644
index 0000000..e69de29
diff --git a/metadata/Cargo.toml b/metadata/Cargo.toml
new file mode 100644
index 0000000..a600f4c
--- /dev/null
+++ b/metadata/Cargo.toml
@@ -0,0 +1,8 @@
+[package]
+name = "metadata"
+version = "0.1.0"
+edition = "2021"
+
+# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
+
+[dependencies]
diff --git a/metadata/src/lib.rs b/metadata/src/lib.rs
new file mode 100644
index 0000000..1b4a90c
--- /dev/null
+++ b/metadata/src/lib.rs
@@ -0,0 +1,8 @@
+#[cfg(test)]
+mod tests {
+    #[test]
+    fn it_works() {
+        let result = 2 + 2;
+        assert_eq!(result, 4);
+    }
+}
diff --git a/protocol/Cargo.toml b/protocol/Cargo.toml
new file mode 100644
index 0000000..77c8260
--- /dev/null
+++ b/protocol/Cargo.toml
@@ -0,0 +1,8 @@
+[package]
+name = "protocol"
+version = "0.1.0"
+edition = "2021"
+
+# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
+
+[dependencies]
diff --git a/protocol/src/lib.rs b/protocol/src/lib.rs
new file mode 100644
index 0000000..1b4a90c
--- /dev/null
+++ b/protocol/src/lib.rs
@@ -0,0 +1,8 @@
+#[cfg(test)]
+mod tests {
+    #[test]
+    fn it_works() {
+        let result = 2 + 2;
+        assert_eq!(result, 4);
+    }
+}
diff --git a/registry/Cargo.toml b/registry/Cargo.toml
new file mode 100644
index 0000000..89c58fc
--- /dev/null
+++ b/registry/Cargo.toml
@@ -0,0 +1,8 @@
+[package]
+name = "registry"
+version = "0.1.0"
+edition = "2021"
+
+# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
+
+[dependencies]
diff --git a/registry/src/lib.rs b/registry/src/lib.rs
new file mode 100644
index 0000000..1b4a90c
--- /dev/null
+++ b/registry/src/lib.rs
@@ -0,0 +1,8 @@
+#[cfg(test)]
+mod tests {
+    #[test]
+    fn it_works() {
+        let result = 2 + 2;
+        assert_eq!(result, 4);
+    }
+}
diff --git a/xds/Cargo.toml b/xds/Cargo.toml
new file mode 100644
index 0000000..75e2515
--- /dev/null
+++ b/xds/Cargo.toml
@@ -0,0 +1,8 @@
+[package]
+name = "xds"
+version = "0.1.0"
+edition = "2021"
+
+# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
+
+[dependencies]
diff --git a/xds/src/client/client.rs b/xds/src/client/client.rs
new file mode 100644
index 0000000..e69de29
diff --git a/xds/src/client/mod.rs b/xds/src/client/mod.rs
new file mode 100644
index 0000000..e69de29
diff --git a/xds/src/lib.rs b/xds/src/lib.rs
new file mode 100644
index 0000000..1b4a90c
--- /dev/null
+++ b/xds/src/lib.rs
@@ -0,0 +1,8 @@
+#[cfg(test)]
+mod tests {
+    #[test]
+    fn it_works() {
+        let result = 2 + 2;
+        assert_eq!(result, 4);
+    }
+}
diff --git a/xds/src/server/mod.rs b/xds/src/server/mod.rs
new file mode 100644
index 0000000..e69de29
diff --git a/xds/src/server/server.rs b/xds/src/server/server.rs
new file mode 100644
index 0000000..e69de29


[dubbo-rust] 01/38: first commit

Posted by li...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

liujun pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/dubbo-rust.git

commit 9e46c77e84ac8c4a51516c0e80bf170d15fbb6af
Author: ken.lj <ke...@gmail.com>
AuthorDate: Sun Apr 3 11:26:36 2022 +0800

    first commit
---
 README.md | 1 +
 1 file changed, 1 insertion(+)

diff --git a/README.md b/README.md
new file mode 100644
index 0000000..f39d9ab
--- /dev/null
+++ b/README.md
@@ -0,0 +1 @@
+# dubbo-rust


[dubbo-rust] 05/38: Doc: fix

Posted by li...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

liujun pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/dubbo-rust.git

commit 336a9a0381ff0d5cf6a176f58422c16fa82a87b0
Author: hanxiaoqing <ha...@rongcloud.cn>
AuthorDate: Mon Apr 25 15:20:02 2022 +0800

    Doc: fix
    
    Signed-off-by: hanxiaoqing <ha...@rongcloud.cn>
---
 contributing.md | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/contributing.md b/contributing.md
index b1265c2..dc3c587 100644
--- a/contributing.md
+++ b/contributing.md
@@ -1,4 +1,4 @@
-Contributing to Dubbogo
+Contributing to dubbo-rust
 
 ## 1. Branch
 


[dubbo-rust] 07/38: Init basic project structure (#3)

Posted by li...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

liujun pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/dubbo-rust.git

commit 28eab63e6b454a70d869d0525ab20f0df68dfa92
Merge: 961471b b630a29
Author: ken.lj <ke...@gmail.com>
AuthorDate: Tue Apr 26 11:32:07 2022 +0800

    Init basic project structure (#3)

 .gitignore                   |   2 +
 Cargo.toml                   |   9 ++
 LICENSE                      | 191 +++++++++++++++++++++++++++++++++++++++++++
 README_CN.md                 |   0
 common/Cargo.toml            |   8 ++
 common/src/lib.rs            |   8 ++
 config/Cargo.toml            |   8 ++
 config/src/lib.rs            |   8 ++
 contributing.md              |  31 +++++++
 examples/LICENSE             | 191 +++++++++++++++++++++++++++++++++++++++++++
 examples/README.md           |   0
 examples/example-tutorial.md |   0
 metadata/Cargo.toml          |   8 ++
 metadata/src/lib.rs          |   8 ++
 protocol/Cargo.toml          |   8 ++
 protocol/src/lib.rs          |   8 ++
 registry/Cargo.toml          |   8 ++
 registry/src/lib.rs          |   8 ++
 xds/Cargo.toml               |   8 ++
 xds/src/client/client.rs     |   0
 xds/src/client/mod.rs        |   0
 xds/src/lib.rs               |   8 ++
 xds/src/server/mod.rs        |   0
 xds/src/server/server.rs     |   0
 24 files changed, 520 insertions(+)


[dubbo-rust] 31/38: Merge pull request #15 from apache/dependabot/cargo/dubbo/prost-types-0.8.0

Posted by li...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

liujun pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/dubbo-rust.git

commit e71b96138f383c489416290672136768c6a23f71
Merge: 4c5b18d 0096d16
Author: ken.lj <ke...@gmail.com>
AuthorDate: Tue Jul 12 15:44:58 2022 +0800

    Merge pull request #15 from apache/dependabot/cargo/dubbo/prost-types-0.8.0
    
    build(deps): bump prost-types from 0.6.1 to 0.8.0 in /dubbo

 dubbo/Cargo.lock | 61 +++++++++++++++++++++-----------------------------------
 dubbo/Cargo.toml |  2 +-
 2 files changed, 24 insertions(+), 39 deletions(-)


[dubbo-rust] 27/38: style: update code format

Posted by li...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

liujun pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/dubbo-rust.git

commit 9588657f6ee0bd7878e6f20bcfee3438959e8d69
Author: yang <96...@qq.com>
AuthorDate: Mon Jul 4 08:33:29 2022 +0800

    style: update code format
---
 Cargo.toml | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/Cargo.toml b/Cargo.toml
index 8c2e58e..970aeb1 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -6,4 +6,4 @@ members = [
   "common",
   "config",
   "dubbo"
-]
\ No newline at end of file
+]


[dubbo-rust] 02/38: repo configuration

Posted by li...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

liujun pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/dubbo-rust.git

commit 961471bf85cab25f4094d1c1b40e8f16d78c62c3
Author: ken.lj <ke...@gmail.com>
AuthorDate: Sun Apr 3 11:30:32 2022 +0800

    repo configuration
---
 .asf.yaml | 38 ++++++++++++++++++++++++++++++++++++++
 1 file changed, 38 insertions(+)

diff --git a/.asf.yaml b/.asf.yaml
new file mode 100644
index 0000000..11f9b19
--- /dev/null
+++ b/.asf.yaml
@@ -0,0 +1,38 @@
+#
+#
+#   Licensed to the Apache Software Foundation (ASF) under one or more
+#   contributor license agreements.  See the NOTICE file distributed with
+#   this work for additional information regarding copyright ownership.
+#   The ASF licenses this file to You 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.
+#
+#
+
+notifications:
+  commits:      commits@dubbo.apache.org
+  issues:       notifications@dubbo.apache.org
+  pullrequests: notifications@dubbo.apache.org
+  jira_options: link label link label
+
+github:
+  homepage: https://dubbo.apache.org/
+  features:
+    # Enable wiki for documentation
+    wiki: true
+    # Enable issue management
+    issues: true
+    # Enable projects for project management boards
+    projects: true
+  protected_branches:
+    master:
+      # only disable force push
+      foo: bar


[dubbo-rust] 30/38: Update licence-checker.yml

Posted by li...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

liujun pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/dubbo-rust.git

commit 4c5b18d6969dcee6a3d06a5e8b1ba04be383c61f
Author: kezhenxu94 <ke...@apache.org>
AuthorDate: Fri Jul 8 21:08:31 2022 +0800

    Update licence-checker.yml
---
 .github/workflows/licence-checker.yml | 4 +---
 1 file changed, 1 insertion(+), 3 deletions(-)

diff --git a/.github/workflows/licence-checker.yml b/.github/workflows/licence-checker.yml
index 0caf87d..ca458e8 100644
--- a/.github/workflows/licence-checker.yml
+++ b/.github/workflows/licence-checker.yml
@@ -37,9 +37,7 @@ jobs:
       - uses: actions/checkout@v2
 
       - name: Check License Header
-        uses: apache/skywalking-eyes@main
-        env:
-          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+        uses: apache/skywalking-eyes/header@501a28d2fb4a9b962661987e50cf0219631b32ff
         with:
           log: info
           config: .licenserc.yaml


[dubbo-rust] 23/38: refactor(dubbo): update by cargo check

Posted by li...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

liujun pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/dubbo-rust.git

commit 29f0eab0073b5d8668a702df932b36040d23f8f9
Author: yang <96...@qq.com>
AuthorDate: Mon Jun 27 21:27:40 2022 +0800

    refactor(dubbo): update by cargo check
---
 dubbo/src/lib.rs                        |  4 +---
 dubbo/src/service/grpc/grpc_exporter.rs |  2 +-
 dubbo/src/service/grpc/grpc_invoker.rs  | 12 ++++++------
 dubbo/src/service/grpc/grpc_server.rs   |  6 +++---
 4 files changed, 11 insertions(+), 13 deletions(-)

diff --git a/dubbo/src/lib.rs b/dubbo/src/lib.rs
index 7a10cf1..317ed6f 100644
--- a/dubbo/src/lib.rs
+++ b/dubbo/src/lib.rs
@@ -1,6 +1,4 @@
 pub mod helloworld;
 pub mod service;
 pub mod common;
-pub mod utils;
-
-pub(crate) type Error = Box<dyn std::error::Error + Send + Sync>;
\ No newline at end of file
+pub mod utils;
\ No newline at end of file
diff --git a/dubbo/src/service/grpc/grpc_exporter.rs b/dubbo/src/service/grpc/grpc_exporter.rs
index 2940429..4f367f2 100644
--- a/dubbo/src/service/grpc/grpc_exporter.rs
+++ b/dubbo/src/service/grpc/grpc_exporter.rs
@@ -7,7 +7,7 @@ pub struct GrpcExporter<T> {
 }
 
 impl<T> GrpcExporter<T> {
-    pub fn new(key: String, invoker: T) -> GrpcExporter<T> {
+    pub fn new(_key: String, invoker: T) -> GrpcExporter<T> {
         Self { invoker }
     }
 }
diff --git a/dubbo/src/service/grpc/grpc_invoker.rs b/dubbo/src/service/grpc/grpc_invoker.rs
index fd48e73..6016914 100644
--- a/dubbo/src/service/grpc/grpc_invoker.rs
+++ b/dubbo/src/service/grpc/grpc_invoker.rs
@@ -53,18 +53,18 @@ impl Invoker for GrpcInvoker {
         let (metadata, _) = req.into_parts();
 
         let resp = invocation::Response::new("string");
-        let (resp_meta, msg) = resp.into_parts();
+        let (_resp_meta, msg) = resp.into_parts();
  
         invocation::Response::from_parts(metadata, msg.to_string())
     }
 }
 
-impl<T> invocation::Request<T> {
+// impl<T> invocation::Request<T> {
 
-    pub(crate) fn to_tonic_req(self) -> tonic::Request<T> {
-        tonic::Request::new(self.message)
-    }
-}
+//     pub(crate) fn to_tonic_req(self) -> tonic::Request<T> {
+//         tonic::Request::new(self.message)
+//     }
+// }
 
 impl Clone for GrpcInvoker {
     fn clone(&self) -> Self {
diff --git a/dubbo/src/service/grpc/grpc_server.rs b/dubbo/src/service/grpc/grpc_server.rs
index 3a9c6a8..1047054 100644
--- a/dubbo/src/service/grpc/grpc_server.rs
+++ b/dubbo/src/service/grpc/grpc_server.rs
@@ -32,12 +32,12 @@ pub trait DubboGrpcService<T>
 
 pub struct ServiceDesc {
     service_name: String,
-    methods: HashMap<String, String> // "/Greeter/hello": "unary"
+    // methods: HashMap<String, String> // "/Greeter/hello": "unary"
 }
 
 impl  ServiceDesc {
-    pub fn new(service_name: String, methods: HashMap<String, String>) -> Self {
-        Self { service_name, methods }
+    pub fn new(service_name: String, _methods: HashMap<String, String>) -> Self {
+        Self { service_name }
     }
 
     pub fn get_service_name(&self) -> String {


[dubbo-rust] 08/38: Fix: edition: 2021

Posted by li...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

liujun pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/dubbo-rust.git

commit 9b974733ada7a8b85d8450c65c2ef0b73b49afbe
Author: johankoi <jo...@163.com>
AuthorDate: Tue Apr 26 15:09:55 2022 +0800

    Fix: edition: 2021
    
    Signed-off-by: johankoi <jo...@163.com>
---
 common/Cargo.toml   | 2 +-
 config/Cargo.toml   | 2 +-
 metadata/Cargo.toml | 2 +-
 protocol/Cargo.toml | 2 +-
 registry/Cargo.toml | 2 +-
 xds/Cargo.toml      | 2 +-
 6 files changed, 6 insertions(+), 6 deletions(-)

diff --git a/common/Cargo.toml b/common/Cargo.toml
index 09624c9..b7723d9 100644
--- a/common/Cargo.toml
+++ b/common/Cargo.toml
@@ -1,7 +1,7 @@
 [package]
 name = "common"
 version = "0.1.0"
-edition = "2022"
+edition = "2021"
 
 # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
 
diff --git a/config/Cargo.toml b/config/Cargo.toml
index f074d2d..b8afece 100644
--- a/config/Cargo.toml
+++ b/config/Cargo.toml
@@ -1,7 +1,7 @@
 [package]
 name = "config"
 version = "0.1.0"
-edition = "2022"
+edition = "2021"
 
 # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
 
diff --git a/metadata/Cargo.toml b/metadata/Cargo.toml
index 7fda9ec..a600f4c 100644
--- a/metadata/Cargo.toml
+++ b/metadata/Cargo.toml
@@ -1,7 +1,7 @@
 [package]
 name = "metadata"
 version = "0.1.0"
-edition = "2022"
+edition = "2021"
 
 # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
 
diff --git a/protocol/Cargo.toml b/protocol/Cargo.toml
index 8000b3c..77c8260 100644
--- a/protocol/Cargo.toml
+++ b/protocol/Cargo.toml
@@ -1,7 +1,7 @@
 [package]
 name = "protocol"
 version = "0.1.0"
-edition = "2022"
+edition = "2021"
 
 # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
 
diff --git a/registry/Cargo.toml b/registry/Cargo.toml
index 4e56c99..89c58fc 100644
--- a/registry/Cargo.toml
+++ b/registry/Cargo.toml
@@ -1,7 +1,7 @@
 [package]
 name = "registry"
 version = "0.1.0"
-edition = "2022"
+edition = "2021"
 
 # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
 
diff --git a/xds/Cargo.toml b/xds/Cargo.toml
index 3b89e37..75e2515 100644
--- a/xds/Cargo.toml
+++ b/xds/Cargo.toml
@@ -1,7 +1,7 @@
 [package]
 name = "xds"
 version = "0.1.0"
-edition = "2022"
+edition = "2021"
 
 # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
 


[dubbo-rust] 13/38: Fix: fix spelling mistake.

Posted by li...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

liujun pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/dubbo-rust.git

commit c0a6af926b0ecce61bddc6d0ec9e416f37d4def9
Author: Zonglei Dong <do...@apache.org>
AuthorDate: Fri May 6 15:18:37 2022 +0800

    Fix: fix spelling mistake.
---
 .github/workflows/CI.yml | 10 +---------
 1 file changed, 1 insertion(+), 9 deletions(-)

diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml
index b377439..f78275a 100644
--- a/.github/workflows/CI.yml
+++ b/.github/workflows/CI.yml
@@ -12,7 +12,7 @@ on:
 
 jobs:
  check:
-    name: check dubbo-rus project
+    name: check dubbo-rust project
     runs-on: ${{ matrix.os }}
     strategy:
       matrix:
@@ -44,11 +44,3 @@ jobs:
           toolchain: ${{ matrix.rust }}
       - run: rustup component add rustfmt
       - run: cargo fmt --all -- --check
-      
-  
-
-    
-
-
-   
-   


[dubbo-rust] 16/38: Fix: fix github actions config file name.

Posted by li...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

liujun pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/dubbo-rust.git

commit 463f84ebde97455a9ca249c9b058dfe439fd55d7
Author: Zonglei Dong <do...@apache.org>
AuthorDate: Sat May 14 15:27:43 2022 +0800

    Fix: fix github actions config file name.
---
 .github/workflows/{CI.yml => github-actions.yml} | 0
 1 file changed, 0 insertions(+), 0 deletions(-)

diff --git a/.github/workflows/CI.yml b/.github/workflows/github-actions.yml
similarity index 100%
rename from .github/workflows/CI.yml
rename to .github/workflows/github-actions.yml


[dubbo-rust] 11/38: Merge branch 'main' into dubbo_rust_1.0

Posted by li...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

liujun pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/dubbo-rust.git

commit 2e73b000b3ef87077860542d9a5e17d40d9377f3
Merge: 9b97473 04a3e3f
Author: johankoi <jo...@163.com>
AuthorDate: Wed Apr 27 00:37:37 2022 +0800

    Merge branch 'main' into dubbo_rust_1.0

 .github/workflows/CI.yml | 54 ++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 54 insertions(+)


[dubbo-rust] 26/38: refactor(dubbo): update code structure

Posted by li...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

liujun pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/dubbo-rust.git

commit 6d0180827c0c4ca69b9d042f88cba35937f1c983
Author: yang <96...@qq.com>
AuthorDate: Tue Jun 28 21:50:34 2022 +0800

    refactor(dubbo): update code structure
---
 dubbo/src/helloworld/helloworld.rs                 |  6 ++--
 dubbo/src/lib.rs                                   |  2 +-
 dubbo/src/main.rs                                  |  2 +-
 .../{service => protocol}/grpc/grpc_exporter.rs    |  3 +-
 .../src/{service => protocol}/grpc/grpc_invoker.rs |  4 +--
 .../{service => protocol}/grpc/grpc_protocol.rs    |  2 +-
 .../src/{service => protocol}/grpc/grpc_server.rs  | 31 -----------------
 dubbo/src/{service => protocol}/grpc/mod.rs        |  4 +--
 dubbo/src/{service => protocol}/invocation.rs      |  0
 dubbo/src/{service/protocol.rs => protocol/mod.rs} | 12 +++++--
 .../grpc_exporter.rs => protocol/server_desc.rs}   | 40 ++++++++++------------
 dubbo/src/service/mod.rs                           | 20 -----------
 12 files changed, 39 insertions(+), 87 deletions(-)

diff --git a/dubbo/src/helloworld/helloworld.rs b/dubbo/src/helloworld/helloworld.rs
index 2b2ef39..a7a2a8b 100644
--- a/dubbo/src/helloworld/helloworld.rs
+++ b/dubbo/src/helloworld/helloworld.rs
@@ -112,9 +112,9 @@ pub mod greeter_client {
 pub mod greeter_server {
     #![allow(unused_variables, dead_code, missing_docs, clippy::let_unit_value)]
 
-    use crate::service::grpc::grpc_server::DubboGrpcService;
-    use crate::service::grpc::grpc_server::ServiceDesc;
-    use crate::service::protocol::Invoker;
+    use crate::protocol::server_desc::ServiceDesc;
+    use crate::protocol::DubboGrpcService;
+    use crate::protocol::Invoker;
     use tonic::codegen::*;
 
     ///Generated trait containing gRPC methods that should be implemented for use with GreeterServer.
diff --git a/dubbo/src/lib.rs b/dubbo/src/lib.rs
index f7cfaef..e292e47 100644
--- a/dubbo/src/lib.rs
+++ b/dubbo/src/lib.rs
@@ -17,5 +17,5 @@
 
 pub mod common;
 pub mod helloworld;
-pub mod service;
+pub mod protocol;
 pub mod utils;
diff --git a/dubbo/src/main.rs b/dubbo/src/main.rs
index 0dd0e47..906e5cb 100644
--- a/dubbo/src/main.rs
+++ b/dubbo/src/main.rs
@@ -17,7 +17,7 @@
 
 pub mod common;
 pub mod helloworld;
-pub mod service;
+pub mod protocol;
 pub mod utils;
 
 #[tokio::main]
diff --git a/dubbo/src/service/grpc/grpc_exporter.rs b/dubbo/src/protocol/grpc/grpc_exporter.rs
similarity index 94%
copy from dubbo/src/service/grpc/grpc_exporter.rs
copy to dubbo/src/protocol/grpc/grpc_exporter.rs
index 591064a..55c41a8 100644
--- a/dubbo/src/service/grpc/grpc_exporter.rs
+++ b/dubbo/src/protocol/grpc/grpc_exporter.rs
@@ -15,8 +15,7 @@
  * limitations under the License.
  */
 
-use crate::service::protocol::Invoker;
-use crate::service::protocol::*;
+use crate::protocol::{Exporter, Invoker};
 
 pub struct GrpcExporter<T> {
     invoker: T,
diff --git a/dubbo/src/service/grpc/grpc_invoker.rs b/dubbo/src/protocol/grpc/grpc_invoker.rs
similarity index 97%
rename from dubbo/src/service/grpc/grpc_invoker.rs
rename to dubbo/src/protocol/grpc/grpc_invoker.rs
index 402e75a..e64a1db 100644
--- a/dubbo/src/service/grpc/grpc_invoker.rs
+++ b/dubbo/src/protocol/grpc/grpc_invoker.rs
@@ -22,8 +22,8 @@ use tonic::transport::Channel;
 use tonic::transport::Endpoint;
 
 use crate::common::url::Url;
-use crate::service::invocation;
-use crate::service::protocol::*;
+use crate::protocol::invocation;
+use crate::protocol::Invoker;
 
 pub struct GrpcInvoker {
     client: Grpc<Channel>,
diff --git a/dubbo/src/service/grpc/grpc_protocol.rs b/dubbo/src/protocol/grpc/grpc_protocol.rs
similarity index 98%
rename from dubbo/src/service/grpc/grpc_protocol.rs
rename to dubbo/src/protocol/grpc/grpc_protocol.rs
index 4762abc..b33468c 100644
--- a/dubbo/src/service/grpc/grpc_protocol.rs
+++ b/dubbo/src/protocol/grpc/grpc_protocol.rs
@@ -21,7 +21,7 @@ use super::grpc_exporter::GrpcExporter;
 use super::grpc_invoker::GrpcInvoker;
 use super::grpc_server::GrpcServer;
 use crate::common::url::Url;
-use crate::service::protocol::Protocol;
+use crate::protocol::Protocol;
 
 pub struct GrpcProtocol {
     server_map: HashMap<String, GrpcServer>,
diff --git a/dubbo/src/service/grpc/grpc_server.rs b/dubbo/src/protocol/grpc/grpc_server.rs
similarity index 78%
rename from dubbo/src/service/grpc/grpc_server.rs
rename to dubbo/src/protocol/grpc/grpc_server.rs
index 3cc5294..872257b 100644
--- a/dubbo/src/service/grpc/grpc_server.rs
+++ b/dubbo/src/protocol/grpc/grpc_server.rs
@@ -15,7 +15,6 @@
  * limitations under the License.
  */
 
-use std::collections::HashMap;
 use std::task::Context;
 use std::task::Poll;
 
@@ -30,36 +29,6 @@ use crate::helloworld::helloworld::greeter_server::GreeterServer;
 use crate::helloworld::helloworld::greeter_server::*;
 use crate::utils::boxed_clone::BoxCloneService;
 
-pub trait DubboGrpcService<T> {
-    fn set_proxy_impl(&mut self, invoker: T);
-    fn service_desc(&self) -> ServiceDesc;
-}
-
-//type ServiceDesc struct {
-//     ServiceName string
-//     // The pointer to the service interface. Used to check whether the user
-//     // provided implementation satisfies the interface requirements.
-//     HandlerType interface{}
-//     Methods     []MethodDesc
-//     Streams     []StreamDesc
-//     Metadata    interface{}
-// }
-
-pub struct ServiceDesc {
-    service_name: String,
-    // methods: HashMap<String, String> // "/Greeter/hello": "unary"
-}
-
-impl ServiceDesc {
-    pub fn new(service_name: String, _methods: HashMap<String, String>) -> Self {
-        Self { service_name }
-    }
-
-    pub fn get_service_name(&self) -> String {
-        self.service_name.clone()
-    }
-}
-
 // codegen
 pub fn register_greeter_server<T: Greeter>(
     server: T,
diff --git a/dubbo/src/service/grpc/mod.rs b/dubbo/src/protocol/grpc/mod.rs
similarity index 97%
rename from dubbo/src/service/grpc/mod.rs
rename to dubbo/src/protocol/grpc/mod.rs
index 91ee2c0..f5a6ca3 100644
--- a/dubbo/src/service/grpc/mod.rs
+++ b/dubbo/src/protocol/grpc/mod.rs
@@ -26,9 +26,9 @@ use std::sync::RwLock;
 
 use crate::helloworld::helloworld::greeter_server::Greeter;
 use crate::helloworld::helloworld::{HelloReply, HelloRequest};
+use crate::protocol::DubboGrpcService;
 use crate::utils::boxed_clone::BoxCloneService;
 use grpc_invoker::GrpcInvoker;
-use grpc_server::DubboGrpcService;
 
 pub type GrpcBoxCloneService = BoxCloneService<
     http::Request<hyper::Body>,
@@ -48,7 +48,7 @@ lazy_static! {
 #[tokio::test]
 async fn test_hello() {
     use crate::common::url::Url;
-    use crate::service::protocol::Protocol;
+    use crate::protocol::Protocol;
     use grpc_server::register_greeter_server;
 
     let (svc, dubbo_svc) = register_greeter_server(MyGreeter {});
diff --git a/dubbo/src/service/invocation.rs b/dubbo/src/protocol/invocation.rs
similarity index 100%
rename from dubbo/src/service/invocation.rs
rename to dubbo/src/protocol/invocation.rs
diff --git a/dubbo/src/service/protocol.rs b/dubbo/src/protocol/mod.rs
similarity index 88%
rename from dubbo/src/service/protocol.rs
rename to dubbo/src/protocol/mod.rs
index bec2b7f..4199142 100644
--- a/dubbo/src/service/protocol.rs
+++ b/dubbo/src/protocol/mod.rs
@@ -15,11 +15,14 @@
  * limitations under the License.
  */
 
-use super::invocation;
-use crate::common::url::Url;
+pub mod grpc;
+pub mod invocation;
+pub mod server_desc;
 
 use async_trait::async_trait;
 
+use crate::common::url::Url;
+
 #[async_trait]
 pub trait Protocol {
     type Invoker;
@@ -45,3 +48,8 @@ pub trait Invoker {
     fn destroy(&self);
     fn get_url(&self) -> Url;
 }
+
+pub trait DubboGrpcService<T> {
+    fn set_proxy_impl(&mut self, invoker: T);
+    fn service_desc(&self) -> server_desc::ServiceDesc;
+}
diff --git a/dubbo/src/service/grpc/grpc_exporter.rs b/dubbo/src/protocol/server_desc.rs
similarity index 54%
rename from dubbo/src/service/grpc/grpc_exporter.rs
rename to dubbo/src/protocol/server_desc.rs
index 591064a..84cbe92 100644
--- a/dubbo/src/service/grpc/grpc_exporter.rs
+++ b/dubbo/src/protocol/server_desc.rs
@@ -15,33 +15,29 @@
  * limitations under the License.
  */
 
-use crate::service::protocol::Invoker;
-use crate::service::protocol::*;
+//type ServiceDesc struct {
+//     ServiceName string
+//     // The pointer to the service interface. Used to check whether the user
+//     // provided implementation satisfies the interface requirements.
+//     HandlerType interface{}
+//     Methods     []MethodDesc
+//     Streams     []StreamDesc
+//     Metadata    interface{}
+// }
 
-pub struct GrpcExporter<T> {
-    invoker: T,
-}
+use std::collections::HashMap;
 
-impl<T> GrpcExporter<T> {
-    pub fn new(_key: String, invoker: T) -> GrpcExporter<T> {
-        Self { invoker }
-    }
+pub struct ServiceDesc {
+    service_name: String,
+    // methods: HashMap<String, String> // "/Greeter/hello": "unary"
 }
 
-impl<T: Invoker + Clone> Exporter for GrpcExporter<T> {
-    type InvokerType = T;
-
-    fn unexport(&self) {}
-
-    fn get_invoker(&self) -> Self::InvokerType {
-        self.invoker.clone()
+impl ServiceDesc {
+    pub fn new(service_name: String, _methods: HashMap<String, String>) -> Self {
+        Self { service_name }
     }
-}
 
-impl<T: Invoker + Clone> Clone for GrpcExporter<T> {
-    fn clone(&self) -> Self {
-        Self {
-            invoker: self.invoker.clone(),
-        }
+    pub fn get_service_name(&self) -> String {
+        self.service_name.clone()
     }
 }
diff --git a/dubbo/src/service/mod.rs b/dubbo/src/service/mod.rs
deleted file mode 100644
index 753f567..0000000
--- a/dubbo/src/service/mod.rs
+++ /dev/null
@@ -1,20 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You 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.
- */
-
-pub mod grpc;
-pub mod invocation;
-pub mod protocol;


[dubbo-rust] 33/38: style: cargo check

Posted by li...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

liujun pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/dubbo-rust.git

commit 6337143b5f053ee70ce15a389533f5c061d201ee
Author: yangyang <96...@qq.com>
AuthorDate: Tue Jul 19 22:55:34 2022 +0800

    style: cargo check
---
 config/src/config.rs                         |  5 +--
 dubbo/src/echo/echo_client.rs                | 50 ++++------------------------
 dubbo/src/protocol/grpc/grpc_server.rs       |  2 +-
 dubbo/src/protocol/triple/triple_exporter.rs |  6 ++++
 dubbo/src/protocol/triple/triple_protocol.rs |  6 ++++
 triple/src/client/grpc.rs                    |  4 +--
 triple/src/server/decode.rs                  |  3 +-
 triple/src/transport/service.rs              |  7 ++--
 8 files changed, 29 insertions(+), 54 deletions(-)

diff --git a/config/src/config.rs b/config/src/config.rs
index 771c7ca..a53dcd2 100644
--- a/config/src/config.rs
+++ b/config/src/config.rs
@@ -20,6 +20,7 @@ use std::{any, collections::HashMap};
 /// used to storage all structed config, from some source: cmd, file..;
 /// Impl Config trait, business init by read Config trait
 #[allow(dead_code)]
+#[derive(Debug, Default)]
 pub struct RootConfig {
     name: String,
     data: HashMap<String, Box<dyn any::Any>>,
@@ -53,7 +54,7 @@ impl Config for RootConfig {
             None => false,
             Some(val) => {
                 if let Some(v) = val.downcast_ref::<bool>() {
-                    return *v;
+                    *v
                 } else {
                     false
                 }
@@ -66,7 +67,7 @@ impl Config for RootConfig {
             None => "".to_string(),
             Some(val) => {
                 if let Some(v) = val.downcast_ref::<String>() {
-                    return v.into();
+                    v.into()
                 } else {
                     "".to_string()
                 }
diff --git a/dubbo/src/echo/echo_client.rs b/dubbo/src/echo/echo_client.rs
index 8db5e89..0f8215b 100644
--- a/dubbo/src/echo/echo_client.rs
+++ b/dubbo/src/echo/echo_client.rs
@@ -13,6 +13,12 @@ pub struct EchoClient {
     uri: String,
 }
 
+impl Default for EchoClient {
+    fn default() -> Self {
+        Self::new()
+    }
+}
+
 impl EchoClient {
     pub fn new() -> Self {
         Self {
@@ -29,10 +35,6 @@ impl EchoClient {
         self
     }
 
-    // pub async fn connect(&self, url: &str) {
-    //     self.inner.request(req)
-    // }
-
     pub async fn bidirectional_streaming_echo(
         mut self,
         req: impl IntoStreamingRequest<Message = HelloRequest>,
@@ -45,44 +47,6 @@ impl EchoClient {
                 http::uri::PathAndQuery::from_static("/bidi_stream"),
             )
             .await
-        // Stream trait to Body
-        // let mut codec = SerdeCodec::<HelloRequest, HelloReply>::default();
-        // let stream = req.into_streaming_request();
-        // let en = encode(codec.encoder(), stream.into_inner().map(Ok));
-        // let body = hyper::Body::wrap_stream(en);
-
-        // let req = http::Request::builder()
-        //     .version(Version::HTTP_2)
-        //     .uri(self.uri.clone() + "/bidi_stream")
-        //     .method("POST")
-        //     .body(body)
-        //     .unwrap();
-
-        // let response = self.inner.request(req).await;
-
-        // match response {
-        //     Ok(v) => {
-        //         println!("response: {:?}", v);
-        //         // println!("grpc status: {:?}", v)
-        //         let mut resp = v.map(|body| Streaming::new(body, codec.decoder()));
-        //         // TODO: rpc response to http response
-        //         let trailers_only_status = tonic::Status::from_header_map(resp.headers_mut());
-        //         println!("trailer only status: {:?}", trailers_only_status);
-
-        //         let (parts, mut body) = resp.into_parts();
-        //         let trailer = body.trailer().await.unwrap();
-        //         println!("trailer: {:?}", trailer);
-
-        //         // if let Some(trailer) = trailer.take() {
-        //         //     println!("trailer: {:?}", trailer);
-        //         // }
-        //         return Ok(Response::new(body));
-        //     }
-        //     Err(err) => {
-        //         println!("error: {}", err);
-        //         return Err(tonic::Status::new(tonic::Code::Internal, err.to_string()));
-        //     }
-        // }
     }
 
     pub async fn say_hello(
@@ -117,7 +81,7 @@ impl EchoClient {
             }
             Err(err) => {
                 println!("{}", err);
-                return Err(tonic::Status::new(tonic::Code::Internal, err.to_string()));
+                Err(tonic::Status::new(tonic::Code::Internal, err.to_string()))
             }
         }
     }
diff --git a/dubbo/src/protocol/grpc/grpc_server.rs b/dubbo/src/protocol/grpc/grpc_server.rs
index 872257b..b949a55 100644
--- a/dubbo/src/protocol/grpc/grpc_server.rs
+++ b/dubbo/src/protocol/grpc/grpc_server.rs
@@ -34,7 +34,7 @@ pub fn register_greeter_server<T: Greeter>(
     server: T,
 ) -> (super::GrpcBoxCloneService, super::DubboGrpcBox) {
     let hello = GreeterServer::<T, GrpcInvoker>::new(server);
-    (BoxCloneService::new(hello.clone()), Box::new(hello.clone()))
+    (BoxCloneService::new(hello.clone()), Box::new(hello))
 }
 
 // 每个service对应一个Server
diff --git a/dubbo/src/protocol/triple/triple_exporter.rs b/dubbo/src/protocol/triple/triple_exporter.rs
index 5f66863..fcddf79 100644
--- a/dubbo/src/protocol/triple/triple_exporter.rs
+++ b/dubbo/src/protocol/triple/triple_exporter.rs
@@ -10,6 +10,12 @@ impl TripleExporter {
     }
 }
 
+impl Default for TripleExporter {
+    fn default() -> Self {
+        Self::new()
+    }
+}
+
 impl Exporter for TripleExporter {
     type InvokerType = TripleInvoker;
 
diff --git a/dubbo/src/protocol/triple/triple_protocol.rs b/dubbo/src/protocol/triple/triple_protocol.rs
index 876f06c..e3abb48 100644
--- a/dubbo/src/protocol/triple/triple_protocol.rs
+++ b/dubbo/src/protocol/triple/triple_protocol.rs
@@ -12,6 +12,12 @@ pub struct TripleProtocol {
     servers: HashMap<String, TripleServer>,
 }
 
+impl Default for TripleProtocol {
+    fn default() -> Self {
+        Self::new()
+    }
+}
+
 impl TripleProtocol {
     pub fn new() -> Self {
         TripleProtocol {
diff --git a/triple/src/client/grpc.rs b/triple/src/client/grpc.rs
index 5126ed1..1277868 100644
--- a/triple/src/client/grpc.rs
+++ b/triple/src/client/grpc.rs
@@ -145,10 +145,10 @@ impl TripleClient {
                 let resp = v.map(|body| Streaming::new(body, codec.decoder()));
 
                 let (_parts, body) = resp.into_parts();
-                return Ok(Response::new(body));
+                Ok(Response::new(body))
             }
             Err(err) => {
-                return Err(tonic::Status::new(tonic::Code::Internal, err.to_string()));
+                Err(tonic::Status::new(tonic::Code::Internal, err.to_string()))
             }
         }
     }
diff --git a/triple/src/server/decode.rs b/triple/src/server/decode.rs
index 06ce3ae..3c62aeb 100644
--- a/triple/src/server/decode.rs
+++ b/triple/src/server/decode.rs
@@ -76,8 +76,7 @@ impl<T> Streaming<T> {
         // while self.message().await?.is_some() {}
 
         let trailer = future::poll_fn(|cx| Pin::new(&mut self.body).poll_trailers(cx)).await;
-        let trailer = trailer.map(|data| data.map(MetadataMap::from_headers));
-        trailer
+        trailer.map(|data| data.map(MetadataMap::from_headers))
     }
 
     pub fn decode_chunk(&mut self) -> Result<Option<T>, tonic::Status> {
diff --git a/triple/src/transport/service.rs b/triple/src/transport/service.rs
index 8001ef5..e470601 100644
--- a/triple/src/transport/service.rs
+++ b/triple/src/transport/service.rs
@@ -48,7 +48,7 @@ pub struct DubboServer {
 impl DubboServer {
     pub fn with_accpet_http1(self, accept_http2: bool) -> Self {
         Self {
-            accept_http2: accept_http2,
+            accept_http2,
             ..self
         }
     }
@@ -170,9 +170,8 @@ where
 impl BusinessConfig for DubboServer {
     fn init() -> Self {
         let conf = config::get_global_config();
-        let server = DubboServer::new()
-            .with_accpet_http1(conf.bool("dubbo.server.accept_http2".to_string()));
-        server
+        DubboServer::new()
+            .with_accpet_http1(conf.bool("dubbo.server.accept_http2".to_string()))
     }
 
     fn load() -> Result<(), std::convert::Infallible> {


[dubbo-rust] 17/38: Fix: fix file license header format.

Posted by li...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

liujun pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/dubbo-rust.git

commit 8fe7044cd86d0bb5dd07d51cd0ff8fb5cd58a813
Author: Zonglei Dong <do...@apache.org>
AuthorDate: Sat May 14 15:28:08 2022 +0800

    Fix: fix file license header format.
---
 .asf.yaml | 2 --
 1 file changed, 2 deletions(-)

diff --git a/.asf.yaml b/.asf.yaml
index 11f9b19..9cc0f3d 100644
--- a/.asf.yaml
+++ b/.asf.yaml
@@ -1,5 +1,4 @@
 #
-#
 #   Licensed to the Apache Software Foundation (ASF) under one or more
 #   contributor license agreements.  See the NOTICE file distributed with
 #   this work for additional information regarding copyright ownership.
@@ -15,7 +14,6 @@
 #   See the License for the specific language governing permissions and
 #   limitations under the License.
 #
-#
 
 notifications:
   commits:      commits@dubbo.apache.org


[dubbo-rust] 06/38: Mod: empty examples src

Posted by li...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

liujun pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/dubbo-rust.git

commit b630a29995480e5537e7223cfe53d4360772cefb
Author: johankoi <jo...@163.com>
AuthorDate: Mon Apr 25 15:35:30 2022 +0800

    Mod: empty  examples src
    
    Signed-off-by: johankoi <jo...@163.com>
---
 examples/Cargo.toml                        | 38 ------------------------------
 examples/build.rs                          |  0
 examples/proto/helloworld/helloworld.proto | 37 -----------------------------
 examples/src/grpc-web/client.rs            |  0
 examples/src/grpc-web/server.rs            |  0
 examples/src/helloworld/client.rs          |  0
 examples/src/helloworld/server.rs          |  0
 examples/src/helloworld/server_blocking.rs |  0
 8 files changed, 75 deletions(-)

diff --git a/examples/Cargo.toml b/examples/Cargo.toml
deleted file mode 100644
index a477bf0..0000000
--- a/examples/Cargo.toml
+++ /dev/null
@@ -1,38 +0,0 @@
-[package]
-name = "examples"
-publish = false
-version = "0.1.0"
-edition = "2022"
-
-[[bin]]
-name = "helloworld-server"
-path = "src/helloworld/server.rs"
-
-[[bin]]
-name = "helloworld-client"
-path = "src/helloworld/client.rs"
-
-[[bin]]
-name = "grpc-web-server"
-path = "src/grpc-web/server.rs"
-
-[[bin]]
-name = "grpc-web-client"
-path = "src/grpc-web/client.rs"
-
-[dependencies]
-async-stream = "0.3"
-futures = { version = "0.3", default-features = false, features = ["alloc"] }
-prost = "0.10"
-tokio = { version = "1.0", features = [ "rt-multi-thread", "time", "fs", "macros", "net",] }
-tokio-stream = { version = "0.1", features = ["net"] }
-# Required for wellknown types
-prost-types = "0.10"
-# grpc-web example
-bytes = "1"
-tokio-rustls = "*"
-hyper-rustls = { version = "0.23", features = ["http2"] }
-rustls-pemfile = "*"
-tower-http = { version = "0.2", features = ["add-extension"] }
-
-[build-dependencies]
diff --git a/examples/build.rs b/examples/build.rs
deleted file mode 100644
index e69de29..0000000
diff --git a/examples/proto/helloworld/helloworld.proto b/examples/proto/helloworld/helloworld.proto
deleted file mode 100644
index 8de5d08..0000000
--- a/examples/proto/helloworld/helloworld.proto
+++ /dev/null
@@ -1,37 +0,0 @@
-// Copyright 2015 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.
-
-syntax = "proto3";
-
-option java_multiple_files = true;
-option java_package = "io.grpc.examples.helloworld";
-option java_outer_classname = "HelloWorldProto";
-
-package helloworld;
-
-// The greeting service definition.
-service Greeter {
-  // Sends a greeting
-  rpc SayHello (HelloRequest) returns (HelloReply) {}
-}
-
-// The request message containing the user's name.
-message HelloRequest {
-  string name = 1;
-}
-
-// The response message containing the greetings
-message HelloReply {
-  string message = 1;
-}
\ No newline at end of file
diff --git a/examples/src/grpc-web/client.rs b/examples/src/grpc-web/client.rs
deleted file mode 100644
index e69de29..0000000
diff --git a/examples/src/grpc-web/server.rs b/examples/src/grpc-web/server.rs
deleted file mode 100644
index e69de29..0000000
diff --git a/examples/src/helloworld/client.rs b/examples/src/helloworld/client.rs
deleted file mode 100644
index e69de29..0000000
diff --git a/examples/src/helloworld/server.rs b/examples/src/helloworld/server.rs
deleted file mode 100644
index e69de29..0000000
diff --git a/examples/src/helloworld/server_blocking.rs b/examples/src/helloworld/server_blocking.rs
deleted file mode 100644
index e69de29..0000000


[dubbo-rust] 32/38: feat(triple): impl triple protocol based json serialization

Posted by li...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

liujun pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/dubbo-rust.git

commit fb37cf280af4baebc14ccaff922b0b1fcfade01a
Author: yangyang <96...@qq.com>
AuthorDate: Tue Jul 19 22:35:59 2022 +0800

    feat(triple): impl triple protocol based json serialization
---
 Cargo.toml                                      |   3 +-
 config/src/config.rs                            |  86 ++++++++++
 config/src/lib.rs                               |   4 +
 dubbo/Cargo.toml                                |  10 +-
 dubbo/src/common/url.rs                         |   2 +-
 dubbo/src/echo/echo_client.rs                   | 124 ++++++++++++++
 dubbo/src/echo/echo_server.rs                   | 188 +++++++++++++++++++++
 dubbo/src/echo/mod.rs                           | 214 ++++++++++++++++++++++++
 dubbo/src/init.rs                               | 110 ++++++++++++
 dubbo/src/lib.rs                                |   5 +
 dubbo/src/main.rs                               |   7 +
 dubbo/src/protocol/grpc/grpc_protocol.rs        |   2 +-
 dubbo/src/protocol/invocation.rs                |  44 +++++
 dubbo/src/protocol/mod.rs                       |  11 +-
 dubbo/src/protocol/triple/mod.rs                |  21 +++
 dubbo/src/protocol/triple/triple_exporter.rs    |  23 +++
 dubbo/src/protocol/triple/triple_invoker.rs     |  38 +++++
 dubbo/src/protocol/triple/triple_protocol.rs    |  48 ++++++
 dubbo/src/protocol/triple/triple_server.rs      |  44 +++++
 {dubbo => triple}/Cargo.toml                    |  18 +-
 triple/src/client/grpc.rs                       | 155 +++++++++++++++++
 dubbo/src/lib.rs => triple/src/client/mod.rs    |   7 +-
 triple/src/codec/buffer.rs                      | 138 +++++++++++++++
 triple/src/codec/mod.rs                         |  71 ++++++++
 triple/src/codec/serde_codec.rs                 |  89 ++++++++++
 triple/src/invocation.rs                        | 125 ++++++++++++++
 dubbo/src/main.rs => triple/src/lib.rs          |  22 ++-
 {dubbo => triple}/src/main.rs                   |  24 ++-
 dubbo/src/lib.rs => triple/src/server/consts.rs |  11 +-
 triple/src/server/decode.rs                     | 166 ++++++++++++++++++
 triple/src/server/encode.rs                     | 169 +++++++++++++++++++
 dubbo/src/main.rs => triple/src/server/mod.rs   |  15 +-
 triple/src/server/server.rs                     | 138 +++++++++++++++
 triple/src/server/service.rs                    |  68 ++++++++
 dubbo/src/lib.rs => triple/src/transport/mod.rs |   7 +-
 triple/src/transport/service.rs                 | 181 ++++++++++++++++++++
 36 files changed, 2343 insertions(+), 45 deletions(-)

diff --git a/Cargo.toml b/Cargo.toml
index 970aeb1..787689c 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -5,5 +5,6 @@ members = [
   "metadata",
   "common",
   "config",
-  "dubbo"
+  "dubbo",
+  "triple"
 ]
diff --git a/config/src/config.rs b/config/src/config.rs
new file mode 100644
index 0000000..771c7ca
--- /dev/null
+++ b/config/src/config.rs
@@ -0,0 +1,86 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.
+ */
+
+use std::{any, collections::HashMap};
+
+/// used to storage all structed config, from some source: cmd, file..;
+/// Impl Config trait, business init by read Config trait
+#[allow(dead_code)]
+pub struct RootConfig {
+    name: String,
+    data: HashMap<String, Box<dyn any::Any>>,
+}
+
+pub fn get_global_config() -> RootConfig {
+    RootConfig::new()
+}
+
+impl RootConfig {
+    pub fn new() -> Self {
+        Self {
+            name: "dubbo".to_string(),
+            data: HashMap::new(),
+        }
+    }
+
+    pub fn load(&mut self) {
+        // 通过环境变量读取某个文件。加在到内存中
+        self.data.insert(
+            "dubbo.provider.url".to_string(),
+            Box::new("dubbo://127.0.0.1:8888/?serviceName=hellworld".to_string()),
+        );
+        // self.data.insert("dubbo.consume.", v)
+    }
+}
+
+impl Config for RootConfig {
+    fn bool(&self, key: String) -> bool {
+        match self.data.get(&key) {
+            None => false,
+            Some(val) => {
+                if let Some(v) = val.downcast_ref::<bool>() {
+                    return *v;
+                } else {
+                    false
+                }
+            }
+        }
+    }
+
+    fn string(&self, key: String) -> String {
+        match self.data.get(&key) {
+            None => "".to_string(),
+            Some(val) => {
+                if let Some(v) = val.downcast_ref::<String>() {
+                    return v.into();
+                } else {
+                    "".to_string()
+                }
+            }
+        }
+    }
+}
+
+pub trait BusinessConfig {
+    fn init() -> Self;
+    fn load() -> Result<(), std::convert::Infallible>;
+}
+
+pub trait Config {
+    fn bool(&self, key: String) -> bool;
+    fn string(&self, key: String) -> String;
+}
diff --git a/config/src/lib.rs b/config/src/lib.rs
index 3e01853..edbaf58 100644
--- a/config/src/lib.rs
+++ b/config/src/lib.rs
@@ -15,6 +15,10 @@
  * limitations under the License.
  */
 
+pub mod config;
+
+pub use config::*;
+
 #[cfg(test)]
 mod tests {
     #[test]
diff --git a/dubbo/Cargo.toml b/dubbo/Cargo.toml
index 7ce6865..1a693ba 100644
--- a/dubbo/Cargo.toml
+++ b/dubbo/Cargo.toml
@@ -11,13 +11,14 @@ path = "src/helloworld/client.rs"
 
 [dependencies]
 h2 = {version = "0.3", optional = true}
-hyper = "0.14.19"
+hyper = { version = "0.14.19", features = ["full"]}
 http = "0.2"
 tonic = {version ="0.7.2", features = ["compression",]}
 tower-service = "0.3.1"
 http-body = "0.4.4"
 tower = "0.4.12"
 futures-util = {version = "0.3", default-features = false}
+futures-core = {version = "0.3", default-features = false}
 tokio = { version = "1.0", features = [ "rt-multi-thread", "time", "fs", "macros", "net", "signal"] }
 prost-derive = {version = "0.10", optional = true}
 prost = "0.10.4"
@@ -25,4 +26,11 @@ prost-types = { version = "0.6", default-features = false }
 lazy_static = "1.3.0"
 async-trait = "0.1.56"
 tower-layer = "0.3"
+bytes = "1.0"
+pin-project = "1.0"
+serde_json = "1.0.82"
+serde = {version="1.0.138", features = ["derive"]}
+tokio-stream = "0.1"
 
+config = {path = "../config"}
+triple = {path = "../triple"}
\ No newline at end of file
diff --git a/dubbo/src/common/url.rs b/dubbo/src/common/url.rs
index e610de3..5d7ce69 100644
--- a/dubbo/src/common/url.rs
+++ b/dubbo/src/common/url.rs
@@ -15,7 +15,7 @@
  * limitations under the License.
  */
 
-#[derive(Debug, Clone)]
+#[derive(Debug, Clone, Default)]
 pub struct Url {
     pub url: String,
     pub service_key: String,
diff --git a/dubbo/src/echo/echo_client.rs b/dubbo/src/echo/echo_client.rs
new file mode 100644
index 0000000..8db5e89
--- /dev/null
+++ b/dubbo/src/echo/echo_client.rs
@@ -0,0 +1,124 @@
+use std::str::FromStr;
+
+use super::echo_server::{HelloReply, HelloRequest};
+use bytes::Buf;
+
+use triple::client::TripleClient;
+use triple::codec::serde_codec::SerdeCodec;
+use triple::invocation::*;
+use triple::server::Streaming;
+
+pub struct EchoClient {
+    inner: TripleClient,
+    uri: String,
+}
+
+impl EchoClient {
+    pub fn new() -> Self {
+        Self {
+            inner: TripleClient::new(),
+            uri: "".to_string(),
+        }
+    }
+
+    pub fn with_uri(mut self, uri: String) -> Self {
+        self.uri = uri;
+        self.inner = self
+            .inner
+            .with_authority(http::uri::Authority::from_str(&self.uri).unwrap());
+        self
+    }
+
+    // pub async fn connect(&self, url: &str) {
+    //     self.inner.request(req)
+    // }
+
+    pub async fn bidirectional_streaming_echo(
+        mut self,
+        req: impl IntoStreamingRequest<Message = HelloRequest>,
+    ) -> Result<Response<Streaming<HelloReply>>, tonic::Status> {
+        let codec = SerdeCodec::<HelloRequest, HelloReply>::default();
+        self.inner
+            .bidi_streaming(
+                req,
+                codec,
+                http::uri::PathAndQuery::from_static("/bidi_stream"),
+            )
+            .await
+        // Stream trait to Body
+        // let mut codec = SerdeCodec::<HelloRequest, HelloReply>::default();
+        // let stream = req.into_streaming_request();
+        // let en = encode(codec.encoder(), stream.into_inner().map(Ok));
+        // let body = hyper::Body::wrap_stream(en);
+
+        // let req = http::Request::builder()
+        //     .version(Version::HTTP_2)
+        //     .uri(self.uri.clone() + "/bidi_stream")
+        //     .method("POST")
+        //     .body(body)
+        //     .unwrap();
+
+        // let response = self.inner.request(req).await;
+
+        // match response {
+        //     Ok(v) => {
+        //         println!("response: {:?}", v);
+        //         // println!("grpc status: {:?}", v)
+        //         let mut resp = v.map(|body| Streaming::new(body, codec.decoder()));
+        //         // TODO: rpc response to http response
+        //         let trailers_only_status = tonic::Status::from_header_map(resp.headers_mut());
+        //         println!("trailer only status: {:?}", trailers_only_status);
+
+        //         let (parts, mut body) = resp.into_parts();
+        //         let trailer = body.trailer().await.unwrap();
+        //         println!("trailer: {:?}", trailer);
+
+        //         // if let Some(trailer) = trailer.take() {
+        //         //     println!("trailer: {:?}", trailer);
+        //         // }
+        //         return Ok(Response::new(body));
+        //     }
+        //     Err(err) => {
+        //         println!("error: {}", err);
+        //         return Err(tonic::Status::new(tonic::Code::Internal, err.to_string()));
+        //     }
+        // }
+    }
+
+    pub async fn say_hello(
+        &self,
+        req: Request<HelloRequest>,
+    ) -> Result<Response<HelloReply>, tonic::Status> {
+        let (_parts, body) = req.into_parts();
+        let v = serde_json::to_vec(&body).unwrap();
+        let req = hyper::Request::builder()
+            .uri("http://".to_owned() + &self.uri.clone() + "/hello")
+            .method("POST")
+            .body(hyper::Body::from(v))
+            .unwrap();
+
+        println!("request: {:?}", req);
+        let response = hyper::Client::builder().build_http().request(req).await;
+
+        match response {
+            Ok(v) => {
+                println!("{:?}", v);
+                let (_parts, body) = v.into_parts();
+                let req_body = hyper::body::to_bytes(body).await.unwrap();
+                let v = req_body.chunk();
+                // let codec = SerdeCodec::<HelloReply, HelloRequest>::default();
+                let data: HelloReply = match serde_json::from_slice(v) {
+                    Ok(data) => data,
+                    Err(err) => {
+                        return Err(tonic::Status::new(tonic::Code::Internal, err.to_string()))
+                    }
+                };
+                Ok(Response::new(data))
+            }
+            Err(err) => {
+                println!("{}", err);
+                return Err(tonic::Status::new(tonic::Code::Internal, err.to_string()));
+            }
+        }
+    }
+}
diff --git a/dubbo/src/echo/echo_server.rs b/dubbo/src/echo/echo_server.rs
new file mode 100644
index 0000000..d6e9476
--- /dev/null
+++ b/dubbo/src/echo/echo_server.rs
@@ -0,0 +1,188 @@
+use async_trait::async_trait;
+
+use tonic::codegen::BoxFuture;
+use triple::codec::serde_codec::SerdeCodec;
+// 定义EchoServer
+// EchoServer 实现了自定义接口,同时可以处理请求分发
+use crate::protocol::triple::triple_invoker::TripleInvoker;
+use crate::protocol::DubboGrpcService;
+use crate::protocol::Invoker;
+use http_body::Body;
+use std::fmt::Debug;
+use std::sync::Arc;
+
+use serde::{Deserialize, Serialize};
+use std::task::Poll;
+use tower_service::Service;
+use triple::invocation::{Request, Response};
+use triple::server::server::TripleServer;
+use triple::server::service::{StreamingSvc, UnaryService};
+use triple::BoxBody;
+
+pub type StdError = Box<dyn std::error::Error + Send + Sync + 'static>;
+
+#[derive(Debug, Clone, Default, PartialEq, Serialize, Deserialize)]
+pub struct HelloRequest {
+    pub name: String,
+}
+
+#[derive(Debug, Clone, Default, PartialEq, Serialize, Deserialize)]
+pub struct HelloReply {
+    pub reply: String,
+}
+
+#[async_trait]
+pub trait Echo: Send + Sync + 'static {
+    async fn hello(
+        &self,
+        req: Request<HelloRequest>,
+    ) -> Result<Response<HelloReply>, tonic::Status>;
+
+    type BidirectionalStreamingEchoStream: futures_util::Stream<Item = Result<HelloReply, tonic::Status>>
+        + Send
+        + 'static;
+    /// BidirectionalStreamingEcho is bidi streaming.
+    async fn bidirectional_streaming_echo(
+        &self,
+        request: Request<triple::server::Streaming<HelloRequest>>,
+    ) -> Result<Response<Self::BidirectionalStreamingEchoStream>, tonic::Status>;
+}
+
+struct _Inner<T>(Arc<T>);
+
+#[derive(Clone)]
+pub struct EchoServer<T, I = TripleInvoker> {
+    inner: _Inner<T>,
+    invoker: Option<I>,
+}
+
+impl<T, I> EchoServer<T, I> {
+    pub fn new(inner: T) -> Self {
+        Self {
+            inner: _Inner(Arc::new(inner)),
+            invoker: None,
+        }
+    }
+}
+
+impl<T: Echo, I, B> Service<http::Request<B>> for EchoServer<T, I>
+where
+    B: Body + Send + 'static,
+    B::Error: Into<StdError> + Debug + Send,
+    <B as Body>::Data: Send,
+    I: Invoker + Send,
+{
+    type Response = http::Response<BoxBody>;
+
+    type Error = std::convert::Infallible;
+
+    type Future = BoxFuture<Self::Response, Self::Error>;
+
+    fn poll_ready(&mut self, _cx: &mut std::task::Context<'_>) -> Poll<Result<(), Self::Error>> {
+        Poll::Ready(Ok(()))
+    }
+
+    fn call(&mut self, req: http::Request<B>) -> Self::Future {
+        let inner = self.inner.clone();
+        match req.uri().path() {
+            "/hello" => {
+                struct UnaryServer<T> {
+                    inner: _Inner<T>,
+                }
+
+                impl<T: Echo> UnaryService<HelloRequest> for UnaryServer<T> {
+                    type Response = HelloReply;
+
+                    type Future = BoxFuture<Response<Self::Response>, tonic::Status>;
+
+                    fn call(&mut self, req: Request<HelloRequest>) -> Self::Future {
+                        let inner = self.inner.0.clone();
+                        let fut = async move { inner.hello(req).await };
+                        Box::pin(fut)
+                    }
+                }
+
+                let fut = async move {
+                    let mut server =
+                        TripleServer::new(SerdeCodec::<HelloReply, HelloRequest>::default());
+                    let resp = server.unary(UnaryServer { inner }, req).await;
+                    Ok(resp)
+                };
+
+                Box::pin(fut)
+            }
+            "/bidi_stream" => {
+                struct StreamingServer<T> {
+                    inner: _Inner<T>,
+                }
+                impl<T: Echo> StreamingSvc<HelloRequest> for StreamingServer<T> {
+                    type Response = HelloReply;
+
+                    type ResponseStream = T::BidirectionalStreamingEchoStream;
+
+                    type Future = BoxFuture<Response<Self::ResponseStream>, tonic::Status>;
+
+                    fn call(
+                        &mut self,
+                        req: Request<triple::server::Streaming<HelloRequest>>,
+                    ) -> Self::Future {
+                        let inner = self.inner.0.clone();
+                        let fut = async move { inner.bidirectional_streaming_echo(req).await };
+                        Box::pin(fut)
+                    }
+                }
+
+                let fut = async move {
+                    let mut server =
+                        TripleServer::new(SerdeCodec::<HelloReply, HelloRequest>::default());
+                    let resp = server.bidi_streaming(StreamingServer { inner }, req).await;
+                    Ok(resp)
+                };
+
+                Box::pin(fut)
+            }
+            _ => {
+                Box::pin(async move {
+                    Ok(http::Response::builder()
+                        .status(200)
+                        .header("grpc-status", "12")
+                        .header("content-type", "application/grpc")
+                        // .body(hyper::Body::from("implement...").map_err(|err| match err {}).boxed())
+                        // .body(hyper::Body::from("implement...").map_err(|err| std::convert::Infallible).into())
+                        // .body(req.into_body())
+                        .body(
+                            http_body::Empty::new()
+                                .map_err(|err| match err {})
+                                .boxed_unsync(),
+                        )
+                        .unwrap())
+                })
+            }
+        }
+    }
+}
+
+impl<T, I> DubboGrpcService<I> for EchoServer<T, I>
+where
+    I: Invoker + Send + Sync + 'static,
+{
+    fn set_proxy_impl(&mut self, invoker: I) {
+        self.invoker = Some(invoker);
+    }
+
+    fn service_desc(&self) -> crate::protocol::server_desc::ServiceDesc {
+        todo!()
+    }
+}
+
+impl<T> Clone for _Inner<T> {
+    fn clone(&self) -> Self {
+        Self(self.0.clone())
+    }
+}
+
+impl<T: Debug> Debug for _Inner<T> {
+    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
+        write!(f, "Inner {:?}", self.0)
+    }
+}
diff --git a/dubbo/src/echo/mod.rs b/dubbo/src/echo/mod.rs
new file mode 100644
index 0000000..356fa9a
--- /dev/null
+++ b/dubbo/src/echo/mod.rs
@@ -0,0 +1,214 @@
+pub mod echo_client;
+pub mod echo_server;
+
+use futures_util::Stream;
+use futures_util::StreamExt;
+use std::io::ErrorKind;
+use std::pin::Pin;
+
+use tokio::sync::mpsc;
+
+use tokio_stream::wrappers::ReceiverStream;
+use tonic::async_trait;
+
+pub use self::echo_server::{Echo, EchoServer, HelloReply, HelloRequest};
+use triple::invocation::*;
+
+#[tokio::test]
+async fn test_client() {
+    use self::echo_client::EchoClient;
+    use self::echo_server::HelloRequest;
+    use futures_util::StreamExt;
+    use triple::invocation::*;
+
+    let cli = EchoClient::new().with_uri("127.0.0.1:8888".to_string());
+    let resp = cli
+        .say_hello(Request::new(HelloRequest {
+            name: "message from client".to_string(),
+        }))
+        .await;
+    let resp = match resp {
+        Ok(resp) => resp,
+        Err(err) => return println!("{:?}", err),
+    };
+    let (_parts, body) = resp.into_parts();
+    println!("Response: {:?}", body);
+
+    let data = vec![
+        HelloRequest {
+            name: "msg1 from client".to_string(),
+        },
+        HelloRequest {
+            name: "msg2 from client".to_string(),
+        },
+        HelloRequest {
+            name: "msg3 from client".to_string(),
+        },
+    ];
+    let req = futures_util::stream::iter(data);
+
+    let bidi_resp = cli.bidirectional_streaming_echo(req).await.unwrap();
+
+    let (_parts, mut body) = bidi_resp.into_parts();
+    // let trailer = body.trailer().await.unwrap();
+    // println!("trailer: {:?}", trailer);
+    while let Some(item) = body.next().await {
+        match item {
+            Ok(v) => {
+                println!("reply: {:?}", v);
+            }
+            Err(err) => {
+                println!("err: {:?}", err);
+            }
+        }
+    }
+    let trailer = body.trailer().await.unwrap();
+    println!("trailer: {:?}", trailer);
+}
+
+type ResponseStream = Pin<Box<dyn Stream<Item = Result<HelloReply, tonic::Status>> + Send>>;
+
+#[tokio::test]
+async fn test_server() {
+    use std::net::ToSocketAddrs;
+    use tokio::time::Duration;
+
+    let esi = EchoServer::<EchoServerImpl>::new(EchoServerImpl {
+        name: "echo server impl".to_string(),
+    });
+    // esi.set_proxy_impl(TripleInvoker);
+
+    let name = "echoServer".to_string();
+    println!("server listening, 0.0.0.0:8888");
+    triple::transport::DubboServer::new()
+        .add_service(name.clone(), esi)
+        .with_http2_keepalive_timeout(Duration::from_secs(60))
+        .serve(
+            name.clone(),
+            "0.0.0.0:8888".to_socket_addrs().unwrap().next().unwrap(),
+        )
+        .await
+        .unwrap();
+    // server.add_service(esi.into());
+}
+
+#[tokio::test]
+async fn test_triple_protocol() {
+    use crate::common::url::Url;
+    use crate::protocol::triple::triple_protocol::TripleProtocol;
+    use crate::protocol::Protocol;
+    use crate::utils::boxed_clone::BoxCloneService;
+
+    // crate::init::init();
+
+    let esi = EchoServer::<EchoServerImpl>::new(EchoServerImpl {
+        name: "echo".to_string(),
+    });
+
+    crate::protocol::triple::TRIPLE_SERVICES
+        .write()
+        .unwrap()
+        .insert("echo".to_string(), BoxCloneService::new(esi));
+
+    println!("triple server running, url: 0.0.0.0:8888");
+    let pro = TripleProtocol::new();
+    pro.export(Url {
+        url: "0.0.0.0:8888".to_string(),
+        service_key: "echo".to_string(),
+    })
+    .await;
+}
+
+#[allow(dead_code)]
+#[derive(Default, Clone)]
+struct EchoServerImpl {
+    name: String,
+}
+
+// #[async_trait]
+#[async_trait]
+impl Echo for EchoServerImpl {
+    async fn hello(
+        &self,
+        req: Request<HelloRequest>,
+    ) -> Result<Response<HelloReply>, tonic::Status> {
+        println!("EchoServer::hello {:?}", req.message);
+
+        Ok(Response::new(HelloReply {
+            reply: "hello, dubbo-rust".to_string(),
+        }))
+    }
+
+    type BidirectionalStreamingEchoStream = ResponseStream;
+
+    async fn bidirectional_streaming_echo(
+        &self,
+        request: Request<triple::server::Streaming<HelloRequest>>,
+    ) -> Result<Response<Self::BidirectionalStreamingEchoStream>, tonic::Status> {
+        println!("EchoServer::bidirectional_streaming_echo");
+
+        let mut in_stream = request.into_inner();
+        let (tx, rx) = mpsc::channel(128);
+
+        // this spawn here is required if you want to handle connection error.
+        // If we just map `in_stream` and write it back as `out_stream` the `out_stream`
+        // will be drooped when connection error occurs and error will never be propagated
+        // to mapped version of `in_stream`.
+        tokio::spawn(async move {
+            while let Some(result) = in_stream.next().await {
+                match result {
+                    Ok(v) => {
+                        // if v.name.starts_with("msg2") {
+                        //     tx.send(Err(tonic::Status::internal(format!("err: args is invalid, {:?}", v.name))
+                        //     )).await.expect("working rx");
+                        //     continue;
+                        // }
+                        tx.send(Ok(HelloReply {
+                            reply: format!("server reply: {:?}", v.name),
+                        }))
+                        .await
+                        .expect("working rx")
+                    }
+                    Err(err) => {
+                        if let Some(io_err) = match_for_io_error(&err) {
+                            if io_err.kind() == ErrorKind::BrokenPipe {
+                                // here you can handle special case when client
+                                // disconnected in unexpected way
+                                eprintln!("\tclient disconnected: broken pipe");
+                                break;
+                            }
+                        }
+
+                        match tx.send(Err(err)).await {
+                            Ok(_) => (),
+                            Err(_err) => break, // response was droped
+                        }
+                    }
+                }
+            }
+            println!("\tstream ended");
+        });
+
+        // echo just write the same data that was received
+        let out_stream = ReceiverStream::new(rx);
+
+        Ok(Response::new(
+            Box::pin(out_stream) as Self::BidirectionalStreamingEchoStream
+        ))
+    }
+}
+
+fn match_for_io_error(err_status: &tonic::Status) -> Option<&std::io::Error> {
+    let mut err: &(dyn std::error::Error + 'static) = err_status;
+
+    loop {
+        if let Some(io_err) = err.downcast_ref::<std::io::Error>() {
+            return Some(io_err);
+        }
+
+        err = match err.source() {
+            Some(err) => err,
+            None => return None,
+        };
+    }
+}
diff --git a/dubbo/src/init.rs b/dubbo/src/init.rs
new file mode 100644
index 0000000..e0d738c
--- /dev/null
+++ b/dubbo/src/init.rs
@@ -0,0 +1,110 @@
+// /// Server 启动的入口。业务侧需要调用该函数进行初始化
+// ///
+// use std::collections::HashMap;
+
+// use crate::common::url::Url;
+// use config::{BusinessConfig, RootConfig};
+
+// pub fn init() {
+//     let _root_config = RootConfig::new().load();
+//     let service_config = ServiceConfig::default()
+//         .group("helloworld".to_string())
+//         .serializer("json".to_string())
+//         .version("1.0".to_string())
+//         .name("echo".to_string());
+
+//     let triple_config = ProtocolConfig::default()
+//         .name("triple".to_string())
+//         .ip("0.0.0.0".to_string())
+//         .port("8888".to_string());
+
+//     let _service_config = service_config.add_protocol_configs(triple_config);
+//     // 根据不同的协议,加载不同的配置
+//     // 初始化全局的services
+//     // let server = DubboServer::init();
+//     // let server = server.add_service("echo".to_string(), service);
+// }
+
+// #[derive(Default)]
+// pub struct ServiceConfig {
+//     version: String,
+//     group: String,
+//     name: String,
+//     protocol_names: Vec<String>,
+//     registry_names: Vec<String>,
+//     serializer: String,
+//     protocol_configs: HashMap<String, ProtocolConfig>,
+// }
+
+// impl ServiceConfig {
+//     pub fn name(self, name: String) -> Self {
+//         Self { name, ..self }
+//     }
+
+//     pub fn version(self, version: String) -> Self {
+//         Self { version, ..self }
+//     }
+
+//     pub fn group(self, group: String) -> Self {
+//         Self { group, ..self }
+//     }
+
+//     pub fn protocol_names(self, protocol_names: Vec<String>) -> Self {
+//         Self {
+//             protocol_names,
+//             ..self
+//         }
+//     }
+
+//     pub fn serializer(self, serializer: String) -> Self {
+//         Self { serializer, ..self }
+//     }
+
+//     pub fn add_protocol_configs(mut self, protocol_config: ProtocolConfig) -> Self {
+//         self.protocol_configs
+//             .insert(protocol_config.name.clone(), protocol_config);
+//         Self { ..self }
+//     }
+
+//     pub fn get_url(&self) -> Vec<Url> {
+//         let mut urls = Vec::new();
+//         for (_, conf) in self.protocol_configs.iter() {
+//             urls.push(Url {
+//                 url: conf.to_owned().to_url(),
+//                 service_key: "".to_string(),
+//             });
+//         }
+
+//         urls
+//     }
+// }
+
+// #[derive(Default, Debug, Clone)]
+// pub struct ProtocolConfig {
+//     ip: String,
+//     port: String,
+//     name: String,
+//     params: HashMap<String, String>,
+// }
+
+// impl ProtocolConfig {
+//     pub fn name(self, name: String) -> Self {
+//         Self { name, ..self }
+//     }
+
+//     pub fn ip(self, ip: String) -> Self {
+//         Self { ip, ..self }
+//     }
+
+//     pub fn port(self, port: String) -> Self {
+//         Self { port, ..self }
+//     }
+
+//     pub fn params(self, params: HashMap<String, String>) -> Self {
+//         Self { params, ..self }
+//     }
+
+//     pub fn to_url(self) -> String {
+//         format!("{}://{}:{}", self.name, self.ip, self.port).to_string()
+//     }
+// }
diff --git a/dubbo/src/lib.rs b/dubbo/src/lib.rs
index e292e47..90ceb1c 100644
--- a/dubbo/src/lib.rs
+++ b/dubbo/src/lib.rs
@@ -16,6 +16,11 @@
  */
 
 pub mod common;
+pub mod echo;
 pub mod helloworld;
+pub mod init;
 pub mod protocol;
+pub mod registry;
 pub mod utils;
+
+pub(crate) type Error = Box<dyn std::error::Error + Send + Sync>;
diff --git a/dubbo/src/main.rs b/dubbo/src/main.rs
index 906e5cb..db99336 100644
--- a/dubbo/src/main.rs
+++ b/dubbo/src/main.rs
@@ -16,11 +16,18 @@
  */
 
 pub mod common;
+pub mod echo;
 pub mod helloworld;
+pub mod init;
 pub mod protocol;
+pub mod registry;
 pub mod utils;
 
+pub(crate) type Error = Box<dyn std::error::Error + Send + Sync>;
+
 #[tokio::main]
 async fn main() {
     println!("hello, dubbo-rust~")
 }
+
+// Refer service: tri://localhost:20000/helloworld.Greeter?app.version=3.0.0&application=dubbo.io&async=false&bean.name=GreeterClientImpl&cluster=failover&config.tracing=&environment=dev&generic=&group=&interface=helloworld.Greeter&loadbalance=&metadata-type=local&module=sample&name=dubbo.io&organization=dubbo-go&owner=dubbo-go&provided-by=&reference.filter=cshutdown&registry.role=0&release=dubbo-golang-3.0.0&retries=&serialization=&side=consumer&sticky=false&timestamp=1657865138&version=
diff --git a/dubbo/src/protocol/grpc/grpc_protocol.rs b/dubbo/src/protocol/grpc/grpc_protocol.rs
index b33468c..bf63a78 100644
--- a/dubbo/src/protocol/grpc/grpc_protocol.rs
+++ b/dubbo/src/protocol/grpc/grpc_protocol.rs
@@ -53,7 +53,7 @@ impl Protocol for GrpcProtocol {
         todo!()
     }
 
-    async fn refer(&self, url: Url) -> Self::Invoker {
+    async fn refer(self, url: Url) -> Self::Invoker {
         GrpcInvoker::new(url)
     }
 
diff --git a/dubbo/src/protocol/invocation.rs b/dubbo/src/protocol/invocation.rs
index a0686b2..50ca421 100644
--- a/dubbo/src/protocol/invocation.rs
+++ b/dubbo/src/protocol/invocation.rs
@@ -15,6 +15,7 @@
  * limitations under the License.
  */
 
+use futures_core::Stream;
 use tonic::metadata::MetadataMap;
 
 pub struct Request<T> {
@@ -30,9 +31,21 @@ impl<T> Request<T> {
         }
     }
 
+    pub fn into_inner(self) -> T {
+        self.message
+    }
+
     pub fn into_parts(self) -> (MetadataMap, T) {
         (self.metadata, self.message)
     }
+
+    pub fn from_http(req: http::Request<T>) -> Self {
+        let (parts, body) = req.into_parts();
+        Request {
+            metadata: MetadataMap::from_headers(parts.headers),
+            message: body,
+        }
+    }
 }
 
 pub struct Response<T> {
@@ -55,4 +68,35 @@ impl<T> Response<T> {
     pub fn into_parts(self) -> (MetadataMap, T) {
         (self.metadata, self.message)
     }
+
+    pub fn map<F, U>(self, f: F) -> Response<U>
+    where
+        F: FnOnce(T) -> U,
+    {
+        let u = f(self.message);
+        Response {
+            message: u,
+            metadata: self.metadata,
+        }
+    }
+}
+
+pub trait IntoStreamingRequest {
+    type Stream: Stream<Item = Self::Message> + Send + 'static;
+    type Message;
+
+    fn into_streaming_request(self) -> Request<Self::Stream>;
+}
+
+impl<T> IntoStreamingRequest for T
+where
+    T: Stream + Send + 'static,
+{
+    type Stream = T;
+
+    type Message = T::Item;
+
+    fn into_streaming_request(self) -> Request<Self::Stream> {
+        Request::new(self)
+    }
 }
diff --git a/dubbo/src/protocol/mod.rs b/dubbo/src/protocol/mod.rs
index 4199142..807c251 100644
--- a/dubbo/src/protocol/mod.rs
+++ b/dubbo/src/protocol/mod.rs
@@ -18,9 +18,12 @@
 pub mod grpc;
 pub mod invocation;
 pub mod server_desc;
+pub mod triple;
 
 use async_trait::async_trait;
 
+use crate::utils::boxed_clone::BoxCloneService;
+
 use crate::common::url::Url;
 
 #[async_trait]
@@ -30,7 +33,7 @@ pub trait Protocol {
 
     fn destroy(&self);
     async fn export(self, url: Url) -> Self::Exporter;
-    async fn refer(&self, url: Url) -> Self::Invoker;
+    async fn refer(self, url: Url) -> Self::Invoker;
 }
 
 pub trait Exporter {
@@ -53,3 +56,9 @@ pub trait DubboGrpcService<T> {
     fn set_proxy_impl(&mut self, invoker: T);
     fn service_desc(&self) -> server_desc::ServiceDesc;
 }
+
+pub type GrpcBoxCloneService = BoxCloneService<
+    http::Request<hyper::Body>,
+    http::Response<hyper::Body>,
+    std::convert::Infallible,
+>;
diff --git a/dubbo/src/protocol/triple/mod.rs b/dubbo/src/protocol/triple/mod.rs
new file mode 100644
index 0000000..32728c3
--- /dev/null
+++ b/dubbo/src/protocol/triple/mod.rs
@@ -0,0 +1,21 @@
+pub mod triple_exporter;
+pub mod triple_invoker;
+pub mod triple_protocol;
+pub mod triple_server;
+
+use lazy_static::lazy_static;
+use std::collections::HashMap;
+use std::sync::RwLock;
+
+use crate::utils::boxed_clone::BoxCloneService;
+use triple::BoxBody;
+
+pub type GrpcBoxCloneService =
+    BoxCloneService<http::Request<hyper::Body>, http::Response<BoxBody>, std::convert::Infallible>;
+
+lazy_static! {
+    // pub static ref DUBBO_GRPC_SERVICES: RwLock<HashMap<String, Box<dyn DubboGrpcService<GrpcInvoker> + Send + Sync + 'static>>> =
+    //     RwLock::new(HashMap::new());
+    pub static ref TRIPLE_SERVICES: RwLock<HashMap<String, GrpcBoxCloneService>> =
+        RwLock::new(HashMap::new());
+}
diff --git a/dubbo/src/protocol/triple/triple_exporter.rs b/dubbo/src/protocol/triple/triple_exporter.rs
new file mode 100644
index 0000000..5f66863
--- /dev/null
+++ b/dubbo/src/protocol/triple/triple_exporter.rs
@@ -0,0 +1,23 @@
+use super::triple_invoker::TripleInvoker;
+use crate::protocol::Exporter;
+
+#[derive(Clone)]
+pub struct TripleExporter {}
+
+impl TripleExporter {
+    pub fn new() -> Self {
+        TripleExporter {}
+    }
+}
+
+impl Exporter for TripleExporter {
+    type InvokerType = TripleInvoker;
+
+    fn unexport(&self) {
+        todo!()
+    }
+
+    fn get_invoker(&self) -> Self::InvokerType {
+        todo!()
+    }
+}
diff --git a/dubbo/src/protocol/triple/triple_invoker.rs b/dubbo/src/protocol/triple/triple_invoker.rs
new file mode 100644
index 0000000..9f064ab
--- /dev/null
+++ b/dubbo/src/protocol/triple/triple_invoker.rs
@@ -0,0 +1,38 @@
+use crate::common::url::Url;
+use crate::protocol::Invoker;
+
+#[allow(dead_code)]
+#[derive(Clone, Default)]
+pub struct TripleInvoker {
+    url: Url,
+}
+
+impl TripleInvoker {
+    pub fn new(url: Url) -> TripleInvoker {
+        Self { url }
+    }
+}
+
+impl Invoker for TripleInvoker {
+    fn invoke<M1>(
+        &self,
+        _req: crate::protocol::invocation::Request<M1>,
+    ) -> crate::protocol::invocation::Response<String>
+    where
+        M1: Send + 'static,
+    {
+        todo!()
+    }
+
+    fn is_available(&self) -> bool {
+        todo!()
+    }
+
+    fn destroy(&self) {
+        todo!()
+    }
+
+    fn get_url(&self) -> Url {
+        todo!()
+    }
+}
diff --git a/dubbo/src/protocol/triple/triple_protocol.rs b/dubbo/src/protocol/triple/triple_protocol.rs
new file mode 100644
index 0000000..876f06c
--- /dev/null
+++ b/dubbo/src/protocol/triple/triple_protocol.rs
@@ -0,0 +1,48 @@
+use std::collections::HashMap;
+
+use async_trait::async_trait;
+
+use super::triple_exporter::TripleExporter;
+use super::triple_invoker::TripleInvoker;
+use super::triple_server::TripleServer;
+use crate::common::url::Url;
+use crate::protocol::Protocol;
+
+pub struct TripleProtocol {
+    servers: HashMap<String, TripleServer>,
+}
+
+impl TripleProtocol {
+    pub fn new() -> Self {
+        TripleProtocol {
+            servers: HashMap::new(),
+        }
+    }
+
+    pub fn get_server(&self, name: String) -> Option<TripleServer> {
+        self.servers.get(&name).map(|data| data.to_owned())
+    }
+}
+
+#[async_trait]
+impl Protocol for TripleProtocol {
+    type Invoker = TripleInvoker;
+
+    type Exporter = TripleExporter;
+
+    fn destroy(&self) {
+        todo!()
+    }
+
+    async fn export(self, url: Url) -> Self::Exporter {
+        let server = TripleServer::new(url.service_key.clone());
+        server.serve(url.url.clone()).await;
+
+        TripleExporter::new()
+    }
+
+    async fn refer(self, url: Url) -> Self::Invoker {
+        TripleInvoker::new(url)
+        // Self::Invoker
+    }
+}
diff --git a/dubbo/src/protocol/triple/triple_server.rs b/dubbo/src/protocol/triple/triple_server.rs
new file mode 100644
index 0000000..b596bb9
--- /dev/null
+++ b/dubbo/src/protocol/triple/triple_server.rs
@@ -0,0 +1,44 @@
+use std::{net::ToSocketAddrs, str::FromStr};
+
+use triple::transport::DubboServer;
+
+#[derive(Default, Clone)]
+pub struct TripleServer {
+    s: DubboServer,
+    name: String,
+}
+
+impl TripleServer {
+    pub fn new(name: String) -> TripleServer {
+        Self {
+            name,
+            ..Default::default()
+        }
+    }
+
+    pub async fn serve(mut self, url: String) {
+        {
+            let lock = super::TRIPLE_SERVICES.read().unwrap();
+            let svc = lock.get(&self.name).unwrap();
+
+            self.s = self.s.add_service(self.name.clone(), svc.clone());
+        }
+
+        let uri = http::Uri::from_str(&url.clone()).unwrap();
+        let server = self.s.clone();
+
+        server
+            .serve(
+                self.name,
+                uri.authority()
+                    .unwrap()
+                    .to_string()
+                    .to_socket_addrs()
+                    .unwrap()
+                    .next()
+                    .unwrap(),
+            )
+            .await
+            .unwrap();
+    }
+}
diff --git a/dubbo/Cargo.toml b/triple/Cargo.toml
similarity index 66%
copy from dubbo/Cargo.toml
copy to triple/Cargo.toml
index 7ce6865..df17abd 100644
--- a/dubbo/Cargo.toml
+++ b/triple/Cargo.toml
@@ -1,23 +1,20 @@
 [package]
-name = "dubbo"
+name = "triple"
 version = "0.1.0"
 edition = "2021"
 
 # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
 
-[[bin]]
-name = "helloworld-client"
-path = "src/helloworld/client.rs"
-
 [dependencies]
 h2 = {version = "0.3", optional = true}
-hyper = "0.14.19"
+hyper = {version="0.14.19", features = ["full"]}
 http = "0.2"
 tonic = {version ="0.7.2", features = ["compression",]}
 tower-service = "0.3.1"
 http-body = "0.4.4"
 tower = "0.4.12"
 futures-util = {version = "0.3", default-features = false}
+futures-core = {version = "0.3", default-features = false}
 tokio = { version = "1.0", features = [ "rt-multi-thread", "time", "fs", "macros", "net", "signal"] }
 prost-derive = {version = "0.10", optional = true}
 prost = "0.10.4"
@@ -25,4 +22,13 @@ prost-types = { version = "0.6", default-features = false }
 lazy_static = "1.3.0"
 async-trait = "0.1.56"
 tower-layer = "0.3"
+pin-project = "1.0"
+axum = "0.5.9"
+bytes = "1.0"
+serde_json = "1.0.82"
+serde = {version="1.0.138", features = ["derive"]}
+async-stream = "0.3"
+tokio-stream = "0.1"
 
+# for test in codegen
+config = {path = "../config"}
\ No newline at end of file
diff --git a/triple/src/client/grpc.rs b/triple/src/client/grpc.rs
new file mode 100644
index 0000000..5126ed1
--- /dev/null
+++ b/triple/src/client/grpc.rs
@@ -0,0 +1,155 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.
+ */
+
+use futures_util::{StreamExt, TryStreamExt};
+use http::HeaderValue;
+
+use crate::codec::Codec;
+use crate::invocation::{IntoStreamingRequest, Response};
+use crate::server::encode::encode;
+use crate::server::Streaming;
+
+#[derive(Debug, Clone, Default)]
+pub struct TripleClient {
+    host: Option<http::uri::Authority>,
+    inner: ConnectionPool,
+}
+
+#[derive(Debug, Default, Clone)]
+pub struct ConnectionPool {
+    http2_only: bool,
+}
+
+impl ConnectionPool {
+    pub fn new() -> Self {
+        ConnectionPool { http2_only: true }
+    }
+
+    pub fn builder(self) -> hyper::Client<hyper::client::HttpConnector> {
+        hyper::Client::builder()
+            .http2_only(self.http2_only)
+            .build_http()
+    }
+}
+
+// TODO: initial connection pool
+impl TripleClient {
+    pub fn new() -> Self {
+        TripleClient {
+            host: None,
+            inner: ConnectionPool::new(),
+        }
+    }
+
+    pub fn with_authority(self, host: http::uri::Authority) -> Self {
+        TripleClient {
+            host: Some(host),
+            ..self
+        }
+    }
+}
+
+impl TripleClient {
+    pub async fn bidi_streaming<C, M1, M2>(
+        &mut self,
+        req: impl IntoStreamingRequest<Message = M1>,
+        mut codec: C,
+        path: http::uri::PathAndQuery,
+    ) -> Result<Response<Streaming<M2>>, tonic::Status>
+    where
+        C: Codec<Encode = M1, Decode = M2>,
+        M1: Send + Sync + 'static,
+        M2: Send + Sync + 'static,
+    {
+        let req = req.into_streaming_request();
+        let en = encode(codec.encoder(), req.into_inner().map(Ok)).into_stream();
+        let body = hyper::Body::wrap_stream(en);
+
+        let mut parts = http::uri::Parts::default();
+        parts.path_and_query = Some(path);
+        parts.authority = self.host.clone();
+        parts.scheme = Some(http::uri::Scheme::HTTP);
+
+        let uri = http::Uri::from_parts(parts).unwrap();
+
+        let mut req = hyper::Request::builder()
+            .version(http::Version::HTTP_2)
+            .uri(uri.clone())
+            .method("POST")
+            .body(body)
+            .unwrap();
+        *req.version_mut() = http::Version::HTTP_2;
+        req.headers_mut()
+            .insert("method", HeaderValue::from_static("POST"));
+        req.headers_mut().insert(
+            "scheme",
+            HeaderValue::from_str(uri.clone().scheme_str().unwrap()).unwrap(),
+        );
+        req.headers_mut()
+            .insert("path", HeaderValue::from_str(uri.clone().path()).unwrap());
+        req.headers_mut().insert(
+            "authority",
+            HeaderValue::from_str(uri.authority().unwrap().as_str()).unwrap(),
+        );
+        req.headers_mut().insert(
+            "content-type",
+            HeaderValue::from_static("application/grpc+json"),
+        );
+        req.headers_mut()
+            .insert("user-agent", HeaderValue::from_static("dubbo-rust/1.0.0"));
+        req.headers_mut()
+            .insert("te", HeaderValue::from_static("trailers"));
+        req.headers_mut().insert(
+            "tri-service-version",
+            HeaderValue::from_static("dubbo-rust/1.0.0"),
+        );
+        req.headers_mut()
+            .insert("tri-service-group", HeaderValue::from_static("cluster"));
+        req.headers_mut().insert(
+            "tri-unit-info",
+            HeaderValue::from_static("dubbo-rust/1.0.0"),
+        );
+
+        // const (
+        //     TripleContentType    = "application/grpc+proto"
+        //     TripleUserAgent      = "grpc-go/1.35.0-dev"
+        //     TripleServiceVersion = "tri-service-version"
+        //     TripleAttachement    = "tri-attachment"
+        //     TripleServiceGroup   = "tri-service-group"
+        //     TripleRequestID      = "tri-req-id"
+        //     TripleTraceID        = "tri-trace-traceid"
+        //     TripleTraceRPCID     = "tri-trace-rpcid"
+        //     TripleTraceProtoBin  = "tri-trace-proto-bin"
+        //     TripleUnitInfo       = "tri-unit-info"
+        // )
+
+        let cli = self.inner.clone().builder();
+        let response = cli.request(req).await;
+
+        match response {
+            Ok(v) => {
+                let resp = v.map(|body| Streaming::new(body, codec.decoder()));
+
+                let (_parts, body) = resp.into_parts();
+                return Ok(Response::new(body));
+            }
+            Err(err) => {
+                return Err(tonic::Status::new(tonic::Code::Internal, err.to_string()));
+            }
+        }
+    }
+}
diff --git a/dubbo/src/lib.rs b/triple/src/client/mod.rs
similarity index 92%
copy from dubbo/src/lib.rs
copy to triple/src/client/mod.rs
index e292e47..5b2603e 100644
--- a/dubbo/src/lib.rs
+++ b/triple/src/client/mod.rs
@@ -15,7 +15,6 @@
  * limitations under the License.
  */
 
-pub mod common;
-pub mod helloworld;
-pub mod protocol;
-pub mod utils;
+pub mod grpc;
+
+pub use grpc::TripleClient;
diff --git a/triple/src/codec/buffer.rs b/triple/src/codec/buffer.rs
new file mode 100644
index 0000000..850f988
--- /dev/null
+++ b/triple/src/codec/buffer.rs
@@ -0,0 +1,138 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.
+ */
+
+use bytes::buf::UninitSlice;
+use bytes::{Buf, BufMut, BytesMut};
+
+/// A specialized buffer to decode gRPC messages from.
+#[derive(Debug)]
+pub struct DecodeBuf<'a> {
+    buf: &'a mut BytesMut,
+    len: usize,
+}
+
+/// A specialized buffer to encode gRPC messages into.
+#[derive(Debug)]
+pub struct EncodeBuf<'a> {
+    buf: &'a mut BytesMut,
+}
+
+impl<'a> DecodeBuf<'a> {
+    pub fn new(buf: &'a mut BytesMut, len: usize) -> Self {
+        DecodeBuf { buf, len }
+    }
+}
+
+impl Buf for DecodeBuf<'_> {
+    #[inline]
+    fn remaining(&self) -> usize {
+        self.len
+    }
+
+    #[inline]
+    fn chunk(&self) -> &[u8] {
+        let ret = self.buf.chunk();
+
+        if ret.len() > self.len {
+            &ret[..self.len]
+        } else {
+            ret
+        }
+    }
+
+    #[inline]
+    fn advance(&mut self, cnt: usize) {
+        assert!(cnt <= self.len);
+        self.buf.advance(cnt);
+        self.len -= cnt;
+    }
+}
+
+impl<'a> EncodeBuf<'a> {
+    pub fn new(buf: &'a mut BytesMut) -> Self {
+        EncodeBuf { buf }
+    }
+}
+
+impl EncodeBuf<'_> {
+    /// Reserves capacity for at least `additional` more bytes to be inserted
+    /// into the buffer.
+    ///
+    /// More than `additional` bytes may be reserved in order to avoid frequent
+    /// reallocations. A call to `reserve` may result in an allocation.
+    #[inline]
+    pub fn reserve(&mut self, additional: usize) {
+        self.buf.reserve(additional);
+    }
+}
+
+unsafe impl BufMut for EncodeBuf<'_> {
+    #[inline]
+    fn remaining_mut(&self) -> usize {
+        self.buf.remaining_mut()
+    }
+
+    #[inline]
+    unsafe fn advance_mut(&mut self, cnt: usize) {
+        self.buf.advance_mut(cnt)
+    }
+
+    #[inline]
+    fn chunk_mut(&mut self) -> &mut UninitSlice {
+        self.buf.chunk_mut()
+    }
+}
+
+#[cfg(test)]
+mod tests {
+    use super::*;
+
+    #[test]
+    fn decode_buf() {
+        let mut payload = BytesMut::with_capacity(100);
+        payload.put(&vec![0u8; 50][..]);
+        let mut buf = DecodeBuf::new(&mut payload, 20);
+
+        assert_eq!(buf.len, 20);
+        assert_eq!(buf.remaining(), 20);
+        assert_eq!(buf.chunk().len(), 20);
+
+        buf.advance(10);
+        assert_eq!(buf.remaining(), 10);
+
+        let mut out = [0; 5];
+        buf.copy_to_slice(&mut out);
+        assert_eq!(buf.remaining(), 5);
+        assert_eq!(buf.chunk().len(), 5);
+
+        assert_eq!(buf.copy_to_bytes(5).len(), 5);
+        assert!(!buf.has_remaining());
+    }
+
+    #[test]
+    fn encode_buf() {
+        let mut bytes = BytesMut::with_capacity(100);
+        let mut buf = EncodeBuf::new(&mut bytes);
+
+        let initial = buf.remaining_mut();
+        unsafe { buf.advance_mut(20) };
+        assert_eq!(buf.remaining_mut(), initial - 20);
+
+        buf.put_u8(b'a');
+        assert_eq!(buf.remaining_mut(), initial - 20 - 1);
+    }
+}
diff --git a/triple/src/codec/mod.rs b/triple/src/codec/mod.rs
new file mode 100644
index 0000000..f6e61d9
--- /dev/null
+++ b/triple/src/codec/mod.rs
@@ -0,0 +1,71 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.
+ */
+
+pub mod buffer;
+pub mod serde_codec;
+
+use std::io;
+
+pub use self::buffer::{DecodeBuf, EncodeBuf};
+use tonic::Status;
+
+pub trait Codec {
+    /// The encodable message.
+    type Encode: Send + 'static;
+    /// The decodable message.
+    type Decode: Send + 'static;
+
+    /// The encoder that can encode a message.
+    type Encoder: Encoder<Item = Self::Encode, Error = Status> + Send + 'static;
+    /// The encoder that can decode a message.
+    type Decoder: Decoder<Item = Self::Decode, Error = Status> + Send + 'static;
+
+    /// Fetch the encoder.
+    fn encoder(&mut self) -> Self::Encoder;
+    /// Fetch the decoder.
+    fn decoder(&mut self) -> Self::Decoder;
+}
+
+/// Encodes gRPC message types
+pub trait Encoder {
+    /// The type that is encoded.
+    type Item;
+
+    /// The type of encoding errors.
+    ///
+    /// The type of unrecoverable frame encoding errors.
+    type Error: From<io::Error>;
+
+    /// Encodes a message into the provided buffer.
+    fn encode(&mut self, item: Self::Item, dst: &mut EncodeBuf<'_>) -> Result<(), Self::Error>;
+}
+
+/// Decodes gRPC message types
+pub trait Decoder {
+    /// The type that is decoded.
+    type Item;
+
+    /// The type of unrecoverable frame decoding errors.
+    type Error: From<io::Error>;
+
+    /// Decode a message from the buffer.
+    ///
+    /// The buffer will contain exactly the bytes of a full message. There
+    /// is no need to get the length from the bytes, gRPC framing is handled
+    /// for you.
+    fn decode(&mut self, src: &mut DecodeBuf<'_>) -> Result<Option<Self::Item>, Self::Error>;
+}
diff --git a/triple/src/codec/serde_codec.rs b/triple/src/codec/serde_codec.rs
new file mode 100644
index 0000000..143eb56
--- /dev/null
+++ b/triple/src/codec/serde_codec.rs
@@ -0,0 +1,89 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.
+ */
+
+use std::marker::PhantomData;
+
+use bytes::{Buf, BufMut};
+use serde::{Deserialize, Serialize};
+
+use super::{Codec, DecodeBuf, Decoder, EncodeBuf, Encoder};
+
+#[derive(Debug)]
+pub struct SerdeCodec<T, U> {
+    _pd: PhantomData<(T, U)>,
+}
+
+impl<T, U> Default for SerdeCodec<T, U> {
+    fn default() -> Self {
+        Self { _pd: PhantomData }
+    }
+}
+
+impl<'a, T, U> Codec for SerdeCodec<T, U>
+where
+    T: Serialize + Send + 'static,
+    U: Deserialize<'a> + Send + 'static,
+{
+    type Encode = T;
+
+    type Decode = U;
+
+    type Encoder = SerdeEncoder<T>;
+
+    type Decoder = SerdeDecoder<U>;
+
+    fn encoder(&mut self) -> Self::Encoder {
+        SerdeEncoder(PhantomData)
+    }
+
+    fn decoder(&mut self) -> Self::Decoder {
+        SerdeDecoder(PhantomData)
+    }
+}
+
+#[derive(Debug, Clone)]
+pub struct SerdeEncoder<T>(PhantomData<T>);
+
+impl<T: Serialize> Encoder for SerdeEncoder<T> {
+    type Item = T;
+
+    type Error = tonic::Status;
+
+    fn encode(&mut self, item: Self::Item, dst: &mut EncodeBuf<'_>) -> Result<(), Self::Error> {
+        item.serialize(&mut serde_json::Serializer::new(dst.writer()))
+            .expect("failed to searialize");
+
+        Ok(())
+    }
+}
+
+pub struct SerdeDecoder<U>(PhantomData<U>);
+
+impl<'a, U: Deserialize<'a>> Decoder for SerdeDecoder<U> {
+    type Item = U;
+
+    type Error = tonic::Status;
+
+    fn decode(&mut self, src: &mut DecodeBuf<'_>) -> Result<Option<Self::Item>, Self::Error> {
+        let value = src.chunk().to_owned();
+        let mut msg = vec![0u8; value.len()];
+        src.copy_to_slice(&mut msg);
+
+        let mut de = serde_json::Deserializer::from_reader(msg.reader());
+        Ok(Some(U::deserialize(&mut de).unwrap()))
+    }
+}
diff --git a/triple/src/invocation.rs b/triple/src/invocation.rs
new file mode 100644
index 0000000..1655312
--- /dev/null
+++ b/triple/src/invocation.rs
@@ -0,0 +1,125 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.
+ */
+
+use futures_core::Stream;
+use tonic::metadata::MetadataMap;
+
+pub struct Request<T> {
+    pub message: T,
+    pub metadata: MetadataMap,
+}
+
+impl<T> Request<T> {
+    pub fn new(message: T) -> Request<T> {
+        Self {
+            message,
+            metadata: MetadataMap::new(),
+        }
+    }
+
+    pub fn into_inner(self) -> T {
+        self.message
+    }
+
+    pub fn into_parts(self) -> (MetadataMap, T) {
+        (self.metadata, self.message)
+    }
+
+    pub fn from_http(req: http::Request<T>) -> Self {
+        let (parts, body) = req.into_parts();
+        Request {
+            metadata: MetadataMap::from_headers(parts.headers),
+            message: body,
+        }
+    }
+
+    pub fn into_http(self) -> http::Request<T> {
+        let mut http_req = http::Request::new(self.message);
+        *http_req.version_mut() = http::Version::HTTP_2;
+        *http_req.headers_mut() = self.metadata.into_headers();
+
+        http_req
+    }
+}
+
+pub struct Response<T> {
+    message: T,
+    metadata: MetadataMap,
+}
+
+impl<T> Response<T> {
+    pub fn new(message: T) -> Response<T> {
+        Self {
+            message,
+            metadata: MetadataMap::new(),
+        }
+    }
+
+    pub fn from_parts(metadata: MetadataMap, message: T) -> Self {
+        Self { message, metadata }
+    }
+
+    pub fn into_parts(self) -> (MetadataMap, T) {
+        (self.metadata, self.message)
+    }
+
+    pub fn into_http(self) -> http::Response<T> {
+        let mut http_resp = http::Response::new(self.message);
+        *http_resp.version_mut() = http::Version::HTTP_2;
+        *http_resp.headers_mut() = self.metadata.into_headers();
+
+        http_resp
+    }
+
+    pub fn map<F, U>(self, f: F) -> Response<U>
+    where
+        F: FnOnce(T) -> U,
+    {
+        let u = f(self.message);
+        Response {
+            message: u,
+            metadata: self.metadata,
+        }
+    }
+}
+
+pub trait IntoStreamingRequest {
+    type Stream: Stream<Item = Self::Message> + Send + 'static;
+    type Message;
+
+    fn into_streaming_request(self) -> Request<Self::Stream>;
+}
+
+impl<T> IntoStreamingRequest for T
+where
+    T: Stream + Send + 'static,
+    // T::Item: Result<Self::Message, std::convert::Infallible>,
+{
+    type Stream = T;
+
+    type Message = T::Item;
+
+    fn into_streaming_request(self) -> Request<Self::Stream> {
+        Request::new(self)
+    }
+}
+
+// impl<T> sealed::Sealed for T {}
+
+// pub mod sealed {
+//     pub trait Sealed {}
+// }
diff --git a/dubbo/src/main.rs b/triple/src/lib.rs
similarity index 67%
copy from dubbo/src/main.rs
copy to triple/src/lib.rs
index 906e5cb..42a3c6d 100644
--- a/dubbo/src/main.rs
+++ b/triple/src/lib.rs
@@ -15,12 +15,20 @@
  * limitations under the License.
  */
 
-pub mod common;
-pub mod helloworld;
-pub mod protocol;
-pub mod utils;
+pub mod client;
+pub mod codec;
+pub mod invocation;
+pub mod server;
+pub mod transport;
 
-#[tokio::main]
-async fn main() {
-    println!("hello, dubbo-rust~")
+use http_body::Body;
+
+pub(crate) type Error = Box<dyn std::error::Error + Send + Sync>;
+
+pub type BoxBody = http_body::combinators::UnsyncBoxBody<bytes::Bytes, tonic::Status>;
+
+pub fn empty_body() -> BoxBody {
+    http_body::Empty::new()
+        .map_err(|err| match err {})
+        .boxed_unsync()
 }
diff --git a/dubbo/src/main.rs b/triple/src/main.rs
similarity index 65%
copy from dubbo/src/main.rs
copy to triple/src/main.rs
index 906e5cb..4350696 100644
--- a/dubbo/src/main.rs
+++ b/triple/src/main.rs
@@ -15,12 +15,22 @@
  * limitations under the License.
  */
 
-pub mod common;
-pub mod helloworld;
-pub mod protocol;
-pub mod utils;
+pub mod client;
+pub mod codec;
+pub mod invocation;
+pub mod server;
+pub mod transport;
 
-#[tokio::main]
-async fn main() {
-    println!("hello, dubbo-rust~")
+use http_body::Body;
+
+pub(crate) type Error = Box<dyn std::error::Error + Send + Sync>;
+pub type BoxBody = http_body::combinators::UnsyncBoxBody<bytes::Bytes, tonic::Status>;
+pub fn empty_body() -> BoxBody {
+    http_body::Empty::new()
+        .map_err(|err| match err {})
+        .boxed_unsync()
+}
+
+fn main() {
+    println!("hello, triple");
 }
diff --git a/dubbo/src/lib.rs b/triple/src/server/consts.rs
similarity index 80%
copy from dubbo/src/lib.rs
copy to triple/src/server/consts.rs
index e292e47..4898211 100644
--- a/dubbo/src/lib.rs
+++ b/triple/src/server/consts.rs
@@ -15,7 +15,10 @@
  * limitations under the License.
  */
 
-pub mod common;
-pub mod helloworld;
-pub mod protocol;
-pub mod utils;
+pub const BUFFER_SIZE: usize = 1024 * 8;
+// 5 bytes
+pub const HEADER_SIZE: usize =
+    // compression flag
+    std::mem::size_of::<u8>() +
+    // data length
+    std::mem::size_of::<u32>();
diff --git a/triple/src/server/decode.rs b/triple/src/server/decode.rs
new file mode 100644
index 0000000..06ce3ae
--- /dev/null
+++ b/triple/src/server/decode.rs
@@ -0,0 +1,166 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.
+ */
+
+use std::{pin::Pin, task::Poll};
+
+use bytes::{Buf, BufMut, Bytes, BytesMut};
+use futures_util::Stream;
+use futures_util::{future, ready};
+use http_body::Body;
+use tonic::metadata::MetadataMap;
+
+use crate::codec::{DecodeBuf, Decoder};
+
+type BoxBody = http_body::combinators::UnsyncBoxBody<Bytes, tonic::Status>;
+
+pub struct Streaming<T> {
+    state: State,
+    body: BoxBody,
+    decoder: Box<dyn Decoder<Item = T, Error = tonic::Status> + Send + 'static>,
+    buf: BytesMut,
+    trailers: Option<MetadataMap>,
+}
+
+#[derive(PartialEq)]
+enum State {
+    ReadHeader,
+    ReadBody { len: usize },
+    Error,
+}
+
+impl<T> Streaming<T> {
+    pub fn new<B, D>(body: B, decoder: D) -> Self
+    where
+        B: Body + Send + 'static,
+        B::Error: Into<crate::Error>,
+        D: Decoder<Item = T, Error = tonic::Status> + Send + 'static,
+    {
+        Self {
+            state: State::ReadHeader,
+            body: body
+                .map_data(|mut buf| buf.copy_to_bytes(buf.remaining()))
+                .map_err(|_err| tonic::Status::internal("err"))
+                .boxed_unsync(),
+            decoder: Box::new(decoder),
+            buf: BytesMut::with_capacity(super::consts::BUFFER_SIZE),
+            trailers: None,
+        }
+    }
+
+    pub async fn message(&mut self) -> Result<Option<T>, tonic::Status> {
+        match future::poll_fn(|cx| Pin::new(&mut *self).poll_next(cx)).await {
+            Some(Ok(res)) => Ok(Some(res)),
+            Some(Err(err)) => Err(err),
+            None => Ok(None),
+        }
+    }
+
+    pub async fn trailer(&mut self) -> Result<Option<MetadataMap>, tonic::Status> {
+        if let Some(t) = self.trailers.take() {
+            return Ok(Some(t));
+        }
+        // while self.message().await?.is_some() {}
+
+        let trailer = future::poll_fn(|cx| Pin::new(&mut self.body).poll_trailers(cx)).await;
+        let trailer = trailer.map(|data| data.map(MetadataMap::from_headers));
+        trailer
+    }
+
+    pub fn decode_chunk(&mut self) -> Result<Option<T>, tonic::Status> {
+        if self.state == State::ReadHeader {
+            // buffer is full
+            if self.buf.remaining() < super::consts::HEADER_SIZE {
+                return Ok(None);
+            }
+
+            let _is_compressed = self.buf.get_u8();
+            let len = self.buf.get_u32() as usize;
+            self.buf.reserve(len as usize);
+
+            self.state = State::ReadBody { len }
+        }
+
+        if let State::ReadBody { len } = self.state {
+            if self.buf.remaining() < len || self.buf.len() < len {
+                return Ok(None);
+            }
+
+            let decoding_result = self.decoder.decode(&mut DecodeBuf::new(&mut self.buf, len));
+
+            return match decoding_result {
+                Ok(Some(r)) => {
+                    self.state = State::ReadHeader;
+                    Ok(Some(r))
+                }
+                Ok(None) => Ok(None),
+                Err(err) => Err(err),
+            };
+        }
+
+        Ok(None)
+    }
+}
+
+impl<T> Stream for Streaming<T> {
+    type Item = Result<T, tonic::Status>;
+
+    fn poll_next(
+        mut self: std::pin::Pin<&mut Self>,
+        cx: &mut std::task::Context<'_>,
+    ) -> std::task::Poll<Option<Self::Item>> {
+        loop {
+            if self.state == State::Error {
+                return Poll::Ready(None);
+            }
+
+            if let Some(item) = self.decode_chunk()? {
+                return Poll::Ready(Some(Ok(item)));
+            }
+
+            let chunk = match ready!(Pin::new(&mut self.body).poll_data(cx)) {
+                Some(Ok(d)) => Some(d),
+                Some(Err(e)) => {
+                    let _ = std::mem::replace(&mut self.state, State::Error);
+                    let err: crate::Error = e.into();
+                    return Poll::Ready(Some(Err(tonic::Status::internal(err.to_string()))));
+                }
+                None => None,
+            };
+
+            if let Some(data) = chunk {
+                self.buf.put(data)
+            } else {
+                break;
+            }
+        }
+
+        match ready!(Pin::new(&mut self.body).poll_trailers(cx)) {
+            Ok(trailer) => {
+                self.trailers = trailer.map(MetadataMap::from_headers);
+            }
+            Err(err) => {
+                println!("poll_trailers, err: {}", err);
+            }
+        }
+
+        Poll::Ready(None)
+    }
+
+    fn size_hint(&self) -> (usize, Option<usize>) {
+        (0, None)
+    }
+}
diff --git a/triple/src/server/encode.rs b/triple/src/server/encode.rs
new file mode 100644
index 0000000..c76f448
--- /dev/null
+++ b/triple/src/server/encode.rs
@@ -0,0 +1,169 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.
+ */
+use std::{pin::Pin, task::Poll};
+
+use bytes::{BufMut, Bytes, BytesMut};
+use futures_core::{Stream, TryStream};
+use futures_util::{ready, StreamExt, TryStreamExt};
+use http_body::Body;
+use pin_project::pin_project;
+use tonic::Status;
+
+use crate::codec::{EncodeBuf, Encoder};
+
+#[allow(unused_must_use)]
+pub fn encode<E, B>(mut encoder: E, resp_body: B) -> impl TryStream<Ok = Bytes, Error = Status>
+where
+    E: Encoder<Error = Status>,
+    B: Stream<Item = Result<E::Item, Status>>,
+{
+    async_stream::stream! {
+        let mut buf = BytesMut::with_capacity(super::consts::BUFFER_SIZE);
+        futures_util::pin_mut!(resp_body);
+
+        loop {
+            match resp_body.next().await {
+                Some(Ok(item)) => {
+                    // 编码数据到缓冲中
+                    buf.reserve(super::consts::HEADER_SIZE);
+                    unsafe {
+                        buf.advance_mut(super::consts::HEADER_SIZE);
+                    }
+                    encoder.encode(item, &mut EncodeBuf::new(&mut buf)).map_err(|_e| tonic::Status::internal("encode error"));
+
+                    let len = buf.len() - super::consts::HEADER_SIZE;
+                    {
+                        let mut buf = &mut buf[..super::consts::HEADER_SIZE];
+                        buf.put_u8(1);
+                        buf.put_u32(len as u32);
+                    }
+
+                    yield Ok(buf.split_to(len + super::consts::HEADER_SIZE).freeze());
+                },
+                Some(Err(err)) => yield Err(err.into()),
+                None => break,
+            }
+        }
+    }
+}
+
+pub fn encode_server<E, B>(
+    encoder: E,
+    body: B,
+) -> EncodeBody<impl Stream<Item = Result<Bytes, Status>>>
+where
+    E: Encoder<Error = Status>,
+    B: Stream<Item = Result<E::Item, Status>>,
+{
+    let s = encode(encoder, body).into_stream();
+    EncodeBody::new_server(s)
+}
+
+pub fn encode_client<E, B>(
+    encoder: E,
+    body: B,
+) -> EncodeBody<impl Stream<Item = Result<Bytes, Status>>>
+where
+    E: Encoder<Error = Status>,
+    B: Stream<Item = E::Item>,
+{
+    let s = encode(encoder, body.map(Ok)).into_stream();
+    EncodeBody::new_client(s)
+}
+
+#[derive(Debug)]
+enum Role {
+    Server,
+    Client,
+}
+#[pin_project]
+pub struct EncodeBody<S> {
+    #[pin]
+    inner: S,
+    role: Role,
+    is_end_stream: bool,
+    error: Option<tonic::Status>,
+}
+
+impl<S> EncodeBody<S> {
+    pub fn new_server(inner: S) -> Self {
+        Self {
+            inner,
+            role: Role::Server,
+            is_end_stream: false,
+            error: None,
+        }
+    }
+
+    pub fn new_client(inner: S) -> Self {
+        Self {
+            inner,
+            role: Role::Client,
+            is_end_stream: false,
+            error: None,
+        }
+    }
+}
+
+impl<S> Body for EncodeBody<S>
+where
+    S: Stream<Item = Result<Bytes, tonic::Status>>,
+{
+    type Data = Bytes;
+
+    type Error = tonic::Status;
+
+    fn is_end_stream(&self) -> bool {
+        self.is_end_stream
+    }
+
+    fn poll_data(
+        self: Pin<&mut Self>,
+        cx: &mut std::task::Context<'_>,
+    ) -> Poll<Option<Result<Self::Data, Self::Error>>> {
+        let mut self_proj = self.project();
+        match ready!(self_proj.inner.try_poll_next_unpin(cx)) {
+            Some(Ok(d)) => Some(Ok(d)).into(),
+            Some(Err(status)) => {
+                *self_proj.error = Some(status);
+                None.into()
+            }
+            None => None.into(),
+        }
+    }
+
+    fn poll_trailers(
+        self: Pin<&mut Self>,
+        _cx: &mut std::task::Context<'_>,
+    ) -> Poll<Result<Option<http::HeaderMap>, Self::Error>> {
+        let self_proj = self.project();
+        if *self_proj.is_end_stream {
+            return Poll::Ready(Ok(None));
+        }
+
+        let status = if let Some(status) = self_proj.error.take() {
+            *self_proj.is_end_stream = true;
+            status
+        } else {
+            tonic::Status::ok("")
+        };
+        let http = status.to_http();
+        println!("status: {:?}", http.headers().clone());
+
+        Poll::Ready(Ok(Some(http.headers().to_owned())))
+    }
+}
diff --git a/dubbo/src/main.rs b/triple/src/server/mod.rs
similarity index 84%
copy from dubbo/src/main.rs
copy to triple/src/server/mod.rs
index 906e5cb..8be7239 100644
--- a/dubbo/src/main.rs
+++ b/triple/src/server/mod.rs
@@ -15,12 +15,11 @@
  * limitations under the License.
  */
 
-pub mod common;
-pub mod helloworld;
-pub mod protocol;
-pub mod utils;
+pub mod consts;
+pub mod decode;
+pub mod encode;
+pub mod server;
+pub mod service;
 
-#[tokio::main]
-async fn main() {
-    println!("hello, dubbo-rust~")
-}
+pub use decode::Streaming;
+pub use encode::{encode, encode_server};
diff --git a/triple/src/server/server.rs b/triple/src/server/server.rs
new file mode 100644
index 0000000..6474d6c
--- /dev/null
+++ b/triple/src/server/server.rs
@@ -0,0 +1,138 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.
+ */
+
+use bytes::{Buf, BytesMut};
+use http_body::Body;
+use std::fmt::Debug;
+
+use crate::codec::{Codec, DecodeBuf, Decoder, EncodeBuf, Encoder};
+use crate::invocation::Request;
+use crate::server::encode::encode_server;
+use crate::server::service::{StreamingSvc, UnaryService};
+use crate::server::Streaming;
+use crate::BoxBody;
+use config::BusinessConfig;
+
+pub struct TripleServer<T> {
+    codec: T,
+}
+
+impl<T> TripleServer<T> {
+    pub fn new(codec: T) -> Self {
+        Self { codec }
+    }
+}
+
+impl<T> TripleServer<T>
+where
+    T: Codec,
+{
+    pub async fn bidi_streaming<S, B>(
+        &mut self,
+        mut service: S,
+        req: http::Request<B>,
+    ) -> http::Response<BoxBody>
+    where
+        S: StreamingSvc<T::Decode, Response = T::Encode>,
+        S::ResponseStream: Send + 'static,
+        B: Body + Send + 'static,
+        B::Error: Into<crate::Error> + Send,
+    {
+        let req_stream = req.map(|body| Streaming::new(body, self.codec.decoder()));
+
+        let resp = service.call(Request::from_http(req_stream)).await;
+
+        let (mut parts, resp_body) = resp.unwrap().into_http().into_parts();
+        let resp_body = encode_server(self.codec.encoder(), resp_body);
+
+        parts.headers.insert(
+            http::header::CONTENT_TYPE,
+            http::HeaderValue::from_static("application/grpc"),
+        );
+        parts.status = http::StatusCode::OK;
+        http::Response::from_parts(parts, BoxBody::new(resp_body))
+    }
+
+    pub async fn unary<S, B>(
+        &mut self,
+        mut service: S,
+        req: http::Request<B>,
+    ) -> http::Response<BoxBody>
+    where
+        S: UnaryService<T::Decode, Response = T::Encode>,
+        B: Body + Send + 'static,
+        B::Error: Debug,
+    {
+        let (_parts, body) = req.into_parts();
+        let req_body = hyper::body::to_bytes(body).await.unwrap();
+        let v = req_body.chunk();
+        let mut req_byte = BytesMut::from(v);
+        let mut de = DecodeBuf::new(&mut req_byte, v.len());
+        let decoder = self
+            .codec
+            .decoder()
+            .decode(&mut de)
+            .map(|v| v.unwrap())
+            .unwrap();
+        let req = Request::new(decoder);
+
+        let resp = service.call(req).await;
+
+        let resp = match resp {
+            Ok(r) => r,
+            Err(status) => {
+                let (mut parts, _body) = http::Response::new(()).into_parts();
+                parts.headers.insert(
+                    http::header::CONTENT_TYPE,
+                    http::HeaderValue::from_static("application/grpc"),
+                );
+                parts.status = status.to_http().status();
+
+                return http::Response::from_parts(parts, crate::empty_body());
+            }
+        };
+        let (mut parts, body) = resp.into_http().into_parts();
+
+        // let data = hyper::body::aggregate(body)
+        // let b = body.size_hint();
+        let mut bytes = BytesMut::with_capacity(100);
+        let mut dst = EncodeBuf::new(&mut bytes);
+        let _res = self.codec.encoder().encode(body, &mut dst);
+        let data = bytes.to_vec();
+
+        let resp_body = hyper::Body::from(data);
+
+        parts.status = http::StatusCode::OK;
+        // http::Response::from_parts(parts, resp_body.map_err(|err| err.into()).boxed_unsync())
+        http::Response::from_parts(
+            parts,
+            resp_body
+                .map_err(|err| tonic::Status::new(tonic::Code::Internal, err.to_string()))
+                .boxed_unsync(),
+        )
+    }
+}
+
+impl<T> BusinessConfig for TripleServer<T> {
+    fn init() -> Self {
+        todo!()
+    }
+
+    fn load() -> Result<(), std::convert::Infallible> {
+        todo!()
+    }
+}
diff --git a/triple/src/server/service.rs b/triple/src/server/service.rs
new file mode 100644
index 0000000..cc2740c
--- /dev/null
+++ b/triple/src/server/service.rs
@@ -0,0 +1,68 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.
+ */
+
+use super::decode::Streaming;
+use crate::invocation::{Request, Response};
+use futures_util::{Future, Stream};
+use tower_service::Service;
+
+pub trait StreamingSvc<R> {
+    // proto response
+    type Response;
+    // the stream of proto message
+    type ResponseStream: Stream<Item = Result<Self::Response, tonic::Status>>;
+    // future of stream of proto message
+    type Future: Future<Output = Result<Response<Self::ResponseStream>, tonic::Status>>;
+
+    fn call(&mut self, req: Request<Streaming<R>>) -> Self::Future;
+}
+
+impl<T, S, M1, M2> StreamingSvc<M1> for T
+where
+    T: Service<Request<Streaming<M1>>, Response = Response<S>, Error = tonic::Status>,
+    S: Stream<Item = Result<M2, tonic::Status>>,
+{
+    type Response = M2;
+
+    type ResponseStream = S;
+
+    type Future = T::Future;
+
+    fn call(&mut self, req: Request<Streaming<M1>>) -> Self::Future {
+        Service::call(self, req)
+    }
+}
+
+pub trait UnaryService<R> {
+    type Response;
+    type Future: Future<Output = Result<Response<Self::Response>, tonic::Status>>;
+
+    fn call(&mut self, req: Request<R>) -> Self::Future;
+}
+
+impl<T, M1, M2> UnaryService<M1> for T
+where
+    T: Service<Request<M1>, Response = Response<M2>, Error = tonic::Status>,
+{
+    type Response = M2;
+
+    type Future = T::Future;
+
+    fn call(&mut self, req: Request<M1>) -> Self::Future {
+        T::call(self, req)
+    }
+}
diff --git a/dubbo/src/lib.rs b/triple/src/transport/mod.rs
similarity index 92%
copy from dubbo/src/lib.rs
copy to triple/src/transport/mod.rs
index e292e47..1f772a6 100644
--- a/dubbo/src/lib.rs
+++ b/triple/src/transport/mod.rs
@@ -15,7 +15,6 @@
  * limitations under the License.
  */
 
-pub mod common;
-pub mod helloworld;
-pub mod protocol;
-pub mod utils;
+pub mod service;
+
+pub use service::DubboServer;
diff --git a/triple/src/transport/service.rs b/triple/src/transport/service.rs
new file mode 100644
index 0000000..8001ef5
--- /dev/null
+++ b/triple/src/transport/service.rs
@@ -0,0 +1,181 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.
+ */
+
+use std::collections::HashMap;
+use std::future;
+use std::net::SocketAddr;
+use std::task::Poll;
+
+use http::{Request, Response};
+use hyper::{body::Body, server::conn::AddrStream};
+use tokio::time::Duration;
+use tower::ServiceExt;
+use tower_service::Service;
+
+use crate::BoxBody;
+use config::BusinessConfig;
+use config::Config;
+
+type BoxService = tower::util::BoxService<Request<Body>, Response<BoxBody>, crate::Error>;
+type BoxCloneService = tower::util::BoxCloneService<Request<Body>, Response<BoxBody>, crate::Error>;
+
+#[derive(Default, Clone)]
+pub struct DubboServer {
+    accept_http2: bool,
+    init_stream_window_size: Option<u32>,
+    init_connection_window_size: Option<u32>,
+    max_concurrent_streams: Option<u32>,
+    max_frame_size: Option<u32>,
+    http2_keepalive_interval: Option<Duration>,
+    http2_keepalive_timeout: Option<Duration>,
+    services: HashMap<String, BoxCloneService>,
+}
+
+impl DubboServer {
+    pub fn with_accpet_http1(self, accept_http2: bool) -> Self {
+        Self {
+            accept_http2: accept_http2,
+            ..self
+        }
+    }
+
+    pub fn with_init_stream_window_size(self, stream_window: u32) -> Self {
+        Self {
+            init_stream_window_size: Some(stream_window),
+            ..self
+        }
+    }
+
+    pub fn with_init_connection_window_size(self, connection_window: u32) -> Self {
+        Self {
+            init_connection_window_size: Some(connection_window),
+            ..self
+        }
+    }
+    pub fn with_max_concurrent_streams(self, concurrent_streams: u32) -> Self {
+        Self {
+            max_concurrent_streams: Some(concurrent_streams),
+            ..self
+        }
+    }
+    pub fn with_max_frame_size(self, max_frame_size: u32) -> Self {
+        Self {
+            max_frame_size: Some(max_frame_size),
+            ..self
+        }
+    }
+    pub fn with_http2_keepalive_interval(self, interval: Duration) -> Self {
+        Self {
+            http2_keepalive_interval: Some(interval),
+            ..self
+        }
+    }
+
+    pub fn with_http2_keepalive_timeout(self, timeout: Duration) -> Self {
+        Self {
+            http2_keepalive_timeout: Some(timeout),
+            ..self
+        }
+    }
+}
+
+impl DubboServer {
+    pub fn new() -> Self {
+        Self {
+            accept_http2: true,
+            init_stream_window_size: None,
+            init_connection_window_size: None,
+            max_concurrent_streams: None,
+            http2_keepalive_interval: None,
+            http2_keepalive_timeout: None,
+            max_frame_size: None,
+            services: HashMap::new(),
+        }
+    }
+}
+
+impl DubboServer {
+    pub fn add_service<S>(mut self, name: String, service: S) -> Self
+    where
+        S: Service<Request<Body>, Response = Response<BoxBody>> + Clone + Send + 'static,
+        S::Future: Send + 'static,
+        S::Error: Into<crate::Error> + Send + 'static,
+    {
+        self.services
+            .insert(name, service.map_err(|err| err.into()).boxed_clone());
+        Self { ..self }
+    }
+
+    pub async fn serve(self, name: String, addr: SocketAddr) -> Result<(), crate::Error> {
+        let svc = MakeSvc {
+            inner: self.services.get(&name).unwrap().clone(),
+        };
+
+        hyper::Server::bind(&addr)
+            .http2_only(self.accept_http2)
+            .http2_max_concurrent_streams(self.max_concurrent_streams)
+            .http2_initial_connection_window_size(self.init_connection_window_size)
+            .http2_initial_stream_window_size(self.init_stream_window_size)
+            .http2_keep_alive_interval(self.http2_keepalive_interval)
+            .http2_keep_alive_timeout(self.http2_keepalive_timeout.unwrap())
+            .http2_max_frame_size(self.max_frame_size)
+            .serve(svc)
+            .await
+            .map_err(|err| println!("Error: {:?}", err))
+            .unwrap();
+
+        Ok(())
+    }
+}
+
+struct MakeSvc<S> {
+    inner: S,
+}
+
+impl<S> Service<&AddrStream> for MakeSvc<S>
+where
+    S: Service<Request<Body>, Response = Response<BoxBody>> + Clone + Send + 'static,
+    S::Future: Send + 'static,
+    S::Error: Into<crate::Error> + Send + 'static,
+{
+    type Response = BoxService;
+    type Error = crate::Error;
+    type Future = future::Ready<Result<Self::Response, Self::Error>>;
+
+    fn poll_ready(&mut self, _cx: &mut std::task::Context<'_>) -> Poll<Result<(), Self::Error>> {
+        Poll::Ready(Ok(()))
+    }
+
+    fn call(&mut self, _conn: &AddrStream) -> Self::Future {
+        let svc = self.inner.clone();
+        let s = svc.map_err(|err| err.into()).boxed();
+        future::ready(Ok(s))
+    }
+}
+
+impl BusinessConfig for DubboServer {
+    fn init() -> Self {
+        let conf = config::get_global_config();
+        let server = DubboServer::new()
+            .with_accpet_http1(conf.bool("dubbo.server.accept_http2".to_string()));
+        server
+    }
+
+    fn load() -> Result<(), std::convert::Infallible> {
+        todo!()
+    }
+}


[dubbo-rust] 24/38: refactor(dubbo): use cargo fmt --all

Posted by li...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

liujun pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/dubbo-rust.git

commit fd2ff6d554a1ec9357f2ecb444c122399c4099a1
Author: yang <96...@qq.com>
AuthorDate: Mon Jun 27 21:37:01 2022 +0800

    refactor(dubbo): use cargo fmt --all
---
 dubbo/src/common/mod.rs                 |  2 +-
 dubbo/src/common/url.rs                 |  4 +-
 dubbo/src/helloworld/client.rs          |  2 +-
 dubbo/src/helloworld/helloworld.rs      | 87 +++++++++++++--------------------
 dubbo/src/helloworld/mod.rs             |  2 +-
 dubbo/src/lib.rs                        |  4 +-
 dubbo/src/main.rs                       |  5 +-
 dubbo/src/service/grpc/grpc_exporter.rs | 22 ++++-----
 dubbo/src/service/grpc/grpc_invoker.rs  | 28 +++++------
 dubbo/src/service/grpc/grpc_protocol.rs | 15 +++---
 dubbo/src/service/grpc/grpc_server.rs   | 51 ++++++++++---------
 dubbo/src/service/grpc/mod.rs           | 49 ++++++++++++-------
 dubbo/src/service/invocation.rs         | 10 ++--
 dubbo/src/service/mod.rs                |  3 +-
 dubbo/src/service/protocol.rs           |  5 +-
 dubbo/src/utils/boxed.rs                |  2 +-
 dubbo/src/utils/boxed_clone.rs          | 15 ++++--
 dubbo/src/utils/mod.rs                  |  2 +-
 18 files changed, 148 insertions(+), 160 deletions(-)

diff --git a/dubbo/src/common/mod.rs b/dubbo/src/common/mod.rs
index aff8e30..591151d 100644
--- a/dubbo/src/common/mod.rs
+++ b/dubbo/src/common/mod.rs
@@ -1 +1 @@
-pub mod url;
\ No newline at end of file
+pub mod url;
diff --git a/dubbo/src/common/url.rs b/dubbo/src/common/url.rs
index 879a1a0..6d4958d 100644
--- a/dubbo/src/common/url.rs
+++ b/dubbo/src/common/url.rs
@@ -1,5 +1,5 @@
 #[derive(Debug, Clone)]
 pub struct Url {
     pub url: String,
-    pub service_key: String
-}
\ No newline at end of file
+    pub service_key: String,
+}
diff --git a/dubbo/src/helloworld/client.rs b/dubbo/src/helloworld/client.rs
index f4517b4..591e382 100644
--- a/dubbo/src/helloworld/client.rs
+++ b/dubbo/src/helloworld/client.rs
@@ -20,4 +20,4 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
     println!("RESPONSE={:?}", response);
 
     Ok(())
-}
\ No newline at end of file
+}
diff --git a/dubbo/src/helloworld/helloworld.rs b/dubbo/src/helloworld/helloworld.rs
index b951157..41eb5d9 100644
--- a/dubbo/src/helloworld/helloworld.rs
+++ b/dubbo/src/helloworld/helloworld.rs
@@ -1,13 +1,13 @@
 /// The request message containing the user's name.
 #[derive(Clone, PartialEq, ::prost::Message)]
 pub struct HelloRequest {
-    #[prost(string, tag="1")]
+    #[prost(string, tag = "1")]
     pub name: ::prost::alloc::string::String,
 }
 /// The response message containing the greetings
 #[derive(Clone, PartialEq, ::prost::Message)]
 pub struct HelloReply {
-    #[prost(string, tag="1")]
+    #[prost(string, tag = "1")]
     pub message: ::prost::alloc::string::String,
 }
 /// Generated client implementations.
@@ -54,9 +54,8 @@ pub mod greeter_client {
                     <T as tonic::client::GrpcService<tonic::body::BoxBody>>::ResponseBody,
                 >,
             >,
-            <T as tonic::codegen::Service<
-                http::Request<tonic::body::BoxBody>,
-            >>::Error: Into<StdError> + Send + Sync,
+            <T as tonic::codegen::Service<http::Request<tonic::body::BoxBody>>>::Error:
+                Into<StdError> + Send + Sync,
         {
             GreeterClient::new(InterceptedService::new(inner, interceptor))
         }
@@ -80,19 +79,14 @@ pub mod greeter_client {
             &mut self,
             request: impl tonic::IntoRequest<super::HelloRequest>,
         ) -> Result<tonic::Response<super::HelloReply>, tonic::Status> {
-            self.inner
-                .ready()
-                .await
-                .map_err(|e| {
-                    tonic::Status::new(
-                        tonic::Code::Unknown,
-                        format!("Service was not ready: {}", e.into()),
-                    )
-                })?;
+            self.inner.ready().await.map_err(|e| {
+                tonic::Status::new(
+                    tonic::Code::Unknown,
+                    format!("Service was not ready: {}", e.into()),
+                )
+            })?;
             let codec = tonic::codec::ProstCodec::default();
-            let path = http::uri::PathAndQuery::from_static(
-                "/helloworld.Greeter/SayHello",
-            );
+            let path = http::uri::PathAndQuery::from_static("/helloworld.Greeter/SayHello");
             self.inner.unary(request.into_request(), path, codec).await
         }
     }
@@ -101,10 +95,10 @@ pub mod greeter_client {
 pub mod greeter_server {
     #![allow(unused_variables, dead_code, missing_docs, clippy::let_unit_value)]
 
-    use tonic::codegen::*;
-    use crate::service::protocol::Invoker;
     use crate::service::grpc::grpc_server::DubboGrpcService;
     use crate::service::grpc::grpc_server::ServiceDesc;
+    use crate::service::protocol::Invoker;
+    use tonic::codegen::*;
 
     ///Generated trait containing gRPC methods that should be implemented for use with GreeterServer.
     #[async_trait]
@@ -137,10 +131,7 @@ pub mod greeter_server {
                 send_compression_encodings: Default::default(),
             }
         }
-        pub fn with_interceptor<F>(
-            inner: T,
-            interceptor: F,
-        ) -> InterceptedService<Self, F>
+        pub fn with_interceptor<F>(inner: T, interceptor: F) -> InterceptedService<Self, F>
         where
             F: tonic::service::Interceptor,
         {
@@ -168,10 +159,7 @@ pub mod greeter_server {
         type Response = http::Response<tonic::body::BoxBody>;
         type Error = std::convert::Infallible;
         type Future = BoxFuture<Self::Response, Self::Error>;
-        fn poll_ready(
-            &mut self,
-            _cx: &mut Context<'_>,
-        ) -> Poll<Result<(), Self::Error>> {
+        fn poll_ready(&mut self, _cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
             Poll::Ready(Ok(()))
         }
         fn call(&mut self, req: http::Request<B>) -> Self::Future {
@@ -180,13 +168,9 @@ pub mod greeter_server {
                 "/helloworld.Greeter/SayHello" => {
                     #[allow(non_camel_case_types)]
                     struct SayHelloSvc<T: Greeter>(pub Arc<T>);
-                    impl<T: Greeter> tonic::server::UnaryService<super::HelloRequest>
-                    for SayHelloSvc<T> {
+                    impl<T: Greeter> tonic::server::UnaryService<super::HelloRequest> for SayHelloSvc<T> {
                         type Response = super::HelloReply;
-                        type Future = BoxFuture<
-                            tonic::Response<Self::Response>,
-                            tonic::Status,
-                        >;
+                        type Future = BoxFuture<tonic::Response<Self::Response>, tonic::Status>;
                         fn call(
                             &mut self,
                             request: tonic::Request<super::HelloRequest>,
@@ -203,32 +187,27 @@ pub mod greeter_server {
                         let inner = inner.0;
                         let method = SayHelloSvc(inner);
                         let codec = tonic::codec::ProstCodec::default();
-                        let mut grpc = tonic::server::Grpc::new(codec)
-                            .apply_compression_config(
-                                accept_compression_encodings,
-                                send_compression_encodings,
-                            );
+                        let mut grpc = tonic::server::Grpc::new(codec).apply_compression_config(
+                            accept_compression_encodings,
+                            send_compression_encodings,
+                        );
                         let res = grpc.unary(method, req).await;
                         Ok(res)
                     };
                     Box::pin(fut)
                 }
-                _ => {
-                    Box::pin(async move {
-                        Ok(
-                            http::Response::builder()
-                                .status(200)
-                                .header("grpc-status", "12")
-                                .header("content-type", "application/grpc")
-                                .body(empty_body())
-                                .unwrap(),
-                        )
-                    })
-                }
+                _ => Box::pin(async move {
+                    Ok(http::Response::builder()
+                        .status(200)
+                        .header("grpc-status", "12")
+                        .header("content-type", "application/grpc")
+                        .body(empty_body())
+                        .unwrap())
+                }),
             }
         }
     }
-    impl<T: Greeter, I: Invoker+ Send+ Sync + 'static> Clone for GreeterServer<T, I> {
+    impl<T: Greeter, I: Invoker + Send + Sync + 'static> Clone for GreeterServer<T, I> {
         fn clone(&self) -> Self {
             let inner = self.inner.clone();
             Self {
@@ -243,7 +222,6 @@ pub mod greeter_server {
                 send_compression_encodings: self.send_compression_encodings,
             }
         }
-
     }
 
     impl<T: Greeter> Clone for _Inner<T> {
@@ -262,7 +240,10 @@ pub mod greeter_server {
         }
 
         fn service_desc(&self) -> ServiceDesc {
-            ServiceDesc::new("helloworld.Greeter".to_string(), std::collections::HashMap::new())
+            ServiceDesc::new(
+                "helloworld.Greeter".to_string(),
+                std::collections::HashMap::new(),
+            )
         }
     }
 
diff --git a/dubbo/src/helloworld/mod.rs b/dubbo/src/helloworld/mod.rs
index 5f1509d..b1358dd 100644
--- a/dubbo/src/helloworld/mod.rs
+++ b/dubbo/src/helloworld/mod.rs
@@ -1 +1 @@
-pub mod helloworld;
\ No newline at end of file
+pub mod helloworld;
diff --git a/dubbo/src/lib.rs b/dubbo/src/lib.rs
index 317ed6f..0e5bedf 100644
--- a/dubbo/src/lib.rs
+++ b/dubbo/src/lib.rs
@@ -1,4 +1,4 @@
+pub mod common;
 pub mod helloworld;
 pub mod service;
-pub mod common;
-pub mod utils;
\ No newline at end of file
+pub mod utils;
diff --git a/dubbo/src/main.rs b/dubbo/src/main.rs
index ecc7b56..4bb2acf 100644
--- a/dubbo/src/main.rs
+++ b/dubbo/src/main.rs
@@ -1,10 +1,9 @@
-pub mod service;
 pub mod common;
-pub mod utils;
 pub mod helloworld;
+pub mod service;
+pub mod utils;
 
 #[tokio::main]
 async fn main() {
     println!("hello, dubbo-rust~")
 }
-
diff --git a/dubbo/src/service/grpc/grpc_exporter.rs b/dubbo/src/service/grpc/grpc_exporter.rs
index 4f367f2..7671b6d 100644
--- a/dubbo/src/service/grpc/grpc_exporter.rs
+++ b/dubbo/src/service/grpc/grpc_exporter.rs
@@ -1,9 +1,8 @@
-
+use crate::service::protocol::Invoker;
 use crate::service::protocol::*;
-use crate::service::protocol::Invoker;    
 
 pub struct GrpcExporter<T> {
-    invoker: T
+    invoker: T,
 }
 
 impl<T> GrpcExporter<T> {
@@ -12,23 +11,20 @@ impl<T> GrpcExporter<T> {
     }
 }
 
-impl<T: Invoker+Clone> Exporter for GrpcExporter<T>
-{
+impl<T: Invoker + Clone> Exporter for GrpcExporter<T> {
     type InvokerType = T;
 
-    fn unexport(&self) {
-    }
+    fn unexport(&self) {}
 
     fn get_invoker(&self) -> Self::InvokerType {
         self.invoker.clone()
     }
-
 }
 
-impl<T: Invoker+Clone> Clone for GrpcExporter<T> {
-    
+impl<T: Invoker + Clone> Clone for GrpcExporter<T> {
     fn clone(&self) -> Self {
-        Self { invoker: self.invoker.clone() }
+        Self {
+            invoker: self.invoker.clone(),
+        }
     }
-
-}
\ No newline at end of file
+}
diff --git a/dubbo/src/service/grpc/grpc_invoker.rs b/dubbo/src/service/grpc/grpc_invoker.rs
index 6016914..3fbd442 100644
--- a/dubbo/src/service/grpc/grpc_invoker.rs
+++ b/dubbo/src/service/grpc/grpc_invoker.rs
@@ -4,41 +4,35 @@ use tonic::client::Grpc;
 use tonic::transport::Channel;
 use tonic::transport::Endpoint;
 
-use crate::service::protocol::*;
-use crate::service::invocation;
 use crate::common::url::Url;
+use crate::service::invocation;
+use crate::service::protocol::*;
 
 pub struct GrpcInvoker {
     client: Grpc<Channel>,
     url: Url,
-    once: Once
+    once: Once,
 }
 
-
-
 impl GrpcInvoker {
     pub fn new(url: Url) -> GrpcInvoker {
-
         let endpoint = Endpoint::new(url.url.clone()).unwrap();
         let conn = endpoint.connect_lazy();
         Self {
             url,
             client: Grpc::new(conn),
-            once: Once::new()
+            once: Once::new(),
         }
     }
 }
 
 impl Invoker for GrpcInvoker {
-
     fn is_available(&self) -> bool {
         true
     }
 
     fn destroy(&self) {
-        self.once.call_once(|| {
-            println!("destroy...")
-        })
+        self.once.call_once(|| println!("destroy..."))
     }
 
     fn get_url(&self) -> Url {
@@ -46,7 +40,7 @@ impl Invoker for GrpcInvoker {
     }
 
     // 根据req中的数据发起req,由Client发起请求,获取响应
-   fn invoke<M1>(&self, req: invocation::Request<M1>) -> invocation::Response<String>
+    fn invoke<M1>(&self, req: invocation::Request<M1>) -> invocation::Response<String>
     where
         M1: Send + 'static,
     {
@@ -54,7 +48,7 @@ impl Invoker for GrpcInvoker {
 
         let resp = invocation::Response::new("string");
         let (_resp_meta, msg) = resp.into_parts();
- 
+
         invocation::Response::from_parts(metadata, msg.to_string())
     }
 }
@@ -68,6 +62,10 @@ impl Invoker for GrpcInvoker {
 
 impl Clone for GrpcInvoker {
     fn clone(&self) -> Self {
-        Self { client: self.client.clone(), url: self.url.clone(), once: Once::new() }
+        Self {
+            client: self.client.clone(),
+            url: self.url.clone(),
+            once: Once::new(),
+        }
     }
-}
\ No newline at end of file
+}
diff --git a/dubbo/src/service/grpc/grpc_protocol.rs b/dubbo/src/service/grpc/grpc_protocol.rs
index 08fe921..8fe1aa8 100644
--- a/dubbo/src/service/grpc/grpc_protocol.rs
+++ b/dubbo/src/service/grpc/grpc_protocol.rs
@@ -1,15 +1,14 @@
-
 use std::collections::HashMap;
 
-use super::grpc_invoker::GrpcInvoker;
 use super::grpc_exporter::GrpcExporter;
+use super::grpc_invoker::GrpcInvoker;
+use super::grpc_server::GrpcServer;
 use crate::common::url::Url;
 use crate::service::protocol::Protocol;
-use super::grpc_server::GrpcServer;
 
 pub struct GrpcProtocol {
     server_map: HashMap<String, GrpcServer>,
-    export_map: HashMap<String, GrpcExporter<GrpcInvoker>>
+    export_map: HashMap<String, GrpcExporter<GrpcInvoker>>,
 }
 
 impl GrpcProtocol {
@@ -28,8 +27,7 @@ impl Default for GrpcProtocol {
 }
 
 #[async_trait::async_trait]
-impl Protocol for GrpcProtocol
-{
+impl Protocol for GrpcProtocol {
     type Invoker = GrpcInvoker;
 
     type Exporter = GrpcExporter<Self::Invoker>;
@@ -45,7 +43,8 @@ impl Protocol for GrpcProtocol
     async fn export(self, url: Url) -> Self::Exporter {
         let service_key = url.service_key.clone();
 
-        let exporter: GrpcExporter<GrpcInvoker> = GrpcExporter::new(service_key.clone(), GrpcInvoker::new(url.clone()));
+        let exporter: GrpcExporter<GrpcInvoker> =
+            GrpcExporter::new(service_key.clone(), GrpcInvoker::new(url.clone()));
         let mut export = self.export_map;
         export.insert(service_key.clone(), exporter.clone());
 
@@ -57,4 +56,4 @@ impl Protocol for GrpcProtocol
         server.serve(url.clone()).await;
         exporter
     }
-}
\ No newline at end of file
+}
diff --git a/dubbo/src/service/grpc/grpc_server.rs b/dubbo/src/service/grpc/grpc_server.rs
index 1047054..9d2656e 100644
--- a/dubbo/src/service/grpc/grpc_server.rs
+++ b/dubbo/src/service/grpc/grpc_server.rs
@@ -2,20 +2,18 @@ use std::collections::HashMap;
 use std::task::Context;
 use std::task::Poll;
 
+use tonic::codegen::BoxFuture;
 use tonic::transport;
-use tower::Service;
 use tonic::transport::NamedService;
-use tonic::codegen::BoxFuture;
-
+use tower::Service;
 
+use super::grpc_invoker::GrpcInvoker;
 use crate::common::url::Url;
 use crate::helloworld::helloworld::greeter_server::GreeterServer;
-use super::grpc_invoker::GrpcInvoker;
 use crate::helloworld::helloworld::greeter_server::*;
 use crate::utils::boxed_clone::BoxCloneService;
 
-pub trait DubboGrpcService<T>
-{
+pub trait DubboGrpcService<T> {
     fn set_proxy_impl(&mut self, invoker: T);
     fn service_desc(&self) -> ServiceDesc;
 }
@@ -35,7 +33,7 @@ pub struct ServiceDesc {
     // methods: HashMap<String, String> // "/Greeter/hello": "unary"
 }
 
-impl  ServiceDesc {
+impl ServiceDesc {
     pub fn new(service_name: String, _methods: HashMap<String, String>) -> Self {
         Self { service_name }
     }
@@ -46,7 +44,9 @@ impl  ServiceDesc {
 }
 
 // codegen
-pub fn register_greeter_server<T: Greeter>(server: T) -> (super::GrpcBoxCloneService, super::DubboGrpcBox) {
+pub fn register_greeter_server<T: Greeter>(
+    server: T,
+) -> (super::GrpcBoxCloneService, super::DubboGrpcBox) {
     let hello = GreeterServer::<T, GrpcInvoker>::new(server);
     (BoxCloneService::new(hello.clone()), Box::new(hello.clone()))
 }
@@ -58,36 +58,39 @@ pub struct GrpcServer {
     name: String,
 }
 
-impl GrpcServer
-{
+impl GrpcServer {
     pub fn new(name: String) -> GrpcServer {
         Self {
             inner: transport::Server::builder(),
-            name
+            name,
         }
     }
 
-    pub async fn serve(mut self, url: Url)
-    where
-    {
+    pub async fn serve(mut self, url: Url) {
         let addr = url.url.clone().parse().unwrap();
-        let svc = super::GRPC_SERVICES.read().unwrap().get(self.name.as_str()).unwrap().clone();
+        let svc = super::GRPC_SERVICES
+            .read()
+            .unwrap()
+            .get(self.name.as_str())
+            .unwrap()
+            .clone();
         println!("server{:?} start...", url);
-        self.inner.add_service(MakeSvc::new(svc)).serve(
-            addr
-        ).await.unwrap();
+        self.inner
+            .add_service(MakeSvc::new(svc))
+            .serve(addr)
+            .await
+            .unwrap();
         println!("server{:?} start...", url);
     }
-
 }
 
 struct MakeSvc<T, U, E> {
-    inner: BoxCloneService<T, U, E>
+    inner: BoxCloneService<T, U, E>,
 }
 
 impl<T, U, E> MakeSvc<T, U, E> {
     pub fn new(inner: BoxCloneService<T, U, E>) -> Self {
-        Self { inner}
+        Self { inner }
     }
 }
 
@@ -111,6 +114,8 @@ impl<T, U, E> Service<T> for MakeSvc<T, U, E> {
 
 impl<T, U, E> Clone for MakeSvc<T, U, E> {
     fn clone(&self) -> Self {
-        Self { inner: self.inner.clone() }
+        Self {
+            inner: self.inner.clone(),
+        }
     }
-}
\ No newline at end of file
+}
diff --git a/dubbo/src/service/grpc/mod.rs b/dubbo/src/service/grpc/mod.rs
index 3350638..7c70105 100644
--- a/dubbo/src/service/grpc/mod.rs
+++ b/dubbo/src/service/grpc/mod.rs
@@ -1,45 +1,56 @@
-pub mod grpc_protocol;
-pub mod grpc_invoker;
 pub mod grpc_exporter;
+pub mod grpc_invoker;
+pub mod grpc_protocol;
 pub mod grpc_server;
 
+use lazy_static::lazy_static;
 use std::collections::HashMap;
 use std::sync::RwLock;
-use lazy_static::lazy_static;
 
-use grpc_server::DubboGrpcService;
-use grpc_invoker::GrpcInvoker;
 use crate::helloworld::helloworld::greeter_server::Greeter;
+use crate::helloworld::helloworld::{HelloReply, HelloRequest};
 use crate::utils::boxed_clone::BoxCloneService;
-use crate::helloworld::helloworld::{HelloRequest, HelloReply};
+use grpc_invoker::GrpcInvoker;
+use grpc_server::DubboGrpcService;
 
-pub type GrpcBoxCloneService = BoxCloneService<http::Request<hyper::Body>, http::Response<tonic::body::BoxBody>, std::convert::Infallible>;
+pub type GrpcBoxCloneService = BoxCloneService<
+    http::Request<hyper::Body>,
+    http::Response<tonic::body::BoxBody>,
+    std::convert::Infallible,
+>;
 
-pub type DubboGrpcBox = Box<dyn DubboGrpcService<GrpcInvoker>+ Send + Sync + 'static>;
+pub type DubboGrpcBox = Box<dyn DubboGrpcService<GrpcInvoker> + Send + Sync + 'static>;
 
 lazy_static! {
-    pub static ref DUBBO_GRPC_SERVICES: RwLock<HashMap<String, Box<dyn DubboGrpcService<GrpcInvoker> + Send + Sync + 'static>>> = RwLock::new(HashMap::new());
-    pub static ref GRPC_SERVICES: RwLock<HashMap<String, GrpcBoxCloneService>> = RwLock::new(HashMap::new());
+    pub static ref DUBBO_GRPC_SERVICES: RwLock<HashMap<String, Box<dyn DubboGrpcService<GrpcInvoker> + Send + Sync + 'static>>> =
+        RwLock::new(HashMap::new());
+    pub static ref GRPC_SERVICES: RwLock<HashMap<String, GrpcBoxCloneService>> =
+        RwLock::new(HashMap::new());
 }
 
 #[tokio::test]
 async fn test_hello() {
-    use grpc_server::register_greeter_server;
-    use crate::service::protocol::Protocol;
     use crate::common::url::Url;
-    
-    let (svc, dubbo_svc) = register_greeter_server(MyGreeter{});
+    use crate::service::protocol::Protocol;
+    use grpc_server::register_greeter_server;
+
+    let (svc, dubbo_svc) = register_greeter_server(MyGreeter {});
     let svc_name = dubbo_svc.service_desc().get_service_name();
-    DUBBO_GRPC_SERVICES.write().unwrap().insert(svc_name.clone(), dubbo_svc);
+    DUBBO_GRPC_SERVICES
+        .write()
+        .unwrap()
+        .insert(svc_name.clone(), dubbo_svc);
     GRPC_SERVICES.write().unwrap().insert(svc_name.clone(), svc);
 
     // server start, api: 0.0.0.0:8888/helloworld.Greeter/SayHello
     let pro = grpc_protocol::GrpcProtocol::new();
-    pro.export(Url{url: "[::1]:50051".to_string(), service_key: svc_name.clone()}).await;
-
+    pro.export(Url {
+        url: "[::1]:50051".to_string(),
+        service_key: svc_name.clone(),
+    })
+    .await;
 }
 
-
 #[derive(Default)]
 pub struct MyGreeter {}
 
@@ -56,4 +67,4 @@ impl Greeter for MyGreeter {
         };
         Ok(tonic::Response::new(reply))
     }
-}
\ No newline at end of file
+}
diff --git a/dubbo/src/service/invocation.rs b/dubbo/src/service/invocation.rs
index dff46fa..690a345 100644
--- a/dubbo/src/service/invocation.rs
+++ b/dubbo/src/service/invocation.rs
@@ -5,12 +5,11 @@ pub struct Request<T> {
     pub metadata: MetadataMap,
 }
 
-
 impl<T> Request<T> {
     pub fn new(message: T) -> Request<T> {
         Self {
             message,
-            metadata: MetadataMap::new()
+            metadata: MetadataMap::new(),
         }
     }
 
@@ -33,13 +32,10 @@ impl<T> Response<T> {
     }
 
     pub fn from_parts(metadata: MetadataMap, message: T) -> Self {
-        Self {
-            message,
-            metadata,
-        }
+        Self { message, metadata }
     }
 
     pub fn into_parts(self) -> (MetadataMap, T) {
         (self.metadata, self.message)
     }
-}
\ No newline at end of file
+}
diff --git a/dubbo/src/service/mod.rs b/dubbo/src/service/mod.rs
index 55bcb2f..49d23a4 100644
--- a/dubbo/src/service/mod.rs
+++ b/dubbo/src/service/mod.rs
@@ -1,4 +1,3 @@
-pub mod protocol;
 pub mod grpc;
 pub mod invocation;
-
+pub mod protocol;
diff --git a/dubbo/src/service/protocol.rs b/dubbo/src/service/protocol.rs
index 18d2d7b..3f42284 100644
--- a/dubbo/src/service/protocol.rs
+++ b/dubbo/src/service/protocol.rs
@@ -7,13 +7,12 @@ use async_trait::async_trait;
 pub trait Protocol {
     type Invoker;
     type Exporter;
-    
+
     fn destroy(&self);
     async fn export(self, url: Url) -> Self::Exporter;
     async fn refer(&self, url: Url) -> Self::Invoker;
 }
 
-
 pub trait Exporter {
     type InvokerType: Invoker;
 
@@ -28,4 +27,4 @@ pub trait Invoker {
     fn is_available(&self) -> bool;
     fn destroy(&self);
     fn get_url(&self) -> Url;
-}
\ No newline at end of file
+}
diff --git a/dubbo/src/utils/boxed.rs b/dubbo/src/utils/boxed.rs
index 63297e9..e820031 100644
--- a/dubbo/src/utils/boxed.rs
+++ b/dubbo/src/utils/boxed.rs
@@ -20,7 +20,7 @@ use std::{
 ///
 /// See module level documentation for more details.
 pub struct BoxService<T, U, E> {
-    inner: Box<dyn Service<T, Response = U, Error = E, Future = BoxFuture<U, E>> + Send+ Sync+>,
+    inner: Box<dyn Service<T, Response = U, Error = E, Future = BoxFuture<U, E>> + Send + Sync>,
 }
 
 /// A boxed `Future + Send` trait object.
diff --git a/dubbo/src/utils/boxed_clone.rs b/dubbo/src/utils/boxed_clone.rs
index 0e5e6c3..dde8ec6 100644
--- a/dubbo/src/utils/boxed_clone.rs
+++ b/dubbo/src/utils/boxed_clone.rs
@@ -1,16 +1,17 @@
-use tower::ServiceExt;
 use futures_util::future::BoxFuture;
 use std::{
     fmt,
     task::{Context, Poll},
 };
+use tower::ServiceExt;
 use tower_layer::{layer_fn, LayerFn};
 use tower_service::Service;
 
 pub struct BoxCloneService<T, U, E>(
     Box<
         dyn CloneService<T, Response = U, Error = E, Future = BoxFuture<'static, Result<U, E>>>
-            + Send+Sync,
+            + Send
+            + Sync,
     >,
 );
 
@@ -65,7 +66,8 @@ trait CloneService<R>: Service<R> {
         &self,
     ) -> Box<
         dyn CloneService<R, Response = Self::Response, Error = Self::Error, Future = Self::Future>
-            + Send + Sync,
+            + Send
+            + Sync,
     >;
 }
 
@@ -75,8 +77,11 @@ where
 {
     fn clone_box(
         &self,
-    ) -> Box<dyn CloneService<R, Response = T::Response, Error = T::Error, Future = T::Future> + Send + Sync>
-    {
+    ) -> Box<
+        dyn CloneService<R, Response = T::Response, Error = T::Error, Future = T::Future>
+            + Send
+            + Sync,
+    > {
         Box::new(self.clone())
     }
 }
diff --git a/dubbo/src/utils/mod.rs b/dubbo/src/utils/mod.rs
index a3bbaaa..bd5e148 100644
--- a/dubbo/src/utils/mod.rs
+++ b/dubbo/src/utils/mod.rs
@@ -1,2 +1,2 @@
 pub mod boxed;
-pub mod boxed_clone;
\ No newline at end of file
+pub mod boxed_clone;


[dubbo-rust] 04/38: modify package info

Posted by li...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

liujun pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/dubbo-rust.git

commit e33e22ced34f744f3cfdb9a97ee4972bec225c53
Author: hanxiaoqing <ha...@rongcloud.cn>
AuthorDate: Mon Apr 25 14:35:33 2022 +0800

    modify package info
    
    Signed-off-by: hanxiaoqing <ha...@rongcloud.cn>
---
 common/Cargo.toml   |   2 +-
 config/Cargo.toml   |   2 +-
 examples/Cargo.toml |   4 +-
 examples/LICENSE    | 210 +++++++++++++++++++++++++++++++++++++++++++++++-----
 metadata/Cargo.toml |   2 +-
 protocol/Cargo.toml |   2 +-
 registry/Cargo.toml |   2 +-
 xds/Cargo.toml      |   2 +-
 8 files changed, 198 insertions(+), 28 deletions(-)

diff --git a/common/Cargo.toml b/common/Cargo.toml
index b7723d9..09624c9 100644
--- a/common/Cargo.toml
+++ b/common/Cargo.toml
@@ -1,7 +1,7 @@
 [package]
 name = "common"
 version = "0.1.0"
-edition = "2021"
+edition = "2022"
 
 # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
 
diff --git a/config/Cargo.toml b/config/Cargo.toml
index b8afece..f074d2d 100644
--- a/config/Cargo.toml
+++ b/config/Cargo.toml
@@ -1,7 +1,7 @@
 [package]
 name = "config"
 version = "0.1.0"
-edition = "2021"
+edition = "2022"
 
 # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
 
diff --git a/examples/Cargo.toml b/examples/Cargo.toml
index 3287f9c..a477bf0 100644
--- a/examples/Cargo.toml
+++ b/examples/Cargo.toml
@@ -1,10 +1,8 @@
 [package]
-authors = ["Johankio Smith <jo...@1991.com>"]
-edition = "2018"
-license = "MIT"
 name = "examples"
 publish = false
 version = "0.1.0"
+edition = "2022"
 
 [[bin]]
 name = "helloworld-server"
diff --git a/examples/LICENSE b/examples/LICENSE
index 3077098..d80bbda 100644
--- a/examples/LICENSE
+++ b/examples/LICENSE
@@ -1,19 +1,191 @@
-Copyright (c) 2020 Lucio Franco
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in
-all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-THE SOFTWARE.
+
+                                 Apache License
+                           Version 2.0, January 2004
+                        http://www.apache.org/licenses/
+
+   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+   1. Definitions.
+
+      "License" shall mean the terms and conditions for use, reproduction,
+      and distribution as defined by Sections 1 through 9 of this document.
+
+      "Licensor" shall mean the copyright owner or entity authorized by
+      the copyright owner that is granting the License.
+
+      "Legal Entity" shall mean the union of the acting entity and all
+      other entities that control, are controlled by, or are under common
+      control with that entity. For the purposes of this definition,
+      "control" means (i) the power, direct or indirect, to cause the
+      direction or management of such entity, whether by contract or
+      otherwise, or (ii) ownership of fifty percent (50%) or more of the
+      outstanding shares, or (iii) beneficial ownership of such entity.
+
+      "You" (or "Your") shall mean an individual or Legal Entity
+      exercising permissions granted by this License.
+
+      "Source" form shall mean the preferred form for making modifications,
+      including but not limited to software source code, documentation
+      source, and configuration files.
+
+      "Object" form shall mean any form resulting from mechanical
+      transformation or translation of a Source form, including but
+      not limited to compiled object code, generated documentation,
+      and conversions to other media types.
+
+      "Work" shall mean the work of authorship, whether in Source or
+      Object form, made available under the License, as indicated by a
+      copyright notice that is included in or attached to the work
+      (an example is provided in the Appendix below).
+
+      "Derivative Works" shall mean any work, whether in Source or Object
+      form, that is based on (or derived from) the Work and for which the
+      editorial revisions, annotations, elaborations, or other modifications
+      represent, as a whole, an original work of authorship. For the purposes
+      of this License, Derivative Works shall not include works that remain
+      separable from, or merely link (or bind by name) to the interfaces of,
+      the Work and Derivative Works thereof.
+
+      "Contribution" shall mean any work of authorship, including
+      the original version of the Work and any modifications or additions
+      to that Work or Derivative Works thereof, that is intentionally
+      submitted to Licensor for inclusion in the Work by the copyright owner
+      or by an individual or Legal Entity authorized to submit on behalf of
+      the copyright owner. For the purposes of this definition, "submitted"
+      means any form of electronic, verbal, or written communication sent
+      to the Licensor or its representatives, including but not limited to
+      communication on electronic mailing lists, source code control systems,
+      and issue tracking systems that are managed by, or on behalf of, the
+      Licensor for the purpose of discussing and improving the Work, but
+      excluding communication that is conspicuously marked or otherwise
+      designated in writing by the copyright owner as "Not a Contribution."
+
+      "Contributor" shall mean Licensor and any individual or Legal Entity
+      on behalf of whom a Contribution has been received by Licensor and
+      subsequently incorporated within the Work.
+
+   2. Grant of Copyright License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      copyright license to reproduce, prepare Derivative Works of,
+      publicly display, publicly perform, sublicense, and distribute the
+      Work and such Derivative Works in Source or Object form.
+
+   3. Grant of Patent License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      (except as stated in this section) patent license to make, have made,
+      use, offer to sell, sell, import, and otherwise transfer the Work,
+      where such license applies only to those patent claims licensable
+      by such Contributor that are necessarily infringed by their
+      Contribution(s) alone or by combination of their Contribution(s)
+      with the Work to which such Contribution(s) was submitted. If You
+      institute patent litigation against any entity (including a
+      cross-claim or counterclaim in a lawsuit) alleging that the Work
+      or a Contribution incorporated within the Work constitutes direct
+      or contributory patent infringement, then any patent licenses
+      granted to You under this License for that Work shall terminate
+      as of the date such litigation is filed.
+
+   4. Redistribution. You may reproduce and distribute copies of the
+      Work or Derivative Works thereof in any medium, with or without
+      modifications, and in Source or Object form, provided that You
+      meet the following conditions:
+
+      (a) You must give any other recipients of the Work or
+          Derivative Works a copy of this License; and
+
+      (b) You must cause any modified files to carry prominent notices
+          stating that You changed the files; and
+
+      (c) You must retain, in the Source form of any Derivative Works
+          that You distribute, all copyright, patent, trademark, and
+          attribution notices from the Source form of the Work,
+          excluding those notices that do not pertain to any part of
+          the Derivative Works; and
+
+      (d) If the Work includes a "NOTICE" text file as part of its
+          distribution, then any Derivative Works that You distribute must
+          include a readable copy of the attribution notices contained
+          within such NOTICE file, excluding those notices that do not
+          pertain to any part of the Derivative Works, in at least one
+          of the following places: within a NOTICE text file distributed
+          as part of the Derivative Works; within the Source form or
+          documentation, if provided along with the Derivative Works; or,
+          within a display generated by the Derivative Works, if and
+          wherever such third-party notices normally appear. The contents
+          of the NOTICE file are for informational purposes only and
+          do not modify the License. You may add Your own attribution
+          notices within Derivative Works that You distribute, alongside
+          or as an addendum to the NOTICE text from the Work, provided
+          that such additional attribution notices cannot be construed
+          as modifying the License.
+
+      You may add Your own copyright statement to Your modifications and
+      may provide additional or different license terms and conditions
+      for use, reproduction, or distribution of Your modifications, or
+      for any such Derivative Works as a whole, provided Your use,
+      reproduction, and distribution of the Work otherwise complies with
+      the conditions stated in this License.
+
+   5. Submission of Contributions. Unless You explicitly state otherwise,
+      any Contribution intentionally submitted for inclusion in the Work
+      by You to the Licensor shall be under the terms and conditions of
+      this License, without any additional terms or conditions.
+      Notwithstanding the above, nothing herein shall supersede or modify
+      the terms of any separate license agreement you may have executed
+      with Licensor regarding such Contributions.
+
+   6. Trademarks. This License does not grant permission to use the trade
+      names, trademarks, service marks, or product names of the Licensor,
+      except as required for reasonable and customary use in describing the
+      origin of the Work and reproducing the content of the NOTICE file.
+
+   7. Disclaimer of Warranty. Unless required by applicable law or
+      agreed to in writing, Licensor provides the Work (and each
+      Contributor provides its Contributions) on an "AS IS" BASIS,
+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+      implied, including, without limitation, any warranties or conditions
+      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+      PARTICULAR PURPOSE. You are solely responsible for determining the
+      appropriateness of using or redistributing the Work and assume any
+      risks associated with Your exercise of permissions under this License.
+
+   8. Limitation of Liability. In no event and under no legal theory,
+      whether in tort (including negligence), contract, or otherwise,
+      unless required by applicable law (such as deliberate and grossly
+      negligent acts) or agreed to in writing, shall any Contributor be
+      liable to You for damages, including any direct, indirect, special,
+      incidental, or consequential damages of any character arising as a
+      result of this License or out of the use or inability to use the
+      Work (including but not limited to damages for loss of goodwill,
+      work stoppage, computer failure or malfunction, or any and all
+      other commercial damages or losses), even if such Contributor
+      has been advised of the possibility of such damages.
+
+   9. Accepting Warranty or Additional Liability. While redistributing
+      the Work or Derivative Works thereof, You may choose to offer,
+      and charge a fee for, acceptance of support, warranty, indemnity,
+      or other liability obligations and/or rights consistent with this
+      License. However, in accepting such obligations, You may act only
+      on Your own behalf and on Your sole responsibility, not on behalf
+      of any other Contributor, and only if You agree to indemnify,
+      defend, and hold each Contributor harmless for any liability
+      incurred by, or claims asserted against, such Contributor by reason
+      of your accepting any such warranty or additional liability.
+
+   END OF TERMS AND CONDITIONS
+
+   Copyright (c) 2016 ~ 2018 Alex Stocks.
+
+   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.
diff --git a/metadata/Cargo.toml b/metadata/Cargo.toml
index a600f4c..7fda9ec 100644
--- a/metadata/Cargo.toml
+++ b/metadata/Cargo.toml
@@ -1,7 +1,7 @@
 [package]
 name = "metadata"
 version = "0.1.0"
-edition = "2021"
+edition = "2022"
 
 # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
 
diff --git a/protocol/Cargo.toml b/protocol/Cargo.toml
index 77c8260..8000b3c 100644
--- a/protocol/Cargo.toml
+++ b/protocol/Cargo.toml
@@ -1,7 +1,7 @@
 [package]
 name = "protocol"
 version = "0.1.0"
-edition = "2021"
+edition = "2022"
 
 # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
 
diff --git a/registry/Cargo.toml b/registry/Cargo.toml
index 89c58fc..4e56c99 100644
--- a/registry/Cargo.toml
+++ b/registry/Cargo.toml
@@ -1,7 +1,7 @@
 [package]
 name = "registry"
 version = "0.1.0"
-edition = "2021"
+edition = "2022"
 
 # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
 
diff --git a/xds/Cargo.toml b/xds/Cargo.toml
index 75e2515..3b89e37 100644
--- a/xds/Cargo.toml
+++ b/xds/Cargo.toml
@@ -1,7 +1,7 @@
 [package]
 name = "xds"
 version = "0.1.0"
-edition = "2021"
+edition = "2022"
 
 # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
 


[dubbo-rust] 29/38: build(deps): bump prost-types from 0.6.1 to 0.8.0 in /dubbo

Posted by li...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

liujun pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/dubbo-rust.git

commit 0096d1660e135651cb670b263cc39adcf425ff50
Author: dependabot[bot] <49...@users.noreply.github.com>
AuthorDate: Wed Jul 6 09:41:04 2022 +0000

    build(deps): bump prost-types from 0.6.1 to 0.8.0 in /dubbo
    
    Bumps [prost-types](https://github.com/tokio-rs/prost) from 0.6.1 to 0.8.0.
    - [Release notes](https://github.com/tokio-rs/prost/releases)
    - [Commits](https://github.com/tokio-rs/prost/compare/v0.6.1...v0.8.0)
    
    ---
    updated-dependencies:
    - dependency-name: prost-types
      dependency-type: direct:production
    ...
    
    Signed-off-by: dependabot[bot] <su...@github.com>
---
 dubbo/Cargo.lock | 61 +++++++++++++++++++++-----------------------------------
 dubbo/Cargo.toml |  2 +-
 2 files changed, 24 insertions(+), 39 deletions(-)

diff --git a/dubbo/Cargo.lock b/dubbo/Cargo.lock
index a69c71b..5c4a6d9 100644
--- a/dubbo/Cargo.lock
+++ b/dubbo/Cargo.lock
@@ -61,7 +61,7 @@ dependencies = [
  "async-trait",
  "axum-core",
  "bitflags",
- "bytes 1.1.0",
+ "bytes",
  "futures-util",
  "http",
  "http-body",
@@ -88,7 +88,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "c2efed1c501becea07ce48118786ebcf229531d0d3b28edf224a720020d9e106"
 dependencies = [
  "async-trait",
- "bytes 1.1.0",
+ "bytes",
  "futures-util",
  "http",
  "http-body",
@@ -107,12 +107,6 @@ version = "1.3.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
 
-[[package]]
-name = "bytes"
-version = "0.5.6"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0e4cec68f03f32e44924783795810fa50a7035d8c8ebe78580ad7e6c703fba38"
-
 [[package]]
 name = "bytes"
 version = "1.1.0"
@@ -233,7 +227,7 @@ version = "0.3.13"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "37a82c6d637fc9515a4694bbf1cb2457b79d81ce52b3108bdeea58b07dd34a57"
 dependencies = [
- "bytes 1.1.0",
+ "bytes",
  "fnv",
  "futures-core",
  "futures-sink",
@@ -267,7 +261,7 @@ version = "0.2.8"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "75f43d41e26995c17e71ee126451dd3941010b0514a81a9d11f3b341debc2399"
 dependencies = [
- "bytes 1.1.0",
+ "bytes",
  "fnv",
  "itoa",
 ]
@@ -278,7 +272,7 @@ version = "0.4.5"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "d5f38f16d184e36f2408a55281cd658ecbd3ca05cce6d6510a176eca393e26d1"
 dependencies = [
- "bytes 1.1.0",
+ "bytes",
  "http",
  "pin-project-lite",
 ]
@@ -307,7 +301,7 @@ version = "0.14.19"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "42dc3c131584288d375f2d07f822b0cb012d8c6fb899a5b9fdb3cb7eb9b6004f"
 dependencies = [
- "bytes 1.1.0",
+ "bytes",
  "futures-channel",
  "futures-core",
  "futures-util",
@@ -347,15 +341,6 @@ dependencies = [
  "hashbrown",
 ]
 
-[[package]]
-name = "itertools"
-version = "0.8.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f56a2d0bc861f9165be4eb3442afd3c236d8a98afd426f65d92324ae1091a484"
-dependencies = [
- "either",
-]
-
 [[package]]
 name = "itertools"
 version = "0.10.3"
@@ -502,12 +487,12 @@ dependencies = [
 
 [[package]]
 name = "prost"
-version = "0.6.1"
+version = "0.8.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ce49aefe0a6144a45de32927c77bd2859a5f7677b55f220ae5b744e87389c212"
+checksum = "de5e2533f59d08fcf364fd374ebda0692a70bd6d7e66ef97f306f45c6c5d8020"
 dependencies = [
- "bytes 0.5.6",
- "prost-derive 0.6.1",
+ "bytes",
+ "prost-derive 0.8.0",
 ]
 
 [[package]]
@@ -516,18 +501,18 @@ version = "0.10.4"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "71adf41db68aa0daaefc69bb30bcd68ded9b9abaad5d1fbb6304c4fb390e083e"
 dependencies = [
- "bytes 1.1.0",
+ "bytes",
  "prost-derive 0.10.1",
 ]
 
 [[package]]
 name = "prost-derive"
-version = "0.6.1"
+version = "0.8.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "537aa19b95acde10a12fec4301466386f757403de4cd4e5b4fa78fb5ecb18f72"
+checksum = "600d2f334aa05acb02a755e217ef1ab6dea4d51b58b7846588b747edec04efba"
 dependencies = [
  "anyhow",
- "itertools 0.8.2",
+ "itertools",
  "proc-macro2",
  "quote",
  "syn",
@@ -540,7 +525,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "7b670f45da57fb8542ebdbb6105a925fe571b67f9e7ed9f47a06a84e72b4e7cc"
 dependencies = [
  "anyhow",
- "itertools 0.10.3",
+ "itertools",
  "proc-macro2",
  "quote",
  "syn",
@@ -548,12 +533,12 @@ dependencies = [
 
 [[package]]
 name = "prost-types"
-version = "0.6.1"
+version = "0.8.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1834f67c0697c001304b75be76f67add9c89742eda3a085ad8ee0bb38c3417aa"
+checksum = "603bbd6394701d13f3f25aada59c7de9d35a6a5887cfc156181234a44002771b"
 dependencies = [
- "bytes 0.5.6",
- "prost 0.6.1",
+ "bytes",
+ "prost 0.8.0",
 ]
 
 [[package]]
@@ -649,7 +634,7 @@ version = "1.19.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "c51a52ed6686dd62c320f9b89299e9dfb46f730c7a48e635c19f21d116cb1439"
 dependencies = [
- "bytes 1.1.0",
+ "bytes",
  "libc",
  "memchr",
  "mio",
@@ -700,7 +685,7 @@ version = "0.7.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "cc463cd8deddc3770d20f9852143d50bf6094e640b485cb2e189a2099085ff45"
 dependencies = [
- "bytes 1.1.0",
+ "bytes",
  "futures-core",
  "futures-sink",
  "pin-project-lite",
@@ -718,7 +703,7 @@ dependencies = [
  "async-trait",
  "axum",
  "base64",
- "bytes 1.1.0",
+ "bytes",
  "flate2",
  "futures-core",
  "futures-util",
@@ -768,7 +753,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "3c530c8675c1dbf98facee631536fa116b5fb6382d7dd6dc1b118d970eafe3ba"
 dependencies = [
  "bitflags",
- "bytes 1.1.0",
+ "bytes",
  "futures-core",
  "futures-util",
  "http",
diff --git a/dubbo/Cargo.toml b/dubbo/Cargo.toml
index 7ce6865..a132d76 100644
--- a/dubbo/Cargo.toml
+++ b/dubbo/Cargo.toml
@@ -21,7 +21,7 @@ futures-util = {version = "0.3", default-features = false}
 tokio = { version = "1.0", features = [ "rt-multi-thread", "time", "fs", "macros", "net", "signal"] }
 prost-derive = {version = "0.10", optional = true}
 prost = "0.10.4"
-prost-types = { version = "0.6", default-features = false }
+prost-types = { version = "0.8", default-features = false }
 lazy_static = "1.3.0"
 async-trait = "0.1.56"
 tower-layer = "0.3"


[dubbo-rust] 35/38: style: add license header

Posted by li...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

liujun pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/dubbo-rust.git

commit 891b189e56deabb413962367c3eb5e2b22d0a5d2
Author: yangyang <96...@qq.com>
AuthorDate: Thu Jul 21 21:47:51 2022 +0800

    style: add license header
---
 dubbo/src/echo/helloworld.rs                 |   7 +-
 dubbo/src/init.rs                            | 110 ---------------------------
 dubbo/src/protocol/triple/mod.rs             |  17 +++++
 dubbo/src/protocol/triple/triple_exporter.rs |  17 +++++
 dubbo/src/protocol/triple/triple_invoker.rs  |  17 +++++
 dubbo/src/protocol/triple/triple_protocol.rs |  17 +++++
 dubbo/src/protocol/triple/triple_server.rs   |  17 +++++
 triple/src/codec/prost.rs                    |  17 +++++
 8 files changed, 103 insertions(+), 116 deletions(-)

diff --git a/dubbo/src/echo/helloworld.rs b/dubbo/src/echo/helloworld.rs
index 9497f4b..039ac43 100644
--- a/dubbo/src/echo/helloworld.rs
+++ b/dubbo/src/echo/helloworld.rs
@@ -15,11 +15,6 @@
  * limitations under the License.
  */
 
-
-
-
-
-
 /// The request message containing the user's name.
 #[derive(Clone, PartialEq, ::prost::Message)]
 pub struct HelloRequest {
@@ -38,7 +33,7 @@ pub mod greeter_client {
     use triple::client::TripleClient;
     use triple::codec::prost::ProstCodec;
     use triple::invocation::*;
-    
+
     /// The greeting service definition.
     #[derive(Debug, Clone)]
     pub struct GreeterClient {
diff --git a/dubbo/src/init.rs b/dubbo/src/init.rs
deleted file mode 100644
index e0d738c..0000000
--- a/dubbo/src/init.rs
+++ /dev/null
@@ -1,110 +0,0 @@
-// /// Server 启动的入口。业务侧需要调用该函数进行初始化
-// ///
-// use std::collections::HashMap;
-
-// use crate::common::url::Url;
-// use config::{BusinessConfig, RootConfig};
-
-// pub fn init() {
-//     let _root_config = RootConfig::new().load();
-//     let service_config = ServiceConfig::default()
-//         .group("helloworld".to_string())
-//         .serializer("json".to_string())
-//         .version("1.0".to_string())
-//         .name("echo".to_string());
-
-//     let triple_config = ProtocolConfig::default()
-//         .name("triple".to_string())
-//         .ip("0.0.0.0".to_string())
-//         .port("8888".to_string());
-
-//     let _service_config = service_config.add_protocol_configs(triple_config);
-//     // 根据不同的协议,加载不同的配置
-//     // 初始化全局的services
-//     // let server = DubboServer::init();
-//     // let server = server.add_service("echo".to_string(), service);
-// }
-
-// #[derive(Default)]
-// pub struct ServiceConfig {
-//     version: String,
-//     group: String,
-//     name: String,
-//     protocol_names: Vec<String>,
-//     registry_names: Vec<String>,
-//     serializer: String,
-//     protocol_configs: HashMap<String, ProtocolConfig>,
-// }
-
-// impl ServiceConfig {
-//     pub fn name(self, name: String) -> Self {
-//         Self { name, ..self }
-//     }
-
-//     pub fn version(self, version: String) -> Self {
-//         Self { version, ..self }
-//     }
-
-//     pub fn group(self, group: String) -> Self {
-//         Self { group, ..self }
-//     }
-
-//     pub fn protocol_names(self, protocol_names: Vec<String>) -> Self {
-//         Self {
-//             protocol_names,
-//             ..self
-//         }
-//     }
-
-//     pub fn serializer(self, serializer: String) -> Self {
-//         Self { serializer, ..self }
-//     }
-
-//     pub fn add_protocol_configs(mut self, protocol_config: ProtocolConfig) -> Self {
-//         self.protocol_configs
-//             .insert(protocol_config.name.clone(), protocol_config);
-//         Self { ..self }
-//     }
-
-//     pub fn get_url(&self) -> Vec<Url> {
-//         let mut urls = Vec::new();
-//         for (_, conf) in self.protocol_configs.iter() {
-//             urls.push(Url {
-//                 url: conf.to_owned().to_url(),
-//                 service_key: "".to_string(),
-//             });
-//         }
-
-//         urls
-//     }
-// }
-
-// #[derive(Default, Debug, Clone)]
-// pub struct ProtocolConfig {
-//     ip: String,
-//     port: String,
-//     name: String,
-//     params: HashMap<String, String>,
-// }
-
-// impl ProtocolConfig {
-//     pub fn name(self, name: String) -> Self {
-//         Self { name, ..self }
-//     }
-
-//     pub fn ip(self, ip: String) -> Self {
-//         Self { ip, ..self }
-//     }
-
-//     pub fn port(self, port: String) -> Self {
-//         Self { port, ..self }
-//     }
-
-//     pub fn params(self, params: HashMap<String, String>) -> Self {
-//         Self { params, ..self }
-//     }
-
-//     pub fn to_url(self) -> String {
-//         format!("{}://{}:{}", self.name, self.ip, self.port).to_string()
-//     }
-// }
diff --git a/dubbo/src/protocol/triple/mod.rs b/dubbo/src/protocol/triple/mod.rs
index 32728c3..0e84907 100644
--- a/dubbo/src/protocol/triple/mod.rs
+++ b/dubbo/src/protocol/triple/mod.rs
@@ -1,3 +1,20 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.
+ */
+
 pub mod triple_exporter;
 pub mod triple_invoker;
 pub mod triple_protocol;
diff --git a/dubbo/src/protocol/triple/triple_exporter.rs b/dubbo/src/protocol/triple/triple_exporter.rs
index fcddf79..48ceab3 100644
--- a/dubbo/src/protocol/triple/triple_exporter.rs
+++ b/dubbo/src/protocol/triple/triple_exporter.rs
@@ -1,3 +1,20 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.
+ */
+
 use super::triple_invoker::TripleInvoker;
 use crate::protocol::Exporter;
 
diff --git a/dubbo/src/protocol/triple/triple_invoker.rs b/dubbo/src/protocol/triple/triple_invoker.rs
index 9f064ab..a7d0587 100644
--- a/dubbo/src/protocol/triple/triple_invoker.rs
+++ b/dubbo/src/protocol/triple/triple_invoker.rs
@@ -1,3 +1,20 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.
+ */
+
 use crate::common::url::Url;
 use crate::protocol::Invoker;
 
diff --git a/dubbo/src/protocol/triple/triple_protocol.rs b/dubbo/src/protocol/triple/triple_protocol.rs
index e3abb48..ba517bb 100644
--- a/dubbo/src/protocol/triple/triple_protocol.rs
+++ b/dubbo/src/protocol/triple/triple_protocol.rs
@@ -1,3 +1,20 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.
+ */
+
 use std::collections::HashMap;
 
 use async_trait::async_trait;
diff --git a/dubbo/src/protocol/triple/triple_server.rs b/dubbo/src/protocol/triple/triple_server.rs
index b596bb9..e49694b 100644
--- a/dubbo/src/protocol/triple/triple_server.rs
+++ b/dubbo/src/protocol/triple/triple_server.rs
@@ -1,3 +1,20 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.
+ */
+
 use std::{net::ToSocketAddrs, str::FromStr};
 
 use triple::transport::DubboServer;
diff --git a/triple/src/codec/prost.rs b/triple/src/codec/prost.rs
index 162ac51..fb52e39 100644
--- a/triple/src/codec/prost.rs
+++ b/triple/src/codec/prost.rs
@@ -1,3 +1,20 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.
+ */
+
 use super::{Codec, DecodeBuf, Decoder, EncodeBuf, Encoder};
 use prost::Message;
 use std::marker::PhantomData;


[dubbo-rust] 19/38: Fix: add license header for file.

Posted by li...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

liujun pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/dubbo-rust.git

commit fbd62f376de39f1744b1ad9473c5026eaef8b99e
Author: Zonglei Dong <do...@apache.org>
AuthorDate: Sat May 14 15:39:53 2022 +0800

    Fix: add license header for file.
---
 common/src/lib.rs        | 17 +++++++++++++++++
 config/src/lib.rs        | 17 +++++++++++++++++
 metadata/src/lib.rs      | 17 +++++++++++++++++
 protocol/src/lib.rs      | 17 +++++++++++++++++
 registry/src/lib.rs      | 17 +++++++++++++++++
 xds/src/client/client.rs | 16 ++++++++++++++++
 xds/src/client/mod.rs    | 16 ++++++++++++++++
 xds/src/lib.rs           | 17 +++++++++++++++++
 xds/src/server/mod.rs    | 16 ++++++++++++++++
 xds/src/server/server.rs | 16 ++++++++++++++++
 10 files changed, 166 insertions(+)

diff --git a/common/src/lib.rs b/common/src/lib.rs
index 1b4a90c..3e01853 100644
--- a/common/src/lib.rs
+++ b/common/src/lib.rs
@@ -1,3 +1,20 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.
+ */
+
 #[cfg(test)]
 mod tests {
     #[test]
diff --git a/config/src/lib.rs b/config/src/lib.rs
index 1b4a90c..3e01853 100644
--- a/config/src/lib.rs
+++ b/config/src/lib.rs
@@ -1,3 +1,20 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.
+ */
+
 #[cfg(test)]
 mod tests {
     #[test]
diff --git a/metadata/src/lib.rs b/metadata/src/lib.rs
index 1b4a90c..3e01853 100644
--- a/metadata/src/lib.rs
+++ b/metadata/src/lib.rs
@@ -1,3 +1,20 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.
+ */
+
 #[cfg(test)]
 mod tests {
     #[test]
diff --git a/protocol/src/lib.rs b/protocol/src/lib.rs
index 1b4a90c..3e01853 100644
--- a/protocol/src/lib.rs
+++ b/protocol/src/lib.rs
@@ -1,3 +1,20 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.
+ */
+
 #[cfg(test)]
 mod tests {
     #[test]
diff --git a/registry/src/lib.rs b/registry/src/lib.rs
index 1b4a90c..3e01853 100644
--- a/registry/src/lib.rs
+++ b/registry/src/lib.rs
@@ -1,3 +1,20 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.
+ */
+
 #[cfg(test)]
 mod tests {
     #[test]
diff --git a/xds/src/client/client.rs b/xds/src/client/client.rs
index e69de29..2944f98 100644
--- a/xds/src/client/client.rs
+++ b/xds/src/client/client.rs
@@ -0,0 +1,16 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.
+ */
diff --git a/xds/src/client/mod.rs b/xds/src/client/mod.rs
index e69de29..2944f98 100644
--- a/xds/src/client/mod.rs
+++ b/xds/src/client/mod.rs
@@ -0,0 +1,16 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.
+ */
diff --git a/xds/src/lib.rs b/xds/src/lib.rs
index 1b4a90c..3e01853 100644
--- a/xds/src/lib.rs
+++ b/xds/src/lib.rs
@@ -1,3 +1,20 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.
+ */
+
 #[cfg(test)]
 mod tests {
     #[test]
diff --git a/xds/src/server/mod.rs b/xds/src/server/mod.rs
index e69de29..2944f98 100644
--- a/xds/src/server/mod.rs
+++ b/xds/src/server/mod.rs
@@ -0,0 +1,16 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.
+ */
diff --git a/xds/src/server/server.rs b/xds/src/server/server.rs
index e69de29..2944f98 100644
--- a/xds/src/server/server.rs
+++ b/xds/src/server/server.rs
@@ -0,0 +1,16 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.
+ */


[dubbo-rust] 09/38: Create CI.yml

Posted by li...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

liujun pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/dubbo-rust.git

commit 949b5f53af57349c927c709f897821fe8397baf4
Author: Johankoi <Jo...@163.com>
AuthorDate: Wed Apr 27 00:26:16 2022 +0800

    Create CI.yml
    
    add workflow
---
 .github/workflows/CI.yml | 56 ++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 56 insertions(+)

diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml
new file mode 100644
index 0000000..993dbd7
--- /dev/null
+++ b/.github/workflows/CI.yml
@@ -0,0 +1,56 @@
+# This is a basic workflow to help you get started with Actions
+
+name: CI
+
+on:
+  push:
+    branches: [ main ]
+  pull_request:
+    branches: [ main ]
+
+  workflow_dispatch:
+
+jobs:
+ check:
+    name: check dubbo-rus project
+    runs-on: ${{ matrix.os }}
+    strategy:
+      matrix:
+        os: [ubuntu-latest, macOS-latest, windows-latest]
+        rust: [stable]
+
+    env:
+      RUSTFLAGS: "-D warnings"
+      
+    steps:
+    - uses: actions/checkout@main
+    - uses: actions-rs/toolchain@v1
+      with:
+          toolchain: ${{ matrix.rust }}
+    - run: cargo che
+    
+ fmt:
+    name: Rustfmt
+    runs-on: ${{ matrix.os }}
+    strategy:
+      matrix:
+        os: [ubuntu-latest, macOS-latest, windows-latest]
+        rust: [stable]
+        
+    steps:
+      - uses: actions/checkout@main
+      - uses: actions-rs/toolchain@v1
+        with:
+          profile: minimal
+          toolchain: stable
+          override: true
+      - run: rustup component add rustfmt
+      - run: cargo fmt --all -- --check
+      
+  
+
+    
+
+
+   
+   


[dubbo-rust] 22/38: docs: generic protocol design RFC

Posted by li...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

liujun pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/dubbo-rust.git

commit 8ec9b6f0dc8eb4c9dcbf6dff99bb90487898c30e
Author: yang <96...@qq.com>
AuthorDate: Sun Jun 26 22:53:07 2022 +0800

    docs: generic protocol design RFC
---
 docs/filter-design.md           |  0
 docs/generic-protocol-design.md | 35 +++++++++++++++++++++++++++++++++++
 docs/readme.md                  |  3 +++
 3 files changed, 38 insertions(+)

diff --git a/docs/filter-design.md b/docs/filter-design.md
new file mode 100644
index 0000000..e69de29
diff --git a/docs/generic-protocol-design.md b/docs/generic-protocol-design.md
new file mode 100644
index 0000000..d91ed85
--- /dev/null
+++ b/docs/generic-protocol-design.md
@@ -0,0 +1,35 @@
+author: Yang Yang
+date: 2022-06-26
+
+## 简介
+
+dubbo-rust支持多种协议:Triple、gRPC、jsonRPC等
+
+## Protocol设计
+
+Protocol的核心设计是基于dubbo的URL模型,对外暴露通用的服务端和客户端抽象接口。
+
+在Dubbo的整体生态中,服务端接口使用`Exporter`来描述;客户端接口使用`Invoker`来描述。
+
+Protocol模块的核心功能:
++ 对外提供服务注册接口
++ 管理注册的服务:run, destroy, stop, gracefulStop
++ 接口路由
++ 通用、高效的Listener层
++ 等等
+
+### Exporter
+
+### Invoker
+
+Invoker提供的通用的接口,使得dubbo在不同的协议下遵循相同的接口抽象。
+
+在Invoker中,需要做的功能包括
++ 编解码层
++ Streaming trait实现
++ 自定义请求/响应
++ 等等
+
+## 目前存在的问题
+
++ 如何管理服务:服务是动态的,需要保证Server是Send+Sync的
\ No newline at end of file
diff --git a/docs/readme.md b/docs/readme.md
new file mode 100644
index 0000000..ee2738f
--- /dev/null
+++ b/docs/readme.md
@@ -0,0 +1,3 @@
+# Readme
+
+There is some RFCs of dubbo-rust design.
\ No newline at end of file


[dubbo-rust] 20/38: Merge pull request #10 from dongzl/license-check

Posted by li...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

liujun pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/dubbo-rust.git

commit 69249f06079b343aecc5549cfc70093c08f0d099
Merge: 2b2eef4 fbd62f3
Author: ken.lj <ke...@gmail.com>
AuthorDate: Thu May 26 10:28:43 2022 +0800

    Merge pull request #10 from dongzl/license-check
    
    add license check github action.

 .asf.yaml                                        |  2 -
 .github/workflows/{CI.yml => github-actions.yml} |  0
 .github/workflows/licence-checker.yml            | 45 +++++++++++++++
 .licenserc.yaml                                  | 72 ++++++++++++++++++++++++
 common/src/lib.rs                                | 17 ++++++
 config/src/lib.rs                                | 17 ++++++
 metadata/src/lib.rs                              | 17 ++++++
 protocol/src/lib.rs                              | 17 ++++++
 registry/src/lib.rs                              | 17 ++++++
 xds/src/client/client.rs                         | 16 ++++++
 xds/src/client/mod.rs                            | 16 ++++++
 xds/src/lib.rs                                   | 17 ++++++
 xds/src/server/mod.rs                            | 16 ++++++
 xds/src/server/server.rs                         | 16 ++++++
 14 files changed, 283 insertions(+), 2 deletions(-)


[dubbo-rust] 14/38: Fix: add new git ignore content.

Posted by li...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

liujun pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/dubbo-rust.git

commit 291a41b970a84a8a410b031d199bc7b271c3ced1
Author: Zonglei Dong <do...@apache.org>
AuthorDate: Fri May 6 15:25:39 2022 +0800

    Fix: add new git ignore content.
---
 .gitignore | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/.gitignore b/.gitignore
index 4fffb2f..386dbf6 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,2 +1,5 @@
 /target
 /Cargo.lock
+**/*.rs.bk
+.vscode/
+.idea/


[dubbo-rust] 25/38: style(dubbo): add license header

Posted by li...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

liujun pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/dubbo-rust.git

commit f72e75b3b635b023901ac63426e7d7c24ffefa7b
Author: yang <96...@qq.com>
AuthorDate: Mon Jun 27 21:48:32 2022 +0800

    style(dubbo): add license header
---
 dubbo/src/common/mod.rs                 | 17 +++++++++++++++++
 dubbo/src/common/url.rs                 | 17 +++++++++++++++++
 dubbo/src/helloworld/client.rs          | 17 +++++++++++++++++
 dubbo/src/helloworld/helloworld.rs      | 17 +++++++++++++++++
 dubbo/src/helloworld/mod.rs             | 17 +++++++++++++++++
 dubbo/src/helloworld/server.rs          | 16 ++++++++++++++++
 dubbo/src/lib.rs                        | 17 +++++++++++++++++
 dubbo/src/main.rs                       | 17 +++++++++++++++++
 dubbo/src/service/grpc/grpc_exporter.rs | 17 +++++++++++++++++
 dubbo/src/service/grpc/grpc_invoker.rs  | 17 +++++++++++++++++
 dubbo/src/service/grpc/grpc_protocol.rs | 17 +++++++++++++++++
 dubbo/src/service/grpc/grpc_server.rs   | 17 +++++++++++++++++
 dubbo/src/service/grpc/mod.rs           | 17 +++++++++++++++++
 dubbo/src/service/invocation.rs         | 17 +++++++++++++++++
 dubbo/src/service/mod.rs                | 17 +++++++++++++++++
 dubbo/src/service/protocol.rs           | 17 +++++++++++++++++
 dubbo/src/utils/boxed.rs                | 17 +++++++++++++++++
 dubbo/src/utils/boxed_clone.rs          | 17 +++++++++++++++++
 dubbo/src/utils/mod.rs                  | 17 +++++++++++++++++
 19 files changed, 322 insertions(+)

diff --git a/dubbo/src/common/mod.rs b/dubbo/src/common/mod.rs
index 591151d..0bfd0ed 100644
--- a/dubbo/src/common/mod.rs
+++ b/dubbo/src/common/mod.rs
@@ -1 +1,18 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.
+ */
+
 pub mod url;
diff --git a/dubbo/src/common/url.rs b/dubbo/src/common/url.rs
index 6d4958d..e610de3 100644
--- a/dubbo/src/common/url.rs
+++ b/dubbo/src/common/url.rs
@@ -1,3 +1,20 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.
+ */
+
 #[derive(Debug, Clone)]
 pub struct Url {
     pub url: String,
diff --git a/dubbo/src/helloworld/client.rs b/dubbo/src/helloworld/client.rs
index 591e382..5fd571d 100644
--- a/dubbo/src/helloworld/client.rs
+++ b/dubbo/src/helloworld/client.rs
@@ -1,3 +1,20 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.
+ */
+
 use dubbo::helloworld::helloworld::greeter_client::GreeterClient;
 use dubbo::helloworld::helloworld::HelloRequest;
 
diff --git a/dubbo/src/helloworld/helloworld.rs b/dubbo/src/helloworld/helloworld.rs
index 41eb5d9..2b2ef39 100644
--- a/dubbo/src/helloworld/helloworld.rs
+++ b/dubbo/src/helloworld/helloworld.rs
@@ -1,3 +1,20 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 request message containing the user's name.
 #[derive(Clone, PartialEq, ::prost::Message)]
 pub struct HelloRequest {
diff --git a/dubbo/src/helloworld/mod.rs b/dubbo/src/helloworld/mod.rs
index b1358dd..35bbf94 100644
--- a/dubbo/src/helloworld/mod.rs
+++ b/dubbo/src/helloworld/mod.rs
@@ -1 +1,18 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.
+ */
+
 pub mod helloworld;
diff --git a/dubbo/src/helloworld/server.rs b/dubbo/src/helloworld/server.rs
index e69de29..2944f98 100644
--- a/dubbo/src/helloworld/server.rs
+++ b/dubbo/src/helloworld/server.rs
@@ -0,0 +1,16 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.
+ */
diff --git a/dubbo/src/lib.rs b/dubbo/src/lib.rs
index 0e5bedf..f7cfaef 100644
--- a/dubbo/src/lib.rs
+++ b/dubbo/src/lib.rs
@@ -1,3 +1,20 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.
+ */
+
 pub mod common;
 pub mod helloworld;
 pub mod service;
diff --git a/dubbo/src/main.rs b/dubbo/src/main.rs
index 4bb2acf..0dd0e47 100644
--- a/dubbo/src/main.rs
+++ b/dubbo/src/main.rs
@@ -1,3 +1,20 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.
+ */
+
 pub mod common;
 pub mod helloworld;
 pub mod service;
diff --git a/dubbo/src/service/grpc/grpc_exporter.rs b/dubbo/src/service/grpc/grpc_exporter.rs
index 7671b6d..591064a 100644
--- a/dubbo/src/service/grpc/grpc_exporter.rs
+++ b/dubbo/src/service/grpc/grpc_exporter.rs
@@ -1,3 +1,20 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.
+ */
+
 use crate::service::protocol::Invoker;
 use crate::service::protocol::*;
 
diff --git a/dubbo/src/service/grpc/grpc_invoker.rs b/dubbo/src/service/grpc/grpc_invoker.rs
index 3fbd442..402e75a 100644
--- a/dubbo/src/service/grpc/grpc_invoker.rs
+++ b/dubbo/src/service/grpc/grpc_invoker.rs
@@ -1,3 +1,20 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.
+ */
+
 use std::sync::Once;
 
 use tonic::client::Grpc;
diff --git a/dubbo/src/service/grpc/grpc_protocol.rs b/dubbo/src/service/grpc/grpc_protocol.rs
index 8fe1aa8..4762abc 100644
--- a/dubbo/src/service/grpc/grpc_protocol.rs
+++ b/dubbo/src/service/grpc/grpc_protocol.rs
@@ -1,3 +1,20 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.
+ */
+
 use std::collections::HashMap;
 
 use super::grpc_exporter::GrpcExporter;
diff --git a/dubbo/src/service/grpc/grpc_server.rs b/dubbo/src/service/grpc/grpc_server.rs
index 9d2656e..3cc5294 100644
--- a/dubbo/src/service/grpc/grpc_server.rs
+++ b/dubbo/src/service/grpc/grpc_server.rs
@@ -1,3 +1,20 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.
+ */
+
 use std::collections::HashMap;
 use std::task::Context;
 use std::task::Poll;
diff --git a/dubbo/src/service/grpc/mod.rs b/dubbo/src/service/grpc/mod.rs
index 7c70105..91ee2c0 100644
--- a/dubbo/src/service/grpc/mod.rs
+++ b/dubbo/src/service/grpc/mod.rs
@@ -1,3 +1,20 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.
+ */
+
 pub mod grpc_exporter;
 pub mod grpc_invoker;
 pub mod grpc_protocol;
diff --git a/dubbo/src/service/invocation.rs b/dubbo/src/service/invocation.rs
index 690a345..a0686b2 100644
--- a/dubbo/src/service/invocation.rs
+++ b/dubbo/src/service/invocation.rs
@@ -1,3 +1,20 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.
+ */
+
 use tonic::metadata::MetadataMap;
 
 pub struct Request<T> {
diff --git a/dubbo/src/service/mod.rs b/dubbo/src/service/mod.rs
index 49d23a4..753f567 100644
--- a/dubbo/src/service/mod.rs
+++ b/dubbo/src/service/mod.rs
@@ -1,3 +1,20 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.
+ */
+
 pub mod grpc;
 pub mod invocation;
 pub mod protocol;
diff --git a/dubbo/src/service/protocol.rs b/dubbo/src/service/protocol.rs
index 3f42284..bec2b7f 100644
--- a/dubbo/src/service/protocol.rs
+++ b/dubbo/src/service/protocol.rs
@@ -1,3 +1,20 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.
+ */
+
 use super::invocation;
 use crate::common::url::Url;
 
diff --git a/dubbo/src/utils/boxed.rs b/dubbo/src/utils/boxed.rs
index e820031..326dea6 100644
--- a/dubbo/src/utils/boxed.rs
+++ b/dubbo/src/utils/boxed.rs
@@ -1,3 +1,20 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.
+ */
+
 use tower::ServiceExt;
 use tower_layer::{layer_fn, LayerFn};
 use tower_service::Service;
diff --git a/dubbo/src/utils/boxed_clone.rs b/dubbo/src/utils/boxed_clone.rs
index dde8ec6..a4aa5ba 100644
--- a/dubbo/src/utils/boxed_clone.rs
+++ b/dubbo/src/utils/boxed_clone.rs
@@ -1,3 +1,20 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.
+ */
+
 use futures_util::future::BoxFuture;
 use std::{
     fmt,
diff --git a/dubbo/src/utils/mod.rs b/dubbo/src/utils/mod.rs
index bd5e148..f088d72 100644
--- a/dubbo/src/utils/mod.rs
+++ b/dubbo/src/utils/mod.rs
@@ -1,2 +1,19 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.
+ */
+
 pub mod boxed;
 pub mod boxed_clone;


[dubbo-rust] 38/38: Merge pull request #21 from yang20150702/main

Posted by li...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

liujun pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/dubbo-rust.git

commit fd2958a448e9ff2ef96fd69b53138b9c38f8a43b
Merge: e71b961 3f8a62a
Author: ken.lj <ke...@gmail.com>
AuthorDate: Sat Jul 23 22:43:57 2022 +0800

    Merge pull request #21 from yang20150702/main
    
    feat: impl of Triple protocol

 .gitignore                                         |   4 +-
 Cargo.toml                                         |   3 +-
 config/src/config.rs                               | 107 +++
 config/src/lib.rs                                  |   6 +
 config/src/{lib.rs => protocol.rs}                 |  35 +-
 config/src/service.rs                              |  74 ++
 dubbo/Cargo.lock                                   | 914 ---------------------
 dubbo/Cargo.toml                                   |  11 +-
 dubbo/src/common/url.rs                            |   2 +-
 dubbo/src/echo/echo_client.rs                      |  73 ++
 dubbo/src/echo/echo_server.rs                      | 220 +++++
 dubbo/src/echo/helloworld.rs                       | 291 +++++++
 dubbo/src/echo/mod.rs                              | 264 ++++++
 dubbo/src/lib.rs                                   |   7 +
 dubbo/src/main.rs                                  |   9 +
 dubbo/src/protocol/grpc/grpc_protocol.rs           |   2 +-
 dubbo/src/protocol/grpc/grpc_server.rs             |   2 +-
 dubbo/src/protocol/invocation.rs                   |  44 +
 dubbo/src/protocol/mod.rs                          |  11 +-
 dubbo/src/{main.rs => protocol/triple/mod.rs}      |  26 +-
 .../src/protocol/triple/triple_exporter.rs         |  33 +-
 .../src/protocol/triple/triple_invoker.rs          |  42 +-
 dubbo/src/protocol/triple/triple_protocol.rs       |  71 ++
 dubbo/src/protocol/triple/triple_server.rs         |  61 ++
 {dubbo => triple}/Cargo.toml                       |  20 +-
 triple/readme.md                                   |  15 +
 triple/src/client/grpc.rs                          | 205 +++++
 dubbo/src/lib.rs => triple/src/client/mod.rs       |   7 +-
 triple/src/codec/buffer.rs                         | 138 ++++
 triple/src/codec/mod.rs                            |  72 ++
 triple/src/codec/prost.rs                          | 253 ++++++
 triple/src/codec/serde_codec.rs                    |  89 ++
 triple/src/invocation.rs                           | 148 ++++
 dubbo/src/main.rs => triple/src/lib.rs             |  22 +-
 {dubbo => triple}/src/main.rs                      |  24 +-
 dubbo/src/main.rs => triple/src/server/consts.rs   |  16 +-
 triple/src/server/decode.rs                        | 165 ++++
 triple/src/server/encode.rs                        | 168 ++++
 dubbo/src/main.rs => triple/src/server/mod.rs      |  15 +-
 triple/src/server/server.rs                        | 112 +++
 triple/src/server/service.rs                       |  68 ++
 dubbo/src/lib.rs => triple/src/transport/mod.rs    |   7 +-
 triple/src/transport/service.rs                    | 183 +++++
 43 files changed, 3046 insertions(+), 993 deletions(-)


[dubbo-rust] 36/38: Merge branch 'apache:main' into main

Posted by li...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

liujun pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/dubbo-rust.git

commit 5c0ff914bb3c7c8c8f9040b04cfedc8bdc897556
Merge: 891b189 e71b961
Author: yang <96...@qq.com>
AuthorDate: Thu Jul 21 21:51:31 2022 +0800

    Merge branch 'apache:main' into main

 .github/workflows/licence-checker.yml |  4 +--
 dubbo/Cargo.lock                      | 61 +++++++++++++----------------------
 dubbo/Cargo.toml                      |  2 +-
 3 files changed, 25 insertions(+), 42 deletions(-)



[dubbo-rust] 34/38: refactor(triple): add prost codec, start server by config

Posted by li...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

liujun pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/dubbo-rust.git

commit b6e165f1ef744e204f78427132ee5f069f2b9506
Author: yangyang <96...@qq.com>
AuthorDate: Thu Jul 21 21:36:44 2022 +0800

    refactor(triple): add prost codec, start server by config
---
 config/src/config.rs               |  26 +++-
 config/src/lib.rs                  |   2 +
 config/src/{lib.rs => protocol.rs} |  35 ++++-
 config/src/service.rs              |  74 ++++++++++
 dubbo/Cargo.toml                   |   1 +
 dubbo/src/echo/echo_client.rs      |  59 +++-----
 dubbo/src/echo/echo_server.rs      |  68 ++++++---
 dubbo/src/echo/helloworld.rs       | 296 +++++++++++++++++++++++++++++++++++++
 dubbo/src/echo/mod.rs              |  94 +++++++++---
 dubbo/src/lib.rs                   |   8 +-
 dubbo/src/main.rs                  |   8 +-
 triple/readme.md                   |  15 ++
 triple/src/client/grpc.rs          | 108 ++++++++++----
 triple/src/codec/mod.rs            |   1 +
 triple/src/codec/prost.rs          | 236 +++++++++++++++++++++++++++++
 triple/src/invocation.rs           |  23 +++
 triple/src/server/encode.rs        |   1 -
 triple/src/server/server.rs        |  68 +++------
 triple/src/transport/service.rs    |  11 +-
 19 files changed, 959 insertions(+), 175 deletions(-)

diff --git a/config/src/config.rs b/config/src/config.rs
index a53dcd2..1adf7d3 100644
--- a/config/src/config.rs
+++ b/config/src/config.rs
@@ -17,28 +17,48 @@
 
 use std::{any, collections::HashMap};
 
+use super::protocol::ProtocolConfig;
+use super::service::ServiceConfig;
+
 /// used to storage all structed config, from some source: cmd, file..;
 /// Impl Config trait, business init by read Config trait
 #[allow(dead_code)]
 #[derive(Debug, Default)]
 pub struct RootConfig {
-    name: String,
-    data: HashMap<String, Box<dyn any::Any>>,
+    pub name: String,
+    pub service: ServiceConfig,
+    pub data: HashMap<String, Box<dyn any::Any>>,
 }
 
 pub fn get_global_config() -> RootConfig {
-    RootConfig::new()
+    let mut c = RootConfig::new();
+    c.load();
+    c
 }
 
 impl RootConfig {
     pub fn new() -> Self {
         Self {
             name: "dubbo".to_string(),
+            service: ServiceConfig::default(),
             data: HashMap::new(),
         }
     }
 
     pub fn load(&mut self) {
+        let service_config = ServiceConfig::default()
+            .group("test".to_string())
+            .serializer("json".to_string())
+            .version("1.0.0".to_string())
+            .name("echo".to_string());
+
+        let triple_config = ProtocolConfig::default()
+            .name("triple".to_string())
+            .ip("0.0.0.0".to_string())
+            .port("8888".to_string());
+
+        let service_config = service_config.add_protocol_configs(triple_config);
+        self.service = service_config;
         // 通过环境变量读取某个文件。加在到内存中
         self.data.insert(
             "dubbo.provider.url".to_string(),
diff --git a/config/src/lib.rs b/config/src/lib.rs
index edbaf58..6237816 100644
--- a/config/src/lib.rs
+++ b/config/src/lib.rs
@@ -16,6 +16,8 @@
  */
 
 pub mod config;
+pub mod protocol;
+pub mod service;
 
 pub use config::*;
 
diff --git a/config/src/lib.rs b/config/src/protocol.rs
similarity index 54%
copy from config/src/lib.rs
copy to config/src/protocol.rs
index edbaf58..d139bed 100644
--- a/config/src/lib.rs
+++ b/config/src/protocol.rs
@@ -15,15 +15,34 @@
  * limitations under the License.
  */
 
-pub mod config;
+use std::collections::HashMap;
 
-pub use config::*;
+#[derive(Default, Debug, Clone)]
+pub struct ProtocolConfig {
+    pub ip: String,
+    pub port: String,
+    pub name: String,
+    pub params: HashMap<String, String>,
+}
+
+impl ProtocolConfig {
+    pub fn name(self, name: String) -> Self {
+        Self { name, ..self }
+    }
+
+    pub fn ip(self, ip: String) -> Self {
+        Self { ip, ..self }
+    }
+
+    pub fn port(self, port: String) -> Self {
+        Self { port, ..self }
+    }
+
+    pub fn params(self, params: HashMap<String, String>) -> Self {
+        Self { params, ..self }
+    }
 
-#[cfg(test)]
-mod tests {
-    #[test]
-    fn it_works() {
-        let result = 2 + 2;
-        assert_eq!(result, 4);
+    pub fn to_url(self) -> String {
+        format!("{}://{}:{}", self.name, self.ip, self.port)
     }
 }
diff --git a/config/src/service.rs b/config/src/service.rs
new file mode 100644
index 0000000..aeda24b
--- /dev/null
+++ b/config/src/service.rs
@@ -0,0 +1,74 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.
+ */
+
+use std::collections::HashMap;
+
+use super::protocol::ProtocolConfig;
+
+#[derive(Debug, Default)]
+pub struct ServiceConfig {
+    pub version: String,
+    pub group: String,
+    pub name: String,
+    pub protocol_names: Vec<String>,
+    pub registry_names: Vec<String>,
+    pub serializer: String,
+    pub protocol_configs: HashMap<String, ProtocolConfig>,
+}
+
+impl ServiceConfig {
+    pub fn name(self, name: String) -> Self {
+        Self { name, ..self }
+    }
+
+    pub fn version(self, version: String) -> Self {
+        Self { version, ..self }
+    }
+
+    pub fn group(self, group: String) -> Self {
+        Self { group, ..self }
+    }
+
+    pub fn protocol_names(self, protocol_names: Vec<String>) -> Self {
+        Self {
+            protocol_names,
+            ..self
+        }
+    }
+
+    pub fn serializer(self, serializer: String) -> Self {
+        Self { serializer, ..self }
+    }
+
+    pub fn add_protocol_configs(mut self, protocol_config: ProtocolConfig) -> Self {
+        self.protocol_configs
+            .insert(protocol_config.name.clone(), protocol_config);
+        Self { ..self }
+    }
+
+    // pub fn get_url(&self) -> Vec<Url> {
+    //     let mut urls = Vec::new();
+    //     for (_, conf) in self.protocol_configs.iter() {
+    //         urls.push(Url {
+    //             url: conf.to_owned().to_url(),
+    //             service_key: "".to_string(),
+    //         });
+    //     }
+
+    //     urls
+    // }
+}
diff --git a/dubbo/Cargo.toml b/dubbo/Cargo.toml
index 1a693ba..ce32cb4 100644
--- a/dubbo/Cargo.toml
+++ b/dubbo/Cargo.toml
@@ -31,6 +31,7 @@ pin-project = "1.0"
 serde_json = "1.0.82"
 serde = {version="1.0.138", features = ["derive"]}
 tokio-stream = "0.1"
+futures = "0.3"
 
 config = {path = "../config"}
 triple = {path = "../triple"}
\ No newline at end of file
diff --git a/dubbo/src/echo/echo_client.rs b/dubbo/src/echo/echo_client.rs
index 0f8215b..ebe7908 100644
--- a/dubbo/src/echo/echo_client.rs
+++ b/dubbo/src/echo/echo_client.rs
@@ -1,7 +1,21 @@
-use std::str::FromStr;
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.
+ */
 
 use super::echo_server::{HelloReply, HelloRequest};
-use bytes::Buf;
 
 use triple::client::TripleClient;
 use triple::codec::serde_codec::SerdeCodec;
@@ -28,10 +42,8 @@ impl EchoClient {
     }
 
     pub fn with_uri(mut self, uri: String) -> Self {
-        self.uri = uri;
-        self.inner = self
-            .inner
-            .with_authority(http::uri::Authority::from_str(&self.uri).unwrap());
+        self.uri = uri.clone();
+        self.inner = self.inner.with_host(uri);
         self
     }
 
@@ -53,36 +65,9 @@ impl EchoClient {
         &self,
         req: Request<HelloRequest>,
     ) -> Result<Response<HelloReply>, tonic::Status> {
-        let (_parts, body) = req.into_parts();
-        let v = serde_json::to_vec(&body).unwrap();
-        let req = hyper::Request::builder()
-            .uri("http://".to_owned() + &self.uri.clone() + "/hello")
-            .method("POST")
-            .body(hyper::Body::from(v))
-            .unwrap();
-
-        println!("request: {:?}", req);
-        let response = hyper::Client::builder().build_http().request(req).await;
-
-        match response {
-            Ok(v) => {
-                println!("{:?}", v);
-                let (_parts, body) = v.into_parts();
-                let req_body = hyper::body::to_bytes(body).await.unwrap();
-                let v = req_body.chunk();
-                // let codec = SerdeCodec::<HelloReply, HelloRequest>::default();
-                let data: HelloReply = match serde_json::from_slice(v) {
-                    Ok(data) => data,
-                    Err(err) => {
-                        return Err(tonic::Status::new(tonic::Code::Internal, err.to_string()))
-                    }
-                };
-                Ok(Response::new(data))
-            }
-            Err(err) => {
-                println!("{}", err);
-                Err(tonic::Status::new(tonic::Code::Internal, err.to_string()))
-            }
-        }
+        let codec = SerdeCodec::<HelloRequest, HelloReply>::default();
+        self.inner
+            .unary(req, codec, http::uri::PathAndQuery::from_static("/hello"))
+            .await
     }
 }
diff --git a/dubbo/src/echo/echo_server.rs b/dubbo/src/echo/echo_server.rs
index d6e9476..96d89f3 100644
--- a/dubbo/src/echo/echo_server.rs
+++ b/dubbo/src/echo/echo_server.rs
@@ -1,3 +1,20 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.
+ */
+
 use async_trait::async_trait;
 
 use tonic::codegen::BoxFuture;
@@ -50,7 +67,6 @@ pub trait Echo: Send + Sync + 'static {
 
 struct _Inner<T>(Arc<T>);
 
-#[derive(Clone)]
 pub struct EchoServer<T, I = TripleInvoker> {
     inner: _Inner<T>,
     invoker: Option<I>,
@@ -141,23 +157,18 @@ where
 
                 Box::pin(fut)
             }
-            _ => {
-                Box::pin(async move {
-                    Ok(http::Response::builder()
-                        .status(200)
-                        .header("grpc-status", "12")
-                        .header("content-type", "application/grpc")
-                        // .body(hyper::Body::from("implement...").map_err(|err| match err {}).boxed())
-                        // .body(hyper::Body::from("implement...").map_err(|err| std::convert::Infallible).into())
-                        // .body(req.into_body())
-                        .body(
-                            http_body::Empty::new()
-                                .map_err(|err| match err {})
-                                .boxed_unsync(),
-                        )
-                        .unwrap())
-                })
-            }
+            _ => Box::pin(async move {
+                Ok(http::Response::builder()
+                    .status(200)
+                    .header("grpc-status", "12")
+                    .header("content-type", "application/grpc")
+                    .body(
+                        http_body::Empty::new()
+                            .map_err(|err| match err {})
+                            .boxed_unsync(),
+                    )
+                    .unwrap())
+            }),
         }
     }
 }
@@ -186,3 +197,24 @@ impl<T: Debug> Debug for _Inner<T> {
         write!(f, "Inner {:?}", self.0)
     }
 }
+
+impl<T: Echo, I: Invoker + Send + Sync + 'static> Clone for EchoServer<T, I> {
+    fn clone(&self) -> Self {
+        let inner = self.inner.clone();
+        Self {
+            inner,
+            invoker: None,
+        }
+    }
+}
+
+pub fn register_echo_server<T: Echo>(server: T) {
+    let s = EchoServer::<_, TripleInvoker>::new(server);
+    crate::protocol::triple::TRIPLE_SERVICES
+        .write()
+        .unwrap()
+        .insert(
+            "echo".to_string(),
+            crate::utils::boxed_clone::BoxCloneService::new(s),
+        );
+}
diff --git a/dubbo/src/echo/helloworld.rs b/dubbo/src/echo/helloworld.rs
new file mode 100644
index 0000000..9497f4b
--- /dev/null
+++ b/dubbo/src/echo/helloworld.rs
@@ -0,0 +1,296 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 request message containing the user's name.
+#[derive(Clone, PartialEq, ::prost::Message)]
+pub struct HelloRequest {
+    #[prost(string, tag = "1")]
+    pub name: ::prost::alloc::string::String,
+}
+/// The response message containing the greetings
+#[derive(Clone, PartialEq, ::prost::Message)]
+pub struct HelloReply {
+    #[prost(string, tag = "1")]
+    pub message: ::prost::alloc::string::String,
+}
+/// Generated client implementations.
+pub mod greeter_client {
+    #![allow(unused_variables, dead_code, missing_docs, clippy::let_unit_value)]
+    use triple::client::TripleClient;
+    use triple::codec::prost::ProstCodec;
+    use triple::invocation::*;
+    
+    /// The greeting service definition.
+    #[derive(Debug, Clone)]
+    pub struct GreeterClient {
+        inner: TripleClient,
+        uri: String,
+    }
+    // impl GreeterClient<tonic::transport::Channel> {
+    //     /// Attempt to create a new client by connecting to a given endpoint.
+    //     pub async fn connect<D>(dst: D) -> Result<Self, tonic::transport::Error>
+    //     where
+    //         D: std::convert::TryInto<tonic::transport::Endpoint>,
+    //         D::Error: Into<StdError>,
+    //     {
+    //         let conn = tonic::transport::Endpoint::new(dst)?.connect().await?;
+    //         Ok(Self::new(conn))
+    //     }
+    // }
+    impl GreeterClient {
+        pub fn new() -> Self {
+            Self {
+                inner: TripleClient::new(),
+                uri: "".to_string(),
+            }
+        }
+        // pub fn with_interceptor<F>(
+        //     inner: T,
+        //     interceptor: F,
+        // ) -> GreeterClient<InterceptedService<T, F>>
+        // where
+        //     F: tonic::service::Interceptor,
+        //     T::ResponseBody: Default,
+        //     T: tonic::codegen::Service<
+        //         http::Request<tonic::body::BoxBody>,
+        //         Response = http::Response<
+        //             <T as tonic::client::GrpcService<tonic::body::BoxBody>>::ResponseBody,
+        //         >,
+        //     >,
+        //     <T as tonic::codegen::Service<http::Request<tonic::body::BoxBody>>>::Error:
+        //         Into<StdError> + Send + Sync,
+        // {
+        //     GreeterClient::new(InterceptedService::new(inner, interceptor))
+        // }
+        /// Compress requests with `gzip`.
+        ///
+        /// This requires the server to support it otherwise it might respond with an
+        /// error.
+        // #[must_use]
+        // pub fn send_gzip(mut self) -> Self {
+        //     self.inner = self.inner.send_gzip();
+        //     self
+        // }
+        // /// Enable decompressing responses with `gzip`.
+        // #[must_use]
+        // pub fn accept_gzip(mut self) -> Self {
+        //     self.inner = self.inner.accept_gzip();
+        //     self
+        // }
+        /// Sends a greeting
+        pub async fn say_hello(
+            &mut self,
+            request: Request<super::HelloRequest>,
+        ) -> Result<Response<super::HelloReply>, tonic::Status> {
+            // self.inner.ready().await.map_err(|e| {
+            //     tonic::Status::new(
+            //         tonic::Code::Unknown,
+            //         format!("Service was not ready: {}", e.into()),
+            //     )
+            // })?;
+            let codec = ProstCodec::<super::HelloRequest, super::HelloReply>::default();
+            let path = http::uri::PathAndQuery::from_static("/helloworld.Greeter/SayHello");
+            self.inner.unary(request, codec, path).await
+        }
+    }
+}
+/// Generated server implementations.
+pub mod greeter_server {
+    #![allow(unused_variables, dead_code, missing_docs, clippy::let_unit_value)]
+
+    use crate::protocol::server_desc::ServiceDesc;
+    use crate::protocol::triple::triple_invoker::TripleInvoker;
+    use crate::protocol::DubboGrpcService;
+    use crate::protocol::Invoker;
+    use crate::{BoxFuture, StdError};
+    use async_trait::async_trait;
+    use http_body::Body;
+    use std::sync::Arc;
+    use std::task::Context;
+    use std::task::Poll;
+    use tower_service::Service;
+    use triple::codec::prost::ProstCodec;
+    use triple::empty_body;
+    use triple::invocation::{Request, Response};
+    use triple::server::server::TripleServer;
+    use triple::server::service::UnaryService;
+
+    ///Generated trait containing gRPC methods that should be implemented for use with GreeterServer.
+    #[async_trait]
+    pub trait Greeter: Send + Sync + 'static {
+        /// Sends a greeting
+        async fn say_hello(
+            &self,
+            request: Request<super::HelloRequest>,
+        ) -> Result<Response<super::HelloReply>, tonic::Status>;
+    }
+    /// The greeting service definition.
+    #[derive(Debug)]
+    pub struct GreeterServer<T: Greeter, I> {
+        inner: _Inner<T>,
+        invoker: Option<_Inner<I>>,
+        // accept_compression_encodings: EnabledCompressionEncodings,
+        // send_compression_encodings: EnabledCompressionEncodings,
+    }
+    struct _Inner<T>(Arc<T>);
+    impl<T: Greeter, I> GreeterServer<T, I> {
+        pub fn new(inner: T) -> Self {
+            Self::from_arc(Arc::new(inner))
+        }
+        pub fn from_arc(inner: Arc<T>) -> Self {
+            let inner = _Inner(inner);
+            Self {
+                inner,
+                invoker: None,
+                // accept_compression_encodings: Default::default(),
+                // send_compression_encodings: Default::default(),
+            }
+        }
+        // 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 `gzip`.
+        // #[must_use]
+        // pub fn accept_gzip(mut self) -> Self {
+        //     self.accept_compression_encodings.enable_gzip();
+        //     self
+        // }
+        // /// Compress responses with `gzip`, if the client supports it.
+        // #[must_use]
+        // pub fn send_gzip(mut self) -> Self {
+        //     self.send_compression_encodings.enable_gzip();
+        //     self
+        // }
+    }
+    impl<T, B, I> Service<http::Request<B>> for GreeterServer<T, I>
+    where
+        T: Greeter,
+        B: Body + Send + 'static,
+        B::Error: Into<StdError> + Send + 'static,
+    {
+        type Response = http::Response<tonic::body::BoxBody>;
+        type Error = std::convert::Infallible;
+        type Future = BoxFuture<Self::Response, Self::Error>;
+        fn poll_ready(&mut self, _cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
+            Poll::Ready(Ok(()))
+        }
+        fn call(&mut self, req: http::Request<B>) -> Self::Future {
+            let inner = self.inner.clone();
+            match req.uri().path() {
+                "/helloworld.Greeter/SayHello" => {
+                    #[allow(non_camel_case_types)]
+                    struct SayHelloSvc<T: Greeter>(pub Arc<T>);
+                    impl<T: Greeter> UnaryService<super::HelloRequest> for SayHelloSvc<T> {
+                        type Response = super::HelloReply;
+                        type Future = BoxFuture<Response<Self::Response>, tonic::Status>;
+                        fn call(&mut self, request: Request<super::HelloRequest>) -> Self::Future {
+                            let inner = self.0.clone();
+                            let fut = async move { (*inner).say_hello(request).await };
+                            Box::pin(fut)
+                        }
+                    }
+                    // let accept_compression_encodings = self.accept_compression_encodings;
+                    // let send_compression_encodings = self.send_compression_encodings;
+                    let inner = self.inner.clone();
+                    let fut = async move {
+                        let inner = inner.0;
+                        let method = SayHelloSvc(inner);
+                        let codec = ProstCodec::<super::HelloReply, super::HelloRequest>::default();
+                        // let mut grpc = tonic::server::Grpc::new(codec).apply_compression_config(
+                        //     accept_compression_encodings,
+                        //     send_compression_encodings,
+                        // );
+                        let mut grpc = TripleServer::new(codec);
+                        let res = grpc.unary(method, req).await;
+                        Ok(res)
+                    };
+                    Box::pin(fut)
+                }
+                _ => Box::pin(async move {
+                    Ok(http::Response::builder()
+                        .status(200)
+                        .header("grpc-status", "12")
+                        .header("content-type", "application/grpc")
+                        .body(empty_body())
+                        .unwrap())
+                }),
+            }
+        }
+    }
+    impl<T: Greeter, I: Invoker + Send + Sync + 'static> Clone for GreeterServer<T, I> {
+        fn clone(&self) -> Self {
+            let inner = self.inner.clone();
+            Self {
+                inner,
+                invoker: None,
+                // invoker: if let Some(v) = self.invoker.borrow_mut() {
+                //     Some(v.clone())
+                // } else {
+                //     None
+                // },
+                // accept_compression_encodings: self.accept_compression_encodings,
+                // send_compression_encodings: self.send_compression_encodings,
+            }
+        }
+    }
+
+    impl<T: Greeter> Clone for _Inner<T> {
+        fn clone(&self) -> Self {
+            Self(self.0.clone())
+        }
+    }
+    impl<T: std::fmt::Debug> std::fmt::Debug for _Inner<T> {
+        fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
+            write!(f, "{:?}", self.0)
+        }
+    }
+    impl<T: Greeter, I: Invoker> DubboGrpcService<I> for GreeterServer<T, I> {
+        fn set_proxy_impl(&mut self, invoker: I) {
+            self.invoker = Some(_Inner(Arc::new(invoker)));
+        }
+
+        fn service_desc(&self) -> ServiceDesc {
+            ServiceDesc::new(
+                "helloworld.Greeter".to_string(),
+                std::collections::HashMap::new(),
+            )
+        }
+    }
+
+    impl<T: Greeter, I> tonic::transport::NamedService for GreeterServer<T, I> {
+        const NAME: &'static str = "helloworld.Greeter";
+    }
+
+    pub fn register_greeter_server<T: Greeter>(server: T) {
+        let s = GreeterServer::<_, TripleInvoker>::new(server);
+        crate::protocol::triple::TRIPLE_SERVICES
+            .write()
+            .unwrap()
+            .insert(
+                "helloworld.Greeter".to_string(),
+                crate::utils::boxed_clone::BoxCloneService::new(s),
+            );
+    }
+}
diff --git a/dubbo/src/echo/mod.rs b/dubbo/src/echo/mod.rs
index 356fa9a..4df0678 100644
--- a/dubbo/src/echo/mod.rs
+++ b/dubbo/src/echo/mod.rs
@@ -1,5 +1,23 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.
+ */
+
 pub mod echo_client;
 pub mod echo_server;
+pub mod helloworld;
 
 use futures_util::Stream;
 use futures_util::StreamExt;
@@ -21,7 +39,7 @@ async fn test_client() {
     use futures_util::StreamExt;
     use triple::invocation::*;
 
-    let cli = EchoClient::new().with_uri("127.0.0.1:8888".to_string());
+    let cli = EchoClient::new().with_uri("http://127.0.0.1:8888".to_string());
     let resp = cli
         .say_hello(Request::new(HelloRequest {
             name: "message from client".to_string(),
@@ -49,9 +67,8 @@ async fn test_client() {
 
     let bidi_resp = cli.bidirectional_streaming_echo(req).await.unwrap();
 
-    let (_parts, mut body) = bidi_resp.into_parts();
-    // let trailer = body.trailer().await.unwrap();
-    // println!("trailer: {:?}", trailer);
+    let (parts, mut body) = bidi_resp.into_parts();
+    println!("parts: {:?}", parts);
     while let Some(item) = body.next().await {
         match item {
             Ok(v) => {
@@ -97,26 +114,39 @@ async fn test_triple_protocol() {
     use crate::common::url::Url;
     use crate::protocol::triple::triple_protocol::TripleProtocol;
     use crate::protocol::Protocol;
-    use crate::utils::boxed_clone::BoxCloneService;
+    use config::get_global_config;
+    use futures::join;
 
-    // crate::init::init();
+    let conf = get_global_config();
+    let server_name = "echo".to_string();
 
-    let esi = EchoServer::<EchoServerImpl>::new(EchoServerImpl {
-        name: "echo".to_string(),
+    echo_server::register_echo_server(EchoServerImpl {
+        name: server_name.clone(),
     });
+    helloworld::greeter_server::register_greeter_server(GreeterImpl {});
+    println!("root config: {:?}", conf);
+    println!(
+        "register service num: {:?}",
+        crate::protocol::triple::TRIPLE_SERVICES
+            .read()
+            .unwrap()
+            .len()
+    );
+
+    let mut urls = Vec::<Url>::new();
+    for (_, proto_conf) in conf.service.protocol_configs.iter() {
+        println!("{:?}", proto_conf);
+        let u = Url {
+            url: proto_conf.to_owned().to_url().clone(),
+            service_key: server_name.clone(),
+        };
+        urls.push(u.clone());
 
-    crate::protocol::triple::TRIPLE_SERVICES
-        .write()
-        .unwrap()
-        .insert("echo".to_string(), BoxCloneService::new(esi));
-
-    println!("triple server running, url: 0.0.0.0:8888");
-    let pro = TripleProtocol::new();
-    pro.export(Url {
-        url: "0.0.0.0:8888".to_string(),
-        service_key: "echo".to_string(),
-    })
-    .await;
+        println!("triple server running, url: 0.0.0.0:8888, {:?}", u);
+        let pro = TripleProtocol::new();
+        let tri_fut = pro.export(u.clone());
+        let _res = join!(tri_fut);
+    }
 }
 
 #[allow(dead_code)]
@@ -132,7 +162,7 @@ impl Echo for EchoServerImpl {
         &self,
         req: Request<HelloRequest>,
     ) -> Result<Response<HelloReply>, tonic::Status> {
-        println!("EchoServer::hello {:?}", req.message);
+        println!("EchoServer::hello {:?}", req.metadata);
 
         Ok(Response::new(HelloReply {
             reply: "hello, dubbo-rust".to_string(),
@@ -145,7 +175,10 @@ impl Echo for EchoServerImpl {
         &self,
         request: Request<triple::server::Streaming<HelloRequest>>,
     ) -> Result<Response<Self::BidirectionalStreamingEchoStream>, tonic::Status> {
-        println!("EchoServer::bidirectional_streaming_echo");
+        println!(
+            "EchoServer::bidirectional_streaming_echo, grpc header: {:?}",
+            request.metadata
+        );
 
         let mut in_stream = request.into_inner();
         let (tx, rx) = mpsc::channel(128);
@@ -212,3 +245,20 @@ fn match_for_io_error(err_status: &tonic::Status) -> Option<&std::io::Error> {
         };
     }
 }
+
+use helloworld::greeter_server::Greeter;
+
+struct GreeterImpl {}
+
+#[async_trait]
+impl Greeter for GreeterImpl {
+    async fn say_hello(
+        &self,
+        request: Request<helloworld::HelloRequest>,
+    ) -> Result<Response<helloworld::HelloReply>, tonic::Status> {
+        println!("greeter: req: {:?}", request.metadata);
+        Ok(Response::new(helloworld::HelloReply {
+            message: "hello, rust".to_string(),
+        }))
+    }
+}
diff --git a/dubbo/src/lib.rs b/dubbo/src/lib.rs
index 90ceb1c..1740648 100644
--- a/dubbo/src/lib.rs
+++ b/dubbo/src/lib.rs
@@ -18,9 +18,11 @@
 pub mod common;
 pub mod echo;
 pub mod helloworld;
-pub mod init;
 pub mod protocol;
-pub mod registry;
 pub mod utils;
 
-pub(crate) type Error = Box<dyn std::error::Error + Send + Sync>;
+use std::future::Future;
+use std::pin::Pin;
+
+pub type StdError = Box<dyn std::error::Error + Send + Sync + 'static>;
+pub type BoxFuture<T, E> = self::Pin<Box<dyn self::Future<Output = Result<T, E>> + Send + 'static>>;
diff --git a/dubbo/src/main.rs b/dubbo/src/main.rs
index db99336..baa5af4 100644
--- a/dubbo/src/main.rs
+++ b/dubbo/src/main.rs
@@ -18,12 +18,14 @@
 pub mod common;
 pub mod echo;
 pub mod helloworld;
-pub mod init;
 pub mod protocol;
-pub mod registry;
 pub mod utils;
 
-pub(crate) type Error = Box<dyn std::error::Error + Send + Sync>;
+use std::future::Future;
+use std::pin::Pin;
+
+pub type StdError = Box<dyn std::error::Error + Send + Sync + 'static>;
+pub type BoxFuture<T, E> = self::Pin<Box<dyn self::Future<Output = Result<T, E>> + Send + 'static>>;
 
 #[tokio::main]
 async fn main() {
diff --git a/triple/readme.md b/triple/readme.md
new file mode 100644
index 0000000..c969a78
--- /dev/null
+++ b/triple/readme.md
@@ -0,0 +1,15 @@
+# Triple Protocol
+
+Triple协议使用了hyper作为C/S之间的通信层,支持triple spec中自定义的header。
+
+整体模块划分为:
++ codec
++ server:
+  + Router
+  + 网络事件处理层
+  + 线程池:参考triple-go的线程模型
++ client:
+  + 线程池
+  + 连接处理层,类似于grpc channel层
+
+Triple支持tls、grpc压缩
\ No newline at end of file
diff --git a/triple/src/client/grpc.rs b/triple/src/client/grpc.rs
index 1277868..362a0f2 100644
--- a/triple/src/client/grpc.rs
+++ b/triple/src/client/grpc.rs
@@ -15,17 +15,19 @@
  * limitations under the License.
  */
 
-use futures_util::{StreamExt, TryStreamExt};
+use std::str::FromStr;
+
+use futures_util::{future, stream, StreamExt, TryStreamExt};
 use http::HeaderValue;
 
 use crate::codec::Codec;
-use crate::invocation::{IntoStreamingRequest, Response};
+use crate::invocation::{IntoStreamingRequest, Request, Response};
 use crate::server::encode::encode;
 use crate::server::Streaming;
 
 #[derive(Debug, Clone, Default)]
 pub struct TripleClient {
-    host: Option<http::uri::Authority>,
+    host: Option<http::Uri>,
     inner: ConnectionPool,
 }
 
@@ -55,52 +57,42 @@ impl TripleClient {
         }
     }
 
-    pub fn with_authority(self, host: http::uri::Authority) -> Self {
+    /// host: http://0.0.0.0:8888
+    pub fn with_host(self, host: String) -> Self {
+        let uri = http::Uri::from_str(&host).unwrap();
         TripleClient {
-            host: Some(host),
+            host: Some(uri),
             ..self
         }
     }
 }
 
 impl TripleClient {
-    pub async fn bidi_streaming<C, M1, M2>(
-        &mut self,
-        req: impl IntoStreamingRequest<Message = M1>,
-        mut codec: C,
+    fn map_request(
+        &self,
         path: http::uri::PathAndQuery,
-    ) -> Result<Response<Streaming<M2>>, tonic::Status>
-    where
-        C: Codec<Encode = M1, Decode = M2>,
-        M1: Send + Sync + 'static,
-        M2: Send + Sync + 'static,
-    {
-        let req = req.into_streaming_request();
-        let en = encode(codec.encoder(), req.into_inner().map(Ok)).into_stream();
-        let body = hyper::Body::wrap_stream(en);
-
-        let mut parts = http::uri::Parts::default();
+        body: hyper::Body,
+    ) -> http::Request<hyper::Body> {
+        let mut parts = self.host.clone().unwrap().into_parts();
         parts.path_and_query = Some(path);
-        parts.authority = self.host.clone();
-        parts.scheme = Some(http::uri::Scheme::HTTP);
 
         let uri = http::Uri::from_parts(parts).unwrap();
-
         let mut req = hyper::Request::builder()
             .version(http::Version::HTTP_2)
             .uri(uri.clone())
             .method("POST")
             .body(body)
             .unwrap();
+
         *req.version_mut() = http::Version::HTTP_2;
         req.headers_mut()
             .insert("method", HeaderValue::from_static("POST"));
         req.headers_mut().insert(
             "scheme",
-            HeaderValue::from_str(uri.clone().scheme_str().unwrap()).unwrap(),
+            HeaderValue::from_str(uri.scheme_str().unwrap()).unwrap(),
         );
         req.headers_mut()
-            .insert("path", HeaderValue::from_str(uri.clone().path()).unwrap());
+            .insert("path", HeaderValue::from_str(uri.path()).unwrap());
         req.headers_mut().insert(
             "authority",
             HeaderValue::from_str(uri.authority().unwrap().as_str()).unwrap(),
@@ -136,20 +128,78 @@ impl TripleClient {
         //     TripleTraceProtoBin  = "tri-trace-proto-bin"
         //     TripleUnitInfo       = "tri-unit-info"
         // )
+        req
+    }
+
+    pub async fn unary<C, M1, M2>(
+        &self,
+        req: Request<M1>,
+        mut codec: C,
+        path: http::uri::PathAndQuery,
+    ) -> Result<Response<M2>, tonic::Status>
+    where
+        C: Codec<Encode = M1, Decode = M2>,
+        M1: Send + Sync + 'static,
+        M2: Send + Sync + 'static,
+    {
+        let req = req.map(|m| stream::once(future::ready(m)));
+        let body_stream = encode(codec.encoder(), req.into_inner().map(Ok)).into_stream();
+        let body = hyper::Body::wrap_stream(body_stream);
 
+        let req = self.map_request(path, body);
         let cli = self.inner.clone().builder();
         let response = cli.request(req).await;
 
         match response {
             Ok(v) => {
                 let resp = v.map(|body| Streaming::new(body, codec.decoder()));
+                let (mut parts, body) = Response::from_http(resp).into_parts();
+
+                futures_util::pin_mut!(body);
+
+                let message = body.try_next().await?.ok_or_else(|| {
+                    tonic::Status::new(tonic::Code::Internal, "Missing response message.")
+                })?;
 
-                let (_parts, body) = resp.into_parts();
-                Ok(Response::new(body))
+                if let Some(trailers) = body.trailer().await? {
+                    let mut h = parts.into_headers();
+                    h.extend(trailers.into_headers());
+                    parts = tonic::metadata::MetadataMap::from_headers(h);
+                }
+
+                Ok(Response::from_parts(parts, message))
             }
-            Err(err) => {
-                Err(tonic::Status::new(tonic::Code::Internal, err.to_string()))
+            Err(err) => Err(tonic::Status::new(tonic::Code::Internal, err.to_string())),
+        }
+    }
+
+    pub async fn bidi_streaming<C, M1, M2>(
+        &mut self,
+        req: impl IntoStreamingRequest<Message = M1>,
+        mut codec: C,
+        path: http::uri::PathAndQuery,
+    ) -> Result<Response<Streaming<M2>>, tonic::Status>
+    where
+        C: Codec<Encode = M1, Decode = M2>,
+        M1: Send + Sync + 'static,
+        M2: Send + Sync + 'static,
+    {
+        let req = req.into_streaming_request();
+        let en = encode(codec.encoder(), req.into_inner().map(Ok)).into_stream();
+        let body = hyper::Body::wrap_stream(en);
+
+        let req = self.map_request(path, body);
+
+        let cli = self.inner.clone().builder();
+        let response = cli.request(req).await;
+
+        match response {
+            Ok(v) => {
+                let resp = v.map(|body| Streaming::new(body, codec.decoder()));
+
+                Ok(Response::from_http(resp))
             }
+            Err(err) => Err(tonic::Status::new(tonic::Code::Internal, err.to_string())),
         }
     }
 }
diff --git a/triple/src/codec/mod.rs b/triple/src/codec/mod.rs
index f6e61d9..c21b69a 100644
--- a/triple/src/codec/mod.rs
+++ b/triple/src/codec/mod.rs
@@ -16,6 +16,7 @@
  */
 
 pub mod buffer;
+pub mod prost;
 pub mod serde_codec;
 
 use std::io;
diff --git a/triple/src/codec/prost.rs b/triple/src/codec/prost.rs
new file mode 100644
index 0000000..162ac51
--- /dev/null
+++ b/triple/src/codec/prost.rs
@@ -0,0 +1,236 @@
+use super::{Codec, DecodeBuf, Decoder, EncodeBuf, Encoder};
+use prost::Message;
+use std::marker::PhantomData;
+use tonic::{Code, Status};
+
+/// A [`Codec`] that implements `application/grpc+proto` via the prost library..
+#[derive(Debug, Clone)]
+pub struct ProstCodec<T, U> {
+    _pd: PhantomData<(T, U)>,
+}
+
+impl<T, U> Default for ProstCodec<T, U> {
+    fn default() -> Self {
+        Self { _pd: PhantomData }
+    }
+}
+
+impl<T, U> Codec for ProstCodec<T, U>
+where
+    T: Message + Send + 'static,
+    U: Message + Default + Send + 'static,
+{
+    type Encode = T;
+    type Decode = U;
+
+    type Encoder = ProstEncoder<T>;
+    type Decoder = ProstDecoder<U>;
+
+    fn encoder(&mut self) -> Self::Encoder {
+        ProstEncoder(PhantomData)
+    }
+
+    fn decoder(&mut self) -> Self::Decoder {
+        ProstDecoder(PhantomData)
+    }
+}
+
+/// A [`Encoder`] that knows how to encode `T`.
+#[derive(Debug, Clone, Default)]
+pub struct ProstEncoder<T>(PhantomData<T>);
+
+impl<T: Message> Encoder for ProstEncoder<T> {
+    type Item = T;
+    type Error = Status;
+
+    fn encode(&mut self, item: Self::Item, buf: &mut EncodeBuf<'_>) -> Result<(), Self::Error> {
+        item.encode(buf)
+            .expect("Message only errors if not enough space");
+
+        Ok(())
+    }
+}
+
+/// A [`Decoder`] that knows how to decode `U`.
+#[derive(Debug, Clone, Default)]
+pub struct ProstDecoder<U>(PhantomData<U>);
+
+impl<U: Message + Default> Decoder for ProstDecoder<U> {
+    type Item = U;
+    type Error = Status;
+
+    fn decode(&mut self, buf: &mut DecodeBuf<'_>) -> Result<Option<Self::Item>, Self::Error> {
+        let item = Message::decode(buf)
+            .map(Option::Some)
+            .map_err(from_decode_error)?;
+
+        Ok(item)
+    }
+}
+
+fn from_decode_error(error: prost::DecodeError) -> Status {
+    // Map Protobuf parse errors to an INTERNAL status code, as per
+    // https://github.com/grpc/grpc/blob/master/doc/statuscodes.md
+    Status::new(Code::Internal, error.to_string())
+}
+
+// #[cfg(test)]
+// mod tests {
+//     use crate::codec::compression::SingleMessageCompressionOverride;
+//     use crate::codec::{
+//         encode_server, DecodeBuf, Decoder, EncodeBuf, Encoder, Streaming, HEADER_SIZE,
+//     };
+//     use crate::Status;
+//     use bytes::{Buf, BufMut, BytesMut};
+//     use http_body::Body;
+
+//     const LEN: usize = 10000;
+
+//     #[tokio::test]
+//     async fn decode() {
+//         let decoder = MockDecoder::default();
+
+//         let msg = vec![0u8; LEN];
+
+//         let mut buf = BytesMut::new();
+
+//         buf.reserve(msg.len() + HEADER_SIZE);
+//         buf.put_u8(0);
+//         buf.put_u32(msg.len() as u32);
+
+//         buf.put(&msg[..]);
+
+//         let body = body::MockBody::new(&buf[..], 10005, 0);
+
+//         let mut stream = Streaming::new_request(decoder, body, None);
+
+//         let mut i = 0usize;
+//         while let Some(output_msg) = stream.message().await.unwrap() {
+//             assert_eq!(output_msg.len(), msg.len());
+//             i += 1;
+//         }
+//         assert_eq!(i, 1);
+//     }
+
+//     #[tokio::test]
+//     async fn encode() {
+//         let encoder = MockEncoder::default();
+
+//         let msg = Vec::from(&[0u8; 1024][..]);
+
+//         let messages = std::iter::repeat_with(move || Ok::<_, Status>(msg.clone())).take(10000);
+//         let source = futures_util::stream::iter(messages);
+
+//         let body = encode_server(
+//             encoder,
+//             source,
+//             None,
+//             SingleMessageCompressionOverride::default(),
+//         );
+
+//         futures_util::pin_mut!(body);
+
+//         while let Some(r) = body.data().await {
+//             r.unwrap();
+//         }
+//     }
+
+//     #[derive(Debug, Clone, Default)]
+//     struct MockEncoder;
+
+//     impl Encoder for MockEncoder {
+//         type Item = Vec<u8>;
+//         type Error = Status;
+
+//         fn encode(&mut self, item: Self::Item, buf: &mut EncodeBuf<'_>) -> Result<(), Self::Error> {
+//             buf.put(&item[..]);
+//             Ok(())
+//         }
+//     }
+
+//     #[derive(Debug, Clone, Default)]
+//     struct MockDecoder;
+
+//     impl Decoder for MockDecoder {
+//         type Item = Vec<u8>;
+//         type Error = Status;
+
+//         fn decode(&mut self, buf: &mut DecodeBuf<'_>) -> Result<Option<Self::Item>, Self::Error> {
+//             let out = Vec::from(buf.chunk());
+//             buf.advance(LEN);
+//             Ok(Some(out))
+//         }
+//     }
+
+//     mod body {
+//         use crate::Status;
+//         use bytes::Bytes;
+//         use http_body::Body;
+//         use std::{
+//             pin::Pin,
+//             task::{Context, Poll},
+//         };
+
+//         #[derive(Debug)]
+//         pub(super) struct MockBody {
+//             data: Bytes,
+
+//             // the size of the partial message to send
+//             partial_len: usize,
+
+//             // the number of times we've sent
+//             count: usize,
+//         }
+
+//         impl MockBody {
+//             pub(super) fn new(b: &[u8], partial_len: usize, count: usize) -> Self {
+//                 MockBody {
+//                     data: Bytes::copy_from_slice(b),
+//                     partial_len,
+//                     count,
+//                 }
+//             }
+//         }
+
+//         impl Body for MockBody {
+//             type Data = Bytes;
+//             type Error = Status;
+
+//             fn poll_data(
+//                 mut self: Pin<&mut Self>,
+//                 cx: &mut Context<'_>,
+//             ) -> Poll<Option<Result<Self::Data, Self::Error>>> {
+//                 // every other call to poll_data returns data
+//                 let should_send = self.count % 2 == 0;
+//                 let data_len = self.data.len();
+//                 let partial_len = self.partial_len;
+//                 let count = self.count;
+//                 if data_len > 0 {
+//                     let result = if should_send {
+//                         let response =
+//                             self.data
+//                                 .split_to(if count == 0 { partial_len } else { data_len });
+//                         Poll::Ready(Some(Ok(response)))
+//                     } else {
+//                         cx.waker().wake_by_ref();
+//                         Poll::Pending
+//                     };
+//                     // make some fake progress
+//                     self.count += 1;
+//                     result
+//                 } else {
+//                     Poll::Ready(None)
+//                 }
+//             }
+
+//             #[allow(clippy::drop_ref)]
+//             fn poll_trailers(
+//                 self: Pin<&mut Self>,
+//                 cx: &mut Context<'_>,
+//             ) -> Poll<Result<Option<http::HeaderMap>, Self::Error>> {
+//                 drop(cx);
+//                 Poll::Ready(Ok(None))
+//             }
+//         }
+//     }
+// }
diff --git a/triple/src/invocation.rs b/triple/src/invocation.rs
index 1655312..de2e36e 100644
--- a/triple/src/invocation.rs
+++ b/triple/src/invocation.rs
@@ -39,6 +39,10 @@ impl<T> Request<T> {
         (self.metadata, self.message)
     }
 
+    pub fn from_parts(metadata: MetadataMap, message: T) -> Self {
+        Request { message, metadata }
+    }
+
     pub fn from_http(req: http::Request<T>) -> Self {
         let (parts, body) = req.into_parts();
         Request {
@@ -54,6 +58,17 @@ impl<T> Request<T> {
 
         http_req
     }
+
+    pub fn map<F, U>(self, f: F) -> Request<U>
+    where
+        F: FnOnce(T) -> U,
+    {
+        let m = f(self.message);
+        Request {
+            message: m,
+            metadata: self.metadata,
+        }
+    }
 }
 
 pub struct Response<T> {
@@ -85,6 +100,14 @@ impl<T> Response<T> {
         http_resp
     }
 
+    pub fn from_http(resp: http::Response<T>) -> Self {
+        let (part, body) = resp.into_parts();
+        Response {
+            message: body,
+            metadata: MetadataMap::from_headers(part.headers),
+        }
+    }
+
     pub fn map<F, U>(self, f: F) -> Response<U>
     where
         F: FnOnce(T) -> U,
diff --git a/triple/src/server/encode.rs b/triple/src/server/encode.rs
index c76f448..9e4ebc1 100644
--- a/triple/src/server/encode.rs
+++ b/triple/src/server/encode.rs
@@ -162,7 +162,6 @@ where
             tonic::Status::ok("")
         };
         let http = status.to_http();
-        println!("status: {:?}", http.headers().clone());
 
         Poll::Ready(Ok(Some(http.headers().to_owned())))
     }
diff --git a/triple/src/server/server.rs b/triple/src/server/server.rs
index 6474d6c..859f545 100644
--- a/triple/src/server/server.rs
+++ b/triple/src/server/server.rs
@@ -15,11 +15,10 @@
  * limitations under the License.
  */
 
-use bytes::{Buf, BytesMut};
+use futures_util::{future, stream, StreamExt, TryStreamExt};
 use http_body::Body;
-use std::fmt::Debug;
 
-use crate::codec::{Codec, DecodeBuf, Decoder, EncodeBuf, Encoder};
+use crate::codec::Codec;
 use crate::invocation::Request;
 use crate::server::encode::encode_server;
 use crate::server::service::{StreamingSvc, UnaryService};
@@ -75,55 +74,30 @@ where
     where
         S: UnaryService<T::Decode, Response = T::Encode>,
         B: Body + Send + 'static,
-        B::Error: Debug,
+        B::Error: Into<crate::Error> + Send,
     {
-        let (_parts, body) = req.into_parts();
-        let req_body = hyper::body::to_bytes(body).await.unwrap();
-        let v = req_body.chunk();
-        let mut req_byte = BytesMut::from(v);
-        let mut de = DecodeBuf::new(&mut req_byte, v.len());
-        let decoder = self
-            .codec
-            .decoder()
-            .decode(&mut de)
-            .map(|v| v.unwrap())
-            .unwrap();
-        let req = Request::new(decoder);
-
-        let resp = service.call(req).await;
-
-        let resp = match resp {
-            Ok(r) => r,
-            Err(status) => {
-                let (mut parts, _body) = http::Response::new(()).into_parts();
-                parts.headers.insert(
-                    http::header::CONTENT_TYPE,
-                    http::HeaderValue::from_static("application/grpc"),
-                );
-                parts.status = status.to_http().status();
-
-                return http::Response::from_parts(parts, crate::empty_body());
-            }
-        };
-        let (mut parts, body) = resp.into_http().into_parts();
+        let req_stream = req.map(|body| Streaming::new(body, self.codec.decoder()));
+        let (parts, mut body) = Request::from_http(req_stream).into_parts();
+        let msg = body
+            .try_next()
+            .await
+            .unwrap()
+            .ok_or_else(|| tonic::Status::new(tonic::Code::Unknown, "request wrong"));
 
-        // let data = hyper::body::aggregate(body)
-        // let b = body.size_hint();
-        let mut bytes = BytesMut::with_capacity(100);
-        let mut dst = EncodeBuf::new(&mut bytes);
-        let _res = self.codec.encoder().encode(body, &mut dst);
-        let data = bytes.to_vec();
+        let resp = service.call(Request::from_parts(parts, msg.unwrap())).await;
 
-        let resp_body = hyper::Body::from(data);
+        let (mut parts, resp_body) = resp.unwrap().into_http().into_parts();
+        let resp_body = encode_server(
+            self.codec.encoder(),
+            stream::once(future::ready(resp_body)).map(Ok).into_stream(),
+        );
 
+        parts.headers.insert(
+            http::header::CONTENT_TYPE,
+            http::HeaderValue::from_static("application/grpc"),
+        );
         parts.status = http::StatusCode::OK;
-        // http::Response::from_parts(parts, resp_body.map_err(|err| err.into()).boxed_unsync())
-        http::Response::from_parts(
-            parts,
-            resp_body
-                .map_err(|err| tonic::Status::new(tonic::Code::Internal, err.to_string()))
-                .boxed_unsync(),
-        )
+        http::Response::from_parts(parts, BoxBody::new(resp_body))
     }
 }
 
diff --git a/triple/src/transport/service.rs b/triple/src/transport/service.rs
index e470601..fdd6ecb 100644
--- a/triple/src/transport/service.rs
+++ b/triple/src/transport/service.rs
@@ -125,17 +125,21 @@ impl DubboServer {
             inner: self.services.get(&name).unwrap().clone(),
         };
 
+        let http2_keepalive_timeout = self
+            .http2_keepalive_timeout
+            .unwrap_or_else(|| Duration::new(60, 0));
+
         hyper::Server::bind(&addr)
             .http2_only(self.accept_http2)
             .http2_max_concurrent_streams(self.max_concurrent_streams)
             .http2_initial_connection_window_size(self.init_connection_window_size)
             .http2_initial_stream_window_size(self.init_stream_window_size)
             .http2_keep_alive_interval(self.http2_keepalive_interval)
-            .http2_keep_alive_timeout(self.http2_keepalive_timeout.unwrap())
+            .http2_keep_alive_timeout(http2_keepalive_timeout)
             .http2_max_frame_size(self.max_frame_size)
             .serve(svc)
             .await
-            .map_err(|err| println!("Error: {:?}", err))
+            .map_err(|err| println!("hyper serve, Error: {:?}", err))
             .unwrap();
 
         Ok(())
@@ -170,8 +174,7 @@ where
 impl BusinessConfig for DubboServer {
     fn init() -> Self {
         let conf = config::get_global_config();
-        DubboServer::new()
-            .with_accpet_http1(conf.bool("dubbo.server.accept_http2".to_string()))
+        DubboServer::new().with_accpet_http1(conf.bool("dubbo.server.accept_http2".to_string()))
     }
 
     fn load() -> Result<(), std::convert::Infallible> {


[dubbo-rust] 18/38: Ftr: add license check github action.

Posted by li...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

liujun pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/dubbo-rust.git

commit 61d6a0da212ca6e83b6a4cebfbbcc51f484e9eb4
Author: Zonglei Dong <do...@apache.org>
AuthorDate: Sat May 14 15:28:21 2022 +0800

    Ftr: add license check github action.
---
 .github/workflows/licence-checker.yml | 45 ++++++++++++++++++++++
 .licenserc.yaml                       | 72 +++++++++++++++++++++++++++++++++++
 2 files changed, 117 insertions(+)

diff --git a/.github/workflows/licence-checker.yml b/.github/workflows/licence-checker.yml
new file mode 100644
index 0000000..0caf87d
--- /dev/null
+++ b/.github/workflows/licence-checker.yml
@@ -0,0 +1,45 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you 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.
+#
+
+name: License checker
+
+on:
+  push:
+    branches:
+      - main
+  pull_request:
+    branches:
+      - main
+  pull_request_target:
+    branches:
+      - main
+
+jobs:
+  check-license:
+    runs-on: ubuntu-latest
+    steps:
+      - uses: actions/checkout@v2
+
+      - name: Check License Header
+        uses: apache/skywalking-eyes@main
+        env:
+          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+        with:
+          log: info
+          config: .licenserc.yaml
diff --git a/.licenserc.yaml b/.licenserc.yaml
new file mode 100644
index 0000000..bdecd85
--- /dev/null
+++ b/.licenserc.yaml
@@ -0,0 +1,72 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements.  See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You 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.
+#
+
+header: # `header` section is configurations for source codes license header.
+  license:
+    spdx-id: Apache-2.0 # the spdx id of the license, it's convenient when your license is standard SPDX license.
+    copyright-owner: Apache Software Foundation # the copyright owner to replace the [owner] in the `spdx-id` template.
+    content: | # `license` will be used as the content when `fix` command needs to insert a license header.
+      Licensed to the Apache Software Foundation (ASF) under one or more
+      contributor license agreements.  See the NOTICE file distributed with
+      this work for additional information regarding copyright ownership.
+      The ASF licenses this file to You 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.
+    # `pattern` is optional regexp if all the file headers are the same as `license` or the license of `spdx-id` and `copyright-owner`.
+    pattern: |
+      Licensed to the Apache Software Foundation under one or more contributor
+      license agreements. See the NOTICE file distributed with
+      this work for additional information regarding copyright
+      ownership. The Apache Software Foundation licenses this file to you 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.
+  paths: # `paths` are the path list that will be checked (and fixed) by license-eye, default is ['**'].
+    - '**'
+
+  paths-ignore: # `paths-ignore` are the path list that will be ignored by license-eye.
+    - '**/*.md'
+    - '**/Cargo.toml'
+    - 'LICENSE'
+    - 'NOTICE'
+    - '.asf.yml'
+    - '.gitignore'
+    - '.github'
+  comment: on-failure # on what condition license-eye will comment on the pull request, `on-failure`, `always`, `never`.
+
+  # license-location-threshold specifies the index threshold where the license header can be located,
+  # after all, a "header" cannot be TOO far from the file start.
+  license-location-threshold: 80
+
+dependency:
+  files:
+    - Cargo.toml


[dubbo-rust] 10/38: Update CI.yml

Posted by li...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

liujun pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/dubbo-rust.git

commit 04a3e3f0fb9ed4e8a633f4359ec503d523ed0b09
Author: Johankoi <Jo...@163.com>
AuthorDate: Wed Apr 27 00:28:44 2022 +0800

    Update CI.yml
    
    fix work flow
---
 .github/workflows/CI.yml | 6 ++----
 1 file changed, 2 insertions(+), 4 deletions(-)

diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml
index 993dbd7..b377439 100644
--- a/.github/workflows/CI.yml
+++ b/.github/workflows/CI.yml
@@ -27,7 +27,7 @@ jobs:
     - uses: actions-rs/toolchain@v1
       with:
           toolchain: ${{ matrix.rust }}
-    - run: cargo che
+    - run: cargo check
     
  fmt:
     name: Rustfmt
@@ -41,9 +41,7 @@ jobs:
       - uses: actions/checkout@main
       - uses: actions-rs/toolchain@v1
         with:
-          profile: minimal
-          toolchain: stable
-          override: true
+          toolchain: ${{ matrix.rust }}
       - run: rustup component add rustfmt
       - run: cargo fmt --all -- --check
       


[dubbo-rust] 15/38: Fix spell mistake #9

Posted by li...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

liujun pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/dubbo-rust.git

commit 2b2eef47ce8c691d195c622a0c3ba6e665a4c050
Merge: 1f5fb8e 291a41b
Author: ken.lj <ke...@gmail.com>
AuthorDate: Sat May 14 10:19:58 2022 +0800

    Fix spell mistake #9

 .github/workflows/CI.yml | 10 +---------
 .gitignore               |  3 +++
 2 files changed, 4 insertions(+), 9 deletions(-)