Remove NextId from internal stores when the NextObj fails

Change-Id: I105d32ea3a2278254edd8746d41552c2c4a699fa
diff --git a/app/src/main/java/org/onosproject/segmentrouting/grouphandler/DefaultGroupHandler.java b/app/src/main/java/org/onosproject/segmentrouting/grouphandler/DefaultGroupHandler.java
index 3fe934c..1ffd8e8 100644
--- a/app/src/main/java/org/onosproject/segmentrouting/grouphandler/DefaultGroupHandler.java
+++ b/app/src/main/java/org/onosproject/segmentrouting/grouphandler/DefaultGroupHandler.java
@@ -388,10 +388,11 @@
         ObjectiveContext context = new DefaultObjectiveContext(
                 (objective) -> log.debug("addToHash port/label {} addedTo "
                         + "NextObj {} on {}", portLabels, nextId, deviceId),
-                (objective, error) ->
-                        log.warn("addToHash failed to add port/label {} to"
-                                + " NextObj {} on {}: {}", portLabels,
-                                 nextId, deviceId, error));
+                (objective, error) -> {
+                    log.warn("addToHash failed to add port/label {} to NextObj {} on {}: {}",
+                            portLabels, nextId, deviceId, error);
+                    srManager.invalidateNextObj(objective.id());
+                });
         NextObjective nextObjective = nextObjBuilder.addToExisting(context);
         flowObjectiveService.next(deviceId, nextObjective);
     }
@@ -435,9 +436,11 @@
         ObjectiveContext context = new DefaultObjectiveContext(
                 (objective) -> log.debug("port/label {} removedFrom NextObj"
                         + " {} on {}", portLabels, nextId, deviceId),
-                (objective, error) ->
-                log.warn("port/label {} failed to removeFrom NextObj {} on "
-                        + "{}: {}", portLabels, nextId, deviceId, error));
+                (objective, error) -> {
+                    log.warn("port/label {} failed to removeFrom NextObj {} on {}: {}",
+                            portLabels, nextId, deviceId, error);
+                    srManager.invalidateNextObj(objective.id());
+                });
         NextObjective nextObjective = nextObjBuilder.removeFromExisting(context);
         flowObjectiveService.next(deviceId, nextObjective);
     }
@@ -718,10 +721,11 @@
             (objective) -> log.debug("port {} successfully {} NextObj {} on {}",
                                      port, (portUp) ? "addedTo" : "removedFrom",
                                      nextId, deviceId),
-            (objective, error) ->
-            log.warn("port {} failed to {} NextObj {} on {}: {}",
-                     port, (portUp) ? "addTo" : "removeFrom",
-                     nextId, deviceId, error));
+            (objective, error) -> {
+                log.warn("port {} failed to {} NextObj {} on {}: {}",
+                        port, (portUp) ? "addTo" : "removeFrom", nextId, deviceId, error);
+                srManager.invalidateNextObj(objective.id());
+            });
 
         NextObjective nextObj = (portUp) ? nextObjBuilder.addToExisting(context)
                                          : nextObjBuilder.removeFromExisting(context);
@@ -1029,10 +1033,11 @@
                 (objective) ->
                 log.debug("createGroupsFromDestinationSet installed "
                         + "NextObj {} on {}", nextId, deviceId),
-                (objective, error) ->
-                log.warn("createGroupsFromDestinationSet failed to install"
-                        + " NextObj {} on {}: {}", nextId, deviceId, error)
-                );
+                (objective, error) -> {
+                    log.warn("createGroupsFromDestinationSet failed to install NextObj {} on {}: {}",
+                            nextId, deviceId, error);
+                    srManager.invalidateNextObj(objective.id());
+                });
         NextObjective nextObj = nextObjBuilder.add(context);
         log.debug(".. createGroupsFromDestinationSet: Submitted "
                 + "next objective {} in device {}", nextId, deviceId);
@@ -1090,10 +1095,11 @@
             (objective) ->
                 log.debug("createBroadcastGroupFromVlan installed "
                         + "NextObj {} on {}", nextId, deviceId),
