This is an automated email from the ASF dual-hosted git repository.
xuetaoli pushed a commit to branch develop
in repository https://gitbox.apache.org/repos/asf/dubbo-go.git
The following commit(s) were added to refs/heads/develop by this push:
new 0026310a4 chore: update tag and polaris from config to global (#3029)
0026310a4 is described below
commit 0026310a4a9e208c45a4f7d53889e3393c947bbc
Author: Zerui Yang <[email protected]>
AuthorDate: Sun Nov 16 20:09:14 2025 +0800
chore: update tag and polaris from config to global (#3029)
* fix(router): enhance router configuration with global
---
client/action.go | 1 +
client/client.go | 1 +
client/options.go | 52 ++++++++++++---
cluster/router/affinity/router.go | 14 ++--
cluster/router/config.go | 32 ---------
cluster/router/polaris/factory.go | 4 +-
cluster/router/polaris/router.go | 60 ++++++++++++-----
cluster/router/tag/match.go | 8 +--
cluster/router/tag/router.go | 8 +--
cluster/router/tag/router_test.go | 32 ++++-----
common/constant/key.go | 5 +-
global/registry_config.go | 17 +++++
global/router_config.go | 134 ++++++++++++++++++++++++++++++++++++++
options.go | 2 +-
registry/directory/directory.go | 40 ++++++++++++
15 files changed, 315 insertions(+), 95 deletions(-)
diff --git a/client/action.go b/client/action.go
index f66547f15..1c85908cf 100644
--- a/client/action.go
+++ b/client/action.go
@@ -149,6 +149,7 @@ func (refOpts *ReferenceOptions) refer(srv
common.RPCService, info *ClientInfo)
// TODO: remove ISIDL after old triple removed
common.WithParamsValue(constant.IDLMode, ref.IDLMode),
common.WithAttribute(constant.ConsumerConfigKey,
refOpts.Consumer),
+ common.WithAttribute(constant.RegistriesConfigKey,
refOpts.Registries),
)
// for new triple IDL mode
diff --git a/client/client.go b/client/client.go
index 1fddf423e..6fb0c7104 100644
--- a/client/client.go
+++ b/client/client.go
@@ -165,6 +165,7 @@ func (cli *Client) dial(interfaceName string, info
*ClientInfo, srv any, opts ..
setReference(cli.cliOpts.overallReference),
setApplicationCompat(cli.cliOpts.applicationCompat),
setRegistriesCompat(cli.cliOpts.registriesCompat),
+ setRegistries(cli.cliOpts.Registries),
setConsumer(cli.cliOpts.Consumer),
setMetrics(cli.cliOpts.Metrics),
setOtel(cli.cliOpts.Otel),
diff --git a/client/options.go b/client/options.go
index bcefc3c2d..b6dd1f7ae 100644
--- a/client/options.go
+++ b/client/options.go
@@ -41,11 +41,12 @@ import (
)
type ReferenceOptions struct {
- Reference *global.ReferenceConfig
- Consumer *global.ConsumerConfig
- Metrics *global.MetricsConfig
- Otel *global.OtelConfig
- TLS *global.TLSConfig
+ Reference *global.ReferenceConfig
+ Consumer *global.ConsumerConfig
+ Metrics *global.MetricsConfig
+ Otel *global.OtelConfig
+ TLS *global.TLSConfig
+ Registries map[string]*global.RegistryConfig
pxy *proxy.Proxy
id string
@@ -61,10 +62,11 @@ type ReferenceOptions struct {
func defaultReferenceOptions() *ReferenceOptions {
return &ReferenceOptions{
- Reference: global.DefaultReferenceConfig(),
- Metrics: global.DefaultMetricsConfig(),
- Otel: global.DefaultOtelConfig(),
- TLS: global.DefaultTLSConfig(),
+ Reference: global.DefaultReferenceConfig(),
+ Metrics: global.DefaultMetricsConfig(),
+ Otel: global.DefaultOtelConfig(),
+ TLS: global.DefaultTLSConfig(),
+ Registries: global.DefaultRegistriesConfig(),
}
}
@@ -107,6 +109,19 @@ func (refOpts *ReferenceOptions) init(opts
...ReferenceOption) error {
}
// init registries
+ // convert Registries to registriesCompat
+ if len(refOpts.Registries) > 0 {
+ if refOpts.registriesCompat == nil {
+ refOpts.registriesCompat =
make(map[string]*config.RegistryConfig)
+ }
+ for id, reg := range refOpts.Registries {
+ refOpts.registriesCompat[id] = compatRegistryConfig(reg)
+ if err := refOpts.registriesCompat[id].Init(); err !=
nil {
+ return err
+ }
+ }
+ }
+
if len(refOpts.registriesCompat) > 0 {
regs := refOpts.registriesCompat
if len(refConf.RegistryIDs) <= 0 {
@@ -193,6 +208,17 @@ func WithRegistryIDs(registryIDs ...string)
ReferenceOption {
}
}
+func WithRegistry(opts ...registry.Option) ReferenceOption {
+ regOpts := registry.NewOptions(opts...)
+
+ return func(refOpts *ReferenceOptions) {
+ if refOpts.Registries == nil {
+ refOpts.Registries =
make(map[string]*global.RegistryConfig)
+ }
+ refOpts.Registries[regOpts.ID] = regOpts.Registry
+ }
+}
+
// ========== Cluster Strategy ==========
func WithClusterAvailable() ReferenceOption {
@@ -478,6 +504,12 @@ func setTLS(tls *global.TLSConfig) ReferenceOption {
}
}
+func setRegistries(regs map[string]*global.RegistryConfig) ReferenceOption {
+ return func(opts *ReferenceOptions) {
+ opts.Registries = regs
+ }
+}
+
type ClientOptions struct {
Consumer *global.ConsumerConfig
Application *global.ApplicationConfig
@@ -495,7 +527,7 @@ type ClientOptions struct {
func defaultClientOptions() *ClientOptions {
return &ClientOptions{
Consumer: global.DefaultConsumerConfig(),
- Registries: make(map[string]*global.RegistryConfig),
+ Registries: global.DefaultRegistriesConfig(),
Application: global.DefaultApplicationConfig(),
Shutdown: global.DefaultShutdownConfig(),
Metrics: global.DefaultMetricsConfig(),
diff --git a/cluster/router/affinity/router.go
b/cluster/router/affinity/router.go
index 0b69bfe50..d6687902f 100644
--- a/cluster/router/affinity/router.go
+++ b/cluster/router/affinity/router.go
@@ -30,7 +30,6 @@ import (
)
import (
- "dubbo.apache.org/dubbo-go/v3/cluster/router"
"dubbo.apache.org/dubbo-go/v3/cluster/router/condition"
"dubbo.apache.org/dubbo-go/v3/common"
conf "dubbo.apache.org/dubbo-go/v3/common/config"
@@ -85,14 +84,13 @@ type ApplicationAffinityRoute struct {
func newApplicationAffinityRouter(url *common.URL) *ApplicationAffinityRoute {
- application, ok := url.GetAttribute(constant.ApplicationKey)
- if !ok {
- logger.Warnf("ApplicationAffinityRoute url does not have
application attribute, url=%s", url)
+ applicationName := url.GetParam(constant.ApplicationKey, "")
+
+ if applicationName == "" {
+ logger.Errorf("Application affinity router must set application
name")
return nil
}
- applicationName := application.(global.ApplicationConfig).Name
-
a := &ApplicationAffinityRoute{
currentApplication: applicationName,
}
@@ -225,8 +223,8 @@ func (a *affinityRoute) Notify(_ []base.Invoker) {
panic("this function should not be called")
}
-func parseConfig(c string) (router.AffinityRouter, error) {
- res := router.AffinityRouter{}
+func parseConfig(c string) (global.AffinityRouter, error) {
+ res := global.AffinityRouter{}
err := yaml.Unmarshal([]byte(c), &res)
return res, err
}
diff --git a/cluster/router/config.go b/cluster/router/config.go
deleted file mode 100644
index 2231898c2..000000000
--- a/cluster/router/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 router
-
-type AffinityAware struct {
- Key string `default:"" yaml:"key" json:"key,omitempty" property:"key"`
- Ratio int32 `default:"0" yaml:"ratio" json:"ratio,omitempty"
property:"ratio"`
-}
-
-// 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"`
-}
diff --git a/cluster/router/polaris/factory.go
b/cluster/router/polaris/factory.go
index 0eeb6fdcb..3f6fc9c2a 100644
--- a/cluster/router/polaris/factory.go
+++ b/cluster/router/polaris/factory.go
@@ -31,6 +31,6 @@ func NewPolarisRouterFactory() router.PriorityRouterFactory {
}
// NewPriorityRouter construct a new PriorityRouter
-func (f *RouteFactory) NewPriorityRouter(_ *common.URL)
(router.PriorityRouter, error) {
- return newPolarisRouter()
+func (f *RouteFactory) NewPriorityRouter(url *common.URL)
(router.PriorityRouter, error) {
+ return newPolarisRouter(url)
}
diff --git a/cluster/router/polaris/router.go b/cluster/router/polaris/router.go
index 317ea16dd..98f41966e 100644
--- a/cluster/router/polaris/router.go
+++ b/cluster/router/polaris/router.go
@@ -21,6 +21,7 @@ import (
"errors"
"fmt"
"strings"
+ "sync"
"time"
)
@@ -36,7 +37,7 @@ import (
"dubbo.apache.org/dubbo-go/v3/cluster/router"
"dubbo.apache.org/dubbo-go/v3/common"
"dubbo.apache.org/dubbo-go/v3/common/constant"
- "dubbo.apache.org/dubbo-go/v3/config"
+ "dubbo.apache.org/dubbo-go/v3/global"
"dubbo.apache.org/dubbo-go/v3/protocol/base"
remotingpolaris "dubbo.apache.org/dubbo-go/v3/remoting/polaris"
"dubbo.apache.org/dubbo-go/v3/remoting/polaris/parser"
@@ -50,7 +51,21 @@ var (
ErrorPolarisServiceRouteRuleEmpty = errors.New("service route rule is
empty")
)
-func newPolarisRouter() (*polarisRouter, error) {
+func newPolarisRouter(url *common.URL) (*polarisRouter, error) {
+
+ // get from url param
+ applicationName := url.GetParam(constant.ApplicationKey, "")
+
+ if applicationName == "" {
+ return nil, fmt.Errorf("polaris router must set application
name")
+ }
+
+ // get from url attr
+ registries, ok := url.GetAttribute(constant.RegistriesConfigKey)
+ if !ok {
+ registries = make(map[string]*global.RegistryConfig)
+ }
+
if err := remotingpolaris.Check(); errors.Is(err,
remotingpolaris.ErrorNoOpenPolarisAbility) {
return &polarisRouter{
openRoute: false,
@@ -67,9 +82,11 @@ func newPolarisRouter() (*polarisRouter, error) {
}
return &polarisRouter{
- openRoute: true,
- routerAPI: routerAPI,
- consumerAPI: consumerAPI,
+ openRoute: true,
+ routerAPI: routerAPI,
+ consumerAPI: consumerAPI,
+ currentApplication: applicationName,
+ Registries:
registries.(map[string]*global.RegistryConfig),
}, nil
}
@@ -78,6 +95,11 @@ type polarisRouter struct {
routerAPI polaris.RouterAPI
consumerAPI polaris.ConsumerAPI
+
+ // config change: config to global
+ mu sync.RWMutex
+ currentApplication string
+ Registries map[string]*global.RegistryConfig
}
// Route Determine the target invokers list.
@@ -94,7 +116,7 @@ func (p *polarisRouter) Route(invokers []base.Invoker, url
*common.URL,
return invokers
}
- service := getService(url)
+ service := p.getService(url)
instanceMap := p.buildInstanceMap(service)
if len(instanceMap) == 0 {
return invokers
@@ -138,17 +160,20 @@ func (p *polarisRouter) Route(invokers []base.Invoker,
url *common.URL,
return ret
}
-func getService(url *common.URL) string {
+func (p *polarisRouter) getService(url *common.URL) string {
+ p.mu.RLock()
+ defer p.mu.RUnlock()
+
applicationMode := false
- for _, item := range config.GetRootConfig().Registries {
- if item.Protocol == constant.PolarisKey {
+ for _, item := range p.Registries {
+ if item != nil && item.Protocol == constant.PolarisKey {
applicationMode = item.RegistryType ==
constant.ServiceKey
}
}
service := url.Interface()
if applicationMode {
- service = config.GetApplicationConfig().Name
+ service = p.currentApplication
}
return service
@@ -176,7 +201,7 @@ func (p *polarisRouter) buildRouteRequest(svc string, url
*common.URL,
for i := range labels {
label := labels[i]
if strings.Compare(label, model.LabelKeyPath) == 0 {
-
routeReq.AddArguments(model.BuildPathArgument(getInvokeMethod(url, invocation)))
+
routeReq.AddArguments(model.BuildPathArgument(p.getInvokeMethod(url,
invocation)))
continue
}
if strings.HasPrefix(label, model.LabelKeyHeader) {
@@ -215,15 +240,18 @@ func (p *polarisRouter) buildTrafficLabels(svc string)
([]string, error) {
routeRule := resp.GetValue().(*v1.Routing)
labels := make([]string, 0, 4)
labels = append(labels, collectRouteLabels(routeRule.GetInbounds())...)
- labels = append(labels, collectRouteLabels(routeRule.GetInbounds())...)
+ labels = append(labels, collectRouteLabels(routeRule.GetOutbounds())...)
return labels, nil
}
-func getInvokeMethod(url *common.URL, invoaction base.Invocation) string {
+func (p *polarisRouter) getInvokeMethod(url *common.URL, invoaction
base.Invocation) string {
+ p.mu.RLock()
+ defer p.mu.RUnlock()
+
applicationMode := false
- for _, item := range config.GetRootConfig().Registries {
- if item.Protocol == constant.PolarisKey {
+ for _, item := range p.Registries {
+ if item != nil && item.Protocol == constant.PolarisKey {
applicationMode = item.RegistryType ==
constant.ServiceKey
}
}
@@ -293,7 +321,7 @@ func (p *polarisRouter) Notify(invokers []base.Invoker) {
if len(invokers) == 0 {
return
}
- service := getService(invokers[0].GetURL())
+ service := p.getService(invokers[0].GetURL())
if service == "" {
logger.Error("url service is empty")
return
diff --git a/cluster/router/tag/match.go b/cluster/router/tag/match.go
index 60739ef2d..e8208848c 100644
--- a/cluster/router/tag/match.go
+++ b/cluster/router/tag/match.go
@@ -28,7 +28,7 @@ import (
import (
"dubbo.apache.org/dubbo-go/v3/common"
"dubbo.apache.org/dubbo-go/v3/common/constant"
- "dubbo.apache.org/dubbo-go/v3/config"
+ "dubbo.apache.org/dubbo-go/v3/global"
"dubbo.apache.org/dubbo-go/v3/protocol/base"
)
@@ -62,7 +62,7 @@ func staticTag(invokers []base.Invoker, url *common.URL,
invocation base.Invocat
}
// dynamic tag matching. used configuration center to create tag router
configuration
-func dynamicTag(invokers []base.Invoker, url *common.URL, invocation
base.Invocation, cfg config.RouterConfig) []base.Invoker {
+func dynamicTag(invokers []base.Invoker, url *common.URL, invocation
base.Invocation, cfg global.RouterConfig) []base.Invoker {
tag := invocation.GetAttachmentWithDefaultValue(constant.Tagkey,
url.GetParam(constant.Tagkey, ""))
if tag == "" {
return requestEmptyTag(invokers, cfg)
@@ -73,7 +73,7 @@ func dynamicTag(invokers []base.Invoker, url *common.URL,
invocation base.Invoca
// if request.tag is not set, only providers with empty tags will be matched.
// even if a service is available in the cluster, it cannot be invoked if the
tag does not match,
// and requests without tags or other tags will never be able to access
services with other tags.
-func requestEmptyTag(invokers []base.Invoker, cfg config.RouterConfig)
[]base.Invoker {
+func requestEmptyTag(invokers []base.Invoker, cfg global.RouterConfig)
[]base.Invoker {
result := filterInvokers(invokers, "", func(invoker base.Invoker, tag
any) bool {
return invoker.GetURL().GetParam(constant.Tagkey, "") != ""
})
@@ -95,7 +95,7 @@ func requestEmptyTag(invokers []base.Invoker, cfg
config.RouterConfig) []base.In
// if no service corresponding to the request tag exists in the cluster,
// the provider with the empty request tag is degraded by default.
// to change the default behavior that no provider matching TAG1 returns an
exception, set request.tag.force=true.
-func requestTag(invokers []base.Invoker, url *common.URL, invocation
base.Invocation, cfg config.RouterConfig, tag string) []base.Invoker {
+func requestTag(invokers []base.Invoker, url *common.URL, invocation
base.Invocation, cfg global.RouterConfig, tag string) []base.Invoker {
var (
addresses []string
result []base.Invoker
diff --git a/cluster/router/tag/router.go b/cluster/router/tag/router.go
index 825dc080e..8e4fafd26 100644
--- a/cluster/router/tag/router.go
+++ b/cluster/router/tag/router.go
@@ -32,8 +32,8 @@ 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/config"
"dubbo.apache.org/dubbo-go/v3/config_center"
+ "dubbo.apache.org/dubbo-go/v3/global"
"dubbo.apache.org/dubbo-go/v3/protocol/base"
"dubbo.apache.org/dubbo-go/v3/remoting"
)
@@ -58,7 +58,7 @@ func (p *PriorityRouter) Route(invokers []base.Invoker, url
*common.URL, invocat
if !ok {
return staticTag(invokers, url, invocation)
}
- routerCfg := value.(config.RouterConfig)
+ routerCfg := value.(global.RouterConfig)
if !*routerCfg.Enabled || !*routerCfg.Valid {
return staticTag(invokers, url, invocation)
}
@@ -116,9 +116,9 @@ func (p *PriorityRouter) Process(event
*config_center.ConfigChangeEvent) {
logger.Infof("[tag router]Parse tag router config
success,routerConfig=%+v", routerConfig)
}
-func parseRoute(routeContent string) (*config.RouterConfig, error) {
+func parseRoute(routeContent string) (*global.RouterConfig, error) {
routeDecoder := yaml.NewDecoder(strings.NewReader(routeContent))
- routerConfig := &config.RouterConfig{}
+ routerConfig := &global.RouterConfig{}
err := routeDecoder.Decode(routerConfig)
if err != nil {
return nil, err
diff --git a/cluster/router/tag/router_test.go
b/cluster/router/tag/router_test.go
index b30f62c6c..71316f45f 100644
--- a/cluster/router/tag/router_test.go
+++ b/cluster/router/tag/router_test.go
@@ -31,9 +31,9 @@ import (
common_cfg "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/config_center"
"dubbo.apache.org/dubbo-go/v3/config_center/configurator"
+ "dubbo.apache.org/dubbo-go/v3/global"
"dubbo.apache.org/dubbo-go/v3/protocol/base"
"dubbo.apache.org/dubbo-go/v3/protocol/invocation"
)
@@ -134,7 +134,7 @@ func TestRouter(t *testing.T) {
t.Run("dynamicEmptyTag_requestEmptyTag", func(t *testing.T) {
p, err := NewTagPriorityRouter()
assert.Nil(t, err)
-
p.routerConfigs.Store(consumerUrl.Service()+constant.TagRouterRuleSuffix,
config.RouterConfig{
+
p.routerConfigs.Store(consumerUrl.Service()+constant.TagRouterRuleSuffix,
global.RouterConfig{
Key: consumerUrl.Service() +
constant.TagRouterRuleSuffix,
Force: falsePointer,
Enabled: truePointer,
@@ -154,7 +154,7 @@ func TestRouter(t *testing.T) {
t.Run("dynamicEmptyTag_requestHasTag", func(t *testing.T) {
p, err := NewTagPriorityRouter()
assert.Nil(t, err)
-
p.routerConfigs.Store(consumerUrl.Service()+constant.TagRouterRuleSuffix,
config.RouterConfig{
+
p.routerConfigs.Store(consumerUrl.Service()+constant.TagRouterRuleSuffix,
global.RouterConfig{
Key: consumerUrl.Service() +
constant.TagRouterRuleSuffix,
Force: falsePointer,
Enabled: truePointer,
@@ -175,12 +175,12 @@ func TestRouter(t *testing.T) {
t.Run("dynamicTag_requestEmptyTag", func(t *testing.T) {
p, err := NewTagPriorityRouter()
assert.Nil(t, err)
-
p.routerConfigs.Store(strings.Join([]string{consumerUrl.GetParam(constant.ApplicationKey,
""), constant.TagRouterRuleSuffix}, ""), config.RouterConfig{
+
p.routerConfigs.Store(strings.Join([]string{consumerUrl.GetParam(constant.ApplicationKey,
""), constant.TagRouterRuleSuffix}, ""), global.RouterConfig{
Key: consumerUrl.Service() +
constant.TagRouterRuleSuffix,
Force: falsePointer,
Enabled: truePointer,
Valid: truePointer,
- Tags: []config.Tag{{
+ Tags: []global.Tag{{
Name: "tag",
Addresses: []string{"192.168.0.3:20000"},
}},
@@ -199,12 +199,12 @@ func TestRouter(t *testing.T) {
t.Run("dynamicTag_emptyAddress_requestHasTag", func(t *testing.T) {
p, err := NewTagPriorityRouter()
assert.Nil(t, err)
-
p.routerConfigs.Store(consumerUrl.Service()+constant.TagRouterRuleSuffix,
config.RouterConfig{
+
p.routerConfigs.Store(consumerUrl.Service()+constant.TagRouterRuleSuffix,
global.RouterConfig{
Key: consumerUrl.Service() +
constant.TagRouterRuleSuffix,
Force: falsePointer,
Enabled: truePointer,
Valid: truePointer,
- Tags: []config.Tag{{
+ Tags: []global.Tag{{
Name: "tag",
}},
})
@@ -223,12 +223,12 @@ func TestRouter(t *testing.T) {
t.Run("dynamicTag_address_requestHasTag", func(t *testing.T) {
p, err := NewTagPriorityRouter()
assert.Nil(t, err)
-
p.routerConfigs.Store(strings.Join([]string{consumerUrl.GetParam(constant.ApplicationKey,
""), constant.TagRouterRuleSuffix}, ""), config.RouterConfig{
+
p.routerConfigs.Store(strings.Join([]string{consumerUrl.GetParam(constant.ApplicationKey,
""), constant.TagRouterRuleSuffix}, ""), global.RouterConfig{
Key: consumerUrl.Service() +
constant.TagRouterRuleSuffix,
Force: falsePointer,
Enabled: truePointer,
Valid: truePointer,
- Tags: []config.Tag{{
+ Tags: []global.Tag{{
Name: "tag",
Addresses: []string{"192.168.0.3:20000"},
}},
@@ -248,12 +248,12 @@ func TestRouter(t *testing.T) {
t.Run("dynamicTag_twoAddress_requestHasTag", func(t *testing.T) {
p, err := NewTagPriorityRouter()
assert.Nil(t, err)
-
p.routerConfigs.Store(strings.Join([]string{consumerUrl.GetParam(constant.ApplicationKey,
""), constant.TagRouterRuleSuffix}, ""), config.RouterConfig{
+
p.routerConfigs.Store(strings.Join([]string{consumerUrl.GetParam(constant.ApplicationKey,
""), constant.TagRouterRuleSuffix}, ""), global.RouterConfig{
Key: consumerUrl.Service() +
constant.TagRouterRuleSuffix,
Force: falsePointer,
Enabled: truePointer,
Valid: truePointer,
- Tags: []config.Tag{{
+ Tags: []global.Tag{{
Name: "tag",
Addresses: []string{"192.168.0.1:20000",
"192.168.0.3:20000"},
}},
@@ -273,12 +273,12 @@ func TestRouter(t *testing.T) {
t.Run("dynamicTag_addressNotMatch_requestHasTag", func(t *testing.T) {
p, err := NewTagPriorityRouter()
assert.Nil(t, err)
-
p.routerConfigs.Store(consumerUrl.Service()+constant.TagRouterRuleSuffix,
config.RouterConfig{
+
p.routerConfigs.Store(consumerUrl.Service()+constant.TagRouterRuleSuffix,
global.RouterConfig{
Key: consumerUrl.Service() +
constant.TagRouterRuleSuffix,
Force: falsePointer,
Enabled: truePointer,
Valid: truePointer,
- Tags: []config.Tag{{
+ Tags: []global.Tag{{
Name: "tag",
Addresses: []string{"192.168.0.4:20000"},
}},
@@ -298,12 +298,12 @@ func TestRouter(t *testing.T) {
t.Run("dynamicTag_notValid", func(t *testing.T) {
p, err := NewTagPriorityRouter()
assert.Nil(t, err)
-
p.routerConfigs.Store(consumerUrl.Service()+constant.TagRouterRuleSuffix,
config.RouterConfig{
+
p.routerConfigs.Store(consumerUrl.Service()+constant.TagRouterRuleSuffix,
global.RouterConfig{
Key: consumerUrl.Service() +
constant.TagRouterRuleSuffix,
Force: falsePointer,
Enabled: truePointer,
Valid: falsePointer,
- Tags: []config.Tag{{
+ Tags: []global.Tag{{
Name: "tag",
Addresses: []string{"192.168.0.1:20000",
"192.168.0.3:20000"},
}},
@@ -367,7 +367,7 @@ tags:
p.Notify(invokerList)
value, ok :=
p.routerConfigs.Load(url1.GetParam(constant.ApplicationKey, "") +
constant.TagRouterRuleSuffix)
assert.True(t, ok)
- routerCfg := value.(config.RouterConfig)
+ routerCfg := value.(global.RouterConfig)
assert.True(t, routerCfg.Key ==
"org.apache.dubbo.UserProvider.Test")
assert.True(t, len(routerCfg.Tags) == 2)
assert.True(t, *routerCfg.Enabled)
diff --git a/common/constant/key.go b/common/constant/key.go
index 3740e7445..bf61b1a32 100644
--- a/common/constant/key.go
+++ b/common/constant/key.go
@@ -70,8 +70,9 @@ const (
// TODO: remove IDLMode after old triple removed
IDLMode = "IDL-mode"
- TripleConfigKey = "triple-config"
- ConsumerConfigKey = "consumer-config"
+ TripleConfigKey = "triple-config"
+ ConsumerConfigKey = "consumer-config"
+ RegistriesConfigKey = "registries-config"
)
// TODO: remove this after old triple removed
diff --git a/global/registry_config.go b/global/registry_config.go
index 20f89cc14..8b5ebac57 100644
--- a/global/registry_config.go
+++ b/global/registry_config.go
@@ -48,6 +48,23 @@ func DefaultRegistryConfig() *RegistryConfig {
return &RegistryConfig{UseAsMetaReport: "true", UseAsConfigCenter:
"true", Timeout: "5s", TTL: "15m"}
}
+// DefaultRegistriesConfig returns an empty map for registries configuration
+func DefaultRegistriesConfig() map[string]*RegistryConfig {
+ return make(map[string]*RegistryConfig)
+}
+
+// CloneRegistriesConfig clones a map of RegistryConfig
+func CloneRegistriesConfig(regs map[string]*RegistryConfig)
map[string]*RegistryConfig {
+ if regs == nil {
+ return nil
+ }
+ cloned := make(map[string]*RegistryConfig, len(regs))
+ for k, v := range regs {
+ cloned[k] = v.Clone()
+ }
+ return cloned
+}
+
// Clone a new RegistryConfig
func (c *RegistryConfig) Clone() *RegistryConfig {
if c == nil {
diff --git a/global/router_config.go b/global/router_config.go
new file mode 100644
index 000000000..9b161b5eb
--- /dev/null
+++ b/global/router_config.go
@@ -0,0 +1,134 @@
+/*
+ * 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 global
+
+import (
+ "dubbo.apache.org/dubbo-go/v3/common"
+)
+
+type RouterConfig struct {
+ Scope string `validate:"required" yaml:"scope"
json:"scope,omitempty" property:"scope"`
+ Key string `validate:"required" yaml:"key"
json:"key,omitempty" property:"key"`
+ 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"`
+}
+
+func (c *RouterConfig) Clone() *RouterConfig {
+ if c == nil {
+ return nil
+ }
+
+ var newForce *bool
+ if c.Force != nil {
+ newForce = new(bool)
+ *newForce = *c.Force
+ }
+
+ var newRuntime *bool
+ if c.Runtime != nil {
+ newRuntime = new(bool)
+ *newRuntime = *c.Runtime
+ }
+
+ var newEnabled *bool
+ if c.Enabled != nil {
+ newEnabled = new(bool)
+ *newEnabled = *c.Enabled
+ }
+
+ var newValid *bool
+ if c.Valid != nil {
+ newValid = new(bool)
+ *newValid = *c.Valid
+ }
+
+ newConditions := make([]string, len(c.Conditions))
+ copy(newConditions, c.Conditions)
+
+ newTags := make([]Tag, len(c.Tags))
+ copy(newTags, c.Tags)
+
+ return &RouterConfig{
+ Scope: c.Scope,
+ Key: c.Key,
+ Force: newForce,
+ Runtime: newRuntime,
+ Enabled: newEnabled,
+ Valid: newValid,
+ Priority: c.Priority,
+ Conditions: newConditions,
+ Tags: newTags,
+ ScriptType: c.ScriptType,
+ Script: c.Script,
+ }
+}
diff --git a/options.go b/options.go
index 83c81af4c..46df750b6 100644
--- a/options.go
+++ b/options.go
@@ -66,7 +66,7 @@ func defaultInstanceOptions() *InstanceOptions {
return &InstanceOptions{
Application: global.DefaultApplicationConfig(),
Protocols: make(map[string]*global.ProtocolConfig),
- Registries: make(map[string]*global.RegistryConfig),
+ Registries: global.DefaultRegistriesConfig(),
ConfigCenter: global.DefaultCenterConfig(),
MetadataReport: global.DefaultMetadataReportConfig(),
Provider: global.DefaultProviderConfig(),
diff --git a/registry/directory/directory.go b/registry/directory/directory.go
index 987e964c9..f2e80705d 100644
--- a/registry/directory/directory.go
+++ b/registry/directory/directory.go
@@ -83,11 +83,51 @@ func NewRegistryDirectory(url *common.URL, registry
registry.Registry) (director
}
logger.Debugf("new RegistryDirectory for service :%s.", url.Key())
+ // TODO: Temporary compatibility with old APIs, can be removed later
+
+ // set application if not exist
if _, ok := url.GetAttribute(constant.ApplicationKey); !ok {
application := config.GetRootConfig().Application
if application == nil {
defaultAppConfig := global.DefaultApplicationConfig()
url.SetAttribute(constant.ApplicationKey,
defaultAppConfig)
+ } else {
+ url.SetAttribute(constant.ApplicationKey, application)
+ }
+ }
+ // set registry if not exist
+ if _, ok := url.GetAttribute(constant.RegistriesConfigKey); !ok {
+ configRegistries := config.GetRootConfig().Registries
+ if configRegistries == nil {
+ defaultRegistryConfig := global.DefaultRegistryConfig()
+ url.SetAttribute(constant.RegistriesConfigKey,
map[string]*global.RegistryConfig{
+ constant.DefaultKey: defaultRegistryConfig,
+ })
+ } else {
+ // convert config.RegistryConfig to
global.RegistryConfig
+ globalRegistries :=
make(map[string]*global.RegistryConfig, len(configRegistries))
+ for key, configRegistry := range configRegistries {
+ globalRegistry := &global.RegistryConfig{
+ Protocol:
configRegistry.Protocol,
+ Timeout:
configRegistry.Timeout,
+ Group: configRegistry.Group,
+ Namespace:
configRegistry.Namespace,
+ TTL: configRegistry.TTL,
+ Address:
configRegistry.Address,
+ Username:
configRegistry.Username,
+ Password:
configRegistry.Password,
+ Simplified:
configRegistry.Simplified,
+ Preferred:
configRegistry.Preferred,
+ Zone: configRegistry.Zone,
+ Weight:
configRegistry.Weight,
+ Params:
configRegistry.Params,
+ RegistryType:
configRegistry.RegistryType,
+ UseAsMetaReport:
configRegistry.UseAsMetaReport,
+ UseAsConfigCenter:
configRegistry.UseAsConfigCenter,
+ }
+ globalRegistries[key] = globalRegistry
+ }
+ url.SetAttribute(constant.RegistriesConfigKey,
globalRegistries)
}
}