Beispiel #1
0
    def _proceed_to_instantiate_NFFG(self, mapped_nffg):
        """
    Send NFFG to Resource Orchestration Sublayer in an implementation-specific
    way.

    General function which is used from microtask and Python thread also.

    This function contains the last steps before the mapped NFFG will be sent
    to the next layer.

    :param mapped_nffg: mapped Service Graph
    :type mapped_nffg: :class:`NFFG`
    :return: None
    """
        # Rebind requirement link fragments for lower layer mapping
        mapped_nffg = NFFGToolBox.rebind_e2e_req_links(nffg=mapped_nffg,
                                                       log=log)
        # Log verbose mapping result in unified way (threaded/non-threaded)
        log.log(VERBOSE,
                "Mapping result of Service Layer:\n%s" % mapped_nffg.dump())
        # Notify remote visualizer about the mapping result if it's needed
        # notify_remote_visualizer(data=mapped_nffg, id=LAYER_NAME)
        sas_res = self.__get_sas_resource_view().get_resource_info()
        # Sending mapped SG / NF-FG to Orchestration layer as an Event
        # Exceptions in event handlers are caught by default in a non-blocking way
        self.raiseEventNoErrors(InstantiateNFFGEvent, mapped_nffg, sas_res)
        log.getChild('API').info(
            "Generated NF-FG: %s has been sent to Orchestration..." %
            mapped_nffg)
Beispiel #2
0
 def __handle_mapping_result(self, nffg_id, fail):
     if not (hasattr(self, 'rest_api') and self.rest_api):
         return
     log.getChild('API').debug("Cache request status...")
     req_status = self.rest_api.request_cache.get_request_by_nffg_id(
         nffg_id)
     if req_status is None:
         log.getChild('API').debug(
             "Request status is missing for NFFG: %s! "
             "Skip result processing..." % nffg_id)
         return
     log.getChild('API').debug("Process mapping result...")
     message_id = req_status.message_id
     if message_id is not None:
         if fail:
             self.rest_api.request_cache.set_error_result(id=message_id)
         else:
             self.rest_api.request_cache.set_success_result(id=message_id)
         ret = self.rest_api.invoke_callback(message_id=message_id)
         if ret is None:
             log.getChild('API').debug("No callback was defined!")
         else:
             log.getChild('API').debug(
                 "Callback: %s has invoked with return value: %s" %
                 (req_status.get_callback(), ret))
     RequestScheduler().set_orchestration_finished(id=nffg_id)
Beispiel #3
0
  def __proceed_sg_request (self, service_nffg):
    """
    Initiate a Service Graph (UNIFY U-Sl API).

    :param service_nffg: service graph instance
    :type service_nffg: :any:`NFFG`
    :return: None
    """
    # Store request if it is received on REST-API
    if hasattr(self, 'rest_api') and self.rest_api:
      self.rest_api.request_cache.add_request(id=service_nffg.id)
      self.rest_api.request_cache.set_in_progress(id=service_nffg.id)
    log.getChild('API').info("Invoke request_service on %s with SG: %s " %
                             (self.__class__.__name__, service_nffg))
    # Initiate service request mapping
    mapped_nffg = self.service_orchestrator.initiate_service_graph(
      service_nffg)
    log.getChild('API').debug("Invoked request_service on %s is finished" %
                              self.__class__.__name__)
    # If mapping is not threaded and finished with OK
    if mapped_nffg is not None and not \
       self.service_orchestrator.mapper.threaded:
      self._proceed_to_instantiate_NFFG(mapped_nffg)
      self.last_sg = mapped_nffg
    else:
      log.warning("Something went wrong in service request initiation: "
                  "mapped service data is missing!")
Beispiel #4
0
    def __handle_mapping_result(self, nffg_id, fail):
        """
    Perform necessary task for callback and cache functionality based on mapping
    result.

    :param nffg_id: request ID
    :type nffg_id: str or int
    :param fail: mapping result
    :type fail: bool
    :return: None
    """
        log.getChild('API').debug("Cache request status...")
        req_status = self.api_mgr.request_cache.get_request_by_nffg_id(nffg_id)
        if req_status is None:
            log.getChild('API').debug(
                "Request status is missing for NFFG: %s! "
                "Skip result processing..." % nffg_id)
            return
        log.getChild('API').debug("Process mapping result...")
        message_id = req_status.message_id
        if message_id is not None:
            if fail:
                self.api_mgr.request_cache.set_error_result(id=message_id)
            else:
                self.api_mgr.request_cache.set_success_result(id=message_id)
            ret = self.api_mgr.invoke_callback(message_id=message_id)
            if ret is None:
                log.getChild('API').debug("No callback was defined!")
            else:
                log.getChild('API').debug(
                    "Callback: %s has invoked with return value: %s" %
                    (req_status.get_callback(), ret))
        RequestScheduler().set_orchestration_finished(id=nffg_id)
Beispiel #5
0
 def _handle_InstantiationFinishedEvent (self, event):
   """
   """
   if hasattr(self, 'rest_api') and self.rest_api:
     self.rest_api.request_cache.set_result(id=event.id, result=event.result)
   if event.result:
     log.getChild('API').info(
       "Service request(id=%s) has been finished successfully!" % event.id)
   else:
     log.getChild('API').error(
       "Service request(id=%s) has been finished with error!" % event.id)
Beispiel #6
0
  def _handle_VirtResInfoEvent (self, event):
    """
    Save requested virtual resource info as an :class:`AbstractVirtualizer
    <escape.orchest.virtualization_mgmt.AbstractVirtualizer>`.

    :param event: event object
    :type event: :any:`VirtResInfoEvent`
    :return: None
    """
    log.getChild('API').debug("Received <Virtual View>: %s from %s layer" % (
      event.virtualizer, str(event.source._core_name).title()))
    self.service_orchestrator.virtResManager.virtual_view = event.virtualizer
Beispiel #7
0
    def _handle_MissingVirtualViewEvent(self, event):
        """
    Request virtual resource info from Orchestration layer (UNIFY Sl - Or API).

    Invoked when a :class:`MissingVirtualViewEvent` raised.

    Service layer is identified with the sid value automatically.

    :param event: event object
    :type event: :any:`MissingVirtualViewEvent`
    :return: None
    """
        log.getChild('API').debug(
            "Send <Virtual View> request(with layer ID: %s) to Orchestration "
            "layer..." % self.__sid)
        self.raiseEventNoErrors(GetVirtResInfoEvent, self.__sid)
Beispiel #8
0
    def _handle_InstantiationFinishedEvent(self, event):
        """
    Receive the result of the instantiated NFFG and save it.

    :param event: event object
    :type event: :any:`InstantiationFinishedEvent`
    :return: None
    """
        if not BaseResultEvent.is_error(event.result):
            log.getChild('API').info(
                "Service request(id=%s) has been finished successfully with result: %s!"
                % (event.id, event.result))
        else:
            log.getChild('API').error(
                "Service request(id=%s) has been finished with error result: %s!"
                % (event.id, event.result))
        if not event.is_pending(event.result):
            self.__handle_mapping_result(nffg_id=event.id,
                                         fail=event.is_error(event.result))
        # Quit ESCAPE if test mode is active
        if get_global_parameter(name="QUIT_AFTER_PROCESS"):
            quit_with_ok("Detected QUIT mode! Exiting ESCAPE...")
