Add Executions and Tasks root API endpoints
Change-Id: I580086c81b26db6a5f51b4ada4b0eb697e8dea49 Implements: blueprint mistral-ui
This commit is contained in:
parent
ca1b448aab
commit
201c902b99
@ -83,7 +83,28 @@ class Executions(resource.Resource):
|
||||
|
||||
class ExecutionsController(rest.RestController):
|
||||
|
||||
tasks = task.TasksController()
|
||||
def _get(self, id):
|
||||
values = db_api.execution_get(id)
|
||||
return Execution.from_dict(values)
|
||||
|
||||
def _put(self, id, execution):
|
||||
values = db_api.execution_update(id, execution.to_dict())
|
||||
|
||||
return Execution.from_dict(values)
|
||||
|
||||
def _delete(self, id):
|
||||
db_api.execution_delete(id)
|
||||
|
||||
def _get_all(self, **kwargs):
|
||||
executions = [Execution.from_dict(values) for values
|
||||
in db_api.executions_get(**kwargs)]
|
||||
|
||||
return Executions(executions=executions)
|
||||
|
||||
|
||||
class WorkbookExecutionsController(ExecutionsController):
|
||||
|
||||
tasks = task.WorkbookTasksController()
|
||||
|
||||
@rest_utils.wrap_wsme_controller_exception
|
||||
@wsme_pecan.wsexpose(Execution, wtypes.text, wtypes.text)
|
||||
@ -91,8 +112,7 @@ class ExecutionsController(rest.RestController):
|
||||
"""Return the specified Execution."""
|
||||
LOG.debug("Fetch execution [workbook_name=%s, id=%s]" %
|
||||
(workbook_name, id))
|
||||
values = db_api.execution_get(id)
|
||||
return Execution.from_dict(values)
|
||||
return self._get(id)
|
||||
|
||||
@rest_utils.wrap_wsme_controller_exception
|
||||
@wsme_pecan.wsexpose(Execution, wtypes.text, wtypes.text, body=Execution)
|
||||
@ -100,11 +120,7 @@ class ExecutionsController(rest.RestController):
|
||||
"""Update the specified Execution."""
|
||||
LOG.debug("Update execution [workbook_name=%s, id=%s, execution=%s]" %
|
||||
(workbook_name, id, execution))
|
||||
|
||||
values = db_api.execution_update(id,
|
||||
execution.to_dict())
|
||||
|
||||
return Execution.from_dict(values)
|
||||
return self._put(id, execution)
|
||||
|
||||
@rest_utils.wrap_wsme_controller_exception
|
||||
@wsme_pecan.wsexpose(Execution, wtypes.text, body=Execution,
|
||||
@ -133,7 +149,7 @@ class ExecutionsController(rest.RestController):
|
||||
"""Delete the specified Execution."""
|
||||
LOG.debug("Delete execution [workbook_name=%s, id=%s]" %
|
||||
(workbook_name, id))
|
||||
db_api.execution_delete(id)
|
||||
return self._delete(id)
|
||||
|
||||
@wsme_pecan.wsexpose(Executions, wtypes.text)
|
||||
def get_all(self, workbook_name):
|
||||
@ -141,9 +157,38 @@ class ExecutionsController(rest.RestController):
|
||||
LOG.debug("Fetch executions [workbook_name=%s]" % workbook_name)
|
||||
|
||||
if db_api.workbook_get(workbook_name):
|
||||
executions = [
|
||||
Execution.from_dict(values) for values
|
||||
in db_api.executions_get(workbook_name=workbook_name)
|
||||
]
|
||||
return self._get_all(workbook_name=workbook_name)
|
||||
|
||||
return Executions(executions=executions)
|
||||
|
||||
class RootExecutionsController(ExecutionsController):
|
||||
|
||||
tasks = task.ExecutionTasksController()
|
||||
|
||||
@rest_utils.wrap_wsme_controller_exception
|
||||
@wsme_pecan.wsexpose(Execution, wtypes.text)
|
||||
def get(self, id):
|
||||
"""Return the specified Execution."""
|
||||
LOG.debug("Fetch execution [id=%s]" % id)
|
||||
return self._get(id)
|
||||
|
||||
@rest_utils.wrap_wsme_controller_exception
|
||||
@wsme_pecan.wsexpose(Execution, wtypes.text, body=Execution)
|
||||
def put(self, id, execution):
|
||||
"""Update the specified Execution."""
|
||||
LOG.debug("Update execution [id=%s, execution=%s]" %
|
||||
(id, execution))
|
||||
return self._put(id, execution)
|
||||
|
||||
@rest_utils.wrap_wsme_controller_exception
|
||||
@wsme_pecan.wsexpose(None, wtypes.text, status_code=204)
|
||||
def delete(self, id):
|
||||
"""Delete the specified Execution."""
|
||||
LOG.debug("Delete execution [id=%s]" % id)
|
||||
return self._delete(id)
|
||||
|
||||
@wsme_pecan.wsexpose(Executions)
|
||||
def get_all(self):
|
||||
"""Return all Executions."""
|
||||
LOG.debug("Fetch executions")
|
||||
|
||||
return self._get_all()
|
||||
|
@ -19,6 +19,8 @@ from wsme import types as wtypes
|
||||
import wsmeext.pecan as wsme_pecan
|
||||
|
||||
from mistral.api.controllers import resource
|
||||
from mistral.api.controllers.v1 import execution
|
||||
from mistral.api.controllers.v1 import task
|
||||
from mistral.api.controllers.v1 import workbook
|
||||
|
||||
|
||||
@ -39,6 +41,8 @@ class Controller(object):
|
||||
"""API root controller for version 1."""
|
||||
|
||||
workbooks = workbook.WorkbooksController()
|
||||
executions = execution.RootExecutionsController()
|
||||
tasks = task.RootTasksController()
|
||||
|
||||
@wsme_pecan.wsexpose(RootResource)
|
||||
def index(self):
|
||||
|
@ -85,6 +85,27 @@ class Tasks(resource.Resource):
|
||||
|
||||
|
||||
class TasksController(rest.RestController):
|
||||
def _get(self, id):
|
||||
values = db_api.task_get(id)
|
||||
return Task.from_dict(values)
|
||||
|
||||
def _put(self, id, task):
|
||||
if db_api.task_get(id):
|
||||
# TODO(rakhmerov): pass task result once it's implemented
|
||||
engine = pecan.request.context['engine']
|
||||
values = engine.convey_task_result(id,
|
||||
task.state, None)
|
||||
|
||||
return Task.from_dict(values)
|
||||
|
||||
def _get_all(self, **kwargs):
|
||||
tasks = [Task.from_dict(values)
|
||||
for values in db_api.tasks_get(**kwargs)]
|
||||
|
||||
return Tasks(tasks=tasks)
|
||||
|
||||
|
||||
class WorkbookTasksController(TasksController):
|
||||
@rest_utils.wrap_wsme_controller_exception
|
||||
@wsme_pecan.wsexpose(Task, wtypes.text, wtypes.text, wtypes.text)
|
||||
def get(self, workbook_name, execution_id, id):
|
||||
@ -92,8 +113,7 @@ class TasksController(rest.RestController):
|
||||
LOG.debug("Fetch task [workbook_name=%s, execution_id=%s, id=%s]" %
|
||||
(workbook_name, execution_id, id))
|
||||
|
||||
values = db_api.task_get(id)
|
||||
return Task.from_dict(values)
|
||||
return self._get(id)
|
||||
|
||||
@rest_utils.wrap_wsme_controller_exception
|
||||
@wsme_pecan.wsexpose(Task, wtypes.text, wtypes.text, wtypes.text,
|
||||
@ -104,13 +124,7 @@ class TasksController(rest.RestController):
|
||||
"[workbook_name=%s, execution_id=%s, id=%s, task=%s]" %
|
||||
(workbook_name, execution_id, id, task))
|
||||
|
||||
if db_api.task_get(id):
|
||||
# TODO(rakhmerov): pass task result once it's implemented
|
||||
engine = pecan.request.context['engine']
|
||||
values = engine.convey_task_result(id,
|
||||
task.state, None)
|
||||
|
||||
return Task.from_dict(values)
|
||||
return self._put(id, task)
|
||||
|
||||
@rest_utils.wrap_wsme_controller_exception
|
||||
@wsme_pecan.wsexpose(Tasks, wtypes.text, wtypes.text)
|
||||
@ -121,8 +135,62 @@ class TasksController(rest.RestController):
|
||||
LOG.debug("Fetch tasks [workbook_name=%s, execution_id=%s]" %
|
||||
(workbook_name, execution_id))
|
||||
|
||||
tasks = [Task.from_dict(values)
|
||||
for values in db_api.tasks_get(workbook_name=workbook_name,
|
||||
execution_id=execution_id)]
|
||||
return self._get_all(workbook_name=workbook_name,
|
||||
execution_id=execution_id)
|
||||
|
||||
return Tasks(tasks=tasks)
|
||||
|
||||
class ExecutionTasksController(TasksController):
|
||||
@rest_utils.wrap_wsme_controller_exception
|
||||
@wsme_pecan.wsexpose(Task, wtypes.text, wtypes.text)
|
||||
def get(self, execution_id, id):
|
||||
"""Return the specified task."""
|
||||
LOG.debug("Fetch task [execution_id=%s, id=%s]" %
|
||||
(execution_id, id))
|
||||
|
||||
return self._get(id)
|
||||
|
||||
@rest_utils.wrap_wsme_controller_exception
|
||||
@wsme_pecan.wsexpose(Task, wtypes.text, wtypes.text,
|
||||
body=Task)
|
||||
def put(self, execution_id, id, task):
|
||||
"""Update the specified task."""
|
||||
LOG.debug("Update task "
|
||||
"[execution_id=%s, id=%s, task=%s]" %
|
||||
(execution_id, id, task))
|
||||
|
||||
return self._put(id, task)
|
||||
|
||||
@wsme_pecan.wsexpose(Tasks, wtypes.text)
|
||||
def get_all(self, execution_id):
|
||||
"""Return all tasks within the execution."""
|
||||
LOG.debug("Fetch tasks [execution_id=%s]" % execution_id)
|
||||
|
||||
return self._get_all(execution_id=execution_id)
|
||||
|
||||
|
||||
class RootTasksController(TasksController):
|
||||
@rest_utils.wrap_wsme_controller_exception
|
||||
@wsme_pecan.wsexpose(Task, wtypes.text)
|
||||
def get(self, id):
|
||||
"""Return the specified task."""
|
||||
LOG.debug("Fetch task [id=%s]" % id)
|
||||
|
||||
return self._get(id)
|
||||
|
||||
@rest_utils.wrap_wsme_controller_exception
|
||||
@wsme_pecan.wsexpose(Task, wtypes.text,
|
||||
body=Task)
|
||||
def put(self, id, task):
|
||||
"""Update the specified task."""
|
||||
LOG.debug("Update task "
|
||||
"[id=%s, task=%s]" %
|
||||
(id, task))
|
||||
|
||||
return self._put(id, task)
|
||||
|
||||
@wsme_pecan.wsexpose(Tasks)
|
||||
def get_all(self):
|
||||
"""Return all tasks within the execution."""
|
||||
LOG.debug("Fetch tasks")
|
||||
|
||||
return self._get_all()
|
||||
|
@ -57,7 +57,7 @@ class Workbooks(resource.Resource):
|
||||
class WorkbooksController(rest.RestController):
|
||||
definition = workbook_definition.WorkbookDefinitionController()
|
||||
listeners = listener.ListenersController()
|
||||
executions = execution.ExecutionsController()
|
||||
executions = execution.WorkbookExecutionsController()
|
||||
|
||||
@rest_utils.wrap_wsme_controller_exception
|
||||
@wsme_pecan.wsexpose(Workbook, wtypes.text)
|
||||
|
@ -65,12 +65,20 @@ def canonize(json_dict):
|
||||
class TestExecutionsController(base.FunctionalTest):
|
||||
@mock.patch.object(db_api, 'execution_get',
|
||||
mock.MagicMock(return_value=EXECS[0]))
|
||||
def test_get(self):
|
||||
def test_workbook_get(self):
|
||||
resp = self.app.get('/v1/workbooks/my_workbook/executions/123')
|
||||
|
||||
self.assertEqual(resp.status_int, 200)
|
||||
self.assertDictEqual(EXECS[0], canonize(resp.json))
|
||||
|
||||
@mock.patch.object(db_api, 'execution_get',
|
||||
mock.MagicMock(return_value=EXECS[0]))
|
||||
def test_root_get(self):
|
||||
resp = self.app.get('/v1/executions/123')
|
||||
|
||||
self.assertEqual(resp.status_int, 200)
|
||||
self.assertDictEqual(EXECS[0], canonize(resp.json))
|
||||
|
||||
@mock.patch.object(db_api, 'execution_get',
|
||||
mock.MagicMock(side_effect=ex.NotFoundException()))
|
||||
def test_get_empty(self):
|
||||
@ -80,13 +88,22 @@ class TestExecutionsController(base.FunctionalTest):
|
||||
|
||||
@mock.patch.object(db_api, 'execution_update',
|
||||
mock.MagicMock(return_value=UPDATED_EXEC))
|
||||
def test_put(self):
|
||||
def test_workbook_put(self):
|
||||
resp = self.app.put_json('/v1/workbooks/my_workbook/executions/123',
|
||||
dict(state='STOPPED'))
|
||||
|
||||
self.assertEqual(resp.status_int, 200)
|
||||
self.assertDictEqual(UPDATED_EXEC, canonize(resp.json))
|
||||
|
||||
@mock.patch.object(db_api, 'execution_update',
|
||||
mock.MagicMock(return_value=UPDATED_EXEC))
|
||||
def test_root_put(self):
|
||||
resp = self.app.put_json('/v1/executions/123',
|
||||
dict(state='STOPPED'))
|
||||
|
||||
self.assertEqual(resp.status_int, 200)
|
||||
self.assertDictEqual(UPDATED_EXEC, canonize(resp.json))
|
||||
|
||||
@mock.patch.object(db_api, 'execution_update',
|
||||
mock.MagicMock(
|
||||
side_effect=ex.NotFoundException()))
|
||||
@ -137,11 +154,18 @@ class TestExecutionsController(base.FunctionalTest):
|
||||
|
||||
@mock.patch.object(db_api, 'execution_delete',
|
||||
mock.MagicMock(return_value=None))
|
||||
def test_delete(self):
|
||||
def test_workbook_delete(self):
|
||||
resp = self.app.delete('/v1/workbooks/my_workbook/executions/123')
|
||||
|
||||
self.assertEqual(resp.status_int, 204)
|
||||
|
||||
@mock.patch.object(db_api, 'execution_delete',
|
||||
mock.MagicMock(return_value=None))
|
||||
def test_root_delete(self):
|
||||
resp = self.app.delete('/v1/executions/123')
|
||||
|
||||
self.assertEqual(resp.status_int, 204)
|
||||
|
||||
@mock.patch.object(db_api, 'execution_delete',
|
||||
mock.MagicMock(side_effect=ex.NotFoundException))
|
||||
def test_delete_not_found(self):
|
||||
@ -154,7 +178,7 @@ class TestExecutionsController(base.FunctionalTest):
|
||||
mock.MagicMock(return_value=EXECS))
|
||||
@mock.patch.object(db_api, 'workbook_get',
|
||||
mock.MagicMock(return_value={'name': 'my_workbook'}))
|
||||
def test_get_all(self):
|
||||
def test_workbook_get_all(self):
|
||||
resp = self.app.get('/v1/workbooks/my_workbook/executions')
|
||||
|
||||
self.assertEqual(resp.status_int, 200)
|
||||
@ -162,6 +186,18 @@ class TestExecutionsController(base.FunctionalTest):
|
||||
self.assertEqual(len(resp.json), 1)
|
||||
self.assertDictEqual(EXECS[0], canonize(resp.json['executions'][0]))
|
||||
|
||||
@mock.patch.object(db_api, 'executions_get',
|
||||
mock.MagicMock(return_value=EXECS))
|
||||
@mock.patch.object(db_api, 'workbook_get',
|
||||
mock.MagicMock(return_value={'name': 'my_workbook'}))
|
||||
def test_root_get_all(self):
|
||||
resp = self.app.get('/v1/executions')
|
||||
|
||||
self.assertEqual(resp.status_int, 200)
|
||||
|
||||
self.assertEqual(len(resp.json), 1)
|
||||
self.assertDictEqual(EXECS[0], canonize(resp.json['executions'][0]))
|
||||
|
||||
@mock.patch.object(db_api, 'executions_get',
|
||||
mock.MagicMock(return_value=EXECS))
|
||||
def test_get_all_no_workbook(self):
|
||||
|
@ -58,23 +58,61 @@ def canonize(json_dict):
|
||||
class TestTasksController(base.FunctionalTest):
|
||||
@mock.patch.object(db_api, "task_get",
|
||||
mock.MagicMock(return_value=TASKS[0]))
|
||||
def test_get(self):
|
||||
def test_workbook_get(self):
|
||||
resp = self.app.get('/v1/workbooks/my_workbook/executions/123/tasks/1')
|
||||
|
||||
self.assertEqual(resp.status_int, 200)
|
||||
self.assertDictEqual(TASKS[0], canonize(resp.json))
|
||||
|
||||
@mock.patch.object(db_api, "task_get",
|
||||
mock.MagicMock(return_value=TASKS[0]))
|
||||
def test_execution_get(self):
|
||||
resp = self.app.get('/v1/executions/123/tasks/1')
|
||||
|
||||
self.assertEqual(resp.status_int, 200)
|
||||
self.assertDictEqual(TASKS[0], canonize(resp.json))
|
||||
|
||||
@mock.patch.object(db_api, "task_get",
|
||||
mock.MagicMock(return_value=TASKS[0]))
|
||||
def test_root_get(self):
|
||||
resp = self.app.get('/v1/tasks/1')
|
||||
|
||||
self.assertEqual(resp.status_int, 200)
|
||||
self.assertDictEqual(TASKS[0], canonize(resp.json))
|
||||
|
||||
@mock.patch.object(engine.EngineClient, "convey_task_result",
|
||||
mock.MagicMock(return_value=UPDATED_TASK))
|
||||
@mock.patch.object(db_api, "task_get",
|
||||
mock.MagicMock(return_value=TASKS[0]))
|
||||
def test_put(self):
|
||||
def test_workbook_put(self):
|
||||
resp = self.app.put_json(
|
||||
'/v1/workbooks/my_workbook/executions/123/tasks/1',
|
||||
dict(state='STOPPED'))
|
||||
self.assertEqual(resp.status_int, 200)
|
||||
self.assertDictEqual(UPDATED_TASK, canonize(resp.json))
|
||||
|
||||
@mock.patch.object(engine.EngineClient, "convey_task_result",
|
||||
mock.MagicMock(return_value=UPDATED_TASK))
|
||||
@mock.patch.object(db_api, "task_get",
|
||||
mock.MagicMock(return_value=TASKS[0]))
|
||||
def test_execution_put(self):
|
||||
resp = self.app.put_json(
|
||||
'/v1/executions/123/tasks/1',
|
||||
dict(state='STOPPED'))
|
||||
self.assertEqual(resp.status_int, 200)
|
||||
self.assertDictEqual(UPDATED_TASK, canonize(resp.json))
|
||||
|
||||
@mock.patch.object(engine.EngineClient, "convey_task_result",
|
||||
mock.MagicMock(return_value=UPDATED_TASK))
|
||||
@mock.patch.object(db_api, "task_get",
|
||||
mock.MagicMock(return_value=TASKS[0]))
|
||||
def test_root_put(self):
|
||||
resp = self.app.put_json(
|
||||
'/v1/tasks/1',
|
||||
dict(state='STOPPED'))
|
||||
self.assertEqual(resp.status_int, 200)
|
||||
self.assertDictEqual(UPDATED_TASK, canonize(resp.json))
|
||||
|
||||
@mock.patch.object(engine.EngineClient, "convey_task_result",
|
||||
mock.MagicMock(return_value=UPDATED_TASK))
|
||||
def test_put_no_task(self):
|
||||
@ -87,7 +125,7 @@ class TestTasksController(base.FunctionalTest):
|
||||
mock.MagicMock(return_value=TASKS))
|
||||
@mock.patch.object(db_api, "ensure_execution_exists",
|
||||
mock.MagicMock(return_value={'id': "abc123"}))
|
||||
def test_get_all(self):
|
||||
def test_workbook_get_all(self):
|
||||
resp = self.app.get('/v1/workbooks/my_workbook/executions/123/tasks')
|
||||
|
||||
self.assertEqual(resp.status_int, 200)
|
||||
@ -95,6 +133,30 @@ class TestTasksController(base.FunctionalTest):
|
||||
self.assertEqual(len(resp.json), 1)
|
||||
self.assertDictEqual(TASKS[0], canonize(resp.json['tasks'][0]))
|
||||
|
||||
@mock.patch.object(db_api, "tasks_get",
|
||||
mock.MagicMock(return_value=TASKS))
|
||||
@mock.patch.object(db_api, "ensure_execution_exists",
|
||||
mock.MagicMock(return_value={'id': "abc123"}))
|
||||
def test_execution_get_all(self):
|
||||
resp = self.app.get('/v1/executions/123/tasks')
|
||||
|
||||
self.assertEqual(resp.status_int, 200)
|
||||
|
||||
self.assertEqual(len(resp.json), 1)
|
||||
self.assertDictEqual(TASKS[0], canonize(resp.json['tasks'][0]))
|
||||
|
||||
@mock.patch.object(db_api, "tasks_get",
|
||||
mock.MagicMock(return_value=TASKS))
|
||||
@mock.patch.object(db_api, "ensure_execution_exists",
|
||||
mock.MagicMock(return_value={'id': "abc123"}))
|
||||
def test_root_get_all(self):
|
||||
resp = self.app.get('/v1/tasks')
|
||||
|
||||
self.assertEqual(resp.status_int, 200)
|
||||
|
||||
self.assertEqual(len(resp.json), 1)
|
||||
self.assertDictEqual(TASKS[0], canonize(resp.json['tasks'][0]))
|
||||
|
||||
@mock.patch.object(db_api, "tasks_get",
|
||||
mock.MagicMock(return_value=TASKS))
|
||||
def test_get_all_nonexistent_execution(self):
|
||||
|
Loading…
Reference in New Issue
Block a user