[ONOS-5170] GroupStore: add purgeGroupEntries

The GroupStore exposes purgeGroupEntry, which purges
from the store by a specific device.

Add purgeGroupEntries, to purge entries from all devices
from the GroupStore, and expose purgeGroupEntries to allow
applications to purge all group entries from the GroupStore
without specifying a device.

Change-Id: I735f011a1fbbfa3ce8f1dd57a591a81c4377b012
diff --git a/core/api/src/main/java/org/onosproject/net/group/GroupService.java b/core/api/src/main/java/org/onosproject/net/group/GroupService.java
index 369cc37..692bde8 100644
--- a/core/api/src/main/java/org/onosproject/net/group/GroupService.java
+++ b/core/api/src/main/java/org/onosproject/net/group/GroupService.java
@@ -113,6 +113,11 @@
     void purgeGroupEntries(DeviceId deviceId);
 
     /**
+     * Purges all group entries.
+     */
+    default void purgeGroupEntries() {};
+
+    /**
      * Deletes a group associated to an application cookie.
      * GROUP_DELETED or GROUP_DELETE_FAILED notifications would be
      * provided along with cookie depending on the result of the
diff --git a/core/api/src/main/java/org/onosproject/net/group/GroupStore.java b/core/api/src/main/java/org/onosproject/net/group/GroupStore.java
index d2dd992..2cf4aa5 100644
--- a/core/api/src/main/java/org/onosproject/net/group/GroupStore.java
+++ b/core/api/src/main/java/org/onosproject/net/group/GroupStore.java
@@ -125,6 +125,11 @@
     void purgeGroupEntry(DeviceId deviceId);
 
     /**
+     * Removes all group entries from store.
+     */
+    default void purgeGroupEntries() {};
+
+    /**
      * A group entry that is present in switch but not in the store.
      *
      * @param group group entry
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 62c3e30..01930ef 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
@@ -482,6 +482,18 @@
     }
 
     @Override
+    public void purgeGroupEntries() {
+        groupEntriesById.values().forEach(groupEntries -> {
+            groupEntries.entrySet().forEach(entry -> {
+                notifyDelegate(new GroupEvent(Type.GROUP_REMOVED, entry.getValue()));
+            });
+        });
+
+        groupEntriesById.clear();
+        groupEntriesByKey.clear();
+    }
+
+    @Override
     public void deviceInitialAuditCompleted(DeviceId deviceId,
                                             boolean completed) {
         synchronized (deviceAuditStatus) {
diff --git a/core/common/src/test/java/org/onosproject/store/trivial/SimpleGroupStoreTest.java b/core/common/src/test/java/org/onosproject/store/trivial/SimpleGroupStoreTest.java
index 834c8ee..1e6f865 100644
--- a/core/common/src/test/java/org/onosproject/store/trivial/SimpleGroupStoreTest.java
+++ b/core/common/src/test/java/org/onosproject/store/trivial/SimpleGroupStoreTest.java
@@ -214,10 +214,15 @@
         // Testing removeGroupEntry operation from southbound
         testRemoveGroupFromSB(currKey);
 
-        // Testing removing all groups on the given device
+        // Testing removing all groups on the given device by deviceid
         newKey = new DefaultGroupKey("group1".getBytes());
         testStoreAndGetGroup(newKey);
         testDeleteGroupOnDevice(newKey);
+
+        // Testing removing all groups on the given device
+        newKey = new DefaultGroupKey("group1".getBytes());
+        testStoreAndGetGroup(newKey);
+        testPurgeGroupEntries();
     }
 
     // Testing storeGroup operation
@@ -432,6 +437,13 @@
         assertThat(simpleGroupStore.getGroupCount(D1), is(0));
     }
 
+    // Testing purgeGroupEntries
+    private void testPurgeGroupEntries() {
+        assertThat(simpleGroupStore.getGroupCount(D1), is(1));
+        simpleGroupStore.purgeGroupEntries();
+        assertThat(simpleGroupStore.getGroupCount(D1), is(0));
+    }
+
     // Testing removeGroupEntry operation from southbound
     private void testRemoveGroupFromSB(GroupKey currKey) {
         Group existingGroup = simpleGroupStore.getGroup(D1, currKey);
diff --git a/core/net/src/main/java/org/onosproject/net/group/impl/GroupManager.java b/core/net/src/main/java/org/onosproject/net/group/impl/GroupManager.java
index 2e4a375..09930d2 100644
--- a/core/net/src/main/java/org/onosproject/net/group/impl/GroupManager.java
+++ b/core/net/src/main/java/org/onosproject/net/group/impl/GroupManager.java
@@ -230,6 +230,11 @@
         store.purgeGroupEntry(deviceId);
     }
 
+    @Override
+    public void purgeGroupEntries() {
+        checkPermission(GROUP_WRITE);
+        store.purgeGroupEntries();
+    }
 
     /**
      * Delete a group associated to an application cookie.
diff --git a/core/store/dist/src/main/java/org/onosproject/store/group/impl/DistributedGroupStore.java b/core/store/dist/src/main/java/org/onosproject/store/group/impl/DistributedGroupStore.java
index ab66bd4..64df685 100644
--- a/core/store/dist/src/main/java/org/onosproject/store/group/impl/DistributedGroupStore.java
+++ b/core/store/dist/src/main/java/org/onosproject/store/group/impl/DistributedGroupStore.java
@@ -931,19 +931,27 @@
         }
     }
 
+    private void purgeGroupEntries(Set<Entry<GroupStoreKeyMapKey, StoredGroupEntry>> entries) {
+        entries.forEach(entry -> {
+            groupStoreEntriesByKey.remove(entry.getKey());
+        });
+    }
+
     @Override
     public void purgeGroupEntry(DeviceId deviceId) {
-        Set<Entry<GroupStoreKeyMapKey, StoredGroupEntry>> entryPendingRemove =
+        Set<Entry<GroupStoreKeyMapKey, StoredGroupEntry>> entriesPendingRemove =
                 new HashSet<>();
 
         getGroupStoreKeyMap().entrySet().stream()
                 .filter(entry -> entry.getKey().deviceId().equals(deviceId))
-                .forEach(entryPendingRemove::add);
+                .forEach(entriesPendingRemove::add);
 
-        entryPendingRemove.forEach(entry -> {
-            groupStoreEntriesByKey.remove(entry.getKey());
-            notifyDelegate(new GroupEvent(Type.GROUP_REMOVED, entry.getValue()));
-        });
+        purgeGroupEntries(entriesPendingRemove);
+    }
+
+    @Override
+    public void purgeGroupEntries() {
+        purgeGroupEntries(getGroupStoreKeyMap().entrySet());
     }
 
     @Override
diff --git a/core/store/dist/src/test/java/org/onosproject/store/group/impl/DistributedGroupStoreTest.java b/core/store/dist/src/test/java/org/onosproject/store/group/impl/DistributedGroupStoreTest.java
index 288d8de..a3ca1ec 100644
--- a/core/store/dist/src/test/java/org/onosproject/store/group/impl/DistributedGroupStoreTest.java
+++ b/core/store/dist/src/test/java/org/onosproject/store/group/impl/DistributedGroupStoreTest.java
@@ -236,6 +236,10 @@
         groupStore.purgeGroupEntry(deviceId2);
         assertThat(groupStore.getGroupCount(deviceId1), is(1));
         assertThat(groupStore.getGroupCount(deviceId2), is(0));
+
+        groupStore.purgeGroupEntries();
+        assertThat(groupStore.getGroupCount(deviceId1), is(0));
+        assertThat(groupStore.getGroupCount(deviceId2), is(0));
     }
 
     /**