Ejemplo n.º 1
0
 def invoke_hook(self, msg_id, result, body=None):
     try:
         result = int(result)
     except ValueError:
         log.error(
             "Received response code is not valid: %s! Abort callback..." %
             result)
         return
     if msg_id not in self.__register:
         log.warning(
             "Received unregistered callback with id: %s from domain: %s" %
             (msg_id, self.domain_name))
         return
     log.debug(
         "Received valid callback with id: %s, result: %s from domain: %s" %
         (msg_id, "TIMEOUT" if not result else result, self.domain_name))
     cb = self.__register.get(msg_id)
     if cb is None:
         log.error("Missing callback: %s from register!" % msg_id)
         return
     cb.result_code = result
     cb.body = body
     if cb.hook is None:
         log.debug("No hook was defined!")
         self.__blocking_mutex.set()
         return
     elif callable(cb.hook):
         log.debug("Schedule callback hook: %s" % cb.short())
         cb.hook(callback=cb)
     else:
         log.warning(
             "No callable hook was defined for the received callback: %s!" %
             msg_id)
Ejemplo n.º 2
0
    def add_domain(self, domain, nffg):
        """
    Update the global view data with the specific domain info.

    :param domain: domain name
    :type domain: str
    :param nffg: infrastructure info collected from the domain
    :type nffg: :any:`NFFG`
    :return: None
    """
        # If the domain is not tracked
        if domain not in self.__tracked_domains:
            if not nffg:
                log.warning("Got empty data. Skip domain addition...")
                return
            log.info("Append %s domain to DoV..." % domain)
            # If DoV is empty
            if not self.__dov.is_empty():
                # Merge domain topo into global view
                self.__dov.merge_new_domain_into_dov(nffg=nffg)
            else:
                # No other domain detected, set NFFG as the whole Global view
                log.debug(
                    "DoV is empty! Add new domain: %s as the global view!" %
                    domain)
                self.__dov.set_domain_as_global_view(domain=domain, nffg=nffg)
            # Add detected domain to cached domains
            self.__tracked_domains.add(domain)
        else:
            log.error(
                "New domain: %s has already tracked: %s! Abort adding..." %
                (domain, self.__tracked_domains))
Ejemplo n.º 3
0
  def __proceed_installation (self, mapped_nffg, original_request=None):
    """
    Helper function to instantiate the NFFG mapping from different source.

    :param mapped_nffg: pre-mapped service request
    :type mapped_nffg: :class:`NFFG`
    :return: None
    """
    log.getChild('API').info("Invoke install_nffg on %s with NF-FG: %s " % (
      self.__class__.__name__, mapped_nffg))
    stats.add_measurement_start_entry(type=stats.TYPE_DEPLOY,
                                      info=LAYER_NAME)
    try:
      deploy_status = self.controller_adapter.install_nffg(mapped_nffg,
                                                           original_request)
    except Exception:
      log.error("Something went wrong during NFFG installation!")
      self.raiseEventNoErrors(InstallationFinishedEvent,
                              result=InstallationFinishedEvent.DEPLOY_ERROR)
      raise
    log.getChild('API').debug("Invoked install_nffg on %s is finished!" %
                              self.__class__.__name__)
    if not deploy_status.still_pending:
      id = mapped_nffg.id
      result = InstallationFinishedEvent.get_result_from_status(deploy_status)
      log.info("Overall installation result: %s" % result)
      self.raiseEventNoErrors(InstallationFinishedEvent, id=id, result=result)
Ejemplo n.º 4
0
 def run(self):
     try:
         log.debug("Start %s for domain: %s on %s:%s" %
                   (self.__class__.__name__, self.domain_name,
                    self.server_address[0], self.server_address[1]))
         self.serve_forever()
     except KeyboardInterrupt:
         raise
     except Exception as e:
         log.error("Got exception in %s: %s" % (self.__class__.__name__, e))
     finally:
         self.server_close()
Ejemplo n.º 5
0
    def invoke_hook(self, msg_id, domain, result, body=None):
        """
    Main entry point to invoke a callback based on the extracted data from
    received message.

    :param msg_id: message id
    :type msg_id: str
    :param domain: domain name
    :type domain: str
    :param result: result of the callback
    :type result: str
    :param body: parsed callback body (optional)
    :type body: str or None
    :return: None
    """
        try:
            result = int(result)
        except ValueError:
            log.error(
                "Received response code is not valid: %s! Abort callback..." %
                result)
            return
        if (domain, msg_id) not in self.__register:
            log.warning(
                "Received unregistered callback with id: %s from domain: %s" %
                (msg_id, domain))
            return
        log.debug(
            "Received valid callback with id: %s, result: %s from domain: %s" %
            (msg_id, "TIMEOUT" if not result else result, domain))
        cb = self.__register.get((domain, msg_id))
        if cb is None:
            log.error("Missing callback: %s from register!" % msg_id)
            return
        stats.add_measurement_start_entry(type=stats.TYPE_DEPLOY_CALLBACK,
                                          info="%s-callback_received" % domain)
        cb.result_code = result
        cb.body = body
        if cb.hook is None:
            log.debug("No hook was defined!")
            self.__blocking_mutex.set()
            return
        elif callable(cb.hook):
            log.debug("Schedule callback hook: %s" % cb.short())
            cb.hook(callback=cb)
        else:
            log.warning(
                "No callable hook was defined for the received callback: %s!" %
                msg_id)
Ejemplo n.º 6
0
    def __proceed_installation(self,
                               mapped_nffg,
                               original_request=None,
                               direct_deploy=False):
        """
    Helper function to instantiate the NFFG mapping from different source.

    :param mapped_nffg: pre-mapped service request
    :type mapped_nffg: :class:`NFFG`
    :return: None
    """
        log.getChild('API').info("Invoke install_nffg on %s with NF-FG: %s " %
                                 (self.__class__.__name__, mapped_nffg))
        stats.add_measurement_start_entry(type=stats.TYPE_DEPLOY,
                                          info=LAYER_NAME)
        try:
            deploy_status = self.controller_adapter.install_nffg(
                mapped_nffg=mapped_nffg,
                original_request=original_request,
                direct_deploy=direct_deploy)
        except Exception as e:
            log.error("Something went wrong during NFFG installation: %s" % e)
            self._process_mapping_result(nffg_id=mapped_nffg.id, fail=True)
            self.raiseEventNoErrors(
                InstallationFinishedEvent,
                id=mapped_nffg.id,
                result=InstallationFinishedEvent.DEPLOY_ERROR)
            return
        log.getChild('API').debug("Invoked install_nffg on %s is finished!" %
                                  self.__class__.__name__)
        if deploy_status is None:
            log.error("Deploy status is missing!")
            self._process_mapping_result(nffg_id=mapped_nffg.id, fail=True)
            self.raiseEventNoErrors(
                InstallationFinishedEvent,
                id=mapped_nffg.id,
                result=InstallationFinishedEvent.DEPLOY_ERROR)
        elif not deploy_status.still_pending:
            result = InstallationFinishedEvent.get_result_from_status(
                deploy_status)
            log.info("Overall installation result: %s" % result)
            is_fail = InstallationFinishedEvent.is_error(result)
            self._process_mapping_result(nffg_id=mapped_nffg.id, fail=is_fail)
            self.raiseEventNoErrors(InstallationFinishedEvent,
                                    id=mapped_nffg.id,
                                    result=result)
        elif deploy_status.standby:
            if self._dovapi:
                RequestScheduler().set_orchestration_standby()
