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  }