This is an automated email from the ASF dual-hosted git repository.

liujun pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/dubbo-go.git


The following commit(s) were added to refs/heads/main by this push:
     new 27279e765 Fix url attributes merge (#2504)
27279e765 is described below

commit 27279e765a7ed5f681631f876e630ad018694dc9
Author: finalt <finalt1...@163.com>
AuthorDate: Mon Nov 27 16:40:08 2023 +0800

    Fix url attributes merge (#2504)
    
    followup of #2503
---
 client/action.go                |  2 +-
 common/url.go                   | 35 ++++++++++++++++++-----------------
 common/url_test.go              |  2 +-
 config/reference_config.go      |  2 +-
 registry/directory/directory.go |  6 +++---
 5 files changed, 24 insertions(+), 23 deletions(-)

diff --git a/client/action.go b/client/action.go
index aa6908940..7cc67a08d 100644
--- a/client/action.go
+++ b/client/action.go
@@ -255,7 +255,7 @@ func (refOpts *ReferenceOptions) processURL(cfgURL 
*common.URL) error {
                                }
                                // 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 := serviceURL.MergeURL(cfgURL)
                                newURL.AddParam("peer", "true")
                                refOpts.urls = append(refOpts.urls, newURL)
                        }
diff --git a/common/url.go b/common/url.go
index e98543390..156ba9f90 100644
--- a/common/url.go
+++ b/common/url.go
@@ -772,20 +772,20 @@ func (c *URL) ToMap() map[string]string {
 // TODO configuration merge, in the future , the configuration center's config 
should merge too.
 
 // MergeURL will merge those two URL
-// the result is based on serviceURL, and the key which si only contained in 
referenceURL
+// the result is based on c, and the key which si only contained in anotherUrl
 // will be added into result.
-// for example, if serviceURL contains params (a1->v1, b1->v2) and 
referenceURL contains params(a2->v3, b1 -> v4)
+// for example, if c contains params (a1->v1, b1->v2) and anotherUrl contains 
params(a2->v3, b1 -> v4)
 // the params of result will be (a1->v1, b1->v2, a2->v3).
 // You should notice that the value of b1 is v2, not v4
 // except constant.LoadbalanceKey, constant.ClusterKey, constant.RetriesKey, 
constant.TimeoutKey.
 // due to URL is not thread-safe, so this method is not thread-safe
-func MergeURL(serviceURL *URL, referenceURL *URL) *URL {
+func (c *URL) MergeURL(anotherUrl *URL) *URL {
        // After Clone, it is a new URL that there is no thread safe issue.
-       mergedURL := serviceURL.Clone()
+       mergedURL := c.Clone()
        params := mergedURL.GetParams()
-       // iterator the referenceURL if serviceURL not have the key ,merge in
-       // referenceURL usually will not changed. so change RangeParams to 
GetParams to avoid the string value copy.// Group get group
-       for key, value := range referenceURL.GetParams() {
+       // iterator the anotherUrl if c not have the key ,merge in
+       // anotherUrl usually will not changed. so change RangeParams to 
GetParams to avoid the string value copy.// Group get group
+       for key, value := range anotherUrl.GetParams() {
                if _, ok := mergedURL.GetNonDefaultParam(key); !ok {
                        if len(value) > 0 {
                                params[key] = value
@@ -796,35 +796,36 @@ func MergeURL(serviceURL *URL, referenceURL *URL) *URL {
        }
 
        // remote timestamp
-       if v, ok := serviceURL.GetNonDefaultParam(constant.TimestampKey); !ok {
+       if v, ok := c.GetNonDefaultParam(constant.TimestampKey); !ok {
                params[constant.RemoteTimestampKey] = []string{v}
-               params[constant.TimestampKey] = 
[]string{referenceURL.GetParam(constant.TimestampKey, "")}
+               params[constant.TimestampKey] = 
[]string{anotherUrl.GetParam(constant.TimestampKey, "")}
        }
 
        // finally execute methodConfigMergeFcn
-       mergedURL.Methods = make([]string, len(referenceURL.Methods))
-       for i, method := range referenceURL.Methods {
+       mergedURL.Methods = make([]string, len(anotherUrl.Methods))
+       for i, method := range anotherUrl.Methods {
                for _, paramKey := range []string{constant.LoadbalanceKey, 
constant.ClusterKey, constant.RetriesKey, constant.TimeoutKey} {
-                       if v := referenceURL.GetParam(paramKey, ""); len(v) > 0 
{
+                       if v := anotherUrl.GetParam(paramKey, ""); len(v) > 0 {
                                params[paramKey] = []string{v}
                        }
 
                        methodsKey := "methods." + method + "." + paramKey
                        //if len(mergedURL.GetParam(methodsKey, "")) == 0 {
-                       if v := referenceURL.GetParam(methodsKey, ""); len(v) > 
0 {
+                       if v := anotherUrl.GetParam(methodsKey, ""); len(v) > 0 
{
                                params[methodsKey] = []string{v}
                        }
                        //}
                        mergedURL.Methods[i] = method
                }
        }
-
        // merge attributes
        if mergedURL.attributes == nil {
-               mergedURL.attributes = make(map[string]interface{}, 
len(referenceURL.attributes))
+               mergedURL.attributes = make(map[string]interface{}, 
len(anotherUrl.attributes))
        }
-       for attrK, attrV := range referenceURL.attributes {
-               mergedURL.attributes[attrK] = attrV
+       for attrK, attrV := range anotherUrl.attributes {
+               if _, ok := mergedURL.GetAttribute(attrK); !ok {
+                       mergedURL.attributes[attrK] = attrV
+               }
        }
        // In this way, we will raise some performance.
        mergedURL.ReplaceParams(params)
diff --git a/common/url_test.go b/common/url_test.go
index 7c9cdf875..fcb437f9b 100644
--- a/common/url_test.go
+++ b/common/url_test.go
@@ -340,7 +340,7 @@ func TestMergeUrl(t *testing.T) {
        referenceUrl, _ := NewURL("mock1://127.0.0.1:1111", 
WithParams(referenceUrlParams), WithMethods([]string{"testMethod"}))
        serviceUrl, _ := NewURL("mock2://127.0.0.1:20000", 
WithParams(serviceUrlParams))
 
-       mergedUrl := MergeURL(serviceUrl, referenceUrl)
+       mergedUrl := serviceUrl.MergeURL(referenceUrl)
        assert.Equal(t, "random", mergedUrl.GetParam(constant.ClusterKey, ""))
        assert.Equal(t, "1", mergedUrl.GetParam("test2", ""))
        assert.Equal(t, "1", mergedUrl.GetParam("test3", ""))
diff --git a/config/reference_config.go b/config/reference_config.go
index c48bc5d9b..5cd98cc87 100644
--- a/config/reference_config.go
+++ b/config/reference_config.go
@@ -220,7 +220,7 @@ func (rc *ReferenceConfig) Refer(srv interface{}) {
                                }
                                // 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 := serviceURL.MergeURL(cfgURL)
                                newURL.AddParam("peer", "true")
                                rc.urls = append(rc.urls, newURL)
                        }
diff --git a/registry/directory/directory.go b/registry/directory/directory.go
index 27cab6223..142361528 100644
--- a/registry/directory/directory.go
+++ b/registry/directory/directory.go
@@ -184,7 +184,7 @@ func (dir *RegistryDirectory) refreshAllInvokers(events 
[]*registry.ServiceEvent
                // Originally it will Merge URL many times, now we just execute 
once.
                // MergeURL is executed once and put the result into Event. 
After this, the key will get from Event.Key().
                newUrl := dir.convertUrl(event)
-               newUrl = common.MergeURL(newUrl, referenceUrl)
+               newUrl = newUrl.MergeURL(referenceUrl)
                dir.overrideUrl(newUrl)
                event.Update(newUrl)
        }
@@ -249,7 +249,7 @@ func (dir *RegistryDirectory) invokerCacheKey(event 
*registry.ServiceEvent) stri
                return event.Key()
        }
        referenceUrl := dir.GetDirectoryUrl().SubURL
-       newUrl := common.MergeURL(event.Service, referenceUrl)
+       newUrl := event.Service.MergeURL(referenceUrl)
        event.Update(newUrl)
        return event.Key()
 }
@@ -391,7 +391,7 @@ func (dir *RegistryDirectory) cacheInvoker(url *common.URL, 
event *registry.Serv
        }
        // check the url's protocol is equal to the protocol which is 
configured in reference config or referenceUrl is not care about protocol
        if url.Protocol == referenceUrl.Protocol || referenceUrl.Protocol == "" 
{
-               newUrl := common.MergeURL(url, referenceUrl)
+               newUrl := url.MergeURL(referenceUrl)
                dir.overrideUrl(newUrl)
                event.Update(newUrl)
                if v, ok := dir.doCacheInvoker(newUrl, event); ok {

Reply via email to