o
    .&ßajP  ã                   @   s¾   d dl Z d dlZd dlZd dlZd dlmZmZmZ d dlm	Z
 e e¡ZG dd„ deƒZG dd„ deƒZG dd	„ d	eƒZG d
d„ deƒZG dd„ deƒZG dd„ deƒZG dd„ deƒZdS )é    N)Úensure_unicodeÚensure_bytesÚurlparse)ÚEXCEPTION_MAPc                   @   s,   e Zd Zg d¢Zdd„ Zdd„ Zdd„ ZdS )	ÚMonitor)zbefore-parameter-buildzrequest-createdzresponse-receivedz
after-callzafter-call-errorc                 C   s   || _ || _dS )zåAbstraction for monitoring clients API calls

        :param adapter: An adapter that takes event emitter events
            and produces monitor events

        :param publisher: A publisher for generated monitor events
        N)Ú_adapterÚ
_publisher)ÚselfÚadapterÚ	publisher© r   ú5/usr/lib/python3/dist-packages/botocore/monitoring.pyÚ__init__"   s   
zMonitor.__init__c                 C   s   | j D ]	}| || j¡ qdS )z(Register an event emitter to the monitorN)Ú_EVENTS_TO_REGISTERÚregister_lastÚcapture)r	   Úevent_emitterÚevent_to_registerr   r   r   Úregister-   s   
ÿzMonitor.registerc              
   K   sd   z| j  ||¡}|r| j |¡ W dS W dS  ty1 } ztjd||dd� W Y d}~dS d}~ww )zÚCaptures an incoming event from the event emitter

        It will feed an event emitter event to the monitor's adaptor to create
        a monitor event and then publish that event to the monitor's publisher.
        z:Exception %s raised by client monitor in handling event %sT)Úexc_infoN)r   Úfeedr   ÚpublishÚ	ExceptionÚloggerÚdebug)r	   Ú
event_nameÚpayloadÚmonitor_eventÚer   r   r   r   2   s   ÿþ€ÿzMonitor.captureN)Ú__name__Ú
__module__Ú__qualname__r   r   r   r   r   r   r   r   r      s
    r   c                   @   sr   e Zd Zejfdd„Zdd„ Zdd„ Zdd„ Zd	d
„ Zdd„ Z	dd„ Z
dd„ Zdd„ Zdd„ Zdd„ Zdd„ ZdS )ÚMonitorEventAdapterc                 C   s
   || _ dS )z›Adapts event emitter events to produce monitor events

        :type time: callable
        :param time: A callable that produces the current time
        N)Ú_time)r	   Útimer   r   r   r   C   s   
zMonitorEventAdapter.__init__c                 C   s   |   |¡di |¤ŽS )a   Feed an event emitter event to generate a monitor event

        :type emitter_event_name: str
        :param emitter_event_name: The name of the event emitted

        :type emitter_payload: dict
        :param emitter_payload: The payload to associated to the event
            emitted

        :rtype: BaseMonitorEvent
        :returns: A monitor event based on the event emitter events
            fired
        Nr   )Ú_get_handler)r	   Úemitter_event_nameÚemitter_payloadr   r   r   r   K   s   zMonitorEventAdapter.feedc                 C   s    t | d| d¡d  dd¡ ƒS )NÚ_handle_Ú.r   ú-Ú_)ÚgetattrÚsplitÚreplace)r	   r   r   r   r   r%   [   s   ÿz MonitorEventAdapter._get_handlerc                 K   s    t |jj|j|  ¡ d�|d< d S )N©ÚserviceÚ	operationÚ	timestampÚcurrent_api_call_event)ÚAPICallEventÚservice_modelÚ
