3 # Copyright 2016 RIFT.IO Inc
5 # Licensed under the Apache License, Version 2.0 (the "License");
6 # you may not use this file except in compliance with the License.
7 # You may obtain a copy of the License at
9 # http://www.apache.org/licenses/LICENSE-2.0
11 # Unless required by applicable law or agreed to in writing, software
12 # distributed under the License is distributed on an "AS IS" BASIS,
13 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 # See the License for the specific language governing permissions and
15 # limitations under the License.
19 @author Austin Cormier(austin.cormier@riftio.com)
20 @author Varun Prasad(varun.prasad@riftio.com)
26 import concurrent
.futures
31 import tornado
.httpserver
33 import tornado
.platform
.asyncio
36 gi
.require_version('RwcalYang', '1.0')
37 gi
.require_version('RwCal', '1.0')
38 gi
.require_version('RwLog', '1.0')
39 gi
.require_version('RwTypes', '1.0')
40 from gi
.repository
import (
46 logger
= logging
.getLogger(__name__
)
48 if sys
.version_info
< (3, 4, 4):
49 asyncio
.ensure_future
= asyncio
.async
52 class CalCallFailure(Exception):
56 class RPCParam(object):
57 def __init__(self
, key
, proto_type
=None):
59 self
.proto_type
= proto_type
62 class CalRequestHandler(tornado
.web
.RequestHandler
):
63 def initialize(self
, log
, loop
, cal
, account
, executor
, cal_method
,
64 input_params
=None, output_params
=None):
68 self
.account
= account
69 self
.executor
= executor
70 self
.cal_method
= cal_method
71 self
.input_params
= input_params
72 self
.output_params
= output_params
74 def wrap_status_fn(self
, fn
, *args
, **kwargs
):
76 ret
= fn(*args
, **kwargs
)
77 if not isinstance(ret
, collections
.Iterable
):
82 if type(rw_status
) is RwCal
.RwcalStatus
:
83 rw_status
= rw_status
.status
85 if type(rw_status
) != RwTypes
.RwStatus
:
86 raise ValueError("First return value of %s function was not a RwStatus" %
89 if rw_status
!= RwTypes
.RwStatus
.SUCCESS
:
90 msg
= "%s returned %s" % (fn
.__name
__, str(rw_status
))
92 raise CalCallFailure(msg
)
96 @tornado.gen
.coroutine
98 def body_to_cal_args():
100 if self
.input_params
is None:
103 input_dict
= tornado
.escape
.json_decode(self
.request
.body
)
104 if len(input_dict
) != len(self
.input_params
):
105 raise ValueError("Got %s parameters, expected %s" %
106 (len(input_dict
), len(self
.input_params
)))
108 for input_param
in self
.input_params
:
109 key
= input_param
.key
110 value
= input_dict
[key
]
111 proto_type
= input_param
.proto_type
113 if proto_type
is not None:
114 proto_cls
= getattr(RwcalYang
, proto_type
)
115 self
.log
.debug("Deserializing into %s type", proto_cls
)
116 value
= proto_cls
.from_dict(value
)
118 cal_args
.append(value
)
122 def cal_return_vals(return_vals
):
123 output_params
= self
.output_params
124 if output_params
is None:
127 if len(return_vals
) != len(output_params
):
128 raise ValueError("Got %s return values. Expected %s",
129 len(return_vals
), len(output_params
))
131 write_dict
= {"return_vals": []}
132 for i
, output_param
in enumerate(output_params
):
133 key
= output_param
.key
134 proto_type
= output_param
.proto_type
135 output_value
= return_vals
[i
]
137 if proto_type
is not None:
138 output_value
= output_value
.as_dict()
142 "value": output_value
,
143 "proto_type": proto_type
,
146 write_dict
["return_vals"].append(return_val
)
151 def handle_request():
152 self
.log
.debug("Got cloudsimproxy POST request: %s", self
.request
.body
)
153 cal_args
= body_to_cal_args()
155 # Execute the CAL request in a seperate thread to prevent
156 # blocking the main loop.
157 return_vals
= yield from self
.loop
.run_in_executor(
160 getattr(self
.cal
, self
.cal_method
),
165 return cal_return_vals(return_vals
)
167 f
= asyncio
.ensure_future(handle_request(), loop
=self
.loop
)
168 return_dict
= yield tornado
.platform
.asyncio
.to_tornado_future(f
)
170 self
.log
.debug("Responding to %s RPC with %s", self
.cal_method
, return_dict
)
174 self
.write(return_dict
)
177 class CalProxyApp(tornado
.web
.Application
):
178 def __init__(self
, log
, loop
, cal_interface
, cal_account
):
181 self
.cal
= cal_interface
182 self
.account
= cal_account
189 # Create an executor with a single worker to prevent
190 # having multiple simulteneous calls into CAL (which is not threadsafe)
191 executor
=concurrent
.futures
.ThreadPoolExecutor(1)
194 def mk_attrs(cal_method
, input_params
=None, output_params
=None):
196 "cal_method": cal_method
,
197 "input_params": input_params
,
198 "output_params": output_params
200 new_attrs
.update(attrs
)
204 super(CalProxyApp
, self
).__init
__([
205 (r
"/api/get_image_list", CalRequestHandler
,
207 cal_method
="get_image_list",
209 RPCParam("images", "VimResources"),
214 (r
"/api/create_image", CalRequestHandler
,
216 cal_method
="create_image",
218 RPCParam("image", "ImageInfoItem"),
221 RPCParam("image_id"),
226 (r
"/api/delete_image", CalRequestHandler
,
228 cal_method
="delete_image",
230 RPCParam("image_id"),
235 (r
"/api/get_image", CalRequestHandler
,
237 cal_method
="get_image",
239 RPCParam("image_id"),
242 RPCParam("image", "ImageInfoItem"),
247 (r
"/api/create_vm", CalRequestHandler
,
249 cal_method
="create_vm",
251 RPCParam("vm", "VMInfoItem"),
259 (r
"/api/start_vm", CalRequestHandler
,
261 cal_method
="start_vm",
268 (r
"/api/stop_vm", CalRequestHandler
,
270 cal_method
="stop_vm",
277 (r
"/api/delete_vm", CalRequestHandler
,
279 cal_method
="delete_vm",
286 (r
"/api/reboot_vm", CalRequestHandler
,
288 cal_method
="reboot_vm",
295 (r
"/api/get_vm_list", CalRequestHandler
,
297 cal_method
="get_vm_list",
299 RPCParam("vms", "VimResources"),
304 (r
"/api/get_vm", CalRequestHandler
,
311 RPCParam("vms", "VMInfoItem"),
316 (r
"/api/create_flavor", CalRequestHandler
,
318 cal_method
="create_flavor",
320 RPCParam("flavor", "FlavorInfoItem"),
323 RPCParam("flavor_id"),
328 (r
"/api/delete_flavor", CalRequestHandler
,
330 cal_method
="delete_flavor",
332 RPCParam("flavor_id"),
337 (r
"/api/get_flavor_list", CalRequestHandler
,
339 cal_method
="get_flavor_list",
341 RPCParam("flavors", "VimResources"),
346 (r
"/api/get_flavor", CalRequestHandler
,
348 cal_method
="get_flavor",
350 RPCParam("flavor_id"),
353 RPCParam("flavor", "FlavorInfoItem"),
358 (r
"/api/create_network", CalRequestHandler
,
360 cal_method
="create_network",
362 RPCParam("network", "NetworkInfoItem"),
365 RPCParam("network_id"),
370 (r
"/api/delete_network", CalRequestHandler
,
372 cal_method
="delete_network",
374 RPCParam("network_id"),
379 (r
"/api/get_network", CalRequestHandler
,
381 cal_method
="get_network",
383 RPCParam("network_id"),
386 RPCParam("network", "NetworkInfoItem"),
391 (r
"/api/get_network_list", CalRequestHandler
,
393 cal_method
="get_network_list",
395 RPCParam("networks", "VimResources"),
400 (r
"/api/get_management_network", CalRequestHandler
,
402 cal_method
="get_management_network",
404 RPCParam("network", "NetworkInfoItem"),
409 (r
"/api/create_port", CalRequestHandler
,
411 cal_method
="create_port",
413 RPCParam("port", "PortInfoItem"),
421 (r
"/api/delete_port", CalRequestHandler
,
423 cal_method
="delete_port",
430 (r
"/api/get_port", CalRequestHandler
,
432 cal_method
="get_port",
437 RPCParam("port", "PortInfoItem"),
442 (r
"/api/get_port_list", CalRequestHandler
,
444 cal_method
="get_port_list",
446 RPCParam("ports", "VimResources"),
451 (r
"/api/create_virtual_link", CalRequestHandler
,
453 cal_method
="create_virtual_link",
455 RPCParam("link_params", "VirtualLinkReqParams"),
463 (r
"/api/delete_virtual_link", CalRequestHandler
,
465 cal_method
="delete_virtual_link",
472 (r
"/api/get_virtual_link", CalRequestHandler
,
474 cal_method
="get_virtual_link",
479 RPCParam("response", "VirtualLinkInfoParams"),
484 (r
"/api/get_virtual_link_list", CalRequestHandler
,
486 cal_method
="get_virtual_link_list",
488 RPCParam("resources", "VNFResources"),
493 (r
"/api/create_vdu", CalRequestHandler
,
495 cal_method
="create_vdu",
497 RPCParam("vdu_params", "VDUInitParams"),
505 (r
"/api/modify_vdu", CalRequestHandler
,
507 cal_method
="modify_vdu",
509 RPCParam("vdu_params", "VDUModifyParams"),
514 (r
"/api/delete_vdu", CalRequestHandler
,
516 cal_method
="delete_vdu",
523 (r
"/api/get_vdu", CalRequestHandler
,
525 cal_method
="get_vdu",
530 RPCParam("response", "VDUInfoParams"),
535 (r
"/api/get_vdu_list", CalRequestHandler
,
537 cal_method
="get_vdu_list",
539 RPCParam("resources", "VNFResources"),