1 Star 0 Fork 0

csingo / cConfig

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
克隆/下载
FileClient.go 7.40 KB
一键复制 编辑 原始数据 按行查看 历史
joe 提交于 2023-12-13 11:05 . update
package cConfig
import (
"encoding/json"
"fmt"
"io/ioutil"
"os"
"path/filepath"
"reflect"
"regexp"
"strings"
"time"
"gitee.com/csingo/cHelper"
"gitee.com/csingo/cLog"
)
type FileClient struct{}
func (i *FileClient) initClient() (err error) {
config, err := GetConf("ConfigCenterConf.Clients.File")
if err != nil {
return err
}
fClient := config.(*ConfigCenterConf_FileClient)
if fClient.Path == "" {
fClient.Path, err = os.Getwd()
if err != nil {
return err
}
}
fClient.Path = strings.TrimRight(fClient.Path, "/")
container.clients.file = &fileClient{
path: fClient.Path,
namespace: fClient.Namespace,
}
cLog.WithContext(nil, map[string]interface{}{
"source": "cConfig.FileClient.InitClient",
"client": selfConfigCenterConf.Clients.File,
}).Trace("初始化配置中心 file 客户端成功")
return nil
}
func (i *FileClient) getConf(dataId, group string) ([]byte, error) {
// 读取文件
filename := dataId
if group != "" {
filename = fmt.Sprintf("%s.%s", filename, group)
}
if container.clients.file.namespace != "" {
filename = fmt.Sprintf("%s.%s", filename, container.clients.file.namespace)
}
filePath := fmt.Sprintf("%s/%s.json", container.clients.file.path, filename)
return ioutil.ReadFile(filepath.Clean(filePath))
}
func (i *FileClient) readConf(name string) {
instance, instanceExists := container.getInstance(name)
listenData, listenDataExists := container.getListenData(name)
listenGroup, listenGroupExists := container.getListenGroup(name)
// 判断配置是否已经注入
if !instanceExists {
cLog.WithContext(nil, map[string]interface{}{
"source": "cConfig.FileClient.ReadConf",
"config": name,
}).Error("加载配置中心配置失败: 配置未注入")
return
}
// 判断listenData是否存在
if !listenDataExists {
cLog.WithContext(nil, map[string]interface{}{
"source": "cConfig.FileClient.ReadConf",
"config": name,
}).Error("加载配置中心配置失败: 配置未监听")
return
}
// 判断ListenGroup是否存在
if !listenGroupExists {
cLog.WithContext(nil, map[string]interface{}{
"source": "cConfig.FileClient.ReadConf",
"config": name,
}).Error("加载配置中心配置失败: 未设置监听分组")
return
}
data, err := i.getConf(listenData, listenGroup)
if err != nil {
cLog.WithContext(nil, map[string]interface{}{
"source": "cConfig.FileClient.ReadConf",
"config": name,
"err": err.Error(),
}).Error("加载配置中心配置失败: 获取配置失败")
return
}
data = i.explainConf(data, container.layers)
cLog.WithContext(nil, map[string]interface{}{
"source": "cConfig.FileClient.ReadConf",
"config": name,
}).Trace("读取配置中心配置成功")
version := cHelper.Md5(data)
// 判断版本是否一致,不一致才更新
if container.isUpdateVersion(name, version) {
// 写入配置
instanceType := reflect.ValueOf(instance).Elem().Type()
newInstance := reflect.New(instanceType).Interface()
err := json.Unmarshal(data, newInstance)
if err != nil {
cLog.WithContext(nil, map[string]interface{}{
"source": "cConfig.FileClient.ReadConf",
"config": name,
"err": err.Error(),
}).Error("记录配置版本失败: json解析失败")
return
}
newInstanceElem := reflect.ValueOf(newInstance).Elem()
reflect.ValueOf(instance).Elem().Set(newInstanceElem)
container.saveListenVersion(name, version)
container.saveListenExecEnable(name, true)
cLog.WithContext(nil, map[string]interface{}{
"source": "cConfig.FileClient.ReadConf",
"config": name,
}).Trace("更新配置成功")
container.saveHandlerEnables(name, true)
} else {
cLog.WithContext(nil, map[string]interface{}{
"source": "cConfig.FileClient.ReadConf",
"config": name,
}).Trace("配置已最新")
container.saveHandlerEnables(name, false)
}
}
func (i *FileClient) listenConf(name string) {
// 判断是否存在定时器
timer, timerExists := container.getTimer(name)
if !timerExists {
cLog.WithContext(nil, map[string]interface{}{
"source": "cConfig.FileClient.ReadConf",
"config": name,
}).Error("监听配置失败: 定时器不存在")
return
}
go func(name string, timer *time.Ticker) {
cLog.WithContext(nil, map[string]interface{}{
"source": "cConfig.FileClient.ReadConf",
"config": name,
}).Trace("监听配置: 启动定时器消费")
for {
<-timer.C
i.readConf(name)
// 执行 HandleFunc
handlers := container.getHandlers(name)
if len(handlers) == 0 {
continue
}
if !container.getHandlerEnables(name) {
continue
}
for _, handleFunc := range handlers {
go execHandleFunc(name, handleFunc)
}
}
}(name, timer)
}
func (i *FileClient) explainConf(data []byte, count int64) []byte {
count = count - 1
var isMatch1, isMatch2, isMatch3 bool
data, isMatch1 = i.explainTextConf(data)
data, isMatch2 = i.explainJsonConf(data)
data, isMatch3 = i.explainJsonArrayConf(data)
if (isMatch1 || isMatch2 || isMatch3) && count > 0 {
data = i.explainConf(data, count)
}
return data
}
func (i *FileClient) explainTextConf(data []byte) ([]byte, bool) {
isMatch := false
reg := regexp.MustCompile(`\$text\{[^\.\{\$\}]+(\.[^\.\}]+)?\}`)
matches := reg.FindAll(data, -1)
for _, match := range matches {
tempMatch := string(match)
tempMatch = strings.TrimPrefix(tempMatch, "$text{")
tempMatch = strings.TrimSuffix(tempMatch, "}")
tempContent, err := i.getConf(tempMatch, "")
if err != nil {
cLog.WithContext(nil, map[string]interface{}{
"source": "cConfig.FileClient.ReadConf",
"config": tempMatch,
"err": err.Error(),
}).Error("解析引用配置异常: text")
continue
}
tempData := strings.ReplaceAll(string(data), string(match), string(tempContent))
data = []byte(tempData)
isMatch = true
}
return data, isMatch
}
func (i *FileClient) explainJsonConf(data []byte) ([]byte, bool) {
isMatch := false
reg := regexp.MustCompile(`\"\$json\{[^\.\{\$\}]+(\.[^\.\}]+)?\}\"`)
matches := reg.FindAll(data, -1)
for _, match := range matches {
tempMatch := string(match)
tempMatch = strings.TrimPrefix(tempMatch, "\"$json{")
tempMatch = strings.TrimSuffix(tempMatch, "}\"")
tempContent, err := i.getConf(tempMatch, "")
if err != nil {
cLog.WithContext(nil, map[string]interface{}{
"source": "cConfig.FileClient.ReadConf",
"config": tempMatch,
"err": err.Error(),
}).Error("解析引用配置异常: json")
continue
}
tempData := strings.ReplaceAll(string(data), string(match), string(tempContent))
data = []byte(tempData)
isMatch = true
}
return data, isMatch
}
func (i *FileClient) explainJsonArrayConf(data []byte) ([]byte, bool) {
isMatch := false
reg := regexp.MustCompile(`\"\$jsonArray\{[^\.\{\$\}]+(\.[^\.\}]+)?\}\"`)
matches := reg.FindAll(data, -1)
for _, match := range matches {
tempMatch := string(match)
tempMatch = strings.TrimPrefix(tempMatch, "\"$jsonArray{")
tempMatch = strings.TrimSuffix(tempMatch, "}\"")
tempContent, err := i.getConf(tempMatch, "")
if err != nil {
cLog.WithContext(nil, map[string]interface{}{
"source": "cConfig.FileClient.ReadConf",
"config": tempMatch,
"err": err.Error(),
}).Error("解析引用配置异常: jsonArray")
continue
}
tempContentStr := strings.TrimPrefix(string(tempContent), "[")
tempContentStr = strings.TrimSuffix(tempContentStr, "]")
tempData := strings.ReplaceAll(string(data), string(match), tempContentStr)
data = []byte(tempData)
isMatch = true
}
return data, isMatch
}
Go
1
https://gitee.com/csingo/cConfig.git
git@gitee.com:csingo/cConfig.git
csingo
cConfig
cConfig
v0.0.52

搜索帮助