Ejemplo n.º 7
0
    def get_virtual_view(self, virtualizer_id, type=None, cls=None, **kwargs):
        """
    Return the Virtual View as a derived class of :class:`AbstractVirtualizer
    <escape.orchest.virtualization_mgmt.AbstractVirtualizer>`.

    :param virtualizer_id: unique id of the requested Virtual view
    :type virtualizer_id: int or str
    :param type: type of the Virtualizer predefined in this class
    :type type: str
    :param cls: specific Virtualizer class if type is not given
    :type cls: :any:`AbstractVirtualizer`
    :param kwargs: optional parameters for Virtualizer
    :type kwargs: dict
    :return: virtual view
    :rtype: :any:`AbstractVirtualizer`
    """
        log.debug("Invoke %s to get <Virtual View> (for layer ID: %s)" %
                  (self.__class__.__name__, virtualizer_id))
        # If this is the first request, need to generate the view
        if virtualizer_id not in self._virtualizers:
            if type is not None:
                if type in self.VIRTUALIZERS:
                    virtualizer_class = self.VIRTUALIZERS[type]
                    self._virtualizers[virtualizer_id] = virtualizer_class(
                        self.dov, virtualizer_id, **kwargs)
                    log.debug(
                        "Generated Virtualizer with type: %s id: %s, params: %s"
                        % (type, virtualizer_id, kwargs))
                # Not supported format
                else:
                    log.error("Unsupported Virtualizer type: %s" % type)
                    return
            # If a specific AbstractVirtualizer type was given
            elif cls is not None:
                log.debug(
                    "Generating Virtualizer type: %s with id: %s, params: %s" %
                    (cls.__name__, virtualizer_id, kwargs))
                self._virtualizers[virtualizer_id] = cls(
                    self.dov, virtualizer_id, **kwargs)
            # Generate a Single BiS-BiS Virtualizer by default
            else:
                # Virtualizer type is not defined: Use SingleBiSBiSVirtualizer by
                # default
                log.error(
                    "Virtualizer type is missing for requested Virtualizer: %s!"
                    % virtualizer_id)
                return None
        # Return Virtualizer
        return self._virtualizers[virtualizer_id]
Ejemplo n.º 8
0
    def rest_api_get_config(self):
        """
    Implementation of REST-API RPC: get-config. Return with the global
    resource as an :class:`NFFG` if it has been changed otherwise return with
    False.

    :return: global resource view (DoV)
    :rtype: :class:`NFFG` or False
    """
        # return self.controller_adapter.DoVManager.dov.get_resource_info()
        log.getChild('[DOV-API]').debug("Requesting Virtualizer for DoV-API")
        if self.dov_api_view is not None:
            # Check the topology is initialized
            if self.dov_api_view.revision is None:
                log.getChild('[DOV-API]').debug(
                    "DoV has not initialized yet! "
                    "Force to get default topology...")
            else:
                # Check if the resource is changed
                if self.api_mgr.topology_revision == self.dov_api_view.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)! " %
                        self.dov_api_view.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.getChild('[DOV-API]').debug(
                        "Response cache is outdated "
                        "(new revision: %s)!" % self.dov_api_view.revision)
            res = self.dov_api_view.get_resource_info()
            self.api_mgr.topology_revision = self.dov_api_view.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.error("Virtualizer(id=%s) assigned to DoV-API is not found!" %
                      self._core_name)
Ejemplo n.º 9
0
    def clean_domain(self, domain):
        """
    Clean given domain.

    :param domain: domain name
    :type domain: str
    :return: None
    """
        if domain in self.__tracked_domains:
            log.info(
                "Remove initiated VNFs and flowrules from the domain: %s" %
                domain)
            self.__dov.clean_domain_from_dov(domain=domain)
        else:
            log.error(
                "Detected domain: %s is not included in tracked domains: %s! Abort "
                "cleaning..." % (domain, self.__tracked_domains))
Ejemplo n.º 10
0
 def initialize (self):
   """
   .. seealso::
     :func:`AbstractAPI.initialize() <escape.util.api.AbstractAPI.initialize>`
   """
   log.debug("Initializing Controller Adaptation Sublayer...")
   self.controller_adapter = ControllerAdapter(self, with_infr=self._with_infr)
   if self._mapped_nffg:
     try:
       mapped_request = self._read_data_from_file(self._mapped_nffg)
       mapped_request = NFFG.parse(mapped_request)
       self.__proceed_installation(mapped_nffg=mapped_request)
     except (ValueError, IOError, TypeError) as e:
       log.error("Can't load service request from file because of: " + str(e))
     else:
       log.debug("Graph representation is loaded successfully!")
   log.info("Controller Adaptation Sublayer has been initialized!")
