blob: bd344dba21d42a76a1a47fe2897b02e88c6c9ab5 [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;
Simon Hunt4a6b54b2015-10-27 22:08:25 -070056import org.onosproject.net.intent.Key;
Thomas Vachuska329af532015-03-10 02:08:33 -070057import org.onosproject.net.intent.MultiPointToSinglePointIntent;
Deepa Vaddireddy63340922017-01-19 08:15:31 +053058import org.onosproject.net.intent.IntentState;
59import org.onosproject.net.intent.IntentService;
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";
Thomas Vachuskaf0397b52015-05-29 13:50:17 -0700114 private static final String REQ_ALL_FLOW_TRAFFIC = "requestAllFlowTraffic";
115 private static final String REQ_ALL_PORT_TRAFFIC = "requestAllPortTraffic";
Simon Huntd2747a02015-04-30 22:41:16 -0700116 private static final String REQ_DEV_LINK_FLOWS = "requestDeviceLinkFlows";
117 private static final String CANCEL_TRAFFIC = "cancelTraffic";
118 private static final String REQ_SUMMARY = "requestSummary";
119 private static final String CANCEL_SUMMARY = "cancelSummary";
120 private static final String EQ_MASTERS = "equalizeMasters";
121 private static final String SPRITE_LIST_REQ = "spriteListRequest";
122 private static final String SPRITE_DATA_REQ = "spriteDataRequest";
123 private static final String TOPO_START = "topoStart";
Simon Hunte05cae42015-07-23 17:35:24 -0700124 private static final String TOPO_SELECT_OVERLAY = "topoSelectOverlay";
Simon Huntd2747a02015-04-30 22:41:16 -0700125 private static final String TOPO_STOP = "topoStop";
126
Simon Huntb745ca62015-07-28 15:37:11 -0700127 // outgoing event types
128 private static final String SHOW_SUMMARY = "showSummary";
129 private static final String SHOW_DETAILS = "showDetails";
130 private static final String SPRITE_LIST_RESPONSE = "spriteListResponse";
131 private static final String SPRITE_DATA_RESPONSE = "spriteDataResponse";
132 private static final String UPDATE_INSTANCE = "updateInstance";
Simon Hunt4a6b54b2015-10-27 22:08:25 -0700133 private static final String TOPO_START_DONE = "topoStartDone";
Simon Huntb745ca62015-07-28 15:37:11 -0700134
135 // fields
Simon Hunt5c1a9382016-06-01 19:35:35 -0700136 private static final String PAYLOAD = "payload";
137 private static final String EXTRA = "extra";
Simon Huntb745ca62015-07-28 15:37:11 -0700138 private static final String ID = "id";
Simon Hunt4a6b54b2015-10-27 22:08:25 -0700139 private static final String KEY = "key";
140 private static final String APP_ID = "appId";
141 private static final String APP_NAME = "appName";
Simon Huntb745ca62015-07-28 15:37:11 -0700142 private static final String DEVICE = "device";
143 private static final String HOST = "host";
144 private static final String CLASS = "class";
145 private static final String UNKNOWN = "unknown";
146 private static final String ONE = "one";
147 private static final String TWO = "two";
148 private static final String SRC = "src";
149 private static final String DST = "dst";
150 private static final String DATA = "data";
151 private static final String NAME = "name";
152 private static final String NAMES = "names";
153 private static final String ACTIVATE = "activate";
154 private static final String DEACTIVATE = "deactivate";
Viswanath KSP813a20d2016-09-13 04:25:41 +0530155 private static final String PURGE = "purge";
Simon Huntb745ca62015-07-28 15:37:11 -0700156
Simon Huntd2747a02015-04-30 22:41:16 -0700157
Simon Hunt4a6b54b2015-10-27 22:08:25 -0700158 private static final String MY_APP_ID = "org.onosproject.gui";
Thomas Vachuska329af532015-03-10 02:08:33 -0700159
Simon Hunta17fa672015-08-19 18:42:22 -0700160 private static final long TRAFFIC_PERIOD = 5000;
161 private static final long SUMMARY_PERIOD = 30000;
Thomas Vachuska329af532015-03-10 02:08:33 -0700162
163 private static final Comparator<? super ControllerNode> NODE_COMPARATOR =
Simon Hunt8a0429a2017-01-06 16:52:47 -0800164 Comparator.comparing(o -> o.id().toString());
Thomas Vachuska329af532015-03-10 02:08:33 -0700165
166
Thomas Vachuska52c98bd2015-05-27 20:54:02 -0700167 private final Timer timer = new Timer("onos-topology-view");
Thomas Vachuska329af532015-03-10 02:08:33 -0700168
169 private static final int MAX_EVENTS = 1000;
170 private static final int MAX_BATCH_MS = 5000;
171 private static final int MAX_IDLE_MS = 1000;
172
173 private ApplicationId appId;
174
175 private final ClusterEventListener clusterListener = new InternalClusterListener();
176 private final MastershipListener mastershipListener = new InternalMastershipListener();
177 private final DeviceListener deviceListener = new InternalDeviceListener();
178 private final LinkListener linkListener = new InternalLinkListener();
179 private final HostListener hostListener = new InternalHostListener();
180 private final IntentListener intentListener = new InternalIntentListener();
181 private final FlowRuleListener flowListener = new InternalFlowListener();
182
183 private final Accumulator<Event> eventAccummulator = new InternalEventAccummulator();
Thomas Vachuska52c98bd2015-05-27 20:54:02 -0700184 private final ExecutorService msgSender =
Yuta HIGUCHI1624df12016-07-21 16:54:33 -0700185 newSingleThreadExecutor(groupedThreads("onos/gui", "msg-sender", log));
Thomas Vachuska329af532015-03-10 02:08:33 -0700186
Simon Hunta17fa672015-08-19 18:42:22 -0700187 private TopoOverlayCache overlayCache;
Simon Hunt4fc86852015-08-20 17:57:52 -0700188 private TrafficMonitor traffic;
Thomas Vachuska329af532015-03-10 02:08:33 -0700189
Simon Huntd2747a02015-04-30 22:41:16 -0700190 private TimerTask summaryTask = null;
191 private boolean summaryRunning = false;
Thomas Vachuska329af532015-03-10 02:08:33 -0700192
Simon Huntd5b96732016-07-08 13:22:27 -0700193 private volatile boolean listenersRemoved = false;
Thomas Vachuska329af532015-03-10 02:08:33 -0700194
Thomas Vachuska329af532015-03-10 02:08:33 -0700195
196 @Override
197 public void init(UiConnection connection, ServiceDirectory directory) {
198 super.init(connection, directory);
Simon Hunt4a6b54b2015-10-27 22:08:25 -0700199 appId = directory.get(CoreService.class).registerApplication(MY_APP_ID);
Simon Hunt4fc86852015-08-20 17:57:52 -0700200 traffic = new TrafficMonitor(TRAFFIC_PERIOD, servicesBundle, this);
Thomas Vachuska329af532015-03-10 02:08:33 -0700201 }
202
203 @Override
204 public void destroy() {
205 cancelAllRequests();
Thomas Vachuska2bb48632015-04-28 14:40:42 -0700206 removeListeners();
Thomas Vachuska329af532015-03-10 02:08:33 -0700207 super.destroy();
208 }
209
Thomas Vachuska329af532015-03-10 02:08:33 -0700210 @Override
Simon Huntda580882015-05-12 20:58:18 -0700211 protected Collection<RequestHandler> createRequestHandlers() {
Simon Huntd2747a02015-04-30 22:41:16 -0700212 return ImmutableSet.of(
213 new TopoStart(),
Simon Hunte05cae42015-07-23 17:35:24 -0700214 new TopoSelectOverlay(),
Simon Huntd2747a02015-04-30 22:41:16 -0700215 new TopoStop(),
216 new ReqSummary(),
217 new CancelSummary(),
218 new SpriteListReq(),
219 new SpriteDataReq(),
220 new RequestDetails(),
221 new UpdateMeta(),
222 new EqMasters(),
Thomas Vachuska329af532015-03-10 02:08:33 -0700223
Simon Huntd2747a02015-04-30 22:41:16 -0700224 // TODO: migrate traffic related to separate app
225 new AddHostIntent(),
226 new AddMultiSourceIntent(),
Viswanath KSP0f297702016-08-13 18:02:43 +0530227 new RemoveIntent(),
Viswanath KSP14aee092016-10-02 01:47:40 +0530228 new ResubmitIntent(),
Deepa Vaddireddy63340922017-01-19 08:15:31 +0530229 new RemoveIntents(),
Simon Hunta17fa672015-08-19 18:42:22 -0700230
231 new ReqAllFlowTraffic(),
232 new ReqAllPortTraffic(),
233 new ReqDevLinkFlows(),
Simon Huntd2747a02015-04-30 22:41:16 -0700234 new ReqRelatedIntents(),
235 new ReqNextIntent(),
236 new ReqPrevIntent(),
237 new ReqSelectedIntentTraffic(),
Simon Hunt4a6b54b2015-10-27 22:08:25 -0700238 new SelIntent(),
Simon Hunta17fa672015-08-19 18:42:22 -0700239
Simon Huntd2747a02015-04-30 22:41:16 -0700240 new CancelTraffic()
241 );
242 }
Thomas Vachuska329af532015-03-10 02:08:33 -0700243
Simon Hunte05cae42015-07-23 17:35:24 -0700244 /**
245 * Injects the topology overlay cache.
246 *
247 * @param overlayCache injected cache
248 */
249 void setOverlayCache(TopoOverlayCache overlayCache) {
250 this.overlayCache = overlayCache;
251 }
252
Simon Huntd2747a02015-04-30 22:41:16 -0700253 // ==================================================================
Thomas Vachuska329af532015-03-10 02:08:33 -0700254
Simon Huntd2747a02015-04-30 22:41:16 -0700255 private final class TopoStart extends RequestHandler {
256 private TopoStart() {
257 super(TOPO_START);
258 }
Thomas Vachuska329af532015-03-10 02:08:33 -0700259
Simon Huntd2747a02015-04-30 22:41:16 -0700260 @Override
Simon Hunt8a0429a2017-01-06 16:52:47 -0800261 public void process(ObjectNode payload) {
Simon Huntd2747a02015-04-30 22:41:16 -0700262 addListeners();
263 sendAllInstances(null);
264 sendAllDevices();
265 sendAllLinks();
266 sendAllHosts();
Simon Hunt4a6b54b2015-10-27 22:08:25 -0700267 sendTopoStartDone();
Thomas Vachuska329af532015-03-10 02:08:33 -0700268 }
269 }
270
Simon Hunte05cae42015-07-23 17:35:24 -0700271 private final class TopoSelectOverlay extends RequestHandler {
272 private TopoSelectOverlay() {
273 super(TOPO_SELECT_OVERLAY);
274 }
275
276 @Override
Simon Hunt8a0429a2017-01-06 16:52:47 -0800277 public void process(ObjectNode payload) {
Simon Huntb745ca62015-07-28 15:37:11 -0700278 String deact = string(payload, DEACTIVATE);
279 String act = string(payload, ACTIVATE);
Simon Hunte05cae42015-07-23 17:35:24 -0700280 overlayCache.switchOverlay(deact, act);
281 }
282 }
283
Simon Huntd2747a02015-04-30 22:41:16 -0700284 private final class TopoStop extends RequestHandler {
285 private TopoStop() {
286 super(TOPO_STOP);
287 }
288
289 @Override
Simon Hunt8a0429a2017-01-06 16:52:47 -0800290 public void process(ObjectNode payload) {
Simon Hunt1ad59272015-11-10 15:23:21 -0800291 removeListeners();
Simon Huntd2747a02015-04-30 22:41:16 -0700292 stopSummaryMonitoring();
Simon Hunt4fc86852015-08-20 17:57:52 -0700293 traffic.stopMonitoring();
Simon Huntd2747a02015-04-30 22:41:16 -0700294 }
295 }
296
297 private final class ReqSummary extends RequestHandler {
298 private ReqSummary() {
299 super(REQ_SUMMARY);
300 }
301
302 @Override
Simon Hunt8a0429a2017-01-06 16:52:47 -0800303 public void process(ObjectNode payload) {
304 requestSummary();
Simon Huntd2747a02015-04-30 22:41:16 -0700305 startSummaryMonitoring();
306 }
307 }
308
309 private final class CancelSummary extends RequestHandler {
310 private CancelSummary() {
311 super(CANCEL_SUMMARY);
312 }
313
314 @Override
Simon Hunt8a0429a2017-01-06 16:52:47 -0800315 public void process(ObjectNode payload) {
Simon Huntd2747a02015-04-30 22:41:16 -0700316 stopSummaryMonitoring();
317 }
318 }
319
320 private final class SpriteListReq extends RequestHandler {
321 private SpriteListReq() {
322 super(SPRITE_LIST_REQ);
323 }
324
325 @Override
Simon Hunt8a0429a2017-01-06 16:52:47 -0800326 public void process(ObjectNode payload) {
Simon Huntda580882015-05-12 20:58:18 -0700327 ObjectNode root = objectNode();
328 ArrayNode names = arrayNode();
Simon Huntd2747a02015-04-30 22:41:16 -0700329 get(SpriteService.class).getNames().forEach(names::add);
Simon Huntb745ca62015-07-28 15:37:11 -0700330 root.set(NAMES, names);
Simon Hunt8a0429a2017-01-06 16:52:47 -0800331 sendMessage(SPRITE_LIST_RESPONSE, root);
Simon Huntd2747a02015-04-30 22:41:16 -0700332 }
333 }
334
335 private final class SpriteDataReq extends RequestHandler {
336 private SpriteDataReq() {
337 super(SPRITE_DATA_REQ);
338 }
339
340 @Override
Simon Hunt8a0429a2017-01-06 16:52:47 -0800341 public void process(ObjectNode payload) {
Simon Huntb745ca62015-07-28 15:37:11 -0700342 String name = string(payload, NAME);
Simon Huntda580882015-05-12 20:58:18 -0700343 ObjectNode root = objectNode();
Simon Huntb745ca62015-07-28 15:37:11 -0700344 root.set(DATA, get(SpriteService.class).get(name));
Simon Hunt8a0429a2017-01-06 16:52:47 -0800345 sendMessage(SPRITE_DATA_RESPONSE, root);
Simon Huntd2747a02015-04-30 22:41:16 -0700346 }
347 }
348
349 private final class RequestDetails extends RequestHandler {
350 private RequestDetails() {
351 super(REQ_DETAILS);
352 }
353
354 @Override
Simon Hunt8a0429a2017-01-06 16:52:47 -0800355 public void process(ObjectNode payload) {
Simon Huntb745ca62015-07-28 15:37:11 -0700356 String type = string(payload, CLASS, UNKNOWN);
357 String id = string(payload, ID);
358 PropertyPanel pp = null;
Simon Huntd2747a02015-04-30 22:41:16 -0700359
Simon Huntb745ca62015-07-28 15:37:11 -0700360 if (type.equals(DEVICE)) {
Simon Huntde99e0b2015-10-23 18:54:06 -0700361 DeviceId did = deviceId(id);
Simon Hunt8a0429a2017-01-06 16:52:47 -0800362 pp = deviceDetails(did);
Simon Huntde99e0b2015-10-23 18:54:06 -0700363 overlayCache.currentOverlay().modifyDeviceDetails(pp, did);
Simon Huntb745ca62015-07-28 15:37:11 -0700364 } else if (type.equals(HOST)) {
Simon Huntde99e0b2015-10-23 18:54:06 -0700365 HostId hid = hostId(id);
Simon Hunt8a0429a2017-01-06 16:52:47 -0800366 pp = hostDetails(hid);
Simon Huntde99e0b2015-10-23 18:54:06 -0700367 overlayCache.currentOverlay().modifyHostDetails(pp, hid);
Simon Huntd2747a02015-04-30 22:41:16 -0700368 }
Simon Huntb745ca62015-07-28 15:37:11 -0700369
Simon Hunt8a0429a2017-01-06 16:52:47 -0800370 sendMessage(envelope(SHOW_DETAILS, json(pp)));
Simon Huntd2747a02015-04-30 22:41:16 -0700371 }
372 }
373
374 private final class UpdateMeta extends RequestHandler {
375 private UpdateMeta() {
376 super(UPDATE_META);
377 }
378
379 @Override
Simon Hunt8a0429a2017-01-06 16:52:47 -0800380 public void process(ObjectNode payload) {
Simon Huntd2747a02015-04-30 22:41:16 -0700381 updateMetaUi(payload);
382 }
383 }
384
385 private final class EqMasters extends RequestHandler {
386 private EqMasters() {
387 super(EQ_MASTERS);
388 }
389
390 @Override
Simon Hunt8a0429a2017-01-06 16:52:47 -0800391 public void process(ObjectNode payload) {
Simon Huntd2747a02015-04-30 22:41:16 -0700392 directory.get(MastershipAdminService.class).balanceRoles();
393 }
394 }
395
Simon Hunta17fa672015-08-19 18:42:22 -0700396
397 // ========= -----------------------------------------------------------------
398
Simon Huntd2747a02015-04-30 22:41:16 -0700399 // === TODO: move traffic related classes to traffic app
400
401 private final class AddHostIntent extends RequestHandler {
402 private AddHostIntent() {
403 super(ADD_HOST_INTENT);
404 }
405
406 @Override
Simon Hunt8a0429a2017-01-06 16:52:47 -0800407 public void process(ObjectNode payload) {
Simon Huntd2747a02015-04-30 22:41:16 -0700408 // TODO: add protection against device ids and non-existent hosts.
Simon Huntb745ca62015-07-28 15:37:11 -0700409 HostId one = hostId(string(payload, ONE));
410 HostId two = hostId(string(payload, TWO));
Simon Huntd2747a02015-04-30 22:41:16 -0700411
412 HostToHostIntent intent = HostToHostIntent.builder()
Thomas Vachuskacb5016f2015-05-18 14:11:43 -0700413 .appId(appId)
414 .one(one)
415 .two(two)
416 .build();
Simon Huntd2747a02015-04-30 22:41:16 -0700417
418 intentService.submit(intent);
Simon Huntd2862c32015-08-24 17:41:51 -0700419 if (overlayCache.isActive(TrafficOverlay.TRAFFIC_ID)) {
420 traffic.monitor(intent);
421 }
Simon Huntd2747a02015-04-30 22:41:16 -0700422 }
423 }
424
Viswanath KSP0f297702016-08-13 18:02:43 +0530425 private Intent findIntentByPayload(ObjectNode payload) {
426 int appId = Integer.parseInt(string(payload, APP_ID));
427 String appName = string(payload, APP_NAME);
428 ApplicationId applicId = new DefaultApplicationId(appId, appName);
429 long intentKey = Long.decode(string(payload, KEY));
430
431 Key key = Key.of(intentKey, applicId);
432 log.debug("Attempting to select intent by key={}", key);
433
Viswanath KSP813a20d2016-09-13 04:25:41 +0530434 return intentService.getIntent(key);
Viswanath KSP0f297702016-08-13 18:02:43 +0530435 }
436
437 private final class RemoveIntent extends RequestHandler {
438 private RemoveIntent() {
439 super(REMOVE_INTENT);
440 }
441
Viswanath KSP813a20d2016-09-13 04:25:41 +0530442 private boolean isIntentToBePurged(ObjectNode payload) {
443 return bool(payload, PURGE);
444 }
445
Viswanath KSP0f297702016-08-13 18:02:43 +0530446 @Override
Simon Hunt8a0429a2017-01-06 16:52:47 -0800447 public void process(ObjectNode payload) {
Viswanath KSP0f297702016-08-13 18:02:43 +0530448 Intent intent = findIntentByPayload(payload);
449 if (intent == null) {
450 log.warn("Unable to find intent from payload {}", payload);
451 } else {
Viswanath KSP813a20d2016-09-13 04:25:41 +0530452 log.debug("Withdrawing / Purging intent {}", intent.key());
453 if (isIntentToBePurged(payload)) {
454 intentService.purge(intent);
455 } else {
456 intentService.withdraw(intent);
457 }
Viswanath KSP0f297702016-08-13 18:02:43 +0530458 }
459 }
460 }
461
Viswanath KSP14aee092016-10-02 01:47:40 +0530462 private final class ResubmitIntent extends RequestHandler {
463 private ResubmitIntent() {
464 super(RESUBMIT_INTENT);
465 }
466
467 @Override
Simon Hunt8a0429a2017-01-06 16:52:47 -0800468 public void process(ObjectNode payload) {
Viswanath KSP14aee092016-10-02 01:47:40 +0530469 Intent intent = findIntentByPayload(payload);
470 if (intent == null) {
471 log.warn("Unable to find intent from payload {}", payload);
472 } else {
473 log.debug("Resubmitting intent {}", intent.key());
474 intentService.submit(intent);
475 }
476 }
477 }
478
Simon Huntd2747a02015-04-30 22:41:16 -0700479 private final class AddMultiSourceIntent extends RequestHandler {
480 private AddMultiSourceIntent() {
481 super(ADD_MULTI_SRC_INTENT);
482 }
483
484 @Override
Simon Hunt8a0429a2017-01-06 16:52:47 -0800485 public void process(ObjectNode payload) {
Simon Huntd2747a02015-04-30 22:41:16 -0700486 // TODO: add protection against device ids and non-existent hosts.
Simon Huntb745ca62015-07-28 15:37:11 -0700487 Set<HostId> src = getHostIds((ArrayNode) payload.path(SRC));
488 HostId dst = hostId(string(payload, DST));
Simon Huntd2747a02015-04-30 22:41:16 -0700489 Host dstHost = hostService.getHost(dst);
490
491 Set<ConnectPoint> ingressPoints = getHostLocations(src);
492
493 // FIXME: clearly, this is not enough
494 TrafficSelector selector = DefaultTrafficSelector.builder()
495 .matchEthDst(dstHost.mac()).build();
496 TrafficTreatment treatment = DefaultTrafficTreatment.emptyTreatment();
497
498 MultiPointToSinglePointIntent intent =
499 MultiPointToSinglePointIntent.builder()
500 .appId(appId)
501 .selector(selector)
502 .treatment(treatment)
503 .ingressPoints(ingressPoints)
504 .egressPoint(dstHost.location())
505 .build();
506
507 intentService.submit(intent);
Simon Huntd2862c32015-08-24 17:41:51 -0700508 if (overlayCache.isActive(TrafficOverlay.TRAFFIC_ID)) {
509 traffic.monitor(intent);
510 }
Simon Huntd2747a02015-04-30 22:41:16 -0700511 }
512 }
513
Deepa Vaddireddy63340922017-01-19 08:15:31 +0530514 private final class RemoveIntents extends RequestHandler {
515 private RemoveIntents() {
516 super(REMOVE_INTENTS);
517 }
518
519
520 @Override
521 public void process(ObjectNode payload) {
522 IntentService intentService = get(IntentService.class);
523 for (Intent intent : intentService.getIntents()) {
524 if (intentService.getIntentState(intent.key()) == IntentState.WITHDRAWN) {
525 intentService.purge(intent);
526 }
527 }
528
529 }
530 }
531
Simon Hunta17fa672015-08-19 18:42:22 -0700532 // ========= -----------------------------------------------------------------
Simon Huntd2747a02015-04-30 22:41:16 -0700533
Thomas Vachuskaf0397b52015-05-29 13:50:17 -0700534 private final class ReqAllFlowTraffic extends RequestHandler {
535 private ReqAllFlowTraffic() {
536 super(REQ_ALL_FLOW_TRAFFIC);
Simon Huntd2747a02015-04-30 22:41:16 -0700537 }
538
539 @Override
Simon Hunt8a0429a2017-01-06 16:52:47 -0800540 public void process(ObjectNode payload) {
Simon Hunt4fc86852015-08-20 17:57:52 -0700541 traffic.monitor(Mode.ALL_FLOW_TRAFFIC);
Thomas Vachuskaf0397b52015-05-29 13:50:17 -0700542 }
543 }
544
545 private final class ReqAllPortTraffic extends RequestHandler {
546 private ReqAllPortTraffic() {
547 super(REQ_ALL_PORT_TRAFFIC);
548 }
549
550 @Override
Simon Hunt8a0429a2017-01-06 16:52:47 -0800551 public void process(ObjectNode payload) {
Simon Hunt4fc86852015-08-20 17:57:52 -0700552 traffic.monitor(Mode.ALL_PORT_TRAFFIC);
Simon Huntd2747a02015-04-30 22:41:16 -0700553 }
554 }
555
556 private final class ReqDevLinkFlows extends RequestHandler {
557 private ReqDevLinkFlows() {
558 super(REQ_DEV_LINK_FLOWS);
559 }
560
561 @Override
Simon Hunt8a0429a2017-01-06 16:52:47 -0800562 public void process(ObjectNode payload) {
Simon Hunta17fa672015-08-19 18:42:22 -0700563 NodeSelection nodeSelection =
Prince Pereira46c82d42016-09-19 13:30:50 +0530564 new NodeSelection(payload, deviceService, hostService, linkService);
Simon Hunt4fc86852015-08-20 17:57:52 -0700565 traffic.monitor(Mode.DEV_LINK_FLOWS, nodeSelection);
Simon Hunta17fa672015-08-19 18:42:22 -0700566 }
567 }
568
569 private final class ReqRelatedIntents extends RequestHandler {
570 private ReqRelatedIntents() {
571 super(REQ_RELATED_INTENTS);
572 }
573
574 @Override
Simon Hunt8a0429a2017-01-06 16:52:47 -0800575 public void process(ObjectNode payload) {
Simon Hunta17fa672015-08-19 18:42:22 -0700576 NodeSelection nodeSelection =
Prince Pereira46c82d42016-09-19 13:30:50 +0530577 new NodeSelection(payload, deviceService, hostService, linkService);
Simon Hunt4fc86852015-08-20 17:57:52 -0700578 traffic.monitor(Mode.RELATED_INTENTS, nodeSelection);
Simon Hunta17fa672015-08-19 18:42:22 -0700579 }
580 }
581
582 private final class ReqNextIntent extends RequestHandler {
583 private ReqNextIntent() {
584 super(REQ_NEXT_INTENT);
585 }
586
587 @Override
Simon Hunt8a0429a2017-01-06 16:52:47 -0800588 public void process(ObjectNode payload) {
Simon Hunt4fc86852015-08-20 17:57:52 -0700589 traffic.selectNextIntent();
Simon Hunta17fa672015-08-19 18:42:22 -0700590 }
591 }
592
593 private final class ReqPrevIntent extends RequestHandler {
594 private ReqPrevIntent() {
595 super(REQ_PREV_INTENT);
596 }
597
598 @Override
Simon Hunt8a0429a2017-01-06 16:52:47 -0800599 public void process(ObjectNode payload) {
Simon Hunt4fc86852015-08-20 17:57:52 -0700600 traffic.selectPreviousIntent();
Simon Hunta17fa672015-08-19 18:42:22 -0700601 }
602 }
603
604 private final class ReqSelectedIntentTraffic extends RequestHandler {
605 private ReqSelectedIntentTraffic() {
606 super(REQ_SEL_INTENT_TRAFFIC);
607 }
608
609 @Override
Simon Hunt8a0429a2017-01-06 16:52:47 -0800610 public void process(ObjectNode payload) {
Simon Hunt4fc86852015-08-20 17:57:52 -0700611 traffic.monitor(Mode.SELECTED_INTENT);
Simon Huntd2747a02015-04-30 22:41:16 -0700612 }
613 }
614
Simon Hunt4a6b54b2015-10-27 22:08:25 -0700615 private final class SelIntent extends RequestHandler {
616 private SelIntent() {
617 super(SEL_INTENT);
618 }
619
620 @Override
Simon Hunt8a0429a2017-01-06 16:52:47 -0800621 public void process(ObjectNode payload) {
Viswanath KSP0f297702016-08-13 18:02:43 +0530622 Intent intent = findIntentByPayload(payload);
Simon Hunt4a6b54b2015-10-27 22:08:25 -0700623 if (intent == null) {
Viswanath KSP0f297702016-08-13 18:02:43 +0530624 log.warn("Unable to find intent from payload {}", payload);
Simon Hunt4a6b54b2015-10-27 22:08:25 -0700625 } else {
Viswanath KSP0f297702016-08-13 18:02:43 +0530626 log.debug("starting to monitor intent {}", intent.key());
Simon Hunt4a6b54b2015-10-27 22:08:25 -0700627 traffic.monitor(intent);
628 }
629 }
630 }
631
Simon Huntd2747a02015-04-30 22:41:16 -0700632 private final class CancelTraffic extends RequestHandler {
633 private CancelTraffic() {
634 super(CANCEL_TRAFFIC);
635 }
636
637 @Override
Simon Hunt8a0429a2017-01-06 16:52:47 -0800638 public void process(ObjectNode payload) {
Simon Hunt4fc86852015-08-20 17:57:52 -0700639 traffic.stopMonitoring();
Simon Huntd2747a02015-04-30 22:41:16 -0700640 }
641 }
642
643 //=======================================================================
644
Simon Hunta17fa672015-08-19 18:42:22 -0700645 // Converts highlights to JSON format and sends the message to the client
Simon Hunt8a0429a2017-01-06 16:52:47 -0800646 void sendHighlights(Highlights highlights) {
Simon Hunt52560662015-08-27 22:46:44 -0700647 sendMessage(highlightsMessage(highlights));
Thomas Vachuska329af532015-03-10 02:08:33 -0700648 }
649
Simon Huntd2747a02015-04-30 22:41:16 -0700650 // Subscribes for summary messages.
Simon Hunt8a0429a2017-01-06 16:52:47 -0800651 private synchronized void requestSummary() {
652 PropertyPanel pp = summmaryMessage();
Simon Hunt0af1ec32015-07-24 12:17:55 -0700653 overlayCache.currentOverlay().modifySummary(pp);
Simon Hunt8a0429a2017-01-06 16:52:47 -0800654 sendMessage(envelope(SHOW_SUMMARY, json(pp)));
Thomas Vachuska329af532015-03-10 02:08:33 -0700655 }
656
Simon Huntd2747a02015-04-30 22:41:16 -0700657
Thomas Vachuska329af532015-03-10 02:08:33 -0700658 private void cancelAllRequests() {
659 stopSummaryMonitoring();
Simon Hunt4fc86852015-08-20 17:57:52 -0700660 traffic.stopMonitoring();
Thomas Vachuska329af532015-03-10 02:08:33 -0700661 }
662
663 // Sends all controller nodes to the client as node-added messages.
664 private void sendAllInstances(String messageType) {
665 List<ControllerNode> nodes = new ArrayList<>(clusterService.getNodes());
Simon Hunt8a0429a2017-01-06 16:52:47 -0800666 nodes.sort(NODE_COMPARATOR);
Thomas Vachuska329af532015-03-10 02:08:33 -0700667 for (ControllerNode node : nodes) {
668 sendMessage(instanceMessage(new ClusterEvent(INSTANCE_ADDED, node),
Simon Hunt5c1a9382016-06-01 19:35:35 -0700669 messageType));
Thomas Vachuska329af532015-03-10 02:08:33 -0700670 }
671 }
672
673 // Sends all devices to the client as device-added messages.
674 private void sendAllDevices() {
675 // Send optical first, others later for layered rendering
676 for (Device device : deviceService.getDevices()) {
Rimon Ashkenazy8ebfff02016-02-01 11:56:36 +0200677 if ((device.type() == Device.Type.ROADM) ||
Simon Hunt5c1a9382016-06-01 19:35:35 -0700678 (device.type() == Device.Type.OTN)) {
Thomas Vachuska329af532015-03-10 02:08:33 -0700679 sendMessage(deviceMessage(new DeviceEvent(DEVICE_ADDED, device)));
680 }
681 }
682 for (Device device : deviceService.getDevices()) {
Rimon Ashkenazy8ebfff02016-02-01 11:56:36 +0200683 if ((device.type() != Device.Type.ROADM) &&
Simon Hunt5c1a9382016-06-01 19:35:35 -0700684 (device.type() != Device.Type.OTN)) {
Thomas Vachuska329af532015-03-10 02:08:33 -0700685 sendMessage(deviceMessage(new DeviceEvent(DEVICE_ADDED, device)));
686 }
687 }
688 }
689
690 // Sends all links to the client as link-added messages.
691 private void sendAllLinks() {
692 // Send optical first, others later for layered rendering
693 for (Link link : linkService.getLinks()) {
694 if (link.type() == Link.Type.OPTICAL) {
Simon Hunt5c1a9382016-06-01 19:35:35 -0700695 sendMessage(composeLinkMessage(new LinkEvent(LINK_ADDED, link)));
Thomas Vachuska329af532015-03-10 02:08:33 -0700696 }
697 }
698 for (Link link : linkService.getLinks()) {
699 if (link.type() != Link.Type.OPTICAL) {
Simon Hunt5c1a9382016-06-01 19:35:35 -0700700 sendMessage(composeLinkMessage(new LinkEvent(LINK_ADDED, link)));
Thomas Vachuska329af532015-03-10 02:08:33 -0700701 }
702 }
703 }
704
Simon Hunt5c1a9382016-06-01 19:35:35 -0700705 // Temporary mechanism to support topology overlays adding their own
706 // properties to the link events.
707 private ObjectNode composeLinkMessage(LinkEvent event) {
708 // start with base message
709 ObjectNode msg = linkMessage(event);
710 Map<String, String> additional =
711 overlayCache.currentOverlay().additionalLinkData(event);
712
713 if (additional != null) {
714 // attach additional key-value pairs as extra data structure
715 ObjectNode payload = (ObjectNode) msg.get(PAYLOAD);
716 payload.set(EXTRA, createExtra(additional));
717 }
718 return msg;
719 }
720
721 private ObjectNode createExtra(Map<String, String> additional) {
722 ObjectNode extra = objectNode();
723 for (Map.Entry<String, String> entry : additional.entrySet()) {
724 extra.put(entry.getKey(), entry.getValue());
725 }
726 return extra;
727 }
728
Thomas Vachuska329af532015-03-10 02:08:33 -0700729 // Sends all hosts to the client as host-added messages.
730 private void sendAllHosts() {
731 for (Host host : hostService.getHosts()) {
732 sendMessage(hostMessage(new HostEvent(HOST_ADDED, host)));
733 }
734 }
735
Thomas Vachuska329af532015-03-10 02:08:33 -0700736 private Set<ConnectPoint> getHostLocations(Set<HostId> hostIds) {
737 Set<ConnectPoint> points = new HashSet<>();
738 for (HostId hostId : hostIds) {
739 points.add(getHostLocation(hostId));
740 }
741 return points;
742 }
743
744 private HostLocation getHostLocation(HostId hostId) {
745 return hostService.getHost(hostId).location();
746 }
747
748 // Produces a list of host ids from the specified JSON array.
749 private Set<HostId> getHostIds(ArrayNode ids) {
750 Set<HostId> hostIds = new HashSet<>();
751 for (JsonNode id : ids) {
752 hostIds.add(hostId(id.asText()));
753 }
754 return hostIds;
755 }
756
Simon Hunt4a6b54b2015-10-27 22:08:25 -0700757 private void sendTopoStartDone() {
758 sendMessage(JsonUtils.envelope(TOPO_START_DONE, objectNode()));
759 }
Thomas Vachuska329af532015-03-10 02:08:33 -0700760
Simon Huntd2747a02015-04-30 22:41:16 -0700761 private synchronized void startSummaryMonitoring() {
Thomas Vachuska329af532015-03-10 02:08:33 -0700762 stopSummaryMonitoring();
Thomas Vachuska329af532015-03-10 02:08:33 -0700763 summaryTask = new SummaryMonitor();
Simon Hunta17fa672015-08-19 18:42:22 -0700764 timer.schedule(summaryTask, SUMMARY_PERIOD, SUMMARY_PERIOD);
Simon Huntd2747a02015-04-30 22:41:16 -0700765 summaryRunning = true;
Thomas Vachuska329af532015-03-10 02:08:33 -0700766 }
767
768 private synchronized void stopSummaryMonitoring() {
Simon Huntd2747a02015-04-30 22:41:16 -0700769 if (summaryTask != null) {
Thomas Vachuska329af532015-03-10 02:08:33 -0700770 summaryTask.cancel();
771 summaryTask = null;
Thomas Vachuska329af532015-03-10 02:08:33 -0700772 }
Simon Huntd2747a02015-04-30 22:41:16 -0700773 summaryRunning = false;
Thomas Vachuska9ed335b2015-04-14 12:07:47 -0700774 }
775
Thomas Vachuska329af532015-03-10 02:08:33 -0700776
777 // Adds all internal listeners.
Thomas Vachuska35fa3d42015-04-30 10:11:47 -0700778 private synchronized void addListeners() {
Thomas Vachuskae586b792015-03-26 13:59:38 -0700779 listenersRemoved = false;
Thomas Vachuska329af532015-03-10 02:08:33 -0700780 clusterService.addListener(clusterListener);
781 mastershipService.addListener(mastershipListener);
782 deviceService.addListener(deviceListener);
783 linkService.addListener(linkListener);
784 hostService.addListener(hostListener);
785 intentService.addListener(intentListener);
786 flowService.addListener(flowListener);
787 }
788
789 // Removes all internal listeners.
790 private synchronized void removeListeners() {
791 if (!listenersRemoved) {
792 listenersRemoved = true;
793 clusterService.removeListener(clusterListener);
794 mastershipService.removeListener(mastershipListener);
795 deviceService.removeListener(deviceListener);
796 linkService.removeListener(linkListener);
797 hostService.removeListener(hostListener);
798 intentService.removeListener(intentListener);
799 flowService.removeListener(flowListener);
800 }
801 }
802
803 // Cluster event listener.
Simon Hunt7092cc42016-04-06 18:40:17 -0700804 // TODO: Superceded by UiSharedTopologyModel.ModelEventListener
805 @Deprecated
Thomas Vachuska329af532015-03-10 02:08:33 -0700806 private class InternalClusterListener implements ClusterEventListener {
807 @Override
808 public void event(ClusterEvent event) {
Thomas Vachuskac7f79962015-05-28 09:37:34 -0700809 msgSender.execute(() -> sendMessage(instanceMessage(event, null)));
Thomas Vachuska329af532015-03-10 02:08:33 -0700810 }
811 }
812
813 // Mastership change listener
Simon Hunt7092cc42016-04-06 18:40:17 -0700814 // TODO: Superceded by UiSharedTopologyModel.ModelEventListener
815 @Deprecated
Thomas Vachuska329af532015-03-10 02:08:33 -0700816 private class InternalMastershipListener implements MastershipListener {
817 @Override
818 public void event(MastershipEvent event) {
Thomas Vachuska52c98bd2015-05-27 20:54:02 -0700819 msgSender.execute(() -> {
Simon Huntb745ca62015-07-28 15:37:11 -0700820 sendAllInstances(UPDATE_INSTANCE);
Thomas Vachuska52c98bd2015-05-27 20:54:02 -0700821 Device device = deviceService.getDevice(event.subject());
822 if (device != null) {
823 sendMessage(deviceMessage(new DeviceEvent(DEVICE_UPDATED, device)));
824 }
825 });
Thomas Vachuska329af532015-03-10 02:08:33 -0700826 }
827 }
828
829 // Device event listener.
Simon Hunt7092cc42016-04-06 18:40:17 -0700830 // TODO: Superceded by UiSharedTopologyModel.ModelEventListener
831 @Deprecated
Thomas Vachuska329af532015-03-10 02:08:33 -0700832 private class InternalDeviceListener implements DeviceListener {
833 @Override
834 public void event(DeviceEvent event) {
Thomas Vachuskacb5016f2015-05-18 14:11:43 -0700835 if (event.type() != PORT_STATS_UPDATED) {
Thomas Vachuskac7f79962015-05-28 09:37:34 -0700836 msgSender.execute(() -> sendMessage(deviceMessage(event)));
Simon Hunta1f1c022016-03-03 15:54:57 -0800837 msgSender.execute(traffic::pokeIntent);
Thomas Vachuskacb5016f2015-05-18 14:11:43 -0700838 eventAccummulator.add(event);
839 }
Thomas Vachuska329af532015-03-10 02:08:33 -0700840 }
841 }
842
843 // Link event listener.
Simon Hunt7092cc42016-04-06 18:40:17 -0700844 // TODO: Superceded by UiSharedTopologyModel.ModelEventListener
845 @Deprecated
Thomas Vachuska329af532015-03-10 02:08:33 -0700846 private class InternalLinkListener implements LinkListener {
847 @Override
848 public void event(LinkEvent event) {
Simon Hunt5c1a9382016-06-01 19:35:35 -0700849 msgSender.execute(() -> sendMessage(composeLinkMessage(event)));
Simon Hunta1f1c022016-03-03 15:54:57 -0800850 msgSender.execute(traffic::pokeIntent);
Thomas Vachuska329af532015-03-10 02:08:33 -0700851 eventAccummulator.add(event);
852 }
853 }
854
855 // Host event listener.
Simon Hunt7092cc42016-04-06 18:40:17 -0700856 // TODO: Superceded by UiSharedTopologyModel.ModelEventListener
857 @Deprecated
Thomas Vachuska329af532015-03-10 02:08:33 -0700858 private class InternalHostListener implements HostListener {
859 @Override
860 public void event(HostEvent event) {
Thomas Vachuskac7f79962015-05-28 09:37:34 -0700861 msgSender.execute(() -> sendMessage(hostMessage(event)));
Simon Hunta1f1c022016-03-03 15:54:57 -0800862 msgSender.execute(traffic::pokeIntent);
Thomas Vachuska329af532015-03-10 02:08:33 -0700863 eventAccummulator.add(event);
864 }
865 }
866
867 // Intent event listener.
Simon Hunt7092cc42016-04-06 18:40:17 -0700868 // TODO: Superceded by UiSharedTopologyModel.ModelEventListener
869 @Deprecated
Thomas Vachuska329af532015-03-10 02:08:33 -0700870 private class InternalIntentListener implements IntentListener {
871 @Override
872 public void event(IntentEvent event) {
Simon Hunt4fc86852015-08-20 17:57:52 -0700873 msgSender.execute(traffic::pokeIntent);
Thomas Vachuska329af532015-03-10 02:08:33 -0700874 eventAccummulator.add(event);
875 }
876 }
877
878 // Intent event listener.
Simon Hunt7092cc42016-04-06 18:40:17 -0700879 // TODO: Superceded by UiSharedTopologyModel.ModelEventListener
880 @Deprecated
Thomas Vachuska329af532015-03-10 02:08:33 -0700881 private class InternalFlowListener implements FlowRuleListener {
882 @Override
883 public void event(FlowRuleEvent event) {
884 eventAccummulator.add(event);
885 }
886 }
887
Simon Huntd2747a02015-04-30 22:41:16 -0700888
Simon Hunta17fa672015-08-19 18:42:22 -0700889 // === SUMMARY MONITORING
Thomas Vachuska329af532015-03-10 02:08:33 -0700890
891 // Periodic update of the summary information
892 private class SummaryMonitor extends TimerTask {
893 @Override
894 public void run() {
895 try {
Simon Huntd2747a02015-04-30 22:41:16 -0700896 if (summaryRunning) {
Simon Hunt8a0429a2017-01-06 16:52:47 -0800897 msgSender.execute(() -> requestSummary());
Thomas Vachuska329af532015-03-10 02:08:33 -0700898 }
899 } catch (Exception e) {
900 log.warn("Unable to handle summary request due to {}", e.getMessage());
901 log.warn("Boom!", e);
902 }
903 }
904 }
905
906 // Accumulates events to drive methodic update of the summary pane.
907 private class InternalEventAccummulator extends AbstractAccumulator<Event> {
908 protected InternalEventAccummulator() {
909 super(new Timer("topo-summary"), MAX_EVENTS, MAX_BATCH_MS, MAX_IDLE_MS);
910 }
911
912 @Override
913 public void processItems(List<Event> items) {
Simon Hunta17fa672015-08-19 18:42:22 -0700914 // Start-of-Debugging -- Keep in until ONOS-2572 is fixed for reals
Simon Hunt8d22c4b2015-08-06 16:24:43 -0700915 long now = System.currentTimeMillis();
916 String me = this.toString();
917 String miniMe = me.replaceAll("^.*@", "me@");
918 log.debug("Time: {}; this: {}, processing items ({} events)",
Simon Hunt5c1a9382016-06-01 19:35:35 -0700919 now, miniMe, items.size());
Simon Hunt8d22c4b2015-08-06 16:24:43 -0700920 // End-of-Debugging
921
Thomas Vachuska329af532015-03-10 02:08:33 -0700922 try {
Simon Huntd2747a02015-04-30 22:41:16 -0700923 if (summaryRunning) {
Simon Hunt8a0429a2017-01-06 16:52:47 -0800924 msgSender.execute(() -> requestSummary());
Thomas Vachuska329af532015-03-10 02:08:33 -0700925 }
926 } catch (Exception e) {
927 log.warn("Unable to handle summary request due to {}", e.getMessage());
928 log.debug("Boom!", e);
929 }
930 }
931 }
932}