func WithConfigCenterNamespace(namespace string) CenterConfigOpt {
	return func(config *CenterConfig) {
		config.Namespace = namespace
	}
}
WithConfigCenterNamespace set ProtocolConfig with given @namespace
package config
import (
	"net/url"
	"strings"
)
import (
	"github.com/creasty/defaults"
	"github.com/knadh/koanf"
	"github.com/knadh/koanf/parsers/yaml"
	"github.com/knadh/koanf/providers/rawbytes"
	"github.com/pkg/errors"
)
import (
	"dubbo.apache.org/dubbo-go/v3/common"
	conf "dubbo.apache.org/dubbo-go/v3/common/config"
	"dubbo.apache.org/dubbo-go/v3/common/constant"
	"dubbo.apache.org/dubbo-go/v3/common/extension"
	"dubbo.apache.org/dubbo-go/v3/common/logger"
	"dubbo.apache.org/dubbo-go/v3/config_center"
)
type CenterConfig struct {
	Protocol string `validate:"required" yaml:"protocol"  json:"protocol,omitempty"`
	Address  string `validate:"required" yaml:"address" json:"address,omitempty"`
	DataId   string `validate:"required" yaml:"data-id" json:"data-id,omitempty"`
	Cluster  string `yaml:"cluster" json:"cluster,omitempty"`
	Group    string `default:"dubbo" yaml:"group" json:"group,omitempty"`
	Username string `yaml:"username" json:"username,omitempty"`
	Password string `yaml:"password" json:"password,omitempty"`
	LogDir string `yaml:"log-dir" json:"log-dir,omitempty"`
	ConfigFile string `default:"dubbo.properties" yaml:"config-file"  json:"config-file,omitempty"`
	Namespace  string `default:"dubbo" yaml:"namespace"  json:"namespace,omitempty"`
	AppConfigFile string `default:"dubbo.properties" yaml:"app-config-file"  json:"app-config-file,omitempty"`
	AppID   string `default:"dubbo" yaml:"app-id"  json:"app-id,omitempty"`
	Timeout string `default:"10s" yaml:"timeout"  json:"timeout,omitempty"`
	RemoteRef string            `required:"false"  yaml:"remote-ref"  json:"remote-ref,omitempty"`
	Params    map[string]string `yaml:"params"  json:"parameters,omitempty"`
}
func (CenterConfig) Prefix() string {
	return constant.ConfigCenterPrefix
}
func GetConfigCenterInstance(opts ...CenterConfigOpt) *CenterConfig {
	cc := &CenterConfig{
		Params: make(map[string]string, 1),
	}
	for _, opt := range opts {
		opt(cc)
	}
	return cc
}
func (c *CenterConfig) check() error {
	if err := defaults.Set(c); err != nil {
		return err
	}
	c.translateConfigAddress()
	return verify(c)
}
func (c *CenterConfig) Init(rc *RootConfig) error {
	if c == nil {
		return nil
	}
	if err := c.check(); err != nil {
		return err
	}
	return startConfigCenter(rc)
}
func (c *CenterConfig) GetUrlMap() url.Values {
	urlMap := url.Values{}
	urlMap.Set(constant.CONFIG_NAMESPACE_KEY, c.Namespace)
	urlMap.Set(constant.CONFIG_GROUP_KEY, c.Group)
	urlMap.Set(constant.CONFIG_CLUSTER_KEY, c.Cluster)
	urlMap.Set(constant.CONFIG_APP_ID_KEY, c.AppID)
	urlMap.Set(constant.CONFIG_LOG_DIR_KEY, c.LogDir)
	urlMap.Set(constant.CONFIG_USERNAME_KEY, c.Username)
	urlMap.Set(constant.CONFIG_PASSWORD_KEY, c.Password)
	urlMap.Set(constant.CONFIG_TIMEOUT_KEY, c.Timeout)
	for key, val := range c.Params {
		urlMap.Set(key, val)
	}
	return urlMap
}
func (c *CenterConfig) translateConfigAddress() string {
	if strings.Contains(c.Address, "://") {
		translatedUrl, err := url.Parse(c.Address)
		if err != nil {
			logger.Errorf("The config address:%s is invalid, error: %#v", c.Address, err)
			panic(err)
		}
		c.Protocol = translatedUrl.Scheme
		c.Address = strings.Replace(c.Address, translatedUrl.Scheme+"://", "", -1)
	}
	return c.Address
}
func (c *CenterConfig) toURL() (*common.URL, error) {
	return common.NewURL(c.Address,
		common.WithProtocol(c.Protocol),
		common.WithParams(c.GetUrlMap()))
}
func startConfigCenter(rc *RootConfig) error {
	cc := rc.ConfigCenter
	configCenterUrl, err := cc.toURL()
	if err != nil {
		return err
	}
	strConf, err := cc.prepareEnvironment(configCenterUrl)
	if err != nil {
		return errors.WithMessagef(err, "start config center error!")
	}
	koan := koanf.New(".")
	if err = koan.Load(rawbytes.Provider([]byte(strConf)), yaml.Parser()); err != nil {
		return err
	}
	if err = koan.UnmarshalWithConf(rc.Prefix(),
		rc, koanf.UnmarshalConf{Tag: "yaml"}); err != nil {
		return err
	}
	return nil
}
func (c *CenterConfig) GetDynamicConfiguration() (config_center.DynamicConfiguration, error) {
	configCenterUrl, err := c.toURL()
	if err != nil {
		return nil, err
	}
	factory := extension.GetConfigCenterFactory(configCenterUrl.Protocol)
	if factory == nil {
		return nil, errors.New("get config center factory failed")
	}
	return factory.GetDynamicConfiguration(configCenterUrl)
}
func (c *CenterConfig) prepareEnvironment(configCenterUrl *common.URL) (string, error) {
	factory := extension.GetConfigCenterFactory(configCenterUrl.Protocol)
	if factory == nil {
		return "", errors.New("get config center factory failed")
	}
	dynamicConfig, err := factory.GetDynamicConfiguration(configCenterUrl)
	if err != nil {
		logger.Errorf("Get dynamic configuration error , error message is %v", err)
		return "", errors.WithStack(err)
	}
	envInstance := conf.GetEnvInstance()
	envInstance.SetDynamicConfiguration(dynamicConfig)
	return dynamicConfig.GetProperties(c.DataId, config_center.WithGroup(c.Group))
}
type CenterConfigOpt func(config *CenterConfig)
func NewConfigCenterConfig(opts ...CenterConfigOpt) *CenterConfig {
	centerConfig := &CenterConfig{
		Params: make(map[string]string),
	}
	for _, o := range opts {
		o(centerConfig)
	}
	return centerConfig
}
func WithConfigCenterProtocol(protocol string) CenterConfigOpt {
	return func(config *CenterConfig) {
		config.Protocol = protocol
	}
}
func WithConfigCenterAddress(addr string) CenterConfigOpt {
	return func(config *CenterConfig) {
		config.Address = addr
	}
}
func WithConfigCenterDataID(dataID string) CenterConfigOpt {
	return func(config *CenterConfig) {
		config.DataId = dataID
	}
}
func WithConfigCenterGroup(group string) CenterConfigOpt {
	return func(config *CenterConfig) {
		config.Group = group
	}
}
func WithConfigCenterUsername(username string) CenterConfigOpt {
	return func(config *CenterConfig) {
		config.Username = username
	}
}
func WithConfigCenterPassword(password string) CenterConfigOpt {
	return func(config *CenterConfig) {
		config.Password = password
	}
}