Added a KademliaDHT Interface and setup the DHT class and the rest of the system to use this interface

This commit is contained in:
Joshua Kissoon 2014-05-23 22:14:08 +05:30
parent 568f2fe9a8
commit 9fb139571a
13 changed files with 178 additions and 115 deletions

View File

@ -14,6 +14,7 @@ import java.util.TimerTask;
import kademlia.dht.GetParameter; import kademlia.dht.GetParameter;
import kademlia.dht.DHT; import kademlia.dht.DHT;
import kademlia.dht.KadContent; import kademlia.dht.KadContent;
import kademlia.dht.KademliaDHT;
import kademlia.dht.StorageEntry; import kademlia.dht.StorageEntry;
import kademlia.exceptions.ContentNotFoundException; import kademlia.exceptions.ContentNotFoundException;
import kademlia.exceptions.RoutingException; import kademlia.exceptions.RoutingException;
@ -50,7 +51,7 @@ public class JKademliaNode implements KademliaNode
/* Objects to be used */ /* Objects to be used */
private final transient Node localNode; private final transient Node localNode;
private final transient KadServer server; private final transient KadServer server;
private final transient DHT dht; private final transient KademliaDHT dht;
private transient KademliaRoutingTable routingTable; private transient KademliaRoutingTable routingTable;
private final int udpPort; private final int udpPort;
private transient KadConfiguration config; private transient KadConfiguration config;
@ -87,7 +88,7 @@ public class JKademliaNode implements KademliaNode
* from disk <i>or</i> a network error occurred while * from disk <i>or</i> a network error occurred while
* attempting to bootstrap to the network * attempting to bootstrap to the network
* */ * */
public JKademliaNode(String ownerId, Node localNode, int udpPort, DHT dht, KademliaRoutingTable routingTable, KadConfiguration config) throws IOException public JKademliaNode(String ownerId, Node localNode, int udpPort, KademliaDHT dht, KademliaRoutingTable routingTable, KadConfiguration config) throws IOException
{ {
this.ownerId = ownerId; this.ownerId = ownerId;
this.udpPort = udpPort; this.udpPort = udpPort;
@ -217,7 +218,7 @@ public class JKademliaNode implements KademliaNode
* @section Read the DHT * @section Read the DHT
*/ */
din = new DataInputStream(new FileInputStream(getStateStorageFolderName(ownerId, iconfig) + File.separator + "dht.kns")); din = new DataInputStream(new FileInputStream(getStateStorageFolderName(ownerId, iconfig) + File.separator + "dht.kns"));
DHT idht = new JsonDHTSerializer().read(din); KademliaDHT idht = new JsonDHTSerializer().read(din);
idht.setConfiguration(iconfig); idht.setConfiguration(iconfig);
return new JKademliaNode(ownerId, inode, ikad.getPort(), idht, irtbl, iconfig); return new JKademliaNode(ownerId, inode, ikad.getPort(), idht, irtbl, iconfig);
@ -236,7 +237,7 @@ public class JKademliaNode implements KademliaNode
} }
@Override @Override
public DHT getDHT() public KademliaDHT getDHT()
{ {
return this.dht; return this.dht;
} }

View File

