Simon Hunt

ONOS-1479 - GUI Topology Overlay Work - (WIP)

- Implemented initial ability to have overlay modify the summary panel data.

Change-Id: I0d6bd6d62f0e0d5ba9d901a47271044e0c8d0c89
......@@ -17,6 +17,7 @@
package org.onosproject.ui;
import org.onosproject.ui.topo.PropertyPanel;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
......@@ -75,4 +76,13 @@ public class UiTopoOverlay {
*/
public void destroy() {
}
/**
* Callback to modify the contents of the summary panel.
* This default implementation does nothing.
*
* @param pp property panel model of summary data
*/
public void modifySummary(PropertyPanel pp) {
}
}
......
/*
* 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 java.util.ArrayList;
import java.util.List;
/**
* Models a panel displayed on the Topology View.
*/
public class PropertyPanel {
private String title;
private String typeId;
private List<Prop> properties = new ArrayList<>();
public PropertyPanel(String title, String typeId) {
this.title = title;
this.typeId = typeId;
}
public PropertyPanel add(Prop p) {
properties.add(p);
return this;
}
public String title() {
return title;
}
public String typeId() {
return typeId;
}
// TODO: consider protecting this?
public List<Prop> properties() {
return properties;
}
public PropertyPanel title(String title) {
this.title = title;
return this;
}
// TODO: add other builder-like setters here
// ====================
public static class Prop {
public final String key;
public final String value;
public Prop(String key, String value) {
this.key = key;
this.value = value;
}
public String key() {
return key;
}
public String value() {
return value;
}
}
// Auxiliary properties separator
public static class Separator extends Prop {
public Separator() {
super("-", "");
}
}
}
......@@ -22,13 +22,22 @@ import org.onosproject.ui.UiTopoOverlay;
import java.util.HashMap;
import java.util.Map;
import static com.google.common.base.Strings.isNullOrEmpty;
/**
* A cache of {@link org.onosproject.ui.UiTopoOverlay}'s that were registered
* at the time the UI connection was established.
*/
public class TopoOverlayCache {
private static final UiTopoOverlay NONE = new NullOverlay();
private final Map<String, UiTopoOverlay> overlays = new HashMap<>();
private UiTopoOverlay current = NONE;
public TopoOverlayCache() {
overlays.put(null, NONE);
}
/**
* Adds a topology overlay to the cache.
......@@ -55,16 +64,18 @@ public class TopoOverlayCache {
public void switchOverlay(String deact, String act) {
UiTopoOverlay toDeactivate = getOverlay(deact);
UiTopoOverlay toActivate = getOverlay(act);
if (toDeactivate != null) {
toDeactivate.deactivate();
}
if (toActivate != null) {
toActivate.activate();
}
toDeactivate.deactivate();
current = toActivate;
current.activate();
}
private UiTopoOverlay getOverlay(String id) {
return id == null ? null : overlays.get(id);
return isNullOrEmpty(id) ? NONE : overlays.get(id);
}
public UiTopoOverlay currentOverlay() {
return current;
}
/**
......@@ -75,4 +86,28 @@ public class TopoOverlayCache {
public int size() {
return overlays.size();
}
private static class NullOverlay extends UiTopoOverlay {
public NullOverlay() {
super(null);
}
@Override
public void init() {
}
@Override
public void activate() {
}
@Override
public void deactivate() {
}
@Override
public void destroy() {
}
}
}
......
......@@ -57,6 +57,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.topo.PropertyPanel;
import java.util.ArrayList;
import java.util.Collection;
......@@ -561,7 +562,10 @@ public class TopologyViewMessageHandler extends TopologyViewMessageHandlerBase {
// Subscribes for summary messages.
private synchronized void requestSummary(long sid) {
sendMessage(summmaryMessage(sid));
PropertyPanel pp = summmaryMessage(sid);
overlayCache.currentOverlay().modifySummary(pp);
ObjectNode json = JsonUtils.envelope("showSummary", sid, json(pp));
sendMessage(json);
}
......
......@@ -72,6 +72,7 @@ import org.onosproject.net.topology.TopologyService;
import org.onosproject.ui.JsonUtils;
import org.onosproject.ui.UiConnection;
import org.onosproject.ui.UiMessageHandler;
import org.onosproject.ui.topo.PropertyPanel;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
......@@ -443,19 +444,20 @@ public abstract class TopologyViewMessageHandlerBase extends UiMessageHandler {
}
// Returns summary response.
protected ObjectNode summmaryMessage(long sid) {
protected PropertyPanel summmaryMessage(long sid) {
Topology topology = topologyService.currentTopology();
return JsonUtils.envelope("showSummary", sid,
json("ONOS Summary", "node",
new Prop("Devices", format(topology.deviceCount())),
new Prop("Links", format(topology.linkCount())),
new Prop("Hosts", format(hostService.getHostCount())),
new Prop("Topology SCCs", format(topology.clusterCount())),
new Separator(),
new Prop("Intents", format(intentService.getIntentCount())),
new Prop("Tunnels", format(tunnelService.tunnelCount())),
new Prop("Flows", format(flowService.getFlowRuleCount())),
new Prop("Version", version)));
PropertyPanel pp = new PropertyPanel("ONOS Summary", "node")
.add(new PropertyPanel.Prop("Devices", format(topology.deviceCount())))
.add(new PropertyPanel.Prop("Links", format(topology.linkCount())))
.add(new PropertyPanel.Prop("Hosts", format(hostService.getHostCount())))
.add(new PropertyPanel.Prop("Topology SCCs", format(topology.clusterCount())))
.add(new PropertyPanel.Separator())
.add(new PropertyPanel.Prop("Intents", format(intentService.getIntentCount())))
.add(new PropertyPanel.Prop("Tunnels", format(tunnelService.tunnelCount())))
.add(new PropertyPanel.Prop("Flows", format(flowService.getFlowRuleCount())))
.add(new PropertyPanel.Prop("Version", version));
return pp;
}
// Returns device details response.
......@@ -840,6 +842,20 @@ public abstract class TopologyViewMessageHandlerBase extends UiMessageHandler {
link.dst().elementId(), link.dst().port());
}
protected ObjectNode json(PropertyPanel pp) {
ObjectNode result = objectNode()
.put("title", pp.title()).put("type", pp.typeId());
ObjectNode pnode = objectNode();
ArrayNode porder = arrayNode();
for (PropertyPanel.Prop p : pp.properties()) {
porder.add(p.key());
pnode.put(p.key(), p.value());
}
result.set("propOrder", porder);
result.set("props", pnode);
return result;
}
// Produces JSON property details.
private ObjectNode json(String id, String type, Prop... props) {
ObjectNode result = objectNode()
......
......@@ -126,6 +126,9 @@
current = overlay(id);
current && doop('activate');
wss.sendEvent('topoSelectOverlay', payload);
// TODO: refactor to emit "flush on overlay change" messages
wss.sendEvent('requestSummary');
}
}
......
......@@ -208,7 +208,7 @@
gs.addGlyph(svg, 'node', 40);
gs.addGlyph(svg, 'bird', 24, true, [8,12]);
title.text(data.id);
title.text(data.title);
listProps(tbody, data);
}
......