Skip to content
Snippets Groups Projects
RSA.py 52.7 KiB
Newer Older
# Copyright 2022-2024 ETSI SDG TeraFlowSDN (TFS) (https://tfs.etsi.org/)
Lluis Gifre Renom's avatar
Lluis Gifre Renom committed
#
# 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.

Lluis Gifre Renom's avatar
Lluis Gifre Renom committed
import logging
from opticalcontroller.dijkstra import Graph, shortest_path
from opticalcontroller.tools import *
from opticalcontroller.variables import *
Lluis Gifre Renom's avatar
Lluis Gifre Renom committed
LOGGER = logging.getLogger(__name__)

def print(*args) -> None:
    LOGGER.info(' '.join([str(a) for a in args]))

class RSA():
    def __init__(self, nodes, links):
        self.nodes_dict = nodes
        self.links_dict = links
        self.g = None

        self.flow_id = 0
        self.opt_band_id = 0
        self.db_flows = {}
        self.initGraph2()
        self.c_slot_number = 0
        self.l_slot_number = 0
        self.s_slot_number = 0
        self.optical_bands = {}
    def init_link_slots(self):
            for l in self.links_dict["optical_links"]:
                for fib in l["optical_link"]["details"]["fibers"]:
                    #fib = self.links_dict[l]["fibers"][f]
                    if len(fib["c_slots"]) > 0:
                        fib["c_slots"] = list(range(0, Nc))
                    if len(fib["l_slots"]) > 0:
                        fib["l_slots"] = list(range(0, Nl))
                    if len(fib["s_slots"]) > 0:
                        fib["s_slots"] = list(range(0, Ns))
                    if debug:
                        print(fib)
        for l1 in self.links_dict["optical_links"]:

            for fib1 in l1["optical_link"]["details"]["fibers"]:
                #fib1 = self.links_dict[l1]["details"]["fibers"][f1]

                self.c_slot_number = len(fib1["c_slots"])
                self.l_slot_number = len(fib1["l_slots"])
                self.s_slot_number = len(fib1["s_slots"])

                break
            break
        return "{},{},{}".format(self.c_slot_number, self.l_slot_number, self.s_slot_number)

    def init_link_slots2(self):
            for l in self.links_dict["optical_links"]:
                fib = l["optical_details"]
                #fib = self.links_dict[l]["fibers"][f]
                if len(fib["c_slots"]) > 0:
                    for c in range(0, Nc):
                        fib["c_slots"][c] = 1
                if len(fib["l_slots"]) > 0:
                    for c in range(0, Nl):
                        fib["l_slots"][c] = 1
                if len(fib["s_slots"]) > 0:
                    for c in range(0, Ns):
                        fib["s_slots"][c] = 1
                if debug:
                    print(fib)
        for l1 in self.links_dict["optical_links"]:
            fib1 = l1["optical_details"]
            self.c_slot_number = len(fib1["c_slots"].keys())
            self.l_slot_number = len(fib1["l_slots"].keys())
            self.s_slot_number = len(fib1["s_slots"].keys())
            break
        return "{},{},{}".format(self.c_slot_number, self.l_slot_number, self.s_slot_number)

    def initGraph(self):
        self.g = Graph()
        for n in self.nodes_dict:
            self.g.add_vertex(n)
        for l in self.links_dict["optical_links"]:
            if debug:
                print(l)
            [s, d] = l["optical_link"]["name"].split('-')
            ps = l["optical_link"]["details"]["source"]
            pd = l["optical_link"]["details"]["target"]
            self.g.add_edge(s, d, ps, pd, 1)

        print("INFO: Graph initiated.")
        if debug:
            self.g.printGraph()

    def initGraph2(self):
        self.g = Graph()
        for n in self.nodes_dict:
            self.g.add_vertex(n)
        for l in self.links_dict["optical_links"]:
            if debug:
                print(l)
            [s, d] = l["name"].split('-')
            ps = l["optical_details"]["src_port"]
            pd = l["optical_details"]["dst_port"]
            self.g.add_edge(s, d, ps, pd, 1)

        print("INFO: Graph initiated.2")
        if debug:
            self.g.printGraph()

    def compute_path(self, src, dst):
        path = shortest_path(self.g, self.g.get_vertex(src), self.g.get_vertex(dst))
        print("INFO: Path from {} to {} with distance: {}".format(src, dst, self.g.get_vertex(dst).get_distance()))
        if debug:
            print(path)
        links = []
        for i in range(0, len(path) - 1):
            s = path[i]
            if debug:
                print(s)
            if i < len(path) - 1:
                d = path[i + 1]
                link_id = "{}-{}".format(s, d)
                if debug:
                    #print(link_id, self.links_dict[link_id])
                    print(link_id, self.get_link_by_name(link_id))

                links.append(link_id)
        self.g.reset_graph()
        return links, path

    def get_slots(self, links, slots, optical_band_id=None):

        if isinstance(slots, int):
            val_c = slots
            val_s = slots
            val_l = slots
        else:
            val_c = self.c_slot_number
            val_l = self.l_slot_number
            val_s = self.s_slot_number

        c_sts = []
        l_sts = []
        s_sts = []
        c_slots = {}
        l_slots = {}
        s_slots = {}
        add = ""
        drop = ""
        src_1, dst_1 = links[0].split('-')
        src_2, dst_2 = links[-1].split('-')
        if self.nodes_dict[src_1]["type"] == "OC-TP":
            add = links[0]
        if self.nodes_dict[dst_2]["type"] == "OC-TP":
            drop = links[-1]
        found = 0
        for l in links:
            c_slots[l] = []
            l_slots[l] = []
            s_slots[l] = []

            link = self.get_link_by_name(l)
            fib = link["optical_details"]
            if l == add:
                if 'used' in fib:
                    if fib["used"]:
                        #if debug:
                        print("WARNING!!!: link {}, is already in use".format(l))
                        return [], [], []
            if l == drop:
                if 'used' in fib:
                    if fib["used"]:
                        #if debug:
                        print("WARNING!!!: link {} is already in use".format(l))
                        return [], [], []
            c_found = l_found = s_found = 0
            if len(fib["c_slots"].keys()) > 0:
                #c_slots[l] = combine(c_slots[l], consecutives(fib["c_slots"], val_c))
                c_slots[l] = combine(c_slots[l], consecutives(fib["c_slots"], val_c))
                c_found = 1
            if len(fib["l_slots"].keys()) > 0:
                l_slots[l] = combine(l_slots[l], consecutives(fib["l_slots"], val_l))
                l_found = 1
            if len(fib["s_slots"].keys()) > 0:
                s_slots[l] = combine(s_slots[l], consecutives(fib["s_slots"], val_s))
                s_found = 1
