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