text: import time
  import uuid
  import socket
  
  import six
  from abc import ABCMeta, abstractmethod, abstractproperty
  
  from deuce import conf
  
  
  @six.add_metaclass(ABCMeta)
  class BlockStorageDriver(object):
  
      """Defines an abstract class for implementing a block storage
      driver for Deuce. The block storage driver is only responsible
      for storing and retrieving individual blocks and has no notion
      of files (files exist only as a notion in the metadata layer).
      """
  
      @abstractmethod
      def block_exists(self, vault_id, storage_block_id):
          """Determines if the specified block exists in the vault.
  
          :param vault_id: The ID of the vault to check
          :param storage_block_id: The Storage ID of the block to check"""
          raise NotImplementedError
  
      @abstractmethod
      def create_vault(self, vault_id):
          """Allocates space in the storage backend for the specified
          vault ID
  
          :param vault_id: The ID of the vault"""
          raise NotImplementedError
  
      @abstractmethod
      def delete_vault(self, vault_id):
          """Deletes the storage allocation for this vault.
  
          :param vault_id: The ID of the vault to delete
          :pre: The vault must be empty
          """
          raise NotImplementedError
  
      @abstractmethod
      def vault_exists(self, vault_id):
          """Determines if block space has been allocated for the
          specified vault_id
  
          :param vault_id: The ID of the vault to check for"""
          raise NotImplementedError
  
      @abstractmethod
      def get_vault_statistics(self, vault_id):
          """Return the statistics on the vault.
  
          "param vault_id: The ID of the vault to gather statistics for"""
          raise NotImplementedError
  
      @abstractmethod
      def get_vault_block_list(self, vault_id, marker, limit):
          """Return the list of blocks in vault from storage."""
  
          raise NotImplementedError
  
      @abstractmethod
      def get_block_obj(self, vault_id, storage_block_id):
          """Returns a single file-like object"""
          raise NotImplementedError
  
      @abstractmethod
      def get_block_object_length(self, vault_id, storage_block_id):
          """Returns the length of an object"""
          raise NotImplementedError
  
      @abstractmethod
      def store_block(self, vault_id, metadata_block_id, block_data):
          """Stores the block into the specified vault
  
          :param metadata_block_id: The Metadata ID of the block
          :returns: A tuple containing the status of saving the block to storage
                      (True/False), and the storage id of the block"""
          raise NotImplementedError
  
      @abstractmethod
      def store_async_block(self, vault_id, metadata_block_ids, block_datas):
          """Stores blocks asynchronously into the specified vault
  
          :param vault_id: The IDs of the vault
          :param metadata_block_ids: The Metadata IDs of the blocks
          :param block_datas: The content of the blocks
          """
          raise NotImplementedError
  
      @abstractmethod
      def block_exists(self, vault_id, storage_block_id):
          """Determines if the specified block exists in the
          vault."""
          raise NotImplementedError
  
      @abstractmethod
      def delete_block(self, vault_id, storage_block_id):
          """Deletes the specified block from storage"""
          raise NotImplementedError
  
      def create_blocks_generator(self, vault_id, storage_block_gen):
          """Returns a generator of file-like objects that are
          ready to read. These objects will get closed
          individually."""
          return ((storage_block_id,
                   self.get_block_obj(vault_id, storage_block_id))
              for storage_block_id in storage_block_gen)
  
      @staticmethod
      def storage_id(metadata_block_id):
          """Generates a storage id, for a given
          metadata block id, by prefixing the metadata blockid to a uuid5.
          The uuid5 is generated by using a default namespace of
          uuid.NAMESPACE_URL and  a name consisting of the concatenation
          of the metadata blockid, host's name and the current time.
  
          """
          return str(metadata_block_id) + '_' + \
              str(uuid.uuid5(uuid.NAMESPACE_URL,
                             metadata_block_id +
                             str(socket.gethostname()) +
                             str(time.time())))
  