Soft Patch Panel
 help / color / mirror / Atom feed
* [spp] [PATCH 0/2] Add topo http command
@ 2018-06-12  7:03 ogawa.yasufumi
  2018-06-12  7:03 ` [spp] [PATCH 1/2] controller: add websocket server for topo cmd ogawa.yasufumi
                   ` (2 more replies)
  0 siblings, 3 replies; 4+ messages in thread
From: ogawa.yasufumi @ 2018-06-12  7:03 UTC (permalink / raw)
  To: ferruh.yigit, spp; +Cc: Yasufumi Ogawa

From: Yasufumi Ogawa <ogawa.yasufumi@lab.ntt.co.jp>

'topo http' command is used to display in a browser. It is useful if you
login and run SPP controller via ssh because you cannot display an image
on the terminal from remote node.

To use this feature, you should install 'tornado' websocket server and
'websocket-client' with pip.

This series of patches is for adding websocket server and client side
scripts. It also includes updates of documentation for how to setup and
usages.


Yasufumi Ogawa (2):
  controller: add websocket server for topo cmd
  docs: update topo command manual

 docs/guides/commands/experimental.rst         | 33 ++++++-
 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 ++++++++
 5 files changed, 304 insertions(+), 4 deletions(-)
 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

-- 
2.17.1

^ permalink raw reply	[flat|nested] 4+ messages in thread

* [spp] [PATCH 1/2] controller: add websocket server for topo cmd
  2018-06-12  7:03 [spp] [PATCH 0/2] Add topo http command ogawa.yasufumi
@ 2018-06-12  7:03 ` ogawa.yasufumi
  2018-06-12  7:03 ` [spp] [PATCH 2/2] docs: update topo command manual ogawa.yasufumi
  2018-06-27 10:52 ` [spp] [PATCH 0/2] Add topo http command Ferruh Yigit
  2 siblings, 0 replies; 4+ messages in thread
From: ogawa.yasufumi @ 2018-06-12  7:03 UTC (permalink / raw)
  To: ferruh.yigit, spp; +Cc: Yasufumi Ogawa

From: Yasufumi Ogawa <ogawa.yasufumi@lab.ntt.co.jp>

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 <ogawa.yasufumi@lab.ntt.co.jp>
---
 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 @@
+<!doctype html>
+<html>
+  <head>
+    <title>SPP Topo Viewer</title>
+
+    <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"
+      type="text/javascript"></script>
+    <script src="http://visjs.org/dist/vis.js" type="text/javascript"></script>
+    <link rel="stylesheet" href="{{ static_url("main.css") }}" type="text/css" />
+    <link rel="stylesheet" href="http://visjs.org/dist/vis-network.min.css"
+    type="text/css" />
+  </head>
+  <body>
+
+    <div id="header">
+      <h1>SPP Topo Viewer</h1>
+      <div>
+        Show topology of
+        <a href="https://spp.readthedocs.io/en/latest/index.html">SPP</a> network
+        from '<i>topo http</i>' command.
+        Please refer
+        <a href="https://spp.readthedocs.io/en/latest/commands/experimental.html#topo">
+          topo
+        </a> command reference.
+      </div>
+    </div>
+
+    <div id="contents">
+      <div id="right">
+        <div id="spp_topo_network"></div>
+      </div>
+    </div>
+
+    <script type="text/javascript">
+      {% autoescape None %}
+      var dotData = '{{ dotData }}';
+    </script>
+    <script src="{{ static_url("spp_ws.js") }}" type="text/javascript"></script>
+  </body>
+</html>
-- 
2.17.1

^ permalink raw reply	[flat|nested] 4+ messages in thread

* [spp] [PATCH 2/2] docs: update topo command manual
  2018-06-12  7:03 [spp] [PATCH 0/2] Add topo http command ogawa.yasufumi
  2018-06-12  7:03 ` [spp] [PATCH 1/2] controller: add websocket server for topo cmd ogawa.yasufumi
@ 2018-06-12  7:03 ` ogawa.yasufumi
  2018-06-27 10:52 ` [spp] [PATCH 0/2] Add topo http command Ferruh Yigit
  2 siblings, 0 replies; 4+ messages in thread
From: ogawa.yasufumi @ 2018-06-12  7:03 UTC (permalink / raw)
  To: ferruh.yigit, spp; +Cc: Yasufumi Ogawa

