def findPred(self, key): if (self.fingerTable is None or len(self.fingerTable) == 0): raise ttypes.SystemException( "No finger table present for this node") if (key > self.id and key >= self.fingerTable[0].id and self.fingerTable[0].id < self.id): #This means key is between the largest node and the smallest node but it is larger than the largest node return self.node elif (key < self.id and key <= self.fingerTable[0].id and self.fingerTable[0].id < self.id): #this means key is between the largest node and the smallest node but it is smaller than the smallest node return self.node elif (key <= self.id or key > self.fingerTable[0].id): #ask the closest known pred node predNode = self.closestPred(key) if (predNode.id != self.id): #ask the pred node for the actual pred node transport = TSocket.TSocket(predNode.ip, int(predNode.port)) transport = TTransport.TBufferedTransport(transport) protocol = TBinaryProtocol.TBinaryProtocol(transport) client = FileStore.Client(protocol) transport.open() pred = client.findPred(key) transport.close() return pred else: return self.node else: return self.node
def writeFile(self, rfile): ''' Writes the file to the server dictionary, such that filename is key and RFile object is data. input : RFile rfile ''' # contentHash is useful in error detecting no use here. # saving dict{file_name_hash : RFile object} this will be usefull in locating files efficiently file_name_hash = _hl.sha256(rfile.meta.filename).hexdigest() test_node = self.findSucc(file_name_hash) #print("\nin server write : test_node"+str(test_node)+"self.node : "+str(self.node)) #print(test_node == self.node) if test_node == self.node: if file_name_hash not in self.dht_files: #if file already not in memory, save it with version = 0 meta = _tt.RFileMetadata() meta = rfile.meta meta.version= 0 meta.contentHash = _hl.sha256(rfile.content).hexdigest() w_file = _tt.RFile() w_file.meta = meta w_file.content = rfile.content self.dht_files[file_name_hash] = w_file else: # else if file already in memory version += 1 amd replace the content self.dht_files[file_name_hash].meta.version += 1 self.dht_files[file_name_hash].meta.content = rfile.content # requirements pdf doesn't say this. mention in the documentation self.dht_files[file_name_hash].meta.contentHash = _hl.sha256(rfile.content).hexdigest() else: raise _tt.SystemException(message="Server : "+str(self.node)+" doesn't own this file id.")
def findPred(self, file_id): ''' returns the preceding node of the node which keeps the file_id. input : sha256(file_name) file_id output: NodeID n ''' if not self.node_list: raise _tt.SystemException(message="Fingertable not set for the server : "+str(self.node)) # comparison between strings work(sha256().hexdigest()), check again with more examples. #print("\nin pred : "+str(self.node)+"\n\n") if self.node.id > self.node_list[0].id: if file_id > self.node.id or file_id <= self.node_list[0].id: return self.node # else can be removed but eases the readding. else: if file_id > self.node.id and file_id <= self.node_list[0].id: return self.node pred_node = None for i in reversed(range(-256, 0, 1)): if self.node_list[i].id > self.node.id: if self.node_list[i].id > self.node.id and self.node_list[i].id <= file_id: pred_node = self.node_list[i] break else: if file_id > self.node_list[i].id and file_id < self.node.id: pred_node = self.node_list[i] break if not pred_node: return self.node #print("\n\n=========After calculating pred_node===="+str(pred_node)+"\n\n") pred_node = create_pred_client(pred_node).findPred(file_id) return pred_node
def readFile(self, filename): if (filename not in self.files): raise ttypes.SystemException( "Given filename not present in this node") sha256 = hashlib.sha256() sha256.update(filename.encode('utf-8')) fileid = sha256.hexdigest() if (fileid <= self.pred.id or fileid > self.id): raise ttypes.SystemException( "Given filename not present in this node") readFile = open(filename, "r") content = readFile.read() readFile.close() metadata = ttypes.RFileMetadata(filename, self.files[filename]) rFile = ttypes.RFile(metadata, content) return rFile
def getNodeSucc(self): ''' returns the next active node in the DHT chord. output: NodeID n ''' if not self.node_list: raise _tt.SystemException(message="Fingertable not set for the server : "+str(self.node)) # this should work but the printed node list didn't seem like it return self.node_list[0]
def readFile(self, file_name): ''' Reads file from the server dictionary. input : string file_name output: RFile file_name ''' # inside the if rfile exists on this node block. file_name_hash = _hl.sha256(file_name).hexdigest() test_node = self.findSucc(file_name_hash) # __eq__ is implemented in init so it should work if test_node == self.node: if file_name_hash not in self.dht_files: ex = _tt.SystemException(message="No such file with this filename exists on this server!"+ str(self.node)) raise ex return self.dht_files[file_name_hash] raise _tt.SystemException(message="Server : "+str(self.node)+" doesn't own this file.")
def findSucc(self, key): if (self.fingerTable is None or len(self.fingerTable) == 0): raise ttypes.SystemException( "No finger table present for this node") if (key == self.id): return self.node pred = self.findPred(key) if (pred.id == self.id): return self.getNodeSucc() else: #ask pred node for its succesor and return it transport = TSocket.TSocket(pred.ip, int(pred.port)) transport = TTransport.TBufferedTransport(transport) protocol = TBinaryProtocol.TBinaryProtocol(transport) client = FileStore.Client(protocol) transport.open() succ = client.getNodeSucc() transport.close() return succ
def writeFile(self, rFile): rFileMeta = rFile.meta filename = rFileMeta.filename sha256 = hashlib.sha256() sha256.update(filename.encode('utf-8')) fileid = sha256.hexdigest() if (self.pred == None): self.pred = self.findPred(self.id) if (fileid <= self.pred.id or fileid > self.id): raise ttypes.SystemException( "File id does not belong to this node") if (filename in self.files): self.files[filename] += 1 else: self.files[filename] = 0 fileWrite = open(filename, "w") fileWrite.write(rFile.content) fileWrite.flush() fileWrite.close()
def setFingertable(self, node_list): ''' Sets server's finger table to node_list. input : list<NodeID> node_list ''' try: self.node_list = node_list #print self.node_list except: ex = _tt.SystemException(message="Could not set finger table for node : "+ str(self.node)) raise ex # If you want to have a better look at fingertables of all nodes uncomment the following if else block if 'nodes.txt' not in os.listdir(os.getcwd()): test_file = open('nodes.txt', 'w+') test_file.write("\n\n----begin----\n\n"+str(self.node_list)+"\n\n----END---\n\n") test_file.close() else: test_file = open('nodes.txt', 'a') test_file.write("\n\n----"+str(self.node)+"----\n\n"+str(self.node_list)+"\n\n----END---\n\n") test_file.close()
def getNodeSucc(self): if (self.fingerTable is None or len(self.fingerTable) == 0): raise ttypes.SystemException( "No finger table present for this node") return self.fingerTable[0]