Skip to content
Snippets Groups Projects
Commit 8f8642e1 authored by aliiohs's avatar aliiohs
Browse files

Merge remote-tracking branch 'remotes/upstream/develop' into feature/addCommentFoDirectory

# Conflicts:
#	registry/directory/directory.go
parents 5635b9a6 68024040
No related branches found
No related tags found
No related merge requests found
Showing
with 626 additions and 59 deletions
language: go
dist: trusty
sudo: required
# define the dependence env
language: go
os:
- linux
go:
- "1.13"
services:
- docker
env:
- GO111MODULE=on
install: true
# define ci-stage
script:
# license-check
- echo 'start license check'
- go fmt ./... && [[ -z `git status -s` ]]
- sh before_validate_license.sh
- chmod u+x /tmp/tools/license/license-header-checker
- /tmp/tools/license/license-header-checker -v -a -r -i vendor /tmp/tools/license/license.txt . go && [[ -z `git status -s` ]]
# unit-test
- echo 'start unit-test'
- chmod u+x before_ut.sh && ./before_ut.sh
- go mod vendor && go test ./... -coverprofile=coverage.txt -covermode=atomic
# integrate-test
- echo 'start integrate-test'
# start zookeeper registry insecure listen in [:]:2181
- docker run -d --network host zookeeper
- ROOTDIR=$(pwd)
- cd ./test/integrate/dubbo/go-client && docker build . -t ci-consumer --build-arg PR_ORIGIN_REPO=${TRAVIS_PULL_REQUEST_SLUG} --build-arg PR_ORIGIN_COMMITID=${TRAVIS_PULL_REQUEST_SHA} && cd $ROOTDIR
- cd ./test/integrate/dubbo/go-server && docker build . -t ci-provider --build-arg PR_ORIGIN_REPO=${TRAVIS_PULL_REQUEST_SLUG} --build-arg PR_ORIGIN_COMMITID=${TRAVIS_PULL_REQUEST_SHA} && cd $ROOTDIR
- docker run -d --network host ci-provider
- docker run -it --network host ci-consumer
# another registry instance, start it by dep
# start etcd registry insecure listen in [:]:2379
#- docker run -d --network host k8s.gcr.io/etcd:3.3.10 etcd
# start consul registry insecure listen in [:]:8500
#- docker run -d --network host consul
# start nacos registry insecure listen in [:]:8848
#- docker run -d --network host nacos/nacos-server:latest
after_success:
- bash <(curl -s https://codecov.io/bash)
notifications:
webhooks: https://oapi.dingtalk.com/robot/send?access_token=f5d6237f2c79db584e75604f7f88db1ce1673c8c0e98451217b28fde791e1d4f
\ No newline at end of file
webhooks: https://oapi.dingtalk.com/robot/send?access_token=f5d6237f2c79db584e75604f7f88db1ce1673c8c0e98451217b28fde791e1d4f
......@@ -30,7 +30,7 @@ Apache License, Version 2.0
Both extension module and layered project architecture is according to Apache Dubbo (including protocol layer, registry layer, cluster layer, config layer and so on), the advantage of this arch is as following: you can implement these layered interfaces in your own way, override the default implementation of dubbo-go by calling 'extension.SetXXX' of extension, complete your special needs without modifying the source code. At the same time, you are welcome to contribute implementation of useful extension to the community.
![frame design](https://raw.githubusercontent.com/wiki/dubbo/dubbo-go/dubbo-go%E4%BB%A3%E7%A0%81%E5%88%86%E5%B1%82%E8%AE%BE%E8%AE%A1.png)
![dubbo go extend](./doc/pic/arch/dubbo-go-ext.png)
If you wanna know more about dubbo-go, please visit this reference [Project Architeture design](https://github.com/apache/dubbo-go/wiki/dubbo-go-V1.0-design)
......
......@@ -29,7 +29,7 @@ Apache License, Version 2.0
基于dubbo的extension模块和分层的代码设计(包括 protocol layer, registry layer, cluster layer, config 等等)。我们的目标是:你可以对这些分层接口进行新的实现,并通过调用 extension 模块的“ extension.SetXXX ”方法来覆盖 dubbo-go [同 go-for-apache-dubbo ]的默认实现,以完成自己的特殊需求而无需修改源代码。同时,欢迎你为社区贡献有用的拓展实现。
![框架设计](https://raw.githubusercontent.com/wiki/dubbo/dubbo-go/dubbo-go%E4%BB%A3%E7%A0%81%E5%88%86%E5%B1%82%E8%AE%BE%E8%AE%A1.png)
![dubbo go extend](./doc/pic/arch/dubbo-go-ext.png)
关于详细设计请阅读 [code layered design](https://github.com/apache/dubbo-go/wiki/dubbo-go-V1.0-design)
......@@ -108,6 +108,7 @@ Apache License, Version 2.0
* [For dubbo](https://github.com/apache/dubbo-go/pull/344)
* [For grpc](https://github.com/apache/dubbo-go/pull/397)
- 其他功能支持:
* 启动时检查
* 服务直连
......
#
# 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.
remoteLicenseCheckerPath="https://github.com/dubbogo/resources/raw/master/tools/license"
remoteLicenseCheckerName="license-header-checker"
remoteLicenseCheckerURL="${remoteLicenseCheckerPath}/${remoteLicenseCheckerName}"
remoteLicenseName="license.txt"
remoteLicenseURL="${remoteLicenseCheckerPath}/${remoteLicenseName}"
licensePath="/tmp/tools/license"
mkdir -p ${licensePath}
wget -P "${licensePath}" ${remoteLicenseCheckerURL}
wget -P "${licensePath}" ${remoteLicenseURL}
......@@ -27,7 +27,9 @@ import (
"strconv"
"strings"
)
import (
gxsort "github.com/dubbogo/gost/sort"
)
import (
"github.com/apache/dubbo-go/cluster"
"github.com/apache/dubbo-go/common/constant"
......@@ -40,7 +42,7 @@ const (
ConsistentHash = "consistenthash"
// HashNodes ...
HashNodes = "hash.nodes"
// HashArguments ...
// HashArguments key of hash arguments in url
HashArguments = "hash.arguments"
)
......@@ -53,16 +55,16 @@ func init() {
extension.SetLoadbalance(ConsistentHash, NewConsistentHashLoadBalance)
}
// ConsistentHashLoadBalance ...
// ConsistentHashLoadBalance implementation of load balancing: using consistent hashing
type ConsistentHashLoadBalance struct {
}
// NewConsistentHashLoadBalance ...
// NewConsistentHashLoadBalance creates NewConsistentHashLoadBalance
func NewConsistentHashLoadBalance() cluster.LoadBalance {
return &ConsistentHashLoadBalance{}
}
// Select ...
// Select gets invoker based on load balancing strategy
func (lb *ConsistentHashLoadBalance) Select(invokers []protocol.Invoker, invocation protocol.Invocation) protocol.Invoker {
methodName := invocation.MethodName()
key := invokers[0].GetUrl().ServiceKey() + "." + methodName
......@@ -85,27 +87,12 @@ func (lb *ConsistentHashLoadBalance) Select(invokers []protocol.Invoker, invocat
return selector.Select(invocation)
}
// Uint32Slice ...
type Uint32Slice []uint32
func (s Uint32Slice) Len() int {
return len(s)
}
func (s Uint32Slice) Less(i, j int) bool {
return s[i] < s[j]
}
func (s Uint32Slice) Swap(i, j int) {
s[i], s[j] = s[j], s[i]
}
// ConsistentHashSelector ...
// ConsistentHashSelector implementation of Selector:get invoker based on load balancing strategy
type ConsistentHashSelector struct {
hashCode uint32
replicaNum int
virtualInvokers map[uint32]protocol.Invoker
keys Uint32Slice
keys gxsort.Uint32Slice
argumentIndex []int
}
......@@ -141,7 +128,7 @@ func newConsistentHashSelector(invokers []protocol.Invoker, methodName string,
return selector
}
// Select ...
// Select gets invoker based on load balancing strategy
func (c *ConsistentHashSelector) Select(invocation protocol.Invocation) protocol.Invoker {
key := c.toKey(invocation.Arguments())
digest := md5.Sum([]byte(key))
......
......@@ -113,7 +113,7 @@ conditions:
assert.Nil(t, err)
assert.NotNil(t, appRouter)
rule, err := Parse(testYML)
rule, err := getRule(testYML)
assert.Nil(t, err)
appRouter.generateConditions(rule)
......
......@@ -44,7 +44,7 @@ type FileConditionRouter struct {
// NewFileConditionRouter Create file condition router instance with content ( from config file)
func NewFileConditionRouter(content []byte) (*FileConditionRouter, error) {
fileRouter := &FileConditionRouter{}
rule, err := Parse(string(content))
rule, err := getRule(string(content))
if err != nil {
return nil, perrors.Errorf("yaml.Unmarshal() failed , error:%v", perrors.WithStack(err))
}
......
......@@ -102,7 +102,7 @@ func (l *listenableRouter) Process(event *config_center.ConfigChangeEvent) {
return
}
routerRule, err := Parse(content)
routerRule, err := getRule(content)
if err != nil {
logger.Errorf("Parse condition router rule fail,error:[%s] ", err)
return
......
......@@ -27,7 +27,6 @@ import (
)
import (
matcher "github.com/apache/dubbo-go/cluster/router/match"
"github.com/apache/dubbo-go/common"
"github.com/apache/dubbo-go/common/constant"
"github.com/apache/dubbo-go/common/logger"
......@@ -301,7 +300,7 @@ func (pair MatchPair) isMatch(value string, param *common.URL) bool {
if !pair.Matches.Empty() && pair.Mismatches.Empty() {
for match := range pair.Matches.Items {
if matcher.IsMatchGlobalPattern(match.(string), value, param) {
if isMatchGlobalPattern(match.(string), value, param) {
return true
}
}
......@@ -310,7 +309,7 @@ func (pair MatchPair) isMatch(value string, param *common.URL) bool {
if !pair.Mismatches.Empty() && pair.Matches.Empty() {
for mismatch := range pair.Mismatches.Items {
if matcher.IsMatchGlobalPattern(mismatch.(string), value, param) {
if isMatchGlobalPattern(mismatch.(string), value, param) {
return false
}
}
......@@ -319,12 +318,12 @@ func (pair MatchPair) isMatch(value string, param *common.URL) bool {
if !pair.Mismatches.Empty() && !pair.Matches.Empty() {
//when both mismatches and matches contain the same value, then using mismatches first
for mismatch := range pair.Mismatches.Items {
if matcher.IsMatchGlobalPattern(mismatch.(string), value, param) {
if isMatchGlobalPattern(mismatch.(string), value, param) {
return false
}
}
for match := range pair.Matches.Items {
if matcher.IsMatchGlobalPattern(match.(string), value, param) {
if isMatchGlobalPattern(match.(string), value, param) {
return true
}
}
......
......@@ -18,11 +18,17 @@
package condition
import (
"gopkg.in/yaml.v2"
"strings"
)
import (
gxstrings "github.com/dubbogo/gost/strings"
)
import (
"github.com/apache/dubbo-go/cluster/router"
"github.com/apache/dubbo-go/common"
"github.com/apache/dubbo-go/common/yaml"
)
// RouterRule RouterRule config read from config file or config center
......@@ -44,9 +50,9 @@ type RouterRule struct {
* =>
* 1.1.1.1
*/
func Parse(rawRule string) (*RouterRule, error) {
func getRule(rawRule string) (*RouterRule, error) {
r := &RouterRule{}
err := yaml.Unmarshal([]byte(rawRule), r)
err := yaml.UnmarshalYML([]byte(rawRule), r)
if err != nil {
return r, err
}
......@@ -57,3 +63,11 @@ func Parse(rawRule string) (*RouterRule, error) {
return r, nil
}
// isMatchGlobalPattern Match value to param content by pattern
func isMatchGlobalPattern(pattern string, value string, param *common.URL) bool {
if param != nil && strings.HasPrefix(pattern, "$") {
pattern = param.GetRawParam(pattern[1:])
}
return gxstrings.IsMatchPattern(pattern, value)
}
......@@ -20,11 +20,16 @@ package condition
import (
"testing"
)
import (
"github.com/stretchr/testify/assert"
)
func TestParse(t *testing.T) {
import (
"github.com/apache/dubbo-go/common"
)
func TestGetRule(t *testing.T) {
testyml := `
scope: application
runtime: true
......@@ -36,7 +41,7 @@ conditions:
ip=127.0.0.1
=>
1.1.1.1`
rule, e := Parse(testyml)
rule, e := getRule(testyml)
assert.Nil(t, e)
assert.NotNil(t, rule)
......@@ -50,3 +55,8 @@ conditions:
assert.Equal(t, false, rule.Dynamic)
assert.Equal(t, "", rule.Key)
}
func TestIsMatchGlobPattern(t *testing.T) {
url, _ := common.NewURL("dubbo://localhost:8080/Foo?key=v*e")
assert.Equal(t, true, isMatchGlobalPattern("$key", "value", &url))
}
......@@ -31,7 +31,7 @@ type RouterFactory interface {
}
// RouterFactory Router create factory use for parse config file
type FIleRouterFactory interface {
type FileRouterFactory interface {
// NewFileRouters Create file router with config file
NewFileRouter([]byte) (Router, error)
}
......
/*
* 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 tag
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.TagRouterName, NewTagRouterFactory)
}
type tagRouterFactory struct{}
// NewTagRouterFactory create a tagRouterFactory
func NewTagRouterFactory() router.RouterFactory {
return &tagRouterFactory{}
}
// NewRouter create a tagRouter by tagRouterFactory with a url
// The url contains router configuration information
func (c *tagRouterFactory) NewRouter(url *common.URL) (router.Router, error) {
return NewTagRouter(url)
}
// NewFileRouter create a tagRouter by profile content
func (c *tagRouterFactory) NewFileRouter(content []byte) (router.Router, error) {
return NewFileTagRouter(content)
}
......@@ -15,7 +15,7 @@
* limitations under the License.
*/
package match
package tag
import (
"testing"
......@@ -29,18 +29,11 @@ import (
"github.com/apache/dubbo-go/common"
)
func TestIsMatchInternalPattern(t *testing.T) {
assert.Equal(t, true, isMatchInternalPattern("*", "value"))
assert.Equal(t, true, isMatchInternalPattern("", ""))
assert.Equal(t, false, isMatchInternalPattern("", "value"))
assert.Equal(t, true, isMatchInternalPattern("value", "value"))
assert.Equal(t, true, isMatchInternalPattern("v*", "value"))
assert.Equal(t, true, isMatchInternalPattern("*ue", "value"))
assert.Equal(t, true, isMatchInternalPattern("*e", "value"))
assert.Equal(t, true, isMatchInternalPattern("v*e", "value"))
}
func TestIsMatchGlobPattern(t *testing.T) {
url, _ := common.NewURL("dubbo://localhost:8080/Foo?key=v*e")
assert.Equal(t, true, IsMatchGlobalPattern("$key", "value", &url))
func TestTagRouterFactory_NewRouter(t *testing.T) {
u1, err := common.NewURL("dubbo://127.0.0.1:20000/com.ikurento.user.UserProvider?interface=com.ikurento.user.UserProvider&group=&version=2.6.0&enabled=true")
assert.Nil(t, err)
factory := NewTagRouterFactory()
tagRouter, e := factory.NewRouter(&u1)
assert.Nil(t, e)
assert.NotNil(t, tagRouter)
}
/*
* 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 tag
import (
"net/url"
"strconv"
"sync"
)
import (
perrors "github.com/pkg/errors"
)
import (
"github.com/apache/dubbo-go/common"
"github.com/apache/dubbo-go/common/constant"
"github.com/apache/dubbo-go/protocol"
)
// FileTagRouter Use for parse config file of Tag router
type FileTagRouter struct {
parseOnce sync.Once
router *tagRouter
routerRule *RouterRule
url *common.URL
force bool
}
// NewFileTagRouter Create file tag router instance with content ( from config file)
func NewFileTagRouter(content []byte) (*FileTagRouter, error) {
fileRouter := &FileTagRouter{}
rule, err := getRule(string(content))
if err != nil {
return nil, perrors.Errorf("yaml.Unmarshal() failed , error:%v", perrors.WithStack(err))
}
fileRouter.routerRule = rule
url := fileRouter.URL()
fileRouter.router, err = NewTagRouter(&url)
return fileRouter, err
}
// URL Return URL in file tag router n
func (f *FileTagRouter) URL() common.URL {
f.parseOnce.Do(func() {
routerRule := f.routerRule
f.url = common.NewURLWithOptions(
common.WithProtocol(constant.TAG_ROUTE_PROTOCOL),
common.WithParams(url.Values{}),
common.WithParamsValue(constant.ForceUseTag, strconv.FormatBool(routerRule.Force)),
common.WithParamsValue(constant.RouterPriority, strconv.Itoa(routerRule.Priority)),
common.WithParamsValue(constant.ROUTER_KEY, constant.TAG_ROUTE_PROTOCOL))
})
return *f.url
}
// Priority Return Priority in listenable router
func (f *FileTagRouter) Priority() int64 {
return f.router.priority
}
func (f *FileTagRouter) Route(invokers []protocol.Invoker, url *common.URL, invocation protocol.Invocation) []protocol.Invoker {
if len(invokers) == 0 {
return invokers
}
return f.Route(invokers, url, invocation)
}
/*
* 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 tag
import (
"testing"
)
import (
"github.com/stretchr/testify/assert"
)
import (
"github.com/apache/dubbo-go/common/constant"
)
func TestNewFileTagRouter(t *testing.T) {
router, e := NewFileTagRouter([]byte(`priority: 100
force: true`))
assert.Nil(t, e)
assert.NotNil(t, router)
assert.Equal(t, 100, router.routerRule.Priority)
assert.Equal(t, true, router.routerRule.Force)
}
func TestFileTagRouter_URL(t *testing.T) {
router, e := NewFileTagRouter([]byte(`priority: 100
force: true`))
assert.Nil(t, e)
assert.NotNil(t, router)
url := router.URL()
assert.NotNil(t, url)
force := url.GetParam(constant.ForceUseTag, "false")
priority := url.GetParam(constant.RouterPriority, "0")
assert.Equal(t, "true", force)
assert.Equal(t, "100", priority)
}
func TestFileTagRouter_Priority(t *testing.T) {
router, e := NewFileTagRouter([]byte(`priority: 100
force: true`))
assert.Nil(t, e)
assert.NotNil(t, router)
priority := router.Priority()
assert.Equal(t, int64(100), 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 tag
import (
"github.com/apache/dubbo-go/cluster/router"
"github.com/apache/dubbo-go/common/yaml"
)
// RouterRule RouterRule config read from config file or config center
type RouterRule struct {
router.BaseRouterRule `yaml:",inline""`
}
func getRule(rawRule string) (*RouterRule, error) {
r := &RouterRule{}
err := yaml.UnmarshalYML([]byte(rawRule), r)
if err != nil {
return r, err
}
r.RawRule = rawRule
return r, 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 tag
import (
"testing"
)
import (
"github.com/stretchr/testify/assert"
)
func TestGetRule(t *testing.T) {
yml := `
scope: application
runtime: true
force: true
`
rule, e := getRule(yml)
assert.Nil(t, e)
assert.NotNil(t, rule)
assert.Equal(t, true, rule.Force)
assert.Equal(t, true, rule.Runtime)
assert.Equal(t, "application", rule.Scope)
}
/*
* 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 tag
import (
"strconv"
)
import (
perrors "github.com/pkg/errors"
)
import (
"github.com/apache/dubbo-go/common"
"github.com/apache/dubbo-go/common/constant"
"github.com/apache/dubbo-go/protocol"
)
type tagRouter struct {
url *common.URL
enabled bool
priority int64
}
func NewTagRouter(url *common.URL) (*tagRouter, error) {
if url == nil {
return nil, perrors.Errorf("Illegal route URL!")
}
return &tagRouter{
url: url,
enabled: url.GetParamBool(constant.RouterEnabled, true),
priority: url.GetParamInt(constant.RouterPriority, 0),
}, nil
}
func (c *tagRouter) isEnabled() bool {
return c.enabled
}
func (c *tagRouter) Route(invokers []protocol.Invoker, url *common.URL, invocation protocol.Invocation) []protocol.Invoker {
if !c.isEnabled() {
return invokers
}
if len(invokers) == 0 {
return invokers
}
return filterUsingStaticTag(invokers, url, invocation)
}
func (c *tagRouter) URL() common.URL {
return *c.url
}
func (c *tagRouter) Priority() int64 {
return c.priority
}
func filterUsingStaticTag(invokers []protocol.Invoker, url *common.URL, invocation protocol.Invocation) []protocol.Invoker {
if tag, ok := invocation.Attachments()[constant.Tagkey]; ok {
result := make([]protocol.Invoker, 0, 8)
for _, v := range invokers {
if v.GetUrl().GetParam(constant.Tagkey, "") == tag {
result = append(result, v)
}
}
if len(result) == 0 && !isForceUseTag(url, invocation) {
return invokers
}
return result
}
return invokers
}
func isForceUseTag(url *common.URL, invocation protocol.Invocation) bool {
if b, e := strconv.ParseBool(invocation.AttachmentsByKey(constant.ForceUseTag, url.GetParam(constant.ForceUseTag, "false"))); e == nil {
return b
}
return false
}
/*
* 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 tag
import (
"context"
"testing"
)
import (
"github.com/stretchr/testify/assert"
)
import (
"github.com/apache/dubbo-go/common"
"github.com/apache/dubbo-go/protocol"
"github.com/apache/dubbo-go/protocol/invocation"
)
// MockInvoker is only mock the Invoker to support test tagRouter
type MockInvoker struct {
url common.URL
available bool
destroyed bool
successCount int
}
func NewMockInvoker(url common.URL) *MockInvoker {
return &MockInvoker{
url: url,
available: true,
destroyed: false,
successCount: 0,
}
}
func (bi *MockInvoker) GetUrl() common.URL {
return bi.url
}
func (bi *MockInvoker) IsAvailable() bool {
return bi.available
}
func (bi *MockInvoker) IsDestroyed() bool {
return bi.destroyed
}
func (bi *MockInvoker) Invoke(_ context.Context, _ protocol.Invocation) protocol.Result {
bi.successCount++
result := &protocol.RPCResult{Err: nil}
return result
}
func (bi *MockInvoker) Destroy() {
bi.destroyed = true
bi.available = false
}
func TestTagRouter_Priority(t *testing.T) {
u1, err := common.NewURL("dubbo://127.0.0.1:20000/com.ikurento.user.UserConsumer?interface=com.ikurento.user.UserConsumer&group=&version=2.6.0&enabled=true&dubbo.force.tag=true")
assert.Nil(t, err)
tagRouter, e := NewTagRouter(&u1)
assert.Nil(t, e)
p := tagRouter.Priority()
assert.Equal(t, int64(0), p)
}
func TestTagRouter_Route_force(t *testing.T) {
u1, e1 := common.NewURL("dubbo://127.0.0.1:20000/com.ikurento.user.UserConsumer?interface=com.ikurento.user.UserConsumer&group=&version=2.6.0&enabled=true&dubbo.force.tag=true")
assert.Nil(t, e1)
tagRouter, e := NewTagRouter(&u1)
assert.Nil(t, e)
u2, e2 := common.NewURL("dubbo://127.0.0.1:20000/com.ikurento.user.UserProvider?interface=com.ikurento.user.UserProvider&group=&version=2.6.0&enabled=true&dubbo.tag=hangzhou")
u3, e3 := common.NewURL("dubbo://127.0.0.1:20000/com.ikurento.user.UserProvider?interface=com.ikurento.user.UserProvider&group=&version=2.6.0&enabled=true&dubbo.tag=shanghai")
u4, e4 := common.NewURL("dubbo://127.0.0.1:20000/com.ikurento.user.UserProvider?interface=com.ikurento.user.UserProvider&group=&version=2.6.0&enabled=true&dubbo.tag=beijing")
assert.Nil(t, e2)
assert.Nil(t, e3)
assert.Nil(t, e4)
inv2 := NewMockInvoker(u2)
inv3 := NewMockInvoker(u3)
inv4 := NewMockInvoker(u4)
var invokers []protocol.Invoker
invokers = append(invokers, inv2, inv3, inv4)
inv := &invocation.RPCInvocation{}
inv.SetAttachments("dubbo.tag", "hangzhou")
invRst1 := tagRouter.Route(invokers, &u1, inv)
assert.Equal(t, 1, len(invRst1))
assert.Equal(t, "hangzhou", invRst1[0].GetUrl().GetParam("dubbo.tag", ""))
inv.SetAttachments("dubbo.tag", "guangzhou")
invRst2 := tagRouter.Route(invokers, &u1, inv)
assert.Equal(t, 0, len(invRst2))
inv.SetAttachments("dubbo.force.tag", "false")
inv.SetAttachments("dubbo.tag", "guangzhou")
invRst3 := tagRouter.Route(invokers, &u1, inv)
assert.Equal(t, 3, len(invRst3))
}
func TestTagRouter_Route_noForce(t *testing.T) {
u1, e1 := common.NewURL("dubbo://127.0.0.1:20000/com.ikurento.user.UserConsumer?interface=com.ikurento.user.UserConsumer&group=&version=2.6.0&enabled=true")
assert.Nil(t, e1)
tagRouter, e := NewTagRouter(&u1)
assert.Nil(t, e)
u2, e2 := common.NewURL("dubbo://127.0.0.1:20000/com.ikurento.user.UserProvider?interface=com.ikurento.user.UserProvider&group=&version=2.6.0&enabled=true&dubbo.tag=hangzhou")
u3, e3 := common.NewURL("dubbo://127.0.0.1:20000/com.ikurento.user.UserProvider?interface=com.ikurento.user.UserProvider&group=&version=2.6.0&enabled=true&dubbo.tag=shanghai")
u4, e4 := common.NewURL("dubbo://127.0.0.1:20000/com.ikurento.user.UserProvider?interface=com.ikurento.user.UserProvider&group=&version=2.6.0&enabled=true&dubbo.tag=beijing")
assert.Nil(t, e2)
assert.Nil(t, e3)
assert.Nil(t, e4)
inv2 := NewMockInvoker(u2)
inv3 := NewMockInvoker(u3)
inv4 := NewMockInvoker(u4)
var invokers []protocol.Invoker
invokers = append(invokers, inv2, inv3, inv4)
inv := &invocation.RPCInvocation{}
inv.SetAttachments("dubbo.tag", "hangzhou")
invRst := tagRouter.Route(invokers, &u1, inv)
assert.Equal(t, 1, len(invRst))
assert.Equal(t, "hangzhou", invRst[0].GetUrl().GetParam("dubbo.tag", ""))
inv.SetAttachments("dubbo.tag", "guangzhou")
inv.SetAttachments("dubbo.force.tag", "true")
invRst1 := tagRouter.Route(invokers, &u1, inv)
assert.Equal(t, 0, len(invRst1))
inv.SetAttachments("dubbo.force.tag", "false")
invRst2 := tagRouter.Route(invokers, &u1, inv)
assert.Equal(t, 3, len(invRst2))
}
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