Skip to content
Snippets Groups Projects
Commit 6191550c authored by luckyxiaoqiang's avatar luckyxiaoqiang
Browse files

Improve config center

parent 52e4c97e
No related branches found
No related tags found
No related merge requests found
......@@ -72,6 +72,12 @@ func (env *Environment) UpdateExternalConfigMap(externalMap map[string]string) {
for k, v := range externalMap {
env.externalConfigMap.Store(k, v)
}
env.externalConfigMap.Range(func(key, value interface{}) bool {
if _, ok := externalMap[key.(string)]; !ok {
env.externalConfigMap.Delete(key)
}
return true
})
}
// UpdateAppExternalConfigMap updates env appExternalConfigMap field
......@@ -79,15 +85,21 @@ func (env *Environment) UpdateAppExternalConfigMap(externalMap map[string]string
for k, v := range externalMap {
env.appExternalConfigMap.Store(k, v)
}
env.appExternalConfigMap.Range(func(key, value interface{}) bool {
if _, ok := externalMap[key.(string)]; !ok {
env.appExternalConfigMap.Delete(key)
}
return true
})
}
// Configuration puts externalConfigMap and appExternalConfigMap into list
// List represents a doubly linked list.
func (env *Environment) Configuration() *list.List {
cfgList := list.New()
// The sequence would be: SystemConfiguration -> ExternalConfiguration -> AppExternalConfiguration -> AbstractConfig -> PropertiesConfiguration
cfgList.PushFront(newInmemoryConfiguration(&(env.externalConfigMap)))
cfgList.PushFront(newInmemoryConfiguration(&(env.appExternalConfigMap)))
// The sequence would be: SystemConfiguration -> AppExternalConfiguration -> ExternalConfiguration -> AbstractConfig -> PropertiesConfiguration
cfgList.PushBack(newInmemoryConfiguration(&(env.appExternalConfigMap)))
cfgList.PushBack(newInmemoryConfiguration(&(env.externalConfigMap)))
return cfgList
}
......
......@@ -34,6 +34,29 @@ func TestEnvironmentUpdateExternalConfigMap(t *testing.T) {
v, ok := GetEnvInstance().externalConfigMap.Load("1")
assert.True(t, ok)
assert.Equal(t, "2", v)
GetEnvInstance().UpdateExternalConfigMap(map[string]string{"a": "b"})
v, ok = GetEnvInstance().externalConfigMap.Load("a")
assert.True(t, ok)
assert.Equal(t, "b", v)
v, ok = GetEnvInstance().externalConfigMap.Load("1")
assert.False(t, ok)
assert.Equal(t, nil, v)
}
func TestEnvironmentUpdateAppExternalConfigMap(t *testing.T) {
GetEnvInstance().UpdateAppExternalConfigMap(map[string]string{"1": "2"})
v, ok := GetEnvInstance().appExternalConfigMap.Load("1")
assert.True(t, ok)
assert.Equal(t, "2", v)
GetEnvInstance().UpdateAppExternalConfigMap(map[string]string{"a": "b"})
v, ok = GetEnvInstance().appExternalConfigMap.Load("a")
assert.True(t, ok)
assert.Equal(t, "b", v)
v, ok = GetEnvInstance().appExternalConfigMap.Load("1")
assert.False(t, ok)
assert.Equal(t, nil, v)
}
func TestEnvironmentConfigurationAndGetProperty(t *testing.T) {
......
......@@ -50,6 +50,9 @@ type BaseConfig struct {
EventDispatcherType string `default:"direct" yaml:"event_dispatcher_type" json:"event_dispatcher_type,omitempty"`
MetricConfig *MetricConfig `yaml:"metrics" json:"metrics,omitempty"`
fileStream *bytes.Buffer
// cache file used to store the current used configurations.
CacheFile string `yaml:"cache_file" json:"cache_file,omitempty" property:"cache_file"`
}
// nolint
......@@ -240,7 +243,7 @@ func setFieldValue(val reflect.Value, id reflect.Value, config *config.InmemoryC
func (c *BaseConfig) fresh() {
configList := config.GetEnvInstance().Configuration()
for element := configList.Front(); element != nil; element = element.Next() {
for element := configList.Back(); element != nil; element = element.Prev() {
cfg := element.Value.(*config.InmemoryConfiguration)
c.freshInternalConfig(cfg)
}
......
......@@ -112,6 +112,7 @@ func TestRefresh(t *testing.T) {
mockMap["dubbo.shutdown.timeout"] = "12s"
config.GetEnvInstance().UpdateExternalConfigMap(mockMap)
config.GetEnvInstance().UpdateAppExternalConfigMap(map[string]string{})
father := &ConsumerConfig{
Check: &[]bool{true}[0],
......@@ -144,9 +145,10 @@ func TestAppExternalRefresh(t *testing.T) {
mockMap := getMockMap()
mockMap["dubbo.reference.com.MockService.retries"] = "5"
config.GetEnvInstance().UpdateAppExternalConfigMap(mockMap)
mockMap["dubbo.consumer.check"] = "true"
config.GetEnvInstance().UpdateExternalConfigMap(mockMap)
mockMap["dubbo.consumer.check"] = "true"
config.GetEnvInstance().UpdateAppExternalConfigMap(mockMap)
father := &ConsumerConfig{
Check: &[]bool{true}[0],
BaseConfig: BaseConfig{
......@@ -172,9 +174,9 @@ func TestAppExternalWithoutIDRefresh(t *testing.T) {
delete(mockMap, "dubbo.reference.com.MockService.MockService.retries")
mockMap["dubbo.reference.com.MockService.retries"] = "10"
config.GetEnvInstance().UpdateAppExternalConfigMap(mockMap)
mockMap["dubbo.consumer.check"] = "true"
config.GetEnvInstance().UpdateExternalConfigMap(mockMap)
mockMap["dubbo.consumer.check"] = "true"
config.GetEnvInstance().UpdateAppExternalConfigMap(mockMap)
father := &ConsumerConfig{
Check: &[]bool{true}[0],
BaseConfig: BaseConfig{
......@@ -204,6 +206,7 @@ func TestRefreshSingleRegistry(t *testing.T) {
mockMap["dubbo.application.name"] = "dubbo"
config.GetEnvInstance().UpdateExternalConfigMap(mockMap)
config.GetEnvInstance().UpdateAppExternalConfigMap(map[string]string{})
father := &ConsumerConfig{
Check: &[]bool{true}[0],
......@@ -235,6 +238,7 @@ func TestRefreshProvider(t *testing.T) {
mockMap["dubbo.protocols.jsonrpc1.port"] = "20001"
config.GetEnvInstance().UpdateExternalConfigMap(mockMap)
config.GetEnvInstance().UpdateAppExternalConfigMap(map[string]string{})
father := &ProviderConfig{
BaseConfig: BaseConfig{
......
......@@ -162,11 +162,11 @@ func (b *configCenter) prepareEnvironment(baseConfig BaseConfig, configCenterUrl
// appGroup config file
if len(appContent) != 0 {
appMapConent, err := dynamicConfig.Parser().Parse(appContent)
appMapContent, err := dynamicConfig.Parser().Parse(appContent)
if err != nil {
return perrors.WithStack(err)
}
config.GetEnvInstance().UpdateAppExternalConfigMap(appMapConent)
config.GetEnvInstance().UpdateAppExternalConfigMap(appMapContent)
}
return nil
......
......@@ -19,6 +19,7 @@ package config
import (
"fmt"
"io/ioutil"
"log"
"os"
"reflect"
......@@ -37,6 +38,7 @@ import (
"github.com/apache/dubbo-go/common/extension"
"github.com/apache/dubbo-go/common/logger"
_ "github.com/apache/dubbo-go/common/observer/dispatcher"
"github.com/apache/dubbo-go/common/yaml"
"github.com/apache/dubbo-go/registry"
)
......@@ -138,6 +140,17 @@ func loadConsumerConfig() {
ref.Implement(rpcService)
}
// Write current configuration to cache file.
if consumerConfig.CacheFile != "" {
if data, err := yaml.MarshalYML(consumerConfig); err != nil {
logger.Errorf("Marshal consumer config err: %s", err.Error())
} else {
if err := ioutil.WriteFile(consumerConfig.CacheFile, data, 0666); err != nil {
logger.Errorf("Write consumer config cache file err: %s", err.Error())
}
}
}
// wait for invoker is available, if wait over default 3s, then panic
var count int
for {
......@@ -194,6 +207,17 @@ func loadProviderConfig() {
}
checkRegistries(providerConfig.Registries, providerConfig.Registry)
// Write the current configuration to cache file.
if providerConfig.CacheFile != "" {
if data, err := yaml.MarshalYML(providerConfig); err != nil {
logger.Errorf("Marshal provider config err: %s", err.Error())
} else {
if err := ioutil.WriteFile(providerConfig.CacheFile, data, 0666); err != nil {
logger.Errorf("Write provider config cache file err: %s", err.Error())
}
}
}
for key, svs := range providerConfig.Services {
rpcService := GetProviderService(key)
if rpcService == nil {
......
......@@ -43,9 +43,9 @@ const (
// ConsumerConfig is Consumer default configuration
type ConsumerConfig struct {
BaseConfig `yaml:",inline"`
configCenter
Filter string `yaml:"filter" json:"filter,omitempty" property:"filter"`
BaseConfig `yaml:",inline"`
configCenter `yaml:"-"`
Filter string `yaml:"filter" json:"filter,omitempty" property:"filter"`
// client
Connect_Timeout string `default:"100ms" yaml:"connect_timeout" json:"connect_timeout,omitempty" property:"connect_timeout"`
ConnectTimeout time.Duration
......
......@@ -37,8 +37,8 @@ import (
// ProviderConfig is the default configuration of service provider
type ProviderConfig struct {
BaseConfig `yaml:",inline"`
configCenter
BaseConfig `yaml:",inline"`
configCenter `yaml:"-"`
Filter string `yaml:"filter" json:"filter,omitempty" property:"filter"`
ProxyFactory string `yaml:"proxy_factory" default:"default" json:"proxy_factory,omitempty" property:"proxy_factory"`
Services map[string]*ServiceConfig `yaml:"services" json:"services,omitempty" property:"services"`
......
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment