예제 #1
0
    def __init__(self, url, prefix="", features=None, **kwargs):
        """
    Init.

    :param url: url of RESTful API
    :type url: str
    :param prefix: URL prefix
    :type prefix: str
    :param features: limitation anf filter parameters for the Adapter class
    :type features: dict
    :return: None
    """
        AbstractRESTAdapter.__init__(self,
                                     base_url=url,
                                     prefix=prefix,
                                     **kwargs)
        AbstractESCAPEAdapter.__init__(self, **kwargs)
        log.debug("Init %s - type: %s, domain: %s, URL: %s" %
                  (self.__class__.__name__, self.type, self.domain_name, url))
        # Converter object
        self.converter = NFFGConverter(
            unique_bb_id=CONFIG.ensure_unique_bisbis_id(),
            unique_nf_id=CONFIG.ensure_unique_vnf_id(),
            domain=self.domain_name,
            logger=log)
        self.features = features if features is not None else {}
        # Cache for parsed Virtualizer
        self.__last_virtualizer = None
        self.__last_request = None
        self.__original_virtualizer = None
예제 #2
0
  def __init__ (self, url=None, rpc=None, timeout=DEFAULT_TIMEOUT,
                instance_id=None):
    """
    Init.

    :param url: URL of the remote server
    :type url: str
    :param rpc: RPC name
    :type rpc: str
    :param timeout: connections timeout
    :type timeout: int
    :param instance_id: additional id to join to the end of the id
    :type instance_id: str
    :return: None
    """
    super(RemoteVisualizer, self).__init__()
    self.log = core.getLogger("visualizer")
    if url is None:
      url = CONFIG.get_visualization_url()
    if rpc is None:
      rpc = CONFIG.get_visualization_rpc()
    self._url = urlparse.urljoin(url, rpc)
    if self._url is None:
      raise RuntimeError("Missing URL from %s" % self.__class__.__name__)
    self._timeout = timeout
    if instance_id is None:
      self.instance_id = CONFIG.get_visualization_instance_id()
    self.log.info("Setup remote Visualizer with URL: %s" % self._url)
    # Store the last request
    self._response = None
    self.converter = NFFGConverter(domain="ESCAPE", logger=log,
                                   unique_bb_id=CONFIG.ensure_unique_bisbis_id(),
                                   unique_nf_id=CONFIG.ensure_unique_vnf_id())
    # Suppress low level logging
    self.__suppress_requests_logging()
예제 #3
0
    def _initiate_rest_api(self):
        """
    Initialize and set up REST API in a different thread.

    :return: None
    """
        # set bounded layer name here to avoid circular dependency problem
        handler = CONFIG.get_sas_api_class()
        handler.bounded_layer = self._core_name
        params = CONFIG.get_sas_agent_params()
        # can override from global config
        if 'prefix' in params:
            handler.prefix = params['prefix']
        if 'unify_interface' in params:
            handler.virtualizer_format_enabled = params['unify_interface']
        address = (params.get('address'), params.get('port'))
        self.rest_api = RESTServer(handler, *address)
        self.rest_api.api_id = handler.LOGGER_NAME = "U-Sl"
        handler.log.info("Init REST-API for %s on %s:%s!" %
                         (self.rest_api.api_id, address[0], address[1]))
        self.rest_api.start()
        handler.log.debug(
            "Enforced configuration for %s: interface: %s" %
            (self.rest_api.api_id, "UNIFY"
             if handler.virtualizer_format_enabled else "Internal-NFFG"))
예제 #4
0
    def _handle_ComponentRegistered(self, event):
        """
    Wait for controller (internal POX module)

    :param event: registered component event
    :type event: :class:`ComponentRegistered`
    :return: None
    """
        # Check if our POX controller is up
        # ESCAPEConfig follows Singleton design pattern
        internal_adapters = CONFIG.get_component_params(
            component="INTERNAL")['adapters']
        # print internal_adapters
        internal_controller = CONFIG.get_component(component="CONTROLLER",
                                                   parent=internal_adapters)
        # print internal_controller
        if event.name == internal_controller.name and isinstance(
                event.component, OpenFlow_01_Task):
            if self.topology is not None:
                log.info(
                    "Internal domain controller is up! Initiate network emulation "
                    "now...")
                self.topology.start_network()
            else:
                log.error(
                    "Mininet topology is missing! Skip network starting...")
예제 #5
0
  def send_notification (self, data, url=None, unique_id=None, **kwargs):
    """
    Send given data to a remote server for visualization.
    Convert given NFFG into Virtualizer format if needed.

    :param data: topology description need to send
    :type data: :class:`NFFG` or :class:`Virtualizer`
    :param url: additional URL (optional)
    :type url: str
    :param unique_id: use given ID as NFFG id
    :type unique_id: str or int
    :param kwargs: additional params to request
    :type kwargs: dict
    :return: response text
    :rtype: str
    """
    if url is None:
      url = self._url
    if url is None:
      self.log.error("Missing URL for remote visualizer! Skip notification...")
      return
    if 'timeout' not in kwargs:
      kwargs['timeout'] = self._timeout
    self.log.debug("Send visualization notification to %s" % self._url)
    try:
      if data is None:
        self.log.warning("Missing data! Skip notifying remote visualizer.")
        return False
      elif isinstance(data, NFFG):
        data = self.converter.dump_to_Virtualizer(nffg=data)
      elif not isinstance(data, Virtualizer.Virtualizer):
        self.log.warning(
          "Unsupported data type: %s! Skip notification..." % type(data))
        return
      if unique_id:
        data.id.set_value(value=unique_id)
      # If additional params is not empty dict -> override the basic params
      if 'headers' in kwargs:
        kwargs['headers'].update(self.basic_headers)
      else:
        kwargs['headers'] = self.basic_headers.copy()
      kwargs['headers'].update(CONFIG.get_visualization_headers())
      if "params" in kwargs:
        kwargs['params'].update(CONFIG.get_visualization_params())
      else:
        kwargs['params'] = CONFIG.get_visualization_params()
      self.log.debug("Sending visualization notification...")
      self._response = self.request(method='POST', url=url, data=data.xml(),
                                    **kwargs)
      self._response.raise_for_status()
      return self._response.text
    except (ConnectionError, HTTPError, KeyboardInterrupt) as e:
      self.log.warning(
        "Got exception during notifying remote Visualizer: %s!" % e)
      return False
    except Timeout:
      self.log.warning(
        "Got timeout(%ss) during notify remote Visualizer!" % kwargs['timeout'])
      return True
예제 #6
0
 def __create_server(self):
     host = CONFIG.get_rest_api_host()
     port = CONFIG.get_rest_api_port()
     self.flask = Flask(__name__)
     self.__werkzeug = make_server(host=host if host else self.DEFAULT_HOST,
                                   port=port if port else self.DEFAULT_PORT,
                                   app=self.flask)
     # Suppress low level logging
     logging.getLogger("werkzeug").setLevel(logging.WARNING)
예제 #7
0
파일: api.py 프로젝트: walexzzy/escape
    def _all_dependencies_met(self):
        """
    Called when every component on which depends are initialized on POX core.

    Contain dependency relevant initialization.

    :return: None
    """
        try:
            self.initialize()
            # With fully event-driven communication between the layers the dependency
            # handling takes care by listen_to_dependencies() run into a dead-lock.
            # The root of this problem is the bidirectional or cyclic dependency
            # between the components, so basically the layers will always wait to each
            # other to be registered on core. To avoid this situation the naming
            # convention of event handlers on which the dependency checking based is
            # not followed (a.k.a. leave _handle_<component name>_<event name>) and
            # the event listeners is set up manually. For automatic core registration
            # the components have to contain dependencies explicitly.
            for dep in self.dependencies:
                if not self._standalone:
                    if core.core.hasComponent(dep):
                        dep_layer = core.components[dep]
                        # Register actual event handlers on dependent layer
                        dep_layer.addListeners(self)
                        # Register dependent layer's event handlers on actual layer
                        self.addListeners(dep_layer)
                    else:
                        raise AttributeError(
                            "Component is not registered on core")
                else:
                    # In case of standalone mode set up a StandaloneHelper in this object
                    # with the name of the dependency to handle raised events
                    # automatically
                    setattr(self, dep, SimpleStandaloneHelper(self, dep))
            # Subscribe for GoingDownEvent to finalize API classes
            # shutdown() function will be called if POX's core going down
            core.addListenerByName('GoingDownEvent', self.shutdown)
            # Subscribe for UpEvent to call functions after everithing is up
            core.addListenerByName('UpEvent', self.post_up_hook)
            # Subscribe core event for advanced functions
            # Listeners' name must follow POX naming conventions
            core.addListeners(self)
            # Everything is set up an "running" so register the component on pox.core
            # as a final step. Other dependent component can finish initialization
            # now.
            core.core.register(self._core_name, self)
            # Set "running" config for convenience purposes
            CONFIG.set_layer_loaded(self._core_name)
        except KeyboardInterrupt:
            quit_with_error(
                msg="Initialization of %s was interrrupted by user!" %
                self.__class__.__name__)
        except Exception as e:
            quit_with_error(msg="Abort ESCAPEv2 initialization...",
                            exception=e)
