Commit ff7c4811 authored by Andrea Sgambelluri's avatar Andrea Sgambelluri
Browse files

first version with preferreb band, alien waves and full spectrum

parent 95573131
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -95,7 +95,7 @@ metadata:
    app: telemetryservice
spec:
  type: LoadBalancer
  loadBalancerIP: _LOAD_BALANCER_IP_
  loadBalancerIP: 192.168.5.250
  externalTrafficPolicy: Local
  selector:
    app: telemetryservice
+36 −11
Original line number Diff line number Diff line
@@ -69,18 +69,18 @@ class AddLightpath(Resource):


#@optical.route('/AddFlexLightpath/<string:src>/<string:dst>/<int:bitrate>')
@optical.route('/AddFlexLightpath/<string:src>/<string:dst>/<int:bitrate>',
@optical.route('/AddFlexLightpath/<string:src>/<string:dst>/<int:bitrate>/<string:pref>',
               defaults={"bidir": 1, "band": None, "obx_idx": None})
@optical.route('/AddFlexLightpath/<string:src>/<string:dst>/<int:bitrate>/<int:bidir>',
@optical.route('/AddFlexLightpath/<string:src>/<string:dst>/<int:bitrate>/<string:pref>/<int:bidir>',
               defaults={"band": None, "obx_idx": None})
@optical.route('/AddFlexLightpath/<string:src>/<string:dst>/<int:bitrate>/<int:bidir>/<int:band>',
@optical.route('/AddFlexLightpath/<string:src>/<string:dst>/<int:bitrate>/<string:pref>/<int:bidir>/<int:band>',
               defaults={"obx_idx": None})
@optical.route('/AddFlexLightpath/<string:src>/<string:dst>/<int:bitrate>/<int:bidir>/<int:band>/<int:obx_idx>')
@optical.route('/AddFlexLightpath/<string:src>/<string:dst>/<int:bitrate>/<string:pref>/<int:bidir>/<int:band>/<int:obx_idx>')
@optical.response(200, 'Success')
@optical.response(404, 'Error, not found')
class AddFlexLightpath(Resource):
    @staticmethod
    def put(src, dst, bitrate, bidir=1, band=None, obx_idx = None):
    def put(src, dst, bitrate, pref, bidir=0, band=None, obx_idx = None ):

        print("INFO: New MGON request from {} to {} with rate {} and band {}".format(src, dst, bitrate, band))
        t0 = time.time()*1000.0
@@ -88,7 +88,7 @@ class AddFlexLightpath(Resource):
        #    rsa.g.printGraph()

        if rsa is not None:
            flow_id, optical_band_id = rsa.rsa_fs_computation(src, dst, bitrate, bidir, band, obx_idx)
            flow_id, optical_band_id = rsa.rsa_fs_computation(src, dst, bitrate, bidir, band, obx_idx, pref)
            if flow_id is not None:
                if rsa.db_flows[flow_id]["op-mode"] == 0:
                    return 'No path found', 404
@@ -109,14 +109,39 @@ class AddFlexLightpath(Resource):
        else:
            return "Error", 404

@optical.route('/AddAlienFLexLightpath/<string:src>/<string:s_port>/<string:dst>/<string:d_port>/<int:band>/<int:obx_idx>',
               defaults={"bidir": 0})
@optical.route('/AddAlienFLexLightpath/<string:src>/<string:s_port>/<string:dst>/<string:d_port>/<int:band>/<int:obx_idx>/<int:bidir>')
@optical.response(200, 'Success')
@optical.response(404, 'Error, not found')
class AddAlienFLexLightpath(Resource):
    @staticmethod
    def put(src, s_port, dst, d_port, band, obx_idx, bidir=0):

        print("INFO: New Alien MGON request from {} to {} with band {}".format(src, dst, band))
        t0 = time.time()*1000.0
        #if debug:
        #    rsa.g.printGraph()

        if rsa is not None:
            flow_id = rsa.rsa_fs_alien_computation(src, s_port, dst, d_port, band, bidir, obx_idx)
            if flow_id is not None:
                if not rsa.db_flows[flow_id]["is_active"]:
                    return 'No path found', 404
                t1 = time.time() * 1000.0
                elapsed = t1 - t0
                print("INFO: time elapsed = {} ms".format(elapsed))
                return rsa.db_flows[flow_id], 200


# @optical.route('/DelFlexLightpath/<string:src>/<string:dst>/<int:bitrate>/<int:o_band_id>')
@optical.route('/DelFlexLightpath/<string:src>/<string:dst>/<int:bitrate>/<int:flow_id>')
@optical.route('/DelFlexLightpath/<string:src>/<string:dst>/<int:bitrate>/<int:flow_id>/<int:o_band_id>')
@optical.route('/DelFlexLightpath/<string:src>/<string:dst>/<int:flow_id>')
@optical.route('/DelFlexLightpath/<string:src>/<string:dst>/<int:flow_id>/<int:o_band_id>')
@optical.response(200, 'Success')
@optical.response(404, 'Error, not found')
class DelFLightpath(Resource):
    @staticmethod
    def delete( src, dst, bitrate, o_band_id=None, flow_id=None):
    def delete( src, dst, flow_id, o_band_id=None):
            flow = None
            match1=False
            ob_id=None
@@ -124,13 +149,13 @@ class DelFLightpath(Resource):
     
                if flow_id in rsa.db_flows.keys():
                   flow = rsa.db_flows[flow_id]
                   match1 = flow["src"] == src and flow["dst"] == dst and flow["bitrate"] == bitrate
                   match1 = flow["src"] == src and flow["dst"] == dst
                   ob_id = flow["parent_opt_band"] if 'parent_opt_band' in flow else None
                   flow['is_active']=False
            if flow is not None:
                bidir = flow["bidir"]
                if bidir:
                    match2 = flow["src"] == dst and flow["dst"] == src and flow["bitrate"] == bitrate
                    match2 = flow["src"] == dst and flow["dst"] == src
                    if match1 or match2:
                        ob_id = flow["parent_opt_band"] if 'parent_opt_band' in flow else None
                        rsa.db_flows[flow_id]["is_active"] = False
+194 −15
Original line number Diff line number Diff line
@@ -68,18 +68,19 @@ class RSA():

    def init_link_slots2(self):
        if full_links:
            print("2026 initialize full spectrum")
            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
                        fib["c_slots"][str(c)] = 1
                if len(fib["l_slots"]) > 0:
                    for c in range(0, Nl):
                        fib["l_slots"][c] = 1
                        fib["l_slots"][str(c)] = 1
                if len(fib["s_slots"]) > 0:
                    for c in range(0, Ns):
                        fib["s_slots"][c] = 1
                        fib["s_slots"][str(c)] = 1
                if debug:
                    print(fib)
        for l1 in self.links_dict["optical_links"]:
@@ -291,13 +292,14 @@ class RSA():
            else:
                s_sts = []
        if old_band_x == "c_slots":
            c_sts = []
            l_sts = []
            s_sts = []
        if old_band_x == "l_slots":
            c_sts = []
            l_sts = []
        if old_band_x == "s_slots":
            s_sts = []
            c_sts = []
            a_sts = []
        
        return c_sts, l_sts, s_sts

@@ -606,10 +608,10 @@ class RSA():
        return fiber_list

    #function invoked for lightpaths and OB
    def select_slots_and_ports(self, links, n_slots, c, l, s, bidir):
    def select_slots_and_ports(self, links, n_slots, c, l, s, bidir, preferred=None):
        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)
        band, slots = slot_selection(c, l, s, n_slots, self.c_slot_number, self.l_slot_number, self.s_slot_number, preferred)
        if debug:
            print (band, slots)
        if band is None:
@@ -687,6 +689,7 @@ class RSA():
            return None, None, None, None, None
        if debug:
            print(f"INFO: XXXX {band}, {slots}")
        
        self.get_fibers_forward(links, slots, band)
        if bidir:
            self.get_fibers_backward(links, slots, band)
@@ -774,13 +777,85 @@ class RSA():
        
        #if debug:
        #    print(self.links_dict)
        print("INFO: 4")
        #if debug:
        #    print(t_flows)
        print("INFO: Flow matrix computed for Flex Lightpath")

        return t_flows, band, slots, {}, {}

    #function ivoked for fs lightpaths only
    def alien_select_slots_and_ports_fs(self, src_port, dst_port, n_slots, c, l, s, bidir, o_band_id):
        print("PDP: inside flow creation")
        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("PDP ERROR: No slots available in the three bands")
            return None, None, None, None, None
        print(f"PDP: {band}, {slots}")
        #if debug:
        #    print(f"INFO: XXXX {band}, {slots}")

        self.update_optical_band(o_band_id, slots, band)
        print("INFO: 1")

        t_flows = {}

        '''
        #flows_add_side
        src, dst = add.split("-")
        lx = self.get_link_by_name(add)["optical_details"]
        #outport = self.links_dict[add]['fibers'][f]["src_port"]
        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"]
            r_inport = lx["local_peer_port"]
            t_flows[src]["b"] = {"in": r_inport, "out": port_0}
        print("INFO: 2")
        '''
        src = self.optical_bands[o_band_id]["src"]
        dst = self.optical_bands[o_band_id]["dst"]
        #R1 rules
        t_flows[src] = {}
        t_flows[src]["f"] = {}
        t_flows[src]["b"] = {}
        opt_band_src_port = self.optical_bands[o_band_id]["src_port"]
        t_flows[src]["f"] = {"in": src_port, "out": opt_band_src_port}
        #to modify to peer ports
        '''
        if bidir:
            #r_inport = self.links_dict[add]['fibers'][f]["local_peer_port"]
            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"]
            r_outport = lx["remote_peer_port"]
            t_flows[dst]["b"] = {"in": rev_opt_band_dst_port, "out": r_outport}
        '''

        #flows_drop_side
        # R2 rules
        
        t_flows[dst] = {}
        t_flows[dst]["f"] = {}
        t_flows[dst]["b"] = {}
        opt_band_dst_port = self.optical_bands[o_band_id]["dst_port"]
        t_flows[dst]["f"] = {"in": opt_band_dst_port, "out": dst_port}
        '''
        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"]
            r_inport = ly["local_peer_port"]
            t_flows[src]["b"] = {"in": r_inport, "out": rev_opt_band_src_port}
        '''
        print("PDP: Flow matrix computed for Alien Flex Lightpath")

        return t_flows, band, slots, {}, {}

    def rsa_computation(self, src, dst, rate, bidir):
        if self.flow_id == 0:
            self.flow_id += 1
@@ -869,7 +944,7 @@ class RSA():
        #self.db_flows[flow_id]["parent_opt_band"] = 0
        #self.db_flows[flow_id]["new_optical_band"] = 0

    def create_optical_band(self, links, path, bidir, num_slots, old_band_x=None):
    def create_optical_band(self, links, path, bidir, num_slots, old_band_x=None, preferred=None):
        print("INFO: Creating optical-band of {} slots".format(num_slots))
        if self.opt_band_id == 0:
            self.opt_band_id += 1
@@ -924,7 +999,7 @@ class RSA():
            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)
            flow_list, band_range, slots, fiber_f, fiber_b = self.select_slots_and_ports(links, num_slots, c_slots, l_slots, s_slots, bidir, preferred)
            if debug:
                print(flow_list, band_range, slots, fiber_f, fiber_b)
            f0, band = frequency_converter(band_range, slots)
@@ -1020,7 +1095,108 @@ class RSA():
                result.append(ob_id)
        return result

    def rsa_fs_computation(self, src, dst, rate, bidir, band, bandx_id):
    def get_alien_slots(self, optical_band_id, num_slots):
        print(f"ALIEN SLOTS: {self.optical_bands[optical_band_id]}")
        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
                #MOD
                c_sts = consecutives(self.optical_bands[optical_band_id]["c_slots"], num_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
                l_sts = consecutives(self.optical_bands[optical_band_id]["l_slots"], num_slots)
                #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
                s_sts = consecutives(self.optical_bands[optical_band_id]["s_slots"], num_slots)
                #s_sts = common_slots(a_s, b_s)
        else:
            s_sts = []
        return c_sts, l_sts, s_sts


    def rsa_fs_alien_computation(self, src, s_port, dst, d_port, band, bidir, obx_idx):
        if self.flow_id == 0:
            self.flow_id += 1
        else:
            if (self.db_flows[self.flow_id]["bidir"] == 1):
                self.flow_id += 2
            else:
                self.flow_id += 1
        if self.nodes_dict[src]["type"] == "OC-ROADM" and self.nodes_dict[dst]["type"] == "OC-ROADM":
            if obx_idx in self.optical_bands.keys():
                #optical_band = self.optical_bands[obx_idx]
                num_slots = map_band_to_slot(band)
                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"] = None
                self.db_flows[self.flow_id]["bidir"] = bidir
                self.db_flows[self.flow_id]["src_port"] = s_port
                self.db_flows[self.flow_id]["dst_port"] = d_port
                
                c_slots, l_slots, s_slots = self.get_alien_slots(obx_idx, num_slots)                 
                if debug:
                    print(f"PDP: {c_slots}")
                    print(f"PDP: {l_slots}")
                    print(f"PDP: {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.alien_select_slots_and_ports_fs(s_port, d_port, num_slots,
                                                                                                    c_slots, l_slots, s_slots, bidir,
                                                                                                    obx_idx)
                    f0, band = frequency_converter(band_range, slots)
                    if debug:
                        print(f0, band)
                    print("INFO: RSA completed for Alien Flex Lightpath with OB already in place")
                    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"] = None
                    self.db_flows[self.flow_id]["n_slots"] = num_slots
                    self.db_flows[self.flow_id]["links"] = []
                    self.db_flows[self.flow_id]["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"] = obx_idx
                    self.db_flows[self.flow_id]["new_optical_band"] = 0
                    self.optical_bands[obx_idx]["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(flow_id)
                    '''
                    return self.flow_id
                else:
                    self.null_values(self.flow_id)
                    return self.flow_id



        else:
            print("error")
            self.null_values(self.flow_id)
            return self.flow_id
            
    def rsa_fs_computation(self, src, dst, rate, bidir, band, bandx_id, preferred=None):
        if band is not None:
            num_slots_ob = map_band_to_slot(band)
            print(band, num_slots_ob)
@@ -1044,7 +1220,7 @@ class RSA():
            if len(path) < 1:
                self.null_values_ob(self.opt_band_id)
                return self.opt_band_id, []
            optical_band_id, temp_links = self.create_optical_band(links, path, bidir, num_slots_ob, old_band_x)
            optical_band_id, temp_links = self.create_optical_band(links, path, bidir, num_slots_ob, old_band_x, preferred)
            return None, optical_band_id
        print("INFO: TP to TP connection")
        if self.flow_id == 0:
@@ -1330,6 +1506,8 @@ class RSA():
            print("INFO: Trying to move connection to an existing OB")
            #first checking in existing OB
            for ob_id in existing_ob:
                if ob_id == ob_idx:
                    continue
                if "is_active" in self.optical_bands[ob_id].keys():
                    is_active = self.optical_bands[ob_id]["is_active"]
                    if not is_active:
@@ -1345,13 +1523,14 @@ class RSA():
                    print(l_slots)
                    print(s_slots)
                if band_type == "c_slots":
                    c_slots = []
                    l_slots =[]
                    s_slots = []
                elif band_type == "l_slots":
                    c_slots = []
                    l_slots = []
                elif band_type == "s_slots":
                    s_slots = []
                elif band_type == "s_slots":
                    c_slots = []
                    l_slots =[]
                if debug:
                    print("OFC26 available slots after reset due to band")
                    print(c_slots)
+41 −8
Original line number Diff line number Diff line
@@ -242,7 +242,7 @@ def get_links_to_node(topology, node):
    return result


def slot_selection(c, l, s, n_slots, Nc, Nl, Ns):
def slot_selection(c, l, s, n_slots, Nc, Nl, Ns, preferred=None):
    # First Fit
    
    if isinstance(n_slots, int):
@@ -253,6 +253,7 @@ def slot_selection(c, l, s, n_slots, Nc, Nl, Ns):
        slot_c = Nc
        slot_l = Nl
        slot_s = Ns
    if preferred == None or preferred == "ANY":
        if len(c) >= slot_c:
            return "c_slots", c[0: slot_c]
        elif len(l) >= slot_l:
@@ -261,6 +262,38 @@ def slot_selection(c, l, s, n_slots, Nc, Nl, Ns):
            return "s_slots", s[0: slot_s]
        else:
            return None, None
    else:
        if preferred == "C_BAND":
            if len(c) >= slot_c:
                return "c_slots", c[0: slot_c]
            elif len(l) >= slot_l:
                return "l_slots", l[0: slot_l]
            elif len(s) >= slot_s:
                return "s_slots", s[0: slot_s]
            else:
                return None, None
        elif preferred == "L_BAND":
            if len(l) >= slot_l:
                return "l_slots", l[0: slot_l]
            elif len(c) >= slot_c: 
                return "c_slots", c[0: slot_c]
            elif len(s) >= slot_s:
                return "s_slots", s[0: slot_s]
            else:
                return None, None
        elif preferred == "S_BAND":
            if len(s) >= slot_s:
                return "s_slots", s[0: slot_s]
            elif len(l) >= slot_l:
                return "l_slots", l[0: slot_l]
            elif len(c) >= slot_c: 
                return "c_slots", c[0: slot_c]
            else:
                return None, None
        else:
            logging.INFO("PDP: wrong preferred value")
            return None, None
            

def handle_slot (slot_field, slot):
    for key,value in slot.items() :
+1 −1
Original line number Diff line number Diff line
@@ -23,4 +23,4 @@ Nc = 320
#Nc = 10
Ns = 720

full_links = 0
full_links = 1
Loading