Ejemplo n.º 11
0
    def run(self):
        """
    Start waiting for callbacks.

    :return: None
    """
        self.bind_and_activate()
        try:
            log.debug("Start %s on %s:%s" %
                      (self.__class__.__name__, self.server_address[0],
                       self.server_address[1]))
            self.serve_forever()
        except KeyboardInterrupt:
            raise
        except Exception as e:
            log.error("Got exception in %s: %s" % (self.__class__.__name__, e))
        finally:
            self.server_close()
Ejemplo n.º 12
0
    def update_domain(self, domain, nffg):
        """
    Update the detected domain in the global view with the given info.

    :param domain: domain name
    :type domain: str
    :param nffg: changed infrastructure info
    :type nffg: :any:`NFFG`
    :return: None
    """
        if domain in self.__tracked_domains:
            log.info("Update domain: %s in DoV..." % domain)
            if self._remerge:
                log.debug("Using REMERGE strategy for DoV update...")
                self.__dov.remerge_domain_in_dov(domain=domain, nffg=nffg)
            else:
                log.debug("Using UPDATE strategy for DoV update...")
                self.__dov.update_domain_in_dov(domain=domain, nffg=nffg)
        else:
            log.error(
                "Detected domain: %s is not included in tracked domains: %s! Abort "
                "updating..." % (domain, self.__tracked_domains))
Ejemplo n.º 13
0
  def __proceed_installation (self, mapped_nffg):
    """
    Helper function to instantiate the NFFG mapping from different source.

    :param mapped_nffg: pre-mapped service request
    :type mapped_nffg: :any:`NFFG`
    :return: None
    """
    log.getChild('API').info("Invoke install_nffg on %s with NF-FG: %s " % (
      self.__class__.__name__, mapped_nffg))
    log.info(int(round(time.time() * 1000)))
    try:
      install_result = self.controller_adapter.install_nffg(mapped_nffg)
    except Exception as e:
      log.error("Something went wrong during NFFG installation!")
      self.raiseEventNoErrors(InstallationFinishedEvent, result=False, error=e)
      raise
    log.getChild('API').debug("Invoked install_nffg on %s is finished" %
                              self.__class__.__name__)
    log.info(int(round(time.time() * 1000)))
    self.raiseEventNoErrors(InstallationFinishedEvent, id=mapped_nffg.id,
                            result=install_result)
Ejemplo n.º 14
0
   def wrapper(*args, **kwargs):
       """
 Wrapper function which call policy checking functions if they exist.
 """
       if len(args) > 0:
           # Call Policy checking function before original
           if hooks[0]:
               log.debug("Invoke Policy checking function: [PRE] %s" %
                         (hooks[0].__name__.split('pre_', 1)[1]))
               hooks[0](args, kwargs)
           # Call original function
           ret_value = orig_func(*args, **kwargs)
           # Call Policy checking function after original
           if hooks[1]:
               log.debug("Invoke Policy checking function: [POST] %s" %
                         (hooks[1].__name__.split('post_', 1)[1]))
               hooks[1](args, kwargs, ret_value)
           return ret_value
       else:
           log.warning(
               "Something went wrong during binding Policy checker!")
       log.error("Abort policy enforcement checking!")
       raise PolicyEnforcementError(
           "Policy enforcement checking is aborted")
Ejemplo n.º 15
0
    def load_component(self, component_name, params=None, parent=None):
        """
    Load given component (DomainAdapter/DomainManager) from config.
    Initiate the given component class, pass the additional attributes,
    register the event listeners and return with the newly created object.

    :param component_name: component's config name
    :type component_name: str
    :param params: component parameters
    :type params: dict
    :param parent: define the parent of the actual component's configuration
    :type parent: dict
    :return: initiated component
    :rtype: :any:`AbstractESCAPEAdapter` or :any:`AbstractDomainManager`
    """
        try:
            # Get component class
            component_class = CONFIG.get_component(component=component_name,
                                                   parent=parent)
            # If it's found
            if component_class is not None:
                # Get optional parameters of this component
                if not params:
                    params = CONFIG.get_component_params(
                        component=component_name, parent=parent)
                # Initialize component
                component = component_class(**params)
                # Set up listeners for e.g. DomainChangedEvents
                component.addListeners(self._ca)
                # Set up listeners for DeployNFFGEvent
                component.addListeners(self._ca._layer_API)
                # Return the newly created object
                return component
            else:
                log.error(
                    "Configuration of '%s' is missing. Skip initialization!" %
                    component_name)
                raise ConfigurationError("Missing component configuration!")
        except AttributeError:
            log.error("%s is not found. Skip component initialization!" %
                      component_name)
            raise
        except ImportError:
            log.error(
                "Could not import module: %s. Skip component initialization!" %
                component_name)
            raise
