blob: dfedaf3cebb02286d0fb304ab1d27cb0bb2e880c [file] [log] [blame]
Simon Hunt1911fe42017-05-02 18:25:58 -07001/*
2 * Copyright 2017-present Open Networking Laboratory
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 *
16 */
17
18package org.onosproject.ui.impl;
19
20import org.onosproject.ui.impl.topo.util.ServicesBundle;
21import org.onosproject.ui.topo.AbstractTopoMonitor;
22import org.onosproject.ui.topo.TopoUtils;
23import org.slf4j.Logger;
24import org.slf4j.LoggerFactory;
25
26import java.util.Timer;
27import java.util.TimerTask;
28
29import static org.onosproject.ui.impl.TrafficMonitorBase.Mode.IDLE;
30
31/**
32 * Base superclass for traffic monitor (both 'classic' and 'topo2' versions).
33 */
34public abstract class TrafficMonitorBase extends AbstractTopoMonitor {
35
36 private final Logger log = LoggerFactory.getLogger(getClass());
37
38 // 4 Kilo Bytes as threshold
39 static final double BPS_THRESHOLD = 4 * TopoUtils.N_KILO;
40
41
42 /**
43 * Designates the different modes of operation.
44 */
45 public enum Mode {
46 IDLE,
47 ALL_FLOW_TRAFFIC_BYTES,
48 ALL_PORT_TRAFFIC_BIT_PS,
49 ALL_PORT_TRAFFIC_PKT_PS,
50 DEV_LINK_FLOWS,
51 RELATED_INTENTS,
52 SELECTED_INTENT
53 }
54
55 /**
56 * Number of milliseconds between invocations of sending traffic data.
57 */
58 protected final long trafficPeriod;
59
60 /**
61 * Holds references to services.
62 */
63 protected final ServicesBundle services;
64
65 /**
66 * Current operating mode.
67 */
68 protected Mode mode = Mode.IDLE;
69
70 private final Timer timer;
71 private TimerTask trafficTask = null;
72
73 /**
74 * Constructs the monitor, initializing the task period and
75 * services bundle reference.
76 *
77 * @param trafficPeriod traffic task period in ms
78 * @param servicesBundle bundle of services
79 */
80 protected TrafficMonitorBase(long trafficPeriod,
81 ServicesBundle servicesBundle) {
82 this.trafficPeriod = trafficPeriod;
83 this.services = servicesBundle;
84 timer = new Timer("uiTopo-" + getClass().getSimpleName());
85 }
86
87 /**
88 * Initiates monitoring of traffic for a given mode.
89 * This causes a background traffic task to be
90 * scheduled to repeatedly compute and transmit the appropriate traffic
91 * data to the client.
92 * <p>
93 * The monitoring mode is expected to be one of:
94 * <ul>
95 * <li>ALL_FLOW_TRAFFIC_BYTES</li>
96 * <li>ALL_PORT_TRAFFIC_BIT_PS</li>
97 * <li>ALL_PORT_TRAFFIC_PKT_PS</li>
98 * <li>SELECTED_INTENT</li>
99 * </ul>
100 *
101 * @param mode the monitoring mode
102 */
103 public synchronized void monitor(Mode mode) {
104 this.mode = mode;
105
106 switch (mode) {
107
108 case ALL_FLOW_TRAFFIC_BYTES:
109 clearSelection();
110 scheduleTask();
111 sendAllFlowTraffic();
112 break;
113
114 case ALL_PORT_TRAFFIC_BIT_PS:
115 clearSelection();
116 scheduleTask();
117 sendAllPortTrafficBits();
118 break;
119
120 case ALL_PORT_TRAFFIC_PKT_PS:
121 clearSelection();
122 scheduleTask();
123 sendAllPortTrafficPackets();
124 break;
125
126 case SELECTED_INTENT:
127 sendSelectedIntentTraffic();
128 scheduleTask();
129 break;
130
131 default:
132 log.warn("Unexpected call to monitor({})", mode);
133 clearAll();
134 break;
135 }
136 }
137
138 /**
139 * Subclass should compile and send appropriate highlights data showing
140 * flow traffic (bytes on links).
141 */
142 protected abstract void sendAllFlowTraffic();
143
144 /**
145 * Subclass should compile and send appropriate highlights data showing
146 * bits per second, as computed using port stats.
147 */
148 protected abstract void sendAllPortTrafficBits();
149
150 /**
151 * Subclass should compile and send appropriate highlights data showing
152 * packets per second, as computed using port stats.
153 */
154 protected abstract void sendAllPortTrafficPackets();
155
156 /**
157 * Subclass should compile and send appropriate highlights data showing
158 * number of flows traversing links for the "selected" device(s).
159 */
160 protected abstract void sendDeviceLinkFlows();
161
162 /**
163 * Subclass should compile and send appropriate highlights data showing
164 * traffic traversing links for the "selected" intent.
165 */
166 protected abstract void sendSelectedIntentTraffic();
167
168 /**
169 * Subclass should send a "clear highlights" event.
170 */
171 protected abstract void sendClearHighlights();
172
173 /**
174 * Subclasses should clear any selection state.
175 */
176 protected abstract void clearSelection();
177
178 /**
179 * Sets the mode to IDLE, clears the selection, cancels the background
180 * task, and sends a clear highlights event to the client.
181 */
182 protected void clearAll() {
183 this.mode = Mode.IDLE;
184 clearSelection();
185 cancelTask();
186 sendClearHighlights();
187 }
188
189 /**
190 * Schedules the background monitor task to run.
191 */
192 protected synchronized void scheduleTask() {
193 if (trafficTask == null) {
194 log.debug("Starting up background traffic task...");
195 trafficTask = new TrafficUpdateTask();
196 timer.schedule(trafficTask, trafficPeriod, trafficPeriod);
197 } else {
198 log.debug("(traffic task already running)");
199 }
200 }
201
202 /**
203 * Cancels the background monitor task.
204 */
205 protected synchronized void cancelTask() {
206 if (trafficTask != null) {
207 trafficTask.cancel();
208 trafficTask = null;
209 }
210 }
211
212 /**
213 * Stops monitoring. (Invokes {@link #clearAll}, if not idle).
214 */
215 public synchronized void stopMonitoring() {
216 log.debug("STOP monitoring");
217 if (mode != IDLE) {
218 clearAll();
219 }
220 }
221
222
223 // =======================================================================
224 // === Background Task
225
226 // Provides periodic update of traffic information to the client
227 private class TrafficUpdateTask extends TimerTask {
228 @Override
229 public void run() {
230 try {
231 switch (mode) {
232 case ALL_FLOW_TRAFFIC_BYTES:
233 sendAllFlowTraffic();
234 break;
235 case ALL_PORT_TRAFFIC_BIT_PS:
236 sendAllPortTrafficBits();
237 break;
238 case ALL_PORT_TRAFFIC_PKT_PS:
239 sendAllPortTrafficPackets();
240 break;
241 case DEV_LINK_FLOWS:
242 sendDeviceLinkFlows();
243 break;
244 case SELECTED_INTENT:
245 sendSelectedIntentTraffic();
246 break;
247
248 default:
249 // RELATED_INTENTS and IDLE modes should never invoke
250 // the background task, but if they do, they have
251 // nothing to do
252 break;
253 }
254
255 } catch (Exception e) {
256 log.warn("Unable to process traffic task due to {}", e.getMessage());
257 log.warn("Boom!", e);
258 }
259 }
260 }
261
262}