def __init__(self): """ Init. """ super(SGManager, self).__init__() log.debug("Init %s" % self.__class__.__name__) self._service_graphs = dict()
def __init__(self, strategy=None): """ Init Service mapper. :return: None """ super(ServiceGraphMapper, self).__init__(LAYER_NAME, strategy) log.debug("Init %s with strategy: %s" % (self.__class__.__name__, self.strategy.__name__))
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
def shutdown(self, event): """ .. seealso:: :func:`AbstractAPI.shutdown() <escape.util.api.AbstractAPI.shutdown>` :param event: event object """ log.info("Service Layer is going down...") if self.gui_proc: log.debug("Shut down GUI process - PID: %s" % self.gui_proc.pid) self.gui_proc.terminate()
def __init__(self): """ Initialize virtual resource manager. :return: None """ super(VirtualResourceManager, self).__init__() # Derived object from AbstractVirtualizer which represent the virtual # view of this layer self._virtual_view = None log.debug("Init %s" % self.__class__.__name__)
def __init__ (self, strategy=None, mapping_state=None, persistent_state=None): """ Init Service mapper. :return: None """ super(ServiceGraphMapper, self).__init__(LAYER_NAME, strategy) log.debug("Init %s with strategy: %s" % ( self.__class__.__name__, self.strategy.__name__)) self.last_mapping_state = mapping_state self.persistent_state = persistent_state
def shutdown (self, event): """ .. seealso:: :func:`AbstractAPI.shutdown() <escape.util.api.AbstractAPI.shutdown>` :param event: event object """ log.info("Service Layer is going down...") if hasattr(self, 'rest_api') and self.rest_api: log.debug("REST-API: %s is shutting down..." % self.rest_api.api_id) # self.rest_api.stop() if self.gui_proc: log.debug("Shut down GUI process - PID: %s" % self.gui_proc.pid) self.gui_proc.terminate()
def save(self, sg): """ Save SG in a dict. :param sg: Service Graph :type sg: :any:`NFFG` :return: computed id of given Service Graph :rtype: int """ sg_id = self._generate_id(sg) self._service_graphs[sg_id] = sg.copy() log.debug("SG: %s is saved by %s with id: %s" % (sg, self.__class__.__name__, sg_id)) return sg.id
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!")
def __sg_preprocessing(nffg): """ Preprocess given :class:`NFFG` based on request mode. :param nffg: received service request :type nffg: :class:`NFFG` :return: modified request :rtype: :class:`NFFG` """ if nffg.mode == NFFG.MODE_DEL: log.debug("Explicitly mark NF nodes in DELETE request...") for nf in nffg.nfs: nf.operation = NFFG.OP_DELETE log.debug("%s --> %s" % (nf.id, nf.operation)) return nffg
def _mapping_finished (self, mapped_nffg): """ Called from a separate thread when the mapping process is finished. :param mapped_nffg: generated NF-FG :type mapped_nffg: :any:`NFFG` :return: None """ # TODO - rethink threaded/non-threaded function call paths to call port # mapping functions in a joint way only once if mapped_nffg is None: log.error("Mapping process is failed! Abort orchestration process.") return None # Steps after mapping (optional) if the mapping was threaded log.debug("Inform SAS layer API that SG mapping has been finished...") self.raiseEventNoErrors(SGMappingFinishedEvent, mapped_nffg)
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
def __init__(self, layer_API): """ Initialize main Service Layer components. :param layer_API: layer API instance :type layer_API: :any:`ServiceLayerAPI` :return: None """ super(ServiceOrchestrator, self).__init__(layer_API=layer_API) log.debug("Init %s" % self.__class__.__name__) # Init SG Manager self.sgManager = SGManager() # Init virtual resource manager # Listeners must be weak references in order the layer API can garbage # collected self.virtResManager = VirtualResourceManager() self.virtResManager.addListeners(layer_API, weak=True)
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)
def virtual_view(self): """ Return resource info of actual layer as an :class:`NFFG <escape.util.nffg.NFFG>` instance. If it isn't exist requires it from Orchestration layer. :return: resource info as a Virtualizer :rtype: :any:`AbstractVirtualizer` """ log.debug("Invoke %s to get the <Virtual View>" % self.__class__.__name__) if not self._virtual_view: log.debug( "Missing <Virtual View>! Requesting <Virtual View> now...") self.raiseEventNoErrors(MissingVirtualViewEvent) if self._virtual_view is not None: log.debug("Got requested <Virtual View>: %s" % self._virtual_view) return self._virtual_view
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!")
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 __sg_preprocessing(self, nffg): if nffg.mode == NFFG.MODE_DEL: log.debug("Explicitly mark NF nodes in DELETE request...") for nf in nffg.nfs: nf.operation = NFFG.OP_DELETE log.debug("%s --> %s" % (nf.id, nf.operation))
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))
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
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)