예제 #8
0
    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__)
예제 #9
0
  def orchestrate (self, input_graph, resource_view):
    """
    Abstract function for wrapping optional steps connected to orchestration.

    Implemented function call the mapping algorithm.

    If a derived class of :any:`AbstractMappingDataProcessor` is set in the
    global config under the name "PROCESSOR" then the this class performs
    pre/post mapping steps.

    After the pre/post-processor steps the relevant Mapping event will be
    raised on the main API class of the layer!

    :param input_graph: graph representation which need to be mapped
    :type input_graph: :class:`NFFG`
    :param resource_view: resource information
    :type resource_view: :any:`AbstractVirtualizer`
    :raise: NotImplementedError
    :return: mapped graph
    :rtype: :class:`NFFG`
    """
    # Get resource info
    resource_graph = resource_view.get_resource_info()
    # If validator is not None call the pre function
    if CONFIG.get_processor_enabled(layer=self._layer_name):
      # Preform pre-mapping validation
      if self.processor is not None and self.processor.pre_mapping_exec(
         input_graph=input_graph, resource_graph=resource_graph):
        # Raise Error if processor function return with True
        raise ProcessorError("Pre mapping validation is failed!")
    # Raise event for external POX modules
    if core.hasComponent(self._layer_name):
      core.components[self._layer_name].raiseEvent(
        PreMapEvent, input_graph=input_graph, resource_graph=resource_graph)
    # Invoke mapping algorithm
    mapping_result = self._perform_mapping(input_graph=input_graph,
                                           resource_view=resource_view)
    # Perform post-mapping validation
    # If the mapping is threaded skip post mapping here
    if not self._threaded:
      # If validator is not None call the post function
      if CONFIG.get_processor_enabled(layer=self._layer_name):
        if self.processor is not None and self.processor.post_mapping_exec(
           input_graph=input_graph, resource_graph=resource_graph,
           result_graph=mapping_result):
          # Raise Error if processor function return with True
          raise ProcessorError("Post mapping validation is failed!")
      # Raise event for external POX modules
      if core.hasComponent(self._layer_name):
        core.components[self._layer_name].raiseEvent(
          PostMapEvent, input_graph=input_graph, resource_graph=resource_graph,
          result_graph=mapping_result)
    # Return the mapped NFFG
    return mapping_result
예제 #10
0
 def __get_slor_resource_view(self):
     """
 :return: Return with the Virtualizer object assigned to the Sl-Or interface.
 :rtype: :any:`AbstractVirtualizer`
 """
     virt_mgr = self.orchestrator.virtualizerManager
     virtualizer_type = CONFIG.get_api_virtualizer(layer=self._core_name)
     params = CONFIG.get_virtualizer_params(layer=self._core_name)
     log.debug("Acquired Virtualizer type: %s, params: %s" %
               (virtualizer_type, params))
     return virt_mgr.get_virtual_view(virtualizer_id=self._core_name,
                                      type=virtualizer_type,
                                      **params)
예제 #11
0
 def initialize(self):
     """
 .. seealso::
   :func:`AbstractAPI.initialize() <escape.util.api.AbstractAPI.initialize>`
 """
     log.debug("Initializing Infrastructure Layer...")
     # Set layer's LOADED value manually here to avoid issues
     CONFIG.set_layer_loaded(self._core_name)
     mn_opts = CONFIG.get_mn_network_opts()
     # Build the emulated topology with the NetworkBuilder
     optional_topo = getattr(self, '_topo', None)
     self.topology = ESCAPENetworkBuilder(**mn_opts).build(
         topo=optional_topo)
     log.info("Infrastructure Layer has been initialized!")
