From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mogw0908.ocn.ad.jp (mogw0908.ocn.ad.jp [153.149.227.14]) by dpdk.org (Postfix) with ESMTP id DB5521E973 for ; Tue, 12 Jun 2018 09:03:50 +0200 (CEST) Received: from mf-smf-ucb020c3 (mf-smf-ucb020c3.ocn.ad.jp [153.153.66.135]) by mogw0908.ocn.ad.jp (Postfix) with ESMTP id 6E02140023A; Tue, 12 Jun 2018 16:03:49 +0900 (JST) Received: from ntt.pod01.mv-mta-ucb026 ([153.149.142.100]) by mf-smf-ucb020c3 with ESMTP id SdLIf9mwx0tw2SdLJfuZ6k; Tue, 12 Jun 2018 16:03:49 +0900 Received: from smtp.ocn.ne.jp ([153.149.227.133]) by ntt.pod01.mv-mta-ucb026 with id xj3p1x00K2tKTyH01j3p0k; Tue, 12 Jun 2018 07:03:49 +0000 Received: from localhost.localdomain (p5164-ipngn8501marunouchi.tokyo.ocn.ne.jp [153.214.228.164]) by smtp.ocn.ne.jp (Postfix) with ESMTPA; Tue, 12 Jun 2018 16:03:49 +0900 (JST) From: ogawa.yasufumi@lab.ntt.co.jp To: ferruh.yigit@intel.com, spp@dpdk.org Cc: Yasufumi Ogawa Date: Tue, 12 Jun 2018 16:03:42 +0900 Message-Id: <20180612070343.5350-2-ogawa.yasufumi@lab.ntt.co.jp> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20180612070343.5350-1-ogawa.yasufumi@lab.ntt.co.jp> References: <20180612070343.5350-1-ogawa.yasufumi@lab.ntt.co.jp> Subject: [spp] [PATCH 1/2] controller: add websocket server for topo cmd X-BeenThere: spp@dpdk.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: Soft Patch Panel List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 12 Jun 2018 07:03:51 -0000 From: Yasufumi Ogawa Topo command is for showing SPP network configuration graphically. This update is to add the feature to output in browser. Network topology is shown on a browser by runnign 'topo http' from SPP controller. It is implemented with 'tornado'[1] for websocket and 'vis.js'[2] for parsing dot language and depicting on browser. Using websocket means that you can display the topology immediately if it is updated. Expression of dot of 'vis.js' is poor comparing with graphviz actually. However, you can see the topology on remote node with 'topo http', and 'topo term' cannot do it. To activate this 'topo http' command, you should install requried packages with pip (or pip3). * tornado * websocket-client [1] http://www.tornadoweb.org/en/stable/ [2] http://visjs.org/ Signed-off-by: Yasufumi Ogawa --- src/controller/websocket/spp_ws.py | 98 +++++++++++++++++++ src/controller/websocket/static/main.css | 67 +++++++++++++ src/controller/websocket/static/spp_ws.js | 70 +++++++++++++ src/controller/websocket/templates/index.html | 40 ++++++++ 4 files changed, 275 insertions(+) create mode 100755 src/controller/websocket/spp_ws.py create mode 100644 src/controller/websocket/static/main.css create mode 100644 src/controller/websocket/static/spp_ws.js create mode 100644 src/controller/websocket/templates/index.html diff --git a/src/controller/websocket/spp_ws.py b/src/controller/websocket/spp_ws.py new file mode 100755 index 0000000..848945a --- /dev/null +++ b/src/controller/websocket/spp_ws.py @@ -0,0 +1,98 @@ +#!/usr/bin/env python +# SPDX-License-Identifier: BSD-3-Clause +# Copyright(c) 2017-2018 Nippon Telegraph and Telephone Corporation + +import logging +import os +import tornado.escape +import tornado.ioloop +import tornado.options +import tornado.web +import tornado.websocket + +from tornado.options import define +from tornado.options import options + +curdir = os.path.abspath(os.path.dirname(__file__)) +logging.basicConfig( + filename='%s/server.log' % curdir, level=logging.DEBUG) + +# Server address +ipaddr = '127.0.0.1' # used only for start message +port = 8989 + +define("port", default=port, help="Wait for 'topo http' command", type=int) + + +class Application(tornado.web.Application): + def __init__(self): + handlers = [ + (r"/", MainHandler), + (r"/spp_ws", SppWsHandler), + ] + settings = dict( + template_path=os.path.join( + os.path.dirname(__file__), "templates"), + static_path=os.path.join( + os.path.dirname(__file__), "static"), + cookie_secret="yasupyasup", + xsrf_cookies=True, + ) + super(Application, self).__init__(handlers, **settings) + + +class MainHandler(tornado.web.RequestHandler): + def get(self): + logging.info("Render to browser\n%s", SppWsHandler.dot) + self.render( + "index.html", + dotData=SppWsHandler.dot.replace('\n', '')) + + +class SppWsHandler(tornado.websocket.WebSocketHandler): + waiters = set() + dot = "" + + def get_compression_options(self): + # Non-None enables compression with default options. + return {} + + def open(self): + SppWsHandler.waiters.add(self) + + def on_close(self): + SppWsHandler.waiters.remove(self) + + @classmethod + def update_dot(cls, msg): + cls.dot = msg + + @classmethod + def send_updates(cls, msg): + logging.info( + "Send message to %d clients", len(cls.waiters)) + for waiter in cls.waiters: + try: + waiter.write_message(msg) + except Exception: + pass + logging.error("Error sending message", exc_info=True) + + def on_message(self, message): + logging.info("Received from client\n%r", message) + self.dot = message + SppWsHandler.update_dot(message) + SppWsHandler.send_updates(message) + + +def main(): + tornado.options.parse_command_line() + app = Application() + app.listen(options.port) + print('Running SPP topo server on http://%s:%d ...' % ( + ipaddr, port)) + tornado.ioloop.IOLoop.current().start() + + +if __name__ == "__main__": + main() diff --git a/src/controller/websocket/static/main.css b/src/controller/websocket/static/main.css new file mode 100644 index 0000000..d2fdfa9 --- /dev/null +++ b/src/controller/websocket/static/main.css @@ -0,0 +1,67 @@ +body, html { + font: 10pt sans; + line-height: 1.5em;; + width: 100%; + height: 100%; + padding: 0; + margin: 0; + color: #4d4d4d; + box-sizing: border-box; + overflow: hidden; +} + +#header { + margin: 0; + padding: 10px; + box-sizing: border-box; +} + +#contents { + height: 100%; + margin: 0; + padding: 0; + box-sizing: border-box; + position: relative; +} + +#right { + position: absolute; + width: 100%; + height: 100%; + margin: 0; + padding: 10px; + box-sizing: border-box; + display: inline-block; +} + +#right { + top: 0; + right: 0; +} + +#error { + color: red; +} + +#data { + width: 100%; + height: 100%; + border: 1px solid #d3d3d3; + box-sizing: border-box; + resize: none; +} + +#draw, #reset { + padding: 5px 15px; +} + +#spp_topo_network{ + width: 100%; + height: 100%; + border: 1px solid #d3d3d3; + box-sizing: border-box; +} + +a:hover { + color: red; +} diff --git a/src/controller/websocket/static/spp_ws.js b/src/controller/websocket/static/spp_ws.js new file mode 100644 index 0000000..80b70b6 --- /dev/null +++ b/src/controller/websocket/static/spp_ws.js @@ -0,0 +1,70 @@ +/** + * @license + * SPDX-License-Identifier: BSD-3-Clause + * Copyright(c) 2017-2018 Nippon Telegraph and Telephone Corporation + */ + +$(document).ready(function() { + if (!window.console) window.console = {}; + if (!window.console.log) window.console.log = function() {}; + + updater.start(); +}); + +var updater = { + socket: null, + + start: function() { + var url = "ws://" + location.host + "/spp_ws"; + updater.socket = new WebSocket(url); + updater.socket.onmessage = function(event) { + updater.showDot(event.data); + } + }, + + showDot: function(dot) { + console.log(dot); + dotData = dot + draw(); + } +}; + + +// create a network +var container = document.getElementById('spp_topo_network'); +var options = { + physics: { + stabilization: false, + barnesHut: { + springLength: 200 + } + } +}; +var data = {}; +var network = new vis.Network(container, data, options); + +$(window).resize(resize); +$(window).load(draw); + +function resize() { + $('#contents').height($('body').height() - $('#header').height() - 30); +} + +function draw() { + try { + resize(); + $('#error').html(''); + + data = vis.network.convertDot(dotData); + + network.setData(data); + } + catch (err) { + // show an error message + $('#error').html(err.toString()); + } +} + +window.onload = function() { + draw(); +} diff --git a/src/controller/websocket/templates/index.html b/src/controller/websocket/templates/index.html new file mode 100644 index 0000000..ceedc21 --- /dev/null +++ b/src/controller/websocket/templates/index.html @@ -0,0 +1,40 @@ + + + + SPP Topo Viewer + + + + + + + + + + +
+ +
+ + + + + -- 2.17.1