Repository: apache/dubbo (Java)
Date: 2021-09-28 15:57:46+00:00
Task type: Bug Fix

Issue:
Instance registry mode can't use mesh route
- [x] I have searched the [issues](https://github.com/apache/dubbo/issues) of this repository and believe that this is not a duplicate.
- [x] I have checked the [FAQ](https://github.com/apache/dubbo/blob/master/FAQ.md) of this repository and believe that this is not a duplicate.

### Environment

* Dubbo version: 3.0.3

### Steps to reproduce this issue

1. 启动 provider `-Ddubbo.application.register-mode=instance`
2. 启动 consumer `dubbo.application.service-discovery.migration=FORCE_APPLICATION`
3. 使用 `dubbo admin` 创建 mesh 路由
4. `org.apache.dubbo.registry.client.InstanceAddressURL#getParameters` 不能获取真正的 url 参数，导致路由规则匹配失败
![image](https://user-images.githubusercontent.com/43994656/134940925-96081a6c-500c-4b71-89cc-bbd22d0be296.png)
5. 原因在于 `getProtocolServiceKey()` 方法是从`RpcContext`中获取，此时获取的`protocolServiceKey` 为 null，导致获取的为 instance 参数，实际需要获取对应服务的参数。
```
    public Map<String, String> getParameters() {
        String protocolServiceKey = getProtocolServiceKey();
        if (StringUtils.isEmpty(protocolServiceKey)) {
            return getInstance().getAllParams();
        }
        return getServiceParameters(protocolServiceKey);
    }
```
```
    public String getProtocolServiceKey() {
        return RpcContext.getServiceContext().getProtocolServiceKey();
    }
```



Issue discussion:

Solution patch:
diff --git a/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/router/mesh/route/MeshRuleRouter.java b/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/router/mesh/route/MeshRuleRouter.java
--- a/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/router/mesh/route/MeshRuleRouter.java
+++ b/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/router/mesh/route/MeshRuleRouter.java
@@ -288,7 +288,7 @@ protected Map<String, List<Invoker<?>>> computeSubsetMap(List<Invoker<?>> invoke
                 Map<String, String> labels = subset.getLabels();
 
                 for (Invoker<?> invoker : invokers) {
-                    Map<String, String> parameters = invoker.getUrl().getParameters();
+                    Map<String, String> parameters = invoker.getUrl().getServiceParameters(url.getProtocolServiceKey());
                     if (containMapKeyValue(parameters, labels)) {
                         subsetInvokerList.add(invoker);
                     }


Test patch:
diff --git a/dubbo-cluster/src/test/java/org/apache/dubbo/rpc/cluster/router/mesh/route/MeshRuleRouterTest.java b/dubbo-cluster/src/test/java/org/apache/dubbo/rpc/cluster/router/mesh/route/MeshRuleRouterTest.java
--- a/dubbo-cluster/src/test/java/org/apache/dubbo/rpc/cluster/router/mesh/route/MeshRuleRouterTest.java
+++ b/dubbo-cluster/src/test/java/org/apache/dubbo/rpc/cluster/router/mesh/route/MeshRuleRouterTest.java
@@ -95,7 +95,7 @@ public void computeSubsetMap() {
             Map<String, String> invoker1Map = new HashMap<>();
             invoker1Map.put("env", "test1");
 
-            when(invoker1URL.getParameters()).thenReturn(invoker1Map);
+            when(invoker1URL.getServiceParameters(url.getProtocolServiceKey())).thenReturn(invoker1Map);
             when(invoker1.getUrl()).thenReturn(invoker1URL);
 
             invokers.add(invoker1);
@@ -107,7 +107,7 @@ public void computeSubsetMap() {
             Map<String, String> invoker1Map = new HashMap<>();
             invoker1Map.put("env", "test2");
 
-            when(invoker1URL.getParameters()).thenReturn(invoker1Map);
+            when(invoker1URL.getServiceParameters(url.getProtocolServiceKey())).thenReturn(invoker1Map);
             when(invoker1.getUrl()).thenReturn(invoker1URL);
 
             invokers.add(invoker1);
@@ -120,7 +120,7 @@ public void computeSubsetMap() {
             Map<String, String> invoker1Map = new HashMap<>();
             invoker1Map.put("env", "test3");
 
-            when(invoker1URL.getParameters()).thenReturn(invoker1Map);
+            when(invoker1URL.getServiceParameters(url.getProtocolServiceKey())).thenReturn(invoker1Map);
             when(invoker1.getUrl()).thenReturn(invoker1URL);
 
             invokers.add(invoker1);
@@ -241,7 +241,7 @@ public void computeSubset() {
             Map<String, String> invoker1Map = new HashMap<>();
             invoker1Map.put("env", "test1");
 
-            when(invoker1URL.getParameters()).thenReturn(invoker1Map);
+            when(invoker1URL.getServiceParameters(url.getProtocolServiceKey())).thenReturn(invoker1Map);
             when(invoker1.getUrl()).thenReturn(invoker1URL);
 
             invokers.add(invoker1);
@@ -253,7 +253,7 @@ public void computeSubset() {
             Map<String, String> invoker1Map = new HashMap<>();
             invoker1Map.put("env", "test2");
 
-            when(invoker1URL.getParameters()).thenReturn(invoker1Map);
+            when(invoker1URL.getServiceParameters(url.getProtocolServiceKey())).thenReturn(invoker1Map);
             when(invoker1.getUrl()).thenReturn(invoker1URL);
 
             invokers.add(invoker1);
@@ -266,7 +266,7 @@ public void computeSubset() {
             Map<String, String> invoker1Map = new HashMap<>();
             invoker1Map.put("env", "test3");
 
-            when(invoker1URL.getParameters()).thenReturn(invoker1Map);
+            when(invoker1URL.getServiceParameters(url.getProtocolServiceKey())).thenReturn(invoker1Map);
             when(invoker1.getUrl()).thenReturn(invoker1URL);
 
             invokers.add(invoker1);
@@ -786,7 +786,7 @@ public void testNotify() {
             Map<String, String> invoker1Map = new HashMap<>();
             invoker1Map.put("env", "test1");
 
-            when(invoker1URL.getParameters()).thenReturn(invoker1Map);
+            when(invoker1URL.getServiceParameters(url.getProtocolServiceKey())).thenReturn(invoker1Map);
             when(invoker1.getUrl()).thenReturn(invoker1URL);
 
             invokers.add(invoker1);
@@ -798,7 +798,7 @@ public void testNotify() {
             Map<String, String> invoker1Map = new HashMap<>();
             invoker1Map.put("env", "test2");
 
-            when(invoker1URL.getParameters()).thenReturn(invoker1Map);
+            when(invoker1URL.getServiceParameters(url.getProtocolServiceKey())).thenReturn(invoker1Map);
             when(invoker1.getUrl()).thenReturn(invoker1URL);
 
             invokers.add(invoker1);
@@ -811,7 +811,7 @@ public void testNotify() {
             Map<String, String> invoker1Map = new HashMap<>();
             invoker1Map.put("env", "test3");
 
-            when(invoker1URL.getParameters()).thenReturn(invoker1Map);
+            when(invoker1URL.getServiceParameters(url.getProtocolServiceKey())).thenReturn(invoker1Map);
             when(invoker1.getUrl()).thenReturn(invoker1URL);
 
             invokers.add(invoker1);
@@ -929,7 +929,7 @@ public void route() {
             Map<String, String> invoker1Map = new HashMap<>();
             invoker1Map.put("env", "test1");
 
-            when(invoker1URL.getParameters()).thenReturn(invoker1Map);
+            when(invoker1URL.getServiceParameters(url.getProtocolServiceKey())).thenReturn(invoker1Map);
             when(invoker1.getUrl()).thenReturn(invoker1URL);
 
             invokers.add(invoker1);
@@ -941,7 +941,7 @@ public void route() {
             Map<String, String> invoker1Map = new HashMap<>();
             invoker1Map.put("env", "test2");
 
-            when(invoker1URL.getParameters()).thenReturn(invoker1Map);
+            when(invoker1URL.getServiceParameters(url.getProtocolServiceKey())).thenReturn(invoker1Map);
             when(invoker1.getUrl()).thenReturn(invoker1URL);
 
             invokers.add(invoker1);
@@ -954,7 +954,7 @@ public void route() {
             Map<String, String> invoker1Map = new HashMap<>();
             invoker1Map.put("env", "test3");
 
-            when(invoker1URL.getParameters()).thenReturn(invoker1Map);
+            when(invoker1URL.getServiceParameters(url.getProtocolServiceKey())).thenReturn(invoker1Map);
             when(invoker1.getUrl()).thenReturn(invoker1URL);
 
             invokers.add(invoker1);
@@ -1134,7 +1134,7 @@ public void route() {
             Map<String, String> invokerParameterMap = new HashMap<>();
             invokerParameterMap.put("env", "test1");
 
-            assertEquals(invokerParameterMap, ((Invoker) meshRuleRouter.route((List) inputInvokers, inputURL, invocation).get(0)).getUrl().getParameters());
+            assertEquals(invokerParameterMap, ((Invoker) meshRuleRouter.route((List) inputInvokers, inputURL, invocation).get(0)).getUrl().getServiceParameters(url.getProtocolServiceKey()));
         }
     }
 
@@ -1165,7 +1165,7 @@ public void routeFallback() {
             Map<String, String> invoker1Map = new HashMap<>();
             invoker1Map.put("env", "test1");
 
-            when(invoker1URL.getParameters()).thenReturn(invoker1Map);
+            when(invoker1URL.getServiceParameters(url.getProtocolServiceKey())).thenReturn(invoker1Map);
             when(invoker1.getUrl()).thenReturn(invoker1URL);
 
             invokers.add(invoker1);
@@ -1177,7 +1177,7 @@ public void routeFallback() {
             Map<String, String> invoker1Map = new HashMap<>();
             invoker1Map.put("env", "test2");
 
-            when(invoker1URL.getParameters()).thenReturn(invoker1Map);
+            when(invoker1URL.getServiceParameters(url.getProtocolServiceKey())).thenReturn(invoker1Map);
             when(invoker1.getUrl()).thenReturn(invoker1URL);
 
             invokers.add(invoker1);
@@ -1190,7 +1190,7 @@ public void routeFallback() {
             Map<String, String> invoker1Map = new HashMap<>();
             invoker1Map.put("env", "test3");
 
-            when(invoker1URL.getParameters()).thenReturn(invoker1Map);
+            when(invoker1URL.getServiceParameters(url.getProtocolServiceKey())).thenReturn(invoker1Map);
             when(invoker1.getUrl()).thenReturn(invoker1URL);
 
             invokers.add(invoker1);
@@ -1328,7 +1328,7 @@ public void routeFallback() {
             Map<String, String> invokerParameterMap = new HashMap<>();
             invokerParameterMap.put("env", "test1");
 
-            assertEquals(invokerParameterMap, ((Invoker) meshRuleRouter.route((List) inputInvokers, inputURL, invocation).get(0)).getUrl().getParameters());
+            assertEquals(invokerParameterMap, ((Invoker) meshRuleRouter.route((List) inputInvokers, inputURL, invocation).get(0)).getUrl().getServiceParameters(url.getProtocolServiceKey()));
         }
 
         {