dubbo.apache.org/dubbo-go/v3@v3.1.1/cluster/router/tag/router.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 tag 19 20 import ( 21 "strings" 22 "sync" 23 ) 24 25 import ( 26 "github.com/dubbogo/gost/log/logger" 27 28 "gopkg.in/yaml.v2" 29 ) 30 31 import ( 32 "dubbo.apache.org/dubbo-go/v3/common" 33 conf "dubbo.apache.org/dubbo-go/v3/common/config" 34 "dubbo.apache.org/dubbo-go/v3/common/constant" 35 "dubbo.apache.org/dubbo-go/v3/config" 36 "dubbo.apache.org/dubbo-go/v3/config_center" 37 "dubbo.apache.org/dubbo-go/v3/protocol" 38 "dubbo.apache.org/dubbo-go/v3/remoting" 39 ) 40 41 type PriorityRouter struct { 42 routerConfigs sync.Map 43 } 44 45 func NewTagPriorityRouter() (*PriorityRouter, error) { 46 return &PriorityRouter{}, nil 47 } 48 49 // Route Determine the target invokers list. 50 func (p *PriorityRouter) Route(invokers []protocol.Invoker, url *common.URL, invocation protocol.Invocation) []protocol.Invoker { 51 if len(invokers) == 0 { 52 logger.Warnf("[tag router] invokers from previous router is empty") 53 return invokers 54 } 55 // tag is valid in application 56 key := strings.Join([]string{url.GetParam(constant.ApplicationKey, ""), constant.TagRouterRuleSuffix}, "") 57 value, ok := p.routerConfigs.Load(key) 58 if !ok { 59 return staticTag(invokers, url, invocation) 60 } 61 routerCfg := value.(config.RouterConfig) 62 if !*routerCfg.Enabled || !*routerCfg.Valid { 63 return staticTag(invokers, url, invocation) 64 } 65 return dynamicTag(invokers, url, invocation, routerCfg) 66 } 67 68 func (p *PriorityRouter) URL() *common.URL { 69 return nil 70 } 71 72 func (p *PriorityRouter) Priority() int64 { 73 return 0 74 } 75 76 func (p *PriorityRouter) Notify(invokers []protocol.Invoker) { 77 if len(invokers) == 0 { 78 return 79 } 80 application := invokers[0].GetURL().GetParam(constant.ApplicationKey, "") 81 if application == "" { 82 logger.Error("url application is empty") 83 return 84 } 85 dynamicConfiguration := conf.GetEnvInstance().GetDynamicConfiguration() 86 if dynamicConfiguration == nil { 87 logger.Infof("Config center does not start, Tag router will not be enabled") 88 return 89 } 90 key := strings.Join([]string{application, constant.TagRouterRuleSuffix}, "") 91 dynamicConfiguration.AddListener(key, p) 92 value, err := dynamicConfiguration.GetRule(key) 93 if err != nil { 94 logger.Errorf("query router rule fail,key=%s,err=%v", key, err) 95 return 96 } 97 p.Process(&config_center.ConfigChangeEvent{Key: key, Value: value, ConfigType: remoting.EventTypeAdd}) 98 } 99 100 func (p *PriorityRouter) Process(event *config_center.ConfigChangeEvent) { 101 if event.ConfigType == remoting.EventTypeDel { 102 p.routerConfigs.Delete(event.Key) 103 return 104 } 105 routerConfig, err := parseRoute(event.Value.(string)) 106 if err != nil { 107 logger.Warnf("[tag router]Parse new tag route config error, %+v "+ 108 "and we will use the original tag rule configuration.", err) 109 return 110 } 111 p.routerConfigs.Store(event.Key, *routerConfig) 112 logger.Infof("[tag router]Parse tag router config success,routerConfig=%+v", routerConfig) 113 } 114 115 func parseRoute(routeContent string) (*config.RouterConfig, error) { 116 routeDecoder := yaml.NewDecoder(strings.NewReader(routeContent)) 117 routerConfig := &config.RouterConfig{} 118 err := routeDecoder.Decode(routerConfig) 119 if err != nil { 120 return nil, err 121 } 122 routerConfig.Valid = new(bool) 123 *routerConfig.Valid = true 124 if len(routerConfig.Tags) == 0 { 125 *routerConfig.Valid = false 126 } 127 return routerConfig, nil 128 }