3 from opnfv_testapi.common import message
4 from opnfv_testapi.common import raises
5 from opnfv_testapi.handlers import base_handlers
6 import opnfv_testapi.models.scenario_models as models
7 from opnfv_testapi.tornado_swagger import swagger
10 class GenericScenarioHandler(base_handlers.GenericApiHandler):
11 def __init__(self, application, request, **kwargs):
12 super(GenericScenarioHandler, self).__init__(application,
15 self.table = self.db_scenarios
16 self.table_cls = models.Scenario
18 def set_query(self, locators):
21 for k, v in locators.iteritems():
24 elif k == 'installer':
25 elem_query["installer"] = v
27 elem_query["versions.version"] = v
29 elem_query["versions.projects.project"] = v
33 query['installers'] = {'$elemMatch': elem_query}
37 class ScenariosCLHandler(GenericScenarioHandler):
38 @swagger.operation(nickname="queryScenarios")
41 @description: Retrieve scenario(s).
42 @notes: Retrieve scenario(s)
43 Available filters for this request are :
44 - name : scenario name
46 GET /scenarios?name=scenario_1
47 @param name: scenario name
51 @param installer: installer type
52 @type installer: L{string}
54 @required installer: False
55 @param version: version
56 @type version: L{string}
58 @required version: False
59 @param project: project name
60 @type project: L{string}
62 @required project: False
63 @return 200: all scenarios satisfy queries,
64 empty list if no scenario is found
71 for k in self.request.query_arguments.keys():
72 v = self.get_query_argument(k)
74 elem_query["installer"] = v
76 elem_query["versions.version"] = v
78 elem_query["versions.projects.project"] = v
82 query['installers'] = {'$elemMatch': elem_query}
85 self._list(query=_set_query())
87 @swagger.operation(nickname="createScenario")
90 @description: create a new scenario by name
91 @param body: scenario to be created
92 @type body: L{ScenarioCreateRequest}
94 @rtype: L{CreateResponse}
95 @return 200: scenario is created.
96 @raise 403: scenario already exists
97 @raise 400: body or name not provided
100 return {'name': self.json_args.get('name')}
101 miss_fields = ['name']
102 self._create(miss_fields=miss_fields, query=query)
105 class ScenarioGURHandler(GenericScenarioHandler):
106 @swagger.operation(nickname='getScenarioByName')
109 @description: get a single scenario by name
111 @return 200: scenario exist
112 @raise 404: scenario not exist
114 self._get_one(query={'name': name})
117 @swagger.operation(nickname="updateScenarioName")
120 @description: update scenario, only rename is supported currently
121 @param body: fields to be updated
122 @type body: L{ScenarioUpdateRequest}
125 @return 200: update success
126 @raise 404: scenario not exist
127 @raise 403: nothing to update
129 query = {'name': name}
131 self._update(query=query, db_keys=db_keys)
133 @swagger.operation(nickname="deleteScenarioByName")
134 def delete(self, name):
136 @description: delete a scenario by name
137 @return 200: delete success
138 @raise 404: scenario not exist:
140 self._delete(query={'name': name})
143 class ScenarioUpdater(object):
144 def __init__(self, data, body=None,
145 installer=None, version=None, project=None):
148 self.installer = installer
149 self.version = version
150 self.project = project
152 def update(self, item, action):
154 ('scores', 'post'): self._update_requests_add_score,
155 ('trust_indicators', 'post'): self._update_requests_add_ti,
156 ('customs', 'post'): self._update_requests_add_customs,
157 ('customs', 'put'): self._update_requests_update_customs,
158 ('customs', 'delete'): self._update_requests_delete_customs,
159 ('projects', 'post'): self._update_requests_add_projects,
160 ('projects', 'put'): self._update_requests_update_projects,
161 ('projects', 'delete'): self._update_requests_delete_projects,
162 ('owner', 'put'): self._update_requests_change_owner,
163 ('versions', 'post'): self._update_requests_add_versions,
164 ('versions', 'put'): self._update_requests_update_versions,
165 ('versions', 'delete'): self._update_requests_delete_versions,
166 ('installers', 'post'): self._update_requests_add_installers,
167 ('installers', 'put'): self._update_requests_update_installers,
168 ('installers', 'delete'): self._update_requests_delete_installers,
170 updates[(item, action)](self.data)
172 return self.data.format()
174 def iter_installers(xstep):
175 @functools.wraps(xstep)
176 def magic(self, data):
177 [xstep(self, installer)
178 for installer in self._filter_installers(data.installers)]
181 def iter_versions(xstep):
182 @functools.wraps(xstep)
183 def magic(self, installer):
184 [xstep(self, version)
185 for version in (self._filter_versions(installer.versions))]
188 def iter_projects(xstep):
189 @functools.wraps(xstep)
190 def magic(self, version):
191 [xstep(self, project)
192 for project in (self._filter_projects(version.projects))]
198 def _update_requests_add_score(self, project):
199 project.scores.append(
200 models.ScenarioScore.from_dict(self.body))
205 def _update_requests_add_ti(self, project):
206 project.trust_indicators.append(
207 models.ScenarioTI.from_dict(self.body))
212 def _update_requests_add_customs(self, project):
213 project.customs = list(set(project.customs + self.body))
218 def _update_requests_update_customs(self, project):
219 project.customs = list(set(self.body))
224 def _update_requests_delete_customs(self, project):
225 project.customs = filter(
226 lambda f: f not in self.body,
231 def _update_requests_add_projects(self, version):
232 version.projects = self._update_with_body(models.ScenarioProject,
238 def _update_requests_update_projects(self, version):
239 version.projects = self._update_with_body(models.ScenarioProject,
245 def _update_requests_delete_projects(self, version):
246 version.projects = self._remove_projects(version.projects)
250 def _update_requests_change_owner(self, version):
251 version.owner = self.body.get('owner')
254 def _update_requests_add_versions(self, installer):
255 installer.versions = self._update_with_body(models.ScenarioVersion,
260 def _update_requests_update_versions(self, installer):
261 installer.versions = self._update_with_body(models.ScenarioVersion,
266 def _update_requests_delete_versions(self, installer):
267 installer.versions = self._remove_versions(installer.versions)
269 def _update_requests_add_installers(self, scenario):
270 scenario.installers = self._update_with_body(models.ScenarioInstaller,
274 def _update_requests_update_installers(self, scenario):
275 scenario.installers = self._update_with_body(models.ScenarioInstaller,
279 def _update_requests_delete_installers(self, scenario):
280 scenario.installers = self._remove_installers(scenario.installers)
282 def _update_with_body(self, clazz, field, withs):
285 for new in self.body:
287 format_new = clazz.from_dict_with_raise(new)
288 new_name = getattr(format_new, field)
289 if not any(getattr(o, field) == new_name for o in withs):
290 withs.append(format_new)
292 exists.append(new_name)
293 except Exception as error:
294 malformat.append(error.message)
296 raises.BadRequest(message.bad_format(malformat))
298 raises.Conflict(message.exist('{}s'.format(field), exists))
301 def _filter_installers(self, installers):
302 return self._filter('installer', installers)
304 def _remove_installers(self, installers):
305 return self._remove('installer', installers)
307 def _filter_versions(self, versions):
308 return self._filter('version', versions)
310 def _remove_versions(self, versions):
311 return self._remove('version', versions)
313 def _filter_projects(self, projects):
314 return self._filter('project', projects)
316 def _remove_projects(self, projects):
317 return self._remove('project', projects)
319 def _filter(self, item, items):
321 lambda f: getattr(f, item) == getattr(self, item),
324 def _remove(self, field, fields):
326 lambda f: getattr(f, field) not in self.body,
330 class GenericScenarioUpdateHandler(GenericScenarioHandler):
331 def __init__(self, application, request, **kwargs):
332 super(GenericScenarioUpdateHandler, self).__init__(application,
335 self.installer = None
341 def do_update(self, item, action, locators):
344 for k, v in locators.iteritems():
346 v = self.get_query_argument(k)
349 self.pure_update(query=self.set_query(locators=locators))
351 def _update_requests(self, data):
352 return ScenarioUpdater(data,
356 self.project).update(self.item, self.action)
359 class ScenarioScoresHandler(GenericScenarioUpdateHandler):
360 @swagger.operation(nickname="addScoreRecord")
361 def post(self, scenario):
363 @description: add a new score record
364 @notes: add a new score record to a project
365 POST /api/v1/scenarios/<scenario_name>/scores? \
366 installer=<installer_name>& \
367 version=<version_name>& \
368 project=<project_name>
369 @param body: score to be added
370 @type body: L{ScenarioScore}
372 @param installer: installer type
373 @type installer: L{string}
375 @required installer: True
376 @param version: version
377 @type version: L{string}
379 @required version: True
380 @param project: project name
381 @type project: L{string}
383 @required project: True
384 @return 200: score is created.
385 @raise 404: scenario/installer/version/project not existed
387 self.do_update('scores',
389 locators={'scenario': scenario,
395 class ScenarioTIsHandler(GenericScenarioUpdateHandler):
396 @swagger.operation(nickname="addTrustIndicatorRecord")
397 def post(self, scenario):
399 @description: add a new trust indicator record
400 @notes: add a new trust indicator record to a project
401 POST /api/v1/scenarios/<scenario_name>/trust_indicators? \
402 installer=<installer_name>& \
403 version=<version_name>& \
404 project=<project_name>
405 @param body: trust indicator to be added
406 @type body: L{ScenarioTI}
408 @param installer: installer type
409 @type installer: L{string}
411 @required installer: True
412 @param version: version
413 @type version: L{string}
415 @required version: True
416 @param project: project name
417 @type project: L{string}
419 @required project: True
420 @return 200: trust indicator is added.
421 @raise 404: scenario/installer/version/project not existed
423 self.do_update('trust_indicators',
425 locators={'scenario': scenario,
431 class ScenarioCustomsHandler(GenericScenarioUpdateHandler):
432 @swagger.operation(nickname="addCustomizedTestCases")
433 def post(self, scenario):
435 @description: add customized test cases
436 @notes: add several test cases to a project
437 POST /api/v1/scenarios/<scenario_name>/customs? \
438 installer=<installer_name>& \
439 version=<version_name>& \
440 project=<project_name>
441 @param body: test cases to be added
442 @type body: C{list} of L{string}
444 @param installer: installer type
445 @type installer: L{string}
447 @required installer: True
448 @param version: version
449 @type version: L{string}
451 @required version: True
452 @param project: project name
453 @type project: L{string}
455 @required project: True
456 @return 200: test cases are added.
457 @raise 404: scenario/installer/version/project not existed
459 self.do_update('customs',
461 locators={'scenario': scenario,
466 @swagger.operation(nickname="updateCustomizedTestCases")
467 def put(self, scenario):
469 @description: update customized test cases
470 @notes: substitute all the customized test cases
471 PUT /api/v1/scenarios/<scenario_name>/customs? \
472 installer=<installer_name>& \
473 version=<version_name>& \
474 project=<project_name>
475 @param body: new supported test cases
476 @type body: C{list} of L{string}
478 @param installer: installer type
479 @type installer: L{string}
481 @required installer: True
482 @param version: version
483 @type version: L{string}
485 @required version: True
486 @param project: project name
487 @type project: L{string}
489 @required project: True
490 @return 200: substitute test cases success.
491 @raise 404: scenario/installer/version/project not existed
493 self.do_update('customs',
495 locators={'scenario': scenario,
500 @swagger.operation(nickname="deleteCustomizedTestCases")
501 def delete(self, scenario):
503 @description: delete one or several customized test cases
504 @notes: delete one or some customized test cases
505 DELETE /api/v1/scenarios/<scenario_name>/customs? \
506 installer=<installer_name>& \
507 version=<version_name>& \
508 project=<project_name>
509 @param body: test case(s) to be deleted
510 @type body: C{list} of L{string}
512 @param installer: installer type
513 @type installer: L{string}
515 @required installer: True
516 @param version: version
517 @type version: L{string}
519 @required version: True
520 @param project: project name
521 @type project: L{string}
523 @required project: True
524 @return 200: delete test case(s) success.
525 @raise 404: scenario/installer/version/project not existed
527 self.do_update('customs',
529 locators={'scenario': scenario,
535 class ScenarioProjectsHandler(GenericScenarioUpdateHandler):
536 @swagger.operation(nickname="addProjectsUnderScenario")
537 def post(self, scenario):
539 @description: add projects to scenario
540 @notes: add one or multiple projects
541 POST /api/v1/scenarios/<scenario_name>/projects? \
542 installer=<installer_name>& \
543 version=<version_name>
544 @param body: projects to be added
545 @type body: C{list} of L{ScenarioProject}
547 @param installer: installer type
548 @type installer: L{string}
550 @required installer: True
551 @param version: version
552 @type version: L{string}
554 @required version: True
555 @return 200: projects are added.
556 @raise 400: bad schema
557 @raise 409: conflict, project already exists
558 @raise 404: scenario/installer/version not existed
560 self.do_update('projects',
562 locators={'scenario': scenario,
566 @swagger.operation(nickname="updateScenarioProjects")
567 def put(self, scenario):
569 @description: replace all projects
570 @notes: substitute all projects, delete existed ones with new provides
571 PUT /api/v1/scenarios/<scenario_name>/projects? \
572 installer=<installer_name>& \
573 version=<version_name>
574 @param body: new projects
575 @type body: C{list} of L{ScenarioProject}
577 @param installer: installer type
578 @type installer: L{string}
580 @required installer: True
581 @param version: version
582 @type version: L{string}
584 @required version: True
585 @return 200: replace projects success.
586 @raise 400: bad schema
587 @raise 404: scenario/installer/version not existed
589 self.do_update('projects',
591 locators={'scenario': scenario,
595 @swagger.operation(nickname="deleteProjectsUnderScenario")
596 def delete(self, scenario):
598 @description: delete one or multiple projects
599 @notes: delete one or multiple projects
600 DELETE /api/v1/scenarios/<scenario_name>/projects? \
601 installer=<installer_name>& \
602 version=<version_name>
603 @param body: projects(names) to be deleted
604 @type body: C{list} of L{string}
606 @param installer: installer type
607 @type installer: L{string}
609 @required installer: True
610 @param version: version
611 @type version: L{string}
613 @required version: True
614 @return 200: delete project(s) success.
615 @raise 404: scenario/installer/version not existed
617 self.do_update('projects',
619 locators={'scenario': scenario,
624 class ScenarioOwnerHandler(GenericScenarioUpdateHandler):
625 @swagger.operation(nickname="changeScenarioOwner")
626 def put(self, scenario):
628 @description: change scenario owner
629 @notes: substitute all projects, delete existed ones with new provides
630 PUT /api/v1/scenarios/<scenario_name>/owner? \
631 installer=<installer_name>& \
632 version=<version_name>
633 @param body: new owner
634 @type body: L{ScenarioChangeOwnerRequest}
636 @param installer: installer type
637 @type installer: L{string}
639 @required installer: True
640 @param version: version
641 @type version: L{string}
643 @required version: True
644 @return 200: change owner success.
645 @raise 404: scenario/installer/version not existed
647 self.do_update('owner',
649 locators={'scenario': scenario,
654 class ScenarioVersionsHandler(GenericScenarioUpdateHandler):
655 @swagger.operation(nickname="addVersionsUnderScenario")
656 def post(self, scenario):
658 @description: add versions to scenario
659 @notes: add one or multiple versions
660 POST /api/v1/scenarios/<scenario_name>/versions? \
661 installer=<installer_name>
662 @param body: versions to be added
663 @type body: C{list} of L{ScenarioVersion}
665 @param installer: installer type
666 @type installer: L{string}
668 @required installer: True
669 @return 200: versions are added.
670 @raise 400: bad schema
671 @raise 409: conflict, version already exists
672 @raise 404: scenario/installer not exist
674 self.do_update('versions',
676 locators={'scenario': scenario,
679 @swagger.operation(nickname="updateVersionsUnderScenario")
680 def put(self, scenario):
682 @description: replace all versions
683 @notes: substitute all versions as a totality
684 PUT /api/v1/scenarios/<scenario_name>/versions? \
685 installer=<installer_name>
686 @param body: new versions
687 @type body: C{list} of L{ScenarioVersion}
689 @param installer: installer type
690 @type installer: L{string}
692 @required installer: True
693 @return 200: replace versions success.
694 @raise 400: bad schema
695 @raise 404: scenario/installer not exist
697 self.do_update('versions',
699 locators={'scenario': scenario,
702 @swagger.operation(nickname="deleteVersionsUnderScenario")
703 def delete(self, scenario):
705 @description: delete one or multiple versions
706 @notes: delete one or multiple versions
707 DELETE /api/v1/scenarios/<scenario_name>/versions? \
708 installer=<installer_name>
709 @param body: versions(names) to be deleted
710 @type body: C{list} of L{string}
712 @param installer: installer type
713 @type installer: L{string}
715 @required installer: True
716 @return 200: delete versions success.
717 @raise 404: scenario/installer not exist
719 self.do_update('versions',
721 locators={'scenario': scenario,
725 class ScenarioInstallersHandler(GenericScenarioUpdateHandler):
726 @swagger.operation(nickname="addInstallersUnderScenario")
727 def post(self, scenario):
729 @description: add installers to scenario
730 @notes: add one or multiple installers
731 POST /api/v1/scenarios/<scenario_name>/installers
732 @param body: installers to be added
733 @type body: C{list} of L{ScenarioInstaller}
735 @return 200: installers are added.
736 @raise 400: bad schema
737 @raise 409: conflict, installer already exists
738 @raise 404: scenario not exist
740 self.do_update('installers',
742 locators={'scenario': scenario})
744 @swagger.operation(nickname="updateInstallersUnderScenario")
745 def put(self, scenario):
747 @description: replace all installers
748 @notes: substitute all installers as a totality
749 PUT /api/v1/scenarios/<scenario_name>/installers
750 @param body: new installers
751 @type body: C{list} of L{ScenarioInstaller}
753 @return 200: replace versions success.
754 @raise 400: bad schema
755 @raise 404: scenario/installer not exist
757 self.do_update('installers',
759 locators={'scenario': scenario})
761 @swagger.operation(nickname="deleteInstallersUnderScenario")
762 def delete(self, scenario):
764 @description: delete one or multiple installers
765 @notes: delete one or multiple installers
766 DELETE /api/v1/scenarios/<scenario_name>/installers
767 @param body: installers(names) to be deleted
768 @type body: C{list} of L{string}
770 @return 200: delete versions success.
771 @raise 404: scenario/installer not exist
773 self.do_update('installers',
775 locators={'scenario': scenario})