├── .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 |
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 | [](https://github.com/apache/dubbo-rust/actions/workflows/github-actions.yml?query=branch%3Amain)
9 | 
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 | 
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 |
5 |
6 | Apache Dubbo-rust, Dubbo RPC框架的Rust实现。请访问 [Dubbo官网](https://dubbo.apache.org/) 查看更多信息.
7 |
8 | [](https://github.com/apache/dubbo-rust/actions/workflows/github-actions.yml?query=branch%3Amain)
9 | 
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 | 
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