Statistics
| Branch: | Tag: | Revision:

root / snf-astakos-app / astakos / im / endpoints / qh.py @ b4be4eee

History | View | Annotate | Download (10.3 kB)

1 fc1e2f02 Sofia Papagiannaki
# Copyright 2011-2012 GRNET S.A. All rights reserved.
2 5ce3ce4f Sofia Papagiannaki
#
3 fc1e2f02 Sofia Papagiannaki
# Redistribution and use in source and binary forms, with or
4 fc1e2f02 Sofia Papagiannaki
# without modification, are permitted provided that the following
5 fc1e2f02 Sofia Papagiannaki
# conditions are met:
6 5ce3ce4f Sofia Papagiannaki
#
7 fc1e2f02 Sofia Papagiannaki
#   1. Redistributions of source code must retain the above
8 fc1e2f02 Sofia Papagiannaki
#      copyright notice, this list of conditions and the following
9 fc1e2f02 Sofia Papagiannaki
#      disclaimer.
10 5ce3ce4f Sofia Papagiannaki
#
11 fc1e2f02 Sofia Papagiannaki
#   2. Redistributions in binary form must reproduce the above
12 fc1e2f02 Sofia Papagiannaki
#      copyright notice, this list of conditions and the following
13 fc1e2f02 Sofia Papagiannaki
#      disclaimer in the documentation and/or other materials
14 fc1e2f02 Sofia Papagiannaki
#      provided with the distribution.
15 5ce3ce4f Sofia Papagiannaki
#
16 fc1e2f02 Sofia Papagiannaki
# THIS SOFTWARE IS PROVIDED BY GRNET S.A. ``AS IS'' AND ANY EXPRESS
17 fc1e2f02 Sofia Papagiannaki
# OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 fc1e2f02 Sofia Papagiannaki
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
19 fc1e2f02 Sofia Papagiannaki
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GRNET S.A OR
20 fc1e2f02 Sofia Papagiannaki
# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21 fc1e2f02 Sofia Papagiannaki
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22 fc1e2f02 Sofia Papagiannaki
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
23 fc1e2f02 Sofia Papagiannaki
# USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
24 fc1e2f02 Sofia Papagiannaki
# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25 fc1e2f02 Sofia Papagiannaki
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
26 fc1e2f02 Sofia Papagiannaki
# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27 fc1e2f02 Sofia Papagiannaki
# POSSIBILITY OF SUCH DAMAGE.
28 5ce3ce4f Sofia Papagiannaki
#
29 fc1e2f02 Sofia Papagiannaki
# The views and conclusions contained in the software and
30 fc1e2f02 Sofia Papagiannaki
# documentation are those of the authors and should not be
31 fc1e2f02 Sofia Papagiannaki
# interpreted as representing official policies, either expressed
32 fc1e2f02 Sofia Papagiannaki
# or implied, of GRNET S.A.
33 fc1e2f02 Sofia Papagiannaki
34 fc1e2f02 Sofia Papagiannaki
import logging
35 bd4f356c Sofia Papagiannaki
import itertools
36 bd4f356c Sofia Papagiannaki
37 bd4f356c Sofia Papagiannaki
from functools import wraps
38 4fc7d569 Sofia Papagiannaki
from collections import namedtuple
39 fc1e2f02 Sofia Papagiannaki
40 fc1e2f02 Sofia Papagiannaki
from django.utils.translation import ugettext as _
41 fc1e2f02 Sofia Papagiannaki
42 30d92d1e Georgios D. Tsoukalas
from astakos.im.settings import (
43 0ea1f32b Georgios D. Tsoukalas
        QUOTAHOLDER_URL, QUOTAHOLDER_TOKEN, LOGGING_LEVEL)
44 fc1e2f02 Sofia Papagiannaki
45 30d92d1e Georgios D. Tsoukalas
if QUOTAHOLDER_URL:
46 c836d69f Georgios D. Tsoukalas
    from kamaki.clients.quotaholder import QuotaholderClient