예제 #12
0
  def __init__ (self, layer_API, mapper=None, strategy=None):
    """
    Init.

    :param layer_API: reference os the actual layer performing the orchestration
    :type layer_API: :any:`AbstractAPI`
    :param mapper: additional mapper class (optional)
    :type mapper: :any:`AbstractMapper`
    :param strategy: override strategy class for the used Mapper (optional)
    :type strategy: :any:`AbstractMappingStrategy`
    :return: None
    """
    layer_name = layer_API._core_name
    # Set Mapper
    if mapper is None:
      # Use the Mapper in CONFIG
      mapper = CONFIG.get_mapper(layer_name)
      if mapper is None and self.DEFAULT_MAPPER is not None:
        # Use de default Mapper if it's set
        self.mapper = self.DEFAULT_MAPPER
      if mapper is None:
        raise RuntimeError("Mapper class is not found!")
    assert issubclass(mapper, AbstractMapper), "Mapper is not subclass of " \
                                               "AbstractMapper!"
    self.mapper = mapper(strategy=strategy)
    # Init Mapper listeners
    # Listeners must be weak references in order the layer API can garbage
    # collected
    # self.mapper is set by the AbstractOrchestrator's constructor
    self.mapper.addListeners(layer_API, weak=True)
    super(AbstractOrchestrator, self).__init__()
예제 #13
0
    def __filter_external_domains(nffg):
        """
    Filter out domains detected by external DomainManagers.

    :param nffg: filtered NFFG
    :return: :class:`NFFG`
    """
        log.debug("Filtering domains detected from external DomainManagers...")
        # Get External DomainManager names
        ext_mgr = CONFIG.get_external_managers()
        # Copy NFFG
        filtered_nffg = nffg.copy()
        # Remove the detected domains by External DomainManagers
        for ext in ext_mgr:
            # Get all the domains
            domains = NFFGToolBox.detect_domains(nffg=filtered_nffg)
            # Get domains detected and initiated by the External DomainManager
            ext_domains = [d for d in domains if ext in d]
            # Remove collected domains from NFFG
            for domain in ext_domains:
                log.debug(
                    "Remove domain: %s originated from external DomainManager: %s"
                    % (domain, ext))
                NFFGToolBox.remove_domain(base=filtered_nffg,
                                          domain=domain,
                                          log=log)
        filtered_nffg.name += "-filtered"
        return filtered_nffg
예제 #14
0
 def collect_mappings(self, mappings, slor_topo):
     dov = self.virtualizerManager.dov.get_resource_info()
     response = mappings.full_copy()
     log.debug("Start checking mappings...")
     for mapping in response:
         bb, nf = detect_bb_nf_from_path(path=mapping.object.get_value(),
                                         topo=slor_topo)
         if not nf:
             # mapping.target.object.set_value("NOT_FOUND")
             mapping.target.domain.set_value("N/A")
             continue
         m_result = self.__collect_binding(dov=dov, nfs=[nf])
         if not m_result:
             log.warning("Mapping is not found for NF: %s!" % nf)
             # mapping.target.object.set_value("NOT_FOUND")
             mapping.target.domain.set_value("N/A")
             continue
         try:
             node = m_result[0]['bisbis']['id']
             domain = m_result[0]['bisbis']['domain']
         except KeyError:
             log.warning("Missing mapping element from: %s" % m_result)
             # mapping.target.object.set_value("NOT_FOUND")
             mapping.target.domain.set_value("N/A")
             continue
         log.debug("Found mapping: %s@%s (domain: %s)" % (nf, node, domain))
         mapping.target.object.set_value(NF_PATH_TEMPLATE % (node, nf))
         mapping.target.domain.set_value(
             CONFIG.get_domain_url(domain=domain))
     return response
예제 #15
0
    def _handle_InstallationFinishedEvent(self, event):
        """
    Get information from NFFG installation process.

    :param event: event object info
    :type event: :any:`InstallationFinishedEvent`
    :return: None
    """
        if not InstantiationFinishedEvent.is_error(event.result):
            self.log.info(
                "NF-FG(%s) instantiation has been finished successfully "
                "with result: %s!" % (event.id, event.result))
        else:
            self.log.error(
                "NF-FG(%s) instantiation has been finished with error "
                "result: %s!" % (event.id, event.result))
            if InstantiationFinishedEvent.is_deploy_error(event.result):
                if CONFIG.get_trial_and_error(layer=LAYER_NAME):
                    log.info(
                        "TRIAL_AND_ERROR is enabled! Reschedule for mapping..."
                    )
                    self.__proceed_trial_and_error(
                        original_request_id=event.id)
                    return
                else:
                    log.debug("TRIAL_AND_ERROR is disabled! Proceeding...")
        if not event.is_pending(event.result):
            self.__process_mapping_result(nffg_id=event.id,
                                          fail=event.is_error(event.result))
        self.raiseEventNoErrors(InstantiationFinishedEvent,
                                id=event.id,
                                result=event.result)
예제 #16
0
    def __update_nffg_domain(nffg_part, domain_name=None):
        """
    Update domain descriptor of infras: REMOTE -> INTERNAL

    :param nffg_part: NF-FG need to be updated
    :type nffg_part: :class:`NFFG`
    :return: updated NFFG
    :rtype: :class:`NFFG`
    """
        rewritten = []
        if domain_name is None:
            local_mgr = CONFIG.get_internal_manager()
            if local_mgr is None:
                log.error("No local Manager has been initiated! "
                          "Skip domain rewriting!")
            elif len(local_mgr) > 1:
                log.warning("Multiple local Manager has been initiated: %s! "
                            "Arbitrarily use the first..." % local_mgr)
            domain_name = local_mgr.pop()
        log.debug("Rewrite received NFFG domain to %s..." % domain_name)
        for infra in nffg_part.infras:
            infra.domain = domain_name
            rewritten.append(infra.id)
        log.debug("Rewritten infrastructure nodes: %s" % rewritten)
        return nffg_part
예제 #17
0
    def __manage_neo4j_service(self):
        """
    Manage neo4j service.

    :return: None
    """
        if not CONFIG.get_manage_neo4j_service():
            log.debug("Skip Neo4j service management...")
            return
        log.debug("Detected Neo4j service name: %s" % self.service_name)
        if check_service_status(self.service_name):
            log.debug("%s service is already running..." % self.service_name)
            return
        log.info("Starting service: %s..." % self.service_name)
        ret = run_cmd('sudo service %s start' % self.service_name)
        if "failed" in ret:
            log.error("Neo4j service initiation status: %s" % ret)
            return
        log.log(VERBOSE, "Neo4j service initiation status: %s" % ret)
        # Check if the service has been started - only 5 try
        if port_tester(host=self.DB_HOST,
                       port=self.DB_PORT,
                       interval=1,
                       period=10,
                       log=log):
            log.debug("Neo4j service has been verified!")
        else:
            log.error("Neo4j service has not started correctly!")
예제 #18
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!")
예제 #19
0
 def __init__(self, standalone=False, **kwargs):
     log.info("Starting REST-API Sublayer...")
     self.__server = MainApiServer()
     self.__entry_point_cache = {}
     self.mgrs = {}
     self.is_up = False
     self.prefix = CONFIG.get_rest_api_prefix()
     super(RestInterfaceAPI, self).__init__(standalone, **kwargs)
예제 #20
0
    def finalize(self):
        """
    Finalize function for the class.

    :return: None
    """
        if CONFIG.get_manage_neo4j_service():
            log.info("Stopping %s service..." % self.service_name)
            ret = run_cmd('sudo service %s stop' % self.service_name)
            log.log(VERBOSE, "Neo4j service shutdown status: %s" % ret)
