迁移rmi协议到开源模块

git-svn-id: http://code.alibabatech.com/svn/dubbo/trunk@77 1a56cb94-b969-4eaa-88fa-be21384802f2
This commit is contained in:
william.liangf 2011-10-26 09:04:16 +00:00
parent 036ca61aa1
commit 92b4472168
14 changed files with 1061 additions and 0 deletions

View File

@ -31,5 +31,10 @@
<artifactId>dubbo-rpc</artifactId>
<version>${project.parent.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring</artifactId>
<scope>provided</scope>
</dependency>
</dependencies>
</project>

View File

@ -0,0 +1,37 @@
/*
* Copyright 1999-2101 Alibaba Group.
*
* Licensed 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.rmi;
import java.lang.reflect.InvocationTargetException;
import java.rmi.RemoteException;
import com.alibaba.dubbo.rpc.Invocation;
import com.alibaba.dubbo.rpc.RpcInvocation;
import com.alibaba.dubbo.rpc.RpcResult;
/**
* AbstratcRmiInvocationHandler
*
* @author william.liangf
*/
public abstract class AbstractRmiInvocationHandler implements RmiInvocationHandler {
public RpcResult invoke(RpcInvocation invocation) throws RemoteException, NoSuchMethodException,
IllegalAccessException, InvocationTargetException {
return (RpcResult) invoke((Invocation) invocation);
}
}

View File

@ -0,0 +1,75 @@
/*
* Copyright 1999-2101 Alibaba Group.
*
* Licensed 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.rmi;
import java.lang.reflect.InvocationTargetException;
import java.rmi.Remote;
import java.rmi.RemoteException;
import com.alibaba.dubbo.common.bytecode.Wrapper;
import com.alibaba.dubbo.rpc.Invocation;
import com.alibaba.dubbo.rpc.Result;
import com.alibaba.dubbo.rpc.RpcResult;
/**
* Generic Remote object adapter to rmi invocation handler.
*
* @serial
* @author qian.lei
*/
class RemoteObject2RmiInvocationHandler extends AbstractRmiInvocationHandler
{
private Remote mRemote;
private Wrapper mWrapper;
RemoteObject2RmiInvocationHandler(Remote remote, Class<?> type)
{
// check remote object and interface.
if( type.isInterface() == false )
throw new IllegalArgumentException("Service type must be interface. " + type.getName());
if( type.isInstance(remote) == false )
throw new IllegalArgumentException("Remote object must implement interface: " + type.getName());
mRemote = remote;
mWrapper = Wrapper.getWrapper(type);
}
public Result invoke(Invocation inv)
throws RemoteException, NoSuchMethodException, IllegalAccessException, InvocationTargetException
{
RpcResult result = new RpcResult();
try
{
result.setResult(mWrapper.invokeMethod(mRemote, inv.getMethodName(), inv.getParameterTypes(), inv.getArguments()));
}
catch(InvocationTargetException e)
{
Throwable rmiInvocationEx = e.getTargetException();
if(null == rmiInvocationEx) throw e;
if(rmiInvocationEx.getClass().getName().startsWith("java.rmi.")
|| rmiInvocationEx.getClass().getName().startsWith("javax.rmi.")) {
throw new RemoteException("", rmiInvocationEx);
}
result.setException(rmiInvocationEx);
}
return result;
}
}

View File

@ -0,0 +1,76 @@
/*
* Copyright 1999-2101 Alibaba Group.
*
* Licensed 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.rmi;
import java.rmi.Remote;
import java.rmi.registry.Registry;
import java.rmi.server.UnicastRemoteObject;
import com.alibaba.dubbo.common.logger.Logger;
import com.alibaba.dubbo.common.logger.LoggerFactory;
import com.alibaba.dubbo.rpc.Invoker;
import com.alibaba.dubbo.rpc.protocol.AbstractExporter;
/**
* Rmi exporter.
*
* @author qian.lei
*/
public class RmiExporter<T> extends AbstractExporter<T>
{
private static final Logger Log = LoggerFactory.getLogger(RmiExporter.class);
private Remote mRemote;
private Registry mRmiRegistry;
RmiExporter(Invoker<T> invoker) {
super(invoker);
}
public void unexport()
{
super.unexport();
if( mRmiRegistry != null )
{
try
{
// unbind.
mRmiRegistry.unbind(getInvoker().getUrl().getPath());
// unexport.
if( mRemote != null )
UnicastRemoteObject.unexportObject(mRemote, true);
}
catch(Exception e)
{
Log.warn("Unexport rmi object error.", e); //ignore it.
}
mRemote = null;
mRmiRegistry = null;
}
}
void setRmiRegistry(Registry reg)
{
mRmiRegistry = reg;
}
void setRemoteObject(Remote remote)
{
mRemote = remote;
}
}

View File

@ -0,0 +1,46 @@
/*
* Copyright 1999-2011 Alibaba Group.
*
* Licensed 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.rmi;
import java.lang.reflect.InvocationTargetException;
import java.rmi.Remote;
import java.rmi.RemoteException;
import com.alibaba.dubbo.rpc.Invocation;
import com.alibaba.dubbo.rpc.Result;
/**
* rmi invocation handler.
*
* @serial Don't change the class name.
* @author qianlei
*/
public interface RmiInvocationHandler extends Remote {
/**
* invoke.
*
* @param invocation invocation.
* @return result.
* @throws RemoteException.
* @throws NoSuchMethodException.
* @throws IllegalAccessException.
* @throws InvocationTargetException.
*/
public Result invoke(Invocation invocation) throws RemoteException, NoSuchMethodException,
IllegalAccessException, InvocationTargetException;
}

View File

@ -0,0 +1,105 @@
/*
* Copyright 1999-2101 Alibaba Group.
*
* Licensed 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.rmi;
import java.rmi.NotBoundException;
import java.rmi.Remote;
import java.rmi.RemoteException;
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;
import com.alibaba.dubbo.common.URL;
import com.alibaba.dubbo.rpc.Invocation;
import com.alibaba.dubbo.rpc.Result;
import com.alibaba.dubbo.rpc.RpcException;
import com.alibaba.dubbo.rpc.RpcInvocation;
import com.alibaba.dubbo.rpc.protocol.AbstractInvoker;
/**
* rmi rpc invoker.
*
* @author qian.lei
*/
public class RmiInvoker<T> extends AbstractInvoker<T> {
private RmiInvocationHandler proxy;
static boolean isInstance(Object obj, String interfaceClazzName) {
for(Class<?> clazz = obj.getClass(); clazz != null && !clazz.equals(Object.class);
clazz = clazz.getSuperclass()) {
Class<?>[] interfaces = clazz.getInterfaces();
for(Class<?> itf : interfaces) {
if(itf.getName().equals(interfaceClazzName)) return true;
}
}
return false;
}
public RmiInvoker(Class<T> serviceType, URL url)
{
super(serviceType, url);
try
{
Registry reg = LocateRegistry.getRegistry(url.getHost(), url.getPort());
String path = url.getPath();
if (path == null || path.length() == 0) {
path = serviceType.getName();
}
Remote rmt = reg.lookup(path);
if( rmt instanceof RmiInvocationHandler ) {
// is the Remote wrap type in Dubbo2
proxy = (RmiInvocationHandler)rmt;
}
else if(isInstance(rmt, "org.springframework.remoting.rmi.RmiInvocationHandler")) {
// is the Remote wrap type in spring? (spring rmi is used in Dubbo1)
proxy = new SpringHandler2RmiInvocationHandler((org.springframework.remoting.rmi.RmiInvocationHandler)rmt, serviceType);
}
else
proxy = new RemoteObject2RmiInvocationHandler(rmt, serviceType);
}
catch(RemoteException e)
{
Throwable cause = e.getCause();
boolean isExportedBySpringButNoSpringClass = ClassNotFoundException.class.isInstance(cause)
&& cause.getMessage().contains("org.springframework.remoting.rmi.RmiInvocationHandler");
String msg = String.format("Can not create remote object%s. url = %s",
isExportedBySpringButNoSpringClass ? "(Rmi object is exported by spring rmi but NO spring class org.springframework.remoting.rmi.RmiInvocationHandler at consumer side)" : "",
url);
throw new RpcException(msg, e);
}
catch(NotBoundException e)
{
throw new RpcException("Rmi service not found. url = " + url, e);
}
}
@Override
protected Object doInvoke(Invocation invocation) throws Throwable {
Result result;
try
{
result = proxy.invoke((RpcInvocation) invocation);
}
catch(Throwable e) // here is non-biz exception, wrap it.
{
throw new RpcException(e);
}
return result.recreate();
}
}

View File

@ -0,0 +1,280 @@
/*
* Copyright 1999-2011 Alibaba Group.
*
* Licensed 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.rmi;
import java.io.IOException;
import java.io.Serializable;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.net.InetSocketAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.rmi.AlreadyBoundException;
import java.rmi.Remote;
import java.rmi.RemoteException;
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;
import java.rmi.server.RMIClientSocketFactory;
import java.rmi.server.RMIServerSocketFactory;
import java.rmi.server.RemoteServer;
import java.rmi.server.ServerNotActiveException;
import java.rmi.server.UnicastRemoteObject;
import java.util.ArrayList;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import org.springframework.remoting.support.RemoteInvocation;
import com.alibaba.dubbo.common.Constants;
import com.alibaba.dubbo.common.Extension;
import com.alibaba.dubbo.common.URL;
import com.alibaba.dubbo.common.bytecode.Proxy;
import com.alibaba.dubbo.common.utils.StringUtils;
import com.alibaba.dubbo.rpc.Exporter;
import com.alibaba.dubbo.rpc.Invocation;
import com.alibaba.dubbo.rpc.Invoker;
import com.alibaba.dubbo.rpc.Result;
import com.alibaba.dubbo.rpc.RpcException;
import com.alibaba.dubbo.rpc.RpcInvocation;
import com.alibaba.dubbo.rpc.protocol.AbstractProtocol;
/**
* RmiProtocolSupport.
*
* @author qian.lei
*/
@Extension("rmi")
public class RmiProtocol extends AbstractProtocol {
public static final int DEFAULT_PORT = 1099;
private final Map<Integer, Registry> registryMap = new ConcurrentHashMap<Integer, Registry>();
private final Map<String, RmiExporter<?>> exporterMap = new ConcurrentHashMap<String, RmiExporter<?>>(); // <service
public int getDefaultPort() {
return DEFAULT_PORT;
}
Remote getObjectToExport(final RmiExporter<?> rpcExporter, boolean isSpringCodec, final String host,
final int port, final Class<?> serviceType) {
boolean isRemoteType = Remote.class.isAssignableFrom(serviceType);
Remote exportedObj;
if (isRemoteType) {
Proxy proxy = Proxy.getProxy(new Class<?>[] { serviceType });
Object proxyService = proxy.newInstance(new InvocationHandler() {
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
String client = null;
try {
client = RemoteServer.getClientHost();
} catch (ServerNotActiveException e) {
// Ignore it.
}
Invocation inv = new RpcInvocation(method, args);
try {
return rpcExporter.invoke(inv, client, 0).recreate();
} catch (RpcException e) {
throw new RemoteException(StringUtils.toString(e));
}
}
});
exportedObj = (Remote) proxyService;
} else if (isSpringCodec) {
try {
Class.forName("org.springframework.remoting.rmi.RmiInvocationHandler");
} catch (ClassNotFoundException e1) {
throw new RpcException(
"set codec spring for protocol rmi,"
+ " but NO spring class org.springframework.remoting.rmi.RmiInvocationHandler at provider side!");
}
exportedObj = new org.springframework.remoting.rmi.RmiInvocationHandler() {
public Object invoke(RemoteInvocation invocation) throws RemoteException, NoSuchMethodException,
IllegalAccessException, InvocationTargetException {
String client = null;
try {
client = RemoteServer.getClientHost();
} catch (ServerNotActiveException e) {
// Ignore it.
}
Invocation inv = new RpcInvocation(invocation.getMethodName(),
invocation.getParameterTypes(),
invocation.getArguments());
try {
return rpcExporter.invoke(inv, client, 0).recreate();
} catch (RpcException e) {
throw new RemoteException(StringUtils.toString(e));
} catch (Throwable t) {
throw new InvocationTargetException(t);
}
}
public String getTargetInterfaceName() throws RemoteException {
return serviceType.getName();
}
};
} else {
exportedObj = new AbstractRmiInvocationHandler() {
public Result invoke(Invocation inv) throws RemoteException, NoSuchMethodException,
IllegalAccessException, InvocationTargetException {
String client = null;
try {
client = RemoteServer.getClientHost();
} catch (ServerNotActiveException e) {
// Ignore it.
}
return rpcExporter.invoke(inv, client, 0);
}
};
}
return exportedObj;
}
public <T> Exporter<T> export(Invoker<T> invoker) throws RpcException {
Class<T> serviceType = invoker.getInterface();
URL url = invoker.getUrl();
String codec = url.getParameter(Constants.CODEC_KEY, "spring");
boolean isSpringCodec;
if ("spring".equals(codec)) {
isSpringCodec = true;
} else if ("dubbo".equals(codec)) {
isSpringCodec = false;
} else {
throw new IllegalArgumentException("Unsupported protocol codec " + codec
+ " for protocol RMI, Only support \"dubbo\", \"spring\" codec.");
}
final RmiExporter<T> ret = new RmiExporter<T>(invoker);
Remote exportedObj = getObjectToExport(ret, isSpringCodec, url.getHost(), url.getPort(), serviceType);
// export.
try {
// UnicastRemoteObject.exportObject(exportedObj, 0, new InternalClientSocketFactory(), new
// InternalServerSocketFactory());
UnicastRemoteObject.exportObject(exportedObj, 0);
ret.setRemoteObject(exportedObj);
} catch (RemoteException e) {
if ("object already exported".equalsIgnoreCase(e.getMessage())) logger.warn("Ignore 'object already exported' exception.",
e);
else throw new RpcException("Export rmi service error.", e);
}
// register.
Registry reg = getOrCreateRegistry(url.getPort());
try {
// bind service.
reg.bind(url.getPath(), exportedObj);
ret.setRmiRegistry(reg);
} catch (RemoteException e) {
throw new RpcException("Bind rmi service [" + url.getPath() + "] error.", e);
} catch (AlreadyBoundException e) {
throw new RpcException("Bind rmi service error. Service name [" + url.getPath() + "] already bound.", e);
}
exporterMap.put(serviceKey(url), ret);
return ret;
}
public <T> Invoker<T> refer(Class<T> serviceType, URL url) throws RpcException {
Invoker<T> invoker = new RmiInvoker<T>(serviceType, url);
invokers.add(invoker);
return invoker ;
}
protected Registry getOrCreateRegistry(int port) {
Registry reg = registryMap.get(port);
if (reg == null) {
try {
// reg = LocateRegistry.createRegistry(port, new InternalClientSocketFactory(), new
// InternalServerSocketFactory());
reg = LocateRegistry.createRegistry(port);
} catch (RemoteException e) {
throw new IllegalStateException("Failed to create rmi registry on port " + port + ", cause: " + e.getMessage(), e);
}
registryMap.put(port, reg);
}
return reg;
}
public void destroy() {
super.destroy();
for (Integer key : new ArrayList<Integer>(registryMap.keySet())) {
Registry registry = registryMap.remove(key);
if (registry != null) {
try {
String[] services = registry.list();
if (services != null && services.length > 0) {
for (String service : services) {
if (logger.isInfoEnabled()) {
logger.info("Unbind rmi service: " + service);
}
registry.unbind(service);
}
}
} catch (Throwable t) {
logger.warn(t.getMessage(), t);
}
}
}
}
/**
* 自定义的RMIClientSocketFactory类用于控制Rmi Client端连接的控制如连接池监控等 这个类会序列化传到Rmi ClientClient可能没有这个类考虑到与Native
* Rmi的目前不使用这个类
*
* @author qian.lei
*/
@SuppressWarnings("unused")
private static class InternalClientSocketFactory implements RMIClientSocketFactory, Serializable {
private static final long serialVersionUID = 8412843862275448994L;
public Socket createSocket(String host, int port) throws IOException {
Socket socket = new Socket();
socket.connect(new InetSocketAddress(host, port));
return socket;
}
}
/**
* @author qian.lei
*/
@SuppressWarnings("unused")
private static class InternalServerSocketFactory implements RMIServerSocketFactory {
public ServerSocket createServerSocket(int port) throws IOException {
return new InternalServerSocket(port);
}
}
private static class InternalServerSocket extends ServerSocket {
public InternalServerSocket(int port) throws IOException{
super(port);
}
public Socket accept() throws IOException {
Socket socket = super.accept();
return socket;
}
}
}

