Example #1
0
    def __process_data_block(self, key, raw_data, is_replica=False):
        self.__processed_local_blocks += 1
        try:
            raw_header = raw_data.read(DataBlockHeader.HEADER_LEN)
            primary_key, replica_count, checksum, user_id, stored_dt = DataBlockHeader.unpack(raw_header)
            if not is_replica:
                if key != primary_key:
                    raise Exception("Primary key is invalid: %s != %s" % (key, primary_key))

            data_keys = KeyUtils.get_all_keys(primary_key, replica_count)
            if is_replica:
                if key not in data_keys:
                    raise Exception("Replica key is invalid: %s" % key)
        except Exception, err:
            self.__invalid_local_blocks += 1
            logger.error("[RepairDataBlocks] %s" % err)
            return
Example #2
0
    def test02_dht_init_fail(self):
        server = server1 = None
        try:
            home1 = '/tmp/node_1986_home'
            home2 = '/tmp/node_1987_home'
            if os.path.exists(home1):
                shutil.rmtree(home1)
            os.mkdir(home1)
            if os.path.exists(home2):
                shutil.rmtree(home2)
            os.mkdir(home2)

            server = TestServerThread(1986, home1)
            server.start()
            time.sleep(1)
            server1 = TestServerThread(1987, home2, neighbour='127.0.0.1:1986',  config={'DHT_CYCLE_TRY_COUNT':20, 'ALLOW_USED_SIZE_PERCENTS':0})
            server1.start()
            time.sleep(1.5)
            self.assertNotEqual(server1.operator.get_status(), DS_NORMALWORK)
            for i in xrange(3):
                try:
                    server.operator.split_range(0, 100500)
                    break
                except Exception, err:
                    time.sleep(.1)
            time.sleep(.2)
            server.operator.join_subranges()
            time.sleep(.2)
            server1.operator.update_config({'DHT': {'ALLOW_USED_SIZE_PERCENTS':70}})
            self.__wait_oper_status(server1, DS_NORMALWORK, server1.operator.get_config())

            data_block = 'Hello, fabregas! '*100
            checksum = hashlib.sha1(data_block).hexdigest()
            header1 = DataBlockHeader.pack('0000000000000000000000000000000000000000', 2, checksum)
            self.assertEqual(len(header1), DataBlockHeader.HEADER_LEN)
            time.sleep(1)

            server1.put_data_block(data_block, MAX_HASH/2+100)
            resp = server1.put_data_block(header1+data_block, MAX_HASH/2+100, npkey=True)
            self.assertEqual(resp.ret_code, RC_OLD_DATA, resp.ret_message)

            data = server1.get_data_block(MAX_HASH/2+100)
            self.assertEqual(data.data(), data_block)
Example #3
0
    def process(self, packet):
        """In this method should be implemented logic of processing
        reuqest packet from sender node

        @param packet - object of FabnetPacketRequest class
        @return object of FabnetPacketResponse
                or None for disabling packet response to sender
        """
        primary_key = packet.parameters.get('primary_key', None)
        replica_count =  packet.parameters.get('replica_count', None)
        key = packet.parameters.get('key', None)
        checksum = packet.parameters.get('checksum', None)
        is_replica = packet.parameters.get('is_replica', False)
        user_id = packet.parameters.get('user_id', None)
        carefully_save = packet.parameters.get('carefully_save', False)

        if not packet.binary_data:
            return FabnetPacketResponse(ret_code=RC_ERROR, ret_message='Binary data does not found!')

        if key is None:
            return FabnetPacketResponse(ret_code=RC_ERROR, ret_message='key does not found!')

        key = KeyUtils.to_hex(key)
        data_list = []
        if primary_key:
            primary_key = KeyUtils.to_hex(primary_key)
            if replica_count is None:
                return FabnetPacketResponse(ret_code=RC_ERROR, ret_message='replica count for data block does not found!')
            if checksum is None:
                return FabnetPacketResponse(ret_code=RC_ERROR, ret_message='data checksum does not found!')
            if user_id is None:
                return FabnetPacketResponse(ret_code=RC_ERROR, ret_message='user_id does not found!')

            header = DataBlockHeader.pack(primary_key, replica_count, checksum, user_id)
            data_list.append(header)

        data_list.append(packet.binary_data)
        tempfile_path = self.operator.get_tempfile()
        try:
            tempfile = TmpFile(tempfile_path, data_list)
            self.operator.put_data_block(key, tempfile_path, is_replica, carefully_save)
        except FSHashRangesOldDataDetected, err:
            return FabnetPacketResponse(ret_code=RC_OLD_DATA, ret_message=str(err))
Example #4
0
    def process(self, packet):
        """In this method should be implemented logic of processing
        reuqest packet from sender node

        @param packet - object of FabnetPacketRequest class
        @return object of FabnetPacketResponse
                or None for disabling packet response to sender
        """
        if not packet.binary_data:
            return FabnetPacketResponse(ret_code=RC_ERROR, ret_message='No binary data found!')

        key = packet.parameters.get('key', None)
        if key is not None:
            self._validate_key(key)

        replica_count = int(packet.parameters.get('replica_count', MIN_REPLICA_COUNT))
        wait_writes_count = int(packet.parameters.get('wait_writes_count', 1))

        if wait_writes_count <= 0:
            wait_writes_count = 1
        if wait_writes_count > (replica_count+1):
            return FabnetPacketResponse(ret_code=RC_ERROR, ret_message='Cant waiting more replicas than saving!')
        if replica_count < MIN_REPLICA_COUNT:
            return FabnetPacketResponse(ret_code=RC_ERROR, ret_message='Minimum replica count is equal to %s!'%MIN_REPLICA_COUNT)

        succ_count = 0
        carefully_save = True
        is_replica = False
        errors = []
        local_save = None
        keys = KeyUtils.generate_new_keys(self.node_name, replica_count, prime_key=key)

        tempfile_path = self.operator.get_tempfile()
        tempfile = TmpFile(tempfile_path, packet.binary_data, seek=DataBlockHeader.HEADER_LEN)
        checksum = tempfile.checksum()
        header = DataBlockHeader.pack(keys[0], replica_count, checksum, packet.session_id)
        tempfile.write(header, seek=0)

        for key in keys:
            h_range = self.operator.find_range(key)
            if not h_range:
                logger.info('[ClientPutOperation] Internal error: No hash range found for key=%s!'%key)
            else:
                _, _, node_address = h_range
                params = {'key': key, 'is_replica': is_replica, 'replica_count': replica_count, 'carefully_save': carefully_save}
                if succ_count >= wait_writes_count:
                    binary_data_pointer = BinaryDataPointer(tempfile.hardlink(), remove_on_close=True)
                    self._init_operation(node_address, 'PutDataBlock', params, binary_data=binary_data_pointer)
                else:
                    if self.self_address == node_address and local_save is None:
                        local_save = (key, is_replica)
                        succ_count += 1
                    else:
                        resp = self._init_operation(node_address, 'PutDataBlock', params, sync=True, binary_data=tempfile.chunks())
                        if resp.ret_code != RC_OK:
                            logger.error('[ClientPutOperation] PutDataBlock error from %s: %s'%(node_address, resp.ret_message))
                            errors.append('From %s: %s'%(node_address, resp.ret_message))
                        else:
                            succ_count += 1

            is_replica = True

        try:
            if local_save:
                key, is_replica = local_save
                self.operator.put_data_block(key, tempfile.file_path(), is_replica, carefully_save)
        except Exception, err:
            succ_count -= 1
            msg = 'Saving data block to local range is failed: %s'%err
            logger.error(msg)
            errors.append(msg)