ONOS-1951: Segment Routing multi-instance instability: Plugging Objective context to monitor any errors

Change-Id: Ic710a756b7fec411a52a356409639c3f96c3129d
diff --git a/src/main/java/org/onosproject/segmentrouting/RoutingRulePopulator.java b/src/main/java/org/onosproject/segmentrouting/RoutingRulePopulator.java
index 8c84e39..59fc4ca 100644
--- a/src/main/java/org/onosproject/segmentrouting/RoutingRulePopulator.java
+++ b/src/main/java/org/onosproject/segmentrouting/RoutingRulePopulator.java
@@ -35,7 +35,10 @@
 import org.onosproject.net.flowobjective.DefaultForwardingObjective;
 import org.onosproject.net.flowobjective.FilteringObjective;
 import org.onosproject.net.flowobjective.ForwardingObjective;
+import org.onosproject.net.flowobjective.Objective;
+import org.onosproject.net.flowobjective.ObjectiveError;
 import org.onosproject.net.flowobjective.ForwardingObjective.Builder;
+import org.onosproject.net.flowobjective.ObjectiveContext;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -113,7 +116,11 @@
 
         log.debug("Installing IPv4 forwarding objective "
                 + "for host {} in switch {}", hostIp, deviceId);
-        srManager.flowObjectiveService.forward(deviceId, fwdBuilder.add());
+        srManager.flowObjectiveService.
+            forward(deviceId,
+                    fwdBuilder.
+                    add(new SRObjectiveContext(deviceId,
+                                           SRObjectiveContext.ObjectiveType.FORWARDING)));
         rulePopulationCounter.incrementAndGet();
     }
 
@@ -192,7 +199,11 @@
                         + "for router IP/subnet {} in switch {}",
                 ipPrefix,
                 deviceId);
-        srManager.flowObjectiveService.forward(deviceId, fwdBuilder.add());
+        srManager.flowObjectiveService.
+            forward(deviceId,
+                    fwdBuilder.
+                    add(new SRObjectiveContext(deviceId,
+                                               SRObjectiveContext.ObjectiveType.FORWARDING)));
         rulePopulationCounter.incrementAndGet();
 
         return true;
@@ -275,8 +286,11 @@
                     .makePermanent()).withSelector(selector)
                     .withPriority(100))
                     .withFlag(ForwardingObjective.Flag.SPECIFIC);
-            srManager.flowObjectiveService.forward(deviceId,
-                                                   fwdObjBuilder.add());
+            srManager.flowObjectiveService.
+                forward(deviceId,
+                        fwdObjBuilder.
+                        add(new SRObjectiveContext(deviceId,
+                                                   SRObjectiveContext.ObjectiveType.FORWARDING)));
             rulePopulationCounter.incrementAndGet();
         }
 
@@ -346,7 +360,10 @@
                 .addCondition(Criteria.matchVlanId(VlanId.NONE));
         fob.permit().fromApp(srManager.appId);
         log.debug("populateTableVlan: Installing filtering objective for untagged packets");
