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

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


The following commit(s) were added to refs/heads/3.2 by this push:
     new 51f60139f0 Feature/dubbo3.2 export path matcher&invoker to user 
(#12482)
51f60139f0 is described below

commit 51f60139f04f4834c44c54c52c81258755903bd0
Author: suncairong163 <[email protected]>
AuthorDate: Mon Jun 12 12:38:05 2023 +0800

    Feature/dubbo3.2 export path matcher&invoker to user (#12482)
---
 .../apache/dubbo/metadata/rest/PathMatcher.java    |  73 ++++++++++++--
 .../dubbo/metadata/rest/ServiceRestMetadata.java   |   1 +
 .../org/apache/dubbo/metadata/PathMatcherTest.java |  35 +++++++
 .../rpc/protocol/rest/PathAndInvokerMapper.java    |  26 ++---
 .../rpc/protocol/rest/RestRPCInvocationUtil.java   | 109 +++++++++++++++++++--
 .../rpc/protocol/rest/constans/RestConstant.java   |   5 +
 .../protocol/rest/handler/NettyHttpHandler.java    |  14 ++-
 .../rpc/protocol/rest/JaxrsRestProtocolTest.java   |  23 +++++
 .../protocol/rest/rest/TestGetInvokerService.java  |  30 ++++++
 .../rest/rest/TestGetInvokerServiceImpl.java       |  57 +++++++++++
 10 files changed, 340 insertions(+), 33 deletions(-)

diff --git 
a/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/rest/PathMatcher.java
 
b/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/rest/PathMatcher.java
index f4d57b1c30..7abefcf71e 100644
--- 
a/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/rest/PathMatcher.java
+++ 
b/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/rest/PathMatcher.java
@@ -17,6 +17,8 @@
 package org.apache.dubbo.metadata.rest;
 
 
+import java.lang.reflect.Method;
+import java.util.Arrays;
 import java.util.Objects;
 
 /**
@@ -32,8 +34,13 @@ public class PathMatcher {
     private boolean hasPathVariable;
     private String contextPath;
     private String httpMethod;
-    // for provider http method compare
-    private boolean needCompareMethod = true;
+    // for provider http method compare,http 405
+    private boolean needCompareHttpMethod = true;
+    //  compare method directly (for get Invoker by method)
+    private boolean needCompareServiceMethod = false;
+
+    // service method
+    private Method method;
 
 
     public PathMatcher(String path) {
@@ -53,7 +60,14 @@ public class PathMatcher {
         setHttpMethod(httpMethod);
     }
 
+    public PathMatcher(Method method) {
+        this.method = method;
+    }
+
     private void dealPathVariable(String path) {
+        if (path == null) {
+            return;
+        }
         this.pathSplits = path.split(SEPARATOR);
 
         for (String pathSplit : pathSplits) {
@@ -99,6 +113,10 @@ public class PathMatcher {
         return new PathMatcher(path, version, group, port, 
method).noNeedHttpMethodCompare();
     }
 
+    public static PathMatcher getInvokeCreatePathMatcher(Method serviceMethod) 
{
+        return new 
PathMatcher(serviceMethod).setNeedCompareServiceMethod(true);
+    }
+
     public boolean hasPathVariable() {
         return hasPathVariable;
     }
@@ -117,7 +135,20 @@ public class PathMatcher {
     }
 
     private PathMatcher noNeedHttpMethodCompare() {
-        this.needCompareMethod = false;
+        this.needCompareHttpMethod = false;
+        return this;
+    }
+
+    public Method getMethod() {
+        return method;
+    }
+
+    public void setMethod(Method method) {
+        this.method = method;
+    }
+
+    private PathMatcher setNeedCompareServiceMethod(boolean 
needCompareServiceMethod) {
+        this.needCompareServiceMethod = needCompareServiceMethod;
         return this;
     }
 
@@ -126,18 +157,48 @@ public class PathMatcher {
         if (this == o) return true;
         if (o == null || getClass() != o.getClass()) return false;
         PathMatcher that = (PathMatcher) o;
-        return pathEqual(that)
-            && Objects.equals(version, that.version)
-            && (this.needCompareMethod ? Objects.equals(httpMethod, 
that.httpMethod) : true)
+        return serviceMethodEqual(that, this)
+            || pathMatch(that);
+    }
+
+    private boolean pathMatch(PathMatcher that) {
+        return (!that.needCompareServiceMethod && !needCompareServiceMethod) 
// no need service method compare
+            && pathEqual(that) // path compare
+            && Objects.equals(version, that.version) // service  version 
compare
+            && httpMethodMatch(that) // http method compare
             && Objects.equals(group, that.group) && Objects.equals(port, 
that.port);
     }
 
+    /**
+     * it is needed to compare http method when one of needCompareHttpMethod 
is true,and don`t compare when both needCompareHttpMethod are false
+     *
+     * @param that
+     * @return
+     */
+    private boolean httpMethodMatch(PathMatcher that) {
+        return !that.needCompareHttpMethod || !this.needCompareHttpMethod ?  
true: Objects.equals(this.httpMethod, that.httpMethod);
+    }
+
+    private boolean serviceMethodEqual(PathMatcher thatPathMatcher, 
PathMatcher thisPathMatcher) {
+        Method thatMethod = thatPathMatcher.method;
+        Method thisMethod = thisPathMatcher.method;
+        return thatMethod != null
+            && thisMethod != null
+            && (thatPathMatcher.needCompareServiceMethod || 
thisPathMatcher.needCompareServiceMethod)
+            && thisMethod.getName().equals(thatMethod.getName())
+            && Arrays.equals(thisMethod.getParameterTypes(), 
thatMethod.getParameterTypes());
+    }
+
     @Override
     public int hashCode() {
         return Objects.hash(version, group, port);
     }
 
     private boolean pathEqual(PathMatcher pathMatcher) {
+        // path is null return false directly
+        if (this.path == null || pathMatcher.path == null) {
+            return false;
+        }
 
 
         // no place hold
diff --git 
a/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/rest/ServiceRestMetadata.java
 
b/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/rest/ServiceRestMetadata.java
index 14f8bdcbb9..b384bbd7d5 100644
--- 
a/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/rest/ServiceRestMetadata.java
+++ 
b/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/rest/ServiceRestMetadata.java
@@ -111,6 +111,7 @@ public class ServiceRestMetadata implements Serializable {
     public void addRestMethodMetadata(RestMethodMetadata restMethodMetadata) {
         PathMatcher pathMather = new 
PathMatcher(restMethodMetadata.getRequest().getPath(),
             this.getVersion(), this.getGroup(), 
this.getPort(),restMethodMetadata.getRequest().getMethod());
+        pathMather.setMethod(restMethodMetadata.getReflectMethod());
         addPathToServiceMap(pathMather, restMethodMetadata);
         addMethodToServiceMap(restMethodMetadata);
         getMeta().add(restMethodMetadata);
diff --git 
a/dubbo-metadata/dubbo-metadata-api/src/test/java/org/apache/dubbo/metadata/PathMatcherTest.java
 
b/dubbo-metadata/dubbo-metadata-api/src/test/java/org/apache/dubbo/metadata/PathMatcherTest.java
index 8e56cc202d..b46675c3bf 100644
--- 
a/dubbo-metadata/dubbo-metadata-api/src/test/java/org/apache/dubbo/metadata/PathMatcherTest.java
+++ 
b/dubbo-metadata/dubbo-metadata-api/src/test/java/org/apache/dubbo/metadata/PathMatcherTest.java
@@ -20,6 +20,8 @@ import org.apache.dubbo.metadata.rest.PathMatcher;
 import org.junit.jupiter.api.Assertions;
 import org.junit.jupiter.api.Test;
 
+import java.lang.reflect.Method;
+
 public class PathMatcherTest {
 
     @Test
@@ -65,4 +67,37 @@ public class PathMatcherTest {
         Assertions.assertEquals(pathMatherMeta, pathMatherMeta1);
         Assertions.assertEquals(pathMatherMeta.toString(), 
pathMatherMeta1.toString());
     }
+
+    @Test
+    void testMethodCompare() {
+        Method hashCode = null;
+        Method equals = null;
+        try {
+            hashCode = Object.class.getDeclaredMethod("hashCode");
+            equals = Object.class.getDeclaredMethod("equals", Object.class);
+        } catch (NoSuchMethodException e) {
+
+        }
+
+        // no need to compare service method
+        PathMatcher pathMatcher = new PathMatcher(hashCode);
+        PathMatcher pathMatchers = new PathMatcher(hashCode);
+        Assertions.assertNotEquals(pathMatcher, pathMatchers);
+
+
+        //  equal
+        PathMatcher pathMatherMetaHashCode = 
PathMatcher.getInvokeCreatePathMatcher(hashCode);
+        PathMatcher pathMatherMetaHashCodes = new PathMatcher(hashCode);
+        Assertions.assertEquals(pathMatherMetaHashCode, 
pathMatherMetaHashCodes);
+
+
+        PathMatcher pathMatherMetaEquals = 
PathMatcher.getInvokeCreatePathMatcher(equals);
+        PathMatcher pathMatherMetaEqual = 
PathMatcher.getInvokeCreatePathMatcher(equals);
+        Assertions.assertEquals(pathMatherMetaEqual, pathMatherMetaEquals);
+
+
+        Assertions.assertNotEquals(pathMatherMetaHashCode, 
pathMatherMetaEquals);
+    }
+
+
 }
diff --git 
a/dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/PathAndInvokerMapper.java
 
b/dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/PathAndInvokerMapper.java
index 1d7aa3de05..a9fc5c2d2d 100644
--- 
a/dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/PathAndInvokerMapper.java
+++ 
b/dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/PathAndInvokerMapper.java
@@ -22,7 +22,6 @@ import org.apache.dubbo.metadata.rest.PathMatcher;
 import org.apache.dubbo.metadata.rest.RestMethodMetadata;
 import org.apache.dubbo.rpc.Invoker;
 import org.apache.dubbo.rpc.protocol.rest.exception.DoublePathCheckException;
-import org.apache.dubbo.rpc.protocol.rest.exception.PathNoFoundException;
 import 
org.apache.dubbo.rpc.protocol.rest.pair.InvokerAndRestMethodMetadataPair;
 
 import java.util.Map;
@@ -56,31 +55,26 @@ public class PathAndInvokerMapper {
         });
     }
 
+
     /**
-     * acquire metadata & invoker by service info
-     *
-     * @param path
-     * @param version
-     * @param group
-     * @param port
+     *  get rest method metadata by path matcher
+     * @param pathMatcher
      * @return
      */
-    public InvokerAndRestMethodMetadataPair getRestMethodMetadata(String path, 
String version, String group, Integer port,String method) {
-
-
-        PathMatcher pathMather = PathMatcher.getInvokeCreatePathMatcher(path, 
version, group, port,method);
+    public InvokerAndRestMethodMetadataPair getRestMethodMetadata(PathMatcher 
pathMatcher) {
 
         // first search from pathToServiceMapNoPathVariable
-        if (pathToServiceMapNoPathVariable.containsKey(pathMather)) {
-            return pathToServiceMapNoPathVariable.get(pathMather);
+        if (pathToServiceMapNoPathVariable.containsKey(pathMatcher)) {
+            return pathToServiceMapNoPathVariable.get(pathMatcher);
         }
 
         // second search from pathToServiceMapContainPathVariable
-        if (pathToServiceMapContainPathVariable.containsKey(pathMather)) {
-            return pathToServiceMapContainPathVariable.get(pathMather);
+        if (pathToServiceMapContainPathVariable.containsKey(pathMatcher)) {
+            return pathToServiceMapContainPathVariable.get(pathMatcher);
         }
 
-        throw new PathNoFoundException("rest service Path no found, current 
path info:" + pathMather);
+        return null;
+
     }
 
     /**
diff --git 
a/dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/RestRPCInvocationUtil.java
 
b/dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/RestRPCInvocationUtil.java
index 1d0221a587..e736a39292 100644
--- 
a/dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/RestRPCInvocationUtil.java
+++ 
b/dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/RestRPCInvocationUtil.java
@@ -20,16 +20,21 @@ import org.apache.dubbo.common.BaseServiceMetadata;
 import org.apache.dubbo.common.logger.ErrorTypeAwareLogger;
 import org.apache.dubbo.common.logger.LoggerFactory;
 import org.apache.dubbo.metadata.rest.ArgInfo;
+import org.apache.dubbo.metadata.rest.PathMatcher;
 import org.apache.dubbo.metadata.rest.RestMethodMetadata;
+import org.apache.dubbo.rpc.Invoker;
+import org.apache.dubbo.rpc.RpcContext;
 import org.apache.dubbo.rpc.RpcInvocation;
 import org.apache.dubbo.rpc.protocol.rest.annotation.ParamParserManager;
 import 
org.apache.dubbo.rpc.protocol.rest.annotation.param.parse.provider.ProviderParseContext;
+import org.apache.dubbo.rpc.protocol.rest.constans.RestConstant;
 import org.apache.dubbo.rpc.protocol.rest.exception.ParamParseException;
 import 
org.apache.dubbo.rpc.protocol.rest.pair.InvokerAndRestMethodMetadataPair;
 import org.apache.dubbo.rpc.protocol.rest.request.RequestFacade;
 import org.apache.dubbo.rpc.protocol.rest.util.HttpHeaderUtil;
 
 
+import java.lang.reflect.Method;
 import java.util.Arrays;
 import java.util.List;
 
@@ -77,15 +82,15 @@ public class RestRPCInvocationUtil {
      * create parseMethodArgs context
      *
      * @param request
-     * @param servletRequest
-     * @param servletResponse
+     * @param originRequest
+     * @param originResponse
      * @param restMethodMetadata
      * @return
      */
-    private static ProviderParseContext createParseContext(RequestFacade 
request, Object servletRequest, Object servletResponse, RestMethodMetadata 
restMethodMetadata) {
+    private static ProviderParseContext createParseContext(RequestFacade 
request, Object originRequest, Object originResponse, RestMethodMetadata 
restMethodMetadata) {
         ProviderParseContext parseContext = new ProviderParseContext(request);
-        parseContext.setResponse(servletResponse);
-        parseContext.setRequest(servletRequest);
+        parseContext.setResponse(originResponse);
+        parseContext.setRequest(originRequest);
 
         Object[] objects = new Object[restMethodMetadata.getArgInfos().size()];
         parseContext.setArgs(Arrays.asList(objects));
@@ -124,19 +129,105 @@ public class RestRPCInvocationUtil {
 
 
     /**
-     * get  path mapping
+     * get InvokerAndRestMethodMetadataPair by path matcher
+     *
+     * @param pathMatcher
+     * @return
+     */
+    public static InvokerAndRestMethodMetadataPair 
getRestMethodMetadataAndInvokerPair(PathMatcher pathMatcher) {
+
+        PathAndInvokerMapper pathAndInvokerMapper = (PathAndInvokerMapper) 
RpcContext.getServerAttachment().getObjectAttachment(RestConstant.PATH_AND_INVOKER_MAPPER);
+
+        if (pathAndInvokerMapper == null) {
+            return null;
+        }
+        return pathAndInvokerMapper.getRestMethodMetadata(pathMatcher);
+    }
+
+    /**
+     * get  InvokerAndRestMethodMetadataPair from rpc context
+     *
+     * @param request
+     * @return
+     */
+
+    public static InvokerAndRestMethodMetadataPair 
getRestMethodMetadataAndInvokerPair(RequestFacade request) {
+
+
+        PathMatcher pathMather = createPathMatcher(request);
+
+        return getRestMethodMetadataAndInvokerPair(pathMather);
+    }
+
+
+    /**
+     * get  invoker by request
+     *
+     * @param request
+     * @return
+     */
+
+    public static Invoker getInvokerByRequest(RequestFacade request) {
+
+        PathMatcher pathMatcher = createPathMatcher(request);
+
+        return getInvoker(pathMatcher);
+    }
+
+
+    /**
+     * get invoker by service method
+     *
+     * compare method`s name,param types
+     *
+     * @param serviceMethod
+     * @return
+     */
+
+    public static Invoker getInvokerByServiceInvokeMethod(Method 
serviceMethod) {
+
+        if (serviceMethod == null) {
+            return null;
+        }
+
+        InvokerAndRestMethodMetadataPair pair = 
getRestMethodMetadataAndInvokerPair(PathMatcher.getInvokeCreatePathMatcher(serviceMethod));
+
+        if (pair == null) {
+            return null;
+        }
+
+        return pair.getInvoker();
+    }
+
+    /**
+     * get invoker by path matcher
+     *
+     * @param pathMatcher
+     * @return
+     */
+    public static Invoker getInvoker(PathMatcher pathMatcher) {
+        InvokerAndRestMethodMetadataPair pair = 
getRestMethodMetadataAndInvokerPair(pathMatcher);
+
+        if (pair == null) {
+            return null;
+        }
+
+        return pair.getInvoker();
+    }
+
+    /**
+     * create path matcher by request
      *
      * @param request
-     * @param pathAndInvokerMapper
      * @return
      */
-    public static InvokerAndRestMethodMetadataPair 
getRestMethodMetadata(RequestFacade request, PathAndInvokerMapper 
pathAndInvokerMapper) {
+    public static PathMatcher createPathMatcher(RequestFacade request) {
         String path = request.getPath();
         String version = request.getHeader(RestHeaderEnum.VERSION.getHeader());
         String group = request.getHeader(RestHeaderEnum.GROUP.getHeader());
         String method = request.getMethod();
 
-        return pathAndInvokerMapper.getRestMethodMetadata(path, version, 
group, null, method);
+        return PathMatcher.getInvokeCreatePathMatcher(path, version, group, 
null, method);
     }
 
 
diff --git 
a/dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/constans/RestConstant.java
 
b/dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/constans/RestConstant.java
index b853c5477c..09835f8cd6 100644
--- 
a/dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/constans/RestConstant.java
+++ 
b/dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/constans/RestConstant.java
@@ -63,5 +63,10 @@ public interface RestConstant {
     int IDLE_TIMEOUT = -1;
     int KEEP_ALIVE_TIMEOUT = 60;
 
+    /**
+     * ServerAttachment  pathAndInvokerMapper key
+     */
+    String PATH_AND_INVOKER_MAPPER = "pathAndInvokerMapper";
+
 
 }
diff --git 
a/dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/handler/NettyHttpHandler.java
 
b/dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/handler/NettyHttpHandler.java
index 7edf7c4ddf..f82f21737d 100644
--- 
a/dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/handler/NettyHttpHandler.java
+++ 
b/dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/handler/NettyHttpHandler.java
@@ -17,6 +17,7 @@
 package org.apache.dubbo.rpc.protocol.rest.handler;
 
 import io.netty.handler.codec.http.FullHttpRequest;
+import io.netty.handler.codec.http.HttpRequest;
 import org.apache.dubbo.common.logger.ErrorTypeAwareLogger;
 import org.apache.dubbo.common.logger.LoggerFactory;
 import org.apache.dubbo.metadata.rest.RestMethodMetadata;
@@ -44,6 +45,8 @@ import org.apache.dubbo.rpc.protocol.rest.util.MediaTypeUtil;
 
 import java.io.IOException;
 
+import static 
org.apache.dubbo.rpc.protocol.rest.constans.RestConstant.PATH_AND_INVOKER_MAPPER;
+
 /**
  * netty http request handler
  */
@@ -72,6 +75,8 @@ public class NettyHttpHandler implements 
HttpHandler<NettyRequestFacade, NettyHt
 
         // set response
         RpcContext.getServiceContext().setResponse(nettyHttpResponse);
+
+        
RpcContext.getServerAttachment().setObjectAttachment(PATH_AND_INVOKER_MAPPER, 
pathAndInvokerMapper);
         // TODO add request filter chain
 
         FullHttpRequest nettyHttpRequest = requestFacade.getRequest();
@@ -96,9 +101,14 @@ public class NettyHttpHandler implements 
HttpHandler<NettyRequestFacade, NettyHt
 
     }
 
-    private void doHandler(FullHttpRequest nettyHttpRequest, NettyHttpResponse 
nettyHttpResponse, RequestFacade request) throws Exception {
+    protected void doHandler(HttpRequest nettyHttpRequest, NettyHttpResponse 
nettyHttpResponse, RequestFacade request) throws Exception {
         //  acquire metadata by request
-        InvokerAndRestMethodMetadataPair restMethodMetadataPair = 
RestRPCInvocationUtil.getRestMethodMetadata(request, pathAndInvokerMapper);
+        InvokerAndRestMethodMetadataPair restMethodMetadataPair = 
RestRPCInvocationUtil.getRestMethodMetadataAndInvokerPair(request);
+
+        // path NoFound 404
+        if (restMethodMetadataPair == null) {
+            throw new PathNoFoundException("rest service Path no found, 
current path info:" + RestRPCInvocationUtil.createPathMatcher(request));
+        }
 
         Invoker invoker = restMethodMetadataPair.getInvoker();
 
diff --git 
a/dubbo-rpc/dubbo-rpc-rest/src/test/java/org/apache/dubbo/rpc/protocol/rest/JaxrsRestProtocolTest.java
 
b/dubbo-rpc/dubbo-rpc-rest/src/test/java/org/apache/dubbo/rpc/protocol/rest/JaxrsRestProtocolTest.java
index c227ba68f2..b7d529d18e 100644
--- 
a/dubbo-rpc/dubbo-rpc-rest/src/test/java/org/apache/dubbo/rpc/protocol/rest/JaxrsRestProtocolTest.java
+++ 
b/dubbo-rpc/dubbo-rpc-rest/src/test/java/org/apache/dubbo/rpc/protocol/rest/JaxrsRestProtocolTest.java
@@ -49,6 +49,8 @@ import 
org.apache.dubbo.rpc.protocol.rest.rest.HttpMethodServiceImpl;
 import org.apache.dubbo.rpc.protocol.rest.rest.RestDemoForTestException;
 import org.apache.dubbo.rpc.protocol.rest.rest.RestDemoService;
 import org.apache.dubbo.rpc.protocol.rest.rest.RestDemoServiceImpl;
+import org.apache.dubbo.rpc.protocol.rest.rest.TestGetInvokerService;
+import org.apache.dubbo.rpc.protocol.rest.rest.TestGetInvokerServiceImpl;
 import org.hamcrest.CoreMatchers;
 import org.jboss.resteasy.specimpl.MultivaluedMapImpl;
 import org.junit.jupiter.api.AfterEach;
@@ -595,6 +597,27 @@ class JaxrsRestProtocolTest {
         exporter.unexport();
     }
 
+    @Test
+    void testGetInvoker() {
+       Assertions.assertDoesNotThrow(()->{
+           URL exportUrl = URL.valueOf("rest://127.0.0.1:" + availablePort + 
"/rest?interface=org.apache.dubbo.rpc.protocol.rest.rest.TestGetInvokerService");
+
+           TestGetInvokerService server = new TestGetInvokerServiceImpl();
+
+           URL url = this.registerProvider(exportUrl, server, 
DemoService.class);
+
+           Exporter<TestGetInvokerService> exporter = 
protocol.export(proxy.getInvoker(server, TestGetInvokerService.class, url));
+
+           TestGetInvokerService invokerService = 
this.proxy.getProxy(protocol.refer(TestGetInvokerService.class, url));
+
+
+           String invoker = invokerService.getInvoker();
+           Assertions.assertEquals("success", invoker);
+
+           exporter.unexport();
+       });
+    }
+
     private URL registerProvider(URL url, Object impl, Class<?> 
interfaceClass) {
         ServiceDescriptor serviceDescriptor = 
repository.registerService(interfaceClass);
         ProviderModel providerModel = new ProviderModel(
diff --git 
a/dubbo-rpc/dubbo-rpc-rest/src/test/java/org/apache/dubbo/rpc/protocol/rest/rest/TestGetInvokerService.java
 
b/dubbo-rpc/dubbo-rpc-rest/src/test/java/org/apache/dubbo/rpc/protocol/rest/rest/TestGetInvokerService.java
new file mode 100644
index 0000000000..39b42e740b
--- /dev/null
+++ 
b/dubbo-rpc/dubbo-rpc-rest/src/test/java/org/apache/dubbo/rpc/protocol/rest/rest/TestGetInvokerService.java
@@ -0,0 +1,30 @@
+/*
+ * 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 org.apache.dubbo.rpc.protocol.rest.rest;
+
+
+import javax.ws.rs.GET;
+import javax.ws.rs.Path;
+
+@Path("/test")
+public interface TestGetInvokerService {
+
+
+    @GET
+    @Path("/getInvoker")
+    String getInvoker();
+}
diff --git 
a/dubbo-rpc/dubbo-rpc-rest/src/test/java/org/apache/dubbo/rpc/protocol/rest/rest/TestGetInvokerServiceImpl.java
 
b/dubbo-rpc/dubbo-rpc-rest/src/test/java/org/apache/dubbo/rpc/protocol/rest/rest/TestGetInvokerServiceImpl.java
new file mode 100644
index 0000000000..b61f4afdfa
--- /dev/null
+++ 
b/dubbo-rpc/dubbo-rpc-rest/src/test/java/org/apache/dubbo/rpc/protocol/rest/rest/TestGetInvokerServiceImpl.java
@@ -0,0 +1,57 @@
+/*
+ * 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 org.apache.dubbo.rpc.protocol.rest.rest;
+
+
+import org.apache.dubbo.rpc.Invoker;
+import org.apache.dubbo.rpc.RpcContext;
+import org.apache.dubbo.rpc.protocol.rest.RestRPCInvocationUtil;
+import org.apache.dubbo.rpc.protocol.rest.request.RequestFacade;
+import org.junit.jupiter.api.Assertions;
+
+import java.lang.reflect.Method;
+
+public class TestGetInvokerServiceImpl implements TestGetInvokerService {
+
+
+    @Override
+    public String getInvoker() {
+        Object request = RpcContext.getServiceContext().getRequest();
+        Invoker invokerByRequest = 
RestRPCInvocationUtil.getInvokerByRequest((RequestFacade) request);
+
+
+        Method hello = null;
+        Method hashcode = null;
+        try {
+            hello = 
TestGetInvokerServiceImpl.class.getDeclaredMethod("getInvoker");
+            hashcode = 
TestGetInvokerServiceImpl.class.getDeclaredMethod("hashcode");
+
+        } catch (NoSuchMethodException e) {
+
+        }
+
+        Invoker invokerByServiceInvokeMethod = 
RestRPCInvocationUtil.getInvokerByServiceInvokeMethod(hello);
+
+        Invoker invoker = 
RestRPCInvocationUtil.getInvokerByServiceInvokeMethod(hashcode);
+
+
+        Assertions.assertEquals(invokerByRequest, 
invokerByServiceInvokeMethod);
+        Assertions.assertNull(invoker);
+
+        return "success";
+    }
+}

Reply via email to