Statistics
| Branch: | Tag: | Revision:

root / snf-astakos-client / astakosclient / __init__.py @ f8388a90

History | View | Annotate | Download (3.9 kB)

1
# Copyright (C) 2012, 2013 GRNET S.A. All rights reserved.
2
#
3
# Redistribution and use in source and binary forms, with or
4
# without modification, are permitted provided that the following
5
# conditions are met:
6
#
7
#   1. Redistributions of source code must retain the above
8
#      copyright notice, this list of conditions and the following
9
#      disclaimer.
10
#
11
#   2. Redistributions in binary form must reproduce the above
12
#      copyright notice, this list of conditions and the following
13
#      disclaimer in the documentation and/or other materials
14
#      provided with the distribution.
15
#
16
# THIS SOFTWARE IS PROVIDED BY GRNET S.A. ``AS IS'' AND ANY EXPRESS
17
# OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
19
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GRNET S.A OR
20
# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
23
# USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
24
# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
26
# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27
# POSSIBILITY OF SUCH DAMAGE.
28
#
29
# The views and conclusions contained in the software and
30
# documentation are those of the authors and should not be
31
# interpreted as representing official policies, either expressed
32
# or implied, of GRNET S.A.
33

    
34
import logging
35
import urlparse
36
import httplib
37

    
38
import simplejson
39
import objpool.http
40

    
41

    
42
logger = logging.getLogger(__name__)
43

    
44

    
45
# --------------------------------------------------------------------
46
# Private functions
47
def _scheme_to_class(scheme):
48
    """Return the appropriate httplib class for given scheme"""
49
    if scheme == "http":
50
        return httplib.HTTPConnection
51
    elif scheme == "https":
52
        return httplib.HTTPSConnection
53
    else:
54
        return None
55

    
56

    
57
def _doRequest(conn, method, url, **kwargs):
58
    """The actual request. This function can easily be mocked"""
59
    conn.request(method, url, **kwargs)
60
    response = conn.getresponse()
61
    length = response.getheader('content-length', None)
62
    data = response.read(length)
63
    status = int(response.status)
64
    return (status, data)
65

    
66

    
67
def _callAstakos(token, url, headers={}, body=None,
68
                 method='GET', use_pool=False):
69
    """Make the actual call to astakos service"""
70
    logger.debug("Make a %s request to %s with token %s, "
71
                 "headers %s and body %s, %s using the pool" %
72
                 (method, url, token, headers, body,
73
                     "not" if not use_pool else ""))
74

    
75
    # Build request's header and body
76
    kwargs = {}
77
    kwargs['headers'] = headers
78
    kwargs['headers']['X-Auth-Token'] = token
79
    if body:
80
        kwargs['body'] = body
81
        kwargs['headers'].setdefault(
82
            'content-type', 'application/octet-stream')
83
    kwargs['headers'].setdefault('content-length', len(body) if body else 0)
84

    
85
    # Check for supported scheme
86
    p = urlparse.urlparse(url)
87
    connection_class = _scheme_to_class(p.scheme)
88
    if connection_class is None:
89
        m = "Unsupported scheme: %s" % p.scheme
90
        logger.error(m)
91
        raise ValueError(m)
92

    
93
    # Get connection object
94
    if use_pool:
95
        conn = objpool.http.get_http_connection(p.netloc, p.scheme)
96
    else:
97
        conn = connection_class(p.netloc)
98

    
99
    # Send request
100
    try:
101
        request_url = p.path + '?' + p.query
102
        (status, data) = _doRequest(conn, method, request_url, **kwargs)
103
    except httplib.HTTPException as err:
104
        logger.error("Failed to send request: %s" % err)
105
        raise
106
    finally:
107
        conn.close()
108

    
109
    # Return
110
    logger.debug("Request returned with status %s" % status)
111
    if status < 200 or status >= 300:
112
        raise Exception(data, status)
113
    return simplejson.loads(unicode(data))