This is an automated email from the ASF dual-hosted git repository.
liujun pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/dubbo-go.git
The following commit(s) were added to refs/heads/main by this push:
new 8035430c1 Design and implement new conditional rules V3.1 (#2686)
8035430c1 is described below
commit 8035430c1b3f4d8c4e3b3ef8ff3eac26daeb8954
Author: YarBor <[email protected]>
AuthorDate: Tue Jun 11 18:03:41 2024 +0800
Design and implement new conditional rules V3.1 (#2686)
---
cluster/router/condition/dynamic_router.go | 45 ++++---
cluster/router/condition/route.go | 172 +++++++++++++++++++++++---
cluster/router/condition/router_test.go | 190 +++++++++++++++++++----------
common/constant/key.go | 47 +++----
config/router_config.go | 18 ++-
5 files changed, 352 insertions(+), 120 deletions(-)
diff --git a/cluster/router/condition/dynamic_router.go
b/cluster/router/condition/dynamic_router.go
index 38e718736..6603d9bad 100644
--- a/cluster/router/condition/dynamic_router.go
+++ b/cluster/router/condition/dynamic_router.go
@@ -40,14 +40,15 @@ import (
"gopkg.in/yaml.v2"
)
-type conditionRoute []*StateRouter
+// for version 3.0-
+type stateRouters []*StateRouter
-func (p conditionRoute) route(invokers []protocol.Invoker, url *common.URL,
invocation protocol.Invocation) []protocol.Invoker {
+func (p stateRouters) route(invokers []protocol.Invoker, url *common.URL,
invocation protocol.Invocation) []protocol.Invoker {
if len(invokers) == 0 || len(p) == 0 {
return invokers
}
for _, router := range p {
- invokers, _ = router.Route(invokers, url, invocation)
+ invokers = router.Route(invokers, url, invocation)
if len(invokers) == 0 {
break
}
@@ -55,18 +56,18 @@ func (p conditionRoute) route(invokers []protocol.Invoker,
url *common.URL, invo
return invokers
}
-type multiplyConditionRoute []*StateRouter
+type multiplyConditionRoute []*MultiDestRouter
func (m multiplyConditionRoute) route(invokers []protocol.Invoker, url
*common.URL, invocation protocol.Invocation) []protocol.Invoker {
if len(invokers) == 0 || len(m) == 0 {
return invokers
}
for _, router := range m {
- matchInvokers, isMatch := router.Route(invokers, url,
invocation)
- if !isMatch || (len(matchInvokers) == 0 && !router.force) {
+ res, isMatchWhen := router.Route(invokers, url, invocation)
+ if !isMatchWhen || (len(res) == 0 &&
invocation.GetAttachmentInterface(constant.TrafficDisableKey) == nil &&
!router.force) {
continue
}
- return matchInvokers
+ return res
}
return []protocol.Invoker{}
}
@@ -96,8 +97,10 @@ func (d *DynamicRouter) Route(invokers []protocol.Invoker,
url *common.URL, invo
}
if cr != nil {
res := cr.route(invokers, url, invocation)
- if len(res) == 0 && !force {
- return invokers
+ if len(res) == 0 {
+ if
invocation.GetAttachmentInterface(constant.TrafficDisableKey) == nil && !force {
+ return invokers
+ }
}
return res
} else {
@@ -176,21 +179,33 @@ func generateMultiConditionRoute(rawConfig string)
(multiplyConditionRoute, bool
return nil, false, false, err
}
- force, enable := routerConfig.Enabled, routerConfig.Force
+ enable, force := routerConfig.Enabled, routerConfig.Force
if !enable {
return nil, false, false, nil
}
- conditionRouters := make([]*StateRouter, 0,
len(routerConfig.Conditions))
+ conditionRouters := make([]*MultiDestRouter, 0,
len(routerConfig.Conditions))
for _, conditionRule := range routerConfig.Conditions {
url, err := common.NewURL("condition://")
if err != nil {
return nil, false, false, err
}
- url.AddParam(constant.RuleKey, conditionRule.Rule)
+
+ url.SetAttribute(constant.RuleKey, conditionRule)
+ url.AddParam(constant.TrafficDisableKey,
strconv.FormatBool(conditionRule.Disable))
url.AddParam(constant.ForceKey,
strconv.FormatBool(conditionRule.Force))
- url.AddParam(constant.PriorityKey,
strconv.FormatInt(int64(conditionRule.Priority), 10))
- conditionRoute, err := NewConditionStateRouter(url)
+ if conditionRule.Priority < 0 {
+ logger.Warnf("got
conditionRouteConfig.conditions.priority (%d < 0) is invalid, ignore priority
value, use defatult %d ", conditionRule.Priority, constant.DefaultRoutePriority)
+ } else {
+ url.AddParam(constant.PriorityKey,
strconv.FormatInt(int64(conditionRule.Priority), 10))
+ }
+ if conditionRule.Ratio < 0 || conditionRule.Ratio > 100 {
+ logger.Warnf("got conditionRouteConfig.conditions.ratio
(%d) is invalid, hope (0 - 100), ignore ratio value, use defatult %d ",
conditionRule.Ratio, constant.DefaultRouteRatio)
+ } else {
+ url.AddParam(constant.RatioKey,
strconv.FormatInt(int64(conditionRule.Ratio), 10))
+ }
+
+ conditionRoute, err := NewConditionMultiDestRouter(url)
if err != nil {
return nil, false, false, err
}
@@ -203,7 +218,7 @@ func generateMultiConditionRoute(rawConfig string)
(multiplyConditionRoute, bool
return conditionRouters, force, enable, nil
}
-func generateConditionsRoute(rawConfig string) (conditionRoute, bool, bool,
error) {
+func generateConditionsRoute(rawConfig string) (stateRouters, bool, bool,
error) {
routerConfig, err := parseConditionRoute(rawConfig)
if err != nil {
logger.Warnf("[condition router]Build a new condition route
config error, %s and we will use the original condition rule configuration.",
err.Error())
diff --git a/cluster/router/condition/route.go
b/cluster/router/condition/route.go
index 7d3074af2..55e85bdfd 100644
--- a/cluster/router/condition/route.go
+++ b/cluster/router/condition/route.go
@@ -18,6 +18,7 @@
package condition
import (
+ "math/rand"
"regexp"
"sort"
"strings"
@@ -48,9 +49,6 @@ var (
)
type StateRouter struct {
- priority int64
- force bool
- url *common.URL
whenCondition map[string]matcher.Matcher
thenCondition map[string]matcher.Matcher
}
@@ -62,13 +60,7 @@ func NewConditionStateRouter(url *common.URL) (*StateRouter,
error) {
return nil, errors.Errorf("No ConditionMatcherFactory exists")
}
- force := url.GetParamBool(constant.ForceKey, false)
- priority := url.GetParamInt(constant.PriorityKey,
constant.DefaultPriority)
- c := &StateRouter{
- url: url,
- force: force,
- priority: priority,
- }
+ c := &StateRouter{}
when, then, err := generateMatcher(url)
if err != nil {
@@ -83,18 +75,18 @@ func NewConditionStateRouter(url *common.URL)
(*StateRouter, error) {
// condition rule like `self_condition => peers_condition `
//
// @return active_peers_invokers, Is_self_condition_match_success
-func (s *StateRouter) Route(invokers []protocol.Invoker, url *common.URL,
invocation protocol.Invocation) ([]protocol.Invoker, bool) {
+func (s *StateRouter) Route(invokers []protocol.Invoker, url *common.URL,
invocation protocol.Invocation) []protocol.Invoker {
if len(invokers) == 0 {
- return invokers, false
+ return invokers
}
if !s.matchWhen(url, invocation) {
- return invokers, false
+ return invokers
}
if len(s.thenCondition) == 0 {
logger.Warn("condition state router thenCondition is empty")
- return []protocol.Invoker{}, true
+ return []protocol.Invoker{}
}
var result = make([]protocol.Invoker, 0, len(invokers))
@@ -104,7 +96,7 @@ func (s *StateRouter) Route(invokers []protocol.Invoker, url
*common.URL, invoca
}
}
- return result, true
+ return result
}
func (s *StateRouter) matchWhen(url *common.URL, invocation
protocol.Invocation) bool {
@@ -307,6 +299,156 @@ func parseConditionRoute(routeContent string)
(*config.RouterConfig, error) {
return routerConfig, nil
}
+// MultiDestRouter Multiply-Destination-Router
+type MultiDestRouter struct {
+ whenCondition map[string]matcher.Matcher
+ trafficDisable bool
+ thenCondition []condSet
+ ratio int
+ priority int
+ force bool
+}
+
+type condSet struct {
+ cond map[string]matcher.Matcher
+ subSetWeight int
+}
+
+func newCondSet(cond map[string]matcher.Matcher, subSetWeight int) *condSet {
+ if subSetWeight <= 0 {
+ subSetWeight = constant.DefaultRouteConditionSubSetWeight
+ }
+ return &condSet{cond: cond, subSetWeight: subSetWeight}
+}
+
+type destSets struct {
+ dest []struct {
+ weight int
+ ivks []protocol.Invoker
+ }
+ weightSum int
+}
+
+func newDestSets() *destSets {
+ return &destSets{
+ dest: make([]struct {
+ weight int
+ ivks []protocol.Invoker
+ }, 0),
+ weightSum: 0,
+ }
+}
+
+func (s *destSets) addDest(weight int, ivks []protocol.Invoker) {
+ s.dest = append(s.dest, struct {
+ weight int
+ ivks []protocol.Invoker
+ }{weight: weight, ivks: ivks})
+ s.weightSum += weight
+}
+
+func (s *destSets) randDest() []protocol.Invoker {
+ if len(s.dest) == 1 {
+ return s.dest[0].ivks
+ }
+ sum := rand.Intn(s.weightSum)
+ for _, d := range s.dest {
+ sum -= d.weight
+ if sum <= 0 {
+ return d.ivks
+ }
+ }
+ return nil
+}
+
+func (m MultiDestRouter) Route(invokers []protocol.Invoker, url *common.URL,
invocation protocol.Invocation) ([]protocol.Invoker, bool) {
+ if len(invokers) == 0 {
+ return invokers, false
+ }
+
+ if !doMatch(url, nil, invocation, m.whenCondition, true) {
+ return invokers, false
+ }
+
+ if m.trafficDisable {
+ invocation.SetAttachment(constant.TrafficDisableKey, struct{}{})
+ return []protocol.Invoker{}, true
+ }
+
+ if len(m.thenCondition) == 0 {
+ logger.Warn("condition state router thenCondition is empty")
+ return []protocol.Invoker{}, true
+ }
+
+ destinations := newDestSets()
+ for _, condition := range m.thenCondition {
+ res := make([]protocol.Invoker, 0)
+ for _, invoker := range invokers {
+ if doMatch(invoker.GetURL(), url, nil, condition.cond,
false) {
+ res = append(res, invoker)
+ }
+ }
+ if len(res) != 0 {
+ destinations.addDest(condition.subSetWeight, res)
+ }
+ }
+
+ if len(destinations.dest) != 0 {
+ res := destinations.randDest()
+ // check x% > m.ratio%
+ if len(res)*100/len(invokers) > m.ratio {
+ return res, true
+ }
+ }
+
+ return []protocol.Invoker{}, true
+}
+
+func NewConditionMultiDestRouter(url *common.URL) (*MultiDestRouter, error) {
+ once.Do(initMatcherFactories)
+
+ if len(matcherFactories) == 0 {
+ return nil, errors.Errorf("No ConditionMatcherFactory exists")
+ }
+
+ rawCondConf, ok := url.GetAttribute(constant.RuleKey)
+ if !ok {
+ return nil, errors.Errorf("Condition Router can't get the rule
key")
+ }
+ condConf, ok := rawCondConf.(config.ConditionRule)
+ if !ok {
+ return nil, errors.Errorf("Condition Router get the rule key
invaild , got %T", rawCondConf)
+ }
+
+ c := &MultiDestRouter{
+ whenCondition: make(map[string]matcher.Matcher),
+ thenCondition: make([]condSet, 0, len(condConf.To)),
+ trafficDisable: url.GetParamBool(constant.TrafficDisableKey,
false),
+ ratio: int(url.GetParamInt32(constant.RatioKey,
constant.DefaultRouteRatio)),
+ priority: int(url.GetParamInt32(constant.PriorityKey,
constant.DefaultRoutePriority)),
+ force: url.GetParamBool(constant.ForceKey, false),
+ }
+
+ m, err := parseRule(condConf.From.Match)
+ if err != nil {
+ return nil, err
+ }
+ for k, v := range m {
+ // if key same, cover
+ c.whenCondition[k] = v
+ }
+
+ for _, ruleTo := range condConf.To {
+ cond, err := parseRule(ruleTo.Match)
+ if err != nil {
+ return nil, err
+ }
+ c.thenCondition = append(c.thenCondition, *newCondSet(cond,
ruleTo.Weight))
+ }
+
+ return c, nil
+}
+
func parseMultiConditionRoute(routeContent string) (*config.ConditionRouter,
error) {
routeDecoder := yaml.NewDecoder(strings.NewReader(routeContent))
routerConfig := &config.ConditionRouter{}
diff --git a/cluster/router/condition/router_test.go
b/cluster/router/condition/router_test.go
index d8de7c374..fe0b66954 100644
--- a/cluster/router/condition/router_test.go
+++ b/cluster/router/condition/router_test.go
@@ -214,7 +214,7 @@ func TestRouteMatchFilter(t *testing.T) {
router, err := NewConditionStateRouter(url)
assert.Nil(t, err)
- filteredInvokers, _ := router.Route(invokerList,
data.comsumerURL, rpcInvocation)
+ filteredInvokers := router.Route(invokerList,
data.comsumerURL, rpcInvocation)
resVal := len(filteredInvokers)
assert.Equal(t, data.wantVal, resVal)
})
@@ -407,7 +407,7 @@ func TestRouteReturn(t *testing.T) {
router, err := NewConditionStateRouter(url)
assert.Nil(t, err)
- filterInvokers, _ := router.Route(invokers,
consumerURL, rpcInvocation)
+ filterInvokers := router.Route(invokers, consumerURL,
rpcInvocation)
resVal := len(filterInvokers)
assert.Equal(t, data.wantVal, resVal)
@@ -479,7 +479,7 @@ func TestRouteArguments(t *testing.T) {
rpcInvocation := invocation.NewRPCInvocation("getBar",
arguments, nil)
- filterInvokers, _ := router.Route(invokerList,
consumerURL, rpcInvocation)
+ filterInvokers := router.Route(invokerList,
consumerURL, rpcInvocation)
resVal := len(filterInvokers)
assert.Equal(t, data.wantVal, resVal)
@@ -559,7 +559,7 @@ func TestRouteAttachments(t *testing.T) {
router, err := NewConditionStateRouter(url)
assert.Nil(t, err)
- filterInvokers, _ := router.Route(invokerList,
consumerURL, rpcInvocation)
+ filterInvokers := router.Route(invokerList,
consumerURL, rpcInvocation)
resVal := len(filterInvokers)
assert.Equal(t, data.wantVal, resVal)
@@ -648,7 +648,7 @@ func TestRouteRangePattern(t *testing.T) {
router, err := NewConditionStateRouter(url)
assert.Nil(t, err)
- filterInvokers, _ := router.Route(invokerList,
consumerURL, rpcInvocation)
+ filterInvokers := router.Route(invokerList,
consumerURL, rpcInvocation)
resVal := len(filterInvokers)
assert.Equal(t, data.wantVal, resVal)
@@ -712,7 +712,7 @@ func TestRouteMultipleConditions(t *testing.T) {
rpcInvocation := invocation.NewRPCInvocation(method,
arguments, nil)
- filterInvokers, _ := router.Route(invokerList,
consumerUrl, rpcInvocation)
+ filterInvokers := router.Route(invokerList,
consumerUrl, rpcInvocation)
resVal := len(filterInvokers)
assert.Equal(t, data.wantVal, resVal)
})
@@ -867,68 +867,77 @@ func buildInvokers() []protocol.Invoker {
func TestConditionRoutePriority(t *testing.T) {
ivks := buildInvokers()
ar := NewApplicationRouter()
- ar.Process(&config_center.ConfigChangeEvent{Key: "", Value: `
-configVersion: v3.1
+ ar.Process(&config_center.ConfigChangeEvent{Key: "", Value:
`configVersion: v3.1
scope: service
-force: true
+force: false
runtime: true
enabled: true
-key: org.apache.dubbo.samples.CommentService
-conditionAction : true
+key: shop
conditions:
- - rule: method=getComment & env=gray => region=Hangzhou & env=gray
- priority: 3
- - rule: method=getComment & env=gray => region=beijing & env=gray
- priority: 3
- - rule: method=getComment & env=gray => region=$region & env=gray
- priority: 3
- - rule: method=getComment & env=normal => region=beijing
- priority: 3
- - rule: method=getComment => region=$region ######### match here
- priority: 30
- - rule: method=echo => region=$region
- - rule: method=echo =>
- force: true
+ - from:
+ match:
+ to:
+ - match: region=$region & version=v1
+ - match: region=$region & version=v2
+ weight: 200
+ - match: region=$region & version=v3
+ weight: 300
+ force: false
+ ratio: 20
+ priority: 20
+ - from:
+ match:
+ region=beijing & version=v1
+ to:
+ - match: env=$env & region=beijing
+ force: false
+ priority: 100
`, ConfigType: remoting.EventTypeUpdate})
- consumerUrl, err :=
common.NewURL("consumer://127.0.0.1/com.foo.BarService?env=gray®ion=beijing")
+ consumerUrl, err :=
common.NewURL("consumer://127.0.0.1/com.foo.BarService?env=gray®ion=beijing&version=v1")
if err != nil {
panic(err)
}
got := ar.Route(ivks, consumerUrl,
invocation.NewRPCInvocation("getComment", nil, nil))
expLen := 0
for _, ivk := range ivks {
- if ivk.GetURL().GetParam("region", "") == "beijing" {
+ if ivk.GetURL().GetParam("region", "") == "beijing" && "gray"
== ivk.GetURL().GetParam("env", "") {
expLen++
}
}
+ if len(ivks)*100/expLen <= 20 {
+ expLen = 0
+ }
assert.Equal(t, expLen, len(got))
}
func TestConditionRouteTrafficDisable(t *testing.T) {
ivks := buildInvokers()
ar := NewApplicationRouter()
- ar.Process(&config_center.ConfigChangeEvent{Key: "", Value: `
-configVersion: v3.1
+ ar.Process(&config_center.ConfigChangeEvent{Key: "", Value:
`configVersion: v3.1
scope: service
force: true
runtime: true
enabled: true
-key: org.apache.dubbo.samples.CommentService
-conditionAction : true
+key: shop
conditions:
- - rule: method=getComment & env=gray => region=Hangzhou & env=gray
- priority: 3
- - rule: method=getComment & env=gray => region=beijing & env=gray
- priority: 3
- - rule: method=getComment & env=gray => region=$region & env=gray
- priority: 3
- - rule: method=getComment & env=normal => region=beijing
- priority: 3
- - rule: method=getComment => region=$region
- priority: 30
- - rule: method=echo =>
+ - from:
+ match:
+ to:
+ - match: region=$region & version=v1
+ - match: region=$region & version=v2
+ weight: 200
+ - match: region=$region & version=v3
+ weight: 300
+ force: false
+ ratio: 20
+ priority: 20
+ - from:
+ match:
+ region=beijing & version=v1
+ to:
force: true
- - rule: method=echo => region=$region
+ ratio: 20
+ priority: 100
`, ConfigType: remoting.EventTypeUpdate})
consumerUrl, err :=
common.NewURL("consumer://127.0.0.1/com.foo.BarService?env=gray®ion=beijing")
if err != nil {
@@ -941,23 +950,17 @@ conditions:
func TestConditionRouteRegionPriority(t *testing.T) {
ivks := buildInvokers()
ar := NewApplicationRouter()
- ar.Process(&config_center.ConfigChangeEvent{Key: "", Value: `
-configVersion: v3.1
+ ar.Process(&config_center.ConfigChangeEvent{Key: "", Value:
`configVersion: v3.1
scope: service
force: true
runtime: true
enabled: true
-key: org.apache.dubbo.samples.CommentService
-conditionAction : true
+key: shop
conditions:
- - rule: => region=$region & env=$env
- - rule: method=getComment & env=gray => env=$env
- - rule: method=getComment & env=gray & region=beijing => region=beijing &
env=gray
- - rule: method=getComment & env=gray => region=$region & env=gray
- - rule: method=getComment & env=normal => region=beijing
- - rule: method=echo =>
- force: true
- - rule: method=echo => region=$region
+ - from:
+ match:
+ to:
+ - match: region=$region & env=$env
`, ConfigType: remoting.EventTypeUpdate})
consumerUrl, err :=
common.NewURL("consumer://127.0.0.1/com.foo.BarService?env=gray®ion=beijing")
if err != nil {
@@ -992,33 +995,88 @@ conditions:
got = ar.Route(ivks, consumerUrl,
invocation.NewRPCInvocation("getComment", nil, nil))
expLen = 0
for _, ivk := range ivks {
- if ivk.GetURL().GetRawParam("region") == "beijing" {
+ if ivk.GetURL().GetRawParam("region") ==
consumerUrl.GetRawParam("region") &&
+ ivk.GetURL().GetRawParam("env") ==
consumerUrl.GetRawParam("env") {
expLen++
}
}
assert.Equal(t, expLen, len(got))
}
+func TestConditionRouteRegionPriorityFail(t *testing.T) {
+ ivks := buildInvokers()
+ ar := NewApplicationRouter()
+ ar.Process(&config_center.ConfigChangeEvent{Key: "", Value:
`configVersion: v3.1
+scope: service
+force: true
+runtime: true
+enabled: true
+key: shop
+conditions:
+ - from:
+ match:
+ to:
+ - match: region=$region & env=$env
+ ratio: 100
+`, ConfigType: remoting.EventTypeUpdate})
+ consumerUrl, err :=
common.NewURL("consumer://127.0.0.1/com.foo.BarService?env=gray®ion=beijing")
+ if err != nil {
+ panic(err)
+ }
+ got := ar.Route(ivks, consumerUrl,
invocation.NewRPCInvocation("getComment", nil, nil))
+ assert.Equal(t, 0, len(got))
+}
+
func TestConditionRouteMatchFail(t *testing.T) {
ivks := buildInvokers()
ar := NewApplicationRouter()
- ar.Process(&config_center.ConfigChangeEvent{Key: "", Value: `
-configVersion: v3.1
+ ar.Process(&config_center.ConfigChangeEvent{Key: "", Value:
`configVersion: v3.1
scope: service
force: false
runtime: true
enabled: true
-key: org.apache.dubbo.samples.CommentService
-conditionAction : true
+key: shop
conditions:
- - rule: => region=$region & env=$env & errTag=errTag
- - rule: method=getComment & env=gray => env=$env
- - rule: method=getComment & env=gray & region=beijing => region=beijing &
env=gray
- - rule: method=getComment & env=gray => region=$region & env=gray
- - rule: method=getComment & env=normal => region=beijing
- - rule: method=echo =>
+ - from:
+ match:
+ to:
+ - match: region=$region & env=$env & err-tag=Err-tag
+ - from:
+ match:
+ trafficDisable: true
+ to:
+ - match:
+`, ConfigType: remoting.EventTypeUpdate})
+ consumerUrl, err :=
common.NewURL("consumer://127.0.0.1/com.foo.BarService?env=gray®ion=beijing")
+ if err != nil {
+ panic(err)
+ }
+ got := ar.Route(ivks, consumerUrl,
invocation.NewRPCInvocation("errMethod", nil, nil))
+ assert.Equal(t, 0, len(got))
+}
+
+func TestConditionRouteBanSpecialTraffic(t *testing.T) {
+ ivks := buildInvokers()
+ ar := NewApplicationRouter()
+ ar.Process(&config_center.ConfigChangeEvent{Key: "", Value:
`configVersion: v3.1
+scope: service
+force: true
+runtime: true
+enabled: true
+key: shop
+conditions:
+ - from:
+ match: env=gray
+ to:
+ - match:
+ force: true
+ priority: 100
+ - from:
+ match:
+ to:
+ - match:
force: true
- - rule: method=echo => region=$region
+ priority: 100
`, ConfigType: remoting.EventTypeUpdate})
consumerUrl, err :=
common.NewURL("consumer://127.0.0.1/com.foo.BarService?env=gray®ion=beijing")
if err != nil {
diff --git a/common/constant/key.go b/common/constant/key.go
index 1e9959947..6ffe0642c 100644
--- a/common/constant/key.go
+++ b/common/constant/key.go
@@ -308,27 +308,32 @@ const (
// Use for router module
const (
- ScriptRouterRuleSuffix = ".script-router"
- TagRouterRuleSuffix = ".tag-router"
- ConditionRouterRuleSuffix = ".condition-router" // Specify
condition router suffix
- MeshRouteSuffix = ".MESHAPPRULE" // Specify mesh
router suffix
- ForceUseTag = "dubbo.force.tag" // the tag in
attachment
- ForceUseCondition = "dubbo.force.condition"
- Tagkey = "dubbo.tag" // key of tag
- ConditionKey = "dubbo.condition"
- AttachmentKey = DubboCtxKey("attachment") // key in
context in invoker
- TagRouterFactoryKey = "tag"
- ConditionAppRouterFactoryKey = "provider.condition"
- ConditionServiceRouterFactoryKey = "service.condition"
- ScriptRouterFactoryKey = "consumer.script"
- ForceKey = "force"
- PriorityKey = "priority"
- Arguments = "arguments"
- Attachments = "attachments"
- Param = "param"
- Scope = "scope"
- Wildcard = "wildcard"
- MeshRouterFactoryKey = "mesh"
+ ScriptRouterRuleSuffix = ".script-router"
+ TagRouterRuleSuffix = ".tag-router"
+ ConditionRouterRuleSuffix = ".condition-router" // Specify
condition router suffix
+ MeshRouteSuffix = ".MESHAPPRULE" // Specify mesh
router suffix
+ ForceUseTag = "dubbo.force.tag" // the tag in
attachment
+ ForceUseCondition = "dubbo.force.condition"
+ Tagkey = "dubbo.tag" // key of tag
+ ConditionKey = "dubbo.condition"
+ AttachmentKey = DubboCtxKey("attachment") // key in
context in invoker
+ TagRouterFactoryKey = "tag"
+ ConditionAppRouterFactoryKey = "provider.condition"
+ ConditionServiceRouterFactoryKey = "service.condition"
+ ScriptRouterFactoryKey = "consumer.script"
+ ForceKey = "force"
+ TrafficDisableKey = "trafficDisable"
+ PriorityKey = "priority"
+ RatioKey = "RatioKey"
+ Arguments = "arguments"
+ Attachments = "attachments"
+ Param = "param"
+ Scope = "scope"
+ Wildcard = "wildcard"
+ MeshRouterFactoryKey = "mesh"
+ DefaultRouteRatio = 0
+ DefaultRouteConditionSubSetWeight = 100
+ DefaultRoutePriority = 0
)
// Auth filter
diff --git a/config/router_config.go b/config/router_config.go
index 3cfff9cad..e8f155789 100644
--- a/config/router_config.go
+++ b/config/router_config.go
@@ -50,9 +50,21 @@ type Tag struct {
}
type ConditionRule struct {
- Rule string `validate:"required" yaml:"rule" json:"rule,omitempty"
property:"rule"`
- Priority int `default:"0" yaml:"priority" json:"priority,omitempty"
property:"priority"`
- Force bool `default:"false" yaml:"force" json:"force,omitempty"
property:"force"`
+ Priority int `default:"0" yaml:"priority"
json:"priority,omitempty" property:"priority"`
+ From ConditionRuleFrom `yaml:"from" json:"from,omitempty"
property:"from"`
+ Disable bool `default:"false" yaml:"trafficDisable"
json:"trafficDisable,omitempty" property:"trafficDisable"`
+ To []ConditionRuleTo `yaml:"to" json:"to,omitempty" property:"to"`
+ Ratio int `default:"0" yaml:"ratio"
json:"ratio,omitempty" property:"priority"`
+ Force bool `default:"false" yaml:"force"
json:"force,omitempty" property:"force"`
+}
+
+type ConditionRuleFrom struct {
+ Match string `yaml:"match" json:"match,omitempty" property:"match"`
+}
+
+type ConditionRuleTo struct {
+ Match string `yaml:"match" json:"match,omitempty" property:"match"`
+ Weight int `default:"100" yaml:"weight" json:"weight,omitempty"
property:"weight"`
}
// ConditionRouter -- when RouteConfigVersion == v3.1, decode by this