Merge "Bug 3618: Tenant.OPER not removed when Tenant.CONF removed"
authorKeith Burns <alagalah@gmail.com>
Thu, 18 Jun 2015 22:09:45 +0000 (22:09 +0000)
committerGerrit Code Review <gerrit@opendaylight.org>
Thu, 18 Jun 2015 22:09:45 +0000 (22:09 +0000)
groupbasedpolicy-ui/module/src/main/resources/gbp/gbp.controller.js
groupbasedpolicy-ui/module/src/main/resources/gbp/gbp.css
groupbasedpolicy-ui/module/src/main/resources/gbp/gbp.services.js
groupbasedpolicy-ui/module/src/main/resources/gbp/js/joint.clean.build.js [changed mode: 0644->0755]
groupbasedpolicy-ui/module/src/main/resources/gbp/views/main/policy-renderer.tpl.html
neutron-ovsdb/src/main/java/org/opendaylight/groupbasedpolicy/neutron/ovsdb/NodeDataChangeListener.java
neutron-ovsdb/src/main/java/org/opendaylight/groupbasedpolicy/neutron/ovsdb/TerminationPointDataChangeListener.java
neutron-ovsdb/src/main/java/org/opendaylight/groupbasedpolicy/neutron/ovsdb/util/InventoryHelper.java
renderers/ofoverlay/src/main/java/org/opendaylight/groupbasedpolicy/renderer/ofoverlay/arp/ArpTasker.java
renderers/ofoverlay/src/main/java/org/opendaylight/groupbasedpolicy/renderer/ofoverlay/node/SwitchManager.java

index d4cce73d348088c298499e0f3ba984931d99a025..d139f9cff7d848d4966fcd04105c5b8e5c03d279 100755 (executable)
@@ -344,7 +344,7 @@ define(modules, function(gbp) {
 \r
                 providers.forEach(function(p) {\r
                     p.contract.forEach(function(con) {\r
-                        providerLinkItems.push(JointGraphFactory.createLink(epgItem.id, contracts[con].id, 'blue'));    \r
+                        providerLinkItems.push(JointGraphFactory.createLink(epgItem.id, contracts[con].id, 'blue'));\r
                     });\r
                 });\r
 \r
@@ -607,6 +607,7 @@ define(modules, function(gbp) {
                         JointGraphOffsetFactory.checkObjsHoffsets(itemsArray.subject ,offsetHobj.pEpg, paper);\r
                         offsetHobj.subject = JointGraphOffsetFactory.getCurrentOffset(itemsArray.subject, 'y');\r
                         JointGraphOffsetFactory.checkObjsHoffsets(itemsArray.cEpg ,offsetHobj.subject, paper);\r
+\r
                     }, function(){});\r
 \r
                 }\r
@@ -810,14 +811,17 @@ define(modules, function(gbp) {
             // init();\r
     }]);\r
 \r
