Started working on Node refreshing the K-Buckets and DHT content at every time interval t

Started working on PUT, GET, STORE operation and on DHT Storage
This commit is contained in:
Joshua Kissoon 2014-02-24 21:26:49 +05:30
parent 3344511603
commit 44077d344d
9 changed files with 203 additions and 29 deletions

View File

@ -26,7 +26,7 @@ public class Configuration
/** /**
* Maximum number of concurrent messages in transit. * Maximum number of concurrent messages in transit.
* */ * */
public static int CONCURRENCY = 2; public static int CONCURRENCY = 10;
/** /**
* Log base exponent. * Log base exponent.

View File

@ -1,26 +1,29 @@
/**
* @author Joshua Kissoon
* @created 20140215
* @desc The main Kademlia network management class
*/
package kademlia.core; package kademlia.core;
import java.io.IOException; import java.io.IOException;
import java.net.InetAddress; import java.net.InetAddress;
import java.util.Timer; import java.util.Timer;
import java.util.TimerTask; import java.util.TimerTask;
import kademlia.dht.DHTContent;
import kademlia.exceptions.RoutingException; import kademlia.exceptions.RoutingException;
import kademlia.message.MessageFactory; import kademlia.message.MessageFactory;
import kademlia.node.Node; import kademlia.node.Node;
import kademlia.node.NodeId; import kademlia.node.NodeId;
import kademlia.operation.ConnectOperation; import kademlia.operation.ConnectOperation;
import kademlia.operation.Operation; import kademlia.operation.Operation;
import kademlia.operation.RefreshOperation;
/**
* The main Kademlia network management class
*
* @author Joshua Kissoon
* @since 20140215
*/
public class Kademlia public class Kademlia
{ {
/* Kademlia Attributes */ /* Kademlia Attributes */
private final String name; private final String ownerId;
/* Objects to be used */ /* Objects to be used */
private final Node localNode; private final Node localNode;
@ -36,7 +39,7 @@ public class Kademlia
* The instance is bootstraped to an existing network by specifying the * The instance is bootstraped to an existing network by specifying the
* address of a bootstrap node in the network. * address of a bootstrap node in the network.
* *
* @param name The Name of this node used for storage * @param ownerId The Name of this node used for storage
* @param defaultId Default id for the node * @param defaultId Default id for the node
* @param udpPort The UDP port to use for routing messages * @param udpPort The UDP port to use for routing messages
* *
@ -44,9 +47,9 @@ public class Kademlia
* from disk <i>or</i> a network error occurred while * from disk <i>or</i> a network error occurred while
* attempting to connect to the network * attempting to connect to the network
* */ * */
public Kademlia(String name, NodeId defaultId, int udpPort) throws IOException public Kademlia(String ownerId, NodeId defaultId, int udpPort) throws IOException
{ {
this.name = name; this.ownerId = ownerId;
this.localNode = new Node(defaultId, InetAddress.getLocalHost(), udpPort); this.localNode = new Node(defaultId, InetAddress.getLocalHost(), udpPort);
this.messageFactory = new MessageFactory(localNode); this.messageFactory = new MessageFactory(localNode);
this.server = new KadServer(udpPort, this.messageFactory, this.localNode); this.server = new KadServer(udpPort, this.messageFactory, this.localNode);
@ -59,12 +62,15 @@ public class Kademlia
@Override @Override
public void run() public void run()
{ {
/** try
* @todo Create Operation that {
* Refreshes all buckets and sends HashMessages to all nodes that are /* Runs a RefreshOperation to refresh K-Buckets and stored content */
* among the K closest to mappings stored at this node. Also deletes any new RefreshOperation(server, localNode).execute();
* mappings that this node is no longer among the K closest to. }
* */ catch (IOException e)
{
System.err.println("Refresh Operation Failed; Message: " + e.getMessage());
}
} }
}, },
// Delay // Interval // Delay // Interval
@ -102,4 +108,29 @@ public class Kademlia
Operation op = new ConnectOperation(this.server, this.localNode, n); Operation op = new ConnectOperation(this.server, this.localNode, n);
op.execute(); op.execute();
} }
/**
* Stores the specified value under the given key
* This value is stored on K nodes on the network, or all nodes if there are > K total nodes in the network
*
* @param content The content to put onto the DHT
*
*/
public boolean put(DHTContent content)
{
return false;
}
/**
* Get some content stored on the DHT
*
* @param key The key of this content
*
* @return DHTContent The content
*/
public DHTContent get(NodeId key)
{
return null;
}
} }

View File

@ -0,0 +1,35 @@
package kademlia.dht;
import kademlia.node.NodeId;
/**
* Any piece of content that needs to be stored on the DHT
*
* @author Joshua Kissoon
* @since 20140224
*/
public interface DHTContent
{
/**
* @return NodeId The DHT key for this content
*/
public NodeId getKey();
/**
* @return String The type of content
*/
public String getType();
/**
* Each content will have an expiry date for when a user should delete it form his/her machine
*
* @return long The expiry date of this content
*/
public long getExpiryDate();
/**
* @return The ID of the owner of this content
*/
public String getOwnerId();
}

View File