47 8b59b8ea Sofia Papagiannaki
48 fc1e2f02 Sofia Papagiannaki
ENTITY_KEY = '1'
49 4319c408 Kostas Papadimitriou
PRACTICALLY_INF = pow(2, 70)
50 fc1e2f02 Sofia Papagiannaki
51 ae497612 Olga Brani
inf = float('inf')
52 ae497612 Olga Brani
53 fc1e2f02 Sofia Papagiannaki
logger = logging.getLogger(__name__)
54 fc1e2f02 Sofia Papagiannaki
55 ae497612 Olga Brani
inf = float('inf')
56 5ce3ce4f Sofia Papagiannaki
57 ee45eb81 Giorgos Korfiatis
clientkey = 'astakos'
58 ee45eb81 Giorgos Korfiatis
59 73fbaec4 Sofia Papagiannaki
_client = None
60 73fbaec4 Sofia Papagiannaki
def get_client():
61 73fbaec4 Sofia Papagiannaki
    global _client
62 73fbaec4 Sofia Papagiannaki
    if _client:
63 73fbaec4 Sofia Papagiannaki
        return _client
64 73fbaec4 Sofia Papagiannaki
    if not QUOTAHOLDER_URL:
65 73fbaec4 Sofia Papagiannaki
        return
66 73fbaec4 Sofia Papagiannaki
    _client = QuotaholderClient(QUOTAHOLDER_URL, token=QUOTAHOLDER_TOKEN)
67 52116521 Sofia Papagiannaki
    return _client
68 73fbaec4 Sofia Papagiannaki
69 8978cfbd Sofia Papagiannaki
def set_quota(payload):
70 8978cfbd Sofia Papagiannaki
    c = get_client()
71 8978cfbd Sofia Papagiannaki
    if not c:
72 8978cfbd Sofia Papagiannaki
        return
73 8978cfbd Sofia Papagiannaki
    result = c.set_quota(context={}, clientkey=clientkey, set_quota=payload)
74 8978cfbd Sofia Papagiannaki
    logger.info('set_quota: %s rejected: %s' % (payload, result))
75 8978cfbd Sofia Papagiannaki
    return result
76 8978cfbd Sofia Papagiannaki
77 16cfac45 Sofia Papagiannaki
def get_quota(user):
78 8978cfbd Sofia Papagiannaki
    c = get_client()
79 8978cfbd Sofia Papagiannaki
    if not c:
80 8978cfbd Sofia Papagiannaki
        return
81 16cfac45 Sofia Papagiannaki
    payload = []
82 16cfac45 Sofia Papagiannaki
    append = payload.append
83 16cfac45 Sofia Papagiannaki
    for r in user.quota.keys():
84 16cfac45 Sofia Papagiannaki
        append((user.uuid, r, ENTITY_KEY),)
85 8978cfbd Sofia Papagiannaki
    result = c.get_quota(context={}, clientkey=clientkey, get_quota=payload)
86 8978cfbd Sofia Papagiannaki
    logger.info('get_quota: %s rejected: %s' % (payload, result))
87 8978cfbd Sofia Papagiannaki
    return result
88 8978cfbd Sofia Papagiannaki
89 8978cfbd Sofia Papagiannaki
def create_entity(payload):
90 8978cfbd Sofia Papagiannaki
    c = get_client()
91 8978cfbd Sofia Papagiannaki
    if not c:
92 8978cfbd Sofia Papagiannaki
        return
93 8978cfbd Sofia Papagiannaki
    result = c.create_entity(context={}, clientkey=clientkey, create_entity=payload)
94 8978cfbd Sofia Papagiannaki
    logger.info('create_entity: %s rejected: %s' % (payload, result))
95 8978cfbd Sofia Papagiannaki
    return result
