Thomas Vachuska

Hooking up GUI server & client via web-socket.

Change-Id: If522a5f46de528f28bf09a985af40b140ef5abaa
...@@ -15,8 +15,18 @@ ...@@ -15,8 +15,18 @@
15 */ 15 */
16 package org.onlab.onos.gui; 16 package org.onlab.onos.gui;
17 17
18 +import com.fasterxml.jackson.databind.JsonNode;
19 +import com.fasterxml.jackson.databind.ObjectMapper;
20 +import com.fasterxml.jackson.databind.node.ArrayNode;
21 +import com.fasterxml.jackson.databind.node.ObjectNode;
18 import org.eclipse.jetty.websocket.WebSocket; 22 import org.eclipse.jetty.websocket.WebSocket;
23 +import org.onlab.onos.event.Event;
24 +import org.onlab.onos.net.Annotations;
25 +import org.onlab.onos.net.Device;
26 +import org.onlab.onos.net.Link;
27 +import org.onlab.onos.net.device.DeviceEvent;
19 import org.onlab.onos.net.device.DeviceService; 28 import org.onlab.onos.net.device.DeviceService;
29 +import org.onlab.onos.net.link.LinkEvent;
20 import org.onlab.onos.net.topology.Topology; 30 import org.onlab.onos.net.topology.Topology;
21 import org.onlab.onos.net.topology.TopologyEdge; 31 import org.onlab.onos.net.topology.TopologyEdge;
22 import org.onlab.onos.net.topology.TopologyEvent; 32 import org.onlab.onos.net.topology.TopologyEvent;
...@@ -28,6 +38,11 @@ import org.onlab.osgi.ServiceDirectory; ...@@ -28,6 +38,11 @@ import org.onlab.osgi.ServiceDirectory;
28 38
29 import java.io.IOException; 39 import java.io.IOException;
30 40
41 +import static org.onlab.onos.net.device.DeviceEvent.Type.DEVICE_ADDED;
42 +import static org.onlab.onos.net.device.DeviceEvent.Type.DEVICE_REMOVED;
43 +import static org.onlab.onos.net.link.LinkEvent.Type.LINK_ADDED;
44 +import static org.onlab.onos.net.link.LinkEvent.Type.LINK_REMOVED;
45 +
31 /** 46 /**
32 * Web socket capable of interacting with the GUI topology view. 47 * Web socket capable of interacting with the GUI topology view.
33 */ 48 */
...@@ -37,6 +52,8 @@ public class TopologyWebSocket implements WebSocket.OnTextMessage, TopologyListe ...@@ -37,6 +52,8 @@ public class TopologyWebSocket implements WebSocket.OnTextMessage, TopologyListe
37 private final TopologyService topologyService; 52 private final TopologyService topologyService;
38 private final DeviceService deviceService; 53 private final DeviceService deviceService;
39 54
55 + private final ObjectMapper mapper = new ObjectMapper();
56 +
40 private Connection connection; 57 private Connection connection;
41 58
42 /** 59 /**
...@@ -58,22 +75,19 @@ public class TopologyWebSocket implements WebSocket.OnTextMessage, TopologyListe ...@@ -58,22 +75,19 @@ public class TopologyWebSocket implements WebSocket.OnTextMessage, TopologyListe
58 if (topologyService != null && deviceService != null) { 75 if (topologyService != null && deviceService != null) {
59 topologyService.addListener(this); 76 topologyService.addListener(this);
60 77
61 - sendMessage("Yo!!!");
62 -
63 Topology topology = topologyService.currentTopology(); 78 Topology topology = topologyService.currentTopology();
64 TopologyGraph graph = topologyService.getGraph(topology); 79 TopologyGraph graph = topologyService.getGraph(topology);
65 for (TopologyVertex vertex : graph.getVertexes()) { 80 for (TopologyVertex vertex : graph.getVertexes()) {
66 - sendMessage(deviceService.getDevice(vertex.deviceId()).toString()); 81 + sendMessage(message(new DeviceEvent(DEVICE_ADDED,
82 + deviceService.getDevice(vertex.deviceId()))));
67 } 83 }
68 84
69 for (TopologyEdge edge : graph.getEdges()) { 85 for (TopologyEdge edge : graph.getEdges()) {
70 - sendMessage(edge.link().toString()); 86 + sendMessage(message(new LinkEvent(LINK_ADDED, edge.link())));
71 } 87 }
72 88
73 - sendMessage("That's what we're starting with...");
74 -
75 } else { 89 } else {
76 - sendMessage("No topology service!!!"); 90 + sendMessage(message("error", "No topology service!!!"));
77 } 91 }
78 } 92 }
79 93
...@@ -90,7 +104,7 @@ public class TopologyWebSocket implements WebSocket.OnTextMessage, TopologyListe ...@@ -90,7 +104,7 @@ public class TopologyWebSocket implements WebSocket.OnTextMessage, TopologyListe
90 System.out.println("Received: " + data); 104 System.out.println("Received: " + data);
91 } 105 }
92 106
93 - public void sendMessage(String data) { 107 + private void sendMessage(String data) {
94 try { 108 try {
95 connection.sendMessage(data); 109 connection.sendMessage(data);
96 } catch (IOException e) { 110 } catch (IOException e) {
...@@ -98,9 +112,80 @@ public class TopologyWebSocket implements WebSocket.OnTextMessage, TopologyListe ...@@ -98,9 +112,80 @@ public class TopologyWebSocket implements WebSocket.OnTextMessage, TopologyListe
98 } 112 }
99 } 113 }
100 114
115 + // Produces a link event message to the client.
116 + private String message(DeviceEvent event) {
117 + Device device = event.subject();
118 + ObjectNode payload = mapper.createObjectNode()
119 + .put("id", device.id().toString())
120 + .put("type", device.type().toString().toLowerCase())
121 + .put("online", deviceService.isAvailable(device.id()));
122 +
123 + // Generate labels: id, chassis id, no-label, optional-name
124 + ArrayNode labels = mapper.createArrayNode();
125 + labels.add(device.id().toString());
126 + labels.add(device.chassisId().toString());
127 + labels.add(" "); // compact no-label view
128 + labels.add(device.annotations().value("name"));
129 +
130 + // Add labels, props and stuff the payload into envelope.
131 + payload.set("labels", labels);
132 + payload.set("props", props(device.annotations()));
133 + payload.set("metaUi", mapper.createObjectNode());
134 +
135 + String type = (event.type() == DEVICE_ADDED) ? "addDevice" :
136 + ((event.type() == DEVICE_REMOVED) ? "removeDevice" : "updateDevice");
137 + return envelope(type, payload);
138 + }
139 +
140 + // Produces a link event message to the client.
141 + private String message(LinkEvent event) {
142 + Link link = event.subject();
143 + ObjectNode payload = mapper.createObjectNode()
144 + .put("type", link.type().toString().toLowerCase())
145 + .put("linkWidth", 2)
146 + .put("src", link.src().deviceId().toString())
147 + .put("srcPort", link.src().port().toString())
148 + .put("dst", link.dst().deviceId().toString())
149 + .put("dstPort", link.dst().port().toString());
150 + String type = (event.type() == LINK_ADDED) ? "addLink" :
151 + ((event.type() == LINK_REMOVED) ? "removeLink" : "removeLink");
152 + return envelope(type, payload);
153 + }
154 +
155 + // Produces JSON structure from annotations.
156 + private JsonNode props(Annotations annotations) {
157 + ObjectNode props = mapper.createObjectNode();
158 + for (String key : annotations.keys()) {
159 + props.put(key, annotations.value(key));
160 + }
161 + return props;
162 + }
163 +
164 + // Produces a log message event bound to the client.
165 + private String message(String severity, String message) {
166 + return envelope("message",
167 + mapper.createObjectNode()
168 + .put("severity", severity)
169 + .put("message", message));
170 + }
171 +
172 + // Puts the payload into an envelope and returns it.
173 + private String envelope(String type, ObjectNode payload) {
174 + ObjectNode event = mapper.createObjectNode();
175 + event.put("event", type);
176 + event.set("payload", payload);
177 + return event.toString();
178 + }
179 +
101 @Override 180 @Override
102 public void event(TopologyEvent event) { 181 public void event(TopologyEvent event) {
103 - sendMessage(event.toString()); 182 + for (Event reason : event.reasons()) {
183 + if (reason instanceof DeviceEvent) {
184 + sendMessage(message((DeviceEvent) reason));
185 + } else if (reason instanceof LinkEvent) {
186 + sendMessage(message((LinkEvent) reason));
187 + }
188 + }
104 } 189 }
105 } 190 }
106 191
......
...@@ -604,6 +604,7 @@ ...@@ -604,6 +604,7 @@
604 webSock.ws.onmessage = function(m) { 604 webSock.ws.onmessage = function(m) {
605 if (m.data) { 605 if (m.data) {
606 console.log(m.data); 606 console.log(m.data);
607 + handleServerEvent(JSON.parse(m.data));
607 } 608 }
608 }; 609 };
609 610
......