This is an automated email from the ASF dual-hosted git repository.
albumenj 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 c5a03c9458 Rest bugfix & optimization (#11617)
c5a03c9458 is described below
commit c5a03c94581e6a68443146ead2b632c34c2f6138
Author: Mengyang Tang <[email protected]>
AuthorDate: Thu Feb 23 09:40:25 2023 +0800
Rest bugfix & optimization (#11617)
* Modifier optimize
* rawtypes problem optimize
* Remove commented redundant code
* Constants optimize
* Fix consistency bug
* Support exception mapper extension
* resolve conflict
---
.../rpc/protocol/rest/BaseRestProtocolServer.java | 12 ++++----
.../apache/dubbo/rpc/protocol/rest/Constants.java | 14 ++++++++-
.../rpc/protocol/rest/DubboHttpProtocolServer.java | 9 +++---
.../rpc/protocol/rest/DubboResourceFactory.java | 22 ++------------
.../rpc/protocol/rest/NettyRestProtocolServer.java | 3 +-
.../rpc/protocol/rest/ReferenceCountedClient.java | 2 +-
.../dubbo/rpc/protocol/rest/RestProtocol.java | 35 +++++++++++++---------
.../rpc/protocol/rest/RestProtocolServer.java | 4 +--
.../dubbo/rpc/protocol/rest/RestServerFactory.java | 5 ++--
.../dubbo/rpc/protocol/rest/RpcContextFilter.java | 9 +++---
.../rpc/protocol/rest/RpcExceptionMapper.java | 11 +++----
.../rpc/protocol/rest/JaxrsRestProtocolTest.java | 31 +++++++++++++++++--
.../rpc/protocol/rest/RpcExceptionMapperTest.java | 4 +--
13 files changed, 94 insertions(+), 67 deletions(-)
diff --git
a/dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/BaseRestProtocolServer.java
b/dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/BaseRestProtocolServer.java
index 95bdccb707..baa0fff9cc 100644
---
a/dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/BaseRestProtocolServer.java
+++
b/dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/BaseRestProtocolServer.java
@@ -25,22 +25,22 @@ import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import static
org.apache.dubbo.common.constants.CommonConstants.COMMA_SPLIT_PATTERN;
+import static
org.apache.dubbo.rpc.protocol.rest.Constants.EXCEPTION_MAPPER_KEY;
import static org.apache.dubbo.rpc.protocol.rest.Constants.EXTENSION_KEY;
public abstract class BaseRestProtocolServer implements RestProtocolServer {
private String address;
- private Map<String, Object> attributes = new ConcurrentHashMap<>();
+ private final Map<String, Object> attributes = new ConcurrentHashMap<>();
@Override
public void start(URL url) {
getDeployment().getMediaTypeMappings().put("json", "application/json");
getDeployment().getMediaTypeMappings().put("xml", "text/xml");
-// server.getDeployment().getMediaTypeMappings().put("xml",
"application/xml");
getDeployment().getProviderClasses().add(RpcContextFilter.class.getName());
- // TODO users can override this mapper, but we just rely on the
current priority strategy of resteasy
-
getDeployment().getProviderClasses().add(RpcExceptionMapper.class.getName());
+
+ loadProviders(url.getParameter(EXCEPTION_MAPPER_KEY,
RpcExceptionMapper.class.getName()));
loadProviders(url.getParameter(EXTENSION_KEY, ""));
@@ -48,7 +48,7 @@ public abstract class BaseRestProtocolServer implements
RestProtocolServer {
}
@Override
- public void deploy(Class resourceDef, Object resourceInstance, String
contextPath) {
+ public void deploy(Class<?> resourceDef, Object resourceInstance, String
contextPath) {
if (StringUtils.isEmpty(contextPath)) {
getDeployment().getRegistry().addResourceFactory(new
DubboResourceFactory(resourceInstance, resourceDef));
} else {
@@ -57,7 +57,7 @@ public abstract class BaseRestProtocolServer implements
RestProtocolServer {
}
@Override
- public void undeploy(Class resourceDef) {
+ public void undeploy(Class<?> resourceDef) {
getDeployment().getRegistry().removeRegistrations(resourceDef);
}
diff --git
a/dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/Constants.java
b/dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/Constants.java
index 90747c9a3a..8966315425 100644
---
a/dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/Constants.java
+++
b/dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/Constants.java
@@ -18,7 +18,7 @@
package org.apache.dubbo.rpc.protocol.rest;
/**
- *
+ * Constants definition.
*/
public interface Constants {
String KEEP_ALIVE_KEY = "keepalive";
@@ -26,4 +26,16 @@ public interface Constants {
boolean DEFAULT_KEEP_ALIVE = true;
String EXTENSION_KEY = "extension";
+
+ // http server
+ String SERVLET = "servlet";
+
+ String JETTY = "jetty";
+
+ String TOMCAT = "tomcat";
+
+ String NETTY = "netty";
+
+ // exception mapper
+ String EXCEPTION_MAPPER_KEY = "exception.mapper";
}
diff --git
a/dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/DubboHttpProtocolServer.java
b/dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/DubboHttpProtocolServer.java
index 71db6b963a..475238d548 100644
---
a/dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/DubboHttpProtocolServer.java
+++
b/dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/DubboHttpProtocolServer.java
@@ -40,9 +40,8 @@ public class DubboHttpProtocolServer extends
BaseRestProtocolServer {
private final HttpServletDispatcher dispatcher = new
HttpServletDispatcher();
private final ResteasyDeployment deployment = new ResteasyDeployment();
- private HttpBinder httpBinder;
+ private final HttpBinder httpBinder;
private HttpServer httpServer;
-// private boolean isExternalServer;
public DubboHttpProtocolServer(HttpBinder httpBinder) {
this.httpBinder = httpBinder;
@@ -114,15 +113,15 @@ public class DubboHttpProtocolServer extends
BaseRestProtocolServer {
}
@Override
- public Enumeration getInitParameterNames() {
- return new Enumeration() {
+ public Enumeration<String> getInitParameterNames() {
+ return new Enumeration<String>() {
@Override
public boolean hasMoreElements() {
return false;
}
@Override
- public Object nextElement() {
+ public String nextElement() {
return null;
}
};
diff --git
a/dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/DubboResourceFactory.java
b/dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/DubboResourceFactory.java
index 191102e2cd..ac8695ccc4 100644
---
a/dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/DubboResourceFactory.java
+++
b/dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/DubboResourceFactory.java
@@ -23,24 +23,17 @@ import org.jboss.resteasy.spi.ResteasyProviderFactory;
/**
* We don't support propertyInjector here since the resource impl should be
singleton in dubbo
- *
*/
public class DubboResourceFactory implements ResourceFactory {
- private Object resourceInstance;
- private Class scannableClass;
-// private PropertyInjector propertyInjector;
-// private String context = null;
+ private final Object resourceInstance;
+ private final Class<?> scannableClass;
- public DubboResourceFactory(Object resourceInstance, Class scannableClass)
{
+ public DubboResourceFactory(Object resourceInstance, Class<?>
scannableClass) {
this.resourceInstance = resourceInstance;
this.scannableClass = scannableClass;
}
-// public PropertyInjector getPropertyInjector() {
-// return propertyInjector;
-// }
-
@Override
public Object createResource(HttpRequest request, HttpResponse response,
ResteasyProviderFactory factory) {
@@ -54,7 +47,6 @@ public class DubboResourceFactory implements ResourceFactory {
@Override
public void registered(ResteasyProviderFactory factory) {
-// this.propertyInjector =
factory.getInjectorFactory().createPropertyInjector(getScannableClass(),
factory);
}
@Override
@@ -65,12 +57,4 @@ public class DubboResourceFactory implements ResourceFactory
{
@Override
public void unregistered() {
}
-
-// public void setContext(String context) {
-// this.context = context;
-// }
-//
-// public String getContext() {
-// return context;
-// }
}
diff --git
a/dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/NettyRestProtocolServer.java
b/dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/NettyRestProtocolServer.java
index b066c79f43..fbb9be782e 100644
---
a/dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/NettyRestProtocolServer.java
+++
b/dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/NettyRestProtocolServer.java
@@ -46,13 +46,14 @@ public class NettyRestProtocolServer extends
BaseRestProtocolServer {
private final NettyJaxrsServer server = new NettyJaxrsServer();
@Override
+ @SuppressWarnings("rawtypes")
protected void doStart(URL url) {
String bindIp = url.getParameter(BIND_IP_KEY, url.getHost());
if (!url.isAnyHost() && NetUtils.isValidLocalHost(bindIp)) {
server.setHostname(bindIp);
}
server.setPort(url.getParameter(BIND_PORT_KEY, url.getPort()));
- Map<ChannelOption, Object> channelOption = new HashMap<ChannelOption,
Object>();
+ Map<ChannelOption, Object> channelOption = new HashMap<>();
channelOption.put(ChannelOption.SO_KEEPALIVE,
url.getParameter(KEEP_ALIVE_KEY, DEFAULT_KEEP_ALIVE));
server.setChildChannelOptions(channelOption);
server.setExecutorThreadCount(url.getParameter(THREADS_KEY,
DEFAULT_THREADS));
diff --git
a/dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/ReferenceCountedClient.java
b/dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/ReferenceCountedClient.java
index fc8d4664c8..22de2147c2 100644
---
a/dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/ReferenceCountedClient.java
+++
b/dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/ReferenceCountedClient.java
@@ -26,7 +26,7 @@ import static
org.apache.dubbo.common.constants.LoggerCodeConstants.PROTOCOL_ERR
public class ReferenceCountedClient<T extends RestClient> extends
ReferenceCountedResource {
private static final ErrorTypeAwareLogger logger =
LoggerFactory.getErrorTypeAwareLogger(ReferenceCountedClient.class);
- private T client;
+ private final T client;
public ReferenceCountedClient(T client) {
this.client = client;
diff --git
a/dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/RestProtocol.java
b/dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/RestProtocol.java
index 90e254be71..4cd8376263 100644
---
a/dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/RestProtocol.java
+++
b/dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/RestProtocol.java
@@ -65,12 +65,12 @@ import static
org.apache.dubbo.common.constants.LoggerCodeConstants.PROTOCOL_ERR
import static
org.apache.dubbo.common.constants.LoggerCodeConstants.PROTOCOL_ERROR_CLOSE_SERVER;
import static org.apache.dubbo.remoting.Constants.SERVER_KEY;
import static org.apache.dubbo.rpc.Constants.TOKEN_KEY;
+import static
org.apache.dubbo.rpc.protocol.rest.constans.RestConstant.PATH_SEPARATOR;
public class RestProtocol extends AbstractProxyProtocol {
private static final int DEFAULT_PORT = 80;
- private static final String DEFAULT_SERVER = "jetty";
- private static final String DEFAULT_CLIENT =
org.apache.dubbo.remoting.Constants.OK_HTTP;
+ private static final String DEFAULT_SERVER = Constants.JETTY;
private final RestServerFactory serverFactory = new RestServerFactory();
@@ -95,7 +95,7 @@ public class RestProtocol extends AbstractProxyProtocol {
@Override
protected <T> Runnable doExport(T impl, Class<T> type, URL url) throws
RpcException {
String addr = getAddr(url);
- Class implClass = url.getServiceModel().getProxyObject().getClass();
+ Class<?> implClass = url.getServiceModel().getProxyObject().getClass();
RestProtocolServer server = (RestProtocolServer)
ConcurrentHashMapUtils.computeIfAbsent(serverMap, addr, restServer -> {
RestProtocolServer s =
serverFactory.createServer(url.getParameter(SERVER_KEY, DEFAULT_SERVER));
s.setAddress(url.getAddress());
@@ -104,7 +104,7 @@ public class RestProtocol extends AbstractProxyProtocol {
});
String contextPath = getContextPath(url);
- if ("servlet".equalsIgnoreCase(url.getParameter(SERVER_KEY,
DEFAULT_SERVER))) {
+ if (Constants.SERVLET.equalsIgnoreCase(url.getParameter(SERVER_KEY,
DEFAULT_SERVER))) {
ServletContext servletContext =
ServletManager.getInstance().getServletContext(ServletManager.EXTERNAL_SERVER_PORT);
if (servletContext == null) {
throw new RpcException("No servlet context found. Since you
are using server='servlet', " +
@@ -118,13 +118,13 @@ public class RestProtocol extends AbstractProxyProtocol {
"make sure that the 'contextpath' property starts with
the path of external webapp");
}
contextPath = contextPath.substring(webappPath.length());
- if (contextPath.startsWith("/")) {
+ if (contextPath.startsWith(PATH_SEPARATOR)) {
contextPath = contextPath.substring(1);
}
}
}
- final Class resourceDef = GetRestful.getRootResourceClass(implClass)
!= null ? implClass : type;
+ final Class<?> resourceDef =
GetRestful.getRootResourceClass(implClass) != null ? implClass : type;
server.deploy(resourceDef, impl, contextPath);
@@ -136,15 +136,22 @@ public class RestProtocol extends AbstractProxyProtocol {
};
}
-
@Override
protected <T> Invoker<T> protocolBindingRefer(final Class<T> type, final
URL url) throws RpcException {
- ReferenceCountedClient<? extends RestClient> refClient =
- clients.computeIfAbsent(url.getAddress(), key ->
createReferenceCountedClient(url));
-
+ ReferenceCountedClient<? extends RestClient> refClient =
clients.get(url.getAddress());
+ if (refClient == null || refClient.isDestroyed()) {
+ synchronized (clients) {
+ refClient = clients.get(url.getAddress());
+ if (refClient == null || refClient.isDestroyed()) {
+ refClient =
ConcurrentHashMapUtils.computeIfAbsent(clients, url.getAddress(), _key ->
createReferenceCountedClient(url));
+ }
+ }
+ }
refClient.retain();
+ final ReferenceCountedClient<? extends RestClient> glueRefClient =
refClient;
+
// resolve metadata
Map<String, Map<ParameterTypesComparator, RestMethodMetadata>>
metadataMap = MetadataResolver.resolveConsumerServiceMetadata(type, url);
@@ -168,7 +175,7 @@ public class RestProtocol extends AbstractProxyProtocol {
intercept.intercept(httpConnectionCreateContext);
}
- CompletableFuture<RestResult> future =
refClient.getClient().send(requestTemplate);
+ CompletableFuture<RestResult> future =
glueRefClient.getClient().send(requestTemplate);
CompletableFuture<AppResponse> responseFuture = new
CompletableFuture<>();
AsyncRpcResult asyncRpcResult = new
AsyncRpcResult(responseFuture, invocation);
future.whenComplete((r, t) -> {
@@ -260,7 +267,7 @@ public class RestProtocol extends AbstractProxyProtocol {
if (logger.isInfoEnabled()) {
logger.info("Closing rest clients");
}
- for (ReferenceCountedClient client : clients.values()) {
+ for (ReferenceCountedClient<?> client : clients.values()) {
try {
// destroy directly regardless of the current reference count.
client.destroy();
@@ -287,7 +294,7 @@ public class RestProtocol extends AbstractProxyProtocol {
if (contextPath.endsWith(url.getParameter(INTERFACE_KEY))) {
contextPath = contextPath.substring(0,
contextPath.lastIndexOf(url.getParameter(INTERFACE_KEY)));
}
- return contextPath.endsWith("/") ? contextPath.substring(0,
contextPath.length() - 1) : contextPath;
+ return contextPath.endsWith(PATH_SEPARATOR) ?
contextPath.substring(0, contextPath.length() - 1) : contextPath;
} else {
return "";
}
@@ -296,7 +303,7 @@ public class RestProtocol extends AbstractProxyProtocol {
@Override
protected void destroyInternal(URL url) {
try {
- ReferenceCountedClient referenceCountedClient =
clients.get(url.getAddress());
+ ReferenceCountedClient<?> referenceCountedClient =
clients.get(url.getAddress());
if (referenceCountedClient != null &&
referenceCountedClient.release()) {
clients.remove(url.getAddress());
}
diff --git
a/dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/RestProtocolServer.java
b/dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/RestProtocolServer.java
index fe16f4687f..ee03685662 100644
---
a/dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/RestProtocolServer.java
+++
b/dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/RestProtocolServer.java
@@ -26,8 +26,8 @@ public interface RestProtocolServer extends ProtocolServer {
/**
* @param resourceDef it could be either resource interface or resource
impl
*/
- void deploy(Class resourceDef, Object resourceInstance, String
contextPath);
+ void deploy(Class<?> resourceDef, Object resourceInstance, String
contextPath);
- void undeploy(Class resourceDef);
+ void undeploy(Class<?> resourceDef);
}
diff --git
a/dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/RestServerFactory.java
b/dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/RestServerFactory.java
index 265987241e..01c0df5aed 100644
---
a/dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/RestServerFactory.java
+++
b/dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/RestServerFactory.java
@@ -28,10 +28,9 @@ public class RestServerFactory {
private static final HttpBinder httpBinder =
FrameworkModel.defaultModel().getAdaptiveExtension(HttpBinder.class);
public RestProtocolServer createServer(String name) {
- // TODO move names to Constants
- if ("servlet".equalsIgnoreCase(name) || "jetty".equalsIgnoreCase(name)
|| "tomcat".equalsIgnoreCase(name)) {
+ if (Constants.SERVLET.equalsIgnoreCase(name) ||
Constants.JETTY.equalsIgnoreCase(name) ||
Constants.TOMCAT.equalsIgnoreCase(name)) {
return new DubboHttpProtocolServer(httpBinder);
- } else if ("netty".equalsIgnoreCase(name)) {
+ } else if (Constants.NETTY.equalsIgnoreCase(name)) {
return new NettyRestProtocolServer();
} else {
throw new IllegalArgumentException("Unrecognized server name: " +
name);
diff --git
a/dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/RpcContextFilter.java
b/dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/RpcContextFilter.java
index 70edad5bcc..3572ea67e3 100644
---
a/dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/RpcContextFilter.java
+++
b/dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/RpcContextFilter.java
@@ -16,6 +16,7 @@
*/
package org.apache.dubbo.rpc.protocol.rest;
+import org.apache.dubbo.common.constants.CommonConstants;
import org.apache.dubbo.common.utils.CollectionUtils;
import org.apache.dubbo.common.utils.StringUtils;
import org.apache.dubbo.rpc.Invocation;
@@ -40,7 +41,7 @@ public class RpcContextFilter implements
ContainerRequestFilter, ClientRequestFi
private static final String DUBBO_ATTACHMENT_HEADER = "Dubbo-Attachments";
- // currently we use a single header to hold the attachments so that the
total attachment size limit is about 8k
+ // currently, we use a single header to hold the attachments so that the
total attachment size limit is about 8k
private static final int MAX_HEADER_SIZE = 8 * 1024;
@Override
@@ -57,7 +58,7 @@ public class RpcContextFilter implements
ContainerRequestFilter, ClientRequestFi
String headers =
requestContext.getHeaderString(DUBBO_ATTACHMENT_HEADER);
if (headers != null) {
- for (String header : headers.split(",")) {
+ for (String header :
headers.split(CommonConstants.COMMA_SEPARATOR)) {
int index = header.indexOf("=");
if (index > 0) {
String key = header.substring(0, index);
@@ -101,14 +102,14 @@ public class RpcContextFilter implements
ContainerRequestFilter, ClientRequestFi
private boolean illegalHttpHeaderKey(String key) {
if (StringUtils.isNotEmpty(key)) {
- return key.contains(",") || key.contains("=");
+ return key.contains(CommonConstants.COMMA_SEPARATOR) ||
key.contains("=");
}
return false;
}
private boolean illegalHttpHeaderValue(String value) {
if (StringUtils.isNotEmpty(value)) {
- return value.contains(",");
+ return value.contains(CommonConstants.COMMA_SEPARATOR);
}
return false;
}
diff --git
a/dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/RpcExceptionMapper.java
b/dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/RpcExceptionMapper.java
index e0fb782607..de6d2e45a6 100644
---
a/dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/RpcExceptionMapper.java
+++
b/dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/RpcExceptionMapper.java
@@ -28,24 +28,21 @@ public class RpcExceptionMapper implements
ExceptionMapper<RpcException> {
@Override
public Response toResponse(RpcException e) {
- // TODO do more sophisticated exception handling and output
if (e.getCause() instanceof ConstraintViolationException) {
return
handleConstraintViolationException((ConstraintViolationException) e.getCause());
}
// we may want to avoid exposing the dubbo exception details to
certain clients
- // TODO for now just do plain text output
return
Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity("Internal server
error: " + e.getMessage()).type(ContentType.TEXT_PLAIN_UTF_8).build();
}
protected Response
handleConstraintViolationException(ConstraintViolationException cve) {
ViolationReport report = new ViolationReport();
- for (ConstraintViolation cv : cve.getConstraintViolations()) {
+ for (ConstraintViolation<?> cv : cve.getConstraintViolations()) {
report.addConstraintViolation(new RestConstraintViolation(
- cv.getPropertyPath().toString(),
- cv.getMessage(),
- cv.getInvalidValue() == null ? "null" :
cv.getInvalidValue().toString()));
+ cv.getPropertyPath().toString(),
+ cv.getMessage(),
+ cv.getInvalidValue() == null ? "null" :
cv.getInvalidValue().toString()));
}
- // TODO for now just do xml output
return
Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(report).type(ContentType.TEXT_XML_UTF_8).build();
}
}
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 3c4510056b..cff2d73222 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
@@ -35,15 +35,19 @@ import org.apache.dubbo.rpc.model.ServiceDescriptor;
import org.apache.dubbo.rpc.protocol.rest.rest.AnotherUserRestService;
import org.apache.dubbo.rpc.protocol.rest.rest.AnotherUserRestServiceImpl;
+
import org.hamcrest.CoreMatchers;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
+import javax.ws.rs.core.Response;
+import javax.ws.rs.ext.ExceptionMapper;
import java.util.Arrays;
import java.util.Map;
import static org.apache.dubbo.remoting.Constants.SERVER_KEY;
+import static
org.apache.dubbo.rpc.protocol.rest.Constants.EXCEPTION_MAPPER_KEY;
import static org.apache.dubbo.rpc.protocol.rest.Constants.EXTENSION_KEY;
import static org.hamcrest.CoreMatchers.equalTo;
import static org.hamcrest.CoreMatchers.is;
@@ -51,8 +55,8 @@ import static org.hamcrest.CoreMatchers.nullValue;
import static org.hamcrest.MatcherAssert.assertThat;
class JaxrsRestProtocolTest {
- private Protocol protocol =
ExtensionLoader.getExtensionLoader(Protocol.class).getExtension("rest");
- private ProxyFactory proxy =
ExtensionLoader.getExtensionLoader(ProxyFactory.class).getAdaptiveExtension();
+ private final Protocol protocol =
ExtensionLoader.getExtensionLoader(Protocol.class).getExtension("rest");
+ private final ProxyFactory proxy =
ExtensionLoader.getExtensionLoader(ProxyFactory.class).getAdaptiveExtension();
private final int availablePort = NetUtils.getAvailablePort();
private final URL exportUrl = URL.valueOf("rest://127.0.0.1:" +
availablePort +
"/rest?interface=org.apache.dubbo.rpc.protocol.rest.DemoService");
private final ModuleServiceRepository repository =
ApplicationModel.defaultModel().getDefaultModule().getServiceRepository();
@@ -282,6 +286,29 @@ class JaxrsRestProtocolTest {
assertThat(protocol.getDefaultPort(), is(80));
}
+ @Test
+ void testExceptionMapper() {
+ DemoService server = new DemoServiceImpl();
+
+ URL url = this.registerProvider(exportUrl, server, DemoService.class);
+
+ URL exceptionUrl = url.addParameter(EXCEPTION_MAPPER_KEY,
TestExceptionMapper.class.getName());
+
+ protocol.export(proxy.getInvoker(server, DemoService.class,
exceptionUrl));
+
+ DemoService referDemoService =
this.proxy.getProxy(protocol.refer(DemoService.class, exceptionUrl));
+
+ Assertions.assertEquals("test-exception", referDemoService.error());
+ }
+
+ public static class TestExceptionMapper implements
ExceptionMapper<RuntimeException> {
+
+ @Override
+ public Response toResponse(RuntimeException e) {
+ return Response.ok("test-exception").build();
+ }
+ }
+
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/RpcExceptionMapperTest.java
b/dubbo-rpc/dubbo-rpc-rest/src/test/java/org/apache/dubbo/rpc/protocol/rest/RpcExceptionMapperTest.java
index 5d4410ed7e..b8a983c055 100644
---
a/dubbo-rpc/dubbo-rpc-rest/src/test/java/org/apache/dubbo/rpc/protocol/rest/RpcExceptionMapperTest.java
+++
b/dubbo-rpc/dubbo-rpc-rest/src/test/java/org/apache/dubbo/rpc/protocol/rest/RpcExceptionMapperTest.java
@@ -46,8 +46,8 @@ class RpcExceptionMapperTest {
@Test
void testConstraintViolationException() {
ConstraintViolationException violationException =
mock(ConstraintViolationException.class);
- ConstraintViolation violation = mock(ConstraintViolation.class,
Answers.RETURNS_DEEP_STUBS);
-
given(violationException.getConstraintViolations()).willReturn(Sets.<ConstraintViolation<?>>newSet(violation));
+ ConstraintViolation<?> violation = mock(ConstraintViolation.class,
Answers.RETURNS_DEEP_STUBS);
+
given(violationException.getConstraintViolations()).willReturn(Sets.newSet(violation));
RpcException rpcException = new RpcException("violation",
violationException);
Response response = exceptionMapper.toResponse(rpcException);