dubbo.apache.org/dubbo-go/v3@v3.1.1/cluster/router/condition/matcher/pattern_value/scope.go (about) 1 /* 2 * Licensed to the Apache Software Foundation (ASF) under one or more 3 * contributor license agreements. See the NOTICE file distributed with 4 * this work for additional information regarding copyright ownership. 5 * The ASF licenses this file to You under the Apache License, Version 2.0 6 * (the "License"); you may not use this file except in compliance with 7 * the License. You may obtain a copy of the License at 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the License for the specific language governing permissions and 15 * limitations under the License. 16 */ 17 18 package pattern_value 19 20 import ( 21 "strconv" 22 "strings" 23 ) 24 25 import ( 26 "github.com/dubbogo/gost/log/logger" 27 ) 28 29 import ( 30 "dubbo.apache.org/dubbo-go/v3/common" 31 "dubbo.apache.org/dubbo-go/v3/common/constant" 32 "dubbo.apache.org/dubbo-go/v3/protocol" 33 ) 34 35 // ScopeValuePattern matches with patterns like 'key=1~100', 'key=~100' or 'key=1~' 36 type ScopeValuePattern struct { 37 } 38 39 func init() { 40 SetValuePattern(constant.Scope, NewScopeValuePattern) 41 } 42 43 func NewScopeValuePattern() ValuePattern { 44 return &ScopeValuePattern{} 45 } 46 47 func (s *ScopeValuePattern) Priority() int64 { 48 return 100 49 } 50 51 func (s *ScopeValuePattern) ShouldMatch(pattern string) bool { 52 return strings.Contains(pattern, "~") 53 } 54 55 func (s *ScopeValuePattern) Match(pattern string, value string, url *common.URL, invocation protocol.Invocation, isWhenCondition bool) bool { 56 defaultValue := !isWhenCondition 57 intValue, err := strconv.Atoi(value) 58 if err != nil { 59 logError(pattern, value) 60 return defaultValue 61 } 62 63 arr := strings.Split(pattern, "~") 64 if len(arr) < 2 { 65 logError(pattern, value) 66 return defaultValue 67 } 68 69 rawStart := arr[0] 70 rawEnd := arr[1] 71 72 if rawStart == "" && rawEnd == "" { 73 return defaultValue 74 } 75 76 return s.matchRange(intValue, rawStart, rawEnd, defaultValue, pattern, value) 77 } 78 79 func (s *ScopeValuePattern) matchRange(intValue int, rawStart, rawEnd string, defaultValue bool, pattern, value string) bool { 80 if rawStart == "" { 81 end, err := strconv.Atoi(rawEnd) 82 if err != nil { 83 logError(pattern, value) 84 return defaultValue 85 } 86 if intValue > end { 87 return false 88 } 89 } else if rawEnd == "" { 90 start, err := strconv.Atoi(rawStart) 91 if err != nil { 92 logError(pattern, value) 93 return defaultValue 94 } 95 if intValue < start { 96 return false 97 } 98 } else { 99 start, end, err := convertToIntRange(rawStart, rawEnd) 100 if err != nil { 101 logError(pattern, value) 102 return defaultValue 103 } 104 if intValue < start || intValue > end { 105 return false 106 } 107 } 108 109 return true 110 } 111 112 func convertToIntRange(rawStart, rawEnd string) (int, int, error) { 113 start, err := strconv.Atoi(rawStart) 114 if err != nil { 115 return 0, 0, err 116 } 117 end, err := strconv.Atoi(rawEnd) 118 if err != nil { 119 return 0, 0, err 120 } 121 return start, end, nil 122 } 123 124 func logError(pattern, value string) { 125 logger.Errorf("Parse integer error, Invalid condition rule '%s' or value '%s', will ignore.", pattern, value) 126 }