Mohammad Ismaeel's avatar
Mohammad Ismaeel committed
            if debug:
                print(l, c_slots[l])
            if c_found == 0 and l_found == 0 and s_found == 0:
                return [], [], []

        keys = list(c_slots.keys())
        if debug:
            print(len(keys))
        if debug:
            print(keys[0])
        # intersection among the slots over all links
        if len(keys) == 1:
            c_sts = c_slots[keys[0]]
            l_sts = l_slots[keys[0]]
            s_sts = s_slots[keys[0]]
        else:
            for i in range(1, len(keys)):
                if debug:
                    print(keys[i])
                # set a for the intersection
                if i == 1:
                    a_c = c_slots[keys[i - 1]]
                    a_l = l_slots[keys[i - 1]]
                    a_s = s_slots[keys[i - 1]]
                else:
                    a_c = c_sts
                    a_l = l_sts
                    a_s = s_sts
                # set b for the intersection
                b_c = c_slots[keys[i]]
                b_l = l_slots[keys[i]]
                b_s = s_slots[keys[i]]

                c_sts = common_slots(a_c, b_c)
                l_sts = common_slots(a_l, b_l)
                s_sts = common_slots(a_s, b_s)
Mohammad Ismaeel's avatar
Mohammad Ismaeel committed
                '''
             if len(fib["l_slots"]) > 0:
                l_slots[l] = combine(l_slots[l], consecutives(fib["l_slots"], val_l))
                l_found = 1'''
        if optical_band_id is not None:
            if "c_slots" in self.optical_bands[optical_band_id].keys():
                if len(self.optical_bands[optical_band_id]["c_slots"]) > 0:
                    a_c = c_sts
Mohammad Ismaeel's avatar
Mohammad Ismaeel committed
                    #MOD
                    b_c = consecutives(self.optical_bands[optical_band_id]["c_slots"], val_c)
                    #b_c = self.optical_bands[optical_band_id]["c_slots"]
                    c_sts = common_slots(a_c, b_c)
            else:
                c_sts = []
            if "l_slots" in self.optical_bands[optical_band_id].keys():
                if len(self.optical_bands[optical_band_id]["l_slots"]) > 0:
                    a_l = l_sts
Mohammad Ismaeel's avatar
Mohammad Ismaeel committed
                    b_l = consecutives(self.optical_bands[optical_band_id]["l_slots"], val_c)
                    l_sts = common_slots(a_l, b_l)
            else:
                l_sts = []
            if "s_slots" in self.optical_bands[optical_band_id].keys():
                if len(self.optical_bands[optical_band_id]["s_slots"]) > 0:
                    a_s = s_sts
Mohammad Ismaeel's avatar
Mohammad Ismaeel committed
                    b_s = consecutives(str_list_to_int(self.optical_bands[optical_band_id]["s_slots"].keys()), val_c)
                    s_sts = common_slots(a_s, b_s)
            else:
                s_sts = []

        return c_sts, l_sts, s_sts

    def update_link(self, fib, slots, band):
        for i in slots:
Mohammad Ismaeel's avatar
Mohammad Ismaeel committed
            fib[band][str(i)] = 0
        if 'used' in fib:
            fib['used'] = True
        print(f"fib updated {fib}")

    def update_optical_band(self, optical_band_id, slots, band):
        for i in slots:
Mohammad Ismaeel's avatar
Mohammad Ismaeel committed
            self.optical_bands[optical_band_id][band][str(i)] = 0
    def augment_optical_band(self, optical_band_id, slots, band):
        for i in slots:
            self.optical_bands[optical_band_id][band][str(i)] = 1

    def restore_link(self, fib, slots, band):
        for i in slots:
Mohammad Ismaeel's avatar
Mohammad Ismaeel committed
            fib[band][str(i)] = 1
        if 'used' in fib:
            fib['used'] = False

    def restore_optical_band(self, optical_band_id, slots, band):
        for i in slots:
Mohammad Ismaeel's avatar
Mohammad Ismaeel committed
            self.optical_bands[optical_band_id][band][str(i)] = 1
            #self.optical_bands[optical_band_id][band].append(int(i))
        #self.optical_bands[optical_band_id][band].sort()
    def restore_optical_band_2(self, optical_band_id, slots, band ,links):
        print(f"example of  band { band}")
        print(f"example of slots {slots}")
        print(f"example of self.optical_bands_before { self.optical_bands}")
        for i in slots:
            self.optical_bands[optical_band_id][band][str(i)] = 1
        print(f"example of self.optical_bands_after { self.optical_bands}")

        #link_name=    self.optical_bands[optical_band_id]['links'][0] 
        #link = self.get_link_by_name(link_name)    
        #update_optical_band(optical_bands=self.optical_bands,optical_band_id=optical_band_id,band=band,link=link)
Mohammad Ismaeel's avatar
Mohammad Ismaeel committed
    def del_flow(self, flow,flow_id, o_b_id = None):
        flows = flow["flows"]
        band = flow["band_type"]
        slots = flow["slots"]
        fiber_f = flow["fiber_forward"]
        fiber_b = flow["fiber_backward"]
        op = flow["op-mode"]
        n_slots = flow["n_slots"]
        path = flow["path"]
        links = flow["links"]
        bidir = flow["bidir"]
Andrea Sgambelluri's avatar
Andrea Sgambelluri committed
        flow_id = flow["flow_id"]

Mohammad Ismaeel's avatar
Mohammad Ismaeel committed
        for l in links:
            if debug:
                print(l)
            #link = self.links_dict[l]
            #f = fiber_f[l]
            #fib = link['fibers'][f]
Mohammad Ismaeel's avatar
Mohammad Ismaeel committed
            fib = self.get_link_by_name(l)["optical_details"]
            self.restore_link(fib, slots, band)
            if debug:
                print(fib[band])
        if o_b_id is not None:
Mohammad Ismaeel's avatar
Mohammad Ismaeel committed
            if debug:
                print("restoring OB")
            print(f"invoking restore_optical_band o_b_id: {o_b_id} , slots {slots} , band {band} ")    
            self.restore_optical_band(o_b_id, slots, band)
Andrea Sgambelluri's avatar
Andrea Sgambelluri committed
            if flow_id in self.optical_bands[o_b_id]["served_lightpaths"]:
                if flow_id in self.optical_bands[o_b_id]["served_lightpaths"]:
                    self.optical_bands[o_b_id]["served_lightpaths"].remove(flow_id)

            #self.restore_optical_band_2(o_b_id, slots, band,links)
        if bidir:
Mohammad Ismaeel's avatar
Mohammad Ismaeel committed
            for l in links:
                r_l = reverse_link(l)
                if debug:
                    print(r_l)
                # link = self.links_dict[l]
                # f = fiber_f[l]
                # fib = link['fibers'][f]
                fib = self.get_link_by_name(r_l)["optical_details"]
                if list_in_list(slots, str_list_to_int(fib[band].keys())):
                    self.restore_link(fib, slots, band)
Mohammad Ismaeel's avatar
Mohammad Ismaeel committed
                    if debug:
                        print(fib[band])
            '''
            for rl in fiber_b.keys():
                if debug:
                    print(rl)
                    print(fiber_b[rl])
                #rlink = self.links_dict[rl]
                #rf = fiber_b[rl]
                #rfib = rlink['fibers'][rf]
                rfib = self.get_fiber_details(rl, fiber_b[rl])
                if not list_in_list(slots, rfib[band]):
                    self.restore_link(rfib, slots, band)
                    if debug:
                        print(rfib[band])
Mohammad Ismaeel's avatar
Mohammad Ismaeel committed
            '''
            #changed according to TFS development
            #if o_b_id is not None:
            #    rev_o_band_id = self.optical_bands[o_b_id]["reverse_optical_band_id"]
            #    self.restore_optical_band(rev_o_band_id, slots, band)
        return True
Mohammad Ismaeel's avatar
Mohammad Ismaeel committed
    def del_band(self, flow, o_b_id = None):
        print(f"delete band {flow} ")
        flows = flow["flows"]
        band = None
Mohammad Ismaeel's avatar
Mohammad Ismaeel committed
        #slots = flow["slots"]
        fiber_f = flow["fiber_forward"]
        fiber_b = flow["fiber_backward"]
        op = flow["op-mode"]
        n_slots = 0
        path = flow["path"]
        bidir = flow["bidir"]
        links =  []
        if o_b_id is not None:
           links= self.optical_bands[o_b_id]["links"]
           band = self.optical_bands[o_b_id]["band_type"]
           n_slots =self.optical_bands[o_b_id]["n_slots"]
           if n_slots > 0: 
               slots=[i+1 for i in range(n_slots)]
       
        for l in links:
            if debug:
                print(l)
            #link = self.links_dict[l]
            #f = fiber_f[l]
            #fib = link['fibers'][f]
            fib = self.get_link_by_name(l)["optical_details"]
            print(f"del_flow_fib {fib } and band {band}")
            print(f"del_flow { str_list_to_int(fib[band].keys())}")
          
            print(f"invoking restore_link fib: {fib} , slots {slots} , band {band} ")
            self.restore_link(fib, slots, band)
            self.optical_bands[o_b_id]["is_active"]=False
Mohammad Ismaeel's avatar
Mohammad Ismaeel committed
           
            if debug:
                print(fib[band])
            
        if o_b_id is not None:
            
            if debug:
                print("restoring OB")
            print(f"invoking restore_optical_band o_b_id: {o_b_id} , slots {slots} , band {band} ")    
            self.restore_optical_band(o_b_id, slots, band)
            #self.restore_optical_band_2(o_b_id, slots, band,links)
        if bidir:
            for l in links:
                r_l = reverse_link(l)
                if debug:
                    print(r_l)
                # link = self.links_dict[l]
                # f = fiber_f[l]
                # fib = link['fibers'][f]
                fib = self.get_link_by_name(r_l)["optical_details"]
                if list_in_list(slots, str_list_to_int(fib[band].keys())):
                    self.restore_link(fib, slots, band)
                    if debug:
                        print(fib[band])
            '''
            for rl in fiber_b.keys():
                if debug:
                    print(rl)
                    print(fiber_b[rl])
                #rlink = self.links_dict[rl]
                #rf = fiber_b[rl]
                #rfib = rlink['fibers'][rf]
                rfib = self.get_fiber_details(rl, fiber_b[rl])
                if not list_in_list(slots, rfib[band]):
                    self.restore_link(rfib, slots, band)
                    if debug:
                        print(rfib[band])
            '''
            #changed according to TFS development
            #if o_b_id is not None:
            #    rev_o_band_id = self.optical_bands[o_b_id]["reverse_optical_band_id"]
            #    self.restore_optical_band(rev_o_band_id, slots, band)
        return True
Mohammad Ismaeel's avatar
Mohammad Ismaeel committed
    def del_handler(self, flow,flow_id, o_b_id = None,delete_band=0):
        print(f" del_handler flow {flow} flow_id {flow_id}  o_b_id {o_b_id} delete_band {delete_band}")
Mohammad Ismaeel's avatar
Mohammad Ismaeel committed
        if delete_band != 0:
            print(f"delete band del_band")
            self.del_band(flow,flow_id,o_b_id=o_b_id)
        else :
Mohammad Ismaeel's avatar
Mohammad Ismaeel committed
            self.del_flow(flow,flow_id=flow_id,o_b_id=o_b_id)   
    def get_fibers_forward(self, links, slots, band):
        fiber_list = {}
        add = links[0]
        drop = links[-1]
Mohammad Ismaeel's avatar
Mohammad Ismaeel committed
        #print(links)
        '''
        for link in self.links_dict["links"]:
            if link["optical_link"]["name"] == l:
                # for f in self.links_dict[l]['fibers'].keys():
                for fib in link["optical_link"]["details"]["fibers"]:

        '''
        for l in links:
Mohammad Ismaeel's avatar
Mohammad Ismaeel committed
            for link in self.links_dict["optical_links"]:
                print(f"tracking link info {link}")    
Mohammad Ismaeel's avatar
Mohammad Ismaeel committed
                if link["name"] == l:
                    fib = link["optical_details"]
                    #for f in self.links_dict[l]['fibers'].keys():
                    #for fib in l["optical_link"]["details"]["fibers"]:
                    #fib = self.links_dict[l]['fibers'][f]
                    if l == add:
                        if 'used' in fib:
                            if fib["used"]:
                                if debug:
                                    print("link {} is already in use".format(l))
                                continue
                    if l == drop:
                        if 'used' in fib:
                            if fib["used"]:
                                if debug:
                                    print("link {} is already in use".format(l))
                                continue
                    if list_in_list(slots, str_list_to_int(fib[band].keys())):
                        #fiber_list[l] = fib["ID"]
                        self.update_link(fib, slots, band)
Mohammad Ismaeel's avatar
Mohammad Ismaeel committed
                        break
        print("INFO: Path forward computation completed")
        return fiber_list

    def get_link_by_name (self, key):
Mohammad Ismaeel's avatar
Mohammad Ismaeel committed
        for link in self.links_dict["optical_links"]:
            if link["name"] == key:
                if debug:
                    print(link)
                break
Mohammad Ismaeel's avatar
Mohammad Ismaeel committed
        return link

    def get_fiber_details(self, link_key, fiber_id):
Mohammad Ismaeel's avatar
Mohammad Ismaeel committed
        for link in self.links_dict["optical_links"]:
            if link["name"] == link_key:
                if debug:
                    print(link)
Mohammad Ismaeel's avatar
Mohammad Ismaeel committed
                for fib in link["optical_details"]:
                    if fib["ID"] == fiber_id:
                        return fib
        return None

Mohammad Ismaeel's avatar
Mohammad Ismaeel committed
    def get_fibers_backward(self, links, slots, band):
        fiber_list = {}
        #r_drop = reverse_link(links[0])
        #r_add = reverse_link(links[-1])
