From 30f75d330aa34addd0a9f593e147b59878caa76b Mon Sep 17 00:00:00 2001 From: alanxtl Date: Mon, 22 Jun 2026 12:51:40 +0800 Subject: [PATCH 1/2] decouple config reader --- common/extension/config_reader.go | 14 ++++++++++---- protocol/rest/config/reader/rest_config_reader.go | 3 +-- 2 files changed, 11 insertions(+), 6 deletions(-) diff --git a/common/extension/config_reader.go b/common/extension/config_reader.go index e493d3c3f3..2670adf372 100644 --- a/common/extension/config_reader.go +++ b/common/extension/config_reader.go @@ -18,21 +18,27 @@ package extension import ( - "dubbo.apache.org/dubbo-go/v3/config/interfaces" + "bytes" ) +// ConfigReader is used to read config from consumer or provider. +type ConfigReader interface { + ReadConsumerConfig(reader *bytes.Buffer) error + ReadProviderConfig(reader *bytes.Buffer) error +} + var ( - configReaders = NewRegistry[func() interfaces.ConfigReader]("config reader") + configReaders = NewRegistry[func() ConfigReader]("config reader") defaults = NewRegistry[string]("default config reader") ) // SetConfigReaders sets a creator of config reader with @name -func SetConfigReaders(name string, v func() interfaces.ConfigReader) { +func SetConfigReaders(name string, v func() ConfigReader) { configReaders.Register(name, v) } // GetConfigReaders gets a config reader with @name -func GetConfigReaders(name string) interfaces.ConfigReader { +func GetConfigReaders(name string) ConfigReader { return configReaders.MustGet(name)() } diff --git a/protocol/rest/config/reader/rest_config_reader.go b/protocol/rest/config/reader/rest_config_reader.go index c052d67215..5dab913c08 100644 --- a/protocol/rest/config/reader/rest_config_reader.go +++ b/protocol/rest/config/reader/rest_config_reader.go @@ -34,7 +34,6 @@ import ( import ( "dubbo.apache.org/dubbo-go/v3/common/constant" "dubbo.apache.org/dubbo-go/v3/common/extension" - "dubbo.apache.org/dubbo-go/v3/config/interfaces" "dubbo.apache.org/dubbo-go/v3/protocol/rest/config" ) @@ -45,7 +44,7 @@ func init() { type RestConfigReader struct{} -func NewRestConfigReader() interfaces.ConfigReader { +func NewRestConfigReader() extension.ConfigReader { return &RestConfigReader{} } From 62c832d929364549965c28e176234432c47f69e2 Mon Sep 17 00:00:00 2001 From: alanxtl Date: Mon, 22 Jun 2026 12:52:27 +0800 Subject: [PATCH 2/2] complete delete config package --- config/application_config.go | 131 ---- config/application_config_test.go | 68 -- config/client_protocol_config.go | 26 - config/config_center_config.go | 244 ------- config/config_loader.go | 123 ---- config/config_loader_options.go | 227 ------- config/config_loader_options_test.go | 110 ---- config/config_resolver.go | 112 ---- config/config_resolver_test.go | 49 -- config/config_setter.go | 22 - config/config_utils.go | 122 ---- config/config_utils_test.go | 83 --- config/consumer_config.go | 279 -------- config/custom_config.go | 80 --- config/custom_config_test.go | 90 --- config/doc.go | 21 - config/generic/generic_service.go | 32 - config/graceful_shutdown.go | 243 ------- config/graceful_shutdown_config.go | 79 --- config/graceful_shutdown_config_test.go | 104 --- config/graceful_shutdown_signal_darwin.go | 38 -- config/graceful_shutdown_signal_linux.go | 38 -- config/graceful_shutdown_signal_windows.go | 35 - config/graceful_shutdown_test.go | 205 ------ config/http3_config.go | 38 -- config/interfaces/config_post_processor.go | 32 - config/interfaces/config_reader.go | 28 - config/logger_config.go | 223 ------- config/logger_config_test.go | 176 ----- config/metadata_config.go | 237 ------- config/metadata_config_test.go | 48 -- config/method_config.go | 112 ---- config/metric_config.go | 175 ----- config/metric_config_test.go | 40 -- config/mock_rpcservice.go | 40 -- config/mock_rpcservice_test.go | 40 -- config/options.go | 123 ---- config/otel_config.go | 120 ---- config/otel_config_test.go | 40 -- config/profiles_config.go | 44 -- config/profiles_config_test.go | 76 --- config/protocol_config.go | 100 --- config/protocol_config_test.go | 53 -- config/provider_config.go | 279 -------- config/provider_config_test.go | 87 --- config/reference_config.go | 547 ---------------- config/reference_config_test.go | 483 -------------- config/registry_config.go | 491 -------------- config/registry_config_test.go | 150 ----- config/remote_config.go | 154 ----- config/remote_config_test.go | 78 --- config/root_config.go | 429 ------------- config/root_config_test.go | 142 ---- config/router_config.go | 214 ------- config/router_config_test.go | 87 --- config/service.go | 148 ----- config/service_config.go | 606 ------------------ config/service_config_test.go | 231 ------- config/service_discovery_config.go | 74 --- config/service_discovery_config_test.go | 45 -- config/service_test.go | 118 ---- config/ssl_config.go | 49 -- config/ssl_config_test.go | 47 -- config/testdata/application.yaml | 50 -- .../config/active/application-local.yaml | 31 - .../testdata/config/active/application.yaml | 22 - config/testdata/config/app/application.yaml | 36 -- .../config/application/application.yaml | 19 - .../config/center/conf-application.yaml | 28 - config/testdata/config/custom/custom.yaml | 28 - config/testdata/config/custom/empty.yaml | 26 - config/testdata/config/logger/empty_log.yaml | 26 - config/testdata/config/logger/file_log.yaml | 37 -- config/testdata/config/logger/log.yaml | 51 -- .../config/properties/application.properties | 13 - .../testdata/config/protocol/application.yaml | 27 - .../config/protocol/empty_application.yaml | 22 - .../testdata/config/provider/application.yaml | 32 - .../provider/empty_registry_application.yaml | 23 - .../config/provider/registry_application.yaml | 28 - .../testdata/config/registry/application.yaml | 25 - .../config/registry/empty_application.yaml | 17 - .../testdata/config/resolver/application.yaml | 51 -- config/testdata/consumer_config.properties | 52 -- config/testdata/consumer_config.yml | 111 ---- .../consumer_config_with_configcenter.yml | 58 -- .../consumer_config_withoutProtocol.yml | 96 --- config/testdata/provider_config.properties | 58 -- config/testdata/provider_config.yml | 114 ---- .../provider_config_withoutProtocol.yml | 94 --- config/testdata/root_config_test.yml | 38 -- config/testdata/router_config_dest_rule.yml | 32 - .../router_config_virtual_service.yml | 185 ------ config/tls_config.go | 146 ----- config/tls_config_test.go | 45 -- config/tracing_config.go | 47 -- config/tracing_config_test.go | 41 -- config/triple_config.go | 32 - 98 files changed, 10506 deletions(-) delete mode 100644 config/application_config.go delete mode 100644 config/application_config_test.go delete mode 100644 config/client_protocol_config.go delete mode 100644 config/config_center_config.go delete mode 100644 config/config_loader.go delete mode 100644 config/config_loader_options.go delete mode 100644 config/config_loader_options_test.go delete mode 100644 config/config_resolver.go delete mode 100644 config/config_resolver_test.go delete mode 100644 config/config_setter.go delete mode 100644 config/config_utils.go delete mode 100644 config/config_utils_test.go delete mode 100644 config/consumer_config.go delete mode 100644 config/custom_config.go delete mode 100644 config/custom_config_test.go delete mode 100644 config/doc.go delete mode 100644 config/generic/generic_service.go delete mode 100644 config/graceful_shutdown.go delete mode 100644 config/graceful_shutdown_config.go delete mode 100644 config/graceful_shutdown_config_test.go delete mode 100644 config/graceful_shutdown_signal_darwin.go delete mode 100644 config/graceful_shutdown_signal_linux.go delete mode 100644 config/graceful_shutdown_signal_windows.go delete mode 100644 config/graceful_shutdown_test.go delete mode 100644 config/http3_config.go delete mode 100644 config/interfaces/config_post_processor.go delete mode 100644 config/interfaces/config_reader.go delete mode 100644 config/logger_config.go delete mode 100644 config/logger_config_test.go delete mode 100644 config/metadata_config.go delete mode 100644 config/metadata_config_test.go delete mode 100644 config/method_config.go delete mode 100644 config/metric_config.go delete mode 100644 config/metric_config_test.go delete mode 100644 config/mock_rpcservice.go delete mode 100644 config/mock_rpcservice_test.go delete mode 100644 config/options.go delete mode 100644 config/otel_config.go delete mode 100644 config/otel_config_test.go delete mode 100644 config/profiles_config.go delete mode 100644 config/profiles_config_test.go delete mode 100644 config/protocol_config.go delete mode 100644 config/protocol_config_test.go delete mode 100644 config/provider_config.go delete mode 100644 config/provider_config_test.go delete mode 100644 config/reference_config.go delete mode 100644 config/reference_config_test.go delete mode 100644 config/registry_config.go delete mode 100644 config/registry_config_test.go delete mode 100644 config/remote_config.go delete mode 100644 config/remote_config_test.go delete mode 100644 config/root_config.go delete mode 100644 config/root_config_test.go delete mode 100644 config/router_config.go delete mode 100644 config/router_config_test.go delete mode 100644 config/service.go delete mode 100644 config/service_config.go delete mode 100644 config/service_config_test.go delete mode 100644 config/service_discovery_config.go delete mode 100644 config/service_discovery_config_test.go delete mode 100644 config/service_test.go delete mode 100644 config/ssl_config.go delete mode 100644 config/ssl_config_test.go delete mode 100644 config/testdata/application.yaml delete mode 100644 config/testdata/config/active/application-local.yaml delete mode 100644 config/testdata/config/active/application.yaml delete mode 100644 config/testdata/config/app/application.yaml delete mode 100644 config/testdata/config/application/application.yaml delete mode 100644 config/testdata/config/center/conf-application.yaml delete mode 100644 config/testdata/config/custom/custom.yaml delete mode 100644 config/testdata/config/custom/empty.yaml delete mode 100644 config/testdata/config/logger/empty_log.yaml delete mode 100644 config/testdata/config/logger/file_log.yaml delete mode 100644 config/testdata/config/logger/log.yaml delete mode 100644 config/testdata/config/properties/application.properties delete mode 100644 config/testdata/config/protocol/application.yaml delete mode 100644 config/testdata/config/protocol/empty_application.yaml delete mode 100644 config/testdata/config/provider/application.yaml delete mode 100644 config/testdata/config/provider/empty_registry_application.yaml delete mode 100644 config/testdata/config/provider/registry_application.yaml delete mode 100644 config/testdata/config/registry/application.yaml delete mode 100644 config/testdata/config/registry/empty_application.yaml delete mode 100644 config/testdata/config/resolver/application.yaml delete mode 100644 config/testdata/consumer_config.properties delete mode 100644 config/testdata/consumer_config.yml delete mode 100644 config/testdata/consumer_config_with_configcenter.yml delete mode 100644 config/testdata/consumer_config_withoutProtocol.yml delete mode 100644 config/testdata/provider_config.properties delete mode 100644 config/testdata/provider_config.yml delete mode 100644 config/testdata/provider_config_withoutProtocol.yml delete mode 100644 config/testdata/root_config_test.yml delete mode 100644 config/testdata/router_config_dest_rule.yml delete mode 100644 config/testdata/router_config_virtual_service.yml delete mode 100644 config/tls_config.go delete mode 100644 config/tls_config_test.go delete mode 100644 config/tracing_config.go delete mode 100644 config/tracing_config_test.go delete mode 100644 config/triple_config.go diff --git a/config/application_config.go b/config/application_config.go deleted file mode 100644 index c245c8a5ec..0000000000 --- a/config/application_config.go +++ /dev/null @@ -1,131 +0,0 @@ -/* - * 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 ( - "strconv" -) - -import ( - "github.com/creasty/defaults" - - "github.com/pkg/errors" -) - -import ( - "dubbo.apache.org/dubbo-go/v3/common/constant" -) - -// ApplicationConfig is a configuration for current applicationConfig, whether the applicationConfig is a provider or a consumer -type ApplicationConfig struct { - Organization string `default:"dubbo-go" yaml:"organization" json:"organization,omitempty" property:"organization"` - Name string `yaml:"name" json:"name,omitempty" property:"name"` - Module string `default:"sample" yaml:"module" json:"module,omitempty" property:"module"` - Group string `yaml:"group" json:"group,omitempty" property:"module"` - Version string `yaml:"version" json:"version,omitempty" property:"version"` - Owner string `default:"dubbo-go" yaml:"owner" json:"owner,omitempty" property:"owner"` - Environment string `yaml:"environment" json:"environment,omitempty" property:"environment"` - // the metadata type. remote or local - MetadataType string `default:"local" yaml:"metadata-type" json:"metadataType,omitempty" property:"metadataType"` - Tag string `yaml:"tag" json:"tag,omitempty" property:"tag"` - MetadataServicePort string `yaml:"metadata-service-port" json:"metadata-service-port,omitempty" property:"metadata-service-port"` - MetadataServiceProtocol string `yaml:"metadata-service-protocol" json:"metadata-service-protocol,omitempty" property:"metadata-service-protocol"` -} - -// Prefix dubbo.application -func (ac *ApplicationConfig) Prefix() string { - return constant.ApplicationConfigPrefix -} - -// Init application config and set default value -func (ac *ApplicationConfig) Init() error { - if ac == nil { - return errors.New("application is null") - } - if err := ac.check(); err != nil { - return err - } - if ac.Name == "" { - ac.Name = constant.DefaultDubboApp - } - return nil -} - -func (ac *ApplicationConfig) check() error { - if err := defaults.Set(ac); err != nil { - return err - } - return verify(ac) -} - -func NewApplicationConfigBuilder() *ApplicationConfigBuilder { - return &ApplicationConfigBuilder{application: &ApplicationConfig{}} -} - -type ApplicationConfigBuilder struct { - application *ApplicationConfig -} - -func (acb *ApplicationConfigBuilder) SetOrganization(organization string) *ApplicationConfigBuilder { - acb.application.Organization = organization - return acb -} - -func (acb *ApplicationConfigBuilder) SetName(name string) *ApplicationConfigBuilder { - acb.application.Name = name - return acb -} - -func (acb *ApplicationConfigBuilder) SetModule(module string) *ApplicationConfigBuilder { - acb.application.Module = module - return acb -} - -func (acb *ApplicationConfigBuilder) SetVersion(version string) *ApplicationConfigBuilder { - acb.application.Version = version - return acb -} - -func (acb *ApplicationConfigBuilder) SetOwner(owner string) *ApplicationConfigBuilder { - acb.application.Owner = owner - return acb -} - -func (acb *ApplicationConfigBuilder) SetEnvironment(environment string) *ApplicationConfigBuilder { - acb.application.Environment = environment - return acb -} - -func (acb *ApplicationConfigBuilder) SetMetadataType(metadataType string) *ApplicationConfigBuilder { - acb.application.MetadataType = metadataType - return acb -} - -func (acb *ApplicationConfigBuilder) SetMetadataServicePort(port int) *ApplicationConfigBuilder { - acb.application.MetadataServicePort = strconv.Itoa(port) - return acb -} - -func (acb *ApplicationConfigBuilder) SetMetadataServiceProtocol(protocol string) *ApplicationConfigBuilder { - acb.application.MetadataServiceProtocol = protocol - return acb -} - -func (acb *ApplicationConfigBuilder) Build() *ApplicationConfig { - return acb.application -} diff --git a/config/application_config_test.go b/config/application_config_test.go deleted file mode 100644 index adbc51b8a1..0000000000 --- a/config/application_config_test.go +++ /dev/null @@ -1,68 +0,0 @@ -/* - * 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/stretchr/testify/assert" - "github.com/stretchr/testify/require" -) - -import ( - "dubbo.apache.org/dubbo-go/v3/common/constant" - _ "dubbo.apache.org/dubbo-go/v3/metadata/report/nacos" -) - -func TestApplicationConfig(t *testing.T) { - - err := Load(WithPath("./testdata/config/application/application.yaml")) - require.NoError(t, err) - - center := GetRootConfig().Registries - assert.NotNil(t, center) -} - -func TestApplicationConfigBuilder(t *testing.T) { - - application := NewApplicationConfigBuilder(). - SetOrganization("organization"). - SetName("name"). - SetModule("module"). - SetVersion("version"). - SetOwner("owner"). - SetEnvironment("environment"). - SetMetadataType("metadataType"). - Build() - - err := application.check() - require.NoError(t, err) - err = application.Init() - - require.NoError(t, err) - assert.Equal(t, "name", application.Name) - assert.Equal(t, "organization", application.Organization) - assert.Equal(t, "module", application.Module) - assert.Equal(t, "version", application.Version) - assert.Equal(t, "owner", application.Owner) - assert.Equal(t, "environment", application.Environment) - assert.Equal(t, "metadataType", application.MetadataType) - assert.Equal(t, constant.ApplicationConfigPrefix, application.Prefix()) -} diff --git a/config/client_protocol_config.go b/config/client_protocol_config.go deleted file mode 100644 index e801a0f78e..0000000000 --- a/config/client_protocol_config.go +++ /dev/null @@ -1,26 +0,0 @@ -/* - * 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 - -// ClientProtocolConfig represents the config of client's protocol -type ClientProtocolConfig struct { - // TODO: maybe we could use this field - Name string `yaml:"name" json:"name,omitempty" property:"name"` - - TripleConfig *TripleConfig `yaml:"triple" json:"triple,omitempty" property:"triple"` -} diff --git a/config/config_center_config.go b/config/config_center_config.go deleted file mode 100644 index 0c82a97dbe..0000000000 --- a/config/config_center_config.go +++ /dev/null @@ -1,244 +0,0 @@ -/* - * 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 ( - "net/url" - "strings" -) - -import ( - "github.com/creasty/defaults" - - "github.com/dubbogo/gost/log/logger" - - "github.com/knadh/koanf" - - "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/config_center" - "dubbo.apache.org/dubbo-go/v3/metrics" - metricsConfigCenter "dubbo.apache.org/dubbo-go/v3/metrics/config_center" - "dubbo.apache.org/dubbo-go/v3/remoting" -) - -// CenterConfig is configuration for config center -// -// ConfigCenter also introduced concepts of namespace and group to better manage Key-Value pairs by group, -// those configs are already built-in in many professional third-party configuration centers. -// In most cases, namespace is used to isolate different tenants, while group is used to divide the key set from one tenant into groups. -// -// CenterConfig has currently supported Zookeeper, Nacos, Etcd, Consul, Apollo -type CenterConfig struct { - Protocol string `validate:"required" yaml:"protocol" json:"protocol,omitempty"` - Address string `validate:"required" yaml:"address" json:"address,omitempty"` - DataId string `yaml:"data-id" json:"data-id,omitempty"` - Cluster string `yaml:"cluster" json:"cluster,omitempty"` - Group string `yaml:"group" json:"group,omitempty"` - Username string `yaml:"username" json:"username,omitempty"` - Password string `yaml:"password" json:"password,omitempty"` - Namespace string `yaml:"namespace" json:"namespace,omitempty"` - AppID string `default:"dubbo" yaml:"app-id" json:"app-id,omitempty"` - Timeout string `default:"10s" yaml:"timeout" json:"timeout,omitempty"` - Params map[string]string `yaml:"params" json:"parameters,omitempty"` - - //FileExtension the suffix of config dataId, also the file extension of config content - FileExtension string `default:"yaml" yaml:"file-extension" json:"file-extension" ` -} - -// Prefix dubbo.config-center -func (CenterConfig) Prefix() string { - return constant.ConfigCenterPrefix -} - -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) -} - -// GetUrlMap gets url map from ConfigCenterConfig -func (c *CenterConfig) GetUrlMap() url.Values { - urlMap := url.Values{} - urlMap.Set(constant.ConfigNamespaceKey, c.Namespace) - urlMap.Set(constant.ConfigGroupKey, c.Group) - urlMap.Set(constant.ConfigClusterKey, c.Cluster) - urlMap.Set(constant.ConfigAppIDKey, c.AppID) - urlMap.Set(constant.ConfigTimeoutKey, c.Timeout) - urlMap.Set(constant.ClientNameKey, clientNameID(c, c.Protocol, c.Address)) - - for key, val := range c.Params { - urlMap.Set(key, val) - } - return urlMap -} - -// translateConfigAddress translate config address -// -// eg:address=nacos://127.0.0.1:8848 will return 127.0.0.1:8848 and protocol will set nacos -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.ReplaceAll(c.Address, translatedUrl.Scheme+"://", "") - } - return c.Address -} - -// toURL will compatible with baseConfig.ShutdownConfig.Address and baseConfig.ShutdownConfig.RemoteRef before 1.6.0 -// After 1.6.0 will not compatible, only baseConfig.ShutdownConfig.RemoteRef -func (c *CenterConfig) toURL() (*common.URL, error) { - return common.NewURL(c.Address, - common.WithProtocol(c.Protocol), - common.WithParams(c.GetUrlMap()), - common.WithUsername(c.Username), - common.WithPassword(c.Password), - ) - -} - -// startConfigCenter will start the config center. -// it will prepare the environment -func startConfigCenter(rc *RootConfig) error { - cc := rc.ConfigCenter - dynamicConfig, err := cc.GetDynamicConfiguration() - if err != nil { - logger.Errorf("[Config Center] Start dynamic configuration center error, error message is %v", err) - return err - } - - strConf, err := dynamicConfig.GetProperties(cc.DataId, config_center.WithGroup(cc.Group)) - if err != nil { - logger.Warnf("[Config Center] Dynamic config center has started, but config may not be initialized, because: %s", err) - return nil - } - defer metrics.Publish(metricsConfigCenter.NewIncMetricEvent(cc.DataId, cc.Group, remoting.EventTypeAdd, cc.Protocol)) - if len(strConf) == 0 { - logger.Warnf("[Config Center] Dynamic config center has started, but got empty config with config-center configuration %+v\n"+ - "Please check if your config-center config is correct.", cc) - return nil - } - config := NewLoaderConf(WithDelim("."), WithGenre(cc.FileExtension), WithBytes([]byte(strConf))) - koan := GetConfigResolver(config) - if err = koan.UnmarshalWithConf(rc.Prefix(), rc, koanf.UnmarshalConf{Tag: "yaml"}); err != nil { - return err - } - - dynamicConfig.AddListener(cc.DataId, rc, config_center.WithGroup(cc.Group)) - return nil -} - -func (c *CenterConfig) CreateDynamicConfiguration() (config_center.DynamicConfiguration, error) { - configCenterUrl, err := c.toURL() - if err != nil { - return nil, err - } - factory, err := extension.GetConfigCenterFactory(configCenterUrl.Protocol) - if err != nil { - return nil, err - } - return factory.GetDynamicConfiguration(configCenterUrl) -} - -func (c *CenterConfig) GetDynamicConfiguration() (config_center.DynamicConfiguration, error) { - envInstance := conf.GetEnvInstance() - if envInstance.GetDynamicConfiguration() != nil { - return envInstance.GetDynamicConfiguration(), nil - } - dynamicConfig, err := c.CreateDynamicConfiguration() - if err != nil { - return nil, errors.WithStack(err) - } - envInstance.SetDynamicConfiguration(dynamicConfig) - return dynamicConfig, nil -} - -func NewConfigCenterConfigBuilder() *ConfigCenterConfigBuilder { - return &ConfigCenterConfigBuilder{configCenterConfig: newEmptyConfigCenterConfig()} -} - -type ConfigCenterConfigBuilder struct { - configCenterConfig *CenterConfig -} - -func (ccb *ConfigCenterConfigBuilder) SetProtocol(protocol string) *ConfigCenterConfigBuilder { - ccb.configCenterConfig.Protocol = protocol - return ccb -} - -func (ccb *ConfigCenterConfigBuilder) SetUserName(userName string) *ConfigCenterConfigBuilder { - ccb.configCenterConfig.Username = userName - return ccb -} - -func (ccb *ConfigCenterConfigBuilder) SetAddress(address string) *ConfigCenterConfigBuilder { - ccb.configCenterConfig.Address = address - return ccb -} - -func (ccb *ConfigCenterConfigBuilder) SetPassword(password string) *ConfigCenterConfigBuilder { - ccb.configCenterConfig.Password = password - return ccb -} - -func (ccb *ConfigCenterConfigBuilder) SetNamespace(namespace string) *ConfigCenterConfigBuilder { - ccb.configCenterConfig.Namespace = namespace - return ccb -} - -func (ccb *ConfigCenterConfigBuilder) SetDataID(dataID string) *ConfigCenterConfigBuilder { - ccb.configCenterConfig.DataId = dataID - return ccb -} - -func (ccb *ConfigCenterConfigBuilder) SetGroup(group string) *ConfigCenterConfigBuilder { - ccb.configCenterConfig.Group = group - return ccb -} - -func (ccb *ConfigCenterConfigBuilder) Build() *CenterConfig { - return ccb.configCenterConfig -} - -func newEmptyConfigCenterConfig() *CenterConfig { - return &CenterConfig{ - Params: make(map[string]string), - } -} diff --git a/config/config_loader.go b/config/config_loader.go deleted file mode 100644 index c232cc894a..0000000000 --- a/config/config_loader.go +++ /dev/null @@ -1,123 +0,0 @@ -/* - * 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 ( - "errors" - "sync/atomic" -) - -import ( - gostLogger "github.com/dubbogo/gost/log/logger" - - "github.com/knadh/koanf" -) - -import ( - "dubbo.apache.org/dubbo-go/v3/common" - dubboLogger "dubbo.apache.org/dubbo-go/v3/logger" - _ "dubbo.apache.org/dubbo-go/v3/logger/core/logrus" - "dubbo.apache.org/dubbo-go/v3/logger/core/zap" -) - -var ( - rootConfigStore = func() *atomic.Pointer[RootConfig] { - store := &atomic.Pointer[RootConfig]{} - store.Store(NewRootConfigBuilder().Build()) - return store - }() -) - -func setRootConfigInternal(rc *RootConfig) { - rootConfigStore.Store(rc) -} - -func init() { - log := zap.NewDefault() - dubboLogger.SetLogger(log) - gostLogger.SetLogger(log) -} - -func Load(opts ...LoaderConfOption) error { - // conf - conf := NewLoaderConf(opts...) - loadConfig := conf.rc - - if conf.rc == nil { - loadConfig = NewRootConfigBuilder().Build() - koan := GetConfigResolver(conf) - koan = conf.MergeConfig(koan) - if err := koan.UnmarshalWithConf(loadConfig.Prefix(), - loadConfig, koanf.UnmarshalConf{Tag: "yaml"}); err != nil { - return err - } - } - - if err := loadConfig.Init(); err != nil { - return err - } - return nil -} - -func check() error { - if GetRootConfig() == nil { - return errors.New("execute the config.Load() method first") - } - return nil -} - -// GetRPCService get rpc service for consumer -func GetRPCService(name string) common.RPCService { - return GetRootConfig().Consumer.References[name].GetRPCService() -} - -// RPCService create rpc service for consumer -func RPCService(service common.RPCService) { - ref := common.GetReference(service) - GetRootConfig().Consumer.References[ref].Implement(service) -} - -// GetMetricConfig find the MetricsConfig -// if it is nil, create a new one -// we use double-check to reduce race condition -// In general, it will be locked 0 or 1 time. -// So you don't need to worry about the race condition -func GetMetricConfig() *MetricsConfig { - // todo - //if GetBaseConfig().Metrics == nil { - // configAccessMutex.Lock() - // defer configAccessMutex.Unlock() - // if GetBaseConfig().Metrics == nil { - // GetBaseConfig().Metrics = &metric.Metrics{} - // } - //} - //return GetBaseConfig().Metrics - return GetRootConfig().Metrics -} - -func GetTracingConfig(tracingKey string) *TracingConfig { - return GetRootConfig().Tracing[tracingKey] -} - -func GetMetadataReportConfg() *MetadataReportConfig { - return GetRootConfig().MetadataReport -} - -func IsProvider() bool { - return len(GetRootConfig().Provider.Services) > 0 -} diff --git a/config/config_loader_options.go b/config/config_loader_options.go deleted file mode 100644 index 4f2899baf2..0000000000 --- a/config/config_loader_options.go +++ /dev/null @@ -1,227 +0,0 @@ -/* - * 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 ( - "os" - "path/filepath" - "runtime" - "strings" -) - -import ( - "github.com/dubbogo/gost/log/logger" - - "github.com/knadh/koanf" - - "github.com/pkg/errors" -) - -import ( - "dubbo.apache.org/dubbo-go/v3/common/constant" - "dubbo.apache.org/dubbo-go/v3/common/constant/file" -) - -type loaderConf struct { - suffix string // loaderConf file extension default yaml - path string // loaderConf file path default ./conf/dubbogo.yaml - delim string // loaderConf file delim default . - bytes []byte // config bytes - rc *RootConfig // user provide rootConfig built by config api - name string // config file name -} - -func NewLoaderConf(opts ...LoaderConfOption) *loaderConf { - configFilePath := "../conf/dubbogo.yaml" - if configFilePathFromEnv := os.Getenv(constant.ConfigFileEnvKey); configFilePathFromEnv != "" { - configFilePath = configFilePathFromEnv - } - name, suffix := resolverFilePath(configFilePath) - conf := &loaderConf{ - suffix: suffix, - path: absolutePath(configFilePath), - delim: ".", - name: name, - } - for _, opt := range opts { - opt.apply(conf) - } - if conf.rc != nil { - return conf - } - if len(conf.bytes) <= 0 { - if bytes, err := os.ReadFile(conf.path); err != nil { - panic(err) - } else { - conf.bytes = bytes - } - } - return conf -} - -type LoaderConfOption interface { - apply(vc *loaderConf) -} - -type loaderConfigFunc func(*loaderConf) - -func (fn loaderConfigFunc) apply(vc *loaderConf) { - fn(vc) -} - -// WithGenre set load config file suffix -// Deprecated: replaced by WithSuffix -func WithGenre(suffix string) LoaderConfOption { - return loaderConfigFunc(func(conf *loaderConf) { - g := strings.ToLower(suffix) - if err := checkFileSuffix(g); err != nil { - panic(err) - } - conf.suffix = g - }) -} - -// WithSuffix set load config file suffix -func WithSuffix(suffix file.Suffix) LoaderConfOption { - return loaderConfigFunc(func(conf *loaderConf) { - conf.suffix = string(suffix) - }) -} - -// WithPath set load config path -func WithPath(path string) LoaderConfOption { - return loaderConfigFunc(func(conf *loaderConf) { - conf.path = absolutePath(path) - if bytes, err := os.ReadFile(conf.path); err != nil { - panic(err) - } else { - conf.bytes = bytes - } - name, suffix := resolverFilePath(path) - conf.suffix = suffix - conf.name = name - }) -} - -func WithRootConfig(rc *RootConfig) LoaderConfOption { - return loaderConfigFunc(func(conf *loaderConf) { - conf.rc = rc - }) -} - -func WithDelim(delim string) LoaderConfOption { - return loaderConfigFunc(func(conf *loaderConf) { - conf.delim = delim - }) -} - -// WithBytes set load config bytes -func WithBytes(bytes []byte) LoaderConfOption { - return loaderConfigFunc(func(conf *loaderConf) { - conf.bytes = bytes - }) -} - -// absolutePath get absolut path -func absolutePath(inPath string) string { - - if inPath == "$HOME" || strings.HasPrefix(inPath, "$HOME"+string(os.PathSeparator)) { - inPath = userHomeDir() + inPath[5:] - } - - if filepath.IsAbs(inPath) { - return filepath.Clean(inPath) - } - - p, err := filepath.Abs(inPath) - if err == nil { - return filepath.Clean(p) - } - - return "" -} - -// userHomeDir get gopath -func userHomeDir() string { - if runtime.GOOS == "windows" { - home := os.Getenv("HOMEDRIVE") + os.Getenv("HOMEPATH") - if home == "" { - home = os.Getenv("USERPROFILE") - } - return home - } - return os.Getenv("HOME") -} - -// checkFileSuffix check file suffix -func checkFileSuffix(suffix string) error { - for _, g := range []string{"json", "toml", "yaml", "yml", "properties"} { - if g == suffix { - return nil - } - } - 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 deleted file mode 100644 index 501579c2ed..0000000000 --- a/config/config_loader_options_test.go +++ /dev/null @@ -1,110 +0,0 @@ -/* - * 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 ( - "strings" - "testing" -) - -import ( - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" -) - -import ( - "dubbo.apache.org/dubbo-go/v3/common/constant/file" -) - -func TestCheckGenre(t *testing.T) { - - err := checkFileSuffix("abc") - require.Error(t, err) - - err = checkFileSuffix("zc") - require.Error(t, err) - - err = checkFileSuffix("json") - assert.NoError(t, err) -} - -func TestFileGenre(t *testing.T) { - conf := NewLoaderConf(WithPath("../config/testdata/config/properties/application.properties")) - assert.Equal(t, "properties", conf.suffix) -} - -func TestRootConfig(t *testing.T) { - rc := NewRootConfigBuilder().SetApplication(NewApplicationConfigBuilder().SetName("test-app").Build()).Build() - conf := NewLoaderConf(WithRootConfig(rc)) - assert.Equal(t, "test-app", conf.rc.Application.Name) -} - -func TestNewLoaderConf_WithBytes(t *testing.T) { - str := `dubbo.application.name=dubbo-go -dubbo.application.module=local -dubbo.services.HelloService.registry=nacos,zk` - - conf := NewLoaderConf(WithBytes([]byte(str)), WithGenre("properties")) - - assert.NotNil(t, conf) - assert.NotEmpty(t, conf.bytes) -} - -func TestNewLoaderConf_WithSuffix(t *testing.T) { - conf := NewLoaderConf( - WithSuffix(file.JSON), - WithPath("../config/testdata/config/properties/application.properties"), - ) - - assert.Equal(t, conf.suffix, string(file.PROPERTIES)) -} - -func TestResolverFilePath(t *testing.T) { - name, suffix := resolverFilePath("../config/application.properties") - assert.Equal(t, "application", name) - assert.Equal(t, "properties", suffix) -} - -func TestResolverFilePath_Illegal_Path(t *testing.T) { - name, suffix := resolverFilePath("application.properties") - assert.Equal(t, "application", name) - assert.Equal(t, "properties", suffix) -} - -func TestResolverFilePath_Illegal_Path_Name(t *testing.T) { - name, suffix := resolverFilePath("application") - assert.Equal(t, "application", name) - 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.True(t, strings.HasSuffix(filePath, "application-dev.properties")) - - exists := pathExists(filePath) - assert.False(t, exists) - exists = pathExists("application.properties") - assert.False(t, exists) - -} diff --git a/config/config_resolver.go b/config/config_resolver.go deleted file mode 100644 index 7da6485b61..0000000000 --- a/config/config_resolver.go +++ /dev/null @@ -1,112 +0,0 @@ -/* - * 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 ( - "strings" -) - -import ( - log "github.com/dubbogo/gost/log/logger" - - "github.com/knadh/koanf" - "github.com/knadh/koanf/parsers/json" - "github.com/knadh/koanf/parsers/yaml" - "github.com/knadh/koanf/providers/confmap" - "github.com/knadh/koanf/providers/rawbytes" - - "github.com/pkg/errors" -) - -import ( - "dubbo.apache.org/dubbo-go/v3/common/constant/file" -) - -// GetConfigResolver get config resolver -func GetConfigResolver(conf *loaderConf) *koanf.Koanf { - var ( - k *koanf.Koanf - err error - ) - if len(conf.suffix) <= 0 { - conf.suffix = string(file.YAML) - } - if len(conf.delim) <= 0 { - conf.delim = "." - } - bytes := conf.bytes - if len(bytes) <= 0 { - panic(errors.New("bytes is nil,please set bytes or file path")) - } - k = koanf.New(conf.delim) - - switch conf.suffix { - case "yaml", "yml": - err = k.Load(rawbytes.Provider(bytes), yaml.Parser()) - case "json": - err = k.Load(rawbytes.Provider(bytes), json.Parser()) - default: - err = errors.Errorf("no support %s file suffix", conf.suffix) - } - - if err != nil { - panic(err) - } - return resolvePlaceholder(k) -} - -// resolvePlaceholder replace ${xx} with real value -func resolvePlaceholder(resolver *koanf.Koanf) *koanf.Koanf { - m := make(map[string]any) - 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 deleted file mode 100644 index 2f5a0823a6..0000000000 --- a/config/config_resolver_test.go +++ /dev/null @@ -1,49 +0,0 @@ -/* - * 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" - "github.com/stretchr/testify/require" -) - -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.Empty(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"}) - require.NoError(t, err) - assert.Equal(t, rc.ConfigCenter.Address, rc.Registries["nacos"].Address) - //not exist, default - assert.Empty(t, rc.Registries["nacos"].Group) - assert.Equal(t, "dev", rc.Registries["zk"].Group) - - }) -} diff --git a/config/config_setter.go b/config/config_setter.go deleted file mode 100644 index c92a2af2ad..0000000000 --- a/config/config_setter.go +++ /dev/null @@ -1,22 +0,0 @@ -/* - * 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 - -type Setter interface { - Set(name string, config any) -} diff --git a/config/config_utils.go b/config/config_utils.go deleted file mode 100644 index 8a3c8a60f0..0000000000 --- a/config/config_utils.go +++ /dev/null @@ -1,122 +0,0 @@ -/* - * 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 ( - "fmt" - "regexp" - "strings" -) - -import ( - "github.com/go-playground/validator/v10" - - "github.com/pkg/errors" -) - -import ( - "dubbo.apache.org/dubbo-go/v3/common/constant" - "dubbo.apache.org/dubbo-go/v3/common/extension" -) - -var validate *validator.Validate - -func init() { - validate = validator.New() -} - -func mergeValue(str1, str2, def string) string { - if str1 == "" && str2 == "" { - return def - } - s1 := strings.Split(str1, ",") - s2 := strings.Split(str2, ",") - str := "," + strings.Join(append(s1, s2...), ",") - defKey := strings.Contains(str, ","+constant.DefaultKey) - if !defKey { - str = "," + constant.DefaultKey + str - } - str = strings.TrimPrefix(strings.ReplaceAll(str, ","+constant.DefaultKey, ","+def), ",") - return removeMinus(strings.Split(str, ",")) -} - -func removeMinus(strArr []string) string { - if len(strArr) == 0 { - return "" - } - var normalStr string - var minusStrArr []string - for _, v := range strArr { - if strings.HasPrefix(v, "-") { - minusStrArr = append(minusStrArr, v[1:]) - } else { - normalStr += fmt.Sprintf(",%s", v) - } - } - normalStr = strings.Trim(normalStr, ",") - for _, v := range minusStrArr { - normalStr = strings.Replace(normalStr, v, "", 1) - } - reg := regexp.MustCompile("[,]+") - normalStr = reg.ReplaceAllString(strings.Trim(normalStr, ","), ",") - return normalStr -} - -// removeDuplicateElement remove duplicate element -func removeDuplicateElement(items []string) []string { - result := make([]string, 0, len(items)) - temp := map[string]struct{}{} - for _, item := range items { - if _, ok := temp[item]; !ok && item != "" { - temp[item] = struct{}{} - result = append(result, item) - } - } - return result -} - -// translateIds string "nacos,zk" => ["nacos","zk"] -func translateIds(registryIds []string) []string { - ids := make([]string, 0) - for _, id := range registryIds { - - ids = append(ids, strings.Split(id, ",")...) - } - return removeDuplicateElement(ids) -} - -func verify(s any) error { - if err := validate.Struct(s); err != nil { - errs := err.(validator.ValidationErrors) - var slice []string - for _, msg := range errs { - slice = append(slice, msg.Error()) - } - return errors.New(strings.Join(slice, ",")) - } - return nil -} - -// clientNameID unique identifier id for client -func clientNameID(config extension.Config, protocol, address string) string { - return strings.Join([]string{config.Prefix(), protocol, address}, "-") -} - -func isValid(addr string) bool { - return addr != "" && addr != constant.NotAvailable -} diff --git a/config/config_utils_test.go b/config/config_utils_test.go deleted file mode 100644 index 184d7be760..0000000000 --- a/config/config_utils_test.go +++ /dev/null @@ -1,83 +0,0 @@ -/* - * 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/stretchr/testify/assert" -) - -func TestMergeValue(t *testing.T) { - str := mergeValue("", "", "a,b") - assert.Equal(t, "a,b", str) - - str = mergeValue("c,d", "e,f", "a,b") - assert.Equal(t, "a,b,c,d,e,f", str) - - str = mergeValue("c,d", "e,d,f", "a,b") - assert.Equal(t, "a,b,c,d,e,d,f", str) - - str = mergeValue("c,default,d", "-c,-a,e,f", "a,b") - assert.Equal(t, "b,d,e,f", str) - - str = mergeValue("", "default,-b,e,f", "a,b") - assert.Equal(t, "a,e,f", str) -} - -func TestRemoveMinus(t *testing.T) { - strList := removeMinus([]string{}) - assert.Empty(t, strList) - - strList = removeMinus([]string{"a", "b", "c", "d", "-a"}) - assert.Equal(t, "b,c,d", strList) - - strList = removeMinus([]string{"a", "b", "c", "d", "-a", "-b"}) - assert.Equal(t, "c,d", strList) - - strList = removeMinus([]string{"a", "b", "c", "-c", "-a", "-b"}) - assert.Empty(t, strList) - - strList = removeMinus([]string{"b", "a", "-c", "c"}) - assert.Equal(t, "b,a", strList) - - strList = removeMinus([]string{"c", "b", "a", "d", "c", "-c", "-a", "e", "f"}) - assert.Equal(t, "b,d,c,e,f", strList) -} - -type mockConfig struct { - protocol string - address string -} - -func (m *mockConfig) Prefix() string { - return "mock" -} - -func TestClientNameID(t *testing.T) { - t.Run("normal", func(t *testing.T) { - m := &mockConfig{"nacos", "127.0.0.1:8848"} - assert.Equal(t, "mock-nacos-127.0.0.1:8848", clientNameID(m, m.protocol, m.address)) - }) - t.Run("protocolIsNil", func(t *testing.T) { - m := &mockConfig{} - assert.Equal(t, "mock--", clientNameID(m, m.protocol, m.address)) - }) -} diff --git a/config/consumer_config.go b/config/consumer_config.go deleted file mode 100644 index e7902cf8db..0000000000 --- a/config/consumer_config.go +++ /dev/null @@ -1,279 +0,0 @@ -/* - * 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 ( - "fmt" - "strings" - "time" -) - -import ( - "github.com/creasty/defaults" - - "github.com/dubbogo/gost/log/logger" - - tripleConstant "github.com/dubbogo/triple/pkg/common/constant" -) - -import ( - "dubbo.apache.org/dubbo-go/v3/common" - "dubbo.apache.org/dubbo-go/v3/common/constant" -) - -// ConsumerConfig is Consumer default configuration -type ConsumerConfig struct { - Filter string `yaml:"filter" json:"filter,omitempty" property:"filter"` - RegistryIDs []string `yaml:"registry-ids" json:"registry-ids,omitempty" property:"registry-ids"` - Protocol string `yaml:"protocol" json:"protocol,omitempty" property:"protocol"` - RequestTimeout string `default:"3s" yaml:"request-timeout" json:"request-timeout,omitempty" property:"request-timeout"` - ProxyFactory string `default:"default" yaml:"proxy" json:"proxy,omitempty" property:"proxy"` - Check bool `yaml:"check" json:"check,omitempty" property:"check"` - AdaptiveService bool `default:"false" yaml:"adaptive-service" json:"adaptive-service" property:"adaptive-service"` - References map[string]*ReferenceConfig `yaml:"references" json:"references,omitempty" property:"references"` - TracingKey string `yaml:"tracing-key" json:"tracing-key" property:"tracing-key"` - FilterConf any `yaml:"filter-conf" json:"filter-conf,omitempty" property:"filter-conf"` - MaxWaitTimeForServiceDiscovery string `default:"3s" yaml:"max-wait-time-for-service-discovery" json:"max-wait-time-for-service-discovery,omitempty" property:"max-wait-time-for-service-discovery"` - MeshEnabled bool `yaml:"mesh-enabled" json:"mesh-enabled,omitempty" property:"mesh-enabled"` - rootConfig *RootConfig -} - -// Prefix dubbo.consumer -func (ConsumerConfig) Prefix() string { - return constant.ConsumerConfigPrefix -} - -func (cc *ConsumerConfig) Init(rc *RootConfig) error { - if cc == nil { - return nil - } - - buildDebugMsg := func() string { - if len(cc.References) == 0 { - return "empty" - } - consumerNames := make([]string, 0, len(cc.References)) - for k := range cc.References { - consumerNames = append(consumerNames, k) - } - return strings.Join(consumerNames, ", ") - } - logger.Debugf("Registered consumer clients are %v", buildDebugMsg()) - - cc.RegistryIDs = translateIds(cc.RegistryIDs) - if len(cc.RegistryIDs) <= 0 { - cc.RegistryIDs = rc.getRegistryIds() - } - if cc.TracingKey == "" && len(rc.Tracing) > 0 { - for k := range rc.Tracing { - cc.TracingKey = k - break - } - } - for key, referenceConfig := range cc.References { - if referenceConfig.InterfaceName == "" { - reference := GetConsumerService(key) - // try to use interface name defined by pb - triplePBService, ok := reference.(common.TriplePBService) - if !ok { - logger.Errorf("Dubbo-go cannot get interface name with reference = %s."+ - "Please run the command 'go install github.com/dubbogo/dubbogo-cli/cmd/protoc-gen-go-triple@latest' to get the latest "+ - "protoc-gen-go-triple, and then re-generate your pb file again by this tool."+ - "If you are not using pb serialization, please set 'interfaceName' field in reference config to let dubbogo get the interface name.", key) - continue - } else { - // use interface name defined by pb - referenceConfig.InterfaceName = triplePBService.XXX_InterfaceName() - } - } - if err := referenceConfig.Init(rc); err != nil { - return err - } - } - if err := defaults.Set(cc); err != nil { - return err - } - if err := verify(cc); err != nil { - return err - } - - cc.rootConfig = rc - return nil -} - -func (cc *ConsumerConfig) Load() { - for registeredTypeName, refRPCService := range GetConsumerServiceMap() { - refConfig, ok := cc.References[registeredTypeName] - if !ok { - // not found configuration, now new a configuration with default. - refConfig = NewReferenceConfigBuilder().SetProtocol(tripleConstant.TRIPLE).Build() - triplePBService, ok := refRPCService.(common.TriplePBService) - if !ok { - logger.Errorf("Dubbo-go cannot get interface name with registeredTypeName = %s."+ - "Please run the command 'go install github.com/dubbogo/dubbogo-cli/cmd/protoc-gen-go-triple@latest' to get the latest "+ - "protoc-gen-go-triple, and then re-generate your pb file again by this tool."+ - "If you are not using pb serialization, please set 'interfaceName' field in reference config to let dubbogo get the interface name.", registeredTypeName) - continue - } else { - // use interface name defined by pb - refConfig.InterfaceName = triplePBService.XXX_InterfaceName() - } - if err := refConfig.Init(GetRootConfig()); err != nil { - logger.Errorf(fmt.Sprintf("reference with registeredTypeName = %s init failed! err: %#v", registeredTypeName, err)) - continue - } - } - refConfig.id = registeredTypeName - refConfig.Refer(refRPCService) - refConfig.Implement(refRPCService) - } - - var maxWait int - - if maxWaitDuration, err := time.ParseDuration(cc.MaxWaitTimeForServiceDiscovery); err != nil { - logger.Warnf("Invalid consumer max wait time for service discovery: %s, fallback to 3s", cc.MaxWaitTimeForServiceDiscovery) - maxWait = 3 - } else { - maxWait = int(maxWaitDuration.Seconds()) - } - - // wait for invoker is available, if wait over default 3s, then panic - var count int - for { - checkok := true - for key, ref := range cc.References { - if (ref.Check != nil && *ref.Check && GetProviderService(key) == nil) || - (ref.Check == nil && cc.Check && GetProviderService(key) == nil) || - (ref.Check == nil && GetProviderService(key) == nil) { // default to true - - if ref.invoker != nil && !ref.invoker.IsAvailable() { - checkok = false - count++ - if count > maxWait { - errMsg := fmt.Sprintf("No provider available of the service %v.please check configuration.", ref.InterfaceName) - logger.Error(errMsg) - panic(errMsg) - } - time.Sleep(time.Second * 1) - break - } - if ref.invoker == nil { - logger.Warnf("The interface %s invoker not exist, may you should check your interface config.", ref.InterfaceName) - } - } - } - if checkok { - break - } - } -} - -// SetConsumerConfig sets consumerConfig by @c -func SetConsumerConfig(c ConsumerConfig) { - rc := GetRootConfig() - if rc == nil { - rc = NewRootConfigBuilder().Build() - } - next := *rc - next.Consumer = &c - SetRootConfig(next) -} - -func newEmptyConsumerConfig() *ConsumerConfig { - newConsumerConfig := &ConsumerConfig{ - References: make(map[string]*ReferenceConfig, 8), - RequestTimeout: "3s", - Check: true, - } - return newConsumerConfig -} - -type ConsumerConfigBuilder struct { - consumerConfig *ConsumerConfig -} - -func NewConsumerConfigBuilder() *ConsumerConfigBuilder { - return &ConsumerConfigBuilder{consumerConfig: newEmptyConsumerConfig()} -} - -func (ccb *ConsumerConfigBuilder) SetFilter(filter string) *ConsumerConfigBuilder { - ccb.consumerConfig.Filter = filter - return ccb -} - -func (ccb *ConsumerConfigBuilder) SetRegistryIDs(RegistryIDs ...string) *ConsumerConfigBuilder { - ccb.consumerConfig.RegistryIDs = RegistryIDs - return ccb -} - -func (ccb *ConsumerConfigBuilder) SetRequestTimeout(requestTimeout string) *ConsumerConfigBuilder { - ccb.consumerConfig.RequestTimeout = requestTimeout - return ccb -} - -func (ccb *ConsumerConfigBuilder) SetMaxWaitTimeForServiceDiscovery(maxWaitTimeForServiceDiscovery string) *ConsumerConfigBuilder { - ccb.consumerConfig.MaxWaitTimeForServiceDiscovery = maxWaitTimeForServiceDiscovery - return ccb -} - -func (ccb *ConsumerConfigBuilder) SetProxyFactory(proxyFactory string) *ConsumerConfigBuilder { - ccb.consumerConfig.ProxyFactory = proxyFactory - return ccb -} - -func (ccb *ConsumerConfigBuilder) SetCheck(check bool) *ConsumerConfigBuilder { - ccb.consumerConfig.Check = check - return ccb -} - -func (ccb *ConsumerConfigBuilder) AddReference(referenceKey string, referenceConfig *ReferenceConfig) *ConsumerConfigBuilder { - ccb.consumerConfig.References[referenceKey] = referenceConfig - return ccb -} - -func (ccb *ConsumerConfigBuilder) SetReferences(references map[string]*ReferenceConfig) *ConsumerConfigBuilder { - ccb.consumerConfig.References = references - return ccb -} - -func (ccb *ConsumerConfigBuilder) SetFilterConf(filterConf any) *ConsumerConfigBuilder { - ccb.consumerConfig.FilterConf = filterConf - return ccb -} - -func (ccb *ConsumerConfigBuilder) SetMeshEnabled(meshEnabled bool) *ConsumerConfigBuilder { - ccb.consumerConfig.MeshEnabled = meshEnabled - return ccb -} - -func (ccb *ConsumerConfigBuilder) SetRootConfig(rootConfig *RootConfig) *ConsumerConfigBuilder { - ccb.consumerConfig.rootConfig = rootConfig - return ccb -} - -func (ccb *ConsumerConfigBuilder) Build() *ConsumerConfig { - return ccb.consumerConfig -} - -// DynamicUpdateProperties dynamically update properties. -func (cc *ConsumerConfig) DynamicUpdateProperties(newConsumerConfig *ConsumerConfig) { - if newConsumerConfig != nil && newConsumerConfig.RequestTimeout != cc.RequestTimeout { - cc.RequestTimeout = newConsumerConfig.RequestTimeout - logger.Infof("ConsumerConfig's RequestTimeout was dynamically updated, new value:%v", cc.RequestTimeout) - } -} diff --git a/config/custom_config.go b/config/custom_config.go deleted file mode 100644 index eb247defc6..0000000000 --- a/config/custom_config.go +++ /dev/null @@ -1,80 +0,0 @@ -/* - * 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 ( - "github.com/creasty/defaults" -) - -import ( - "dubbo.apache.org/dubbo-go/v3/common/constant" -) - -type CustomConfig struct { - ConfigMap map[string]any `yaml:"config-map" json:"config-map,omitempty" property:"config-map"` -} - -func (*CustomConfig) Prefix() string { - return constant.CustomConfigPrefix -} - -func (c *CustomConfig) Init() error { - return c.check() -} - -func (c *CustomConfig) check() error { - if err := defaults.Set(c); err != nil { - return err - } - return verify(c) -} - -func (c *CustomConfig) GetDefineValue(key string, default_value any) any { - if define_value, ok := c.ConfigMap[key]; ok { - return define_value - } - return default_value -} - -func GetDefineValue(key string, default_value any) any { - rt := GetRootConfig() - if rt.Custom == nil { - return default_value - } - return rt.Custom.GetDefineValue(key, default_value) -} - -type CustomConfigBuilder struct { - customConfig *CustomConfig -} - -func NewCustomConfigBuilder() *CustomConfigBuilder { - return &CustomConfigBuilder{customConfig: &CustomConfig{}} -} - -func (ccb *CustomConfigBuilder) SetDefineConfig(key string, val any) *CustomConfigBuilder { - if ccb.customConfig.ConfigMap == nil { - ccb.customConfig.ConfigMap = make(map[string]any) - } - ccb.customConfig.ConfigMap[key] = val - return ccb -} - -func (ccb *CustomConfigBuilder) Build() *CustomConfig { - return ccb.customConfig -} diff --git a/config/custom_config_test.go b/config/custom_config_test.go deleted file mode 100644 index af412c3d79..0000000000 --- a/config/custom_config_test.go +++ /dev/null @@ -1,90 +0,0 @@ -/* - * 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 ( - "strings" - "testing" -) - -import ( - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" -) - -import ( - "dubbo.apache.org/dubbo-go/v3/common/constant" - _ "dubbo.apache.org/dubbo-go/v3/metadata/report/zookeeper" -) - -func TestCustomInit(t *testing.T) { - t.Run("empty use default", func(t *testing.T) { - err := Load(WithPath("./testdata/config/custom/empty.yaml")) - require.NoError(t, err) - assert.NotNil(t, GetRootConfig()) - customConfig := GetRootConfig().Custom - assert.NotNil(t, customConfig) - assert.Equal(t, customConfig.ConfigMap, map[string]any(nil)) - assert.Equal(t, "test", customConfig.GetDefineValue("test", "test")) - assert.Equal(t, "test", GetDefineValue("test", "test")) - }) - - t.Run("use config", func(t *testing.T) { - err := Load(WithPath("./testdata/config/custom/custom.yaml")) - require.NoError(t, err) - assert.NotNil(t, GetRootConfig()) - customConfig := GetRootConfig().Custom - assert.NotNil(t, customConfig) - assert.Equal(t, map[string]any{"test-config": true}, customConfig.ConfigMap) - assert.Equal(t, true, customConfig.GetDefineValue("test-config", false)) - assert.Equal(t, false, customConfig.GetDefineValue("test-no-config", false)) - assert.Equal(t, true, GetDefineValue("test-config", false)) - assert.Equal(t, false, GetDefineValue("test-no-config", false)) - }) - - t.Run("config builder", func(t *testing.T) { - customConfigBuilder := NewCustomConfigBuilder() - customConfigBuilder.SetDefineConfig("test-build", true) - customConfig := customConfigBuilder.Build() - assert.NotNil(t, customConfig) - assert.Equal(t, true, customConfig.GetDefineValue("test-build", false)) - assert.Equal(t, false, customConfig.GetDefineValue("test-no-build", false)) - // todo @(laurence) now we should guarantee rootConfig ptr can't be changed during test - tempRootConfig := GetRootConfig() - rt := NewRootConfigBuilder().SetCustom(customConfig).Build() - SetRootConfig(*rt) - assert.Equal(t, true, GetDefineValue("test-build", false)) - assert.Equal(t, false, GetDefineValue("test-no-build", false)) - SetRootConfig(*tempRootConfig) - }) -} - -func TestConfigUtils(t *testing.T) { - config := NewRegistryConfigWithProtocolDefaultPort("nacos") - - id := clientNameID(config, config.Protocol, config.Address) - - assert.Equal(t, id, strings.Join([]string{constant.RegistryConfigPrefix, "nacos", "127.0.0.1:8848"}, "-")) - - ids := translateIds([]string{"nacos,zk"}) - assert.Equal(t, "nacos", ids[0]) - assert.Equal(t, "zk", ids[1]) - - element := removeDuplicateElement([]string{"nacos", "nacos"}) - assert.Len(t, element, 1) -} diff --git a/config/doc.go b/config/doc.go deleted file mode 100644 index b13e49495f..0000000000 --- a/config/doc.go +++ /dev/null @@ -1,21 +0,0 @@ -/* - * 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 assembles all Dubbo configurations and works as the entrance of the whole Dubbo process. -// -// Deprecated: This package is for internal use only starting from 3.2.0, users must not depend on this package directly. -package config diff --git a/config/generic/generic_service.go b/config/generic/generic_service.go deleted file mode 100644 index bcadb130dd..0000000000 --- a/config/generic/generic_service.go +++ /dev/null @@ -1,32 +0,0 @@ -/* - * 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 generic provides type aliases for backward compatibility. -// Deprecated: Use dubbo.apache.org/dubbo-go/v3/filter/generic instead. -package generic - -import ( - "dubbo.apache.org/dubbo-go/v3/filter/generic" -) - -// GenericService is an alias for backward compatibility. -// Deprecated: Use dubbo.apache.org/dubbo-go/v3/filter/generic.GenericService instead. -type GenericService = generic.GenericService - -// NewGenericService is an alias for backward compatibility. -// Deprecated: Use dubbo.apache.org/dubbo-go/v3/filter/generic.NewGenericService instead. -var NewGenericService = generic.NewGenericService diff --git a/config/graceful_shutdown.go b/config/graceful_shutdown.go deleted file mode 100644 index 8080f994bd..0000000000 --- a/config/graceful_shutdown.go +++ /dev/null @@ -1,243 +0,0 @@ -/* - * 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 ( - "os" - "os/signal" - "runtime/debug" - "time" -) - -import ( - gxset "github.com/dubbogo/gost/container/set" - "github.com/dubbogo/gost/log/logger" -) - -import ( - "dubbo.apache.org/dubbo-go/v3/common/constant" - "dubbo.apache.org/dubbo-go/v3/common/extension" -) - -/* - * The key point is that find out the signals to handle. - * The most important documentation is https://golang.org/pkg/os/signal/ - * From this documentation, we can know that: - * 1. The signals SIGKILL and SIGSTOP may not be caught by signal package; - * 2. SIGHUP, SIGINT, or SIGTERM signal causes the program to exit - * 3. SIGQUIT, SIGILL, SIGTRAP, SIGABRT, SIGSTKFLT, SIGEMT, or SIGSYS signal causes the program to exit with a stack dump - * 4. The invocation of Notify(signal...) will disable the default behavior of those signals. - * - * So the signals SIGKILL, SIGSTOP, SIGHUP, SIGINT, SIGTERM, SIGQUIT, SIGILL, SIGTRAP, SIGABRT, SIGSTKFLT, SIGEMT, SIGSYS - * should be processed. - * syscall.SIGEMT cannot be found in CI - * It's seems that the Unix/Linux does not have the signal SIGSTKFLT. https://github.com/golang/go/issues/33381 - * So this signal will be ignored. - * The signals are different on different platforms. - * We define them by using 'package build' feature https://golang.org/pkg/go/build/ - */ -const defaultShutDownTime = constant.DefaultShutdownConfigTimeout - -func gracefulShutdownInit() { - // retrieve ShutdownConfig for gracefulShutdownFilter - gracefulShutdownConsumerFilter, exist := extension.GetFilter(constant.GracefulShutdownConsumerFilterKey) - if !exist { - return - } - gracefulShutdownProviderFilter, exist := extension.GetFilter(constant.GracefulShutdownProviderFilterKey) - if !exist { - return - } - rc := GetRootConfig() - if filter, ok := gracefulShutdownConsumerFilter.(Setter); ok && rc != nil && rc.Shutdown != nil { - filter.Set(constant.GracefulShutdownFilterShutdownConfig, GetShutDown()) - } - - if filter, ok := gracefulShutdownProviderFilter.(Setter); ok && rc != nil && rc.Shutdown != nil { - filter.Set(constant.GracefulShutdownFilterShutdownConfig, GetShutDown()) - } - - if GetShutDown().GetInternalSignal() { - signals := make(chan os.Signal, 1) - signal.Notify(signals, ShutdownSignals...) - - go func() { - sig := <-signals - logger.Infof("get signal %s, applicationConfig will shutdown.", sig) - // gracefulShutdownOnce.Do(func() { - time.AfterFunc(totalTimeout(), func() { - logger.Warn("Shutdown gracefully timeout, applicationConfig will shutdown immediately. ") - os.Exit(0) - }) - BeforeShutdown() - // those signals' original behavior is exit with dump ths stack, so we try to keep the behavior - for _, dumpSignal := range DumpHeapShutdownSignals { - if sig == dumpSignal { - debug.WriteHeapDump(os.Stdout.Fd()) - } - } - os.Exit(0) - - }() - } -} - -// BeforeShutdown provides processing flow before shutdown -func BeforeShutdown() { - destroyAllRegistries() - // waiting for a short time so that the clients have enough time to get the notification that server shutdowns - // The value of configuration depends on how long the clients will get notification. - waitAndAcceptNewRequests() - - // reject sending/receiving the new request, but keeping waiting for accepting requests - waitForSendingAndReceivingRequests() - - // destroy all protocols - destroyProtocols() - - logger.Info("Graceful shutdown --- Execute the custom callbacks.") - customCallbacks := extension.GetAllCustomShutdownCallbacks() - for callback := customCallbacks.Front(); callback != nil; callback = callback.Next() { - callback.Value.(func())() - } -} - -func destroyAllRegistries() { - logger.Info("Graceful shutdown --- Destroy all registriesConfig. ") - registryProtocol := extension.GetProtocol(constant.RegistryProtocol) - registryProtocol.Destroy() -} - -// destroyProtocols destroys protocols. -// First we destroy provider's protocols, and then we destroy the consumer protocols. -func destroyProtocols() { - logger.Info("Graceful shutdown --- Destroy protocols. ") - - rc := GetRootConfig() - if rc == nil || rc.Protocols == nil { - return - } - - consumerProtocols := getConsumerProtocols(rc) - - destroyProviderProtocols(rc, consumerProtocols) - destroyConsumerProtocols(consumerProtocols) -} - -// destroyProviderProtocols destroys the provider's protocol. -// if the protocol is consumer's protocol too, we will keep it -func destroyProviderProtocols(rc *RootConfig, consumerProtocols *gxset.HashSet) { - logger.Info("Graceful shutdown --- First destroy provider's protocols. ") - for _, protocol := range rc.Protocols { - // the protocol is the consumer's protocol too, we can not destroy it. - if consumerProtocols.Contains(protocol.Name) { - continue - } - extension.GetProtocol(protocol.Name).Destroy() - } -} - -func destroyConsumerProtocols(consumerProtocols *gxset.HashSet) { - logger.Info("Graceful shutdown --- Second Destroy consumer's protocols. ") - for name := range consumerProtocols.Items { - extension.GetProtocol(name.(string)).Destroy() - } -} - -func waitAndAcceptNewRequests() { - logger.Info("Graceful shutdown --- Keep waiting and accept new requests for a short time. ") - rc := GetRootConfig() - if rc == nil || rc.Shutdown == nil { - return - } - - time.Sleep(rc.Shutdown.GetConsumerUpdateWaitTime()) - - timeout := rc.Shutdown.GetStepTimeout() - // ignore this step - if timeout < 0 { - return - } - waitingProviderProcessedTimeout(rc.Shutdown) -} - -func waitingProviderProcessedTimeout(shutdownConfig *ShutdownConfig) { - timeout := shutdownConfig.GetStepTimeout() - if timeout <= 0 { - return - } - deadline := time.Now().Add(timeout) - - offlineRequestWindowTimeout := shutdownConfig.GetOfflineRequestWindowTimeout() - for time.Now().Before(deadline) && - (shutdownConfig.ProviderActiveCount.Load() > 0 || time.Now().Before(shutdownConfig.ProviderLastReceivedRequestTime.Load().Add(offlineRequestWindowTimeout))) { - // sleep 10 ms and then we check it again - time.Sleep(10 * time.Millisecond) - logger.Infof("waiting for provider active invocation count = %d, provider last received request time: %v", - shutdownConfig.ProviderActiveCount.Load(), shutdownConfig.ProviderLastReceivedRequestTime.Load()) - } -} - -// for provider. It will wait for processing receiving requests -func waitForSendingAndReceivingRequests() { - logger.Info("Graceful shutdown --- Keep waiting until sending/accepting requests finish or timeout. ") - rc := GetRootConfig() - if rc == nil || rc.Shutdown == nil { - // ignore this step - return - } - rc.Shutdown.RejectRequest.Store(true) - waitingConsumerProcessedTimeout(rc.Shutdown) -} - -func waitingConsumerProcessedTimeout(shutdownConfig *ShutdownConfig) { - timeout := shutdownConfig.GetStepTimeout() - if timeout <= 0 { - return - } - deadline := time.Now().Add(timeout) - - for time.Now().Before(deadline) && shutdownConfig.ConsumerActiveCount.Load() > 0 { - // sleep 10 ms and then we check it again - time.Sleep(10 * time.Millisecond) - logger.Infof("waiting for consumer active invocation count = %d", shutdownConfig.ConsumerActiveCount.Load()) - } -} - -func totalTimeout() time.Duration { - timeout := defaultShutDownTime - rc := GetRootConfig() - if rc != nil && rc.Shutdown != nil && rc.Shutdown.GetTimeout() > timeout { - timeout = rc.Shutdown.GetTimeout() - } - - return timeout -} - -// we can not get the protocols from consumerConfig because some protocol don't have configuration, like jsonrpc. -func getConsumerProtocols(rc *RootConfig) *gxset.HashSet { - result := gxset.NewSet() - if rc == nil || rc.Consumer == nil || rc.Consumer.References == nil { - return result - } - - for _, reference := range rc.Consumer.References { - result.Add(reference.Protocol) - } - return result -} diff --git a/config/graceful_shutdown_config.go b/config/graceful_shutdown_config.go deleted file mode 100644 index eb288312ab..0000000000 --- a/config/graceful_shutdown_config.go +++ /dev/null @@ -1,79 +0,0 @@ -/* - * 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 ( - "github.com/creasty/defaults" -) - -import ( - "dubbo.apache.org/dubbo-go/v3/global" -) - -// ShutdownConfig is kept as a compatibility alias for global.ShutdownConfig. -// Use global.ShutdownConfig directly in new code. Field documentation lives on -// global.ShutdownConfig because it owns the graceful shutdown configuration. -type ShutdownConfig = global.ShutdownConfig - -type ShutdownConfigBuilder struct { - shutdownConfig *ShutdownConfig -} - -func NewShutDownConfigBuilder() *ShutdownConfigBuilder { - return &ShutdownConfigBuilder{shutdownConfig: &ShutdownConfig{}} -} - -func (scb *ShutdownConfigBuilder) SetTimeout(timeout string) *ShutdownConfigBuilder { - scb.shutdownConfig.Timeout = timeout - return scb -} - -func (scb *ShutdownConfigBuilder) SetStepTimeout(stepTimeout string) *ShutdownConfigBuilder { - scb.shutdownConfig.StepTimeout = stepTimeout - return scb -} - -func (scb *ShutdownConfigBuilder) SetNotifyTimeout(notifyTimeout string) *ShutdownConfigBuilder { - scb.shutdownConfig.NotifyTimeout = notifyTimeout - return scb -} - -func (scb *ShutdownConfigBuilder) SetRejectRequestHandler(rejectRequestHandler string) *ShutdownConfigBuilder { - scb.shutdownConfig.RejectRequestHandler = rejectRequestHandler - return scb -} - -func (scb *ShutdownConfigBuilder) SetRejectRequest(rejectRequest bool) *ShutdownConfigBuilder { - scb.shutdownConfig.RejectRequest.Store(rejectRequest) - return scb -} - -func (scb *ShutdownConfigBuilder) SetInternalSignal(internalSignal bool) *ShutdownConfigBuilder { - scb.shutdownConfig.InternalSignal = &internalSignal - return scb -} - -func (scb *ShutdownConfigBuilder) Build() *ShutdownConfig { - defaults.MustSet(scb.shutdownConfig) - return scb.shutdownConfig -} - -func (scb *ShutdownConfigBuilder) SetOfflineRequestWindowTimeout(offlineRequestWindowTimeout string) *ShutdownConfigBuilder { - scb.shutdownConfig.OfflineRequestWindowTimeout = offlineRequestWindowTimeout - return scb -} diff --git a/config/graceful_shutdown_config_test.go b/config/graceful_shutdown_config_test.go deleted file mode 100644 index 73aba2da88..0000000000 --- a/config/graceful_shutdown_config_test.go +++ /dev/null @@ -1,104 +0,0 @@ -/* - * 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" - "time" -) - -import ( - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" -) - -import ( - "dubbo.apache.org/dubbo-go/v3/common/constant" -) - -func TestShutdownConfigGetTimeout(t *testing.T) { - config := ShutdownConfig{} - assert.False(t, config.RejectRequest.Load()) - - config = ShutdownConfig{ - Timeout: "60s", - StepTimeout: "10s", - OfflineRequestWindowTimeout: "30s", - } - - assert.Equal(t, 60*time.Second, config.GetTimeout()) - assert.Equal(t, 10*time.Second, config.GetStepTimeout()) - assert.Equal(t, 30*time.Second, config.GetOfflineRequestWindowTimeout()) - config = ShutdownConfig{ - Timeout: "34ms", - StepTimeout: "79ms", - OfflineRequestWindowTimeout: "13ms", - } - - assert.Equal(t, 34*time.Millisecond, config.GetTimeout()) - assert.Equal(t, 79*time.Millisecond, config.GetStepTimeout()) - assert.Equal(t, 13*time.Millisecond, config.GetOfflineRequestWindowTimeout()) - - // test default - config = ShutdownConfig{} - - assert.Equal(t, 60*time.Second, config.GetTimeout()) - assert.Equal(t, 3*time.Second, config.GetStepTimeout()) - assert.Equal(t, 3*time.Second, config.GetOfflineRequestWindowTimeout()) -} - -func TestNewShutDownConfigBuilder(t *testing.T) { - config := NewShutDownConfigBuilder(). - SetTimeout("10s"). - SetStepTimeout("15s"). - SetOfflineRequestWindowTimeout("13s"). - SetRejectRequestHandler("handler"). - SetRejectRequest(true). - SetInternalSignal(false). - Build() - - assert.Equal(t, constant.ShutdownConfigPrefix, config.Prefix()) - - timeout := config.GetTimeout() - assert.Equal(t, 10*time.Second, timeout) - - stepTimeout := config.GetStepTimeout() - assert.Equal(t, 15*time.Second, stepTimeout) - - offlineRequestWindowTimeout := config.GetOfflineRequestWindowTimeout() - assert.Equal(t, 13*time.Second, offlineRequestWindowTimeout) - err := config.Init() - require.NoError(t, err) - - waitTime := config.GetConsumerUpdateWaitTime() - assert.Equal(t, 3*time.Second, waitTime) - - assert.False(t, config.GetInternalSignal()) -} - -func TestGetInternalSignal(t *testing.T) { - config := NewShutDownConfigBuilder(). - SetTimeout("10s"). - SetStepTimeout("15s"). - SetOfflineRequestWindowTimeout("13s"). - SetRejectRequestHandler("handler"). - SetRejectRequest(true). - Build() - - assert.True(t, config.GetInternalSignal()) -} diff --git a/config/graceful_shutdown_signal_darwin.go b/config/graceful_shutdown_signal_darwin.go deleted file mode 100644 index 9b694b5e09..0000000000 --- a/config/graceful_shutdown_signal_darwin.go +++ /dev/null @@ -1,38 +0,0 @@ -/* - * 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 ( - "os" - "syscall" -) - -var ( - // ShutdownSignals receives shutdown signals to process - ShutdownSignals = []os.Signal{ - os.Interrupt, os.Kill, syscall.SIGKILL, syscall.SIGSTOP, - syscall.SIGHUP, syscall.SIGINT, syscall.SIGQUIT, syscall.SIGILL, syscall.SIGTRAP, - syscall.SIGABRT, syscall.SIGSYS, syscall.SIGTERM, - } - - // DumpHeapShutdownSignals receives shutdown signals to process - DumpHeapShutdownSignals = []os.Signal{ - syscall.SIGQUIT, syscall.SIGILL, - syscall.SIGTRAP, syscall.SIGABRT, syscall.SIGSYS, - } -) diff --git a/config/graceful_shutdown_signal_linux.go b/config/graceful_shutdown_signal_linux.go deleted file mode 100644 index 9b694b5e09..0000000000 --- a/config/graceful_shutdown_signal_linux.go +++ /dev/null @@ -1,38 +0,0 @@ -/* - * 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 ( - "os" - "syscall" -) - -var ( - // ShutdownSignals receives shutdown signals to process - ShutdownSignals = []os.Signal{ - os.Interrupt, os.Kill, syscall.SIGKILL, syscall.SIGSTOP, - syscall.SIGHUP, syscall.SIGINT, syscall.SIGQUIT, syscall.SIGILL, syscall.SIGTRAP, - syscall.SIGABRT, syscall.SIGSYS, syscall.SIGTERM, - } - - // DumpHeapShutdownSignals receives shutdown signals to process - DumpHeapShutdownSignals = []os.Signal{ - syscall.SIGQUIT, syscall.SIGILL, - syscall.SIGTRAP, syscall.SIGABRT, syscall.SIGSYS, - } -) diff --git a/config/graceful_shutdown_signal_windows.go b/config/graceful_shutdown_signal_windows.go deleted file mode 100644 index 17c209e8f5..0000000000 --- a/config/graceful_shutdown_signal_windows.go +++ /dev/null @@ -1,35 +0,0 @@ -/* - * 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 ( - "os" - "syscall" -) - -var ( - // ShutdownSignals receives shutdown signals to process - ShutdownSignals = []os.Signal{ - os.Interrupt, os.Kill, syscall.SIGKILL, - syscall.SIGHUP, syscall.SIGINT, syscall.SIGQUIT, syscall.SIGILL, syscall.SIGTRAP, - syscall.SIGABRT, syscall.SIGTERM, - } - - // DumpHeapShutdownSignals receives shutdown signals to process - DumpHeapShutdownSignals = []os.Signal{syscall.SIGQUIT, syscall.SIGILL, syscall.SIGTRAP, syscall.SIGABRT} -) diff --git a/config/graceful_shutdown_test.go b/config/graceful_shutdown_test.go deleted file mode 100644 index 9b9245b514..0000000000 --- a/config/graceful_shutdown_test.go +++ /dev/null @@ -1,205 +0,0 @@ -/* - * 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 ( - "context" - "testing" -) - -import ( - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" -) - -import ( - "dubbo.apache.org/dubbo-go/v3/common/constant" - "dubbo.apache.org/dubbo-go/v3/common/extension" - "dubbo.apache.org/dubbo-go/v3/filter" - "dubbo.apache.org/dubbo-go/v3/global" - "dubbo.apache.org/dubbo-go/v3/protocol/base" - "dubbo.apache.org/dubbo-go/v3/protocol/result" -) - -type captureShutdownConfigFilter struct { - captured any -} - -func (f *captureShutdownConfigFilter) Invoke(context.Context, base.Invoker, base.Invocation) result.Result { - return &result.RPCResult{} -} - -func (f *captureShutdownConfigFilter) OnResponse(context.Context, result.Result, base.Invoker, base.Invocation) result.Result { - return &result.RPCResult{} -} - -func (f *captureShutdownConfigFilter) Set(_ string, config any) { - f.captured = config -} - -func TestGracefulShutdownInitPassesGlobalShutdownConfigToFilters(t *testing.T) { - oldRoot := GetRootConfig() - oldConsumerFilter, hadConsumerFilter := extension.GetFilter(constant.GracefulShutdownConsumerFilterKey) - oldProviderFilter, hadProviderFilter := extension.GetFilter(constant.GracefulShutdownProviderFilterKey) - t.Cleanup(func() { - setRootConfigInternal(oldRoot) - if hadConsumerFilter { - extension.SetFilter(constant.GracefulShutdownConsumerFilterKey, func() filter.Filter { - return oldConsumerFilter - }) - } else { - extension.UnregisterFilter(constant.GracefulShutdownConsumerFilterKey) - } - if hadProviderFilter { - extension.SetFilter(constant.GracefulShutdownProviderFilterKey, func() filter.Filter { - return oldProviderFilter - }) - } else { - extension.UnregisterFilter(constant.GracefulShutdownProviderFilterKey) - } - }) - - internalSignal := false - SetRootConfig(RootConfig{ - Shutdown: &ShutdownConfig{ - Timeout: "11s", - StepTimeout: "2s", - NotifyTimeout: "4s", - InternalSignal: &internalSignal, - }, - }) - - consumerFilter := &captureShutdownConfigFilter{} - providerFilter := &captureShutdownConfigFilter{} - extension.SetFilter(constant.GracefulShutdownConsumerFilterKey, func() filter.Filter { - return consumerFilter - }) - extension.SetFilter(constant.GracefulShutdownProviderFilterKey, func() filter.Filter { - return providerFilter - }) - - gracefulShutdownInit() - - consumerShutdown, ok := consumerFilter.captured.(*global.ShutdownConfig) - require.True(t, ok) - assert.Equal(t, "11s", consumerShutdown.Timeout) - assert.Equal(t, "2s", consumerShutdown.StepTimeout) - assert.Equal(t, "4s", consumerShutdown.NotifyTimeout) - - providerShutdown, ok := providerFilter.captured.(*global.ShutdownConfig) - require.True(t, ok) - assert.Equal(t, "11s", providerShutdown.Timeout) - assert.Equal(t, "2s", providerShutdown.StepTimeout) - assert.Equal(t, "4s", providerShutdown.NotifyTimeout) -} - -// -//import ( -// "dubbo.apache.org/dubbo-go/v3/config" -// "dubbo.apache.org/dubbo-go/v3/config/consumer" -// protocol2 "dubbo.apache.org/dubbo-go/v3/config/protocol" -// "dubbo.apache.org/dubbo-go/v3/config/provider" -// "dubbo.apache.org/dubbo-go/v3/config/reference" -// "testing" -//) -// -//import ( -// "dubbo.apache.org/dubbo-go/v3/common/constant" -// "dubbo.apache.org/dubbo-go/v3/common/extension" -// "dubbo.apache.org/dubbo-go/v3/filter" -// "dubbo.apache.org/dubbo-go/v3/protocol" -//) -// -//func TestGracefulShutdownInit(t *testing.T) { -// extension.SetFilter(constant.GracefulShutdownConsumerFilterKey, func() filter.Filter { -// return &config.mockGracefulShutdownFilter{} -// }) -// extension.SetFilter(constant.GracefulShutdownProviderFilterKey, func() filter.Filter { -// return &config.mockGracefulShutdownFilter{} -// }) -// GracefulShutdownInit() -//} -// -//func TestBeforeShutdown(t *testing.T) { -// extension.SetProtocol("registry", func() protocol.Protocol { -// return &config.mockRegistryProtocol{} -// }) -// extension.SetProtocol(constant.DUBBO, func() protocol.Protocol { -// return &config.mockRegistryProtocol{} -// }) -// -// extension.SetProtocol("mock", func() protocol.Protocol { -// return &config.mockRegistryProtocol{} -// }) -// -// consumerReferences := map[string]*reference.ReferenceConfig{} -// consumerReferences[constant.DUBBO] = &reference.ReferenceConfig{ -// Protocol: constant.DUBBO, -// } -// -// // without configuration -// config.consumerConfig = nil -// config.referenceConfig = nil -// BeforeShutdown() -// -// config.consumerConfig = &consumer.ShutdownConfig{ -// References: consumerReferences, -// ShutdownConfig: &ShutdownConfig{ -// Timeout: "1", -// StepTimeout: "1s", -// }, -// } -// -// providerProtocols := map[string]*protocol2.ProtocolConfig{} -// providerProtocols[constant.DUBBO] = &protocol2.ProtocolConfig{ -// Name: constant.DUBBO, -// } -// -// providerProtocols["mock"] = &protocol2.ProtocolConfig{ -// Name: "mock", -// } -// -// config.referenceConfig = &provider.ProviderConfig{ -// ShutdownConfig: &ShutdownConfig{ -// Timeout: "1", -// StepTimeout: "1s", -// }, -// Protocols: providerProtocols, -// } -// // test destroy protocol -// BeforeShutdown() -// -// config.referenceConfig = &provider.ProviderConfig{ -// ShutdownConfig: &ShutdownConfig{ -// Timeout: "1", -// StepTimeout: "-1s", -// }, -// Protocols: providerProtocols, -// } -// -// config.consumerConfig = &consumer.ShutdownConfig{ -// References: consumerReferences, -// ShutdownConfig: &ShutdownConfig{ -// Timeout: "1", -// StepTimeout: "-1s", -// }, -// } -// -// // test ignore steps -// BeforeShutdown() -//} diff --git a/config/http3_config.go b/config/http3_config.go deleted file mode 100644 index 7b830ff325..0000000000 --- a/config/http3_config.go +++ /dev/null @@ -1,38 +0,0 @@ -/* - * 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 - -// Http3Config represents the config of http3 -type Http3Config struct { - // Whether to enable HTTP/3 support. - // When set to true, both HTTP/2 and HTTP/3 servers will be started simultaneously. - // When set to false, only HTTP/2 server will be started. - // The default value is false. - Enable bool `yaml:"enable" json:"enable,omitempty"` - - // Whether to enable HTTP/3 negotiation. - // If set to true, HTTP/2 alt-svc negotiation will be enabled, - // allowing clients to negotiate between HTTP/2 and HTTP/3. - // If set to false, HTTP/2 alt-svc negotiation will be skipped, - // Clients cannot discover HTTP/3 via Alt-Svc. - // The default value is true. - // ref: https://quic-go.net/docs/http3/server/#advertising-http3-via-alt-svc - Negotiation bool `yaml:"negotiation" json:"negotiation,omitempty"` - - // TODO: add more params about http3 -} diff --git a/config/interfaces/config_post_processor.go b/config/interfaces/config_post_processor.go deleted file mode 100644 index c3165738f1..0000000000 --- a/config/interfaces/config_post_processor.go +++ /dev/null @@ -1,32 +0,0 @@ -/* - * 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 interfaces - -import ( - "dubbo.apache.org/dubbo-go/v3/common" -) - -// ConfigPostProcessor is an extension to give users a chance to customize configs against ReferenceConfig and -// ServiceConfig during deployment time. -type ConfigPostProcessor interface { - // PostProcessReferenceConfig customizes ReferenceConfig's params. - PostProcessReferenceConfig(*common.URL) - - // PostProcessServiceConfig customizes ServiceConfig's params. - PostProcessServiceConfig(*common.URL) -} diff --git a/config/interfaces/config_reader.go b/config/interfaces/config_reader.go deleted file mode 100644 index b82d87332c..0000000000 --- a/config/interfaces/config_reader.go +++ /dev/null @@ -1,28 +0,0 @@ -/* - * 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 interfaces - -import ( - "bytes" -) - -// ConfigReader is used to read config from consumer or provider -type ConfigReader interface { - ReadConsumerConfig(reader *bytes.Buffer) error - ReadProviderConfig(reader *bytes.Buffer) error -} diff --git a/config/logger_config.go b/config/logger_config.go deleted file mode 100644 index 65e2125f12..0000000000 --- a/config/logger_config.go +++ /dev/null @@ -1,223 +0,0 @@ -/* - * 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 ( - "fmt" - "strconv" -) - -import ( - getty "github.com/apache/dubbo-getty" - - "github.com/creasty/defaults" - - gostLogger "github.com/dubbogo/gost/log/logger" -) - -import ( - "dubbo.apache.org/dubbo-go/v3/common" - "dubbo.apache.org/dubbo-go/v3/common/constant" - "dubbo.apache.org/dubbo-go/v3/common/extension" - dubboLogger "dubbo.apache.org/dubbo-go/v3/logger" -) - -type LoggerConfig struct { - // logger driver default zap - Driver string `default:"zap" yaml:"driver"` - - // logger level - Level string `default:"info" yaml:"level"` - - // logger formatter default text - Format string `default:"text" yaml:"format"` - - // supports simultaneous file and console eg: console,file default console - Appender string `default:"console" yaml:"appender"` - - // logger file - File *File `yaml:"file"` - - // trace integration configuration - TraceIntegration *TraceIntegrationConfig `yaml:"trace-integration"` -} - -// TraceIntegrationConfig configures the integration between logging and OpenTelemetry tracing. -type TraceIntegrationConfig struct { - // whether to enable trace integration (inject traceId, spanId into logs) - Enabled *bool `default:"false" yaml:"enabled"` - - // whether to record error logs to span - RecordErrorToSpan *bool `default:"true" yaml:"record-error-to-span"` -} - -type File struct { - // log file name default dubbo.log - Name string `default:"dubbo.log" yaml:"name"` - - // log max size default 100Mb - MaxSize int `default:"100" yaml:"max-size"` - - // log max backups default 5 - MaxBackups int `default:"5" yaml:"max-backups"` - - // log file max age default 3 day - MaxAge int `default:"3" yaml:"max-age"` - - Compress *bool `default:"true" yaml:"compress"` -} - -// Prefix dubbo.logger -func (l *LoggerConfig) Prefix() string { - return constant.LoggerConfigPrefix -} - -func (l *LoggerConfig) Init() error { - var ( - log gostLogger.Logger - err error - ) - if err = l.check(); err != nil { - return err - } - - if log, err = extension.GetLogger(l.Driver, l.toURL()); err != nil { - return err - } - // set log - gostLogger.SetLogger(log) - dubboLogger.SetLogger(log) - getty.SetLogger(log) - return nil -} - -func (l *LoggerConfig) check() error { - if err := defaults.Set(l); err != nil { - return err - } - return verify(l) -} - -func (l *LoggerConfig) toURL() *common.URL { - address := fmt.Sprintf("%s://%s", l.Driver, l.Level) - url, _ := common.NewURL(address, - common.WithParamsValue(constant.LoggerLevelKey, l.Level), - common.WithParamsValue(constant.LoggerDriverKey, l.Driver), - common.WithParamsValue(constant.LoggerFormatKey, l.Format), - common.WithParamsValue(constant.LoggerAppenderKey, l.Appender), - common.WithParamsValue(constant.LoggerFileNameKey, l.File.Name), - common.WithParamsValue(constant.LoggerFileNaxSizeKey, strconv.Itoa(l.File.MaxSize)), - common.WithParamsValue(constant.LoggerFileMaxBackupsKey, strconv.Itoa(l.File.MaxBackups)), - common.WithParamsValue(constant.LoggerFileMaxAgeKey, strconv.Itoa(l.File.MaxAge)), - common.WithParamsValue(constant.LoggerFileCompressKey, strconv.FormatBool(*l.File.Compress)), - ) - - // Add trace integration parameters if configured - if l.TraceIntegration != nil { - if l.TraceIntegration.Enabled != nil { - url.SetParam(constant.LoggerTraceEnabledKey, strconv.FormatBool(*l.TraceIntegration.Enabled)) - } - if l.TraceIntegration.RecordErrorToSpan != nil { - url.SetParam(constant.LoggerTraceRecordErrorKey, strconv.FormatBool(*l.TraceIntegration.RecordErrorToSpan)) - } - } - - return url -} - -// DynamicUpdateProperties dynamically update properties. -func (l *LoggerConfig) DynamicUpdateProperties(new *LoggerConfig) { - -} - -type LoggerConfigBuilder struct { - loggerConfig *LoggerConfig -} - -func NewLoggerConfigBuilder() *LoggerConfigBuilder { - return &LoggerConfigBuilder{loggerConfig: &LoggerConfig{File: &File{}}} -} - -func (lcb *LoggerConfigBuilder) SetDriver(driver string) *LoggerConfigBuilder { - lcb.loggerConfig.Driver = driver - return lcb -} - -func (lcb *LoggerConfigBuilder) SetLevel(level string) *LoggerConfigBuilder { - lcb.loggerConfig.Level = level - return lcb -} - -func (lcb *LoggerConfigBuilder) SetFormat(format string) *LoggerConfigBuilder { - lcb.loggerConfig.Format = format - return lcb -} - -func (lcb *LoggerConfigBuilder) SetAppender(appender string) *LoggerConfigBuilder { - lcb.loggerConfig.Appender = appender - return lcb -} - -func (lcb *LoggerConfigBuilder) SetFileName(name string) *LoggerConfigBuilder { - lcb.loggerConfig.File.Name = name - return lcb -} - -func (lcb *LoggerConfigBuilder) SetFileMaxSize(maxSize int) *LoggerConfigBuilder { - lcb.loggerConfig.File.MaxSize = maxSize - return lcb -} - -func (lcb *LoggerConfigBuilder) SetFileMaxBackups(maxBackups int) *LoggerConfigBuilder { - lcb.loggerConfig.File.MaxBackups = maxBackups - return lcb -} - -func (lcb *LoggerConfigBuilder) SetFileMaxAge(maxAge int) *LoggerConfigBuilder { - lcb.loggerConfig.File.MaxAge = maxAge - return lcb -} - -func (lcb *LoggerConfigBuilder) SetFileCompress(compress bool) *LoggerConfigBuilder { - lcb.loggerConfig.File.Compress = &compress - return lcb -} - -func (lcb *LoggerConfigBuilder) SetTraceIntegrationEnabled(enabled bool) *LoggerConfigBuilder { - if lcb.loggerConfig.TraceIntegration == nil { - lcb.loggerConfig.TraceIntegration = &TraceIntegrationConfig{} - } - lcb.loggerConfig.TraceIntegration.Enabled = &enabled - return lcb -} - -func (lcb *LoggerConfigBuilder) SetRecordErrorToSpan(enabled bool) *LoggerConfigBuilder { - if lcb.loggerConfig.TraceIntegration == nil { - lcb.loggerConfig.TraceIntegration = &TraceIntegrationConfig{} - } - lcb.loggerConfig.TraceIntegration.RecordErrorToSpan = &enabled - return lcb -} - -// Build return config and set default value if nil -func (lcb *LoggerConfigBuilder) Build() *LoggerConfig { - if err := defaults.Set(lcb.loggerConfig); err != nil { - return nil - } - return lcb.loggerConfig -} diff --git a/config/logger_config_test.go b/config/logger_config_test.go deleted file mode 100644 index a8c31ee6d1..0000000000 --- a/config/logger_config_test.go +++ /dev/null @@ -1,176 +0,0 @@ -/* - * 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/dubbogo/gost/log/logger" - - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" -) - -import ( - dubboLogger "dubbo.apache.org/dubbo-go/v3/logger" -) - -func TestLoggerInit(t *testing.T) { - t.Run("empty use default", func(t *testing.T) { - err := Load(WithPath("./testdata/config/logger/empty_log.yaml")) - require.NoError(t, err) - assert.NotNil(t, GetRootConfig()) - loggerConfig := GetRootConfig().Logger - assert.NotNil(t, loggerConfig) - }) - - t.Run("use config", func(t *testing.T) { - err := Load(WithPath("./testdata/config/logger/log.yaml")) - require.NoError(t, err) - loggerConfig := GetRootConfig().Logger - assert.NotNil(t, loggerConfig) - // default - logger.Info("hello") - }) - - t.Run("use config with file", func(t *testing.T) { - err := Load(WithPath("./testdata/config/logger/file_log.yaml")) - require.NoError(t, err) - loggerConfig := GetRootConfig().Logger - assert.NotNil(t, loggerConfig) - logger.Debug("debug") - logger.Info("info") - logger.Warn("warn") - logger.Error("error") - logger.Debugf("%s", "debug") - logger.Infof("%s", "info") - logger.Warnf("%s", "warn") - logger.Errorf("%s", "error") - }) -} - -func TestNewLoggerConfigBuilder(t *testing.T) { - config := NewLoggerConfigBuilder(). - SetDriver("zap"). - SetLevel("info"). - SetFileName("dubbo.log"). - SetFileMaxAge(10). - Build() - - assert.NotNil(t, config) - - assert.Equal(t, "dubbo.log", config.File.Name) - assert.Equal(t, "zap", config.Driver) - assert.Equal(t, "info", config.Level) - assert.Equal(t, 10, config.File.MaxAge) - - // default value - assert.Equal(t, "console", config.Appender) - assert.Equal(t, "text", config.Format) - assert.Equal(t, 100, config.File.MaxSize) - assert.True(t, *config.File.Compress) - assert.Equal(t, 5, config.File.MaxBackups) -} - -func TestLoggerConfigBuilder_TraceIntegration(t *testing.T) { - t.Run("with trace integration enabled", func(t *testing.T) { - config := NewLoggerConfigBuilder(). - SetDriver("zap"). - SetLevel("info"). - SetTraceIntegrationEnabled(true). - SetRecordErrorToSpan(false). - Build() - - assert.NotNil(t, config) - assert.NotNil(t, config.TraceIntegration) - assert.NotNil(t, config.TraceIntegration.Enabled) - assert.True(t, *config.TraceIntegration.Enabled) - assert.NotNil(t, config.TraceIntegration.RecordErrorToSpan) - assert.False(t, *config.TraceIntegration.RecordErrorToSpan) - }) - - t.Run("with trace integration disabled", func(t *testing.T) { - config := NewLoggerConfigBuilder(). - SetDriver("zap"). - SetTraceIntegrationEnabled(false). - SetRecordErrorToSpan(true). - Build() - - assert.NotNil(t, config) - assert.NotNil(t, config.TraceIntegration) - assert.NotNil(t, config.TraceIntegration.Enabled) - assert.False(t, *config.TraceIntegration.Enabled) - assert.NotNil(t, config.TraceIntegration.RecordErrorToSpan) - assert.True(t, *config.TraceIntegration.RecordErrorToSpan) - }) - - t.Run("without trace integration config", func(t *testing.T) { - config := NewLoggerConfigBuilder(). - SetDriver("zap"). - SetLevel("info"). - Build() - - assert.NotNil(t, config) - // TraceIntegration should be nil if not configured - assert.Nil(t, config.TraceIntegration) - }) -} - -func TestLoggerConfigInit_SyncsDubboFacade_Zap(t *testing.T) { - config := NewLoggerConfigBuilder(). - SetDriver("zap"). - SetLevel("info"). - Build() - - require.NoError(t, config.Init()) - assert.NotNil(t, dubboLogger.GetLogger(), "dubbo-go logger facade should not be nil after LoggerConfig.Init()") -} - -func TestLoggerConfigInit_SyncsDubboFacade_Logrus(t *testing.T) { - config := NewLoggerConfigBuilder(). - SetDriver("logrus"). - SetLevel("info"). - Build() - - require.NoError(t, config.Init()) - assert.NotNil(t, dubboLogger.GetLogger(), "dubbo-go logger facade should not be nil after LoggerConfig.Init() with logrus driver") -} - -func TestLoggerConfigInit_SetLoggerLevel_WorksAfterInit(t *testing.T) { - config := NewLoggerConfigBuilder(). - SetDriver("zap"). - SetLevel("info"). - Build() - - require.NoError(t, config.Init()) - assert.True(t, dubboLogger.SetLoggerLevel("debug"), "SetLoggerLevel should return true after LoggerConfig.Init() with zap driver") -} - -func TestLoggerConfigInit_TraceIntegration_FacadeNotNil(t *testing.T) { - config := NewLoggerConfigBuilder(). - SetDriver("zap"). - SetLevel("info"). - SetTraceIntegrationEnabled(true). - Build() - - require.NoError(t, config.Init()) - assert.NotNil(t, dubboLogger.GetLogger(), "dubbo-go logger facade should not be nil after Init() with trace-integration enabled") - assert.True(t, dubboLogger.SetLoggerLevel("debug"), "SetLoggerLevel should work through ZapCtxLogger wrapper with trace-integration enabled") -} diff --git a/config/metadata_config.go b/config/metadata_config.go deleted file mode 100644 index 36d38230db..0000000000 --- a/config/metadata_config.go +++ /dev/null @@ -1,237 +0,0 @@ -/* - * 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 ( - "strconv" - "time" -) - -import ( - "github.com/dubbogo/gost/log/logger" - - perrors "github.com/pkg/errors" -) - -import ( - "dubbo.apache.org/dubbo-go/v3/common" - "dubbo.apache.org/dubbo-go/v3/common/constant" - "dubbo.apache.org/dubbo-go/v3/metadata" -) - -// MetadataReportConfig is app level configuration -type MetadataReportConfig struct { - Protocol string `required:"true" yaml:"protocol" json:"protocol,omitempty"` - Address string `required:"true" yaml:"address" json:"address"` - Username string `yaml:"username" json:"username,omitempty"` - Password string `yaml:"password" json:"password,omitempty"` - Timeout string `yaml:"timeout" json:"timeout,omitempty"` - Group string `yaml:"group" json:"group,omitempty"` - Namespace string `yaml:"namespace" json:"namespace,omitempty"` - Params map[string]string `yaml:"params" json:"parameters,omitempty"` - // metadataType of this application is defined by application config, local or remote - metadataType string -} - -func initMetadata(rc *RootConfig) error { - opts := metadata.NewOptions( - metadata.WithAppName(rc.Application.Name), - metadata.WithMetadataType(rc.Application.MetadataType), - metadata.WithPort(getMetadataPort(rc)), - ) - if err := opts.Init(); err != nil { - return err - } - return nil -} - -func getMetadataPort(rc *RootConfig) int { - port := rc.Application.MetadataServicePort - if port == "" { - protocolConfig, ok := rc.Protocols[constant.DefaultProtocol] - if ok { - port = protocolConfig.Port - } else { - logger.Warnf("[Metadata Service] Dubbo-go %s version's MetadataService only support dubbo protocol,"+ - "MetadataService will use random port", - constant.Version) - } - } - if port == "" { - return 0 - } - p, err := strconv.Atoi(port) - if err != nil { - logger.Error("MetadataService port parse error %v, MetadataService will use random port", err) - return 0 - } - return p -} - -// Prefix dubbo.consumer -func (*MetadataReportConfig) Prefix() string { - return constant.MetadataReportPrefix -} - -func (mc *MetadataReportConfig) toReportOptions() (*metadata.ReportOptions, error) { - opts := metadata.NewReportOptions( - metadata.WithRegistryId(constant.DefaultKey), - metadata.WithProtocol(mc.Protocol), - metadata.WithAddress(mc.Address), - metadata.WithUsername(mc.Username), - metadata.WithPassword(mc.Password), - metadata.WithGroup(mc.Group), - metadata.WithNamespace(mc.Namespace), - metadata.WithParams(mc.Params), - ) - if mc.Timeout != "" { - timeout, err := time.ParseDuration(mc.Timeout) - if err != nil { - return nil, err - } - metadata.WithTimeout(timeout)(opts) - } - return opts, nil -} - -func registryToReportOptions(id string, rc *RegistryConfig) (*metadata.ReportOptions, error) { - opts := metadata.NewReportOptions( - metadata.WithRegistryId(id), - metadata.WithProtocol(rc.Protocol), - metadata.WithAddress(rc.Address), - metadata.WithUsername(rc.Username), - metadata.WithPassword(rc.Password), - metadata.WithGroup(rc.Group), - metadata.WithNamespace(rc.Namespace), - metadata.WithParams(rc.Params), - ) - if rc.Timeout != "" { - timeout, err := time.ParseDuration(rc.Timeout) - if err != nil { - return nil, err - } - metadata.WithTimeout(timeout)(opts) - } - return opts, nil -} - -func (mc *MetadataReportConfig) Init(rc *RootConfig) error { - if mc == nil { - return nil - } - mc.metadataType = rc.Application.MetadataType - if mc.Address != "" { - // if metadata report config is avaible, then init metadata report instance - opts, err := mc.toReportOptions() - if err != nil { - return err - } - return opts.Init() - } - if len(rc.Registries) > 0 { - // if metadata report config is not available, then init metadata report instance with registries - for id, reg := range rc.Registries { - if isValid(reg.Address) { - ok, err := strconv.ParseBool(reg.UseAsMetaReport) - if err != nil { - return err - } - if ok { - opts, err := registryToReportOptions(id, reg) - if err != nil { - return err - } - if err = opts.Init(); err != nil { - return err - } - } - } - } - } - return nil -} - -func (mc *MetadataReportConfig) ToUrl() (*common.URL, error) { - res, err := common.NewURL(mc.Address, - common.WithUsername(mc.Username), - common.WithPassword(mc.Password), - common.WithLocation(mc.Address), - common.WithProtocol(mc.Protocol), - common.WithParamsValue(constant.TimeoutKey, mc.Timeout), - common.WithParamsValue(constant.MetadataReportGroupKey, mc.Group), - common.WithParamsValue(constant.MetadataReportNamespaceKey, mc.Namespace), - common.WithParamsValue(constant.MetadataTypeKey, mc.metadataType), - common.WithParamsValue(constant.ClientNameKey, clientNameID(mc, mc.Protocol, mc.Address)), - ) - if err != nil || len(res.Protocol) == 0 { - return nil, perrors.New("Invalid MetadataReport Config.") - } - res.SetParam("metadata", res.Protocol) - for key, val := range mc.Params { - res.SetParam(key, val) - } - return res, nil -} - -type MetadataReportConfigBuilder struct { - metadataReportConfig *MetadataReportConfig -} - -func NewMetadataReportConfigBuilder() *MetadataReportConfigBuilder { - return &MetadataReportConfigBuilder{metadataReportConfig: newEmptyMetadataReportConfig()} -} - -func (mrcb *MetadataReportConfigBuilder) SetProtocol(protocol string) *MetadataReportConfigBuilder { - mrcb.metadataReportConfig.Protocol = protocol - return mrcb -} - -func (mrcb *MetadataReportConfigBuilder) SetAddress(address string) *MetadataReportConfigBuilder { - mrcb.metadataReportConfig.Address = address - return mrcb -} - -func (mrcb *MetadataReportConfigBuilder) SetUsername(username string) *MetadataReportConfigBuilder { - mrcb.metadataReportConfig.Username = username - return mrcb -} - -func (mrcb *MetadataReportConfigBuilder) SetPassword(password string) *MetadataReportConfigBuilder { - mrcb.metadataReportConfig.Password = password - return mrcb -} - -func (mrcb *MetadataReportConfigBuilder) SetTimeout(timeout string) *MetadataReportConfigBuilder { - mrcb.metadataReportConfig.Timeout = timeout - return mrcb -} - -func (mrcb *MetadataReportConfigBuilder) SetGroup(group string) *MetadataReportConfigBuilder { - mrcb.metadataReportConfig.Group = group - return mrcb -} - -func (mrcb *MetadataReportConfigBuilder) Build() *MetadataReportConfig { - return mrcb.metadataReportConfig -} - -func newEmptyMetadataReportConfig() *MetadataReportConfig { - return &MetadataReportConfig{ - Params: make(map[string]string), - } -} diff --git a/config/metadata_config_test.go b/config/metadata_config_test.go deleted file mode 100644 index 51e5594ba6..0000000000 --- a/config/metadata_config_test.go +++ /dev/null @@ -1,48 +0,0 @@ -/* - * 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/stretchr/testify/assert" - "github.com/stretchr/testify/require" -) - -import ( - "dubbo.apache.org/dubbo-go/v3/common/constant" -) - -func TestNewMetadataReportConfigBuilder(t *testing.T) { - config := NewMetadataReportConfigBuilder(). - SetProtocol("nacos"). - SetAddress("127.0.0.1:8848"). - SetUsername("nacos"). - SetPassword("123456"). - SetTimeout("10s"). - SetGroup("dubbo"). - Build() - - assert.Equal(t, constant.MetadataReportPrefix, config.Prefix()) - - url, err := config.ToUrl() - require.NoError(t, err) - assert.Equal(t, "10s", url.GetParam(constant.TimeoutKey, "3s")) -} diff --git a/config/method_config.go b/config/method_config.go deleted file mode 100644 index 3a52260eab..0000000000 --- a/config/method_config.go +++ /dev/null @@ -1,112 +0,0 @@ -/* - * 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 ( - "fmt" - "strconv" -) - -import ( - "github.com/creasty/defaults" -) - -import ( - "dubbo.apache.org/dubbo-go/v3/common/constant" - "dubbo.apache.org/dubbo-go/v3/common/extension" -) - -// MethodConfig defines method config -type MethodConfig struct { - InterfaceId string - InterfaceName string - Name string `yaml:"name" json:"name,omitempty" property:"name"` - Retries string `yaml:"retries" json:"retries,omitempty" property:"retries"` - LoadBalance string `yaml:"loadbalance" json:"loadbalance,omitempty" property:"loadbalance"` - Weight int64 `yaml:"weight" json:"weight,omitempty" property:"weight"` - TpsLimitInterval string `yaml:"tps.limit.interval" json:"tps.limit.interval,omitempty" property:"tps.limit.interval"` - TpsLimitRate string `yaml:"tps.limit.rate" json:"tps.limit.rate,omitempty" property:"tps.limit.rate"` - TpsLimitStrategy string `yaml:"tps.limit.strategy" json:"tps.limit.strategy,omitempty" property:"tps.limit.strategy"` - ExecuteLimit string `yaml:"execute.limit" json:"execute.limit,omitempty" property:"execute.limit"` - ExecuteLimitRejectedHandler string `yaml:"execute.limit.rejected.handler" json:"execute.limit.rejected.handler,omitempty" property:"execute.limit.rejected.handler"` - Sticky bool `yaml:"sticky" json:"sticky,omitempty" property:"sticky"` - RequestTimeout string `yaml:"timeout" json:"timeout,omitempty" property:"timeout"` -} - -// Prefix builds the configuration key prefix for this method. -func (m *MethodConfig) Prefix() string { - if len(m.InterfaceId) != 0 { - return constant.Dubbo + "." + m.InterfaceName + "." + m.InterfaceId + "." + m.Name + "." - } - - return constant.Dubbo + "." + m.InterfaceName + "." + m.Name + "." -} - -func (m *MethodConfig) Init() error { - return m.check() -} - -func initProviderMethodConfig(sc *ServiceConfig) error { - methods := sc.Methods - if methods == nil { - return nil - } - for _, method := range methods { - if err := method.check(); err != nil { - return err - } - } - sc.Methods = methods - return nil -} - -// check set default value and verify -func (m *MethodConfig) check() error { - qualifieldMethodName := m.InterfaceName + "#" + m.Name - if m.TpsLimitStrategy != "" { - _, err := extension.GetTpsLimitStrategyCreator(m.TpsLimitStrategy) - if err != nil { - panic(err) - } - } - - if m.TpsLimitInterval != "" { - tpsLimitInterval, err := strconv.ParseInt(m.TpsLimitInterval, 0, 0) - if err != nil { - return fmt.Errorf("[MethodConfig] Cannot parse the configuration tps.limit.interval for method %s, please check your configuration", qualifieldMethodName) - } - if tpsLimitInterval < 0 { - return fmt.Errorf("[MethodConfig] The configuration tps.limit.interval for %s must be positive, please check your configuration", qualifieldMethodName) - } - } - - if m.TpsLimitRate != "" { - tpsLimitRate, err := strconv.ParseInt(m.TpsLimitRate, 0, 0) - if err != nil { - return fmt.Errorf("[MethodConfig] Cannot parse the configuration tps.limit.rate for method %s, please check your configuration", qualifieldMethodName) - } - if tpsLimitRate < 0 { - return fmt.Errorf("[MethodConfig] The configuration tps.limit.rate for method %s must be positive, please check your configuration", qualifieldMethodName) - } - } - - if err := defaults.Set(m); err != nil { - return err - } - return verify(m) -} diff --git a/config/metric_config.go b/config/metric_config.go deleted file mode 100644 index 12875d7d28..0000000000 --- a/config/metric_config.go +++ /dev/null @@ -1,175 +0,0 @@ -/* - * 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 ( - "strconv" -) - -import ( - "github.com/creasty/defaults" - - "github.com/pkg/errors" -) - -import ( - "dubbo.apache.org/dubbo-go/v3/common" - "dubbo.apache.org/dubbo-go/v3/common/constant" - "dubbo.apache.org/dubbo-go/v3/metrics" -) - -// MetricsConfig This is the config struct for all metrics implementation -type MetricsConfig struct { - Enable *bool `default:"false" yaml:"enable" json:"enable,omitempty" property:"enable"` - Port string `default:"9090" yaml:"port" json:"port,omitempty" property:"port"` - Path string `default:"/metrics" yaml:"path" json:"path,omitempty" property:"path"` - Protocol string `default:"prometheus" yaml:"protocol" json:"protocol,omitempty" property:"protocol"` - EnableMetadata *bool `default:"false" yaml:"enable-metadata" json:"enable-metadata,omitempty" property:"enable-metadata"` - EnableRegistry *bool `default:"false" yaml:"enable-registry" json:"enable-registry,omitempty" property:"enable-registry"` - EnableConfigCenter *bool `default:"false" yaml:"enable-config-center" json:"enable-config-center,omitempty" property:"enable-config-center"` - Prometheus *PrometheusConfig `yaml:"prometheus" json:"prometheus" property:"prometheus"` - Aggregation *AggregateConfig `yaml:"aggregation" json:"aggregation" property:"aggregation"` - Probe *ProbeConfig `yaml:"probe" json:"probe" property:"probe"` - rootConfig *RootConfig -} - -type AggregateConfig struct { - Enabled *bool `default:"false" yaml:"enabled" json:"enabled,omitempty" property:"enabled"` - BucketNum int `default:"10" yaml:"bucket-num" json:"bucket-num,omitempty" property:"bucket-num"` - TimeWindowSeconds int `default:"120" yaml:"time-window-seconds" json:"time-window-seconds,omitempty" property:"time-window-seconds"` -} - -type PrometheusConfig struct { - Exporter *Exporter `yaml:"exporter" json:"exporter,omitempty" property:"exporter"` - Pushgateway *PushgatewayConfig `yaml:"pushgateway" json:"pushgateway,omitempty" property:"pushgateway"` -} - -type ProbeConfig struct { - Enabled *bool `default:"false" yaml:"enabled" json:"enabled,omitempty" property:"enabled"` - Port string `default:"22222" yaml:"port" json:"port,omitempty" property:"port"` - LivenessPath string `default:"/live" yaml:"liveness-path" json:"liveness-path,omitempty" property:"liveness-path"` - ReadinessPath string `default:"/ready" yaml:"readiness-path" json:"readiness-path,omitempty" property:"readiness-path"` - StartupPath string `default:"/startup" yaml:"startup-path" json:"startup-path,omitempty" property:"startup-path"` - UseInternalState *bool `default:"true" yaml:"use-internal-state" json:"use-internal-state,omitempty" property:"use-internal-state"` -} - -type Exporter struct { - Enabled *bool `default:"true" yaml:"enabled" json:"enabled,omitempty" property:"enabled"` -} - -type PushgatewayConfig struct { - Enabled *bool `default:"false" yaml:"enabled" json:"enabled,omitempty" property:"enabled"` - BaseUrl string `default:"" yaml:"base-url" json:"base-url,omitempty" property:"base-url"` - Job string `default:"default_dubbo_job" yaml:"job" json:"job,omitempty" property:"job"` - Username string `default:"" yaml:"username" json:"username,omitempty" property:"username"` - Password string `default:"" yaml:"password" json:"password,omitempty" property:"password"` - PushInterval int `default:"30" yaml:"push-interval" json:"push-interval,omitempty" property:"push-interval"` -} - -func (mc *MetricsConfig) ToReporterConfig() *metrics.ReporterConfig { - defaultMetricsReportConfig := metrics.NewReporterConfig() - - defaultMetricsReportConfig.Enable = *mc.Enable - defaultMetricsReportConfig.Port = mc.Port - defaultMetricsReportConfig.Path = mc.Path - defaultMetricsReportConfig.Protocol = mc.Protocol - return defaultMetricsReportConfig -} - -func (mc *MetricsConfig) Init(rc *RootConfig) error { - if mc == nil { - return errors.New("metrics config is null") - } - if err := defaults.Set(mc); err != nil { - return err - } - if err := verify(mc); err != nil { - return err - } - mc.rootConfig = rc - if *mc.Enable { - metrics.Init(mc.toURL()) - } - return nil -} - -type MetricConfigBuilder struct { - metricConfig *MetricsConfig -} - -func NewMetricConfigBuilder() *MetricConfigBuilder { - return &MetricConfigBuilder{metricConfig: &MetricsConfig{}} -} - -func (mcb *MetricConfigBuilder) SetMetadataEnabled(enabled bool) *MetricConfigBuilder { - mcb.metricConfig.EnableMetadata = &enabled - return mcb -} - -func (mcb *MetricConfigBuilder) SetRegistryEnabled(enabled bool) *MetricConfigBuilder { - mcb.metricConfig.EnableRegistry = &enabled - return mcb -} - -func (mcb *MetricConfigBuilder) SetConfigCenterEnabled(enabled bool) *MetricConfigBuilder { - mcb.metricConfig.EnableConfigCenter = &enabled - return mcb -} - -func (mcb *MetricConfigBuilder) Build() *MetricsConfig { - return mcb.metricConfig -} - -// DynamicUpdateProperties dynamically update properties. -func (mc *MetricsConfig) DynamicUpdateProperties(newMetricConfig *MetricsConfig) { - // TODO update -} - -// prometheus://localhost:9090?&histogram.enabled=false&prometheus.exporter.enabled=false -func (mc *MetricsConfig) toURL() *common.URL { - url, _ := common.NewURL("localhost", common.WithProtocol(mc.Protocol)) - url.SetParam(constant.PrometheusExporterMetricsPortKey, mc.Port) - url.SetParam(constant.PrometheusExporterMetricsPathKey, mc.Path) - url.SetParam(constant.ApplicationKey, mc.rootConfig.Application.Name) - url.SetParam(constant.AppVersionKey, mc.rootConfig.Application.Version) - url.SetParam(constant.RpcEnabledKey, strconv.FormatBool(*mc.Enable)) - url.SetParam(constant.MetadataEnabledKey, strconv.FormatBool(*mc.EnableMetadata)) - url.SetParam(constant.RegistryEnabledKey, strconv.FormatBool(*mc.EnableRegistry)) - url.SetParam(constant.ConfigCenterEnabledKey, strconv.FormatBool(*mc.EnableConfigCenter)) - if mc.Aggregation != nil { - url.SetParam(constant.AggregationEnabledKey, strconv.FormatBool(*mc.Aggregation.Enabled)) - url.SetParam(constant.AggregationBucketNumKey, strconv.Itoa(mc.Aggregation.BucketNum)) - url.SetParam(constant.AggregationTimeWindowSecondsKey, strconv.Itoa(mc.Aggregation.TimeWindowSeconds)) - } - if mc.Prometheus != nil { - if mc.Prometheus.Exporter != nil { - exporter := mc.Prometheus.Exporter - url.SetParam(constant.PrometheusExporterEnabledKey, strconv.FormatBool(*exporter.Enabled)) - } - if mc.Prometheus.Pushgateway != nil { - pushGateWay := mc.Prometheus.Pushgateway - url.SetParam(constant.PrometheusPushgatewayEnabledKey, strconv.FormatBool(*pushGateWay.Enabled)) - url.SetParam(constant.PrometheusPushgatewayBaseUrlKey, pushGateWay.BaseUrl) - url.SetParam(constant.PrometheusPushgatewayUsernameKey, pushGateWay.Username) - url.SetParam(constant.PrometheusPushgatewayPasswordKey, pushGateWay.Password) - url.SetParam(constant.PrometheusPushgatewayPushIntervalKey, strconv.Itoa(pushGateWay.PushInterval)) - url.SetParam(constant.PrometheusPushgatewayJobKey, pushGateWay.Job) - } - } - return url -} diff --git a/config/metric_config_test.go b/config/metric_config_test.go deleted file mode 100644 index e87bd18304..0000000000 --- a/config/metric_config_test.go +++ /dev/null @@ -1,40 +0,0 @@ -/* - * 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/stretchr/testify/assert" -) - -func TestMetricConfigBuilder(t *testing.T) { - config := NewMetricConfigBuilder(). - SetConfigCenterEnabled(false). - SetMetadataEnabled(false). - SetRegistryEnabled(false). - Build() - enable := false - assert.Equal(t, &MetricsConfig{ - EnableConfigCenter: &enable, - EnableMetadata: &enable, - EnableRegistry: &enable, - }, config) -} diff --git a/config/mock_rpcservice.go b/config/mock_rpcservice.go deleted file mode 100644 index 3a769e8b3d..0000000000 --- a/config/mock_rpcservice.go +++ /dev/null @@ -1,40 +0,0 @@ -/* - * 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 ( - "context" -) - -// MockService mocks the rpc service for test -type MockService struct{} - -// Reference mocks the Reference method -func (*MockService) Reference() string { - return "MockService" -} - -// GetUser mocks the GetUser method -func (*MockService) GetUser(ctx context.Context, itf []any, str *struct{}) error { - return nil -} - -// GetUser1 mocks the GetUser1 method -func (*MockService) GetUser1(ctx context.Context, itf []any, str *struct{}) error { - return nil -} diff --git a/config/mock_rpcservice_test.go b/config/mock_rpcservice_test.go deleted file mode 100644 index b7af8ef780..0000000000 --- a/config/mock_rpcservice_test.go +++ /dev/null @@ -1,40 +0,0 @@ -/* - * 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 ( - "context" - "testing" -) - -import ( - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" -) - -func TestMockService(t *testing.T) { - - mockService := &MockService{} - reference := mockService.Reference() - assert.Equal(t, "MockService", reference) - - err := mockService.GetUser1(context.TODO(), nil, nil) - require.NoError(t, err) - err = mockService.GetUser(context.TODO(), nil, nil) - require.NoError(t, err) -} diff --git a/config/options.go b/config/options.go deleted file mode 100644 index ca607c84f5..0000000000 --- a/config/options.go +++ /dev/null @@ -1,123 +0,0 @@ -/* - * 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 ( - "strconv" - "time" -) - -import ( - "dubbo.apache.org/dubbo-go/v3/global" -) - -type MethodOption func(*MethodOptions) - -func WithInterfaceId(id string) MethodOption { - return func(opts *MethodOptions) { - opts.Method.InterfaceId = id - } -} - -func WithInterfaceName(name string) MethodOption { - return func(opts *MethodOptions) { - opts.Method.InterfaceName = name - } -} - -func WithName(name string) MethodOption { - return func(opts *MethodOptions) { - opts.Method.Name = name - } -} - -func WithRetries(retries int) MethodOption { - return func(opts *MethodOptions) { - opts.Method.Retries = strconv.Itoa(retries) - } -} - -func WithLoadBalance(lb string) MethodOption { - return func(opts *MethodOptions) { - opts.Method.LoadBalance = lb - } -} - -func WithWeight(weight int64) MethodOption { - return func(opts *MethodOptions) { - opts.Method.Weight = weight - } -} - -func WithTpsLimitInterval(interval int) MethodOption { - return func(opts *MethodOptions) { - opts.Method.TpsLimitInterval = strconv.Itoa(interval) - } -} - -func WithTpsLimitRate(rate int) MethodOption { - return func(opts *MethodOptions) { - opts.Method.TpsLimitRate = strconv.Itoa(rate) - } -} - -func WithTpsLimitStrategy(strategy string) MethodOption { - return func(opts *MethodOptions) { - opts.Method.TpsLimitStrategy = strategy - } -} - -func WithExecuteLimit(limit int) MethodOption { - return func(opts *MethodOptions) { - opts.Method.ExecuteLimit = strconv.Itoa(limit) - } -} - -func WithExecuteLimitRejectedHandler(handler string) MethodOption { - return func(opts *MethodOptions) { - opts.Method.ExecuteLimitRejectedHandler = handler - } -} - -func WithSticky() MethodOption { - return func(opts *MethodOptions) { - opts.Method.Sticky = true - } -} - -func WithRequestTimeout(timeout time.Duration) MethodOption { - return func(opts *MethodOptions) { - opts.Method.RequestTimeout = timeout.String() - } -} - -type MethodOptions struct { - Method *global.MethodConfig -} - -func defaultMethodOptions() *MethodOptions { - return &MethodOptions{Method: &global.MethodConfig{}} -} - -func NewMethodOptions(opts ...MethodOption) *MethodOptions { - defOpts := defaultMethodOptions() - for _, opt := range opts { - opt(defOpts) - } - return defOpts -} diff --git a/config/otel_config.go b/config/otel_config.go deleted file mode 100644 index cf7a352e47..0000000000 --- a/config/otel_config.go +++ /dev/null @@ -1,120 +0,0 @@ -/* - * 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 ( - "github.com/creasty/defaults" - - "github.com/dubbogo/gost/log/logger" - - "github.com/pkg/errors" - - "go.opentelemetry.io/otel" -) - -import ( - "dubbo.apache.org/dubbo-go/v3/common/extension" - "dubbo.apache.org/dubbo-go/v3/otel/trace" -) - -type OtelConfig struct { - TraceConfig *OtelTraceConfig `yaml:"tracing" json:"trace,omitempty" property:"trace"` -} - -type OtelTraceConfig struct { - Enable *bool `default:"false" yaml:"enable" json:"enable,omitempty" property:"enable"` - Exporter string `default:"stdout" yaml:"exporter" json:"exporter,omitempty" property:"exporter"` // stdout, jaeger, zipkin, otlp-http, otlp-grpc - Endpoint string `default:"" yaml:"endpoint" json:"endpoint,omitempty" property:"endpoint"` - Propagator string `default:"w3c" yaml:"propagator" json:"propagator,omitempty" property:"propagator"` // one of w3c(standard), b3(for zipkin), - SampleMode string `default:"ratio" yaml:"sample-mode" json:"sample-mode,omitempty" property:"sample-mode"` // one of always, never, ratio - SampleRatio float64 `default:"0.5" yaml:"sample-ratio" json:"sample-ratio,omitempty" property:"sample-ratio"` // [0.0, 1.0] - Insecure bool `default:"false" yaml:"insecure" json:"insecure,omitempty" property:"insecure"` -} - -func (oc *OtelConfig) Init(appConfig *ApplicationConfig) error { - if oc == nil { - return errors.New("otel config is nil") - } - if err := defaults.Set(oc); err != nil { - return err - } - if err := verify(oc); err != nil { - return err - } - if *oc.TraceConfig.Enable { - extension.AddCustomShutdownCallback(extension.GetTraceShutdownCallback()) - return oc.TraceConfig.init(appConfig) - } - - return nil -} - -func (c *OtelTraceConfig) init(appConfig *ApplicationConfig) error { - exporter, err := extension.GetTraceExporter(c.Exporter, c.toTraceProviderConfig(appConfig)) - if err != nil { - return err - } - otel.SetTracerProvider(exporter.GetTracerProvider()) - otel.SetTextMapPropagator(exporter.GetPropagator()) - - // print trace exporter configuration - if c.Exporter == "stdout" { - logger.Infof("enable %s trace provider with propagator: %s", c.Exporter, c.Propagator) - } else { - logger.Infof("enable %s trace provider with endpoint: %s, propagator: %s", c.Exporter, c.Endpoint, c.Propagator) - } - logger.Infof("sample mode: %s", c.SampleMode) - if c.SampleMode == "ratio" { - logger.Infof("sample ratio: %.2f", c.SampleRatio) - } - - return nil -} - -func (c *OtelTraceConfig) toTraceProviderConfig(a *ApplicationConfig) *trace.ExporterConfig { - tpc := &trace.ExporterConfig{ - Exporter: c.Exporter, - Endpoint: c.Endpoint, - SampleMode: c.SampleMode, - SampleRatio: c.SampleRatio, - Propagator: c.Propagator, - ServiceNamespace: a.Organization, - ServiceName: a.Name, - ServiceVersion: a.Version, - Insecure: c.Insecure, - } - return tpc -} - -type OtelConfigBuilder struct { - otelConfig *OtelConfig -} - -func NewOtelConfigBuilder() *OtelConfigBuilder { - return &OtelConfigBuilder{ - otelConfig: &OtelConfig{ - TraceConfig: &OtelTraceConfig{}, - }, - } -} - -func (ocb *OtelConfigBuilder) Build() *OtelConfig { - return ocb.otelConfig -} - -// TODO: dynamic config diff --git a/config/otel_config_test.go b/config/otel_config_test.go deleted file mode 100644 index 20f6db6e23..0000000000 --- a/config/otel_config_test.go +++ /dev/null @@ -1,40 +0,0 @@ -/* - * 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/stretchr/testify/assert" - "github.com/stretchr/testify/require" -) - -func TestNewOtelConfigBuilder(t *testing.T) { - config := NewOtelConfigBuilder().Build() - assert.NotNil(t, config) - assert.NotNil(t, config.TraceConfig) - - ac := NewApplicationConfigBuilder().Build() - err := config.Init(ac) - require.NoError(t, err) - - tpc := config.TraceConfig.toTraceProviderConfig(ac) - assert.NotNil(t, tpc) -} diff --git a/config/profiles_config.go b/config/profiles_config.go deleted file mode 100644 index a47c8a7194..0000000000 --- a/config/profiles_config.go +++ /dev/null @@ -1,44 +0,0 @@ -/* - * 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 deleted file mode 100644 index e16c3a7a10..0000000000 --- a/config/profiles_config_test.go +++ /dev/null @@ -1,76 +0,0 @@ -/* - * 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" - "github.com/stretchr/testify/require" -) - -import ( - "dubbo.apache.org/dubbo-go/v3/common/constant" -) - -func TestProfilesConfig_Prefix(t *testing.T) { - profiles := &ProfilesConfig{} - assert.Equal(t, constant.ProfilesConfigPrefix, profiles.Prefix()) -} - -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"}) - require.NoError(t, err) - - registries := rc.Registries - assert.NotNil(t, registries) - assert.Equal(t, "10s", registries["nacos"].Timeout) - assert.Equal(t, "nacos://127.0.0.1:8848", registries["nacos"].Address) - - protocols := rc.Protocols - assert.NotNil(t, protocols) - assert.Equal(t, "dubbo", protocols["dubbo"].Name) - assert.Equal(t, "20000", protocols["dubbo"].Port) - - consumer := rc.Consumer - assert.NotNil(t, consumer) - assert.Equal(t, "dubbo", consumer.References["helloService"].Protocol) - assert.Equal(t, "org.github.dubbo.HelloService", consumer.References["helloService"].InterfaceName) -} - -func Test_getLegalActive(t *testing.T) { - - t.Run("default", func(t *testing.T) { - active := getLegalActive("") - assert.Equal(t, "default", active) - }) - - t.Run("normal", func(t *testing.T) { - active := getLegalActive("active") - assert.Equal(t, "active", active) - }) -} diff --git a/config/protocol_config.go b/config/protocol_config.go deleted file mode 100644 index f75a1c8490..0000000000 --- a/config/protocol_config.go +++ /dev/null @@ -1,100 +0,0 @@ -/* - * 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 ( - "github.com/creasty/defaults" -) - -import ( - "dubbo.apache.org/dubbo-go/v3/common/constant" -) - -// ProtocolConfig is protocol configuration -type ProtocolConfig struct { - Name string `default:"tri" validate:"required" yaml:"name" json:"name,omitempty" property:"name"` - Ip string `yaml:"ip" json:"ip,omitempty" property:"ip"` - Port string `default:"50051" yaml:"port" json:"port,omitempty" property:"port"` - Params any `yaml:"params" json:"params,omitempty" property:"params"` - - TripleConfig *TripleConfig `yaml:"triple" json:"triple,omitempty" property:"triple"` - - // MaxServerSendMsgSize max size of server send message, 1mb=1000kb=1000000b 1mib=1024kb=1048576b. - // more detail to see https://pkg.go.dev/github.com/dustin/go-humanize#pkg-constants - MaxServerSendMsgSize string `yaml:"max-server-send-msg-size" json:"max-server-send-msg-size,omitempty"` - // MaxServerRecvMsgSize max size of server receive message - MaxServerRecvMsgSize string `default:"4mib" yaml:"max-server-recv-msg-size" json:"max-server-recv-msg-size,omitempty"` -} - -// Prefix dubbo.config-center -func (ProtocolConfig) Prefix() string { - return constant.ConfigCenterPrefix -} - -func GetProtocolsInstance() map[string]*ProtocolConfig { - return make(map[string]*ProtocolConfig, 1) -} - -func (p *ProtocolConfig) Init() error { - if err := defaults.Set(p); err != nil { - return err - } - return verify(p) -} - -func NewProtocolConfigBuilder() *ProtocolConfigBuilder { - return &ProtocolConfigBuilder{protocolConfig: &ProtocolConfig{}} -} - -type ProtocolConfigBuilder struct { - protocolConfig *ProtocolConfig -} - -func (pcb *ProtocolConfigBuilder) SetName(name string) *ProtocolConfigBuilder { - pcb.protocolConfig.Name = name - return pcb -} - -func (pcb *ProtocolConfigBuilder) SetIp(ip string) *ProtocolConfigBuilder { - pcb.protocolConfig.Ip = ip - return pcb -} - -func (pcb *ProtocolConfigBuilder) SetPort(port string) *ProtocolConfigBuilder { - pcb.protocolConfig.Port = port - return pcb -} - -func (pcb *ProtocolConfigBuilder) SetParams(params any) *ProtocolConfigBuilder { - pcb.protocolConfig.Params = params - return pcb -} - -func (pcb *ProtocolConfigBuilder) SetMaxServerSendMsgSize(maxServerSendMsgSize string) *ProtocolConfigBuilder { - pcb.protocolConfig.MaxServerSendMsgSize = maxServerSendMsgSize - return pcb -} - -func (pcb *ProtocolConfigBuilder) SetMaxServerRecvMsgSize(maxServerRecvMsgSize string) *ProtocolConfigBuilder { - pcb.protocolConfig.MaxServerRecvMsgSize = maxServerRecvMsgSize - return pcb -} - -func (pcb *ProtocolConfigBuilder) Build() *ProtocolConfig { - return pcb.protocolConfig -} diff --git a/config/protocol_config_test.go b/config/protocol_config_test.go deleted file mode 100644 index 543ed34336..0000000000 --- a/config/protocol_config_test.go +++ /dev/null @@ -1,53 +0,0 @@ -/* - * 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/stretchr/testify/assert" - "github.com/stretchr/testify/require" -) - -func TestGetProtocolsConfig(t *testing.T) { - - t.Run("empty use default", func(t *testing.T) { - err := Load(WithPath("./testdata/config/protocol/empty_application.yaml")) - require.NoError(t, err) - protocols := GetRootConfig().Protocols - assert.NotNil(t, protocols) - // default - assert.Equal(t, "tri", protocols["tri"].Name) - assert.Equal(t, string("50051"), protocols["tri"].Port) - assert.Equal(t, "4mib", protocols["tri"].MaxServerRecvMsgSize) - }) - - t.Run("use config", func(t *testing.T) { - err := Load(WithPath("./testdata/config/protocol/application.yaml")) - require.NoError(t, err) - protocols := GetRootConfig().Protocols - assert.NotNil(t, protocols) - // default - assert.Equal(t, "dubbo", protocols["dubbo"].Name) - assert.Equal(t, string("20000"), protocols["dubbo"].Port) - assert.Equal(t, "4mib", protocols["dubbo"].MaxServerSendMsgSize) - assert.Equal(t, "4mib", protocols["dubbo"].MaxServerRecvMsgSize) - }) -} diff --git a/config/provider_config.go b/config/provider_config.go deleted file mode 100644 index e84e395d90..0000000000 --- a/config/provider_config.go +++ /dev/null @@ -1,279 +0,0 @@ -/* - * 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 ( - "fmt" - "strings" -) - -import ( - "github.com/creasty/defaults" - - "github.com/dubbogo/gost/log/logger" - - tripleConstant "github.com/dubbogo/triple/pkg/common/constant" - - perrors "github.com/pkg/errors" -) - -import ( - "dubbo.apache.org/dubbo-go/v3/common" - "dubbo.apache.org/dubbo-go/v3/common/constant" - aslimiter "dubbo.apache.org/dubbo-go/v3/filter/adaptivesvc/limiter" -) - -// ProviderConfig is the default configuration of service provider -type ProviderConfig struct { - Filter string `yaml:"filter" json:"filter,omitempty" property:"filter"` - // Deprecated Register whether registration is required - Register bool `yaml:"register" json:"register" property:"register"` - // RegistryIDs is registry ids list - RegistryIDs []string `yaml:"registry-ids" json:"registry-ids" property:"registry-ids"` - // protocol - ProtocolIDs []string `yaml:"protocol-ids" json:"protocol-ids" property:"protocol-ids"` - // TracingKey is tracing ids list - TracingKey string `yaml:"tracing-key" json:"tracing-key" property:"tracing-key"` - // Services services - Services map[string]*ServiceConfig `yaml:"services" json:"services,omitempty" property:"services"` - ProxyFactory string `default:"default" yaml:"proxy" json:"proxy,omitempty" property:"proxy"` - FilterConf any `yaml:"filter_conf" json:"filter_conf,omitempty" property:"filter_conf"` - ConfigType map[string]string `yaml:"config_type" json:"config_type,omitempty" property:"config_type"` - // adaptive service - AdaptiveService bool `yaml:"adaptive-service" json:"adaptive-service" property:"adaptive-service"` - AdaptiveServiceVerbose bool `yaml:"adaptive-service-verbose" json:"adaptive-service-verbose" property:"adaptive-service-verbose"` - - rootConfig *RootConfig -} - -func (ProviderConfig) Prefix() string { - return constant.ProviderConfigPrefix -} - -func (c *ProviderConfig) check() error { - if err := defaults.Set(c); err != nil { - return err - } - return verify(c) -} - -func (c *ProviderConfig) Init(rc *RootConfig) error { - if c == nil { - return nil - } - buildDebugMsg := func() string { - if len(c.Services) == 0 { - return "empty" - } - providerNames := make([]string, 0, len(c.Services)) - for k := range c.Services { - providerNames = append(providerNames, k) - } - return strings.Join(providerNames, ", ") - } - logger.Debugf("Registered provider services are %v", buildDebugMsg()) - - c.RegistryIDs = translateIds(c.RegistryIDs) - if len(c.RegistryIDs) <= 0 { - c.RegistryIDs = rc.getRegistryIds() - } - c.ProtocolIDs = translateIds(c.ProtocolIDs) - - if c.TracingKey == "" && len(rc.Tracing) > 0 { - for k := range rc.Tracing { - c.TracingKey = k - break - } - } - for key, serviceConfig := range c.Services { - if serviceConfig.Interface == "" { - service := GetProviderService(key) - // try to use interface name defined by pb - supportPBPackagerNameService, ok := service.(common.TriplePBService) - if !ok { - logger.Errorf("Service with reference = %s is not support read interface name from it."+ - "Please run go install github.com/dubbogo/dubbogo-cli/cmd/protoc-gen-go-triple@latest to update your "+ - "protoc-gen-go-triple and re-generate your pb file again."+ - "If you are not using pb serialization, please set 'interface' field in service config.", key) - continue - } else { - // use interface name defined by pb - serviceConfig.Interface = supportPBPackagerNameService.XXX_InterfaceName() - } - } - if err := serviceConfig.Init(rc); err != nil { - return err - } - - serviceConfig.adaptiveService = c.AdaptiveService - } - - for k, v := range rc.Protocols { - if v.Name == tripleConstant.TRIPLE { - // Auto create grpc based health check service. - healthService := NewServiceConfigBuilder(). - SetProtocolIDs(k). - SetNotRegister(true). - SetInterface(constant.HealthCheckServiceInterface). - Build() - if err := healthService.Init(rc); err != nil { - return err - } - c.Services[constant.HealthCheckServiceTypeName] = healthService - - // Auto create reflection service configure only when provider with triple service is configured. - tripleReflectionService := NewServiceConfigBuilder(). - SetProtocolIDs(k). - SetNotRegister(true). - SetInterface(constant.ReflectionServiceInterface). - Build() - if err := tripleReflectionService.Init(rc); err != nil { - return err - } - // Maybe only register once, If setting this service, break from traversing Protocols. - c.Services[constant.ReflectionServiceTypeName] = tripleReflectionService - break - } - } - - if err := c.check(); err != nil { - return err - } - // enable adaptive service verbose - if c.AdaptiveServiceVerbose { - if !c.AdaptiveService { - return perrors.Errorf("The adaptive service is disabled, " + - "adaptive service verbose should be disabled either.") - } - logger.Infof("adaptive service verbose is enabled.") - logger.Debugf("debug-level info could be shown.") - aslimiter.Verbose = true - } - return nil -} - -func (c *ProviderConfig) Load() { - for registeredTypeName, service := range GetProviderServiceMap() { - serviceConfig, ok := c.Services[registeredTypeName] - if !ok { - if registeredTypeName == constant.ReflectionServiceTypeName || - registeredTypeName == constant.HealthCheckServiceTypeName { - // do not auto generate reflection or health check server's configuration. - continue - } - // service doesn't config in config file, create one with default - supportPBPackagerNameService, ok := service.(common.TriplePBService) - if !ok { - logger.Warnf( - "The provider service %s is ignored: neither the config is found, nor it is a valid Triple service.", - registeredTypeName) - continue - } - serviceConfig = NewServiceConfigBuilder().Build() - // use interface name defined by pb - serviceConfig.Interface = supportPBPackagerNameService.XXX_InterfaceName() - if err := serviceConfig.Init(GetRootConfig()); err != nil { - logger.Errorf("Service with registeredTypeName = %s init failed with error = %#v", registeredTypeName, err) - } - serviceConfig.adaptiveService = c.AdaptiveService - } - serviceConfig.id = registeredTypeName - serviceConfig.Implement(service) - if err := serviceConfig.Export(); err != nil { - logger.Errorf(fmt.Sprintf("service with registeredTypeName = %s export failed! err: %#v", registeredTypeName, err)) - } - } -} - -// newEmptyProviderConfig returns ProviderConfig with default ApplicationConfig -func newEmptyProviderConfig() *ProviderConfig { - newProviderConfig := &ProviderConfig{ - Services: make(map[string]*ServiceConfig), - RegistryIDs: make([]string, 8), - ProtocolIDs: make([]string, 8), - } - return newProviderConfig -} - -type ProviderConfigBuilder struct { - providerConfig *ProviderConfig -} - -func NewProviderConfigBuilder() *ProviderConfigBuilder { - return &ProviderConfigBuilder{providerConfig: newEmptyProviderConfig()} -} - -func (pcb *ProviderConfigBuilder) SetFilter(filter string) *ProviderConfigBuilder { - pcb.providerConfig.Filter = filter - return pcb -} - -func (pcb *ProviderConfigBuilder) SetRegister(register bool) *ProviderConfigBuilder { - pcb.providerConfig.Register = register - return pcb -} - -func (pcb *ProviderConfigBuilder) SetRegistryIDs(RegistryIDs ...string) *ProviderConfigBuilder { - pcb.providerConfig.RegistryIDs = RegistryIDs - return pcb -} - -func (pcb *ProviderConfigBuilder) SetServices(services map[string]*ServiceConfig) *ProviderConfigBuilder { - pcb.providerConfig.Services = services - return pcb -} - -func (pcb *ProviderConfigBuilder) AddService(serviceID string, serviceConfig *ServiceConfig) *ProviderConfigBuilder { - if pcb.providerConfig.Services == nil { - pcb.providerConfig.Services = make(map[string]*ServiceConfig) - } - pcb.providerConfig.Services[serviceID] = serviceConfig - return pcb -} - -func (pcb *ProviderConfigBuilder) SetProxyFactory(proxyFactory string) *ProviderConfigBuilder { - pcb.providerConfig.ProxyFactory = proxyFactory - return pcb -} - -func (pcb *ProviderConfigBuilder) SetFilterConf(filterConf any) *ProviderConfigBuilder { - pcb.providerConfig.FilterConf = filterConf - return pcb -} - -func (pcb *ProviderConfigBuilder) SetConfigType(configType map[string]string) *ProviderConfigBuilder { - pcb.providerConfig.ConfigType = configType - return pcb -} - -func (pcb *ProviderConfigBuilder) AddConfigType(key, value string) *ProviderConfigBuilder { - if pcb.providerConfig.ConfigType == nil { - pcb.providerConfig.ConfigType = make(map[string]string) - } - pcb.providerConfig.ConfigType[key] = value - return pcb -} - -func (pcb *ProviderConfigBuilder) SetRootConfig(rootConfig *RootConfig) *ProviderConfigBuilder { - pcb.providerConfig.rootConfig = rootConfig - return pcb -} - -func (pcb *ProviderConfigBuilder) Build() *ProviderConfig { - return pcb.providerConfig -} diff --git a/config/provider_config_test.go b/config/provider_config_test.go deleted file mode 100644 index 8dc861ccef..0000000000 --- a/config/provider_config_test.go +++ /dev/null @@ -1,87 +0,0 @@ -/* - * 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/stretchr/testify/assert" - "github.com/stretchr/testify/require" -) - -import ( - "dubbo.apache.org/dubbo-go/v3/common/constant" - _ "dubbo.apache.org/dubbo-go/v3/metadata/report/nacos" -) - -func TestProviderConfigEmptyRegistry(t *testing.T) { - err := Load(WithPath("./testdata/config/provider/empty_registry_application.yaml")) - require.NoError(t, err) - provider := GetRootConfig().Provider - assert.Len(t, provider.RegistryIDs, 1) - assert.Equal(t, "nacos", provider.RegistryIDs[0]) -} - -func TestProviderConfigRootRegistry(t *testing.T) { - err := Load(WithPath("./testdata/config/provider/registry_application.yaml")) - require.NoError(t, err) - provider := GetRootConfig().Provider - assert.NotNil(t, provider) - assert.NotNil(t, provider.Services["HelloService"]) - assert.NotNil(t, provider.Services["OrderService"]) - - assert.Len(t, provider.Services["HelloService"].RegistryIDs, 2) - assert.Len(t, provider.Services["OrderService"].RegistryIDs, 1) -} - -// -//func TestConsumerInitWithDefaultProtocol(t *testing.T) { -// conPath, err := filepath.Abs("./testdata/consumer_config_withoutProtocol.yml") -// require.NoError(t, err) -// assert.NoError(t, consumer.ConsumerInit(conPath)) -// assert.Equal(t, "dubbo", config.consumerConfig.References["UserProvider"].Protocol) -//} -// -//func TestProviderInitWithDefaultProtocol(t *testing.T) { -// conPath, err := filepath.Abs("./testdata/provider_config_withoutProtocol.yml") -// require.NoError(t, err) -// assert.NoError(t, ProviderInit(conPath)) -// assert.Equal(t, "dubbo", config.referenceConfig.Services["UserProvider"].Protocol) -//} - -func TestNewProviderConfigBuilder(t *testing.T) { - - config := NewProviderConfigBuilder(). - SetFilter("echo"). - SetRegister(true). - SetRegistryIDs("nacos"). - SetServices(map[string]*ServiceConfig{}). - AddService("HelloService", &ServiceConfig{}). - SetProxyFactory("default"). - SetFilterConf(nil). - SetConfigType(map[string]string{}). - AddConfigType("", ""). - SetRootConfig(nil). - Build() - - err := config.check() - require.NoError(t, err) - assert.Equal(t, constant.ProviderConfigPrefix, config.Prefix()) -} diff --git a/config/reference_config.go b/config/reference_config.go deleted file mode 100644 index 6ac6f4e818..0000000000 --- a/config/reference_config.go +++ /dev/null @@ -1,547 +0,0 @@ -/* - * 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 ( - "fmt" - "net/url" - "os" - "strconv" - "time" -) - -import ( - "github.com/creasty/defaults" - - "github.com/dubbogo/gost/log/logger" - gxstrings "github.com/dubbogo/gost/strings" - - constant2 "github.com/dubbogo/triple/pkg/common/constant" -) - -import ( - "dubbo.apache.org/dubbo-go/v3/cluster/directory/static" - "dubbo.apache.org/dubbo-go/v3/common" - "dubbo.apache.org/dubbo-go/v3/common/constant" - "dubbo.apache.org/dubbo-go/v3/common/extension" - "dubbo.apache.org/dubbo-go/v3/filter/generic" - "dubbo.apache.org/dubbo-go/v3/protocol/base" - "dubbo.apache.org/dubbo-go/v3/protocol/protocolwrapper" - "dubbo.apache.org/dubbo-go/v3/proxy" -) - -// ReferenceConfig is the configuration of service consumer -type ReferenceConfig struct { - pxy *proxy.Proxy - invoker base.Invoker - urls []*common.URL - rootConfig *RootConfig - - id string - InterfaceName string `yaml:"interface" json:"interface,omitempty" property:"interface"` - Check *bool `yaml:"check" json:"check,omitempty" property:"check"` - URL string `yaml:"url" json:"url,omitempty" property:"url"` - Filter string `yaml:"filter" json:"filter,omitempty" property:"filter"` - Protocol string `yaml:"protocol" json:"protocol,omitempty" property:"protocol"` - RegistryIDs []string `yaml:"registry-ids" json:"registry-ids,omitempty" property:"registry-ids"` - Cluster string `yaml:"cluster" json:"cluster,omitempty" property:"cluster"` - Loadbalance string `yaml:"loadbalance" json:"loadbalance,omitempty" property:"loadbalance"` - Retries string `yaml:"retries" json:"retries,omitempty" property:"retries"` - Group string `yaml:"group" json:"group,omitempty" property:"group"` - Version string `yaml:"version" json:"version,omitempty" property:"version"` - Serialization string `yaml:"serialization" json:"serialization" property:"serialization"` - ProvidedBy string `yaml:"provided_by" json:"provided_by,omitempty" property:"provided_by"` - - MethodsConfig []*MethodConfig `yaml:"methods" json:"methods,omitempty" property:"methods"` - // TODO: rename protocol_config to protocol when publish 4.0.0. - ProtocolClientConfig *ClientProtocolConfig `yaml:"protocol_config" json:"protocol_config,omitempty" property:"protocol_config"` - - Async bool `yaml:"async" json:"async,omitempty" property:"async"` - Params map[string]string `yaml:"params" json:"params,omitempty" property:"params"` - Generic string `yaml:"generic" json:"generic,omitempty" property:"generic"` - Sticky bool `yaml:"sticky" json:"sticky,omitempty" property:"sticky"` - RequestTimeout string `yaml:"timeout" json:"timeout,omitempty" property:"timeout"` - ForceTag bool `yaml:"force.tag" json:"force.tag,omitempty" property:"force.tag"` - TracingKey string `yaml:"tracing-key" json:"tracing-key,omitempty" propertiy:"tracing-key"` - metaDataType string - metricsEnable bool - MeshProviderPort int `yaml:"mesh-provider-port" json:"mesh-provider-port,omitempty" propertiy:"mesh-provider-port"` -} - -func (rc *ReferenceConfig) Prefix() string { - return constant.ReferenceConfigPrefix + rc.InterfaceName + "." -} - -func (rc *ReferenceConfig) Init(root *RootConfig) error { - for _, method := range rc.MethodsConfig { - if err := method.Init(); err != nil { - return err - } - } - if err := defaults.Set(rc); err != nil { - return err - } - rc.rootConfig = root - if root.Application != nil { - rc.metaDataType = root.Application.MetadataType - if rc.Group == "" { - rc.Group = root.Application.Group - } - if rc.Version == "" { - rc.Version = root.Application.Version - } - } - rc.RegistryIDs = translateIds(rc.RegistryIDs) - if root.Consumer != nil { - if rc.Filter == "" { - rc.Filter = root.Consumer.Filter - } - if len(rc.RegistryIDs) <= 0 { - rc.RegistryIDs = root.Consumer.RegistryIDs - } - if rc.Protocol == "" { - rc.Protocol = root.Consumer.Protocol - } - if rc.RequestTimeout == "" && root.Consumer.RequestTimeout != "" { - rc.RequestTimeout = root.Consumer.RequestTimeout - } - if rc.TracingKey == "" { - rc.TracingKey = root.Consumer.TracingKey - } - if rc.Check == nil { - rc.Check = &root.Consumer.Check - } - } - if rc.Cluster == "" { - rc.Cluster = "failover" - } - if root.Metrics.Enable != nil { - rc.metricsEnable = *root.Metrics.Enable - } - - return verify(rc) -} - -func getEnv(key, fallback string) string { - if value, ok := os.LookupEnv(key); ok { - return value - } - return fallback -} - -func updateOrCreateMeshURL(rc *ReferenceConfig) { - if rc.URL != "" { - logger.Infof("URL specified explicitly %v", rc.URL) - } - - if !rc.rootConfig.Consumer.MeshEnabled { - return - } - if rc.Protocol != constant2.TRIPLE { - panic(fmt.Sprintf("Mesh mode enabled, Triple protocol expected but %v protocol found!", rc.Protocol)) - } - if rc.ProvidedBy == "" { - panic("Mesh mode enabled, provided-by should not be empty!") - } - - podNamespace := getEnv(constant.PodNamespaceEnvKey, constant.DefaultNamespace) - clusterDomain := getEnv(constant.ClusterDomainKey, constant.DefaultClusterDomain) - - var meshPort int - if rc.MeshProviderPort > 0 { - meshPort = rc.MeshProviderPort - } else { - meshPort = constant.DefaultMeshPort - } - - rc.URL = "tri://" + rc.ProvidedBy + "." + podNamespace + constant.SVC + clusterDomain + ":" + strconv.Itoa(meshPort) -} - -// Refer retrieves invokers from urls. -func (rc *ReferenceConfig) Refer(srv any) { - // If adaptive service is enabled, - // the cluster and load balance should be overridden to "adaptivesvc" and "p2c" respectively. - if rc.rootConfig.Consumer.AdaptiveService { - rc.Cluster = constant.ClusterKeyAdaptiveService - rc.Loadbalance = constant.LoadBalanceKeyP2C - } - - // cfgURL is an interface-level invoker url, in the other words, it represents an interface. - cfgURL := common.NewURLWithOptions( - common.WithPath(rc.InterfaceName), - common.WithProtocol(rc.Protocol), - common.WithParams(rc.getURLMap()), - common.WithParamsValue(constant.BeanNameKey, rc.id), - common.WithParamsValue(constant.MetadataTypeKey, rc.metaDataType), - ) - - SetConsumerServiceByInterfaceName(rc.InterfaceName, srv) - if rc.ForceTag { - cfgURL.SetParam(constant.ForceUseTag, "true") - } - rc.postProcessConfig(cfgURL) - - // if mesh-enabled is set - updateOrCreateMeshURL(rc) - - // retrieving urls from config, and appending the urls to rc.urls - if rc.URL != "" { // use user-specific urls - /* - Two types of URL are allowed for rc.URL: - 1. direct url: server IP, that is, no need for a registry anymore - 2. registry url - They will be handled in different ways: - For example, we have a direct url and a registry url: - 1. "tri://localhost:10000" is a direct url - 2. "registry://localhost:2181" is a registry url. - Then, rc.URL looks like a string separated by semicolon: "tri://localhost:10000;registry://localhost:2181". - The result of urlStrings is a string array: []string{"tri://localhost:10000", "registry://localhost:2181"}. - */ - urlStrings := gxstrings.RegSplit(rc.URL, "\\s*[;]+\\s*") - for _, urlStr := range urlStrings { - serviceURL, err := common.NewURL(urlStr) - if err != nil { - panic(fmt.Sprintf("url configuration error, please check your configuration, user specified URL %v refer error, error message is %v ", urlStr, err)) - } - if serviceURL.Protocol == constant.RegistryProtocol { // serviceURL in this branch is a registry protocol - serviceURL.SubURL = cfgURL - rc.urls = append(rc.urls, serviceURL) - } else { // serviceURL in this branch is the target endpoint IP address - if serviceURL.Path == "" { - serviceURL.Path = "/" + rc.InterfaceName - } - // replace params of serviceURL with params of cfgUrl - // other stuff, e.g. IP, port, etc., are same as serviceURL - newURL := serviceURL.MergeURL(cfgURL) - newURL.SetParam("peer", "true") - rc.urls = append(rc.urls, newURL) - } - } - } else { // use registry configs - rc.urls = LoadRegistries(rc.RegistryIDs, rc.rootConfig.Registries, common.CONSUMER) - // set url to regURLs - for _, regURL := range rc.urls { - regURL.SubURL = cfgURL - } - } - - // Get invokers according to rc.urls - var ( - invoker base.Invoker - regURL *common.URL - ) - invokers := make([]base.Invoker, len(rc.urls)) - for i, u := range rc.urls { - if u.Protocol == constant.ServiceRegistryProtocol { - invoker = extension.GetProtocol(constant.RegistryProtocol).Refer(u) - } else { - invoker = extension.GetProtocol(u.Protocol).Refer(u) - } - - if rc.URL != "" { - invoker = protocolwrapper.BuildInvokerChain(invoker, constant.ReferenceFilterKey) - } - - invokers[i] = invoker - if u.Protocol == constant.RegistryProtocol { - regURL = u - } - } - - // TODO(hxmhlt): decouple from directory, config should not depend on directory module - if len(invokers) == 1 { - rc.invoker = invokers[0] - if rc.URL != "" { - hitClu := constant.ClusterKeyFailover - if u := rc.invoker.GetURL(); u != nil { - hitClu = u.GetParam(constant.ClusterKey, constant.ClusterKeyZoneAware) - } - cluster, err := extension.GetCluster(hitClu) - if err != nil { - logger.Errorf("reference config get cluster %s error, error message is %w, will skip this invoker", - hitClu, err) - return - } - if cluster == nil { - logger.Errorf("reference config cluster is nil for key %s, will skip this invoker", hitClu) - return - } - rc.invoker = cluster.Join(static.NewDirectory(invokers)) - } - } else { - var hitClu string - if regURL != nil { - // for multi-subscription scenario, use 'zone-aware' policy by default - hitClu = constant.ClusterKeyZoneAware - } else { - // not a registry url, must be direct invoke. - hitClu = constant.ClusterKeyFailover - if u := invokers[0].GetURL(); u != nil { - hitClu = u.GetParam(constant.ClusterKey, constant.ClusterKeyZoneAware) - } - } - cluster, err := extension.GetCluster(hitClu) - if err != nil { - logger.Errorf("reference config get cluster %s error, error message is %w, will skip this invoker", - hitClu, err) - return - } - if cluster == nil { - logger.Errorf("reference config cluster is nil for key %s, will skip this invoker", hitClu) - return - } - rc.invoker = cluster.Join(static.NewDirectory(invokers)) - } - - // create proxy - if rc.Async { - callback := GetCallback(rc.id) - rc.pxy = extension.GetProxyFactory(rc.rootConfig.Consumer.ProxyFactory).GetAsyncProxy(rc.invoker, callback, cfgURL) - } else { - rc.pxy = extension.GetProxyFactory(rc.rootConfig.Consumer.ProxyFactory).GetProxy(rc.invoker, cfgURL) - } -} - -// Implement -// @v is service provider implemented RPCService -func (rc *ReferenceConfig) Implement(v common.RPCService) { - rc.pxy.Implement(v) -} - -// GetRPCService gets RPCService from proxy -func (rc *ReferenceConfig) GetRPCService() common.RPCService { - return rc.pxy.Get() -} - -// GetProxy gets proxy -func (rc *ReferenceConfig) GetProxy() *proxy.Proxy { - return rc.pxy -} - -func (rc *ReferenceConfig) getURLMap() url.Values { - urlMap := url.Values{} - // first set user params - for k, v := range rc.Params { - urlMap.Set(k, v) - } - - urlMap.Set(constant.InterfaceKey, rc.InterfaceName) - urlMap.Set(constant.TimestampKey, strconv.FormatInt(time.Now().Unix(), 10)) - urlMap.Set(constant.ClusterKey, rc.Cluster) - urlMap.Set(constant.LoadbalanceKey, rc.Loadbalance) - urlMap.Set(constant.RetriesKey, rc.Retries) - urlMap.Set(constant.GroupKey, rc.Group) - urlMap.Set(constant.VersionKey, rc.Version) - urlMap.Set(constant.GenericKey, rc.Generic) - urlMap.Set(constant.RegistryRoleKey, strconv.Itoa(common.CONSUMER)) - urlMap.Set(constant.ProvidedBy, rc.ProvidedBy) - urlMap.Set(constant.SerializationKey, rc.Serialization) - urlMap.Set(constant.TracingConfigKey, rc.TracingKey) - - urlMap.Set(constant.ReleaseKey, "dubbo-golang-"+constant.Version) - urlMap.Set(constant.SideKey, (common.RoleType(common.CONSUMER)).Role()) - - if len(rc.RequestTimeout) != 0 { - urlMap.Set(constant.TimeoutKey, rc.RequestTimeout) - } - // getty invoke async or sync - urlMap.Set(constant.AsyncKey, strconv.FormatBool(rc.Async)) - urlMap.Set(constant.StickyKey, strconv.FormatBool(rc.Sticky)) - - // applicationConfig info - urlMap.Set(constant.ApplicationKey, rc.rootConfig.Application.Name) - urlMap.Set(constant.OrganizationKey, rc.rootConfig.Application.Organization) - urlMap.Set(constant.NameKey, rc.rootConfig.Application.Name) - urlMap.Set(constant.ModuleKey, rc.rootConfig.Application.Module) - urlMap.Set(constant.AppVersionKey, rc.rootConfig.Application.Version) - urlMap.Set(constant.OwnerKey, rc.rootConfig.Application.Owner) - urlMap.Set(constant.EnvironmentKey, rc.rootConfig.Application.Environment) - - // filter - defaultReferenceFilter := constant.DefaultReferenceFilters - if rc.Generic != "" { - defaultReferenceFilter = constant.GenericFilterKey + "," + defaultReferenceFilter - } - if rc.metricsEnable { - defaultReferenceFilter += fmt.Sprintf(",%s", constant.MetricsFilterKey) - } - urlMap.Set(constant.ReferenceFilterKey, mergeValue(rc.Filter, "", defaultReferenceFilter)) - - for _, v := range rc.MethodsConfig { - urlMap.Set("methods."+v.Name+"."+constant.LoadbalanceKey, v.LoadBalance) - urlMap.Set("methods."+v.Name+"."+constant.RetriesKey, v.Retries) - urlMap.Set("methods."+v.Name+"."+constant.StickyKey, strconv.FormatBool(v.Sticky)) - if len(v.RequestTimeout) != 0 { - urlMap.Set("methods."+v.Name+"."+constant.TimeoutKey, v.RequestTimeout) - } - } - - return urlMap -} - -// GenericLoad ... -func (rc *ReferenceConfig) GenericLoad(id string) { - genericService := generic.NewGenericService(id) - SetConsumerService(genericService) - rc.id = id - rc.Refer(genericService) - rc.Implement(genericService) -} - -// GetInvoker get invoker from ReferenceConfig -func (rc *ReferenceConfig) GetInvoker() base.Invoker { - return rc.invoker -} - -// postProcessConfig asks registered ConfigPostProcessor to post-process the current ReferenceConfig. -func (rc *ReferenceConfig) postProcessConfig(url *common.URL) { - for _, p := range extension.GetConfigPostProcessors() { - p.PostProcessReferenceConfig(url) - } -} - -//////////////////////////////////// reference config api - -// newEmptyReferenceConfig returns empty ReferenceConfig -func newEmptyReferenceConfig() *ReferenceConfig { - newReferenceConfig := &ReferenceConfig{} - newReferenceConfig.MethodsConfig = make([]*MethodConfig, 0, 8) - newReferenceConfig.Params = make(map[string]string, 8) - return newReferenceConfig -} - -type ReferenceConfigBuilder struct { - referenceConfig *ReferenceConfig -} - -func NewReferenceConfigBuilder() *ReferenceConfigBuilder { - return &ReferenceConfigBuilder{referenceConfig: newEmptyReferenceConfig()} -} - -func (pcb *ReferenceConfigBuilder) SetInterface(interfaceName string) *ReferenceConfigBuilder { - pcb.referenceConfig.InterfaceName = interfaceName - return pcb -} - -func (pcb *ReferenceConfigBuilder) SetRegistryIDs(registryIDs ...string) *ReferenceConfigBuilder { - pcb.referenceConfig.RegistryIDs = registryIDs - return pcb -} - -func (pcb *ReferenceConfigBuilder) SetGeneric(generic bool) *ReferenceConfigBuilder { - if generic { - pcb.referenceConfig.Generic = "true" - } else { - pcb.referenceConfig.Generic = "false" - } - return pcb -} - -func (pcb *ReferenceConfigBuilder) SetCluster(cluster string) *ReferenceConfigBuilder { - pcb.referenceConfig.Cluster = cluster - return pcb -} - -func (pcb *ReferenceConfigBuilder) SetSerialization(serialization string) *ReferenceConfigBuilder { - pcb.referenceConfig.Serialization = serialization - return pcb -} - -func (pcb *ReferenceConfigBuilder) SetProtocol(protocol string) *ReferenceConfigBuilder { - pcb.referenceConfig.Protocol = protocol - return pcb -} - -func (pcb *ReferenceConfigBuilder) SetURL(url string) *ReferenceConfigBuilder { - pcb.referenceConfig.URL = url - return pcb -} - -func (pcb *ReferenceConfigBuilder) SetFilter(filter string) *ReferenceConfigBuilder { - pcb.referenceConfig.Filter = filter - return pcb -} - -func (pcb *ReferenceConfigBuilder) SetLoadbalance(loadbalance string) *ReferenceConfigBuilder { - pcb.referenceConfig.Loadbalance = loadbalance - return pcb -} - -func (pcb *ReferenceConfigBuilder) SetRetries(retries string) *ReferenceConfigBuilder { - pcb.referenceConfig.Retries = retries - return pcb -} - -func (pcb *ReferenceConfigBuilder) SetGroup(group string) *ReferenceConfigBuilder { - pcb.referenceConfig.Group = group - return pcb -} - -func (pcb *ReferenceConfigBuilder) SetVersion(version string) *ReferenceConfigBuilder { - pcb.referenceConfig.Version = version - return pcb -} - -func (pcb *ReferenceConfigBuilder) SetProvidedBy(providedBy string) *ReferenceConfigBuilder { - pcb.referenceConfig.ProvidedBy = providedBy - return pcb -} - -func (pcb *ReferenceConfigBuilder) SetMethodConfig(methodConfigs []*MethodConfig) *ReferenceConfigBuilder { - pcb.referenceConfig.MethodsConfig = methodConfigs - return pcb -} - -func (pcb *ReferenceConfigBuilder) AddMethodConfig(methodConfig *MethodConfig) *ReferenceConfigBuilder { - pcb.referenceConfig.MethodsConfig = append(pcb.referenceConfig.MethodsConfig, methodConfig) - return pcb -} - -func (pcb *ReferenceConfigBuilder) SetAsync(async bool) *ReferenceConfigBuilder { - pcb.referenceConfig.Async = async - return pcb -} - -func (pcb *ReferenceConfigBuilder) SetParams(params map[string]string) *ReferenceConfigBuilder { - pcb.referenceConfig.Params = params - return pcb -} - -func (pcb *ReferenceConfigBuilder) SetSticky(sticky bool) *ReferenceConfigBuilder { - pcb.referenceConfig.Sticky = sticky - return pcb -} - -func (pcb *ReferenceConfigBuilder) SetRequestTimeout(requestTimeout string) *ReferenceConfigBuilder { - pcb.referenceConfig.RequestTimeout = requestTimeout - return pcb -} - -func (pcb *ReferenceConfigBuilder) SetForceTag(forceTag bool) *ReferenceConfigBuilder { - pcb.referenceConfig.ForceTag = forceTag - return pcb -} - -func (pcb *ReferenceConfigBuilder) SetTracingKey(tracingKey string) *ReferenceConfigBuilder { - pcb.referenceConfig.TracingKey = tracingKey - return pcb -} - -func (pcb *ReferenceConfigBuilder) Build() *ReferenceConfig { - return pcb.referenceConfig -} diff --git a/config/reference_config_test.go b/config/reference_config_test.go deleted file mode 100644 index 4844692ffa..0000000000 --- a/config/reference_config_test.go +++ /dev/null @@ -1,483 +0,0 @@ -/* - * 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/stretchr/testify/assert" - "github.com/stretchr/testify/require" -) - -import ( - "dubbo.apache.org/dubbo-go/v3/common/constant" - _ "dubbo.apache.org/dubbo-go/v3/proxy/proxy_factory" -) - -// import ( -// -// "context" -// "dubbo.apache.org/dubbo-go/v3/config" -// "dubbo.apache.org/dubbo-go/v3/config/applicationConfig" -// "dubbo.apache.org/dubbo-go/v3/config/base" -// "dubbo.apache.org/dubbo-go/v3/config/consumer" -// "dubbo.apache.org/dubbo-go/v3/config/instance" -// "dubbo.apache.org/dubbo-go/v3/config/method" -// registry2 "dubbo.apache.org/dubbo-go/v3/config/registry" -// "sync" -// "testing" -// -// ) -// -// import ( -// -// "github.com/stretchr/testify/assert" -// -// ) -// -// import ( -// -// "dubbo.apache.org/dubbo-go/v3/cluster/cluster_impl" -// "dubbo.apache.org/dubbo-go/v3/common" -// "dubbo.apache.org/dubbo-go/v3/common/constant" -// "dubbo.apache.org/dubbo-go/v3/common/extension" -// "dubbo.apache.org/dubbo-go/v3/filter" -// "dubbo.apache.org/dubbo-go/v3/protocol" -// "dubbo.apache.org/dubbo-go/v3/registry" -// -// ) -// -// var regProtocol protocol.Protocol -// -// func doInitConsumer() { -// config.consumerConfig = &consumer.Config{ -// BaseConfig: base.Config{ -// applicationConfig.Config: &applicationConfig.Config{ -// Organization: "dubbo_org", -// Name: "dubbo", -// Module: "module", -// Version: "2.6.0", -// Owner: "dubbo", -// Environment: "test", -// }, -// }, -// -// Registries: map[string]*registry2.RegistryConfig{ -// "shanghai_reg1": { -// Protocol: "mock", -// TimeoutStr: "2s", -// Group: "shanghai_idc", -// Address: "127.0.0.1:2181", -// Username: "user1", -// Password: "pwd1", -// }, -// "shanghai_reg2": { -// Protocol: "mock", -// TimeoutStr: "2s", -// Group: "shanghai_idc", -// Address: "127.0.0.2:2181", -// Username: "user1", -// Password: "pwd1", -// }, -// "hangzhou_reg1": { -// Protocol: "mock", -// TimeoutStr: "2s", -// Group: "hangzhou_idc", -// Address: "127.0.0.3:2181", -// Username: "user1", -// Password: "pwd1", -// }, -// "hangzhou_reg2": { -// Protocol: "mock", -// TimeoutStr: "2s", -// Group: "hangzhou_idc", -// Address: "127.0.0.4:2181", -// Username: "user1", -// Password: "pwd1", -// }, -// }, -// -// References: map[string]*ReferenceConfig{ -// "MockService": { -// id: "MockProvider", -// Params: map[string]string{ -// "serviceid": "soa.mock", -// "forks": "5", -// }, -// Sticky: false, -// Registry: "shanghai_reg1,shanghai_reg2,hangzhou_reg1,hangzhou_reg2", -// InterfaceName: "com.MockService", -// Protocol: "mock", -// Cluster: "failover", -// Loadbalance: "random", -// Retries: "3", -// Group: "huadong_idc", -// Version: "1.0.0", -// Methods: []*method.MethodConfig{ -// { -// Name: "GetUser", -// Retries: "2", -// LoadBalance: "random", -// }, -// { -// Name: "GetUser1", -// Retries: "2", -// LoadBalance: "random", -// Sticky: true, -// }, -// }, -// }, -// }, -// } -// } -// -// var mockProvider = new(MockProvider) -// -// type MockProvider struct{} -// -// func (m *MockProvider) Reference() string { -// return "MockProvider" -// } -// -// func (m *MockProvider) CallBack(res common.CallbackResponse) { -// // CallBack is a mock function. to implement the interface -// } -// -// func doInitConsumerAsync() { -// doInitConsumer() -// instance.SetConsumerService(mockProvider) -// for _, v := range config.consumerConfig.References { -// v.Async = true -// } -// } -// -// func doInitConsumerWithSingleRegistry() { -// config.consumerConfig = &consumer.Config{ -// BaseConfig: base.Config{ -// applicationConfig.Config: &applicationConfig.Config{ -// Organization: "dubbo_org", -// Name: "dubbo", -// Module: "module", -// Version: "2.6.0", -// Owner: "dubbo", -// Environment: "test", -// }, -// }, -// -// Registry: ®istry2.RegistryConfig{ -// Address: "mock://27.0.0.1:2181", -// Username: "user1", -// Password: "pwd1", -// }, -// Registries: map[string]*registry2.RegistryConfig{}, -// -// References: map[string]*ReferenceConfig{ -// "MockService": { -// Params: map[string]string{ -// "serviceid": "soa.mock", -// "forks": "5", -// }, -// InterfaceName: "com.MockService", -// Protocol: "mock", -// Cluster: "failover", -// Loadbalance: "random", -// Retries: "3", -// Group: "huadong_idc", -// Version: "1.0.0", -// Methods: []*method.MethodConfig{ -// { -// Name: "GetUser", -// Retries: "2", -// LoadBalance: "random", -// }, -// { -// Name: "GetUser1", -// Retries: "2", -// LoadBalance: "random", -// }, -// }, -// }, -// }, -// } -// } -// -// func TestReferMultiReg(t *testing.T) { -// doInitConsumer() -// extension.SetProtocol("registry", GetProtocol) -// extension.SetCluster(constant.ZONEAWARE_CLUSTER_NAME, cluster_impl.NewZoneAwareCluster) -// for _, reference := range config.consumerConfig.References { -// reference.Refer(nil) -// assert.NotNil(t, reference.invoker) -// assert.NotNil(t, reference.pxy) -// } -// config.consumerConfig = nil -// } -// -// func TestRefer(t *testing.T) { -// doInitConsumer() -// extension.SetProtocol("registry", GetProtocol) -// extension.SetCluster(constant.ZONEAWARE_CLUSTER_NAME, cluster_impl.NewZoneAwareCluster) -// -// for _, reference := range config.consumerConfig.References { -// reference.Refer(nil) -// assert.Equal(t, "soa.mock", reference.Params["serviceid"]) -// assert.NotNil(t, reference.invoker) -// assert.NotNil(t, reference.pxy) -// } -// config.consumerConfig = nil -// } -// -// func TestReferAsync(t *testing.T) { -// doInitConsumerAsync() -// extension.SetProtocol("registry", GetProtocol) -// extension.SetCluster(constant.ZONEAWARE_CLUSTER_NAME, cluster_impl.NewZoneAwareCluster) -// -// for _, reference := range config.consumerConfig.References { -// reference.Refer(nil) -// assert.Equal(t, "soa.mock", reference.Params["serviceid"]) -// assert.NotNil(t, reference.invoker) -// assert.NotNil(t, reference.pxy) -// assert.NotNil(t, reference.pxy.GetCallback()) -// } -// config.consumerConfig = nil -// } -// -// func TestReferP2P(t *testing.T) { -// doInitConsumer() -// extension.SetProtocol("dubbo", GetProtocol) -// mockFilter() -// m := config.consumerConfig.References["MockService"] -// m.URL = "dubbo://127.0.0.1:20000" -// -// for _, reference := range config.consumerConfig.References { -// reference.Refer(nil) -// assert.NotNil(t, reference.invoker) -// assert.NotNil(t, reference.pxy) -// } -// config.consumerConfig = nil -// } -// -// func TestReferMultiP2P(t *testing.T) { -// doInitConsumer() -// extension.SetProtocol("dubbo", GetProtocol) -// mockFilter() -// m := config.consumerConfig.References["MockService"] -// m.URL = "dubbo://127.0.0.1:20000;dubbo://127.0.0.2:20000" -// -// for _, reference := range config.consumerConfig.References { -// reference.Refer(nil) -// assert.NotNil(t, reference.invoker) -// assert.NotNil(t, reference.pxy) -// } -// config.consumerConfig = nil -// } -// -// func TestReferMultiP2PWithReg(t *testing.T) { -// doInitConsumer() -// extension.SetProtocol("dubbo", GetProtocol) -// extension.SetProtocol("registry", GetProtocol) -// mockFilter() -// m := config.consumerConfig.References["MockService"] -// m.URL = "dubbo://127.0.0.1:20000;registry://127.0.0.2:20000" -// -// for _, reference := range config.consumerConfig.References { -// reference.Refer(nil) -// assert.NotNil(t, reference.invoker) -// assert.NotNil(t, reference.pxy) -// } -// config.consumerConfig = nil -// } -// -// func TestImplement(t *testing.T) { -// doInitConsumer() -// extension.SetProtocol("registry", GetProtocol) -// extension.SetCluster(constant.ZONEAWARE_CLUSTER_NAME, cluster_impl.NewZoneAwareCluster) -// for _, reference := range config.consumerConfig.References { -// reference.Refer(nil) -// reference.Implement(&config.MockService{}) -// assert.NotNil(t, reference.GetRPCService()) -// -// } -// config.consumerConfig = nil -// } -// -// func TestForking(t *testing.T) { -// doInitConsumer() -// extension.SetProtocol("dubbo", GetProtocol) -// extension.SetProtocol("registry", GetProtocol) -// mockFilter() -// m := config.consumerConfig.References["MockService"] -// m.URL = "dubbo://127.0.0.1:20000;registry://127.0.0.2:20000" -// -// for _, reference := range config.consumerConfig.References { -// reference.Refer(nil) -// forks := int(reference.invoker.GetURL().GetParamInt(constant.FORKS_KEY, constant.DEFAULT_FORKS)) -// assert.Equal(t, 5, forks) -// assert.NotNil(t, reference.pxy) -// assert.NotNil(t, reference.Cluster) -// } -// config.consumerConfig = nil -// } -// -// func TestSticky(t *testing.T) { -// doInitConsumer() -// extension.SetProtocol("dubbo", GetProtocol) -// extension.SetProtocol("registry", GetProtocol) -// mockFilter() -// m := config.consumerConfig.References["MockService"] -// m.URL = "dubbo://127.0.0.1:20000;registry://127.0.0.2:20000" -// -// reference := config.consumerConfig.References["MockService"] -// reference.Refer(nil) -// referenceSticky := reference.invoker.GetURL().GetParam(constant.STICKY_KEY, "false") -// assert.Equal(t, "false", referenceSticky) -// -// method0StickKey := reference.invoker.GetURL().GetMethodParam(reference.Methods[0].Name, constant.STICKY_KEY, "false") -// assert.Equal(t, "false", method0StickKey) -// method1StickKey := reference.invoker.GetURL().GetMethodParam(reference.Methods[1].Name, constant.STICKY_KEY, "false") -// assert.Equal(t, "true", method1StickKey) -// } -// -// func GetProtocol() protocol.Protocol { -// if regProtocol != nil { -// return regProtocol -// } -// return newRegistryProtocol() -// } -// -// func newRegistryProtocol() protocol.Protocol { -// return &mockRegistryProtocol{} -// } -// -// type mockRegistryProtocol struct { -// } -// -// func (*mockRegistryProtocol) Refer(url *common.URL) protocol.Invoker { -// return protocol.NewBaseInvoker(url) -// } -// -// func (*mockRegistryProtocol) Export(invoker protocol.Invoker) protocol.Exporter { -// registryURL := getRegistryURL(invoker) -// if registryURL.Protocol == "service-discovery" { -// metaDataService, err := extension.GetLocalMetadataService("") -// if err != nil { -// panic(err) -// } -// ok, err := metaDataService.ExportURL(invoker.GetURL().SubURL.Clone()) -// if err != nil { -// panic(err) -// } -// if !ok { -// panic("The URL has been registry!") -// } -// } -// return protocol.NewBaseExporter("test", invoker, &sync.Map{}) -// } -// -// func (*mockRegistryProtocol) Destroy() { -// // Destroy is a mock function -// } -// -// func getRegistryURL(invoker protocol.Invoker) *common.URL { -// // here add * for return a new url -// url := invoker.GetURL() -// // if the protocol == registry ,set protocol the registry value in url.params -// if url.Protocol == constant.REGISTRY_PROTOCOL { -// protocol := url.GetParam(constant.REGISTRY_KEY, "") -// url.Protocol = protocol -// } -// return url -// } -// -// func (p *mockRegistryProtocol) GetRegistries() []registry.Registry { -// return []registry.Registry{&config.mockServiceDiscoveryRegistry{}} -// } -// -// func mockFilter() { -// consumerFiler := &mockShutdownFilter{} -// extension.SetFilter(constant.GracefulShutdownConsumerFilterKey, func() filter.Filter { -// return consumerFiler -// }) -// } -// -// type mockShutdownFilter struct { -// } -// -// // Invoke adds the requests count and block the new requests if applicationConfig is closing -// -// func (gf *mockShutdownFilter) Invoke(ctx context.Context, invoker protocol.Invoker, invocation protocol.Invocation) protocol.Result { -// return invoker.Invoke(ctx, invocation) -// } -// -// // OnResponse reduces the number of active processes then return the process result -// -// func (gf *mockShutdownFilter) OnResponse(ctx context.Context, result protocol.Result, invoker protocol.Invoker, invocation protocol.Invocation) protocol.Result { -// return result -// } -func TestNewReferenceConfigBuilder(t *testing.T) { - registryConfig := NewRegistryConfigWithProtocolDefaultPort("nacos") - protocolConfig := NewProtocolConfigBuilder(). - SetName("dubbo"). - SetPort("20000"). - Build() - config := NewReferenceConfigBuilder(). - SetInterface("org.apache.dubbo.HelloService"). - SetRegistryIDs("nacos"). - SetGeneric(false). - SetCluster("cluster"). - SetSerialization("serialization"). - SetProtocol("dubbo"). - Build() - - config.rootConfig = NewRootConfigBuilder(). - SetProtocols(map[string]*ProtocolConfig{"dubbo": protocolConfig}). - SetRegistries(map[string]*RegistryConfig{"nacos": registryConfig}). - Build() - - assert.Equal(t, config.Prefix(), constant.ReferenceConfigPrefix+config.InterfaceName+".") - proxy := config.GetProxy() - assert.Nil(t, proxy) - - values := config.getURLMap() - assert.Empty(t, values.Get(constant.GroupKey)) - - invoker := config.GetInvoker() - assert.Nil(t, invoker) -} - -func TestReferenceConfigInitWithoutConsumerConfig(t *testing.T) { - testRootConfig := NewRootConfigBuilder().Build() - testRootConfig.Consumer = nil - err := NewReferenceConfigBuilder().Build().Init(testRootConfig) - assert.NoError(t, err) -} - -func TestReferenceConfigInitInheritsConsumerRequestTimeout(t *testing.T) { - root := NewRootConfigBuilder(). - SetApplication(NewApplicationConfigBuilder().SetName("test-app").Build()). - SetConsumer(NewConsumerConfigBuilder().SetRequestTimeout("5s").Build()). - Build() - - ref := NewReferenceConfigBuilder().Build() - err := ref.Init(root) - require.NoError(t, err) - assert.Equal(t, "5s", ref.RequestTimeout) - assert.Equal(t, "5s", ref.getURLMap().Get(constant.TimeoutKey)) -} diff --git a/config/registry_config.go b/config/registry_config.go deleted file mode 100644 index 0c1d93134d..0000000000 --- a/config/registry_config.go +++ /dev/null @@ -1,491 +0,0 @@ -/* - * 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 ( - "net/url" - "strconv" - "strings" -) - -import ( - "github.com/creasty/defaults" - - "github.com/dubbogo/gost/log/logger" - - perrors "github.com/pkg/errors" -) - -import ( - "dubbo.apache.org/dubbo-go/v3/common" - "dubbo.apache.org/dubbo-go/v3/common/constant" - "dubbo.apache.org/dubbo-go/v3/common/extension" - "dubbo.apache.org/dubbo-go/v3/registry" -) - -// RegistryConfig is the configuration of the registry center -type RegistryConfig struct { - Protocol string `validate:"required" yaml:"protocol" json:"protocol,omitempty" property:"protocol"` - Timeout string `default:"5s" validate:"required" yaml:"timeout" json:"timeout,omitempty" property:"timeout"` // unit: second - Group string `yaml:"group" json:"group,omitempty" property:"group"` - Namespace string `yaml:"namespace" json:"namespace,omitempty" property:"namespace"` - TTL string `default:"15m" yaml:"ttl" json:"ttl,omitempty" property:"ttl"` // unit: minute - Address string `validate:"required" yaml:"address" json:"address,omitempty" property:"address"` - Username string `yaml:"username" json:"username,omitempty" property:"username"` - Password string `yaml:"password" json:"password,omitempty" property:"password"` - Simplified bool `yaml:"simplified" json:"simplified,omitempty" property:"simplified"` - Preferred bool `yaml:"preferred" json:"preferred,omitempty" property:"preferred"` // Always use this registry first if set to true, useful when subscribe to multiple registriesConfig - Zone string `yaml:"zone" json:"zone,omitempty" property:"zone"` // The region where the registry belongs, usually used to isolate traffics - Weight int64 `yaml:"weight" json:"weight,omitempty" property:"weight"` // Affects traffic distribution among registriesConfig, useful when subscribe to multiple registriesConfig Take effect only when no preferred registry is specified. - Params map[string]string `yaml:"params" json:"params,omitempty" property:"params"` - RegistryType string `yaml:"registry-type"` - UseAsMetaReport string `default:"true" yaml:"use-as-meta-report" json:"use-as-meta-report,omitempty" property:"use-as-meta-report"` - UseAsConfigCenter string `yaml:"use-as-config-center" json:"use-as-config-center,omitempty" property:"use-as-config-center"` -} - -// Prefix dubbo.registries -func (RegistryConfig) Prefix() string { - return constant.RegistryConfigPrefix -} - -func (c *RegistryConfig) Init() error { - if err := defaults.Set(c); err != nil { - return err - } - return c.startRegistryConfig() -} - -func (c *RegistryConfig) getUrlMap(roleType common.RoleType) url.Values { - urlMap := url.Values{} - urlMap.Set(constant.RegistryGroupKey, c.Group) - urlMap.Set(constant.RegistryRoleKey, strconv.Itoa(int(roleType))) - urlMap.Set(constant.RegistryKey, c.Protocol) - urlMap.Set(constant.RegistryTimeoutKey, c.Timeout) - // multi registry invoker weight label for load balance - urlMap.Set(constant.RegistryKey+"."+constant.RegistryLabelKey, strconv.FormatBool(true)) - urlMap.Set(constant.RegistryKey+"."+constant.PreferredKey, strconv.FormatBool(c.Preferred)) - urlMap.Set(constant.RegistryKey+"."+constant.RegistryZoneKey, c.Zone) - urlMap.Set(constant.RegistryKey+"."+constant.WeightKey, strconv.FormatInt(c.Weight, 10)) - urlMap.Set(constant.RegistryTTLKey, c.TTL) - urlMap.Set(constant.ClientNameKey, clientNameID(c, c.Protocol, c.Address)) - urlMap.Set(constant.RegistryTypeKey, c.RegistryType) - - for k, v := range c.Params { - urlMap.Set(k, v) - } - return urlMap -} - -func (c *RegistryConfig) startRegistryConfig() error { - c.translateRegistryAddress() - return verify(c) -} - -// toMetadataReportUrl translate the registry configuration to the metadata reporting url -func (c *RegistryConfig) toMetadataReportUrl() (*common.URL, error) { - res, err := common.NewURL(c.Address, - common.WithLocation(c.Address), - common.WithProtocol(c.Protocol), - common.WithUsername(c.Username), - common.WithPassword(c.Password), - common.WithParamsValue(constant.TimeoutKey, c.Timeout), - common.WithParamsValue(constant.ClientNameKey, clientNameID(c, c.Protocol, c.Address)), - common.WithParamsValue(constant.MetadataReportGroupKey, c.Group), - common.WithParamsValue(constant.MetadataReportNamespaceKey, c.Namespace), - ) - if err != nil || len(res.Protocol) == 0 { - return nil, perrors.New("Invalid Registry Config.") - } - return res, nil -} - -// translateRegistryAddress translate registry address -// -// eg:address=nacos://127.0.0.1:8848 will return 127.0.0.1:8848 and protocol will set nacos -func (c *RegistryConfig) translateRegistryAddress() string { - if strings.Contains(c.Address, "://") { - u, err := url.Parse(c.Address) - if err != nil { - logger.Errorf("The registry url is invalid, error: %#v", err) - panic(err) - } - c.Protocol = u.Scheme - c.Address = strings.Join([]string{u.Host, u.Path}, "") - } - return c.Address -} - -func (c *RegistryConfig) GetInstance(roleType common.RoleType) (registry.Registry, error) { - u, err := c.toURL(roleType) - if err != nil { - return nil, err - } - // if the protocol == registry, set protocol the registry value in url.params - if u.Protocol == constant.RegistryProtocol { - u.Protocol = u.GetParam(constant.RegistryKey, "") - } - return extension.GetRegistry(u.Protocol, u) -} - -func (c *RegistryConfig) toURL(roleType common.RoleType) (*common.URL, error) { - address := c.translateRegistryAddress() - var registryURLProtocol string - - switch c.RegistryType { - case constant.RegistryTypeService: - // service discovery protocol - registryURLProtocol = constant.ServiceRegistryProtocol - case constant.RegistryTypeInterface: - registryURLProtocol = constant.RegistryProtocol - default: - registryURLProtocol = constant.ServiceRegistryProtocol - } - return common.NewURL(registryURLProtocol+"://"+address, - common.WithParams(c.getUrlMap(roleType)), - common.WithParamsValue(constant.RegistrySimplifiedKey, strconv.FormatBool(c.Simplified)), - common.WithParamsValue(constant.RegistryKey, c.Protocol), - common.WithParamsValue(constant.RegistryNamespaceKey, c.Namespace), - common.WithParamsValue(constant.RegistryTimeoutKey, c.Timeout), - common.WithUsername(c.Username), - common.WithPassword(c.Password), - common.WithLocation(c.Address), - ) -} - -func (c *RegistryConfig) toURLs(roleType common.RoleType) ([]*common.URL, error) { - address := c.translateRegistryAddress() - var urls []*common.URL - var err error - var registryURL *common.URL - - if !isValid(c.Address) { - logger.Infof("Empty or N/A registry address found, the process will work with no registry enabled " + - "which means that the address of this instance will not be registered and not able to be found by other consumer instances.") - return urls, nil - } - switch c.RegistryType { - case constant.RegistryTypeService: - // service discovery protocol - if registryURL, err = c.createNewURL(constant.ServiceRegistryProtocol, address, roleType); err == nil { - urls = append(urls, registryURL) - } - case constant.RegistryTypeInterface: - if registryURL, err = c.createNewURL(constant.RegistryProtocol, address, roleType); err == nil { - urls = append(urls, registryURL) - } - case constant.RegistryTypeAll: - if registryURL, err = c.createNewURL(constant.ServiceRegistryProtocol, address, roleType); err == nil { - urls = append(urls, registryURL) - } - if registryURL, err = c.createNewURL(constant.RegistryProtocol, address, roleType); err == nil { - urls = append(urls, registryURL) - } - default: - if registryURL, err = c.createNewURL(constant.ServiceRegistryProtocol, address, roleType); err == nil { - urls = append(urls, registryURL) - } - } - return urls, err -} - -func LoadRegistries(registryIds []string, registries map[string]*RegistryConfig, roleType common.RoleType) []*common.URL { - var registryURLs []*common.URL - //trSlice := strings.Split(targetRegistries, ",") - - for k, registryConf := range registries { - target := false - - // if user not config targetRegistries, default load all - // Notice: in func "func Split(s, sep string) []string" comment: - // if s does not contain sep and sep is not empty, SplitAfter returns - // a slice of length 1 whose only element is s. So we have to add the - // condition when targetRegistries string is not set (it will be "" when not set) - if len(registryIds) == 0 || (len(registryIds) == 1 && registryIds[0] == "") { - target = true - } else { - // else if user config targetRegistries - for _, tr := range registryIds { - if tr == k { - target = true - break - } - } - } - - if target { - if urls, err := registryConf.toURLs(roleType); err != nil { - logger.Errorf("The registry id: %s url is invalid, error: %#v", k, err) - panic(err) - } else { - for _, u := range urls { - u.SetParam(constant.RegistryIdKey, k) - } - registryURLs = append(registryURLs, urls...) - } - } - } - - return registryURLs -} - -func (c *RegistryConfig) createNewURL(protocol string, address string, roleType common.RoleType) (*common.URL, error) { - return common.NewURL(protocol+"://"+address, - common.WithParams(c.getUrlMap(roleType)), - common.WithParamsValue(constant.RegistrySimplifiedKey, strconv.FormatBool(c.Simplified)), - common.WithParamsValue(constant.RegistryKey, c.Protocol), - common.WithParamsValue(constant.RegistryNamespaceKey, c.Namespace), - common.WithParamsValue(constant.RegistryTimeoutKey, c.Timeout), - common.WithUsername(c.Username), - common.WithPassword(c.Password), - common.WithLocation(c.Address), - ) -} - -const ( - defaultZKAddr = "127.0.0.1:2181" // default registry address of zookeeper - defaultNacosAddr = "127.0.0.1:8848" // the default registry address of nacos - defaultRegistryTimeout = "3s" // the default registry timeout -) - -type RegistryConfigOpt func(config *RegistryConfig) *RegistryConfig - -// NewRegistryConfigWithProtocolDefaultPort New default registry config -// the input @protocol can only be: -// "zookeeper" with default addr "127.0.0.1:2181" -// "nacos" with default addr "127.0.0.1:8848" -func NewRegistryConfigWithProtocolDefaultPort(protocol string) *RegistryConfig { - switch protocol { - case "zookeeper": - return &RegistryConfig{ - Protocol: protocol, - Address: defaultZKAddr, - Timeout: defaultRegistryTimeout, - } - case "nacos": - return &RegistryConfig{ - Protocol: protocol, - Address: defaultNacosAddr, - Timeout: defaultRegistryTimeout, - } - default: - return &RegistryConfig{ - Protocol: protocol, - } - } -} - -// NewRegistryConfig creates New RegistryConfig with @opts -func NewRegistryConfig(opts ...RegistryConfigOpt) *RegistryConfig { - newRegistryConfig := NewRegistryConfigWithProtocolDefaultPort("") - for _, v := range opts { - newRegistryConfig = v(newRegistryConfig) - } - return newRegistryConfig -} - -// WithRegistryProtocol returns RegistryConfigOpt with given @regProtocol name -func WithRegistryProtocol(regProtocol string) RegistryConfigOpt { - return func(config *RegistryConfig) *RegistryConfig { - config.Protocol = regProtocol - return config - } -} - -// WithRegistryAddress returns RegistryConfigOpt with given @addr registry address -func WithRegistryAddress(addr string) RegistryConfigOpt { - return func(config *RegistryConfig) *RegistryConfig { - config.Address = addr - return config - } -} - -// WithRegistryTimeOut returns RegistryConfigOpt with given @timeout registry config -func WithRegistryTimeOut(timeout string) RegistryConfigOpt { - return func(config *RegistryConfig) *RegistryConfig { - config.Timeout = timeout - return config - } -} - -// WithRegistryGroup returns RegistryConfigOpt with given @group registry group -func WithRegistryGroup(group string) RegistryConfigOpt { - return func(config *RegistryConfig) *RegistryConfig { - config.Group = group - return config - } -} - -// WithRegistryTTL returns RegistryConfigOpt with given @ttl registry ttl -func WithRegistryTTL(ttl string) RegistryConfigOpt { - return func(config *RegistryConfig) *RegistryConfig { - config.TTL = ttl - return config - } -} - -// WithRegistryUserName returns RegistryConfigOpt with given @userName registry userName -func WithRegistryUserName(userName string) RegistryConfigOpt { - return func(config *RegistryConfig) *RegistryConfig { - config.Username = userName - return config - } -} - -// WithRegistryPassword returns RegistryConfigOpt with given @psw registry password -func WithRegistryPassword(psw string) RegistryConfigOpt { - return func(config *RegistryConfig) *RegistryConfig { - config.Password = psw - return config - } -} - -// WithRegistrySimplified returns RegistryConfigOpt with given @simplified registry simplified flag -func WithRegistrySimplified(simplified bool) RegistryConfigOpt { - return func(config *RegistryConfig) *RegistryConfig { - config.Simplified = simplified - return config - } -} - -// WithRegistryPreferred returns RegistryConfig with given @preferred registry preferred flag -func WithRegistryPreferred(preferred bool) RegistryConfigOpt { - return func(config *RegistryConfig) *RegistryConfig { - config.Preferred = preferred - return config - } -} - -// WithRegistryWeight returns RegistryConfigOpt with given @weight registry weight flag -func WithRegistryWeight(weight int64) RegistryConfigOpt { - return func(config *RegistryConfig) *RegistryConfig { - config.Weight = weight - return config - } -} - -// WithRegistryParams returns RegistryConfigOpt with given registry @params -func WithRegistryParams(params map[string]string) RegistryConfigOpt { - return func(config *RegistryConfig) *RegistryConfig { - config.Params = params - return config - } -} - -func NewRegistryConfigBuilder() *RegistryConfigBuilder { - return &RegistryConfigBuilder{ - registryConfig: &RegistryConfig{}, - } -} - -type RegistryConfigBuilder struct { - registryConfig *RegistryConfig -} - -func (rcb *RegistryConfigBuilder) SetProtocol(protocol string) *RegistryConfigBuilder { - rcb.registryConfig.Protocol = protocol - return rcb -} - -func (rcb *RegistryConfigBuilder) SetTimeout(timeout string) *RegistryConfigBuilder { - rcb.registryConfig.Timeout = timeout - return rcb -} - -func (rcb *RegistryConfigBuilder) SetGroup(group string) *RegistryConfigBuilder { - rcb.registryConfig.Group = group - return rcb -} - -func (rcb *RegistryConfigBuilder) SetNamespace(namespace string) *RegistryConfigBuilder { - rcb.registryConfig.Namespace = namespace - return rcb -} - -func (rcb *RegistryConfigBuilder) SetTTL(ttl string) *RegistryConfigBuilder { - rcb.registryConfig.TTL = ttl - return rcb -} - -func (rcb *RegistryConfigBuilder) SetAddress(address string) *RegistryConfigBuilder { - rcb.registryConfig.Address = address - return rcb -} - -func (rcb *RegistryConfigBuilder) SetUsername(username string) *RegistryConfigBuilder { - rcb.registryConfig.Username = username - return rcb -} - -func (rcb *RegistryConfigBuilder) SetPassword(password string) *RegistryConfigBuilder { - rcb.registryConfig.Password = password - return rcb -} - -func (rcb *RegistryConfigBuilder) SetSimplified(simplified bool) *RegistryConfigBuilder { - rcb.registryConfig.Simplified = simplified - return rcb -} - -func (rcb *RegistryConfigBuilder) SetPreferred(preferred bool) *RegistryConfigBuilder { - rcb.registryConfig.Preferred = preferred - return rcb -} - -func (rcb *RegistryConfigBuilder) SetZone(zone string) *RegistryConfigBuilder { - rcb.registryConfig.Zone = zone - return rcb -} - -func (rcb *RegistryConfigBuilder) SetWeight(weight int64) *RegistryConfigBuilder { - rcb.registryConfig.Weight = weight - return rcb -} - -func (rcb *RegistryConfigBuilder) SetParams(params map[string]string) *RegistryConfigBuilder { - rcb.registryConfig.Params = params - return rcb -} - -func (rcb *RegistryConfigBuilder) AddParam(key, value string) *RegistryConfigBuilder { - if rcb.registryConfig.Params == nil { - rcb.registryConfig.Params = make(map[string]string) - } - rcb.registryConfig.Params[key] = value - return rcb -} - -func (rcb *RegistryConfigBuilder) SetRegistryType(registryType string) *RegistryConfigBuilder { - rcb.registryConfig.RegistryType = registryType - return rcb -} - -func (rcb *RegistryConfigBuilder) Build() *RegistryConfig { - if err := rcb.registryConfig.Init(); err != nil { - panic(err) - } - return rcb.registryConfig -} - -// DynamicUpdateProperties update registry -func (c *RegistryConfig) DynamicUpdateProperties(updateRegistryConfig *RegistryConfig) { - // if nacos's registry timeout not equal local root config's registry timeout , update. - if updateRegistryConfig != nil && updateRegistryConfig.Timeout != c.Timeout { - c.Timeout = updateRegistryConfig.Timeout - logger.Infof("RegistryConfigs Timeout was dynamically updated, new value:%v", c.Timeout) - } -} diff --git a/config/registry_config_test.go b/config/registry_config_test.go deleted file mode 100644 index 011e081019..0000000000 --- a/config/registry_config_test.go +++ /dev/null @@ -1,150 +0,0 @@ -/* - * 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/stretchr/testify/assert" - "github.com/stretchr/testify/require" -) - -import ( - "dubbo.apache.org/dubbo-go/v3/common" - "dubbo.apache.org/dubbo-go/v3/common/constant" -) - -func TestLoadRegistries(t *testing.T) { - target := []string{"shanghai1"} - regs := map[string]*RegistryConfig{ - - "shanghai1": { - Protocol: "mock", - Timeout: "2s", - Group: "shanghai_idc", - Address: "127.0.0.2:2181,128.0.0.1:2181", - Username: "user1", - Password: "pwd1", - }, - } - urls := LoadRegistries(target, regs, common.CONSUMER) - t.Logf("LoadRegistries() = urls:%v", urls) - assert.Equal(t, "127.0.0.2:2181,128.0.0.1:2181", urls[0].Location) - assert.Equal(t, "service-discovery-registry://127.0.0.2:2181,128.0.0.1:2181/shanghai_idc", urls[0].PrimitiveURL) -} - -func TestLoadRegistries1(t *testing.T) { - target := []string{"shanghai1"} - regs := map[string]*RegistryConfig{ - - "shanghai1": { - Protocol: "mock", - Timeout: "2s", - Group: "shanghai_idc", - Address: "127.0.0.2:2181", - Username: "user1", - Password: "pwd1", - }, - } - urls := LoadRegistries(target, regs, common.CONSUMER) - t.Logf("LoadRegistries() = urls:%v", urls) - assert.Equal(t, "127.0.0.2:2181", urls[0].Location) - assert.Equal(t, "service-discovery-registry://127.0.0.2:2181/shanghai_idc", urls[0].PrimitiveURL) -} - -func TestRegistryTypeAll(t *testing.T) { - target := []string{"test"} - regs := map[string]*RegistryConfig{ - "test": { - Protocol: "mock", - Address: "127.0.0.2:2181", - RegistryType: constant.RegistryTypeAll, - }, - } - urls := LoadRegistries(target, regs, common.PROVIDER) - assert.Len(t, urls, 2) - assert.Equal(t, "service-discovery-registry://127.0.0.2:2181", urls[0].PrimitiveURL) -} - -func TestTranslateRegistryAddress(t *testing.T) { - reg := new(RegistryConfig) - reg.Address = "nacos://127.0.0.1:8848" - - reg.translateRegistryAddress() - - assert.Equal(t, "nacos", reg.Protocol) - assert.Equal(t, "127.0.0.1:8848", reg.Address) -} - -func TestNewRegistryConfigBuilder(t *testing.T) { - - config := NewRegistryConfigBuilder(). - SetProtocol("nacos"). - SetTimeout("10s"). - SetGroup("group"). - SetNamespace("public"). - SetTTL("10s"). - SetAddress("127.0.0.1:8848"). - SetUsername("nacos"). - SetPassword("123456"). - SetSimplified(true). - SetPreferred(true). - SetZone("zone"). - SetWeight(100). - SetParams(map[string]string{"timeout": "3s"}). - AddParam("timeout", "15s"). - SetRegistryType("local"). - Build() - - config.DynamicUpdateProperties(config) - - assert.Equal(t, constant.RegistryConfigPrefix, config.Prefix()) - - values := config.getUrlMap(common.PROVIDER) - assert.Equal(t, "15s", values.Get("timeout")) - - url, err := config.toMetadataReportUrl() - require.NoError(t, err) - assert.Equal(t, "10s", url.GetParam("timeout", "3s")) - - url, err = config.toURL(common.PROVIDER) - require.NoError(t, err) - assert.Equal(t, "15s", url.GetParam("timeout", "3s")) - - address := config.translateRegistryAddress() - assert.Equal(t, "127.0.0.1:8848", address) -} - -func TestNewRegistryConfig(t *testing.T) { - config := NewRegistryConfig( - WithRegistryProtocol("nacos"), - WithRegistryAddress("127.0.0.1:8848"), - WithRegistryTimeOut("10s"), - WithRegistryGroup("group"), - WithRegistryTTL("10s"), - WithRegistryUserName("nacos"), - WithRegistryPassword("123456"), - WithRegistrySimplified(true), - WithRegistryPreferred(true), - WithRegistryWeight(100), - WithRegistryParams(map[string]string{"timeout": "3s"})) - - assert.Equal(t, "10s", config.Timeout) -} diff --git a/config/remote_config.go b/config/remote_config.go deleted file mode 100644 index 7af5c10401..0000000000 --- a/config/remote_config.go +++ /dev/null @@ -1,154 +0,0 @@ -/* - * 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 ( - "net/url" - "time" -) - -import ( - perrors "github.com/pkg/errors" -) - -import ( - "dubbo.apache.org/dubbo-go/v3/common" - "dubbo.apache.org/dubbo-go/v3/common/constant" -) - -// RemoteConfig usually we need some middleware, including nacos, zookeeper -// this represents an instance of this middleware -// so that other module, like config center, registry could reuse the config -// but now, only metadata report, metadata service, service discovery use this structure -type RemoteConfig struct { - Protocol string `yaml:"protocol" json:"protocol,omitempty" property:"protocol"` - Address string `yaml:"address" json:"address,omitempty" property:"address"` - Timeout string `default:"5s" yaml:"timeout" json:"timeout,omitempty" property:"timeout"` - Username string `yaml:"username" json:"username,omitempty" property:"username"` - Password string `yaml:"password" json:"password,omitempty" property:"password"` - Params map[string]string `yaml:"params" json:"params,omitempty"` -} - -// Prefix dubbo.remote. -func (rc *RemoteConfig) Prefix() string { - return constant.RemotePrefix -} - -func (rc *RemoteConfig) Init() error { - return nil -} - -// GetTimeout return timeout duration. -// if the configure is invalid, or missing, the default value 5s will be returned -func (rc *RemoteConfig) GetTimeout() time.Duration { - if res, err := time.ParseDuration(rc.Timeout); err == nil { - return res - } - return 5 * time.Second -} - -// GetParam will return the value of the key. If not found, def will be return; -// def => default value -func (rc *RemoteConfig) GetParam(key string, def string) string { - param, ok := rc.Params[key] - if !ok { - return def - } - return param -} - -// ToURL config to url -func (rc *RemoteConfig) ToURL() (*common.URL, error) { - if len(rc.Protocol) == 0 { - return nil, perrors.Errorf("Must provide protocol in RemoteConfig.") - } - return common.NewURL(rc.Address, - common.WithProtocol(rc.Protocol), - common.WithUsername(rc.Username), - common.WithPassword(rc.Password), - common.WithLocation(rc.Address), - common.WithParams(rc.getUrlMap()), - ) -} - -// getUrlMap get url map -func (rc *RemoteConfig) getUrlMap() url.Values { - urlMap := url.Values{} - urlMap.Set(constant.ConfigUsernameKey, rc.Username) - urlMap.Set(constant.ConfigPasswordKey, rc.Password) - urlMap.Set(constant.ConfigTimeoutKey, rc.Timeout) - urlMap.Set(constant.ClientNameKey, clientNameID(rc, rc.Protocol, rc.Protocol)) - - for key, val := range rc.Params { - urlMap.Set(key, val) - } - return urlMap -} - -func NewRemoteConfigBuilder() *RemoteConfigBuilder { - return &RemoteConfigBuilder{remoteConfig: &RemoteConfig{}} -} - -type RemoteConfigBuilder struct { - remoteConfig *RemoteConfig -} - -func (rcb *RemoteConfigBuilder) SetProtocol(protocol string) *RemoteConfigBuilder { - rcb.remoteConfig.Protocol = protocol - return rcb -} - -func (rcb *RemoteConfigBuilder) SetAddress(address string) *RemoteConfigBuilder { - rcb.remoteConfig.Address = address - return rcb -} - -func (rcb *RemoteConfigBuilder) SetTimeout(timeout string) *RemoteConfigBuilder { - rcb.remoteConfig.Timeout = timeout - return rcb -} - -func (rcb *RemoteConfigBuilder) SetUsername(username string) *RemoteConfigBuilder { - rcb.remoteConfig.Username = username - return rcb -} - -func (rcb *RemoteConfigBuilder) SetPassword(password string) *RemoteConfigBuilder { - rcb.remoteConfig.Password = password - return rcb -} - -func (rcb *RemoteConfigBuilder) SetParams(params map[string]string) *RemoteConfigBuilder { - rcb.remoteConfig.Params = params - return rcb -} - -func (rcb *RemoteConfigBuilder) AddParam(key, value string) *RemoteConfigBuilder { - if rcb.remoteConfig.Params == nil { - rcb.remoteConfig.Params = make(map[string]string) - } - rcb.remoteConfig.Params[key] = value - return rcb -} - -func (rcb *RemoteConfigBuilder) Build() *RemoteConfig { - if err := rcb.remoteConfig.Init(); err != nil { - panic(err) - } - return rcb.remoteConfig -} diff --git a/config/remote_config_test.go b/config/remote_config_test.go deleted file mode 100644 index f9433e063b..0000000000 --- a/config/remote_config_test.go +++ /dev/null @@ -1,78 +0,0 @@ -/* - * 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" - "time" -) - -import ( - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" -) - -import ( - "dubbo.apache.org/dubbo-go/v3/common/constant" -) - -func TestRemoteConfig_GetParam(t *testing.T) { - rc := &RemoteConfig{ - Params: make(map[string]string, 1), - } - - def := "default value" - key := "key" - value := rc.GetParam(key, def) - assert.Equal(t, def, value) - - actualVal := "actual value" - rc.Params[key] = actualVal - - value = rc.GetParam(key, def) - assert.Equal(t, actualVal, value) -} - -func TestNewRemoteConfigBuilder(t *testing.T) { - config := NewRemoteConfigBuilder(). - SetProtocol("nacos"). - SetAddress("127.0.0.1:8848"). - SetTimeout("10s"). - SetUsername("nacos"). - SetPassword("nacos"). - SetParams(map[string]string{"timeout": "3s"}). - AddParam("timeout", "15s"). - Build() - - values := config.getUrlMap() - assert.Equal(t, "15s", values.Get("timeout")) - - url, err := config.ToURL() - require.NoError(t, err) - assert.Equal(t, "15s", url.GetParam("timeout", "3s")) - - err = config.Init() - require.NoError(t, err) - - timeout := config.GetTimeout() - assert.Equal(t, 10*time.Second, timeout) - assert.Equal(t, constant.RemotePrefix, config.Prefix()) - - param := config.GetParam("timeout", "3s") - assert.Equal(t, "15s", param) -} diff --git a/config/root_config.go b/config/root_config.go deleted file mode 100644 index 409f2cece0..0000000000 --- a/config/root_config.go +++ /dev/null @@ -1,429 +0,0 @@ -/* - * 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 ( - "fmt" - "sync" -) - -import ( - hessian "github.com/apache/dubbo-go-hessian2" - - "github.com/dubbogo/gost/log/logger" - - "github.com/knadh/koanf" -) - -import ( - "dubbo.apache.org/dubbo-go/v3/common" - "dubbo.apache.org/dubbo-go/v3/common/constant" - "dubbo.apache.org/dubbo-go/v3/config_center" - "dubbo.apache.org/dubbo-go/v3/registry/exposed_tmp" -) - -var ( - startOnce sync.Once -) - -// RootConfig is the root config -type RootConfig struct { - Application *ApplicationConfig `validate:"required" yaml:"application" json:"application,omitempty" property:"application"` - Protocols map[string]*ProtocolConfig `validate:"required" yaml:"protocols" json:"protocols" property:"protocols"` - Registries map[string]*RegistryConfig `yaml:"registries" json:"registries" property:"registries"` - ConfigCenter *CenterConfig `yaml:"config-center" json:"config-center,omitempty"` - MetadataReport *MetadataReportConfig `yaml:"metadata-report" json:"metadata-report,omitempty" property:"metadata-report"` - Provider *ProviderConfig `yaml:"provider" json:"provider" property:"provider"` - Consumer *ConsumerConfig `yaml:"consumer" json:"consumer" property:"consumer"` - Otel *OtelConfig `yaml:"otel" json:"otel,omitempty" property:"otel"` - Metrics *MetricsConfig `yaml:"metrics" json:"metrics,omitempty" property:"metrics"` - Tracing map[string]*TracingConfig `yaml:"tracing" json:"tracing,omitempty" property:"tracing"` - Logger *LoggerConfig `yaml:"logger" json:"logger,omitempty" property:"logger"` - Shutdown *ShutdownConfig `yaml:"shutdown" json:"shutdown,omitempty" property:"shutdown"` - Router []*RouterConfig `yaml:"router" json:"router,omitempty" property:"router"` - EventDispatcherType string `default:"direct" yaml:"event-dispatcher-type" json:"event-dispatcher-type,omitempty"` - CacheFile string `yaml:"cache_file" json:"cache_file,omitempty" property:"cache_file"` - Custom *CustomConfig `yaml:"custom" json:"custom,omitempty" property:"custom"` - Profiles *ProfilesConfig `yaml:"profiles" json:"profiles,omitempty" property:"profiles"` - TLSConfig *TLSConfig `yaml:"tls_config" json:"tls_config,omitempty" property:"tls_config"` -} - -func SetRootConfig(r RootConfig) { - rc := r - setRootConfigInternal(&rc) -} - -// Prefix dubbo -func (rc *RootConfig) Prefix() string { - return constant.DubboProtocol -} - -func GetRootConfig() *RootConfig { - return rootConfigStore.Load() -} - -func GetProviderConfig() *ProviderConfig { - rc := GetRootConfig() - if err := check(); err == nil && rc.Provider != nil { - return rc.Provider - } - return NewProviderConfigBuilder().Build() -} - -func GetConsumerConfig() *ConsumerConfig { - rc := GetRootConfig() - if err := check(); err == nil && rc.Consumer != nil { - return rc.Consumer - } - return NewConsumerConfigBuilder().Build() -} - -func GetApplicationConfig() *ApplicationConfig { - return GetRootConfig().Application -} - -func GetShutDown() *ShutdownConfig { - rc := GetRootConfig() - if err := check(); err == nil && rc.Shutdown != nil { - return rc.Shutdown - } - return NewShutDownConfigBuilder().Build() -} - -func GetTLSConfig() *TLSConfig { - rc := GetRootConfig() - if err := check(); err == nil && rc.TLSConfig != nil { - return rc.TLSConfig - } - return NewTLSConfigBuilder().Build() -} - -// getRegistryIds get registry ids -func (rc *RootConfig) getRegistryIds() []string { - ids := make([]string, 0) - for key := range rc.Registries { - ids = append(ids, key) - } - return removeDuplicateElement(ids) -} -func registerPOJO() { - hessian.RegisterPOJO(&common.URL{}) -} - -// Init is to start dubbo-go framework, load local configuration, or read configuration from config-center if necessary. -// It's deprecated for user to call rootConfig.Init() manually, try config.Load(config.WithRootConfig(rootConfig)) instead. -func (rc *RootConfig) Init() error { - registerPOJO() - if err := rc.Logger.Init(); err != nil { // init default logger - return err - } - if err := rc.ConfigCenter.Init(rc); err != nil { - logger.Infof("[Config Center] Config center doesn't start") - logger.Debugf("config center doesn't start because %s", err) - } else { - if err = rc.Logger.Init(); err != nil { // init logger using config from config center again - return err - } - } - if err := rc.Application.Init(); err != nil { - return err - } - - // init user define - if err := rc.Custom.Init(); err != nil { - return err - } - - // init protocol - protocols := rc.Protocols - if len(protocols) <= 0 { - protocol := ProtocolConfig{} - protocols = make(map[string]*ProtocolConfig, 1) - // todo, default value should be determined in a unified way - protocols["tri"] = &protocol - rc.Protocols = protocols - } - for _, protocol := range protocols { - if err := protocol.Init(); err != nil { - return err - } - } - - // init registry - for _, reg := range rc.Registries { - if err := reg.Init(); err != nil { - return err - } - } - - // TODO:When config is migrated later, the impact of this will be migrated to the global module - if err := validateRegistryAddresses(rc.Registries); err != nil { - return err - } - - if err := rc.MetadataReport.Init(rc); err != nil { - return err - } - - if err := rc.Otel.Init(rc.Application); err != nil { - return err - } - if err := rc.Metrics.Init(rc); err != nil { - return err - } - for _, t := range rc.Tracing { - if err := t.Init(); err != nil { - return err - } - } - if err := initRouterConfig(rc); err != nil { - return err - } - - // provider、consumer must last init - if err := rc.Provider.Init(rc); err != nil { - return err - } - if err := rc.Consumer.Init(rc); err != nil { - return err - } - if err := rc.Shutdown.Init(); err != nil { - return err - } - SetRootConfig(*rc) - // todo if we can remove this from Init in the future? - rc.Start() - return nil -} - -func (rc *RootConfig) Start() { - startOnce.Do(func() { - gracefulShutdownInit() - - rc.Consumer.Load() - rc.Provider.Load() - if err := initMetadata(rc); err != nil { - panic(err) - } - if err := exposed_tmp.RegisterServiceInstance(); err != nil { - panic(err) - } - }) -} - -// newEmptyRootConfig get empty root config -func newEmptyRootConfig() *RootConfig { - newRootConfig := &RootConfig{ - ConfigCenter: NewConfigCenterConfigBuilder().Build(), - MetadataReport: NewMetadataReportConfigBuilder().Build(), - Application: NewApplicationConfigBuilder().Build(), - Registries: make(map[string]*RegistryConfig), - Protocols: make(map[string]*ProtocolConfig), - Tracing: make(map[string]*TracingConfig), - Provider: NewProviderConfigBuilder().Build(), - Consumer: NewConsumerConfigBuilder().Build(), - Otel: NewOtelConfigBuilder().Build(), - Metrics: NewMetricConfigBuilder().Build(), - Logger: NewLoggerConfigBuilder().Build(), - Custom: NewCustomConfigBuilder().Build(), - Shutdown: NewShutDownConfigBuilder().Build(), - TLSConfig: NewTLSConfigBuilder().Build(), - } - return newRootConfig -} - -func NewRootConfigBuilder() *RootConfigBuilder { - return &RootConfigBuilder{rootConfig: newEmptyRootConfig()} -} - -type RootConfigBuilder struct { - rootConfig *RootConfig -} - -func (rb *RootConfigBuilder) SetApplication(application *ApplicationConfig) *RootConfigBuilder { - rb.rootConfig.Application = application - return rb -} - -func (rb *RootConfigBuilder) AddProtocol(protocolID string, protocolConfig *ProtocolConfig) *RootConfigBuilder { - rb.rootConfig.Protocols[protocolID] = protocolConfig - return rb -} - -func (rb *RootConfigBuilder) AddRegistry(registryID string, registryConfig *RegistryConfig) *RootConfigBuilder { - rb.rootConfig.Registries[registryID] = registryConfig - return rb -} - -func (rb *RootConfigBuilder) SetProtocols(protocols map[string]*ProtocolConfig) *RootConfigBuilder { - rb.rootConfig.Protocols = protocols - return rb -} - -func (rb *RootConfigBuilder) SetRegistries(registries map[string]*RegistryConfig) *RootConfigBuilder { - rb.rootConfig.Registries = registries - return rb -} - -func (rb *RootConfigBuilder) SetMetadataReport(metadataReport *MetadataReportConfig) *RootConfigBuilder { - rb.rootConfig.MetadataReport = metadataReport - return rb -} - -func (rb *RootConfigBuilder) SetProvider(provider *ProviderConfig) *RootConfigBuilder { - rb.rootConfig.Provider = provider - return rb -} - -func (rb *RootConfigBuilder) SetConsumer(consumer *ConsumerConfig) *RootConfigBuilder { - rb.rootConfig.Consumer = consumer - return rb -} - -func (rb *RootConfigBuilder) SetOtel(otel *OtelConfig) *RootConfigBuilder { - rb.rootConfig.Otel = otel - return rb -} - -func (rb *RootConfigBuilder) SetMetric(metric *MetricsConfig) *RootConfigBuilder { - rb.rootConfig.Metrics = metric - return rb -} - -func (rb *RootConfigBuilder) SetLogger(logger *LoggerConfig) *RootConfigBuilder { - rb.rootConfig.Logger = logger - return rb -} - -func (rb *RootConfigBuilder) SetShutdown(shutdown *ShutdownConfig) *RootConfigBuilder { - rb.rootConfig.Shutdown = shutdown - return rb -} - -func (rb *RootConfigBuilder) SetRouter(router []*RouterConfig) *RootConfigBuilder { - rb.rootConfig.Router = router - return rb -} - -func (rb *RootConfigBuilder) SetEventDispatcherType(eventDispatcherType string) *RootConfigBuilder { - rb.rootConfig.EventDispatcherType = eventDispatcherType - return rb -} - -func (rb *RootConfigBuilder) SetCacheFile(cacheFile string) *RootConfigBuilder { - rb.rootConfig.CacheFile = cacheFile - return rb -} - -func (rb *RootConfigBuilder) SetConfigCenter(configCenterConfig *CenterConfig) *RootConfigBuilder { - rb.rootConfig.ConfigCenter = configCenterConfig - return rb -} - -func (rb *RootConfigBuilder) SetCustom(customConfig *CustomConfig) *RootConfigBuilder { - rb.rootConfig.Custom = customConfig - return rb -} - -func (rb *RootConfigBuilder) SetShutDown(shutDownConfig *ShutdownConfig) *RootConfigBuilder { - rb.rootConfig.Shutdown = shutDownConfig - return rb -} - -func (rb *RootConfigBuilder) SetTLSConfig(tlsConfig *TLSConfig) *RootConfigBuilder { - rb.rootConfig.TLSConfig = tlsConfig - return rb -} - -func (rb *RootConfigBuilder) Build() *RootConfig { - return rb.rootConfig -} - -// Process receive changing listener's event, dynamic update config -func (rc *RootConfig) Process(event *config_center.ConfigChangeEvent) { - logger.Infof("CenterConfig process event:\n%+v", event) - config := NewLoaderConf(WithBytes([]byte(event.Value.(string)))) - koan := GetConfigResolver(config) - - updateRootConfig := &RootConfig{} - if err := koan.UnmarshalWithConf(rc.Prefix(), - updateRootConfig, koanf.UnmarshalConf{Tag: "yaml"}); err != nil { - logger.Errorf("CenterConfig process unmarshalConf failed, got error %#v", err) - return - } - nextRootConfig := cloneRootConfigForDynamicUpdate(rc) - // dynamically update register - for registerId, updateRegister := range updateRootConfig.Registries { - if register := nextRootConfig.Registries[registerId]; register != nil { - register.DynamicUpdateProperties(updateRegister) - } - } - // dynamically update consumer - if nextRootConfig.Consumer != nil { - nextRootConfig.Consumer.DynamicUpdateProperties(updateRootConfig.Consumer) - } - - setRootConfigInternal(nextRootConfig) -} - -func cloneRootConfigForDynamicUpdate(rc *RootConfig) *RootConfig { - next := *rc - if rc.Registries != nil { - next.Registries = make(map[string]*RegistryConfig, len(rc.Registries)) - for registryID, registryConfig := range rc.Registries { - if registryConfig == nil { - next.Registries[registryID] = nil - continue - } - registryCopy := *registryConfig - next.Registries[registryID] = ®istryCopy - } - } - - if rc.Consumer != nil { - consumerCopy := *rc.Consumer - next.Consumer = &consumerCopy - } - return &next -} - -// TODO:When config is migrated later, the impact of this will be migrated to the global module -// validateRegistryAddresses Checks whether there are duplicate registry addresses -func validateRegistryAddresses(registries map[string]*RegistryConfig) error { - cacheKeyMap := make(map[string]string, len(registries)) - - for id, reg := range registries { - address := reg.Address - namespace := reg.Namespace - - cacheKey := address - if namespace != "" { - cacheKey = cacheKey + "?" + constant.NacosNamespaceID + "=" + namespace - } - - if existingID, exists := cacheKeyMap[cacheKey]; exists { - err := fmt.Errorf("duplicate registry address: [%s] used by both [%s] and [%s]", cacheKey, existingID, id) - logger.Errorf("duplicate registry address: [%s] used by both [%s] and [%s]", cacheKey, existingID, id) - return err - } - - cacheKeyMap[cacheKey] = id - } - - return nil -} diff --git a/config/root_config_test.go b/config/root_config_test.go deleted file mode 100644 index 92415594da..0000000000 --- a/config/root_config_test.go +++ /dev/null @@ -1,142 +0,0 @@ -/* - * 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 ( - "fmt" - "sync" - "testing" -) - -import ( - "github.com/dubbogo/gost/encoding/yaml" - - "github.com/stretchr/testify/assert" -) - -import ( - "dubbo.apache.org/dubbo-go/v3/common/constant" - "dubbo.apache.org/dubbo-go/v3/config_center" -) - -func TestGoConfigProcess(t *testing.T) { - rc := &RootConfigBuilder{rootConfig: newEmptyRootConfig()} - r := &RegistryConfig{Protocol: "zookeeper", Timeout: "10s", Address: "127.0.0.1:2181"} - rc.AddRegistry("demoZK", r) - SetRootConfig(*rc.rootConfig) - - // test koan.UnmarshalWithConf error - b := "dubbo:\n registries:\n demoZK:\n protocol: zookeeper\n timeout: 11s\n address: 127.0.0.1:2181\n simplified: abc123" - c2 := &config_center.ConfigChangeEvent{Key: "test", Value: b} - GetRootConfig().Process(c2) - assert.Equal(t, "10s", GetRootConfig().Registries["demoZK"].Timeout) - - // test update registry time out - bs, _ := yaml.LoadYMLConfig("./testdata/root_config_test.yml") - c := &config_center.ConfigChangeEvent{Key: "test", Value: string(bs)} - GetRootConfig().Process(c) - assert.Equal(t, "11s", GetRootConfig().Registries["demoZK"].Timeout) - assert.Equal(t, "6s", GetRootConfig().Consumer.RequestTimeout) - -} - -func TestNewRootConfigBuilder(t *testing.T) { - registryConfig := NewRegistryConfigWithProtocolDefaultPort("nacos") - protocolConfig := NewProtocolConfigBuilder(). - SetName("dubbo"). - SetPort("20000"). - Build() - newConfig := NewRootConfigBuilder(). - SetConfigCenter(NewConfigCenterConfigBuilder().Build()). - SetMetadataReport(NewMetadataReportConfigBuilder().Build()). - AddProtocol("dubbo", protocolConfig). - AddRegistry("nacos", registryConfig). - SetProtocols(map[string]*ProtocolConfig{"dubbo": protocolConfig}). - SetRegistries(map[string]*RegistryConfig{"nacos": registryConfig}). - SetProvider(NewProviderConfigBuilder().Build()). - SetConsumer(NewConsumerConfigBuilder().Build()). - SetMetric(NewMetricConfigBuilder().Build()). - SetLogger(NewLoggerConfigBuilder().Build()). - SetShutdown(NewShutDownConfigBuilder().Build()). - SetShutDown(NewShutDownConfigBuilder().Build()). - SetRouter([]*RouterConfig{}). - SetEventDispatcherType("direct"). - SetCacheFile("abc=123"). - Build() - - SetRootConfig(*newConfig) - - assert.Equal(t, constant.Dubbo, newConfig.Prefix()) - ids := newConfig.getRegistryIds() - assert.Equal(t, "nacos", ids[0]) - - down := GetShutDown() - assert.NotNil(t, down) - - application := GetApplicationConfig() - assert.NotNil(t, application) - - registerPOJO() - config := GetRootConfig() - assert.Equal(t, newConfig, config) -} - -func TestRootConfigConcurrentSetAndGet(t *testing.T) { - SetRootConfig(*NewRootConfigBuilder().Build()) - - var wg sync.WaitGroup - for i := 0; i < 50; i++ { - wg.Add(2) - go func(idx int) { - defer wg.Done() - cfg := NewRootConfigBuilder().Build() - cfg.Application.Name = fmt.Sprintf("app-%d", idx) - SetRootConfig(*cfg) - }(i) - go func() { - defer wg.Done() - _ = GetRootConfig() - }() - } - wg.Wait() - finalCfg := GetRootConfig() - assert.NotNil(t, finalCfg) - assert.NotEmpty(t, finalCfg.Application.Name) -} - -func TestRootConfigProcessCopyOnWrite(t *testing.T) { - base := NewRootConfigBuilder().Build() - base.Registries["demoZK"] = &RegistryConfig{ - Protocol: "zookeeper", - Timeout: "10s", - Address: "127.0.0.1:2181", - } - base.Consumer.RequestTimeout = "3s" - SetRootConfig(*base) - - oldSnapshot := GetRootConfig() - eventValue := "dubbo:\n registries:\n demoZK:\n protocol: zookeeper\n timeout: 11s\n address: 127.0.0.1:2181\n consumer:\n request-timeout: 6s\n" - oldSnapshot.Process(&config_center.ConfigChangeEvent{Key: "test", Value: eventValue}) - - newSnapshot := GetRootConfig() - assert.NotSame(t, oldSnapshot, newSnapshot) - assert.Equal(t, "10s", oldSnapshot.Registries["demoZK"].Timeout) - assert.Equal(t, "3s", oldSnapshot.Consumer.RequestTimeout) - assert.Equal(t, "11s", newSnapshot.Registries["demoZK"].Timeout) - assert.Equal(t, "6s", newSnapshot.Consumer.RequestTimeout) -} diff --git a/config/router_config.go b/config/router_config.go deleted file mode 100644 index 7971fd58f6..0000000000 --- a/config/router_config.go +++ /dev/null @@ -1,214 +0,0 @@ -/* - * 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 ( - "reflect" -) - -import ( - "github.com/creasty/defaults" -) - -import ( - _ "dubbo.apache.org/dubbo-go/v3/cluster/router/chain" - "dubbo.apache.org/dubbo-go/v3/common" - "dubbo.apache.org/dubbo-go/v3/common/constant" - _ "dubbo.apache.org/dubbo-go/v3/metrics/prometheus" -) - -// RouterConfig is the configuration of the router. -type RouterConfig struct { - Scope string `validate:"required" yaml:"scope" json:"scope,omitempty" property:"scope"` // must be chosen from `service` and `application`. - Key string `validate:"required" yaml:"key" json:"key,omitempty" property:"key"` // specifies which service or application the rule body acts on. - Force *bool `default:"false" yaml:"force" json:"force,omitempty" property:"force"` - Runtime *bool `default:"false" yaml:"runtime" json:"runtime,omitempty" property:"runtime"` - Enabled *bool `default:"true" yaml:"enabled" json:"enabled,omitempty" property:"enabled"` - Valid *bool `default:"true" yaml:"valid" json:"valid,omitempty" property:"valid"` - Priority int `default:"0" yaml:"priority" json:"priority,omitempty" property:"priority"` - Conditions []string `yaml:"conditions" json:"conditions,omitempty" property:"conditions"` - Tags []Tag `yaml:"tags" json:"tags,omitempty" property:"tags"` - ScriptType string `yaml:"type" json:"type,omitempty" property:"type"` - Script string `yaml:"script" json:"script,omitempty" property:"script"` -} - -type Tag struct { - Name string `yaml:"name" json:"name,omitempty" property:"name"` - Match []*common.ParamMatch `yaml:"match" json:"match,omitempty" property:"match"` - Addresses []string `yaml:"addresses" json:"addresses,omitempty" property:"addresses"` -} - -type ConditionRule struct { - From ConditionRuleFrom `yaml:"from" json:"from,omitempty" property:"from"` - To []ConditionRuleTo `yaml:"to" json:"to,omitempty" property:"to"` -} - -type ConditionRuleFrom struct { - Match string `yaml:"match" json:"match,omitempty" property:"match"` -} - -type ConditionRuleTo struct { - Match string `yaml:"match" json:"match,omitempty" property:"match"` - Weight int `default:"100" yaml:"weight" json:"weight,omitempty" property:"weight"` -} - -type ConditionRuleDisable struct { - Match string `yaml:"match" json:"match,omitempty" property:"match"` -} - -type AffinityAware struct { - Key string `default:"" yaml:"key" json:"key,omitempty" property:"key"` - Ratio int32 `default:"0" yaml:"ratio" json:"ratio,omitempty" property:"ratio"` -} - -// ConditionRouter -- when RouteConfigVersion == v3.1, decode by this -type ConditionRouter struct { - Scope string `validate:"required" yaml:"scope" json:"scope,omitempty" property:"scope"` // must be chosen from `service` and `application`. - Key string `validate:"required" yaml:"key" json:"key,omitempty" property:"key"` // specifies which service or application the rule body acts on. - Force bool `default:"false" yaml:"force" json:"force,omitempty" property:"force"` - Runtime bool `default:"false" yaml:"runtime" json:"runtime,omitempty" property:"runtime"` - Enabled bool `default:"true" yaml:"enabled" json:"enabled,omitempty" property:"enabled"` - Conditions []*ConditionRule `yaml:"conditions" json:"conditions,omitempty" property:"conditions"` -} - -// AffinityRouter -- RouteConfigVersion == v3.1 -type AffinityRouter struct { - Scope string `validate:"required" yaml:"scope" json:"scope,omitempty" property:"scope"` // must be chosen from `service` and `application`. - Key string `validate:"required" yaml:"key" json:"key,omitempty" property:"key"` // specifies which service or application the rule body acts on. - Runtime bool `default:"false" yaml:"runtime" json:"runtime,omitempty" property:"runtime"` - Enabled bool `default:"true" yaml:"enabled" json:"enabled,omitempty" property:"enabled"` - AffinityAware AffinityAware `yaml:"affinityAware" json:"affinityAware,omitempty" property:"affinityAware"` -} - -// Prefix dubbo.router -func (RouterConfig) Prefix() string { - return constant.RouterConfigPrefix -} - -func (c *RouterConfig) Init() error { - if err := defaults.Set(c); err != nil { - return err - } - return verify(c) -} - -func initRouterConfig(rc *RootConfig) error { - routers := rc.Router - if len(routers) > 0 { - for _, r := range routers { - if err := r.Init(); err != nil { - return err - } - } - rc.Router = routers - } - - //chain.SetVSAndDRConfigByte(vsBytes, drBytes) - return nil -} - -type RouterConfigBuilder struct { - routerConfig *RouterConfig -} - -func NewRouterConfigBuilder() *RouterConfigBuilder { - return &RouterConfigBuilder{routerConfig: &RouterConfig{}} -} - -func (rcb *RouterConfigBuilder) SetScope(scope string) *RouterConfigBuilder { - rcb.routerConfig.Scope = scope - return rcb -} - -func (rcb *RouterConfigBuilder) SetKey(key string) *RouterConfigBuilder { - rcb.routerConfig.Key = key - return rcb -} - -func (rcb *RouterConfigBuilder) SetForce(force bool) *RouterConfigBuilder { - rcb.routerConfig.Force = &force - return rcb -} - -func (rcb *RouterConfigBuilder) SetRuntime(runtime bool) *RouterConfigBuilder { - rcb.routerConfig.Runtime = &runtime - return rcb -} - -func (rcb *RouterConfigBuilder) SetEnabled(enabled bool) *RouterConfigBuilder { - rcb.routerConfig.Enabled = &enabled - return rcb -} - -func (rcb *RouterConfigBuilder) SetValid(valid bool) *RouterConfigBuilder { - rcb.routerConfig.Valid = &valid - return rcb -} - -func (rcb *RouterConfigBuilder) SetPriority(priority int) *RouterConfigBuilder { - rcb.routerConfig.Priority = priority - return rcb -} - -func (rcb *RouterConfigBuilder) SetConditions(conditions []string) *RouterConfigBuilder { - rcb.routerConfig.Conditions = conditions - return rcb -} - -func (rcb *RouterConfigBuilder) AddCondition(condition string) *RouterConfigBuilder { - if rcb.routerConfig.Conditions == nil { - rcb.routerConfig.Conditions = make([]string, 0) - } - rcb.routerConfig.Conditions = append(rcb.routerConfig.Conditions, condition) - return rcb -} - -func (rcb *RouterConfigBuilder) SetTags(tags []Tag) *RouterConfigBuilder { - rcb.routerConfig.Tags = tags - return rcb -} - -func (rcb *RouterConfigBuilder) AddTag(tag Tag) *RouterConfigBuilder { - if rcb.routerConfig.Tags == nil { - rcb.routerConfig.Tags = make([]Tag, 0) - } - rcb.routerConfig.Tags = append(rcb.routerConfig.Tags, tag) - return rcb -} - -func (rcb *RouterConfigBuilder) Build() *RouterConfig { - if err := rcb.routerConfig.Init(); err != nil { - panic(err) - } - return rcb.routerConfig -} - -func (x *ConditionRule) Equal(t *ConditionRule) bool { - if !reflect.DeepEqual(x.From, t.From) { - return false - } - if len(x.To) != len(t.To) { - return false - } - for i := range x.To { - if !reflect.DeepEqual(x.To[i], t.To[i]) { - return false - } - } - return true -} diff --git a/config/router_config_test.go b/config/router_config_test.go deleted file mode 100644 index fcaed0670b..0000000000 --- a/config/router_config_test.go +++ /dev/null @@ -1,87 +0,0 @@ -/* - * 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 ( - "strings" - "testing" -) - -import ( - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" -) - -import ( - "dubbo.apache.org/dubbo-go/v3/common/constant" -) - -func TestString(t *testing.T) { - s := "a1=>a2" - s1 := "=>a2" - s2 := "a1=>" - - n := strings.SplitN(s, "=>", 2) - n1 := strings.SplitN(s1, "=>", 2) - n2 := strings.SplitN(s2, "=>", 2) - - assert.Equal(t, "a1", n[0]) - assert.Equal(t, "a2", n[1]) - - assert.Empty(t, n1[0]) - assert.Equal(t, "a2", n1[1]) - - assert.Equal(t, "a1", n2[0]) - assert.Empty(t, n2[1]) -} - -func TestRouterInit(t *testing.T) { - //err := RouterInit(testVirtualServiceYML, testDestinationRuleYML) - //require.NoError(t, err) - // - //err = RouterInit(testVirtualServiceYML, errorTestDestinationRuleYML) - //assert.Error(t, err) -} - -func TestNewRouterConfigBuilder(t *testing.T) { - tag := Tag{ - Name: "tag", - Addresses: []string{"127.0.0.1"}, - } - rc := newEmptyRootConfig() - config := NewRouterConfigBuilder(). - SetScope("scope"). - SetKey("key"). - SetForce(true). - SetRuntime(true). - SetEnabled(true). - SetValid(true). - SetPriority(10). - SetConditions([]string{"condition"}). - AddCondition("condition"). - SetTags([]Tag{tag}). - AddTag(tag). - Build() - - err := initRouterConfig(rc) - require.NoError(t, err) - err = config.Init() - require.NoError(t, err) - - assert.Equal(t, constant.RouterConfigPrefix, config.Prefix()) -} diff --git a/config/service.go b/config/service.go deleted file mode 100644 index cdcfbc52a1..0000000000 --- a/config/service.go +++ /dev/null @@ -1,148 +0,0 @@ -/* - * 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 ( - "sync" -) - -import ( - "github.com/dubbogo/gost/log/logger" -) - -import ( - "dubbo.apache.org/dubbo-go/v3/common" -) - -var ( - conServicesLock = sync.Mutex{} // used to guard conServices map. - conServices = map[string]common.RPCService{} // service name -> service - proServicesLock = sync.Mutex{} // used to guard proServices map and proServicesInfo map - proServices = map[string]common.RPCService{} // service name -> service - proServicesInfo = map[string]any{} // service name -> service info - interfaceNameConServicesLock = sync.Mutex{} // used to guard interfaceNameConServices map - interfaceNameConServices = map[string]common.RPCService{} // interfaceName -> service -) - -// SetConsumerService is called by init() of implement of RPCService -func SetConsumerService(service common.RPCService) { - ref := common.GetReference(service) - conServicesLock.Lock() - defer func() { - conServicesLock.Unlock() - logger.Debugf("A consumer service %s was registered successfully.", ref) - }() - conServices[ref] = service -} - -// SetProviderService is called by init() of implementation of RPCService -func SetProviderService(service common.RPCService) { - ref := common.GetReference(service) - proServicesLock.Lock() - defer func() { - proServicesLock.Unlock() - logger.Debugf("A provider service %s was registered successfully.", ref) - }() - proServices[ref] = service -} - -// SetProviderServiceWithInfo is called by init() of implementation of RPCService -func SetProviderServiceWithInfo(service common.RPCService, info any) { - ref := common.GetReference(service) - proServicesLock.Lock() - defer func() { - proServicesLock.Unlock() - logger.Debugf("A provider service %s was registered successfully.", ref) - }() - proServices[ref] = service - proServicesInfo[ref] = info -} - -// GetConsumerService gets ConsumerService by @name -func GetConsumerService(name string) common.RPCService { - conServicesLock.Lock() - defer conServicesLock.Unlock() - return conServices[name] -} - -// GetProviderService gets ProviderService by @name -func GetProviderService(name string) common.RPCService { - proServicesLock.Lock() - defer proServicesLock.Unlock() - return proServices[name] -} - -// GetProviderServiceMap gets ProviderServiceMap -func GetProviderServiceMap() map[string]common.RPCService { - proServicesLock.Lock() - defer proServicesLock.Unlock() - - m := make(map[string]common.RPCService, len(proServices)) - for k, v := range proServices { - m[k] = v - } - return m -} - -func GetProviderServiceInfo(name string) any { - proServicesLock.Lock() - defer proServicesLock.Unlock() - return proServicesInfo[name] -} - -// GetConsumerServiceMap gets ProviderServiceMap -func GetConsumerServiceMap() map[string]common.RPCService { - conServicesLock.Lock() - defer conServicesLock.Unlock() - - m := make(map[string]common.RPCService, len(conServices)) - for k, v := range conServices { - m[k] = v - } - return m -} - -// SetConsumerServiceByInterfaceName is used by pb serialization -func SetConsumerServiceByInterfaceName(interfaceName string, srv common.RPCService) { - interfaceNameConServicesLock.Lock() - defer interfaceNameConServicesLock.Unlock() - interfaceNameConServices[interfaceName] = srv -} - -// GetConsumerServiceByInterfaceName is used by pb serialization -func GetConsumerServiceByInterfaceName(interfaceName string) common.RPCService { - interfaceNameConServicesLock.Lock() - defer interfaceNameConServicesLock.Unlock() - return interfaceNameConServices[interfaceName] -} - -// GetCallback gets CallbackResponse by @name -func GetCallback(name string) func(response common.CallbackResponse) { - service := GetConsumerService(name) - if sv, ok := service.(common.AsyncCallbackService); ok { - return sv.CallBack - } - return nil -} - -// SetClientInfoService is used by new Triple generated code -// use any to represent info because config package can not depend on client package. -// When refactoring work finished, this info should be with *client.ClientInfo type and this -// function would be implemented. -// todo(DMWangnima): refactor and implement this function -func SetClientInfoService(info any, service common.RPCService) {} diff --git a/config/service_config.go b/config/service_config.go deleted file mode 100644 index cf7e5fb1aa..0000000000 --- a/config/service_config.go +++ /dev/null @@ -1,606 +0,0 @@ -/* - * 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 ( - "container/list" - "fmt" - "net/url" - "os" - "strconv" - "strings" - "sync" - "time" -) - -import ( - "github.com/creasty/defaults" - - "github.com/dubbogo/gost/log/logger" - - perrors "github.com/pkg/errors" - - "go.uber.org/atomic" -) - -import ( - "dubbo.apache.org/dubbo-go/v3/common" - "dubbo.apache.org/dubbo-go/v3/common/constant" - "dubbo.apache.org/dubbo-go/v3/common/extension" - "dubbo.apache.org/dubbo-go/v3/protocol/base" - "dubbo.apache.org/dubbo-go/v3/protocol/protocolwrapper" -) - -// ServiceConfig is the configuration of the service provider -type ServiceConfig struct { - id string - Filter string `yaml:"filter" json:"filter,omitempty" property:"filter"` - ProtocolIDs []string `yaml:"protocol-ids" json:"protocol-ids,omitempty" property:"protocol-ids"` // multi protocolIDs support, split by ',' - Interface string `yaml:"interface" json:"interface,omitempty" property:"interface"` - RegistryIDs []string `yaml:"registry-ids" json:"registry-ids,omitempty" property:"registry-ids"` - Cluster string `default:"failover" yaml:"cluster" json:"cluster,omitempty" property:"cluster"` - Loadbalance string `default:"random" yaml:"loadbalance" json:"loadbalance,omitempty" property:"loadbalance"` - Group string `yaml:"group" json:"group,omitempty" property:"group"` - Version string `yaml:"version" json:"version,omitempty" property:"version" ` - Methods []*MethodConfig `yaml:"methods" json:"methods,omitempty" property:"methods"` - Warmup string `yaml:"warmup" json:"warmup,omitempty" property:"warmup"` - Retries string `yaml:"retries" json:"retries,omitempty" property:"retries"` - Serialization string `yaml:"serialization" json:"serialization" property:"serialization"` - Params map[string]string `yaml:"params" json:"params,omitempty" property:"params"` - Token string `yaml:"token" json:"token,omitempty" property:"token"` - AccessLog string `yaml:"accesslog" json:"accesslog,omitempty" property:"accesslog"` - TpsLimiter string `yaml:"tps.limiter" json:"tps.limiter,omitempty" property:"tps.limiter"` - TpsLimitInterval string `yaml:"tps.limit.interval" json:"tps.limit.interval,omitempty" property:"tps.limit.interval"` - TpsLimitRate string `yaml:"tps.limit.rate" json:"tps.limit.rate,omitempty" property:"tps.limit.rate"` - TpsLimitStrategy string `yaml:"tps.limit.strategy" json:"tps.limit.strategy,omitempty" property:"tps.limit.strategy"` - TpsLimitRejectedHandler string `yaml:"tps.limit.rejected.handler" json:"tps.limit.rejected.handler,omitempty" property:"tps.limit.rejected.handler"` - ExecuteLimit string `yaml:"execute.limit" json:"execute.limit,omitempty" property:"execute.limit"` - ExecuteLimitRejectedHandler string `yaml:"execute.limit.rejected.handler" json:"execute.limit.rejected.handler,omitempty" property:"execute.limit.rejected.handler"` - Auth string `yaml:"auth" json:"auth,omitempty" property:"auth"` - NotRegister bool `yaml:"not_register" json:"not_register,omitempty" property:"not_register"` - ParamSign string `yaml:"param.sign" json:"param.sign,omitempty" property:"param.sign"` - Tag string `yaml:"tag" json:"tag,omitempty" property:"tag"` - TracingKey string `yaml:"tracing-key" json:"tracing-key,omitempty" propertiy:"tracing-key"` - - RCProtocolsMap map[string]*ProtocolConfig - RCRegistriesMap map[string]*RegistryConfig - ProxyFactoryKey string - adaptiveService bool - metricsEnable bool // whether append metrics filter to filter chain - unexported *atomic.Bool - exported *atomic.Bool - export bool // a flag to control whether the current service should export or not - rpcService common.RPCService - cacheMutex sync.Mutex - cacheProtocol base.Protocol - exportersLock sync.Mutex - exporters []base.Exporter - - metadataType string - rc *RootConfig -} - -// Prefix returns dubbo.service.${InterfaceName}. -func (s *ServiceConfig) Prefix() string { - return strings.Join([]string{constant.ServiceConfigPrefix, s.id}, ".") -} - -func (s *ServiceConfig) Init(rc *RootConfig) error { - s.rc = rc - if err := initProviderMethodConfig(s); err != nil { - return err - } - if err := defaults.Set(s); err != nil { - return err - } - s.exported = atomic.NewBool(false) - s.metadataType = rc.Application.MetadataType - if s.Filter == "" { - s.Filter = rc.Provider.Filter - } - if s.Version == "" { - s.Version = rc.Application.Version - } - if s.Group == "" { - s.Group = rc.Application.Group - } - s.unexported = atomic.NewBool(false) - if len(s.RCRegistriesMap) == 0 { - s.RCRegistriesMap = rc.Registries - } - if len(s.RCProtocolsMap) == 0 { - s.RCProtocolsMap = rc.Protocols - } - if rc.Provider != nil { - s.ProxyFactoryKey = rc.Provider.ProxyFactory - } - s.RegistryIDs = translateIds(s.RegistryIDs) - if len(s.RegistryIDs) <= 0 { - s.RegistryIDs = rc.Provider.RegistryIDs - } - - s.ProtocolIDs = translateIds(s.ProtocolIDs) - if len(s.ProtocolIDs) <= 0 { - s.ProtocolIDs = rc.Provider.ProtocolIDs - } - if len(s.ProtocolIDs) <= 0 { - for k := range rc.Protocols { - s.ProtocolIDs = append(s.ProtocolIDs, k) - } - } - if s.TracingKey == "" { - s.TracingKey = rc.Provider.TracingKey - } - if rc.Metrics.Enable != nil { - s.metricsEnable = *rc.Metrics.Enable - } - err := s.check() - if err != nil { - panic(err) - } - s.export = true - return verify(s) -} - -func (s *ServiceConfig) check() error { - // check if the limiter has been imported - if s.TpsLimiter != "" { - _, err := extension.GetTpsLimiter(s.TpsLimiter) - if err != nil { - panic(err) - } - } - if s.TpsLimitStrategy != "" { - _, err := extension.GetTpsLimitStrategyCreator(s.TpsLimitStrategy) - if err != nil { - panic(err) - } - } - if s.TpsLimitRejectedHandler != "" { - _, err := extension.GetRejectedExecutionHandler(s.TpsLimitRejectedHandler) - if err != nil { - panic(err) - } - } - - if s.TpsLimitInterval != "" { - tpsLimitInterval, err := strconv.ParseInt(s.TpsLimitInterval, 0, 0) - if err != nil { - return fmt.Errorf("[ServiceConfig] Cannot parse the configuration tps.limit.interval for service %s, please check your configuration", s.Interface) - } - if tpsLimitInterval < 0 { - return fmt.Errorf("[ServiceConfig] The configuration tps.limit.interval for service %s must be positive, please check your configuration", s.Interface) - } - } - - if s.TpsLimitRate != "" { - tpsLimitRate, err := strconv.ParseInt(s.TpsLimitRate, 0, 0) - if err != nil { - return fmt.Errorf("[ServiceConfig] Cannot parse the configuration tps.limit.rate for service %s, please check your configuration", s.Interface) - } - if tpsLimitRate < 0 { - return fmt.Errorf("[ServiceConfig] The configuration tps.limit.rate for service %s must be positive, please check your configuration", s.Interface) - } - } - return nil -} - -// InitExported will set exported as false atom bool -func (s *ServiceConfig) InitExported() { - s.exported = atomic.NewBool(false) -} - -// IsExport will return whether the service config is exported or not -func (s *ServiceConfig) IsExport() bool { - return s.exported.Load() -} - -// Get Random Port -func getRandomPort(protocolConfigs []*ProtocolConfig) *list.List { - ports := list.New() - for _, proto := range protocolConfigs { - if port, err := strconv.Atoi(proto.Port); err != nil { - logger.Infof( - "%s will be assgined to a random port, since the port is an invalid number", - proto.Name, - ) - } else if port > 0 { - continue - } - - ports.PushBack(common.GetRandomPort(proto.Ip)) - } - return ports -} - -// Export exports the service -func (s *ServiceConfig) Export() error { - // TODO: delay export - if s.unexported != nil && s.unexported.Load() { - err := perrors.Errorf("The service %v has already unexported!", s.Interface) - logger.Errorf(err.Error()) - return err - } - if s.exported != nil && s.exported.Load() { - logger.Warnf("The service %v has already exported!", s.Interface) - return nil - } - - common.WarnVariadicRPCMethods(s.Interface, s.rpcService) - - regUrls := make([]*common.URL, 0) - if !s.NotRegister { - regUrls = LoadRegistries(s.RegistryIDs, s.RCRegistriesMap, common.PROVIDER) - } - - urlMap := s.getUrlMap() - protocolConfigs := loadProtocol(s.ProtocolIDs, s.RCProtocolsMap) - if len(protocolConfigs) == 0 { - logger.Warnf("The service %v's '%v' protocols don't has right protocolConfigs, Please check your configuration center and transfer protocol ", s.Interface, s.ProtocolIDs) - return nil - } - - var invoker base.Invoker - ports := getRandomPort(protocolConfigs) - nextPort := ports.Front() - - for _, protocolConf := range protocolConfigs { - // registry the service reflect - methods, err := common.ServiceMap.Register(s.Interface, protocolConf.Name, s.Group, s.Version, s.rpcService) - if err != nil { - formatErr := perrors.Errorf("The service %v export the protocol %v error! Error message is %v.", - s.Interface, protocolConf.Name, err.Error()) - logger.Errorf(formatErr.Error()) - return formatErr - } - - port := protocolConf.Port - if num, err := strconv.Atoi(protocolConf.Port); err != nil || num <= 0 { - port = nextPort.Value.(string) - nextPort = nextPort.Next() - } - ivkURL := common.NewURLWithOptions( - common.WithPath(s.Interface), - common.WithProtocol(protocolConf.Name), - common.WithIp(protocolConf.Ip), - common.WithPort(port), - common.WithParams(urlMap), - common.WithParamsValue(constant.BeanNameKey, s.id), - common.WithParamsValue(constant.ApplicationTagKey, s.rc.Application.Tag), - //common.WithParamsValue(constant.SslEnabledKey, strconv.FormatBool(config.GetSslEnabled())), - common.WithMethods(strings.Split(methods, ",")), - common.WithAttribute(constant.RpcServiceKey, s.rpcService), - common.WithAttribute(constant.ProviderConfigKey, s.rc.Provider), - common.WithToken(s.Token), - common.WithParamsValue(constant.MetadataTypeKey, s.metadataType), - // fix https://github.com/apache/dubbo-go/issues/2176 - common.WithParamsValue(constant.MaxServerSendMsgSize, protocolConf.MaxServerSendMsgSize), - common.WithParamsValue(constant.MaxServerRecvMsgSize, protocolConf.MaxServerRecvMsgSize), - ) - info := GetProviderServiceInfo(s.id) - if info != nil { - ivkURL.SetAttribute(constant.ServiceInfoKey, info) - } - - if len(s.Tag) > 0 { - ivkURL.SetParam(constant.Tagkey, s.Tag) - } - - // post process the URL to be exported - s.postProcessConfig(ivkURL) - // config post processor may set "export" to false - if !ivkURL.GetParamBool(constant.ExportKey, true) { - return nil - } - - if len(regUrls) > 0 { - s.cacheMutex.Lock() - if s.cacheProtocol == nil { - logger.Debugf(fmt.Sprintf("First load the registry protocol, url is {%v}!", ivkURL)) - s.cacheProtocol = extension.GetProtocol(constant.RegistryProtocol) - } - s.cacheMutex.Unlock() - - for _, regUrl := range regUrls { - setRegistrySubURL(ivkURL, regUrl) - - invoker = s.generatorInvoker(regUrl, info) - exporter := s.cacheProtocol.Export(invoker) - if exporter == nil { - return perrors.New(fmt.Sprintf("Registry protocol new exporter error, registry is {%v}, url is {%v}", regUrl, ivkURL)) - } - s.exporters = append(s.exporters, exporter) - } - } else { - invoker = s.generatorInvoker(ivkURL, info) - exporter := extension.GetProtocol(protocolwrapper.FILTER).Export(invoker) - if exporter == nil { - return perrors.New(fmt.Sprintf("Filter protocol without registry new exporter error, url is {%v}", ivkURL)) - } - s.exporters = append(s.exporters, exporter) - } - } - s.exported.Store(true) - return nil -} - -func (s *ServiceConfig) generatorInvoker(url *common.URL, info any) base.Invoker { - proxyFactory := extension.GetProxyFactory(s.ProxyFactoryKey) - if info != nil { - url.SetAttribute(constant.ServiceInfoKey, info) - url.SetAttribute(constant.RpcServiceKey, s.rpcService) - } - return proxyFactory.GetInvoker(url) -} - -// setRegistrySubURL set registry sub url is ivkURl -func setRegistrySubURL(ivkURL *common.URL, regUrl *common.URL) { - ivkURL.SetParam(constant.RegistryKey, regUrl.GetParam(constant.RegistryKey, "")) - regUrl.SubURL = ivkURL -} - -// loadProtocol filter protocols by ids -func loadProtocol(protocolIds []string, protocols map[string]*ProtocolConfig) []*ProtocolConfig { - returnProtocols := make([]*ProtocolConfig, 0, len(protocols)) - for _, v := range protocolIds { - for k, config := range protocols { - if v == k { - returnProtocols = append(returnProtocols, config) - } - } - } - return returnProtocols -} - -// Unexport will call unexport of all exporters service config exported -func (s *ServiceConfig) Unexport() { - if !s.exported.Load() { - return - } - if s.unexported.Load() { - return - } - - func() { - s.exportersLock.Lock() - defer s.exportersLock.Unlock() - for _, exporter := range s.exporters { - exporter.UnExport() - } - s.exporters = nil - }() - - s.exported.Store(false) - s.unexported.Store(true) -} - -// Implement only store the @s and return -func (s *ServiceConfig) Implement(rpcService common.RPCService) { - s.rpcService = rpcService -} - -func (s *ServiceConfig) getUrlMap() url.Values { - urlMap := url.Values{} - // first set user params - for k, v := range s.Params { - urlMap.Set(k, v) - } - urlMap.Set(constant.InterfaceKey, s.Interface) - urlMap.Set(constant.TimestampKey, strconv.FormatInt(time.Now().Unix(), 10)) - urlMap.Set(constant.ClusterKey, s.Cluster) - urlMap.Set(constant.LoadbalanceKey, s.Loadbalance) - urlMap.Set(constant.WarmupKey, s.Warmup) - urlMap.Set(constant.RetriesKey, s.Retries) - if s.Group != "" { - urlMap.Set(constant.GroupKey, s.Group) - } - if s.Version != "" { - urlMap.Set(constant.VersionKey, s.Version) - } - urlMap.Set(constant.RegistryRoleKey, strconv.Itoa(common.PROVIDER)) - urlMap.Set(constant.ReleaseKey, "dubbo-golang-"+constant.Version) - urlMap.Set(constant.SideKey, (common.RoleType(common.PROVIDER)).Role()) - // todo: move - urlMap.Set(constant.SerializationKey, s.Serialization) - // application config info - ac := GetApplicationConfig() - urlMap.Set(constant.ApplicationKey, ac.Name) - urlMap.Set(constant.OrganizationKey, ac.Organization) - urlMap.Set(constant.NameKey, ac.Name) - urlMap.Set(constant.ModuleKey, ac.Module) - urlMap.Set(constant.AppVersionKey, ac.Version) - urlMap.Set(constant.OwnerKey, ac.Owner) - urlMap.Set(constant.EnvironmentKey, ac.Environment) - - // filter - var filters string - if s.Filter == "" { - filters = constant.DefaultServiceFilters - } else { - filters = s.Filter - } - if s.adaptiveService { - filters += fmt.Sprintf(",%s", constant.AdaptiveServiceProviderFilterKey) - } - if s.metricsEnable { - filters += fmt.Sprintf(",%s", constant.MetricsFilterKey) - } - urlMap.Set(constant.ServiceFilterKey, filters) - - // filter special config - urlMap.Set(constant.AccessLogFilterKey, s.AccessLog) - // tps limiter - urlMap.Set(constant.TPSLimitStrategyKey, s.TpsLimitStrategy) - urlMap.Set(constant.TPSLimitIntervalKey, s.TpsLimitInterval) - urlMap.Set(constant.TPSLimitRateKey, s.TpsLimitRate) - urlMap.Set(constant.TPSLimiterKey, s.TpsLimiter) - urlMap.Set(constant.TPSRejectedExecutionHandlerKey, s.TpsLimitRejectedHandler) - urlMap.Set(constant.TracingConfigKey, s.TracingKey) - - // execute limit filter - urlMap.Set(constant.ExecuteLimitKey, s.ExecuteLimit) - urlMap.Set(constant.ExecuteRejectedExecutionHandlerKey, s.ExecuteLimitRejectedHandler) - - // auth filter - urlMap.Set(constant.ServiceAuthKey, s.Auth) - urlMap.Set(constant.ParameterSignatureEnableKey, s.ParamSign) - - // whether to export or not - urlMap.Set(constant.ExportKey, strconv.FormatBool(s.export)) - urlMap.Set(constant.PIDKey, fmt.Sprintf("%d", os.Getpid())) - - for _, v := range s.Methods { - prefix := "methods." + v.Name + "." - urlMap.Set(prefix+constant.LoadbalanceKey, v.LoadBalance) - urlMap.Set(prefix+constant.RetriesKey, v.Retries) - urlMap.Set(prefix+constant.WeightKey, strconv.FormatInt(v.Weight, 10)) - - urlMap.Set(prefix+constant.TPSLimitStrategyKey, v.TpsLimitStrategy) - urlMap.Set(prefix+constant.TPSLimitIntervalKey, v.TpsLimitInterval) - urlMap.Set(prefix+constant.TPSLimitRateKey, v.TpsLimitRate) - - urlMap.Set(constant.ExecuteLimitKey, v.ExecuteLimit) - urlMap.Set(constant.ExecuteRejectedExecutionHandlerKey, v.ExecuteLimitRejectedHandler) - } - - return urlMap -} - -// GetExportedUrls will return the url in service config's exporter -func (s *ServiceConfig) GetExportedUrls() []*common.URL { - if s.exported.Load() { - var urls []*common.URL - for _, exporter := range s.exporters { - urls = append(urls, exporter.GetInvoker().GetURL()) - } - return urls - } - return nil -} - -// postProcessConfig asks registered ConfigPostProcessor to post-process the current ServiceConfig. -func (s *ServiceConfig) postProcessConfig(url *common.URL) { - for _, p := range extension.GetConfigPostProcessors() { - p.PostProcessServiceConfig(url) - } -} - -// newEmptyServiceConfig returns default ServiceConfig -func newEmptyServiceConfig() *ServiceConfig { - newServiceConfig := &ServiceConfig{ - unexported: atomic.NewBool(false), - exported: atomic.NewBool(false), - export: true, - RCProtocolsMap: make(map[string]*ProtocolConfig), - RCRegistriesMap: make(map[string]*RegistryConfig), - } - newServiceConfig.Params = make(map[string]string) - newServiceConfig.Methods = make([]*MethodConfig, 0, 8) - return newServiceConfig -} - -type ServiceConfigBuilder struct { - serviceConfig *ServiceConfig -} - -func NewServiceConfigBuilder() *ServiceConfigBuilder { - return &ServiceConfigBuilder{serviceConfig: newEmptyServiceConfig()} -} - -func (pcb *ServiceConfigBuilder) SetRegistryIDs(registryIDs ...string) *ServiceConfigBuilder { - pcb.serviceConfig.RegistryIDs = registryIDs - return pcb -} - -func (pcb *ServiceConfigBuilder) SetProtocolIDs(protocolIDs ...string) *ServiceConfigBuilder { - pcb.serviceConfig.ProtocolIDs = protocolIDs - return pcb -} - -func (pcb *ServiceConfigBuilder) SetInterface(interfaceName string) *ServiceConfigBuilder { - pcb.serviceConfig.Interface = interfaceName - return pcb -} - -func (pcb *ServiceConfigBuilder) SetMetadataType(setMetadataType string) *ServiceConfigBuilder { - pcb.serviceConfig.metadataType = setMetadataType - return pcb -} - -func (pcb *ServiceConfigBuilder) SetLoadBalance(lb string) *ServiceConfigBuilder { - pcb.serviceConfig.Loadbalance = lb - return pcb -} - -func (pcb *ServiceConfigBuilder) SetWarmUpTie(warmUp string) *ServiceConfigBuilder { - pcb.serviceConfig.Warmup = warmUp - return pcb -} - -func (pcb *ServiceConfigBuilder) SetCluster(cluster string) *ServiceConfigBuilder { - pcb.serviceConfig.Cluster = cluster - return pcb -} - -func (pcb *ServiceConfigBuilder) AddRCProtocol(protocolName string, protocolConfig *ProtocolConfig) *ServiceConfigBuilder { - pcb.serviceConfig.RCProtocolsMap[protocolName] = protocolConfig - return pcb -} - -func (pcb *ServiceConfigBuilder) AddRCRegistry(registryName string, registryConfig *RegistryConfig) *ServiceConfigBuilder { - pcb.serviceConfig.RCRegistriesMap[registryName] = registryConfig - return pcb -} - -func (pcb *ServiceConfigBuilder) SetGroup(group string) *ServiceConfigBuilder { - pcb.serviceConfig.Group = group - return pcb -} -func (pcb *ServiceConfigBuilder) SetVersion(version string) *ServiceConfigBuilder { - pcb.serviceConfig.Version = version - return pcb -} - -func (pcb *ServiceConfigBuilder) SetProxyFactoryKey(proxyFactoryKey string) *ServiceConfigBuilder { - pcb.serviceConfig.ProxyFactoryKey = proxyFactoryKey - return pcb -} - -func (pcb *ServiceConfigBuilder) SetRPCService(service common.RPCService) *ServiceConfigBuilder { - pcb.serviceConfig.rpcService = service - return pcb -} - -func (pcb *ServiceConfigBuilder) SetSerialization(serialization string) *ServiceConfigBuilder { - pcb.serviceConfig.Serialization = serialization - return pcb -} - -func (pcb *ServiceConfigBuilder) SetServiceID(id string) *ServiceConfigBuilder { - pcb.serviceConfig.id = id - return pcb -} - -func (pcb *ServiceConfigBuilder) SetNotRegister(notRegister bool) *ServiceConfigBuilder { - pcb.serviceConfig.NotRegister = notRegister - return pcb -} - -func (pcb *ServiceConfigBuilder) Build() *ServiceConfig { - return pcb.serviceConfig -} diff --git a/config/service_config_test.go b/config/service_config_test.go deleted file mode 100644 index 36f5f2bab0..0000000000 --- a/config/service_config_test.go +++ /dev/null @@ -1,231 +0,0 @@ -/* - * 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 ( - "context" - "fmt" - "strings" - "testing" -) - -import ( - gostlogger "github.com/dubbogo/gost/log/logger" - - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" -) - -import ( - "dubbo.apache.org/dubbo-go/v3/common" - "dubbo.apache.org/dubbo-go/v3/common/constant" - "dubbo.apache.org/dubbo-go/v3/common/extension" - "dubbo.apache.org/dubbo-go/v3/protocol/protocolwrapper" - _ "dubbo.apache.org/dubbo-go/v3/proxy/proxy_factory" -) - -type HelloService struct { -} - -func (hs *HelloService) Say(ctx context.Context, name string) (string, error) { - return name, nil -} -func (hs *HelloService) Reference() string { - return "HelloService" -} - -func (hs *HelloService) JavaClassName() string { - return "org.apache.dubbo.HelloService" -} - -type VariadicHelloService struct{} - -func (hs *VariadicHelloService) Fanout(ctx context.Context, names ...string) error { - return nil -} - -func (hs *VariadicHelloService) Reference() string { - return "VariadicHelloService" -} - -type serviceConfigCaptureWarnLogger struct { - gostlogger.Logger - warns []string -} - -func (l *serviceConfigCaptureWarnLogger) Warnf(template string, args ...any) { - l.warns = append(l.warns, fmt.Sprintf(template, args...)) -} - -func TestNewServiceConfigBuilder(t *testing.T) { - SetProviderService(&HelloService{}) - var serviceConfig = newEmptyServiceConfig() - t.Run("NewServiceConfigBuilder", func(t *testing.T) { - registryConfig := NewRegistryConfigWithProtocolDefaultPort("nacos") - protocolConfig := NewProtocolConfigBuilder(). - SetName("dubbo"). - SetPort("20000"). - Build() - rc := newEmptyRootConfig() - - serviceConfig = NewServiceConfigBuilder(). - SetRegistryIDs("nacos"). - SetProtocolIDs("dubbo"). - SetInterface("org.apache.dubbo.HelloService"). - SetMetadataType("local"). - SetLoadBalance("random"). - SetWarmUpTie("warmup"). - SetCluster("cluster"). - AddRCRegistry("nacos", registryConfig). - AddRCProtocol("dubbo", protocolConfig). - SetGroup("dubbo"). - SetVersion("1.0.0"). - SetProxyFactoryKey("default"). - SetSerialization("serialization"). - SetServiceID("HelloService"). - Build() - - serviceConfig.InitExported() - - serviceConfig.Methods = []*MethodConfig{ - { - Name: "Say", - Retries: "3", - }, - } - - err := serviceConfig.Init(rc) - require.NoError(t, err) - err = serviceConfig.check() - require.NoError(t, err) - - assert.Equal(t, serviceConfig.Prefix(), strings.Join([]string{constant.ServiceConfigPrefix, serviceConfig.id}, ".")) - assert.False(t, serviceConfig.IsExport()) - }) - - t.Run("LoadRegistries&loadProtocol&getRandomPort", func(t *testing.T) { - registries := LoadRegistries(serviceConfig.RegistryIDs, serviceConfig.RCRegistriesMap, common.PROVIDER) - assert.Len(t, registries, 1) - assert.Equal(t, "service-discovery-registry", registries[0].Protocol) - assert.Equal(t, "8848", registries[0].Port) - assert.Equal(t, "3", registries[0].GetParam("registry.role", "1")) - assert.Equal(t, "nacos", registries[0].GetParam("registry", "zk")) - - protocols := loadProtocol(serviceConfig.ProtocolIDs, serviceConfig.RCProtocolsMap) - assert.Len(t, protocols, 1) - assert.Equal(t, "dubbo", protocols[0].Name) - assert.Equal(t, "20000", protocols[0].Port) - - ports := getRandomPort(protocols) - nextPort := ports.Front() - assert.Nil(t, nextPort) - }) - t.Run("getUrlMap", func(t *testing.T) { - values := serviceConfig.getUrlMap() - assert.Equal(t, "0", values.Get("methods.Say.weight")) - assert.Empty(t, values.Get("methods.Say.tps.limit.rate")) - assert.Equal(t, "echo,token,accesslog,tps,generic_service,execute,pshutdown", values.Get(constant.ServiceFilterKey)) - }) - - t.Run("Implement", func(t *testing.T) { - serviceConfig.Implement(&HelloService{}) - //urls := serviceConfig.GetExportedUrls() - //err := serviceConfig.Export() - assert.NotNil(t, serviceConfig.rpcService) - }) -} - -func TestServiceConfigExportWarnsOnVariadicRPCMethods(t *testing.T) { - prev := gostlogger.GetLogger() - capture := &serviceConfigCaptureWarnLogger{Logger: prev} - gostlogger.SetLogger(capture) - t.Cleanup(func() { - gostlogger.SetLogger(prev) - }) - - serviceConfig := newEmptyServiceConfig() - serviceConfig.Interface = "com.example.VariadicHelloService" - serviceConfig.NotRegister = true - serviceConfig.rpcService = &VariadicHelloService{} - - err := serviceConfig.Export() - require.NoError(t, err) - - warns := strings.Join(capture.warns, "\n") - assert.Contains(t, warns, serviceConfig.Interface) - assert.Contains(t, warns, "Fanout") -} - -func TestServiceConfigExportDoesNotWarnOnNonVariadicRPCMethods(t *testing.T) { - prev := gostlogger.GetLogger() - capture := &serviceConfigCaptureWarnLogger{Logger: prev} - gostlogger.SetLogger(capture) - t.Cleanup(func() { - gostlogger.SetLogger(prev) - }) - - serviceConfig := newEmptyServiceConfig() - serviceConfig.Interface = "org.apache.dubbo.HelloService" - serviceConfig.NotRegister = true - serviceConfig.rpcService = &HelloService{} - - err := serviceConfig.Export() - require.NoError(t, err) - - for _, warn := range capture.warns { - assert.NotContains(t, warn, "variadic RPC method") - } -} - -func TestServiceConfigExportCarriesProviderAttributes(t *testing.T) { - extension.SetProtocol(protocolwrapper.FILTER, protocolwrapper.NewMockProtocolFilter) - - const interfaceName = "org.apache.dubbo.ProviderAttributeService" - serviceConfig := newEmptyServiceConfig() - serviceConfig.id = "ProviderAttributeService" - serviceConfig.Interface = interfaceName - serviceConfig.NotRegister = true - serviceConfig.ProtocolIDs = []string{"dubbo"} - serviceConfig.rpcService = &HelloService{} - - rc := newEmptyRootConfig() - rc.Protocols["dubbo"] = NewProtocolConfigBuilder(). - SetName("dubbo"). - SetPort("20000"). - Build() - - err := serviceConfig.Init(rc) - require.NoError(t, err) - err = serviceConfig.Export() - require.NoError(t, err) - t.Cleanup(serviceConfig.Unexport) - t.Cleanup(func() { - _ = common.ServiceMap.UnRegister(interfaceName, "dubbo", common.ServiceKey(interfaceName, "", "")) - }) - - urls := serviceConfig.GetExportedUrls() - require.Len(t, urls, 1) - - providerRaw, ok := urls[0].GetAttribute(constant.ProviderConfigKey) - require.True(t, ok) - assert.Same(t, rc.Provider, providerRaw) - - rpcServiceRaw, ok := urls[0].GetAttribute(constant.RpcServiceKey) - require.True(t, ok) - assert.Same(t, serviceConfig.rpcService, rpcServiceRaw) -} diff --git a/config/service_discovery_config.go b/config/service_discovery_config.go deleted file mode 100644 index d93aea57f0..0000000000 --- a/config/service_discovery_config.go +++ /dev/null @@ -1,74 +0,0 @@ -/* - * 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" -) - -// ServiceDiscoveryConfig will be used to create -type ServiceDiscoveryConfig struct { - // Protocol indicate which implementation will be used. - // for example, if the Protocol is nacos, it means that we will use nacosServiceDiscovery - Protocol string `yaml:"protocol" json:"protocol,omitempty" property:"protocol"` - // Group, usually you don't need to config this field. - // you can use this to do some isolation - Group string `yaml:"group" json:"group,omitempty"` - // RemoteRef is the reference point to RemoteConfig which will be used to create remotes instances. - RemoteRef string `yaml:"remote_ref" json:"remote_ref,omitempty" property:"remote_ref"` -} - -func (ServiceDiscoveryConfig) Prefix() string { - return constant.ServiceDiscPrefix -} - -func (ServiceDiscoveryConfig) Init() error { - return nil -} - -func NewServiceDiscoveryConfigBuilder() *ServiceDiscoveryConfigBuilder { - return &ServiceDiscoveryConfigBuilder{ - serviceDiscoveryConfig: &ServiceDiscoveryConfig{}, - } -} - -type ServiceDiscoveryConfigBuilder struct { - serviceDiscoveryConfig *ServiceDiscoveryConfig -} - -func (sdcb *ServiceDiscoveryConfigBuilder) SetProtocol(protocol string) *ServiceDiscoveryConfigBuilder { - sdcb.serviceDiscoveryConfig.Protocol = protocol - return sdcb -} - -func (sdcb *ServiceDiscoveryConfigBuilder) SetGroup(group string) *ServiceDiscoveryConfigBuilder { - sdcb.serviceDiscoveryConfig.Group = group - return sdcb -} - -func (sdcb *ServiceDiscoveryConfigBuilder) SetRemoteRef(remoteRef string) *ServiceDiscoveryConfigBuilder { - sdcb.serviceDiscoveryConfig.RemoteRef = remoteRef - return sdcb -} - -func (sdcb *ServiceDiscoveryConfigBuilder) Build() *ServiceDiscoveryConfig { - if err := sdcb.serviceDiscoveryConfig.Init(); err != nil { - panic(err) - } - return sdcb.serviceDiscoveryConfig -} diff --git a/config/service_discovery_config_test.go b/config/service_discovery_config_test.go deleted file mode 100644 index f94a715880..0000000000 --- a/config/service_discovery_config_test.go +++ /dev/null @@ -1,45 +0,0 @@ -/* - * 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/stretchr/testify/assert" - "github.com/stretchr/testify/require" -) - -import ( - "dubbo.apache.org/dubbo-go/v3/common/constant" -) - -func TestNewServiceDiscoveryConfigBuilder(t *testing.T) { - - config := NewServiceDiscoveryConfigBuilder(). - SetProtocol("protocol"). - SetGroup("group"). - SetRemoteRef("remote"). - Build() - - err := config.Init() - require.NoError(t, err) - assert.Equal(t, "protocol", config.Protocol) - assert.Equal(t, constant.ServiceDiscPrefix, config.Prefix()) -} diff --git a/config/service_test.go b/config/service_test.go deleted file mode 100644 index 179ffa2f66..0000000000 --- a/config/service_test.go +++ /dev/null @@ -1,118 +0,0 @@ -/* - * 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 ( - "maps" - "testing" -) - -import ( - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" -) - -import ( - "dubbo.apache.org/dubbo-go/v3/common" -) - -func cloneRPCServiceMap(src map[string]common.RPCService) map[string]common.RPCService { - return maps.Clone(src) -} - -func TestGetConsumerService(t *testing.T) { - - SetConsumerService(&HelloService{}) - SetProviderService(&HelloService{}) - - service := GetConsumerService("HelloService") - reference := service.(*HelloService).Reference() - - assert.Equal(t, "HelloService", reference) - - SetConsumerServiceByInterfaceName("org.apache.dubbo.HelloService", &HelloService{}) - service = GetConsumerServiceByInterfaceName("org.apache.dubbo.HelloService") - reference = service.(*HelloService).Reference() - assert.Equal(t, "HelloService", reference) - - callback := GetCallback(reference) - assert.Nil(t, callback) -} - -func TestGetProviderServiceMapReturnsCopy(t *testing.T) { - proServicesLock.Lock() - originalProServices := cloneRPCServiceMap(proServices) - originalProServicesInfo := maps.Clone(proServicesInfo) - proServices = map[string]common.RPCService{} - proServicesInfo = map[string]any{} - proServicesLock.Unlock() - - defer func() { - proServicesLock.Lock() - proServices = originalProServices - proServicesInfo = originalProServicesInfo - proServicesLock.Unlock() - }() - - svc := &HelloService{} - SetProviderService(svc) - - got := GetProviderServiceMap() - require.Len(t, got, 1) - - got["Injected"] = &HelloService{} - got["HelloService"] = &HelloService{} - - proServicesLock.Lock() - _, hasInjected := proServices["Injected"] - _, hasHelloService := proServices["HelloService"] - proServicesLock.Unlock() - - assert.False(t, hasInjected) - assert.True(t, hasHelloService) -} - -func TestGetConsumerServiceMapReturnsCopy(t *testing.T) { - conServicesLock.Lock() - originalConServices := cloneRPCServiceMap(conServices) - conServices = map[string]common.RPCService{} - conServicesLock.Unlock() - - defer func() { - conServicesLock.Lock() - conServices = originalConServices - conServicesLock.Unlock() - }() - - svc := &HelloService{} - SetConsumerService(svc) - - got := GetConsumerServiceMap() - require.Len(t, got, 1) - - got["Injected"] = &HelloService{} - got["HelloService"] = &HelloService{} - - conServicesLock.Lock() - _, hasInjected := conServices["Injected"] - stored := conServices["HelloService"] - conServicesLock.Unlock() - - assert.False(t, hasInjected) - assert.Equal(t, svc, stored) -} diff --git a/config/ssl_config.go b/config/ssl_config.go deleted file mode 100644 index 8551b4cf53..0000000000 --- a/config/ssl_config.go +++ /dev/null @@ -1,49 +0,0 @@ -/* - * 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 ( - "github.com/apache/dubbo-getty" -) - -var ( - // Deprecated: use TLSConfig instead. - serverTlsConfigBuilder getty.TlsConfigBuilder - // Deprecated: use TLSConfig instead. - clientTlsConfigBuilder getty.TlsConfigBuilder -) - -// Deprecated: use TLSConfig instead. -func GetServerTlsConfigBuilder() getty.TlsConfigBuilder { - return serverTlsConfigBuilder -} - -// Deprecated: use TLSConfig instead. -func GetClientTlsConfigBuilder() getty.TlsConfigBuilder { - return clientTlsConfigBuilder -} - -// Deprecated: use TLSConfig instead. -func SetServerTlsConfigBuilder(configBuilder getty.TlsConfigBuilder) { - serverTlsConfigBuilder = configBuilder -} - -// Deprecated: use TLSConfig instead. -func SetClientTlsConfigBuilder(configBuilder getty.TlsConfigBuilder) { - clientTlsConfigBuilder = configBuilder -} diff --git a/config/ssl_config_test.go b/config/ssl_config_test.go deleted file mode 100644 index 75a37be7e8..0000000000 --- a/config/ssl_config_test.go +++ /dev/null @@ -1,47 +0,0 @@ -/* - * 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 ( - "reflect" - "testing" -) - -import ( - getty "github.com/apache/dubbo-getty" - - "github.com/stretchr/testify/assert" -) - -func TestServerTlsConfigBuilder(t *testing.T) { - - SetServerTlsConfigBuilder(&getty.ServerTlsConfigBuilder{}) - SetClientTlsConfigBuilder(&getty.ClientTlsConfigBuilder{}) - - serverTlsConfig := GetServerTlsConfigBuilder() - clientTlsConfig := GetClientTlsConfigBuilder() - - vf := reflect.ValueOf(serverTlsConfig) - name := reflect.Indirect(vf).Type().Name() - - assert.Equal(t, "ServerTlsConfigBuilder", name) - - vf = reflect.ValueOf(clientTlsConfig) - name = reflect.Indirect(vf).Type().Name() - assert.Equal(t, "ClientTlsConfigBuilder", name) -} diff --git a/config/testdata/application.yaml b/config/testdata/application.yaml deleted file mode 100644 index b1a90870c9..0000000000 --- a/config/testdata/application.yaml +++ /dev/null @@ -1,50 +0,0 @@ -# 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. - -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: 127.0.0.1 - port: 20000 - registries: - nacos: - timeout: 5s - group: dev - address: nacos://127.0.0.1:8848 - zk: - protocol: zookeeper - group: 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 diff --git a/config/testdata/config/active/application-local.yaml b/config/testdata/config/active/application-local.yaml deleted file mode 100644 index a56662cd73..0000000000 --- a/config/testdata/config/active/application-local.yaml +++ /dev/null @@ -1,31 +0,0 @@ -# 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. - -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 deleted file mode 100644 index 0555b5c942..0000000000 --- a/config/testdata/config/active/application.yaml +++ /dev/null @@ -1,22 +0,0 @@ -# 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. - -dubbo: - profiles: - active: local - registries: - nacos: - timeout: 3s - address: nacos://127.0.0.1:8848 \ No newline at end of file diff --git a/config/testdata/config/app/application.yaml b/config/testdata/config/app/application.yaml deleted file mode 100644 index 21deb3eee3..0000000000 --- a/config/testdata/config/app/application.yaml +++ /dev/null @@ -1,36 +0,0 @@ -# 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. - -dubbo: - registries: - nacos: - timeout: 3s - address: nacos://127.0.0.1:8848 - protocols: - dubbo: - name: dubbo - port: 20000 - consumer: - references: - helloService: - protocol: dubbo - interface: org.github.dubbo.HelloService # must be compatible with grpc or dubbo-java - provider: - register: true - registry-ids: nacos - services: - helloService: - protocol: dubbo - interface: org.github.dubbo.HelloService # must be compatible with grpc or dubbo-java \ No newline at end of file diff --git a/config/testdata/config/application/application.yaml b/config/testdata/config/application/application.yaml deleted file mode 100644 index 773e87cc60..0000000000 --- a/config/testdata/config/application/application.yaml +++ /dev/null @@ -1,19 +0,0 @@ -# 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. - -dubbo: - registries: - nacos: - address: nacos://127.0.0.1:8848 \ No newline at end of file diff --git a/config/testdata/config/center/conf-application.yaml b/config/testdata/config/center/conf-application.yaml deleted file mode 100644 index f41cf1b502..0000000000 --- a/config/testdata/config/center/conf-application.yaml +++ /dev/null @@ -1,28 +0,0 @@ -# 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. - -dubbo: - registries: - nacos: - timeout: 5s - group: dev - address: nacos://127.0.0.1:8848 - config-center: - address: nacos://127.0.0.1:8848 - cluster: dev - namespace: dubbo - log-dir: ./logs - config-file: dubbo.yaml - app-id: dubbo \ No newline at end of file diff --git a/config/testdata/config/custom/custom.yaml b/config/testdata/config/custom/custom.yaml deleted file mode 100644 index d6da15f4e9..0000000000 --- a/config/testdata/config/custom/custom.yaml +++ /dev/null @@ -1,28 +0,0 @@ -# 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. - -dubbo: - registries: - nacos: - timeout: 5s - group: dev - address: nacos://127.0.0.1:8848 - zk: - protocol: zookeeper - group: test - address: 127.0.0.1:2181 - custom: - config-map: - test-config: true diff --git a/config/testdata/config/custom/empty.yaml b/config/testdata/config/custom/empty.yaml deleted file mode 100644 index 8fc58887b9..0000000000 --- a/config/testdata/config/custom/empty.yaml +++ /dev/null @@ -1,26 +0,0 @@ -# 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. - -dubbo: - custom: - registries: - nacos: - timeout: 5s - group: dev - address: nacos://127.0.0.1:8848 - zk: - protocol: zookeeper - group: test - address: 127.0.0.1:2181 diff --git a/config/testdata/config/logger/empty_log.yaml b/config/testdata/config/logger/empty_log.yaml deleted file mode 100644 index befa55dda0..0000000000 --- a/config/testdata/config/logger/empty_log.yaml +++ /dev/null @@ -1,26 +0,0 @@ -# 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. - -dubbo: - logger: - registries: - nacos: - timeout: 5s - group: dev - address: nacos://127.0.0.1:8848 - zk: - protocol: zookeeper - group: test - address: 127.0.0.1:2181 \ No newline at end of file diff --git a/config/testdata/config/logger/file_log.yaml b/config/testdata/config/logger/file_log.yaml deleted file mode 100644 index 0bcfd2e5d3..0000000000 --- a/config/testdata/config/logger/file_log.yaml +++ /dev/null @@ -1,37 +0,0 @@ -# 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. - -dubbo: - registries: - nacos: - timeout: 5s - group: dev - address: nacos://127.0.0.1:8848 - zk: - protocol: zookeeper - group: test - address: 127.0.0.1:2181 - logger: - logger: - level: debug - driver: logrus - format: text - appender: console,file - file: - name: pandora.log - max-size: 1 - max-backups: 2 - max-age: 3 - compress: true diff --git a/config/testdata/config/logger/log.yaml b/config/testdata/config/logger/log.yaml deleted file mode 100644 index 5e9c0bef81..0000000000 --- a/config/testdata/config/logger/log.yaml +++ /dev/null @@ -1,51 +0,0 @@ -# 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. - -dubbo: - registries: - nacos: - timeout: 5s - group: dev - address: nacos://127.0.0.1:8848 - zk: - protocol: zookeeper - group: test - address: 127.0.0.1:2181 - logger: - zap-config: - level: debug - development: false - disable-caller: false - disable-stacktrace: false - sampling: - encoding: console - # encoder - encoder-config: - message-key: message - level-key: level - time-key: time - name-key: logger - caller-key: caller - stacktrace-key: stacktrace - level-encoder: capitalColor - time-encoder: iso8601 - duration-encoder: seconds - caller-encoder: short - name-encoder: - output-paths: - - stderr - error-output-paths: - - stderr - initial-fields: diff --git a/config/testdata/config/properties/application.properties b/config/testdata/config/properties/application.properties deleted file mode 100644 index 273dbddcfe..0000000000 --- a/config/testdata/config/properties/application.properties +++ /dev/null @@ -1,13 +0,0 @@ -dubbo.application.name=dubbo-go -dubbo.application.module=local -dubbo.application.version=1.0.0 -dubbo.application.owner=zhaoyunxing -dubbo.registries.nacos.protocol=nacos -dubbo.registries.nacos.timeout=5s -dubbo.registries.nacos.address=127.0.0.1:8848 -dubbo.registries.zk.protocol=zookeeper -dubbo.registries.zk.timeout=5s -dubbo.registries.zk.group=dev -dubbo.registries.zk.address=127.0.0.1:2181 -dubbo.services.HelloService.interface=org.dubbo.service.HelloService -dubbo.services.HelloService.registry=nacos,zk \ No newline at end of file diff --git a/config/testdata/config/protocol/application.yaml b/config/testdata/config/protocol/application.yaml deleted file mode 100644 index 9dbd0b00ea..0000000000 --- a/config/testdata/config/protocol/application.yaml +++ /dev/null @@ -1,27 +0,0 @@ -# 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. - -dubbo: - registries: - nacos: - timeout: 5s - group: dev - address: nacos://127.0.0.1:8848 - protocols: - dubbo: - name: dubbo - port: 20000 - max-server-send-msg-size: 4mib - max-server-recv-msg-size: 4mib \ No newline at end of file diff --git a/config/testdata/config/protocol/empty_application.yaml b/config/testdata/config/protocol/empty_application.yaml deleted file mode 100644 index f01c21abef..0000000000 --- a/config/testdata/config/protocol/empty_application.yaml +++ /dev/null @@ -1,22 +0,0 @@ -# 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. - -dubbo: - registries: - nacos: - timeout: 5s - group: dev - address: nacos://127.0.0.1:8848 - protocols: \ No newline at end of file diff --git a/config/testdata/config/provider/application.yaml b/config/testdata/config/provider/application.yaml deleted file mode 100644 index 4665c3ddf3..0000000000 --- a/config/testdata/config/provider/application.yaml +++ /dev/null @@ -1,32 +0,0 @@ -# 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. - -dubbo: - registries: - nacos: - timeout: 5s - group: dev - address: nacos://127.0.0.1:8848 - provider: - register: true - registry-ids: - - nacos - - zk - services: - helloService: - interface: org.dubbo.service.HelloService - registry-ids: nacos,zk - orderService: - interface: org.dubbo.service.OrderService \ No newline at end of file diff --git a/config/testdata/config/provider/empty_registry_application.yaml b/config/testdata/config/provider/empty_registry_application.yaml deleted file mode 100644 index 4412102cba..0000000000 --- a/config/testdata/config/provider/empty_registry_application.yaml +++ /dev/null @@ -1,23 +0,0 @@ -# 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. - -dubbo: - registries: - nacos: - timeout: 5s - group: dev - address: nacos://127.0.0.1:8848 - provider: - register: true \ No newline at end of file diff --git a/config/testdata/config/provider/registry_application.yaml b/config/testdata/config/provider/registry_application.yaml deleted file mode 100644 index a1604e94df..0000000000 --- a/config/testdata/config/provider/registry_application.yaml +++ /dev/null @@ -1,28 +0,0 @@ -# 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. - -dubbo: - registries: - nacos: - timeout: 3s - address: nacos://127.0.0.1:8848 - provider: - registry-ids: nacos - services: - HelloService: - interface: org.dubbo.service.HelloService - registry-ids: nacos,zk - OrderService: - interface: org.dubbo.service.OrderService \ No newline at end of file diff --git a/config/testdata/config/registry/application.yaml b/config/testdata/config/registry/application.yaml deleted file mode 100644 index 59d23e1fd8..0000000000 --- a/config/testdata/config/registry/application.yaml +++ /dev/null @@ -1,25 +0,0 @@ -# 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. - -dubbo: - registries: - nacos: - timeout: 5s - group: dev - address: nacos://127.0.0.1:8848 - zk: - protocol: zookeeper - group: test - address: 127.0.0.1:2181 \ No newline at end of file diff --git a/config/testdata/config/registry/empty_application.yaml b/config/testdata/config/registry/empty_application.yaml deleted file mode 100644 index 6e86eced56..0000000000 --- a/config/testdata/config/registry/empty_application.yaml +++ /dev/null @@ -1,17 +0,0 @@ -# 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. - -dubbo: - registries: \ No newline at end of file diff --git a/config/testdata/config/resolver/application.yaml b/config/testdata/config/resolver/application.yaml deleted file mode 100644 index 511370b8d2..0000000000 --- a/config/testdata/config/resolver/application.yaml +++ /dev/null @@ -1,51 +0,0 @@ -# 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. - -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 diff --git a/config/testdata/consumer_config.properties b/config/testdata/consumer_config.properties deleted file mode 100644 index 7a551e1130..0000000000 --- a/config/testdata/consumer_config.properties +++ /dev/null @@ -1,52 +0,0 @@ -filter= -request_timeout=100ms -connect_timeout=100ms -check=true -application.organization=ikurento.com -application.name=BDTService -application.module=dubbogo user-info client -application.version=0.0.1 -application.owner=ZX -application.environment=dev -registries.hangzhouzk.protocol=zookeeper -registries.hangzhouzk.timeout=3s -registries.hangzhouzk.address=127.0.0.1:2181 -registries.hangzhouzk.username= -registries.hangzhouzk.password= -registries.shanghaizk.protocol=zookeeper -registries.shanghaizk.timeout=3s -registries.shanghaizk.address=127.0.0.1:2182 -registries.shanghaizk.username= -registries.shanghaizk.password= -references.UserProvider.registry=hangzhouzk,shanghaizk -references.UserProvider.filter= -references.UserProvider.version=1.0 -references.UserProvider.group=as -references.UserProvider.interface=com.ikurento.user.UserProvider -references.UserProvider.url=dubbo://127.0.0.1:20000/UserProvider -references.UserProvider.cluster=failover -references.UserProvider.methods[0].name=GetUser -references.UserProvider.methods[0].retries=3 -references.UserProvider.params.serviceid=soa.com.ikurento.user.UserProvider -references.UserProvider.params.forks=5 -protocol_conf.dubbo.reconnect_interval=0 -protocol_conf.dubbo.connection_number=2 -protocol_conf.dubbo.heartbeat_period=5s -protocol_conf.dubbo.session_timeout=20s -protocol_conf.dubbo.pool_size=64 -protocol_conf.dubbo.pool_ttl=600 -protocol_conf.dubbo.gr_pool_size=1200 -protocol_conf.dubbo.queue_len=64 -protocol_conf.dubbo.queue_number=60 -protocol_conf.dubbo.getty_session_param.compress_encoding=false -protocol_conf.dubbo.getty_session_param.tcp_no_delay=true -protocol_conf.dubbo.getty_session_param.tcp_keep_alive=true -protocol_conf.dubbo.getty_session_param.keep_alive_period=120s -protocol_conf.dubbo.getty_session_param.tcp_r_buf_size=262144 -protocol_conf.dubbo.getty_session_param.tcp_w_buf_size=65536 -protocol_conf.dubbo.getty_session_param.pkg_wq_size=512 -protocol_conf.dubbo.getty_session_param.tcp_read_timeout=1s -protocol_conf.dubbo.getty_session_param.tcp_write_timeout=5s -protocol_conf.dubbo.getty_session_param.wait_timeout=1s -protocol_conf.dubbo.getty_session_param.max_msg_len=1024000 -protocol_conf.dubbo.getty_session_param.session_name=client \ No newline at end of file diff --git a/config/testdata/consumer_config.yml b/config/testdata/consumer_config.yml deleted file mode 100644 index a71ea0143d..0000000000 --- a/config/testdata/consumer_config.yml +++ /dev/null @@ -1,111 +0,0 @@ -# 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. - -# dubbo client yaml configure file - -filter: "" - -# client -request_timeout : "100ms" -# connect timeout -connect_timeout : "100ms" -check: true -# application config -application: - organization : "ikurento.com" - name : "BDTService" - module : "dubbogo user-info client" - version : "0.0.1" - owner : "ZX" - environment : "dev" - -registries : - - "hangzhouzk": - protocol: "zookeeper" - timeout : "3s" - address: "127.0.0.1:2181" - username: "" - password: "" - "shanghaizk": - protocol: "zookeeper" - timeout : "3s" - address: "127.0.0.1:2182" - username: "" - password: "" - -references: - "UserProvider": - registry-ids: "hangzhouzk,shanghaizk" - filter: "" - protocol : "dubbo" - version: "1.0" - group: "as" - interface : "com.ikurento.user.UserProvider" - url: "dubbo://127.0.0.1:20000/UserProvider" - cluster: "failover" - timeout: "3s" - methods : - - name: "GetUser" - retries: "3" - timeout: "5s" - params: - "serviceid": - "soa.com.ikurento.user.UserProvider" - "forks": 5 - -shutdown_conf: - timeout: 60s - step-timeout: 10s - -protocol_conf: - # when you choose the Dubbo protocol, the following configuration takes effect - dubbo: - reconnect_interval: 0 - # reconnect_interval is the actual number of connections a session can use - connection_number: 2 - # heartbeat_period is heartbeat interval between server and client connection. - # Effective by client configuration - heartbeat_period: "30s" - # when the session is inactive for more than session_timeout, the session may be closed - session_timeout: "30s" - # a reference has the size of the session connection pool - # that is the maximum number of sessions it may have - pool_size: 4 - # dubbo-go uses getty as the network connection library. - # The following is the relevant configuration of getty - pool_ttl: 600 - # gr_pool_size is recommended to be set to [cpu core number] * 100 - gr_pool_size: 1200 - # queue_len is recommended to be set to 64 or 128 - queue_len: 64 - # queue_number is recommended to be set to gr_pool_size / 20 - queue_number: 60 - # dubbo-go uses getty as the network connection library. - # The following is the relevant configuration of getty - getty_session_param: - compress_encoding: false - tcp_no_delay: true - tcp_keep_alive: true - keep_alive_period: "120s" - tcp_r_buf_size: 262144 - tcp_w_buf_size: 65536 - tcp_read_timeout: "1s" - tcp_write_timeout: "5s" - wait_timeout: "1s" - # maximum len of data per request - # this refers to the total amount of data requested or returned - max_msg_len: 1024000 - session_name: "client" diff --git a/config/testdata/consumer_config_with_configcenter.yml b/config/testdata/consumer_config_with_configcenter.yml deleted file mode 100644 index caff614e94..0000000000 --- a/config/testdata/consumer_config_with_configcenter.yml +++ /dev/null @@ -1,58 +0,0 @@ -# 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. - -# dubbo client yaml configure file - -application: - name: "BDTService" -config_center: - protocol: "mock" - address: "127.0.0.1" -references: - "UserProvider": - registry-ids: "hangzhouzk,shanghaizk" - filter: "" - protocol : "dubbo" - interface : "com.ikurento.user.UserProvider" - url: "dubbo://127.0.0.1:20000/UserProvider" - cluster: "failover" - methods : - - name: "GetUser" - retries: "3" - -shutdown_conf: - timeout: 60s - step-timeout: 10s - -protocol_conf: - dubbo: - reconnect_interval: 0 - connection_number: 2 - heartbeat_period: "5s" - session_timeout: "20s" - pool_size: 64 - pool_ttl: 600 - getty_session_param: - compress_encoding: false - tcp_no_delay: true - tcp_keep_alive: true - keep_alive_period: "120s" - tcp_r_buf_size: 262144 - tcp_w_buf_size: 65536 - tcp_read_timeout: "1s" - tcp_write_timeout: "5s" - wait_timeout: "1s" - max_msg_len: 16498688 - session_name: "client" diff --git a/config/testdata/consumer_config_withoutProtocol.yml b/config/testdata/consumer_config_withoutProtocol.yml deleted file mode 100644 index 817212b9ff..0000000000 --- a/config/testdata/consumer_config_withoutProtocol.yml +++ /dev/null @@ -1,96 +0,0 @@ -# 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. - -# dubbo client yaml configure file - -filter: "" - -# client -request_timeout : "100ms" -# connect timeout -connect_timeout : "100ms" -check: true -# application config -application: - organization : "ikurento.com" - name : "BDTService" - module : "dubbogo user-info client" - version : "0.0.1" - owner : "ZX" - environment : "dev" - -registries : - - "hangzhouzk": - protocol: "zookeeper" - timeout : "3s" - address: "127.0.0.1:2181" - username: "" - password: "" - "shanghaizk": - protocol: "zookeeper" - timeout : "3s" - address: "127.0.0.1:2182" - username: "" - password: "" - -references: - "UserProvider": - registry-ids: "hangzhouzk,shanghaizk" - filter: "" - version: "1.0" - group: "as" - interface : "com.ikurento.user.UserProvider" - url: "dubbo://127.0.0.1:20000/UserProvider" - cluster: "failover" - methods : - - name: "GetUser" - retries: 3 - params: - "serviceid": - "soa.com.ikurento.user.UserProvider" - "forks": 5 - -shutdown_conf: - timeout: 60s - step-timeout: 10s - -protocol_conf: - dubbo: - reconnect_interval: 0 - connection_number: 2 - heartbeat_period: "5s" - session_timeout: "20s" - pool_size: 64 - pool_ttl: 600 - # gr_pool_size is recommended to be set to [cpu core number] * 100 - gr_pool_size: 1200 - # queue_len is recommended to be set to 64 or 128 - queue_len: 64 - # queue_number is recommended to be set to gr_pool_size / 20 - queue_number: 60 - getty_session_param: - compress_encoding: false - tcp_no_delay: true - tcp_keep_alive: true - keep_alive_period: "120s" - tcp_r_buf_size: 262144 - tcp_w_buf_size: 65536 - tcp_read_timeout: "1s" - tcp_write_timeout: "5s" - wait_timeout: "1s" - max_msg_len: 16498688 - session_name: "client" - diff --git a/config/testdata/provider_config.properties b/config/testdata/provider_config.properties deleted file mode 100644 index 6a1e96409d..0000000000 --- a/config/testdata/provider_config.properties +++ /dev/null @@ -1,58 +0,0 @@ -filter= -application.organization=ikurento.com -application.name=BDTService -application.module=dubbogo user-info server -application.version=0.0.1 -application.owner=ZX -application.environment=dev -registries.hangzhouzk.protocol=zookeeper -registries.hangzhouzk.timeout=3s -registries.hangzhouzk.address=127.0.0.1:2181 -registries.hangzhouzk.username= -registries.hangzhouzk.password= -registries.shanghaizk.protocol=zookeeper -registries.shanghaizk.timeout=3s -registries.shanghaizk.address=127.0.0.1:2182 -registries.shanghaizk.username= -registries.shanghaizk.password= -services.UserProvider.registry=hangzhouzk,shanghaizk -services.UserProvider.filter= -services.UserProvider.tps.limiter=default -services.UserProvider.tps.limit.interval=60000 -services.UserProvider.tps.limit.rate=200 -services.UserProvider.tps.limit.strategy=slidingWindow -services.UserProvider.tps.limit.rejected.handler=default -services.UserProvider.execute.limit=200 -services.UserProvider.execute.limit.rejected.handler=default -services.UserProvider.protocol=dubbo -services.UserProvider.interface=com.ikurento.user.UserProvider -services.UserProvider.loadbalance=random -services.UserProvider.version=1.0 -services.UserProvider.group=as -services.UserProvider.warmup=100 -services.UserProvider.cluster=failover -services.UserProvider.methods[0].name=GetUser -services.UserProvider.methods[0].retries=1 -services.UserProvider.methods[0].loadbalance=random -services.UserProvider.methods[0].execute.limit=200 -services.UserProvider.methods[0].execute.limit.rejected.handler=default -protocols.dubbo.name=dubbo -protocols.dubbo.ip=127.0.0.1 -protocols.dubbo.port=20000 -protocol_conf.dubbo.session_number=700 -protocol_conf.dubbo.session_timeout=20s -protocol_conf.dubbo.gr_pool_size=120 -protocol_conf.dubbo.queue_len=64 -protocol_conf.dubbo.queue_number=6 -protocol_conf.dubbo.getty_session_param.compress_encoding=false -protocol_conf.dubbo.getty_session_param.tcp_no_delay=true -protocol_conf.dubbo.getty_session_param.tcp_keep_alive=true -protocol_conf.dubbo.getty_session_param.keep_alive_period=120s -protocol_conf.dubbo.getty_session_param.tcp_r_buf_size=262144 -protocol_conf.dubbo.getty_session_param.tcp_w_buf_size=65536 -protocol_conf.dubbo.getty_session_param.pkg_wq_size=512 -protocol_conf.dubbo.getty_session_param.tcp_read_timeout=1s -protocol_conf.dubbo.getty_session_param.tcp_write_timeout=5s -protocol_conf.dubbo.getty_session_param.wait_timeout=1s -protocol_conf.dubbo.getty_session_param.max_msg_len=1024000 -protocol_conf.dubbo.getty_session_param.session_name=server \ No newline at end of file diff --git a/config/testdata/provider_config.yml b/config/testdata/provider_config.yml deleted file mode 100644 index a0e0adef82..0000000000 --- a/config/testdata/provider_config.yml +++ /dev/null @@ -1,114 +0,0 @@ -# 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. - -# dubbo server yaml configure file - -filter: "" -# application config -application: - organization : "ikurento.com" - name : "BDTService" - module : "dubbogo user-info server" - version : "0.0.1" - owner : "ZX" - environment : "dev" - -registries : - "hangzhouzk": - protocol: "zookeeper" - timeout : "3s" - address: "127.0.0.1:2181" - username: "" - password: "" - "shanghaizk": - protocol: "zookeeper" - timeout : "3s" - address: "127.0.0.1:2182" - username: "" - password: "" - - -services: - "UserProvider": - registry-ids: "hangzhouzk,shanghaizk" - filter: "" - # the name of limiter - tps.limiter: "default" - # the time unit of interval is ms - tps.limit.interval: 60000 - tps.limit.rate: 200 - # the name of strategy - tps.limit.strategy: "slidingWindow" - # the name of RejectedExecutionHandler - tps.limit.rejected.handler: "default" - # the concurrent request limitation of this service - # if the value < 0, it will not be limited. - execute.limit: "200" - # the name of RejectedExecutionHandler - execute.limit.rejected.handler: "default" - protocol : "dubbo" - # equivalent to interface of dubbo.xml - interface : "com.ikurento.user.UserProvider" - loadbalance: "random" - version: "1.0" - group: "as" - warmup: "100" - cluster: "failover" - methods: - - name: "GetUser" - retries: 1 - loadbalance: "random" - # the concurrent request limitation of this method - # if the value < 0, it will not be limited. - execute.limit: "200" - # the name of RejectedExecutionHandler - execute.limit.rejected.handler: "default" - -protocols: - "dubbo": - name: "dubbo" - # while using dubbo protocol, ip cannot is 127.0.0.1, because client of java-dubbo will get 'connection refuse' - ip : "127.0.0.1" - port : 20000 - #- name: "jsonrpc" - # ip: "127.0.0.1" - # port: 20001 - -shutdown_conf: - timeout: 60s - step-timeout: 10s - -protocol_conf: - dubbo: - session_number: 700 - session_timeout: "20s" - # gr_pool_size is recommended to be set to [cpu core number] * 10 - gr_pool_size: 120 - # queue_len is recommended to be set to 64 or 128 - queue_len: 64 - # queue_number is recommended to be set to gr_pool_size / 20 - queue_number: 6 - getty_session_param: - compress_encoding: false - tcp_no_delay: true - tcp_keep_alive: true - keep_alive_period: "120s" - tcp_r_buf_size: 262144 - tcp_w_buf_size: 65536 - tcp_read_timeout: "1s" - tcp_write_timeout: "5s" - wait_timeout: "1s" - max_msg_len: 16498688 - session_name: "server" diff --git a/config/testdata/provider_config_withoutProtocol.yml b/config/testdata/provider_config_withoutProtocol.yml deleted file mode 100644 index 5e17d1e5f6..0000000000 --- a/config/testdata/provider_config_withoutProtocol.yml +++ /dev/null @@ -1,94 +0,0 @@ -# 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. - -# dubbo server yaml configure file - -filter: "" -# application config -application: - organization : "ikurento.com" - name : "BDTService" - module : "dubbogo user-info server" - version : "0.0.1" - owner : "ZX" - environment : "dev" - -registries : - "hangzhouzk": - protocol: "zookeeper" - timeout : "3s" - address: "127.0.0.1:2181" - username: "" - password: "" - "shanghaizk": - protocol: "zookeeper" - timeout : "3s" - address: "127.0.0.1:2182" - username: "" - password: "" - - -services: - "UserProvider": - registry-ids: "hangzhouzk,shanghaizk" - filter: "" - # equivalent to interface of dubbo.xml - interface : "com.ikurento.user.UserProvider" - loadbalance: "random" - version: "1.0" - group: "as" - warmup: "100" - cluster: "failover" - methods: - - name: "GetUser" - retries: 1 - loadbalance: "random" - -protocols: - "dubbo": - name: "dubbo" - # while using dubbo protocol, ip cannot is 127.0.0.1, because client of java-dubbo will get 'connection refuse' - ip : "127.0.0.1" - port : 20000 - #- name: "jsonrpc" - # ip: "127.0.0.1" - # port: 20001 - -shutdown_conf: - timeout: 60s - step-timeout: 10s - -protocol_conf: - dubbo: - session_number: 700 - session_timeout: "20s" - # gr_pool_size is recommended to be set to [cpu core number] * 10 - gr_pool_size: 120 - # queue_len is recommended to be set to 64 or 128 - queue_len: 64 - # queue_number is recommended to be set to gr_pool_size / 20 - queue_number: 6 - getty_session_param: - compress_encoding: false - tcp_no_delay: true - tcp_keep_alive: true - keep_alive_period: "120s" - tcp_r_buf_size: 262144 - tcp_w_buf_size: 65536 - tcp_read_timeout: "1s" - tcp_write_timeout: "5s" - wait_timeout: "1s" - max_msg_len: 16498688 - session_name: "server" diff --git a/config/testdata/root_config_test.yml b/config/testdata/root_config_test.yml deleted file mode 100644 index 4f8b4cd278..0000000000 --- a/config/testdata/root_config_test.yml +++ /dev/null @@ -1,38 +0,0 @@ -# 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. - -dubbo: - registries: - demoZK: - protocol: zookeeper - timeout: 11s - address: 127.0.0.1:2181 - protocols: - triple: - name: tri - port: 20000 - provider: - registry-ids: - - demoZK - services: - GreeterProvider: - protocol-ids: triple - interface: com.apache.dubbo.sample.basic.IGreeter # must be compatible with grpc or dubbo-java - consumer: - request-timeout: 6s - references: - GreeterClientImpl: - protocol: tri - interface: com.apache.dubbo.HelloService # must be compatible with grpc or dubbo-java \ No newline at end of file diff --git a/config/testdata/router_config_dest_rule.yml b/config/testdata/router_config_dest_rule.yml deleted file mode 100644 index 9f43c55965..0000000000 --- a/config/testdata/router_config_dest_rule.yml +++ /dev/null @@ -1,32 +0,0 @@ -# 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. - -apiVersion: service.dubbo.apache.org/v1alpha1 -kind: DestinationRule -metadata: - name: demo-route -spec: - host: demo - subsets: - - name: v1 - labels: - sigma.ali/mg: v1-host - generic: false - - name: v2 - labels: - generic: false - - name: v3 - labels: - sigma.ali/mg: v3-host \ No newline at end of file diff --git a/config/testdata/router_config_virtual_service.yml b/config/testdata/router_config_virtual_service.yml deleted file mode 100644 index d460a34c0e..0000000000 --- a/config/testdata/router_config_virtual_service.yml +++ /dev/null @@ -1,185 +0,0 @@ -# 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. - -apiVersion: service.dubbo.apache.org/v1alpha1 -kind: VirtualService -metadata: - name: demo-route -spec: - hosts: - - demo # 统一定义为应用名 - dubbo: - - service: - - exact: com.taobao.hsf.demoService:1.0.0 - - exact: com.taobao.hsf.demoService:2.0.0 - routedetail: - - name: sayHello-String-method-route - match: - - method: - name_match: - exact: "sayHello" - # argp: - # - string - route: - - destination: - host: demo - subset: v1 - fallback: - destination: - host: demo - subset: v2 - fallback: - destination: - host: demo - subset: v3 - - - name: sayHello-method-route - match: - - method: - name_match: - exact: "s-method" - route: - - destination: - host: demo - subset: v2 - fallback: - destination: - host: demo - subset: v3 - - name: some-method-route - match: - - method: - name_match: - exact: "some-method" - route: - - destination: - host: demo - subset: v4 - -# - name: interface-route -# route: -# - destination: -# host: demo -# subset: v3 - - name: final - match: - - method: - name_match: - exact: "GetUser" - - route: - - destination: - host: demo - subset: v1 - fallback: - destination: - host: demo - subset: v2 - fallback: - destination: - host: demo - subset: v3 - - destination: - host: demo - subset: v3 - fallback: - destination: - host: demo - subset: v2 - fallback: - destination: - host: demo - subset: v1 - - service: - - exact: com.taobao.hsf.demoService:1.0.0 - - exact: org.apache.dubbo.UserProvider - routedetail: - - name: sayHello-String-method-route - match: - - method: - name_match: - exact: "sayHello" - # argp: - # - string - route: - - destination: - host: demo - subset: v1 - fallback: - destination: - host: demo - subset: v2 - fallback: - destination: - host: demo - subset: v3 - - - name: sayHello-method-route - match: - - method: - name_match: - exact: "s-method" - route: - - destination: - host: demo - subset: v2 - fallback: - destination: - host: demo - subset: v3 - - name: some-method-route - match: - - method: - name_match: - exact: "some-method" - route: - - destination: - host: demo - subset: v4 - - # - name: interface-route - # route: - # - destination: - # host: demo - # subset: v3 - - name: final - match: - - method: - name_match: - exact: "GetUser" - - route: - - destination: - host: demo - subset: v1 - fallback: - destination: - host: demo - subset: v2 - fallback: - destination: - host: demo - subset: v3 - - destination: - host: demo - subset: v3 - fallback: - destination: - host: demo - subset: v2 - fallback: - destination: - host: demo - subset: v1 \ No newline at end of file diff --git a/config/tls_config.go b/config/tls_config.go deleted file mode 100644 index 2802a23b5b..0000000000 --- a/config/tls_config.go +++ /dev/null @@ -1,146 +0,0 @@ -/* - * 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 ( - "crypto/tls" - "crypto/x509" - "errors" - "os" -) - -import ( - "dubbo.apache.org/dubbo-go/v3/common/constant" -) - -// TLSConfig tls config -type TLSConfig struct { - CACertFile string `yaml:"ca-cert-file" json:"ca-cert-file" property:"ca-cert-file"` - TLSCertFile string `yaml:"tls-cert-file" json:"tls-cert-file" property:"tls-cert-file"` - TLSKeyFile string `yaml:"tls-key-file" json:"tls-key-file" property:"tls-key-file"` - TLSServerName string `yaml:"tls-server-name" json:"tls-server-name" property:"tls-server-name"` -} - -func (t *TLSConfig) Prefix() string { - return constant.TLSConfigPrefix -} - -// GetServerTlsConfig build server tls config from TLSConfig -func GetServerTlsConfig(opt *TLSConfig) (*tls.Config, error) { - //no TLS - if opt.TLSCertFile == "" && opt.TLSKeyFile == "" { - return nil, nil - } - var ca *x509.CertPool - cfg := &tls.Config{} - //need mTLS - if opt.CACertFile != "" { - ca = x509.NewCertPool() - caBytes, err := os.ReadFile(opt.CACertFile) - if err != nil { - return nil, err - } - if ok := ca.AppendCertsFromPEM(caBytes); !ok { - return nil, errors.New("failed to parse root certificate") - } - cfg.ClientAuth = tls.RequireAndVerifyClientCert - cfg.ClientCAs = ca - } - cert, err := tls.LoadX509KeyPair(opt.TLSCertFile, opt.TLSKeyFile) - if err != nil { - return nil, err - } - cfg.Certificates = []tls.Certificate{cert} - cfg.ServerName = opt.TLSServerName - - return cfg, nil -} - -// GetClientTlsConfig build client tls config from TLSConfig -func GetClientTlsConfig(opt *TLSConfig) (*tls.Config, error) { - //no TLS - if opt.CACertFile == "" { - return nil, nil - } - cfg := &tls.Config{ - ServerName: opt.TLSServerName, - } - ca := x509.NewCertPool() - caBytes, err := os.ReadFile(opt.CACertFile) - if err != nil { - return nil, err - } - if ok := ca.AppendCertsFromPEM(caBytes); !ok { - return nil, errors.New("failed to parse root certificate") - } - cfg.RootCAs = ca - //need mTls - if opt.TLSCertFile != "" { - var cert tls.Certificate - cert, err = tls.LoadX509KeyPair(opt.TLSCertFile, opt.TLSKeyFile) - if err != nil { - return nil, err - } - cfg.Certificates = []tls.Certificate{cert} - } - return cfg, err -} - -type TLSConfigBuilder struct { - tlsConfig *TLSConfig -} - -func NewTLSConfigBuilder() *TLSConfigBuilder { - return &TLSConfigBuilder{} -} - -func (tcb *TLSConfigBuilder) SetCACertFile(caCertFile string) *TLSConfigBuilder { - if tcb.tlsConfig == nil { - tcb.tlsConfig = &TLSConfig{} - } - tcb.tlsConfig.CACertFile = caCertFile - return tcb -} - -func (tcb *TLSConfigBuilder) SetTLSCertFile(tlsCertFile string) *TLSConfigBuilder { - if tcb.tlsConfig == nil { - tcb.tlsConfig = &TLSConfig{} - } - tcb.tlsConfig.TLSCertFile = tlsCertFile - return tcb -} - -func (tcb *TLSConfigBuilder) SetTLSKeyFile(tlsKeyFile string) *TLSConfigBuilder { - if tcb.tlsConfig == nil { - tcb.tlsConfig = &TLSConfig{} - } - tcb.tlsConfig.TLSKeyFile = tlsKeyFile - return tcb -} - -func (tcb *TLSConfigBuilder) SetTLSServerName(tlsServerName string) *TLSConfigBuilder { - if tcb.tlsConfig == nil { - tcb.tlsConfig = &TLSConfig{} - } - tcb.tlsConfig.TLSServerName = tlsServerName - return tcb -} - -func (tcb *TLSConfigBuilder) Build() *TLSConfig { - return tcb.tlsConfig -} diff --git a/config/tls_config_test.go b/config/tls_config_test.go deleted file mode 100644 index c533fc42cd..0000000000 --- a/config/tls_config_test.go +++ /dev/null @@ -1,45 +0,0 @@ -/* - * 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/stretchr/testify/assert" -) - -import ( - "dubbo.apache.org/dubbo-go/v3/common/constant" -) - -func TestNewTLSConfigBuilder(t *testing.T) { - config := NewTLSConfigBuilder(). - SetCACertFile("ca_cert_file"). - SetTLSKeyFile("tls_key_file"). - SetTLSServerName("tls_server_name"). - SetTLSCertFile("tls_cert_file"). - Build() - assert.Equal(t, "ca_cert_file", config.CACertFile) - assert.Equal(t, "tls_cert_file", config.TLSCertFile) - assert.Equal(t, "tls_server_name", config.TLSServerName) - assert.Equal(t, "tls_key_file", config.TLSKeyFile) - assert.Equal(t, constant.TLSConfigPrefix, config.Prefix()) - -} diff --git a/config/tracing_config.go b/config/tracing_config.go deleted file mode 100644 index ba85fe5c3b..0000000000 --- a/config/tracing_config.go +++ /dev/null @@ -1,47 +0,0 @@ -/* - * 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 ( - "github.com/creasty/defaults" -) - -import ( - "dubbo.apache.org/dubbo-go/v3/common/constant" -) - -// TracingConfig is the configuration of the tracing. -// Deprecated: It's designed to be replaced with config.OtelConfig -type TracingConfig struct { - Name string `default:"jaeger" yaml:"name" json:"name,omitempty" property:"name"` // jaeger or zipkin(todo) - ServiceName string `yaml:"serviceName" json:"serviceName,omitempty" property:"serviceName"` - Address string `yaml:"address" json:"address,omitempty" property:"address"` - UseAgent *bool `default:"false" yaml:"use-agent" json:"use-agent,omitempty" property:"use-agent"` -} - -// Prefix dubbo.router -func (TracingConfig) Prefix() string { - return constant.TracingConfigPrefix -} - -func (c *TracingConfig) Init() error { - if err := defaults.Set(c); err != nil { - return err - } - return verify(c) -} diff --git a/config/tracing_config_test.go b/config/tracing_config_test.go deleted file mode 100644 index ab89f4c0e8..0000000000 --- a/config/tracing_config_test.go +++ /dev/null @@ -1,41 +0,0 @@ -/* - * 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/stretchr/testify/assert" - "github.com/stretchr/testify/require" -) - -import ( - "dubbo.apache.org/dubbo-go/v3/common/constant" -) - -func TestTracingConfig(t *testing.T) { - - tracing := &TracingConfig{} - err := tracing.Init() - require.NoError(t, err) - assert.Equal(t, constant.TracingConfigPrefix, tracing.Prefix()) - assert.Equal(t, "jaeger", tracing.Name) - assert.False(t, *tracing.UseAgent) -} diff --git a/config/triple_config.go b/config/triple_config.go deleted file mode 100644 index 5a05611120..0000000000 --- a/config/triple_config.go +++ /dev/null @@ -1,32 +0,0 @@ -/* - * 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 - -// TripleConfig represents the config of triple protocol -type TripleConfig struct { - // MaxServerSendMsgSize max size of server send message, 1mb=1000kb=1000000b 1mib=1024kb=1048576b. - // more detail to see https://pkg.go.dev/github.com/dustin/go-humanize#pkg-constants - MaxServerSendMsgSize string `yaml:"max-server-send-msg-size" json:"max-server-send-msg-size,omitempty"` - // MaxServerRecvMsgSize max size of server receive message - MaxServerRecvMsgSize string `yaml:"max-server-recv-msg-size" json:"max-server-recv-msg-size,omitempty"` - - Http3 *Http3Config `yaml:"http3" json:"http3,omitempty" property:"http3"` - - KeepAliveInterval string `yaml:"keep-alive-interval" json:"keep-alive-interval,omitempty" property:"keep-alive-interval"` - KeepAliveTimeout string `yaml:"keep-alive-timeout" json:"keep-alive-timeout,omitempty" property:"keep-alive-timeout"` -}