Beispiel #9
0
    def rest_api_topology(self):
        """
    Return with the topology description.

    :return: topology description requested from the layer's Virtualizer
    :rtype: :class:`NFFG`
    """
        log.getChild('[U-Sl]').debug("Requesting Virtualizer for REST-API...")
        # Get or if not available then request the layer's Virtualizer
        sas_virt = self.__get_sas_resource_view()
        if sas_virt is not None:
            if sas_virt.revision is None:
                log.debug("Not initialized yet!")
            else:
                # Check if the resource is changed
                if self.api_mgr.topology_revision == sas_virt.revision:
                    # If resource has not been changed return False
                    # This causes to response with the cached topology
                    log.debug(
                        "Global resource has not changed (revision: %s)! " %
                        sas_virt.revision)
                    log.debug("Send topology from cache...")
                    if self.api_mgr.last_response is None:
                        log.error("Cached topology is missing!")
                        return
                    else:
                        return self.api_mgr.last_response
                else:
                    log.debug(
                        "Response cache is outdated (new revision: %s)!" %
                        sas_virt.revision)
                log.getChild('[U-Sl]').debug("Generate topo description...")
            # return with the virtual view as an NFFG
            res = sas_virt.get_resource_info()
            self.api_mgr.topology_revision = sas_virt.revision
            log.debug("Updated revision number: %s" %
                      self.api_mgr.topology_revision)
            if CONFIG.get_rest_api_config(self._core_name)['unify_interface']:
                log.info("Convert internal NFFG to Virtualizer...")
                res = self.api_mgr.converter.dump_to_Virtualizer(nffg=res)
            log.debug("Cache acquired topology...")
            self.api_mgr.last_response = res
            return res
        else:
            log.getChild('[U-Sl]').error(
                "Virtualizer(id=%s) assigned to REST-API is not found!" %
                self._core_name)
Beispiel #10
0
    def api_sas_get_topology(self):
        """
    Return with the topology description.

    :return: topology description requested from the layer's Virtualizer
    :rtype: :class:`NFFG`
    """
        log.getChild('[U-Sl]').debug("Requesting Virtualizer for REST-API...")
        # Get or if not available then request the layer's Virtualizer
        sas_virt = self.__get_sas_resource_view()
        if sas_virt is not None:
            log.getChild('[U-Sl]').debug("Generate topo description...")
            # return with the virtual view as an NFFG
            return sas_virt.get_resource_info()
        else:
            log.getChild('[U-Sl]').error(
                "Virtualizer(id=%s) assigned to REST-API is not found!" %
                self.rest_api.api_id)
Beispiel #11
0
  def api_sas_get_topology (self):
    """
    Return with the topology description.

    :return: topology description requested from the layer's Virtualizer
    :rtype: :any:`NFFG`
    """
    log.getChild('[U-Sl]').info("Requesting Virtualizer for REST-API...")
    # Get or if not available then request the layer's Virtualizer
    sas_virtualizer = self.service_orchestrator.virtResManager.virtual_view
    if sas_virtualizer is not None:
      log.getChild('[U-Sl]').info("Generate topo description...")
      # return with the virtual view as an NFFG
      return sas_virtualizer.get_resource_info()
    else:
      log.getChild('[U-Sl]').error(
        "Virtualizer(id=%s) assigned to REST-API is not found!" %
        self.cfor_api.api_id)
Beispiel #12
0
class ServiceRequestHandler(BasicUnifyRequestHandler):
    """
  Request Handler for Service Adaptation SubLayer.

  .. warning::
    This class is out of the context of the recoco's co-operative thread
    context! While you don't need to worry much about synchronization between
    recoco tasks, you do need to think about synchronization between recoco task
    and normal threads. Synchronisation is needed to take care manually: use
    relevant helper function of core object: `callLater`/`raiseLater` or use
    `schedule_as_coop_task` decorator defined in util.misc on the called
    function.
  """
    # Bind HTTP verbs to UNIFY's API functions
    request_perm = {
        'GET': ('ping', 'version', 'operations', 'topology', 'status'),
        'POST': ('ping', 'sg', 'topology'),
        # 'DELETE': ('sg',),
        'PUT': ('sg', )
    }
    """Bind HTTP verbs to UNIFY's API functions"""
    # Statically defined layer component to which this handler is bounded
    # Need to be set by container class
    bounded_layer = 'service'
    """Statically defined layer component to which this handler is bounded"""
    static_prefix = "escape"
    # Logger name
    LOGGER_NAME = "U-Sl"
    """Logger name"""
    log = log.getChild("[%s]" % LOGGER_NAME)
    # Use Virtualizer format
    virtualizer_format_enabled = False
    """Use Virtualizer format"""
    # Default communication approach
    DEFAULT_DIFF = True
    """Default communication approach"""
    # Bound function
    API_CALL_RESOURCE = 'api_sas_get_topology'
    API_CALL_REQUEST = 'api_sas_sg_request'

    def __init__(self, request, client_address, server):
        """
    Init.

    :param request: request type
    :type request: str
    :param client_address: client address
    :type client_address: str
    :param server: server object
    :type server: :any:`BaseHTTPServer.HTTPServer`
    :return: None
    """
        AbstractRequestHandler.__init__(self, request, client_address, server)

    def status(self, params):
        """
    Return status of the given request.

    :param params:
    :return:
    """
        message_id = params.get('message-id')
        if not message_id:
            self.send_error(code=httplib.BAD_REQUEST,
                            message="message-id is missing")
            return
        code, result = self._proceed_API_call('api_sas_status', message_id)
        if not result:
            self.send_acknowledge(code=code, message_id=message_id)
            self.log.debug("Responded status code: %s" % code)
        else:
            self.send_json_response(code=code, data=result)
            self.log.debug("Responded status code: %s, data: %s" %
                           (code, result))

    def topology(self, params):
        """
    Provide internal topology description

    Same functionality as "get-config" in UNIFY interface.

    :return: None
    """
        self.log.debug("Call %s function: topology" % self.LOGGER_NAME)
        # Forward call to main layer class
        resource = self._proceed_API_call(self.API_CALL_RESOURCE)
        self._topology_view_responder(resource_nffg=resource,
                                      message_id=params.get(
                                          self.MESSAGE_ID_NAME))
        self.log.debug("%s function: topology ended!" % self.LOGGER_NAME)

    def sg(self, params):
        """
    Main API function for Service Graph initiation.

    Same functionality as "get-config" in UNIFY interface.

    Bounded to POST HTTP verb.

    :return: None
    """
        self.log.debug("Call %s function: sg" % self.LOGGER_NAME)
        nffg = self._service_request_parser()
        if nffg:
            if nffg.service_id is None:
                nffg.service_id = nffg.id
            nffg.id = params[self.MESSAGE_ID_NAME]
            nffg.metadata['params'] = params
            # self._proceed_API_call(self.API_CALL_REQUEST,
            #                        service_nffg=nffg,
            #                        params=params)
            self.server.scheduler.schedule_request(
                id=nffg.id,
                layer=self.bounded_layer,
                function=self.API_CALL_REQUEST,
                service_nffg=nffg,
                params=params)
            self.send_acknowledge(message_id=params[self.MESSAGE_ID_NAME])
        self.log.debug("%s function: sg ended!" % self.LOGGER_NAME)