@ -3,8 +3,8 @@ package kademlia;
import java.io.IOException; import java.io.IOException;
import java.util.NoSuchElementException; import java.util.NoSuchElementException;
import kademlia.dht.GetParameter; import kademlia.dht.GetParameter;
import kademlia.dht.DHT;
import kademlia.dht.KadContent; import kademlia.dht.KadContent;
import kademlia.dht.KademliaDHT;
import kademlia.dht.StorageEntry; import kademlia.dht.StorageEntry;
import kademlia.exceptions.ContentNotFoundException; import kademlia.exceptions.ContentNotFoundException;
import kademlia.exceptions.RoutingException; import kademlia.exceptions.RoutingException;
@ -44,7 +44,7 @@ public interface KademliaNode
/** /**
* @return The DHT for this kad instance * @return The DHT for this kad instance
*/ */
public DHT getDHT(); public KademliaDHT getDHT();
/** /**
* @return The current KadConfiguration object being used * @return The current KadConfiguration object being used

View File

@ -22,7 +22,7 @@ import kademlia.util.serializer.KadSerializer;
* @author Joshua Kissoon * @author Joshua Kissoon
* @since 20140226 * @since 20140226
*/ */
public class DHT public class DHT implements KademliaDHT
{ {
private transient StoredContentManager contentManager; private transient StoredContentManager contentManager;
@ -38,29 +38,19 @@ public class DHT
this.initialize(); this.initialize();
} }
/** @Override
* Initialize this DHT to it's default state
*/
public final void initialize() public final void initialize()
{ {
contentManager = new StoredContentManager(); contentManager = new StoredContentManager();
} }
/** @Override
* Set a new configuration. Mainly used when we restore the DHT state from a file
*
* @param con The new configuration file
*/
public void setConfiguration(KadConfiguration con) public void setConfiguration(KadConfiguration con)
{ {
this.config = con; this.config = con;
} }
/** @Override
* Creates a new Serializer or returns an existing serializer
*
* @return The new ContentSerializer
*/
public KadSerializer<StorageEntry> getSerializer() public KadSerializer<StorageEntry> getSerializer()
{ {
if (null == serializer) if (null == serializer)
@ -71,15 +61,7 @@ public class DHT
return serializer; return serializer;
} }
/** @Override
* Handle storing content locally
*
* @param content The DHT content to store
*
* @return boolean true if we stored the content, false if the content already exists and is up to date
*
* @throws java.io.IOException
*/
public boolean store(StorageEntry content) throws IOException public boolean store(StorageEntry content) throws IOException
{ {
/* Lets check if we have this content and it's the updated version */ /* Lets check if we have this content and it's the updated version */
@ -141,47 +123,27 @@ public class DHT
} }
} }
@Override
public boolean store(KadContent content) throws IOException public boolean store(KadContent content) throws IOException
{ {
return this.store(new StorageEntry(content)); return this.store(new StorageEntry(content));
} }
/** @Override
* Retrieves a Content from local storage public StorageEntry retrieve(KademliaId key, int hashCode) throws FileNotFoundException, IOException, ClassNotFoundException
*
* @param key The Key of the content to retrieve
* @param hashCode The hash code of the content to retrieve
*
* @return A KadContent object
*/
private StorageEntry retrieve(KademliaId key, int hashCode) throws FileNotFoundException, IOException, ClassNotFoundException
{ {
String folder = this.getContentStorageFolderName(key); String folder = this.getContentStorageFolderName(key);
DataInputStream din = new DataInputStream(new FileInputStream(folder + File.separator + hashCode + ".kct")); DataInputStream din = new DataInputStream(new FileInputStream(folder + File.separator + hashCode + ".kct"));
return this.getSerializer().read(din); return this.getSerializer().read(din);
} }
/** @Override
* Check if any content for the given criteria exists in this DHT
*
* @param param The content search criteria
*
* @return boolean Whether any content exist that satisfy the criteria
*/
public boolean contains(GetParameter param) public boolean contains(GetParameter param)
{ {
return this.contentManager.contains(param); return this.contentManager.contains(param);
} }
/** @Override
* Retrieve and create a KadContent object given the StorageEntry object
*
* @param entry The StorageEntry used to retrieve this content
*
* @return KadContent The content object
*
* @throws java.io.IOException
*/
public StorageEntry get(StorageEntryMetadata entry) throws IOException, NoSuchElementException public StorageEntry get(StorageEntryMetadata entry) throws IOException, NoSuchElementException
{ {
try try
@ -201,16 +163,7 @@ public class DHT
throw new NoSuchElementException(); throw new NoSuchElementException();
} }
/** @Override
* Get the StorageEntry for the content if any exist,
* retrieve the KadContent from the storage system and return it
*
* @param param The parameters used to filter the content needed
*
* @return KadContent A KadContent found on the DHT satisfying the given criteria
*
* @throws java.io.IOException
*/
public StorageEntry get(GetParameter param) throws NoSuchElementException, IOException public StorageEntry get(GetParameter param) throws NoSuchElementException, IOException
{ {
/* Load a KadContent if any exist for the given criteria */ /* Load a KadContent if any exist for the given criteria */
@ -232,19 +185,13 @@ public class DHT
throw new NoSuchElementException(); throw new NoSuchElementException();
} }
/** @Override
* Delete a content from local storage
*
* @param content The Content to Remove
*
*
* @throws kademlia.exceptions.ContentNotFoundException
*/
public void remove(KadContent content) throws ContentNotFoundException public void remove(KadContent content) throws ContentNotFoundException
{ {
this.remove(new StorageEntryMetadata(content)); this.remove(new StorageEntryMetadata(content));
} }
@Override
public void remove(StorageEntryMetadata entry) throws ContentNotFoundException public void remove(StorageEntryMetadata entry) throws ContentNotFoundException
{ {
String folder = this.getContentStorageFolderName(entry.getKey()); String folder = this.getContentStorageFolderName(entry.getKey());
@ -288,20 +235,13 @@ public class DHT
return contentStorageFolder.toString(); return contentStorageFolder.toString();
} }
/** @Override
* @return A List of all StorageEntries for this node
*/
public List<StorageEntryMetadata> getStorageEntries() public List<StorageEntryMetadata> getStorageEntries()
{ {
return contentManager.getAllEntries(); return contentManager.getAllEntries();
} }
/** @Override
* Used to add a list of storage entries for existing content to the DHT.
* Mainly used when retrieving StorageEntries from a saved state file.
*
* @param ientries The entries to add
*/
public void putStorageEntries(List<StorageEntryMetadata> ientries) public void putStorageEntries(List<StorageEntryMetadata> ientries)
{ {
for (StorageEntryMetadata e : ientries) for (StorageEntryMetadata e : ientries)

View File

@ -0,0 +1,122 @@
package kademlia.dht;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.List;
import java.util.NoSuchElementException;
import kademlia.KadConfiguration;
import kademlia.exceptions.ContentNotFoundException;
import kademlia.node.KademliaId;
import kademlia.util.serializer.KadSerializer;
/**
* The main Distributed Hash Table interface that manages the entire DHT
*
* @author Joshua Kissoon
* @since 20140523
*/
public interface KademliaDHT
{
/**
* Initialize this DHT to it's default state
*/
public void initialize();
/**
* Set a new configuration. Mainly used when we restore the DHT state from a file
*
* @param con The new configuration file
*/
public void setConfiguration(KadConfiguration con);
/**
* Creates a new Serializer or returns an existing serializer
*
* @return The new ContentSerializer
*/
public KadSerializer<StorageEntry> getSerializer();
/**
* Handle storing content locally
*
* @param content The DHT content to store
*
* @return boolean true if we stored the content, false if the content already exists and is up to date
*
* @throws java.io.IOException
*/
public boolean store(StorageEntry content) throws IOException;
public boolean store(KadContent content) throws IOException;
/**
* Retrieves a Content from local storage
*
* @param key The Key of the content to retrieve
* @param hashCode The hash code of the content to retrieve
*
* @return A KadContent object
*
* @throws java.io.FileNotFoundException
* @throws java.lang.ClassNotFoundException
*/
public StorageEntry retrieve(KademliaId key, int hashCode) throws FileNotFoundException, IOException, ClassNotFoundException;
/**
* Check if any content for the given criteria exists in this DHT
*
* @param param The content search criteria
*
* @return boolean Whether any content exist that satisfy the criteria
*/
public boolean contains(GetParameter param);
/**
* Retrieve and create a KadContent object given the StorageEntry object
*
* @param entry The StorageEntry used to retrieve this content
*
* @return KadContent The content object
*
* @throws java.io.IOException
*/
public StorageEntry get(StorageEntryMetadata entry) throws IOException, NoSuchElementException;
/**
* Get the StorageEntry for the content if any exist.
*
* @param param The parameters used to filter the content needed
*
* @return KadContent A KadContent found on the DHT satisfying the given criteria
*
* @throws java.io.IOException
*/
public StorageEntry get(GetParameter param) throws NoSuchElementException, IOException;
/**
* Delete a content from local storage
*
* @param content The Content to Remove
*
*
* @throws kademlia.exceptions.ContentNotFoundException
*/
public void remove(KadContent content) throws ContentNotFoundException;
public void remove(StorageEntryMetadata entry) throws ContentNotFoundException;
/**
* @return A List of all StorageEntries for this node
*/
public List<StorageEntryMetadata> getStorageEntries();
/**
* Used to add a list of storage entries for existing content to the DHT.
* Mainly used when retrieving StorageEntries from a saved state file.
*
* @param ientries The entries to add
*/
public void putStorageEntries(List<StorageEntryMetadata> ientries);
}

View File

@ -1,8 +1,8 @@
package kademlia.message; package kademlia.message;
import java.io.IOException; import java.io.IOException;
import kademlia.JKademliaNode;
import kademlia.KadServer; import kademlia.KadServer;
import kademlia.KademliaNode;
/** /**
* Receives a ConnectMessage and sends an AcknowledgeMessage as reply. * Receives a ConnectMessage and sends an AcknowledgeMessage as reply.
@ -14,9 +14,9 @@ public class ConnectReceiver implements Receiver
{ {
private final KadServer server; private final KadServer server;
private final JKademliaNode localNode; private final KademliaNode localNode;
public ConnectReceiver(KadServer server, JKademliaNode local) public ConnectReceiver(KadServer server, KademliaNode local)
{ {
this.server = server; this.server = server;
this.localNode = local; this.localNode = local;

View File

@ -2,10 +2,10 @@ package kademlia.message;
import java.io.IOException; import java.io.IOException;
import java.util.NoSuchElementException; import java.util.NoSuchElementException;
import kademlia.JKademliaNode;
import kademlia.KadConfiguration; import kademlia.KadConfiguration;
import kademlia.KadServer; import kademlia.KadServer;
import kademlia.dht.DHT; import kademlia.KademliaNode;
import kademlia.dht.KademliaDHT;
/** /**
* Responds to a ContentLookupMessage by sending a ContentMessage containing the requested content; * Responds to a ContentLookupMessage by sending a ContentMessage containing the requested content;
@ -18,11 +18,11 @@ public class ContentLookupReceiver implements Receiver
{ {
private final KadServer server; private final KadServer server;
private final JKademliaNode localNode; private final KademliaNode localNode;
private final DHT dht; private final KademliaDHT dht;
private final KadConfiguration config; private final KadConfiguration config;
public ContentLookupReceiver(KadServer server, JKademliaNode localNode, DHT dht, KadConfiguration config) public ContentLookupReceiver(KadServer server, KademliaNode localNode, KademliaDHT dht, KadConfiguration config)
{ {
this.server = server; this.server = server;
this.localNode = localNode; this.localNode = localNode;

View File

@ -2,10 +2,10 @@ package kademlia.message;
import java.io.DataInputStream; import java.io.DataInputStream;
import java.io.IOException; import java.io.IOException;
import kademlia.JKademliaNode;
import kademlia.KadConfiguration; import kademlia.KadConfiguration;
import kademlia.KadServer; import kademlia.KadServer;
import kademlia.dht.DHT; import kademlia.KademliaNode;
import kademlia.dht.KademliaDHT;
/** /**
* Handles creating messages and receivers * Handles creating messages and receivers
@ -16,11 +16,11 @@ import kademlia.dht.DHT;
public class MessageFactory implements KademliaMessageFactory public class MessageFactory implements KademliaMessageFactory
{ {
private final JKademliaNode localNode; private final KademliaNode localNode;
private final DHT dht; private final KademliaDHT dht;
private final KadConfiguration config; private final KadConfiguration config;
public MessageFactory(JKademliaNode local, DHT dht, KadConfiguration config) public MessageFactory(KademliaNode local, KademliaDHT dht, KadConfiguration config)
{ {
this.localNode = local; this.localNode = local;
this.dht = dht; this.dht = dht;

View File

@ -2,9 +2,9 @@ package kademlia.message;
import java.io.IOException; import java.io.IOException;
import java.util.List; import java.util.List;
import kademlia.JKademliaNode;
import kademlia.KadConfiguration; import kademlia.KadConfiguration;
import kademlia.KadServer; import kademlia.KadServer;
import kademlia.KademliaNode;
import kademlia.node.Node; import kademlia.node.Node;
/** /**
@ -17,10 +17,10 @@ public class NodeLookupReceiver implements Receiver
{ {
private final KadServer server; private final KadServer server;
private final JKademliaNode localNode; private final KademliaNode localNode;
private final KadConfiguration config; private final KadConfiguration config;
public NodeLookupReceiver(KadServer server, JKademliaNode local, KadConfiguration config) public NodeLookupReceiver(KadServer server, KademliaNode local, KadConfiguration config)
{ {
this.server = server; this.server = server;
this.localNode = local; this.localNode = local;

View File

@ -1,9 +1,9 @@
package kademlia.message; package kademlia.message;
import java.io.IOException; import java.io.IOException;
import kademlia.JKademliaNode;
import kademlia.KadServer; import kademlia.KadServer;
import kademlia.dht.DHT; import kademlia.KademliaNode;
import kademlia.dht.KademliaDHT;
/** /**
* Receiver for incoming StoreContentMessage * Receiver for incoming StoreContentMessage
@ -15,10 +15,10 @@ public class StoreContentReceiver implements Receiver
{ {
private final KadServer server; private final KadServer server;
private final JKademliaNode localNode; private final KademliaNode localNode;
private final DHT dht; private final KademliaDHT dht;
public StoreContentReceiver(KadServer server, JKademliaNode localNode, DHT dht) public StoreContentReceiver(KadServer server, KademliaNode localNode, KademliaDHT dht)
{ {
this.server = server; this.server = server;
this.localNode = localNode; this.localNode = localNode;

View File

@ -5,7 +5,7 @@ import java.util.List;
import kademlia.JKademliaNode; import kademlia.JKademliaNode;
import kademlia.KadConfiguration; import kademlia.KadConfiguration;
import kademlia.KadServer; import kademlia.KadServer;
import kademlia.dht.DHT; import kademlia.dht.KademliaDHT;
import kademlia.dht.StorageEntryMetadata; import kademlia.dht.StorageEntryMetadata;
import kademlia.exceptions.ContentNotFoundException; import kademlia.exceptions.ContentNotFoundException;
import kademlia.message.Message; import kademlia.message.Message;
@ -23,10 +23,10 @@ public class ContentRefreshOperation implements Operation
private final KadServer server; private final KadServer server;
private final JKademliaNode localNode; private final JKademliaNode localNode;
private final DHT dht; private final KademliaDHT dht;
private final KadConfiguration config; private final KadConfiguration config;
public ContentRefreshOperation(KadServer server, JKademliaNode localNode, DHT dht, KadConfiguration config) public ContentRefreshOperation(KadServer server, JKademliaNode localNode, KademliaDHT dht, KadConfiguration config)
{ {
this.server = server; this.server = server;
this.localNode = localNode; this.localNode = localNode;

View File

@ -4,7 +4,7 @@ import java.io.IOException;
import kademlia.JKademliaNode; import kademlia.JKademliaNode;
import kademlia.KadConfiguration; import kademlia.KadConfiguration;
import kademlia.KadServer; import kademlia.KadServer;
import kademlia.dht.DHT; import kademlia.dht.KademliaDHT;
/** /**
* An operation that handles refreshing the entire Kademlia Systems including buckets and content * An operation that handles refreshing the entire Kademlia Systems including buckets and content
@ -17,10 +17,10 @@ public class KadRefreshOperation implements Operation
private final KadServer server; private final KadServer server;
private final JKademliaNode localNode; private final JKademliaNode localNode;
private final DHT dht; private final KademliaDHT dht;
private final KadConfiguration config; private final KadConfiguration config;
public KadRefreshOperation(KadServer server, JKademliaNode localNode, DHT dht, KadConfiguration config) public KadRefreshOperation(KadServer server, JKademliaNode localNode, KademliaDHT dht, KadConfiguration config)
{ {
this.server = server; this.server = server;
this.localNode = localNode; this.localNode = localNode;

View File

@ -5,8 +5,7 @@ import java.util.List;
import kademlia.JKademliaNode; import kademlia.JKademliaNode;
import kademlia.KadConfiguration; import kademlia.KadConfiguration;
import kademlia.KadServer; import kademlia.KadServer;
import kademlia.dht.DHT; import kademlia.dht.KademliaDHT;
import kademlia.dht.KadContent;
import kademlia.dht.StorageEntry; import kademlia.dht.StorageEntry;
import kademlia.message.Message; import kademlia.message.Message;
import kademlia.message.StoreContentMessage; import kademlia.message.StoreContentMessage;
@ -24,7 +23,7 @@ public class StoreOperation implements Operation
private final KadServer server; private final KadServer server;
private final JKademliaNode localNode; private final JKademliaNode localNode;
private final StorageEntry storageEntry; private final StorageEntry storageEntry;
private final DHT localDht; private final KademliaDHT localDht;
private final KadConfiguration config; private final KadConfiguration config;
/** /**
@ -34,7 +33,7 @@ public class StoreOperation implements Operation
* @param localDht The local DHT * @param localDht The local DHT
* @param config * @param config
*/ */
public StoreOperation(KadServer server, JKademliaNode localNode, StorageEntry storageEntry, DHT localDht, KadConfiguration config) public StoreOperation(KadServer server, JKademliaNode localNode, StorageEntry storageEntry, KademliaDHT localDht, KadConfiguration config)
{ {
this.server = server; this.server = server;
this.localNode = localNode; this.localNode = localNode;

View File

@ -12,6 +12,7 @@ import java.io.OutputStreamWriter;
import java.lang.reflect.Type; import java.lang.reflect.Type;
import java.util.List; import java.util.List;
import kademlia.dht.DHT; import kademlia.dht.DHT;
import kademlia.dht.KademliaDHT;
import kademlia.dht.StorageEntryMetadata; import kademlia.dht.StorageEntryMetadata;
/** /**
@ -38,7 +39,7 @@ import kademlia.dht.StorageEntryMetadata;
* *
* @since 20140310 * @since 20140310
*/ */
public class JsonDHTSerializer implements KadSerializer<DHT> public class JsonDHTSerializer implements KadSerializer<KademliaDHT>
{ {
private final Gson gson; private final Gson gson;
@ -54,7 +55,7 @@ public class JsonDHTSerializer implements KadSerializer<DHT>
} }
@Override @Override
public void write(DHT data, DataOutputStream out) throws IOException public void write(KademliaDHT data, DataOutputStream out) throws IOException
{ {
try (JsonWriter writer = new JsonWriter(new OutputStreamWriter(out))) try (JsonWriter writer = new JsonWriter(new OutputStreamWriter(out)))
{ {
@ -72,7 +73,7 @@ public class JsonDHTSerializer implements KadSerializer<DHT>
} }
@Override @Override
public DHT read(DataInputStream in) throws IOException, ClassNotFoundException public KademliaDHT read(DataInputStream in) throws IOException, ClassNotFoundException
{ {
try (DataInputStream din = new DataInputStream(in); try (DataInputStream din = new DataInputStream(in);
JsonReader reader = new JsonReader(new InputStreamReader(in))) JsonReader reader = new JsonReader(new InputStreamReader(in)))