topoTraffic.js 6.53 KB
/*
 * Copyright 2015 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.
 */

/*
 ONOS GUI -- Topology Traffic Module.
 Defines behavior for viewing different traffic modes.
 */

(function () {
    'use strict';

    // injected refs
    var $log, fs, flash, wss;

    // api to topoForce
    var api;
    /*
     clearLinkTrafficStyle()
     removeLinkLabels()
     updateLinks()
     findLinkById( id )
     hovered()
     validateSelectionContext()
     */

    // constants
    var hoverModeNone = 0,
        hoverModeAll = 1,
        hoverModeFlows = 2,
        hoverModeIntents = 3;

    // internal state
    var hoverMode = hoverModeNone;


    // === -----------------------------------------------------
    //  Event Handlers

    function showTraffic(data) {
        var paths = data.paths;

        api.clearLinkTrafficStyle();
        api.removeLinkLabels();

        // Now highlight all links in the paths payload, and attach
        //  labels to them, if they are defined.
        paths.forEach(function (p) {
            var n = p.links.length,
                i, ldata;

            for (i=0; i<n; i++) {
                ldata = api.findLinkById(p.links[i]);
                if (ldata && ldata.el) {
                    ldata.el.classed(p.class, true);
                    ldata.label = p.labels[i];
                }
            }
        });

        api.updateLinks();
    }

    // === -----------------------------------------------------
    //  Helper functions

    function requestDeviceLinkFlows() {
        var hov = api.hovered();

        function hoverValid() {
            return hoverMode === hoverModeFlows &&
                hov && (hov.class === 'device');
        }

        if (api.validateSelectionContext()) {
            wss.sendEvent('requestDeviceLinkFlows', {
                ids: api.selectOrder(),
                hover: hoverValid() ? hov.id : ''
            });
        }
    }

    function requestRelatedIntents() {
        var hov = api.hovered();

        function hoverValid() {
            return hoverMode === hoverModeIntents &&
                hov && (hov.class === 'host' || hov.class === 'device');
        }

        if (api.validateSelectionContext()) {
            wss.sendEvent('requestRelatedIntents', {
                ids: api.selectOrder(),
                hover: hoverValid() ? hov.id : ''
            });
        }
    }


    // === -----------------------------------------------------
    //  Traffic requests

    function cancelTraffic() {
        wss.sendEvent('cancelTraffic');
    }

    // invoked in response to change in selection and/or mouseover/out:
    function requestTrafficForMode() {
        if (hoverMode === hoverModeFlows) {
            requestDeviceLinkFlows();
        } else if (hoverMode === hoverModeIntents) {
            requestRelatedIntents();
        }
    }

    // === -----------------------------
    // keystroke commands

    // keystroke-right-arrow (see topo.js)
    function showNextIntentAction() {
        hoverMode = hoverModeNone;
        wss.sendEvent('requestNextRelatedIntent');
        flash.flash('Next related intent');
    }

    // keystroke-left-arrow (see topo.js)
    function showPrevIntentAction() {
        hoverMode = hoverModeNone;
        wss.sendEvent('requestPrevRelatedIntent');
        flash.flash('Previous related intent');
    }

    // keystroke-W (see topo.js)
    function showSelectedIntentTrafficAction() {
        hoverMode = hoverModeNone;
        wss.sendEvent('requestSelectedIntentTraffic');
        flash.flash('Traffic on Selected Path');
    }

    // keystroke-A (see topo.js)
    function showAllTrafficAction() {
        hoverMode = hoverModeAll;
        wss.sendEvent('requestAllTraffic');
        flash.flash('All Traffic');
    }

    // === -----------------------------
    // action buttons on detail panel

    // also, keystroke-V (see topo.js)
    function showRelatedIntentsAction () {
        hoverMode = hoverModeIntents;
        requestRelatedIntents();
        flash.flash('Related Paths');
    }

    function addHostIntentAction () {
        var so = api.selectOrder();
        wss.sendEvent('addHostIntent', {
            one: so[0],
            two: so[1],
            ids: so
        });
        flash.flash('Host-to-Host flow added');
    }

    function addMultiSourceIntentAction () {
        var so = api.selectOrder();
        wss.sendEvent('addMultiSourceIntent', {
            src: so.slice(0, so.length - 1),
            dst: so[so.length - 1],
            ids: so
        });
        flash.flash('Multi-Source flow added');
    }

    // also, keystroke-F (see topo.js)
    function showDeviceLinkFlowsAction () {
        hoverMode = hoverModeFlows;
        requestDeviceLinkFlows();
        flash.flash('Device Flows');
    }


    // === -----------------------------------------------------
    // === MODULE DEFINITION ===

    angular.module('ovTopo')
    .factory('TopoTrafficService',
        ['$log', 'FnService', 'FlashService', 'WebSocketService',

        function (_$log_, _fs_, _flash_, _wss_) {
            $log = _$log_;
            fs = _fs_;
            flash = _flash_;
            wss = _wss_;

            function initTraffic(_api_) {
                api = _api_;
            }

            function destroyTraffic() { }

            return {
                initTraffic: initTraffic,
                destroyTraffic: destroyTraffic,

                showTraffic: showTraffic,

                cancelTraffic: cancelTraffic,
                requestTrafficForMode: requestTrafficForMode,
                showRelatedIntentsAction: showRelatedIntentsAction,
                addHostIntentAction: addHostIntentAction,
                addMultiSourceIntentAction: addMultiSourceIntentAction,
                showDeviceLinkFlowsAction: showDeviceLinkFlowsAction,
                showNextIntentAction: showNextIntentAction,
                showPrevIntentAction: showPrevIntentAction,
                showSelectedIntentTrafficAction: showSelectedIntentTrafficAction,
                showAllTrafficAction: showAllTrafficAction
            };
        }]);
}());