Beispiel #13
0
    def __proceed_sg_request(self, service_nffg):
        """
    Initiate a Service Graph (UNIFY U-Sl API).

    :param service_nffg: service graph instance
    :type service_nffg: :class:`NFFG`
    :return: None
    """
        log.getChild('API').info("Invoke request_service on %s with SG: %s " %
                                 (self.__class__.__name__, service_nffg))
        # Check if mapping mode is set globally in CONFIG
        mapper_params = CONFIG.get_mapping_config(layer=LAYER_NAME)
        if 'mode' in mapper_params and mapper_params['mode'] is not None:
            mapping_mode = mapper_params['mode']
            log.info("Detected mapping mode from configuration: %s" %
                     mapping_mode)
        elif service_nffg.mode is not None:
            mapping_mode = service_nffg.mode
            log.info("Detected mapping mode from NFFG: %s" % mapping_mode)
        else:
            mapping_mode = None
            log.info("No mapping mode was detected!")
        self.__sg_preprocessing(nffg=service_nffg)
        # Store request if it is received on REST-API
        if hasattr(self, 'rest_api') and self.rest_api:
            log.getChild('API').debug("Store received NFFG request info...")
            msg_id = self.rest_api.request_cache.cache_request_by_nffg(
                nffg=service_nffg)
            if msg_id is not None:
                self.rest_api.request_cache.set_in_progress(id=msg_id)
                log.getChild('API').debug("Request is stored with id: %s" %
                                          msg_id)
            else:
                log.getChild('API').debug("No request info detected.")
        try:
            # Initiate service request mapping
            mapped_nffg = self.service_orchestrator.initiate_service_graph(
                service_nffg)
            # Rewrite REMAP mode for backward compatibility
            if mapped_nffg is not None and mapping_mode == NFFG.MODE_REMAP:
                mapped_nffg.mode = mapping_mode
                log.debug("Rewrite mapping mode: %s into mapped NFFG..." %
                          mapped_nffg.mode)
            else:
                log.debug("Skip mapping mode rewriting! Mode remained: %s" %
                          mapping_mode)
            log.getChild('API').debug(
                "Invoked request_service on %s is finished" %
                self.__class__.__name__)
            # If mapping is not threaded and finished with OK
            if mapped_nffg is not None and not \
               self.service_orchestrator.mapper.threaded:
                self._proceed_to_instantiate_NFFG(mapped_nffg)
                self.last_sg = mapped_nffg
            else:
                log.warning(
                    "Something went wrong in service request initiation: "
                    "mapped service data is missing!")
                self.__handle_mapping_result(nffg_id=service_nffg.id,
                                             fail=True)
                self._handle_InstantiationFinishedEvent(
                    event=InstantiationFinishedEvent(
                        id=service_nffg.id,
                        result=InstantiationFinishedEvent.MAPPING_ERROR))
        except ProcessorError as e:
            self.__handle_mapping_result(nffg_id=service_nffg.id, fail=True)
            self._handle_InstantiationFinishedEvent(
                event=InstantiationFinishedEvent(
                    id=service_nffg.id,
                    result=InstantiationFinishedEvent.REFUSED_BY_VERIFICATION,
                    error=e))