예제 #21
0
  def __init__ (self, layer_name, strategy=None, threaded=None):
    """
    Initialize Mapper class.

    Set given strategy class and threaded value or check in `CONFIG`.

    If no valid value is found for arguments set the default params defined
    in `_default`.

    .. warning::
      Strategy classes must be a subclass of AbstractMappingStrategy

    :param layer_name: name of the layer which initialize this class. This
      value is used to search the layer configuration in `CONFIG`
    :type layer_name: str
    :param strategy: strategy class (optional)
    :type strategy: :any:`AbstractMappingStrategy`
    :param threaded: run mapping algorithm in separate Python thread instead
      of in the coop microtask environment (optional)
    :type threaded: bool
    :return: None
    """
    self._layer_name = layer_name
    # Set threaded
    self._threaded = threaded if threaded is not None else CONFIG.get_threaded(
      layer_name)
    # Set strategy
    if strategy is None:
      # Use the Strategy in CONFIG
      strategy = CONFIG.get_strategy(layer_name)
      if strategy is None and self.DEFAULT_STRATEGY is not None:
        # Use the default Strategy if it's set
        strategy = self.DEFAULT_STRATEGY
      if strategy is None:
        raise RuntimeError("Strategy class is not found!")
    self.strategy = strategy
    assert issubclass(strategy,
                      AbstractMappingStrategy), "Mapping strategy is not " \
                                                "subclass of " \
                                                "AbstractMappingStrategy!"
    self.processor = CONFIG.get_mapping_processor(layer_name)(layer_name)
    super(AbstractMapper, self).__init__()
예제 #22
0
파일: callback.py 프로젝트: walexzzy/escape
    def initialize_on_demand(cls):
        """
    Initialize the CallbackManager on demand.

    :return: initializer manager object
    :rtype: :class:`CallbackManager`
    """
        global_cb_cfg = CONFIG.get_callback_config()
        callback_manager = cls(**global_cb_cfg)
        callback_manager.start()
        return callback_manager
예제 #23
0
    def __init__(self, domain_name=None, path=None, diff=None, **kwargs):
        """
    Init.

    :param path: file path offered as the domain topology
    :type path: str
    :return: None
    """
        log.debug(
            "Init %s - type: %s, domain: %s, path: %s, diff: %s" %
            (self.__class__.__name__, self.type, domain_name, path, diff))
        # Converter object
        self.converter = NFFGConverter(
            unique_bb_id=CONFIG.ensure_unique_bisbis_id(),
            unique_nf_id=CONFIG.ensure_unique_vnf_id(),
            domain=domain_name,
            logger=log)
        super(VirtualizerBasedStaticFileAdapter,
              self).__init__(domain_name=domain_name, path=path, **kwargs)
        self.diff = diff
예제 #24
0
    def _handle_GetVirtResInfoEvent(self, event):
        """
    Generate virtual resource info and send back to SAS.

    :param event: event object contains service layer id
    :type event: :any:`GetVirtResInfoEvent`
    :return: None
    """
        self.log.debug("Received <Virtual View> request from %s layer" %
                       str(event.source._core_name).title())
        # Currently view is a Virtualizer to keep ESCAPE fast
        # Virtualizer type for Sl-Or API
        virtualizer_type = CONFIG.get_api_virtualizer(layer=event.sid)
        params = CONFIG.get_virtualizer_params(layer=event.sid)
        v = self.orchestrator.virtualizerManager.get_virtual_view(
            virtualizer_id=event.sid, type=virtualizer_type, **params)
        if v is None:
            self.log.error("Missing Virtualizer for id: %s!" % event.sid)
            return
        self.log.debug("Sending back <Virtual View>: %s..." % v)
        self.raiseEventNoErrors(VirtResInfoEvent, v)
예제 #25
0
    def __init_from_CONFIG(self, format=DEFAULT_NFFG_FORMAT):
        """
    Build a pre-defined topology from an NFFG stored in a file.
    The file path is searched in CONFIG with tha name ``TOPO``.

    :param format: NF-FG storing format (default: internal NFFG representation)
    :type format: str
    :return: None
    """
        path = CONFIG.get_mininet_topology()
        if path is None:
            raise TopologyBuilderException("Missing Topology!")
        self.__init_from_file(path=path, format=format)
예제 #26
0
 def register_component(self, component):
     component_name = component._core_name
     mgr_klass = CONFIG.get_rest_api_resource_class(layer=component_name)
     if mgr_klass is None:
         log.error("REST-API configuration is missing for component: %s" %
                   component_name)
         return
     mgr = mgr_klass(layer_api=self)
     mgr.register_routes(app=self.__server.flask)
     self._register_entry_points(component=component)
     self.mgrs[mgr.LAYER_NAME] = mgr
     log.debug("Register component: %s into %s" %
               (component_name, self.__server))
