Commit eedbd381 authored by Daniele Venzano's avatar Daniele Venzano

Make sure all exception are caught correctly

parent 080ce380
......@@ -80,7 +80,7 @@ class APIEndpoint:
running_execs += self.sql.executions.select(**{'status': 'image download', 'user_id': user.id})
running_execs += self.sql.executions.select(**{'status': 'submitted', 'user_id': user.id})
if len(running_execs) >= quota.concurrent_executions:
raise zoe_api.exceptions.ZoeException('You cannot run more than {} executions at a time, quota exceeded.'.format(quota.concurrent_executions))
raise zoe_api.exceptions.ZoeQuotaException('You cannot run more than {} executions at a time, quota exceeded.'.format(quota.concurrent_executions))
# TODO: implement core and memory quotas
......@@ -89,14 +89,14 @@ class APIEndpoint:
try:
zoe_lib.applications.app_validate(application_description)
except zoe_lib.exceptions.InvalidApplicationDescription as e:
raise zoe_api.exceptions.ZoeException('Invalid application description: ' + e.message)
raise zoe_api.exceptions.ZoeRestAPIException('Invalid application description: ' + e.message)
self._check_quota(user, application_description)
new_id = self.sql.executions.insert(exec_name, user.id, application_description)
success, message = self.master.execution_start(new_id)
if not success:
raise zoe_api.exceptions.ZoeException('The Zoe master is unavailable, execution will be submitted automatically when the master is back up ({}).'.format(message))
raise zoe_api.exceptions.ZoeRestAPIException('The Zoe master is unavailable, execution will be submitted automatically when the master is back up ({}).'.format(message), status_code=503)
return new_id
......@@ -108,12 +108,14 @@ class APIEndpoint:
raise zoe_api.exceptions.ZoeNotFoundException('No such execution')
if e.user_id != user.id and not user.role.can_operate_others:
raise zoe_api.exceptions.ZoeException('You are not authorized to terminate this execution')
raise zoe_api.exceptions.ZoeAuthException('You are not authorized to terminate this execution')
if e.is_active:
return self.master.execution_terminate(exec_id)
success, message = self.master.execution_terminate(exec_id)
if not success:
raise zoe_api.exceptions.ZoeRestAPIException(message)
else:
raise zoe_api.exceptions.ZoeException('Execution is not running')
raise zoe_api.exceptions.ZoeRestAPIException('Execution is not running')
def execution_delete(self, user: zoe_lib.state.User, exec_id: int):
"""Delete an execution."""
......@@ -126,17 +128,16 @@ class APIEndpoint:
raise zoe_api.exceptions.ZoeNotFoundException('No such execution')
if e.user_id != user.id and not user.role.can_operate_others:
raise zoe_api.exceptions.ZoeException('You are not authorized to terminate this execution')
raise zoe_api.exceptions.ZoeAuthException('You are not authorized to terminate this execution')
if e.is_active:
raise zoe_api.exceptions.ZoeException('Cannot delete an active execution')
raise zoe_api.exceptions.ZoeRestAPIException('Cannot delete an active execution')
status, message = self.master.execution_delete(exec_id)
if status:
self.sql.executions.delete(exec_id)
return True, ''
else:
raise zoe_api.exceptions.ZoeException(message)
raise zoe_api.exceptions.ZoeRestAPIException(message)
def service_by_id(self, user: zoe_lib.state.User, service_id: int) -> zoe_lib.state.Service:
"""Lookup a service by its ID."""
......@@ -206,7 +207,11 @@ class APIEndpoint:
if not user.role.can_change_config:
raise zoe_api.exceptions.ZoeAuthException()
return self.sql.user.select(only_one=True, id=user_id)
ret = self.sql.user.select(only_one=True, id=user_id)
if ret is None:
raise zoe_api.exceptions.ZoeNotFoundException("No such user")
else:
return ret
def user_delete(self, user: zoe_lib.state.User, user_id: int):
"""Deletes the user identified by the ID."""
......@@ -281,7 +286,11 @@ class APIEndpoint:
def quota_by_id(self, quota_id) -> zoe_lib.state.Quota:
"""Finds a quota in the database looking it up by its id."""
return self.sql.quota.select(only_one=True, **{'id': quota_id})
quota = self.sql.quota.select(only_one=True, **{'id': quota_id})
if quota is None:
raise zoe_api.exceptions.ZoeNotFoundException('No such quota')
else:
return quota
def role_by_name(self, role) -> zoe_lib.state.Role:
"""Finds a role in the database looking it up by its name."""
......@@ -289,7 +298,11 @@ class APIEndpoint:
def role_by_id(self, role_id) -> zoe_lib.state.Role:
"""Finds a role in the database looking it up by its id."""
return self.sql.role.select(only_one=True, **{'id': role_id})
role = self.sql.role.select(only_one=True, **{'id': role_id})
if role is None:
raise zoe_api.exceptions.ZoeNotFoundException('No such role')
else:
return role
def role_new(self, user: zoe_lib.state.User, role_data) -> int:
"""Creates a new role."""
......
......@@ -58,3 +58,12 @@ class ZoeRestAPIException(ZoeException):
def __init__(self, message, status_code=400):
super().__init__(message)
self.status_code = status_code
class ZoeQuotaException(ZoeException):
"""
An exception generated by the REST API.
"""
def __init__(self, message):
super().__init__(message)
self.status_code = 409
......@@ -16,6 +16,7 @@
"""The Discovery API endpoint."""
from zoe_api.rest_api.request_handler import ZoeAPIRequestHandler
from zoe_api.exceptions import ZoeException
class DiscoveryAPI(ZoeAPIRequestHandler):
......@@ -26,11 +27,16 @@ class DiscoveryAPI(ZoeAPIRequestHandler):
if self.current_user is None:
return
self.api_endpoint.execution_by_id(self.current_user, execution_id)
if service_group != 'all':
services = self.api_endpoint.service_list(self.current_user, service_group=service_group, execution_id=execution_id)
else:
services = self.api_endpoint.service_list(self.current_user, execution_id=execution_id)
try:
self.api_endpoint.execution_by_id(self.current_user, execution_id)
if service_group != 'all':
services = self.api_endpoint.service_list(self.current_user, service_group=service_group, execution_id=execution_id)
else:
services = self.api_endpoint.service_list(self.current_user, execution_id=execution_id)
except ZoeException as e:
self.set_status(e.status_code, e.message)
return
ret = {
'service_type': service_group,
'execution_id': execution_id,
......
......@@ -18,6 +18,7 @@
import tornado.escape
from zoe_api.rest_api.request_handler import ZoeAPIRequestHandler
from zoe_api.exceptions import ZoeException
class ExecutionAPI(ZoeAPIRequestHandler):
......@@ -28,7 +29,11 @@ class ExecutionAPI(ZoeAPIRequestHandler):
if self.current_user is None:
return
e = self.api_endpoint.execution_by_id(self.current_user, execution_id)
try:
e = self.api_endpoint.execution_by_id(self.current_user, execution_id)
except ZoeException as e:
self.set_status(e.status_code, e.message)
return
self.write(e.serialize())
......@@ -41,9 +46,10 @@ class ExecutionAPI(ZoeAPIRequestHandler):
if self.current_user is None:
return
success, message = self.api_endpoint.execution_terminate(self.current_user, execution_id)
if not success:
self.set_status(400, message)
try:
self.api_endpoint.execution_terminate(self.current_user, execution_id)
except ZoeException as e:
self.set_status(e.status_code, e.message)
else:
self.set_status(204)
......@@ -60,9 +66,10 @@ class ExecutionDeleteAPI(ZoeAPIRequestHandler):
if self.current_user is None:
return
success, message = self.api_endpoint.execution_delete(self.current_user, execution_id)
if not success:
self.set_status(400, message)
try:
self.api_endpoint.execution_delete(self.current_user, execution_id)
except ZoeException as e:
self.set_status(e.status_code, e.message)
else:
self.set_status(204)
......@@ -117,7 +124,11 @@ class ExecutionCollectionAPI(ZoeAPIRequestHandler):
else:
filt_dict[filt[0]] = filt[1](self.request.arguments[filt[0]][0])
execs = self.api_endpoint.execution_list(self.current_user, **filt_dict)
try:
execs = self.api_endpoint.execution_list(self.current_user, **filt_dict)
except ZoeException as e:
self.set_status(e.status_code, e.message)
return
self.write(dict([(e.id, e.serialize()) for e in execs]))
......@@ -139,7 +150,11 @@ class ExecutionCollectionAPI(ZoeAPIRequestHandler):
application_description = data['application']
exec_name = data['name']
new_id = self.api_endpoint.execution_start(self.current_user, exec_name, application_description)
try:
new_id = self.api_endpoint.execution_start(self.current_user, exec_name, application_description)
except ZoeException as e:
self.set_status(e.status_code, e.message)
return
self.set_status(201)
self.write({'execution_id': new_id})
......@@ -157,7 +172,11 @@ class ExecutionEndpointsAPI(ZoeAPIRequestHandler):
if self.current_user is None:
return
execution = self.api_endpoint.execution_by_id(self.current_user, execution_id)
services_, endpoints = self.api_endpoint.execution_endpoints(self.current_user, execution)
try:
execution = self.api_endpoint.execution_by_id(self.current_user, execution_id)
services_, endpoints = self.api_endpoint.execution_endpoints(self.current_user, execution)
except ZoeException as e:
self.set_status(e.status_code, e.message)
return
self.write({'endpoints': endpoints})
......@@ -29,7 +29,12 @@ class QuotaAPI(ZoeAPIRequestHandler):
if self.current_user is None:
return
quota = self.api_endpoint.quota_by_id(quota_id)
try:
quota = self.api_endpoint.quota_by_id(quota_id)
except ZoeException as e:
self.set_status(e.status_code, e.message)
return
ret = {
'quota': quota.serialize()
}
......
......@@ -29,7 +29,12 @@ class RoleAPI(ZoeAPIRequestHandler):
if self.current_user is None:
return
role = self.api_endpoint.role_by_id(role_id)
try:
role = self.api_endpoint.role_by_id(role_id)
except ZoeException as e:
self.set_status(e.status_code, e.message)
return
ret = {
'role': role.serialize()
}
......
......@@ -22,6 +22,7 @@ import tornado.gen
import tornado.iostream
from zoe_api.rest_api.request_handler import ZoeAPIRequestHandler
from zoe_api.exceptions import ZoeException
log = logging.getLogger(__name__)
......@@ -36,7 +37,11 @@ class ServiceAPI(ZoeAPIRequestHandler):
if self.current_user is None:
return
service = self.api_endpoint.service_by_id(self.current_user, service_id)
try:
service = self.api_endpoint.service_by_id(self.current_user, service_id)
except ZoeException as e:
self.set_status(e.status_code, e.message)
return
self.write(service.serialize())
......@@ -64,7 +69,11 @@ class ServiceLogsAPI(ZoeAPIRequestHandler):
if self.current_user is None:
return
log_obj = self.api_endpoint.service_logs(self.current_user, service_id)
try:
log_obj = self.api_endpoint.service_logs(self.current_user, service_id)
except ZoeException as e:
self.set_status(e.status_code, e.message)
return
while not self.connection_closed:
try:
......
......@@ -16,6 +16,7 @@
"""The Scheduler Statistics API endpoint."""
from zoe_api.rest_api.request_handler import ZoeAPIRequestHandler
from zoe_api.exceptions import ZoeException
class SchedulerStatsAPI(ZoeAPIRequestHandler):
......@@ -23,5 +24,9 @@ class SchedulerStatsAPI(ZoeAPIRequestHandler):
def get(self):
"""HTTP GET method."""
statistics = self.api_endpoint.statistics_scheduler()
try:
statistics = self.api_endpoint.statistics_scheduler()
except ZoeException as e:
self.set_status(e.status_code, e.message)
return
self.write(statistics)
......@@ -34,9 +34,10 @@ class UserAPI(ZoeAPIRequestHandler):
'user': self.current_user.serialize()
}
else:
user = self.api_endpoint.user_by_id(self.current_user, user_id)
if user is None:
self.set_status(404, "No such user")
try:
user = self.api_endpoint.user_by_id(self.current_user, user_id)
except ZoeException as e:
self.set_status(e.status_code, e.message)
return
ret = {
'user': user.serialize()
......
......@@ -18,6 +18,7 @@
import tornado.escape
from zoe_api.rest_api.request_handler import ZoeAPIRequestHandler
from zoe_api.exceptions import ZoeException
class ZAppValidateAPI(ZoeAPIRequestHandler):
......@@ -33,6 +34,10 @@ class ZAppValidateAPI(ZoeAPIRequestHandler):
application_description = data['application']
self.api_endpoint.zapp_validate(application_description)
try:
self.api_endpoint.zapp_validate(application_description)
except ZoeException as e:
self.set_status(e.status_code, e.message)
return
self.write({'validation': 'ok'})
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment