blob: e20216d2f0c73fc3c7901049b583ea07d6259f96 [file] [log] [blame]
Thomas Vachuska329af532015-03-10 02:08:33 -07001/*
Brian O'Connor5ab426f2016-04-09 01:19:45 -07002 * Copyright 2015-present Open Networking Laboratory
Thomas Vachuska329af532015-03-10 02:08:33 -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 */
16package org.onosproject.ui.impl;
17
18import com.fasterxml.jackson.databind.JsonNode;
19import com.fasterxml.jackson.databind.node.ArrayNode;
20import com.fasterxml.jackson.databind.node.ObjectNode;
21import com.google.common.collect.ImmutableSet;
22import org.onlab.osgi.ServiceDirectory;
23import org.onlab.util.AbstractAccumulator;
24import org.onlab.util.Accumulator;
25import org.onosproject.cluster.ClusterEvent;
26import org.onosproject.cluster.ClusterEventListener;
27import org.onosproject.cluster.ControllerNode;
28import org.onosproject.core.ApplicationId;
29import org.onosproject.core.CoreService;
Simon Hunt4a6b54b2015-10-27 22:08:25 -070030import org.onosproject.core.DefaultApplicationId;
Thomas Vachuska329af532015-03-10 02:08:33 -070031import org.onosproject.event.Event;
32import org.onosproject.mastership.MastershipAdminService;
33import org.onosproject.mastership.MastershipEvent;
34import org.onosproject.mastership.MastershipListener;
35import org.onosproject.net.ConnectPoint;
36import org.onosproject.net.Device;
Simon Huntde99e0b2015-10-23 18:54:06 -070037import org.onosproject.net.DeviceId;
Thomas Vachuska329af532015-03-10 02:08:33 -070038import org.onosproject.net.Host;
39import org.onosproject.net.HostId;
40import org.onosproject.net.HostLocation;
41import org.onosproject.net.Link;
42import org.onosproject.net.device.DeviceEvent;
43import org.onosproject.net.device.DeviceListener;
44import org.onosproject.net.flow.DefaultTrafficSelector;
45import org.onosproject.net.flow.DefaultTrafficTreatment;
46import org.onosproject.net.flow.FlowRuleEvent;
47import org.onosproject.net.flow.FlowRuleListener;
48import org.onosproject.net.flow.TrafficSelector;
49import org.onosproject.net.flow.TrafficTreatment;
50import org.onosproject.net.host.HostEvent;
51import org.onosproject.net.host.HostListener;
52import org.onosproject.net.intent.HostToHostIntent;
Simon Hunt4a6b54b2015-10-27 22:08:25 -070053import org.onosproject.net.intent.Intent;
Thomas Vachuska329af532015-03-10 02:08:33 -070054import org.onosproject.net.intent.IntentEvent;
55import org.onosproject.net.intent.IntentListener;
Deepa Vaddireddy63340922017-01-19 08:15:31 +053056import org.onosproject.net.intent.IntentService;
Andrea Campanella732ea832017-02-06 09:25:59 -080057import org.onosproject.net.intent.IntentState;
Simon Hunt21281fd2017-03-30 22:28:28 -070058import org.onosproject.net.intent.Key;
59import org.onosproject.net.intent.MultiPointToSinglePointIntent;
Thomas Vachuska329af532015-03-10 02:08:33 -070060import org.onosproject.net.link.LinkEvent;
61import org.onosproject.net.link.LinkListener;
Simon Hunt4a6b54b2015-10-27 22:08:25 -070062import org.onosproject.ui.JsonUtils;
Simon Huntd2747a02015-04-30 22:41:16 -070063import org.onosproject.ui.RequestHandler;
Thomas Vachuska329af532015-03-10 02:08:33 -070064import org.onosproject.ui.UiConnection;
Simon Hunt4fc86852015-08-20 17:57:52 -070065import org.onosproject.ui.impl.TrafficMonitor.Mode;
Simon Hunta17fa672015-08-19 18:42:22 -070066import org.onosproject.ui.topo.Highlights;
Simon Huntd3ceffa2015-08-25 12:44:35 -070067import org.onosproject.ui.topo.NodeSelection;
Simon Hunt0af1ec32015-07-24 12:17:55 -070068import org.onosproject.ui.topo.PropertyPanel;
Thomas Vachuska329af532015-03-10 02:08:33 -070069
70import java.util.ArrayList;
Simon Huntd2747a02015-04-30 22:41:16 -070071import java.util.Collection;
Thomas Vachuska329af532015-03-10 02:08:33 -070072import java.util.Comparator;
73import java.util.HashSet;
74import java.util.List;
Simon Hunt5c1a9382016-06-01 19:35:35 -070075import java.util.Map;
Thomas Vachuska329af532015-03-10 02:08:33 -070076import java.util.Set;
77import java.util.Timer;
78import java.util.TimerTask;
Thomas Vachuska52c98bd2015-05-27 20:54:02 -070079import java.util.concurrent.ExecutorService;
Thomas Vachuska329af532015-03-10 02:08:33 -070080
Thomas Vachuska52c98bd2015-05-27 20:54:02 -070081import static java.util.concurrent.Executors.newSingleThreadExecutor;
82import static org.onlab.util.Tools.groupedThreads;
Thomas Vachuska329af532015-03-10 02:08:33 -070083import static org.onosproject.cluster.ClusterEvent.Type.INSTANCE_ADDED;
84import static org.onosproject.net.DeviceId.deviceId;
85import static org.onosproject.net.HostId.hostId;
Simon Hunt4a6b54b2015-10-27 22:08:25 -070086import static org.onosproject.net.device.DeviceEvent.Type.DEVICE_ADDED;
87import static org.onosproject.net.device.DeviceEvent.Type.DEVICE_UPDATED;
88import static org.onosproject.net.device.DeviceEvent.Type.PORT_STATS_UPDATED;
Thomas Vachuska329af532015-03-10 02:08:33 -070089import static org.onosproject.net.host.HostEvent.Type.HOST_ADDED;
90import static org.onosproject.net.link.LinkEvent.Type.LINK_ADDED;
Simon Huntd3ceffa2015-08-25 12:44:35 -070091import static org.onosproject.ui.JsonUtils.envelope;
Viswanath KSP0f297702016-08-13 18:02:43 +053092import static org.onosproject.ui.JsonUtils.string;
Simon Hunt52560662015-08-27 22:46:44 -070093import static org.onosproject.ui.topo.TopoJson.highlightsMessage;
94import static org.onosproject.ui.topo.TopoJson.json;
Thomas Vachuska329af532015-03-10 02:08:33 -070095
96/**
97 * Web socket capable of interacting with the GUI topology view.
98 */
99public class TopologyViewMessageHandler extends TopologyViewMessageHandlerBase {
100
Simon Huntb745ca62015-07-28 15:37:11 -0700101 // incoming event types
Simon Huntd2747a02015-04-30 22:41:16 -0700102 private static final String REQ_DETAILS = "requestDetails";
103 private static final String UPDATE_META = "updateMeta";
104 private static final String ADD_HOST_INTENT = "addHostIntent";
Viswanath KSP0f297702016-08-13 18:02:43 +0530105 private static final String REMOVE_INTENT = "removeIntent";
Deepa Vaddireddy63340922017-01-19 08:15:31 +0530106 private static final String REMOVE_INTENTS = "removeIntents";
Viswanath KSP14aee092016-10-02 01:47:40 +0530107 private static final String RESUBMIT_INTENT = "resubmitIntent";
Simon Huntd2747a02015-04-30 22:41:16 -0700108 private static final String ADD_MULTI_SRC_INTENT = "addMultiSourceIntent";
109 private static final String REQ_RELATED_INTENTS = "requestRelatedIntents";
110 private static final String REQ_NEXT_INTENT = "requestNextRelatedIntent";
111 private static final String REQ_PREV_INTENT = "requestPrevRelatedIntent";
112 private static final String REQ_SEL_INTENT_TRAFFIC = "requestSelectedIntentTraffic";
Simon Hunt4a6b54b2015-10-27 22:08:25 -0700113 private static final String SEL_INTENT = "selectIntent";
Simon Hunt21281fd2017-03-30 22:28:28 -0700114 private static final String REQ_ALL_TRAFFIC = "requestAllTraffic";
Simon Huntd2747a02015-04-30 22:41:16 -0700115 private static final String REQ_DEV_LINK_FLOWS = "requestDeviceLinkFlows";
116 private static final String CANCEL_TRAFFIC = "cancelTraffic";
117 private static final String REQ_SUMMARY = "requestSummary";
118 private static final String CANCEL_SUMMARY = "cancelSummary";
119 private static final String EQ_MASTERS = "equalizeMasters";
120 private static final String SPRITE_LIST_REQ = "spriteListRequest";
121 private static final String SPRITE_DATA_REQ = "spriteDataRequest";
122 private static final String TOPO_START = "topoStart";
Simon Hunte05cae42015-07-23 17:35:24 -0700123 private static final String TOPO_SELECT_OVERLAY = "topoSelectOverlay";
Simon Huntd2747a02015-04-30 22:41:16 -0700124 private static final String TOPO_STOP = "topoStop";
Andrea Campanella732ea832017-02-06 09:25:59 -0800125 private static final String SEL_PROTECTED_INTENT = "selectProtectedIntent";
126 private static final String CANCEL_PROTECTED_INTENT_HIGHLIGHT = "cancelProtectedIntentHighlight";
127
Simon Huntb745ca62015-07-28 15:37:11 -0700128 // outgoing event types
129 private static final String SHOW_SUMMARY = "showSummary";
130 private static final String SHOW_DETAILS = "showDetails";
131 private static final String SPRITE_LIST_RESPONSE = "spriteListResponse";
132 private static final String SPRITE_DATA_RESPONSE = "spriteDataResponse";
133 private static final String UPDATE_INSTANCE = "updateInstance";
Simon Hunt4a6b54b2015-10-27 22:08:25 -0700134 private static final String TOPO_START_DONE = "topoStartDone";
Simon Huntb745ca62015-07-28 15:37:11 -0700135
136 // fields
Simon Hunt5c1a9382016-06-01 19:35:35 -0700137 private static final String PAYLOAD = "payload";
138 private static final String EXTRA = "extra";
Simon Huntb745ca62015-07-28 15:37:11 -0700139 private static final String ID = "id";
Simon Hunt4a6b54b2015-10-27 22:08:25 -0700140 private static final String KEY = "key";
141 private static final String APP_ID = "appId";
142 private static final String APP_NAME = "appName";
Simon Huntb745ca62015-07-28 15:37:11 -0700143 private static final String DEVICE = "device";
144 private static final String HOST = "host";
145 private static final String CLASS = "class";
146 private static final String UNKNOWN = "unknown";
147 private static final String ONE = "one";
148 private static final String TWO = "two";
149 private static final String SRC = "src";
150 private static final String DST = "dst";
151 private static final String DATA = "data";
152 private static final String NAME = "name";
153 private static final String NAMES = "names";
154 private static final String ACTIVATE = "activate";
155 private static final String DEACTIVATE = "deactivate";
Viswanath KSP813a20d2016-09-13 04:25:41 +0530156 private static final String PURGE = "purge";
Simon Hunt21281fd2017-03-30 22:28:28 -0700157 private static final String TRAFFIC_TYPE = "trafficType";
Simon Huntb745ca62015-07-28 15:37:11 -0700158
Simon Hunt21281fd2017-03-30 22:28:28 -0700159 // field values
160 private static final String FLOW_STATS_BYTES = "flowStatsBytes";
161 private static final String PORT_STATS_BIT_SEC = "portStatsBitSec";
162 private static final String PORT_STATS_PKT_SEC = "portStatsPktSec";
Simon Huntd2747a02015-04-30 22:41:16 -0700163
Simon Hunt4a6b54b2015-10-27 22:08:25 -0700164 private static final String MY_APP_ID = "org.onosproject.gui";
Thomas Vachuska329af532015-03-10 02:08:33 -0700165
Simon Hunta17fa672015-08-19 18:42:22 -0700166 private static final long TRAFFIC_PERIOD = 5000;
167 private static final long SUMMARY_PERIOD = 30000;
Thomas Vachuska329af532015-03-10 02:08:33 -0700168
169 private static final Comparator<? super ControllerNode> NODE_COMPARATOR =
Simon Hunt8a0429a2017-01-06 16:52:47 -0800170 Comparator.comparing(o -> o.id().toString());
Thomas Vachuska329af532015-03-10 02:08:33 -0700171
172
Thomas Vachuska52c98bd2015-05-27 20:54:02 -0700173 private final Timer timer = new Timer("onos-topology-view");
Thomas Vachuska329af532015-03-10 02:08:33 -0700174
175 private static final int MAX_EVENTS = 1000;
176 private static final int MAX_BATCH_MS = 5000;
177 private static final int MAX_IDLE_MS = 1000;
178
179 private ApplicationId appId;
180
181 private final ClusterEventListener clusterListener = new InternalClusterListener();
182 private final MastershipListener mastershipListener = new InternalMastershipListener();
183 private final DeviceListener deviceListener = new InternalDeviceListener();
184 private final LinkListener linkListener = new InternalLinkListener();
185 private final HostListener hostListener = new InternalHostListener();
186 private final IntentListener intentListener = new InternalIntentListener();
187 private final FlowRuleListener flowListener = new InternalFlowListener();
188
189 private final Accumulator<Event> eventAccummulator = new InternalEventAccummulator();
Thomas Vachuska52c98bd2015-05-27 20:54:02 -0700190 private final ExecutorService msgSender =
Yuta HIGUCHI1624df12016-07-21 16:54:33 -0700191 newSingleThreadExecutor(groupedThreads("onos/gui", "msg-sender", log));
Thomas Vachuska329af532015-03-10 02:08:33 -0700192
Simon Hunta17fa672015-08-19 18:42:22 -0700193 private TopoOverlayCache overlayCache;
Simon Hunt4fc86852015-08-20 17:57:52 -0700194 private TrafficMonitor traffic;
Andrea Campanella732ea832017-02-06 09:25:59 -0800195 private ProtectedIntentMonitor protectedIntentMonitor;
Thomas Vachuska329af532015-03-10 02:08:33 -0700196
Simon Huntd2747a02015-04-30 22:41:16 -0700197 private TimerTask summaryTask = null;
198 private boolean summaryRunning = false;
Thomas Vachuska329af532015-03-10 02:08:33 -0700199
Simon Huntd5b96732016-07-08 13:22:27 -0700200 private volatile boolean listenersRemoved = false;
Thomas Vachuska329af532015-03-10 02:08:33 -0700201
Thomas Vachuska329af532015-03-10 02:08:33 -0700202
203 @Override
204 public void init(UiConnection connection, ServiceDirectory directory) {
205 super.init(connection, directory);
Simon Hunt4a6b54b2015-10-27 22:08:25 -0700206 appId = directory.get(CoreService.class).registerApplication(MY_APP_ID);
Simon Hunt4fc86852015-08-20 17:57:52 -0700207 traffic = new TrafficMonitor(TRAFFIC_PERIOD, servicesBundle, this);
Andrea Campanella732ea832017-02-06 09:25:59 -0800208 protectedIntentMonitor = new ProtectedIntentMonitor(TRAFFIC_PERIOD, servicesBundle, this);
Thomas Vachuska329af532015-03-10 02:08:33 -0700209 }
210
211 @Override
212 public void destroy() {
213 cancelAllRequests();
Thomas Vachuska2bb48632015-04-28 14:40:42 -0700214 removeListeners();
Thomas Vachuska329af532015-03-10 02:08:33 -0700215 super.destroy();
216 }
217
Thomas Vachuska329af532015-03-10 02:08:33 -0700218 @Override
Simon Huntda580882015-05-12 20:58:18 -0700219 protected Collection<RequestHandler> createRequestHandlers() {
Simon Huntd2747a02015-04-30 22:41:16 -0700220 return ImmutableSet.of(
221 new TopoStart(),
Simon Hunte05cae42015-07-23 17:35:24 -0700222 new TopoSelectOverlay(),
Simon Huntd2747a02015-04-30 22:41:16 -0700223 new TopoStop(),
224 new ReqSummary(),
225 new CancelSummary(),
226 new SpriteListReq(),
227 new SpriteDataReq(),
228 new RequestDetails(),
229 new UpdateMeta(),
230 new EqMasters(),
Thomas Vachuska329af532015-03-10 02:08:33 -0700231
Simon Huntd2747a02015-04-30 22:41:16 -0700232 // TODO: migrate traffic related to separate app
233 new AddHostIntent(),
234 new AddMultiSourceIntent(),
Viswanath KSP0f297702016-08-13 18:02:43 +0530235 new RemoveIntent(),
Viswanath KSP14aee092016-10-02 01:47:40 +0530236 new ResubmitIntent(),
Deepa Vaddireddy63340922017-01-19 08:15:31 +0530237 new RemoveIntents(),
Simon Hunta17fa672015-08-19 18:42:22 -0700238
Simon Hunt21281fd2017-03-30 22:28:28 -0700239 new ReqAllTraffic(),
Simon Hunta17fa672015-08-19 18:42:22 -0700240 new ReqDevLinkFlows(),
Simon Huntd2747a02015-04-30 22:41:16 -0700241 new ReqRelatedIntents(),
242 new ReqNextIntent(),
243 new ReqPrevIntent(),
244 new ReqSelectedIntentTraffic(),
Simon Hunt4a6b54b2015-10-27 22:08:25 -0700245 new SelIntent(),
Andrea Campanella732ea832017-02-06 09:25:59 -0800246 new SelProtectedIntent(),
Simon Hunta17fa672015-08-19 18:42:22 -0700247
Andrea Campanella732ea832017-02-06 09:25:59 -0800248 new CancelTraffic(),
249 new CancelProtectedIntentHighlight()
Simon Huntd2747a02015-04-30 22:41:16 -0700250 );
251 }
Thomas Vachuska329af532015-03-10 02:08:33 -0700252
Simon Hunte05cae42015-07-23 17:35:24 -0700253 /**
254 * Injects the topology overlay cache.
255 *
256 * @param overlayCache injected cache
257 */
258 void setOverlayCache(TopoOverlayCache overlayCache) {
259 this.overlayCache = overlayCache;
260 }
261
Simon Huntd2747a02015-04-30 22:41:16 -0700262 // ==================================================================
Thomas Vachuska329af532015-03-10 02:08:33 -0700263
Simon Huntd2747a02015-04-30 22:41:16 -0700264 private final class TopoStart extends RequestHandler {
265 private TopoStart() {
266 super(TOPO_START);
267 }
Thomas Vachuska329af532015-03-10 02:08:33 -0700268
Simon Huntd2747a02015-04-30 22:41:16 -0700269 @Override
Simon Hunt8a0429a2017-01-06 16:52:47 -0800270 public void process(ObjectNode payload) {
Simon Huntd2747a02015-04-30 22:41:16 -0700271 addListeners();
272 sendAllInstances(null);
273 sendAllDevices();
274 sendAllLinks();
275 sendAllHosts();
Simon Hunt4a6b54b2015-10-27 22:08:25 -0700276 sendTopoStartDone();
Thomas Vachuska329af532015-03-10 02:08:33 -0700277 }
278 }
279
Simon Hunte05cae42015-07-23 17:35:24 -0700280 private final class TopoSelectOverlay extends RequestHandler {
281 private TopoSelectOverlay() {
282 super(TOPO_SELECT_OVERLAY);
283 }
284
285 @Override
Simon Hunt8a0429a2017-01-06 16:52:47 -0800286 public void process(ObjectNode payload) {
Simon Huntb745ca62015-07-28 15:37:11 -0700287 String deact = string(payload, DEACTIVATE);
288 String act = string(payload, ACTIVATE);
Simon Hunte05cae42015-07-23 17:35:24 -0700289 overlayCache.switchOverlay(deact, act);
290 }
291 }
292
Simon Huntd2747a02015-04-30 22:41:16 -0700293 private final class TopoStop extends RequestHandler {
294 private TopoStop() {
295 super(TOPO_STOP);
296 }
297
298 @Override
Simon Hunt8a0429a2017-01-06 16:52:47 -0800299 public void process(ObjectNode payload) {
Simon Hunt1ad59272015-11-10 15:23:21 -0800300 removeListeners();
Simon Huntd2747a02015-04-30 22:41:16 -0700301 stopSummaryMonitoring();
Simon Hunt4fc86852015-08-20 17:57:52 -0700302 traffic.stopMonitoring();
Simon Huntd2747a02015-04-30 22:41:16 -0700303 }
304 }
305
306 private final class ReqSummary extends RequestHandler {
307 private ReqSummary() {
308 super(REQ_SUMMARY);
309 }
310
311 @Override
Simon Hunt8a0429a2017-01-06 16:52:47 -0800312 public void process(ObjectNode payload) {
313 requestSummary();
Simon Huntd2747a02015-04-30 22:41:16 -0700314 startSummaryMonitoring();
315 }
316 }
317
318 private final class CancelSummary extends RequestHandler {
319 private CancelSummary() {
320 super(CANCEL_SUMMARY);
321 }
322
323 @Override
Simon Hunt8a0429a2017-01-06 16:52:47 -0800324 public void process(ObjectNode payload) {
Simon Huntd2747a02015-04-30 22:41:16 -0700325 stopSummaryMonitoring();
326 }
327 }
328
329 private final class SpriteListReq extends RequestHandler {
330 private SpriteListReq() {
331 super(SPRITE_LIST_REQ);
332 }
333
334 @Override
Simon Hunt8a0429a2017-01-06 16:52:47 -0800335 public void process(ObjectNode payload) {
Simon Huntda580882015-05-12 20:58:18 -0700336 ObjectNode root = objectNode();
337 ArrayNode names = arrayNode();
Simon Huntd2747a02015-04-30 22:41:16 -0700338 get(SpriteService.class).getNames().forEach(names::add);
Simon Huntb745ca62015-07-28 15:37:11 -0700339 root.set(NAMES, names);
Simon Hunt8a0429a2017-01-06 16:52:47 -0800340 sendMessage(SPRITE_LIST_RESPONSE, root);
Simon Huntd2747a02015-04-30 22:41:16 -0700341 }
342 }
343
344 private final class SpriteDataReq extends RequestHandler {
345 private SpriteDataReq() {
346 super(SPRITE_DATA_REQ);
347 }
348
349 @Override
Simon Hunt8a0429a2017-01-06 16:52:47 -0800350 public void process(ObjectNode payload) {
Simon Huntb745ca62015-07-28 15:37:11 -0700351 String name = string(payload, NAME);
Simon Huntda580882015-05-12 20:58:18 -0700352 ObjectNode root = objectNode();
Simon Huntb745ca62015-07-28 15:37:11 -0700353 root.set(DATA, get(SpriteService.class).get(name));
Simon Hunt8a0429a2017-01-06 16:52:47 -0800354 sendMessage(SPRITE_DATA_RESPONSE, root);
Simon Huntd2747a02015-04-30 22:41:16 -0700355 }
356 }
357
358 private final class RequestDetails extends RequestHandler {
359 private RequestDetails() {
360 super(REQ_DETAILS);
361 }
362
363 @Override
Simon Hunt8a0429a2017-01-06 16:52:47 -0800364 public void process(ObjectNode payload) {
Simon Huntb745ca62015-07-28 15:37:11 -0700365 String type = string(payload, CLASS, UNKNOWN);
366 String id = string(payload, ID);
367 PropertyPanel pp = null;
Simon Huntd2747a02015-04-30 22:41:16 -0700368
Simon Huntb745ca62015-07-28 15:37:11 -0700369 if (type.equals(DEVICE)) {
Simon Huntde99e0b2015-10-23 18:54:06 -0700370 DeviceId did = deviceId(id);
Simon Hunt8a0429a2017-01-06 16:52:47 -0800371 pp = deviceDetails(did);
Simon Huntde99e0b2015-10-23 18:54:06 -0700372 overlayCache.currentOverlay().modifyDeviceDetails(pp, did);
Simon Huntb745ca62015-07-28 15:37:11 -0700373 } else if (type.equals(HOST)) {
Simon Huntde99e0b2015-10-23 18:54:06 -0700374 HostId hid = hostId(id);
Simon Hunt8a0429a2017-01-06 16:52:47 -0800375 pp = hostDetails(hid);
Simon Huntde99e0b2015-10-23 18:54:06 -0700376 overlayCache.currentOverlay().modifyHostDetails(pp, hid);
Simon Huntd2747a02015-04-30 22:41:16 -0700377 }
Simon Huntb745ca62015-07-28 15:37:11 -0700378
Simon Hunt8a0429a2017-01-06 16:52:47 -0800379 sendMessage(envelope(SHOW_DETAILS, json(pp)));
Simon Huntd2747a02015-04-30 22:41:16 -0700380 }
381 }
382
383 private final class UpdateMeta extends RequestHandler {
384 private UpdateMeta() {
385 super(UPDATE_META);
386 }
387
388 @Override
Simon Hunt8a0429a2017-01-06 16:52:47 -0800389 public void process(ObjectNode payload) {
Simon Huntd2747a02015-04-30 22:41:16 -0700390 updateMetaUi(payload);
391 }
392 }
393
394 private final class EqMasters extends RequestHandler {
395 private EqMasters() {
396 super(EQ_MASTERS);
397 }
398
399 @Override
Simon Hunt8a0429a2017-01-06 16:52:47 -0800400 public void process(ObjectNode payload) {
Simon Huntd2747a02015-04-30 22:41:16 -0700401 directory.get(MastershipAdminService.class).balanceRoles();
402 }
403 }
404
Simon Hunta17fa672015-08-19 18:42:22 -0700405
406 // ========= -----------------------------------------------------------------
407
Simon Huntd2747a02015-04-30 22:41:16 -0700408 // === TODO: move traffic related classes to traffic app
409
410 private final class AddHostIntent extends RequestHandler {
411 private AddHostIntent() {
412 super(ADD_HOST_INTENT);
413 }
414
415 @Override
Simon Hunt8a0429a2017-01-06 16:52:47 -0800416 public void process(ObjectNode payload) {
Simon Huntd2747a02015-04-30 22:41:16 -0700417 // TODO: add protection against device ids and non-existent hosts.
Simon Huntb745ca62015-07-28 15:37:11 -0700418 HostId one = hostId(string(payload, ONE));
419 HostId two = hostId(string(payload, TWO));
Simon Huntd2747a02015-04-30 22:41:16 -0700420
421 HostToHostIntent intent = HostToHostIntent.builder()
Thomas Vachuskacb5016f2015-05-18 14:11:43 -0700422 .appId(appId)
423 .one(one)
424 .two(two)
425 .build();
Simon Huntd2747a02015-04-30 22:41:16 -0700426
427 intentService.submit(intent);
Simon Huntd2862c32015-08-24 17:41:51 -0700428 if (overlayCache.isActive(TrafficOverlay.TRAFFIC_ID)) {
429 traffic.monitor(intent);
430 }
Simon Huntd2747a02015-04-30 22:41:16 -0700431 }
432 }
433
Viswanath KSP0f297702016-08-13 18:02:43 +0530434 private Intent findIntentByPayload(ObjectNode payload) {
Yi Tseng3a9b01c2017-02-16 14:24:28 -0800435 Intent intent;
436 Key key;
Viswanath KSP0f297702016-08-13 18:02:43 +0530437 int appId = Integer.parseInt(string(payload, APP_ID));
438 String appName = string(payload, APP_NAME);
439 ApplicationId applicId = new DefaultApplicationId(appId, appName);
Yi Tseng3a9b01c2017-02-16 14:24:28 -0800440 String stringKey = string(payload, KEY);
441 try {
442 // FIXME: If apps use different string key, but they contains
443 // same numeric value (e.g. "020", "0x10", "16", "#10")
444 // and one intent using long key (e.g. 16L)
445 // this function might return wrong intent.
Viswanath KSP0f297702016-08-13 18:02:43 +0530446
Yi Tseng3a9b01c2017-02-16 14:24:28 -0800447 long longKey = Long.decode(stringKey);
448 key = Key.of(longKey, applicId);
449 intent = intentService.getIntent(key);
450
451 if (intent == null) {
452 // Intent might using string key, not long key
453 key = Key.of(stringKey, applicId);
454 intent = intentService.getIntent(key);
455 }
456 } catch (NumberFormatException ex) {
457 // string key
458 key = Key.of(stringKey, applicId);
459 intent = intentService.getIntent(key);
460 }
461
Viswanath KSP0f297702016-08-13 18:02:43 +0530462 log.debug("Attempting to select intent by key={}", key);
463
Yi Tseng3a9b01c2017-02-16 14:24:28 -0800464 return intent;
Viswanath KSP0f297702016-08-13 18:02:43 +0530465 }
466
467 private final class RemoveIntent extends RequestHandler {
468 private RemoveIntent() {
469 super(REMOVE_INTENT);
470 }
471
Viswanath KSP813a20d2016-09-13 04:25:41 +0530472 private boolean isIntentToBePurged(ObjectNode payload) {
473 return bool(payload, PURGE);
474 }
475
Viswanath KSP0f297702016-08-13 18:02:43 +0530476 @Override
Simon Hunt8a0429a2017-01-06 16:52:47 -0800477 public void process(ObjectNode payload) {
Viswanath KSP0f297702016-08-13 18:02:43 +0530478 Intent intent = findIntentByPayload(payload);
479 if (intent == null) {
480 log.warn("Unable to find intent from payload {}", payload);
481 } else {
Viswanath KSP813a20d2016-09-13 04:25:41 +0530482 log.debug("Withdrawing / Purging intent {}", intent.key());
483 if (isIntentToBePurged(payload)) {
484 intentService.purge(intent);
485 } else {
486 intentService.withdraw(intent);
487 }
Viswanath KSP0f297702016-08-13 18:02:43 +0530488 }
489 }
490 }
491
Viswanath KSP14aee092016-10-02 01:47:40 +0530492 private final class ResubmitIntent extends RequestHandler {
493 private ResubmitIntent() {
494 super(RESUBMIT_INTENT);
495 }
496
497 @Override
Simon Hunt8a0429a2017-01-06 16:52:47 -0800498 public void process(ObjectNode payload) {
Viswanath KSP14aee092016-10-02 01:47:40 +0530499 Intent intent = findIntentByPayload(payload);
500 if (intent == null) {
501 log.warn("Unable to find intent from payload {}", payload);
502 } else {
503 log.debug("Resubmitting intent {}", intent.key());
504 intentService.submit(intent);
505 }
506 }
507 }
508
Simon Huntd2747a02015-04-30 22:41:16 -0700509 private final class AddMultiSourceIntent extends RequestHandler {
510 private AddMultiSourceIntent() {
511 super(ADD_MULTI_SRC_INTENT);
512 }
513
514 @Override
Simon Hunt8a0429a2017-01-06 16:52:47 -0800515 public void process(ObjectNode payload) {
Simon Huntd2747a02015-04-30 22:41:16 -0700516 // TODO: add protection against device ids and non-existent hosts.
Simon Huntb745ca62015-07-28 15:37:11 -0700517 Set<HostId> src = getHostIds((ArrayNode) payload.path(SRC));
518 HostId dst = hostId(string(payload, DST));
Simon Huntd2747a02015-04-30 22:41:16 -0700519 Host dstHost = hostService.getHost(dst);
520
521 Set<ConnectPoint> ingressPoints = getHostLocations(src);
522
523 // FIXME: clearly, this is not enough
524 TrafficSelector selector = DefaultTrafficSelector.builder()
525 .matchEthDst(dstHost.mac()).build();
526 TrafficTreatment treatment = DefaultTrafficTreatment.emptyTreatment();
527
528 MultiPointToSinglePointIntent intent =
529 MultiPointToSinglePointIntent.builder()
530 .appId(appId)
531 .selector(selector)
532 .treatment(treatment)
533 .ingressPoints(ingressPoints)
534 .egressPoint(dstHost.location())
535 .build();
536
537 intentService.submit(intent);
Simon Huntd2862c32015-08-24 17:41:51 -0700538 if (overlayCache.isActive(TrafficOverlay.TRAFFIC_ID)) {
539 traffic.monitor(intent);
540 }
Simon Huntd2747a02015-04-30 22:41:16 -0700541 }
542 }
543
Deepa Vaddireddy63340922017-01-19 08:15:31 +0530544 private final class RemoveIntents extends RequestHandler {
545 private RemoveIntents() {
546 super(REMOVE_INTENTS);
547 }
548
549
550 @Override
551 public void process(ObjectNode payload) {
552 IntentService intentService = get(IntentService.class);
553 for (Intent intent : intentService.getIntents()) {
554 if (intentService.getIntentState(intent.key()) == IntentState.WITHDRAWN) {
555 intentService.purge(intent);
556 }
557 }
558
559 }
560 }
561
Simon Hunta17fa672015-08-19 18:42:22 -0700562 // ========= -----------------------------------------------------------------
Simon Huntd2747a02015-04-30 22:41:16 -0700563
Simon Hunt21281fd2017-03-30 22:28:28 -0700564 private final class ReqAllTraffic extends RequestHandler {
565 private ReqAllTraffic() {
566 super(REQ_ALL_TRAFFIC);
Simon Huntd2747a02015-04-30 22:41:16 -0700567 }
568
569 @Override
Simon Hunt8a0429a2017-01-06 16:52:47 -0800570 public void process(ObjectNode payload) {
Simon Hunt21281fd2017-03-30 22:28:28 -0700571 String trafficType = string(payload, TRAFFIC_TYPE, FLOW_STATS_BYTES);
Thomas Vachuskaf0397b52015-05-29 13:50:17 -0700572
Simon Hunt21281fd2017-03-30 22:28:28 -0700573 switch (trafficType) {
574 case FLOW_STATS_BYTES:
575 traffic.monitor(Mode.ALL_FLOW_TRAFFIC_BYTES);
576 break;
577 case PORT_STATS_BIT_SEC:
578 traffic.monitor(Mode.ALL_PORT_TRAFFIC_BIT_PS);
579 break;
580 case PORT_STATS_PKT_SEC:
581 traffic.monitor(Mode.ALL_PORT_TRAFFIC_PKT_PS);
582 break;
583 default:
584 break;
585 }
Simon Huntd2747a02015-04-30 22:41:16 -0700586 }
587 }
588
589 private final class ReqDevLinkFlows extends RequestHandler {
590 private ReqDevLinkFlows() {
591 super(REQ_DEV_LINK_FLOWS);
592 }
593
594 @Override
Simon Hunt8a0429a2017-01-06 16:52:47 -0800595 public void process(ObjectNode payload) {
Simon Hunta17fa672015-08-19 18:42:22 -0700596 NodeSelection nodeSelection =
Prince Pereira46c82d42016-09-19 13:30:50 +0530597 new NodeSelection(payload, deviceService, hostService, linkService);
Simon Hunt4fc86852015-08-20 17:57:52 -0700598 traffic.monitor(Mode.DEV_LINK_FLOWS, nodeSelection);
Simon Hunta17fa672015-08-19 18:42:22 -0700599 }
600 }
601
602 private final class ReqRelatedIntents extends RequestHandler {
603 private ReqRelatedIntents() {
604 super(REQ_RELATED_INTENTS);
605 }
606
607 @Override
Simon Hunt8a0429a2017-01-06 16:52:47 -0800608 public void process(ObjectNode payload) {
Simon Hunta17fa672015-08-19 18:42:22 -0700609 NodeSelection nodeSelection =
Prince Pereira46c82d42016-09-19 13:30:50 +0530610 new NodeSelection(payload, deviceService, hostService, linkService);
Simon Hunt4fc86852015-08-20 17:57:52 -0700611 traffic.monitor(Mode.RELATED_INTENTS, nodeSelection);
Simon Hunta17fa672015-08-19 18:42:22 -0700612 }
613 }
614
615 private final class ReqNextIntent extends RequestHandler {
616 private ReqNextIntent() {
617 super(REQ_NEXT_INTENT);
618 }
619
620 @Override
Simon Hunt8a0429a2017-01-06 16:52:47 -0800621 public void process(ObjectNode payload) {
Simon Hunt4fc86852015-08-20 17:57:52 -0700622 traffic.selectNextIntent();
Simon Hunta17fa672015-08-19 18:42:22 -0700623 }
624 }
625
626 private final class ReqPrevIntent extends RequestHandler {
627 private ReqPrevIntent() {
628 super(REQ_PREV_INTENT);
629 }
630
631 @Override
Simon Hunt8a0429a2017-01-06 16:52:47 -0800632 public void process(ObjectNode payload) {
Simon Hunt4fc86852015-08-20 17:57:52 -0700633 traffic.selectPreviousIntent();
Simon Hunta17fa672015-08-19 18:42:22 -0700634 }
635 }
636
637 private final class ReqSelectedIntentTraffic extends RequestHandler {
638 private ReqSelectedIntentTraffic() {
639 super(REQ_SEL_INTENT_TRAFFIC);
640 }
641
642 @Override
Simon Hunt8a0429a2017-01-06 16:52:47 -0800643 public void process(ObjectNode payload) {
Simon Hunt4fc86852015-08-20 17:57:52 -0700644 traffic.monitor(Mode.SELECTED_INTENT);
Simon Huntd2747a02015-04-30 22:41:16 -0700645 }
646 }
647
Simon Hunt4a6b54b2015-10-27 22:08:25 -0700648 private final class SelIntent extends RequestHandler {
649 private SelIntent() {
650 super(SEL_INTENT);
651 }
652
653 @Override
Simon Hunt8a0429a2017-01-06 16:52:47 -0800654 public void process(ObjectNode payload) {
Viswanath KSP0f297702016-08-13 18:02:43 +0530655 Intent intent = findIntentByPayload(payload);
Simon Hunt4a6b54b2015-10-27 22:08:25 -0700656 if (intent == null) {
Viswanath KSP0f297702016-08-13 18:02:43 +0530657 log.warn("Unable to find intent from payload {}", payload);
Simon Hunt4a6b54b2015-10-27 22:08:25 -0700658 } else {
Viswanath KSP0f297702016-08-13 18:02:43 +0530659 log.debug("starting to monitor intent {}", intent.key());
Simon Hunt4a6b54b2015-10-27 22:08:25 -0700660 traffic.monitor(intent);
661 }
662 }
663 }
664
Andrea Campanella732ea832017-02-06 09:25:59 -0800665 private final class SelProtectedIntent extends RequestHandler {
666 private SelProtectedIntent() {
667 super(SEL_PROTECTED_INTENT);
668 }
669
670 @Override
671 public void process(ObjectNode payload) {
672 Intent intent = findIntentByPayload(payload);
673 if (intent == null) {
674 log.warn("Unable to find protected intent from payload {}", payload);
675 } else {
676 log.debug("starting to monitor protected intent {}", intent.key());
677 protectedIntentMonitor.monitor(intent);
678 }
679 }
680 }
681
Simon Huntd2747a02015-04-30 22:41:16 -0700682 private final class CancelTraffic extends RequestHandler {
683 private CancelTraffic() {
684 super(CANCEL_TRAFFIC);
685 }
686
687 @Override
Simon Hunt8a0429a2017-01-06 16:52:47 -0800688 public void process(ObjectNode payload) {
Simon Hunt4fc86852015-08-20 17:57:52 -0700689 traffic.stopMonitoring();
Simon Huntd2747a02015-04-30 22:41:16 -0700690 }
691 }
692
Andrea Campanella732ea832017-02-06 09:25:59 -0800693 private final class CancelProtectedIntentHighlight extends RequestHandler {
694 private CancelProtectedIntentHighlight() {
695 super(CANCEL_PROTECTED_INTENT_HIGHLIGHT);
696 }
697
698 @Override
699 public void process(ObjectNode payload) {
700 protectedIntentMonitor.stopMonitoring();
701 }
702 }
703
Simon Huntd2747a02015-04-30 22:41:16 -0700704 //=======================================================================
705
Simon Hunta17fa672015-08-19 18:42:22 -0700706 // Converts highlights to JSON format and sends the message to the client
Simon Hunt8a0429a2017-01-06 16:52:47 -0800707 void sendHighlights(Highlights highlights) {
Simon Hunt52560662015-08-27 22:46:44 -0700708 sendMessage(highlightsMessage(highlights));
Thomas Vachuska329af532015-03-10 02:08:33 -0700709 }
710
Simon Huntd2747a02015-04-30 22:41:16 -0700711 // Subscribes for summary messages.
Simon Hunt8a0429a2017-01-06 16:52:47 -0800712 private synchronized void requestSummary() {
713 PropertyPanel pp = summmaryMessage();
Simon Hunt0af1ec32015-07-24 12:17:55 -0700714 overlayCache.currentOverlay().modifySummary(pp);
Simon Hunt8a0429a2017-01-06 16:52:47 -0800715 sendMessage(envelope(SHOW_SUMMARY, json(pp)));
Thomas Vachuska329af532015-03-10 02:08:33 -0700716 }
717
Simon Huntd2747a02015-04-30 22:41:16 -0700718
Thomas Vachuska329af532015-03-10 02:08:33 -0700719 private void cancelAllRequests() {
720 stopSummaryMonitoring();
Simon Hunt4fc86852015-08-20 17:57:52 -0700721 traffic.stopMonitoring();
Thomas Vachuska329af532015-03-10 02:08:33 -0700722 }
723
724 // Sends all controller nodes to the client as node-added messages.
725 private void sendAllInstances(String messageType) {
726 List<ControllerNode> nodes = new ArrayList<>(clusterService.getNodes());
Simon Hunt8a0429a2017-01-06 16:52:47 -0800727 nodes.sort(NODE_COMPARATOR);
Thomas Vachuska329af532015-03-10 02:08:33 -0700728 for (ControllerNode node : nodes) {
729 sendMessage(instanceMessage(new ClusterEvent(INSTANCE_ADDED, node),
Andrea Campanella732ea832017-02-06 09:25:59 -0800730 messageType));
Thomas Vachuska329af532015-03-10 02:08:33 -0700731 }
732 }
733
734 // Sends all devices to the client as device-added messages.
735 private void sendAllDevices() {
736 // Send optical first, others later for layered rendering
737 for (Device device : deviceService.getDevices()) {
Rimon Ashkenazy8ebfff02016-02-01 11:56:36 +0200738 if ((device.type() == Device.Type.ROADM) ||
Simon Hunt5c1a9382016-06-01 19:35:35 -0700739 (device.type() == Device.Type.OTN)) {
Thomas Vachuska329af532015-03-10 02:08:33 -0700740 sendMessage(deviceMessage(new DeviceEvent(DEVICE_ADDED, device)));
741 }
742 }
743 for (Device device : deviceService.getDevices()) {
Rimon Ashkenazy8ebfff02016-02-01 11:56:36 +0200744 if ((device.type() != Device.Type.ROADM) &&
Simon Hunt5c1a9382016-06-01 19:35:35 -0700745 (device.type() != Device.Type.OTN)) {
Thomas Vachuska329af532015-03-10 02:08:33 -0700746 sendMessage(deviceMessage(new DeviceEvent(DEVICE_ADDED, device)));
747 }
748 }
749 }
750
751 // Sends all links to the client as link-added messages.
752 private void sendAllLinks() {
753 // Send optical first, others later for layered rendering
754 for (Link link : linkService.getLinks()) {
755 if (link.type() == Link.Type.OPTICAL) {
Simon Hunt5c1a9382016-06-01 19:35:35 -0700756 sendMessage(composeLinkMessage(new LinkEvent(LINK_ADDED, link)));
Thomas Vachuska329af532015-03-10 02:08:33 -0700757 }
758 }
759 for (Link link : linkService.getLinks()) {
760 if (link.type() != Link.Type.OPTICAL) {
Simon Hunt5c1a9382016-06-01 19:35:35 -0700761 sendMessage(composeLinkMessage(new LinkEvent(LINK_ADDED, link)));
Thomas Vachuska329af532015-03-10 02:08:33 -0700762 }
763 }
764 }
765
Simon Hunt5c1a9382016-06-01 19:35:35 -0700766 // Temporary mechanism to support topology overlays adding their own
767 // properties to the link events.
768 private ObjectNode composeLinkMessage(LinkEvent event) {
769 // start with base message
770 ObjectNode msg = linkMessage(event);
771 Map<String, String> additional =
772 overlayCache.currentOverlay().additionalLinkData(event);
773
774 if (additional != null) {
775 // attach additional key-value pairs as extra data structure
776 ObjectNode payload = (ObjectNode) msg.get(PAYLOAD);
777 payload.set(EXTRA, createExtra(additional));
778 }
779 return msg;
780 }
781
782 private ObjectNode createExtra(Map<String, String> additional) {
783 ObjectNode extra = objectNode();
784 for (Map.Entry<String, String> entry : additional.entrySet()) {
785 extra.put(entry.getKey(), entry.getValue());
786 }
787 return extra;
788 }
789
Thomas Vachuska329af532015-03-10 02:08:33 -0700790 // Sends all hosts to the client as host-added messages.
791 private void sendAllHosts() {
792 for (Host host : hostService.getHosts()) {
793 sendMessage(hostMessage(new HostEvent(HOST_ADDED, host)));
794 }
795 }
796
Thomas Vachuska329af532015-03-10 02:08:33 -0700797 private Set<ConnectPoint> getHostLocations(Set<HostId> hostIds) {
798 Set<ConnectPoint> points = new HashSet<>();
799 for (HostId hostId : hostIds) {
800 points.add(getHostLocation(hostId));
801 }
802 return points;
803 }
804
805 private HostLocation getHostLocation(HostId hostId) {
806 return hostService.getHost(hostId).location();
807 }
808
809 // Produces a list of host ids from the specified JSON array.
810 private Set<HostId> getHostIds(ArrayNode ids) {
811 Set<HostId> hostIds = new HashSet<>();
812 for (JsonNode id : ids) {
813 hostIds.add(hostId(id.asText()));
814 }
815 return hostIds;
816 }
817
Simon Hunt4a6b54b2015-10-27 22:08:25 -0700818 private void sendTopoStartDone() {
819 sendMessage(JsonUtils.envelope(TOPO_START_DONE, objectNode()));
820 }
Thomas Vachuska329af532015-03-10 02:08:33 -0700821
Simon Huntd2747a02015-04-30 22:41:16 -0700822 private synchronized void startSummaryMonitoring() {
Thomas Vachuska329af532015-03-10 02:08:33 -0700823 stopSummaryMonitoring();
Thomas Vachuska329af532015-03-10 02:08:33 -0700824 summaryTask = new SummaryMonitor();
Simon Hunta17fa672015-08-19 18:42:22 -0700825 timer.schedule(summaryTask, SUMMARY_PERIOD, SUMMARY_PERIOD);
Simon Huntd2747a02015-04-30 22:41:16 -0700826 summaryRunning = true;
Thomas Vachuska329af532015-03-10 02:08:33 -0700827 }
828
829 private synchronized void stopSummaryMonitoring() {
Simon Huntd2747a02015-04-30 22:41:16 -0700830 if (summaryTask != null) {
Thomas Vachuska329af532015-03-10 02:08:33 -0700831 summaryTask.cancel();
832 summaryTask = null;
Thomas Vachuska329af532015-03-10 02:08:33 -0700833 }
Simon Huntd2747a02015-04-30 22:41:16 -0700834 summaryRunning = false;
Thomas Vachuska9ed335b2015-04-14 12:07:47 -0700835 }
836
Thomas Vachuska329af532015-03-10 02:08:33 -0700837
838 // Adds all internal listeners.
Thomas Vachuska35fa3d42015-04-30 10:11:47 -0700839 private synchronized void addListeners() {
Thomas Vachuskae586b792015-03-26 13:59:38 -0700840 listenersRemoved = false;
Thomas Vachuska329af532015-03-10 02:08:33 -0700841 clusterService.addListener(clusterListener);
842 mastershipService.addListener(mastershipListener);
843 deviceService.addListener(deviceListener);
844 linkService.addListener(linkListener);
845 hostService.addListener(hostListener);
846 intentService.addListener(intentListener);
847 flowService.addListener(flowListener);
848 }
849
850 // Removes all internal listeners.
851 private synchronized void removeListeners() {
852 if (!listenersRemoved) {
853 listenersRemoved = true;
854 clusterService.removeListener(clusterListener);
855 mastershipService.removeListener(mastershipListener);
856 deviceService.removeListener(deviceListener);
857 linkService.removeListener(linkListener);
858 hostService.removeListener(hostListener);
859 intentService.removeListener(intentListener);
860 flowService.removeListener(flowListener);
861 }
862 }
863
864 // Cluster event listener.
Simon Hunt7092cc42016-04-06 18:40:17 -0700865 // TODO: Superceded by UiSharedTopologyModel.ModelEventListener
866 @Deprecated
Thomas Vachuska329af532015-03-10 02:08:33 -0700867 private class InternalClusterListener implements ClusterEventListener {
868 @Override
869 public void event(ClusterEvent event) {
Thomas Vachuskac7f79962015-05-28 09:37:34 -0700870 msgSender.execute(() -> sendMessage(instanceMessage(event, null)));
Thomas Vachuska329af532015-03-10 02:08:33 -0700871 }
872 }
873
874 // Mastership change listener
Simon Hunt7092cc42016-04-06 18:40:17 -0700875 // TODO: Superceded by UiSharedTopologyModel.ModelEventListener
876 @Deprecated
Thomas Vachuska329af532015-03-10 02:08:33 -0700877 private class InternalMastershipListener implements MastershipListener {
878 @Override
879 public void event(MastershipEvent event) {
Thomas Vachuska52c98bd2015-05-27 20:54:02 -0700880 msgSender.execute(() -> {
Simon Huntb745ca62015-07-28 15:37:11 -0700881 sendAllInstances(UPDATE_INSTANCE);
Thomas Vachuska52c98bd2015-05-27 20:54:02 -0700882 Device device = deviceService.getDevice(event.subject());
883 if (device != null) {
884 sendMessage(deviceMessage(new DeviceEvent(DEVICE_UPDATED, device)));
885 }
886 });
Thomas Vachuska329af532015-03-10 02:08:33 -0700887 }
888 }
889
890 // Device event listener.
Simon Hunt7092cc42016-04-06 18:40:17 -0700891 // TODO: Superceded by UiSharedTopologyModel.ModelEventListener
892 @Deprecated
Thomas Vachuska329af532015-03-10 02:08:33 -0700893 private class InternalDeviceListener implements DeviceListener {
894 @Override
895 public void event(DeviceEvent event) {
Thomas Vachuskacb5016f2015-05-18 14:11:43 -0700896 if (event.type() != PORT_STATS_UPDATED) {
Thomas Vachuskac7f79962015-05-28 09:37:34 -0700897 msgSender.execute(() -> sendMessage(deviceMessage(event)));
Simon Hunta1f1c022016-03-03 15:54:57 -0800898 msgSender.execute(traffic::pokeIntent);
Thomas Vachuskacb5016f2015-05-18 14:11:43 -0700899 eventAccummulator.add(event);
900 }
Thomas Vachuska329af532015-03-10 02:08:33 -0700901 }
902 }
903
904 // Link event listener.
Simon Hunt7092cc42016-04-06 18:40:17 -0700905 // TODO: Superceded by UiSharedTopologyModel.ModelEventListener
906 @Deprecated
Thomas Vachuska329af532015-03-10 02:08:33 -0700907 private class InternalLinkListener implements LinkListener {
908 @Override
909 public void event(LinkEvent event) {
Simon Hunt5c1a9382016-06-01 19:35:35 -0700910 msgSender.execute(() -> sendMessage(composeLinkMessage(event)));
Simon Hunta1f1c022016-03-03 15:54:57 -0800911 msgSender.execute(traffic::pokeIntent);
Thomas Vachuska329af532015-03-10 02:08:33 -0700912 eventAccummulator.add(event);
913 }
914 }
915
916 // Host event listener.
Simon Hunt7092cc42016-04-06 18:40:17 -0700917 // TODO: Superceded by UiSharedTopologyModel.ModelEventListener
918 @Deprecated
Thomas Vachuska329af532015-03-10 02:08:33 -0700919 private class InternalHostListener implements HostListener {
920 @Override
921 public void event(HostEvent event) {
Thomas Vachuskac7f79962015-05-28 09:37:34 -0700922 msgSender.execute(() -> sendMessage(hostMessage(event)));
Simon Hunta1f1c022016-03-03 15:54:57 -0800923 msgSender.execute(traffic::pokeIntent);
Thomas Vachuska329af532015-03-10 02:08:33 -0700924 eventAccummulator.add(event);
925 }
926 }
927
928 // Intent event listener.
Simon Hunt7092cc42016-04-06 18:40:17 -0700929 // TODO: Superceded by UiSharedTopologyModel.ModelEventListener
930 @Deprecated
Thomas Vachuska329af532015-03-10 02:08:33 -0700931 private class InternalIntentListener implements IntentListener {
932 @Override
933 public void event(IntentEvent event) {
Simon Hunt4fc86852015-08-20 17:57:52 -0700934 msgSender.execute(traffic::pokeIntent);
Thomas Vachuska329af532015-03-10 02:08:33 -0700935 eventAccummulator.add(event);
936 }
937 }
938
939 // Intent event listener.
Simon Hunt7092cc42016-04-06 18:40:17 -0700940 // TODO: Superceded by UiSharedTopologyModel.ModelEventListener
941 @Deprecated
Thomas Vachuska329af532015-03-10 02:08:33 -0700942 private class InternalFlowListener implements FlowRuleListener {
943 @Override
944 public void event(FlowRuleEvent event) {
945 eventAccummulator.add(event);
946 }
947 }
948
Simon Huntd2747a02015-04-30 22:41:16 -0700949
Simon Hunta17fa672015-08-19 18:42:22 -0700950 // === SUMMARY MONITORING
Thomas Vachuska329af532015-03-10 02:08:33 -0700951
952 // Periodic update of the summary information
953 private class SummaryMonitor extends TimerTask {
954 @Override
955 public void run() {
956 try {
Simon Huntd2747a02015-04-30 22:41:16 -0700957 if (summaryRunning) {
Simon Hunt8a0429a2017-01-06 16:52:47 -0800958 msgSender.execute(() -> requestSummary());
Thomas Vachuska329af532015-03-10 02:08:33 -0700959 }
960 } catch (Exception e) {
961 log.warn("Unable to handle summary request due to {}", e.getMessage());
962 log.warn("Boom!", e);
963 }
964 }
965 }
966
967 // Accumulates events to drive methodic update of the summary pane.
968 private class InternalEventAccummulator extends AbstractAccumulator<Event> {
969 protected InternalEventAccummulator() {
970 super(new Timer("topo-summary"), MAX_EVENTS, MAX_BATCH_MS, MAX_IDLE_MS);
971 }
972
973 @Override
974 public void processItems(List<Event> items) {
Simon Hunta17fa672015-08-19 18:42:22 -0700975 // Start-of-Debugging -- Keep in until ONOS-2572 is fixed for reals
Simon Hunt8d22c4b2015-08-06 16:24:43 -0700976 long now = System.currentTimeMillis();
977 String me = this.toString();
978 String miniMe = me.replaceAll("^.*@", "me@");
979 log.debug("Time: {}; this: {}, processing items ({} events)",
Andrea Campanella732ea832017-02-06 09:25:59 -0800980 now, miniMe, items.size());
Simon Hunt8d22c4b2015-08-06 16:24:43 -0700981 // End-of-Debugging
982
Thomas Vachuska329af532015-03-10 02:08:33 -0700983 try {
Simon Huntd2747a02015-04-30 22:41:16 -0700984 if (summaryRunning) {
Simon Hunt8a0429a2017-01-06 16:52:47 -0800985 msgSender.execute(() -> requestSummary());
Thomas Vachuska329af532015-03-10 02:08:33 -0700986 }
987 } catch (Exception e) {
988 log.warn("Unable to handle summary request due to {}", e.getMessage());
989 log.debug("Boom!", e);
990 }
991 }
992 }
993}