~hudson-openstack/burrow/trunk

« back to all changes in this revision

Viewing changes to burrow/frontend/wsgi.py

  • Committer: Eric Day
  • Date: 2011-08-16 23:37:49 UTC
  • mto: This revision was merged to the branch mainline in revision 35.
  • Revision ID: eday@oddments.org-20110816233749-h6g4vm7ak015bs44
Cleaned up WSGI frontend.

Show diffs side-by-side

added added

removed removed

Lines of Context:
17
17
import json
18
18
import types
19
19
 
20
 
import eventlet
21
20
import eventlet.wsgi
22
 
import routes
23
21
import routes.middleware
24
22
import webob.dec
25
23
 
77
75
        log_format = '%(client_ip)s "%(request_line)s" %(status_code)s ' \
78
76
                     '%(body_length)s %(wall_seconds).6f'
79
77
        if thread_pool_size == 0:
80
 
            eventlet.wsgi.server(socket, self, log=WSGILog(self.log),
 
78
            eventlet.wsgi.server(socket, self, log=_WSGILog(self.log),
81
79
                log_format=log_format, custom_pool=thread_pool)
82
80
        else:
83
 
            eventlet.wsgi.server(socket, self, log=WSGILog(self.log),
 
81
            eventlet.wsgi.server(socket, self, log=_WSGILog(self.log),
84
82
                log_format=log_format, max_size=thread_pool_size)
85
83
 
86
84
    def __call__(self, *args, **kwargs):
88
86
 
89
87
    @webob.dec.wsgify
90
88
    def _route(self, req):
 
89
        '''Parse the request args and see if there is a matching method.'''
91
90
        args = req.environ['wsgiorg.routing_args'][1]
92
91
        if not args:
93
92
            return self._response(status=404)
94
93
        action = args.pop('action')
95
 
        method = getattr(self, '_%s_%s' % (req.method.lower(), action), False)
96
 
        if not method:
 
94
        method = getattr(self, '_%s_%s' % (req.method.lower(), action), None)
 
95
        if method is not None:
 
96
            return method(req, **args)
 
97
        method = req.method.lower()
 
98
        args = dict(args)
 
99
        if method == 'post':
 
100
            method = 'update'
 
101
            args['attributes'] = self._parse_attributes(req)
 
102
        method = getattr(self.backend, '%s_%s' % (method, action), None)
 
103
        if method is None:
97
104
            return self._response(status=400)
98
 
        return method(req, **args)
 
105
        args['filters'] = self._parse_filters(req)
 
106
        return self._response(body=lambda: method(**args))
99
107
 
100
108
    @webob.dec.wsgify
101
109
    def _get_versions(self, _req):
 
110
        '''Return a list of API versions.'''
102
111
        return self._response(body=['v1.0'])
103
112
 
104
113
    @webob.dec.wsgify
105
 
    def _delete_accounts(self, req):
106
 
        filters = self._parse_filters(req)
107
 
        return self._response(body=self.backend.delete_accounts(filters))
108
 
 
109
 
    @webob.dec.wsgify
110
 
    def _get_accounts(self, req):
111
 
        filters = self._parse_filters(req)
112
 
        return self._response(body=self.backend.get_accounts(filters))
113
 
 
114
 
    @webob.dec.wsgify
115
 
    def _delete_queues(self, req, account):
116
 
        filters = self._parse_filters(req)
117
 
        queues = self.backend.delete_queues(account, filters)
118
 
        return self._response(body=queues)
119
 
 
120
 
    @webob.dec.wsgify
121
 
    def _get_queues(self, req, account):
122
 
        filters = self._parse_filters(req)
123
 
        return self._response(body=self.backend.get_queues(account, filters))
124
 
 
125
 
    @webob.dec.wsgify
126
 
    def _delete_messages(self, req, account, queue):
127
 
        filters = self._parse_filters(req)
128
 
        messages = self.backend.delete_messages(account, queue, filters)
129
 
        return self._response(body=messages)
130
 
 
131
 
    @webob.dec.wsgify
132
 
    def _get_messages(self, req, account, queue):
133
 
        filters = self._parse_filters(req)
134
 
        messages = self.backend.get_messages(account, queue, filters)
135
 
        return self._response(body=messages)
136
 
 
137
 
    @webob.dec.wsgify
138
 
    def _post_messages(self, req, account, queue):
139
 
        attributes = self._parse_attributes(req)
140
 
        filters = self._parse_filters(req)
141
 
        messages = self.backend.update_messages(account, queue, attributes,
142
 
            filters)
143
 
        return self._response(body=messages)
144
 
 
145
 
    @webob.dec.wsgify
146
 
    def _delete_message(self, req, account, queue, message):
147
 
        filters = self._parse_filters(req)
148
 
        body = lambda: self.backend.delete_message(account, queue, message,
149
 
            filters)
150
 
        return self._response(body=body)
151
 
 
152
 
    @webob.dec.wsgify
153
 
    def _get_message(self, req, account, queue, message):
154
 
        filters = self._parse_filters(req)
155
 
        body = lambda: self.backend.get_message(account, queue, message,
156
 
            filters)
157
 
        return self._response(body=body)
158
 
 
159
 
    @webob.dec.wsgify
160
 
    def _post_message(self, req, account, queue, message):
161
 
        attributes = self._parse_attributes(req)
162
 
        filters = self._parse_filters(req)
163
 
        body = lambda: self.backend.update_message(account, queue, message,
164
 
            attributes, filters)
165
 
        return self._response(body=body)
166
 
 
167
 
    @webob.dec.wsgify
168
114
    def _put_message(self, req, account, queue, message):
 
115
        '''Read the request body and create a new message.'''
169
116
        attributes = self._parse_attributes(req, self.default_ttl,
170
117
            self.default_hide)
171
118
        body = ''
177
124
        return self._response()
178
125
 
179
126
    def _parse_filters(self, req):
 
127
        '''Parse filters from a request object and build a dict to
 
128
        pass into the backend methods.'''
180
129
        filters = {}
181
130
        if 'limit' in req.params:
182
131
            filters['limit'] = int(req.params['limit'])
192
141
        return filters
193
142
 
194
143
    def _parse_attributes(self, req, default_ttl=None, default_hide=None):
 
144
        '''Parse attributes from a request object and build a dict
 
145
        to pass into the backend methods.'''
195
146
        attributes = {}
196
147
        if 'ttl' in req.params:
197
148
            ttl = int(req.params['ttl'])
206
157
        return attributes
207
158
 
208
159
    def _response(self, status=200, body=None, content_type=None):
209
 
        try:
210
 
            if isinstance(body, types.GeneratorType):
211
 
                body = list(body)
212
 
            if isinstance(body, types.FunctionType):
213
 
                body = body()
214
 
        except burrow.backend.InvalidArguments:
215
 
            status = 400
216
 
            body = None
217
 
        except burrow.backend.NotFound:
218
 
            status = 404
219
 
            body = None
220
 
        if body == []:
221
 
            body = None
 
160
        '''Pack result into an appropriate HTTP response.'''
 
161
        status, body = self._response_body(status, body)
222
162
        if body is None:
223
163
            content_type = ''
224
164
            if status == 200:
240
180
                response.body = body
241
181
        return response
242
182
 
243
 
 
244
 
class WSGILog(object):
 
183
    def _response_body(self, status, body):
 
184
        '''Normalize the body from the type given.'''
 
185
        try:
 
186
            if isinstance(body, types.FunctionType):
 
187
                body = body()
 
188
            if isinstance(body, types.GeneratorType):
 
189
                body = list(body)
 
190
        except burrow.backend.InvalidArguments:
 
191
            status = 400
 
192
            body = None
 
193
        except burrow.backend.NotFound:
 
194
            status = 404
 
195
            body = None
 
196
        if body == []:
 
197
            body = None
 
198
        return status, body
 
199
 
 
200
 
 
201
class _WSGILog(object):
245
202
    '''Class for eventlet.wsgi.server to forward logging messages.'''
246
203
 
247
204
    def __init__(self, log):
248
205
        self.log = log
249
206
 
250
207
    def write(self, message):
 
208
        '''Write WSGI log message to burrow log.'''
251
209
        self.log.debug(message.rstrip())