Skip to content
Snippets Groups Projects
Unverified Commit 2aafdeb0 authored by panty's avatar panty Committed by GitHub
Browse files

Merge pull request #662 from williamfeng323/feature/application-level-router

Ftr: Feature/application and service level router
parents 613cc6ed 5f02d537
No related branches found
No related tags found
No related merge requests found
Showing
with 429 additions and 55 deletions
......@@ -85,15 +85,21 @@ func (dir *BaseDirectory) SetRouters(urls []*common.URL) {
for _, url := range urls {
routerKey := url.GetParam(constant.ROUTER_KEY, "")
if len(routerKey) > 0 {
factory := extension.GetRouterFactory(url.Protocol)
r, err := factory.NewPriorityRouter(url)
if err != nil {
logger.Errorf("Create router fail. router key: %s, url:%s, error: %+v", routerKey, url.Service(), err)
return
if len(routerKey) == 0 {
continue
}
if url.Protocol == constant.CONDITION_ROUTE_PROTOCOL {
if !dir.isProperRouter(url) {
continue
}
routers = append(routers, r)
}
factory := extension.GetRouterFactory(url.Protocol)
r, err := factory.NewPriorityRouter(url)
if err != nil {
logger.Errorf("Create router fail. router key: %s, url:%s, error: %+v", routerKey, url.Service(), err)
return
}
routers = append(routers, r)
}
logger.Infof("Init file condition router success, size: %v", len(routers))
......@@ -104,6 +110,21 @@ func (dir *BaseDirectory) SetRouters(urls []*common.URL) {
rc.AddRouters(routers)
}
func (dir *BaseDirectory) isProperRouter(url *common.URL) bool {
app := url.GetParam(constant.APPLICATION_KEY, "")
serviceKey := dir.GetUrl().ServiceKey()
if serviceKey == "" {
serviceKey = dir.GetUrl().SubURL.ServiceKey()
}
if len(app) > 0 && app == dir.GetUrl().GetParam(constant.APPLICATION_KEY, "") {
return true
}
if url.ServiceKey() == serviceKey {
return true
}
return false
}
// Destroy Destroy
func (dir *BaseDirectory) Destroy(doDestroy func()) {
if dir.destroyed.CAS(false, true) {
......
......@@ -37,7 +37,7 @@ import (
var (
url, _ = common.NewURL(
fmt.Sprintf("dubbo://%s:%d/com.ikurento.user.UserProvider", constant.LOCAL_HOST_VALUE, constant.DEFAULT_PORT))
anyUrl, _ = common.NewURL(fmt.Sprintf("condition://%s/com.foo.BarService", constant.ANYHOST_VALUE))
anyURL, _ = common.NewURL(fmt.Sprintf("condition://%s/com.foo.BarService", constant.ANYHOST_VALUE))
)
func TestNewBaseDirectory(t *testing.T) {
......@@ -48,13 +48,17 @@ func TestNewBaseDirectory(t *testing.T) {
}
func TestBuildRouterChain(t *testing.T) {
directory := NewBaseDirectory(&url)
regURL := url
regURL.AddParam(constant.INTERFACE_KEY, "mock-app")
directory := NewBaseDirectory(&regURL)
assert.NotNil(t, directory)
localIP, _ := gxnet.GetLocalIP()
rule := base64.URLEncoding.EncodeToString([]byte("true => " + " host = " + localIP))
routeURL := getRouteUrl(rule)
routeURL := getRouteURL(rule, anyURL)
routeURL.AddParam(constant.INTERFACE_KEY, "mock-app")
routerURLs := make([]*common.URL, 0)
routerURLs = append(routerURLs, routeURL)
directory.SetRouters(routerURLs)
......@@ -63,9 +67,53 @@ func TestBuildRouterChain(t *testing.T) {
assert.NotNil(t, chain)
}
func getRouteUrl(rule string) *common.URL {
anyUrl.AddParam("rule", rule)
anyUrl.AddParam("force", "true")
anyUrl.AddParam(constant.ROUTER_KEY, "router")
return &url
func getRouteURL(rule string, u common.URL) *common.URL {
ru := u
ru.AddParam("rule", rule)
ru.AddParam("force", "true")
ru.AddParam(constant.ROUTER_KEY, "router")
return &ru
}
func TestIsProperRouter(t *testing.T) {
regURL := url
regURL.AddParam(constant.APPLICATION_KEY, "mock-app")
d := NewBaseDirectory(&regURL)
localIP, _ := gxnet.GetLocalIP()
rule := base64.URLEncoding.EncodeToString([]byte("true => " + " host = " + localIP))
routeURL := getRouteURL(rule, anyURL)
routeURL.AddParam(constant.APPLICATION_KEY, "mock-app")
rst := d.isProperRouter(routeURL)
assert.True(t, rst)
regURL.AddParam(constant.APPLICATION_KEY, "")
regURL.AddParam(constant.INTERFACE_KEY, "com.foo.BarService")
d = NewBaseDirectory(&regURL)
routeURL = getRouteURL(rule, anyURL)
routeURL.AddParam(constant.INTERFACE_KEY, "com.foo.BarService")
rst = d.isProperRouter(routeURL)
assert.True(t, rst)
regURL.AddParam(constant.APPLICATION_KEY, "")
regURL.AddParam(constant.INTERFACE_KEY, "")
d = NewBaseDirectory(&regURL)
routeURL = getRouteURL(rule, anyURL)
rst = d.isProperRouter(routeURL)
assert.True(t, rst)
regURL.SetParam(constant.APPLICATION_KEY, "")
regURL.SetParam(constant.INTERFACE_KEY, "")
d = NewBaseDirectory(&regURL)
routeURL = getRouteURL(rule, anyURL)
routeURL.AddParam(constant.APPLICATION_KEY, "mock-service")
rst = d.isProperRouter(routeURL)
assert.False(t, rst)
regURL.SetParam(constant.APPLICATION_KEY, "")
regURL.SetParam(constant.INTERFACE_KEY, "")
d = NewBaseDirectory(&regURL)
routeURL = getRouteURL(rule, anyURL)
routeURL.AddParam(constant.INTERFACE_KEY, "mock-service")
rst = d.isProperRouter(routeURL)
assert.False(t, rst)
}
......@@ -66,7 +66,9 @@ func TestNewRouterChain(t *testing.T) {
err = z.Create(path)
assert.NoError(t, err)
testyml := `enabled: true
testyml := `scope: application
key: mock-app
enabled: true
force: true
runtime: false
conditions:
......@@ -93,7 +95,7 @@ conditions:
assert.NotNil(t, appRouter)
assert.NotNil(t, appRouter.RouterRule())
rule := appRouter.RouterRule()
assert.Equal(t, "", rule.Scope)
assert.Equal(t, "application", rule.Scope)
assert.True(t, rule.Force)
assert.True(t, rule.Enabled)
assert.True(t, rule.Valid)
......@@ -101,7 +103,7 @@ conditions:
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, "mock-app", rule.Key)
}
func TestNewRouterChainURLNil(t *testing.T) {
......@@ -116,7 +118,9 @@ func TestRouterChainAddRouters(t *testing.T) {
err = z.Create(path)
assert.NoError(t, err)
testyml := `enabled: true
testyml := `scope: application
key: mock-app
enabled: true
force: true
runtime: false
conditions:
......@@ -182,7 +186,9 @@ func TestRouterChainRouteAppRouter(t *testing.T) {
err = z.Create(path)
assert.NoError(t, err)
testyml := `enabled: true
testyml := `scope: application
key: mock-app
enabled: true
force: true
runtime: false
conditions:
......
......@@ -52,7 +52,9 @@ var (
func TestNewAppRouter(t *testing.T) {
testYML := `enabled: true
testYML := `scope: application
key: mock-app
enabled: true
force: true
runtime: false
conditions:
......@@ -83,7 +85,7 @@ conditions:
assert.NotNil(t, appRouter)
assert.NotNil(t, appRouter.RouterRule())
rule := appRouter.RouterRule()
assert.Equal(t, "", rule.Scope)
assert.Equal(t, "application", rule.Scope)
assert.True(t, rule.Force)
assert.True(t, rule.Enabled)
assert.True(t, rule.Valid)
......@@ -91,13 +93,15 @@ conditions:
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, "mock-app", rule.Key)
assert.Equal(t, 0, rule.Priority)
}
func TestGenerateConditions(t *testing.T) {
testYML := `enabled: true
testYML := `scope: application
key: mock-app
enabled: true
force: true
runtime: false
conditions:
......@@ -135,7 +139,9 @@ conditions:
func TestProcess(t *testing.T) {
testYML := `enabled: true
testYML := `scope: application
key: mock-app
enabled: true
force: true
runtime: false
conditions:
......@@ -165,7 +171,8 @@ conditions:
assert.Equal(t, 1, len(appRouter.conditionRouters))
testNewYML := `
testNewYML := `scope: application
key: mock-app
enabled: true
force: true
runtime: false
......
......@@ -20,6 +20,7 @@ package condition
import (
"encoding/base64"
"net/url"
"regexp"
"strconv"
"strings"
"sync"
......@@ -71,11 +72,53 @@ func (f *FileConditionRouter) URL() common.URL {
common.WithParamsValue(constant.RouterPriority, strconv.Itoa(routerRule.Priority)),
common.WithParamsValue(constant.RULE_KEY, base64.URLEncoding.EncodeToString([]byte(rule))),
common.WithParamsValue(constant.ROUTER_KEY, constant.CONDITION_ROUTE_PROTOCOL),
common.WithParamsValue(constant.CATEGORY_KEY, constant.ROUTERS_CATEGORY))
common.WithParamsValue(constant.CATEGORY_KEY, constant.ROUTERS_CATEGORY),
)
if routerRule.Scope == constant.RouterApplicationScope {
f.url.AddParam(constant.APPLICATION_KEY, routerRule.Key)
return
}
grp, srv, ver, e := parseServiceRouterKey(routerRule.Key)
if e != nil {
return
}
if len(grp) > 0 {
f.url.AddParam(constant.GROUP_KEY, grp)
}
if len(ver) > 0 {
f.url.AddParam(constant.VERSION_KEY, ver)
}
if len(srv) > 0 {
f.url.AddParam(constant.INTERFACE_KEY, srv)
}
})
return f.url
}
// The input value must follow [{group}/]{service}[:{version}] pattern
// the returning strings are representing group, service, version respectively.
// input: mock-group/mock-service:1.0.0 ==> "mock-group", "mock-service", "1.0.0"
// input: mock-group/mock-service ==> "mock-group", "mock-service", ""
// input: mock-service:1.0.0 ==> "", "mock-service", "1.0.0"
// For more samples, please refer to unit test.
func parseServiceRouterKey(key string) (string, string, string, error) {
if len(strings.TrimSpace(key)) == 0 {
return "", "", "", nil
}
reg := regexp.MustCompile(`(.*/{1})?([^:/]+)(:{1}[^:]*)?`)
strs := reg.FindAllStringSubmatch(key, -1)
if strs == nil || len(strs) > 1 {
return "", "", "", perrors.Errorf("Invalid key, service key must follow [{group}/]{service}[:{version}] pattern")
}
if len(strs[0]) != 4 {
return "", "", "", perrors.Errorf("Parse service router key failed")
}
grp := strings.TrimSpace(strings.TrimRight(strs[0][1], "/"))
srv := strings.TrimSpace(strs[0][2])
ver := strings.TrimSpace(strings.TrimLeft(strs[0][3], ":"))
return grp, srv, ver, nil
}
func parseCondition(conditions []string) string {
var when, then string
for _, condition := range conditions {
......
......@@ -26,7 +26,9 @@ import (
)
func TestLoadYmlConfig(t *testing.T) {
router, e := NewFileConditionRouter([]byte(`priority: 1
router, e := NewFileConditionRouter([]byte(`scope: application
key: mock-app
priority: 1
force: true
conditions :
- "a => b"
......@@ -47,12 +49,78 @@ func TestParseCondition(t *testing.T) {
}
func TestFileRouterURL(t *testing.T) {
router, e := NewFileConditionRouter([]byte(`priority: 1
router, e := NewFileConditionRouter([]byte(`scope: application
key: mock-app
priority: 1
force: true
conditions :
- "a => b"
- "c => d"`))
assert.Nil(t, e)
assert.NotNil(t, router)
assert.Equal(t, "condition://0.0.0.0:?category=routers&force=true&priority=1&router=condition&rule=YSAmIGMgPT4gYiAmIGQ%3D", router.URL().String())
assert.Equal(t, "condition://0.0.0.0:?application=mock-app&category=routers&force=true&priority=1&router=condition&rule=YSAmIGMgPT4gYiAmIGQ%3D", router.URL().String())
router, e = NewFileConditionRouter([]byte(`scope: service
key: mock-service
priority: 1
force: true
conditions :
- "a => b"
- "c => d"`))
assert.Nil(t, e)
assert.NotNil(t, router)
assert.Equal(t, "condition://0.0.0.0:?category=routers&force=true&interface=mock-service&priority=1&router=condition&rule=YSAmIGMgPT4gYiAmIGQ%3D", router.URL().String())
router, e = NewFileConditionRouter([]byte(`scope: service
key: grp1/mock-service:v1
priority: 1
force: true
conditions :
- "a => b"
- "c => d"`))
assert.Nil(t, e)
assert.NotNil(t, router)
assert.Equal(t, "condition://0.0.0.0:?category=routers&force=true&group=grp1&interface=mock-service&priority=1&router=condition&rule=YSAmIGMgPT4gYiAmIGQ%3D&version=v1", router.URL().String())
}
func TestParseServiceRouterKey(t *testing.T) {
testString := " mock-group / mock-service:1.0.0"
grp, srv, ver, err := parseServiceRouterKey(testString)
assert.Equal(t, "mock-group", grp)
assert.Equal(t, "mock-service", srv)
assert.Equal(t, "1.0.0", ver)
testString = "mock-group/mock-service"
grp, srv, ver, err = parseServiceRouterKey(testString)
assert.Equal(t, "mock-group", grp)
assert.Equal(t, "mock-service", srv)
assert.Equal(t, "", ver)
testString = "mock-service:1.0.0"
grp, srv, ver, err = parseServiceRouterKey(testString)
assert.Equal(t, "", grp)
assert.Equal(t, "mock-service", srv)
assert.Equal(t, "1.0.0", ver)
testString = "mock-service"
grp, srv, ver, err = parseServiceRouterKey(testString)
assert.Equal(t, "", grp)
assert.Equal(t, "mock-service", srv)
assert.Equal(t, "", ver)
testString = "/mock-service:"
grp, srv, ver, err = parseServiceRouterKey(testString)
assert.Equal(t, "", grp)
assert.Equal(t, "mock-service", srv)
assert.Equal(t, "", ver)
testString = "grp:mock-service:123"
grp, srv, ver, err = parseServiceRouterKey(testString)
assert.Error(t, err)
testString = ""
grp, srv, ver, err = parseServiceRouterKey(testString)
assert.Equal(t, "", grp)
assert.Equal(t, "", srv)
assert.Equal(t, "", ver)
}
......@@ -117,7 +117,13 @@ func NewConditionRouter(url *common.URL) (*ConditionRouter, error) {
}
router.url = url
router.priority = url.GetParamInt(constant.RouterPriority, 0)
var defaultPriority int64 = 0
if url.GetParam(constant.APPLICATION_KEY, "") != "" {
defaultPriority = 150
} else if url.GetParam(constant.INTERFACE_KEY, "") != "" {
defaultPriority = 140
}
router.priority = url.GetParamInt(constant.RouterPriority, defaultPriority)
router.Force = url.GetParamBool(constant.RouterForce, false)
router.enabled = url.GetParamBool(constant.RouterEnabled, true)
......
......@@ -28,12 +28,13 @@ import (
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/yaml"
)
// RouterRule RouterRule config read from config file or config center
type RouterRule struct {
router.BaseRouterRule `yaml:",inline""`
router.BaseRouterRule `yaml:",inline"`
Conditions []string
}
......@@ -57,7 +58,7 @@ func getRule(rawRule string) (*RouterRule, error) {
return r, err
}
r.RawRule = rawRule
if len(r.Conditions) != 0 {
if len(r.Conditions) > 0 && len(r.Key) > 0 && (r.Scope == constant.RouterApplicationScope || r.Scope == constant.RouterServiceScope) {
r.Valid = true
}
......
......@@ -32,6 +32,7 @@ import (
func TestGetRule(t *testing.T) {
testyml := `
scope: application
key: test-provider
runtime: true
force: false
conditions:
......@@ -50,10 +51,31 @@ conditions:
assert.True(t, rule.Runtime)
assert.Equal(t, false, rule.Force)
assert.Equal(t, testyml, rule.RawRule)
assert.True(t, true, rule.Valid)
assert.True(t, rule.Valid)
assert.Equal(t, false, rule.Enabled)
assert.Equal(t, false, rule.Dynamic)
assert.Equal(t, "", rule.Key)
assert.Equal(t, "test-provider", rule.Key)
testyml = `
key: test-provider
runtime: true
force: false
conditions:
- >
method!=sayHello =>`
rule, e = getRule(testyml)
assert.Nil(t, e)
assert.False(t, rule.Valid)
testyml = `
scope: noApplication
key: test-provider
conditions:
- >
method!=sayHello =>`
rule, e = getRule(testyml)
assert.Nil(t, e)
assert.False(t, rule.Valid)
}
func TestIsMatchGlobPattern(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 condition
import (
"testing"
)
import (
"github.com/apache/dubbo-go/common"
"github.com/dubbogo/gost/container/set"
"github.com/stretchr/testify/assert"
)
func TestParseRule(t *testing.T) {
testString := ``
matchPair, err := parseRule(testString)
assert.Nil(t, err)
assert.EqualValues(t, matchPair, make(map[string]MatchPair, 16))
testString = `method!=sayHello&application=sayGoodBye`
matchPair, err = parseRule(testString)
assert.Nil(t, err)
assert.EqualValues(t, matchPair["method"].Mismatches, gxset.NewSet("sayHello"))
assert.EqualValues(t, matchPair["application"].Matches, gxset.NewSet("sayGoodBye"))
testString = `noRule`
matchPair, err = parseRule(testString)
assert.Nil(t, err)
assert.EqualValues(t, matchPair["noRule"].Mismatches, gxset.NewSet())
assert.EqualValues(t, matchPair["noRule"].Matches, gxset.NewSet())
testString = `method!=sayHello,sayGoodBye`
matchPair, err = parseRule(testString)
assert.Nil(t, err)
assert.EqualValues(t, matchPair["method"].Mismatches, gxset.NewSet(`sayHello`, `sayGoodBye`))
testString = `method!=sayHello,sayGoodDay=sayGoodBye`
matchPair, err = parseRule(testString)
assert.Nil(t, err)
assert.EqualValues(t, matchPair["method"].Mismatches, gxset.NewSet(`sayHello`, `sayGoodDay`))
assert.EqualValues(t, matchPair["method"].Matches, gxset.NewSet(`sayGoodBye`))
}
func TestNewConditionRouter(t *testing.T) {
url, _ := common.NewURL(`condition://0.0.0.0:?application=mock-app&category=routers&force=true&priority=1&router=condition&rule=YSAmIGMgPT4gYiAmIGQ%3D`)
router, err := NewConditionRouter(&url)
assert.Nil(t, err)
assert.Equal(t, true, router.Enabled())
assert.Equal(t, true, router.Force)
assert.Equal(t, int64(1), router.Priority())
whenRule, _ := parseRule("a & c")
thenRule, _ := parseRule("b & d")
assert.EqualValues(t, router.WhenCondition, whenRule)
assert.EqualValues(t, router.ThenCondition, thenRule)
router, err = NewConditionRouter(nil)
assert.Error(t, err)
url, _ = common.NewURL(`condition://0.0.0.0:?application=mock-app&category=routers&force=true&priority=1&router=condition&rule=YSAmT4gYiAmIGQ%3D`)
router, err = NewConditionRouter(&url)
assert.Error(t, err)
url, _ = common.NewURL(`condition://0.0.0.0:?application=mock-app&category=routers&force=true&router=condition&rule=YSAmIGMgPT4gYiAmIGQ%3D`)
router, err = NewConditionRouter(&url)
assert.Nil(t, err)
assert.Equal(t, int64(150), router.Priority())
url, _ = common.NewURL(`condition://0.0.0.0:?category=routers&force=true&interface=mock-service&router=condition&rule=YSAmIGMgPT4gYiAmIGQ%3D`)
router, err = NewConditionRouter(&url)
assert.Nil(t, err)
assert.Equal(t, int64(140), router.Priority())
}
......@@ -24,7 +24,7 @@ import (
// RouterRule RouterRule config read from config file or config center
type RouterRule struct {
router.BaseRouterRule `yaml:",inline""`
router.BaseRouterRule `yaml:",inline"`
}
func getRule(rawRule string) (*RouterRule, error) {
......
......@@ -197,7 +197,14 @@ const (
RouterEnabled = "enabled"
// Priority Priority key in router module
RouterPriority = "priority"
// RouterScope Scope key in router module
RouterScope = "scope"
// RouterApplicationScope Scope key in router module
RouterApplicationScope = "application"
// RouterServiceScope Scope key in router module
RouterServiceScope = "service"
// RouterRuleKey defines the key of the router, service's/application's name
RouterRuleKey = "key"
// ForceUseTag is the tag in attachment
ForceUseTag = "dubbo.force.tag"
Tagkey = "dubbo.tag"
......
......@@ -381,7 +381,7 @@ func (c URL) Service() string {
if service != "" {
return service
} else if c.SubURL != nil {
service = c.GetParam(constant.INTERFACE_KEY, strings.TrimPrefix(c.Path, "/"))
service = c.SubURL.GetParam(constant.INTERFACE_KEY, strings.TrimPrefix(c.Path, "/"))
if service != "" { // if url.path is "" then return suburl's path, special for registry url
return service
}
......
......@@ -27,7 +27,7 @@ import (
"gopkg.in/yaml.v2"
)
// loadYMLConfig Load yml config byte from file
// LoadYMLConfig Load yml config byte from file
func LoadYMLConfig(confProFile string) ([]byte, error) {
if len(confProFile) == 0 {
return nil, perrors.Errorf("application configure(provider) file name is nil")
......@@ -40,7 +40,7 @@ func LoadYMLConfig(confProFile string) ([]byte, error) {
return ioutil.ReadFile(confProFile)
}
// unmarshalYMLConfig Load yml config byte from file, then unmarshal to object
// UnmarshalYMLConfig Load yml config byte from file, then unmarshal to object
func UnmarshalYMLConfig(confProFile string, out interface{}) ([]byte, error) {
confFileStream, err := LoadYMLConfig(confProFile)
if err != nil {
......@@ -49,6 +49,12 @@ func UnmarshalYMLConfig(confProFile string, out interface{}) ([]byte, error) {
return confFileStream, yaml.Unmarshal(confFileStream, out)
}
//UnmarshalYML unmarshals decodes the first document found within the in byte slice and assigns decoded values into the out value.
func UnmarshalYML(data []byte, out interface{}) error {
return yaml.Unmarshal(data, out)
}
// MarshalYML serializes the value provided into a YAML document.
func MarshalYML(in interface{}) ([]byte, error) {
return yaml.Marshal(in)
}
......@@ -23,6 +23,7 @@ import (
)
import (
"github.com/apache/dubbo-go/cluster/router"
"github.com/apache/dubbo-go/common/extension"
"github.com/apache/dubbo-go/common/logger"
"github.com/apache/dubbo-go/common/yaml"
......@@ -32,16 +33,37 @@ var (
routerURLSet = gxset.NewSet()
)
// LocalRouterRules defines the local router config structure
type LocalRouterRules struct {
RouterRules []interface{} `yaml:"routerRules"`
}
// RouterInit Load config file to init router config
func RouterInit(confRouterFile string) error {
fileRouterFactories := extension.GetFileRouterFactories()
bytes, err := yaml.LoadYMLConfig(confRouterFile)
if err != nil {
return perrors.Errorf("ioutil.ReadFile(file:%s) = error:%v", confRouterFile, perrors.WithStack(err))
}
logger.Warnf("get fileRouterFactories len{%+v})", len(fileRouterFactories))
for k, factory := range fileRouterFactories {
r, e := factory.NewFileRouter(bytes)
routerRules := &LocalRouterRules{}
err = yaml.UnmarshalYML(bytes, routerRules)
if err != nil {
return perrors.Errorf("Load router file %s failed due to error: %v", confRouterFile, perrors.WithStack(err))
}
if len(routerRules.RouterRules) == 0 {
return perrors.Errorf("No router configurations in file %s", confRouterFile)
}
fileRouterFactories := extension.GetFileRouterFactories()
for _, v := range routerRules.RouterRules {
content, _ := yaml.MarshalYML(v)
err = initRouterConfig(content, fileRouterFactories)
}
return err
}
func initRouterConfig(content []byte, factories map[string]router.FilePriorityRouterFactory) error {
logger.Warnf("get fileRouterFactories len{%+v})", len(factories))
for k, factory := range factories {
r, e := factory.NewFileRouter(content)
if e == nil {
url := r.URL()
routerURLSet.Add(&url)
......@@ -52,6 +74,7 @@ func RouterInit(confRouterFile string) error {
return perrors.Errorf("no file router exists for parse %s , implement router.FIleRouterFactory please.", confRouterFile)
}
// GetRouterURLSet exposes the routerURLSet
func GetRouterURLSet() *gxset.HashSet {
return routerURLSet
}
......@@ -23,6 +23,7 @@ import (
)
import (
"github.com/dubbogo/gost/container/set"
"github.com/stretchr/testify/assert"
)
......@@ -31,6 +32,7 @@ import (
)
const testYML = "testdata/router_config.yml"
const testMultiRouterYML = "testdata/router_multi_config.yml"
const errorTestYML = "testdata/router_config_error.yml"
func TestString(t *testing.T) {
......@@ -63,4 +65,10 @@ func TestRouterInit(t *testing.T) {
assert.NoError(t, errPro)
assert.Equal(t, 1, routerURLSet.Size())
routerURLSet = gxset.NewSet()
errPro = RouterInit(testMultiRouterYML)
assert.NoError(t, errPro)
assert.Equal(t, 2, routerURLSet.Size())
}
......@@ -153,7 +153,7 @@ func TestExport(t *testing.T) {
providerConfig = nil
}
func TestgetRandomPort(t *testing.T) {
func TestGetRandomPort(t *testing.T) {
protocolConfigs := make([]*ProtocolConfig, 0, 3)
ip, err := gxnet.GetLocalIP()
......
# dubbo router yaml configure file
priority: 1
force: true
conditions :
- "a => b"
- "c => d"
\ No newline at end of file
routerRules:
- scope: application
key: mock-app
priority: 1
force: true
conditions :
- "a => b"
- "c => d"
\ No newline at end of file
# dubbo router yaml configure file
priority: 1
force: true
noConditions :
- "a => b"
- "c => d"
\ No newline at end of file
routerRules:
- priority: 1
force: true
noConditions :
- "a => b"
- "c => d"
\ No newline at end of file
# dubbo router yaml configure file
routerRules:
- scope: application
key: mock-app
priority: 1
force: true
conditions :
- "a => b"
- "c => d"
- scope: application
key: mock-app2
priority: 1
force: true
conditions :
- "a => b"
- "c => d"
\ No newline at end of file
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