/
wrapper.go
135 lines (109 loc) · 2.76 KB
/
wrapper.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
package config
import (
"bytes"
"github.com/fsnotify/fsnotify"
"github.com/spf13/viper"
"log"
"sync"
"time"
)
// MARK: ViperWrapper
// ViperWrapper object
type ViperWrapper struct {
Instance *viper.Viper
ConfigPath []string
ConfigName string
ConfigEnvPrefix string
ConfigResourcePlace string
lastModified time.Time
wg sync.WaitGroup
lock sync.Mutex
}
// MARK: Public Methods
// Load - It creates new instance of Viper and load config file base on ConfigName
func (w *ViperWrapper) Load() error {
w.wg.Add(1)
defer w.wg.Done()
w.Instance = viper.New()
for _, path := range w.ConfigPath {
w.Instance.AddConfigPath(path)
}
w.Instance.SetConfigName(w.ConfigName)
err := w.Instance.ReadInConfig()
if err != nil {
return err
}
// Get env variables and bind them if exist in config file
env, exist := w.Get("env", true)
if env != nil && exist {
envArray := make([]string, len(env.([]interface{})))
for i, v := range env.([]interface{}) {
envArray[i] = v.(string)
}
if len(envArray) > 0 {
w.Instance.SetEnvPrefix(w.ConfigEnvPrefix)
for _, e := range envArray {
_ = w.Instance.BindEnv(e)
}
}
}
return nil
}
// LoadFromRemote - loads the configs from the remote server
func (w *ViperWrapper) LoadFromRemote(data []byte) error {
w.wg.Add(1)
defer w.wg.Done()
if w.Instance == nil {
w.Instance = viper.New()
}
err := w.Instance.ReadConfig(bytes.NewBuffer(data))
if err != nil {
return err
}
// Get env variables and bind them if exist in config file
env, exist := w.Get("env", true)
if env != nil && exist {
envArray := make([]string, len(env.([]interface{})))
for i, v := range env.([]interface{}) {
envArray[i] = v.(string)
}
if len(envArray) > 0 {
w.Instance.SetEnvPrefix(w.ConfigEnvPrefix)
for _, e := range envArray {
_ = w.Instance.BindEnv(e)
}
}
}
return nil
}
// RegisterChangeCallback - get function and call it when config file changed
func (w *ViperWrapper) RegisterChangeCallback(fn func() interface{}) {
w.wg.Wait()
w.Instance.WatchConfig()
w.Instance.OnConfigChange(func(e fsnotify.Event) {
log.Println(w.ConfigName, "Config file changed: ", e.Name)
if fn != nil {
fn()
}
})
}
// Get method - returns value base on key
func (w *ViperWrapper) Get(key string, bypass bool) (interface{}, bool) {
if !bypass {
w.wg.Wait()
}
w.lock.Lock()
defer w.lock.Unlock()
exist := w.Instance.InConfig(key)
return w.Instance.Get(key), exist
}
// Set method - set value by given key and write it back to file
func (w *ViperWrapper) Set(key string, value interface{}, bypass bool) error {
if !bypass {
w.wg.Wait()
}
w.lock.Lock()
defer w.lock.Unlock()
w.Instance.Set(key, value)
return w.Instance.SafeWriteConfig()
}