You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
120 lines
2.8 KiB
120 lines
2.8 KiB
2 years ago
|
package polaris
|
||
|
|
||
|
import (
|
||
|
"path/filepath"
|
||
|
"strings"
|
||
|
|
||
|
"github.com/polarismesh/polaris-go"
|
||
|
"github.com/polarismesh/polaris-go/pkg/model"
|
||
|
|
||
|
"github.com/go-kratos/kratos/v2/config"
|
||
|
"github.com/go-kratos/kratos/v2/log"
|
||
|
)
|
||
|
|
||
|
// ConfigOption is polaris config option.
|
||
|
type ConfigOption func(o *configOptions)
|
||
|
|
||
|
type configOptions struct {
|
||
|
namespace string
|
||
|
files []File
|
||
|
configFile []polaris.ConfigFile
|
||
|
}
|
||
|
|
||
|
// WithConfigFile with polaris config file
|
||
|
func WithConfigFile(file ...File) ConfigOption {
|
||
|
return func(o *configOptions) {
|
||
|
o.files = file
|
||
|
}
|
||
|
}
|
||
|
|
||
|
type File struct {
|
||
|
Name string
|
||
|
Group string
|
||
|
}
|
||
|
|
||
|
type source struct {
|
||
|
client polaris.ConfigAPI
|
||
|
options *configOptions
|
||
|
}
|
||
|
|
||
|
// Load return the config values
|
||
|
func (s *source) Load() ([]*config.KeyValue, error) {
|
||
|
kv := make([]*config.KeyValue, 0)
|
||
|
for _, file := range s.options.files {
|
||
|
configFile, err := s.client.GetConfigFile(s.options.namespace, file.Group, file.Name)
|
||
|
if err != nil {
|
||
|
return nil, err
|
||
|
}
|
||
|
s.options.configFile = append(s.options.configFile, configFile)
|
||
|
kv = append(kv, &config.KeyValue{
|
||
|
Key: file.Name,
|
||
|
Value: []byte(configFile.GetContent()),
|
||
|
Format: strings.TrimPrefix(filepath.Ext(file.Name), "."),
|
||
|
})
|
||
|
}
|
||
|
return kv, nil
|
||
|
}
|
||
|
|
||
|
// Watch return the watcher
|
||
|
func (s *source) Watch() (config.Watcher, error) {
|
||
|
return newConfigWatcher(s.options.configFile), nil
|
||
|
}
|
||
|
|
||
|
type ConfigWatcher struct {
|
||
|
event chan model.ConfigFileChangeEvent
|
||
|
cfg []*config.KeyValue
|
||
|
}
|
||
|
|
||
|
func receive(event chan model.ConfigFileChangeEvent) func(m model.ConfigFileChangeEvent) {
|
||
|
return func(m model.ConfigFileChangeEvent) {
|
||
|
defer func() {
|
||
|
if err := recover(); err != nil {
|
||
|
log.Error(err)
|
||
|
}
|
||
|
}()
|
||
|
event <- m
|
||
|
}
|
||
|
}
|
||
|
|
||
|
func newConfigWatcher(configFile []polaris.ConfigFile) *ConfigWatcher {
|
||
|
w := &ConfigWatcher{
|
||
|
event: make(chan model.ConfigFileChangeEvent, len(configFile)),
|
||
|
}
|
||
|
for _, file := range configFile {
|
||
|
w.cfg = append(w.cfg, &config.KeyValue{
|
||
|
Key: file.GetFileName(),
|
||
|
Value: []byte(file.GetContent()),
|
||
|
Format: strings.TrimPrefix(filepath.Ext(file.GetFileName()), "."),
|
||
|
})
|
||
|
}
|
||
|
for _, file := range configFile {
|
||
|
file.AddChangeListener(receive(w.event))
|
||
|
}
|
||
|
return w
|
||
|
}
|
||
|
|
||
|
func (w *ConfigWatcher) Next() ([]*config.KeyValue, error) {
|
||
|
if event, ok := <-w.event; ok {
|
||
|
m := make(map[string]*config.KeyValue)
|
||
|
for _, file := range w.cfg {
|
||
|
m[file.Key] = file
|
||
|
}
|
||
|
m[event.ConfigFileMetadata.GetFileName()] = &config.KeyValue{
|
||
|
Key: event.ConfigFileMetadata.GetFileName(),
|
||
|
Value: []byte(event.NewValue),
|
||
|
Format: strings.TrimPrefix(filepath.Ext(event.ConfigFileMetadata.GetFileName()), "."),
|
||
|
}
|
||
|
w.cfg = make([]*config.KeyValue, 0, len(m))
|
||
|
for _, kv := range m {
|
||
|
w.cfg = append(w.cfg, kv)
|
||
|
}
|
||
|
return w.cfg, nil
|
||
|
}
|
||
|
return w.cfg, nil
|
||
|
}
|
||
|
|
||
|
func (w *ConfigWatcher) Stop() error {
|
||
|
close(w.event)
|
||
|
return nil
|
||
|
}
|