def do_GET(self): logging.info("Receive GET media request: '%s'.", self.path) reg_object = re.match("/media/(\S+)", self.path) if (reg_object is None): self.reply(404) return media_name = reg_object.group(1) media_filepath = os.path.join(os.path.dirname(__file__), configuration.get_media_storage(), media_name) if (media_filepath is False): self.reply(404) return if (os.path.isfile(media_filepath) is False): self.reply(404) return media_descriptior = open(media_filepath) file_stat = os.fstat(media_descriptior.fileno()) self.send_response(200) self.send_header('Content-type', 'audio/x-wav') self.send_header('Content-Length', file_stat.st_size) self.send_header('Accept-Ranges', 'bytes') self.end_headers() self.wfile.write(media_descriptior.read()) media_descriptior.close() logging.info("Sent audio file '%s'.", media_name)
def stop(self): with self.__code_block_locker: self.__context.insert_code_block([ (command_type.COMMAND_EXIT, "") ]); reply_code = self.notify(tas_command_type.IVR_STOP); logging.info("Stop command from session manager is received (reply code: '%s').", str(reply_code)); return reply_code;
def do_GET(self): tas_host, tas_port = self.client_address[:2] logging.info( "Receive HTTP GET request from TAS: '%s' (address: '%s:%s').", self.path, tas_host, tas_port) request = http_parser.parse(http_method.HTTP_GET, self.path) if (request == None): self.__send_response(http_code.HTTP_BAD_REQUEST, "\"Impossible to parse GET request.\"") return # # TAS_IVR_EXECUTION_STATUS # if (request[struct_field.id] == tas_command_type.EXECUTION_STATUS): if (configuration.get_failure_execution_status_code() is not None): self.__send_response( configuration.get_failure_execution_status_code(), None, configuration.get_failure_execution_status_message()) return session_id = request[struct_field.session_id] #script_id = request[struct_field.script_id]; if (self.__get_session_manager().exist(session_id)): json_response = json_builder.execution_status_response("Ok") self.__send_response(http_code.HTTP_OK, json_response) else: self.__send_response( http_code.HTTP_NOT_FOUND, "\"Session '" + str(session_id) + "' is not found.\"") # # TAS_IVR_SERVICE_STATUS # elif (request[struct_field.id] == tas_command_type.SERVICE_STATUS): if (configuration.get_failure_service_status_code() is not None): self.__send_response( configuration.get_failure_service_status_code(), None, configuration.get_failure_service_status_message()) return json_response = json_builder.service_status_response( "Ok", {"amount_sessions": session_manager.get_amount_sessions()}) self.__send_response(http_code.HTTP_OK, json_response) else: self.__send_response( http_code.HTTP_BAD_REQUEST, "\"Unknown GET type command '" + str(request[struct_field.id]) + "'.\"")
def __run(self): while (self.__stop_flag is not True): with self.__stop_condition: self.__stop_condition.wait(self.__logging_period_seconds) logging.info( "IVR Simulator statistics:\n\n" "\tTAS REQs (in): %4d, TAS RESPs (in): %4d\n" "\tIVR REQs (out): %4d, IVR RESPs (out): %4d\n\n", statistical.get_tas_requests(), statistical.get_tas_responses(), statistical.get_ivr_requests(), statistical.get_ivr_responses())
def notify(self, tas_notification_id, message_payload = None): reply_code = None; string_message_id = tas_command_type.to_string(tas_notification_id); with self.__code_block_locker: trigger = self.__context.get_trigger(string_message_id); if (trigger is not None): self.__context.insert_code_block(trigger.commands); reply_code = trigger.reply_code; logging.info("Code block for the message '%s' is found (reply code: '%s').", string_message_id, str(reply_code)); with self.__tas_response_condition: self.__context.set_last_input_message((tas_notification_id, message_payload)); self.__tas_responses.append(string_message_id); self.__tas_response_condition.notify_all(); return reply_code;
def do_DELETE(self): tas_host, tas_port = self.client_address[:2] logging.info( "Receive HTTP DELETE request from TAS: '%s' (address: '%s:%s').", self.path, tas_host, tas_port) request = http_parser.parse(http_method.HTTP_DELETE, self.path) if (request == None): self.__send_response(http_code.HTTP_BAD_REQUEST, "\"Impossible to parse DELETE request.\"") return # # TAS_IVR_STOP_REQ # if (request[struct_field.id] != tas_command_type.IVR_STOP): self.__send_response( http_code.HTTP_BAD_REQUEST, "\"Unknown DELETE type command '" + str(request[struct_field.id]) + "'.\"") return if (configuration.get_failure_stop_ivr_code() is not None): self.__send_response(configuration.get_failure_stop_ivr_code(), None, configuration.get_failure_stop_ivr_message()) return session_id = request[struct_field.session_id] # script_id = request[struct_field.script_id]; if (self.__get_session_manager().exist(session_id) is True): reply_code = self.__get_session_manager().delete(session_id) if (reply_code is None): reply_code = http_code.HTTP_OK_DELETED json_response = json_builder.stop_ivr_response() self.__send_response(reply_code, json_response) else: self.__send_response( http_code.HTTP_NOT_FOUND, "\"Session '" + str(session_id) + "' is not found.\"")
def __send_response(self, http_code, json_data=None, http_message=None): time.sleep(configuration.get_response_delay() / 1000.0) self.send_response(http_code, http_message) self.send_header('Content-Type', 'application/json') body = None if (json_data is not None): body = json_data.encode("utf-8") self.send_header('Content-Length', len(body)) self.end_headers() if (body is not None): self.wfile.write(body) statistical.inc_ivr_responses() logging.info( "Send response to TAS (HTTP code '%d (%s)', HTTP body '%s')", http_code, str(http_message), body)
def __run(self): logging.debug("(IVR session '%s') session '%s' is started at '%s'.", self.__context.get_id(), self.__context.get_id(), time.ctime()); with self.__code_block_locker: command_container = self.__context.get_next_command(); while( (self.__active is True) and (command_container is not None) ): (command, arguments) = command_container; if (command == command_type.COMMAND_SEND): self.__process_send_command(arguments[0], arguments[1], arguments[2]); elif (command == command_type.COMMAND_TIMEOUT): self.__process_timeout_command(arguments[0]); elif (command == command_type.COMMAND_WAIT): self.__process_wait_command(arguments[0]); elif (command == command_type.COMMAND_PRINT): self.__process_print_comand(arguments[0]); elif (command == command_type.COMMAND_EXIT): logging.info("(IVR session '%s') exit command is detected - termination...", self.__context.get_id()); self.__active = False; elif (command == command_type.COMMAND_MOVE_JSON): self.__process_move_json(arguments[0]); elif (command == command_type.COMMAND_IF): self.__process_conditional_block(arguments[0], arguments[1]); else: logging.error("(IVR session '%s') unexpected command is detected...", self.__context.get_id()); with self.__code_block_locker: command_container = self.__context.get_next_command(); self.__manager.delete(self.__context.get_id(), internal = True); logging.info("(IVR session '%s') session is terminated at '%s'.", self.__context.get_id(), time.ctime());
def launch(session_id): with session_manager.__resource_locker: logging.info("Launch session instance (session id: '%s').", session_id) session_manager.__sessions[session_id].start()
def __process_send_command(self, method, tas_content, arguments): logging.debug("(IVR session '%s') command SEND is executing...", self.__context.get_id()); tas_link = None; tas_method = None; if (method == "SAY"): tas_link = self.__context.get_tas_link_say(); tas_method = "POST"; elif (method == "STOP_SAY"): tas_link = self.__context.get_tas_link_stop_say(); tas_method = "DELETE"; elif (method == "PLAY"): tas_link = self.__context.get_tas_link_play(); tas_method = "POST"; elif (method == "STOP_PLAY"): tas_link = self.__context.get_tas_link_stop_play(); tas_method = "DELETE"; elif (method == "COLLECT"): tas_link = self.__context.get_tas_link_collect(); tas_method = "POST"; elif (method == "STOP_COLLECT"): tas_link = self.__context.get_tas_link_stop_collect(); tas_method = "DELETE"; elif (method == "FORWARD"): tas_link = self.__context.get_tas_link_forward(); tas_method = "PUT"; elif (method == "EXCEPTION"): tas_link = self.__context.get_tas_link_exception(); tas_method = "PUT"; if (len(arguments) > 0): tas_link_pattern = arguments[0]; tas_link = self.__change_tas_link(tas_link, tas_link_pattern); tas_content = self.__translate_content(tas_content); logging.info("(IVR session '%s') send command request to TAS ('%s', '%s').", self.__context.get_id(), tas_method, method); (status, json_response) = self.__send(tas_method, tas_link, tas_content); if ( (status >= 200) and (status <= 299) ): if (tas_method == "POST"): response = json.loads(json_response); if (response.get("id", None) == None): logging.error("(IVR session '%s') TAS reply to '%s' command '%s' without JSON body with 'id' key.", self.__context.get_id(), tas_method, method); else: action_id = response['id']; if (method == "SAY"): self.__context.set_say_id(action_id); elif (method == "PLAY"): self.__context.set_play_id(action_id); elif (method == "COLLECT"): self.__context.set_collect_id(action_id); logging.info("(IVR session '%s') TAS accepts '%s' command '%s' and return action id: '%s'.", self.__context.get_id(), tas_method, method, action_id) else: logging.warning("(IVR session '%s') TAS reply to '%s' command '%s' by failure status (code: '%d').", self.__context.get_id(), tas_method, method, status);
def do_POST(self): tas_host, tas_port = self.client_address[:2] logging.info( "Receive HTTP POST request from TAS: '%s' (address: '%s:%s').", self.path, tas_host, tas_port) request = http_parser.parse(http_method.HTTP_POST, self.path) if (request == None): self.__send_response(http_code.HTTP_BAD_REQUEST, "\"Impossible to parse POST request.\"") return # # TAS_IVR_START_REQ # if (request[struct_field.id] == tas_command_type.IVR_START): if (configuration.get_failure_start_ivr_code() is not None): self.__send_response( configuration.get_failure_start_ivr_code(), None, configuration.get_failure_start_ivr_message()) return # extract TAS request for session and attach additional information json_request = self.rfile.read(int(self.headers['Content-Length'])) tas_request = json.loads(json_request) tas_request["tas_address"] = { "ip": tas_host, "port": tas_port } tas_request["account_id"] = request[struct_field.account_id] session_id = self.__get_session_manager().create( request[struct_field.script_id], tas_request) if (session_id is None): self.__send_response( http_code.HTTP_NOT_FOUND, "\"Session '" + str(session_id) + "' is not found.\"") return json_response = json_builder.start_ivr_response(session_id) self.__send_response(http_code.HTTP_OK_CREATED, json_response) self.__get_session_manager().launch(session_id) # # RESULT_ACTION # elif (request[struct_field.id] == tas_command_type.RESULT_COLLECT or request[struct_field.id] == tas_command_type.RESULT_PLAY or request[struct_field.id] == tas_command_type.RESULT_SAY): if (configuration.get_failure_action_result_code() is not None): self.__send_response( configuration.get_failure_action_result_code(), None, configuration.get_failure_action_result_message()) return session_id = request[struct_field.session_id] message_id = request[struct_field.id] # script_id = request[struct_field.script_id]; json_result = self.rfile.read(int(self.headers['Content-Length'])) logging.info("Callback action result is received (id: '%d').", request[struct_field.id]) logging.debug("Content of the callback result:\n%s", json_result) # it is represented by map because most probably other staff may be conveyed to session. json_instance = None try: json_instance = json.loads(json_result) except: logging.error( "Impossible to parse JSON - corrupted JSON payload is received." ) self.__send_response( http_code.HTTP_BAD_REQUEST, "\"Corrupted JSON payload in POST request.\"") return message_playload = { 'json': json_instance } if (self.__get_session_manager().exist(session_id)): reply_code = self.__get_session_manager().notify( session_id, message_id, message_playload) reply_message = None if (reply_code is None): reply_code = http_code.HTTP_OK reply_message = "\"Success.\"" else: reply_message = "\"Specified reply code is used.\"" self.__send_response(reply_code, reply_message) return self.__send_response( http_code.HTTP_NOT_FOUND, "\"Session '" + str(session_id) + "' is not found.\"") else: self.__send_response( http_code.HTTP_BAD_REQUEST, "\"Unknown POST type command '" + str(request[struct_field.id]) + "'.\"") return