Adding code to enable GUI failover.
Change-Id: I8423f17349411d24332db8670840438d0d8ec8ba
Showing
7 changed files
with
75 additions
and
99 deletions
... | @@ -29,4 +29,13 @@ public interface UiConnection { | ... | @@ -29,4 +29,13 @@ public interface UiConnection { |
29 | */ | 29 | */ |
30 | void sendMessage(ObjectNode message); | 30 | void sendMessage(ObjectNode message); |
31 | 31 | ||
32 | + /** | ||
33 | + * Composes a message into JSON and sends it to the user interface client. | ||
34 | + * | ||
35 | + * @param type message type | ||
36 | + * @param sid message sequence number | ||
37 | + * @param payload message payload | ||
38 | + */ | ||
39 | + void sendMessage(String type, long sid, ObjectNode payload); | ||
40 | + | ||
32 | } | 41 | } |
... | \ No newline at end of file | ... | \ No newline at end of file | ... | ... |
tools/test/cells/beastMod
0 → 100644
1 | +# Bare metal cluster with rearranged nodes | ||
2 | + | ||
3 | +# Use the 10G NIC for cluster communications | ||
4 | +export ONOS_NIC="10.254.1.*" | ||
5 | + | ||
6 | +# ONOS Test proxy | ||
7 | +export OCT=10.254.1.200 | ||
8 | + | ||
9 | +# Use the 1G NICs for external access | ||
10 | +export OC1=10.254.1.207 | ||
11 | +export OC2=10.254.1.202 | ||
12 | +export OC3=10.254.1.203 | ||
13 | +export OC4=10.254.1.204 | ||
14 | +export OC5=10.254.1.206 | ||
15 | + | ||
16 | +export OCI=${OC1} | ||
17 | + | ||
18 | +export ONOS_FEATURES=webconsole,onos-api,onos-core,onos-cli,onos-rest,onos-null |
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 | -} |
... | @@ -305,7 +305,7 @@ public abstract class TopologyViewMessageHandlerBase extends UiMessageHandler { | ... | @@ -305,7 +305,7 @@ public abstract class TopologyViewMessageHandlerBase extends UiMessageHandler { |
305 | .put("id", node.id().toString()) | 305 | .put("id", node.id().toString()) |
306 | .put("ip", node.ip().toString()) | 306 | .put("ip", node.ip().toString()) |
307 | .put("online", clusterService.getState(node.id()) == ACTIVE) | 307 | .put("online", clusterService.getState(node.id()) == ACTIVE) |
308 | - .put("uiAttached", event.subject().equals(clusterService.getLocalNode())) | 308 | + .put("uiAttached", node.equals(clusterService.getLocalNode())) |
309 | .put("switches", switchCount); | 309 | .put("switches", switchCount); |
310 | 310 | ||
311 | ArrayNode labels = mapper.createArrayNode(); | 311 | ArrayNode labels = mapper.createArrayNode(); | ... | ... |
... | @@ -61,7 +61,6 @@ public class UiExtensionManager implements UiExtensionService { | ... | @@ -61,7 +61,6 @@ public class UiExtensionManager implements UiExtensionService { |
61 | new UiView("device", "Devices")); | 61 | new UiView("device", "Devices")); |
62 | UiMessageHandlerFactory messageHandlerFactory = | 62 | UiMessageHandlerFactory messageHandlerFactory = |
63 | () -> ImmutableList.of( | 63 | () -> ImmutableList.of( |
64 | - new BootstrapMessageHandler(), | ||
65 | new TopologyViewMessageHandler() | 64 | new TopologyViewMessageHandler() |
66 | ); | 65 | ); |
67 | return new UiExtension(coreViews, messageHandlerFactory, "core", | 66 | return new UiExtension(coreViews, messageHandlerFactory, "core", | ... | ... |
... | @@ -16,9 +16,12 @@ | ... | @@ -16,9 +16,12 @@ |
16 | package org.onosproject.ui.impl; | 16 | package org.onosproject.ui.impl; |
17 | 17 | ||
18 | import com.fasterxml.jackson.databind.ObjectMapper; | 18 | import com.fasterxml.jackson.databind.ObjectMapper; |
19 | +import com.fasterxml.jackson.databind.node.ArrayNode; | ||
19 | import com.fasterxml.jackson.databind.node.ObjectNode; | 20 | import com.fasterxml.jackson.databind.node.ObjectNode; |
20 | import org.eclipse.jetty.websocket.WebSocket; | 21 | import org.eclipse.jetty.websocket.WebSocket; |
21 | import org.onlab.osgi.ServiceDirectory; | 22 | import org.onlab.osgi.ServiceDirectory; |
23 | +import org.onosproject.cluster.ClusterService; | ||
24 | +import org.onosproject.cluster.ControllerNode; | ||
22 | import org.onosproject.ui.UiConnection; | 25 | import org.onosproject.ui.UiConnection; |
23 | import org.onosproject.ui.UiExtensionService; | 26 | import org.onosproject.ui.UiExtensionService; |
24 | import org.onosproject.ui.UiMessageHandler; | 27 | import org.onosproject.ui.UiMessageHandler; |
... | @@ -99,6 +102,7 @@ public class UiWebSocket | ... | @@ -99,6 +102,7 @@ public class UiWebSocket |
99 | this.connection = connection; | 102 | this.connection = connection; |
100 | this.control = (FrameConnection) connection; | 103 | this.control = (FrameConnection) connection; |
101 | createHandlers(); | 104 | createHandlers(); |
105 | + sendInstanceData(); | ||
102 | } | 106 | } |
103 | 107 | ||
104 | @Override | 108 | @Override |
... | @@ -143,6 +147,18 @@ public class UiWebSocket | ... | @@ -143,6 +147,18 @@ public class UiWebSocket |
143 | } | 147 | } |
144 | } | 148 | } |
145 | 149 | ||
150 | + @Override | ||
151 | + public void sendMessage(String type, long sid, ObjectNode payload) { | ||
152 | + ObjectNode message = mapper.createObjectNode(); | ||
153 | + message.put("event", type); | ||
154 | + if (sid > 0) { | ||
155 | + message.put("sid", sid); | ||
156 | + } | ||
157 | + message.set("payload", payload); | ||
158 | + sendMessage(message); | ||
159 | + | ||
160 | + } | ||
161 | + | ||
146 | // Creates new message handlers. | 162 | // Creates new message handlers. |
147 | private void createHandlers() { | 163 | private void createHandlers() { |
148 | handlers = new HashMap<>(); | 164 | handlers = new HashMap<>(); |
... | @@ -163,5 +179,24 @@ public class UiWebSocket | ... | @@ -163,5 +179,24 @@ public class UiWebSocket |
163 | handlers.forEach((type, handler) -> handler.destroy()); | 179 | handlers.forEach((type, handler) -> handler.destroy()); |
164 | handlers.clear(); | 180 | handlers.clear(); |
165 | } | 181 | } |
182 | + | ||
183 | + // Sends cluster node/instance information to allow GUI to fail-over. | ||
184 | + private void sendInstanceData() { | ||
185 | + ClusterService service = directory.get(ClusterService.class); | ||
186 | + ArrayNode instances = mapper.createArrayNode(); | ||
187 | + | ||
188 | + for (ControllerNode node : service.getNodes()) { | ||
189 | + ObjectNode instance = mapper.createObjectNode() | ||
190 | + .put("id", node.id().toString()) | ||
191 | + .put("ip", node.ip().toString()) | ||
192 | + .put("uiAttached", node.equals(service.getLocalNode())); | ||
193 | + instances.add(instance); | ||
194 | + } | ||
195 | + | ||
196 | + ObjectNode payload = mapper.createObjectNode(); | ||
197 | + payload.set("instances", instances); | ||
198 | + sendMessage("onosInstances", 0, payload); | ||
199 | + } | ||
200 | + | ||
166 | } | 201 | } |
167 | 202 | ... | ... |
... | @@ -29,8 +29,14 @@ | ... | @@ -29,8 +29,14 @@ |
29 | sid = 0, // event sequence identifier | 29 | sid = 0, // event sequence identifier |
30 | handlers = {}, // event handler bindings | 30 | handlers = {}, // event handler bindings |
31 | pendingEvents = [], // events TX'd while socket not up | 31 | pendingEvents = [], // events TX'd while socket not up |
32 | - url; // web socket URL | 32 | + url, // web socket URL |
33 | + instances = []; | ||
33 | 34 | ||
35 | + var builtinHandlers = { | ||
36 | + onosInstances: function (data) { | ||
37 | + instances = data.instances; | ||
38 | + } | ||
39 | + } | ||
34 | 40 | ||
35 | // ========================== | 41 | // ========================== |
36 | // === Web socket callbacks | 42 | // === Web socket callbacks |
... | @@ -186,6 +192,11 @@ | ... | @@ -186,6 +192,11 @@ |
186 | wsock = _wsock_; | 192 | wsock = _wsock_; |
187 | vs = _vs_; | 193 | vs = _vs_; |
188 | 194 | ||
195 | + // Bind instance handlers | ||
196 | + bindHandlers({ | ||
197 | + onosInstances: builtinHandlers | ||
198 | + }); | ||
199 | + | ||
189 | return { | 200 | return { |
190 | resetSid: resetSid, | 201 | resetSid: resetSid, |
191 | createWebSocket: createWebSocket, | 202 | createWebSocket: createWebSocket, | ... | ... |
-
Please register or login to post a comment