支持yaml配置文件

This commit is contained in:
sk 2024-12-04 16:27:19 +08:00
parent 85b568ec75
commit 173042787f
2 changed files with 99 additions and 64 deletions

View File

@ -1,14 +1,16 @@
package core package core
import ( import (
"encoding/json"
"io" "io"
"io/ioutil" "strings"
"path"
"mongo.games.com/goserver/core/logger" "mongo.games.com/goserver/core/logger"
"mongo.games.com/goserver/core/viperx"
) )
var packages = make(map[string]Package)
var packagesLoaded = make(map[string]bool)
// Package 功能包 // Package 功能包
// 只做初始化,不要依赖其它功能包 // 只做初始化,不要依赖其它功能包
type Package interface { type Package interface {
@ -16,84 +18,83 @@ type Package interface {
Init() error Init() error
io.Closer io.Closer
} }
type ConfigFileEncryptorHook interface {
IsCipherText([]byte) bool
Encrypt([]byte) []byte
Decrtypt([]byte) []byte
}
var packages = make(map[string]Package)
var packagesLoaded = make(map[string]bool)
var configFileEH ConfigFileEncryptorHook
// RegistePackage 注册功能包
func RegistePackage(p Package) { func RegistePackage(p Package) {
packages[p.Name()] = p packages[p.Name()] = p
} }
func IsPackageRegisted(name string) bool { // IsPackageRegistered 判断功能包是否已经注册
func IsPackageRegistered(name string) bool {
if _, exist := packages[name]; exist { if _, exist := packages[name]; exist {
return true return true
} }
return false return false
} }
// IsPackageLoaded 判断功能包是否已经加载
func IsPackageLoaded(name string) bool { func IsPackageLoaded(name string) bool {
if _, exist := packagesLoaded[name]; exist { if _, exist := packagesLoaded[name]; exist {
return true return true
} }
return false return false
} }
func RegisterConfigEncryptor(h ConfigFileEncryptorHook) {
configFileEH = h // RegisterConfigEncryptor 注册配置文件加密器
func RegisterConfigEncryptor(h viperx.ConfigFileEncryptorHook) {
viperx.RegisterConfigEncryptor(h)
} }
// LoadPackages 加载功能包
func LoadPackages(configFile string) { func LoadPackages(configFile string) {
//logger.Logger.Infof("Build time is: %s", BuildTime()) val := strings.Split(configFile, ".")
switch path.Ext(configFile) { if len(val) != 2 {
case ".json": panic("config file name error")
fileBuff, err := ioutil.ReadFile(configFile)
if err != nil {
logger.Logger.Errorf("Error while reading config file %s: %s", configFile, err)
break
} }
if configFileEH != nil {
if configFileEH.IsCipherText(fileBuff) { vp := viperx.GetViper(val[0], val[1])
fileBuff = configFileEH.Decrtypt(fileBuff)
var err error
var notFoundConfig []string
var notFoundPackage []string
for k := range vp.AllSettings() {
if _, ok := packages[k]; !ok {
notFoundPackage = append(notFoundPackage, k)
continue
} }
name := k
pkg := packages[k]
if err = vp.UnmarshalKey(k, pkg); err != nil {
logger.Logger.Errorf("Package %s: Error while unmarshalling from config file %s: %v", name, configFile, err)
continue
} }
var fileData interface{}
err = json.Unmarshal(fileBuff, &fileData) if err = pkg.Init(); err != nil {
if err != nil { logger.Logger.Errorf("Package %s: Error while initializing from config file %s: %v", name, configFile, err)
break continue
} }
fileMap := fileData.(map[string]interface{})
for name, pkg := range packages {
if moduleData, ok := fileMap[name]; ok {
if data, ok := moduleData.(map[string]interface{}); ok {
modelBuff, _ := json.Marshal(data)
err = json.Unmarshal(modelBuff, &pkg)
if err != nil {
logger.Logger.Errorf("Error while unmarshalling JSON from config file %s: %s", configFile, err)
} else {
err = pkg.Init()
if err != nil {
logger.Logger.Errorf("Error while initializing package %s: %s", pkg.Name(), err)
} else {
packagesLoaded[pkg.Name()] = true packagesLoaded[pkg.Name()] = true
logger.Logger.Infof("package [%16s] load success", pkg.Name()) logger.Logger.Infof("package [%16s] load success", pkg.Name())
} }
}
} else { for k := range packages {
logger.Logger.Errorf("Package %v init data unmarshal failed.", pkg.Name()) if !IsPackageLoaded(k) {
} notFoundConfig = append(notFoundConfig, k)
} else {
logger.Logger.Errorf("Package %v init data not exist.", pkg.Name())
} }
} }
default:
panic("Unsupported config file: " + configFile) if len(notFoundConfig) > 0 {
logger.Logger.Warnf("package load success, not found config: %v", notFoundConfig)
}
if len(notFoundPackage) > 0 {
logger.Logger.Warnf("package load success, not found package: %v", notFoundPackage)
} }
} }
// ClosePackages 关闭功能包
func ClosePackages() { func ClosePackages() {
for _, pkg := range packages { for _, pkg := range packages {
err := pkg.Close() err := pkg.Close()

View File

@ -1,7 +1,9 @@
package viperx package viperx
import ( import (
"bytes"
"fmt" "fmt"
"os"
"github.com/spf13/viper" "github.com/spf13/viper"
) )
@ -12,18 +14,50 @@ var paths = []string{
"./config", "./config",
} }
// ConfigFileEncryptorHook 配置文件加密器
type ConfigFileEncryptorHook interface {
IsCipherText([]byte) bool
Encrypt([]byte) []byte
Decrypt([]byte) []byte
}
var configFileEH ConfigFileEncryptorHook
// RegisterConfigEncryptor 注册配置文件加密器
func RegisterConfigEncryptor(h ConfigFileEncryptorHook) {
configFileEH = h
}
// GetViper 获取viper配置
// name: 配置文件名,不带后缀
// filetype: 配置文件类型如json、yaml、ini等
func GetViper(name, filetype string) *viper.Viper { func GetViper(name, filetype string) *viper.Viper {
vp := viper.New() buf, err := ReadFile(name, filetype)
// 配置文件 if err != nil {
vp.SetConfigName(name) panic(fmt.Sprintf("Error while reading config file %s: %v", name+filetype, err))
vp.SetConfigType(filetype)
for _, v := range paths {
vp.AddConfigPath(v)
} }
err := vp.ReadInConfig() if configFileEH != nil {
if err != nil { if configFileEH.IsCipherText(buf) {
panic(fmt.Errorf("fatal error config file: %w", err)) buf = configFileEH.Decrypt(buf)
}
}
vp := viper.New()
vp.SetConfigName(name)
vp.SetConfigType(filetype)
if err = vp.ReadConfig(bytes.NewReader(buf)); err != nil {
panic(fmt.Sprintf("Error while reading config file %s: %v", name+filetype, err))
} }
return vp return vp
} }
func ReadFile(name, filetype string) ([]byte, error) {
for _, v := range paths {
file := fmt.Sprintf("%s/%s.%s", v, name, filetype)
if _, err := os.Stat(file); err == nil {
return os.ReadFile(file)
}
}
return nil, nil
}