From 23f5b402a10d8f11b73dd3d9676b088cb7977f35 Mon Sep 17 00:00:00 2001 From: "vito.he" <hxmhlt@163.com> Date: Tue, 10 Sep 2019 18:42:31 +0800 Subject: [PATCH] Add:support single registry config in config center --- common/config/environment.go | 23 ++-- common/config/environment_test.go | 2 +- common/constant/key.go | 13 ++- config/base_config.go | 106 ++++++++++++++---- config/base_config_test.go | 158 ++++++++++++++++++++++++++- config/config_center_config.go | 21 ++-- config/config_loader.go | 7 ++ config/config_loader_test.go | 93 +++++++++++++++- config/consumer_config.go | 1 + config/provider_config.go | 1 + config/reference_config_test.go | 61 +++++++++-- config/registry_config.go | 49 +++++---- config/service_config_test.go | 54 ++++++++- config_center/mock_dynamic_config.go | 8 +- 14 files changed, 515 insertions(+), 82 deletions(-) diff --git a/common/config/environment.go b/common/config/environment.go index a9447aa12..931f04609 100644 --- a/common/config/environment.go +++ b/common/config/environment.go @@ -36,6 +36,7 @@ type Environment struct { configCenterFirst bool externalConfigs sync.Map externalConfigMap sync.Map + appExternalConfigMap sync.Map dynamicConfiguration config_center.DynamicConfiguration } @@ -50,6 +51,9 @@ func GetEnvInstance() *Environment { }) return instance } +func NewEnvInstance() { + instance = &Environment{configCenterFirst: true} +} //func (env *Environment) SetConfigCenterFirst() { // env.configCenterFirst = true @@ -65,11 +69,17 @@ func (env *Environment) UpdateExternalConfigMap(externalMap map[string]string) { } } +func (env *Environment) UpdateAppExternalConfigMap(externalMap map[string]string) { + for k, v := range externalMap { + env.appExternalConfigMap.Store(k, v) + } +} + func (env *Environment) Configuration() *list.List { list := list.New() - memConf := newInmemoryConfiguration() - memConf.setProperties(&(env.externalConfigMap)) - list.PushBack(memConf) + // The sequence would be: SystemConfiguration -> ExternalConfiguration -> AppExternalConfiguration -> AbstractConfig -> PropertiesConfiguration + list.PushFront(newInmemoryConfiguration(&(env.externalConfigMap))) + list.PushFront(newInmemoryConfiguration(&(env.appExternalConfigMap))) return list } @@ -85,11 +95,8 @@ type InmemoryConfiguration struct { store *sync.Map } -func newInmemoryConfiguration() *InmemoryConfiguration { - return &InmemoryConfiguration{} -} -func (conf *InmemoryConfiguration) setProperties(p *sync.Map) { - conf.store = p +func newInmemoryConfiguration(p *sync.Map) *InmemoryConfiguration { + return &InmemoryConfiguration{store: p} } func (conf *InmemoryConfiguration) GetProperty(key string) (bool, string) { diff --git a/common/config/environment_test.go b/common/config/environment_test.go index 0e1d679bc..2d84dc4ae 100644 --- a/common/config/environment_test.go +++ b/common/config/environment_test.go @@ -39,7 +39,7 @@ func TestEnvironment_UpdateExternalConfigMap(t *testing.T) { func TestEnvironment_ConfigurationAndGetProperty(t *testing.T) { GetEnvInstance().UpdateExternalConfigMap(map[string]string{"1": "2"}) list := GetEnvInstance().Configuration() - ok, v := list.Front().Value.(*InmemoryConfiguration).GetProperty("1") + ok, v := list.Back().Value.(*InmemoryConfiguration).GetProperty("1") assert.True(t, ok) assert.Equal(t, "2", v) } diff --git a/common/constant/key.go b/common/constant/key.go index feb6fc9aa..1b25d11ed 100644 --- a/common/constant/key.go +++ b/common/constant/key.go @@ -91,12 +91,13 @@ const ( COMPATIBLE_CONFIG_KEY = "compatible_config" ) const ( - RegistryConfigPrefix = "dubbo.registries." - ReferenceConfigPrefix = "dubbo.reference." - ServiceConfigPrefix = "dubbo.service." - ProtocolConfigPrefix = "dubbo.protocols." - ProviderConfigPrefix = "dubbo.provider." - ConsumerConfigPrefix = "dubbo.consumer." + RegistryConfigPrefix = "dubbo.registries." + SingleRegistryConfigPrefix = "dubbo.registry." + ReferenceConfigPrefix = "dubbo.reference." + ServiceConfigPrefix = "dubbo.service." + ProtocolConfigPrefix = "dubbo.protocols." + ProviderConfigPrefix = "dubbo.provider." + ConsumerConfigPrefix = "dubbo.consumer." ) const ( diff --git a/config/base_config.go b/config/base_config.go index 6c85b5e46..e51d8b955 100644 --- a/config/base_config.go +++ b/config/base_config.go @@ -20,6 +20,7 @@ import ( "context" "reflect" "strconv" + "strings" ) import ( @@ -72,15 +73,43 @@ func (c *BaseConfig) prepareEnvironment() error { logger.Errorf("Get config content in dynamic configuration error , error message is %v", err) return perrors.WithStack(err) } + var appGroup string + var appContent string + if providerConfig != nil && providerConfig.ApplicationConfig != nil && + reflect.ValueOf(c.fatherConfig).Elem().Type().Name() == "ProviderConfig" { + appGroup = providerConfig.ApplicationConfig.Name + } else if consumerConfig != nil && consumerConfig.ApplicationConfig != nil && + reflect.ValueOf(c.fatherConfig).Elem().Type().Name() == "ConsumerConfig" { + appGroup = consumerConfig.ApplicationConfig.Name + } + + if len(appGroup) != 0 { + configFile := c.ConfigCenterConfig.AppConfigFile + if len(configFile) == 0 { + configFile = c.ConfigCenterConfig.ConfigFile + } + appContent, err = dynamicConfig.GetConfig(configFile, config_center.WithGroup(appGroup)) + } + //global config file mapContent, err := dynamicConfig.Parser().Parse(content) if err != nil { return perrors.WithStack(err) } config.GetEnvInstance().UpdateExternalConfigMap(mapContent) + + //appGroup config file + if len(appContent) != 0 { + appMapConent, err := dynamicConfig.Parser().Parse(appContent) + if err != nil { + return perrors.WithStack(err) + } + config.GetEnvInstance().UpdateAppExternalConfigMap(appMapConent) + } + return nil } -func getKeyPrefix(val reflect.Value, id reflect.Value) string { +func getKeyPrefix(val reflect.Value, id reflect.Value) []string { var ( prefix string idStr string @@ -94,21 +123,42 @@ func getKeyPrefix(val reflect.Value, id reflect.Value) string { } else { prefix = val.MethodByName("Prefix").Call(nil)[0].String() } + var retPrefixs []string - if idStr != "" { - return prefix + idStr + "." - } else { - return prefix + for _, pfx := range strings.Split(prefix, "|") { + if idStr != "" { + retPrefixs = append(retPrefixs, pfx+idStr+".") + } else { + retPrefixs = append(retPrefixs, pfx) + } } -} + return retPrefixs +} +func getPtrElement(v reflect.Value) reflect.Value { + if v.Kind() == reflect.Ptr { + v = v.Elem() + if v.Kind() == reflect.Ptr { + return getPtrElement(v) + } + } + return v +} func setFieldValue(val reflect.Value, id reflect.Value, config *config.InmemoryConfiguration) { for i := 0; i < val.NumField(); i++ { if key := val.Type().Field(i).Tag.Get("property"); key != "-" && key != "" { f := val.Field(i) if f.IsValid() { setBaseValue := func(f reflect.Value) { - ok, value := config.GetProperty(getKeyPrefix(val, id) + key) + var ok bool + var value string + prefixs := getKeyPrefix(val, id) + for _, pfx := range prefixs { + ok, value = config.GetProperty(pfx + key) + if ok { + break + } + } if ok { switch f.Kind() { case reflect.Int64: @@ -154,12 +204,12 @@ func setFieldValue(val reflect.Value, id reflect.Value, config *config.InmemoryC } - setBaseValue(f) if f.Kind() == reflect.Ptr { - if f.Elem().Kind() == reflect.Struct { - setFieldValue(f.Elem(), reflect.Value{}, config) + f = getPtrElement(f) + if f.Kind() == reflect.Struct { + setFieldValue(f, reflect.Value{}, config) } else { - setBaseValue(f.Elem()) + setBaseValue(f) } } @@ -170,10 +220,11 @@ func setFieldValue(val reflect.Value, id reflect.Value, config *config.InmemoryC for i := 0; i < f.Len(); i++ { e := f.Index(i) if e.Kind() == reflect.Ptr { - if e.Elem().Kind() == reflect.Struct { - setFieldValue(e.Elem(), reflect.Value{}, config) + e = getPtrElement(e) + if e.Kind() == reflect.Struct { + setFieldValue(e, reflect.Value{}, config) } else { - setBaseValue(e.Elem()) + setBaseValue(e) } } @@ -186,10 +237,16 @@ func setFieldValue(val reflect.Value, id reflect.Value, config *config.InmemoryC //initiate config s := reflect.New(f.Type().Elem().Elem()) prefix := s.MethodByName("Prefix").Call(nil)[0].String() - m := config.GetSubProperty(prefix) - for k := range m { - f.SetMapIndex(reflect.ValueOf(k), reflect.New(f.Type().Elem().Elem())) + for _, pfx := range strings.Split(prefix, "|") { + m := config.GetSubProperty(pfx) + if m != nil { + for k := range m { + f.SetMapIndex(reflect.ValueOf(k), reflect.New(f.Type().Elem().Elem())) + } + } + } + } //iter := f.MapRange() @@ -198,10 +255,11 @@ func setFieldValue(val reflect.Value, id reflect.Value, config *config.InmemoryC v := f.MapIndex(k) switch v.Kind() { case reflect.Ptr: - if v.Elem().Kind() == reflect.Struct { - setFieldValue(v.Elem(), k, config) + v = getPtrElement(v) + if v.Kind() == reflect.Struct { + setFieldValue(v, k, config) } else { - setBaseValue(v.Elem()) + setBaseValue(v) } case reflect.Int64, reflect.String, reflect.Bool, reflect.Float64: setBaseValue(v) @@ -210,6 +268,7 @@ func setFieldValue(val reflect.Value, id reflect.Value, config *config.InmemoryC } } } + setBaseValue(f) } } @@ -217,8 +276,13 @@ func setFieldValue(val reflect.Value, id reflect.Value, config *config.InmemoryC } func (c *BaseConfig) fresh() { configList := config.GetEnvInstance().Configuration() - config := configList.Front().Value.(*config.InmemoryConfiguration) + for element := configList.Front(); element != nil; element = element.Next() { + config := element.Value.(*config.InmemoryConfiguration) + c.freshInternalConfig(config) + } +} +func (c *BaseConfig) freshInternalConfig(config *config.InmemoryConfiguration) { //reflect to init struct tp := reflect.ValueOf(c.fatherConfig).Elem().Type() initializeStruct(tp, reflect.ValueOf(c.fatherConfig).Elem()) diff --git a/config/base_config_test.go b/config/base_config_test.go index d07d983f6..239bece47 100644 --- a/config/base_config_test.go +++ b/config/base_config_test.go @@ -125,6 +125,162 @@ func Test_refresh(t *testing.T) { assert.Equal(t, "dubbo", father.ApplicationConfig.Name) } +func Test_appExternal_refresh(t *testing.T) { + c := &BaseConfig{} + mockMap := map[string]string{} + mockMap["dubbo.registries.shanghai_reg1.protocol"] = "mock100" + mockMap["dubbo.reference.com.MockService.MockService.retries"] = "10" + mockMap["dubbo.com.MockService.MockService.GetUser.retries"] = "10" + mockMap["dubbo.consumer.check"] = "false" + mockMap["dubbo.application.name"] = "dubbo" + + config.GetEnvInstance().UpdateAppExternalConfigMap(mockMap) + mockMap["dubbo.consumer.check"] = "true" + config.GetEnvInstance().UpdateExternalConfigMap(mockMap) + father := &ConsumerConfig{ + Check: &[]bool{true}[0], + ApplicationConfig: &ApplicationConfig{ + Organization: "dubbo_org", + Name: "dubbo", + Module: "module", + Version: "2.6.0", + Owner: "dubbo", + Environment: "test"}, + Registries: map[string]*RegistryConfig{ + //"shanghai_reg1": { + // id: "shanghai_reg1", + // Protocol: "mock", + // TimeoutStr: "2s", + // Group: "shanghai_idc", + // Address: "127.0.0.1:2181", + // Username: "user1", + // Password: "pwd1", + //}, + "shanghai_reg2": { + Protocol: "mock", + TimeoutStr: "2s", + Group: "shanghai_idc", + Address: "127.0.0.2:2181", + Username: "user1", + Password: "pwd1", + }, + "hangzhou_reg1": { + Protocol: "mock", + TimeoutStr: "2s", + Group: "hangzhou_idc", + Address: "127.0.0.3:2181", + Username: "user1", + Password: "pwd1", + }, + "hangzhou_reg2": { + Protocol: "mock", + TimeoutStr: "2s", + Group: "hangzhou_idc", + Address: "127.0.0.4:2181", + Username: "user1", + Password: "pwd1", + }, + }, + References: map[string]*ReferenceConfig{ + "MockService": { + InterfaceName: "com.MockService", + Protocol: "mock", + Cluster: "failover", + Loadbalance: "random", + Retries: 3, + Group: "huadong_idc", + Version: "1.0.0", + Methods: []*MethodConfig{ + { + InterfaceId: "MockService", + InterfaceName: "com.MockService", + Name: "GetUser", + Retries: 2, + Loadbalance: "random", + }, + { + InterfaceId: "MockService", + InterfaceName: "com.MockService", + Name: "GetUser1", + Retries: 2, + Loadbalance: "random", + }, + }, + }, + }, + } + + c.SetFatherConfig(father) + c.fresh() + assert.Equal(t, "mock100", father.Registries["shanghai_reg1"].Protocol) + assert.Equal(t, int64(10), father.References["MockService"].Retries) + + assert.Equal(t, int64(10), father.References["MockService"].Methods[0].Retries) + assert.Equal(t, &[]bool{true}[0], father.Check) + assert.Equal(t, "dubbo", father.ApplicationConfig.Name) +} + +func Test_refresh_singleRegistry(t *testing.T) { + c := &BaseConfig{} + mockMap := map[string]string{} + mockMap["dubbo.registry.address"] = "mock100://127.0.0.1:2181" + mockMap["dubbo.reference.com.MockService.MockService.retries"] = "10" + mockMap["dubbo.com.MockService.MockService.GetUser.retries"] = "10" + mockMap["dubbo.consumer.check"] = "false" + mockMap["dubbo.application.name"] = "dubbo" + + config.GetEnvInstance().UpdateExternalConfigMap(mockMap) + + father := &ConsumerConfig{ + Check: &[]bool{true}[0], + ApplicationConfig: &ApplicationConfig{ + Organization: "dubbo_org", + Name: "dubbo", + Module: "module", + Version: "2.6.0", + Owner: "dubbo", + Environment: "test"}, + Registries: map[string]*RegistryConfig{}, + Registry: &RegistryConfig{}, + References: map[string]*ReferenceConfig{ + "MockService": { + InterfaceName: "com.MockService", + Protocol: "mock", + Cluster: "failover", + Loadbalance: "random", + Retries: 3, + Group: "huadong_idc", + Version: "1.0.0", + Methods: []*MethodConfig{ + { + InterfaceId: "MockService", + InterfaceName: "com.MockService", + Name: "GetUser", + Retries: 2, + Loadbalance: "random", + }, + { + InterfaceId: "MockService", + InterfaceName: "com.MockService", + Name: "GetUser1", + Retries: 2, + Loadbalance: "random", + }, + }, + }, + }, + } + + c.SetFatherConfig(father) + c.fresh() + assert.Equal(t, "mock100://127.0.0.1:2181", father.Registry.Address) + assert.Equal(t, int64(10), father.References["MockService"].Retries) + + assert.Equal(t, int64(10), father.References["MockService"].Methods[0].Retries) + assert.Equal(t, &[]bool{false}[0], father.Check) + assert.Equal(t, "dubbo", father.ApplicationConfig.Name) +} + func Test_refreshProvider(t *testing.T) { c := &BaseConfig{} mockMap := map[string]string{} @@ -233,7 +389,7 @@ func Test_startConfigCenter(t *testing.T) { }} err := c.startConfigCenter(context.Background()) assert.NoError(t, err) - b, v := config.GetEnvInstance().Configuration().Front().Value.(*config.InmemoryConfiguration).GetProperty("dubbo.application.organization") + b, v := config.GetEnvInstance().Configuration().Back().Value.(*config.InmemoryConfiguration).GetProperty("dubbo.application.organization") assert.True(t, b) assert.Equal(t, "ikurento.com", v) } diff --git a/config/config_center_config.go b/config/config_center_config.go index 47efce126..e7bbd8e24 100644 --- a/config/config_center_config.go +++ b/config/config_center_config.go @@ -23,14 +23,15 @@ import ( ) type ConfigCenterConfig struct { - context context.Context - Protocol string `required:"true" yaml:"protocol" json:"protocol,omitempty"` - Address string `yaml:"address" json:"address,omitempty"` - Cluster string `yaml:"cluster" json:"cluster,omitempty"` - Group string `default:"dubbo" yaml:"group" json:"group,omitempty"` - Username string `yaml:"username" json:"username,omitempty"` - Password string `yaml:"password" json:"password,omitempty"` - ConfigFile string `default:"dubbo.properties" yaml:"config_file" json:"config_file,omitempty"` - TimeoutStr string `yaml:"timeout" json:"timeout,omitempty"` - timeout time.Duration + context context.Context + Protocol string `required:"true" yaml:"protocol" json:"protocol,omitempty"` + Address string `yaml:"address" json:"address,omitempty"` + Cluster string `yaml:"cluster" json:"cluster,omitempty"` + Group string `default:"dubbo" yaml:"group" json:"group,omitempty"` + Username string `yaml:"username" json:"username,omitempty"` + Password string `yaml:"password" json:"password,omitempty"` + ConfigFile string `default:"dubbo.properties" yaml:"config_file" json:"config_file,omitempty"` + AppConfigFile string `yaml:"app_config_file" json:"app_config_file,omitempty"` + TimeoutStr string `yaml:"timeout" json:"timeout,omitempty"` + timeout time.Duration } diff --git a/config/config_loader.go b/config/config_loader.go index c5127c8c4..8561828ae 100644 --- a/config/config_loader.go +++ b/config/config_loader.go @@ -54,6 +54,11 @@ func init() { providerConfig = nil } } +func checkRegistries(registries map[string]*RegistryConfig, singleRegistry *RegistryConfig) { + if len(registries) == 0 && singleRegistry != nil { + registries[constant.DEFAULT_KEY] = singleRegistry + } +} // Dubbo Init func Load() { @@ -64,6 +69,7 @@ func Load() { if err := configCenterRefreshConsumer(); err != nil { logger.Errorf("[consumer config center refresh] %#v", err) } + checkRegistries(consumerConfig.Registries, consumerConfig.Registry) for key, ref := range consumerConfig.References { if ref.Generic { genericService := NewGenericService(key) @@ -116,6 +122,7 @@ func Load() { if err := configCenterRefreshProvider(); err != nil { logger.Errorf("[provider config center refresh] %#v", err) } + checkRegistries(providerConfig.Registries, providerConfig.Registry) for key, svs := range providerConfig.Services { rpcService := GetProviderService(key) if rpcService == nil { diff --git a/config/config_loader_test.go b/config/config_loader_test.go index 107fea0b1..3562bf5a1 100644 --- a/config/config_loader_test.go +++ b/config/config_loader_test.go @@ -29,6 +29,8 @@ import ( import ( "github.com/apache/dubbo-go/cluster/cluster_impl" "github.com/apache/dubbo-go/common" + "github.com/apache/dubbo-go/common/config" + "github.com/apache/dubbo-go/common/constant" "github.com/apache/dubbo-go/common/extension" "github.com/apache/dubbo-go/common/proxy/proxy_factory" "github.com/apache/dubbo-go/config_center" @@ -58,8 +60,36 @@ func TestConfigLoader(t *testing.T) { } func TestLoad(t *testing.T) { - doInit() - doinit() + doInitConsumer() + doInitProvider() + + ms := &MockService{} + SetConsumerService(ms) + SetProviderService(ms) + + extension.SetProtocol("registry", GetProtocol) + extension.SetCluster("registryAware", cluster_impl.NewRegistryAwareCluster) + extension.SetProxyFactory("default", proxy_factory.NewDefaultProxyFactory) + + Load() + + assert.Equal(t, ms, GetRPCService(ms.Reference())) + ms2 := &struct { + MockService + }{} + RPCService(ms2) + assert.NotEqual(t, ms2, GetRPCService(ms2.Reference())) + + conServices = map[string]common.RPCService{} + proServices = map[string]common.RPCService{} + common.ServiceMap.UnRegister("mock", "MockService") + consumerConfig = nil + providerConfig = nil +} + +func TestLoadWithSingleReg(t *testing.T) { + doInitConsumerWithSingleRegistry() + doInitProviderWithSingleRegistry() ms := &MockService{} SetConsumerService(ms) @@ -86,8 +116,8 @@ func TestLoad(t *testing.T) { } func TestWithNoRegLoad(t *testing.T) { - doInit() - doinit() + doInitConsumer() + doInitProvider() providerConfig.Services["MockService"].Registry = "" consumerConfig.References["MockService"].Registry = "" ms := &MockService{} @@ -145,3 +175,58 @@ func TestConfigLoaderWithConfigCenter(t *testing.T) { assert.Equal(t, "127.0.0.1:2181", consumerConfig.Registries["hangzhouzk"].Address) } + +func TestConfigLoaderWithConfigCenterSingleRegistry(t *testing.T) { + consumerConfig = nil + providerConfig = nil + config.NewEnvInstance() + extension.SetConfigCenterFactory("mock", func() config_center.DynamicConfigurationFactory { + return &config_center.MockDynamicConfigurationFactory{Content: ` + dubbo.consumer.request_timeout=5s + dubbo.consumer.connect_timeout=5s + dubbo.application.organization=ikurento.com + dubbo.application.name=BDTService + dubbo.application.module=dubbogo user-info server + dubbo.application.version=0.0.1 + dubbo.application.owner=ZX + dubbo.application.environment=dev + dubbo.registry.address=mock://127.0.0.1:2182 + dubbo.service.com.ikurento.user.UserProvider.protocol=dubbo + dubbo.service.com.ikurento.user.UserProvider.interface=com.ikurento.user.UserProvider + dubbo.service.com.ikurento.user.UserProvider.loadbalance=random + dubbo.service.com.ikurento.user.UserProvider.warmup=100 + dubbo.service.com.ikurento.user.UserProvider.cluster=failover + dubbo.protocols.jsonrpc1.name=jsonrpc + dubbo.protocols.jsonrpc1.ip=127.0.0.1 + dubbo.protocols.jsonrpc1.port=20001 +`} + }) + + conPath, err := filepath.Abs("./testdata/consumer_config_with_configcenter.yml") + assert.NoError(t, err) + proPath, err := filepath.Abs("./testdata/provider_config.yml") + assert.NoError(t, err) + + assert.Nil(t, consumerConfig) + assert.Equal(t, ConsumerConfig{}, GetConsumerConfig()) + assert.Nil(t, providerConfig) + assert.Equal(t, ProviderConfig{}, GetProviderConfig()) + + err = ConsumerInit(conPath) + configCenterRefreshConsumer() + checkRegistries(consumerConfig.Registries, consumerConfig.Registry) + assert.NoError(t, err) + err = ProviderInit(proPath) + configCenterRefreshProvider() + checkRegistries(providerConfig.Registries, providerConfig.Registry) + assert.NoError(t, err) + + assert.NotNil(t, consumerConfig) + assert.NotEqual(t, ConsumerConfig{}, GetConsumerConfig()) + assert.NotNil(t, providerConfig) + assert.NotEqual(t, ProviderConfig{}, GetProviderConfig()) + + assert.Equal(t, "BDTService", consumerConfig.ApplicationConfig.Name) + assert.Equal(t, "mock://127.0.0.1:2182", consumerConfig.Registries[constant.DEFAULT_KEY].Address) + +} diff --git a/config/consumer_config.go b/config/consumer_config.go index ebeb7fe75..48d1a2760 100644 --- a/config/consumer_config.go +++ b/config/consumer_config.go @@ -51,6 +51,7 @@ type ConsumerConfig struct { ProxyFactory string `yaml:"proxy_factory" default:"default" json:"proxy_factory,omitempty" property:"proxy_factory"` Check *bool `yaml:"check" json:"check,omitempty" property:"check"` + Registry *RegistryConfig `yaml:"registry" json:"registry,omitempty" property:"registry"` Registries map[string]*RegistryConfig `yaml:"registries" json:"registries,omitempty" property:"registries"` References map[string]*ReferenceConfig `yaml:"references" json:"references,omitempty" property:"references"` ProtocolConf interface{} `yaml:"protocol_conf" json:"protocol_conf,omitempty" property:"protocol_conf"` diff --git a/config/provider_config.go b/config/provider_config.go index db8abaf73..726d05ae6 100644 --- a/config/provider_config.go +++ b/config/provider_config.go @@ -42,6 +42,7 @@ type ProviderConfig struct { ProxyFactory string `yaml:"proxy_factory" default:"default" json:"proxy_factory,omitempty" property:"proxy_factory"` ApplicationConfig *ApplicationConfig `yaml:"application_config" json:"application_config,omitempty" property:"application_config"` + Registry *RegistryConfig `yaml:"registry" json:"registry,omitempty" property:"registry"` Registries map[string]*RegistryConfig `yaml:"registries" json:"registries,omitempty" property:"registries"` Services map[string]*ServiceConfig `yaml:"services" json:"services,omitempty" property:"services"` Protocols map[string]*ProtocolConfig `yaml:"protocols" json:"protocols,omitempty" property:"protocols"` diff --git a/config/reference_config_test.go b/config/reference_config_test.go index d36fa04d7..4dbdd31d8 100644 --- a/config/reference_config_test.go +++ b/config/reference_config_test.go @@ -36,7 +36,7 @@ import ( var regProtocol protocol.Protocol -func doInit() { +func doInitConsumer() { consumerConfig = &ConsumerConfig{ ApplicationConfig: &ApplicationConfig{ Organization: "dubbo_org", @@ -110,8 +110,53 @@ func doInit() { } } +func doInitConsumerWithSingleRegistry() { + consumerConfig = &ConsumerConfig{ + ApplicationConfig: &ApplicationConfig{ + Organization: "dubbo_org", + Name: "dubbo", + Module: "module", + Version: "2.6.0", + Owner: "dubbo", + Environment: "test"}, + Registry: &RegistryConfig{ + Address: "mock://27.0.0.1:2181", + Username: "user1", + Password: "pwd1", + }, + Registries: map[string]*RegistryConfig{}, + References: map[string]*ReferenceConfig{ + "MockService": { + Params: map[string]string{ + "serviceid": "soa.mock", + "forks": "5", + }, + InterfaceName: "com.MockService", + Protocol: "mock", + Cluster: "failover", + Loadbalance: "random", + Retries: 3, + Group: "huadong_idc", + Version: "1.0.0", + Methods: []*MethodConfig{ + { + Name: "GetUser", + Retries: 2, + Loadbalance: "random", + }, + { + Name: "GetUser1", + Retries: 2, + Loadbalance: "random", + }, + }, + }, + }, + } +} + func Test_ReferMultireg(t *testing.T) { - doInit() + doInitConsumer() extension.SetProtocol("registry", GetProtocol) extension.SetCluster("registryAware", cluster_impl.NewRegistryAwareCluster) @@ -124,7 +169,7 @@ func Test_ReferMultireg(t *testing.T) { } func Test_Refer(t *testing.T) { - doInit() + doInitConsumer() extension.SetProtocol("registry", GetProtocol) extension.SetCluster("registryAware", cluster_impl.NewRegistryAwareCluster) @@ -137,7 +182,7 @@ func Test_Refer(t *testing.T) { consumerConfig = nil } func Test_ReferP2P(t *testing.T) { - doInit() + doInitConsumer() extension.SetProtocol("dubbo", GetProtocol) m := consumerConfig.References["MockService"] m.Url = "dubbo://127.0.0.1:20000" @@ -151,7 +196,7 @@ func Test_ReferP2P(t *testing.T) { } func Test_ReferMultiP2P(t *testing.T) { - doInit() + doInitConsumer() extension.SetProtocol("dubbo", GetProtocol) m := consumerConfig.References["MockService"] m.Url = "dubbo://127.0.0.1:20000;dubbo://127.0.0.2:20000" @@ -165,7 +210,7 @@ func Test_ReferMultiP2P(t *testing.T) { } func Test_ReferMultiP2PWithReg(t *testing.T) { - doInit() + doInitConsumer() extension.SetProtocol("dubbo", GetProtocol) extension.SetProtocol("registry", GetProtocol) m := consumerConfig.References["MockService"] @@ -180,7 +225,7 @@ func Test_ReferMultiP2PWithReg(t *testing.T) { } func Test_Implement(t *testing.T) { - doInit() + doInitConsumer() extension.SetProtocol("registry", GetProtocol) extension.SetCluster("registryAware", cluster_impl.NewRegistryAwareCluster) for _, reference := range consumerConfig.References { @@ -193,7 +238,7 @@ func Test_Implement(t *testing.T) { } func Test_Forking(t *testing.T) { - doInit() + doInitConsumer() extension.SetProtocol("dubbo", GetProtocol) extension.SetProtocol("registry", GetProtocol) m := consumerConfig.References["MockService"] diff --git a/config/registry_config.go b/config/registry_config.go index 0abdab810..480377754 100644 --- a/config/registry_config.go +++ b/config/registry_config.go @@ -43,7 +43,7 @@ type RegistryConfig struct { } func (*RegistryConfig) Prefix() string { - return constant.RegistryConfigPrefix + return constant.RegistryConfigPrefix + "|" + constant.SingleRegistryConfigPrefix } func loadRegistries(targetRegistries string, registries map[string]*RegistryConfig, roleType common.RoleType) []*common.URL { @@ -73,27 +73,22 @@ func loadRegistries(targetRegistries string, registries map[string]*RegistryConf url common.URL err error ) - if addresses := strings.Split(registryConf.Address, ","); len(addresses) > 1 { - url, err = common.NewURL( - context.Background(), - constant.REGISTRY_PROTOCOL+"://"+addresses[0], - common.WithParams(registryConf.getUrlMap(roleType)), - common.WithUsername(registryConf.Username), - common.WithPassword(registryConf.Password), - common.WithLocation(registryConf.Address), - ) - } else { - url, err = common.NewURL( - context.Background(), - constant.REGISTRY_PROTOCOL+"://"+registryConf.Address, - common.WithParams(registryConf.getUrlMap(roleType)), - common.WithUsername(registryConf.Username), - common.WithPassword(registryConf.Password), - ) - } + + addresses := strings.Split(registryConf.Address, ",") + address := addresses[0] + address = traslateRegistryConf(address, registryConf) + url, err = common.NewURL( + context.Background(), + constant.REGISTRY_PROTOCOL+"://"+address, + common.WithParams(registryConf.getUrlMap(roleType)), + common.WithUsername(registryConf.Username), + common.WithPassword(registryConf.Password), + common.WithLocation(registryConf.Address), + ) if err != nil { - logger.Errorf("The registry id:%s url is invalid ,and will skip the registry, error: %#v", k, err) + logger.Errorf("The registry id:%s url is invalid , error: %#v", k, err) + panic(err) } else { urls = append(urls, &url) } @@ -115,3 +110,17 @@ func (regconfig *RegistryConfig) getUrlMap(roleType common.RoleType) url.Values } return urlMap } + +func traslateRegistryConf(address string, registryConf *RegistryConfig) string { + if strings.Contains(address, "://") { + translatedUrl, err := url.Parse(address) + if err != nil { + logger.Errorf("The registry url is invalid , error: %#v", err) + panic(err) + } + address = translatedUrl.Host + registryConf.Protocol = translatedUrl.Scheme + registryConf.Address = strings.Replace(registryConf.Address, translatedUrl.Scheme+"://", "", -1) + } + return address +} diff --git a/config/service_config_test.go b/config/service_config_test.go index f1de3ac08..d229ce4d2 100644 --- a/config/service_config_test.go +++ b/config/service_config_test.go @@ -25,7 +25,7 @@ import ( "github.com/apache/dubbo-go/common/extension" ) -func doinit() { +func doInitProvider() { providerConfig = &ProviderConfig{ ApplicationConfig: &ApplicationConfig{ Organization: "dubbo_org", @@ -104,8 +104,58 @@ func doinit() { } } +func doInitProviderWithSingleRegistry() { + providerConfig = &ProviderConfig{ + ApplicationConfig: &ApplicationConfig{ + Organization: "dubbo_org", + Name: "dubbo", + Module: "module", + Version: "2.6.0", + Owner: "dubbo", + Environment: "test"}, + Registry: &RegistryConfig{ + Address: "mock://127.0.0.1:2181", + Username: "user1", + Password: "pwd1", + }, + Registries: map[string]*RegistryConfig{}, + Services: map[string]*ServiceConfig{ + "MockService": { + InterfaceName: "com.MockService", + Protocol: "mock", + Cluster: "failover", + Loadbalance: "random", + Retries: 3, + Group: "huadong_idc", + Version: "1.0.0", + Methods: []*MethodConfig{ + { + Name: "GetUser", + Retries: 2, + Loadbalance: "random", + Weight: 200, + }, + { + Name: "GetUser1", + Retries: 2, + Loadbalance: "random", + Weight: 200, + }, + }, + }, + }, + Protocols: map[string]*ProtocolConfig{ + "mock": { + Name: "mock", + Ip: "127.0.0.1", + Port: "20000", + }, + }, + } +} + func Test_Export(t *testing.T) { - doinit() + doInitProvider() extension.SetProtocol("registry", GetProtocol) for i := range providerConfig.Services { diff --git a/config_center/mock_dynamic_config.go b/config_center/mock_dynamic_config.go index e8f10d45f..47b509231 100644 --- a/config_center/mock_dynamic_config.go +++ b/config_center/mock_dynamic_config.go @@ -32,7 +32,9 @@ import ( "github.com/apache/dubbo-go/remoting" ) -type MockDynamicConfigurationFactory struct{} +type MockDynamicConfigurationFactory struct { + Content string +} var ( once sync.Once @@ -44,6 +46,7 @@ func (f *MockDynamicConfigurationFactory) GetDynamicConfiguration(url *common.UR once.Do(func() { dynamicConfiguration = &MockDynamicConfiguration{listener: map[string]ConfigurationListener{}} dynamicConfiguration.SetParser(&parser.DefaultConfigurationParser{}) + dynamicConfiguration.content = ` dubbo.consumer.request_timeout=5s dubbo.consumer.connect_timeout=5s @@ -69,6 +72,9 @@ func (f *MockDynamicConfigurationFactory) GetDynamicConfiguration(url *common.UR dubbo.protocols.jsonrpc1.port=20001 ` }) + if len(f.Content) != 0 { + dynamicConfiguration.content = f.Content + } return dynamicConfiguration, err } -- GitLab