| /* |
| * Copyright 2016-present Open Networking Laboratory |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| package org.onosproject.ui.impl.topo.util; |
| |
| import org.onosproject.net.Link; |
| import org.onosproject.net.LinkKey; |
| import org.onosproject.net.statistic.Load; |
| import org.onosproject.ui.topo.BiLink; |
| import org.onosproject.ui.topo.LinkHighlight; |
| import org.onosproject.ui.topo.LinkHighlight.Flavor; |
| import org.onosproject.ui.topo.Mod; |
| import org.onosproject.ui.topo.TopoUtils.Magnitude; |
| import org.onosproject.ui.topo.TopoUtils.ValueLabel; |
| |
| import java.util.HashSet; |
| import java.util.Set; |
| |
| import static org.onosproject.ui.topo.LinkHighlight.Flavor.NO_HIGHLIGHT; |
| import static org.onosproject.ui.topo.LinkHighlight.Flavor.PRIMARY_HIGHLIGHT; |
| import static org.onosproject.ui.topo.LinkHighlight.Flavor.SECONDARY_HIGHLIGHT; |
| import static org.onosproject.ui.topo.TopoUtils.formatBytes; |
| import static org.onosproject.ui.topo.TopoUtils.formatClippedBitRate; |
| import static org.onosproject.ui.topo.TopoUtils.formatFlows; |
| import static org.onosproject.ui.topo.TopoUtils.formatPacketRate; |
| |
| /** |
| * Representation of a link and its inverse, and associated traffic data. |
| * This class understands how to generate the appropriate |
| * {@link LinkHighlight}s for showing traffic data on the topology view. |
| */ |
| public class TrafficLink extends BiLink { |
| private static final Mod PORT_TRAFFIC_GREEN = new Mod("port-traffic-green"); |
| private static final Mod PORT_TRAFFIC_YELLOW = new Mod("port-traffic-yellow"); |
| private static final Mod PORT_TRAFFIC_ORANGE = new Mod("port-traffic-orange"); |
| private static final Mod PORT_TRAFFIC_RED = new Mod("port-traffic-red"); |
| |
| private static final String EMPTY = ""; |
| |
| private long bytes = 0; |
| private long rate = 0; |
| private long flows = 0; |
| private Flavor taggedFlavor = NO_HIGHLIGHT; |
| private boolean hasTraffic = false; |
| private boolean isOptical = false; |
| private boolean antMarch = false; |
| private Set<Mod> mods = new HashSet<>(); |
| |
| /** |
| * Constructs a traffic link for the given key and initial link. |
| * |
| * @param key canonical key for this traffic link |
| * @param link first link |
| */ |
| public TrafficLink(LinkKey key, Link link) { |
| super(key, link); |
| } |
| |
| /** |
| * Sets the optical flag to the given value. |
| * |
| * @param b true if an optical link |
| * @return self, for chaining |
| */ |
| public TrafficLink optical(boolean b) { |
| isOptical = b; |
| return this; |
| } |
| |
| /** |
| * Sets the ant march flag to the given value. |
| * |
| * @param b true if marching ants required |
| * @return self, for chaining |
| */ |
| public TrafficLink antMarch(boolean b) { |
| antMarch = b; |
| return this; |
| } |
| |
| /** |
| * Tags this traffic link with the flavor to be used in visual rendering. |
| * |
| * @param flavor the flavor to tag |
| * @return self, for chaining |
| */ |
| public TrafficLink tagFlavor(Flavor flavor) { |
| taggedFlavor = flavor; |
| return this; |
| } |
| |
| /** |
| * Tags this traffic link with the mods to be used in visual rendering. |
| * |
| * @param mods the mods to tag on this link |
| * @return self, for chaining |
| */ |
| public TrafficLink tagMods(Set<Mod> mods) { |
| if (mods != null) { |
| this.mods.addAll(mods); |
| } |
| return this; |
| } |
| |
| /** |
| * Adds load statistics, marks the traffic link as having traffic. |
| * |
| * @param load load to add |
| */ |
| public void addLoad(Load load) { |
| addLoad(load, 0); |
| } |
| |
| /** |
| * Adds load statistics, marks the traffic link as having traffic, if the |
| * load {@link Load#rate rate} is greater than the given threshold |
| * (expressed in bytes per second). |
| * |
| * @param load load to add |
| * @param threshold threshold to register traffic |
| */ |
| public void addLoad(Load load, double threshold) { |
| if (load != null) { |
| this.hasTraffic = hasTraffic || load.rate() > threshold; |
| this.bytes += load.latest(); |
| this.rate += load.rate(); |
| } |
| } |
| |
| /** |
| * Adds the given count of flows to this traffic link. |
| * |
| * @param count count of flows |
| */ |
| public void addFlows(int count) { |
| this.flows += count; |
| } |
| |
| @Override |
| public LinkHighlight highlight(Enum<?> type) { |
| StatsType statsType = (StatsType) type; |
| switch (statsType) { |
| case FLOW_COUNT: |
| return highlightForFlowCount(); |
| |
| case FLOW_STATS: |
| case PORT_STATS: |
| case PORT_PACKET_STATS: |
| return highlightForStats(statsType); |
| |
| case TAGGED: |
| return highlightForTagging(); |
| |
| default: |
| throw new IllegalStateException("unexpected case: " + statsType); |
| } |
| } |
| |
| private LinkHighlight highlightForStats(StatsType type) { |
| ValueLabel vl = null; |
| Mod m = null; |
| |
| // based on the type of stats, need to determine the label and "color"... |
| switch (type) { |
| case FLOW_STATS: |
| vl = formatBytes(bytes); |
| // default to "secondary highlighting" of link |
| break; |
| |
| case PORT_STATS: |
| vl = formatClippedBitRate(rate); |
| |
| // set color based on bits per second... |
| if (vl.magnitude() == Magnitude.ONE || |
| vl.magnitude() == Magnitude.KILO) { |
| m = PORT_TRAFFIC_GREEN; |
| |
| } else if (vl.magnitude() == Magnitude.MEGA) { |
| m = PORT_TRAFFIC_YELLOW; |
| |
| } else if (vl.magnitude() == Magnitude.GIGA) { |
| m = vl.clipped() ? PORT_TRAFFIC_RED : PORT_TRAFFIC_ORANGE; |
| } |
| break; |
| |
| case PORT_PACKET_STATS: |
| vl = formatPacketRate(rate); |
| |
| // FIXME: Provisional color threshold parameters for packets |
| // set color based on bits per second... |
| if (rate < 10) { |
| m = PORT_TRAFFIC_GREEN; |
| |
| } else if (rate < 1000) { |
| m = PORT_TRAFFIC_YELLOW; |
| |
| } else if (rate < 100000) { |
| m = PORT_TRAFFIC_ORANGE; |
| } else { |
| m = PORT_TRAFFIC_RED; |
| } |
| break; |
| |
| default: |
| break; |
| } |
| |
| LinkHighlight hlite = new LinkHighlight(linkId(), SECONDARY_HIGHLIGHT); |
| if (vl != null) { |
| hlite.setLabel(vl.toString()); |
| } |
| if (m != null) { |
| hlite.addMod(m); |
| } |
| |
| return addCustomMods(hlite); |
| } |
| |
| private LinkHighlight highlightForFlowCount() { |
| Flavor flavor = flows > 0 ? PRIMARY_HIGHLIGHT : SECONDARY_HIGHLIGHT; |
| LinkHighlight hlite = new LinkHighlight(linkId(), flavor) |
| .setLabel(formatFlows(flows)); |
| |
| return addCustomMods(hlite); |
| } |
| |
| private LinkHighlight highlightForTagging() { |
| LinkHighlight hlite = new LinkHighlight(linkId(), taggedFlavor) |
| .setLabel(hasTraffic ? formatBytes(bytes).toString() : EMPTY); |
| |
| if (isOptical) { |
| hlite.addMod(LinkHighlight.MOD_OPTICAL); |
| } |
| if (antMarch) { |
| hlite.addMod(LinkHighlight.MOD_ANIMATED); |
| } |
| return addCustomMods(hlite); |
| } |
| |
| private LinkHighlight addCustomMods(LinkHighlight hlite) { |
| if (!mods.isEmpty()) { |
| mods.forEach(hlite::addMod); |
| } |
| return hlite; |
| } |
| |
| /** |
| * Returns true if this link has been deemed to have enough traffic |
| * to register on the topology view in the web UI. |
| * |
| * @return true if this link has displayable traffic |
| */ |
| public boolean hasTraffic() { |
| return hasTraffic; |
| } |
| |
| /** |
| * Designates type of traffic statistics to report on a highlighted link. |
| */ |
| public enum StatsType { |
| /** |
| * Number of flows. |
| */ |
| FLOW_COUNT, |
| |
| /** |
| * Number of bytes. |
| */ |
| FLOW_STATS, |
| |
| /** |
| * Number of bits per second. |
| */ |
| PORT_STATS, |
| |
| /** |
| * Number of packets per second. |
| */ |
| PORT_PACKET_STATS, |
| |
| /** |
| * Custom tagged information. |
| */ |
| TAGGED |
| } |
| } |