SFC topology
[groupbasedpolicy.git] / groupbasedpolicy-ui / module / src / main / resources / gbp / common / gbp.controller.js
index f1295b11cd5b69057be731abffd115690f2a45c1..cb04cc439c2a993a5e671af3e0ee9ec800d09b60 100644 (file)
@@ -3,27 +3,34 @@ define(['app/gbp/common/gbp.service', 'app/gbp/resolved-policy/resolved-policy.s
 
     angular.module('app.gbp').controller('RootGbpCtrl', RootGbpCtrl);
 
-    RootGbpCtrl.$inject = ['$state', '$rootScope', '$scope', '$filter', 'RootGbpService', 'TenantListService', 'TenantService', 'EpgListService', 'ResolvedPolicyService', 'NextTopologyService', 'EndpointsListService'];
+    RootGbpCtrl.$inject = ['$state', '$rootScope', '$scope', '$filter', '$mdDialog', 'RootGbpService',
+        'TenantListService', 'EpgListService', 'ResolvedPolicyService', 'NextTopologyService', 'EndpointsListService'];
 
-    function RootGbpCtrl($state, $rootScope, $scope, $filter, RootGbpService, TenantListService, TenantService, EpgListService, ResolvedPolicyService, NextTopologyService, EndpointsListService) {
+    function RootGbpCtrl($state, $rootScope, $scope, $filter, $mdDialog, RootGbpService,
+        TenantListService, EpgListService, ResolvedPolicyService, NextTopologyService, EndpointsListService) {
         /* properties */
-        $scope.stateUrl = null;
+        $scope.apiType = 'operational';
+        $scope.activeObject = null;
+        $scope.endpoints = EndpointsListService.createList();
+        $scope.rootTenant = null;
+        $scope.rootTenants = TenantListService.createList();
+        $scope.resolvedPolicy = {};
+        $scope.selectedNode = {};
+        $scope.sidePanelObject = {};
         $scope.sidePanelPage = false;
         $scope.sidePanelPageEndpoint = false;
-        $scope.sidePanelObject = {};
-        $scope.rootTenant = TenantService.createObject();
-        $scope.rootTenants = TenantListService.createList();
-        $scope.policyDisabled = true;
+        $scope.stateUrl = null;
+        $scope.topologyData = {nodes: [], links: []};
         $scope.viewPath = 'src/app/gbp/';
-        $scope.selectedNode = {};
-        $scope.apiType = 'operational';
-        $scope.parentTenant = 'tenant-red';
-        $scope.resolvedPolicy = {};
-        $scope.endpoints = EndpointsListService.createList();
+
+        var resolvedPolicies = ResolvedPolicyService.createObject();
+        resolvedPolicies.get(fillTopologyData);
 
         /* methods */
+        $scope.fillTopologyData = fillTopologyData;
         $scope.broadcastFromRoot = broadcastFromRoot;
         $scope.closeSidePanel = closeSidePanel;
+        $scope.openSfcDialog = openSfcDialog;
         $scope.openSidePanel = openSidePanel;
         $scope.setRootTenant = setRootTenant;
         $scope.toggleExpanded = toggleExpanded;
@@ -38,115 +45,289 @@ define(['app/gbp/common/gbp.service', 'app/gbp/resolved-policy/resolved-policy.s
         $scope.highlightNode = highlightNode;
         $scope.highlightLink = highlightLink;
         $scope.fadeAll = fadeAll;
+        $scope.rootOpenEndpointDialog = rootOpenEndpointDialog;
+        $scope.rootDeleteEndpointDialog = rootDeleteEndpointDialog;
+        $scope.getEndpointsList = getEndpointsList;
 
         RootGbpService.setMainClass();
-        console.log('RootGbpCtrl initialized');
-
         init();
 
-
-        $scope.topologyData = {
-            nodes: [],
-            links: [],
-        };
-
         /* implementations */
+
         /**
-         * Sets '$scope.sidePanelPage' to false. This variable is watched in index.tpl.html template
-         * and opens/closes side panel
+         *
+         * @param eventName
+         * @param val
          */
-        function init() {
-            $scope.rootTenants.clearData();
-            $scope.rootTenants.get('config');
-        }
-
         function broadcastFromRoot(eventName, val) {
             $scope.$broadcast(eventName, val);
         }
 
-        function setRootTenant() {
-            $scope.broadcastFromRoot('ROOT_TENANT_CHANGED');
-            enableButtons();
+        /**
+         *
+         */
+        function closeSidePanel() {
+            if($scope.sidePanelPage) {
+                $scope.sidePanelPage = false;
+                $scope.fadeAll();
+            }
         }
 
-        function closeSidePanel() {
-            $scope.sidePanelPage = false;
-            NextTopologyService.fadeInAllLayers($rootScope.nxTopology);
+        /**
+         *
+         * @param arr
+         */
+        function collapseAll(arr) {
+            arr.forEach(function(element) {
+                element.expanded = false;
+            });
         }
 
         /**
-         * fills $scope.stateUrl with loaded url
-         * It's called on $viewContentLoaded event
+         *
+         * @param source
+         * @param target
+         * @param contract
+         * @param tenant
+         * @returns {{id: string, source: *, target: *, tenant: *}}
          */
-        function setStateUrl() {
-            $scope.stateUrl = $state.current.url;
+        function createLink( source, target, contract, tenant) {
+            return {
+                'id': generateLinkId(contract, source, target),
+                'source': source,
+                'target': target,
+                'tenant': tenant,
+            };
         }
 
         /**
-         * Sets '$scope.sidePanelPage' to true. This variable is watched in index.tpl.html template
-         * and opens/closes side panel
+         *
+         * @param nodeName
+         * @param tenantId
+         * @returns {{id: *, tenantId: *, node-id: *, label: *}}
          */
-        function openSidePanel(page, object, cbk) {
-            if(object.constructor.name == 'Epg') {
-                $scope.endpoints.clearData();
-                $scope.endpoints.getByEpg(object.data.id);
-            }
-            var samePage = page === $scope.sidePanelPage;
+        function createNode(nodeName, tenantId) {
+            return {
+                'id': nodeName,
+                'tenantId' : tenantId,
+                'node-id': nodeName,
+                'label': nodeName,
+            };
+        }
 
-            $scope.selectedNode = object;
+        /**
+         *
+         */
+        function deselectContract() {
+            $scope.fadeAll();
+            $scope.sidePanelPage = 'resolved-policy/contract-sidepanel';
 
-            $scope.sidePanelCbk = cbk;
-            $scope.sidePanelPage = page;
-            $scope.sidePanelObject = object;
+            var obj = Object.keys($scope.resolvedPolicy).map(function(k) {
+                var obj = $scope.resolvedPolicy[k];
+                obj.linkId = k;
 
-            if ( samePage &&  $scope.sidePanelCbk) {
-                $scope.sidePanelCbk();
-            }
+                return obj;
+            });
+
+            $scope.sidePanelObject = obj;
+            $scope.selectedNode = null;
+            $scope.activeObject = 'contract';
         }
 
+        /**
+         *
+         */
         function deselectEpg() {
-            NextTopologyService.fadeInAllLayers($rootScope.nxTopology);
+            $scope.fadeAll();
             var elements;
 
             $scope.sidePanelPage = 'resolved-policy/epg-sidepanel';
             elements = EpgListService.createList();
-            elements.get($scope.apiType, $scope.parentTenant);
+            elements.get($scope.apiType, $scope.rootTenant);
             $scope.sidePanelObject = elements;
             $scope.selectedNode = null;
+            $scope.activeObject = 'epg';
         }
 
-        function deselectContract() {
-            NextTopologyService.fadeInAllLayers($rootScope.nxTopology);
-            $scope.sidePanelPage = 'resolved-policy/contract-sidepanel';
+        /**
+         *
+         * @param arr
+         */
+        function expandAll(arr) {
+            arr.forEach(function(element) {
+                element.expanded = true;
+            });
+        }
 
-            var obj = Object.keys($scope.resolvedPolicy).map(function(k) {
-                var obj = $scope.resolvedPolicy[k];
-                obj.linkId = k;
+        /**
+         *
+         */
+        function fadeAll() {
+            $rootScope.nxTopology && NextTopologyService.fadeInAllLayers($rootScope.nxTopology);
+        }
 
-                return obj;
-            });
+        /**
+         *
+         * @param data
+         */
+        function fillResolvedPolicy(data) {
+            if(data['policy-rule-group-with-endpoint-constraints']) {
+                processPolicyRuleGroupWithEpConstraints(
+                    data['policy-rule-group-with-endpoint-constraints'],
+                    data['provider-epg-id'],
+                    data['consumer-epg-id']);
+            }
 
-            $scope.sidePanelObject = obj;
-            $scope.selectedNode = null;
         }
 
-        function openSidePanelTpl(tpl) {
-            switch(tpl) {
-            case 'contract':
-                $scope.sidePanelPage = 'resolved-policy/contract-sidepanel';
-                break;
-            case 'subject':
-                $scope.sidePanelPage = 'resolved-policy/subject-sidepanel';
-                break;
-            case 'clause':
-                $scope.sidePanelPage = 'resolved-policy/clause-sidepanel';
-                break;
-            case 'rule':
-                $scope.sidePanelPage = 'resolved-policy/rule-sidepanel';
-                break;
+        /**
+         *
+         */
+        function fillTopologyData() {
+            if($scope.rootTenant) {
+                var topoData = {nodes: [], links: [],},
+                    filteredResolvedPolicies = $filter('filter')(resolvedPolicies.data, {
+                        'consumer-tenant-id': $scope.rootTenant,
+                        'provider-tenant-id': $scope.rootTenant
+                    });
+
+
+                filteredResolvedPolicies && filteredResolvedPolicies.forEach(function(rp) {
+                    if(rp['consumer-tenant-id'] === $scope.rootTenant) {
+                        topoData.nodes.push(createNode(rp['consumer-epg-id'], rp['consumer-tenant-id']));
+                    }
+                    topoData.nodes.push(createNode(rp['provider-epg-id'], rp['provider-tenant-id']));
+
+                    fillResolvedPolicy(rp);
+                    topoData.links = getContracts(rp);
+                });
+
+                $scope.topologyData = topoData;
+                $scope.topologyLoaded = true;
             }
         }
 
+        /**
+         *
+         * @param contractId
+         * @param providerEpgId
+         * @param consumerEpgId
+         * @returns {string}
+         */
+        function generateLinkId(contractId, providerEpgId, consumerEpgId) {
+            return contractId + '_' + providerEpgId + '_' + consumerEpgId;
+        }
+
+        /**
+         *
+         * @param data
+         * @returns {Array}
+         */
+        function getContracts(data) {
+            var retVal = [];
+
+            if( data['policy-rule-group-with-endpoint-constraints'] &&
+                data['policy-rule-group-with-endpoint-constraints'][0]['policy-rule-group']) {
+                data['policy-rule-group-with-endpoint-constraints'][0]['policy-rule-group'].forEach(function(prg) {
+                    retVal.push(
+                        createLink(
+                            data['provider-epg-id'],
+                            data['consumer-epg-id'],
+                            prg['contract-id'],
+                            prg['tenant-id']
+                        )
+                    )
+                });
+            }
+
+            return retVal;
+        }
+
+        /**
+         *
+         * @param obj
+         * @returns {*}
+         */
+        function getObjectsCount(obj) {
+            if(obj)
+                return Object.keys(obj).length;
+            else
+                return 0;
+        }
+
+        /**
+         *
+         * @param node
+         */
+        function highlightNode(node) {
+            NextTopologyService.highlightNode($rootScope.nxTopology, node);
+        }
+
+        /**
+         *
+         * @param link
+         */
+        function highlightLink(link) {
+            NextTopologyService.highlightLink($rootScope.nxTopology, link);
+        }
+
+        /**
+         *
+         */
+        function init() {
+            $scope.rootTenants.clearData();
+            $scope.rootTenants.get('config');
+        }
+
+        /**
+         *
+         * @param chainName
+         */
+        function openSfcDialog(chainName) {
+            $mdDialog.show({
+                clickOutsideToClose: true,
+                controller: 'SfcTopologyController',
+                preserveScope: true,
+                templateUrl: $scope.viewPath + 'sfc/dialog-sfc-topology.tpl.html',
+                parent: angular.element(document.body),
+                scope: $scope,
+                locals: {
+                    chainName: chainName,
+                },
+            });
+        }
+
+
+        /**
+         * Sets '$scope.sidePanelPage' to true. This variable is watched in index.tpl.html template
+         * and opens/closes side panel
+         */
+        function openSidePanel(page, object, cbk) {
+            if(object.constructor.name == 'Epg') {
+                $scope.endpoints.clearData();
+                $scope.endpoints.getByEpg(object.data.id);
+                $scope.activeObject = 'epg';
+            }
+            else
+                $scope.activeObject = 'contract';
+
+            var samePage = page === $scope.sidePanelPage;
+
+            $scope.selectedNode = object;
+
+            $scope.sidePanelCbk = cbk;
+            $scope.sidePanelPage = page;
+            $scope.sidePanelObject = object;
+
+            if ( samePage &&  $scope.sidePanelCbk) {
+                $scope.sidePanelCbk();
+            }
+        }
+
+        /**
+         *
+         * @param idElement
+         */
         function openSidePanelContract(idElement) {
             var obj = $filter('filter')(Object.keys($scope.resolvedPolicy).map(function(k) {
                 var obj = $scope.resolvedPolicy[k];
@@ -158,10 +339,16 @@ define(['app/gbp/common/gbp.service', 'app/gbp/resolved-policy/resolved-policy.s
             $scope.sidePanelPage = 'resolved-policy/contract-sidepanel';
             $scope.sidePanelObject = obj[0];
             $scope.selectedNode = obj[0];
+            $scope.activeObject = 'contract';
 
             NextTopologyService.highlightLink($rootScope.nxTopology, obj[0].linkId);
         }
 
+        /**
+         * .
+         * @param index
+         * @param type
+         */
         function openSidePanelChild(index, type) {
             switch(type) {
             case 'subject':
@@ -179,73 +366,40 @@ define(['app/gbp/common/gbp.service', 'app/gbp/resolved-policy/resolved-policy.s
             }
         }
 
-        function getObjectsCount(obj) {
-            if(obj)
-                return Object.keys(obj).length;
-            else
-                return 0;
-        }
-
-        function enableButtons() {
-            $scope.policyDisabled = false;
-        }
-
-        function toggleExpanded(element) {
-            if(typeof element !== 'string') {
-                if(element.expanded)
-                    element.expanded = false;
-                else
-                    element.expanded = true;
-            }
-        }
-
-        function expandAll(arr) {
-            arr.forEach(function(element) {
-                element.expanded = true;
-            });
-        }
-
-        function collapseAll(arr) {
-            arr.forEach(function(element) {
-                element.expanded = false;
-            });
-        }
-
-        var resolvedPolicies = ResolvedPolicyService.createObject();
-        resolvedPolicies.get(function () {
-            fillTopologyData();
-        });
-
-        function fillTopologyData() {
-            var topoData = {nodes: [], links: [],};
-
-            resolvedPolicies.data.forEach(function(rp) {
-                topoData.nodes.push(createNode(rp['consumer-epg-id'], rp['consumer-tenant-id']));
-                topoData.nodes.push(createNode(rp['provider-epg-id'], rp['provider-tenant-id']));
-
-                fillResolvedPolicy(rp);
-                topoData.links = getContracts(rp);
-            });
-
-            $scope.topologyData = topoData;
-            $scope.topologyLoaded = true;
-        }
-
-        function fillResolvedPolicy(data) {
-            if(data['policy-rule-group-with-endpoint-constraints']) {
-                processPolicyRuleGroupWithEpConstraints(
-                    data['policy-rule-group-with-endpoint-constraints'],
-                    data['provider-epg-id'],
-                    data['consumer-epg-id']);
+        /**
+         *
+         * @param tpl
+         */
+        function openSidePanelTpl(tpl) {
+            switch(tpl) {
+            case 'contract':
+                $scope.sidePanelPage = 'resolved-policy/contract-sidepanel';
+                break;
+            case 'subject':
+                $scope.sidePanelPage = 'resolved-policy/subject-sidepanel';
+                break;
+            case 'clause':
+                $scope.sidePanelPage = 'resolved-policy/clause-sidepanel';
+                break;
+            case 'rule':
+                $scope.sidePanelPage = 'resolved-policy/rule-sidepanel';
+                break;
             }
-
         }
 
+        /**
+         *
+         * @param data
+         * @param providerEpgId
+         * @param consumerEpgId
+         */
         function processPolicyRuleGroupWithEpConstraints(data, providerEpgId, consumerEpgId) {
             data.forEach(function(element) {
                 element['policy-rule-group'].forEach(function(el) {
                     var linkId = generateLinkId(el['contract-id'], providerEpgId, consumerEpgId);
 
+                    $scope.resolvedPolicy = {};
+
                     if(!$scope.resolvedPolicy.hasOwnProperty(linkId)) {
                         $scope.resolvedPolicy[linkId] = {
                             'contract-id': el['contract-id'],
@@ -258,62 +412,87 @@ define(['app/gbp/common/gbp.service', 'app/gbp/resolved-policy/resolved-policy.s
                     }
 
                     $scope.resolvedPolicy[linkId].subjects[el['subject-name']]['resolved-rule'].push(el['resolved-rule']);
-                })
-            })
-        }
-
-        function generateLinkId(contractId, providerEpgId, consumerEpgId) {
-            return contractId + '_' + providerEpgId + '_' + consumerEpgId;
+                });
+            });
         }
 
-        function createNode(nodeName, tenantId) {
-            return {
-                'id': nodeName,
-                'tenantId' : tenantId,
-                'node-id': nodeName,
-                'label': nodeName,
-            };
-        }
+        /**
+         *
+         */
+        function setRootTenant() {
+            $scope.broadcastFromRoot('ROOT_TENANT_CHANGED');
 
-        function createLink( source, target, contract, tenant) {
-            return {
-                'id': generateLinkId(contract, source, target),
-                'source': source,
-                'target': target,
-                'tenant': tenant,
-            };
+            if($scope.stateUrl.startsWith('/resolved-policy')) {
+                fillTopologyData();
+                if($scope.sidePanelPage) {
+                    if($scope.activeObject == 'epg')
+                        deselectEpg();
+                    else if($scope.activeObject == 'contract')
+                        deselectContract();
+                }
+            }
         }
 
-        function getContracts(data) {
-            var retVal = [];
+        /**
+         * fills $scope.stateUrl with loaded url
+         * It's called on $viewContentLoaded event
+         */
+        function setStateUrl() {
+            $scope.stateUrl = $state.current.url;
+            closeSidePanel();
 
-            if( data['policy-rule-group-with-endpoint-constraints'] &&
-                data['policy-rule-group-with-endpoint-constraints'][0]['policy-rule-group']) {
-                data['policy-rule-group-with-endpoint-constraints'][0]['policy-rule-group'].forEach(function(prg) {
-                        retVal.push(
-                            createLink(
-                                data['provider-epg-id'],
-                                data['consumer-epg-id'],
-                                prg['contract-id'],
-                                prg['tenant-id']
-                            )
-                        )
-                    });
+            if($scope.stateUrl.startsWith('/resolved-policy')) {
+                fillTopologyData();
             }
+        }
 
-            return retVal;
+        /**
+         *
+         * @param element
+         */
+        function toggleExpanded(element) {
+            if(typeof element !== 'string') {
+                if(element.expanded)
+                    element.expanded = false;
+                else
+                    element.expanded = true;
+            }
         }
 
-        function highlightNode(node) {
-            NextTopologyService.highlightNode($rootScope.nxTopology, node);
+        function rootOpenEndpointDialog(operation, endpointData) {
+            $scope.disableKeyFieldsEditing = operation === 'edit';
+            $mdDialog.show({
+                clickOutsideToClose: true,
+                controller: 'AddEndpointController',
+                preserveScope: true,
+                templateUrl: $scope.viewPath + 'endpoints/dialog-add-endpoint.tpl.html',
+                parent: angular.element(document.body),
+                scope: $scope,
+                locals: {
+                    endpoint: endpointData,
+                },
+            });
         }
 
-        function highlightLink(link) {
-            NextTopologyService.highlightLink($rootScope.nxTopology, link);
+        function rootDeleteEndpointDialog(endpointData) {
+            var confirm = $mdDialog.confirm()
+                .title('Delete endpoint')
+                .textContent('Do you want to delete endpoint?')
+                .ok('Delete')
+                .cancel('Cancel');
+
+            $mdDialog.show(confirm).then(function () {
+                endpointData.deleteEndpoint(function () {
+                    getEndpointsList();
+                });
+            }, function () {
+
+            });
         }
 
-        function fadeAll() {
-            NextTopologyService.fadeInAllLayers($rootScope.nxTopology);
+        function getEndpointsList() {
+            $scope.endpoints.clearData();
+            $scope.endpoints.getByEpg($scope.selectedNode.data.id);
         }
 
         /* event listeners */
@@ -321,9 +500,5 @@ define(['app/gbp/common/gbp.service', 'app/gbp/resolved-policy/resolved-policy.s
          * Event fired after content loaded, setStateUrl function is called to fill stateUrl method
          */
         $scope.$on('$viewContentLoaded', setStateUrl);
-
-        // $scope.$watch('nxTopology', function() {
-        //     $rootScope.nxTopology = $scope.nxTopology;
-        // });
     }
 });