Kaynağa Gözat

feat: 加上config Load

lihf 1 ay önce
ebeveyn
işleme
a0e9717717
5 değiştirilmiş dosya ile 193 ekleme ve 1 silme
  1. 31 0
      config/file.go
  2. 113 0
      config/load.go
  3. 30 0
      config/source.go
  4. 8 1
      go.mod
  5. 11 0
      go.sum

+ 31 - 0
config/file.go

@@ -0,0 +1,31 @@
+package config
+
+import (
+	"fmt"
+	"github.com/go-kratos/kratos/v2/config"
+	"github.com/go-kratos/kratos/v2/config/file"
+)
+
+type FileSource struct {
+	Format Format
+	Path   string
+}
+
+func (s *FileSource) NewSource() (config.Source, error) {
+	source := file.NewSource(s.Path)
+	return source, nil
+}
+
+func (s *FileSource) Validate() bool {
+	if !s.Format.Validate() {
+		return false
+	}
+	if s.Path == "" {
+		return false
+	}
+	return true
+}
+
+func (s *FileSource) String() string {
+	return fmt.Sprintf("file source format:%v, path:%v", s.Format, s.Path)
+}

+ 113 - 0
config/load.go

@@ -0,0 +1,113 @@
+package config
+
+import (
+	"errors"
+	"fmt"
+
+	"dario.cat/mergo"
+	"git.ikuban.com/server/yaml"
+	"github.com/elliotchance/orderedmap/v3"
+	"github.com/go-kratos/kratos/v2/config"
+)
+
+func Load(sources []Source, bc any) error {
+	configSources := make([]config.Source, 0)
+	sourceMap := orderedmap.NewOrderedMap[string, any]() // 有序map控制优先级
+
+	for _, source := range sources {
+		if !source.Validate() {
+			continue
+		}
+		s, err := source.NewSource()
+		if err != nil {
+			return fmt.Errorf("%v, new source error: %v", source.String(), err)
+		}
+
+		kvs, err := s.Load()
+		if err != nil {
+			return fmt.Errorf("%v, source load error: %v", source.String(), err)
+		}
+
+		for _, v := range kvs {
+			sourceMap.Set(v.Key, map[string]any{})
+		}
+
+		configSources = append(configSources, s)
+	}
+
+	if sourceMap.Len() == 0 {
+		return errors.New("config source is empty")
+	}
+
+	c := config.New(
+		config.WithSource(configSources...),
+		config.WithDecoder(func(kv *config.KeyValue, v map[string]interface{}) error {
+
+			ok := sourceMap.Has(kv.Key)
+			if !ok {
+				return errors.New("unknown config key")
+			}
+
+			next := map[string]any{}
+			err := yaml.Unmarshal(kv.Value, next)
+			if err != nil {
+				return err
+			}
+
+			sourceMap.Set(kv.Key, convertMap(next))
+
+			merged := make(map[string]any)
+			for c := range sourceMap.Values() {
+				err = mergo.Merge(&merged, c, mergo.WithOverride)
+				if err != nil {
+					return err
+				}
+			}
+
+			b, err := yaml.Marshal(merged)
+			if err != nil {
+				return err
+			}
+
+			err = yaml.Unmarshal(b, bc)
+			if err != nil {
+				return err
+			}
+
+			return nil
+		}),
+	)
+	if err := c.Load(); err != nil {
+		return err
+	}
+
+	return nil
+}
+
+func convertMap(src interface{}) interface{} {
+	switch m := src.(type) {
+	case map[string]interface{}:
+		dst := make(map[string]interface{}, len(m))
+		for k, v := range m {
+			dst[k] = convertMap(v)
+		}
+		return dst
+	case map[interface{}]interface{}:
+		dst := make(map[interface{}]interface{}, len(m))
+		for k, v := range m {
+			dst[k] = convertMap(v)
+		}
+		return dst
+	case []interface{}:
+		dst := make([]interface{}, len(m))
+		for k, v := range m {
+			dst[k] = convertMap(v)
+		}
+		return dst
+	case []byte:
+		// there will be no binary data in the config data
+		return string(m)
+	default:
+		return src
+	}
+}

