def handle_event(self,data): ''' Validates event, and if it's ok dispatchs Returns: * Event accepted. Bool * Description. String ''' # Validate event client = self.is_client(data['client_key']) if not client: return (False,'Client does not exist') # TODO Check if client has credit and so # if client ok # go on # else # return (False, "not enough credit") event = Event( client_key = data['client_key'],\ message = data['message'],\ tag = data['tag'],\ ip_addr = data['ip_addr'] ) # Check against self.current_events logger.debug('Checking if event is repeated') if self.current_events.exists(event.get_hash()): return (False,'Event repeated') else: # Add to current events self.current_events.set(event.get_hash(),event) # Dispatch event logger.debug('All tests passed. Dispatching event.') self.equeue.push_event(event) return (True,event.get_hash())
def action(self): logger.debug("Executing Announce Call Action") result = None ami = asterisk.AsteriskAMI() result = ami.announce_call(ddi=self.ddi, cli=self.cli, retries=self.retries, duration=self.duration, lang=self.lang, message=self.message) return result
def action(self): logger.debug("Executing Simple Call Action") result = None ami = asterisk.AsteriskAMI() result = ami.simple_call(ddi=self.ddi, cli=self.cli, retries=self.retries, duration=self.duration) return result
def __init__(self): logger.debug("Creating Event Manager object") self.equeue = event_queue self.equeue.reset_counter() self.current_event = None self.wqueue = worker_queue signal.signal(signal.SIGTERM, self.signal_pushback) signal.signal(signal.SIGINT, self.signal_pushback)
def get_action(self): client_key = self.current_event.client_key tag = self.current_event.tag step = self.current_event.step action_config = models.Client.query.filter( models.Client.client_key == client_key).first().get_action( tag, step) logger.debug('Action Config retrieved: {0}'.format(action_config)) if action_config: # Create object of type 'action_type' action = actions.Action.subclass()[action_config.action_type]( self.current_event.get_data(), params) return action
def get_auth_cookie(self, response): # Get headers and cookie value try: head = response.getheaders() for attr in head: if attr[0] == "set-cookie" and attr[1].split(";")[0].split( "=")[0] == COOKIE_NAME: cookieValue = attr[1].split(";")[0].split("=")[1].replace( "\"", "") break logger.debug("Authentication success . AuthCookie value: " + COOKIE_NAME + " = " + cookieValue) return {"Cookie": COOKIE_NAME + "=" + cookieValue} except: logger.error("Cannot get HTTP headers. Authentication failed!") raise Exception
def consume_queue(self): ''' Consumes an event and decides if it should be executed ''' logger.info("Waiting for events to arrive...") self.current_event = self.equeue.pop_event() t0 = time.time() # TODO Max numbers of steps if self.current_event.step < 3: try: action = self.get_action() logger.info( "Action decided in {0} seconds".format(time.time() - t0)) if action: logger.debug("Action: {0}".format(action)) self.wqueue.enqueue(action.execute) logger.info("Action {0} dispatched".format( action.get_type())) else: logger.info( "Action not definied. Changing step and pushing back to queue" ) self.current_event.step += 1 self.equeue.push_event(self.current_event) except Exception: logger.error( "Failed processing event: {1}\nException data is:\n{0}". format(traceback.format_exc(), self.current_event)) logger.error("Sending data back to queue...") try: self.equeue.push_event(self.current_event) logger.info("Data succesfully sent back to queue!") except: logger.critical("Could not send data back to queue") logger.critical(traceback.format_exc()) sys.exit(-1) else: logger.debug("Event step exceeded. Discarding event.") # TODO Save discarded event self.current_event = None
def signal_pushback(self, signum, frame): logger.debug("Caught signal" + str(signum)) try: if self.current_event: logger.error( "Signal recieved while inserting, sending data back to event queue..." ) try: self.equeue.push_event(self.current_event) logger.info("Data succesfully sent back to event queue!") except: logger.error("Can't insert back to event queue") logger.error("Event: {0}".format(self.current_event)) except: logger.debug("Something went wrong {0}".format( traceback.format_exc())) finally: logger.info("Exiting now") sys.exit(0)
def send_call(self, request): success = False for AsteriskServer in self.AsteriskServersList: #Authenticates to the server prior to sending the requests logger.info( "Trying HTTP connection to AMI {0}".format(AsteriskServer)) conn = httplib.HTTPConnection(AsteriskServer.host, port=AsteriskServer.port) try: logger.debug('Login Request: ' + LOGIN_REQUEST.format( AsteriskServer.user, AsteriskServer.passwd)) conn.request( "GET", LOGIN_REQUEST.format(AsteriskServer.user, AsteriskServer.passwd)) response = conn.getresponse() logger.debug('Login Response: {0}'.format(response.read())) logger.debug("Getting auth cookie...") auth_cookie = self.get_auth_cookie(response) except Exception: logger.error("Cannot connect to Asterisk server {0}".format( AsteriskServer.host)) break # Pass to next server, or return false else: logger.info("Connected to Asterisk server {0}".format( AsteriskServer.host)) conn.request('GET', request, None, auth_cookie) logger.debug("Call request made. Request: {0}".format(request)) response = conn.getresponse() #Handle response success = self.handle_response(response) break finally: logger.info("Disconnecting from Asterisk server {0}".format( AsteriskServer.host)) conn.close() return success
def handle_response(self, response): success = False logger.debug('Handling response...') try: xmldoc = response.read() xmldoc = xmldoc.rstrip("\r\n ") xml_response = xml.dom.minidom.parseString(xmldoc) logger.debug(xml_response.toprettyxml()) if xml_response.getElementsByTagName( "generic")[0].attributes["response"].value == "Success": success = True except: logger.error("Response handling failed. Response: ".format(xmldoc)) finally: logger.debug( 'Asterisk response handling successful. Return {0}'.format( success)) return success
def is_client(self,client_key): logger.debug('Checking client with key {0}'.format(client_key)) return models.Client.query.filter(models.Client.client_key == client_key).scalar().name
def __init__(self): self.equeue = event_queue self.current_events = shared_mem logger.debug("API manager created")
def execute(self): logger.debug('Execution started...') self.event_data['execution_date'] = datetime.utcnow() result = self.action() self.callback(result)
def signal_handler(signum, frame): logger.debug("Caught signal" + str(signum)) logger.info("Exiting now") sys.exit(0)
def signalHandler(signum, frame): logger.debug("Caught signal" + str(signum)) raise KeyboardInterrupt
'RETRIES={0}'.format(retries) timeout = 'data={0}'.format(duration) request = '&'.join([ANNOUNCE_CALL_REQUEST, timeout, variables]) return self.send_call(request) # Handles the TERM signal (triggered by keyboard or kill command) def signalHandler(signum, frame): logger.debug("Caught signal" + str(signum)) raise KeyboardInterrupt signal.signal(signal.SIGTERM, signalHandler) if __name__ == '__main__': logger.debug("Testing unit") ami = AsteriskAMI() data = {} data['ddi'] = 695624167 data['cli'] = 666666666 data['duration'] = 100 data['retries'] = 1 #data['message'] = urllib.quote_plus('Hello Charles') data['message'] = urllib.quote_plus( "Pacific Rim is a 2013 American science fiction monster film directed by Guillermo del Toro, written by del Toro and Travis Beacham, and starring Charlie Hunnam, Idris Elba, Rinko Kikuchi, Charlie Day, Robert Kazinsky, Max Martini, and Ron Perlman. The film is set in the 2020s, when Earth is at war with the Kaijus,[note1 1] colossal monsters which have emerged from an interdimensional portal on the floor of the Pacific Ocean. To combat the monsters, humanity unites to create the Jaegers [note2 1] : gigantic humanoid mecha, each controlled by at least two pilots, whose minds are joined by a neural bridge. Focusing on the war's later days, the story follows Raleigh Becket, a washed-up Jaeger pilot called out of retirement and teamed with rookie pilot Mako Mori as part of a last-ditch effort to defeat the Kaijus." ) ami.simple_call(data)