Commit 79bed174 authored by Giorgos Korfiatis's avatar Giorgos Korfiatis
Browse files

Merge Policy model into Holding

Since the removal of quantity, Policy was left with only one value:
capacity. To simplify things, we directly include capacity in Holding.

This makes obsolete the following functions, which are removed:
get_limits, set_limits, get_holding, set_holding.
parent 92bc7295
......@@ -45,88 +45,17 @@ from astakos.quotaholder.api import QH_PRACTICALLY_INFINITE
from django.db.models import Q, Count
from django.db.models import Q
from .models import (Policy, Holding,
from .models import (Holding,
Commission, Provision, ProvisionLog,
now,
db_get_holding, db_get_policy,
db_get_holding,
db_get_commission, db_filter_provision)
class QuotaholderDjangoDBCallpoint(object):
def get_limits(self, context=None, get_limits=[]):
limits = []
append = limits.append
for policy in get_limits:
try:
p = Policy.objects.get(policy=policy)
except Policy.DoesNotExist:
continue
append((policy, p.capacity))
return limits
def set_limits(self, context=None, set_limits=[]):
for (policy, capacity) in set_limits:
try:
policy = db_get_policy(policy=policy, for_update=True)
except Policy.DoesNotExist:
Policy.objects.create(policy=policy,
capacity=capacity,
)
else:
policy.capacity = capacity
policy.save()
return ()
def get_holding(self, context=None, get_holding=[]):
holdings = []
append = holdings.append
for holder, resource in get_holding:
try:
h = Holding.objects.get(holder=holder, resource=resource)
except Holding.DoesNotExist:
continue
append((h.holder, h.resource, h.policy.policy,
h.imported_min, h.imported_max,
h.stock_min, h.stock_max, h.flags))
return holdings
def set_holding(self, context=None, set_holding=[]):
rejected = []
append = rejected.append
for holder, resource, policy, flags in set_holding:
try:
p = Policy.objects.get(policy=policy)
except Policy.DoesNotExist:
append((holder, resource, policy))
continue
try:
h = db_get_holding(holder=holder, resource=resource,
for_update=True)
h.policy = p
h.flags = flags
h.save()
except Holding.DoesNotExist:
h = Holding.objects.create(holder=holder, resource=resource,
policy=p, flags=flags)
if rejected:
raise QuotaholderError(rejected)
return rejected
def _init_holding(self,
holder, resource, policy,
holder, resource, capacity,
imported_min, imported_max, stock_min, stock_max,
flags):
try:
......@@ -135,7 +64,7 @@ class QuotaholderDjangoDBCallpoint(object):
except Holding.DoesNotExist:
h = Holding(holder=holder, resource=resource)
h.policy = policy
h.capacity = capacity
h.flags = flags
h.imported_min = imported_min
h.imported_max = imported_max
......@@ -148,17 +77,11 @@ class QuotaholderDjangoDBCallpoint(object):
append = rejected.append
for idx, sfh in enumerate(init_holding):
(holder, resource, policy,
(holder, resource, capacity,
imported_min, imported_max, stock_min, stock_max,
flags) = sfh
try:
p = Policy.objects.get(policy=policy)
except Policy.DoesNotExist:
append(idx)
continue
self._init_holding(holder, resource, p,
self._init_holding(holder, resource, capacity,
imported_min, imported_max,
stock_min, stock_max,
flags)
......@@ -254,7 +177,7 @@ class QuotaholderDjangoDBCallpoint(object):
append = quotas.append
holders = set(holder for holder, r in get_quota)
hs = Holding.objects.select_related().filter(holder__in=holders)
hs = Holding.objects.filter(holder__in=holders)
holdings = {}
for h in hs:
holdings[(h.holder, h.resource)] = h
......@@ -265,9 +188,7 @@ class QuotaholderDjangoDBCallpoint(object):
except:
continue
p = h.policy
append((h.holder, h.resource, p.capacity,
append((h.holder, h.resource, h.capacity,
h.imported_min, h.imported_max,
h.stock_min, h.stock_max,
h.flags))
......@@ -288,36 +209,21 @@ class QuotaholderDjangoDBCallpoint(object):
for h in hs:
holdings[(h.holder, h.resource)] = h
old_policies = []
for (holder, resource,
capacity,
flags) in set_quota:
policy = newname('policy_')
newp = Policy(policy=policy,
capacity=capacity,
)
try:
h = holdings[(holder, resource)]
old_policies.append(h.policy_id)
h.policy = newp
h.flags = flags
except KeyError:
h = Holding(holder=holder, resource=resource,
policy=newp, flags=flags)
flags=flags)
# the order is intentionally reversed so that it
# would break if we are not within a transaction.
# Has helped before.
h.capacity = capacity
h.save()
newp.save()
holdings[(holder, resource)] = h
objs = Policy.objects.annotate(refs=Count('holding'))
objs.filter(policy__in=old_policies, refs=0).delete()
if rejected:
raise QuotaholderError(rejected)
return rejected
......@@ -339,11 +245,6 @@ class QuotaholderDjangoDBCallpoint(object):
for h in hs:
holdings[(h.holder, h.resource)] = h
pids = [h.policy_id for h in hs]
policies = Policy.objects.in_bulk(pids)
old_policies = []
for removing, source in [(True, sub_quota), (False, add_quota)]:
for (holder, resource,
capacity,
......@@ -351,42 +252,25 @@ class QuotaholderDjangoDBCallpoint(object):
try:
h = holdings[(holder, resource)]
old_policies.append(h.policy_id)
try:
p = policies[h.policy_id]
except KeyError:
raise AssertionError("no policy %s" % h.policy_id)
current_capacity = h.capacity
except KeyError:
if removing:
append((holder, resource))
continue
h = Holding(holder=holder, resource=resource, flags=0)
p = None
policy = newname('policy_')
newp = Policy(policy=policy)
current_capacity = 0
newp.capacity = _add(p.capacity if p else 0, capacity,
invert=removing)
h.capacity = (current_capacity - capacity if removing else
current_capacity + capacity)
if _isneg(newp.capacity):
if h.capacity < 0:
append((holder, resource))
continue
h.policy = newp
# the order is intentionally reversed so that it
# would break if we are not within a transaction.
# Has helped before.
h.save()
newp.save()
policies[policy] = newp
holdings[(holder, resource)] = h
objs = Policy.objects.annotate(refs=Count('holding'))
objs.filter(policy__in=old_policies, refs=0).delete()
if rejected:
raise QuotaholderError(rejected)
......@@ -473,9 +357,7 @@ class QuotaholderDjangoDBCallpoint(object):
provision, log_time, reason):
s_holder = s_holding.holder
s_policy = s_holding.policy
t_holder = t_holding.holder
t_policy = t_holding.policy
kwargs = {
'serial': commission.serial,
......@@ -483,12 +365,12 @@ class QuotaholderDjangoDBCallpoint(object):
'source': s_holder,
'target': t_holder,
'resource': provision.resource,
'source_capacity': s_policy.capacity,
'source_capacity': s_holding.capacity,
'source_imported_min': s_holding.imported_min,
'source_imported_max': s_holding.imported_max,
'source_stock_min': s_holding.stock_min,
'source_stock_max': s_holding.stock_max,
'target_capacity': t_policy.capacity,
'target_capacity': t_holding.capacity,
'target_imported_min': t_holding.imported_min,
'target_imported_max': t_holding.imported_max,
'target_stock_min': t_holding.stock_min,
......@@ -690,12 +572,4 @@ class QuotaholderDjangoDBCallpoint(object):
return timeline
def _add(x, y, invert=False):
return x + y if not invert else x - y
def _isneg(x):
return x < 0
API_Callpoint = QuotaholderDjangoDBCallpoint
......@@ -80,7 +80,7 @@ class Import(Operation):
imported_max = holding.imported_max
new_imported_max = imported_max + quantity
capacity = holding.policy.capacity
capacity = holding.capacity
if check and new_imported_max > capacity:
holder = holding.holder
resource = holding.resource
......
......@@ -39,19 +39,12 @@ from django.db.models import (Model, BigIntegerField, CharField,
from django.db import transaction
from synnefo.lib.db.managers import ForUpdateManager
class Policy(Model):
policy = CharField(max_length=4096, primary_key=True)
capacity = intDecimalField()
objects = ForUpdateManager()
class Holding(Model):
holder = CharField(max_length=4096, db_index=True)
resource = CharField(max_length=4096, null=False)
policy = ForeignKey(Policy, to_field='policy')
capacity = intDecimalField()
flags = BigIntegerField(null=False, default=0)
imported_min = intDecimalField(default=0)
......@@ -142,9 +135,6 @@ def _filter(*args, **kwargs):
def db_get_holding(*args, **kwargs):
return _get(Holding, *args, **kwargs)
def db_get_policy(*args, **kwargs):
return _get(Policy, *args, **kwargs)
def db_get_commission(*args, **kwargs):
return _get(Commission, *args, **kwargs)
......
......@@ -73,12 +73,6 @@ class QHAPITest(QHTestCase):
def rand_holder(self):
return self.rand_name(self.used_entities)
used_policies = []
@classmethod
def rand_policy(self):
return self.rand_name(self.used_policies)
used_resources = []
@classmethod
......@@ -89,11 +83,6 @@ class QHAPITest(QHTestCase):
c = random_nat()
return (c,)
def rand_policy_limits(self):
p = self.rand_policy()
limits = self.rand_limits()
return p, limits
def rand_flags(self):
return random_nat()
......@@ -105,50 +94,6 @@ class QHAPITest(QHTestCase):
self.qh.set_limits(set_limits=[(p,) + limits])
return p, limits
@transaction.commit_on_success
def test_006_get_set_limits(self):
p1, limits1 = self.rand_policy_limits()
limits2 = self.rand_limits()
r = self.qh.set_limits(set_limits=[(p1,) + limits1,
(p1,) + limits2])
p2, _ = self.rand_policy_limits()
r = self.qh.get_limits(get_limits=[p1, p2])
self.assertEqual(r, [(p1,) + limits2])
@transaction.commit_on_success
def test_007_get_set_holding(self):
e = self.rand_holder()
resource = self.rand_resource()
p0 = self.rand_policy()
f0 = self.rand_flags()
p1, _ = self.new_policy()
f1 = self.rand_flags()
p2, _ = self.new_policy()
f2 = self.rand_flags()
with self.assertRaises(QuotaholderError) as cm:
self.qh.set_holding(set_holding=[(e, resource, p0, f0),
(e, resource, p1, f1),
(e, resource, p2, f2)])
# Python people consider this a legal use
# It's even in the library docs... whatever
err = cm.exception
self.assertEqual(err.message, [(e, resource, p0)])
self.qh.get_holding(get_holding=[(e, resource)])
self.qh.set_holding(set_holding=[(e, resource, p1, f1),
(e, resource, p2, f2)])
resource1 = self.rand_resource()
r = self.qh.get_holding(get_holding=[(e, resource),
(e, resource1)])
self.assertEqual(r, [(e, resource, p2) + DEFAULT_HOLDING + (f2,)])
@transaction.commit_on_success
def test_0080_get_set_quota(self):
e = self.rand_holder()
......@@ -414,9 +359,9 @@ class QHAPITest(QHTestCase):
e0 = self.rand_holder()
e1 = self.rand_holder()
resource = self.rand_resource()
p, _ = self.new_policy()
c, = self.rand_limits()
f = self.rand_flags()
r = self.qh.set_holding(set_holding=[(e1, resource, p, f)])
r = self.qh.set_quota(set_quota=[(e1, resource, c, f)])
counters = self.rand_counters()
......@@ -428,8 +373,8 @@ class QHAPITest(QHTestCase):
err = cm.exception
self.assertEqual(err.message, [0])
r = self.qh.get_holding(get_holding=[(e1, resource)])
self.assertEqual(r, [(e1, resource, p) + counters + (f,)])
r = self.qh.get_quota(get_quota=[(e1, resource)])
self.assertEqual(r, [(e1, resource, c) + counters + (f,)])
@transaction.commit_on_success
def test_015_release_nocapacity(self):
......@@ -439,31 +384,21 @@ class QHAPITest(QHTestCase):
resource = "resource"
target = "test_015_release_nocapacity_target"
flags = 0
source_limits = [source, 6]
source_holding = [source, resource, source, flags]
target_limits = [target, 5]
target_holding = [target, resource, target, flags]
failed = AssertionError("Quotaholder call failed")
if qh.set_limits(set_limits=[source_limits, target_limits]):
raise failed
if qh.set_holding(set_holding=[source_holding, target_holding]):
raise failed
self.qh.reset_holding(
reset_holding=[(source, resource, 6, 6, 6, 6)])
qh.init_holding(init_holding=[(source, resource, 6, 6, 6, 6, 6, 0)])
qh.set_quota(set_quota=[(target, resource, 5, 0)])
serial = qh.issue_commission(clientkey=self.client, target=target,
name="something",
provisions=[(source, resource, 5)])
qh.accept_commission(clientkey=self.client, serials=[serial])
holding = qh.get_holding(get_holding=[[source, resource]])
holding = qh.get_quota(get_quota=[[source, resource]])
self.assertEqual(tuple(holding[0]),
(source, resource, source, 6, 6, 1, 1, flags))
holding = qh.get_holding(get_holding=[[target, resource]])
(source, resource, 6, 6, 6, 1, 1, flags))
holding = qh.get_quota(get_quota=[[target, resource]])
self.assertEqual(tuple(holding[0]),
(target, resource, target, 5, 5, 5, 5, flags))
(target, resource, 5, 5, 5, 5, 5, flags))
if qh.reset_holding(
reset_holding=[[target, resource, 10, 10, 10, 10]]):
......@@ -484,12 +419,12 @@ class QHAPITest(QHTestCase):
provisions=[(source, resource, -1)])
qh.accept_commission(clientkey=self.client, serials=[serial])
holding = qh.get_holding(get_holding=[[source, resource]])
holding = qh.get_quota(get_quota=[[source, resource]])
self.assertEqual(tuple(holding[0]),
(source, resource, source, 6, 6, 2, 2, flags))
holding = qh.get_holding(get_holding=[[target, resource]])
(source, resource, 6, 6, 6, 2, 2, flags))
holding = qh.get_quota(get_quota=[[target, resource]])
self.assertEqual(tuple(holding[0]),
(target, resource, target, 9, 9, 9, 9, flags))
(target, resource, 5, 9, 9, 9, 9, flags))
with self.assertRaises(NonExportedError):
qh.issue_commission(clientkey=self.client, target=target,
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment