BUG 7414: Tunnel pushed to wrong OVS 80/49680/3
authorVishal Thapar <vishal.thapar@ericsson.com>
Wed, 21 Dec 2016 05:49:12 +0000 (11:19 +0530)
committerVishal Thapar <vishal.thapar@ericsson.com>
Wed, 21 Dec 2016 13:26:23 +0000 (18:56 +0530)
If we get DTCN with modiications on multiple nodes, we're processing the
changes as if they were recieved on all nodes. updateData() gets client
for each node in change, but instead of passing on the changes that are
made only on that node, it passes it all the changes including ones on
other nodes/clients.

Fix is to have a map of changes per client and only transact this subset
to the client.

Change-Id: Ie03176b470b120eba76478c8c12e44d831329953
Signed-off-by: Vishal Thapar <vishal.thapar@ericsson.com>
southbound/southbound-impl/src/main/java/org/opendaylight/ovsdb/southbound/OvsdbDataTreeChangeListener.java

index 8efe3d41b2b813858e5c1041fc8b73141a8e2a98..dfe6261c2280bc94670d1dd74838762922d9447b 100644 (file)
@@ -10,6 +10,7 @@ package org.opendaylight.ovsdb.southbound;
 
 import java.net.ConnectException;
 import java.net.UnknownHostException;
+import java.util.ArrayList;
 import java.util.Collection;
 import java.util.HashMap;
 import java.util.Map;
@@ -181,18 +182,18 @@ public class OvsdbDataTreeChangeListener implements ClusteredDataTreeChangeListe
     }
 
     private void updateData(@Nonnull Collection<DataTreeModification<Node>> changes) {
-        for (Entry<InstanceIdentifier<Node>, OvsdbConnectionInstance> connectionInstanceEntry :
-                connectionInstancesFromChanges(changes).entrySet()) {
-            OvsdbConnectionInstance connectionInstance = connectionInstanceEntry.getValue();
+        for (Entry<OvsdbConnectionInstance, Collection<DataTreeModification<Node>>> connectionInstanceEntry :
+                changesPerConnectionInstance(changes).entrySet()) {
+            OvsdbConnectionInstance connectionInstance = connectionInstanceEntry.getKey();
+            Collection<DataTreeModification<Node>> clientChanges = connectionInstanceEntry.getValue();
             connectionInstance.transact(new TransactCommandAggregator(),
-                    new BridgeOperationalState(db, changes), changes, instanceIdentifierCodec);
+                    new BridgeOperationalState(db, clientChanges), clientChanges, instanceIdentifierCodec);
         }
     }
 
-    private Map<InstanceIdentifier<Node>, OvsdbConnectionInstance> connectionInstancesFromChanges(
+    private Map<OvsdbConnectionInstance, Collection<DataTreeModification<Node>>> changesPerConnectionInstance(
             @Nonnull Collection<DataTreeModification<Node>> changes) {
-        Map<InstanceIdentifier<Node>,OvsdbConnectionInstance> result =
-                new HashMap<>();
+        Map<OvsdbConnectionInstance, Collection<DataTreeModification<Node>>> result = new HashMap<>();
         for (DataTreeModification<Node> change : changes) {
             OvsdbConnectionInstance client = null;
             Node node = change.getRootNode().getDataAfter() != null
@@ -240,7 +241,7 @@ public class OvsdbDataTreeChangeListener implements ClusteredDataTreeChangeListe
                      */
                 if ( cm.getHasDeviceOwnership(client.getMDConnectionInfo())) {
                     LOG.debug("*This* instance of southbound plugin is an owner of the device {}", node);
-                    result.put(change.getRootPath().getRootIdentifier(), client);
+                    result.computeIfAbsent(client, key -> new ArrayList<>()).add(change);
                 } else {
                     LOG.debug("*This* instance of southbound plugin is *not* an owner of the device {}", node);
                 }
@@ -248,6 +249,7 @@ public class OvsdbDataTreeChangeListener implements ClusteredDataTreeChangeListe
                 LOG.debug("Did not find client for {}", node);
             }
         }
+
         return result;
     }
 }