@ -1,8 +1,3 @@
/**
* @author Joshua
* @created
* @desc
*/
package kademlia.node; package kademlia.node;
import java.io.DataInput; import java.io.DataInput;
@ -15,6 +10,13 @@ import java.util.Comparator;
import kademlia.message.Streamable; import kademlia.message.Streamable;
import kademlia.routing.RoutingTable; import kademlia.routing.RoutingTable;
/**
* A Node in the Kademlia network
*
* @author Joshua Kissoon
* @since 20140202
* @version 0.1
*/
public class Node implements Streamable public class Node implements Streamable
{ {
@ -167,7 +169,9 @@ public class Node implements Streamable
{ {
Node n1 = (Node) o1; Node n1 = (Node) o1;
Node n2 = (Node) o2; Node n2 = (Node) o2;
if(n1.getNodeId().equals(n2.getNodeId()))
/* Check if they are equal and return 0 */
if (n1.getNodeId().equals(n2.getNodeId()))
{ {
return 0; return 0;
} }
@ -179,18 +183,20 @@ public class Node implements Streamable
int index2 = nodeId.xor(n2.getNodeId()).getFirstSetBitIndex(); int index2 = nodeId.xor(n2.getNodeId()).getFirstSetBitIndex();
//System.out.println("Node " + n2.getNodeId() + " distance: " + index2); //System.out.println("Node " + n2.getNodeId() + " distance: " + index2);
/* If the first node is closer to the given node, return 1 */
int retval; int retval;
if (index1 < index2) if (index1 < index2)
{ {
/* If the first node is closer to the given node, return 1 */
retval = 1; retval = 1;
} }
else if (index1 > index2)
{
retval = -1;
}
else else
{ {
/**
* If the first node is farther to the given node, return 1
*
* @note -1 will also be returned if both nodes are the same distance away
* This really don't make a difference though, since they need to be sorted.
*/
retval = -1; retval = -1;
} }

View File

@ -67,8 +67,12 @@ public class ConnectOperation implements Operation, Receiver
/* Perform lookup for our own ID to get nodes close to us */ /* Perform lookup for our own ID to get nodes close to us */
Operation lookup = new NodeLookupOperation(this.server, this.localNode, this.localNode.getNodeId()); Operation lookup = new NodeLookupOperation(this.server, this.localNode, this.localNode.getNodeId());
lookup.execute(); lookup.execute();
/* @todo Refresh buckets to get a good routing table */ /**
* @todo Refresh buckets to get a good routing table
* I think after the above lookup operation, K buckets will be filled
* Not sure if this operation is needed here
*/
return null; return null;
} }

View File

@ -17,6 +17,8 @@ public interface Operation
* @return The return value can differ per operation * @return The return value can differ per operation
* *
* @throws kademlia.exceptions.RoutingException * @throws kademlia.exceptions.RoutingException
*
* @todo Remove the Object return type, those operations that return things should have a method to return the data
*/ */
public Object execute() throws IOException, RoutingException; public Object execute() throws IOException, RoutingException;
} }

View File

@ -0,0 +1,43 @@
package kademlia.operation;
import java.io.IOException;
import kademlia.core.KadServer;
import kademlia.node.Node;
/**
* At each time interval t, nodes need to refresh their K-Buckets and their Data Storage
* This Operation will manage refreshing the K-Buckets and data storage
*
* @author Joshua Kissoon
* @created 20140224
*/
public class RefreshOperation implements Operation
{
private final KadServer server;
private final Node localNode;
public RefreshOperation(KadServer server, Node localNode)
{
this.server = server;
this.localNode = localNode;
}
@Override
public synchronized Object execute() throws IOException
{
/* @todo Do a Node Lookup operation to refresh K-Buckets */
new NodeLookupOperation(this.server, this.localNode, this.localNode.getNodeId()).execute();
/**
* @todo Send data in DHT to closest Nodes if they don't have it
* This is better than asking closest nodes for data,
* since the data may not always come from the closest nodes
*/
/**
* @todo Delete any content on this node that this node is not one of the K-Closest nodes to
* @todo Delete any expired content
*/
return null;
}
}

View File

@ -0,0 +1,41 @@
package kademlia.operation;
import java.io.IOException;
import java.util.ArrayList;
import kademlia.core.KadServer;
import kademlia.dht.DHTContent;
import kademlia.node.Node;
/**
* Operation that stores a DHT Content onto the K closest nodes to the content Key
*
* @author Joshua Kissoon
* @since 20140224
*/
public class StoreOperation implements Operation
{
private final KadServer server;
private final Node localNode;
private final DHTContent content;
/**
* @param server
* @param localNode
* @param content The content to be stored on the DHT
*/
public StoreOperation(KadServer server, Node localNode, DHTContent content)
{
this.server = server;
this.localNode = localNode;
this.content = content;
}
@Override
public synchronized Object execute() throws IOException
{
/* Get the nodes on which we need to store the content */
ArrayList<Node> nodes = new NodeLookupOperation(this.server, this.localNode, this.content.getKey()).execute();
return null;
}
}

View File

@ -0,0 +1,12 @@
package kademlia.tests;
/**
* A simple DHT Content object to test DHT storage
*
* @author Joshua Kissoon
* @since 20140224
*/
public class DHTContentImpl
{
}