Add API(v2) to get all task info
[yardstick.git] / api / resources / v2 / tasks.py
1 import uuid
2 import logging
3 from datetime import datetime
4
5 from oslo_serialization import jsonutils
6
7 from api import ApiResource
8 from api.database.v2.handlers import V2TaskHandler
9 from api.database.v2.handlers import V2ProjectHandler
10 from api.database.v2.handlers import V2EnvironmentHandler
11 from api.utils.thread import TaskThread
12 from yardstick.common.utils import result_handler
13 from yardstick.common.utils import change_obj_to_dict
14 from yardstick.common import constants as consts
15 from yardstick.benchmark.core.task import Task
16 from yardstick.benchmark.core import Param
17
18 LOG = logging.getLogger(__name__)
19 LOG.setLevel(logging.DEBUG)
20
21
22 class V2Tasks(ApiResource):
23
24     def get(self):
25         task_handler = V2TaskHandler()
26         tasks = [change_obj_to_dict(t) for t in task_handler.list_all()]
27
28         for t in tasks:
29             result = t['result']
30             t['result'] = jsonutils.loads(result) if result else None
31
32         return result_handler(consts.API_SUCCESS, {'tasks': tasks})
33
34     def post(self):
35         return self._dispatch_post()
36
37     def create_task(self, args):
38         try:
39             name = args['name']
40         except KeyError:
41             return result_handler(consts.API_ERROR, 'name must be provided')
42
43         try:
44             project_id = args['project_id']
45         except KeyError:
46             return result_handler(consts.API_ERROR, 'project_id must be provided')
47
48         task_id = str(uuid.uuid4())
49         create_time = datetime.now()
50         task_handler = V2TaskHandler()
51
52         LOG.info('create task in database')
53         task_init_data = {
54             'uuid': task_id,
55             'project_id': project_id,
56             'name': name,
57             'time': create_time,
58             'status': -1
59         }
60         task_handler.insert(task_init_data)
61
62         LOG.info('create task in project')
63         project_handler = V2ProjectHandler()
64         project_handler.append_attr(project_id, {'tasks': task_id})
65
66         return result_handler(consts.API_SUCCESS, {'uuid': task_id})
67
68
69 class V2Task(ApiResource):
70
71     def get(self, task_id):
72         try:
73             uuid.UUID(task_id)
74         except ValueError:
75             return result_handler(consts.API_ERROR, 'invalid task id')
76
77         task_handler = V2TaskHandler()
78         try:
79             task = task_handler.get_by_uuid(task_id)
80         except ValueError:
81             return result_handler(consts.API_ERROR, 'no such task id')
82
83         task_info = change_obj_to_dict(task)
84         result = task_info['result']
85         task_info['result'] = jsonutils.loads(result) if result else None
86
87         return result_handler(consts.API_SUCCESS, {'task': task_info})
88
89     def delete(self, task_id):
90         try:
91             uuid.UUID(task_id)
92         except ValueError:
93             return result_handler(consts.API_ERROR, 'invalid task id')
94
95         task_handler = V2TaskHandler()
96         try:
97             project_id = task_handler.get_by_uuid(task_id).project_id
98         except ValueError:
99             return result_handler(consts.API_ERROR, 'no such task id')
100
101         LOG.info('delete task in database')
102         task_handler.delete_by_uuid(task_id)
103
104         project_handler = V2ProjectHandler()
105         project = project_handler.get_by_uuid(project_id)
106
107         if project.tasks:
108             LOG.info('update tasks in project')
109             new_task_list = project.tasks.split(',').remove(task_id)
110             if new_task_list:
111                 new_tasks = ','.join(new_task_list)
112             else:
113                 new_tasks = None
114             project_handler.update_attr(project_id, {'tasks': new_tasks})
115
116         return result_handler(consts.API_SUCCESS, {'task': task_id})
117
118     def put(self, task_id):
119
120         try:
121             uuid.UUID(task_id)
122         except ValueError:
123             return result_handler(consts.API_ERROR, 'invalid task id')
124
125         task_handler = V2TaskHandler()
126         try:
127             task_handler.get_by_uuid(task_id)
128         except ValueError:
129             return result_handler(consts.API_ERROR, 'no such task id')
130
131         return self._dispatch_post(task_id=task_id)
132
133     def add_environment(self, args):
134
135         task_id = args['task_id']
136         try:
137             environment_id = args['environment_id']
138         except KeyError:
139             return result_handler(consts.API_ERROR, 'environment_id must be provided')
140
141         try:
142             uuid.UUID(environment_id)
143         except ValueError:
144             return result_handler(consts.API_ERROR, 'invalid environment id')
145
146         environment_handler = V2EnvironmentHandler()
147         try:
148             environment_handler.get_by_uuid(environment_id)
149         except ValueError:
150             return result_handler(consts.API_ERROR, 'no such environment id')
151
152         LOG.info('update environment_id in task')
153         task_handler = V2TaskHandler()
154         task_handler.update_attr(task_id, {'environment_id': environment_id})
155
156         return result_handler(consts.API_SUCCESS, {'uuid': task_id})
157
158     def add_case(self, args):
159         task_id = args['task_id']
160         try:
161             name = args['case_name']
162         except KeyError:
163             return result_handler(consts.API_ERROR, 'case_name must be provided')
164
165         try:
166             content = args['case_content']
167         except KeyError:
168             return result_handler(consts.API_ERROR, 'case_content must be provided')
169
170         LOG.info('update case info in task')
171         task_handler = V2TaskHandler()
172         task_update_data = {
173             'case_name': name,
174             'content': content,
175             'suite': False
176         }
177         task_handler.update_attr(task_id, task_update_data)
178
179         return result_handler(consts.API_SUCCESS, {'uuid': task_id})
180
181     def add_suite(self, args):
182         task_id = args['task_id']
183         try:
184             name = args['suite_name']
185         except KeyError:
186             return result_handler(consts.API_ERROR, 'suite_name must be provided')
187
188         try:
189             content = args['suite_content']
190         except KeyError:
191             return result_handler(consts.API_ERROR, 'suite_content must be provided')
192
193         LOG.info('update suite info in task')
194         task_handler = V2TaskHandler()
195         task_update_data = {
196             'case_name': name,
197             'content': content,
198             'suite': True
199         }
200         task_handler.update_attr(task_id, task_update_data)
201
202         return result_handler(consts.API_SUCCESS, {'uuid': task_id})
203
204     def run(self, args):
205         try:
206             task_id = args['task_id']
207         except KeyError:
208             return result_handler(consts.API_ERROR, 'task_id must be provided')
209
210         try:
211             uuid.UUID(task_id)
212         except ValueError:
213             return result_handler(consts.API_ERROR, 'invalid task id')
214
215         task_handler = V2TaskHandler()
216         try:
217             task = task_handler.get_by_uuid(task_id)
218         except ValueError:
219             return result_handler(consts.API_ERROR, 'no such task id')
220
221         if not task.environment_id:
222             return result_handler(consts.API_ERROR, 'environment not set')
223
224         if not task.case_name or not task.content:
225             return result_handler(consts.API_ERROR, 'case not set')
226
227         if task.status == 0:
228             return result_handler(consts.API_ERROR, 'task is already running')
229
230         with open('/tmp/{}.yaml'.format(task.case_name), 'w') as f:
231             f.write(task.content)
232
233         data = {
234             'inputfile': ['/tmp/{}.yaml'.format(task.case_name)],
235             'task_id': task_id
236         }
237         if task.suite:
238             data.update({'suite': True})
239
240         LOG.info('start task thread')
241         param = Param(data)
242         task_thread = TaskThread(Task().start, param, task_handler)
243         task_thread.start()
244
245         return result_handler(consts.API_SUCCESS, {'uuid': task_id})