Files
nexus/sreweekly/articles/90/12-documenting-your-architecture-wireshark-plantuml-and-a-repl-to-glue-th.html
2026-09-12 17:23:01 +08:00

320 lines
19 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<!DOCTYPE html>
<!--[if lt IE 8 ]><html class="no-js ie ie7" lang="en"> <![endif]--><!--[if IE 8 ]><html class="no-js ie ie8" lang="en"> <![endif]--><!--[if IE 9 ]><html class="no-js ie ie9" lang="en"> <![endif]--><!--[if (gte IE 9)|!(IE)]><!--><html class="no-js" lang="en"> <!--<![endif]-->
<head>
<!--- Basic Page Needs
================================================== -->
<meta charset="utf-8" />
<title>Documenting your architecture: Wireshark, PlantUML and a REPL to glue them all.</title>
<meta content="Instead of drawing UML diagrams, why not generate them from a network traffic capture of the running system?" name="description" /><meta content="Document architecture wireshark plantuml UML Clojure sequence diagram" name="keywords" /><meta content="Daniel Lebrero Berna" name="author" /><meta content="Documenting your architecture: Wireshark, PlantUML and a REPL to glue them all." property="og:title" /><meta content="Instead of drawing UML diagrams, why not generate them from a network traffic capture of the running system?" property="og:description" /><meta content="https://danlebrero.com/2017/04/06/documenting-your-architecture-wireshark-plantuml-and-a-repl/" property="og:url" /><meta content="Documenting your architecture: Wireshark, PlantUML and a REPL to glue them all." name="twitter:title" /><meta content="Instead of drawing UML diagrams, why not generate them from a network traffic capture of the running system?" name="twitter:description" /><meta content="summary_large_image" name="twitter:card" /><meta content="https://danlebrero.com/images/blog/documenting-architecture.jpg" name="twitter:image" /><meta content="https://danlebrero.com/images/blog/documenting-architecture.jpg" property="og:image" />
<meta name="twitter:site" content="@danlebrero" />
<meta name="twitter:creator" content="@danlebrero" />
<link rel="canonical" href="https://danlebrero.com/2017/04/06/documenting-your-architecture-wireshark-plantuml-and-a-repl/" />
<link rel="alternate" type="application/rss+xml" title="Daniel Lebrero Berna Blog" href="/feed.rss" />
<!-- Mobile Specific Metas
================================================== -->
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1" />
<!-- CSS
================================================== -->
<link rel="stylesheet" href="/css/base.css" />
<link rel="stylesheet" href="/css/main.css" />
<link rel="stylesheet" href="/css/media-queries.css" />
<link rel="stylesheet" href="/css/railscasts.css" />
<link rel="stylesheet" href="/css/shariff.min.css" />
<!-- Script
=================================================== -->
<script src="/js/modernizr.js"></script>
<!-- Favicons
=================================================== -->
<link rel="shortcut icon" href="/favicon.ico" />
<!-- Google tag (gtag.js) -->
<script async="async" src="https://www.googletagmanager.com/gtag/js?id=G-3KPNQF7Y7S"></script>
<script>
window.dataLayer = window.dataLayer || [];
function gtag(){dataLayer.push(arguments);}
gtag('js', new Date());
gtag('config', 'G-3KPNQF7Y7S');
</script> <link href="//cdn-images.mailchimp.com/embedcode/slim-10_7.css" rel="stylesheet" type="text/css" />
<style type="text/css">#mc_embed_signup{background:#fff; clear:left; font:14px Helvetica,Arial,sans-serif; }</style>
</head>
<body>
<!-- Header
=================================================== -->
<header id="main-header">
<div class="row header-inner">
<!--div class="logo">
<a class="smoothscroll" href="#hero">Puremedia.</a>
</- -div-->
<nav id="nav-wrap">
<a class="mobile-btn" href="#nav-wrap" title="Show navigation">
<span class="menu-text">Show Menu</span>
<span class="menu-icon"></span>
</a>
<a class="mobile-btn" href="#" title="Hide navigation">
<span class="menu-text">Hide Menu</span>
<span class="menu-icon"></span>
</a>
<ul id="nav" class="nav">
<li class="current"><a href="/">Home.</a></li>
<!--<li id="menu-work"><a class="smoothscroll" href="/portfolio.html">Works.</a></li>-->
<li id="menu-archives"><a href="/archives/">Archives.</a></li>
<!-- <li id="menu-popular"><a class="smoothscroll" href="/popular/">Popular entries.</a></li>-->
</ul>
</nav> <!-- /nav-wrap -->
</div> <!-- /header-inner -->
</header>
<!-- Page Title
================================================== -->
<section id="page-title">
<div class="row">
<div class="twelve columns">
<p id="the-title"><a href="/">@DanLebrero<span>.</span></a></p>
<p>software, simply</p>
</div>
</div> <!-- /row -->
</section> <!-- /page-title -->
<!-- Content
================================================== -->
<section id="content">
<div class="row">
<div id="main" class="tab-whole nine columns">
<article class="entry">
<header class="entry-header">
<h1 class="entry-title">Documenting your architecture: Wireshark, PlantUML and a REPL to glue them all.</h1>
<div class="entry-meta">
<ul>
<li id="entry-date">Thu, 6 Apr 2017</li>
</ul>
</div>
</header>
<p class="lead" id="entry-summary">Instead of drawing UML diagrams, why not generate them from a network traffic capture of the running system?</p>
<div class="entry-content-media">
<div class="post-thumb">
<img src="/images/blog/documenting-architecture.jpg" />
</div>
</div>
<div class="entry-content"><p>I recently had to document the results of the evaluation of a new system.</p><p>The proof of concept for the system included six possible configurations, each option having a significant architectural impact on the system.</p><p>To understand all six, I have been squinting at the logs from the servers plus the Chrome DevTools network panel, trying to correlate the requests with the responses and the traffic between the servers.</p><p>As part of the documentation I thought it would be important to have some sequence diagrams to explain the protocol between the different parts of the system.</p><p>But when trying to draw the sequence diagrams, I realized that all that squinting had just allowed me to grasp the general feeling of the difference between the options, but not enough to write down a proper and accurate description of each one.</p><p>Also, the prospective boredom of opening my least hated UML tool and spending some hours dragging and dropping boxes and fiddling around with lines, didn’t fill me with joy.</p><p>Given that I already had the six combinations running for the proof of concept, couldn’t I leverage on that?</p><h2>The tools</h2><p>First, we need to find out all the traffic between the components of the system. For this we will use the venerable <a href="https://www.wireshark.org/">Wireshark</a>. </p><p>Wireshark will allow us to capture any network traffic, filtering out anything unnecessary, plus it comes with a handy <a href="http://stackoverflow.com/a/40540149">export to json</a> feature to simplify the parsing of the output.</p><p>A snippet of what a HTTP request looks like:</p><p><img src="/images/blog/wireshark-json-example.jpg" alt="wireshark-json-sample" title="A Wireshark json example" /></p><p>Second, we will need to generate the UML diagrams. For this we will use <a href="http://plantuml.com">PlantUML</a>, which is a text based UML DSL with the accompanying libraries to generate images. Being text based, our problem of generating UML diagrams becomes one of string concatenation.</p><p>Lastly, we need some glue to transform the Wireshark json files to PlantUML text files. We will use Clojure but any turing complete language would do. Of course, a <a href="/2018/11/26/repl-driven-development-immediate-feedback-for-you-backend/#content">Clojure REPL</a> makes the task more pleasant.</p><h2>The result</h2><p>First, to show off, lets look at how one of the diagrams looks like:</p><p><img src="/images/blog/bearer-only-uma-authz.jpg" alt="keycloak-uma" title="KeyCloak UMA Authz sequence diagram" /></p><p>This diagram requires 40 lines of PlantUML that look like:</p>
<pre><code class="nohighlight">browser -&gt; backend: /api/datasets/ds-1 (536.0B)
browser &lt;-- backend: 200 json (0.7KB)
browser -&gt; backend: /api/library (525.0B)
browser &lt;-- backend: 200 json (1.0KB)
note over browser, nginx: -&gt;1.2KB/&lt;-532.0B
note over browser, backend: -&gt;4.4KB/&lt;-5.3KB
</code></pre><p>The whole PlantUML code is <a href="https://gist.githubusercontent.com/dlebrero/acf5d1ba5156bc10048d006d6f18705c/raw/fb432f56cb7ec043f027d6d3d3373f5b69283987/plantuml.puml">here</a> and the code can be found <a href="https://github.com/dlebrero/wireshark-plantuml">here</a>.</p><p>If you are curious, the diagram corresponds to loading a <a href="https://en.wikipedia.org/wiki/Single-page_application">Single-page application</a>, doing authentication with <a href="https://en.wikipedia.org/wiki/OpenID_Connect">OpenID Connect</a> and authorizing an API endpoint with <a href="https://en.wikipedia.org/wiki/User-Managed_Access">User-Managed Access</a>.</p><h2>Benefits</h2><p>The benefits of using these three tools are:</p>
<ol>
<li>We are able to generate a set of diagrams that are accurate, giving you the confidence that you are not missing anything. Assuming no bugs in the parsing code <i class="far fa-smile" aria-hidden="true"></i>.</li>
<li>As the set of diagrams are generated using the same code, they all look consistent, both in the data that they contain and in their look and feel.</li>
<li>The data, the diagrams and the code to generate them are all text, which means that can be version control and manually inspected or tweaked if required.</li>
<li>If we decide to change any details about the diagrams, it will take no time to update all diagrams.</li>
<li>Maybe the code to generate the diagrams can be used in other projects.</li>
<li>The diagrams have the desired level of detail. For example, in the diagrams we have removed the loading of images, css and javascript files.</li>
<li>You can add a great deal of detail to the diagrams, as the data capture has even the request/response, so you could parse them and extract the information that was relevant to your system.</li>
<li>You can do all from your favourite IDE in an interactive fashion:</li>
</ol><p><iframe width="560" height="315" src="https://www.youtube.com/embed/J2RGAPGFfP8" frameborder="0" allowfullscreen="allowfullscreen"></iframe></p><h2>Drawbacks</h2><p>Of course there are some drawbacks:</p>
<ol>
<li>We have to have the system working and we have to be able to sniff the traffic.</li>
<li>The data capture can be huge, so some pre-filtering during the capture phase maybe necessary.</li>
<li>There can be sensitive data in the capture. Be careful with the security!</li>
</ol><h2>More benefits!</h2><p>Last, but probably the most important benefit, is that we have converted a tedious task into an enjoyable one.</p><p>I never thought I would say this but … Happy documenting!</p></div>
<hr />
<div class="cta">
<center>Did you enjoy it? <a href="https://twitter.com/DanLebrero" class="twitter-follow-button" data-show-count="true">Follow @DanLebrero</a><script async="async" src="//platform.twitter.com/widgets.js" charset="utf-8"></script> or share!</center>
</div>
<div class="shariff" data-lang="en" data-mail-url="mailto:" data-twitter-via="danlebrero" data-services="[&quot;reddit&quot;,&quot;twitter&quot;, &quot;linkedin&quot;,&quot;facebook&quot;,&quot;mail&quot;]"></div>
<p class="tags">
<span>Tagged in </span>:
<a href="/tags/Architecture/index.html">Architecture </a><a href="/tags/Clojure/index.html">Clojure </a>
</p>
<div id="disqus_thread"></div>
<script id="disqus_script">
(function() {
var d = document, s = d.createElement('script');
s.src = 'https://danlebrero.disqus.com/embed.js';
s.setAttribute('data-timestamp', +new Date());
(d.head || d.body).appendChild(s);
})();
</script>
</article> <!-- /entry -->
</div> <!-- /main -->
<div class="tab-whole three columns end" id="secondary">
<aside id="sidebar">
<div class="widget-title">
<form class="ddg" name="x" action="//duckduckgo.com/">
<input type="hidden" value="danlebrero.com" name="sites" />
<input type="hidden" value="1" name="kh" />
<input type="hidden" value="1" name="kn" />
<input type="hidden" value="1" name="kac" />
<input type="search" placeholder="Search" name="q" />
<input type="submit" value="Go" class="button" />
</form>
</div> <!-- /widget_search -->
<div class="widget widget_text">
<h5 class="widget-title">About me</h5>
<div class="textwidget">
<img class="pull-left" style="border-radius: 5a 0%;" src="https://en.gravatar.com/userimage/38792381/b0f54df774ad03c9b8c553be0af3b322.jpeg" />
Daniel Lebrero is a baby CTO, a teen remote worker, a mature Clojurian, an elder Architect, an ancient TDDer and an antediluvian Java dev.
<br />
With more than 20 years of software development experience, he has worked on monolithic websites, embedded applications, low latency systems, micro services, streaming applications and big data.
<br />
<p>Right now, SVP of Engineering at <a href="https://www.lifecheq.co.za">LifeCheq</a>. Maybe <a href="https://lifecheq.freshteam.com/jobs">we are hiring.</a></p>
<p><b>Need help?</b> Reach me at <a href="https://twitter.com/DanLebrero"><i class="fab fa-twitter-square"></i></a>,
drop me an <a href="mailto:dlebrero@gmail.com"><i class="far fa-envelope"></i></a>
or connect with <a href="https://www.linkedin.com/in/danlebrero/"><i class="fab fa-linkedin"></i>.</a></p>
</div>
<!--h5 class="widget-title">Next talks</h5>
<div class="textwidget">
<a href="https://www.wearedevelopers.com/sessions/java-with-a-clojure-mindset"><img src="/images/logo-wearedevelopers-2018.png"/></a>
</div-->
<div class="container">
<!--div class="row">
<div id="toprightbanner" class="widget six columns">
</div>
<div id="toprightbanner2" class="widget six columns">
</div>
</div-->
</div>
</div> <!-- /widget_text -->
<div class="widget">
<h5 class="widget-title"><a href="/archives/">Archives</a></h5>
<!-- <h5 class="widget-title"><a href="/popular/">Popular Entries</a></h5>-->
<h5 class="widget-title">RSS feed: <a href="/feed.rss"><img src="/images/feed.png" /></a></h5>
<!-- Begin Mailchimp Signup Form -->
<form action="https://danlebrero.us7.list-manage.com/subscribe/post?u=261eea2437ba4ca873e34b694&amp;id=eec8fa45ea" method="post" id="mc-embedded-subscribe-form" name="mc-embedded-subscribe-form" class="validate" target="_blank" novalidate="novalidate">
<div id="mc_embed_signup_scroll">
<h5 class="widget-title">Subscribe by email:</h5>
<input type="email" value="" name="EMAIL" class="email" id="mce-EMAIL" placeholder="email address" required="required" />
<input type="submit" value="Subscribe" name="subscribe" id="mc-embedded-subscribe" class="button" />
<div style="position: absolute; left: -5000px;" aria-hidden="true"><input type="text" name="b_261eea2437ba4ca873e34b694_eec8fa45ea" tabindex="-1" value="" /></div>
</div>
</form>
<!--End mc_embed_signup-->
</div>
<div class="widget widget_categories">
<h5 class="widget-title">Categories</h5>
<ul id="categories" class="link-list group"><li><a href="/tags/Architecture/index.html">Architecture (42)</a></li><li><a href="/tags/CTO_diary/index.html">CTO diary (9)</a></li><li><a href="/tags/Career/index.html">Career (11)</a></li><li><a href="/tags/Clojure/index.html">Clojure (37)</a></li><li><a href="/tags/Humour/index.html">Humour (12)</a></li><li><a href="/tags/Java/index.html">Java (7)</a></li><li><a href="/tags/Kafka/index.html">Kafka (8)</a></li><li><a href="/tags/Kubernetes/index.html">Kubernetes (5)</a></li><li><a href="/tags/Talks/index.html">Talks (12)</a></li><li><a href="/tags/book_notes/index.html">book notes (54)</a></li><li><a href="/tags/good_practices/index.html">good practices (27)</a></li><li><a href="/tags/resilience/index.html">resilience (7)</a></li><li><a href="/tags/testing/index.html">testing (10)</a></li></ul>
</div> <!-- /widget_categories -->
<div class="widget widget_categories">
<!--h5 class="widget-title">Now Reading</h5>
<iframe sandbox="allow-popups allow-scripts allow-modals allow-forms allow-same-origin" style="width:120px;height:240px;" marginwidth="0" marginheight="0" scrolling="no" frameborder="0" src="//ws-na.amazon-adsystem.com/widgets/q?ServiceVersion=20070822&OneJS=1&Operation=GetAdHtml&MarketPlace=US&source=ss&ref=as_ss_li_til&ad_type=product_link&tracking_id=danlebrero-20&language=en_US&marketplace=amazon&region=US&placement=1950508838&asins=1950508838&linkId=1abcab6ed414fe6ad50e093b9d78cb44&show_border=true&link_opens_in_new_window=true"></iframe></iframe-->
</div>
<!-- /widget_tag_cloud -->
</aside> <!-- /sidebar -->
</div> <!-- /secondary -->
</div> <!-- /row -->
</section> <!-- /content -->
<!-- Footer
================================================== -->
<footer>
<p class="copyright">© Copyright 2016 Daniel Lebrero. Design by <a href="http://www.styleshout.com/">Styleshout.</a></p>
<div id="go-top">
<a class="smoothscroll" title="Back to Top" href="#content"><span>Top</span><i class="fas fa-long-arrow-alt-up"></i></a>
</div>
</footer> <!-- /footer -->
<!-- Java Script
================================================== -->
<div id="scripts" style="display:none;">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
<script src="/js/jquery-1.10.2.min.js"></script>
<script type="text/javascript" src="/js/jquery-migrate-1.2.1.min.js"></script>
<script src="/js/jquery.flexslider.js"></script>
<script src="/js/jquery.fittext.js"></script>
<script src="/js/backstretch.js"></script>
<script src="/js/waypoints.js"></script>
<script src="/js/main.js"></script>
<script src="/js/highlight.pack.10.5.0.js"></script>
<script src="/js/shariff.min.js"></script>
<script>hljs.initHighlightingOnLoad();</script>
<script>
$(document).ready(function() {
$(".shariff").find('a').each(function() {
var which = $(this).attr("title").substr(9);;
$(this).click(function(event) {
ga('send', 'social', which, 'share', window.location.href);
});
});
});
</script>
<div id="debug" style="display: none;">
</div>
</div>
</body>
</html>