diff --git a/common/constant/file/suffix.go b/common/constant/file/suffix.go index bd8876c57e..fe1b41ebbd 100644 --- a/common/constant/file/suffix.go +++ b/common/constant/file/suffix.go @@ -26,3 +26,8 @@ const ( YML = Suffix("yml") PROPERTIES = Suffix("properties") ) + +const ( + PlaceholderPrefix = "${" + PlaceholderSuffix = "}" +) diff --git a/config/config_resolver.go b/config/config_resolver.go index 0e4eefd4a6..517a419841 100644 --- a/config/config_resolver.go +++ b/config/config_resolver.go @@ -18,10 +18,17 @@ package config import ( + "strings" +) + +import ( + log "github.com/dubbogo/gost/log/logger" + "github.com/knadh/koanf" "github.com/knadh/koanf/parsers/json" "github.com/knadh/koanf/parsers/toml" "github.com/knadh/koanf/parsers/yaml" + "github.com/knadh/koanf/providers/confmap" "github.com/knadh/koanf/providers/rawbytes" "github.com/pkg/errors" @@ -66,5 +73,46 @@ func GetConfigResolver(conf *loaderConf) *koanf.Koanf { if err != nil { panic(err) } - return k + return resolvePlaceholder(k) +} + +// resolvePlaceholder replace ${xx} with real value +func resolvePlaceholder(resolver *koanf.Koanf) *koanf.Koanf { + m := make(map[string]interface{}) + for k, v := range resolver.All() { + s, ok := v.(string) + if !ok { + continue + } + newKey, defaultValue := checkPlaceholder(s) + if newKey == "" { + continue + } + m[k] = resolver.Get(newKey) + if m[k] == nil { + m[k] = defaultValue + } + } + err := resolver.Load(confmap.Provider(m, resolver.Delim()), nil) + if err != nil { + log.Errorf("resolvePlaceholder error %s", err) + } + return resolver +} + +func checkPlaceholder(s string) (newKey, defaultValue string) { + s = strings.TrimSpace(s) + if !strings.HasPrefix(s, file.PlaceholderPrefix) || !strings.HasSuffix(s, file.PlaceholderSuffix) { + return + } + s = s[len(file.PlaceholderPrefix) : len(s)-len(file.PlaceholderSuffix)] + indexColon := strings.Index(s, ":") + if indexColon == -1 { + newKey = strings.TrimSpace(s) + return + } + newKey = strings.TrimSpace(s[0:indexColon]) + defaultValue = strings.TrimSpace(s[indexColon+1:]) + + return } diff --git a/config/config_resolver_test.go b/config/config_resolver_test.go new file mode 100644 index 0000000000..449544744c --- /dev/null +++ b/config/config_resolver_test.go @@ -0,0 +1,48 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package config + +import ( + "testing" +) + +import ( + "github.com/knadh/koanf" + + "github.com/stretchr/testify/assert" +) + +func TestResolvePlaceHolder(t *testing.T) { + t.Run("test resolver", func(t *testing.T) { + conf := NewLoaderConf(WithPath("./testdata/config/resolver/application.yaml")) + koan := GetConfigResolver(conf) + assert.Equal(t, koan.Get("dubbo.config-center.address"), koan.Get("dubbo.registries.nacos.address")) + assert.Equal(t, koan.Get("localhost"), koan.Get("dubbo.protocols.dubbo.ip")) + assert.Equal(t, "", koan.Get("dubbo.registries.nacos.group")) + assert.Equal(t, "dev", koan.Get("dubbo.registries.zk.group")) + + rc := NewRootConfigBuilder().Build() + err := koan.UnmarshalWithConf(rc.Prefix(), rc, koanf.UnmarshalConf{Tag: "yaml"}) + assert.Nil(t, err) + assert.Equal(t, rc.ConfigCenter.Address, rc.Registries["nacos"].Address) + //not exist, default + assert.Equal(t, "", rc.Registries["nacos"].Group) + assert.Equal(t, "dev", rc.Registries["zk"].Group) + + }) +} diff --git a/config/testdata/config/resolver/application.yaml b/config/testdata/config/resolver/application.yaml new file mode 100644 index 0000000000..92b157e918 --- /dev/null +++ b/config/testdata/config/resolver/application.yaml @@ -0,0 +1,36 @@ +localhost: 127.0.0.1 +dubbo: + application: + name: dubbo-go + module: local + version: 1.0.0 + owner: zhaoyunxing + config-center: + address: nacos://127.0.0.1:8848 + cluster: dev + namespace: dubbo + log-dir: ./logs + protocols: + dubbo: + name: dubbo + ip: ${localhost} + port: 20000 + registries: + nacos: + timeout: 5s + group: ${notexist} + address: ${dubbo.config-center.address:nacos://127.0.0.1:8848} + zk: + protocol: zookeeper + group: ${notexist:dev} + address: 127.0.0.1:2181 + services: + helloService: + interface: org.dubbo.service.HelloService + registry-ids: nacos,zk + orderService: + interface: org.dubbo.service.OrderService + registry-ids: nacos + provider: + register: true + services: \ No newline at end of file