Skip to content
Snippets Groups Projects
Commit f3b5be5d authored by Patrick's avatar Patrick
Browse files

Merge remote-tracking branch 'upstream/develop' into rest

parents fa5ee683 a7ae33fa
No related branches found
No related tags found
No related merge requests found
Showing
with 1074 additions and 160 deletions
...@@ -30,4 +30,5 @@ coverage.txt ...@@ -30,4 +30,5 @@ coverage.txt
remoting/zookeeper/zookeeper-4unittest/ remoting/zookeeper/zookeeper-4unittest/
config_center/zookeeper/zookeeper-4unittest/ config_center/zookeeper/zookeeper-4unittest/
registry/zookeeper/zookeeper-4unittest/ registry/zookeeper/zookeeper-4unittest/
registry/consul/agent* registry/consul/agent*
\ No newline at end of file config_center/apollo/mockDubbog.properties.json
language: go language: go
os:
- linux
- osx
go: go:
- "1.12" - "1.13"
env: env:
- GO111MODULE=on - GO111MODULE=on
...@@ -10,10 +14,7 @@ install: true ...@@ -10,10 +14,7 @@ install: true
script: script:
- go fmt ./... && [[ -z `git status -s` ]] - go fmt ./... && [[ -z `git status -s` ]]
- mkdir -p remoting/zookeeper/zookeeper-4unittest/contrib/fatjar config_center/zookeeper/zookeeper-4unittest/contrib/fatjar registry/zookeeper/zookeeper-4unittest/contrib/fatjar - chmod u+x before_ut.sh && ./before_ut.sh
- wget -P "remoting/zookeeper/zookeeper-4unittest/contrib/fatjar" https://github.com/dubbogo/resources/raw/master/zookeeper-4unitest/contrib/fatjar/zookeeper-3.4.9-fatjar.jar
- cp remoting/zookeeper/zookeeper-4unittest/contrib/fatjar/zookeeper-3.4.9-fatjar.jar config_center/zookeeper/zookeeper-4unittest/contrib/fatjar/
- cp remoting/zookeeper/zookeeper-4unittest/contrib/fatjar/zookeeper-3.4.9-fatjar.jar registry/zookeeper/zookeeper-4unittest/contrib/fatjar/
- go mod vendor && go test ./... -coverprofile=coverage.txt -covermode=atomic - go mod vendor && go test ./... -coverprofile=coverage.txt -covermode=atomic
after_success: after_success:
......
# Release Notes # Release Notes
---
## 1.3.0
### New Features
- [Add apollo config center support](https://github.com/apache/dubbo-go/pull/250)
- [Gracefully shutdown](https://github.com/apache/dubbo-go/pull/255)
- [Add consistent hash load balance support](https://github.com/apache/dubbo-go/pull/261)
- [Add sticky connection support](https://github.com/apache/dubbo-go/pull/270)
- [Add async call for dubbo protocol](https://github.com/apache/dubbo-go/pull/272)
- [Add generic implement](https://github.com/apache/dubbo-go/pull/291)
- [Add request timeout for method](https://github.com/apache/dubbo-go/pull/284)
- [Add grpc protocol](https://github.com/apache/dubbo-go/pull/311)
### Enhancement
- [The SIGSYS and SIGSTOP are not supported in windows platform](https://github.com/apache/dubbo-go/pull/262)
- [Error should be returned when `NewURL` failed](https://github.com/apache/dubbo-go/pull/266)
- [Split config center GetConfig method](https://github.com/apache/dubbo-go/pull/267)
- [Modify closing method for dubbo protocol](https://github.com/apache/dubbo-go/pull/268)
- [Add SetLoggerLevel method](https://github.com/apache/dubbo-go/pull/271)
- [Change the position of the lock](https://github.com/apache/dubbo-go/pull/286)
- [Change zk version and add base_registry](https://github.com/apache/dubbo-go/pull/355)
### Bugfixes
- [Fix negative wait group count](https://github.com/apache/dubbo-go/pull/253)
- [After disconnection with ZK registry, cosumer can't listen to provider changes](https://github.com/apache/dubbo-go/pull/258)
- [The generic filter and default reference filters lack ','](https://github.com/apache/dubbo-go/pull/260)
- [Url encode zkpath](https://github.com/apache/dubbo-go/pull/283)
- [Fix jsonrpc about HTTP/1.1](https://github.com/apache/dubbo-go/pull/327)
- [Fix zk bug](https://github.com/apache/dubbo-go/pull/346)
- [HessianCodec failed to check package header length](https://github.com/apache/dubbo-go/pull/381)
## 1.2.0 ## 1.2.0
### New Features ### New Features
- Add etcdv3 registry support<https://github.com/apache/dubbo-go/pull/148> - [Add etcdv3 registry support](https://github.com/apache/dubbo-go/pull/148)
- Add nacos registry support<https://github.com/apache/dubbo-go/pull/151> - [Add nacos registry support](https://github.com/apache/dubbo-go/pull/151)
- Add fail fast cluster support<https://github.com/apache/dubbo-go/pull/140> - [Add fail fast cluster support](https://github.com/apache/dubbo-go/pull/140)
- Add available cluster support<https://github.com/apache/dubbo-go/pull/155> - [Add available cluster support](https://github.com/apache/dubbo-go/pull/155)
- Add broadcast cluster support<https://github.com/apache/dubbo-go/pull/158> - [Add broadcast cluster support](https://github.com/apache/dubbo-go/pull/158)
- Add forking cluster support<https://github.com/apache/dubbo-go/pull/161> - [Add forking cluster support](https://github.com/apache/dubbo-go/pull/161)
- Add service token authorization support<https://github.com/apache/dubbo-go/pull/202> - [Add service token authorization support](https://github.com/apache/dubbo-go/pull/202)
- Add accessLog filter support<https://github.com/apache/dubbo-go/pull/214> - [Add accessLog filter support](https://github.com/apache/dubbo-go/pull/214)
- Add tps limit support<https://github.com/apache/dubbo-go/pull/237> - [Add tps limit support](https://github.com/apache/dubbo-go/pull/237)
- Add execute limit support<https://github.com/apache/dubbo-go/pull/246> - [Add execute limit support](https://github.com/apache/dubbo-go/pull/246)
- Move callService to invoker & support attachments<https://github.com/apache/dubbo-go/pull/193> - [Move callService to invoker & support attachments](https://github.com/apache/dubbo-go/pull/193)
- Move example in dubbo-go project away<https://github.com/apache/dubbo-go/pull/228> - [Move example in dubbo-go project away](https://github.com/apache/dubbo-go/pull/228)
- Support dynamic config center which compatible with dubbo 2.6.x & 2.7.x and commit the zookeeper impl<https://github.com/apache/dubbo-go/pull/194> - [Support dynamic config center which compatible with dubbo 2.6.x & 2.7.x and commit the zookeeper impl](https://github.com/apache/dubbo-go/pull/194)
### Enhancement ### Enhancement
- Split gettyRPCClient.close and gettyRPCClientPool.remove in protocol/dubbo/pool.go<https://github.com/apache/dubbo-go/pull/186> - [Split gettyRPCClient.close and gettyRPCClientPool.remove in protocol/dubbo/pool.go](https://github.com/apache/dubbo-go/pull/186)
- Remove client from pool before closing it<https://github.com/apache/dubbo-go/pull/190> - [Remove client from pool before closing it](https://github.com/apache/dubbo-go/pull/190)
- Enhance the logic for fetching the local address<https://github.com/apache/dubbo-go/pull/209> - [Enhance the logic for fetching the local address](https://github.com/apache/dubbo-go/pull/209)
- Add protocol_conf default values<https://github.com/apache/dubbo-go/pull/221> - [Add protocol_conf default values](https://github.com/apache/dubbo-go/pull/221)
- Add task pool for getty<https://github.com/apache/dubbo-go/pull/141> - [Add task pool for getty](https://github.com/apache/dubbo-go/pull/141)
- Update getty: remove read queue<https://github.com/apache/dubbo-go/pull/137> - [Update getty: remove read queue](https://github.com/apache/dubbo-go/pull/137)
- Clean heartbeat from PendingResponse<https://github.com/apache/dubbo-go/pull/166> - [Clean heartbeat from PendingResponse](https://github.com/apache/dubbo-go/pull/166)
### Bugfixes ### Bugfixes
- GettyRPCClientPool remove deadlock<https://github.com/apache/dubbo-go/pull/183/files> - [GettyRPCClientPool remove deadlock](https://github.com/apache/dubbo-go/pull/183/files)
- Fix failover cluster bug and url parameter retries change int to string type<https://github.com/apache/dubbo-go/pull/195> - [Fix failover cluster bug and url parameter retries change int to string type](https://github.com/apache/dubbo-go/pull/195)
- Fix url params unsafe map<https://github.com/apache/dubbo-go/pull/201> - [Fix url params unsafe map](https://github.com/apache/dubbo-go/pull/201)
- Read protocol config by map key in config yaml instead of protocol name<https://github.com/apache/dubbo-go/pull/218> - [Read protocol config by map key in config yaml instead of protocol name](https://github.com/apache/dubbo-go/pull/218)
- Fix dubbo group issues #238<https://github.com/apache/dubbo-go/pull/243>/<https://github.com/apache/dubbo-go/pull/244> - *Fix dubbo group issues #238* [pr #243](https://github.com/apache/dubbo-go/pull/243) and [pr #244](https://github.com/apache/dubbo-go/pull/244)
- Fix bug in reference_config<https://github.com/apache/dubbo-go/pull/157> - [Fix bug in reference_config](https://github.com/apache/dubbo-go/pull/157)
- Fix high memory bug in zookeeper listener<https://github.com/apache/dubbo-go/pull/168> - [Fix high memory bug in zookeeper listener](https://github.com/apache/dubbo-go/pull/168)
## 1.1.0 ## 1.1.0
### New Features ### New Features
- Support Java bigdecimal<https://github.com/apache/dubbo-go/pull/126> - [Support Java bigdecimal](https://github.com/apache/dubbo-go/pull/126)
- Support all JDK exceptions<https://github.com/apache/dubbo-go/pull/120> - [Support all JDK exceptions](https://github.com/apache/dubbo-go/pull/120)
- Support multi-version of service<https://github.com/apache/dubbo-go/pull/119> - [Support multi-version of service](https://github.com/apache/dubbo-go/pull/119)
- Allow user set custom params for registry<https://github.com/apache/dubbo-go/pull/117> - [Allow user set custom params for registry](https://github.com/apache/dubbo-go/pull/117)
- Support zookeeper config center<https://github.com/apache/dubbo-go/pull/99> - [Support zookeeper config center](https://github.com/apache/dubbo-go/pull/99)
- Failsafe/Failback Cluster Strategy<https://github.com/apache/dubbo-go/pull/136>; - [Failsafe/Failback Cluster Strategy](https://github.com/apache/dubbo-go/pull/136)
### Enhancement ### Enhancement
- Use time wheel instead of time.After to defeat timer object memory leakage<https://github.com/apache/dubbo-go/pull/130> - [Use time wheel instead of time.After to defeat timer object memory leakage](https://github.com/apache/dubbo-go/pull/130)
### Bugfixes ### Bugfixes
- Preventing dead loop when got zookeeper unregister event<https://github.com/apache/dubbo-go/pull/129> - [Preventing dead loop when got zookeeper unregister event](https://github.com/apache/dubbo-go/pull/129)
- Delete ineffassign<https://github.com/apache/dubbo-go/pull/127> - [Delete ineffassign](https://github.com/apache/dubbo-go/pull/127)
- Add wg.Done() for mockDataListener<https://github.com/apache/dubbo-go/pull/118> - [Add wg.Done() for mockDataListener](https://github.com/apache/dubbo-go/pull/118)
- Delete wrong spelling words<https://github.com/apache/dubbo-go/pull/107> - [Delete wrong spelling words](https://github.com/apache/dubbo-go/pull/107)
- Use sync.Map to defeat from gettyClientPool deadlock<https://github.com/apache/dubbo-go/pull/106> - [Use sync.Map to defeat from gettyClientPool deadlock](https://github.com/apache/dubbo-go/pull/106)
- Handle panic when function args list is empty<https://github.com/apache/dubbo-go/pull/98> - [Handle panic when function args list is empty](https://github.com/apache/dubbo-go/pull/98)
- url.Values is not safe map<https://github.com/apache/dubbo-go/pull/172>; - [url.Values is not safe map](https://github.com/apache/dubbo-go/pull/172)
...@@ -14,11 +14,13 @@ Apache License, Version 2.0 ...@@ -14,11 +14,13 @@ Apache License, Version 2.0
## Release note ## ## Release note ##
[v1.0.0 - May 29, 2019 compatible with dubbo v2.6.5](https://github.com/apache/dubbo-go/releases/tag/v1.0.0) [v1.3.0 - Mar 1, 2020](https://github.com/apache/dubbo-go/releases/tag/v1.3.0)
[v1.2.0 - Nov 15, 2019](https://github.com/apache/dubbo-go/releases/tag/v1.2.0)
[v1.1.0 - Sep 7, 2019 the first release after transferred to apache](https://github.com/apache/dubbo-go/releases/tag/v1.1.0) [v1.1.0 - Sep 7, 2019 the first release after transferred to apache](https://github.com/apache/dubbo-go/releases/tag/v1.1.0)
[v1.2.0 - Nov 15, 2019](https://github.com/apache/dubbo-go/releases/tag/v1.2.0) [v1.0.0 - May 29, 2019 compatible with dubbo v2.6.5](https://github.com/apache/dubbo-go/releases/tag/v1.0.0)
## Project Architecture ## ## Project Architecture ##
...@@ -43,18 +45,18 @@ Finished List: ...@@ -43,18 +45,18 @@ Finished List:
- Codec - Codec
* JsonRPC V2 * JsonRPC V2
* Hessian V2 * Hessian V2
- Protocol - Protocol
* Dubbo * Dubbo
* Jsonrpc2.0 * Jsonrpc2.0
* [gRPC](https://github.com/apache/dubbo-go/pull/311) * [gRPC](https://github.com/apache/dubbo-go/pull/311)
- Registry - Registry
* ZooKeeper * ZooKeeper
* [etcd v3](https://github.com/apache/dubbo-go/pull/148) * [etcd v3](https://github.com/apache/dubbo-go/pull/148)
* [nacos](https://github.com/apache/dubbo-go/pull/151) * [nacos](https://github.com/apache/dubbo-go/pull/151)
* [consul](https://github.com/apache/dubbo-go/pull/121) * [consul](https://github.com/apache/dubbo-go/pull/121)
- Dynamic Configure Center & Service Management Configurator - Dynamic Configure Center & Service Management Configurator
* Zookeeper * Zookeeper
* [apollo](https://github.com/apache/dubbo-go/pull/250) * [apollo](https://github.com/apache/dubbo-go/pull/250)
...@@ -66,12 +68,13 @@ Finished List: ...@@ -66,12 +68,13 @@ Finished List:
* [Available](https://github.com/apache/dubbo-go/pull/155) * [Available](https://github.com/apache/dubbo-go/pull/155)
* [Broadcast](https://github.com/apache/dubbo-go/pull/158) * [Broadcast](https://github.com/apache/dubbo-go/pull/158)
* [Forking](https://github.com/apache/dubbo-go/pull/161) * [Forking](https://github.com/apache/dubbo-go/pull/161)
- Load Balance - Load Balance
* Random * Random
* [RoundRobin](https://github.com/apache/dubbo-go/pull/66) * [RoundRobin](https://github.com/apache/dubbo-go/pull/66)
* [LeastActive](https://github.com/apache/dubbo-go/pull/65) * [LeastActive](https://github.com/apache/dubbo-go/pull/65)
* [ConsistentHash](https://github.com/apache/dubbo-go/pull/261)
- Filter - Filter
* Echo Health Check * Echo Health Check
* [Circuit break and service downgrade](https://github.com/apache/dubbo-go/pull/133) * [Circuit break and service downgrade](https://github.com/apache/dubbo-go/pull/133)
...@@ -80,10 +83,10 @@ Finished List: ...@@ -80,10 +83,10 @@ Finished List:
* [TpsLimitFilter](https://github.com/apache/dubbo-go/pull/237) * [TpsLimitFilter](https://github.com/apache/dubbo-go/pull/237)
* [ExecuteLimitFilter](https://github.com/apache/dubbo-go/pull/246) * [ExecuteLimitFilter](https://github.com/apache/dubbo-go/pull/246)
* [GenericServiceFilter](https://github.com/apache/dubbo-go/pull/291) * [GenericServiceFilter](https://github.com/apache/dubbo-go/pull/291)
- Invoke - Invoke
* [generic invoke](https://github.com/apache/dubbo-go/pull/122) * [generic invoke](https://github.com/apache/dubbo-go/pull/122)
- Others: - Others:
* start check * start check
* connecting certain provider * connecting certain provider
...@@ -94,14 +97,13 @@ Finished List: ...@@ -94,14 +97,13 @@ Finished List:
Working List: Working List:
- Load Balance: ConsistentHash
- Registry: k8s - Registry: k8s
- Metadata Center (dubbo v2.7.x) - Metadata Center (dubbo v2.7.x)
- Metrics: Opentracing/Promethus(dubbo v2.7.x) - Metrics: Opentracing/Promethus(dubbo v2.7.x)
You can know more about dubbo-go by its [roadmap](https://github.com/apache/dubbo-go/wiki/Roadmap). You can know more about dubbo-go by its [roadmap](https://github.com/apache/dubbo-go/wiki/Roadmap).
![feature](https://raw.githubusercontent.com/wiki/apache/dubbo-go/arch.png) ![feature](https://raw.githubusercontent.com/wiki/apache/dubbo-go/dubbo-go-arch.png)
## Document ## Document
...@@ -125,7 +127,7 @@ Windows ...@@ -125,7 +127,7 @@ Windows
before_ut.bat before_ut.bat
``` ```
# Run ### Run
```bash ```bash
go test ./... go test ./...
...@@ -133,6 +135,10 @@ go test ./... ...@@ -133,6 +135,10 @@ go test ./...
go test ./... -coverprofile=coverage.txt -covermode=atomic go test ./... -coverprofile=coverage.txt -covermode=atomic
``` ```
## Build
Please move to [dubbo-samples/golang](https://github.com/dubbogo/dubbo-samples)
## Contributing ## Contributing
If you are willing to do some code contributions and document contributions to [Apache/dubbo-go](https://github.com/apache/dubbo-go), please visit [contribution intro](https://github.com/apache/dubbo-go/blob/master/contributing.md). If you are willing to do some code contributions and document contributions to [Apache/dubbo-go](https://github.com/apache/dubbo-go), please visit [contribution intro](https://github.com/apache/dubbo-go/blob/master/contributing.md).
...@@ -147,11 +153,6 @@ About dubbo-go benchmarking report, please refer to [dubbo benchmarking report]( ...@@ -147,11 +153,6 @@ About dubbo-go benchmarking report, please refer to [dubbo benchmarking report](
If you are using [apache/dubbo-go](github.com/apache/dubbo-go) and think that it helps you or want do some contributions to it, please add your company to to [the user list](https://github.com/apache/dubbo-go/issues/2) to let us know your needs. If you are using [apache/dubbo-go](github.com/apache/dubbo-go) and think that it helps you or want do some contributions to it, please add your company to to [the user list](https://github.com/apache/dubbo-go/issues/2) to let us know your needs.
![ctrip](https://pic.c-ctrip.com/common/c_logo2013.png)
![ctrip](https://pic.c-ctrip.com/common/c_logo2013.png)![Excellent Health Technology Group](https://raw.githubusercontent.com/dajiiu/photo/static/mirror/haozhuo_logo.png) ![Excellent Health Technology Group](https://raw.githubusercontent.com/dajiiu/photo/static/mirror/haozhuo_logo.png)
![ctrip](https://raw.githubusercontent.com/pantianying/go-tool/master/picture/logo_2-removebg-preview.png) ![tuya](https://raw.githubusercontent.com/pantianying/go-tool/master/picture/logo_2-removebg-preview.png)
## Stargazers
[![Stargazers over time](https://starchart.cc/apache/dubbo-go.svg)](https://starchart.cc/apache/dubbo-go)
...@@ -2,6 +2,7 @@ ...@@ -2,6 +2,7 @@
[![Build Status](https://travis-ci.org/apache/dubbo-go.svg?branch=master)](https://travis-ci.org/apache/dubbo-go) [![Build Status](https://travis-ci.org/apache/dubbo-go.svg?branch=master)](https://travis-ci.org/apache/dubbo-go)
[![codecov](https://codecov.io/gh/apache/dubbo-go/branch/master/graph/badge.svg)](https://codecov.io/gh/apache/dubbo-go) [![codecov](https://codecov.io/gh/apache/dubbo-go/branch/master/graph/badge.svg)](https://codecov.io/gh/apache/dubbo-go)
[![go.dev reference](https://img.shields.io/badge/go.dev-reference-007d9c?logo=go&logoColor=white&style=flat-square)](https://pkg.go.dev/github.com/apache/dubbo-go?tab=doc)
--- ---
Apache Dubbo Go 语言实现 Apache Dubbo Go 语言实现
...@@ -12,11 +13,13 @@ Apache License, Version 2.0 ...@@ -12,11 +13,13 @@ Apache License, Version 2.0
## 发布日志 ## ## 发布日志 ##
[v1.0.0 - 2019年5月29日 兼容dubbo v2.6.5 版本](https://github.com/apache/dubbo-go/releases/tag/v1.0.0) [v1.3.0 - 2020年3月1日](https://github.com/apache/dubbo-go/releases/tag/v1.3.0)
[v1.2.0 - 2019年11月15日](https://github.com/apache/dubbo-go/releases/tag/v1.2.0)
[v1.1.0 - 2019年9月7日 捐献给Apache之后的第一次release](https://github.com/apache/dubbo-go/releases/tag/v1.1.0) [v1.1.0 - 2019年9月7日 捐献给Apache之后的第一次release](https://github.com/apache/dubbo-go/releases/tag/v1.1.0)
[v1.2.0 - 2019年11月15日](https://github.com/apache/dubbo-go/releases/tag/v1.2.0) [v1.0.0 - 2019年5月29日 兼容dubbo v2.6.5 版本](https://github.com/apache/dubbo-go/releases/tag/v1.0.0)
## 工程架构 ## ## 工程架构 ##
...@@ -33,7 +36,7 @@ Apache License, Version 2.0 ...@@ -33,7 +36,7 @@ Apache License, Version 2.0
- 角色端 - 角色端
* Consumer * Consumer
* Provider * Provider
- 传输协议 - 传输协议
* HTTP * HTTP
* TCP * TCP
...@@ -46,17 +49,17 @@ Apache License, Version 2.0 ...@@ -46,17 +49,17 @@ Apache License, Version 2.0
* Dubbo * Dubbo
* Jsonrpc2.0 * Jsonrpc2.0
* [gRPC](https://github.com/apache/dubbo-go/pull/311) * [gRPC](https://github.com/apache/dubbo-go/pull/311)
- 注册中心 - 注册中心
* ZooKeeper * ZooKeeper
* [etcd v3](https://github.com/apache/dubbo-go/pull/148) * [etcd v3](https://github.com/apache/dubbo-go/pull/148)
* [nacos](https://github.com/apache/dubbo-go/pull/151) * [nacos](https://github.com/apache/dubbo-go/pull/151)
* [consul](https://github.com/apache/dubbo-go/pull/121) * [consul](https://github.com/apache/dubbo-go/pull/121)
- 动态配置中心与服务治理配置器 - 动态配置中心与服务治理配置器
* Zookeeper * Zookeeper
* [apollo](https://github.com/apache/dubbo-go/pull/250) * [apollo](https://github.com/apache/dubbo-go/pull/250)
- 集群策略 - 集群策略
* Failover * Failover
* [Failfast](https://github.com/apache/dubbo-go/pull/140) * [Failfast](https://github.com/apache/dubbo-go/pull/140)
...@@ -64,12 +67,13 @@ Apache License, Version 2.0 ...@@ -64,12 +67,13 @@ Apache License, Version 2.0
* [Available](https://github.com/apache/dubbo-go/pull/155) * [Available](https://github.com/apache/dubbo-go/pull/155)
* [Broadcast](https://github.com/apache/dubbo-go/pull/158) * [Broadcast](https://github.com/apache/dubbo-go/pull/158)
* [Forking](https://github.com/apache/dubbo-go/pull/161) * [Forking](https://github.com/apache/dubbo-go/pull/161)
- 负载均衡策略 - 负载均衡策略
* Random * Random
* [RoundRobin](https://github.com/apache/dubbo-go/pull/66) * [RoundRobin](https://github.com/apache/dubbo-go/pull/66)
* [LeastActive](https://github.com/apache/dubbo-go/pull/65) * [LeastActive](https://github.com/apache/dubbo-go/pull/65)
* [ConsistentHash](https://github.com/apache/dubbo-go/pull/261)
- 过滤器 - 过滤器
* Echo Health Check * Echo Health Check
* [服务熔断&降级](https://github.com/apache/dubbo-go/pull/133) * [服务熔断&降级](https://github.com/apache/dubbo-go/pull/133)
...@@ -77,10 +81,10 @@ Apache License, Version 2.0 ...@@ -77,10 +81,10 @@ Apache License, Version 2.0
* [AccessLogFilter](https://github.com/apache/dubbo-go/pull/214) * [AccessLogFilter](https://github.com/apache/dubbo-go/pull/214)
* [TpsLimitFilter](https://github.com/apache/dubbo-go/pull/237) * [TpsLimitFilter](https://github.com/apache/dubbo-go/pull/237)
* [ExecuteLimitFilter](https://github.com/apache/dubbo-go/pull/246) * [ExecuteLimitFilter](https://github.com/apache/dubbo-go/pull/246)
- 调用 - 调用
* [泛化调用](https://github.com/apache/dubbo-go/pull/122) * [泛化调用](https://github.com/apache/dubbo-go/pull/122)
- 其他功能支持: - 其他功能支持:
* 启动时检查 * 启动时检查
* 服务直连 * 服务直连
...@@ -91,14 +95,13 @@ Apache License, Version 2.0 ...@@ -91,14 +95,13 @@ Apache License, Version 2.0
开发中列表: 开发中列表:
- 负载均衡策略: ConsistentHash
- 注册中心: k8s - 注册中心: k8s
- 元数据中心 (dubbo v2.7.x) - 元数据中心 (dubbo v2.7.x)
- Metrics: Opentracing/Promethus(dubbo v2.7.x) - Metrics: Opentracing/Promethus(dubbo v2.7.x)
你可以通过访问 [roadmap](https://github.com/apache/dubbo-go/wiki/Roadmap) 知道更多关于 dubbo-go 的信息。 你可以通过访问 [roadmap](https://github.com/apache/dubbo-go/wiki/Roadmap) 知道更多关于 dubbo-go 的信息。
![feature](https://raw.githubusercontent.com/wiki/apache/dubbo-go/arch.png) ![feature](https://raw.githubusercontent.com/wiki/apache/dubbo-go/dubbo-go-arch.png)
## 文档 ## 文档
...@@ -122,7 +125,7 @@ Windows ...@@ -122,7 +125,7 @@ Windows
before_ut.bat before_ut.bat
``` ```
# 执行 ### 执行
```bash ```bash
go test ./... go test ./...
...@@ -130,6 +133,10 @@ go test ./... ...@@ -130,6 +133,10 @@ go test ./...
go test ./... -coverprofile=coverage.txt -covermode=atomic go test ./... -coverprofile=coverage.txt -covermode=atomic
``` ```
## 编译
请移步 [dubbo-samples/golang](https://github.com/dubbogo/dubbo-samples)
## 如何贡献 ## 如何贡献
如果您愿意给 [Apache/dubbo-go](https://github.com/apache/dubbo-go) 贡献代码或者文档,我们都热烈欢迎。具体请参考 [contribution intro](https://github.com/apache/dubbo-go/blob/master/contributing.md) 如果您愿意给 [Apache/dubbo-go](https://github.com/apache/dubbo-go) 贡献代码或者文档,我们都热烈欢迎。具体请参考 [contribution intro](https://github.com/apache/dubbo-go/blob/master/contributing.md)
...@@ -145,8 +152,5 @@ go test ./... -coverprofile=coverage.txt -covermode=atomic ...@@ -145,8 +152,5 @@ go test ./... -coverprofile=coverage.txt -covermode=atomic
若你正在使用 [apache/dubbo-go](github.com/apache/dubbo-go) 且认为其有用或者向对其做改进,请忝列贵司信息于 [用户列表](https://github.com/apache/dubbo-go/issues/2),以便我们知晓之。 若你正在使用 [apache/dubbo-go](github.com/apache/dubbo-go) 且认为其有用或者向对其做改进,请忝列贵司信息于 [用户列表](https://github.com/apache/dubbo-go/issues/2),以便我们知晓之。
![ctrip](https://pic.c-ctrip.com/common/c_logo2013.png) ![ctrip](https://pic.c-ctrip.com/common/c_logo2013.png)
![Excellent Health Technology Group](https://raw.githubusercontent.com/dajiiu/photo/static/mirror/haozhuo_logo.png)
## Stargazers ![tuya](https://raw.githubusercontent.com/pantianying/go-tool/master/picture/logo_2-removebg-preview.png)
[![Stargazers over time](https://starchart.cc/apache/dubbo-go.svg)](https://starchart.cc/apache/dubbo-go)
...@@ -14,8 +14,24 @@ ...@@ -14,8 +14,24 @@
:: See the License for the specific language governing permissions and :: See the License for the specific language governing permissions and
:: limitations under the License. :: limitations under the License.
set zkJar=zookeeper-3.4.9-fatjar.jar set zkJarName="zookeeper-3.4.9-fatjar.jar"
md remoting\zookeeper\zookeeper-4unittest\contrib\fatjar config_center\zookeeper\zookeeper-4unittest\contrib\fatjar registry\zookeeper\zookeeper-4unittest\contrib\fatjar set remoteJarUrl="https://github.com/dubbogo/resources/raw/master/zookeeper-4unitest/contrib/fatjar/%zkJarName%"
curl -L https://github.com/dubbogo/resources/raw/master/zookeeper-4unitest/contrib/fatjar/%zkJar% -o remoting/zookeeper/zookeeper-4unittest/contrib/fatjar/%zkJar% set zkJarPath="remoting/zookeeper/zookeeper-4unittest/contrib/fatjar"
xcopy /f "remoting/zookeeper/zookeeper-4unittest/contrib/fatjar/%zkJar%" "config_center/zookeeper/zookeeper-4unittest/contrib/fatjar/" set zkJar="%zkJarPath%/%zkJarName%"
xcopy /f "remoting/zookeeper/zookeeper-4unittest/contrib/fatjar/%zkJar%" "registry/zookeeper/zookeeper-4unittest/contrib/fatjar/"
\ No newline at end of file if not exist "%zkJar%" (
md %zkJarPath%
curl -L %remoteJarUrl% -o %zkJar%
)
md config_center\zookeeper\zookeeper-4unittest\contrib\fatjar
xcopy /f "%zkJar%" "config_center/zookeeper/zookeeper-4unittest/contrib/fatjar/"
md registry\zookeeper\zookeeper-4unittest\contrib\fatjar
xcopy /f "%zkJar%" "registry/zookeeper/zookeeper-4unittest/contrib/fatjar/"
md cluster\router\chain\zookeeper-4unittest\contrib\fatjar
xcopy /f "%zkJar%" "cluster/router/chain/zookeeper-4unittest/contrib/fatjar/"
md cluster\router\condition\zookeeper-4unittest\contrib\fatjar
xcopy /f "%zkJar%" "cluster/router/condition/zookeeper-4unittest/contrib/fatjar/"
\ No newline at end of file
before_ut.sh 100644 → 100755
...@@ -14,8 +14,24 @@ ...@@ -14,8 +14,24 @@
# See the License for the specific language governing permissions and # See the License for the specific language governing permissions and
# limitations under the License. # limitations under the License.
zkJarName="zookeeper-3.4.9-fatjar.jar"
remoteJarUrl="https://github.com/dubbogo/resources/raw/master/zookeeper-4unitest/contrib/fatjar/${zkJarName}"
zkJarPath="remoting/zookeeper/zookeeper-4unittest/contrib/fatjar"
zkJar="${zkJarPath}/${zkJarName}"
mkdir -p remoting/zookeeper/zookeeper-4unittest/contrib/fatjar config_center/zookeeper/zookeeper-4unittest/contrib/fatjar registry/zookeeper/zookeeper-4unittest/contrib/fatjar if [ ! -f "${zkJar}" ]; then
wget -P "remoting/zookeeper/zookeeper-4unittest/contrib/fatjar" https://github.com/dubbogo/resources/raw/master/zookeeper-4unitest/contrib/fatjar/zookeeper-3.4.9-fatjar.jar mkdir -p ${zkJarPath}
cp remoting/zookeeper/zookeeper-4unittest/contrib/fatjar/zookeeper-3.4.9-fatjar.jar config_center/zookeeper/zookeeper-4unittest/contrib/fatjar/ wget -P "${zkJarPath}" ${remoteJarUrl}
cp remoting/zookeeper/zookeeper-4unittest/contrib/fatjar/zookeeper-3.4.9-fatjar.jar registry/zookeeper/zookeeper-4unittest/contrib/fatjar/ fi
\ No newline at end of file
mkdir -p config_center/zookeeper/zookeeper-4unittest/contrib/fatjar
cp ${zkJar} config_center/zookeeper/zookeeper-4unittest/contrib/fatjar/
mkdir -p registry/zookeeper/zookeeper-4unittest/contrib/fatjar
cp ${zkJar} registry/zookeeper/zookeeper-4unittest/contrib/fatjar/
mkdir -p cluster/router/chain/zookeeper-4unittest/contrib/fatjar
cp ${zkJar} cluster/router/chain/zookeeper-4unittest/contrib/fatjar
mkdir -p cluster/router/condition/zookeeper-4unittest/contrib/fatjar
cp ${zkJar} cluster/router/condition/zookeeper-4unittest/contrib/fatjar
\ No newline at end of file
...@@ -45,6 +45,7 @@ func newBaseClusterInvoker(directory cluster.Directory) baseClusterInvoker { ...@@ -45,6 +45,7 @@ func newBaseClusterInvoker(directory cluster.Directory) baseClusterInvoker {
destroyed: atomic.NewBool(false), destroyed: atomic.NewBool(false),
} }
} }
func (invoker *baseClusterInvoker) GetUrl() common.URL { func (invoker *baseClusterInvoker) GetUrl() common.URL {
return invoker.directory.GetUrl() return invoker.directory.GetUrl()
} }
......
...@@ -47,6 +47,7 @@ func Test_StickyNormal(t *testing.T) { ...@@ -47,6 +47,7 @@ func Test_StickyNormal(t *testing.T) {
result1 := base.doSelect(loadbalance.NewRandomLoadBalance(), invocation.NewRPCInvocation("getUser", nil, nil), invokers, invoked) result1 := base.doSelect(loadbalance.NewRandomLoadBalance(), invocation.NewRPCInvocation("getUser", nil, nil), invokers, invoked)
assert.Equal(t, result, result1) assert.Equal(t, result, result1)
} }
func Test_StickyNormalWhenError(t *testing.T) { func Test_StickyNormalWhenError(t *testing.T) {
invokers := []protocol.Invoker{} invokers := []protocol.Invoker{}
for i := 0; i < 10; i++ { for i := 0; i < 10; i++ {
......
...@@ -118,6 +118,7 @@ func normalInvoke(t *testing.T, successCount int, urlParam url.Values, invocatio ...@@ -118,6 +118,7 @@ func normalInvoke(t *testing.T, successCount int, urlParam url.Values, invocatio
} }
return clusterInvoker.Invoke(context.Background(), &invocation.RPCInvocation{}) return clusterInvoker.Invoke(context.Background(), &invocation.RPCInvocation{})
} }
func Test_FailoverInvokeSuccess(t *testing.T) { func Test_FailoverInvokeSuccess(t *testing.T) {
urlParams := url.Values{} urlParams := url.Values{}
result := normalInvoke(t, 3, urlParams) result := normalInvoke(t, 3, urlParams)
......
...@@ -20,39 +20,94 @@ package directory ...@@ -20,39 +20,94 @@ package directory
import ( import (
"sync" "sync"
) )
import ( import (
"github.com/dubbogo/gost/container/set"
"go.uber.org/atomic" "go.uber.org/atomic"
) )
import ( import (
"github.com/apache/dubbo-go/cluster/router"
"github.com/apache/dubbo-go/cluster/router/chain"
"github.com/apache/dubbo-go/common" "github.com/apache/dubbo-go/common"
"github.com/apache/dubbo-go/common/constant"
"github.com/apache/dubbo-go/common/extension"
"github.com/apache/dubbo-go/common/logger"
) )
// BaseDirectory ... var routerURLSet = gxset.NewSet()
// BaseDirectory Abstract implementation of Directory: Invoker list returned from this Directory's list method have been filtered by Routers
type BaseDirectory struct { type BaseDirectory struct {
url *common.URL url *common.URL
destroyed *atomic.Bool destroyed *atomic.Bool
mutex sync.Mutex // this mutex for change the properties in BaseDirectory, like routerChain , destroyed etc
mutex sync.Mutex
routerChain router.Chain
} }
// NewBaseDirectory ... // NewBaseDirectory Create BaseDirectory with URL
func NewBaseDirectory(url *common.URL) BaseDirectory { func NewBaseDirectory(url *common.URL) BaseDirectory {
return BaseDirectory{ return BaseDirectory{
url: url, url: url,
destroyed: atomic.NewBool(false), destroyed: atomic.NewBool(false),
routerChain: &chain.RouterChain{},
} }
} }
// GetUrl ... // RouterChain Return router chain in directory
func (dir *BaseDirectory) RouterChain() router.Chain {
return dir.routerChain
}
// SetRouterChain Set router chain in directory
func (dir *BaseDirectory) SetRouterChain(routerChain router.Chain) {
dir.mutex.Lock()
defer dir.mutex.Unlock()
dir.routerChain = routerChain
}
// GetUrl Get URL
func (dir *BaseDirectory) GetUrl() common.URL { func (dir *BaseDirectory) GetUrl() common.URL {
return *dir.url return *dir.url
} }
// GetDirectoryUrl ... // GetDirectoryUrl Get URL instance
func (dir *BaseDirectory) GetDirectoryUrl() *common.URL { func (dir *BaseDirectory) GetDirectoryUrl() *common.URL {
return dir.url return dir.url
} }
// Destroy ... // SetRouters Convert url to routers and add them into dir.routerChain
func (dir *BaseDirectory) SetRouters(urls []*common.URL) {
if len(urls) == 0 {
return
}
routers := make([]router.Router, 0, len(urls))
for _, url := range urls {
routerKey := url.GetParam(constant.ROUTER_KEY, "")
if len(routerKey) > 0 {
factory := extension.GetRouterFactory(url.Protocol)
r, err := factory.NewRouter(url)
if err != nil {
logger.Errorf("Create router fail. router key: %s, error: %v", routerKey, url.Service(), err)
return
}
routers = append(routers, r)
}
}
logger.Infof("Init file condition router success, size: %v", len(routers))
dir.mutex.Lock()
rc := dir.routerChain
dir.mutex.Unlock()
rc.AddRouters(routers)
}
// Destroy Destroy
func (dir *BaseDirectory) Destroy(doDestroy func()) { func (dir *BaseDirectory) Destroy(doDestroy func()) {
if dir.destroyed.CAS(false, true) { if dir.destroyed.CAS(false, true) {
dir.mutex.Lock() dir.mutex.Lock()
...@@ -61,7 +116,18 @@ func (dir *BaseDirectory) Destroy(doDestroy func()) { ...@@ -61,7 +116,18 @@ func (dir *BaseDirectory) Destroy(doDestroy func()) {
} }
} }
// IsAvailable ... // IsAvailable Once directory init finish, it will change to true
func (dir *BaseDirectory) IsAvailable() bool { func (dir *BaseDirectory) IsAvailable() bool {
return !dir.destroyed.Load() return !dir.destroyed.Load()
} }
// GetRouterURLSet Return router URL
func GetRouterURLSet() *gxset.HashSet {
return routerURLSet
}
// AddRouterURLSet Add router URL
// Router URL will init in config/config_loader.go
func AddRouterURLSet(url *common.URL) {
routerURLSet.Add(url)
}
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package directory
import (
"encoding/base64"
"fmt"
"testing"
)
import (
gxnet "github.com/dubbogo/gost/net"
"github.com/stretchr/testify/assert"
)
import (
_ "github.com/apache/dubbo-go/cluster/router/condition"
"github.com/apache/dubbo-go/common"
"github.com/apache/dubbo-go/common/constant"
)
func TestNewBaseDirectory(t *testing.T) {
url, _ := common.NewURL(fmt.Sprintf("dubbo://192.168.1.1:20000/com.ikurento.user.UserProvider"))
directory := NewBaseDirectory(&url)
assert.NotNil(t, directory)
assert.Equal(t, url, directory.GetUrl())
assert.Equal(t, &url, directory.GetDirectoryUrl())
}
func TestBuildRouterChain(t *testing.T) {
url, _ := common.NewURL(fmt.Sprintf("dubbo://192.168.1.1:20000/com.ikurento.user.UserProvider"))
directory := NewBaseDirectory(&url)
assert.NotNil(t, directory)
localIP, _ := gxnet.GetLocalIP()
rule := base64.URLEncoding.EncodeToString([]byte("true => " + " host = " + localIP))
routeURL := getRouteUrl(rule)
routerURLs := make([]*common.URL, 0)
routerURLs = append(routerURLs, routeURL)
directory.SetRouters(routerURLs)
chain := directory.RouterChain()
assert.NotNil(t, chain)
}
func getRouteUrl(rule string) *common.URL {
url, _ := common.NewURL("condition://0.0.0.0/com.foo.BarService")
url.AddParam("rule", rule)
url.AddParam("force", "true")
url.AddParam(constant.ROUTER_KEY, "router")
return &url
}
...@@ -18,6 +18,11 @@ ...@@ -18,6 +18,11 @@
package directory package directory
import ( import (
perrors "github.com/pkg/errors"
)
import (
"github.com/apache/dubbo-go/cluster/router/chain"
"github.com/apache/dubbo-go/common" "github.com/apache/dubbo-go/common"
"github.com/apache/dubbo-go/protocol" "github.com/apache/dubbo-go/protocol"
) )
...@@ -27,7 +32,7 @@ type staticDirectory struct { ...@@ -27,7 +32,7 @@ type staticDirectory struct {
invokers []protocol.Invoker invokers []protocol.Invoker
} }
// NewStaticDirectory ... // NewStaticDirectory Create a new staticDirectory with invokers
func NewStaticDirectory(invokers []protocol.Invoker) *staticDirectory { func NewStaticDirectory(invokers []protocol.Invoker) *staticDirectory {
var url common.URL var url common.URL
...@@ -53,11 +58,21 @@ func (dir *staticDirectory) IsAvailable() bool { ...@@ -53,11 +58,21 @@ func (dir *staticDirectory) IsAvailable() bool {
return true return true
} }
// List List invokers
func (dir *staticDirectory) List(invocation protocol.Invocation) []protocol.Invoker { func (dir *staticDirectory) List(invocation protocol.Invocation) []protocol.Invoker {
//TODO:Here should add router l := len(dir.invokers)
return dir.invokers invokers := make([]protocol.Invoker, l, l)
copy(invokers, dir.invokers)
routerChain := dir.RouterChain()
if routerChain == nil {
return invokers
}
dirUrl := dir.GetUrl()
return routerChain.Route(invokers, &dirUrl, invocation)
} }
// Destroy Destroy
func (dir *staticDirectory) Destroy() { func (dir *staticDirectory) Destroy() {
dir.BaseDirectory.Destroy(func() { dir.BaseDirectory.Destroy(func() {
for _, ivk := range dir.invokers { for _, ivk := range dir.invokers {
...@@ -66,3 +81,17 @@ func (dir *staticDirectory) Destroy() { ...@@ -66,3 +81,17 @@ func (dir *staticDirectory) Destroy() {
dir.invokers = []protocol.Invoker{} dir.invokers = []protocol.Invoker{}
}) })
} }
// BuildRouterChain build router chain by invokers
func (dir *staticDirectory) BuildRouterChain(invokers []protocol.Invoker) error {
if len(invokers) == 0 {
return perrors.Errorf("invokers == null")
}
url := invokers[0].GetUrl()
routerChain, e := chain.NewRouterChain(&url)
if e != nil {
return e
}
dir.SetRouterChain(routerChain)
return nil
}
...@@ -40,7 +40,9 @@ func Test_StaticDirList(t *testing.T) { ...@@ -40,7 +40,9 @@ func Test_StaticDirList(t *testing.T) {
} }
staticDir := NewStaticDirectory(invokers) staticDir := NewStaticDirectory(invokers)
assert.Len(t, staticDir.List(&invocation.RPCInvocation{}), 10) list := staticDir.List(&invocation.RPCInvocation{})
assert.Len(t, list, 10)
} }
func Test_StaticDirDestroy(t *testing.T) { func Test_StaticDirDestroy(t *testing.T) {
......
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package chain
import (
"math"
"sort"
"sync"
)
import (
perrors "github.com/pkg/errors"
)
import (
"github.com/apache/dubbo-go/cluster/router"
"github.com/apache/dubbo-go/common"
"github.com/apache/dubbo-go/common/extension"
"github.com/apache/dubbo-go/common/logger"
"github.com/apache/dubbo-go/protocol"
)
// RouterChain Router chain
type RouterChain struct {
// Full list of addresses from registry, classified by method name.
invokers []protocol.Invoker
// Containing all routers, reconstruct every time 'route://' urls change.
routers []router.Router
// Fixed router instances: ConfigConditionRouter, TagRouter, e.g., the rule for each instance may change but the
// instance will never delete or recreate.
builtinRouters []router.Router
mutex sync.RWMutex
}
// Route Loop routers in RouterChain and call Route method to determine the target invokers list.
func (c *RouterChain) Route(invoker []protocol.Invoker, url *common.URL, invocation protocol.Invocation) []protocol.Invoker {
finalInvokers := invoker
l := len(c.routers)
rs := make([]router.Router, l, int(math.Ceil(float64(l)*1.2)))
c.mutex.RLock()
copy(rs, c.routers)
c.mutex.RUnlock()
for _, r := range rs {
finalInvokers = r.Route(finalInvokers, url, invocation)
}
return finalInvokers
}
// AddRouters Add routers to router chain
// New a array add builtinRouters which is not sorted in RouterChain and routers
// Sort the array
// Replace router array in RouterChain
func (c *RouterChain) AddRouters(routers []router.Router) {
newRouters := make([]router.Router, 0, len(c.builtinRouters)+len(routers))
newRouters = append(newRouters, c.builtinRouters...)
newRouters = append(newRouters, routers...)
sortRouter(newRouters)
c.mutex.Lock()
defer c.mutex.Unlock()
c.routers = newRouters
}
// NewRouterChain Use url to init router chain
// Loop routerFactories and call NewRouter method
func NewRouterChain(url *common.URL) (*RouterChain, error) {
routerFactories := extension.GetRouterFactories()
if len(routerFactories) == 0 {
return nil, perrors.Errorf("No routerFactory exits , create one please")
}
routers := make([]router.Router, 0, len(routerFactories))
for key, routerFactory := range routerFactories {
r, err := routerFactory().NewRouter(url)
if r == nil || err != nil {
logger.Errorf("router chain build router fail! routerFactories key:%s error:%s", key, err.Error())
continue
}
routers = append(routers, r)
}
newRouters := make([]router.Router, len(routers))
copy(newRouters, routers)
sortRouter(newRouters)
chain := &RouterChain{
builtinRouters: routers,
routers: newRouters,
}
return chain, nil
}
// sortRouter Sort router instance by priority with stable algorithm
func sortRouter(routers []router.Router) {
sort.Stable(byPriority(routers))
}
// byPriority Sort by priority
type byPriority []router.Router
func (a byPriority) Len() int { return len(a) }
func (a byPriority) Swap(i, j int) { a[i], a[j] = a[j], a[i] }
func (a byPriority) Less(i, j int) bool { return a[i].Priority() < a[j].Priority() }
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package chain
import (
"encoding/base64"
"fmt"
"strconv"
"testing"
"time"
)
import (
"github.com/stretchr/testify/assert"
)
import (
"github.com/apache/dubbo-go/cluster/router"
"github.com/apache/dubbo-go/cluster/router/condition"
"github.com/apache/dubbo-go/common"
"github.com/apache/dubbo-go/common/config"
"github.com/apache/dubbo-go/common/constant"
"github.com/apache/dubbo-go/common/extension"
_ "github.com/apache/dubbo-go/config_center/zookeeper"
"github.com/apache/dubbo-go/protocol"
"github.com/apache/dubbo-go/protocol/invocation"
"github.com/apache/dubbo-go/remoting/zookeeper"
)
func TestNewRouterChain(t *testing.T) {
ts, z, _, err := zookeeper.NewMockZookeeperClient("test", 15*time.Second)
assert.NoError(t, err)
err = z.Create("/dubbo/config/dubbo/test-condition.condition-router")
assert.NoError(t, err)
testyml := `enabled: true
force: true
runtime: false
conditions:
- => host != 172.22.3.91
`
_, err = z.Conn.Set("/dubbo/config/dubbo/test-condition.condition-router", []byte(testyml), 0)
assert.NoError(t, err)
defer ts.Stop()
defer z.Close()
zkUrl, _ := common.NewURL("zookeeper://127.0.0.1:" + strconv.Itoa(ts.Servers[0].Port))
configuration, err := extension.GetConfigCenterFactory("zookeeper").GetDynamicConfiguration(&zkUrl)
config.GetEnvInstance().SetDynamicConfiguration(configuration)
assert.Nil(t, err)
assert.NotNil(t, configuration)
chain, err := NewRouterChain(getRouteUrl("test-condition"))
assert.Nil(t, err)
assert.Equal(t, 1, len(chain.routers))
appRouter := chain.routers[0].(*condition.AppRouter)
assert.NotNil(t, appRouter)
assert.NotNil(t, appRouter.RouterRule())
rule := appRouter.RouterRule()
assert.Equal(t, "", rule.Scope)
assert.True(t, rule.Force)
assert.True(t, rule.Enabled)
assert.True(t, rule.Valid)
assert.Equal(t, testyml, rule.RawRule)
assert.Equal(t, false, rule.Runtime)
assert.Equal(t, false, rule.Dynamic)
assert.Equal(t, "", rule.Key)
}
func TestNewRouterChainURLNil(t *testing.T) {
chain, err := NewRouterChain(nil)
assert.NoError(t, err)
assert.NotNil(t, chain)
}
func TestRouterChain_AddRouters(t *testing.T) {
ts, z, _, err := zookeeper.NewMockZookeeperClient("test", 15*time.Second)
assert.NoError(t, err)
err = z.Create("/dubbo/config/dubbo/test-condition.condition-router")
assert.NoError(t, err)
testyml := `enabled: true
force: true
runtime: false
conditions:
- => host != 172.22.3.91
`
_, err = z.Conn.Set("/dubbo/config/dubbo/test-condition.condition-router", []byte(testyml), 0)
assert.NoError(t, err)
defer ts.Stop()
defer z.Close()
zkUrl, _ := common.NewURL("zookeeper://127.0.0.1:" + strconv.Itoa(ts.Servers[0].Port))
configuration, err := extension.GetConfigCenterFactory("zookeeper").GetDynamicConfiguration(&zkUrl)
config.GetEnvInstance().SetDynamicConfiguration(configuration)
chain, err := NewRouterChain(getConditionRouteUrl("test-condition"))
assert.Nil(t, err)
assert.Equal(t, 2, len(chain.routers))
url := getConditionRouteUrl("test-condition")
assert.NotNil(t, url)
factory := extension.GetRouterFactory(url.Protocol)
r, err := factory.NewRouter(url)
assert.Nil(t, err)
assert.NotNil(t, r)
routers := make([]router.Router, 0)
routers = append(routers, r)
chain.AddRouters(routers)
assert.Equal(t, 3, len(chain.routers))
}
func TestRouterChain_Route(t *testing.T) {
ts, z, _, err := zookeeper.NewMockZookeeperClient("test", 15*time.Second)
defer ts.Stop()
defer z.Close()
zkUrl, _ := common.NewURL("zookeeper://127.0.0.1:" + strconv.Itoa(ts.Servers[0].Port))
configuration, err := extension.GetConfigCenterFactory("zookeeper").GetDynamicConfiguration(&zkUrl)
config.GetEnvInstance().SetDynamicConfiguration(configuration)
chain, err := NewRouterChain(getConditionRouteUrl("test-condition"))
assert.Nil(t, err)
assert.Equal(t, 1, len(chain.routers))
url := getConditionRouteUrl("test-condition")
assert.NotNil(t, url)
invokers := []protocol.Invoker{}
dubboURL, _ := common.NewURL(fmt.Sprintf("dubbo://1.2.3.4:20000/com.foo.BarService"))
invokers = append(invokers, protocol.NewBaseInvoker(dubboURL))
targetURL, _ := common.NewURL(fmt.Sprintf("consumer://1.1.1.1/com.foo.BarService"))
inv := &invocation.RPCInvocation{}
finalInvokers := chain.Route(invokers, &targetURL, inv)
assert.Equal(t, 1, len(finalInvokers))
}
func TestRouterChain_Route_AppRouter(t *testing.T) {
ts, z, _, err := zookeeper.NewMockZookeeperClient("test", 15*time.Second)
assert.NoError(t, err)
err = z.Create("/dubbo/config/dubbo/test-condition.condition-router")
assert.NoError(t, err)
testyml := `enabled: true
force: true
runtime: false
conditions:
- => host = 1.1.1.1 => host != 1.2.3.4
`
_, err = z.Conn.Set("/dubbo/config/dubbo/test-condition.condition-router", []byte(testyml), 0)
assert.NoError(t, err)
defer ts.Stop()
defer z.Close()
zkUrl, _ := common.NewURL("zookeeper://127.0.0.1:" + strconv.Itoa(ts.Servers[0].Port))
configuration, err := extension.GetConfigCenterFactory("zookeeper").GetDynamicConfiguration(&zkUrl)
config.GetEnvInstance().SetDynamicConfiguration(configuration)
chain, err := NewRouterChain(getConditionRouteUrl("test-condition"))
assert.Nil(t, err)
assert.Equal(t, 2, len(chain.routers))
invokers := []protocol.Invoker{}
dubboURL, _ := common.NewURL(fmt.Sprintf("dubbo://1.2.3.4:20000/com.foo.BarService"))
invokers = append(invokers, protocol.NewBaseInvoker(dubboURL))
targetURL, _ := common.NewURL(fmt.Sprintf("consumer://1.1.1.1/com.foo.BarService"))
inv := &invocation.RPCInvocation{}
finalInvokers := chain.Route(invokers, &targetURL, inv)
assert.Equal(t, 0, len(finalInvokers))
}
func TestRouterChain_Route_NoRoute(t *testing.T) {
ts, z, _, err := zookeeper.NewMockZookeeperClient("test", 15*time.Second)
defer ts.Stop()
defer z.Close()
zkUrl, _ := common.NewURL("zookeeper://127.0.0.1:" + strconv.Itoa(ts.Servers[0].Port))
configuration, err := extension.GetConfigCenterFactory("zookeeper").GetDynamicConfiguration(&zkUrl)
config.GetEnvInstance().SetDynamicConfiguration(configuration)
chain, err := NewRouterChain(getConditionNoRouteUrl("test-condition"))
assert.Nil(t, err)
assert.Equal(t, 1, len(chain.routers))
url := getConditionRouteUrl("test-condition")
assert.NotNil(t, url)
invokers := []protocol.Invoker{}
dubboURL, _ := common.NewURL(fmt.Sprintf("dubbo://1.2.3.4:20000/com.foo.BarService"))
invokers = append(invokers, protocol.NewBaseInvoker(dubboURL))
targetURL, _ := common.NewURL(fmt.Sprintf("consumer://1.1.1.1/com.foo.BarService"))
inv := &invocation.RPCInvocation{}
finalInvokers := chain.Route(invokers, &targetURL, inv)
assert.Equal(t, 0, len(finalInvokers))
}
func getConditionNoRouteUrl(applicationKey string) *common.URL {
url, _ := common.NewURL("condition://0.0.0.0/com.foo.BarService")
url.AddParam("application", applicationKey)
url.AddParam("force", "true")
rule := base64.URLEncoding.EncodeToString([]byte("host = 1.1.1.1 => host != 1.2.3.4"))
url.AddParam(constant.RULE_KEY, rule)
return &url
}
func getConditionRouteUrl(applicationKey string) *common.URL {
url, _ := common.NewURL("condition://0.0.0.0/com.foo.BarService")
url.AddParam("application", applicationKey)
url.AddParam("force", "true")
rule := base64.URLEncoding.EncodeToString([]byte("host = 1.1.1.1 => host = 1.2.3.4"))
url.AddParam(constant.RULE_KEY, rule)
return &url
}
func getRouteUrl(applicationKey string) *common.URL {
url, _ := common.NewURL("condition://0.0.0.0/com.foo.BarService")
url.AddParam("application", applicationKey)
url.AddParam("force", "true")
return &url
}
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package condition
import (
perrors "github.com/pkg/errors"
)
import (
"github.com/apache/dubbo-go/common"
"github.com/apache/dubbo-go/common/constant"
)
const (
// Default priority for application router
appRouterDefaultPriority = int64(150)
)
// AppRouter For listen application router with config center
type AppRouter struct {
listenableRouter
}
// NewAppRouter Init AppRouter by url
func NewAppRouter(url *common.URL) (*AppRouter, error) {
if url == nil {
return nil, perrors.Errorf("No route URL for create app router!")
}
appRouter, err := newListenableRouter(url, url.GetParam(constant.APPLICATION_KEY, ""))
if err != nil {
return nil, err
}
appRouter.priority = appRouterDefaultPriority
return appRouter, nil
}
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package condition
import (
"strconv"
"testing"
"time"
)
import (
_ "github.com/apache/dubbo-go/config_center/zookeeper"
"github.com/stretchr/testify/assert"
)
import (
"github.com/apache/dubbo-go/common"
"github.com/apache/dubbo-go/common/config"
"github.com/apache/dubbo-go/common/extension"
"github.com/apache/dubbo-go/config_center"
"github.com/apache/dubbo-go/remoting"
"github.com/apache/dubbo-go/remoting/zookeeper"
)
func TestNewAppRouter(t *testing.T) {
testYML := `enabled: true
force: true
runtime: false
conditions:
- => host != 172.22.3.91
`
ts, z, _, err := zookeeper.NewMockZookeeperClient("test", 15*time.Second)
assert.NoError(t, err)
err = z.Create("/dubbo/config/dubbo/test-condition.condition-router")
assert.NoError(t, err)
_, err = z.Conn.Set("/dubbo/config/dubbo/test-condition.condition-router", []byte(testYML), 0)
assert.NoError(t, err)
defer ts.Stop()
defer z.Close()
zkUrl, _ := common.NewURL("zookeeper://127.0.0.1:" + strconv.Itoa(ts.Servers[0].Port))
configuration, err := extension.GetConfigCenterFactory("zookeeper").GetDynamicConfiguration(&zkUrl)
config.GetEnvInstance().SetDynamicConfiguration(configuration)
assert.Nil(t, err)
assert.NotNil(t, configuration)
appRouteURL := getAppRouteURL("test-condition")
appRouter, err := NewAppRouter(appRouteURL)
assert.Nil(t, err)
assert.NotNil(t, appRouter)
assert.NotNil(t, appRouter)
assert.NotNil(t, appRouter.RouterRule())
rule := appRouter.RouterRule()
assert.Equal(t, "", rule.Scope)
assert.True(t, rule.Force)
assert.True(t, rule.Enabled)
assert.True(t, rule.Valid)
assert.Equal(t, testYML, rule.RawRule)
assert.Equal(t, false, rule.Runtime)
assert.Equal(t, false, rule.Dynamic)
assert.Equal(t, "", rule.Key)
assert.Equal(t, 0, rule.Priority)
}
func TestGenerateConditions(t *testing.T) {
testYML := `enabled: true
force: true
runtime: false
conditions:
- => host != 172.22.3.91
- host = 192.168.199.208 => host = 192.168.199.208
`
ts, z, _, err := zookeeper.NewMockZookeeperClient("test", 15*time.Second)
assert.NoError(t, err)
err = z.Create("/dubbo/config/dubbo/test-condition.condition-router")
assert.NoError(t, err)
_, err = z.Conn.Set("/dubbo/config/dubbo/test-condition.condition-router", []byte(testYML), 0)
assert.NoError(t, err)
defer ts.Stop()
defer z.Close()
zkUrl, _ := common.NewURL("zookeeper://127.0.0.1:" + strconv.Itoa(ts.Servers[0].Port))
configuration, err := extension.GetConfigCenterFactory("zookeeper").GetDynamicConfiguration(&zkUrl)
config.GetEnvInstance().SetDynamicConfiguration(configuration)
assert.Nil(t, err)
assert.NotNil(t, configuration)
appRouteURL := getAppRouteURL("test-condition")
appRouter, err := NewAppRouter(appRouteURL)
assert.Nil(t, err)
assert.NotNil(t, appRouter)
rule, err := Parse(testYML)
assert.Nil(t, err)
appRouter.generateConditions(rule)
assert.Equal(t, 2, len(appRouter.conditionRouters))
}
func TestProcess(t *testing.T) {
testYML := `enabled: true
force: true
runtime: false
conditions:
- => host != 172.22.3.91
`
ts, z, _, err := zookeeper.NewMockZookeeperClient("test", 15*time.Second)
assert.NoError(t, err)
err = z.Create("/dubbo/config/dubbo/test-condition.condition-router")
assert.NoError(t, err)
_, err = z.Conn.Set("/dubbo/config/dubbo/test-condition.condition-router", []byte(testYML), 0)
assert.NoError(t, err)
defer ts.Stop()
defer z.Close()
zkUrl, _ := common.NewURL("zookeeper://127.0.0.1:" + strconv.Itoa(ts.Servers[0].Port))
configuration, err := extension.GetConfigCenterFactory("zookeeper").GetDynamicConfiguration(&zkUrl)
config.GetEnvInstance().SetDynamicConfiguration(configuration)
assert.Nil(t, err)
assert.NotNil(t, configuration)
appRouteURL := getAppRouteURL("test-condition")
appRouter, err := NewAppRouter(appRouteURL)
assert.Nil(t, err)
assert.NotNil(t, appRouter)
assert.Equal(t, 1, len(appRouter.conditionRouters))
testNewYML := `
enabled: true
force: true
runtime: false
conditions:
- => host != 172.22.3.91
- host = 192.168.199.208 => host = 192.168.199.208
`
appRouter.Process(&config_center.ConfigChangeEvent{ConfigType: remoting.EventTypeDel})
assert.Equal(t, 0, len(appRouter.conditionRouters))
appRouter.Process(&config_center.ConfigChangeEvent{Value: testNewYML, ConfigType: remoting.EventTypeAdd})
assert.Equal(t, 2, len(appRouter.conditionRouters))
}
func getAppRouteURL(applicationKey string) *common.URL {
url, _ := common.NewURL("condition://0.0.0.0/com.foo.BarService")
url.AddParam("application", applicationKey)
url.AddParam("force", "true")
return &url
}
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package condition
import (
"github.com/apache/dubbo-go/cluster/router"
"github.com/apache/dubbo-go/common"
"github.com/apache/dubbo-go/common/constant"
"github.com/apache/dubbo-go/common/extension"
)
func init() {
extension.SetRouterFactory(constant.ConditionRouterName, newConditionRouterFactory)
extension.SetRouterFactory(constant.ConditionAppRouterName, newAppRouterFactory)
}
// ConditionRouterFactory Condition router factory
type ConditionRouterFactory struct{}
func newConditionRouterFactory() router.RouterFactory {
return &ConditionRouterFactory{}
}
// NewRouter Create ConditionRouterFactory by URL
func (c *ConditionRouterFactory) NewRouter(url *common.URL) (router.Router, error) {
return NewConditionRouter(url)
}
// NewRouter Create FileRouterFactory by Content
func (c *ConditionRouterFactory) NewFileRouter(content []byte) (router.Router, error) {
return NewFileConditionRouter(content)
}
// AppRouterFactory Application router factory
type AppRouterFactory struct{}
func newAppRouterFactory() router.RouterFactory {
return &AppRouterFactory{}
}
// NewRouter Create AppRouterFactory by URL
func (c *AppRouterFactory) NewRouter(url *common.URL) (router.Router, error) {
return NewAppRouter(url)
}
...@@ -15,7 +15,7 @@ ...@@ -15,7 +15,7 @@
* limitations under the License. * limitations under the License.
*/ */
package router package condition
import ( import (
"context" "context"
...@@ -119,33 +119,33 @@ func (bi *MockInvoker) Destroy() { ...@@ -119,33 +119,33 @@ func (bi *MockInvoker) Destroy() {
func TestRoute_matchWhen(t *testing.T) { func TestRoute_matchWhen(t *testing.T) {
inv := &invocation.RPCInvocation{} inv := &invocation.RPCInvocation{}
rule := base64.URLEncoding.EncodeToString([]byte("=> host = 1.2.3.4")) rule := base64.URLEncoding.EncodeToString([]byte("=> host = 1.2.3.4"))
router, _ := NewConditionRouterFactory().Router(getRouteUrl(rule)) router, _ := newConditionRouterFactory().NewRouter(getRouteUrl(rule))
cUrl, _ := common.NewURL("consumer://1.1.1.1/com.foo.BarService") cUrl, _ := common.NewURL("consumer://1.1.1.1/com.foo.BarService")
matchWhen, _ := router.(*ConditionRouter).MatchWhen(cUrl, inv) matchWhen := router.(*ConditionRouter).MatchWhen(&cUrl, inv)
assert.Equal(t, true, matchWhen) assert.Equal(t, true, matchWhen)
rule1 := base64.URLEncoding.EncodeToString([]byte("host = 2.2.2.2,1.1.1.1,3.3.3.3 => host = 1.2.3.4")) rule1 := base64.URLEncoding.EncodeToString([]byte("host = 2.2.2.2,1.1.1.1,3.3.3.3 => host = 1.2.3.4"))
router1, _ := NewConditionRouterFactory().Router(getRouteUrl(rule1)) router1, _ := newConditionRouterFactory().NewRouter(getRouteUrl(rule1))
matchWhen1, _ := router1.(*ConditionRouter).MatchWhen(cUrl, inv) matchWhen1 := router1.(*ConditionRouter).MatchWhen(&cUrl, inv)
assert.Equal(t, true, matchWhen1) assert.Equal(t, true, matchWhen1)
rule2 := base64.URLEncoding.EncodeToString([]byte("host = 2.2.2.2,1.1.1.1,3.3.3.3 & host !=1.1.1.1 => host = 1.2.3.4")) rule2 := base64.URLEncoding.EncodeToString([]byte("host = 2.2.2.2,1.1.1.1,3.3.3.3 & host !=1.1.1.1 => host = 1.2.3.4"))
router2, _ := NewConditionRouterFactory().Router(getRouteUrl(rule2)) router2, _ := newConditionRouterFactory().NewRouter(getRouteUrl(rule2))
matchWhen2, _ := router2.(*ConditionRouter).MatchWhen(cUrl, inv) matchWhen2 := router2.(*ConditionRouter).MatchWhen(&cUrl, inv)
assert.Equal(t, false, matchWhen2) assert.Equal(t, false, matchWhen2)
rule3 := base64.URLEncoding.EncodeToString([]byte("host !=4.4.4.4 & host = 2.2.2.2,1.1.1.1,3.3.3.3 => host = 1.2.3.4")) rule3 := base64.URLEncoding.EncodeToString([]byte("host !=4.4.4.4 & host = 2.2.2.2,1.1.1.1,3.3.3.3 => host = 1.2.3.4"))
router3, _ := NewConditionRouterFactory().Router(getRouteUrl(rule3)) router3, _ := newConditionRouterFactory().NewRouter(getRouteUrl(rule3))
matchWhen3, _ := router3.(*ConditionRouter).MatchWhen(cUrl, inv) matchWhen3 := router3.(*ConditionRouter).MatchWhen(&cUrl, inv)
assert.Equal(t, true, matchWhen3) assert.Equal(t, true, matchWhen3)
rule4 := base64.URLEncoding.EncodeToString([]byte("host !=4.4.4.* & host = 2.2.2.2,1.1.1.1,3.3.3.3 => host = 1.2.3.4")) rule4 := base64.URLEncoding.EncodeToString([]byte("host !=4.4.4.* & host = 2.2.2.2,1.1.1.1,3.3.3.3 => host = 1.2.3.4"))
router4, _ := NewConditionRouterFactory().Router(getRouteUrl(rule4)) router4, _ := newConditionRouterFactory().NewRouter(getRouteUrl(rule4))
matchWhen4, _ := router4.(*ConditionRouter).MatchWhen(cUrl, inv) matchWhen4 := router4.(*ConditionRouter).MatchWhen(&cUrl, inv)
assert.Equal(t, true, matchWhen4) assert.Equal(t, true, matchWhen4)
rule5 := base64.URLEncoding.EncodeToString([]byte("host = 2.2.2.2,1.1.1.*,3.3.3.3 & host != 1.1.1.1 => host = 1.2.3.4")) rule5 := base64.URLEncoding.EncodeToString([]byte("host = 2.2.2.2,1.1.1.*,3.3.3.3 & host != 1.1.1.1 => host = 1.2.3.4"))
router5, _ := NewConditionRouterFactory().Router(getRouteUrl(rule5)) router5, _ := newConditionRouterFactory().NewRouter(getRouteUrl(rule5))
matchWhen5, _ := router5.(*ConditionRouter).MatchWhen(cUrl, inv) matchWhen5 := router5.(*ConditionRouter).MatchWhen(&cUrl, inv)
assert.Equal(t, false, matchWhen5) assert.Equal(t, false, matchWhen5)
rule6 := base64.URLEncoding.EncodeToString([]byte("host = 2.2.2.2,1.1.1.*,3.3.3.3 & host != 1.1.1.2 => host = 1.2.3.4")) rule6 := base64.URLEncoding.EncodeToString([]byte("host = 2.2.2.2,1.1.1.*,3.3.3.3 & host != 1.1.1.2 => host = 1.2.3.4"))
router6, _ := NewConditionRouterFactory().Router(getRouteUrl(rule6)) router6, _ := newConditionRouterFactory().NewRouter(getRouteUrl(rule6))
matchWhen6, _ := router6.(*ConditionRouter).MatchWhen(cUrl, inv) matchWhen6 := router6.(*ConditionRouter).MatchWhen(&cUrl, inv)
assert.Equal(t, true, matchWhen6) assert.Equal(t, true, matchWhen6)
} }
...@@ -162,19 +162,19 @@ func TestRoute_matchFilter(t *testing.T) { ...@@ -162,19 +162,19 @@ func TestRoute_matchFilter(t *testing.T) {
rule4 := base64.URLEncoding.EncodeToString([]byte("host = " + localIP + " => " + " host = 10.20.3.2,10.20.3.3,10.20.3.4")) rule4 := base64.URLEncoding.EncodeToString([]byte("host = " + localIP + " => " + " host = 10.20.3.2,10.20.3.3,10.20.3.4"))
rule5 := base64.URLEncoding.EncodeToString([]byte("host = " + localIP + " => " + " host != 10.20.3.3")) rule5 := base64.URLEncoding.EncodeToString([]byte("host = " + localIP + " => " + " host != 10.20.3.3"))
rule6 := base64.URLEncoding.EncodeToString([]byte("host = " + localIP + " => " + " serialization = fastjson")) rule6 := base64.URLEncoding.EncodeToString([]byte("host = " + localIP + " => " + " serialization = fastjson"))
router1, _ := NewConditionRouterFactory().Router(getRouteUrl(rule1)) router1, _ := newConditionRouterFactory().NewRouter(getRouteUrl(rule1))
router2, _ := NewConditionRouterFactory().Router(getRouteUrl(rule2)) router2, _ := newConditionRouterFactory().NewRouter(getRouteUrl(rule2))
router3, _ := NewConditionRouterFactory().Router(getRouteUrl(rule3)) router3, _ := newConditionRouterFactory().NewRouter(getRouteUrl(rule3))
router4, _ := NewConditionRouterFactory().Router(getRouteUrl(rule4)) router4, _ := newConditionRouterFactory().NewRouter(getRouteUrl(rule4))
router5, _ := NewConditionRouterFactory().Router(getRouteUrl(rule5)) router5, _ := newConditionRouterFactory().NewRouter(getRouteUrl(rule5))
router6, _ := NewConditionRouterFactory().Router(getRouteUrl(rule6)) router6, _ := newConditionRouterFactory().NewRouter(getRouteUrl(rule6))
cUrl, _ := common.NewURL("consumer://" + localIP + "/com.foo.BarService") cUrl, _ := common.NewURL("consumer://" + localIP + "/com.foo.BarService")
fileredInvokers1 := router1.Route(invokers, cUrl, &invocation.RPCInvocation{}) fileredInvokers1 := router1.Route(invokers, &cUrl, &invocation.RPCInvocation{})
fileredInvokers2 := router2.Route(invokers, cUrl, &invocation.RPCInvocation{}) fileredInvokers2 := router2.Route(invokers, &cUrl, &invocation.RPCInvocation{})
fileredInvokers3 := router3.Route(invokers, cUrl, &invocation.RPCInvocation{}) fileredInvokers3 := router3.Route(invokers, &cUrl, &invocation.RPCInvocation{})
fileredInvokers4 := router4.Route(invokers, cUrl, &invocation.RPCInvocation{}) fileredInvokers4 := router4.Route(invokers, &cUrl, &invocation.RPCInvocation{})
fileredInvokers5 := router5.Route(invokers, cUrl, &invocation.RPCInvocation{}) fileredInvokers5 := router5.Route(invokers, &cUrl, &invocation.RPCInvocation{})
fileredInvokers6 := router6.Route(invokers, cUrl, &invocation.RPCInvocation{}) fileredInvokers6 := router6.Route(invokers, &cUrl, &invocation.RPCInvocation{})
assert.Equal(t, 1, len(fileredInvokers1)) assert.Equal(t, 1, len(fileredInvokers1))
assert.Equal(t, 0, len(fileredInvokers2)) assert.Equal(t, 0, len(fileredInvokers2))
assert.Equal(t, 0, len(fileredInvokers3)) assert.Equal(t, 0, len(fileredInvokers3))
...@@ -187,22 +187,22 @@ func TestRoute_matchFilter(t *testing.T) { ...@@ -187,22 +187,22 @@ func TestRoute_matchFilter(t *testing.T) {
func TestRoute_methodRoute(t *testing.T) { func TestRoute_methodRoute(t *testing.T) {
inv := invocation.NewRPCInvocationWithOptions(invocation.WithMethodName("getFoo"), invocation.WithParameterTypes([]reflect.Type{}), invocation.WithArguments([]interface{}{})) inv := invocation.NewRPCInvocationWithOptions(invocation.WithMethodName("getFoo"), invocation.WithParameterTypes([]reflect.Type{}), invocation.WithArguments([]interface{}{}))
rule := base64.URLEncoding.EncodeToString([]byte("host !=4.4.4.* & host = 2.2.2.2,1.1.1.1,3.3.3.3 => host = 1.2.3.4")) rule := base64.URLEncoding.EncodeToString([]byte("host !=4.4.4.* & host = 2.2.2.2,1.1.1.1,3.3.3.3 => host = 1.2.3.4"))
router, _ := NewConditionRouterFactory().Router(getRouteUrl(rule)) router, _ := newConditionRouterFactory().NewRouter(getRouteUrl(rule))
url, _ := common.NewURL("consumer://1.1.1.1/com.foo.BarService?methods=setFoo,getFoo,findFoo") url, _ := common.NewURL("consumer://1.1.1.1/com.foo.BarService?methods=setFoo,getFoo,findFoo")
matchWhen, _ := router.(*ConditionRouter).MatchWhen(url, inv) matchWhen := router.(*ConditionRouter).MatchWhen(&url, inv)
assert.Equal(t, true, matchWhen) assert.Equal(t, true, matchWhen)
url1, _ := common.NewURL("consumer://1.1.1.1/com.foo.BarService?methods=getFoo") url1, _ := common.NewURL("consumer://1.1.1.1/com.foo.BarService?methods=getFoo")
matchWhen, _ = router.(*ConditionRouter).MatchWhen(url1, inv) matchWhen = router.(*ConditionRouter).MatchWhen(&url1, inv)
assert.Equal(t, true, matchWhen) assert.Equal(t, true, matchWhen)
url2, _ := common.NewURL("consumer://1.1.1.1/com.foo.BarService?methods=getFoo") url2, _ := common.NewURL("consumer://1.1.1.1/com.foo.BarService?methods=getFoo")
rule2 := base64.URLEncoding.EncodeToString([]byte("methods=getFoo & host!=1.1.1.1 => host = 1.2.3.4")) rule2 := base64.URLEncoding.EncodeToString([]byte("methods=getFoo & host!=1.1.1.1 => host = 1.2.3.4"))
router2, _ := NewConditionRouterFactory().Router(getRouteUrl(rule2)) router2, _ := newConditionRouterFactory().NewRouter(getRouteUrl(rule2))
matchWhen, _ = router2.(*ConditionRouter).MatchWhen(url2, inv) matchWhen = router2.(*ConditionRouter).MatchWhen(&url2, inv)
assert.Equal(t, false, matchWhen) assert.Equal(t, false, matchWhen)
url3, _ := common.NewURL("consumer://1.1.1.1/com.foo.BarService?methods=getFoo") url3, _ := common.NewURL("consumer://1.1.1.1/com.foo.BarService?methods=getFoo")
rule3 := base64.URLEncoding.EncodeToString([]byte("methods=getFoo & host=1.1.1.1 => host = 1.2.3.4")) rule3 := base64.URLEncoding.EncodeToString([]byte("methods=getFoo & host=1.1.1.1 => host = 1.2.3.4"))
router3, _ := NewConditionRouterFactory().Router(getRouteUrl(rule3)) router3, _ := newConditionRouterFactory().NewRouter(getRouteUrl(rule3))
matchWhen, _ = router3.(*ConditionRouter).MatchWhen(url3, inv) matchWhen = router3.(*ConditionRouter).MatchWhen(&url3, inv)
assert.Equal(t, true, matchWhen) assert.Equal(t, true, matchWhen)
} }
...@@ -214,8 +214,8 @@ func TestRoute_ReturnFalse(t *testing.T) { ...@@ -214,8 +214,8 @@ func TestRoute_ReturnFalse(t *testing.T) {
inv := &invocation.RPCInvocation{} inv := &invocation.RPCInvocation{}
rule := base64.URLEncoding.EncodeToString([]byte("host = " + localIP + " => false")) rule := base64.URLEncoding.EncodeToString([]byte("host = " + localIP + " => false"))
curl, _ := common.NewURL("consumer://" + localIP + "/com.foo.BarService") curl, _ := common.NewURL("consumer://" + localIP + "/com.foo.BarService")
router, _ := NewConditionRouterFactory().Router(getRouteUrl(rule)) router, _ := newConditionRouterFactory().NewRouter(getRouteUrl(rule))
fileredInvokers := router.(*ConditionRouter).Route(invokers, curl, inv) fileredInvokers := router.(*ConditionRouter).Route(invokers, &curl, inv)
assert.Equal(t, 0, len(fileredInvokers)) assert.Equal(t, 0, len(fileredInvokers))
} }
...@@ -226,19 +226,24 @@ func TestRoute_ReturnEmpty(t *testing.T) { ...@@ -226,19 +226,24 @@ func TestRoute_ReturnEmpty(t *testing.T) {
inv := &invocation.RPCInvocation{} inv := &invocation.RPCInvocation{}
rule := base64.URLEncoding.EncodeToString([]byte("host = " + localIP + " => ")) rule := base64.URLEncoding.EncodeToString([]byte("host = " + localIP + " => "))
curl, _ := common.NewURL("consumer://" + localIP + "/com.foo.BarService") curl, _ := common.NewURL("consumer://" + localIP + "/com.foo.BarService")
router, _ := NewConditionRouterFactory().Router(getRouteUrl(rule)) router, _ := newConditionRouterFactory().NewRouter(getRouteUrl(rule))
fileredInvokers := router.(*ConditionRouter).Route(invokers, curl, inv) fileredInvokers := router.(*ConditionRouter).Route(invokers, &curl, inv)
assert.Equal(t, 0, len(fileredInvokers)) assert.Equal(t, 0, len(fileredInvokers))
} }
func TestRoute_ReturnAll(t *testing.T) { func TestRoute_ReturnAll(t *testing.T) {
localIP, _ := gxnet.GetLocalIP() localIP, _ := gxnet.GetLocalIP()
invokers := []protocol.Invoker{&MockInvoker{}, &MockInvoker{}, &MockInvoker{}} urlString := "dubbo://" + localIP + "/com.foo.BarService"
dubboURL, _ := common.NewURL(urlString)
mockInvoker1 := NewMockInvoker(dubboURL, 1)
mockInvoker2 := NewMockInvoker(dubboURL, 1)
mockInvoker3 := NewMockInvoker(dubboURL, 1)
invokers := []protocol.Invoker{mockInvoker1, mockInvoker2, mockInvoker3}
inv := &invocation.RPCInvocation{} inv := &invocation.RPCInvocation{}
rule := base64.URLEncoding.EncodeToString([]byte("host = " + localIP + " => " + " host = " + localIP)) rule := base64.URLEncoding.EncodeToString([]byte("host = " + localIP + " => " + " host = " + localIP))
curl, _ := common.NewURL("consumer://" + localIP + "/com.foo.BarService") curl, _ := common.NewURL("consumer://" + localIP + "/com.foo.BarService")
router, _ := NewConditionRouterFactory().Router(getRouteUrl(rule)) router, _ := newConditionRouterFactory().NewRouter(getRouteUrl(rule))
fileredInvokers := router.(*ConditionRouter).Route(invokers, curl, inv) fileredInvokers := router.(*ConditionRouter).Route(invokers, &curl, inv)
assert.Equal(t, invokers, fileredInvokers) assert.Equal(t, invokers, fileredInvokers)
} }
...@@ -254,8 +259,8 @@ func TestRoute_HostFilter(t *testing.T) { ...@@ -254,8 +259,8 @@ func TestRoute_HostFilter(t *testing.T) {
inv := &invocation.RPCInvocation{} inv := &invocation.RPCInvocation{}
rule := base64.URLEncoding.EncodeToString([]byte("host = " + localIP + " => " + " host = " + localIP)) rule := base64.URLEncoding.EncodeToString([]byte("host = " + localIP + " => " + " host = " + localIP))
curl, _ := common.NewURL("consumer://" + localIP + "/com.foo.BarService") curl, _ := common.NewURL("consumer://" + localIP + "/com.foo.BarService")
router, _ := NewConditionRouterFactory().Router(getRouteUrl(rule)) router, _ := newConditionRouterFactory().NewRouter(getRouteUrl(rule))
fileredInvokers := router.(*ConditionRouter).Route(invokers, curl, inv) fileredInvokers := router.(*ConditionRouter).Route(invokers, &curl, inv)
assert.Equal(t, 2, len(fileredInvokers)) assert.Equal(t, 2, len(fileredInvokers))
assert.Equal(t, invoker2, fileredInvokers[0]) assert.Equal(t, invoker2, fileredInvokers[0])
assert.Equal(t, invoker3, fileredInvokers[1]) assert.Equal(t, invoker3, fileredInvokers[1])
...@@ -273,8 +278,8 @@ func TestRoute_Empty_HostFilter(t *testing.T) { ...@@ -273,8 +278,8 @@ func TestRoute_Empty_HostFilter(t *testing.T) {
inv := &invocation.RPCInvocation{} inv := &invocation.RPCInvocation{}
rule := base64.URLEncoding.EncodeToString([]byte(" => " + " host = " + localIP)) rule := base64.URLEncoding.EncodeToString([]byte(" => " + " host = " + localIP))
curl, _ := common.NewURL("consumer://" + localIP + "/com.foo.BarService") curl, _ := common.NewURL("consumer://" + localIP + "/com.foo.BarService")
router, _ := NewConditionRouterFactory().Router(getRouteUrl(rule)) router, _ := newConditionRouterFactory().NewRouter(getRouteUrl(rule))
fileredInvokers := router.(*ConditionRouter).Route(invokers, curl, inv) fileredInvokers := router.(*ConditionRouter).Route(invokers, &curl, inv)
assert.Equal(t, 2, len(fileredInvokers)) assert.Equal(t, 2, len(fileredInvokers))
assert.Equal(t, invoker2, fileredInvokers[0]) assert.Equal(t, invoker2, fileredInvokers[0])
assert.Equal(t, invoker3, fileredInvokers[1]) assert.Equal(t, invoker3, fileredInvokers[1])
...@@ -292,8 +297,8 @@ func TestRoute_False_HostFilter(t *testing.T) { ...@@ -292,8 +297,8 @@ func TestRoute_False_HostFilter(t *testing.T) {
inv := &invocation.RPCInvocation{} inv := &invocation.RPCInvocation{}
rule := base64.URLEncoding.EncodeToString([]byte("true => " + " host = " + localIP)) rule := base64.URLEncoding.EncodeToString([]byte("true => " + " host = " + localIP))
curl, _ := common.NewURL("consumer://" + localIP + "/com.foo.BarService") curl, _ := common.NewURL("consumer://" + localIP + "/com.foo.BarService")
router, _ := NewConditionRouterFactory().Router(getRouteUrl(rule)) router, _ := newConditionRouterFactory().NewRouter(getRouteUrl(rule))
fileredInvokers := router.(*ConditionRouter).Route(invokers, curl, inv) fileredInvokers := router.(*ConditionRouter).Route(invokers, &curl, inv)
assert.Equal(t, 2, len(fileredInvokers)) assert.Equal(t, 2, len(fileredInvokers))
assert.Equal(t, invoker2, fileredInvokers[0]) assert.Equal(t, invoker2, fileredInvokers[0])
assert.Equal(t, invoker3, fileredInvokers[1]) assert.Equal(t, invoker3, fileredInvokers[1])
...@@ -311,8 +316,8 @@ func TestRoute_Placeholder(t *testing.T) { ...@@ -311,8 +316,8 @@ func TestRoute_Placeholder(t *testing.T) {
inv := &invocation.RPCInvocation{} inv := &invocation.RPCInvocation{}
rule := base64.URLEncoding.EncodeToString([]byte("host = " + localIP + " => " + " host = $host")) rule := base64.URLEncoding.EncodeToString([]byte("host = " + localIP + " => " + " host = $host"))
curl, _ := common.NewURL("consumer://" + localIP + "/com.foo.BarService") curl, _ := common.NewURL("consumer://" + localIP + "/com.foo.BarService")
router, _ := NewConditionRouterFactory().Router(getRouteUrl(rule)) router, _ := newConditionRouterFactory().NewRouter(getRouteUrl(rule))
fileredInvokers := router.(*ConditionRouter).Route(invokers, curl, inv) fileredInvokers := router.(*ConditionRouter).Route(invokers, &curl, inv)
assert.Equal(t, 2, len(fileredInvokers)) assert.Equal(t, 2, len(fileredInvokers))
assert.Equal(t, invoker2, fileredInvokers[0]) assert.Equal(t, invoker2, fileredInvokers[0])
assert.Equal(t, invoker3, fileredInvokers[1]) assert.Equal(t, invoker3, fileredInvokers[1])
...@@ -330,8 +335,8 @@ func TestRoute_NoForce(t *testing.T) { ...@@ -330,8 +335,8 @@ func TestRoute_NoForce(t *testing.T) {
inv := &invocation.RPCInvocation{} inv := &invocation.RPCInvocation{}
rule := base64.URLEncoding.EncodeToString([]byte("host = " + localIP + " => " + " host = 1.2.3.4")) rule := base64.URLEncoding.EncodeToString([]byte("host = " + localIP + " => " + " host = 1.2.3.4"))
curl, _ := common.NewURL("consumer://" + localIP + "/com.foo.BarService") curl, _ := common.NewURL("consumer://" + localIP + "/com.foo.BarService")
router, _ := NewConditionRouterFactory().Router(getRouteUrlWithNoForce(rule)) router, _ := newConditionRouterFactory().NewRouter(getRouteUrlWithNoForce(rule))
fileredInvokers := router.(*ConditionRouter).Route(invokers, curl, inv) fileredInvokers := router.(*ConditionRouter).Route(invokers, &curl, inv)
assert.Equal(t, invokers, fileredInvokers) assert.Equal(t, invokers, fileredInvokers)
} }
...@@ -347,7 +352,17 @@ func TestRoute_Force(t *testing.T) { ...@@ -347,7 +352,17 @@ func TestRoute_Force(t *testing.T) {
inv := &invocation.RPCInvocation{} inv := &invocation.RPCInvocation{}
rule := base64.URLEncoding.EncodeToString([]byte("host = " + localIP + " => " + " host = 1.2.3.4")) rule := base64.URLEncoding.EncodeToString([]byte("host = " + localIP + " => " + " host = 1.2.3.4"))
curl, _ := common.NewURL("consumer://" + localIP + "/com.foo.BarService") curl, _ := common.NewURL("consumer://" + localIP + "/com.foo.BarService")
router, _ := NewConditionRouterFactory().Router(getRouteUrlWithForce(rule, "true")) router, _ := newConditionRouterFactory().NewRouter(getRouteUrlWithForce(rule, "true"))
fileredInvokers := router.(*ConditionRouter).Route(invokers, curl, inv) fileredInvokers := router.(*ConditionRouter).Route(invokers, &curl, inv)
assert.Equal(t, 0, len(fileredInvokers)) assert.Equal(t, 0, len(fileredInvokers))
} }
func TestNewConditionRouterFactory(t *testing.T) {
factory := newConditionRouterFactory()
assert.NotNil(t, factory)
}
func TestNewAppRouterFactory(t *testing.T) {
factory := newAppRouterFactory()
assert.NotNil(t, factory)
}
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment