Beispiel #1
0
        def deleteUpdate(nodeID, path, session):
            try:
                print "Node " + str(
                    nodeID) + " has successfully deleted " + str(path)
                if path in self.reg.data:
                    if session.finished():
                        print "Deletion complete!"
                        rec = self.reg.data.pop(path)

                        response = ClientResponse(type=ClientRequestType.rm,
                                                  output="Deletion Success",
                                                  success=True)
                        session.clientsocket.send(response.toJson())
                        session.clientsocket.close()
                        session.mutex.release()
                        print "All filenodes have deleted " + path + " -- Disconnecting from client"
                        if path in self.sessions:
                            del self.sessions[path]
                    else:
                        session.mutex.release()
                else:
                    raise DFSError("Deletion update for " + str(path) + \
                                   ", which does not exist on master.")
            except Exception as e:
                raise DFSError("Exception with name " + str(e) +
                               " raised in handleNodeUpdate/deleteUpdate")
Beispiel #2
0
def readJSONFromSock(sock, addr):
    data = ''
    timeout_seconds = 60
    wait_until = datetime.datetime.now() + timedelta(seconds=timeout_seconds)
    while True:
        try:
            data += sock.recv(BUFSIZE)
            obj = json.loads(data)
            break
        except socket.error as ex:
            print "Error reading from socket -- connection may have broken."
            sock.close()
            raise DFSError("Socket broken in readJSONFromSock.")
            return
        except Exception as ex:
            if wait_until < datetime.datetime.now():
                print "READ TIMED OUT."
                sock.close()
                return
            time.sleep(WAIT_INTERVAL)
            continue

    if not data: raise DFSError("No data recieved in readJSONFromSock")
    # print str(obj)
    return obj
Beispiel #3
0
    def handleConnection(self, sock, address):

        try:
            request = readJSONFromSock(sock, address)
        except:
            print "Error getting data from " + str(address) + " in 'handleConnection'"
            print "Closing socket."
            sock.close()

        # handle request
        try:
            if not 'type' in request:
                raise DFSError("Bad request to filenode recieved from " + str(address))

            type = request['type']

            if  type  is ReqType.store:
                self.handleFileStore(sock, address, request)

            elif type is ReqType.retrieve:
                self.handleFileRetrieve(sock, address, request)

            elif type is ReqType.delete:
                self.handleFileDelete(sock, address, request)

            elif type is ReqType.copy:
                self.handleFileCopy(sock, address, request)

            elif type is ReqType.n2ncopy:
                self.handleExternalFileCopy(sock, address, request)

            elif type is ReqType.rename:
                self.handleRename(sock, address, request)

            elif type is ReqType.m2n_kill:
                self.handleKill(sock, address, request)

            elif type is ReqType.ping:
                self.handleStatusCheck(sock, address, request)

            else:
                raise DFSError("Invalid request to file node from " + str(address))

        except Exception as ex:
            print "An exception in 'handleConnection' with name \n" + str(ex) + \
                  "\n was raised. Closing socket...\n"
            sock.close()
            return
Beispiel #4
0
        def uploadUpdate(nodeID, path, session):
            try:
                if path not in self.reg.data:
                    session.dir.files.add(path.split('/')[-1])
                    rec = DataRecord(path, [nodeID], session.checksum)
                    self.reg.addFile(rec)
                else:
                    self.reg.data[path].nodeIDList.append(nodeID)

                print "Node " + str(
                    nodeID) + " has received " + path + " successfully."

                if session.finished():
                    print "All filenodes have received " + path + "\nDisconnecting from client."
                    response = ClientResponse(type=ClientRequestType.upload,
                                              output="Upload Success",
                                              success=True)
                    session.clientsocket.send(response.toJson())
                    session.clientsocket.close()
                    session.mutex.release()
                    if path in self.sessions:
                        del self.sessions[path]
                else:
                    session.mutex.release()

            except Exception as e:
                raise DFSError("Exception with name " + str(e) +
                               " raised in handleNodeUpdate/uploadUpdate")
Beispiel #5
0
    def handleFileDelete(self, socket, address, request):
        print "FILE DELETE: " + str(request)
        try:
            if 'path' in request:
                path = request['path']
                hashpath = self.hashForPath(path)
                socket.close()
                rawfpath = self.dirpath + '/' + hashpath + RAWFILE_EXT
                metapath = self.dirpath + '/' + hashpath + META_EXT

                if os.path.isfile(rawfpath) and os.path.isfile(metapath):

                    os.remove(rawfpath)
                    os.remove(metapath)
                    req = Request(ReqType.n2m_update, data = self.nodeID,
                                  path = path, status = True)
                    print "Deletion success for " + str(path)
                else:
                    print "Deletion failure for " + str(path)
                    self.failureUpdate()
                    msock.close()
                    return
                msock = self.reqToMaster(req.toJson())
                msock.close()


            else:
                print "Request to delete sent with malformed request."
                print "Closing socket."

        except Exception as ex:
            raise DFSError("Error in 'handleFileDelete'" + " with value " + str(ex))
        socket.close()
Beispiel #6
0
    def uploadToNode(self, hashed_path, plaintext_path, node_address):

        def connectToNode(node_address):
            s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
            s.connect(node_address)
            return s

        def messageSocket(s, message):
            s.send(message.toJson())
            return readJSONFromSock(s, str(s.getpeername()))

        with io.open(hashed_path, 'rb') as file:
            size = os.path.getsize(hashed_path)
            s = connectToNode(node_address)
            res = messageSocket(s, Request(ReqType.store,
                                            path = plaintext_path, length = size))

            print "Sending data transfer request to filenode..."
            if res and 'type' in res and res['type'] is ResType.ok:
                pass
            else:
                print "Did not receive ack from filenode"
                raise DFSError("No ack from filenode in 'handleExternalFileCopy'")

            print "Sending data to filenode..."
            while True:
                data = file.read(setup.BUFSIZE)
                if data:
                    s.send(data)
                else:
                    break
            s.close()
Beispiel #7
0
 def reqToMaster(self, request):
     try:
         sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
         sock.connect(setup.MASTER_NODE_ADDR)
         sock.send(request)
     except socket.error as e:
         raise DFSError("Socket error in 'reqToMaster'" + \
                        " with value " + str(e) + " in function 'reqToMaster'.")
     return sock
Beispiel #8
0
 def handleCopyRequest(self, socket, newpath, oldpath):
     pass
     try:
         command = ['cd', path]
         output = viewer.process(len(command), command)
         if output != None:
             command = 'mkdir ' + dirname
             self.handleViewerRequest(socket, viewer, command)
     except Exception as e:
         raise DFSError("Exception raised in 'handleCopyRequest': \n" +
                        str(ex))
Beispiel #9
0
 def __init__(self, filepath, nodeIDList, dataChecksum):
     try:
         self.filepath = filepath
         self.nodeIDList = nodeIDList
         self.dataChecksum = dataChecksum
         self.timecreated = time.time()
         self.timemodified = self.timecreated
         self.timeaccessed = self.timecreated
         self.checksum = dataChecksum
     except Exception as e:
         raise DFSError("Error initializing DataRecord for file " +
                        str(filepath) + " with exception " + str(e))
Beispiel #10
0
    def handleClientRequest(self, socket, address):

        viewer = Viewer(self.root)

        while True:
            try:
                data = socket.recv(setup.BUFSIZE)
                if data:
                    request = json.loads(data)
                    if 'type' in request:
                        # print "Raw Client Request: \n " + str(request)
                        self.processClientRequest(socket, request,
                                                  request['type'], viewer)
                    else:
                        raise DFSError("Invalid Client Request")
                else:
                    raise DFSError("Client disconnected")
            except Exception as ex:
                print "Exception raised in 'handleClientRequest': \n" + str(ex)
                print "Disconnecting client."
                socket.close()
                return
Beispiel #11
0
    def handleFileRetrieve(self, socket, address, request):
        # get file from storage
        # send it in chunks that won't be too big for ram
        try:
            path = request['path']
            print "Received download request for " + path
            pathHashStr = self.hashForPath(path)
            chunkFilename = self.dirpath + '/' + pathHashStr + RAWFILE_EXT
            print chunkFilename
            # TODO: Convert path to filenode file scheme to get the file, then send to client

            with open(chunkFilename, 'rb') as file:
                size = os.path.getsize(chunkFilename)
                ack = Response(ResType.ok, path=path, length=size)
                socket.send(ack.toJson())

                res = readJSONFromSock(socket, address)
                if res and 'type' in res and res['type'] is ResType.ok:
                    pass
                else:
                    raise DFSError("Did not receive ack from client")

                self.log.insert(0, SessionLog('download', size))

                print "Sending data to client"
                while True:
                    data = file.read(setup.BUFSIZE)
                    if data:
                        socket.send(data)
                    else:
                        break

        except Exception as ex:
            raise DFSError("Socket error in 'handleFileRetrieve'" + \
                           " with value " + str(ex) + " in function 'handleFileRetrieve'.")

        socket.close()
Beispiel #12
0
    def confirmDeletion(sock):
        while True:
            print "Waiting for deletion confirmation from Master..."
            res = readJSONFromSock(s, 'masternode')

            if 'type' not in res or res['type'] is not ClientRequestType.rm:
                raise DFSError("Recieved response of incorrect type from Master.")

            if 'success' in res and res['success']:
                print "File deletion completed with message: " + str(res['output'])
                sys.exit()
            else:
                print "File deletion unsuccessful. Retrying..."
                addrs = zip(res['address'], res['port'])
                [deleteFromNode(address, server_file_path) for address in addrs]
Beispiel #13
0
    def handleExternalFileCopy(self, socket, address, request):

        try:
            if 'path' in request and 'data' in request:
                plainpath = request['path']
                addrs = request['data']
                if 'address' in addrs and 'port' in addrs:
                    ips = addrs['address']
                    ports = addrs['port']
                else:
                    self.failureUpdate(plainpath)
                    socket.close()
                    return

                print "Performing external file copy of " + str(plainpath) + " to " + str(addrs)
                hashpath = self.hashForPath(plainpath)
                rawfpath = self.dirpath + '/' + hashpath + RAWFILE_EXT

                if os.path.isfile(rawfpath):
                    target = self.uploadToNode
                    adds = [pair for pair in zip(ips, ports)]
                    for ad in adds:
                        args = [rawfpath, plainpath, ad]
                        uploadThread = Thread(target = target, args = args)
                        uploadThread.start()

                    # wait for server to tell you that it worked. if not,
                    # resend the file
                    while True:
                        res = readJSONFromSock(socket, setup.MASTER_NODE_ADDR)
                        if res:
                            print res['output']
                            if res['success']:
                                break
                            else:
                                address = (res['address'], res['port'])
                                args = [rawfpath, plainpath, address]
                                uploadThread = Thread(target = target, args = args)
                                uploadThread.start()

                else:
                    self.failureUpdate(plainpath)
            else:
                self.failureUpdate('unknown_path')

        except Exception as e:
            raise DFSError("Error in 'handleExternalFileCopy' with value " + str(e))
        socket.close()
Beispiel #14
0
        def deleteRetry(nodeID, path, session):
            try:
                print "Node " + str(nodeID) + " failed to delete " + str(path) +\
                      "\n File was already deleted."
                if session.finished():
                    session.mutex.release()
                    del self.sessions[path]
                    response = ClientResponse(ClientRequestType.rm,
                                              output="File deleted: " +
                                              str(path),
                                              success=True)
                    session.clientsocket.send(response.toJson())
                else:
                    session.mutex.release()

            except Exception as e:
                raise DFSError("Exception with name " + str(e) +
                               " raised in handleNodeUpdate/deleteRetry")
Beispiel #15
0
def stat(server_file_path):
    try:
        req = ClientRequest(type = ClientRequestType.stat,
                        serverPath = server_file_path,
                        name = '')
        s = connect_to_master()
        s.send(req.toJson())
        res = readJSONFromSock(s, 'masternode')
        if 'success' in res and res['success'] and 'output' in res:
            print res['output']
        elif not res['success']:
            print "STAT Failure."
            if 'output' in res: print res['output']

    except Exception as e:
        DFSError("Error raised in 'stat' due to exception \n" + str(ex) +
                 "\nShutting down.")
        sys.exit()
Beispiel #16
0
def rm(server_file_path):

    def deleteFromNode(address, server_file_path):
        filenodesock = connect_to_node(address)
        req = FileRequest(FileRequestType.delete, path = server_file_path)
        filenodesock.send(req.toJson())

    def confirmDeletion(sock):
        while True:
            print "Waiting for deletion confirmation from Master..."
            res = readJSONFromSock(s, 'masternode')

            if 'type' not in res or res['type'] is not ClientRequestType.rm:
                raise DFSError("Recieved response of incorrect type from Master.")

            if 'success' in res and res['success']:
                print "File deletion completed with message: " + str(res['output'])
                sys.exit()
            else:
                print "File deletion unsuccessful. Retrying..."
                addrs = zip(res['address'], res['port'])
                [deleteFromNode(address, server_file_path) for address in addrs]

    try:
        req = ClientRequest(ClientRequestType.rm, serverPath = server_file_path, name = '')
        s = connect_to_master()
        s.send(req.toJson())
        res = readJSONFromSock(s, 'mastenode')
        if 'success' in res and res['success']:
            addrs = zip(res['address'], res['port'])
            [deleteFromNode(address, server_file_path) for address in addrs]
            confirmDeletion(s)


        else:
            output = res['output'] if 'output' in res else None
            print output
            raise DFSError("RM failed due to failure response from server with value: " + str(output))

    except Exception as e:
        print "Error in RM while trying to remove " + str(server_file_path) + " because: "
        print str(e)
        print "Aborting..."
        sys.exit()
Beispiel #17
0
    def handleFileDeleteRequest(self, socket, path, name):
        # find all active nodes with file
        # open sessions for file removal
        # tell client to send remove signals to those files
        try:

            fullpath = path + name
            if self.validPath(fullpath):

                nids = self.reg.data[fullpath].nodeIDList
                nids = [n for n in nids if n in self.reg.activenodes]
                ips = [self.reg.activenodes[n].address[0] for n in nids]
                ports = [self.reg.activenodes[n].address[1] for n in nids]
                self.waitForSessionClose(fullpath)
                session = Session(path=fullpath,
                                  type='delete',
                                  nodeIDs=nids,
                                  clientsocket=socket,
                                  dir=self.root.cd(fullpath[1:].split('/')))
                self.sessionmutex.acquire()
                self.sessions[fullpath] = session
                self.sessionmutex.release()
                res = ClientResponse(ClientRequestType.rm,
                                     output='Delete Request for ' +
                                     str(fullpath) + ' received',
                                     success=True,
                                     address=ips,
                                     port=ports)
                print "Delete request for existing file " + str(fullpath) + \
                      " recieved. Directing client to delete on nodes " + str(nids)
            else:
                res = ClientResponse(ClientRequestType.rm,
                                     output='Error removing ' + str(fullpath) +
                                     '. File not found.',
                                     success=False)
                print "Remove request failed. File " + str(
                    fullpath) + " not found."
            socket.send(res.toJson())

        except Exception as e:
            raise DFSError(
                ("Exception raised in 'handleFileDeleteRequest: \n" + str(e)))
Beispiel #18
0
    def wakeup(self):

        dirs = os.walk(NODE_FILEPATH).next()[1] # list of directories
        if self.mode == 'fresh':
            ids = []
        else:
            ids = [int(re.findall('\d+', d).pop()) for d in dirs]
        data = {'ids': ids, 'port': self.server.port}
        request = Request(ReqType.n2m_wakeup, data).toJson()
        clientsocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

        try:

            clientsocket.connect(setup.MASTER_NODE_ADDR)
            clientsocket.send(request)
            print "ID REQUEST: " + request
            response = readJSONFromSock(clientsocket, setup.MASTER_NODE_ADDR)

            if not 'type' in response:
                raise DFSError("Master sent bad response.")

            if response['type'] is ResType.m2n_wakeres:
                nodeID = int(response['data'])

            elif response['type'] is ResType.m2n_kill:
                print "Recieved shutdown signal from masternode. Shutting down."
                sys.exit()

            else:
                print "Recieved invalid response type from masternode."
                sys.exit()

        except Exception, ex:

            print "Unable to obtain filenode ID becuase exception \n" + \
                   str(ex) + "\n" + " was raised. Shutting down."
            sys.exit()
Beispiel #19
0
        def uploadRetry(nodeID, path, session):
            try:
                print "Node " + str(nodeID) + " failed the upload for " + path
                if session.nTriesLeft > 0:
                    node = self.reg.activenodes[nodeID]
                    response = ClientResponse(type=ClientRequestType.upload,
                                              output="Retrying Upload...",
                                              success=False,
                                              address=node.address[0],
                                              port=node.address[1])
                    session.nTriesLeft = session.nTriesLeft - 1
                    session.clientsocket.send(response.toJson())
                    session.mutex.release()
                else:
                    print "Upload out of tries."
                    if path in self.reg.data:
                        print "File " + str(path) + " under replicated."
                        response = ClientResponse(
                            type=ClientRequestType.upload,
                            output="Upload soft failure. " + str(path) +
                            " under-replicated.",
                            success=True)
                        session.clientsocket.send(response.toJson())
                    else:
                        print "File " + str(
                            path) + " not stored in filesystem."
                        response = ClientResponse(
                            type=ClientRequestType.upload,
                            output="UPLOAD " + str(path) + "ABORTED.",
                            success=True)
                        session.clientsocket.send(response.toJson())
                    session.mutex.release()
                    del self.sessions[path]

            except Exception as e:
                raise DFSError("Exception with name " + str(e) +
                               " raised in handleNodeUpdate/uploadRetry")
Beispiel #20
0
    def handleUploadRequest(self, socket, path, filesize, filename, checksum):
        def error(message):
            response = ClientResponse(ClientRequestType.upload, message, False)
            socket.send(response.toJson())
            tprint("Upload Failed: " + message)

        tprint("Received Request to upload " + filename + " (" +
               str(filesize) + ") to " + str(path))

        if path[0] == '/':
            dir = self.root.cd(path[1:].split('/'))
            if dir:
                try:
                    tprint("Sending upload ACK to client")
                    nodes = self.priorityQueue()[:setup.NODES_PER_FILE]
                    for node in nodes:
                        node.hits += 1
                    addrs = [node.address[0] for node in nodes]
                    ports = [node.address[1] for node in nodes]
                    response = ClientResponse(type=ClientRequestType.upload,
                                              output="Initiating Upload...",
                                              success=True,
                                              address=addrs,
                                              port=ports)

                    tprint(
                        "Sending upload info to client for the following nodes:"
                    )
                    for node in nodes:
                        print node.address
                    serverFile = path + '/' + filename if path[
                        -1] != '/' else path + filename

                    ids = [node.id for node in nodes]
                    session = Session(path=serverFile,
                                      type='upload',
                                      nodeIDs=ids,
                                      clientsocket=socket,
                                      dir=dir,
                                      checksum=checksum)
                    self.waitForSessionClose(
                        serverFile)  # to avoid session overlap
                    self.sessionmutex.acquire()
                    self.sessions[serverFile] = session
                    self.sessionmutex.release()
                    socket.send(response.toJson())
                    tprint("Upload info sent to client.")

                    if serverFile in self.reg.data:
                        del self.reg.data[serverFile]

                except Exception as ex:
                    raise DFSError(
                        "Exception raised in 'handleUploadRequest': \n" +
                        str(ex))
            else:
                response = ClientResponse(type=ClientRequestType.upload,
                                          output="Invalid directory path",
                                          success=False)
                socket.send(response.toJson())
                error("Directory path was not found")
        else:
            error("Directory must start with '/'")
