Revision 79e3da8a snf-astakos-app/astakos/quotaholder/callpoint.py
b/snf-astakos-app/astakos/quotaholder/callpoint.py | ||
---|---|---|
31 | 31 |
# interpreted as representing official policies, either expressed |
32 | 32 |
# or implied, of GRNET S.A. |
33 | 33 |
|
34 |
from functools import partial |
|
35 |
|
|
34 | 36 |
from astakos.quotaholder.exception import ( |
35 | 37 |
QuotaholderError, |
38 |
NoCommissionError, |
|
36 | 39 |
CorruptedError, InvalidDataError, |
37 |
NoCapacityError,
|
|
40 |
NoHoldingError,
|
|
38 | 41 |
DuplicateError) |
39 | 42 |
|
40 | 43 |
from astakos.quotaholder.commission import ( |
... | ... | |
311 | 314 |
context=None, |
312 | 315 |
clientkey=None, |
313 | 316 |
name=None, |
317 |
force=False, |
|
314 | 318 |
provisions=()): |
315 | 319 |
|
316 | 320 |
if name is None: |
... | ... | |
323 | 327 |
|
324 | 328 |
try: |
325 | 329 |
checked = [] |
326 |
for holder, source, resource, quantity in provisions: |
|
330 |
for provision in provisions: |
|
331 |
try: |
|
332 |
holder = provision['holder'] |
|
333 |
source = provision['source'] |
|
334 |
resource = provision['resource'] |
|
335 |
quantity = provision['quantity'] |
|
336 |
except KeyError: |
|
337 |
raise InvalidDataError("Malformed provision") |
|
327 | 338 |
|
328 |
if holder == source: |
|
329 |
m = ("Cannot issue commission from a holder " |
|
330 |
"to itself (%s)" % (holder,)) |
|
331 |
raise InvalidDataError(m) |
|
339 |
if not isinstance(quantity, (int, long)): |
|
340 |
raise InvalidDataError("Malformed provision") |
|
332 | 341 |
|
333 | 342 |
ent_res = holder, resource |
334 | 343 |
if ent_res in checked: |
335 | 344 |
m = "Duplicate provision for %s.%s" % ent_res |
336 |
raise DuplicateError(m) |
|
345 |
details = {'message': m, |
|
346 |
} |
|
347 |
raise DuplicateError(m, |
|
348 |
provision=provision, |
|
349 |
details=details) |
|
337 | 350 |
checked.append(ent_res) |
338 | 351 |
|
339 | 352 |
# Target |
... | ... | |
343 | 356 |
source=source, |
344 | 357 |
for_update=True) |
345 | 358 |
except Holding.DoesNotExist: |
346 |
m = ("There is no capacity " |
|
347 |
"to allocate into in %s.%s" % (holder, resource)) |
|
348 |
raise NoCapacityError(m, |
|
349 |
holder=holder, |
|
350 |
resource=resource, |
|
351 |
requested=quantity, |
|
352 |
current=0, |
|
353 |
limit=0) |
|
359 |
m = ("There is no such holding %s.%s" |
|
360 |
% (holder, resource)) |
|
361 |
raise NoHoldingError(m, |
|
362 |
provision=provision) |
|
354 | 363 |
|
355 | 364 |
if quantity >= 0: |
356 |
operations.prepare(Import, th, quantity) |
|
365 |
operations.prepare(Import, th, quantity, force)
|
|
357 | 366 |
|
358 | 367 |
else: # release |
359 | 368 |
abs_quantity = -quantity |
360 |
operations.prepare(Release, th, abs_quantity) |
|
369 |
operations.prepare(Release, th, abs_quantity, force)
|
|
361 | 370 |
|
362 | 371 |
Provision.objects.create(serial=commission, |
363 | 372 |
holding=th, |
... | ... | |
393 | 402 |
|
394 | 403 |
def accept_commission(self, |
395 | 404 |
context=None, clientkey=None, |
396 |
serials=[], reason=''):
|
|
405 |
serial=None, reason=''):
|
|
397 | 406 |
log_time = now() |
398 | 407 |
|
399 |
for serial in serials: |
|
400 |
try: |
|
401 |
c = db_get_commission(clientkey=clientkey, serial=serial, |
|
402 |
for_update=True) |
|
403 |
except Commission.DoesNotExist: |
|
404 |
return |
|
405 |
|
|
406 |
operations = Operations() |
|
408 |
try: |
|
409 |
c = db_get_commission(clientkey=clientkey, serial=serial, |
|
410 |
for_update=True) |
|
411 |
except Commission.DoesNotExist: |
|
412 |
return False |
|
407 | 413 |
|
408 |
provisions = db_filter_provision(serial=serial, for_update=True) |
|
409 |
for pv in provisions: |
|
410 |
try: |
|
411 |
th = db_get_holding(id=pv.holding_id, |
|
412 |
for_update=True) |
|
413 |
except Holding.DoesNotExist: |
|
414 |
m = "Corrupted provision" |
|
415 |
raise CorruptedError(m) |
|
414 |
operations = Operations() |
|
416 | 415 |
|
417 |
quantity = pv.quantity |
|
416 |
provisions = db_filter_provision(serial=serial, for_update=True) |
|
417 |
for pv in provisions: |
|
418 |
try: |
|
419 |
th = db_get_holding(id=pv.holding_id, |
|
420 |
for_update=True) |
|
421 |
except Holding.DoesNotExist: |
|
422 |
m = "Corrupted provision" |
|
423 |
raise CorruptedError(m) |
|
418 | 424 |
|
419 |
if quantity >= 0: |
|
420 |
operations.finalize(Import, th, quantity) |
|
421 |
else: # release |
|
422 |
abs_quantity = -quantity |
|
423 |
operations.finalize(Release, th, abs_quantity) |
|
425 |
quantity = pv.quantity |
|
424 | 426 |
|
425 |
reason = 'ACCEPT:' + reason[-121:] |
|
426 |
self._log_provision(c, pv, log_time, reason) |
|
427 |
pv.delete() |
|
428 |
c.delete() |
|
427 |
if quantity >= 0: |
|
428 |
operations.finalize(Import, th, quantity) |
|
429 |
else: # release |
|
430 |
abs_quantity = -quantity |
|
431 |
operations.finalize(Release, th, abs_quantity) |
|
429 | 432 |
|
430 |
return |
|
433 |
reason = 'ACCEPT:' + reason[-121:] |
|
434 |
self._log_provision(c, pv, log_time, reason) |
|
435 |
pv.delete() |
|
436 |
c.delete() |
|
437 |
return True |
|
431 | 438 |
|
432 | 439 |
def reject_commission(self, |
433 | 440 |
context=None, clientkey=None, |
434 |
serials=[], reason=''):
|
|
441 |
serial=None, reason=''):
|
|
435 | 442 |
log_time = now() |
436 | 443 |
|
437 |
for serial in serials: |
|
438 |
try: |
|
439 |
c = db_get_commission(clientkey=clientkey, serial=serial, |
|
440 |
for_update=True) |
|
441 |
except Commission.DoesNotExist: |
|
442 |
return |
|
443 |
|
|
444 |
operations = Operations() |
|
444 |
try: |
|
445 |
c = db_get_commission(clientkey=clientkey, serial=serial, |
|
446 |
for_update=True) |
|
447 |
except Commission.DoesNotExist: |
|
448 |
return False |
|
445 | 449 |
|
446 |
provisions = db_filter_provision(serial=serial, for_update=True) |
|
447 |
for pv in provisions: |
|
448 |
try: |
|
449 |
th = db_get_holding(id=pv.holding_id, |
|
450 |
for_update=True) |
|
451 |
except Holding.DoesNotExist: |
|
452 |
m = "Corrupted provision" |
|
453 |
raise CorruptedError(m) |
|
450 |
operations = Operations() |
|
454 | 451 |
|
455 |
quantity = pv.quantity |
|
452 |
provisions = db_filter_provision(serial=serial, for_update=True) |
|
453 |
for pv in provisions: |
|
454 |
try: |
|
455 |
th = db_get_holding(id=pv.holding_id, |
|
456 |
for_update=True) |
|
457 |
except Holding.DoesNotExist: |
|
458 |
m = "Corrupted provision" |
|
459 |
raise CorruptedError(m) |
|
456 | 460 |
|
457 |
if quantity >= 0: |
|
458 |
operations.undo(Import, th, quantity) |
|
459 |
else: # release |
|
460 |
abs_quantity = -quantity |
|
461 |
operations.undo(Release, th, abs_quantity) |
|
461 |
quantity = pv.quantity |
|
462 | 462 |
|
463 |
reason = 'REJECT:' + reason[-121:] |
|
464 |
self._log_provision(c, pv, log_time, reason) |
|
465 |
pv.delete() |
|
466 |
c.delete() |
|
463 |
if quantity >= 0: |
|
464 |
operations.undo(Import, th, quantity) |
|
465 |
else: # release |
|
466 |
abs_quantity = -quantity |
|
467 |
operations.undo(Release, th, abs_quantity) |
|
467 | 468 |
|
468 |
return |
|
469 |
reason = 'REJECT:' + reason[-121:] |
|
470 |
self._log_provision(c, pv, log_time, reason) |
|
471 |
pv.delete() |
|
472 |
c.delete() |
|
473 |
return True |
|
469 | 474 |
|
470 | 475 |
def get_pending_commissions(self, context=None, clientkey=None): |
471 | 476 |
pending = Commission.objects.filter(clientkey=clientkey) |
472 | 477 |
pending_list = pending.values_list('serial', flat=True) |
473 |
return pending_list |
|
478 |
return list(pending_list) |
|
479 |
|
|
480 |
def get_commission(self, clientkey=None, serial=None): |
|
481 |
try: |
|
482 |
commission = Commission.objects.get(clientkey=clientkey, |
|
483 |
serial=serial) |
|
484 |
except Commission.DoesNotExist: |
|
485 |
raise NoCommissionError(serial) |
|
486 |
|
|
487 |
objs = Provision.objects.select_related('holding') |
|
488 |
provisions = objs.filter(serial=commission) |
|
489 |
|
|
490 |
ps = [p.todict() for p in provisions] |
|
491 |
|
|
492 |
response = {'serial': serial, |
|
493 |
'provisions': ps, |
|
494 |
'issue_time': commission.issue_time, |
|
495 |
} |
|
496 |
return response |
|
497 |
|
|
498 |
def _resolve(self, include, exclude, operation): |
|
499 |
done = [] |
|
500 |
failed = [] |
|
501 |
for serial in include: |
|
502 |
if serial in exclude: |
|
503 |
failed.append((serial, 'CONFLICT')) |
|
504 |
else: |
|
505 |
response = operation(serial=serial) |
|
506 |
if response: |
|
507 |
done.append(serial) |
|
508 |
else: |
|
509 |
failed.append((serial, 'NOTFOUND')) |
|
510 |
return done, failed |
|
474 | 511 |
|
475 | 512 |
def resolve_pending_commissions(self, |
476 | 513 |
context=None, clientkey=None, |
477 |
max_serial=None, accept_set=[]):
|
|
514 |
accept_set=[], reject_set=[]):
|
|
478 | 515 |
accept_set = set(accept_set) |
479 |
pending = self.get_pending_commissions(context=context, |
|
480 |
clientkey=clientkey) |
|
481 |
pending = sorted(pending) |
|
482 |
|
|
483 |
accept = self.accept_commission |
|
484 |
reject = self.reject_commission |
|
516 |
reject_set = set(reject_set) |
|
485 | 517 |
|
486 |
for serial in pending: |
|
487 |
if serial > max_serial: |
|
488 |
break |
|
518 |
accept = partial(self.accept_commission, clientkey=clientkey) |
|
519 |
reject = partial(self.reject_commission, clientkey=clientkey) |
|
489 | 520 |
|
490 |
if serial in accept_set: |
|
491 |
accept(context=context, clientkey=clientkey, serials=[serial]) |
|
492 |
else: |
|
493 |
reject(context=context, clientkey=clientkey, serials=[serial]) |
|
521 |
accepted, failed_ac = self._resolve(accept_set, reject_set, accept) |
|
522 |
rejected, failed_re = self._resolve(reject_set, accept_set, reject) |
|
494 | 523 |
|
495 |
return |
|
524 |
failed = list(set(failed_ac + failed_re)) |
|
525 |
return accepted, rejected, failed |
|
496 | 526 |
|
497 | 527 |
def get_timeline(self, context=None, after="", before="Z", get_timeline=[]): |
498 | 528 |
holder_set = set() |
Also available in: Unified diff