RIFT OSM R1 Initial Submission
[osm/SO.git] / rwcal / rift / cal / server / app.py
diff --git a/rwcal/rift/cal/server/app.py b/rwcal/rift/cal/server/app.py
new file mode 100644 (file)
index 0000000..355d653
--- /dev/null
@@ -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"),
+                            ],
+                        ),
+                    )
+            ])