update from RIFT as of 696b75d2fe9fb046261b08c616f1bcf6c0b54a9b second try
[osm/SO.git] / rwcal / rift / cal / server / app.py
1 """
2 #
3 # Copyright 2016 RIFT.IO Inc
4 #
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
8 #
9 # http://www.apache.org/licenses/LICENSE-2.0
10 #
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.
16 #
17
18 @file app.py
19 @author Austin Cormier(austin.cormier@riftio.com)
20 @author Varun Prasad(varun.prasad@riftio.com)
21 @date 2016-06-14
22 """
23
24 import asyncio
25 import collections
26 import concurrent.futures
27 import logging
28 import sys
29
30 import tornado
31 import tornado.httpserver
32 import tornado.web
33 import tornado.platform.asyncio
34
35 import gi
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 (
41 RwCal,
42 RwcalYang,
43 RwTypes,
44 )
45
46 logger = logging.getLogger(__name__)
47
48 if sys.version_info < (3, 4, 4):
49 asyncio.ensure_future = asyncio.async
50
51
52 class CalCallFailure(Exception):
53 pass
54
55
56 class RPCParam(object):
57 def __init__(self, key, proto_type=None):
58 self.key = key
59 self.proto_type = proto_type
60
61
62 class CalRequestHandler(tornado.web.RequestHandler):
63 def initialize(self, log, loop, cal, account, executor, cal_method,
64 input_params=None, output_params=None):
65 self.log = log
66 self.loop = loop
67 self.cal = cal
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
73
74 def wrap_status_fn(self, fn, *args, **kwargs):
75
76 ret = fn(*args, **kwargs)
77 if not isinstance(ret, collections.Iterable):
78 ret = [ret]
79
80 rw_status = ret[0]
81
82 if type(rw_status) is RwCal.RwcalStatus:
83 rw_status = rw_status.status
84
85 if type(rw_status) != RwTypes.RwStatus:
86 raise ValueError("First return value of %s function was not a RwStatus" %
87 fn.__name__)
88
89 if rw_status != RwTypes.RwStatus.SUCCESS:
90 msg = "%s returned %s" % (fn.__name__, str(rw_status))
91 self.log.error(msg)
92 raise CalCallFailure(msg)
93
94 return ret[1:]
95
96 @tornado.gen.coroutine
97 def post(self):
98 def body_to_cal_args():
99 cal_args = []
100 if self.input_params is None:
101 return cal_args
102
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)))
107
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
112
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)
117
118 cal_args.append(value)
119
120 return cal_args
121
122 def cal_return_vals(return_vals):
123 output_params = self.output_params
124 if output_params is None:
125 output_params = []
126
127 if len(return_vals) != len(output_params):
128 raise ValueError("Got %s return values. Expected %s",
129 len(return_vals), len(output_params))
130
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]
136
137 if proto_type is not None:
138 output_value = output_value.as_dict()
139
140 return_val = {
141 "key": key,
142 "value": output_value,
143 "proto_type": proto_type,
144 }
145
146 write_dict["return_vals"].append(return_val)
147
148 return write_dict
149
150 @asyncio.coroutine
151 def handle_request():
152 self.log.debug("Got cloudsimproxy POST request: %s", self.request.body)
153 cal_args = body_to_cal_args()
154
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(
158 self.executor,
159 self.wrap_status_fn,
160 getattr(self.cal, self.cal_method),
161 self.account,
162 *cal_args
163 )
164
165 return cal_return_vals(return_vals)
166
167 f = asyncio.ensure_future(handle_request(), loop=self.loop)
168 return_dict = yield tornado.platform.asyncio.to_tornado_future(f)
169
170 self.log.debug("Responding to %s RPC with %s", self.cal_method, return_dict)
171
172 self.clear()
173 self.set_status(200)
174 self.write(return_dict)
175
176
177 class CalProxyApp(tornado.web.Application):
178 def __init__(self, log, loop, cal_interface, cal_account):
179 self.log = log
180 self.loop = loop
181 self.cal = cal_interface
182 self.account = cal_account
183
184 attrs = dict(
185 log=self.log,
186 loop=self.loop,
187 cal=cal_interface,
188 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)
192 )
193
194 def mk_attrs(cal_method, input_params=None, output_params=None):
195 new_attrs = {
196 "cal_method": cal_method,
197 "input_params": input_params,
198 "output_params": output_params
199 }
200 new_attrs.update(attrs)
201
202 return new_attrs
203
204 super(CalProxyApp, self).__init__([
205 (r"/api/get_image_list", CalRequestHandler,
206 mk_attrs(
207 cal_method="get_image_list",
208 output_params=[
209 RPCParam("images", "VimResources"),
210 ]
211 ),
212 ),
213
214 (r"/api/create_image", CalRequestHandler,
215 mk_attrs(
216 cal_method="create_image",
217 input_params=[
218 RPCParam("image", "ImageInfoItem"),
219 ],
220 output_params=[
221 RPCParam("image_id"),
222 ]
223 ),
224 ),
225
226 (r"/api/delete_image", CalRequestHandler,
227 mk_attrs(
228 cal_method="delete_image",
229 input_params=[
230 RPCParam("image_id"),
231 ],
232 ),
233 ),
234
235 (r"/api/get_image", CalRequestHandler,
236 mk_attrs(
237 cal_method="get_image",
238 input_params=[
239 RPCParam("image_id"),
240 ],
241 output_params=[
242 RPCParam("image", "ImageInfoItem"),
243 ],
244 ),
245 ),
246
247 (r"/api/create_vm", CalRequestHandler,
248 mk_attrs(
249 cal_method="create_vm",
250 input_params=[
251 RPCParam("vm", "VMInfoItem"),
252 ],
253 output_params=[
254 RPCParam("vm_id"),
255 ],
256 ),
257 ),
258
259 (r"/api/start_vm", CalRequestHandler,
260 mk_attrs(
261 cal_method="start_vm",
262 input_params=[
263 RPCParam("vm_id"),
264 ],
265 ),
266 ),
267
268 (r"/api/stop_vm", CalRequestHandler,
269 mk_attrs(
270 cal_method="stop_vm",
271 input_params=[
272 RPCParam("vm_id"),
273 ],
274 ),
275 ),
276
277 (r"/api/delete_vm", CalRequestHandler,
278 mk_attrs(
279 cal_method="delete_vm",
280 input_params=[
281 RPCParam("vm_id"),
282 ],
283 ),
284 ),
285
286 (r"/api/reboot_vm", CalRequestHandler,
287 mk_attrs(
288 cal_method="reboot_vm",
289 input_params=[
290 RPCParam("vm_id"),
291 ],
292 ),
293 ),
294
295 (r"/api/get_vm_list", CalRequestHandler,
296 mk_attrs(
297 cal_method="get_vm_list",
298 output_params=[
299 RPCParam("vms", "VimResources"),
300 ],
301 ),
302 ),
303
304 (r"/api/get_vm", CalRequestHandler,
305 mk_attrs(
306 cal_method="get_vm",
307 input_params=[
308 RPCParam("vm_id"),
309 ],
310 output_params=[
311 RPCParam("vms", "VMInfoItem"),
312 ],
313 ),
314 ),
315
316 (r"/api/create_flavor", CalRequestHandler,
317 mk_attrs(
318 cal_method="create_flavor",
319 input_params=[
320 RPCParam("flavor", "FlavorInfoItem"),
321 ],
322 output_params=[
323 RPCParam("flavor_id"),
324 ],
325 ),
326 ),
327
328 (r"/api/delete_flavor", CalRequestHandler,
329 mk_attrs(
330 cal_method="delete_flavor",
331 input_params=[
332 RPCParam("flavor_id"),
333 ],
334 ),
335 ),
336
337 (r"/api/get_flavor_list", CalRequestHandler,
338 mk_attrs(
339 cal_method="get_flavor_list",
340 output_params=[
341 RPCParam("flavors", "VimResources"),
342 ],
343 ),
344 ),
345
346 (r"/api/get_flavor", CalRequestHandler,
347 mk_attrs(
348 cal_method="get_flavor",
349 input_params=[
350 RPCParam("flavor_id"),
351 ],
352 output_params=[
353 RPCParam("flavor", "FlavorInfoItem"),
354 ],
355 ),
356 ),
357
358 (r"/api/create_network", CalRequestHandler,
359 mk_attrs(
360 cal_method="create_network",
361 input_params=[
362 RPCParam("network", "NetworkInfoItem"),
363 ],
364 output_params=[
365 RPCParam("network_id"),
366 ],
367 ),
368 ),
369
370 (r"/api/delete_network", CalRequestHandler,
371 mk_attrs(
372 cal_method="delete_network",
373 input_params=[
374 RPCParam("network_id"),
375 ],
376 ),
377 ),
378
379 (r"/api/get_network", CalRequestHandler,
380 mk_attrs(
381 cal_method="get_network",
382 input_params=[
383 RPCParam("network_id"),
384 ],
385 output_params=[
386 RPCParam("network", "NetworkInfoItem"),
387 ],
388 ),
389 ),
390
391 (r"/api/get_network_list", CalRequestHandler,
392 mk_attrs(
393 cal_method="get_network_list",
394 output_params=[
395 RPCParam("networks", "VimResources"),
396 ],
397 ),
398 ),
399
400 (r"/api/get_management_network", CalRequestHandler,
401 mk_attrs(
402 cal_method="get_management_network",
403 output_params=[
404 RPCParam("network", "NetworkInfoItem"),
405 ],
406 ),
407 ),
408
409 (r"/api/create_port", CalRequestHandler,
410 mk_attrs(
411 cal_method="create_port",
412 input_params=[
413 RPCParam("port", "PortInfoItem"),
414 ],
415 output_params=[
416 RPCParam("port_id"),
417 ],
418 ),
419 ),
420
421 (r"/api/delete_port", CalRequestHandler,
422 mk_attrs(
423 cal_method="delete_port",
424 input_params=[
425 RPCParam("port_id"),
426 ],
427 ),
428 ),
429
430 (r"/api/get_port", CalRequestHandler,
431 mk_attrs(
432 cal_method="get_port",
433 input_params=[
434 RPCParam("port_id"),
435 ],
436 output_params=[
437 RPCParam("port", "PortInfoItem"),
438 ],
439 ),
440 ),
441
442 (r"/api/get_port_list", CalRequestHandler,
443 mk_attrs(
444 cal_method="get_port_list",
445 output_params=[
446 RPCParam("ports", "VimResources"),
447 ],
448 ),
449 ),
450
451 (r"/api/create_virtual_link", CalRequestHandler,
452 mk_attrs(
453 cal_method="create_virtual_link",
454 input_params=[
455 RPCParam("link_params", "VirtualLinkReqParams"),
456 ],
457 output_params=[
458 RPCParam("link_id"),
459 ],
460 ),
461 ),
462
463 (r"/api/delete_virtual_link", CalRequestHandler,
464 mk_attrs(
465 cal_method="delete_virtual_link",
466 input_params=[
467 RPCParam("link_id"),
468 ],
469 ),
470 ),
471
472 (r"/api/get_virtual_link", CalRequestHandler,
473 mk_attrs(
474 cal_method="get_virtual_link",
475 input_params=[
476 RPCParam("link_id"),
477 ],
478 output_params=[
479 RPCParam("response", "VirtualLinkInfoParams"),
480 ],
481 ),
482 ),
483
484 (r"/api/get_virtual_link_by_name", CalRequestHandler,
485 mk_attrs(
486 cal_method="get_virtual_link_by_name",
487 input_params=[
488 RPCParam("link_name"),
489 ],
490 output_params=[
491 RPCParam("response", "VirtualLinkInfoParams"),
492 ],
493 ),
494 ),
495
496 (r"/api/get_virtual_link_list", CalRequestHandler,
497 mk_attrs(
498 cal_method="get_virtual_link_list",
499 output_params=[
500 RPCParam("resources", "VNFResources"),
501 ],
502 ),
503 ),
504
505 (r"/api/create_vdu", CalRequestHandler,
506 mk_attrs(
507 cal_method="create_vdu",
508 input_params=[
509 RPCParam("vdu_params", "VDUInitParams"),
510 ],
511 output_params=[
512 RPCParam("vdu_id"),
513 ],
514 ),
515 ),
516
517 (r"/api/modify_vdu", CalRequestHandler,
518 mk_attrs(
519 cal_method="modify_vdu",
520 input_params=[
521 RPCParam("vdu_params", "VDUModifyParams"),
522 ],
523 ),
524 ),
525
526 (r"/api/delete_vdu", CalRequestHandler,
527 mk_attrs(
528 cal_method="delete_vdu",
529 input_params=[
530 RPCParam("vdu_id"),
531 ],
532 ),
533 ),
534
535 (r"/api/get_vdu", CalRequestHandler,
536 mk_attrs(
537 cal_method="get_vdu",
538 input_params=[
539 RPCParam("vdu_id"),
540 ],
541 output_params=[
542 RPCParam("response", "VDUInfoParams"),
543 ],
544 ),
545 ),
546
547 (r"/api/get_vdu_list", CalRequestHandler,
548 mk_attrs(
549 cal_method="get_vdu_list",
550 output_params=[
551 RPCParam("resources", "VNFResources"),
552 ],
553 ),
554 )
555 ])