Newer
Older
# Copyright 2022-2024 ETSI OSG/SDG TeraFlowSDN (TFS) (https://tfs.etsi.org/)
#
# 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.
from flask import Flask
from flask import render_template
from flask_restplus import Resource, Api
from tools import *
from variables import *
from RSA import RSA
from common.proto.context_pb2 import TopologyId , OpticalLink
from google.protobuf.message import Message
from google.protobuf.json_format import MessageToDict
from common.tools.object_factory.OpticalLink import order_dict
global rsa
global links_dict
app = Flask(__name__)
api = Api(app, version='1.0', title='Optical controller API',
description='Rest API to configure OC Optical devices in TFS')
# app.config.from_object('config')
# appbuilder = AppBuilder(app, indexview=MyIndexView)
optical = api.namespace('OpticalTFS', description='TFS Optical APIs')
@app.route('/index')
def index():
return render_template('index.html')
#@optical.route('/AddLightpath/<string:src>/<string:dst>/<int:bitrate>/<int:bidir>')
@optical.route('/AddLightpath/<string:src>/<string:dst>/<int:bitrate>')
@optical.response(200, 'Success')
@optical.response(404, 'Error, not found')
class AddLightpath(Resource):
@staticmethod
def put(src, dst, bitrate, bidir=1):
print("INFO: New Lightpath request from {} to {} with rate {} ".format(src, dst, bitrate))
t0 = time.time()*1000.0
if debug:
rsa.g.printGraph()
if rsa is not None:
flow_id = rsa.rsa_computation(src, dst, bitrate, bidir)
if rsa.db_flows[flow_id]["op-mode"] == 0:
return 'No path found', 404
print("INFO: time elapsed = {} ms".format(elapsed))
return rsa.db_flows[flow_id], 200
else:
return "Error", 404
#@optical.route('/AddFlexLightpath/<string:src>/<string:dst>/<int:bitrate>')
@optical.route('/AddFlexLightpath/<string:src>/<string:dst>/<int:bitrate>',
defaults={"bidir": 1, "band": None})
@optical.route('/AddFlexLightpath/<string:src>/<string:dst>/<int:bitrate>/<int:bidir>',
defaults={"band": None})
@optical.route('/AddFlexLightpath/<string:src>/<string:dst>/<int:bitrate>/<int:bidir>/<int:band>',)
@optical.response(200, 'Success')
@optical.response(404, 'Error, not found')
class AddFlexLightpath(Resource):
@staticmethod
def put(src, dst, bitrate, bidir=1, band=None):
print("INFO: New FlexLightpath request from {} to {} with rate {} ".format(src, dst, bitrate))
t0 = time.time()*1000.0
if debug:
rsa.g.printGraph()
if rsa is not None:
flow_id, optical_band_id = rsa.rsa_fs_computation(src, dst, bitrate, bidir, band)
if flow_id is not None:
if rsa.db_flows[flow_id]["op-mode"] == 0:
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
else:
if len(rsa.optical_bands[optical_band_id]["flows"]) == 0:
return 'No path found', 404
else:
t1 = time.time() * 1000.0
elapsed = t1 - t0
print("INFO: time elapsed = {} ms".format(elapsed))
return rsa.optical_bands[optical_band_id], 200
else:
return "Error", 404
# @optical.route('/DelFlexLightpath/<string:src>/<string:dst>/<int:bitrate>/<int:o_band_id>')
@optical.route('/DelFlexLightpath/<string:src>/<string:dst>/<int:bitrate>/<int:o_band_id>')
@optical.route('/DelFlexLightpath/<string:src>/<string:dst>/<int:bitrate>/<int:o_band_id>/<int:flow_id>')
@optical.response(200, 'Success')
@optical.response(404, 'Error, not found')
def delete( src, dst, bitrate, o_band_id,flow_id=None):
flow = None
match1=False
ob_id=None
if flow_id is not None:
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
ob_id = flow["parent_opt_band"]
if flow is not None:
bidir = flow["bidir"]
if bidir:
match2 = flow["src"] == dst and flow["dst"] == src and flow["bitrate"] == bitrate
if match1 or match2:
ob_id = flow["parent_opt_band"]
rsa.del_flow(flow, ob_id)
rsa.db_flows[flow_id]["is_active"] = False
if flow_id in rsa.optical_bands[ob_id]["served_lightpaths"].remove:
rsa.optical_bands[ob_id]["served_lightpaths"].remove(flow_id)
#if rsa.optical_bands[ob_id]["reverse_optical_band_id"] != 0:
# rev_ob_id = rsa.optical_bands[ob_id]["reverse_optical_band_id"]
# rsa.optical_bands[rev_ob_id]["served_lightpaths"].remove(flow_id)
if debug:
print(rsa.links_dict)
return "flow {} deleted".format(flow_id), 200
else:
return "flow {} not matching".format(flow_id), 404
# if delete_band !=0 and ob_id is not None:
# print(f"delete_lightpath {delete_band} and ob_id {ob_id}")
# if len( rsa.optical_bands[ob_id]["served_lightpaths"]) != 0:
# return "DELETE_NOT_ALLOWED" ,400
if debug:
print(f"vor ob_id {ob_id} rsa.optical_bands {rsa.optical_bands[ob_id]}")
print(f"rsa.links_dict {rsa.links_dict}")
return "flow {} deleted".format(flow_id), 200
else:
return "flow {} not matching".format(flow_id), 404
else:
return "flow id {} does not exist".format(flow_id), 404
@optical.route('/DelOpticalBand/<string:src>/<string:dst>/<int:o_band_id>',methods=['DELETE'])
@optical.response(200, 'Success')
@optical.response(404, 'Error, not found')
class DelOpticalBand(Resource):
@staticmethod
if o_band_id in rsa.optical_bands.keys():
flow=rsa.optical_bands[o_band_id]
#match1 = flow["src"] == src and flow["dst"] == dst
ob_id=o_band_id
if flow is not None:
bidir = flow["bidir"]
if bidir:
match2 = flow["src"] == dst and flow["dst"] == src and flow["bitrate"]
if match1 or match2:
ob_id = flow["parent_opt_band"]
#rsa.del_flow(flow, ob_id)
rsa.optical_bands[ob_id]["is_active"] = False
# if flow_id in rsa.optical_bands[ob_id]["served_lightpaths"].remove:
# rsa.optical_bands[ob_id]["served_lightpaths"].remove(flow_id)
#if rsa.optical_bands[ob_id]["reverse_optical_band_id"] != 0:
# rev_ob_id = rsa.optical_bands[ob_id]["reverse_optical_band_id"]
# rsa.optical_bands[rev_ob_id]["served_lightpaths"].remove(flow_id)
if debug:
print(rsa.links_dict)
return "ob_id {} deleted".format(ob_id), 200
else:
return "ob_id {} not matching".format(ob_id), 404
if len( rsa.optical_bands[ob_id]["served_lightpaths"]) != 0:
return "DELETE_NOT_ALLOWED" ,400
rsa.del_band(flow,ob_id)
if debug:
print(f"vor ob_id {ob_id} rsa.optical_bands {rsa.optical_bands[ob_id]}")
print(f"rsa.links_dict {rsa.links_dict}")
return "ob_id {} deleted".format(ob_id), 200
else :
return "flow for ob_id {} not found".format(ob_id),400
return "ob_id {} does not exist".format(ob_id), 404
@optical.route('/DelLightpath/<int:flow_id>/<string:src>/<string:dst>/<int:bitrate>')
@optical.response(200, 'Success')
@optical.response(404, 'Error, not found')
class DelLightpath(Resource):
@staticmethod
def delete(flow_id, src, dst, bitrate):
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
match2 = flow["src"] == dst and flow["dst"] == src and flow["bitrate"] == bitrate
if match1 or match2:
rsa.del_flow(flow)
rsa.db_flows[flow_id]["is_active"] = False
if debug:
Andrea Sgambelluri
committed
print(rsa.links_dict)
return "flow {} deleted".format(flow_id), 200
else:
return "flow {} not matching".format(flow_id), 404
else:
return "flow id {} does not exist".format(flow_id), 404
@optical.route('/GetLightpaths')
@optical.response(200, 'Success')
@optical.response(404, 'Error, not found')
class GetFlows(Resource):
@staticmethod
def get():
try:
if debug:
return rsa.db_flows, 200
except:
return "Error", 404
@optical.route('/GetOpticalBands')
@optical.response(200, 'Success')
@optical.response(404, 'Error, not found')
class GetBands(Resource):
@staticmethod
def get():
try:
if debug:
return rsa.optical_bands, 200
except:
return "Error", 404
@optical.route('/GetOpticalBand/<int:ob_id>')
@optical.response(200, 'Success')
@optical.response(404, 'Error, not found')
class GetBand(Resource):
@staticmethod
def get(ob_id):
for ob_idx in rsa.optical_bands.keys():
if str(ob_idx) == str(ob_id):
if debug:
return rsa.optical_bands[ob_idx], 200
return {}, 404
@optical.route('/GetLinks')
@optical.response(200, 'Success')
@optical.response(404, 'Error, not found')
class GetFlows(Resource):
@staticmethod
def get():
#global links_dict
links = None
if rsa is not None :
links = rsa.links_dict
@optical.route('/GetTopology/<path:context_id>/<path:topology_id>',methods=['GET'])
@optical.response(200, 'Success')
@optical.response(404, 'Error, not found')
class GetTopology(Resource):
@staticmethod
if (rsa is not None):
return "Opticalcontroller is synchronised" ,200
topog_id = TopologyId()
topog_id.topology_uuid.uuid=topology_id
topog_id.context_id.context_uuid.uuid=context_id
try:
links_dict={"optical_links":[]}
node_dict = {}
topo , nodes = readTopologyDataFromContext(topog_id)
for link in topo:
link_dict_type = MessageToDict(link, preserving_proto_field_name=True)
if "c_slots" in link_dict_type["optical_details"] :
link_dict_type["optical_details"]["c_slots"]=order_dict(link_dict_type["optical_details"]["c_slots"])
if "l_slots" in link_dict_type["optical_details"] :
link_dict_type["optical_details"]["l_slots"]=order_dict(link_dict_type["optical_details"]["l_slots"])
if "s_slots" in link_dict_type["optical_details"] :
link_dict_type["optical_details"]["s_slots"]=order_dict(link_dict_type["optical_details"]["s_slots"])
links_dict["optical_links"].append(link_dict_type)
dev_dic = {}
dev_dic = {
"id":device.device_id.device_uuid.uuid,
#"ip":f"10.30.2.{207+i}",
#"port":"50001",
"type":"OC-ROADM" if device.device_type =="optical-roadm" else "OC-TP",
"driver": "OpticalOC"
}
node_dict[device.name]=dev_dic
#i+=1
#print(f"refresh_optical controller optical_links_dict= {links_dict}")
#print(f"refresh_optical controller node_dict {node_dict}")
rsa = RSA(node_dict, links_dict)
if debug:
print(rsa.init_link_slots2(testing))
app.run(host='0.0.0.0', port=10060)