Skip to content

Commit

Permalink
Merge pull request apache#665 from watermelo/featrue/tagRouter
Browse files Browse the repository at this point in the history
Ftr: dynamic tag router
  • Loading branch information
AlexStocks authored Aug 6, 2020
2 parents 0b5e2f4 + a31a4e2 commit 5e377f4
Show file tree
Hide file tree
Showing 10 changed files with 733 additions and 22 deletions.
3 changes: 3 additions & 0 deletions before_ut.sh
Original file line number Diff line number Diff line change
Expand Up @@ -36,5 +36,8 @@ 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

mkdir -p cluster/router/tag/zookeeper-4unittest/contrib/fatjar
cp ${zkJar} cluster/router/tag/zookeeper-4unittest/contrib/fatjar

mkdir -p metadata/report/zookeeper/zookeeper-4unittest/contrib/fatjar
cp ${zkJar} metadata/report/zookeeper/zookeeper-4unittest/contrib/fatjar
2 changes: 1 addition & 1 deletion cluster/router/condition/app_router_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@ import (
)

import (
_ "github.com/apache/dubbo-go/config_center/zookeeper"
"github.com/stretchr/testify/assert"
)

Expand All @@ -34,6 +33,7 @@ import (
"github.com/apache/dubbo-go/common/constant"
"github.com/apache/dubbo-go/common/extension"
"github.com/apache/dubbo-go/config_center"
_ "github.com/apache/dubbo-go/config_center/zookeeper"
"github.com/apache/dubbo-go/remoting"
"github.com/apache/dubbo-go/remoting/zookeeper"
)
Expand Down
2 changes: 1 addition & 1 deletion cluster/router/condition/listenable_router.go
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ func newListenableRouter(url *common.URL, ruleKey string) (*AppRouter, error) {
return l, nil
}

// Process Process config change event , generate routers and set them to the listenableRouter instance
// Process Process config change event, generate routers and set them to the listenableRouter instance
func (l *listenableRouter) Process(event *config_center.ConfigChangeEvent) {
logger.Infof("Notification of condition rule, change type is:[%s] , raw rule is:[%v]", event.ConfigType, event.Value)
if remoting.EventTypeDel == event.ConfigType {
Expand Down
2 changes: 1 addition & 1 deletion cluster/router/tag/file.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ type FileTagRouter struct {
force bool
}

// NewFileTagRouter Create file tag router instance with content ( from config file)
// NewFileTagRouter Create file tag router instance with content (from config file)
func NewFileTagRouter(content []byte) (*FileTagRouter, error) {
fileRouter := &FileTagRouter{}
rule, err := getRule(string(content))
Expand Down
71 changes: 71 additions & 0 deletions cluster/router/tag/router_rule.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,27 @@ import (
"github.com/apache/dubbo-go/common/yaml"
)

/**
* %YAML1.2
* ---
* force: true
* runtime: false
* enabled: true
* priority: 1
* key: demo-provider
* tags:
* - name: tag1
* addresses: [ip1, ip2]
* - name: tag2
* addresses: [ip3, ip4]
* ...
*/
// RouterRule RouterRule config read from config file or config center
type RouterRule struct {
router.BaseRouterRule `yaml:",inline""`
Tags []Tag
addressToTagNames map[string][]string
tagNameToAddresses map[string][]string
}

func getRule(rawRule string) (*RouterRule, error) {
Expand All @@ -34,5 +52,58 @@ func getRule(rawRule string) (*RouterRule, error) {
return r, err
}
r.RawRule = rawRule
r.init()
return r, nil
}

func (t *RouterRule) init() {
t.addressToTagNames = make(map[string][]string, 8)
t.tagNameToAddresses = make(map[string][]string, 8)
for _, tag := range t.Tags {
for _, address := range tag.Addresses {
t.addressToTagNames[address] = append(t.addressToTagNames[address], tag.Name)
}
t.tagNameToAddresses[tag.Name] = tag.Addresses
}
}

func (t *RouterRule) getAddresses() []string {
var result = make([]string, 0, 8*len(t.Tags))
for _, tag := range t.Tags {
result = append(result, tag.Addresses...)
}
return result
}

func (t *RouterRule) getTagNames() []string {
var result = make([]string, 0, len(t.Tags))
for _, tag := range t.Tags {
result = append(result, tag.Name)
}
return result
}

func (t *RouterRule) hasTag(tag string) bool {
for _, t := range t.Tags {
if tag == t.Name {
return true
}
}
return false
}

func (t *RouterRule) getAddressToTagNames() map[string][]string {
return t.addressToTagNames
}

func (t *RouterRule) getTagNameToAddresses() map[string][]string {
return t.tagNameToAddresses
}

func (t *RouterRule) getTags() []Tag {
return t.Tags
}

func (t *RouterRule) setTags(tags []Tag) {
t.Tags = tags
}
55 changes: 46 additions & 9 deletions cluster/router/tag/router_rule_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,19 +22,56 @@ import (
)

import (
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/suite"
)

func TestGetRule(t *testing.T) {
type RuleTestSuite struct {
suite.Suite
rule *RouterRule
}

func (suite *RuleTestSuite) SetupTest() {
var err error
yml := `
scope: application
runtime: true
force: true
runtime: false
enabled: true
priority: 1
key: demo-provider
tags:
- name: tag1
addresses: [ip1, ip2]
- name: tag2
addresses: [ip3, ip4]
`
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)
suite.rule, err = getRule(yml)
suite.Nil(err)
}

func (suite *RuleTestSuite) TestGetRule() {
var err error
suite.Equal(true, suite.rule.Force)
suite.Equal(false, suite.rule.Runtime)
suite.Equal("application", suite.rule.Scope)
suite.Equal(1, suite.rule.Priority)
suite.Equal("demo-provider", suite.rule.Key)
suite.Nil(err)
}

func (suite *RuleTestSuite) TestGetTagNames() {
suite.Equal([]string{"tag1", "tag2"}, suite.rule.getTagNames())
}

func (suite *RuleTestSuite) TestGetAddresses() {
suite.Equal([]string{"ip1", "ip2", "ip3", "ip4"}, suite.rule.getAddresses())
}

func (suite *RuleTestSuite) TestHasTag() {
suite.Equal(true, suite.rule.hasTag("tag1"))
suite.Equal(false, suite.rule.hasTag("tag404"))
}

func TestRuleTestSuite(t *testing.T) {
suite.Run(t, new(RuleTestSuite))
}
39 changes: 39 additions & 0 deletions cluster/router/tag/tag.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
/*
* 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

type Tag struct {
Name string
Addresses []string
}

func (t *Tag) getName() string {
return t.Name
}

func (t *Tag) setName(name string) {
t.Name = name
}

func (t *Tag) getAddresses() []string {
return t.Addresses
}

func (t *Tag) setAddresses(addresses []string) {
t.Addresses = addresses
}
Loading

0 comments on commit 5e377f4

Please sign in to comment.