Beispiel #21
0
 def failureUpdate(self, path, sock):
     raise DFSError("Failure when performing an action on " + str(path))
Beispiel #22
0
    def handleNodeUpdate(self, socket, request):
        def uploadUpdate(nodeID, path, session):
            try:
                if path not in self.reg.data:
                    session.dir.files.add(path.split('/')[-1])
                    rec = DataRecord(path, [nodeID], session.checksum)
                    self.reg.addFile(rec)
                else:
                    self.reg.data[path].nodeIDList.append(nodeID)

                print "Node " + str(
                    nodeID) + " has received " + path + " successfully."

                if session.finished():
                    print "All filenodes have received " + path + "\nDisconnecting from client."
                    response = ClientResponse(type=ClientRequestType.upload,
                                              output="Upload Success",
                                              success=True)
                    session.clientsocket.send(response.toJson())
                    session.clientsocket.close()
                    session.mutex.release()
                    if path in self.sessions:
                        del self.sessions[path]
                else:
                    session.mutex.release()

            except Exception as e:
                raise DFSError("Exception with name " + str(e) +
                               " raised in handleNodeUpdate/uploadUpdate")

        def deleteUpdate(nodeID, path, session):
            try:
                print "Node " + str(
                    nodeID) + " has successfully deleted " + str(path)
                if path in self.reg.data:
                    if session.finished():
                        print "Deletion complete!"
                        rec = self.reg.data.pop(path)

                        response = ClientResponse(type=ClientRequestType.rm,
                                                  output="Deletion Success",
                                                  success=True)
                        session.clientsocket.send(response.toJson())
                        session.clientsocket.close()
                        session.mutex.release()
                        print "All filenodes have deleted " + path + " -- Disconnecting from client"
                        if path in self.sessions:
                            del self.sessions[path]
                    else:
                        session.mutex.release()
                else:
                    raise DFSError("Deletion update for " + str(path) + \
                                   ", which does not exist on master.")
            except Exception as e:
                raise DFSError("Exception with name " + str(e) +
                               " raised in handleNodeUpdate/deleteUpdate")

        def uploadRetry(nodeID, path, session):
            try:
                print "Node " + str(nodeID) + " failed the upload for " + path
                if session.nTriesLeft > 0:
                    node = self.reg.activenodes[nodeID]
                    response = ClientResponse(type=ClientRequestType.upload,
                                              output="Retrying Upload...",
                                              success=False,
                                              address=node.address[0],
                                              port=node.address[1])
                    session.nTriesLeft = session.nTriesLeft - 1
                    session.clientsocket.send(response.toJson())
                    session.mutex.release()
                else:
                    print "Upload out of tries."
                    if path in self.reg.data:
                        print "File " + str(path) + " under replicated."
                        response = ClientResponse(
                            type=ClientRequestType.upload,
                            output="Upload soft failure. " + str(path) +
                            " under-replicated.",
                            success=True)
                        session.clientsocket.send(response.toJson())
                    else:
                        print "File " + str(
                            path) + " not stored in filesystem."
                        response = ClientResponse(
                            type=ClientRequestType.upload,
                            output="UPLOAD " + str(path) + "ABORTED.",
                            success=True)
                        session.clientsocket.send(response.toJson())
                    session.mutex.release()
                    del self.sessions[path]

            except Exception as e:
                raise DFSError("Exception with name " + str(e) +
                               " raised in handleNodeUpdate/uploadRetry")

        def deleteRetry(nodeID, path, session):
            try:
                print "Node " + str(nodeID) + " failed to delete " + str(path) +\
                      "\n File was already deleted."
                if session.finished():
                    session.mutex.release()
                    del self.sessions[path]
                    response = ClientResponse(ClientRequestType.rm,
                                              output="File deleted: " +
                                              str(path),
                                              success=True)
                    session.clientsocket.send(response.toJson())
                else:
                    session.mutex.release()

            except Exception as e:
                raise DFSError("Exception with name " + str(e) +
                               " raised in handleNodeUpdate/deleteRetry")

        try:
            if 'data' not in request or 'path' not in request or 'chksum' not in request or 'status' not in request:
                raise DFSError("Bad update from filenode sent to Master.")

            nodeID = request['data']
            path = request['path']
            checksum = request['chksum']
            status = request['status']

            if path in self.sessions:
                session = self.sessions[path]
                session.mutex.acquire()
            else:
                raise DFSError(
                    "Got Node Update for file that is not in session.")

            if status and session.verify(checksum, nodeID):
                session.nodeIDs.remove(nodeID)
                if session.type is 'upload':
                    uploadUpdate(nodeID, path, session)
                elif session.type is 'delete':
                    deleteUpdate(nodeID, path, session)
            elif session.type is 'upload':
                uploadRetry(nodeID, path, session)
            elif session.type is 'delete':
                deleteRetry(nodeID, path, session)

        except Exception, ex:
            print "An exception in 'handleNodeUpdate' with name \n" + str(ex) + \
                  "\n was raised. Sending shutdown signal to filenode."
