Beispiel #1
0
    def get_variable(self, name):
        if name not in self.__variables:
            logging.error(
                "Impossible to get value of variable '%s' because it does not exist.",
                name)
            return None

        return self.__variables[name]
Beispiel #2
0
    def __run(self):
        logging.debug("(Q Service 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], arguments[3])
            
            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_REPLY:
                self.__process_reply_command(arguments[0], arguments[1], arguments[2], arguments[3])

            elif command == command_type.COMMAND_IGNORE:
                self.__process_ignore_command()

            elif command == command_type.COMMAND_ASK:
                self.__process_ask_command(arguments[0])

            elif command == command_type.COMMAND_ASSIGN:
                self.__process_assign_command(arguments[0], arguments[1])

            elif command == command_type.COMMAND_PRINT:
                self.__process_print_comand(arguments[0])
            
            elif command == command_type.COMMAND_EXIT:
                logging.info("(QSim Service task '%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("(QSim Service task '%s') unexpected command is detected...", self.__context.get_id())

            self.__previous_command = command

            with self.__code_block_locker:
                command_container = self.__context.get_next_command()
        
        self.__manager.delete(self.__context.get_id())
        logging.info("(QSim Service task '%s') session is terminated at '%s'.", self.__context.get_id(), time.ctime())
Beispiel #3
0
    def __assign_variable_value(self, variable_name, variable_value):
        if variable_name not in {"SESSION_ID", "PARTY_ID", "RCACCOUNT_ID", "RCEXTENSION_ID"}:
            logging.error("(QSim Service task '%s') Variable '%s' is not supported.", self.__context.get_id(), variable_name)
            return

        if variable_name == "SESSION_ID":
            self.__context.set_session_id(variable_value)
        elif variable_name == "PARTY_ID":
            self.__context.set_party_id(variable_value)
        elif variable_name == "RCACCOUNT_ID":
            self.__context.set_rcaccount_id(variable_value)
        elif variable_name == "RCEXTENSION_ID":
            self.__context.set_rcextension_id(variable_value)
Beispiel #4
0
    def __process_command_content(self):
        if self.__content_flag is not True:
            logging.error("Incorrect script-file format in line '%s' (%d).", self.__line_counter, self.__line)
            sys.exit(error_code.ERROR_SCRIPT_INCORRECT_FORMAT)

        reg_object = re.match("HEADER (.*) (.*)", self.__line)

        if reg_object:
            key = reg_object.group(1).rstrip().lstrip()
            value = reg_object.group(2).rstrip().lstrip()

            self.__command_headers[key] = value
        else:
            self.__command_content += self.__line
Beispiel #5
0
    def load(script_id):
        script_filepath = os.path.join(script.__DEFAULT_FOLDER, script_id)
        if script_filepath is False:
            logging.error(
                "Impossible to load script because it does not exist.")
            sys.exit(error_code.ERROR_SCRIPT_NOT_FOUND)

        with open(script_filepath) as file_descriptor:
            content = file_descriptor.readlines()

        block = code_block(0, content)
        block.load()

        return block
Beispiel #6
0
 def __process_command_else(self, command):
     if self.__command_sequence[len(self.__command_sequence) - 1][0] != command_type.COMMAND_IF:
         if self.__subfunction == code_block_type.CODE_BLOCK_MAIN:
             logging.error("Unexpected keyword '%s' (else branch of conditional block) without conditional block in line '%s' (%d).", command, self.__line, self.__line_counter)
             sys.exit(error_code.ERROR_SCRIPT_INCORRECT_FORMAT)
             
         # go to upper level to process it without shifting line (we still need to process else keyword)
         self.__line_counter = self.__line_counter - 1
         return False
     
     else:
         block = code_block(self.__line_counter, self.__content, code_block_type.CODE_BLOCK_CONDITION)
         block.load()
         
         self.__line_counter = block.get_cursor()
         self.__command_sequence.append((command, [block.get_commands()]))
     
     return True
Beispiel #7
0
    def send_request(self, http_method, http_link, json_request, general_headers):
        response_body = None

        connection = http.client.HTTPConnection(self.__address, self.__port, timeout=1)

        try:
            logging.vip("Send HTTP request to TAS (%s:%s): '%s' '%s'.", self.__address, self.__port, http_method, http_link)
            logging.debug("JSON payload of the HTTP request to TAS: '%s'.", json_request)

            headers = {"Content-Type": "application/json",
                       "Accept": "*/*"}

            body = None
            if json_request is not None:
                body = json_request.encode("utf-8")
                headers['Content-Length'] = len(body)

            headers.update(general_headers)

            statistical.inc_qsim_requests()
            connection.request(http_method, http_link, body, headers)

            logging.debug("Check for HTTP response from TAS.")
            response = connection.getresponse()
            response_status = response.status

            logging.debug("Read body of the HTTP response from TAS.")
            response_body = response.read()

            statistical.inc_qsim_responses()
            logging.vip("HTTP response (code: %d) from TAS:", response_status)
            logging.debug(response_body.decode("utf-8"))

        except Exception as expection_object:
            response_status = 600
            logging.error("Impossible to communicate correctly with TAS using HTTP (reason: '%s')." % expection_object)

        finally:
            connection.close()
        
        return response_status, response_body
Beispiel #8
0
 def __process_command_trigger(self, command, argument):
     if self.__subfunction != code_block_type.CODE_BLOCK_MAIN:
         logging.error("Unexpected keyword '%s' (start trigger) in sub-block in line '%s' (%d).", command, self.__line, self.__line_counter)
         sys.exit(error_code.ERROR_SCRIPT_INCORRECT_FORMAT)
     
     if argument in self.__triggers:
         logging.error("Trigger redefinition (trigger for '%s' is already defined) in line '%s' (%d).", argument, self.__line, self.__line_counter)
         sys.exit(error_code.ERROR_SCRIPT_INCORRECT_FORMAT)
     
     # extract code block
     block = code_block(self.__line_counter, self.__content, code_block_type.CODE_BLOCK_TRIGGER)
     block.load()
     
     self.__line_counter = block.get_cursor()
     
     # extract arguments
     command_line_arguments = argument.split()
     
     if len(command_line_arguments) == 1:
         trigger_message_id, trigger_reply_code = command_line_arguments[0], None
         
     elif len(command_line_arguments) == 2:
         trigger_message_id, trigger_reply_code = command_line_arguments[0], command_line_arguments[1]
         
     else:
         logging.error("Invalid number of arguments of '%d' in line '%s' (%d).", len(command_line_arguments), self.__line, self.__line_counter)
         sys.exit(error_code.ERROR_SCRIPT_AMOUNT_ARGUMENTS)
     
     if trigger_reply_code is not None:
         trigger_reply_code = int(trigger_reply_code)
     
     # create and store trigger
     self.__triggers[trigger_message_id] = trigger(trigger_message_id, block.get_commands(), trigger_reply_code)
     
     return True
Beispiel #9
0
    def __process_reply_command(self, code, message, json_body, headers):
        logging.debug("(QSim Service task '%s') command REPLY is executing...", self.__context.get_id())

        previous_message = self.__context.get_last_input_message()[0]

        if previous_message is None:
            logging.error("(QSim Service task '%s') impossible to reply, nothing was received.", self.__context.get_id())
            return

        if previous_message == tas_command_type.TASK_START:
            if (json_body is None) or (len(json_body) == 0):
                json_body = json_builder.start_qsim_response(self.__context.get_id())

            event = event_start_response(code, message, headers, json_body)

        else:
            event = event_response(code, message, headers, json_body)

        queue.put(event)

        logging.debug("(QSim Service task '%s') Send event response to '%s' (code: '%d') to HTTP handler queue.",
                      self.__context.get_id(), previous_message, code)
Beispiel #10
0
    def evaluate(self):
        (variables_names, variables_values) = self.__extract_variables()
        for index_variable in range(len(variables_names)):
            if variables_names[index_variable] == "$(QSIM.CONTEXT)":
                internal_variable_name = "expression_analyser.current_context.get_tas_info()"
            else:
                internal_variable_name = "variables_values[" + str(
                    index_variable) + "]"

            self.__expression = self.__expression.replace(
                variables_names[index_variable], internal_variable_name)

        result = None
        try:
            with expression_analyser.__evaluation_guard:
                expression_analyser.current_context = self.__context
                result = eval(self.__expression)
        except:
            logging.error("Impossible to evaluate expression '%s'.",
                          self.__expression)

        return result
Beispiel #11
0
    def __send_response(self,
                        http_code,
                        json_data=None,
                        http_message=None,
                        headers=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))

        if headers is not None:
            for key, value in headers.items():
                self.send_header(key, value)

        try:
            self.end_headers()

            if body is not None:
                self.wfile.write(body)

            statistical.inc_qsim_responses()

            logging.info("Send response to TAS (code '%d (%s)', body '%s')",
                         http_code, str(http_message), body)

        except ConnectionResetError:
            logging.error(
                "Impossible to send request to TAS due to reset connection.")

        except Exception as expection_object:
            logging.error(
                "Impossible to send request to TAS due to unknown reason ('%s')."
                % expection_object)
Beispiel #12
0
    def parse(method, path):
        if method == http_method.HTTP_POST:
            reg_object = re.match(
                "/telephony/v1/account/(\d+)/services/queue/(\d+)/voice/tasks$",
                path)
            if (reg_object):
                return http_parser.extract_qsim_start_request(reg_object)

            if re.match(".*/on-command-error", path):
                return http_parser.extract_tas_error_callback()
            if re.match(".*/on-command-update", path):
                return http_parser.extract_tas_update_callback()

        elif method == http_method.HTTP_DELETE:
            reg_object = re.match(
                "/telephony/v1/account/(\d+)/services/queue/(\d+)/voice/tasks/(\d+)",
                path)
            if reg_object:
                return http_parser.extract_qsim_stop_request(reg_object)

        elif method == http_method.HTTP_GET:
            reg_object = re.match(
                "/telephony/v1/account/(\d+)/services/queue/(\d+)/voice/tasks/(\d+)",
                path)
            if reg_object:
                return http_parser.extract_qsim_execution_status(reg_object)

            reg_object = re.match(
                "/telephony/v1/account/(\d+)/services/status(.*)", path)
            if reg_object:
                return http_parser.extract_qsim_service_status(reg_object)

        else:
            logging.error("HTTP method '%s' is not supported.", method)
            return parser_failure.UNKNOWN_METHOD

        return parser_failure.UNKNOWN_PATH
Beispiel #13
0
    def __extract_variables(self):
        variables_names = []
        variables_values = []

        start_variable = self.__expression.find("$(", 0)
        while start_variable >= 0:
            stop_variable = self.__expression.find(")", start_variable + 1)
            if stop_variable < 0:
                logging.error(
                    "Impossible to parse expression with variable - incorrect format of variables (expression: '%s').",
                    self.__expression)
                break

            # extract variable name
            variable_name = self.__expression[start_variable:stop_variable + 1]

            # check if it is a system variable
            if variable_name == "$(QSIM.CONTEXT)":
                variables_names.append(variable_name)
                variables_values.append(self.__context)

            else:
                if variable_name not in self.__context.get_variables():
                    logging.error(
                        "Impossible to find variable '%s' because of not declaration (expression: '%s').",
                        variable_name, self.__expression)
                    break

                if variable_name not in variables_names:
                    variables_names.append(variable_name)
                    variables_values.append(
                        self.__context.get_variable(variable_name))

            start_variable = self.__expression.find("$(", stop_variable)

        return variables_names, variables_values
Beispiel #14
0
    def do_POST(self):
        tas_host, tas_port = self.client_address[:2]

        logging.vip(
            "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 isinstance(request, parser_failure):
            self.__send_response(self.__parser_failure_to_http_code(request),
                                 "\"Impossible to process POST request.\"")
            return

        #
        # TASK_START
        #
        if request[struct_field.id] == tas_command_type.TASK_START:
            if configuration.get_failure_start_qsim_code() is not None:
                self.__send_response(
                    configuration.get_failure_start_qsim_code(), None,
                    configuration.get_failure_start_qsim_message())
                return

            # extract TAS request for session and attach additional information
            tas_request = {}
            json_request = self.rfile.read(int(
                self.headers['Content-Length'])).decode('utf-8')
            if (json_request is not None) and (len(json_request) > 0):
                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]

            # fill by default values
            tas_request["session_id"] = tas_request["sessionId"]
            tas_request["party_id"] = tas_request["inPartyId"]
            tas_request["q_party_id"] = tas_request["qPartyId"]
            tas_request["rcaccount_id"] = tas_request["account_id"]
            tas_request["rcextension_id"] = tas_request["account_id"]
            tas_request["rcbrand_id"] = "1210"

            logging.debug(
                "QueueId (%s): Store default party ID (%s) and session ID (%s)."
                % (request[struct_field.script_id], tas_request["party_id"],
                   tas_request["session_id"]))

            if self.__get_session_manager().create(
                    request[struct_field.script_id], tas_request) is False:
                message = "Impossible to create session object due to lack of scenario file."
                logging.error(message)
                self.__send_response(http_code.HTTP_NOT_FOUND,
                                     "\"%s\"" % message)
                return

            try:
                response = queue.get(True, 2)
            except:
                response = None

            if response is None:
                message = "Event with response is not received."
                logging.error(message)
                self.__send_response(http_code.HTTP_INTERNAL_SERVER_ERROR,
                                     "\"%s\"" % message)
                return

            event_type = type(response)
            if event_type == event_start_response:
                self.__send_response(response.code, response.body,
                                     response.message, response.headers)

            elif event_type == event_ignore:
                pass

            else:
                message = "Unexpected event is received."
                logging.error(message)

        #
        # RESULT_ACTION
        #
        elif (request[struct_field.id] == tas_command_type.ON_COMMAND_UPDATE or
              request[struct_field.id] == tas_command_type.ON_COMMAND_ERROR):

            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

            message_size = int(self.headers['Content-Length'])
            json_result = self.rfile.read(message_size).decode('utf-8')

            # it is represented by map because most probably other staff may be conveyed to session.
            json_instance = None
            if message_size > 0:
                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}

            action_type = request[struct_field.id]
            command_id = json_instance.get("commandId", None)
            if command_id is None:
                logging.error(
                    "Incorrect action request - commandId is not found in JSON."
                )
                self.__send_response(
                    http_code.HTTP_BAD_REQUEST,
                    "\"JSON body does not contain 'commandId' field.\"")
                return

            logging.info("Received callback id: '%s':", command_id)
            logging.debug(json_result)

            session_instance = self.__get_session_manager(
            ).get_session_by_command_id(command_id)

            if session_instance is not None:
                # check if code is returned by trigger
                reply_code = session_instance.notify(action_type,
                                                     message_playload)
                #reply_code = self.__get_session_manager().notify(session_id, command_id, message_playload)

                if reply_code is None:
                    # if there is no trigger then let's take it from the queue, if there is user-specific code
                    try:
                        response = queue.get(True, 1)
                        event_type = type(response)
                        if event_type == event_ignore:
                            logging.debug(
                                "Ignore incoming request (do not sent response)."
                            )
                            return

                        reply_code = response.code
                        reply_message = response.message

                        logging.debug(
                            "Specific reply to incoming request '%s' (code: '%s', command ID: '%s')."
                            % (command_id, reply_code, reply_message))

                    except:
                        # otherwise send default code
                        reply_code = http_code.HTTP_OK
                        reply_message = "\"Success.\""

                        logging.debug(
                            "Default reply is used for incoming request '%s'."
                            % action_type)
                else:
                    reply_message = "\"Specified reply code is used.\""
                    logging.debug(
                        "Specific reply is used for incoming request '%s' via trigger "
                        "(code: '%s', message: '%s')." %
                        (command_id, reply_code, reply_message))

                self.__send_response(reply_code, reply_message)
                return

            self.__send_response(
                http_code.HTTP_NOT_FOUND, "\"Session for action '" +
                str(command_id) + "' is not found.\"")
            self.__get_session_manager().get_session_by_command_id(command_id)

        else:
            self.__send_response(
                http_code.HTTP_BAD_REQUEST, "\"Unknown POST type command '" +
                str(request[struct_field.id]) + "'.\"")
            return
Beispiel #15
0
    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 isinstance(request, parser_failure):
            self.__send_response(self.__parser_failure_to_http_code(request),
                                 "\"Impossible to process DELETE request.\"")
            return

        #
        # TASK_STOP
        #
        if request[struct_field.id] != tas_command_type.TASK_STOP:
            self.__send_response(
                http_code.HTTP_BAD_REQUEST, "\"Unknown DELETE type command '" +
                str(request[struct_field.id]) + "'.\"")
            return

        if configuration.get_failure_stop_qsim_code() is not None:
            self.__send_response(configuration.get_failure_stop_qsim_code(),
                                 None,
                                 configuration.get_failure_stop_qsim_message())
            return

        session_id = request[struct_field.session_id]

        if self.__get_session_manager().exist(session_id) is True:
            # notify to check whether scenario contains something specific about termination
            self.__get_session_manager().notify(session_id,
                                                tas_command_type.TASK_STOP,
                                                None)

            try:
                response = queue.get(True, 1)
            except:
                response = None

            if response is None:  # scenario does not have anything specific about termination
                reply_code = self.__get_session_manager().delete(session_id)
                if reply_code is None:
                    reply_code = http_code.HTTP_OK_NO_CONTENT

                logging.info(
                    "Reply is not provided for TASK_STOP, use simulator response code (%d).",
                    reply_code)
                self.__send_response(reply_code)

            else:
                event_type = type(response)
                if event_type == event_ignore:
                    pass

                elif event_type == event_response:
                    logging.info(
                        "Reply to TASK_STOP is provided by scenario (code: %d).",
                        response.code)
                    self.__send_response(response.code, response.body,
                                         response.message, response.headers)

                else:
                    message = "Unexpected event is received."
                    logging.error(message)

        else:
            self.__send_response(
                http_code.HTTP_NOT_FOUND,
                "\"Session '" + str(session_id) + "' is not found.\"")
Beispiel #16
0
 def __process_command_end_trigger(self, command):
     if self.__subfunction != code_block_type.CODE_BLOCK_TRIGGER:
         logging.error("Unexpected keyword '%s' is appeard in non-subbody in line '%s' (%d).", command, self.__line, self.__line_counter)
         sys.exit(error_code.ERROR_SCRIPT_INCORRECT_FORMAT)
     
     return True
Beispiel #17
0
 def __process_command_end_if(self, command):
     if self.__subfunction != code_block_type.CODE_BLOCK_CONDITION:
         logging.error("Unexpected keyword '%s' (end of conditional block) without conditional block in line '%s' (%d).", command, self.__line, self.__line_counter)
         sys.exit(error_code.ERROR_SCRIPT_INCORRECT_FORMAT)
     
     return True
Beispiel #18
0
    def __process_command(self, command, argument):
        if self.__content_flag is True:
            if self.__command_sequence[-1][0] == command_type.COMMAND_REPLY:
                self.__command_sequence[-1][1][2] = self.__command_content.lstrip().rstrip()
                self.__command_sequence[-1][1][3] = self.__command_headers
            elif self.__command_sequence[-1][0] == command_type.COMMAND_SEND:
                self.__command_sequence[-1][1][1] = self.__command_content.lstrip().rstrip()
                self.__command_sequence[-1][1][2] = self.__command_headers
        
        self.__content_flag = False
        self.__command_content = ""
        self.__command_headers = {}

        if command == command_type.COMMAND_SEND:
            self.__process_command_send(command, argument)

        elif command == command_type.COMMAND_TIMEOUT:
            self.__process_command_timeout(command, argument)
        
        elif command == command_type.COMMAND_WAIT:
            self.__process_command_wait(command, argument)

        elif command == command_type.COMMAND_REPLY:
            self.__process_command_reply(command, argument)

        elif command == command_type.COMMAND_IGNORE:
            self.__process_command_ignore(command, argument)

        elif command == command_type.COMMAND_ASK:
            self.__process_command_ask(command, argument)

        elif command == command_type.COMMAND_ASSIGN:
            self.__process_command_assign(command, argument)

        elif command == command_type.COMMAND_EXIT:
            self.__process_command_exit(command)
        
        elif command == command_type.COMMAND_PRINT:
            self.__process_command_print(command, argument)

        elif command == command_type.COMMAND_MOVE_JSON:
            self.__process_command_move_json(command, argument)
        
        elif command == command_type.COMMAND_IF:
            self.__process_command_if(command, argument)
        
        elif command == command_type.COMMAND_ELSE:
            if self.__process_command_else(command) is False:
                return False
        
        elif command == command_type.COMMAND_END_IF:
            if self.__process_command_end_if(command) is False:
                return False
        
        elif command == command_type.COMMAND_TRIGGER:
            self.__process_command_trigger(command, argument)
        
        elif command == command_type.COMMAND_END_TRIGGER:
            if self.__process_command_end_trigger(command) is False:
                return False
        
        else:
            logging.error("Unknown command is detected '%s' in line '%s' (%d).", command, self.__line, self.__line_counter)
            sys.exit(error_code.ERROR_SCRIPT_UNKNOWN_COMMAND)
Beispiel #19
0
    def __process_send_command(self, action, tas_content, headers, arguments):
        logging.debug("(QSim Service task '%s') command SEND is executing...", self.__context.get_id())
        
        if action == "PLAY":
            tas_link = self.__context.get_tas_link_start_play()
            tas_method = "POST"
        
        elif action == "STOP_PLAY":
            tas_link = self.__context.get_tas_link_stop_play()
            tas_method = "DELETE"

        elif action == "GET_PLAY":
            tas_link = self.__context.get_tas_link_stop_play()
            tas_method = "GET"

        elif action == "COLLECT":
            tas_link = self.__context.get_tas_link_start_collect()
            tas_method = "POST"

        elif action == "GET_COLLECT":
            tas_link = self.__context.get_tas_link_get_collect()
            tas_method = "GET"

        elif action == "STOP_COLLECT":
            tas_link = self.__context.get_tas_link_stop_collect()
            tas_method = "DELETE"

        elif action == "FORWARD":
            party_id = None
            if len(arguments) > 0:
                expression = arguments[0]
                analyser = expression_analyser(expression, self.__context)
                party_id = analyser.evaluate()
                arguments = []

            tas_link = self.__context.get_tas_link_forward(party_id)
            tas_method = "POST"

        elif action == "FORWARD_GROUP":
            tas_link = self.__context.get_tas_link_add_forward_group()
            tas_method = "POST"

        elif action == "PATCH_FORWARD_GROUP":
            tas_link = self.__context.get_tas_link_forward_group()
            tas_method = "PATCH"

        elif action == "GET_FORWARD_GROUP":
            tas_link = self.__context.get_tas_link_forward_group()
            tas_method = "GET"

        elif action == "DELETE_FORWARD_GROUP":
            tas_link = self.__context.get_tas_link_forward_group()
            tas_method = "DELETE"

        elif action == "GET_SESSION":
            tas_link = self.__context.get_tas_link_session()
            tas_method = "GET"

        else:
            logging.error("Unknown send command '%s'.", action)
            return

        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("(QSim Service task '%s') send command request to TAS ('%s', '%s').", self.__context.get_id(), tas_method, action)


        custom_headers = {"rcaccountid": self.__context.get_rcaccount_id(),
                          "rcextensionid": self.__context.get_rcextension_id(),
                          "rcbrandid": self.__context.get_brand_id(),
                          "origin": "127.0.0.1:" + str(configuration.get_qsim_port())}

        # add new and overwrite existed default custom headers in line with scenario
        for key, value in headers.items():
            custom_headers[key.lower()] = value

        (status, json_response) = self.__send(tas_method, tas_link, tas_content, custom_headers)
        if json_response is not None:
            self.__context.set_last_input_message(json_response)

        if (status >= 200) and (status <= 299):
            if (tas_method == "POST") and (json_response is not None) and (len(json_response) > 0):
                response = json.loads(json_response.decode('utf-8'))

                if action == "PLAY":
                    action_id = response['id']
                    self.__context.set_play_id(action_id)

                elif action == "COLLECT":
                    action_id = response['id']
                    self.__context.set_collect_id(action_id)

                elif action == "FORWARD_GROUP":
                    action_id = response['id']
                    self.__context.set_forward_group_id(action_id)

                else:
                    action_id = None

                logging.info("(QSim Service task '%s') TAS accepts '%s' command '%s' and return action id: '%s'.", self.__context.get_id(), tas_method, action, action_id)
            else:
                logging.vip("(QSim Service task '%s') TAS reply to '%s' command '%s' by success status (code: '%d').", self.__context.get_id(), tas_method, action, status)
        else:
            logging.warning("(QSim Service task '%s') TAS reply to '%s' command '%s' by failure status (code: '%d', reason: '%s').", self.__context.get_id(), tas_method, action, status, json_response)