blob: 057a05050c86d6df8184673f9c0229705520d3f2 [file] [log] [blame]
Simon Huntd5b96732016-07-08 13:22:27 -07001/*
Brian O'Connora09fe5b2017-08-03 21:12:30 -07002 * Copyright 2016-present Open Networking Foundation
Simon Huntd5b96732016-07-08 13:22:27 -07003 *
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
17package org.onosproject.ui.impl.topo;
18
19import com.fasterxml.jackson.databind.node.ObjectNode;
20import com.google.common.collect.ImmutableSet;
21import org.onlab.osgi.ServiceDirectory;
22import org.onosproject.ui.RequestHandler;
23import org.onosproject.ui.UiConnection;
24import org.onosproject.ui.UiMessageHandler;
25import org.onosproject.ui.impl.UiWebSocket;
26import org.onosproject.ui.model.topo.UiClusterMember;
Simon Hunt98189192016-07-29 19:02:27 -070027import org.onosproject.ui.model.topo.UiNode;
Simon Huntd5b96732016-07-08 13:22:27 -070028import org.onosproject.ui.model.topo.UiRegion;
Simon Huntc13082f2016-08-03 21:20:23 -070029import org.onosproject.ui.model.topo.UiSynthLink;
Simon Huntd5b96732016-07-08 13:22:27 -070030import org.onosproject.ui.model.topo.UiTopoLayout;
31import org.slf4j.Logger;
32import org.slf4j.LoggerFactory;
33
34import java.util.Collection;
35import java.util.List;
Simon Hunt977aa052016-07-20 17:08:29 -070036import java.util.Set;
37
Simon Huntd5b96732016-07-08 13:22:27 -070038/*
39 NOTES:
40
41 The original topology view message handler was broken into two classes
42 TopologyViewMessageHandler, and TopologyViewMessageHandlerBase.
Simon Huntd5b96732016-07-08 13:22:27 -070043
Simon Hunta7aea842017-05-03 19:42:50 -070044 We do not need to follow that model necessarily. Instead, we have this
45 class and Topo2Jsonifier, which takes UiModel objects and renders them
46 as JSON objects.
Simon Huntd5b96732016-07-08 13:22:27 -070047
48 */
49
50/**
51 * Server-side component for interacting with the new "Region aware" topology
52 * view in the Web UI.
53 */
54public class Topo2ViewMessageHandler extends UiMessageHandler {
55
56 private final Logger log = LoggerFactory.getLogger(getClass());
57
58 // === Inbound event identifiers
Simon Hunt98189192016-07-29 19:02:27 -070059 private static final String START = "topo2Start";
60 private static final String NAV_REGION = "topo2navRegion";
61 private static final String STOP = "topo2Stop";
Steven Burrowse7cc3082016-09-27 11:24:58 -070062 private static final String UPDATE_META2 = "updateMeta2";
Simon Huntd5b96732016-07-08 13:22:27 -070063
64 // === Outbound event identifiers
Simon Hunt977aa052016-07-20 17:08:29 -070065 private static final String ALL_INSTANCES = "topo2AllInstances";
Simon Huntd5b96732016-07-08 13:22:27 -070066 private static final String CURRENT_LAYOUT = "topo2CurrentLayout";
67 private static final String CURRENT_REGION = "topo2CurrentRegion";
Simon Hunt977aa052016-07-20 17:08:29 -070068 private static final String PEER_REGIONS = "topo2PeerRegions";
Simon Hunt22c35df2017-04-26 17:28:42 -070069 private static final String OVERLAYS = "topo2Overlays";
Sean Condonadeb7162019-04-13 20:56:14 +010070 private static final String TOPO_SELECT_OVERLAY = "topoSelectOverlay";
Simon Huntd5b96732016-07-08 13:22:27 -070071
Sean Condonadeb7162019-04-13 20:56:14 +010072 // fields
73 private static final String ACTIVATE = "activate";
74 private static final String DEACTIVATE = "deactivate";
Simon Hunt977aa052016-07-20 17:08:29 -070075
Simon Huntd5b96732016-07-08 13:22:27 -070076 private UiTopoSession topoSession;
77 private Topo2Jsonifier t2json;
Simon Hunt22c35df2017-04-26 17:28:42 -070078 private Topo2OverlayCache overlay2Cache;
Simon Hunt2d7cd6f2017-05-04 13:04:50 -070079 private Topo2TrafficMessageHandler trafficHandler;
Simon Huntd5b96732016-07-08 13:22:27 -070080
81
82 @Override
83 public void init(UiConnection connection, ServiceDirectory directory) {
84 super.init(connection, directory);
85
86 // get the topo session from the UiWebSocket
87 topoSession = ((UiWebSocket) connection).topoSession();
Simon Hunt95f4b422017-03-03 13:49:05 -080088 t2json = new Topo2Jsonifier(directory, connection.userName());
Simon Huntd5b96732016-07-08 13:22:27 -070089 }
90
Simon Hunt22c35df2017-04-26 17:28:42 -070091 /**
92 * Sets a reference to the overlay cache for interacting with registered
93 * overlays.
94 *
95 * @param overlay2Cache the overlay cache
96 */
97 public void setOverlayCache(Topo2OverlayCache overlay2Cache) {
98 this.overlay2Cache = overlay2Cache;
99 }
100
Simon Hunt2d7cd6f2017-05-04 13:04:50 -0700101 /**
102 * Sets a reference to the traffic message handler.
103 *
104 * @param traffic the traffic message handler instance
105 */
106 public void setTrafficHandler(Topo2TrafficMessageHandler traffic) {
107 trafficHandler = traffic;
108 }
109
Simon Hunt22c35df2017-04-26 17:28:42 -0700110
Simon Huntd5b96732016-07-08 13:22:27 -0700111 @Override
112 protected Collection<RequestHandler> createRequestHandlers() {
113 return ImmutableSet.of(
114 new Topo2Start(),
Simon Hunt98189192016-07-29 19:02:27 -0700115 new Topo2NavRegion(),
Steven Burrowse7cc3082016-09-27 11:24:58 -0700116 new Topo2Stop(),
117 new Topo2UpdateMeta()
Simon Huntd5b96732016-07-08 13:22:27 -0700118 );
119 }
120
Sean Condonadeb7162019-04-13 20:56:14 +0100121 private final class TopoSelectOverlay extends RequestHandler {
122 private TopoSelectOverlay() {
123 super(TOPO_SELECT_OVERLAY);
124 }
125
126 @Override
127 public void process(ObjectNode payload) {
128 String deact = string(payload, DEACTIVATE);
129 String act = string(payload, ACTIVATE);
130 overlay2Cache.switchOverlay(deact, act);
131 }
132 }
133
Simon Huntd5b96732016-07-08 13:22:27 -0700134 // ==================================================================
135
Simon Hunt377f5d22016-09-01 16:27:21 -0700136 private ObjectNode mkLayoutMessage(UiTopoLayout currentLayout) {
137 List<UiTopoLayout> crumbs = topoSession.breadCrumbs();
Simon Huntf7e7d4a2017-03-24 15:22:20 -0700138 return t2json.layout(currentLayout, crumbs);
Simon Hunt377f5d22016-09-01 16:27:21 -0700139 }
140
141 private ObjectNode mkRegionMessage(UiTopoLayout currentLayout) {
142 UiRegion region = topoSession.getRegion(currentLayout);
143 Set<UiRegion> kids = topoSession.getSubRegions(currentLayout);
144 List<UiSynthLink> links = topoSession.getLinks(currentLayout);
145 return t2json.region(region, kids, links);
146 }
147
148 private ObjectNode mkPeersMessage(UiTopoLayout currentLayout) {
149 Set<UiNode> peers = topoSession.getPeerNodes(currentLayout);
150 ObjectNode peersPayload = objectNode();
Simon Huntf7e7d4a2017-03-24 15:22:20 -0700151 String rid = currentLayout.regionId().toString();
152 peersPayload.set("peers", t2json.closedNodes(rid, peers));
Simon Hunt377f5d22016-09-01 16:27:21 -0700153 return peersPayload;
154 }
155
Simon Hunt22c35df2017-04-26 17:28:42 -0700156 // ==================================================================
157
Simon Hunt377f5d22016-09-01 16:27:21 -0700158
Simon Huntd5b96732016-07-08 13:22:27 -0700159 private final class Topo2Start extends RequestHandler {
160 private Topo2Start() {
Simon Hunt98189192016-07-29 19:02:27 -0700161 super(START);
Simon Huntd5b96732016-07-08 13:22:27 -0700162 }
163
164 @Override
Simon Hunt8a0429a2017-01-06 16:52:47 -0800165 public void process(ObjectNode payload) {
Simon Huntd5b96732016-07-08 13:22:27 -0700166 // client view is ready to receive data to display; so start up
167 // server-side processing, and send over initial state
168
169 log.debug("topo2Start: {}", payload);
170
Simon Huntb1ce2602016-07-23 14:04:31 -0700171 // this may be a little heavyweight, but it might be safer to do
172 // this than make assumptions about the order in which devices
173 // and regions are added... and thus internal linkages set up
174 // correctly
175 topoSession.refreshModel();
176
Simon Hunt377f5d22016-09-01 16:27:21 -0700177 // start with the list of ONOS cluster members
Simon Huntd5b96732016-07-08 13:22:27 -0700178 List<UiClusterMember> instances = topoSession.getAllInstances();
179 sendMessage(ALL_INSTANCES, t2json.instances(instances));
180
Simon Hunt377f5d22016-09-01 16:27:21 -0700181
182 // Send layout, region, peers data...
183
Simon Hunt977aa052016-07-20 17:08:29 -0700184 // this is the layout that the user has chosen to display
Simon Huntd5b96732016-07-08 13:22:27 -0700185 UiTopoLayout currentLayout = topoSession.currentLayout();
Simon Hunt377f5d22016-09-01 16:27:21 -0700186 sendMessage(CURRENT_LAYOUT, mkLayoutMessage(currentLayout));
Simon Huntd5b96732016-07-08 13:22:27 -0700187
Simon Hunt977aa052016-07-20 17:08:29 -0700188 // this is the region that is associated with the current layout
189 // this message includes details of the sub-regions, devices,
190 // hosts, and links within the region
191 // (as well as layer-order hints)
Simon Hunt377f5d22016-09-01 16:27:21 -0700192 sendMessage(CURRENT_REGION, mkRegionMessage(currentLayout));
Simon Huntd5b96732016-07-08 13:22:27 -0700193
Simon Hunt98189192016-07-29 19:02:27 -0700194 // these are the regions/devices that are siblings to this region
Simon Hunt377f5d22016-09-01 16:27:21 -0700195 sendMessage(PEER_REGIONS, mkPeersMessage(currentLayout));
Simon Huntd5b96732016-07-08 13:22:27 -0700196 }
Simon Hunt977aa052016-07-20 17:08:29 -0700197 }
198
Simon Hunt98189192016-07-29 19:02:27 -0700199 private final class Topo2NavRegion extends RequestHandler {
200 private Topo2NavRegion() {
201 super(NAV_REGION);
202 }
203
204 @Override
Simon Hunt8a0429a2017-01-06 16:52:47 -0800205 public void process(ObjectNode payload) {
Simon Hunt98189192016-07-29 19:02:27 -0700206 String rid = string(payload, "rid");
Simon Hunt377f5d22016-09-01 16:27:21 -0700207 log.debug("topo2navRegion: rid={}", rid);
208
209 // NOTE: we are NOT re-issuing information about the cluster nodes
210
211 // switch to the selected region...
212 topoSession.navToRegion(rid);
213
214 // re-send layout, region, peers data...
215 UiTopoLayout currentLayout = topoSession.currentLayout();
216 sendMessage(CURRENT_LAYOUT, mkLayoutMessage(currentLayout));
217 sendMessage(CURRENT_REGION, mkRegionMessage(currentLayout));
218 sendMessage(PEER_REGIONS, mkPeersMessage(currentLayout));
Simon Hunt98189192016-07-29 19:02:27 -0700219 }
220 }
221
Simon Huntd5b96732016-07-08 13:22:27 -0700222 private final class Topo2Stop extends RequestHandler {
223 private Topo2Stop() {
Simon Hunt98189192016-07-29 19:02:27 -0700224 super(STOP);
Simon Huntd5b96732016-07-08 13:22:27 -0700225 }
226
227 @Override
Simon Hunt8a0429a2017-01-06 16:52:47 -0800228 public void process(ObjectNode payload) {
Simon Huntd5b96732016-07-08 13:22:27 -0700229 // client view has gone away; so shut down server-side processing
Simon Huntd5b96732016-07-08 13:22:27 -0700230
231 log.debug("topo2Stop: {}", payload);
Simon Hunt2d7cd6f2017-05-04 13:04:50 -0700232 trafficHandler.ceaseAndDesist();
Simon Huntd5b96732016-07-08 13:22:27 -0700233
234 // OLD CODE DID THE FOLLOWING...
Simon Huntd5b96732016-07-08 13:22:27 -0700235// stopSummaryMonitoring();
Simon Huntd5b96732016-07-08 13:22:27 -0700236 }
237 }
238
Steven Burrowse7cc3082016-09-27 11:24:58 -0700239 private final class Topo2UpdateMeta extends RequestHandler {
240 private Topo2UpdateMeta() {
241 super(UPDATE_META2);
242 }
243
244 @Override
Simon Hunt8a0429a2017-01-06 16:52:47 -0800245 public void process(ObjectNode payload) {
Simon Hunt2521d5f2017-03-20 18:17:28 -0700246 // NOTE: metadata for a node is stored within the context of the
247 // current region.
Simon Huntf7e7d4a2017-03-24 15:22:20 -0700248 String rid = topoSession.currentLayout().regionId().toString();
249 t2json.updateMeta(rid, payload);
Steven Burrowse7cc3082016-09-27 11:24:58 -0700250 }
251 }
252
Simon Huntd5b96732016-07-08 13:22:27 -0700253}