<reponame>onap/optf-osdf<gh_stars>1-10
# -------------------------------------------------------------------------
#   Copyright (c) 2020 Fujitsu Limited Intellectual Property
#
#   Licensed under the Apache License, Version 2.0 (the "License");
#   you may not use this file except in compliance with the License.
#   You may obtain a copy of the License at
#
#       http://www.apache.org/licenses/LICENSE-2.0
#
#   Unless required by applicable law or agreed to in writing, software
#   distributed under the License is distributed on an "AS IS" BASIS,
#   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
#   See the License for the specific language governing permissions and
#   limitations under the License.
#
# -------------------------------------------------------------------------


import os
import itertools
import json
import requests
from requests.auth import HTTPBasicAuth
import urllib3

from osdf.logging.osdf_logging import audit_log
import pymzn
from sklearn import preprocessing

BASE_DIR = os.path.dirname(__file__)
urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)


class InterDomainRouteOpt:

    """
    This values will need to deleted..
    only added for the debug purpose
    """
    aai_headers = {
        "X-TransactionId": "9999",
        "X-FromAppId": "OOF",
        "Accept": "application/json",
        "Content-Type": "application/json",
    }


    def get_route(self, request, osdf_config):
        """
        This method processes the mdons route request
        and returns an optimised path for the given
        two ports
        """

        try:
            route_info = request["routeInfo"]["routeRequest"]
            src_controller_id = route_info["srcDetails"]["controllerId"]
            src_port_id = route_info["srcDetails"]["interfaceId"]
            dst_controller_id = route_info["dstDetails"]["controllerId"]
            dst_port_id = route_info["dstDetails"]["interfaceId"]
            service_rate = route_info["serviceRate"]
            dzn_data, mapping_table = self.build_dzn_data(osdf_config, src_controller_id,
                                                          dst_controller_id, service_rate)
            audit_log.info("Dzn data")
            audit_log.info(dzn_data)
            mzn_model = os.path.join(BASE_DIR, 'route_opt.mzn')
            links_list = self.find_suitable_path(mzn_model, dzn_data, mapping_table)
            ordered_list = self.get_ordered_route_list(links_list,
                                                       src_controller_id, dst_controller_id)
            solution = self.get_solution_object(ordered_list, src_port_id, dst_port_id)
            return {
                "requestId": request["requestInfo"]["requestId"],
                "transactionId": request["requestInfo"]["transactionId"],
                "statusMessage": "SUCCESS",
                "requestStatus": "accepted",
                "solutions": solution
                }
        except Exception as err:
            audit_log.info(err)
            raise err

    def get_solution_object(self, ordered_list, src_port_id, dst_port_id):
        """
        :param ordered_list: service_route list
        :param src_port_id: source port id of route
        :param dst_port_id: destination port id of route
        :return: solution object of the route respone
        """
        service_route_list = []
        link_list = []
        for value in ordered_list:
            service_route_object = {}
            service_route_object["srcInterfaceId"] = src_port_id
            service_route_object["dstInterfaceId"] = value["srcPortId"]
            service_route_object["controllerId"] = value["srcControllerId"]
            service_route_list.append(service_route_object)
            link_list.append(value["linkName"])
            src_port_id = value["dstPortId"]
            dst_controller_id = value["dstControllerId"]
        service_route_object = {}
        service_route_object["srcInterfaceId"] = src_port_id
        service_route_object["dstInterfaceId"] = dst_port_id
        service_route_object["controllerId"] = dst_controller_id
        service_route_list.append(service_route_object)
        route_info_object = {
            "serviceRoute" : service_route_list,
            "linkList" : link_list
            }
        solution = {
            "routeInfo" : route_info_object
            }
        return solution


    def get_ordered_route_list(self, link_list, src_controller_id, dst_controller_id):
        """
        :param link_list: link list from the minizinc response
        :param src_controller_id: source port id of route
        :param dst_controller_id: destination port id of route
        :return: route list in order
        """
        ordered_link_list = []
        flag = True
        while flag:
            for item in link_list:
                if item["srcControllerId"] == src_controller_id:
                    ordered_link_list.append(item)
                    src_controller_id = item["dstControllerId"]
                    if src_controller_id == dst_controller_id:
                        flag = False
        return ordered_link_list


    def find_suitable_path(self, mzn_model, dzn_data, mapping_table):
        """
        :param mzn_model: minizinc model details
        :param dzn_data: minizinc data
        :param mapping_table: list that maintains AAI link details
        :return: list of link from after running minizinc
        """
        minizinc_solution = self.solve(mzn_model, dzn_data)
        audit_log.info("Minizinc Solution ==========>")
        routes = list(minizinc_solution)
        audit_log.info(routes)
        try:
            arr = routes[0]['x']
        except Exception as err:
            audit_log.info("No minizinc solutions found")
            raise err
        links_list = []
        for i in range(0, len(routes[0]['x'])):
            if arr[i] == 1:
                links_list.append(mapping_table[i])
        return links_list


    def process_inter_domain_link(self, logical_link, osdf_config):
        """
        :param logical_link: logical links from AAI
        :param osdf_config: OSDF config details
        :return: list of link object with src and dst controller details
        """
        link_details = {}
        link_details["linkName"] = logical_link["link-name"]
        relationship = logical_link["relationship-list"]["relationship"]
        flag = 1

        for value in relationship:
            if value["related-to"] == "p-interface" and flag == 1:
                src_port_id = value["relationship-data"][1]["relationship-value"]
                src_controller_id = self.get_controller_for_interface(osdf_config, src_port_id)
                link_details["srcPortId"] = src_port_id
                link_details["srcControllerId"] = src_controller_id
                flag += 1
            elif value["related-to"] == "p-interface" and flag == 2:
                dest_port_id = value["relationship-data"][1]["relationship-value"]
                dest_controller_id = self.get_controller_for_interface(osdf_config, dest_port_id)
                link_details["dstPortId"] = dest_port_id
                link_details["dstControllerId"] = dest_controller_id
        return link_details


    def prepare_map_table(self, osdf_config, logical_links):
        """
        :param logical_links: logical links from AAI
        :param osdf_config: OSDF config details
        :return: list of link object with src and dst controller details
        """
        results = map(self.process_inter_domain_link, logical_links,
                      itertools.repeat(osdf_config, len(logical_links)))
        new_results = list(results)

        new_list = []
        new_list += new_results
        for i in new_results:
            link_details = {}
            link_details["linkName"] = i["linkName"]
            link_details["srcPortId"] = i["dstPortId"]
            link_details["srcControllerId"] = i["dstControllerId"]
            link_details["dstPortId"] = i["srcPortId"]
            link_details["dstControllerId"] = i["srcControllerId"]
            new_list.append(link_details)
        return new_list


    def solve(self, mzn_model, dzn_data):
        """
        :param mzn_model: minizinc template
        :param dzn_data: minizinc data model
        :return: minizinc response
        """
        return pymzn.minizinc(mzn=mzn_model, data=dzn_data)


    def get_links_based_on_bandwidth_attributes(self, logical_links_list,
                                                osdf_config, service_rate):
        """
        This method filters the logical links based on the
        bandwidth attribute availability of the interfaces
        from AAI
        :return: filtered_list[]
        """
        filtered_list = []
        for logical_link in logical_links_list:
            relationship = logical_link["relationship-list"]["relationship"]
            count = 0
            for value in relationship:
                if value["related-to"] == "p-interface":
                    interface_url = value["related-link"]
                    if self.get_available_bandwidth_aai(interface_url, osdf_config, service_rate):
                        count += 1
            if count == 2:
                filtered_list.append(logical_link)

        return  filtered_list


    def build_dzn_data(self, osdf_config, src_controller_id, dst_controller_id, service_rate):
        """
        :param osdf_config: OSDF config details
        :param src_controller_id: controller Id of the source port
        :param dst_controller_id: controller id of the destination port
        :param service_rate: service rate
        :return: mapping atble which maintains link details from AAI
        and minizinc data model to be used by template
        """
        logical_links = self.get_inter_domain_links(osdf_config)
        logical_links_list = logical_links["logical-link"]
        mapping_table = self.prepare_map_table(osdf_config,
                                               self.get_links_based_on_bandwidth_attributes(logical_links_list, osdf_config, service_rate))

        edge_start = []
        edge_end = []
        for item in mapping_table:
            edge_start.append(item["srcControllerId"])
            edge_end.append(item["dstControllerId"])
        link_cost = []
        for k in range(0, len(edge_start)):
            link_cost.append(1)
        list_controllers = self.get_controllers_from_aai(osdf_config)
        le = preprocessing.LabelEncoder()
        le.fit(list_controllers)

        start_edge = le.transform(edge_start)
        end_edge = le.transform(edge_end)
        source = le.transform([src_controller_id])
        destination = le.transform([dst_controller_id])

        final_dzn_start_arr = []
        for i in start_edge:
            final_dzn_start_arr.append(i)

        final_dzn_end_arr = []
        for j in end_edge:
            final_dzn_end_arr.append(j)

        contollers_length = len(list_controllers)
        no_of_edges = len(final_dzn_start_arr)
        dzn_data = {
            'N': contollers_length,
            'M': no_of_edges,
            'Edge_Start': final_dzn_start_arr,
            'Edge_End': final_dzn_end_arr,
            'L': link_cost,
            'Start': source[0],
            'End' : destination[0]
            }
        return dzn_data, mapping_table


    def get_inter_domain_links(self, osdf_config):
        """
        This method returns list of all cross ONAP links
        from /aai/v19/network/logical-links?link-type=inter-domain&operational-status="Up"
        :return: logical-links[]
        """

        config = osdf_config.deployment
        aai_url = config["aaiUrl"]
        aai_req_url = aai_url + config["aaiGetInterDomainLinksUrl"]
        response = requests.get(aai_req_url, headers=self.aai_headers,
                                auth=HTTPBasicAuth("AAI", "AAI"), verify=False)
        if response.status_code == 200:
            return response.json()


    def get_controller_for_interface(self, osdf_config, port_id):
        """
        This method returns returns the controller id
        given a p-interface from the below query
        :return: controller_id
        """
        data = {
            "start": ["external-system"],
            "query": "query/getDomainController?portid="
        }
        query = data.get("query") + port_id
        data.update(query=query)
        config = osdf_config.deployment
        aai_url = config["aaiUrl"]
        aai_req_url = aai_url + config["controllerQueryUrl"]
        response = requests.put(aai_req_url, data=json.dumps(data),
                                headers=self.aai_headers,
                                auth=HTTPBasicAuth("AAI", "AAI"),
                                verify=False)
        if response.status_code == 200:
            response_body = response.json()
            return response_body["results"][0]["esr-thirdparty-sdnc"]["thirdparty-sdnc-id"]


    def get_controllers_from_aai(self, osdf_config):
        """
        This method returns returns the list of
        controller names in AAI
        :return: controllers_list[]
        """
        controllers_list = []
        config = osdf_config.deployment
        aai_url = config["aaiUrl"]
        aai_req_url = aai_url + config["aaiGetControllersUrl"]
        response = requests.get(aai_req_url,
                                headers=self.aai_headers,
                                auth=HTTPBasicAuth("AAI", "AAI"),
                                verify=False)
        if response.status_code == 200:
            response_body = response.json()
            esr_thirdparty_list = response_body["esr-thirdparty-sdnc"]

            for item in esr_thirdparty_list:
                controllers_list.append(item["thirdparty-sdnc-id"])
            return controllers_list


    def get_available_bandwidth_aai(self, interface_url, osdf_config, service_rate):
        """
        Checks if the given interface has the required bandwidth
        :return: boolean flag
        """
        config = osdf_config.deployment
        aai_url = config["aaiUrl"]
        aai_req_url = aai_url + interface_url + "?depth=all"
        response = requests.get(aai_req_url,
                                headers=self.aai_headers,
                                auth=HTTPBasicAuth("AAI", "AAI"), verify=False)
        if response.status_code == 200:
            response_body = response.json()
            available_bandwidth = response_body["bandwidth-attributes"]["bandwidth-attribute"][0]["available-bandwidth-map"]["available-bandwidth"]
            for i in available_bandwidth:
                if i["odu-type"] == service_rate and i["number"] > 0:
                    return True

