Removed "reverse" from policy resolution process 59/19759/3
authorMartin Sunal <msunal@cisco.com>
Thu, 7 May 2015 00:18:47 +0000 (02:18 +0200)
committerMartin Sunal <msunal@cisco.com>
Sat, 9 May 2015 20:36:45 +0000 (20:36 +0000)
Reversed EPG roles(cons/prov) based on ID complicates debugging.

Signed-off-by: Martin Sunal <msunal@cisco.com>
groupbasedpolicy/src/main/java/org/opendaylight/groupbasedpolicy/resolver/Policy.java
groupbasedpolicy/src/main/java/org/opendaylight/groupbasedpolicy/resolver/PolicyInfo.java
groupbasedpolicy/src/main/java/org/opendaylight/groupbasedpolicy/resolver/PolicyResolver.java
groupbasedpolicy/src/main/java/org/opendaylight/groupbasedpolicy/resolver/RuleGroup.java
groupbasedpolicy/src/test/java/org/opendaylight/groupbasedpolicy/resolver/PolicyResolverTest.java
renderers/ofoverlay/src/main/java/org/opendaylight/groupbasedpolicy/renderer/ofoverlay/flow/PolicyEnforcer.java

index e283a13a42d21436bf5017e517c05fbb5954431e..9522fdc3c0cdb2b0aabb839d0e64e2a70100a887 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
+ * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved.
  *
  * This program and the accompanying materials are made available under the
  * terms of the Eclipse Public License v1.0 which accompanies this distribution,
@@ -12,6 +12,8 @@ import java.util.ArrayList;
 import java.util.Collections;
 import java.util.List;
 
