import logging
import threading
-from flask import Flask
+from flask import Flask, send_from_directory
from flask_restful import Api
from gevent.pywsgi import WSGIServer
self.connectDCNetwork(DCnetwork)
# setup Flask
- # find directory of dashboard files
- dashboard_file = pkg_resources.resource_filename(
- 'emuvim.dashboard', "index.html")
- dashboard_dir = path.dirname(dashboard_file)
- logging.info("Started emu dashboard: {0}".format(dashboard_dir))
-
- self.app = Flask(__name__, static_folder=dashboard_dir,
- static_url_path='/dashboard')
+ self.app = Flask(__name__)
self.api = Api(self.app)
- # setup endpoints
+ # define dashboard endpoints
+ db_dir, db_file = self.get_dashboard_path()
+ @self.app.route('/dashboard/<path:path>')
+ def db_file(path):
+ logging.info("[DB] Serving: {}".format(path))
+ return send_from_directory(db_dir, path)
+ # define REST API endpoints
# compute related actions (start/stop VNFs, get info)
self.api.add_resource(
Compute, "/restapi/compute/<dc_label>/<compute_name>")
logging.debug("Created API endpoint %s(%s:%d)" %
(self.__class__.__name__, self.ip, self.port))
+ def get_dashboard_path(self):
+ """
+ Return absolute path to dashboard files.
+ """
+ db_file = pkg_resources.resource_filename(
+ 'emuvim.dashboard', "index.html")
+ db_dir = path.dirname(db_file)
+ logging.info("[DB] Serving emulator dashboard from: {} and {}"
+ .format(db_dir, db_file))
+ return db_dir, db_file
+
def connectDatacenter(self, dc):
compute.dcs[dc.label] = dc
logging.info(
partner consortium (www.sonata-nfv.eu).
-->
-# son-emu Dashboard
+# vim-emu dashbaord
-A simple web-based dashboard that polls the REST API and displays running services etc. It does not do much more than son-cli but it looks nicer and improves the visualization of the emulator state for live demos.
+Reachable under `<vim-emu-host>:<rest-api-port>/dashboard/dashboard.html`.
--- /dev/null
+<!--
+ Copyright (c) 2017 SONATA-NFV and Paderborn University
+ ALL RIGHTS RESERVED.
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+
+ Neither the name of the SONATA-NFV, Paderborn University
+ nor the names of its contributors may be used to endorse or promote
+ products derived from this software without specific prior written
+ permission.
+
+ This work has been performed in the framework of the SONATA project,
+ funded by the European Commission under Grant number 671517 through
+ the Horizon 2020 and 5G-PPP programmes. The authors would like to
+ acknowledge the contributions of their colleagues of the SONATA
+ partner consortium (www.sonata-nfv.eu).
+-->
+
+<!DOCTYPE html>
+<html lang="en">
+<head>
+ <meta charset="utf-8">
+ <meta http-equiv="X-UA-Compatible" content="IE=edge">
+ <meta name="viewport" content="width=device-width, initial-scale=1">
+ <!-- The above 3 meta tags *must* come first in the head; any other head content must come *after* these tags -->
+ <title>VIM-EMU Dashboard</title>
+
+ <!-- Bootstrap -->
+ <!--<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet">-->
+ <link href="https://maxcdn.bootstrapcdn.com/bootswatch/3.3.7/flatly/bootstrap.min.css" rel="stylesheet" integrity="sha384-+ENW/yibaokMnme+vBLnHMphUYxHs34h9lpdbSLuAwGkOKFRl4C34WkjazBtb7eT" crossorigin="anonymous">
+
+ <link href="css/main.css" rel="stylesheet">
+
+ <!-- jQuery -->
+ <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.1.1/jquery.min.js" type="text/javascript"></script>
+ <!--<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.jss" type="text/javascript"></script>-->
+ <script src="https://cdnjs.cloudflare.com/ajax/libs/bootbox.js/4.4.0/bootbox.min.js" type="text/javascript"></script>
+
+ <!-- HTML5 shim and Respond.js for IE8 support of HTML5 elements and media queries -->
+ <!-- WARNING: Respond.js doesn't work if you view the page via file:// -->
+ <!--[if lt IE 9]>
+ <script src="https://oss.maxcdn.com/html5shiv/3.7.2/html5shiv.min.js"></script>
+ <script src="https://oss.maxcdn.com/respond/1.4.2/respond.min.js"></script>
+ <![endif]-->
+
+ <script src="js/main.js" type="text/javascript"></script>
+
+
+</head>
+<style>
+
+.link {
+ stroke: #ccc;
+}
+
+.node text {
+ pointer-events: none;
+ font: 15px sans-serif;
+}
+
+</style>
+<body>
+ <div id="page-top" class="fixed-top">
+ <div class="row">
+ <div class="col-sm-4"><h1>VIM-EMU Dashboard</h1></div>
+ <div class="col-sm-8 text-right">
+ <img src="https://peuster.de/vimemu_dashboard_resources/upb.png">
+ <img src="https://peuster.de/vimemu_dashboard_resources/tango.png">
+ <img src="https://peuster.de/vimemu_dashboard_resources/osm.png">
+ </div>
+ </div>
+ </div>
+
+ <div id="content">
+
+
+<div class="panel panel-primary">
+ <!-- Default panel contents -->
+ <div class="panel-heading"><span>Emulated Datacenters</span> <span class="badge" id="lbl_datacenter_count">0</span><span class="pull-right" id="lbl_lateness_datacenter">Lateness: -</span></div>
+ <!-- Table -->
+ <table class="table table-striped table-hover" id="table_datacenter">
+ </table>
+</div>
+
+<div class="spacer"> </div>
+
+<div class="panel panel-primary">
+ <!-- Default panel contents -->
+ <div class="panel-heading"><span>Running Containers</span> <span class="badge" id="lbl_container_count">0</span><span class="pull-right" id="lbl_lateness_container">Lateness: -</span></div>
+ <!-- Table -->
+ <table class="table table-striped table-hover" id="table_container">
+ </table>
+</div>
+
+<div class="spacer"> </div>
+
+<div class="panel panel-primary">
+ <div class="panel-heading"><span>Deployment Graph</span> </div>
+ <table class="table table-striped table-hover" id="table_graph">
+
+ </table>
+</div>
+ <script src="https://d3js.org/d3.v3.min.js"></script>
+ <script src="js/graph.js" type="text/javascript"></script>
+
+
+</div>
+
+<footer class="footer text-center small">(c) 2019 by ETSI OSM, 5GTANGO consortium, SONATA-NFV consortium, Paderborn University and IMEC</footer>
+
+
+</body>
+
+</html>
+++ /dev/null
-<!--
- Copyright (c) 2017 SONATA-NFV and Paderborn University
- ALL RIGHTS RESERVED.
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
-
- Neither the name of the SONATA-NFV, Paderborn University
- nor the names of its contributors may be used to endorse or promote
- products derived from this software without specific prior written
- permission.
-
- This work has been performed in the framework of the SONATA project,
- funded by the European Commission under Grant number 671517 through
- the Horizon 2020 and 5G-PPP programmes. The authors would like to
- acknowledge the contributions of their colleagues of the SONATA
- partner consortium (www.sonata-nfv.eu).
--->
-
-<!DOCTYPE html>
-<html lang="en">
-<head>
- <meta charset="utf-8">
- <meta http-equiv="X-UA-Compatible" content="IE=edge">
- <meta name="viewport" content="width=device-width, initial-scale=1">
- <!-- The above 3 meta tags *must* come first in the head; any other head content must come *after* these tags -->
- <title>Emulator Dashboard</title>
-
- <!-- Bootstrap -->
- <!--<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet">-->
- <link href="https://maxcdn.bootstrapcdn.com/bootswatch/3.3.7/flatly/bootstrap.min.css" rel="stylesheet" integrity="sha384-+ENW/yibaokMnme+vBLnHMphUYxHs34h9lpdbSLuAwGkOKFRl4C34WkjazBtb7eT" crossorigin="anonymous">
-
- <link href="css/main.css" rel="stylesheet">
-
- <!-- jQuery -->
- <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.1.1/jquery.min.js" type="text/javascript"></script>
- <!--<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.jss" type="text/javascript"></script>-->
- <script src="https://cdnjs.cloudflare.com/ajax/libs/bootbox.js/4.4.0/bootbox.min.js" type="text/javascript"></script>
-
- <!-- HTML5 shim and Respond.js for IE8 support of HTML5 elements and media queries -->
- <!-- WARNING: Respond.js doesn't work if you view the page via file:// -->
- <!--[if lt IE 9]>
- <script src="https://oss.maxcdn.com/html5shiv/3.7.2/html5shiv.min.js"></script>
- <script src="https://oss.maxcdn.com/respond/1.4.2/respond.min.js"></script>
- <![endif]-->
-
-
-
- <script src="js/main.js" type="text/javascript"></script>
-
-
-</head>
-<style>
-
-.link {
- stroke: #ccc;
-}
-
-.node text {
- pointer-events: none;
- font: 15px sans-serif;
-}
-
-</style>
-<body>
- <div id="page-top">
- <div class="row">
- <div class="col-sm-8"><h1>Emulator Dashboard</h1></div>
- </div>
-
-
-
-</div>
- <div id="content">
-
-
-<div class="panel panel-primary">
- <!-- Default panel contents -->
- <div class="panel-heading"><span>Emulated Datacenters</span> <span class="badge" id="lbl_datacenter_count">0</span><span class="pull-right" id="lbl_lateness_datacenter">Lateness: -</span></div>
- <!-- Table -->
- <table class="table table-striped table-hover" id="table_datacenter">
- </table>
-</div>
-
-<div class="spacer"> </div>
-
-<div class="panel panel-primary">
- <!-- Default panel contents -->
- <div class="panel-heading"><span>Running Containers</span> <span class="badge" id="lbl_container_count">0</span><span class="pull-right" id="lbl_lateness_container">Lateness: -</span></div>
- <!-- Table -->
- <table class="table table-striped table-hover" id="table_container">
- </table>
-</div>
-
-<div class="spacer"> </div>
-
-<div class="panel panel-primary">
- <div class="panel-heading"><span>Placement Graph</span> </div>
- <table class="table table-striped table-hover" id="table_graph">
-
- </table>
-</div>
- <script src="js/d3.v3.min.js"></script>
- <script src="js/graph.js" type="text/javascript"></script>
-
-</div>
-
-<footer class="footer text-center small">(c) 2017 by SONATA Consortium and Paderborn University and IMEC</footer>
-
-
-</body>
-
-</html>
+++ /dev/null
-<!--
- Copyright (c) 2017 SONATA-NFV and Paderborn University
- ALL RIGHTS RESERVED.
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
-
- Neither the name of the SONATA-NFV, Paderborn University
- nor the names of its contributors may be used to endorse or promote
- products derived from this software without specific prior written
- permission.
-
- This work has been performed in the framework of the SONATA project,
- funded by the European Commission under Grant number 671517 through
- the Horizon 2020 and 5G-PPP programmes. The authors would like to
- acknowledge the contributions of their colleagues of the SONATA
- partner consortium (www.sonata-nfv.eu).
--->
-
-<!DOCTYPE html>
-<html lang="en">
-<head>
- <meta charset="utf-8">
- <meta http-equiv="X-UA-Compatible" content="IE=edge">
- <meta name="viewport" content="width=device-width, initial-scale=1">
- <!-- The above 3 meta tags *must* come first in the head; any other head content must come *after* these tags -->
- <title>Emulator Dashboard</title>
-
- <!-- Bootstrap -->
- <!--<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet">-->
- <link href="https://maxcdn.bootstrapcdn.com/bootswatch/3.3.7/flatly/bootstrap.min.css" rel="stylesheet" integrity="sha384-+ENW/yibaokMnme+vBLnHMphUYxHs34h9lpdbSLuAwGkOKFRl4C34WkjazBtb7eT" crossorigin="anonymous">
-
- <link href="css/main.css" rel="stylesheet">
-
- <!-- jQuery -->
- <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.1.1/jquery.min.js" type="text/javascript"></script>
- <!--<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.jss" type="text/javascript"></script>-->
- <script src="https://cdnjs.cloudflare.com/ajax/libs/bootbox.js/4.4.0/bootbox.min.js" type="text/javascript"></script>
-
- <!-- HTML5 shim and Respond.js for IE8 support of HTML5 elements and media queries -->
- <!-- WARNING: Respond.js doesn't work if you view the page via file:// -->
- <!--[if lt IE 9]>
- <script src="https://oss.maxcdn.com/html5shiv/3.7.2/html5shiv.min.js"></script>
- <script src="https://oss.maxcdn.com/respond/1.4.2/respond.min.js"></script>
- <![endif]-->
-
- <script src="js/main_upb.js" type="text/javascript"></script>
-
-
-</head>
-<style>
-
-.link {
- stroke: #ccc;
-}
-
-.node text {
- pointer-events: none;
- font: 15px sans-serif;
-}
-
-</style>
-<body>
- <div id="page-top">
- <div class="row">
- <div class="col-sm-8"><h1>Emulator Dashboard</h1></div>
- </div>
-
-</div>
- <div id="content">
-
-
-<div class="panel panel-primary">
- <!-- Default panel contents -->
- <div class="panel-heading"><span>Emulated Datacenters</span> <span class="badge" id="lbl_datacenter_count">0</span><span class="pull-right" id="lbl_lateness_datacenter">Lateness: -</span></div>
- <!-- Table -->
- <table class="table table-striped table-hover" id="table_datacenter">
- </table>
-</div>
-
-<div class="spacer"> </div>
-
-<div class="panel panel-primary">
- <!-- Default panel contents -->
- <div class="panel-heading"><span>Running Containers</span> <span class="badge" id="lbl_container_count">0</span><span class="pull-right" id="lbl_lateness_container">Lateness: -</span></div>
- <!-- Table -->
- <table class="table table-striped table-hover" id="table_container">
- </table>
-</div>
-
-
-</div>
-
-<footer class="footer text-center small">(c) 2017 by SONATA Consortium, Paderborn University and IMEC</footer>
-
-
-</body>
-
-</html>
--- /dev/null
+/*
+ Copyright (c) 2017 SONATA-NFV, IMEC and Paderborn University
+ ALL RIGHTS RESERVED.
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+
+ Neither the name of the SONATA-NFV, Paderborn University
+ nor the names of its contributors may be used to endorse or promote
+ products derived from this software without specific prior written
+ permission.
+
+ This work has been performed in the framework of the SONATA project,
+ funded by the European Commission under Grant number 671517 through
+ the Horizon 2020 and 5G-PPP programmes. The authors would like to
+ acknowledge the contributions of their colleagues of the SONATA
+ partner consortium (www.sonata-nfv.eu).
+*/
+
+ //functions to make the nodes stick after they have been manually maoved
+ function tick() {
+ link.attr("x1", function(d) { return d.source.x; })
+ .attr("y1", function(d) { return d.source.y; })
+ .attr("x2", function(d) { return d.target.x; })
+ .attr("y2", function(d) { return d.target.y; });
+
+ node.attr("cx", function(d) { return d.x; })
+ .attr("cy", function(d) { return d.y; });
+ }
+
+ function dragstart(d) {
+ d3.select(this).classed("fixed", d.fixed = true);
+ }
+
+var width = 960,
+ height = 500,
+ color = d3.scale.category10();
+
+var svg = d3.select("#table_graph").append("svg")
+ .attr("width", width)
+ .attr("height", height);
+
+var force = d3.layout.force()
+ .gravity(0.05)
+ .distance(100)
+ .charge(-100)
+ .size([width, height])
+ .on("tick", tick);
+
+var drag = force.drag()
+ .on("dragstart", dragstart);
+
+d3.json("/restapi/network/d3jsgraph", function(error, json) {
+ if (error) throw error;
+
+ force
+ .nodes(json.nodes)
+ .links(json.links)
+ .start();
+
+ var link = svg.selectAll(".link")
+ .data(json.links)
+ .enter().append("line")
+ .attr("class", "link");
+
+ var node = svg.selectAll(".node")
+ .data(json.nodes)
+ .enter().append("g")
+ .attr("class", "node")
+ .call(drag);
+
+ node.append("circle")
+ .attr("r", 10)
+ .style("fill", function(d) { return color(d.group); });
+
+ node.append("text")
+ .attr("dx", 12)
+ .attr("dy", ".35em")
+ .text(function(d) { return d.name });
+
+ force.on("tick", function() {
+ link.attr("x1", function(d) { return d.source.x; })
+ .attr("y1", function(d) { return d.source.y; })
+ .attr("x2", function(d) { return d.target.x; })
+ .attr("y2", function(d) { return d.target.y; });
+
+ node.attr("transform", function(d) { return "translate(" + d.x + "," + d.y + ")"; });
+ });
+
+
+});
acknowledge the contributions of their colleagues of the SONATA
partner consortium (www.sonata-nfv.eu).
*/
-var API_HOST = "http://127.0.0.1:5001";
+var API_HOST = ""; // set to a remote url if dashboard is not served by REST API server
var ERROR_ALERT = false;
var TIMESTAMP = 0;
var CONNECTED = false;
var LATENESS_UPDATE_INTERVAL = 50;
-var DATA_UPDATE_INTERVAL = 1000 * 10;
+var DATA_UPDATE_INTERVAL = 1000 * 30; // 30 seconds
var LAST_UPDATE_TIMESTAMP_CONTAINER = 0;
var LAST_UPDATE_TIMESTAMP_DATACENTER = 0;
function update_lateness_loop() {
lateness_datacenter= (Date.now() - LAST_UPDATE_TIMESTAMP_DATACENTER) / 1000;
- $("#lbl_lateness_datacenter").text("Lateness: " + Number(lateness_datacenter).toPrecision(3) + "s");
+ $("#lbl_lateness_datacenter").text("Lateness: " + Number(lateness_datacenter).toPrecision(2) + "s");
lateness_container= (Date.now() - LAST_UPDATE_TIMESTAMP_CONTAINER) / 1000;
- $("#lbl_lateness_container").text("Lateness: " + Number(lateness_container).toPrecision(3) + "s");
+ $("#lbl_lateness_container").text("Lateness: " + Number(lateness_container).toPrecision(2) + "s");
// loop while connected
if(CONNECTED)
setTimeout(update_lateness_loop, LATENESS_UPDATE_INTERVAL)
{
ERROR_ALERT = true;
// show message
- alert("ERROR!\nAPI request failed.\n\n Please check the backend connection.", function() {
- // callback
- ERROR_ALERT = false;
- });
+ //alert("API request failed. Is the emulator running?", function() {
+ // // callback
+ // ERROR_ALERT = false;
+ //});
}
+ CONNECTED = false;
+ console.error("API request failed. Is the emulator running?")
}
$.each(data, function(i, item) {
var row_str = "";
row_str += '<tr class="tbl-row clickable_row" id="datacenter_row_' + i +'">';
- row_str += '<td>' + item.label + '1</td>';
+ row_str += '<td>' + item.label + '</td>';
row_str += '<td>' + item.internalname + '</td>';
row_str += '<td>' + item.switch + '</td>';
row_str += '<td><span class="badge">' + item.n_running_containers + '</span></td>';
// clear table
$("#table_container").empty();
// header
- $("#table_container").append('<tr class="tbl-head"><td>Datacenter</td><td>Container</td><td>Image</td><td>docker0</td><td>--Networking--<div id="table_network"></div></td></tr>');
+ $("#table_container").append('<tr class="tbl-head"><td>Datacenter</td><td>Container</td><td>Image</td><td>docker0</td><td>Status</td></tr>');
// fill table
$.each(data, function(i, item) {
var row_str = "";
- row_str += '<tr class="tbl-row clickable_row" id="container_row_' + item[0] +'">';
+ row_str += '<tr class="tbl-row clickable_row" id="container_row_' + i +'">';
row_str += '<td>' + item[1].datacenter + '</td>';
row_str += '<td>' + item[0] + '</td>';
row_str += '<td>' + item[1].image + '</td>';
- row_str += '<td><code>' + item[1].docker_network + '</code></td>';
- row_str += '<td><table class="interface_table" id="network_list_' + item[0] + '">';
- //row_str += build_network_table(item[1].network, item[0]);
- row_str += '</table></td>';
- row_str += '</tr>';
- $("#table_container").append(row_str);
- build_network_table(item[1].network, item[0]);
+ row_str += '<td><code>' + item[1].docker_network + '<code></td>';
+ if(item[1].state.Status == "running")
+ row_str += '<td><span class="label label-success">running</span></td>';
+ else
+ row_str += '<td><span class="label label-danger">stopped</span></td>';
+ row_str += '<tr>';
+ $("#table_container").append(row_str);
});
$("#lbl_container_count").text(data.length);
- $("#table_network").append('<table class="interface_table"><tr class="interface_row"><td class="interface_port">datacenter port</td><td class="interface_name">interface</td><td class="interface_ip">ip</td><td class="interface_mac">mac</td></tr></table>')
// update lateness counter
LAST_UPDATE_TIMESTAMP_CONTAINER = Date.now();
}
-function build_network_table(network_list, id)
-{
- console.debug('network list ' + id)
- console.debug(network_list)
- var row_str = "";
- network_list.forEach(function(interface) {
- row_str += '<tr class="interface_row">';
- row_str += '<td class="interface_port">' + interface.dc_portname + '</td>';
- row_str += '<td class="interface_name">' + interface.intf_name + '</td>';
- row_str += '<td class="interface_ip">' + interface.ip + '</td>';
- row_str += '<td class="interface_mac">' + interface.mac + '</td>';
- row_str += '</tr>';
- });
- $("#network_list_" + id).append(row_str)
-}
function fetch_datacenter()
{
}
-function fetch_d3graph()
-{
- // do HTTP request and trigger gui update on success
- var request_url = API_HOST + "/restapi/network/d3jsgraph";
- console.debug("fetching from: " + request_url);
- //$.getJSON(request_url, update_graph);
-}
-
function fetch_loop()
{
// only fetch if we are connected
{
console.info("connect()");
// get host address
- API_HOST = "http://" + $("#text_api_host").val();
+ //API_HOST = "http://" + $("#text_api_host").val();
console.debug("API address: " + API_HOST);
// reset data
LAST_UPDATE_TIMESTAMP_DATACENTER = Date.now();
update_lateness_loop();
// restart data fetch loop
fetch_loop();
- // gui updates
- $("#btn_disconnect").removeClass("disabled");
- $("#btn_connect").addClass("disabled");
-}
-
-function disconnect()
-{
- console.info("disconnect()");
- CONNECTED = false;
- // gui updates
- $("#btn_connect").removeClass("disabled");
- $("#btn_disconnect").addClass("disabled");
}
$(document).ready(function(){
console.info("document ready");
// setup global connection error handling
- /*
+
$.ajaxSetup({
"error": errorAjaxConnection
});
- // add listeners
- $("#btn_connect").click(connect);
- $("#btn_disconnect").click(disconnect);
- */
- setTimeout(fetch_datacenter, 500);//fetch_datacenter();
- setTimeout(fetch_container, 1000);//fetch_container();
-
+ // connect
+ connect();
// additional refresh on window focus
$(window).focus(function () {
+++ /dev/null
-/*
- Copyright (c) 2017 SONATA-NFV and Paderborn University
- ALL RIGHTS RESERVED.
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
-
- Neither the name of the SONATA-NFV, Paderborn University
- nor the names of its contributors may be used to endorse or promote
- products derived from this software without specific prior written
- permission.
-
- This work has been performed in the framework of the SONATA project,
- funded by the European Commission under Grant number 671517 through
- the Horizon 2020 and 5G-PPP programmes. The authors would like to
- acknowledge the contributions of their colleagues of the SONATA
- partner consortium (www.sonata-nfv.eu).
-*/
-var API_HOST = ""; // set to a remote url if dashboard is not served by REST API server
-var ERROR_ALERT = false;
-var TIMESTAMP = 0;
-var CONNECTED = false;
-var LATENESS_UPDATE_INTERVAL = 50;
-var DATA_UPDATE_INTERVAL = 1000 * 2;
-var LAST_UPDATE_TIMESTAMP_CONTAINER = 0;
-var LAST_UPDATE_TIMESTAMP_DATACENTER = 0;
-
-
-function update_lateness_loop() {
- lateness_datacenter= (Date.now() - LAST_UPDATE_TIMESTAMP_DATACENTER) / 1000;
- $("#lbl_lateness_datacenter").text("Lateness: " + Number(lateness_datacenter).toPrecision(2) + "s");
- lateness_container= (Date.now() - LAST_UPDATE_TIMESTAMP_CONTAINER) / 1000;
- $("#lbl_lateness_container").text("Lateness: " + Number(lateness_container).toPrecision(2) + "s");
- // loop while connected
- if(CONNECTED)
- setTimeout(update_lateness_loop, LATENESS_UPDATE_INTERVAL)
-}
-
-
-function errorAjaxConnection()
-{
- // only do once
- if(!ERROR_ALERT)
- {
- ERROR_ALERT = true;
- // show message
- alert("API request failed. Is the emulator running?", function() {
- // callback
- ERROR_ALERT = false;
- });
- }
- CONNECTED = false;
-}
-
-
-function update_table_datacenter(data)
-{
- console.debug(data)
- // clear table
- $("#table_datacenter").empty();
- // header
- $("#table_datacenter").append('<tr class="tbl-head"><td>Label</td><td>Int. Name</td><td>Switch</td><td>Num. Containers</td><td>VNFs</td></tr>');
- // fill table
- $.each(data, function(i, item) {
- var row_str = "";
- row_str += '<tr class="tbl-row clickable_row" id="datacenter_row_' + i +'">';
- row_str += '<td>' + item.label + '1</td>';
- row_str += '<td>' + item.internalname + '</td>';
- row_str += '<td>' + item.switch + '</td>';
- row_str += '<td><span class="badge">' + item.n_running_containers + '</span></td>';
- //row_str += '<td><span class="badge">' + Object.keys(item.metadata).length + '</span></td>';
- row_str += '<td>' + item.vnf_list + '</span></td>';
- row_str += '<tr>';
- $("#table_datacenter").append(row_str);
- });
- $("#lbl_datacenter_count").text(data.length);
- // update lateness counter
- LAST_UPDATE_TIMESTAMP_DATACENTER = Date.now();
-}
-
-
-function update_table_container(data)
-{
- console.debug(data)
- // clear table
- $("#table_container").empty();
- // header
- $("#table_container").append('<tr class="tbl-head"><td>Datacenter</td><td>Container</td><td>Image</td><td>docker0</td><td>Status</td></tr>');
- // fill table
- $.each(data, function(i, item) {
- var row_str = "";
- row_str += '<tr class="tbl-row clickable_row" id="container_row_' + i +'">';
- row_str += '<td>' + item[1].datacenter + '</td>';
- row_str += '<td>' + item[0] + '</td>';
- row_str += '<td>' + item[1].image + '</td>';
- row_str += '<td><code>' + item[1].docker_network + '<code></td>';
- if(item[1].state.Status == "running")
- row_str += '<td><span class="label label-success">running</span></td>';
- else
- row_str += '<td><span class="label label-danger">stopped</span></td>';
- row_str += '<tr>';
- $("#table_container").append(row_str);
- });
- $("#lbl_container_count").text(data.length);
- // update lateness counter
- LAST_UPDATE_TIMESTAMP_CONTAINER = Date.now();
-}
-
-
-function fetch_datacenter()
-{
- // do HTTP request and trigger gui update on success
- var request_url = API_HOST + "/restapi/datacenter";
- console.debug("fetching from: " + request_url);
- $.getJSON(request_url, update_table_datacenter);
-}
-
-
-function fetch_container()
-{
- // do HTTP request and trigger gui update on success
- var request_url = API_HOST + "/restapi/compute";
- console.debug("fetching from: " + request_url);
- $.getJSON(request_url, update_table_container);
-}
-
-
-function fetch_loop()
-{
- // only fetch if we are connected
- if(!CONNECTED)
- return;
-
- // download data
- fetch_datacenter();
- fetch_container();
-
- // loop while connected
- if(CONNECTED)
- setTimeout(fetch_loop, DATA_UPDATE_INTERVAL);
-}
-
-
-function connect()
-{
- console.info("connect()");
- // get host address
- //API_HOST = "http://" + $("#text_api_host").val();
- console.debug("API address: " + API_HOST);
- // reset data
- LAST_UPDATE_TIMESTAMP_DATACENTER = Date.now();
- LAST_UPDATE_TIMESTAMP_CONTAINER = Date.now();
- CONNECTED = true;
- // restart lateness counter
- update_lateness_loop();
- // restart data fetch loop
- fetch_loop();
-}
-
-
-$(document).ready(function(){
- console.info("document ready");
- // setup global connection error handling
-
- $.ajaxSetup({
- "error": errorAjaxConnection
- });
-
- // connect
- connect();
-
- // additional refresh on window focus
- $(window).focus(function () {
- if(CONNECTED)
- {
- fetch_datacenter();
- fetch_container();
- }
- });
-
-});