ONOS-1443: Group bucket statistics support and group CLI formatting
Change-Id: Iaa6d8ae1f9222eb9c29d14bf1615a7449e50c4d3
diff --git a/core/api/src/main/java/org/onosproject/net/group/DefaultGroupBucket.java b/core/api/src/main/java/org/onosproject/net/group/DefaultGroupBucket.java
index e4910d5..6efd3e7 100644
--- a/core/api/src/main/java/org/onosproject/net/group/DefaultGroupBucket.java
+++ b/core/api/src/main/java/org/onosproject/net/group/DefaultGroupBucket.java
@@ -38,12 +38,14 @@
* in the group. A failover group bucket is associated with a
* specific port or group that controls its liveness.
*/
-public final class DefaultGroupBucket implements GroupBucket {
+public final class DefaultGroupBucket implements GroupBucket, StoredGroupBucketEntry {
private final GroupDescription.Type type;
private final TrafficTreatment treatment;
private final short weight;
private final PortNumber watchPort;
private final GroupId watchGroup;
+ private long packets;
+ private long bytes;
/**
* Group bucket constructor with the parameters.
@@ -223,6 +225,28 @@
return toStringHelper(this)
.add("type", type)
.add("treatment", treatment)
+ .add("packets", packets)
+ .add("bytes", bytes)
.toString();
}
+
+ @Override
+ public long packets() {
+ return packets;
+ }
+
+ @Override
+ public long bytes() {
+ return bytes;
+ }
+
+ @Override
+ public void setPackets(long packets) {
+ this.packets = packets;
+ }
+
+ @Override
+ public void setBytes(long bytes) {
+ this.bytes = bytes;
+ }
}
diff --git a/core/api/src/main/java/org/onosproject/net/group/GroupBucket.java b/core/api/src/main/java/org/onosproject/net/group/GroupBucket.java
index 2bf8882..401c769 100644
--- a/core/api/src/main/java/org/onosproject/net/group/GroupBucket.java
+++ b/core/api/src/main/java/org/onosproject/net/group/GroupBucket.java
@@ -64,4 +64,17 @@
*/
public GroupId watchGroup();
+ /**
+ * Returns the number of packets processed by this group bucket.
+ *
+ * @return number of packets
+ */
+ long packets();
+
+ /**
+ * Returns the number of bytes processed by this group bucket.
+ *
+ * @return number of bytes
+ */
+ long bytes();
}
diff --git a/core/api/src/main/java/org/onosproject/net/group/GroupBuckets.java b/core/api/src/main/java/org/onosproject/net/group/GroupBuckets.java
index 26cd5f6..c0b5e5c 100644
--- a/core/api/src/main/java/org/onosproject/net/group/GroupBuckets.java
+++ b/core/api/src/main/java/org/onosproject/net/group/GroupBuckets.java
@@ -70,7 +70,7 @@
@Override
public String toString() {
return toStringHelper(this)
- .add("buckets", buckets)
+ .add("buckets", buckets.toString())
.toString();
}
}
\ No newline at end of file
diff --git a/core/api/src/main/java/org/onosproject/net/group/GroupBucketEntry.java b/core/api/src/main/java/org/onosproject/net/group/StoredGroupBucketEntry.java
similarity index 72%
rename from core/api/src/main/java/org/onosproject/net/group/GroupBucketEntry.java
rename to core/api/src/main/java/org/onosproject/net/group/StoredGroupBucketEntry.java
index f7a6617..131875b 100644
--- a/core/api/src/main/java/org/onosproject/net/group/GroupBucketEntry.java
+++ b/core/api/src/main/java/org/onosproject/net/group/StoredGroupBucketEntry.java
@@ -20,18 +20,18 @@
* group object. A group bucket entry provides additional info of
* group bucket like statistics...etc
*/
-public interface GroupBucketEntry extends GroupBucket {
+public interface StoredGroupBucketEntry extends GroupBucket {
/**
- * Returns Number of packets processed by bucket.
+ * Sets number of packets processed by this group bucket entry.
*
- * @return long
+ * @param packets a long value
*/
- public long packets();
+ void setPackets(long packets);
/**
- * Returns Number of bytes processed by bucket.
+ * Sets number of bytes processed by this group bucket entry.
*
- * @return long
+ * @param bytes a long value
*/
- public long bytes();
+ void setBytes(long bytes);
}
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 1930a47..b447732 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
@@ -15,8 +15,10 @@
*/
package org.onosproject.store.group.impl;
+import com.google.common.base.Optional;
import com.google.common.collect.FluentIterable;
import com.google.common.collect.Iterables;
+
import org.apache.felix.scr.annotations.Activate;
import org.apache.felix.scr.annotations.Component;
import org.apache.felix.scr.annotations.Deactivate;
@@ -54,6 +56,7 @@
import org.onosproject.net.group.GroupOperation;
import org.onosproject.net.group.GroupStore;
import org.onosproject.net.group.GroupStoreDelegate;
+import org.onosproject.net.group.StoredGroupBucketEntry;
import org.onosproject.net.group.StoredGroupEntry;
import org.onosproject.store.AbstractStore;
import org.onosproject.store.Timestamp;
@@ -624,6 +627,22 @@
group.id(),
group.deviceId());
synchronized (existing) {
+ for (GroupBucket bucket:group.buckets().buckets()) {
+ java.util.Optional<GroupBucket> matchingBucket =
+ existing.buckets().buckets()
+ .stream()
+ .filter((existingBucket)->(existingBucket.equals(bucket)))
+ .findFirst();
+ if (matchingBucket.isPresent()) {
+ ((StoredGroupBucketEntry) matchingBucket.
+ get()).setPackets(bucket.packets());
+ ((StoredGroupBucketEntry) matchingBucket.
+ get()).setBytes(bucket.bytes());
+ } else {
+ log.warn("addOrUpdateGroupEntry: No matching "
+ + "buckets to update stats");
+ }
+ }
existing.setLife(group.life());
existing.setPackets(group.packets());
existing.setBytes(group.bytes());
diff --git a/core/store/trivial/src/main/java/org/onosproject/store/trivial/impl/SimpleGroupStore.java b/core/store/trivial/src/main/java/org/onosproject/store/trivial/impl/SimpleGroupStore.java
index d35a5c0..7c4f8c31 100644
--- a/core/store/trivial/src/main/java/org/onosproject/store/trivial/impl/SimpleGroupStore.java
+++ b/core/store/trivial/src/main/java/org/onosproject/store/trivial/impl/SimpleGroupStore.java
@@ -46,6 +46,7 @@
import org.onosproject.net.group.GroupOperation;
import org.onosproject.net.group.GroupStore;
import org.onosproject.net.group.GroupStoreDelegate;
+import org.onosproject.net.group.StoredGroupBucketEntry;
import org.onosproject.net.group.StoredGroupEntry;
import org.onosproject.store.AbstractStore;
import org.slf4j.Logger;
@@ -416,6 +417,22 @@
if (existing != null) {
synchronized (existing) {
+ for (GroupBucket bucket:group.buckets().buckets()) {
+ java.util.Optional<GroupBucket> matchingBucket =
+ existing.buckets().buckets()
+ .stream()
+ .filter((existingBucket)->(existingBucket.equals(bucket)))
+ .findFirst();
+ if (matchingBucket.isPresent()) {
+ ((StoredGroupBucketEntry) matchingBucket.
+ get()).setPackets(bucket.packets());
+ ((StoredGroupBucketEntry) matchingBucket.
+ get()).setBytes(bucket.bytes());
+ } else {
+ log.warn("addOrUpdateGroupEntry: No matching "
+ + "buckets to update stats");
+ }
+ }
existing.setLife(group.life());
existing.setPackets(group.packets());
existing.setBytes(group.bytes());
@@ -424,7 +441,7 @@
event = new GroupEvent(Type.GROUP_ADDED, existing);
} else {
if (existing.state() == GroupState.PENDING_UPDATE) {
- existing.setState(GroupState.PENDING_UPDATE);
+ existing.setState(GroupState.ADDED);
}
event = new GroupEvent(Type.GROUP_UPDATED, existing);
}
diff --git a/core/store/trivial/src/test/java/org/onosproject/store/trivial/impl/SimpleGroupStoreTest.java b/core/store/trivial/src/test/java/org/onosproject/store/trivial/impl/SimpleGroupStoreTest.java
index 92ae5d7..61d60b1 100644
--- a/core/store/trivial/src/test/java/org/onosproject/store/trivial/impl/SimpleGroupStoreTest.java
+++ b/core/store/trivial/src/test/java/org/onosproject/store/trivial/impl/SimpleGroupStoreTest.java
@@ -34,6 +34,7 @@
import org.onosproject.net.PortNumber;
import org.onosproject.net.flow.DefaultTrafficTreatment;
import org.onosproject.net.flow.TrafficTreatment;
+import org.onosproject.net.group.DefaultGroup;
import org.onosproject.net.group.DefaultGroupBucket;
import org.onosproject.net.group.DefaultGroupDescription;
import org.onosproject.net.group.DefaultGroupKey;
@@ -46,6 +47,8 @@
import org.onosproject.net.group.GroupOperation;
import org.onosproject.net.group.GroupStore.UpdateType;
import org.onosproject.net.group.GroupStoreDelegate;
+import org.onosproject.net.group.StoredGroupBucketEntry;
+import org.onosproject.net.group.StoredGroupEntry;
import com.google.common.collect.Iterables;
@@ -100,6 +103,26 @@
createdGroupId = event.subject().id();
assertEquals(Group.GroupState.ADDED,
event.subject().state());
+ } else if (expectedEvent == GroupEvent.Type.GROUP_UPDATED) {
+ createdGroupId = event.subject().id();
+ assertEquals(true,
+ event.subject().buckets().
+ buckets().containsAll(createdBuckets.buckets()));
+ assertEquals(true,
+ createdBuckets.buckets().
+ containsAll(event.subject().buckets().buckets()));
+ for (GroupBucket bucket:event.subject().buckets().buckets()) {
+ java.util.Optional<GroupBucket> matched = createdBuckets.buckets()
+ .stream()
+ .filter((expected) -> expected.equals(bucket))
+ .findFirst();
+ assertEquals(matched.get().packets(),
+ bucket.packets());
+ assertEquals(matched.get().bytes(),
+ bucket.bytes());
+ }
+ assertEquals(Group.GroupState.ADDED,
+ event.subject().state());
} else if (expectedEvent == GroupEvent.Type.GROUP_UPDATE_REQUESTED) {
assertEquals(Group.GroupState.PENDING_UPDATE,
event.subject().state());
@@ -243,13 +266,33 @@
// Testing addOrUpdateGroupEntry operation from southbound
private void testUpdateGroupEntryFromSB(GroupKey currKey) {
Group existingGroup = simpleGroupStore.getGroup(D1, currKey);
+ int totalPkts = 0;
+ int totalBytes = 0;
+ List<GroupBucket> newBucketList = new ArrayList<GroupBucket>();
+ for (GroupBucket bucket:existingGroup.buckets().buckets()) {
+ StoredGroupBucketEntry newBucket =
+ (StoredGroupBucketEntry)
+ DefaultGroupBucket.createSelectGroupBucket(bucket.treatment());
+ newBucket.setPackets(10);
+ newBucket.setBytes(10 * 256 * 8);
+ totalPkts += 10;
+ totalBytes += 10 * 256 * 8;
+ newBucketList.add(newBucket);
+ }
+ GroupBuckets updatedBuckets = new GroupBuckets(newBucketList);
+ Group updatedGroup = new DefaultGroup(existingGroup.id(),
+ existingGroup.deviceId(),
+ existingGroup.type(),
+ updatedBuckets);
+ ((StoredGroupEntry) updatedGroup).setPackets(totalPkts);
+ ((StoredGroupEntry) updatedGroup).setBytes(totalBytes);
InternalGroupStoreDelegate updateGroupEntryDelegate =
new InternalGroupStoreDelegate(currKey,
- existingGroup.buckets(),
+ updatedBuckets,
GroupEvent.Type.GROUP_UPDATED);
simpleGroupStore.setDelegate(updateGroupEntryDelegate);
- simpleGroupStore.addOrUpdateGroupEntry(existingGroup);
+ simpleGroupStore.addOrUpdateGroupEntry(updatedGroup);
simpleGroupStore.unsetDelegate(updateGroupEntryDelegate);
}