GUI -- Reworked sprite definition loading via websocket events.
- includes option to specify sprite definition id: #/topo?sprites=defn_name. Change-Id: If2ce59384e01bb5f35827a503748e21ab4fb1b31
Showing
8 changed files
with
69 additions
and
74 deletions
| ... | @@ -6,6 +6,12 @@ | ... | @@ -6,6 +6,12 @@ |
| 6 | node=${1} | 6 | node=${1} |
| 7 | sprites=${2} | 7 | sprites=${2} |
| 8 | 8 | ||
| 9 | +if [ -z "$node" -o -z "$sprites" ] | ||
| 10 | +then | ||
| 11 | + echo "Usage: onos-upload-sprites <server-ip> <sprites-defn.json>" | ||
| 12 | + exit 1 | ||
| 13 | +fi | ||
| 14 | + | ||
| 9 | export URL=http://$node:8181/onos/ui/rs/topology/sprites | 15 | export URL=http://$node:8181/onos/ui/rs/topology/sprites |
| 10 | export HDR="-HContent-Type:application/json" | 16 | export HDR="-HContent-Type:application/json" |
| 11 | 17 | ... | ... |
| ... | @@ -86,7 +86,7 @@ public class TopologyResource extends BaseResource { | ... | @@ -86,7 +86,7 @@ public class TopologyResource extends BaseResource { |
| 86 | @Consumes("application/json") | 86 | @Consumes("application/json") |
| 87 | public Response setSprites(InputStream stream) throws IOException { | 87 | public Response setSprites(InputStream stream) throws IOException { |
| 88 | JsonNode root = mapper.readTree(stream); | 88 | JsonNode root = mapper.readTree(stream); |
| 89 | - String name = root.path("defn_id").asText("sprites"); | 89 | + String name = root.path("defn_name").asText("sprites"); |
| 90 | get(SpriteService.class).put(name, root); | 90 | get(SpriteService.class).put(name, root); |
| 91 | return Response.ok().build(); | 91 | return Response.ok().build(); |
| 92 | } | 92 | } | ... | ... |
| ... | @@ -581,8 +581,9 @@ public class TopologyViewMessageHandler extends TopologyViewMessageHandlerBase { | ... | @@ -581,8 +581,9 @@ public class TopologyViewMessageHandler extends TopologyViewMessageHandlerBase { |
| 581 | 581 | ||
| 582 | // Sends requested sprite data. | 582 | // Sends requested sprite data. |
| 583 | private void sendSpriteData(ObjectNode event) { | 583 | private void sendSpriteData(ObjectNode event) { |
| 584 | + String name = event.path("payload").path("name").asText(); | ||
| 584 | ObjectNode root = mapper.createObjectNode(); | 585 | ObjectNode root = mapper.createObjectNode(); |
| 585 | - root.set("defn", get(SpriteService.class).get(event.path("payload").path("name").asText())); | 586 | + root.set("data", get(SpriteService.class).get(name)); |
| 586 | sendMessage(envelope("spriteDataResponse", number(event, "sid"), root)); | 587 | sendMessage(envelope("spriteDataResponse", number(event, "sid"), root)); |
| 587 | } | 588 | } |
| 588 | 589 | ... | ... |
| ... | @@ -130,7 +130,7 @@ public class UiExtensionManager implements UiExtensionService, SpriteService { | ... | @@ -130,7 +130,7 @@ public class UiExtensionManager implements UiExtensionService, SpriteService { |
| 130 | 130 | ||
| 131 | @Override | 131 | @Override |
| 132 | public void put(String name, JsonNode spriteData) { | 132 | public void put(String name, JsonNode spriteData) { |
| 133 | - log.info("Registered sprite definition {}", name); | 133 | + log.info("Registered sprite definition [{}]", name); |
| 134 | sprites.put(name, spriteData); | 134 | sprites.put(name, spriteData); |
| 135 | } | 135 | } |
| 136 | 136 | ... | ... |
| ... | @@ -366,7 +366,7 @@ | ... | @@ -366,7 +366,7 @@ |
| 366 | } | 366 | } |
| 367 | ); | 367 | ); |
| 368 | spriteG = zoomLayer.append ('g').attr('id', 'topo-sprites'); | 368 | spriteG = zoomLayer.append ('g').attr('id', 'topo-sprites'); |
| 369 | - tspr.loadSprites(spriteG); | 369 | + tspr.loadSprites(spriteG, $loc.search().sprites); |
| 370 | 370 | ||
| 371 | forceG = zoomLayer.append('g').attr('id', 'topo-force'); | 371 | forceG = zoomLayer.append('g').attr('id', 'topo-force'); |
| 372 | tfs.initForce(svg, forceG, uplink, dim); | 372 | tfs.initForce(svg, forceG, uplink, dim); | ... | ... |
| ... | @@ -27,7 +27,7 @@ | ... | @@ -27,7 +27,7 @@ |
| 27 | 'use strict'; | 27 | 'use strict'; |
| 28 | 28 | ||
| 29 | // injected refs | 29 | // injected refs |
| 30 | - var $log, wss, tps, tis, tfs, tss, tts; | 30 | + var $log, wss, tps, tis, tfs, tss, tts, tspr; |
| 31 | 31 | ||
| 32 | // internal state | 32 | // internal state |
| 33 | var handlerMap, | 33 | var handlerMap, |
| ... | @@ -55,7 +55,10 @@ | ... | @@ -55,7 +55,10 @@ |
| 55 | removeHost: tfs, | 55 | removeHost: tfs, |
| 56 | addLink: tfs, | 56 | addLink: tfs, |
| 57 | updateLink: tfs, | 57 | updateLink: tfs, |
| 58 | - removeLink: tfs | 58 | + removeLink: tfs, |
| 59 | + | ||
| 60 | + spriteListResponse: tspr, | ||
| 61 | + spriteDataResponse: tspr | ||
| 59 | }; | 62 | }; |
| 60 | } | 63 | } |
| 61 | 64 | ||
| ... | @@ -69,9 +72,9 @@ | ... | @@ -69,9 +72,9 @@ |
| 69 | .factory('TopoEventService', | 72 | .factory('TopoEventService', |
| 70 | ['$log', '$location', 'WebSocketService', | 73 | ['$log', '$location', 'WebSocketService', |
| 71 | 'TopoPanelService', 'TopoInstService', 'TopoForceService', | 74 | 'TopoPanelService', 'TopoInstService', 'TopoForceService', |
| 72 | - 'TopoSelectService', 'TopoTrafficService', | 75 | + 'TopoSelectService', 'TopoTrafficService', 'TopoSpriteService', |
| 73 | 76 | ||
| 74 | - function (_$log_, $loc, _wss_, _tps_, _tis_, _tfs_, _tss_, _tts_) { | 77 | + function (_$log_, $loc, _wss_, _tps_, _tis_, _tfs_, _tss_, _tts_, _tspr_) { |
| 75 | $log = _$log_; | 78 | $log = _$log_; |
| 76 | wss = _wss_; | 79 | wss = _wss_; |
| 77 | tps = _tps_; | 80 | tps = _tps_; |
| ... | @@ -79,6 +82,7 @@ | ... | @@ -79,6 +82,7 @@ |
| 79 | tfs = _tfs_; | 82 | tfs = _tfs_; |
| 80 | tss = _tss_; | 83 | tss = _tss_; |
| 81 | tts = _tts_; | 84 | tts = _tts_; |
| 85 | + tspr = _tspr_; | ||
| 82 | 86 | ||
| 83 | createHandlerMap(); | 87 | createHandlerMap(); |
| 84 | 88 | ||
| ... | @@ -86,8 +90,6 @@ | ... | @@ -86,8 +90,6 @@ |
| 86 | openListener = wss.addOpenListener(wsOpen); | 90 | openListener = wss.addOpenListener(wsOpen); |
| 87 | wss.bindHandlers(handlerMap); | 91 | wss.bindHandlers(handlerMap); |
| 88 | wss.sendEvent('topoStart'); | 92 | wss.sendEvent('topoStart'); |
| 89 | - wss.sendEvent('spriteListRequest'); | ||
| 90 | - wss.sendEvent('spriteDataRequest', {name: 'sample'}); | ||
| 91 | $log.debug('topo comms started'); | 93 | $log.debug('topo comms started'); |
| 92 | } | 94 | } |
| 93 | 95 | ... | ... |
| ... | @@ -23,55 +23,12 @@ | ... | @@ -23,55 +23,12 @@ |
| 23 | 'use strict'; | 23 | 'use strict'; |
| 24 | 24 | ||
| 25 | // injected refs | 25 | // injected refs |
| 26 | - var $log, $http, fs, sus; | 26 | + var $log, $http, fs, sus, wss; |
| 27 | 27 | ||
| 28 | - // internal state | 28 | + var tssid = 'TopoSpriteService: '; |
| 29 | - var spriteLayer, | ||
| 30 | - cache = d3.map(); | ||
| 31 | - | ||
| 32 | - // constants | ||
| 33 | - var urlPrefix = 'data/ext/'; | ||
| 34 | - | ||
| 35 | - function getUrl(id) { | ||
| 36 | - return urlPrefix + id + '.json'; | ||
| 37 | - } | ||
| 38 | - | ||
| 39 | - // ========================= | ||
| 40 | - | ||
| 41 | - function clearCache() { | ||
| 42 | - cache = d3.map(); | ||
| 43 | - } | ||
| 44 | - | ||
| 45 | - | ||
| 46 | - function loadSpriteData(id, cb) { | ||
| 47 | - var url = getUrl(id), | ||
| 48 | - promise = cache.get(id); | ||
| 49 | - | ||
| 50 | - if (!promise) { | ||
| 51 | - // need to fetch data and cache it | ||
| 52 | - promise = $http.get(url); | ||
| 53 | - | ||
| 54 | - promise.meta = { | ||
| 55 | - id: id, | ||
| 56 | - url: url, | ||
| 57 | - wasCached: false | ||
| 58 | - }; | ||
| 59 | 29 | ||
| 60 | - promise.then(function (response) { | 30 | + // internal state |
| 61 | - // success | 31 | + var spriteLayer; |
| 62 | - promise.spriteData = response.data; | ||
| 63 | - cb(promise.spriteData); | ||
| 64 | - }, function (response) { | ||
| 65 | - // error | ||
| 66 | - $log.warn('Failed to retrieve sprite data: ' + url, | ||
| 67 | - response.status, response.data); | ||
| 68 | - }); | ||
| 69 | - | ||
| 70 | - } else { | ||
| 71 | - promise.meta.wasCached = true; | ||
| 72 | - cb(promise.spriteData); | ||
| 73 | - } | ||
| 74 | - } | ||
| 75 | 32 | ||
| 76 | function doSprite(def, item) { | 33 | function doSprite(def, item) { |
| 77 | var g; | 34 | var g; |
| ... | @@ -100,42 +57,71 @@ | ... | @@ -100,42 +57,71 @@ |
| 100 | }); | 57 | }); |
| 101 | } | 58 | } |
| 102 | 59 | ||
| 103 | - function loadSprites(layer) { | 60 | + // ========================== |
| 104 | - spriteLayer = layer; | 61 | + // event handlers |
| 105 | 62 | ||
| 106 | - loadSpriteData('sprites', function (data) { | 63 | + // Handles response from 'spriteListRequest' which lists all the |
| 107 | - var defs = {}; | 64 | + // registered sprite definitions on the server. |
| 65 | + // (see onos-upload-sprites) | ||
| 66 | + function inList(payload) { | ||
| 67 | + $log.debug(tssid + 'Registered sprite definitions:', payload.names); | ||
| 68 | + // Some day, we will make this list available to the user in | ||
| 69 | + // a dropdown selection box... | ||
| 70 | + } | ||
| 108 | 71 | ||
| 109 | - $log.debug("Loading sprites...", data.file_desc); | 72 | + // Handles response from 'spriteDataRequest' which provides the |
| 73 | + // data for the requested sprite definition. | ||
| 74 | + function inData(payload) { | ||
| 75 | + var data = payload.data, | ||
| 76 | + name = data && data.defn_name, | ||
| 77 | + desc = data && data.defn_desc, | ||
| 78 | + defs = {}; | ||
| 79 | + | ||
| 80 | + if (!data) { | ||
| 81 | + $log.warn(tssid + 'No sprite data loaded.') | ||
| 82 | + return; | ||
| 83 | + } | ||
| 110 | 84 | ||
| 111 | - data.defn.forEach(function (d) { | 85 | + $log.debug("Loading sprites...[" + name + "]", desc); |
| 112 | - defs[d.id] = d; | ||
| 113 | - }); | ||
| 114 | 86 | ||
| 115 | - data.load.forEach(function (item) { | 87 | + data.defn.forEach(function (d) { |
| 116 | - doSprite(defs[item.id], item); | 88 | + defs[d.id] = d; |
| 117 | - }); | ||
| 118 | }); | 89 | }); |
| 119 | 90 | ||
| 91 | + data.load.forEach(function (item) { | ||
| 92 | + doSprite(defs[item.id], item); | ||
| 93 | + }); | ||
| 120 | } | 94 | } |
| 121 | 95 | ||
| 122 | 96 | ||
| 97 | + function loadSprites(layer, defname) { | ||
| 98 | + var name = defname || 'sprites'; | ||
| 99 | + spriteLayer = layer; | ||
| 100 | + | ||
| 101 | + $log.info(tssid + 'Requesting sprite definition ['+name+']...'); | ||
| 102 | + | ||
| 103 | + wss.sendEvent('spriteListRequest'); | ||
| 104 | + wss.sendEvent('spriteDataRequest', {name: name}); | ||
| 105 | + } | ||
| 106 | + | ||
| 123 | // === ----------------------------------------------------- | 107 | // === ----------------------------------------------------- |
| 124 | // === MODULE DEFINITION === | 108 | // === MODULE DEFINITION === |
| 125 | 109 | ||
| 126 | angular.module('ovTopo') | 110 | angular.module('ovTopo') |
| 127 | .factory('TopoSpriteService', | 111 | .factory('TopoSpriteService', |
| 128 | - ['$log', '$http', 'FnService', 'SvgUtilService', | 112 | + ['$log', '$http', 'FnService', 'SvgUtilService', 'WebSocketService', |
| 129 | 113 | ||
| 130 | - function (_$log_, _$http_, _fs_, _sus_) { | 114 | + function (_$log_, _$http_, _fs_, _sus_, _wss_) { |
| 131 | $log = _$log_; | 115 | $log = _$log_; |
| 132 | $http = _$http_; | 116 | $http = _$http_; |
| 133 | fs = _fs_; | 117 | fs = _fs_; |
| 134 | sus = _sus_; | 118 | sus = _sus_; |
| 119 | + wss = _wss_; | ||
| 135 | 120 | ||
| 136 | return { | 121 | return { |
| 137 | - clearCache: clearCache, | 122 | + loadSprites: loadSprites, |
| 138 | - loadSprites: loadSprites | 123 | + spriteListResponse: inList, |
| 124 | + spriteDataResponse: inData | ||
| 139 | }; | 125 | }; |
| 140 | }]); | 126 | }]); |
| 141 | 127 | ... | ... |
| 1 | { | 1 | { |
| 2 | - "defn_id": "sample", | 2 | + "defn_name": "sample", |
| 3 | - "file_desc": "Cloud Sprite Data", | 3 | + "defn_desc": "Sample Cloud Sprite Data", |
| 4 | 4 | ||
| 5 | "_comment": [ | 5 | "_comment": [ |
| 6 | "configuration file for loading canned and/or custom sprites (and labels)", | 6 | "configuration file for loading canned and/or custom sprites (and labels)", | ... | ... |
-
Please register or login to post a comment