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  }