coze-studio/backend/infra/impl/dynconf/static/static_config.go

149 lines
3.6 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/*
* Copyright 2025 coze-dev Authors
*
* 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
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package static
import (
"fmt"
"sync"
)
const (
defaultBase = "/deploy"
)
type Options struct {
absRepoRoot string // yaml文件root前缀的绝对路径
useJson bool // 需要bind json文件不指定默认bind yaml
groups []string
}
type OptFunc func(o *Options)
// WithAbsRepoRoot 传入自定义指定读取绝对路径/xx下的config.<xx>.(yaml,json),例如/opt/tiger/xxx
func WithAbsRepoRoot(absRepoRoot string) OptFunc {
return func(o *Options) {
if len(absRepoRoot) > 0 {
o.absRepoRoot = absRepoRoot
}
}
}
// WithUseJSONType 需要查找xx.json结尾的文
func WithUseJSONType(useJson bool) OptFunc {
return func(o *Options) {
o.useJson = useJson
}
}
func WithGroups(groups []string) OptFunc {
return func(o *Options) {
o.groups = groups
}
}
func loadOpts(opts ...OptFunc) *Options {
o := &Options{}
for _, opt := range opts {
opt(o)
}
return o
}
var configers sync.Map // key: abs path, value: configer
// New 可传入local_config_dir指定读取自定义的绝对路径文件 `<local_config_dir>/config.<env>.<region>.<cluster>.yaml`
func getOrCreateConf(opts ...OptFunc) (configer, error) {
options := loadOpts(opts...)
if options.absRepoRoot == "" {
options.absRepoRoot = defaultBase
}
keyFn := func(dir string, withJSON bool) string {
fileFmt := "yaml"
if withJSON {
fileFmt = "json"
}
return dir + "_" + fileFmt
}
dir := options.absRepoRoot
withJSON := options.useJson
key := keyFn(dir, withJSON)
val, exist := configers.Load(key)
if exist {
if conf, ok := val.(configer); ok {
return conf, nil
}
}
var (
cfg configer
err error
)
if withJSON {
cfg, err = NewConfJson(dir, options.groups)
if err != nil {
return nil, err
}
} else {
cfg, err = NewConfYaml(dir, options.groups) // 默认使用yaml
if err != nil {
return nil, err
}
}
configers.Store(key, cfg)
return cfg, nil
}
// JSONBind 不传dir值按默认路径优先级读取/opt/tiger/flowdevops/confcenter/psm/p.s.m/config.<env>.<region>.<cluster>.json
// 可使用WithAbsRepoRoot 传入自定义指定读取
func JSONBind(structPtr interface{}, opts ...OptFunc) error {
opts = append(opts, WithUseJSONType(true))
conf, err := getOrCreateConf(opts...)
if err != nil {
return fmt.Errorf("find config failed: %w", err)
}
return bindAndValidate(structPtr, conf)
}
// YAMLBind 不传dir值按默认路径按优先级读取/opt/tiger/flowdevops/confcenter/psm/p.s.m/config.<env>.<region>.<cluster>.yaml
// 可使用WithAbsRepoRoot 传入自定义指定读取
func YAMLBind(structPtr interface{}, opts ...OptFunc) error {
conf, err := getOrCreateConf(opts...)
if err != nil {
return fmt.Errorf("find config failed: %w", err)
}
return bindAndValidate(structPtr, conf)
}
type MarshalFunc func(data interface{}) ([]byte, error)
type UnmarshalFunc func(data []byte, v interface{}) error
type configer interface {
GetBytes() []byte
MarshalFunc() MarshalFunc
UnmarshalFunc() UnmarshalFunc
}
func bindAndValidate(structPtr interface{}, cnf configer) error {
return cnf.UnmarshalFunc()(cnf.GetBytes(), structPtr)
}