Srikanth Vavilapalli
Committed by Gerrit Code Review

ONOS-1443: Group bucket statistics support and group CLI formatting

Change-Id: Iaa6d8ae1f9222eb9c29d14bf1615a7449e50c4d3
...@@ -25,6 +25,7 @@ import org.onosproject.net.Element; ...@@ -25,6 +25,7 @@ import org.onosproject.net.Element;
25 import org.onosproject.net.ElementId; 25 import org.onosproject.net.ElementId;
26 import org.onosproject.net.Port; 26 import org.onosproject.net.Port;
27 import org.onosproject.net.flow.FlowRule; 27 import org.onosproject.net.flow.FlowRule;
28 +import org.onosproject.net.group.Group;
28 import org.onosproject.net.host.PortAddresses; 29 import org.onosproject.net.host.PortAddresses;
29 import org.onosproject.net.topology.TopologyCluster; 30 import org.onosproject.net.topology.TopologyCluster;
30 31
...@@ -72,6 +73,13 @@ public final class Comparators { ...@@ -72,6 +73,13 @@ public final class Comparators {
72 } 73 }
73 }; 74 };
74 75
76 + public static final Comparator<Group> GROUP_COMPARATOR = new Comparator<Group>() {
77 + @Override
78 + public int compare(Group g1, Group g2) {
79 + return Long.valueOf(g1.id().id()).compareTo(Long.valueOf(g2.id().id()));
80 + }
81 + };
82 +
75 public static final Comparator<Port> PORT_COMPARATOR = new Comparator<Port>() { 83 public static final Comparator<Port> PORT_COMPARATOR = new Comparator<Port>() {
76 @Override 84 @Override
77 public int compare(Port p1, Port p2) { 85 public int compare(Port p1, Port p2) {
......
...@@ -15,11 +15,23 @@ ...@@ -15,11 +15,23 @@
15 */ 15 */
16 package org.onosproject.cli.net; 16 package org.onosproject.cli.net;
17 17
18 +import static com.google.common.collect.Lists.newArrayList;
19 +
20 +import java.util.Collections;
21 +import java.util.List;
22 +import java.util.SortedMap;
23 +import java.util.TreeMap;
24 +
25 +import org.apache.karaf.shell.commands.Argument;
18 import org.apache.karaf.shell.commands.Command; 26 import org.apache.karaf.shell.commands.Command;
19 import org.onosproject.cli.AbstractShellCommand; 27 import org.onosproject.cli.AbstractShellCommand;
28 +import org.onosproject.cli.Comparators;
29 +import org.onosproject.net.Device;
20 import org.onosproject.net.DeviceId; 30 import org.onosproject.net.DeviceId;
21 import org.onosproject.net.device.DeviceService; 31 import org.onosproject.net.device.DeviceService;
22 import org.onosproject.net.group.Group; 32 import org.onosproject.net.group.Group;
33 +import org.onosproject.net.group.Group.GroupState;
34 +import org.onosproject.net.group.GroupBucket;
23 import org.onosproject.net.group.GroupService; 35 import org.onosproject.net.group.GroupService;
24 36
25 /** 37 /**
...@@ -30,23 +42,75 @@ import org.onosproject.net.group.GroupService; ...@@ -30,23 +42,75 @@ import org.onosproject.net.group.GroupService;
30 public class GroupsListCommand extends AbstractShellCommand { 42 public class GroupsListCommand extends AbstractShellCommand {
31 43
32 private static final String FORMAT = 44 private static final String FORMAT =
33 - " key=%s, id=%s, state=%s, bytes=%s, packets=%s, appId=%s, buckets=%s"; 45 + " id=%s, state=%s, bytes=%s, packets=%s, appId=%s";
46 + private static final String BUCKET_FORMAT =
47 + " id=%s, bucket=%s, bytes=%s, packets=%s, actions=%s";
48 +
49 + @Argument(index = 1, name = "uri", description = "Device ID",
50 + required = false, multiValued = false)
51 + String uri = null;
52 +
53 + @Argument(index = 0, name = "state", description = "Group state",
54 + required = false, multiValued = false)
55 + String state;
34 56
35 @Override 57 @Override
36 protected void execute() { 58 protected void execute() {
37 DeviceService deviceService = get(DeviceService.class); 59 DeviceService deviceService = get(DeviceService.class);
38 GroupService groupService = get(GroupService.class); 60 GroupService groupService = get(GroupService.class);
61 + SortedMap<Device, List<Group>> sortedGroups =
62 + getSortedGroups(deviceService, groupService);
39 63
40 - deviceService.getDevices().forEach(d -> 64 + sortedGroups.forEach((device, groups) -> printGroups(device.id(), groups));
41 - printGroups(d.id(), groupService.getGroups(d.id())) 65 + }
42 - ); 66 +
67 + /**
68 + * Returns the list of devices sorted using the device ID URIs.
69 + *
70 + * @param deviceService device service
71 + * @param groupService group service
72 + * @return sorted device list
73 + */
74 + protected SortedMap<Device, List<Group>>
75 + getSortedGroups(DeviceService deviceService,
76 + GroupService groupService) {
77 + SortedMap<Device, List<Group>> sortedGroups =
78 + new TreeMap<>(Comparators.ELEMENT_COMPARATOR);
79 + List<Group> groups;
80 + GroupState s = null;
81 + if (state != null && !state.equals("any")) {
82 + s = GroupState.valueOf(state.toUpperCase());
83 + }
84 + Iterable<Device> devices = (uri == null) ? deviceService.getDevices() :
85 + Collections.singletonList(deviceService.getDevice(DeviceId.deviceId(uri)));
86 + for (Device d : devices) {
87 + if (s == null) {
88 + groups = newArrayList(groupService.getGroups(d.id()));
89 + } else {
90 + groups = newArrayList();
91 + for (Group g : groupService.getGroups(d.id())) {
92 + if (g.state().equals(s)) {
93 + groups.add(g);
94 + }
95 + }
96 + }
97 + groups.sort(Comparators.GROUP_COMPARATOR);
98 + sortedGroups.put(d, groups);
99 + }
100 + return sortedGroups;
43 } 101 }
44 102
45 - private void printGroups(DeviceId deviceId, Iterable<Group> groups) { 103 + private void printGroups(DeviceId deviceId, List<Group> groups) {
46 print("deviceId=%s", deviceId); 104 print("deviceId=%s", deviceId);
47 for (Group group : groups) { 105 for (Group group : groups) {
48 - print(FORMAT, group.appCookie(), group.id(), group.state(), 106 + print(FORMAT, group.id().id(), group.state(),
49 - group.bytes(), group.packets(), group.appId(), group.buckets()); 107 + group.bytes(), group.packets(), group.appId().name());
108 + int i = 0;
109 + for (GroupBucket bucket:group.buckets().buckets()) {
110 + print(BUCKET_FORMAT, group.id().id(), ++i,
111 + bucket.bytes(), bucket.packets(),
112 + bucket.treatment().allInstructions());
113 + }
50 } 114 }
51 } 115 }
52 } 116 }
......
...@@ -38,12 +38,14 @@ import static com.google.common.base.Preconditions.checkNotNull; ...@@ -38,12 +38,14 @@ import static com.google.common.base.Preconditions.checkNotNull;
38 * in the group. A failover group bucket is associated with a 38 * in the group. A failover group bucket is associated with a
39 * specific port or group that controls its liveness. 39 * specific port or group that controls its liveness.
40 */ 40 */
41 -public final class DefaultGroupBucket implements GroupBucket { 41 +public final class DefaultGroupBucket implements GroupBucket, StoredGroupBucketEntry {
42 private final GroupDescription.Type type; 42 private final GroupDescription.Type type;
43 private final TrafficTreatment treatment; 43 private final TrafficTreatment treatment;
44 private final short weight; 44 private final short weight;
45 private final PortNumber watchPort; 45 private final PortNumber watchPort;
46 private final GroupId watchGroup; 46 private final GroupId watchGroup;
47 + private long packets;
48 + private long bytes;
47 49
48 /** 50 /**
49 * Group bucket constructor with the parameters. 51 * Group bucket constructor with the parameters.
...@@ -223,6 +225,28 @@ public final class DefaultGroupBucket implements GroupBucket { ...@@ -223,6 +225,28 @@ public final class DefaultGroupBucket implements GroupBucket {
223 return toStringHelper(this) 225 return toStringHelper(this)
224 .add("type", type) 226 .add("type", type)
225 .add("treatment", treatment) 227 .add("treatment", treatment)
228 + .add("packets", packets)
229 + .add("bytes", bytes)
226 .toString(); 230 .toString();
227 } 231 }
232 +
233 + @Override
234 + public long packets() {
235 + return packets;
236 + }
237 +
238 + @Override
239 + public long bytes() {
240 + return bytes;
241 + }
242 +
243 + @Override
244 + public void setPackets(long packets) {
245 + this.packets = packets;
246 + }
247 +
248 + @Override
249 + public void setBytes(long bytes) {
250 + this.bytes = bytes;
251 + }
228 } 252 }
......
...@@ -64,4 +64,17 @@ public interface GroupBucket { ...@@ -64,4 +64,17 @@ public interface GroupBucket {
64 */ 64 */
65 public GroupId watchGroup(); 65 public GroupId watchGroup();
66 66
67 + /**
68 + * Returns the number of packets processed by this group bucket.
69 + *
70 + * @return number of packets
71 + */
72 + long packets();
73 +
74 + /**
75 + * Returns the number of bytes processed by this group bucket.
76 + *
77 + * @return number of bytes
78 + */
79 + long bytes();
67 } 80 }
......
...@@ -70,7 +70,7 @@ public final class GroupBuckets { ...@@ -70,7 +70,7 @@ public final class GroupBuckets {
70 @Override 70 @Override
71 public String toString() { 71 public String toString() {
72 return toStringHelper(this) 72 return toStringHelper(this)
73 - .add("buckets", buckets) 73 + .add("buckets", buckets.toString())
74 .toString(); 74 .toString();
75 } 75 }
76 } 76 }
...\ No newline at end of file ...\ No newline at end of file
......
...@@ -20,18 +20,18 @@ package org.onosproject.net.group; ...@@ -20,18 +20,18 @@ package org.onosproject.net.group;
20 * group object. A group bucket entry provides additional info of 20 * group object. A group bucket entry provides additional info of
21 * group bucket like statistics...etc 21 * group bucket like statistics...etc
22 */ 22 */
23 -public interface GroupBucketEntry extends GroupBucket { 23 +public interface StoredGroupBucketEntry extends GroupBucket {
24 /** 24 /**
25 - * Returns Number of packets processed by bucket. 25 + * Sets number of packets processed by this group bucket entry.
26 * 26 *
27 - * @return long 27 + * @param packets a long value
28 */ 28 */
29 - public long packets(); 29 + void setPackets(long packets);
30 30
31 /** 31 /**
32 - * Returns Number of bytes processed by bucket. 32 + * Sets number of bytes processed by this group bucket entry.
33 * 33 *
34 - * @return long 34 + * @param bytes a long value
35 */ 35 */
36 - public long bytes(); 36 + void setBytes(long bytes);
37 } 37 }
......
...@@ -15,8 +15,10 @@ ...@@ -15,8 +15,10 @@
15 */ 15 */
16 package org.onosproject.store.group.impl; 16 package org.onosproject.store.group.impl;
17 17
18 +import com.google.common.base.Optional;
18 import com.google.common.collect.FluentIterable; 19 import com.google.common.collect.FluentIterable;
19 import com.google.common.collect.Iterables; 20 import com.google.common.collect.Iterables;
21 +
20 import org.apache.felix.scr.annotations.Activate; 22 import org.apache.felix.scr.annotations.Activate;
21 import org.apache.felix.scr.annotations.Component; 23 import org.apache.felix.scr.annotations.Component;
22 import org.apache.felix.scr.annotations.Deactivate; 24 import org.apache.felix.scr.annotations.Deactivate;
...@@ -54,6 +56,7 @@ import org.onosproject.net.group.GroupKey; ...@@ -54,6 +56,7 @@ import org.onosproject.net.group.GroupKey;
54 import org.onosproject.net.group.GroupOperation; 56 import org.onosproject.net.group.GroupOperation;
55 import org.onosproject.net.group.GroupStore; 57 import org.onosproject.net.group.GroupStore;
56 import org.onosproject.net.group.GroupStoreDelegate; 58 import org.onosproject.net.group.GroupStoreDelegate;
59 +import org.onosproject.net.group.StoredGroupBucketEntry;
57 import org.onosproject.net.group.StoredGroupEntry; 60 import org.onosproject.net.group.StoredGroupEntry;
58 import org.onosproject.store.AbstractStore; 61 import org.onosproject.store.AbstractStore;
59 import org.onosproject.store.Timestamp; 62 import org.onosproject.store.Timestamp;
...@@ -624,6 +627,22 @@ public class DistributedGroupStore ...@@ -624,6 +627,22 @@ public class DistributedGroupStore
624 group.id(), 627 group.id(),
625 group.deviceId()); 628 group.deviceId());
626 synchronized (existing) { 629 synchronized (existing) {
630 + for (GroupBucket bucket:group.buckets().buckets()) {
631 + java.util.Optional<GroupBucket> matchingBucket =
632 + existing.buckets().buckets()
633 + .stream()
634 + .filter((existingBucket)->(existingBucket.equals(bucket)))
635 + .findFirst();
636 + if (matchingBucket.isPresent()) {
637 + ((StoredGroupBucketEntry) matchingBucket.
638 + get()).setPackets(bucket.packets());
639 + ((StoredGroupBucketEntry) matchingBucket.
640 + get()).setBytes(bucket.bytes());
641 + } else {
642 + log.warn("addOrUpdateGroupEntry: No matching "
643 + + "buckets to update stats");
644 + }
645 + }
627 existing.setLife(group.life()); 646 existing.setLife(group.life());
628 existing.setPackets(group.packets()); 647 existing.setPackets(group.packets());
629 existing.setBytes(group.bytes()); 648 existing.setBytes(group.bytes());
......
...@@ -46,6 +46,7 @@ import org.onosproject.net.group.GroupKey; ...@@ -46,6 +46,7 @@ import org.onosproject.net.group.GroupKey;
46 import org.onosproject.net.group.GroupOperation; 46 import org.onosproject.net.group.GroupOperation;
47 import org.onosproject.net.group.GroupStore; 47 import org.onosproject.net.group.GroupStore;
48 import org.onosproject.net.group.GroupStoreDelegate; 48 import org.onosproject.net.group.GroupStoreDelegate;
49 +import org.onosproject.net.group.StoredGroupBucketEntry;
49 import org.onosproject.net.group.StoredGroupEntry; 50 import org.onosproject.net.group.StoredGroupEntry;
50 import org.onosproject.store.AbstractStore; 51 import org.onosproject.store.AbstractStore;
51 import org.slf4j.Logger; 52 import org.slf4j.Logger;
...@@ -416,6 +417,22 @@ public class SimpleGroupStore ...@@ -416,6 +417,22 @@ public class SimpleGroupStore
416 417
417 if (existing != null) { 418 if (existing != null) {
418 synchronized (existing) { 419 synchronized (existing) {
420 + for (GroupBucket bucket:group.buckets().buckets()) {
421 + java.util.Optional<GroupBucket> matchingBucket =
422 + existing.buckets().buckets()
423 + .stream()
424 + .filter((existingBucket)->(existingBucket.equals(bucket)))
425 + .findFirst();
426 + if (matchingBucket.isPresent()) {
427 + ((StoredGroupBucketEntry) matchingBucket.
428 + get()).setPackets(bucket.packets());
429 + ((StoredGroupBucketEntry) matchingBucket.
430 + get()).setBytes(bucket.bytes());
431 + } else {
432 + log.warn("addOrUpdateGroupEntry: No matching "
433 + + "buckets to update stats");
434 + }
435 + }
419 existing.setLife(group.life()); 436 existing.setLife(group.life());
420 existing.setPackets(group.packets()); 437 existing.setPackets(group.packets());
421 existing.setBytes(group.bytes()); 438 existing.setBytes(group.bytes());
...@@ -424,7 +441,7 @@ public class SimpleGroupStore ...@@ -424,7 +441,7 @@ public class SimpleGroupStore
424 event = new GroupEvent(Type.GROUP_ADDED, existing); 441 event = new GroupEvent(Type.GROUP_ADDED, existing);
425 } else { 442 } else {
426 if (existing.state() == GroupState.PENDING_UPDATE) { 443 if (existing.state() == GroupState.PENDING_UPDATE) {
427 - existing.setState(GroupState.PENDING_UPDATE); 444 + existing.setState(GroupState.ADDED);
428 } 445 }
429 event = new GroupEvent(Type.GROUP_UPDATED, existing); 446 event = new GroupEvent(Type.GROUP_UPDATED, existing);
430 } 447 }
......
...@@ -34,6 +34,7 @@ import org.onosproject.net.DeviceId; ...@@ -34,6 +34,7 @@ import org.onosproject.net.DeviceId;
34 import org.onosproject.net.PortNumber; 34 import org.onosproject.net.PortNumber;
35 import org.onosproject.net.flow.DefaultTrafficTreatment; 35 import org.onosproject.net.flow.DefaultTrafficTreatment;
36 import org.onosproject.net.flow.TrafficTreatment; 36 import org.onosproject.net.flow.TrafficTreatment;
37 +import org.onosproject.net.group.DefaultGroup;
37 import org.onosproject.net.group.DefaultGroupBucket; 38 import org.onosproject.net.group.DefaultGroupBucket;
38 import org.onosproject.net.group.DefaultGroupDescription; 39 import org.onosproject.net.group.DefaultGroupDescription;
39 import org.onosproject.net.group.DefaultGroupKey; 40 import org.onosproject.net.group.DefaultGroupKey;
...@@ -46,6 +47,8 @@ import org.onosproject.net.group.GroupKey; ...@@ -46,6 +47,8 @@ import org.onosproject.net.group.GroupKey;
46 import org.onosproject.net.group.GroupOperation; 47 import org.onosproject.net.group.GroupOperation;
47 import org.onosproject.net.group.GroupStore.UpdateType; 48 import org.onosproject.net.group.GroupStore.UpdateType;
48 import org.onosproject.net.group.GroupStoreDelegate; 49 import org.onosproject.net.group.GroupStoreDelegate;
50 +import org.onosproject.net.group.StoredGroupBucketEntry;
51 +import org.onosproject.net.group.StoredGroupEntry;
49 52
50 import com.google.common.collect.Iterables; 53 import com.google.common.collect.Iterables;
51 54
...@@ -100,6 +103,26 @@ public class SimpleGroupStoreTest { ...@@ -100,6 +103,26 @@ public class SimpleGroupStoreTest {
100 createdGroupId = event.subject().id(); 103 createdGroupId = event.subject().id();
101 assertEquals(Group.GroupState.ADDED, 104 assertEquals(Group.GroupState.ADDED,
102 event.subject().state()); 105 event.subject().state());
106 + } else if (expectedEvent == GroupEvent.Type.GROUP_UPDATED) {
107 + createdGroupId = event.subject().id();
108 + assertEquals(true,
109 + event.subject().buckets().
110 + buckets().containsAll(createdBuckets.buckets()));
111 + assertEquals(true,
112 + createdBuckets.buckets().
113 + containsAll(event.subject().buckets().buckets()));
114 + for (GroupBucket bucket:event.subject().buckets().buckets()) {
115 + java.util.Optional<GroupBucket> matched = createdBuckets.buckets()
116 + .stream()
117 + .filter((expected) -> expected.equals(bucket))
118 + .findFirst();
119 + assertEquals(matched.get().packets(),
120 + bucket.packets());
121 + assertEquals(matched.get().bytes(),
122 + bucket.bytes());
123 + }
124 + assertEquals(Group.GroupState.ADDED,
125 + event.subject().state());
103 } else if (expectedEvent == GroupEvent.Type.GROUP_UPDATE_REQUESTED) { 126 } else if (expectedEvent == GroupEvent.Type.GROUP_UPDATE_REQUESTED) {
104 assertEquals(Group.GroupState.PENDING_UPDATE, 127 assertEquals(Group.GroupState.PENDING_UPDATE,
105 event.subject().state()); 128 event.subject().state());
...@@ -243,13 +266,33 @@ public class SimpleGroupStoreTest { ...@@ -243,13 +266,33 @@ public class SimpleGroupStoreTest {
243 // Testing addOrUpdateGroupEntry operation from southbound 266 // Testing addOrUpdateGroupEntry operation from southbound
244 private void testUpdateGroupEntryFromSB(GroupKey currKey) { 267 private void testUpdateGroupEntryFromSB(GroupKey currKey) {
245 Group existingGroup = simpleGroupStore.getGroup(D1, currKey); 268 Group existingGroup = simpleGroupStore.getGroup(D1, currKey);
269 + int totalPkts = 0;
270 + int totalBytes = 0;
271 + List<GroupBucket> newBucketList = new ArrayList<GroupBucket>();
272 + for (GroupBucket bucket:existingGroup.buckets().buckets()) {
273 + StoredGroupBucketEntry newBucket =
274 + (StoredGroupBucketEntry)
275 + DefaultGroupBucket.createSelectGroupBucket(bucket.treatment());
276 + newBucket.setPackets(10);
277 + newBucket.setBytes(10 * 256 * 8);
278 + totalPkts += 10;
279 + totalBytes += 10 * 256 * 8;
280 + newBucketList.add(newBucket);
281 + }
282 + GroupBuckets updatedBuckets = new GroupBuckets(newBucketList);
283 + Group updatedGroup = new DefaultGroup(existingGroup.id(),
284 + existingGroup.deviceId(),
285 + existingGroup.type(),
286 + updatedBuckets);
287 + ((StoredGroupEntry) updatedGroup).setPackets(totalPkts);
288 + ((StoredGroupEntry) updatedGroup).setBytes(totalBytes);
246 289
247 InternalGroupStoreDelegate updateGroupEntryDelegate = 290 InternalGroupStoreDelegate updateGroupEntryDelegate =
248 new InternalGroupStoreDelegate(currKey, 291 new InternalGroupStoreDelegate(currKey,
249 - existingGroup.buckets(), 292 + updatedBuckets,
250 GroupEvent.Type.GROUP_UPDATED); 293 GroupEvent.Type.GROUP_UPDATED);
251 simpleGroupStore.setDelegate(updateGroupEntryDelegate); 294 simpleGroupStore.setDelegate(updateGroupEntryDelegate);
252 - simpleGroupStore.addOrUpdateGroupEntry(existingGroup); 295 + simpleGroupStore.addOrUpdateGroupEntry(updatedGroup);
253 simpleGroupStore.unsetDelegate(updateGroupEntryDelegate); 296 simpleGroupStore.unsetDelegate(updateGroupEntryDelegate);
254 } 297 }
255 298
......
...@@ -17,6 +17,7 @@ ...@@ -17,6 +17,7 @@
17 package org.onosproject.provider.of.group.impl; 17 package org.onosproject.provider.of.group.impl;
18 18
19 import com.google.common.collect.Maps; 19 import com.google.common.collect.Maps;
20 +
20 import org.apache.felix.scr.annotations.Activate; 21 import org.apache.felix.scr.annotations.Activate;
21 import org.apache.felix.scr.annotations.Component; 22 import org.apache.felix.scr.annotations.Component;
22 import org.apache.felix.scr.annotations.Deactivate; 23 import org.apache.felix.scr.annotations.Deactivate;
...@@ -34,6 +35,7 @@ import org.onosproject.net.group.GroupOperations; ...@@ -34,6 +35,7 @@ import org.onosproject.net.group.GroupOperations;
34 import org.onosproject.net.group.GroupProvider; 35 import org.onosproject.net.group.GroupProvider;
35 import org.onosproject.net.group.GroupProviderRegistry; 36 import org.onosproject.net.group.GroupProviderRegistry;
36 import org.onosproject.net.group.GroupProviderService; 37 import org.onosproject.net.group.GroupProviderService;
38 +import org.onosproject.net.group.StoredGroupBucketEntry;
37 import org.onosproject.net.provider.AbstractProvider; 39 import org.onosproject.net.provider.AbstractProvider;
38 import org.onosproject.net.provider.ProviderId; 40 import org.onosproject.net.provider.ProviderId;
39 import org.onosproject.openflow.controller.Dpid; 41 import org.onosproject.openflow.controller.Dpid;
...@@ -42,6 +44,7 @@ import org.onosproject.openflow.controller.OpenFlowEventListener; ...@@ -42,6 +44,7 @@ import org.onosproject.openflow.controller.OpenFlowEventListener;
42 import org.onosproject.openflow.controller.OpenFlowSwitch; 44 import org.onosproject.openflow.controller.OpenFlowSwitch;
43 import org.onosproject.openflow.controller.OpenFlowSwitchListener; 45 import org.onosproject.openflow.controller.OpenFlowSwitchListener;
44 import org.onosproject.openflow.controller.RoleState; 46 import org.onosproject.openflow.controller.RoleState;
47 +import org.projectfloodlight.openflow.protocol.OFBucketCounter;
45 import org.projectfloodlight.openflow.protocol.OFErrorMsg; 48 import org.projectfloodlight.openflow.protocol.OFErrorMsg;
46 import org.projectfloodlight.openflow.protocol.OFErrorType; 49 import org.projectfloodlight.openflow.protocol.OFErrorType;
47 import org.projectfloodlight.openflow.protocol.OFGroupDescStatsEntry; 50 import org.projectfloodlight.openflow.protocol.OFGroupDescStatsEntry;
...@@ -208,6 +211,7 @@ public class OpenFlowGroupProvider extends AbstractProvider implements GroupProv ...@@ -208,6 +211,7 @@ public class OpenFlowGroupProvider extends AbstractProvider implements GroupProv
208 211
209 Map<Integer, Group> groups = Maps.newHashMap(); 212 Map<Integer, Group> groups = Maps.newHashMap();
210 213
214 +
211 for (OFGroupDescStatsEntry entry: groupDescStatsReply.getEntries()) { 215 for (OFGroupDescStatsEntry entry: groupDescStatsReply.getEntries()) {
212 int id = entry.getGroup().getGroupNumber(); 216 int id = entry.getGroup().getGroupNumber();
213 GroupId groupId = new DefaultGroupId(id); 217 GroupId groupId = new DefaultGroupId(id);
...@@ -226,6 +230,19 @@ public class OpenFlowGroupProvider extends AbstractProvider implements GroupProv ...@@ -226,6 +230,19 @@ public class OpenFlowGroupProvider extends AbstractProvider implements GroupProv
226 group.setLife(entry.getDurationSec()); 230 group.setLife(entry.getDurationSec());
227 group.setPackets(entry.getPacketCount().getValue()); 231 group.setPackets(entry.getPacketCount().getValue());
228 group.setReferenceCount(entry.getRefCount()); 232 group.setReferenceCount(entry.getRefCount());
233 + int bucketIndex = 0;
234 + for (OFBucketCounter bucketStats:entry.getBucketStats()) {
235 + ((StoredGroupBucketEntry) group.buckets().buckets()
236 + .get(bucketIndex))
237 + .setPackets(bucketStats
238 + .getPacketCount().getValue());
239 + ((StoredGroupBucketEntry) group.buckets().buckets()
240 + .get(bucketIndex))
241 + .setBytes(entry.getBucketStats()
242 + .get(bucketIndex)
243 + .getByteCount().getValue());
244 + bucketIndex++;
245 + }
229 } 246 }
230 } 247 }
231 248
......