-            (objective, error) ->
-                log.warn("createBroadcastGroupFromVlan failed to install"
-                        + " NextObj {} on {}: {}", nextId, deviceId, error)
-            );
+            (objective, error) -> {
+                log.warn("createBroadcastGroupFromVlan failed to install NextObj {} on {}: {}",
+                        nextId, deviceId, error);
+                srManager.invalidateNextObj(objective.id());
+            });
         NextObjective nextObj = nextObjBuilder.add(context);
         flowObjectiveService.next(deviceId, nextObj);
         log.debug("createBcastGroupFromVlan: Submitted next objective {} "
@@ -1141,10 +1147,11 @@
                 (objective) ->
                         log.debug("removeBroadcastGroupFromVlan removed "
                                           + "NextObj {} on {}", nextId, deviceId),
-                (objective, error) ->
-                        log.warn("removeBroadcastGroupFromVlan failed to remove "
-                                         + " NextObj {} on {}: {}", nextId, deviceId, error)
-        );
+                (objective, error) -> {
+                    log.warn("removeBroadcastGroupFromVlan failed to remove NextObj {} on {}: {}",
+                            nextId, deviceId, error);
+                    srManager.invalidateNextObj(objective.id());
+                });
         NextObjective nextObj = nextObjBuilder.remove(context);
         flowObjectiveService.next(deviceId, nextObj);
         log.debug("removeBcastGroupFromVlan: Submited next objective {} in device {}",
@@ -1191,10 +1198,10 @@
             (objective) ->
                 log.debug("createGroupFromPort installed "
                         + "NextObj {} on {}", nextId, deviceId),
-            (objective, error) ->
-                log.warn("createGroupFromPort failed to install"
-                        + " NextObj {} on {}: {}", nextId, deviceId, error)
-            );
+            (objective, error) -> {
+                log.warn("createGroupFromPort failed to install NextObj {} on {}: {}", nextId, deviceId, error);
+                srManager.invalidateNextObj(objective.id());
+            });
         NextObjective nextObj = nextObjBuilder.add(context);
         flowObjectiveService.next(deviceId, nextObj);
         log.debug("createGroupFromPort: Submited next objective {} in device {} "
@@ -1233,9 +1240,11 @@
             ObjectiveContext context = new DefaultObjectiveContext(
                     (objective) -> log.debug("removePortNextObjective removes NextObj {} on {}",
                                              portNextObjId, deviceId),
-                    (objective, error) ->
-                            log.warn("removePortNextObjective failed to remove NextObj {} on {}: {}",
-                                     portNextObjId, deviceId, error));
+                    (objective, error) -> {
+                        log.warn("removePortNextObjective failed to remove NextObj {} on {}: {}",
+                                portNextObjId, deviceId, error);
+                        srManager.invalidateNextObj(objective.id());
+                    });
             NextObjective nextObjective = nextObjBuilder.remove(context);
             log.info("**removePortNextObjective: Submitted "
                              + "next objective {} in device {}",
@@ -1266,9 +1275,10 @@
             ObjectiveContext context = new DefaultObjectiveContext(
                     (objective) -> log.debug("RemoveGroup removes NextObj {} on {}",
                             objectiveId, deviceId),
-                    (objective, error) ->
-                            log.warn("RemoveGroup failed to remove NextObj {} on {}: {}",
-                                    objectiveId, deviceId, error));
+                    (objective, error) -> {
+                        log.warn("RemoveGroup failed to remove NextObj {} on {}: {}", objectiveId, deviceId, error);
+                        srManager.invalidateNextObj(objective.id());
+                    });
             NextObjective nextObjective = nextObjBuilder.remove(context);
             log.info("**removeGroup: Submited "
                     + "next objective {} in device {}",
@@ -1306,9 +1316,10 @@
                 (objective) ->
                         log.info("removeGroupFromPort installed "
                                           + "NextObj {} on {}", nextId, deviceId),
-                (objective, error) ->
-                        log.warn("removeGroupFromPort failed to install"
-                                         + " NextObj {} on {}: {}", nextId, deviceId, error)
+                (objective, error) -> {
+                    log.warn("removeGroupFromPort failed to install NextObj {} on {}: {}", nextId, deviceId, error);
+                    srManager.invalidateNextObj(objective.id());
+                }
         );
         NextObjective nextObj = nextObjBuilder.remove(context);
         flowObjectiveService.next(deviceId, nextObj);