View File

@ -0,0 +1,66 @@
/*
* Copyright 1999-2101 Alibaba Group.
*
* Licensed 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.rmi;
import java.lang.reflect.InvocationTargetException;
import java.rmi.RemoteException;
import org.springframework.remoting.support.RemoteInvocation;
import com.alibaba.dubbo.rpc.Invocation;
import com.alibaba.dubbo.rpc.Result;
import com.alibaba.dubbo.rpc.RpcResult;
/**
*
* @serial
* @author ding.lid
*/
class SpringHandler2RmiInvocationHandler extends AbstractRmiInvocationHandler {
private org.springframework.remoting.rmi.RmiInvocationHandler springHandler;
SpringHandler2RmiInvocationHandler(org.springframework.remoting.rmi.RmiInvocationHandler springHandler, Class<?> type)
{
// check remote object and interface.
if( type.isInterface() == false )
throw new IllegalArgumentException("Service type must be interface. " + type.getName());
this.springHandler = springHandler;
}
public Result invoke(Invocation inv)
throws RemoteException, NoSuchMethodException, IllegalAccessException, InvocationTargetException
{
RpcResult result = new RpcResult();
try
{
RemoteInvocation i = new RemoteInvocation();
i.setMethodName(inv.getMethodName());
i.setParameterTypes(inv.getParameterTypes());
i.setArguments(inv.getArguments());
result.setResult(springHandler.invoke(i));
}
catch(InvocationTargetException e)
{
result.setException(e.getTargetException());
}
return result;
}
}

