[SDFAB-359] Allow purging flows, groups and meters by device and application ID

Change-Id: I5e507d230789979ac997dbc99697fa0483363f70
(cherry picked from commit cfd774018c0ed926873b1e171c106217cb2ac568)
diff --git a/core/common/src/test/java/org/onosproject/store/trivial/SimpleFlowRuleStore.java b/core/common/src/test/java/org/onosproject/store/trivial/SimpleFlowRuleStore.java
index 31b58fb..3b667a8 100644
--- a/core/common/src/test/java/org/onosproject/store/trivial/SimpleFlowRuleStore.java
+++ b/core/common/src/test/java/org/onosproject/store/trivial/SimpleFlowRuleStore.java
@@ -25,6 +25,7 @@
 import com.google.common.collect.Streams;
 import com.google.common.util.concurrent.SettableFuture;
 import org.onlab.util.Tools;
+import org.onosproject.core.ApplicationId;
 import org.onosproject.net.DeviceId;
 import org.onosproject.net.flow.CompletedBatchOperation;
 import org.onosproject.net.flow.DefaultFlowEntry;
@@ -301,6 +302,16 @@
     }
 
     @Override
+    public boolean purgeFlowRules(DeviceId deviceId, ApplicationId appId) {
+        flowEntries.get(deviceId).values()
+                .removeIf(storedFlowEntries -> {
+                    storedFlowEntries.removeIf(storedFlowEntry -> storedFlowEntry.appId() == appId.id());
+                    return storedFlowEntries.isEmpty();
+                });
+        return true;
+    }
+
+    @Override
     public void purgeFlowRules() {
         flowEntries.clear();
     }
diff --git a/core/common/src/test/java/org/onosproject/store/trivial/SimpleGroupStore.java b/core/common/src/test/java/org/onosproject/store/trivial/SimpleGroupStore.java
index bf8ba59..8ece648 100644
--- a/core/common/src/test/java/org/onosproject/store/trivial/SimpleGroupStore.java
+++ b/core/common/src/test/java/org/onosproject/store/trivial/SimpleGroupStore.java
@@ -17,6 +17,7 @@
 
 import com.google.common.collect.FluentIterable;
 import com.google.common.collect.Sets;
+import org.onosproject.core.ApplicationId;
 import org.onosproject.core.GroupId;
 import org.onosproject.net.DeviceId;
 import org.onosproject.net.group.DefaultGroup;
@@ -51,6 +52,7 @@
 import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.ConcurrentMap;
 import java.util.concurrent.atomic.AtomicInteger;
+import java.util.stream.Collectors;
 
 import static org.slf4j.LoggerFactory.getLogger;
 
@@ -482,6 +484,31 @@
     }
 
     @Override
+    public void purgeGroupEntries(DeviceId deviceId, ApplicationId appId) {
+        List<StoredGroupEntry> entryPendingRemove =
+                groupEntriesById.get(deviceId).values().stream()
+                        .filter(storedGroupEntry -> storedGroupEntry.appId().equals(appId))
+                        .collect(Collectors.toList());
+
+        entryPendingRemove.forEach(storedGroupEntry -> {
+            groupEntriesById.computeIfPresent(deviceId, (k, value) -> {
+                value.remove(storedGroupEntry.id());
+                if (value.isEmpty()) {
+                    return null;
+                }
+                return value;
+            });
+            groupEntriesByKey.computeIfPresent(deviceId, (k, value) -> {
+                value.remove(storedGroupEntry.appCookie());
+                if (value.isEmpty()) {
+                    return null;
+                }
+                return value;
+            });
+        });
+    }
+
+    @Override
     public void purgeGroupEntries() {
         groupEntriesById.values().forEach(groupEntries -> {
             groupEntries.entrySet().forEach(entry -> {