diff options
| author | Dan Smith <danms@us.ibm.com> | 2013-06-18 11:01:50 -0700 |
|---|---|---|
| committer | Chris Behrens <cbehrens@codestud.com> | 2013-06-22 21:20:57 +0000 |
| commit | 92a3190128547403dc603e5a40e377c6eb0c8025 (patch) | |
| tree | 1a2f81063bc97414f46cca0ef7fff0ef89a328fd /nova/objects | |
| parent | a9c695d82111702c562f4bb36fb9ea964b9d0913 (diff) | |
| download | nova-92a3190128547403dc603e5a40e377c6eb0c8025.tar.gz nova-92a3190128547403dc603e5a40e377c6eb0c8025.tar.xz nova-92a3190128547403dc603e5a40e377c6eb0c8025.zip | |
Fix serialization of iterable types
So far, we have not supported serialization of iterable type
arguments to RPC methods. However, the recent change to pass
args as a tuple instead of forcing everything to kwargs means
that serialization of non-keyword args is broken. This patch
adds that support, as well as tests for the serializer, which
should have been there in the first place.
Related to blueprint unified-object-model
Change-Id: Ie02fffd89d9b79b4bc8270c14b2860c0e37d7a92
Diffstat (limited to 'nova/objects')
| -rw-r--r-- | nova/objects/base.py | 26 |
1 files changed, 24 insertions, 2 deletions
diff --git a/nova/objects/base.py b/nova/objects/base.py index f5fc37e03..6f2b6c81f 100644 --- a/nova/objects/base.py +++ b/nova/objects/base.py @@ -425,13 +425,35 @@ class NovaObjectSerializer(nova.openstack.common.rpc.serializer.Serializer): that needs to accept or return NovaObjects 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 (hasattr(entity, 'obj_to_primitive') and - callable(entity.obj_to_primitive)): + 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 'nova_object.name' in entity: entity = NovaObject.obj_from_primitive(entity, context=context) + elif isinstance(entity, (tuple, list, set)): + entity = self._process_iterable(context, self.deserialize_entity, + entity) return entity |
