U
    Z+d                     @   s   d Z ddlmZ ddlmZ ddlmZ ddlmZ ddl	m
Z
 ddlmZ zDdd	lZdd
lmZ ddlmZmZmZ ddlmZ ddlmZ W n0 ek
r   d	 Z Z Z Z Z ZZY nX dZdZdZe
eZG dd deZd	S )z3The CosmosDB/SQL backend for Celery (experimental).    )cached_property)bytes_to_str)
_parse_url)ImproperlyConfigured)
get_logger   )KeyValueStoreBackendN)DocumentClient)ConnectionPolicyConsistencyLevelPartitionKind)HTTPFailure)RetryOptions)CosmosDBSQLBackendi  i  c                       s   e Zd ZdZd fdd	Zedd Zedd Zd	d
 Z	dd Z
edd Zedd Zdd Zedd Zdd Zdd Zdd Zdd Z  ZS )r   z CosmosDB/SQL backend for Celery.Nc           
         s   t  j|| td krtd| jj}	| |\| _| _|pB|	d | _	|pP|	d | _
ztt|pd|	d | _W n tk
r   tdY nX |p|	d | _|p|	d | _d S )NzIYou need to install the pydocumentdb library to use the CosmosDB backend.Zcosmosdbsql_database_nameZcosmosdbsql_collection_nameZcosmosdbsql_consistency_levelz"Unknown CosmosDB consistency levelZcosmosdbsql_max_retry_attemptsZcosmosdbsql_max_retry_wait_time)super__init__pydocumentdbr   Zappconfr   	_endpoint_key_database_name_collection_namegetattrr   _consistency_levelAttributeError_max_retry_attempts_max_retry_wait_time)
selfurlZdatabase_nameZcollection_nameconsistency_levelZmax_retry_attemptsZmax_retry_wait_timeargskwargsr   	__class__ ?/tmp/pip-unpacked-wheel-ucduq0nd/celery/backends/cosmosdbsql.pyr   "   s6    	
zCosmosDBSQLBackend.__init__c                 C   sZ   t |\}}}}}}}|r|s&td|s.d}|dkr:dnd}| d| d| }||fS )NzInvalid URLi  httpshttpz://:)r   r   )clsr   _hostportpasswordschemeZendpointr$   r$   r%   r   N   s    zCosmosDBSQLBackend._parse_urlc                 C   sJ   t  }t| j| jd|_t| jd| ji|| jd}| | | 	| |S )zReturn the CosmosDB/SQL client.

        If this is the first call to the property, the client is created and
        the database and collection are initialized if they don't yet exist.

        )Zmax_retry_attempt_countZmax_wait_time_in_secondsZ	masterKey)connection_policyr   )
r
   r   r   r   r	   r   r   r   _create_database_if_not_exists _create_collection_if_not_exists)r   r/   clientr$   r$   r%   _client\   s    

zCosmosDBSQLBackend._clientc              
   C   sV   z| d| ji W n. tk
rB } z|jtkr2 W 5 d }~X Y nX td| j d S )NidzCreated CosmosDB database %s)ZCreateDatabaser   r   status_codeERROR_EXISTSLOGGERinfor   r2   exr$   r$   r%   r0   t   s    
z1CosmosDBSQLBackend._create_database_if_not_existsc              
   C   sj   z$| | j| jdgtjdd W n. tk
rR } z|jtkrB W 5 d }~X Y nX t	d| j
| j d S )Nz/id)pathskind)r4   partitionKeyz!Created CosmosDB collection %s/%s)ZCreateCollection_database_linkr   r   ZHashr   r5   r6   r7   r8   r   r9   r$   r$   r%   r1   ~   s     
 z3CosmosDBSQLBackend._create_collection_if_not_existsc                 C   s
   d| j  S )Nzdbs/)r   r   r$   r$   r%   r>      s    z!CosmosDBSQLBackend._database_linkc                 C   s   | j d | j S )Nz/colls/)r>   r   r?   r$   r$   r%   _collection_link   s    z#CosmosDBSQLBackend._collection_linkc                 C   s   | j d | S )Nz/docs/)r@   r   keyr$   r$   r%   _get_document_link   s    z%CosmosDBSQLBackend._get_document_linkc                 C   s   |r|  rtdd|iS )Nz(Key cannot be none, empty or whitespace.r=   )isspace
ValueError)r)   rB   r$   r$   r%   _get_partition_key   s    z%CosmosDBSQLBackend._get_partition_keyc              
   C   s~   t |}td| j| j| z| j| || |}W n4 t	k
rn } z|j
tkrX W Y dS d}~X Y nX |dS dS )zxRead the value stored at the given key.

        Args:
              key: The key for which to read the value.

        z"Getting CosmosDB document %s/%s/%sNvalue)r   r7   debugr   r   r3   ZReadDocumentrC   rF   r   r5   ERROR_NOT_FOUNDget)r   rB   documentr:   r$   r$   r%   rJ      s       
zCosmosDBSQLBackend.getc                 C   s>   t |}td| j| j| | j| j||d| | dS )zStore a value for a given key.

        Args:
              key: The key at which to store the value.
              value: The value to store.

        z#Creating CosmosDB document %s/%s/%s)r4   rG   N)	r   r7   rH   r   r   r3   ZCreateDocumentr@   rF   )r   rB   rG   r$   r$   r%   set   s      zCosmosDBSQLBackend.setc                    s    fdd|D S )zqRead all the values for the provided keys.

        Args:
              keys: The list of keys to read.

        c                    s   g | ]}  |qS r$   )rJ   ).0rB   r?   r$   r%   
<listcomp>   s     z+CosmosDBSQLBackend.mget.<locals>.<listcomp>r$   )r   keysr$   r?   r%   mget   s    zCosmosDBSQLBackend.mgetc                 C   s:   t |}td| j| j| | j| || | dS )zlDelete the value at a given key.

        Args:
              key: The key of the value to delete.

        z#Deleting CosmosDB document %s/%s/%sN)	r   r7   rH   r   r   r3   ZDeleteDocumentrC   rF   rA   r$   r$   r%   delete   s      zCosmosDBSQLBackend.delete)NNNNNN)__name__
__module____qualname____doc__r   classmethodr   r   r3   r0   r1   r>   r@   rC   rF   rJ   rL   rP   rQ   __classcell__r$   r$   r"   r%   r      s2         ,





	r   )rU   Zkombu.utilsr   Zkombu.utils.encodingr   Zkombu.utils.urlr   Zcelery.exceptionsr   Zcelery.utils.logr   baser   r   Zpydocumentdb.document_clientr	   Zpydocumentdb.documentsr
   r   r   Zpydocumentdb.errorsr   Zpydocumentdb.retry_optionsr   ImportError__all__rI   r6   rR   r7   r   r$   r$   r$   r%   <module>   s2    