Simon Hunt

ONOS-2186 - GUI Topo Overlay - (WIP)

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

Change-Id: Icfa85bc44a223c6cf245a4005170583dad1cc801
Showing 20 changed files with 603 additions and 325 deletions
......@@ -18,22 +18,38 @@
package org.onosproject.ui.topo;
/**
* Partial implementation of the types of highlight to apply to topology
* elements.
* Partial implementation of the highlighting to apply to topology
* view elements.
*/
public abstract class AbstractHighlight {
private final TopoElementType type;
private final String elementId;
/**
* Constructs the highlight.
*
* @param type highlight element type
* @param elementId element identifier
*/
public AbstractHighlight(TopoElementType type, String elementId) {
this.type = type;
this.elementId = elementId;
}
/**
* Returns the element type.
*
* @return element type
*/
public TopoElementType type() {
return type;
}
/**
* Returns the element identifier.
*
* @return element identifier
*/
public String elementId() {
return elementId;
}
......
......@@ -18,7 +18,7 @@
package org.onosproject.ui.topo;
/**
* Denotes the types of highlight to apply to a link.
* Denotes the highlighting to apply to a device.
*/
public class DeviceHighlight extends AbstractHighlight {
......@@ -26,5 +26,8 @@ public class DeviceHighlight extends AbstractHighlight {
super(TopoElementType.DEVICE, deviceId);
}
// TODO: implement device highlighting:
// - visual highlight
// - badging
}
......
......@@ -18,7 +18,7 @@
package org.onosproject.ui.topo;
/**
* Denotes the types of highlight to apply to a link.
* Denotes the highlighting to apply to a host.
*/
public class HostHighlight extends AbstractHighlight {
......@@ -26,5 +26,8 @@ public class HostHighlight extends AbstractHighlight {
super(TopoElementType.HOST, hostId);
}
// TODO: implement host highlighting:
// - visual highlight
// - badging
}
......
......@@ -27,8 +27,8 @@ import static com.google.common.base.Preconditions.checkNotNull;
* Denotes the highlighting to be applied to a link.
* {@link Flavor} is a closed set of NO-, PRIMARY-, or SECONDARY- highlighting.
* {@link Mod} is an open ended set of additional modifications (CSS classes)
* to apply. Note that {@link #MOD_OPTICAL} and {@link #MOD_ANIMATED} are
* pre-defined mods.
* that may also be applied.
* Note that {@link #MOD_OPTICAL} and {@link #MOD_ANIMATED} are pre-defined mods.
* Label text may be set, which will also be displayed on the link.
*/
public class LinkHighlight extends AbstractHighlight {
......@@ -136,48 +136,6 @@ public class LinkHighlight extends AbstractHighlight {
}
/**
* Link highlighting modification.
* <p>
* Note that this translates to a CSS class name that is applied to
* the link in the Topology UI.
*/
public static final class Mod implements Comparable<Mod> {
private final String modId;
public Mod(String modId) {
this.modId = checkNotNull(modId);
}
@Override
public String toString() {
return modId;
}
@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass()) {
return false;
}
Mod mod = (Mod) o;
return modId.equals(mod.modId);
}
@Override
public int hashCode() {
return modId.hashCode();
}
@Override
public int compareTo(Mod o) {
return this.modId.compareTo(o.modId);
}
}
/**
* Denotes a link to be tagged as an optical link.
*/
public static final Mod MOD_OPTICAL = new Mod("optical");
......
/*
* Copyright 2015 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.topo;
import static com.google.common.base.Preconditions.checkNotNull;
/**
* Highlighting modification.
* <p>
* Note that (for link highlights) this translates to a CSS class name
* that is applied to the link in the Topology UI.
*/
public final class Mod implements Comparable<Mod> {
private final String modId;
/**
* Constructs a mod with the given identifier.
*
* @param modId modification identifier
*/
public Mod(String modId) {
this.modId = checkNotNull(modId);
}
@Override
public String toString() {
return modId;
}
@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass()) {
return false;
}
Mod mod = (Mod) o;
return modId.equals(mod.modId);
}
@Override
public int hashCode() {
return modId.hashCode();
}
@Override
public int compareTo(Mod o) {
return this.modId.compareTo(o.modId);
}
}
......@@ -18,21 +18,18 @@ package org.onosproject.ui.impl;
import com.fasterxml.jackson.databind.node.ObjectNode;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Maps;
import org.onosproject.net.Link;
import org.onosproject.net.LinkKey;
import org.onosproject.net.link.LinkService;
import org.onosproject.ui.RequestHandler;
import org.onosproject.ui.UiMessageHandler;
import org.onosproject.ui.impl.topo.BiLink;
import org.onosproject.ui.impl.topo.TopoUtils;
import org.onosproject.ui.impl.topo.BaseLink;
import org.onosproject.ui.impl.topo.BaseLinkMap;
import org.onosproject.ui.table.TableModel;
import org.onosproject.ui.table.TableRequestHandler;
import org.onosproject.ui.table.cell.ConnectPointFormatter;
import org.onosproject.ui.table.cell.EnumFormatter;
import java.util.Collection;
import java.util.Map;
/**
* Message handler for link view related messages.
......@@ -41,6 +38,7 @@ public class LinkViewMessageHandler extends UiMessageHandler {
private static final String A_BOTH_B = "A &harr; B";
private static final String A_SINGLE_B = "A &rarr; B";
private static final String SLASH = " / ";
private static final String LINK_DATA_REQ = "linkDataRequest";
private static final String LINK_DATA_RESP = "linkDataResponse";
......@@ -93,42 +91,37 @@ public class LinkViewMessageHandler extends UiMessageHandler {
@Override
protected void populateTable(TableModel tm, ObjectNode payload) {
LinkService ls = get(LinkService.class);
// First consolidate all uni-directional links into two-directional ones.
Map<LinkKey, BiLink> biLinks = Maps.newHashMap();
ls.getLinks().forEach(link -> TopoUtils.addLink(biLinks, link));
// Now scan over all bi-links and produce table rows from them.
biLinks.values().forEach(biLink -> populateRow(tm.addRow(), biLink));
BaseLinkMap linkMap = new BaseLinkMap();
ls.getLinks().forEach(linkMap::add);
linkMap.biLinks().forEach(blink -> populateRow(tm.addRow(), blink));
}
private void populateRow(TableModel.Row row, BiLink biLink) {
row.cell(ONE, biLink.one().src())
.cell(TWO, biLink.one().dst())
.cell(TYPE, linkType(biLink))
.cell(STATE, linkState(biLink))
.cell(DIRECTION, linkDir(biLink))
.cell(DURABLE, biLink.one().isDurable());
private void populateRow(TableModel.Row row, BaseLink blink) {
row.cell(ONE, blink.one().src())
.cell(TWO, blink.one().dst())
.cell(TYPE, linkType(blink))
.cell(STATE, linkState(blink))
.cell(DIRECTION, linkDir(blink))
.cell(DURABLE, blink.one().isDurable());
}
private String linkType(BiLink link) {
private String linkType(BaseLink link) {
StringBuilder sb = new StringBuilder();
sb.append(link.one().type());
if (link.two() != null && link.two().type() != link.one().type()) {
sb.append(" / ").append(link.two().type());
sb.append(SLASH).append(link.two().type());
}
return sb.toString();
}
private String linkState(BiLink link) {
private String linkState(BaseLink link) {
return (link.one().state() == Link.State.ACTIVE ||
link.two().state() == Link.State.ACTIVE) ?
ICON_ID_ONLINE : ICON_ID_OFFLINE;
}
private String linkDir(BiLink link) {
private String linkDir(BaseLink link) {
return link.two() != null ? A_BOTH_B : A_SINGLE_B;
}
}
}
......
......@@ -56,7 +56,7 @@ import org.onosproject.net.link.LinkListener;
import org.onosproject.ui.JsonUtils;
import org.onosproject.ui.RequestHandler;
import org.onosproject.ui.UiConnection;
import org.onosproject.ui.impl.TrafficMonitorObject.Mode;
import org.onosproject.ui.impl.TrafficMonitor.Mode;
import org.onosproject.ui.impl.topo.NodeSelection;
import org.onosproject.ui.topo.Highlights;
import org.onosproject.ui.topo.PropertyPanel;
......@@ -162,9 +162,8 @@ public class TopologyViewMessageHandler extends TopologyViewMessageHandlerBase {
private final ExecutorService msgSender =
newSingleThreadExecutor(groupedThreads("onos/gui", "msg-sender"));
private TrafficMonitorObject tmo;
private TopoOverlayCache overlayCache;
private TrafficMonitor traffic;
private TimerTask summaryTask = null;
private boolean summaryRunning = false;
......@@ -176,7 +175,7 @@ public class TopologyViewMessageHandler extends TopologyViewMessageHandlerBase {
public void init(UiConnection connection, ServiceDirectory directory) {
super.init(connection, directory);
appId = directory.get(CoreService.class).registerApplication(APP_ID);
tmo = new TrafficMonitorObject(TRAFFIC_PERIOD, servicesBundle, this);
traffic = new TrafficMonitor(TRAFFIC_PERIOD, servicesBundle, this);
}
@Override
......@@ -275,7 +274,7 @@ public class TopologyViewMessageHandler extends TopologyViewMessageHandlerBase {
@Override
public void process(long sid, ObjectNode payload) {
stopSummaryMonitoring();
tmo.stop();
traffic.stopMonitoring();
}
}
......@@ -400,7 +399,7 @@ public class TopologyViewMessageHandler extends TopologyViewMessageHandlerBase {
.build();
intentService.submit(intent);
tmo.monitor(intent);
traffic.monitor(intent);
}
}
......@@ -433,7 +432,7 @@ public class TopologyViewMessageHandler extends TopologyViewMessageHandlerBase {
.build();
intentService.submit(intent);
tmo.monitor(intent);
traffic.monitor(intent);
}
}
......@@ -446,7 +445,7 @@ public class TopologyViewMessageHandler extends TopologyViewMessageHandlerBase {
@Override
public void process(long sid, ObjectNode payload) {
tmo.monitor(Mode.ALL_FLOW_TRAFFIC);
traffic.monitor(Mode.ALL_FLOW_TRAFFIC);
}
}
......@@ -457,7 +456,7 @@ public class TopologyViewMessageHandler extends TopologyViewMessageHandlerBase {
@Override
public void process(long sid, ObjectNode payload) {
tmo.monitor(Mode.ALL_PORT_TRAFFIC);
traffic.monitor(Mode.ALL_PORT_TRAFFIC);
}
}
......@@ -470,7 +469,7 @@ public class TopologyViewMessageHandler extends TopologyViewMessageHandlerBase {
public void process(long sid, ObjectNode payload) {
NodeSelection nodeSelection =
new NodeSelection(payload, deviceService, hostService);
tmo.monitor(Mode.DEV_LINK_FLOWS, nodeSelection);
traffic.monitor(Mode.DEV_LINK_FLOWS, nodeSelection);
}
}
......@@ -483,7 +482,7 @@ public class TopologyViewMessageHandler extends TopologyViewMessageHandlerBase {
public void process(long sid, ObjectNode payload) {
NodeSelection nodeSelection =
new NodeSelection(payload, deviceService, hostService);
tmo.monitor(Mode.RELATED_INTENTS, nodeSelection);
traffic.monitor(Mode.RELATED_INTENTS, nodeSelection);
}
}
......@@ -494,7 +493,7 @@ public class TopologyViewMessageHandler extends TopologyViewMessageHandlerBase {
@Override
public void process(long sid, ObjectNode payload) {
tmo.selectNextIntent();
traffic.selectNextIntent();
}
}
......@@ -505,7 +504,7 @@ public class TopologyViewMessageHandler extends TopologyViewMessageHandlerBase {
@Override
public void process(long sid, ObjectNode payload) {
tmo.selectPreviousIntent();
traffic.selectPreviousIntent();
}
}
......@@ -516,7 +515,7 @@ public class TopologyViewMessageHandler extends TopologyViewMessageHandlerBase {
@Override
public void process(long sid, ObjectNode payload) {
tmo.monitor(Mode.SEL_INTENT);
traffic.monitor(Mode.SELECTED_INTENT);
}
}
......@@ -527,7 +526,7 @@ public class TopologyViewMessageHandler extends TopologyViewMessageHandlerBase {
@Override
public void process(long sid, ObjectNode payload) {
tmo.stop();
traffic.stopMonitoring();
}
}
......@@ -557,7 +556,7 @@ public class TopologyViewMessageHandler extends TopologyViewMessageHandlerBase {
private void cancelAllRequests() {
stopSummaryMonitoring();
tmo.stop();
traffic.stopMonitoring();
}
// Sends all controller nodes to the client as node-added messages.
......@@ -726,7 +725,7 @@ public class TopologyViewMessageHandler extends TopologyViewMessageHandlerBase {
private class InternalIntentListener implements IntentListener {
@Override
public void event(IntentEvent event) {
msgSender.execute(tmo::pokeIntent);
msgSender.execute(traffic::pokeIntent);
eventAccummulator.add(event);
}
}
......
/*
* Copyright 2015 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;
import org.onosproject.net.Link;
import org.onosproject.net.LinkKey;
import org.onosproject.ui.topo.LinkHighlight;
/**
* A simple concrete implementation of a {@link BiLink}.
* Note that this implementation does not generate any link highlights.
*/
public class BaseLink extends BiLink {
/**
* Constructs a base link for the given key and initial link.
*
* @param key canonical key for this base link
* @param link first link
*/
public BaseLink(LinkKey key, Link link) {
super(key, link);
}
@Override
public LinkHighlight highlight(Enum<?> type) {
return null;
}
}
......@@ -17,27 +17,15 @@
package org.onosproject.ui.impl.topo;
import org.onosproject.net.Link;
import org.onosproject.net.LinkKey;
/**
* Designates type of stats to report on a highlighted link.
* Collection of {@link BaseLink}s.
*/
public enum LinkStatsType {
/**
* Number of flows.
*/
FLOW_COUNT,
/**
* Number of bytes.
*/
FLOW_STATS,
/**
* Number of bits per second.
*/
PORT_STATS,
/**
* Custom tagged information.
*/
TAGGED
public class BaseLinkMap extends BiLinkMap<BaseLink> {
@Override
public BaseLink create(LinkKey key, Link link) {
return new BaseLink(key, link);
}
}
......
......@@ -19,226 +19,87 @@ package org.onosproject.ui.impl.topo;
import org.onosproject.net.Link;
import org.onosproject.net.LinkKey;
import org.onosproject.net.statistic.Load;
import org.onosproject.ui.topo.LinkHighlight;
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 com.google.common.base.Preconditions.checkNotNull;
/**
* Representation of a link and its inverse, and any associated traffic data.
* This class understands how to generate {@link LinkHighlight}s for sending
* back to the topology view.
* Representation of a link and its inverse, as a partial implementation.
* <p>
* Subclasses will decide how to generate the link highlighting (coloring
* and labeling) for the topology view.
*/
public class BiLink {
private static final String EMPTY = "";
public abstract class BiLink {
private final LinkKey key;
private final Link one;
private Link two;
private boolean hasTraffic = false;
private long bytes = 0;
private long rate = 0;
private long flows = 0;
private boolean isOptical = false;
private LinkHighlight.Flavor taggedFlavor = NO_HIGHLIGHT;
private boolean antMarch = false;
/**
* Constructs a bilink for the given key and initial link.
* Constructs a bi-link for the given key and initial link. It is expected
* that the caller will have used {@link TopoUtils#canonicalLinkKey(Link)}
* to generate the key.
*
* @param key canonical key for this bilink
* @param key canonical key for this bi-link
* @param link first link
*/
public BiLink(LinkKey key, Link link) {
this.key = key;
this.one = link;
this.key = checkNotNull(key);
this.one = checkNotNull(link);
}
/**
* Sets the second link for this bilink.
* Sets the second link for this bi-link.
*
* @param link second link
*/
public void setOther(Link link) {
this.two = link;
this.two = checkNotNull(link);
}
/**
* Sets the optical flag to the given value.
* Returns the link identifier in the form expected on the Topology View
* in the web client.
*
* @param b true if an optical link
* @return link identifier
*/
public void setOptical(boolean b) {
isOptical = b;
}
/**
* Sets the ant march flag to the given value.
*
* @param b true if marching ants required
*/
public void setAntMarch(boolean b) {
antMarch = b;
}
/**
* Tags this bilink with a link flavor to be used in visual rendering.
*
* @param flavor the flavor to tag
*/
public void tagFlavor(LinkHighlight.Flavor flavor) {
this.taggedFlavor = flavor;
public String linkId() {
return TopoUtils.compactLinkString(one);
}
/**
* Adds load statistics, marks the bilink as having traffic.
* Returns the key for this bi-link.
*
* @param load load to add
* @return the key
*/
public void addLoad(Load load) {
addLoad(load, 0);
public LinkKey key() {
return key;
}
/**
* Adds load statistics, marks the bilink as having traffic, if the
* load rate is greater than the given threshold.
* Returns the first link in this bi-link.
*
* @param load load to add
* @param threshold threshold to register traffic
* @return the first link
*/
public void addLoad(Load load, double threshold) {
if (load != null) {
this.hasTraffic = hasTraffic || load.rate() > threshold;
this.bytes += load.latest();
this.rate += load.rate();
}
public Link one() {
return one;
}
/**
* Adds the given count of flows to this bilink.
* Returns the second link in this bi-link.
*
* @param count count of flows
* @return the second link
*/
public void addFlows(int count) {
this.flows += count;
public Link two() {
return two;
}
/**
* Generates a link highlight entity, based on state of this bilink.
* Returns the link highlighting to use, based on this bi-link's current
* state.
*
* @param type the type of statistics to use to interpret the data
* @return link highlight data for this bilink
* @param type optional highlighting type parameter
* @return link highlighting model
*/
public LinkHighlight generateHighlight(LinkStatsType type) {
switch (type) {
case FLOW_COUNT:
return highlightForFlowCount(type);
case FLOW_STATS:
case PORT_STATS:
return highlightForStats(type);
case TAGGED:
return highlightForTagging(type);
default:
throw new IllegalStateException("unexpected case: " + type);
}
}
private LinkHighlight highlightForStats(LinkStatsType type) {
return new LinkHighlight(linkId(), SECONDARY_HIGHLIGHT)
.setLabel(generateLabel(type));
}
private LinkHighlight highlightForFlowCount(LinkStatsType type) {
LinkHighlight.Flavor flavor = flows() > 0 ?
PRIMARY_HIGHLIGHT : SECONDARY_HIGHLIGHT;
return new LinkHighlight(linkId(), flavor)
.setLabel(generateLabel(type));
}
private LinkHighlight highlightForTagging(LinkStatsType type) {
LinkHighlight hlite = new LinkHighlight(linkId(), flavor())
.setLabel(generateLabel(type));
if (isOptical()) {
hlite.addMod(LinkHighlight.MOD_OPTICAL);
}
if (isAntMarch()) {
hlite.addMod(LinkHighlight.MOD_ANIMATED);
}
return hlite;
}
// Generates a link identifier in the form that the Topology View on the
private String linkId() {
return TopoUtils.compactLinkString(one);
}
// Generates a string representation of the load, to be used as a label
private String generateLabel(LinkStatsType type) {
switch (type) {
case FLOW_COUNT:
return TopoUtils.formatFlows(flows());
case FLOW_STATS:
return TopoUtils.formatBytes(bytes());
case PORT_STATS:
return TopoUtils.formatBitRate(rate());
case TAGGED:
return hasTraffic() ? TopoUtils.formatBytes(bytes()) : EMPTY;
default:
return "?";
}
}
// === ----------------------------------------------------------------
// accessors
public LinkKey key() {
return key;
}
public Link one() {
return one;
}
public Link two() {
return two;
}
public boolean hasTraffic() {
return hasTraffic;
}
public boolean isOptical() {
return isOptical;
}
public boolean isAntMarch() {
return antMarch;
}
public LinkHighlight.Flavor flavor() {
return taggedFlavor;
}
public long bytes() {
return bytes;
}
public long rate() {
return rate;
}
public long flows() {
return flows;
}
public abstract LinkHighlight highlight(Enum<?> type);
}
......
/*
* Copyright 2015 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;
import org.onosproject.net.Link;
import org.onosproject.net.LinkKey;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
import static com.google.common.base.Preconditions.checkNotNull;
/**
* Represents a collection of {@link BiLink} concrete classes. These maps
* are used to collate a set of unidirectional {@link Link}s into a smaller
* set of bi-directional {@link BiLink} derivatives.
* <p>
* @param <B> the type of bi-link subclass
*/
public abstract class BiLinkMap<B extends BiLink> {
private final Map<LinkKey, B> map = new HashMap<>();
/**
* Creates a new instance of a bi-link. Concrete subclasses should
* instantiate and return the appropriate bi-link subclass.
*
* @param key the link key
* @param link the initial link
* @return a new instance
*/
public abstract B create(LinkKey key, Link link);
/**
* Adds the given link to our collection, returning the corresponding
* bi-link (creating one if needed necessary).
*
* @param link the link to add to the collection
* @return the corresponding bi-link wrapper
*/
public B add(Link link) {
LinkKey key = TopoUtils.canonicalLinkKey(checkNotNull(link));
B blink = map.get(key);
if (blink == null) {
// no bi-link yet exists for this link
blink = create(key, link);
map.put(key, blink);
} else {
// we have a bi-link for this link.
if (!blink.one().equals(link)) {
blink.setOther(link);
}
}
return blink;
}
/**
* Returns the bi-link instances in the collection.
*
* @return the bi-links in this map
*/
public Collection<B> biLinks() {
return map.values();
}
/**
* Returns the number of bi-links in the collection.
*
* @return number of bi-links
*/
public int size() {
return map.size();
}
}
......@@ -47,7 +47,7 @@ public class IntentSelection {
* @param nodes node selection
* @param filter intent filter
*/
public IntentSelection(NodeSelection nodes, TopologyViewIntentFilter filter) {
public IntentSelection(NodeSelection nodes, TopoIntentFilter filter) {
this.nodes = nodes;
intents = filter.findPathIntents(nodes.hosts(), nodes.devices());
}
......
......@@ -41,7 +41,7 @@ import static org.onosproject.net.HostId.hostId;
*/
public class NodeSelection {
protected static final Logger log =
private static final Logger log =
LoggerFactory.getLogger(NodeSelection.class);
private static final String IDS = "ids";
......@@ -183,5 +183,4 @@ public class NodeSelection {
}
return unmatched;
}
}
......
......@@ -42,6 +42,7 @@ public class ServicesBundle {
/**
* Creates the services bundle.
*
* @param intentService intent service reference
* @param deviceService device service reference
* @param hostService host service reference
......@@ -66,30 +67,65 @@ public class ServicesBundle {
this.portStatsService = checkNotNull(portStatsService);
}
/**
* Returns a reference to the intent service.
*
* @return intent service reference
*/
public IntentService intentService() {
return intentService;
}
/**
* Returns a reference to the device service.
*
* @return device service reference
*/
public DeviceService deviceService() {
return deviceService;
}
/**
* Returns a reference to the host service.
*
* @return host service reference
*/
public HostService hostService() {
return hostService;
}
/**
* Returns a reference to the link service.
*
* @return link service reference
*/
public LinkService linkService() {
return linkService;
}
/**
* Returns a reference to the flow rule service.
*
* @return flow service reference
*/
public FlowRuleService flowService() {
return flowService;
}
/**
* Returns a reference to the flow statistics service.
*
* @return flow statistics service reference
*/
public StatisticService flowStatsService() {
return flowStatsService;
}
/**
* Returns a reference to the port statistics service.
*
* @return port statistics service reference
*/
public PortStatisticsService portStatsService() {
return portStatsService;
}
......
......@@ -48,7 +48,7 @@ import static org.onosproject.net.intent.IntentState.INSTALLED;
* Auxiliary facility to query the intent service based on the specified
* set of end-station hosts, edge points or infrastructure devices.
*/
public class TopologyViewIntentFilter {
public class TopoIntentFilter {
private final IntentService intentService;
private final DeviceService deviceService;
......@@ -60,19 +60,13 @@ public class TopologyViewIntentFilter {
*
* @param services service references bundle
*/
public TopologyViewIntentFilter(ServicesBundle services) {
public TopoIntentFilter(ServicesBundle services) {
this.intentService = services.intentService();
this.deviceService = services.deviceService();
this.hostService = services.hostService();
this.linkService = services.linkService();
}
// TODO: Review - do we need this signature, with sourceIntents??
// public List<Intent> findPathIntents(Set<Host> hosts, Set<Device> devices,
// Iterable<Intent> sourceIntents) {
// }
/**
* Finds all path (host-to-host or point-to-point) intents that pertain
* to the given hosts and devices.
......@@ -277,5 +271,4 @@ public class TopologyViewIntentFilter {
}
return null;
}
}
......
......@@ -21,15 +21,16 @@ import org.onosproject.net.Link;
import org.onosproject.net.LinkKey;
import java.text.DecimalFormat;
import java.util.Map;
import static org.onosproject.net.LinkKey.linkKey;
/**
* Utility methods for helping out with the topology view.
* Utility methods for helping out with formatting data for the Topology View
* in the web client.
*/
public final class TopoUtils {
// explicit decision made to not 'javadoc' these self explanatory constants
public static final double KILO = 1024;
public static final double MEGA = 1024 * KILO;
public static final double GIGA = 1024 * MEGA;
......@@ -155,30 +156,4 @@ public final class TopoUtils {
}
return String.valueOf(flows) + SPACE + (flows > 1 ? FLOWS : FLOW);
}
/**
* Creates a new biLink with the supplied link (and adds it to the map),
* or attaches the link to an existing biLink (which already has the
* peer link).
*
* @param linkMap map of biLinks
* @param link the link to add
* @return the biLink to which the link was added
*/
// creates a new biLink with supplied link, or attaches link to the
// existing biLink (which already has its peer link)
public static BiLink addLink(Map<LinkKey, BiLink> linkMap, Link link) {
LinkKey key = TopoUtils.canonicalLinkKey(link);
BiLink biLink = linkMap.get(key);
if (biLink != null) {
biLink.setOther(link);
} else {
biLink = new BiLink(key, link);
linkMap.put(key, biLink);
}
return biLink;
}
}
......
......@@ -24,6 +24,7 @@ import org.onosproject.ui.topo.LinkHighlight;
* Auxiliary data carrier for assigning a highlight class to a set of
* intents, for visualization in the topology view.
*/
@Deprecated
public class TrafficClass {
private final LinkHighlight.Flavor flavor;
......
/*
* Copyright 2015 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;
import org.onosproject.net.Link;
import org.onosproject.net.LinkKey;
import org.onosproject.net.statistic.Load;
import org.onosproject.ui.topo.LinkHighlight;
import org.onosproject.ui.topo.LinkHighlight.Flavor;
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;
/**
* 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 String EMPTY = "";
private static final String QUE = "?";
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;
/**
* 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) {
this.taggedFlavor = flavor;
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(statsType);
case FLOW_STATS:
case PORT_STATS:
return highlightForStats(statsType);
case TAGGED:
return highlightForTagging(statsType);
default:
throw new IllegalStateException("unexpected case: " + statsType);
}
}
private LinkHighlight highlightForStats(StatsType type) {
return new LinkHighlight(linkId(), SECONDARY_HIGHLIGHT)
.setLabel(generateLabel(type));
}
private LinkHighlight highlightForFlowCount(StatsType type) {
Flavor flavor = flows > 0 ? PRIMARY_HIGHLIGHT : SECONDARY_HIGHLIGHT;
return new LinkHighlight(linkId(), flavor)
.setLabel(generateLabel(type));
}
private LinkHighlight highlightForTagging(StatsType type) {
LinkHighlight hlite = new LinkHighlight(linkId(), taggedFlavor)
.setLabel(generateLabel(type));
if (isOptical) {
hlite.addMod(LinkHighlight.MOD_OPTICAL);
}
if (antMarch) {
hlite.addMod(LinkHighlight.MOD_ANIMATED);
}
return hlite;
}
// Generates a string representation of the load, to be used as a label
private String generateLabel(StatsType type) {
switch (type) {
case FLOW_COUNT:
return TopoUtils.formatFlows(flows);
case FLOW_STATS:
return TopoUtils.formatBytes(bytes);
case PORT_STATS:
return TopoUtils.formatBitRate(rate);
case TAGGED:
return hasTraffic ? TopoUtils.formatBytes(bytes) : EMPTY;
default:
return QUE;
}
}
/**
* 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,
/**
* Custom tagged information.
*/
TAGGED
}
}
/*
* Copyright 2015 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;
import org.onosproject.net.Link;
import org.onosproject.net.LinkKey;
/**
* Collection of {@link TrafficLink}s.
*/
public class TrafficLinkMap extends BiLinkMap<TrafficLink> {
@Override
public TrafficLink create(LinkKey key, Link link) {
return new TrafficLink(key, link);
}
}