2 * Copyright (C) 2014 SDN Hub
4 * Licensed under the GNU GENERAL PUBLIC LICENSE, Version 3.
5 * You may not use this file except in compliance with this License.
6 * You may obtain a copy of the License at
8 * http://www.gnu.org/licenses/gpl-3.0.txt
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
18 var hostSwitchLinkList = [];
20 var url = "http://" + location.hostname + ":8080";
21 var graph = new joint.dia.Graph;
22 var erd = joint.shapes.erd;
24 var element = function(elm, x, y, label) {
25 var cell = new elm({ position: { x: x, y: y }, size: { width: 150, height: 30 },
26 attrs: { text: { text: label }}});
29 rect: { fill: '#2C3E50', rx: 5, ry: 5, 'stroke-width': 2, stroke: 'black' },
32 'font-size': 16, 'font-weight': 'bold', 'font-variant': 'small-caps', 'text-transform': 'capitalize'
39 var link = function(elm1, elm2) {
41 var cell = new erd.Line({ source: { id: elm1.id }, target: { id: elm2.id },
42 attrs : { '.connection': { stroke: 'blue' } },
43 labels: [{ text: {'font-size': 10 } },
44 { text: {'font-size': 10 } }]
55 var getSwitchDesc = function(dpid) {
56 var ofctl_dpid = parseInt(dpid, 16);
57 $.getJSON(url.concat("/stats/desc/").concat(ofctl_dpid), function(descs){
58 $.each(descs, function(key, value){
59 var valueJson = JSON.stringify(value);
60 var switchDesc = JSON.parse(valueJson);
62 switchList[dpid]['desc'] = switchDesc;
64 }).then(setSwitchTooltip);
67 var getDom = function(modelId) {
68 var elems = document.getElementsByClassName("element");
69 for (i=0;i < elems.length; i++) {
70 dom = document.getElementById(elems[i].id);
71 if (modelId == dom.getAttribute("model-id"))
77 var setSwitchTooltip = function() {
78 $.each(switchList, function(dpid, value) {
79 var rectDom = getDom(value.element.id);
80 if (rectDom != undefined && value.desc != undefined) {
81 value['tooltip'] = new joint.ui.Tooltip({
83 content: '<span>Switch ' + value['name'] + '</span>' +
85 '<tr><td>H/w type:</td><td>' + value.desc.hw_desc + '</td></tr>' +
86 '<tr><td>S/w version:</td><td>' + value.desc.sw_desc + '</td></tr>' +
87 '<tr><td>Vendor:</td><td>' + value.desc.mfr_desc + '</td></tr>' +
88 '<tr><td>Serial #:</td><td>' + value.desc.serial_num + '</td></tr>' +
89 '<tr><td>Description:</td><td>' + value.desc.dp_desc + '</td></tr>' +
98 var hostCleanup = function(currentHosts) {
99 $.each(hostList, function(key, value){
100 value.tooltip.remove();
106 if (!(key in currentHosts))
107 value.element.remove();
111 var drawHosts = function() {
115 $.getJSON(url.concat("/v1.0/hosts"), function(hosts){
116 //Remove old tooltips and host links
119 $.each(hosts, function(key, value){
120 //Do all common stuff for an IP
121 if (!(key in hostList))
124 if (!('element' in hostList[key])) {
125 var x = 1000, y=1000;
126 var cell = new erd.Normal({ position: { x: x, y: y }, attrs: { text: { text: key }}});
129 hostList[key]['element'] = cell;
130 hostList[key]['dom'] = getDom(cell.id);
133 hostList[key]['entry'] = value;
134 var hostDom = hostList[key]['dom'];
135 var cell = hostList[key]['element'];
137 if (value.dpid in switchList && hostDom != undefined) {
138 var date = new Date(value.timestamp * 1000);
139 var dateStr = (date.getMonth() + 1) + "/" +
140 date.getDate() + "/" +
141 date.getFullYear() + " " +
142 date.getHours() + ":" +
143 date.getMinutes() + ":" +
146 hostList[key]['tooltip'] = new joint.ui.Tooltip({
149 '<tr><td>IP:</td><td>' + key + '</td></tr>' +
150 '<tr><td>MAC:</td><td>' + value.mac + '</td></tr>' +
151 '<tr><td>Assoc switch:</td><td>' + value.dpid + '</td></tr>' +
152 '<tr><td>Assoc port:</td><td>' + value.port + '</td></tr>' +
153 '<tr><td>Time seen:</td><td>' + dateStr + '</td></tr>' +
160 hostList[key]['link'] =link(switchList[value.dpid]['element'], cell);
167 joint.layout.DirectedGraph.layout(graph, { setLinkVertices: false, edgeSep: 20, rankSep: 80, nodeSep: 50 });
174 var drawLinks = function() {
177 $.getJSON(url.concat("/v1.0/topology/links"), function(links){
178 $.each(links, function(key, value){
179 var valueJson = JSON.stringify(value);
180 var obj = JSON.parse(valueJson);
182 var portname = obj.src.name;
185 link(switchList[obj.src.dpid]['element'],
186 switchList[obj.dst.dpid]['element']).cardinality(portname);
189 joint.layout.DirectedGraph.layout(graph, { setLinkVertices: false, edgeSep: 20, rankSep: 80, nodeSep: 80 });
197 var paperScroller = new joint.ui.PaperScroller;
199 var paper = new joint.dia.Paper({
200 el: paperScroller.el,
206 paperScroller.options.paper = paper;
207 $('#paper-container').append(paperScroller.render().el);
208 paper.on('blank:pointerdown', paperScroller.startPanning);
210 $.getJSON(url.concat("/v1.0/topology/switches"), function(switches){
212 $.each(switches, function(index, value){
213 var valueJson = JSON.stringify(value);
214 var obj = JSON.parse(valueJson);
216 switchList[obj.dpid] = {}
218 var switchName = obj.dpid;
219 switchList[obj.dpid]['name'] = switchName;
221 var x = 200 + 150 * (index % 4);
222 var y = 100 + 150 * Math.floor(index/4);
224 //console.log("DPID: " + obj.dpid + " X = "+x + " Y = "+y)
225 switchList[obj.dpid]['element'] = element(joint.shapes.basic.Rect, x, y, switchName);
227 getSwitchDesc(obj.dpid);
228 //console.log(switchList[obj.dpid]['element'])
233 paper.on('cell:pointerdown',
234 function(cellView, evt, x, y) {
235 $.each(switchList, function(key, value) {
236 if (value.id == cellView.model.id) {
237 console.log("Clicked " + key);
242 var drawHostIntervalD = setInterval(function(){drawHosts()}, 10000);
246 graph.on('change:position', function(cell) {
247 var parentId = cell.get('parent');
248 if (!parentId) return;
250 var parent = graph.getCell(parentId);
251 var parentBbox = parent.getBBox();
252 var cellBbox = cell.getBBox();
254 if (parentBbox.containsPoint(cellBbox.origin()) &&
255 parentBbox.containsPoint(cellBbox.topRight()) &&
256 parentBbox.containsPoint(cellBbox.corner()) &&
257 parentBbox.containsPoint(cellBbox.bottomLeft())) {
259 // All the four corners of the child are inside
264 // Revert the child position.
265 cell.set('position', cell.previous('position'));