Simon Hunt

ONOS-2186 - GUI Topo Overlay - (WIP)

- split BiLink into abstract superclass and concrete subclasses.
- created BiLinkMap to collate bilinks (and derivative subclasses).
- added missing Javadocs, and other general cleanup.

Change-Id: Icfa85bc44a223c6cf245a4005170583dad1cc801
Showing 20 changed files with 724 additions and 406 deletions
...@@ -18,22 +18,38 @@ ...@@ -18,22 +18,38 @@
18 package org.onosproject.ui.topo; 18 package org.onosproject.ui.topo;
19 19
20 /** 20 /**
21 - * Partial implementation of the types of highlight to apply to topology 21 + * Partial implementation of the highlighting to apply to topology
22 - * elements. 22 + * view elements.
23 */ 23 */
24 public abstract class AbstractHighlight { 24 public abstract class AbstractHighlight {
25 private final TopoElementType type; 25 private final TopoElementType type;
26 private final String elementId; 26 private final String elementId;
27 27
28 + /**
29 + * Constructs the highlight.
30 + *
31 + * @param type highlight element type
32 + * @param elementId element identifier
33 + */
28 public AbstractHighlight(TopoElementType type, String elementId) { 34 public AbstractHighlight(TopoElementType type, String elementId) {
29 this.type = type; 35 this.type = type;
30 this.elementId = elementId; 36 this.elementId = elementId;
31 } 37 }
32 38
39 + /**
40 + * Returns the element type.
41 + *
42 + * @return element type
43 + */
33 public TopoElementType type() { 44 public TopoElementType type() {
34 return type; 45 return type;
35 } 46 }
36 47
48 + /**
49 + * Returns the element identifier.
50 + *
51 + * @return element identifier
52 + */
37 public String elementId() { 53 public String elementId() {
38 return elementId; 54 return elementId;
39 } 55 }
......
...@@ -18,7 +18,7 @@ ...@@ -18,7 +18,7 @@
18 package org.onosproject.ui.topo; 18 package org.onosproject.ui.topo;
19 19
20 /** 20 /**
21 - * Denotes the types of highlight to apply to a link. 21 + * Denotes the highlighting to apply to a device.
22 */ 22 */
23 public class DeviceHighlight extends AbstractHighlight { 23 public class DeviceHighlight extends AbstractHighlight {
24 24
...@@ -26,5 +26,8 @@ public class DeviceHighlight extends AbstractHighlight { ...@@ -26,5 +26,8 @@ public class DeviceHighlight extends AbstractHighlight {
26 super(TopoElementType.DEVICE, deviceId); 26 super(TopoElementType.DEVICE, deviceId);
27 } 27 }
28 28
29 + // TODO: implement device highlighting:
30 + // - visual highlight
31 + // - badging
29 32
30 } 33 }
......
...@@ -18,7 +18,7 @@ ...@@ -18,7 +18,7 @@
18 package org.onosproject.ui.topo; 18 package org.onosproject.ui.topo;
19 19
20 /** 20 /**
21 - * Denotes the types of highlight to apply to a link. 21 + * Denotes the highlighting to apply to a host.
22 */ 22 */
23 public class HostHighlight extends AbstractHighlight { 23 public class HostHighlight extends AbstractHighlight {
24 24
...@@ -26,5 +26,8 @@ public class HostHighlight extends AbstractHighlight { ...@@ -26,5 +26,8 @@ public class HostHighlight extends AbstractHighlight {
26 super(TopoElementType.HOST, hostId); 26 super(TopoElementType.HOST, hostId);
27 } 27 }
28 28
29 + // TODO: implement host highlighting:
30 + // - visual highlight
31 + // - badging
29 32
30 } 33 }
......
...@@ -27,8 +27,8 @@ import static com.google.common.base.Preconditions.checkNotNull; ...@@ -27,8 +27,8 @@ import static com.google.common.base.Preconditions.checkNotNull;
27 * Denotes the highlighting to be applied to a link. 27 * Denotes the highlighting to be applied to a link.
28 * {@link Flavor} is a closed set of NO-, PRIMARY-, or SECONDARY- highlighting. 28 * {@link Flavor} is a closed set of NO-, PRIMARY-, or SECONDARY- highlighting.
29 * {@link Mod} is an open ended set of additional modifications (CSS classes) 29 * {@link Mod} is an open ended set of additional modifications (CSS classes)
30 - * to apply. Note that {@link #MOD_OPTICAL} and {@link #MOD_ANIMATED} are 30 + * that may also be applied.
31 - * pre-defined mods. 31 + * Note that {@link #MOD_OPTICAL} and {@link #MOD_ANIMATED} are pre-defined mods.
32 * Label text may be set, which will also be displayed on the link. 32 * Label text may be set, which will also be displayed on the link.
33 */ 33 */
34 public class LinkHighlight extends AbstractHighlight { 34 public class LinkHighlight extends AbstractHighlight {
...@@ -136,48 +136,6 @@ public class LinkHighlight extends AbstractHighlight { ...@@ -136,48 +136,6 @@ public class LinkHighlight extends AbstractHighlight {
136 } 136 }
137 137
138 /** 138 /**
139 - * Link highlighting modification.
140 - * <p>
141 - * Note that this translates to a CSS class name that is applied to
142 - * the link in the Topology UI.
143 - */
144 - public static final class Mod implements Comparable<Mod> {
145 - private final String modId;
146 -
147 - public Mod(String modId) {
148 - this.modId = checkNotNull(modId);
149 - }
150 -
151 - @Override
152 - public String toString() {
153 - return modId;
154 - }
155 -
156 - @Override
157 - public boolean equals(Object o) {
158 - if (this == o) {
159 - return true;
160 - }
161 - if (o == null || getClass() != o.getClass()) {
162 - return false;
163 - }
164 - Mod mod = (Mod) o;
165 - return modId.equals(mod.modId);
166 - }
167 -
168 - @Override
169 - public int hashCode() {
170 - return modId.hashCode();
171 - }
172 -
173 -
174 - @Override
175 - public int compareTo(Mod o) {
176 - return this.modId.compareTo(o.modId);
177 - }
178 - }
179 -
180 - /**
181 * Denotes a link to be tagged as an optical link. 139 * Denotes a link to be tagged as an optical link.
182 */ 140 */
183 public static final Mod MOD_OPTICAL = new Mod("optical"); 141 public static final Mod MOD_OPTICAL = new Mod("optical");
......
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 + */
17 +
18 +package org.onosproject.ui.topo;
19 +
20 +import static com.google.common.base.Preconditions.checkNotNull;
21 +
22 +/**
23 + * Highlighting modification.
24 + * <p>
25 + * Note that (for link highlights) this translates to a CSS class name
26 + * that is applied to the link in the Topology UI.
27 + */
28 +public final class Mod implements Comparable<Mod> {
29 + private final String modId;
30 +
31 + /**
32 + * Constructs a mod with the given identifier.
33 + *
34 + * @param modId modification identifier
35 + */
36 + public Mod(String modId) {
37 + this.modId = checkNotNull(modId);
38 + }
39 +
40 + @Override
41 + public String toString() {
42 + return modId;
43 + }
44 +
45 + @Override
46 + public boolean equals(Object o) {
47 + if (this == o) {
48 + return true;
49 + }
50 + if (o == null || getClass() != o.getClass()) {
51 + return false;
52 + }
53 + Mod mod = (Mod) o;
54 + return modId.equals(mod.modId);
55 + }
56 +
57 + @Override
58 + public int hashCode() {
59 + return modId.hashCode();
60 + }
61 +
62 + @Override
63 + public int compareTo(Mod o) {
64 + return this.modId.compareTo(o.modId);
65 + }
66 +}
...@@ -18,21 +18,18 @@ package org.onosproject.ui.impl; ...@@ -18,21 +18,18 @@ package org.onosproject.ui.impl;
18 18
19 import com.fasterxml.jackson.databind.node.ObjectNode; 19 import com.fasterxml.jackson.databind.node.ObjectNode;
20 import com.google.common.collect.ImmutableSet; 20 import com.google.common.collect.ImmutableSet;
21 -import com.google.common.collect.Maps;
22 import org.onosproject.net.Link; 21 import org.onosproject.net.Link;
23 -import org.onosproject.net.LinkKey;
24 import org.onosproject.net.link.LinkService; 22 import org.onosproject.net.link.LinkService;
25 import org.onosproject.ui.RequestHandler; 23 import org.onosproject.ui.RequestHandler;
26 import org.onosproject.ui.UiMessageHandler; 24 import org.onosproject.ui.UiMessageHandler;
27 -import org.onosproject.ui.impl.topo.BiLink; 25 +import org.onosproject.ui.impl.topo.BaseLink;
28 -import org.onosproject.ui.impl.topo.TopoUtils; 26 +import org.onosproject.ui.impl.topo.BaseLinkMap;
29 import org.onosproject.ui.table.TableModel; 27 import org.onosproject.ui.table.TableModel;
30 import org.onosproject.ui.table.TableRequestHandler; 28 import org.onosproject.ui.table.TableRequestHandler;
31 import org.onosproject.ui.table.cell.ConnectPointFormatter; 29 import org.onosproject.ui.table.cell.ConnectPointFormatter;
32 import org.onosproject.ui.table.cell.EnumFormatter; 30 import org.onosproject.ui.table.cell.EnumFormatter;
33 31
34 import java.util.Collection; 32 import java.util.Collection;
35 -import java.util.Map;
36 33
37 /** 34 /**
38 * Message handler for link view related messages. 35 * Message handler for link view related messages.
...@@ -41,6 +38,7 @@ public class LinkViewMessageHandler extends UiMessageHandler { ...@@ -41,6 +38,7 @@ public class LinkViewMessageHandler extends UiMessageHandler {
41 38
42 private static final String A_BOTH_B = "A &harr; B"; 39 private static final String A_BOTH_B = "A &harr; B";
43 private static final String A_SINGLE_B = "A &rarr; B"; 40 private static final String A_SINGLE_B = "A &rarr; B";
41 + private static final String SLASH = " / ";
44 42
45 private static final String LINK_DATA_REQ = "linkDataRequest"; 43 private static final String LINK_DATA_REQ = "linkDataRequest";
46 private static final String LINK_DATA_RESP = "linkDataResponse"; 44 private static final String LINK_DATA_RESP = "linkDataResponse";
...@@ -93,42 +91,37 @@ public class LinkViewMessageHandler extends UiMessageHandler { ...@@ -93,42 +91,37 @@ public class LinkViewMessageHandler extends UiMessageHandler {
93 @Override 91 @Override
94 protected void populateTable(TableModel tm, ObjectNode payload) { 92 protected void populateTable(TableModel tm, ObjectNode payload) {
95 LinkService ls = get(LinkService.class); 93 LinkService ls = get(LinkService.class);
96 - 94 + BaseLinkMap linkMap = new BaseLinkMap();
97 - // First consolidate all uni-directional links into two-directional ones. 95 + ls.getLinks().forEach(linkMap::add);
98 - Map<LinkKey, BiLink> biLinks = Maps.newHashMap(); 96 + linkMap.biLinks().forEach(blink -> populateRow(tm.addRow(), blink));
99 - ls.getLinks().forEach(link -> TopoUtils.addLink(biLinks, link));
100 -
101 - // Now scan over all bi-links and produce table rows from them.
102 - biLinks.values().forEach(biLink -> populateRow(tm.addRow(), biLink));
103 } 97 }
104 98
105 - private void populateRow(TableModel.Row row, BiLink biLink) { 99 + private void populateRow(TableModel.Row row, BaseLink blink) {
106 - row.cell(ONE, biLink.one().src()) 100 + row.cell(ONE, blink.one().src())
107 - .cell(TWO, biLink.one().dst()) 101 + .cell(TWO, blink.one().dst())
108 - .cell(TYPE, linkType(biLink)) 102 + .cell(TYPE, linkType(blink))
109 - .cell(STATE, linkState(biLink)) 103 + .cell(STATE, linkState(blink))
110 - .cell(DIRECTION, linkDir(biLink)) 104 + .cell(DIRECTION, linkDir(blink))
111 - .cell(DURABLE, biLink.one().isDurable()); 105 + .cell(DURABLE, blink.one().isDurable());
112 } 106 }
113 107
114 - private String linkType(BiLink link) { 108 + private String linkType(BaseLink link) {
115 StringBuilder sb = new StringBuilder(); 109 StringBuilder sb = new StringBuilder();
116 sb.append(link.one().type()); 110 sb.append(link.one().type());
117 if (link.two() != null && link.two().type() != link.one().type()) { 111 if (link.two() != null && link.two().type() != link.one().type()) {
118 - sb.append(" / ").append(link.two().type()); 112 + sb.append(SLASH).append(link.two().type());
119 } 113 }
120 return sb.toString(); 114 return sb.toString();
121 } 115 }
122 116
123 - private String linkState(BiLink link) { 117 + private String linkState(BaseLink link) {
124 return (link.one().state() == Link.State.ACTIVE || 118 return (link.one().state() == Link.State.ACTIVE ||
125 link.two().state() == Link.State.ACTIVE) ? 119 link.two().state() == Link.State.ACTIVE) ?
126 ICON_ID_ONLINE : ICON_ID_OFFLINE; 120 ICON_ID_ONLINE : ICON_ID_OFFLINE;
127 } 121 }
128 122
129 - private String linkDir(BiLink link) { 123 + private String linkDir(BaseLink link) {
130 return link.two() != null ? A_BOTH_B : A_SINGLE_B; 124 return link.two() != null ? A_BOTH_B : A_SINGLE_B;
131 } 125 }
132 } 126 }
133 -
134 } 127 }
......
...@@ -56,7 +56,7 @@ import org.onosproject.net.link.LinkListener; ...@@ -56,7 +56,7 @@ import org.onosproject.net.link.LinkListener;
56 import org.onosproject.ui.JsonUtils; 56 import org.onosproject.ui.JsonUtils;
57 import org.onosproject.ui.RequestHandler; 57 import org.onosproject.ui.RequestHandler;
58 import org.onosproject.ui.UiConnection; 58 import org.onosproject.ui.UiConnection;
59 -import org.onosproject.ui.impl.TrafficMonitorObject.Mode; 59 +import org.onosproject.ui.impl.TrafficMonitor.Mode;
60 import org.onosproject.ui.impl.topo.NodeSelection; 60 import org.onosproject.ui.impl.topo.NodeSelection;
61 import org.onosproject.ui.topo.Highlights; 61 import org.onosproject.ui.topo.Highlights;
62 import org.onosproject.ui.topo.PropertyPanel; 62 import org.onosproject.ui.topo.PropertyPanel;
...@@ -162,9 +162,8 @@ public class TopologyViewMessageHandler extends TopologyViewMessageHandlerBase { ...@@ -162,9 +162,8 @@ public class TopologyViewMessageHandler extends TopologyViewMessageHandlerBase {
162 private final ExecutorService msgSender = 162 private final ExecutorService msgSender =
163 newSingleThreadExecutor(groupedThreads("onos/gui", "msg-sender")); 163 newSingleThreadExecutor(groupedThreads("onos/gui", "msg-sender"));
164 164
165 - private TrafficMonitorObject tmo;
166 -
167 private TopoOverlayCache overlayCache; 165 private TopoOverlayCache overlayCache;
166 + private TrafficMonitor traffic;
168 167
169 private TimerTask summaryTask = null; 168 private TimerTask summaryTask = null;
170 private boolean summaryRunning = false; 169 private boolean summaryRunning = false;
...@@ -176,7 +175,7 @@ public class TopologyViewMessageHandler extends TopologyViewMessageHandlerBase { ...@@ -176,7 +175,7 @@ public class TopologyViewMessageHandler extends TopologyViewMessageHandlerBase {
176 public void init(UiConnection connection, ServiceDirectory directory) { 175 public void init(UiConnection connection, ServiceDirectory directory) {
177 super.init(connection, directory); 176 super.init(connection, directory);
178 appId = directory.get(CoreService.class).registerApplication(APP_ID); 177 appId = directory.get(CoreService.class).registerApplication(APP_ID);
179 - tmo = new TrafficMonitorObject(TRAFFIC_PERIOD, servicesBundle, this); 178 + traffic = new TrafficMonitor(TRAFFIC_PERIOD, servicesBundle, this);
180 } 179 }
181 180
182 @Override 181 @Override
...@@ -275,7 +274,7 @@ public class TopologyViewMessageHandler extends TopologyViewMessageHandlerBase { ...@@ -275,7 +274,7 @@ public class TopologyViewMessageHandler extends TopologyViewMessageHandlerBase {
275 @Override 274 @Override
276 public void process(long sid, ObjectNode payload) { 275 public void process(long sid, ObjectNode payload) {
277 stopSummaryMonitoring(); 276 stopSummaryMonitoring();
278 - tmo.stop(); 277 + traffic.stopMonitoring();
279 } 278 }
280 } 279 }
281 280
...@@ -400,7 +399,7 @@ public class TopologyViewMessageHandler extends TopologyViewMessageHandlerBase { ...@@ -400,7 +399,7 @@ public class TopologyViewMessageHandler extends TopologyViewMessageHandlerBase {
400 .build(); 399 .build();
401 400
402 intentService.submit(intent); 401 intentService.submit(intent);
403 - tmo.monitor(intent); 402 + traffic.monitor(intent);
404 } 403 }
405 } 404 }
406 405
...@@ -433,7 +432,7 @@ public class TopologyViewMessageHandler extends TopologyViewMessageHandlerBase { ...@@ -433,7 +432,7 @@ public class TopologyViewMessageHandler extends TopologyViewMessageHandlerBase {
433 .build(); 432 .build();
434 433
435 intentService.submit(intent); 434 intentService.submit(intent);
436 - tmo.monitor(intent); 435 + traffic.monitor(intent);
437 } 436 }
438 } 437 }
439 438
...@@ -446,7 +445,7 @@ public class TopologyViewMessageHandler extends TopologyViewMessageHandlerBase { ...@@ -446,7 +445,7 @@ public class TopologyViewMessageHandler extends TopologyViewMessageHandlerBase {
446 445
447 @Override 446 @Override
448 public void process(long sid, ObjectNode payload) { 447 public void process(long sid, ObjectNode payload) {
449 - tmo.monitor(Mode.ALL_FLOW_TRAFFIC); 448 + traffic.monitor(Mode.ALL_FLOW_TRAFFIC);
450 } 449 }
451 } 450 }
452 451
...@@ -457,7 +456,7 @@ public class TopologyViewMessageHandler extends TopologyViewMessageHandlerBase { ...@@ -457,7 +456,7 @@ public class TopologyViewMessageHandler extends TopologyViewMessageHandlerBase {
457 456
458 @Override 457 @Override
459 public void process(long sid, ObjectNode payload) { 458 public void process(long sid, ObjectNode payload) {
460 - tmo.monitor(Mode.ALL_PORT_TRAFFIC); 459 + traffic.monitor(Mode.ALL_PORT_TRAFFIC);
461 } 460 }
462 } 461 }
463 462
...@@ -470,7 +469,7 @@ public class TopologyViewMessageHandler extends TopologyViewMessageHandlerBase { ...@@ -470,7 +469,7 @@ public class TopologyViewMessageHandler extends TopologyViewMessageHandlerBase {
470 public void process(long sid, ObjectNode payload) { 469 public void process(long sid, ObjectNode payload) {
471 NodeSelection nodeSelection = 470 NodeSelection nodeSelection =
472 new NodeSelection(payload, deviceService, hostService); 471 new NodeSelection(payload, deviceService, hostService);
473 - tmo.monitor(Mode.DEV_LINK_FLOWS, nodeSelection); 472 + traffic.monitor(Mode.DEV_LINK_FLOWS, nodeSelection);
474 } 473 }
475 } 474 }
476 475
...@@ -483,7 +482,7 @@ public class TopologyViewMessageHandler extends TopologyViewMessageHandlerBase { ...@@ -483,7 +482,7 @@ public class TopologyViewMessageHandler extends TopologyViewMessageHandlerBase {
483 public void process(long sid, ObjectNode payload) { 482 public void process(long sid, ObjectNode payload) {
484 NodeSelection nodeSelection = 483 NodeSelection nodeSelection =
485 new NodeSelection(payload, deviceService, hostService); 484 new NodeSelection(payload, deviceService, hostService);
486 - tmo.monitor(Mode.RELATED_INTENTS, nodeSelection); 485 + traffic.monitor(Mode.RELATED_INTENTS, nodeSelection);
487 } 486 }
488 } 487 }
489 488
...@@ -494,7 +493,7 @@ public class TopologyViewMessageHandler extends TopologyViewMessageHandlerBase { ...@@ -494,7 +493,7 @@ public class TopologyViewMessageHandler extends TopologyViewMessageHandlerBase {
494 493
495 @Override 494 @Override
496 public void process(long sid, ObjectNode payload) { 495 public void process(long sid, ObjectNode payload) {
497 - tmo.selectNextIntent(); 496 + traffic.selectNextIntent();
498 } 497 }
499 } 498 }
500 499
...@@ -505,7 +504,7 @@ public class TopologyViewMessageHandler extends TopologyViewMessageHandlerBase { ...@@ -505,7 +504,7 @@ public class TopologyViewMessageHandler extends TopologyViewMessageHandlerBase {
505 504
506 @Override 505 @Override
507 public void process(long sid, ObjectNode payload) { 506 public void process(long sid, ObjectNode payload) {
508 - tmo.selectPreviousIntent(); 507 + traffic.selectPreviousIntent();
509 } 508 }
510 } 509 }
511 510
...@@ -516,7 +515,7 @@ public class TopologyViewMessageHandler extends TopologyViewMessageHandlerBase { ...@@ -516,7 +515,7 @@ public class TopologyViewMessageHandler extends TopologyViewMessageHandlerBase {
516 515
517 @Override 516 @Override
518 public void process(long sid, ObjectNode payload) { 517 public void process(long sid, ObjectNode payload) {
519 - tmo.monitor(Mode.SEL_INTENT); 518 + traffic.monitor(Mode.SELECTED_INTENT);
520 } 519 }
521 } 520 }
522 521
...@@ -527,7 +526,7 @@ public class TopologyViewMessageHandler extends TopologyViewMessageHandlerBase { ...@@ -527,7 +526,7 @@ public class TopologyViewMessageHandler extends TopologyViewMessageHandlerBase {
527 526
528 @Override 527 @Override
529 public void process(long sid, ObjectNode payload) { 528 public void process(long sid, ObjectNode payload) {
530 - tmo.stop(); 529 + traffic.stopMonitoring();
531 } 530 }
532 } 531 }
533 532
...@@ -557,7 +556,7 @@ public class TopologyViewMessageHandler extends TopologyViewMessageHandlerBase { ...@@ -557,7 +556,7 @@ public class TopologyViewMessageHandler extends TopologyViewMessageHandlerBase {
557 556
558 private void cancelAllRequests() { 557 private void cancelAllRequests() {
559 stopSummaryMonitoring(); 558 stopSummaryMonitoring();
560 - tmo.stop(); 559 + traffic.stopMonitoring();
561 } 560 }
562 561
563 // Sends all controller nodes to the client as node-added messages. 562 // Sends all controller nodes to the client as node-added messages.
...@@ -726,7 +725,7 @@ public class TopologyViewMessageHandler extends TopologyViewMessageHandlerBase { ...@@ -726,7 +725,7 @@ public class TopologyViewMessageHandler extends TopologyViewMessageHandlerBase {
726 private class InternalIntentListener implements IntentListener { 725 private class InternalIntentListener implements IntentListener {
727 @Override 726 @Override
728 public void event(IntentEvent event) { 727 public void event(IntentEvent event) {
729 - msgSender.execute(tmo::pokeIntent); 728 + msgSender.execute(traffic::pokeIntent);
730 eventAccummulator.add(event); 729 eventAccummulator.add(event);
731 } 730 }
732 } 731 }
......
...@@ -22,7 +22,6 @@ import org.onosproject.net.Device; ...@@ -22,7 +22,6 @@ import org.onosproject.net.Device;
22 import org.onosproject.net.DeviceId; 22 import org.onosproject.net.DeviceId;
23 import org.onosproject.net.Host; 23 import org.onosproject.net.Host;
24 import org.onosproject.net.Link; 24 import org.onosproject.net.Link;
25 -import org.onosproject.net.LinkKey;
26 import org.onosproject.net.PortNumber; 25 import org.onosproject.net.PortNumber;
27 import org.onosproject.net.flow.FlowEntry; 26 import org.onosproject.net.flow.FlowEntry;
28 import org.onosproject.net.flow.TrafficTreatment; 27 import org.onosproject.net.flow.TrafficTreatment;
...@@ -35,14 +34,14 @@ import org.onosproject.net.intent.OpticalConnectivityIntent; ...@@ -35,14 +34,14 @@ import org.onosproject.net.intent.OpticalConnectivityIntent;
35 import org.onosproject.net.intent.OpticalPathIntent; 34 import org.onosproject.net.intent.OpticalPathIntent;
36 import org.onosproject.net.intent.PathIntent; 35 import org.onosproject.net.intent.PathIntent;
37 import org.onosproject.net.statistic.Load; 36 import org.onosproject.net.statistic.Load;
38 -import org.onosproject.ui.impl.topo.BiLink;
39 import org.onosproject.ui.impl.topo.IntentSelection; 37 import org.onosproject.ui.impl.topo.IntentSelection;
40 -import org.onosproject.ui.impl.topo.LinkStatsType;
41 import org.onosproject.ui.impl.topo.NodeSelection; 38 import org.onosproject.ui.impl.topo.NodeSelection;
42 import org.onosproject.ui.impl.topo.ServicesBundle; 39 import org.onosproject.ui.impl.topo.ServicesBundle;
43 import org.onosproject.ui.impl.topo.TopoUtils; 40 import org.onosproject.ui.impl.topo.TopoUtils;
44 -import org.onosproject.ui.impl.topo.TopologyViewIntentFilter; 41 +import org.onosproject.ui.impl.topo.TopoIntentFilter;
45 import org.onosproject.ui.impl.topo.TrafficClass; 42 import org.onosproject.ui.impl.topo.TrafficClass;
43 +import org.onosproject.ui.impl.topo.TrafficLink;
44 +import org.onosproject.ui.impl.topo.TrafficLinkMap;
46 import org.onosproject.ui.topo.Highlights; 45 import org.onosproject.ui.topo.Highlights;
47 import org.slf4j.Logger; 46 import org.slf4j.Logger;
48 import org.slf4j.LoggerFactory; 47 import org.slf4j.LoggerFactory;
...@@ -59,21 +58,21 @@ import java.util.Timer; ...@@ -59,21 +58,21 @@ import java.util.Timer;
59 import java.util.TimerTask; 58 import java.util.TimerTask;
60 59
61 import static org.onosproject.net.DefaultEdgeLink.createEdgeLink; 60 import static org.onosproject.net.DefaultEdgeLink.createEdgeLink;
62 -import static org.onosproject.ui.impl.TrafficMonitorObject.Mode.IDLE; 61 +import static org.onosproject.ui.impl.TrafficMonitor.Mode.IDLE;
63 -import static org.onosproject.ui.impl.TrafficMonitorObject.Mode.SEL_INTENT; 62 +import static org.onosproject.ui.impl.TrafficMonitor.Mode.SELECTED_INTENT;
64 import static org.onosproject.ui.topo.LinkHighlight.Flavor.PRIMARY_HIGHLIGHT; 63 import static org.onosproject.ui.topo.LinkHighlight.Flavor.PRIMARY_HIGHLIGHT;
65 import static org.onosproject.ui.topo.LinkHighlight.Flavor.SECONDARY_HIGHLIGHT; 64 import static org.onosproject.ui.topo.LinkHighlight.Flavor.SECONDARY_HIGHLIGHT;
66 65
67 /** 66 /**
68 * Encapsulates the behavior of monitoring specific traffic patterns. 67 * Encapsulates the behavior of monitoring specific traffic patterns.
69 */ 68 */
70 -public class TrafficMonitorObject { 69 +public class TrafficMonitor {
71 70
72 // 4 Kilo Bytes as threshold 71 // 4 Kilo Bytes as threshold
73 private static final double BPS_THRESHOLD = 4 * TopoUtils.KILO; 72 private static final double BPS_THRESHOLD = 4 * TopoUtils.KILO;
74 73
75 private static final Logger log = 74 private static final Logger log =
76 - LoggerFactory.getLogger(TrafficMonitorObject.class); 75 + LoggerFactory.getLogger(TrafficMonitor.class);
77 76
78 /** 77 /**
79 * Designates the different modes of operation. 78 * Designates the different modes of operation.
...@@ -84,13 +83,13 @@ public class TrafficMonitorObject { ...@@ -84,13 +83,13 @@ public class TrafficMonitorObject {
84 ALL_PORT_TRAFFIC, 83 ALL_PORT_TRAFFIC,
85 DEV_LINK_FLOWS, 84 DEV_LINK_FLOWS,
86 RELATED_INTENTS, 85 RELATED_INTENTS,
87 - SEL_INTENT 86 + SELECTED_INTENT
88 } 87 }
89 88
90 private final long trafficPeriod; 89 private final long trafficPeriod;
91 private final ServicesBundle servicesBundle; 90 private final ServicesBundle servicesBundle;
92 - private final TopologyViewMessageHandler messageHandler; 91 + private final TopologyViewMessageHandler msgHandler;
93 - private final TopologyViewIntentFilter intentFilter; 92 + private final TopoIntentFilter intentFilter;
94 93
95 private final Timer timer = new Timer("topo-traffic"); 94 private final Timer timer = new Timer("topo-traffic");
96 95
...@@ -105,21 +104,35 @@ public class TrafficMonitorObject { ...@@ -105,21 +104,35 @@ public class TrafficMonitorObject {
105 * 104 *
106 * @param trafficPeriod traffic task period in ms 105 * @param trafficPeriod traffic task period in ms
107 * @param servicesBundle bundle of services 106 * @param servicesBundle bundle of services
108 - * @param messageHandler our message handler 107 + * @param msgHandler our message handler
109 */ 108 */
110 - public TrafficMonitorObject(long trafficPeriod, 109 + public TrafficMonitor(long trafficPeriod, ServicesBundle servicesBundle,
111 - ServicesBundle servicesBundle, 110 + TopologyViewMessageHandler msgHandler) {
112 - TopologyViewMessageHandler messageHandler) {
113 this.trafficPeriod = trafficPeriod; 111 this.trafficPeriod = trafficPeriod;
114 this.servicesBundle = servicesBundle; 112 this.servicesBundle = servicesBundle;
115 - this.messageHandler = messageHandler; 113 + this.msgHandler = msgHandler;
116 114
117 - intentFilter = new TopologyViewIntentFilter(servicesBundle); 115 + intentFilter = new TopoIntentFilter(servicesBundle);
118 } 116 }
119 117
120 // ======================================================================= 118 // =======================================================================
121 - // === API === // TODO: add javadocs 119 + // === API ===
122 120
121 + /**
122 + * Monitor for traffic data to be sent back to the web client, under
123 + * the given mode. This causes a background traffic task to be
124 + * scheduled to repeatedly compute and transmit the appropriate traffic
125 + * data to the client.
126 + * <p>
127 + * The monitoring mode is expected to be one of:
128 + * <ul>
129 + * <li>ALL_FLOW_TRAFFIC</li>
130 + * <li>ALL_PORT_TRAFFIC</li>
131 + * <li>SELECTED_INTENT</li>
132 + * </ul>
133 + *
134 + * @param mode monitoring mode
135 + */
123 public synchronized void monitor(Mode mode) { 136 public synchronized void monitor(Mode mode) {
124 log.debug("monitor: {}", mode); 137 log.debug("monitor: {}", mode);
125 this.mode = mode; 138 this.mode = mode;
...@@ -137,7 +150,7 @@ public class TrafficMonitorObject { ...@@ -137,7 +150,7 @@ public class TrafficMonitorObject {
137 sendAllPortTraffic(); 150 sendAllPortTraffic();
138 break; 151 break;
139 152
140 - case SEL_INTENT: 153 + case SELECTED_INTENT:
141 scheduleTask(); 154 scheduleTask();
142 sendSelectedIntentTraffic(); 155 sendSelectedIntentTraffic();
143 break; 156 break;
...@@ -149,6 +162,22 @@ public class TrafficMonitorObject { ...@@ -149,6 +162,22 @@ public class TrafficMonitorObject {
149 } 162 }
150 } 163 }
151 164
165 + /**
166 + * Monitor for traffic data to be sent back to the web client, under
167 + * the given mode, using the given selection of devices and hosts.
168 + * In the case of "device link flows", this causes a background traffic
169 + * task to be scheduled to repeatedly compute and transmit the appropriate
170 + * traffic data to the client. In the case of "related intents", no
171 + * repeating task is scheduled.
172 + * <p>
173 + * The monitoring mode is expected to be one of:
174 + * <ul>
175 + * <li>DEV_LINK_FLOWS</li>
176 + * <li>RELATED_INTENTS</li>
177 + * </ul>
178 + *
179 + * @param mode monitoring mode
180 + */
152 public synchronized void monitor(Mode mode, NodeSelection nodeSelection) { 181 public synchronized void monitor(Mode mode, NodeSelection nodeSelection) {
153 log.debug("monitor: {} -- {}", mode, nodeSelection); 182 log.debug("monitor: {} -- {}", mode, nodeSelection);
154 this.mode = mode; 183 this.mode = mode;
...@@ -185,15 +214,27 @@ public class TrafficMonitorObject { ...@@ -185,15 +214,27 @@ public class TrafficMonitorObject {
185 } 214 }
186 } 215 }
187 216
217 + // TODO: move this out to the "h2h/multi-intent app"
218 + /**
219 + * Monitor for traffic data to be sent back to the web client, for the
220 + * given intent.
221 + *
222 + * @param intent the intent to monitor
223 + */
188 public synchronized void monitor(Intent intent) { 224 public synchronized void monitor(Intent intent) {
189 log.debug("monitor intent: {}", intent.id()); 225 log.debug("monitor intent: {}", intent.id());
190 selectedNodes = null; 226 selectedNodes = null;
191 selectedIntents = new IntentSelection(intent); 227 selectedIntents = new IntentSelection(intent);
192 - mode = SEL_INTENT; 228 + mode = SELECTED_INTENT;
193 scheduleTask(); 229 scheduleTask();
194 sendSelectedIntentTraffic(); 230 sendSelectedIntentTraffic();
195 } 231 }
196 232
233 + /**
234 + * Selects the next intent in the select group (if there is one),
235 + * and sends highlighting data back to the web client to display
236 + * which path is selected.
237 + */
197 public synchronized void selectNextIntent() { 238 public synchronized void selectNextIntent() {
198 if (selectedIntents != null) { 239 if (selectedIntents != null) {
199 selectedIntents.next(); 240 selectedIntents.next();
...@@ -201,6 +242,11 @@ public class TrafficMonitorObject { ...@@ -201,6 +242,11 @@ public class TrafficMonitorObject {
201 } 242 }
202 } 243 }
203 244
245 + /**
246 + * Selects the previous intent in the select group (if there is one),
247 + * and sends highlighting data back to the web client to display
248 + * which path is selected.
249 + */
204 public synchronized void selectPreviousIntent() { 250 public synchronized void selectPreviousIntent() {
205 if (selectedIntents != null) { 251 if (selectedIntents != null) {
206 selectedIntents.prev(); 252 selectedIntents.prev();
...@@ -208,14 +254,21 @@ public class TrafficMonitorObject { ...@@ -208,14 +254,21 @@ public class TrafficMonitorObject {
208 } 254 }
209 } 255 }
210 256
257 + /**
258 + * Resends selected intent traffic data. This is called, for example,
259 + * when the system detects an intent update happened.
260 + */
211 public synchronized void pokeIntent() { 261 public synchronized void pokeIntent() {
212 - if (mode == SEL_INTENT) { 262 + if (mode == SELECTED_INTENT) {
213 sendSelectedIntentTraffic(); 263 sendSelectedIntentTraffic();
214 } 264 }
215 } 265 }
216 266
217 - public synchronized void stop() { 267 + /**
218 - log.debug("STOP"); 268 + * Stop all traffic monitoring.
269 + */
270 + public synchronized void stopMonitoring() {
271 + log.debug("STOP monitoring");
219 if (mode != IDLE) { 272 if (mode != IDLE) {
220 sendClearAll(); 273 sendClearAll();
221 } 274 }
...@@ -244,7 +297,7 @@ public class TrafficMonitorObject { ...@@ -244,7 +297,7 @@ public class TrafficMonitorObject {
244 private synchronized void scheduleTask() { 297 private synchronized void scheduleTask() {
245 if (trafficTask == null) { 298 if (trafficTask == null) {
246 log.debug("Starting up background traffic task..."); 299 log.debug("Starting up background traffic task...");
247 - trafficTask = new TrafficMonitor(); 300 + trafficTask = new TrafficUpdateTask();
248 timer.schedule(trafficTask, trafficPeriod, trafficPeriod); 301 timer.schedule(trafficTask, trafficPeriod, trafficPeriod);
249 } else { 302 } else {
250 // TEMPORARY until we are sure this is working correctly 303 // TEMPORARY until we are sure this is working correctly
...@@ -259,64 +312,56 @@ public class TrafficMonitorObject { ...@@ -259,64 +312,56 @@ public class TrafficMonitorObject {
259 } 312 }
260 } 313 }
261 314
262 - // ---
263 -
264 private void sendAllFlowTraffic() { 315 private void sendAllFlowTraffic() {
265 log.debug("sendAllFlowTraffic"); 316 log.debug("sendAllFlowTraffic");
266 - sendHighlights(trafficSummary(LinkStatsType.FLOW_STATS)); 317 + msgHandler.sendHighlights(trafficSummary(TrafficLink.StatsType.FLOW_STATS));
267 } 318 }
268 319
269 private void sendAllPortTraffic() { 320 private void sendAllPortTraffic() {
270 log.debug("sendAllPortTraffic"); 321 log.debug("sendAllPortTraffic");
271 - sendHighlights(trafficSummary(LinkStatsType.PORT_STATS)); 322 + msgHandler.sendHighlights(trafficSummary(TrafficLink.StatsType.PORT_STATS));
272 } 323 }
273 324
274 private void sendDeviceLinkFlows() { 325 private void sendDeviceLinkFlows() {
275 log.debug("sendDeviceLinkFlows: {}", selectedNodes); 326 log.debug("sendDeviceLinkFlows: {}", selectedNodes);
276 - sendHighlights(deviceLinkFlows()); 327 + msgHandler.sendHighlights(deviceLinkFlows());
277 } 328 }
278 329
279 private void sendSelectedIntents() { 330 private void sendSelectedIntents() {
280 log.debug("sendSelectedIntents: {}", selectedIntents); 331 log.debug("sendSelectedIntents: {}", selectedIntents);
281 - sendHighlights(intentGroup()); 332 + msgHandler.sendHighlights(intentGroup());
282 } 333 }
283 334
284 private void sendSelectedIntentTraffic() { 335 private void sendSelectedIntentTraffic() {
285 log.debug("sendSelectedIntentTraffic: {}", selectedIntents); 336 log.debug("sendSelectedIntentTraffic: {}", selectedIntents);
286 - sendHighlights(intentTraffic()); 337 + msgHandler.sendHighlights(intentTraffic());
287 } 338 }
288 339
289 private void sendClearHighlights() { 340 private void sendClearHighlights() {
290 log.debug("sendClearHighlights"); 341 log.debug("sendClearHighlights");
291 - sendHighlights(new Highlights()); 342 + msgHandler.sendHighlights(new Highlights());
292 - }
293 -
294 - private void sendHighlights(Highlights highlights) {
295 - messageHandler.sendHighlights(highlights);
296 } 343 }
297 344
298 -
299 // ======================================================================= 345 // =======================================================================
300 // === Generate messages in JSON object node format 346 // === Generate messages in JSON object node format
301 347
302 - private Highlights trafficSummary(LinkStatsType type) { 348 + private Highlights trafficSummary(TrafficLink.StatsType type) {
303 Highlights highlights = new Highlights(); 349 Highlights highlights = new Highlights();
304 350
305 - // compile a set of bilinks (combining pairs of unidirectional links) 351 + TrafficLinkMap linkMap = new TrafficLinkMap();
306 - Map<LinkKey, BiLink> linkMap = new HashMap<>();
307 compileLinks(linkMap); 352 compileLinks(linkMap);
308 addEdgeLinks(linkMap); 353 addEdgeLinks(linkMap);
309 354
310 - for (BiLink blink : linkMap.values()) { 355 + for (TrafficLink tlink : linkMap.biLinks()) {
311 - if (type == LinkStatsType.FLOW_STATS) { 356 + if (type == TrafficLink.StatsType.FLOW_STATS) {
312 - attachFlowLoad(blink); 357 + attachFlowLoad(tlink);
313 - } else if (type == LinkStatsType.PORT_STATS) { 358 + } else if (type == TrafficLink.StatsType.PORT_STATS) {
314 - attachPortLoad(blink); 359 + attachPortLoad(tlink);
315 } 360 }
316 361
317 // we only want to report on links deemed to have traffic 362 // we only want to report on links deemed to have traffic
318 - if (blink.hasTraffic()) { 363 + if (tlink.hasTraffic()) {
319 - highlights.add(blink.generateHighlight(type)); 364 + highlights.add(tlink.highlight(type));
320 } 365 }
321 } 366 }
322 return highlights; 367 return highlights;
...@@ -328,19 +373,19 @@ public class TrafficMonitorObject { ...@@ -328,19 +373,19 @@ public class TrafficMonitorObject {
328 373
329 if (selectedNodes != null && !selectedNodes.devices().isEmpty()) { 374 if (selectedNodes != null && !selectedNodes.devices().isEmpty()) {
330 // capture flow counts on bilinks 375 // capture flow counts on bilinks
331 - Map<LinkKey, BiLink> linkMap = new HashMap<>(); 376 + TrafficLinkMap linkMap = new TrafficLinkMap();
332 377
333 for (Device device : selectedNodes.devices()) { 378 for (Device device : selectedNodes.devices()) {
334 Map<Link, Integer> counts = getLinkFlowCounts(device.id()); 379 Map<Link, Integer> counts = getLinkFlowCounts(device.id());
335 for (Link link : counts.keySet()) { 380 for (Link link : counts.keySet()) {
336 - BiLink blink = TopoUtils.addLink(linkMap, link); 381 + TrafficLink tlink = linkMap.add(link);
337 - blink.addFlows(counts.get(link)); 382 + tlink.addFlows(counts.get(link));
338 } 383 }
339 } 384 }
340 385
341 // now report on our collated links 386 // now report on our collated links
342 - for (BiLink blink : linkMap.values()) { 387 + for (TrafficLink tlink : linkMap.biLinks()) {
343 - highlights.add(blink.generateHighlight(LinkStatsType.FLOW_COUNT)); 388 + highlights.add(tlink.highlight(TrafficLink.StatsType.FLOW_COUNT));
344 } 389 }
345 390
346 } 391 }
...@@ -398,18 +443,16 @@ public class TrafficMonitorObject { ...@@ -398,18 +443,16 @@ public class TrafficMonitorObject {
398 return highlights; 443 return highlights;
399 } 444 }
400 445
401 -
402 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 446 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
403 447
404 - private void compileLinks(Map<LinkKey, BiLink> linkMap) { 448 + private void compileLinks(TrafficLinkMap linkMap) {
405 - servicesBundle.linkService().getLinks() 449 + servicesBundle.linkService().getLinks().forEach(linkMap::add);
406 - .forEach(link -> TopoUtils.addLink(linkMap, link));
407 } 450 }
408 451
409 - private void addEdgeLinks(Map<LinkKey, BiLink> biLinks) { 452 + private void addEdgeLinks(TrafficLinkMap linkMap) {
410 servicesBundle.hostService().getHosts().forEach(host -> { 453 servicesBundle.hostService().getHosts().forEach(host -> {
411 - TopoUtils.addLink(biLinks, createEdgeLink(host, true)); 454 + linkMap.add(createEdgeLink(host, true));
412 - TopoUtils.addLink(biLinks, createEdgeLink(host, false)); 455 + linkMap.add(createEdgeLink(host, false));
413 }); 456 });
414 } 457 }
415 458
...@@ -420,12 +463,12 @@ public class TrafficMonitorObject { ...@@ -420,12 +463,12 @@ public class TrafficMonitorObject {
420 return null; 463 return null;
421 } 464 }
422 465
423 - private void attachFlowLoad(BiLink link) { 466 + private void attachFlowLoad(TrafficLink link) {
424 link.addLoad(getLinkFlowLoad(link.one())); 467 link.addLoad(getLinkFlowLoad(link.one()));
425 link.addLoad(getLinkFlowLoad(link.two())); 468 link.addLoad(getLinkFlowLoad(link.two()));
426 } 469 }
427 470
428 - private void attachPortLoad(BiLink link) { 471 + private void attachPortLoad(TrafficLink link) {
429 // For bi-directional traffic links, use 472 // For bi-directional traffic links, use
430 // the max link rate of either direction 473 // the max link rate of either direction
431 // (we choose 'one' since we know that is never null) 474 // (we choose 'one' since we know that is never null)
...@@ -433,7 +476,7 @@ public class TrafficMonitorObject { ...@@ -433,7 +476,7 @@ public class TrafficMonitorObject {
433 Load egressSrc = servicesBundle.portStatsService().load(one.src()); 476 Load egressSrc = servicesBundle.portStatsService().load(one.src());
434 Load egressDst = servicesBundle.portStatsService().load(one.dst()); 477 Load egressDst = servicesBundle.portStatsService().load(one.dst());
435 link.addLoad(maxLoad(egressSrc, egressDst), BPS_THRESHOLD); 478 link.addLoad(maxLoad(egressSrc, egressDst), BPS_THRESHOLD);
436 -// link.addLoad(maxLoad(egressSrc, egressDst), 10); // FIXME - debug only 479 +// link.addLoad(maxLoad(egressSrc, egressDst), 10); // DEBUG ONLY!!
437 } 480 }
438 481
439 private Load maxLoad(Load a, Load b) { 482 private Load maxLoad(Load a, Load b) {
...@@ -446,18 +489,18 @@ public class TrafficMonitorObject { ...@@ -446,18 +489,18 @@ public class TrafficMonitorObject {
446 return a.rate() > b.rate() ? a : b; 489 return a.rate() > b.rate() ? a : b;
447 } 490 }
448 491
449 - // ---
450 -
451 // Counts all flow entries that egress on the links of the given device. 492 // Counts all flow entries that egress on the links of the given device.
452 private Map<Link, Integer> getLinkFlowCounts(DeviceId deviceId) { 493 private Map<Link, Integer> getLinkFlowCounts(DeviceId deviceId) {
453 // get the flows for the device 494 // get the flows for the device
454 List<FlowEntry> entries = new ArrayList<>(); 495 List<FlowEntry> entries = new ArrayList<>();
455 - for (FlowEntry flowEntry : servicesBundle.flowService().getFlowEntries(deviceId)) { 496 + for (FlowEntry flowEntry : servicesBundle.flowService()
497 + .getFlowEntries(deviceId)) {
456 entries.add(flowEntry); 498 entries.add(flowEntry);
457 } 499 }
458 500
459 // get egress links from device, and include edge links 501 // get egress links from device, and include edge links
460 - Set<Link> links = new HashSet<>(servicesBundle.linkService().getDeviceEgressLinks(deviceId)); 502 + Set<Link> links = new HashSet<>(servicesBundle.linkService()
503 + .getDeviceEgressLinks(deviceId));
461 Set<Host> hosts = servicesBundle.hostService().getConnectedHosts(deviceId); 504 Set<Host> hosts = servicesBundle.hostService().getConnectedHosts(deviceId);
462 if (hosts != null) { 505 if (hosts != null) {
463 for (Host host : hosts) { 506 for (Host host : hosts) {
...@@ -489,22 +532,20 @@ public class TrafficMonitorObject { ...@@ -489,22 +532,20 @@ public class TrafficMonitorObject {
489 return count; 532 return count;
490 } 533 }
491 534
492 - // ---
493 private void highlightIntents(Highlights highlights, 535 private void highlightIntents(Highlights highlights,
494 TrafficClass... trafficClasses) { 536 TrafficClass... trafficClasses) {
495 - Map<LinkKey, BiLink> linkMap = new HashMap<>(); 537 + TrafficLinkMap linkMap = new TrafficLinkMap();
496 -
497 538
498 for (TrafficClass trafficClass : trafficClasses) { 539 for (TrafficClass trafficClass : trafficClasses) {
499 classifyLinkTraffic(linkMap, trafficClass); 540 classifyLinkTraffic(linkMap, trafficClass);
500 } 541 }
501 542
502 - for (BiLink blink : linkMap.values()) { 543 + for (TrafficLink tlink : linkMap.biLinks()) {
503 - highlights.add(blink.generateHighlight(LinkStatsType.TAGGED)); 544 + highlights.add(tlink.highlight(TrafficLink.StatsType.TAGGED));
504 } 545 }
505 } 546 }
506 547
507 - private void classifyLinkTraffic(Map<LinkKey, BiLink> linkMap, 548 + private void classifyLinkTraffic(TrafficLinkMap linkMap,
508 TrafficClass trafficClass) { 549 TrafficClass trafficClass) {
509 for (Intent intent : trafficClass.intents()) { 550 for (Intent intent : trafficClass.intents()) {
510 boolean isOptical = intent instanceof OpticalConnectivityIntent; 551 boolean isOptical = intent instanceof OpticalConnectivityIntent;
...@@ -532,17 +573,17 @@ public class TrafficMonitorObject { ...@@ -532,17 +573,17 @@ public class TrafficMonitorObject {
532 } 573 }
533 574
534 private void classifyLinks(TrafficClass trafficClass, boolean isOptical, 575 private void classifyLinks(TrafficClass trafficClass, boolean isOptical,
535 - Map<LinkKey, BiLink> linkMap, 576 + TrafficLinkMap linkMap,
536 Iterable<Link> links) { 577 Iterable<Link> links) {
537 if (links != null) { 578 if (links != null) {
538 for (Link link : links) { 579 for (Link link : links) {
539 - BiLink blink = TopoUtils.addLink(linkMap, link); 580 + TrafficLink tlink = linkMap.add(link);
540 if (trafficClass.showTraffic()) { 581 if (trafficClass.showTraffic()) {
541 - blink.addLoad(getLinkFlowLoad(link)); 582 + tlink.addLoad(getLinkFlowLoad(link));
542 - blink.setAntMarch(true); 583 + tlink.antMarch(true);
543 } 584 }
544 - blink.setOptical(isOptical); 585 + tlink.optical(isOptical);
545 - blink.tagFlavor(trafficClass.flavor()); 586 + tlink.tagFlavor(trafficClass.flavor());
546 } 587 }
547 } 588 }
548 } 589 }
...@@ -559,7 +600,7 @@ public class TrafficMonitorObject { ...@@ -559,7 +600,7 @@ public class TrafficMonitorObject {
559 // === Background Task 600 // === Background Task
560 601
561 // Provides periodic update of traffic information to the client 602 // Provides periodic update of traffic information to the client
562 - private class TrafficMonitor extends TimerTask { 603 + private class TrafficUpdateTask extends TimerTask {
563 @Override 604 @Override
564 public void run() { 605 public void run() {
565 try { 606 try {
...@@ -573,7 +614,7 @@ public class TrafficMonitorObject { ...@@ -573,7 +614,7 @@ public class TrafficMonitorObject {
573 case DEV_LINK_FLOWS: 614 case DEV_LINK_FLOWS:
574 sendDeviceLinkFlows(); 615 sendDeviceLinkFlows();
575 break; 616 break;
576 - case SEL_INTENT: 617 + case SELECTED_INTENT:
577 sendSelectedIntentTraffic(); 618 sendSelectedIntentTraffic();
578 break; 619 break;
579 620
...@@ -590,5 +631,4 @@ public class TrafficMonitorObject { ...@@ -590,5 +631,4 @@ public class TrafficMonitorObject {
590 } 631 }
591 } 632 }
592 } 633 }
593 -
594 } 634 }
......
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 + */
17 +
18 +package org.onosproject.ui.impl.topo;
19 +
20 +import org.onosproject.net.Link;
21 +import org.onosproject.net.LinkKey;
22 +import org.onosproject.ui.topo.LinkHighlight;
23 +
24 +/**
25 + * A simple concrete implementation of a {@link BiLink}.
26 + * Note that this implementation does not generate any link highlights.
27 + */
28 +public class BaseLink extends BiLink {
29 +
30 + /**
31 + * Constructs a base link for the given key and initial link.
32 + *
33 + * @param key canonical key for this base link
34 + * @param link first link
35 + */
36 + public BaseLink(LinkKey key, Link link) {
37 + super(key, link);
38 + }
39 +
40 + @Override
41 + public LinkHighlight highlight(Enum<?> type) {
42 + return null;
43 + }
44 +}
...@@ -17,27 +17,15 @@ ...@@ -17,27 +17,15 @@
17 17
18 package org.onosproject.ui.impl.topo; 18 package org.onosproject.ui.impl.topo;
19 19
20 +import org.onosproject.net.Link;
21 +import org.onosproject.net.LinkKey;
22 +
20 /** 23 /**
21 - * Designates type of stats to report on a highlighted link. 24 + * Collection of {@link BaseLink}s.
22 */ 25 */
23 -public enum LinkStatsType { 26 +public class BaseLinkMap extends BiLinkMap<BaseLink> {
24 - /** 27 + @Override
25 - * Number of flows. 28 + public BaseLink create(LinkKey key, Link link) {
26 - */ 29 + return new BaseLink(key, link);
27 - FLOW_COUNT, 30 + }
28 -
29 - /**
30 - * Number of bytes.
31 - */
32 - FLOW_STATS,
33 -
34 - /**
35 - * Number of bits per second.
36 - */
37 - PORT_STATS,
38 -
39 - /**
40 - * Custom tagged information.
41 - */
42 - TAGGED
43 } 31 }
......
...@@ -19,226 +19,87 @@ package org.onosproject.ui.impl.topo; ...@@ -19,226 +19,87 @@ package org.onosproject.ui.impl.topo;
19 19
20 import org.onosproject.net.Link; 20 import org.onosproject.net.Link;
21 import org.onosproject.net.LinkKey; 21 import org.onosproject.net.LinkKey;
22 -import org.onosproject.net.statistic.Load;
23 import org.onosproject.ui.topo.LinkHighlight; 22 import org.onosproject.ui.topo.LinkHighlight;
24 23
25 -import static org.onosproject.ui.topo.LinkHighlight.Flavor.NO_HIGHLIGHT; 24 +import static com.google.common.base.Preconditions.checkNotNull;
26 -import static org.onosproject.ui.topo.LinkHighlight.Flavor.PRIMARY_HIGHLIGHT;
27 -import static org.onosproject.ui.topo.LinkHighlight.Flavor.SECONDARY_HIGHLIGHT;
28 25
29 /** 26 /**
30 - * Representation of a link and its inverse, and any associated traffic data. 27 + * Representation of a link and its inverse, as a partial implementation.
31 - * This class understands how to generate {@link LinkHighlight}s for sending 28 + * <p>
32 - * back to the topology view. 29 + * Subclasses will decide how to generate the link highlighting (coloring
30 + * and labeling) for the topology view.
33 */ 31 */
34 -public class BiLink { 32 +public abstract class BiLink {
35 -
36 - private static final String EMPTY = "";
37 33
38 private final LinkKey key; 34 private final LinkKey key;
39 private final Link one; 35 private final Link one;
40 private Link two; 36 private Link two;
41 37
42 - private boolean hasTraffic = false;
43 - private long bytes = 0;
44 - private long rate = 0;
45 - private long flows = 0;
46 - private boolean isOptical = false;
47 - private LinkHighlight.Flavor taggedFlavor = NO_HIGHLIGHT;
48 - private boolean antMarch = false;
49 -
50 /** 38 /**
51 - * Constructs a bilink for the given key and initial link. 39 + * Constructs a bi-link for the given key and initial link. It is expected
40 + * that the caller will have used {@link TopoUtils#canonicalLinkKey(Link)}
41 + * to generate the key.
52 * 42 *
53 - * @param key canonical key for this bilink 43 + * @param key canonical key for this bi-link
54 * @param link first link 44 * @param link first link
55 */ 45 */
56 public BiLink(LinkKey key, Link link) { 46 public BiLink(LinkKey key, Link link) {
57 - this.key = key; 47 + this.key = checkNotNull(key);
58 - this.one = link; 48 + this.one = checkNotNull(link);
59 } 49 }
60 50
61 /** 51 /**
62 - * Sets the second link for this bilink. 52 + * Sets the second link for this bi-link.
63 * 53 *
64 * @param link second link 54 * @param link second link
65 */ 55 */
66 public void setOther(Link link) { 56 public void setOther(Link link) {
67 - this.two = link; 57 + this.two = checkNotNull(link);
68 } 58 }
69 59
70 /** 60 /**
71 - * Sets the optical flag to the given value. 61 + * Returns the link identifier in the form expected on the Topology View
62 + * in the web client.
72 * 63 *
73 - * @param b true if an optical link 64 + * @return link identifier
74 */ 65 */
75 - public void setOptical(boolean b) { 66 + public String linkId() {
76 - isOptical = b; 67 + return TopoUtils.compactLinkString(one);
77 - }
78 -
79 - /**
80 - * Sets the ant march flag to the given value.
81 - *
82 - * @param b true if marching ants required
83 - */
84 - public void setAntMarch(boolean b) {
85 - antMarch = b;
86 - }
87 -
88 - /**
89 - * Tags this bilink with a link flavor to be used in visual rendering.
90 - *
91 - * @param flavor the flavor to tag
92 - */
93 - public void tagFlavor(LinkHighlight.Flavor flavor) {
94 - this.taggedFlavor = flavor;
95 } 68 }
96 69
97 /** 70 /**
98 - * Adds load statistics, marks the bilink as having traffic. 71 + * Returns the key for this bi-link.
99 * 72 *
100 - * @param load load to add 73 + * @return the key
101 */ 74 */
102 - public void addLoad(Load load) { 75 + public LinkKey key() {
103 - addLoad(load, 0); 76 + return key;
104 } 77 }
105 78
106 /** 79 /**
107 - * Adds load statistics, marks the bilink as having traffic, if the 80 + * Returns the first link in this bi-link.
108 - * load rate is greater than the given threshold.
109 * 81 *
110 - * @param load load to add 82 + * @return the first link
111 - * @param threshold threshold to register traffic
112 */ 83 */
113 - public void addLoad(Load load, double threshold) { 84 + public Link one() {
114 - if (load != null) { 85 + return one;
115 - this.hasTraffic = hasTraffic || load.rate() > threshold;
116 - this.bytes += load.latest();
117 - this.rate += load.rate();
118 - }
119 } 86 }
120 87
121 /** 88 /**
122 - * Adds the given count of flows to this bilink. 89 + * Returns the second link in this bi-link.
123 * 90 *
124 - * @param count count of flows 91 + * @return the second link
125 */ 92 */
126 - public void addFlows(int count) { 93 + public Link two() {
127 - this.flows += count; 94 + return two;
128 } 95 }
129 96
130 /** 97 /**
131 - * Generates a link highlight entity, based on state of this bilink. 98 + * Returns the link highlighting to use, based on this bi-link's current
99 + * state.
132 * 100 *
133 - * @param type the type of statistics to use to interpret the data 101 + * @param type optional highlighting type parameter
134 - * @return link highlight data for this bilink 102 + * @return link highlighting model
135 */ 103 */
136 - public LinkHighlight generateHighlight(LinkStatsType type) { 104 + public abstract LinkHighlight highlight(Enum<?> type);
137 - switch (type) {
138 - case FLOW_COUNT:
139 - return highlightForFlowCount(type);
140 -
141 - case FLOW_STATS:
142 - case PORT_STATS:
143 - return highlightForStats(type);
144 -
145 - case TAGGED:
146 - return highlightForTagging(type);
147 -
148 - default:
149 - throw new IllegalStateException("unexpected case: " + type);
150 - }
151 - }
152 -
153 - private LinkHighlight highlightForStats(LinkStatsType type) {
154 - return new LinkHighlight(linkId(), SECONDARY_HIGHLIGHT)
155 - .setLabel(generateLabel(type));
156 - }
157 -
158 - private LinkHighlight highlightForFlowCount(LinkStatsType type) {
159 - LinkHighlight.Flavor flavor = flows() > 0 ?
160 - PRIMARY_HIGHLIGHT : SECONDARY_HIGHLIGHT;
161 - return new LinkHighlight(linkId(), flavor)
162 - .setLabel(generateLabel(type));
163 - }
164 -
165 - private LinkHighlight highlightForTagging(LinkStatsType type) {
166 - LinkHighlight hlite = new LinkHighlight(linkId(), flavor())
167 - .setLabel(generateLabel(type));
168 - if (isOptical()) {
169 - hlite.addMod(LinkHighlight.MOD_OPTICAL);
170 - }
171 - if (isAntMarch()) {
172 - hlite.addMod(LinkHighlight.MOD_ANIMATED);
173 - }
174 - return hlite;
175 - }
176 -
177 - // Generates a link identifier in the form that the Topology View on the
178 - private String linkId() {
179 - return TopoUtils.compactLinkString(one);
180 - }
181 -
182 - // Generates a string representation of the load, to be used as a label
183 - private String generateLabel(LinkStatsType type) {
184 - switch (type) {
185 - case FLOW_COUNT:
186 - return TopoUtils.formatFlows(flows());
187 -
188 - case FLOW_STATS:
189 - return TopoUtils.formatBytes(bytes());
190 -
191 - case PORT_STATS:
192 - return TopoUtils.formatBitRate(rate());
193 -
194 - case TAGGED:
195 - return hasTraffic() ? TopoUtils.formatBytes(bytes()) : EMPTY;
196 -
197 - default:
198 - return "?";
199 - }
200 - }
201 -
202 - // === ----------------------------------------------------------------
203 - // accessors
204 -
205 - public LinkKey key() {
206 - return key;
207 - }
208 -
209 - public Link one() {
210 - return one;
211 - }
212 -
213 - public Link two() {
214 - return two;
215 - }
216 -
217 - public boolean hasTraffic() {
218 - return hasTraffic;
219 - }
220 -
221 - public boolean isOptical() {
222 - return isOptical;
223 - }
224 -
225 - public boolean isAntMarch() {
226 - return antMarch;
227 - }
228 -
229 - public LinkHighlight.Flavor flavor() {
230 - return taggedFlavor;
231 - }
232 -
233 - public long bytes() {
234 - return bytes;
235 - }
236 -
237 - public long rate() {
238 - return rate;
239 - }
240 -
241 - public long flows() {
242 - return flows;
243 - }
244 } 105 }
......
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 + */
17 +
18 +package org.onosproject.ui.impl.topo;
19 +
20 +import org.onosproject.net.Link;
21 +import org.onosproject.net.LinkKey;
22 +
23 +import java.util.Collection;
24 +import java.util.HashMap;
25 +import java.util.Map;
26 +
27 +import static com.google.common.base.Preconditions.checkNotNull;
28 +
29 +/**
30 + * Represents a collection of {@link BiLink} concrete classes. These maps
31 + * are used to collate a set of unidirectional {@link Link}s into a smaller
32 + * set of bi-directional {@link BiLink} derivatives.
33 + * <p>
34 + * @param <B> the type of bi-link subclass
35 + */
36 +public abstract class BiLinkMap<B extends BiLink> {
37 +
38 + private final Map<LinkKey, B> map = new HashMap<>();
39 +
40 + /**
41 + * Creates a new instance of a bi-link. Concrete subclasses should
42 + * instantiate and return the appropriate bi-link subclass.
43 + *
44 + * @param key the link key
45 + * @param link the initial link
46 + * @return a new instance
47 + */
48 + public abstract B create(LinkKey key, Link link);
49 +
50 + /**
51 + * Adds the given link to our collection, returning the corresponding
52 + * bi-link (creating one if needed necessary).
53 + *
54 + * @param link the link to add to the collection
55 + * @return the corresponding bi-link wrapper
56 + */
57 + public B add(Link link) {
58 + LinkKey key = TopoUtils.canonicalLinkKey(checkNotNull(link));
59 + B blink = map.get(key);
60 + if (blink == null) {
61 + // no bi-link yet exists for this link
62 + blink = create(key, link);
63 + map.put(key, blink);
64 + } else {
65 + // we have a bi-link for this link.
66 + if (!blink.one().equals(link)) {
67 + blink.setOther(link);
68 + }
69 + }
70 + return blink;
71 + }
72 +
73 + /**
74 + * Returns the bi-link instances in the collection.
75 + *
76 + * @return the bi-links in this map
77 + */
78 + public Collection<B> biLinks() {
79 + return map.values();
80 + }
81 +
82 + /**
83 + * Returns the number of bi-links in the collection.
84 + *
85 + * @return number of bi-links
86 + */
87 + public int size() {
88 + return map.size();
89 + }
90 +}
...@@ -47,7 +47,7 @@ public class IntentSelection { ...@@ -47,7 +47,7 @@ public class IntentSelection {
47 * @param nodes node selection 47 * @param nodes node selection
48 * @param filter intent filter 48 * @param filter intent filter
49 */ 49 */
50 - public IntentSelection(NodeSelection nodes, TopologyViewIntentFilter filter) { 50 + public IntentSelection(NodeSelection nodes, TopoIntentFilter filter) {
51 this.nodes = nodes; 51 this.nodes = nodes;
52 intents = filter.findPathIntents(nodes.hosts(), nodes.devices()); 52 intents = filter.findPathIntents(nodes.hosts(), nodes.devices());
53 } 53 }
......
...@@ -41,7 +41,7 @@ import static org.onosproject.net.HostId.hostId; ...@@ -41,7 +41,7 @@ import static org.onosproject.net.HostId.hostId;
41 */ 41 */
42 public class NodeSelection { 42 public class NodeSelection {
43 43
44 - protected static final Logger log = 44 + private static final Logger log =
45 LoggerFactory.getLogger(NodeSelection.class); 45 LoggerFactory.getLogger(NodeSelection.class);
46 46
47 private static final String IDS = "ids"; 47 private static final String IDS = "ids";
...@@ -183,5 +183,4 @@ public class NodeSelection { ...@@ -183,5 +183,4 @@ public class NodeSelection {
183 } 183 }
184 return unmatched; 184 return unmatched;
185 } 185 }
186 -
187 } 186 }
......
...@@ -42,6 +42,7 @@ public class ServicesBundle { ...@@ -42,6 +42,7 @@ public class ServicesBundle {
42 42
43 /** 43 /**
44 * Creates the services bundle. 44 * Creates the services bundle.
45 + *
45 * @param intentService intent service reference 46 * @param intentService intent service reference
46 * @param deviceService device service reference 47 * @param deviceService device service reference
47 * @param hostService host service reference 48 * @param hostService host service reference
...@@ -66,30 +67,65 @@ public class ServicesBundle { ...@@ -66,30 +67,65 @@ public class ServicesBundle {
66 this.portStatsService = checkNotNull(portStatsService); 67 this.portStatsService = checkNotNull(portStatsService);
67 } 68 }
68 69
70 + /**
71 + * Returns a reference to the intent service.
72 + *
73 + * @return intent service reference
74 + */
69 public IntentService intentService() { 75 public IntentService intentService() {
70 return intentService; 76 return intentService;
71 } 77 }
72 78
79 + /**
80 + * Returns a reference to the device service.
81 + *
82 + * @return device service reference
83 + */
73 public DeviceService deviceService() { 84 public DeviceService deviceService() {
74 return deviceService; 85 return deviceService;
75 } 86 }
76 87
88 + /**
89 + * Returns a reference to the host service.
90 + *
91 + * @return host service reference
92 + */
77 public HostService hostService() { 93 public HostService hostService() {
78 return hostService; 94 return hostService;
79 } 95 }
80 96
97 + /**
98 + * Returns a reference to the link service.
99 + *
100 + * @return link service reference
101 + */
81 public LinkService linkService() { 102 public LinkService linkService() {
82 return linkService; 103 return linkService;
83 } 104 }
84 105
106 + /**
107 + * Returns a reference to the flow rule service.
108 + *
109 + * @return flow service reference
110 + */
85 public FlowRuleService flowService() { 111 public FlowRuleService flowService() {
86 return flowService; 112 return flowService;
87 } 113 }
88 114
115 + /**
116 + * Returns a reference to the flow statistics service.
117 + *
118 + * @return flow statistics service reference
119 + */
89 public StatisticService flowStatsService() { 120 public StatisticService flowStatsService() {
90 return flowStatsService; 121 return flowStatsService;
91 } 122 }
92 123
124 + /**
125 + * Returns a reference to the port statistics service.
126 + *
127 + * @return port statistics service reference
128 + */
93 public PortStatisticsService portStatsService() { 129 public PortStatisticsService portStatsService() {
94 return portStatsService; 130 return portStatsService;
95 } 131 }
......
...@@ -48,7 +48,7 @@ import static org.onosproject.net.intent.IntentState.INSTALLED; ...@@ -48,7 +48,7 @@ import static org.onosproject.net.intent.IntentState.INSTALLED;
48 * Auxiliary facility to query the intent service based on the specified 48 * Auxiliary facility to query the intent service based on the specified
49 * set of end-station hosts, edge points or infrastructure devices. 49 * set of end-station hosts, edge points or infrastructure devices.
50 */ 50 */
51 -public class TopologyViewIntentFilter { 51 +public class TopoIntentFilter {
52 52
53 private final IntentService intentService; 53 private final IntentService intentService;
54 private final DeviceService deviceService; 54 private final DeviceService deviceService;
...@@ -60,19 +60,13 @@ public class TopologyViewIntentFilter { ...@@ -60,19 +60,13 @@ public class TopologyViewIntentFilter {
60 * 60 *
61 * @param services service references bundle 61 * @param services service references bundle
62 */ 62 */
63 - public TopologyViewIntentFilter(ServicesBundle services) { 63 + public TopoIntentFilter(ServicesBundle services) {
64 this.intentService = services.intentService(); 64 this.intentService = services.intentService();
65 this.deviceService = services.deviceService(); 65 this.deviceService = services.deviceService();
66 this.hostService = services.hostService(); 66 this.hostService = services.hostService();
67 this.linkService = services.linkService(); 67 this.linkService = services.linkService();
68 } 68 }
69 69
70 -
71 - // TODO: Review - do we need this signature, with sourceIntents??
72 -// public List<Intent> findPathIntents(Set<Host> hosts, Set<Device> devices,
73 -// Iterable<Intent> sourceIntents) {
74 -// }
75 -
76 /** 70 /**
77 * Finds all path (host-to-host or point-to-point) intents that pertain 71 * Finds all path (host-to-host or point-to-point) intents that pertain
78 * to the given hosts and devices. 72 * to the given hosts and devices.
...@@ -277,5 +271,4 @@ public class TopologyViewIntentFilter { ...@@ -277,5 +271,4 @@ public class TopologyViewIntentFilter {
277 } 271 }
278 return null; 272 return null;
279 } 273 }
280 -
281 } 274 }
......
...@@ -21,15 +21,16 @@ import org.onosproject.net.Link; ...@@ -21,15 +21,16 @@ import org.onosproject.net.Link;
21 import org.onosproject.net.LinkKey; 21 import org.onosproject.net.LinkKey;
22 22
23 import java.text.DecimalFormat; 23 import java.text.DecimalFormat;
24 -import java.util.Map;
25 24
26 import static org.onosproject.net.LinkKey.linkKey; 25 import static org.onosproject.net.LinkKey.linkKey;
27 26
28 /** 27 /**
29 - * Utility methods for helping out with the topology view. 28 + * Utility methods for helping out with formatting data for the Topology View
29 + * in the web client.
30 */ 30 */
31 public final class TopoUtils { 31 public final class TopoUtils {
32 32
33 + // explicit decision made to not 'javadoc' these self explanatory constants
33 public static final double KILO = 1024; 34 public static final double KILO = 1024;
34 public static final double MEGA = 1024 * KILO; 35 public static final double MEGA = 1024 * KILO;
35 public static final double GIGA = 1024 * MEGA; 36 public static final double GIGA = 1024 * MEGA;
...@@ -155,30 +156,4 @@ public final class TopoUtils { ...@@ -155,30 +156,4 @@ public final class TopoUtils {
155 } 156 }
156 return String.valueOf(flows) + SPACE + (flows > 1 ? FLOWS : FLOW); 157 return String.valueOf(flows) + SPACE + (flows > 1 ? FLOWS : FLOW);
157 } 158 }
158 -
159 -
160 - /**
161 - * Creates a new biLink with the supplied link (and adds it to the map),
162 - * or attaches the link to an existing biLink (which already has the
163 - * peer link).
164 - *
165 - * @param linkMap map of biLinks
166 - * @param link the link to add
167 - * @return the biLink to which the link was added
168 - */
169 - // creates a new biLink with supplied link, or attaches link to the
170 - // existing biLink (which already has its peer link)
171 - public static BiLink addLink(Map<LinkKey, BiLink> linkMap, Link link) {
172 - LinkKey key = TopoUtils.canonicalLinkKey(link);
173 - BiLink biLink = linkMap.get(key);
174 - if (biLink != null) {
175 - biLink.setOther(link);
176 - } else {
177 - biLink = new BiLink(key, link);
178 - linkMap.put(key, biLink);
179 - }
180 - return biLink;
181 - }
182 -
183 -
184 } 159 }
......
...@@ -24,6 +24,7 @@ import org.onosproject.ui.topo.LinkHighlight; ...@@ -24,6 +24,7 @@ import org.onosproject.ui.topo.LinkHighlight;
24 * Auxiliary data carrier for assigning a highlight class to a set of 24 * Auxiliary data carrier for assigning a highlight class to a set of
25 * intents, for visualization in the topology view. 25 * intents, for visualization in the topology view.
26 */ 26 */
27 +@Deprecated
27 public class TrafficClass { 28 public class TrafficClass {
28 29
29 private final LinkHighlight.Flavor flavor; 30 private final LinkHighlight.Flavor flavor;
......
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 + */
17 +
18 +package org.onosproject.ui.impl.topo;
19 +
20 +import org.onosproject.net.Link;
21 +import org.onosproject.net.LinkKey;
22 +import org.onosproject.net.statistic.Load;
23 +import org.onosproject.ui.topo.LinkHighlight;
24 +import org.onosproject.ui.topo.LinkHighlight.Flavor;
25 +
26 +import static org.onosproject.ui.topo.LinkHighlight.Flavor.NO_HIGHLIGHT;
27 +import static org.onosproject.ui.topo.LinkHighlight.Flavor.PRIMARY_HIGHLIGHT;
28 +import static org.onosproject.ui.topo.LinkHighlight.Flavor.SECONDARY_HIGHLIGHT;
29 +
30 +/**
31 + * Representation of a link and its inverse, and associated traffic data.
32 + * This class understands how to generate the appropriate
33 + * {@link LinkHighlight}s for showing traffic data on the topology view.
34 + */
35 +public class TrafficLink extends BiLink {
36 +
37 + private static final String EMPTY = "";
38 + private static final String QUE = "?";
39 +
40 + private long bytes = 0;
41 + private long rate = 0;
42 + private long flows = 0;
43 + private Flavor taggedFlavor = NO_HIGHLIGHT;
44 + private boolean hasTraffic = false;
45 + private boolean isOptical = false;
46 + private boolean antMarch = false;
47 +
48 + /**
49 + * Constructs a traffic link for the given key and initial link.
50 + *
51 + * @param key canonical key for this traffic link
52 + * @param link first link
53 + */
54 + public TrafficLink(LinkKey key, Link link) {
55 + super(key, link);
56 + }
57 +
58 + /**
59 + * Sets the optical flag to the given value.
60 + *
61 + * @param b true if an optical link
62 + * @return self, for chaining
63 + */
64 + public TrafficLink optical(boolean b) {
65 + isOptical = b;
66 + return this;
67 + }
68 +
69 + /**
70 + * Sets the ant march flag to the given value.
71 + *
72 + * @param b true if marching ants required
73 + * @return self, for chaining
74 + */
75 + public TrafficLink antMarch(boolean b) {
76 + antMarch = b;
77 + return this;
78 + }
79 +
80 + /**
81 + * Tags this traffic link with the flavor to be used in visual rendering.
82 + *
83 + * @param flavor the flavor to tag
84 + * @return self, for chaining
85 + */
86 + public TrafficLink tagFlavor(Flavor flavor) {
87 + this.taggedFlavor = flavor;
88 + return this;
89 + }
90 +
91 + /**
92 + * Adds load statistics, marks the traffic link as having traffic.
93 + *
94 + * @param load load to add
95 + */
96 + public void addLoad(Load load) {
97 + addLoad(load, 0);
98 + }
99 +
100 + /**
101 + * Adds load statistics, marks the traffic link as having traffic, if the
102 + * load {@link Load#rate rate} is greater than the given threshold
103 + * (expressed in bytes per second).
104 + *
105 + * @param load load to add
106 + * @param threshold threshold to register traffic
107 + */
108 + public void addLoad(Load load, double threshold) {
109 + if (load != null) {
110 + this.hasTraffic = hasTraffic || load.rate() > threshold;
111 + this.bytes += load.latest();
112 + this.rate += load.rate();
113 + }
114 + }
115 +
116 + /**
117 + * Adds the given count of flows to this traffic link.
118 + *
119 + * @param count count of flows
120 + */
121 + public void addFlows(int count) {
122 + this.flows += count;
123 + }
124 +
125 + @Override
126 + public LinkHighlight highlight(Enum<?> type) {
127 + StatsType statsType = (StatsType) type;
128 + switch (statsType) {
129 + case FLOW_COUNT:
130 + return highlightForFlowCount(statsType);
131 +
132 + case FLOW_STATS:
133 + case PORT_STATS:
134 + return highlightForStats(statsType);
135 +
136 + case TAGGED:
137 + return highlightForTagging(statsType);
138 +
139 + default:
140 + throw new IllegalStateException("unexpected case: " + statsType);
141 + }
142 + }
143 +
144 + private LinkHighlight highlightForStats(StatsType type) {
145 + return new LinkHighlight(linkId(), SECONDARY_HIGHLIGHT)
146 + .setLabel(generateLabel(type));
147 + }
148 +
149 + private LinkHighlight highlightForFlowCount(StatsType type) {
150 + Flavor flavor = flows > 0 ? PRIMARY_HIGHLIGHT : SECONDARY_HIGHLIGHT;
151 + return new LinkHighlight(linkId(), flavor)
152 + .setLabel(generateLabel(type));
153 + }
154 +
155 + private LinkHighlight highlightForTagging(StatsType type) {
156 + LinkHighlight hlite = new LinkHighlight(linkId(), taggedFlavor)
157 + .setLabel(generateLabel(type));
158 + if (isOptical) {
159 + hlite.addMod(LinkHighlight.MOD_OPTICAL);
160 + }
161 + if (antMarch) {
162 + hlite.addMod(LinkHighlight.MOD_ANIMATED);
163 + }
164 + return hlite;
165 + }
166 +
167 + // Generates a string representation of the load, to be used as a label
168 + private String generateLabel(StatsType type) {
169 + switch (type) {
170 + case FLOW_COUNT:
171 + return TopoUtils.formatFlows(flows);
172 +
173 + case FLOW_STATS:
174 + return TopoUtils.formatBytes(bytes);
175 +
176 + case PORT_STATS:
177 + return TopoUtils.formatBitRate(rate);
178 +
179 + case TAGGED:
180 + return hasTraffic ? TopoUtils.formatBytes(bytes) : EMPTY;
181 +
182 + default:
183 + return QUE;
184 + }
185 + }
186 +
187 + /**
188 + * Returns true if this link has been deemed to have enough traffic
189 + * to register on the topology view in the web UI.
190 + *
191 + * @return true if this link has displayable traffic
192 + */
193 + public boolean hasTraffic() {
194 + return hasTraffic;
195 + }
196 +
197 + /**
198 + * Designates type of traffic statistics to report on a highlighted link.
199 + */
200 + public enum StatsType {
201 + /**
202 + * Number of flows.
203 + */
204 + FLOW_COUNT,
205 +
206 + /**
207 + * Number of bytes.
208 + */
209 + FLOW_STATS,
210 +
211 + /**
212 + * Number of bits per second.
213 + */
214 + PORT_STATS,
215 +
216 + /**
217 + * Custom tagged information.
218 + */
219 + TAGGED
220 + }
221 +}
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 + */
17 +
18 +package org.onosproject.ui.impl.topo;
19 +
20 +import org.onosproject.net.Link;
21 +import org.onosproject.net.LinkKey;
22 +
23 +/**
24 + * Collection of {@link TrafficLink}s.
25 + */
26 +public class TrafficLinkMap extends BiLinkMap<TrafficLink> {
27 +
28 + @Override
29 + public TrafficLink create(LinkKey key, Link link) {
30 + return new TrafficLink(key, link);
31 + }
32 +}