dubbo.apache.org/dubbo-go/v3@v3.1.1/metadata/service/local/metadata_service_proxy_factory.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 local
    19  
    20  import (
    21  	"encoding/json"
    22  	"sync"
    23  )
    24  
    25  import (
    26  	"github.com/dubbogo/gost/log/logger"
    27  )
    28  
    29  import (
    30  	"dubbo.apache.org/dubbo-go/v3/common"
    31  	"dubbo.apache.org/dubbo-go/v3/common/constant"
    32  	"dubbo.apache.org/dubbo-go/v3/common/extension"
    33  	"dubbo.apache.org/dubbo-go/v3/metadata/service"
    34  	"dubbo.apache.org/dubbo-go/v3/registry"
    35  )
    36  
    37  func init() {
    38  	factory := service.NewBaseMetadataServiceProxyFactory(createProxy)
    39  	extension.SetMetadataServiceProxyFactory(constant.DefaultKey, func() service.MetadataServiceProxyFactory {
    40  		return factory
    41  	})
    42  }
    43  
    44  var (
    45  	factory service.MetadataServiceProxyFactory
    46  	once    *sync.Once
    47  )
    48  
    49  func GetInMemoryMetadataServiceProxyFactory() service.MetadataServiceProxyFactory {
    50  	once.Do(func() {
    51  		factory = service.NewBaseMetadataServiceProxyFactory(createProxy)
    52  	})
    53  	return factory
    54  }
    55  
    56  // createProxy creates an instance of MetadataServiceProxy
    57  // we read the metadata from ins.Metadata()
    58  // and then create an Invoker instance
    59  // also we will mark this proxy as golang's proxy
    60  func createProxy(ins registry.ServiceInstance) service.MetadataService {
    61  	urls := buildStandardMetadataServiceURL(ins)
    62  	if len(urls) == 0 {
    63  		logger.Errorf("metadata service urls not found, %v", ins)
    64  		return nil
    65  	}
    66  
    67  	u := urls[0]
    68  	p := extension.GetProtocol(u.Protocol)
    69  	invoker := p.Refer(u)
    70  	return &MetadataServiceProxy{
    71  		Invoker: invoker,
    72  	}
    73  }
    74  
    75  // buildStandardMetadataServiceURL will use standard format to build the metadata service url.
    76  func buildStandardMetadataServiceURL(ins registry.ServiceInstance) []*common.URL {
    77  	ps := getMetadataServiceUrlParams(ins)
    78  	if ps[constant.ProtocolKey] == "" {
    79  		return nil
    80  	}
    81  	res := make([]*common.URL, 0, len(ps))
    82  	sn := ins.GetServiceName()
    83  	host := ins.GetHost()
    84  	convertedParams := make(map[string][]string, len(ps))
    85  	for k, v := range ps {
    86  		convertedParams[k] = []string{v}
    87  	}
    88  	u := common.NewURLWithOptions(common.WithIp(host),
    89  		common.WithPath(constant.MetadataServiceName),
    90  		common.WithProtocol(ps[constant.ProtocolKey]),
    91  		common.WithPort(ps[constant.PortKey]),
    92  		common.WithParams(convertedParams),
    93  		common.WithParamsValue(constant.GroupKey, sn),
    94  		common.WithParamsValue(constant.InterfaceKey, constant.MetadataServiceName))
    95  	res = append(res, u)
    96  
    97  	return res
    98  }
    99  
   100  // getMetadataServiceUrlParams this will convert the metadata service url parameters to map structure
   101  // it looks like:
   102  // {"dubbo":{"timeout":"10000","version":"1.0.0","dubbo":"2.0.2","release":"2.7.6","port":"20880"}}
   103  func getMetadataServiceUrlParams(ins registry.ServiceInstance) map[string]string {
   104  	ps := ins.GetMetadata()
   105  	res := make(map[string]string, 2)
   106  	if str, ok := ps[constant.MetadataServiceURLParamsPropertyName]; ok && len(str) > 0 {
   107  
   108  		err := json.Unmarshal([]byte(str), &res)
   109  		if err != nil {
   110  			logger.Errorf("could not parse the metadata service url parameters to map", err)
   111  		}
   112  	}
   113  	return res
   114  }