Your IP : 172.28.240.42


Current Path : /usr/lib/python2.7/dist-packages/landscape/broker/
Upload File :
Current File : //usr/lib/python2.7/dist-packages/landscape/broker/server.pyc


Tc@sudZddlZddlmZddlmZddlmZddlm	Z	dZ
defd	YZdS(
sBridge client side plugins to the C{MessageExchange}.

The C{BrokerServer} provides C{BrokerClient}s with a mechanism to send messages
to the server and, likewise, triggers those plugins to take action when a
exchange is impending or resynchronisaton is required.

Each C{BrokerClient} has to be registered using the
L{BrokerServer.register_client} method, after which two way communications is
possible between the C{BrokerServer} and the C{BrokerClient}.

Resynchronisation Sequence
==========================

See L{landscape.broker.exchange} sequence diagram for origin of the
"resynchronize-clients" event.

Diagram::


 1. [event 1]               --->  BrokerServer        : Event
                                                      : "resynchronize-clients"

 2. [event 2]               <---  BrokerServer        : Broadcast event
                                                      : "resynchronize"

 3. [optional: various L{BrowserClientPlugin}s respond
               to the "resynchronize" event to reset
               themselves and start report afresh.]
     (See: L{landscape.monitor.packagemonitor.PackageMonitor}
           L{landscape.monitor.plugin.MonitorPlugin}
           L{landscape.manager.keystonetoken.KeystoneToken}
           L{landscape.monitor.activeprocessinfo.ActiveProcessInfo} )


 4. [event 1]               ---> MessageExchange      : Event
    (NOTE, this is the same event as step 1           : "resynchronize-clients"
     it is handled by both BrokerServer and
     MessageExchange.
     See MessageExchange._resynchronize )

 5. MessageExchange         ---> MessageExchange      : Schedule urgent
                                                      : exchange

iN(tDeferred(tgather_results(tremote(tFAILEDcs(|jjddfd}|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-csCg}x0|jD]"}|j|j||qWt|S(N(tget_clientstappendt
fire_eventR(tselftargstkwargstfiredtclient(t
event_type(s;/usr/lib/python2.7/dist-packages/landscape/broker/server.pytbroadcast_event@s (t__name__treplace(tmethodR((Rs;/usr/lib/python2.7/dist-packages/landscape/broker/server.pytevent7stBrokerServercBseZdZdZdZedZeddZedZ	dZ
dZdZd	Z
eed
ZedZedZed
ZedZedZedZedZedZedZedZedZedZedZedZedZedZ dZ!dZ"edZ#RS(s
    A broker server capable of handling messages from plugins connected using
    the L{BrokerProtocol}.

    @param config: The L{BrokerConfiguration} used by the broker.
    @param reactor: The L{LandscapeReactor} 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}.
    tbrokercCsddlm}||_||_||_||_||_||_i|_i|_	||_
|jd|j|jd|j
|jd|j|jd|j|jd|j|jd|jdS(	Ni(tget_component_registrytmessagesimpending-exchangesmessage-type-acceptance-changedsserver-uuid-changedspackage-data-changedsresynchronize-clients(tlandscape.broker.ampRtconnectors_registryt_configt_reactort
_exchangert
_registrationt_message_storet_registered_clientst_connectorst_pingertcall_ontbroadcast_messagetimpending_exchangetmessage_type_acceptance_changedtserver_uuid_changedtpackage_data_changedt
resynchronize(R	tconfigtreactortexchangetregistrationt
message_storetpingerR((s;/usr/lib/python2.7/dist-packages/landscape/broker/server.pyt__init__Vs"									
cCstS(sReturn C{True}.(tTrue(R	((s;/usr/lib/python2.7/dist-packages/landscape/broker/server.pytpingkscCs|jjd|S(sGet a unique session ID to be used when sending messages.

        Anything that wants to send a message to the server via the broker is
        required to first acquire a session ID with this method. Such session
        IDs must be passed to L{send_message} whenever sending a message.

        The broker keeps track of the session IDs that it hands out and will
        drop them when a re-synchronisation event occurs.  Further messages
        sent using expired IDs will be silently discarded.

        For example each L{BrokerClientPlugin} calls this method to get a
        session ID and use it when sending messages, until the plugin gets
        notified of a re-synchronisation event and then asks for a new one.

        This eliminates issues with out-of-date messages being delivered to the
        server after a re-synchronisation request. For example when the client
        re-registers and gets a new computer ID we don't want to deliver
        messages containing references to activity IDs of the old computer
        (e.g. a message with the result of a "change-packages" activity
        delivered before re-registering). See also #328005 and #1158822.

        tscope(Rtget_session_id(R	R2((s;/usr/lib/python2.7/dist-packages/landscape/broker/server.pyR3pscsUjj}|jjfd}j}|j|S(sRRegister a broker client called C{name}.

        Various broker clients interact with the broker server, such as the
        monitor for example, using the L{BrokerServerConnector} 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}.
        cs|j<j|<dS(N(RR (t
remote_client(t	connectorR	tname(s;/usr/lib/python2.7/dist-packages/landscape/broker/server.pytregisters
(RtgetRRtconnecttaddCallback(R	R6tconnector_classR7t	connected((R6R	R5s;/usr/lib/python2.7/dist-packages/landscape/broker/server.pytregister_clients
cCs
|jjS(s5Get L{RemoteClient} instances for registered clients.(Rtvalues(R	((s;/usr/lib/python2.7/dist-packages/landscape/broker/server.pyRscCs|jj|S(s4Return the client with the given C{name} or C{None}.(RR8(R	R6((s;/usr/lib/python2.7/dist-packages/landscape/broker/server.pyt
get_clientscCs
|jjS(saGet connectors for registered clients.

        @see L{RemoteLandscapeComponentCreator}.
        (R R>(R	((s;/usr/lib/python2.7/dist-packages/landscape/broker/server.pytget_connectorsscCs|jj|j|S(s6Return the connector for the given C{name} or C{None}.(R R8R?(R	R6((s;/usr/lib/python2.7/dist-packages/landscape/broker/server.pyt
get_connectorscCs{t|tr4|ddkr4t}|j}n|dkrOtdn|jj|rw|jj	|d|SdS(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 session_id: A session ID.  You should acquire this
            with C{get_session_id} before attempting to send a message.
        @param urgent: If C{True}, exchange urgently, otherwise exchange
            during the next regularly scheduled exchange.
        @return: The message identifier created when queuing C{message}.
        ttypesoperation-resultschange-packages-results:Session ID must be set before attempting to send a messageturgentN(soperation-resultschange-packages-result(
t
isinstancetboolR0R3tNonetRuntimeErrorRtis_valid_session_idRtsend(R	Rt
session_idRC((s;/usr/lib/python2.7/dist-packages/landscape/broker/server.pytsend_messages	cCs|jj|S(s:Indicate if a message with given C{message_id} is pending.(Rt
is_pending(R	t
message_id((s;/usr/lib/python2.7/dist-packages/landscape/broker/server.pytis_message_pendingscCsRg}x'|jD]}|j|jqWt|dt}|jdS(sTell all the clients to exit.tconsume_errorscSsdS(N(RF(tignored((s;/usr/lib/python2.7/dist-packages/landscape/broker/server.pyt<lambda>s(RRtexitRR0R:(R	tresultsR
tresult((s;/usr/lib/python2.7/dist-packages/landscape/broker/server.pytstop_clientss
cCs|jj|jS(s4Reload the configuration file, and stop all clients.(RtreloadRU(R	((s;/usr/lib/python2.7/dist-packages/landscape/broker/server.pytreload_configurations
cCs
|jjS(sfAttempt to register with the Landscape server.

        @see: L{RegistrationHandler.register}
        (RR7(R	((s;/usr/lib/python2.7/dist-packages/landscape/broker/server.pyR7scCs
|jjS(s:Return the message types accepted by the Landscape server.(Rtget_accepted_types(R	((s;/usr/lib/python2.7/dist-packages/landscape/broker/server.pytget_accepted_message_typesscCs
|jjS(s:Return the uuid of the Landscape server we're pointing at.(Rtget_server_uuid(R	((s;/usr/lib/python2.7/dist-packages/landscape/broker/server.pyRZscCs|jj|dS(s|Register a new message type which can be accepted by this client.

        @param type: The message type to accept.
        N(Rt%register_client_accepted_message_type(R	RB((s;/usr/lib/python2.7/dist-packages/landscape/broker/server.pyR[scCs|jj|dS(s$Fire an event in the broker reactor.N(Rtfire(R	R((s;/usr/lib/python2.7/dist-packages/landscape/broker/server.pyR	scs(j}fd}|j|S(sRequest 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.
        cs jjdfddS(Nics
jjS(N(Rtstop((R	(s;/usr/lib/python2.7/dist-packages/landscape/broker/server.pyRQ$s(Rt
call_later(RP(R	(s;/usr/lib/python2.7/dist-packages/landscape/broker/server.pytschedule_reactor_stops(RUtaddBoth(R	tclients_stoppedR_((R	s;/usr/lib/python2.7/dist-packages/landscape/broker/server.pyRRs
cCsdS(s2Broadcast a C{resynchronize} event to the clients.N((R	((s;/usr/lib/python2.7/dist-packages/landscape/broker/server.pyR((scCsdS(s8Broadcast an C{impending-exchange} event to the clients.N((R	((s;/usr/lib/python2.7/dist-packages/landscape/broker/server.pyR$,scsatgfd}x6|D].}jj|||}j|q+WS(sk
        Return a C{Deferred} that fires when the first event occurs among the
        given ones.
        csfd}|S(Ncs2xD]}jj|qWjdS(N(Rtcancel_calltcallback(tcall(tdeferredR	Rtcalls(s;/usr/lib/python2.7/dist-packages/landscape/broker/server.pythandler;s
((RRg(ReR	Rf(Rs;/usr/lib/python2.7/dist-packages/landscape/broker/server.pytget_handler9s(RRR"R(R	tevent_typesRhRRd((RfR	Res;/usr/lib/python2.7/dist-packages/landscape/broker/server.pyt
listen_events0s		
cCsdS(s5Broadcast a C{broker-reconnect} event to the clients.N((R	((s;/usr/lib/python2.7/dist-packages/landscape/broker/server.pytbroker_reconnectGscCsdS(s8Broadcast a C{server-uuid-changed} event to the clients.N((R	told_uuidtnew_uuid((s;/usr/lib/python2.7/dist-packages/landscape/broker/server.pyR&KscCsdS(N((R	RBtaccepted((s;/usr/lib/python2.7/dist-packages/landscape/broker/server.pyR%OscCsdS(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'SscCsRg}x*|jD]}|j|j|qWt|}|j|j|S(seCall the C{message} method of all the registered plugins.

        @see: L{register_plugin}.
        (RRRRR:t_message_delivered(R	RRSR
RT((s;/usr/lib/python2.7/dist-packages/landscape/broker/server.pyR#Ws
cCs|jd}t|kr|d
k	r|ddkr|d}tjd|fd|f}idd6td6|d6|d6}|jj|d	tnd
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-idRBR(sNobody handled the %s message.s4Landscape 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.
soperation-resulttstatussresult-textRCN(R8R0RFtloggingterrorRRRI(R	RSRtopidtmtypetresult_texttresponse((s;/usr/lib/python2.7/dist-packages/landscape/broker/server.pyRobs


cCs|jj|jjdS(s
        Stop exchaging messages with the message server.

        Eventually, it is required by the plugin that no more message exchanges
        are performed.
        For example, when a reboot process in running, the client stops
        accepting new messages so that no client action is running while the
        machine is rebooting.
        Also, some activities should be explicitly require that no more
        messages are exchanged so some level of serialization in the client
        could be achieved.
        N(RR]R!(R	((s;/usr/lib/python2.7/dist-packages/landscape/broker/server.pytstop_exchanger}s
N($Rt
__module__t__doc__R6R/RR1RFR3R=RR?R@RAtFalseRKRNRURWR7RYRZR[RRRRR(R$RjRkR&R%R'R#RoRw(((s;/usr/lib/python2.7/dist-packages/landscape/broker/server.pyRIs@
					!
		(
RyRqttwisted.internet.deferRtlandscape.lib.twisted_utilRt
landscape.ampRtlandscape.manager.managerRRtobjectR(((s;/usr/lib/python2.7/dist-packages/landscape/broker/server.pyt<module>,s