Added create and update hooks to version mixin

Objects using the version mixin will now have the version automatically
added or updated in the create and update hooks respectively.

Change-Id: I198eb89b45f0f16abb97611b8e43c106e24b9b49
Closes-Bug: #1808331
Co-Authored-By: Omer Anson <omer.anson@toganetworks.com>
This commit is contained in:
Shachar Snapiri 2018-12-18 10:12:28 +02:00 committed by Omer Anson
parent f016d8433f
commit 11cf7741cd
7 changed files with 67 additions and 6 deletions

View File

@ -233,8 +233,8 @@ director objects better we could define a common class:
super(AccessMixin, self).on_create_pre() super(AccessMixin, self).on_create_pre()
self.created_at = datetime.datetime.now() self.created_at = datetime.datetime.now()
def on_update_pre(self): def on_update_pre(self, orig):
super(AccessMixin, self).on_update_pre() super(AccessMixin, self).on_update_pre(orig)
self.updated_at = datetime.datetime.now() self.updated_at = datetime.datetime.now()
The above code updates the relevant fields on create/update operations, so if The above code updates the relevant fields on create/update operations, so if

View File

@ -189,6 +189,7 @@ operations performed in NbApi, e.g.
* `on_update_pre` - Called on the object each time it is updated, can be used * `on_update_pre` - Called on the object each time it is updated, can be used
for example to generate a new version or trigger updates on other objects. for example to generate a new version or trigger updates on other objects.
Gets the original object that exists in the database as a parameter.
Since those hooks are methods on objects themselves, we can use super() to Since those hooks are methods on objects themselves, we can use super() to
chain all needed hooks in parents and mixins, according to Python's native MRO. chain all needed hooks in parents and mixins, according to Python's native MRO.

View File

@ -14,6 +14,7 @@
# License for the specific language governing permissions and limitations # License for the specific language governing permissions and limitations
# under the License. # under the License.
import copy
import time import time
import traceback import traceback
@ -201,6 +202,7 @@ class NbApi(object):
""" """
model = type(obj) model = type(obj)
full_obj = self.get(obj) full_obj = self.get(obj)
db_obj = copy.copy(full_obj)
if full_obj is None: if full_obj is None:
raise df_exceptions.DBKeyNotFound(key=obj.id) raise df_exceptions.DBKeyNotFound(key=obj.id)
@ -210,7 +212,7 @@ class NbApi(object):
if not changed_fields: if not changed_fields:
return return
full_obj.on_update_pre() full_obj.on_update_pre(db_obj)
serialized_obj = full_obj.to_json() serialized_obj = full_obj.to_json()
topic = _get_topic(full_obj) topic = _get_topic(full_obj)

View File

@ -156,7 +156,7 @@ class _CommonBase(models.Base):
''' '''
pass pass
def on_update_pre(self): def on_update_pre(self, orig):
'''Hook function called before object is updated in the NB database. '''Hook function called before object is updated in the NB database.
''' '''
pass pass

View File

@ -65,6 +65,6 @@ class Listener(mf.ModelBase):
super(Listener, self).on_create_pre() super(Listener, self).on_create_pre()
self.update_timestamp() self.update_timestamp()
def on_update_pre(self): def on_update_pre(self, orig):
super(Listener, self).on_update_pre() super(Listener, self).on_update_pre(orig)
self.update_timestamp() self.update_timestamp()

View File

@ -36,6 +36,16 @@ class BasicEvents(mf.MixinBase):
class Version(mf.MixinBase): class Version(mf.MixinBase):
version = fields.IntField() version = fields.IntField()
def on_create_pre(self):
super(Version, self).on_create_pre()
if self.version is None:
self.version = 1
def on_update_pre(self, orig):
super(Version, self).on_update_pre(orig)
if self.version == orig.version:
self.version += 1
def is_newer_than(self, other): def is_newer_than(self, other):
return other is None or self.version > other.version return other is None or self.version > other.version

View File

@ -0,0 +1,48 @@
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
from jsonmodels import fields
import mock
import testtools
from dragonflow.db import api_nb
import dragonflow.db.model_framework as mf
from dragonflow.db.models import mixins
from dragonflow.tests import base as tests_base
from dragonflow.tests.common import utils
@mf.register_model
@mf.construct_nb_db_model
class FieldTestModel(mf.ModelBase, mixins.Version):
table_name = 'test_mixins'
field = fields.IntField()
class TestMixinVersions(tests_base.BaseTestCase):
def setUp(self):
super(TestMixinVersions, self).setUp()
self.api_nb = api_nb.NbApi(db_driver=mock.Mock())
def test_on_create(self):
instance = FieldTestModel(id='11111111')
self.api_nb.create(instance, True)
self.assertEqual(1, instance.version)
@testtools.skip('review/480194')
@utils.with_nb_objects(
FieldTestModel(id='11111111', version=1, field=1)
)
def test_on_update(self):
instance = FieldTestModel(id='11111111', field=2)
self.api_nb.update(instance, True)
db_inst = self.api_nb.get(FieldTestModel(id='11111111'))
self.assertEqual(2, db_inst.version)