Ejemplo n.º 16
0
    def send_with_timeout(self,
                          method,
                          url=None,
                          body=None,
                          timeout=None,
                          **kwargs):
        """
    Send REST request with handling exceptions except the TimeoutError.

    :param method: HTTP method
    :type method: str
    :param url: valid URL or relevant part follows ``self.base_url``
    :type url: str
    :param body: request body
    :type body: :any:`NFFG` or dict or bytes or str
    :param timeout: optional timeout param can be given also here
    :type timeout: int
    :raises: :any:`requests.Timeout`
    :return: raw response data
    :rtype: str
    """
        try:
            if timeout is not None:
                kwargs['timeout'] = timeout
            self.send_request(method, url, body, **kwargs)
            # return self._response.status_code if self._response is not None else
            # None
            return self._response.text if self._response is not None else None
        except ConnectionError:
            log.error("Remote agent(adapter: %s, url: %s) is not reachable!" %
                      (self.name, self._base_url))
            return None
        except HTTPError as e:
            log.error(
                "Remote agent(adapter: %s, url: %s) responded with an error: %s"
                % (self.name, self._base_url, e.message))
            return None
        except Timeout:
            raise
        except RequestException as e:
            log.error("Got unexpected exception: %s" % e)
            return None
        except KeyboardInterrupt:
            log.warning("Request to remote agent(adapter: %s, url: %s) is "
                        "interrupted by user!" % (self.name, self._base_url))
            return None
