cancel()
- * method inherited from TimerTask
. In this case the caller is
- * responsible for removing the task from the tasks
map.
- * */
- class TimeoutTask extends TimerTask
- {
-
- private final int comm;
- private final Receiver recv;
-
- public TimeoutTask(int comm, Receiver recv)
- {
- this.comm = comm;
- this.recv = recv;
- }
-
- @Override
- public void run()
- {
- if (!KadServer.this.isRunning)
- {
- return;
- }
-
- try
- {
- unregister(comm);
- recv.timeout(comm);
- }
- catch (IOException e)
- {
- System.err.println("Cannot unregister a receiver. Message: " + e.getMessage());
- }
- }
- }
-
- public void printReceivers()
- {
- for (Integer r : this.receivers.keySet())
- {
- System.out.println("Receiver for comm: " + r + "; Receiver: " + this.receivers.get(r));
- }
- }
-
- public boolean isRunning()
- {
- return this.isRunning;
- }
-
-}
diff --git a/src/main/java/io/github/chronosx88/dhtBootstrap/kademlia/KadStatistician.java b/src/main/java/io/github/chronosx88/dhtBootstrap/kademlia/KadStatistician.java
deleted file mode 100644
index 50113e0..0000000
--- a/src/main/java/io/github/chronosx88/dhtBootstrap/kademlia/KadStatistician.java
+++ /dev/null
@@ -1,87 +0,0 @@
-package io.github.chronosx88.dhtBootstrap.kademlia;
-
-/**
- * Specification for class that keeps statistics for a Kademlia instance.
- *
- * These statistics are temporary and will be lost when Kad is shut down.
- *
- * @author Joshua Kissoon
- * @since 20140507
- */
-public interface KadStatistician
-{
-
- /**
- * Used to indicate some data is sent
- *
- * @param size The size of the data sent
- */
- public void sentData(long size);
-
- /**
- * @return The total data sent in KiloBytes
- */
- public long getTotalDataSent();
-
- /**
- * Used to indicate some data was received
- *
- * @param size The size of the data received
- */
- public void receivedData(long size);
-
- /**
- * @return The total data received in KiloBytes
- */
- public long getTotalDataReceived();
-
- /**
- * Sets the bootstrap time for this Kademlia Node
- *
- * @param time The bootstrap time in nanoseconds
- */
- public void setBootstrapTime(long time);
-
- /**
- * @return How long the system took to bootstrap in milliseconds
- */
- public long getBootstrapTime();
-
- /**
- * Add the timing for a new content lookup operation that took place
- *
- * @param time The time the content lookup took in nanoseconds
- * @param routeLength The length of the route it took to get the content
- * @param isSuccessful Whether the content lookup was successful or not
- */
- public void addContentLookup(long time, int routeLength, boolean isSuccessful);
-
- /**
- * @return The total number of content lookups performed.
- */
- public int numContentLookups();
-
- /**
- * @return How many content lookups have failed.
- */
- public int numFailedContentLookups();
-
- /**
- * @return The total time spent on content lookups.
- */
- public long totalContentLookupTime();
-
- /**
- * Compute the average time a content lookup took
- *
- * @return The average time in milliseconds
- */
- public double averageContentLookupTime();
-
- /**
- * Compute the average route length of content lookup operations.
- *
- * @return The average route length
- */
- public double averageContentLookupRouteLength();
-}
diff --git a/src/main/java/io/github/chronosx88/dhtBootstrap/kademlia/KademliaNode.java b/src/main/java/io/github/chronosx88/dhtBootstrap/kademlia/KademliaNode.java
deleted file mode 100644
index 0cbe61d..0000000
--- a/src/main/java/io/github/chronosx88/dhtBootstrap/kademlia/KademliaNode.java
+++ /dev/null
@@ -1,154 +0,0 @@
-package io.github.chronosx88.dhtBootstrap.kademlia;
-
-import java.io.IOException;
-import java.util.NoSuchElementException;
-import io.github.chronosx88.dhtBootstrap.kademlia.dht.GetParameter;
-import io.github.chronosx88.dhtBootstrap.kademlia.dht.JKademliaStorageEntry;
-import io.github.chronosx88.dhtBootstrap.kademlia.dht.KadContent;
-import io.github.chronosx88.dhtBootstrap.kademlia.dht.KademliaDHT;
-import io.github.chronosx88.dhtBootstrap.kademlia.exceptions.ContentNotFoundException;
-import io.github.chronosx88.dhtBootstrap.kademlia.exceptions.RoutingException;
-import io.github.chronosx88.dhtBootstrap.kademlia.node.Node;
-import io.github.chronosx88.dhtBootstrap.kademlia.routing.KademliaRoutingTable;
-
-/**
- * The main Kademlia Node on the network, this node manages everything for this local system.
- *
- * @author Joshua Kissoon
- * @since 20140523
- *
- */
-public interface KademliaNode
-{
-
- /**
- * Schedule the recurring refresh operation
- */
- public void startRefreshOperation();
-
- /**
- * Stop the recurring refresh operation
- */
- public void stopRefreshOperation();
-
- /**
- * @return Node The local node for this system
- */
- public Node getNode();
-
- /**
- * @return The KadServer used to send/receive messages
- */
- public KadServer getServer();
-
- /**
- * @return The DHT for this kad instance
- */
- public KademliaDHT getDHT();
-
- /**
- * @return The current KadConfiguration object being used
- */
- public KadConfiguration getCurrentConfiguration();
-
- /**
- * Connect to an existing peer-to-peer network.
- *
- * @param n The known node in the peer-to-peer network
- *
- * @throws RoutingException If the bootstrap node could not be contacted
- * @throws IOException If a network error occurred
- * @throws IllegalStateException If this object is closed
- * */
- public void bootstrap(Node n) throws IOException, RoutingException;
-
- /**
- * 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
- *
- * @return Integer How many nodes the content was stored on
- *
- * @throws IOException
- *
- */
- public int put(KadContent content) throws IOException;
-
- /**
- * 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 entry The StorageEntry with the content to put onto the DHT
- *
- * @return Integer How many nodes the content was stored on
- *
- * @throws IOException
- *
- */
- public int put(JKademliaStorageEntry entry) throws IOException;
-
- /**
- * Store a content on the local node's DHT
- *
- * @param content The content to put on the DHT
- *
- * @throws IOException
- */
- public void putLocally(KadContent content) throws IOException;
-
- /**
- * Get some content stored on the DHT
- *
- * @param param The parameters used to search for the content
- *
- * @return DHTContent The content
- *
- * @throws IOException
- * @throws ContentNotFoundException
- */
- public JKademliaStorageEntry get(GetParameter param) throws NoSuchElementException, IOException, ContentNotFoundException;
-
- /**
- * Allow the user of the System to call refresh even out of the normal Kad refresh timing
- *
- * @throws IOException
- */
- public void refresh() throws IOException;
-
- /**
- * @return String The ID of the owner of this local network
- */
- public String getOwnerId();
-
- /**
- * @return Integer The port on which this kad instance is running
- */
- public int getPort();
-
- /**
- * Here we handle properly shutting down the Kademlia instance
- *
- * @param saveState Whether to save the application state or not
- *
- * @throws java.io.FileNotFoundException
- */
- public void shutdown(final boolean saveState) throws IOException;
-
- /**
- * Saves the node state to a text file
- *
- * @throws java.io.FileNotFoundException
- */
- public void saveKadState() throws IOException;
-
- /**
- * @return The routing table for this node.
- */
- public KademliaRoutingTable getRoutingTable();
-
- /**
- * @return The statistician that manages all statistics
- */
- public KadStatistician getStatistician();
-}
diff --git a/src/main/java/io/github/chronosx88/dhtBootstrap/kademlia/Statistician.java b/src/main/java/io/github/chronosx88/dhtBootstrap/kademlia/Statistician.java
deleted file mode 100644
index 25cd9ac..0000000
--- a/src/main/java/io/github/chronosx88/dhtBootstrap/kademlia/Statistician.java
+++ /dev/null
@@ -1,182 +0,0 @@
-package io.github.chronosx88.dhtBootstrap.kademlia;
-
-import java.text.DecimalFormat;
-
-/**
- * Class that keeps statistics for this Kademlia instance.
- *
- * These statistics are temporary and will be lost when Kad is shut down.
- *
- * @author Joshua Kissoon
- * @since 20140505
- */
-public class Statistician implements KadStatistician
-{
-
- /* How much data was sent and received by the server over the network */
- private long totalDataSent, totalDataReceived;
- private long numDataSent, numDataReceived;
-
- /* Bootstrap timings */
- private long bootstrapTime;
-
- /* Content lookup operation timing & route length */
- private int numContentLookups, numFailedContentLookups;
- private long totalContentLookupTime;
- private long totalRouteLength;
-
-
- {
- this.totalDataSent = 0;
- this.totalDataReceived = 0;
- this.bootstrapTime = 0;
- this.numContentLookups = 0;
- this.totalContentLookupTime = 0;
- this.totalRouteLength = 0;
- }
-
- @Override
- public void sentData(long size)
- {
- this.totalDataSent += size;
- this.numDataSent++;
- }
-
- @Override
- public long getTotalDataSent()
- {
- if (this.totalDataSent == 0)
- {
- return 0L;
- }
-
- return this.totalDataSent / 1000L;
- }
-
- @Override
- public void receivedData(long size)
- {
- this.totalDataReceived += size;
- this.numDataReceived++;
- }
-
- @Override
- public long getTotalDataReceived()
- {
- if (this.totalDataReceived == 0)
- {
- return 0L;
- }
- return this.totalDataReceived / 1000L;
- }
-
- @Override
- public void setBootstrapTime(long time)
- {
- this.bootstrapTime = time;
- }
-
- @Override
- public long getBootstrapTime()
- {
- return this.bootstrapTime / 1000000L;
- }
-
- @Override
- public void addContentLookup(long time, int routeLength, boolean isSuccessful)
- {
- if (isSuccessful)
- {
- this.numContentLookups++;
- this.totalContentLookupTime += time;
- this.totalRouteLength += routeLength;
- }
- else
- {
- this.numFailedContentLookups++;
- }
- }
-
- @Override
- public int numContentLookups()
- {
- return this.numContentLookups;
- }
-
- @Override
- public int numFailedContentLookups()
- {
- return this.numFailedContentLookups;
- }
-
- @Override
- public long totalContentLookupTime()
- {
- return this.totalContentLookupTime;
- }
-
- @Override
- public double averageContentLookupTime()
- {
- if (this.numContentLookups == 0)
- {
- return 0D;
- }
-
- double avg = (double) ((double) this.totalContentLookupTime / (double) this.numContentLookups) / 1000000D;
- DecimalFormat df = new DecimalFormat("#.00");
- return new Double(df.format(avg));
- }
-
- @Override
- public double averageContentLookupRouteLength()
- {
- if (this.numContentLookups == 0)
- {
- return 0D;
- }
- double avg = (double) ((double) this.totalRouteLength / (double) this.numContentLookups);
- DecimalFormat df = new DecimalFormat("#.00");
- return new Double(df.format(avg));
- }
-
- @Override
- public String toString()
- {
- StringBuilder sb = new StringBuilder("Statistician: [");
-
- sb.append("Bootstrap Time: ");
- sb.append(this.getBootstrapTime());
- sb.append("; ");
-
- sb.append("Data Sent: ");
- sb.append("(");
- sb.append(this.numDataSent);
- sb.append(") ");
- sb.append(this.getTotalDataSent());
- sb.append(" bytes; ");
-
- sb.append("Data Received: ");
- sb.append("(");
- sb.append(this.numDataReceived);
- sb.append(") ");
- sb.append(this.getTotalDataReceived());
- sb.append(" bytes; ");
-
- sb.append("Num Content Lookups: ");
- sb.append(this.numContentLookups());
- sb.append("; ");
-
- sb.append("Avg Content Lookup Time: ");
- sb.append(this.averageContentLookupTime());
- sb.append("; ");
-
- sb.append("Avg Content Lookup Route Lth: ");
- sb.append(this.averageContentLookupRouteLength());
- sb.append("; ");
-
- sb.append("]");
-
- return sb.toString();
- }
-}
diff --git a/src/main/java/io/github/chronosx88/dhtBootstrap/kademlia/dht/DHT.java b/src/main/java/io/github/chronosx88/dhtBootstrap/kademlia/dht/DHT.java
deleted file mode 100644
index 3b34a4a..0000000
--- a/src/main/java/io/github/chronosx88/dhtBootstrap/kademlia/dht/DHT.java
+++ /dev/null
@@ -1,265 +0,0 @@
-package io.github.chronosx88.dhtBootstrap.kademlia.dht;
-
-import java.io.DataInputStream;
-import java.io.DataOutputStream;
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileNotFoundException;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.util.List;
-import java.util.NoSuchElementException;
-import io.github.chronosx88.dhtBootstrap.kademlia.KadConfiguration;
-import io.github.chronosx88.dhtBootstrap.kademlia.exceptions.ContentExistException;
-import io.github.chronosx88.dhtBootstrap.kademlia.exceptions.ContentNotFoundException;
-import io.github.chronosx88.dhtBootstrap.kademlia.node.KademliaId;
-import io.github.chronosx88.dhtBootstrap.kademlia.util.serializer.JsonSerializer;
-import io.github.chronosx88.dhtBootstrap.kademlia.util.serializer.KadSerializer;
-
-/**
- * The main Distributed Hash Table class that manages the entire DHT
- *
- * @author Joshua Kissoon
- * @since 20140226
- */
-public class DHT implements KademliaDHT
-{
-
- private transient StoredContentManager contentManager;
- private transient KadSerializerbyte
type there can
- * be at most 256 different message types.
- *
- * @return byte A unique code representing the message type
- * */
- public byte code();
-}
diff --git a/src/main/java/io/github/chronosx88/dhtBootstrap/kademlia/message/MessageFactory.java b/src/main/java/io/github/chronosx88/dhtBootstrap/kademlia/message/MessageFactory.java
deleted file mode 100644
index eb457fa..0000000
--- a/src/main/java/io/github/chronosx88/dhtBootstrap/kademlia/message/MessageFactory.java
+++ /dev/null
@@ -1,76 +0,0 @@
-package io.github.chronosx88.dhtBootstrap.kademlia.message;
-
-import java.io.DataInputStream;
-import java.io.IOException;
-import io.github.chronosx88.dhtBootstrap.kademlia.KadConfiguration;
-import io.github.chronosx88.dhtBootstrap.kademlia.KadServer;
-import io.github.chronosx88.dhtBootstrap.kademlia.KademliaNode;
-import io.github.chronosx88.dhtBootstrap.kademlia.dht.KademliaDHT;
-
-/**
- * Handles creating messages and receivers
- *
- * @author Joshua Kissoon
- * @since 20140202
- */
-public class MessageFactory implements KademliaMessageFactory
-{
-
- private final KademliaNode localNode;
- private final KademliaDHT dht;
- private final KadConfiguration config;
-
- public MessageFactory(KademliaNode local, KademliaDHT dht, KadConfiguration config)
- {
- this.localNode = local;
- this.dht = dht;
- this.config = config;
- }
-
- @Override
- public Message createMessage(byte code, DataInputStream in) throws IOException
- {
- switch (code)
- {
- case AcknowledgeMessage.CODE:
- return new AcknowledgeMessage(in);
- case ConnectMessage.CODE:
- return new ConnectMessage(in);
- case ContentMessage.CODE:
- return new ContentMessage(in);
- case ContentLookupMessage.CODE:
- return new ContentLookupMessage(in);
- case NodeLookupMessage.CODE:
- return new NodeLookupMessage(in);
- case NodeReplyMessage.CODE:
- return new NodeReplyMessage(in);
- case SimpleMessage.CODE:
- return new SimpleMessage(in);
- case StoreContentMessage.CODE:
- return new StoreContentMessage(in);
- default:
- //System.out.println(this.localNode + " - No Message handler found for message. Code: " + code);
- return new SimpleMessage(in);
-
- }
- }
-
- @Override
- public Receiver createReceiver(byte code, KadServer server)
- {
- switch (code)
- {
- case ConnectMessage.CODE:
- return new ConnectReceiver(server, this.localNode);
- case ContentLookupMessage.CODE:
- return new ContentLookupReceiver(server, this.localNode, this.dht, this.config);
- case NodeLookupMessage.CODE:
- return new NodeLookupReceiver(server, this.localNode, this.config);
- case StoreContentMessage.CODE:
- return new StoreContentReceiver(server, this.localNode, this.dht);
- default:
- //System.out.println("No receiver found for message. Code: " + code);
- return new SimpleReceiver();
- }
- }
-}
diff --git a/src/main/java/io/github/chronosx88/dhtBootstrap/kademlia/message/NodeLookupMessage.java b/src/main/java/io/github/chronosx88/dhtBootstrap/kademlia/message/NodeLookupMessage.java
deleted file mode 100644
index e69f512..0000000
--- a/src/main/java/io/github/chronosx88/dhtBootstrap/kademlia/message/NodeLookupMessage.java
+++ /dev/null
@@ -1,75 +0,0 @@
-package io.github.chronosx88.dhtBootstrap.kademlia.message;
-
-import java.io.DataInputStream;
-import java.io.DataOutputStream;
-import java.io.IOException;
-import io.github.chronosx88.dhtBootstrap.kademlia.node.Node;
-import io.github.chronosx88.dhtBootstrap.kademlia.node.KademliaId;
-
-/**
- * A message sent to other nodes requesting the K-Closest nodes to a key sent in this message.
- *
- * @author Joshua Kissoon
- * @created 20140218
- */
-public class NodeLookupMessage implements Message
-{
-
- private Node origin;
- private KademliaId lookupId;
-
- public static final byte CODE = 0x05;
-
- /**
- * A new NodeLookupMessage to find nodes
- *
- * @param origin The Node from which the message is coming from
- * @param lookup The key for which to lookup nodes for
- */
- public NodeLookupMessage(Node origin, KademliaId lookup)
- {
- this.origin = origin;
- this.lookupId = lookup;
- }
-
- public NodeLookupMessage(DataInputStream in) throws IOException
- {
- this.fromStream(in);
- }
-
- @Override
- public final void fromStream(DataInputStream in) throws IOException
- {
- this.origin = new Node(in);
- this.lookupId = new KademliaId(in);
- }
-
- @Override
- public void toStream(DataOutputStream out) throws IOException
- {
- this.origin.toStream(out);
- this.lookupId.toStream(out);
- }
-
- public Node getOrigin()
- {
- return this.origin;
- }
-
- public KademliaId getLookupId()
- {
- return this.lookupId;
- }
-
- @Override
- public byte code()
- {
- return CODE;
- }
-
- @Override
- public String toString()
- {
- return "NodeLookupMessage[origin=" + origin + ",lookup=" + lookupId + "]";
- }
-}
diff --git a/src/main/java/io/github/chronosx88/dhtBootstrap/kademlia/message/NodeLookupReceiver.java b/src/main/java/io/github/chronosx88/dhtBootstrap/kademlia/message/NodeLookupReceiver.java
deleted file mode 100644
index 541a960..0000000
--- a/src/main/java/io/github/chronosx88/dhtBootstrap/kademlia/message/NodeLookupReceiver.java
+++ /dev/null
@@ -1,72 +0,0 @@
-package io.github.chronosx88.dhtBootstrap.kademlia.message;
-
-import java.io.IOException;
-import java.util.List;
-import io.github.chronosx88.dhtBootstrap.kademlia.KadConfiguration;
-import io.github.chronosx88.dhtBootstrap.kademlia.KadServer;
-import io.github.chronosx88.dhtBootstrap.kademlia.KademliaNode;
-import io.github.chronosx88.dhtBootstrap.kademlia.node.Node;
-
-/**
- * Receives a NodeLookupMessage and sends a NodeReplyMessage as reply with the K-Closest nodes to the ID sent.
- *
- * @author Joshua Kissoon
- * @created 20140219
- */
-public class NodeLookupReceiver implements Receiver
-{
-
- private final KadServer server;
- private final KademliaNode localNode;
- private final KadConfiguration config;
-
- public NodeLookupReceiver(KadServer server, KademliaNode local, KadConfiguration config)
- {
- this.server = server;
- this.localNode = local;
- this.config = config;
- }
-
- /**
- * Handle receiving a NodeLookupMessage
- * Find the set of K nodes closest to the lookup ID and return them
- *
- * @param comm
- *
- * @throws IOException
- */
- @Override
- public void receive(Message incoming, int comm) throws IOException
- {
- NodeLookupMessage msg = (NodeLookupMessage) incoming;
-
- Node origin = msg.getOrigin();
-
- /* Update the local space by inserting the origin node. */
- this.localNode.getRoutingTable().insert(origin);
-
- /* Find nodes closest to the LookupId */
- ListMessageServer.TIMEOUT
seconds for the
- * message with communication id comm
, the MessageServer calls this method
- *
- * @param conversationId The conversation ID of this communication
- *
- * @throws IOException if an I/O error occurs
- * */
- public void timeout(int conversationId) throws IOException;
-}
diff --git a/src/main/java/io/github/chronosx88/dhtBootstrap/kademlia/message/SimpleMessage.java b/src/main/java/io/github/chronosx88/dhtBootstrap/kademlia/message/SimpleMessage.java
deleted file mode 100644
index fee31b2..0000000
--- a/src/main/java/io/github/chronosx88/dhtBootstrap/kademlia/message/SimpleMessage.java
+++ /dev/null
@@ -1,72 +0,0 @@
-package io.github.chronosx88.dhtBootstrap.kademlia.message;
-
-import java.io.DataInputStream;
-import java.io.DataOutputStream;
-import java.io.IOException;
-
-/**
- * A simple message used for testing the system; Default message constructed if the message type sent is not available
- *
- * @author Joshua Kissoon
- * @created 20140217
- */
-public class SimpleMessage implements Message
-{
-
- /* Message constants */
- public static final byte CODE = 0x07;
-
- private String content;
-
- public SimpleMessage(String message)
- {
- this.content = message;
- }
-
- public SimpleMessage(DataInputStream in)
- {
- this.fromStream(in);
- }
-
- @Override
- public byte code()
- {
- return CODE;
- }
-
- @Override
- public void toStream(DataOutputStream out)
- {
- try
- {
- out.writeInt(this.content.length());
- out.writeBytes(this.content);
- }
- catch (IOException e)
- {
- e.printStackTrace();
- }
- }
-
- @Override
- public final void fromStream(DataInputStream in)
- {
- try
- {
- byte[] buff = new byte[in.readInt()];
- in.readFully(buff);
-
- this.content = new String(buff);
- }
- catch (IOException e)
- {
- e.printStackTrace();
- }
- }
-
- @Override
- public String toString()
- {
- return this.content;
- }
-}
diff --git a/src/main/java/io/github/chronosx88/dhtBootstrap/kademlia/message/SimpleReceiver.java b/src/main/java/io/github/chronosx88/dhtBootstrap/kademlia/message/SimpleReceiver.java
deleted file mode 100644
index 1a4b8e0..0000000
--- a/src/main/java/io/github/chronosx88/dhtBootstrap/kademlia/message/SimpleReceiver.java
+++ /dev/null
@@ -1,25 +0,0 @@
-package io.github.chronosx88.dhtBootstrap.kademlia.message;
-
-import java.io.IOException;
-
-/**
- * Default receiver if none other is called
- *
- * @author Joshua Kissoon
- * @created 20140202
- */
-public class SimpleReceiver implements Receiver
-{
-
- @Override
- public void receive(Message incoming, int conversationId)
- {
- //System.out.println("Received message: " + incoming);
- }
-
- @Override
- public void timeout(int conversationId) throws IOException
- {
- //System.out.println("SimpleReceiver message timeout.");
- }
-}
diff --git a/src/main/java/io/github/chronosx88/dhtBootstrap/kademlia/message/StoreContentMessage.java b/src/main/java/io/github/chronosx88/dhtBootstrap/kademlia/message/StoreContentMessage.java
deleted file mode 100644
index ad0b9e4..0000000
--- a/src/main/java/io/github/chronosx88/dhtBootstrap/kademlia/message/StoreContentMessage.java
+++ /dev/null
@@ -1,84 +0,0 @@
-package io.github.chronosx88.dhtBootstrap.kademlia.message;
-
-import java.io.DataInputStream;
-import java.io.DataOutputStream;
-import java.io.IOException;
-import io.github.chronosx88.dhtBootstrap.kademlia.dht.JKademliaStorageEntry;
-import io.github.chronosx88.dhtBootstrap.kademlia.node.Node;
-import io.github.chronosx88.dhtBootstrap.kademlia.util.serializer.JsonSerializer;
-
-/**
- * A StoreContentMessage used to send a store message to a node
- *
- * @author Joshua Kissoon
- * @since 20140225
- */
-public class StoreContentMessage implements Message
-{
-
- public static final byte CODE = 0x08;
-
- private JKademliaStorageEntry content;
- private Node origin;
-
- /**
- * @param origin Where the message came from
- * @param content The content to be stored
- *
- */
- public StoreContentMessage(Node origin, JKademliaStorageEntry content)
- {
- this.content = content;
- this.origin = origin;
- }
-
- public StoreContentMessage(DataInputStream in) throws IOException
- {
- this.fromStream(in);
- }
-
- @Override
- public void toStream(DataOutputStream out) throws IOException
- {
- this.origin.toStream(out);
-
- /* Serialize the KadContent, then send it to the stream */
- new JsonSerializer- * Since the exact class must be known anyway prior to reading, it is incouraged - * that classes implementing Streamble also provide a constructor of the form: - *
- * Streamable(DataInput in) throws IOException;
- * */
-public interface Streamable
-{
-
- /**
- * Writes the internal state of the Streamable object to the output stream
- * in a format that can later be read by the same Streamble class using
- * the {@link #fromStream} method.
- *
- * @param out
- *
- * @throws IOException
- */
- public void toStream(DataOutputStream out) throws IOException;
-
- /**
- * Reads the internal state of the Streamable object from the input stream.
- *
- * @param out
- *
- * @throws IOException
- */
- public void fromStream(DataInputStream out) throws IOException;
-}
diff --git a/src/main/java/io/github/chronosx88/dhtBootstrap/kademlia/node/KademliaId.java b/src/main/java/io/github/chronosx88/dhtBootstrap/kademlia/node/KademliaId.java
deleted file mode 100644
index 1932f44..0000000
--- a/src/main/java/io/github/chronosx88/dhtBootstrap/kademlia/node/KademliaId.java
+++ /dev/null
@@ -1,264 +0,0 @@
-/**
- * @author Joshua Kissoon
- * @created 20140215
- * @desc Represents a Kademlia Node ID
- */
-package io.github.chronosx88.dhtBootstrap.kademlia.node;
-
-import java.io.DataInputStream;
-import java.io.DataOutputStream;
-import java.io.IOException;
-import java.io.Serializable;
-import java.math.BigInteger;
-import java.util.Arrays;
-import java.util.BitSet;
-import java.util.Random;
-import io.github.chronosx88.dhtBootstrap.kademlia.message.Streamable;
-
-import javax.xml.bind.DatatypeConverter;
-
-public class KademliaId implements Streamable, Serializable
-{
-
- public final transient static int ID_LENGTH = 160;
- private byte[] keyBytes;
-
- /**
- * Construct the NodeId from some string
- *
- * @param data The user generated key string
- */
- public KademliaId(String data)
- {
- keyBytes = DatatypeConverter.parseHexBinary(data);
- if (keyBytes.length != ID_LENGTH / 8)
- {
- throw new IllegalArgumentException("Specified Data need to be " + (ID_LENGTH / 8) + " characters long.");
- }
- }
-
- /**
- * Generate a random key
- */
- public KademliaId()
- {
- keyBytes = new byte[ID_LENGTH / 8];
- new Random().nextBytes(keyBytes);
- }
-
- /**
- * Generate the NodeId from a given byte[]
- *
- * @param bytes
- */
- public KademliaId(byte[] bytes)
- {
- /*if (bytes.length != ID_LENGTH / 8)
- {
- throw new IllegalArgumentException("Specified Data need to be " + (ID_LENGTH / 8) + " characters long. Data Given: '" + new String(bytes) + "'");
- }*/
- this.keyBytes = bytes;
- }
-
- /**
- * Load the NodeId from a DataInput stream
- *
- * @param in The stream from which to load the NodeId
- *
- * @throws IOException
- */
- public KademliaId(DataInputStream in) throws IOException
- {
- this.fromStream(in);
- }
-
- public byte[] getBytes()
- {
- return this.keyBytes;
- }
-
- /**
- * @return The BigInteger representation of the key
- */
- public BigInteger getInt()
- {
- return new BigInteger(1, this.getBytes());
- }
-
- /**
- * Compares a NodeId to this NodeId
- *
- * @param o The NodeId to compare to this NodeId
- *
- * @return boolean Whether the 2 NodeIds are equal
- */
- @Override
- public boolean equals(Object o)
- {
- if (o instanceof KademliaId)
- {
- KademliaId nid = (KademliaId) o;
- return this.hashCode() == nid.hashCode();
- }
- return false;
- }
-
- @Override
- public int hashCode()
- {
- int hash = 7;
- hash = 83 * hash + Arrays.hashCode(this.keyBytes);
- return hash;
- }
-
- /**
- * Checks the distance between this and another NodeId
- *
- * @param nid
- *
- * @return The distance of this NodeId from the given NodeId
- */
- public KademliaId xor(KademliaId nid)
- {
- byte[] result = new byte[ID_LENGTH / 8];
- byte[] nidBytes = nid.getBytes();
-
- for (int i = 0; i < ID_LENGTH / 8; i++)
- {
- result[i] = (byte) (this.keyBytes[i] ^ nidBytes[i]);
- }
-
- KademliaId resNid = new KademliaId(result);
-
- return resNid;
- }
-
- /**
- * Generates a NodeId that is some distance away from this NodeId
- *
- * @param distance in number of bits
- *
- * @return NodeId The newly generated NodeId
- */
- public KademliaId generateNodeIdByDistance(int distance)
- {
- byte[] result = new byte[ID_LENGTH / 8];
-
- /* Since distance = ID_LENGTH - prefixLength, we need to fill that amount with 0's */
- int numByteZeroes = (ID_LENGTH - distance) / 8;
- int numBitZeroes = 8 - (distance % 8);
-
- /* Filling byte zeroes */
- for (int i = 0; i < numByteZeroes; i++)
- {
- result[i] = 0;
- }
-
- /* Filling bit zeroes */
- BitSet bits = new BitSet(8);
- bits.set(0, 8);
-
- for (int i = 0; i < numBitZeroes; i++)
- {
- /* Shift 1 zero into the start of the value */
- bits.clear(i);
- }
- bits.flip(0, 8); // Flip the bits since they're in reverse order
- result[numByteZeroes] = (byte) bits.toByteArray()[0];
-
- /* Set the remaining bytes to Maximum value */
- for (int i = numByteZeroes + 1; i < result.length; i++)
- {
- result[i] = Byte.MAX_VALUE;
- }
-
- return this.xor(new KademliaId(result));
- }
-
- /**
- * Counts the number of leading 0's in this NodeId
- *
- * @return Integer The number of leading 0's
- */
- public int getFirstSetBitIndex()
- {
- int prefixLength = 0;
-
- for (byte b : this.keyBytes)
- {
- if (b == 0)
- {
- prefixLength += 8;
- }
- else
- {
- /* If the byte is not 0, we need to count how many MSBs are 0 */
- int count = 0;
- for (int i = 7; i >= 0; i--)
- {
- boolean a = (b & (1 << i)) == 0;
- if (a)
- {
- count++;
- }
- else
- {
- break; // Reset the count if we encounter a non-zero number
- }
- }
-
- /* Add the count of MSB 0s to the prefix length */
- prefixLength += count;
-
- /* Break here since we've now covered the MSB 0s */
- break;
- }
- }
- return prefixLength;
- }
-
- /**
- * Gets the distance from this NodeId to another NodeId
- *
- * @param to
- *
- * @return Integer The distance
- */
- public int getDistance(KademliaId to)
- {
- /**
- * Compute the xor of this and to
- * Get the index i of the first set bit of the xor returned NodeId
- * The distance between them is ID_LENGTH - i
- */
- return ID_LENGTH - this.xor(to).getFirstSetBitIndex();
- }
-
- @Override
- public void toStream(DataOutputStream out) throws IOException
- {
- /* Add the NodeId to the stream */
- out.write(this.getBytes());
- }
-
- @Override
- public final void fromStream(DataInputStream in) throws IOException
- {
- byte[] input = new byte[ID_LENGTH / 8];
- in.readFully(input);
- this.keyBytes = input;
- }
-
- public String hexRepresentation()
- {
- /* Returns the hex format of this NodeId */
- return DatatypeConverter.printHexBinary(keyBytes);
- }
-
- @Override
- public String toString()
- {
- return this.hexRepresentation();
- }
-
-}
diff --git a/src/main/java/io/github/chronosx88/dhtBootstrap/kademlia/node/KeyComparator.java b/src/main/java/io/github/chronosx88/dhtBootstrap/kademlia/node/KeyComparator.java
deleted file mode 100644
index 132ccf2..0000000
--- a/src/main/java/io/github/chronosx88/dhtBootstrap/kademlia/node/KeyComparator.java
+++ /dev/null
@@ -1,44 +0,0 @@
-package io.github.chronosx88.dhtBootstrap.kademlia.node;
-
-import java.math.BigInteger;
-import java.util.Comparator;
-
-/**
- * A Comparator to compare 2 keys to a given key
- *
- * @author Joshua Kissoon
- * @since 20140322
- */
-public class KeyComparator implements ComparatorNode
- * and determine which is closest to the identifier specified in the
- * constructor.
- *
- * @param n1 Node 1 to compare distance from the key
- * @param n2 Node 2 to compare distance from the key
- */
- @Override
- public int compare(Node n1, Node n2)
- {
- BigInteger b1 = n1.getNodeId().getInt();
- BigInteger b2 = n2.getNodeId().getInt();
-
- b1 = b1.xor(key);
- b2 = b2.xor(key);
-
- return b1.abs().compareTo(b2.abs());
- }
-}
diff --git a/src/main/java/io/github/chronosx88/dhtBootstrap/kademlia/node/Node.java b/src/main/java/io/github/chronosx88/dhtBootstrap/kademlia/node/Node.java
deleted file mode 100644
index 05166a4..0000000
--- a/src/main/java/io/github/chronosx88/dhtBootstrap/kademlia/node/Node.java
+++ /dev/null
@@ -1,134 +0,0 @@
-package io.github.chronosx88.dhtBootstrap.kademlia.node;
-
-import java.io.DataInputStream;
-import java.io.DataOutputStream;
-import java.io.IOException;
-import java.io.Serializable;
-import java.net.InetAddress;
-import java.net.InetSocketAddress;
-import io.github.chronosx88.dhtBootstrap.kademlia.message.Streamable;
-
-/**
- * A Node in the Kademlia network - Contains basic node network information.
- *
- * @author Joshua Kissoon
- * @since 20140202
- * @version 0.1
- */
-public class Node implements Streamable, Serializable
-{
-
- private KademliaId nodeId;
- private InetAddress inetAddress;
- private int port;
- private final String strRep;
-
- public Node(KademliaId nid, InetAddress ip, int port)
- {
- this.nodeId = nid;
- this.inetAddress = ip;
- this.port = port;
- this.strRep = this.nodeId.toString();
- }
-
- /**
- * Load the Node's data from a DataInput stream
- *
- * @param in
- *
- * @throws IOException
- */
- public Node(DataInputStream in) throws IOException
- {
- this.fromStream(in);
- this.strRep = this.nodeId.toString();
- }
-
- /**
- * Set the InetAddress of this node
- *
- * @param addr The new InetAddress of this node
- */
- public void setInetAddress(InetAddress addr)
- {
- this.inetAddress = addr;
- }
-
- /**
- * @return The NodeId object of this node
- */
- public KademliaId getNodeId()
- {
- return this.nodeId;
- }
-
- /**
- * Creates a SocketAddress for this node
- *
- * @return
- */
- public InetSocketAddress getSocketAddress()
- {
- return new InetSocketAddress(this.inetAddress, this.port);
- }
-
- @Override
- public void toStream(DataOutputStream out) throws IOException
- {
- /* Add the NodeId to the stream */
- this.nodeId.toStream(out);
-
- /* Add the Node's IP address to the stream */
- byte[] a = inetAddress.getAddress();
- if (a.length != 4)
- {
- throw new RuntimeException("Expected InetAddress of 4 bytes, got " + a.length);
- }
- out.write(a);
-
- /* Add the port to the stream */
- out.writeInt(port);
- }
-
- @Override
- public final void fromStream(DataInputStream in) throws IOException
- {
- /* Load the NodeId */
- this.nodeId = new KademliaId(in);
-
- /* Load the IP Address */
- byte[] ip = new byte[4];
- in.readFully(ip);
- this.inetAddress = InetAddress.getByAddress(ip);
-
- /* Read in the port */
- this.port = in.readInt();
- }
-
- @Override
- public boolean equals(Object o)
- {
- if (o instanceof Node)
- {
- Node n = (Node) o;
- if (n == this)
- {
- return true;
- }
- return this.getNodeId().equals(n.getNodeId());
- }
- return false;
- }
-
- @Override
- public int hashCode()
- {
- return this.getNodeId().hashCode();
- }
-
- @Override
- public String toString()
- {
- return this.getNodeId().toString();
- }
-}
diff --git a/src/main/java/io/github/chronosx88/dhtBootstrap/kademlia/operation/BucketRefreshOperation.java b/src/main/java/io/github/chronosx88/dhtBootstrap/kademlia/operation/BucketRefreshOperation.java
deleted file mode 100644
index f54bbc1..0000000
--- a/src/main/java/io/github/chronosx88/dhtBootstrap/kademlia/operation/BucketRefreshOperation.java
+++ /dev/null
@@ -1,66 +0,0 @@
-package io.github.chronosx88.dhtBootstrap.kademlia.operation;
-
-import java.io.IOException;
-import io.github.chronosx88.dhtBootstrap.kademlia.KadConfiguration;
-import io.github.chronosx88.dhtBootstrap.kademlia.KadServer;
-import io.github.chronosx88.dhtBootstrap.kademlia.KademliaNode;
-import io.github.chronosx88.dhtBootstrap.kademlia.node.KademliaId;
-
-/**
- * At each time interval t, nodes need to refresh their K-Buckets
- * This operation takes care of refreshing this node's K-Buckets
- *
- * @author Joshua Kissoon
- * @created 20140224
- */
-public class BucketRefreshOperation implements Operation
-{
-
- private final KadServer server;
- private final KademliaNode localNode;
- private final KadConfiguration config;
-
- public BucketRefreshOperation(KadServer server, KademliaNode localNode, KadConfiguration config)
- {
- this.server = server;
- this.localNode = localNode;
- this.config = config;
- }
-
- /**
- * Each bucket need to be refreshed at every time interval t.
- * Find an identifier in each bucket's range, use it to look for nodes closest to this identifier
- * allowing the bucket to be refreshed.
- *
- * Then Do a NodeLookupOperation for each of the generated NodeIds,
- * This will find the K-Closest nodes to that ID, and update the necessary K-Bucket
- *
- * @throws IOException
- */
- @Override
- public synchronized void execute() throws IOException
- {
- for (int i = 1; i < KademliaId.ID_LENGTH; i++)
- {
- /* Construct a NodeId that is i bits away from the current node Id */
- final KademliaId current = this.localNode.getNode().getNodeId().generateNodeIdByDistance(i);
-
- /* Run the Node Lookup Operation, each in a different thread to speed up things */
- new Thread()
- {
- @Override
- public void run()
- {
- try
- {
- new NodeLookupOperation(server, localNode, current, BucketRefreshOperation.this.config).execute();
- }
- catch (IOException e)
- {
- //System.err.println("Bucket Refresh Operation Failed. Msg: " + e.getMessage());
- }
- }
- }.start();
- }
- }
-}
diff --git a/src/main/java/io/github/chronosx88/dhtBootstrap/kademlia/operation/ConnectOperation.java b/src/main/java/io/github/chronosx88/dhtBootstrap/kademlia/operation/ConnectOperation.java
deleted file mode 100644
index 261d2f8..0000000
--- a/src/main/java/io/github/chronosx88/dhtBootstrap/kademlia/operation/ConnectOperation.java
+++ /dev/null
@@ -1,140 +0,0 @@
-/**
- * @author Joshua Kissoon
- * @created 20140218
- * @desc Operation that handles connecting to an existing Kademlia network using a bootstrap node
- */
-package io.github.chronosx88.dhtBootstrap.kademlia.operation;
-
-import io.github.chronosx88.dhtBootstrap.kademlia.message.Receiver;
-import java.io.IOException;
-
-import io.github.chronosx88.dhtBootstrap.kademlia.KadConfiguration;
-import io.github.chronosx88.dhtBootstrap.kademlia.KadServer;
-import io.github.chronosx88.dhtBootstrap.kademlia.KademliaNode;
-import io.github.chronosx88.dhtBootstrap.kademlia.exceptions.RoutingException;
-import io.github.chronosx88.dhtBootstrap.kademlia.message.AcknowledgeMessage;
-import io.github.chronosx88.dhtBootstrap.kademlia.message.ConnectMessage;
-import io.github.chronosx88.dhtBootstrap.kademlia.message.Message;
-import io.github.chronosx88.dhtBootstrap.kademlia.node.Node;
-
-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 KademliaNode localNode;
- private final Node bootstrapNode;
- private final KadConfiguration config;
-
- private boolean error;
- private int attempts;
-
- /**
- * @param server The message server used to send/receive messages
- * @param local The local node
- * @param bootstrap Node to use to bootstrap the local node onto the network
- * @param config
- */
- public ConnectOperation(KadServer server, KademliaNode local, Node bootstrap, KadConfiguration config)
- {
- this.server = server;
- this.localNode = local;
- this.bootstrapNode = bootstrap;
- this.config = config;
- }
-
- @Override
- public synchronized void execute() throws IOException
- {
- try
- {
- /* Contact the bootstrap node */
- this.error = true;
- this.attempts = 0;
- Message m = new ConnectMessage(this.localNode.getNode());
-
- /* Send a connect message to the bootstrap node */
- server.sendMessage(this.bootstrapNode, m, this);
-
- /* If we haven't finished as yet, wait for a maximum of config.operationTimeout() time */
- int totalTimeWaited = 0;
- int timeInterval = 50; // We re-check every 300 milliseconds
- while (totalTimeWaited < this.config.operationTimeout())
- {
- if (error)
- {
- wait(timeInterval);
- totalTimeWaited += timeInterval;
- }
- else
- {
- break;
- }
- }
- if (error)
- {
- /* If we still haven't received any responses by then, do a routing timeout */
- throw new RoutingException("ConnectOperation: Bootstrap node did not respond: " + bootstrapNode);
- }
-
- /* Perform lookup for our own ID to get nodes close to us */
- Operation lookup = new NodeLookupOperation(this.server, this.localNode, this.localNode.getNode().getNodeId(), this.config);
- lookup.execute();
-
- /**
- * Refresh buckets to get a good routing table
- * After the above lookup operation, K nodes will be in our routing table,
- * Now we try to populate all of our buckets.
- */
- new BucketRefreshOperation(this.server, this.localNode, this.config).execute();
- }
- catch (InterruptedException e)
- {
- System.err.println("Connect operation was interrupted. ");
- }
- }
-
- /**
- * Receives an AcknowledgeMessage from the bootstrap node.
- *
- * @param comm
- */
- @Override
- public synchronized void receive(Message incoming, int comm)
- {
- /* The incoming message will be an acknowledgement message */
- AcknowledgeMessage msg = (AcknowledgeMessage) incoming;
-
- /* The bootstrap node has responded, insert it into our space */
- this.localNode.getRoutingTable().insert(this.bootstrapNode);
-
- /* We got a response, so the error is false */
- error = false;
-
- /* Wake up any waiting thread */
- notify();
- }
-
- /**
- * Resends a ConnectMessage to the boot strap node a maximum of MAX_ATTEMPTS
- * times.
- *
- * @param comm
- *
- * @throws IOException
- */
- @Override
- public synchronized void timeout(int comm) throws IOException
- {
- if (++this.attempts < MAX_CONNECT_ATTEMPTS)
- {
- this.server.sendMessage(this.bootstrapNode, new ConnectMessage(this.localNode.getNode()), this);
- }
- else
- {
- /* We just exit, so notify all other threads that are possibly waiting */
- notify();
- }
- }
-}
diff --git a/src/main/java/io/github/chronosx88/dhtBootstrap/kademlia/operation/ContentLookupOperation.java b/src/main/java/io/github/chronosx88/dhtBootstrap/kademlia/operation/ContentLookupOperation.java
deleted file mode 100644
index 17e7051..0000000
--- a/src/main/java/io/github/chronosx88/dhtBootstrap/kademlia/operation/ContentLookupOperation.java
+++ /dev/null
@@ -1,342 +0,0 @@
-package io.github.chronosx88.dhtBootstrap.kademlia.operation;
-
-import io.github.chronosx88.dhtBootstrap.kademlia.message.Receiver;
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.Comparator;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.SortedMap;
-import java.util.TreeMap;
-import io.github.chronosx88.dhtBootstrap.kademlia.JKademliaNode;
-import io.github.chronosx88.dhtBootstrap.kademlia.dht.GetParameter;
-import io.github.chronosx88.dhtBootstrap.kademlia.KadConfiguration;
-import io.github.chronosx88.dhtBootstrap.kademlia.KadServer;
-import io.github.chronosx88.dhtBootstrap.kademlia.dht.JKademliaStorageEntry;
-import io.github.chronosx88.dhtBootstrap.kademlia.exceptions.ContentNotFoundException;
-import io.github.chronosx88.dhtBootstrap.kademlia.exceptions.RoutingException;
-import io.github.chronosx88.dhtBootstrap.kademlia.exceptions.UnknownMessageException;
-import io.github.chronosx88.dhtBootstrap.kademlia.message.ContentLookupMessage;
-import io.github.chronosx88.dhtBootstrap.kademlia.message.ContentMessage;
-import io.github.chronosx88.dhtBootstrap.kademlia.message.Message;
-import io.github.chronosx88.dhtBootstrap.kademlia.message.NodeReplyMessage;
-import io.github.chronosx88.dhtBootstrap.kademlia.node.KeyComparator;
-import io.github.chronosx88.dhtBootstrap.kademlia.node.Node;
-import io.github.chronosx88.dhtBootstrap.kademlia.util.RouteLengthChecker;
-
-/**
- * Looks up a specified identifier and returns the value associated with it
- *
- * @author Joshua Kissoon
- * @since 20140226
- */
-public class ContentLookupOperation implements Operation, Receiver
-{
-
- /* Constants */
- private static final Byte UNASKED = (byte) 0x00;
- private static final Byte AWAITING = (byte) 0x01;
- private static final Byte ASKED = (byte) 0x02;
- private static final Byte FAILED = (byte) 0x03;
-
- private final KadServer server;
- private final JKademliaNode localNode;
- private JKademliaStorageEntry contentFound = null;
- private final KadConfiguration config;
-
- private final ContentLookupMessage lookupMessage;
-
- private boolean isContentFound;
- private final SortedMaptrue
if finished OR false
otherwise
- */
- private boolean askNodesorFinish() throws IOException
- {
- /* If >= CONCURRENCY nodes are in transit, don't do anything */
- if (this.config.maxConcurrentMessagesTransiting() <= this.messagesTransiting.size())
- {
- return false;
- }
-
- /* Get unqueried nodes among the K closest seen that have not FAILED */
- Listtrue
if finished OR false
otherwise
- */
- private boolean askNodesorFinish() throws IOException
- {
- /* If >= CONCURRENCY nodes are in transit, don't do anything */
- if (this.config.maxConcurrentMessagesTransiting() <= this.messagesTransiting.size())
- {
- return false;
- }
-
- /* Get unqueried nodes among the K closest seen that have not FAILED */
- List>()
- {
- }.getType();
- }
-
- @Override
- public void write(KademliaDHT data, DataOutputStream out) throws IOException
- {
- try (JsonWriter writer = new JsonWriter(new OutputStreamWriter(out)))
- {
- writer.beginArray();
-
- /* Write the basic DHT */
- gson.toJson(data, DHT.class, writer);
-
- /* Now Store the Entries */
- gson.toJson(data.getStorageEntries(), this.storageEntriesCollectionType, writer);
-
- writer.endArray();
- }
-
- }
-
- @Override
- public KademliaDHT read(DataInputStream in) throws IOException, ClassNotFoundException
- {
- try (DataInputStream din = new DataInputStream(in);
- JsonReader reader = new JsonReader(new InputStreamReader(in)))
- {
- reader.beginArray();
-
- /* Read the basic DHT */
- DHT dht = gson.fromJson(reader, DHT.class);
- dht.initialize();
-
- /* Now get the entries and add them back to the DHT */
- List
>()
- {
- }.getType();
-
- private final KadConfiguration config;
-
-
- {
- gson = new Gson();
- }
-
- /**
- * Initialize the class
- *
- * @param config
- */
- public JsonRoutingTableSerializer(KadConfiguration config)
- {
- this.config = config;
- }
-
- @Override
- public void write(KademliaRoutingTable data, DataOutputStream out) throws IOException
- {
- try (JsonWriter writer = new JsonWriter(new OutputStreamWriter(out)))
- {
- writer.beginArray();
-
- /* Write the basic JKademliaRoutingTable */
- gson.toJson(data, JKademliaRoutingTable.class, writer);
-
- /* Now Store the Contacts */
- gson.toJson(data.getAllContacts(), contactCollectionType, writer);
-
- writer.endArray();
- }
- }
-
- @Override
- public KademliaRoutingTable read(DataInputStream in) throws IOException, ClassNotFoundException
- {
- try (DataInputStream din = new DataInputStream(in);
- JsonReader reader = new JsonReader(new InputStreamReader(in)))
- {
- reader.beginArray();
-
- /* Read the basic JKademliaRoutingTable */
- KademliaRoutingTable tbl = gson.fromJson(reader, KademliaRoutingTable.class);
- tbl.setConfiguration(config);
-
- /* Now get the Contacts and add them back to the JKademliaRoutingTable */
- List