update customs in scenario
[releng.git] / utils / test / testapi / opnfv_testapi / resources / handlers.py
index 0234c8a..aa77da2 100644 (file)
@@ -20,8 +20,8 @@
 # feng.xiaowei@zte.com.cn remove DashboardHandler            5-30-2016
 ##############################################################################
 
-from datetime import datetime
 import json
+from datetime import datetime
 
 from tornado import gen
 from tornado import web
@@ -29,6 +29,7 @@ from tornado import web
 from opnfv_testapi.common import check
 from opnfv_testapi.common import message
 from opnfv_testapi.common import raises
+from opnfv_testapi.db import api as dbapi
 from opnfv_testapi.resources import models
 from opnfv_testapi.tornado_swagger import swagger
 
@@ -38,7 +39,6 @@ DEFAULT_REPRESENTATION = "application/json"
 class GenericApiHandler(web.RequestHandler):
     def __init__(self, application, request, **kwargs):
         super(GenericApiHandler, self).__init__(application, request, **kwargs)
-        self.db = self.settings["db"]
         self.json_args = None
         self.table = None
         self.table_cls = None
@@ -50,7 +50,7 @@ class GenericApiHandler(web.RequestHandler):
         self.auth = self.settings["auth"]
 
     def prepare(self):
-        if self.request.method != "GET" and self.request.method != "DELETE":
+        if self.request.body:
             if self.request.headers.get("Content-Type") is not None:
                 if self.request.headers["Content-Type"].startswith(
                         DEFAULT_REPRESENTATION):
@@ -90,8 +90,7 @@ class GenericApiHandler(web.RequestHandler):
 
         if self.table != 'results':
             data.creation_date = datetime.now()
-        _id = yield self._eval_db(self.table, 'insert', data.format(),
-                                  check_keys=False)
+        _id = yield dbapi.db_save(self.table, data.format())
         if 'name' in self.json_args:
             resource = data.name
         else:
@@ -101,20 +100,55 @@ class GenericApiHandler(web.RequestHandler):
     @web.asynchronous
     @gen.coroutine
     def _list(self, query=None, res_op=None, *args, **kwargs):
-        if query is None:
-            query = {}
-        data = []
         sort = kwargs.get('sort')
         page = kwargs.get('page', 0)
         last = kwargs.get('last', 0)
         per_page = kwargs.get('per_page', 0)
+        if query is None:
+            query = {}
 
-        cursor = self._eval_db(self.table, 'find', query)
-        records_count = yield cursor.count()
+        total_pages = 0
+        if page > 0:
+            cursor = dbapi.db_list(self.table, query)
+            records_count = yield cursor.count()
+            total_pages = self._calc_total_pages(records_count,
+                                                 last,
+                                                 page,
+                                                 per_page)
+        pipelines = self._set_pipelines(query, sort, last, page, per_page)
+        cursor = dbapi.db_aggregate(self.table, pipelines)
+        data = list()
+        while (yield cursor.fetch_next):
+            data.append(self.format_data(cursor.next_object()))
+        if res_op is None:
+            res = {self.table: data}
+        else:
+            res = res_op(data, *args)
+        if page > 0:
+            res.update({
+                'pagination': {
+                    'current_page': kwargs.get('page'),
+                    'total_pages': total_pages
+                }
+            })
+        self.finish_request(res)
+
+    @staticmethod
+    def _calc_total_pages(records_count, last, page, per_page):
         records_nr = records_count
         if (records_count > last) and (last > 0):
             records_nr = last
 
+        total_pages, remainder = divmod(records_nr, per_page)
+        if remainder > 0:
+            total_pages += 1
+        if page > 1 and page > total_pages:
+            raises.BadRequest(
+                'Request page > total_pages [{}]'.format(total_pages))
+        return total_pages
+
+    @staticmethod
+    def _set_pipelines(query, sort, last, page, per_page):
         pipelines = list()
         if query:
             pipelines.append({'$match': query})
@@ -122,33 +156,12 @@ class GenericApiHandler(web.RequestHandler):
             pipelines.append({'$sort': sort})
 
         if page > 0:
-            total_pages, remainder = divmod(records_nr, per_page)
-            if remainder > 0:
-                total_pages += 1
             pipelines.append({'$skip': (page - 1) * per_page})
             pipelines.append({'$limit': per_page})
-        else:
-            pipelines.append({'$limit': records_nr})
+        elif last > 0:
+            pipelines.append({'$limit': last})
 
-        cursor = self._eval_db(self.table,
-                               'aggregate',
-                               pipelines,
-                               allowDiskUse=True)
-
-        while (yield cursor.fetch_next):
-            data.append(self.format_data(cursor.next_object()))
-        if res_op is None:
-            res = {self.table: data}
-        else:
-            res = res_op(data, *args)
-        if page:
-            res.update({
-                'pagination': {
-                    'current_page': page,
-                    'total_pages': total_pages
-                }
-            })
-        self.finish_request(res)
+        return pipelines
 
     @web.asynchronous
     @gen.coroutine
@@ -159,7 +172,7 @@ class GenericApiHandler(web.RequestHandler):
     @check.authenticate
     @check.not_exist
     def _delete(self, data, query=None):
-        yield self._eval_db(self.table, 'remove', query)
+        yield dbapi.db_delete(self.table, query)
         self.finish_request()
 
     @check.authenticate
@@ -169,11 +182,19 @@ class GenericApiHandler(web.RequestHandler):
     def _update(self, data, query=None, **kwargs):
         data = self.table_cls.from_dict(data)
         update_req = self._update_requests(data)
-        yield self._eval_db(self.table, 'update', query, update_req,
-                            check_keys=False)
+        yield dbapi.db_update(self.table, query, update_req)
         update_req['_id'] = str(data._id)
         self.finish_request(update_req)
 
+    @check.authenticate
+    @check.no_body
+    @check.not_exist
+    @check.updated_one_not_exist
+    def pure_update(self, data, query=None, **kwargs):
+        data = self.table_cls.from_dict(data)
+        update_req = self._update_requests(data)
+        yield dbapi.db_update(self.table, query, update_req)
+
     def _update_requests(self, data):
         request = dict()
         for k, v in self.json_args.iteritems():
@@ -213,23 +234,6 @@ class GenericApiHandler(web.RequestHandler):
             query[key] = new
         return query if not equal else dict()
 
-    def _eval_db(self, table, method, *args, **kwargs):
-        exec_collection = self.db.__getattr__(table)
-        return exec_collection.__getattribute__(method)(*args, **kwargs)
-
-    def _eval_db_find_one(self, query, table=None):
-        if table is None:
-            table = self.table
-        return self._eval_db(table, 'find_one', query)
-
-    def db_save(self, collection, data):
-        self._eval_db(collection, 'insert', data, check_keys=False)
-
-    def db_find_one(self, query, collection=None):
-        if not collection:
-            collection = self.table
-        return self._eval_db(collection, 'find_one', query)
-
 
 class VersionHandler(GenericApiHandler):
     @swagger.operation(nickname='listAllVersions')