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 google.protobuf.json_format import MessageToDict
from common.proto.context_pb2 import TopologyId
from opticalcontroller.tools import *
from opticalcontroller.variables import *
from opticalcontroller.RSA import RSA
logging.basicConfig(level=logging.INFO)
LOGGER = logging.getLogger(__name__)
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"]
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
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"]:
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
rsa.del_flow(flow,flow_id,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 "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
ob_id = None
if o_band_id is not None:
if o_band_id in rsa.optical_bands.keys():
flow = rsa.optical_bands[o_band_id]
match1 = flow["src"] == src and flow["dst"] == dst and flow["bitrate"]
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"]:
# 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
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
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"] = link_dict_type["optical_details"]["c_slots"]
if "l_slots" in link_dict_type["optical_details"]:
link_dict_type["optical_details"]["l_slots"] = link_dict_type["optical_details"]["l_slots"]
if "s_slots" in link_dict_type["optical_details"]:
link_dict_type["optical_details"]["s_slots"] = link_dict_type["optical_details"]["s_slots"]
links_dict["optical_links"].append(link_dict_type)
for device in nodes :
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:
LOGGER.exception('Error in GetTopology')
app.run(host='0.0.0.0', port=10060)