From bb979f5ccb83d2d60144c89a8b2d1da67634a967 Mon Sep 17 00:00:00 2001 From: charlie <3140647@qq.com> Date: Wed, 13 Dec 2023 17:08:56 +0800 Subject: [PATCH] config --- configure/config.toml | 7 +++ configure/configure.go | 44 +++++++++++++++ configure/configure_builder.go | 100 +++++++++++++++++++++++++++++++++ configure/configure_test.go | 42 ++++++++++++++ configure/nacos.go | 96 +++++++++++++++++++++++++++++++ 5 files changed, 289 insertions(+) create mode 100644 configure/config.toml create mode 100644 configure/configure.go create mode 100644 configure/configure_builder.go create mode 100644 configure/configure_test.go create mode 100644 configure/nacos.go diff --git a/configure/config.toml b/configure/config.toml new file mode 100644 index 0000000..e45ccc0 --- /dev/null +++ b/configure/config.toml @@ -0,0 +1,7 @@ +Mode = "dev" + +[Nacos] + Address = "192.168.2.121" + Port = 8848 + Namespace = "8560b58d-87d0-4b85-8ac5-f2d308c6669e" + Group = "dev" diff --git a/configure/configure.go b/configure/configure.go new file mode 100644 index 0000000..f9cb7fb --- /dev/null +++ b/configure/configure.go @@ -0,0 +1,44 @@ +package configure + +import ( + "github.com/charlienet/go-mixed/expr" + "github.com/spf13/viper" +) + +type Configure interface { + GetString(string, string) string +} + +type NotifyFunc func(Configure) + +type conf struct { + viper *viper.Viper // + nacos *nacos // + onChangeNotifies map[string][]NotifyFunc // 已经注册的配置变更通知 + nacosOptions *NacosOptions // + useNacos bool // +} + +func (c *conf) GetString(key string, defaultValue string) string { + if c.viper.IsSet(key) { + return c.viper.GetString(key) + } + + return defaultValue +} + +func (c *conf) GetInt(key string, defaultValue int) int { + return expr.Ternary(c.viper.IsSet(key), c.viper.GetInt(key), defaultValue) +} + +func (c *conf) Load(dataId string, v any, onChanged ...NotifyFunc) error { + if err := c.nacos.Load(dataId, v); err != nil { + return err + } + + if len(onChanged) > 0 { + c.onChangeNotifies[dataId] = onChanged + } + + return nil +} diff --git a/configure/configure_builder.go b/configure/configure_builder.go new file mode 100644 index 0000000..4f152eb --- /dev/null +++ b/configure/configure_builder.go @@ -0,0 +1,100 @@ +package configure + +import ( + "github.com/fsnotify/fsnotify" + "github.com/spf13/viper" +) + +func New() *conf { return &conf{viper: viper.New(), onChangeNotifies: make(map[string][]NotifyFunc)} } + +func (c *conf) AddConfigPath(in ...string) *conf { + for _, v := range in { + c.viper.AddConfigPath(v) + } + + return c +} + +func (c *conf) SetConfigName(in string) *conf { + c.viper.SetConfigName(in) + return c +} + +func (c *conf) SetConfigFile(f string) *conf { + c.viper.SetConfigFile(f) + return c +} + +func (c *conf) SetDefault(key string, value any) *conf { + c.viper.SetDefault(key, value) + return c +} + +func (c *conf) AutomaticEnv() *conf { + c.viper.AutomaticEnv() + return c +} + +func (c *conf) Read() (*conf, error) { + // 从本地配置读取 + if err := c.viper.ReadInConfig(); err != nil { + return nil, err + } + + c.viper.WatchConfig() + c.viper.OnConfigChange(c.OnViperChanged) + + // 初始化Nacos客户端 + if err := c.createNacosClient(); err != nil { + return nil, err + } + + return c, nil +} + +func (c *conf) OnViperChanged(in fsnotify.Event) { + +} + +func (c *conf) createNacosClient() error { + opt := c.getNacosOptions() + if opt == nil { + return nil + } + + nc, err := createNacosClient(opt.Address, opt.Port, opt.Namespace, opt.Group) + if err != nil { + return err + } + + c.nacos = &nacos{client: nc, group: opt.Group, onChanged: c.onNacosChanged} + + return nil +} + +func (c *conf) onNacosChanged(dataId, data string) { + if fs, ok := c.onChangeNotifies[dataId]; ok { + for _, f := range fs { + if f != nil { + f(c) + } + } + } +} + +func (c *conf) getNacosOptions() *NacosOptions { + if c.nacosOptions != nil { + return c.nacosOptions + } + + if c.useNacos { + return &NacosOptions{ + Address: c.GetString(AddressKey, "127.0.0.1"), + Port: c.GetInt(PortKey, 8848), + Namespace: c.GetString(Namespace, ""), + Group: c.GetString(Group, ""), + } + } + + return nil +} diff --git a/configure/configure_test.go b/configure/configure_test.go new file mode 100644 index 0000000..a290f8f --- /dev/null +++ b/configure/configure_test.go @@ -0,0 +1,42 @@ +package configure_test + +import ( + "testing" + + "github.com/charlienet/go-mixed/configure" + "github.com/charlienet/go-mixed/json" + "github.com/stretchr/testify/assert" +) + +func TestLoadSpecifiedFile(t *testing.T) { + conf, err := configure.New().SetConfigFile("config.toml").Read() + t.Log(err) + + assert.Equal(t, "192.168.2.121", conf.GetString("nacos.address", "")) + _ = conf +} + +func TestNewConfigure(t *testing.T) { + +} + +func TestNacos(t *testing.T) { + conf, err := configure. + New(). + AddConfigPath("."). + WithNacos(). + Read() + + assert.Nil(t, err) + + t.Log(conf.GetString("nacos.address", "")) + + type redis struct { + Addrs string + } + + r := &redis{} + + t.Log(conf.Load("redis", r)) + t.Log(json.StructToJsonIndent(r)) +} diff --git a/configure/nacos.go b/configure/nacos.go new file mode 100644 index 0000000..2ba2cc2 --- /dev/null +++ b/configure/nacos.go @@ -0,0 +1,96 @@ +package configure + +import ( + "encoding/json" + "fmt" + + "github.com/nacos-group/nacos-sdk-go/v2/clients" + "github.com/nacos-group/nacos-sdk-go/v2/clients/config_client" + "github.com/nacos-group/nacos-sdk-go/v2/common/constant" + "github.com/nacos-group/nacos-sdk-go/v2/vo" +) + +const ( + AddressKey = "Nacos.Address" + PortKey = "Nacos.Port" + Namespace = "Nacos.Namespace" + Group = "Nacos.Group" +) + +type nacos struct { + client config_client.IConfigClient + onChanged func(string, string) + group string +} + +type NacosOptions struct { + Address string + Port int + Namespace string + Group string +} + +func (c *conf) WithNacosOptions(options *NacosOptions) *conf { + c.nacosOptions = options + return c +} + +func (c *conf) WithNacos() *conf { + c.useNacos = true + return c +} + +func (n *nacos) Load(dataId string, v any) error { + voParam := vo.ConfigParam{ + DataId: dataId, + Group: n.group, + OnChange: n.onChange, + } + + content, err := n.client.GetConfig(voParam) + if err != nil { + return err + } + + if len(content) == 0 { + return fmt.Errorf("parameters not configured:%s", dataId) + } + + if err := json.Unmarshal([]byte(content), v); err != nil { + return err + } + + n.client.ListenConfig(voParam) + return nil +} + +func (n *nacos) onChange(namespace, group, dataId, data string) { + n.onChanged(dataId, data) +} + +func createNacosClient(addr string, port int, namespace, group string) (config_client.IConfigClient, error) { + sc := []constant.ServerConfig{{ + IpAddr: addr, + Port: uint64(port), + }} + + cc := constant.ClientConfig{ + NamespaceId: namespace, + TimeoutMs: 5000, + LogDir: "logs", + CacheDir: "cache", + LogLevel: "info", + NotLoadCacheAtStart: true, + } + + configClient, err := clients.CreateConfigClient(map[string]any{ + "serverConfigs": sc, + "clientConfig": cc, + }) + + if err != nil { + return nil, err + } + + return configClient, nil +}