View File

@ -0,0 +1,41 @@
/*
* Copyright 1999-2101 Alibaba Group.
*
* Licensed 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.rmi;
/**
* <code>TestService</code>
*/
public interface DemoService
{
void sayHello(String name);
String echo(String text);
long timestamp();
String getThreadName();
int getSize(String[] strs);
int getSize(Object[] os);
Object invoke(String service, String method) throws Exception;
int stringLength(String str);
Type enumlength(Type... types);
}

View File

@ -0,0 +1,80 @@
/*
* Copyright 1999-2101 Alibaba Group.
*
* Licensed 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.rmi;
import com.alibaba.dubbo.rpc.RpcContext;
/**
* DemoServiceImpl
*/
public class DemoServiceImpl implements DemoService
{
public DemoServiceImpl()
{
super();
}
public void sayHello(String name) {
System.out.println("hello "+name);
}
public String echo(String text)
{
return text;
}
public long timestamp() {
return System.currentTimeMillis();
}
public String getThreadName()
{
return Thread.currentThread().getName();
}
public int getSize(String[] strs)
{
if( strs == null )
return -1;
return strs.length;
}
public int getSize(Object[] os)
{
if( os == null )
return -1;
return os.length;
}
public Object invoke(String service, String method) throws Exception
{
System.out.println("RpcContext.getContext().getRemoteHost()="+RpcContext.getContext().getRemoteHost());
return service + ":" + method;
}
public Type enumlength(Type... types)
{
if( types.length == 0 )
return Type.Lower;
return types[0];
}
public int stringLength(String str)
{
return str.length();
}
}

