@GET @Path("/predecessor-of/{param}") public NodeInfo findPredecessor(@PathParam("param") int id) { // Checks if the id searched for is greater/equal to this nodes ID, and smaller/equal than // successors nodes ID, in which case this node should be returned // if(id >= this.id && id < successorID()). if (this.id < id && successor.getID() >= id) { return thisNode; } // Check if successor is smaller than this node ID, and if searched ID is in between. If so // we're crossing the '0' line, and this node is predecessor // if(succID < this.id) // if(id > this.id || id < succID else if (successor.getID() < this.id) { // we are the highest id in the hood if (this.id < id || successor.getID() >= id) { return thisNode; } } // Special case, only this node in network else if (successor.getID() == this.id) { return thisNode; } // System.out.println(this.id + ": Routed to node " + successor.getID()); // return requestSender.findIdPredecessor(successor, id); // System.out.println(this.id + ": Routed to node " + closestPreceedingFinger(id).getID()); return requestSender.findIdPredecessor(closestPreceedingFinger(id), id); }
// Updates the finger table with the {param} ID node as potential finger @PUT @Path("/update/{param}") @Produces(MediaType.APPLICATION_JSON) public Response updateFingerTable(NodeInfo n, @PathParam("param") int fingerNr) { if (isInRange(n.getID(), thisNode.getID(), fingers[fingerNr].getID())) { fingers[fingerNr] = n; requestSender.updateFingerTable(predecessor, n, fingerNr); } return Response.status(200).entity(n).build(); }
public void takeResponsibilities() { String responsible = requestSender.takePhotonResponsibility(successor, thisNode.getID()); if (responsible.equals("true")) { System.out.println("Becoming new responsible node"); photonData = requestSender.getPhotonData(successor).getList(); updatePhoton(thisNode); // Begin being the responsible node } }
public NodeInfo closestPreceedingFinger(int id) { for (int i = 15; i >= 0; i--) { int fID = fingers[i].getID(); if (isInRange(fID, thisNode.getID(), id)) { return fingers[i]; } } // Returning this node here means something went wrong with the node routing, and it will loop // forever System.out.println("Shouldn't happen"); return thisNode; }
// Receive data from node responsible for data, for replication purposes @POST @Path("/sendPhotonData") @Consumes(MediaType.APPLICATION_JSON) public Response replicatePhotonData(PhotonData pd) { if (photonData.isEmpty()) { photonData = requestSender.getPhotonData(predecessor).getList(); } else { photonData.add(pd); } replicatedValue = pd.replica--; if (pd.replica > 0) { if (successor.getID() != thisNode.getID()) { requestSender.sendPhotonData(successor, pd); } } // System.out.println(thisNode.getPort() + " recieved bunch of data: " + photonData.toString()); return Response.status(200).entity(pd).build(); }
public void initFingerTable(String ip, int port) { // Set first finger, which is just immediate successor fingers[0] = successor; // Fill finger table NodeInfo recentFinger = fingers[0]; int nextFingerID = 0; for (int i = 1; i < 16; i++) { nextFingerID = (thisNode.getID() + (int) Math.pow(2, i)) % (int) Math.pow(2, 16); if (isInRange(nextFingerID, thisNode.getID(), recentFinger.getID())) { fingers[i] = recentFinger; } // ID searched is higher than our current finger, so we ask it to find the next one for us. else { recentFinger = requestSender.findIdSuccessor(ip, port, nextFingerID); fingers[i] = recentFinger; } } }
private void updateOthers() { requestSender.updateNodeSuccessor(predecessor, thisNode); requestSender.updateNodePredecessor(successor, thisNode); int preceedingNodeID; for (int i = 0; i < 16; i++) { preceedingNodeID = ((int) Math.pow(2, 16) + thisNode.getID() - (int) Math.pow(2, i)) % (int) Math.pow(2, 16); NodeInfo p = findPredecessor(preceedingNodeID); requestSender.updateFingerTable(p, thisNode, i); } }
// Finds the responsible node for the photon and updates it and the successor of it public void findResponsibleNode() { String photonJson = requestSender.findSpark(); try { JSONObject temp = new JSONObject(photonJson); JSONObject temp2 = temp.getJSONObject("coreInfo"); String deviceID = temp2.getString("deviceID"); int convertedID = Key.generate16BitsKey(deviceID); NodeInfo responsible = findSuccessor(convertedID); // NodeInfo resposibleSuccessor = requestSender.getNodeSuccessor(responsible); requestSender.updatePhoton(responsible); // requestSender.updatePhoton(resposibleSuccessor); System.out.println("PhotonID: " + convertedID); System.out.println("Responsible is:\n" + responsible.getID()); } catch (JSONException e) { e.printStackTrace(); } }
public void join(String ip, int port) { // n is existing known node to bootstrap into the network System.out.println(this.port + ": Joining"); // Initialize own successor/predecessors successor = requestSender.findIdSuccessor(ip, port, thisNode.getID()); // No ID needed for path predecessor = requestSender.getNodePredecessor(successor); takeResponsibilities(); // createTimerCheckPredecessor(); initFingerTable(ip, port); listenToRequests(); System.out.println(this.port + ": Listening"); // Update successors and predecessor with this node updateOthers(); System.out.println("Join complete!"); System.out.println("Check the node at status at " + thisNode.getIndex()); }
public void printTable() { for (NodeInfo n : fingers) { System.out.println(n.getIP() + ":" + n.getPort() + "/" + n.getID()); } }