Statistics
| Branch: | Tag: | Revision:

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

History | View | Annotate | Download (10.2 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 fc1e2f02 Sofia Papagiannaki
50 ae497612 Olga Brani
inf = float('inf')
51 ae497612 Olga Brani
52 fc1e2f02 Sofia Papagiannaki
logger = logging.getLogger(__name__)
53 fc1e2f02 Sofia Papagiannaki
54 ae497612 Olga Brani
inf = float('inf')
55 5ce3ce4f Sofia Papagiannaki
56 ee45eb81 Giorgos Korfiatis
clientkey = 'astakos'
57 ee45eb81 Giorgos Korfiatis
58 73fbaec4 Sofia Papagiannaki
_client = None
59 73fbaec4 Sofia Papagiannaki
def get_client():
60 73fbaec4 Sofia Papagiannaki
    global _client
61 73fbaec4 Sofia Papagiannaki
    if _client:
62 73fbaec4 Sofia Papagiannaki
        return _client
63 73fbaec4 Sofia Papagiannaki
    if not QUOTAHOLDER_URL:
64 73fbaec4 Sofia Papagiannaki
        return
65 73fbaec4 Sofia Papagiannaki
    _client = QuotaholderClient(QUOTAHOLDER_URL, token=QUOTAHOLDER_TOKEN)
66 52116521 Sofia Papagiannaki
    return _client
67 73fbaec4 Sofia Papagiannaki
68 8978cfbd Sofia Papagiannaki
def set_quota(payload):
69 8978cfbd Sofia Papagiannaki
    c = get_client()
70 8978cfbd Sofia Papagiannaki
    if not c:
71 8978cfbd Sofia Papagiannaki
        return
72 8978cfbd Sofia Papagiannaki
    result = c.set_quota(context={}, clientkey=clientkey, set_quota=payload)
73 8978cfbd Sofia Papagiannaki
    logger.info('set_quota: %s rejected: %s' % (payload, result))
74 8978cfbd Sofia Papagiannaki
    return result
75 8978cfbd Sofia Papagiannaki
76 16cfac45 Sofia Papagiannaki
def get_quota(user):
77 8978cfbd Sofia Papagiannaki
    c = get_client()
78 8978cfbd Sofia Papagiannaki
    if not c:
79 8978cfbd Sofia Papagiannaki
        return
80 16cfac45 Sofia Papagiannaki
    payload = []
81 16cfac45 Sofia Papagiannaki
    append = payload.append
82 16cfac45 Sofia Papagiannaki
    for r in user.quota.keys():
83 16cfac45 Sofia Papagiannaki
        append((user.uuid, r, ENTITY_KEY),)
84 8978cfbd Sofia Papagiannaki
    result = c.get_quota(context={}, clientkey=clientkey, get_quota=payload)
85 8978cfbd Sofia Papagiannaki
    logger.info('get_quota: %s rejected: %s' % (payload, result))
86 8978cfbd Sofia Papagiannaki
    return result
87 8978cfbd Sofia Papagiannaki
88 8978cfbd Sofia Papagiannaki
def create_entity(payload):
89 8978cfbd Sofia Papagiannaki
    c = get_client()
90 8978cfbd Sofia Papagiannaki
    if not c:
91 8978cfbd Sofia Papagiannaki
        return
92 8978cfbd Sofia Papagiannaki
    result = c.create_entity(context={}, clientkey=clientkey, create_entity=payload)
93 8978cfbd Sofia Papagiannaki
    logger.info('create_entity: %s rejected: %s' % (payload, result))
94 8978cfbd Sofia Papagiannaki
    return result
95 5ce3ce4f Sofia Papagiannaki
96 8978cfbd Sofia Papagiannaki
SetQuotaPayload = namedtuple('SetQuotaPayload', ('holder',
97 8978cfbd Sofia Papagiannaki
                                                 'resource',
98 8978cfbd Sofia Papagiannaki
                                                 'key',
99 8978cfbd Sofia Papagiannaki
                                                 'quantity',
100 8978cfbd Sofia Papagiannaki
                                                 'capacity',
101 8978cfbd Sofia Papagiannaki
                                                 'import_limit',
102 8978cfbd Sofia Papagiannaki
                                                 'export_limit',
103 8978cfbd Sofia Papagiannaki
                                                 'flags'))
104 8978cfbd Sofia Papagiannaki
105 8978cfbd Sofia Papagiannaki
GetQuotaPayload = namedtuple('GetQuotaPayload', ('holder',
106 8978cfbd Sofia Papagiannaki
                                                 'resource',
107 8978cfbd Sofia Papagiannaki
                                                 'key'))
108 8978cfbd Sofia Papagiannaki
109 8978cfbd Sofia Papagiannaki
CreateEntityPayload = namedtuple('CreateEntityPayload', ('entity',
110 16cfac45 Sofia Papagiannaki
                                                         'owner',
111 16cfac45 Sofia Papagiannaki
                                                         'key',
112 16cfac45 Sofia Papagiannaki
                                                         'ownerkey'))
113 2a97d93b Giorgos Korfiatis
QuotaLimits = namedtuple('QuotaLimits', ('holder',
114 5cfd4acb Sofia Papagiannaki
                                         'resource',
115 2a97d93b Giorgos Korfiatis
                                         'capacity',
116 2a97d93b Giorgos Korfiatis
                                         'import_limit',
117 2a97d93b Giorgos Korfiatis
                                         'export_limit'))
118 2a97d93b Giorgos Korfiatis
119 8978cfbd Sofia Papagiannaki
def register_users(users):
120 8978cfbd Sofia Papagiannaki
    payload = list(CreateEntityPayload(
121 8978cfbd Sofia Papagiannaki
                    entity=u.uuid,
122 8978cfbd Sofia Papagiannaki
                    owner='system',
123 8978cfbd Sofia Papagiannaki
                    key=ENTITY_KEY,
124 8978cfbd Sofia Papagiannaki
                    ownerkey='') for u in users)
125 8978cfbd Sofia Papagiannaki
    rejected = create_entity(payload)
126 8978cfbd Sofia Papagiannaki
    if not rejected:
127 8978cfbd Sofia Papagiannaki
        payload = []
128 8978cfbd Sofia Papagiannaki
        append = payload.append
129 8978cfbd Sofia Papagiannaki
        for u in users:
130 8978cfbd Sofia Papagiannaki
            for resource, uplimit in u.quota.iteritems():
131 8978cfbd Sofia Papagiannaki
                append( SetQuotaPayload(
132 8978cfbd Sofia Papagiannaki
                                holder=u.uuid,
133 8978cfbd Sofia Papagiannaki
                                resource=resource,
134 8978cfbd Sofia Papagiannaki
                                key=ENTITY_KEY,
135 0b73f8e4 Sofia Papagiannaki
                                quantity=0,
136 8978cfbd Sofia Papagiannaki
                                capacity=uplimit if uplimit != inf else None,
137 0b73f8e4 Sofia Papagiannaki
                                import_limit=0,
138 0b73f8e4 Sofia Papagiannaki
                                export_limit=0,
139 8978cfbd Sofia Papagiannaki
                                flags=0))
140 8978cfbd Sofia Papagiannaki
        return set_quota(payload)
141 8978cfbd Sofia Papagiannaki
142 8978cfbd Sofia Papagiannaki
143 8978cfbd Sofia Papagiannaki
def register_resources(resources):
144 8978cfbd Sofia Papagiannaki
    rdata = ((r.service, r) for r in resources)
145 8978cfbd Sofia Papagiannaki
    services = set(r.service for r in resources)
146 8978cfbd Sofia Papagiannaki
    payload = list(CreateEntityPayload(
147 8978cfbd Sofia Papagiannaki
                    entity=service,
148 8978cfbd Sofia Papagiannaki
                    owner='system',
149 8978cfbd Sofia Papagiannaki
                    key=ENTITY_KEY,
150 8978cfbd Sofia Papagiannaki
                    ownerkey='') for service in set(services))
151 8978cfbd Sofia Papagiannaki
    rejected = create_entity(payload)
152 8978cfbd Sofia Papagiannaki
    if not rejected:
153 8978cfbd Sofia Papagiannaki
        payload = list(SetQuotaPayload(
154 8978cfbd Sofia Papagiannaki
                        holder=resource.service,
155 8978cfbd Sofia Papagiannaki
                        resource=resource,
156 8978cfbd Sofia Papagiannaki
                        key=ENTITY_KEY,
157 8978cfbd Sofia Papagiannaki
                        quantity=None,
158 8978cfbd Sofia Papagiannaki
                        capacity=None,
159 8978cfbd Sofia Papagiannaki
                        import_limit=None,
160 8978cfbd Sofia Papagiannaki
                        export_limit=None,
161 8978cfbd Sofia Papagiannaki
                        flags=0) for resource in resources)
162 8978cfbd Sofia Papagiannaki
        return set_quota(payload)
163 8978cfbd Sofia Papagiannaki
164 d2b32360 Giorgos Korfiatis
def qh_add_quota(serial, sub_list, add_list):
165 ee45eb81 Giorgos Korfiatis
    if not QUOTAHOLDER_URL:
166 ee45eb81 Giorgos Korfiatis
        return ()
167 ee45eb81 Giorgos Korfiatis
168 ee45eb81 Giorgos Korfiatis
    context = {}
169 ee45eb81 Giorgos Korfiatis
    c = get_client()
170 5cfd4acb Sofia Papagiannaki
    
171 d2b32360 Giorgos Korfiatis
    sub_quota = []
172 d2b32360 Giorgos Korfiatis
    sub_append = sub_quota.append
173 d2b32360 Giorgos Korfiatis
    add_quota = []
174 d2b32360 Giorgos Korfiatis
    add_append = add_quota.append
175 d2b32360 Giorgos Korfiatis
176 5cfd4acb Sofia Papagiannaki
    for ql in sub_list:
177 d2b32360 Giorgos Korfiatis
        args = (ql.holder, ql.resource, ENTITY_KEY,
178 d2b32360 Giorgos Korfiatis
                0, ql.capacity, ql.import_limit, ql.export_limit)
179 d2b32360 Giorgos Korfiatis
        sub_append(args)
180 d2b32360 Giorgos Korfiatis
181 5cfd4acb Sofia Papagiannaki
    for ql in add_list:
182 2a97d93b Giorgos Korfiatis
        args = (ql.holder, ql.resource, ENTITY_KEY,
183 2a97d93b Giorgos Korfiatis
                0, ql.capacity, ql.import_limit, ql.export_limit)
184 d2b32360 Giorgos Korfiatis
        add_append(args)
185 2a97d93b Giorgos Korfiatis
186 ee45eb81 Giorgos Korfiatis
    result = c.add_quota(context=context,
187 ee45eb81 Giorgos Korfiatis
                         clientkey=clientkey,
188 ee45eb81 Giorgos Korfiatis
                         serial=serial,
189 d2b32360 Giorgos Korfiatis
                         sub_quota=sub_quota,
190 d2b32360 Giorgos Korfiatis
                         add_quota=add_quota)
191 ee45eb81 Giorgos Korfiatis
192 ee45eb81 Giorgos Korfiatis
    return result
193 ee45eb81 Giorgos Korfiatis
194 ee45eb81 Giorgos Korfiatis
def qh_query_serials(serials):
195 ee45eb81 Giorgos Korfiatis
    if not QUOTAHOLDER_URL:
196 ee45eb81 Giorgos Korfiatis
        return ()
197 ee45eb81 Giorgos Korfiatis
198 ee45eb81 Giorgos Korfiatis
    context = {}
199 ee45eb81 Giorgos Korfiatis
    c = get_client()
200 ee45eb81 Giorgos Korfiatis
    result = c.query_serials(context=context,
201 ee45eb81 Giorgos Korfiatis
                             clientkey=clientkey,
202 ee45eb81 Giorgos Korfiatis
                             serials=serials)
203 ee45eb81 Giorgos Korfiatis
    return result
204 ee45eb81 Giorgos Korfiatis
205 ee45eb81 Giorgos Korfiatis
def qh_ack_serials(serials):
206 ee45eb81 Giorgos Korfiatis
    if not QUOTAHOLDER_URL:
207 ee45eb81 Giorgos Korfiatis
        return ()
208 ee45eb81 Giorgos Korfiatis
209 ee45eb81 Giorgos Korfiatis
    context = {}
210 ee45eb81 Giorgos Korfiatis
    c = get_client()
211 ee45eb81 Giorgos Korfiatis
    result = c.ack_serials(context=context,
212 ee45eb81 Giorgos Korfiatis
                           clientkey=clientkey,
213 ee45eb81 Giorgos Korfiatis
                           serials=serials)
214 ee45eb81 Giorgos Korfiatis
    return
215 5ce3ce4f Sofia Papagiannaki
216 2925e285 root
from datetime import datetime
217 2925e285 root
218 2925e285 root
strptime = datetime.strptime
219 2925e285 root
timefmt = '%Y-%m-%dT%H:%M:%S.%f'
220 2925e285 root
221 476fdba1 root
SECOND_RESOLUTION = 1
222 476fdba1 root
223 9a06d96f Olga Brani
224 2925e285 root
def total_seconds(timedelta_object):
225 2925e285 root
    return timedelta_object.seconds + timedelta_object.days * 86400
226 2925e285 root
227 9a06d96f Olga Brani
228 476fdba1 root
def iter_timeline(timeline, before):
229 476fdba1 root
    if not timeline:
230 476fdba1 root
        return
231 476fdba1 root
232 476fdba1 root
    for t in timeline:
233 476fdba1 root
        yield t
234 476fdba1 root
235 476fdba1 root
    t = dict(t)
236 476fdba1 root
    t['issue_time'] = before
237 476fdba1 root
    yield t
238 476fdba1 root
239 9a06d96f Olga Brani
240 476fdba1 root
def _usage_units(timeline, after, before, details=0):
241 476fdba1 root
242 2925e285 root
    t_total = 0
243 476fdba1 root
    uu_total = 0
244 476fdba1 root
    t_after = strptime(after, timefmt)
245 476fdba1 root
    t_before = strptime(before, timefmt)
246 476fdba1 root
    t0 = t_after
247 476fdba1 root
    u0 = 0
248 2925e285 root
249 476fdba1 root
    for point in iter_timeline(timeline, before):
250 2925e285 root
        issue_time = point['issue_time']
251 2925e285 root
252 476fdba1 root
        if issue_time <= after:
253 476fdba1 root
            u0 = point['target_allocated_through']
254 2925e285 root
            continue
255 2925e285 root
256 476fdba1 root
        t = strptime(issue_time, timefmt) if issue_time <= before else t_before
257 476fdba1 root
        t_diff = int(total_seconds(t - t0) * SECOND_RESOLUTION)
258 2925e285 root
        t_total += t_diff
259 2925e285 root
        uu_cost = u0 * t_diff
260 2925e285 root
        uu_total += uu_cost
261 476fdba1 root
        t0 = t
262 476fdba1 root
        u0 = point['target_allocated_through']
263 2925e285 root
264 476fdba1 root
        target = point['target']
265 2925e285 root
        if details:
266 2925e285 root
            yield  (target,
267 2925e285 root
                    point['resource'],
268 2925e285 root
                    point['name'],
269 2925e285 root
                    issue_time,
270 2925e285 root
                    uu_cost,
271 2925e285 root
                    uu_total)
272 2925e285 root
273 2925e285 root
    if not t_total:
274 2925e285 root
        return
275 2925e285 root
276 2925e285 root
    yield  (target,
277 2925e285 root
            'total',
278 2925e285 root
            point['resource'],
279 2925e285 root
            issue_time,
280 9a06d96f Olga Brani
            uu_total / t_total,
281 2925e285 root
            uu_total)
282 2925e285 root
283 9a06d96f Olga Brani
284 476fdba1 root
def usage_units(timeline, after, before, details=0):
285 476fdba1 root
    return list(_usage_units(timeline, after, before, details=details))
286 2925e285 root
287 9a06d96f Olga Brani
288 476fdba1 root
def traffic_units(timeline, after, before, details=0):
289 82b05401 root
    tu_total = 0
290 82b05401 root
    target = None
291 82b05401 root
    issue_time = None
292 82b05401 root
293 82b05401 root
    for point in timeline:
294 82b05401 root
        issue_time = point['issue_time']
295 476fdba1 root
        if issue_time <= after:
296 476fdba1 root
            continue
297 476fdba1 root
        if issue_time > before:
298 476fdba1 root
            break
299 476fdba1 root
300 476fdba1 root
        target = point['target']
301 82b05401 root
        tu = point['target_allocated_through']
302 82b05401 root
        tu_total += tu
303 82b05401 root
304 82b05401 root
        if details:
305 82b05401 root
            yield  (target,
306 82b05401 root
                    point['resource'],
307 82b05401 root
                    point['name'],
308 82b05401 root
                    issue_time,
309 82b05401 root
                    tu,
310 82b05401 root
                    tu_total)
311 82b05401 root
312 82b05401 root
    if not tu_total:
313 82b05401 root
        return
314 82b05401 root
315 82b05401 root
    yield  (target,
316 82b05401 root
            'total',
317 82b05401 root
            point['resource'],
318 82b05401 root
            issue_time,
319 9a06d96f Olga Brani
            tu_total // len(timeline),
320 82b05401 root
            tu_total)
321 2925e285 root
322 9a06d96f Olga Brani
323 2925e285 root
def timeline_charge(entity, resource, after, before, details, charge_type):
324 2925e285 root
    key = '1'
325 2925e285 root
    if charge_type == 'charge_usage':
326 2925e285 root
        charge_units = usage_units
327 2925e285 root
    elif charge_type == 'charge_traffic':
328 2925e285 root
        charge_units = traffic_units
329 2925e285 root
    else:
330 2925e285 root
        m = 'charge type %s not supported' % charge_type
331 2925e285 root
        raise ValueError(m)
332 2925e285 root
333 30d92d1e Georgios D. Tsoukalas
    quotaholder = QuotaholderClient(QUOTAHOLDER_URL, token=QUOTAHOLDER_TOKEN)
334 2925e285 root
    timeline = quotaholder.get_timeline(
335 9a06d96f Olga Brani
        context={},
336 9a06d96f Olga Brani
        after=after,
337 9a06d96f Olga Brani
        before=before,
338 9a06d96f Olga Brani
        get_timeline=[[entity, resource, key]])
339 476fdba1 root
    cu = charge_units(timeline, after, before, details=details)
340 82b05401 root
    return cu