96 5ce3ce4f Sofia Papagiannaki
97 8978cfbd Sofia Papagiannaki
SetQuotaPayload = namedtuple('SetQuotaPayload', ('holder',
98 8978cfbd Sofia Papagiannaki
                                                 'resource',
99 8978cfbd Sofia Papagiannaki
                                                 'key',
100 8978cfbd Sofia Papagiannaki
                                                 'quantity',
101 8978cfbd Sofia Papagiannaki
                                                 'capacity',
102 8978cfbd Sofia Papagiannaki
                                                 'import_limit',
103 8978cfbd Sofia Papagiannaki
                                                 'export_limit',
104 8978cfbd Sofia Papagiannaki
                                                 'flags'))
105 8978cfbd Sofia Papagiannaki
106 8978cfbd Sofia Papagiannaki
GetQuotaPayload = namedtuple('GetQuotaPayload', ('holder',
107 8978cfbd Sofia Papagiannaki
                                                 'resource',
108 8978cfbd Sofia Papagiannaki
                                                 'key'))
109 8978cfbd Sofia Papagiannaki
110 8978cfbd Sofia Papagiannaki
CreateEntityPayload = namedtuple('CreateEntityPayload', ('entity',
111 16cfac45 Sofia Papagiannaki
                                                         'owner',
112 16cfac45 Sofia Papagiannaki
                                                         'key',
113 16cfac45 Sofia Papagiannaki
                                                         'ownerkey'))
114 2a97d93b Giorgos Korfiatis
QuotaLimits = namedtuple('QuotaLimits', ('holder',
115 5cfd4acb Sofia Papagiannaki
                                         'resource',
116 2a97d93b Giorgos Korfiatis
                                         'capacity',
117 2a97d93b Giorgos Korfiatis
                                         'import_limit',
118 2a97d93b Giorgos Korfiatis
                                         'export_limit'))
119 2a97d93b Giorgos Korfiatis
120 b4be4eee Giorgos Korfiatis
def qh_register_user(user):
121 b4be4eee Giorgos Korfiatis
    return register_users([user])
122 b4be4eee Giorgos Korfiatis
123 8978cfbd Sofia Papagiannaki
def register_users(users):
124 8978cfbd Sofia Papagiannaki
    payload = list(CreateEntityPayload(
125 8978cfbd Sofia Papagiannaki
                    entity=u.uuid,
126 8978cfbd Sofia Papagiannaki
                    owner='system',
127 8978cfbd Sofia Papagiannaki
                    key=ENTITY_KEY,
128 8978cfbd Sofia Papagiannaki
                    ownerkey='') for u in users)
129 8978cfbd Sofia Papagiannaki
    rejected = create_entity(payload)
130 8978cfbd Sofia Papagiannaki
    if not rejected:
131 8978cfbd Sofia Papagiannaki
        payload = []
132 8978cfbd Sofia Papagiannaki
        append = payload.append
133 8978cfbd Sofia Papagiannaki
        for u in users:
134 8978cfbd Sofia Papagiannaki
            for resource, uplimit in u.quota.iteritems():
135 8978cfbd Sofia Papagiannaki
                append( SetQuotaPayload(
136 8978cfbd Sofia Papagiannaki
                                holder=u.uuid,
137 8978cfbd Sofia Papagiannaki
                                resource=resource,
138 8978cfbd Sofia Papagiannaki
                                key=ENTITY_KEY,
139 0b73f8e4 Sofia Papagiannaki
                                quantity=0,
140 8978cfbd Sofia Papagiannaki
                                capacity=uplimit if uplimit != inf else None,
141 de8859f1 Sofia Papagiannaki
                                import_limit=PRACTICALLY_INF,
142 de8859f1 Sofia Papagiannaki
                                export_limit=PRACTICALLY_INF,
143 8978cfbd Sofia Papagiannaki
                                flags=0))
144 8978cfbd Sofia Papagiannaki
        return set_quota(payload)
