ó
½-'Nc           @   so   d  d l  Z  d  d l m Z d  d l m Z d  d l m Z d  d l m Z d „  Z	 d e
 f d „  ƒ  YZ d S(	   iÿÿÿÿN(   t   Deferred(   t   gather_results(   t   RemoteComponentsRegistry(   t   FAILEDc            s(   |  j  j d d ƒ ‰  ‡  f d †  } | S(   s&  Turns a L{BrokerServer} method into an event broadcaster.

    When the decorated method is called, an event is fired on all connected
    clients. The event will have the same name as the method being called,
    except that any underscore in the method name will be replaced with a dash.
    t   _t   -c            sC   g  } x0 |  j  ƒ  D]" } | j | j ˆ  | | Ž ƒ q Wt | ƒ S(   N(   t   get_clientst   appendt
   fire_eventR   (   t   selft   argst   kwargst   firedt   client(   t
   event_type(    s;   /usr/lib/python2.7/dist-packages/landscape/broker/server.pyt   broadcast_event   s     (   t   __name__t   replace(   t   methodR   (    (   R   s;   /usr/lib/python2.7/dist-packages/landscape/broker/server.pyt   event
   s    t   BrokerServerc           B   s+  e  Z d  Z d Z e Z d „  Z d „  Z d „  Z d „  Z	 d „  Z
 d „  Z d „  Z e d	 „ Z d
 „  Z d „  Z d „  Z d „  Z d „  Z d „  Z d „  Z d „  Z d „  Z e d „  ƒ Z e d „  ƒ Z d „  Z e d „  ƒ Z e d „  ƒ Z e d „  ƒ Z e d „  ƒ Z d „  Z  d „  Z! RS(   sn   
    A broker server capable of handling messages from plugins connected using
    the L{BrokerProtocol}.
    t   brokerc         C   sµ   | |  _  | |  _ | |  _ | |  _ | |  _ i  |  _ i  |  _ | j d |  j ƒ | j d |  j	 ƒ | j d |  j
 ƒ | j d |  j ƒ | j d |  j ƒ | j d |  j ƒ d S(   sU  
        @param config: The L{BrokerConfiguration} used by the broker.
        @param reactor: The L{TwistedReactor} driving the broker's events.
        @param exchange: The L{MessageExchange} to send messages with.
        @param registration: The {RegistrationHandler}.
        @param message_store: The broker's L{MessageStore}.
        t   messages   impending-exchanges   message-type-acceptance-changeds   server-uuid-changeds   package-data-changeds   resynchronize-clientsN(   t   _configt   _reactort
   _exchangert   _registrationt   _message_storet   _registered_clientst   _connectorst   call_ont   broadcast_messaget   impending_exchanget   message_type_acceptance_changedt   server_uuid_changedt   package_data_changedt   resynchronize(   R	   t   configt   reactort   exchanget   registrationt   message_store(    (    s;   /usr/lib/python2.7/dist-packages/landscape/broker/server.pyt   __init__$   s    									
c         C   s   t  S(   s   Return C{True}.(   t   True(   R	   (    (    s;   /usr/lib/python2.7/dist-packages/landscape/broker/server.pyt   ping=   s    c            sU   ˆ j  j ˆ  ƒ } | ˆ j ˆ j ƒ ‰ ‡ ‡ ‡  f d †  } ˆ j ƒ  } | j | ƒ S(   sQ  Register a broker client called C{name}.

        Various broker clients interact with the broker server, such as the
        monitor for example, using the L{BrokerServerProtocol} for performing
        remote method calls on the L{BrokerServer}.

        They establish connectivity with the broker by connecting and
        registering themselves, the L{BrokerServer} will in turn connect
        to them in order to be able to perform remote method calls like
        broadcasting events and messages.

        @param name: The name of the client, such a C{monitor} or C{manager}.
        c            s   |  ˆ j  ˆ <ˆ  ˆ j |  <d  S(   N(   R   R   (   t   remote_client(   t	   connectorR	   t   name(    s;   /usr/lib/python2.7/dist-packages/landscape/broker/server.pyt   registerR   s    (   t   connectors_registryt   getR   R   t   connectt   addCallback(   R	   R/   t   connector_classR0   t	   connected(    (   R/   R	   R.   s;   /usr/lib/python2.7/dist-packages/landscape/broker/server.pyt   register_clientA   s
    c         C   s   |  j  j ƒ  S(   s5   Get L{RemoteClient} instances for registered clients.(   R   t   values(   R	   (    (    s;   /usr/lib/python2.7/dist-packages/landscape/broker/server.pyR   Y   s    c         C   s   |  j  j | ƒ S(   s4   Return the client with the given C{name} or C{None}.(   R   R2   (   R	   R/   (    (    s;   /usr/lib/python2.7/dist-packages/landscape/broker/server.pyt
   get_client]   s    c         C   s   |  j  j ƒ  S(   sa   Get connectors for registered clients.

        @see L{RemoteLandscapeComponentCreator}.
        (   R   R8   (   R	   (    (    s;   /usr/lib/python2.7/dist-packages/landscape/broker/server.pyt   get_connectorsa   s    c         C   s   |  j  j |  j | ƒ ƒ S(   s6   Return the connector for the given C{name} or C{None}.(   R   R2   R9   (   R	   R/   (    (    s;   /usr/lib/python2.7/dist-packages/landscape/broker/server.pyt   get_connectorh   s    c         C   s   |  j  j | d | ƒS(   s³  Queue C{message} for delivery to the server at the next exchange.

        @param message: The message C{dict} to send to the server.  It must
            have a C{type} key and be compatible with C{landscape.lib.bpickle}.
        @param urgent: If C{True}, exchange urgently, otherwise exchange
            during the next regularly scheduled exchange.
        @return: The message identifier created when queuing C{message}.
        t   urgent(   R   t   send(   R	   R   R<   (    (    s;   /usr/lib/python2.7/dist-packages/landscape/broker/server.pyt   send_messagel   s    	c         C   s   |  j  j | ƒ S(   s:   Indicate if a message with given C{message_id} is pending.(   R   t
   is_pending(   R	   t
   message_id(    (    s;   /usr/lib/python2.7/dist-packages/landscape/broker/server.pyt   is_message_pendingw   s    c         C   sR   g  } x' |  j  ƒ  D] } | j | j ƒ  ƒ q Wt | d t ƒ} | j d „  ƒ S(   s   Tell all the clients to exit.t   consume_errorsc         S   s   d  S(   N(   t   None(   t   ignored(    (    s;   /usr/lib/python2.7/dist-packages/landscape/broker/server.pyt   <lambda>‚   s    (   R   R   t   exitR   R+   R4   (   R	   t   resultsR   t   result(    (    s;   /usr/lib/python2.7/dist-packages/landscape/broker/server.pyt   stop_clients{   s
    c         C   s   |  j  j ƒ  |  j ƒ  S(   s4   Reload the configuration file, and stop all clients.(   R   t   reloadRI   (   R	   (    (    s;   /usr/lib/python2.7/dist-packages/landscape/broker/server.pyt   reload_configuration„   s    c         C   s   |  j  j ƒ  S(   sf   Attempt to register with the Landscape server.

        @see: L{RegistrationHandler.register}
        (   R   R0   (   R	   (    (    s;   /usr/lib/python2.7/dist-packages/landscape/broker/server.pyR0   ‹   s    c         C   s   |  j  j ƒ  S(   s:   Return the message types accepted by the Landscape server.(   R   t   get_accepted_types(   R	   (    (    s;   /usr/lib/python2.7/dist-packages/landscape/broker/server.pyt   get_accepted_message_types’   s    c         C   s   |  j  j ƒ  S(   s:   Return the uuid of the Landscape server we're pointing at.(   R   t   get_server_uuid(   R	   (    (    s;   /usr/lib/python2.7/dist-packages/landscape/broker/server.pyRN   –   s    c         C   s   |  j  j | ƒ d S(   s|   Register a new message type which can be accepted by this client.

        @param type: The message type to accept.
        N(   R   t%   register_client_accepted_message_type(   R	   t   type(    (    s;   /usr/lib/python2.7/dist-packages/landscape/broker/server.pyRO   œ   s    c         C   s   |  j  j | ƒ d S(   s$   Fire an event in the broker reactor.N(   R   t   fire(   R	   R   (    (    s;   /usr/lib/python2.7/dist-packages/landscape/broker/server.pyR   £   s    c            s8   ˆ  j  j d ƒ ˆ  j ƒ  } ‡  f d †  } | j | ƒ S(   s“  Request a graceful exit from the broker server.

        Before this method returns, all broker clients will be notified
        of the server broker's intention of exiting, so that they have
        the chance to stop whatever they're doing in a graceful way, and
        then exit themselves.

        This method will only return a result when all plugins returned
        their own results.
        s   pre-exitc            s    ˆ  j  j d ‡  f d †  ƒ d  S(   Ni   c              s   ˆ  j  j d ƒ S(   Ns	   post-exit(   R   RQ   (    (   R	   (    s;   /usr/lib/python2.7/dist-packages/landscape/broker/server.pyRE   ½   s    (   R   t
   call_later(   RD   (   R	   (    s;   /usr/lib/python2.7/dist-packages/landscape/broker/server.pyt   fire_post_exitº   s    	(   R   RQ   RI   t   addBoth(   R	   t   clients_stoppedRS   (    (   R	   s;   /usr/lib/python2.7/dist-packages/landscape/broker/server.pyRF   §   s    c         C   s   d S(   s2   Broadcast a C{resynchronize} event to the clients.N(    (   R	   (    (    s;   /usr/lib/python2.7/dist-packages/landscape/broker/server.pyR$   Á   s    c         C   s   d S(   s8   Broadcast an C{impending-exchange} event to the clients.N(    (   R	   (    (    s;   /usr/lib/python2.7/dist-packages/landscape/broker/server.pyR    Å   s    c            sa   t  ƒ  ‰ g  ‰  ‡ ‡ ‡  f d †  } x6 | D]. } ˆ j j | | | ƒ ƒ } ˆ  j | ƒ q+ Wˆ S(   sk   
        Return a C{Deferred} that fires when the first event occurs among the
        given ones.
        c            s   ‡ ‡ ‡  ‡ f d †  } | S(   Nc             s2   x ˆ D] }  ˆ j  j |  ƒ q Wˆ  j ˆ ƒ d  S(   N(   R   t   cancel_callt   callback(   t   call(   t   deferredR	   R   t   calls(    s;   /usr/lib/python2.7/dist-packages/landscape/broker/server.pyt   handlerÓ   s    (    (   R   R[   (   RY   R	   RZ   (   R   s;   /usr/lib/python2.7/dist-packages/landscape/broker/server.pyt   get_handlerÑ   s    (   R    R   R   R   (   R	   t   event_typesR\   R   RX   (    (   RZ   R	   RY   s;   /usr/lib/python2.7/dist-packages/landscape/broker/server.pyt   listen_eventsÉ   s    		c         C   s   d S(   s5   Broadcast a C{broker-reconnect} event to the clients.N(    (   R	   (    (    s;   /usr/lib/python2.7/dist-packages/landscape/broker/server.pyt   broker_reconnectß   s    c         C   s   d S(   s8   Broadcast a C{server-uuid-changed} event to the clients.N(    (   R	   t   old_uuidt   new_uuid(    (    s;   /usr/lib/python2.7/dist-packages/landscape/broker/server.pyR"   ã   s    c         C   s   d  S(   N(    (   R	   RP   t   accepted(    (    s;   /usr/lib/python2.7/dist-packages/landscape/broker/server.pyR!   ç   s    c         C   s   d S(   s@   Fire a package-data-changed event in the reactor of each client.N(    (   R	   (    (    s;   /usr/lib/python2.7/dist-packages/landscape/broker/server.pyR#   ë   s    c         C   sR   g  } x* |  j  ƒ  D] } | j | j | ƒ ƒ q Wt | ƒ } | j |  j | ƒ S(   se   Call the C{message} method of all the registered plugins.

        @see: L{register_plugin}.
        (   R   R   R   R   R4   t   _message_delivered(   R	   R   RG   R   RH   (    (    s;   /usr/lib/python2.7/dist-packages/landscape/broker/server.pyR   ï   s
    c         C   s¡   | j  d ƒ } t | k r | d
 k	 r | d d k r | d } t j d | f ƒ d | f } i d d 6t d 6| d 6| d 6} |  j j | d	 t ƒn  d
 S(   s¾   
        If the message wasn't handled, and it's an operation request (i.e. it
        has an operation-id), then respond with a failing operation result
        indicating as such.
        s   operation-idRP   R$   s   Nobody handled the %s message.s4  Landscape client failed to handle this request (%s) because the
plugin which should handle it isn't available.  This could mean that the
plugin has been intentionally disabled, or that the client isn't running
properly, or you may be running an older version of the client that doesn't
support this feature.
s   operation-resultt   statuss   result-textR<   N(   R2   R+   RC   t   loggingt   errorR   R   R=   (   R	   RG   R   t   opidt   mtypet   result_textt   response(    (    s;   /usr/lib/python2.7/dist-packages/landscape/broker/server.pyRc   ú   s    

("   R   t
   __module__t   __doc__R/   R   R1   R*   R,   R7   R   R9   R:   R;   t   FalseR>   RA   RI   RK   R0   RM   RN   RO   R   RF   R   R$   R    R^   R_   R"   R!   R#   R   Rc   (    (    (    s;   /usr/lib/python2.7/dist-packages/landscape/broker/server.pyR      s:   																			(   Re   t   twisted.internet.deferR    t   landscape.lib.twisted_utilR   t   landscape.ampR   t   landscape.manager.managerR   R   t   objectR   (    (    (    s;   /usr/lib/python2.7/dist-packages/landscape/broker/server.pyt   <module>   s   	