3 from opnfv_testapi.common import message
4 from opnfv_testapi.common import raises
5 from opnfv_testapi.resources import handlers
6 import opnfv_testapi.resources.scenario_models as models
7 from opnfv_testapi.tornado_swagger import swagger
10 class GenericScenarioHandler(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})
120 @swagger.operation(nickname="deleteScenarioByName")
121 def delete(self, name):
123 @description: delete a scenario by name
124 @return 200: delete success
125 @raise 404: scenario not exist:
127 self._delete(query={'name': name})
130 class ScenarioUpdater(object):
131 def __init__(self, data, body=None,
132 installer=None, version=None, project=None):
135 self.installer = installer
136 self.version = version
137 self.project = project
139 def update(self, item, action):
141 ('scores', 'post'): self._update_requests_add_score,
142 ('trust_indicators', 'post'): self._update_requests_add_ti,
143 ('customs', 'post'): self._update_requests_add_customs,
144 ('customs', 'put'): self._update_requests_update_customs,
145 ('customs', 'delete'): self._update_requests_delete_customs,
146 ('projects', 'post'): self._update_requests_add_projects,
147 ('projects', 'put'): self._update_requests_update_projects,
148 ('projects', 'delete'): self._update_requests_delete_projects,
150 updates[(item, action)](self.data)
152 return self.data.format()
154 def iter_installers(xstep):
155 @functools.wraps(xstep)
156 def magic(self, data):
157 [xstep(self, installer)
158 for installer in self._filter_installers(data.installers)]
161 def iter_versions(xstep):
162 @functools.wraps(xstep)
163 def magic(self, installer):
164 [xstep(self, version)
165 for version in (self._filter_versions(installer.versions))]
168 def iter_projects(xstep):
169 @functools.wraps(xstep)
170 def magic(self, version):
171 [xstep(self, project)
172 for project in (self._filter_projects(version.projects))]
178 def _update_requests_add_score(self, project):
179 project.scores.append(
180 models.ScenarioScore.from_dict(self.body))
185 def _update_requests_add_ti(self, project):
186 project.trust_indicators.append(
187 models.ScenarioTI.from_dict(self.body))
192 def _update_requests_add_customs(self, project):
193 project.customs = list(set(project.customs + self.body))
198 def _update_requests_update_customs(self, project):
199 project.customs = list(set(self.body))
204 def _update_requests_delete_customs(self, project):
205 project.customs = filter(
206 lambda f: f not in self.body,
211 def _update_requests_add_projects(self, version):
216 f_n = models.ScenarioProject.from_dict_with_raise(n)
217 if not any(o.project == f_n.project for o in version.projects):
218 version.projects.append(f_n)
220 exists.append(n['project'])
221 except Exception as e:
222 malformat.append(e.message)
224 raises.BadRequest(message.bad_format(malformat))
226 raises.Conflict(message.exist('projects', exists))
230 def _update_requests_update_projects(self, version):
236 f_n = models.ScenarioProject.from_dict_with_raise(n)
237 if not any(o.project == f_n.project for o in projects):
238 projects.append(models.ScenarioProject.from_dict(n))
240 exists.append(n['project'])
244 raises.BadRequest(message.bad_format(malformat))
246 raises.Forbidden(message.exist('projects', exists))
247 version.projects = projects
251 def _update_requests_delete_projects(self, version):
252 version.projects = self._remove_projects(version.projects)
254 def _filter_installers(self, installers):
255 return self._filter('installer', installers)
257 def _filter_versions(self, versions):
258 return self._filter('version', versions)
260 def _filter_projects(self, projects):
261 return self._filter('project', projects)
263 def _remove_projects(self, projects):
264 return self._remove('project', projects)
266 def _filter(self, item, items):
268 lambda f: getattr(f, item) == getattr(self, item),
271 def _remove(self, field, fields):
273 lambda f: getattr(f, field) not in self.body,
277 class GenericScenarioUpdateHandler(GenericScenarioHandler):
278 def __init__(self, application, request, **kwargs):
279 super(GenericScenarioUpdateHandler, self).__init__(application,
282 self.installer = None
288 def do_update(self, item, action, locators):
291 for k, v in locators.iteritems():
293 v = self.get_query_argument(k)
296 self.pure_update(query=self.set_query(locators=locators))
298 def _update_requests(self, data):
299 return ScenarioUpdater(data,
303 self.project).update(self.item, self.action)
306 class ScenarioScoresHandler(GenericScenarioUpdateHandler):
307 @swagger.operation(nickname="addScoreRecord")
308 def post(self, scenario):
310 @description: add a new score record
311 @notes: add a new score record to a project
312 POST /api/v1/scenarios/<scenario_name>/scores? \
313 installer=<installer_name>& \
314 version=<version_name>& \
315 project=<project_name>
316 @param body: score to be added
317 @type body: L{ScenarioScore}
319 @param installer: installer type
320 @type installer: L{string}
322 @required installer: True
323 @param version: version
324 @type version: L{string}
326 @required version: True
327 @param project: project name
328 @type project: L{string}
330 @required project: True
331 @return 200: score is created.
332 @raise 404: scenario/installer/version/project not existed
334 self.do_update('scores',
336 locators={'scenario': scenario,
342 class ScenarioTIsHandler(GenericScenarioUpdateHandler):
343 @swagger.operation(nickname="addTrustIndicatorRecord")
344 def post(self, scenario):
346 @description: add a new trust indicator record
347 @notes: add a new trust indicator record to a project
348 POST /api/v1/scenarios/<scenario_name>/trust_indicators? \
349 installer=<installer_name>& \
350 version=<version_name>& \
351 project=<project_name>
352 @param body: trust indicator to be added
353 @type body: L{ScenarioTI}
355 @param installer: installer type
356 @type installer: L{string}
358 @required installer: True
359 @param version: version
360 @type version: L{string}
362 @required version: True
363 @param project: project name
364 @type project: L{string}
366 @required project: True
367 @return 200: trust indicator is added.
368 @raise 404: scenario/installer/version/project not existed
370 self.do_update('trust_indicators',
372 locators={'scenario': scenario,
378 class ScenarioCustomsHandler(GenericScenarioUpdateHandler):
379 @swagger.operation(nickname="addCustomizedTestCases")
380 def post(self, scenario):
382 @description: add customized test cases
383 @notes: add several test cases to a project
384 POST /api/v1/scenarios/<scenario_name>/customs? \
385 installer=<installer_name>& \
386 version=<version_name>& \
387 project=<project_name>
388 @param body: test cases to be added
389 @type body: C{list} of L{string}
391 @param installer: installer type
392 @type installer: L{string}
394 @required installer: True
395 @param version: version
396 @type version: L{string}
398 @required version: True
399 @param project: project name
400 @type project: L{string}
402 @required project: True
403 @return 200: test cases are added.
404 @raise 404: scenario/installer/version/project not existed
406 self.do_update('customs',
408 locators={'scenario': scenario,
413 @swagger.operation(nickname="updateCustomizedTestCases")
414 def put(self, scenario):
416 @description: update customized test cases
417 @notes: substitute all the customized test cases
418 PUT /api/v1/scenarios/<scenario_name>/customs? \
419 installer=<installer_name>& \
420 version=<version_name>& \
421 project=<project_name>
422 @param body: new supported test cases
423 @type body: C{list} of L{string}
425 @param installer: installer type
426 @type installer: L{string}
428 @required installer: True
429 @param version: version
430 @type version: L{string}
432 @required version: True
433 @param project: project name
434 @type project: L{string}
436 @required project: True
437 @return 200: substitute test cases success.
438 @raise 404: scenario/installer/version/project not existed
440 self.do_update('customs',
442 locators={'scenario': scenario,
447 @swagger.operation(nickname="deleteCustomizedTestCases")
448 def delete(self, scenario):
450 @description: delete one or several customized test cases
451 @notes: delete one or some customized test cases
452 DELETE /api/v1/scenarios/<scenario_name>/customs? \
453 installer=<installer_name>& \
454 version=<version_name>& \
455 project=<project_name>
456 @param body: test case(s) to be deleted
457 @type body: C{list} of L{string}
459 @param installer: installer type
460 @type installer: L{string}
462 @required installer: True
463 @param version: version
464 @type version: L{string}
466 @required version: True
467 @param project: project name
468 @type project: L{string}
470 @required project: True
471 @return 200: delete test case(s) success.
472 @raise 404: scenario/installer/version/project not existed
474 self.do_update('customs',
476 locators={'scenario': scenario,
482 class ScenarioProjectsHandler(GenericScenarioUpdateHandler):
483 @swagger.operation(nickname="addProjectsUnderScenario")
484 def post(self, scenario):
486 @description: add projects to scenario
487 @notes: add one or multiple projects
488 POST /api/v1/scenarios/<scenario_name>/projects? \
489 installer=<installer_name>& \
490 version=<version_name>
491 @param body: projects to be added
492 @type body: C{list} of L{ScenarioProject}
494 @param installer: installer type
495 @type installer: L{string}
497 @required installer: True
498 @param version: version
499 @type version: L{string}
501 @required version: True
502 @return 200: projects are added.
503 @raise 400: bad schema
504 @raise 409: conflict, project already exists
505 @raise 404: scenario/installer/version not existed
507 self.do_update('projects',
509 locators={'scenario': scenario,
513 @swagger.operation(nickname="updateScenarioProjects")
514 def put(self, scenario):
516 @description: replace all projects
517 @notes: substitute all projects, delete existed ones with new provides
518 PUT /api/v1/scenarios/<scenario_name>/projects? \
519 installer=<installer_name>& \
520 version=<version_name>
521 @param body: new projects
522 @type body: C{list} of L{ScenarioProject}
524 @param installer: installer type
525 @type installer: L{string}
527 @required installer: True
528 @param version: version
529 @type version: L{string}
531 @required version: True
532 @return 200: replace projects success.
533 @raise 400: bad schema
534 @raise 404: scenario/installer/version not existed
536 self.do_update('projects',
538 locators={'scenario': scenario,
542 @swagger.operation(nickname="deleteProjectsUnderScenario")
543 def delete(self, scenario):
545 @description: delete one or multiple projects
546 @notes: delete one or multiple projects
547 DELETE /api/v1/scenarios/<scenario_name>/projects? \
548 installer=<installer_name>& \
549 version=<version_name>
550 @param body: projects(names) to be deleted
551 @type body: C{list} of L{string}
553 @param installer: installer type
554 @type installer: L{string}
556 @required installer: True
557 @param version: version
558 @type version: L{string}
560 @required version: True
561 @return 200: delete project(s) success.
562 @raise 404: scenario/installer/version not existed
564 self.do_update('projects',
566 locators={'scenario': scenario,