chickenlj closed pull request #1827: support generic invoke and attachment for
http/hessian protocol
URL: https://github.com/apache/incubator-dubbo/pull/1827
This is a PR merged from a forked repository.
As GitHub hides the original diff on merge, it is displayed below for
the sake of provenance:
As this is a foreign pull request (from a fork), the diff is supplied
below (as it won't show otherwise due to GitHub magic):
diff --git
a/dubbo-config/dubbo-config-api/src/test/java/com/alibaba/dubbo/config/mock/MockProxyFactory.java
b/dubbo-config/dubbo-config-api/src/test/java/com/alibaba/dubbo/config/mock/MockProxyFactory.java
index 3de2e3a983..cd78366c00 100644
---
a/dubbo-config/dubbo-config-api/src/test/java/com/alibaba/dubbo/config/mock/MockProxyFactory.java
+++
b/dubbo-config/dubbo-config-api/src/test/java/com/alibaba/dubbo/config/mock/MockProxyFactory.java
@@ -27,6 +27,11 @@
return null;
}
+ @Override
+ public <T> T getProxy(Invoker<T> invoker, boolean generic) throws
RpcException {
+ return null;
+ }
+
@Override
public <T> Invoker<T> getInvoker(T proxy, Class<T> type, URL url) throws
RpcException {
return null;
diff --git
a/dubbo-rpc/dubbo-rpc-api/src/main/java/com/alibaba/dubbo/rpc/ProxyFactory.java
b/dubbo-rpc/dubbo-rpc-api/src/main/java/com/alibaba/dubbo/rpc/ProxyFactory.java
index 6ba705717b..fb03d6bda4 100644
---
a/dubbo-rpc/dubbo-rpc-api/src/main/java/com/alibaba/dubbo/rpc/ProxyFactory.java
+++
b/dubbo-rpc/dubbo-rpc-api/src/main/java/com/alibaba/dubbo/rpc/ProxyFactory.java
@@ -36,6 +36,15 @@
@Adaptive({Constants.PROXY_KEY})
<T> T getProxy(Invoker<T> invoker) throws RpcException;
+ /**
+ * create proxy.
+ *
+ * @param invoker
+ * @return proxy
+ */
+ @Adaptive({Constants.PROXY_KEY})
+ <T> T getProxy(Invoker<T> invoker, boolean generic) throws RpcException;
+
/**
* create invoker.
*
diff --git
a/dubbo-rpc/dubbo-rpc-api/src/main/java/com/alibaba/dubbo/rpc/filter/GenericFilter.java
b/dubbo-rpc/dubbo-rpc-api/src/main/java/com/alibaba/dubbo/rpc/filter/GenericFilter.java
index d393822625..8404a99f3c 100644
---
a/dubbo-rpc/dubbo-rpc-api/src/main/java/com/alibaba/dubbo/rpc/filter/GenericFilter.java
+++
b/dubbo-rpc/dubbo-rpc-api/src/main/java/com/alibaba/dubbo/rpc/filter/GenericFilter.java
@@ -32,10 +32,12 @@
import com.alibaba.dubbo.rpc.Invocation;
import com.alibaba.dubbo.rpc.Invoker;
import com.alibaba.dubbo.rpc.Result;
+import com.alibaba.dubbo.rpc.RpcContext;
import com.alibaba.dubbo.rpc.RpcException;
import com.alibaba.dubbo.rpc.RpcInvocation;
import com.alibaba.dubbo.rpc.RpcResult;
import com.alibaba.dubbo.rpc.service.GenericException;
+import com.alibaba.dubbo.rpc.service.GenericService;
import com.alibaba.dubbo.rpc.support.ProtocolUtils;
import java.io.IOException;
@@ -52,7 +54,7 @@ public Result invoke(Invoker<?> invoker, Invocation inv)
throws RpcException {
if (inv.getMethodName().equals(Constants.$INVOKE)
&& inv.getArguments() != null
&& inv.getArguments().length == 3
- &&
!ProtocolUtils.isGeneric(invoker.getUrl().getParameter(Constants.GENERIC_KEY)))
{
+ && !invoker.getInterface().equals(GenericService.class)) {
String name = ((String) inv.getArguments()[0]).trim();
String[] types = (String[]) inv.getArguments()[1];
Object[] args = (Object[]) inv.getArguments()[2];
@@ -63,6 +65,11 @@ public Result invoke(Invoker<?> invoker, Invocation inv)
throws RpcException {
args = new Object[params.length];
}
String generic = inv.getAttachment(Constants.GENERIC_KEY);
+
+ if (StringUtils.isBlank(generic)) {
+ generic =
RpcContext.getContext().getAttachment(Constants.GENERIC_KEY);
+ }
+
if (StringUtils.isEmpty(generic)
||
ProtocolUtils.isDefaultGenericSerialization(generic)) {
args = PojoUtils.realize(args, params,
method.getGenericParameterTypes());
diff --git
a/dubbo-rpc/dubbo-rpc-api/src/main/java/com/alibaba/dubbo/rpc/filter/GenericImplFilter.java
b/dubbo-rpc/dubbo-rpc-api/src/main/java/com/alibaba/dubbo/rpc/filter/GenericImplFilter.java
index 99bced54e7..6be08fef47 100644
---
a/dubbo-rpc/dubbo-rpc-api/src/main/java/com/alibaba/dubbo/rpc/filter/GenericImplFilter.java
+++
b/dubbo-rpc/dubbo-rpc-api/src/main/java/com/alibaba/dubbo/rpc/filter/GenericImplFilter.java
@@ -155,13 +155,13 @@ public Result invoke(Invoker<?> invoker, Invocation
invocation) throws RpcExcept
for (Object arg : args) {
if (!(byte[].class == arg.getClass())) {
- error(byte[].class.getName(),
arg.getClass().getName());
+ error(generic, byte[].class.getName(),
arg.getClass().getName());
}
}
} else if (ProtocolUtils.isBeanGenericSerialization(generic)) {
for (Object arg : args) {
if (!(arg instanceof JavaBeanDescriptor)) {
- error(JavaBeanDescriptor.class.getName(),
arg.getClass().getName());
+ error(generic, JavaBeanDescriptor.class.getName(),
arg.getClass().getName());
}
}
}
@@ -172,10 +172,10 @@ public Result invoke(Invoker<?> invoker, Invocation
invocation) throws RpcExcept
return invoker.invoke(invocation);
}
- private void error(String expected, String actual) throws RpcException {
+ private void error(String generic, String expected, String actual) throws
RpcException {
throw new RpcException(
"Generic serialization [" +
- Constants.GENERIC_SERIALIZATION_NATIVE_JAVA +
+ generic +
"] only support message type " +
expected +
" and your message type is " +
diff --git
a/dubbo-rpc/dubbo-rpc-api/src/main/java/com/alibaba/dubbo/rpc/protocol/AbstractProxyProtocol.java
b/dubbo-rpc/dubbo-rpc-api/src/main/java/com/alibaba/dubbo/rpc/protocol/AbstractProxyProtocol.java
index 8136cc0216..561520c49e 100644
---
a/dubbo-rpc/dubbo-rpc-api/src/main/java/com/alibaba/dubbo/rpc/protocol/AbstractProxyProtocol.java
+++
b/dubbo-rpc/dubbo-rpc-api/src/main/java/com/alibaba/dubbo/rpc/protocol/AbstractProxyProtocol.java
@@ -68,7 +68,7 @@ public void setProxyFactory(ProxyFactory proxyFactory) {
if (exporter != null) {
return exporter;
}
- final Runnable runnable = doExport(proxyFactory.getProxy(invoker),
invoker.getInterface(), invoker.getUrl());
+ final Runnable runnable = doExport(proxyFactory.getProxy(invoker,
true), invoker.getInterface(), invoker.getUrl());
exporter = new AbstractExporter<T>(invoker) {
@Override
public void unexport() {
@@ -89,12 +89,12 @@ public void unexport() {
@Override
public <T> Invoker<T> refer(final Class<T> type, final URL url) throws
RpcException {
- final Invoker<T> tagert = proxyFactory.getInvoker(doRefer(type, url),
type, url);
+ final Invoker<T> target = proxyFactory.getInvoker(doRefer(type, url),
type, url);
Invoker<T> invoker = new AbstractInvoker<T>(type, url) {
@Override
protected Result doInvoke(Invocation invocation) throws Throwable {
try {
- Result result = tagert.invoke(invocation);
+ Result result = target.invoke(invocation);
Throwable e = result.getException();
if (e != null) {
for (Class<?> rpcException : rpcExceptions) {
diff --git
a/dubbo-rpc/dubbo-rpc-api/src/main/java/com/alibaba/dubbo/rpc/proxy/AbstractProxyFactory.java
b/dubbo-rpc/dubbo-rpc-api/src/main/java/com/alibaba/dubbo/rpc/proxy/AbstractProxyFactory.java
index 21c350da9c..d27f608970 100644
---
a/dubbo-rpc/dubbo-rpc-api/src/main/java/com/alibaba/dubbo/rpc/proxy/AbstractProxyFactory.java
+++
b/dubbo-rpc/dubbo-rpc-api/src/main/java/com/alibaba/dubbo/rpc/proxy/AbstractProxyFactory.java
@@ -22,6 +22,7 @@
import com.alibaba.dubbo.rpc.ProxyFactory;
import com.alibaba.dubbo.rpc.RpcException;
import com.alibaba.dubbo.rpc.service.EchoService;
+import com.alibaba.dubbo.rpc.service.GenericService;
/**
* AbstractProxyFactory
@@ -30,6 +31,11 @@
@Override
public <T> T getProxy(Invoker<T> invoker) throws RpcException {
+ return getProxy(invoker, false);
+ }
+
+ @Override
+ public <T> T getProxy(Invoker<T> invoker, boolean generic) throws
RpcException {
Class<?>[] interfaces = null;
String config = invoker.getUrl().getParameter("interfaces");
if (config != null && config.length() > 0) {
@@ -46,6 +52,15 @@
if (interfaces == null) {
interfaces = new Class<?>[]{invoker.getInterface(),
EchoService.class};
}
+
+ if (!invoker.getInterface().equals(GenericService.class) && generic) {
+ int len = interfaces.length;
+ Class<?>[] temp = interfaces;
+ interfaces = new Class<?>[len + 1];
+ System.arraycopy(temp, 0, interfaces, 0, len);
+ interfaces[len] = GenericService.class;
+ }
+
return getProxy(invoker, interfaces);
}
diff --git
a/dubbo-rpc/dubbo-rpc-api/src/main/java/com/alibaba/dubbo/rpc/proxy/wrapper/StubProxyFactoryWrapper.java
b/dubbo-rpc/dubbo-rpc-api/src/main/java/com/alibaba/dubbo/rpc/proxy/wrapper/StubProxyFactoryWrapper.java
index ec3db16ceb..3f3ed3ff49 100644
---
a/dubbo-rpc/dubbo-rpc-api/src/main/java/com/alibaba/dubbo/rpc/proxy/wrapper/StubProxyFactoryWrapper.java
+++
b/dubbo-rpc/dubbo-rpc-api/src/main/java/com/alibaba/dubbo/rpc/proxy/wrapper/StubProxyFactoryWrapper.java
@@ -54,6 +54,11 @@ public void setProtocol(Protocol protocol) {
this.protocol = protocol;
}
+ @Override
+ public <T> T getProxy(Invoker<T> invoker, boolean generic) throws
RpcException {
+ return proxyFactory.getProxy(invoker, generic);
+ }
+
@Override
@SuppressWarnings({"unchecked", "rawtypes"})
public <T> T getProxy(Invoker<T> invoker) throws RpcException {
diff --git a/dubbo-rpc/dubbo-rpc-hessian/pom.xml
b/dubbo-rpc/dubbo-rpc-hessian/pom.xml
index 00ca28cf2a..98ad82de8f 100644
--- a/dubbo-rpc/dubbo-rpc-hessian/pom.xml
+++ b/dubbo-rpc/dubbo-rpc-hessian/pom.xml
@@ -48,5 +48,11 @@
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
</dependency>
+ <dependency>
+ <groupId>com.alibaba</groupId>
+ <artifactId>dubbo-serialization-jdk</artifactId>
+ <version>${project.parent.version}</version>
+ <scope>test</scope>
+ </dependency>
</dependencies>
</project>
\ No newline at end of file
diff --git
a/dubbo-rpc/dubbo-rpc-hessian/src/main/java/com/alibaba/dubbo/rpc/protocol/hessian/DubboHessianURLConnectionFactory.java
b/dubbo-rpc/dubbo-rpc-hessian/src/main/java/com/alibaba/dubbo/rpc/protocol/hessian/DubboHessianURLConnectionFactory.java
new file mode 100644
index 0000000000..8fe2f14de4
--- /dev/null
+++
b/dubbo-rpc/dubbo-rpc-hessian/src/main/java/com/alibaba/dubbo/rpc/protocol/hessian/DubboHessianURLConnectionFactory.java
@@ -0,0 +1,40 @@
+/*
+ * 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 com.alibaba.dubbo.rpc.protocol.hessian;
+
+import com.alibaba.dubbo.common.Constants;
+import com.alibaba.dubbo.rpc.RpcContext;
+import com.caucho.hessian.client.HessianConnection;
+import com.caucho.hessian.client.HessianURLConnectionFactory;
+
+import java.io.IOException;
+import java.net.URL;
+
+public class DubboHessianURLConnectionFactory extends
HessianURLConnectionFactory {
+
+ @Override
+ public HessianConnection open(URL url) throws IOException {
+ HessianConnection connection = super.open(url);
+ RpcContext context = RpcContext.getContext();
+ for (String key : context.getAttachments().keySet()) {
+ connection.addHeader(Constants.DEFAULT_EXCHANGER + key,
context.getAttachment(key));
+ }
+
+ return connection;
+ }
+}
diff --git
a/dubbo-rpc/dubbo-rpc-hessian/src/main/java/com/alibaba/dubbo/rpc/protocol/hessian/HessianProtocol.java
b/dubbo-rpc/dubbo-rpc-hessian/src/main/java/com/alibaba/dubbo/rpc/protocol/hessian/HessianProtocol.java
index f1eae5cf63..9733307d62 100644
---
a/dubbo-rpc/dubbo-rpc-hessian/src/main/java/com/alibaba/dubbo/rpc/protocol/hessian/HessianProtocol.java
+++
b/dubbo-rpc/dubbo-rpc-hessian/src/main/java/com/alibaba/dubbo/rpc/protocol/hessian/HessianProtocol.java
@@ -25,8 +25,11 @@
import com.alibaba.dubbo.rpc.RpcException;
import com.alibaba.dubbo.rpc.protocol.AbstractProxyProtocol;
+import com.alibaba.dubbo.rpc.service.GenericService;
+import com.alibaba.dubbo.rpc.support.ProtocolUtils;
import com.caucho.hessian.HessianException;
import com.caucho.hessian.client.HessianConnectionException;
+import com.caucho.hessian.client.HessianConnectionFactory;
import com.caucho.hessian.client.HessianProxyFactory;
import com.caucho.hessian.io.HessianMethodSerializationException;
import com.caucho.hessian.server.HessianSkeleton;
@@ -37,6 +40,7 @@
import java.io.IOException;
import java.net.SocketTimeoutException;
import java.util.ArrayList;
+import java.util.Enumeration;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
@@ -73,12 +77,17 @@ public int getDefaultPort() {
serverMap.put(addr, server);
}
final String path = url.getAbsolutePath();
- HessianSkeleton skeleton = new HessianSkeleton(impl, type);
+ final HessianSkeleton skeleton = new HessianSkeleton(impl, type);
skeletonMap.put(path, skeleton);
+
+ final String genericPath = path + "/" + Constants.GENERIC_KEY;
+ skeletonMap.put(genericPath, new HessianSkeleton(impl,
GenericService.class));
+
return new Runnable() {
@Override
public void run() {
skeletonMap.remove(path);
+ skeletonMap.remove(genericPath);
}
};
}
@@ -86,6 +95,13 @@ public void run() {
@Override
@SuppressWarnings("unchecked")
protected <T> T doRefer(Class<T> serviceType, URL url) throws RpcException
{
+ String generic = url.getParameter(Constants.GENERIC_KEY);
+ boolean isGeneric = ProtocolUtils.isGeneric(generic) ||
serviceType.equals(GenericService.class);
+ if (isGeneric) {
+ RpcContext.getContext().setAttachment(Constants.GENERIC_KEY,
generic);
+ url = url.setPath(url.getPath() + "/" + Constants.GENERIC_KEY);
+ }
+
HessianProxyFactory hessianProxyFactory = new HessianProxyFactory();
boolean isHessian2Request =
url.getParameter(Constants.HESSIAN2_REQUEST_KEY,
Constants.DEFAULT_HESSIAN2_REQUEST);
hessianProxyFactory.setHessian2Request(isHessian2Request);
@@ -96,6 +112,10 @@ public void run() {
hessianProxyFactory.setConnectionFactory(new
HttpClientConnectionFactory());
} else if (client != null && client.length() > 0 &&
!Constants.DEFAULT_HTTP_CLIENT.equals(client)) {
throw new IllegalStateException("Unsupported http protocol
client=\"" + client + "\"!");
+ } else {
+ HessianConnectionFactory factory = new
DubboHessianURLConnectionFactory();
+ factory.setHessianProxyFactory(hessianProxyFactory);
+ hessianProxyFactory.setConnectionFactory(factory);
}
int timeout = url.getParameter(Constants.TIMEOUT_KEY,
Constants.DEFAULT_TIMEOUT);
hessianProxyFactory.setConnectTimeout(timeout);
@@ -148,6 +168,16 @@ public void handle(HttpServletRequest request,
HttpServletResponse response)
response.setStatus(500);
} else {
RpcContext.getContext().setRemoteAddress(request.getRemoteAddr(),
request.getRemotePort());
+
+ Enumeration<String> enumeration = request.getHeaderNames();
+ while (enumeration.hasMoreElements()) {
+ String key = enumeration.nextElement();
+ if (key.startsWith(Constants.DEFAULT_EXCHANGER)) {
+
RpcContext.getContext().setAttachment(key.substring(Constants.DEFAULT_EXCHANGER.length()),
+ request.getHeader(key));
+ }
+ }
+
try {
skeleton.invoke(request.getInputStream(),
response.getOutputStream());
} catch (Throwable e) {
diff --git
a/dubbo-rpc/dubbo-rpc-hessian/src/main/java/com/alibaba/dubbo/rpc/protocol/hessian/HttpClientConnectionFactory.java
b/dubbo-rpc/dubbo-rpc-hessian/src/main/java/com/alibaba/dubbo/rpc/protocol/hessian/HttpClientConnectionFactory.java
index 033277d02e..b19cd275c8 100644
---
a/dubbo-rpc/dubbo-rpc-hessian/src/main/java/com/alibaba/dubbo/rpc/protocol/hessian/HttpClientConnectionFactory.java
+++
b/dubbo-rpc/dubbo-rpc-hessian/src/main/java/com/alibaba/dubbo/rpc/protocol/hessian/HttpClientConnectionFactory.java
@@ -16,6 +16,8 @@
*/
package com.alibaba.dubbo.rpc.protocol.hessian;
+import com.alibaba.dubbo.common.Constants;
+import com.alibaba.dubbo.rpc.RpcContext;
import com.caucho.hessian.client.HessianConnection;
import com.caucho.hessian.client.HessianConnectionFactory;
import com.caucho.hessian.client.HessianProxyFactory;
@@ -41,7 +43,12 @@ public void setHessianProxyFactory(HessianProxyFactory
factory) {
@Override
public HessianConnection open(URL url) throws IOException {
- return new HttpClientConnection(httpClient, url);
+ HttpClientConnection httpClientConnection = new
HttpClientConnection(httpClient, url);
+ RpcContext context = RpcContext.getContext();
+ for (String key : context.getAttachments().keySet()) {
+ httpClientConnection.addHeader(Constants.DEFAULT_EXCHANGER + key,
context.getAttachment(key));
+ }
+ return httpClientConnection;
}
}
diff --git
a/dubbo-rpc/dubbo-rpc-hessian/src/test/java/com/alibaba/dubbo/rpc/protocol/hessian/HessianProtocolTest.java
b/dubbo-rpc/dubbo-rpc-hessian/src/test/java/com/alibaba/dubbo/rpc/protocol/hessian/HessianProtocolTest.java
index 877ecd3884..bae03335c5 100644
---
a/dubbo-rpc/dubbo-rpc-hessian/src/test/java/com/alibaba/dubbo/rpc/protocol/hessian/HessianProtocolTest.java
+++
b/dubbo-rpc/dubbo-rpc-hessian/src/test/java/com/alibaba/dubbo/rpc/protocol/hessian/HessianProtocolTest.java
@@ -17,17 +17,29 @@
package com.alibaba.dubbo.rpc.protocol.hessian;
import com.alibaba.dubbo.common.URL;
+import com.alibaba.dubbo.common.beanutil.JavaBeanDescriptor;
+import com.alibaba.dubbo.common.beanutil.JavaBeanSerializeUtil;
import com.alibaba.dubbo.common.extension.ExtensionLoader;
+import com.alibaba.dubbo.common.serialize.ObjectInput;
+import com.alibaba.dubbo.common.serialize.ObjectOutput;
+import com.alibaba.dubbo.common.serialize.Serialization;
+import com.alibaba.dubbo.common.serialize.nativejava.NativeJavaSerialization;
import com.alibaba.dubbo.rpc.Exporter;
import com.alibaba.dubbo.rpc.Invoker;
import com.alibaba.dubbo.rpc.Protocol;
import com.alibaba.dubbo.rpc.ProxyFactory;
+import com.alibaba.dubbo.rpc.RpcContext;
import com.alibaba.dubbo.rpc.RpcException;
import com.alibaba.dubbo.rpc.protocol.hessian.HessianServiceImpl.MyException;
+import com.alibaba.dubbo.rpc.service.GenericService;
import org.junit.Assert;
import org.junit.Test;
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+
import static org.junit.Assert.fail;
/**
@@ -52,6 +64,87 @@ public void testHessianProtocol() {
exporter.unexport();
}
+ @Test
+ public void testGenericInvoke() {
+ HessianServiceImpl server = new HessianServiceImpl();
+ Assert.assertFalse(server.isCalled());
+ ProxyFactory proxyFactory =
ExtensionLoader.getExtensionLoader(ProxyFactory.class).getAdaptiveExtension();
+ Protocol protocol =
ExtensionLoader.getExtensionLoader(Protocol.class).getAdaptiveExtension();
+ URL url = URL.valueOf("hessian://127.0.0.1:5342/" +
HessianService.class.getName() + "?version=1.0.0");
+ Exporter<HessianService> exporter =
protocol.export(proxyFactory.getInvoker(server, HessianService.class, url));
+ Invoker<GenericService> invoker = protocol.refer(GenericService.class,
url);
+ GenericService client = proxyFactory.getProxy(invoker, true);
+ String result = (String) client.$invoke("sayHello", new
String[]{"java.lang.String"}, new Object[]{"haha"});
+ Assert.assertTrue(server.isCalled());
+ Assert.assertEquals("Hello, haha", result);
+ invoker.destroy();
+ exporter.unexport();
+ }
+
+ @Test
+ public void testGenericInvokeWithNativeJava() throws IOException,
ClassNotFoundException {
+ HessianServiceImpl server = new HessianServiceImpl();
+ Assert.assertFalse(server.isCalled());
+ ProxyFactory proxyFactory =
ExtensionLoader.getExtensionLoader(ProxyFactory.class).getAdaptiveExtension();
+ Protocol protocol =
ExtensionLoader.getExtensionLoader(Protocol.class).getAdaptiveExtension();
+ URL url = URL.valueOf("hessian://127.0.0.1:5342/" +
HessianService.class.getName() + "?version=1.0.0&generic=nativejava");
+ Exporter<HessianService> exporter =
protocol.export(proxyFactory.getInvoker(server, HessianService.class, url));
+ Invoker<GenericService> invoker = protocol.refer(GenericService.class,
url);
+ GenericService client = proxyFactory.getProxy(invoker);
+
+ Serialization serialization = new NativeJavaSerialization();
+ ByteArrayOutputStream byteArrayOutputStream = new
ByteArrayOutputStream();
+
+ ObjectOutput objectOutput = serialization.serialize(url,
byteArrayOutputStream);
+ objectOutput.writeObject("haha");
+ objectOutput.flushBuffer();
+
+ Object result = client.$invoke("sayHello", new
String[]{"java.lang.String"}, new
Object[]{byteArrayOutputStream.toByteArray()});
+ ByteArrayInputStream byteArrayInputStream = new
ByteArrayInputStream((byte[]) result);
+ ObjectInput objectInput = serialization.deserialize(url,
byteArrayInputStream);
+ Assert.assertTrue(server.isCalled());
+ Assert.assertEquals("Hello, haha", objectInput.readObject());
+ invoker.destroy();
+ exporter.unexport();
+ }
+
+ @Test
+ public void testGenericInvokeWithRpcContext() {
+ RpcContext.getContext().setAttachment("myContext", "123");
+
+ HessianServiceImpl server = new HessianServiceImpl();
+ ProxyFactory proxyFactory =
ExtensionLoader.getExtensionLoader(ProxyFactory.class).getAdaptiveExtension();
+ Protocol protocol =
ExtensionLoader.getExtensionLoader(Protocol.class).getAdaptiveExtension();
+ URL url = URL.valueOf("hessian://127.0.0.1:5342/" +
HessianService.class.getName() + "?version=1.0.0");
+ Exporter<HessianService> exporter =
protocol.export(proxyFactory.getInvoker(server, HessianService.class, url));
+ Invoker<GenericService> invoker = protocol.refer(GenericService.class,
url);
+ GenericService client = proxyFactory.getProxy(invoker, true);
+ String result = (String) client.$invoke("context", new
String[]{"java.lang.String"}, new Object[]{"haha"});
+ Assert.assertEquals("Hello, haha context, 123", result);
+ invoker.destroy();
+ exporter.unexport();
+ }
+
+ @Test
+ public void testGenericInvokeWithBean() {
+ HessianServiceImpl server = new HessianServiceImpl();
+ Assert.assertFalse(server.isCalled());
+ ProxyFactory proxyFactory =
ExtensionLoader.getExtensionLoader(ProxyFactory.class).getAdaptiveExtension();
+ Protocol protocol =
ExtensionLoader.getExtensionLoader(Protocol.class).getAdaptiveExtension();
+ URL url = URL.valueOf("hessian://127.0.0.1:5342/" +
HessianService.class.getName() + "?version=1.0.0&generic=bean");
+ Exporter<HessianService> exporter =
protocol.export(proxyFactory.getInvoker(server, HessianService.class, url));
+ Invoker<GenericService> invoker = protocol.refer(GenericService.class,
url);
+ GenericService client = proxyFactory.getProxy(invoker);
+
+ JavaBeanDescriptor javaBeanDescriptor =
JavaBeanSerializeUtil.serialize("haha");
+
+ Object result = client.$invoke("sayHello", new
String[]{"java.lang.String"}, new Object[]{javaBeanDescriptor});
+ Assert.assertTrue(server.isCalled());
+ Assert.assertEquals("Hello, haha",
JavaBeanSerializeUtil.deserialize((JavaBeanDescriptor) result));
+ invoker.destroy();
+ exporter.unexport();
+ }
+
@Test
public void testOverload() {
HessianServiceImpl server = new HessianServiceImpl();
diff --git
a/dubbo-rpc/dubbo-rpc-hessian/src/test/java/com/alibaba/dubbo/rpc/protocol/hessian/HessianService.java
b/dubbo-rpc/dubbo-rpc-hessian/src/test/java/com/alibaba/dubbo/rpc/protocol/hessian/HessianService.java
index 8629425145..9df4524f1d 100644
---
a/dubbo-rpc/dubbo-rpc-hessian/src/test/java/com/alibaba/dubbo/rpc/protocol/hessian/HessianService.java
+++
b/dubbo-rpc/dubbo-rpc-hessian/src/test/java/com/alibaba/dubbo/rpc/protocol/hessian/HessianService.java
@@ -30,4 +30,6 @@
String customException();
+ String context(String name);
+
}
diff --git
a/dubbo-rpc/dubbo-rpc-hessian/src/test/java/com/alibaba/dubbo/rpc/protocol/hessian/HessianServiceImpl.java
b/dubbo-rpc/dubbo-rpc-hessian/src/test/java/com/alibaba/dubbo/rpc/protocol/hessian/HessianServiceImpl.java
index 855de0a28a..68d14b3f2b 100644
---
a/dubbo-rpc/dubbo-rpc-hessian/src/test/java/com/alibaba/dubbo/rpc/protocol/hessian/HessianServiceImpl.java
+++
b/dubbo-rpc/dubbo-rpc-hessian/src/test/java/com/alibaba/dubbo/rpc/protocol/hessian/HessianServiceImpl.java
@@ -16,6 +16,8 @@
*/
package com.alibaba.dubbo.rpc.protocol.hessian;
+import com.alibaba.dubbo.rpc.RpcContext;
+
/**
* HessianServiceImpl
*/
@@ -53,6 +55,10 @@ public String customException() {
throw new MyException("custom exception");
}
+ public String context(String name) {
+ return "Hello, " + name + " context, " +
RpcContext.getContext().getAttachment("myContext");
+ }
+
static class MyException extends RuntimeException {
private static final long serialVersionUID = -3051041116483629056L;
diff --git a/dubbo-rpc/dubbo-rpc-http/pom.xml b/dubbo-rpc/dubbo-rpc-http/pom.xml
index 427b70ba6a..93d8a0f028 100644
--- a/dubbo-rpc/dubbo-rpc-http/pom.xml
+++ b/dubbo-rpc/dubbo-rpc-http/pom.xml
@@ -48,5 +48,11 @@
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
</dependency>
+ <dependency>
+ <groupId>com.alibaba</groupId>
+ <artifactId>dubbo-serialization-jdk</artifactId>
+ <version>${project.parent.version}</version>
+ <scope>test</scope>
+ </dependency>
</dependencies>
</project>
\ No newline at end of file
diff --git
a/dubbo-rpc/dubbo-rpc-http/src/main/java/com/alibaba/dubbo/rpc/protocol/http/HttpProtocol.java
b/dubbo-rpc/dubbo-rpc-http/src/main/java/com/alibaba/dubbo/rpc/protocol/http/HttpProtocol.java
index 27a59134e8..3fc908749a 100644
---
a/dubbo-rpc/dubbo-rpc-http/src/main/java/com/alibaba/dubbo/rpc/protocol/http/HttpProtocol.java
+++
b/dubbo-rpc/dubbo-rpc-http/src/main/java/com/alibaba/dubbo/rpc/protocol/http/HttpProtocol.java
@@ -24,12 +24,16 @@
import com.alibaba.dubbo.rpc.RpcContext;
import com.alibaba.dubbo.rpc.RpcException;
import com.alibaba.dubbo.rpc.protocol.AbstractProxyProtocol;
-
+import com.alibaba.dubbo.rpc.service.GenericService;
+import com.alibaba.dubbo.rpc.support.ProtocolUtils;
+import org.aopalliance.intercept.MethodInvocation;
import org.springframework.remoting.RemoteAccessException;
import
org.springframework.remoting.httpinvoker.HttpComponentsHttpInvokerRequestExecutor;
import org.springframework.remoting.httpinvoker.HttpInvokerProxyFactoryBean;
import org.springframework.remoting.httpinvoker.HttpInvokerServiceExporter;
import
org.springframework.remoting.httpinvoker.SimpleHttpInvokerRequestExecutor;
+import org.springframework.remoting.support.RemoteInvocation;
+import org.springframework.remoting.support.RemoteInvocationFactory;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
@@ -74,6 +78,22 @@ public int getDefaultPort() {
server = httpBinder.bind(url, new InternalHandler());
serverMap.put(addr, server);
}
+ final String path = url.getAbsolutePath();
+ skeletonMap.put(path, createExporter(impl, type));
+
+ final String genericPath = path + "/" + Constants.GENERIC_KEY;
+
+ skeletonMap.put(genericPath, createExporter(impl,
GenericService.class));
+ return new Runnable() {
+ @Override
+ public void run() {
+ skeletonMap.remove(path);
+ skeletonMap.remove(genericPath);
+ }
+ };
+ }
+
+ private <T> HttpInvokerServiceExporter createExporter(T impl, Class<?>
type) {
final HttpInvokerServiceExporter httpServiceExporter = new
HttpInvokerServiceExporter();
httpServiceExporter.setServiceInterface(type);
httpServiceExporter.setService(impl);
@@ -82,21 +102,33 @@ public int getDefaultPort() {
} catch (Exception e) {
throw new RpcException(e.getMessage(), e);
}
- final String path = url.getAbsolutePath();
- skeletonMap.put(path, httpServiceExporter);
- return new Runnable() {
- @Override
- public void run() {
- skeletonMap.remove(path);
- }
- };
+ return httpServiceExporter;
}
@Override
@SuppressWarnings("unchecked")
protected <T> T doRefer(final Class<T> serviceType, final URL url) throws
RpcException {
+ final String generic = url.getParameter(Constants.GENERIC_KEY);
+ final boolean isGeneric = ProtocolUtils.isGeneric(generic) ||
serviceType.equals(GenericService.class);
+
final HttpInvokerProxyFactoryBean httpProxyFactoryBean = new
HttpInvokerProxyFactoryBean();
- httpProxyFactoryBean.setServiceUrl(url.toIdentityString());
+ httpProxyFactoryBean.setRemoteInvocationFactory(new
RemoteInvocationFactory() {
+ @Override
+ public RemoteInvocation createRemoteInvocation(MethodInvocation
methodInvocation) {
+ RemoteInvocation invocation = new
HttpRemoteInvocation(methodInvocation);
+ if (isGeneric) {
+ invocation.addAttribute(Constants.GENERIC_KEY, generic);
+ }
+ return invocation;
+ }
+ });
+
+ String key = url.toIdentityString();
+ if (isGeneric) {
+ key = key + "/" + Constants.GENERIC_KEY;
+ }
+
+ httpProxyFactoryBean.setServiceUrl(key);
httpProxyFactoryBean.setServiceInterface(serviceType);
String client = url.getParameter(Constants.CLIENT_KEY);
if (client == null || client.length() == 0 || "simple".equals(client))
{
@@ -112,7 +144,8 @@ protected void prepareConnection(HttpURLConnection con,
httpProxyFactoryBean.setHttpInvokerRequestExecutor(httpInvokerRequestExecutor);
} else if ("commons".equals(client)) {
HttpComponentsHttpInvokerRequestExecutor
httpInvokerRequestExecutor = new HttpComponentsHttpInvokerRequestExecutor();
-
httpInvokerRequestExecutor.setReadTimeout(url.getParameter(Constants.CONNECT_TIMEOUT_KEY,
Constants.DEFAULT_CONNECT_TIMEOUT));
+
httpInvokerRequestExecutor.setReadTimeout(url.getParameter(Constants.TIMEOUT_KEY,
Constants.DEFAULT_TIMEOUT));
+
httpInvokerRequestExecutor.setConnectTimeout(url.getParameter(Constants.CONNECT_TIMEOUT_KEY,
Constants.DEFAULT_CONNECT_TIMEOUT));
httpProxyFactoryBean.setHttpInvokerRequestExecutor(httpInvokerRequestExecutor);
} else {
throw new IllegalStateException("Unsupported http protocol client
" + client + ", only supported: simple, commons");
diff --git
a/dubbo-rpc/dubbo-rpc-http/src/main/java/com/alibaba/dubbo/rpc/protocol/http/HttpRemoteInvocation.java
b/dubbo-rpc/dubbo-rpc-http/src/main/java/com/alibaba/dubbo/rpc/protocol/http/HttpRemoteInvocation.java
new file mode 100644
index 0000000000..5054c4fded
--- /dev/null
+++
b/dubbo-rpc/dubbo-rpc-http/src/main/java/com/alibaba/dubbo/rpc/protocol/http/HttpRemoteInvocation.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 com.alibaba.dubbo.rpc.protocol.http;
+
+import com.alibaba.dubbo.common.Constants;
+import com.alibaba.dubbo.common.utils.StringUtils;
+import com.alibaba.dubbo.rpc.RpcContext;
+import org.aopalliance.intercept.MethodInvocation;
+import org.springframework.remoting.support.RemoteInvocation;
+
+import java.lang.reflect.InvocationTargetException;
+import java.util.HashMap;
+import java.util.Map;
+
+public class HttpRemoteInvocation extends RemoteInvocation {
+
+ private static final long serialVersionUID = 1L;
+ private static final String dubboAttachmentsAttrName = "dubbo.attachments";
+
+ public HttpRemoteInvocation(MethodInvocation methodInvocation) {
+ super(methodInvocation);
+ addAttribute(dubboAttachmentsAttrName, new HashMap<String,
String>(RpcContext.getContext().getAttachments()));
+ }
+
+ @Override
+ public Object invoke(Object targetObject) throws NoSuchMethodException,
IllegalAccessException,
+ InvocationTargetException {
+ RpcContext context = RpcContext.getContext();
+ context.setAttachments((Map<String, String>)
getAttribute(dubboAttachmentsAttrName));
+
+ String generic = (String) getAttribute(Constants.GENERIC_KEY);
+ if (StringUtils.isNotEmpty(generic)) {
+ context.setAttachment(Constants.GENERIC_KEY, generic);
+ }
+ try {
+ return super.invoke(targetObject);
+ } finally {
+ context.setAttachments(null);
+
+ }
+ }
+}
diff --git
a/dubbo-rpc/dubbo-rpc-http/src/test/java/com/alibaba/dubbo/rpc/protocol/http/HttpProtocolTest.java
b/dubbo-rpc/dubbo-rpc-http/src/test/java/com/alibaba/dubbo/rpc/protocol/http/HttpProtocolTest.java
new file mode 100644
index 0000000000..014eed6558
--- /dev/null
+++
b/dubbo-rpc/dubbo-rpc-http/src/test/java/com/alibaba/dubbo/rpc/protocol/http/HttpProtocolTest.java
@@ -0,0 +1,198 @@
+/*
+ * 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 com.alibaba.dubbo.rpc.protocol.http;
+
+import com.alibaba.dubbo.common.URL;
+import com.alibaba.dubbo.common.beanutil.JavaBeanDescriptor;
+import com.alibaba.dubbo.common.beanutil.JavaBeanSerializeUtil;
+import com.alibaba.dubbo.common.extension.ExtensionLoader;
+import com.alibaba.dubbo.common.serialize.ObjectInput;
+import com.alibaba.dubbo.common.serialize.ObjectOutput;
+import com.alibaba.dubbo.common.serialize.Serialization;
+import com.alibaba.dubbo.common.serialize.nativejava.NativeJavaSerialization;
+import com.alibaba.dubbo.rpc.*;
+import com.alibaba.dubbo.rpc.service.GenericService;
+import junit.framework.Assert;
+import org.junit.Test;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+
+import static org.junit.Assert.fail;
+
+/**
+ * HttpProtocolTest
+ */
+public class HttpProtocolTest {
+
+ @Test
+ public void testHttpProtocol() {
+ HttpServiceImpl server = new HttpServiceImpl();
+ Assert.assertFalse(server.isCalled());
+ ProxyFactory proxyFactory =
ExtensionLoader.getExtensionLoader(ProxyFactory.class).getAdaptiveExtension();
+ Protocol protocol =
ExtensionLoader.getExtensionLoader(Protocol.class).getAdaptiveExtension();
+ URL url = URL.valueOf("http://127.0.0.1:5342/" +
HttpService.class.getName() + "?version=1.0.0");
+ Exporter<HttpService> exporter =
protocol.export(proxyFactory.getInvoker(server, HttpService.class, url));
+ Invoker<HttpService> invoker = protocol.refer(HttpService.class, url);
+ HttpService client = proxyFactory.getProxy(invoker);
+ String result = client.sayHello("haha");
+ Assert.assertTrue(server.isCalled());
+ Assert.assertEquals("Hello, haha", result);
+ invoker.destroy();
+ exporter.unexport();
+ }
+
+ @Test
+ public void testGenericInvoke() {
+ HttpServiceImpl server = new HttpServiceImpl();
+ Assert.assertFalse(server.isCalled());
+ ProxyFactory proxyFactory =
ExtensionLoader.getExtensionLoader(ProxyFactory.class).getAdaptiveExtension();
+ Protocol protocol =
ExtensionLoader.getExtensionLoader(Protocol.class).getAdaptiveExtension();
+ URL url = URL.valueOf("http://127.0.0.1:5342/" +
HttpService.class.getName() + "?version=1.0.0");
+ Exporter<HttpService> exporter =
protocol.export(proxyFactory.getInvoker(server, HttpService.class, url));
+ Invoker<GenericService> invoker = protocol.refer(GenericService.class,
url);
+ GenericService client = proxyFactory.getProxy(invoker, true);
+ String result = (String) client.$invoke("sayHello", new
String[]{"java.lang.String"}, new Object[]{"haha"});
+ Assert.assertTrue(server.isCalled());
+ Assert.assertEquals("Hello, haha", result);
+ invoker.destroy();
+ exporter.unexport();
+ }
+
+ @Test
+ public void testGenericInvokeWithNativeJava() throws IOException,
ClassNotFoundException {
+ HttpServiceImpl server = new HttpServiceImpl();
+ Assert.assertFalse(server.isCalled());
+ ProxyFactory proxyFactory =
ExtensionLoader.getExtensionLoader(ProxyFactory.class).getAdaptiveExtension();
+ Protocol protocol =
ExtensionLoader.getExtensionLoader(Protocol.class).getAdaptiveExtension();
+ URL url = URL.valueOf("http://127.0.0.1:5342/" +
HttpService.class.getName() + "?version=1.0.0&generic=nativejava");
+ Exporter<HttpService> exporter =
protocol.export(proxyFactory.getInvoker(server, HttpService.class, url));
+ Invoker<GenericService> invoker = protocol.refer(GenericService.class,
url);
+ GenericService client = proxyFactory.getProxy(invoker);
+
+ Serialization serialization = new NativeJavaSerialization();
+ ByteArrayOutputStream byteArrayOutputStream = new
ByteArrayOutputStream();
+
+ ObjectOutput objectOutput = serialization.serialize(url,
byteArrayOutputStream);
+ objectOutput.writeObject("haha");
+ objectOutput.flushBuffer();
+
+ Object result = client.$invoke("sayHello", new
String[]{"java.lang.String"}, new
Object[]{byteArrayOutputStream.toByteArray()});
+ ByteArrayInputStream byteArrayInputStream = new
ByteArrayInputStream((byte[]) result);
+ ObjectInput objectInput = serialization.deserialize(url,
byteArrayInputStream);
+ Assert.assertTrue(server.isCalled());
+ Assert.assertEquals("Hello, haha", objectInput.readObject());
+ invoker.destroy();
+ exporter.unexport();
+ }
+
+ @Test
+ public void testGenericInvokeWithBean() {
+ HttpServiceImpl server = new HttpServiceImpl();
+ Assert.assertFalse(server.isCalled());
+ ProxyFactory proxyFactory =
ExtensionLoader.getExtensionLoader(ProxyFactory.class).getAdaptiveExtension();
+ Protocol protocol =
ExtensionLoader.getExtensionLoader(Protocol.class).getAdaptiveExtension();
+ URL url = URL.valueOf("http://127.0.0.1:5342/" +
HttpService.class.getName() + "?version=1.0.0&generic=bean");
+ Exporter<HttpService> exporter =
protocol.export(proxyFactory.getInvoker(server, HttpService.class, url));
+ Invoker<GenericService> invoker = protocol.refer(GenericService.class,
url);
+ GenericService client = proxyFactory.getProxy(invoker);
+
+ JavaBeanDescriptor javaBeanDescriptor =
JavaBeanSerializeUtil.serialize("haha");
+
+ Object result = client.$invoke("sayHello", new
String[]{"java.lang.String"}, new Object[]{javaBeanDescriptor});
+ Assert.assertTrue(server.isCalled());
+ Assert.assertEquals("Hello, haha",
JavaBeanSerializeUtil.deserialize((JavaBeanDescriptor) result));
+ invoker.destroy();
+ exporter.unexport();
+ }
+
+ @Test
+ public void testOverload() {
+ HttpServiceImpl server = new HttpServiceImpl();
+ Assert.assertFalse(server.isCalled());
+ ProxyFactory proxyFactory =
ExtensionLoader.getExtensionLoader(ProxyFactory.class).getAdaptiveExtension();
+ Protocol protocol =
ExtensionLoader.getExtensionLoader(Protocol.class).getAdaptiveExtension();
+ URL url = URL.valueOf("http://127.0.0.1:5342/" +
HttpService.class.getName() +
"?version=1.0.0&hessian.overload.method=true&hessian2.request=false");
+ Exporter<HttpService> exporter =
protocol.export(proxyFactory.getInvoker(server, HttpService.class, url));
+ Invoker<HttpService> invoker = protocol.refer(HttpService.class, url);
+ HttpService client = proxyFactory.getProxy(invoker);
+ String result = client.sayHello("haha");
+ Assert.assertEquals("Hello, haha", result);
+ result = client.sayHello("haha", 1);
+ Assert.assertEquals("Hello, haha. ", result);
+ invoker.destroy();
+ exporter.unexport();
+ }
+
+ @Test
+ public void testSimpleClient() {
+ HttpServiceImpl server = new HttpServiceImpl();
+ Assert.assertFalse(server.isCalled());
+ ProxyFactory proxyFactory =
ExtensionLoader.getExtensionLoader(ProxyFactory.class).getAdaptiveExtension();
+ Protocol protocol =
ExtensionLoader.getExtensionLoader(Protocol.class).getAdaptiveExtension();
+ URL url = URL.valueOf("http://127.0.0.1:5342/" +
HttpService.class.getName() + "?version=1.0.0&client=simple");
+ Exporter<HttpService> exporter =
protocol.export(proxyFactory.getInvoker(server, HttpService.class, url));
+ Invoker<HttpService> invoker = protocol.refer(HttpService.class, url);
+ HttpService client = proxyFactory.getProxy(invoker);
+ String result = client.sayHello("haha");
+ Assert.assertTrue(server.isCalled());
+ Assert.assertEquals("Hello, haha", result);
+ invoker.destroy();
+ exporter.unexport();
+ }
+
+ @Test
+ public void testTimeOut() {
+ HttpServiceImpl server = new HttpServiceImpl();
+ ProxyFactory proxyFactory =
ExtensionLoader.getExtensionLoader(ProxyFactory.class).getAdaptiveExtension();
+ Protocol protocol =
ExtensionLoader.getExtensionLoader(Protocol.class).getAdaptiveExtension();
+ URL url = URL.valueOf("http://127.0.0.1:5342/" +
HttpService.class.getName() + "?version=1.0.0&timeout=10");
+ Exporter<HttpService> exporter =
protocol.export(proxyFactory.getInvoker(server, HttpService.class, url));
+ Invoker<HttpService> invoker = protocol.refer(HttpService.class, url);
+ HttpService client = proxyFactory.getProxy(invoker);
+ try {
+ client.timeOut(6000);
+ fail();
+ } catch (RpcException expected) {
+ Assert.assertEquals(true, expected.isTimeout());
+ } finally {
+ invoker.destroy();
+ exporter.unexport();
+ }
+
+ }
+
+ @Test
+ public void testCustomException() {
+ HttpServiceImpl server = new HttpServiceImpl();
+ ProxyFactory proxyFactory =
ExtensionLoader.getExtensionLoader(ProxyFactory.class).getAdaptiveExtension();
+ Protocol protocol =
ExtensionLoader.getExtensionLoader(Protocol.class).getAdaptiveExtension();
+ URL url = URL.valueOf("http://127.0.0.1:5342/" +
HttpService.class.getName() + "?version=1.0.0");
+ Exporter<HttpService> exporter =
protocol.export(proxyFactory.getInvoker(server, HttpService.class, url));
+ Invoker<HttpService> invoker = protocol.refer(HttpService.class, url);
+ HttpService client = proxyFactory.getProxy(invoker);
+ try {
+ client.customException();
+ fail();
+ } catch (HttpServiceImpl.MyException expected) {
+ }
+ invoker.destroy();
+ exporter.unexport();
+ }
+
+}
diff --git
a/dubbo-rpc/dubbo-rpc-http/src/test/java/com/alibaba/dubbo/rpc/protocol/http/HttpService.java
b/dubbo-rpc/dubbo-rpc-http/src/test/java/com/alibaba/dubbo/rpc/protocol/http/HttpService.java
new file mode 100644
index 0000000000..0d0d22c1e7
--- /dev/null
+++
b/dubbo-rpc/dubbo-rpc-http/src/test/java/com/alibaba/dubbo/rpc/protocol/http/HttpService.java
@@ -0,0 +1,33 @@
+/*
+ * 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 com.alibaba.dubbo.rpc.protocol.http;
+
+
+/**
+ * HttpService
+ */
+public interface HttpService {
+
+ String sayHello(String name);
+
+ String sayHello(String name, int times);
+
+ void timeOut(int millis);
+
+ String customException();
+
+}
diff --git
a/dubbo-rpc/dubbo-rpc-http/src/test/java/com/alibaba/dubbo/rpc/protocol/http/HttpServiceImpl.java
b/dubbo-rpc/dubbo-rpc-http/src/test/java/com/alibaba/dubbo/rpc/protocol/http/HttpServiceImpl.java
new file mode 100644
index 0000000000..1c78b3ba69
--- /dev/null
+++
b/dubbo-rpc/dubbo-rpc-http/src/test/java/com/alibaba/dubbo/rpc/protocol/http/HttpServiceImpl.java
@@ -0,0 +1,64 @@
+/*
+ * 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 com.alibaba.dubbo.rpc.protocol.http;
+
+/**
+ * HttpServiceImpl
+ */
+public class HttpServiceImpl implements HttpService {
+
+ private boolean called;
+
+ public String sayHello(String name) {
+ called = true;
+ return "Hello, " + name;
+ }
+
+ public String sayHello(String name, int times) {
+ called = true;
+ StringBuilder sb = new StringBuilder();
+ for (int i = 0; i < times; i++) {
+ sb.append("Hello, " + name + ". ");
+ }
+ return sb.toString();
+ }
+
+ public boolean isCalled() {
+ return called;
+ }
+
+ public void timeOut(int millis) {
+ try {
+ Thread.sleep(millis);
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ }
+ }
+
+ public String customException() {
+ throw new MyException("custom exception");
+ }
+
+ static class MyException extends RuntimeException {
+
+ private static final long serialVersionUID = -3051041116483629056L;
+
+ public MyException(String message) {
+ super(message);
+ }
+ }
+}
diff --git a/dubbo-rpc/dubbo-rpc-rest/pom.xml b/dubbo-rpc/dubbo-rpc-rest/pom.xml
index 026e2c293a..724ae6dac9 100644
--- a/dubbo-rpc/dubbo-rpc-rest/pom.xml
+++ b/dubbo-rpc/dubbo-rpc-rest/pom.xml
@@ -105,5 +105,11 @@
<artifactId>netty-all</artifactId>
</dependency>
+ <dependency>
+ <groupId>com.alibaba</groupId>
+ <artifactId>dubbo-serialization-jdk</artifactId>
+ <version>${project.parent.version}</version>
+ <scope>test</scope>
+ </dependency>
</dependencies>
</project>
\ No newline at end of file
diff --git
a/dubbo-rpc/dubbo-rpc-rest/src/test/java/com/alibaba/dubbo/rpc/protol/rest/RestProtocolTest.java
b/dubbo-rpc/dubbo-rpc-rest/src/test/java/com/alibaba/dubbo/rpc/protol/rest/RestProtocolTest.java
new file mode 100644
index 0000000000..4764cf6b66
--- /dev/null
+++
b/dubbo-rpc/dubbo-rpc-rest/src/test/java/com/alibaba/dubbo/rpc/protol/rest/RestProtocolTest.java
@@ -0,0 +1,48 @@
+/*
+ * 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 com.alibaba.dubbo.rpc.protol.rest;
+
+import com.alibaba.dubbo.common.URL;
+import com.alibaba.dubbo.common.extension.ExtensionLoader;
+import com.alibaba.dubbo.rpc.*;
+import junit.framework.Assert;
+import org.junit.Test;
+
+/**
+ * RestProtocolTest
+ */
+public class RestProtocolTest {
+
+ private Protocol protocol =
ExtensionLoader.getExtensionLoader(Protocol.class).getAdaptiveExtension();
+ private ProxyFactory proxyFactory =
ExtensionLoader.getExtensionLoader(ProxyFactory.class).getAdaptiveExtension();
+
+ @Test
+ public void testRestProtocol() {
+
ServiceClassHolder.getInstance().pushServiceClass(RestServiceImpl.class);
+ RestServiceImpl server = new RestServiceImpl();
+ Assert.assertFalse(server.isCalled());
+ URL url = URL.valueOf("rest://127.0.0.1:5342/rest/say1?version=1.0.0");
+ Exporter<RestService> exporter =
protocol.export(proxyFactory.getInvoker(server, RestService.class, url));
+ Invoker<RestService> invoker = protocol.refer(RestService.class, url);
+ RestService client = proxyFactory.getProxy(invoker);
+ String result = client.sayHello("haha");
+ Assert.assertTrue(server.isCalled());
+ Assert.assertEquals("Hello, haha", result);
+ invoker.destroy();
+ exporter.unexport();
+ }
+}
diff --git
a/dubbo-rpc/dubbo-rpc-rest/src/test/java/com/alibaba/dubbo/rpc/protol/rest/RestService.java
b/dubbo-rpc/dubbo-rpc-rest/src/test/java/com/alibaba/dubbo/rpc/protol/rest/RestService.java
new file mode 100644
index 0000000000..30441b2a87
--- /dev/null
+++
b/dubbo-rpc/dubbo-rpc-rest/src/test/java/com/alibaba/dubbo/rpc/protol/rest/RestService.java
@@ -0,0 +1,36 @@
+/*
+ * 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 com.alibaba.dubbo.rpc.protol.rest;
+
+
+import javax.ws.rs.Consumes;
+import javax.ws.rs.POST;
+import javax.ws.rs.Path;
+import javax.ws.rs.core.MediaType;
+
+/**
+ * RestService
+ */
+@Path("/rest")
+public interface RestService {
+
+ @POST
+ @Path("/say1")
+ @Consumes({MediaType.TEXT_PLAIN})
+ String sayHello(String name);
+
+}
diff --git
a/dubbo-rpc/dubbo-rpc-rest/src/test/java/com/alibaba/dubbo/rpc/protol/rest/RestServiceImpl.java
b/dubbo-rpc/dubbo-rpc-rest/src/test/java/com/alibaba/dubbo/rpc/protol/rest/RestServiceImpl.java
new file mode 100644
index 0000000000..3de80d266c
--- /dev/null
+++
b/dubbo-rpc/dubbo-rpc-rest/src/test/java/com/alibaba/dubbo/rpc/protol/rest/RestServiceImpl.java
@@ -0,0 +1,36 @@
+/*
+ * 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 com.alibaba.dubbo.rpc.protol.rest;
+
+/**
+ * RestServiceImpl
+ */
+
+public class RestServiceImpl implements RestService {
+
+ private boolean called;
+
+ public String sayHello(String name) {
+ called = true;
+ return "Hello, " + name;
+ }
+
+
+ public boolean isCalled() {
+ return called;
+ }
+}
----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on GitHub and use the
URL above to go to the specific comment.
For queries about this service, please contact Infrastructure at:
[email protected]
With regards,
Apache Git Services
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]