blob: 355d65336d7b1729f122f9e787e904ce4bbde9ec [file] [log] [blame]
"""
#
# 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"),
],
),
)
])