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 }