]> review.fuel-infra Code Review - openstack-build/neutron-build.git/commitdiff
After bulk create send DHCP notification
authorliudong <liudong78@huawei.com>
Mon, 4 Nov 2013 17:14:50 +0000 (01:14 +0800)
committerliudong <willowd878@gmail.com>
Mon, 10 Mar 2014 03:47:14 +0000 (11:47 +0800)
In the past send_dhcp_notification only handle single resource
because of VALID_RESOURCES = ['network', 'subnet', 'port'].
When I use bulk created ports to boot instance, the VMs could
not get IP address from DHCP agent. So I add some special handle
in function notify().

Add unit test for bulk create dhcp notification.

Modify a paramter for code style.

Change-Id: Ibf2b3380dc3081beaf0f2f68042b022f2726bbe7
Closes-Bug: #1247902

neutron/api/rpc/agentnotifiers/dhcp_rpc_agent_api.py
neutron/api/v2/base.py
neutron/tests/unit/test_api_v2.py

index 4ed724dcb36f7c387f7523e9f196df21d2133cbc..4be1072a341ce4bb8af2e3049d31eb8d274afc7a 100644 (file)
@@ -128,9 +128,9 @@ class DhcpAgentNotifyAPI(proxy.RpcProxy):
                                 {'admin_state_up': admin_state_up},
                                 host)
 
-    def notify(self, context, data, methodname):
+    def notify(self, context, data, method_name):
         # data is {'key' : 'value'} with only one key
-        if methodname not in self.VALID_METHOD_NAMES:
+        if method_name not in self.VALID_METHOD_NAMES:
             return
         obj_type = data.keys()[0]
         if obj_type not in self.VALID_RESOURCES:
@@ -143,11 +143,11 @@ class DhcpAgentNotifyAPI(proxy.RpcProxy):
             network_id = obj_value['network_id']
         if not network_id:
             return
-        methodname = methodname.replace(".", "_")
-        if methodname.endswith("_delete_end"):
+        method_name = method_name.replace(".", "_")
+        if method_name.endswith("_delete_end"):
             if 'id' in obj_value:
-                self._notification(context, methodname,
+                self._notification(context, method_name,
                                    {obj_type + '_id': obj_value['id']},
                                    network_id)
         else:
-            self._notification(context, methodname, data, network_id)
+            self._notification(context, method_name, data, network_id)
index 12a10ae34fcbb556ff860435f6f5cbcf6baec08d..b56901450ddd31565d23c029335465555e93e547 100644 (file)
@@ -271,7 +271,12 @@ class Controller(object):
 
     def _send_dhcp_notification(self, context, data, methodname):
         if cfg.CONF.dhcp_agent_notification:
-            self._dhcp_agent_notifier.notify(context, data, methodname)
+            if self._collection in data:
+                for body in data[self._collection]:
+                    item = {self._resource: body}
+                    self._dhcp_agent_notifier.notify(context, item, methodname)
+            else:
+                self._dhcp_agent_notifier.notify(context, data, methodname)
 
     def index(self, request, **kwargs):
         """Returns a list of the requested entity."""
index cbe45304ad2d0f663e3d2df287b75a57e892aade..7291c7d823130e20bd25d8338e5ce9adc2f6edb6 100644 (file)
@@ -26,6 +26,7 @@ import webtest
 
 from neutron.api import api_common
 from neutron.api.extensions import PluginAwareExtensionManager
+from neutron.api.rpc.agentnotifiers import dhcp_rpc_agent_api
 from neutron.api.v2 import attributes
 from neutron.api.v2 import base as v2_base
 from neutron.api.v2 import router
@@ -1305,6 +1306,57 @@ class NotificationTest(APIv2TestBase):
                                    notification_level='DEBUG')
 
 
+class DHCPNotificationTest(APIv2TestBase):
+    def _test_dhcp_notifier(self, opname, resource, initial_input=None):
+        instance = self.plugin.return_value
+        instance.get_networks.return_value = initial_input
+        instance.get_networks_count.return_value = 0
+        expected_code = exc.HTTPCreated.code
+        with mock.patch.object(dhcp_rpc_agent_api.DhcpAgentNotifyAPI,
+                               'notify') as dhcp_notifier:
+            if opname == 'create':
+                res = self.api.post_json(
+                    _get_path('networks'),
+                    initial_input)
+            if opname == 'update':
+                res = self.api.put_json(
+                    _get_path('networks', id=_uuid()),
+                    initial_input)
+                expected_code = exc.HTTPOk.code
+            if opname == 'delete':
+                res = self.api.delete(_get_path('networks', id=_uuid()))
+                expected_code = exc.HTTPNoContent.code
+            expected_item = mock.call(mock.ANY, mock.ANY,
+                                      resource + "." + opname + ".end")
+            if initial_input and resource not in initial_input:
+                resource += 's'
+            num = len(initial_input[resource]) if initial_input and isinstance(
+                initial_input[resource], list) else 1
+            expected = [expected_item for x in xrange(num)]
+            self.assertEqual(expected, dhcp_notifier.call_args_list)
+            self.assertEqual(num, dhcp_notifier.call_count)
+        self.assertEqual(expected_code, res.status_int)
+
+    def test_network_create_dhcp_notifer(self):
+        input = {'network': {'name': 'net',
+                             'tenant_id': _uuid()}}
+        self._test_dhcp_notifier('create', 'network', input)
+
+    def test_network_delete_dhcp_notifer(self):
+        self._test_dhcp_notifier('delete', 'network')
+
+    def test_network_update_dhcp_notifer(self):
+        input = {'network': {'name': 'net'}}
+        self._test_dhcp_notifier('update', 'network', input)
+
+    def test_networks_create_bulk_dhcp_notifer(self):
+        input = {'networks': [{'name': 'net1',
+                               'tenant_id': _uuid()},
+                              {'name': 'net2',
+                               'tenant_id': _uuid()}]}
+        self._test_dhcp_notifier('create', 'network', input)
+
+
 class QuotaTest(APIv2TestBase):
     def test_create_network_quota(self):
         cfg.CONF.set_override('quota_network', 1, group='QUOTAS')