From 9d32b76dde92b7fa1e256c01925d847cf6dd8055 Mon Sep 17 00:00:00 2001
From: Joe Zou <yixian.zou@gmail.com>
Date: Mon, 17 Feb 2020 22:53:47 +0800
Subject: [PATCH] add comment and testcase

---
 cluster/router/condition/file.go      | 31 ++++++++++++++++---------
 cluster/router/condition/file_test.go | 11 +++++++++
 cluster/router/router.go              |  1 +
 common/constant/key.go                | 33 ++++++++++++++-------------
 4 files changed, 49 insertions(+), 27 deletions(-)

diff --git a/cluster/router/condition/file.go b/cluster/router/condition/file.go
index b55479f0e..efeec53ef 100644
--- a/cluster/router/condition/file.go
+++ b/cluster/router/condition/file.go
@@ -22,6 +22,7 @@ import (
 	"net/url"
 	"strconv"
 	"strings"
+	"sync"
 )
 
 import (
@@ -33,10 +34,14 @@ import (
 	"github.com/apache/dubbo-go/common/constant"
 )
 
+// FileConditionRouter Use for parse config file of condition router
 type FileConditionRouter struct {
 	listenableRouter
+	parseOnce sync.Once
+	url       common.URL
 }
 
+// NewFileConditionRouter Create file condition router instance with content ( from config file)
 func NewFileConditionRouter(content []byte) (*FileConditionRouter, error) {
 	fileRouter := &FileConditionRouter{}
 	rule, err := Parse(string(content))
@@ -53,18 +58,22 @@ func NewFileConditionRouter(content []byte) (*FileConditionRouter, error) {
 	return fileRouter, nil
 }
 
+// URL Return URL in file condition router n
 func (f *FileConditionRouter) URL() common.URL {
-	routerRule := f.routerRule
-	rule := parseCondition(routerRule.Conditions)
-	return *common.NewURLWithOptions(
-		common.WithProtocol(constant.ROUTE_PROTOCOL),
-		common.WithIp(constant.ANYHOST_VALUE),
-		common.WithParams(url.Values{}),
-		common.WithParamsValue(constant.RouterForce, strconv.FormatBool(routerRule.Force)),
-		common.WithParamsValue(constant.RouterPriority, strconv.Itoa(routerRule.Priority)),
-		common.WithParamsValue(constant.RULE_KEY, base64.URLEncoding.EncodeToString([]byte(rule))),
-		common.WithParamsValue(constant.ROUTER_KEY, "condition"),
-		common.WithParamsValue(constant.CATEGORY_KEY, constant.ROUTERS_CATEGORY))
+	f.parseOnce.Do(func() {
+		routerRule := f.routerRule
+		rule := parseCondition(routerRule.Conditions)
+		f.url = *common.NewURLWithOptions(
+			common.WithProtocol(constant.CONDITION_ROUTE_PROTOCOL),
+			common.WithIp(constant.ANYHOST_VALUE),
+			common.WithParams(url.Values{}),
+			common.WithParamsValue(constant.RouterForce, strconv.FormatBool(routerRule.Force)),
+			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))
+	})
+	return f.url
 }
 
 func parseCondition(conditions []string) string {
diff --git a/cluster/router/condition/file_test.go b/cluster/router/condition/file_test.go
index 04ef82249..3092b12ff 100644
--- a/cluster/router/condition/file_test.go
+++ b/cluster/router/condition/file_test.go
@@ -45,3 +45,14 @@ func TestParseCondition(t *testing.T) {
 	condition := parseCondition(s)
 	assert.Equal(t, "a & c => b & d", condition)
 }
+
+func TestFileRouterURL(t *testing.T) {
+	router, e := NewFileConditionRouter([]byte(`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())
+}
diff --git a/cluster/router/router.go b/cluster/router/router.go
index c982bd067..a28002a09 100644
--- a/cluster/router/router.go
+++ b/cluster/router/router.go
@@ -30,6 +30,7 @@ type RouterFactory interface {
 	NewRouter(*common.URL) (Router, error)
 }
 
+// RouterFactory Router create factory use for parse config file
 type FIleRouterFactory interface {
 	// NewFileRouters Create file router with config file
 	NewFileRouter([]byte) (Router, error)
diff --git a/common/constant/key.go b/common/constant/key.go
index 39f10fd2e..4536d945c 100644
--- a/common/constant/key.go
+++ b/common/constant/key.go
@@ -90,22 +90,23 @@ const (
 )
 
 const (
-	APPLICATION_KEY    = "application"
-	ORGANIZATION_KEY   = "organization"
-	NAME_KEY           = "name"
-	MODULE_KEY         = "module"
-	APP_VERSION_KEY    = "app.version"
-	OWNER_KEY          = "owner"
-	ENVIRONMENT_KEY    = "environment"
-	METHOD_KEY         = "method"
-	METHOD_KEYS        = "methods"
-	RULE_KEY           = "rule"
-	RUNTIME_KEY        = "runtime"
-	BACKUP_KEY         = "backup"
-	ROUTERS_CATEGORY   = "routers"
-	ROUTE_PROTOCOL     = "route"
-	PROVIDERS_CATEGORY = "providers"
-	ROUTER_KEY         = "router"
+	APPLICATION_KEY          = "application"
+	ORGANIZATION_KEY         = "organization"
+	NAME_KEY                 = "name"
+	MODULE_KEY               = "module"
+	APP_VERSION_KEY          = "app.version"
+	OWNER_KEY                = "owner"
+	ENVIRONMENT_KEY          = "environment"
+	METHOD_KEY               = "method"
+	METHOD_KEYS              = "methods"
+	RULE_KEY                 = "rule"
+	RUNTIME_KEY              = "runtime"
+	BACKUP_KEY               = "backup"
+	ROUTERS_CATEGORY         = "routers"
+	ROUTE_PROTOCOL           = "route"
+	CONDITION_ROUTE_PROTOCOL = "condition"
+	PROVIDERS_CATEGORY       = "providers"
+	ROUTER_KEY               = "router"
 )
 
 const (
-- 
GitLab