Пример #1
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!")
Пример #2
0
 def initialize(self):
     """
 .. seealso::
   :func:`AbstractAPI.initialize() <escape.util.api.AbstractAPI.initialize>`
 """
     log.debug("Initializing Service Layer...")
     self.__sid = CONFIG.get_service_layer_id()
     if self.__sid is not None:
         log.debug("Setup ID for Service Layer: %s" % self.__sid)
     else:
         self.__sid = self.LAYER_ID
         log.error(
             "Missing ID of Service Layer from config. Using default value: %s"
             % self.__sid)
     # Set element manager
     self.elementManager = ClickManager()
     # Init central object of Service layer
     self.service_orchestrator = ServiceOrchestrator(self)
     # Read input from file if it's given and initiate SG
     if self._sg_file:
         try:
             stats.init_request_measurement(request_id=self._sg_file)
             service_request = self._read_data_from_file(self._sg_file)
             log.info("Graph representation is loaded successfully!")
             if service_request.startswith('{'):
                 log.debug(
                     "Detected format: JSON - Parsing from NFFG format...")
                 nffg = NFFG.parse(raw_data=service_request)
             elif service_request.startswith('<'):
                 log.debug(
                     "Detected format: XML - Parsing from Virtualizer format..."
                 )
                 converter = NFFGConverter(domain="INTERNAL", logger=log)
                 nffg = converter.parse_from_Virtualizer(
                     vdata=service_request)
             else:
                 log.warning("Detected unexpected format...")
                 return
             if nffg.mode is not None:
                 log.info('Detected mapping mode in NFFG: %s' % nffg.mode)
             else:
                 nffg.mode = NFFG.MODE_ADD
                 log.info("No mapping mode has been detected in NFFG! "
                          "Set default mode: %s" % nffg.mode)
             log.info("Schedule service request delayed by %d seconds..." %
                      SCHEDULED_SERVICE_REQUEST_DELAY)
             stats.set_request_id(request_id=nffg.id)
             self.api_sas_sg_request_delayed(service_nffg=nffg)
         except (ValueError, IOError, TypeError) as e:
             log.error("Can't load service request from file because of: " +
                       str(e))
             quit_with_error(msg=str(e), logger=log)
     else:
         # Init REST-API if no input file is given
         self._initiate_rest_api()
     # Init GUI
     if self._gui:
         self._initiate_gui()
     log.info("Service Layer has been initialized!")
Пример #3
0
  def _perform_mapping (self, input_graph, resource_view):
    """
    Orchestrate mapping of given service graph on given virtual resource.

    :param input_graph: Service Graph
    :type input_graph: :any:`NFFG`
    :param resource_view: virtual resource view
    :param resource_view: :any:`AbstractVirtualizer`
    :return: Network Function Forwarding Graph
    :rtype: :any:`NFFG`
    """
    if input_graph is None:
      log.error("Missing service request information! Abort mapping process!")
      return None
    log.debug("Request %s to launch orchestration on SG: %s with View: %s" % (
      self.__class__.__name__, input_graph, resource_view))
    # Steps before mapping (optional)
    log.debug("Request resource info from layer virtualizer...")
    virt_resource = resource_view.get_resource_info()
    if virt_resource is None:
      log.error("Missing resource information! Abort mapping process!")
      return None
    # log a warning if resource is empty --> possibly mapping will be failed
    if virt_resource.is_empty():
      log.warning("Resource information is empty!")
    # Log verbose resource view if it is exist
    log.log(VERBOSE, "Service layer resource graph:\n%s" % virt_resource.dump())
    # resource_view.sanity_check(input_graph)
    # Check if the mapping algorithm is enabled
    if not CONFIG.get_mapping_enabled(LAYER_NAME):
      log.warning(
        "Mapping algorithm in Layer: %s is disabled! Skip mapping step and "
        "forward service request to lower layer..." % LAYER_NAME)
      return input_graph
    # Run actual mapping algorithm
    if self._threaded:
      # Schedule a microtask which run mapping algorithm in a Python thread
      log.info(
        "Schedule mapping algorithm: %s in a worker thread" %
        self.strategy.__name__)
      call_as_coop_task(self._start_mapping, graph=input_graph,
                        resource=virt_resource)
      log.info("SG: %s orchestration is finished by %s" % (
        input_graph, self.__class__.__name__))
      # Return with None
      return None
    else:
      mapped_nffg = self.strategy.map(graph=input_graph, resource=virt_resource)
      # Steps after mapping (optional) if the mapping was not threaded
      if mapped_nffg is None:
        log.error("Mapping process is failed! Abort orchestration process.")
      else:
        log.info("SG: %s orchestration is finished by %s successfully!" % (
          input_graph, self.__class__.__name__))
      return mapped_nffg