Mohammad Ismaeel's avatar
Mohammad Ismaeel committed
        for l in links:
            fib = self.get_link_by_name(l)["optical_details"]
            '''
            link = self.get_link_by_name(l)
            #port = self.links_dict[l]["fibers"][fibers[l]]["src_port"]
            for fib in link["optical_link"]["details"]["fibers"]:
                if fib["ID"] == fibers[l]:
            '''
Mohammad Ismaeel's avatar
Mohammad Ismaeel committed
            s_port = fib["src_port"]
            d_port = fib["dst_port"]

            if debug:
                print(l, s_port, d_port)

            r_l = reverse_link(l)
            r_link = self.get_link_by_name(r_l)
Mohammad Ismaeel's avatar
Mohammad Ismaeel committed
            if debug:
                print(r_l)

            #for f in r_link["fibers"].keys():
Mohammad Ismaeel's avatar
Mohammad Ismaeel committed
            r_fib = r_link["optical_details"]
            if r_fib["remote_peer_port"] == s_port and r_fib["local_peer_port"] == d_port:
                if list_in_list(slots, str_list_to_int(r_fib[band].keys())):
                    #fiber_list[r_l] = r_fib["ID"]
                    self.update_link(r_fib, slots, band)
        print("INFO: Path backward computation completed")
        return fiber_list

Mohammad Ismaeel's avatar
Mohammad Ismaeel committed
    #function invoked for lightpaths and OB
    def select_slots_and_ports(self, links, n_slots, c, l, s, bidir):
        if debug:
            print (links, n_slots, c, l, s, bidir, self.c_slot_number, self.l_slot_number, self.s_slot_number)
        band, slots = slot_selection(c, l, s, n_slots, self.c_slot_number, self.l_slot_number, self.s_slot_number)
Mohammad Ismaeel's avatar
Mohammad Ismaeel committed
        if debug:
            print (band, slots)
        if band is None:
            print("No slots available in the three bands")
Mohammad Ismaeel's avatar
Mohammad Ismaeel committed
            #return None, None, None, {}, {}
            return None, None, None, {}, {}
Mohammad Ismaeel's avatar
Mohammad Ismaeel committed
        self.get_fibers_forward(links, slots, band)
        if bidir:
            self.get_fibers_backward(links, slots, band)
        '''
        fibers_f = self.get_fibers_forward(links, slots, band)

        fibers_b = []
        if bidir:
            fibers_b = self.get_fibers_backward(links, fibers_f, slots, band)
        if debug:
            print("forward")
            print(fibers_f)
            print("backward")
            print(fibers_b)
Mohammad Ismaeel's avatar
Mohammad Ismaeel committed
        '''
        add = links[0]
        drop = links[-1]
        inport = "0"
        outport = "0"
        r_inport = "0"
        r_outport = "0"
        t_flows = {}
        #if len(links) == 1:

Mohammad Ismaeel's avatar
Mohammad Ismaeel committed
        for llx in links:
            if llx == add:
                inport = "0"
                r_outport = "0"
Mohammad Ismaeel's avatar
Mohammad Ismaeel committed
            if llx == drop:
                outport = "0"
                r_inport = "0"
Mohammad Ismaeel's avatar
Mohammad Ismaeel committed
            '''
            f = fibers_f[lx]
            fibx = self.get_fiber_details(lx, f)
Mohammad Ismaeel's avatar
Mohammad Ismaeel committed
            '''
            src, dst = llx.split("-")
            #outport = self.links_dict[lx]['fibers'][f]["src_port"]
Mohammad Ismaeel's avatar
Mohammad Ismaeel committed
            lx = self.get_link_by_name(llx)["optical_details"]
            outport = lx["src_port"]

            t_flows[src] = {}
            t_flows[src]["f"] = {}
            t_flows[src]["b"] = {}
            t_flows[src]["f"] = {"in": inport, "out": outport}

            if bidir:
                #r_inport = self.links_dict[lx]['fibers'][f]["local_peer_port"]
Mohammad Ismaeel's avatar
Mohammad Ismaeel committed
                r_inport = lx["local_peer_port"]
                t_flows[src]["b"] = {"in": r_inport, "out": r_outport}

            #inport = self.links_dict[lx]['fibers'][f]["dst_port"]
Mohammad Ismaeel's avatar
Mohammad Ismaeel committed
            inport = lx["dst_port"]
            if bidir:
                #r_outport = self.links_dict[lx]['fibers'][f]["remote_peer_port"]
Mohammad Ismaeel's avatar
Mohammad Ismaeel committed
                r_outport = lx["remote_peer_port"]
            t_flows[dst] = {}
            t_flows[dst]["f"] = {}
            t_flows[dst]["b"] = {}
            t_flows[dst]["f"] = {"in": inport, "out": "0"}
            if bidir:
                t_flows[dst]["b"] = {"in": "0", "out": r_outport}

        if debug:
            print(self.links_dict)

        if debug:
            print(t_flows)
        print("INFO: Flow matrix computed")

Mohammad Ismaeel's avatar
Mohammad Ismaeel committed
        return t_flows, band, slots, {}, {}
Mohammad Ismaeel's avatar
Mohammad Ismaeel committed
    #function ivoked for fs lightpaths only
    def select_slots_and_ports_fs(self, links, n_slots, c, l, s, bidir, o_band_id):
        if debug:
            print(self.links_dict)
        band, slots = slot_selection(c, l, s, n_slots, self.c_slot_number, self.l_slot_number, self.s_slot_number)
        if band is None:
            print("No slots available in the three bands")
            return None, None, None, None, None
        if debug:
            print(band, slots)
Mohammad Ismaeel's avatar
Mohammad Ismaeel committed
        self.get_fibers_forward(links, slots, band)
        if bidir:
Mohammad Ismaeel's avatar
Mohammad Ismaeel committed
            self.get_fibers_backward(links, slots, band)

        #fibers_f = self.get_fibers_forward(links, slots, band)
        self.update_optical_band(o_band_id, slots, band)
        #fibers_b = []
        #if bidir:
        #    fibers_b = self.get_fibers_backward(links, fibers_f, slots, band)
        '''

            rev_o_band_id = self.optical_bands[o_band_id]["reverse_optical_band_id"]
            self.update_optical_band(rev_o_band_id, slots, band)
        '''
        add = links[0]
        drop = links[-1]
        port_0 = "0"

        t_flows = {}

        #flows_add_side
        src, dst = add.split("-")
Mohammad Ismaeel's avatar
Mohammad Ismaeel committed
        lx = self.get_link_by_name(add)["optical_details"]
        #outport = self.links_dict[add]['fibers'][f]["src_port"]
Mohammad Ismaeel's avatar
Mohammad Ismaeel committed
        outport = lx["src_port"]
        #T1 rules
        t_flows[src] = {}
        t_flows[src]["f"] = {}
        t_flows[src]["b"] = {}
        t_flows[src]["f"] = {"in": port_0, "out": outport}
        if bidir:
            #r_inport = self.links_dict[add]['fibers'][f]["local_peer_port"]
Mohammad Ismaeel's avatar
Mohammad Ismaeel committed
            r_inport = lx["local_peer_port"]
            t_flows[src]["b"] = {"in": r_inport, "out": port_0}

        #R1 rules
        t_flows[dst] = {}
        t_flows[dst]["f"] = {}
        t_flows[dst]["b"] = {}
        #inport = self.links_dict[add]['fibers'][f]["dst_port"]
Mohammad Ismaeel's avatar
Mohammad Ismaeel committed
        inport = lx["dst_port"]
        opt_band_src_port = self.optical_bands[o_band_id]["src_port"]
        t_flows[dst]["f"] = {"in": inport, "out": opt_band_src_port}
        #to modify to peer ports
        if bidir:
            #r_inport = self.links_dict[add]['fibers'][f]["local_peer_port"]
Mohammad Ismaeel's avatar
Mohammad Ismaeel committed
            r_inport = lx["local_peer_port"]
            t_flows[src]["b"] = {"in": r_inport, "out": port_0}
        if bidir:
            rev_opt_band_dst_port = self.optical_bands[o_band_id]["rev_dst_port"]
            #r_outport = self.links_dict[add]['fibers'][f]["remote_peer_port"]
Mohammad Ismaeel's avatar
Mohammad Ismaeel committed
            r_outport = lx["remote_peer_port"]
            t_flows[dst]["b"] = {"in": rev_opt_band_dst_port, "out": r_outport}

        #flows_drop_side
        # R2 rules
Mohammad Ismaeel's avatar
Mohammad Ismaeel committed
        ly = self.get_link_by_name(drop)["optical_details"]
        src, dst = drop.split("-")
        #outport = self.links_dict[drop]['fibers'][f]["src_port"]
Mohammad Ismaeel's avatar
Mohammad Ismaeel committed
        outport = ly["src_port"]

        t_flows[src] = {}
        t_flows[src]["f"] = {}
        t_flows[src]["b"] = {}
        opt_band_dst_port = self.optical_bands[o_band_id]["dst_port"]
        t_flows[src]["f"] = {"in": opt_band_dst_port, "out": outport}
        if bidir:
            rev_opt_band_src_port = self.optical_bands[o_band_id]["rev_src_port"]
            #r_inport = self.links_dict[drop]['fibers'][f]["local_peer_port"]
Mohammad Ismaeel's avatar
Mohammad Ismaeel committed
            r_inport = ly["local_peer_port"]
            t_flows[src]["b"] = {"in": r_inport, "out": rev_opt_band_src_port}
        t_flows[dst] = {}
        t_flows[dst]["f"] = {}
        t_flows[dst]["b"] = {}
        #inport = self.links_dict[drop]['fibers'][f]["dst_port"]
Mohammad Ismaeel's avatar
Mohammad Ismaeel committed
        inport = ly["dst_port"]
        t_flows[dst]["f"] = {"in": inport, "out": port_0}
        if bidir:
            #r_inport = self.links_dict[drop]['fibers'][f]["remote_peer_port"]
Mohammad Ismaeel's avatar
Mohammad Ismaeel committed
            r_inport = ly["remote_peer_port"]
            t_flows[dst]["b"] = {"in": port_0, "out": r_inport}

        if debug:
            print(self.links_dict)

        if debug:
            print(t_flows)
        print("INFO: Flow matrix computed for Flex Lightpath")

Mohammad Ismaeel's avatar
Mohammad Ismaeel committed
        return t_flows, band, slots, {}, {}

    def rsa_computation(self, src, dst, rate, bidir):
        self.flow_id += 1
        self.db_flows[self.flow_id] = {}
        self.db_flows[self.flow_id]["flow_id"] = self.flow_id
        self.db_flows[self.flow_id]["src"] = src
        self.db_flows[self.flow_id]["dst"] = dst
        self.db_flows[self.flow_id]["bitrate"] = rate
        self.db_flows[self.flow_id]["bidir"] = bidir

        links, path = self.compute_path(src, dst)

        if len(path) < 1:
            self.null_values(self.flow_id)
            return self.flow_id
        op, num_slots = map_rate_to_slot(rate)
        c_slots, l_slots, s_slots = self.get_slots(links, num_slots)
        if debug:
            print(c_slots)
            print(l_slots)
            print(s_slots)
        if len(c_slots) > 0 or len(l_slots) > 0 or len(s_slots) > 0:
            flow_list, band_range, slots, fiber_f, fiber_b = self.select_slots_and_ports(links, num_slots, c_slots,
                                                                                         l_slots, s_slots, bidir)
            f0, band = frequency_converter(band_range, slots)
            if debug:
                print(f0, band)
            print("INFO: RSA completed for normal wavelenght connection")
            if flow_list is None:
                self.null_values(self.flow_id)
                return self.flow_id
            slots_i = []
            for i in slots:
                slots_i.append(int(i))
            # return links, path, flow_list, band_range, slots, fiber_f, fiber_b, op, num_slots, f0, band
            #        links, path, flows, bx, slots, fiber_f, fiber_b, op, n_slots, f0, band
            self.db_flows[self.flow_id]["flows"] = flow_list
            self.db_flows[self.flow_id]["band_type"] = band_range
            self.db_flows[self.flow_id]["slots"] = slots_i
            self.db_flows[self.flow_id]["fiber_forward"] = fiber_f
            self.db_flows[self.flow_id]["fiber_backward"] = fiber_b
            self.db_flows[self.flow_id]["op-mode"] = op
            self.db_flows[self.flow_id]["n_slots"] = num_slots
            self.db_flows[self.flow_id]["links"] = links
            self.db_flows[self.flow_id]["path"] = path
            self.db_flows[self.flow_id]["band"] = band
            self.db_flows[self.flow_id]["freq"] = f0
            self.db_flows[self.flow_id]["is_active"] = True
        return self.flow_id

    def null_values(self, flow_id):
        self.db_flows[flow_id]["flows"] = {}
        self.db_flows[flow_id]["band_type"] = ""
        self.db_flows[flow_id]["slots"] = []
        self.db_flows[flow_id]["fiber_forward"] = []
        self.db_flows[flow_id]["fiber_backward"] = []
        self.db_flows[flow_id]["op-mode"] = 0
        self.db_flows[flow_id]["n_slots"] = 0
        self.db_flows[flow_id]["links"] = {}
        self.db_flows[flow_id]["path"] = []
        self.db_flows[flow_id]["band"] = 0
        self.db_flows[flow_id]["freq"] = 0
        self.db_flows[flow_id]["is_active"] = False

    def null_values_ob(self, ob_id):
        self.optical_bands[ob_id]["flows"] = {}
        self.optical_bands[ob_id]["band_type"] = ""
        #self.optical_bands[ob_id]["slots"] = []
        self.optical_bands[ob_id]["fiber_forward"] = []
        self.optical_bands[ob_id]["n_slots"] = 0
        self.optical_bands[ob_id]["links"] = {}
        self.optical_bands[ob_id]["path"] = []
        self.optical_bands[ob_id]["band"] = 0
        self.optical_bands[ob_id]["freq"] = 0
        self.optical_bands[ob_id]["is_active"] = False
        self.optical_bands[ob_id]["c_slots"] = []
        self.optical_bands[ob_id]["l_slots"] = []
        self.optical_bands[ob_id]["s_slots"] = []
        self.optical_bands[ob_id]["served_lightpaths"] = []
        self.optical_bands[ob_id]["reverse_optical_band_id"] = 0
        self.db_flows[self.flow_id]["parent_opt_band"] = 0
        self.db_flows[self.flow_id]["new_optical_band"] = 0

    def create_optical_band(self, links, path, bidir, num_slots):
        print("INFO: Creating optical-band of {} slots".format(num_slots))
        self.opt_band_id += 1
        forw_opt_band_id = self.opt_band_id
        self.optical_bands[forw_opt_band_id] = {}
        self.optical_bands[forw_opt_band_id]["optical_band_id"] = forw_opt_band_id
        self.optical_bands[forw_opt_band_id]["bidir"] = bidir
        '''
        back_opt_band_id = 0
        if bidir:
            self.opt_band_id += 1
            back_opt_band_id = self.opt_band_id
            self.optical_bands[back_opt_band_id] = {}
            self.optical_bands[back_opt_band_id]["optical_band_id"] = back_opt_band_id
            self.optical_bands[back_opt_band_id]["bidir"] = bidir
            self.optical_bands[back_opt_band_id]["reverse_optical_band_id"] = forw_opt_band_id
            self.optical_bands[forw_opt_band_id]["reverse_optical_band_id"] = back_opt_band_id
        else:
            self.optical_bands[forw_opt_band_id]["reverse_optical_band_id"] = 0
        '''
        op = 0
        temp_links = []
        #num_slots = "all"
        if self.nodes_dict[path[0]]["type"] == "OC-TP":
            add_link = links[0]
            temp_links.append(add_link)
            links.remove(add_link)
            path.remove(path[0])
        self.optical_bands[forw_opt_band_id]["src"] = path[0]
        '''
        if bidir:
            self.optical_bands[back_opt_band_id]["dst"] = path[0]
        '''
        if self.nodes_dict[path[-1]]["type"] == "OC-TP":
            drop_link = links[-1]
            temp_links.append(drop_link)
            links.remove(drop_link)
            path.remove(path[-1])
        self.optical_bands[forw_opt_band_id]["dst"] = path[-1]
        '''
        if bidir:
            self.optical_bands[back_opt_band_id]["src"] = path[-1]
        '''

        c_slots, l_slots, s_slots = self.get_slots(links, num_slots)
        if debug:
            print(c_slots)
            print(l_slots)
            print(s_slots)
        if len(c_slots) > 0 or len(l_slots) > 0 or len(s_slots) > 0:
            flow_list, band_range, slots, fiber_f, fiber_b = self.select_slots_and_ports(links, num_slots, c_slots, l_slots, s_slots, bidir)
