Synchronize Flow and Group Remove events 44/82444/9
authorGobinath <gobinath@ericsson.com>
Tue, 9 Apr 2019 06:23:10 +0000 (11:53 +0530)
committerArunprakash D <d.arunprakash@ericsson.com>
Mon, 4 Nov 2019 08:27:48 +0000 (08:27 +0000)
Description:
The flow and group remove events have to be synchronized too along with
the add/update events which are already synchronized.If the flow/group
remove events aren't synchronized, it could result in the stale flows
when there are multiple flow updates and deleted (like in case of
bulk evacuation)

Fix:
Used the existing nodeconfigurator framework to synchronize the remove
events too (with nodeId as key)

Change-Id: I9b386e5c8db2c35e721d539fa11558a292214ec0
Signed-off-by: Gobinath <gobinath@ericsson.com>
applications/forwardingrules-manager/src/main/java/org/opendaylight/openflowplugin/applications/frm/impl/BundleFlowForwarder.java
applications/forwardingrules-manager/src/main/java/org/opendaylight/openflowplugin/applications/frm/impl/FlowForwarder.java
applications/forwardingrules-manager/src/main/java/org/opendaylight/openflowplugin/applications/frm/impl/GroupForwarder.java

index 46d866d73d13b0e24bc2361b79ce83637813d8c3..ed0d25122593df7e469ff303c7cbb356f623acfd 100644 (file)
@@ -83,21 +83,25 @@ public class BundleFlowForwarder implements BundleMessagesCommiter<Flow> {
     @Override
     public void remove(final InstanceIdentifier<Flow> identifier, final Flow flow,
             final InstanceIdentifier<FlowCapableNode> nodeIdent, final BundleId bundleId) {
-        final List<Message> messages = new ArrayList<>(1);
-        String node = nodeIdent.firstKeyOf(Node.class).getId().getValue();
-        BundleInnerMessage bundleInnerMessage = new BundleRemoveFlowCaseBuilder()
+        final NodeId nodeId = getNodeIdFromNodeIdentifier(nodeIdent);
+        nodeConfigurator.enqueueJob(nodeId.getValue(), () -> {
+            final List<Message> messages = new ArrayList<>(1);
+            String node = nodeIdent.firstKeyOf(Node.class).getId().getValue();
+            BundleInnerMessage bundleInnerMessage = new BundleRemoveFlowCaseBuilder()
                 .setRemoveFlowCaseData(new RemoveFlowCaseDataBuilder(flow).build()).build();
-        Message message = new MessageBuilder().setNode(new NodeRef(nodeIdent.firstIdentifierOf(Node.class)))
+            Message message = new MessageBuilder().setNode(new NodeRef(nodeIdent.firstIdentifierOf(Node.class)))
                 .setBundleInnerMessage(bundleInnerMessage).build();
-        messages.add(message);
-        AddBundleMessagesInput addBundleMessagesInput = new AddBundleMessagesInputBuilder()
+            messages.add(message);
+            AddBundleMessagesInput addBundleMessagesInput = new AddBundleMessagesInputBuilder()
                 .setNode(new NodeRef(nodeIdent.firstIdentifierOf(Node.class))).setBundleId(bundleId)
                 .setFlags(BUNDLE_FLAGS).setMessages(new MessagesBuilder().setMessage(messages).build()).build();
-        final ListenableFuture<RpcResult<AddBundleMessagesOutput>> resultFuture = forwardingRulesManager
+            final ListenableFuture<RpcResult<AddBundleMessagesOutput>> resultFuture = forwardingRulesManager
                 .getSalBundleService().addBundleMessages(addBundleMessagesInput);
-        LOG.trace("Pushing flow remove message {} to bundle {} for device {}", addBundleMessagesInput,
+            LOG.trace("Pushing flow remove message {} to bundle {} for device {}", addBundleMessagesInput,
                 bundleId.getValue(), node);
-        LoggingFutures.addErrorLogging(resultFuture, LOG, "removeBundleFlow");
+            LoggingFutures.addErrorLogging(resultFuture, LOG, "removeBundleFlow");
+            return resultFuture;
+        });
     }
 
     @Override
index 689ffe48c045cf326ccb9f26976d56c171f3e914..b64fe2b79468628ea47d6fea442d7f5786c12d29 100644 (file)
@@ -128,18 +128,23 @@ public class FlowForwarder extends AbstractListeningCommiter<Flow> {
             if (bundleId != null) {
                 provider.getBundleFlowListener().remove(identifier, removeDataObj, nodeIdent, bundleId);
             } else {
-                final RemoveFlowInputBuilder builder = new RemoveFlowInputBuilder(removeDataObj);
-                builder.setFlowRef(new FlowRef(identifier));
-                builder.setNode(new NodeRef(nodeIdent.firstIdentifierOf(Node.class)));
-                builder.setFlowTable(new FlowTableRef(nodeIdent.child(Table.class, tableKey)));
-
-                // This method is called only when a given flow object has been
-                // removed from datastore. So FRM always needs to set strict flag
-                // into remove-flow input so that only a flow entry associated with
-                // a given flow object is removed.
-                builder.setTransactionUri(new Uri(provider.getNewTransactionId())).setStrict(Boolean.TRUE);
-                LoggingFutures.addErrorLogging(provider.getSalFlowService().removeFlow(builder.build()), LOG,
-                    "removeFlow");
+                final NodeId nodeId = getNodeIdFromNodeIdentifier(nodeIdent);
+                nodeConfigurator.enqueueJob(nodeId.getValue(), () -> {
+                    final RemoveFlowInputBuilder builder = new RemoveFlowInputBuilder(removeDataObj);
+                    builder.setFlowRef(new FlowRef(identifier));
+                    builder.setNode(new NodeRef(nodeIdent.firstIdentifierOf(Node.class)));
+                    builder.setFlowTable(new FlowTableRef(nodeIdent.child(Table.class, tableKey)));
+
+                    // This method is called only when a given flow object has been
+                    // removed from datastore. So FRM always needs to set strict flag
+                    // into remove-flow input so that only a flow entry associated with
+                    // a given flow object is removed.
+                    builder.setTransactionUri(new Uri(provider.getNewTransactionId())).setStrict(Boolean.TRUE);
+                    final ListenableFuture<RpcResult<RemoveFlowOutput>> resultFuture =
+                            provider.getSalFlowService().removeFlow(builder.build());
+                    LoggingFutures.addErrorLogging(resultFuture, LOG, "removeFlow");
+                    return resultFuture;
+                });
             }
         }
     }
index 3dd51cad18e23b6624ddec20807cedac6cd18a91..0d5848d80cac00eab6b4fbdba607ff95d49fdd6f 100644 (file)
@@ -109,20 +109,22 @@ public class GroupForwarder extends AbstractListeningCommiter<Group> {
         if (bundleId != null) {
             provider.getBundleGroupListener().remove(identifier, removeDataObj, nodeIdent, bundleId);
         } else {
-            final Group group = removeDataObj;
-            final RemoveGroupInputBuilder builder = new RemoveGroupInputBuilder(group);
             final NodeId nodeId = getNodeIdFromNodeIdentifier(nodeIdent);
+            nodeConfigurator.enqueueJob(nodeId.getValue(), () -> {
+                final Group group = removeDataObj;
+                final RemoveGroupInputBuilder builder = new RemoveGroupInputBuilder(group);
+                builder.setNode(new NodeRef(nodeIdent.firstIdentifierOf(Node.class)));
+                builder.setGroupRef(new GroupRef(identifier));
+                builder.setTransactionUri(new Uri(provider.getNewTransactionId()));
 
-            builder.setNode(new NodeRef(nodeIdent.firstIdentifierOf(Node.class)));
-            builder.setGroupRef(new GroupRef(identifier));
-            builder.setTransactionUri(new Uri(provider.getNewTransactionId()));
-
-            final ListenableFuture<RpcResult<RemoveGroupOutput>> resultFuture =
+                final ListenableFuture<RpcResult<RemoveGroupOutput>> resultFuture =
                     this.provider.getSalGroupService().removeGroup(builder.build());
-            Futures.addCallback(resultFuture,
+                Futures.addCallback(resultFuture,
                     new RemoveGroupCallBack(removeDataObj.getGroupId().getValue(), nodeId),
                     MoreExecutors.directExecutor());
-            LoggingFutures.addErrorLogging(resultFuture, LOG, "removeGroup");
+                LoggingFutures.addErrorLogging(resultFuture, LOG, "removeGroup");
+                return resultFuture;
+            });
         }
     }