| /* |
| * Copyright 2017-present Open Networking Laboratory |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| * |
| */ |
| |
| package org.onosproject.ui.impl; |
| |
| import org.onosproject.ui.impl.topo.util.ServicesBundle; |
| import org.onosproject.ui.topo.AbstractTopoMonitor; |
| import org.onosproject.ui.topo.TopoUtils; |
| import org.slf4j.Logger; |
| import org.slf4j.LoggerFactory; |
| |
| import java.util.Timer; |
| import java.util.TimerTask; |
| |
| import static org.onosproject.ui.impl.TrafficMonitorBase.Mode.IDLE; |
| |
| /** |
| * Base superclass for traffic monitor (both 'classic' and 'topo2' versions). |
| */ |
| public abstract class TrafficMonitorBase extends AbstractTopoMonitor { |
| |
| private final Logger log = LoggerFactory.getLogger(getClass()); |
| |
| // 4 Kilo Bytes as threshold |
| static final double BPS_THRESHOLD = 4 * TopoUtils.N_KILO; |
| |
| |
| /** |
| * Designates the different modes of operation. |
| */ |
| public enum Mode { |
| IDLE, |
| ALL_FLOW_TRAFFIC_BYTES, |
| ALL_PORT_TRAFFIC_BIT_PS, |
| ALL_PORT_TRAFFIC_PKT_PS, |
| DEV_LINK_FLOWS, |
| RELATED_INTENTS, |
| SELECTED_INTENT |
| } |
| |
| /** |
| * Number of milliseconds between invocations of sending traffic data. |
| */ |
| protected final long trafficPeriod; |
| |
| /** |
| * Holds references to services. |
| */ |
| protected final ServicesBundle services; |
| |
| /** |
| * Current operating mode. |
| */ |
| protected Mode mode = Mode.IDLE; |
| |
| private final Timer timer; |
| private TimerTask trafficTask = null; |
| |
| /** |
| * Constructs the monitor, initializing the task period and |
| * services bundle reference. |
| * |
| * @param trafficPeriod traffic task period in ms |
| * @param servicesBundle bundle of services |
| */ |
| protected TrafficMonitorBase(long trafficPeriod, |
| ServicesBundle servicesBundle) { |
| this.trafficPeriod = trafficPeriod; |
| this.services = servicesBundle; |
| timer = new Timer("uiTopo-" + getClass().getSimpleName()); |
| } |
| |
| /** |
| * Initiates monitoring of traffic for a given mode. |
| * This causes a background traffic task to be |
| * scheduled to repeatedly compute and transmit the appropriate traffic |
| * data to the client. |
| * <p> |
| * The monitoring mode is expected to be one of: |
| * <ul> |
| * <li>ALL_FLOW_TRAFFIC_BYTES</li> |
| * <li>ALL_PORT_TRAFFIC_BIT_PS</li> |
| * <li>ALL_PORT_TRAFFIC_PKT_PS</li> |
| * <li>SELECTED_INTENT</li> |
| * </ul> |
| * |
| * @param mode the monitoring mode |
| */ |
| public synchronized void monitor(Mode mode) { |
| this.mode = mode; |
| |
| switch (mode) { |
| |
| case ALL_FLOW_TRAFFIC_BYTES: |
| clearSelection(); |
| scheduleTask(); |
| sendAllFlowTraffic(); |
| break; |
| |
| case ALL_PORT_TRAFFIC_BIT_PS: |
| clearSelection(); |
| scheduleTask(); |
| sendAllPortTrafficBits(); |
| break; |
| |
| case ALL_PORT_TRAFFIC_PKT_PS: |
| clearSelection(); |
| scheduleTask(); |
| sendAllPortTrafficPackets(); |
| break; |
| |
| case SELECTED_INTENT: |
| sendSelectedIntentTraffic(); |
| scheduleTask(); |
| break; |
| |
| default: |
| log.warn("Unexpected call to monitor({})", mode); |
| clearAll(); |
| break; |
| } |
| } |
| |
| /** |
| * Subclass should compile and send appropriate highlights data showing |
| * flow traffic (bytes on links). |
| */ |
| protected abstract void sendAllFlowTraffic(); |
| |
| /** |
| * Subclass should compile and send appropriate highlights data showing |
| * bits per second, as computed using port stats. |
| */ |
| protected abstract void sendAllPortTrafficBits(); |
| |
| /** |
| * Subclass should compile and send appropriate highlights data showing |
| * packets per second, as computed using port stats. |
| */ |
| protected abstract void sendAllPortTrafficPackets(); |
| |
| /** |
| * Subclass should compile and send appropriate highlights data showing |
| * number of flows traversing links for the "selected" device(s). |
| */ |
| protected abstract void sendDeviceLinkFlows(); |
| |
| /** |
| * Subclass should compile and send appropriate highlights data showing |
| * traffic traversing links for the "selected" intent. |
| */ |
| protected abstract void sendSelectedIntentTraffic(); |
| |
| /** |
| * Subclass should send a "clear highlights" event. |
| */ |
| protected abstract void sendClearHighlights(); |
| |
| /** |
| * Subclasses should clear any selection state. |
| */ |
| protected abstract void clearSelection(); |
| |
| /** |
| * Sets the mode to IDLE, clears the selection, cancels the background |
| * task, and sends a clear highlights event to the client. |
| */ |
| protected void clearAll() { |
| this.mode = Mode.IDLE; |
| clearSelection(); |
| cancelTask(); |
| sendClearHighlights(); |
| } |
| |
| /** |
| * Schedules the background monitor task to run. |
| */ |
| protected synchronized void scheduleTask() { |
| if (trafficTask == null) { |
| log.debug("Starting up background traffic task..."); |
| trafficTask = new TrafficUpdateTask(); |
| timer.schedule(trafficTask, trafficPeriod, trafficPeriod); |
| } else { |
| log.debug("(traffic task already running)"); |
| } |
| } |
| |
| /** |
| * Cancels the background monitor task. |
| */ |
| protected synchronized void cancelTask() { |
| if (trafficTask != null) { |
| trafficTask.cancel(); |
| trafficTask = null; |
| } |
| } |
| |
| /** |
| * Stops monitoring. (Invokes {@link #clearAll}, if not idle). |
| */ |
| public synchronized void stopMonitoring() { |
| log.debug("STOP monitoring"); |
| if (mode != IDLE) { |
| clearAll(); |
| } |
| } |
| |
| |
| // ======================================================================= |
| // === Background Task |
| |
| // Provides periodic update of traffic information to the client |
| private class TrafficUpdateTask extends TimerTask { |
| @Override |
| public void run() { |
| try { |
| switch (mode) { |
| case ALL_FLOW_TRAFFIC_BYTES: |
| sendAllFlowTraffic(); |
| break; |
| case ALL_PORT_TRAFFIC_BIT_PS: |
| sendAllPortTrafficBits(); |
| break; |
| case ALL_PORT_TRAFFIC_PKT_PS: |
| sendAllPortTrafficPackets(); |
| break; |
| case DEV_LINK_FLOWS: |
| sendDeviceLinkFlows(); |
| break; |
| case SELECTED_INTENT: |
| sendSelectedIntentTraffic(); |
| break; |
| |
| default: |
| // RELATED_INTENTS and IDLE modes should never invoke |
| // the background task, but if they do, they have |
| // nothing to do |
| break; |
| } |
| |
| } catch (Exception e) { |
| log.warn("Unable to process traffic task due to {}", e.getMessage()); |
| log.warn("Boom!", e); |
| } |
| } |
| } |
| |
| } |