def on_head(self, req, resp, vault_id, block_id): """Checks for the existence of the block in the metadata storage and if successful check for it in the storage driver if it fails we return a 502, otherwise we return all other headers returned on GET /v1.0/vaults/{vault_id}/blocks/{block_id} """ vault = Vault.get(vault_id) if not vault: logger.error('Vault [{0}] does not exist'.format(vault_id)) raise errors.HTTPNotFound # This is safe to construct before we check the status of the block # b/c the constructor does not do anything other than save values # to itself, no lookups, etc block = Block(vault_id, block_id) try: if not vault.has_block(block_id, check_storage=True): logger.error('block [{0}] does not exist'.format(block_id)) raise errors.HTTPNotFound ref_cnt = block.get_ref_count() resp.set_header('X-Block-Reference-Count', str(ref_cnt)) ref_mod = block.get_ref_modified() resp.set_header('X-Ref-Modified', str(ref_mod)) storage_id = block.get_storage_id() resp.set_header('X-Storage-ID', str(storage_id)) resp.set_header('X-Block-ID', str(block_id)) resp.set_header('X-Block-Size', str(block.get_block_length())) resp.status = falcon.HTTP_204 except ConsistencyError as ex: # We have the block in metadata... # so we can get anything that only touches metadata ref_cnt = block.get_ref_count() resp.set_header('X-Block-Reference-Count', str(ref_cnt)) ref_mod = block.get_ref_modified() resp.set_header('X-Ref-Modified', str(ref_mod)) storage_id = block.get_storage_id() resp.set_header('X-Storage-ID', str(storage_id)) resp.set_header('X-Block-ID', str(block_id)) # Block-size is retrieved from storage... logger.error(ex) raise errors.HTTPGone(str(ex))
def get_block(self, storage_block_id): """Get a block directly from storage """ metadata_block_id = self.get_metadata_id(storage_block_id) obj = deuce.storage_driver.get_block_obj(self.vault_id, storage_block_id) return Block(self.vault_id, metadata_block_id, obj=obj, storage_block_id=storage_block_id) if obj else None
def delete_block(self, storage_block_id): block_id = self.get_metadata_id(storage_block_id) block = Block(self.vault_id, block_id, storage_block_id=storage_block_id) if block_id else None ref_count = block.get_ref_count() if block else None if block is None: return deuce.storage_driver.delete_block(self.vault_id, storage_block_id) else: msg = "Storage ID: {0} has {1} " \ "reference(s) in metadata".format( storage_block_id, ref_count) raise ConstraintError(deuce.context.project_id, self.vault_id, msg)
def on_get(self, req, resp, vault_id, block_id): """Returns a specific block""" # Step 1: Is the block in our vault store? If not, return 404 # Step 2: Stream the block back to the user vault = Vault.get(vault_id) # Existence of the vault should have been confirmed # in the vault controller assert vault is not None try: block = vault.get_block(block_id) if block is None: logger.error('block [{0}] does not exist'.format(block_id)) # We have to do the has_block() check in order to # differentiate between a 404 and 410 error. # 404 should be returned if even metadata doesn't know # about the block; while 410 should be returned if # metadata knows about the block but it is not found # in storage. Since we already know the block doesn't # exist in storage, we can skip the storage check if vault.has_block(block_id, check_storage=False): logger.error( 'block [{0}] does not exist (vault check)'.format( block_id)) raise ConsistencyError(deuce.context.project_id, vault_id, block_id, msg='Block does not exist' ' in Block Storage') raise errors.HTTPNotFound ref_cnt = block.get_ref_count() resp.set_header('X-Block-Reference-Count', str(ref_cnt)) ref_mod = block.get_ref_modified() resp.set_header('X-Ref-Modified', str(ref_mod)) storage_id = block.get_storage_id() resp.set_header('X-Storage-ID', str(storage_id)) resp.set_header('X-Block-ID', str(block_id)) resp.stream = block.get_obj() resp.stream_len = block.get_block_length() resp.status = falcon.HTTP_200 resp.content_type = 'application/octet-stream' except ConsistencyError as ex: # We have the block in metadata... # so we can get anything that only touches metadata block = Block(vault_id, block_id) ref_cnt = block.get_ref_count() resp.set_header('X-Block-Reference-Count', str(ref_cnt)) ref_mod = block.get_ref_modified() resp.set_header('X-Ref-Modified', str(ref_mod)) storage_id = block.get_storage_id() resp.set_header('X-Storage-ID', str(storage_id)) resp.set_header('X-Block-ID', str(block_id)) # Block-size is retrieved from storage... logger.error(ex) raise errors.HTTPGone(str(ex))
def on_get(self, req, resp, vault_id, block_id): """Returns a specific block""" # Step 1: Is the block in our vault store? If not, return 404 # Step 2: Stream the block back to the user vault = Vault.get(vault_id) # Existence of the vault should have been confirmed # in the vault controller assert vault is not None try: block = vault.get_block(block_id) if block is None: logger.error('block [{0}] does not exist' .format(block_id)) # We have to do the has_block() check in order to # differentiate between a 404 and 410 error. # 404 should be returned if even metadata doesn't know # about the block; while 410 should be returned if # metadata knows about the block but it is not found # in storage. Since we already know the block doesn't # exist in storage, we can skip the storage check if vault.has_block(block_id, check_storage=False): logger.error('block [{0}] does not exist (vault check)' .format(block_id)) raise ConsistencyError(deuce.context.project_id, vault_id, block_id, msg='Block does not exist' ' in Block Storage') raise errors.HTTPNotFound ref_cnt = block.get_ref_count() resp.set_header('X-Block-Reference-Count', str(ref_cnt)) ref_mod = block.get_ref_modified() resp.set_header('X-Ref-Modified', str(ref_mod)) storage_id = block.get_storage_id() resp.set_header('X-Storage-ID', str(storage_id)) resp.set_header('X-Block-ID', str(block_id)) resp.stream = block.get_obj() resp.stream_len = block.get_block_length() resp.status = falcon.HTTP_200 resp.content_type = 'application/octet-stream' except ConsistencyError as ex: # We have the block in metadata... # so we can get anything that only touches metadata block = Block(vault_id, block_id) ref_cnt = block.get_ref_count() resp.set_header('X-Block-Reference-Count', str(ref_cnt)) ref_mod = block.get_ref_modified() resp.set_header('X-Ref-Modified', str(ref_mod)) storage_id = block.get_storage_id() resp.set_header('X-Storage-ID', str(storage_id)) resp.set_header('X-Block-ID', str(block_id)) # Block-size is retrieved from storage... logger.error(ex) raise errors.HTTPGone(str(ex))