execution.py 6.36 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
# Copyright (c) 2016, Daniele Venzano
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#    http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
# implied.
# See the License for the specific language governing permissions and
# limitations under the License.

16 17
"""The Execution API endpoints."""

18 19
from tornado.web import RequestHandler
import tornado.escape
20

21
from zoe_api.rest_api.utils import catch_exceptions, get_auth, manage_cors_headers
22
import zoe_api.exceptions
23
from zoe_api.api_endpoint import APIEndpoint  # pylint: disable=unused-import
24 25


26
class ExecutionAPI(RequestHandler):
27 28
    """The Execution API endpoint."""

29 30 31
    def initialize(self, **kwargs):
        """Initializes the request handler."""
        self.api_endpoint = kwargs['api_endpoint']  # type: APIEndpoint
32

33 34 35 36
    def set_default_headers(self):
        """Set up the headers for enabling CORS."""
        manage_cors_headers(self)

Daniele Venzano's avatar
Daniele Venzano committed
37
    def options(self, execution_id):  # pylint: disable=unused-argument
38 39 40 41
        """Needed for CORS."""
        self.set_status(204)
        self.finish()

42 43
    @catch_exceptions
    def get(self, execution_id):
44
        """GET a single execution by its ID."""
45
        uid, role = get_auth(self)
46

47
        e = self.api_endpoint.execution_by_id(uid, role, execution_id)
48

49
        self.write(e.serialize())
50 51 52 53

    @catch_exceptions
    def delete(self, execution_id: int):
        """
54 55
        Terminate an execution.

56
        :param execution_id: the execution to be terminated
57
        """
58
        uid, role = get_auth(self)
59

60
        success, message = self.api_endpoint.execution_terminate(uid, role, execution_id)
61
        if not success:
62
            raise zoe_api.exceptions.ZoeRestAPIException(message, 400)
63

64
        self.set_status(204)
65

66 67 68 69
    def data_received(self, chunk):
        """Not implemented as we do not use stream uploads"""
        pass

70

71
class ExecutionDeleteAPI(RequestHandler):
72 73
    """The ExecutionDelete API endpoints."""

74 75 76
    def initialize(self, **kwargs):
        """Initializes the request handler."""
        self.api_endpoint = kwargs['api_endpoint']  # type: APIEndpoint
77

78 79 80 81
    def set_default_headers(self):
        """Set up the headers for enabling CORS."""
        manage_cors_headers(self)

Daniele Venzano's avatar
Daniele Venzano committed
82 83
    @catch_exceptions
    def options(self, execution_id):  # pylint: disable=unused-argument
84 85 86 87
        """Needed for CORS."""
        self.set_status(204)
        self.finish()

88 89 90
    @catch_exceptions
    def delete(self, execution_id: int):
        """
91 92
        Delete an execution.

93 94
        :param execution_id: the execution to be deleted
        """
95
        uid, role = get_auth(self)
96 97 98 99 100

        success, message = self.api_endpoint.execution_delete(uid, role, execution_id)
        if not success:
            raise zoe_api.exceptions.ZoeRestAPIException(message, 400)

101
        self.set_status(204)
102

103 104 105 106
    def data_received(self, chunk):
        """Not implemented as we do not use stream uploads"""
        pass

107

108
class ExecutionCollectionAPI(RequestHandler):
109 110
    """The Execution Collection API endpoints."""

111 112 113
    def initialize(self, **kwargs):
        """Initializes the request handler."""
        self.api_endpoint = kwargs['api_endpoint']  # type: APIEndpoint
114

115 116 117 118
    def set_default_headers(self):
        """Set up the headers for enabling CORS."""
        manage_cors_headers(self)

Daniele Venzano's avatar
Daniele Venzano committed
119
    @catch_exceptions
120
    def options(self):
121 122 123 124
        """Needed for CORS."""
        self.set_status(204)
        self.finish()

125 126 127 128 129
    @catch_exceptions
    def get(self):
        """
        Returns a list of all active executions.

130 131 132 133
        Return a list of all executions which have status equal to ..."

        example:  curl -u 'username:password' -X GET -H "Content-Type: application/json" -d '{"status":"terminated"}' http://bf5:8080/api/0.6/execution

134 135
        :return:
        """
136
        uid, role = get_auth(self)
137

138 139 140 141 142 143
        filt_dict = {}

        try:
            if self.request.body:
                filt_dict = tornado.escape.json_decode(self.request.body)
        except ValueError:
hxquangnhat's avatar
hxquangnhat committed
144 145
            raise zoe_api.exceptions.ZoeRestAPIException('Error decoding JSON data')

146 147 148 149 150
        if 'status' in filt_dict:
            execs = self.api_endpoint.execution_list(uid, role, status=filt_dict['status'])
        else:
            execs = self.api_endpoint.execution_list(uid, role)

151
        self.write(dict([(e.id, e.serialize()) for e in execs]))
152 153 154 155 156

    @catch_exceptions
    def post(self):
        """
        Starts an execution, given an application description. Takes a JSON object.
157

158 159
        :return: the new execution_id
        """
160
        uid, role = get_auth(self)
161 162

        try:
163 164
            data = tornado.escape.json_decode(self.request.body)
        except ValueError:
165
            raise zoe_api.exceptions.ZoeRestAPIException('Error decoding JSON data')
166 167 168 169

        application_description = data['application']
        exec_name = data['name']

170
        new_id = self.api_endpoint.execution_start(uid, role, exec_name, application_description)
171

172 173
        self.set_status(201)
        self.write({'execution_id': new_id})
174 175 176 177

    def data_received(self, chunk):
        """Not implemented as we do not use stream uploads"""
        pass
178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213


class ExecutionEndpointsAPI(RequestHandler):
    """The ExecutionEndpoints API endpoint."""

    def initialize(self, **kwargs):
        """Initializes the request handler."""
        self.api_endpoint = kwargs['api_endpoint']  # type: APIEndpoint

    def set_default_headers(self):
        """Set up the headers for enabling CORS."""
        manage_cors_headers(self)

    @catch_exceptions
    def options(self):
        """Needed for CORS."""
        self.set_status(204)
        self.finish()

    @catch_exceptions
    def get(self, execution_id: int):
        """
        Get a list of execution endpoints.

        :param execution_id: the execution to be deleted
        """
        uid, role = get_auth(self)

        execution = self.api_endpoint.execution_by_id(uid, role, execution_id)
        services_, endpoints = self.api_endpoint.execution_endpoints(uid, role, execution)

        self.write({'endpoints': endpoints})

    def data_received(self, chunk):
        """Not implemented as we do not use stream uploads"""
        pass