Exemple #1
0
 def _handle_originate(self, e):
     '''Handle originate events
     '''
     uuid = e.getHeader('Unique-ID')
     sess = self.sessions.get(uuid, None)
     self.log.debug("handling originated session '{}'".format(uuid))
     if sess:
         sess.update(e)
         # store local time stamp for originate
         sess.originate_event_time = get_event_time(e)
         sess.originate_time = time.time()
         self.total_originated_sessions += 1
         return True, sess
     return False, sess
Exemple #2
0
    def __init__(self, event, uuid=None, con=None):
        self.events = Events(event)
        self.uuid = uuid or self.events['Unique-ID']
        self.con = con
        # sub-namespace for apps to set/get state
        self.vars = {}

        # external attributes
        self.duration = 0
        self.bg_job = None
        self.answered = False
        self.call = None
        self.hungup = False

        # time stamps
        self.times = {}.fromkeys(
            ('create', 'answer', 'req_originate', 'originate', 'hangup'))
        self.times['create'] = utils.get_event_time(event)
Exemple #3
0
    def _handle_create(self, e):
        '''Handle channel create events by building local
        `Session` and `Call` objects for state tracking.
        '''
        uuid = e.getHeader('Unique-ID')
        self.log.debug("channel created for session '{}'".format(uuid))
        # Record the newly activated session
        # TODO: pass con as weakref?
        con = self._tx_con if not self._shared else None
        sess = Session(event=e, con=con)
        sess.cid = self.get_id(e, 'default')
        # note the start time and current load
        # TODO: move this to Session __init__??
        sess.create_time = get_event_time(e)

        # Use our special Xheader to try and associate sessions into calls
        # (assumes that x-headers are forwarded by the proxy/B2BUA)
        call_uuid = e.getHeader('variable_{}'.format(self.call_corr_xheader))
        # If that fails then try using the freeswitch 'variable_call_uuid'
        # (only works if bridging takes place locally)
        if call_uuid is None:
            call_uuid = e.getHeader(self.call_corr_var)  # could be 'None'
            if not call_uuid:
                self.log.warn("Unable to associate session '{}' into calls"
                              .format(sess.uuid))

        # associate sessions into a call
        # (i.e. set the relevant sessions to reference each other)
        if call_uuid in self.calls:
            call = self.calls[call_uuid]
            self.log.debug("session '{}' is bridged to call '{}'".format(
                           uuid, call.uuid))
            # append this session to the call's set
            call.append(sess)

        else:  # this sess is not yet tracked so use its id as the 'call' id
            call = Call(call_uuid, sess)
            self.calls[call_uuid] = call
            self.log.debug("call created for session '{}'".format(call_uuid))
        sess.call = call
        self.sessions[uuid] = sess
        return True, sess
Exemple #4
0
    def _handle_answer(self, e):
        '''Handle answer events

        Returns
        -------
        sess : session instance corresponding to uuid
        '''
        uuid = e.getHeader('Unique-ID')
        sess = self.sessions.get(uuid, None)
        if sess:
            self.log.debug('answered session {} with call direction {}'
                           .format(uuid,  e.getHeader('Call-Direction')))
            sess.answered = True
            self.total_answered_sessions += 1
            sess.answer_time = get_event_time(e)
            sess.update(e)
            return True, sess
        else:
            self.log.info('skipping answer of {}'.format(uuid))
            return False, None
Exemple #5
0
 def time(self):
     """Time stamp for the most recent received event
     """
     return utils.get_event_time(self.events[0])
Exemple #6
0
    def _process_event(self, e, evname):
        '''Process an ESL event by delegating to the appropriate handler
        and any succeeding callback chain. This is the core handler lookup
        routine and should be optimized for speed.

        An event is considered consumed if:
        1) the handler + callback chain returns True
        2) the handler + callback chain raises a special exception

        Parameters
        ----------
        e : ESL.ESLEvent instance
            event received over esl on self._rx_con
        evname : str
            event type/name string
        '''
        # epoch is the time when first event is received
        if self._epoch:
            self._fs_time = get_event_time(e)
        else:
            self._epoch = self._fs_time = get_event_time(e)

        consumed = False  # is this event consumed by a handler/callback
        if 'CUSTOM' in evname:
            evname = e.getHeader('Event-Subclass')
        self.log.debug("receive event '{}'".format(evname))

        handler = self._handlers.get(evname, False)
        if handler:
            self.log.debug("handler is '{}'".format(handler))
            try:
                consumed, ret = utils.uncons(*handler(e))  # invoke handler
                # attempt to lookup a consuming client app by id
                model = ret[0]
                cid = model.cid if model else self.get_id(e, 'default')
                self.log.debug("consumer id is '{}'".format(cid))
                consumers = self.consumers.get(cid, False)
                if consumers and consumed:
                    cbs = consumers.get(evname, ())
                    self.log.debug(
                        "consumer '{}' has callback '{}' registered for ev {}"
                        .format(cid, cbs, evname)
                    )
                    # look up the client's callback chain and run
                    # e -> handler -> cb1, cb2, ... cbN
                    # map(operator.methodcaller('__call__', *ret),
                    #                           consumers.get(evname, ()))
                    # XXX assign ret on each interation in an attempt to avoid
                    # python's dynamic scope lookup
                    for cb, ret in zip(cbs, itertools.repeat(ret)):
                        cb(*ret)
                    # unblock `session.vars` waiters
                    if model in self._waiters:
                        for varname, events in self._waiters[model].items():
                            if model.vars.get(varname):
                                map(Event.set, events)

            # exception raised by handler/chain on purpose?
            except ESLError:
                consumed = True
                self.log.warning("Caught ESL error for event '{}':\n{}"
                                 .format(evname, traceback.format_exc()))
            except Exception:
                self.log.error("Failed to process event '{}':\n{}"
                               .format(evname, traceback.format_exc()))
            return consumed
        else:
            self.log.error("Unknown event '{}'".format(evname))
