Add interface to add a constraint to context

This adds methods to the Context to add, remove, and get a
constraint on an object to be checked before a change is
made to that object.

Related-Bug: #1493714
Change-Id: Id01c4dfb740f680e96349dc08b11b5bca6c59a74
This commit is contained in:
Kevin Benton 2017-07-12 01:09:22 -07:00
parent 335d30061a
commit 6a2040fcdb
3 changed files with 46 additions and 0 deletions

View File

@ -12,6 +12,7 @@
"""Context: context for security/db session."""
import collections
import copy
import datetime
@ -141,10 +142,15 @@ class ContextBaseWithSession(ContextBase):
pass
_TransactionConstraint = collections.namedtuple(
'TransactionConstraint', ['if_revision_match', 'resource', 'resource_id'])
class Context(ContextBaseWithSession):
def __init__(self, *args, **kwargs):
super(Context, self).__init__(*args, **kwargs)
self._session = None
self._txn_constraint = None
@property
def session(self):
@ -157,6 +163,26 @@ class Context(ContextBaseWithSession):
return self._session
def set_transaction_constraint(self, resource, resource_id, rev_number):
"""Set a revision constraint to enfore before resource_id is changed.
:param resource: collection name of resource (e.g. ports or networks)
:param resource_id: the primary key ID of the individiual resource that
should have its revision number matched before
allowing the transaction to proceed.
:param rev_number: the revision_number that the resource should be at.
"""
self._txn_constraint = _TransactionConstraint(
if_revision_match=rev_number, resource=resource,
resource_id=resource_id)
def clear_transaction_constraint(self):
self._txn_constraint = None
def get_transaction_constraint(self):
return self._txn_constraint
def get_admin_context():
return Context(user_id=None,

View File

@ -213,3 +213,14 @@ class TestNeutronContext(_base.BaseTestCase):
session1 = ctx.session
session2 = ctx.session
self.assertIs(session1, session2)
def test_add_get_remove_constraint(self):
ctx = context.Context('user_id', 'tenant_id')
self.assertIsNone(ctx.get_transaction_constraint())
ctx.set_transaction_constraint('networks', 'net_id', 44)
constraint = ctx.get_transaction_constraint()
self.assertEqual(44, constraint.if_revision_match)
self.assertEqual('networks', constraint.resource)
self.assertEqual('net_id', constraint.resource_id)
ctx.clear_transaction_constraint()
self.assertIsNone(ctx.get_transaction_constraint())

View File

@ -0,0 +1,9 @@
---
features:
- |
Contexts may now have transaction constraints set on them to be enforced
by the revision plugin in Neutron for generalized compare-and-swap updates.
Calling ``set_transaction_constraint`` on the context before performing a
resource mutation will setup the constraint. This is also exposed to users
via the HTTP API with ``if-match`` headers and the API layer sets the
constraint on the context.