Beispiel #14
0
class ServiceRequestHandler(AbstractRequestHandler):
  """
  Request Handler for Service Adaptation SubLayer.

  .. warning::
    This class is out of the context of the recoco's co-operative thread
    context! While you don't need to worry much about synchronization between
    recoco tasks, you do need to think about synchronization between recoco task
    and normal threads. Synchronisation is needed to take care manually: use
    relevant helper function of core object: `callLater`/`raiseLater` or use
    `schedule_as_coop_task` decorator defined in util.misc on the called
    function.
  """
  # Bind HTTP verbs to UNIFY's API functions
  request_perm = {
    'GET': ('ping', 'version', 'operations', 'topology'),
    'POST': ('ping', 'result', 'sg', 'topology')
  }
  # Statically defined layer component to which this handler is bounded
  # Need to be set by container class
  bounded_layer = 'service'
  # Logger name
  LOGGER_NAME = "U-Sl"
  log = log.getChild("[%s]" % LOGGER_NAME)
  # Use Virtualizer format
  virtualizer_format_enabled = False

  def __init__ (self, request, client_address, server):
    """
    Init.
    """
    AbstractRequestHandler.__init__(self, request, client_address, server)

  def result (self):
    """
    Return the result of a request given by the id.
    """
    params = json.loads(self._get_body())
    try:
      id = params["id"]
    except:
      id = None
    res = self._proceed_API_call('get_result', id)
    self._send_json_response({'id': id, 'result': res})

  def topology (self):
    """
    Provide internal topology description

    Same functionality as "get-config" in UNIFY interface.

    :return: None
    """
    self.log.info("Call %s function: topology" % self.LOGGER_NAME)
    # Forward call to main layer class
    topology = self._proceed_API_call('api_sas_get_topology')
    if topology is None:
      self.send_error(404, message="Resource info is missing!")
      return
    # Setup OK status for HTTP response
    self.send_response(200)
    if topology is False:
      self.log.info(
        "Requested resource has not changed! Respond with cached topology...")
      if self.virtualizer_format_enabled:
        data = self.server.last_response.xml()
      else:
        data = self.server.last_response.dump()
    else:
      if self.virtualizer_format_enabled:
        self.log.debug("Convert internal NFFG to Virtualizer...")
        converter = NFFGConverter(domain=None, logger=log)
        # Dump to plain text format
        v_topology = converter.dump_to_Virtualizer(nffg=topology)
        # Cache converted data for edit-config patching
        self.log.debug("Cache converted topology...")
        self.server.last_response = v_topology
        # Dump to plain text format
        data = v_topology.xml()
        # Setup HTTP response format
      else:
        self.log.debug("Cache converted topology...")
        self.server.last_response = topology
        data = topology.dump()
    if self.virtualizer_format_enabled:
      self.send_header('Content-Type', 'application/xml')
    else:
      self.send_header('Content-Type', 'application/json')
    self.log.log(VERBOSE, "Responded topology for 'get-config':\n%s" % data)
    # Setup length for HTTP response
    self.send_header('Content-Length', len(data))
    self.end_headers()
    self.log.info("Send back topology description...")
    self.wfile.write(data)
    self.log.debug("%s function: get-config ended!" % self.LOGGER_NAME)

  def sg (self):
    """
    Main API function for Service Graph initiation.

    Same functionality as "get-config" in UNIFY interface.

    Bounded to POST HTTP verb.

    :return: None
    """
    self.log.debug("Called REST-API function: sg")
    self.log.info(int(round(time.time() * 1000)))
    # Obtain NFFG from request body
    log.debug("Detected response format: %s" % self.headers.get("Content-Type"))
    body = self._get_body()
    # log.getChild("REST-API").debug("Request body:\n%s" % body)
    if body is None or not body:
      log.warning("Received data is empty!")
      self.send_error(400, "Missing body!")
      return
    # Expect XML format --> need to convert first
    if self.virtualizer_format_enabled:
      if self.headers.get("Content-Type") != "application/xml" or \
         not body.startswith("<?xml version="):
        log.error("Received data is not in XML format despite of the UNIFY "
                  "interface is enabled!")
        self.send_error(415)
        return
      # Convert response's body to NFFG
      nffg = NFFGConverter(domain="INTERNAL",
                           logger=log).parse_from_Virtualizer(vdata=body)
    else:
      try:
        nffg = NFFG.parse(body)  # Initialize NFFG from JSON representation
      except Exception as e:
        self.log.error(
          "Abort request! Received exception during payload parsing: %s" % e)
        return
    self.log.debug("Parsed service request: %s" % nffg)
    self._proceed_API_call('api_sas_sg_request', nffg)
    self.send_acknowledge()
    self.log.debug("%s function: get-config ended!" % self.LOGGER_NAME)