Ejemplo n.º 17
0
    def rest_api_edit_config(self, id, data, params=None):
        """
    Implement edit-config call for CAS layer. Receive edit-config request from
    external component and directly forward data for deployment.

    :param params: request params
    :type params: dict
    :return: None
    """
        log.getChild('[DOV-API]').info(
            "Invoke instantiation on %s with NF-FG: "
            "%s " % (self.__class__.__name__, id))
        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_get_config()
                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")
            nffg = self.api_mgr.converter.parse_from_Virtualizer(
                vdata=full_req)
            stats.add_measurement_end_entry(type=stats.TYPE_CONVERSION,
                                            info="VIRTUALIZER-->NFFG")
        else:
            nffg = data
        log.debug("Set NFFG id: %s" % id)
        if nffg.service_id is None:
            nffg.service_id = nffg.id
        nffg.id = id
        if params:
            nffg.add_metadata(name="params", value=params)
        log.info("Proceeding request: %s to instantiation..." % id)
        if CONFIG.get_vnfm_enabled():
            deploy_status = self.controller_adapter.status_mgr.get_last_status(
            )
            if deploy_status is None:
                log.warning(
                    "Received direct DoV rewrite request from external "
                    "component without any preliminary deploy request!")
            else:
                if deploy_status.id != nffg.id:
                    log.error(
                        "Received direct deploy request id: %s is different from "
                        "service request under deploy: %s" %
                        (nffg.id, deploy_status.id))
                    return
                else:
                    self.controller_adapter.cancel_vnfm_timer()
        log.getChild('API').debug("Store received DoV request...")
        msg_id = self.api_mgr.request_cache.cache_request_by_nffg(nffg=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').warning("No request info detected.")
        self.__proceed_installation(mapped_nffg=nffg, direct_deploy=True)
Ejemplo n.º 18
0
    def install_nffg(self, mapped_nffg):
        """
    Start NF-FG installation.

    Process given :any:`NFFG`, slice information self.__global_nffg on
    domains and invoke DomainManagers to install domain specific parts.

    :param mapped_nffg: mapped NF-FG instance which need to be installed
    :type mapped_nffg: NFFG
    :return: mapping result
    :rtype: bool
    """
        log.debug("Invoke %s to install NF-FG(%s)" %
                  (self.__class__.__name__, mapped_nffg.name))
        # # Notify remote visualizer about the deployable NFFG if it's needed
        # notify_remote_visualizer(data=mapped_nffg, id=LAYER_NAME)
        slices = NFFGToolBox.split_into_domains(nffg=mapped_nffg, log=log)
        if slices is None:
            log.warning("Given mapped NFFG: %s can not be sliced! "
                        "Skip domain notification steps" % mapped_nffg)
            return
        log.debug("Notify initiated domains: %s" %
                  [d for d in self.domains.initiated])
        # TODO - abstract/inter-domain tag rewrite
        # NFFGToolBox.rewrite_interdomain_tags(slices)
        mapping_result = True
        for domain, part in slices:
            log.debug(
                "Recreate missing TAG matching fields in domain part: %s..." %
                domain)
            # Temporarily rewrite/recreate TAGs here
            NFFGToolBox.recreate_match_TAGs(nffg=part, log=log)
            # Get Domain Manager
            domain_mgr = self.domains.get_component_by_domain(
                domain_name=domain)
            if domain_mgr is None:
                log.warning(
                    "No DomainManager has been initialized for domain: %s! "
                    "Skip install domain part..." % domain)
                continue
            log.log(VERBOSE,
                    "Splitted domain: %s part:\n%s" % (domain, part.dump()))
            log.info("Delegate splitted part: %s to %s" % (part, domain_mgr))
            # Rebind requirement link fragments as e2e reqs
            part = NFFGToolBox.rebind_e2e_req_links(nffg=part, log=log)
            # Check if need to reset domain before install
            if CONFIG.reset_domains_before_install():
                log.debug("Reset %s domain before deploying mapped NFFG..." %
                          domain_mgr.domain_name)
                domain_mgr.clear_domain()
            # Invoke DomainAdapter's install
            res = domain_mgr.install_nffg(part)
            # Update the DoV based on the mapping result covering some corner case
            if not res:
                log.error("Installation of %s in %s was unsuccessful!" %
                          (part, domain))
            # Note result according to others before
            mapping_result = mapping_result and res
            # If installation of the domain was performed without error
            if not res:
                log.warning("Skip DoV update with domain: %s! Cause: "
                            "Domain installation was unsuccessful!" % domain)
                continue
            # If the domain manager does not poll the domain update here
            # else polling takes care of domain updating
            if isinstance(domain_mgr,
                          AbstractRemoteDomainManager) and domain_mgr._poll:
                log.info("Skip explicit DoV update for domain: %s. "
                         "Cause: polling enabled!" % domain)
                continue
            # If the internalDM is the only initiated mgr, we can override the
            # whole DoV
            if domain_mgr.IS_LOCAL_MANAGER:
                if mapped_nffg.is_SBB():
                    # If the request was a cleanup request, we can simply clean the DOV
                    if mapped_nffg.is_bare():
                        log.debug(
                            "Detected cleanup topology (no NF/Flowrule/SG_hop)! Clean DoV..."
                        )
                        self.DoVManager.clean_domain(domain=domain)
                    # If the reset contains some VNF, cannot clean or override
                    else:
                        log.warning(
                            "Detected SingleBiSBiS topology! Local domain has been already "
                            "cleared, skip DoV update...")
                # If the the topology was a GLOBAL view, just override the whole DoV
                elif not mapped_nffg.is_virtualized():
                    self.DoVManager.set_global_view(nffg=mapped_nffg)
                else:
                    log.warning(
                        "Detected virtualized Infrastructure node in mapped NFFG! Skip "
                        "DoV update...")
                # In case of Local manager skip the rest of the update
                continue
            # Explicit domain update
            self.DoVManager.update_domain(domain=domain, nffg=part)
        log.debug("NF-FG installation is finished by %s" %
                  self.__class__.__name__)
        # Post-mapping steps
        if mapping_result:
            log.info(
                "All installation process has been finished with success! ")
            # Notify remote visualizer about the installation result if it's needed
            notify_remote_visualizer(
                data=self.DoVManager.dov.get_resource_info(), id=LAYER_NAME)
        else:
            log.error("%s installation was not successful!" % mapped_nffg)
        return mapping_result