Merge "Add obj_make_compatible()"
This commit is contained in:
commit
8f62dd1f05
@ -577,8 +577,13 @@ class ConductorManager(manager.Manager):
|
||||
"""Perform a classmethod action on an object."""
|
||||
objclass = nova_object.NovaObject.obj_class_from_name(objname,
|
||||
objver)
|
||||
return self._object_dispatch(objclass, objmethod, context,
|
||||
args, kwargs)
|
||||
result = self._object_dispatch(objclass, objmethod, context,
|
||||
args, kwargs)
|
||||
# NOTE(danms): The RPC layer will convert to primitives for us,
|
||||
# but in this case, we need to honor the version the client is
|
||||
# asking for, so we do it before returning here.
|
||||
return (result.obj_to_primitive(target_version=objver)
|
||||
if isinstance(result, nova_object.NovaObject) else result)
|
||||
|
||||
def object_action(self, context, objinst, objmethod, args, kwargs):
|
||||
"""Perform an action on an object."""
|
||||
|
@ -259,7 +259,23 @@ class NovaObject(object):
|
||||
"""Create a copy."""
|
||||
return copy.deepcopy(self)
|
||||
|
||||
def obj_to_primitive(self):
|
||||
def obj_make_compatible(self, primitive, target_version):
|
||||
"""Make an object representation compatible with a target version.
|
||||
|
||||
This is responsible for taking the primitive representation of
|
||||
an object and making it suitable for the given target_version.
|
||||
This may mean converting the format of object attributes, removing
|
||||
attributes that have been added since the target version, etc.
|
||||
|
||||
:param:primitive: The result of self.obj_to_primitive()
|
||||
:param:target_version: The version string requested by the recipient
|
||||
of the object.
|
||||
:param:raises: nova.exception.UnsupportedObjectError if conversion
|
||||
is not possible for some reason.
|
||||
"""
|
||||
pass
|
||||
|
||||
def obj_to_primitive(self, target_version=None):
|
||||
"""Simple base-case dehydration.
|
||||
|
||||
This calls to_primitive() for each item in fields.
|
||||
@ -269,9 +285,11 @@ class NovaObject(object):
|
||||
if self.obj_attr_is_set(name):
|
||||
primitive[name] = field.to_primitive(self, name,
|
||||
getattr(self, name))
|
||||
if target_version:
|
||||
self.obj_make_compatible(primitive, target_version)
|
||||
obj = {'nova_object.name': self.obj_name(),
|
||||
'nova_object.namespace': 'nova',
|
||||
'nova_object.version': self.VERSION,
|
||||
'nova_object.version': target_version or self.VERSION,
|
||||
'nova_object.data': primitive}
|
||||
if self.obj_what_changed():
|
||||
obj['nova_object.changes'] = list(self.obj_what_changed())
|
||||
|
@ -81,6 +81,12 @@ class MyObj(base.NovaPersistentObject, base.NovaObject):
|
||||
self.save()
|
||||
self.foo = 42
|
||||
|
||||
def obj_make_compatible(self, primitive, target_version):
|
||||
# NOTE(danms): Simulate an older version that had a different
|
||||
# format for the 'bar' attribute
|
||||
if target_version == '1.1':
|
||||
primitive['bar'] = 'old%s' % primitive['bar']
|
||||
|
||||
|
||||
class MyObj2(object):
|
||||
@classmethod
|
||||
@ -363,7 +369,8 @@ class _RemoteTest(_BaseTestCase):
|
||||
kwargs.get('objmethod')))
|
||||
with things_temporarily_local():
|
||||
result = orig_object_class_action(*args, **kwargs)
|
||||
return result
|
||||
return (base.NovaObject.obj_from_primitive(result, context=args[0])
|
||||
if isinstance(result, base.NovaObject) else result)
|
||||
self.stubs.Set(self.conductor_service.manager, 'object_class_action',
|
||||
fake_object_class_action)
|
||||
|
||||
@ -659,6 +666,11 @@ class TestRemoteObject(_RemoteTest, _TestObject):
|
||||
self.assertEqual(obj.bar, 'bar')
|
||||
self.assertRemotes()
|
||||
|
||||
def test_compat(self):
|
||||
MyObj2.VERSION = '1.1'
|
||||
obj = MyObj2.query(self.context)
|
||||
self.assertEqual('oldbar', obj.bar)
|
||||
|
||||
|
||||
class TestObjectListBase(test.TestCase):
|
||||
def test_list_like_operations(self):
|
||||
|
Loading…
x
Reference in New Issue
Block a user