Committed by
Gerrit Code Review
ONOS-1443: Group bucket statistics support and group CLI formatting
Change-Id: Iaa6d8ae1f9222eb9c29d14bf1615a7449e50c4d3
Showing
10 changed files
with
224 additions
and
19 deletions
| ... | @@ -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 | ... | ... |
-
Please register or login to post a comment