[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/api/src/main/java/org/onosproject/net/group/GroupService.java b/core/api/src/main/java/org/onosproject/net/group/GroupService.java
index 47e0882..ef62783 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
@@ -107,6 +107,26 @@
ApplicationId appId);
/**
+ * Set buckets for an existing group. The caller can optionally
+ * associate a new cookie during this updation. GROUP_UPDATED or
+ * GROUP_UPDATE_FAILED notifications would be provided along with
+ * cookie depending on the result of the operation on the device.
+ *
+ * This operation overwrites the previous group buckets entirely.
+ *
+ * @param deviceId device identifier
+ * @param oldCookie cookie to be used to retrieve the existing group
+ * @param buckets immutable list of group buckets to be set
+ * @param newCookie immutable cookie to be used post update operation
+ * @param appId Application Id
+ */
+ default void setBucketsForGroup(DeviceId deviceId,
+ GroupKey oldCookie,
+ GroupBuckets buckets,
+ GroupKey newCookie,
+ ApplicationId appId) {}
+
+ /**
* Purges all the group entries on the specified device.
* @param deviceId device identifier
*/
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 0c0c06c..4559e64 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
@@ -34,7 +34,12 @@
/**
* Modify existing group by removing provided information from it.
*/
- REMOVE
+ REMOVE,
+ /**
+ * Modify existing group entry by setting the provided information,
+ * overwriting the previous group entry entirely.
+ */
+ SET
}
/**
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);
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 09930d2..bcca209 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
@@ -224,6 +224,34 @@
newCookie);
}
+ /**
+ * Set buckets for an existing group. The caller can optionally
+ * associate a new cookie during this updation. GROUP_UPDATED or
+ * GROUP_UPDATE_FAILED notifications would be provided along with
+ * cookie depending on the result of the operation on the device.
+ *
+ * This operation overwrites the previous group buckets entirely.
+ *
+ * @param deviceId device identifier
+ * @param oldCookie cookie to be used to retrieve the existing group
+ * @param buckets immutable list of group buckets to be set
+ * @param newCookie immutable cookie to be used post update operation
+ * @param appId Application Id
+ */
+ @Override
+ public void setBucketsForGroup(DeviceId deviceId,
+ GroupKey oldCookie,
+ GroupBuckets buckets,
+ GroupKey newCookie,
+ ApplicationId appId) {
+ checkPermission(GROUP_WRITE);
+ store.updateGroupDescription(deviceId,
+ oldCookie,
+ UpdateType.SET,
+ buckets,
+ newCookie);
+ }
+
@Override
public void purgeGroupEntries(DeviceId deviceId) {
checkPermission(GROUP_WRITE);
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 28e3302..88a1d54 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
@@ -719,6 +719,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/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 a3ca1ec..e9cebef 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
@@ -430,6 +430,20 @@
assertEquals(weight, bucket.weight());
}
}
+
+ buckets = new GroupBuckets(ImmutableList.of(selectGroupBucketWithWeight));
+
+ groupStore.updateGroupDescription(deviceId1,
+ newKey,
+ SET,
+ buckets,
+ newKey);
+
+ group1 = groupStore.getGroup(deviceId1, groupId1);
+ assertThat(group1.appCookie(), is(newKey));
+ assertThat(group1.buckets().buckets(), hasSize(1));
+ GroupBucket onlyBucket = group1.buckets().buckets().iterator().next();
+ assertEquals(weight, onlyBucket.weight());
}
@Test