From 6b5a4ee0db410817e5263b04dc7cb3762eb5bf41 Mon Sep 17 00:00:00 2001 From: Cedric Brandily Date: Tue, 24 Jan 2017 23:08:43 +0100 Subject: [PATCH] Optimize _make_firewall_group_dict_with_rules This change optimizes _make_firewall_group_dict_with_rules implementation by getting rules for a firewall in one db query (through the new method _get_policy_ordered_rules) instead of one db query per rule (previous implementation) in order to improve performance. Related-Bug: #1658817 Change-Id: Ibf13a9c0a4d504d47bd92fbd958c2d5e24abfdad (cherry picked from commit 0565b488b1c3dd18b927690237ebbe90c510eb4c) --- .../db/firewall/v2/firewall_db_v2.py | 23 +++++++++---------- .../db/firewall/v2/test_firewall_db_v2.py | 14 +++++++++++ 2 files changed, 25 insertions(+), 12 deletions(-) diff --git a/neutron_fwaas/db/firewall/v2/firewall_db_v2.py b/neutron_fwaas/db/firewall/v2/firewall_db_v2.py index c6fa1de61..73674fdc7 100644 --- a/neutron_fwaas/db/firewall/v2/firewall_db_v2.py +++ b/neutron_fwaas/db/firewall/v2/firewall_db_v2.py @@ -233,27 +233,26 @@ class Firewall_db_mixin_v2(fw_ext.Firewallv2PluginBase, base_db.CommonDbMixin): 'status': firewall_group['status']} return self._fields(res, fields) + def _get_policy_ordered_rules(self, context, policy_id): + query = (context.session.query(FirewallRuleV2) + .join(FirewallPolicyRuleAssociation) + .filter_by(firewall_policy_id=policy_id) + .order_by(FirewallPolicyRuleAssociation.position)) + return [self._make_firewall_rule_dict(rule) for rule in query] + def _make_firewall_group_dict_with_rules(self, context, firewall_group_id): firewall_group = self.get_firewall_group(context, firewall_group_id) ingress_policy_id = firewall_group['ingress_firewall_policy_id'] if ingress_policy_id: - ingress_policy = self.get_firewall_policy( - context, ingress_policy_id) - ingress_rules_list = [self.get_firewall_rule( - context, rule_id) for rule_id - in ingress_policy['firewall_rules']] - firewall_group['ingress_rule_list'] = ingress_rules_list + firewall_group['ingress_rule_list'] = ( + self._get_policy_ordered_rules(context, ingress_policy_id)) else: firewall_group['ingress_rule_list'] = [] egress_policy_id = firewall_group['egress_firewall_policy_id'] if egress_policy_id: - egress_policy = self.get_firewall_policy( - context, egress_policy_id) - egress_rules_list = [self.get_firewall_rule( - context, rule_id) for rule_id - in egress_policy['firewall_rules']] - firewall_group['egress_rule_list'] = egress_rules_list + firewall_group['egress_rule_list'] = ( + self._get_policy_ordered_rules(context, egress_policy_id)) else: firewall_group['egress_rule_list'] = [] return firewall_group diff --git a/neutron_fwaas/tests/unit/db/firewall/v2/test_firewall_db_v2.py b/neutron_fwaas/tests/unit/db/firewall/v2/test_firewall_db_v2.py index 60c6fdad1..d45c0fc92 100644 --- a/neutron_fwaas/tests/unit/db/firewall/v2/test_firewall_db_v2.py +++ b/neutron_fwaas/tests/unit/db/firewall/v2/test_firewall_db_v2.py @@ -349,6 +349,20 @@ class FirewallPluginV2DbTestCase(base.NeutronDbPluginV2TestCase): class TestFirewallDBPluginV2(FirewallPluginV2DbTestCase): + def test_get_policy_ordered_rules(self): + with self.firewall_rule(name='alone'), \ + self.firewall_rule(name='fwr1') as fwr1, \ + self.firewall_rule(name='fwr3') as fwr3, \ + self.firewall_rule(name='fwr2') as fwr2: + fwrs = fwr1, fwr2, fwr3 + expected_ids = [fwr['firewall_rule']['id'] for fwr in fwrs] + with self.firewall_policy(firewall_rules=expected_ids) as fwp: + ctx = context.get_admin_context() + fwp_id = fwp['firewall_policy']['id'] + observeds = self.plugin._get_policy_ordered_rules(ctx, fwp_id) + observed_ids = [r['id'] for r in observeds] + self.assertEqual(expected_ids, observed_ids) + def test_create_firewall_policy(self): name = "firewall_policy1" attrs = self._get_test_firewall_policy_attrs(name)