├── .asf.yaml ├── .github └── workflows │ ├── github-actions.yml │ └── licence-checker.yml ├── .gitignore ├── .licenserc.yaml ├── .rustfmt.toml ├── CONTRIBUTING.md ├── Cargo.toml ├── LICENSE ├── NOTICE ├── README.md ├── README_CN.md ├── application.yaml ├── docs ├── config.md ├── filter-design.md ├── generic-protocol-design.md ├── how-to-release.md ├── images │ └── examples │ │ ├── client.png │ │ ├── dir-server.png │ │ └── server.png ├── readme.md └── services.md ├── dubbo-build ├── Cargo.toml ├── LICENSE └── src │ ├── client.rs │ ├── lib.rs │ ├── prost.rs │ └── server.rs ├── dubbo ├── Cargo.toml ├── LICENSE ├── README.md ├── README_CN.md └── src │ ├── cluster │ ├── failover.rs │ ├── mod.rs │ └── router │ │ ├── condition │ │ ├── condition_router.rs │ │ ├── matcher.rs │ │ ├── mod.rs │ │ └── single_router.rs │ │ ├── manager │ │ ├── condition_manager.rs │ │ ├── mod.rs │ │ ├── router_manager.rs │ │ └── tag_manager.rs │ │ ├── mod.rs │ │ ├── nacos_config_center │ │ ├── mod.rs │ │ └── nacos_client.rs │ │ ├── router_chain.rs │ │ ├── tag │ │ ├── mod.rs │ │ └── tag_router.rs │ │ └── utils.rs │ ├── codegen.rs │ ├── config │ ├── config.rs │ ├── mod.rs │ ├── protocol.rs │ ├── provider.rs │ ├── registry.rs │ ├── router.rs │ └── service.rs │ ├── context.rs │ ├── directory │ └── mod.rs │ ├── extension │ ├── invoker_extension.rs │ ├── mod.rs │ └── registry_extension.rs │ ├── filter │ ├── context.rs │ ├── mod.rs │ ├── service.rs │ └── timeout.rs │ ├── framework.rs │ ├── invocation.rs │ ├── invoker │ ├── clone_body.rs │ ├── clone_invoker.rs │ └── mod.rs │ ├── lib.rs │ ├── loadbalancer │ ├── mod.rs │ └── random.rs │ ├── logger │ ├── level.rs │ ├── mod.rs │ └── tracing_configurer.rs │ ├── param.rs │ ├── params │ ├── constants.rs │ ├── extension_param.rs │ ├── mod.rs │ └── registry_param.rs │ ├── protocol │ ├── mod.rs │ ├── server_desc.rs │ └── triple │ │ ├── mod.rs │ │ ├── triple_exporter.rs │ │ ├── triple_invoker.rs │ │ ├── triple_protocol.rs │ │ └── triple_server.rs │ ├── registry │ ├── integration.rs │ ├── memory_registry.rs │ ├── mod.rs │ ├── protocol.rs │ └── registry.rs │ ├── route │ └── mod.rs │ ├── status.rs │ ├── svc.rs │ ├── triple │ ├── client │ │ ├── builder.rs │ │ ├── mod.rs │ │ └── triple.rs │ ├── codec │ │ ├── buffer.rs │ │ ├── mod.rs │ │ ├── prost.rs │ │ └── serde_codec.rs │ ├── compression.rs │ ├── consts.rs │ ├── decode.rs │ ├── encode.rs │ ├── mod.rs │ ├── server │ │ ├── builder.rs │ │ ├── mod.rs │ │ ├── service.rs │ │ └── triple.rs │ └── transport │ │ ├── connection.rs │ │ ├── connector │ │ ├── http_connector.rs │ │ ├── https_connector.rs │ │ ├── mod.rs │ │ └── unix_connector.rs │ │ ├── io │ │ └── mod.rs │ │ ├── listener │ │ ├── mod.rs │ │ ├── tcp_listener.rs │ │ └── unix_listener.rs │ │ ├── mod.rs │ │ ├── resolver │ │ ├── dns.rs │ │ └── mod.rs │ │ ├── router.rs │ │ └── service.rs │ ├── url.rs │ └── utils │ ├── boxed.rs │ ├── boxed_clone.rs │ ├── mod.rs │ ├── tls.rs │ └── yaml_utils.rs ├── examples ├── README.md ├── echo │ ├── Cargo.toml │ ├── LICENSE │ ├── README.md │ ├── README_CN.md │ ├── build.rs │ ├── fixtures │ │ ├── ca.crt │ │ ├── server.crt │ │ └── server.key │ ├── proto │ │ └── echo │ │ │ └── echo.proto │ └── src │ │ ├── echo-tls │ │ ├── client.rs │ │ └── server.rs │ │ ├── echo │ │ ├── client.rs │ │ └── server.rs │ │ ├── generated │ │ ├── grpc.examples.echo.rs │ │ └── mod.rs │ │ └── lib.rs ├── greeter │ ├── Cargo.toml │ ├── LICENSE │ ├── README.md │ ├── README_CN.md │ ├── application.yaml │ ├── build.rs │ ├── proto │ │ └── greeter.proto │ └── src │ │ └── greeter │ │ ├── client.rs │ │ └── server.rs └── helloworld-tutorial.md ├── protocol ├── README.md ├── base │ ├── Cargo.toml │ ├── LICENSE │ └── src │ │ ├── error.rs │ │ ├── invocation.rs │ │ ├── invoker.rs │ │ ├── lib.rs │ │ └── output.rs ├── dubbo2 │ ├── Cargo.toml │ ├── LICENSE │ └── src │ │ └── lib.rs └── triple │ ├── Cargo.toml │ ├── LICENSE │ └── src │ ├── lib.rs │ └── triple_invoker.rs ├── registry ├── README.md ├── nacos │ ├── Cargo.toml │ ├── LICENSE │ └── src │ │ └── lib.rs └── zookeeper │ ├── Cargo.toml │ ├── LICENSE │ └── src │ └── lib.rs ├── release.toml └── remoting ├── README.md ├── base ├── Cargo.toml ├── LICENSE └── src │ ├── builder │ ├── client.rs │ ├── mod.rs │ └── server.rs │ ├── codec.rs │ ├── error.rs │ ├── exchange │ ├── client.rs │ ├── mod.rs │ └── server.rs │ └── lib.rs ├── http ├── Cargo.toml ├── LICENSE └── src │ └── lib.rs ├── net ├── Cargo.toml ├── LICENSE ├── benches │ └── transport_benchmark │ │ └── main.rs └── src │ ├── conn.rs │ ├── dial.rs │ ├── incoming.rs │ ├── lib.rs │ ├── pool.rs │ └── probe.rs ├── xds ├── Cargo.toml ├── LICENSE └── src │ ├── client │ ├── client.rs │ └── mod.rs │ ├── lib.rs │ └── server │ ├── mod.rs │ └── server.rs └── zookeeper ├── Cargo.toml ├── LICENSE └── src └── lib.rs /.asf.yaml: -------------------------------------------------------------------------------- 1 | # 2 | # Licensed to the Apache Software Foundation (ASF) under one or more 3 | # contributor license agreements. See the NOTICE file distributed with 4 | # this work for additional information regarding copyright ownership. 5 | # The ASF licenses this file to You under the Apache License, Version 2.0 6 | # (the "License"); you may not use this file except in compliance with 7 | # the License. You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | # 17 | # See: https://cwiki.apache.org/confluence/display/INFRA/git+-+.asf.yaml+features 18 | 19 | notifications: 20 | commits: commits@dubbo.apache.org 21 | issues: notifications@dubbo.apache.org 22 | pullrequests: notifications@dubbo.apache.org 23 | jira_options: link label link label 24 | 25 | github: 26 | homepage: https://dubbo.apache.org/ 27 | del_branch_on_merge: true 28 | features: 29 | # Enable wiki for documentation 30 | wiki: true 31 | # Enable issue management 32 | issues: true 33 | # Enable projects for project management boards 34 | projects: true 35 | collaborators: # Note: the number of collaborators is limited to 20 36 | - robberphex 37 | enabled_merge_buttons: 38 | # enable squash button: 39 | squash: true 40 | # enable merge button: 41 | merge: false 42 | # disable rebase button: 43 | rebase: false 44 | protected_branches: 45 | main: {} 46 | -------------------------------------------------------------------------------- /.github/workflows/github-actions.yml: -------------------------------------------------------------------------------- 1 | # This is a basic workflow to help you get started with Actions 2 | 3 | name: CI 4 | 5 | on: 6 | push: 7 | branches: ["*"] 8 | pull_request: 9 | branches: 10 | - '*' 11 | - 'refact/*' 12 | 13 | 14 | jobs: 15 | check: 16 | name: check dubbo-rust project 17 | runs-on: ubuntu-latest 18 | 19 | env: 20 | RUSTFLAGS: "-D warnings" 21 | 22 | steps: 23 | - uses: actions/checkout@main 24 | - uses: actions-rs/toolchain@v1 25 | with: 26 | toolchain: nightly 27 | default: true 28 | - name: Set up cargo cache 29 | uses: actions/cache@v3 30 | continue-on-error: false 31 | with: 32 | path: | 33 | ~/.cargo/bin/ 34 | ~/.cargo/registry/index/ 35 | ~/.cargo/registry/cache/ 36 | ~/.cargo/git/db/ 37 | target/ 38 | key: ${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.lock') }} 39 | restore-keys: ${{ runner.os }}-cargo- 40 | - name: setup protoc 41 | run: | 42 | mkdir $HOME/protoc/ -p && 43 | cd $HOME/protoc/ && 44 | curl --location --silent --output /tmp/protoc-21.9-linux-x86_64.zip \ 45 | https://github.com/protocolbuffers/protobuf/releases/download/v21.9/protoc-21.9-linux-x86_64.zip && 46 | unzip /tmp/protoc-21.9-linux-x86_64.zip && 47 | echo "$HOME/protoc/bin" >> $GITHUB_PATH 48 | shell: bash 49 | - run: rustup component add rustfmt 50 | - run: cargo fmt --all -- --check 51 | - run: cargo check 52 | 53 | example-greeter: 54 | name: example/greeter 55 | runs-on: ubuntu-latest 56 | services: 57 | zoo1: 58 | image: zookeeper:3.8 59 | ports: 60 | - 2181:2181 61 | env: 62 | ZOO_MY_ID: 1 63 | nacos: 64 | image: nacos/nacos-server:v2.3.1 65 | ports: 66 | - 8848:8848 67 | - 9848:9848 68 | env: 69 | MODE: standalone 70 | steps: 71 | - uses: actions/checkout@main 72 | - uses: actions-rs/toolchain@v1 73 | with: 74 | toolchain: stable 75 | - name: Set up cargo cache 76 | uses: actions/cache@v3 77 | continue-on-error: false 78 | with: 79 | path: | 80 | ~/.cargo/bin/ 81 | ~/.cargo/registry/index/ 82 | ~/.cargo/registry/cache/ 83 | ~/.cargo/git/db/ 84 | target/ 85 | key: ${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.lock') }} 86 | restore-keys: ${{ runner.os }}-cargo- 87 | - name: setup protoc 88 | run: | 89 | mkdir $HOME/protoc/ -p && 90 | cd $HOME/protoc/ && 91 | curl --location --silent --output /tmp/protoc-21.9-linux-x86_64.zip \ 92 | https://github.com/protocolbuffers/protobuf/releases/download/v21.9/protoc-21.9-linux-x86_64.zip && 93 | unzip /tmp/protoc-21.9-linux-x86_64.zip && 94 | echo "$HOME/protoc/bin" >> $GITHUB_PATH 95 | shell: bash 96 | - run: cargo build 97 | working-directory: examples/greeter 98 | - name: example greeter 99 | run: | 100 | ../../target/debug/greeter-server & 101 | sleep 3 102 | ../../target/debug/greeter-client 103 | env: 104 | ZOOKEEPER_SERVERS: 127.0.0.1:2181 105 | DUBBO_CONFIG_PATH: ./application.yaml 106 | working-directory: examples/greeter 107 | -------------------------------------------------------------------------------- /.github/workflows/licence-checker.yml: -------------------------------------------------------------------------------- 1 | # 2 | # Licensed to the Apache Software Foundation (ASF) under one 3 | # or more contributor license agreements. See the NOTICE file 4 | # distributed with this work for additional information 5 | # regarding copyright ownership. The ASF licenses this file 6 | # to you under the Apache License, Version 2.0 (the 7 | # "License"); you may not use this file except in compliance 8 | # with the License. You may obtain a copy of the License at 9 | # 10 | # http://www.apache.org/licenses/LICENSE-2.0 11 | # 12 | # Unless required by applicable law or agreed to in writing, 13 | # software distributed under the License is distributed on an 14 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 | # KIND, either express or implied. See the License for the 16 | # specific language governing permissions and limitations 17 | # under the License. 18 | # 19 | 20 | name: License checker 21 | 22 | on: 23 | push: 24 | branches: 25 | - main 26 | pull_request: 27 | branches: 28 | - main 29 | pull_request_target: 30 | branches: 31 | - main 32 | 33 | jobs: 34 | check-license: 35 | runs-on: ubuntu-latest 36 | steps: 37 | - uses: actions/checkout@v2 38 | - name: Check License Header 39 | uses: apache/skywalking-eyes/header@501a28d2fb4a9b962661987e50cf0219631b32ff 40 | with: 41 | log: info 42 | config: .licenserc.yaml 43 | - name: Check Dependencies' License 44 | uses: apache/skywalking-eyes/dependency@main 45 | with: 46 | log: info -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | target 2 | Cargo.lock 3 | **/*.rs.bk 4 | .vscode/ 5 | .idea/ 6 | helloworld 7 | .DS_Store 8 | -------------------------------------------------------------------------------- /.rustfmt.toml: -------------------------------------------------------------------------------- 1 | unstable_features = true 2 | format_generated_files = false 3 | imports_granularity = "Crate" 4 | reorder_imports = true 5 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | Contributing to dubbo-rust 2 | 3 | ## 1. Branch 4 | 5 | >- The name of branches `SHOULD` be in the format of `feature/xxx`. 6 | >- You `SHOULD` checkout a new branch after a feature branch already being merged into upstream, `DO NOT` commit in the old branch. 7 | 8 | ## 2. Pull Request 9 | 10 | ### 2.1. Title Format 11 | 12 | The pr head format is ` `. The title should be simpler to show your intent. 13 | 14 | The title format of the pull request `MUST` follow the following rules: 15 | 16 | >- Start with `Doc:` for adding/formatting/improving docs. 17 | >- Start with `Mod:` for formatting codes or adding comment. 18 | >- Start with `Fix:` for fixing bug, and its ending should be ` #issue-id` if being relevant to some issue. 19 | >- Start with `Imp:` for improving performance. 20 | >- Start with `Ftr:` for adding a new feature. 21 | >- Start with `Add:` for adding struct function/member. 22 | >- Start with `Rft:` for refactoring codes. 23 | >- Start with `Tst:` for adding tests. 24 | >- Start with `Dep:` for adding depending libs. 25 | >- Start with `Rem:` for removing feature/struct/function/member/files. 26 | 27 | ## 3. Code Style 28 | 29 | ### 3.1 log 30 | 31 | > 1 when logging the function's input parameter, you should add '@' before input parameter name. 32 | 33 | ## 4. Dev 34 | 35 | ### 4.1 Formating 36 | 37 | Currently, dubbo-rust recommand using rustfmt nightly version for formating: 38 | 1. `rustup toolchain install nightly --component rustfmt` 39 | 2. configure `settings.json`: 40 | ```json 41 | { 42 | "rust-analyzer.rustfmt.overrideCommand": ["cargo", "+nightly", "fmt"] 43 | } 44 | ``` 45 | 46 | ### 4.2 Debugging 47 | 48 | Example launch configuration: 49 | ```json 50 | { 51 | "type": "lldb", 52 | "request": "launch", 53 | "name": "greeter-server", 54 | "program": "${workspaceFolder}/target/debug/greeter-server", 55 | "args": [], 56 | "cwd": "${workspaceFolder}/examples/greeter/", 57 | "terminal": "console", 58 | "env": { 59 | "ZOOKEEPER_SERVERS": "mse-21b397d4-p.zk.mse.aliyuncs.com:2181", 60 | } 61 | } 62 | ``` 63 | -------------------------------------------------------------------------------- /Cargo.toml: -------------------------------------------------------------------------------- 1 | [workspace] 2 | resolver = "2" 3 | members = [ 4 | "registry/zookeeper", 5 | "registry/nacos", 6 | "dubbo", 7 | "examples/echo", 8 | "examples/greeter", 9 | "dubbo-build", 10 | ] 11 | 12 | 13 | [workspace.dependencies] 14 | pin-project = "1" 15 | tokio = "1.0" 16 | tower = "0.4" 17 | tower-service = "0.3.1" 18 | tower-layer = "0.3" 19 | tokio-stream = "0.1" 20 | tokio-util = "0.7" 21 | socket2 = "0.4" 22 | async-trait = "0.1" 23 | dashmap = "5" 24 | lazy_static = "1" 25 | futures = "0.3" 26 | serde = "1" 27 | serde_json = "1" 28 | urlencoding = "2.1.2" 29 | registry-zookeeper = {path="./registry/zookeeper"} 30 | registry-nacos = {path="./registry/nacos"} 31 | anyhow = "1.0.66" 32 | thiserror = "1.0.30" 33 | dubbo = { path = "./dubbo/" } 34 | bb8 = "0.8.0" # A connecton pool based on tokio 35 | serde_yaml = "0.9.4" # yaml file parser 36 | once_cell = "1.16.0" 37 | itertools = "0.10.1" 38 | bytes = "1.0" 39 | prost-serde = "0.3.0" 40 | prost-serde-derive = "0.1.2" 41 | url = "2.5.0" 42 | -------------------------------------------------------------------------------- /NOTICE: -------------------------------------------------------------------------------- 1 | Apache Dubbo 2 | Copyright 2018-2024 The Apache Software Foundation 3 | 4 | This product includes software developed at 5 | The Apache Software Foundation (http://www.apache.org/). 6 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Apache Dubbo-rust 2 | 3 | 4 | logo 5 | 6 | Apache Dubbo-rust, an RPC framework that implements Dubbo written in Rust.Please visit the [official website](https://dubbo.apache.org/) for more information. 7 | 8 | [![Build Status](https://img.shields.io/github/actions/workflow/status/apache/dubbo-rust/.github/workflows/github-actions.yml?branch=main&style=flat-square)](https://github.com/apache/dubbo-rust/actions/workflows/github-actions.yml?query=branch%3Amain) 9 | ![License](https://img.shields.io/github/license/apache/dubbo-rust?style=flat-square) 10 | 11 | [ [中文](./README_CN.md) ] 12 | 13 | ## Overview 14 | 15 | Dubbo-rust is still under development. For now, gRPC calls based on HTTP2 have been implemented. 16 | 17 | The following libraries are mainly dependent on: 18 | 19 | - [`Tokio`](https://github.com/tokio-rs/tokio) is an event-driven, non-blocking I/O platform for writing asynchronous applications with Rust. 20 | 21 | - [`Prost`](https://github.com/tokio-rs/prost/) is a [Protocol Buffers](https://developers.google.com/protocol-buffers/) implementation for Rust. 22 | 23 | - [`Hyper`](https://github.com/hyperium/hyper) is a fast and correct HTTP implementation for Rust. 24 | 25 | - [`Serde`](https://github.com/serde-rs/serde) is a framework for *ser*ializing and *de*serializing Rust data structures efficiently and generically. 26 | 27 | ## Features 28 | 29 | - :white_check_mark: RPC synchronous / asynchronous call 30 | - :white_check_mark: IDL code automatic generation 31 | - :construction: Multiple RPC protocol support (like Triple, Dubbo, gRPC, JSONRPC) 32 | - :construction: Support TCP/HTTP2 transport protocol 33 | - :construction: Service registration and discovery 34 | 35 | ## Get started 36 | 37 | - Dubbo-rust Quick Start: [中文](https://dubbo.apache.org/zh/docs3-v2/rust-sdk/quick-start/), English 38 | - Dubbo-rust Tutorials: [Examples](https://github.com/apache/dubbo-rust/tree/main/examples) 39 | 40 | ## Project structure 41 | 42 | ``` 43 | . 44 | ├── Cargo.toml 45 | ├── LICENSE 46 | ├── README.md 47 | ├── README_CN.md 48 | ├── common 49 | │   ├── Cargo.toml 50 | │   └── src 51 | │   └── lib.rs 52 | ├── config 53 | │   ├── Cargo.toml 54 | │   └── src 55 | │   ├── config.rs 56 | │   ├── lib.rs 57 | │   ├── protocol.rs 58 | │   └── service.rs 59 | ├── contributing.md 60 | ├── docs 61 | │   ├── filter-design.md 62 | │   ├── generic-protocol-design.md 63 | │   ├── readme.md 64 | │   └── services.md 65 | more ... 66 | ``` 67 | 68 | ## Contact Us 69 | 70 | - Subscribe to the official Wechat Account 71 | ![officialAccount](https://user-images.githubusercontent.com/18097545/201456442-68a7bf1e-3c84-4f32-bd45-0fedb4d1012d.png) 72 | 73 | - Search and join the DingTalk group: 44694199 74 | 75 | ## Contribute 76 | 77 | Welcome more developers to join us. About more details please check "[How to contribute](https://github.com/apache/dubbo-rust/blob/main/CONTRIBUTING.md)". 78 | 79 | ## License 80 | 81 | Apache Dubbo-rust software is licenced under the Apache License Version 2.0. See the [LICENSE](https://github.com/apache/dubbo-rust/blob/main/LICENSE) file for details. 82 | -------------------------------------------------------------------------------- /README_CN.md: -------------------------------------------------------------------------------- 1 | # Apache Dubbo-rust 2 | 3 | 4 | logo 5 | 6 | Apache Dubbo-rust, Dubbo RPC框架的Rust实现。请访问 [Dubbo官网](https://dubbo.apache.org/) 查看更多信息. 7 | 8 | [![Build Status](https://img.shields.io/github/actions/workflow/status/apache/dubbo-rust/.github/workflows/github-actions.yml?branch=main&style=flat-square)](https://github.com/apache/dubbo-rust/actions/workflows/github-actions.yml?query=branch%3Amain) 9 | ![License](https://img.shields.io/github/license/apache/dubbo-rust?style=flat-square) 10 | 11 | ## 概述 12 | 13 | Dubbo-rust 目前还在开发阶段. 截至目前, 已经实现了基于HTTP2的gRPC调用. 14 | 15 | 以下为主要的依赖库: 16 | 17 | - [`Tokio`](https://github.com/tokio-rs/tokio) 使用Rust编写事件驱动、无阻塞I/O异步程序的框架。 18 | 19 | - [`Prost`](https://github.com/tokio-rs/prost/) [Protocol Buffers](https://developers.google.com/protocol-buffers/) Rust实现。 20 | 21 | - [`Hyper`](https://github.com/hyperium/hyper) 构建HTTP协议的Rust库。 22 | 23 | - [`Serde`](https://github.com/serde-rs/serde) 序列化/反序列化Rust库 24 | 25 | ## 功能列表 26 | 27 | - :white_check_mark: RPC 异步/同步调用 28 | - :white_check_mark: IDL文件代码生成器 29 | - :construction: RPC多协议支持(如: Triple, Dubbo, gRPC, JSONRPC) 30 | - :construction: 支持 TCP/HTTP2 传输层协议 31 | - :construction: 服务注册与发现 32 | 33 | ## 开始使用 34 | 35 | - Dubbo-rust 快速开始: [中文](https://dubbo.apache.org/zh/docs3-v2/rust-sdk/quick-start/), English 36 | - Dubbo-rust 教程: [Examples](examples/README.md) 37 | 38 | ## 项目结构 39 | 40 | ``` 41 | . 42 | ├── Cargo.toml 43 | ├── LICENSE 44 | ├── README.md 45 | ├── README_CN.md 46 | ├── common 47 | │   ├── Cargo.toml 48 | │   └── src 49 | │   └── lib.rs 50 | ├── config 51 | │   ├── Cargo.toml 52 | │   └── src 53 | │   ├── config.rs 54 | │   ├── lib.rs 55 | │   ├── protocol.rs 56 | │   └── service.rs 57 | ├── contributing.md 58 | ├── docs 59 | │   ├── filter-design.md 60 | │   ├── generic-protocol-design.md 61 | │   ├── readme.md 62 | │   └── services.md 63 | more ... 64 | ``` 65 | 66 | ## 联系方式 67 | 68 | - 订阅官方微信公众号 69 | ![officialAccount](https://user-images.githubusercontent.com/18097545/201456442-68a7bf1e-3c84-4f32-bd45-0fedb4d1012d.png) 70 | 71 | - 搜索并加入钉钉群组: 44694199 72 | 73 | ## 贡献 74 | 75 | 欢迎更多的开发者加入我们。关于更多的信息可以查看 [[CONTRIBUTING](https://github.com/apache/dubbo-rust/blob/main/CONTRIBUTING.md)]。 76 | 77 | ## 许可证 78 | 79 | Apache Dubbo-rust 使用Apache许可证2.0版本。 请参考 [LICENSE](https://github.com/apache/dubbo-rust/blob/main/LICENSE) 文件获得更多信息。 80 | -------------------------------------------------------------------------------- /application.yaml: -------------------------------------------------------------------------------- 1 | logging: 2 | level: debug 3 | dubbo: 4 | protocols: 5 | triple: 6 | ip: 0.0.0.0 7 | port: '8888' 8 | name: tri 9 | registries: 10 | demoZK: 11 | protocol: zookeeper 12 | address: 0.0.0.0:2181 13 | provider: 14 | services: 15 | GreeterProvider: 16 | tag: red 17 | version: 1.0.0 18 | group: test 19 | protocol: triple 20 | interface: org.apache.dubbo.sample.tri.Greeter 21 | consumer: 22 | references: 23 | GreeterClientImpl: 24 | url: tri://localhost:20000 25 | protocol: tri 26 | routers: 27 | consumer: 28 | - service: "org.apache.dubbo.sample.tri.Greeter" 29 | url: tri://127.0.0.1:20000 30 | protocol: triple -------------------------------------------------------------------------------- /docs/config.md: -------------------------------------------------------------------------------- 1 | ## 关于配置的一些约定(暂时) 2 | 3 | 所有的服务只能注册到一个或多个注册中心 4 | 所有的服务只能使用Triple进行通信 5 | Triple只能对外暴露一个端口 6 | 7 | ## Config配置 8 | 9 | 每个组件的配置是独立的。 10 | 11 | Provider、Consumer等使用独立组件的配置进行工作 12 | 13 | Provider Config核心设计以及Url模型流转: 14 | 15 | Provider和Consumer使用组件的配置 -------------------------------------------------------------------------------- /docs/filter-design.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/apache/dubbo-rust/026c4971346e5a21514500d261de5838f0be4d1a/docs/filter-design.md -------------------------------------------------------------------------------- /docs/generic-protocol-design.md: -------------------------------------------------------------------------------- 1 | author: Yang Yang 2 | date: 2022-06-26 3 | 4 | ## 简介 5 | 6 | dubbo-rust支持多种协议:Triple、gRPC、jsonRPC等 7 | 8 | ## Protocol设计 9 | 10 | Protocol的核心设计是基于dubbo的URL模型,对外暴露通用的服务端和客户端抽象接口。 11 | 12 | 在Dubbo的整体生态中,服务端接口使用`Exporter`来描述;客户端接口使用`Invoker`来描述。 13 | 14 | Protocol模块的核心功能: 15 | + 对外提供服务注册接口 16 | + 管理注册的服务:run, destroy, stop, gracefulStop 17 | + 接口路由 18 | + 通用、高效的Listener层 19 | + 等等 20 | 21 | Protocol API支持管理多个底层协议的server以及在一个server上暴露多个服务 22 | + 多个底层通信的server:location(ip:port): server 23 | + 一个server上暴露多个服务: 24 | 25 | ### Exporter 26 | 27 | ### Invoker 28 | 29 | Invoker: 客户端通用能力的封装。获取需要一个private withInvoker 接口 30 | 31 | Invoker应该是基于Connection(Service)实现的Service。并且进行扩展新的接口。 32 | protocol.rs模块:根据Url返回初始化好的Invoker实例。 33 | + 如何设计Invoker接口:扩展Service接口 34 | + cluster模块如何使用Invoker实例呢?这里需要画一个数据流转图 35 | + 如何将初始化好的Invoker与tower::Layer相结合 36 | 37 | Invoker提供的通用的接口,使得dubbo在不同的协议下遵循相同的接口抽象。 38 | 39 | 在Invoker中,需要做的功能包括 40 | + 编解码层 41 | + Streaming trait实现 42 | + 自定义请求/响应 43 | + 等等 44 | 45 | ## 目前存在的问题 46 | 47 | + 如何管理服务:服务是动态的,需要保证Server是Send+Sync的 -------------------------------------------------------------------------------- /docs/how-to-release.md: -------------------------------------------------------------------------------- 1 | # 如何发布dubbo-rust的新版本 2 | 3 | ## 前置条件 4 | 5 | 安装[cargo-release](https://crates.io/crates/cargo-release): 6 | ```shell 7 | $ cargo install cargo-release 8 | ``` 9 | 10 | 登录 crates.io 11 | 12 | ```shell 13 | $ cargo login 14 | ``` 15 | 16 | ## 如何发布一个新版本 17 | 18 | 1. 更新版本号: 19 | ```shell 20 | $ cargo release version minor 21 | $ cargo release version minor --execute 22 | ``` 23 | 24 | 2. 提交 25 | ```shell 26 | $ cargo release commit 27 | $ cargo release commit --execute 28 | ``` 29 | 30 | 3. 打tag: 31 | ```shell 32 | $ cargo release tag 33 | $ cargo release tag --execute 34 | ``` 35 | 36 | 4. push tag: 37 | ```shell 38 | $ cargo release push 39 | $ cargo release push --execute 40 | ``` 41 | 42 | 5. 在邮件列表发起投票 43 | 44 | 例子: 45 | 46 | 6. 发布到 crates.io 47 | 48 | ```shell 49 | $ cargo release publish 50 | $ cargo release publish --execute 51 | ``` 52 | -------------------------------------------------------------------------------- /docs/images/examples/client.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/apache/dubbo-rust/026c4971346e5a21514500d261de5838f0be4d1a/docs/images/examples/client.png -------------------------------------------------------------------------------- /docs/images/examples/dir-server.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/apache/dubbo-rust/026c4971346e5a21514500d261de5838f0be4d1a/docs/images/examples/dir-server.png -------------------------------------------------------------------------------- /docs/images/examples/server.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/apache/dubbo-rust/026c4971346e5a21514500d261de5838f0be4d1a/docs/images/examples/server.png -------------------------------------------------------------------------------- /docs/readme.md: -------------------------------------------------------------------------------- 1 | # Readme 2 | 3 | There is some RFCs of dubbo-rust design. 4 | 5 | ## 关于配置的一些约定(暂时) 6 | 7 | 所有的服务只能注册到一个或多个注册中心 8 | 所有的服务只能使用Triple进行通信 9 | Triple只能对外暴露一个端口 10 | 11 | 一个协议上的server注册到 -------------------------------------------------------------------------------- /docs/services.md: -------------------------------------------------------------------------------- 1 | # Services模块设计 2 | 3 | > 模块名待定 4 | 5 | 该模块负责管理整个框架的生命周期,包括: 6 | + 服务注册 7 | + 服务启动 8 | + 服务停止 9 | + 服务治理插件初始化 10 | + meta服务 11 | + xds服务 -------------------------------------------------------------------------------- /dubbo-build/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "dubbo-build" 3 | version = "0.4.0" 4 | edition = "2021" 5 | license = "Apache-2.0" 6 | description = "dubbo-build" 7 | documentation = "https://github.com/apache/dubbo-rust" 8 | repository = "https://github.com/apache/dubbo-rust.git" 9 | 10 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 11 | 12 | [dependencies] 13 | prost = "0.11.9" 14 | prettyplease = {version = "0.1"} 15 | proc-macro2 = "1.0" 16 | quote = "1.0" 17 | syn = "1.0" 18 | prost-build = "0.11.9" 19 | -------------------------------------------------------------------------------- /dubbo/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "dubbo" 3 | version = "0.4.0" 4 | edition = "2021" 5 | license = "Apache-2.0" 6 | description = "dubbo" 7 | documentation = "https://github.com/apache/dubbo-rust" 8 | repository = "https://github.com/apache/dubbo-rust.git" 9 | 10 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 11 | 12 | [dependencies] 13 | hyper = { version = "0.14.26", features = ["full"] } 14 | http = "0.2" 15 | tower-service.workspace = true 16 | http-body = "0.4.4" 17 | tower = { workspace = true, features = ["timeout", "ready-cache","discover","retry"] } 18 | futures-util = "0.3.23" 19 | futures-core ="0.3.23" 20 | argh = "0.1" 21 | rustls-pemfile = "1.0.0" 22 | rustls-webpki = "0.101.3" 23 | rustls-native-certs = "0.6.3" 24 | tokio-rustls="0.24.1" 25 | tokio = { version = "1.0", features = [ "rt-multi-thread", "time", "fs", "macros", "net", "signal", "full" ] } 26 | prost = "0.11.9" 27 | tokio-util = "0.7.9" 28 | tokio-stream = "0.1" 29 | async-trait = "0.1.56" 30 | tower-layer.workspace = true 31 | bytes.workspace = true 32 | pin-project.workspace = true 33 | rand = "0.8.5" 34 | serde_json.workspace = true 35 | serde = { workspace = true, features = ["derive"] } 36 | futures.workspace = true 37 | axum = "0.5.9" 38 | async-stream = "0.3" 39 | flate2 = "1.0" 40 | aws-smithy-http = "0.55.2" 41 | dyn-clone = "1.0.11" 42 | itertools.workspace = true 43 | urlencoding.workspace = true 44 | lazy_static.workspace = true 45 | once_cell.workspace = true 46 | tracing = "0.1" 47 | tracing-subscriber = "0.3" 48 | project-root = "0.2.2" 49 | anyhow.workspace=true 50 | url.workspace = true 51 | 52 | #对象存储 53 | state = { version = "0.5", features = ["tls"] } 54 | thiserror = "1.0.48" 55 | regex = "1.9.1" 56 | nacos-sdk = { version = "0.3.0", features = ["default"] } 57 | serde_yaml = "0.9.22" 58 | -------------------------------------------------------------------------------- /dubbo/README.md: -------------------------------------------------------------------------------- 1 | ../README.md -------------------------------------------------------------------------------- /dubbo/README_CN.md: -------------------------------------------------------------------------------- 1 | ../README_CN.md -------------------------------------------------------------------------------- /dubbo/src/cluster/failover.rs: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | 18 | use std::task::Poll; 19 | 20 | use crate::StdError; 21 | use futures_util::future; 22 | use http::Request; 23 | use tower::{retry::Retry, util::Oneshot, ServiceExt}; 24 | use tower_service::Service; 25 | 26 | pub struct Failover { 27 | inner: N, // loadbalancer service 28 | } 29 | 30 | #[derive(Clone)] 31 | pub struct FailoverPolicy; 32 | 33 | impl Failover { 34 | pub fn new(inner: N) -> Self { 35 | Self { inner } 36 | } 37 | } 38 | 39 | impl tower::retry::Policy, Res, E> for FailoverPolicy 40 | where 41 | B: http_body::Body + Clone, 42 | { 43 | type Future = future::Ready; 44 | 45 | fn retry(&self, _req: &Request, result: Result<&Res, &E>) -> Option { 46 | //TODO some error handling or logging 47 | match result { 48 | Ok(_) => None, 49 | Err(_) => Some(future::ready(self.clone())), 50 | } 51 | } 52 | 53 | fn clone_request(&self, req: &Request) -> Option> { 54 | let mut clone = http::Request::new(req.body().clone()); 55 | *clone.method_mut() = req.method().clone(); 56 | *clone.uri_mut() = req.uri().clone(); 57 | *clone.headers_mut() = req.headers().clone(); 58 | *clone.version_mut() = req.version(); 59 | 60 | Some(clone) 61 | } 62 | } 63 | 64 | impl Service> for Failover 65 | where 66 | // B is CloneBody 67 | B: http_body::Body + Clone, 68 | // loadbalancer service 69 | N: Service> + Clone + 'static, 70 | N::Error: Into, 71 | N::Future: Send, 72 | { 73 | type Response = N::Response; 74 | 75 | type Error = N::Error; 76 | 77 | type Future = Oneshot, Request>; 78 | 79 | fn poll_ready(&mut self, cx: &mut std::task::Context<'_>) -> Poll> { 80 | self.inner.poll_ready(cx) 81 | } 82 | 83 | fn call(&mut self, req: Request) -> Self::Future { 84 | let retry = Retry::new(FailoverPolicy, self.inner.clone()); 85 | retry.oneshot(req) 86 | } 87 | } 88 | -------------------------------------------------------------------------------- /dubbo/src/cluster/mod.rs: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | 18 | use http::Request; 19 | use tower_service::Service; 20 | 21 | use crate::{ 22 | codegen::RpcInvocation, invoker::clone_body::CloneBody, param::Param, svc::NewService, 23 | }; 24 | 25 | use self::failover::Failover; 26 | 27 | mod failover; 28 | 29 | pub struct NewCluster { 30 | inner: N, // new loadbalancer service 31 | } 32 | 33 | pub struct Cluster { 34 | inner: S, // failover service 35 | } 36 | 37 | impl NewCluster { 38 | pub fn layer() -> impl tower_layer::Layer { 39 | tower_layer::layer_fn(|inner: N| { 40 | NewCluster { 41 | inner, // new loadbalancer service 42 | } 43 | }) 44 | } 45 | } 46 | 47 | impl NewService for NewCluster 48 | where 49 | T: Param, 50 | // new loadbalancer service 51 | S: NewService, 52 | { 53 | type Service = Cluster>; 54 | 55 | fn new_service(&self, target: T) -> Self::Service { 56 | Cluster { 57 | inner: Failover::new(self.inner.new_service(target)), 58 | } 59 | } 60 | } 61 | 62 | impl Service> for Cluster 63 | where 64 | S: Service>, 65 | { 66 | type Response = S::Response; 67 | 68 | type Error = S::Error; 69 | 70 | type Future = S::Future; 71 | 72 | fn poll_ready( 73 | &mut self, 74 | cx: &mut std::task::Context<'_>, 75 | ) -> std::task::Poll> { 76 | self.inner.poll_ready(cx) 77 | } 78 | 79 | fn call(&mut self, req: Request) -> Self::Future { 80 | let (parts, body) = req.into_parts(); 81 | let clone_body = CloneBody::new(body); 82 | let req = Request::from_parts(parts, clone_body); 83 | self.inner.call(req) 84 | } 85 | } 86 | -------------------------------------------------------------------------------- /dubbo/src/cluster/router/condition/condition_router.rs: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | 18 | use crate::{ 19 | cluster::router::{condition::single_router::ConditionSingleRouter, Router}, 20 | codegen::RpcInvocation, 21 | }; 22 | use crate::Url; 23 | use std::{ 24 | fmt::Debug, 25 | sync::{Arc, RwLock}, 26 | }; 27 | 28 | #[derive(Default, Debug, Clone)] 29 | pub struct ConditionRouter { 30 | //condition router for service scope 31 | pub service_routers: Option>>, 32 | //condition router for application scope 33 | pub application_routers: Option>>, 34 | } 35 | 36 | impl Router for ConditionRouter { 37 | fn route(&self, mut invokers: Vec, url: Url, invo: Arc) -> Vec { 38 | if let Some(routers) = &self.application_routers { 39 | for router in &routers.read().unwrap().routers { 40 | invokers = router.route(invokers, url.clone(), invo.clone()); 41 | } 42 | } 43 | if let Some(routers) = &self.service_routers { 44 | for router in &routers.read().unwrap().routers { 45 | invokers = router.route(invokers, url.clone(), invo.clone()); 46 | } 47 | } 48 | invokers 49 | } 50 | } 51 | 52 | impl ConditionRouter { 53 | pub fn new( 54 | service_routers: Option>>, 55 | application_routers: Option>>, 56 | ) -> Self { 57 | Self { 58 | service_routers, 59 | application_routers, 60 | } 61 | } 62 | } 63 | 64 | #[derive(Debug, Clone, Default)] 65 | pub struct ConditionSingleRouters { 66 | pub routers: Vec, 67 | } 68 | 69 | impl ConditionSingleRouters { 70 | pub fn new(routers: Vec) -> Self { 71 | Self { routers } 72 | } 73 | pub fn is_null(&self) -> bool { 74 | self.routers.is_empty() 75 | } 76 | } 77 | -------------------------------------------------------------------------------- /dubbo/src/cluster/router/condition/matcher.rs: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | 18 | use regex::Regex; 19 | use std::{collections::HashSet, error::Error, option::Option}; 20 | 21 | #[derive(Clone, Debug, Default)] 22 | pub struct ConditionMatcher { 23 | _key: String, 24 | matches: HashSet, 25 | mismatches: HashSet, 26 | } 27 | 28 | impl ConditionMatcher { 29 | pub fn new(_key: String) -> Self { 30 | ConditionMatcher { 31 | _key, 32 | matches: HashSet::new(), 33 | mismatches: HashSet::new(), 34 | } 35 | } 36 | 37 | pub fn is_match(&self, value: Option) -> Result> { 38 | match value { 39 | None => Ok(false), 40 | Some(val) => { 41 | for match_ in self.matches.iter() { 42 | if self.do_pattern_match(match_, &val) { 43 | return Ok(true); 44 | } 45 | } 46 | for mismatch in self.mismatches.iter() { 47 | if !self.do_pattern_match(mismatch, &val) { 48 | return Ok(true); 49 | } 50 | } 51 | Ok(false) 52 | } 53 | } 54 | } 55 | 56 | pub fn get_matches(&mut self) -> &mut HashSet { 57 | &mut self.matches 58 | } 59 | pub fn get_mismatches(&mut self) -> &mut HashSet { 60 | &mut self.mismatches 61 | } 62 | 63 | fn do_pattern_match(&self, pattern: &str, value: &str) -> bool { 64 | if pattern.contains('*') { 65 | return star_matcher(pattern, value); 66 | } 67 | 68 | if pattern.contains('~') { 69 | let parts: Vec<&str> = pattern.split('~').collect(); 70 | 71 | if parts.len() == 2 { 72 | if let (Ok(left), Ok(right), Ok(val)) = ( 73 | parts[0].parse::(), 74 | parts[1].parse::(), 75 | value.parse::(), 76 | ) { 77 | return range_matcher(val, left, right); 78 | } 79 | } 80 | return false; 81 | } 82 | pattern == value 83 | } 84 | } 85 | 86 | pub fn star_matcher(pattern: &str, input: &str) -> bool { 87 | // 将*替换为任意字符的正则表达式 88 | let pattern = pattern.replace("*", ".*"); 89 | let regex = Regex::new(&pattern).unwrap(); 90 | regex.is_match(input) 91 | } 92 | 93 | pub fn range_matcher(val: i32, min: i32, max: i32) -> bool { 94 | min <= val && val <= max 95 | } 96 | -------------------------------------------------------------------------------- /dubbo/src/cluster/router/condition/mod.rs: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | pub mod condition_router; 18 | pub mod matcher; 19 | pub mod single_router; 20 | -------------------------------------------------------------------------------- /dubbo/src/cluster/router/manager/mod.rs: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | mod condition_manager; 18 | pub mod router_manager; 19 | mod tag_manager; 20 | -------------------------------------------------------------------------------- /dubbo/src/cluster/router/manager/tag_manager.rs: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | 18 | use crate::cluster::router::tag::tag_router::{TagRouter, TagRouterInner}; 19 | use dubbo_config::router::TagRouterConfig; 20 | use std::sync::{Arc, RwLock}; 21 | 22 | #[derive(Debug, Clone, Default)] 23 | pub struct TagRouterManager { 24 | pub tag_router: Arc>, 25 | } 26 | 27 | impl TagRouterManager { 28 | pub fn get_router(&self, _service_name: &String) -> Option { 29 | Some(TagRouter { 30 | inner: self.tag_router.clone(), 31 | }) 32 | } 33 | 34 | pub fn update(&mut self, config: TagRouterConfig) { 35 | self.tag_router.write().unwrap().parse_config(config); 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /dubbo/src/cluster/router/mod.rs: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | pub mod condition; 18 | pub mod manager; 19 | pub mod nacos_config_center; 20 | pub mod router_chain; 21 | pub mod tag; 22 | pub mod utils; 23 | 24 | use crate::invocation::RpcInvocation; 25 | use crate::Url; 26 | use std::{fmt::Debug, sync::Arc}; 27 | 28 | pub trait Router: Debug { 29 | fn route(&self, invokers: Vec, url: Url, invocation: Arc) -> Vec; 30 | } 31 | 32 | pub type BoxRouter = Box; 33 | 34 | #[derive(Debug, Default, Clone)] 35 | pub struct MockRouter {} 36 | 37 | impl Router for MockRouter { 38 | fn route(&self, invokers: Vec, _url: Url, _invocation: Arc) -> Vec { 39 | invokers 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /dubbo/src/cluster/router/nacos_config_center/mod.rs: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | pub mod nacos_client; 18 | -------------------------------------------------------------------------------- /dubbo/src/cluster/router/router_chain.rs: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | 18 | use crate::{cluster::router::BoxRouter, invocation::RpcInvocation}; 19 | use url::Url; 20 | use std::{collections::HashMap, sync::Arc}; 21 | 22 | #[derive(Debug, Default)] 23 | pub struct RouterChain { 24 | pub routers: HashMap, 25 | pub self_url: Url, 26 | } 27 | 28 | impl RouterChain { 29 | pub fn new() -> Self { 30 | RouterChain { 31 | routers: HashMap::new(), 32 | self_url: Url::new(), 33 | } 34 | } 35 | 36 | pub fn route(&self, mut invokers: Vec, invocation: Arc) -> Vec { 37 | for (_, value) in self.routers.iter() { 38 | invokers = value.route(invokers, self.self_url.clone(), invocation.clone()) 39 | } 40 | invokers 41 | } 42 | 43 | pub fn add_router(&mut self, key: String, router: BoxRouter) { 44 | self.routers.insert(key, router); 45 | } 46 | } 47 | 48 | #[test] 49 | fn test() { 50 | use crate::cluster::router::manager::router_manager::get_global_router_manager; 51 | 52 | let u1 = Url::from_url("tri://127.0.0.1:8888/org.apache.dubbo.sample.tri.Greeter").unwrap(); 53 | let u2 = Url::from_url("tri://127.0.0.1:8889/org.apache.dubbo.sample.tri.Greeter").unwrap(); 54 | let u3 = Url::from_url("tri://127.0.0.1:8800/org.apache.dubbo.sample.tri.Greeter").unwrap(); 55 | let u4 = Url::from_url("tri://127.0.2.1:8880/org.apache.dubbo.sample.tri.Greeter").unwrap(); 56 | let u5 = Url::from_url("tri://127.0.1.1:8882/org.apache.dubbo.sample.tri.Greeter").unwrap(); 57 | let u6 = Url::from_url("tri://213.0.1.1:8888/org.apache.dubbo.sample.tri.Greeter").unwrap(); 58 | let u7 = Url::from_url("tri://169.0.1.1:8887/org.apache.dubbo.sample.tri.Greeter").unwrap(); 59 | let invs = vec![u1, u2, u3, u4, u5, u6, u7]; 60 | let len = invs.len().clone(); 61 | let inv = Arc::new( 62 | RpcInvocation::default() 63 | .with_method_name("greet".to_string()) 64 | .with_service_unique_name("org.apache.dubbo.sample.tri.Greeter".to_string()), 65 | ); 66 | let x = get_global_router_manager() 67 | .read() 68 | .unwrap() 69 | .get_router_chain(inv.get_target_service_unique_name()); 70 | let result = x.route(invs, inv.clone()); 71 | println!("total:{},result:{}", len, result.len().clone()); 72 | dbg!(result); 73 | } 74 | -------------------------------------------------------------------------------- /dubbo/src/cluster/router/tag/mod.rs: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | pub mod tag_router; 18 | -------------------------------------------------------------------------------- /dubbo/src/cluster/router/utils.rs: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | 18 | use crate::Url; 19 | use std::{collections::HashMap, string::String}; 20 | 21 | pub fn to_original_map(url: Url) -> HashMap { 22 | let mut result: HashMap = HashMap::new(); 23 | result.insert("scheme".parse().unwrap(), url.scheme); 24 | result.insert("location".parse().unwrap(), url.location); 25 | result.insert("ip".parse().unwrap(), url.ip); 26 | result.insert("port".parse().unwrap(), url.port); 27 | result.insert("service_name".parse().unwrap(), url.service_name); 28 | result.insert("service_key".parse().unwrap(), url.service_key); 29 | for (key, value) in url.params { 30 | result.insert(key, value); 31 | } 32 | result 33 | } 34 | -------------------------------------------------------------------------------- /dubbo/src/codegen.rs: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | 18 | pub use std::{ 19 | sync::Arc, 20 | task::{Context, Poll}, 21 | }; 22 | 23 | pub use crate::StdError; 24 | pub use async_trait::async_trait; 25 | pub use bytes::Bytes; 26 | pub use http_body::Body; 27 | pub use hyper::Body as hyperBody; 28 | pub use tower_service::Service; 29 | 30 | pub use super::{ 31 | empty_body, 32 | invocation::{IntoStreamingRequest, Metadata, Request, Response, RpcInvocation}, 33 | protocol::{triple::triple_invoker::TripleInvoker, Invoker}, 34 | triple::{ 35 | client::TripleClient, 36 | codec::{prost::ProstCodec, serde_codec::SerdeCodec, Codec}, 37 | decode::Decoding, 38 | server::{ 39 | service::{ClientStreamingSvc, ServerStreamingSvc, StreamingSvc, UnarySvc}, 40 | TripleServer, 41 | }, 42 | }, 43 | BoxBody, BoxFuture, 44 | }; 45 | pub use crate::{ 46 | filter::{service::FilterService, Filter}, 47 | triple::{ 48 | client::builder::ClientBuilder, server::builder::ServerBuilder, 49 | transport::connection::Connection, 50 | }, 51 | }; 52 | -------------------------------------------------------------------------------- /dubbo/src/config/mod.rs: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | 18 | pub use config::*; 19 | 20 | pub mod config; 21 | pub mod protocol; 22 | pub mod provider; 23 | pub mod registry; 24 | pub mod router; 25 | pub mod service; 26 | -------------------------------------------------------------------------------- /dubbo/src/config/protocol.rs: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | 18 | use std::collections::HashMap; 19 | 20 | use serde::{Deserialize, Serialize}; 21 | 22 | pub const DEFAULT_PROTOCOL: &str = "triple"; 23 | 24 | #[derive(Default, Debug, Clone, Serialize, Deserialize)] 25 | pub struct Protocol { 26 | pub ip: String, 27 | pub port: String, 28 | pub name: String, 29 | 30 | #[serde(skip_serializing, skip_deserializing)] 31 | pub params: HashMap, 32 | } 33 | 34 | pub type ProtocolConfig = HashMap; 35 | 36 | pub trait ProtocolRetrieve { 37 | fn get_protocol(&self, protocol_key: &str) -> Option; 38 | fn get_protocol_or_default(&self, protocol_key: &str) -> Protocol; 39 | } 40 | 41 | impl Protocol { 42 | pub fn name(self, name: String) -> Self { 43 | Self { name, ..self } 44 | } 45 | 46 | pub fn ip(self, ip: String) -> Self { 47 | Self { ip, ..self } 48 | } 49 | 50 | pub fn port(self, port: String) -> Self { 51 | Self { port, ..self } 52 | } 53 | 54 | pub fn params(self, params: HashMap) -> Self { 55 | Self { params, ..self } 56 | } 57 | 58 | pub fn to_url(self) -> String { 59 | format!("{}://{}:{}", self.name, self.ip, self.port) 60 | } 61 | } 62 | 63 | impl ProtocolRetrieve for ProtocolConfig { 64 | fn get_protocol(&self, protocol_key: &str) -> Option { 65 | let result = self.get(protocol_key); 66 | if let Some(..) = result { 67 | Some(result.unwrap().clone()) 68 | } else { 69 | None 70 | } 71 | } 72 | 73 | fn get_protocol_or_default(&self, protocol_key: &str) -> Protocol { 74 | let result = self.get_protocol(protocol_key); 75 | if let Some(..) = result { 76 | result.unwrap() 77 | } else { 78 | let result = self.get_protocol(protocol_key); 79 | if let Some(..) = result { 80 | result.unwrap() 81 | } else { 82 | panic!("default triple base dose not defined.") 83 | } 84 | } 85 | } 86 | } 87 | 88 | #[cfg(test)] 89 | mod tests { 90 | 91 | use super::{ProtocolConfig, ProtocolRetrieve}; 92 | 93 | #[test] 94 | #[should_panic(expected = "default triple base dose not defined")] 95 | pub fn test_get_invalid_protocol() { 96 | let config = ProtocolConfig::default(); 97 | 98 | let _ = config.get_protocol_or_default(""); 99 | 100 | () 101 | } 102 | } 103 | -------------------------------------------------------------------------------- /dubbo/src/config/provider.rs: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | 18 | use std::collections::HashMap; 19 | 20 | use serde::{Deserialize, Serialize}; 21 | 22 | use super::service::ServiceConfig; 23 | 24 | #[derive(Debug, Default, Serialize, Deserialize, Clone)] 25 | pub struct ProviderConfig { 26 | #[serde(default)] 27 | pub registry_ids: Vec, 28 | #[serde(default)] 29 | pub protocol_ids: Vec, 30 | #[serde(default)] 31 | pub services: HashMap, 32 | } 33 | 34 | impl ProviderConfig { 35 | pub fn new() -> Self { 36 | ProviderConfig { 37 | registry_ids: vec![], 38 | protocol_ids: vec![], 39 | services: HashMap::new(), 40 | } 41 | } 42 | 43 | pub fn with_registry_ids(mut self, registry_ids: Vec) -> Self { 44 | self.registry_ids = registry_ids; 45 | self 46 | } 47 | 48 | pub fn with_protocol_ids(mut self, protocol_ids: Vec) -> Self { 49 | self.protocol_ids = protocol_ids; 50 | self 51 | } 52 | 53 | pub fn with_services(mut self, services: HashMap) -> Self { 54 | self.services = services; 55 | self 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /dubbo/src/config/registry.rs: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | use serde::{Deserialize, Serialize}; 18 | 19 | #[derive(Debug, Default, Serialize, Deserialize, Clone)] 20 | pub struct RegistryConfig { 21 | #[serde(default)] 22 | pub protocol: String, 23 | #[serde(default)] 24 | pub address: String, 25 | } 26 | -------------------------------------------------------------------------------- /dubbo/src/config/router.rs: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | 18 | use serde::{Deserialize, Serialize}; 19 | 20 | #[derive(Serialize, Deserialize, Debug, PartialEq, Clone, Default)] 21 | pub struct ConditionRouterConfig { 22 | #[serde(rename = "configVersion")] 23 | pub config_version: String, 24 | pub scope: String, 25 | pub force: bool, 26 | pub enabled: bool, 27 | pub key: String, 28 | pub conditions: Vec, 29 | } 30 | 31 | #[derive(Serialize, Deserialize, Default, Debug, Clone, PartialEq)] 32 | pub struct TagRouterConfig { 33 | #[serde(rename = "configVersion")] 34 | pub config_version: String, 35 | pub force: bool, 36 | pub enabled: bool, 37 | pub key: String, 38 | pub tags: Vec, 39 | } 40 | 41 | #[derive(Serialize, Deserialize, Clone, PartialEq, Default, Debug)] 42 | pub struct ConsumerConfig { 43 | pub service: String, 44 | pub url: String, 45 | pub protocol: String, 46 | } 47 | 48 | #[derive(Serialize, Deserialize, Default, Debug, Clone, PartialEq)] 49 | pub struct Tag { 50 | pub name: String, 51 | #[serde(rename = "match")] 52 | pub matches: Vec, 53 | } 54 | 55 | #[derive(Serialize, Deserialize, Default, Debug, Clone, PartialEq)] 56 | pub struct TagMatchRule { 57 | pub key: String, 58 | pub value: String, 59 | } 60 | 61 | impl ConditionRouterConfig { 62 | pub fn new(config: &String) -> Self { 63 | serde_yaml::from_str(config).expect("parse error") 64 | } 65 | } 66 | 67 | #[derive(Serialize, Deserialize, Debug, Default, Clone, PartialEq)] 68 | pub struct EnableAuth { 69 | pub auth_username: String, 70 | pub auth_password: String, 71 | } 72 | 73 | #[derive(Serialize, Deserialize, Debug, Default, Clone, PartialEq)] 74 | pub struct NacosConfig { 75 | pub addr: String, 76 | pub namespace: String, 77 | pub app: String, 78 | pub enable_auth: Option, 79 | pub enable_auth_plugin_http: Option, 80 | } 81 | 82 | #[derive(Serialize, Deserialize, Debug, PartialEq, Clone, Default)] 83 | pub struct RouterConfig { 84 | pub consumer: Option>, 85 | pub nacos: Option, 86 | pub conditions: Option>, 87 | pub tags: Option, 88 | } 89 | -------------------------------------------------------------------------------- /dubbo/src/config/service.rs: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | 18 | use serde::{Deserialize, Serialize}; 19 | 20 | #[derive(Debug, Default, Serialize, Deserialize, Clone)] 21 | pub struct ServiceConfig { 22 | pub version: String, 23 | pub group: String, 24 | pub protocol: String, 25 | pub interface: String, 26 | pub tag: String, 27 | } 28 | 29 | impl ServiceConfig { 30 | pub fn interface(self, interface: String) -> Self { 31 | Self { interface, ..self } 32 | } 33 | 34 | pub fn version(self, version: String) -> Self { 35 | Self { version, ..self } 36 | } 37 | 38 | pub fn group(self, group: String) -> Self { 39 | Self { group, ..self } 40 | } 41 | 42 | pub fn protocol(self, protocol: String) -> Self { 43 | Self { protocol, ..self } 44 | } 45 | pub fn tag(self, tag: String) -> Self { 46 | Self { tag, ..self } 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /dubbo/src/filter/context.rs: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | 18 | use std::time::{SystemTime, UNIX_EPOCH}; 19 | 20 | use crate::logger::tracing::debug; 21 | use serde_json::Value; 22 | 23 | use crate::{ 24 | codegen::Request, 25 | context::{Context, RpcContext}, 26 | filter::{TIMEOUT_COUNTDOWN, TIMEOUT_DEFAULT, TRI_TIMEOUT_DEADLINE_IN_NANOS}, 27 | status::Status, 28 | }; 29 | 30 | use super::Filter; 31 | 32 | #[derive(Clone)] 33 | pub struct ContextFilter {} 34 | 35 | impl Filter for ContextFilter { 36 | fn call(&mut self, req: Request<()>) -> Result, Status> { 37 | let headers = &mut req.metadata.into_headers(); 38 | 39 | let timeout = headers.get(TIMEOUT_COUNTDOWN); 40 | 41 | let time = SystemTime::now() 42 | .duration_since(UNIX_EPOCH) 43 | .unwrap() 44 | .as_nanos(); 45 | 46 | let mut dead_line_in_nanos = 0_u128; 47 | 48 | if let Some(t) = timeout { 49 | let timeout: u128 = t.to_str().unwrap().parse().unwrap(); 50 | if timeout > 0_u128 { 51 | dead_line_in_nanos = time + timeout * 1000000; 52 | } 53 | } else { 54 | let timeout: u128 = TIMEOUT_DEFAULT * 1000000; 55 | dead_line_in_nanos = time + timeout; 56 | } 57 | 58 | debug!( 59 | "ContextFilter tri-timeout-deadline-in-nanos : {}", 60 | dead_line_in_nanos 61 | ); 62 | if let Some(at) = RpcContext::get_attachments() { 63 | let mut attachments = at.lock().unwrap(); 64 | attachments.insert( 65 | String::from(TRI_TIMEOUT_DEADLINE_IN_NANOS), 66 | Value::from(dead_line_in_nanos.to_string()), 67 | ); 68 | } 69 | 70 | Ok(req) 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /dubbo/src/filter/mod.rs: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | 18 | pub mod context; 19 | pub mod service; 20 | pub mod timeout; 21 | 22 | use crate::invocation::Request; 23 | 24 | pub const TRI_TIMEOUT_DEADLINE_IN_NANOS: &str = "tri-timeout-deadline-in-nanos"; 25 | pub const TIMEOUT_COUNTDOWN: &str = "timeout-countdown"; 26 | pub const TIMEOUT_DEFAULT: u128 = 1000; 27 | 28 | pub trait Filter { 29 | fn call(&mut self, req: Request<()>) -> Result, crate::status::Status>; 30 | } 31 | -------------------------------------------------------------------------------- /dubbo/src/filter/service.rs: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | 18 | use tower_service::Service; 19 | 20 | use super::Filter; 21 | use crate::invocation::{Metadata, Request}; 22 | 23 | #[derive(Clone)] 24 | pub struct FilterService { 25 | inner: S, 26 | f: F, 27 | } 28 | 29 | impl FilterService { 30 | pub fn new(inner: S, f: F) -> Self 31 | where 32 | F: Filter, 33 | { 34 | Self { inner, f } 35 | } 36 | } 37 | 38 | impl Service> for FilterService 39 | where 40 | F: Filter, 41 | S: Service, Response = http::Response>, 42 | S::Error: Into, 43 | S::Future: Send + 'static, 44 | { 45 | type Response = http::Response; 46 | 47 | type Error = S::Error; 48 | 49 | type Future = crate::BoxFuture; 50 | 51 | fn poll_ready( 52 | &mut self, 53 | cx: &mut std::task::Context<'_>, 54 | ) -> std::task::Poll> { 55 | self.inner.poll_ready(cx) 56 | } 57 | 58 | fn call(&mut self, req: http::Request) -> Self::Future { 59 | let uri = req.uri().clone(); 60 | let method = req.method().clone(); 61 | let version = req.version(); 62 | let (parts, msg) = req.into_parts(); 63 | 64 | let res = self.f.call(Request::from_parts( 65 | Metadata::from_headers(parts.headers), 66 | (), 67 | )); 68 | match res { 69 | Ok(req) => { 70 | let (metadata, _) = req.into_parts(); 71 | let req = Request::from_parts(Metadata::from_headers(metadata.into_headers()), msg); 72 | let http_req = req.into_http(uri, method, version); 73 | 74 | let resp = self.inner.call(http_req); 75 | Box::pin(resp) 76 | } 77 | Err(err) => { 78 | let fut = async move { Ok(err.to_http()) }; 79 | Box::pin(fut) 80 | } 81 | } 82 | } 83 | } 84 | -------------------------------------------------------------------------------- /dubbo/src/filter/timeout.rs: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | use crate::logger::tracing::debug; 18 | use std::time::{SystemTime, UNIX_EPOCH}; 19 | 20 | use crate::{ 21 | codegen::Request, 22 | context::{Context, RpcContext}, 23 | filter::TRI_TIMEOUT_DEADLINE_IN_NANOS, 24 | status::{Code, Status}, 25 | }; 26 | 27 | use super::Filter; 28 | 29 | #[derive(Clone)] 30 | pub struct TimeoutFilter {} 31 | 32 | /// timeout count 33 | /// 1. ContextFilter 初始化 timeout 时间,初始化后将 tri-timeout-deadline-in-nanos 放入 context 中 34 | /// 2. TimeoutFilter read context tri-timeout-deadline-in-nanos 35 | /// 3. 响应时计算 tri-timeout-deadline-in-nanos - current_nanos <= 0 36 | /// 37 | impl Filter for TimeoutFilter { 38 | fn call(&mut self, req: Request<()>) -> Result, Status> { 39 | if let Some(attachments) = RpcContext::get_attachments() { 40 | let current_nanos = SystemTime::now() 41 | .duration_since(UNIX_EPOCH) 42 | .unwrap() 43 | .as_nanos(); 44 | 45 | let attachments = attachments.lock().unwrap(); 46 | let tri_timeout_deadline_in_nanos = 47 | attachments.get(TRI_TIMEOUT_DEADLINE_IN_NANOS).unwrap(); 48 | let tri_timeout_deadline_in_nanos: u128 = tri_timeout_deadline_in_nanos 49 | .as_str() 50 | .unwrap() 51 | .parse() 52 | .unwrap(); 53 | 54 | debug!( 55 | "TimeoutFilter tri-timeout-deadline-in-nanos : {}, current-nanos:{}", 56 | tri_timeout_deadline_in_nanos, current_nanos 57 | ); 58 | if tri_timeout_deadline_in_nanos - current_nanos <= 0 { 59 | return Err(Status::new(Code::DeadlineExceeded, String::from("Timeout"))); 60 | } 61 | } 62 | 63 | Ok(req) 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /dubbo/src/invoker/mod.rs: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | use crate::{codegen::TripleInvoker, invoker::clone_invoker::CloneInvoker, svc::NewService}; 18 | 19 | pub mod clone_body; 20 | pub mod clone_invoker; 21 | 22 | pub struct NewInvoker; 23 | 24 | impl NewService for NewInvoker { 25 | type Service = CloneInvoker; 26 | 27 | fn new_service(&self, url: String) -> Self::Service { 28 | // todo create another invoker by url protocol 29 | 30 | let url = url.parse().unwrap(); 31 | CloneInvoker::new(TripleInvoker::new(url)) 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /dubbo/src/lib.rs: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | 18 | pub mod cluster; 19 | pub mod codegen; 20 | pub mod config; 21 | pub mod context; 22 | pub mod directory; 23 | pub mod extension; 24 | pub mod filter; 25 | mod framework; 26 | pub mod invocation; 27 | pub mod invoker; 28 | pub mod loadbalancer; 29 | pub mod logger; 30 | pub mod param; 31 | pub mod params; 32 | pub mod protocol; 33 | pub mod registry; 34 | pub mod route; 35 | pub mod status; 36 | pub mod svc; 37 | pub mod triple; 38 | pub mod url; 39 | pub mod utils; 40 | 41 | use http_body::Body; 42 | use std::{env, future::Future, path::PathBuf, pin::Pin}; 43 | 44 | pub use crate::url::Url; 45 | pub use framework::Dubbo; 46 | 47 | pub type BoxFuture = self::Pin> + Send + 'static>>; 48 | pub(crate) type Error = Box; 49 | pub type BoxBody = http_body::combinators::UnsyncBoxBody; 50 | pub type StdError = Box; 51 | 52 | pub fn empty_body() -> BoxBody { 53 | http_body::Empty::new() 54 | .map_err(|err| match err {}) 55 | .boxed_unsync() 56 | } 57 | 58 | pub(crate) fn boxed(body: B) -> BoxBody 59 | where 60 | B: http_body::Body + Send + 'static, 61 | B::Error: Into, 62 | { 63 | body.map_err(|err| { 64 | self::status::Status::new(self::status::Code::Internal, format!("{:?}", err.into())) 65 | }) 66 | .boxed_unsync() 67 | } 68 | 69 | pub fn app_root_dir() -> PathBuf { 70 | match project_root::get_project_root() { 71 | // Cargo.lock file as app root dir 72 | Ok(p) => p, 73 | Err(_) => env::current_dir().unwrap(), 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /dubbo/src/loadbalancer/random.rs: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | 18 | use rand::prelude::SliceRandom; 19 | use tracing::debug; 20 | 21 | use super::{DubboBoxService, LoadBalancer}; 22 | use crate::{ 23 | invocation::Metadata, loadbalancer::CloneInvoker, 24 | protocol::triple::triple_invoker::TripleInvoker, 25 | }; 26 | 27 | #[derive(Clone, Default)] 28 | pub struct RandomLoadBalancer {} 29 | 30 | impl LoadBalancer for RandomLoadBalancer { 31 | type Invoker = DubboBoxService; 32 | 33 | fn select_invokers( 34 | &self, 35 | invokers: Vec>, 36 | metadata: Metadata, 37 | ) -> Self::Invoker { 38 | debug!("random loadbalance {:?}", metadata); 39 | let ivk = invokers.choose(&mut rand::thread_rng()).unwrap().clone(); 40 | DubboBoxService::new(ivk) 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /dubbo/src/logger/level.rs: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | use super::Level; 18 | 19 | pub(crate) struct LevelWrapper { 20 | pub(crate) inner: Level, 21 | } 22 | impl LevelWrapper { 23 | pub fn new(level: Level) -> Self { 24 | LevelWrapper { inner: level } 25 | } 26 | } 27 | 28 | impl From> for LevelWrapper { 29 | fn from(s: Option) -> Self { 30 | match s.unwrap().to_lowercase().as_str().trim() { 31 | "error" => LevelWrapper::new(Level::ERROR), 32 | "warn" => LevelWrapper::new(Level::WARN), 33 | "info" => LevelWrapper::new(Level::INFO), 34 | "debug" => LevelWrapper::new(Level::DEBUG), 35 | "trace" => LevelWrapper::new(Level::TRACE), 36 | _ => LevelWrapper::new(Level::INFO), 37 | } 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /dubbo/src/logger/mod.rs: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | 18 | use std::sync::atomic::{AtomicBool, Ordering}; 19 | 20 | pub use tracing::{self, Level}; 21 | 22 | // flag for the sake of avoiding multiple initialization 23 | static TRACING_CONFIGURED: AtomicBool = AtomicBool::new(false); 24 | 25 | mod level; 26 | mod tracing_configurer; 27 | 28 | // put on main method 29 | pub fn init() { 30 | if !TRACING_CONFIGURED.load(Ordering::SeqCst) { 31 | tracing_configurer::default() 32 | } 33 | } 34 | 35 | #[cfg(test)] 36 | mod tests { 37 | use tracing::{debug, info, trace}; 38 | 39 | #[test] 40 | fn test_print_info_log() { 41 | super::init(); 42 | debug!("hello rust:debug"); 43 | trace!("hello rust:trace"); 44 | info!("hello rust:info"); 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /dubbo/src/logger/tracing_configurer.rs: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | 18 | // https://github.com/tokio-rs/tracing/issues/971 19 | 20 | use super::level::LevelWrapper; 21 | use crate::{app_root_dir, utils::yaml_utils}; 22 | use std::path::PathBuf; 23 | use tracing::debug; 24 | 25 | pub(crate) fn default() { 26 | let path_buf = PathBuf::new().join(app_root_dir()).join("application.yaml"); 27 | let level: LevelWrapper = yaml_utils::yaml_key_reader(path_buf, "logging.level") 28 | .unwrap() 29 | .into(); 30 | tracing_subscriber::fmt() 31 | .compact() 32 | .with_line_number(true) 33 | .with_max_level(level.inner) 34 | // sets this to be the default, global collector for this application. 35 | .try_init() 36 | .expect("init err."); 37 | debug!("Tracing configured.") 38 | } 39 | -------------------------------------------------------------------------------- /dubbo/src/param.rs: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | 18 | pub trait Param { 19 | fn param(&self) -> T; 20 | } 21 | 22 | impl Param for T { 23 | fn param(&self) -> T::Owned { 24 | self.to_owned() 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /dubbo/src/params/constants.rs: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | pub const REGISTRY_PROTOCOL: &str = "registry_protocol"; 18 | pub const PROTOCOL: &str = "protocol"; 19 | pub const REGISTRY: &str = "registry"; 20 | 21 | // URL key 22 | pub const DUBBO_KEY: &str = "dubbo"; 23 | pub const PROVIDERS_KEY: &str = "providers"; 24 | pub const LOCALHOST_IP: &str = "127.0.0.1"; 25 | pub const METADATA_MAPPING_KEY: &str = "mapping"; 26 | pub const VERSION_KEY: &str = "version"; 27 | pub const GROUP_KEY: &str = "group"; 28 | pub const INTERFACE_KEY: &str = "interface"; 29 | pub const ANYHOST_KEY: &str = "anyhost"; 30 | pub const SIDE_KEY: &str = "side"; 31 | pub const TIMESTAMP_KEY: &str = "timestamp"; 32 | -------------------------------------------------------------------------------- /dubbo/src/params/extension_param.rs: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | use crate::{url::UrlParam, StdError}; 18 | use std::{borrow::Cow, convert::Infallible, str::FromStr}; 19 | 20 | pub struct ExtensionName(String); 21 | 22 | impl ExtensionName { 23 | pub fn new(name: String) -> Self { 24 | ExtensionName(name) 25 | } 26 | } 27 | 28 | impl UrlParam for ExtensionName { 29 | type TargetType = String; 30 | 31 | fn name() -> &'static str { 32 | "extension-name" 33 | } 34 | 35 | fn value(&self) -> Self::TargetType { 36 | self.0.clone() 37 | } 38 | 39 | fn as_str(&self) -> Cow { 40 | self.0.as_str().into() 41 | } 42 | } 43 | 44 | impl FromStr for ExtensionName { 45 | type Err = StdError; 46 | 47 | fn from_str(s: &str) -> Result { 48 | Ok(ExtensionName::new(s.to_string())) 49 | } 50 | } 51 | 52 | pub enum ExtensionType { 53 | Registry, 54 | Invoker, 55 | } 56 | 57 | impl UrlParam for ExtensionType { 58 | type TargetType = String; 59 | 60 | fn name() -> &'static str { 61 | "extension-type" 62 | } 63 | 64 | fn value(&self) -> Self::TargetType { 65 | match self { 66 | ExtensionType::Registry => "registry".to_owned(), 67 | ExtensionType::Invoker => "invoker".to_owned(), 68 | } 69 | } 70 | 71 | fn as_str(&self) -> Cow { 72 | match self { 73 | ExtensionType::Registry => Cow::Borrowed("registry"), 74 | ExtensionType::Invoker => Cow::Borrowed("invoker"), 75 | } 76 | } 77 | } 78 | 79 | impl FromStr for ExtensionType { 80 | type Err = Infallible; 81 | 82 | fn from_str(s: &str) -> Result { 83 | match s { 84 | "registry" => Ok(ExtensionType::Registry), 85 | _ => panic!("the extension type enum is not in range"), 86 | } 87 | } 88 | } 89 | -------------------------------------------------------------------------------- /dubbo/src/params/mod.rs: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | #![cfg_attr( 18 | debug_assertions, 19 | allow(dead_code, unused_imports, unused_variables, unused_mut) 20 | )] 21 | pub mod constants; 22 | pub mod extension_param; 23 | pub mod registry_param; 24 | -------------------------------------------------------------------------------- /dubbo/src/protocol/mod.rs: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | 18 | use std::task::{Context, Poll}; 19 | 20 | use async_trait::async_trait; 21 | use aws_smithy_http::body::SdkBody; 22 | use tower_service::Service; 23 | 24 | use crate::Url; 25 | 26 | pub mod server_desc; 27 | pub mod triple; 28 | 29 | #[async_trait] 30 | pub trait Protocol { 31 | type Invoker; 32 | 33 | fn destroy(&self); 34 | async fn export(self, url: Url) -> BoxExporter; 35 | async fn refer(self, url: Url) -> Self::Invoker; 36 | } 37 | 38 | pub trait Exporter { 39 | fn unexport(&self); 40 | } 41 | 42 | pub trait Invoker: Service { 43 | fn get_url(&self) -> Url; 44 | } 45 | 46 | pub type BoxExporter = Box; 47 | pub type BoxInvoker = Box< 48 | dyn Invoker< 49 | http::Request, 50 | Response = http::Response, 51 | Error = crate::Error, 52 | Future = crate::BoxFuture, crate::Error>, 53 | > + Send 54 | + Sync, 55 | >; 56 | 57 | pub struct WrapperInvoker(T); 58 | 59 | impl Service> for WrapperInvoker 60 | where 61 | T: Invoker, Response = http::Response>, 62 | T::Error: Into, 63 | { 64 | type Response = T::Response; 65 | 66 | type Error = T::Error; 67 | 68 | type Future = T::Future; 69 | 70 | fn poll_ready(&mut self, _cx: &mut Context<'_>) -> Poll> { 71 | Poll::Ready(Ok(())) 72 | } 73 | 74 | fn call(&mut self, req: http::Request) -> Self::Future { 75 | self.0.call(req) 76 | } 77 | } 78 | -------------------------------------------------------------------------------- /dubbo/src/protocol/server_desc.rs: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | 18 | //type ServiceDesc struct { 19 | // ServiceName string 20 | // // The pointer to the service interface. Used to check whether the user 21 | // // provided implementation satisfies the interface requirements. 22 | // HandlerType interface{} 23 | // Methods []MethodDesc 24 | // Streams []StreamDesc 25 | // Metadata interface{} 26 | // } 27 | 28 | use std::collections::HashMap; 29 | 30 | pub struct ServiceDesc { 31 | service_name: String, 32 | // methods: HashMap // "/Greeter/hello": "unary" 33 | } 34 | 35 | impl ServiceDesc { 36 | pub fn new(service_name: String, _methods: HashMap) -> Self { 37 | Self { service_name } 38 | } 39 | 40 | pub fn get_service_name(&self) -> String { 41 | self.service_name.clone() 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /dubbo/src/protocol/triple/mod.rs: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | 18 | pub mod triple_exporter; 19 | pub mod triple_invoker; 20 | pub mod triple_protocol; 21 | pub mod triple_server; 22 | 23 | use lazy_static::lazy_static; 24 | use std::{collections::HashMap, sync::RwLock}; 25 | 26 | use crate::{utils::boxed_clone::BoxCloneService, BoxBody}; 27 | 28 | pub type GrpcBoxCloneService = 29 | BoxCloneService, http::Response, std::convert::Infallible>; 30 | 31 | lazy_static! { 32 | pub static ref TRIPLE_SERVICES: RwLock> = 33 | RwLock::new(HashMap::new()); 34 | } 35 | -------------------------------------------------------------------------------- /dubbo/src/protocol/triple/triple_exporter.rs: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | 18 | use crate::protocol::Exporter; 19 | 20 | #[derive(Clone)] 21 | pub struct TripleExporter {} 22 | 23 | impl TripleExporter { 24 | pub fn new() -> Self { 25 | TripleExporter {} 26 | } 27 | } 28 | 29 | impl Default for TripleExporter { 30 | fn default() -> Self { 31 | Self::new() 32 | } 33 | } 34 | 35 | impl Exporter for TripleExporter { 36 | fn unexport(&self) { 37 | todo!() 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /dubbo/src/protocol/triple/triple_protocol.rs: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | 18 | use std::collections::HashMap; 19 | 20 | use super::{ 21 | triple_exporter::TripleExporter, triple_invoker::TripleInvoker, triple_server::TripleServer, 22 | }; 23 | use crate::{ 24 | params::registry_param::InterfaceName, 25 | protocol::{BoxExporter, Protocol}, 26 | url::UrlParam, 27 | Url, 28 | }; 29 | use async_trait::async_trait; 30 | 31 | #[derive(Clone)] 32 | pub struct TripleProtocol { 33 | servers: HashMap, 34 | } 35 | 36 | impl Default for TripleProtocol { 37 | fn default() -> Self { 38 | Self::new() 39 | } 40 | } 41 | 42 | impl TripleProtocol { 43 | pub fn new() -> Self { 44 | TripleProtocol { 45 | servers: HashMap::new(), 46 | } 47 | } 48 | 49 | pub fn get_server(&self, url: Url) -> Option { 50 | let interface_name = url.query::().unwrap(); 51 | self.servers 52 | .get(interface_name.value().as_str()) 53 | .map(|data| data.to_owned()) 54 | } 55 | } 56 | 57 | #[async_trait] 58 | impl Protocol for TripleProtocol { 59 | type Invoker = TripleInvoker; 60 | 61 | fn destroy(&self) { 62 | todo!() 63 | } 64 | 65 | async fn export(mut self, url: Url) -> BoxExporter { 66 | // service_key is same to key of TRIPLE_SERVICES 67 | let server = TripleServer::new(); 68 | 69 | let interface_name = url.query::().unwrap(); 70 | let interface_name = interface_name.value(); 71 | 72 | self.servers.insert(interface_name, server.clone()); 73 | server.serve(url).await; 74 | 75 | Box::new(TripleExporter::new()) 76 | } 77 | 78 | async fn refer(self, _url: Url) -> Self::Invoker { 79 | todo!() 80 | // TripleInvoker::new(url) 81 | // Self::Invoker 82 | } 83 | } 84 | -------------------------------------------------------------------------------- /dubbo/src/protocol/triple/triple_server.rs: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | 18 | use crate::{triple::server::builder::ServerBuilder, Url}; 19 | 20 | #[derive(Default, Clone)] 21 | pub struct TripleServer { 22 | builder: ServerBuilder, 23 | } 24 | 25 | impl TripleServer { 26 | pub fn new() -> TripleServer { 27 | Self { 28 | builder: ServerBuilder::new(), 29 | } 30 | } 31 | 32 | pub async fn serve(mut self, url: Url) { 33 | self.builder = ServerBuilder::from(url); 34 | self.builder.build().serve().await.unwrap() 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /dubbo/src/registry/integration.rs: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | -------------------------------------------------------------------------------- /dubbo/src/registry/mod.rs: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | 18 | use crate::{extension, extension::registry_extension::proxy::RegistryProxy, StdError, Url}; 19 | use std::{ 20 | future::Future, 21 | pin::Pin, 22 | task::{Context, Poll}, 23 | }; 24 | use tower_service::Service; 25 | 26 | pub mod integration; 27 | pub mod protocol; 28 | pub mod registry; 29 | 30 | #[derive(Clone)] 31 | pub struct MkRegistryService { 32 | registry_url: Url, 33 | } 34 | 35 | impl MkRegistryService { 36 | pub fn new(registry_url: Url) -> Self { 37 | Self { registry_url } 38 | } 39 | } 40 | 41 | impl Service<()> for MkRegistryService { 42 | type Response = RegistryProxy; 43 | type Error = StdError; 44 | type Future = 45 | Pin> + Send + 'static>>; 46 | 47 | fn poll_ready(&mut self, _cx: &mut Context<'_>) -> Poll> { 48 | Poll::Ready(Ok(())) 49 | } 50 | 51 | fn call(&mut self, _req: ()) -> Self::Future { 52 | let fut = extension::EXTENSIONS.load_registry(self.registry_url.clone()); 53 | Box::pin(fut) 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /dubbo/src/svc.rs: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | use std::sync::Arc; 18 | 19 | pub trait NewService { 20 | type Service; 21 | 22 | fn new_service(&self, target: T) -> Self::Service; 23 | } 24 | 25 | pub struct ArcNewService { 26 | inner: Arc + Send + Sync>, 27 | } 28 | 29 | impl ArcNewService { 30 | pub fn layer() -> impl tower_layer::Layer + Clone + Copy 31 | where 32 | N: NewService + Send + Sync + 'static, 33 | S: Send + 'static, 34 | { 35 | tower_layer::layer_fn(Self::new) 36 | } 37 | 38 | pub fn new(inner: N) -> Self 39 | where 40 | N: NewService + Send + Sync + 'static, 41 | S: Send + 'static, 42 | { 43 | Self { 44 | inner: Arc::new(inner), 45 | } 46 | } 47 | } 48 | 49 | impl Clone for ArcNewService { 50 | fn clone(&self) -> Self { 51 | Self { 52 | inner: self.inner.clone(), 53 | } 54 | } 55 | } 56 | 57 | impl NewService for ArcNewService { 58 | type Service = S; 59 | 60 | fn new_service(&self, t: T) -> S { 61 | self.inner.new_service(t) 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /dubbo/src/triple/client/mod.rs: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | 18 | pub mod builder; 19 | pub mod triple; 20 | 21 | pub use triple::TripleClient; 22 | -------------------------------------------------------------------------------- /dubbo/src/triple/codec/mod.rs: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | 18 | pub mod buffer; 19 | pub mod prost; 20 | pub mod serde_codec; 21 | 22 | use std::io; 23 | 24 | pub use self::buffer::{DecodeBuf, EncodeBuf}; 25 | use crate::status::Status; 26 | 27 | pub trait Codec { 28 | /// The encodable message. 29 | type Encode: Send + 'static; 30 | /// The decodable message. 31 | type Decode: Send + 'static; 32 | 33 | /// The encoder that can encode a message. 34 | type Encoder: Encoder + Send + 'static; 35 | /// The encoder that can decode a message. 36 | type Decoder: Decoder + Send + 'static; 37 | 38 | /// Fetch the encoder. 39 | fn encoder(&mut self) -> Self::Encoder; 40 | /// Fetch the decoder. 41 | fn decoder(&mut self) -> Self::Decoder; 42 | } 43 | 44 | /// Encodes gRPC message types 45 | pub trait Encoder { 46 | /// The type that is encoded. 47 | type Item; 48 | 49 | /// The type of encoding errors. 50 | /// 51 | /// The type of unrecoverable frame encoding errors. 52 | type Error: From; 53 | 54 | /// Encodes a message into the provided buffer. 55 | fn encode(&mut self, item: Self::Item, dst: &mut EncodeBuf<'_>) -> Result<(), Self::Error>; 56 | } 57 | 58 | /// Decodes gRPC message types 59 | pub trait Decoder { 60 | /// The type that is decoded. 61 | type Item; 62 | 63 | /// The type of unrecoverable frame decoding errors. 64 | type Error: From; 65 | 66 | /// Decode a message from the buffer. 67 | /// 68 | /// The buffer will contain exactly the bytes of a full message. There 69 | /// is no need to get the length from the bytes, gRPC framing is handled 70 | /// for you. 71 | fn decode(&mut self, src: &mut DecodeBuf<'_>) -> Result, Self::Error>; 72 | } 73 | -------------------------------------------------------------------------------- /dubbo/src/triple/codec/prost.rs: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | 18 | use super::{Codec, DecodeBuf, Decoder, EncodeBuf, Encoder}; 19 | use prost::Message; 20 | use std::marker::PhantomData; 21 | 22 | /// A [`Codec`] that implements `application/grpc+proto` via the prost library.. 23 | #[derive(Debug, Clone)] 24 | pub struct ProstCodec { 25 | _pd: PhantomData<(T, U)>, 26 | } 27 | 28 | impl Default for ProstCodec { 29 | fn default() -> Self { 30 | Self { _pd: PhantomData } 31 | } 32 | } 33 | 34 | impl Codec for ProstCodec 35 | where 36 | T: Message + Send + 'static, 37 | U: Message + Default + Send + 'static, 38 | { 39 | type Encode = T; 40 | type Decode = U; 41 | 42 | type Encoder = ProstEncoder; 43 | type Decoder = ProstDecoder; 44 | 45 | fn encoder(&mut self) -> Self::Encoder { 46 | ProstEncoder(PhantomData) 47 | } 48 | 49 | fn decoder(&mut self) -> Self::Decoder { 50 | ProstDecoder(PhantomData) 51 | } 52 | } 53 | 54 | /// A [`Encoder`] that knows how to encode `T`. 55 | #[derive(Debug, Clone, Default)] 56 | pub struct ProstEncoder(PhantomData); 57 | 58 | impl Encoder for ProstEncoder { 59 | type Item = T; 60 | type Error = crate::status::Status; 61 | 62 | fn encode(&mut self, item: Self::Item, buf: &mut EncodeBuf<'_>) -> Result<(), Self::Error> { 63 | item.encode(buf) 64 | .expect("Message only errors if not enough space"); 65 | 66 | Ok(()) 67 | } 68 | } 69 | 70 | /// A [`Decoder`] that knows how to decode `U`. 71 | #[derive(Debug, Clone, Default)] 72 | pub struct ProstDecoder(PhantomData); 73 | 74 | impl Decoder for ProstDecoder { 75 | type Item = U; 76 | type Error = crate::status::Status; 77 | 78 | fn decode(&mut self, buf: &mut DecodeBuf<'_>) -> Result, Self::Error> { 79 | let item = Message::decode(buf) 80 | .map(Option::Some) 81 | .map_err(from_decode_error)?; 82 | 83 | Ok(item) 84 | } 85 | } 86 | 87 | fn from_decode_error(error: prost::DecodeError) -> crate::status::Status { 88 | // Map Protobuf parse errors to an INTERNAL status code, as per 89 | // https://github.com/grpc/grpc/blob/master/doc/statuscodes.md 90 | crate::status::Status::new(crate::status::Code::Internal, error.to_string()) 91 | } 92 | -------------------------------------------------------------------------------- /dubbo/src/triple/codec/serde_codec.rs: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | 18 | use std::marker::PhantomData; 19 | 20 | use bytes::{Buf, BufMut}; 21 | use serde::{Deserialize, Serialize}; 22 | 23 | use super::{Codec, DecodeBuf, Decoder, EncodeBuf, Encoder}; 24 | 25 | #[derive(Debug)] 26 | pub struct SerdeCodec { 27 | _pd: PhantomData<(T, U)>, 28 | } 29 | 30 | impl Default for SerdeCodec { 31 | fn default() -> Self { 32 | Self { _pd: PhantomData } 33 | } 34 | } 35 | 36 | impl<'a, T, U> Codec for SerdeCodec 37 | where 38 | T: Serialize + Send + 'static, 39 | U: Deserialize<'a> + Send + 'static, 40 | { 41 | type Encode = T; 42 | 43 | type Decode = U; 44 | 45 | type Encoder = SerdeEncoder; 46 | 47 | type Decoder = SerdeDecoder; 48 | 49 | fn encoder(&mut self) -> Self::Encoder { 50 | SerdeEncoder(PhantomData) 51 | } 52 | 53 | fn decoder(&mut self) -> Self::Decoder { 54 | SerdeDecoder(PhantomData) 55 | } 56 | } 57 | 58 | #[derive(Debug, Clone)] 59 | pub struct SerdeEncoder(PhantomData); 60 | 61 | impl Encoder for SerdeEncoder { 62 | type Item = T; 63 | 64 | type Error = crate::status::Status; 65 | 66 | fn encode(&mut self, item: Self::Item, dst: &mut EncodeBuf<'_>) -> Result<(), Self::Error> { 67 | item.serialize(&mut serde_json::Serializer::new(dst.writer())) 68 | .expect("failed to searialize"); 69 | 70 | Ok(()) 71 | } 72 | } 73 | 74 | pub struct SerdeDecoder(PhantomData); 75 | 76 | impl<'a, U: Deserialize<'a>> Decoder for SerdeDecoder { 77 | type Item = U; 78 | 79 | type Error = crate::status::Status; 80 | 81 | fn decode(&mut self, src: &mut DecodeBuf<'_>) -> Result, Self::Error> { 82 | let value = src.chunk().to_owned(); 83 | let mut msg = vec![0u8; value.len()]; 84 | src.copy_to_slice(&mut msg); 85 | 86 | let mut de = serde_json::Deserializer::from_reader(msg.reader()); 87 | Ok(Some(U::deserialize(&mut de).unwrap())) 88 | } 89 | } 90 | -------------------------------------------------------------------------------- /dubbo/src/triple/consts.rs: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | 18 | pub const BUFFER_SIZE: usize = 1024 * 8; 19 | // 5 bytes 20 | pub const HEADER_SIZE: usize = 21 | // compression flag 22 | std::mem::size_of::() + 23 | // data length 24 | std::mem::size_of::(); 25 | -------------------------------------------------------------------------------- /dubbo/src/triple/mod.rs: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | 18 | pub mod client; 19 | pub mod codec; 20 | pub mod compression; 21 | pub mod consts; 22 | pub mod decode; 23 | pub mod encode; 24 | pub mod server; 25 | pub mod transport; 26 | -------------------------------------------------------------------------------- /dubbo/src/triple/server/mod.rs: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | 18 | pub mod builder; 19 | pub mod service; 20 | pub mod triple; 21 | 22 | pub use triple::TripleServer; 23 | -------------------------------------------------------------------------------- /dubbo/src/triple/transport/connector/http_connector.rs: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | 18 | use std::{ 19 | net::{Ipv4Addr, SocketAddr, SocketAddrV4}, 20 | str::FromStr, 21 | }; 22 | 23 | use crate::logger::tracing::info; 24 | use http::Uri; 25 | use hyper::client::connect::dns::Name; 26 | use tokio::net::TcpStream; 27 | use tower_service::Service; 28 | 29 | use crate::triple::transport::resolver::{dns::DnsResolver, Resolve}; 30 | 31 | #[derive(Clone, Default)] 32 | pub struct HttpConnector { 33 | resolver: R, 34 | } 35 | 36 | impl HttpConnector { 37 | pub fn new() -> Self { 38 | Self { 39 | resolver: DnsResolver::default(), 40 | } 41 | } 42 | } 43 | 44 | impl HttpConnector { 45 | pub fn new_with_resolver(resolver: R) -> HttpConnector { 46 | Self { resolver } 47 | } 48 | } 49 | 50 | impl Service for HttpConnector 51 | where 52 | R: Resolve + Clone + Send + Sync + 'static, 53 | R::Future: Send, 54 | { 55 | type Response = TcpStream; 56 | 57 | type Error = crate::Error; 58 | 59 | type Future = crate::BoxFuture; 60 | 61 | fn poll_ready( 62 | &mut self, 63 | cx: &mut std::task::Context<'_>, 64 | ) -> std::task::Poll> { 65 | self.resolver.poll_ready(cx).map_err(|err| err.into()) 66 | } 67 | 68 | fn call(&mut self, uri: Uri) -> Self::Future { 69 | let mut inner = self.clone(); 70 | 71 | Box::pin(async move { inner.call_async(uri).await }) 72 | } 73 | } 74 | 75 | impl HttpConnector 76 | where 77 | R: Resolve + Send + Sync + 'static, 78 | { 79 | async fn call_async(&mut self, uri: Uri) -> Result { 80 | let host = uri.host().unwrap(); 81 | let port = uri.port_u16().unwrap(); 82 | 83 | let addr = if let Ok(addr) = host.parse::() { 84 | info!("host is ip address: {:?}", host); 85 | SocketAddr::V4(SocketAddrV4::new(addr, port)) 86 | } else { 87 | info!("host is dns: {:?}", host); 88 | let addrs = self 89 | .resolver 90 | .resolve(Name::from_str(host).unwrap()) 91 | .await 92 | .map_err(|err| err.into())?; 93 | let addrs: Vec = addrs 94 | .map(|mut addr| { 95 | addr.set_port(port); 96 | addr 97 | }) 98 | .collect(); 99 | addrs[0] 100 | }; 101 | 102 | let conn = TcpStream::connect(addr).await?; 103 | 104 | Ok(conn) 105 | } 106 | } 107 | -------------------------------------------------------------------------------- /dubbo/src/triple/transport/connector/mod.rs: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | 18 | pub mod http_connector; 19 | pub mod https_connector; 20 | #[cfg(any(target_os = "macos", target_family = "unix"))] 21 | pub mod unix_connector; 22 | 23 | use hyper::Uri; 24 | use tokio::io::{AsyncRead, AsyncWrite}; 25 | use tower::make::MakeConnection; 26 | use tower_service::Service; 27 | 28 | use super::io::BoxIO; 29 | use crate::utils::boxed_clone::BoxCloneService; 30 | 31 | #[derive(Clone)] 32 | pub struct Connector { 33 | inner: C, 34 | } 35 | 36 | impl Connector { 37 | pub fn new(inner: C) -> Connector 38 | where 39 | C: Service, 40 | C::Error: Into, 41 | C::Response: AsyncRead + AsyncWrite + Send + 'static, 42 | { 43 | Self { inner } 44 | } 45 | } 46 | 47 | impl Service for Connector 48 | where 49 | C: MakeConnection, 50 | C::Connection: Unpin + Send + 'static, 51 | C::Future: Send + 'static, 52 | crate::Error: From + Send + 'static, 53 | { 54 | type Response = BoxIO; 55 | 56 | type Error = crate::Error; 57 | 58 | type Future = crate::BoxFuture; 59 | 60 | fn poll_ready( 61 | &mut self, 62 | cx: &mut std::task::Context<'_>, 63 | ) -> std::task::Poll> { 64 | MakeConnection::poll_ready(&mut self.inner, cx).map_err(Into::into) 65 | } 66 | 67 | fn call(&mut self, uri: Uri) -> Self::Future { 68 | let conn = self.inner.make_connection(uri); 69 | 70 | Box::pin(async move { 71 | let io = conn.await?; 72 | Ok(BoxIO::new(io)) 73 | }) 74 | } 75 | } 76 | 77 | pub fn get_connector(connector: &str) -> BoxCloneService { 78 | match connector { 79 | "http" => { 80 | let c = http_connector::HttpConnector::new(); 81 | BoxCloneService::new(Connector::new(c)) 82 | } 83 | "https" => { 84 | let c = https_connector::HttpsConnector::new(); 85 | BoxCloneService::new(Connector::new(c)) 86 | } 87 | #[cfg(any(target_os = "macos", target_family = "unix"))] 88 | "unix" => { 89 | let c = unix_connector::UnixConnector::new(); 90 | BoxCloneService::new(Connector::new(c)) 91 | } 92 | _ => { 93 | let c = http_connector::HttpConnector::new(); 94 | BoxCloneService::new(Connector::new(c)) 95 | } 96 | } 97 | } 98 | -------------------------------------------------------------------------------- /dubbo/src/triple/transport/io/mod.rs: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | 18 | use std::pin::Pin; 19 | 20 | use hyper::client::connect::Connection; 21 | use tokio::io::{AsyncRead, AsyncWrite}; 22 | 23 | pub struct BoxIO { 24 | reader: Box, 25 | writer: Box, 26 | } 27 | 28 | impl BoxIO { 29 | pub fn new(io: impl AsyncWrite + AsyncRead + Unpin + Send + 'static) -> Self { 30 | let (r, w) = tokio::io::split(io); 31 | BoxIO { 32 | reader: Box::new(r), 33 | writer: Box::new(w), 34 | } 35 | } 36 | } 37 | 38 | impl AsyncWrite for BoxIO { 39 | fn poll_write( 40 | mut self: std::pin::Pin<&mut Self>, 41 | cx: &mut std::task::Context<'_>, 42 | buf: &[u8], 43 | ) -> std::task::Poll> { 44 | let s = &mut *self; 45 | Pin::new(&mut s.writer).poll_write(cx, buf) 46 | } 47 | 48 | fn poll_flush( 49 | mut self: std::pin::Pin<&mut Self>, 50 | cx: &mut std::task::Context<'_>, 51 | ) -> std::task::Poll> { 52 | let s = &mut *self; 53 | Pin::new(&mut s.writer).poll_flush(cx) 54 | } 55 | 56 | fn poll_shutdown( 57 | mut self: std::pin::Pin<&mut Self>, 58 | cx: &mut std::task::Context<'_>, 59 | ) -> std::task::Poll> { 60 | let s = &mut *self; 61 | Pin::new(&mut s.writer).poll_shutdown(cx) 62 | } 63 | } 64 | 65 | impl AsyncRead for BoxIO { 66 | fn poll_read( 67 | mut self: Pin<&mut Self>, 68 | cx: &mut std::task::Context<'_>, 69 | buf: &mut tokio::io::ReadBuf<'_>, 70 | ) -> std::task::Poll> { 71 | let s = &mut *self; 72 | Pin::new(&mut s.reader).poll_read(cx, buf) 73 | } 74 | } 75 | 76 | /// for connector 77 | impl Connection for BoxIO { 78 | fn connected(&self) -> hyper::client::connect::Connected { 79 | hyper::client::connect::Connected::new() 80 | } 81 | } 82 | -------------------------------------------------------------------------------- /dubbo/src/triple/transport/listener/mod.rs: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | 18 | pub mod tcp_listener; 19 | #[cfg(any(target_os = "macos", target_family = "unix"))] 20 | pub mod unix_listener; 21 | 22 | use std::net::SocketAddr; 23 | 24 | use crate::logger::tracing::warn; 25 | use async_trait::async_trait; 26 | use tokio::io::{AsyncRead, AsyncWrite}; 27 | 28 | use super::io::BoxIO; 29 | pub use tcp_listener::TcpListener; 30 | 31 | #[async_trait] 32 | pub trait Listener: Send + Sync { 33 | type Conn: AsyncRead + AsyncWrite + Unpin + Send + 'static; 34 | 35 | async fn accept(&self) -> std::io::Result<(Self::Conn, SocketAddr)>; 36 | } 37 | 38 | pub type BoxListener = Box>; 39 | 40 | pub trait ListenerExt: Listener { 41 | fn boxed(self) -> BoxListener 42 | where 43 | Self: Sized + 'static, 44 | { 45 | Box::new(WrappedListener(self)) 46 | } 47 | } 48 | 49 | impl ListenerExt for T {} 50 | 51 | pub struct WrappedListener(T); 52 | 53 | #[async_trait] 54 | impl Listener for WrappedListener { 55 | type Conn = BoxIO; 56 | 57 | async fn accept(&self) -> std::io::Result<(Self::Conn, SocketAddr)> { 58 | self.0 59 | .accept() 60 | .await 61 | .map(|(io, addr)| (BoxIO::new(io), addr)) 62 | } 63 | } 64 | 65 | pub async fn get_listener(name: String, addr: SocketAddr) -> Result { 66 | match name.as_str() { 67 | "tcp" => Ok(TcpListener::bind(addr).await?.boxed()), 68 | #[cfg(any(target_os = "macos", target_family = "unix"))] 69 | "unix" => Ok(unix_listener::UnixListener::bind(addr).await?.boxed()), 70 | _ => { 71 | warn!("no support listener: {:?}", name); 72 | Err(Box::new(crate::status::DubboError::new(format!( 73 | "no support listener: {:?}", 74 | name 75 | )))) 76 | } 77 | } 78 | } 79 | -------------------------------------------------------------------------------- /dubbo/src/triple/transport/listener/tcp_listener.rs: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | 18 | use std::{net::SocketAddr, task}; 19 | 20 | use super::Listener; 21 | use crate::logger::tracing::error; 22 | use async_trait::async_trait; 23 | use futures_core::Stream; 24 | use hyper::server::accept::Accept; 25 | use tokio::net::{TcpListener as tokioTcpListener, TcpStream}; 26 | 27 | pub struct TcpListener { 28 | inner: tokioTcpListener, 29 | } 30 | 31 | impl TcpListener { 32 | pub async fn bind(addr: SocketAddr) -> std::io::Result { 33 | let listener = tokioTcpListener::bind(addr).await?; 34 | 35 | Ok(TcpListener { inner: listener }) 36 | } 37 | } 38 | 39 | #[async_trait] 40 | impl Listener for TcpListener { 41 | type Conn = TcpStream; 42 | 43 | async fn accept(&self) -> std::io::Result<(Self::Conn, SocketAddr)> { 44 | let conn = self.inner.accept().await?; 45 | 46 | Ok(conn) 47 | } 48 | } 49 | 50 | impl Stream for TcpListener { 51 | type Item = TcpStream; 52 | 53 | fn poll_next( 54 | self: std::pin::Pin<&mut Self>, 55 | cx: &mut std::task::Context<'_>, 56 | ) -> std::task::Poll> { 57 | self.inner.poll_accept(cx).map(|res| match res { 58 | Ok(data) => Some(data.0), 59 | Err(err) => { 60 | error!("TcpListener poll_next Error: {:?}", err); 61 | None 62 | } 63 | }) 64 | } 65 | } 66 | 67 | impl Accept for TcpListener { 68 | type Conn = TcpStream; 69 | 70 | type Error = crate::Error; 71 | 72 | fn poll_accept( 73 | self: std::pin::Pin<&mut Self>, 74 | cx: &mut task::Context<'_>, 75 | ) -> std::task::Poll>> { 76 | self.inner.poll_accept(cx).map(|res| match res { 77 | Ok(data) => Some(Ok(data.0)), 78 | Err(err) => { 79 | error!("TcpListener poll_accept Error: {:?}", err); 80 | None 81 | } 82 | }) 83 | } 84 | } 85 | -------------------------------------------------------------------------------- /dubbo/src/triple/transport/listener/unix_listener.rs: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | 18 | use std::{net::SocketAddr, task}; 19 | 20 | use super::Listener; 21 | use crate::logger::tracing::error; 22 | use async_trait::async_trait; 23 | use futures_core::Stream; 24 | use hyper::server::accept::Accept; 25 | use tokio::net::{UnixListener as tokioUnixListener, UnixStream}; 26 | 27 | pub struct UnixListener { 28 | inner: tokioUnixListener, 29 | path: String, 30 | } 31 | 32 | impl UnixListener { 33 | pub async fn bind(addr: SocketAddr) -> std::io::Result { 34 | let listener = tokioUnixListener::bind(format!("{}", addr.to_string()))?; 35 | 36 | Ok(UnixListener { 37 | inner: listener, 38 | path: addr.to_string(), 39 | }) 40 | } 41 | } 42 | 43 | #[async_trait] 44 | impl Listener for UnixListener { 45 | type Conn = UnixStream; 46 | 47 | async fn accept(&self) -> std::io::Result<(Self::Conn, SocketAddr)> { 48 | let (unix_stream, _unix_addr) = self.inner.accept().await?; 49 | let addr: SocketAddr = self.path.parse().unwrap(); 50 | Ok((unix_stream, addr)) 51 | } 52 | } 53 | 54 | impl Stream for UnixListener { 55 | type Item = UnixStream; 56 | 57 | fn poll_next( 58 | self: std::pin::Pin<&mut Self>, 59 | cx: &mut std::task::Context<'_>, 60 | ) -> std::task::Poll> { 61 | self.inner.poll_accept(cx).map(|res| match res { 62 | Ok(data) => Some(data.0), 63 | Err(err) => { 64 | error!("UnixListener poll_next Error: {:?}", err); 65 | None 66 | } 67 | }) 68 | } 69 | } 70 | 71 | impl Accept for UnixListener { 72 | type Conn = UnixStream; 73 | 74 | type Error = crate::Error; 75 | 76 | fn poll_accept( 77 | self: std::pin::Pin<&mut Self>, 78 | cx: &mut task::Context<'_>, 79 | ) -> std::task::Poll>> { 80 | self.inner.poll_accept(cx).map(|res| match res { 81 | Ok(data) => Some(Ok(data.0)), 82 | Err(err) => { 83 | error!("UnixListener poll_accept Error: {:?}", err); 84 | None 85 | } 86 | }) 87 | } 88 | } 89 | -------------------------------------------------------------------------------- /dubbo/src/triple/transport/mod.rs: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | 18 | pub mod connection; 19 | pub mod connector; 20 | mod io; 21 | pub mod listener; 22 | pub mod resolver; 23 | pub mod router; 24 | pub mod service; 25 | 26 | pub use service::DubboServer; 27 | -------------------------------------------------------------------------------- /dubbo/src/triple/transport/resolver/dns.rs: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | 18 | use std::{ 19 | future::Future, 20 | net::{SocketAddr, ToSocketAddrs}, 21 | pin::Pin, 22 | task::Poll, 23 | vec, 24 | }; 25 | 26 | use tokio::task::JoinHandle; 27 | use tower_service::Service; 28 | 29 | #[derive(Clone, Default)] 30 | pub struct DnsResolver {} 31 | 32 | impl Service for DnsResolver { 33 | type Response = vec::IntoIter; 34 | 35 | type Error = std::io::Error; 36 | 37 | type Future = DnsFuture; 38 | 39 | fn poll_ready(&mut self, _cx: &mut std::task::Context<'_>) -> Poll> { 40 | Poll::Ready(Ok(())) 41 | } 42 | 43 | fn call(&mut self, name: String) -> Self::Future { 44 | let block = tokio::task::spawn_blocking(move || (name, 0).to_socket_addrs()); 45 | 46 | DnsFuture { inner: block } 47 | } 48 | } 49 | 50 | pub struct DnsFuture { 51 | inner: JoinHandle, std::io::Error>>, 52 | } 53 | 54 | impl Future for DnsFuture { 55 | type Output = Result, std::io::Error>; 56 | 57 | fn poll( 58 | mut self: std::pin::Pin<&mut Self>, 59 | cx: &mut std::task::Context<'_>, 60 | ) -> Poll { 61 | Pin::new(&mut self.inner).poll(cx).map(|res| match res { 62 | Ok(Ok(v)) => Ok(v), 63 | Ok(Err(err)) => Err(err), 64 | Err(join_err) => { 65 | if join_err.is_cancelled() { 66 | Err(std::io::Error::new( 67 | std::io::ErrorKind::Interrupted, 68 | join_err, 69 | )) 70 | } else { 71 | panic!("dnsfuture poll failed: {:?}", join_err) 72 | } 73 | } 74 | }) 75 | } 76 | } 77 | -------------------------------------------------------------------------------- /dubbo/src/triple/transport/resolver/mod.rs: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | 18 | pub mod dns; 19 | 20 | use std::{ 21 | net::SocketAddr, 22 | task::{self, Poll}, 23 | }; 24 | 25 | use futures::Future; 26 | use hyper::client::connect::dns::Name; 27 | use tower_service::Service; 28 | 29 | pub trait Resolve { 30 | type Addrs: Iterator; 31 | type Error: Into>; 32 | type Future: Future>; 33 | 34 | fn poll_ready(&mut self, cx: &mut task::Context<'_>) -> Poll>; 35 | fn resolve(&mut self, name: Name) -> Self::Future; 36 | } 37 | 38 | impl Resolve for S 39 | where 40 | S: Service, 41 | S::Response: Iterator, 42 | S::Error: Into>, 43 | { 44 | type Addrs = S::Response; 45 | 46 | type Error = S::Error; 47 | 48 | type Future = S::Future; 49 | 50 | fn poll_ready(&mut self, cx: &mut task::Context<'_>) -> Poll> { 51 | S::poll_ready(self, cx) 52 | } 53 | 54 | fn resolve(&mut self, name: Name) -> Self::Future { 55 | S::call(self, name.to_string()) 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /dubbo/src/triple/transport/router.rs: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | 18 | use std::{ 19 | fmt, 20 | pin::Pin, 21 | task::{Context, Poll}, 22 | }; 23 | 24 | use axum::Router; 25 | use futures_core::Future; 26 | use hyper::{Body, Request, Response}; 27 | use pin_project::pin_project; 28 | use tower::ServiceExt; 29 | use tower_service::Service; 30 | 31 | use crate::BoxBody; 32 | 33 | #[derive(Debug, Clone, Default)] 34 | pub struct DubboRouter { 35 | pub router: Router, 36 | } 37 | 38 | impl DubboRouter { 39 | pub fn new() -> DubboRouter { 40 | Self { 41 | router: Router::new(), 42 | } 43 | } 44 | } 45 | 46 | impl DubboRouter { 47 | pub fn add_service(mut self, name: String, service: S) -> Self 48 | where 49 | S: Service, Response = Response, Error = std::convert::Infallible> 50 | + Clone 51 | + Send 52 | + 'static, 53 | S::Future: Send + 'static, 54 | { 55 | let svc = service.map_response(|res| res.map(axum::body::boxed)); 56 | // *{bubbo} represents wildcard router 57 | self.router = self.router.route(&format!("/{}/*dubbo", name), svc); 58 | 59 | self 60 | } 61 | } 62 | 63 | impl Service> for DubboRouter { 64 | type Response = Response; 65 | type Error = crate::Error; 66 | type Future = RoutesFuture; 67 | 68 | fn poll_ready(&mut self, _: &mut Context<'_>) -> Poll> { 69 | Poll::Ready(Ok(())) 70 | } 71 | 72 | fn call(&mut self, req: Request) -> Self::Future { 73 | RoutesFuture(self.router.call(req)) 74 | } 75 | } 76 | 77 | #[pin_project] 78 | pub struct RoutesFuture(#[pin] axum::routing::future::RouteFuture); 79 | 80 | impl fmt::Debug for RoutesFuture { 81 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { 82 | f.debug_tuple("RoutesFuture").finish() 83 | } 84 | } 85 | 86 | impl Future for RoutesFuture { 87 | type Output = Result, crate::Error>; 88 | 89 | fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll { 90 | match futures_util::ready!(self.project().0.poll(cx)) { 91 | Ok(res) => Ok(res.map(crate::boxed)).into(), 92 | Err(err) => match err {}, 93 | } 94 | } 95 | } 96 | -------------------------------------------------------------------------------- /dubbo/src/utils/boxed.rs: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | 18 | use tower::ServiceExt; 19 | use tower_layer::{layer_fn, LayerFn}; 20 | use tower_service::Service; 21 | 22 | use std::{ 23 | fmt, 24 | future::Future, 25 | pin::Pin, 26 | task::{Context, Poll}, 27 | }; 28 | 29 | /// A boxed `Service + Send` trait object. 30 | /// 31 | /// [`BoxService`] turns a service into a trait object, allowing the response 32 | /// future type to be dynamic. This type requires both the service and the 33 | /// response future to be [`Send`]. 34 | /// 35 | /// If you need a boxed [`Service`] that implements [`Clone`] consider using 36 | /// [`BoxCloneService`](crate::util::BoxCloneService). 37 | /// 38 | /// See module level documentation for more details. 39 | pub struct BoxService { 40 | inner: Box> + Send + Sync>, 41 | } 42 | 43 | /// A boxed `Future + Send` trait object. 44 | /// 45 | /// This type alias represents a boxed future that is [`Send`] and can be moved 46 | /// across threads. 47 | type BoxFuture = Pin> + Send>>; 48 | 49 | impl BoxService { 50 | #[allow(missing_docs)] 51 | pub fn new(inner: S) -> Self 52 | where 53 | S: Service + Send + Sync + 'static, 54 | S::Future: Send + 'static, 55 | { 56 | let inner = Box::new(inner.map_future(|f: S::Future| Box::pin(f) as _)); 57 | BoxService { inner } 58 | } 59 | 60 | // /// Returns a [`Layer`] for wrapping a [`Service`] in a [`BoxService`] 61 | // /// middleware. 62 | // /// 63 | // /// [`Layer`]: crate::Layer 64 | pub fn layer() -> LayerFn Self> 65 | where 66 | S: Service + Send + Sync + 'static, 67 | S::Future: Send + 'static, 68 | { 69 | layer_fn(Self::new) 70 | } 71 | } 72 | 73 | impl Service for BoxService { 74 | type Response = U; 75 | type Error = E; 76 | type Future = BoxFuture; 77 | 78 | fn poll_ready(&mut self, cx: &mut Context<'_>) -> Poll> { 79 | self.inner.poll_ready(cx) 80 | } 81 | 82 | fn call(&mut self, request: T) -> BoxFuture { 83 | self.inner.call(request) 84 | } 85 | } 86 | 87 | impl fmt::Debug for BoxService { 88 | fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { 89 | fmt.debug_struct("BoxService").finish() 90 | } 91 | } 92 | -------------------------------------------------------------------------------- /dubbo/src/utils/mod.rs: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | 18 | pub mod boxed; 19 | pub mod boxed_clone; 20 | pub mod tls; 21 | pub mod yaml_utils; 22 | -------------------------------------------------------------------------------- /dubbo/src/utils/tls.rs: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | 18 | use rustls_pemfile::{certs, ec_private_keys, pkcs8_private_keys, rsa_private_keys}; 19 | use std::{ 20 | fs::File, 21 | io::{self, BufReader, Cursor, Read}, 22 | path::Path, 23 | }; 24 | use tokio_rustls::rustls::{Certificate, PrivateKey}; 25 | 26 | pub fn load_certs(path: &Path) -> io::Result> { 27 | certs(&mut BufReader::new(File::open(path)?)) 28 | .map_err(|_| io::Error::new(io::ErrorKind::InvalidInput, "invalid cert")) 29 | .map(|mut certs| certs.drain(..).map(Certificate).collect()) 30 | } 31 | 32 | pub fn load_keys(path: &Path) -> io::Result> { 33 | let file = &mut BufReader::new(File::open(path)?); 34 | let mut data = Vec::new(); 35 | file.read_to_end(&mut data)?; 36 | 37 | let mut cursor = Cursor::new(data); 38 | 39 | let parsers = [rsa_private_keys, pkcs8_private_keys, ec_private_keys]; 40 | 41 | for parser in &parsers { 42 | if let Ok(mut key) = parser(&mut cursor) { 43 | if !key.is_empty() { 44 | return Ok(key.drain(..).map(PrivateKey).collect()); 45 | } 46 | } 47 | cursor.set_position(0); 48 | } 49 | 50 | Err(io::Error::new(io::ErrorKind::InvalidInput, "invalid key")) 51 | } 52 | -------------------------------------------------------------------------------- /dubbo/src/utils/yaml_utils.rs: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | use std::{collections::HashMap, fs, path::PathBuf, sync::Mutex}; 18 | 19 | use anyhow::Error; 20 | use once_cell::sync::Lazy; 21 | use serde_yaml::{from_slice, Value}; 22 | 23 | static YAML_VALUE_CACHE_MAP: Lazy>> = 24 | Lazy::new(|| Mutex::new(HashMap::new())); 25 | 26 | // parse yaml file to structs 27 | pub fn yaml_file_parser(path: PathBuf) -> Result 28 | where 29 | T: serde::de::DeserializeOwned + std::fmt::Debug, 30 | { 31 | if !path.is_file() { 32 | return Err(anyhow::anyhow!("path is not a file: {:?}", path)); 33 | } 34 | let data = fs::read(path.as_path())?; 35 | Ok(from_slice(&data).unwrap()) 36 | } 37 | 38 | // read value by a key like: logging.level 39 | pub fn yaml_key_reader(path: PathBuf, key: &str) -> Result, Error> { 40 | if !path.is_file() { 41 | return Err(anyhow::anyhow!("path is not a file: {:?}", path)); 42 | } 43 | let cache_map = YAML_VALUE_CACHE_MAP.lock().unwrap(); 44 | let split_keys = key.split('.'); 45 | let data = fs::read(path.as_path())?; 46 | let mut value: Value; 47 | match cache_map.contains_key(path.as_path()) { 48 | true => { 49 | value = cache_map.get(path.as_path()).unwrap().clone(); 50 | } 51 | false => { 52 | value = from_slice(&data).unwrap(); 53 | } 54 | } 55 | for key in split_keys { 56 | value = value[key].clone(); 57 | } 58 | if value.is_null() { 59 | return Ok(None); 60 | } 61 | Ok(Some(value.as_str().unwrap().to_string())) 62 | } 63 | 64 | #[cfg(test)] 65 | mod tests { 66 | use serde_yaml::Value; 67 | use std::collections::HashMap; 68 | 69 | use super::{yaml_file_parser, yaml_key_reader}; 70 | use crate::app_root_dir; 71 | 72 | #[test] 73 | fn test_yaml_file_parser() { 74 | let path = app_root_dir() 75 | .join("common") 76 | .join("utils") 77 | .join("tests") 78 | .join("application.yaml"); 79 | let config = yaml_file_parser::>(path).unwrap(); 80 | println!("{:?}", config); 81 | } 82 | 83 | #[test] 84 | fn test_yaml_key_reader() { 85 | let path = app_root_dir() 86 | .join("common") 87 | .join("utils") 88 | .join("tests") 89 | .join("application.yaml"); 90 | let config = yaml_key_reader(path.clone(), "logging.level").unwrap(); 91 | println!("{:?}", config); 92 | let config = yaml_key_reader(path, "logging.file.path").unwrap(); 93 | println!("{:?}", config); 94 | } 95 | } 96 | -------------------------------------------------------------------------------- /examples/README.md: -------------------------------------------------------------------------------- 1 | # 使用VS Code 运行 Dubbo-rust 2 | 3 | #### 首先我们拉下 Dubbo-rust 项目 4 | ```shell 5 | git clone https://github.com/apache/dubbo-rust.git 6 | ``` 7 | #### 打开编辑器准备启动项目 8 | 打开对应的 **Dubbo-rust** 项目 9 | 在当前目录下创建一个新文件夹,名称为 **.vscode** 10 | 11 | ```shell 12 | mkdir .vscode 13 | ``` 14 | 15 | 创建个json文件,名称为launch.json,该文件 **.vscode** 目录下 将下文的内容复制到launch.json中 16 | 17 | ```jsonc 18 | { 19 | // Use IntelliSense to learn about possible attributes. 20 | // Hover to view descriptions of existing attributes. 21 | // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 22 | "version": "0.2.0", 23 | "configurations": [ 24 | { 25 | "type": "lldb", 26 | "request": "launch", 27 | "name": "greeter-server", 28 | "program": "${workspaceFolder}/target/debug/greeter-server", 29 | "args": [], 30 | "cwd": "${workspaceFolder}/examples/greeter/", 31 | "terminal": "console", 32 | "env": { } 33 | }, 34 | { 35 | "type": "lldb", 36 | "request": "launch", 37 | "name": "greeter-client", 38 | "program": "${workspaceFolder}/target/debug/greeter-client", 39 | "args": [], 40 | "cwd": "${workspaceFolder}/examples/greeter/", 41 | "terminal": "console", 42 | "env": {} 43 | }, 44 | ] 45 | } 46 | ``` 47 | 48 | #### 打开 examples/greeter/src/greeter 目录,选择server.rs 49 | 50 | ![image.png](../docs/images/examples/dir-server.png) 51 | 52 | #### 选择左侧的运行按钮,启动 server 服务 53 | 54 | ![image.png](../docs/images/examples/server.png) 55 | 56 | ##### 启动 client 访问server 端 57 | 58 | ![image.png](../docs/images/examples/client.png) 59 | -------------------------------------------------------------------------------- /examples/echo/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "example-echo" 3 | version = "0.3.0" 4 | edition = "2021" 5 | license = "Apache-2.0" 6 | description = "dubbo-rust-examples-echo" 7 | repository = "https://github.com/apache/dubbo-rust.git" 8 | 9 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 10 | 11 | [package.metadata.release] 12 | release = false 13 | 14 | [[bin]] 15 | name = "echo-server" 16 | path = "src/echo/server.rs" 17 | 18 | [[bin]] 19 | name = "echo-client" 20 | path = "src/echo/client.rs" 21 | 22 | [[bin]] 23 | name = "echo-tls-server" 24 | path = "src/echo-tls/server.rs" 25 | 26 | [[bin]] 27 | name = "echo-tls-client" 28 | path = "src/echo-tls/client.rs" 29 | 30 | [dependencies] 31 | http = "0.2" 32 | http-body = "0.4.4" 33 | futures-util = {version = "0.3", default-features = false} 34 | tokio = { version = "1.0", features = [ "rt-multi-thread", "time", "fs", "macros", "net", "signal"] } 35 | prost-derive = {version = "0.11.9", optional = true} 36 | prost = "0.11.9" 37 | prost-serde = "0.3.0" 38 | prost-serde-derive = "0.1.2" 39 | serde = { version = "1.0.171",features = ["derive"] } 40 | async-trait = "0.1.56" 41 | tokio-stream = "0.1" 42 | 43 | dubbo = {path = "../../dubbo"} 44 | dubbo-registry-zookeeper = {path="../../registry/zookeeper"} 45 | 46 | [build-dependencies] 47 | dubbo-build = {path = "../../dubbo-build", version = "0.4.0" } 48 | -------------------------------------------------------------------------------- /examples/echo/README.md: -------------------------------------------------------------------------------- 1 | # Apache Dubbo-rust example 2 | 3 | ## build and run 4 | 5 | ```sh 6 | $ cd github.com/apache/dubbo-rust/examples/echo/ 7 | $ cargo build 8 | 9 | $ # run sever 10 | $ ../../target/debug/echo-server 11 | 12 | $ # run client 13 | $ ../../target/debug/echo-client 14 | reply: EchoResponse { message: "msg1 from server" } 15 | reply: EchoResponse { message: "msg2 from server" } 16 | reply: EchoResponse { message: "msg3 from server" } 17 | ``` 18 | 19 | ## build and run `echo-tls` 20 | 21 | **Please first install the `ca.crt` certificate file under the `fixtures` path to the platform's native certificate store.** 22 | 23 | ```sh 24 | $ cd github.com/apache/dubbo-rust/examples/echo-tls/ 25 | $ cargo build 26 | 27 | $ # run sever 28 | $ ../../target/debug/echo-tls-server 29 | 30 | $ # run client 31 | $ ../../target/debug/echo-tls-client 32 | reply: EchoResponse { message: "msg1 from tls-server" } 33 | reply: EchoResponse { message: "msg2 from tls-server" } 34 | reply: EchoResponse { message: "msg3 from tls-server" } 35 | ``` 36 | -------------------------------------------------------------------------------- /examples/echo/README_CN.md: -------------------------------------------------------------------------------- 1 | # Apache Dubbo-rust 示例 2 | 3 | ## 构建并运行 4 | 5 | ```sh 6 | $ cd github.com/apache/dubbo-rust/examples/echo/ 7 | $ cargo build 8 | 9 | $ # 运行服务端 10 | $ ../../target/debug/echo-server 11 | 12 | $ # 运行客户端 13 | $ ../../target/debug/echo-client 14 | reply: EchoResponse { message: "msg1 from server" } 15 | reply: EchoResponse { message: "msg2 from server" } 16 | reply: EchoResponse { message: "msg3 from server" } 17 | ``` 18 | 19 | ## 构建并运行`echo-tls` 20 | 21 | **请先将`fixtures`路径下的`ca.crt`证书文件安装到系统信任根证书中.** 22 | 23 | ```sh 24 | $ cd github.com/apache/dubbo-rust/examples/echo-tls/ 25 | $ cargo build 26 | 27 | $ # 运行服务端 28 | $ ../../target/debug/echo-tls-server 29 | 30 | $ # 运行客户端 31 | $ ../../target/debug/echo-tls-client 32 | reply: EchoResponse { message: "msg1 from tls-server" } 33 | reply: EchoResponse { message: "msg2 from tls-server" } 34 | reply: EchoResponse { message: "msg3 from tls-server" } 35 | ``` -------------------------------------------------------------------------------- /examples/echo/build.rs: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | 18 | use std::path::PathBuf; 19 | 20 | fn main() { 21 | let path = PathBuf::from("./src/generated"); 22 | println!("path: {:?}", path); 23 | dubbo_build::prost::configure() 24 | .output_dir(path) 25 | .compile(&["proto/echo/echo.proto"], &["proto/"]) 26 | .unwrap(); 27 | } 28 | -------------------------------------------------------------------------------- /examples/echo/fixtures/ca.crt: -------------------------------------------------------------------------------- 1 | -----BEGIN CERTIFICATE----- 2 | MIIDiTCCAnGgAwIBAgIUGJWxrMGe9qRZzAfd5w4XIT3lkcEwDQYJKoZIhvcNAQEL 3 | BQAwVDEVMBMGA1UEAwwMVGVzdCBSb290IENBMQswCQYDVQQGEwJVUzENMAsGA1UE 4 | CAwEVGVzdDENMAsGA1UEBwwEVGVzdDEQMA4GA1UECgwHT3BlbmRhbDAeFw0yMzA4 5 | MTQxMTEzMzRaFw0yNDA4MTMxMTEzMzRaMFQxFTATBgNVBAMMDFRlc3QgUm9vdCBD 6 | QTELMAkGA1UEBhMCVVMxDTALBgNVBAgMBFRlc3QxDTALBgNVBAcMBFRlc3QxEDAO 7 | BgNVBAoMB09wZW5kYWwwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCt 8 | UF6mcDgSyH5t78XnJusvQxsUfv2XydHtvLcIpwkCkIuIj7nF2WH064Gv12x+y42W 9 | mb+5z6JTgHRMRqcyQM8q4PQFrKvxPX8R2Limd7VLBJzYjR7Ma7JIrDohLnfywxUP 10 | 19P5SzaGiro+ZK3t3xCnmtHcYoM+An0mQdKyVV7ytzAfg1PqkfDme19I28fH8cOP 11 | tF+RU8/LEHnte519O1bawx7xNdPsyykMrFij02o1VUeum2K9Wya8xHDixokveYDW 12 | swg5G4Tsy1QfgqFgxAXahIroPIwQvZOGkWVsmPXRXHtHNFG91ntJivv2HBFniUTq 13 | A0UbVdj09T+h+JLc19G9AgMBAAGjUzBRMB0GA1UdDgQWBBQ2672x8uh6Lud0EkjO 14 | wt2aEioeKjAfBgNVHSMEGDAWgBQ2672x8uh6Lud0EkjOwt2aEioeKjAPBgNVHRMB 15 | Af8EBTADAQH/MA0GCSqGSIb3DQEBCwUAA4IBAQCQkLp3GzZOXXXOKiMF6Iev1OUW 16 | w1jr7hVdJHOVGNCD6uZLuwSXJOWnEP8+hp8WvMl7SQAPpVYsTjdqhLATLaAZDucG 17 | sDq6oUTh/v8QVIBm0qF8+iMU8XZfgoeKuY13RXs23hneMAPQ5rcPwQhQEQkkqUvi 18 | Fq8qYFVd5mEr6Z62DT0s544WaBrpHr37mHOv0hIkHtX7Dy2Juc23MYw+W4PSD4fm 19 | sr1kARwHtY1meX+H3iRsX+7juTa33v+7H4IivhcPobIxFp+Hs9R5mx5u80wKMjVv 20 | t3STmB4nE7pABzucrjkSo43jIUwYN4rwydlSma9VkzvY6ry86HQuemycRb9H 21 | -----END CERTIFICATE----- 22 | -------------------------------------------------------------------------------- /examples/echo/fixtures/server.crt: -------------------------------------------------------------------------------- 1 | -----BEGIN CERTIFICATE----- 2 | MIID1zCCAr+gAwIBAgIUJKTfvASV+RnwF7oLO84HZJDyvLwwDQYJKoZIhvcNAQEL 3 | BQAwVDEVMBMGA1UEAwwMVGVzdCBSb290IENBMQswCQYDVQQGEwJVUzENMAsGA1UE 4 | CAwEVGVzdDENMAsGA1UEBwwEVGVzdDEQMA4GA1UECgwHT3BlbmRhbDAeFw0yMzA4 5 | MTQxNDU5MzZaFw0yNDA2MDkxNDU5MzZaMFkxGjAYBgNVBAMMEVJlZGlzIGNlcnRp 6 | ZmljYXRlMQswCQYDVQQGEwJVUzENMAsGA1UECAwEVGVzdDENMAsGA1UEBwwEVGVz 7 | dDEQMA4GA1UECgwHT3BlbmRhbDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoC 8 | ggEBAIwREKDrRgZ2jlR3tpLHvMiW8JDu4JiLBxyrlJJE5ndhuH7MEgwz8HnXvxbD 9 | eyuamzkAzQIvqfVFVTRuVEYyEtoGzIegDL76H9ybuMGhKBK1m0TmiH7bOsAVMqZN 10 | vDtQJiw8qePtSq3G3H7Sw+/oudrJIc/f7kDox/lndKHTBmLbjSrvpkOJk2qnvhPJ 11 | ih4SuLNiW+tHv4sUdYBXXxn2wLHXNLGrlpeW28jtWGfu2noRCzikOYL/jwg2xzXV 12 | cBSuFwQ3swLDG/htqpePVA/sLxbXTt03A8fCajYcKiJdW88gqw4dW01ya8rCr5MU 13 | 1C7lPwNCB8qNn8pdkmrh/Oc0zDsCAwEAAaOBmzCBmDAfBgNVHSMEGDAWgBQ2672x 14 | 8uh6Lud0EkjOwt2aEioeKjAJBgNVHRMEAjAAMAsGA1UdDwQEAwIE8DA+BgNVHREE 15 | NzA1gglsb2NhbGhvc3SHBH8AAAGHBKweAAKHBKweAAOHBKweAASHBKweAAWHBKwe 16 | AAaHBKweAAcwHQYDVR0OBBYEFGvNF07RBwyi3tbpFIJtvWhXAGblMA0GCSqGSIb3 17 | DQEBCwUAA4IBAQAd57+0YXfg8eIe2UkqLshIEonoIpKhmsIpRJyXLOUWYaSHri4w 18 | aDqPjogA39w34UcZsumfSReWBGrCyBroSCqQZOM166tw79+AVdjHHtgNm8pFRhO7 19 | 0vnFdAU30TOQP+mRF3mXz3hcK68U/4cRhXC5jXq8YRLiAG74G3PmXmmk2phtluEL 20 | SLLCvF5pCz3EaYsEKP+ZQpdY3BLp6Me7XDpGWPuNYVwVTJwwM9CLjQ8pxMlz1O1x 21 | HVN7xGtLz4dw9nEqnmjYBvH8aum+iAQPiHVuGfQfqIea28XeuyV4c5TL2b+OUsLY 22 | BRhX+z5OkGHXcMc1QDKo3PZcs8C1w8SC1x9D 23 | -----END CERTIFICATE----- 24 | -------------------------------------------------------------------------------- /examples/echo/fixtures/server.key: -------------------------------------------------------------------------------- 1 | -----BEGIN PRIVATE KEY----- 2 | MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCMERCg60YGdo5U 3 | d7aSx7zIlvCQ7uCYiwccq5SSROZ3Ybh+zBIMM/B5178Ww3srmps5AM0CL6n1RVU0 4 | blRGMhLaBsyHoAy++h/cm7jBoSgStZtE5oh+2zrAFTKmTbw7UCYsPKnj7Uqtxtx+ 5 | 0sPv6LnaySHP3+5A6Mf5Z3Sh0wZi240q76ZDiZNqp74TyYoeErizYlvrR7+LFHWA 6 | V18Z9sCx1zSxq5aXltvI7Vhn7tp6EQs4pDmC/48INsc11XAUrhcEN7MCwxv4baqX 7 | j1QP7C8W107dNwPHwmo2HCoiXVvPIKsOHVtNcmvKwq+TFNQu5T8DQgfKjZ/KXZJq 8 | 4fznNMw7AgMBAAECggEAA5l0ABv7s90mbDTwBqvxBdtHJFpXKuRhEui1NosPEctQ 9 | 6+/qQ3uu4YVcqO+YweFFEufFMkSvopjHse4R5q87vR7xRkej0Yvo914zFxrBRmB6 10 | CdZoyeXFXTv442gvqaXgzUCOgcfOeafDcSjmayBjwk5qkDEqKhXb/w9HDS+N7vVk 11 | BU+b/lMzQbGWb/oc3pHmEYXqFR+sFkHM2nCWBvQ1hRX4TVaeZpUWH7RBE95z87ug 12 | F21yqEjQfaTh2cidKXWtnozxIv2XgUncY40njdhRRzyJqWIW4CEdxIAX0IWT0z2+ 13 | 4L59DoNyYaimnaaSmNDj5WgDgL7tlTziXBJfBTpqDQKBgQDAe6Tf49eZINZ6bxHC 14 | RDzFSKikBOvC9rkhGOzD6JBALPbdWH9HnnH4cT5F4b5y96rPEqzO1+RYQdIF4GDx 15 | NYafMx8Nht0j0WWJLkygUCa8guqaaFczaquaIHQ2YpzzhpLlmAdEz1Jrsk2LfM2Q 16 | 58b7JHb+Aq/+UAIuBhL7FlRf7QKBgQC6SXR6opkjUfkrsWcQiB5CJDk7zuL8G+Ks 17 | Jle2S1TzFdBL5rNnVttC7yYmZIP7qN6zDtsbDxqW5gEeDmyGDixLeQ0kQ/oPU2/y 18 | lPr9rHx+BUWEGyDiCfG21Y6R/jdfrA4R5T8vPmJXOnnppXZ5Gqi1X0aHprbLYWhz 19 | HpkvBaHHxwKBgAGx1PzHo8FMYbcIPU7JjQNrpVh0VqMLywt4jbUX2hVGkBHY0p4N 20 | zhES5ip1V1jpx041auITUoZYZgH5PMFC6GGEcLSMyGulT1CK4M/UhNLKEEi1vHbO 21 | bJ5ZxMwpyBn4yFhPI1k+vgoGstoUijbJY54YbxfDbEs/5xUCpq4hPzLtAoGAZVBr 22 | 3AKwnMgJZxz9u7z8D+bZhdCYHJsh5ZSY4ZkI44f6mD0pV0uixj2AlyLVsTn/nIy4 23 | 13eYc3c2Jl2b4jC1IHr+jbm2tz0exmUGOI7lyjgdvaJveOAFqPVuq7IB9bOCl3MB 24 | sTURkPVJtqv5yhWYqcPefQpLokMg5nM+xpcejKMCgYEAqv5gj3ez0HmLv/9k86Zs 25 | 8/780lNcYnB1dQYNJ7g3T6wu8WVGNtzOdPXGTMX9sbv9Smq0cZLZKNMtXDsc5aJT 26 | 5yzysPkDxqSK4vJmng74aHUI2HW+HvPqWLZnXC0IYGFvN8KyVkdp/FyhQMNMp6ip 27 | 5rgp5RpXJk5MhvvlYdZrz5Q= 28 | -----END PRIVATE KEY----- 29 | -------------------------------------------------------------------------------- /examples/echo/proto/echo/echo.proto: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | syntax = "proto3"; 18 | 19 | package grpc.examples.echo; 20 | 21 | // EchoRequest is the request for echo. 22 | message EchoRequest { 23 | string message = 1; 24 | } 25 | 26 | // EchoResponse is the response for echo. 27 | message EchoResponse { 28 | string message = 1; 29 | } 30 | 31 | // Echo is the echo service. 32 | service Echo { 33 | // UnaryEcho is unary echo. 34 | rpc UnaryEcho(EchoRequest) returns (EchoResponse) {} 35 | // ServerStreamingEcho is server side streaming. 36 | rpc ServerStreamingEcho(EchoRequest) returns (stream EchoResponse) {} 37 | // ClientStreamingEcho is client side streaming. 38 | rpc ClientStreamingEcho(stream EchoRequest) returns (EchoResponse) {} 39 | // BidirectionalStreamingEcho is bidi streaming. 40 | rpc BidirectionalStreamingEcho(stream EchoRequest) returns (stream EchoResponse) {} 41 | } -------------------------------------------------------------------------------- /examples/echo/src/generated/mod.rs: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | 18 | #[path = "grpc.examples.echo.rs"] 19 | pub mod generated; 20 | -------------------------------------------------------------------------------- /examples/echo/src/lib.rs: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | 18 | pub mod generated; 19 | -------------------------------------------------------------------------------- /examples/greeter/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "example-greeter" 3 | version = "0.3.0" 4 | edition = "2021" 5 | license = "Apache-2.0" 6 | description = "dubbo-rust-examples-greeter" 7 | repository = "https://github.com/apache/dubbo-rust.git" 8 | 9 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 10 | 11 | [package.metadata.release] 12 | release = false 13 | 14 | [[bin]] 15 | name = "greeter-server" 16 | path = "src/greeter/server.rs" 17 | 18 | [[bin]] 19 | name = "greeter-client" 20 | path = "src/greeter/client.rs" 21 | 22 | [dependencies] 23 | http = "0.2" 24 | http-body = "0.4.4" 25 | futures-util = { version = "0.3", default-features = false } 26 | tokio = { version = "1.0", features = ["rt-multi-thread", "time", "fs", "macros", "net", "signal"] } 27 | prost-derive = { version = "0.11.9", optional = true } 28 | prost = "0.11.9" 29 | serde = { version = "1.0.171",features = ["derive"] } 30 | prost-serde = "0.3.0" 31 | prost-serde-derive = "0.1.2" 32 | async-trait = "0.1.56" 33 | tokio-stream = "0.1" 34 | dubbo = { path = "../../dubbo"} 35 | dubbo-registry-zookeeper = {path="../../registry/zookeeper"} 36 | dubbo-registry-nacos = {path="../../registry/nacos"} 37 | 38 | [build-dependencies] 39 | dubbo-build = { path = "../../dubbo-build", version = "0.4.0" } 40 | -------------------------------------------------------------------------------- /examples/greeter/README.md: -------------------------------------------------------------------------------- 1 | # Apache Dubbo-rust example - greeter 2 | 3 | ## build and run 4 | 5 | ```sh 6 | $ cd github.com/apache/dubbo-rust/examples/greeter/ 7 | $ cargo build 8 | 9 | $ # run sever 10 | $ ../../target/debug/greeter-server 11 | 12 | $ # run client 13 | $ ../../target/debug/greeter-client 14 | # unary call 15 | Response: GreeterReply { message: "hello, dubbo-rust" } 16 | # client stream 17 | client streaming, Response: GreeterReply { message: "hello client streaming" } 18 | # bi stream 19 | parts: Metadata { inner: {"date": "Wed, 28 Sep 2022 08:36:50 GMT", "content-type": "application/grpc"} } 20 | reply: GreeterReply { message: "server reply: \"msg1 from client\"" } 21 | reply: GreeterReply { message: "server reply: \"msg2 from client\"" } 22 | reply: GreeterReply { message: "server reply: \"msg3 from client\"" } 23 | trailer: Some(Metadata { inner: {"grpc-message": "poll trailer successfully.", "grpc-accept-encoding": "gzip,identity", "grpc-status": "0", "content-type": "application/grpc"} }) 24 | # server stream 25 | parts: Metadata { inner: {"content-type": "application/grpc", "date": "Wed, 28 Sep 2022 08:36:50 GMT"} } 26 | reply: GreeterReply { message: "msg1 from server" } 27 | reply: GreeterReply { message: "msg2 from server" } 28 | reply: GreeterReply { message: "msg3 from server" } 29 | trailer: Some(Metadata { inner: {"content-type": "application/grpc", "grpc-status": "0", "grpc-accept-encoding": "gzip,identity", "grpc-message": "poll trailer successfully."} }) 30 | ``` 31 | -------------------------------------------------------------------------------- /examples/greeter/README_CN.md: -------------------------------------------------------------------------------- 1 | # Apache Dubbo-rust 示例 - greeter 2 | 3 | ## 构建并运行 4 | 5 | ```sh 6 | $ cd github.com/apache/dubbo-rust/examples/greeter/ 7 | $ cargo build 8 | 9 | $ # 运行服务端 10 | $ ../../target/debug/greeter-server 11 | 12 | $ # 运行客户端 13 | $ ../../target/debug/greeter-client 14 | # unary call 15 | Response: GreeterReply { message: "hello, dubbo-rust" } 16 | # client stream 17 | client streaming, Response: GreeterReply { message: "hello client streaming" } 18 | # bi stream 19 | parts: Metadata { inner: {"date": "Wed, 28 Sep 2022 08:36:50 GMT", "content-type": "application/grpc"} } 20 | reply: GreeterReply { message: "server reply: \"msg1 from client\"" } 21 | reply: GreeterReply { message: "server reply: \"msg2 from client\"" } 22 | reply: GreeterReply { message: "server reply: \"msg3 from client\"" } 23 | trailer: Some(Metadata { inner: {"grpc-message": "poll trailer successfully.", "grpc-accept-encoding": "gzip,identity", "grpc-status": "0", "content-type": "application/grpc"} }) 24 | # server stream 25 | parts: Metadata { inner: {"content-type": "application/grpc", "date": "Wed, 28 Sep 2022 08:36:50 GMT"} } 26 | reply: GreeterReply { message: "msg1 from server" } 27 | reply: GreeterReply { message: "msg2 from server" } 28 | reply: GreeterReply { message: "msg3 from server" } 29 | trailer: Some(Metadata { inner: {"content-type": "application/grpc", "grpc-status": "0", "grpc-accept-encoding": "gzip,identity", "grpc-message": "poll trailer successfully."} }) 30 | ``` 31 | -------------------------------------------------------------------------------- /examples/greeter/application.yaml: -------------------------------------------------------------------------------- 1 | logging: 2 | level: INFO 3 | dubbo: 4 | protocols: 5 | triple: 6 | ip: 0.0.0.0 7 | port: '8888' 8 | name: tri 9 | registries: 10 | demoZK: 11 | protocol: zookeeper 12 | address: 10.0.6.6:2181 13 | provider: 14 | services: 15 | GreeterProvider: 16 | version: 1.0.0 17 | group: test 18 | tag: red 19 | protocol: triple 20 | interface: org.apache.dubbo.sample.tri.Greeter -------------------------------------------------------------------------------- /examples/greeter/build.rs: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | 18 | fn main() { 19 | dubbo_build::prost::configure() 20 | .compile(&["proto/greeter.proto"], &["proto/"]) 21 | .unwrap(); 22 | } 23 | -------------------------------------------------------------------------------- /examples/greeter/proto/greeter.proto: -------------------------------------------------------------------------------- 1 | // Licensed to the Apache Software Foundation (ASF) under one or more 2 | // contributor license agreements. See the NOTICE file distributed with 3 | // this work for additional information regarding copyright ownership. 4 | // The ASF licenses this file to You under the Apache License, Version 2.0 5 | // (the "License"); you may not use this file except in compliance with 6 | // the License. You may obtain a copy of the License at 7 | // 8 | // http://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | syntax = "proto3"; 16 | 17 | option java_multiple_files = true; 18 | 19 | package org.apache.dubbo.sample.tri; 20 | 21 | 22 | // The request message containing the user's name. 23 | message GreeterRequest { 24 | string name = 1; 25 | } 26 | 27 | // The response message containing the greetings 28 | message GreeterReply { 29 | string message = 1; 30 | } 31 | 32 | service Greeter { 33 | 34 | // unary 35 | rpc greet(GreeterRequest) returns (GreeterReply); 36 | 37 | // clientStream 38 | rpc greetClientStream(stream GreeterRequest) returns (GreeterReply); 39 | 40 | // serverStream 41 | rpc greetServerStream(GreeterRequest) returns (stream GreeterReply); 42 | 43 | // bi streaming 44 | rpc greetStream(stream GreeterRequest) returns (stream GreeterReply); 45 | 46 | } 47 | -------------------------------------------------------------------------------- /protocol/README.md: -------------------------------------------------------------------------------- 1 | ```markdown 2 | /protocol 3 | /protocol # define protocol abstract layer 4 | /dubbo2 # for dubbo2 protocol, hessian2 codec as default 5 | /triple # for triple protocol 6 | ``` -------------------------------------------------------------------------------- /protocol/base/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "protocol-base" 3 | version = "0.1.0" 4 | edition = "2021" 5 | 6 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 7 | 8 | [dependencies] 9 | dashmap.workspace = true 10 | dubbo-base.workspace = true 11 | thiserror.workspace = true -------------------------------------------------------------------------------- /protocol/base/src/error.rs: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | use thiserror::Error; 18 | 19 | #[derive(Error, Debug)] 20 | pub enum InvokerError { 21 | #[error("unknown invoker error.")] 22 | Unknown, 23 | } 24 | -------------------------------------------------------------------------------- /protocol/base/src/invocation.rs: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | 18 | use std::{any::Any, sync::Arc}; 19 | 20 | pub trait Invocation { 21 | fn get_method_name(&self) -> String; 22 | fn get_parameter_types(&self) -> Vec; 23 | fn get_arguments(&self) -> Vec; 24 | fn get_reply(&self) -> Arc; 25 | } 26 | 27 | pub type BoxInvocation = Arc; 28 | -------------------------------------------------------------------------------- /protocol/base/src/invoker.rs: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | use crate::{ 18 | invocation::BoxInvocation, 19 | output::{BoxOutput, RPCOutput}, 20 | }; 21 | use dubbo_base::{Node, Url}; 22 | use std::{ 23 | fmt::{Display, Formatter}, 24 | sync::{ 25 | atomic::{AtomicBool, Ordering}, 26 | Arc, 27 | }, 28 | }; 29 | 30 | pub struct BaseInvoker { 31 | url: Arc, 32 | available: AtomicBool, 33 | destroyed: AtomicBool, 34 | } 35 | 36 | pub trait Invoker { 37 | type Output; 38 | fn invoke(&self, invocation: BoxInvocation) -> Self::Output; 39 | } 40 | 41 | impl Invoker for BaseInvoker { 42 | type Output = BoxOutput; 43 | fn invoke(&self, _invocation: BoxInvocation) -> Self::Output { 44 | Arc::new(RPCOutput::default()) 45 | } 46 | } 47 | 48 | impl Node for BaseInvoker { 49 | fn get_url(&self) -> Arc { 50 | self.url.clone() 51 | } 52 | 53 | fn is_available(&self) -> bool { 54 | self.available.load(Ordering::SeqCst) 55 | } 56 | 57 | fn destroy(&self) { 58 | self.destroyed.store(true, Ordering::SeqCst); 59 | self.available.store(false, Ordering::SeqCst) 60 | } 61 | fn is_destroyed(&self) -> bool { 62 | self.destroyed.load(Ordering::SeqCst) 63 | } 64 | } 65 | 66 | impl Display for BaseInvoker { 67 | fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { 68 | f.debug_struct("Invoker") 69 | .field("protocol", &self.url.protocol()) 70 | .field("host", &self.url.host()) 71 | .field("path", &self.url.path()) 72 | .finish() 73 | } 74 | } 75 | 76 | impl BaseInvoker { 77 | pub fn new(url: Url) -> Self { 78 | Self { 79 | url: Arc::new(url), 80 | available: AtomicBool::new(true), 81 | destroyed: AtomicBool::new(false), 82 | } 83 | } 84 | } 85 | -------------------------------------------------------------------------------- /protocol/base/src/lib.rs: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | 18 | pub mod error; 19 | pub mod invocation; 20 | pub mod invoker; 21 | pub mod output; 22 | 23 | pub type ProtocolName = &'static str; 24 | -------------------------------------------------------------------------------- /protocol/dubbo2/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "protocol-dubbo2" 3 | version = "0.1.0" 4 | edition = "2021" 5 | 6 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 7 | 8 | [dependencies] 9 | remoting-base.workspace = true 10 | protocol-base.workspace = true 11 | -------------------------------------------------------------------------------- /protocol/dubbo2/src/lib.rs: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | pub fn add(left: usize, right: usize) -> usize { 18 | left + right 19 | } 20 | 21 | #[cfg(test)] 22 | mod tests { 23 | use super::*; 24 | 25 | #[test] 26 | fn it_works() { 27 | let result = add(2, 2); 28 | assert_eq!(result, 4); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /protocol/triple/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "protocol-triple" 3 | version = "0.1.0" 4 | edition = "2021" 5 | 6 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 7 | 8 | [dependencies] 9 | remoting-net.workspace = true 10 | protocol-base.workspace = true 11 | -------------------------------------------------------------------------------- /protocol/triple/src/lib.rs: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | 18 | pub mod triple_invoker; 19 | 20 | pub fn add(left: usize, right: usize) -> usize { 21 | left + right 22 | } 23 | 24 | #[cfg(test)] 25 | mod tests { 26 | use super::*; 27 | 28 | #[test] 29 | fn it_works() { 30 | let result = add(2, 2); 31 | assert_eq!(result, 4); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /protocol/triple/src/triple_invoker.rs: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | use dubbo_base::{Node, Url}; 18 | 19 | use protocol_base::{ 20 | invocation::BoxInvocation, 21 | invoker::{BaseInvoker, Invoker}, 22 | }; 23 | use std::sync::Arc; 24 | 25 | pub struct TripleInvoker { 26 | base: BaseInvoker, 27 | } 28 | 29 | impl Invoker for TripleInvoker { 30 | type Output = (); 31 | 32 | fn invoke(&self, _invocation: BoxInvocation) -> Self::Output { 33 | todo!() 34 | } 35 | } 36 | 37 | impl Node for TripleInvoker { 38 | fn get_url(&self) -> Arc { 39 | self.base.get_url() 40 | } 41 | 42 | fn is_available(&self) -> bool { 43 | self.base.is_available() 44 | } 45 | 46 | fn destroy(&self) { 47 | todo!() 48 | } 49 | 50 | fn is_destroyed(&self) -> bool { 51 | self.base.is_destroyed() 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /registry/README.md: -------------------------------------------------------------------------------- 1 | /registry 2 | /nacos # nacos registry and servicediscovery implementation 3 | /zookeeper # zookeeper registry and servicediscovery implementation -------------------------------------------------------------------------------- /registry/nacos/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "dubbo-registry-nacos" 3 | version = "0.4.0" 4 | edition = "2021" 5 | license = "Apache-2.0" 6 | description = "dubbo-rust-registry-nacos" 7 | repository = "https://github.com/apache/dubbo-rust.git" 8 | 9 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 10 | 11 | [dependencies] 12 | nacos-sdk = { version = "0.3", features = ["naming", "auth-by-http", "async"] } 13 | dubbo = {path = "../../dubbo/", version = "0.4.0" } 14 | serde_json.workspace = true 15 | serde = { workspace = true, features = ["derive"] } 16 | anyhow.workspace = true 17 | tokio.workspace = true 18 | async-trait.workspace = true 19 | 20 | [dev-dependencies] 21 | tracing-subscriber = "0.3.16" 22 | tracing = "0.1" 23 | -------------------------------------------------------------------------------- /registry/zookeeper/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "dubbo-registry-zookeeper" 3 | version = "0.4.0" 4 | edition = "2021" 5 | license = "Apache-2.0" 6 | description = "dubbo-rust-registry-zookeeper" 7 | repository = "https://github.com/apache/dubbo-rust.git" 8 | 9 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 10 | 11 | [dependencies] 12 | zookeeper = "0.8.0" 13 | dubbo = {path = "../../dubbo/", version = "0.4.0" } 14 | anyhow.workspace = true 15 | serde_json.workspace = true 16 | serde = { workspace = true, features = ["derive"] } 17 | urlencoding.workspace = true 18 | tokio.workspace = true 19 | async-trait.workspace = true 20 | -------------------------------------------------------------------------------- /release.toml: -------------------------------------------------------------------------------- 1 | shared-version = true 2 | tag-prefix = "" 3 | -------------------------------------------------------------------------------- /remoting/README.md: -------------------------------------------------------------------------------- 1 | /remoting 2 | /net # for dubbo2 3 | /http # on top of net, for hessian/rest/grpc/triple protocol 4 | /exchange # convert tcp/http to invocation or invoker for protocol layer 5 | /zookeeper # zk client for registry and config center 6 | /nacos # nacos client for registry and config center -------------------------------------------------------------------------------- /remoting/base/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "remoting-base" 3 | version = "0.1.0" 4 | edition = "2021" 5 | 6 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 7 | 8 | [dependencies] 9 | bytes.workspace = true 10 | thiserror.workspace = true 11 | dashmap.workspace = true 12 | protocol-base.workspace = true 13 | anyhow.workspace = true -------------------------------------------------------------------------------- /remoting/base/src/builder/client.rs: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | // for tower ServiceBuilder; the input starts from Bytes 18 | // exchange is a part of LayerStack 19 | -------------------------------------------------------------------------------- /remoting/base/src/builder/mod.rs: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | pub mod client; 18 | pub mod server; 19 | -------------------------------------------------------------------------------- /remoting/base/src/builder/server.rs: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | // for tower ServiceBuilder; the input starts from Bytes 18 | // exchange is a part of LayerStack 19 | -------------------------------------------------------------------------------- /remoting/base/src/error.rs: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | use protocol_base::ProtocolName; 18 | use thiserror::Error; 19 | 20 | #[derive(Error, Debug)] 21 | pub enum CodecError { 22 | #[error("unknown codec error.")] 23 | Unknown, 24 | #[error("protocol {0} is registered.")] 25 | RegistryExistsProtocol(ProtocolName), 26 | } 27 | 28 | #[derive(Error, Debug)] 29 | pub enum ClientError { 30 | #[error("unknown client error")] 31 | Unknown, 32 | } 33 | -------------------------------------------------------------------------------- /remoting/base/src/exchange/client.rs: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | 18 | use dubbo_base::Url; 19 | use std::{ 20 | sync::{ 21 | atomic::{AtomicBool, AtomicI32, Ordering}, 22 | Arc, 23 | }, 24 | time, 25 | time::Duration, 26 | }; 27 | 28 | use crate::{ 29 | error::ClientError, 30 | exchange::{Request, Response}, 31 | }; 32 | 33 | pub struct BoxedClient(Arc); 34 | 35 | pub trait Client: Sync + Send { 36 | fn connect(&self, url: Url) -> Result<(), ClientError>; 37 | fn request(&self, request: Request, timeout: Duration) -> Result; 38 | fn close(&mut self) -> Result<(), ClientError>; 39 | fn is_available(&self) -> bool; 40 | } 41 | 42 | pub struct ExchangeClient { 43 | connection_timeout: Duration, // timeout when connecting to server 44 | address: String, // listening ip:port 45 | client: Option, // dealing with the transports 46 | init: AtomicBool, // whether the client is initialized 47 | active: AtomicI32, // the number of active service bind to this client 48 | } 49 | 50 | impl ExchangeClient { 51 | pub fn new(url: Url, client: BoxedClient, connection_timeout: Duration) -> Self { 52 | ExchangeClient { 53 | connection_timeout, 54 | address: url.authority().to_owned(), 55 | client: None, 56 | init: AtomicBool::new(false), 57 | active: AtomicI32::new(0), 58 | } 59 | } 60 | } 61 | 62 | impl Client for ExchangeClient { 63 | fn connect(&self, url: Url) -> Result<(), ClientError> { 64 | if self.init.load(Ordering::SeqCst) { 65 | return Ok(()); 66 | } 67 | Ok(()) 68 | } 69 | 70 | fn request(&self, request: Request, timeout: Duration) -> Result { 71 | todo!() 72 | } 73 | 74 | fn close(&mut self) -> Result<(), ClientError> { 75 | self.init.store(false, Ordering::SeqCst); 76 | Ok(()) 77 | } 78 | 79 | fn is_available(&self) -> bool { 80 | let client = self.client.as_ref().unwrap(); 81 | client.0.is_available() 82 | } 83 | } 84 | -------------------------------------------------------------------------------- /remoting/base/src/exchange/mod.rs: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | 18 | use crate::error::CodecError; 19 | use std::{any::Any, sync::Arc}; 20 | pub mod client; 21 | pub mod server; 22 | 23 | pub type BoxedExchangeBody = Arc; 24 | 25 | pub struct Request { 26 | id: u64, 27 | version: String, // protocol version 28 | serial_id: u8, // serial ID (ignore) 29 | body: Option, 30 | two_way: bool, 31 | event: bool, 32 | } 33 | 34 | pub struct Response { 35 | id: u64, 36 | version: String, // protocol version 37 | serial_id: u8, // serial ID (ignore) 38 | status: u8, 39 | body: Option, // mean result 40 | event: bool, 41 | error: Option, 42 | } 43 | 44 | impl Response { 45 | fn is_heart_beat(&self) -> bool { 46 | self.event && self.body.is_none() 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /remoting/base/src/exchange/server.rs: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | 18 | use anyhow::{Error, Result}; 19 | use dubbo_base::Url; 20 | use std::sync::Arc; 21 | 22 | pub struct BoxedServer(Arc); 23 | 24 | pub trait Server: Sync + Send { 25 | fn start(&self) -> Result<(), Error>; 26 | fn stop(&self) -> Result<(), Error>; 27 | } 28 | 29 | pub struct ExchangeServer { 30 | server: BoxedServer, 31 | url: Url, 32 | } 33 | 34 | impl ExchangeServer { 35 | pub fn new(url: Url, server: BoxedServer) -> Self { 36 | ExchangeServer { server, url } 37 | } 38 | } 39 | 40 | impl Server for ExchangeServer { 41 | fn start(&self) -> Result<(), Error> { 42 | self.server.0.start() 43 | } 44 | 45 | fn stop(&self) -> Result<(), Error> { 46 | self.server.0.stop() 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /remoting/base/src/lib.rs: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | #![cfg_attr( 18 | debug_assertions, 19 | allow(dead_code, unused_imports, unused_variables, unused_mut) 20 | )] 21 | pub use codec::Codec; 22 | pub mod builder; 23 | pub mod codec; 24 | pub mod error; 25 | pub mod exchange; 26 | 27 | pub use exchange::{BoxedExchangeBody, Request, Response}; 28 | -------------------------------------------------------------------------------- /remoting/http/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "remoting-http" 3 | version = "0.1.0" 4 | edition = "2021" 5 | 6 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 7 | 8 | [dependencies] 9 | -------------------------------------------------------------------------------- /remoting/http/src/lib.rs: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | pub fn add(left: usize, right: usize) -> usize { 18 | left + right 19 | } 20 | 21 | #[cfg(test)] 22 | mod tests { 23 | use super::*; 24 | 25 | #[test] 26 | fn it_works() { 27 | let result = add(2, 2); 28 | assert_eq!(result, 4); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /remoting/net/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "remoting-net" 3 | version = "0.1.0" 4 | edition = "2021" 5 | 6 | [[bench]] 7 | name = "transport_benchmark" 8 | harness=false 9 | 10 | [dependencies] 11 | pin-project.workspace = true 12 | tokio = { workspace = true, features = ["net", "time", "sync", "io-util", "test-util", "macros"] } 13 | tokio-stream = { workspace = true, features = ["net"] } 14 | tower.workspace = true 15 | socket2.workspace = true 16 | async-trait.workspace = true 17 | dashmap.workspace = true 18 | lazy_static.workspace = true 19 | futures.workspace = true 20 | bb8.workspace = true 21 | -------------------------------------------------------------------------------- /remoting/net/benches/transport_benchmark/main.rs: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | fn main() { 18 | todo!() 19 | } 20 | -------------------------------------------------------------------------------- /remoting/net/src/lib.rs: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | 18 | pub mod conn; 19 | pub mod dial; 20 | pub mod incoming; 21 | mod pool; 22 | mod probe; 23 | 24 | use std::{borrow::Cow, fmt, net::Ipv6Addr, path::Path}; 25 | 26 | pub use incoming::{DefaultIncoming, MakeIncoming}; 27 | 28 | #[derive(Clone, Debug, PartialEq, Eq, Hash)] 29 | pub enum Address { 30 | Ip(std::net::SocketAddr), 31 | #[cfg(target_family = "unix")] 32 | Unix(Cow<'static, Path>), 33 | } 34 | 35 | impl Address { 36 | pub fn favor_dual_stack(self) -> Self { 37 | match self { 38 | Address::Ip(addr) => { 39 | if addr.ip().is_unspecified() && should_favor_ipv6() { 40 | Address::Ip((Ipv6Addr::UNSPECIFIED, addr.port()).into()) 41 | } else { 42 | self 43 | } 44 | } 45 | #[cfg(target_family = "unix")] 46 | _ => self, 47 | } 48 | } 49 | } 50 | 51 | fn should_favor_ipv6() -> bool { 52 | let probed = probe::probe(); 53 | !probed.ipv4 || probed.ipv4_mapped_ipv6 54 | } 55 | 56 | impl fmt::Display for Address { 57 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { 58 | match self { 59 | Address::Ip(addr) => write!(f, "{addr}"), 60 | #[cfg(target_family = "unix")] 61 | Address::Unix(path) => write!(f, "{}", path.display()), 62 | } 63 | } 64 | } 65 | 66 | impl From for Address { 67 | fn from(addr: std::net::SocketAddr) -> Self { 68 | Address::Ip(addr) 69 | } 70 | } 71 | 72 | #[cfg(target_family = "unix")] 73 | impl From> for Address { 74 | fn from(addr: Cow<'static, Path>) -> Self { 75 | Address::Unix(addr) 76 | } 77 | } 78 | 79 | #[cfg(target_family = "unix")] 80 | impl TryFrom for Address { 81 | type Error = std::io::Error; 82 | 83 | fn try_from(value: tokio::net::unix::SocketAddr) -> Result { 84 | Ok(Address::Unix(Cow::Owned( 85 | value 86 | .as_pathname() 87 | .ok_or_else(|| { 88 | std::io::Error::new( 89 | std::io::ErrorKind::Other, 90 | "unix socket doesn't have an address", 91 | ) 92 | })? 93 | .to_owned(), 94 | ))) 95 | } 96 | } 97 | -------------------------------------------------------------------------------- /remoting/net/src/pool.rs: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | -------------------------------------------------------------------------------- /remoting/net/src/probe.rs: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | use lazy_static::lazy_static; 18 | use socket2::{Domain, Protocol, Socket, Type}; 19 | 20 | #[derive(Debug)] 21 | pub struct IpStackCapability { 22 | pub ipv4: bool, 23 | pub ipv6: bool, 24 | pub ipv4_mapped_ipv6: bool, 25 | } 26 | 27 | impl IpStackCapability { 28 | fn probe() -> Self { 29 | IpStackCapability { 30 | ipv4: Self::probe_ipv4(), 31 | ipv6: Self::probe_ipv6(), 32 | ipv4_mapped_ipv6: Self::probe_ipv4_mapped_ipv6(), 33 | } 34 | } 35 | 36 | fn probe_ipv4() -> bool { 37 | let s = Socket::new(Domain::IPV4, Type::STREAM, Some(Protocol::TCP)); 38 | s.is_ok() 39 | } 40 | 41 | fn probe_ipv6() -> bool { 42 | let s = Socket::new(Domain::IPV6, Type::STREAM, Some(Protocol::TCP)); 43 | let s = match s { 44 | Ok(s) => s, 45 | Err(_) => return false, 46 | }; 47 | // this error is ignored in go, follow their strategy 48 | let _ = s.set_only_v6(true); 49 | let addr: std::net::SocketAddr = ([0, 0, 0, 0, 0, 0, 0, 1], 0).into(); 50 | s.bind(&addr.into()).is_ok() 51 | } 52 | 53 | fn probe_ipv4_mapped_ipv6() -> bool { 54 | let s = Socket::new(Domain::IPV6, Type::STREAM, Some(Protocol::TCP)); 55 | let s = match s { 56 | Ok(s) => s, 57 | Err(_) => return false, 58 | }; 59 | !s.only_v6().unwrap_or(true) 60 | } 61 | } 62 | 63 | pub fn probe() -> &'static IpStackCapability { 64 | lazy_static! { 65 | static ref CAPABILITY: IpStackCapability = IpStackCapability::probe(); 66 | } 67 | &CAPABILITY 68 | } 69 | 70 | #[cfg(test)] 71 | mod tests { 72 | use super::*; 73 | 74 | #[test] 75 | #[ignore] 76 | fn tryout_probe() { 77 | println!("{:?}", probe()); 78 | } 79 | } 80 | -------------------------------------------------------------------------------- /remoting/xds/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "dubbo-remoting-xds" 3 | version = "0.3.0" 4 | edition = "2021" 5 | license = "Apache-2.0" 6 | description = "remoting-xds" 7 | repository = "https://github.com/apache/dubbo-rust.git" 8 | 9 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 10 | 11 | [dependencies] 12 | -------------------------------------------------------------------------------- /remoting/xds/src/client/client.rs: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | -------------------------------------------------------------------------------- /remoting/xds/src/client/mod.rs: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | -------------------------------------------------------------------------------- /remoting/xds/src/lib.rs: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | 18 | mod client; 19 | 20 | #[cfg(test)] 21 | mod tests { 22 | #[test] 23 | fn it_works() { 24 | let result = 2 + 2; 25 | assert_eq!(result, 4); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /remoting/xds/src/server/mod.rs: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | -------------------------------------------------------------------------------- /remoting/xds/src/server/server.rs: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | -------------------------------------------------------------------------------- /remoting/zookeeper/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "remoting-zookeeper" 3 | version = "0.1.0" 4 | edition = "2021" 5 | 6 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 7 | 8 | [dependencies] 9 | -------------------------------------------------------------------------------- /remoting/zookeeper/src/lib.rs: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | pub fn add(left: usize, right: usize) -> usize { 18 | left + right 19 | } 20 | 21 | #[cfg(test)] 22 | mod tests { 23 | use super::*; 24 | 25 | #[test] 26 | fn it_works() { 27 | let result = add(2, 2); 28 | assert_eq!(result, 4); 29 | } 30 | } 31 | --------------------------------------------------------------------------------