From: Yasufumi Ogawa <ogawa.yasufumi@lab.ntt.co.jp>

Add instructions for installing required packages and usages of
'topo http' command.

Signed-off-by: Yasufumi Ogawa <ogawa.yasufumi@lab.ntt.co.jp>
---
 docs/guides/commands/experimental.rst | 33 +++++++++++++++++++++++----
 1 file changed, 29 insertions(+), 4 deletions(-)

diff --git a/docs/guides/commands/experimental.rst b/docs/guides/commands/experimental.rst
index a678fe6..42ba371 100644
--- a/docs/guides/commands/experimental.rst
+++ b/docs/guides/commands/experimental.rst
@@ -54,15 +54,23 @@ gfor generating topology file.
 You can also generate a dot formatted file or image files supported by
 graphviz.
 
-Here is a list of required tools for 'topo'.
+Here is a list of required tools for ``topo term`` command to output
+in terminal.
 MacOS is also supported optionally for which SPP controller
 runs on a remote host.
 
 * graphviz
 * imagemagick
-* libsixel-bin (for Ubuntu) and terminal app supporting img2sixel
+* libsixel-bin (for Ubuntu)
 * iTerm2 and imgcat (for MacOS)
 
+To output in browser with ``topo http`` command,
+install packages for websocket with pip or pip3.
+
+* tornado
+* websocket-client
+
+
 Output to Terminal
 ~~~~~~~~~~~~~~~~~~
 
@@ -94,13 +102,30 @@ and save this script as
 Output to Browser
 ~~~~~~~~~~~~~~~~~
 
-Output an image of network configuration in a browser.
+Output an image of network configuration in browser.
 
 .. code-block:: console
 
     spp > topo http
 
-[TODO] Add explanation.
+``topo term`` is useful to understand network configuration intuitively.
+However, it should be executed on a node running SPP controller.
+You cannnot see the image if you login remote node via ssh and running
+SPP controller on remote.
+
+Websocket server is launched from ``src/controller/websocket/spp_ws.py``
+to accept client messages.
+You should start it before using ``topo term`` command.
+Then, open url shown in the terminal (default is
+``http://127.0.0.1:8989``).
+
+Browser and SPP controller behave as clients, but have different roles.
+Browser behaves as a viwer and SPP controller behaves as a udpater.
+If you update network configuration and run ``topo http`` command,
+SPP controller sends a message containing network configuration
+as DOT language format.
+Once the message is accepted, websocket server sends it to viewer clients
+immediately.
 
 
 Output to File
-- 
2.17.1

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [spp] [PATCH 0/2] Add topo http command
  2018-06-12  7:03 [spp] [PATCH 0/2] Add topo http command ogawa.yasufumi
  2018-06-12  7:03 ` [spp] [PATCH 1/2] controller: add websocket server for topo cmd ogawa.yasufumi
  2018-06-12  7:03 ` [spp] [PATCH 2/2] docs: update topo command manual ogawa.yasufumi
@ 2018-06-27 10:52 ` Ferruh Yigit
  2 siblings, 0 replies; 4+ messages in thread
From: Ferruh Yigit @ 2018-06-27 10:52 UTC (permalink / raw)
  To: ogawa.yasufumi, spp

On 6/12/2018 8:03 AM, ogawa.yasufumi@lab.ntt.co.jp wrote:
> From: Yasufumi Ogawa <ogawa.yasufumi@lab.ntt.co.jp>
> 
> 'topo http' command is used to display in a browser. It is useful if you
> login and run SPP controller via ssh because you cannot display an image
> on the terminal from remote node.
> 
> To use this feature, you should install 'tornado' websocket server and
> 'websocket-client' with pip.
> 
> This series of patches is for adding websocket server and client side
> scripts. It also includes updates of documentation for how to setup and
> usages.
> 
> 
> Yasufumi Ogawa (2):
>   controller: add websocket server for topo cmd
>   docs: update topo command manual

Series applied, thanks.

^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2018-06-27 10:52 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2018-06-12  7:03 [spp] [PATCH 0/2] Add topo http command ogawa.yasufumi
2018-06-12  7:03 ` [spp] [PATCH 1/2] controller: add websocket server for topo cmd ogawa.yasufumi
2018-06-12  7:03 ` [spp] [PATCH 2/2] docs: update topo command manual ogawa.yasufumi
2018-06-27 10:52 ` [spp] [PATCH 0/2] Add topo http command Ferruh Yigit

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).