dubbo.apache.org/dubbo-go/v3@v3.1.1/config_center/configurator/override.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 configurator 19 20 import ( 21 "strings" 22 ) 23 24 import ( 25 gxset "github.com/dubbogo/gost/container/set" 26 ) 27 28 import ( 29 "dubbo.apache.org/dubbo-go/v3/common" 30 "dubbo.apache.org/dubbo-go/v3/common/constant" 31 "dubbo.apache.org/dubbo-go/v3/common/extension" 32 "dubbo.apache.org/dubbo-go/v3/config_center" 33 "dubbo.apache.org/dubbo-go/v3/config_center/parser" 34 ) 35 36 func init() { 37 extension.SetDefaultConfigurator(newConfigurator) 38 } 39 40 func newConfigurator(url *common.URL) config_center.Configurator { 41 return &overrideConfigurator{configuratorUrl: url} 42 } 43 44 type overrideConfigurator struct { 45 configuratorUrl *common.URL 46 } 47 48 func (c *overrideConfigurator) GetUrl() *common.URL { 49 return c.configuratorUrl 50 } 51 52 func (c *overrideConfigurator) Configure(url *common.URL) { 53 // remove configuratorUrl some param that can not be configured 54 if c.configuratorUrl.GetParam(constant.EnabledKey, "true") == "false" || len(c.configuratorUrl.Location) == 0 { 55 return 56 } 57 58 // branch for version 2.7.x 59 apiVersion := c.configuratorUrl.GetParam(constant.ConfigVersionKey, "") 60 if len(apiVersion) != 0 { 61 var host string 62 currentSide := url.GetParam(constant.SideKey, "") 63 configuratorSide := c.configuratorUrl.GetParam(constant.SideKey, "") 64 if currentSide == configuratorSide && common.DubboRole[common.CONSUMER] == currentSide { 65 host = common.GetLocalIp() 66 } else if currentSide == configuratorSide && common.DubboRole[common.PROVIDER] == currentSide { 67 host = url.Ip 68 } 69 70 if strings.HasPrefix(apiVersion, constant.APIVersion) { 71 c.configureIfMatchV3(host, url) 72 } else { 73 c.configureIfMatch(host, url) 74 } 75 } else { 76 // branch for version 2.6.x and less 77 c.configureDeprecated(url) 78 } 79 } 80 81 // configureIfMatch 82 func (c *overrideConfigurator) configureIfMatchV3(host string, url *common.URL) { 83 conditionKeys := getConditionKeys() 84 matcher := c.configuratorUrl.GetAttribute(constant.MatchCondition) 85 if matcher != nil { 86 conditionMatcher := matcher.(*parser.ConditionMatch) 87 if conditionMatcher.IsMatch(host, url) { 88 configUrl := c.configuratorUrl.CloneExceptParams(conditionKeys) 89 url.SetParams(configUrl.GetParams()) 90 } 91 } 92 } 93 94 func (c *overrideConfigurator) configureDeprecated(url *common.URL) { 95 // If override url has port, means it is a provider address. We want to control a specific provider with this override url, it may take effect on the specific provider instance or on consumers holding this provider instance. 96 if c.configuratorUrl.Port != "0" { 97 if url.Port == c.configuratorUrl.Port { 98 c.configureIfMatch(url.Ip, url) 99 } 100 } else { 101 // override url don't have a port, means the ip override url specify is a consumer address or 0.0.0.0 102 // 1.If it is a consumer ip address, the intention is to control a specific consumer instance, it must takes effect at the consumer side, any provider received this override url should ignore; 103 // 2.If the ip is 0.0.0.0, this override url can be used on consumer, and also can be used on provider 104 if url.GetParam(constant.SideKey, "") == common.DubboRole[common.CONSUMER] { 105 localIP := common.GetLocalIp() 106 c.configureIfMatch(localIP, url) 107 } else { 108 c.configureIfMatch(constant.AnyHostValue, url) 109 } 110 } 111 } 112 113 func (c *overrideConfigurator) configureIfMatchInternal(url *common.URL) { 114 configApp := c.configuratorUrl.GetParam(constant.ApplicationKey, c.configuratorUrl.Username) 115 currentApp := url.GetParam(constant.ApplicationKey, url.Username) 116 if len(configApp) == 0 || constant.AnyValue == configApp || configApp == currentApp { 117 conditionKeys := getConditionKeys() 118 returnUrl := false 119 c.configuratorUrl.RangeParams(func(k, _ string) bool { 120 value := c.configuratorUrl.GetParam(k, "") 121 if strings.HasPrefix(k, "~") || k == constant.ApplicationKey || k == constant.SideKey { 122 conditionKeys.Add(k) 123 if len(value) != 0 && value != constant.AnyValue && value != url.GetParam(strings.TrimPrefix(k, "~"), "") { 124 returnUrl = true 125 return false 126 } 127 } 128 return true 129 }) 130 if returnUrl { 131 return 132 } 133 configUrl := c.configuratorUrl.CloneExceptParams(conditionKeys) 134 url.SetParams(configUrl.GetParams()) 135 } 136 } 137 138 // configureIfMatch translate from java, compatible rules in java 139 func (c *overrideConfigurator) configureIfMatch(host string, url *common.URL) { 140 if constant.AnyHostValue == c.configuratorUrl.Ip || host == c.configuratorUrl.Ip { 141 providers := c.configuratorUrl.GetParam(constant.OverrideProvidersKey, "") 142 if len(providers) == 0 || strings.Contains(providers, url.Location) || strings.Contains(providers, constant.AnyHostValue) { 143 c.configureIfMatchInternal(url) 144 } 145 } 146 } 147 148 func getConditionKeys() *gxset.HashSet { 149 conditionKeys := gxset.NewSet() 150 conditionKeys.Add(constant.CategoryKey) 151 conditionKeys.Add(constant.CheckKey) 152 conditionKeys.Add(constant.EnabledKey) 153 conditionKeys.Add(constant.GroupKey) 154 conditionKeys.Add(constant.VersionKey) 155 conditionKeys.Add(constant.ApplicationKey) 156 conditionKeys.Add(constant.SideKey) 157 conditionKeys.Add(constant.ConfigVersionKey) 158 conditionKeys.Add(constant.CompatibleConfigKey) 159 return conditionKeys 160 }