Committed by
Gerrit Code Review
GUI -- Added port-statistics traffic visualization to the topo view.
Change-Id: I52b3c1739cc50a026c0796819d61ec1898937ced
Showing
9 changed files
with
310 additions
and
61 deletions
| ... | @@ -26,13 +26,14 @@ public class DefaultLoad implements Load { | ... | @@ -26,13 +26,14 @@ public class DefaultLoad implements Load { |
| 26 | private final long current; | 26 | private final long current; |
| 27 | private final long previous; | 27 | private final long previous; |
| 28 | private final long time; | 28 | private final long time; |
| 29 | + private final int interval; | ||
| 29 | 30 | ||
| 30 | /** | 31 | /** |
| 31 | * Indicates the flow statistics poll interval in seconds. | 32 | * Indicates the flow statistics poll interval in seconds. |
| 32 | */ | 33 | */ |
| 33 | private static int pollInterval = 10; | 34 | private static int pollInterval = 10; |
| 34 | 35 | ||
| 35 | - /** | 36 | + /** |
| 36 | * Creates an invalid load. | 37 | * Creates an invalid load. |
| 37 | */ | 38 | */ |
| 38 | public DefaultLoad() { | 39 | public DefaultLoad() { |
| ... | @@ -40,18 +41,32 @@ public class DefaultLoad implements Load { | ... | @@ -40,18 +41,32 @@ public class DefaultLoad implements Load { |
| 40 | this.time = System.currentTimeMillis(); | 41 | this.time = System.currentTimeMillis(); |
| 41 | this.current = -1; | 42 | this.current = -1; |
| 42 | this.previous = -1; | 43 | this.previous = -1; |
| 44 | + this.interval = pollInterval; | ||
| 43 | } | 45 | } |
| 44 | 46 | ||
| 45 | /** | 47 | /** |
| 46 | * Creates a load value from the parameters. | 48 | * Creates a load value from the parameters. |
| 47 | - * @param current the current value | 49 | + * |
| 50 | + * @param current the current value | ||
| 48 | * @param previous the previous value | 51 | * @param previous the previous value |
| 49 | */ | 52 | */ |
| 50 | public DefaultLoad(long current, long previous) { | 53 | public DefaultLoad(long current, long previous) { |
| 54 | + this(current, previous, pollInterval); | ||
| 55 | + } | ||
| 56 | + | ||
| 57 | + /** | ||
| 58 | + * Creates a load value from the parameters. | ||
| 59 | + * | ||
| 60 | + * @param current the current value | ||
| 61 | + * @param previous the previous value | ||
| 62 | + * @param interval poll interval for this load | ||
| 63 | + */ | ||
| 64 | + public DefaultLoad(long current, long previous, int interval) { | ||
| 51 | this.current = current; | 65 | this.current = current; |
| 52 | this.previous = previous; | 66 | this.previous = previous; |
| 53 | this.time = System.currentTimeMillis(); | 67 | this.time = System.currentTimeMillis(); |
| 54 | this.isValid = true; | 68 | this.isValid = true; |
| 69 | + this.interval = interval; | ||
| 55 | } | 70 | } |
| 56 | 71 | ||
| 57 | /** | 72 | /** |
| ... | @@ -66,7 +81,7 @@ public class DefaultLoad implements Load { | ... | @@ -66,7 +81,7 @@ public class DefaultLoad implements Load { |
| 66 | 81 | ||
| 67 | @Override | 82 | @Override |
| 68 | public long rate() { | 83 | public long rate() { |
| 69 | - return (current - previous) / pollInterval; | 84 | + return (current - previous) / interval; |
| 70 | } | 85 | } |
| 71 | 86 | ||
| 72 | @Override | 87 | @Override | ... | ... |
| 1 | +/* | ||
| 2 | + * Copyright 2015 Open Networking Laboratory | ||
| 3 | + * | ||
| 4 | + * Licensed under the Apache License, Version 2.0 (the "License"); | ||
| 5 | + * you may not use this file except in compliance with the License. | ||
| 6 | + * You may obtain a copy of the License at | ||
| 7 | + * | ||
| 8 | + * http://www.apache.org/licenses/LICENSE-2.0 | ||
| 9 | + * | ||
| 10 | + * Unless required by applicable law or agreed to in writing, software | ||
| 11 | + * distributed under the License is distributed on an "AS IS" BASIS, | ||
| 12 | + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
| 13 | + * See the License for the specific language governing permissions and | ||
| 14 | + * limitations under the License. | ||
| 15 | + */ | ||
| 16 | +package org.onosproject.incubator.net; | ||
| 17 | + | ||
| 18 | +import org.onosproject.net.ConnectPoint; | ||
| 19 | +import org.onosproject.net.statistic.Load; | ||
| 20 | + | ||
| 21 | +/** | ||
| 22 | + * Service for obtaining statistic information about device ports. | ||
| 23 | + */ | ||
| 24 | +public interface PortStatisticsService { | ||
| 25 | + | ||
| 26 | + /** | ||
| 27 | + * Obtain the egress load for the given port. | ||
| 28 | + * | ||
| 29 | + * @param connectPoint the port to query | ||
| 30 | + * @return egress traffic load | ||
| 31 | + */ | ||
| 32 | + Load load(ConnectPoint connectPoint); | ||
| 33 | + | ||
| 34 | +} |
incubator/net/src/main/java/org/onosproject/incubator/net/impl/PortStatisticsManager.java
0 → 100644
| 1 | +/* | ||
| 2 | + * Copyright 2015 Open Networking Laboratory | ||
| 3 | + * | ||
| 4 | + * Licensed under the Apache License, Version 2.0 (the "License"); | ||
| 5 | + * you may not use this file except in compliance with the License. | ||
| 6 | + * You may obtain a copy of the License at | ||
| 7 | + * | ||
| 8 | + * http://www.apache.org/licenses/LICENSE-2.0 | ||
| 9 | + * | ||
| 10 | + * Unless required by applicable law or agreed to in writing, software | ||
| 11 | + * distributed under the License is distributed on an "AS IS" BASIS, | ||
| 12 | + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
| 13 | + * See the License for the specific language governing permissions and | ||
| 14 | + * limitations under the License. | ||
| 15 | + */ | ||
| 16 | +package org.onosproject.incubator.net.impl; | ||
| 17 | + | ||
| 18 | +import com.google.common.collect.Maps; | ||
| 19 | +import org.apache.felix.scr.annotations.Activate; | ||
| 20 | +import org.apache.felix.scr.annotations.Component; | ||
| 21 | +import org.apache.felix.scr.annotations.Deactivate; | ||
| 22 | +import org.apache.felix.scr.annotations.Reference; | ||
| 23 | +import org.apache.felix.scr.annotations.ReferenceCardinality; | ||
| 24 | +import org.apache.felix.scr.annotations.Service; | ||
| 25 | +import org.onosproject.incubator.net.PortStatisticsService; | ||
| 26 | +import org.onosproject.net.ConnectPoint; | ||
| 27 | +import org.onosproject.net.DeviceId; | ||
| 28 | +import org.onosproject.net.device.DeviceEvent; | ||
| 29 | +import org.onosproject.net.device.DeviceListener; | ||
| 30 | +import org.onosproject.net.device.DeviceService; | ||
| 31 | +import org.onosproject.net.device.PortStatistics; | ||
| 32 | +import org.onosproject.net.statistic.DefaultLoad; | ||
| 33 | +import org.onosproject.net.statistic.Load; | ||
| 34 | +import org.slf4j.Logger; | ||
| 35 | + | ||
| 36 | +import java.util.Map; | ||
| 37 | +import java.util.stream.Collectors; | ||
| 38 | + | ||
| 39 | +import static org.onosproject.net.PortNumber.portNumber; | ||
| 40 | +import static org.onosproject.net.device.DeviceEvent.Type.*; | ||
| 41 | +import static org.slf4j.LoggerFactory.getLogger; | ||
| 42 | + | ||
| 43 | +/** | ||
| 44 | + * Implementation of the port statistics service. | ||
| 45 | + */ | ||
| 46 | +@Component(immediate = true) | ||
| 47 | +@Service | ||
| 48 | +public class PortStatisticsManager implements PortStatisticsService { | ||
| 49 | + private final Logger log = getLogger(getClass()); | ||
| 50 | + | ||
| 51 | + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) | ||
| 52 | + protected DeviceService deviceService; | ||
| 53 | + | ||
| 54 | + private final DeviceListener deviceListener = new InternalDeviceListener(); | ||
| 55 | + | ||
| 56 | + private Map<ConnectPoint, DataPoint> current = Maps.newConcurrentMap(); | ||
| 57 | + private Map<ConnectPoint, DataPoint> previous = Maps.newConcurrentMap(); | ||
| 58 | + | ||
| 59 | + @Activate | ||
| 60 | + public void activate() { | ||
| 61 | + deviceService.addListener(deviceListener); | ||
| 62 | + log.info("Started"); | ||
| 63 | + | ||
| 64 | + } | ||
| 65 | + | ||
| 66 | + @Deactivate | ||
| 67 | + public void deactivate() { | ||
| 68 | + deviceService.removeListener(deviceListener); | ||
| 69 | + log.info("Stopped"); | ||
| 70 | + } | ||
| 71 | + | ||
| 72 | + @Override | ||
| 73 | + public Load load(ConnectPoint connectPoint) { | ||
| 74 | + DataPoint c = current.get(connectPoint); | ||
| 75 | + DataPoint p = previous.get(connectPoint); | ||
| 76 | + if (c != null && p != null) { | ||
| 77 | + return new DefaultLoad(c.stats.bytesSent(), p.stats.bytesSent(), | ||
| 78 | + (int) (c.time - p.time) / 1000); | ||
| 79 | + } | ||
| 80 | + return null; | ||
| 81 | + } | ||
| 82 | + | ||
| 83 | + // Monitors port stats update messages. | ||
| 84 | + private class InternalDeviceListener implements DeviceListener { | ||
| 85 | + @Override | ||
| 86 | + public void event(DeviceEvent event) { | ||
| 87 | + DeviceEvent.Type type = event.type(); | ||
| 88 | + DeviceId deviceId = event.subject().id(); | ||
| 89 | + if (type == PORT_STATS_UPDATED) { | ||
| 90 | + // Update port load | ||
| 91 | + updateDeviceData(deviceId); | ||
| 92 | + | ||
| 93 | + } else if (type == DEVICE_REMOVED || | ||
| 94 | + (type == DEVICE_AVAILABILITY_CHANGED && | ||
| 95 | + !deviceService.isAvailable(deviceId))) { | ||
| 96 | + // Clean-up all port loads | ||
| 97 | + pruneDeviceData(deviceId); | ||
| 98 | + } | ||
| 99 | + } | ||
| 100 | + } | ||
| 101 | + | ||
| 102 | + // Updates the port stats for the specified device | ||
| 103 | + private void updateDeviceData(DeviceId deviceId) { | ||
| 104 | + deviceService.getPortStatistics(deviceId) | ||
| 105 | + .forEach(stats -> updatePortData(deviceId, stats)); | ||
| 106 | + } | ||
| 107 | + | ||
| 108 | + // Updates the port stats for the specified port | ||
| 109 | + private void updatePortData(DeviceId deviceId, PortStatistics stats) { | ||
| 110 | + ConnectPoint cp = new ConnectPoint(deviceId, portNumber(stats.port())); | ||
| 111 | + | ||
| 112 | + // If we have a current data point, demote it to previous | ||
| 113 | + DataPoint c = current.get(cp); | ||
| 114 | + if (c != null) { | ||
| 115 | + previous.put(cp, c); | ||
| 116 | + } | ||
| 117 | + | ||
| 118 | + // Create a new data point and make it the current one | ||
| 119 | + current.put(cp, new DataPoint(stats)); | ||
| 120 | + } | ||
| 121 | + | ||
| 122 | + // Cleans all port loads for the specified device | ||
| 123 | + private void pruneDeviceData(DeviceId deviceId) { | ||
| 124 | + pruneMap(current, deviceId); | ||
| 125 | + pruneMap(previous, deviceId); | ||
| 126 | + } | ||
| 127 | + | ||
| 128 | + private void pruneMap(Map<ConnectPoint, DataPoint> map, DeviceId deviceId) { | ||
| 129 | + map.keySet().stream().filter(cp -> deviceId.equals(cp.deviceId())) | ||
| 130 | + .collect(Collectors.toSet()).forEach(map::remove); | ||
| 131 | + } | ||
| 132 | + | ||
| 133 | + // Auxiliary data point to track when we receive different samples. | ||
| 134 | + private class DataPoint { | ||
| 135 | + long time; | ||
| 136 | + PortStatistics stats; | ||
| 137 | + | ||
| 138 | + DataPoint(PortStatistics stats) { | ||
| 139 | + time = System.currentTimeMillis(); | ||
| 140 | + this.stats = stats; | ||
| 141 | + } | ||
| 142 | + } | ||
| 143 | + | ||
| 144 | +} |
| ... | @@ -15,14 +15,15 @@ | ... | @@ -15,14 +15,15 @@ |
| 15 | */ | 15 | */ |
| 16 | package org.onosproject.provider.of.device.impl; | 16 | package org.onosproject.provider.of.device.impl; |
| 17 | 17 | ||
| 18 | +import com.google.common.base.Strings; | ||
| 18 | import com.google.common.collect.Maps; | 19 | import com.google.common.collect.Maps; |
| 19 | import com.google.common.collect.Sets; | 20 | import com.google.common.collect.Sets; |
| 20 | - | ||
| 21 | import org.apache.felix.scr.annotations.Activate; | 21 | import org.apache.felix.scr.annotations.Activate; |
| 22 | import org.apache.felix.scr.annotations.Component; | 22 | import org.apache.felix.scr.annotations.Component; |
| 23 | import org.apache.felix.scr.annotations.Deactivate; | 23 | import org.apache.felix.scr.annotations.Deactivate; |
| 24 | import org.apache.felix.scr.annotations.Reference; | 24 | import org.apache.felix.scr.annotations.Reference; |
| 25 | import org.apache.felix.scr.annotations.ReferenceCardinality; | 25 | import org.apache.felix.scr.annotations.ReferenceCardinality; |
| 26 | +import org.onlab.packet.ChassisId; | ||
| 26 | import org.onosproject.net.AnnotationKeys; | 27 | import org.onosproject.net.AnnotationKeys; |
| 27 | import org.onosproject.net.DefaultAnnotations; | 28 | import org.onosproject.net.DefaultAnnotations; |
| 28 | import org.onosproject.net.Device; | 29 | import org.onosproject.net.Device; |
| ... | @@ -50,7 +51,6 @@ import org.onosproject.openflow.controller.OpenFlowSwitch; | ... | @@ -50,7 +51,6 @@ import org.onosproject.openflow.controller.OpenFlowSwitch; |
| 50 | import org.onosproject.openflow.controller.OpenFlowSwitchListener; | 51 | import org.onosproject.openflow.controller.OpenFlowSwitchListener; |
| 51 | import org.onosproject.openflow.controller.PortDescPropertyType; | 52 | import org.onosproject.openflow.controller.PortDescPropertyType; |
| 52 | import org.onosproject.openflow.controller.RoleState; | 53 | import org.onosproject.openflow.controller.RoleState; |
| 53 | -import org.onlab.packet.ChassisId; | ||
| 54 | import org.projectfloodlight.openflow.protocol.OFFactory; | 54 | import org.projectfloodlight.openflow.protocol.OFFactory; |
| 55 | import org.projectfloodlight.openflow.protocol.OFMessage; | 55 | import org.projectfloodlight.openflow.protocol.OFMessage; |
| 56 | import org.projectfloodlight.openflow.protocol.OFPortConfig; | 56 | import org.projectfloodlight.openflow.protocol.OFPortConfig; |
| ... | @@ -75,8 +75,6 @@ import java.util.HashMap; | ... | @@ -75,8 +75,6 @@ import java.util.HashMap; |
| 75 | import java.util.HashSet; | 75 | import java.util.HashSet; |
| 76 | import java.util.List; | 76 | import java.util.List; |
| 77 | 77 | ||
| 78 | -import com.google.common.base.Strings; | ||
| 79 | - | ||
| 80 | import static org.onosproject.net.DeviceId.deviceId; | 78 | import static org.onosproject.net.DeviceId.deviceId; |
| 81 | import static org.onosproject.net.Port.Type.COPPER; | 79 | import static org.onosproject.net.Port.Type.COPPER; |
| 82 | import static org.onosproject.net.Port.Type.FIBER; | 80 | import static org.onosproject.net.Port.Type.FIBER; |
| ... | @@ -204,36 +202,37 @@ public class OpenFlowDeviceProvider extends AbstractProvider implements DevicePr | ... | @@ -204,36 +202,37 @@ public class OpenFlowDeviceProvider extends AbstractProvider implements DevicePr |
| 204 | 202 | ||
| 205 | private void pushPortMetrics(Dpid dpid, OFPortStatsReply msg) { | 203 | private void pushPortMetrics(Dpid dpid, OFPortStatsReply msg) { |
| 206 | DeviceId deviceId = DeviceId.deviceId(dpid.uri(dpid)); | 204 | DeviceId deviceId = DeviceId.deviceId(dpid.uri(dpid)); |
| 207 | - | ||
| 208 | Collection<PortStatistics> stats = buildPortStatistics(deviceId, msg); | 205 | Collection<PortStatistics> stats = buildPortStatistics(deviceId, msg); |
| 209 | - | ||
| 210 | providerService.updatePortStatistics(deviceId, stats); | 206 | providerService.updatePortStatistics(deviceId, stats); |
| 211 | } | 207 | } |
| 212 | 208 | ||
| 213 | private Collection<PortStatistics> buildPortStatistics(DeviceId deviceId, OFPortStatsReply msg) { | 209 | private Collection<PortStatistics> buildPortStatistics(DeviceId deviceId, OFPortStatsReply msg) { |
| 214 | - | ||
| 215 | HashSet<PortStatistics> stats = Sets.newHashSet(); | 210 | HashSet<PortStatistics> stats = Sets.newHashSet(); |
| 216 | 211 | ||
| 217 | for (OFPortStatsEntry entry: msg.getEntries()) { | 212 | for (OFPortStatsEntry entry: msg.getEntries()) { |
| 218 | - if (entry.getPortNo().getPortNumber() < 0) { | 213 | + try { |
| 219 | - continue; | 214 | + if (entry.getPortNo().getPortNumber() < 0) { |
| 215 | + continue; | ||
| 216 | + } | ||
| 217 | + DefaultPortStatistics.Builder builder = DefaultPortStatistics.builder(); | ||
| 218 | + DefaultPortStatistics stat = builder.setDeviceId(deviceId) | ||
| 219 | + .setPort(entry.getPortNo().getPortNumber()) | ||
| 220 | + .setPacketsReceived(entry.getRxPackets().getValue()) | ||
| 221 | + .setPacketsSent(entry.getTxPackets().getValue()) | ||
| 222 | + .setBytesReceived(entry.getRxBytes().getValue()) | ||
| 223 | + .setBytesSent(entry.getTxBytes().getValue()) | ||
| 224 | + .setPacketsRxDropped(entry.getRxDropped().getValue()) | ||
| 225 | + .setPacketsTxDropped(entry.getTxDropped().getValue()) | ||
| 226 | + .setPacketsRxErrors(entry.getRxErrors().getValue()) | ||
| 227 | + .setPacketsTxErrors(entry.getTxErrors().getValue()) | ||
| 228 | + .setDurationSec(entry.getVersion() == OFVersion.OF_10 ? 0 : entry.getDurationSec()) | ||
| 229 | + .setDurationNano(entry.getVersion() == OFVersion.OF_10 ? 0 : entry.getDurationNsec()) | ||
| 230 | + .build(); | ||
| 231 | + | ||
| 232 | + stats.add(stat); | ||
| 233 | + } catch (Exception e) { | ||
| 234 | + LOG.warn("Unable to process port stats", e); | ||
| 220 | } | 235 | } |
| 221 | - DefaultPortStatistics.Builder builder = DefaultPortStatistics.builder(); | ||
| 222 | - DefaultPortStatistics stat = builder.setDeviceId(deviceId) | ||
| 223 | - .setPort(entry.getPortNo().getPortNumber()) | ||
| 224 | - .setPacketsReceived(entry.getRxPackets().getValue()) | ||
| 225 | - .setPacketsSent(entry.getTxPackets().getValue()) | ||
| 226 | - .setBytesReceived(entry.getRxBytes().getValue()) | ||
| 227 | - .setBytesSent(entry.getTxBytes().getValue()) | ||
| 228 | - .setPacketsRxDropped(entry.getRxDropped().getValue()) | ||
| 229 | - .setPacketsTxDropped(entry.getTxDropped().getValue()) | ||
| 230 | - .setPacketsRxErrors(entry.getRxErrors().getValue()) | ||
| 231 | - .setPacketsTxErrors(entry.getTxErrors().getValue()) | ||
| 232 | - .setDurationSec(entry.getDurationSec()) | ||
| 233 | - .setDurationNano(entry.getDurationNsec()) | ||
| 234 | - .build(); | ||
| 235 | - | ||
| 236 | - stats.add(stat); | ||
| 237 | } | 236 | } |
| 238 | 237 | ||
| 239 | return Collections.unmodifiableSet(stats); | 238 | return Collections.unmodifiableSet(stats); | ... | ... |
| ... | @@ -92,7 +92,8 @@ public class TopologyViewMessageHandler extends TopologyViewMessageHandlerBase { | ... | @@ -92,7 +92,8 @@ public class TopologyViewMessageHandler extends TopologyViewMessageHandlerBase { |
| 92 | private static final String REQ_NEXT_INTENT = "requestNextRelatedIntent"; | 92 | private static final String REQ_NEXT_INTENT = "requestNextRelatedIntent"; |
| 93 | private static final String REQ_PREV_INTENT = "requestPrevRelatedIntent"; | 93 | private static final String REQ_PREV_INTENT = "requestPrevRelatedIntent"; |
| 94 | private static final String REQ_SEL_INTENT_TRAFFIC = "requestSelectedIntentTraffic"; | 94 | private static final String REQ_SEL_INTENT_TRAFFIC = "requestSelectedIntentTraffic"; |
| 95 | - private static final String REQ_ALL_TRAFFIC = "requestAllTraffic"; | 95 | + private static final String REQ_ALL_FLOW_TRAFFIC = "requestAllFlowTraffic"; |
| 96 | + private static final String REQ_ALL_PORT_TRAFFIC = "requestAllPortTraffic"; | ||
| 96 | private static final String REQ_DEV_LINK_FLOWS = "requestDeviceLinkFlows"; | 97 | private static final String REQ_DEV_LINK_FLOWS = "requestDeviceLinkFlows"; |
| 97 | private static final String CANCEL_TRAFFIC = "cancelTraffic"; | 98 | private static final String CANCEL_TRAFFIC = "cancelTraffic"; |
| 98 | private static final String REQ_SUMMARY = "requestSummary"; | 99 | private static final String REQ_SUMMARY = "requestSummary"; |
| ... | @@ -187,7 +188,8 @@ public class TopologyViewMessageHandler extends TopologyViewMessageHandlerBase { | ... | @@ -187,7 +188,8 @@ public class TopologyViewMessageHandler extends TopologyViewMessageHandlerBase { |
| 187 | new ReqNextIntent(), | 188 | new ReqNextIntent(), |
| 188 | new ReqPrevIntent(), | 189 | new ReqPrevIntent(), |
| 189 | new ReqSelectedIntentTraffic(), | 190 | new ReqSelectedIntentTraffic(), |
| 190 | - new ReqAllTraffic(), | 191 | + new ReqAllFlowTraffic(), |
| 192 | + new ReqAllPortTraffic(), | ||
| 191 | new ReqDevLinkFlows(), | 193 | new ReqDevLinkFlows(), |
| 192 | new CancelTraffic() | 194 | new CancelTraffic() |
| 193 | ); | 195 | ); |
| ... | @@ -453,23 +455,33 @@ public class TopologyViewMessageHandler extends TopologyViewMessageHandlerBase { | ... | @@ -453,23 +455,33 @@ public class TopologyViewMessageHandler extends TopologyViewMessageHandlerBase { |
| 453 | 455 | ||
| 454 | @Override | 456 | @Override |
| 455 | public void process(long sid, ObjectNode payload) { | 457 | public void process(long sid, ObjectNode payload) { |
| 456 | - trafficEvent = | 458 | + trafficEvent = new TrafficEvent(TrafficEvent.Type.SEL_INTENT, payload); |
| 457 | - new TrafficEvent(TrafficEvent.Type.SEL_INTENT, payload); | ||
| 458 | requestSelectedIntentTraffic(); | 459 | requestSelectedIntentTraffic(); |
| 459 | startTrafficMonitoring(); | 460 | startTrafficMonitoring(); |
| 460 | } | 461 | } |
| 461 | } | 462 | } |
| 462 | 463 | ||
| 463 | - private final class ReqAllTraffic extends RequestHandler { | 464 | + private final class ReqAllFlowTraffic extends RequestHandler { |
| 464 | - private ReqAllTraffic() { | 465 | + private ReqAllFlowTraffic() { |
| 465 | - super(REQ_ALL_TRAFFIC); | 466 | + super(REQ_ALL_FLOW_TRAFFIC); |
| 466 | } | 467 | } |
| 467 | 468 | ||
| 468 | @Override | 469 | @Override |
| 469 | public void process(long sid, ObjectNode payload) { | 470 | public void process(long sid, ObjectNode payload) { |
| 470 | - trafficEvent = | 471 | + trafficEvent = new TrafficEvent(TrafficEvent.Type.ALL_FLOW_TRAFFIC, payload); |
| 471 | - new TrafficEvent(TrafficEvent.Type.ALL_TRAFFIC, payload); | 472 | + requestAllFlowTraffic(); |
| 472 | - requestAllTraffic(); | 473 | + } |
| 474 | + } | ||
| 475 | + | ||
| 476 | + private final class ReqAllPortTraffic extends RequestHandler { | ||
| 477 | + private ReqAllPortTraffic() { | ||
| 478 | + super(REQ_ALL_PORT_TRAFFIC); | ||
| 479 | + } | ||
| 480 | + | ||
| 481 | + @Override | ||
| 482 | + public void process(long sid, ObjectNode payload) { | ||
| 483 | + trafficEvent = new TrafficEvent(TrafficEvent.Type.ALL_PORT_TRAFFIC, payload); | ||
| 484 | + requestAllPortTraffic(); | ||
| 473 | } | 485 | } |
| 474 | } | 486 | } |
| 475 | 487 | ||
| ... | @@ -480,8 +492,7 @@ public class TopologyViewMessageHandler extends TopologyViewMessageHandlerBase { | ... | @@ -480,8 +492,7 @@ public class TopologyViewMessageHandler extends TopologyViewMessageHandlerBase { |
| 480 | 492 | ||
| 481 | @Override | 493 | @Override |
| 482 | public void process(long sid, ObjectNode payload) { | 494 | public void process(long sid, ObjectNode payload) { |
| 483 | - trafficEvent = | 495 | + trafficEvent = new TrafficEvent(TrafficEvent.Type.DEV_LINK_FLOWS, payload); |
| 484 | - new TrafficEvent(TrafficEvent.Type.DEV_LINK_FLOWS, payload); | ||
| 485 | requestDeviceLinkFlows(payload); | 496 | requestDeviceLinkFlows(payload); |
| 486 | } | 497 | } |
| 487 | } | 498 | } |
| ... | @@ -615,10 +626,16 @@ public class TopologyViewMessageHandler extends TopologyViewMessageHandlerBase { | ... | @@ -615,10 +626,16 @@ public class TopologyViewMessageHandler extends TopologyViewMessageHandlerBase { |
| 615 | } | 626 | } |
| 616 | } | 627 | } |
| 617 | 628 | ||
| 618 | - // Subscribes for host traffic messages. | 629 | + // Subscribes for flow traffic messages. |
| 619 | - private synchronized void requestAllTraffic() { | 630 | + private synchronized void requestAllFlowTraffic() { |
| 620 | startTrafficMonitoring(); | 631 | startTrafficMonitoring(); |
| 621 | - sendMessage(trafficSummaryMessage()); | 632 | + sendMessage(trafficSummaryMessage(StatsType.FLOW)); |
| 633 | + } | ||
| 634 | + | ||
| 635 | + // Subscribes for port traffic messages. | ||
| 636 | + private synchronized void requestAllPortTraffic() { | ||
| 637 | + startTrafficMonitoring(); | ||
| 638 | + sendMessage(trafficSummaryMessage(StatsType.PORT)); | ||
| 622 | } | 639 | } |
| 623 | 640 | ||
| 624 | private void requestDeviceLinkFlows(ObjectNode payload) { | 641 | private void requestDeviceLinkFlows(ObjectNode payload) { |
| ... | @@ -822,7 +839,7 @@ public class TopologyViewMessageHandler extends TopologyViewMessageHandlerBase { | ... | @@ -822,7 +839,7 @@ public class TopologyViewMessageHandler extends TopologyViewMessageHandlerBase { |
| 822 | // encapsulate | 839 | // encapsulate |
| 823 | private static class TrafficEvent { | 840 | private static class TrafficEvent { |
| 824 | enum Type { | 841 | enum Type { |
| 825 | - ALL_TRAFFIC, DEV_LINK_FLOWS, SEL_INTENT | 842 | + ALL_FLOW_TRAFFIC, ALL_PORT_TRAFFIC, DEV_LINK_FLOWS, SEL_INTENT |
| 826 | } | 843 | } |
| 827 | 844 | ||
| 828 | private final Type type; | 845 | private final Type type; |
| ... | @@ -841,8 +858,11 @@ public class TopologyViewMessageHandler extends TopologyViewMessageHandlerBase { | ... | @@ -841,8 +858,11 @@ public class TopologyViewMessageHandler extends TopologyViewMessageHandlerBase { |
| 841 | try { | 858 | try { |
| 842 | if (trafficEvent != null) { | 859 | if (trafficEvent != null) { |
| 843 | switch (trafficEvent.type) { | 860 | switch (trafficEvent.type) { |
| 844 | - case ALL_TRAFFIC: | 861 | + case ALL_FLOW_TRAFFIC: |
| 845 | - requestAllTraffic(); | 862 | + requestAllFlowTraffic(); |
| 863 | + break; | ||
| 864 | + case ALL_PORT_TRAFFIC: | ||
| 865 | + requestAllPortTraffic(); | ||
| 846 | break; | 866 | break; |
| 847 | case DEV_LINK_FLOWS: | 867 | case DEV_LINK_FLOWS: |
| 848 | requestDeviceLinkFlows(trafficEvent.payload); | 868 | requestDeviceLinkFlows(trafficEvent.payload); | ... | ... |
| ... | @@ -27,6 +27,7 @@ import org.onosproject.cluster.ClusterService; | ... | @@ -27,6 +27,7 @@ import org.onosproject.cluster.ClusterService; |
| 27 | import org.onosproject.cluster.ControllerNode; | 27 | import org.onosproject.cluster.ControllerNode; |
| 28 | import org.onosproject.cluster.NodeId; | 28 | import org.onosproject.cluster.NodeId; |
| 29 | import org.onosproject.core.CoreService; | 29 | import org.onosproject.core.CoreService; |
| 30 | +import org.onosproject.incubator.net.PortStatisticsService; | ||
| 30 | import org.onosproject.mastership.MastershipService; | 31 | import org.onosproject.mastership.MastershipService; |
| 31 | import org.onosproject.net.Annotated; | 32 | import org.onosproject.net.Annotated; |
| 32 | import org.onosproject.net.AnnotationKeys; | 33 | import org.onosproject.net.AnnotationKeys; |
| ... | @@ -100,6 +101,7 @@ import static org.onosproject.net.host.HostEvent.Type.HOST_ADDED; | ... | @@ -100,6 +101,7 @@ import static org.onosproject.net.host.HostEvent.Type.HOST_ADDED; |
| 100 | import static org.onosproject.net.host.HostEvent.Type.HOST_REMOVED; | 101 | import static org.onosproject.net.host.HostEvent.Type.HOST_REMOVED; |
| 101 | import static org.onosproject.net.link.LinkEvent.Type.LINK_ADDED; | 102 | import static org.onosproject.net.link.LinkEvent.Type.LINK_ADDED; |
| 102 | import static org.onosproject.net.link.LinkEvent.Type.LINK_REMOVED; | 103 | import static org.onosproject.net.link.LinkEvent.Type.LINK_REMOVED; |
| 104 | +import static org.onosproject.ui.impl.TopologyViewMessageHandlerBase.StatsType.*; | ||
| 103 | 105 | ||
| 104 | /** | 106 | /** |
| 105 | * Facility for creating messages bound for the topology viewer. | 107 | * Facility for creating messages bound for the topology viewer. |
| ... | @@ -123,6 +125,8 @@ public abstract class TopologyViewMessageHandlerBase extends UiMessageHandler { | ... | @@ -123,6 +125,8 @@ public abstract class TopologyViewMessageHandlerBase extends UiMessageHandler { |
| 123 | private static final String KB_UNIT = "KB"; | 125 | private static final String KB_UNIT = "KB"; |
| 124 | private static final String B_UNIT = "B"; | 126 | private static final String B_UNIT = "B"; |
| 125 | 127 | ||
| 128 | + private static final long BPS_THRESHOLD = 1024; | ||
| 129 | + | ||
| 126 | protected ServiceDirectory directory; | 130 | protected ServiceDirectory directory; |
| 127 | protected ClusterService clusterService; | 131 | protected ClusterService clusterService; |
| 128 | protected DeviceService deviceService; | 132 | protected DeviceService deviceService; |
| ... | @@ -131,9 +135,14 @@ public abstract class TopologyViewMessageHandlerBase extends UiMessageHandler { | ... | @@ -131,9 +135,14 @@ public abstract class TopologyViewMessageHandlerBase extends UiMessageHandler { |
| 131 | protected MastershipService mastershipService; | 135 | protected MastershipService mastershipService; |
| 132 | protected IntentService intentService; | 136 | protected IntentService intentService; |
| 133 | protected FlowRuleService flowService; | 137 | protected FlowRuleService flowService; |
| 134 | - protected StatisticService statService; | 138 | + protected StatisticService flowStatsService; |
| 139 | + protected PortStatisticsService portStatsService; | ||
| 135 | protected TopologyService topologyService; | 140 | protected TopologyService topologyService; |
| 136 | 141 | ||
| 142 | + protected enum StatsType { | ||
| 143 | + FLOW, PORT | ||
| 144 | + } | ||
| 145 | + | ||
| 137 | private String version; | 146 | private String version; |
| 138 | 147 | ||
| 139 | // TODO: extract into an external & durable state; good enough for now and demo | 148 | // TODO: extract into an external & durable state; good enough for now and demo |
| ... | @@ -159,7 +168,8 @@ public abstract class TopologyViewMessageHandlerBase extends UiMessageHandler { | ... | @@ -159,7 +168,8 @@ public abstract class TopologyViewMessageHandlerBase extends UiMessageHandler { |
| 159 | mastershipService = directory.get(MastershipService.class); | 168 | mastershipService = directory.get(MastershipService.class); |
| 160 | intentService = directory.get(IntentService.class); | 169 | intentService = directory.get(IntentService.class); |
| 161 | flowService = directory.get(FlowRuleService.class); | 170 | flowService = directory.get(FlowRuleService.class); |
| 162 | - statService = directory.get(StatisticService.class); | 171 | + flowStatsService = directory.get(StatisticService.class); |
| 172 | + portStatsService = directory.get(PortStatisticsService.class); | ||
| 163 | topologyService = directory.get(TopologyService.class); | 173 | topologyService = directory.get(TopologyService.class); |
| 164 | 174 | ||
| 165 | String ver = directory.get(CoreService.class).version().toString(); | 175 | String ver = directory.get(CoreService.class).version().toString(); |
| ... | @@ -532,8 +542,8 @@ public abstract class TopologyViewMessageHandlerBase extends UiMessageHandler { | ... | @@ -532,8 +542,8 @@ public abstract class TopologyViewMessageHandlerBase extends UiMessageHandler { |
| 532 | } | 542 | } |
| 533 | 543 | ||
| 534 | 544 | ||
| 535 | - // Produces JSON message to trigger traffic overview visualization | 545 | + // Produces JSON message to trigger flow traffic overview visualization |
| 536 | - protected ObjectNode trafficSummaryMessage() { | 546 | + protected ObjectNode trafficSummaryMessage(StatsType type) { |
| 537 | ObjectNode payload = objectNode(); | 547 | ObjectNode payload = objectNode(); |
| 538 | ArrayNode paths = arrayNode(); | 548 | ArrayNode paths = arrayNode(); |
| 539 | payload.set("paths", paths); | 549 | payload.set("paths", paths); |
| ... | @@ -560,11 +570,18 @@ public abstract class TopologyViewMessageHandlerBase extends UiMessageHandler { | ... | @@ -560,11 +570,18 @@ public abstract class TopologyViewMessageHandlerBase extends UiMessageHandler { |
| 560 | boolean bi = link.two != null; | 570 | boolean bi = link.two != null; |
| 561 | if (isInfrastructureEgress(link.one) || | 571 | if (isInfrastructureEgress(link.one) || |
| 562 | (bi && isInfrastructureEgress(link.two))) { | 572 | (bi && isInfrastructureEgress(link.two))) { |
| 563 | - link.addLoad(statService.load(link.one)); | 573 | + if (type == FLOW) { |
| 564 | - link.addLoad(bi ? statService.load(link.two) : null); | 574 | + link.addLoad(flowStatsService.load(link.one)); |
| 575 | + link.addLoad(bi ? flowStatsService.load(link.two) : null); | ||
| 576 | + } else if (type == PORT) { | ||
| 577 | + link.addLoad(portStatsService.load(link.one.src()), BPS_THRESHOLD); | ||
| 578 | + link.addLoad(bi ? portStatsService.load(link.two.src()) : null, BPS_THRESHOLD); | ||
| 579 | + } | ||
| 565 | if (link.hasTraffic) { | 580 | if (link.hasTraffic) { |
| 566 | linksNodeT.add(compactLinkString(link.one)); | 581 | linksNodeT.add(compactLinkString(link.one)); |
| 567 | - labelsT.add(formatBytes(link.bytes)); | 582 | + labelsT.add(type == PORT ? |
| 583 | + formatBytes(link.rate) + "ps" : | ||
| 584 | + formatBytes(link.bytes)); | ||
| 568 | } else { | 585 | } else { |
| 569 | linksNodeN.add(compactLinkString(link.one)); | 586 | linksNodeN.add(compactLinkString(link.one)); |
| 570 | labelsN.add(""); | 587 | labelsN.add(""); |
| ... | @@ -692,7 +709,7 @@ public abstract class TopologyViewMessageHandlerBase extends UiMessageHandler { | ... | @@ -692,7 +709,7 @@ public abstract class TopologyViewMessageHandlerBase extends UiMessageHandler { |
| 692 | BiLink biLink = addLink(biLinks, link); | 709 | BiLink biLink = addLink(biLinks, link); |
| 693 | if (isInfrastructureEgress(link)) { | 710 | if (isInfrastructureEgress(link)) { |
| 694 | if (showTraffic) { | 711 | if (showTraffic) { |
| 695 | - biLink.addLoad(statService.load(link)); | 712 | + biLink.addLoad(flowStatsService.load(link)); |
| 696 | } | 713 | } |
| 697 | biLink.addClass(type); | 714 | biLink.addClass(type); |
| 698 | } | 715 | } |
| ... | @@ -727,7 +744,7 @@ public abstract class TopologyViewMessageHandlerBase extends UiMessageHandler { | ... | @@ -727,7 +744,7 @@ public abstract class TopologyViewMessageHandlerBase extends UiMessageHandler { |
| 727 | for (Link link : links) { | 744 | for (Link link : links) { |
| 728 | if (isInfrastructureEgress(link)) { | 745 | if (isInfrastructureEgress(link)) { |
| 729 | linksNode.add(compactLinkString(link)); | 746 | linksNode.add(compactLinkString(link)); |
| 730 | - Load load = statService.load(link); | 747 | + Load load = flowStatsService.load(link); |
| 731 | String label = ""; | 748 | String label = ""; |
| 732 | if (load.rate() > 0) { | 749 | if (load.rate() > 0) { |
| 733 | hasTraffic = true; | 750 | hasTraffic = true; |
| ... | @@ -814,6 +831,7 @@ public abstract class TopologyViewMessageHandlerBase extends UiMessageHandler { | ... | @@ -814,6 +831,7 @@ public abstract class TopologyViewMessageHandlerBase extends UiMessageHandler { |
| 814 | public long bytes = 0; | 831 | public long bytes = 0; |
| 815 | 832 | ||
| 816 | private Set<String> classes = new HashSet<>(); | 833 | private Set<String> classes = new HashSet<>(); |
| 834 | + private long rate; | ||
| 817 | 835 | ||
| 818 | BiLink(LinkKey key, Link link) { | 836 | BiLink(LinkKey key, Link link) { |
| 819 | this.key = key; | 837 | this.key = key; |
| ... | @@ -825,9 +843,14 @@ public abstract class TopologyViewMessageHandlerBase extends UiMessageHandler { | ... | @@ -825,9 +843,14 @@ public abstract class TopologyViewMessageHandlerBase extends UiMessageHandler { |
| 825 | } | 843 | } |
| 826 | 844 | ||
| 827 | void addLoad(Load load) { | 845 | void addLoad(Load load) { |
| 846 | + addLoad(load, 0); | ||
| 847 | + } | ||
| 848 | + | ||
| 849 | + void addLoad(Load load, long threshold) { | ||
| 828 | if (load != null) { | 850 | if (load != null) { |
| 829 | - this.hasTraffic = hasTraffic || load.rate() > 0; | 851 | + this.hasTraffic = hasTraffic || load.rate() > threshold; |
| 830 | this.bytes += load.latest(); | 852 | this.bytes += load.latest(); |
| 853 | + this.rate = load.rate(); | ||
| 831 | } | 854 | } |
| 832 | } | 855 | } |
| 833 | 856 | ... | ... |
| ... | @@ -67,7 +67,8 @@ | ... | @@ -67,7 +67,8 @@ |
| 67 | rightArrow: [tts.showNextIntentAction, 'Show next related intent'], | 67 | rightArrow: [tts.showNextIntentAction, 'Show next related intent'], |
| 68 | leftArrow: [tts.showPrevIntentAction, 'Show previous related intent'], | 68 | leftArrow: [tts.showPrevIntentAction, 'Show previous related intent'], |
| 69 | W: [tts.showSelectedIntentTrafficAction, 'Monitor traffic of selected intent'], | 69 | W: [tts.showSelectedIntentTrafficAction, 'Monitor traffic of selected intent'], |
| 70 | - A: [tts.showAllTrafficAction, 'Monitor all traffic'], | 70 | + A: [tts.showAllFlowTrafficAction, 'Monitor all traffic using flow stats'], |
| 71 | + Q: [tts.showAllPortTrafficAction, 'Monitor all traffic using port stats'], | ||
| 71 | F: [tts.showDeviceLinkFlowsAction, 'Show device link flows'], | 72 | F: [tts.showDeviceLinkFlowsAction, 'Show device link flows'], |
| 72 | 73 | ||
| 73 | E: [equalizeMasters, 'Equalize mastership roles'], | 74 | E: [equalizeMasters, 'Equalize mastership roles'], | ... | ... |
| ... | @@ -150,10 +150,17 @@ | ... | @@ -150,10 +150,17 @@ |
| 150 | } | 150 | } |
| 151 | 151 | ||
| 152 | // keystroke-A (see topo.js) | 152 | // keystroke-A (see topo.js) |
| 153 | - function showAllTrafficAction() { | 153 | + function showAllFlowTrafficAction() { |
| 154 | hoverMode = hoverModeAll; | 154 | hoverMode = hoverModeAll; |
| 155 | - wss.sendEvent('requestAllTraffic'); | 155 | + wss.sendEvent('requestAllFlowTraffic'); |
| 156 | - flash.flash('All Traffic'); | 156 | + flash.flash('All Flow Traffic'); |
| 157 | + } | ||
| 158 | + | ||
| 159 | + // keystroke-A (see topo.js) | ||
| 160 | + function showAllPortTrafficAction() { | ||
| 161 | + hoverMode = hoverModeAll; | ||
| 162 | + wss.sendEvent('requestAllPortTraffic'); | ||
| 163 | + flash.flash('All Port Traffic'); | ||
| 157 | } | 164 | } |
| 158 | 165 | ||
| 159 | // === ----------------------------- | 166 | // === ----------------------------- |
| ... | @@ -228,7 +235,8 @@ | ... | @@ -228,7 +235,8 @@ |
| 228 | showNextIntentAction: showNextIntentAction, | 235 | showNextIntentAction: showNextIntentAction, |
| 229 | showPrevIntentAction: showPrevIntentAction, | 236 | showPrevIntentAction: showPrevIntentAction, |
| 230 | showSelectedIntentTrafficAction: showSelectedIntentTrafficAction, | 237 | showSelectedIntentTrafficAction: showSelectedIntentTrafficAction, |
| 231 | - showAllTrafficAction: showAllTrafficAction | 238 | + showAllFlowTrafficAction: showAllFlowTrafficAction, |
| 239 | + showAllPortTrafficAction: showAllPortTrafficAction | ||
| 232 | }; | 240 | }; |
| 233 | }]); | 241 | }]); |
| 234 | }()); | 242 | }()); | ... | ... |
| ... | @@ -48,6 +48,11 @@ | ... | @@ -48,6 +48,11 @@ |
| 48 | 48 | ||
| 49 | <dependency> | 49 | <dependency> |
| 50 | <groupId>org.onosproject</groupId> | 50 | <groupId>org.onosproject</groupId> |
| 51 | + <artifactId>onos-incubator-api</artifactId> | ||
| 52 | + </dependency> | ||
| 53 | + | ||
| 54 | + <dependency> | ||
| 55 | + <groupId>org.onosproject</groupId> | ||
| 51 | <artifactId>onlab-osgi</artifactId> | 56 | <artifactId>onlab-osgi</artifactId> |
| 52 | <version>${project.version}</version> | 57 | <version>${project.version}</version> |
| 53 | </dependency> | 58 | </dependency> | ... | ... |
-
Please register or login to post a comment