From 5b3e01df4e814d98e6a0d4ffc5bb9c6dc032ba12 Mon Sep 17 00:00:00 2001 From: Joshua Kissoon Date: Tue, 1 Apr 2014 10:42:43 +0530 Subject: [PATCH] Fixed the bug "Getting content from reloaded node(Node whose state have been saved and re-loaded from file) NullPointerException". Wrote a test to show getting content from reloaded node --- src/kademlia/Kademlia.java | 1 + src/kademlia/dht/DHT.java | 39 ++++++++++--- src/kademlia/tests/SaveStateTest2.java | 79 ++++++++++++++++++++++++++ 3 files changed, 110 insertions(+), 9 deletions(-) create mode 100644 src/kademlia/tests/SaveStateTest2.java diff --git a/src/kademlia/Kademlia.java b/src/kademlia/Kademlia.java index 859a88c..5cddf76 100644 --- a/src/kademlia/Kademlia.java +++ b/src/kademlia/Kademlia.java @@ -185,6 +185,7 @@ public class Kademlia */ din = new DataInputStream(new FileInputStream(getStateStorageFolderName(ownerId, iconfig) + File.separator + "dht.kns")); DHT idht = new JsonDHTSerializer().read(din); + idht.setConfiguration(iconfig); return new Kademlia(ownerId, inode, ikad.getPort(), idht, iconfig); } diff --git a/src/kademlia/dht/DHT.java b/src/kademlia/dht/DHT.java index ccb10d6..0036cd1 100644 --- a/src/kademlia/dht/DHT.java +++ b/src/kademlia/dht/DHT.java @@ -15,6 +15,7 @@ import kademlia.exceptions.ContentExistException; import kademlia.exceptions.ContentNotFoundException; import kademlia.node.NodeId; import kademlia.serializer.JsonSerializer; +import kademlia.serializer.KadSerializer; /** * The main Distributed Hash Table class that manages the entire DHT @@ -26,16 +27,11 @@ public class DHT { private transient StorageEntryManager entriesManager; - private final transient JsonSerializer contentSerializer; - private final transient KadConfiguration config; + private transient KadSerializer contentSerializer = null; + private transient KadConfiguration config; private final String ownerId; - - { - contentSerializer = new JsonSerializer<>(); - } - public DHT(String ownerId, KadConfiguration config) { this.ownerId = ownerId; @@ -51,6 +47,31 @@ public class DHT entriesManager = new StorageEntryManager(); } + /** + * 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) + { + this.config = con; + } + + /** + * Creates a new Serializer or returns an existing serializer + * + * @return The new ContentSerializer + */ + public KadSerializer getContentSerializer() + { + if (null == contentSerializer) + { + contentSerializer = new JsonSerializer<>(); + } + + return contentSerializer; + } + /** * Handle storing content locally * @@ -68,7 +89,7 @@ public class DHT /* Now we store the content locally in a file */ String contentStorageFolder = this.getContentStorageFolderName(content.getKey()); DataOutputStream dout = new DataOutputStream(new FileOutputStream(contentStorageFolder + File.separator + sEntry.hashCode() + ".kct")); - contentSerializer.write(content, dout); + getContentSerializer().write(content, dout); } catch (ContentExistException e) { @@ -88,7 +109,7 @@ public class DHT { String folder = this.getContentStorageFolderName(key); DataInputStream in = new DataInputStream(new FileInputStream(folder + File.separator + hashCode + ".kct")); - return contentSerializer.read(in); + return getContentSerializer().read(in); } /** diff --git a/src/kademlia/tests/SaveStateTest2.java b/src/kademlia/tests/SaveStateTest2.java new file mode 100644 index 0000000..f01e52a --- /dev/null +++ b/src/kademlia/tests/SaveStateTest2.java @@ -0,0 +1,79 @@ +package kademlia.tests; + +import java.util.List; +import kademlia.Kademlia; +import kademlia.core.GetParameter; +import kademlia.dht.KadContent; +import kademlia.node.NodeId; + +/** + * Testing the save and retrieve state operations. + * Here we also try to look for content on a restored node + * + * @author Joshua Kissoon + * @since 20140309 + */ +public class SaveStateTest2 +{ + + public 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); + + /* Connecting 2 to 1 */ + System.out.println("Connecting Nodes 1 & 2"); + kad2.bootstrap(kad1.getNode()); + System.out.println(kad1); + System.out.println(kad2); + + DHTContentImpl c; + synchronized (this) + { + System.out.println("\n\n\n\nSTORING CONTENT 1\n\n\n\n"); + c = new DHTContentImpl(kad2.getOwnerId(), "Some Data"); + System.out.println(c); + kad1.putLocally(c); + } + + System.out.println(kad1); + System.out.println(kad2); + + /* Shutting down kad1 and restarting it */ + System.out.println("\n\n\nShutting down Kad 1 instance"); + kad1.shutdown(true); + + System.out.println("\n\n\nReloading Kad instance from file"); + kad1 = Kademlia.loadFromFile("JoshuaK"); + kad1.bootstrap(kad2.getNode()); + System.out.println(kad2); + + /* Trying to get a content stored on the restored node */ + GetParameter gp = new GetParameter(c.getKey(), kad2.getOwnerId(), c.getType()); + List content = kad2.get(gp, 1); + + if (!content.isEmpty()) + { + DHTContentImpl cc = (DHTContentImpl) content.get(0); + System.out.println("Content received: " + cc); + } + else + { + System.out.println("No Content found"); + } + } + + catch (Exception e) + { + e.printStackTrace(); + } + } + + public static void main(String[] args) + { + new SaveStateTest2(); + } +}