load.go 2.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113
  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. fmt.Println(string(kv.Value))
  37. ok := sourceMap.Has(kv.Key)
  38. if !ok {
  39. return errors.New("unknown config key")
  40. }
  41. next := map[string]any{}
  42. err := yaml.Unmarshal(kv.Value, next)
  43. if err != nil {
  44. return err
  45. }
  46. sourceMap.Set(kv.Key, convertMap(next))
  47. merged := make(map[string]any)
  48. for c := range sourceMap.Values() {
  49. err = mergo.Merge(&merged, c, mergo.WithOverride)
  50. if err != nil {
  51. return err
  52. }
  53. }
  54. b, err := yaml.Marshal(merged)
  55. if err != nil {
  56. return err
  57. }
  58. err = yaml.Unmarshal(b, bc)
  59. if err != nil {
  60. return err
  61. }
  62. return nil
  63. }),
  64. )
  65. if err := c.Load(); err != nil {
  66. return err
  67. }
  68. return nil
  69. }
  70. func convertMap(src interface{}) interface{} {
  71. switch m := src.(type) {
  72. case map[string]interface{}:
  73. dst := make(map[string]interface{}, len(m))
  74. for k, v := range m {
  75. dst[k] = convertMap(v)
  76. }
  77. return dst
  78. case map[interface{}]interface{}:
  79. dst := make(map[interface{}]interface{}, len(m))
  80. for k, v := range m {
  81. dst[k] = convertMap(v)
  82. }
  83. return dst
  84. case []interface{}:
  85. dst := make([]interface{}, len(m))
  86. for k, v := range m {
  87. dst[k] = convertMap(v)
  88. }
  89. return dst
  90. case []byte:
  91. // there will be no binary data in the config data
  92. return string(m)
  93. default:
  94. return src
  95. }
  96. }