@@ -1379,9 +1390,10 @@
         ObjectiveContext context = new DefaultObjectiveContext(
                 (objective) -> log.debug("port {} successfully updated NextObj {} on {}",
                                          portNumber, nextId, deviceId),
-                (objective, error) ->
-                        log.warn("port {} failed to updated NextObj {} on {}: {}",
-                                 portNumber, nextId, deviceId, error));
+                (objective, error) -> {
+                    log.warn("port {} failed to updated NextObj {} on {}: {}", portNumber, nextId, deviceId, error);
+                    srManager.invalidateNextObj(objective.id());
+                });
 
         flowObjectiveService.next(deviceId, nextObjBuilder.modify(context));
     }
@@ -1413,9 +1425,10 @@
         ObjectiveContext context = new DefaultObjectiveContext(
                 (objective) -> log.debug("port {} successfully removedFrom NextObj {} on {}",
                                          portNum, nextId, deviceId),
-                (objective, error) ->
-                        log.warn("port {} failed to removedFrom NextObj {} on {}: {}",
-                                 portNum, nextId, deviceId, error));
+                (objective, error) -> {
+                    log.warn("port {} failed to removedFrom NextObj {} on {}: {}", portNum, nextId, deviceId, error);
+                    srManager.invalidateNextObj(objective.id());
+                });
 
         if (install) {
             flowObjectiveService.next(deviceId, nextObjBuilder.addToExisting(context));
diff --git a/app/src/main/java/org/onosproject/segmentrouting/mcast/McastHandler.java b/app/src/main/java/org/onosproject/segmentrouting/mcast/McastHandler.java
index 4f70a1b..f359998 100644
--- a/app/src/main/java/org/onosproject/segmentrouting/mcast/McastHandler.java
+++ b/app/src/main/java/org/onosproject/segmentrouting/mcast/McastHandler.java
@@ -1175,8 +1175,11 @@
         ObjectiveContext context = new DefaultObjectiveContext(
                 (objective) -> log.debug("Successfully add {} on {}/{}, vlan {}",
                         mcastIp, deviceId, port.toLong(), assignedVlan),
-                (objective, error) -> log.warn("Failed to add {} on {}/{}, vlan {}: {}",
-                                mcastIp, deviceId, port.toLong(), assignedVlan, error));
+                (objective, error) -> {
+                    log.warn("Failed to add {} on {}/{}, vlan {}: {}",
+                            mcastIp, deviceId, port.toLong(), assignedVlan, error);
+                    srManager.invalidateNextObj(objective.id());
+                });
         ForwardingObjective fwdObj = mcastUtils.fwdObjBuilder(mcastIp, assignedVlan,
                                                               newNextObj.id()).add(context);
         srManager.flowObjectiveService.next(deviceId, newNextObj);
@@ -1231,8 +1234,11 @@
             context = new DefaultObjectiveContext(
                     (objective) -> log.debug("Successfully update {} on {}/{}, vlan {}",
                             mcastIp, deviceId, port.toLong(), assignedVlan),
-                    (objective, error) -> log.warn("Failed to update {} on {}/{}, vlan {}: {}",
-                                    mcastIp, deviceId, port.toLong(), assignedVlan, error));
+                    (objective, error) -> {
+                        log.warn("Failed to update {} on {}/{}, vlan {}: {}",
+                                mcastIp, deviceId, port.toLong(), assignedVlan, error);
+                        srManager.invalidateNextObj(objective.id());
+                    });
             // Here we store the next objective with the remaining port
             newNextObj = mcastUtils.nextObjBuilder(mcastIp, assignedVlan,
                                         existingPorts, nextObj.id()).removeFromExisting();
diff --git a/app/src/main/java/org/onosproject/segmentrouting/pwaas/DefaultL2TunnelHandler.java b/app/src/main/java/org/onosproject/segmentrouting/pwaas/DefaultL2TunnelHandler.java
index 21a8761..fe65e6e 100644
--- a/app/src/main/java/org/onosproject/segmentrouting/pwaas/DefaultL2TunnelHandler.java
+++ b/app/src/main/java/org/onosproject/segmentrouting/pwaas/DefaultL2TunnelHandler.java
@@ -931,14 +931,12 @@
         nextObjectiveBuilder.withId(nextId);
         String key = generateKey(l2Tunnel.tunnelId(), direction);
         l2InitiationNextObjStore.put(key, nextObjectiveBuilder.add());
