use payloads for PORT BEFORE_UPDATE events

This patch switches the code over to the payload style of callbacks
for PORT BEFORE_UPDATE events

Change-Id: Ie55a04deac6c2f54f7f5d475c350f0fbf7b1fe77
This commit is contained in:
Nurmatov Mamatisa 2021-06-11 11:38:05 +03:00
parent 1e2088abbe
commit 324a35a3d0
5 changed files with 71 additions and 47 deletions

View File

@ -888,20 +888,15 @@ class SecurityGroupDbMixin(ext_sg.SecurityGroupPluginBase,
if default_group: if default_group:
return default_group.security_group_id return default_group.security_group_id
@registry.receives(resources.PORT, [events.BEFORE_UPDATE]) @registry.receives(resources.PORT, [events.BEFORE_CREATE,
def _ensure_default_security_group_handler_port( events.BEFORE_UPDATE])
self, resource, event, trigger, context, **kwargs):
project_id = kwargs['original_' + resource]['tenant_id']
if project_id:
self._ensure_default_security_group(context, project_id)
@registry.receives(resources.PORT, [events.BEFORE_CREATE])
@registry.receives(resources.NETWORK, [events.BEFORE_CREATE]) @registry.receives(resources.NETWORK, [events.BEFORE_CREATE])
def _ensure_default_security_group_handler_before_create( def _ensure_default_security_group_handler(self, resource, event, trigger,
self, resource, event, trigger, payload=None): payload):
if event == events.BEFORE_UPDATE:
# TODO(boden): refactor into single callback method project_id = payload.states[0]['tenant_id']
project_id = payload.latest_state['tenant_id'] else:
project_id = payload.latest_state['tenant_id']
if project_id: if project_id:
self._ensure_default_security_group(payload.context, project_id) self._ensure_default_security_group(payload.context, project_id)

View File

@ -627,16 +627,18 @@ class Ml2Plugin(db_base_plugin_v2.NeutronDbPluginV2,
need_notify, update_binding_levels=True): need_notify, update_binding_levels=True):
port_id = orig_context.current['id'] port_id = orig_context.current['id']
plugin_context = orig_context._plugin_context plugin_context = orig_context._plugin_context
port = orig_context.current
original_port = orig_context.current
orig_binding = orig_context._binding orig_binding = orig_context._binding
new_binding = bind_context._binding new_binding = bind_context._binding
# TODO(yamahata): revise what to be passed or new resource registry.publish(resources.PORT, events.BEFORE_UPDATE, self,
# like PORTBINDING should be introduced? payload=events.DBEventPayload(
# It would be addressed during EventPayload conversion. plugin_context,
registry.notify(resources.PORT, events.BEFORE_UPDATE, self, resource_id=port_id,
context=plugin_context, port=orig_context.current, metadata={'orig_binding': orig_binding,
original_port=orig_context.current, 'new_binding': new_binding},
orig_binding=orig_binding, new_binding=new_binding) states=(original_port, port)))
# After we've attempted to bind the port, we begin a # After we've attempted to bind the port, we begin a
# transaction, get the current port state, and decide whether # transaction, get the current port state, and decide whether
@ -1697,9 +1699,11 @@ class Ml2Plugin(db_base_plugin_v2.NeutronDbPluginV2,
need_port_update_notify = False need_port_update_notify = False
bound_mech_contexts = [] bound_mech_contexts = []
original_port = self.get_port(context, id) original_port = self.get_port(context, id)
registry.notify(resources.PORT, events.BEFORE_UPDATE, self, registry.publish(resources.PORT, events.BEFORE_UPDATE, self,
context=context, port=attrs, payload=events.DBEventPayload(
original_port=original_port) context,
resource_id=id,
states=(original_port, attrs)))
with db_api.CONTEXT_WRITER.using(context): with db_api.CONTEXT_WRITER.using(context):
port_db = self._get_port(context, id) port_db = self._get_port(context, id)
binding = p_utils.get_port_binding_by_status_and_host( binding = p_utils.get_port_binding_by_status_and_host(
@ -2161,9 +2165,11 @@ class Ml2Plugin(db_base_plugin_v2.NeutronDbPluginV2,
portbindings.HOST_ID: host, portbindings.HOST_ID: host,
'status': status 'status': status
} }
registry.notify(resources.PORT, events.BEFORE_UPDATE, self, registry.publish(resources.PORT, events.BEFORE_UPDATE, self,
original_port=port, payload=events.DBEventPayload(
context=context, port=attr) context,
resource_id=port_id,
states=(port, attr,)))
with db_api.CONTEXT_WRITER.using(context): with db_api.CONTEXT_WRITER.using(context):
context.session.add(port) # bring port into writer session context.session.add(port) # bring port into writer session
if (port.status != status and if (port.status != status and

View File

@ -86,9 +86,6 @@ class QoSPlugin(qos.QoSPluginBase):
self._validate_create_port_callback, self._validate_create_port_callback,
callbacks_resources.PORT, callbacks_resources.PORT,
callbacks_events.PRECOMMIT_CREATE) callbacks_events.PRECOMMIT_CREATE)
# TODO(lajoskatona): PORT BEFORE_UPDATE is a notify, so
# "old style" kwargs instead of payload object, let's change it
# to notify and payload.
callbacks_registry.subscribe( callbacks_registry.subscribe(
self._check_port_for_placement_allocation_change, self._check_port_for_placement_allocation_change,
callbacks_resources.PORT, callbacks_resources.PORT,
@ -254,13 +251,14 @@ class QoSPlugin(qos.QoSPluginBase):
self.validate_policy_for_port(context, policy, port) self.validate_policy_for_port(context, policy, port)
def _check_port_for_placement_allocation_change(self, resource, event, def _check_port_for_placement_allocation_change(self, resource, event,
trigger, **kwargs): trigger, payload):
context = kwargs['context'] context = payload.context
orig_port = kwargs['original_port'] orig_port = payload.states[0]
port = payload.latest_state
original_policy_id = orig_port.get(qos_consts.QOS_POLICY_ID) original_policy_id = orig_port.get(qos_consts.QOS_POLICY_ID)
if qos_consts.QOS_POLICY_ID not in kwargs['port']: if qos_consts.QOS_POLICY_ID not in port:
return return
policy_id = kwargs['port'].get(qos_consts.QOS_POLICY_ID) policy_id = port.get(qos_consts.QOS_POLICY_ID)
if policy_id == original_policy_id: if policy_id == original_policy_id:
return return

View File

@ -1471,7 +1471,7 @@ class TestMl2PortsV2(test_plugin.TestPortsV2, Ml2PluginV2TestCase):
ctx = context.get_admin_context() ctx = context.get_admin_context()
b_update_events = [] b_update_events = []
a_update_events = [] a_update_events = []
b_receiver = lambda *a, **k: b_update_events.append(k) b_receiver = lambda r, e, t, payload: b_update_events.append(payload)
a_receiver = lambda *a, **k: a_update_events.append(k['port']) a_receiver = lambda *a, **k: a_update_events.append(k['port'])
registry.subscribe(b_receiver, resources.PORT, registry.subscribe(b_receiver, resources.PORT,
events.BEFORE_UPDATE) events.BEFORE_UPDATE)
@ -1483,20 +1483,24 @@ class TestMl2PortsV2(test_plugin.TestPortsV2, Ml2PluginV2TestCase):
# updating in the host should result in two AFTER_UPDATE events. # updating in the host should result in two AFTER_UPDATE events.
# one to change the host_id, the second to commit a binding # one to change the host_id, the second to commit a binding
self.assertEqual(2, len(b_update_events)) self.assertEqual(2, len(b_update_events))
self.assertEqual({'context': ctx, # use dict for assertEqual because payload is object
'port': {'binding:host_id': 'newhost'}, expected_dict = {'context': ctx,
'original_port': mock.ANY}, 'port': {'binding:host_id': 'newhost'},
b_update_events[0]) 'original_port': mock.ANY}
self.assertIn('orig_binding', b_update_events[1]) actual_dict = {'context': b_update_events[0].context,
self.assertIn('new_binding', b_update_events[1]) 'port': b_update_events[0].latest_state,
self.assertDictContainsSubset({'context': ctx}, b_update_events[1]) 'original_port': b_update_events[0].states[0]}
self.assertEqual(expected_dict, actual_dict)
self.assertIn('orig_binding', b_update_events[1].metadata)
self.assertIn('new_binding', b_update_events[1].metadata)
self.assertDictContainsSubset({'context': ctx}, actual_dict)
self.assertDictContainsSubset({ self.assertDictContainsSubset({
'admin_state_up': True, 'admin_state_up': True,
'binding:host_id': 'newhost', 'binding:host_id': 'newhost',
'binding:vif_type': 'unbound', 'binding:vif_type': 'unbound',
'binding:vnic_type': u'normal', 'binding:vnic_type': u'normal',
'status': 'DOWN'}, 'status': 'DOWN'},
b_update_events[1]['port']) b_update_events[1].latest_state)
self.assertEqual('newhost', a_update_events[0]['binding:host_id']) self.assertEqual('newhost', a_update_events[0]['binding:host_id'])
self.assertEqual('unbound', a_update_events[0]['binding:vif_type']) self.assertEqual('unbound', a_update_events[0]['binding:vif_type'])
self.assertEqual('newhost', a_update_events[1]['binding:host_id']) self.assertEqual('newhost', a_update_events[1]['binding:host_id'])

View File

@ -1355,11 +1355,17 @@ class TestQosPluginDB(base.BaseQosTestCase):
qos1_obj = self._make_qos_policy() qos1_obj = self._make_qos_policy()
kwargs = self._prepare_for_port_placement_allocation_change( kwargs = self._prepare_for_port_placement_allocation_change(
qos1=qos1_obj, qos2=qos1_obj) qos1=qos1_obj, qos2=qos1_obj)
context = kwargs['context']
original_port = kwargs['original_port']
port = kwargs['port']
with mock.patch.object( with mock.patch.object(
self.qos_plugin, self.qos_plugin,
'_change_placement_allocation') as mock_alloc_change: '_change_placement_allocation') as mock_alloc_change:
self.qos_plugin._check_port_for_placement_allocation_change( self.qos_plugin._check_port_for_placement_allocation_change(
'PORT', 'before_update', 'test_plugin', **kwargs) 'PORT', 'before_update', 'test_plugin',
payload=events.DBEventPayload(
context, states=(original_port, port)))
mock_alloc_change.assert_not_called() mock_alloc_change.assert_not_called()
def test_check_port_for_placement_allocation_change(self): def test_check_port_for_placement_allocation_change(self):
@ -1367,12 +1373,17 @@ class TestQosPluginDB(base.BaseQosTestCase):
qos2_obj = self._make_qos_policy() qos2_obj = self._make_qos_policy()
kwargs = self._prepare_for_port_placement_allocation_change( kwargs = self._prepare_for_port_placement_allocation_change(
qos1=qos1_obj, qos2=qos2_obj) qos1=qos1_obj, qos2=qos2_obj)
context = kwargs['context']
original_port = kwargs['original_port']
port = kwargs['port']
with mock.patch.object( with mock.patch.object(
self.qos_plugin, self.qos_plugin,
'_change_placement_allocation') as mock_alloc_change: '_change_placement_allocation') as mock_alloc_change:
self.qos_plugin._check_port_for_placement_allocation_change( self.qos_plugin._check_port_for_placement_allocation_change(
'PORT', 'before_update', 'test_plugin', **kwargs) 'PORT', 'before_update', 'test_plugin',
payload=events.DBEventPayload(
context, states=(original_port, port)))
mock_alloc_change.assert_called_once_with( mock_alloc_change.assert_called_once_with(
qos1_obj, qos2_obj, kwargs['original_port']) qos1_obj, qos2_obj, kwargs['original_port'])
@ -1380,12 +1391,17 @@ class TestQosPluginDB(base.BaseQosTestCase):
qos1_obj = self._make_qos_policy() qos1_obj = self._make_qos_policy()
kwargs = self._prepare_for_port_placement_allocation_change( kwargs = self._prepare_for_port_placement_allocation_change(
qos1=qos1_obj, qos2=None) qos1=qos1_obj, qos2=None)
context = kwargs['context']
original_port = kwargs['original_port']
port = kwargs['port']
with mock.patch.object( with mock.patch.object(
self.qos_plugin, self.qos_plugin,
'_change_placement_allocation') as mock_alloc_change: '_change_placement_allocation') as mock_alloc_change:
self.qos_plugin._check_port_for_placement_allocation_change( self.qos_plugin._check_port_for_placement_allocation_change(
'PORT', 'before_update', 'test_plugin', **kwargs) 'PORT', 'before_update', 'test_plugin',
payload=events.DBEventPayload(
context, states=(original_port, port)))
mock_alloc_change.assert_called_once_with( mock_alloc_change.assert_called_once_with(
qos1_obj, None, kwargs['original_port']) qos1_obj, None, kwargs['original_port'])
@ -1394,12 +1410,17 @@ class TestQosPluginDB(base.BaseQosTestCase):
kwargs = self._prepare_for_port_placement_allocation_change( kwargs = self._prepare_for_port_placement_allocation_change(
qos1=qos1_obj, qos2=None) qos1=qos1_obj, qos2=None)
kwargs['port'].pop('qos_policy_id') kwargs['port'].pop('qos_policy_id')
context = kwargs['context']
original_port = kwargs['original_port']
port = kwargs['port']
with mock.patch.object( with mock.patch.object(
self.qos_plugin, self.qos_plugin,
'_change_placement_allocation') as mock_alloc_change: '_change_placement_allocation') as mock_alloc_change:
self.qos_plugin._check_port_for_placement_allocation_change( self.qos_plugin._check_port_for_placement_allocation_change(
'PORT', 'before_update', 'test_plugin', **kwargs) 'PORT', 'before_update', 'test_plugin',
payload=events.DBEventPayload(
context, states=(original_port, port)))
mock_alloc_change.assert_not_called() mock_alloc_change.assert_not_called()
def _prepare_port_for_placement_allocation(self, qos1, qos2=None, def _prepare_port_for_placement_allocation(self, qos1, qos2=None,