[SDFAB-15] Allow delete with empty actions

Allow delete of flowrules with empty actions by using the stored flowentry attributes
to rebuild the original entry. This is possible as eveything in the flowrules store
is based on the flow id which is an hash of the match keys.

Improve the FabricUpfProgrammable by leveraging the improvements done
in the flowrule store. In particular, it removes the linear scan used
to find the original flowrule which is no longer necessary

Change-Id: I03a6efcdd4e70a7d55cb0757befd0f9b450ab718
diff --git a/core/store/dist/src/main/java/org/onosproject/store/flow/impl/ECFlowRuleStore.java b/core/store/dist/src/main/java/org/onosproject/store/flow/impl/ECFlowRuleStore.java
index 354b494..0a96252 100644
--- a/core/store/dist/src/main/java/org/onosproject/store/flow/impl/ECFlowRuleStore.java
+++ b/core/store/dist/src/main/java/org/onosproject/store/flow/impl/ECFlowRuleStore.java
@@ -54,6 +54,7 @@
 import org.onosproject.net.device.DeviceService;
 import org.onosproject.net.flow.CompletedBatchOperation;
 import org.onosproject.net.flow.DefaultFlowEntry;
+import org.onosproject.net.flow.DefaultFlowRule;
 import org.onosproject.net.flow.FlowEntry;
 import org.onosproject.net.flow.FlowEntry.FlowEntryState;
 import org.onosproject.net.flow.FlowRule;
@@ -518,7 +519,9 @@
                         return flowTable.update(op.target(), stored -> {
                             stored.setState(FlowEntryState.PENDING_REMOVE);
                             log.debug("Setting state of rule to pending remove: {}", stored);
-                            return op;
+                            // Using the stored value instead of op to allow the removal
+                            // of flows that do not specify actions or have empty treatment
+                            return new FlowRuleBatchEntry(op.operator(), new DefaultFlowRule(stored));
                         });
                     default:
                         log.warn("Unknown flow operation operator: {}", op.operator());