mirror of
https://github.com/ChronosX88/KademliaDHT.git
synced 2024-11-25 03:32:19 +00:00
Some major major changes to the entire Kademlia System.
Kademlia Node - The Kademlia class is renamed to KademliaNode - this will now serve as the main node on the network - The RoutingTable will be a part of this node Node - The node class is now a basic class containing information about a node to be used by peers on the network RoutingTable - Working on Evicting contacts from the routing table - Working on Replacement Cache - Written another simulation to test these new RoutingTable features
This commit is contained in:
parent
a2f48d2241
commit
54ac3fe740
@ -34,7 +34,7 @@ import kademlia.util.serializer.JsonRoutingTableSerializer;
|
||||
import kademlia.util.serializer.JsonSerializer;
|
||||
|
||||
/**
|
||||
* The main Kademlia network management class
|
||||
* The main Kademlia Node on the network, this node manages everything for this local system.
|
||||
*
|
||||
* @author Joshua Kissoon
|
||||
* @since 20140215
|
||||
@ -43,7 +43,7 @@ import kademlia.util.serializer.JsonSerializer;
|
||||
* @todo Handle IPv6 Addresses
|
||||
*
|
||||
*/
|
||||
public class Kademlia
|
||||
public class KademliaNode
|
||||
{
|
||||
|
||||
/* Kademlia Attributes */
|
||||
@ -53,6 +53,7 @@ public class Kademlia
|
||||
private final transient Node localNode;
|
||||
private final transient KadServer server;
|
||||
private final transient DHT dht;
|
||||
private transient RoutingTable routingTable;
|
||||
private final transient Timer timer;
|
||||
private final int udpPort;
|
||||
private transient KadConfiguration config;
|
||||
@ -66,24 +67,26 @@ public class Kademlia
|
||||
* The instance is bootstraped to an existing network by specifying the
|
||||
* address of a bootstrap node in the network.
|
||||
*
|
||||
* @param ownerId The Name of this node used for storage
|
||||
* @param localNode The Local Node for this Kad instance
|
||||
* @param udpPort The UDP port to use for routing messages
|
||||
* @param dht The DHT for this instance
|
||||
* @param ownerId The Name of this node used for storage
|
||||
* @param localNode The Local Node for this Kad instance
|
||||
* @param udpPort The UDP port to use for routing messages
|
||||
* @param dht The DHT for this instance
|
||||
* @param config
|
||||
* @param routingTable
|
||||
*
|
||||
* @throws IOException If an error occurred while reading id or local map
|
||||
* from disk <i>or</i> a network error occurred while
|
||||
* attempting to bootstrap to the network
|
||||
* */
|
||||
public Kademlia(String ownerId, Node localNode, int udpPort, DHT dht, KadConfiguration config) throws IOException
|
||||
public KademliaNode(String ownerId, Node localNode, int udpPort, DHT dht, RoutingTable routingTable, KadConfiguration config) throws IOException
|
||||
{
|
||||
this.ownerId = ownerId;
|
||||
this.udpPort = udpPort;
|
||||
this.localNode = localNode;
|
||||
this.dht = dht;
|
||||
this.config = config;
|
||||
this.messageFactory = new MessageFactory(localNode, this.dht, this.config);
|
||||
this.routingTable = routingTable;
|
||||
this.messageFactory = new MessageFactory(this, this.dht, this.config);
|
||||
this.server = new KadServer(udpPort, this.messageFactory, this.localNode, this.config);
|
||||
this.timer = new Timer(true);
|
||||
|
||||
@ -97,7 +100,7 @@ public class Kademlia
|
||||
try
|
||||
{
|
||||
/* Runs a DHT RefreshOperation */
|
||||
Kademlia.this.refresh();
|
||||
KademliaNode.this.refresh();
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
@ -110,15 +113,35 @@ public class Kademlia
|
||||
);
|
||||
}
|
||||
|
||||
public Kademlia(String ownerId, NodeId defaultId, int udpPort, KadConfiguration config) throws IOException
|
||||
public KademliaNode(String ownerId, NodeId defaultId, int udpPort, RoutingTable routingTable, KadConfiguration config) throws IOException
|
||||
{
|
||||
this(ownerId, new Node(defaultId, InetAddress.getLocalHost(), udpPort), udpPort, new DHT(ownerId, config), config);
|
||||
this(ownerId,
|
||||
new Node(defaultId, InetAddress.getLocalHost(), udpPort, config),
|
||||
udpPort,
|
||||
routingTable,
|
||||
new DHT(ownerId, config), config);
|
||||
}
|
||||
|
||||
public Kademlia(String ownerId, NodeId defaultId, int udpPort) throws IOException
|
||||
public KademliaNode(String ownerId, Node node, int udpPort, KadConfiguration config) throws IOException
|
||||
{
|
||||
this(ownerId, new Node(defaultId, InetAddress.getLocalHost(), udpPort), udpPort,
|
||||
new DHT(ownerId, new DefaultConfiguration()), new DefaultConfiguration());
|
||||
this(
|
||||
ownerId,
|
||||
node,
|
||||
udpPort,
|
||||
new DHT(ownerId, config),
|
||||
new RoutingTable(node, config),
|
||||
config
|
||||
);
|
||||
}
|
||||
|
||||
public KademliaNode(String ownerId, NodeId defaultId, int udpPort) throws IOException
|
||||
{
|
||||
this(
|
||||
ownerId,
|
||||
new Node(defaultId, InetAddress.getLocalHost(), udpPort),
|
||||
udpPort,
|
||||
new DefaultConfiguration()
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -131,9 +154,9 @@ public class Kademlia
|
||||
* @throws java.io.FileNotFoundException
|
||||
* @throws java.lang.ClassNotFoundException
|
||||
*/
|
||||
public static Kademlia loadFromFile(String ownerId) throws FileNotFoundException, IOException, ClassNotFoundException
|
||||
public static KademliaNode loadFromFile(String ownerId) throws FileNotFoundException, IOException, ClassNotFoundException
|
||||
{
|
||||
return Kademlia.loadFromFile(ownerId, new DefaultConfiguration());
|
||||
return KademliaNode.loadFromFile(ownerId, new DefaultConfiguration());
|
||||
}
|
||||
|
||||
/**
|
||||
@ -147,7 +170,7 @@ public class Kademlia
|
||||
* @throws java.io.FileNotFoundException
|
||||
* @throws java.lang.ClassNotFoundException
|
||||
*/
|
||||
public static Kademlia loadFromFile(String ownerId, KadConfiguration iconfig) throws FileNotFoundException, IOException, ClassNotFoundException
|
||||
public static KademliaNode loadFromFile(String ownerId, KadConfiguration iconfig) throws FileNotFoundException, IOException, ClassNotFoundException
|
||||
{
|
||||
DataInputStream din;
|
||||
|
||||
@ -155,7 +178,7 @@ public class Kademlia
|
||||
* @section Read Basic Kad data
|
||||
*/
|
||||
din = new DataInputStream(new FileInputStream(getStateStorageFolderName(ownerId, iconfig) + File.separator + "kad.kns"));
|
||||
Kademlia ikad = new JsonSerializer<Kademlia>().read(din);
|
||||
KademliaNode ikad = new JsonSerializer<KademliaNode>().read(din);
|
||||
|
||||
/**
|
||||
* @section Read the routing table
|
||||
@ -168,7 +191,6 @@ public class Kademlia
|
||||
*/
|
||||
din = new DataInputStream(new FileInputStream(getStateStorageFolderName(ownerId, iconfig) + File.separator + "node.kns"));
|
||||
Node inode = new JsonSerializer<Node>().read(din);
|
||||
inode.setRoutingTable(irtbl);
|
||||
|
||||
/**
|
||||
* @section Read the DHT
|
||||
@ -177,7 +199,7 @@ public class Kademlia
|
||||
DHT idht = new JsonDHTSerializer().read(din);
|
||||
idht.setConfiguration(iconfig);
|
||||
|
||||
return new Kademlia(ownerId, inode, ikad.getPort(), idht, iconfig);
|
||||
return new KademliaNode(ownerId, inode, ikad.getPort(), idht, irtbl, iconfig);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -223,7 +245,7 @@ public class Kademlia
|
||||
* */
|
||||
public synchronized final void bootstrap(Node n) throws IOException, RoutingException
|
||||
{
|
||||
Operation op = new ConnectOperation(this.server, this.localNode, n, this.config);
|
||||
Operation op = new ConnectOperation(this.server, this, n, this.config);
|
||||
op.execute();
|
||||
}
|
||||
|
||||
@ -240,7 +262,7 @@ public class Kademlia
|
||||
*/
|
||||
public synchronized int put(KadContent content) throws IOException
|
||||
{
|
||||
StoreOperation sop = new StoreOperation(this.server, this.localNode, content, this.dht, this.config);
|
||||
StoreOperation sop = new StoreOperation(this.server, this, content, this.dht, this.config);
|
||||
sop.execute();
|
||||
|
||||
/* Return how many nodes the content was stored on */
|
||||
@ -279,7 +301,7 @@ public class Kademlia
|
||||
}
|
||||
|
||||
/* Seems like it doesn't exist in our DHT, get it from other Nodes */
|
||||
ContentLookupOperation clo = new ContentLookupOperation(server, localNode, param, this.config);
|
||||
ContentLookupOperation clo = new ContentLookupOperation(server, this, param, this.config);
|
||||
clo.execute();
|
||||
return clo.getContentFound();
|
||||
}
|
||||
@ -291,7 +313,7 @@ public class Kademlia
|
||||
*/
|
||||
public void refresh() throws IOException
|
||||
{
|
||||
new KadRefreshOperation(this.server, this.localNode, this.dht, this.config).execute();
|
||||
new KadRefreshOperation(this.server, this, this.dht, this.config).execute();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -343,7 +365,7 @@ public class Kademlia
|
||||
* @section Store Basic Kad data
|
||||
*/
|
||||
dout = new DataOutputStream(new FileOutputStream(getStateStorageFolderName(this.ownerId, this.config) + File.separator + "kad.kns"));
|
||||
new JsonSerializer<Kademlia>().write(this, dout);
|
||||
new JsonSerializer<KademliaNode>().write(this, dout);
|
||||
|
||||
/**
|
||||
* @section Save the node state
|
||||
@ -357,7 +379,7 @@ public class Kademlia
|
||||
* This will cause a serialization recursion, and in turn a Stack Overflow
|
||||
*/
|
||||
dout = new DataOutputStream(new FileOutputStream(getStateStorageFolderName(this.ownerId, this.config) + File.separator + "routingtable.kns"));
|
||||
new JsonRoutingTableSerializer().write(this.localNode.getRoutingTable(), dout);
|
||||
new JsonRoutingTableSerializer().write(this.getRoutingTable(), dout);
|
||||
|
||||
/**
|
||||
* @section Save the DHT
|
||||
@ -384,6 +406,11 @@ public class Kademlia
|
||||
return nodeStateFolder.toString();
|
||||
}
|
||||
|
||||
public RoutingTable getRoutingTable()
|
||||
{
|
||||
return this.routingTable;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a string containing all data about this Kademlia instance
|
||||
*
|
||||
@ -403,7 +430,7 @@ public class Kademlia
|
||||
|
||||
sb.append("\n");
|
||||
sb.append("Routing Table: ");
|
||||
sb.append(this.localNode.getRoutingTable());
|
||||
sb.append(this.getRoutingTable());
|
||||
sb.append("\n");
|
||||
|
||||
sb.append("\n");
|
@ -14,7 +14,7 @@ public class DefaultConfiguration implements KadConfiguration
|
||||
private final static long RESPONSE_TIMEOUT = 1500;
|
||||
private final static long OPERATION_TIMEOUT = 3000;
|
||||
private final static int CONCURRENCY = 10;
|
||||
private final static int K = 10;
|
||||
private final static int K = 3;
|
||||
private final static int RCSIZE = 3;
|
||||
private final static int STALE = 1;
|
||||
private final static String LOCAL_FOLDER = "kademlia";
|
||||
|
@ -1,8 +1,8 @@
|
||||
package kademlia.message;
|
||||
|
||||
import java.io.IOException;
|
||||
import kademlia.KademliaNode;
|
||||
import kademlia.core.KadServer;
|
||||
import kademlia.node.Node;
|
||||
|
||||
/**
|
||||
* Receives a ConnectMessage and sends an AcknowledgeMessage as reply.
|
||||
@ -14,9 +14,9 @@ public class ConnectReceiver implements Receiver
|
||||
{
|
||||
|
||||
private final KadServer server;
|
||||
private final Node localNode;
|
||||
private final KademliaNode localNode;
|
||||
|
||||
public ConnectReceiver(KadServer server, Node local)
|
||||
public ConnectReceiver(KadServer server, KademliaNode local)
|
||||
{
|
||||
this.server = server;
|
||||
this.localNode = local;
|
||||
@ -38,7 +38,7 @@ public class ConnectReceiver implements Receiver
|
||||
this.localNode.getRoutingTable().insert(mess.getOrigin());
|
||||
|
||||
/* Respond to the connect request */
|
||||
AcknowledgeMessage msg = new AcknowledgeMessage(this.localNode);
|
||||
AcknowledgeMessage msg = new AcknowledgeMessage(this.localNode.getNode());
|
||||
|
||||
/* Reply to the connect message with an Acknowledgement */
|
||||
this.server.reply(mess.getOrigin(), msg, comm);
|
||||
|
@ -1,10 +1,10 @@
|
||||
package kademlia.message;
|
||||
|
||||
import java.io.IOException;
|
||||
import kademlia.KademliaNode;
|
||||
import kademlia.core.KadConfiguration;
|
||||
import kademlia.core.KadServer;
|
||||
import kademlia.dht.DHT;
|
||||
import kademlia.node.Node;
|
||||
|
||||
/**
|
||||
* Responds to a ContentLookupMessage by sending a ContentMessage containing the requested content;
|
||||
@ -17,11 +17,11 @@ public class ContentLookupReceiver implements Receiver
|
||||
{
|
||||
|
||||
private final KadServer server;
|
||||
private final Node localNode;
|
||||
private final KademliaNode localNode;
|
||||
private final DHT dht;
|
||||
private final KadConfiguration config;
|
||||
|
||||
public ContentLookupReceiver(KadServer server, Node localNode, DHT dht, KadConfiguration config)
|
||||
public ContentLookupReceiver(KadServer server, KademliaNode localNode, DHT dht, KadConfiguration config)
|
||||
{
|
||||
this.server = server;
|
||||
this.localNode = localNode;
|
||||
@ -42,7 +42,7 @@ public class ContentLookupReceiver implements Receiver
|
||||
if (this.dht.contains(msg.getParameters()))
|
||||
{
|
||||
/* Return a ContentMessage with the required data */
|
||||
ContentMessage cMsg = new ContentMessage(localNode, this.dht.get(msg.getParameters()));
|
||||
ContentMessage cMsg = new ContentMessage(localNode.getNode(), this.dht.get(msg.getParameters()));
|
||||
server.reply(msg.getOrigin(), cMsg, comm);
|
||||
}
|
||||
else
|
||||
|
@ -2,10 +2,10 @@ package kademlia.message;
|
||||
|
||||
import java.io.DataInputStream;
|
||||
import java.io.IOException;
|
||||
import kademlia.KademliaNode;
|
||||
import kademlia.core.KadConfiguration;
|
||||
import kademlia.core.KadServer;
|
||||
import kademlia.dht.DHT;
|
||||
import kademlia.node.Node;
|
||||
|
||||
/**
|
||||
* Handles creating messages and receivers
|
||||
@ -16,11 +16,11 @@ import kademlia.node.Node;
|
||||
public class MessageFactory
|
||||
{
|
||||
|
||||
private final Node localNode;
|
||||
private final KademliaNode localNode;
|
||||
private final DHT dht;
|
||||
private final KadConfiguration config;
|
||||
|
||||
public MessageFactory(Node local, DHT dht, KadConfiguration config)
|
||||
public MessageFactory(KademliaNode local, DHT dht, KadConfiguration config)
|
||||
{
|
||||
this.localNode = local;
|
||||
this.dht = dht;
|
||||
@ -64,12 +64,10 @@ public class MessageFactory
|
||||
return new ContentLookupReceiver(server, this.localNode, this.dht, this.config);
|
||||
case NodeLookupMessage.CODE:
|
||||
return new NodeLookupReceiver(server, this.localNode, this.config);
|
||||
case SimpleMessage.CODE:
|
||||
return new SimpleReceiver();
|
||||
case StoreContentMessage.CODE:
|
||||
return new StoreContentReceiver(server, this.localNode, this.dht);
|
||||
default:
|
||||
System.out.println("No reveiver found for message. Code: " + code);
|
||||
System.out.println("No receiver found for message. Code: " + code);
|
||||
return new SimpleReceiver();
|
||||
}
|
||||
}
|
||||
|
@ -2,6 +2,7 @@ package kademlia.message;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
import kademlia.KademliaNode;
|
||||
import kademlia.core.KadConfiguration;
|
||||
import kademlia.core.KadServer;
|
||||
import kademlia.node.Node;
|
||||
@ -16,10 +17,10 @@ public class NodeLookupReceiver implements Receiver
|
||||
{
|
||||
|
||||
private final KadServer server;
|
||||
private final Node localNode;
|
||||
private final KademliaNode localNode;
|
||||
private final KadConfiguration config;
|
||||
|
||||
public NodeLookupReceiver(KadServer server, Node local, KadConfiguration config)
|
||||
public NodeLookupReceiver(KadServer server, KademliaNode local, KadConfiguration config)
|
||||
{
|
||||
this.server = server;
|
||||
this.localNode = local;
|
||||
@ -48,7 +49,7 @@ public class NodeLookupReceiver implements Receiver
|
||||
List<Node> nodes = this.localNode.getRoutingTable().findClosest(msg.getLookupId(), this.config.k());
|
||||
|
||||
/* Respond to the NodeLookupMessage */
|
||||
Message reply = new NodeReplyMessage(this.localNode, nodes);
|
||||
Message reply = new NodeReplyMessage(this.localNode.getNode(), nodes);
|
||||
|
||||
/* Let the Server send the reply */
|
||||
this.server.reply(origin, reply, comm);
|
||||
|
@ -89,6 +89,6 @@ public class NodeReplyMessage implements Message
|
||||
@Override
|
||||
public String toString()
|
||||
{
|
||||
return "ConnectMessage[origin NodeId=" + origin.getNodeId() + "]";
|
||||
return "NodeReplyMessage[origin NodeId=" + origin.getNodeId() + "]";
|
||||
}
|
||||
}
|
||||
|
@ -1,9 +1,9 @@
|
||||
package kademlia.message;
|
||||
|
||||
import java.io.IOException;
|
||||
import kademlia.KademliaNode;
|
||||
import kademlia.core.KadServer;
|
||||
import kademlia.dht.DHT;
|
||||
import kademlia.node.Node;
|
||||
|
||||
/**
|
||||
* Receiver for incoming StoreContentMessage
|
||||
@ -15,10 +15,10 @@ public class StoreContentReceiver implements Receiver
|
||||
{
|
||||
|
||||
private final KadServer server;
|
||||
private final Node localNode;
|
||||
private final KademliaNode localNode;
|
||||
private final DHT dht;
|
||||
|
||||
public StoreContentReceiver(KadServer server, Node localNode, DHT dht)
|
||||
public StoreContentReceiver(KadServer server, KademliaNode localNode, DHT dht)
|
||||
{
|
||||
this.server = server;
|
||||
this.localNode = localNode;
|
||||
|
@ -7,10 +7,9 @@ import java.net.InetAddress;
|
||||
import java.net.InetSocketAddress;
|
||||
import java.net.SocketAddress;
|
||||
import kademlia.message.Streamable;
|
||||
import kademlia.routing.RoutingTable;
|
||||
|
||||
/**
|
||||
* A Node in the Kademlia network
|
||||
* A Node in the Kademlia network - Contains basic node network information.
|
||||
*
|
||||
* @author Joshua Kissoon
|
||||
* @since 20140202
|
||||
@ -24,15 +23,12 @@ public class Node implements Streamable
|
||||
private int port;
|
||||
private final String strRep;
|
||||
|
||||
private transient RoutingTable routingTable;
|
||||
|
||||
public Node(NodeId nid, InetAddress ip, int port)
|
||||
{
|
||||
this.nodeId = nid;
|
||||
this.inetAddress = ip;
|
||||
this.port = port;
|
||||
this.strRep = this.nodeId.toString();
|
||||
this.routingTable = new RoutingTable(this);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -109,24 +105,6 @@ public class Node implements Streamable
|
||||
this.port = in.readInt();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return The RoutingTable of this Node
|
||||
*/
|
||||
public RoutingTable getRoutingTable()
|
||||
{
|
||||
return this.routingTable;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets a new routing table to this node, mainly used when we retrieve the node from a saved state
|
||||
*
|
||||
* @param tbl The routing table to use
|
||||
*/
|
||||
public void setRoutingTable(RoutingTable tbl)
|
||||
{
|
||||
this.routingTable = tbl;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o)
|
||||
{
|
||||
|
@ -1,9 +1,9 @@
|
||||
package kademlia.operation;
|
||||
|
||||
import java.io.IOException;
|
||||
import kademlia.KademliaNode;
|
||||
import kademlia.core.KadConfiguration;
|
||||
import kademlia.core.KadServer;
|
||||
import kademlia.node.Node;
|
||||
import kademlia.node.NodeId;
|
||||
|
||||
/**
|
||||
@ -17,10 +17,10 @@ public class BucketRefreshOperation implements Operation
|
||||
{
|
||||
|
||||
private final KadServer server;
|
||||
private final Node localNode;
|
||||
private final KademliaNode localNode;
|
||||
private final KadConfiguration config;
|
||||
|
||||
public BucketRefreshOperation(KadServer server, Node localNode, KadConfiguration config)
|
||||
public BucketRefreshOperation(KadServer server, KademliaNode localNode, KadConfiguration config)
|
||||
{
|
||||
this.server = server;
|
||||
this.localNode = localNode;
|
||||
@ -43,7 +43,7 @@ public class BucketRefreshOperation implements Operation
|
||||
for (int i = 1; i < NodeId.ID_LENGTH; i++)
|
||||
{
|
||||
/* Construct a NodeId that is i bits away from the current node Id */
|
||||
final NodeId current = this.localNode.getNodeId().generateNodeIdByDistance(i);
|
||||
final NodeId current = this.localNode.getNode().getNodeId().generateNodeIdByDistance(i);
|
||||
|
||||
/* Run the Node Lookup Operation, each in a different thread to speed up things */
|
||||
new Thread()
|
||||
@ -53,7 +53,7 @@ public class BucketRefreshOperation implements Operation
|
||||
{
|
||||
try
|
||||
{
|
||||
new NodeLookupOperation(server, localNode, localNode.getNodeId(), BucketRefreshOperation.this.config).execute();
|
||||
new NodeLookupOperation(server, localNode, localNode.getNode().getNodeId(), BucketRefreshOperation.this.config).execute();
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
|
@ -7,6 +7,7 @@ package kademlia.operation;
|
||||
|
||||
import kademlia.message.Receiver;
|
||||
import java.io.IOException;
|
||||
import kademlia.KademliaNode;
|
||||
import kademlia.core.KadConfiguration;
|
||||
import kademlia.core.KadServer;
|
||||
import kademlia.exceptions.RoutingException;
|
||||
@ -21,7 +22,7 @@ public class ConnectOperation implements Operation, Receiver
|
||||
public static final int MAX_CONNECT_ATTEMPTS = 5; // Try 5 times to connect to a node
|
||||
|
||||
private final KadServer server;
|
||||
private final Node localNode;
|
||||
private final KademliaNode localNode;
|
||||
private final Node bootstrapNode;
|
||||
private final KadConfiguration config;
|
||||
|
||||
@ -34,7 +35,7 @@ public class ConnectOperation implements Operation, Receiver
|
||||
* @param bootstrap Node to use to bootstrap the local node onto the network
|
||||
* @param config
|
||||
*/
|
||||
public ConnectOperation(KadServer server, Node local, Node bootstrap, KadConfiguration config)
|
||||
public ConnectOperation(KadServer server, KademliaNode local, Node bootstrap, KadConfiguration config)
|
||||
{
|
||||
this.server = server;
|
||||
this.localNode = local;
|
||||
@ -50,7 +51,7 @@ public class ConnectOperation implements Operation, Receiver
|
||||
/* Contact the bootstrap node */
|
||||
this.error = true;
|
||||
this.attempts = 0;
|
||||
Message m = new ConnectMessage(this.localNode);
|
||||
Message m = new ConnectMessage(this.localNode.getNode());
|
||||
|
||||
/* Send a connect message to the bootstrap node */
|
||||
server.sendMessage(this.bootstrapNode, m, this);
|
||||
@ -77,7 +78,7 @@ public class ConnectOperation implements Operation, Receiver
|
||||
}
|
||||
|
||||
/* Perform lookup for our own ID to get nodes close to us */
|
||||
Operation lookup = new NodeLookupOperation(this.server, this.localNode, this.localNode.getNodeId(), this.config);
|
||||
Operation lookup = new NodeLookupOperation(this.server, this.localNode, this.localNode.getNode().getNodeId(), this.config);
|
||||
lookup.execute();
|
||||
|
||||
/**
|
||||
@ -127,7 +128,7 @@ public class ConnectOperation implements Operation, Receiver
|
||||
{
|
||||
if (++this.attempts < MAX_CONNECT_ATTEMPTS)
|
||||
{
|
||||
this.server.sendMessage(this.bootstrapNode, new ConnectMessage(this.localNode), this);
|
||||
this.server.sendMessage(this.bootstrapNode, new ConnectMessage(this.localNode.getNode()), this);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -10,6 +10,7 @@ import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.SortedMap;
|
||||
import java.util.TreeMap;
|
||||
import kademlia.KademliaNode;
|
||||
import kademlia.dht.GetParameter;
|
||||
import kademlia.core.KadConfiguration;
|
||||
import kademlia.core.KadServer;
|
||||
@ -40,7 +41,7 @@ public class ContentLookupOperation implements Operation, Receiver
|
||||
private static final Byte FAILED = (byte) 0x03;
|
||||
|
||||
private final KadServer server;
|
||||
private final Node localNode;
|
||||
private final KademliaNode localNode;
|
||||
private StorageEntry contentFound = null;
|
||||
private final KadConfiguration config;
|
||||
|
||||
@ -67,10 +68,10 @@ public class ContentLookupOperation implements Operation, Receiver
|
||||
* @param params The parameters to search for the content which we need to find
|
||||
* @param config
|
||||
*/
|
||||
public ContentLookupOperation(KadServer server, Node localNode, GetParameter params, KadConfiguration config)
|
||||
public ContentLookupOperation(KadServer server, KademliaNode localNode, GetParameter params, KadConfiguration config)
|
||||
{
|
||||
/* Construct our lookup message */
|
||||
this.lookupMessage = new ContentLookupMessage(localNode, params);
|
||||
this.lookupMessage = new ContentLookupMessage(localNode.getNode(), params);
|
||||
|
||||
this.server = server;
|
||||
this.localNode = localNode;
|
||||
@ -94,7 +95,7 @@ public class ContentLookupOperation implements Operation, Receiver
|
||||
try
|
||||
{
|
||||
/* Set the local node as already asked */
|
||||
nodes.put(this.localNode, ASKED);
|
||||
nodes.put(this.localNode.getNode(), ASKED);
|
||||
|
||||
this.addNodes(this.localNode.getRoutingTable().getAllNodes());
|
||||
|
||||
|
@ -2,6 +2,7 @@ package kademlia.operation;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
import kademlia.KademliaNode;
|
||||
import kademlia.core.KadConfiguration;
|
||||
import kademlia.core.KadServer;
|
||||
import kademlia.dht.DHT;
|
||||
@ -21,11 +22,11 @@ public class ContentRefreshOperation implements Operation
|
||||
{
|
||||
|
||||
private final KadServer server;
|
||||
private final Node localNode;
|
||||
private final KademliaNode localNode;
|
||||
private final DHT dht;
|
||||
private final KadConfiguration config;
|
||||
|
||||
public ContentRefreshOperation(KadServer server, Node localNode, DHT dht, KadConfiguration config)
|
||||
public ContentRefreshOperation(KadServer server, KademliaNode localNode, DHT dht, KadConfiguration config)
|
||||
{
|
||||
this.server = server;
|
||||
this.localNode = localNode;
|
||||
@ -66,7 +67,7 @@ public class ContentRefreshOperation implements Operation
|
||||
List<Node> closestNodes = this.localNode.getRoutingTable().findClosest(e.getKey(), this.config.k());
|
||||
|
||||
/* Create the message */
|
||||
Message msg = new StoreContentMessage(this.localNode, dht.get(e));
|
||||
Message msg = new StoreContentMessage(this.localNode.getNode(), dht.get(e));
|
||||
|
||||
/*Store the message on all of the K-Nodes*/
|
||||
for (Node n : closestNodes)
|
||||
|
@ -1,10 +1,10 @@
|
||||
package kademlia.operation;
|
||||
|
||||
import java.io.IOException;
|
||||
import kademlia.KademliaNode;
|
||||
import kademlia.core.KadConfiguration;
|
||||
import kademlia.core.KadServer;
|
||||
import kademlia.dht.DHT;
|
||||
import kademlia.node.Node;
|
||||
|
||||
/**
|
||||
* An operation that handles refreshing the entire Kademlia Systems including buckets and content
|
||||
@ -16,11 +16,11 @@ public class KadRefreshOperation implements Operation
|
||||
{
|
||||
|
||||
private final KadServer server;
|
||||
private final Node localNode;
|
||||
private final KademliaNode localNode;
|
||||
private final DHT dht;
|
||||
private final KadConfiguration config;
|
||||
|
||||
public KadRefreshOperation(KadServer server, Node localNode, DHT dht, KadConfiguration config)
|
||||
public KadRefreshOperation(KadServer server, KademliaNode localNode, DHT dht, KadConfiguration config)
|
||||
{
|
||||
this.server = server;
|
||||
this.localNode = localNode;
|
||||
|
@ -8,6 +8,7 @@ import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.TreeMap;
|
||||
import kademlia.KademliaNode;
|
||||
import kademlia.core.KadConfiguration;
|
||||
import kademlia.core.KadServer;
|
||||
import kademlia.exceptions.RoutingException;
|
||||
@ -35,14 +36,14 @@ public class NodeLookupOperation implements Operation, Receiver
|
||||
private static final String AWAITING = "Awaiting";
|
||||
private static final String ASKED = "Asked";
|
||||
private static final String FAILED = "Failed";
|
||||
|
||||
|
||||
private final KadServer server;
|
||||
private final Node localNode;
|
||||
private final KademliaNode localNode;
|
||||
private final NodeId lookupId;
|
||||
private final KadConfiguration config;
|
||||
|
||||
|
||||
private boolean error;
|
||||
|
||||
|
||||
private final Message lookupMessage; // Message sent to each peer
|
||||
private final Map<Node, String> nodes;
|
||||
|
||||
@ -51,7 +52,7 @@ public class NodeLookupOperation implements Operation, Receiver
|
||||
|
||||
/* Used to sort nodes */
|
||||
private final Comparator comparator;
|
||||
|
||||
|
||||
|
||||
{
|
||||
messagesTransiting = new HashMap<>();
|
||||
@ -63,14 +64,14 @@ public class NodeLookupOperation implements Operation, Receiver
|
||||
* @param lookupId The ID for which to find nodes close to
|
||||
* @param config
|
||||
*/
|
||||
public NodeLookupOperation(KadServer server, Node localNode, NodeId lookupId, KadConfiguration config)
|
||||
public NodeLookupOperation(KadServer server, KademliaNode localNode, NodeId lookupId, KadConfiguration config)
|
||||
{
|
||||
this.server = server;
|
||||
this.localNode = localNode;
|
||||
this.lookupId = lookupId;
|
||||
this.config = config;
|
||||
|
||||
this.lookupMessage = new NodeLookupMessage(localNode, lookupId);
|
||||
|
||||
this.lookupMessage = new NodeLookupMessage(localNode.getNode(), lookupId);
|
||||
|
||||
/**
|
||||
* We initialize a TreeMap to store nodes.
|
||||
@ -93,9 +94,9 @@ public class NodeLookupOperation implements Operation, Receiver
|
||||
error = true;
|
||||
|
||||
/* Set the local node as already asked */
|
||||
nodes.put(this.localNode, ASKED);
|
||||
|
||||
this.addNodes(this.localNode.getRoutingTable().getAllNodes());
|
||||
nodes.put(this.localNode.getNode(), ASKED);
|
||||
|
||||
this.addNodes(this.localNode.getRoutingTable().findClosest(this.lookupId, this.config.k()));
|
||||
|
||||
/* If we haven't finished as yet, wait for a maximum of config.operationTimeout() time */
|
||||
int totalTimeWaited = 0;
|
||||
@ -118,28 +119,16 @@ public class NodeLookupOperation implements Operation, Receiver
|
||||
throw new RoutingException("Lookup Timeout.");
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated - replaced by the above code
|
||||
* We just keep this code in case any problems are encountered later
|
||||
*/
|
||||
// if (!this.askNodesorFinish())
|
||||
// {
|
||||
// /* If we haven't finished as yet, wait for a maximum of OPERATION_TIMEOUT time */
|
||||
// wait(this.config.operationTimeout());
|
||||
//
|
||||
// /* If we still haven't received any responses by then, do a routing timeout */
|
||||
// if (error)
|
||||
// {
|
||||
// throw new RoutingException("Lookup Timeout.");
|
||||
// }
|
||||
// }
|
||||
/* Now after we've finished, we would have an idea of offline nodes, lets update our routing table */
|
||||
this.localNode.getRoutingTable().setUnresponsiveContacts(this.getFailedNodes());
|
||||
|
||||
}
|
||||
catch (InterruptedException e)
|
||||
{
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public List<Node> getClosestNodes()
|
||||
{
|
||||
return this.closestNodes(ASKED);
|
||||
@ -183,7 +172,7 @@ public class NodeLookupOperation implements Operation, Receiver
|
||||
|
||||
/* Get unqueried nodes among the K closest seen that have not FAILED */
|
||||
List<Node> unasked = this.closestNodesNotFailed(UNASKED);
|
||||
|
||||
|
||||
if (unasked.isEmpty() && this.messagesTransiting.isEmpty())
|
||||
{
|
||||
/* We have no unasked nodes nor any messages in transit, we're finished! */
|
||||
@ -198,9 +187,9 @@ public class NodeLookupOperation implements Operation, Receiver
|
||||
for (int i = 0; (this.messagesTransiting.size() < this.config.maxConcurrentMessagesTransiting()) && (i < unasked.size()); i++)
|
||||
{
|
||||
Node n = (Node) unasked.get(i);
|
||||
|
||||
|
||||
int comm = server.sendMessage(n, lookupMessage, this);
|
||||
|
||||
|
||||
this.nodes.put(n, AWAITING);
|
||||
this.messagesTransiting.put(comm, n);
|
||||
}
|
||||
@ -218,7 +207,7 @@ public class NodeLookupOperation implements Operation, Receiver
|
||||
{
|
||||
List<Node> closestNodes = new ArrayList<>(this.config.k());
|
||||
int remainingSpaces = this.config.k();
|
||||
|
||||
|
||||
for (Map.Entry e : this.nodes.entrySet())
|
||||
{
|
||||
if (status.equals(e.getValue()))
|
||||
@ -231,7 +220,7 @@ public class NodeLookupOperation implements Operation, Receiver
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return closestNodes;
|
||||
}
|
||||
|
||||
@ -247,7 +236,7 @@ public class NodeLookupOperation implements Operation, Receiver
|
||||
{
|
||||
List<Node> closestNodes = new ArrayList<>(this.config.k());
|
||||
int remainingSpaces = this.config.k();
|
||||
|
||||
|
||||
for (Map.Entry<Node, String> e : this.nodes.entrySet())
|
||||
{
|
||||
if (!FAILED.equals(e.getValue()))
|
||||
@ -257,14 +246,14 @@ public class NodeLookupOperation implements Operation, Receiver
|
||||
/* We got one with the required status, now add it */
|
||||
closestNodes.add(e.getKey());
|
||||
}
|
||||
|
||||
|
||||
if (--remainingSpaces == 0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return closestNodes;
|
||||
}
|
||||
|
||||
@ -308,7 +297,7 @@ public class NodeLookupOperation implements Operation, Receiver
|
||||
{
|
||||
/* Get the node associated with this communication */
|
||||
Node n = this.messagesTransiting.get(new Integer(comm));
|
||||
|
||||
|
||||
if (n == null)
|
||||
{
|
||||
throw new UnknownMessageException("Unknown comm: " + comm);
|
||||
@ -318,7 +307,22 @@ public class NodeLookupOperation implements Operation, Receiver
|
||||
this.nodes.put(n, FAILED);
|
||||
this.localNode.getRoutingTable().remove(n);
|
||||
this.messagesTransiting.remove(comm);
|
||||
|
||||
|
||||
this.askNodesorFinish();
|
||||
}
|
||||
|
||||
public List<Node> getFailedNodes()
|
||||
{
|
||||
List<Node> failedNodes = new ArrayList<>();
|
||||
|
||||
for (Map.Entry<Node, String> e : this.nodes.entrySet())
|
||||
{
|
||||
if (e.getValue().equals(FAILED))
|
||||
{
|
||||
failedNodes.add(e.getKey());
|
||||
}
|
||||
}
|
||||
|
||||
return failedNodes;
|
||||
}
|
||||
}
|
||||
|
@ -2,6 +2,7 @@ package kademlia.operation;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
import kademlia.KademliaNode;
|
||||
import kademlia.core.KadConfiguration;
|
||||
import kademlia.core.KadServer;
|
||||
import kademlia.dht.DHT;
|
||||
@ -21,7 +22,7 @@ public class StoreOperation implements Operation
|
||||
{
|
||||
|
||||
private final KadServer server;
|
||||
private final Node localNode;
|
||||
private final KademliaNode localNode;
|
||||
private final KadContent content;
|
||||
private final DHT localDht;
|
||||
private final KadConfiguration config;
|
||||
@ -33,7 +34,7 @@ public class StoreOperation implements Operation
|
||||
* @param localDht The local DHT
|
||||
* @param config
|
||||
*/
|
||||
public StoreOperation(KadServer server, Node localNode, KadContent content, DHT localDht, KadConfiguration config)
|
||||
public StoreOperation(KadServer server, KademliaNode localNode, KadContent content, DHT localDht, KadConfiguration config)
|
||||
{
|
||||
this.server = server;
|
||||
this.localNode = localNode;
|
||||
@ -51,7 +52,7 @@ public class StoreOperation implements Operation
|
||||
List<Node> nodes = ndlo.getClosestNodes();
|
||||
|
||||
/* Create the message */
|
||||
Message msg = new StoreContentMessage(this.localNode, new StorageEntry(this.content));
|
||||
Message msg = new StoreContentMessage(this.localNode.getNode(), new StorageEntry(this.content));
|
||||
|
||||
/*Store the message on all of the K-Nodes*/
|
||||
for (Node n : nodes)
|
||||
|
@ -15,12 +15,19 @@ import kademlia.node.Node;
|
||||
public class KadBucket implements Bucket
|
||||
{
|
||||
|
||||
/* How deep is this bucket in the Routing Table */
|
||||
private final int depth;
|
||||
|
||||
/* Contacts stored in this routing table */
|
||||
private final Map<Contact, Contact> contacts;
|
||||
|
||||
/* A set of last seen contacts that can replace any current contact that is unresponsive */
|
||||
private final Map<Contact, Contact> replacementCache;
|
||||
|
||||
|
||||
{
|
||||
contacts = new TreeMap<>(new ContactLastSeenComparator());
|
||||
replacementCache = new TreeMap<>(new ContactLastSeenComparator());
|
||||
}
|
||||
|
||||
/**
|
||||
@ -94,9 +101,9 @@ public class KadBucket implements Bucket
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Contact> getContacts()
|
||||
public synchronized List<Contact> getContacts()
|
||||
{
|
||||
return new ArrayList<>(this.contacts.values());
|
||||
return (this.contacts.isEmpty()) ? new ArrayList<>() : new ArrayList<>(this.contacts.values());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -2,6 +2,7 @@ package kademlia.routing;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import kademlia.core.KadConfiguration;
|
||||
import kademlia.node.Node;
|
||||
import kademlia.node.NodeId;
|
||||
|
||||
@ -17,9 +18,12 @@ public class RoutingTable
|
||||
private final Node localNode; // The current node
|
||||
private transient Bucket[] buckets;
|
||||
|
||||
public RoutingTable(Node localNode)
|
||||
private final KadConfiguration config;
|
||||
|
||||
public RoutingTable(Node localNode, KadConfiguration config)
|
||||
{
|
||||
this.localNode = localNode;
|
||||
this.config = config;
|
||||
|
||||
/* Initialize all of the buckets to a specific depth */
|
||||
this.initialize();
|
||||
@ -99,7 +103,7 @@ public class RoutingTable
|
||||
*
|
||||
* @return List A List of contacts closest to target
|
||||
*/
|
||||
public final List<Node> findClosest(NodeId target, int numNodesRequired)
|
||||
public synchronized final List<Node> findClosest(NodeId target, int numNodesRequired)
|
||||
{
|
||||
List<Node> closest = new ArrayList<>(numNodesRequired);
|
||||
|
||||
@ -232,14 +236,35 @@ public class RoutingTable
|
||||
this.buckets = buckets;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method used by operations to notify the routing table of any contacts that have been unresponsive.
|
||||
*
|
||||
* @param contacts The set of unresponsive contacts
|
||||
*/
|
||||
public void setUnresponsiveContacts(List<Node> contacts)
|
||||
{
|
||||
if (contacts.isEmpty())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
System.out.println("Unresponsive contacts: ");
|
||||
for (Node n : contacts)
|
||||
{
|
||||
System.out.println(n);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public final String toString()
|
||||
public synchronized final String toString()
|
||||
{
|
||||
StringBuilder sb = new StringBuilder("\nPrinting Routing Table Started ***************** \n");
|
||||
int totalContacts = 0;
|
||||
for (Bucket b : this.buckets)
|
||||
{
|
||||
if (b.numContacts() > 0)
|
||||
{
|
||||
totalContacts += b.numContacts();
|
||||
sb.append("# nodes in Bucket with depth ");
|
||||
sb.append(b.getDepth());
|
||||
sb.append(": ");
|
||||
@ -249,6 +274,11 @@ public class RoutingTable
|
||||
sb.append("\n");
|
||||
}
|
||||
}
|
||||
|
||||
sb.append("\nTotal Contacts: ");
|
||||
sb.append(totalContacts);
|
||||
sb.append("\n\n");
|
||||
|
||||
sb.append("Printing Routing Table Ended ******************** ");
|
||||
|
||||
return sb.toString();
|
||||
|
@ -3,7 +3,7 @@ package kademlia.tests;
|
||||
import java.util.Timer;
|
||||
import java.util.TimerTask;
|
||||
import kademlia.core.DefaultConfiguration;
|
||||
import kademlia.Kademlia;
|
||||
import kademlia.KademliaNode;
|
||||
import kademlia.core.KadConfiguration;
|
||||
import kademlia.node.NodeId;
|
||||
|
||||
@ -21,11 +21,11 @@ public class AutoRefreshOperationTest
|
||||
try
|
||||
{
|
||||
/* Setting up 2 Kad networks */
|
||||
final Kademlia kad1 = new Kademlia("JoshuaK", new NodeId("ASF456789djem45674DH"), 12049);
|
||||
final Kademlia kad2 = new Kademlia("Crystal", new NodeId("AJDHR678947584567464"), 4585);
|
||||
final Kademlia kad3 = new Kademlia("Shameer", new NodeId("AS84k6789KRNS45KFJ8W"), 8104);
|
||||
final Kademlia kad4 = new Kademlia("Lokesh.", new NodeId("ASF45678947A845674GG"), 8335);
|
||||
final Kademlia kad5 = new Kademlia("Chandu.", new NodeId("AS84kUD894758456dyrj"), 13345);
|
||||
final KademliaNode kad1 = new KademliaNode("JoshuaK", new NodeId("ASF456789djem45674DH"), 12049);
|
||||
final KademliaNode kad2 = new KademliaNode("Crystal", new NodeId("AJDHR678947584567464"), 4585);
|
||||
final KademliaNode kad3 = new KademliaNode("Shameer", new NodeId("AS84k6789KRNS45KFJ8W"), 8104);
|
||||
final KademliaNode kad4 = new KademliaNode("Lokesh.", new NodeId("ASF45678947A845674GG"), 8335);
|
||||
final KademliaNode kad5 = new KademliaNode("Chandu.", new NodeId("AS84kUD894758456dyrj"), 13345);
|
||||
|
||||
/* Connecting nodes */
|
||||
System.out.println("Connecting Nodes");
|
||||
|
@ -3,7 +3,7 @@ package kademlia.tests;
|
||||
import java.util.Timer;
|
||||
import java.util.TimerTask;
|
||||
import kademlia.core.DefaultConfiguration;
|
||||
import kademlia.Kademlia;
|
||||
import kademlia.KademliaNode;
|
||||
import kademlia.core.KadConfiguration;
|
||||
import kademlia.node.NodeId;
|
||||
|
||||
@ -21,9 +21,9 @@ public class AutoRefreshOperationTest2
|
||||
try
|
||||
{
|
||||
/* Setting up 2 Kad networks */
|
||||
final Kademlia kad1 = new Kademlia("JoshuaK", new NodeId("ASF456789djem4567463"), 12049);
|
||||
final Kademlia kad2 = new Kademlia("Crystal", new NodeId("AS84k678DJRW84567465"), 4585);
|
||||
final Kademlia kad3 = new Kademlia("Shameer", new NodeId("AS84k67894758456746A"), 8104);
|
||||
final KademliaNode kad1 = new KademliaNode("JoshuaK", new NodeId("ASF456789djem4567463"), 12049);
|
||||
final KademliaNode kad2 = new KademliaNode("Crystal", new NodeId("AS84k678DJRW84567465"), 4585);
|
||||
final KademliaNode kad3 = new KademliaNode("Shameer", new NodeId("AS84k67894758456746A"), 8104);
|
||||
|
||||
/* Connecting nodes */
|
||||
System.out.println("Connecting Nodes");
|
||||
|
@ -2,7 +2,7 @@ package kademlia.tests;
|
||||
|
||||
import java.io.IOException;
|
||||
import kademlia.dht.GetParameter;
|
||||
import kademlia.Kademlia;
|
||||
import kademlia.KademliaNode;
|
||||
import kademlia.dht.StorageEntry;
|
||||
import kademlia.exceptions.ContentNotFoundException;
|
||||
import kademlia.node.NodeId;
|
||||
@ -21,9 +21,9 @@ public class ContentSendingTest
|
||||
try
|
||||
{
|
||||
/* Setting up 2 Kad networks */
|
||||
Kademlia kad1 = new Kademlia("JoshuaK", new NodeId("ASF45678947584567467"), 7574);
|
||||
KademliaNode kad1 = new KademliaNode("JoshuaK", new NodeId("ASF45678947584567467"), 7574);
|
||||
System.out.println("Created Node Kad 1: " + kad1.getNode().getNodeId());
|
||||
Kademlia kad2 = new Kademlia("Crystal", new NodeId("ASERTKJDHGVHERJHGFLK"), 7572);
|
||||
KademliaNode kad2 = new KademliaNode("Crystal", new NodeId("ASERTKJDHGVHERJHGFLK"), 7572);
|
||||
System.out.println("Created Node Kad 2: " + kad2.getNode().getNodeId());
|
||||
kad2.bootstrap(kad1.getNode());
|
||||
|
||||
|
@ -2,7 +2,7 @@ package kademlia.tests;
|
||||
|
||||
import java.io.IOException;
|
||||
import kademlia.dht.GetParameter;
|
||||
import kademlia.Kademlia;
|
||||
import kademlia.KademliaNode;
|
||||
import kademlia.dht.StorageEntry;
|
||||
import kademlia.exceptions.ContentNotFoundException;
|
||||
import kademlia.node.NodeId;
|
||||
@ -21,9 +21,9 @@ public class ContentUpdatingTest
|
||||
try
|
||||
{
|
||||
/* Setting up 2 Kad networks */
|
||||
Kademlia kad1 = new Kademlia("JoshuaK", new NodeId("ASF45678947584567467"), 7574);
|
||||
KademliaNode kad1 = new KademliaNode("JoshuaK", new NodeId("ASF45678947584567467"), 7574);
|
||||
System.out.println("Created Node Kad 1: " + kad1.getNode().getNodeId());
|
||||
Kademlia kad2 = new Kademlia("Crystal", new NodeId("ASERTKJDHGVHERJHGFLK"), 7572);
|
||||
KademliaNode kad2 = new KademliaNode("Crystal", new NodeId("ASERTKJDHGVHERJHGFLK"), 7572);
|
||||
System.out.println("Created Node Kad 2: " + kad2.getNode().getNodeId());
|
||||
kad2.bootstrap(kad1.getNode());
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
package kademlia.tests;
|
||||
|
||||
import java.io.IOException;
|
||||
import kademlia.Kademlia;
|
||||
import kademlia.KademliaNode;
|
||||
import kademlia.node.NodeId;
|
||||
|
||||
/**
|
||||
@ -18,10 +18,10 @@ public class NodeConnectionTest
|
||||
try
|
||||
{
|
||||
/* Setting up 2 Kad networks */
|
||||
Kademlia kad1 = new Kademlia("JoshuaK", new NodeId("ASF45678947584567467"), 7574);
|
||||
KademliaNode kad1 = new KademliaNode("JoshuaK", new NodeId("ASF45678947584567467"), 7574);
|
||||
System.out.println("Created Node Kad 1: " + kad1.getNode().getNodeId());
|
||||
|
||||
Kademlia kad2 = new Kademlia("Crystal", new NodeId("ASERTKJDHGVHERJHGFLK"), 7572);
|
||||
KademliaNode kad2 = new KademliaNode("Crystal", new NodeId("ASERTKJDHGVHERJHGFLK"), 7572);
|
||||
//NodeId diff12 = kad1.getNode().getNodeId().xor(kad2.getNode().getNodeId());
|
||||
System.out.println("Created Node Kad 2: " + kad2.getNode().getNodeId());
|
||||
// System.out.println(kad1.getNode().getNodeId() + " ^ " + kad2.getNode().getNodeId() + " = " + diff12);
|
||||
@ -37,7 +37,7 @@ public class NodeConnectionTest
|
||||
// System.out.println(kad2.getNode().getRoutingTable());
|
||||
|
||||
/* Creating a new node 3 and connecting it to 1, hoping it'll get onto 2 also */
|
||||
Kademlia kad3 = new Kademlia("Jessica", new NodeId("ASERTKJDOLKMNBVFR45G"), 7783);
|
||||
KademliaNode kad3 = new KademliaNode("Jessica", new NodeId("ASERTKJDOLKMNBVFR45G"), 7783);
|
||||
System.out.println("\n\n\n\n\n\nCreated Node Kad 3: " + kad3.getNode().getNodeId());
|
||||
|
||||
System.out.println("Connecting Kad 3 and Kad 2");
|
||||
@ -47,20 +47,20 @@ public class NodeConnectionTest
|
||||
// NodeId diff31 = kad1.getNode().getNodeId().xor(kad3.getNode().getNodeId());
|
||||
// System.out.println("Kad 3 - Kad 1 distance: " + diff31.getFirstSetBitIndex());
|
||||
// System.out.println("Kad 3 - Kad 2 distance: " + diff32.getFirstSetBitIndex());
|
||||
Kademlia kad4 = new Kademlia("Sandy", new NodeId("ASERTK85OLKMN85FR4SS"), 7789);
|
||||
KademliaNode kad4 = new KademliaNode("Sandy", new NodeId("ASERTK85OLKMN85FR4SS"), 7789);
|
||||
System.out.println("\n\n\n\n\n\nCreated Node Kad 4: " + kad4.getNode().getNodeId());
|
||||
|
||||
System.out.println("Connecting Kad 4 and Kad 2");
|
||||
kad4.bootstrap(kad2.getNode());
|
||||
|
||||
System.out.println("\n\nKad 1: " + kad1.getNode().getNodeId() + " Routing Table: ");
|
||||
System.out.println(kad1.getNode().getRoutingTable());
|
||||
System.out.println(kad1.getRoutingTable());
|
||||
System.out.println("\n\nKad 2: " + kad2.getNode().getNodeId() + " Routing Table: ");
|
||||
System.out.println(kad2.getNode().getRoutingTable());
|
||||
System.out.println(kad2.getRoutingTable());
|
||||
System.out.println("\n\nKad 3: " + kad3.getNode().getNodeId() + " Routing Table: ");
|
||||
System.out.println(kad3.getNode().getRoutingTable());
|
||||
System.out.println(kad3.getRoutingTable());
|
||||
System.out.println("\n\nKad 4: " + kad4.getNode().getNodeId() + " Routing Table: ");
|
||||
System.out.println(kad4.getNode().getRoutingTable());
|
||||
System.out.println(kad4.getRoutingTable());
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
|
@ -2,7 +2,7 @@ package kademlia.tests;
|
||||
|
||||
import java.io.IOException;
|
||||
import kademlia.dht.GetParameter;
|
||||
import kademlia.Kademlia;
|
||||
import kademlia.KademliaNode;
|
||||
import kademlia.dht.StorageEntry;
|
||||
import kademlia.exceptions.ContentNotFoundException;
|
||||
import kademlia.node.NodeId;
|
||||
@ -21,8 +21,8 @@ public class RefreshOperationTest
|
||||
try
|
||||
{
|
||||
/* Setting up 2 Kad networks */
|
||||
Kademlia kad1 = new Kademlia("JoshuaK", new NodeId("ASF45678947584567467"), 7574);
|
||||
Kademlia kad2 = new Kademlia("Crystal", new NodeId("ASERTKJDHGVHERJHGFLK"), 7572);
|
||||
KademliaNode kad1 = new KademliaNode("JoshuaK", new NodeId("ASF45678947584567467"), 7574);
|
||||
KademliaNode kad2 = new KademliaNode("Crystal", new NodeId("ASERTKJDHGVHERJHGFLK"), 7572);
|
||||
kad2.bootstrap(kad1.getNode());
|
||||
|
||||
/* Lets create the content and share it */
|
||||
|
@ -1,6 +1,6 @@
|
||||
package kademlia.tests;
|
||||
|
||||
import kademlia.Kademlia;
|
||||
import kademlia.KademliaNode;
|
||||
import kademlia.node.NodeId;
|
||||
import kademlia.routing.RoutingTable;
|
||||
|
||||
@ -18,13 +18,13 @@ public class RoutingTableSimulation
|
||||
try
|
||||
{
|
||||
/* Setting up 2 Kad networks */
|
||||
Kademlia kad1 = new Kademlia("JoshuaK", new NodeId("ASF45678947584567463"), 12049);
|
||||
Kademlia kad2 = new Kademlia("Crystal", new NodeId("ASF45678947584567464"), 4585);
|
||||
Kademlia kad3 = new Kademlia("Shameer", new NodeId("ASF45678947584567465"), 8104);
|
||||
Kademlia kad4 = new Kademlia("Lokesh", new NodeId("ASF45678947584567466"), 8335);
|
||||
Kademlia kad5 = new Kademlia("Chandu", new NodeId("ASF45678947584567467"), 13345);
|
||||
KademliaNode kad1 = new KademliaNode("JoshuaK", new NodeId("ASF45678947584567463"), 12049);
|
||||
KademliaNode kad2 = new KademliaNode("Crystal", new NodeId("ASF45678947584567464"), 4585);
|
||||
KademliaNode kad3 = new KademliaNode("Shameer", new NodeId("ASF45678947584567465"), 8104);
|
||||
KademliaNode kad4 = new KademliaNode("Lokesh", new NodeId("ASF45678947584567466"), 8335);
|
||||
KademliaNode kad5 = new KademliaNode("Chandu", new NodeId("ASF45678947584567467"), 13345);
|
||||
|
||||
RoutingTable rt = kad1.getNode().getRoutingTable();
|
||||
RoutingTable rt = kad1.getRoutingTable();
|
||||
|
||||
rt.insert(kad2.getNode());
|
||||
rt.insert(kad3.getNode());
|
||||
@ -36,6 +36,9 @@ public class RoutingTableSimulation
|
||||
|
||||
rt.insert(kad3.getNode());
|
||||
System.out.println(rt);
|
||||
|
||||
|
||||
/* Lets shut down a node and then try putting a content on the network. We'll then see how the un-responsive contacts work */
|
||||
}
|
||||
catch (IllegalStateException e)
|
||||
{
|
||||
|
125
src/kademlia/tests/RoutingTableStateTesting.java
Normal file
125
src/kademlia/tests/RoutingTableStateTesting.java
Normal file
@ -0,0 +1,125 @@
|
||||
package kademlia.tests;
|
||||
|
||||
import java.io.IOException;
|
||||
import kademlia.KademliaNode;
|
||||
import kademlia.dht.KadContent;
|
||||
import kademlia.node.NodeId;
|
||||
|
||||
/**
|
||||
* Testing how the routing table works and it's state after different operations
|
||||
*
|
||||
* @author Joshua Kissoon
|
||||
* @since 20140426
|
||||
*/
|
||||
public class RoutingTableStateTesting
|
||||
{
|
||||
|
||||
KademliaNode kad0, kad1, kad2, kad3, kad4, kad5, kad6, kad7, kad8, kad9;
|
||||
|
||||
public RoutingTableStateTesting()
|
||||
{
|
||||
try
|
||||
{
|
||||
/* Setting up 2 Kad networks */
|
||||
kad0 = new KademliaNode("user0", new NodeId("HRF456789SD584567460"), 1334);
|
||||
kad1 = new KademliaNode("user1", new NodeId("ASF456789475DS567461"), 1209);
|
||||
kad2 = new KademliaNode("user2", new NodeId("AFG45678947584567462"), 4585);
|
||||
kad3 = new KademliaNode("user3", new NodeId("FSF45J38947584567463"), 8104);
|
||||
kad4 = new KademliaNode("user4", new NodeId("ASF45678947584567464"), 8335);
|
||||
kad5 = new KademliaNode("user5", new NodeId("GHF4567894DR84567465"), 13345);
|
||||
kad6 = new KademliaNode("user6", new NodeId("ASF45678947584567466"), 12049);
|
||||
kad7 = new KademliaNode("user7", new NodeId("AE345678947584567467"), 14585);
|
||||
kad8 = new KademliaNode("user8", new NodeId("ASAA5678947584567468"), 18104);
|
||||
kad9 = new KademliaNode("user9", new NodeId("ASF456789475845674U9"), 18335);
|
||||
|
||||
kad1.bootstrap(kad0.getNode());
|
||||
kad2.bootstrap(kad0.getNode());
|
||||
kad3.bootstrap(kad0.getNode());
|
||||
kad4.bootstrap(kad0.getNode());
|
||||
kad5.bootstrap(kad0.getNode());
|
||||
kad6.bootstrap(kad0.getNode());
|
||||
kad7.bootstrap(kad0.getNode());
|
||||
kad8.bootstrap(kad0.getNode());
|
||||
kad9.bootstrap(kad0.getNode());
|
||||
|
||||
/* Lets shut down a node and then try putting a content on the network. We'll then see how the un-responsive contacts work */
|
||||
}
|
||||
catch (IllegalStateException e)
|
||||
{
|
||||
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
public KadContent putContent(String content, KademliaNode owner)
|
||||
{
|
||||
DHTContentImpl c = null;
|
||||
try
|
||||
{
|
||||
c = new DHTContentImpl(kad2.getOwnerId(), "Some Data");
|
||||
owner.put(c);
|
||||
return c;
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
System.err.println("Error whiles putting content " + content + " from owner: " + owner.getOwnerId());
|
||||
}
|
||||
|
||||
return c;
|
||||
}
|
||||
|
||||
public void shutdownKad(KademliaNode kad)
|
||||
{
|
||||
try
|
||||
{
|
||||
kad.shutdown(false);
|
||||
}
|
||||
catch (IOException ex)
|
||||
{
|
||||
System.err.println("Error whiles shutting down node with owner: " + kad.getOwnerId());
|
||||
}
|
||||
}
|
||||
|
||||
public void printRoutingTables()
|
||||
{
|
||||
System.out.println(kad0.getRoutingTable());
|
||||
System.out.println(kad1.getRoutingTable());
|
||||
System.out.println(kad2.getRoutingTable());
|
||||
System.out.println(kad3.getRoutingTable());
|
||||
System.out.println(kad4.getRoutingTable());
|
||||
System.out.println(kad5.getRoutingTable());
|
||||
System.out.println(kad6.getRoutingTable());
|
||||
System.out.println(kad7.getRoutingTable());
|
||||
System.out.println(kad8.getRoutingTable());
|
||||
System.out.println(kad9.getRoutingTable());
|
||||
}
|
||||
|
||||
public void printStorage()
|
||||
{
|
||||
System.out.println(kad0.getDHT());
|
||||
System.out.println(kad1.getDHT());
|
||||
System.out.println(kad2.getDHT());
|
||||
System.out.println(kad3.getDHT());
|
||||
System.out.println(kad4.getDHT());
|
||||
System.out.println(kad5.getDHT());
|
||||
System.out.println(kad6.getDHT());
|
||||
System.out.println(kad7.getDHT());
|
||||
System.out.println(kad8.getDHT());
|
||||
System.out.println(kad9.getDHT());
|
||||
}
|
||||
|
||||
public static void main(String[] args)
|
||||
{
|
||||
RoutingTableStateTesting rtss = new RoutingTableStateTesting();
|
||||
rtss.printRoutingTables();
|
||||
|
||||
/* Lets shut down a node to test the node removal operation */
|
||||
rtss.shutdownKad(rtss.kad3);
|
||||
|
||||
rtss.putContent("Content owned by kad0", rtss.kad0);
|
||||
rtss.printStorage();
|
||||
}
|
||||
}
|
@ -1,6 +1,6 @@
|
||||
package kademlia.tests;
|
||||
|
||||
import kademlia.Kademlia;
|
||||
import kademlia.KademliaNode;
|
||||
import kademlia.node.NodeId;
|
||||
|
||||
/**
|
||||
@ -17,11 +17,11 @@ public class SaveStateTest
|
||||
try
|
||||
{
|
||||
/* Setting up 2 Kad networks */
|
||||
Kademlia kad1 = new Kademlia("JoshuaK", new NodeId("ASF45678947584567463"), 12049);
|
||||
Kademlia kad2 = new Kademlia("Crystal", new NodeId("ASF45678947584567464"), 4585);
|
||||
Kademlia kad3 = new Kademlia("Shameer", new NodeId("ASF45678947584567465"), 8104);
|
||||
Kademlia kad4 = new Kademlia("Lokesh", new NodeId("ASF45678947584567466"), 8335);
|
||||
Kademlia kad5 = new Kademlia("Chandu", new NodeId("ASF45678947584567467"), 13345);
|
||||
KademliaNode kad1 = new KademliaNode("JoshuaK", new NodeId("ASF45678947584567463"), 12049);
|
||||
KademliaNode kad2 = new KademliaNode("Crystal", new NodeId("ASF45678947584567464"), 4585);
|
||||
KademliaNode kad3 = new KademliaNode("Shameer", new NodeId("ASF45678947584567465"), 8104);
|
||||
KademliaNode kad4 = new KademliaNode("Lokesh", new NodeId("ASF45678947584567466"), 8335);
|
||||
KademliaNode kad5 = new KademliaNode("Chandu", new NodeId("ASF45678947584567467"), 13345);
|
||||
|
||||
/* Connecting 2 to 1 */
|
||||
System.out.println("Connecting Nodes 1 & 2");
|
||||
@ -76,7 +76,7 @@ public class SaveStateTest
|
||||
kad1.shutdown(true);
|
||||
|
||||
System.out.println("\n\n\nReloading Kad instance from file");
|
||||
Kademlia kadR2 = Kademlia.loadFromFile("JoshuaK");
|
||||
KademliaNode kadR2 = KademliaNode.loadFromFile("JoshuaK");
|
||||
System.out.println(kadR2);
|
||||
}
|
||||
catch (IllegalStateException e)
|
||||
|
@ -1,6 +1,6 @@
|
||||
package kademlia.tests;
|
||||
|
||||
import kademlia.Kademlia;
|
||||
import kademlia.KademliaNode;
|
||||
import kademlia.dht.GetParameter;
|
||||
import kademlia.dht.StorageEntry;
|
||||
import kademlia.node.NodeId;
|
||||
@ -20,8 +20,8 @@ public class SaveStateTest2
|
||||
try
|
||||
{
|
||||
/* Setting up 2 Kad networks */
|
||||
Kademlia kad1 = new Kademlia("JoshuaK", new NodeId("ASF45678947584567463"), 12049);
|
||||
Kademlia kad2 = new Kademlia("Crystal", new NodeId("ASF45678947584567464"), 4585);
|
||||
KademliaNode kad1 = new KademliaNode("JoshuaK", new NodeId("ASF45678947584567463"), 12049);
|
||||
KademliaNode kad2 = new KademliaNode("Crystal", new NodeId("ASF45678947584567464"), 4585);
|
||||
|
||||
/* Connecting 2 to 1 */
|
||||
System.out.println("Connecting Nodes 1 & 2");
|
||||
@ -46,7 +46,7 @@ public class SaveStateTest2
|
||||
kad1.shutdown(true);
|
||||
|
||||
System.out.println("\n\n\nReloading Kad instance from file");
|
||||
kad1 = Kademlia.loadFromFile("JoshuaK");
|
||||
kad1 = KademliaNode.loadFromFile("JoshuaK");
|
||||
kad1.bootstrap(kad2.getNode());
|
||||
System.out.println(kad2);
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
package kademlia.tests;
|
||||
|
||||
import java.io.IOException;
|
||||
import kademlia.Kademlia;
|
||||
import kademlia.KademliaNode;
|
||||
import kademlia.message.SimpleMessage;
|
||||
import kademlia.node.NodeId;
|
||||
import kademlia.message.SimpleReceiver;
|
||||
@ -19,8 +19,8 @@ public class SimpleMessageTest
|
||||
{
|
||||
try
|
||||
{
|
||||
Kademlia kad1 = new Kademlia("Joshua", new NodeId("12345678901234567890"), 7574);
|
||||
Kademlia kad2 = new Kademlia("Crystal", new NodeId("12345678901234567891"), 7572);
|
||||
KademliaNode kad1 = new KademliaNode("Joshua", new NodeId("12345678901234567890"), 7574);
|
||||
KademliaNode kad2 = new KademliaNode("Crystal", new NodeId("12345678901234567891"), 7572);
|
||||
|
||||
kad1.getServer().sendMessage(kad2.getNode(), new SimpleMessage("Some Message"), new SimpleReceiver());
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user