-        srManager.flowObjectiveService.filter(deviceId, fob.add());
+        srManager.flowObjectiveService.
+            filter(deviceId,
+                   fob.add(new SRObjectiveContext(deviceId,
+                                                  SRObjectiveContext.ObjectiveType.FILTER)));
     }
 
     /**
@@ -363,7 +380,10 @@
                                       .getDeviceMac(deviceId)));
         fob.permit().fromApp(srManager.appId);
         log.debug("populateTableVlan: Installing filtering objective for router mac");
-        srManager.flowObjectiveService.filter(deviceId, fob.add());
+        srManager.flowObjectiveService.
+            filter(deviceId,
+                   fob.add(new SRObjectiveContext(deviceId,
+                                                  SRObjectiveContext.ObjectiveType.FILTER)));
     }
 
     private PortNumber selectOnePort(DeviceId srcId, Set<DeviceId> destIds) {
@@ -382,4 +402,29 @@
         return null;
     }
 
+    private static class SRObjectiveContext implements ObjectiveContext {
+        enum ObjectiveType {
+            FILTER,
+            FORWARDING
+        }
+        final DeviceId deviceId;
+        final ObjectiveType type;
+
+        SRObjectiveContext(DeviceId deviceId, ObjectiveType type) {
+            this.deviceId = deviceId;
+            this.type = type;
+        }
+        @Override
+        public void onSuccess(Objective objective) {
+            log.debug("{} objective operation successful in device {}",
+                      type.name(), deviceId);
+        }
+
+        @Override
+        public void onError(Objective objective, ObjectiveError error) {
+            log.warn("{} objective {} operation failed with error: {} in device {}",
+                     type.name(), objective, error, deviceId);
+        }
+    }
+
 }
diff --git a/src/main/java/org/onosproject/segmentrouting/grouphandler/DefaultGroupHandler.java b/src/main/java/org/onosproject/segmentrouting/grouphandler/DefaultGroupHandler.java
index 7226fd8..a43a0f0 100644
--- a/src/main/java/org/onosproject/segmentrouting/grouphandler/DefaultGroupHandler.java
+++ b/src/main/java/org/onosproject/segmentrouting/grouphandler/DefaultGroupHandler.java
@@ -41,6 +41,9 @@
 import org.onosproject.net.flowobjective.DefaultNextObjective;
 import org.onosproject.net.flowobjective.FlowObjectiveService;
 import org.onosproject.net.flowobjective.NextObjective;
+import org.onosproject.net.flowobjective.Objective;
+import org.onosproject.net.flowobjective.ObjectiveContext;
+import org.onosproject.net.flowobjective.ObjectiveError;
 import org.onosproject.net.group.DefaultGroupKey;
 import org.onosproject.net.group.GroupKey;
 import org.onosproject.net.link.LinkService;
@@ -53,7 +56,7 @@
  * whether the current device is an edge device or a transit device.
  */
 public class DefaultGroupHandler {
-    protected final Logger log = getLogger(getClass());
+    protected static final Logger log = getLogger(DefaultGroupHandler.class);
 
     protected final DeviceId deviceId;
     protected final ApplicationId appId;
@@ -211,7 +214,8 @@
                         deviceId,
                         newLink.src().port(),
                         nextId);
-                NextObjective nextObjective = nextObjBuilder.add();
+                NextObjective nextObjective = nextObjBuilder.
+                        add(new SRNextObjectiveContext(deviceId));
                 flowObjectiveService.next(deviceId, nextObjective);
             }
         }
@@ -268,7 +272,8 @@
                         deviceId,
                         port,
                         nextId);
-                NextObjective nextObjective = nextObjBuilder.remove();
+                NextObjective nextObjective = nextObjBuilder.
+                        remove(new SRNextObjectiveContext(deviceId));
 
                 flowObjectiveService.next(deviceId, nextObjective);
             }
@@ -470,7 +475,8 @@
                 }
             }
 
-            NextObjective nextObj = nextObjBuilder.add();
+            NextObjective nextObj = nextObjBuilder.
+                    add(new SRNextObjectiveContext(deviceId));
             flowObjectiveService.next(deviceId, nextObj);
             log.debug("createGroupsFromNeighborsets: Submited "
                             + "next objective {} in device {}",
@@ -496,7 +502,8 @@
             NextObjective.Builder nextObjBuilder = DefaultNextObjective
                     .builder().withId(objectiveId)
                     .withType(NextObjective.Type.HASHED).fromApp(appId);
-            NextObjective nextObjective = nextObjBuilder.remove();
+            NextObjective nextObjective = nextObjBuilder.
+                    remove(new SRNextObjectiveContext(deviceId));
             flowObjectiveService.next(deviceId, nextObjective);
 
             for (Map.Entry<NeighborSetNextObjectiveStoreKey, Integer> entry: nsNextObjStore.entrySet()) {
@@ -510,4 +517,23 @@
 
         return false;
     }
+
+    protected static class SRNextObjectiveContext implements ObjectiveContext {
+        final DeviceId deviceId;
+
+        SRNextObjectiveContext(DeviceId deviceId) {
+            this.deviceId = deviceId;
+        }
+        @Override
+        public void onSuccess(Objective objective) {
+            log.debug("Next objective operation successful in device {}",
+                      deviceId);
+        }
+
+        @Override
+        public void onError(Objective objective, ObjectiveError error) {
+            log.warn("Next objective {} operation failed with error: {} in device {}",
+                     objective, error, deviceId);
+        }
+    }
 }