Simon Hunt

GUI -- Reworked sprite definition loading via websocket events.

- includes option to specify sprite definition id: #/topo?sprites=defn_name.

Change-Id: If2ce59384e01bb5f35827a503748e21ab4fb1b31
......@@ -6,6 +6,12 @@
node=${1}
sprites=${2}
if [ -z "$node" -o -z "$sprites" ]
then
echo "Usage: onos-upload-sprites <server-ip> <sprites-defn.json>"
exit 1
fi
export URL=http://$node:8181/onos/ui/rs/topology/sprites
export HDR="-HContent-Type:application/json"
......
......@@ -86,7 +86,7 @@ public class TopologyResource extends BaseResource {
@Consumes("application/json")
public Response setSprites(InputStream stream) throws IOException {
JsonNode root = mapper.readTree(stream);
String name = root.path("defn_id").asText("sprites");
String name = root.path("defn_name").asText("sprites");
get(SpriteService.class).put(name, root);
return Response.ok().build();
}
......
......@@ -581,8 +581,9 @@ public class TopologyViewMessageHandler extends TopologyViewMessageHandlerBase {
// Sends requested sprite data.
private void sendSpriteData(ObjectNode event) {
String name = event.path("payload").path("name").asText();
ObjectNode root = mapper.createObjectNode();
root.set("defn", get(SpriteService.class).get(event.path("payload").path("name").asText()));
root.set("data", get(SpriteService.class).get(name));
sendMessage(envelope("spriteDataResponse", number(event, "sid"), root));
}
......
......@@ -130,7 +130,7 @@ public class UiExtensionManager implements UiExtensionService, SpriteService {
@Override
public void put(String name, JsonNode spriteData) {
log.info("Registered sprite definition {}", name);
log.info("Registered sprite definition [{}]", name);
sprites.put(name, spriteData);
}
......
......@@ -366,7 +366,7 @@
}
);
spriteG = zoomLayer.append ('g').attr('id', 'topo-sprites');
tspr.loadSprites(spriteG);
tspr.loadSprites(spriteG, $loc.search().sprites);
forceG = zoomLayer.append('g').attr('id', 'topo-force');
tfs.initForce(svg, forceG, uplink, dim);
......
......@@ -27,7 +27,7 @@
'use strict';
// injected refs
var $log, wss, tps, tis, tfs, tss, tts;
var $log, wss, tps, tis, tfs, tss, tts, tspr;
// internal state
var handlerMap,
......@@ -55,7 +55,10 @@
removeHost: tfs,
addLink: tfs,
updateLink: tfs,
removeLink: tfs
removeLink: tfs,
spriteListResponse: tspr,
spriteDataResponse: tspr
};
}
......@@ -69,9 +72,9 @@
.factory('TopoEventService',
['$log', '$location', 'WebSocketService',
'TopoPanelService', 'TopoInstService', 'TopoForceService',
'TopoSelectService', 'TopoTrafficService',
'TopoSelectService', 'TopoTrafficService', 'TopoSpriteService',
function (_$log_, $loc, _wss_, _tps_, _tis_, _tfs_, _tss_, _tts_) {
function (_$log_, $loc, _wss_, _tps_, _tis_, _tfs_, _tss_, _tts_, _tspr_) {
$log = _$log_;
wss = _wss_;
tps = _tps_;
......@@ -79,6 +82,7 @@
tfs = _tfs_;
tss = _tss_;
tts = _tts_;
tspr = _tspr_;
createHandlerMap();
......@@ -86,8 +90,6 @@
openListener = wss.addOpenListener(wsOpen);
wss.bindHandlers(handlerMap);
wss.sendEvent('topoStart');
wss.sendEvent('spriteListRequest');
wss.sendEvent('spriteDataRequest', {name: 'sample'});
$log.debug('topo comms started');
}
......
......@@ -23,55 +23,12 @@
'use strict';
// injected refs
var $log, $http, fs, sus;
var $log, $http, fs, sus, wss;
// internal state
var spriteLayer,
cache = d3.map();
// constants
var urlPrefix = 'data/ext/';
function getUrl(id) {
return urlPrefix + id + '.json';
}
// =========================
function clearCache() {
cache = d3.map();
}
function loadSpriteData(id, cb) {
var url = getUrl(id),
promise = cache.get(id);
if (!promise) {
// need to fetch data and cache it
promise = $http.get(url);
promise.meta = {
id: id,
url: url,
wasCached: false
};
var tssid = 'TopoSpriteService: ';
promise.then(function (response) {
// success
promise.spriteData = response.data;
cb(promise.spriteData);
}, function (response) {
// error
$log.warn('Failed to retrieve sprite data: ' + url,
response.status, response.data);
});
} else {
promise.meta.wasCached = true;
cb(promise.spriteData);
}
}
// internal state
var spriteLayer;
function doSprite(def, item) {
var g;
......@@ -100,42 +57,71 @@
});
}
function loadSprites(layer) {
spriteLayer = layer;
// ==========================
// event handlers
loadSpriteData('sprites', function (data) {
var defs = {};
// Handles response from 'spriteListRequest' which lists all the
// registered sprite definitions on the server.
// (see onos-upload-sprites)
function inList(payload) {
$log.debug(tssid + 'Registered sprite definitions:', payload.names);
// Some day, we will make this list available to the user in
// a dropdown selection box...
}
$log.debug("Loading sprites...", data.file_desc);
// Handles response from 'spriteDataRequest' which provides the
// data for the requested sprite definition.
function inData(payload) {
var data = payload.data,
name = data && data.defn_name,
desc = data && data.defn_desc,
defs = {};
if (!data) {
$log.warn(tssid + 'No sprite data loaded.')
return;
}
data.defn.forEach(function (d) {
defs[d.id] = d;
});
$log.debug("Loading sprites...[" + name + "]", desc);
data.load.forEach(function (item) {
doSprite(defs[item.id], item);
});
data.defn.forEach(function (d) {
defs[d.id] = d;
});
data.load.forEach(function (item) {
doSprite(defs[item.id], item);
});
}
function loadSprites(layer, defname) {
var name = defname || 'sprites';
spriteLayer = layer;
$log.info(tssid + 'Requesting sprite definition ['+name+']...');
wss.sendEvent('spriteListRequest');
wss.sendEvent('spriteDataRequest', {name: name});
}
// === -----------------------------------------------------
// === MODULE DEFINITION ===
angular.module('ovTopo')
.factory('TopoSpriteService',
['$log', '$http', 'FnService', 'SvgUtilService',
['$log', '$http', 'FnService', 'SvgUtilService', 'WebSocketService',
function (_$log_, _$http_, _fs_, _sus_) {
function (_$log_, _$http_, _fs_, _sus_, _wss_) {
$log = _$log_;
$http = _$http_;
fs = _fs_;
sus = _sus_;
wss = _wss_;
return {
clearCache: clearCache,
loadSprites: loadSprites
loadSprites: loadSprites,
spriteListResponse: inList,
spriteDataResponse: inData
};
}]);
......
{
"defn_id": "sample",
"file_desc": "Cloud Sprite Data",
"defn_name": "sample",
"defn_desc": "Sample Cloud Sprite Data",
"_comment": [
"configuration file for loading canned and/or custom sprites (and labels)",
......