+ 30 - 0
config/source.go

@@ -0,0 +1,30 @@
+package config
+
+import (
+	"github.com/go-kratos/kratos/v2/config"
+)
+
+type Source interface {
+	NewSource() (config.Source, error)
+	Validate() bool
+	String() string
+}
+
+type Format string
+
+const (
+	Yaml Format = "yaml"
+)
+
+var formatMap = map[Format]string{
+	Yaml: "yaml",
+}
+
+func (f Format) String() string {
+	return string(f)
+}
+
+func (f Format) Validate() bool {
+	_, ok := formatMap[f]
+	return ok
+}

+ 8 - 1
go.mod

@@ -1,12 +1,17 @@
 module git.ikuban.com/server/kratos-utils
 
-go 1.22
+go 1.23.0
+
+toolchain go1.24.4
 
 require (
+	dario.cat/mergo v1.0.2
 	git.ikuban.com/server/json v0.0.0-20210408053838-50ac5ceda83a
+	git.ikuban.com/server/yaml v0.0.0-20220411094446-ff9c47c8eeaf
 	github.com/dcsunny/gocrypt v0.0.0-20200828060317-4dec5212cc15
 	github.com/dcsunny/mwt v0.0.0-20210128034911-2f50006077f5
 	github.com/dgrijalva/jwt-go v3.2.0+incompatible
+	github.com/elliotchance/orderedmap/v3 v3.1.0
 	github.com/go-kratos/kratos/v2 v2.7.2
 	github.com/go-resty/resty/v2 v2.7.0
 	github.com/google/uuid v1.3.0
@@ -19,11 +24,13 @@ require (
 
 require (
 	github.com/decred/dcrd/dcrec/secp256k1/v4 v4.0.0-20210816181553-5444fa50b93d // indirect
+	github.com/fsnotify/fsnotify v1.6.0 // indirect
 	github.com/go-kratos/aegis v0.2.0 // indirect
 	github.com/go-playground/form/v4 v4.2.0 // indirect
 	github.com/goccy/go-json v0.9.7 // indirect
 	github.com/golang/protobuf v1.5.3 // indirect
 	github.com/gorilla/mux v1.8.0 // indirect
+	github.com/imdario/mergo v0.3.16 // indirect
 	github.com/kr/text v0.1.0 // indirect
 	github.com/lestrrat-go/backoff/v2 v2.0.8 // indirect
 	github.com/lestrrat-go/blackmagic v1.0.0 // indirect

+ 11 - 0
go.sum

@@ -1,5 +1,9 @@
+dario.cat/mergo v1.0.2 h1:85+piFYR1tMbRrLcDwR18y4UKJ3aH1Tbzi24VRW1TK8=
+dario.cat/mergo v1.0.2/go.mod h1:E/hbnu0NxMFBjpMIE34DRGLWqDy0g5FuKDhCb31ngxA=
 git.ikuban.com/server/json v0.0.0-20210408053838-50ac5ceda83a h1:2OcIUm+cnO7dbUNPxoylWFkNizpeLI1RxiV4jVHSDbc=
 git.ikuban.com/server/json v0.0.0-20210408053838-50ac5ceda83a/go.mod h1:tRbbUpdE5PLoYhhkgt+XjE4RiydCsgm2r/Vjq/LtZic=
+git.ikuban.com/server/yaml v0.0.0-20220411094446-ff9c47c8eeaf h1:fqbBaasBkDOOUIGVe1ikz/dHzTLP9e0HayM4NhvhvXs=
+git.ikuban.com/server/yaml v0.0.0-20220411094446-ff9c47c8eeaf/go.mod h1:eovuz52s0DRORmHHZrvkUpRUwDMzFCeKQEm6GwiHOwM=
 github.com/census-instrumentation/opencensus-proto v0.4.1 h1:iKLQ0xPNFxR/2hzXZMrBo8f1j86j5WHzznCCQxV/b8g=
 github.com/census-instrumentation/opencensus-proto v0.4.1/go.mod h1:4T9NM4+4Vw91VeyqjLS6ao50K5bOcLKN6Q42XnYaRYw=
 github.com/cncf/xds/go v0.0.0-20230607035331-e9ce68804cb4 h1:/inchEIKaYC1Akx+H+gqO04wryn5h75LSazbRlnya1k=
@@ -16,10 +20,14 @@ github.com/decred/dcrd/dcrec/secp256k1/v4 v4.0.0-20210816181553-5444fa50b93d h1:
 github.com/decred/dcrd/dcrec/secp256k1/v4 v4.0.0-20210816181553-5444fa50b93d/go.mod h1:tmAIfUFEirG/Y8jhZ9M+h36obRZAk/1fcSpXwAVlfqE=
 github.com/dgrijalva/jwt-go v3.2.0+incompatible h1:7qlOGliEKZXTDg6OTjfoBKDXWrumCAMpl/TFQ4/5kLM=
 github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ=
+github.com/elliotchance/orderedmap/v3 v3.1.0 h1:j4DJ5ObEmMBt/lcwIecKcoRxIQUEnw0L804lXYDt/pg=
+github.com/elliotchance/orderedmap/v3 v3.1.0/go.mod h1:G+Hc2RwaZvJMcS4JpGCOyViCnGeKf0bTYCGTO4uhjSo=
 github.com/envoyproxy/go-control-plane v0.11.2-0.20230627204322-7d0032219fcb h1:kxNVXsNro/lpR5WD+P1FI/yUHn2G03Glber3k8cQL2Y=
 github.com/envoyproxy/go-control-plane v0.11.2-0.20230627204322-7d0032219fcb/go.mod h1:GxGqnjWzl1Gz8WfAfMJSfhvsi4EPZayRb25nLHDWXyA=
 github.com/envoyproxy/protoc-gen-validate v0.10.1 h1:c0g45+xCJhdgFGw7a5QAfdS4byAbud7miNWJ1WwEVf8=
 github.com/envoyproxy/protoc-gen-validate v0.10.1/go.mod h1:DRjgyB0I43LtJapqN6NiRwroiAU2PaFuvk/vjgh61ss=
+github.com/fsnotify/fsnotify v1.6.0 h1:n+5WquG0fcWoWp6xPWfHdbskMCQaFnG6PfBrh1Ky4HY=
+github.com/fsnotify/fsnotify v1.6.0/go.mod h1:sl3t1tCWJFWoRz9R8WJCbQihKKwmorjAbSClcnxKAGw=
 github.com/go-kratos/aegis v0.2.0 h1:dObzCDWn3XVjUkgxyBp6ZeWtx/do0DPZ7LY3yNSJLUQ=
 github.com/go-kratos/aegis v0.2.0/go.mod h1:v0R2m73WgEEYB3XYu6aE2WcMwsZkJ/Rzuf5eVccm7bI=
 github.com/go-kratos/kratos/v2 v2.7.2 h1:WVPGFNLKpv+0odMnCPxM4ZHa2hy9I5FOnwpG3Vv4w5c=
@@ -42,6 +50,8 @@ github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I=
 github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
 github.com/gorilla/mux v1.8.0 h1:i40aqfkR1h2SlN9hojwV5ZA91wcXFOvkdNIeFDP5koI=
 github.com/gorilla/mux v1.8.0/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So=
+github.com/imdario/mergo v0.3.16 h1:wwQJbIsHYGMUyLSPrEq1CT16AhnhNJQ51+4fdHUnCl4=
+github.com/imdario/mergo v0.3.16/go.mod h1:WBLT9ZmE3lPoWsEzCh9LPo3TiwVN+ZKEjmz+hD27ysY=
 github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
 github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk=
 github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
@@ -93,6 +103,7 @@ golang.org/x/net v0.23.0/go.mod h1:JKghWKKOSdJwpW2GEx0Ja7fmaKnMsbu+MWVZTokSYmg=
 golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/sys v0.18.0 h1:DBdB3niSjOA/O0blCZBqDefyWNYveAYMNF1Wum0DYQ4=
 golang.org/x/sys v0.18.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
 golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=