[ONOS-5797] GroupService: add setBucketsForGroup

Add method to set all buckets from a group, overwriting the
previous group buckets entirely. Useful for edits that before
required two operations: removing the buckets and then adding
others. It can all be done with one OF message in the end.

Change-Id: Ic5669603ed4fd18b8efaa8d0253ab9d7b1e870f5
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 01930ef..42a6d56 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
@@ -321,6 +321,10 @@
     private List<GroupBucket> getUpdatedBucketList(Group oldGroup,
                                                    UpdateType type,
                                                    GroupBuckets buckets) {
+        if (type == UpdateType.SET) {
+            return buckets.buckets();
+        }
+
         List<GroupBucket> oldBuckets = oldGroup.buckets().buckets();
         List<GroupBucket> updatedBucketList = new ArrayList<>();
         boolean groupDescUpdated = false;
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 1e6f865..2f87a5c 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
@@ -204,6 +204,11 @@
         newKey = new DefaultGroupKey("group1RemoveBuckets".getBytes());
         testRemoveBuckets(currKey, newKey);
 
+        // Testing updateGroupDescription for SET operation from northbound
+        currKey = newKey;
+        newKey = new DefaultGroupKey("group1SetBuckets".getBytes());
+        testSetBuckets(currKey, newKey);
+
         // Testing addOrUpdateGroupEntry operation from southbound
         currKey = newKey;
         testUpdateGroupEntryFromSB(currKey);
@@ -418,6 +423,35 @@
         simpleGroupStore.unsetDelegate(removeGroupDescDelegate);
     }
 
+    // Testing updateGroupDescription for SET operation from northbound
+    private void testSetBuckets(GroupKey currKey, GroupKey setKey) {
+        List<GroupBucket> toSetBuckets = new ArrayList<>();
+
+        short weight = 5;
+        PortNumber portNumber = PortNumber.portNumber(42);
+        TrafficTreatment.Builder tBuilder = DefaultTrafficTreatment.builder();
+        tBuilder.setOutput(portNumber)
+                .setEthDst(MacAddress.valueOf("00:00:00:00:00:03"))
+                .setEthSrc(MacAddress.valueOf("00:00:00:00:00:01"))
+                .pushMpls()
+                .setMpls(MplsLabel.mplsLabel(106));
+        toSetBuckets.add(DefaultGroupBucket.createSelectGroupBucket(
+                tBuilder.build(), weight));
+
+        GroupBuckets toSetGroupBuckets = new GroupBuckets(toSetBuckets);
+        InternalGroupStoreDelegate updateGroupDescDelegate =
+                new InternalGroupStoreDelegate(setKey,
+                        toSetGroupBuckets,
+                        GroupEvent.Type.GROUP_UPDATE_REQUESTED);
+        simpleGroupStore.setDelegate(updateGroupDescDelegate);
+        simpleGroupStore.updateGroupDescription(D1,
+                currKey,
+                UpdateType.SET,
+                toSetGroupBuckets,
+                setKey);
+        simpleGroupStore.unsetDelegate(updateGroupDescDelegate);
+    }
+
     // Testing deleteGroupDescription operation from northbound
     private void testDeleteGroup(GroupKey currKey) {
         Group existingGroup = simpleGroupStore.getGroup(D1, currKey);