From 8d674556f447c20a9843292ce7985efb39bf6a7c Mon Sep 17 00:00:00 2001 From: weihaoyu <444216978@qq.com> Date: Sun, 15 May 2022 14:29:31 +0800 Subject: [PATCH 01/12] add GetValueNotWait func --- go.mod | 1 + go.sum | 2 + storage/repository.go | 148 ++++++++++++++++++++++--------------- storage/repository_test.go | 42 +++++++++-- 4 files changed, 126 insertions(+), 67 deletions(-) diff --git a/go.mod b/go.mod index 1f5c1f5..7252cb7 100644 --- a/go.mod +++ b/go.mod @@ -1,6 +1,7 @@ module github.com/apolloconfig/agollo/v4 require ( + github.com/pkg/errors v0.9.1 github.com/spf13/viper v1.7.1 github.com/tevid/gohamcrest v1.1.1 ) diff --git a/go.sum b/go.sum index 3dfc818..fc6808b 100644 --- a/go.sum +++ b/go.sum @@ -130,6 +130,8 @@ github.com/pelletier/go-toml v1.2.0 h1:T5zMGML61Wp+FlcbWjRDT7yAxhJNAiPPLOFECq181 github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= +github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI= diff --git a/storage/repository.go b/storage/repository.go index 684f955..663f38c 100644 --- a/storage/repository.go +++ b/storage/repository.go @@ -24,16 +24,17 @@ import ( "sync" "sync/atomic" - "github.com/apolloconfig/agollo/v4/env/config" + "github.com/pkg/errors" "github.com/apolloconfig/agollo/v4/agcache" "github.com/apolloconfig/agollo/v4/component/log" + "github.com/apolloconfig/agollo/v4/env/config" "github.com/apolloconfig/agollo/v4/extension" "github.com/apolloconfig/agollo/v4/utils" ) const ( - //1 minute + // 1 minute configCacheExpireTime = 120 defaultNamespace = "application" @@ -47,7 +48,7 @@ type Cache struct { changeListeners *list.List } -//GetConfig 根据namespace获取apollo配置 +// GetConfig 根据namespace获取apollo配置 func (c *Cache) GetConfig(namespace string) *Config { if namespace == "" { return nil @@ -62,9 +63,9 @@ func (c *Cache) GetConfig(namespace string) *Config { return config.(*Config) } -//CreateNamespaceConfig 根据namespace初始化agollo内润配置 +// CreateNamespaceConfig 根据namespace初始化agollo内润配置 func CreateNamespaceConfig(namespace string) *Cache { - //config from apollo + // config from apollo var apolloConfigCache sync.Map config.SplitNamespaces(namespace, func(namespace string) { if _, ok := apolloConfigCache.Load(namespace); ok { @@ -89,7 +90,7 @@ func initConfig(namespace string, factory agcache.CacheFactory) *Config { return c } -//Config apollo配置项 +// Config apollo配置项 type Config struct { namespace string cache agcache.CacheInterface @@ -97,45 +98,63 @@ type Config struct { waitInit sync.WaitGroup } -//GetIsInit 获取标志 +// GetIsInit 获取标志 func (c *Config) GetIsInit() bool { return c.isInit.Load().(bool) } -//GetWaitInit 获取标志 +// GetWaitInit 获取标志 func (c *Config) GetWaitInit() *sync.WaitGroup { return &c.waitInit } -//GetCache 获取cache +// GetCache 获取cache func (c *Config) GetCache() agcache.CacheInterface { return c.cache } -//getConfigValue 获取配置值 -func (c *Config) getConfigValue(key string) interface{} { +// getConfigValue 获取配置值 +func (c *Config) getConfigValue(key string, waitInit bool) (value interface{}, err error) { b := c.GetIsInit() if !b { + if !waitInit { + err = errors.Errorf("get config fail, init not done") + return + } c.waitInit.Wait() } if c.cache == nil { - log.Errorf("get config value fail!namespace:%s is not exist!", c.namespace) - return nil + err = errors.Errorf("get config value fail!namespace:%s is not exist!", c.namespace) + return + } + + if value, err = c.cache.Get(key); err != nil { + err = errors.Errorf("get config value fail!key:%s,err:%s", key, err) + return } - value, err := c.cache.Get(key) + return +} + +// GetValueNotWait 获取配置值,不阻塞(string) +func (c *Config) GetValueNotWait(key string) (string, error) { + value, err := c.getConfigValue(key, false) if err != nil { - log.Errorf("get config value fail!key:%s,err:%s", key, err) - return nil + return utils.Empty, err } - return value + v, ok := value.(string) + if !ok { + return utils.Empty, errors.Errorf("convert to string fail ! source type:%T", value) + } + return v, nil } -//GetValue 获取配置值(string) +// GetValue 获取配置值(string) func (c *Config) GetValue(key string) string { - value := c.getConfigValue(key) - if value == nil { + value, err := c.getConfigValue(key, true) + if err != nil { + log.Errorf(err.Error()) return utils.Empty } @@ -147,7 +166,7 @@ func (c *Config) GetValue(key string) string { return v } -//GetStringValue 获取配置值(string),获取不到则取默认值 +// GetStringValue 获取配置值(string),获取不到则取默认值 func (c *Config) GetStringValue(key string, defaultValue string) string { value := c.GetValue(key) if value == utils.Empty { @@ -157,12 +176,14 @@ func (c *Config) GetStringValue(key string, defaultValue string) string { return value } -//GetStringSliceValue 获取配置值([]string) +// GetStringSliceValue 获取配置值([]string) func (c *Config) GetStringSliceValue(key string, defaultValue []string) []string { - value := c.getConfigValue(key) - if value == nil { + value, err := c.getConfigValue(key, true) + if err != nil { + log.Errorf(err.Error()) return defaultValue } + v, ok := value.([]string) if !ok { log.Debug("convert to []string fail ! source type:%T", value) @@ -171,12 +192,14 @@ func (c *Config) GetStringSliceValue(key string, defaultValue []string) []string return v } -//GetIntSliceValue 获取配置值([]int) +// GetIntSliceValue 获取配置值([]int) func (c *Config) GetIntSliceValue(key string, defaultValue []int) []int { - value := c.getConfigValue(key) - if value == nil { + value, err := c.getConfigValue(key, true) + if err != nil { + log.Errorf(err.Error()) return defaultValue } + v, ok := value.([]int) if !ok { log.Debug("convert to []int fail ! source type:%T", value) @@ -185,12 +208,14 @@ func (c *Config) GetIntSliceValue(key string, defaultValue []int) []int { return v } -//GetSliceValue 获取配置值([]interface) +// GetSliceValue 获取配置值([]interface) func (c *Config) GetSliceValue(key string, defaultValue []interface{}) []interface{} { - value := c.getConfigValue(key) - if value == nil { + value, err := c.getConfigValue(key, true) + if err != nil { + log.Errorf(err.Error()) return defaultValue } + v, ok := value.([]interface{}) if !ok { log.Debug("convert to []interface{} fail ! source type:%T", value) @@ -199,13 +224,14 @@ func (c *Config) GetSliceValue(key string, defaultValue []interface{}) []interfa return v } -//GetIntValue 获取配置值(int),获取不到则取默认值 +// GetIntValue 获取配置值(int),获取不到则取默认值 func (c *Config) GetIntValue(key string, defaultValue int) int { - value := c.getConfigValue(key) - - if value == nil { + value, err := c.getConfigValue(key, true) + if err != nil { + log.Errorf(err.Error()) return defaultValue } + v, ok := value.(int) if !ok { log.Debug("convert to int fail ! source type:%T", value) @@ -214,11 +240,11 @@ func (c *Config) GetIntValue(key string, defaultValue int) int { return v } -//GetFloatValue 获取配置值(float),获取不到则取默认值 +// GetFloatValue 获取配置值(float),获取不到则取默认值 func (c *Config) GetFloatValue(key string, defaultValue float64) float64 { - value := c.getConfigValue(key) - - if value == nil { + value, err := c.getConfigValue(key, true) + if err != nil { + log.Errorf(err.Error()) return defaultValue } @@ -230,9 +256,13 @@ func (c *Config) GetFloatValue(key string, defaultValue float64) float64 { return v } -//GetBoolValue 获取配置值(bool),获取不到则取默认值 +// GetBoolValue 获取配置值(bool),获取不到则取默认值 func (c *Config) GetBoolValue(key string, defaultValue bool) bool { - value := c.getConfigValue(key) + value, err := c.getConfigValue(key, true) + if err != nil { + log.Errorf(err.Error()) + return defaultValue + } v, ok := value.(bool) if !ok { @@ -242,8 +272,8 @@ func (c *Config) GetBoolValue(key string, defaultValue bool) bool { return v } -//UpdateApolloConfig 根据config server返回的内容更新内存 -//并判断是否需要写备份文件 +// UpdateApolloConfig 根据config server返回的内容更新内存 +// 并判断是否需要写备份文件 func (c *Cache) UpdateApolloConfig(apolloConfig *config.ApolloConfig, appConfigFunc func() config.AppConfig) { if apolloConfig == nil { log.Error("apolloConfig is null,can't update!") @@ -251,33 +281,33 @@ func (c *Cache) UpdateApolloConfig(apolloConfig *config.ApolloConfig, appConfigF } appConfig := appConfigFunc() - //update apollo connection config + // update apollo connection config appConfig.SetCurrentApolloConfig(&apolloConfig.ApolloConnConfig) - //get change list + // get change list changeList := c.UpdateApolloConfigCache(apolloConfig.Configurations, configCacheExpireTime, apolloConfig.NamespaceName) notify := appConfig.GetNotificationsMap().GetNotify(apolloConfig.NamespaceName) - //push all newest changes + // push all newest changes c.pushNewestChanges(apolloConfig.NamespaceName, apolloConfig.Configurations, notify) if len(changeList) > 0 { - //create config change event base on change list + // create config change event base on change list event := createConfigChangeEvent(changeList, apolloConfig.NamespaceName, notify) - //push change event to channel + // push change event to channel c.pushChangeEvent(event) } if appConfig.GetIsBackupConfig() { - //write config file async + // write config file async apolloConfig.AppID = appConfig.AppID go extension.GetFileHandler().WriteConfigFile(apolloConfig, appConfig.GetBackupConfigPath()) } } -//UpdateApolloConfigCache 根据conf[ig server返回的内容更新内存 +// UpdateApolloConfigCache 根据conf[ig server返回的内容更新内存 func (c *Cache) UpdateApolloConfigCache(configurations map[string]interface{}, expireTime int, namespace string) map[string]*ConfigChange { config := c.GetConfig(namespace) if config == nil { @@ -302,7 +332,7 @@ func (c *Cache) UpdateApolloConfigCache(configurations map[string]interface{}, e return nil } - //get old keys + // get old keys mp := map[string]bool{} config.cache.Range(func(key, value interface{}) bool { mp[key.(string)] = true @@ -315,12 +345,12 @@ func (c *Cache) UpdateApolloConfigCache(configurations map[string]interface{}, e // update new // keys for key, value := range configurations { - //key state insert or update - //insert + // key state insert or update + // insert if !mp[key] { changes[key] = createAddConfigChange(value) } else { - //update + // update oldValue, _ := config.cache.Get(key) if !reflect.DeepEqual(oldValue, value) { changes[key] = createModifyConfigChange(oldValue, value) @@ -336,7 +366,7 @@ func (c *Cache) UpdateApolloConfigCache(configurations map[string]interface{}, e // remove del keys for key := range mp { - //get old value and del + // get old value and del oldValue, _ := config.cache.Get(key) changes[key] = createDeletedConfigChange(oldValue) @@ -347,7 +377,7 @@ func (c *Cache) UpdateApolloConfigCache(configurations map[string]interface{}, e return changes } -//GetContent 获取配置文件内容 +// GetContent 获取配置文件内容 func (c *Config) GetContent() string { return convertToProperties(c.cache) } @@ -364,12 +394,12 @@ func convertToProperties(cache agcache.CacheInterface) string { return properties } -//GetDefaultNamespace 获取默认命名空间 +// GetDefaultNamespace 获取默认命名空间 func GetDefaultNamespace() string { return defaultNamespace } -//AddChangeListener 增加变更监控 +// AddChangeListener 增加变更监控 func (c *Cache) AddChangeListener(listener ChangeListener) { if listener == nil { return @@ -377,7 +407,7 @@ func (c *Cache) AddChangeListener(listener ChangeListener) { c.changeListeners.PushBack(listener) } -//RemoveChangeListener 增加变更监控 +// RemoveChangeListener 增加变更监控 func (c *Cache) RemoveChangeListener(listener ChangeListener) { if listener == nil { return @@ -395,7 +425,7 @@ func (c *Cache) GetChangeListeners() *list.List { return c.changeListeners } -//push config change event +// push config change event func (c *Cache) pushChangeEvent(event *ChangeEvent) { c.pushChange(func(listener ChangeListener) { go listener.OnChange(event) diff --git a/storage/repository_test.go b/storage/repository_test.go index 6767cca..1b98555 100644 --- a/storage/repository_test.go +++ b/storage/repository_test.go @@ -26,6 +26,7 @@ import ( "github.com/apolloconfig/agollo/v4/env/config" jsonFile "github.com/apolloconfig/agollo/v4/env/file/json" "github.com/apolloconfig/agollo/v4/extension" + "github.com/apolloconfig/agollo/v4/utils" _ "github.com/apolloconfig/agollo/v4/agcache/memory" "github.com/apolloconfig/agollo/v4/env" @@ -36,7 +37,7 @@ import ( _ "github.com/apolloconfig/agollo/v4/utils/parse/properties" ) -//init param +// init param func init() { extension.SetCacheFactory(&memory.DefaultCacheFactory{}) extension.SetFileHandler(&jsonFile.FileHandler{}) @@ -54,7 +55,6 @@ func creatTestApolloConfig(configurations map[string]interface{}, namespace stri return *appConfig }) return c - } func TestUpdateApolloConfigNull(t *testing.T) { @@ -87,7 +87,6 @@ func TestUpdateApolloConfigNull(t *testing.T) { Assert(t, apolloConfig.Cluster, Equal(config.Cluster)) Assert(t, "", Equal(config.ReleaseKey)) Assert(t, len(apolloConfig.Configurations), Equal(5)) - } func TestGetDefaultNamespace(t *testing.T) { @@ -108,26 +107,26 @@ func TestGetConfig(t *testing.T) { config := c.GetConfig("test") Assert(t, config, NotNilVal()) - //string + // string s := config.GetStringValue("string", "s") Assert(t, s, Equal(configurations["string"])) s = config.GetStringValue("s", "s") Assert(t, s, Equal("s")) - //int + // int i := config.GetIntValue("int", 3) Assert(t, i, Equal(2)) i = config.GetIntValue("i", 3) Assert(t, i, Equal(3)) - //float + // float f := config.GetFloatValue("float", 2) Assert(t, f, Equal(1.9)) f = config.GetFloatValue("f", 2) Assert(t, f, Equal(float64(2))) - //bool + // bool b := config.GetBoolValue("bool", true) Assert(t, b, Equal(false)) @@ -143,7 +142,7 @@ func TestGetConfig(t *testing.T) { sliceInter := config.GetSliceValue("sliceInter", []interface{}{}) Assert(t, sliceInter, Equal([]interface{}{1, "2", 3})) - //content + // content content := config.GetContent() hasFloat := strings.Contains(content, "float=1") Assert(t, hasFloat, Equal(true)) @@ -225,3 +224,30 @@ func TestDispatchInRepository(t *testing.T) { _, ok = l.Keys["modify"] Assert(t, ok, Equal(false)) } + +func TestGetValueNotWait(t *testing.T) { + c := initConfig("namespace", extension.GetCacheFactory()) + + res, err := c.GetValueNotWait("namespace") + Assert(t, res, Equal(utils.Empty)) + Assert(t, err.Error(), Equal("get config fail, init not done")) + + c.isInit.Store(true) + res, err = c.GetValueNotWait("namespace") + Assert(t, res, Equal(utils.Empty)) + Assert(t, err.Error(), Equal("get config value fail!key:namespace,err:load default cache fail")) + + res, err = c.GetValueNotWait("namespace1") + Assert(t, res, Equal(utils.Empty)) + Assert(t, err.Error(), Equal("get config value fail!key:namespace1,err:load default cache fail")) + + c.cache.Set("namespace", 1, 3) + res, err = c.GetValueNotWait("namespace") + Assert(t, res, Equal(utils.Empty)) + Assert(t, err.Error(), Equal("convert to string fail ! source type:int")) + + c.cache.Set("namespace", "config", 3) + res, err = c.GetValueNotWait("namespace") + Assert(t, res, Equal("config")) + Assert(t, err, Equal(nil)) +} From a5bbb3c75529f1db905f72ce3981b3a401c5f70d Mon Sep 17 00:00:00 2001 From: weihaoyu <444216978@qq.com> Date: Mon, 16 May 2022 11:22:41 +0800 Subject: [PATCH 02/12] GetValueImmediately --- go.mod | 1 - go.sum | 3 +- storage/repository.go | 171 ++++++++++++++++++++++++++++--------- storage/repository_test.go | 66 +++++++++++--- 4 files changed, 188 insertions(+), 53 deletions(-) diff --git a/go.mod b/go.mod index 7252cb7..1f5c1f5 100644 --- a/go.mod +++ b/go.mod @@ -1,7 +1,6 @@ module github.com/apolloconfig/agollo/v4 require ( - github.com/pkg/errors v0.9.1 github.com/spf13/viper v1.7.1 github.com/tevid/gohamcrest v1.1.1 ) diff --git a/go.sum b/go.sum index fc6808b..18af665 100644 --- a/go.sum +++ b/go.sum @@ -129,9 +129,8 @@ github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FI github.com/pelletier/go-toml v1.2.0 h1:T5zMGML61Wp+FlcbWjRDT7yAxhJNAiPPLOFECq181zc= github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I= github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= -github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= -github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI= diff --git a/storage/repository.go b/storage/repository.go index 663f38c..969ecc8 100644 --- a/storage/repository.go +++ b/storage/repository.go @@ -24,8 +24,6 @@ import ( "sync" "sync/atomic" - "github.com/pkg/errors" - "github.com/apolloconfig/agollo/v4/agcache" "github.com/apolloconfig/agollo/v4/component/log" "github.com/apolloconfig/agollo/v4/env/config" @@ -114,47 +112,148 @@ func (c *Config) GetCache() agcache.CacheInterface { } // getConfigValue 获取配置值 -func (c *Config) getConfigValue(key string, waitInit bool) (value interface{}, err error) { +func (c *Config) getConfigValue(key string, waitInit bool) interface{} { b := c.GetIsInit() if !b { if !waitInit { - err = errors.Errorf("get config fail, init not done") - return + log.Errorf("getConfigValue fail, init not done, namespace:%s key:%s", c.namespace, key) + return nil } c.waitInit.Wait() } if c.cache == nil { - err = errors.Errorf("get config value fail!namespace:%s is not exist!", c.namespace) - return + log.Errorf("get config value fail!namespace:%s is not exist!", c.namespace) + return nil } - if value, err = c.cache.Get(key); err != nil { - err = errors.Errorf("get config value fail!key:%s,err:%s", key, err) - return + value, err := c.cache.Get(key) + if err != nil { + log.Errorf("get config value fail!key:%s,err:%s", key, err) + return nil } - return + return value } -// GetValueNotWait 获取配置值,不阻塞(string) -func (c *Config) GetValueNotWait(key string) (string, error) { - value, err := c.getConfigValue(key, false) - if err != nil { - return utils.Empty, err +// GetValueImmediately 获取配置值(string),立即返回,初始化未完成直接返回错误 +func (c *Config) GetValueImmediately(key string) string { + value := c.getConfigValue(key, false) + if value == nil { + return utils.Empty } v, ok := value.(string) if !ok { - return utils.Empty, errors.Errorf("convert to string fail ! source type:%T", value) + log.Debug("convert to string fail ! source type:%T", value) + return utils.Empty } - return v, nil + return v +} + +// GetStringValue 获取配置值(string),获取不到则取默认值,立即返回,初始化未完成直接返回错误 +func (c *Config) GetStringValueImmediately(key string, defaultValue string) string { + value := c.GetValueImmediately(key) + if value == utils.Empty { + return defaultValue + } + + return value +} + +// GetStringSliceValueImmediately 获取配置值([]string),立即返回,初始化未完成直接返回错误 +func (c *Config) GetStringSliceValueImmediately(key string, defaultValue []string) []string { + value := c.getConfigValue(key, false) + if value == nil { + return defaultValue + } + + v, ok := value.([]string) + if !ok { + log.Debug("convert to []string fail ! source type:%T", value) + return defaultValue + } + return v +} + +// GetIntSliceValueImmediately 获取配置值([]int),立即返回,初始化未完成直接返回错误 +func (c *Config) GetIntSliceValueImmediately(key string, defaultValue []int) []int { + value := c.getConfigValue(key, false) + if value == nil { + return defaultValue + } + + v, ok := value.([]int) + if !ok { + log.Debug("convert to []int fail ! source type:%T", value) + return defaultValue + } + return v +} + +// GetSliceValueImmediately 获取配置值([]interface),立即返回,初始化未完成直接返回错误 +func (c *Config) GetSliceValueImmediately(key string, defaultValue []interface{}) []interface{} { + value := c.getConfigValue(key, false) + if value == nil { + return defaultValue + } + + v, ok := value.([]interface{}) + if !ok { + log.Debug("convert to []interface{} fail ! source type:%T", value) + return defaultValue + } + return v +} + +// GetIntValueImmediately 获取配置值(int),获取不到则取默认值,立即返回,初始化未完成直接返回错误 +func (c *Config) GetIntValueImmediately(key string, defaultValue int) int { + value := c.getConfigValue(key, false) + if value == nil { + return defaultValue + } + + v, ok := value.(int) + if !ok { + log.Debug("convert to int fail ! source type:%T", value) + return defaultValue + } + return v +} + +// GetFloatValueImmediately 获取配置值(float),获取不到则取默认值,立即返回,初始化未完成直接返回错误 +func (c *Config) GetFloatValueImmediately(key string, defaultValue float64) float64 { + value := c.getConfigValue(key, false) + if value == nil { + return defaultValue + } + + v, ok := value.(float64) + if !ok { + log.Debug("convert to float64 fail ! source type:%T", value) + return defaultValue + } + return v +} + +// GetBoolValueImmediately 获取配置值(bool),获取不到则取默认值,立即返回,初始化未完成直接返回错误 +func (c *Config) GetBoolValueImmediately(key string, defaultValue bool) bool { + value := c.getConfigValue(key, false) + if value == nil { + return defaultValue + } + + v, ok := value.(bool) + if !ok { + log.Debug("convert to bool fail ! source type:%T", value) + return defaultValue + } + return v } // GetValue 获取配置值(string) func (c *Config) GetValue(key string) string { - value, err := c.getConfigValue(key, true) - if err != nil { - log.Errorf(err.Error()) + value := c.getConfigValue(key, true) + if value == nil { return utils.Empty } @@ -178,9 +277,8 @@ func (c *Config) GetStringValue(key string, defaultValue string) string { // GetStringSliceValue 获取配置值([]string) func (c *Config) GetStringSliceValue(key string, defaultValue []string) []string { - value, err := c.getConfigValue(key, true) - if err != nil { - log.Errorf(err.Error()) + value := c.getConfigValue(key, true) + if value == nil { return defaultValue } @@ -194,9 +292,8 @@ func (c *Config) GetStringSliceValue(key string, defaultValue []string) []string // GetIntSliceValue 获取配置值([]int) func (c *Config) GetIntSliceValue(key string, defaultValue []int) []int { - value, err := c.getConfigValue(key, true) - if err != nil { - log.Errorf(err.Error()) + value := c.getConfigValue(key, true) + if value == nil { return defaultValue } @@ -210,9 +307,8 @@ func (c *Config) GetIntSliceValue(key string, defaultValue []int) []int { // GetSliceValue 获取配置值([]interface) func (c *Config) GetSliceValue(key string, defaultValue []interface{}) []interface{} { - value, err := c.getConfigValue(key, true) - if err != nil { - log.Errorf(err.Error()) + value := c.getConfigValue(key, true) + if value == nil { return defaultValue } @@ -226,9 +322,8 @@ func (c *Config) GetSliceValue(key string, defaultValue []interface{}) []interfa // GetIntValue 获取配置值(int),获取不到则取默认值 func (c *Config) GetIntValue(key string, defaultValue int) int { - value, err := c.getConfigValue(key, true) - if err != nil { - log.Errorf(err.Error()) + value := c.getConfigValue(key, true) + if value == nil { return defaultValue } @@ -242,9 +337,8 @@ func (c *Config) GetIntValue(key string, defaultValue int) int { // GetFloatValue 获取配置值(float),获取不到则取默认值 func (c *Config) GetFloatValue(key string, defaultValue float64) float64 { - value, err := c.getConfigValue(key, true) - if err != nil { - log.Errorf(err.Error()) + value := c.getConfigValue(key, true) + if value == nil { return defaultValue } @@ -258,9 +352,8 @@ func (c *Config) GetFloatValue(key string, defaultValue float64) float64 { // GetBoolValue 获取配置值(bool),获取不到则取默认值 func (c *Config) GetBoolValue(key string, defaultValue bool) bool { - value, err := c.getConfigValue(key, true) - if err != nil { - log.Errorf(err.Error()) + value := c.getConfigValue(key, true) + if value == nil { return defaultValue } diff --git a/storage/repository_test.go b/storage/repository_test.go index 1b98555..dcf03aa 100644 --- a/storage/repository_test.go +++ b/storage/repository_test.go @@ -225,29 +225,73 @@ func TestDispatchInRepository(t *testing.T) { Assert(t, ok, Equal(false)) } -func TestGetValueNotWait(t *testing.T) { +func TestGetValueImmediately(t *testing.T) { c := initConfig("namespace", extension.GetCacheFactory()) - res, err := c.GetValueNotWait("namespace") + res := c.GetValueImmediately("namespace") Assert(t, res, Equal(utils.Empty)) - Assert(t, err.Error(), Equal("get config fail, init not done")) c.isInit.Store(true) - res, err = c.GetValueNotWait("namespace") + res = c.GetValueImmediately("namespace") Assert(t, res, Equal(utils.Empty)) - Assert(t, err.Error(), Equal("get config value fail!key:namespace,err:load default cache fail")) - res, err = c.GetValueNotWait("namespace1") + res = c.GetValueImmediately("namespace1") Assert(t, res, Equal(utils.Empty)) - Assert(t, err.Error(), Equal("get config value fail!key:namespace1,err:load default cache fail")) c.cache.Set("namespace", 1, 3) - res, err = c.GetValueNotWait("namespace") + res = c.GetValueImmediately("namespace") Assert(t, res, Equal(utils.Empty)) - Assert(t, err.Error(), Equal("convert to string fail ! source type:int")) c.cache.Set("namespace", "config", 3) - res, err = c.GetValueNotWait("namespace") + res = c.GetValueImmediately("namespace") Assert(t, res, Equal("config")) - Assert(t, err, Equal(nil)) +} + +func TestGetConfigImmediately(t *testing.T) { + configurations := make(map[string]interface{}) + configurations["string"] = "string2" + configurations["int"] = 2 + configurations["float"] = 1.9 + configurations["bool"] = false + configurations["sliceString"] = []string{"1", "2", "3"} + configurations["sliceInt"] = []int{1, 2, 3} + configurations["sliceInter"] = []interface{}{1, "2", 3} + c := creatTestApolloConfig(configurations, "test") + config := c.GetConfig("test") + Assert(t, config, NotNilVal()) + + // string + s := config.GetStringValueImmediately("string", "s") + Assert(t, s, Equal(configurations["string"])) + + s = config.GetStringValueImmediately("s", "s") + Assert(t, s, Equal("s")) + + // int + i := config.GetIntValueImmediately("int", 3) + Assert(t, i, Equal(2)) + i = config.GetIntValueImmediately("i", 3) + Assert(t, i, Equal(3)) + + // float + f := config.GetFloatValueImmediately("float", 2) + Assert(t, f, Equal(1.9)) + f = config.GetFloatValueImmediately("f", 2) + Assert(t, f, Equal(float64(2))) + + // bool + b := config.GetBoolValueImmediately("bool", true) + Assert(t, b, Equal(false)) + + b = config.GetBoolValueImmediately("b", false) + Assert(t, b, Equal(false)) + + slice := config.GetStringSliceValueImmediately("sliceString", []string{}) + Assert(t, slice, Equal([]string{"1", "2", "3"})) + + sliceInt := config.GetIntSliceValueImmediately("sliceInt", []int{}) + Assert(t, sliceInt, Equal([]int{1, 2, 3})) + + sliceInter := config.GetSliceValueImmediately("sliceInter", []interface{}{}) + Assert(t, sliceInter, Equal([]interface{}{1, "2", 3})) } From 6fac6547959eefb2b21d587f90e57200c63b9467 Mon Sep 17 00:00:00 2001 From: weihaoyu <444216978@qq.com> Date: Mon, 16 May 2022 11:22:41 +0800 Subject: [PATCH 03/12] GetValueImmediately --- storage/repository.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/storage/repository.go b/storage/repository.go index 969ecc8..5efd51f 100644 --- a/storage/repository.go +++ b/storage/repository.go @@ -150,7 +150,7 @@ func (c *Config) GetValueImmediately(key string) string { return v } -// GetStringValue 获取配置值(string),获取不到则取默认值,立即返回,初始化未完成直接返回错误 +// GetStringValueImmediately 获取配置值(string),获取不到则取默认值,立即返回,初始化未完成直接返回错误 func (c *Config) GetStringValueImmediately(key string, defaultValue string) string { value := c.GetValueImmediately(key) if value == utils.Empty { From d013a018d8782e6318e92963475bf3fb18fa34b7 Mon Sep 17 00:00:00 2001 From: weihaoyu <444216978@qq.com> Date: Mon, 16 May 2022 11:27:13 +0800 Subject: [PATCH 04/12] apidoc --- storage/repository.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/storage/repository.go b/storage/repository.go index 5efd51f..52422b8 100644 --- a/storage/repository.go +++ b/storage/repository.go @@ -150,7 +150,7 @@ func (c *Config) GetValueImmediately(key string) string { return v } -// GetStringValueImmediately 获取配置值(string),获取不到则取默认值,立即返回,初始化未完成直接返回错误 +// GetStringValueImmediately 获取配置值(string),立即返回,初始化未完成直接返回错误 func (c *Config) GetStringValueImmediately(key string, defaultValue string) string { value := c.GetValueImmediately(key) if value == utils.Empty { From fea036f5fe48879e62a6d7d2320b2c85fd477cd6 Mon Sep 17 00:00:00 2001 From: weihaoyu <444216978@qq.com> Date: Tue, 17 May 2022 13:40:39 +0800 Subject: [PATCH 05/12] change go.sum --- go.sum | 1 - 1 file changed, 1 deletion(-) diff --git a/go.sum b/go.sum index 18af665..3dfc818 100644 --- a/go.sum +++ b/go.sum @@ -129,7 +129,6 @@ github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FI github.com/pelletier/go-toml v1.2.0 h1:T5zMGML61Wp+FlcbWjRDT7yAxhJNAiPPLOFECq181zc= github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= -github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I= github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= From c221c81dd66b2642ae4c24d1fa01fce270dae153 Mon Sep 17 00:00:00 2001 From: fatelei Date: Tue, 19 Jul 2022 18:19:33 +0800 Subject: [PATCH 06/12] chore: using log with format method --- component/common_test.go | 2 +- component/remote/async.go | 6 +++--- component/remote/sync.go | 2 +- component/serverlist/sync.go | 2 +- env/config/json/json_config.go | 2 +- env/file/json/json.go | 2 +- protocol/http/request.go | 6 +++--- protocol/http/request_test.go | 4 ++-- storage/repository.go | 28 ++++++++++++++-------------- 9 files changed, 27 insertions(+), 27 deletions(-) diff --git a/component/common_test.go b/component/common_test.go index 316ac7f..76270e8 100644 --- a/component/common_test.go +++ b/component/common_test.go @@ -146,7 +146,7 @@ func SyncServerIPListSuccessCallBack(responseBody []byte, callback http.CallBack err = json2.Unmarshal(responseBody, &tmpServerInfo) if err != nil { - log.Error("Unmarshal json Fail,Error:", err) + log.Errorf("Unmarshal json Fail,Error: %s", err) return } diff --git a/component/remote/async.go b/component/remote/async.go index 586326b..623e696 100644 --- a/component/remote/async.go +++ b/component/remote/async.go @@ -138,7 +138,7 @@ func toApolloConfig(resBody []byte) ([]*config.Notification, error) { err := json.Unmarshal(resBody, &remoteConfig) if err != nil { - log.Error("Unmarshal Msg Fail,Error:", err) + log.Errorf("Unmarshal Msg Fail,Error: %v", err) return nil, err } return remoteConfig, nil @@ -149,7 +149,7 @@ func loadBackupConfig(namespace string, appConfig config.AppConfig) []*config.Ap config.SplitNamespaces(namespace, func(namespace string) { c, err := extension.GetFileHandler().LoadConfigFile(appConfig.BackupConfigPath, appConfig.AppID, namespace) if err != nil { - log.Error("LoadConfigFile error, error", err) + log.Errorf("LoadConfigFile error, error: %v", err) return } if c == nil { @@ -177,7 +177,7 @@ func createApolloConfigWithJSON(b []byte, callback http.CallBack) (o interface{} } m, err := parser.Parse(apolloConfig.Configurations[defaultContentKey]) if err != nil { - log.Debug("GetContent fail ! error:", err) + log.Debugf("GetContent fail ! error: %v", err) } if len(m) > 0 { diff --git a/component/remote/sync.go b/component/remote/sync.go index b347d76..8153587 100644 --- a/component/remote/sync.go +++ b/component/remote/sync.go @@ -85,7 +85,7 @@ func processJSONFiles(b []byte, callback http.CallBack) (o interface{}, err erro } m, err := parser.Parse(configurations[defaultContentKey]) if err != nil { - log.Debug("GetContent fail ! error:", err) + log.Debugf("GetContent fail ! error: %v", err) } if len(m) > 0 { diff --git a/component/serverlist/sync.go b/component/serverlist/sync.go index cc4652c..b6479ac 100644 --- a/component/serverlist/sync.go +++ b/component/serverlist/sync.go @@ -109,7 +109,7 @@ func SyncServerIPListSuccessCallBack(responseBody []byte, callback http.CallBack err = json.Unmarshal(responseBody, &tmpServerInfo) if err != nil { - log.Error("Unmarshal json Fail,Error:", err) + log.Error("Unmarshal json Fail,Error: %v", err) return } diff --git a/env/config/json/json_config.go b/env/config/json/json_config.go index a341380..157c389 100644 --- a/env/config/json/json_config.go +++ b/env/config/json/json_config.go @@ -55,7 +55,7 @@ func (t *ConfigFile) Write(content interface{}, configPath string) error { } file, e := os.Create(configPath) if e != nil { - log.Errorf("writeConfigFile fail,error:", e) + log.Errorf("writeConfigFile fail,error: %v", e) return e } defer file.Close() diff --git a/env/file/json/json.go b/env/file/json/json.go index 4308545..375eb6d 100644 --- a/env/file/json/json.go +++ b/env/file/json/json.go @@ -98,7 +98,7 @@ func (fileHandler *FileHandler) GetConfigFile(configDir string, appID string, na //LoadConfigFile load config from file func (fileHandler *FileHandler) LoadConfigFile(configDir string, appID string, namespace string) (*config.ApolloConfig, error) { configFilePath := fileHandler.GetConfigFile(configDir, appID, namespace) - log.Info("load config file from :", configFilePath) + log.Infof("load config file from: %s", configFilePath) c, e := jsonFileConfig.Load(configFilePath, func(b []byte) (interface{}, error) { config := &config.ApolloConfig{} e := json.NewDecoder(bytes.NewBuffer(b)).Decode(config) diff --git a/protocol/http/request.go b/protocol/http/request.go index b657f12..0e9cf1b 100644 --- a/protocol/http/request.go +++ b/protocol/http/request.go @@ -99,7 +99,7 @@ func Request(requestURL string, connectionConfig *env.ConnectConfig, callBack *C var err error url, err := url2.Parse(requestURL) if err != nil { - log.Error("request Apollo Server url:%s, is invalid %s", requestURL, err) + log.Errorf("request Apollo Server url: %s, is invalid: %v", requestURL, err) return nil, err } var insecureSkipVerify bool @@ -167,7 +167,7 @@ func Request(requestURL string, connectionConfig *env.ConnectConfig, callBack *C } return nil, nil case http.StatusNotModified: - log.Debug("Config Not Modified:", err) + log.Debugf("Config Not Modified: %v", err) if callBack != nil && callBack.NotModifyCallBack != nil { return nil, callBack.NotModifyCallBack() } @@ -180,7 +180,7 @@ func Request(requestURL string, connectionConfig *env.ConnectConfig, callBack *C } } - log.Error("Over Max Retry Still Error,Error:", err) + log.Errorf("Over Max Retry Still Error,Error: %v", err) if retry > retries { err = errors.New("over Max Retry Still Error") } diff --git a/protocol/http/request_test.go b/protocol/http/request_test.go index 89b9562..1f81b04 100644 --- a/protocol/http/request_test.go +++ b/protocol/http/request_test.go @@ -161,14 +161,14 @@ func getConfigURLSuffix(config *config.AppConfig, namespaceName string) string { //SyncServerIPListSuccessCallBack 同步服务器列表成功后的回调 func SyncServerIPListSuccessCallBack(responseBody []byte, callback CallBack) (o interface{}, err error) { - log.Debug("get all server info:", string(responseBody)) + log.Debugf("get all server info: %s", string(responseBody)) tmpServerInfo := make([]*config.ServerInfo, 0) err = json2.Unmarshal(responseBody, &tmpServerInfo) if err != nil { - log.Error("Unmarshal json Fail,Error:", err) + log.Errorf("Unmarshal json Fail,Error: %v", err) return } diff --git a/storage/repository.go b/storage/repository.go index 957ba20..f794f38 100644 --- a/storage/repository.go +++ b/storage/repository.go @@ -145,7 +145,7 @@ func (c *Config) GetValueImmediately(key string) string { v, ok := value.(string) if !ok { - log.Debug("convert to string fail ! source type:%T", value) + log.Debugf("convert to string fail ! source type:%T", value) return utils.Empty } return v @@ -170,7 +170,7 @@ func (c *Config) GetStringSliceValueImmediately(key string, defaultValue []strin v, ok := value.([]string) if !ok { - log.Debug("convert to []string fail ! source type:%T", value) + log.Debugf("convert to []string fail ! source type:%T", value) return defaultValue } return v @@ -185,7 +185,7 @@ func (c *Config) GetIntSliceValueImmediately(key string, defaultValue []int) []i v, ok := value.([]int) if !ok { - log.Debug("convert to []int fail ! source type:%T", value) + log.Debugf("convert to []int fail ! source type:%T", value) return defaultValue } return v @@ -200,7 +200,7 @@ func (c *Config) GetSliceValueImmediately(key string, defaultValue []interface{} v, ok := value.([]interface{}) if !ok { - log.Debug("convert to []interface{} fail ! source type:%T", value) + log.Debugf("convert to []interface{} fail ! source type:%T", value) return defaultValue } return v @@ -215,7 +215,7 @@ func (c *Config) GetIntValueImmediately(key string, defaultValue int) int { v, ok := value.(int) if !ok { - log.Debug("convert to int fail ! source type:%T", value) + log.Debugf("convert to int fail ! source type:%T", value) return defaultValue } return v @@ -230,7 +230,7 @@ func (c *Config) GetFloatValueImmediately(key string, defaultValue float64) floa v, ok := value.(float64) if !ok { - log.Debug("convert to float64 fail ! source type:%T", value) + log.Debugf("convert to float64 fail ! source type:%T", value) return defaultValue } return v @@ -245,7 +245,7 @@ func (c *Config) GetBoolValueImmediately(key string, defaultValue bool) bool { v, ok := value.(bool) if !ok { - log.Debug("convert to bool fail ! source type:%T", value) + log.Debugf("convert to bool fail ! source type:%T", value) return defaultValue } return v @@ -260,7 +260,7 @@ func (c *Config) GetValue(key string) string { v, ok := value.(string) if !ok { - log.Debug("convert to string fail ! source type:%T", value) + log.Debugf("convert to string fail ! source type:%T", value) return utils.Empty } return v @@ -285,7 +285,7 @@ func (c *Config) GetStringSliceValue(key string, defaultValue []string) []string v, ok := value.([]string) if !ok { - log.Debug("convert to []string fail ! source type:%T", value) + log.Debugf("convert to []string fail ! source type:%T", value) return defaultValue } return v @@ -300,7 +300,7 @@ func (c *Config) GetIntSliceValue(key string, defaultValue []int) []int { v, ok := value.([]int) if !ok { - log.Debug("convert to []int fail ! source type:%T", value) + log.Debugf("convert to []int fail ! source type:%T", value) return defaultValue } return v @@ -315,7 +315,7 @@ func (c *Config) GetSliceValue(key string, defaultValue []interface{}) []interfa v, ok := value.([]interface{}) if !ok { - log.Debug("convert to []interface{} fail ! source type:%T", value) + log.Debugf("convert to []interface{} fail ! source type:%T", value) return defaultValue } return v @@ -330,7 +330,7 @@ func (c *Config) GetIntValue(key string, defaultValue int) int { v, ok := value.(int) if !ok { - log.Debug("convert to int fail ! source type:%T", value) + log.Debugf("convert to int fail ! source type:%T", value) return defaultValue } return v @@ -345,7 +345,7 @@ func (c *Config) GetFloatValue(key string, defaultValue float64) float64 { v, ok := value.(float64) if !ok { - log.Debug("convert to float64 fail ! source type:%T", value) + log.Debugf("convert to float64 fail ! source type:%T", value) return defaultValue } return v @@ -360,7 +360,7 @@ func (c *Config) GetBoolValue(key string, defaultValue bool) bool { v, ok := value.(bool) if !ok { - log.Debug("convert to bool fail ! source type:%T", value) + log.Debugf("convert to bool fail ! source type:%T", value) return defaultValue } return v From c594924eb90acf30d950e780da8fa4026cacf9b5 Mon Sep 17 00:00:00 2001 From: "shuai.qi" Date: Wed, 17 Aug 2022 10:14:59 +0800 Subject: [PATCH 07/12] =?UTF-8?q?=E4=BD=BF=E7=94=A8MkdirAll=E9=98=B2?= =?UTF-8?q?=E6=AD=A2=E5=A4=9A=E7=BA=A7=E7=9B=AE=E5=BD=95=E4=B8=8D=E5=AD=98?= =?UTF-8?q?=E5=9C=A8=E5=AF=BC=E8=87=B4=E5=88=9B=E5=BB=BA=E5=A4=B1=E8=B4=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- env/file/json/json.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/env/file/json/json.go b/env/file/json/json.go index 4308545..fd1f815 100644 --- a/env/file/json/json.go +++ b/env/file/json/json.go @@ -59,7 +59,7 @@ func (fileHandler *FileHandler) createDir(configPath string) error { configFileDirMapLock.Lock() defer configFileDirMapLock.Unlock() if !configFileDirMap[configPath] { - err := os.Mkdir(configPath, os.ModePerm) + err := os.MkdirAll(configPath, os.ModePerm) if err != nil && !os.IsExist(err) { log.Errorf("Create backup dir:%s fail,error:&s", configPath, err) return err From b299cedf5cd67d1be61abb62580ce5cf0adf3feb Mon Sep 17 00:00:00 2001 From: weihaoyu <444216978@qq.com> Date: Thu, 25 Aug 2022 16:58:19 +0800 Subject: [PATCH 08/12] fix unit test data race --- start_test.go | 21 +++++++++------------ storage/event_dispatch_test.go | 14 +++++++++++++- storage/repository_test.go | 14 +++++++------- 3 files changed, 29 insertions(+), 20 deletions(-) diff --git a/start_test.go b/start_test.go index cf2c68d..2d6039f 100644 --- a/start_test.go +++ b/start_test.go @@ -121,7 +121,6 @@ func TestErrorStart(t *testing.T) { value2 := client.GetValue("key2") Assert(t, "value2", Equal(value2)) - } func getTestAppConfig() *config.AppConfig { @@ -166,14 +165,15 @@ func TestStructInit(t *testing.T) { Assert(t, "dev1", Equal(apolloConfig.Cluster)) Assert(t, "application1", Equal(apolloConfig.NamespaceName)) - //revert file config + // revert file config env.InitFileConfig() } func TestSetLogger(t *testing.T) { - logger := &log.DefaultLogger{} - SetLogger(logger) - Assert(t, log.Logger, Equal(logger)) + // TODO log.Logger data race + // logger := &log.DefaultLogger{} + // SetLogger(logger) + // Assert(t, log.Logger, Equal(logger)) } func TestSetCache(t *testing.T) { @@ -182,10 +182,9 @@ func TestSetCache(t *testing.T) { Assert(t, extension.GetCacheFactory(), Equal(defaultCacheFactory)) } -type TestLoadBalance struct { -} +type TestLoadBalance struct{} -//Load 负载均衡 +// Load 负载均衡 func (r *TestLoadBalance) Load(servers map[string]*config.ServerInfo) *config.ServerInfo { return nil } @@ -199,9 +198,8 @@ func TestSetLoadBalance(t *testing.T) { Assert(t, t2, Equal(extension.GetLoadBalance())) } -//testFileHandler 默认备份文件读写 -type testFileHandler struct { -} +// testFileHandler 默认备份文件读写 +type testFileHandler struct{} // WriteConfigFile write config to file func (fileHandler *testFileHandler) WriteConfigFile(config *config.ApolloConfig, configPath string) error { @@ -273,5 +271,4 @@ func TestStartWithConfigMustReadFromRemote(t *testing.T) { Assert(t, "value1", Equal(value)) handler := extension.GetFileHandler() Assert(t, handler, NotNilVal()) - } diff --git a/storage/event_dispatch_test.go b/storage/event_dispatch_test.go index 66a4383..8facbf6 100644 --- a/storage/event_dispatch_test.go +++ b/storage/event_dispatch_test.go @@ -35,6 +35,19 @@ func (t *CustomListener) Event(event *Event) { t.Keys[event.Key] = event.Value } +func (t *CustomListener) Value(key string) (interface{}, bool) { + t.l.Lock() + defer t.l.Unlock() + v, ok := t.Keys[key] + return v, ok +} + +func (t *CustomListener) Len() int { + t.l.Lock() + defer t.l.Unlock() + return len(t.Keys) +} + func TestDispatch(t *testing.T) { dispatch := UseEventDispatch() l := &CustomListener{ @@ -89,5 +102,4 @@ func TestUnRegisterListener(t *testing.T) { Assert(t, err, NilVal()) Assert(t, len(dispatch.listeners), Equal(1)) Assert(t, len(dispatch.listeners["ad.*"]), Equal(0)) - } diff --git a/storage/repository_test.go b/storage/repository_test.go index dcf03aa..2693cfd 100644 --- a/storage/repository_test.go +++ b/storage/repository_test.go @@ -192,11 +192,11 @@ func TestRegDispatchInRepository(t *testing.T) { cache.AddChangeListener(dispatch) cache.pushChangeEvent(cEvent) time.Sleep(1 * time.Second) - Assert(t, len(l.Keys), Equal(2)) - v, ok := l.Keys["add"] + Assert(t, l.Len(), Equal(2)) + v, ok := l.Value("add") Assert(t, v, Equal("new")) Assert(t, ok, Equal(true)) - v, ok = l.Keys["adx"] + v, ok = l.Value("adx") Assert(t, v, Equal("new")) Assert(t, ok, Equal(true)) } @@ -214,14 +214,14 @@ func TestDispatchInRepository(t *testing.T) { cache.AddChangeListener(dispatch) cache.pushChangeEvent(cEvent) time.Sleep(1 * time.Second) - Assert(t, len(l.Keys), Equal(2)) - v, ok := l.Keys["add"] + Assert(t, l.Len(), Equal(2)) + v, ok := l.Value("add") Assert(t, v, Equal("new")) Assert(t, ok, Equal(true)) - v, ok = l.Keys["delete"] + v, ok = l.Value("delete") Assert(t, ok, Equal(true)) Assert(t, v, Equal("old")) - _, ok = l.Keys["modify"] + _, ok = l.Value("modify") Assert(t, ok, Equal(false)) } From 7aab4fb0647331b9ba6c59d2eead4bcbb4f78d7d Mon Sep 17 00:00:00 2001 From: weihaoyu <444216978@qq.com> Date: Thu, 25 Aug 2022 17:14:53 +0800 Subject: [PATCH 09/12] fix repository get func string value convert to target type --- storage/repository.go | 82 +++++++++++++++++++++++++++++++++++--- storage/repository_test.go | 31 +++++++++++++- 2 files changed, 106 insertions(+), 7 deletions(-) diff --git a/storage/repository.go b/storage/repository.go index 957ba20..b728ea9 100644 --- a/storage/repository.go +++ b/storage/repository.go @@ -21,6 +21,7 @@ import ( "container/list" "fmt" "reflect" + "strconv" "sync" "sync/atomic" @@ -214,10 +215,22 @@ func (c *Config) GetIntValueImmediately(key string, defaultValue int) int { } v, ok := value.(int) + if ok { + return v + } + + s, ok := value.(string) if !ok { - log.Debug("convert to int fail ! source type:%T", value) + log.Debug("convert to string fail ! source type:%T", value) + return defaultValue + } + + v, err := strconv.Atoi(s) + if err != nil { + log.Debug("Atoi fail err:%s", err.Error()) return defaultValue } + return v } @@ -229,10 +242,22 @@ func (c *Config) GetFloatValueImmediately(key string, defaultValue float64) floa } v, ok := value.(float64) + if ok { + return v + } + + s, ok := value.(string) if !ok { - log.Debug("convert to float64 fail ! source type:%T", value) + log.Debug("convert to string fail ! source type:%T", value) return defaultValue } + + v, err := strconv.ParseFloat(s, 64) + if err != nil { + log.Debug("ParseFloat fail err:%s", err.Error()) + return defaultValue + } + return v } @@ -244,10 +269,22 @@ func (c *Config) GetBoolValueImmediately(key string, defaultValue bool) bool { } v, ok := value.(bool) + if ok { + return v + } + + s, ok := value.(string) if !ok { - log.Debug("convert to bool fail ! source type:%T", value) + log.Debug("convert to string fail ! source type:%T", value) + return defaultValue + } + + v, err := strconv.ParseBool(s) + if err != nil { + log.Debug("ParseBool fail err:%s", err.Error()) return defaultValue } + return v } @@ -329,8 +366,19 @@ func (c *Config) GetIntValue(key string, defaultValue int) int { } v, ok := value.(int) + if ok { + return v + } + + s, ok := value.(string) if !ok { - log.Debug("convert to int fail ! source type:%T", value) + log.Debug("convert to string fail ! source type:%T", value) + return defaultValue + } + + v, err := strconv.Atoi(s) + if err != nil { + log.Debug("Atoi fail err:%s", err.Error()) return defaultValue } return v @@ -344,8 +392,19 @@ func (c *Config) GetFloatValue(key string, defaultValue float64) float64 { } v, ok := value.(float64) + if ok { + return v + } + + s, ok := value.(string) if !ok { - log.Debug("convert to float64 fail ! source type:%T", value) + log.Debug("convert to string fail ! source type:%T", value) + return defaultValue + } + + v, err := strconv.ParseFloat(s, 64) + if err != nil { + log.Debug("ParseFloat fail err:%s", err.Error()) return defaultValue } return v @@ -359,8 +418,19 @@ func (c *Config) GetBoolValue(key string, defaultValue bool) bool { } v, ok := value.(bool) + if ok { + return v + } + + s, ok := value.(string) if !ok { - log.Debug("convert to bool fail ! source type:%T", value) + log.Debug("convert to string fail ! source type:%T", value) + return defaultValue + } + + v, err := strconv.ParseBool(s) + if err != nil { + log.Debug("ParseBool fail err:%s", err.Error()) return defaultValue } return v diff --git a/storage/repository_test.go b/storage/repository_test.go index 2693cfd..4a8895f 100644 --- a/storage/repository_test.go +++ b/storage/repository_test.go @@ -98,8 +98,11 @@ func TestGetConfig(t *testing.T) { configurations := make(map[string]interface{}) configurations["string"] = "string2" configurations["int"] = 2 + configurations["string_int"] = "2" configurations["float"] = 1.9 + configurations["string_float"] = "1.9" configurations["bool"] = false + configurations["string_bool"] = "false" configurations["sliceString"] = []string{"1", "2", "3"} configurations["sliceInt"] = []int{1, 2, 3} configurations["sliceInter"] = []interface{}{1, "2", 3} @@ -117,18 +120,30 @@ func TestGetConfig(t *testing.T) { // int i := config.GetIntValue("int", 3) Assert(t, i, Equal(2)) + i = config.GetIntValue("string_int", 3) + Assert(t, i, Equal(2)) + i = config.GetIntValue("float", 3) + Assert(t, i, Equal(3)) i = config.GetIntValue("i", 3) Assert(t, i, Equal(3)) // float f := config.GetFloatValue("float", 2) Assert(t, f, Equal(1.9)) + f = config.GetFloatValue("string_float", 2) + Assert(t, f, Equal(1.9)) + f = config.GetFloatValue("int", 2) + Assert(t, f, Equal(float64(2))) f = config.GetFloatValue("f", 2) Assert(t, f, Equal(float64(2))) // bool b := config.GetBoolValue("bool", true) Assert(t, b, Equal(false)) + b = config.GetBoolValue("string_bool", true) + Assert(t, b, Equal(false)) + b = config.GetBoolValue("int", true) + Assert(t, b, Equal(true)) b = config.GetBoolValue("b", false) Assert(t, b, Equal(false)) @@ -251,8 +266,11 @@ func TestGetConfigImmediately(t *testing.T) { configurations := make(map[string]interface{}) configurations["string"] = "string2" configurations["int"] = 2 + configurations["string_int"] = "2" configurations["float"] = 1.9 + configurations["string_float"] = "1.9" configurations["bool"] = false + configurations["string_bool"] = "false" configurations["sliceString"] = []string{"1", "2", "3"} configurations["sliceInt"] = []int{1, 2, 3} configurations["sliceInter"] = []interface{}{1, "2", 3} @@ -270,19 +288,30 @@ func TestGetConfigImmediately(t *testing.T) { // int i := config.GetIntValueImmediately("int", 3) Assert(t, i, Equal(2)) + i = config.GetIntValueImmediately("string_int", 3) + Assert(t, i, Equal(2)) + i = config.GetIntValueImmediately("float", 3) + Assert(t, i, Equal(3)) i = config.GetIntValueImmediately("i", 3) Assert(t, i, Equal(3)) // float f := config.GetFloatValueImmediately("float", 2) Assert(t, f, Equal(1.9)) + f = config.GetFloatValueImmediately("string_float", 2) + Assert(t, f, Equal(1.9)) f = config.GetFloatValueImmediately("f", 2) Assert(t, f, Equal(float64(2))) + f = config.GetFloatValueImmediately("int", 2) + Assert(t, f, Equal(float64(2))) // bool b := config.GetBoolValueImmediately("bool", true) Assert(t, b, Equal(false)) - + b = config.GetBoolValueImmediately("string_bool", true) + Assert(t, b, Equal(false)) + b = config.GetBoolValueImmediately("int", false) + Assert(t, b, Equal(false)) b = config.GetBoolValueImmediately("b", false) Assert(t, b, Equal(false)) From ba95af1cec7efe2ff909d76a613980ff95b49540 Mon Sep 17 00:00:00 2001 From: "shuai.qi" Date: Mon, 22 Aug 2022 11:26:17 +0800 Subject: [PATCH 10/12] Using debug logging when 304 http code returned from server --- component/remote/abs.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/component/remote/abs.go b/component/remote/abs.go index 76379ef..88c540a 100644 --- a/component/remote/abs.go +++ b/component/remote/abs.go @@ -62,7 +62,7 @@ func (a *AbsApolloConfig) SyncWithNamespace(namespace string, appConfigFunc func } if apolloConfig == nil { - log.Warn("apolloConfig is nil") + log.Debug("apolloConfig is nil") return nil } From 7b505c075e5a80ad8e65959ce2759fa096a7e455 Mon Sep 17 00:00:00 2001 From: weihaoyu <444216978@qq.com> Date: Mon, 16 May 2022 11:22:41 +0800 Subject: [PATCH 11/12] GetValueImmediately --- component/common_test.go | 2 +- component/remote/abs.go | 2 +- component/remote/async.go | 6 +++--- component/remote/sync.go | 2 +- component/serverlist/sync.go | 2 +- env/config/json/json_config.go | 2 +- env/file/json/json.go | 4 ++-- protocol/http/request.go | 6 +++--- protocol/http/request_test.go | 4 ++-- storage/repository.go | 28 ++++++++++++++-------------- 10 files changed, 29 insertions(+), 29 deletions(-) diff --git a/component/common_test.go b/component/common_test.go index 316ac7f..76270e8 100644 --- a/component/common_test.go +++ b/component/common_test.go @@ -146,7 +146,7 @@ func SyncServerIPListSuccessCallBack(responseBody []byte, callback http.CallBack err = json2.Unmarshal(responseBody, &tmpServerInfo) if err != nil { - log.Error("Unmarshal json Fail,Error:", err) + log.Errorf("Unmarshal json Fail,Error: %s", err) return } diff --git a/component/remote/abs.go b/component/remote/abs.go index 76379ef..88c540a 100644 --- a/component/remote/abs.go +++ b/component/remote/abs.go @@ -62,7 +62,7 @@ func (a *AbsApolloConfig) SyncWithNamespace(namespace string, appConfigFunc func } if apolloConfig == nil { - log.Warn("apolloConfig is nil") + log.Debug("apolloConfig is nil") return nil } diff --git a/component/remote/async.go b/component/remote/async.go index 586326b..623e696 100644 --- a/component/remote/async.go +++ b/component/remote/async.go @@ -138,7 +138,7 @@ func toApolloConfig(resBody []byte) ([]*config.Notification, error) { err := json.Unmarshal(resBody, &remoteConfig) if err != nil { - log.Error("Unmarshal Msg Fail,Error:", err) + log.Errorf("Unmarshal Msg Fail,Error: %v", err) return nil, err } return remoteConfig, nil @@ -149,7 +149,7 @@ func loadBackupConfig(namespace string, appConfig config.AppConfig) []*config.Ap config.SplitNamespaces(namespace, func(namespace string) { c, err := extension.GetFileHandler().LoadConfigFile(appConfig.BackupConfigPath, appConfig.AppID, namespace) if err != nil { - log.Error("LoadConfigFile error, error", err) + log.Errorf("LoadConfigFile error, error: %v", err) return } if c == nil { @@ -177,7 +177,7 @@ func createApolloConfigWithJSON(b []byte, callback http.CallBack) (o interface{} } m, err := parser.Parse(apolloConfig.Configurations[defaultContentKey]) if err != nil { - log.Debug("GetContent fail ! error:", err) + log.Debugf("GetContent fail ! error: %v", err) } if len(m) > 0 { diff --git a/component/remote/sync.go b/component/remote/sync.go index b347d76..8153587 100644 --- a/component/remote/sync.go +++ b/component/remote/sync.go @@ -85,7 +85,7 @@ func processJSONFiles(b []byte, callback http.CallBack) (o interface{}, err erro } m, err := parser.Parse(configurations[defaultContentKey]) if err != nil { - log.Debug("GetContent fail ! error:", err) + log.Debugf("GetContent fail ! error: %v", err) } if len(m) > 0 { diff --git a/component/serverlist/sync.go b/component/serverlist/sync.go index cc4652c..b6479ac 100644 --- a/component/serverlist/sync.go +++ b/component/serverlist/sync.go @@ -109,7 +109,7 @@ func SyncServerIPListSuccessCallBack(responseBody []byte, callback http.CallBack err = json.Unmarshal(responseBody, &tmpServerInfo) if err != nil { - log.Error("Unmarshal json Fail,Error:", err) + log.Error("Unmarshal json Fail,Error: %v", err) return } diff --git a/env/config/json/json_config.go b/env/config/json/json_config.go index a341380..157c389 100644 --- a/env/config/json/json_config.go +++ b/env/config/json/json_config.go @@ -55,7 +55,7 @@ func (t *ConfigFile) Write(content interface{}, configPath string) error { } file, e := os.Create(configPath) if e != nil { - log.Errorf("writeConfigFile fail,error:", e) + log.Errorf("writeConfigFile fail,error: %v", e) return e } defer file.Close() diff --git a/env/file/json/json.go b/env/file/json/json.go index 4308545..c78e38e 100644 --- a/env/file/json/json.go +++ b/env/file/json/json.go @@ -59,7 +59,7 @@ func (fileHandler *FileHandler) createDir(configPath string) error { configFileDirMapLock.Lock() defer configFileDirMapLock.Unlock() if !configFileDirMap[configPath] { - err := os.Mkdir(configPath, os.ModePerm) + err := os.MkdirAll(configPath, os.ModePerm) if err != nil && !os.IsExist(err) { log.Errorf("Create backup dir:%s fail,error:&s", configPath, err) return err @@ -98,7 +98,7 @@ func (fileHandler *FileHandler) GetConfigFile(configDir string, appID string, na //LoadConfigFile load config from file func (fileHandler *FileHandler) LoadConfigFile(configDir string, appID string, namespace string) (*config.ApolloConfig, error) { configFilePath := fileHandler.GetConfigFile(configDir, appID, namespace) - log.Info("load config file from :", configFilePath) + log.Infof("load config file from: %s", configFilePath) c, e := jsonFileConfig.Load(configFilePath, func(b []byte) (interface{}, error) { config := &config.ApolloConfig{} e := json.NewDecoder(bytes.NewBuffer(b)).Decode(config) diff --git a/protocol/http/request.go b/protocol/http/request.go index b657f12..0e9cf1b 100644 --- a/protocol/http/request.go +++ b/protocol/http/request.go @@ -99,7 +99,7 @@ func Request(requestURL string, connectionConfig *env.ConnectConfig, callBack *C var err error url, err := url2.Parse(requestURL) if err != nil { - log.Error("request Apollo Server url:%s, is invalid %s", requestURL, err) + log.Errorf("request Apollo Server url: %s, is invalid: %v", requestURL, err) return nil, err } var insecureSkipVerify bool @@ -167,7 +167,7 @@ func Request(requestURL string, connectionConfig *env.ConnectConfig, callBack *C } return nil, nil case http.StatusNotModified: - log.Debug("Config Not Modified:", err) + log.Debugf("Config Not Modified: %v", err) if callBack != nil && callBack.NotModifyCallBack != nil { return nil, callBack.NotModifyCallBack() } @@ -180,7 +180,7 @@ func Request(requestURL string, connectionConfig *env.ConnectConfig, callBack *C } } - log.Error("Over Max Retry Still Error,Error:", err) + log.Errorf("Over Max Retry Still Error,Error: %v", err) if retry > retries { err = errors.New("over Max Retry Still Error") } diff --git a/protocol/http/request_test.go b/protocol/http/request_test.go index 89b9562..1f81b04 100644 --- a/protocol/http/request_test.go +++ b/protocol/http/request_test.go @@ -161,14 +161,14 @@ func getConfigURLSuffix(config *config.AppConfig, namespaceName string) string { //SyncServerIPListSuccessCallBack 同步服务器列表成功后的回调 func SyncServerIPListSuccessCallBack(responseBody []byte, callback CallBack) (o interface{}, err error) { - log.Debug("get all server info:", string(responseBody)) + log.Debugf("get all server info: %s", string(responseBody)) tmpServerInfo := make([]*config.ServerInfo, 0) err = json2.Unmarshal(responseBody, &tmpServerInfo) if err != nil { - log.Error("Unmarshal json Fail,Error:", err) + log.Errorf("Unmarshal json Fail,Error: %v", err) return } diff --git a/storage/repository.go b/storage/repository.go index b728ea9..aa3f3a0 100644 --- a/storage/repository.go +++ b/storage/repository.go @@ -146,7 +146,7 @@ func (c *Config) GetValueImmediately(key string) string { v, ok := value.(string) if !ok { - log.Debug("convert to string fail ! source type:%T", value) + log.Debugf("convert to string fail ! source type:%T", value) return utils.Empty } return v @@ -171,7 +171,7 @@ func (c *Config) GetStringSliceValueImmediately(key string, defaultValue []strin v, ok := value.([]string) if !ok { - log.Debug("convert to []string fail ! source type:%T", value) + log.Debugf("convert to []string fail ! source type:%T", value) return defaultValue } return v @@ -186,7 +186,7 @@ func (c *Config) GetIntSliceValueImmediately(key string, defaultValue []int) []i v, ok := value.([]int) if !ok { - log.Debug("convert to []int fail ! source type:%T", value) + log.Debugf("convert to []int fail ! source type:%T", value) return defaultValue } return v @@ -201,7 +201,7 @@ func (c *Config) GetSliceValueImmediately(key string, defaultValue []interface{} v, ok := value.([]interface{}) if !ok { - log.Debug("convert to []interface{} fail ! source type:%T", value) + log.Debugf("convert to []interface{} fail ! source type:%T", value) return defaultValue } return v @@ -221,7 +221,7 @@ func (c *Config) GetIntValueImmediately(key string, defaultValue int) int { s, ok := value.(string) if !ok { - log.Debug("convert to string fail ! source type:%T", value) + log.Debug("convert to int fail ! source type:%T", value) return defaultValue } @@ -248,7 +248,7 @@ func (c *Config) GetFloatValueImmediately(key string, defaultValue float64) floa s, ok := value.(string) if !ok { - log.Debug("convert to string fail ! source type:%T", value) + log.Debugf("convert to float64 fail ! source type:%T", value) return defaultValue } @@ -275,7 +275,7 @@ func (c *Config) GetBoolValueImmediately(key string, defaultValue bool) bool { s, ok := value.(string) if !ok { - log.Debug("convert to string fail ! source type:%T", value) + log.Debug("convert to bool fail ! source type:%T", value) return defaultValue } @@ -297,7 +297,7 @@ func (c *Config) GetValue(key string) string { v, ok := value.(string) if !ok { - log.Debug("convert to string fail ! source type:%T", value) + log.Debugf("convert to string fail ! source type:%T", value) return utils.Empty } return v @@ -322,7 +322,7 @@ func (c *Config) GetStringSliceValue(key string, defaultValue []string) []string v, ok := value.([]string) if !ok { - log.Debug("convert to []string fail ! source type:%T", value) + log.Debugf("convert to []string fail ! source type:%T", value) return defaultValue } return v @@ -337,7 +337,7 @@ func (c *Config) GetIntSliceValue(key string, defaultValue []int) []int { v, ok := value.([]int) if !ok { - log.Debug("convert to []int fail ! source type:%T", value) + log.Debugf("convert to []int fail ! source type:%T", value) return defaultValue } return v @@ -352,7 +352,7 @@ func (c *Config) GetSliceValue(key string, defaultValue []interface{}) []interfa v, ok := value.([]interface{}) if !ok { - log.Debug("convert to []interface{} fail ! source type:%T", value) + log.Debugf("convert to []interface{} fail ! source type:%T", value) return defaultValue } return v @@ -372,7 +372,7 @@ func (c *Config) GetIntValue(key string, defaultValue int) int { s, ok := value.(string) if !ok { - log.Debug("convert to string fail ! source type:%T", value) + log.Debug("convert to int fail ! source type:%T", value) return defaultValue } @@ -398,7 +398,7 @@ func (c *Config) GetFloatValue(key string, defaultValue float64) float64 { s, ok := value.(string) if !ok { - log.Debug("convert to string fail ! source type:%T", value) + log.Debug("convert to float64 fail ! source type:%T", value) return defaultValue } @@ -424,7 +424,7 @@ func (c *Config) GetBoolValue(key string, defaultValue bool) bool { s, ok := value.(string) if !ok { - log.Debug("convert to string fail ! source type:%T", value) + log.Debug("convert to bool fail ! source type:%T", value) return defaultValue } From 800122c04a85ea88f6d4f185b1bcf645259ed283 Mon Sep 17 00:00:00 2001 From: Joe Zou Date: Thu, 29 Sep 2022 09:03:43 +0800 Subject: [PATCH 12/12] Update README.md (#252) --- README.md | 2 -- 1 file changed, 2 deletions(-) diff --git a/README.md b/README.md index 843f2d4..ff1c96a 100644 --- a/README.md +++ b/README.md @@ -54,8 +54,6 @@ func main() { Secret: "6ce3ff7e96a24335a9634fe9abca6d51", } - agollo.SetLogger(&DefaultLogger{}) - client, _ := agollo.StartWithConfig(func() (*config.AppConfig, error) { return c, nil })