Thomas Vachuska

Adding ability for the server to notify clients about GUI additions/removals.

Change-Id: I505f68c33cb9cf7b875b53792f8442ba0cf0662a
...@@ -56,9 +56,10 @@ import static org.onosproject.security.AppPermission.Type.UI_WRITE; ...@@ -56,9 +56,10 @@ import static org.onosproject.security.AppPermission.Type.UI_WRITE;
56 @Service 56 @Service
57 public class UiExtensionManager implements UiExtensionService, SpriteService { 57 public class UiExtensionManager implements UiExtensionService, SpriteService {
58 58
59 - private static final ClassLoader CL = 59 + private static final ClassLoader CL = UiExtensionManager.class.getClassLoader();
60 - UiExtensionManager.class.getClassLoader();
61 private static final String CORE = "core"; 60 private static final String CORE = "core";
61 + private static final String GUI_ADDED = "guiAdded";
62 + private static final String GUI_REMOVED = "guiRemoved";
62 63
63 private final Logger log = LoggerFactory.getLogger(getClass()); 64 private final Logger log = LoggerFactory.getLogger(getClass());
64 65
...@@ -146,6 +147,7 @@ public class UiExtensionManager implements UiExtensionService, SpriteService { ...@@ -146,6 +147,7 @@ public class UiExtensionManager implements UiExtensionService, SpriteService {
146 for (UiView view : extension.views()) { 147 for (UiView view : extension.views()) {
147 views.put(view.id(), extension); 148 views.put(view.id(), extension);
148 } 149 }
150 + UiWebSocketServlet.sendToAll(GUI_ADDED, null);
149 } 151 }
150 } 152 }
151 153
...@@ -153,8 +155,8 @@ public class UiExtensionManager implements UiExtensionService, SpriteService { ...@@ -153,8 +155,8 @@ public class UiExtensionManager implements UiExtensionService, SpriteService {
153 public synchronized void unregister(UiExtension extension) { 155 public synchronized void unregister(UiExtension extension) {
154 checkPermission(UI_WRITE); 156 checkPermission(UI_WRITE);
155 extensions.remove(extension); 157 extensions.remove(extension);
156 - extension.views().stream() 158 + extension.views().stream().map(UiView::id).collect(toSet()).forEach(views::remove);
157 - .map(UiView::id).collect(toSet()).forEach(views::remove); 159 + UiWebSocketServlet.sendToAll(GUI_REMOVED, null);
158 } 160 }
159 161
160 @Override 162 @Override
......
...@@ -170,9 +170,8 @@ public class UiWebSocket ...@@ -170,9 +170,8 @@ public class UiWebSocket
170 if (sid > 0) { 170 if (sid > 0) {
171 message.put("sid", sid); 171 message.put("sid", sid);
172 } 172 }
173 - message.set("payload", payload); 173 + message.set("payload", payload != null ? payload : mapper.createObjectNode());
174 sendMessage(message); 174 sendMessage(message);
175 -
176 } 175 }
177 176
178 // Creates new message handlers. 177 // Creates new message handlers.
......
...@@ -15,6 +15,7 @@ ...@@ -15,6 +15,7 @@
15 */ 15 */
16 package org.onosproject.ui.impl; 16 package org.onosproject.ui.impl;
17 17
18 +import com.fasterxml.jackson.databind.node.ObjectNode;
18 import org.eclipse.jetty.websocket.WebSocket; 19 import org.eclipse.jetty.websocket.WebSocket;
19 import org.eclipse.jetty.websocket.WebSocketServlet; 20 import org.eclipse.jetty.websocket.WebSocketServlet;
20 import org.onlab.osgi.DefaultServiceDirectory; 21 import org.onlab.osgi.DefaultServiceDirectory;
...@@ -76,6 +77,18 @@ public class UiWebSocketServlet extends WebSocketServlet { ...@@ -76,6 +77,18 @@ public class UiWebSocketServlet extends WebSocketServlet {
76 return socket; 77 return socket;
77 } 78 }
78 79
80 + /**
81 + * Sends the specified message to all the GUI clients.
82 + *
83 + * @param type message type
84 + * @param payload message payload
85 + */
86 + static void sendToAll(String type, ObjectNode payload) {
87 + if (instance != null) {
88 + instance.sockets.forEach(ws -> ws.sendMessage(type, 0, payload));
89 + }
90 + }
91 +
79 // Task for pruning web-sockets that are idle. 92 // Task for pruning web-sockets that are idle.
80 private class Pruner extends TimerTask { 93 private class Pruner extends TimerTask {
81 @Override 94 @Override
......
...@@ -27,8 +27,16 @@ ...@@ -27,8 +27,16 @@
27 var mastHeight = 36, 27 var mastHeight = 36,
28 padMobile = 16; 28 padMobile = 16;
29 29
30 - angular.module('onosMast', ['onosNav']) 30 + var dialogId = 'app-dialog',
31 - .controller('MastCtrl', ['$log', 'NavService', function (_$log_, ns) { 31 + dialogOpts = {
32 + edge: 'left'
33 + };
34 +
35 + angular.module('onosMast', ['onosNav'])
36 + .controller('MastCtrl', ['$log', '$window', 'NavService',
37 + 'DialogService', 'WebSocketService',
38 +
39 + function (_$log_, $window, ns, ds, wss) {
32 var self = this; 40 var self = this;
33 41
34 $log = _$log_; 42 $log = _$log_;
...@@ -36,6 +44,36 @@ ...@@ -36,6 +44,36 @@
36 // initialize mast controller here... 44 // initialize mast controller here...
37 self.radio = null; 45 self.radio = null;
38 46
47 + function triggerRefresh(action) {
48 + function createConfirmationText() {
49 + var content = ds.createDiv();
50 + content.append('p').text(action + ' Press OK to update the GUI.');
51 + return content;
52 + }
53 +
54 +
55 + function dOk() {
56 + $log.debug('Refreshing GUI');
57 + $window.location.reload();
58 + }
59 +
60 + function dCancel() {
61 + $log.debug('Canceling GUI refresh');
62 + }
63 +
64 + ds.openDialog(dialogId, dialogOpts)
65 + .setTitle('Confirm GUI Refresh')
66 + .addContent(createConfirmationText())
67 + .addOk(dOk)
68 + .addCancel(dCancel)
69 + .bindKeys();
70 + }
71 +
72 + wss.bindHandlers({
73 + 'guiAdded': function () { triggerRefresh('New GUI components were added.') },
74 + 'guiRemoved': function () { triggerRefresh('Some GUI components were removed.') }
75 + });
76 +
39 // delegate to NavService 77 // delegate to NavService
40 self.toggleNav = function () { 78 self.toggleNav = function () {
41 ns.toggleNav(); 79 ns.toggleNav();
......