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
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)
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
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
def time(self): """Time stamp for the most recent received event """ return utils.get_event_time(self.events[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))
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