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)
def install_nffg (self, nffg_part): """ Install :class:`NFFG` part into the domain using the specific REST-API function and Virtualizer format. :param nffg_part: domain related part of the mapped :class:`NFFG` :type nffg_part: :class:`NFFG` :return: status if the installation was success :rtype: bool """ # if nffg_part.is_bare(): # self.log.info(">>> Splitted part is a bare NFFG! Skip domain deploy...") # return True self.log.info(">>> Install %s domain part..." % self.domain_name) try: log.debug("Request and store the most recent domain topology....") topo = self.topoAdapter.get_config() if topo: self.__last_success_state = topo log.log(VERBOSE, "Last successful state:\n%s" % self.__last_success_state.xml()) request_params = {"diff": self._diff, "message_id": "edit-config-%s" % nffg_part.id} cb = None if self.callback_manager is not None: cb_url = self.callback_manager.get_url(domain=self.domain_name) log.debug("Set callback URL: %s" % cb_url) request_params["callback"] = cb_url cb = self._setup_callback(hook=self.edit_config_hook, req_id=nffg_part.id, msg_id=request_params.get('message_id'), type=self.CALLBACK_TYPE_INSTALL, data=nffg_part) response = self.topoAdapter.edit_config(nffg_part, **request_params) stats.add_measurement_start_entry(type=stats.TYPE_DEPLOY_REQUEST, info="%s-%s" % (self.domain_name, "with_callback" if self.callback_manager else "no_callback")) if not self.callback_manager: stats.add_measurement_end_entry(type=stats.TYPE_DEPLOY_REQUEST, info="%s-no_callback" % self.domain_name) else: stats.add_measurement_end_entry(type=stats.TYPE_DEPLOY_REQUEST, info="%s-with_callback" % self.domain_name) if self.callback_manager and cb: if response is None or response == 0: log.debug("Unsubscribe callback of unsuccessful request!") self.callback_manager.unsubscribe_callback(cb_id=cb.callback_id, domain=self.domain_name) return response return response is not None except: self.log.exception("Got exception during NFFG installation into: %s." % self.domain_name) return False
def rest_api_edit_config(self, id, data, params=None): """ Implementation of REST-API RPC: edit-config :param params: original request params :type params: dict :return: None """ self.log.info("Invoke preprocessing on %s with SG: %s " % (self.__class__.__name__, id)) if self._agent: # ESCAPE serves as a local orchestrator, probably with infrastructure # layer --> rewrite domain nffg = self.__update_nffg_domain(nffg_part=data) # Update API cache if CONFIG.get_rest_api_config(self._core_name)['unify_interface']: self.log.debug( "Virtualizer format enabled! Start conversion step...") if CONFIG.get_rest_api_config(self._core_name)['diff']: self.log.debug("Diff format enabled! Start patching step...") if self.api_mgr.last_response is None: self.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") self.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 self.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 self.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) self.log.info("Proceeding request: %s to instantiation..." % id) # Get resource view of the interface res = self.__get_slor_resource_view().get_resource_info() # ESCAPE serves as a global or proxy orchestrator self.__proceed_instantiation(nffg=nffg, resource_nffg=res) self.log.info("Preprocessing on %s ended!" % self.__class__.__name__)
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)
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()
def _proceed_API_call(self, request): """ Fail-safe method to call API function. The cooperative micro-task context is handled by actual APIs. Should call this with params, not directly the function of actual API. :param request: scheduled request container object :type request: APIRequest :return: None """ self.log.info("Start request processing in coop-task: %s" % request) stats.add_measurement_start_entry(stats.TYPE_SCHEDULED, request.id) if callable(request.hook): return request.hook(id=request.id, data=request.data, **request.kwargs) else: raise RESTError( msg='Error: No component has registered with name: %s, ' 'ABORT function call!' % request.layer)
def call_mapping_algorithm(cls, request, topology, profiling=False, stats_type=stats.TYPE_ORCHESTRATION_MAPPING, stat_level=None, **params): """ Template function to call the main algorithm. Provide an easy way to change the algorithm easily in child classes. Contains profiling to measure basic performance of the algorithm. :param request: request graph :type request: :class:`NFFG` :param topology: topology graph :type topology: :class:`NFFG` :param profiling: enables cProfile for mapping which bring big overhead :type profiling: bool :param stats_type: use explicit identifier for statistic :type stats_type: int :param stat_level: use explicit level for statistic :type stat_level: str :param params: additional mapping parameters :type params: dict :return: mapping result :rtype: :class:`NFFG` """ log.debug("Call mapping algorithm with parameters:\n%s" % pprint.pformat(params)) stat_level = stat_level if stat_level else cls.__name__ stats.add_measurement_start_entry(type=stats_type, info=stat_level) try: if profiling: ret = cls.cprofiler_decorator(MAP, request, topology, **params) else: ret = cls.timer_decorator(MAP, request, topology, **params) finally: stats.add_measurement_end_entry(type=stats_type, info=stat_level) return ret
def _proceed_API_call(self, request): """ Fail-safe method to call API function. The cooperative micro-task context is handled by actual APIs. Should call this with params, not directly the function of actual API. :param request: scheduled request container object :type request: APIRequest :return: None """ self.log.info("Start request processing in coop-task: %s" % request) stats.add_measurement_start_entry(stats.TYPE_SCHEDULED, request.id) if core.core.hasComponent(request.layer): layer = core.components[request.layer] if hasattr(layer, request.function): return getattr(layer, request.function)(**request.kwargs) else: raise RESTError( msg='Mistyped or not implemented API function call: %s ' % request.function) else: raise RESTError( msg='Error: No component has registered with name: %s, ' 'ABORT function call!' % request.layer)
def edit_config(self, data, diff=False, message_id=None, callback=None, full_conversion=False): """ Send the requested configuration with a netconf-like "edit-config" command. Remote domains always expect diff of mapping changes. :param data: whole domain view :type data: :class:`NFFG` :param diff: send the diff of the mapping request (default: False) :param diff: bool :param message_id: optional message id :type message_id: str :param callback: callback URL :type callback: str :param full_conversion: do full conversion instead of adapt (default: False) :type full_conversion: bool :return: response data / empty str if request was successful else None :rtype: str """ log.debug("Prepare edit-config request for remote agent at: %s" % self._base_url) if isinstance(data, Virtualizer): # Nothing to do vdata = data elif isinstance(data, NFFG): log.debug("Convert NFFG to XML/Virtualizer format...") if self.last_virtualizer is None: log.debug("Missing last received Virtualizer! " "Updating last topology view now...") self.get_config() if self.last_virtualizer is None: return False stats.add_measurement_start_entry(type=stats.TYPE_CONVERSION, info="%s-deploy" % self.domain_name) if full_conversion: vdata = self.converter.dump_to_Virtualizer(nffg=data) else: vdata = self.converter.adapt_mapping_into_Virtualizer( virtualizer=self.last_virtualizer, nffg=data, reinstall=diff) stats.add_measurement_end_entry(type=stats.TYPE_CONVERSION, info="%s-deploy" % self.domain_name) log.log(VERBOSE, "Adapted Virtualizer:\n%s" % vdata.xml()) else: raise RuntimeError( "Not supported config format: %s for 'edit-config'!" % type(data)) self.__cache_request(data=vdata) if diff: log.debug( "DIFF is enabled. Calculating difference of mapping changes..." ) stats.add_measurement_start_entry(type=stats.TYPE_PROCESSING, info="%s-DIFF" % self.domain_name) vdata = self.__calculate_diff(vdata) stats.add_measurement_end_entry(type=stats.TYPE_PROCESSING, info="%s-DIFF" % self.domain_name) else: log.debug("Using given Virtualizer as full mapping request") plain_data = vdata.xml() log.log(VERBOSE, "Generated Virtualizer:\n%s" % plain_data) if is_empty(virtualizer=vdata): log.info("Generated edit-config request is empty! Skip sending...") return self.SKIPPED_REQUEST log.debug("Send request to %s domain agent at %s..." % (self.domain_name, self._base_url)) params = {} if message_id is not None: params[self.MESSAGE_ID_NAME] = message_id log.debug("Using explicit message-id: %s" % message_id) if callback is not None: params[self.CALLBACK_NAME] = callback log.debug("Using explicit callback: %s" % callback) MessageDumper().dump_to_file(data=plain_data, unique="%s-edit-config" % self.domain_name) try: response = self.send_with_timeout(method=self.POST, url='edit-config', body=plain_data, params=params) except Timeout: log.warning( "Reached timeout(%ss) while waiting for 'edit-config' response!" " Ignore exception..." % self.CONNECTION_TIMEOUT) # Ignore exception - assume the request was successful -> return True return True if response is not None: log.debug("Deploy request has been sent successfully!") return response
def __proceed_instantiation(self, nffg, resource_nffg): """ Helper function to instantiate the NFFG mapping from different source. :param nffg: pre-mapped service request :type nffg: :class:`NFFG` :return: None """ self.log.info("Invoke instantiation on %s with NF-FG: %s" % (self.__class__.__name__, nffg.name)) stats.add_measurement_start_entry(type=stats.TYPE_ORCHESTRATION, info=LAYER_NAME) # Get shown topology view if resource_nffg is None: log.error("Missing resource for difference calculation!") return log.debug("Got resource view for difference calculation: %s" % resource_nffg) self.log.debug("Store received NFFG request info...") 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) self.log.debug("Request is stored with id: %s" % msg_id) else: self.log.debug("No request info detected.") # 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 nffg.mode is not None: mapping_mode = nffg.mode log.info("Detected mapping mode from NFFG: %s" % mapping_mode) else: mapping_mode = None log.info("No mapping mode was defined explicitly!") if not CONFIG.get_mapping_enabled(layer=LAYER_NAME): log.warning("Mapping is disabled! Skip difference calculation...") elif nffg.status == NFFG.MAP_STATUS_SKIPPED: log.debug("Detected NFFG map status: %s! " "Skip difference calculation and " "proceed with original request..." % nffg.status) elif mapping_mode != NFFG.MODE_REMAP: # Calculated ADD-DELETE difference log.debug("Calculate ADD - DELETE difference with mapping mode...") # Recreate SG-hops for diff calc. log.debug("Recreate SG hops for difference calculation...") NFFGToolBox.recreate_all_sghops(nffg=nffg) NFFGToolBox.recreate_all_sghops(nffg=resource_nffg) log.log(VERBOSE, "New NFFG:\n%s" % nffg.dump()) log.log(VERBOSE, "Resource NFFG:\n%s" % resource_nffg.dump()) # Calculate difference add_nffg, del_nffg = NFFGToolBox.generate_difference_of_nffgs( old=resource_nffg, new=nffg, ignore_infras=True) log.log(VERBOSE, "Calculated ADD NFFG:\n%s" % add_nffg.dump()) log.log(VERBOSE, "Calculated DEL NFFG:\n%s" % del_nffg.dump()) if not add_nffg.is_bare() and del_nffg.is_bare(): nffg = add_nffg log.info("DEL NFFG is bare! Calculated mapping mode: %s" % nffg.mode) elif add_nffg.is_bare() and not del_nffg.is_bare(): nffg = del_nffg log.info("ADD NFFG is bare! Calculated mapping mode: %s" % nffg.mode) elif not add_nffg.is_bare() and not del_nffg.is_bare(): log.warning("Both ADD / DEL mode is not supported currently") self.__process_mapping_result(nffg_id=nffg.id, fail=True) stats.add_measurement_end_entry(type=stats.TYPE_ORCHESTRATION, info=LAYER_NAME + "-FAILED") self.raiseEventNoErrors( InstantiationFinishedEvent, id=nffg.id, result=InstantiationFinishedEvent.ABORTED) return else: log.debug("Difference calculation resulted empty subNFFGs!") log.warning( "No change has been detected in request! Skip mapping...") self.log.debug("Invoked instantiation on %s is finished!" % self.__class__.__name__) self.__process_mapping_result(nffg_id=nffg.id, fail=False) stats.add_measurement_end_entry(type=stats.TYPE_ORCHESTRATION, info=LAYER_NAME + "-SKIPPED") return else: log.debug( "Mode: %s detected from config! Skip difference calculation..." % mapping_mode) try: if CONFIG.get_mapping_enabled(layer=LAYER_NAME): # Initiate request mapping mapped_nffg = self.orchestrator.instantiate_nffg(nffg=nffg) else: log.warning("Mapping is disabled! Skip instantiation step...") mapped_nffg = 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) self.log.debug("Invoked instantiate_nffg 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.orchestrator.mapper.threaded: self._proceed_to_install_NFFG(mapped_nffg=mapped_nffg, original_request=nffg) else: log.warning( "Something went wrong in service request instantiation: " "mapped service request is missing!") self.__process_mapping_result(nffg_id=nffg.id, fail=True) stats.add_measurement_end_entry(type=stats.TYPE_ORCHESTRATION, info=LAYER_NAME + "-FAILED") self.raiseEventNoErrors( InstantiationFinishedEvent, id=nffg.id, result=InstantiationFinishedEvent.MAPPING_ERROR) except ProcessorError as e: self.__process_mapping_result(nffg_id=nffg.id, fail=True) stats.add_measurement_end_entry(type=stats.TYPE_ORCHESTRATION, info=LAYER_NAME + "-DENIED") self.raiseEventNoErrors( InstantiationFinishedEvent, id=nffg.id, result=InstantiationFinishedEvent.REFUSED_BY_VERIFICATION, error=e)
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))
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)) stats.add_measurement_start_entry(type=stats.TYPE_SERVICE, info=LAYER_NAME) # 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))
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)