View File

@ -0,0 +1,169 @@
/*
* Copyright 1999-2101 Alibaba Group.
*
* Licensed 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.rmi;
import static junit.framework.Assert.assertEquals;
import org.junit.Ignore;
import org.junit.Test;
import com.alibaba.dubbo.common.ExtensionLoader;
import com.alibaba.dubbo.common.URL;
import com.alibaba.dubbo.rpc.Exporter;
import com.alibaba.dubbo.rpc.Protocol;
import com.alibaba.dubbo.rpc.ProxyFactory;
import com.alibaba.dubbo.rpc.service.EchoService;
/**
* <code>ProxiesTest</code>
*/
public class ProtocolsTest
{
private Protocol protocol = ExtensionLoader.getExtensionLoader(Protocol.class).getAdaptiveExtension();
private ProxyFactory proxy = ExtensionLoader.getExtensionLoader(ProxyFactory.class).getAdaptiveExtension();
@Test
public void testRmiProtocol() throws Exception
{
{
DemoService service = new DemoServiceImpl();
Exporter<?> rpcExporter = protocol.export(proxy.getInvoker(service, DemoService.class, URL.valueOf("rmi://127.0.0.1:9001/TestService")));
service = proxy.getProxy(protocol.refer(DemoService.class, URL.valueOf("rmi://127.0.0.1:9001/TestService")));
assertEquals(service.getSize(null), -1);
assertEquals(service.getSize(new String[]{"", "", ""}), 3);
Object result = service.invoke("rmi://127.0.0.1:9001/TestService", "invoke");
assertEquals("rmi://127.0.0.1:9001/TestService:invoke", result);
rpcExporter.unexport();
}
{
RemoteService remoteService = new RemoteServiceImpl();
Exporter<?> rpcExporter = protocol.export(proxy.getInvoker(remoteService, RemoteService.class, URL.valueOf("rmi://127.0.0.1:9001/remoteService")));
remoteService = proxy.getProxy(protocol.refer(RemoteService.class, URL.valueOf("rmi://127.0.0.1:9001/remoteService")));
remoteService.getThreadName();
for(int i=0;i<100;i++) {
String say = remoteService.sayHello("abcd");
assertEquals("hello abcd@com.alibaba.dubbo.rpc.proxy.RemoteServiceImpl", say);
}
rpcExporter.unexport();
}
}
// FIXME RMI协议目前的实现不支持转型成 EchoService
@Ignore
@Test
public void testRmiProtocol_echoService() throws Exception
{
DemoService service = new DemoServiceImpl();
Exporter<?> rpcExporter = protocol.export(proxy.getInvoker(service, DemoService.class, URL.valueOf("rmi://127.0.0.1:9002/TestService")));
// cast to EchoService
EchoService echo = proxy.getProxy(protocol.refer(EchoService.class, URL.valueOf("rmi://127.0.0.1:9002/TestService")));
assertEquals(echo.$echo("test"), "test");
assertEquals(echo.$echo("abcdefg"), "abcdefg");
assertEquals(echo.$echo(1234), 1234);
rpcExporter.unexport();
RemoteService remoteService = new RemoteServiceImpl();
rpcExporter = protocol.export(proxy.getInvoker(remoteService, RemoteService.class, URL.valueOf("rmi://127.0.0.1:9002/remoteService")));
// cast to EchoService
echo = proxy.getProxy(protocol.refer(EchoService.class, URL.valueOf("rmi://127.0.0.1:9002/remoteService")));
assertEquals(echo.$echo("test"), "test");
assertEquals(echo.$echo("abcdefg"), "abcdefg");
assertEquals(echo.$echo(1234), 1234);
rpcExporter.unexport();
}
/*@Test
public void testRpcInvokerGroup() throws Exception
{
DemoService service = new DemoServiceImpl();
RpcUtils.export("demo://127.0.0.1:9030/com.alibaba.dubbo.rpc.TestService",DemoService.class,service);
RpcUtils.export("dubbo://127.0.0.1:9031/TestService",DemoService.class,service);
RpcUtils.export("rmi://127.0.0.1:9032/com.alibaba.dubbo.rpc.TestService",DemoService.class,service);
RpcUtils.export("rmi://127.0.0.1:9033/com.alibaba.dubbo.rpc.TestService",DemoService.class,service);
service = RpcUtils.createProxy(DemoService.class,
new String[]{
"demo://127.0.0.1:9030/com.alibaba.dubbo.rpc.TestService?weight=20",
"dubbo://127.0.0.1:9031/TestService?weight=20",
"rmi://127.0.0.1:9032/com.alibaba.dubbo.rpc.TestService",
});
assertEquals(service.getSize(null), -1);
assertEquals(service.getSize(new String[]{"","",""}), 3);
// cast to EchoService
EchoService echo = RpcUtils.createProxy(EchoService.class,
new String[]{
"demo://127.0.0.1:9030/com.alibaba.dubbo.rpc.TestService?weight=20",
"dubbo://127.0.0.1:9031/TestService?weight=20",
"rmi://127.0.0.1:9032/com.alibaba.dubbo.rpc.TestService",
});
assertEquals(echo.$echo("test"), "test");
assertEquals(echo.$echo("abcdefg"), "abcdefg");
assertEquals(echo.$echo(1234), 1234);
}*/
/*public void testForkInvoke() throws Exception
{
DemoService service = new DemoServiceImpl();
protocol.export(proxy.createInvoker("dubbo://127.0.0.1:9040/TestService", DemoService.class, service);
protocol.export(proxy.createInvoker("dubbo://127.0.0.1:9041/TestService", DemoService.class, service);
protocol.export(proxy.createInvoker("rmi://127.0.0.1:9042/com.alibaba.dubbo.rpc.TestService", DemoService.class, service);
protocol.export(proxy.createInvoker("rmi://127.0.0.1:9043/com.alibaba.dubbo.rpc.TestService", DemoService.class, service);
RpcInvokerGroup group = Proxies.createInvoker(DemoService.class, new String[]{
"dubbo://127.0.0.1:9040/TestService",
"dubbo://127.0.0.1:9041/TestService",
"rmi://127.0.0.1:9042/com.alibaba.dubbo.rpc.TestService",
"rmi://127.0.0.1:9043/com.alibaba.dubbo.rpc.TestService",
});
group.getMethodSettings("echo").setFork(true);
group.getMethodSettings("echo").setForkInvokeCallback(new ForkInvokeCallback(){
public Object merge(RpcInvocation invocation, RpcResult[] results) throws Throwable
{
System.out.println("merge result begin:");
for( RpcResult result : results )
{
if( result.hasException() )
System.out.println("exception:"+result.getException().getMessage());
else
System.out.println("result:"+result.getResult());
}
System.out.println("merge result end:");
return "aaaa";
}
});
service = proxy.createProxy(protocol.refer(DemoService.class, group);
service.echo("test");
// cast to EchoService
EchoService echo = proxy.createProxy(protocol.refer(EchoService.class, group);
assertEquals(echo.$echo("test"), "test");
assertEquals(echo.$echo("abcdefg"), "abcdefg");
assertEquals(echo.$echo(1234), 1234);
}*/
}

View File

@ -0,0 +1,26 @@
/*
* Copyright 1999-2101 Alibaba Group.
*
* Licensed 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.rmi;
import java.rmi.Remote;
import java.rmi.RemoteException;
public interface RemoteService extends Remote
{
String sayHello(String name) throws RemoteException;
String getThreadName() throws RemoteException;
}

View File

@ -0,0 +1,34 @@
/*
* Copyright 1999-2101 Alibaba Group.
*
* Licensed 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.rmi;
import java.rmi.RemoteException;
import com.alibaba.dubbo.rpc.RpcContext;
public class RemoteServiceImpl implements RemoteService
{
public String getThreadName() throws RemoteException
{
System.out.println("RpcContext.getContext().getRemoteHost()="+RpcContext.getContext().getRemoteHost());
return Thread.currentThread().getName();
}
public String sayHello(String name) throws RemoteException
{
return "hello " + name + "@" + RemoteServiceImpl.class.getName();
}
}

View File

@ -0,0 +1,21 @@
/*
* Copyright 1999-2101 Alibaba Group.
*
* Licensed 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.rmi;
public enum Type
{
High, Normal, Lower
}