In this commit:
   Bug fix where filtering objectives are not installed due to available ports becoming enabled later.
   Bug fix where flow objective store had no listener for notifications from drivers across multiple instances of the controller.
   NPE fix in ofdpa driver for non-existing groups.
   Preventing ofdpa driver from sending spurious pass notification to app.
   Incrementing retry filter timer from 1 to 5 secs in default routing handler.
   Made several debug messages clearer.

Change-Id: I828671ee4c8bcfe03c946d051e1d1aac9d8f68dd
diff --git a/drivers/default/src/main/java/org/onosproject/driver/pipeline/Ofdpa2Pipeline.java b/drivers/default/src/main/java/org/onosproject/driver/pipeline/Ofdpa2Pipeline.java
index 6f42dbc..d1b285b 100644
--- a/drivers/default/src/main/java/org/onosproject/driver/pipeline/Ofdpa2Pipeline.java
+++ b/drivers/default/src/main/java/org/onosproject/driver/pipeline/Ofdpa2Pipeline.java
@@ -182,6 +182,12 @@
         FlowRuleOperations.Builder flowOpsBuilder = FlowRuleOperations.builder();
 
         rules = processForward(fwd);
+        if (rules == null || rules.isEmpty()) {
+            // Assumes fail message has already been generated to the objective
+            // context. Returning here prevents spurious pass message to be
+            // generated by FlowRule service for empty flowOps.
+            return;
+        }
         switch (fwd.op()) {
             case ADD:
                 rules.stream()
@@ -748,7 +754,7 @@
      *            returned if there is an issue in processing the objective.
      */
     protected Collection<FlowRule> processSpecific(ForwardingObjective fwd) {
-        log.trace("Processing specific fwd objective:{} in dev:{} with next:{}",
+        log.debug("Processing specific fwd objective:{} in dev:{} with next:{}",
                   fwd.id(), deviceId, fwd.nextId());
         boolean isEthTypeObj = isSupportedEthTypeObjective(fwd);
         boolean isEthDstObj = isSupportedEthDstObjective(fwd);
@@ -885,8 +891,8 @@
         if (fwd.nextId() != null) {
             if (forTableId == MPLS_TABLE_1 && !popMpls) {
                 log.warn("SR CONTINUE case cannot be handled as MPLS ECMP "
-                        + "is not implemented in OF-DPA yet. Aborting this flow "
-                        + "in this device {}", deviceId);
+                        + "is not implemented in OF-DPA yet. Aborting this flow {} -> next:{}"
+                        + "in this device {}", fwd.id(), fwd.nextId(), deviceId);
                 // XXX We could convert to forwarding to a single-port, via a
                 // MPLS interface, or a MPLS SWAP (with-same) but that would
                 // have to be handled in the next-objective. Also the pop-mpls
@@ -907,6 +913,11 @@
                     return Collections.emptySet();
                 }
                 tb.deferred().group(group.id());
+            } else {
+                log.warn("Cannot find group for nextId:{} in dev:{}. Aborting fwd:{}",
+                         fwd.nextId(), deviceId, fwd.id());
+                fail(fwd, ObjectiveError.FLOWINSTALLATIONFAILED);
+                return Collections.emptySet();
             }
         }
         tb.transition(ACL_TABLE);
@@ -1063,7 +1074,7 @@
             for (GroupKey gk : gkd) {
                 Group g = groupService.getGroup(deviceId, gk);
                 if (g == null) {
-                    gchain.append("  ERROR").append(" -->");
+                    gchain.append("  NoGrp").append(" -->");
                     continue;
                 }
                 gchain.append("  0x").append(Integer.toHexString(g.id().id()))
@@ -1071,7 +1082,12 @@
                 lastGroup = g;
             }
             // add port information for last group in group-chain
-            for (Instruction i: lastGroup.buckets().buckets().get(0).treatment().allInstructions()) {
+            List<Instruction> lastGroupIns = new ArrayList<Instruction>();
+            if (gchain != null) {
+                lastGroupIns = lastGroup.buckets().buckets().get(0)
+                                    .treatment().allInstructions();
+            }
+            for (Instruction i: lastGroupIns) {
                 if (i instanceof OutputInstruction) {
                     gchain.append(" port:").append(((OutputInstruction) i).port());
                 }