Beispiel #1
0
    def watch(self, interval, handler, evtype=None):
        """
        Request to receive notice of subscribe/unsubscribe events for a given
        event type.
        
        (Currently there is no option to also select on subscriber.)

        Returns a Deferred status value is returned indicating the outcome of the subscribe 
        operation - StatusVal.SUBSCRIBED indicates a successful outcome.
        
        HACK:  for subscription notification events, the subscribed event type is treated as 
        the source for subscription.  This avoids having to keep a separate table for watchers.
        """
        Trace("%s watch %us, handler %s to %s"%(self.getUri(), interval, str(handler), evtype), 
              context="EventLib.EventPubSub")
        sts = self.subscribe(interval, handler, evtype=URI.EventSubscribeType, source=evtype)
        if sts.syncValue() == StatusVal.SUBSCRIBED:
            # Scan existing subscriptions for immediate watch events
            Trace("- scanning subscriptions", context="EventLib.EventPubSub")
            event = makeEvent(evtype=URI.EventSubscribeType, source=evtype)
            for (t,s,h) in self._sub.iterateWild(evtype, None):
                Trace("- subscribed (%s,%s,%s)"%(t,s,h), context="EventLib.EventPubSub")
                handler.handleEvent(event)
            pass
        return sts
    def watch(self, interval, handler, evtype=None):
        """
        Request to receive notice of subscribe/unsubscribe events for a given
        event type.
        
        (Currently there is no option to also select on subscriber.)

        Returns a Deferred status value is returned indicating the outcome of the subscribe 
        operation - StatusVal.SUBSCRIBED indicates a successful outcome.
        
        HACK:  for subscription notification events, the subscribed event type is treated as 
        the source for subscription.  This avoids having to keep a separate table for watchers.
        """
        Trace("%s watch %us, handler %s to %s"%(self.getUri(), interval, str(handler), evtype), 
              context="EventLib.EventPubSub")
        sts = self.subscribe(interval, handler, evtype=URI.EventSubscribeType, source=evtype)
        if sts.syncValue() == StatusVal.SUBSCRIBED:
            # Scan existing subscriptions for immediate watch events
            Trace("- scanning subscriptions", context="EventLib.EventPubSub")
            event = makeEvent(evtype=URI.EventSubscribeType, source=evtype)
            for (t,s,h) in self._sub.iterateWild(evtype, None):
                Trace("- subscribed (%s,%s,%s)"%(t,s,h), context="EventLib.EventPubSub")
                handler.handleEvent(event)
            pass
        return sts
def makeSubscribeEvent(subtype, subscriber, interval, evtype, source):
    """
    Return an event object to convey the supplied subscription details.

    interval=0 for unsubscribe.
    """
    payload = [interval, evtype, source]
    return makeEvent(subtype, subscriber, payload)
Beispiel #4
0
def makeSubscribeEvent(subtype, subscriber, interval, evtype, source):
    """
    Return an event object to convey the supplied subscription details.

    interval=0 for unsubscribe.
    """
    payload = [interval, evtype, source]
    return makeEvent(subtype, subscriber, payload)
 def close(self):
     """
     Shut down the event router thread
     """
     # 'EventCloseType' is a private event type used to shut down the event router,
     # which is otherwise ignored.
     self._closing = True
     self._queue.put( (self.getUri(), makeEvent(evtype=EventCloseType, source=self.getUri())) )
     self._thread.join()
     return
