迁移rmi协议到开源模块
git-svn-id: http://code.alibabatech.com/svn/dubbo/trunk@77 1a56cb94-b969-4eaa-88fa-be21384802f2
This commit is contained in:
parent
036ca61aa1
commit
92b4472168
|
|
@ -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>
|
||||
|
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
@ -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;
|
||||
|
||||
}
|
||||
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
|
@ -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 Client(Client可能没有这个类),考虑到与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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -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);
|
||||
}
|
||||
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
|
@ -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);
|
||||
}*/
|
||||
|
||||
}
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
|
@ -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
|
||||
}
|
||||
Loading…
Reference in New Issue