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