Simon Hunt
Committed by Gerrit Code Review

GUI -- Initial cut at bootstrap message from server to client.

- Note.. Thomas to layer changes on top of this... WIP

Change-Id: I6e2a624e2cfd6fc0ece761be46b71b23242dd2b2
...@@ -15,6 +15,7 @@ ...@@ -15,6 +15,7 @@
15 */ 15 */
16 package org.onosproject.ui; 16 package org.onosproject.ui;
17 17
18 +import com.fasterxml.jackson.databind.ObjectMapper;
18 import com.fasterxml.jackson.databind.node.ObjectNode; 19 import com.fasterxml.jackson.databind.node.ObjectNode;
19 import org.onlab.osgi.ServiceDirectory; 20 import org.onlab.osgi.ServiceDirectory;
20 21
...@@ -44,6 +45,9 @@ public abstract class UiMessageHandler { ...@@ -44,6 +45,9 @@ public abstract class UiMessageHandler {
44 private UiConnection connection; 45 private UiConnection connection;
45 private ServiceDirectory directory; 46 private ServiceDirectory directory;
46 47
48 + /** Mapper for creating ObjectNodes and ArrayNodes etc. */
49 + protected final ObjectMapper mapper = new ObjectMapper();
50 +
47 /** 51 /**
48 * Creates a new message handler for the specified set of message types. 52 * Creates a new message handler for the specified set of message types.
49 * 53 *
...@@ -121,4 +125,23 @@ public abstract class UiMessageHandler { ...@@ -121,4 +125,23 @@ public abstract class UiMessageHandler {
121 return directory.get(serviceClass); 125 return directory.get(serviceClass);
122 } 126 }
123 127
128 + /**
129 + * Wraps a message payload into an event structure for the given event
130 + * type and sequence ID. Generally the
131 + *
132 + * @param type event type
133 + * @param sid sequence ID
134 + * @param payload event payload
135 + * @return the object node representation
136 + */
137 + protected ObjectNode envelope(String type, long sid, ObjectNode payload) {
138 + ObjectNode event = mapper.createObjectNode();
139 + event.put("event", type);
140 + if (sid > 0) {
141 + event.put("sid", sid);
142 + }
143 + event.set("payload", payload);
144 + return event;
145 + }
146 +
124 } 147 }
......
1 +/*
2 + * Copyright 2015 Open Networking Laboratory
3 + *
4 + * Licensed under the Apache License, Version 2.0 (the "License");
5 + * you may not use this file except in compliance with the License.
6 + * You may obtain a copy of the License at
7 + *
8 + * http://www.apache.org/licenses/LICENSE-2.0
9 + *
10 + * Unless required by applicable law or agreed to in writing, software
11 + * distributed under the License is distributed on an "AS IS" BASIS,
12 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 + * See the License for the specific language governing permissions and
14 + * limitations under the License.
15 + */
16 +package org.onosproject.ui.impl;
17 +
18 +import com.fasterxml.jackson.databind.ObjectMapper;
19 +import com.fasterxml.jackson.databind.node.ArrayNode;
20 +import com.fasterxml.jackson.databind.node.ObjectNode;
21 +import com.google.common.collect.ImmutableSet;
22 +import org.onlab.osgi.ServiceDirectory;
23 +import org.onosproject.cluster.ClusterService;
24 +import org.onosproject.cluster.ControllerNode;
25 +import org.onosproject.ui.UiConnection;
26 +import org.onosproject.ui.UiMessageHandler;
27 +
28 +import java.util.ArrayList;
29 +import java.util.Collections;
30 +import java.util.Comparator;
31 +import java.util.List;
32 +
33 +
34 +/**
35 + * Facility for creating and sending initial bootstrap message to the GUI.
36 + */
37 +public class BootstrapMessageHandler extends UiMessageHandler {
38 +
39 + private static final String BOOTSTRAP = "bootstrap";
40 +
41 + private static final Comparator<? super ControllerNode> NODE_COMPARATOR =
42 + new Comparator<ControllerNode>() {
43 + @Override
44 + public int compare(ControllerNode o1, ControllerNode o2) {
45 + return o1.id().toString().compareTo(o2.id().toString());
46 + }
47 + };
48 +
49 + private final ObjectMapper mapper = new ObjectMapper();
50 +
51 + private ClusterService clusterService;
52 +
53 + // TODO: ClusterEventListener - update GUI when instances come or go...
54 +
55 + /**
56 + * Creates a new bootstrap message handler for bootstrapping the GUI.
57 + */
58 + protected BootstrapMessageHandler() {
59 + super(ImmutableSet.of(BOOTSTRAP));
60 + }
61 +
62 + @Override
63 + public void init(UiConnection connection, ServiceDirectory directory) {
64 + super.init(connection, directory);
65 + clusterService = directory.get(ClusterService.class);
66 +
67 + // Obtain list of cluster nodes and send bootstrap message to GUI
68 + List<ControllerNode> nodes = new ArrayList<>(clusterService.getNodes());
69 + Collections.sort(nodes, NODE_COMPARATOR);
70 +
71 + ObjectNode payload = mapper.createObjectNode();
72 +
73 + ArrayNode anode = mapper.createArrayNode();
74 + for (ControllerNode node : nodes) {
75 + anode.add(clusterNodeData(node));
76 + }
77 + payload.set("instances", anode);
78 + connection.sendMessage(envelope(BOOTSTRAP, 0, payload));
79 + }
80 +
81 + private ObjectNode clusterNodeData(ControllerNode node) {
82 + return mapper.createObjectNode()
83 + .put("id", node.id().toString())
84 + .put("ip", node.ip().toString())
85 + .put("uiAttached", node.equals(clusterService.getLocalNode()));
86 + }
87 +
88 +
89 + @Override
90 + public void process(ObjectNode message) {
91 + // We registered for "bootstrap" events, but we don't expect
92 + // the GUI to send us any; it was just that we had to define a
93 + // non-empty set of events that we handle, in the constructor.
94 + }
95 +
96 +}
...@@ -127,7 +127,6 @@ public abstract class TopologyViewMessageHandlerBase extends UiMessageHandler { ...@@ -127,7 +127,6 @@ public abstract class TopologyViewMessageHandlerBase extends UiMessageHandler {
127 protected StatisticService statService; 127 protected StatisticService statService;
128 protected TopologyService topologyService; 128 protected TopologyService topologyService;
129 129
130 - protected final ObjectMapper mapper = new ObjectMapper();
131 private String version; 130 private String version;
132 131
133 // TODO: extract into an external & durable state; good enough for now and demo 132 // TODO: extract into an external & durable state; good enough for now and demo
......
...@@ -59,7 +59,11 @@ public class UiExtensionManager implements UiExtensionService { ...@@ -59,7 +59,11 @@ public class UiExtensionManager implements UiExtensionService {
59 List<UiView> coreViews = of(new UiView("sample", "Sample"), 59 List<UiView> coreViews = of(new UiView("sample", "Sample"),
60 new UiView("topo", "Topology View"), 60 new UiView("topo", "Topology View"),
61 new UiView("device", "Devices")); 61 new UiView("device", "Devices"));
62 - UiMessageHandlerFactory messageHandlerFactory = () -> ImmutableList.of(new TopologyViewMessageHandler()); 62 + UiMessageHandlerFactory messageHandlerFactory =
63 + () -> ImmutableList.of(
64 + new BootstrapMessageHandler(),
65 + new TopologyViewMessageHandler()
66 + );
63 return new UiExtension(coreViews, messageHandlerFactory, "core", 67 return new UiExtension(coreViews, messageHandlerFactory, "core",
64 UiExtensionManager.class.getClassLoader()); 68 UiExtensionManager.class.getClassLoader());
65 } 69 }
......