-    gbp.register.controller('policyRendererCtrl', ['$scope', '$http', '$timeout', 'PGNServices', 'TopoServices', 'GBPTenantServices', 'GBPConstants',\r
-        function ($scope, $http, $timeout, PGNServices, TopoServices, GBPTenantServices, GBPConstants) {\r
+    gbp.register.controller('policyRendererCtrl', ['$scope', '$http', '$timeout', 'PGNServices', 'TopoServices', 'GBPTenantServices', 'GBPConstants', 'JointGraphFactory','GBPJointGraphBuilder',\r
+        function ($scope, $http, $timeout, PGNServices, TopoServices, GBPTenantServices, GBPConstants, JointGraphFactory, GBPJointGraphBuilder) {\r
             \r
             $scope.topologyData = { nodes: [], links: [] };\r
             $scope.topologyType = null;\r
+            $scope.topologyArgs = {};\r
             $scope.legend = {};\r
             $scope.showLegend = false;\r
 \r
+            var paper = JointGraphFactory.createGraph();\r
+\r
             var reloadShowLegend = function() {\r
                 $scope.showLegend = !$.isEmptyObject($scope.legend);\r
             };\r
@@ -838,67 +842,38 @@ define(modules, function(gbp) {
                 button: false\r
             };\r
 \r
-\r
-            // $scope.selectedTenant = null;\r
+            paper.on('cell:pointerdown', function(cellView, evt) {\r
+                if (cellView.model.isLink() && cellView.model.attributes.objData) {\r
+                    $scope.$broadcast('SET_LINK_DATA', cellView.model.attributes.objData);\r
+                }\r
+            });\r
 \r
             $scope.mandatoryProperties = [];\r
             $scope.loadTopology = function(type, args) {\r
-                if ( $scope.selectedTenant  ) {\r
-\r
-                    $scope.topologyData = { nodes: [], links: [] };\r
+                if ($scope.selectedTenant) {\r
                     $scope.topologyType = type;\r
-\r
-                    TopoServices.loadTopology(type, function(nodes, links) {\r
-                        $scope.topologyData = { nodes: nodes, links: links };\r
-                        $scope.viewTopo.box = true;\r
-                        $scope.viewTopo.button = type !== GBPConstants.strings.l2l3 && type !== null ? true : false;\r
-                        $scope.legend = TopoServices.getLegend(type);\r
-                        reloadShowLegend();\r
-                    }, function() {\r
-                        $scope.legend = {};\r
-                        reloadShowLegend();\r
-                    }, args);\r
-\r
+                    $scope.topologyArgs = args;\r
+                    GBPJointGraphBuilder.loadTopology(args, paper, type);\r
                 }\r
             };\r
-\r
-            $scope.topologyCustfunc = function(sigmaIstance, getSlowDownNum, dragListener, resize){\r
-\r
-                sigmaIstance.bind('clickStage', function(e){\r
-                  sigmaIstance.killForceAtlas2();\r
-                });\r
-\r
-                // Bind the events:\r
-                // sigmaIstance.bind('overNode outNode clickNode doubleClickNode rightClickNode', function(e) {\r
-                //   console.log(e.type, e.data.node.label, e.data.captor);\r
-                // });\r
-                // sigmaIstance.bind('overEdge outEdge clickEdge doubleClickEdge rightClickEdge', function(e) {\r
-                //   console.log(e.type, e.data.edge, e.data.captor);\r
-                // });\r
-                // sigmaIstance.bind('clickStage', function(e) {\r
-                //   console.log(e.type, e.data.captor);\r
-                // });\r
-                // sigmaIstance.bind('doubleClickStage rightClickStage', function(e) {\r
-                //   console.log(e.type, e.data.captor);\r
-                // });\r
-\r
-              };\r
-\r
             $scope.toggleExpanded = function(expand, show) {\r
                 $scope.setViewExpand('policyRendererView',expand, show, 'l2');\r
 \r
-                if($scope.policyRendererView[expand]) {\r
+                if($scope.policyRendererView[expand] && $scope.selectedTenant) {\r
+                    $scope.topologyArgs.tenantId = $scope.selectedTenant.id;\r
+\r
                     if((expand === 'epg' || expand === 'contracts' || expand === 'classifiers' || expand === 'actions' || expand === 'renderers') && ($scope.topologyType !== GBPConstants.strings.config)) {\r
-                        $scope.loadTopology(GBPConstants.strings.config, { tenantId: $scope.selectedTenant ? $scope.selectedTenant.id : null, storage: 'config' });\r
+                        $scope.loadTopology(GBPConstants.strings.config, $scope.topologyArgs);\r
                     } else if((expand === 'l2l3' || expand === 'registerEndpoint' || expand === 'registerL3PrefixEndpoint') && ($scope.topologyType !== GBPConstants.strings.l2l3)) {\r
-                        $scope.loadTopology(GBPConstants.strings.l2l3, { tenantId: $scope.selectedTenant ? $scope.selectedTenant.id : null });\r
+                        $scope.loadTopology(GBPConstants.strings.l2l3, $scope.topologyArgs);\r
                     }\r
                 }\r
             };\r
 \r
-            $scope.loadTopo = function() {\r
+            $scope.reloadTopo = function() {\r
                 if($scope.selectedTenant) {\r
-                    $scope.loadTopology($scope.topologyType, { tenantId: $scope.selectedTenant.id });\r
+                    $scope.topologyArgs.tenantId = $scope.selectedTenant.id;\r
+                    GBPJointGraphBuilder.loadTopology($scope.topologyArgs, paper, $scope.topologyType);\r
                 }\r
             };\r
 \r
@@ -936,13 +911,9 @@ define(modules, function(gbp) {
 \r
     }]);\r
 \r
-    gbp.register.controller('topoDataCtrl',['$scope', 'TopoServices',  function($scope, TopoServices){\r
+    gbp.register.controller('linkDataCtrl',['$scope', function($scope){\r
         $scope.showTable = false;\r
 \r
-        $scope.getConsProvLabel = function(edge){\r
-            return TopoServices.getConsProvLabel(edge, $scope.topologyData);\r
-        };\r
-\r
         $scope.show = function(){\r
             $scope.showTable = true;\r
         };\r
@@ -950,6 +921,12 @@ define(modules, function(gbp) {
         $scope.close = function(){\r
             $scope.showTable = false;\r
         };\r
+        \r
+        $scope.$on('SET_LINK_DATA', function(e, obj){\r
+           $scope.linkData = obj;\r
+           $scope.show();\r
+           $scope.$apply();\r
+        });\r
     }]);\r
 \r
     gbp.register.controller('crudCtrl',['$scope',  function($scope){\r
@@ -1239,6 +1216,7 @@ define(modules, function(gbp) {
         });\r
 \r
         $scope.$on('GBP_CONTRACT_RELOAD',function(){\r
+            $scope.internalView.clause = false;\r
             $scope.init();\r
         });\r
 \r
@@ -1358,6 +1336,7 @@ define(modules, function(gbp) {
         });\r
 \r
         $scope.$on('GBP_CONTRACT_RELOAD',function(){\r
+            $scope.internalView.subject = false;\r
             $scope.init();\r
         });\r
 \r
@@ -1602,6 +1581,7 @@ define(modules, function(gbp) {
         });\r
 \r
         $scope.$on('GBP_RULE_RELOAD',function(){\r
+            $scope.internalView.actionRef = false;\r
             $scope.init();\r
         });\r
 \r
@@ -1736,6 +1716,7 @@ define(modules, function(gbp) {
         });\r
 \r
         $scope.$on('GBP_RULE_RELOAD',function(){\r
+            $scope.internalView.classifierRef = false;\r
             $scope.init();\r
         });\r
 \r
@@ -1906,6 +1887,7 @@ define(modules, function(gbp) {
                     $scope.internalView.epg = false;\r
                     $scope.reloadNewObj();\r
                     $scope.internalView.edit = "view";\r
+                    $scope.reloadTopo();\r
                 }, function(){\r
                     //TODO: error cbk\r
                 });\r
@@ -1918,6 +1900,7 @@ define(modules, function(gbp) {
                 GBPEpgServices.delete(path, function(data){\r
                     $scope.init();\r
                     $scope.internalView.epg = false;\r
+                    $scope.reloadTopo();\r
                 }, function(){\r
                     //TODO: error cbk\r
                 });\r
@@ -2043,6 +2026,7 @@ define(modules, function(gbp) {
                     $scope.internalView.cns = false;\r
                     $scope.internalView.cns = "view";\r
                     $scope.reloadNewObj();\r
+                    $scope.reloadTopo();\r
                 }, function(){\r
                     //TODO: error cbk\r
                 });\r
@@ -2054,6 +2038,7 @@ define(modules, function(gbp) {
                 path = GBPConNamedSelServices.createPathObj($scope.selectedTenant.id, $scope.selectedEpg.id, $scope.selectedCNS.name);\r
                 GBPConNamedSelServices.delete(path, function(data){\r
                     $scope.init();\r
+                    $scope.reloadTopo();\r
                 }, function(){\r
                     //TODO: error cbk\r
                 });\r
@@ -2171,6 +2156,7 @@ define(modules, function(gbp) {
                     $scope.internalView.pns = false;\r
                     $scope.reloadNewObj();\r
                     $scope.internalView.cns = "view";\r
+                    $scope.reloadTopo();\r
                 }, function(){\r
                     //TODO: error cbk\r
                 });\r
@@ -2182,6 +2168,7 @@ define(modules, function(gbp) {
                 path = GBPProNamedSelServices.createPathObj($scope.selectedTenant.id, $scope.selectedEpg.id, $scope.selectedPNS.name);\r
                 GBPProNamedSelServices.delete(path, function(data){\r
                     $scope.init();\r
+                    $scope.reloadTopo();\r
                 }, function(){\r
                     //TODO: error cbk\r
                 });\r
@@ -2296,6 +2283,8 @@ define(modules, function(gbp) {
                     $scope.view.l2flood = false;\r
                     $scope.view.edit = "view";\r
                     $scope.sendReloadEventFromRoot('GBP_L2FLOOD_RELOAD');\r
+\r
+                    $scope.reloadTopo();\r
                 }, function(){\r
                     //TODO: error cbk\r
                 });\r
@@ -2310,6 +2299,8 @@ define(modules, function(gbp) {
                     $scope.view.l2flood = false;\r
                     $scope.view.edit = "view";\r
                     $scope.sendReloadEventFromRoot('GBP_L2FLOOD_RELOAD');\r
+\r
+                    $scope.reloadTopo();\r
                 }, function(){\r
                     //TODO: error cbk\r
                 });\r
@@ -2435,6 +2426,8 @@ define(modules, function(gbp) {
                     $scope.view.l2bridge = false;\r
                     $scope.view.edit = "view";\r
                     $scope.sendReloadEventFromRoot('GBP_L2BRIDGE_RELOAD');\r
+\r
+                    $scope.reloadTopo();\r
                 }, function(){\r
                     //TODO: error cbk\r
                 });\r
@@ -2449,6 +2442,8 @@ define(modules, function(gbp) {
                     $scope.view.l2bridge = false;\r
                     $scope.view.edit = "view";\r
                     $scope.sendReloadEventFromRoot('GBP_L2BRIDGE_RELOAD');\r
+\r
+                    $scope.reloadTopo();\r
                 }, function(){\r
                     //TODO: error cbk\r
                 });\r
@@ -2557,6 +2552,8 @@ define(modules, function(gbp) {
                     $scope.view.l3context = false;\r
                     $scope.view.edit = "view";\r
                     $scope.sendReloadEventFromRoot('GBP_L3CONTEXT_RELOAD');\r
+\r
+                    $scope.reloadTopo();\r
                 }, function(){\r
                     //TODO: error cbk\r
                 });\r
@@ -2571,6 +2568,8 @@ define(modules, function(gbp) {
                     $scope.view.l3context = false;\r
                     $scope.view.edit = "view";\r
                     $scope.sendReloadEventFromRoot('GBP_L3CONTEXT_RELOAD');\r
+\r
+                    $scope.reloadTopo();\r
                 }, function(){\r
                     //TODO: error cbk\r
                 });\r
@@ -2706,6 +2705,8 @@ define(modules, function(gbp) {
                     $scope.init();\r
                     $scope.view.subnet = false;\r
                     $scope.view.edit = "view";\r
+\r
+                    $scope.reloadTopo();\r
                 }, function(){\r
                     //TODO: error cbk\r
                 });\r
@@ -2719,6 +2720,8 @@ define(modules, function(gbp) {
                     $scope.init();\r
                     $scope.view.subnet = false;\r
                     $scope.view.edit = "view";\r
+\r
+                    $scope.reloadTopo();\r
                 }, function(){\r
                     //TODO: error cbk\r
                 });\r
@@ -3880,6 +3883,7 @@ define(modules, function(gbp) {
             GBPTenantServices.send(path, $scope.tenant, function(data){\r
                 $scope.wizards.accessModelWizard = false;\r
                 $scope.sendReloadEventFromRoot('GBP_GLOBAL_TENANT_RELOAD');\r
+                $scope.reloadTopo();\r
             }, function(){\r
                 //TODO: error cbk\r
             });\r
index 298d66f0f9750d8b9bd08c911aea69c20b01b876..fb2b1f7720ff60d579023cb20fb8d3a4de01e2a3 100755 (executable)
@@ -1,4 +1,3 @@
-/*GBP*/\r
 .pl0 {\r
   padding-left: 0 !important;\r
 }\r
   border-right: 5px solid #393939;\r
 }\r
 .gbpWrapper .mainNavigation .middleBox .infinityIcon {\r
-  background: transparent url('../../../src/app/gbp/images/infinity-loop.tpl.html') no-repeat center center;\r
+  background: transparent url('../../src/app/gbp/images/infinity-loop.tpl.html') no-repeat center center;\r
   width: 128px;\r
   height: 128px;\r
   margin: 11px auto 0;\r
 .connection-wrap,\r
 .marker-arrowheads {\r
   display: none;\r
-}\r
-/*-------------------YangUI import START-------------------*/\r
+}/*-------------------YangUI import START-------------------*/\r
 .gbpWrapper .customContainer {\r
   border-left: 1px solid #7a7a7a;\r
   margin: 35px 5px 5px 15px;\r
index 22a1410cb657df0b021bf0124168e8293f38359a..064fd5c9ad57b569228acd20812fd998ba75b8e5 100755 (executable)
@@ -13,6 +13,10 @@ define(['app/gbp/gbp.module', 'app/gbp/js/joint.clean.build'], function(gbp, joi
         c.strings.bridge = 'bridge';\r
         c.strings.l3ctx = 'l3ctx';\r
         c.strings.subnet = 'subnet';\r
+        c.strings.linklabel = 'linklabel';\r
+        c.strings.in = 'in';\r
+        c.strings.out = 'out';\r
+        c.strings.bi = 'bidirectional';\r
 \r
         c.strings.config = 'CONFIG';\r
         c.strings.oper = 'OPERATIONAL';\r
@@ -26,6 +30,8 @@ define(['app/gbp/gbp.module', 'app/gbp/js/joint.clean.build'], function(gbp, joi
         c.colors[c.strings.l3ctx] = '#3ADF00';\r
         c.colors[c.strings.subnet] = '#FF9933';\r
         c.colors[c.strings.sigmaTopoDefaultText] = '#fff';\r
+        c.colors[c.strings.epg] = '#8fde70';\r
+        c.colors[c.strings.linklabel] = '#3366CC';\r
 \r
         c.colors[c.strings.flood+'-'+c.strings.bridge] = '#6666FF';\r
         c.colors[c.strings.bridge+'-'+c.strings.l3ctx] = '#6666FF';\r
@@ -174,19 +180,21 @@ define(['app/gbp/gbp.module', 'app/gbp/js/joint.clean.build'], function(gbp, joi
                             'size': 1,\r
                             'x': Math.random(),\r
                             'y': Math.random(),\r
-                            'color': GBPConstants.colors[GBPConstants.strings.sigmaTopoDefault]\r
+                            'color': GBPConstants.colors[GBPConstants.strings.sigmaTopoDefault],\r
+                            'type': obj.type\r
                         };\r
 \r
                     nodes.push(nodeObj);\r
                     return nodeObj.id;\r
                 },\r
-                setEdge = function(sourceId, destId, data) {\r
+                setEdge = function(sourceId, destId, data, direction) {\r
                     var obj = {\r
                             'id': 'e' + edges.length,\r
                             'source': sourceId,\r
                             'target': destId,\r
                             'color': GBPConstants.colors[GBPConstants.strings.sigmaTopoDefault],\r
-                            'data': data\r
+                            'data': data,\r
+                            'direction' : direction\r
                             // 'type': 'curve',\r
                             // 'size' : 100\r
                         };\r
@@ -197,6 +205,26 @@ define(['app/gbp/gbp.module', 'app/gbp/js/joint.clean.build'], function(gbp, joi
                     return list.filter(function(i){\r
                         return i[prop] === val;\r
                     });\r
+                },\r
+                getDirection = function(subjects){\r
+                    var directions = [];\r
+                    if ( subjects ) {\r
+                        subjects.forEach(function(s){\r
+                            if ( s['ui-rule'] ) {\r
+                                s['ui-rule'].forEach(function(rule){\r
+                                    if ( rule['classifier-ref'] ) {\r
+                                        rule['classifier-ref'].forEach(function(classifier){\r
+                                            if ( classifier.direction && directions.indexOf(classifier.direction) === -1 ){\r
+                                                directions.push(classifier.direction);\r
+                                            }\r
+                                        });\r
+                                    }\r
+                                });\r
+                            }\r
+                        });\r
+                    }\r
+                    return directions.length === 1 ? directions[0] : directions.length > 1 ? 'bidirectional' : null;\r
+\r
                 };\r
 \r
             if(epgData) {\r
@@ -222,8 +250,11 @@ define(['app/gbp/gbp.module', 'app/gbp/js/joint.clean.build'], function(gbp, joi
                     } else {\r
                         pepgnId = getObjByProp(e['provider-endpoint-group-id'],'name', nodes)[0].id;\r
                     }\r
+\r
+                    var direction = getDirection(e['ui-subject']);\r
+\r
                     if ( cepgnId && pepgnId ) {\r
-                        setEdge(cepgnId, pepgnId, e['ui-subject']);\r
+                        setEdge(cepgnId, pepgnId, e['ui-subject'], direction);\r
                     }\r
                 });\r
             }\r
@@ -260,7 +291,8 @@ define(['app/gbp/gbp.module', 'app/gbp/js/joint.clean.build'], function(gbp, joi
                             'size': 3,\r
                             'x': Math.random(),\r
                             'y': Math.random(),\r
-                            'color': getNodeColor(srcDesc)\r
+                            'color': getNodeColor(srcDesc),\r
+                            'elemType': srcDesc\r
                         };\r
 \r
                         nid += 1;\r
@@ -2412,12 +2444,23 @@ define(['app/gbp/gbp.module', 'app/gbp/js/joint.clean.build'], function(gbp, joi
                 width: 1300,\r
                 height: 650,\r
                 model: graph,\r
-                gridSize: 1\r
+                gridSize: 1,\r
+                interactive: { vertexAdd: false }\r
             });\r
 \r
             return paper;\r
         };\r
 \r
+        jgf.resetGraphDimension = function(paper, element, paddingT, paddingL){\r
+            paddingT = paddingT ? paddingT : 0;\r
+            paddingL = paddingL ? paddingL : paddingT;\r
+\r
+            var paperWidth = element.width() - paddingL,\r
+                paperHeight = element.height() - paddingT - 5;\r
+\r
+            paper.setDimensions(paperWidth, paperHeight);\r
+        };\r
+\r
         jgf.reloadGraph = function(graph) {\r
             graph.clear();\r
         };\r
@@ -2519,22 +2562,309 @@ define(['app/gbp/gbp.module', 'app/gbp/js/joint.clean.build'], function(gbp, joi
             graph.addCells(listItem);\r
         };\r
 \r
-        jgf.createLink = function(srcId, targetId, color) {\r
-            color = color || defaulColor;\r
+        jgf.createLink = function(srcId, targetId, colorIn, colorOut, direction, objData) {\r
+            colorIn = colorIn || defaulColor;\r
+            colorOut = colorOut || defaulColor;\r
 \r
-            var link = new joint.dia.Link({\r
+            var labelTextColor = GBPConstants.colors[GBPConstants.strings.sigmaTopoDefaultText],\r
+                labelBckColor = GBPConstants.colors[GBPConstants.strings.linklabel];\r
+\r
+            var linkObj = {\r
                 source: { id: srcId },\r
-                target: { id: targetId }\r
-            });\r
+                target: { id: targetId },\r
+                attrs: {\r
+                    '.connection': { stroke: colorIn, 'stroke-width': 2, name: 'normal' },\r
+                    '.connection-wrap': { 'stroke-width': 10 } \r
+                },\r
+                objData: objData\r
+            };\r
+\r
+            if(direction === 'in' || direction == 'bidirectional' || direction === undefined || direction === null) {\r
+                linkObj.attrs['.marker-target'] = { fill: colorIn, d: 'M 10 0 L 0 5 L 10 10 z' };\r
+            }\r
+\r
+            if(direction === 'out' || direction == 'bidirectional') {\r
+                linkObj.attrs['.marker-source'] = { fill: colorOut, d: 'M 10 0 L 0 5 L 10 10 z' };\r
+            }\r
+\r
+            var link = new joint.dia.Link(linkObj);\r
+\r
+            // if(labelText) {\r
+            //     link.label(0, { position: 0.3, attrs: { text: { text: labelText, fill: labelTextColor }, rect: { stroke: labelBckColor, 'stroke-width': 20 }}});\r
+            // }\r
 \r
-            link.attr({\r
-                '.connection': { stroke: color },\r
-                '.marker-target': { fill: color, d: 'M 10 0 L 0 5 L 10 10 z' }\r
-            });\r
 \r
             return link;\r
         };\r
 \r
         return jgf;\r
     });\r
+\r
+    gbp.register.factory('GBPJointGraphBuilder', function(GBPRestangular, GBPConstants, JointGraphFactory, JointGraphOffsetFactory, TopologyDataLoaders){\r
+        var jgb = {};\r
+\r
+        var builders = {};\r
+\r
+        var buildJointData = function(paper, nodes, links) {\r
+\r
+        };\r
+\r
+        var setOperConfigTopoData = function(paper, data){\r
+            var topo = TopologyDataLoaders.getEpgTopo(data);\r
+\r
+            var offsetObj = {\r
+                    ow: 100,\r
+                    oh: 100,\r
+                    w: 100,\r
+                    h: 100\r
+                },\r
+                marginObj = {\r
+                    w: 50,\r
+                    h: 80\r
+                },\r
+                offsetHobj = {\r
+                    pEpg: 0,\r
+                    cEpg: 0,\r
+                    subject: 0\r
+                },\r
+                itemsArray = {\r
+                    epg: []\r
+                },\r
+                linksArray = [];\r
+\r
+            JointGraphFactory.resetGraphDimension(paper, $('.policyGraphWrapper'));\r
+            JointGraphFactory.reloadGraph(paper.model);\r
+\r
+            var deg2rad = function(deg){\r
+                return deg * Math.PI / 180;\r
+            };\r
+\r
+            var getXYInCircle = function(elementIndex, elementsCount, paperCenterX, paperCenterY, elementWidth, elementHeight){\r
+                var result = {x:0, y:0};\r
+                    circleMargin = 100;\r
+                    r = (paperCenterX < paperCenterY ? paperCenterX : paperCenterY ) - circleMargin;\r
+                    degs = 360 / elementsCount * (elementIndex+1) + 180;\r
+                    rads = deg2rad(degs);\r
+                \r
+                elementWidth = elementWidth ? elementWidth : GBPConstants.jointElements.minWidth;\r
+                elementHeight = elementHeight ? elementHeight : GBPConstants.jointElements.minHeight;\r
+                \r
+                if(elementWidth < GBPConstants.jointElements.minWidth){elementWidth = GBPConstants.jointElements.minWidth;}\r
+                if(elementWidth > GBPConstants.jointElements.maxWidth){elementWidth = GBPConstants.jointElements.maxWidth;}\r
+                if(elementHeight < GBPConstants.jointElements.minHeight){elementHeight = GBPConstants.jointElements.minHeight;}\r
+                if(elementHeight > GBPConstants.jointElements.maxHeight){elementHeight = GBPConstants.jointElements.maxHeight;}\r
+                    \r
+                result.x = paperCenterX + r * Math.cos(rads);\r
+                result.y = paperCenterY + r * Math.sin(rads);\r
+                \r
+                degs = degs % 360;\r
+                if(degs > 90 && degs < 270){\r
+                    result.x = result.x - elementWidth;\r
+                }\r
+                if(degs == 90 || degs == 270){\r
+                    result.x = result.x - elementWidth / 2;\r
+                }\r
+                if(degs > 180 && degs < 360){\r
+                    result.y = result.y - elementHeight;\r
+                }\r
+                if(degs === 0 || degs == 180){\r
+                    result.y = result.y - elementHeight / 2;\r
+                }\r
+                return result;\r
+            };\r
+            \r
+            var paperCenterX = (paper.options.width) / 2;\r
+            var paperCenterY = (paper.options.height) / 2;\r
+            topo.nodes.forEach(function(i, index){\r
+                var label = i.label,\r
+                    header = 'Epg',\r
+                    width =  Math.max(JointGraphFactory.getLabelLength(label.length), JointGraphFactory.getLabelLength(header.length)),\r
+                    color = GBPConstants.colors[GBPConstants.strings.epg];\r
+                    \r
+                var itemPos = getXYInCircle(index, topo.nodes.length, paperCenterX, paperCenterY, width, null);\r
+                var item = JointGraphFactory.createElement(label, itemPos.x, itemPos.y, width, null, GBPConstants.strings.epg , i, label, color, header);\r
+\r
+                itemsArray.epg.push(item);\r
+\r
+                // JointGraphOffsetFactory.updateOffsets(JointGraphOffsetFactory.createWHObj(width), offsetObj, marginObj, JointGraphOffsetFactory.createWHObj(paper.options.width, paper.options.height), paper);\r
+                JointGraphFactory.addItem(paper.model, item);\r
+            });\r
+\r
+            var getItemById = function(id, array){\r
+                var item = array.filter(function(i){\r
+                    return i.attributes.objData.id === id;\r
+                });\r
+\r
+                return item.length ? item[0] : null;\r
+            };\r
+\r
+            topo.links.forEach(function(l){\r
+                var sourceItem = getItemById(l.source, itemsArray.epg),\r
+                    targetItem = getItemById(l.target, itemsArray.epg);\r
+\r
+                if (sourceItem && targetItem) {\r
+                    var link = JointGraphFactory.createLink(sourceItem.id, targetItem.id, 'blue', 'green', l.direction, l.data);\r
+                    linksArray.push(link);\r
+                }\r
+            });\r
+\r
+            JointGraphFactory.addItemList(paper.model, linksArray);\r
+        };\r
+\r
+        jgb.loadTopology = function(args, paper, type) {\r
+            if(type === null || builders.hasOwnProperty(type) === false) {\r
+                type = GBPConstants.strings.empty;\r
+            }\r
+\r
+            builders[type](args, paper);\r
+        };\r
+\r
+        builders[GBPConstants.strings.empty] = function(args, paper) {\r
+            JointGraphFactory.reloadGraph(paper.model);\r
+        };\r
+\r
+        builders[GBPConstants.strings.config] = function(args, paper) {\r
+            var storage = args.storage || 'config',\r
+                tenantId = args.tenantId;\r
+                \r
+       \r
+            TopologyDataLoaders.getSubjectsBetweenEndpointGroups(false, tenantId, function(data){\r
+                setOperConfigTopoData(paper, data);\r
+            }, function(){});\r
+        };\r
+\r
+        builders[GBPConstants.strings.oper] = function(args, paper) {\r
+            var storage = args.storage || 'config',\r
+                tenantId = args.tenantId;\r
+\r
+            TopologyDataLoaders.getSubjectsBetweenEndpointGroups(true, tenantId, function(data){\r
+                setOperConfigTopoData(paper, data);\r
+            }, function(){});\r
+        };\r
+\r
+        builders[GBPConstants.strings.l2l3] = function(args, paper) {\r
+            var storage = args.storage || 'config',\r
+                tenantId = args.tenantId;\r
+\r
+            if(storage && tenantId) {\r
+                restObj = GBPRestangular.one('restconf').one(storage).one('policy:tenants').one('tenant').one(tenantId);\r
+\r
+                restObj.get().then(function(data) {\r
+                    var createLinks = function(srcList, srcItems, dstItems) {\r
+                        var linkItems = srcList.map(function(srcObj) {\r
+                            var linkItem = null;\r
+                            if(srcObj.parent && dstItems[srcObj.parent]) {\r
+                                linkItem = JointGraphFactory.createLink(srcItems[srcObj.id].id, dstItems[srcObj.parent].id, 'blue');\r
+                            }\r
+                            return linkItem;\r
+                        }).filter(function(linkObj) {\r
+                            return linkObj !== null;\r
+                        });\r
+\r
+                        return linkItems;\r
+                    };\r
+\r
+                    var offsetObj = {\r
+                        ow: 100,\r
+                        oh: 100,\r
+                        w: 100,\r
+                        h: 100\r
+                    },\r
+                    marginObj = {\r
+                        w: 50,\r
+                        h: 80\r
+                    },\r
+                    itemsArray = {\r
+                        l3: {},\r
+                        l2bridge: {},\r
+                        l2flood: {},\r
+                        subnets: {}\r
+                    };\r
+\r
+                    JointGraphFactory.reloadGraph(paper.model);\r
+\r
+                    data.tenant[0]['l3-context'].forEach(function(c, i) {\r
+                        var label = c.name || c.id,\r
+                            header = 'L3 context',\r
+                            color = GBPConstants.colors[GBPConstants.strings.l3ctx],\r
+                            width = Math.max(JointGraphFactory.getLabelLength(label.length), JointGraphFactory.getLabelLength(header.length));\r
+                            item = JointGraphFactory.createElement(label, offsetObj.w, offsetObj.h, width, null, GBPConstants.strings.l3ctx , c, null, color, header);\r
+\r
+                        itemsArray.l3[c.id] = item;\r
+\r
+                        JointGraphOffsetFactory.updateOffsets(JointGraphOffsetFactory.createWHObj(width), offsetObj, marginObj, JointGraphOffsetFactory.createWHObj(paper.options.width, paper.options.height), paper);\r
+                        JointGraphFactory.addItem(paper.model, item);\r
+                    });\r
+\r
+                    JointGraphOffsetFactory.resetOffsets(offsetObj, offsetObj.ow, offsetObj.h + 100);\r
+\r
+                    data.tenant[0]['l2-bridge-domain'].forEach(function(c, i) {\r
+                        var label = c.name || c.id,\r
+                            header = 'L2 bridge domain',\r
+                            color = GBPConstants.colors[GBPConstants.strings.bridge],\r
+                            width = Math.max(JointGraphFactory.getLabelLength(label.length), JointGraphFactory.getLabelLength(header.length));\r
+                            item = JointGraphFactory.createElement(label, offsetObj.w, offsetObj.h, width, null, GBPConstants.strings.bridge , c, null, color, header);\r
+\r
+                        itemsArray.l2bridge[c.id] = item;\r
+\r
+                        JointGraphOffsetFactory.updateOffsets(JointGraphOffsetFactory.createWHObj(width), offsetObj, marginObj, JointGraphOffsetFactory.createWHObj(paper.options.width, paper.options.height), paper);\r
+                        JointGraphFactory.addItem(paper.model, item);\r
+                    });\r
+\r
+                    JointGraphOffsetFactory.resetOffsets(offsetObj, offsetObj.ow, offsetObj.h + 100);\r
+\r
+                    data.tenant[0]['l2-flood-domain'].forEach(function(c, i) {\r
+                        var label = c.name || c.id,\r
+                            header = 'L2 flood domain',\r
+                            color = GBPConstants.colors[GBPConstants.strings.flood],\r
+                            width = Math.max(JointGraphFactory.getLabelLength(label.length), JointGraphFactory.getLabelLength(header.length));\r
+                            item = JointGraphFactory.createElement(label, offsetObj.w, offsetObj.h, width, null, GBPConstants.strings.flood , c, null, color, header);\r
+\r
+                        itemsArray.l2flood[c.id] = item;\r
+\r
+                        JointGraphOffsetFactory.updateOffsets(JointGraphOffsetFactory.createWHObj(width), offsetObj, marginObj, JointGraphOffsetFactory.createWHObj(paper.options.width, paper.options.height), paper);\r
+                        JointGraphFactory.addItem(paper.model, item);\r
+                    });\r
+\r
+                    JointGraphOffsetFactory.resetOffsets(offsetObj, offsetObj.ow, offsetObj.h + 100);\r
+\r
+                    data.tenant[0]['subnet'].forEach(function(c, i) {\r
+                        var label = c.name || c.id,\r
+                            header = 'Subnet',\r
+                            color = GBPConstants.colors[GBPConstants.strings.subnet],\r
+                            width = Math.max(JointGraphFactory.getLabelLength(label.length), JointGraphFactory.getLabelLength(header.length));\r
+                            item = JointGraphFactory.createElement(label, offsetObj.w, offsetObj.h, width, null, GBPConstants.strings.subnet , c, null, color, header);\r
+\r
+                        itemsArray.subnets[c.id] = item;\r
+\r
+                        JointGraphOffsetFactory.updateOffsets(JointGraphOffsetFactory.createWHObj(width), offsetObj, marginObj, JointGraphOffsetFactory.createWHObj(paper.options.width, paper.options.height), paper);\r
+                        JointGraphFactory.addItem(paper.model, item);\r
+                    });\r
+\r
+                    JointGraphOffsetFactory.resetOffsets(offsetObj, offsetObj.ow, offsetObj.oh);\r
+\r
+                    var l2bridgeL3 = createLinks(data.tenant[0]['l2-bridge-domain'], itemsArray.l2bridge, itemsArray.l3);\r
+                    JointGraphFactory.addItemList(paper.model, l2bridgeL3);\r
+\r
+                    var l2floodL2bridge = createLinks(data.tenant[0]['l2-flood-domain'], itemsArray.l2flood, itemsArray.l2bridge);\r
+                    JointGraphFactory.addItemList(paper.model, l2floodL2bridge);\r
+\r
+                    var l2floodSubnet = createLinks(data.tenant[0]['subnet'], itemsArray.subnets, itemsArray.l2flood);\r
+                    JointGraphFactory.addItemList(paper.model, l2floodSubnet);\r
+\r
+                    var l2bridgeSubnet = createLinks(data.tenant[0]['subnet'], itemsArray.subnets, itemsArray.l2bridge);\r
+                    JointGraphFactory.addItemList(paper.model, l2bridgeSubnet);\r
+\r
+                    var l3Subnet = createLinks(data.tenant[0]['subnet'], itemsArray.subnets, itemsArray.l3);\r
+                    JointGraphFactory.addItemList(paper.model, l3Subnet);\r
+\r
+                }, function() {\r
+\r
+                });\r
+            }\r
+        };\r
+\r
+\r
+        return jgb;\r
+    });\r
 });
\ No newline at end of file
index 8181f0223be23fba41a17f317cdf5bc470da551e..3efb4f2168ebcb6e05e50221fa9a998eafafa9bb 100755 (executable)
@@ -1,53 +1,39 @@
 <section ng-controller="policyRendererCtrl">\r
     <!-- TOPOLOGY -->\r
     <section class="sigmaWrapper col-md-9">\r
-        \r
-        <section class="sigmaModalWrapper" ng-show="viewTopo.box" ng-controller="topoDataCtrl">\r
-\r
-            <div class="legend" ng-show="showLegend">\r
-              <ul>\r
-                <li><span>Legend:</span></li>\r
-                <li ng-repeat="(key, value) in legend" class="clearfix">\r
-                  <div class="itemWrapper left">\r
-                    <div class="color left" style="background: {{value}};"></div>\r
-                    <div class="left text">{{key}}</div>\r
-                  </div>\r
-                </li>\r
-              </ul>\r
-            </div>\r
-\r
-            <button class="btn btn-primary" ng-show="viewTopo.button" ng-click="show()">Show topology data</button>\r
-\r
-            <div class="tableWrapper" ng-show="showTable">\r
+        <section class="sigmaModalWrapper simpleBox" ng-controller="linkDataCtrl" ng-show="showTable">\r
+            <div class="tableWrapper">\r
                 <i class="icon-remove" ng-click="close()"></i>\r
 \r
                 <div class="dataWrapper">\r
-                    <div class="rowWrapper" ng-repeat="edge in topologyData.links">\r
+                    <section ng-repeat="subject in linkData">\r
                         <section class="header">\r
-                            <label>End Point Groups:</label>\r
-                            <span class="block">{{ getConsProvLabel(edge) }}</span>\r
+                            <span class="block">{{ 'Subject: ' + subject.name }}</span>\r
                         </section>\r
 \r
-                        <section ng-repeat="subject in edge.data">\r
-                            <section ng-repeat="rule in subject['ui-rule']">\r
-                                <label class="block">Subject:{{subject.name}} - Rule:{{rule.name}}</label>\r
-                                <section ng-repeat="classifier in rule['classifier-ref']">\r
-                                    <span class="block">Classifier:</span>\r
-                                    <ul>\r
-                                        <li ng-repeat="(key, value) in classifier">{{key}}: {{value}}</li>\r
-                                    </ul>\r
-                                </section>\r
+                        <section class="ml10" ng-repeat="rule in subject['ui-rule']">\r
+                            <label class="block">Rule:{{rule.name}}</label>\r
+                            <section class="ml10" ng-repeat="classifier in rule['classifier-ref']">\r
+                                <span class="block">Classifier:</span>\r
+                                <ul>\r
+                                    <li ng-repeat="(key, value) in classifier">{{key}}: {{value}}</li>\r
+                                </ul>\r
+                            </section>\r
+                            <section ng-repeat="classifier in rule['action-ref']">\r
+                                <span class="block">Action:</span>\r
+                                <ul>\r
+                                    <li ng-repeat="(key, value) in classifier">{{key}}: {{value}}</li>\r
+                                </ul>\r
                             </section>\r
                         </section>\r
-                    </div>\r
+                    </section>\r
                 </div>\r
-                \r
             </div>\r
-\r
         </section>\r
-\r
-        <section>\r
-            <sigma-topology drag-nodes="true" topology-data="topologyData" settings-sigma="settingsSigma" settings-atlas="settingsAtlas" topology-custfunc="topologyCustfunc"></sigma-toppology>\r
+        \r
+        \r
+        <section class="policyGraphWrapper">\r
+            <div graph="graph" id="graph" grid-size="1" />\r
         </section>\r
 \r
         <div class="topoNav">\r
@@ -72,7 +58,7 @@
                 <div class="rowWrapper clearfix">\r
                     <label class="block"><span>Tenants list</span></label>\r
                     <div class="selectWrapper col-md-12">\r
-                        <select class="form-control" ng-model="selectedTenant" ng-change="setTenant(selectedTenant);loadTopo();" ng-options="getDisplayLabel(d, tenantDisplayLabel) for d in tenantList">\r
+                        <select class="form-control" ng-model="selectedTenant" ng-change="setTenant(selectedTenant); reloadTopo();" ng-options="getDisplayLabel(d, tenantDisplayLabel) for d in tenantList">\r
                             <option value="">Select option</option>\r
                         </select>\r
                     </div>\r
index 5263ca7c07a8f28c2a75f75e45720ff76a6177a2..81940fa39c745fde20ca7b01d3d7d8c9467096b0 100644 (file)
@@ -14,16 +14,21 @@ import static org.opendaylight.groupbasedpolicy.neutron.ovsdb.util.InventoryHelp
 import static org.opendaylight.groupbasedpolicy.neutron.ovsdb.util.NeutronOvsdbIidFactory.ovsdbNodeAugmentationIid;
 import static org.opendaylight.groupbasedpolicy.neutron.ovsdb.util.OvsdbHelper.getNodeFromBridgeRef;
 
+import java.util.HashMap;
 import java.util.List;
+import java.util.Map;
 import java.util.Map.Entry;
 
 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
 import org.opendaylight.controller.md.sal.binding.api.DataChangeListener;
+import org.opendaylight.controller.md.sal.binding.api.ReadWriteTransaction;
 import org.opendaylight.controller.md.sal.common.api.data.AsyncDataBroker.DataChangeScope;
 import org.opendaylight.controller.md.sal.common.api.data.AsyncDataChangeEvent;
 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
 import org.opendaylight.ovsdb.southbound.SouthboundConstants;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.ofoverlay.rev140528.nodes.node.ExternalInterfaces;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorId;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbBridgeAugmentation;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbNodeAugmentation;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbTerminationPointAugmentation;
@@ -37,6 +42,11 @@ import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
+import com.google.common.base.Strings;
+
+import static org.opendaylight.groupbasedpolicy.util.DataStoreHelper.removeIfExists;
+import static org.opendaylight.groupbasedpolicy.util.DataStoreHelper.submitToDs;
+
 public class NodeDataChangeListener implements DataChangeListener, AutoCloseable {
 
     private static final Logger LOG = LoggerFactory.getLogger(NodeDataChangeListener.class);
@@ -52,7 +62,14 @@ public class NodeDataChangeListener implements DataChangeListener, AutoCloseable
         LOG.trace("NodeDataChangeListener started");
     }
 
+    /*
+     * When vSwitch is deleted, we loose data in operational DS to determine Iid of
+     * corresponding ExternalInterfaces.
+     */
+    public static final Map<InstanceIdentifier<OvsdbNodeAugmentation>, InstanceIdentifier<ExternalInterfaces>> nodeIdByExtInterface = new HashMap<>();
+
     @Override
+    @SuppressWarnings("unchecked")
     public void onDataChanged(AsyncDataChangeEvent<InstanceIdentifier<?>, DataObject> change) {
 
         /*
@@ -62,7 +79,11 @@ public class NodeDataChangeListener implements DataChangeListener, AutoCloseable
         for (Entry<InstanceIdentifier<?>, DataObject> entry : change.getCreatedData().entrySet()) {
             if (entry.getValue() instanceof OvsdbNodeAugmentation) {
                 OvsdbNodeAugmentation ovsdbNode = (OvsdbNodeAugmentation) entry.getValue();
-                processNodeNotification(ovsdbNode);
+                InstanceIdentifier<OvsdbNodeAugmentation> key = (InstanceIdentifier<OvsdbNodeAugmentation>) entry.getKey();
+                InstanceIdentifier<ExternalInterfaces> extInterfacesIid = processNodeNotification(ovsdbNode);
+                if (extInterfacesIid != null) {
+                    nodeIdByExtInterface.put(key, extInterfacesIid);
+                }
             }
         }
 
@@ -72,7 +93,9 @@ public class NodeDataChangeListener implements DataChangeListener, AutoCloseable
         for (Entry<InstanceIdentifier<?>, DataObject> entry : change.getUpdatedData().entrySet()) {
             if (entry.getValue() instanceof OvsdbNodeAugmentation) {
                 OvsdbNodeAugmentation ovsdbNode = (OvsdbNodeAugmentation) entry.getValue();
-                processNodeNotification(ovsdbNode);
+                if (Strings.isNullOrEmpty(getProviderMapping(ovsdbNode))) {
+                    removeExternalInterfaces((InstanceIdentifier<OvsdbNodeAugmentation>) entry.getKey());
+                }
             }
         }
 
@@ -80,10 +103,10 @@ public class NodeDataChangeListener implements DataChangeListener, AutoCloseable
          * Deletions
          */
         for (InstanceIdentifier<?> iid : change.getRemovedPaths()) {
-            if (iid instanceof OvsdbTerminationPointAugmentation) {
-                /*
-                 * Remove the state from OfOverlay?
-                 */
+            if (iid.getTargetType().equals(OvsdbNodeAugmentation.class)) {
+                if (nodeIdByExtInterface.get(iid) != null) {
+                    removeExternalInterfaces((InstanceIdentifier<OvsdbNodeAugmentation>) iid);
+                }
             }
         }
     }
@@ -93,8 +116,7 @@ public class NodeDataChangeListener implements DataChangeListener, AutoCloseable
         registration.close();
     }
 
-
-    public static void processNodeNotification(OvsdbNodeAugmentation ovsdbNode) {
+    public static InstanceIdentifier<ExternalInterfaces> processNodeNotification(OvsdbNodeAugmentation ovsdbNode) {
         LOG.trace("Search for provider mapping on node {}", ovsdbNode);
         String providerPortName = getProviderMapping(ovsdbNode);
         if (providerPortName != null) {
@@ -105,9 +127,18 @@ public class NodeDataChangeListener implements DataChangeListener, AutoCloseable
                 String[] elements = nodeConnectorIdString.split(":");
                 String nodeIdString = elements[0] + ":" + elements[1];
                 NodeConnectorId ncid = getNodeConnectorId(nodeConnectorIdString);
-                addOfOverlayExternalPort(nodeIdString, ncid, dataBroker);
+                return addOfOverlayExternalPort(new NodeId(nodeIdString), ncid, dataBroker);
             }
         }
+        return null;
+    }
+
+    private void removeExternalInterfaces(InstanceIdentifier<OvsdbNodeAugmentation> iidOvsdbNodeAug){
+        InstanceIdentifier<ExternalInterfaces> iidExtInterface = nodeIdByExtInterface.get(iidOvsdbNodeAug);
+        ReadWriteTransaction wTx = dataBroker.newReadWriteTransaction();
+        removeIfExists(LogicalDatastoreType.CONFIGURATION, iidExtInterface, wTx);
+        submitToDs(wTx);
+        nodeIdByExtInterface.remove(iidOvsdbNodeAug);
     }
 
     private static NodeConnectorId getNodeConnectorId(String nodeConnectorIdString) {
index a078e2c6ab52113a10b8b6660186a44d47fa2143..343687a43077e914e35793cd41f5934374aef301 100755 (executable)
@@ -28,7 +28,9 @@ import static org.opendaylight.groupbasedpolicy.util.DataStoreHelper.readFromDs;
 
 import java.util.ArrayList;
 import java.util.Collections;
+import java.util.HashMap;
 import java.util.List;
+import java.util.Map;
 import java.util.Map.Entry;
 
 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
@@ -44,6 +46,7 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.EndpointService;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.endpoints.Endpoint;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.endpoints.EndpointKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbBridgeAugmentation;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbNodeAugmentation;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbTerminationPointAugmentation;
@@ -95,6 +98,12 @@ public class TerminationPointDataChangeListener implements DataChangeListener, A
         registration.close();
     }
 
+    /*
+     * When vSwitch is deleted, we loose data in operational DS to determine Iid of
+     * corresponding NodeId.
+     */
+    private static final Map<InstanceIdentifier<OvsdbTerminationPointAugmentation>, NodeId> nodeIdByTerminPoint = new HashMap<>();
+
     @Override
     public void onDataChanged(AsyncDataChangeEvent<InstanceIdentifier<?>, DataObject> change) {
 
@@ -105,8 +114,11 @@ public class TerminationPointDataChangeListener implements DataChangeListener, A
         for (Entry<InstanceIdentifier<?>, DataObject> entry : change.getCreatedData().entrySet()) {
             if (entry.getValue() instanceof OvsdbTerminationPointAugmentation) {
                 OvsdbTerminationPointAugmentation ovsdbTp = (OvsdbTerminationPointAugmentation) entry.getValue();
+                @SuppressWarnings("unchecked")
                 InstanceIdentifier<OvsdbTerminationPointAugmentation> ovsdbTpIid = (InstanceIdentifier<OvsdbTerminationPointAugmentation>) entry.getKey();
                 OvsdbBridgeAugmentation ovsdbBridge = getOvsdbBridgeFromTerminationPoint(ovsdbTpIid, dataBroker);
+                nodeIdByTerminPoint.put(ovsdbTpIid,
+                        new NodeId(getInventoryNodeIdString(ovsdbBridge, ovsdbTpIid, dataBroker)));
                 processOvsdbBridge(ovsdbBridge, ovsdbTp, ovsdbTpIid);
             }
         }
@@ -117,6 +129,7 @@ public class TerminationPointDataChangeListener implements DataChangeListener, A
         for (Entry<InstanceIdentifier<?>, DataObject> entry : change.getUpdatedData().entrySet()) {
             if (entry.getValue() instanceof OvsdbTerminationPointAugmentation) {
                 OvsdbTerminationPointAugmentation ovsdbTp = (OvsdbTerminationPointAugmentation) entry.getValue();
+                @SuppressWarnings("unchecked")
                 InstanceIdentifier<OvsdbTerminationPointAugmentation> ovsdbTpIid = (InstanceIdentifier<OvsdbTerminationPointAugmentation>) entry.getKey();
                 OvsdbBridgeAugmentation ovsdbBridge = getOvsdbBridgeFromTerminationPoint(ovsdbTpIid, dataBroker);
                 processOvsdbBridge(ovsdbBridge, ovsdbTp, ovsdbTpIid);
@@ -132,10 +145,7 @@ public class TerminationPointDataChangeListener implements DataChangeListener, A
                 OvsdbTerminationPointAugmentation ovsdbTp = (OvsdbTerminationPointAugmentation) old;
                 @SuppressWarnings("unchecked")
                 InstanceIdentifier<OvsdbTerminationPointAugmentation> ovsdbTpIid = (InstanceIdentifier<OvsdbTerminationPointAugmentation>) iid;
-                OvsdbBridgeAugmentation ovsdbBridge = getOvsdbBridgeFromTerminationPoint(ovsdbTpIid, dataBroker);
-                if (ovsdbBridge != null) {
-                    processRemovedTp(ovsdbBridge, ovsdbTp, ovsdbTpIid);
-                }
+                processRemovedTp(nodeIdByTerminPoint.get(ovsdbTpIid) , ovsdbTp, ovsdbTpIid);
             }
         }
     }
@@ -251,24 +261,10 @@ public class TerminationPointDataChangeListener implements DataChangeListener, A
      * @param ovsdbTp {@link OvsdbTerminationPointAugmentation}
      * @param ovsdbTpIid termination point's IID {@link InstanceIdentifier}
      */
-    private void processRemovedTp(OvsdbBridgeAugmentation ovsdbBridge, OvsdbTerminationPointAugmentation ovsdbTp,
+    private void processRemovedTp(NodeId nodeId, OvsdbTerminationPointAugmentation ovsdbTp,
             InstanceIdentifier<OvsdbTerminationPointAugmentation> ovsdbTpIid) {
-
-        checkNotNull(ovsdbBridge);
-        if (ovsdbBridge.getBridgeName().getValue().equals(ovsdbTp.getName())) {
-            LOG.debug("Termination Point {} same as Bridge {}. Not processing.", ovsdbTp.getName(),
-                    ovsdbBridge.getBridgeName().getValue());
-            return;
-        }
-
-        String nodeIdString = getInventoryNodeIdString(ovsdbBridge, ovsdbTpIid, dataBroker);
-        if (nodeIdString == null) {
-            LOG.debug("nodeIdString for TerminationPoint {} was null.", ovsdbTp);
-            return;
-        }
-
         if (isTunnelPort(ovsdbTp, requiredTunnelTypes)) {
-            removeTunnelsOfOverlayConfig(nodeIdString, requiredTunnelTypes, dataBroker);
+            removeTunnelsOfOverlayConfig(nodeId.getValue(), requiredTunnelTypes, dataBroker);
         } else {
             deleteLocationForTp(ovsdbTp);
         }
index 7ec29c0961cee178a28cd3666a0a927050e7fca9..3762b9af929f7505124a606a58edee383592ddd1 100755 (executable)
@@ -24,7 +24,6 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.ofoverlay.
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.ofoverlay.rev140528.nodes.node.ExternalInterfacesKey;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.ofoverlay.rev140528.nodes.node.Tunnel;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.ofoverlay.rev140528.nodes.node.TunnelBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.ofoverlay.rev140528.nodes.node.TunnelKey;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorId;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.Nodes;
@@ -38,9 +37,7 @@ import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 import java.util.ArrayList;
-import java.util.HashSet;
 import java.util.List;
-import java.util.Set;
 
 import static org.opendaylight.groupbasedpolicy.neutron.ovsdb.util.OvsdbHelper.getOvsdbBridgeFromTerminationPoint;
 import static org.opendaylight.groupbasedpolicy.neutron.ovsdb.util.OvsdbHelper.getOvsdbTerminationPoint;
@@ -168,9 +165,9 @@ public class InventoryHelper {
         return true;
     }
 
-    public static void addOfOverlayExternalPort(String nodeIdString, NodeConnectorId ncId, DataBroker dataBroker) {
+    public static InstanceIdentifier<ExternalInterfaces> addOfOverlayExternalPort(NodeId nodeId, NodeConnectorId ncId, DataBroker dataBroker) {
         InstanceIdentifier<ExternalInterfaces> nodeExternalInterfacesIid = InstanceIdentifier.builder(Nodes.class)
-            .child(Node.class, new NodeKey(new NodeId(nodeIdString)))
+            .child(Node.class, new NodeKey(nodeId))
             .augmentation(OfOverlayNodeConfig.class)
             .child(ExternalInterfaces.class, new ExternalInterfacesKey(ncId))
             .build();
@@ -181,7 +178,8 @@ public class InventoryHelper {
         WriteTransaction transaction = dataBroker.newReadWriteTransaction();
         transaction.put(LogicalDatastoreType.CONFIGURATION, nodeExternalInterfacesIid, externalInterfaces, true);
         submitToDs(transaction);
-        LOG.trace("Added external interface node connector {} to node {}", ncId.getValue(), nodeIdString);
+        LOG.trace("Added external interface node connector {} to node {}", ncId.getValue(), nodeId.getValue());
+        return nodeExternalInterfacesIid;
     }
 
     public static OfOverlayNodeConfig getOfOverlayConfig(String nodeIdString, DataBroker dataBroker) {
@@ -199,17 +197,6 @@ public class InventoryHelper {
         return null;
     }
 
-    private static boolean addOfOverlayAugmentation(OfOverlayNodeConfig config, String nodeIdString, DataBroker dataBroker) {
-        InstanceIdentifier<OfOverlayNodeConfig> ofOverlayNodeIid = InstanceIdentifier.builder(Nodes.class)
-            .child(Node.class, new NodeKey(new NodeId(nodeIdString)))
-            .augmentation(OfOverlayNodeConfig.class)
-            .build();
-
-        WriteTransaction transaction = dataBroker.newReadWriteTransaction();
-        transaction.put(LogicalDatastoreType.CONFIGURATION, ofOverlayNodeIid, config, true);
-        return submitToDs(transaction);
-    }
-
     /**
      * Update the {@link OfOverlayConfig} of an Inventory Node
      * using the new tunnel state.
@@ -283,7 +270,7 @@ public class InventoryHelper {
             ofOverlayNodeConfigBuilder.setTunnel(new ArrayList<Tunnel>(existingTunnels));
         }
         OfOverlayNodeConfig newConfig = ofOverlayNodeConfigBuilder.build();
-        if (addOfOverlayAugmentation(newConfig, nodeIdString, dataBroker)) {
+        if (addTunnelsOfOverlayConfig(newConfig.getTunnel(), new NodeId(nodeIdString), dataBroker)) {
             LOG.trace("updateOfOverlayConfig - Added Tunnel: {} to Node: {} at NodeConnector: {}",tunnelBuilder.build(), nodeIdString, nodeConnectorIdString);
             return;
         } else {
@@ -315,14 +302,31 @@ public class InventoryHelper {
 
         // runs only if some tunnels were really removed
         if (existingTunnels.removeAll(tunnelsToRemove)) {
-            OfOverlayNodeConfigBuilder ofOverlayBuilder;
-            if (ofConfig == null) {
-                ofOverlayBuilder = new OfOverlayNodeConfigBuilder();
-            } else {
-                ofOverlayBuilder = new OfOverlayNodeConfigBuilder(ofConfig);
+            ReadWriteTransaction wTx = dataBroker.newReadWriteTransaction();
+            for (Tunnel tunnel : tunnelsToRemove) {
+                InstanceIdentifier<Tunnel> tunnelIid = InstanceIdentifier.builder(Nodes.class)
+                    .child(Node.class, new NodeKey(new NodeId(nodeIdString)))
+                    .augmentation(OfOverlayNodeConfig.class)
+                    .child(Tunnel.class, tunnel.getKey())
+                    .build();
+                wTx.delete(LogicalDatastoreType.CONFIGURATION, tunnelIid);
+                LOG.trace("Removing tunnel: {} from node {}",tunnel, nodeIdString);
             }
-            ofOverlayBuilder.setTunnel(existingTunnels);
-            addOfOverlayAugmentation(ofOverlayBuilder.build(), nodeIdString, dataBroker);
+            submitToDs(wTx);
+        }
+    }
+
+    private static boolean addTunnelsOfOverlayConfig(List<Tunnel> tunnels, NodeId nodeId, DataBroker dataBroker) {
+        ReadWriteTransaction wTx = dataBroker.newReadWriteTransaction();
+        for (Tunnel tunnel : tunnels) {
+            InstanceIdentifier<Tunnel> tunnelIid = InstanceIdentifier.builder(Nodes.class)
+                .child(Node.class, new NodeKey(nodeId))
+                .augmentation(OfOverlayNodeConfig.class)
+                .child(Tunnel.class, tunnel.getKey())
+                .build();
+            wTx.put(LogicalDatastoreType.CONFIGURATION, tunnelIid, tunnel, true);
+            LOG.trace("Adding tunnel: {} to node {}",tunnel, nodeId.getValue());
         }
+        return submitToDs(wTx);
     }
 }
index 96db98ba8f9adb5ae7633a57c3d0388c9d614fda..2689fa9dce98e5a4d9f47e45cde043599b4b37da 100644 (file)
@@ -320,6 +320,12 @@ public class ArpTasker implements PacketProcessingListener {
         List<Node> nodes = potentialNodes.get().getNode();
         SetMultimap<Node, NodeConnectorId> extIfacesByNode = HashMultimap.create();
         for (Node node : nodes) {
+            Optional<Node> potentialNodeFromOper = DataStoreHelper.readFromDs(LogicalDatastoreType.OPERATIONAL,
+                    InstanceIdentifier.builder(Nodes.class).child(Node.class, node.getKey()).build(), rTx);
+            if (!potentialNodeFromOper.isPresent()) {
+                LOG.debug("Node exists in CONF DS but not in OPER DS. Node from CONF: {}", node);
+                continue;
+            }
             OfOverlayNodeConfig ofOverlayNode = node.getAugmentation(OfOverlayNodeConfig.class);
             if (ofOverlayNode != null) {
                 List<ExternalInterfaces> externalIfaces = ofOverlayNode.getExternalInterfaces();
index 3ec0a16aa0eedf3615730a1adfbee6e7a573ee19..6c007a7dd1df5a582599fdc8e74db98309a2a797 100644 (file)
@@ -103,7 +103,7 @@ public class SwitchManager implements AutoCloseable {
             LOG.error("No SwitchState for {} in deactivatingSwitch. This should not happen.",nodeId);
             return;
         }
-        state.setHasEndpoints(false);;
+        state.setHasEndpoints(false);
         state.updateStatus();
     }
 
@@ -136,8 +136,9 @@ public class SwitchManager implements AutoCloseable {
 
     public synchronized Set<NodeConnectorId> getExternalPorts(NodeId nodeId) {
         SwitchState state = switches.get(nodeId);
-        if (state == null)
+        if (state == null) {
             return Collections.emptySet();
+        }
         return ImmutableSet.copyOf(state.externalPorts);
     }
 
@@ -407,12 +408,15 @@ public class SwitchManager implements AutoCloseable {
         }
 
         public boolean isConfigurationEmpty() {
-            if (fcNode != null)
+            if (fcNode != null) {
                 return false;
-            if (nodeConfig != null)
+            }
+            if (nodeConfig != null) {
                 return false;
-            if (!fcncByNcIid.isEmpty())
+            }
+            if (!fcncByNcIid.isEmpty()) {
                 return false;
+            }
             return true;
         }