X-Git-Url: https://osm.etsi.org/gitweb/?a=blobdiff_plain;f=rwcal%2Frift%2Fcal%2Fserver%2Fapp.py;fp=rwcal%2Frift%2Fcal%2Fserver%2Fapp.py;h=355d65336d7b1729f122f9e787e904ce4bbde9ec;hb=6f07e6f33f751ab4ffe624f6037f887b243bece2;hp=0000000000000000000000000000000000000000;hpb=72a563886272088feb7cb52e4aafbe6d2c580ff9;p=osm%2FSO.git diff --git a/rwcal/rift/cal/server/app.py b/rwcal/rift/cal/server/app.py new file mode 100644 index 00000000..355d6533 --- /dev/null +++ b/rwcal/rift/cal/server/app.py @@ -0,0 +1,543 @@ +""" +# +# Copyright 2016 RIFT.IO Inc +# +# 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. +# + +@file app.py +@author Austin Cormier(austin.cormier@riftio.com) +@author Varun Prasad(varun.prasad@riftio.com) +@date 2016-06-14 +""" + +import asyncio +import collections +import concurrent.futures +import logging +import sys + +import tornado +import tornado.httpserver +import tornado.web +import tornado.platform.asyncio + +import gi +gi.require_version('RwcalYang', '1.0') +gi.require_version('RwCal', '1.0') +gi.require_version('RwLog', '1.0') +gi.require_version('RwTypes', '1.0') +from gi.repository import ( + RwCal, + RwcalYang, + RwTypes, +) + +logger = logging.getLogger(__name__) + +if sys.version_info < (3, 4, 4): + asyncio.ensure_future = asyncio.async + + +class CalCallFailure(Exception): + pass + + +class RPCParam(object): + def __init__(self, key, proto_type=None): + self.key = key + self.proto_type = proto_type + + +class CalRequestHandler(tornado.web.RequestHandler): + def initialize(self, log, loop, cal, account, executor, cal_method, + input_params=None, output_params=None): + self.log = log + self.loop = loop + self.cal = cal + self.account = account + self.executor = executor + self.cal_method = cal_method + self.input_params = input_params + self.output_params = output_params + + def wrap_status_fn(self, fn, *args, **kwargs): + + ret = fn(*args, **kwargs) + if not isinstance(ret, collections.Iterable): + ret = [ret] + + rw_status = ret[0] + + if type(rw_status) is RwCal.RwcalStatus: + rw_status = rw_status.status + + if type(rw_status) != RwTypes.RwStatus: + raise ValueError("First return value of %s function was not a RwStatus" % + fn.__name__) + + if rw_status != RwTypes.RwStatus.SUCCESS: + msg = "%s returned %s" % (fn.__name__, str(rw_status)) + self.log.error(msg) + raise CalCallFailure(msg) + + return ret[1:] + + @tornado.gen.coroutine + def post(self): + def body_to_cal_args(): + cal_args = [] + if self.input_params is None: + return cal_args + + input_dict = tornado.escape.json_decode(self.request.body) + if len(input_dict) != len(self.input_params): + raise ValueError("Got %s parameters, expected %s" % + (len(input_dict), len(self.input_params))) + + for input_param in self.input_params: + key = input_param.key + value = input_dict[key] + proto_type = input_param.proto_type + + if proto_type is not None: + proto_cls = getattr(RwcalYang, proto_type) + self.log.debug("Deserializing into %s type", proto_cls) + value = proto_cls.from_dict(value) + + cal_args.append(value) + + return cal_args + + def cal_return_vals(return_vals): + output_params = self.output_params + if output_params is None: + output_params = [] + + if len(return_vals) != len(output_params): + raise ValueError("Got %s return values. Expected %s", + len(return_vals), len(output_params)) + + write_dict = {"return_vals": []} + for i, output_param in enumerate(output_params): + key = output_param.key + proto_type = output_param.proto_type + output_value = return_vals[i] + + if proto_type is not None: + output_value = output_value.as_dict() + + return_val = { + "key": key, + "value": output_value, + "proto_type": proto_type, + } + + write_dict["return_vals"].append(return_val) + + return write_dict + + @asyncio.coroutine + def handle_request(): + self.log.debug("Got cloudsimproxy POST request: %s", self.request.body) + cal_args = body_to_cal_args() + + # Execute the CAL request in a seperate thread to prevent + # blocking the main loop. + return_vals = yield from self.loop.run_in_executor( + self.executor, + self.wrap_status_fn, + getattr(self.cal, self.cal_method), + self.account, + *cal_args + ) + + return cal_return_vals(return_vals) + + f = asyncio.ensure_future(handle_request(), loop=self.loop) + return_dict = yield tornado.platform.asyncio.to_tornado_future(f) + + self.log.debug("Responding to %s RPC with %s", self.cal_method, return_dict) + + self.clear() + self.set_status(200) + self.write(return_dict) + + +class CalProxyApp(tornado.web.Application): + def __init__(self, log, loop, cal_interface, cal_account): + self.log = log + self.loop = loop + self.cal = cal_interface + self.account = cal_account + + attrs = dict( + log=self.log, + loop=self.loop, + cal=cal_interface, + account=cal_account, + # Create an executor with a single worker to prevent + # having multiple simulteneous calls into CAL (which is not threadsafe) + executor=concurrent.futures.ThreadPoolExecutor(1) + ) + + def mk_attrs(cal_method, input_params=None, output_params=None): + new_attrs = { + "cal_method": cal_method, + "input_params": input_params, + "output_params": output_params + } + new_attrs.update(attrs) + + return new_attrs + + super(CalProxyApp, self).__init__([ + (r"/api/get_image_list", CalRequestHandler, + mk_attrs( + cal_method="get_image_list", + output_params=[ + RPCParam("images", "VimResources"), + ] + ), + ), + + (r"/api/create_image", CalRequestHandler, + mk_attrs( + cal_method="create_image", + input_params=[ + RPCParam("image", "ImageInfoItem"), + ], + output_params=[ + RPCParam("image_id"), + ] + ), + ), + + (r"/api/delete_image", CalRequestHandler, + mk_attrs( + cal_method="delete_image", + input_params=[ + RPCParam("image_id"), + ], + ), + ), + + (r"/api/get_image", CalRequestHandler, + mk_attrs( + cal_method="get_image", + input_params=[ + RPCParam("image_id"), + ], + output_params=[ + RPCParam("image", "ImageInfoItem"), + ], + ), + ), + + (r"/api/create_vm", CalRequestHandler, + mk_attrs( + cal_method="create_vm", + input_params=[ + RPCParam("vm", "VMInfoItem"), + ], + output_params=[ + RPCParam("vm_id"), + ], + ), + ), + + (r"/api/start_vm", CalRequestHandler, + mk_attrs( + cal_method="start_vm", + input_params=[ + RPCParam("vm_id"), + ], + ), + ), + + (r"/api/stop_vm", CalRequestHandler, + mk_attrs( + cal_method="stop_vm", + input_params=[ + RPCParam("vm_id"), + ], + ), + ), + + (r"/api/delete_vm", CalRequestHandler, + mk_attrs( + cal_method="delete_vm", + input_params=[ + RPCParam("vm_id"), + ], + ), + ), + + (r"/api/reboot_vm", CalRequestHandler, + mk_attrs( + cal_method="reboot_vm", + input_params=[ + RPCParam("vm_id"), + ], + ), + ), + + (r"/api/get_vm_list", CalRequestHandler, + mk_attrs( + cal_method="get_vm_list", + output_params=[ + RPCParam("vms", "VimResources"), + ], + ), + ), + + (r"/api/get_vm", CalRequestHandler, + mk_attrs( + cal_method="get_vm", + input_params=[ + RPCParam("vm_id"), + ], + output_params=[ + RPCParam("vms", "VMInfoItem"), + ], + ), + ), + + (r"/api/create_flavor", CalRequestHandler, + mk_attrs( + cal_method="create_flavor", + input_params=[ + RPCParam("flavor", "FlavorInfoItem"), + ], + output_params=[ + RPCParam("flavor_id"), + ], + ), + ), + + (r"/api/delete_flavor", CalRequestHandler, + mk_attrs( + cal_method="delete_flavor", + input_params=[ + RPCParam("flavor_id"), + ], + ), + ), + + (r"/api/get_flavor_list", CalRequestHandler, + mk_attrs( + cal_method="get_flavor_list", + output_params=[ + RPCParam("flavors", "VimResources"), + ], + ), + ), + + (r"/api/get_flavor", CalRequestHandler, + mk_attrs( + cal_method="get_flavor", + input_params=[ + RPCParam("flavor_id"), + ], + output_params=[ + RPCParam("flavor", "FlavorInfoItem"), + ], + ), + ), + + (r"/api/create_network", CalRequestHandler, + mk_attrs( + cal_method="create_network", + input_params=[ + RPCParam("network", "NetworkInfoItem"), + ], + output_params=[ + RPCParam("network_id"), + ], + ), + ), + + (r"/api/delete_network", CalRequestHandler, + mk_attrs( + cal_method="delete_network", + input_params=[ + RPCParam("network_id"), + ], + ), + ), + + (r"/api/get_network", CalRequestHandler, + mk_attrs( + cal_method="get_network", + input_params=[ + RPCParam("network_id"), + ], + output_params=[ + RPCParam("network", "NetworkInfoItem"), + ], + ), + ), + + (r"/api/get_network_list", CalRequestHandler, + mk_attrs( + cal_method="get_network_list", + output_params=[ + RPCParam("networks", "VimResources"), + ], + ), + ), + + (r"/api/get_management_network", CalRequestHandler, + mk_attrs( + cal_method="get_management_network", + output_params=[ + RPCParam("network", "NetworkInfoItem"), + ], + ), + ), + + (r"/api/create_port", CalRequestHandler, + mk_attrs( + cal_method="create_port", + input_params=[ + RPCParam("port", "PortInfoItem"), + ], + output_params=[ + RPCParam("port_id"), + ], + ), + ), + + (r"/api/delete_port", CalRequestHandler, + mk_attrs( + cal_method="delete_port", + input_params=[ + RPCParam("port_id"), + ], + ), + ), + + (r"/api/get_port", CalRequestHandler, + mk_attrs( + cal_method="get_port", + input_params=[ + RPCParam("port_id"), + ], + output_params=[ + RPCParam("port", "PortInfoItem"), + ], + ), + ), + + (r"/api/get_port_list", CalRequestHandler, + mk_attrs( + cal_method="get_port_list", + output_params=[ + RPCParam("ports", "VimResources"), + ], + ), + ), + + (r"/api/create_virtual_link", CalRequestHandler, + mk_attrs( + cal_method="create_virtual_link", + input_params=[ + RPCParam("link_params", "VirtualLinkReqParams"), + ], + output_params=[ + RPCParam("link_id"), + ], + ), + ), + + (r"/api/delete_virtual_link", CalRequestHandler, + mk_attrs( + cal_method="delete_virtual_link", + input_params=[ + RPCParam("link_id"), + ], + ), + ), + + (r"/api/get_virtual_link", CalRequestHandler, + mk_attrs( + cal_method="get_virtual_link", + input_params=[ + RPCParam("link_id"), + ], + output_params=[ + RPCParam("response", "VirtualLinkInfoParams"), + ], + ), + ), + + (r"/api/get_virtual_link_list", CalRequestHandler, + mk_attrs( + cal_method="get_virtual_link_list", + output_params=[ + RPCParam("resources", "VNFResources"), + ], + ), + ), + + (r"/api/create_vdu", CalRequestHandler, + mk_attrs( + cal_method="create_vdu", + input_params=[ + RPCParam("vdu_params", "VDUInitParams"), + ], + output_params=[ + RPCParam("vdu_id"), + ], + ), + ), + + (r"/api/modify_vdu", CalRequestHandler, + mk_attrs( + cal_method="modify_vdu", + input_params=[ + RPCParam("vdu_params", "VDUModifyParams"), + ], + ), + ), + + (r"/api/delete_vdu", CalRequestHandler, + mk_attrs( + cal_method="delete_vdu", + input_params=[ + RPCParam("vdu_id"), + ], + ), + ), + + (r"/api/get_vdu", CalRequestHandler, + mk_attrs( + cal_method="get_vdu", + input_params=[ + RPCParam("vdu_id"), + ], + output_params=[ + RPCParam("response", "VDUInfoParams"), + ], + ), + ), + + (r"/api/get_vdu_list", CalRequestHandler, + mk_attrs( + cal_method="get_vdu_list", + output_params=[ + RPCParam("resources", "VNFResources"), + ], + ), + ) + ])