diff --git a/cluster/router/condition_router.go b/cluster/router/condition_router.go index b63fa093d7dded5d6699c667591db5bc7dd7f9db..45ea0ab890592fb246335c430bd4776483c16401 100644 --- a/cluster/router/condition_router.go +++ b/cluster/router/condition_router.go @@ -134,7 +134,6 @@ func (c *ConditionRouter) Route(invokers []protocol.Invoker, url common.URL, inv if len(c.ThenCondition) == 0 { return result } - localIP, _ := gxnet.GetLocalIP() for _, invoker := range invokers { isMatchThen, err := c.MatchThen(invoker.GetUrl(), url) if err != nil { @@ -153,6 +152,7 @@ func (c *ConditionRouter) Route(invokers []protocol.Invoker, url common.URL, inv return result } else if c.Force { rule, _ := url.GetParamAndDecoded(constant.RULE_KEY) + localIP, _ := gxnet.GetLocalIP() logger.Warnf("The route result is empty and force execute. consumer: %s, service: %s, router: %s", localIP, url.Service(), rule) return result } @@ -222,18 +222,18 @@ func parseRule(rule string) (map[string]MatchPair, error) { // func (c *ConditionRouter) MatchWhen(url common.URL, invocation protocol.Invocation) (bool, error) { - condition, err := MatchCondition(c.WhenCondition, &url, nil, invocation) + condition, err := matchCondition(c.WhenCondition, &url, nil, invocation) return len(c.WhenCondition) == 0 || condition, err } //MatchThen MatchThen func (c *ConditionRouter) MatchThen(url common.URL, param common.URL) (bool, error) { - condition, err := MatchCondition(c.ThenCondition, &url, ¶m, nil) + condition, err := matchCondition(c.ThenCondition, &url, ¶m, nil) return len(c.ThenCondition) > 0 && condition, err } //MatchCondition MatchCondition -func MatchCondition(pairs map[string]MatchPair, url *common.URL, param *common.URL, invocation protocol.Invocation) (bool, error) { +func matchCondition(pairs map[string]MatchPair, url *common.URL, param *common.URL, invocation protocol.Invocation) (bool, error) { sample := url.ToMap() if sample == nil { return true, perrors.Errorf("url is not allowed be nil") @@ -292,6 +292,7 @@ func (pair MatchPair) isMatch(value string, param *common.URL) bool { return true } if !pair.Mismatches.Empty() && !pair.Matches.Empty() { + //when both mismatches and matches contain the same value, then using mismatches first for mismatch := range pair.Mismatches.Items { if isMatchGlobPattern(mismatch.(string), value, param) { return false @@ -306,31 +307,3 @@ func (pair MatchPair) isMatch(value string, param *common.URL) bool { } return false } - -func isMatchGlobPattern(pattern string, value string, param *common.URL) bool { - if param != nil && strings.HasPrefix(pattern, "$") { - pattern = param.GetRawParam(pattern[1:]) - } - if "*" == pattern { - return true - } - if len(pattern) == 0 && len(value) == 0 { - return true - } - if len(pattern) == 0 || len(value) == 0 { - return false - } - i := strings.LastIndex(pattern, "*") - switch i { - case -1: - return value == pattern - case len(pattern) - 1: - return strings.HasPrefix(value, pattern[0:i]) - case 0: - return strings.HasSuffix(value, pattern[:i+1]) - default: - prefix := pattern[0:1] - suffix := pattern[i+1:] - return strings.HasPrefix(value, prefix) && strings.HasSuffix(value, suffix) - } -} diff --git a/cluster/router/url_utils.go b/cluster/router/url_utils.go new file mode 100644 index 0000000000000000000000000000000000000000..0adff7503be107f710549f0e99238c140d70af37 --- /dev/null +++ b/cluster/router/url_utils.go @@ -0,0 +1,62 @@ +/* + * 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 router + +import ( + "strings" +) + +import ( + "github.com/apache/dubbo-go/common" +) + +func isMatchGlobPattern(pattern string, value string, param *common.URL) bool { + if param != nil && strings.HasPrefix(pattern, "$") { + pattern = param.GetRawParam(pattern[1:]) + } + return isMatchInternalPattern(pattern, value) +} + +func isMatchInternalPattern(pattern string, value string) bool { + if "*" == pattern { + return true + } + if len(pattern) == 0 && len(value) == 0 { + return true + } + if len(pattern) == 0 || len(value) == 0 { + return false + } + i := strings.LastIndex(pattern, "*") + switch i { + case -1: + // doesn't find "*" + return value == pattern + case len(pattern) - 1: + // "*" is at the end + return strings.HasPrefix(value, pattern[0:i]) + case 0: + // "*" is at the beginning + return strings.HasSuffix(value, pattern[i+1:]) + default: + // "*" is in the middle + prefix := pattern[0:1] + suffix := pattern[i+1:] + return strings.HasPrefix(value, prefix) && strings.HasSuffix(value, suffix) + } +} diff --git a/cluster/router/url_utils_test.go b/cluster/router/url_utils_test.go new file mode 100644 index 0000000000000000000000000000000000000000..caabf35515b934b49c6473b098db9f40ca973cd2 --- /dev/null +++ b/cluster/router/url_utils_test.go @@ -0,0 +1,44 @@ +/* + * 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 router + +import ( + "context" + "testing" + + "github.com/apache/dubbo-go/common" +) +import ( + "github.com/stretchr/testify/assert" +) + +func TestIsMatchInternalPattern(t *testing.T) { + assert.Equal(t, true, isMatchInternalPattern("*", "value")) + assert.Equal(t, true, isMatchInternalPattern("", "")) + assert.Equal(t, false, isMatchInternalPattern("", "value")) + assert.Equal(t, true, isMatchInternalPattern("value", "value")) + assert.Equal(t, true, isMatchInternalPattern("v*", "value")) + assert.Equal(t, true, isMatchInternalPattern("*ue", "value")) + assert.Equal(t, true, isMatchInternalPattern("*e", "value")) + assert.Equal(t, true, isMatchInternalPattern("v*e", "value")) +} + +func TestIsMatchGlobPattern(t *testing.T) { + url, _ := common.NewURL(context.TODO(), "dubbo://localhost:8080/Foo?key=v*e") + assert.Equal(t, true, isMatchGlobPattern("$key", "value", &url)) +} diff --git a/registry/directory/directory.go b/registry/directory/directory.go index 96ea612a1db5d116bd696019685acdc9a23cd389..044e4ea4da21d0aab6805a3cb992639c593e33de 100644 --- a/registry/directory/directory.go +++ b/registry/directory/directory.go @@ -18,7 +18,6 @@ package directory import ( - "fmt" "reflect" "sync" "time"