feat: refactor client module to resolve circular dependencies (#2399)
diff --git a/client/client.go b/client/client.go
index 9619321..ab93c37 100644
--- a/client/client.go
+++ b/client/client.go
@@ -1,3 +1,20 @@
+/*
+ * 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 client
import (
@@ -98,10 +115,7 @@
}
func NewClient(opts ...ReferenceOption) (*Client, error) {
- // get default RootConfigs
- //rootCfg := config.NewRootConfigBuilder().Build()
- //rootCfg.Init()
- // todo: create a default ReferenceConfig
+ // todo(DMwangnima): create a default ReferenceConfig
newRefCfg := &ReferenceConfig{}
if err := newRefCfg.Init(opts...); err != nil {
return nil, err
diff --git a/client/compat.go b/client/compat.go
new file mode 100644
index 0000000..f03592c
--- /dev/null
+++ b/client/compat.go
@@ -0,0 +1,62 @@
+/*
+ * 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 client
+
+import (
+ commonCfg "dubbo.apache.org/dubbo-go/v3/common/config"
+ "dubbo.apache.org/dubbo-go/v3/config"
+ "dubbo.apache.org/dubbo-go/v3/registry"
+)
+
+// these functions are used to resolve circular dependencies temporarily.
+// please refer to issue(https://github.com/apache/dubbo-go/issues/2377)
+// todo(DMwangnima): remove these functions when refactoring dubbo-go
+func compatApplicationConfig(c *commonCfg.ApplicationConfig) *config.ApplicationConfig {
+ return &config.ApplicationConfig{
+ Organization: c.Organization,
+ Name: c.Name,
+ Module: c.Module,
+ Group: c.Group,
+ Version: c.Version,
+ Owner: c.Owner,
+ Environment: c.Environment,
+ MetadataType: c.MetadataType,
+ Tag: c.Tag,
+ }
+}
+
+func compatRegistryConfig(c *registry.RegistryConfig) *config.RegistryConfig {
+ return &config.RegistryConfig{
+ Protocol: c.Protocol,
+ Timeout: c.Timeout,
+ Group: c.Group,
+ Namespace: c.Namespace,
+ TTL: c.TTL,
+ Address: c.Address,
+ Username: c.Username,
+ Password: c.Password,
+ Simplified: c.Simplified,
+ Preferred: c.Preferred,
+ Zone: c.Zone,
+ Weight: c.Weight,
+ Params: c.Params,
+ RegistryType: c.RegistryType,
+ UseAsMetaReport: c.UseAsMetaReport,
+ UseAsConfigCenter: c.UseAsConfigCenter,
+ }
+}
diff --git a/client/options.go b/client/options.go
index cea2e48..aac3202 100644
--- a/client/options.go
+++ b/client/options.go
@@ -1,3 +1,20 @@
+/*
+ * 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 client
import (
diff --git a/client/reference_config.go b/client/reference_config.go
index ca75dd7..6e52dae 100644
--- a/client/reference_config.go
+++ b/client/reference_config.go
@@ -40,6 +40,7 @@
commonCfg "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"
"dubbo.apache.org/dubbo-go/v3/protocol"
"dubbo.apache.org/dubbo-go/v3/protocol/protocolwrapper"
"dubbo.apache.org/dubbo-go/v3/proxy"
@@ -84,9 +85,11 @@
adaptiveService bool
proxyFactory string
- application *commonCfg.ApplicationConfig
+ application *commonCfg.ApplicationConfig
+ applicationCompat *config.ApplicationConfig
- registries map[string]*registry.RegistryConfig
+ registries map[string]*registry.RegistryConfig
+ registriesCompat map[string]*config.RegistryConfig
}
func (rc *ReferenceConfig) Prefix() string {
@@ -94,30 +97,47 @@
}
func (rc *ReferenceConfig) Init(opts ...ReferenceOption) error {
- for _, method := range rc.Methods {
- if err := method.Init(); err != nil {
- return err
- }
- }
if err := defaults.Set(rc); err != nil {
return err
}
for _, opt := range opts {
opt(rc)
}
- if rc.application != nil {
- rc.metaDataType = rc.application.MetadataType
- if rc.Group == "" {
- rc.Group = rc.application.Group
- }
- if rc.Version == "" {
- rc.Version = rc.application.Version
+ // init method
+ for _, method := range rc.Methods {
+ if err := method.Init(); err != nil {
+ return err
}
}
+ // init application
+ if rc.application != nil {
+ rc.applicationCompat = compatApplicationConfig(rc.application)
+ if err := rc.applicationCompat.Init(); err != nil {
+ return err
+ }
+ rc.metaDataType = rc.applicationCompat.MetadataType
+ if rc.Group == "" {
+ rc.Group = rc.applicationCompat.Group
+ }
+ if rc.Version == "" {
+ rc.Version = rc.applicationCompat.Version
+ }
+ }
+ // init cluster
if rc.Cluster == "" {
rc.Cluster = "failover"
}
// todo: move to registry package
+ // init registries
+ if rc.registries != nil {
+ rc.registriesCompat = make(map[string]*config.RegistryConfig)
+ for key, reg := range rc.registries {
+ rc.registriesCompat[key] = compatRegistryConfig(reg)
+ if err := rc.registriesCompat[key].Init(); err != nil {
+ return err
+ }
+ }
+ }
rc.RegistryIDs = commonCfg.TranslateIds(rc.RegistryIDs)
return commonCfg.Verify(rc)
@@ -158,16 +178,20 @@
rc.URL = "tri://" + rc.ProvidedBy + "." + podNamespace + constant.SVC + clusterDomain + ":" + strconv.Itoa(meshPort)
}
-// Refer retrieves invokers from urls.
-func (rc *ReferenceConfig) Refer(srv interface{}) {
- rc.refer(nil, srv)
+// ReferWithService retrieves invokers from urls.
+func (rc *ReferenceConfig) ReferWithService(srv common.RPCService) {
+ rc.refer(srv, nil)
}
func (rc *ReferenceConfig) ReferWithInfo(info *ClientInfo) {
- rc.refer(info, nil)
+ rc.refer(nil, info)
}
-func (rc *ReferenceConfig) refer(info *ClientInfo, srv interface{}) {
+func (rc *ReferenceConfig) ReferWithServiceAndInfo(srv common.RPCService, info *ClientInfo) {
+ rc.refer(srv, info)
+}
+
+func (rc *ReferenceConfig) refer(srv common.RPCService, info *ClientInfo) {
var methods []string
if info != nil {
rc.InterfaceName = info.InterfaceName
@@ -236,7 +260,7 @@
}
}
} else { // use registry configs
- rc.urls = registry.LoadRegistries(rc.RegistryIDs, rc.registries, common.CONSUMER)
+ rc.urls = config.LoadRegistries(rc.RegistryIDs, rc.registriesCompat, common.CONSUMER)
// set url to regURLs
for _, regURL := range rc.urls {
regURL.SubURL = cfgURL
@@ -382,14 +406,14 @@
urlMap.Set(constant.StickyKey, strconv.FormatBool(rc.Sticky))
// applicationConfig info
- if rc.application != nil {
- urlMap.Set(constant.ApplicationKey, rc.application.Name)
- urlMap.Set(constant.OrganizationKey, rc.application.Organization)
- urlMap.Set(constant.NameKey, rc.application.Name)
- urlMap.Set(constant.ModuleKey, rc.application.Module)
- urlMap.Set(constant.AppVersionKey, rc.application.Version)
- urlMap.Set(constant.OwnerKey, rc.application.Owner)
- urlMap.Set(constant.EnvironmentKey, rc.application.Environment)
+ if rc.applicationCompat != nil {
+ urlMap.Set(constant.ApplicationKey, rc.applicationCompat.Name)
+ urlMap.Set(constant.OrganizationKey, rc.applicationCompat.Organization)
+ urlMap.Set(constant.NameKey, rc.applicationCompat.Name)
+ urlMap.Set(constant.ModuleKey, rc.applicationCompat.Module)
+ urlMap.Set(constant.AppVersionKey, rc.applicationCompat.Version)
+ urlMap.Set(constant.OwnerKey, rc.applicationCompat.Owner)
+ urlMap.Set(constant.EnvironmentKey, rc.applicationCompat.Environment)
}
// filter
diff --git a/common/config/application.go b/common/config/application.go
index 246346b..eaebd65 100644
--- a/common/config/application.go
+++ b/common/config/application.go
@@ -17,15 +17,7 @@
package config
-import (
- "github.com/creasty/defaults"
-
- "github.com/pkg/errors"
-)
-
-import (
- "dubbo.apache.org/dubbo-go/v3/common/constant"
-)
+// todo(DMwangnima): think about the location of this type of configuration.
// ApplicationConfig is a configuration for current applicationConfig, whether the applicationConfig is a provider or a consumer
type ApplicationConfig struct {
@@ -41,29 +33,6 @@
Tag string `yaml:"tag" json:"tag,omitempty" property:"tag"`
}
-// 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
- }
- return nil
-}
-
-func (ac *ApplicationConfig) check() error {
- if err := defaults.Set(ac); err != nil {
- return err
- }
- return Verify(ac)
-}
-
type ApplicationOption func(*ApplicationConfig)
func WithOrganization(organization string) ApplicationOption {
diff --git a/config/application_config.go b/config/application_config.go
index 88a42c9..60ea32f 100644
--- a/config/application_config.go
+++ b/config/application_config.go
@@ -18,15 +18,58 @@
package config
import (
- commonCfg "dubbo.apache.org/dubbo-go/v3/common/config"
+ "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 `default:"dubbo.io" 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"`
+}
+
+// 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
+ }
+ 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: &commonCfg.ApplicationConfig{}}
+ return &ApplicationConfigBuilder{application: &ApplicationConfig{}}
}
type ApplicationConfigBuilder struct {
- application *commonCfg.ApplicationConfig
+ application *ApplicationConfig
}
func (acb *ApplicationConfigBuilder) SetOrganization(organization string) *ApplicationConfigBuilder {
@@ -64,6 +107,6 @@
return acb
}
-func (acb *ApplicationConfigBuilder) Build() *commonCfg.ApplicationConfig {
+func (acb *ApplicationConfigBuilder) Build() *ApplicationConfig {
return acb.application
}
diff --git a/config/consumer_config.go b/config/consumer_config.go
index fbcf5f3..c49811f 100644
--- a/config/consumer_config.go
+++ b/config/consumer_config.go
@@ -32,7 +32,6 @@
)
import (
- "dubbo.apache.org/dubbo-go/v3/client"
"dubbo.apache.org/dubbo-go/v3/common"
"dubbo.apache.org/dubbo-go/v3/common/constant"
)
@@ -43,21 +42,19 @@
// 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]*client.ReferenceConfig `yaml:"references" json:"references,omitempty" property:"references"`
- TracingKey string `yaml:"tracing-key" json:"tracing-key" property:"tracing-key"`
- FilterConf interface{} `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"`
+ 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 interface{} `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
-
- refOpts []client.ReferenceOption
}
// Prefix dubbo.consumer
@@ -92,20 +89,6 @@
break
}
}
-
- cc.refOpts = []client.ReferenceOption{
- client.WithFilter(cc.Filter),
- client.WithRegistryIDs(cc.RegistryIDs),
- client.WithProtocol(cc.Protocol),
- client.WithTracingKey(cc.TracingKey),
- client.WithCheck(cc.Check),
- client.WithMeshEnabled(cc.MeshEnabled),
- client.WithAdaptiveService(cc.AdaptiveService),
- client.WithProxyFactory(cc.ProxyFactory),
- client.WithApplication(rc.Application),
- client.WithRegistries(rc.Registries),
- }
-
for key, referenceConfig := range cc.References {
if referenceConfig.InterfaceName == "" {
reference := GetConsumerService(key)
@@ -122,11 +105,10 @@
referenceConfig.InterfaceName = triplePBService.XXX_InterfaceName()
}
}
- if err := referenceConfig.Init(cc.refOpts...); err != nil {
+ if err := referenceConfig.Init(rc); err != nil {
return err
}
}
- // todo: maybe defaults.Set function should be moved to upper place?
if err := defaults.Set(cc); err != nil {
return err
}
@@ -155,24 +137,14 @@
// use interface name defined by pb
refConfig.InterfaceName = triplePBService.XXX_InterfaceName()
}
- if err := refConfig.Init(cc.refOpts...); err != nil {
+ if err := refConfig.Init(rootConfig); 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)
- SetConsumerServiceByInterfaceName(refConfig.InterfaceName, refRPCService)
- }
-
- for info, refRPCService := range GetClientInfoServicesMap() {
- refConfig, ok := cc.References[info.InterfaceName]
- if !ok {
- logger.Errorf("Dubbo-go can not find %s Reference in References config, please check your configuration file", info.InterfaceName)
- continue
- }
- refConfig.ReferWithInfo(info)
- refConfig.Implement(refRPCService)
}
var maxWait int
@@ -193,7 +165,7 @@
(ref.Check == nil && cc.Check && GetProviderService(key) == nil) ||
(ref.Check == nil && GetProviderService(key) == nil) { // default to true
- if !ref.CheckAvailable() {
+ if ref.invoker != nil && !ref.invoker.IsAvailable() {
checkok = false
count++
if count > maxWait {
@@ -204,6 +176,9 @@
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 {
@@ -219,7 +194,7 @@
func newEmptyConsumerConfig() *ConsumerConfig {
newConsumerConfig := &ConsumerConfig{
- References: make(map[string]*client.ReferenceConfig, 8),
+ References: make(map[string]*ReferenceConfig, 8),
RequestTimeout: "3s",
Check: true,
}
@@ -264,12 +239,12 @@
return ccb
}
-func (ccb *ConsumerConfigBuilder) AddReference(referenceKey string, referenceConfig *client.ReferenceConfig) *ConsumerConfigBuilder {
+func (ccb *ConsumerConfigBuilder) AddReference(referenceKey string, referenceConfig *ReferenceConfig) *ConsumerConfigBuilder {
ccb.consumerConfig.References[referenceKey] = referenceConfig
return ccb
}
-func (ccb *ConsumerConfigBuilder) SetReferences(references map[string]*client.ReferenceConfig) *ConsumerConfigBuilder {
+func (ccb *ConsumerConfigBuilder) SetReferences(references map[string]*ReferenceConfig) *ConsumerConfigBuilder {
ccb.consumerConfig.References = references
return ccb
}
diff --git a/config/reference_config.go b/config/reference_config.go
index 824f315..1d6899e 100644
--- a/config/reference_config.go
+++ b/config/reference_config.go
@@ -18,20 +18,390 @@
package config
import (
- "dubbo.apache.org/dubbo-go/v3/client"
+ "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/config/generic"
+ "dubbo.apache.org/dubbo-go/v3/protocol"
+ "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
+ 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"`
+ Methods []*MethodConfig `yaml:"methods" json:"methods,omitempty" property:"methods"`
+ Async bool `yaml:"async" json:"async,omitempty" property:"async"`
+ Params map[string]string `yaml:"params" json:"params,omitempty" property:"params"`
+ invoker protocol.Invoker
+ urls []*common.URL
+ 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"`
+ rootConfig *RootConfig
+ metaDataType string
+ 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.Methods {
+ 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
+ }
+ }
+ if rc.Filter == "" {
+ rc.Filter = root.Consumer.Filter
+ }
+ if rc.Cluster == "" {
+ rc.Cluster = "failover"
+ }
+ rc.RegistryIDs = translateIds(rc.RegistryIDs)
+ if len(rc.RegistryIDs) <= 0 {
+ rc.RegistryIDs = root.Consumer.RegistryIDs
+ }
+
+ if rc.Protocol == "" {
+ rc.Protocol = root.Consumer.Protocol
+ }
+
+ if rc.TracingKey == "" {
+ rc.TracingKey = root.Consumer.TracingKey
+ }
+ if rc.Check == nil {
+ rc.Check = &root.Consumer.Check
+ }
+ 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 interface{}) {
+ // 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.AddParam(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.Error()))
+ }
+ 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 := common.MergeURL(serviceURL, cfgURL)
+ newURL.AddParam("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 protocol.Invoker
+ regURL *common.URL
+ )
+ invokers := make([]protocol.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 {
+ panic(err)
+ } else {
+ 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 {
+ panic(err)
+ } else {
+ rc.invoker = cluster.Join(static.NewDirectory(invokers))
+ }
+ }
+
+ // publish consumer's metadata
+ publishServiceDefinition(cfgURL)
+ // 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
+ }
+ urlMap.Set(constant.ReferenceFilterKey, mergeValue(rc.Filter, "", defaultReferenceFilter))
+
+ for _, v := range rc.Methods {
+ 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(rc.id)
+ SetConsumerService(genericService)
+ rc.id = id
+ rc.Refer(genericService)
+ rc.Implement(genericService)
+}
+
+// GetInvoker get invoker from ReferenceConfig
+func (rc *ReferenceConfig) GetInvoker() protocol.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() *client.ReferenceConfig {
- newReferenceConfig := &client.ReferenceConfig{}
- newReferenceConfig.Methods = make([]*client.MethodConfig, 0, 8)
+func newEmptyReferenceConfig() *ReferenceConfig {
+ newReferenceConfig := &ReferenceConfig{}
+ newReferenceConfig.Methods = make([]*MethodConfig, 0, 8)
newReferenceConfig.Params = make(map[string]string, 8)
return newReferenceConfig
}
type ReferenceConfigBuilder struct {
- referenceConfig *client.ReferenceConfig
+ referenceConfig *ReferenceConfig
}
func NewReferenceConfigBuilder() *ReferenceConfigBuilder {
@@ -107,13 +477,13 @@
return pcb
}
-func (pcb *ReferenceConfigBuilder) SetMethodConfig(methodConfigs []*client.MethodConfig) *ReferenceConfigBuilder {
+func (pcb *ReferenceConfigBuilder) SetMethodConfig(methodConfigs []*MethodConfig) *ReferenceConfigBuilder {
pcb.referenceConfig.Methods = methodConfigs
return pcb
}
-func (pcb *ReferenceConfigBuilder) AddMethodConfig(methodConfigs *client.MethodConfig) *ReferenceConfigBuilder {
- pcb.referenceConfig.Methods = append(pcb.referenceConfig.Methods, methodConfigs)
+func (pcb *ReferenceConfigBuilder) AddMethodConfig(methodConfig *MethodConfig) *ReferenceConfigBuilder {
+ pcb.referenceConfig.Methods = append(pcb.referenceConfig.Methods, methodConfig)
return pcb
}
@@ -147,6 +517,6 @@
return pcb
}
-func (pcb *ReferenceConfigBuilder) Build() *client.ReferenceConfig {
+func (pcb *ReferenceConfigBuilder) Build() *ReferenceConfig {
return pcb.referenceConfig
}
diff --git a/config/registry_config.go b/config/registry_config.go
index 2f196fe..9eca5ea 100644
--- a/config/registry_config.go
+++ b/config/registry_config.go
@@ -18,44 +18,281 @@
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/config/instance"
"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 bool `default:"true" yaml:"use-as-meta-report" json:"use-as-meta-report,omitempty" property:"use-as-meta-report"`
+ UseAsConfigCenter bool `default:"true" 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))
+
+ for k, v := range c.Params {
+ urlMap.Set(k, v)
+ }
+ return urlMap
+}
+
+func (c *RegistryConfig) startRegistryConfig() error {
+ c.translateRegistryAddress()
+ if c.UseAsMetaReport && isValid(c.Address) {
+ if tmpUrl, err := c.toMetadataReportUrl(); err == nil {
+ instance.SetMetadataReportInstanceByReg(tmpUrl)
+ } else {
+ return perrors.Wrap(err, "Start RegistryConfig failed.")
+ }
+ }
+ 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
+ if c.RegistryType == constant.RegistryTypeService {
+ // service discovery protocol
+ registryURLProtocol = constant.ServiceRegistryProtocol
+ } else if c.RegistryType == constant.RegistryTypeInterface {
+ registryURLProtocol = constant.RegistryProtocol
+ } else {
+ 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
+ }
+
+ if c.RegistryType == constant.RegistryTypeService {
+ // service discovery protocol
+ if registryURL, err = c.createNewURL(constant.ServiceRegistryProtocol, address, roleType); err == nil {
+ urls = append(urls, registryURL)
+ }
+ } else if c.RegistryType == constant.RegistryTypeInterface {
+ if registryURL, err = c.createNewURL(constant.RegistryProtocol, address, roleType); err == nil {
+ urls = append(urls, registryURL)
+ }
+ } else if c.RegistryType == 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)
+ }
+ } else {
+ 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 {
+ 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 *registry.RegistryConfig) *registry.RegistryConfig
+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) *registry.RegistryConfig {
+func NewRegistryConfigWithProtocolDefaultPort(protocol string) *RegistryConfig {
switch protocol {
case "zookeeper":
- return ®istry.RegistryConfig{
+ return &RegistryConfig{
Protocol: protocol,
Address: defaultZKAddr,
Timeout: defaultRegistryTimeout,
}
case "nacos":
- return ®istry.RegistryConfig{
+ return &RegistryConfig{
Protocol: protocol,
Address: defaultNacosAddr,
Timeout: defaultRegistryTimeout,
}
default:
- return ®istry.RegistryConfig{
+ return &RegistryConfig{
Protocol: protocol,
}
}
}
-// NewRegistryConfig creates New registry.RegistryConfig with @opts
-func NewRegistryConfig(opts ...RegistryConfigOpt) *registry.RegistryConfig {
+// NewRegistryConfig creates New RegistryConfig with @opts
+func NewRegistryConfig(opts ...RegistryConfigOpt) *RegistryConfig {
newRegistryConfig := NewRegistryConfigWithProtocolDefaultPort("")
for _, v := range opts {
newRegistryConfig = v(newRegistryConfig)
@@ -65,7 +302,7 @@
// WithRegistryProtocol returns RegistryConfigOpt with given @regProtocol name
func WithRegistryProtocol(regProtocol string) RegistryConfigOpt {
- return func(config *registry.RegistryConfig) *registry.RegistryConfig {
+ return func(config *RegistryConfig) *RegistryConfig {
config.Protocol = regProtocol
return config
}
@@ -73,7 +310,7 @@
// WithRegistryAddress returns RegistryConfigOpt with given @addr registry address
func WithRegistryAddress(addr string) RegistryConfigOpt {
- return func(config *registry.RegistryConfig) *registry.RegistryConfig {
+ return func(config *RegistryConfig) *RegistryConfig {
config.Address = addr
return config
}
@@ -81,7 +318,7 @@
// WithRegistryTimeOut returns RegistryConfigOpt with given @timeout registry config
func WithRegistryTimeOut(timeout string) RegistryConfigOpt {
- return func(config *registry.RegistryConfig) *registry.RegistryConfig {
+ return func(config *RegistryConfig) *RegistryConfig {
config.Timeout = timeout
return config
}
@@ -89,7 +326,7 @@
// WithRegistryGroup returns RegistryConfigOpt with given @group registry group
func WithRegistryGroup(group string) RegistryConfigOpt {
- return func(config *registry.RegistryConfig) *registry.RegistryConfig {
+ return func(config *RegistryConfig) *RegistryConfig {
config.Group = group
return config
}
@@ -97,7 +334,7 @@
// WithRegistryTTL returns RegistryConfigOpt with given @ttl registry ttl
func WithRegistryTTL(ttl string) RegistryConfigOpt {
- return func(config *registry.RegistryConfig) *registry.RegistryConfig {
+ return func(config *RegistryConfig) *RegistryConfig {
config.TTL = ttl
return config
}
@@ -105,7 +342,7 @@
// WithRegistryUserName returns RegistryConfigOpt with given @userName registry userName
func WithRegistryUserName(userName string) RegistryConfigOpt {
- return func(config *registry.RegistryConfig) *registry.RegistryConfig {
+ return func(config *RegistryConfig) *RegistryConfig {
config.Username = userName
return config
}
@@ -113,7 +350,7 @@
// WithRegistryPassword returns RegistryConfigOpt with given @psw registry password
func WithRegistryPassword(psw string) RegistryConfigOpt {
- return func(config *registry.RegistryConfig) *registry.RegistryConfig {
+ return func(config *RegistryConfig) *RegistryConfig {
config.Password = psw
return config
}
@@ -121,15 +358,15 @@
// WithRegistrySimplified returns RegistryConfigOpt with given @simplified registry simplified flag
func WithRegistrySimplified(simplified bool) RegistryConfigOpt {
- return func(config *registry.RegistryConfig) *registry.RegistryConfig {
+ return func(config *RegistryConfig) *RegistryConfig {
config.Simplified = simplified
return config
}
}
-// WithRegistryPreferred returns registry.RegistryConfig with given @preferred registry preferred flag
+// WithRegistryPreferred returns RegistryConfig with given @preferred registry preferred flag
func WithRegistryPreferred(preferred bool) RegistryConfigOpt {
- return func(config *registry.RegistryConfig) *registry.RegistryConfig {
+ return func(config *RegistryConfig) *RegistryConfig {
config.Preferred = preferred
return config
}
@@ -137,7 +374,7 @@
// WithRegistryWeight returns RegistryConfigOpt with given @weight registry weight flag
func WithRegistryWeight(weight int64) RegistryConfigOpt {
- return func(config *registry.RegistryConfig) *registry.RegistryConfig {
+ return func(config *RegistryConfig) *RegistryConfig {
config.Weight = weight
return config
}
@@ -145,7 +382,7 @@
// WithRegistryParams returns RegistryConfigOpt with given registry @params
func WithRegistryParams(params map[string]string) RegistryConfigOpt {
- return func(config *registry.RegistryConfig) *registry.RegistryConfig {
+ return func(config *RegistryConfig) *RegistryConfig {
config.Params = params
return config
}
@@ -153,12 +390,12 @@
func NewRegistryConfigBuilder() *RegistryConfigBuilder {
return &RegistryConfigBuilder{
- registryConfig: ®istry.RegistryConfig{},
+ registryConfig: &RegistryConfig{},
}
}
type RegistryConfigBuilder struct {
- registryConfig *registry.RegistryConfig
+ registryConfig *RegistryConfig
}
func (rcb *RegistryConfigBuilder) SetProtocol(protocol string) *RegistryConfigBuilder {
@@ -239,9 +476,18 @@
return rcb
}
-func (rcb *RegistryConfigBuilder) Build() *registry.RegistryConfig {
+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
index e4caa82..1223f6b 100644
--- a/config/registry_config_test.go
+++ b/config/registry_config_test.go
@@ -25,45 +25,109 @@
"github.com/stretchr/testify/assert"
)
-// todo: think about how to expose functions of RegistryConfig
-//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, config.Prefix(), constant.RegistryConfigPrefix)
-//
-// values := config.getUrlMap(common.PROVIDER)
-// assert.Equal(t, values.Get("timeout"), "15s")
-//
-// url, err := config.toMetadataReportUrl()
-// assert.NoError(t, err)
-// assert.Equal(t, url.GetParam("timeout", "3s"), "10s")
-//
-// url, err = config.toURL(common.PROVIDER)
-// assert.NoError(t, err)
-// assert.Equal(t, url.GetParam("timeout", "3s"), "15s")
-//
-// address := config.translateRegistryAddress()
-// assert.Equal(t, address, "127.0.0.1:8848")
-//}
+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)
+}
+
+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)
+}
+
+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.Equal(t, 2, len(urls))
+}
+
+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, config.Prefix(), constant.RegistryConfigPrefix)
+
+ values := config.getUrlMap(common.PROVIDER)
+ assert.Equal(t, values.Get("timeout"), "15s")
+
+ url, err := config.toMetadataReportUrl()
+ assert.NoError(t, err)
+ assert.Equal(t, url.GetParam("timeout", "3s"), "10s")
+
+ url, err = config.toURL(common.PROVIDER)
+ assert.NoError(t, err)
+ assert.Equal(t, url.GetParam("timeout", "3s"), "15s")
+
+ address := config.translateRegistryAddress()
+ assert.Equal(t, address, "127.0.0.1:8848")
+}
+
func TestNewRegistryConfig(t *testing.T) {
config := NewRegistryConfig(
WithRegistryProtocol("nacos"),
diff --git a/config/root_config.go b/config/root_config.go
index 95a1636..7517702 100644
--- a/config/root_config.go
+++ b/config/root_config.go
@@ -35,12 +35,10 @@
import (
"dubbo.apache.org/dubbo-go/v3/common"
- commonCfg "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/metadata/service/exporter"
- "dubbo.apache.org/dubbo-go/v3/registry"
)
var (
@@ -50,23 +48,23 @@
// RootConfig is the root config
type RootConfig struct {
- Application *commonCfg.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]*registry.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"`
- Metric *MetricConfig `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"`
+ 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"`
+ Metric *MetricConfig `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) {
@@ -96,7 +94,7 @@
return NewConsumerConfigBuilder().Build()
}
-func GetApplicationConfig() *commonCfg.ApplicationConfig {
+func GetApplicationConfig() *ApplicationConfig {
return rootConfig.Application
}
@@ -224,7 +222,7 @@
ConfigCenter: NewConfigCenterConfigBuilder().Build(),
MetadataReport: NewMetadataReportConfigBuilder().Build(),
Application: NewApplicationConfigBuilder().Build(),
- Registries: make(map[string]*registry.RegistryConfig),
+ Registries: make(map[string]*RegistryConfig),
Protocols: make(map[string]*ProtocolConfig),
Tracing: make(map[string]*TracingConfig),
Provider: NewProviderConfigBuilder().Build(),
@@ -246,7 +244,7 @@
rootConfig *RootConfig
}
-func (rb *RootConfigBuilder) SetApplication(application *commonCfg.ApplicationConfig) *RootConfigBuilder {
+func (rb *RootConfigBuilder) SetApplication(application *ApplicationConfig) *RootConfigBuilder {
rb.rootConfig.Application = application
return rb
}
@@ -256,7 +254,7 @@
return rb
}
-func (rb *RootConfigBuilder) AddRegistry(registryID string, registryConfig *registry.RegistryConfig) *RootConfigBuilder {
+func (rb *RootConfigBuilder) AddRegistry(registryID string, registryConfig *RegistryConfig) *RootConfigBuilder {
rb.rootConfig.Registries[registryID] = registryConfig
return rb
}
@@ -266,7 +264,7 @@
return rb
}
-func (rb *RootConfigBuilder) SetRegistries(registries map[string]*registry.RegistryConfig) *RootConfigBuilder {
+func (rb *RootConfigBuilder) SetRegistries(registries map[string]*RegistryConfig) *RootConfigBuilder {
rb.rootConfig.Registries = registries
return rb
}
diff --git a/config/root_config_test.go b/config/root_config_test.go
index 42e27f7..e49e145 100644
--- a/config/root_config_test.go
+++ b/config/root_config_test.go
@@ -30,12 +30,11 @@
import (
"dubbo.apache.org/dubbo-go/v3/common/constant"
"dubbo.apache.org/dubbo-go/v3/config_center"
- "dubbo.apache.org/dubbo-go/v3/registry"
)
func TestGoConfigProcess(t *testing.T) {
rc := &RootConfigBuilder{rootConfig: newEmptyRootConfig()}
- r := ®istry.RegistryConfig{Protocol: "zookeeper", Timeout: "10s", Address: "127.0.0.1:2181"}
+ r := &RegistryConfig{Protocol: "zookeeper", Timeout: "10s", Address: "127.0.0.1:2181"}
rc.AddRegistry("demoZK", r)
// test koan.UnmarshalWithConf error
@@ -65,7 +64,7 @@
AddProtocol("dubbo", protocolConfig).
AddRegistry("nacos", registryConfig).
SetProtocols(map[string]*ProtocolConfig{"dubbo": protocolConfig}).
- SetRegistries(map[string]*registry.RegistryConfig{"nacos": registryConfig}).
+ SetRegistries(map[string]*RegistryConfig{"nacos": registryConfig}).
SetProvider(NewProviderConfigBuilder().Build()).
SetConsumer(NewConsumerConfigBuilder().Build()).
SetMetric(NewMetricConfigBuilder().Build()).
diff --git a/config/service.go b/config/service.go
index 0621bc2..513048a 100644
--- a/config/service.go
+++ b/config/service.go
@@ -26,19 +26,16 @@
)
import (
- "dubbo.apache.org/dubbo-go/v3/client"
"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
- proServices = map[string]common.RPCService{} // service name -> service
- interfaceNameConServicesLock = sync.Mutex{} // used to guard interfaceNameConServices map
- interfaceNameConServices = map[string]common.RPCService{} // interfaceName -> service
- clientInfoServicesLock = sync.Mutex{} // used to guard clientInfoServices map
- clientInfoServices = map[*client.ClientInfo]common.RPCService{} // ClientInfo -> service
+ conServicesLock = sync.Mutex{} // used to guard conServices map.
+ conServices = map[string]common.RPCService{} // service name -> service
+ proServicesLock = sync.Mutex{} // used to guard proServices map
+ proServices = map[string]common.RPCService{} // service name -> service
+ interfaceNameConServicesLock = sync.Mutex{} // used to guard interfaceNameConServices map
+ interfaceNameConServices = map[string]common.RPCService{} // interfaceName -> service
)
// SetConsumerService is called by init() of implement of RPCService
@@ -110,17 +107,9 @@
return nil
}
-// SetClientInfoService set new info and service into clientInfosServices if new info and service are not nil
-func SetClientInfoService(info *client.ClientInfo, srv common.RPCService) {
- if info == nil || info.ClientInjectFunc == nil || srv == nil {
- return
- }
- clientInfoServicesLock.Lock()
- defer clientInfoServicesLock.Unlock()
- clientInfoServices[info] = srv
-}
-
-// GetClientInfoServicesMap returns clientInfoServices
-func GetClientInfoServicesMap() map[*client.ClientInfo]common.RPCService {
- return clientInfoServices
-}
+// SetClientInfoService is used by new Triple generated code
+// use interface{} 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 interface{}, service common.RPCService) {}
diff --git a/config/service_config.go b/config/service_config.go
index fb97233..6689810 100644
--- a/config/service_config.go
+++ b/config/service_config.go
@@ -209,7 +209,12 @@
func getRandomPort(protocolConfigs []*ProtocolConfig) *list.List {
ports := list.New()
for _, proto := range protocolConfigs {
- if len(proto.Port) > 0 {
+ 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
}
@@ -238,7 +243,7 @@
regUrls := make([]*common.URL, 0)
if !s.NotRegister {
- regUrls = loadRegistries(s.RegistryIDs, s.RCRegistriesMap, common.PROVIDER)
+ regUrls = LoadRegistries(s.RegistryIDs, s.RCRegistriesMap, common.PROVIDER)
}
urlMap := s.getUrlMap()
diff --git a/config/service_config_test.go b/config/service_config_test.go
index da6b5af..3d6494d 100644
--- a/config/service_config_test.go
+++ b/config/service_config_test.go
@@ -93,8 +93,8 @@
assert.Equal(t, serviceConfig.IsExport(), false)
})
- t.Run("loadRegistries&loadProtocol&getRandomPort", func(t *testing.T) {
- registries := loadRegistries(serviceConfig.RegistryIDs, serviceConfig.RCRegistriesMap, common.PROVIDER)
+ t.Run("LoadRegistries&loadProtocol&getRandomPort", func(t *testing.T) {
+ registries := LoadRegistries(serviceConfig.RegistryIDs, serviceConfig.RCRegistriesMap, common.PROVIDER)
assert.Equal(t, len(registries), 1)
assert.Equal(t, "service-discovery-registry", registries[0].Protocol)
assert.Equal(t, registries[0].Port, "8848")
diff --git a/protocol/triple/triple-tool/protoc-gen-triple/main.go b/protocol/triple/triple-tool/protoc-gen-triple/main.go
index 7f7ea59..4a60279 100644
--- a/protocol/triple/triple-tool/protoc-gen-triple/main.go
+++ b/protocol/triple/triple-tool/protoc-gen-triple/main.go
@@ -18,15 +18,22 @@
package main
import (
- "dubbo.apache.org/dubbo-go/v3/triple-tool/gen/generator"
- "dubbo.apache.org/dubbo-go/v3/triple-tool/internal/version"
"fmt"
- "google.golang.org/protobuf/compiler/protogen"
- "google.golang.org/protobuf/types/pluginpb"
"os"
"path/filepath"
)
+import (
+ "google.golang.org/protobuf/compiler/protogen"
+
+ "google.golang.org/protobuf/types/pluginpb"
+)
+
+import (
+ "dubbo.apache.org/dubbo-go/v3/triple-tool/gen/generator"
+ "dubbo.apache.org/dubbo-go/v3/triple-tool/internal/version"
+)
+
const (
usage = "See https://connect.build/docs/go/getting-started to learn how to use this plugin.\n\nFlags:\n -h, --help\tPrint this help and exit.\n --version\tPrint the version and exit."
)
diff --git a/protocol/triple/triple-tool/util/module.go b/protocol/triple/triple-tool/util/module.go
index d871c9a..1157598 100644
--- a/protocol/triple/triple-tool/util/module.go
+++ b/protocol/triple/triple-tool/util/module.go
@@ -17,7 +17,9 @@
package util
-import "strings"
+import (
+ "strings"
+)
func GetModuleName() (string, error) {
output, err := Exec("go list -m", "./")
diff --git a/registry/registry_config.go b/registry/registry_config.go
index 7ecac63..ae1ac66 100644
--- a/registry/registry_config.go
+++ b/registry/registry_config.go
@@ -17,27 +17,9 @@
package registry
-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"
- commonCfg "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/instance"
-)
+// todo(DMwangnima): finish refactoring and move related logic from config package to this file.
+// This RegistryConfig is a copy of /config/RegistryConfig right now.
+// Please refer to issue(https://github.com/apache/dubbo-go/issues/2377).
// RegistryConfig is the configuration of the registry center
type RegistryConfig struct {
@@ -58,216 +40,3 @@
UseAsMetaReport bool `default:"true" yaml:"use-as-meta-report" json:"use-as-meta-report,omitempty" property:"use-as-meta-report"`
UseAsConfigCenter bool `default:"true" 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))
-
- for k, v := range c.Params {
- urlMap.Set(k, v)
- }
- return urlMap
-}
-
-func (c *RegistryConfig) startRegistryConfig() error {
- c.translateRegistryAddress()
- if c.UseAsMetaReport && commonCfg.IsValid(c.Address) {
- if tmpUrl, err := c.toMetadataReportUrl(); err == nil {
- instance.SetMetadataReportInstanceByReg(tmpUrl)
- } else {
- return perrors.Wrap(err, "Start RegistryConfig failed.")
- }
- }
- return commonCfg.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, 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
- if c.RegistryType == constant.RegistryTypeService {
- // service discovery protocol
- registryURLProtocol = constant.ServiceRegistryProtocol
- } else if c.RegistryType == constant.RegistryTypeInterface {
- registryURLProtocol = constant.RegistryProtocol
- } else {
- 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 !commonCfg.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
- }
-
- if c.RegistryType == constant.RegistryTypeService {
- // service discovery protocol
- if registryURL, err = c.createNewURL(constant.ServiceRegistryProtocol, address, roleType); err == nil {
- urls = append(urls, registryURL)
- }
- } else if c.RegistryType == constant.RegistryTypeInterface {
- if registryURL, err = c.createNewURL(constant.RegistryProtocol, address, roleType); err == nil {
- urls = append(urls, registryURL)
- }
- } else if c.RegistryType == 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)
- }
- } else {
- 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 {
- registryURLs = append(registryURLs, urls...)
- }
- }
- }
-
- return registryURLs
-}
-
-// ClientNameID unique identifier id for client
-func ClientNameID(config *RegistryConfig, protocol, address string) string {
- return strings.Join([]string{config.Prefix(), protocol, address}, "-")
-}
-
-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),
- )
-}
-
-// 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/registry/registry_config_test.go b/registry/registry_config_test.go
deleted file mode 100644
index ab9a874..0000000
--- a/registry/registry_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 registry
-
-import (
- "testing"
-)
-
-import (
- "github.com/stretchr/testify/assert"
-)
-
-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)
-}
-
-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)
-}
-
-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.Equal(t, 2, len(urls))
-}
-
-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)
-}