e95ae055007959bf81f7f7461868c8b50a06f2fb
[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(',')
110             new_task_list.remove(task_id)
111             if new_task_list:
112                 new_tasks = ','.join(new_task_list)
113             else:
114                 new_tasks = None
115             project_handler.update_attr(project_id, {'tasks': new_tasks})
116
117         return result_handler(consts.API_SUCCESS, {'task': task_id})
118
119     def put(self, task_id):
120
121         try:
122             uuid.UUID(task_id)
123         except ValueError:
124             return result_handler(consts.API_ERROR, 'invalid task id')
125
126         task_handler = V2TaskHandler()
127         try:
128             task_handler.get_by_uuid(task_id)
129         except ValueError:
130             return result_handler(consts.API_ERROR, 'no such task id')
131
132         return self._dispatch_post(task_id=task_id)
133
134     def add_environment(self, args):
135
136         task_id = args['task_id']
137         try:
138             environment_id = args['environment_id']
139         except KeyError:
140             return result_handler(consts.API_ERROR, 'environment_id must be provided')
141
142         try:
143             uuid.UUID(environment_id)
144         except ValueError:
145             return result_handler(consts.API_ERROR, 'invalid environment id')
146
147         environment_handler = V2EnvironmentHandler()
148         try:
149             environment_handler.get_by_uuid(environment_id)
150         except ValueError:
151             return result_handler(consts.API_ERROR, 'no such environment id')
152
153         LOG.info('update environment_id in task')
154         task_handler = V2TaskHandler()
155         task_handler.update_attr(task_id, {'environment_id': environment_id})
156
157         return result_handler(consts.API_SUCCESS, {'uuid': task_id})
158
159     def add_case(self, args):
160         task_id = args['task_id']
161         try:
162             name = args['case_name']
163         except KeyError:
164             return result_handler(consts.API_ERROR, 'case_name must be provided')
165
166         try:
167             content = args['case_content']
168         except KeyError:
169             return result_handler(consts.API_ERROR, 'case_content must be provided')
170
171         LOG.info('update case info in task')
172         task_handler = V2TaskHandler()
173         task_update_data = {
174             'case_name': name,
175             'content': content,
176             'suite': False
177         }
178         task_handler.update_attr(task_id, task_update_data)
179
180         return result_handler(consts.API_SUCCESS, {'uuid': task_id})
181
182     def add_suite(self, args):
183         task_id = args['task_id']
184         try:
185             name = args['suite_name']
186         except KeyError:
187             return result_handler(consts.API_ERROR, 'suite_name must be provided')
188
189         try:
190             content = args['suite_content']
191         except KeyError:
192             return result_handler(consts.API_ERROR, 'suite_content must be provided')
193
194         LOG.info('update suite info in task')
195         task_handler = V2TaskHandler()
196         task_update_data = {
197             'case_name': name,
198             'content': content,
199             'suite': True
200         }
201         task_handler.update_attr(task_id, task_update_data)
202
203         return result_handler(consts.API_SUCCESS, {'uuid': task_id})
204
205     def run(self, args):
206         try:
207             task_id = args['task_id']
208         except KeyError:
209             return result_handler(consts.API_ERROR, 'task_id must be provided')
210
211         try:
212             uuid.UUID(task_id)
213         except ValueError:
214             return result_handler(consts.API_ERROR, 'invalid task id')
215
216         task_handler = V2TaskHandler()
217         try:
218             task = task_handler.get_by_uuid(task_id)
219         except ValueError:
220             return result_handler(consts.API_ERROR, 'no such task id')
221
222         if not task.environment_id:
223             return result_handler(consts.API_ERROR, 'environment not set')
224
225         if not task.case_name or not task.content:
226             return result_handler(consts.API_ERROR, 'case not set')
227
228         if task.status == 0:
229             return result_handler(consts.API_ERROR, 'task is already running')
230
231         with open('/tmp/{}.yaml'.format(task.case_name), 'w') as f:
232             f.write(task.content)
233
234         data = {
235             'inputfile': ['/tmp/{}.yaml'.format(task.case_name)],
236             'task_id': task_id
237         }
238         if task.suite:
239             data.update({'suite': True})
240
241         LOG.info('start task thread')
242         param = Param(data)
243         task_thread = TaskThread(Task().start, param, task_handler)
244         task_thread.start()
245
246         return result_handler(consts.API_SUCCESS, {'uuid': task_id})