diff --git a/config/base_config.go b/config/base_config.go index 0937d51be3..034e49cb51 100644 --- a/config/base_config.go +++ b/config/base_config.go @@ -31,6 +31,7 @@ import ( import ( "github.com/apache/dubbo-go/common/config" "github.com/apache/dubbo-go/common/logger" + "github.com/apache/dubbo-go/common/yaml" ) // BaseConfig is the common configuration for provider and consumer @@ -55,6 +56,19 @@ type BaseConfig struct { CacheFile string `yaml:"cache_file" json:"cache_file,omitempty" property:"cache_file"` } +func BaseInit(confBaseFile string) error { + if confBaseFile == "" { + return perrors.Errorf("application configure(base) file name is nil") + } + baseConfig = &BaseConfig{} + fileStream, err := yaml.UnmarshalYMLConfig(confBaseFile, baseConfig) + if err != nil { + return perrors.Errorf("unmarshalYmlConfig error %v", perrors.WithStack(err)) + } + baseConfig.fileStream = bytes.NewBuffer(fileStream) + return nil +} + // nolint func (c *BaseConfig) GetServiceDiscoveries(name string) (config *ServiceDiscoveryConfig, ok bool) { config, ok = c.ServiceDiscoveries[name] diff --git a/config/config_loader.go b/config/config_loader.go index d9c50a2094..f4790f4f98 100644 --- a/config/config_loader.go +++ b/config/config_loader.go @@ -54,15 +54,16 @@ var ( // it should be used combine with double-check to avoid the race condition configAccessMutex sync.Mutex - maxWait = 3 - confRouterFile string + maxWait = 3 + confRouterFile string + confBaseFile string uniformVirturlServiceConfigPath string uniformDestRuleConfigPath string ) // loaded consumer & provider config from xxx.yml, and log config from xxx.xml // Namely: dubbo.consumer.xml & dubbo.provider.xml in java dubbo -func init() { +func DefaultInit() []LoaderInitOption { var ( confConFile string confProFile string @@ -89,30 +90,7 @@ func init() { if confRouterFile == "" { confRouterFile = constant.DEFAULT_ROUTER_CONF_FILE_PATH } - - if errCon := ConsumerInit(confConFile); errCon != nil { - log.Printf("[consumerInit] %#v", errCon) - consumerConfig = nil - } else { - // Check if there are some important key fields missing, - // if so, we set a default value for it - setDefaultValue(consumerConfig) - // Even though baseConfig has been initialized, we override it - // because we think read from config file is correct config - baseConfig = &consumerConfig.BaseConfig - } - - if errPro := ProviderInit(confProFile); errPro != nil { - log.Printf("[providerInit] %#v", errPro) - providerConfig = nil - } else { - // Check if there are some important key fields missing, - // if so, we set a default value for it - setDefaultValue(providerConfig) - // Even though baseConfig has been initialized, we override it - // because we think read from config file is correct config - baseConfig = &providerConfig.BaseConfig - } + return []LoaderInitOption{RouterInitOption(confRouterFile), BaseInitOption(""), ConsumerInitOption(confConFile), ProviderInitOption(confProFile)} } // setDefaultValue set default value for providerConfig or consumerConfig if it is null @@ -391,23 +369,19 @@ func initRouter() { // Load Dubbo Init func Load() { - // init router - initRouter() - - // init the global event dispatcher - extension.SetAndInitGlobalDispatcher(GetBaseConfig().EventDispatcherType) + options := DefaultInit() + LoadWithOptions(options...) +} - // start the metadata report if config set - if err := startMetadataReport(GetApplicationConfig().MetadataType, GetBaseConfig().MetadataReportConfig); err != nil { - logger.Errorf("Provider starts metadata report error, and the error is {%#v}", err) - return +func LoadWithOptions(options ...LoaderInitOption) { + for _, option := range options { + option.init() } - - // reference config - loadConsumerConfig() - - // service config - loadProviderConfig() + for _, option := range options { + option.apply() + } + // init router + initRouter() // init the shutdown callback GracefulShutdownInit() diff --git a/config/config_loader_options.go b/config/config_loader_options.go new file mode 100644 index 0000000000..bde32f3173 --- /dev/null +++ b/config/config_loader_options.go @@ -0,0 +1,142 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package config + +import ( + "github.com/apache/dubbo-go/common/extension" + "github.com/apache/dubbo-go/common/logger" + "log" +) + +type LoaderInitOption interface { + init() + apply() +} + +type optionFunc struct { + initFunc func() + applyFunc func() +} + +func (f *optionFunc) init() { + f.initFunc() +} + +func (f *optionFunc) apply() { + f.applyFunc() +} + +func ConsumerInitOption(confConFile string) LoaderInitOption { + return consumerInitOption(confConFile, false) +} + +func ConsumerMustInitOption(confConFile string) LoaderInitOption { + return consumerInitOption(confConFile, true) +} + +func consumerInitOption(confConFile string, must bool) LoaderInitOption { + return &optionFunc{ + func() { + if consumerConfig != nil && !must { + return + } + if errCon := ConsumerInit(confConFile); errCon != nil { + log.Printf("[consumerInit] %#v", errCon) + consumerConfig = nil + } else if confBaseFile == "" { + // Check if there are some important key fields missing, + // if so, we set a default value for it + setDefaultValue(consumerConfig) + // Even though baseConfig has been initialized, we override it + // because we think read from config file is correct config + baseConfig = &consumerConfig.BaseConfig + } + }, + func() { + loadConsumerConfig() + }, + } +} + +func ProviderInitOption(confProFile string) LoaderInitOption { + return providerInitOption(confProFile, false) +} + +func ProviderMustInitOption(confProFile string) LoaderInitOption { + return providerInitOption(confProFile, true) +} + +func providerInitOption(confProFile string, must bool) LoaderInitOption { + return &optionFunc{ + func() { + if providerConfig != nil && !must { + return + } + if errPro := ProviderInit(confProFile); errPro != nil { + log.Printf("[providerInit] %#v", errPro) + providerConfig = nil + } else if confBaseFile == "" { + // Check if there are some important key fields missing, + // if so, we set a default value for it + setDefaultValue(providerConfig) + // Even though baseConfig has been initialized, we override it + // because we think read from config file is correct config + baseConfig = &providerConfig.BaseConfig + } + }, + func() { + loadProviderConfig() + }, + } +} + +func RouterInitOption(crf string) LoaderInitOption { + return &optionFunc{ + func() { + confRouterFile = crf + }, + func() { + initRouter() + }, + } +} + +func BaseInitOption(cbf string) LoaderInitOption { + return &optionFunc{ + func() { + if cbf == "" { + return + } + confBaseFile = cbf + if err := BaseInit(cbf); err != nil { + log.Printf("[BaseInit] %#v", err) + baseConfig = nil + } + }, + func() { + // init the global event dispatcher + extension.SetAndInitGlobalDispatcher(GetBaseConfig().EventDispatcherType) + + // start the metadata report if config set + if err := startMetadataReport(GetApplicationConfig().MetadataType, GetBaseConfig().MetadataReportConfig); err != nil { + logger.Errorf("Provider starts metadata report error, and the error is {%#v}", err) + return + } + }, + } +}