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