# -------------------------------------------------------------------------
#   Copyright (c) 2020 Fujitsu Limited Intellectual Property
#
#   Licensed under the Apache License, Version 2.0 (the "License");
#   you may not use this file except in compliance with the License.
#   You may obtain a copy of the License at
#
#       http://www.apache.org/licenses/LICENSE-2.0
#
#   Unless required by applicable law or agreed to in writing, software
#   distributed under the License is distributed on an "AS IS" BASIS,
#   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
#   See the License for the specific language governing permissions and
#   limitations under the License.
#
# -------------------------------------------------------------------------


import os
import itertools
import json
import requests
from requests.auth import HTTPBasicAuth
import urllib3

from osdf.logging.osdf_logging import audit_log
import pymzn
from sklearn import preprocessing

BASE_DIR = os.path.dirname(__file__)
urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)


class InterDomainRouteOpt:

    """
    This values will need to deleted..
    only added for the debug purpose
    """
    aai_headers = {
        "X-TransactionId": "9999",
        "X-FromAppId": "OOF",
        "Accept": "application/json",
        "Content-Type": "application/json",
    }


    def get_route(self, request, osdf_config):
        """
        This method processes the mdons route request
        and returns an optimised path for the given
        two ports
        """

        try:
            route_info = request["routeInfo"]["routeRequest"]
            src_controller_id = route_info["srcDetails"]["controllerId"]
            src_port_id = route_info["srcDetails"]["interfaceId"]
            dst_controller_id = route_info["dstDetails"]["controllerId"]
            dst_port_id = route_info["dstDetails"]["interfaceId"]
            service_rate = route_info["serviceRate"]
            dzn_data, mapping_table = self.build_dzn_data(osdf_config, src_controller_id,
                                                          dst_controller_id, service_rate)
            audit_log.info("Dzn data")
            audit_log.info(dzn_data)
            mzn_model = os.path.join(BASE_DIR, 'route_opt.mzn')
            links_list = self.find_suitable_path(mzn_model, dzn_data, mapping_table)
            ordered_list = self.get_ordered_route_list(links_list,
                                                       src_controller_id, dst_controller_id)
            solution = self.get_solution_object(ordered_list, src_port_id, dst_port_id)
            return {
                "requestId": request["requestInfo"]["requestId"],
                "transactionId": request["requestInfo"]["transactionId"],
                "statusMessage": "SUCCESS",
                "requestStatus": "accepted",
                "solutions": solution
                }
        except Exception as err:
            audit_log.info(err)
            raise err

    def get_solution_object(self, ordered_list, src_port_id, dst_port_id):
        """
        :param ordered_list: service_route list
        :param src_port_id: source port id of route
        :param dst_port_id: destination port id of route
        :return: solution object of the route respone
        """
        service_route_list = []
        link_list = []
        for value in ordered_list:
            service_route_object = {}
            service_route_object["srcInterfaceId"] = src_port_id
            service_route_object["dstInterfaceId"] = value["srcPortId"]
            service_route_object["controllerId"] = value["srcControllerId"]
            service_route_list.append(service_route_object)
            link_list.append(value["linkName"])
            src_port_id = value["dstPortId"]
            dst_controller_id = value["dstControllerId"]
        service_route_object = {}
        service_route_object["srcInterfaceId"] = src_port_id
        service_route_object["dstInterfaceId"] = dst_port_id
        service_route_object["controllerId"] = dst_controller_id
        service_route_list.append(service_route_object)
        route_info_object = {
            "serviceRoute" : service_route_list,
            "linkList" : link_list
            }
        solution = {
            "routeInfo" : route_info_object
            }
        return solution


    def get_ordered_route_list(self, link_list, src_controller_id, dst_controller_id):
        """
        :param link_list: link list from the minizinc response
        :param src_controller_id: source port id of route
        :param dst_controller_id: destination port id of route
        :return: route list in order
        """
        ordered_link_list = []
        flag = True
        while flag:
            for item in link_list:
                if item["srcControllerId"] == src_controller_id:
                    ordered_link_list.append(item)
                    src_controller_id = item["dstControllerId"]
                    if src_controller_id == dst_controller_id:
                        flag = False
        return ordered_link_list


    def find_suitable_path(self, mzn_model, dzn_data, mapping_table):
        """
        :param mzn_model: minizinc model details
        :param dzn_data: minizinc data
        :param mapping_table: list that maintains AAI link details
        :return: list of link from after running minizinc
        """
        minizinc_solution = self.solve(mzn_model, dzn_data)
        audit_log.info("Minizinc Solution ==========>")
        routes = list(minizinc_solution)
        audit_log.info(routes)
        try:
            arr = routes[0]['x']
        except Exception as err:
            audit_log.info("No minizinc solutions found")
            raise err
        links_list = []
        for i in range(0, len(routes[0]['x'])):
            if arr[i] == 1:
                links_list.append(mapping_table[i])
        return links_list


    def process_inter_domain_link(self, logical_link, osdf_config):
        """
        :param logical_link: logical links from AAI
        :param osdf_config: OSDF config details
        :return: list of link object with src and dst controller details
        """
        link_details = {}
        link_details["linkName"] = logical_link["link-name"]
        relationship = logical_link["relationship-list"]["relationship"]
        flag = 1

        for value in relationship:
            if value["related-to"] == "p-interface" and flag == 1:
                src_port_id = value["relationship-data"][1]["relationship-value"]
                src_controller_id = self.get_controller_for_interface(osdf_config, src_port_id)
                link_details["srcPortId"] = src_port_id
                link_details["srcControllerId"] = src_controller_id
                flag += 1
            elif value["related-to"] == "p-interface" and flag == 2:
                dest_port_id = value["relationship-data"][1]["relationship-value"]
                dest_controller_id = self.get_controller_for_interface(osdf_config, dest_port_id)
                link_details["dstPortId"] = dest_port_id
                link_details["dstControllerId"] = dest_controller_id
        return link_details


    def prepare_map_table(self, osdf_config, logical_links):
        """
        :param logical_links: logical links from AAI
        :param osdf_config: OSDF config details
        :return: list of link object with src and dst controller details
        """
        results = map(self.process_inter_domain_link, logical_links,
                      itertools.repeat(osdf_config, len(logical_links)))
        new_results = list(results)

        new_list = []
        new_list += new_results
        for i in new_results:
            link_details = {}
            link_details["linkName"] = i["linkName"]
            link_details["srcPortId"] = i["dstPortId"]
            link_details["srcControllerId"] = i["dstControllerId"]
            link_details["dstPortId"] = i["srcPortId"]
            link_details["dstControllerId"] = i["srcControllerId"]
            new_list.append(link_details)
        return new_list


    def solve(self, mzn_model, dzn_data):
        """
        :param mzn_model: minizinc template
        :param dzn_data: minizinc data model
        :return: minizinc response
        """
        return pymzn.minizinc(mzn=mzn_model, data=dzn_data)


    def get_links_based_on_bandwidth_attributes(self, logical_links_list,
                                                osdf_config, service_rate):
        """
        This method filters the logical links based on the
        bandwidth attribute availability of the interfaces
        from AAI
        :return: filtered_list[]
        """
        filtered_list = []
        for logical_link in logical_links_list:
            relationship = logical_link["relationship-list"]["relationship"]
            count = 0
            for value in relationship:
                if value["related-to"] == "p-interface":
                    interface_url = value["related-link"]
                    if self.get_available_bandwidth_aai(interface_url, osdf_config, service_rate):
                        count += 1
            if count == 2:
                filtered_list.append(logical_link)

        return  filtered_list


    def build_dzn_data(self, osdf_config, src_controller_id, dst_controller_id, service_rate):
        """
        :param osdf_config: OSDF config details
        :param src_controller_id: controller Id of the source port
        :param dst_controller_id: controller id of the destination port
        :param service_rate: service rate
        :return: mapping atble which maintains link details from AAI
        and minizinc data model to be used by template
        """
        logical_links = self.get_inter_domain_links(osdf_config)
        logical_links_list = logical_links["logical-link"]
        mapping_table = self.prepare_map_table(osdf_config,
                                               self.get_links_based_on_bandwidth_attributes(logical_links_list, osdf_config, service_rate))

        edge_start = []
        edge_end = []
        for item in mapping_table:
            edge_start.append(item["srcControllerId"])
            edge_end.append(item["dstControllerId"])
        link_cost = []
        for k in range(0, len(edge_start)):
            link_cost.append(1)
        list_controllers = self.get_controllers_from_aai(osdf_config)
        le = preprocessing.LabelEncoder()
        le.fit(list_controllers)

        start_edge = le.transform(edge_start)
        end_edge = le.transform(edge_end)
        source = le.transform([src_controller_id])
        destination = le.transform([dst_controller_id])

        final_dzn_start_arr = []
        for i in start_edge:
            final_dzn_start_arr.append(i)

        final_dzn_end_arr = []
        for j in end_edge:
            final_dzn_end_arr.append(j)

        contollers_length = len(list_controllers)
        no_of_edges = len(final_dzn_start_arr)
        dzn_data = {
            'N': contollers_length,
            'M': no_of_edges,
            'Edge_Start': final_dzn_start_arr,
            'Edge_End': final_dzn_end_arr,
            'L': link_cost,
            'Start': source[0],
            'End' : destination[0]
            }
        return dzn_data, mapping_table


    def get_inter_domain_links(self, osdf_config):
        """
        This method returns list of all cross ONAP links
        from /aai/v19/network/logical-links?link-type=inter-domain&operational-status="Up"
        :return: logical-links[]
        """

        config = osdf_config.deployment
        aai_url = config["aaiUrl"]
        aai_req_url = aai_url + config["aaiGetInterDomainLinksUrl"]
        response = requests.get(aai_req_url, headers=self.aai_headers,
                                auth=HTTPBasicAuth("AAI", "AAI"), verify=False)
        if response.status_code == 200:
            return response.json()


    def get_controller_for_interface(self, osdf_config, port_id):
        """
        This method returns returns the controller id
        given a p-interface from the below query
        :return: controller_id
        """
        data = {
            "start": ["external-system"],
            "query": "query/getDomainController?portid="
        }
        query = data.get("query") + port_id
        data.update(query=query)
        config = osdf_config.deployment
        aai_url = config["aaiUrl"]
        aai_req_url = aai_url + config["controllerQueryUrl"]
        response = requests.put(aai_req_url, data=json.dumps(data),
                                headers=self.aai_headers,
                                auth=HTTPBasicAuth("AAI", "AAI"),
                                verify=False)
        if response.status_code == 200:
            response_body = response.json()
            return response_body["results"][0]["esr-thirdparty-sdnc"]["thirdparty-sdnc-id"]


    def get_controllers_from_aai(self, osdf_config):
        """
        This method returns returns the list of
        controller names in AAI
        :return: controllers_list[]
        """
        controllers_list = []
        config = osdf_config.deployment
        aai_url = config["aaiUrl"]
        aai_req_url = aai_url + config["aaiGetControllersUrl"]
        response = requests.get(aai_req_url,
                                headers=self.aai_headers,
                                auth=HTTPBasicAuth("AAI", "AAI"),
                                verify=False)
        if response.status_code == 200:
            response_body = response.json()
            esr_thirdparty_list = response_body["esr-thirdparty-sdnc"]

            for item in esr_thirdparty_list:
                controllers_list.append(item["thirdparty-sdnc-id"])
            return controllers_list


    def get_available_bandwidth_aai(self, interface_url, osdf_config, service_rate):
        """
        Checks if the given interface has the required bandwidth
        :return: boolean flag
        """
        config = osdf_config.deployment
        aai_url = config["aaiUrl"]
        aai_req_url = aai_url + interface_url + "?depth=all"
        response = requests.get(aai_req_url,
                                headers=self.aai_headers,
                                auth=HTTPBasicAuth("AAI", "AAI"), verify=False)
        if response.status_code == 200:
            response_body = response.json()
            available_bandwidth = response_body["bandwidth-attributes"]["bandwidth-attribute"][0]["available-bandwidth-map"]["available-bandwidth"]
            for i in available_bandwidth:
                if i["odu-type"] == service_rate and i["number"] > 0:
                    return True
