Revision 6cc50d6a snf-astakos-app/astakos/quotaholder/callpoint.py
b/snf-astakos-app/astakos/quotaholder/callpoint.py | ||
---|---|---|
46 | 46 |
from astakos.quotaholder.utils.newname import newname |
47 | 47 |
from astakos.quotaholder.api import QH_PRACTICALLY_INFINITE |
48 | 48 |
|
49 |
from django.db.models import Q, Count |
|
50 |
from django.db.models import Q |
|
51 | 49 |
from .models import (Holding, |
52 | 50 |
Commission, Provision, ProvisionLog, |
53 | 51 |
now, |
... | ... | |
57 | 55 |
|
58 | 56 |
class QuotaholderDjangoDBCallpoint(object): |
59 | 57 |
|
60 |
def _init_holding(self, |
|
61 |
holder, resource, limit, |
|
62 |
imported_min, imported_max, |
|
63 |
flags): |
|
64 |
try: |
|
65 |
h = db_get_holding(holder=holder, resource=resource, |
|
66 |
for_update=True) |
|
67 |
except Holding.DoesNotExist: |
|
68 |
h = Holding(holder=holder, resource=resource) |
|
69 |
|
|
70 |
h.limit = limit |
|
71 |
h.flags = flags |
|
72 |
h.imported_min = imported_min |
|
73 |
h.imported_max = imported_max |
|
74 |
h.save() |
|
75 |
|
|
76 |
def init_holding(self, context=None, init_holding=[]): |
|
77 |
rejected = [] |
|
78 |
append = rejected.append |
|
79 |
|
|
80 |
for idx, sfh in enumerate(init_holding): |
|
81 |
(holder, resource, limit, |
|
82 |
imported_min, imported_max, |
|
83 |
flags) = sfh |
|
84 |
|
|
85 |
self._init_holding(holder, resource, limit, |
|
86 |
imported_min, imported_max, |
|
87 |
flags) |
|
88 |
if rejected: |
|
89 |
raise QuotaholderError(rejected) |
|
90 |
return rejected |
|
91 |
|
|
92 |
def reset_holding(self, context=None, reset_holding=[]): |
|
93 |
rejected = [] |
|
94 |
append = rejected.append |
|
95 |
|
|
96 |
for idx, tpl in enumerate(reset_holding): |
|
97 |
(holder, source, resource, |
|
98 |
imported_min, imported_max) = tpl |
|
99 |
|
|
100 |
try: |
|
101 |
h = db_get_holding(holder=holder, |
|
102 |
source=source, |
|
103 |
resource=resource, |
|
104 |
for_update=True) |
|
105 |
h.imported_min = imported_min |
|
106 |
h.imported_max = imported_max |
|
107 |
h.save() |
|
108 |
except Holding.DoesNotExist: |
|
109 |
append(idx) |
|
110 |
continue |
|
111 |
|
|
112 |
if rejected: |
|
113 |
raise QuotaholderError(rejected) |
|
114 |
return rejected |
|
115 |
|
|
116 |
def _check_pending(self, holding): |
|
117 |
ps = Provision.objects.filter(holding=holding) |
|
118 |
return ps.count() |
|
119 |
|
|
120 |
def release_holding(self, context=None, release_holding=[]): |
|
121 |
rejected = [] |
|
122 |
append = rejected.append |
|
123 |
|
|
124 |
for idx, (holder, source, resource) in enumerate(release_holding): |
|
125 |
try: |
|
126 |
h = db_get_holding(holder=holder, |
|
127 |
source=source, |
|
128 |
resource=resource, |
|
129 |
for_update=True) |
|
130 |
except Holding.DoesNotExist: |
|
131 |
append(idx) |
|
132 |
continue |
|
133 |
|
|
134 |
if self._check_pending(h): |
|
135 |
append(idx) |
|
136 |
continue |
|
137 |
|
|
138 |
if h.imported_max > 0: |
|
139 |
append(idx) |
|
140 |
continue |
|
141 |
|
|
142 |
h.delete() |
|
143 |
|
|
144 |
if rejected: |
|
145 |
raise QuotaholderError(rejected) |
|
146 |
return rejected |
|
147 |
|
|
148 |
def list_resources(self, context=None, holder=None): |
|
149 |
holdings = Holding.objects.filter(holder=holder) |
|
150 |
resources = [h.resource for h in holdings] |
|
151 |
return resources |
|
152 |
|
|
153 |
def list_holdings(self, context=None, list_holdings=[]): |
|
154 |
rejected = [] |
|
155 |
reject = rejected.append |
|
156 |
holdings_list = [] |
|
157 |
append = holdings_list.append |
|
158 |
|
|
159 |
for holder in list_holdings: |
|
160 |
holdings = list(Holding.objects.filter(holder=holder)) |
|
161 |
if not holdings: |
|
162 |
reject(holder) |
|
163 |
continue |
|
164 |
|
|
165 |
append([(holder, h.source, h.resource, |
|
166 |
h.imported_min, h.imported_max) |
|
167 |
for h in holdings]) |
|
168 |
|
|
169 |
return holdings_list, rejected |
|
170 |
|
|
171 | 58 |
def get_holder_quota(self, holders=None, sources=None, resources=None): |
172 | 59 |
holdings = Holding.objects.filter(holder__in=holders) |
173 | 60 |
|
... | ... | |
185 | 72 |
|
186 | 73 |
return quotas |
187 | 74 |
|
188 |
def get_quota(self, context=None, get_quota=[]): |
|
189 |
quotas = [] |
|
190 |
append = quotas.append |
|
191 |
|
|
192 |
holders = set(holder for holder, r in get_quota) |
|
193 |
hs = Holding.objects.filter(holder__in=holders) |
|
194 |
holdings = {} |
|
195 |
for h in hs: |
|
196 |
holdings[(h.holder, h.source, h.resource)] = h |
|
197 |
|
|
198 |
for holder, source, resource in get_quota: |
|
199 |
try: |
|
200 |
h = holdings[(holder, source, resource)] |
|
201 |
except: |
|
202 |
continue |
|
203 |
|
|
204 |
append((h.holder, h.source, h.resource, h.limit, |
|
205 |
h.imported_min, h.imported_max, |
|
206 |
h.flags)) |
|
207 |
|
|
208 |
return quotas |
|
209 |
|
|
210 | 75 |
def set_holder_quota(self, quotas): |
211 | 76 |
holders = quotas.keys() |
212 | 77 |
hs = Holding.objects.filter(holder__in=holders).select_for_update() |
... | ... | |
227 | 92 |
h.limit = limit |
228 | 93 |
h.save() |
229 | 94 |
|
230 |
def set_quota(self, context=None, set_quota=[]): |
|
231 |
rejected = [] |
|
232 |
append = rejected.append |
|
233 |
|
|
234 |
q_holdings = Q() |
|
235 |
holders = [] |
|
236 |
for (holder, source, resource, _, _) in set_quota: |
|
237 |
holders.append(holder) |
|
238 |
|
|
239 |
hs = Holding.objects.filter(holder__in=holders).select_for_update() |
|
240 |
holdings = {} |
|
241 |
for h in hs: |
|
242 |
holdings[(h.holder, h.source, h.resource)] = h |
|
243 |
|
|
244 |
for (holder, source, resource, |
|
245 |
limit, |
|
246 |
flags) in set_quota: |
|
247 |
|
|
248 |
try: |
|
249 |
h = holdings[(holder, source, resource)] |
|
250 |
h.flags = flags |
|
251 |
except KeyError: |
|
252 |
h = Holding(holder=holder, |
|
253 |
source=source, |
|
254 |
resource=resource, |
|
255 |
flags=flags) |
|
256 |
|
|
257 |
h.limit = limit |
|
258 |
h.save() |
|
259 |
holdings[(holder, source, resource)] = h |
|
260 |
|
|
261 |
if rejected: |
|
262 |
raise QuotaholderError(rejected) |
|
263 |
return rejected |
|
264 |
|
|
265 |
def add_quota(self, |
|
266 |
context=None, |
|
267 |
sub_quota=[], add_quota=[]): |
|
268 |
rejected = [] |
|
269 |
append = rejected.append |
|
270 |
|
|
271 |
sources = sub_quota + add_quota |
|
272 |
q_holdings = Q() |
|
273 |
holders = [] |
|
274 |
for (holder, resource, _) in sources: |
|
275 |
holders.append(holder) |
|
276 |
|
|
277 |
hs = Holding.objects.filter(holder__in=holders).select_for_update() |
|
278 |
holdings = {} |
|
279 |
for h in hs: |
|
280 |
holdings[(h.holder, h.resource)] = h |
|
281 |
|
|
282 |
for removing, source in [(True, sub_quota), (False, add_quota)]: |
|
283 |
for (holder, resource, |
|
284 |
limit, |
|
285 |
) in source: |
|
286 |
|
|
287 |
try: |
|
288 |
h = holdings[(holder, resource)] |
|
289 |
current_limit = h.limit |
|
290 |
except KeyError: |
|
291 |
if removing: |
|
292 |
append((holder, resource)) |
|
293 |
continue |
|
294 |
|
|
295 |
h = Holding(holder=holder, resource=resource, flags=0) |
|
296 |
current_limit = 0 |
|
297 |
|
|
298 |
h.limit = (current_limit - limit if removing else |
|
299 |
current_limit + limit) |
|
300 |
|
|
301 |
if h.limit < 0: |
|
302 |
append((holder, resource)) |
|
303 |
continue |
|
304 |
|
|
305 |
h.save() |
|
306 |
holdings[(holder, resource)] = h |
|
307 |
|
|
308 |
if rejected: |
|
309 |
raise QuotaholderError(rejected) |
|
310 |
|
|
311 |
return rejected |
|
312 |
|
|
313 | 95 |
def issue_commission(self, |
314 | 96 |
context=None, |
315 | 97 |
clientkey=None, |
... | ... | |
524 | 306 |
failed = list(set(failed_ac + failed_re)) |
525 | 307 |
return accepted, rejected, failed |
526 | 308 |
|
527 |
def get_timeline(self, context=None, after="", before="Z", get_timeline=[]): |
|
528 |
holder_set = set() |
|
529 |
e_add = holder_set.add |
|
530 |
resource_set = set() |
|
531 |
r_add = resource_set.add |
|
532 |
|
|
533 |
for holder, resource in get_timeline: |
|
534 |
if holder not in holder_set: |
|
535 |
e_add(holder) |
|
536 |
|
|
537 |
r_add((holder, resource)) |
|
538 |
|
|
539 |
chunk_size = 65536 |
|
540 |
nr = 0 |
|
541 |
timeline = [] |
|
542 |
append = timeline.append |
|
543 |
filterlogs = ProvisionLog.objects.filter |
|
544 |
if holder_set: |
|
545 |
q_holder = Q(source__in=holder_set) | Q(target__in=holder_set) |
|
546 |
else: |
|
547 |
q_holder = Q() |
|
548 |
|
|
549 |
while 1: |
|
550 |
logs = filterlogs(q_holder, |
|
551 |
issue_time__gt=after, |
|
552 |
issue_time__lte=before, |
|
553 |
reason__startswith='ACCEPT:') |
|
554 |
|
|
555 |
logs = logs.order_by('issue_time') |
|
556 |
#logs = logs.values() |
|
557 |
logs = logs[:chunk_size] |
|
558 |
nr += len(logs) |
|
559 |
if not logs: |
|
560 |
break |
|
561 |
for g in logs: |
|
562 |
if ((g.source, g.resource) not in resource_set |
|
563 |
or (g.target, g.resource) not in resource_set): |
|
564 |
continue |
|
565 |
|
|
566 |
o = { |
|
567 |
'serial': g.serial, |
|
568 |
'source': g.source, |
|
569 |
'target': g.target, |
|
570 |
'resource': g.resource, |
|
571 |
'name': g.name, |
|
572 |
'quantity': g.delta_quantity, |
|
573 |
'source_allocated': g.source_allocated(), |
|
574 |
'source_allocated_through': g.source_allocated_through(), |
|
575 |
'source_inbound': g.source_inbound(), |
|
576 |
'source_inbound_through': g.source_inbound_through(), |
|
577 |
'source_outbound': g.source_outbound(), |
|
578 |
'source_outbound_through': g.source_outbound_through(), |
|
579 |
'target_allocated': g.target_allocated(), |
|
580 |
'target_allocated_through': g.target_allocated_through(), |
|
581 |
'target_inbound': g.target_inbound(), |
|
582 |
'target_inbound_through': g.target_inbound_through(), |
|
583 |
'target_outbound': g.target_outbound(), |
|
584 |
'target_outbound_through': g.target_outbound_through(), |
|
585 |
'issue_time': g.issue_time, |
|
586 |
'log_time': g.log_time, |
|
587 |
'reason': g.reason, |
|
588 |
} |
|
589 |
|
|
590 |
append(o) |
|
591 |
|
|
592 |
after = g.issue_time |
|
593 |
if after >= before: |
|
594 |
break |
|
595 |
|
|
596 |
return timeline |
|
597 |
|
|
598 | 309 |
|
599 | 310 |
API_Callpoint = QuotaholderDjangoDBCallpoint |
Also available in: Unified diff