-        ObjectiveContext context = new DefaultObjectiveContext((objective) ->
-                                                                 log.debug("Initiation l2 tunnel rule " +
-                                                                                   "for {} populated",
-                                                                           l2Tunnel.tunnelId()),
-                                                               (objective, error) ->
-                                                                       log.warn("Failed to populate Initiation " +
-                                                                                        "l2 tunnel rule for {}: {}",
-                                                                                l2Tunnel.tunnelId(), error));
+        ObjectiveContext context = new DefaultObjectiveContext(
+                (objective) -> log.debug("Initiation l2 tunnel rule for {} populated", l2Tunnel.tunnelId()),
+                (objective, error) -> {
+                    log.warn("Failed to populate Initiation l2 tunnel rule for {}: {}", l2Tunnel.tunnelId(), error);
+                    srManager.invalidateNextObj(objective.id());
+                });
         NextObjective nextObjective = nextObjectiveBuilder.add(context);
         srManager.flowObjectiveService.next(ingress.deviceId(), nextObjective);
         log.debug("Initiation next objective for {} not found. Creating new NextObj with id={}",
@@ -985,14 +983,12 @@
         nextObjectiveBuilder.withId(nextId);
         String key = generateKey(l2Tunnel.tunnelId(), direction);
         l2TerminationNextObjStore.put(key, nextObjectiveBuilder.add());
-        ObjectiveContext context = new DefaultObjectiveContext((objective) -> log.debug("Termination l2 tunnel rule " +
-                                                                                        "for {} populated",
-                                                                                        l2Tunnel.tunnelId()),
-                                                               (objective, error) -> log.warn("Failed to populate " +
-                                                                                              "termination l2 tunnel " +
-                                                                                              "rule for {}: {}",
-                                                                                              l2Tunnel.tunnelId(),
-                                                                                              error));
+        ObjectiveContext context = new DefaultObjectiveContext(
+                (objective) -> log.debug("Termination l2 tunnel rule for {} populated", l2Tunnel.tunnelId()),
+                (objective, error) -> {
+                    log.warn("Failed to populate termination l2 tunnel rule for {}: {}", l2Tunnel.tunnelId(), error);
+                    srManager.invalidateNextObj(objective.id());
+                });
         NextObjective nextObjective = nextObjectiveBuilder.add(context);
         srManager.flowObjectiveService.next(egress.deviceId(), nextObjective);
         log.debug("Termination next objective for {} not found. Creating new NextObj with id={}",
diff --git a/app/src/main/java/org/onosproject/segmentrouting/xconnect/impl/XconnectManager.java b/app/src/main/java/org/onosproject/segmentrouting/xconnect/impl/XconnectManager.java
index ab4ec53..e571811 100644
--- a/app/src/main/java/org/onosproject/segmentrouting/xconnect/impl/XconnectManager.java
+++ b/app/src/main/java/org/onosproject/segmentrouting/xconnect/impl/XconnectManager.java
@@ -327,9 +327,10 @@
                     // To serialize this with kryo
                     (Serializable & Consumer<Objective>) (objective) ->
                             log.debug("XConnect NextObj for {} added", key),
-                    (Serializable & BiConsumer<Objective, ObjectiveError>) (objective, error) ->
-                            log.warn("Failed to add XConnect NextObj for {}: {}", key, error)
-            );
+                    (Serializable & BiConsumer<Objective, ObjectiveError>) (objective, error) -> {
+                        log.warn("Failed to add XConnect NextObj for {}: {}", key, error);
+                        srService.invalidateNextObj(objective.id());
+                    });
             nextObj = nextObjBuilder.add(nextContext);
             flowObjectiveService.next(key.deviceId(), nextObj);
             xconnectNextObjStore.put(key, nextObj);
@@ -434,10 +435,10 @@
                 if (nextFuture != null) {
                     nextFuture.complete(error);
                 }
+                srService.invalidateNextObj(objective.id());
             }
         };
-        flowObjectiveService.next(key.deviceId(),
-                (NextObjective) nextObj.copy().remove(context));
+        flowObjectiveService.next(key.deviceId(), nextObj.copy().remove(context));
         xconnectNextObjStore.remove(key);
     }