Fix for flow equality bug which can cause:

 * multiple flows with the same match to be simultaneously present in the flow
   store, and
 * similar but different rule in switch and store, resulting in flows stuck in
   PENDING_ADD state.

Fixes ONOS-2426.

Ported from onos-1.2 branch.

Change-Id: I4b4e444c3a6dba7e4d3278e9469069e2dbdb9b67
diff --git a/core/net/src/main/java/org/onosproject/net/flow/impl/FlowRuleManager.java b/core/net/src/main/java/org/onosproject/net/flow/impl/FlowRuleManager.java
index b35002d..488d35c 100644
--- a/core/net/src/main/java/org/onosproject/net/flow/impl/FlowRuleManager.java
+++ b/core/net/src/main/java/org/onosproject/net/flow/impl/FlowRuleManager.java
@@ -387,12 +387,22 @@
 
         @Override
         public void pushFlowMetrics(DeviceId deviceId, Iterable<FlowEntry> flowEntries) {
-            Set<FlowEntry> storedRules = Sets.newHashSet(store.getFlowEntries(deviceId));
+            Map<FlowEntry, FlowEntry> storedRules = Maps.newHashMap();
+            store.getFlowEntries(deviceId).forEach(f -> storedRules.put(f, f));
+
             for (FlowEntry rule : flowEntries) {
                 try {
-                    if (storedRules.remove(rule)) {
-                        // we both have the rule, let's update some info then.
-                        flowAdded(rule);
+                    FlowEntry storedRule = storedRules.remove(rule);
+                    if (storedRule != null) {
+                        if (storedRule.exactMatch(rule)) {
+                            // we both have the rule, let's update some info then.
+                            flowAdded(rule);
+                        } else {
+                            // the two rules are not an exact match - remove the
+                            // switch's rule and install our rule
+                            extraneousFlow(rule);
+                            flowMissing(storedRule);
+                        }
                     } else {
                         // the device has a rule the store does not have
                         if (!allowExtraneousRules) {
@@ -404,7 +414,7 @@
                     continue;
                 }
             }
-            for (FlowEntry rule : storedRules) {
+            for (FlowEntry rule : storedRules.keySet()) {
                 try {
                     // there are rules in the store that aren't on the switch
                     log.debug("Adding rule in store, but not on switch {}", rule);