11c3310d11
This patch renames every package, file, match of Marconi in the codebase to Zaqar *except* for the .gitreview file, which will have to be updated *after* I8e587af588d9be0b5ebbab4b0f729b106a2ae537 lands. Implements blueprint: project-rename Change-Id: I0c82be81f74d022ab609eea8f40ac2c0635374b1
112 lines
3.9 KiB
Python
112 lines
3.9 KiB
Python
# Copyright (c) 2013 Red Hat, Inc.
|
|
#
|
|
# 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.
|
|
|
|
import json
|
|
|
|
from zaqarclient.common import http
|
|
from zaqarclient.transport import base
|
|
# NOTE(flaper87): Something is completely borked
|
|
# with some imports. Using `from ... import errors`
|
|
# will end up importing `zaqarclient.errors` instead
|
|
# of transports
|
|
import zaqarclient.transport.errors as errors
|
|
from zaqarclient.transport import response
|
|
|
|
|
|
class HttpTransport(base.Transport):
|
|
|
|
http_to_zaqar = {
|
|
400: errors.MalformedRequest,
|
|
401: errors.UnauthorizedError,
|
|
403: errors.ForbiddenError,
|
|
404: errors.ResourceNotFound,
|
|
500: errors.InternalServerError,
|
|
503: errors.ServiceUnavailableError
|
|
}
|
|
|
|
def __init__(self, options):
|
|
super(HttpTransport, self).__init__(options)
|
|
self.client = http.Client()
|
|
|
|
def _prepare(self, request):
|
|
if not request.api:
|
|
return request.endpoint, 'GET', request
|
|
|
|
# TODO(flaper87): Validate if the user
|
|
# explicitly wants so. Validation must
|
|
# happen before any other operation here.
|
|
# request.validate()
|
|
|
|
schema = {}
|
|
ref_params = {}
|
|
ref = request.ref
|
|
|
|
if request.operation:
|
|
schema = request.api.get_schema(request.operation)
|
|
ref = ref or schema.get('ref', '')
|
|
|
|
# FIXME(flaper87): We expect the endpoint
|
|
# to have the API version label already,
|
|
# however in a follow-your-nose implementation
|
|
# it should be the other way around.
|
|
ref = ref.lstrip('/' + request.api.label)
|
|
|
|
for param in list(request.params.keys()):
|
|
if '{{{0}}}'.format(param) in ref:
|
|
value = request.params.pop(param)
|
|
|
|
# NOTE(flaper87): Zaqar API parses
|
|
# sequences encoded as '1,2,3,4'. Let's
|
|
# encode lists, tuples and sets before
|
|
# sending them to the server.
|
|
if isinstance(value, (list, tuple, set)):
|
|
value = ','.join(value)
|
|
|
|
ref_params[param] = value
|
|
|
|
url = '{0}/{1}/{2}'.format(request.endpoint.rstrip('/'),
|
|
request.api.label,
|
|
ref.format(**ref_params))
|
|
return url, schema.get('method', 'GET'), request
|
|
|
|
def send(self, request):
|
|
url, method, request = self._prepare(request)
|
|
|
|
# NOTE(flape87): Do not modify
|
|
# request's headers directly.
|
|
headers = request.headers.copy()
|
|
headers['content-type'] = 'application/json'
|
|
|
|
resp = self.client.request(method,
|
|
url=url,
|
|
params=request.params,
|
|
headers=headers,
|
|
data=request.content)
|
|
|
|
if resp.status_code in self.http_to_zaqar:
|
|
try:
|
|
msg = json.loads(resp.text)['description']
|
|
except Exception:
|
|
# TODO(flaper87): Log this exception
|
|
# but don't stop raising the corresponding
|
|
# exception
|
|
msg = ''
|
|
raise self.http_to_zaqar[resp.status_code](msg)
|
|
|
|
# NOTE(flaper87): This reads the whole content
|
|
# and will consume any attempt of streaming.
|
|
return response.Response(request, resp.text,
|
|
headers=resp.headers)
|