145 8978cfbd Sofia Papagiannaki
146 8978cfbd Sofia Papagiannaki
147 8978cfbd Sofia Papagiannaki
def register_resources(resources):
148 8978cfbd Sofia Papagiannaki
    rdata = ((r.service, r) for r in resources)
149 8978cfbd Sofia Papagiannaki
    services = set(r.service for r in resources)
150 8978cfbd Sofia Papagiannaki
    payload = list(CreateEntityPayload(
151 8978cfbd Sofia Papagiannaki
                    entity=service,
152 8978cfbd Sofia Papagiannaki
                    owner='system',
153 8978cfbd Sofia Papagiannaki
                    key=ENTITY_KEY,
154 8978cfbd Sofia Papagiannaki
                    ownerkey='') for service in set(services))
155 8978cfbd Sofia Papagiannaki
    rejected = create_entity(payload)
156 8978cfbd Sofia Papagiannaki
    if not rejected:
157 8978cfbd Sofia Papagiannaki
        payload = list(SetQuotaPayload(
158 8978cfbd Sofia Papagiannaki
                        holder=resource.service,
159 8978cfbd Sofia Papagiannaki
                        resource=resource,
160 8978cfbd Sofia Papagiannaki
                        key=ENTITY_KEY,
161 af877ee0 root
                        quantity=PRACTICALLY_INF,
162 de8859f1 Sofia Papagiannaki
                        capacity=0,
163 de8859f1 Sofia Papagiannaki
                        import_limit=PRACTICALLY_INF,
164 de8859f1 Sofia Papagiannaki
                        export_limit=PRACTICALLY_INF,
165 8978cfbd Sofia Papagiannaki
                        flags=0) for resource in resources)
166 8978cfbd Sofia Papagiannaki
        return set_quota(payload)
167 8978cfbd Sofia Papagiannaki
168 d2b32360 Giorgos Korfiatis
def qh_add_quota(serial, sub_list, add_list):
169 ee45eb81 Giorgos Korfiatis
    if not QUOTAHOLDER_URL:
170 ee45eb81 Giorgos Korfiatis
        return ()
171 ee45eb81 Giorgos Korfiatis
172 ee45eb81 Giorgos Korfiatis
    context = {}
173 ee45eb81 Giorgos Korfiatis
    c = get_client()
174 4319c408 Kostas Papadimitriou
175 d2b32360 Giorgos Korfiatis
    sub_quota = []
176 d2b32360 Giorgos Korfiatis
    sub_append = sub_quota.append
177 d2b32360 Giorgos Korfiatis
    add_quota = []
178 d2b32360 Giorgos Korfiatis
    add_append = add_quota.append
179 d2b32360 Giorgos Korfiatis
180 5cfd4acb Sofia Papagiannaki
    for ql in sub_list:
181 d2b32360 Giorgos Korfiatis
        args = (ql.holder, ql.resource, ENTITY_KEY,
182 d2b32360 Giorgos Korfiatis
                0, ql.capacity, ql.import_limit, ql.export_limit)
183 d2b32360 Giorgos Korfiatis
        sub_append(args)
184 d2b32360 Giorgos Korfiatis
185 5cfd4acb Sofia Papagiannaki
    for ql in add_list:
186 2a97d93b Giorgos Korfiatis
        args = (ql.holder, ql.resource, ENTITY_KEY,
187 2a97d93b Giorgos Korfiatis
                0, ql.capacity, ql.import_limit, ql.export_limit)
188 d2b32360 Giorgos Korfiatis
        add_append(args)
189 2a97d93b Giorgos Korfiatis
190 ee45eb81 Giorgos Korfiatis
    result = c.add_quota(context=context,
191 ee45eb81 Giorgos Korfiatis
                         clientkey=clientkey,
192 ee45eb81 Giorgos Korfiatis
                         serial=serial,
193 d2b32360 Giorgos Korfiatis
                         sub_quota=sub_quota,
194 d2b32360 Giorgos Korfiatis
                         add_quota=add_quota)
