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 ↔ B"; | 39 | private static final String A_BOTH_B = "A ↔ B"; |
| 43 | private static final String A_SINGLE_B = "A → B"; | 40 | private static final String A_SINGLE_B = "A → 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 | +} |
-
Please register or login to post a comment