-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathconfig.go
More file actions
204 lines (179 loc) · 4.86 KB
/
config.go
File metadata and controls
204 lines (179 loc) · 4.86 KB
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
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
/*
* Copyright 2022-2026 Thorsten A. Knieling
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
*/
package services
import (
"bytes"
"fmt"
"io"
"os"
"strings"
"sync"
"time"
"github.com/tknie/log"
)
// BuildDate build date
var BuildDate string
// BuildVersion build version
var BuildVersion string
// Version component version
var Version string
var once sync.Once
var configLock sync.Mutex
// ConfigStoreType config store type
type ConfigStoreType byte
const (
// NoStoreType no store type found
NoStoreType ConfigStoreType = iota
// XMLStoreType using XML to store config
XMLStoreType
// YAMLStoreType using YAML to store config
YAMLStoreType
// JSONStoreType using JSON to store config
JSONStoreType
)
var configWatcher *ConfigFileWatcher
// DefaultEnvironment default environment path
var DefaultEnvironment = ""
// ActualConfigStoreType actual config store type
var ActualConfigStoreType = XMLStoreType
var storeTypeSuffixes = []string{".xml", ".yaml", ".json"}
func evaluateConfigStore(file string) ConfigStoreType {
if file != "" {
for i, s := range storeTypeSuffixes {
if strings.HasSuffix(strings.ToLower(file), s) {
return ConfigStoreType(i + 1)
}
}
}
return NoStoreType
}
// ConfigInterface config interface for logging
type ConfigInterface interface {
Logging(interface{}) *Logging
SetLogging(*Logging)
Default() interface{}
Current() interface{}
Loaded(interface{}) error
IsServer() bool
}
func loadConfig(file string, handler any) error {
config := handler.(ConfigInterface)
configLock.Lock()
defer configLock.Unlock()
log.Log.Debugf("Load config file: %s", file)
byteValue, err := ReadConfig(file)
if err != nil {
return err
}
switch ActualConfigStoreType {
case XMLStoreType:
return loadXMLConfig(byteValue, config)
case YAMLStoreType:
return loadYAMLConfig(byteValue, config)
case JSONStoreType:
return loadJSONConfig(byteValue, config)
default:
}
return nil
}
// ParseConfig parse config input with config store type
func ParseConfig(byteValue []byte, config ConfigInterface) error {
configLock.Lock()
defer configLock.Unlock()
switch ActualConfigStoreType {
case XMLStoreType:
return loadXMLConfig(byteValue, config)
case YAMLStoreType:
return loadYAMLConfig(byteValue, config)
case JSONStoreType:
return loadJSONConfig(byteValue, config)
default:
}
return nil
}
// ReadConfig read config file
func ReadConfig(file string) ([]byte, error) {
xmlFile, err := os.Open(file)
if err != nil {
log.Log.Debugf("Open file error: %#v", err)
return nil, fmt.Errorf("open file err of %s: %v", file, err)
}
defer xmlFile.Close()
fi, _ := xmlFile.Stat()
log.Log.Debugf("File size=%d", fi.Size())
var buffer bytes.Buffer
_, err = io.Copy(&buffer, xmlFile)
if err != nil {
log.Log.Debugf("Read file error: %#v", err)
return nil, fmt.Errorf("read file err of %s: %v", file, err)
}
return buffer.Bytes(), nil
}
// StoreConfig store configuration
func StoreConfig(file string, config ConfigInterface) error {
if config == nil {
return fmt.Errorf("config is not defined")
}
if file == "" {
return fmt.Errorf("file name not set")
}
ActualConfigStoreType = evaluateConfigStore(file)
configFile, err := os.OpenFile(file, os.O_RDWR|os.O_CREATE|os.O_EXCL, 0666)
// if we os.Open returns an error then handle it
if err != nil {
d := time.Now().Format("-20060102-150405")
err = os.Rename(file, file+d)
if err != nil {
ServerMessage("Error renaming storage file %s: %v", file, err)
log.Log.Debugf("Rename file error: %#v", err)
return err
}
configFile, err = os.OpenFile(file, os.O_RDWR|os.O_CREATE|os.O_EXCL, 0666)
// if we os.Open returns an error then handle it
if err != nil {
ServerMessage("Error opening storage file %s: %v", file, err)
log.Log.Debugf("Open file error: %#v", err)
return err
}
}
defer configFile.Close()
log.Log.Debugf("Write configuration file: %s", file)
switch ActualConfigStoreType {
case XMLStoreType:
return storeXMLConfig(configFile, config)
case YAMLStoreType:
return storeYAMLConfig(configFile, config)
case JSONStoreType:
return storeJSONConfig(configFile, config)
default:
}
return fmt.Errorf("no store type found")
}
// LoadConfig load old XML configuration
func LoadConfig(file string, config ConfigInterface, watch bool) (err error) {
ActualConfigStoreType = evaluateConfigStore(file)
if watch {
configWatcher, err = InitWatcher(file, config, loadConfig)
if err != nil {
ServerMessage("ERROR: Watcher failed to be activated: %v", err)
}
}
err = loadConfig(file, config)
if err != nil {
err = fmt.Errorf("config read error: %v", err.Error())
return err
}
return nil
}
// CloseConfig close watcher and configuration file
func CloseConfig() {
configWatcher.CloseConfig()
}