Get rid of marshall_fdb_entries

This function isn't necessary. The json encoding of a
named tuple will already turn into a normal list.

ports = [l2pop_rpc.PortInfo('abcdef', '1.1.1.1')]
json.dumps(ports) == json.dumps([(mac, ip) for (mac, ip) in ports])

An argument could be made that the PortInfo object could have
something added to it later that we wouldn't want to serialize
in order to remain backward compatible. However, doing so would
break all of the constructions of PortInfo objects on the agents
once they got the updated code for PortInfo that requires the
new parameter.

So there is no way currently to add a new field to PortInfo without
breaking existing legacy clients or breaking new clients.
Given that, let's stop doing the json encoder's job.

This patch also adds a sanity unit test to make sure the json
serialization method used in oslo does not break on the named tuples.

Change-Id: I45ae69ef8c9c15ad21a28dc42f2d78b234ccfb0c
changes/05/274605/2
Kevin Benton 7 years ago
parent 9546ee7d92
commit a19029d3d6
  1. 32
      neutron/plugins/ml2/drivers/l2pop/rpc.py
  2. 22
      neutron/tests/unit/plugins/ml2/drivers/l2pop/test_mech_driver.py

@ -14,7 +14,6 @@
# under the License.
import collections
import copy
from oslo_log import log as logging
import oslo_messaging
@ -46,9 +45,8 @@ class L2populationAgentNotifyAPI(object):
'method': method,
'fdb_entries': fdb_entries})
marshalled_fdb_entries = self._marshall_fdb_entries(fdb_entries)
cctxt = self.client.prepare(topic=self.topic_l2pop_update, fanout=True)
cctxt.cast(context, method, fdb_entries=marshalled_fdb_entries)
cctxt.cast(context, method, fdb_entries=fdb_entries)
def _notification_host(self, context, method, fdb_entries, host):
LOG.debug('Notify l2population agent %(host)s at %(topic)s the '
@ -58,9 +56,8 @@ class L2populationAgentNotifyAPI(object):
'method': method,
'fdb_entries': fdb_entries})
marshalled_fdb_entries = self._marshall_fdb_entries(fdb_entries)
cctxt = self.client.prepare(topic=self.topic_l2pop_update, server=host)
cctxt.cast(context, method, fdb_entries=marshalled_fdb_entries)
cctxt.cast(context, method, fdb_entries=fdb_entries)
def add_fdb_entries(self, context, fdb_entries, host=None):
if fdb_entries:
@ -88,28 +85,3 @@ class L2populationAgentNotifyAPI(object):
else:
self._notification_fanout(context, 'update_fdb_entries',
fdb_entries)
@staticmethod
def _marshall_fdb_entries(fdb_entries):
"""Prepares fdb_entries for serialization to JSON for RPC.
All methods in this class that send messages should call this to
marshall fdb_entries for the wire.
:param fdb_entries: Original fdb_entries data-structure. Looks like:
{
<uuid>: {
...,
'ports': {
<ip address>: [ PortInfo, ... ],
...
:returns: Deep copy with PortInfo converted to [mac, ip]
"""
marshalled = copy.deepcopy(fdb_entries)
for value in marshalled.values():
if 'ports' in value:
for address, port_infos in value['ports'].items():
value['ports'][address] = [[mac, ip]
for mac, ip in port_infos]
return marshalled

@ -14,6 +14,7 @@
# under the License.
import mock
from oslo_serialization import jsonutils
import testtools
from neutron.common import constants
@ -138,22 +139,11 @@ class TestL2PopulationRpcTestCase(test_plugin.Ml2PluginV2TestCase):
self.assertEqual(('00:00:00:00:00:00', '0.0.0.0'), port_info_list[0])
self.assertEqual(('fa:16:3e:ff:8c:0f', '10.0.0.6'), port_info_list[1])
def test__marshall_fdb_entries(self):
entries = {'foouuid': {
'segment_id': 1001,
'ports': {'192.168.0.10': [('00:00:00:00:00:00', '0.0.0.0'),
('fa:16:3e:ff:8c:0f', '10.0.0.6')]},
'network_type': 'vxlan'}}
entries = l2pop_rpc.L2populationAgentNotifyAPI._marshall_fdb_entries(
entries)
port_info_list = entries['foouuid']['ports']['192.168.0.10']
# Check that the PortInfo tuples have been converted to list
self.assertIsInstance(port_info_list[0], list)
self.assertIsInstance(port_info_list[1], list)
self.assertEqual(['00:00:00:00:00:00', '0.0.0.0'], port_info_list[0])
self.assertEqual(['fa:16:3e:ff:8c:0f', '10.0.0.6'], port_info_list[1])
def test_portinfo_marshalled_as_list(self):
entry = ['fa:16:3e:ff:8c:0f', '10.0.0.6']
payload = {'netuuid': {'ports': {'1': [l2pop_rpc.PortInfo(*entry)]}}}
result = jsonutils.loads(jsonutils.dumps(payload))
self.assertEqual(entry, result['netuuid']['ports']['1'][0])
def test_fdb_add_called(self):
self._register_ml2_agents()

Loading…
Cancel
Save