From 209fcf36681af55db335e0c1d44a0abad8a74cf4 Mon Sep 17 00:00:00 2001 From: aliiohs <rzy1107@163.com> Date: Thu, 27 Jun 2019 19:33:43 +0800 Subject: [PATCH] fix --- cluster/router.go | 1 - cluster/router/condition_router.go | 62 ++++++++++++------------- cluster/router/condition_router_test.go | 39 ++++++---------- common/url.go | 4 +- common/url_test.go | 20 ++++---- protocol/invocation/rpcinvocation.go | 2 +- 6 files changed, 57 insertions(+), 71 deletions(-) diff --git a/cluster/router.go b/cluster/router.go index a9908dcf9..30771fcfc 100644 --- a/cluster/router.go +++ b/cluster/router.go @@ -30,7 +30,6 @@ type RouterFactory interface { type Router interface { Route([]protocol.Invoker, common.URL, protocol.Invocation) []protocol.Invoker - CompareTo(router Router) int } type RouterChain struct { diff --git a/cluster/router/condition_router.go b/cluster/router/condition_router.go index 8dcfe92f6..b5f8551e9 100644 --- a/cluster/router/condition_router.go +++ b/cluster/router/condition_router.go @@ -22,7 +22,6 @@ import ( "regexp" "strings" - "github.com/apache/dubbo-go/cluster" "github.com/apache/dubbo-go/common" "github.com/apache/dubbo-go/common/constant" "github.com/apache/dubbo-go/common/logger" @@ -33,9 +32,9 @@ import ( ) const ( - RoutePattern = `([&!=,]*)\\s*([^&!=,\\s]+)` - FORCE = "force" - PRIORITY = "priority" + ROUTE_PATTERN = `([&!=,]*)\\s*([^&!=,\\s]+)` + FORCE = "force" + PRIORITY = "priority" ) //ConditionRouter condition router struct @@ -48,39 +47,30 @@ type ConditionRouter struct { ThenCondition map[string]MatchPair } -//CompareTo -func (c ConditionRouter) CompareTo(r cluster.Router) int { - var result int - router, ok := r.(*ConditionRouter) - if r == nil || !ok { - return 1 - } - if c.Priority == router.Priority { - result = strings.Compare(c.Url.String(), router.Url.String()) - } else { - if c.Priority > router.Priority { - result = 1 - } else { - result = -1 - } - } - return result -} - func newConditionRouter(url common.URL) (*ConditionRouter, error) { var ( whenRule string thenRule string + when map[string]MatchPair + then map[string]MatchPair ) - rule, err := url.GetParameterAndDecoded(constant.RULE_KEY) + rule, err := url.GetParamAndDecoded(constant.RULE_KEY) if err != nil || rule == "" { return nil, perrors.Errorf("Illegal route rule!") } rule = strings.Replace(rule, "consumer.", "", -1) rule = strings.Replace(rule, "provider.", "", -1) i := strings.Index(rule, "=>") - whenRule = strings.Trim(If(i < 0, "", rule[0:i]).(string), " ") - thenRule = strings.Trim(If(i < 0, rule, rule[i+2:]).(string), " ") + if i > 0 { + whenRule = rule[0:i] + } + if i < 0 { + thenRule = rule + } else { + thenRule = rule[i+2:] + } + whenRule = strings.Trim(whenRule, " ") + thenRule = strings.Trim(thenRule, " ") w, err := parseRule(whenRule) if err != nil { return nil, perrors.Errorf("%s", "") @@ -89,11 +79,18 @@ func newConditionRouter(url common.URL) (*ConditionRouter, error) { if err != nil { return nil, perrors.Errorf("%s", "") } - when := If(whenRule == "" || "true" == whenRule, make(map[string]MatchPair), w).(map[string]MatchPair) - then := If(thenRule == "" || "false" == thenRule, make(map[string]MatchPair), t).(map[string]MatchPair) - + if whenRule == "" || "true" == whenRule { + when = make(map[string]MatchPair) + } else { + when = w + } + if thenRule == "" || "false" == thenRule { + when = make(map[string]MatchPair) + } else { + then = t + } return &ConditionRouter{ - RoutePattern, + ROUTE_PATTERN, url, url.GetParamInt(PRIORITY, 0), url.GetParamBool(FORCE, false), @@ -141,7 +138,8 @@ func (c *ConditionRouter) Route(invokers []protocol.Invoker, url common.URL, inv if len(result) > 0 { return result } else if c.Force { - logger.Warnf("The route result is empty and force execute. consumer: %s, service: %s, router: %s", localIP, url.Service()) + rule, _ := url.GetParamAndDecoded(constant.RULE_KEY) + logger.Warnf("The route result is empty and force execute. consumer: %s, service: %s, router: %s", localIP, url.Service(), rule) return result } return invokers @@ -301,7 +299,7 @@ func (pair MatchPair) isMatch(value string, param *common.URL) bool { func isMatchGlobPattern(pattern string, value string, param *common.URL) bool { if param != nil && strings.HasPrefix(pattern, "$") { - pattern = param.GetRawParameter(pattern[1:]) + pattern = param.GetRawParam(pattern[1:]) } if "*" == pattern { return true diff --git a/cluster/router/condition_router_test.go b/cluster/router/condition_router_test.go index 2a3ee11d1..d24e0ec86 100644 --- a/cluster/router/condition_router_test.go +++ b/cluster/router/condition_router_test.go @@ -35,10 +35,9 @@ import ( ) type MockInvoker struct { - url common.URL - available bool - destroyed bool - + url common.URL + available bool + destroyed bool successCount int } @@ -61,12 +60,14 @@ func getRouteUrl(rule string) common.URL { url.AddParam("force", "true") return url } + func getRouteUrlWithForce(rule, force string) common.URL { url, _ := common.NewURL(context.TODO(), "condition://0.0.0.0/com.foo.BarService") url.AddParam("rule", rule) url.AddParam("force", force) return url } + func getRouteUrlWithNoForce(rule string) common.URL { url, _ := common.NewURL(context.TODO(), "condition://0.0.0.0/com.foo.BarService") url.AddParam("rule", rule) @@ -98,7 +99,6 @@ func (bi *MockInvoker) Invoke(invocation protocol.Invocation) protocol.Result { err = perrors.New("error") } result := &protocol.RPCResult{Err: err, Rest: rest{tried: count, success: success}} - return result } @@ -113,40 +113,34 @@ func TestRoute_matchWhen(t *testing.T) { rule := base64.URLEncoding.EncodeToString([]byte("=> host = 1.2.3.4")) router, _ := NewConditionRouterFactory().Router(getRouteUrl(rule)) cUrl, _ := common.NewURL(context.TODO(), "consumer://1.1.1.1/com.foo.BarService") - matchWhen, _ := router.(*ConditionRouter).MatchWhen(cUrl, inv) 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")) router1, _ := NewConditionRouterFactory().Router(getRouteUrl(rule1)) matchWhen1, _ := router1.(*ConditionRouter).MatchWhen(cUrl, inv) 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")) router2, _ := NewConditionRouterFactory().Router(getRouteUrl(rule2)) matchWhen2, _ := router2.(*ConditionRouter).MatchWhen(cUrl, inv) 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")) router3, _ := NewConditionRouterFactory().Router(getRouteUrl(rule3)) matchWhen3, _ := router3.(*ConditionRouter).MatchWhen(cUrl, inv) 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")) router4, _ := NewConditionRouterFactory().Router(getRouteUrl(rule4)) matchWhen4, _ := router4.(*ConditionRouter).MatchWhen(cUrl, inv) 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")) router5, _ := NewConditionRouterFactory().Router(getRouteUrl(rule5)) matchWhen5, _ := router5.(*ConditionRouter).MatchWhen(cUrl, inv) 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")) router6, _ := NewConditionRouterFactory().Router(getRouteUrl(rule6)) matchWhen6, _ := router6.(*ConditionRouter).MatchWhen(cUrl, inv) assert.Equal(t, true, matchWhen6) } + func TestRoute_matchFilter(t *testing.T) { localIP, _ := utils.GetLocalIP() url1, _ := common.NewURL(context.TODO(), "dubbo://10.20.3.3:20880/com.foo.BarService?default.serialization=fastjson") @@ -166,7 +160,6 @@ func TestRoute_matchFilter(t *testing.T) { router5, _ := NewConditionRouterFactory().Router(getRouteUrl(rule5)) router6, _ := NewConditionRouterFactory().Router(getRouteUrl(rule6)) cUrl, _ := common.NewURL(context.TODO(), "consumer://"+localIP+"/com.foo.BarService") - fileredInvokers1 := router1.Route(invokers, cUrl, &invocation.RPCInvocation{}) fileredInvokers2 := router2.Route(invokers, cUrl, &invocation.RPCInvocation{}) fileredInvokers3 := router3.Route(invokers, cUrl, &invocation.RPCInvocation{}) @@ -183,25 +176,20 @@ func TestRoute_matchFilter(t *testing.T) { } func TestRoute_methodRoute(t *testing.T) { - - inv := invocation.NewRPCInvocation("getFoo", []reflect.Type{}, []interface{}{}) + inv := invocation.NewRPCInvocationForUT("getFoo", []reflect.Type{}, []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")) router, _ := NewConditionRouterFactory().Router(getRouteUrl(rule)) - url, _ := common.NewURL(context.TODO(), "consumer://1.1.1.1/com.foo.BarService?methods=setFoo,getFoo,findFoo") matchWhen, _ := router.(*ConditionRouter).MatchWhen(url, inv) assert.Equal(t, true, matchWhen) - url1, _ := common.NewURL(context.TODO(), "consumer://1.1.1.1/com.foo.BarService?methods=getFoo") matchWhen, _ = router.(*ConditionRouter).MatchWhen(url1, inv) assert.Equal(t, true, matchWhen) - url2, _ := common.NewURL(context.TODO(), "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")) router2, _ := NewConditionRouterFactory().Router(getRouteUrl(rule2)) matchWhen, _ = router2.(*ConditionRouter).MatchWhen(url2, inv) assert.Equal(t, false, matchWhen) - url3, _ := common.NewURL(context.TODO(), "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")) router3, _ := NewConditionRouterFactory().Router(getRouteUrl(rule3)) @@ -217,11 +205,11 @@ func TestRoute_ReturnFalse(t *testing.T) { inv := &invocation.RPCInvocation{} rule := base64.URLEncoding.EncodeToString([]byte("host = " + localIP + " => false")) curl, _ := common.NewURL(context.TODO(), "consumer://"+localIP+"/com.foo.BarService") - router, _ := NewConditionRouterFactory().Router(getRouteUrl(rule)) fileredInvokers := router.(*ConditionRouter).Route(invokers, curl, inv) assert.Equal(t, 0, len(fileredInvokers)) } + func TestRoute_ReturnEmpty(t *testing.T) { localIP, _ := utils.GetLocalIP() url, _ := common.NewURL(context.TODO(), "") @@ -229,18 +217,17 @@ func TestRoute_ReturnEmpty(t *testing.T) { inv := &invocation.RPCInvocation{} rule := base64.URLEncoding.EncodeToString([]byte("host = " + localIP + " => ")) curl, _ := common.NewURL(context.TODO(), "consumer://"+localIP+"/com.foo.BarService") - router, _ := NewConditionRouterFactory().Router(getRouteUrl(rule)) fileredInvokers := router.(*ConditionRouter).Route(invokers, curl, inv) assert.Equal(t, 0, len(fileredInvokers)) } + func TestRoute_ReturnAll(t *testing.T) { localIP, _ := utils.GetLocalIP() invokers := []protocol.Invoker{&MockInvoker{}, &MockInvoker{}, &MockInvoker{}} inv := &invocation.RPCInvocation{} rule := base64.URLEncoding.EncodeToString([]byte("host = " + localIP + " => " + " host = " + localIP)) curl, _ := common.NewURL(context.TODO(), "consumer://"+localIP+"/com.foo.BarService") - router, _ := NewConditionRouterFactory().Router(getRouteUrl(rule)) fileredInvokers := router.(*ConditionRouter).Route(invokers, curl, inv) assert.Equal(t, invokers, fileredInvokers) @@ -264,6 +251,7 @@ func TestRoute_HostFilter(t *testing.T) { assert.Equal(t, invoker2, fileredInvokers[0]) assert.Equal(t, invoker3, fileredInvokers[1]) } + func TestRoute_Empty_HostFilter(t *testing.T) { localIP, _ := utils.GetLocalIP() url1, _ := common.NewURL(context.TODO(), "dubbo://10.20.3.3:20880/com.foo.BarService") @@ -276,13 +264,13 @@ func TestRoute_Empty_HostFilter(t *testing.T) { inv := &invocation.RPCInvocation{} rule := base64.URLEncoding.EncodeToString([]byte(" => " + " host = " + localIP)) curl, _ := common.NewURL(context.TODO(), "consumer://"+localIP+"/com.foo.BarService") - router, _ := NewConditionRouterFactory().Router(getRouteUrl(rule)) fileredInvokers := router.(*ConditionRouter).Route(invokers, curl, inv) assert.Equal(t, 2, len(fileredInvokers)) assert.Equal(t, invoker2, fileredInvokers[0]) assert.Equal(t, invoker3, fileredInvokers[1]) } + func TestRoute_False_HostFilter(t *testing.T) { localIP, _ := utils.GetLocalIP() url1, _ := common.NewURL(context.TODO(), "dubbo://10.20.3.3:20880/com.foo.BarService") @@ -295,13 +283,13 @@ func TestRoute_False_HostFilter(t *testing.T) { inv := &invocation.RPCInvocation{} rule := base64.URLEncoding.EncodeToString([]byte("true => " + " host = " + localIP)) curl, _ := common.NewURL(context.TODO(), "consumer://"+localIP+"/com.foo.BarService") - router, _ := NewConditionRouterFactory().Router(getRouteUrl(rule)) fileredInvokers := router.(*ConditionRouter).Route(invokers, curl, inv) assert.Equal(t, 2, len(fileredInvokers)) assert.Equal(t, invoker2, fileredInvokers[0]) assert.Equal(t, invoker3, fileredInvokers[1]) } + func TestRoute_Placeholder(t *testing.T) { localIP, _ := utils.GetLocalIP() url1, _ := common.NewURL(context.TODO(), "dubbo://10.20.3.3:20880/com.foo.BarService") @@ -320,6 +308,7 @@ func TestRoute_Placeholder(t *testing.T) { assert.Equal(t, invoker2, fileredInvokers[0]) assert.Equal(t, invoker3, fileredInvokers[1]) } + func TestRoute_NoForce(t *testing.T) { localIP, _ := utils.GetLocalIP() url1, _ := common.NewURL(context.TODO(), "dubbo://10.20.3.3:20880/com.foo.BarService") @@ -336,6 +325,7 @@ func TestRoute_NoForce(t *testing.T) { fileredInvokers := router.(*ConditionRouter).Route(invokers, curl, inv) assert.Equal(t, invokers, fileredInvokers) } + func TestRoute_Force(t *testing.T) { localIP, _ := utils.GetLocalIP() url1, _ := common.NewURL(context.TODO(), "dubbo://10.20.3.3:20880/com.foo.BarService") @@ -348,7 +338,6 @@ func TestRoute_Force(t *testing.T) { inv := &invocation.RPCInvocation{} rule := base64.URLEncoding.EncodeToString([]byte("host = " + localIP + " => " + " host = 1.2.3.4")) curl, _ := common.NewURL(context.TODO(), "consumer://"+localIP+"/com.foo.BarService") - router, _ := NewConditionRouterFactory().Router(getRouteUrlWithForce(rule, "true")) fileredInvokers := router.(*ConditionRouter).Route(invokers, curl, inv) assert.Equal(t, 0, len(fileredInvokers)) diff --git a/common/url.go b/common/url.go index 22c1a6d6b..5343bf585 100644 --- a/common/url.go +++ b/common/url.go @@ -293,13 +293,13 @@ func (c URL) GetParam(s string, d string) string { } return r } -func (c URL) GetParameterAndDecoded(key string) (string, error) { +func (c URL) GetParamAndDecoded(key string) (string, error) { ruleDec, err := base64.URLEncoding.DecodeString(c.GetParam(key, "")) value := string(ruleDec) return value, err } -func (c URL) GetRawParameter(key string) string { +func (c URL) GetRawParam(key string) string { if "protocol" == key { return c.Protocol } diff --git a/common/url_test.go b/common/url_test.go index 986855370..224dbd6d9 100644 --- a/common/url_test.go +++ b/common/url_test.go @@ -130,25 +130,25 @@ func TestURL_GetParamBool(t *testing.T) { assert.Equal(t, false, v) } -func TestURL_GetParameterAndDecoded(t *testing.T) { +func TestURL_GetParamAndDecoded(t *testing.T) { rule := "host = 2.2.2.2,1.1.1.1,3.3.3.3 & host !=1.1.1.1 => host = 1.2.3.4" params := url.Values{} params.Set("rule", base64.URLEncoding.EncodeToString([]byte(rule))) u := URL{baseUrl: baseUrl{Params: params}} - v, _ := u.GetParameterAndDecoded("rule") + v, _ := u.GetParamAndDecoded("rule") assert.Equal(t, rule, v) } -func TestURL_GetRawParameter(t *testing.T) { +func TestURL_GetRawParam(t *testing.T) { u, _ := NewURL(context.TODO(), "condition://0.0.0.0:8080/com.foo.BarService?serialization=fastjson") u.Username = "test" u.Password = "test" - assert.Equal(t, "condition", u.GetRawParameter("protocol")) - assert.Equal(t, "0.0.0.0", u.GetRawParameter("host")) - assert.Equal(t, "8080", u.GetRawParameter("port")) - assert.Equal(t, "test", u.GetRawParameter("username")) - assert.Equal(t, "test", u.GetRawParameter("password")) - assert.Equal(t, "/com.foo.BarService", u.GetRawParameter("path")) - assert.Equal(t, "fastjson", u.GetRawParameter("serialization")) + assert.Equal(t, "condition", u.GetRawParam("protocol")) + assert.Equal(t, "0.0.0.0", u.GetRawParam("host")) + assert.Equal(t, "8080", u.GetRawParam("port")) + assert.Equal(t, "test", u.GetRawParam("username")) + assert.Equal(t, "test", u.GetRawParam("password")) + assert.Equal(t, "/com.foo.BarService", u.GetRawParam("path")) + assert.Equal(t, "fastjson", u.GetRawParam("serialization")) } func TestURL_ToMap(t *testing.T) { u, _ := NewURL(context.TODO(), "condition://0.0.0.0:8080/com.foo.BarService?serialization=fastjson") diff --git a/protocol/invocation/rpcinvocation.go b/protocol/invocation/rpcinvocation.go index 222921890..183596eec 100644 --- a/protocol/invocation/rpcinvocation.go +++ b/protocol/invocation/rpcinvocation.go @@ -69,7 +69,7 @@ func NewRPCInvocationForProvider(methodName string, arguments []interface{}, att } } -func NewRPCInvocation(methodName string, parameterTypes []reflect.Type, arguments []interface{}) *RPCInvocation { +func NewRPCInvocationForUT(methodName string, parameterTypes []reflect.Type, arguments []interface{}) *RPCInvocation { return &RPCInvocation{ methodName: methodName, arguments: arguments, -- GitLab