Пример #4
0
  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)
Пример #5
0
  def map (cls, graph, resource):
    """
    Default mapping algorithm which maps given Service Graph on one BiS-BiS.

    :param graph: Service Graph
    :type graph: :any:`NFFG`
    :param resource: virtual resource
    :type resource: :any:`NFFG`
    :return: Network Function Forwarding Graph
    :rtype: :any:`NFFG`
    """
    log.debug("Invoke mapping algorithm: %s - request: %s resource: %s" %
              (cls.__name__, graph, resource))
    if graph is None:
      log.error("Missing request NFFG! Abort mapping process...")
      return
    if resource is None:
      log.error("Missing resource NFFG! Abort mapping process...")
      return
    try:
      mapper_params = CONFIG.get_mapping_config(layer=LAYER_NAME)
      mapped_nffg = MAP(request=graph.copy(),
                        network=resource.copy(),
                        **mapper_params)
      # Set mapped NFFG id for original SG request tracking
      mapped_nffg.id = graph.id
      mapped_nffg.name = graph.name + "-sas-mapped"
    except MappingException as e:
      log.error("Got exception during the mapping process! Cause:\n%s" % e.msg)
      log.warning("Mapping algorithm on %s isaborted!" % graph)
      return
    except BadInputException as e:
      log.error("Mapping algorithm refuse given input! Cause:\n%s" % e.msg)
      log.warning("Mapping algorithm on %s is aborted!" % graph)
      return
    except InternalAlgorithmException as e:
      log.critical(
        "Mapping algorithm fails due to implementation error or conceptual "
        "error! Cause:\n%s" % e.msg)
      log.warning("Mapping algorithm on %s is aborted!" % graph)
      return
    except:
      log.exception("Got unexpected error during mapping process!")
      return
    log.debug(
      "Mapping algorithm: %s is finished on SG: %s" % (cls.__name__, graph))
    return mapped_nffg
Пример #6
0
    def initiate_service_graph(self, sg):
        """
    Main function for initiating Service Graphs.

    :param sg: service graph stored in NFFG instance
    :type sg: :class:`NFFG`
    :return: NF-FG description
    :rtype: :class:`NFFG`
    """
        log.debug("Invoke %s to initiate SG(id=%s)" %
                  (self.__class__.__name__, sg.id))
        # Store newly created SG
        self.sgManager.save(sg)
        # Get virtual resource info as a Virtualizer
        virtual_view = self.virtResManager.virtual_view
        # Notify remote visualizer about resource view of this layer if it's needed
        # notify_remote_visualizer(data=virtual_view.get_resource_info(),
        #                          id=LAYER_NAME)
        # Log verbose service request
        log.log(VERBOSE, "Service layer request graph:\n%s" % sg.dump())
        if virtual_view is not None:
            if isinstance(virtual_view, AbstractVirtualizer):
                # If the request is a bare NFFG, it is probably an empty topo for domain
                # deletion --> skip mapping to avoid BadInputException and forward
                # topo to adaptation layer
                if sg.is_bare():
                    log.warning(
                        "No valid service request (VNFs/Flowrules/SGhops) has "
                        "been detected in SG request! Skip orchestration in "
                        "layer: %s and proceed with the bare %s..." %
                        (LAYER_NAME, sg))
                    if sg.is_virtualized():
                        if sg.is_SBB():
                            log.debug(
                                "Request is a bare SingleBiSBiS representation!"
                            )
                        else:
                            log.warning(
                                "Detected virtualized representation with multiple "
                                "BiSBiS nodes! Currently this type of virtualization "
                                "is nut fully supported!")
                    else:
                        log.debug("Detected full view representation!")
                    # Return with the original request
                    return sg
                else:
                    log.info("Request check: detected valid NFFG content!")
                try:
                    # Run orchestration before service mapping algorithm
                    mapped_nffg = self.mapper.orchestrate(sg, virtual_view)
                    log.debug("SG initiation is finished by %s" %
                              self.__class__.__name__)
                    return mapped_nffg
                except ProcessorError as e:
                    log.warning(
                        "Mapping pre/post processing was unsuccessful! "
                        "Cause: %s" % e)
                    # Propagate the ProcessError to API layer
                    raise
            else:
                log.warning(
                    "Virtual view is not subclass of AbstractVirtualizer!")
        else:
            log.warning("Virtual view is not acquired correctly!")
        # Only goes there if there is a problem
        log.error("Abort orchestration process!")
