Simon Hunt
Committed by Gerrit Code Review

Implement navigate-to-region (topo2navRegion) event; update scaffolding view (topoX) to exercise.

Change-Id: Ib342f791854664b31bd1724a446008c960231784
......@@ -94,6 +94,26 @@ public class Topo2ViewMessageHandler extends UiMessageHandler {
// ==================================================================
private ObjectNode mkLayoutMessage(UiTopoLayout currentLayout) {
List<UiTopoLayout> crumbs = topoSession.breadCrumbs();
return t2json.layout(currentLayout, crumbs);
}
private ObjectNode mkRegionMessage(UiTopoLayout currentLayout) {
UiRegion region = topoSession.getRegion(currentLayout);
Set<UiRegion> kids = topoSession.getSubRegions(currentLayout);
List<UiSynthLink> links = topoSession.getLinks(currentLayout);
return t2json.region(region, kids, links);
}
private ObjectNode mkPeersMessage(UiTopoLayout currentLayout) {
Set<UiNode> peers = topoSession.getPeerNodes(currentLayout);
ObjectNode peersPayload = objectNode();
peersPayload.set("peers", t2json.closedNodes(peers));
return peersPayload;
}
private final class Topo2Start extends RequestHandler {
private Topo2Start() {
super(START);
......@@ -112,34 +132,26 @@ public class Topo2ViewMessageHandler extends UiMessageHandler {
// correctly
topoSession.refreshModel();
// this is the list of ONOS cluster members
// start with the list of ONOS cluster members
List<UiClusterMember> instances = topoSession.getAllInstances();
sendMessage(ALL_INSTANCES, t2json.instances(instances));
// Send layout, region, peers data...
// this is the layout that the user has chosen to display
UiTopoLayout currentLayout = topoSession.currentLayout();
List<UiTopoLayout> crumbs = topoSession.breadCrumbs();
sendMessage(CURRENT_LAYOUT, t2json.layout(currentLayout, crumbs));
sendMessage(CURRENT_LAYOUT, mkLayoutMessage(currentLayout));
// this is the region that is associated with the current layout
// this message includes details of the sub-regions, devices,
// hosts, and links within the region
// (as well as layer-order hints)
UiRegion region = topoSession.getRegion(currentLayout);
Set<UiRegion> kids = topoSession.getSubRegions(currentLayout);
List<UiSynthLink> links = topoSession.getLinks(currentLayout);
sendMessage(CURRENT_REGION, t2json.region(region, kids, links));
sendMessage(CURRENT_REGION, mkRegionMessage(currentLayout));
// these are the regions/devices that are siblings to this region
Set<UiNode> peers = topoSession.getPeerNodes(currentLayout);
ObjectNode peersPayload = objectNode();
peersPayload.set("peers", t2json.closedNodes(peers));
sendMessage(PEER_REGIONS, peersPayload);
// finally, tell the UI that we are done : TODO review / delete??
sendMessage(TOPO_START_DONE, null);
sendMessage(PEER_REGIONS, mkPeersMessage(currentLayout));
}
}
private final class Topo2NavRegion extends RequestHandler {
......@@ -149,9 +161,19 @@ public class Topo2ViewMessageHandler extends UiMessageHandler {
@Override
public void process(long sid, ObjectNode payload) {
String dir = string(payload, "dir");
String rid = string(payload, "rid");
log.debug("NavRegion: dir={}, rid={}", dir, rid);
log.debug("topo2navRegion: rid={}", rid);
// NOTE: we are NOT re-issuing information about the cluster nodes
// switch to the selected region...
topoSession.navToRegion(rid);
// re-send layout, region, peers data...
UiTopoLayout currentLayout = topoSession.currentLayout();
sendMessage(CURRENT_LAYOUT, mkLayoutMessage(currentLayout));
sendMessage(CURRENT_REGION, mkRegionMessage(currentLayout));
sendMessage(PEER_REGIONS, mkPeersMessage(currentLayout));
}
}
......
......@@ -250,4 +250,18 @@ public class UiTopoSession implements UiModelListener {
public void refreshModel() {
sharedModel.refresh();
}
/**
* Navigates to the specified region by setting the associated layout as
* current.
*
* @param regionId region identifier
*/
public void navToRegion(String regionId) {
// 1. find the layout corresponding to the region ID
// 2. set this layout to be "current"
RegionId r = RegionId.regionId(regionId);
UiTopoLayout layout = layoutService.getLayout(r);
setCurrentLayout(layout);
}
}
......
......@@ -27,18 +27,23 @@
}
#topoXtmp {
height: 600px;
height: 700px;
width: 98%;
overflow-y: scroll;
}
#topoXtmp div {
padding: 8px 24px;
margin: 8px;
padding: 2px 24px;
margin: 6px;
background-color: #ddddff;
}
#topoXtmp div div {
padding: 4px 10px;
padding: 0 10px;
}
#topoXtmp div div span {
color: purple;
font-style: italic;
font-weight: bold;
}
#topoXtmp h4 {
......@@ -54,4 +59,9 @@
font-weight: bold;
text-decoration: underline;
cursor: pointer;
color: blue;
}
.subRegions div p {
width: 40px;
}
......
......@@ -17,11 +17,33 @@
<!-- Topology View partial HTML -->
<div id="ov-topoX">
<div id="topoXtmp">
<div class="parentRegion">
Parent Region: <span> - </span>
<div class="instances">
<h4>Instances</h4>
<div></div>
</div>
<div class="layoutData">
<h4>Layout Data</h4>
<div class="l_id">
Layout ID: <span> - </span>
</div>
<div class="l_parent">
Layout Parent: <span> - </span>
</div>
<div class="l_region">
Region ID: <span> - </span>
</div>
<div class="l_regionName">
Region Name: <span> - </span>
</div>
<div class="l_crumbs">
Breadcrumbs: <span> </span>
</div>
</div>
<div class="thisRegion">
This Region: <span> - </span>
<b>This Region ID:</b> <span></span>
</div>
<div class="subRegions">
<h4>Subregions</h4>
......
......@@ -25,9 +25,13 @@
// injected refs
var $log, wss;
// selected DOM refs
var topdiv;
// ========================== Helper Functions
function init() {
topdiv = d3.select('#topoXtmp');
$log.debug('Initialize topo force layout');
}
......@@ -35,44 +39,82 @@
$log.debug('Destroy topo force layout');
}
// ========================== Temporary Code (to be deleted later)
function rmP(div) {
div.selectAll('p').remove();
}
function request(dir, rid) {
function navRequest(rid) {
wss.sendEvent('topo2navRegion', {
dir: dir,
rid: rid
});
}
function doTmpInstances(data) {
var idiv = topdiv.select('.instances').select('div');
data.members.forEach(function (m) {
idiv.append('div').text(m.id);
});
}
function doTmpCurrentLayout(data) {
var topdiv = d3.select('#topoXtmp');
var parentRegion = data.parent;
var span = topdiv.select('.parentRegion').select('span');
span.text(parentRegion || '[no parent]');
span.classed('nav-me', !!parentRegion);
var ldDiv = topdiv.select('.layoutData'),
bcs = ldDiv.select('.l_crumbs');
function setSpan(v, val) {
var cls = '.l_' + v,
span = ldDiv.select(cls).select('span'),
value = val || data[v];
span.html(value);
}
setSpan('id');
setSpan('parent');
setSpan('region');
setSpan('regionName');
addCrumbNav(bcs, data.crumbs, data.region);
}
function addCrumbNav(span, array, id) {
var rev = [];
span.selectAll('span').remove();
array.forEach(function (a) {
rev.unshift(a.id);
});
rev.forEach(function (rid, idx) {
if (idx) {
span.append('span').text(' +++ ');
}
if (rid != id) {
addNavigable(span, 'span', rid);
} else {
span.append('span').text(rid);
}
});
}
function addNavigable(span, what, rid) {
span.append(what).classed('nav-me', true)
.text(rid)
.on('click', function () { navRequest(rid); });
}
function doTmpCurrentRegion(data) {
var topdiv = d3.select('#topoXtmp');
var span = topdiv.select('.thisRegion').select('span');
var div;
span.text(data.id);
div = topdiv.select('.subRegions').select('div');
rmP(div);
data.subregions.forEach(function (r) {
function nav() {
request('down', r.id);
}
div.append('p')
.classed('nav-me', true)
.text(r.id)
.on('click', nav);
addNavigable(div, 'p', r.id);
});
div = topdiv.select('.devices').select('div');
rmP(div);
data.layerOrder.forEach(function (tag, idx) {
var devs = data.devices[idx];
devs.forEach(function (d) {
......@@ -83,6 +125,7 @@
});
div = topdiv.select('.hosts').select('div');
rmP(div);
data.layerOrder.forEach(function (tag, idx) {
var hosts = data.hosts[idx];
hosts.forEach(function (h) {
......@@ -92,8 +135,8 @@
});
div = topdiv.select('.links').select('div');
var links = data.links;
links.forEach(function (lnk) {
rmP(div);
data.links.forEach(function (lnk) {
div.append('p')
.text(lnk.id);
});
......@@ -106,26 +149,27 @@
// ========================== Event Handlers
function allInstances(data) {
$log.debug('>> topo2AllInstances event:', data)
doTmpCurrentLayout(data);
$log.debug('>> topo2AllInstances event:', data);
doTmpInstances(data);
}
function currentLayout(data) {
$log.debug('>> topo2CurrentLayout event:', data)
$log.debug('>> topo2CurrentLayout event:', data);
doTmpCurrentLayout(data);
}
function currentRegion(data) {
$log.debug('>> topo2CurrentRegion event:', data)
$log.debug('>> topo2CurrentRegion event:', data);
doTmpCurrentRegion(data);
}
function peerRegions(data) {
$log.debug('>> topo2PeerRegions event:', data)
$log.debug('>> topo2PeerRegions event:', data);
doTmpPeerRegions(data);
}
function startDone(data) {
$log.debug('>> topo2StartDone event:', data)
$log.debug('>> topo2StartDone event:', data);
}
// ========================== Main Service Definition
......