/***************************************************************************
* *
* RMIProxy.java *
* ------------------- *
* date : 22.02.2008, 14:10:04 *
* copyright : (C) 2008 Distributed and *
* Mobile Systems Group *
* Lehrstuhl fuer Praktische Informatik *
* Universitaet Bamberg *
* http://www.uni-bamberg.de/pi/ *
* email : sven.kaffille@uni-bamberg.de *
* *
* *
***************************************************************************/
/***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* A copy of the license can be found in the license.txt file supplied *
* with this software or at: http://www.gnu.org/copyleft/gpl.html *
* *
***************************************************************************/
package de.uniba.wiai.lspi.chord.com.rmi;
import java.rmi.NotBoundException;
import java.rmi.RemoteException;
import java.rmi.registry.LocateRegistry;
import java.util.LinkedList;
import java.util.List;
import java.util.Set;
import de.uniba.wiai.lspi.chord.com.Broadcast;
import de.uniba.wiai.lspi.chord.com.CommunicationException;
import de.uniba.wiai.lspi.chord.com.Endpoint;
import de.uniba.wiai.lspi.chord.com.Entry;
import de.uniba.wiai.lspi.chord.com.Node;
import de.uniba.wiai.lspi.chord.com.Proxy;
import de.uniba.wiai.lspi.chord.com.RefsAndEntries;
import de.uniba.wiai.lspi.chord.data.ID;
import de.uniba.wiai.lspi.chord.data.URL;
public final class RMIProxy extends Proxy {
private static final String NAME_IN_REGISTRY = RMIEndpoint.NAME_IN_REGISTRY;
/**
*
*/
private RemoteNode remoteNode;
/**
*
*/
private URL localURL;
private volatile boolean connected;
private RMIEndpoint localEndpoint;
/**
*
* @param rNode
* @param url
*/
RMIProxy(RemoteNodeInfo rNode, URL url) {
super(rNode.getUrl());
if (url == null) {
throw new IllegalArgumentException("URL of local node must not be null!");
}
this.remoteNode = rNode.getRemoteNode();
this.nodeID = rNode.getNodeID();
this.localURL = url;
this.connected = true;
this.localEndpoint = (RMIEndpoint)Endpoint.getEndpoint(this.localURL);
}
/**
*
* @param localURL
* @param url
* @throws RemoteException
* @throws CommunicationException
*/
RMIProxy(URL localURL, URL url) throws RemoteException, CommunicationException {
super(url);
if (url == null) {
throw new IllegalArgumentException("URL of local node must not be null!");
}
this.localURL = localURL;
try {
this.remoteNode = (RemoteNode) LocateRegistry.getRegistry(
url.getHost(), url.getPort()).lookup(NAME_IN_REGISTRY+url.toString());
} catch (NotBoundException e) {
throw new CommunicationException("Cannot find stub with name " + url.getHost(), e);
}
this.nodeID = this.remoteNode.getNodeID();
this.connected = true;
this.localEndpoint = (RMIEndpoint)Endpoint.getEndpoint(this.localURL);
}
/**
*
* @param localURL
* @param url
* @return
* @throws CommunicationException
*/
public static RMIProxy create(URL localURL, URL url) throws CommunicationException {
try {
return new RMIProxy(localURL, url);
} catch (RemoteException e) {
throw new CommunicationException(
"Connection cannot be established!", e);
}
}
/**
*
* @return
*/
RemoteNode getRemoteNode() {
return this.remoteNode;
}
@Override
public void disconnect() {
this.connected = false;
}
public void testConnection() throws CommunicationException{
if (this.connected == false) {
throw new CommunicationException("Not connected!");
}
}
@Override
public Node findSuccessor(ID key) throws CommunicationException {
this.testConnection();
try {
RemoteNodeInfo info = this.remoteNode.findSuccessor(key);
return new RMIProxy(info, this.localURL);
} catch (RemoteException e) {
throw new CommunicationException("Could not connect to "
+ this.nodeURL + "!", e);
}
}
@Override
public void insertEntry(Entry entryToInsert) throws CommunicationException {
this.testConnection();
try {
this.remoteNode.insertEntry(entryToInsert);
} catch (RemoteException e) {
throw new CommunicationException("Could not connect to "
+ this.nodeURL + "!", e);
}
}
@Override
public void insertReplicas(Set<Entry> entries)
throws CommunicationException {
this.testConnection();
try {
this.remoteNode.insertReplicas(entries);
} catch (RemoteException e) {
throw new CommunicationException("Could not connect to "
+ this.nodeURL + "!", e);
}
}
@Override
public void leavesNetwork(Node predecessor) throws CommunicationException {
this.testConnection();
try {
RemoteNodeInfo info = null;
if (this.localURL.equals(predecessor.getNodeURL())) {
info = new RemoteNodeInfo(
this.localEndpoint.getRemoteNode(),
predecessor.getNodeID(), predecessor.getNodeURL());
} else {
info = new RemoteNodeInfo(
((RMIProxy)predecessor).remoteNode,
predecessor.getNodeID(), predecessor.getNodeURL());
}
this.remoteNode.leavesNetwork(info);
} catch (RemoteException e) {
throw new CommunicationException("Could not connect to "
+ this.getNodeURL() + "!", e);
}
}
@Override
public List<Node> notify(Node predecessor) throws CommunicationException {
this.testConnection();
try {
RemoteNodeInfo info = null;
if (this.localURL.equals(predecessor.getNodeURL())) {
info = new RemoteNodeInfo(
this.localEndpoint.getRemoteNode(),
predecessor.getNodeID(), predecessor.getNodeURL());
} else {
info = new RemoteNodeInfo(
((RMIProxy)predecessor).remoteNode,
predecessor.getNodeID(), predecessor.getNodeURL());
}
List<RemoteNodeInfo> infos = this.remoteNode
.notify(info);
List<Node> nodes = new LinkedList<Node>();
for (RemoteNodeInfo i : infos) {
nodes.add(new RMIProxy(i, this.localURL));
}
return nodes;
} catch (RemoteException e) {
throw new CommunicationException("Could not connect to "
+ this.nodeURL + "!", e);
}
}
@Override
public RefsAndEntries notifyAndCopyEntries(Node predecessor)
throws CommunicationException {
this.testConnection();
try {
RemoteNodeInfo info = null;
if (this.localURL.equals(predecessor.getNodeURL())) {
info = new RemoteNodeInfo(
this.localEndpoint.getRemoteNode(),
predecessor.getNodeID(), predecessor.getNodeURL());
} else {
info = new RemoteNodeInfo(
((RMIProxy)predecessor).remoteNode,
predecessor.getNodeID(), predecessor.getNodeURL());
}
RemoteRefsAndEntries rraes = this.remoteNode
.notifyAndCopyEntries(info);
List<Node> nodes = new LinkedList<Node>();
List<RemoteNodeInfo> infos = rraes.getNodeInfos();
for (RemoteNodeInfo i : infos) {
nodes.add(new RMIProxy(i, this.localURL));
}
RefsAndEntries raes = new RefsAndEntries(nodes, rraes.getEntries());
return raes;
} catch (RemoteException e) {
throw new CommunicationException("Could not connect to "
+ this.nodeURL + "!", e);
}
}
@Override
public void ping() throws CommunicationException {
this.testConnection();
try {
this.remoteNode.ping();
} catch (RemoteException e) {
throw new CommunicationException("Could not connect to "
+ this.nodeURL + "!", e);
}
}
@Override
public void removeEntry(Entry entryToRemove) throws CommunicationException {
this.testConnection();
try {
this.remoteNode.removeEntry(entryToRemove);
} catch (RemoteException e) {
throw new CommunicationException("Could not connect to "
+ this.nodeURL + "!", e);
}
}
@Override
public void removeReplicas(ID sendingNode, Set<Entry> replicasToRemove)
throws CommunicationException {
this.testConnection();
try {
this.remoteNode.removeReplicas(sendingNode, replicasToRemove);
} catch (RemoteException e) {
throw new CommunicationException("Could not connect to "
+ this.nodeURL + "!", e);
}
}
@Override
public Set<Entry> retrieveEntries(ID id) throws CommunicationException {
this.testConnection();
try {
return this.remoteNode.retrieveEntries(id);
} catch (RemoteException e) {
throw new CommunicationException("Could not connect to "
+ this.nodeURL + "!", e);
}
}
@Override
public void broadcast(Broadcast info) throws CommunicationException {
this.testConnection();
try {
this.remoteNode.broadcast(info);
} catch (RemoteException e) {
throw new CommunicationException("Could not connect to "
+ this.nodeURL + "!", e);
}
}
}