Beispiel #15
0
    def __proceed_sg_request(self, id, data, params=None):
        """
    Initiate a Service Graph (UNIFY U-Sl API).

    :return: None
    """
        log.info("Invoke preprocessing on %s with SG: %s " %
                 (self.__class__.__name__, id))
        stats.add_measurement_start_entry(type=stats.TYPE_SERVICE,
                                          info=LAYER_NAME)
        if CONFIG.get_rest_api_config(self._core_name)['unify_interface']:
            log.debug("Virtualizer format enabled! Start conversion step...")
            if CONFIG.get_rest_api_config(self._core_name)['diff']:
                log.debug("Diff format enabled! Start patching step...")
                if self.api_mgr.last_response is None:
                    log.info(
                        "Missing cached Virtualizer! Acquiring topology now..."
                    )
                    self.rest_api_topology()
                stats.add_measurement_start_entry(type=stats.TYPE_PROCESSING,
                                                  info="RECREATE-FULL-REQUEST")
                log.info("Patching cached topology with received diff...")
                full_req = self.api_mgr.last_response.yang_copy()
                full_req.patch(source=data)
                stats.add_measurement_end_entry(type=stats.TYPE_PROCESSING,
                                                info="RECREATE-FULL-REQUEST")
            else:
                full_req = data
            log.info("Converting full request data...")
            stats.add_measurement_start_entry(type=stats.TYPE_CONVERSION,
                                              info="VIRTUALIZER-->NFFG")
            service_nffg = self.api_mgr.converter.parse_from_Virtualizer(
                vdata=full_req)
            stats.add_measurement_end_entry(type=stats.TYPE_CONVERSION,
                                            info="VIRTUALIZER-->NFFG")
        else:
            service_nffg = data
        log.debug("Set NFFG id: %s" % id)
        if service_nffg.service_id is None:
            service_nffg.service_id = service_nffg.id
        service_nffg.id = id
        service_nffg.add_metadata(name="params", value=params)
        # Check if mapping mode is set globally in CONFIG
        mapper_params = CONFIG.get_mapping_config(layer=LAYER_NAME)
        if 'mode' in mapper_params and mapper_params['mode'] is not None:
            mapping_mode = mapper_params['mode']
            log.info("Detected mapping mode from configuration: %s" %
                     mapping_mode)
        elif service_nffg.mode is not None:
            mapping_mode = service_nffg.mode
            log.info("Detected mapping mode from NFFG: %s" % mapping_mode)
        else:
            mapping_mode = None
            log.info("No mapping mode was detected!")
        self.__sg_preprocessing(nffg=service_nffg)
        # Store request if it is received on REST-API
        log.getChild('API').debug("Store received NFFG request info...")
        msg_id = self.api_mgr.request_cache.cache_request_by_nffg(
            nffg=service_nffg)
        if msg_id is not None:
            self.api_mgr.request_cache.set_in_progress(id=msg_id)
            log.getChild('API').debug("Request is stored with id: %s" % msg_id)
        else:
            log.getChild('API').debug("No request info detected.")
        try:
            if CONFIG.get_mapping_enabled(layer=LAYER_NAME):
                # Initiate service request mapping
                mapped_nffg = self.service_orchestrator.initiate_service_graph(
                    service_nffg)
            else:
                log.warning("Mapping is disabled! Skip instantiation step...")
                mapped_nffg = service_nffg
                mapped_nffg.status = NFFG.MAP_STATUS_SKIPPED
                log.debug("Mark NFFG status: %s!" % mapped_nffg.status)
            # Rewrite REMAP mode for backward compatibility
            if mapped_nffg is not None and mapping_mode == NFFG.MODE_REMAP:
                mapped_nffg.mode = mapping_mode
                log.debug("Rewrite mapping mode: %s into mapped NFFG..." %
                          mapped_nffg.mode)
            else:
                log.debug("Skip mapping mode rewriting! Mode remained: %s" %
                          mapping_mode)
            log.getChild('API').debug(
                "Invoked request_service on %s is finished" %
                self.__class__.__name__)
            # If mapping is not threaded and finished with OK
            if mapped_nffg is not None and not \
               self.service_orchestrator.mapper.threaded:
                self._proceed_to_instantiate_NFFG(mapped_nffg)
                self.last_sg = mapped_nffg
            else:
                log.warning(
                    "Something went wrong in service request initiation: "
                    "mapped service data is missing!")
                self.__handle_mapping_result(nffg_id=service_nffg.id,
                                             fail=True)
                stats.add_measurement_end_entry(type=stats.TYPE_SERVICE,
                                                info=LAYER_NAME + "-FAILED")
                self._handle_InstantiationFinishedEvent(
                    event=InstantiationFinishedEvent(
                        id=service_nffg.id,
                        result=InstantiationFinishedEvent.MAPPING_ERROR))
        except ProcessorError as e:
            self.__handle_mapping_result(nffg_id=service_nffg.id, fail=True)
            stats.add_measurement_end_entry(type=stats.TYPE_SERVICE,
                                            info=LAYER_NAME + "-DENIED")
            self._handle_InstantiationFinishedEvent(
                event=InstantiationFinishedEvent(
                    id=service_nffg.id,
                    result=InstantiationFinishedEvent.REFUSED_BY_VERIFICATION,
                    error=e))