Exemple #7
0
def producer(eventURL, broker, auth_token, topic, metadata_topic_base, event_name, nside, area_center_nside=None, area_center_pixel=None, area_num_pixels=None, pixel_list=None):
    """
    Handle incoming events and perform a full scan.
    """
    if (area_center_nside is not None or area_center_pixel is not None or area_num_pixels is not None) and \
       (area_center_nside is None or area_center_pixel is None or area_num_pixels is None):
       raise RuntimeError("You have to either set none of the three options area_center_nside,area_center_pixel,area_num_pixels or all of them")

    try:
        # figure out if this is supposed to be JSON or .i3:
        url_file_path = urlparse(eventURL).path
        file_name, file_ext = os.path.splitext(url_file_path)
        if file_ext == '.json':
            file_format = 'json'
        elif file_ext == '.i3':
            file_format = 'i3'
        elif file_ext in ['.zst', '.gz', '.bz2', '.xz']:
            file_name, file_ext2 = os.path.splitext(file_name)
            if file_ext2 == '.i3':
                file_format = 'i3'
            else:
                raise RuntimeError("File format {}.{} is unknown (url={})".format(file_ext2, file_ext, eventURL))
        else:
            raise RuntimeError("File format {} is unknown (url={})".format(file_ext, eventURL))
            
        # load JSON
        if file_format == 'json':
            # get a file stager
            stagers = dataio.get_stagers()

            print('Skymap scanner is starting. Reading event information from JSON blob at `{0}`.'.format(eventURL))

            print("reading JSON blob from {0}".format( eventURL ))
            json_blob_handle = stagers.GetReadablePath( eventURL )
            if not os.path.isfile( str(json_blob_handle) ):
                print("problem reading JSON blob from {0}".format( eventURL ))
                raise RuntimeError("problem reading JSON blob from {0}".format( eventURL ))
            with open( str(json_blob_handle) ) as json_data:
                json_event = json.load(json_data)
            del json_blob_handle

            # extract the JSON message
            print('Event loaded. I am extracting it now...')
            GCDQp_packet = extract_json_message(json_event)
            
            # Note: the online messages to not use pulse cleaning, so we will need to work with
            # "SplitUncleanedInIcePulses" instead of "SplitInIcePulses" as the P-frame pulse map.
            # (Setting `pulsesName` will make sure "SplitInIcePulses" gets created and just points
            # to "SplitUncleanedInIcePulses".)
            pulsesName="SplitUncleanedInIcePulses"
        else: # file_format == 'i3'
            print('Skymap scanner is starting. Reading event information from i3 file at `{0}`.'.format(eventURL))
            GCDQp_packet = extract_i3_file( eventURL )

            pulsesName="SplitInIcePulses"
        
        # rename frame onbjects we might recreate
        GCDQp_packet = clean_old_frame_objects(GCDQp_packet)
        
        # (re-)create the online alert information
        GCDQp_packet = calculate_online_alert_dict(GCDQp_packet, pulsesName=pulsesName)
        
        # This step will create missing frame objects if necessary.
        print('Event extracted. I will now perform some simple tasks like the HESE veto calculation...')
        GCDQp_packet = prepare_frames(GCDQp_packet, pulsesName=pulsesName)
        print('Done.')
        
        
        # get the event id
        event_id = get_event_id(GCDQp_packet)

        # get the event time
        time = get_event_time(GCDQp_packet)

        print("Event `{0}` happened at `{1}`.".format(event_id, str(time)))

        print("Publishing events to   {}".format(topic))
        print("Publishing metadata to {}<...>".format(metadata_topic_base))

        print("Submitting scan...")
        send_scan(
            frame_packet=GCDQp_packet,
            broker=broker, 
            auth_token=auth_token,
            topic=topic,
            metadata_topic_base=metadata_topic_base,
            event_name=event_name,
            nside=nside,
            area_center_nside=area_center_nside,
            area_center_pixel=area_center_pixel,
            area_num_pixels=area_num_pixels,
            pixel_list=pixel_list
            )

        print("All scans for `{0}` are submitted.".format(event_id))
    except:
        exception_message = str(sys.exc_info()[0])+'\n'+str(sys.exc_info()[1])+'\n'+str(sys.exc_info()[2])
        print('Something went wrong while scanning the event (python caught an exception): ```{0}```'.format(exception_message))
        raise # re-raise exceptions