+import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
 import javax.annotation.concurrent.Immutable;
 
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.SubjectName;
@@ -24,55 +26,83 @@ import com.google.common.collect.Table.Cell;
 
 /**
  * Represent the policy that applies to a single pair of endpoint groups
- * The policy is represented as a list of {@link RuleGroup} objects.  A 
- * {@link RuleGroup} references ordered lists of rules from the policy,
- * along with the associated {@link Tenant}, {@link Contract}, and 
- * {@link SubjectName}.
- * 
+ * The policy is represented as a list of {@link RuleGroup} objects. A {@link RuleGroup} references
+ * ordered lists of rules from the policy,
+ * along with the associated {@link Tenant}, {@link Contract}, and {@link SubjectName}.
  * A {@link RuleGroup} applies to a particular endpoint based on the set of
- * conditions that are active for that endpoint.  All rule groups associated
+ * conditions that are active for that endpoint. All rule groups associated
  * with matching {@link ConditionSet}s apply.
- * @author readams
  */
 @Immutable
 public class Policy {
-    public static final Policy EMPTY = 
-            new Policy(ImmutableTable.<ConditionSet, ConditionSet, 
-                                       List<RuleGroup>>of());
-    
-    final Table<ConditionSet, ConditionSet, List<RuleGroup>> ruleMap;
-    final boolean reversed;
-    public Policy(Table<ConditionSet, ConditionSet, List<RuleGroup>> ruleMap) {
-        super();
-        this.ruleMap = ruleMap;
-        this.reversed = false;
-    }
-    public Policy(Policy existing, boolean reversed) {
-        super();
-        this.ruleMap = existing.ruleMap;
-        this.reversed = existing.reversed != reversed;
+
+    /**
+     * Policy where {@link #getRuleMap()} returns empty table
+     */
+    public static final Policy EMPTY = new Policy(ImmutableTable.<ConditionSet, ConditionSet, List<RuleGroup>>of());
+
+    private final Table<ConditionSet, ConditionSet, List<RuleGroup>> ruleMap;
+
+    /**
+     * @param ruleMap {@code null} means that created {@link Policy} equals {@link Policy#EMPTY}
+     */
+    public Policy(@Nullable Table<ConditionSet, ConditionSet, List<RuleGroup>> ruleMap) {
+        if (ruleMap == null) {
+            this.ruleMap = EMPTY.getRuleMap();
+        } else {
+            this.ruleMap = ImmutableTable.copyOf(ruleMap);
+        }
     }
-    
-    @Override
-    public String toString() {
-        return "Policy [ruleMap=" + ruleMap + "]";
+
+    public @Nonnull Table<ConditionSet, ConditionSet, List<RuleGroup>> getRuleMap() {
+        return ruleMap;
     }
-    
+
     /**
      * Get the rules that apply to a particular pair of condition groups
+     *
      * @param fromCg the condition group that applies to the origin endpoint
      * @param toCg the condition group that applies to the destination endpoint
-     * @return
+     * @return sorted {@link RuleGroup} list
      */
-    public List<RuleGroup> getRules(ConditionGroup fromCg,
-                                    ConditionGroup toCg) {
-        ArrayList<RuleGroup> rules = new ArrayList<>();
+    public List<RuleGroup> getRules(ConditionGroup fromCg, ConditionGroup toCg) {
+        List<RuleGroup> rules = new ArrayList<>();
         for (Cell<ConditionSet, ConditionSet, List<RuleGroup>> cell : ruleMap.cellSet()) {
-            if (fromCg.contains(cell.getRowKey()) &&
-                    toCg.contains(cell.getColumnKey()))
+            if (fromCg.contains(cell.getRowKey()) && toCg.contains(cell.getColumnKey()))
                 rules.addAll(cell.getValue());
         }
         Collections.sort(rules);
         return rules;
     }
-}
\ No newline at end of file
+
+    @Override
+    public int hashCode() {
+        final int prime = 31;
+        int result = 1;
+        result = prime * result + ((ruleMap == null) ? 0 : ruleMap.hashCode());
+        return result;
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj)
+            return true;
+        if (obj == null)
+            return false;
+        if (getClass() != obj.getClass())
+            return false;
+        Policy other = (Policy) obj;
+        if (ruleMap == null) {
+            if (other.ruleMap != null)
+                return false;
+        } else if (!ruleMap.equals(other.ruleMap))
+            return false;
+        return true;
+    }
+
+    @Override
+    public String toString() {
+        return "Policy [ruleMap=" + ruleMap + "]";
+    }
+
+}
index aa6448f0417c5558096de7ec7cec3cbac90ae12d..8b0f8bb1078d3f45f7e12153bc13a4a1ad5e8ea8 100644 (file)
@@ -14,6 +14,7 @@ import java.util.List;
 import java.util.Map;
 import java.util.Set;
 
+import javax.annotation.Nonnull;
 import javax.annotation.concurrent.Immutable;
 
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.ConditionName;
@@ -40,20 +41,19 @@ public class PolicyInfo {
     public Table<EgKey, EgKey, Policy> getPolicyMap() {
         return policyMap;
     }
-    
+
     /**
-     * Get the policy that currently applies to traffic flowing out of 
-     * the specified originating endpoint group into the specified destination
-     * endpoint group.  Note that there will be policy only for one of the two
-     * possible directions.
-     * 
-     * @param fromGroup the endpoint group for the originating endpoint
-     * @param toGroup the endpoint group for the destination endpoint
-     * @return the {@link Policy} that applies.  Cannot be null
+     * Get the policy that currently applies between consumer endpoint group and provider endpoint
+     * group.
+     *
+     * @param consEgKey the consumer endpoint group
+     * @param provEgKey the provider endpoint group
+     * @return the {@link Policy} that applies. Cannot be null
      */
-    public Policy getPolicy(EgKey fromGroup, EgKey toGroup) {
-        Policy p = policyMap.get(fromGroup, toGroup);
-        if (p == null) return Policy.EMPTY;
+    public @Nonnull Policy getPolicy(EgKey consEgKey, EgKey provEgKey) {
+        Policy p = policyMap.get(consEgKey, provEgKey);
+        if (p == null)
+            return Policy.EMPTY;
         return p;
     }
 
@@ -66,14 +66,14 @@ public class PolicyInfo {
     public Set<ConditionSet> getEgConditions(EgKey eg) {
         return Collections.unmodifiableSet(egConditions.get(eg));
     }
-    
+
     /**
      * Get the condition group as it applies to the given list of conditions
      * @param eg
      * @param conditions
      * @return
      */
-    public ConditionGroup getEgCondGroup(EgKey eg, 
+    public ConditionGroup getEgCondGroup(EgKey eg,
                                          List<ConditionName> conditions) {
         Set<ConditionSet> egconds = egConditions.get(eg);
         if (egconds == null) return ConditionGroup.EMPTY;
@@ -95,7 +95,7 @@ public class PolicyInfo {
      * @return the set of endpoint groups
      */
     public Set<EgKey> getPeers(EgKey eg) {
-        return Sets.union(policyMap.row(eg).keySet(), 
+        return Sets.union(policyMap.row(eg).keySet(),
                           policyMap.column(eg).keySet());
     }
 }
\ No newline at end of file
index 6371f10a30f2d5150fff309c6257ee2d87680642..8fe0a5ddecced97539a172b34ae7798b5e9ef77a 100644 (file)
@@ -36,11 +36,8 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.SubjectName;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.TenantId;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.ConsumerSelectionRelator;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.HasDirection.Direction;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.Matcher.MatchType;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.ProviderSelectionRelator;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.has.classifier.refs.ClassifierRef;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.has.classifier.refs.ClassifierRefBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.has.condition.matchers.ConditionMatcher;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.has.conditions.Condition;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.target.selector.QualityMatcher;
@@ -56,7 +53,6 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.contract.clause.provider.matchers.group.identification.constraints.GroupCapabilityConstraintCase;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.contract.clause.provider.matchers.group.identification.constraints.group.capability.constraint._case.CapabilityMatcher;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.contract.subject.Rule;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.contract.subject.RuleBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.endpoint.group.ConsumerNamedSelector;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.endpoint.group.ConsumerTargetSelector;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.endpoint.group.ProviderNamedSelector;
@@ -454,7 +450,7 @@ public class PolicyResolver implements AutoCloseable {
         }
     }
 
-    private boolean clauseMatches(Clause clause, ContractMatch match) {
+    private boolean clauseMatchesByGroupReqAndCapConstraints(Clause clause, ContractMatch match) {
         if (clause.getConsumerMatchers() != null) {
             GroupIdentificationConstraints groupIdentificationConstraintsConsumer = clause.getConsumerMatchers()
                     .getGroupIdentificationConstraints();
@@ -551,87 +547,37 @@ public class PolicyResolver implements AutoCloseable {
 
     private Policy resolvePolicy(Tenant contractTenant,
             Contract contract,
-            boolean reverse,
             Policy merge,
             Table<ConditionSet, ConditionSet,
             List<Subject>> subjectMap) {
         Table<ConditionSet, ConditionSet, List<RuleGroup>> ruleMap =
                 HashBasedTable.create();
         if (merge != null) {
-            ruleMap.putAll(merge.ruleMap);
+            ruleMap.putAll(merge.getRuleMap());
         }
         for (Cell<ConditionSet, ConditionSet, List<Subject>> entry : subjectMap.cellSet()) {
             List<RuleGroup> rules = new ArrayList<>();
-            ConditionSet rowKey = entry.getRowKey();
-            ConditionSet columnKey = entry.getColumnKey();
-            if (reverse) {
-                rowKey = columnKey;
-                columnKey = entry.getRowKey();
-            }
-            List<RuleGroup> oldrules =
-                    ruleMap.get(rowKey, columnKey);
+            ConditionSet consConds = entry.getRowKey();
+            ConditionSet provConds = entry.getColumnKey();
+            List<RuleGroup> oldrules = ruleMap.get(consConds, provConds);
             if (oldrules != null) {
                 rules.addAll(oldrules);
             }
             for (Subject s : entry.getValue()) {
                 if (s.getRule() == null)
                     continue;
-                List<Rule> srules;
-                if (reverse)
-                    srules = reverseRules(s.getRule());
-                else
-                    srules = Ordering
-                            .from(TenantUtils.RULE_COMPARATOR)
-                            .immutableSortedCopy(s.getRule());
-
-                RuleGroup rg = new RuleGroup(srules, s.getOrder(),
+
+                RuleGroup rg = new RuleGroup(s.getRule(), s.getOrder(),
                         contractTenant, contract,
                         s.getName());
                 rules.add(rg);
             }
             Collections.sort(rules);
-            ruleMap.put(rowKey, columnKey,
-                    Collections.unmodifiableList(rules));
+            ruleMap.put(consConds, provConds, Collections.unmodifiableList(rules));
         }
         return new Policy(ruleMap);
     }
 
-    private List<Rule> reverseRules(List<Rule> rules) {
-        ArrayList<Rule> nrules = new ArrayList<>();
-        for (Rule input : rules) {
-            if (input.getClassifierRef() == null ||
-                    input.getClassifierRef().size() == 0) {
-                nrules.add(input);
-                continue;
-            }
-
-            List<ClassifierRef> classifiers = new ArrayList<>();
-            for (ClassifierRef clr : input.getClassifierRef()) {
-                Direction nd = Direction.Bidirectional;
-                if (clr.getDirection() != null) {
-                    switch (clr.getDirection()) {
-                    case In:
-                        nd = Direction.Out;
-                        break;
-                    case Out:
-                        nd = Direction.In;
-                        break;
-                    case Bidirectional:
-                    default:
-                        nd = Direction.Bidirectional;
-                    }
-                }
-                classifiers.add(new ClassifierRefBuilder(clr)
-                        .setDirection(nd).build());
-            }
-            nrules.add(new RuleBuilder(input)
-                    .setClassifierRef(Collections.unmodifiableList(classifiers))
-                    .build());
-        }
-        Collections.sort(nrules, TenantUtils.RULE_COMPARATOR);
-        return Collections.unmodifiableList(nrules);
-    }
-
     /**
      * Get the "natural" direction for the policy for the given pair of endpoint
      * groups.
@@ -664,6 +610,8 @@ public class PolicyResolver implements AutoCloseable {
      * Choose the set of subjects that in scope for each possible set of
      * endpoint conditions
      */
+    // TODO Li msunal do we really need contractMatches to be a type Table<EgKey, EgKey, List<ContractMatch>>
+    // it should be sufficient to be just List<ContractMatch>
     protected Table<EgKey, EgKey, Policy>
             selectSubjects(Table<EgKey, EgKey,
                     List<ContractMatch>> contractMatches,
@@ -689,14 +637,7 @@ public class PolicyResolver implements AutoCloseable {
                         match.consumer.getId());
                 EgKey pkey = new EgKey(match.providerTenant.getId(),
                         match.provider.getId());
-                EgKey one = ckey;
-                EgKey two = pkey;
-                boolean reverse = shouldReverse(ckey, pkey);
-                if (reverse) {
-                    one = pkey;
-                    two = ckey;
-                }
-                Policy existing = policy.get(one, two);
+                Policy existing = policy.get(ckey, pkey);
 
                 HashMap<SubjectName, Subject> subjects = new HashMap<>();
                 for (Subject s : subjectList) {
@@ -708,7 +649,7 @@ public class PolicyResolver implements AutoCloseable {
 
                 for (Clause clause : clauses) {
                     if (clause.getSubjectRefs() != null &&
-                            clauseMatches(clause, match)) {
+                            clauseMatchesByGroupReqAndCapConstraints(clause, match)) {
                         ConditionSet consCSet = buildConsConditionSet(clause);
                         addConditionSet(ckey, consCSet, egConditions);
                         ConditionSet provCSet = buildProvConditionSet(clause);
@@ -727,10 +668,9 @@ public class PolicyResolver implements AutoCloseable {
                     }
                 }
 
-                policy.put(one, two,
+                policy.put(ckey, pkey,
                         resolvePolicy(match.contractTenant,
                                 match.contract,
-                                reverse,
                                 existing,
                                 subjectMap));
             }
index e3dfbe1bc91360831fc96039c79f2e2b53053b5d..372f0ff44829c2c5ea0c7dc76c0c0beb4c595077 100644 (file)
@@ -21,12 +21,12 @@ import com.google.common.collect.ComparisonChain;
 import com.google.common.collect.Ordering;
 
 /**
- * Represent a group of rules that could apply to a given pair of endpoints.  
- * Includes references back to the normalized policy that resulted in the rule 
+ * Represent a group of rules that could apply to a given pair of endpoints.
+ * Includes references back to the normalized policy that resulted in the rule
  * group.
  * @author readams
  */
-@Immutable 
+@Immutable
 public class RuleGroup implements Comparable<RuleGroup> {
     final List<Rule> rules;
     final Integer order;
@@ -38,13 +38,16 @@ public class RuleGroup implements Comparable<RuleGroup> {
                      Tenant contractTenant, Contract contract,
                      SubjectName subject) {
         super();
-        this.rules = rules;
+        this.rules = Ordering.from(TenantUtils.RULE_COMPARATOR).immutableSortedCopy(rules);
         this.order = order;
         this.contractTenant = contractTenant;
         this.relatedContract = contract;
         this.relatedSubject = subject;
     }
 
+    /**
+     * @return sorted {@link Rule} list
+     */
     public List<Rule> getRules() {
         return rules;
     }
@@ -106,7 +109,7 @@ public class RuleGroup implements Comparable<RuleGroup> {
     @Override
     public int compareTo(RuleGroup o) {
         return ComparisonChain.start()
-            .compare(order, o.order, 
+            .compare(order, o.order,
                      Ordering.natural().nullsLast())
             .compare(relatedSubject.getValue(), o.relatedSubject.getValue(),
                      Ordering.natural().nullsLast())
@@ -116,8 +119,8 @@ public class RuleGroup implements Comparable<RuleGroup> {
     @Override
     public String toString() {
         return "RuleGroup [rules=" + rules + ", order=" + order +
-               ", contractTenant=" + contractTenant.getId() + 
-               ", relatedContract=" + relatedContract.getId() + 
+               ", contractTenant=" + contractTenant.getId() +
+               ", relatedContract=" + relatedContract.getId() +
                ", relatedSubject=" + relatedSubject + "]";
     }
 
index cf87c52dbd483049bbe5834baeb7b8d9390a9c4e..72d516e5c7ac2fb1527bea498f26dde930ac5cc1 100644 (file)
@@ -137,7 +137,7 @@ public class PolicyResolverTest {
     Target t0 = new TargetBuilder()
         .setName(new TargetName("t1"))
         .build();
-    
+
     Rule rule1 = new RuleBuilder()
         .setName(new RuleName("r1"))
         .setOrder(Integer.valueOf(5))
@@ -212,7 +212,7 @@ public class PolicyResolverTest {
         .setConsumerMatchers(new ConsumerMatchersBuilder().build())
         .setProviderMatchers(new ProviderMatchersBuilder().build())
         .build();
-    
+
     Contract contract1 = new ContractBuilder()
         .setId(new ContractId("c9eea992-ba51-4e11-b797-986853832ad9"))
         .setTarget(ImmutableList.of(t1))
@@ -232,7 +232,7 @@ public class PolicyResolverTest {
         .setId(new ContractId("79de88e8-b37f-4764-a1a3-7f3b37b15433"))
         .setTarget(ImmutableList.of(t0))
         .build();
-    
+
     ConsumerNamedSelector cns1 = new ConsumerNamedSelectorBuilder()
         .setName(new SelectorName("cns1"))
         .setContract(ImmutableList.of(contract1.getId()))
@@ -248,7 +248,7 @@ public class PolicyResolverTest {
         .setContract(ImmutableList.of(contract1.getId(), contract2.getId()))
         .setCapability(ImmutableList.of(cap1, cap3))
         .build();
-    
+
     QualityMatcher qm1 = new QualityMatcherBuilder()
         .setName(new QualityMatcherName("qm1"))
         .setMatcherQuality(ImmutableList.of(new MatcherQualityBuilder(q1).build()))
@@ -265,7 +265,7 @@ public class PolicyResolverTest {
         .setName(new SelectorName("pts1"))
         .setQualityMatcher(ImmutableList.of(qm3))
         .build();
-    
+
     EndpointGroup eg1 = new EndpointGroupBuilder()
         .setId(new EndpointGroupId("12802e21-8602-40ec-91d3-a75a296881ab"))
         .setConsumerNamedSelector(ImmutableList.of(cns1))
@@ -312,12 +312,12 @@ public class PolicyResolverTest {
         .build();
 
     PolicyResolver resolver;
-    
+
     @Before
     public void setup() throws Exception {
         resolver = new PolicyResolver(null, null);
     }
-    
+
     public void verifyMatches(List<ContractId> contrids,
                               List<TenantId> contrtids,
                               List<ContractMatch> matches) {
@@ -327,31 +327,31 @@ public class PolicyResolverTest {
         }
         assertEquals(contrids.size(), matches.size());
         for (ContractMatch m : matches) {
-            ContractMatchKey k = 
-                    new ContractMatchKey(m.contractTenant.getId(), 
+            ContractMatchKey k =
+                    new ContractMatchKey(m.contractTenant.getId(),
                                          m.contract.getId());
             assertTrue(v.contains(k));
         }
     }
-    
+
     @Test
     public void testContractSelection() throws Exception {
         // named selectors
         TenantContext tc = new TenantContext(null);
         Collection<TenantContext> tCol = Collections.singleton(tc);
-        
+
         tc.tenant.set(new IndexedTenant(tenant1));
         Table<EgKey, EgKey, List<ContractMatch>> contractMatches =
                 resolver.selectContracts(tCol);
         assertEquals(1, contractMatches.size());
-        List<ContractMatch> matches = 
+        List<ContractMatch> matches =
                 contractMatches.get(new EgKey(tenant1.getId(), eg1.getId()),
                                     new EgKey(tenant1.getId(), eg2.getId()));
         verifyMatches(ImmutableList.of(contract1.getId()),
                       ImmutableList.of(tenant1.getId()),
                       matches);
 
-        
+
         tc.tenant.set(new IndexedTenant(tenant2));
         contractMatches = resolver.selectContracts(tCol);
         assertEquals(2, contractMatches.size());
@@ -360,13 +360,13 @@ public class PolicyResolverTest {
         verifyMatches(ImmutableList.of(contract1.getId()),
                       ImmutableList.of(tenant2.getId()),
                       matches);
-        
+
         matches = contractMatches.get(new EgKey(tenant2.getId(), eg3.getId()),
                                       new EgKey(tenant2.getId(), eg2.getId()));
         verifyMatches(ImmutableList.of(contract2.getId(), contract1.getId()),
                       ImmutableList.of(tenant2.getId(), tenant2.getId()),
                       matches);
-        
+
         // target selectors
         tc.tenant.set(new IndexedTenant(tenant3));
         contractMatches = resolver.selectContracts(tCol);
@@ -376,7 +376,7 @@ public class PolicyResolverTest {
         verifyMatches(ImmutableList.of(contract2.getId()),
                       ImmutableList.of(tenant3.getId()),
                       matches);
-        
+
         // empty matches
         tc.tenant.set(new IndexedTenant(tenant0));
         contractMatches = resolver.selectContracts(tCol);
@@ -389,24 +389,23 @@ public class PolicyResolverTest {
 
     @Test
     public void testSubjectSelection() throws Exception {
-        ConditionSet cs = 
-                new ConditionSet(ImmutableSet.of(cond1.getName()), 
+        ConditionSet cs =
+                new ConditionSet(ImmutableSet.of(cond1.getName()),
                                  ImmutableSet.of(cond3.getName()),
-                                 ImmutableSet.of(ImmutableSet.of(cond1.getName(), 
+                                 ImmutableSet.of(ImmutableSet.of(cond1.getName(),
                                                                  cond2.getName())));
         TenantContext tc = new TenantContext(null);
         Collection<TenantContext> tCol = Collections.singleton(tc);
-        
+
         tc.tenant.set(new IndexedTenant(tenant1));
         Table<EgKey, EgKey, List<ContractMatch>> contractMatches =
                 resolver.selectContracts(tCol);
         Map<EgKey, Set<ConditionSet>> egConditions = new HashMap<>();
-        Table<EgKey, EgKey, Policy> policy = 
+        Table<EgKey, EgKey, Policy> policy =
                 resolver.selectSubjects(contractMatches, egConditions);
         assertEquals(1, policy.size());
-        Policy p = policy.get(new EgKey(tenant1.getId(), eg2.getId()),
-                              new EgKey(tenant1.getId(), eg1.getId()));
-        List<RuleGroup> rules = p.ruleMap.get(ConditionSet.EMPTY, cs);
+        Policy p = policy.get(new EgKey(tenant1.getId(), eg1.getId()), new EgKey(tenant1.getId(), eg2.getId()));
+        List<RuleGroup> rules = p.getRuleMap().get(cs, ConditionSet.EMPTY);
         assertNotNull(rules);
         assertEquals(1, rules.size());
         RuleGroup rg = rules.get(0);
@@ -422,9 +421,9 @@ public class PolicyResolverTest {
         policy = resolver.selectSubjects(contractMatches, egConditions);
 
         assertEquals(2, policy.size());
-        p = policy.get(new EgKey(tenant2.getId(), eg2.getId()),
-                       new EgKey(tenant2.getId(), eg3.getId()));
-        rules = p.ruleMap.get(ConditionSet.EMPTY, cs);
+        p = policy.get(new EgKey(tenant2.getId(), eg3.getId()),
+                       new EgKey(tenant2.getId(), eg2.getId()));
+        rules = p.getRuleMap().get(cs, ConditionSet.EMPTY);
         assertNotNull(rules);
         assertEquals(1, rules.size());
         rg = rules.get(0);
@@ -434,7 +433,7 @@ public class PolicyResolverTest {
         assertEquals(1, rg.rules.size());
         assertEquals(rule1.getName(), rg.rules.get(0).getName());
 
-        rules = p.ruleMap.get(ConditionSet.EMPTY, ConditionSet.EMPTY);
+        rules = p.getRuleMap().get(ConditionSet.EMPTY, ConditionSet.EMPTY);
         assertNotNull(rules);
         assertEquals(1, rules.size());
         rg = rules.get(0);
@@ -443,10 +442,10 @@ public class PolicyResolverTest {
         assertEquals(s2.getName(), rg.relatedSubject);
         assertEquals(1, rg.rules.size());
         assertEquals(rule2.getName(), rg.rules.get(0).getName());
-        
-        p = policy.get(new EgKey(tenant2.getId(), eg2.getId()),
-                       new EgKey(tenant2.getId(), eg1.getId()));
-        rules = p.ruleMap.get(ConditionSet.EMPTY, cs);
+
+        p = policy.get(new EgKey(tenant2.getId(), eg1.getId()),
+                       new EgKey(tenant2.getId(), eg2.getId()));
+        rules = p.getRuleMap().get(cs, ConditionSet.EMPTY);
         assertNotNull(rules);
         assertEquals(1, rules.size());
         rg = rules.get(0);
@@ -462,9 +461,9 @@ public class PolicyResolverTest {
         policy = resolver.selectSubjects(contractMatches, egConditions);
 
         assertEquals(1, policy.size());
-        p = policy.get(new EgKey(tenant3.getId(), eg5.getId()),
-                       new EgKey(tenant3.getId(), eg4.getId()));
-        rules = p.ruleMap.get(ConditionSet.EMPTY, ConditionSet.EMPTY);
+        p = policy.get(new EgKey(tenant3.getId(), eg4.getId()),
+                       new EgKey(tenant3.getId(), eg5.getId()));
+        rules = p.getRuleMap().get(ConditionSet.EMPTY, ConditionSet.EMPTY);
         assertNotNull(rules);
         assertEquals(1, rules.size());
         rg = rules.get(0);
index d68d196a83e2f90d5e7d7cd44ed918d1ea4adf41..d895c4a2e2c6801f97d8ebb3c289c50a646588cc 100644 (file)
@@ -129,18 +129,22 @@ public class PolicyEnforcer extends FlowTable {
                         conds = ctx.getEndpointManager().getCondsForEndpoint(dstEp);
                         ConditionGroup dcg = policyInfo.getEgCondGroup(dstEpgKey, conds);
 
+                        Policy policy = policyInfo.getPolicy(dstEpgKey, srcEpgKey);
+                        List<RuleGroup> rgs = policy.getRules(dcg, scg);
                         CgPair p = new CgPair(depgId, sepgId, dcgId, scgId);
                         if (visitedPairs.contains(p))
                             continue;
                         visitedPairs.add(p);
-                        syncPolicy(flowMap, nodeId, policyInfo, p, dstEpgKey, srcEpgKey, dcg, scg);
+                        syncPolicy(flowMap, nodeId, rgs, p);
 
                         // Reverse
+                        policy = policyInfo.getPolicy(srcEpgKey, dstEpgKey);
+                        rgs = policy.getRules(scg, dcg);
                         p = new CgPair(sepgId, depgId, scgId, dcgId);
                         if (visitedPairs.contains(p))
                             continue;
                         visitedPairs.add(p);
-                        syncPolicy(flowMap, nodeId, policyInfo, p, srcEpgKey, dstEpgKey, scg, dcg);
+                        syncPolicy(flowMap, nodeId, rgs, p);
                     }
                 }
             }
@@ -232,13 +236,7 @@ public class PolicyEnforcer extends FlowTable {
 
     }
 
-    private void syncPolicy(FlowMap flowMap, NodeId nodeId, PolicyInfo policyInfo, CgPair p, EgKey sepg, EgKey depg,
-            ConditionGroup scg, ConditionGroup dcg) throws Exception {
-        // XXX - TODO raise an exception for rules between the same
-        // endpoint group that are asymmetric
-        Policy policy = policyInfo.getPolicy(sepg, depg);
-        List<RuleGroup> rgs = policy.getRules(scg, dcg);
-
+    private void syncPolicy(FlowMap flowMap, NodeId nodeId, List<RuleGroup> rgs, CgPair p) {
         int priority = 65000;
         for (RuleGroup rg : rgs) {
             TenantId tenantId = rg.getContractTenant().getId();