Migrate IronicObjectSerializer to subclass from oslo

This replace Ironic's IronicObjectSerializer with
oslo.versionedobjects's VersionedObjectSerializer.

IPA's lookup should not return node as object anymore, because
Node object is not Json serializable. So return node as a pure dict.

Partial-Bug: #1461239
Change-Id: Ieec505613469536d941e54548cc228e5d05708b0
This commit is contained in:
Lin Tan 2015-07-13 16:26:32 +08:00
parent 24da11e97f
commit 1bd5f7f3a1
4 changed files with 7 additions and 56 deletions

View File

@ -348,7 +348,7 @@ class BaseAgentVendor(base.VendorInterface):
return { return {
'heartbeat_timeout': CONF.agent.heartbeat_timeout, 'heartbeat_timeout': CONF.agent.heartbeat_timeout,
'node': node 'node': node.as_dict()
} }
def _get_completed_cleaning_command(self, task): def _get_completed_cleaning_command(self, task):

View File

@ -19,7 +19,6 @@ import copy
from oslo_context import context from oslo_context import context
from oslo_log import log as logging from oslo_log import log as logging
import oslo_messaging as messaging
from oslo_utils import versionutils from oslo_utils import versionutils
from oslo_versionedobjects import base as object_base from oslo_versionedobjects import base as object_base
import six import six
@ -177,6 +176,7 @@ class IronicObject(object_base.VersionedObjectDictCompat):
as appropriate. as appropriate.
""" """
OBJ_SERIAL_NAMESPACE = 'ironic_object'
# Version of this object (see rules above check_object_version()) # Version of this object (see rules above check_object_version())
VERSION = '1.0' VERSION = '1.0'
@ -420,48 +420,9 @@ class ObjectListBase(object_base.ObjectListBase):
} }
class IronicObjectSerializer(messaging.NoOpSerializer): class IronicObjectSerializer(object_base.VersionedObjectSerializer):
"""A IronicObject-aware Serializer. # Base class to use for object hydration
OBJ_BASE_CLASS = IronicObject
This implements the Oslo Serializer interface and provides the
ability to serialize and deserialize IronicObject entities. Any service
that needs to accept or return IronicObjects as arguments or result values
should pass this to its RpcProxy and RpcDispatcher objects.
"""
def _process_iterable(self, context, action_fn, values):
"""Process an iterable, taking an action on each value.
:param:context: Request context
:param:action_fn: Action to take on each item in values
:param:values: Iterable container of things to take action on
:returns: A new container of the same type (except set) with
items from values having had action applied.
"""
iterable = values.__class__
if iterable == set:
# NOTE(danms): A set can't have an unhashable value inside, such as
# a dict. Convert sets to tuples, which is fine, since we can't
# send them over RPC anyway.
iterable = tuple
return iterable([action_fn(context, value) for value in values])
def serialize_entity(self, context, entity):
if isinstance(entity, (tuple, list, set)):
entity = self._process_iterable(context, self.serialize_entity,
entity)
elif (hasattr(entity, 'obj_to_primitive') and
callable(entity.obj_to_primitive)):
entity = entity.obj_to_primitive()
return entity
def deserialize_entity(self, context, entity):
if isinstance(entity, dict) and 'ironic_object.name' in entity:
entity = IronicObject.obj_from_primitive(entity, context=context)
elif isinstance(entity, (tuple, list, set)):
entity = self._process_iterable(context, self.deserialize_entity,
entity)
return entity
def obj_to_primitive(obj): def obj_to_primitive(obj):

View File

@ -111,7 +111,7 @@ class TestBaseAgentVendor(db_base.DbTestCase):
find_mock.return_value = self.node find_mock.return_value = self.node
with task_manager.acquire(self.context, self.node.uuid) as task: with task_manager.acquire(self.context, self.node.uuid) as task:
node = self.passthru.lookup(task.context, **kwargs) node = self.passthru.lookup(task.context, **kwargs)
self.assertEqual(self.node, node['node']) self.assertEqual(self.node.as_dict(), node['node'])
def test_lookup_v2_missing_inventory(self): def test_lookup_v2_missing_inventory(self):
with task_manager.acquire(self.context, self.node.uuid) as task: with task_manager.acquire(self.context, self.node.uuid) as task:
@ -156,7 +156,7 @@ class TestBaseAgentVendor(db_base.DbTestCase):
mock_get_node.return_value = self.node mock_get_node.return_value = self.node
with task_manager.acquire(self.context, self.node.uuid) as task: with task_manager.acquire(self.context, self.node.uuid) as task:
node = self.passthru.lookup(task.context, **kwargs) node = self.passthru.lookup(task.context, **kwargs)
self.assertEqual(self.node, node['node']) self.assertEqual(self.node.as_dict(), node['node'])
mock_get_node.assert_called_once_with(mock.ANY, 'fake uuid') mock_get_node.assert_called_once_with(mock.ANY, 'fake uuid')
@mock.patch.object(objects.port.Port, 'get_by_address', @mock.patch.object(objects.port.Port, 'get_by_address',

View File

@ -471,16 +471,6 @@ class TestObject(_LocalTest, _TestObject):
class TestObjectSerializer(test_base.TestCase): class TestObjectSerializer(test_base.TestCase):
def test_serialize_entity_primitive(self):
ser = base.IronicObjectSerializer()
for thing in (1, 'foo', [1, 2], {'foo': 'bar'}):
self.assertEqual(thing, ser.serialize_entity(None, thing))
def test_deserialize_entity_primitive(self):
ser = base.IronicObjectSerializer()
for thing in (1, 'foo', [1, 2], {'foo': 'bar'}):
self.assertEqual(thing, ser.deserialize_entity(None, thing))
def test_object_serialization(self): def test_object_serialization(self):
ser = base.IronicObjectSerializer() ser = base.IronicObjectSerializer()
obj = MyObj(self.context) obj = MyObj(self.context)