Beispiel #23
0
    def handleFileStore(self, clientSocket, address, request):

        try:
            if not ('len' in request and 'path' in request):
                raise DFSError("Incorrect fields present in STORE JSON.")

            elif request['len'] is None or request['path'] is None:
                raise DFSError("Len and path fields initialized to None in STORE JSON")

            nBytesExpected = request['len']
            if not isinstance(nBytesExpected, int):
                raise DFSError("Len field is not an integer in STORE request from " + str(address))

            # hash filepath to get file handle
            path = request['path']
            pathHashStr = self.hashForPath(path)
            chunkFilename = self.dirpath + '/' + pathHashStr + RAWFILE_EXT
            metaFilename  = self.dirpath + '/' + pathHashStr + META_EXT

            res = Response(ResType.ok)
            clientSocket.send(res.toJson())

            # read in the file
            nRecvd = 0
            h = hashlib.md5()
            with io.open(chunkFilename, 'wb') as cFile:

                while nRecvd < nBytesExpected:

                    newBytes = clientSocket.recv(setup.BUFSIZE)
                    nRecvd = nRecvd + len(newBytes)
                    print "Received " + str(nRecvd) + " of " + str(nBytesExpected) + " bytes"
                    encodedBytes = bytearray(newBytes)
                    n = cFile.write(encodedBytes)
                    h.update(encodedBytes)

            dataChecksum = h.hexdigest()

            with io.open(metaFilename, 'wb') as mFile:
                metadata = {'checksum': dataChecksum}
                mFile.write(str(metadata))

            print "Done writing file " + str(path) + " to disk..."

            # Log new file download
            self.log.insert(0, SessionLog('upload', nBytesExpected))

            # send a hash of the new file to the server to confirm integrity
            request = Request(ReqType.n2m_update,
                              data = self.nodeID,
                              path = path,
                              status = True,
                              chksum = dataChecksum).toJson()

            # wait for verification response
            mastersock = self.reqToMaster(request)
            mastersock.close()

            clientSocket.close()

        except Exception as ex:
            print "An exception in 'handleFileStore' with name \n" + str(ex) + \
                  "\n was raised. Closing socket...\n"
            clientSocket.close()
            try:
                request = Request(ReqType.n2m_update,
                                  data = self.nodeID,
                                  path = path,
                                  status = False,
                                  chksum = dataChecksum).toJson()

                # wait for verification response
                mastersock = self.reqToMaster(request)
                mastersock.close()
            except Exception as ex:
                raise DFSError("Error sending failure update to master in " + \
                               "handleFileStore")