Mohammad Ismaeel's avatar
Mohammad Ismaeel committed
            if debug:
                print(flow_list, band_range, slots, fiber_f, fiber_b)
            f0, band = frequency_converter(band_range, slots)
            if debug:
                print(f0, band)
            print("INFO: RSA completed for optical band")
            if flow_list is None:
                self.null_values(self.flow_id)
                return self.flow_id, []
Mohammad Ismaeel's avatar
Mohammad Ismaeel committed
            #slots_i = []
            #for i in slots:
            #    slots_i.append(int(i))
            slots_i = {}
            for i in slots:
Mohammad Ismaeel's avatar
Mohammad Ismaeel committed
                slots_i[str(i)] = 1

            # return links, path, flow_list, band_range, slots, fiber_f, fiber_b, op, num_slots, f0, band
            #        links, path, flows, bx, slots, fiber_f, fiber_b, op, n_slots, f0, band
Mohammad Ismaeel's avatar
Mohammad Ismaeel committed
            if debug:
                print(links)
            if len(flow_list) > 0:
                src_port = flow_list[path[0]]['f']['out']
                dst_port = flow_list[path[-1]]['f']['in']
Mohammad Ismaeel's avatar
Mohammad Ismaeel committed
                if debug:
                    print(flow_list)
            if len(links) == 1:
                #fib_x = fiber_f[link_x]
                #rev_dst_port = self.links_dict[link_x]['fibers'][fib_x]["local_peer_port"]
                #rev_src_port = self.links_dict[link_x]['fibers'][fib_x]["remote_peer_port"]
Mohammad Ismaeel's avatar
Mohammad Ismaeel committed
                fibx = self.get_link_by_name(links[0])["optical_details"]
                rev_dst_port = fibx["local_peer_port"]
                rev_src_port = fibx["remote_peer_port"]
            else:
Mohammad Ismaeel's avatar
Mohammad Ismaeel committed
                link_in = links[0]
                link_out = links[-1]
                fib_inx = self.get_link_by_name(link_in)["optical_details"]
                fib_outx = self.get_link_by_name(link_out)["optical_details"]
                rev_dst_port = fib_inx["local_peer_port"]
                rev_src_port = fib_outx["remote_peer_port"]

                #fib_in = fiber_f[link_in]
                #fib_out = fiber_f[link_out]
                #rev_dst_port = self.links_dict[link_in]['fibers'][fib_in]["local_peer_port"]
                #rev_src_port = self.links_dict[link_out]['fibers'][fib_out]["remote_peer_port"]

            self.optical_bands[forw_opt_band_id]["flows"] = flow_list
            self.optical_bands[forw_opt_band_id]["band_type"] = band_range
            self.optical_bands[forw_opt_band_id]["fiber_forward"] = fiber_f
            self.optical_bands[forw_opt_band_id]["fiber_backward"] = fiber_b
            self.optical_bands[forw_opt_band_id]["op-mode"] = op
            self.optical_bands[forw_opt_band_id]["n_slots"] = num_slots
            self.optical_bands[forw_opt_band_id]["links"] = links
            self.optical_bands[forw_opt_band_id]["path"] = path
            self.optical_bands[forw_opt_band_id]["band"] = band
            self.optical_bands[forw_opt_band_id]["freq"] = f0
            self.optical_bands[forw_opt_band_id]["is_active"] = True
            self.optical_bands[forw_opt_band_id]["src_port"] = src_port
            self.optical_bands[forw_opt_band_id]["dst_port"] = dst_port
            self.optical_bands[forw_opt_band_id]["rev_dst_port"] = rev_dst_port
            self.optical_bands[forw_opt_band_id]["rev_src_port"] = rev_src_port
            self.optical_bands[forw_opt_band_id][band_range] = slots_i
            self.optical_bands[forw_opt_band_id]["served_lightpaths"] = []
            '''
            if bidir:
                self.optical_bands[back_opt_band_id]["flows"] = flow_list_b
                self.optical_bands[back_opt_band_id]["band_type"] = band_range
                self.optical_bands[back_opt_band_id]["fiber_forward"] = fiber_b
                # self.optical_bands[back_opt_band_id]["fiber_backward"] = fiber_b
                self.optical_bands[back_opt_band_id]["op-mode"] = op
                self.optical_bands[back_opt_band_id]["n_slots"] = num_slots
                self.optical_bands[back_opt_band_id]["links"] = rev_links
                self.optical_bands[back_opt_band_id]["path"] = rev_path
                self.optical_bands[back_opt_band_id]["band"] = band
                self.optical_bands[back_opt_band_id]["freq"] = f0
                self.optical_bands[back_opt_band_id]["is_active"] = True
                self.optical_bands[back_opt_band_id]["src_port"] = rev_src_port
                self.optical_bands[back_opt_band_id]["dst_port"] = rev_dst_port
                self.optical_bands[back_opt_band_id][band_range] = slots_i.copy()
                self.optical_bands[back_opt_band_id]["served_lightpaths"] = []
            '''

        return forw_opt_band_id, temp_links

    def get_optical_bands(self, r_src, r_dst):
        result = []
        for ob_id in self.optical_bands:
            ob = self.optical_bands[ob_id]
            if debug:
                print(r_src, ob["src"])
                print(r_dst, ob["dst"])
                print(ob)
            if ob["src"] == r_src and ob["dst"] == r_dst:
                result.append(ob_id)
        return result

    def rsa_fs_computation(self, src, dst, rate, bidir, band):
        num_slots_ob = "full_band"
        if band is not None:
            num_slots_ob = map_band_to_slot(band)
            print(band, num_slots_ob)
        if self.nodes_dict[src]["type"] == "OC-ROADM" and self.nodes_dict[dst]["type"] == "OC-ROADM":
            print("INFO: ROADM to ROADM connection")
            links, path = self.compute_path(src, dst)
            if len(path) < 1:
                self.null_values_ob(self.opt_band_id)
                return self.flow_id, []
            optical_band_id, temp_links = self.create_optical_band(links, path, bidir, num_slots_ob)
            return None, optical_band_id
