Statistics
| Branch: | Tag: | Revision:

root / snf-astakos-app / astakos / api / quotas.py @ 18f21257

History | View | Annotate | Download (7.1 kB)

1
# Copyright 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
from django.utils import simplejson as json
35
from django.views.decorators.csrf import csrf_exempt
36
from django.http import HttpResponse
37

    
38
from synnefo.lib.db.transaction import commit_on_success_strict
39
from astakos.api.util import json_response
40
from astakos.im.api.user import api_method as user_api_method
41
from astakos.im.api.service import api_method as service_api_method
42
from astakos.im.api.faults import BadRequest, InternalServerError
43
from astakos.im.quotas import get_user_quotas
44

    
45
import astakos.quotaholder.exception as qh_exception
46
from astakos.quotaholder.callpoint import QuotaholderDjangoDBCallpoint
47
qh = QuotaholderDjangoDBCallpoint()
48

    
49

    
50
@user_api_method(http_method='GET', token_required=True)
51
def quotas(request, user=None):
52
    result = get_user_quotas(user)
53
    return json_response(result)
54

    
55

    
56
@csrf_exempt
57
def commissions(request):
58
    method = request.method
59
    if method == 'GET':
60
        return get_pending_commissions(request)
61
    elif method == 'POST':
62
        return issue_commission(request)
63
    else:
64
        raise BadRequest('Method not allowed.')
65

    
66

    
67
@service_api_method(http_method='GET', token_required=True)
68
def get_pending_commissions(request):
69
    data = request.GET
70
    client_key = data['client_key']
71

    
72
    result = qh.get_pending_commissions(clientkey=client_key)
73
    return json_response(result)
74

    
75

    
76
@csrf_exempt
77
@service_api_method(http_method='POST', token_required=True)
78
def issue_commission(request):
79
    data = request.raw_post_data
80
    input_data = json.loads(data)
81

    
82
    client_key = input_data['client_key']
83
    provisions = input_data['provisions']
84
    force = input_data.get('force', False)
85
    auto_accept = input_data.get('auto_accept', False)
86

    
87
    try:
88
        result = _issue_commission(clientkey=client_key,
89
                                   provisions=provisions,
90
                                   force=force,
91
                                   accept=auto_accept)
92
        data = {"serial": result}
93
        status_code = 201
94
    except (qh_exception.NoCapacityError,
95
            qh_exception.NoQuantityError) as e:
96
        status_code = 413
97
        body = {"message": e.message,
98
                "code": status_code,
99
                "data": e.data,
100
                }
101
        data = {"overLimit": body}
102
    except qh_exception.NoHoldingError as e:
103
        status_code = 404
104
        body = {"message": e.message,
105
                "code": status_code,
106
                "data": e.data,
107
                }
108
        data = {"itemNotFound": body}
109
    except qh_exception.InvalidDataError as e:
110
        status_code = 400
111
        body = {"message": e.message,
112
                "code": status_code,
113
                }
114
        data = {"badRequest": body}
115

    
116
    return json_response(data, status_code=status_code)
117

    
118

    
119
@commit_on_success_strict()
120
def _issue_commission(clientkey, provisions, force, accept):
121
    serial = qh.issue_commission(clientkey=clientkey,
122
                                 provisions=provisions,
123
                                 force=force)
124
    if accept:
125
        done = qh.accept_commission(clientkey=clientkey,
126
                                    serial=serial)
127

    
128
    return serial
129

    
130

    
131
def failed_to_cloudfault(failed):
132
    serial, reason = failed
133
    if reason == 'NOTFOUND':
134
        body = {"code": 404,
135
                "message": "serial %s does not exist" % serial,
136
                }
137
        cloudfault = {"itemNotFound": body}
138
    elif reason == 'CONFLICT':
139
        body = {"code": 400,
140
                "message": "cannot both accept and reject serial %s" % serial,
141
                }
142
        cloudfault = {"badRequest": body}
143
    else:
144
        raise InternalServerError('Unexpected error')
145
    return (serial, cloudfault)
146

    
147

    
148
@csrf_exempt
149
@service_api_method(http_method='POST', token_required=True)
150
@commit_on_success_strict()
151
def resolve_pending_commissions(request):
152
    data = request.raw_post_data
153
    input_data = json.loads(data)
154

    
155
    client_key = input_data['client_key']
156
    accept = input_data.get('accept', [])
157
    reject = input_data.get('reject', [])
158

    
159
    result = qh.resolve_pending_commissions(clientkey=client_key,
160
                                            accept_set=accept,
161
                                            reject_set=reject)
162
    accepted, rejected, failed = result
163
    cloudfaults = [failed_to_cloudfault(f) for f in failed]
164
    data = {'accepted': accepted,
165
            'rejected': rejected,
166
            'failed': cloudfaults
167
            }
168

    
169
    return json_response(data)
170

    
171

    
172
@service_api_method(http_method='GET', token_required=True)
173
def get_commission(request, serial):
174
    data = request.GET
175
    client_key = data['client_key']
176
    serial = int(serial)
177

    
178
    try:
179
        data = qh.get_commission(clientkey=client_key,
180
                                 serial=serial)
181
        status_code = 200
182
        return json_response(data, status_code)
183
    except qh_exception.NoCommissionError as e:
184
        return HttpResponse(status=404)
185

    
186

    
187
@csrf_exempt
188
@service_api_method(http_method='POST', token_required=True)
189
@commit_on_success_strict()
190
def serial_action(request, serial):
191
    data = request.raw_post_data
192
    input_data = json.loads(data)
193
    serial = int(serial)
194

    
195
    client_key = input_data['client_key']
196

    
197
    accept = 'accept' in input_data
198
    reject = 'reject' in input_data
199

    
200
    if accept == reject:
201
        raise BadRequest('Specify either accept or reject action.')
202

    
203
    if accept:
204
        result = qh.accept_commission(clientkey=client_key,
205
                                      serial=serial)
206
    else:
207
        result = qh.reject_commission(clientkey=client_key,
208
                                      serial=serial)
209

    
210
    response = HttpResponse()
211
    if not result:
212
        response.status_code = 404
213

    
214
    return response