# ------------------------------------------------------------------------- #   Copyright (c) 2020 Fujitsu Limited Intellectual Property # #   Licensed under the Apache License, Version 2.0 (the "License"); #   you may not use this file except in compliance with the License. #   You may obtain a copy of the License at # #       http://www.apache.org/licenses/LICENSE-2.0 # #   Unless required by applicable law or agreed to in writing, software #   distributed under the License is distributed on an "AS IS" BASIS, #   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. #   See the License for the specific language governing permissions and #   limitations under the License. # # ------------------------------------------------------------------------- This values will need to deleted..     only added for the debug purpose This method processes the mdons route request         and returns an optimised path for the given         two ports :param ordered_list: service_route list         :param src_port_id: source port id of route         :param dst_port_id: destination port id of route         :return: solution object of the route respone :param link_list: link list from the minizinc response         :param src_controller_id: source port id of route         :param dst_controller_id: destination port id of route         :return: route list in order :param mzn_model: minizinc model details         :param dzn_data: minizinc data         :param mapping_table: list that maintains AAI link details         :return: list of link from after running minizinc :param logical_link: logical links from AAI         :param osdf_config: OSDF config details         :return: list of link object with src and dst controller details :param logical_links: logical links from AAI         :param osdf_config: OSDF config details         :return: list of link object with src and dst controller details :param mzn_model: minizinc template         :param dzn_data: minizinc data model         :return: minizinc response This method filters the logical links based on the         bandwidth attribute availability of the interfaces         from AAI         :return: filtered_list[] :param osdf_config: OSDF config details         :param src_controller_id: controller Id of the source port         :param dst_controller_id: controller id of the destination port         :param service_rate: service rate         :return: mapping atble which maintains link details from AAI         and minizinc data model to be used by template This method returns list of all cross ONAP links         from /aai/v19/network/logical-links?link-type=inter-domain&operational-status="Up"         :return: logical-links[] This method returns returns the controller id         given a p-interface from the below query         :return: controller_id This method returns returns the list of         controller names in AAI         :return: controllers_list[] Checks if the given interface has the required bandwidth         :return: boolean flag