Mohammad Ismaeel's avatar
Mohammad Ismaeel committed
        print("INFO: TP to TP connection")
        self.flow_id += 1
        self.db_flows[self.flow_id] = {}
        self.db_flows[self.flow_id]["flow_id"] = self.flow_id
        self.db_flows[self.flow_id]["src"] = src
        self.db_flows[self.flow_id]["dst"] = dst
        self.db_flows[self.flow_id]["bitrate"] = rate
        self.db_flows[self.flow_id]["bidir"] = bidir
        if band is None:
            temp_links2 = []
            temp_path = []
            src_links = get_links_from_node(self.links_dict, src)
            dst_links = get_links_to_node(self.links_dict, dst)
            if len(src_links.keys()) >= 1:
                temp_links2.append(list(src_links.keys())[0])
            if len(dst_links.keys()) >= 1:
                temp_links2.append(list(dst_links.keys())[0])

            if len(temp_links2) == 2:
                [t_src, roadm_src] = temp_links2[0].split('-')
                [roadm_dst, t_dst] = temp_links2[1].split('-')
                temp_path.append(t_src)
                temp_path.append(roadm_src)
                temp_path.append(roadm_dst)
                temp_path.append(t_dst)
                existing_ob = self.get_optical_bands(roadm_src, roadm_dst)

                if len(existing_ob) > 0:
                    print("INFO: Evaluating existing OB  {}".format(existing_ob))
                    #first checking in existing OB
                    ob_found = 0
                    for ob_id in existing_ob:
                        if "is_active" in self.optical_bands[ob_id].keys():
                            is_active = self.optical_bands[ob_id]["is_active"]
                            if not is_active:
                                continue
                        op, num_slots = map_rate_to_slot(rate)
                        if debug:
                            print(temp_links2)
                        c_slots, l_slots, s_slots = self.get_slots(temp_links2, num_slots, ob_id)
                        if debug:
                            print(c_slots)
                            print(l_slots)
                            print(s_slots)
                        if len(c_slots) >= num_slots or len(l_slots) >= num_slots or len(s_slots) >= num_slots:
                            flow_list, band_range, slots, fiber_f, fiber_b = self.select_slots_and_ports_fs(temp_links2, num_slots,
                                                                                                            c_slots,
                                                                                                            l_slots, s_slots, bidir,
                                                                                                            ob_id)
                            f0, band = frequency_converter(band_range, slots)
                            if debug:
                                print(f0, band)
                            print("INFO: RSA completed for Flex Lightpath with OB already in place")
                            if flow_list is None:
                                self.null_values(self.flow_id)
                                continue
                            slots_i = []
                            for i in slots:
                                slots_i.append(int(i))
                            # return links, path, flow_list, band_range, slots, fiber_f, fiber_b, op, num_slots, f0, band
                            #        links, path, flows, bx, slots, fiber_f, fiber_b, op, n_slots, f0, band
                            self.db_flows[self.flow_id]["flows"] = flow_list
                            self.db_flows[self.flow_id]["band_type"] = band_range
                            self.db_flows[self.flow_id]["slots"] = slots_i
                            self.db_flows[self.flow_id]["fiber_forward"] = fiber_f
                            self.db_flows[self.flow_id]["fiber_backward"] = fiber_b
                            self.db_flows[self.flow_id]["op-mode"] = op
                            self.db_flows[self.flow_id]["n_slots"] = num_slots
                            self.db_flows[self.flow_id]["links"] = temp_links2
                            self.db_flows[self.flow_id]["path"] = temp_path
                            self.db_flows[self.flow_id]["band"] = band
                            self.db_flows[self.flow_id]["freq"] = f0
                            self.db_flows[self.flow_id]["is_active"] = True
                            self.db_flows[self.flow_id]["parent_opt_band"] = ob_id
                            self.db_flows[self.flow_id]["new_optical_band"] = 0
                            self.optical_bands[ob_id]["served_lightpaths"].append(self.flow_id)
                            '''
                            if bidir:
                                rev_ob_id = self.optical_bands[ob_id]["reverse_optical_band_id"]
                                self.optical_bands[rev_ob_id]["served_lightpaths"].append(self.flow_id)
                            '''
                            return self.flow_id, ob_id
                        else:
                            print("not enough slots")
                            print("trying to extend OB {}".format(ob_id))
                            new_slots = self.extend_optical_band(ob_id, band=None)

                            if len(new_slots) > 0:
                                band_type = self.optical_bands[ob_id]["band_type"]
                                c_slots = []
                                l_slots = []
                                s_slots = []
                                if band_type == "c_slots":
                                    c_slots = new_slots
                                elif band_type == "l_slots":
                                    l_slots = new_slots
                                else:
                                    s_slots = new_slots
                                op, num_slots = map_rate_to_slot(rate)
                                if debug:
                                    print(temp_links2)
                                c_slots, l_slots, s_slots = self.get_slots(temp_links2, num_slots, ob_id)
                                if debug:
                                    print(c_slots)
                                    print(l_slots)
                                    print(s_slots)
                                #print(c_slots)
                                #print(l_slots)
                                #print(s_slots)
                                if len(c_slots) >= num_slots or len(l_slots) >= num_slots or len(s_slots) >= num_slots:
                                    flow_list, band_range, slots, fiber_f, fiber_b = self.select_slots_and_ports_fs(
                                        temp_links2, num_slots,
                                        c_slots,
                                        l_slots, s_slots, bidir,
                                        ob_id)
                                    f0, band = frequency_converter(band_range, slots)
                                    if debug:
                                        print(f0, band)
                                    print("INFO: RSA completed for Flex Lightpath with OB already in place")
                                    if flow_list is None:
                                        self.null_values(self.flow_id)
                                        continue
                                    slots_i = []
                                    for i in slots:
                                        slots_i.append(int(i))
                                    # return links, path, flow_list, band_range, slots, fiber_f, fiber_b, op, num_slots, f0, band
                                    #        links, path, flows, bx, slots, fiber_f, fiber_b, op, n_slots, f0, band
                                    self.db_flows[self.flow_id]["flows"] = flow_list
                                    self.db_flows[self.flow_id]["band_type"] = band_range
                                    self.db_flows[self.flow_id]["slots"] = slots_i
                                    self.db_flows[self.flow_id]["fiber_forward"] = fiber_f
                                    self.db_flows[self.flow_id]["fiber_backward"] = fiber_b
                                    self.db_flows[self.flow_id]["op-mode"] = op
                                    self.db_flows[self.flow_id]["n_slots"] = num_slots
                                    self.db_flows[self.flow_id]["links"] = temp_links2
                                    self.db_flows[self.flow_id]["path"] = temp_path
                                    self.db_flows[self.flow_id]["band"] = band
                                    self.db_flows[self.flow_id]["freq"] = f0
                                    self.db_flows[self.flow_id]["is_active"] = True
                                    self.db_flows[self.flow_id]["parent_opt_band"] = ob_id
                                    self.db_flows[self.flow_id]["new_optical_band"] = 1
                                    #self.db_flows[self.flow_id]["new_optical_band"] = 2
                                    self.optical_bands[ob_id]["served_lightpaths"].append(self.flow_id)
                                    '''
                                    if bidir:
                                        rev_ob_id = self.optical_bands[ob_id]["reverse_optical_band_id"]
                                        self.optical_bands[rev_ob_id]["served_lightpaths"].append(self.flow_id)
                                    '''
                                    return self.flow_id, ob_id
                                else:
                                    print("it is not possible to allocate connection in extended OB {}".format(ob_id))
                                    

        if band is None:
            print("INFO: Not existing optical-band meeting the requirements")
        else:
            print("INFO: optical-band width specified")
        #if no OB I create a new one
        links, path = self.compute_path(src, dst)
        optical_band_id, temp_links = self.create_optical_band(links, path, bidir, num_slots_ob)
        op, num_slots = map_rate_to_slot(rate)
        if debug:
            print(temp_links)
        c_slots, l_slots, s_slots = self.get_slots(temp_links, num_slots, optical_band_id)
        if debug:
            print(c_slots)
            print(l_slots)
            print(s_slots)
        if len(c_slots) > 0 or len(l_slots) > 0 or len(s_slots) > 0:
            flow_list, band_range, slots, fiber_f, fiber_b = self.select_slots_and_ports_fs(temp_links, num_slots, c_slots,
                                                                                            l_slots, s_slots, bidir, optical_band_id)
            f0, band = frequency_converter(band_range, slots)
            if debug:
                print(f0, band)
            print("INFO: RSA completed for FLex Lightpath with new OB")
            if flow_list is None:
                self.null_values(self.flow_id)
                return self.flow_id, optical_band_id
            slots_i = []
            for i in slots:
                slots_i.append(int(i))

            self.db_flows[self.flow_id]["flows"] = flow_list
            self.db_flows[self.flow_id]["band_type"] = band_range
            self.db_flows[self.flow_id]["slots"] = slots_i
            self.db_flows[self.flow_id]["fiber_forward"] = fiber_f
            self.db_flows[self.flow_id]["fiber_backward"] = fiber_b
            self.db_flows[self.flow_id]["op-mode"] = op
            self.db_flows[self.flow_id]["n_slots"] = num_slots
            self.db_flows[self.flow_id]["links"] = temp_links
            self.db_flows[self.flow_id]["path"] = path
            self.db_flows[self.flow_id]["band"] = band
            self.db_flows[self.flow_id]["freq"] = f0
            self.db_flows[self.flow_id]["is_active"] = True
            self.db_flows[self.flow_id]["parent_opt_band"] = optical_band_id
            self.db_flows[self.flow_id]["new_optical_band"] = 1
            self.optical_bands[optical_band_id]["served_lightpaths"].append(self.flow_id)
            '''
            if bidir:
                rev_ob_id = self.optical_bands[optical_band_id]["reverse_optical_band_id"]
                self.optical_bands[rev_ob_id]["served_lightpaths"].append(self.flow_id)
            '''
        return self.flow_id, optical_band_id

    def extend_optical_band(self, ob_id, band=None):
        ob = self.optical_bands[ob_id]
        links = ob["links"]
        old_band = ob["band"]
        band_type = ob["band_type"]
        f0 = ob["freq"]
        slots = ob[band_type]
        if band is None:
            num_slots_ob = map_band_to_slot(old_band/1000.0)
        else:
            num_slots_ob = map_band_to_slot(band)
        new_slots = []
        for l in links:
            link = self.get_link_by_name(l)
            fib = link["optical_details"][band_type]
            #s_slots = get_side_slots_on_link(link, band_type, num_slots_ob, slots)
            s_slots, s_num = get_side_slots_on_link(fib, num_slots_ob, slots)
            print("NEW SLOTS {}".format(s_slots))
            if len(new_slots) == 0:
                new_slots = s_slots
            else:
                if len(new_slots) < s_num:
                    new_slots = list_in_list(new_slots, s_slots)
        print("NEW SLOTS {}".format(new_slots))
        self.augment_optical_band(ob_id, new_slots, band_type)
        new_band = int(len(new_slots)*12.5*1000)
        print("{}, {},{},{} ".format(old_band, f0, len(new_slots), new_band))
        final_band = old_band + new_band
        final_f0 = int(f0 + new_band/2)
        print("{}, {}".format(final_band, final_f0))
        ob["band"] = final_band
        ob["freq"] = final_f0
        for link_x in links:
            link = self.get_link_by_name(link_x)
            fib = link["optical_details"]
            self.update_link(fib, new_slots, band_type)
        return new_slots