Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Rmi support generic #3577

Merged
merged 3 commits into from
Mar 4, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,12 @@
import org.apache.dubbo.common.URL;
import org.apache.dubbo.rpc.RpcException;
import org.apache.dubbo.rpc.protocol.AbstractProxyProtocol;

import org.apache.dubbo.rpc.service.GenericService;
import org.apache.dubbo.rpc.support.ProtocolUtils;
import org.springframework.remoting.RemoteAccessException;
import org.springframework.remoting.rmi.RmiProxyFactoryBean;
import org.springframework.remoting.rmi.RmiServiceExporter;
import org.springframework.remoting.support.RemoteInvocation;

import java.io.IOException;
import java.net.SocketTimeoutException;
Expand All @@ -50,21 +52,14 @@ public int getDefaultPort() {

@Override
protected <T> Runnable doExport(final T impl, Class<T> type, URL url) throws RpcException {
final RmiServiceExporter rmiServiceExporter = new RmiServiceExporter();
rmiServiceExporter.setRegistryPort(url.getPort());
rmiServiceExporter.setServiceName(url.getPath());
rmiServiceExporter.setServiceInterface(type);
rmiServiceExporter.setService(impl);
try {
rmiServiceExporter.afterPropertiesSet();
} catch (RemoteException e) {
throw new RpcException(e.getMessage(), e);
}
RmiServiceExporter rmiServiceExporter = createExporter(impl, type, url, false);
RmiServiceExporter genericServiceExporter = createExporter(impl, GenericService.class, url, true);
return new Runnable() {
@Override
public void run() {
try {
rmiServiceExporter.destroy();
genericServiceExporter.destroy();
} catch (Throwable e) {
logger.warn(e.getMessage(), e);
}
Expand All @@ -76,6 +71,8 @@ public void run() {
@SuppressWarnings("unchecked")
protected <T> T doRefer(final Class<T> serviceType, final URL url) throws RpcException {
final RmiProxyFactoryBean rmiProxyFactoryBean = new RmiProxyFactoryBean();
final String generic = url.getParameter(Constants.GENERIC_KEY);
final boolean isGeneric = ProtocolUtils.isGeneric(generic) || serviceType.equals(GenericService.class);
/*
RMI needs extra parameter since it uses customized remote invocation object

Expand All @@ -86,11 +83,27 @@ protected <T> T doRefer(final Class<T> serviceType, final URL url) throws RpcExc
3. if the provider version is lower than v2.6.3, does not use customized RemoteInvocation.
*/
if (isRelease270OrHigher(url.getParameter(Constants.RELEASE_KEY))) {
rmiProxyFactoryBean.setRemoteInvocationFactory(RmiRemoteInvocation::new);
rmiProxyFactoryBean.setRemoteInvocationFactory((methodInvocation) -> {
RemoteInvocation invocation = new RmiRemoteInvocation(methodInvocation);
if (invocation != null && isGeneric) {
invocation.addAttribute(Constants.GENERIC_KEY, generic);
}
return invocation;
});
} else if (isRelease263OrHigher(url.getParameter(Constants.DUBBO_VERSION_KEY))) {
rmiProxyFactoryBean.setRemoteInvocationFactory(com.alibaba.dubbo.rpc.protocol.rmi.RmiRemoteInvocation::new);
rmiProxyFactoryBean.setRemoteInvocationFactory((methodInvocation) -> {
RemoteInvocation invocation = new com.alibaba.dubbo.rpc.protocol.rmi.RmiRemoteInvocation(methodInvocation);
if (invocation != null && isGeneric) {
invocation.addAttribute(Constants.GENERIC_KEY, generic);
}
return invocation;
});
}
String serviceUrl = url.toIdentityString();
if (isGeneric) {
serviceUrl = serviceUrl + "/" + Constants.GENERIC_KEY;
}
rmiProxyFactoryBean.setServiceUrl(url.toIdentityString());
rmiProxyFactoryBean.setServiceUrl(serviceUrl);
rmiProxyFactoryBean.setServiceInterface(serviceType);
rmiProxyFactoryBean.setCacheStub(true);
rmiProxyFactoryBean.setLookupStubOnStartup(true);
Expand All @@ -117,4 +130,22 @@ protected int getErrorCode(Throwable e) {
return super.getErrorCode(e);
}

private <T> RmiServiceExporter createExporter(T impl, Class<?> type, URL url, boolean isGeneric) {
final RmiServiceExporter rmiServiceExporter = new RmiServiceExporter();
rmiServiceExporter.setRegistryPort(url.getPort());
if (isGeneric) {
rmiServiceExporter.setServiceName(url.getPath() + "/" + Constants.GENERIC_KEY);
} else {
rmiServiceExporter.setServiceName(url.getPath());
}
rmiServiceExporter.setServiceInterface(type);
rmiServiceExporter.setService(impl);
try {
rmiServiceExporter.afterPropertiesSet();
} catch (RemoteException e) {
throw new RpcException(e.getMessage(), e);
}
return rmiServiceExporter;
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@
*/
package org.apache.dubbo.rpc.protocol.rmi;

import org.apache.dubbo.common.Constants;
import org.apache.dubbo.common.utils.StringUtils;
import org.apache.dubbo.rpc.RpcContext;

import org.aopalliance.intercept.MethodInvocation;
Expand All @@ -34,7 +36,7 @@ public class RmiRemoteInvocation extends RemoteInvocation {
*/
public RmiRemoteInvocation(MethodInvocation methodInvocation) {
super(methodInvocation);
addAttribute(dubboAttachmentsAttrName, new HashMap<String, String>(RpcContext.getContext().getAttachments()));
addAttribute(dubboAttachmentsAttrName, new HashMap<>(RpcContext.getContext().getAttachments()));
}

/**
Expand All @@ -48,6 +50,10 @@ public Object invoke(Object targetObject) throws NoSuchMethodException, IllegalA
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 {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@
public interface DemoService {
void sayHello(String name);

String sayHi(String name);

String echo(String text);

long timestamp();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,10 @@ public void sayHello(String name) {
System.out.println("hello " + name);
}

public String sayHi(String name) {
return "Hi, " + name;
}

public String echo(String text) {
return text;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,11 @@
import org.apache.dubbo.rpc.Protocol;
import org.apache.dubbo.rpc.ProxyFactory;
import org.apache.dubbo.rpc.RpcException;
import org.apache.dubbo.rpc.Invoker;
import org.apache.dubbo.rpc.service.EchoService;

import org.apache.dubbo.rpc.service.GenericService;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;

Expand Down Expand Up @@ -115,6 +118,19 @@ public void testRmiProtocol_echoService() throws Exception {
rpcExporter.unexport();
}

@Test
public void testGenericInvoke() {
DemoService service = new DemoServiceImpl();
URL url = URL.valueOf("rmi://127.0.0.1:9003/" + DemoService.class.getName() + "?release=2.7.0");
Exporter<DemoService> exporter = protocol.export(proxy.getInvoker(service, DemoService.class, url));
Invoker<GenericService> invoker = protocol.refer(GenericService.class, url);
GenericService client = proxy.getProxy(invoker, true);
String result = (String) client.$invoke("sayHi", new String[]{"java.lang.String"}, new Object[]{"haha"});
Assertions.assertEquals("Hi, haha", result);
invoker.destroy();
exporter.unexport();
}

public static interface NonStdRmiInterface {
void bark();
}
Expand Down