\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
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
// 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
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
\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
$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
});\r
\r
$scope.$on('GBP_CONTRACT_RELOAD',function(){\r
+ $scope.internalView.clause = false;\r
$scope.init();\r
});\r
\r
});\r
\r
$scope.$on('GBP_CONTRACT_RELOAD',function(){\r
+ $scope.internalView.subject = false;\r
$scope.init();\r
});\r
\r
});\r
\r
$scope.$on('GBP_RULE_RELOAD',function(){\r
+ $scope.internalView.actionRef = false;\r
$scope.init();\r
});\r
\r
});\r
\r
$scope.$on('GBP_RULE_RELOAD',function(){\r
+ $scope.internalView.classifierRef = false;\r
$scope.init();\r
});\r
\r
$scope.internalView.epg = false;\r
$scope.reloadNewObj();\r
$scope.internalView.edit = "view";\r
+ $scope.reloadTopo();\r
}, function(){\r
//TODO: error cbk\r
});\r
GBPEpgServices.delete(path, function(data){\r
$scope.init();\r
$scope.internalView.epg = false;\r
+ $scope.reloadTopo();\r
}, function(){\r
//TODO: error cbk\r
});\r
$scope.internalView.cns = false;\r
$scope.internalView.cns = "view";\r
$scope.reloadNewObj();\r
+ $scope.reloadTopo();\r
}, function(){\r
//TODO: error cbk\r
});\r
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
$scope.internalView.pns = false;\r
$scope.reloadNewObj();\r
$scope.internalView.cns = "view";\r
+ $scope.reloadTopo();\r
}, function(){\r
//TODO: error cbk\r
});\r
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
$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
$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
$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
$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
$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
$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
$scope.init();\r
$scope.view.subnet = false;\r
$scope.view.edit = "view";\r
+\r
+ $scope.reloadTopo();\r
}, function(){\r
//TODO: error cbk\r
});\r
$scope.init();\r
$scope.view.subnet = false;\r
$scope.view.edit = "view";\r
+\r
+ $scope.reloadTopo();\r
}, function(){\r
//TODO: error cbk\r
});\r
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
-/*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
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
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
'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
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
} 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
'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
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
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
<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
<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
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;
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);
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) {
/*
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);
+ }
}
}
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());
+ }
}
}
* 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);
+ }
}
}
}
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) {
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) {
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;
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;
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) {
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);
}
}
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);
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);
}
}
}
* @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);
}
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;
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;
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();
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) {
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.
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 {
// 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);
}
}
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();
LOG.error("No SwitchState for {} in deactivatingSwitch. This should not happen.",nodeId);
return;
}
- state.setHasEndpoints(false);;
+ state.setHasEndpoints(false);
state.updateStatus();
}
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);
}
}
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;
}