diff --git a/marconiclient/transport/request.py b/marconiclient/transport/request.py index 9ec0395c..28e91521 100644 --- a/marconiclient/transport/request.py +++ b/marconiclient/transport/request.py @@ -1,4 +1,5 @@ # Copyright (c) 2013 Rackspace, Inc. +# 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. @@ -13,19 +14,69 @@ # See the License for the specific language governing permissions and # limitations under the License. +import json +from marconiclient import auth from marconiclient.common import api -class Request(object): - """General data for a Marconi request, passed to the transport layer. - The idea is to be declarative i.e. specify *what* is desired. It's up to - the respective transport to turn this into a layer-specific request. +def prepare_request(conf, data=None): + """Prepares a request + + This method takes care of authentication + and all other steps in the preparation chain. + + The request returned by this call is ready to + be sent to the server. + + :param conf: `cfg.ConfigOpts` instance to use. + :type conf: `cfg.ConfigOpts` + :param data: Optional data to send along with the + request. If data is not None, it'll be serialized. + :type data: Any primitive type that is json-serializable. + + :returns: A `Request` instance ready to be sent. + :rtype: `Request` """ - def __init__(self, endpoint='', operation='', params=None, headers=None): + req = Request() + auth_backend = auth.get_backend(conf) + # TODO(flaper87): Do something smarter + # to get the api_version. + req = auth_backend.authenticate(1, req) + + if data is not None: + req.content = json.dumps(data) + return req + + +class Request(object): + """General data for a Marconi request + + The idea is to be declarative i.e. specify *what* is desired. It's up to + the respective transport to turn this into a layer-specific request. + + *NOTE:* This implementation is not definitive and may change. + + :param endpoint: Server's endpoint + :type endpoint: str + :param operation: Operation to issue on the endpoint, i.e: + - get_queues + - get_messages + :type operation: str + :param content: Request's body. Default: None + :type content: str + :param params: Query string params. Default: None + :type params: dict + :param headers: Request headers. Default: None + :type headers: dict + """ + + def __init__(self, endpoint='', operation='', + content=None, params=None, headers=None): self.endpoint = endpoint self.operation = operation + self.content = content self.params = params or {} self.headers = headers or {} diff --git a/tests/unit/transport/test_request.py b/tests/unit/transport/test_request.py index d01044d1..f3d2ee87 100644 --- a/tests/unit/transport/test_request.py +++ b/tests/unit/transport/test_request.py @@ -13,6 +13,8 @@ # See the License for the specific language governing permissions and # limitations under the License. +import json + from marconiclient.tests import base from marconiclient.transport import request @@ -46,3 +48,14 @@ class TestRequest(base.TestBase): req = request.Request(endpoint=HREF, operation='delete_queue', params=dict(queue_name='xy', WAT='!?')) self.assertEqual("Invalid params: 'WAT'", req.validate()) + + def test_prepare_request(self): + req = request.prepare_request(self.conf) + self.assertTrue(isinstance(req, request.Request)) + self.assertIsNone(req.content) + + def test_prepare_request_with_data(self): + data = {"data": "tons of GBs"} + req = request.prepare_request(self.conf, data) + self.assertTrue(isinstance(req, request.Request)) + self.assertEquals(req.content, json.dumps(data))