dubbo.apache.org/dubbo-go/v3@v3.1.1/config/config_resolver.go (about) 1 /* 2 * Licensed to the Apache Software Foundation (ASF) under one or more 3 * contributor license agreements. See the NOTICE file distributed with 4 * this work for additional information regarding copyright ownership. 5 * The ASF licenses this file to You under the Apache License, Version 2.0 6 * (the "License"); you may not use this file except in compliance with 7 * the License. You may obtain a copy of the License at 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the License for the specific language governing permissions and 15 * limitations under the License. 16 */ 17 18 package config 19 20 import ( 21 "strings" 22 ) 23 24 import ( 25 log "github.com/dubbogo/gost/log/logger" 26 27 "github.com/knadh/koanf" 28 "github.com/knadh/koanf/parsers/json" 29 "github.com/knadh/koanf/parsers/toml" 30 "github.com/knadh/koanf/parsers/yaml" 31 "github.com/knadh/koanf/providers/confmap" 32 "github.com/knadh/koanf/providers/rawbytes" 33 34 "github.com/pkg/errors" 35 ) 36 37 import ( 38 "dubbo.apache.org/dubbo-go/v3/common/constant/file" 39 "dubbo.apache.org/dubbo-go/v3/config/parsers/properties" 40 ) 41 42 // GetConfigResolver get config resolver 43 func GetConfigResolver(conf *loaderConf) *koanf.Koanf { 44 var ( 45 k *koanf.Koanf 46 err error 47 ) 48 if len(conf.suffix) <= 0 { 49 conf.suffix = string(file.YAML) 50 } 51 if len(conf.delim) <= 0 { 52 conf.delim = "." 53 } 54 bytes := conf.bytes 55 if len(bytes) <= 0 { 56 panic(errors.New("bytes is nil,please set bytes or file path")) 57 } 58 k = koanf.New(conf.delim) 59 60 switch conf.suffix { 61 case "yaml", "yml": 62 err = k.Load(rawbytes.Provider(bytes), yaml.Parser()) 63 case "json": 64 err = k.Load(rawbytes.Provider(bytes), json.Parser()) 65 case "toml": 66 err = k.Load(rawbytes.Provider(bytes), toml.Parser()) 67 case "properties": 68 err = k.Load(rawbytes.Provider(bytes), properties.Parser()) 69 default: 70 err = errors.Errorf("no support %s file suffix", conf.suffix) 71 } 72 73 if err != nil { 74 panic(err) 75 } 76 return resolvePlaceholder(k) 77 } 78 79 // resolvePlaceholder replace ${xx} with real value 80 func resolvePlaceholder(resolver *koanf.Koanf) *koanf.Koanf { 81 m := make(map[string]interface{}) 82 for k, v := range resolver.All() { 83 s, ok := v.(string) 84 if !ok { 85 continue 86 } 87 newKey, defaultValue := checkPlaceholder(s) 88 if newKey == "" { 89 continue 90 } 91 m[k] = resolver.Get(newKey) 92 if m[k] == nil { 93 m[k] = defaultValue 94 } 95 } 96 err := resolver.Load(confmap.Provider(m, resolver.Delim()), nil) 97 if err != nil { 98 log.Errorf("resolvePlaceholder error %s", err) 99 } 100 return resolver 101 } 102 103 func checkPlaceholder(s string) (newKey, defaultValue string) { 104 s = strings.TrimSpace(s) 105 if !strings.HasPrefix(s, file.PlaceholderPrefix) || !strings.HasSuffix(s, file.PlaceholderSuffix) { 106 return 107 } 108 s = s[len(file.PlaceholderPrefix) : len(s)-len(file.PlaceholderSuffix)] 109 indexColon := strings.Index(s, ":") 110 if indexColon == -1 { 111 newKey = strings.TrimSpace(s) 112 return 113 } 114 newKey = strings.TrimSpace(s[0:indexColon]) 115 defaultValue = strings.TrimSpace(s[indexColon+1:]) 116 117 return 118 }