def __NC_ApplicationsInstantiation(self, nffg):
        """
        Instantiate applications on the controller implementing VNFs of the NF_FG.
        The vnf are categorized in three groups:
        SWITCH: vnfs that implement a L2 bridge connecting endpoints
        DETACHED: vnfs that have flows just to/from endpoints
        ATTACHED: vnfs that have flows to/from an other vnf
        :param nffg:
        :return:
        """

        def raise_useless_info(msg):
            logging.debug("NFFG vnf emulation: " + msg + ". This DO does not process this kind of data.")
            raise NffgUselessInformations("NFFG vnf emulation: " + msg + ". This DO does not process this kind of data.")

        domain_info = DomainInfo.get_from_file(Configuration().MSG_RESDESC_FILE)

        # [ SWITCH VNFs ]
        if len(self.NetManager.ProfileGraph.getSwitchesVnfs()) != 0:
            # TODO add support to emulate a L2 switch connecting the end points
            raise_useless_info("Switch vnf not supported yet")

        # [ DETACHED VNFs ]
        for vnf in self.NetManager.ProfileGraph.getDetachedVnfs():
            # get the name of the application
            application_name = ""
            for capability in domain_info.capabilities.functional_capabilities:
                if capability.template == vnf.template:
                    application_name = capability.name
            # we just need to activate the application and to pass as configuration the interfaces
            self.__NC_ProcessDetachedVnf(application_name, vnf)

        # [ ATTACHED VNFs ]
        if len(self.NetManager.ProfileGraph.getSwitchesVnfs()) != 0:
            # TODO add support to emulate a L2 switch connecting the end points
            raise_useless_info("Attached vnf not supported yet")
    def NFFG_Validate(self, nffg):
        '''
        A validator for this specific domain orchestrator.
        The original json, as specified in the extern NFFG library,
        could contain useless objects and fields for this DO.
        If this happens, we have to raise exceptions to stop the request processing.  
        '''

        def raise_useless_info(msg):
            logging.debug("NFFG Validation: " + msg + ". This DO does not process this kind of data.")
            raise NffgUselessInformations("NFFG Validation: " + msg + ". This DO does not process this kind of data.")

        def raise_invalid_actions(msg):
            logging.debug("NFFG Validation: " + msg + ". This DO does not process this kind of flowrules.")
            raise NffgUselessInformations("NFFG Validation: " + msg +
                                          ". This DO does not process this kind of flowrules.")

        # EP Array
        EPs = {}

        '''
        The below domain could offer some network function capabilities that could be used to implement
        the VNFs of this graph. Here we check if this is possible (all VNFs of the graph could be implemented on the
        domain), else raise an error.
        '''
        # VNFs inspections
        # TODO this check is implemented through the 'template' information. I don't know if is the best approach
        print(Configuration().MSG_RESDESC_FILE)
        domain_info = DomainInfo.get_from_file(Configuration().MSG_RESDESC_FILE)
        available_functions = []
        for functional_capability in domain_info.capabilities.functional_capabilities:
            available_functions.append(functional_capability.tamplate)
        for vnf in nffg.vnfs:
            if vnf.template not in available_functions:
                raise_useless_info("The VNF '" + vnf.name + "' cannot be implemented on this domain")

        '''
        Busy VLAN ID: the control on the required vlan id(s) must wait for
        the graph instantiation into the database in order to clarify the situation.
        Finally, the the control on the required vlan id(s) is always made before
        processing a flowrule (see the first rows of "__NC_ProcessFlowrule").
        '''

        # END POINTs inspections
        for ep in nffg.end_points:
            if ep.type is not None and ep.type != "interface" and ep.type != "vlan":
                raise_useless_info("'end-points.type' must be 'interface' or 'vlan' (not '" + ep.type + "')")
            if ep.remote_endpoint_id is not None:
                raise_useless_info("presence of 'end-points.remote_endpoint_id'")
            if ep.remote_ip is not None:
                raise_useless_info("presence of 'end-points.remote-ip'")
            if ep.local_ip is not None:
                raise_useless_info("presence of 'end-points.local-ip'")
            if ep.gre_key is not None:
                raise_useless_info("presence of 'gre-key'")
            if ep.ttl is not None:
                raise_useless_info("presence of 'ttl'")
            if ep.prepare_connection_to_remote_endpoint_id is not None:
                raise_useless_info("presence of connection to remote endpoint")
            if ep.prepare_connection_to_remote_endpoint_ids is not None and len(
                    ep.prepare_connection_to_remote_endpoint_ids) > 0:
                raise_useless_info("presence of connection to remote endpoints")
            """
            # Check endpoints in ResourceDescription.json (switch/port)
            if ResourceDescription().checkEndpoint(ep.node_id, ep.interface)==False:
                raise GraphError("Endpoint "+str(ep.id)+" not found")
            """
            # Check vlan availability
            # if ep.type == "vlan" and ep.vlan_id is not None:
            #    if ResourceDescription().VlanID_isAvailable(int(ep.vlan_id), ep.node_id, ep.interface)==False:
            #        vids_list = ResourceDescription().VlanID_getAvailables_asString(ep.node_id, ep.interface)
            #        raise GraphError("Vlan ID "+str(ep.vlan_id)+" not allowed on the endpoint "+str(ep.id)+"! Valid vlan ids: "+vids_list)

            # Add the endpoint
            EPs['endpoint:' + ep.id] = {"sid": ep.node_id, "pid": ep.interface}

        # FLOW RULEs inspection
        for flowrule in nffg.flow_rules:

            if flowrule.match is None:
                GraphError("Flowrule " + flowrule.id + " has not match section")
            if flowrule.match.port_in is None:
                GraphError("Flowrule " + flowrule.id + " has not an ingress endpoint ('port_in')")
            if self.__getEndpointIdFromString(flowrule.match.port_in) is None:
                GraphError("Flowrule " + flowrule.id + " has not an ingress endpoint ('port_in')")

            # Check vlan availability
            # if flowrule.match.vlan_id is not None and ResourceDescription().VlanID_isAvailable(int(flowrule.match.vlan_id), EPs[flowrule.match.port_in]['sid'], EPs[flowrule.match.port_in]['pid'])==False:
            #    vids_list = ResourceDescription().VlanID_getAvailables_asString(ep.node_id, ep.interface)
            #    raise GraphError("Vlan ID "+str(ep.vlan_id)+" not allowed! Valid vlan ids: "+vids_list)

            # Detect multiple output actions (they are not allowed).
            # If multiple output are needed, multiple flow rules should be written
            # in the nffg.json, with a different priorities!
            output_action_counter = 0
            output_ep = None
            for a in flowrule.actions:
                if a.controller is not None and a.controller == True:
                    raise_useless_info("presence of 'output_to_controller'")
                if a.output_to_queue is not None:
                    raise_useless_info("presence of 'output_to_queue'")
                if a.output is not None:
                    if output_action_counter > 0:
                        raise_invalid_actions(
                            "Multiple 'output_to_port' not allowed (flow rule " + str(flowrule.id) + ")")
                    output_action_counter = output_action_counter + 1
                    if self.__getEndpointIdFromString(a.output) is None:
                        GraphError("Flowrule " + str(
                            flowrule.id) + " has not an egress endpoint ('output_to_port' in 'action')")
                    output_ep = a.output

            # Check vlan availability
            for a in flowrule.actions:
                if a.push_vlan is not None and ResourceDescription().VlanID_isAvailable(int(a.push_vlan),
                                                                                        EPs[output_ep]['sid'],
                                                                                        EPs[output_ep]['pid']) == False:
                    vids_list = str(Configuration().VLAN_AVAILABLE_IDS)
                    raise GraphError("Vlan ID " + str(a.push_vlan) + " not allowed! Valid vlan ids: " + vids_list)
                if a.set_vlan_id is not None and ResourceDescription().VlanID_isAvailable(int(a.set_vlan_id),
                                                                                          EPs[output_ep]['sid'],
                                                                                          EPs[output_ep][
                                                                                              'pid']) == False:
                    vids_list = str(Configuration().VLAN_AVAILABLE_IDS)
                    raise GraphError("Vlan ID " + str(a.set_vlan_id) + " not allowed! Valid vlan ids: " + vids_list)