195 ee45eb81 Giorgos Korfiatis
196 ee45eb81 Giorgos Korfiatis
    return result
197 ee45eb81 Giorgos Korfiatis
198 ee45eb81 Giorgos Korfiatis
def qh_query_serials(serials):
199 ee45eb81 Giorgos Korfiatis
    if not QUOTAHOLDER_URL:
200 ee45eb81 Giorgos Korfiatis
        return ()
201 ee45eb81 Giorgos Korfiatis
202 ee45eb81 Giorgos Korfiatis
    context = {}
203 ee45eb81 Giorgos Korfiatis
    c = get_client()
204 ee45eb81 Giorgos Korfiatis
    result = c.query_serials(context=context,
205 ee45eb81 Giorgos Korfiatis
                             clientkey=clientkey,
206 ee45eb81 Giorgos Korfiatis
                             serials=serials)
207 ee45eb81 Giorgos Korfiatis
    return result
208 ee45eb81 Giorgos Korfiatis
209 ee45eb81 Giorgos Korfiatis
def qh_ack_serials(serials):
210 ee45eb81 Giorgos Korfiatis
    if not QUOTAHOLDER_URL:
211 ee45eb81 Giorgos Korfiatis
        return ()
212 ee45eb81 Giorgos Korfiatis
213 ee45eb81 Giorgos Korfiatis
    context = {}
214 ee45eb81 Giorgos Korfiatis
    c = get_client()
215 ee45eb81 Giorgos Korfiatis
    result = c.ack_serials(context=context,
216 ee45eb81 Giorgos Korfiatis
                           clientkey=clientkey,
217 ee45eb81 Giorgos Korfiatis
                           serials=serials)
218 ee45eb81 Giorgos Korfiatis
    return
219 5ce3ce4f Sofia Papagiannaki
220 2925e285 root
from datetime import datetime
221 2925e285 root
222 2925e285 root
strptime = datetime.strptime
223 2925e285 root
timefmt = '%Y-%m-%dT%H:%M:%S.%f'
224 2925e285 root
225 476fdba1 root
SECOND_RESOLUTION = 1
226 476fdba1 root
227 9a06d96f Olga Brani
228 2925e285 root
def total_seconds(timedelta_object):
229 2925e285 root
    return timedelta_object.seconds + timedelta_object.days * 86400
230 2925e285 root
231 9a06d96f Olga Brani
232 476fdba1 root
def iter_timeline(timeline, before):
233 476fdba1 root
    if not timeline:
234 476fdba1 root
        return
235 476fdba1 root
236 476fdba1 root
    for t in timeline:
237 476fdba1 root
        yield t
238 476fdba1 root
239 476fdba1 root
    t = dict(t)
240 476fdba1 root
    t['issue_time'] = before
241 476fdba1 root
    yield t
242 476fdba1 root
243 9a06d96f Olga Brani
244 476fdba1 root
def _usage_units(timeline, after, before, details=0):
245 476fdba1 root
246 2925e285 root
    t_total = 0
247 476fdba1 root
    uu_total = 0
248 476fdba1 root
    t_after = strptime(after, timefmt)
249 476fdba1 root
    t_before = strptime(before, timefmt)
250 476fdba1 root
    t0 = t_after
251 476fdba1 root
    u0 = 0
252 2925e285 root
253 476fdba1 root
    for point in iter_timeline(timeline, before):
254 2925e285 root
        issue_time = point['issue_time']
255 2925e285 root
256 476fdba1 root
        if issue_time <= after:
257 476fdba1 root
            u0 = point['target_allocated_through']
258 2925e285 root
            continue
259 2925e285 root
260 476fdba1 root
        t = strptime(issue_time, timefmt) if issue_time <= before else t_before
261 476fdba1 root
        t_diff = int(total_seconds(t - t0) * SECOND_RESOLUTION)
262 2925e285 root
        t_total += t_diff
263 2925e285 root
        uu_cost = u0 * t_diff
264 2925e285 root
        uu_total += uu_cost
265 476fdba1 root
        t0 = t
266 476fdba1 root
        u0 = point['target_allocated_through']
267 2925e285 root
268 476fdba1 root
        target = point['target']
269 2925e285 root
        if details:
270 2925e285 root
            yield  (target,
271 2925e285 root
                    point['resource'],
272 2925e285 root
                    point['name'],
273 2925e285 root
                    issue_time,
274 2925e285 root
                    uu_cost,
275 2925e285 root
                    uu_total)
276 2925e285 root
277 2925e285 root
    if not t_total:
278 2925e285 root
        return
279 2925e285 root
280 2925e285 root
    yield  (target,
281 2925e285 root
            'total',
282 2925e285 root
            point['resource'],
283 2925e285 root
            issue_time,
284 9a06d96f Olga Brani
            uu_total / t_total,
285 2925e285 root
            uu_total)
286 2925e285 root
287 9a06d96f Olga Brani
288 476fdba1 root
def usage_units(timeline, after, before, details=0):
289 476fdba1 root
    return list(_usage_units(timeline, after, before, details=details))
290 2925e285 root
291 9a06d96f Olga Brani
292 476fdba1 root
def traffic_units(timeline, after, before, details=0):
293 82b05401 root
    tu_total = 0
294 82b05401 root
    target = None
295 82b05401 root
    issue_time = None
296 82b05401 root
297 82b05401 root
    for point in timeline:
298 82b05401 root
        issue_time = point['issue_time']
299 476fdba1 root
        if issue_time <= after:
300 476fdba1 root
            continue
301 476fdba1 root
        if issue_time > before:
302 476fdba1 root
            break
303 476fdba1 root
304 476fdba1 root
        target = point['target']
305 82b05401 root
        tu = point['target_allocated_through']
306 82b05401 root
        tu_total += tu
307 82b05401 root
308 82b05401 root
        if details:
309 82b05401 root
            yield  (target,
310 82b05401 root
                    point['resource'],
311 82b05401 root
                    point['name'],
312 82b05401 root
                    issue_time,
313 82b05401 root
                    tu,
314 82b05401 root
                    tu_total)
315 82b05401 root
316 82b05401 root
    if not tu_total:
317 82b05401 root
        return
318 82b05401 root
319 82b05401 root
    yield  (target,
320 82b05401 root
            'total',
321 82b05401 root
            point['resource'],
322 82b05401 root
            issue_time,
323 9a06d96f Olga Brani
            tu_total // len(timeline),
324 82b05401 root
            tu_total)
325 2925e285 root
326 9a06d96f Olga Brani
327 2925e285 root
def timeline_charge(entity, resource, after, before, details, charge_type):
328 2925e285 root
    key = '1'
329 2925e285 root
    if charge_type == 'charge_usage':
330 2925e285 root
        charge_units = usage_units
331 2925e285 root
    elif charge_type == 'charge_traffic':
332 2925e285 root
        charge_units = traffic_units
333 2925e285 root
    else:
334 2925e285 root
        m = 'charge type %s not supported' % charge_type
335 2925e285 root
        raise ValueError(m)
336 2925e285 root
337 30d92d1e Georgios D. Tsoukalas
    quotaholder = QuotaholderClient(QUOTAHOLDER_URL, token=QUOTAHOLDER_TOKEN)
338 2925e285 root
    timeline = quotaholder.get_timeline(
339 9a06d96f Olga Brani
        context={},
340 9a06d96f Olga Brani
        after=after,
341 9a06d96f Olga Brani
        before=before,
342 9a06d96f Olga Brani
        get_timeline=[[entity, resource, key]])
343 476fdba1 root
    cu = charge_units(timeline, after, before, details=details)
344 82b05401 root
    return cu