Package com.spidercache.dht

Source Code of com.spidercache.dht.DHT

package com.spidercache.dht;

import java.io.IOException;
import java.io.Serializable;
import java.math.BigInteger;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.UnknownHostException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.logging.Level;
import java.util.logging.Logger;

import org.planx.routing.kademlia.Node;
import org.apache.log4j.*;
import org.planx.routing.kademlia.*;
import org.planx.routing.messaging.*;
import org.planx.routing.*;

/**
* Class for creating a DHT.
*
* @author Michael Neu
*
*/
public class DHT {

  /**
   * Kademlia DHT object inside this DHT object
   */
  private Kademlia dht;
  /**
   * Kademlia node representation used in this DHT object; used with Message
   * Server
   */
  private Node node;
  /**
   * Kademlia MessageServer object used in this DHT object
   */
  private MessageServer messageServer;
 
  /**
   * Log4j Log.
   */
  private Logger log;

  /**
   * Constructor for creating a DHT object.
   *
   * @param name
   *            Name of node. Used as the filename base if given. If null then persistence is not used.
   * @param dhtUdpPort
   *            UDP Port for the DHT to route messages on
   * @param messageServerUdpPort
   *            UDP Port for the MessageServer to listen on
   * @param bootStrapNodeHostName
   *            Hostname of node to bootstrap to
   * @param bootStrapNodePort
   *            UDP Port of node to bootstrap to
   */
  public DHT(String name, int dhtUdpPort, int messageServerUdpPort,
      String bootStrapNodeHostName, int bootStrapNodePort) {
    Kademlia dhtMain = null;
    Node dhtNode = null;
    MessageServer msgServer = null;
    Configuration dhtConfiguration = configure();
    try {
      dhtMain = new Kademlia(Identifier.randomIdentifier(), dhtUdpPort);
      dhtNode = new Node(InetAddress.getLocalHost(),
          messageServerUdpPort, Identifier.randomIdentifier());
      Space space1 = new Space(dhtNode, dhtConfiguration);
      MessageFactory factory1 = new DHTMessageFactoryImpl(null, dhtNode, space1);
      msgServer = new MessageServer(messageServerUdpPort, factory1, 500);
      if (bootStrapNodeHostName != null) { // bootstrap to given node
        dhtMain.connect(new InetSocketAddress(bootStrapNodeHostName,
            bootStrapNodePort));
      } else{
        //currently does nothing
      }
    } catch (RoutingException ex) {
      Logger.getLogger(DHT.class.getName()).log(Level.SEVERE, null, ex);
    } catch (IOException ex) {
      Logger.getLogger(DHT.class.getName()).log(Level.SEVERE, null, ex);
    }
    dht = dhtMain;
    node = dhtNode;
    messageServer = msgServer;
  }

  /**
   * Connects to the DHT via the given bootstrap node's hostname and port.
   *
   * @param bootStrapNodeHostName
   *            Hostname of the DHT Node to connect to
   * @param bootStrapNodePort
   *            Port of the DHT Node to connect to
   * @throws RoutingException
   *             If the bootstrap node could not be contacted
   * @throws IOException
   *             If a network error occurred
   */
  public boolean connectNode(String bootStrapNodeHostName, int bootStrapNodePort){

    InetSocketAddress socketAddress = new InetSocketAddress(
        bootStrapNodeHostName, bootStrapNodePort);
    try{
    dht.connect(socketAddress);
    return true;
    }
    catch(RoutingException e){
      return false;
    }
    catch(IOException e){
      return false;
    }
  }

  /**
   * Closes the DHT. Once closed the DHT will not accept any new messages or
   * DHT operation requests.
   *
   * @throws IOException
   *             If an error occurred while writing data to disk while closing
   *             the DHT
   */
  public boolean closeNode(){
    try{
    dht.close();
    messageServer.close();
    return true;
    }
    catch(IOException e){
      return false;
    }
  }

  /**
   * Constructs a Kademlia Configuration object. Currently only returns a
   * default Configuration object.
   *
   * @return Constructed Kademlia Configuration object.
   */
  private Configuration configure() {
    Configuration dhtConfiguration = new Configuration();
    return dhtConfiguration;
  }

  /**
   * Adds an object to the DHT with the given key.
   *
   * @param key
   *            Key of the Object being added to the DHT
   * @param object
   *            Object to add to the DHT
   * @throws RoutingException
   *             If the operation timed out
   * @throws IOException
   *             If a network error occurred
   */
  public boolean put(String key, Serializable object){
    Identifier id = toIdentifier(key);
    try{
    dht.put(id, object);
    return true;
    }
    catch(RoutingException e){
      return false;
    }
    catch(IOException e){
      return false;
    }
  }

  /**
   * Checks the DHT for the given key. Returns true if the key is in the DHT
   * and false if it is not.
   *
   * @param key
   *            The key to search the DHT for
   * @return True if the key is found and false if it is not
   * @throws RoutingException
   *             If the lookup operation timed out
   * @throws IOException
   *             If a network error occurred
   */
  public boolean canFind(String key) throws RoutingException, IOException {
    Identifier id = toIdentifier(key);
    boolean exists = dht.contains(id);
    return exists;
  }

  /**
   * Returns the object which is mapped to the given key. If the value is
   * stored locally no DHT lookup is performed.
   *
   * @param key
   *            The key of the object to search the DHT for
   * @return The value mapped to the key or null if no value is mapped to the
   *         key.
   * @throws RoutingException
   *             If the lookup operation timed out
   * @throws IOException
   *             If a network error occurred
   */
  public Serializable get(String key) throws RoutingException, IOException {
    Identifier id = toIdentifier(key);
    Serializable data = dht.get(id);
    return data;
  }

  /**
   * Removes the object mapped to the given key from the DHT
   *
   * @param key
   *            The key to the object that is to be removed.
   * @throws IOException
   *             If a network error occurred
   */
  public boolean remove(String key){
    Identifier id = toIdentifier(key);
    try{
    dht.remove(id);
    return true;
    }
    catch(RoutingException e){
      return false;
    }
    catch(IOException e){
      return false;
    }
  }

  /**
   * Sends the given Message and calls the given Receiver when a reply for the
   * message is received. If the given receiver is null then replies are
   * ignored. Returns a unique communication id which can be used to identify
   * a reply.
   *
   * @param message
   *            Message to send
   * @param toIp
   *            InetAddress of the Message Server of the Node that the Message
   *            is to be sent to
   * @param toPort
   *            UDP Port of the Messaging Server of the Node that the Message
   *            is to be sent to
   * @return Unique message ID for the reply. ID is an int.
   * @throws IOException
   *             If a network error occurred
   */
  public int sendMessage(Message message, InetAddress toIp, int toPort,
      Receiver receiver) throws IOException {
    int replyID = messageServer.send(message, toIp, toPort, receiver);
    return replyID;
  }

  /**
   * Sends a reply Message with the specified message ID.
   *
   * @param message
   * @param toIp
   *            InetAddress of the Message Server of the Node that the Message
   *            is being sent to
   * @param toPort
   *            UDP Port of the Messaging Server of the Node that the reply
   *            Message is to be sent to
   * @param messageID
   *            Unique message ID that this message is responding to.
   * @throws IOException
   *             If a network error occurred
   */
  public void replyMessage(Message message, InetAddress toIp, int toPort,
      int messageID) throws IOException {
    messageServer.reply(messageID, message, toIp, toPort);
  }

  /*
   * (non-Javadoc)
   *
   * @see java.lang.Object#toString()
   */
  @Override
  public String toString() {
    return "DHT [dht=" + dht.toString() + ", node=" + node.toString()
        + ", messageServer=" + messageServer.toString() + "]";
  }

  /**
   * Utility method to convert a String key into an Identifier object which
   * can be used as a key within the Kadmelia DHT.
   *
   * @param key
   *            Key to turn into an Identifier which can be used within the
   *            DHT
   * @return The Identifier representation of the given String key
   */
  private static Identifier toIdentifier(String key) {
    MessageDigest md5;
    Identifier id = null;
    try {
      md5 = MessageDigest.getInstance("MD5");
      md5.update(key.getBytes());
      byte[] md5Bytes = md5.digest();
      md5.reset();
      BigInteger bi = new BigInteger(1, md5Bytes);
      id = new Identifier(bi);
    } catch (NoSuchAlgorithmException ex) {
      Logger.getLogger(DHT.class.getName()).log(Level.SEVERE, null, ex);
    }
    return id;
  }

  /**
   * Utility method to return the Node object of the DHT.
   *
   * @return the Node object of the DHT
   */
  public Node getNode() {
    return node;
  }
 
  public static void main(String args[]) throws RoutingException, IOException{
    DHT D = new DHT("SpiderCache", 6661, 6662, "172.31.219.26", 6661);
    String s = (String) D.get("hello");
    System.out.println(s);
  }

}
TOP

Related Classes of com.spidercache.dht.DHT

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.