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";
+ }
+}