예제 #27
0
    def get_network(self):
        """
    Return the bridge to the constructed network.

    :return: object representing the emulated network
    :rtype: :any:`ESCAPENetworkBridge`
    """
        if self.mn_bridge is None:
            # Create the Interface object and set the topology description as the
            # original NFFG
            self.mn_bridge = ESCAPENetworkBridge(network=self.mn,
                                                 topo_desc=self.topo_desc)
            # Additional settings
            self.mn_bridge._need_clean = CONFIG.get_clean_after_shutdown()
        return self.mn_bridge
예제 #28
0
 def __init__(self, standalone=False, **kwargs):
     """
 .. seealso::
   :func:`AbstractAPI.__init__() <escape.util.api.AbstractAPI.__init__>`
 """
     log.info("Starting Resource Orchestration Sublayer...")
     # Mandatory super() call
     self.orchestrator = None
     """:type: ResourceOrchestrator"""
     self.api_mgr = RESTAPIManager(
         unique_bb_id=False,
         unique_nf_id=CONFIG.ensure_unique_vnf_id(),
         logger=log)
     self.log = log.getChild('API')
     super(ResourceOrchestrationAPI, self).__init__(standalone, **kwargs)
예제 #29
0
 def dispatch_request(self):
     """
 :return:
 """
     log.info("Received edit-config deploy request...")
     if not request.data:
         log.error("No data received!")
         return Response("Request data is missing!", httplib.BAD_REQUEST)
     # Get message-id
     unique = "ESCAPE-%s-edit-config" % self.mgr.LAYER_NAME
     # Trailing
     stats.init_request_measurement(request_id=unique)
     MessageDumper().dump_to_file(data=request.data, unique=unique)
     # Parsing
     log.debug("Parsing request (body_size: %s)..." % len(request.data))
     if CONFIG.get_rest_api_config(self.mgr.LAYER_NAME)['unify_interface']:
         req = Virtualizer.parse_from_text(text=request.data)
     else:
         req = NFFG.parse(raw_data=request.data)
         if req.mode:
             log.info("Detected mapping mode in request body: %s" %
                      req.mode)
         else:
             if request.method == 'POST':
                 req.mode = req.MODE_ADD
                 log.debug('Add mapping mode: %s based on HTTP verb: %s' %
                           (req.mode, request.method))
             elif request.method == 'PUT':
                 req.mode = NFFG.MODE_DEL
                 log.debug('Add mapping mode: %s based on HTTP verb: %s' %
                           (req.mode, request.method))
             else:
                 log.info('No mode parameter has been defined in body!')
     log.debug("Request parsing ended...")
     # Scheduling
     params = request.args.to_dict(flat=True)
     msg_id = self.get_message_id()
     log.info("Acquired message-id: %s" % msg_id)
     params[self.MESSAGE_ID_NAME] = msg_id
     entry_point = self.mgr.layer_api.get_entry_point(
         layer=self.mgr.LAYER_NAME, rpc=self.name)
     self.mgr.scheduler.schedule_request(id=msg_id,
                                         layer=self.mgr.LAYER_NAME,
                                         hook=entry_point,
                                         data=req,
                                         params=params)
     return Response(status=httplib.ACCEPTED,
                     headers={"message-id": msg_id})
예제 #30
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
    """
        self.log.debug("Requesting Virtualizer for %s" % self._core_name)
        slor_virt = self.__get_slor_resource_view()
        if slor_virt is not None:
            # Check the topology is initialized
            if slor_virt.revision is None:
                self.log.debug("DoV has not initialized yet! "
                               "Force to get default topology...")
            else:
                # Check if the resource is changed
                if self.api_mgr.topology_revision == slor_virt.revision:
                    # If resource has not been changed return False
                    # This causes to response with the cached topology
                    self.log.debug(
                        "Global resource has not changed (revision: %s)! " %
                        slor_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:
                    self.log.debug(
                        "Response cache is outdated (new revision: %s)!" %
                        slor_virt.revision)
            # Get topo view as NFFG
            res = slor_virt.get_resource_info()
            self.api_mgr.topology_revision = slor_virt.revision
            self.log.debug("Updated revision number: %s" %
                           self.api_mgr.topology_revision)
            if CONFIG.get_rest_api_config(self._core_name)['unify_interface']:
                self.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 assigned to %s is not found!" %
                      self._core_name)