Beispiel #24
0
    def processClientRequest(self, socket, request, type, viewer):

        if type is ClientRequestType.viewer:
            if 'command' in request:
                command = request['command']
                self.handleViewerRequest(socket, viewer, command)
            else:
                raise DFSError(
                    ("Exception raised in 'processClientRequest/viewer': \n" +
                     str(ex)))

        elif type is ClientRequestType.download:
            try:
                path = request['serverPath']
                self.handleDownloadRequest(socket, path)
            except Exception as ex:
                raise DFSError((
                    "Exception raised in 'processClientRequest/download': \n" +
                    str(ex)))

        elif type is ClientRequestType.upload:
            try:
                path = request['serverPath']
                size = request['filesize']
                name = request['name']
                checksum = request['checksum']
                self.handleUploadRequest(socket, path, size, name, checksum)
            except Exception as ex:
                raise DFSError(
                    ("Exception raised in 'processClientRequest/upload': \n" +
                     str(ex)))

        elif type is ClientRequestType.rm:  # 3-way w/ filenode
            try:
                path = request['serverPath']
                name = request['name']
                self.handleFileDeleteRequest(socket, path, name)
            except Exception as ex:
                raise DFSError(
                    ("Exception raised in 'processClientRequest/rm': \n" +
                     str(ex)))

        elif type is ClientRequestType.mv:  # 3-way w/ filenode
            try:
                oldpath = request['serverPath']
                newpath = request['name']
                self.handleMVRequest(socket, newpath, oldpath)
            except:
                raise DFSError(
                    ("Exception raised in 'processClientRequest/mv': \n" +
                     str(ex)))

        elif type is ClientRequestType.rmdir:  # 3-way with filenode if recursive data deletion
            try:
                path = request['serverPath']
                dirname = request['name']
                handleDirDeleteRequest(socket, path, dirname)
            except Exception as ex:
                raise DFSError(
                    ("Exception raised in 'processClientRequest/rmdir': \n" +
                     str(ex)))

        elif type is ClientRequestType.mkdir:
            try:
                path = request['serverPath']
                dirname = request['name']
                wd = self.root.cd(path)
                wd.mkdir(dirname)
                res = ClientResponse(type=mkdir,
                                     output="New directory: " +
                                     str(path + dirname),
                                     success=True)
                socket.send(res.toJson())
                socket.close()

            except Exception as ex:
                try:
                    res = ClientResponse(
                        type=mkdir,
                        output="Error creating new directory.",
                        success=False)
                    socket.send(res.toJson())
                    socket.close()
                except:
                    raise DFSError(
                        ("Exception raised in 'processClientRequest/mkdir': \n"
                         + str(ex)))
                print "Failure to make new directory in MasterNode->processClientRequest->mkdir."
                print "Disconnecting client."
                socket.close()

        elif type == ClientRequestType.cp:  # 3-way with filenode
            try:
                path = request['serverPath']
                filename = request['name']
            except Exception as ex:
                raise DFSError(
                    ("Exception raised in 'processClientRequest/cp': \n" +
                     str(ex)))

            # # I didn't want to create a merge conflict, but I think this will work
            # # It just creatively reuses code from the viewer class
            # try:
            #     path = request['serverPath']
            #     dirname = request['name']
            #     command = ['cd', path]
            #     output = viewer.process(len(command), command)
            #     if output != None:
            #         command = 'mkdir ' + dirname
            #         self.handleViewerRequest(socket, viewer, command)

        elif type == ClientRequestType.rmdir:  # 3-way with filenode if recursive data deletion
            try:
                path = request['serverPath']
                name = request['name']
            except Exception as ex:
                raise DFSError(
                    ("Exception raised in 'processClientRequest/rmdir': \n" +
                     str(ex)))

        elif type == ClientRequestType.stat:
            try:
                path = request['serverPath']
                name = request['name']
                fullpath = path + name

                if fullpath in self.reg.data:
                    filedata = self.reg.data[fullpath]
                    res = ClientResponse(type=type,
                                         output=filedata,
                                         success=True)
                else:
                    errmsg = "Error: " + str(fullpath) + " does not exist."
                    res = ClientResponse(type=type,
                                         output=errmsg,
                                         success=False)

                socket.send(res.toJson())
                socket.close()

            except Exception as ex:
                raise DFSError(
                    ("Exception raised in 'processClientRequest/stat': \n" +
                     str(ex)))

        else:
            raise error("Invalid Type Request")