service_idÚ	wire_nameÚ_get_current_time)r	   ÚmodelÚcontextÚkwargsr   r   r   Ú_handle_before_parameter_build`   s
   ýz2MonitorEventAdapter._handle_before_parameter_buildc                 K   s6   |j }|d j|  ¡ d�}|j|_|j|_||d< d S )Nr3   )r2   Úcurrent_api_call_attempt_event)r:   Únew_api_call_attemptr8   ÚheadersÚrequest_headersÚurl)r	   Úrequestr;   r:   Únew_attempt_eventr   r   r   Ú_handle_request_createdg   s   ÿþz+MonitorEventAdapter._handle_request_createdc                 K   sT   |  d¡}|  |¡|_|d ur%|d d |_|d d |_| d¡|_|S ||_|S )Nr=   ÚResponseMetadataÚHTTPStatusCodeÚHTTPHeadersÚError)ÚpopÚ_get_latencyÚlatencyÚhttp_status_codeÚresponse_headersÚgetÚparsed_errorÚwire_exception)r	   Úparsed_responser:   Ú	exceptionr;   Úattempt_eventr   r   r   Ú_handle_response_receivedp   s"   
ÿÿÿÿÿz-MonitorEventAdapter._handle_response_receivedc                 K   s    |d   dd¡|d _|  |¡S )NrE   ÚMaxAttemptsReachedFr3   )rN   Úretries_exceededÚ_complete_api_call)r	   r:   Úparsedr;   r   r   r   Ú_handle_after_call~   s   ÿÿ
z&MonitorEventAdapter._handle_after_callc                 K   s   |   |¡|d _|  |¡S ©Nr3   )Ú_is_retryable_exceptionrV   rW   )r	   r:   rR   r;   r   r   r   Ú_handle_after_call_errorƒ   s   ÿ
z,MonitorEventAdapter._handle_after_call_errorc                 C   s   t |ttd ƒƒS )NÚGENERAL_CONNECTION_ERROR)Ú
isinstanceÚtupleÚRETRYABLE_EXCEPTIONS)r	   rR   r   r   r   r[   Œ   s   ÿz+MonitorEventAdapter._is_retryable_exceptionc                 C   s   |  d¡}|  |¡|_|S rZ   )rI   rJ   rK   )r	   r:   Ú
call_eventr   r   r   rW   �   s   
z&MonitorEventAdapter._complete_api_callc                 C   s   |   ¡ |j S ©N)r8   r2   ©r	   Úeventr   r   r   rJ   •   s   z MonitorEventAdapter._get_latencyc                 C   s   t |  ¡ d ƒS )Niè  )Úintr#   ©r	   r   r   r   r8   ˜   s   z%MonitorEventAdapter._get_current_timeN)r   r    r!   r$   r   r   r%   r<   rD   rT   rY   r\   r[   rW   rJ   r8   r   r   r   r   r"   B   s    		r"   c                   @   s$   e Zd Zdd„ Zdd„ Zdd„ ZdS )ÚBaseMonitorEventc                 C   s   || _ || _|| _dS )a‹  Base monitor event

        :type service: str
        :param service: A string identifying the service associated to
            the event

        :type operation: str
        :param operation: A string identifying the operation of service
            associated to the event

        :type timestamp: int
        :param timestamp: Epoch time in milliseconds from when the event began
        Nr/   )r	   r0   r1   r2   r   r   r   r   �   s   
zBaseMonitorEvent.__init__c                 C   s   d| j j| jf S )Nz%s(%r))Ú	__class__r   Ú__dict__rf   r   r   r   Ú__repr__¯   ó   zBaseMonitorEvent.__repr__c                 C   s   t || jƒr| j|jkS dS )NF)r^   rh   ri   )r	   Úotherr   r   r   Ú__eq__²   s   zBaseMonitorEvent.__eq__N)r   r    r!   r   rj   rm   r   r   r   r   rg   œ   s    rg   c                       s*   e Zd Z		d‡ fdd„	Zdd„ Z‡  ZS )r4   NFc                    s:   t t| ƒj|||d� || _|| _|du rg | _|| _dS )a¡  Monitor event for a single API call

        This event corresponds to a single client method call, which includes
        every HTTP requests attempt made in order to complete the client call

        :type service: str
        :param service: A string identifying the service associated to
            the event

        :type operation: str
        :param operation: A string identifying the operation of service
            associated to the event

        :type timestamp: int
        :param timestamp: Epoch time in milliseconds from when the event began

        :type latency: int
        :param latency: The time in milliseconds to complete the client call

        :type attempts: list
        :param attempts: The list of APICallAttempts associated to the
            APICall

        :type retries_exceeded: bool
        :param retries_exceeded: True if API call exceeded retries. False
            otherwise
        r/   N)Úsuperr4   r   rK   ÚattemptsrV   )r	   r0   r1   r2   rK   ro   rV   ©rh   r   r   r   ¹   s   
ÿ
zAPICallEvent.__init__c                 C   s"   t | j| j|d�}| j |¡ |S )zÏInstantiates APICallAttemptEvent associated to the APICallEvent

        :type timestamp: int
        :param timestamp: Epoch time in milliseconds to associate to the
            APICallAttemptEvent
        r/   )ÚAPICallAttemptEventr0   r1   ro   Úappend)r	   r2   rS   r   r   r   r>   Þ   s   ýz!APICallEvent.new_api_call_attempt)NNF)r   r    r!   r   r>   Ú__classcell__r   r   rp   r   r4   ¸   s
    ÿ%r4   c                       s$   e Zd Z			d‡ fdd„	Z‡  ZS )rq   Nc                    sD   t t| ƒj|||d� || _|| _|| _|| _|| _|	| _|
| _	dS )aÞ  Monitor event for a single API call attempt

        This event corresponds to a single HTTP request attempt in completing
        the entire client method call.

        :type service: str
        :param service: A string identifying the service associated to
            the event

        :type operation: str
        :param operation: A string identifying the operation of service
            associated to the event

        :type timestamp: int
        :param timestamp: Epoch time in milliseconds from when the HTTP request
            started

        :type latency: int
        :param latency: The time in milliseconds to complete the HTTP request
            whether it succeeded or failed

        :type url: str
        :param url: The URL the attempt was sent to

        :type http_status_code: int
        :param http_status_code: The HTTP status code of the HTTP response
            if there was a response

        :type request_headers: dict
        :param request_headers: The HTTP headers sent in making the HTTP
            request

        :type response_headers: dict
        :param response_headers: The HTTP headers returned in the HTTP response
            if there was a response

        :type parsed_error: dict
        :param parsed_error: The error parsed if the service returned an
            error back

        :type wire_exception: Exception
        :param wire_exception: The exception raised in sending the HTTP
            request (i.e. ConnectionError)
        r/   N)
rn   rq   r   rK   rA   rL   r@   rM   rO   rP   )r	   r0   r1   r2   rK   rA   rL   r@   rM   rO   rP   rp   r   r   r   ï   s   
0ÿ
zAPICallAttemptEvent.__init__)NNNNNNN)r   r    r!   r   rs   r   r   rp   r   rq   î   s
    ýrq   c                   @   s  e Zd ZdZdZdZdZdZddddœZe	 
d	¡e	 
d
¡dœZg d¢Zdd„ Zdd„ Zdd„ Zdd„ Zdd„ Zdd„ Zdd„ Zdd„ Zdd„ Zdd „ Zd!d"„ Zd#d$„ Zd%d&„ Zd'd(„ Zd)d*„ Zd+d,„ Zd-d.„ Zd/d0„ Zd1d2„ Zd3d4„ Z d5d6„ Z!d7d8„ Z"d9d:„ Z#d;d<„ Z$d=d>„ Z%d?S )@ÚCSMSerializeréÿ   é€   é   i   ÚXAmznRequestIdÚXAmzRequestIdÚXAmzId2)zx-amzn-requestidzx-amz-request-idz
x-amz-id-2zSAWS4-HMAC-SHA256 Credential=(?P<access_key>\w+)/\d+/(?P<signing_region>[a-z0-9-]+)/zAWS (?P<access_key>\w+):)Úv4Ús3)r0   r1   r2   ro   rK   rV   rA   r@   rL   rM   rO   rP   c                 C   s   |   |¡ || _dS )zÖSerializes monitor events to CSM (Client Side Monitoring) format

        :type csm_client_id: str
        :param csm_client_id: The application identifier to associate
            to the serialized events
        N)Ú_validate_client_idÚcsm_client_id©r	   r~   r   r   r   r   O  s   

zCSMSerializer.__init__c                 C   s$   t |ƒ| jkrtd|| jf ƒ‚d S )NzTThe value provided for csm_client_id: %s exceeds the maximum length of %s characters)ÚlenÚ_MAX_CLIENT_ID_LENGTHÚ
ValueErrorr   r   r   r   r}   Y  s   ÿÿÿÿz!CSMSerializer._validate_client_idc                 C   sf   |   |¡}|  |¡}||d< | jD ]}t||dƒ}|dur)t| d| ƒ|||d� qttj|dd�ƒS )zàSerializes a monitor event to the CSM format

        :type event: BaseMonitorEvent
        :param event: The event to serialize to bytes

        :rtype: bytes
        :returns: The CSM serialized form of the event
        ÚTypeNÚ_serialize_)Ú
event_type)ú,ú:)Ú
separators)Ú_get_base_event_dictÚ_get_event_typeÚ_SERIALIZEABLE_EVENT_PROPERTIESr,   r   ÚjsonÚdumps)r	   rd   Ú
event_dictr…   ÚattrÚvaluer   r   r   Ú	serializea  s   
	

ÿ€ÿzCSMSerializer.serializec                 C   s   d| j dœS )Né   )ÚVersionÚClientId)r~   rc   r   r   r   r‰   u  s   þz"CSMSerializer._get_base_event_dictc                 K   ó   ||d< d S )NÚServicer   )r	   r0   rŽ   r;   r   r   r   Ú_serialize_service{  ó   z CSMSerializer._serialize_servicec                 K   r•   )NÚApir   )r	   r1   rŽ   r;   r   r   r   Ú_serialize_operation~  r˜   z"CSMSerializer._serialize_operationc                 K   r•   )NÚ	Timestampr   )r	   r2   rŽ   r;   r   r   r   Ú_serialize_timestamp�  r˜   z"CSMSerializer._serialize_timestampc                 K   s(   t |ƒ|d< |r|  ||d ¡ d S d S )NÚAttemptCountéÿÿÿÿ)r€   Ú_add_fields_from_last_attempt)r	   ro   rŽ   r;   r   r   r   Ú_serialize_attempts„  s   ÿz!CSMSerializer._serialize_attemptsc                 C   s‚   |j r|  |j ¡}|d ur||d< |  |j ¡|d< |jd ur#|j|d< |jd ur0|  |j|d¡ |jd ur?|  |j|d¡ d S d S )NÚRegionÚ	UserAgentÚFinalHttpStatusCodeÚApiCall)r@   Ú_get_regionÚ_get_user_agentrL   rO   Ú_serialize_parsed_errorrP   Ú_serialize_wire_exception)r	   rŽ   Úlast_attemptÚregionr   r   r   rŸ   ‰  s$   ÿ


ÿ
ÿÿz+CSMSerializer._add_fields_from_last_attemptc                 C   s,   |dkr
||d< d S |dkr||d< d S d S )Nr¤   ÚLatencyÚApiCallAttemptÚAttemptLatencyr   )r	   rK   rŽ   r…   r   r   r   Ú_serialize_latency›  s
   ÿz CSMSerializer._serialize_latencyc                 K   s   |rdnd|d< d S )Nr’   r   ÚMaxRetriesExceededr   )r	   rV   rŽ   r;   r   r   r   Ú_serialize_retries_exceeded¡  s   z)CSMSerializer._serialize_retries_exceededc                 K   s   t |ƒj|d< d S )NÚFqdn)r   Únetloc)r	   rA   rŽ   r;   r   r   r   Ú_serialize_url¥  rk   zCSMSerializer._serialize_urlc                 K   s\   |   |¡|d< |  |¡r|  |¡|d< |  |¡}|d ur ||d< d|v r,|d |d< d S d S )Nr¢   Ú	AccessKeyr¡   zX-Amz-Security-TokenÚSessionToken)r¦   Ú
_is_signedÚ_get_access_keyr¥   )r	   r@   rŽ   r;   rª   r   r   r   Ú_serialize_request_headers¨  s   

ÿÿz(CSMSerializer._serialize_request_headersc                 K   r•   )NÚHttpStatusCoder   )r	   rL   rŽ   r;   r   r   r   Ú_serialize_http_status_code´  s   z)CSMSerializer._serialize_http_status_codec                 K   s,   | j  ¡ D ]\}}||v r|| ||< qd S rb   )Ú"_RESPONSE_HEADERS_TO_EVENT_ENTRIESÚitems)r	   rM   rŽ   r;   ÚheaderÚentryr   r   r   Ú_serialize_response_headers¸  s
   €þz)CSMSerializer._serialize_response_headersc                 K   sH   |dkrdnd}|   |d | j¡||d < |   |d | j¡||d < d S )Nr¤   ÚFinalÚ ÚCodeÚAwsExceptionÚMessageÚAwsExceptionMessage)Ú	_truncateÚ_MAX_ERROR_CODE_LENGTHÚ_MAX_MESSAGE_LENGTH)r	   rO   rŽ   r…   r;   Úfield_prefixr   r   r   r§   ¾  s   
ÿ
ÿz%CSMSerializer._serialize_parsed_errorc                 K   sH   |dkrdnd}|   |jj| j¡||d < |   t|ƒ| j¡||d < d S )Nr¤   rÀ   rÁ   ÚSdkExceptionÚSdkExceptionMessage)rÆ   rh   r   Ú_MAX_EXCEPTION_CLASS_LENGTHÚstrrÈ   )r	   rP   rŽ   r…   r;   rÉ   r   r   r   r¨   Æ  s   þ
ÿz'CSMSerializer._serialize_wire_exceptionc                 C   s    t |tƒrdS t |tƒrdS d S )Nr¤   r¬   )r^   r4   rq   rc   r   r   r   rŠ   Ï  s
   

ÿzCSMSerializer._get_event_typec                 C   s"   |   |¡}|  |¡\}}| d¡S )NÚ
access_key)Ú_get_auth_valueÚ_get_auth_matchÚgroup)r	   r@   Úauth_valr+   Ú
auth_matchr   r   r   r·   Õ  s   

zCSMSerializer._get_access_keyc                 C   s<   |   |¡sd S |  |¡}|  |¡\}}|dkrd S | d¡S )Nr{   Úsigning_region)r¶   rÏ   rÐ   rÑ   )r	   r@   rÒ   Úsignature_versionrÓ   r   r   r   r¥   Ú  s   


zCSMSerializer._get_regionc                 C   s   |   t| dd¡ƒ| j¡S )Nz
User-AgentrÁ   )rÆ   r   rN   Ú_MAX_USER_AGENT_LENGTH©r	   r@   r   r   r   r¦   ã  s   þzCSMSerializer._get_user_agentc                 C   s   d|v S ©NÚAuthorizationr   r×   r   r   r   r¶   é  s   zCSMSerializer._is_signedc                 C   s   t |d ƒS rØ   )r   r×   r   r   r   rÏ   ì  r˜   zCSMSerializer._get_auth_valuec                 C   s2   | j  ¡ D ]\}}| |¡}|r||f  S qdS )N)NN)Ú_AUTH_REGEXSr¼   Úmatch)r	   rÒ   rÕ   ÚregexrÛ   r   r   r   rÐ   ï  s   
ÿzCSMSerializer._get_auth_matchc                 C   s*   t |ƒ|krt d||¡ |d |… S |S )Nz6Truncating following value to maximum length of %s: %s)r€   r   r   )r	   ÚtextÚ
max_lengthr   r   r   rÆ   ö  s   þzCSMSerializer._truncateN)&r   r    r!   r�   rÌ   rÇ   rÖ   rÈ   r»   ÚreÚcompilerÚ   r‹   r   r}   r‘   r‰   r—   rš   rœ   r    rŸ   r®   r°   r³   r¸   rº   r¿   r§   r¨   rŠ   r·   r¥   r¦   r¶   rÏ   rÐ   rÆ   r   r   r   r   rt   +  sV    ýÿÿú

		rt   c                   @   s    e Zd ZdZdd„ Zdd„ ZdS )ÚSocketPublisheri    c                 C   s   || _ ||f| _|| _dS )a)  Publishes monitor events to a socket

        :type socket: socket.socket
        :param socket: The socket object to use to publish events

        :type host: string
        :param host: The host to send events to

        :type port: integer
        :param port: The port on the host to send events to

        :param serializer: The serializer to use to serialize the event
            to a form that can be published to the socket. This must
            have a `serialize()` method that accepts a monitor event
            and return bytes
        N)Ú_socketÚ_addressÚ_serializer)r	   ÚsocketÚhostÚportÚ
serializerr   r   r   r     s   

zSocketPublisher.__init__c                 C   sF   | j  |¡}t|ƒ| jkrt dt|ƒ| j¡ dS | j || j¡ dS )zÆPublishes a specified monitor event

        :type event: BaseMonitorEvent
        :param event: The monitor event to be sent
            over the publisher's socket to the desired address.
        z`Serialized event of size %s exceeds the maximum length allowed: %s. Not sending event to socket.N)	rä   r‘   r€   Ú_MAX_MONITOR_EVENT_LENGTHr   r   râ   Úsendtorã   )r	   rd   Úserialized_eventr   r   r   r     s   
ýzSocketPublisher.publishN)r   r    r!   ré   r   r   r   r   r   r   rá   ÿ  s    rá   )rŒ   Úloggingrß   r$   Úbotocore.compatr   r   r   Úbotocore.retryhandlerr   r`   Ú	getLoggerr   r   Úobjectr   r"   rg   r4   rq   rt   rá   r   r   r   r   Ú<module>   s   
)Z6= U