You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@dubbo.apache.org by al...@apache.org on 2022/02/18 13:04:45 UTC
[dubbo-go] branch 3.0 updated: config merge (#1754)
This is an automated email from the ASF dual-hosted git repository.
alexstocks pushed a commit to branch 3.0
in repository https://gitbox.apache.org/repos/asf/dubbo-go.git
The following commit(s) were added to refs/heads/3.0 by this push:
new 074eac7 config merge (#1754)
074eac7 is described below
commit 074eac796f597ee8b0c1388b00c372617e244e1b
Author: zhaoyunxing <zh...@apache.org>
AuthorDate: Fri Feb 18 21:04:36 2022 +0800
config merge (#1754)
* config merge
* fmt
* add license
* fix npe
* up test
* 代码优化
* add active ut
---
common/constant/key.go | 1 +
config/config_loader.go | 1 +
config/config_loader_options.go | 80 ++++++++++++++++++----
config/config_loader_options_test.go | 36 ++++++++++
config/profiles_config.go | 44 ++++++++++++
config/profiles_config_test.go | 75 ++++++++++++++++++++
config/root_config.go | 3 +
.../testdata/config/active/application-local.yaml | 16 +++++
config/testdata/config/active/application.yaml | 7 ++
9 files changed, 251 insertions(+), 12 deletions(-)
diff --git a/common/constant/key.go b/common/constant/key.go
index 6480841..2b7ef46 100644
--- a/common/constant/key.go
+++ b/common/constant/key.go
@@ -220,6 +220,7 @@ const (
TracingConfigPrefix = "dubbo.tracing"
LoggerConfigPrefix = "dubbo.logger"
CustomConfigPrefix = "dubbo.custom"
+ ProfilesConfigPrefix = "dubbo.profiles"
)
const (
diff --git a/config/config_loader.go b/config/config_loader.go
index 8b8b09a..99c35b2 100644
--- a/config/config_loader.go
+++ b/config/config_loader.go
@@ -45,6 +45,7 @@ func Load(opts ...LoaderConfOption) error {
conf := NewLoaderConf(opts...)
if conf.rc == nil {
koan := GetConfigResolver(conf)
+ koan = conf.MergeConfig(koan)
if err := koan.UnmarshalWithConf(rootConfig.Prefix(),
rootConfig, koanf.UnmarshalConf{Tag: "yaml"}); err != nil {
return err
diff --git a/config/config_loader_options.go b/config/config_loader_options.go
index d2cd1b7..0cd062f 100644
--- a/config/config_loader_options.go
+++ b/config/config_loader_options.go
@@ -26,19 +26,22 @@ import (
)
import (
+ "github.com/knadh/koanf"
+
"github.com/pkg/errors"
)
import (
"dubbo.apache.org/dubbo-go/v3/common/constant"
"dubbo.apache.org/dubbo-go/v3/common/file"
+ "dubbo.apache.org/dubbo-go/v3/common/logger"
)
type loaderConf struct {
// loaderConf file extension default yaml
suffix string
- // loaderConf file path default ./conf
+ // loaderConf file path default ./conf/dubbogo.yaml
path string
// loaderConf file delim default .
@@ -49,18 +52,22 @@ type loaderConf struct {
// user provide rootConfig built by config api
rc *RootConfig
+
+ // config file name
+ name string
}
func NewLoaderConf(opts ...LoaderConfOption) *loaderConf {
- configFilePath := "../conf/dubbogo.yaml"
+ configFilePath := "./conf/dubbogo.yaml"
if configFilePathFromEnv := os.Getenv(constant.ConfigFileEnvKey); configFilePathFromEnv != "" {
configFilePath = configFilePathFromEnv
}
- suffix := strings.Split(configFilePath, ".")
+ name, suffix := resolverFilePath(configFilePath)
conf := &loaderConf{
- suffix: suffix[len(suffix)-1],
+ suffix: suffix,
path: absolutePath(configFilePath),
delim: ".",
+ name: name,
}
for _, opt := range opts {
opt.apply(conf)
@@ -69,11 +76,11 @@ func NewLoaderConf(opts ...LoaderConfOption) *loaderConf {
return conf
}
if len(conf.bytes) <= 0 {
- bytes, err := ioutil.ReadFile(conf.path)
- if err != nil {
+ if bytes, err := ioutil.ReadFile(conf.path); err != nil {
panic(err)
+ } else {
+ conf.bytes = bytes
}
- conf.bytes = bytes
}
return conf
}
@@ -111,13 +118,14 @@ func WithSuffix(suffix file.Suffix) LoaderConfOption {
func WithPath(path string) LoaderConfOption {
return loaderConfigFunc(func(conf *loaderConf) {
conf.path = absolutePath(path)
- bytes, err := ioutil.ReadFile(path)
- if err != nil {
+ if bytes, err := ioutil.ReadFile(path); err != nil {
panic(err)
+ } else {
+ conf.bytes = bytes
}
- conf.bytes = bytes
- genre := strings.Split(path, ".")
- conf.suffix = genre[len(genre)-1]
+ name, suffix := resolverFilePath(path)
+ conf.suffix = suffix
+ conf.name = name
})
}
@@ -180,3 +188,51 @@ func checkFileSuffix(suffix string) error {
}
return errors.Errorf("no support file suffix: %s", suffix)
}
+
+//resolverFilePath resolver file path
+// eg: give a ./conf/dubbogo.yaml return dubbogo and yaml
+func resolverFilePath(path string) (name, suffix string) {
+ paths := strings.Split(path, "/")
+ fileName := strings.Split(paths[len(paths)-1], ".")
+ if len(fileName) < 2 {
+ return fileName[0], string(file.YAML)
+ }
+ return fileName[0], fileName[1]
+}
+
+//MergeConfig merge config file
+func (conf *loaderConf) MergeConfig(koan *koanf.Koanf) *koanf.Koanf {
+ var (
+ activeKoan *koanf.Koanf
+ activeConf *loaderConf
+ )
+ active := koan.String("dubbo.profiles.active")
+ active = getLegalActive(active)
+ logger.Infof("The following profiles are active: %s", active)
+ if defaultActive != active {
+ path := conf.getActiveFilePath(active)
+ if !pathExists(path) {
+ logger.Debugf("Config file:%s not exist skip config merge", path)
+ return koan
+ }
+ activeConf = NewLoaderConf(WithPath(path))
+ activeKoan = GetConfigResolver(activeConf)
+ if err := koan.Merge(activeKoan); err != nil {
+ logger.Debugf("Config merge err %s", err)
+ }
+ }
+ return koan
+}
+
+func (conf *loaderConf) getActiveFilePath(active string) string {
+ suffix := constant.DotSeparator + conf.suffix
+ return strings.ReplaceAll(conf.path, suffix, "") + "-" + active + suffix
+}
+
+func pathExists(path string) bool {
+ if _, err := os.Stat(path); err == nil {
+ return true
+ } else {
+ return !os.IsNotExist(err)
+ }
+}
diff --git a/config/config_loader_options_test.go b/config/config_loader_options_test.go
index 01b517a..2ace22b 100644
--- a/config/config_loader_options_test.go
+++ b/config/config_loader_options_test.go
@@ -18,6 +18,7 @@
package config
import (
+ "strings"
"testing"
)
@@ -71,3 +72,38 @@ func TestNewLoaderConf_WithSuffix(t *testing.T) {
assert.Equal(t, conf.suffix, string(file.PROPERTIES))
}
+
+func TestResolverFilePath(t *testing.T) {
+ name, suffix := resolverFilePath("../config/application.properties")
+ assert.Equal(t, name, "application")
+ assert.Equal(t, suffix, "properties")
+}
+
+func TestResolverFilePath_Illegal_Path(t *testing.T) {
+ name, suffix := resolverFilePath("application.properties")
+ assert.Equal(t, name, "application")
+ assert.Equal(t, suffix, "properties")
+}
+
+func TestResolverFilePath_Illegal_Path_Name(t *testing.T) {
+ name, suffix := resolverFilePath("application")
+ assert.Equal(t, name, "application")
+ assert.Equal(t, suffix, string(file.YAML))
+}
+
+func Test_getActiveFilePath(t *testing.T) {
+ conf := NewLoaderConf(
+ WithSuffix(file.JSON),
+ WithPath("../config/testdata/config/properties/application.properties"),
+ )
+
+ filePath := conf.getActiveFilePath("dev")
+
+ assert.Equal(t, strings.HasSuffix(filePath, "application-dev.properties"), true)
+
+ exists := pathExists(filePath)
+ assert.Equal(t, exists, false)
+ exists = pathExists("application.properties")
+ assert.Equal(t, exists, false)
+
+}
diff --git a/config/profiles_config.go b/config/profiles_config.go
new file mode 100644
index 0000000..a47c8a7
--- /dev/null
+++ b/config/profiles_config.go
@@ -0,0 +1,44 @@
+/*
+ * 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 (
+ "dubbo.apache.org/dubbo-go/v3/common/constant"
+)
+
+var (
+ defaultActive = "default"
+)
+
+type ProfilesConfig struct {
+ // active profiles
+ Active string
+}
+
+// Prefix dubbo.profiles
+func (ProfilesConfig) Prefix() string {
+ return constant.ProfilesConfigPrefix
+}
+
+// getLegalActive if active is null return default
+func getLegalActive(active string) string {
+ if len(active) == 0 {
+ return defaultActive
+ }
+ return active
+}
diff --git a/config/profiles_config_test.go b/config/profiles_config_test.go
new file mode 100644
index 0000000..45e31f4
--- /dev/null
+++ b/config/profiles_config_test.go
@@ -0,0 +1,75 @@
+/*
+ * 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"
+)
+
+import (
+ "dubbo.apache.org/dubbo-go/v3/common/constant"
+)
+
+func TestProfilesConfig_Prefix(t *testing.T) {
+ profiles := &ProfilesConfig{}
+ assert.Equal(t, profiles.Prefix(), constant.ProfilesConfigPrefix)
+}
+
+func TestLoaderConf_MergeConfig(t *testing.T) {
+ rc := NewRootConfigBuilder().Build()
+ conf := NewLoaderConf(WithPath("./testdata/config/active/application.yaml"))
+ koan := GetConfigResolver(conf)
+ koan = conf.MergeConfig(koan)
+
+ err := koan.UnmarshalWithConf(rc.Prefix(), rc, koanf.UnmarshalConf{Tag: "yaml"})
+ assert.Nil(t, err)
+
+ registries := rc.Registries
+ assert.NotNil(t, registries)
+ assert.Equal(t, registries["nacos"].Timeout, "10s")
+ assert.Equal(t, registries["nacos"].Address, "nacos://127.0.0.1:8848")
+
+ protocols := rc.Protocols
+ assert.NotNil(t, protocols)
+ assert.Equal(t, protocols["dubbo"].Name, "dubbo")
+ assert.Equal(t, protocols["dubbo"].Port, "20000")
+
+ consumer := rc.Consumer
+ assert.NotNil(t, consumer)
+ assert.Equal(t, consumer.References["helloService"].Protocol, "dubbo")
+ assert.Equal(t, consumer.References["helloService"].InterfaceName, "org.github.dubbo.HelloService")
+}
+
+func Test_getLegalActive(t *testing.T) {
+
+ t.Run("default", func(t *testing.T) {
+ active := getLegalActive("")
+ assert.Equal(t, active, "default")
+ })
+
+ t.Run("normal", func(t *testing.T) {
+ active := getLegalActive("active")
+ assert.Equal(t, active, "active")
+ })
+}
diff --git a/config/root_config.go b/config/root_config.go
index 4a4807a..8a7a01c 100644
--- a/config/root_config.go
+++ b/config/root_config.go
@@ -85,6 +85,9 @@ type RootConfig struct {
CacheFile string `yaml:"cache_file" json:"cache_file,omitempty" property:"cache_file"`
Custom *CustomConfig `yaml:"custom" json:"custom,omitempty" property:"custom"`
+
+ // Profiles config
+ Profiles *ProfilesConfig `yaml:"profiles" json:"profiles,omitempty" property:"profiles"`
}
func SetRootConfig(r RootConfig) {
diff --git a/config/testdata/config/active/application-local.yaml b/config/testdata/config/active/application-local.yaml
new file mode 100644
index 0000000..0d87a9e
--- /dev/null
+++ b/config/testdata/config/active/application-local.yaml
@@ -0,0 +1,16 @@
+dubbo:
+ profiles:
+ active: local
+ registries:
+ nacos:
+ timeout: 10s
+ address: nacos://127.0.0.1:8848
+ protocols:
+ dubbo:
+ name: dubbo
+ port: 20000
+ consumer:
+ references:
+ helloService:
+ protocol: dubbo
+ interface: org.github.dubbo.HelloService
\ No newline at end of file
diff --git a/config/testdata/config/active/application.yaml b/config/testdata/config/active/application.yaml
new file mode 100644
index 0000000..1f51654
--- /dev/null
+++ b/config/testdata/config/active/application.yaml
@@ -0,0 +1,7 @@
+dubbo:
+ profiles:
+ active: local
+ registries:
+ nacos:
+ timeout: 3s
+ address: nacos://127.0.0.1:8848
\ No newline at end of file