Пример #7
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))
Пример #8
0
    def _perform_mapping(self, input_graph, resource_view, continued=False):
        """
    Orchestrate mapping of given service graph on given virtual resource.

    :param input_graph: Service Graph
    :type input_graph: :class:`NFFG`
    :param resource_view: virtual resource view
    :param resource_view: :any:`AbstractVirtualizer`
    :return: Network Function Forwarding Graph
    :rtype: :class:`NFFG`
    """
        if input_graph is None:
            log.error(
                "Missing service request information! Abort mapping process!")
            return None
        log.debug(
            "Request %s to launch orchestration on SG: %s with View: %s,"
            "continued remap: %s" %
            (self.__class__.__name__, input_graph, resource_view, continued))
        # Steps before mapping (optional)
        log.debug("Request resource info from layer virtualizer...")
        virt_resource = resource_view.get_resource_info()
        if virt_resource is None:
            log.error("Missing resource information! Abort mapping process!")
            return None
        # log a warning if resource is empty --> possibly mapping will be failed
        if virt_resource.is_empty():
            log.warning("Resource information is empty!")
        # Log verbose resource view if it is exist
        log.log(VERBOSE,
                "Service layer resource graph:\n%s" % virt_resource.dump())
        # resource_view.sanity_check(input_graph)
        # Check if the mapping algorithm is enabled
        if not CONFIG.get_mapping_enabled(LAYER_NAME):
            log.warning(
                "Mapping algorithm in Layer: %s is disabled! Skip mapping step and "
                "forward service request to lower layer..." % LAYER_NAME)
            input_graph.status = NFFG.MAP_STATUS_SKIPPED
            log.debug("Mark NFFG status: %s!" % input_graph.status)
            return input_graph
        # Run actual mapping algorithm
        if self._threaded:
            # Schedule a microtask which run mapping algorithm in a Python thread
            log.info("Schedule mapping algorithm: %s in a worker thread" %
                     self.strategy.__name__)
            call_as_coop_task(self._start_mapping,
                              graph=input_graph,
                              resource=virt_resource)
            log.info("SG: %s orchestration is finished by %s" %
                     (input_graph, self.__class__.__name__))
            # Return with None
            return None
        else:
            state = self.last_mapping_state if continued else None
            mapping_result = self.strategy.map(graph=input_graph,
                                               resource=virt_resource,
                                               pre_state=state)
            if isinstance(mapping_result, tuple or list):
                if len(mapping_result) != 2:
                    log.error("Mapping result is invalid: %s" %
                              repr(mapping_result))
                    mapped_nffg = None
                else:
                    mapped_nffg = mapping_result[0]
                    self.last_mapping_state = mapping_result[1]
                    log.debug("Cache returned mapping state: %s" %
                              self.last_mapping_state)
            else:
                mapped_nffg = mapping_result
            # Steps after mapping (optional) if the mapping was not threaded
            if mapped_nffg is None:
                log.error(
                    "Mapping process is failed! Abort orchestration process.")
            else:
                log.info(
                    "SG: %s orchestration is finished by %s successfully!" %
                    (input_graph, self.__class__.__name__))
            log.debug("Last mapping state: %s" % self.last_mapping_state)
            log.info("Mapping iteration: %s" %
                     self.last_mapping_state.get_number_of_trials() if self.
                     last_mapping_state else None)
            return mapped_nffg
Пример #9
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))