github.com/polarismesh/polaris@v1.17.8/cache/service/router_rule_query.go (about) 1 /** 2 * Tencent is pleased to support the open source community by making Polaris available. 3 * 4 * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. 5 * 6 * Licensed under the BSD 3-Clause License (the "License"); 7 * you may not use this file except in compliance with the License. 8 * You may obtain a copy of the License at 9 * 10 * https://opensource.org/licenses/BSD-3-Clause 11 * 12 * Unless required by applicable law or agreed to in writing, software distributed 13 * under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR 14 * CONDITIONS OF ANY KIND, either express or implied. See the License for the 15 * specific language governing permissions and limitations under the License. 16 */ 17 18 package service 19 20 import ( 21 "sort" 22 "strings" 23 24 apitraffic "github.com/polarismesh/specification/source/go/api/v1/traffic_manage" 25 26 types "github.com/polarismesh/polaris/cache/api" 27 "github.com/polarismesh/polaris/common/model" 28 "github.com/polarismesh/polaris/common/utils" 29 ) 30 31 // forceUpdate 更新配置 32 func (rc *routingConfigCache) forceUpdate() error { 33 if err := rc.Update(); err != nil { 34 return err 35 } 36 return nil 37 } 38 39 func queryRoutingRuleV2ByService(rule *model.ExtendRouterConfig, sourceNamespace, sourceService, 40 destNamespace, destService string, both bool) bool { 41 var ( 42 sourceFind bool 43 destFind bool 44 ) 45 46 hasSourceSvc := len(sourceService) != 0 47 hasSourceNamespace := len(sourceNamespace) != 0 48 hasDestSvc := len(destService) != 0 49 hasDestNamespace := len(destNamespace) != 0 50 51 sourceService, isWildSourceSvc := utils.ParseWildName(sourceService) 52 sourceNamespace, isWildSourceNamespace := utils.ParseWildName(sourceNamespace) 53 destService, isWildDestSvc := utils.ParseWildName(destService) 54 destNamespace, isWildDestNamespace := utils.ParseWildName(destNamespace) 55 56 for i := range rule.RuleRouting.Rules { 57 subRule := rule.RuleRouting.Rules[i] 58 sources := subRule.GetSources() 59 if hasSourceNamespace || hasSourceSvc { 60 for i := range sources { 61 item := sources[i] 62 if hasSourceSvc { 63 if isWildSourceSvc { 64 if !strings.Contains(item.Service, sourceService) { 65 continue 66 } 67 } else if item.Service != sourceService { 68 continue 69 } 70 } 71 if hasSourceNamespace { 72 if isWildSourceNamespace { 73 if !strings.Contains(item.Namespace, sourceNamespace) { 74 continue 75 } 76 } else if item.Namespace != sourceNamespace { 77 continue 78 } 79 } 80 sourceFind = true 81 break 82 } 83 } 84 85 destinations := subRule.GetDestinations() 86 if hasDestNamespace || hasDestSvc { 87 for i := range destinations { 88 item := destinations[i] 89 if hasDestSvc { 90 if isWildDestSvc && !strings.Contains(item.Service, destService) { 91 continue 92 } 93 if item.Service != destService { 94 continue 95 } 96 } 97 if hasDestNamespace { 98 if isWildDestNamespace && !strings.Contains(item.Namespace, destNamespace) { 99 continue 100 } 101 if item.Namespace != destNamespace { 102 continue 103 } 104 } 105 destFind = true 106 break 107 } 108 } 109 110 if both { 111 if sourceFind && destFind { 112 return true 113 } 114 } else if sourceFind || destFind { 115 return true 116 } 117 } 118 return false 119 } 120 121 // QueryRoutingConfigsV2 Query Route Configuration List 122 func (rc *routingConfigCache) QueryRoutingConfigsV2(args *types.RoutingArgs) (uint32, []*model.ExtendRouterConfig, error) { 123 if err := rc.forceUpdate(); err != nil { 124 return 0, nil, err 125 } 126 hasSourceQuery := len(args.SourceService) != 0 || len(args.SourceNamespace) != 0 127 hasDestQuery := len(args.DestinationService) != 0 || len(args.DestinationNamespace) != 0 128 129 res := make([]*model.ExtendRouterConfig, 0, 8) 130 131 var process = func(_ string, routeRule *model.ExtendRouterConfig) { 132 if args.ID != "" && args.ID != routeRule.ID { 133 return 134 } 135 136 if routeRule.GetRoutingPolicy() == apitraffic.RoutingPolicy_RulePolicy { 137 if args.Namespace != "" && args.Service != "" { 138 if !queryRoutingRuleV2ByService(routeRule, args.Namespace, args.Service, 139 args.Namespace, args.Service, false) { 140 return 141 } 142 } 143 144 if hasSourceQuery || hasDestQuery { 145 if !queryRoutingRuleV2ByService(routeRule, args.SourceNamespace, args.SourceService, args.DestinationNamespace, 146 args.DestinationService, hasSourceQuery && hasDestQuery) { 147 return 148 } 149 } 150 } 151 152 if args.Name != "" { 153 name, isWild := utils.ParseWildName(args.Name) 154 if isWild { 155 if !strings.Contains(routeRule.Name, name) { 156 return 157 } 158 } else if args.Name != routeRule.Name { 159 return 160 } 161 } 162 163 if args.Enable != nil && *args.Enable != routeRule.Enable { 164 return 165 } 166 167 res = append(res, routeRule) 168 } 169 170 rc.IteratorRouterRule(func(key string, value *model.ExtendRouterConfig) { 171 process(key, value) 172 }) 173 174 amount, routings := rc.sortBeforeTrim(res, args) 175 return amount, routings, nil 176 } 177 178 func (rc *routingConfigCache) sortBeforeTrim(routings []*model.ExtendRouterConfig, 179 args *types.RoutingArgs) (uint32, []*model.ExtendRouterConfig) { 180 amount := uint32(len(routings)) 181 if args.Offset >= amount || args.Limit == 0 { 182 return amount, nil 183 } 184 sort.Slice(routings, func(i, j int) bool { 185 asc := strings.ToLower(args.OrderType) == "asc" || args.OrderType == "" 186 if strings.ToLower(args.OrderField) == "priority" { 187 return orderByRoutingPriority(routings[i], routings[j], asc) 188 } 189 return orderByRoutingModifyTime(routings[i], routings[j], asc) 190 }) 191 endIdx := args.Offset + args.Limit 192 if endIdx > amount { 193 endIdx = amount 194 } 195 return amount, routings[args.Offset:endIdx] 196 } 197 198 func orderByRoutingPriority(a, b *model.ExtendRouterConfig, asc bool) bool { 199 if a.Priority < b.Priority { 200 return asc 201 } 202 if a.Priority > b.Priority { 203 // false && asc always false 204 return false 205 } 206 return strings.Compare(a.ID, b.ID) < 0 && asc 207 } 208 209 func orderByRoutingModifyTime(a, b *model.ExtendRouterConfig, asc bool) bool { 210 if a.ModifyTime.After(b.ModifyTime) { 211 return asc 212 } 213 if a.ModifyTime.Before(b.ModifyTime) { 214 // false && asc always false 215 return false 216 } 217 return strings.Compare(a.ID, b.ID) < 0 && asc 218 }