load.go 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123
  1. package config
  2. import (
  3. "errors"
  4. "fmt"
  5. "dario.cat/mergo"
  6. "git.ikuban.com/server/yaml"
  7. "github.com/elliotchance/orderedmap/v3"
  8. "github.com/go-kratos/kratos/v2/config"
  9. )
  10. func Load(sources []Source, bc any) error {
  11. configSources := make([]config.Source, 0)
  12. sourceMap := orderedmap.NewOrderedMap[string, any]() // 有序map控制优先级
  13. for _, source := range sources {
  14. if !source.Validate() {
  15. continue
  16. }
  17. s, err := source.NewSource()
  18. if err != nil {
  19. return fmt.Errorf("%v, new source error: %v", source.String(), err)
  20. }
  21. kvs, err := s.Load()
  22. if err != nil {
  23. return fmt.Errorf("%v, source load error: %v", source.String(), err)
  24. }
  25. for _, v := range kvs {
  26. sourceMap.Set(v.Key, map[string]any{})
  27. }
  28. configSources = append(configSources, s)
  29. }
  30. if sourceMap.Len() == 0 {
  31. return errors.New("config source is empty")
  32. }
  33. c := config.New(
  34. config.WithSource(configSources...),
  35. config.WithDecoder(func(kv *config.KeyValue, v map[string]interface{}) error {
  36. ok := sourceMap.Has(kv.Key)
  37. if !ok {
  38. return fmt.Errorf("unknown config key,key:%s", kv.Key)
  39. }
  40. next := map[string]any{}
  41. err := yaml.Unmarshal(kv.Value, next)
  42. if err != nil {
  43. return err
  44. }
  45. sourceMap.Set(kv.Key, convertMap(next))
  46. merged := make(map[string]any)
  47. for c := range sourceMap.Values() {
  48. err = mergo.Merge(&merged, c, mergo.WithOverride)
  49. if err != nil {
  50. return err
  51. }
  52. }
  53. b, err := yaml.Marshal(merged)
  54. if err != nil {
  55. return err
  56. }
  57. err = yaml.Unmarshal(b, bc)
  58. if err != nil {
  59. return err
  60. }
  61. if defaultCfg != nil {
  62. defaultCfg(bc)
  63. }
  64. return nil
  65. }),
  66. )
  67. if err := c.Load(); err != nil {
  68. return err
  69. }
  70. return nil
  71. }
  72. type DefaultCfg func(bc any)
  73. var defaultCfg DefaultCfg
  74. func SetDefaultCfg(f DefaultCfg) {
  75. defaultCfg = f
  76. }
  77. func convertMap(src interface{}) interface{} {
  78. switch m := src.(type) {
  79. case map[string]interface{}:
  80. dst := make(map[string]interface{}, len(m))
  81. for k, v := range m {
  82. dst[k] = convertMap(v)
  83. }
  84. return dst
  85. case map[interface{}]interface{}:
  86. dst := make(map[interface{}]interface{}, len(m))
  87. for k, v := range m {
  88. dst[k] = convertMap(v)
  89. }
  90. return dst
  91. case []interface{}:
  92. dst := make([]interface{}, len(m))
  93. for k, v := range m {
  94. dst[k] = convertMap(v)
  95. }
  96. return dst
  97. case []byte:
  98. // there will be no binary data in the config data
  99. return string(m)
  100. default:
  101. return src
  102. }
  103. }