blob: 609b7757ce13b27103c24685133fb7173bfcd3d6 [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;
58import org.onosproject.net.link.LinkEvent;
59import org.onosproject.net.link.LinkListener;
Simon Hunt4a6b54b2015-10-27 22:08:25 -070060import org.onosproject.ui.JsonUtils;
Simon Huntd2747a02015-04-30 22:41:16 -070061import org.onosproject.ui.RequestHandler;
Thomas Vachuska329af532015-03-10 02:08:33 -070062import org.onosproject.ui.UiConnection;
Simon Hunt4fc86852015-08-20 17:57:52 -070063import org.onosproject.ui.impl.TrafficMonitor.Mode;
Simon Hunta17fa672015-08-19 18:42:22 -070064import org.onosproject.ui.topo.Highlights;
Simon Huntd3ceffa2015-08-25 12:44:35 -070065import org.onosproject.ui.topo.NodeSelection;
Simon Hunt0af1ec32015-07-24 12:17:55 -070066import org.onosproject.ui.topo.PropertyPanel;
Thomas Vachuska329af532015-03-10 02:08:33 -070067
68import java.util.ArrayList;
Simon Huntd2747a02015-04-30 22:41:16 -070069import java.util.Collection;
Thomas Vachuska329af532015-03-10 02:08:33 -070070import java.util.Comparator;
71import java.util.HashSet;
72import java.util.List;
Simon Hunt5c1a9382016-06-01 19:35:35 -070073import java.util.Map;
Thomas Vachuska329af532015-03-10 02:08:33 -070074import java.util.Set;
75import java.util.Timer;
76import java.util.TimerTask;
Thomas Vachuska52c98bd2015-05-27 20:54:02 -070077import java.util.concurrent.ExecutorService;
Thomas Vachuska329af532015-03-10 02:08:33 -070078
Thomas Vachuska52c98bd2015-05-27 20:54:02 -070079import static java.util.concurrent.Executors.newSingleThreadExecutor;
80import static org.onlab.util.Tools.groupedThreads;
Thomas Vachuska329af532015-03-10 02:08:33 -070081import static org.onosproject.cluster.ClusterEvent.Type.INSTANCE_ADDED;
82import static org.onosproject.net.DeviceId.deviceId;
83import static org.onosproject.net.HostId.hostId;
Simon Hunt4a6b54b2015-10-27 22:08:25 -070084import static org.onosproject.net.device.DeviceEvent.Type.DEVICE_ADDED;
85import static org.onosproject.net.device.DeviceEvent.Type.DEVICE_UPDATED;
86import static org.onosproject.net.device.DeviceEvent.Type.PORT_STATS_UPDATED;
Thomas Vachuska329af532015-03-10 02:08:33 -070087import static org.onosproject.net.host.HostEvent.Type.HOST_ADDED;
88import static org.onosproject.net.link.LinkEvent.Type.LINK_ADDED;
Simon Huntd3ceffa2015-08-25 12:44:35 -070089import static org.onosproject.ui.JsonUtils.envelope;
Viswanath KSP0f297702016-08-13 18:02:43 +053090import static org.onosproject.ui.JsonUtils.string;
Simon Hunt52560662015-08-27 22:46:44 -070091import static org.onosproject.ui.topo.TopoJson.highlightsMessage;
92import static org.onosproject.ui.topo.TopoJson.json;
Thomas Vachuska329af532015-03-10 02:08:33 -070093
94/**
95 * Web socket capable of interacting with the GUI topology view.
96 */
97public class TopologyViewMessageHandler extends TopologyViewMessageHandlerBase {
98
Simon Huntb745ca62015-07-28 15:37:11 -070099 // incoming event types
Simon Huntd2747a02015-04-30 22:41:16 -0700100 private static final String REQ_DETAILS = "requestDetails";
101 private static final String UPDATE_META = "updateMeta";
102 private static final String ADD_HOST_INTENT = "addHostIntent";
Viswanath KSP0f297702016-08-13 18:02:43 +0530103 private static final String REMOVE_INTENT = "removeIntent";
Viswanath KSP14aee092016-10-02 01:47:40 +0530104 private static final String RESUBMIT_INTENT = "resubmitIntent";
Simon Huntd2747a02015-04-30 22:41:16 -0700105 private static final String ADD_MULTI_SRC_INTENT = "addMultiSourceIntent";
106 private static final String REQ_RELATED_INTENTS = "requestRelatedIntents";
107 private static final String REQ_NEXT_INTENT = "requestNextRelatedIntent";
108 private static final String REQ_PREV_INTENT = "requestPrevRelatedIntent";
109 private static final String REQ_SEL_INTENT_TRAFFIC = "requestSelectedIntentTraffic";
Simon Hunt4a6b54b2015-10-27 22:08:25 -0700110 private static final String SEL_INTENT = "selectIntent";
Thomas Vachuskaf0397b52015-05-29 13:50:17 -0700111 private static final String REQ_ALL_FLOW_TRAFFIC = "requestAllFlowTraffic";
112 private static final String REQ_ALL_PORT_TRAFFIC = "requestAllPortTraffic";
Simon Huntd2747a02015-04-30 22:41:16 -0700113 private static final String REQ_DEV_LINK_FLOWS = "requestDeviceLinkFlows";
114 private static final String CANCEL_TRAFFIC = "cancelTraffic";
115 private static final String REQ_SUMMARY = "requestSummary";
116 private static final String CANCEL_SUMMARY = "cancelSummary";
117 private static final String EQ_MASTERS = "equalizeMasters";
118 private static final String SPRITE_LIST_REQ = "spriteListRequest";
119 private static final String SPRITE_DATA_REQ = "spriteDataRequest";
120 private static final String TOPO_START = "topoStart";
Simon Hunte05cae42015-07-23 17:35:24 -0700121 private static final String TOPO_SELECT_OVERLAY = "topoSelectOverlay";
Simon Huntd2747a02015-04-30 22:41:16 -0700122 private static final String TOPO_STOP = "topoStop";
123
Simon Huntb745ca62015-07-28 15:37:11 -0700124 // outgoing event types
125 private static final String SHOW_SUMMARY = "showSummary";
126 private static final String SHOW_DETAILS = "showDetails";
127 private static final String SPRITE_LIST_RESPONSE = "spriteListResponse";
128 private static final String SPRITE_DATA_RESPONSE = "spriteDataResponse";
129 private static final String UPDATE_INSTANCE = "updateInstance";
Simon Hunt4a6b54b2015-10-27 22:08:25 -0700130 private static final String TOPO_START_DONE = "topoStartDone";
Simon Huntb745ca62015-07-28 15:37:11 -0700131
132 // fields
Simon Hunt5c1a9382016-06-01 19:35:35 -0700133 private static final String PAYLOAD = "payload";
134 private static final String EXTRA = "extra";
Simon Huntb745ca62015-07-28 15:37:11 -0700135 private static final String ID = "id";
Simon Hunt4a6b54b2015-10-27 22:08:25 -0700136 private static final String KEY = "key";
137 private static final String APP_ID = "appId";
138 private static final String APP_NAME = "appName";
Simon Huntb745ca62015-07-28 15:37:11 -0700139 private static final String DEVICE = "device";
140 private static final String HOST = "host";
141 private static final String CLASS = "class";
142 private static final String UNKNOWN = "unknown";
143 private static final String ONE = "one";
144 private static final String TWO = "two";
145 private static final String SRC = "src";
146 private static final String DST = "dst";
147 private static final String DATA = "data";
148 private static final String NAME = "name";
149 private static final String NAMES = "names";
150 private static final String ACTIVATE = "activate";
151 private static final String DEACTIVATE = "deactivate";
Viswanath KSP813a20d2016-09-13 04:25:41 +0530152 private static final String PURGE = "purge";
Simon Huntb745ca62015-07-28 15:37:11 -0700153
Simon Huntd2747a02015-04-30 22:41:16 -0700154
Simon Hunt4a6b54b2015-10-27 22:08:25 -0700155 private static final String MY_APP_ID = "org.onosproject.gui";
Thomas Vachuska329af532015-03-10 02:08:33 -0700156
Simon Hunta17fa672015-08-19 18:42:22 -0700157 private static final long TRAFFIC_PERIOD = 5000;
158 private static final long SUMMARY_PERIOD = 30000;
Thomas Vachuska329af532015-03-10 02:08:33 -0700159
160 private static final Comparator<? super ControllerNode> NODE_COMPARATOR =
Simon Hunt8a0429a2017-01-06 16:52:47 -0800161 Comparator.comparing(o -> o.id().toString());
Thomas Vachuska329af532015-03-10 02:08:33 -0700162
163
Thomas Vachuska52c98bd2015-05-27 20:54:02 -0700164 private final Timer timer = new Timer("onos-topology-view");
Thomas Vachuska329af532015-03-10 02:08:33 -0700165
166 private static final int MAX_EVENTS = 1000;
167 private static final int MAX_BATCH_MS = 5000;
168 private static final int MAX_IDLE_MS = 1000;
169
170 private ApplicationId appId;
171
172 private final ClusterEventListener clusterListener = new InternalClusterListener();
173 private final MastershipListener mastershipListener = new InternalMastershipListener();
174 private final DeviceListener deviceListener = new InternalDeviceListener();
175 private final LinkListener linkListener = new InternalLinkListener();
176 private final HostListener hostListener = new InternalHostListener();
177 private final IntentListener intentListener = new InternalIntentListener();
178 private final FlowRuleListener flowListener = new InternalFlowListener();
179
180 private final Accumulator<Event> eventAccummulator = new InternalEventAccummulator();
Thomas Vachuska52c98bd2015-05-27 20:54:02 -0700181 private final ExecutorService msgSender =
Yuta HIGUCHI1624df12016-07-21 16:54:33 -0700182 newSingleThreadExecutor(groupedThreads("onos/gui", "msg-sender", log));
Thomas Vachuska329af532015-03-10 02:08:33 -0700183
Simon Hunta17fa672015-08-19 18:42:22 -0700184 private TopoOverlayCache overlayCache;
Simon Hunt4fc86852015-08-20 17:57:52 -0700185 private TrafficMonitor traffic;
Thomas Vachuska329af532015-03-10 02:08:33 -0700186
Simon Huntd2747a02015-04-30 22:41:16 -0700187 private TimerTask summaryTask = null;
188 private boolean summaryRunning = false;
Thomas Vachuska329af532015-03-10 02:08:33 -0700189
Simon Huntd5b96732016-07-08 13:22:27 -0700190 private volatile boolean listenersRemoved = false;
Thomas Vachuska329af532015-03-10 02:08:33 -0700191
Thomas Vachuska329af532015-03-10 02:08:33 -0700192
193 @Override
194 public void init(UiConnection connection, ServiceDirectory directory) {
195 super.init(connection, directory);
Simon Hunt4a6b54b2015-10-27 22:08:25 -0700196 appId = directory.get(CoreService.class).registerApplication(MY_APP_ID);
Simon Hunt4fc86852015-08-20 17:57:52 -0700197 traffic = new TrafficMonitor(TRAFFIC_PERIOD, servicesBundle, this);
Thomas Vachuska329af532015-03-10 02:08:33 -0700198 }
199
200 @Override
201 public void destroy() {
202 cancelAllRequests();
Thomas Vachuska2bb48632015-04-28 14:40:42 -0700203 removeListeners();
Thomas Vachuska329af532015-03-10 02:08:33 -0700204 super.destroy();
205 }
206
Thomas Vachuska329af532015-03-10 02:08:33 -0700207 @Override
Simon Huntda580882015-05-12 20:58:18 -0700208 protected Collection<RequestHandler> createRequestHandlers() {
Simon Huntd2747a02015-04-30 22:41:16 -0700209 return ImmutableSet.of(
210 new TopoStart(),
Simon Hunte05cae42015-07-23 17:35:24 -0700211 new TopoSelectOverlay(),
Simon Huntd2747a02015-04-30 22:41:16 -0700212 new TopoStop(),
213 new ReqSummary(),
214 new CancelSummary(),
215 new SpriteListReq(),
216 new SpriteDataReq(),
217 new RequestDetails(),
218 new UpdateMeta(),
219 new EqMasters(),
Thomas Vachuska329af532015-03-10 02:08:33 -0700220
Simon Huntd2747a02015-04-30 22:41:16 -0700221 // TODO: migrate traffic related to separate app
222 new AddHostIntent(),
223 new AddMultiSourceIntent(),
Viswanath KSP0f297702016-08-13 18:02:43 +0530224 new RemoveIntent(),
Viswanath KSP14aee092016-10-02 01:47:40 +0530225 new ResubmitIntent(),
Simon Hunta17fa672015-08-19 18:42:22 -0700226
227 new ReqAllFlowTraffic(),
228 new ReqAllPortTraffic(),
229 new ReqDevLinkFlows(),
Simon Huntd2747a02015-04-30 22:41:16 -0700230 new ReqRelatedIntents(),
231 new ReqNextIntent(),
232 new ReqPrevIntent(),
233 new ReqSelectedIntentTraffic(),
Simon Hunt4a6b54b2015-10-27 22:08:25 -0700234 new SelIntent(),
Simon Hunta17fa672015-08-19 18:42:22 -0700235
Simon Huntd2747a02015-04-30 22:41:16 -0700236 new CancelTraffic()
237 );
238 }
Thomas Vachuska329af532015-03-10 02:08:33 -0700239
Simon Hunte05cae42015-07-23 17:35:24 -0700240 /**
241 * Injects the topology overlay cache.
242 *
243 * @param overlayCache injected cache
244 */
245 void setOverlayCache(TopoOverlayCache overlayCache) {
246 this.overlayCache = overlayCache;
247 }
248
Simon Huntd2747a02015-04-30 22:41:16 -0700249 // ==================================================================
Thomas Vachuska329af532015-03-10 02:08:33 -0700250
Simon Huntd2747a02015-04-30 22:41:16 -0700251 private final class TopoStart extends RequestHandler {
252 private TopoStart() {
253 super(TOPO_START);
254 }
Thomas Vachuska329af532015-03-10 02:08:33 -0700255
Simon Huntd2747a02015-04-30 22:41:16 -0700256 @Override
Simon Hunt8a0429a2017-01-06 16:52:47 -0800257 public void process(ObjectNode payload) {
Simon Huntd2747a02015-04-30 22:41:16 -0700258 addListeners();
259 sendAllInstances(null);
260 sendAllDevices();
261 sendAllLinks();
262 sendAllHosts();
Simon Hunt4a6b54b2015-10-27 22:08:25 -0700263 sendTopoStartDone();
Thomas Vachuska329af532015-03-10 02:08:33 -0700264 }
265 }
266
Simon Hunte05cae42015-07-23 17:35:24 -0700267 private final class TopoSelectOverlay extends RequestHandler {
268 private TopoSelectOverlay() {
269 super(TOPO_SELECT_OVERLAY);
270 }
271
272 @Override
Simon Hunt8a0429a2017-01-06 16:52:47 -0800273 public void process(ObjectNode payload) {
Simon Huntb745ca62015-07-28 15:37:11 -0700274 String deact = string(payload, DEACTIVATE);
275 String act = string(payload, ACTIVATE);
Simon Hunte05cae42015-07-23 17:35:24 -0700276 overlayCache.switchOverlay(deact, act);
277 }
278 }
279
Simon Huntd2747a02015-04-30 22:41:16 -0700280 private final class TopoStop extends RequestHandler {
281 private TopoStop() {
282 super(TOPO_STOP);
283 }
284
285 @Override
Simon Hunt8a0429a2017-01-06 16:52:47 -0800286 public void process(ObjectNode payload) {
Simon Hunt1ad59272015-11-10 15:23:21 -0800287 removeListeners();
Simon Huntd2747a02015-04-30 22:41:16 -0700288 stopSummaryMonitoring();
Simon Hunt4fc86852015-08-20 17:57:52 -0700289 traffic.stopMonitoring();
Simon Huntd2747a02015-04-30 22:41:16 -0700290 }
291 }
292
293 private final class ReqSummary extends RequestHandler {
294 private ReqSummary() {
295 super(REQ_SUMMARY);
296 }
297
298 @Override
Simon Hunt8a0429a2017-01-06 16:52:47 -0800299 public void process(ObjectNode payload) {
300 requestSummary();
Simon Huntd2747a02015-04-30 22:41:16 -0700301 startSummaryMonitoring();
302 }
303 }
304
305 private final class CancelSummary extends RequestHandler {
306 private CancelSummary() {
307 super(CANCEL_SUMMARY);
308 }
309
310 @Override
Simon Hunt8a0429a2017-01-06 16:52:47 -0800311 public void process(ObjectNode payload) {
Simon Huntd2747a02015-04-30 22:41:16 -0700312 stopSummaryMonitoring();
313 }
314 }
315
316 private final class SpriteListReq extends RequestHandler {
317 private SpriteListReq() {
318 super(SPRITE_LIST_REQ);
319 }
320
321 @Override
Simon Hunt8a0429a2017-01-06 16:52:47 -0800322 public void process(ObjectNode payload) {
Simon Huntda580882015-05-12 20:58:18 -0700323 ObjectNode root = objectNode();
324 ArrayNode names = arrayNode();
Simon Huntd2747a02015-04-30 22:41:16 -0700325 get(SpriteService.class).getNames().forEach(names::add);
Simon Huntb745ca62015-07-28 15:37:11 -0700326 root.set(NAMES, names);
Simon Hunt8a0429a2017-01-06 16:52:47 -0800327 sendMessage(SPRITE_LIST_RESPONSE, root);
Simon Huntd2747a02015-04-30 22:41:16 -0700328 }
329 }
330
331 private final class SpriteDataReq extends RequestHandler {
332 private SpriteDataReq() {
333 super(SPRITE_DATA_REQ);
334 }
335
336 @Override
Simon Hunt8a0429a2017-01-06 16:52:47 -0800337 public void process(ObjectNode payload) {
Simon Huntb745ca62015-07-28 15:37:11 -0700338 String name = string(payload, NAME);
Simon Huntda580882015-05-12 20:58:18 -0700339 ObjectNode root = objectNode();
Simon Huntb745ca62015-07-28 15:37:11 -0700340 root.set(DATA, get(SpriteService.class).get(name));
Simon Hunt8a0429a2017-01-06 16:52:47 -0800341 sendMessage(SPRITE_DATA_RESPONSE, root);
Simon Huntd2747a02015-04-30 22:41:16 -0700342 }
343 }
344
345 private final class RequestDetails extends RequestHandler {
346 private RequestDetails() {
347 super(REQ_DETAILS);
348 }
349
350 @Override
Simon Hunt8a0429a2017-01-06 16:52:47 -0800351 public void process(ObjectNode payload) {
Simon Huntb745ca62015-07-28 15:37:11 -0700352 String type = string(payload, CLASS, UNKNOWN);
353 String id = string(payload, ID);
354 PropertyPanel pp = null;
Simon Huntd2747a02015-04-30 22:41:16 -0700355
Simon Huntb745ca62015-07-28 15:37:11 -0700356 if (type.equals(DEVICE)) {
Simon Huntde99e0b2015-10-23 18:54:06 -0700357 DeviceId did = deviceId(id);
Simon Hunt8a0429a2017-01-06 16:52:47 -0800358 pp = deviceDetails(did);
Simon Huntde99e0b2015-10-23 18:54:06 -0700359 overlayCache.currentOverlay().modifyDeviceDetails(pp, did);
Simon Huntb745ca62015-07-28 15:37:11 -0700360 } else if (type.equals(HOST)) {
Simon Huntde99e0b2015-10-23 18:54:06 -0700361 HostId hid = hostId(id);
Simon Hunt8a0429a2017-01-06 16:52:47 -0800362 pp = hostDetails(hid);
Simon Huntde99e0b2015-10-23 18:54:06 -0700363 overlayCache.currentOverlay().modifyHostDetails(pp, hid);
Simon Huntd2747a02015-04-30 22:41:16 -0700364 }
Simon Huntb745ca62015-07-28 15:37:11 -0700365
Simon Hunt8a0429a2017-01-06 16:52:47 -0800366 sendMessage(envelope(SHOW_DETAILS, json(pp)));
Simon Huntd2747a02015-04-30 22:41:16 -0700367 }
368 }
369
370 private final class UpdateMeta extends RequestHandler {
371 private UpdateMeta() {
372 super(UPDATE_META);
373 }
374
375 @Override
Simon Hunt8a0429a2017-01-06 16:52:47 -0800376 public void process(ObjectNode payload) {
Simon Huntd2747a02015-04-30 22:41:16 -0700377 updateMetaUi(payload);
378 }
379 }
380
381 private final class EqMasters extends RequestHandler {
382 private EqMasters() {
383 super(EQ_MASTERS);
384 }
385
386 @Override
Simon Hunt8a0429a2017-01-06 16:52:47 -0800387 public void process(ObjectNode payload) {
Simon Huntd2747a02015-04-30 22:41:16 -0700388 directory.get(MastershipAdminService.class).balanceRoles();
389 }
390 }
391
Simon Hunta17fa672015-08-19 18:42:22 -0700392
393 // ========= -----------------------------------------------------------------
394
Simon Huntd2747a02015-04-30 22:41:16 -0700395 // === TODO: move traffic related classes to traffic app
396
397 private final class AddHostIntent extends RequestHandler {
398 private AddHostIntent() {
399 super(ADD_HOST_INTENT);
400 }
401
402 @Override
Simon Hunt8a0429a2017-01-06 16:52:47 -0800403 public void process(ObjectNode payload) {
Simon Huntd2747a02015-04-30 22:41:16 -0700404 // TODO: add protection against device ids and non-existent hosts.
Simon Huntb745ca62015-07-28 15:37:11 -0700405 HostId one = hostId(string(payload, ONE));
406 HostId two = hostId(string(payload, TWO));
Simon Huntd2747a02015-04-30 22:41:16 -0700407
408 HostToHostIntent intent = HostToHostIntent.builder()
Thomas Vachuskacb5016f2015-05-18 14:11:43 -0700409 .appId(appId)
410 .one(one)
411 .two(two)
412 .build();
Simon Huntd2747a02015-04-30 22:41:16 -0700413
414 intentService.submit(intent);
Simon Huntd2862c32015-08-24 17:41:51 -0700415 if (overlayCache.isActive(TrafficOverlay.TRAFFIC_ID)) {
416 traffic.monitor(intent);
417 }
Simon Huntd2747a02015-04-30 22:41:16 -0700418 }
419 }
420
Viswanath KSP0f297702016-08-13 18:02:43 +0530421 private Intent findIntentByPayload(ObjectNode payload) {
422 int appId = Integer.parseInt(string(payload, APP_ID));
423 String appName = string(payload, APP_NAME);
424 ApplicationId applicId = new DefaultApplicationId(appId, appName);
425 long intentKey = Long.decode(string(payload, KEY));
426
427 Key key = Key.of(intentKey, applicId);
428 log.debug("Attempting to select intent by key={}", key);
429
Viswanath KSP813a20d2016-09-13 04:25:41 +0530430 return intentService.getIntent(key);
Viswanath KSP0f297702016-08-13 18:02:43 +0530431 }
432
433 private final class RemoveIntent extends RequestHandler {
434 private RemoveIntent() {
435 super(REMOVE_INTENT);
436 }
437
Viswanath KSP813a20d2016-09-13 04:25:41 +0530438 private boolean isIntentToBePurged(ObjectNode payload) {
439 return bool(payload, PURGE);
440 }
441
Viswanath KSP0f297702016-08-13 18:02:43 +0530442 @Override
Simon Hunt8a0429a2017-01-06 16:52:47 -0800443 public void process(ObjectNode payload) {
Viswanath KSP0f297702016-08-13 18:02:43 +0530444 Intent intent = findIntentByPayload(payload);
445 if (intent == null) {
446 log.warn("Unable to find intent from payload {}", payload);
447 } else {
Viswanath KSP813a20d2016-09-13 04:25:41 +0530448 log.debug("Withdrawing / Purging intent {}", intent.key());
449 if (isIntentToBePurged(payload)) {
450 intentService.purge(intent);
451 } else {
452 intentService.withdraw(intent);
453 }
Viswanath KSP0f297702016-08-13 18:02:43 +0530454 }
455 }
456 }
457
Viswanath KSP14aee092016-10-02 01:47:40 +0530458 private final class ResubmitIntent extends RequestHandler {
459 private ResubmitIntent() {
460 super(RESUBMIT_INTENT);
461 }
462
463 @Override
Simon Hunt8a0429a2017-01-06 16:52:47 -0800464 public void process(ObjectNode payload) {
Viswanath KSP14aee092016-10-02 01:47:40 +0530465 Intent intent = findIntentByPayload(payload);
466 if (intent == null) {
467 log.warn("Unable to find intent from payload {}", payload);
468 } else {
469 log.debug("Resubmitting intent {}", intent.key());
470 intentService.submit(intent);
471 }
472 }
473 }
474
Simon Huntd2747a02015-04-30 22:41:16 -0700475 private final class AddMultiSourceIntent extends RequestHandler {
476 private AddMultiSourceIntent() {
477 super(ADD_MULTI_SRC_INTENT);
478 }
479
480 @Override
Simon Hunt8a0429a2017-01-06 16:52:47 -0800481 public void process(ObjectNode payload) {
Simon Huntd2747a02015-04-30 22:41:16 -0700482 // TODO: add protection against device ids and non-existent hosts.
Simon Huntb745ca62015-07-28 15:37:11 -0700483 Set<HostId> src = getHostIds((ArrayNode) payload.path(SRC));
484 HostId dst = hostId(string(payload, DST));
Simon Huntd2747a02015-04-30 22:41:16 -0700485 Host dstHost = hostService.getHost(dst);
486
487 Set<ConnectPoint> ingressPoints = getHostLocations(src);
488
489 // FIXME: clearly, this is not enough
490 TrafficSelector selector = DefaultTrafficSelector.builder()
491 .matchEthDst(dstHost.mac()).build();
492 TrafficTreatment treatment = DefaultTrafficTreatment.emptyTreatment();
493
494 MultiPointToSinglePointIntent intent =
495 MultiPointToSinglePointIntent.builder()
496 .appId(appId)
497 .selector(selector)
498 .treatment(treatment)
499 .ingressPoints(ingressPoints)
500 .egressPoint(dstHost.location())
501 .build();
502
503 intentService.submit(intent);
Simon Huntd2862c32015-08-24 17:41:51 -0700504 if (overlayCache.isActive(TrafficOverlay.TRAFFIC_ID)) {
505 traffic.monitor(intent);
506 }
Simon Huntd2747a02015-04-30 22:41:16 -0700507 }
508 }
509
Simon Hunta17fa672015-08-19 18:42:22 -0700510 // ========= -----------------------------------------------------------------
Simon Huntd2747a02015-04-30 22:41:16 -0700511
Thomas Vachuskaf0397b52015-05-29 13:50:17 -0700512 private final class ReqAllFlowTraffic extends RequestHandler {
513 private ReqAllFlowTraffic() {
514 super(REQ_ALL_FLOW_TRAFFIC);
Simon Huntd2747a02015-04-30 22:41:16 -0700515 }
516
517 @Override
Simon Hunt8a0429a2017-01-06 16:52:47 -0800518 public void process(ObjectNode payload) {
Simon Hunt4fc86852015-08-20 17:57:52 -0700519 traffic.monitor(Mode.ALL_FLOW_TRAFFIC);
Thomas Vachuskaf0397b52015-05-29 13:50:17 -0700520 }
521 }
522
523 private final class ReqAllPortTraffic extends RequestHandler {
524 private ReqAllPortTraffic() {
525 super(REQ_ALL_PORT_TRAFFIC);
526 }
527
528 @Override
Simon Hunt8a0429a2017-01-06 16:52:47 -0800529 public void process(ObjectNode payload) {
Simon Hunt4fc86852015-08-20 17:57:52 -0700530 traffic.monitor(Mode.ALL_PORT_TRAFFIC);
Simon Huntd2747a02015-04-30 22:41:16 -0700531 }
532 }
533
534 private final class ReqDevLinkFlows extends RequestHandler {
535 private ReqDevLinkFlows() {
536 super(REQ_DEV_LINK_FLOWS);
537 }
538
539 @Override
Simon Hunt8a0429a2017-01-06 16:52:47 -0800540 public void process(ObjectNode payload) {
Simon Hunta17fa672015-08-19 18:42:22 -0700541 NodeSelection nodeSelection =
Prince Pereira46c82d42016-09-19 13:30:50 +0530542 new NodeSelection(payload, deviceService, hostService, linkService);
Simon Hunt4fc86852015-08-20 17:57:52 -0700543 traffic.monitor(Mode.DEV_LINK_FLOWS, nodeSelection);
Simon Hunta17fa672015-08-19 18:42:22 -0700544 }
545 }
546
547 private final class ReqRelatedIntents extends RequestHandler {
548 private ReqRelatedIntents() {
549 super(REQ_RELATED_INTENTS);
550 }
551
552 @Override
Simon Hunt8a0429a2017-01-06 16:52:47 -0800553 public void process(ObjectNode payload) {
Simon Hunta17fa672015-08-19 18:42:22 -0700554 NodeSelection nodeSelection =
Prince Pereira46c82d42016-09-19 13:30:50 +0530555 new NodeSelection(payload, deviceService, hostService, linkService);
Simon Hunt4fc86852015-08-20 17:57:52 -0700556 traffic.monitor(Mode.RELATED_INTENTS, nodeSelection);
Simon Hunta17fa672015-08-19 18:42:22 -0700557 }
558 }
559
560 private final class ReqNextIntent extends RequestHandler {
561 private ReqNextIntent() {
562 super(REQ_NEXT_INTENT);
563 }
564
565 @Override
Simon Hunt8a0429a2017-01-06 16:52:47 -0800566 public void process(ObjectNode payload) {
Simon Hunt4fc86852015-08-20 17:57:52 -0700567 traffic.selectNextIntent();
Simon Hunta17fa672015-08-19 18:42:22 -0700568 }
569 }
570
571 private final class ReqPrevIntent extends RequestHandler {
572 private ReqPrevIntent() {
573 super(REQ_PREV_INTENT);
574 }
575
576 @Override
Simon Hunt8a0429a2017-01-06 16:52:47 -0800577 public void process(ObjectNode payload) {
Simon Hunt4fc86852015-08-20 17:57:52 -0700578 traffic.selectPreviousIntent();
Simon Hunta17fa672015-08-19 18:42:22 -0700579 }
580 }
581
582 private final class ReqSelectedIntentTraffic extends RequestHandler {
583 private ReqSelectedIntentTraffic() {
584 super(REQ_SEL_INTENT_TRAFFIC);
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.monitor(Mode.SELECTED_INTENT);
Simon Huntd2747a02015-04-30 22:41:16 -0700590 }
591 }
592
Simon Hunt4a6b54b2015-10-27 22:08:25 -0700593 private final class SelIntent extends RequestHandler {
594 private SelIntent() {
595 super(SEL_INTENT);
596 }
597
598 @Override
Simon Hunt8a0429a2017-01-06 16:52:47 -0800599 public void process(ObjectNode payload) {
Viswanath KSP0f297702016-08-13 18:02:43 +0530600 Intent intent = findIntentByPayload(payload);
Simon Hunt4a6b54b2015-10-27 22:08:25 -0700601 if (intent == null) {
Viswanath KSP0f297702016-08-13 18:02:43 +0530602 log.warn("Unable to find intent from payload {}", payload);
Simon Hunt4a6b54b2015-10-27 22:08:25 -0700603 } else {
Viswanath KSP0f297702016-08-13 18:02:43 +0530604 log.debug("starting to monitor intent {}", intent.key());
Simon Hunt4a6b54b2015-10-27 22:08:25 -0700605 traffic.monitor(intent);
606 }
607 }
608 }
609
Simon Huntd2747a02015-04-30 22:41:16 -0700610 private final class CancelTraffic extends RequestHandler {
611 private CancelTraffic() {
612 super(CANCEL_TRAFFIC);
613 }
614
615 @Override
Simon Hunt8a0429a2017-01-06 16:52:47 -0800616 public void process(ObjectNode payload) {
Simon Hunt4fc86852015-08-20 17:57:52 -0700617 traffic.stopMonitoring();
Simon Huntd2747a02015-04-30 22:41:16 -0700618 }
619 }
620
621 //=======================================================================
622
Simon Hunta17fa672015-08-19 18:42:22 -0700623 // Converts highlights to JSON format and sends the message to the client
Simon Hunt8a0429a2017-01-06 16:52:47 -0800624 void sendHighlights(Highlights highlights) {
Simon Hunt52560662015-08-27 22:46:44 -0700625 sendMessage(highlightsMessage(highlights));
Thomas Vachuska329af532015-03-10 02:08:33 -0700626 }
627
Simon Huntd2747a02015-04-30 22:41:16 -0700628 // Subscribes for summary messages.
Simon Hunt8a0429a2017-01-06 16:52:47 -0800629 private synchronized void requestSummary() {
630 PropertyPanel pp = summmaryMessage();
Simon Hunt0af1ec32015-07-24 12:17:55 -0700631 overlayCache.currentOverlay().modifySummary(pp);
Simon Hunt8a0429a2017-01-06 16:52:47 -0800632 sendMessage(envelope(SHOW_SUMMARY, json(pp)));
Thomas Vachuska329af532015-03-10 02:08:33 -0700633 }
634
Simon Huntd2747a02015-04-30 22:41:16 -0700635
Thomas Vachuska329af532015-03-10 02:08:33 -0700636 private void cancelAllRequests() {
637 stopSummaryMonitoring();
Simon Hunt4fc86852015-08-20 17:57:52 -0700638 traffic.stopMonitoring();
Thomas Vachuska329af532015-03-10 02:08:33 -0700639 }
640
641 // Sends all controller nodes to the client as node-added messages.
642 private void sendAllInstances(String messageType) {
643 List<ControllerNode> nodes = new ArrayList<>(clusterService.getNodes());
Simon Hunt8a0429a2017-01-06 16:52:47 -0800644 nodes.sort(NODE_COMPARATOR);
Thomas Vachuska329af532015-03-10 02:08:33 -0700645 for (ControllerNode node : nodes) {
646 sendMessage(instanceMessage(new ClusterEvent(INSTANCE_ADDED, node),
Simon Hunt5c1a9382016-06-01 19:35:35 -0700647 messageType));
Thomas Vachuska329af532015-03-10 02:08:33 -0700648 }
649 }
650
651 // Sends all devices to the client as device-added messages.
652 private void sendAllDevices() {
653 // Send optical first, others later for layered rendering
654 for (Device device : deviceService.getDevices()) {
Rimon Ashkenazy8ebfff02016-02-01 11:56:36 +0200655 if ((device.type() == Device.Type.ROADM) ||
Simon Hunt5c1a9382016-06-01 19:35:35 -0700656 (device.type() == Device.Type.OTN)) {
Thomas Vachuska329af532015-03-10 02:08:33 -0700657 sendMessage(deviceMessage(new DeviceEvent(DEVICE_ADDED, device)));
658 }
659 }
660 for (Device device : deviceService.getDevices()) {
Rimon Ashkenazy8ebfff02016-02-01 11:56:36 +0200661 if ((device.type() != Device.Type.ROADM) &&
Simon Hunt5c1a9382016-06-01 19:35:35 -0700662 (device.type() != Device.Type.OTN)) {
Thomas Vachuska329af532015-03-10 02:08:33 -0700663 sendMessage(deviceMessage(new DeviceEvent(DEVICE_ADDED, device)));
664 }
665 }
666 }
667
668 // Sends all links to the client as link-added messages.
669 private void sendAllLinks() {
670 // Send optical first, others later for layered rendering
671 for (Link link : linkService.getLinks()) {
672 if (link.type() == Link.Type.OPTICAL) {
Simon Hunt5c1a9382016-06-01 19:35:35 -0700673 sendMessage(composeLinkMessage(new LinkEvent(LINK_ADDED, link)));
Thomas Vachuska329af532015-03-10 02:08:33 -0700674 }
675 }
676 for (Link link : linkService.getLinks()) {
677 if (link.type() != Link.Type.OPTICAL) {
Simon Hunt5c1a9382016-06-01 19:35:35 -0700678 sendMessage(composeLinkMessage(new LinkEvent(LINK_ADDED, link)));
Thomas Vachuska329af532015-03-10 02:08:33 -0700679 }
680 }
681 }
682
Simon Hunt5c1a9382016-06-01 19:35:35 -0700683 // Temporary mechanism to support topology overlays adding their own
684 // properties to the link events.
685 private ObjectNode composeLinkMessage(LinkEvent event) {
686 // start with base message
687 ObjectNode msg = linkMessage(event);
688 Map<String, String> additional =
689 overlayCache.currentOverlay().additionalLinkData(event);
690
691 if (additional != null) {
692 // attach additional key-value pairs as extra data structure
693 ObjectNode payload = (ObjectNode) msg.get(PAYLOAD);
694 payload.set(EXTRA, createExtra(additional));
695 }
696 return msg;
697 }
698
699 private ObjectNode createExtra(Map<String, String> additional) {
700 ObjectNode extra = objectNode();
701 for (Map.Entry<String, String> entry : additional.entrySet()) {
702 extra.put(entry.getKey(), entry.getValue());
703 }
704 return extra;
705 }
706
Thomas Vachuska329af532015-03-10 02:08:33 -0700707 // Sends all hosts to the client as host-added messages.
708 private void sendAllHosts() {
709 for (Host host : hostService.getHosts()) {
710 sendMessage(hostMessage(new HostEvent(HOST_ADDED, host)));
711 }
712 }
713
Thomas Vachuska329af532015-03-10 02:08:33 -0700714 private Set<ConnectPoint> getHostLocations(Set<HostId> hostIds) {
715 Set<ConnectPoint> points = new HashSet<>();
716 for (HostId hostId : hostIds) {
717 points.add(getHostLocation(hostId));
718 }
719 return points;
720 }
721
722 private HostLocation getHostLocation(HostId hostId) {
723 return hostService.getHost(hostId).location();
724 }
725
726 // Produces a list of host ids from the specified JSON array.
727 private Set<HostId> getHostIds(ArrayNode ids) {
728 Set<HostId> hostIds = new HashSet<>();
729 for (JsonNode id : ids) {
730 hostIds.add(hostId(id.asText()));
731 }
732 return hostIds;
733 }
734
Simon Hunt4a6b54b2015-10-27 22:08:25 -0700735 private void sendTopoStartDone() {
736 sendMessage(JsonUtils.envelope(TOPO_START_DONE, objectNode()));
737 }
Thomas Vachuska329af532015-03-10 02:08:33 -0700738
Simon Huntd2747a02015-04-30 22:41:16 -0700739 private synchronized void startSummaryMonitoring() {
Thomas Vachuska329af532015-03-10 02:08:33 -0700740 stopSummaryMonitoring();
Thomas Vachuska329af532015-03-10 02:08:33 -0700741 summaryTask = new SummaryMonitor();
Simon Hunta17fa672015-08-19 18:42:22 -0700742 timer.schedule(summaryTask, SUMMARY_PERIOD, SUMMARY_PERIOD);
Simon Huntd2747a02015-04-30 22:41:16 -0700743 summaryRunning = true;
Thomas Vachuska329af532015-03-10 02:08:33 -0700744 }
745
746 private synchronized void stopSummaryMonitoring() {
Simon Huntd2747a02015-04-30 22:41:16 -0700747 if (summaryTask != null) {
Thomas Vachuska329af532015-03-10 02:08:33 -0700748 summaryTask.cancel();
749 summaryTask = null;
Thomas Vachuska329af532015-03-10 02:08:33 -0700750 }
Simon Huntd2747a02015-04-30 22:41:16 -0700751 summaryRunning = false;
Thomas Vachuska9ed335b2015-04-14 12:07:47 -0700752 }
753
Thomas Vachuska329af532015-03-10 02:08:33 -0700754
755 // Adds all internal listeners.
Thomas Vachuska35fa3d42015-04-30 10:11:47 -0700756 private synchronized void addListeners() {
Thomas Vachuskae586b792015-03-26 13:59:38 -0700757 listenersRemoved = false;
Thomas Vachuska329af532015-03-10 02:08:33 -0700758 clusterService.addListener(clusterListener);
759 mastershipService.addListener(mastershipListener);
760 deviceService.addListener(deviceListener);
761 linkService.addListener(linkListener);
762 hostService.addListener(hostListener);
763 intentService.addListener(intentListener);
764 flowService.addListener(flowListener);
765 }
766
767 // Removes all internal listeners.
768 private synchronized void removeListeners() {
769 if (!listenersRemoved) {
770 listenersRemoved = true;
771 clusterService.removeListener(clusterListener);
772 mastershipService.removeListener(mastershipListener);
773 deviceService.removeListener(deviceListener);
774 linkService.removeListener(linkListener);
775 hostService.removeListener(hostListener);
776 intentService.removeListener(intentListener);
777 flowService.removeListener(flowListener);
778 }
779 }
780
781 // Cluster event listener.
Simon Hunt7092cc42016-04-06 18:40:17 -0700782 // TODO: Superceded by UiSharedTopologyModel.ModelEventListener
783 @Deprecated
Thomas Vachuska329af532015-03-10 02:08:33 -0700784 private class InternalClusterListener implements ClusterEventListener {
785 @Override
786 public void event(ClusterEvent event) {
Thomas Vachuskac7f79962015-05-28 09:37:34 -0700787 msgSender.execute(() -> sendMessage(instanceMessage(event, null)));
Thomas Vachuska329af532015-03-10 02:08:33 -0700788 }
789 }
790
791 // Mastership change listener
Simon Hunt7092cc42016-04-06 18:40:17 -0700792 // TODO: Superceded by UiSharedTopologyModel.ModelEventListener
793 @Deprecated
Thomas Vachuska329af532015-03-10 02:08:33 -0700794 private class InternalMastershipListener implements MastershipListener {
795 @Override
796 public void event(MastershipEvent event) {
Thomas Vachuska52c98bd2015-05-27 20:54:02 -0700797 msgSender.execute(() -> {
Simon Huntb745ca62015-07-28 15:37:11 -0700798 sendAllInstances(UPDATE_INSTANCE);
Thomas Vachuska52c98bd2015-05-27 20:54:02 -0700799 Device device = deviceService.getDevice(event.subject());
800 if (device != null) {
801 sendMessage(deviceMessage(new DeviceEvent(DEVICE_UPDATED, device)));
802 }
803 });
Thomas Vachuska329af532015-03-10 02:08:33 -0700804 }
805 }
806
807 // Device event listener.
Simon Hunt7092cc42016-04-06 18:40:17 -0700808 // TODO: Superceded by UiSharedTopologyModel.ModelEventListener
809 @Deprecated
Thomas Vachuska329af532015-03-10 02:08:33 -0700810 private class InternalDeviceListener implements DeviceListener {
811 @Override
812 public void event(DeviceEvent event) {
Thomas Vachuskacb5016f2015-05-18 14:11:43 -0700813 if (event.type() != PORT_STATS_UPDATED) {
Thomas Vachuskac7f79962015-05-28 09:37:34 -0700814 msgSender.execute(() -> sendMessage(deviceMessage(event)));
Simon Hunta1f1c022016-03-03 15:54:57 -0800815 msgSender.execute(traffic::pokeIntent);
Thomas Vachuskacb5016f2015-05-18 14:11:43 -0700816 eventAccummulator.add(event);
817 }
Thomas Vachuska329af532015-03-10 02:08:33 -0700818 }
819 }
820
821 // Link event listener.
Simon Hunt7092cc42016-04-06 18:40:17 -0700822 // TODO: Superceded by UiSharedTopologyModel.ModelEventListener
823 @Deprecated
Thomas Vachuska329af532015-03-10 02:08:33 -0700824 private class InternalLinkListener implements LinkListener {
825 @Override
826 public void event(LinkEvent event) {
Simon Hunt5c1a9382016-06-01 19:35:35 -0700827 msgSender.execute(() -> sendMessage(composeLinkMessage(event)));
Simon Hunta1f1c022016-03-03 15:54:57 -0800828 msgSender.execute(traffic::pokeIntent);
Thomas Vachuska329af532015-03-10 02:08:33 -0700829 eventAccummulator.add(event);
830 }
831 }
832
833 // Host event listener.
Simon Hunt7092cc42016-04-06 18:40:17 -0700834 // TODO: Superceded by UiSharedTopologyModel.ModelEventListener
835 @Deprecated
Thomas Vachuska329af532015-03-10 02:08:33 -0700836 private class InternalHostListener implements HostListener {
837 @Override
838 public void event(HostEvent event) {
Thomas Vachuskac7f79962015-05-28 09:37:34 -0700839 msgSender.execute(() -> sendMessage(hostMessage(event)));
Simon Hunta1f1c022016-03-03 15:54:57 -0800840 msgSender.execute(traffic::pokeIntent);
Thomas Vachuska329af532015-03-10 02:08:33 -0700841 eventAccummulator.add(event);
842 }
843 }
844
845 // Intent event listener.
Simon Hunt7092cc42016-04-06 18:40:17 -0700846 // TODO: Superceded by UiSharedTopologyModel.ModelEventListener
847 @Deprecated
Thomas Vachuska329af532015-03-10 02:08:33 -0700848 private class InternalIntentListener implements IntentListener {
849 @Override
850 public void event(IntentEvent event) {
Simon Hunt4fc86852015-08-20 17:57:52 -0700851 msgSender.execute(traffic::pokeIntent);
Thomas Vachuska329af532015-03-10 02:08:33 -0700852 eventAccummulator.add(event);
853 }
854 }
855
856 // Intent event listener.
Simon Hunt7092cc42016-04-06 18:40:17 -0700857 // TODO: Superceded by UiSharedTopologyModel.ModelEventListener
858 @Deprecated
Thomas Vachuska329af532015-03-10 02:08:33 -0700859 private class InternalFlowListener implements FlowRuleListener {
860 @Override
861 public void event(FlowRuleEvent event) {
862 eventAccummulator.add(event);
863 }
864 }
865
Simon Huntd2747a02015-04-30 22:41:16 -0700866
Simon Hunta17fa672015-08-19 18:42:22 -0700867 // === SUMMARY MONITORING
Thomas Vachuska329af532015-03-10 02:08:33 -0700868
869 // Periodic update of the summary information
870 private class SummaryMonitor extends TimerTask {
871 @Override
872 public void run() {
873 try {
Simon Huntd2747a02015-04-30 22:41:16 -0700874 if (summaryRunning) {
Simon Hunt8a0429a2017-01-06 16:52:47 -0800875 msgSender.execute(() -> requestSummary());
Thomas Vachuska329af532015-03-10 02:08:33 -0700876 }
877 } catch (Exception e) {
878 log.warn("Unable to handle summary request due to {}", e.getMessage());
879 log.warn("Boom!", e);
880 }
881 }
882 }
883
884 // Accumulates events to drive methodic update of the summary pane.
885 private class InternalEventAccummulator extends AbstractAccumulator<Event> {
886 protected InternalEventAccummulator() {
887 super(new Timer("topo-summary"), MAX_EVENTS, MAX_BATCH_MS, MAX_IDLE_MS);
888 }
889
890 @Override
891 public void processItems(List<Event> items) {
Simon Hunta17fa672015-08-19 18:42:22 -0700892 // Start-of-Debugging -- Keep in until ONOS-2572 is fixed for reals
Simon Hunt8d22c4b2015-08-06 16:24:43 -0700893 long now = System.currentTimeMillis();
894 String me = this.toString();
895 String miniMe = me.replaceAll("^.*@", "me@");
896 log.debug("Time: {}; this: {}, processing items ({} events)",
Simon Hunt5c1a9382016-06-01 19:35:35 -0700897 now, miniMe, items.size());
Simon Hunt8d22c4b2015-08-06 16:24:43 -0700898 // End-of-Debugging
899
Thomas Vachuska329af532015-03-10 02:08:33 -0700900 try {
Simon Huntd2747a02015-04-30 22:41:16 -0700901 if (summaryRunning) {
Simon Hunt8a0429a2017-01-06 16:52:47 -0800902 msgSender.execute(() -> requestSummary());
Thomas Vachuska329af532015-03-10 02:08:33 -0700903 }
904 } catch (Exception e) {
905 log.warn("Unable to handle summary request due to {}", e.getMessage());
906 log.debug("Boom!", e);
907 }
908 }
909 }
910}