dubbo.apache.org/dubbo-go/v3@v3.1.1/registry/xds/registry.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 xds
    19  
    20  import (
    21  	"bytes"
    22  	"os"
    23  	"strconv"
    24  	"strings"
    25  )
    26  
    27  import (
    28  	"github.com/dubbogo/gost/log/logger"
    29  
    30  	perrors "github.com/pkg/errors"
    31  )
    32  
    33  import (
    34  	"dubbo.apache.org/dubbo-go/v3/common"
    35  	"dubbo.apache.org/dubbo-go/v3/common/constant"
    36  	"dubbo.apache.org/dubbo-go/v3/common/extension"
    37  	"dubbo.apache.org/dubbo-go/v3/registry"
    38  	"dubbo.apache.org/dubbo-go/v3/remoting/xds"
    39  	common2 "dubbo.apache.org/dubbo-go/v3/remoting/xds/common"
    40  )
    41  
    42  var localIP = ""
    43  var DefaultXDSSniffingTimeoutStr = "5s"
    44  
    45  func init() {
    46  	localIP = common.GetLocalIp()
    47  	extension.SetRegistry(constant.XDSRegistryKey, newXDSRegistry)
    48  }
    49  
    50  type xdsRegistry struct {
    51  	xdsWrappedClient xds.XDSWrapperClient
    52  	registryURL      *common.URL
    53  }
    54  
    55  func isProvider(url *common.URL) bool {
    56  	return getCategory(url) == constant.ProviderCategory
    57  }
    58  
    59  func getCategory(url *common.URL) string {
    60  	role, _ := strconv.Atoi(url.GetParam(constant.RegistryRoleKey, strconv.Itoa(constant.NacosDefaultRoleType)))
    61  	category := common.DubboNodes[role]
    62  	return category
    63  }
    64  
    65  // getServiceName return serviceName $(providers_or_consumers):$(interfaceName):$(version):$(group)
    66  func getServiceName(url *common.URL) string {
    67  	var buffer bytes.Buffer
    68  
    69  	buffer.Write([]byte(getCategory(url)))
    70  	appendParam(&buffer, url, constant.InterfaceKey)
    71  	appendParam(&buffer, url, constant.VersionKey)
    72  	appendParam(&buffer, url, constant.GroupKey)
    73  	return buffer.String()
    74  }
    75  
    76  // getSubscribeName returns subscribeName is providers:$(interfaceName):$(version):$(group)
    77  func getSubscribeName(url *common.URL) string {
    78  	var buffer bytes.Buffer
    79  
    80  	buffer.Write([]byte(common.DubboNodes[common.PROVIDER]))
    81  	appendParam(&buffer, url, constant.InterfaceKey)
    82  	appendParam(&buffer, url, constant.VersionKey)
    83  	appendParam(&buffer, url, constant.GroupKey)
    84  	return buffer.String()
    85  }
    86  
    87  func appendParam(target *bytes.Buffer, url *common.URL, key string) {
    88  	value := url.GetParam(key, "")
    89  	target.Write([]byte(constant.NacosServiceNameSeparator))
    90  	if strings.TrimSpace(value) != "" {
    91  		target.Write([]byte(value))
    92  	}
    93  }
    94  
    95  // Register will register the service @url to its nacos registry center
    96  func (nr *xdsRegistry) Register(url *common.URL) error {
    97  	if !isProvider(url) {
    98  		return nil
    99  	}
   100  	return nr.xdsWrappedClient.ChangeInterfaceMap(getServiceName(url), true)
   101  }
   102  
   103  // UnRegister
   104  func (nr *xdsRegistry) UnRegister(url *common.URL) error {
   105  	return nr.xdsWrappedClient.ChangeInterfaceMap(getServiceName(url), false)
   106  }
   107  
   108  // Subscribe from xds client
   109  func (nr *xdsRegistry) Subscribe(url *common.URL, notifyListener registry.NotifyListener) error {
   110  	if isProvider(url) {
   111  		return nil
   112  	}
   113  	hostAddr, svcAddr, err := nr.getHostAddrFromURL(url)
   114  	if err != nil {
   115  		return err
   116  	}
   117  	return nr.xdsWrappedClient.Subscribe(svcAddr, url.GetParam(constant.InterfaceKey, ""), hostAddr, notifyListener)
   118  }
   119  
   120  // UnSubscribe from xds client
   121  func (nr *xdsRegistry) UnSubscribe(url *common.URL, _ registry.NotifyListener) error {
   122  	_, svcAddr, err := nr.getHostAddrFromURL(url)
   123  	if err != nil {
   124  		return err
   125  	}
   126  	nr.xdsWrappedClient.UnSubscribe(svcAddr)
   127  	return nil
   128  }
   129  
   130  // LoadSubscribeInstances load subscribe instance
   131  func (nr *xdsRegistry) LoadSubscribeInstances(_ *common.URL, _ registry.NotifyListener) error {
   132  	return nil
   133  }
   134  
   135  // GetURL gets its registration URL
   136  func (nr *xdsRegistry) GetURL() *common.URL {
   137  	return nr.registryURL
   138  }
   139  
   140  func (nr *xdsRegistry) getHostAddrFromURL(url *common.URL) (string, string, error) {
   141  	svcName := getSubscribeName(url)
   142  	hostAddr, err := nr.xdsWrappedClient.GetHostAddrByServiceUniqueKey(svcName)
   143  	return hostAddr, svcName, err
   144  }
   145  
   146  // IsAvailable determines nacos registry center whether it is available
   147  func (nr *xdsRegistry) IsAvailable() bool {
   148  	// TODO
   149  	return true
   150  }
   151  
   152  // nolint
   153  func (nr *xdsRegistry) Destroy() {
   154  	// todo unregistry all
   155  	//for _, url := range nr.registryUrls {
   156  	//	err := nr.UnRegister(url)
   157  	//	logger.Infof("DeRegister Nacos URL:%+v", url)
   158  	//	if err != nil {
   159  	//		logger.Errorf("Deregister URL:%+v err:%v", url, err.Error())
   160  	//	}
   161  	//}
   162  	return
   163  }
   164  
   165  // newXDSRegistry will create new instance
   166  func newXDSRegistry(url *common.URL) (registry.Registry, error) {
   167  	logger.Infof("[XDS Registry] New XDS registry with url = %+v", url.ToMap())
   168  	pn := os.Getenv(constant.PodNameEnvKey)
   169  	ns := os.Getenv(constant.PodNamespaceEnvKey)
   170  	if pn == "" || ns == "" {
   171  		return nil, perrors.Errorf("%s and %s can't be empty when using xds registry",
   172  			constant.PodNameEnvKey, constant.PodNamespaceEnvKey)
   173  	}
   174  
   175  	wrappedXDSClient, err := xds.NewXDSWrappedClient(xds.Config{
   176  		PodName:   pn,
   177  		Namespace: ns,
   178  		LocalIP:   localIP,
   179  		IstioAddr: common2.NewHostNameOrIPAddr(url.Ip + ":" + url.Port),
   180  	})
   181  	if err != nil {
   182  		return nil, err
   183  	}
   184  
   185  	newRegistry := &xdsRegistry{
   186  		xdsWrappedClient: wrappedXDSClient,
   187  		registryURL:      url,
   188  	}
   189  
   190  	return newRegistry, nil
   191  }