Beispiel #6
0
 def close(self):
     """
     Shut down the event router thread
     """
     # 'EventCloseType' is a private event type used to shut down the event router,
     # which is otherwise ignored.
     self._closing = True
     self._queue.put( (self.getUri(), makeEvent(evtype=EventCloseType, source=self.getUri())) )
     self._thread.join()
     return
    def do_POST(self):
        """
        The client is forwarding an event or subscription request:
        it needs to be processed for the underlying local event router.
        """
        router = self.getRelay()
        msgbody = ""
        l = int(self.headers.get("content-length", "0"))
        if l:
            msgbody = self.rfile.read(l)
        Info("%s do_POST: '%s'" % (self.getRelay().getUri(), msgbody),
             "EventLib.EventRelayHTTPS")
        # Parse message and act accordingly
        msgdata = parseMessageData(msgbody)
        if msgdata == None:
            self.send_error(400, "Request body malformed")
            return
        if msgdata[0] == "forward":
            # msgdata = ["forward", [['R1', 'R2', 'R3'], 'ev:typ', 'ev:src', 'payload']]
            event = makeEvent(evtype=msgdata[1][1],
                              source=msgdata[1][2],
                              payload=msgdata[1][3])
            env = constructEnvelope(msgdata[1][0], event)
            self.getRelay().forward(event, env)
        elif msgdata[0] == "idle":
            self.send_response(200, "OK idle")
            self.end_headers()
            return
        elif msgdata[0] == "closedown":
            self.send_response(200, "OK closedown")
            self.end_headers()
            return
        else:
            self.send_error(400,
                            "Request body unrecognized option: " + msgdata[0])
            return

        # Complete request with success response
        self.send_response(200, "OK")
        self.end_headers()
    def do_POST(self):
        """
        The client is forwarding an event or subscription request:
        it needs to be processed for the underlying local event router.
        """
        router  = self.getRelay()
        msgbody = ""
        l       = int(self.headers.get("content-length","0"))
        if l:
            msgbody = self.rfile.read(l)
        Info("%s do_POST: '%s'"%(self.getRelay().getUri(),msgbody), "EventLib.EventRelayHTTPS")
        # Parse message and act accordingly
        msgdata = parseMessageData(msgbody)
        if msgdata == None:
            self.send_error(400, "Request body malformed") 
            return
        if msgdata[0] == "forward":
            # msgdata = ["forward", [['R1', 'R2', 'R3'], 'ev:typ', 'ev:src', 'payload']]
            event = makeEvent(evtype=msgdata[1][1],source=msgdata[1][2],payload=msgdata[1][3])
            env   = constructEnvelope(msgdata[1][0], event)
            self.getRelay().forward(event, env)
        elif msgdata[0] == "idle":
            self.send_response(200, "OK idle")
            self.end_headers() 
            return            
        elif msgdata[0] == "closedown":
            self.send_response(200, "OK closedown")
            self.end_headers() 
            return            
        else:
            self.send_error(400, "Request body unrecognized option: "+msgdata[0])
            return

        # Complete request with success response
        self.send_response(200, "OK")
        self.end_headers() 
 def processEvent(self):
     """
     This function is the HTTP client worker thread.
     """
     # Note: break out of event dispatch loop when closedown event is received
     # and closing flag is set.  This is to prevent DoS attack by faked closedown
     # event type, and to ensure that prior events received are all processed.
     delay_on_error_min = 0.125  # Back off retry interval on error..
     delay_on_error_max = 20.0  # ..
     delay_on_error = delay_on_error_min  # ..
     while True:
         if delay_on_error < delay_on_error_max:
             delay_on_error *= 2
         try:
             if not self._queue.empty():
                 Trace("%s queue.get ..." % (self.getUri()),
                       "EventLib.EventRelayHTTPC")
                 ###msgbody = self._queue.get()
                 ###Trace("%s get msgbody: %s"%(self.getUri(),msgbody), "EventLib.EventRelayHTTPC")
                 ###self._event.set()
                 msgbody = self.getQueuedItem()
                 [typ, env] = msgbody
                 if typ == "closedown":
                     if self._closing: break
                 else:
                     # process request as an HTTP POST request
                     data = makeEnvelopeData(env)
                     headers = {
                         "Content-type": "text/plain",
                         "Accept": "text/plain",
                         "Content-length": str(len(data))
                     }
                     self._httpcon.request("POST", "/request_path_ignored",
                                           data, headers)
                     response = self._httpcon.getresponse()
                     delay_on_error = delay_on_error_min
             else:
                 # Nothing in queue:
                 # issue a GET for incoming events
                 Trace("%s HTTP get ..." % (self.getUri()),
                       "EventLib.EventRelayHTTPC")
                 headers = {"Accept": "text/plain"}
                 self._httpcon.request("GET", "/request_path_ignored", None,
                                       headers)
                 response = self._httpcon.getresponse()
                 if response.status == 200:
                     delay_on_error = delay_on_error_min
                     msgbody = response.read()
                     Trace("%s get msgbody: %s" % (self.getUri(), msgbody),
                           "EventLib.EventRelayHTTPC")
                     # Parse message and act accordingly
                     msgdata = parseMessageData(msgbody)
                     Trace(
                         "%s get msgdata: %s" %
                         (self.getUri(), str(msgdata)),
                         "EventLib.EventRelayHTTPC")
                     if msgdata == None:
                         #TODO: Log "Request body malformed"
                         pass
                     elif msgdata[0] == "forward":
                         # msgdata = ["forward", [['R1', 'R2', 'R3'], 'ev:typ', 'ev:src', 'payload']]
                         event = makeEvent(evtype=msgdata[1][1],
                                           source=msgdata[1][2],
                                           payload=msgdata[1][3])
                         env = constructEnvelope(msgdata[1][0], event)
                         self.forward(event, env)
                     elif msgdata[0] == "idle":
                         # Idle response gives client a chance to send if anything is queued
                         pass
                     else:
                         #TODO: handle closedown message?
                         Warn(
                             "%s Request body unrecognized option: %s" %
                             (self.getUri(), msgdata[0]), "EventRelayHTTPC")
                         pass
                 elif response.status == 503:
                     Trace(
                         "%s processEvent error response: %u, %s" %
                         (self.getUri(), response.status, response.reason),
                         "EventLib.EventRelayHTTPC")
                     # Remote end closed down
                     break
                 else:
                     # TODO: (log error response)
                     Warn(
                         "%s processEvent error response: %u, %s" %
                         (self.getUri(), response.status, response.reason),
                         "EventLib.EventRelayHTTPC")
                     time.sleep(delay_on_error)
         except httplib.BadStatusLine, e:
             # This can happen at closedown
             Info(
                 "%s processEvent bad response: %s" %
                 (self.getUri(), str(e)), "EventLib.EventRelayHTTPC")
             time.sleep(delay_on_error)
         except httplib.CannotSendRequest, e:
             # This can happen at closedown
             Info("%s Cannot send request: %s" % (self.getUri(), str(e)),
                  "EventLib.EventRelayHTTPC")
             time.sleep(delay_on_error)
 def processEvent(self):
     """
     This function is the HTTP client worker thread.
     """
     # Note: break out of event dispatch loop when closedown event is received
     # and closing flag is set.  This is to prevent DoS attack by faked closedown
     # event type, and to ensure that prior events received are all processed.
     delay_on_error_min = 0.125              # Back off retry interval on error..
     delay_on_error_max = 20.0               # ..
     delay_on_error     = delay_on_error_min # ..
     while True:
         if delay_on_error < delay_on_error_max:
             delay_on_error *= 2
         try:
             # PLEASE NOTE: In the event that the HTTPC is run as duplex, not simplex
             # then the post methods will be delayed if nothing is sent down to the client
             # from the server. This timeout is controlled by QUEUE_WAIT_TIMEOUT in EventRouterHTTPS.py
             if self._simplex == True:
                 self._queueEvent.wait()
                 self._queueEvent.clear()
 
             if not self._queue.empty():
                 Trace("%s queue.get ..."%(self.getUri()), "EventLib.EventRelayHTTPC")
                 ###msgbody = self._queue.get()
                 ###Trace("%s get msgbody: %s"%(self.getUri(),msgbody), "EventLib.EventRelayHTTPC")
                 ###self._event.set()
                 msgbody = self.getQueuedItem()
                 [typ,env] = msgbody
                 if typ == "closedown":
                     if self._closing: break
                 else:
                     # process request as an HTTP POST request
                     data    = makeEnvelopeData(env)
                     headers = { "Content-type": "text/plain",
                                 "Accept": "text/plain",
                                 "Content-length": str(len(data)) }
                     self._httpcon.request("POST", "/request_path_ignored", data, headers)
                     response = self._httpcon.getresponse()
                     delay_on_error = delay_on_error_min
             elif self._simplex == False:
                 # Nothing in queue:
                 # issue a GET for incoming events
                 _log.info("%s HTTP get ..."%(self.getUri()))
                 headers = { "Accept": "text/plain" }
                 self._httpcon.request("GET", "/request_path_ignored", None, headers)
                 response = self._httpcon.getresponse()
                 if response.status == 200:
                     delay_on_error = delay_on_error_min
                     msgbody = response.read()
                     Trace("%s get msgbody: %s"%(self.getUri(),msgbody), "EventLib.EventRelayHTTPC")
                     # Parse message and act accordingly
                     msgdata = parseMessageData(msgbody)
                     Trace("%s get msgdata: %s"%(self.getUri(),str(msgdata)), "EventLib.EventRelayHTTPC")
                     if msgdata == None:
                         #TODO: Log "Request body malformed"
                         pass
                     elif msgdata[0] == "forward":
                         # msgdata = ["forward", [['R1', 'R2', 'R3'], 'ev:typ', 'ev:src', 'payload']]
                         event = makeEvent(evtype=msgdata[1][1],source=msgdata[1][2],payload=msgdata[1][3])
                         env   = constructEnvelope(msgdata[1][0], event)
                         self.forward(event, env)
                     elif msgdata[0] == "idle":
                         # Idle response gives client a chance to send if anything is queued
                         pass
                     else:
                         #TODO: handle closedown message?
                         Warn( "%s Request body unrecognized option: %s"%(self.getUri(),msgdata[0]), "EventRelayHTTPC")
                         pass
                 elif response.status == 503:
                     Trace( "%s processEvent error response: %u, %s"%(self.getUri(),response.status,response.reason), "EventLib.EventRelayHTTPC")
                     # Remote end closed down
                     break
                 else:
                     # TODO: (log error response)
                     Warn( "%s processEvent error response: %u, %s"%(self.getUri(),response.status,response.reason), "EventLib.EventRelayHTTPC")
                     time.sleep(delay_on_error)
                 
         except httplib.BadStatusLine, e:
             # This can happen at closedown
             Info( "%s processEvent bad response: %s"%(self.getUri(), str(e)), "EventLib.EventRelayHTTPC")
             time.sleep(delay_on_error)
         except httplib.CannotSendRequest, e:
             # This can happen at closedown
             Info( "%s Cannot send request: %s"%(self.getUri(), str(e)), "EventLib.EventRelayHTTPC")
             time.sleep(delay_on_error)