nacos viper remote provider
This commit is contained in:
parent
20220cb36f
commit
bcd01f97cc
74
example/main.go
Normal file
74
example/main.go
Normal file
@ -0,0 +1,74 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/spf13/viper"
|
||||
remote "github.com/yoyofxteam/nacos-viper-remote"
|
||||
"os"
|
||||
"os/signal"
|
||||
"syscall"
|
||||
"time"
|
||||
)
|
||||
|
||||
func main() {
|
||||
config_viper := viper.New()
|
||||
runtime_viper := config_viper
|
||||
runtime_viper.SetConfigFile("./example_config.yaml")
|
||||
_ = runtime_viper.ReadInConfig()
|
||||
var option *remote.Option
|
||||
_ = runtime_viper.Sub("yoyogo.cloud.discovery.metadata").Unmarshal(&option)
|
||||
|
||||
remote.SetOptions(option)
|
||||
|
||||
//remote.SetOptions(&remote.Option{
|
||||
// Url: "localhost",
|
||||
// Port: 80,
|
||||
// NamespaceId: "public",
|
||||
// GroupName: "DEFAULT_GROUP",
|
||||
// Config: remote.Config{ DataId: "config_dev" },
|
||||
// Auth: nil,
|
||||
//})
|
||||
//localSetting := runtime_viper.AllSettings()
|
||||
remote_viper := viper.New()
|
||||
err := remote_viper.AddRemoteProvider("nacos", "localhost", "")
|
||||
remote_viper.SetConfigType("yaml")
|
||||
|
||||
err = remote_viper.ReadRemoteConfig()
|
||||
if err == nil {
|
||||
err = remote_viper.WatchRemoteConfigOnChannel()
|
||||
if err == nil {
|
||||
config_viper = remote_viper
|
||||
fmt.Println("used remote viper")
|
||||
}
|
||||
}
|
||||
|
||||
appName := config_viper.GetString("yoyogo.application.name")
|
||||
|
||||
fmt.Println(appName)
|
||||
|
||||
go func() {
|
||||
for {
|
||||
time.Sleep(time.Second * 30) // delay after each request
|
||||
appName = config_viper.GetString("yoyogo.application.name")
|
||||
fmt.Println(appName)
|
||||
}
|
||||
}()
|
||||
|
||||
onExit()
|
||||
}
|
||||
|
||||
func onExit() {
|
||||
c := make(chan os.Signal)
|
||||
signal.Notify(c, syscall.SIGHUP, syscall.SIGINT, syscall.SIGTERM,
|
||||
syscall.SIGQUIT, syscall.SIGUSR1, syscall.SIGUSR2)
|
||||
|
||||
for s := range c {
|
||||
switch s {
|
||||
case syscall.SIGHUP, syscall.SIGINT, syscall.SIGTERM, syscall.SIGQUIT:
|
||||
fmt.Println("Program Exit...", s)
|
||||
|
||||
default:
|
||||
fmt.Println("other signal", s)
|
||||
}
|
||||
}
|
||||
}
|
20
example_config.yaml
Normal file
20
example_config.yaml
Normal file
@ -0,0 +1,20 @@
|
||||
yoyogo:
|
||||
application:
|
||||
name: yoyogo_demo_dev
|
||||
cloud:
|
||||
discovery:
|
||||
cache:
|
||||
ttl: 30 # seconds
|
||||
strategy: "round-robin" # round-robin , weight-time , random
|
||||
type: "nacos"
|
||||
metadata:
|
||||
url: "120.53.133.30"
|
||||
port: 80
|
||||
namespace: "public"
|
||||
group: "DEFAULT_GROUP"
|
||||
configserver:
|
||||
dataId: "config_dev"
|
||||
auth:
|
||||
enable: true
|
||||
username: "root"
|
||||
password: "1234"
|
8
go.mod
Normal file
8
go.mod
Normal file
@ -0,0 +1,8 @@
|
||||
module github.com/yoyofxteam/nacos-viper-remote
|
||||
|
||||
go 1.14
|
||||
|
||||
require (
|
||||
github.com/spf13/viper v1.7.1
|
||||
github.com/nacos-group/nacos-sdk-go v1.0.7
|
||||
)
|
94
nacos_manager.go
Normal file
94
nacos_manager.go
Normal file
@ -0,0 +1,94 @@
|
||||
package nacos_viper_remote
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/nacos-group/nacos-sdk-go/clients"
|
||||
"github.com/nacos-group/nacos-sdk-go/clients/config_client"
|
||||
"github.com/nacos-group/nacos-sdk-go/common/constant"
|
||||
"github.com/nacos-group/nacos-sdk-go/common/logger"
|
||||
"github.com/nacos-group/nacos-sdk-go/vo"
|
||||
"github.com/spf13/viper"
|
||||
"strings"
|
||||
)
|
||||
|
||||
type nacosConfigManager struct {
|
||||
client config_client.IConfigClient
|
||||
option *Option
|
||||
}
|
||||
|
||||
func NewNacosConfigManager(option *Option) (*nacosConfigManager, error) {
|
||||
var serverConfigs []constant.ServerConfig
|
||||
urls := strings.Split(option.Url, ";")
|
||||
for _, url := range urls {
|
||||
serverConfigs = append(serverConfigs, constant.ServerConfig{
|
||||
ContextPath: "/nacos",
|
||||
IpAddr: url,
|
||||
Port: option.Port,
|
||||
})
|
||||
}
|
||||
clientConfig := constant.ClientConfig{
|
||||
NamespaceId: option.NamespaceId,
|
||||
TimeoutMs: 5000,
|
||||
NotLoadCacheAtStart: true,
|
||||
RotateTime: "1h",
|
||||
MaxAge: 3,
|
||||
LogLevel: "info",
|
||||
}
|
||||
if option.Auth != nil && option.Auth.Enable {
|
||||
clientConfig.Username = option.Auth.User
|
||||
clientConfig.Password = option.Auth.Password
|
||||
}
|
||||
client, err := clients.CreateConfigClient(map[string]interface{}{
|
||||
"serverConfigs": serverConfigs,
|
||||
"clientConfig": clientConfig,
|
||||
})
|
||||
if err != nil {
|
||||
logger.Error(err.Error())
|
||||
return nil, err
|
||||
}
|
||||
|
||||
manager := &nacosConfigManager{client: client, option: option}
|
||||
|
||||
return manager, err
|
||||
}
|
||||
|
||||
func (cm *nacosConfigManager) Get(dataId string) ([]byte, error) {
|
||||
//get config
|
||||
content, err := cm.client.GetConfig(vo.ConfigParam{
|
||||
DataId: cm.option.Config.DataId,
|
||||
Group: cm.option.GroupName,
|
||||
})
|
||||
return []byte(content), err
|
||||
}
|
||||
|
||||
func (cm *nacosConfigManager) Watch(dataId string, stop chan bool) <-chan *viper.RemoteResponse {
|
||||
resp := make(chan *viper.RemoteResponse)
|
||||
|
||||
configParams := vo.ConfigParam{
|
||||
DataId: cm.option.Config.DataId,
|
||||
Group: cm.option.GroupName,
|
||||
OnChange: func(namespace, group, dataId, data string) {
|
||||
fmt.Println("config changed group:" + group + ", dataId:" + dataId)
|
||||
resp <- &viper.RemoteResponse{
|
||||
Value: []byte(data),
|
||||
Error: nil,
|
||||
}
|
||||
},
|
||||
}
|
||||
err := cm.client.ListenConfig(configParams)
|
||||
if err != nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
go func() {
|
||||
for {
|
||||
select {
|
||||
case <-stop:
|
||||
_ = cm.client.CancelListenConfig(configParams)
|
||||
return
|
||||
}
|
||||
}
|
||||
}()
|
||||
|
||||
return resp
|
||||
}
|
20
nacos_options.go
Normal file
20
nacos_options.go
Normal file
@ -0,0 +1,20 @@
|
||||
package nacos_viper_remote
|
||||
|
||||
type Option struct {
|
||||
Url string `mapstructure:"url"`
|
||||
Port uint64 `mapstructure:"port"`
|
||||
NamespaceId string `mapstructure:"namespace"`
|
||||
GroupName string `mapstructure:"group"`
|
||||
Config Config `mapstructure:"configserver"`
|
||||
Auth *Auth `mapstructure:"auth"`
|
||||
}
|
||||
|
||||
type Config struct {
|
||||
DataId string `mapstructure:"dataId"`
|
||||
}
|
||||
|
||||
type Auth struct {
|
||||
Enable bool `mapstructure:"enable"`
|
||||
User string `mapstructure:"username"`
|
||||
Password string `mapstructure:"password"`
|
||||
}
|
8
viper_manager.go
Normal file
8
viper_manager.go
Normal file
@ -0,0 +1,8 @@
|
||||
package nacos_viper_remote
|
||||
|
||||
import "github.com/spf13/viper"
|
||||
|
||||
type viperConfigManager interface {
|
||||
Get(key string) ([]byte, error)
|
||||
Watch(key string, stop chan bool) <-chan *viper.RemoteResponse
|
||||
}
|
66
viper_remote.go
Normal file
66
viper_remote.go
Normal file
@ -0,0 +1,66 @@
|
||||
package nacos_viper_remote
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"errors"
|
||||
"github.com/spf13/viper"
|
||||
"io"
|
||||
)
|
||||
|
||||
var nacosOptions = &Option{}
|
||||
|
||||
func SetOptions(option *Option) {
|
||||
nacosOptions = option
|
||||
}
|
||||
|
||||
type remoteConfigProvider struct {
|
||||
}
|
||||
|
||||
func (rc *remoteConfigProvider) Get(rp viper.RemoteProvider) (io.Reader, error) {
|
||||
cmt, err := getConfigManager(rp)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var b []byte
|
||||
switch cm := cmt.(type) {
|
||||
case viperConfigManager:
|
||||
b, err = cm.Get(rp.Path())
|
||||
}
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return bytes.NewReader(b), nil
|
||||
}
|
||||
|
||||
func (rc *remoteConfigProvider) Watch(rp viper.RemoteProvider) (io.Reader, error) {
|
||||
return rc.Get(rp)
|
||||
}
|
||||
|
||||
func (rc *remoteConfigProvider) WatchChannel(rp viper.RemoteProvider) (<-chan *viper.RemoteResponse, chan bool) {
|
||||
cmt, err := getConfigManager(rp)
|
||||
if err != nil {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
switch cm := cmt.(type) {
|
||||
case viperConfigManager:
|
||||
quit := make(chan bool)
|
||||
viperResponseCh := cm.Watch("dataId", quit)
|
||||
return viperResponseCh, quit
|
||||
}
|
||||
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func getConfigManager(rp viper.RemoteProvider) (interface{}, error) {
|
||||
if rp.Provider() == "nacos" {
|
||||
return NewNacosConfigManager(nacosOptions)
|
||||
} else {
|
||||
return nil, errors.New("The Nacos configuration manager is not supported!")
|
||||
}
|
||||
}
|
||||
|
||||
func init() {
|
||||
viper.SupportedRemoteProviders = []string{"nacos"}
|
||||
viper.RemoteConfig = &remoteConfigProvider{}
|
||||
}
|
Loading…
Reference in New Issue
Block a user