ó
ÍÿŠTc           @   sœ   d  d l  m Z m Z d  d l m Z d  d l m Z d  d l m Z d  d l	 m
 Z
 d e f d „  ƒ  YZ d e f d	 „  ƒ  YZ d
 e f d „  ƒ  YZ d S(   iÿÿÿÿ(   t   infot	   exception(   t   maybeDeferred(   t   format_object(   t   gather_results(   t   remotet   HandlerNotFoundErrorc           B   s   e  Z d  Z RS(   s3   A handler for the given message type was not found.(   t   __name__t
   __module__t   __doc__(    (    (    s;   /usr/lib/python2.7/dist-packages/landscape/broker/client.pyR   
   s   t   BrokerClientPluginc           B   sk   e  Z d  Z d Z e Z d Z d Z d Z	 d „  Z
 e d „  ƒ Z d „  Z d d „ Z d „  Z d „  Z RS(	   sT  A convenience for writing L{BrokerClient} plugins.

    This provides a register method which will set up a bunch of
    reactor handlers in the idiomatic way.

    If C{run} is defined on subclasses, it will be called every C{run_interval}
    +seconds after being registered.

    @cvar run_interval: The interval, in seconds, to execute the C{run} method.
        If set to C{None}, then C{run} will not be scheduled.
    @cvar run_immediately: If C{True} the plugin will be run immediately after
        it is registered.
    @ivar _session_id: the session id to be passed when sending messages via
        the broker.  This variable is set by the C{register} method and
        should only need to be renewed when a re-synchronisation request is
        sent. See L{landscape.broker.server.BrokerServer.send_message} for
        more details.
    i   c         C   sQ   | |  _  |  j  j j d |  j ƒ |  j  j j d |  j ƒ } | j |  j ƒ d  S(   Nt   resynchronizet   scope(	   t   clientt   reactort   call_ont   _resynchronizet   brokert   get_session_idR   t   addCallbackt   _got_session_id(   t   selfR   t   deferred(    (    s;   /usr/lib/python2.7/dist-packages/landscape/broker/client.pyt   register'   s    	c         C   s   |  j  S(   s%   An alias for the C{client} attribute.(   R   (   R   (    (    s;   /usr/lib/python2.7/dist-packages/landscape/broker/client.pyt   registry-   s    c            s5   ‡ ‡  ‡ f d †  } |  j  j j d | f | ƒ d S(   sV   
        Register a callback fired upon a C{message-type-acceptance-changed}.
        c            s   |  r ˆ  ˆ ˆ Ž  Sd  S(   N(    (   t
   acceptance(   t   callablet   argst   kwargs(    s;   /usr/lib/python2.7/dist-packages/landscape/broker/client.pyt   acceptance_changed7   s    s   message-type-acceptance-changedN(   R   R   R   (   R   t   typeR   R   R   R   (    (   R   R   R   s;   /usr/lib/python2.7/dist-packages/landscape/broker/client.pyt   call_on_accepted2   s    c         C   s€   | d k p |  j | k s d S|  j d k	 rG |  j j j |  j ƒ n  |  j ƒ  |  j j j d |  j ƒ } | j	 |  j
 ƒ | S(   s½   
        Handle the 'resynchronize' event.  Subclasses should do any clear-down
        operations specific to their state within an implementation of the
        L{_reset} method.
        NR   (   t   NoneR   t   _loopR   R   t   cancel_callt   _resetR   R   R   R   (   R   t   scopesR   (    (    s;   /usr/lib/python2.7/dist-packages/landscape/broker/client.pyR   >   s    
c         C   s   d S(   sÄ   
        Reset plugin specific state.

        Sub-classes should override this method to clear down data for
        resynchronisation.  Sub-classes with no state can simply ignore this.
        N(    (   R   (    (    s;   /usr/lib/python2.7/dist-packages/landscape/broker/client.pyR#   W   s    c         C   sq   | |  _  t |  d d ƒ d k	 rm |  j r7 |  j ƒ  n  |  j d k	 rm |  j j j |  j |  j ƒ |  _	 qm n  d S(   sÞ   Save the session ID and invoke the C{run} method.

        We set the C{_session_id} attribute on the instance because it's
        required in order to send messages.  See
        L{BrokerService.get_session_id}.
        t   runN(
   t   _session_idt   getattrR    t   run_immediatelyR%   t   run_intervalR   R   t
   call_everyR!   (   R   t
   session_id(    (    s;   /usr/lib/python2.7/dist-packages/landscape/broker/client.pyR   _   s    		N(   R   R   R	   R)   t   FalseR(   R    R   R&   R!   R   t   propertyR   R   R   R#   R   (    (    (    s;   /usr/lib/python2.7/dist-packages/landscape/broker/client.pyR
      s   			t   BrokerClientc           B   s¡   e  Z d  Z d Z d „  Z e d „  ƒ Z d „  Z d „  Z d „  Z	 d „  Z
 d „  Z e d	 „  ƒ Z d
 „  Z d „  Z e d „  ƒ Z d „  Z e d „  ƒ Z RS(   s  Basic plugin registry for clients that have to deal with the broker.

    This knows about the needs of a client when dealing with the Landscape
    broker, including interest in messages of a particular type delivered
    by the broker to the client.

    @cvar name: The name used when registering to the broker, it must be
        defined by sub-classes.
    @ivar broker: A reference to a connected L{RemoteBroker}, it must be set
        by the connecting machinery at service startup.

    @param reactor: A L{LandscapeReactor}.
    R   c         C   sp   t  t |  ƒ j ƒ  | |  _ d  |  _ i  |  _ g  |  _ i  |  _ |  j j	 d |  j
 ƒ |  j j	 d |  j ƒ d  S(   Ns   impending-exchanges   broker-reconnect(   t   superR.   t   __init__R   R    R   t   _registered_messagest   _pluginst   _plugin_namesR   t   notify_exchanget   handle_reconnect(   R   R   (    (    s;   /usr/lib/python2.7/dist-packages/landscape/broker/client.pyR0      s    					c         C   s   t  S(   s   Return C{True}(   t   True(   R   (    (    s;   /usr/lib/python2.7/dist-packages/landscape/broker/client.pyt   ping‹   s    c         C   sV   t  d t | ƒ ƒ |  j j | ƒ t | d ƒ rE | |  j | j <n  | j |  ƒ d S(   s  Add a plugin.

        The plugin's C{register} method will be called with this broker client
        as its argument.

        If the plugin has a C{plugin_name} attribute, it will be possible to
        look up the plugin later with L{get_plugin}.
        s   Registering plugin %s.t   plugin_nameN(   R    R   R2   t   appendt   hasattrR3   R8   R   (   R   t   plugin(    (    s;   /usr/lib/python2.7/dist-packages/landscape/broker/client.pyt   add   s
    	c         C   s   |  j  S(   s   Get the list of plugins.(   R2   (   R   (    (    s;   /usr/lib/python2.7/dist-packages/landscape/broker/client.pyt   get_pluginsŸ   s    c         C   s   |  j  | S(   s    Get a particular plugin by name.(   R3   (   R   t   name(    (    s;   /usr/lib/python2.7/dist-packages/landscape/broker/client.pyt
   get_plugin£   s    c         C   s   | |  j  | <|  j j | ƒ S(   st  
        Register interest in a particular type of Landscape server->client
        message.

        @param type: The type of message to register C{handler} for.
        @param handler: A callable taking a message as a parameter, called
            when messages of C{type} are received.
        @return: A C{Deferred} that will fire when registration completes.
        (   R1   R   t%   register_client_accepted_message_type(   R   R   t   handler(    (    s;   /usr/lib/python2.7/dist-packages/landscape/broker/client.pyt   register_message§   s    
c         C   sg   | d } |  j  j | ƒ } | d k r7 t | ƒ ‚ n  y | | ƒ SWn t d | | f ƒ n Xd S(   sÆ   Run the handler registered for the type of the given message.

        @return: The return value of the handler, if found.
        @raises: HandlerNotFoundError if the handler was not found
        R   s-   Error running message handler for type %r: %rN(   R1   t   getR    R   R   (   R   t   messageR   RA   (    (    s;   /usr/lib/python2.7/dist-packages/landscape/broker/client.pyt   dispatch_message´   s    
c         C   s.   y |  j  | ƒ t SWn t k
 r) t SXd S(   sŠ   Call C{dispatch_message} for the given C{message}.

        @return: A boolean indicating if a handler for the message was found.
        N(   RE   R6   R   R,   (   R   RD   (    (    s;   /usr/lib/python2.7/dist-packages/landscape/broker/client.pyRD   Ä   s
    c         C   sO   xH |  j  ƒ  D]: } t | d ƒ r y | j ƒ  WqG t d ƒ qG Xq q Wd S(   s    Call C{exchange} on all plugins.t   exchanges   Error during plugin exchangeN(   R=   R:   RF   R   (   R   R;   (    (    s;   /usr/lib/python2.7/dist-packages/landscape/broker/client.pyRF   Ð   s    c         C   s   t  d ƒ |  j ƒ  d S(   s/   Notify all plugins about an impending exchange.s>   Got notification of impending exchange. Notifying all plugins.N(   R    RF   (   R   (    (    s;   /usr/lib/python2.7/dist-packages/landscape/broker/client.pyR4   Ù   s    
c         O   s   | d k r> | d } | d } |  j  j | | f | ƒ } n |  j  j | | | Ž } t g  | D] } t d „  | ƒ ^ q` ƒ S(   s´   Fire an event of a given type.

        @return: A L{Deferred} resulting in a list of returns values of
            the fired event handlers, in the order they were fired.
        s   message-type-acceptance-changedi    i   c         S   s   |  S(   N(    (   t   x(    (    s;   /usr/lib/python2.7/dist-packages/landscape/broker/client.pyt   <lambda>ì   s    (   R   t   fireR   R   (   R   t
   event_typeR   R   t   message_typeR   t   resultst   result(    (    s;   /usr/lib/python2.7/dist-packages/landscape/broker/client.pyt
   fire_eventÞ   s    

c         C   s;   x! |  j  D] } |  j j | ƒ q
 W|  j j |  j ƒ d S(   s  Called when the connection with the broker is established again.

        The following needs to be done:

          - Re-register any previously registered message types, so the broker
            knows we have interest on them.

          - Re-register ourselves as client, so the broker knows we exist and
            will talk to us firing events and dispatching messages.
        N(   R1   R   R@   t   register_clientR>   (   R   R   (    (    s;   /usr/lib/python2.7/dist-packages/landscape/broker/client.pyR5   î   s    c         C   s   |  j  j d |  j  j ƒ d S(   s&   Stop the reactor and exit the process.gš™™™™™¹?N(   R   t
   call_latert   stop(   R   (    (    s;   /usr/lib/python2.7/dist-packages/landscape/broker/client.pyt   exitý   s    (   R   R   R	   R>   R0   R   R7   R<   R=   R?   RB   RE   RD   RF   R4   RN   R5   RR   (    (    (    s;   /usr/lib/python2.7/dist-packages/landscape/broker/client.pyR.   o   s   										N(   t   loggingR    R   t   twisted.internet.deferR   t   landscape.logR   t   landscape.lib.twisted_utilR   t   landscape.ampR   t	   ExceptionR   t   objectR
   R.   (    (    (    s;   /usr/lib/python2.7/dist-packages/landscape/broker/client.pyt   <module>   s   a