package ds.controller.rmi;
import java.io.FileNotFoundException;
import java.net.Socket;
import java.rmi.Naming;
import java.rmi.RemoteException;
import java.util.Properties;
import java.util.Vector;
import org.apache.log4j.Logger;
import ds.controller.helper.NodeInfo;
import ds.controller.helper.NodeSelecter;
import ds.shared.rmi.FileServerImpl;
import ds.shared.rmi.FileServerInterface;
import ds.shared.socket.ServerSocketHandler;
/**
* The remote object that the Controller exports.
* The controller is responsible for connection clients and nodes.
* It contains a list of available nodes and files.
*
* @author save
*/
@SuppressWarnings("serial")
public class ControllerFileServerImpl extends FileServerImpl implements ControllerFileServerInterface {
// Define a static logger variable
private final static Logger LOGGER = Logger.getLogger(ControllerFileServerImpl.class);
// List of registered nodes
private Vector<NodeInfo> nodes = null;
/**
* Construct a remote object
*
* @param handler
* Serversocket used to assign clients a new connection
* @param conf
* Configuration options
* @param nodes
* List of registered nodes
* if the object handle cannot be constructed.
*/
public ControllerFileServerImpl(ServerSocketHandler handler, Properties conf,
Vector<NodeInfo> nodes) throws RemoteException {
super(handler, conf);
this.nodes = nodes;
}
/**
* Lets a new node register itself.
*
* @param name
* The remote name of the node so we can find its interface.
* @return boolean
* True if the operation was succesfull.
* @throws RemoteException
* if the object handle cannot be constructed.
*/
public boolean register(String name) throws RemoteException {
try {
// Assume localhost for now
String server = "localhost";
FileServerInterface node = (FileServerInterface) Naming.lookup ("//"+server+"/"+name);
LOGGER.debug("Registering node " + name);
int port = node.getServerSocketPort();
LOGGER.debug("Connecting to socket on " + server + ":" + port);
Socket socket = new Socket(server, port);
LOGGER.debug("Opened socket connection");
NodeInfo info = new NodeInfo(node, socket, name);
this.nodes.add(info);
} catch (Exception e) {
LOGGER.debug("Connection could not be made to controller");
//e.printStackTrace();
}
return true;
}
/**
* See if a file exists in the distributed file system.
*
* @param file
* File name
* @throws RemoteException
* if the object handle cannot be constructed.
*/
public boolean exists(String file) throws RemoteException {
// We should have a node that contains this file
int loc = NodeSelecter.select_get(file);
if (loc < 0) {
// File not in our list
return false;
}
else {
// Is it still there?
return nodes.get(loc).getNode().exists(file);
}
}
/**
* If we can find the file, now give me the file size.
* Either from the local file system of the remote node.
*
* @param file
* File name
* @return long
* File size
* @throws RemoteException
* if the object handle cannot be constructed.
*/
public long getFileSize(String file) throws RemoteException {
// We should have a node that contains this file
int loc = NodeSelecter.select_get(file);
return nodes.get(loc).getNode().getFileSize(file);
}
/**
* Returns a list of all the files in a particular entity.
*
* @throws FileNotFoundException
*/
public Vector<String> getFileList() throws RemoteException {
Vector<String> temp = new Vector<String>();
for(int i = 0; i < nodes.size(); i++) {
temp.addAll( nodes.get(i).getNode().getFileList() );
}
return temp;
}
/**
* Lets a new node remove itself when it quits.
*
* @param location
* The remote location of the node, where we can find its interface.
* @return boolean
* True if the operation was succesfull.
* @throws RemoteException
* if the object handle cannot be constructed.
*/
public boolean remove(String location) throws RemoteException {
// TODO: implement
return false;
}
}