dubbo.apache.org/dubbo-go/v3@v3.1.1/config/config_loader.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 config 19 20 import ( 21 "errors" 22 "reflect" 23 "strconv" 24 ) 25 26 import ( 27 "github.com/dubbogo/gost/log/logger" 28 29 "github.com/knadh/koanf" 30 31 perrors "github.com/pkg/errors" 32 ) 33 34 import ( 35 "dubbo.apache.org/dubbo-go/v3/common" 36 "dubbo.apache.org/dubbo-go/v3/common/constant" 37 "dubbo.apache.org/dubbo-go/v3/common/extension" 38 "dubbo.apache.org/dubbo-go/v3/logger/zap" 39 "dubbo.apache.org/dubbo-go/v3/registry" 40 ) 41 42 var ( 43 rootConfig = NewRootConfigBuilder().Build() 44 ) 45 46 func init() { 47 log := zap.NewDefault() 48 logger.SetLogger(log) 49 } 50 51 func Load(opts ...LoaderConfOption) error { 52 // conf 53 conf := NewLoaderConf(opts...) 54 if conf.rc == nil { 55 koan := GetConfigResolver(conf) 56 koan = conf.MergeConfig(koan) 57 if err := koan.UnmarshalWithConf(rootConfig.Prefix(), 58 rootConfig, koanf.UnmarshalConf{Tag: "yaml"}); err != nil { 59 return err 60 } 61 } else { 62 rootConfig = conf.rc 63 } 64 65 if err := rootConfig.Init(); err != nil { 66 return err 67 } 68 return nil 69 } 70 71 func check() error { 72 if rootConfig == nil { 73 return errors.New("execute the config.Load() method first") 74 } 75 return nil 76 } 77 78 // registerServiceInstance register service instance 79 func registerServiceInstance() { 80 url := selectMetadataServiceExportedURL() 81 if url == nil { 82 return 83 } 84 instance, err := createInstance(url) 85 if err != nil { 86 panic(err) 87 } 88 p := extension.GetProtocol(constant.RegistryProtocol) 89 var rp registry.RegistryFactory 90 var ok bool 91 if rp, ok = p.(registry.RegistryFactory); !ok { 92 panic("dubbo registry protocol{" + reflect.TypeOf(p).String() + "} is invalid") 93 } 94 rs := rp.GetRegistries() 95 for _, r := range rs { 96 var sdr registry.ServiceDiscoveryHolder 97 if sdr, ok = r.(registry.ServiceDiscoveryHolder); !ok { 98 continue 99 } 100 // publish app level data to registry 101 logger.Infof("Starting register instance address %v", instance) 102 err := sdr.GetServiceDiscovery().Register(instance) 103 if err != nil { 104 panic(err) 105 } 106 } 107 // publish metadata to remote 108 if GetApplicationConfig().MetadataType == constant.RemoteMetadataStorageType { 109 if remoteMetadataService, err := extension.GetRemoteMetadataService(); err == nil && remoteMetadataService != nil { 110 remoteMetadataService.PublishMetadata(GetApplicationConfig().Name) 111 } 112 } 113 } 114 115 // // nolint 116 func createInstance(url *common.URL) (registry.ServiceInstance, error) { 117 appConfig := GetApplicationConfig() 118 port, err := strconv.ParseInt(url.Port, 10, 32) 119 if err != nil { 120 return nil, perrors.WithMessage(err, "invalid port: "+url.Port) 121 } 122 123 host := url.Ip 124 if len(host) == 0 { 125 host = common.GetLocalIp() 126 } 127 128 // usually we will add more metadata 129 metadata := make(map[string]string, 8) 130 metadata[constant.MetadataStorageTypePropertyName] = appConfig.MetadataType 131 132 instance := ®istry.DefaultServiceInstance{ 133 ServiceName: appConfig.Name, 134 Host: host, 135 Port: int(port), 136 ID: host + constant.KeySeparator + url.Port, 137 Enable: true, 138 Healthy: true, 139 Metadata: metadata, 140 Tag: appConfig.Tag, 141 } 142 143 for _, cus := range extension.GetCustomizers() { 144 cus.Customize(instance) 145 } 146 147 return instance, nil 148 } 149 150 // GetRPCService get rpc service for consumer 151 func GetRPCService(name string) common.RPCService { 152 return rootConfig.Consumer.References[name].GetRPCService() 153 } 154 155 // RPCService create rpc service for consumer 156 func RPCService(service common.RPCService) { 157 ref := common.GetReference(service) 158 rootConfig.Consumer.References[ref].Implement(service) 159 } 160 161 // GetMetricConfig find the MetricConfig 162 // if it is nil, create a new one 163 // we use double-check to reduce race condition 164 // In general, it will be locked 0 or 1 time. 165 // So you don't need to worry about the race condition 166 func GetMetricConfig() *MetricConfig { 167 // todo 168 //if GetBaseConfig().Metric == nil { 169 // configAccessMutex.Lock() 170 // defer configAccessMutex.Unlock() 171 // if GetBaseConfig().Metric == nil { 172 // GetBaseConfig().Metric = &metric.Metric{} 173 // } 174 //} 175 //return GetBaseConfig().Metric 176 return rootConfig.Metric 177 } 178 179 func GetTracingConfig(tracingKey string) *TracingConfig { 180 return rootConfig.Tracing[tracingKey] 181 } 182 183 func GetMetadataReportConfg() *MetadataReportConfig { 184 return rootConfig.MetadataReport 185 } 186 187 func IsProvider() bool { 188 return len(rootConfig.Provider.Services) > 0 189 }