<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[The Musings of Marc]]></title><description><![CDATA[I'm a core contributor on apiman, an open source API Management platform. My surname does not rhyme with gravy.]]></description><link>http://www.rhymewithgravy.com</link><generator>RSS for Node</generator><lastBuildDate>Thu, 28 Mar 2019 20:38:13 GMT</lastBuildDate><atom:link href="http://www.rhymewithgravy.com/rss/" rel="self" type="application/rss+xml"/><ttl>60</ttl><item><title><![CDATA[Setting Content-Type for multipart/form-data values]]></title><description><![CDATA[<div class="paragraph">
<p>I was recently creating a form that submitted two elements at once: a JSON payload, and a file.
My back-end kept choking on the JSON payload, claiming it did not know how to decode it.
That seemed odd, to say the least.</p>
</div>
<div class="paragraph">
<p>My first attempt looked something like this:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code>    const file ....
    const jsonPayload: String = JSON.stringify(objToSend);
    const formData: FormData = new FormData();

    formData.append('jsonPayload', jsonPayload);
    formData.append('my-file', file);

    return this.http.post&lt;File&gt;(`${this.resourceUrl}`, formData, {
        observe: 'response'
    });</code></pre>
</div>
</div>
<div class="paragraph">
<p>This <em>appears</em> to work, however your backend will likely start complaining about the <code>jsonPayload</code> field. Why?</p>
</div>
<div class="paragraph">
<p>Let&#8217;s see what the browser sent:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code>------WebKitFormBoundaryJU3pJb6zPtyXf5GH
Content-Disposition: form-data; name="jsonPayload"

{"foo":"bar"}

------WebKitFormBoundaryJU3pJb6zPtyXf5GH
Content-Disposition: form-data; name="my-file"; filename="something.csv"
Content-Type: text/csv <i class="conum" data-value="1"></i><b>(1)</b>

------WebKitFormBoundaryJU3pJb6zPtyXf5GH--</code></pre>
</div>
</div>
<div class="paragraph">
<p>At first blush, everything seems okay; the data is there, and the names seem correct.
However, on closer inspection, notice that <code>my-file</code> has a <code>Content-Type</code> set at <strong>(1)</strong>, whilst <code>jsonPayload</code> does not.</p>
</div>
<div class="paragraph">
<p>By default, most browsers will infer a <code>File</code> Content-Type correctly, but will not set a the Content-Type for the <code>jsonPayload</code> string.</p>
</div>
<div class="paragraph">
<p>Unfortunately, the standard <code>append</code> String method on FormData doesn&#8217;t seem to let us set the content type; so we must take a slightly more obscure route by creating a new <code>Blob</code>, into which goes our <code>jsonPayload</code>&#8201;&#8212;&#8201;setting the content type in the subsequent options parameter:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code>   formData.append('jsonPayload', new Blob([
       jsonPayload
   ], {
       type: "application/json"
   }));</code></pre>
</div>
</div>
<div class="paragraph">
<p>Now it should be behaving as expected:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code>------WebKitFormBoundaryJU3pJb6zPtyXf5GH
Content-Disposition: form-data; name="jsonPayload"; filename="blob"
Content-Type: application/json <i class="conum" data-value="1"></i><b>(1)</b>

{"foo":"bar"}
------WebKitFormBoundaryJU3pJb6zPtyXf5GH
Content-Disposition: form-data; name="my-file"; filename="something.csv"
Content-Type: text/csv


------WebKitFormBoundaryJU3pJb6zPtyXf5GH--</code></pre>
</div>
</div>
<div class="colist arabic">
<table>
<tr>
<td><i class="conum" data-value="1"></i><b>1</b></td>
<td>Now our JSON payload has the correct Content-Type, hooray!</td>
</tr>
</table>
</div>]]></description><link>http://www.rhymewithgravy.com/2019/03/28/Setting-Content-Type-for-multipartform-data-values.html</link><guid isPermaLink="true">http://www.rhymewithgravy.com/2019/03/28/Setting-Content-Type-for-multipartform-data-values.html</guid><category><![CDATA[typescript]]></category><category><![CDATA[ javascript]]></category><dc:creator><![CDATA[Marc Savy]]></dc:creator><pubDate>Thu, 28 Mar 2019 00:00:00 GMT</pubDate></item><item><title><![CDATA[Farewell, Red Hat friends!]]></title><description><![CDATA[<div class="paragraph">
<p><em>This is an approximate reproduction of the email I sent to my soon-to-be erstwhile Red Hat colleagues:</em></p>
</div>
<div class="paragraph">
<p>This is a difficult email to write. I&#8217;ve had the great fortune to be part of Red Hat for over 8 years, and whilst there have been many challenges and accomplishments along the way, the one constant has been the wonderful people.</p>
</div>
<div class="paragraph">
<p>For many, colleagues are only ever acquaintances; it&#8217;s a tribute to you all that many have become personal friends. I am certain we&#8217;ll stay that way.</p>
</div>
<div class="paragraph">
<p>Whilst it&#8217;s time for me to move on and embrace a new challenge, I very much hope this isn&#8217;t the last I will see of you all. Whether in person, or in the open source community.</p>
</div>
<div class="paragraph">
<p>I have so many of you to thank for helping me develop my career, and more importantly, being a significant presence outside of work; always offering good advice, encouragement, and advocating for me. Truly, thank you.</p>
</div>
<div class="paragraph">
<p>I&#8217;d like to make special mention of Eric, who has been a truly excellent person to collaborate with, and has helped me develop in ways I wouldn&#8217;t have imagined. You could not wish to work with a better person. We nearly got over the line, but not quite!</p>
</div>
<div class="paragraph">
<p>There are so many other Red Hatters who have had very a positive influence on my career and life, and it&#8217;s difficult to choose who to mention, but I&#8217;d like to explicitly call out a few: Julien and all the Vert.x team, Sanne, Stian and the KC team, Andrew Dinn, Dave, MarkL, Keith Babo, Keith Lynch, Kev, Ken, Bob, Lance, Ben &amp; Co, Rachel, all my friends at Newcastle, our excellent friends in QE, and all those that advocated for our work. There are so many others, and your name not explicitly being here isn&#8217;t a sign of anything other than my attempt at brevity.</p>
</div>
<div class="paragraph">
<p>If you have time, I would love for you all to check out Apicurio (<a href="https://www.apicur.io/"><a href="https://www.apicur.io/" class="bare">https://www.apicur.io/</a></a>&#8201;&#8212;&#8201;click "try live"); it&#8217;s Eric&#8217;s latest project, and I&#8217;ve been assisting the last month or so. It&#8217;s a rich UI, editor, and validator for creating and collaborating on OpenAPI (fka Swagger) documents; moreover, it can generate code and is increasingly providing slick integration with other Red Hat projects. It&#8217;s really at the head of the pipe when it comes to the developer experience, and I think it&#8217;s a fantastic addition to the Middleware portfolio.</p>
</div>
<div class="paragraph">
<p>Finally, I wish you all the very best of luck with your endeavours. Your technical talents, understanding of open source and community, and continued hard work will be amongst the key attributes that I hope will allow Middleware to prevail.</p>
</div>
<div class="paragraph">
<p>Regards,</p>
</div>
<div class="paragraph">
<p>Marc</p>
</div>
<meta property="og:image" content="https://avatars2.githubusercontent.com/u/423513?v=4" />
<meta property="og:image:url" content="https://avatars2.githubusercontent.com/u/423513?v=4" />
<meta property="og:image:type" content="image/jpeg" />]]></description><link>http://www.rhymewithgravy.com/2019/01/18/Farewell-Red-Hat-friends.html</link><guid isPermaLink="true">http://www.rhymewithgravy.com/2019/01/18/Farewell-Red-Hat-friends.html</guid><category><![CDATA[personal]]></category><dc:creator><![CDATA[Marc Savy]]></dc:creator><pubDate>Fri, 18 Jan 2019 00:00:00 GMT</pubDate></item><item><title><![CDATA[I was involved in a shocking incident and want to talk about mental health - and what we're doing as a country to address it.]]></title><description><![CDATA[<div id="preamble">
<div class="sectionbody">
<div class="admonitionblock warning">
<table>
<tr>
<td class="icon">
<i class="fa icon-warning" title="Warning"></i>
</td>
<td class="content">
<div class="paragraph">
<p>This post covers sensitive topics including attempted suicide and mental illness.</p>
</div>
<div class="paragraph">
<p>Please, if you ever have suicidal thoughts, reach out to an organisation such as <a href="https://www.samaritans.org/how-we-can-help-you/contact-us">The Samaritans</a>. People truly care about you.</p>
</div>
</td>
</tr>
</table>
</div>
<div class="paragraph">
<p>On 7th May, at about 10pm, I pulled back a suicidal man who was jumping off the Redheugh Bridge in Newcastle/Gateshead.</p>
</div>
<div class="paragraph">
<p>It was one of the most extraordinary and frightening moments in my life.</p>
</div>
<div class="paragraph">
<p>I wasn&#8217;t intending to go out at all on that day. At the last minute a friend called me and we decided to meet up. One thing led to another and we ended up going for a walk down the river and grabbing a few drinks. We then decided to go for something to eat, but the first choice was closed; we ended up going to a Japanese restaurant. The food was slow as it was very busy, so it was much later than expected when I started heading back home.</p>
</div>
<div class="paragraph">
<p>There&#8217;s a narrow walkway along the bridge, with 4 lanes of traffic and chest-high barriers to either side. I saw a large, shirtless, and shoeless man walking the opposite way to me. He suddenly straddled the barrier.</p>
</div>
<div class="paragraph">
<p>I ran towards him, grabbed his arm and started talking to him; trying to convince him not to jump. I said I wanted to hear what he had to say, and that I could see that he is in a dark place, but his life is valuable and important, and that although things seem awful now, they can improve.</p>
</div>
<div class="paragraph">
<p>He was talking back to me, but refused to come down; saying he was going to jump and kill himself.</p>
</div>
<div class="paragraph">
<p>A lady who seemed to have encountered him before ran up and also tried to persuade him to come down.</p>
</div>
<div class="paragraph">
<p>We were there for a good while talking back and forth as I tried to convince him, but he wasn&#8217;t coming back.</p>
</div>
<div class="paragraph">
<p>He eventually started objecting to me holding his arm, and kept pushing me off. So, I moved slightly behind him and tried to position myself as best I could.</p>
</div>
<div class="paragraph">
<p>Suddenly he went for it and started dropping off the side.</p>
</div>
<div class="paragraph">
<p>I had to try something, as things seemed to have reached a point of no return. I reached over and yanked him with all my force and, fortunately, dragged him back over, off the barrier, and onto the floor of the walkway.</p>
</div>
<div class="paragraph">
<p>He was pretty angry for a few moments, and he was a lot larger than me, so I probably took my chances. After a short while he started crying and said he is bipolar. I managed to keep him on the floor. He clearly was in a terribly dark place and mentioned awful reasons contributing to his state that I won&#8217;t repeat here.</p>
</div>
<div class="paragraph">
<p>I&#8217;m so glad for his sakes, and mine, that he didn&#8217;t go off and I was able to stop him. I think I would have been messed up for life if I&#8217;d seen him fall and die.</p>
</div>
<div class="paragraph">
<p>A passerby came as I was dragging the guy back over, and he called the emergency services. My phone had died so, unfortunately, I didn&#8217;t get to collect his details. I&#8217;m also going to reach out to the officers to see if I can send him my contact information to thank him in person and talk about what happened.</p>
</div>
<div class="paragraph">
<p>The Police arrived for the ill man soon after and took some of my information.</p>
</div>
<div class="paragraph">
<p>The suicidal man shook my hand and thanked me as they took him to hospital. One of the officers was a bit impatient with him because he wasn&#8217;t being completely cooperative. I guess they get compassion fatigue from seeing this sort of thing so frequently. I imagine the most challenging types of compassion and empathy are with types of people we aren&#8217;t innately sympathetic towards, and who don&#8217;t necessarily cooperate.</p>
</div>
<div class="paragraph">
<p>The officers gave me a lift back home and suggested I "have a stiff drink". I was so amped up I couldn&#8217;t sleep for several hours; felt weird for a few days, but I&#8217;m perfectly okay now.</p>
</div>
<div class="paragraph">
<p>It really strikes me that my coincidental encounter with this man was promulgated by a huge sequence of unusual events and timings. With the smallest change I would have missed him, or worse, seen him drop. I wasn&#8217;t planning to go out at all, let alone planning to be out late.</p>
</div>
<div class="paragraph">
<p>I&#8217;m writing about this for a few reasons:</p>
</div>
<div class="paragraph">
<p>Firstly, we need to do much better at looking after people with severe mental health issues. I&#8217;ve become increasingly concerned over the last few years about underfunding of mental health care causing people who ought to be receiving intensive levels of care to be sent home when it is not in their best interests. I hope by recounting this it makes some people rethink how much they are willing to contribute to ensure we are able to offer sufficient care to vulnerable people. I truly hope he gets the care he needs - given the extremity of the issue hopefully he&#8217;ll be prioritised.</p>
</div>
<div class="paragraph">
<p>He said he&#8217;d felt suicidal many times before but nobody had taken him seriously. I&#8217;d guess his perception is likely shaped through the lens of his illness, but the fact he was wandering around half-naked in such a distressed state is a terrible shame.</p>
</div>
<div class="paragraph">
<p>I hope everyone would try to help a stranger in such a state. I asked a couple of (homeless, I think) guys walking past to help, but they just ignored me and walked off. We&#8217;re nothing if we don&#8217;t help one another.</p>
</div>
<div class="paragraph">
<p>People with addiction and mental health issues are often at the bottom of the pile in society. This encounter really reminded me that we need to be better to one another and do more to address MH concerns. I&#8217;m cognisant that many people are extremely difficult to deal with and there are no easy solutions, but perhaps we don&#8217;t have the balance right.</p>
</div>
<div class="paragraph">
<p>I think the barriers are far too low on the Redheugh bridge. I realise that a thoroughly determined person will defeat any measures, but my understanding is that many suicides are spur-of-the-moment, and modest impediments can help delay their actions long enough for them to find the clarity they need to reconsider. Perhaps they need to think about nets or similar devices that have been used successfully in other locations. I plan to bring it up with my MP, but I&#8217;m sure it ultimately comes down to a lack of funding and/or structural issues.</p>
</div>
</div>
</div>
<div class="sect2">
<h3 id="_follow_up">Follow-up</h3>
<div class="paragraph">
<p>I went down to the police station the next day to give them my phone number. An officer emailed later asking what I wanted to know, but then didn&#8217;t bother responding to my message. I had wanted to make myself available to give a full statement and record the very serious things the man had told me; they would have been relevant to his treatment team (and likely legally). I guess it was too much hassle.</p>
</div>
<div class="paragraph">
<p>If you made it this far: thank you for reading.</p>
</div>
<meta name="og:image" content="https://www.rhymewithgravy.com/images/neurons.jpg" />
<meta name="twitter:description" content="I was involved in a shocking incident and want to talk about mental health - and what we're doing as a country to address it." />
</div>]]></description><link>http://www.rhymewithgravy.com/2018/05/18/I-was-involved-in-a-shocking-incident-and-want-to-talk-about-mental-health-and-what-were-doing-as-a-country-to-address-it.html</link><guid isPermaLink="true">http://www.rhymewithgravy.com/2018/05/18/I-was-involved-in-a-shocking-incident-and-want-to-talk-about-mental-health-and-what-were-doing-as-a-country-to-address-it.html</guid><category><![CDATA[personal]]></category><dc:creator><![CDATA[Marc Savy]]></dc:creator><pubDate>Fri, 18 May 2018 00:00:00 GMT</pubDate></item><item><title><![CDATA[Introducing asciidoc-admonition-icons, a GitBook plugin to restore font icons for AsciiDoc admonition blocks.]]></title><description><![CDATA[<div id="preamble">
<div class="sectionbody">
<div class="paragraph">
<p>I&#8217;ve been working hard on the <a href="https://github.com/msavy/apiman-docs-installation-guide">apiman 1.3.x documentation</a>.
One nice feature of AsciiDoc/Asciidoctor are <a href="http://asciidoctor.org/docs/user-manual/#admonition">admonition blocks</a>; allowing visually clear and categorised emphasis for the important points.</p>
</div>
<div class="paragraph">
<p>However, at the time of writing this blog, the <a href="https://toolchain.gitbook.com/syntax/asciidoc.html">GitBook AsciiDoc</a> 3.x.x rendering pipeline does <em>not</em> support icons for admonition blocks, providing an inconspicuous, text-only representation:</p>
</div>
<div class="imageblock">
<div class="content">
<img src="https://cloud.githubusercontent.com/assets/423513/25775568/fbde3670-329f-11e7-9e5a-a5a1e716be38.png" alt="fbde3670 329f 11e7 9e5a a5a1e716be38.png">
</div>
</div>
<div class="paragraph">
<p>There are some PRs and GitHub issues with people trying to get this fixed, but none of them has been merged, so I really wanted to provide an interim solution that would still work on the gitbook.com hosted platform.</p>
</div>
</div>
</div>
<div class="sect1">
<h2 id="_plugin_to_the_rescue">Plugin to the rescue.</h2>
<div class="sectionbody">
<div class="paragraph">
<p>The solution was to <a href="https://plugins.gitbook.com/plugin/asciidoc-admonition-icons">create a simple plugin</a>, <code>asciidoc-admonition-icons</code> <sup class="footnote">[<a id="_footnoteref_1" class="footnote" href="#_footnote_1" title="View footnote.">1</a>]</sup>, that identifies admonition blocks and rewrites the label element to contain the missing glyphs:</p>
</div>
<div class="imageblock">
<div class="content">
<img src="https://cloud.githubusercontent.com/assets/423513/25775581/46741c22-32a0-11e7-9279-7c7d5d27e280.png" alt="46741c22 32a0 11e7 9279 7c7d5d27e280.png">
</div>
</div>
<div class="paragraph">
<p>The default styling provides a similar look-and-feel to the Asciidoctor&#8217;s standard theme; with FontAwesome icons and a comparable colour scheme.
Naturally, you can override both the glyphs and styling.</p>
</div>
<div class="paragraph">
<p>This should hopefully provide a satisfactory workaround until the GitBook team resolve the issue properly in their codebase.</p>
</div>
<div class="paragraph">
<p>If you have any problems, please feel free to file an issue.</p>
</div>
</div>
</div>
<div class="sect1">
<h2 id="_installation_configuration">Installation &amp; Configuration</h2>
<div class="sectionbody">
<div class="paragraph">
<p>In your <code>book.json</code>, put <code>asciidoc-admonition-icons</code> in your <code>plugins</code> array</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-json" data-lang="json">{
	"plugins": ["asciidoc-admonition-icons"],
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>Provide your overrides in <code>pluginsConfig.admonitions</code>:</p>
</div>
<div class="ulist">
<ul>
<li>
<p>The 5 standard AsciiDoc admonition types are available:</p>
</li>
<li>
<p><code>classes</code>: CSS classes of the admonition icon container.</p>
</li>
<li>
<p><code>title</code>: HTML title attribute of admonition icon container.</p>
</li>
<li>
<p><code>content</code>: Unicode value of glyph to use.</p>
</li>
</ul>
</div>
<div class="paragraph">
<p>The entire set of defaults are shown here for illustrative purposes, but you need only provide those you&#8217;re overriding:</p>
</div>
<div class="paragraph">
<p><strong>Example book.json configuration:</strong></p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-json" data-lang="json">"pluginsConfig": {
    "admonitions": {
        "note": {
            "classes": "fa icon-note",
            "title": "Note",
            "content": "\uf05a"
        },
        "tip": {
            "classes": "fa icon-tip",
            "title": "Tip",
            "content": "\uf0eb"
        },
        "important": {
            "classes": "fa icon-important",
            "title": "Important",
            "content": "\uf06a"
        },
        "caution": {
            "classes": "fa icon-caution",
            "title": "Caution",
            "content": "\uf06d"
        },
        "warning": {
            "classes": "fa icon-warning",
            "title": "Warning",
            "content": "\uf071"
        }
    }
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>For example, if we were to override the <code>important</code> icon with another glyph:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-json" data-lang="json">"important": {
	"classes": "fa icon-important",
    "title": "La bañera es muy importante!",
    "content": "\uf2cd"
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>Check out the plugin&#8217;s <a href="https://plugins.gitbook.com/plugin/asciidoc-admonition-icons">GitBook plugin page</a>, <a href="https://github.com/msavy/gitbook-plugin-asciidoc-admonition-icons#installation">GitHub repo</a> or <a href="https://www.npmjs.com/package/gitbook-plugin-asciidoc-admonition-icons">NPM readme</a> for detailed instructions.</p>
</div>
<div class="paragraph">
<p>Despite being simple code, quite interesting customisations are possible using a combination of configuration options and CSS. I might add some more sophisticated examples in a future blog post (refer to the docs for some simple ones).</p>
</div>
</div>
</div>
<div id="footnotes">
<hr>
<div class="footnote" id="_footnote_1">
<a href="#_footnoteref_1">1</a>. Full NPM package name is: <code>gitbook-plugin-asciidoc-admonition-icons</code>
</div>
</div>]]></description><link>http://www.rhymewithgravy.com/2017/05/07/Introducing-asciidoc-admonition-icons-a-Git-Book-plugin-to-restore-font-icons-for-Ascii-Doc-admonition-blocks.html</link><guid isPermaLink="true">http://www.rhymewithgravy.com/2017/05/07/Introducing-asciidoc-admonition-icons-a-Git-Book-plugin-to-restore-font-icons-for-Ascii-Doc-admonition-blocks.html</guid><category><![CDATA[gitbook]]></category><category><![CDATA[ gitbook-plugin]]></category><category><![CDATA[ asciidoc]]></category><category><![CDATA[ asciidoctor]]></category><dc:creator><![CDATA[Marc Savy]]></dc:creator><pubDate>Sun, 07 May 2017 00:00:00 GMT</pubDate></item><item><title><![CDATA[Generic JWT policy for apiman]]></title><description><![CDATA[<div id="preamble">
<div class="sectionbody">
<div class="paragraph">
<p>I just pushed an initial (very simple) generic JWT authentication plugin policy to master. It should work with any JWT provider! Let me know how it works for you.</p>
</div>
<hr>
<div class="paragraph">
<p><strong>Update on 23/01/07</strong>: The JWT plugin has now been released to Maven, you can install it via:</p>
</div>
<div class="dlist">
<dl>
<dt class="hdlist1">G</dt>
<dd>
<p>io.apiman.plugins</p>
</dd>
<dt class="hdlist1">A</dt>
<dd>
<p>apiman-plugins-jwt-policy</p>
</dd>
<dt class="hdlist1">V</dt>
<dd>
<p>1.2.9.Final (or whatever the latest/matching version of apiman is)</p>
</dd>
</dl>
</div>
<hr>
<div class="paragraph">
<p>Old Instructions:</p>
</div>
</div>
</div>
<div class="sect1">
<h2 id="_build_and_install">Build and install</h2>
<div class="sectionbody">
<div class="paragraph">
<p>To try it out immediately you will need to build it from source. Just check out the <a href="https://github.com/apiman/apiman-plugins">apiman/apiman-plugins</a> repo and execute:</p>
</div>
<div class="paragraph">
<p><code>mvn clean install</code></p>
</div>
<div class="paragraph">
<p>The plugin coordinates will be:</p>
</div>
<div class="dlist">
<dl>
<dt class="hdlist1">G</dt>
<dd>
<p>io.apiman.plugins</p>
</dd>
<dt class="hdlist1">A</dt>
<dd>
<p>apiman-plugins-jwt-policy</p>
</dd>
<dt class="hdlist1">V</dt>
<dd>
<p>1.2.9-SNAPSHOT</p>
</dd>
</dl>
</div>
<div class="paragraph">
<p>It isn&#8217;t yet as feature-rich as the <a href="http://www.apiman.io/blog/gateway/security/oauth2/keycloak/authentication/authorization/1.2.x/2016/01/22/keycloak-oauth2-redux.html">Keycloak plugin</a>, but you can:</p>
</div>
<div class="ulist">
<ul>
<li>
<p>Require JWT.</p>
</li>
<li>
<p>Require claims (e.g. sub = foo).</p>
</li>
<li>
<p>Require transport security (TLS, SSL).</p>
</li>
<li>
<p>Require JWT be cryptographically signed (aka. JWS).</p>
</li>
<li>
<p>Validate JWT against a provided public key.</p>
</li>
<li>
<p>Remove auth tokens (prevent them reaching the backend).</p>
</li>
<li>
<p>Set maximum clock skew.</p>
</li>
</ul>
</div>
<div class="paragraph">
<p>I&#8217;ll expand on this in the near future to add some commonly-used features from the Keycloak plugin:</p>
</div>
<div class="ulist">
<ul>
<li>
<p>Extraction of roles for authorization</p>
</li>
<li>
<p><s>Forward token fields as headers (e.g. X-Sub = sub)</s> ✓</p>
</li>
</ul>
</div>
</div>
</div>
<div class="sect1">
<h2 id="_how_to_use_it">How to use it</h2>
<div class="sectionbody">
<div class="paragraph">
<p>Either:</p>
</div>
<div class="ulist">
<ul>
<li>
<p>Set the <code>Authorization</code> header as <code>Authorization: Bearer &lt;B64 encoded token&gt;</code></p>
</li>
<li>
<p>Set the <code>access_token</code> query parameter as <code>example.com?access_token=&lt;B64 encoded token&gt;</code></p>
</li>
</ul>
</div>
</div>
</div>]]></description><link>http://www.rhymewithgravy.com/2016/12/01/Generic-JWT-policy-for-apiman.html</link><guid isPermaLink="true">http://www.rhymewithgravy.com/2016/12/01/Generic-JWT-policy-for-apiman.html</guid><category><![CDATA[apiman]]></category><category><![CDATA[ apiman-gateway]]></category><category><![CDATA[ apiman-custom-policies]]></category><category><![CDATA[ jwt]]></category><category><![CDATA[ security]]></category><dc:creator><![CDATA[Marc Savy]]></dc:creator><pubDate>Thu, 01 Dec 2016 00:00:00 GMT</pubDate></item><item><title><![CDATA[Apiman's New Execute Blocking Component]]></title><description><![CDATA[<div id="preamble">
<div class="sectionbody">
<div class="paragraph">
<p>The Execute Blocking component is a small but potentially useful <a href="https://github.com/apiman/apiman/pull/509">new component I&#8217;ve written and committed to the apiman gateway</a>, allowing <a href="http://www.apiman.io/latest/developer-guide.html#_plugins">custom policy plugin</a> authors to <em>safely execute blocking code</em>.</p>
</div>
</div>
</div>
<div class="sect1">
<h2 id="_blocking_is_bad_but">Blocking is bad, but&#8230;&#8203;</h2>
<div class="sectionbody">
<div class="paragraph">
<p>Apiman&#8217;s gateway embraces non-blocking and asychronous design principles in order to best exploit the beneficial performance characteristics of platforms such as <a href="http://vertx.io/">Vert.x</a>.</p>
</div>
<div class="paragraph">
<p>A constraint of this approach means that code must not block the thread it is executing upon for excessive periods of time, lest an entire reactor (and often physical core) becomes completely unavailable; blocking on IO or holding locks for example. For those who are interested <a href="https://www.rhymewithgravy.com/2016/10/18/Vertx-and-Blocking-Code.html">I explored this issue in more depth in a previous post</a>, but safe to say, this <em>golden rule</em> can be difficult to abide by in the real world where libraries and protocols outside of our control may not behave as we need.</p>
</div>
<div class="paragraph">
<p>The Execute Blocking Component (<code>IExecuteBlockingComponent</code>) comes to our rescue, providing a mechanism to execute blocking code <em>from a threadpool</em> rather than directly on the reactor.</p>
</div>
<div class="paragraph">
<p>Needless to say, special attention should be paid to its limitations and characteristics. Only use this functionality when strictly necessary, and with the smallest practical scope, as it substantially reduces the performance benefits of the underlying non-blocking architecture.</p>
</div>
</div>
</div>
<div class="sect1">
<h2 id="_execute_blocking">Execute Blocking</h2>
<div class="sectionbody">
<div class="paragraph">
<p>Here&#8217;s a short example of the component in action:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-java" data-lang="java">void doApply(ApiRequest request, IPolicyContext context,
    IPolicyChain&lt;ApiRequest&gt; chain) {

    IExecuteBlockingComponent ebComponent =
        context.getComponent("IExecuteBlockingComponent.class");

        ebComponent.executeBlocking(future -&gt; { <i class="conum" data-value="1"></i><b>(1)</b>
            String result = BlockingService(50000); <i class="conum" data-value="2"></i><b>(2)</b>
            future.completed(result); <i class="conum" data-value="3"></i><b>(3)</b>
        },
        result -&gt; { <i class="conum" data-value="4"></i><b>(4)</b>
            if (result.successful()) {
                request.getHeaders().put("Foo", request.getResult()) <i class="conum" data-value="5"></i><b>(5)</b>
                chain.doApply(request);
            } else {
                chain.doFailure(new PolFailure(result.getError())); <i class="conum" data-value="6"></i><b>(6)</b>
            }
        });
}</code></pre>
</div>
</div>
<div class="colist arabic">
<table>
<tr>
<td><i class="conum" data-value="1"></i><b>1</b></td>
<td>Execute your blocking code within the first lambda, and indicate to the <code>future</code> when your code has terminated, either <code>completed</code> or <code>fail</code>. Exceptions thrown within the scope of the lambda will be caught and implicitly passed to <code>fail</code>.</td>
</tr>
<tr>
<td><i class="conum" data-value="2"></i><b>2</b></td>
<td>Imaginary blocking service that blocks for 50000ms.</td>
</tr>
<tr>
<td><i class="conum" data-value="3"></i><b>3</b></td>
<td>Indicating the future has completed successfully and passing the result to <code>completed</code>.</td>
</tr>
<tr>
<td><i class="conum" data-value="4"></i><b>4</b></td>
<td>The result is passed to this second lambda <em>asynchronously</em>.</td>
</tr>
<tr>
<td><i class="conum" data-value="5"></i><b>5</b></td>
<td>Set our successful result as a header <code>Foo</code>.</td>
</tr>
<tr>
<td><i class="conum" data-value="6"></i><b>6</b></td>
<td>Creating a policy failure with the error.</td>
</tr>
</table>
</div>
<div class="admonitionblock important">
<table>
<tr>
<td class="icon">
<i class="fa icon-important" title="Important"></i>
</td>
<td class="content">
Only use <em>executeBlocking</em> when absolutely necessary and constrain it as tightly as possible.
</td>
</tr>
</table>
</div>
</div>
</div>
<div class="sect1">
<h2 id="_apiman_on_blocking_platforms">Apiman on blocking platforms</h2>
<div class="sectionbody">
<div class="paragraph">
<p>You may be wondering what happens if you use <code>executeBlocking</code> on an apiman platform which has backed by a implementation where it&#8217;s safe to block the executing thread (such a servlet on WildFly). Simply, a passthrough implementation is used on those platforms which executes immediately on the same thread - so it&#8217;s safe to use on any platform.</p>
</div>
<div class="paragraph">
<p>Even if you tend to run your plugins on a blocking platform you should still respect the "no blocking the main thread" rule and use <code>executeBlocking</code>, as other platforms and users <em>will</em> expect this guarantee - it&#8217;s especially crucial if you wish to share your work with the community.</p>
</div>
</div>
</div>
<div class="sect1">
<h2 id="_final_words">Final Words</h2>
<div class="sectionbody">
<div class="paragraph">
<p>This is the first commit of this code onto master, so changes are possible. This feature is directly designed to enable the use of Vert.x, so their interface has been adopted fairly closely, so many thanks to them again for their brilliant work which we&#8217;re fortunate to be able harness in apiman.</p>
</div>
</div>
</div>]]></description><link>http://www.rhymewithgravy.com/2016/11/27/Apimans-New-Execute-Blocking-Component.html</link><guid isPermaLink="true">http://www.rhymewithgravy.com/2016/11/27/Apimans-New-Execute-Blocking-Component.html</guid><category><![CDATA[apiman]]></category><category><![CDATA[ apiman-gateway]]></category><category><![CDATA[ apiman-components]]></category><category><![CDATA[ apiman-custom-policies]]></category><dc:creator><![CDATA[Marc Savy]]></dc:creator><pubDate>Sun, 27 Nov 2016 00:00:00 GMT</pubDate></item><item><title><![CDATA[Stopping Vert.x BlockedThreadChecker exceptions during interactive debugging]]></title><description><![CDATA[<div id="preamble">
<div class="sectionbody">
<div class="paragraph">
<p>Vert.x&#8217;s standard verticles require <a href="https://www.rhymewithgravy.com/2016/10/18/Vertx-and-Blocking-Code.html">non-blocking code</a> to work optimally. A watchdog will warn you (extremely insistently) if anything does block for an excessive period. However, if you&#8217;re just trying to run an interactive debugger <sup class="footnote">[<a id="_footnoteref_1" class="footnote" href="#_footnote_1" title="View footnote.">1</a>]</sup> then this can become extremely annoying as your console is flooded with <code>io.vertx.core.impl.BlockedThreadChecker</code> exceptions that look something like this:</p>
</div>
<script src="https://gist.github.com/msavy/cffdaa3c3e4dcb2395b09666f09e4cae.js"></script>
<div id="toc" class="toc">
<div id="toctitle" class="title">Sections</div>
<ul class="sectlevel1">
<li><a href="#_what_s_the_cause">What&#8217;s the cause?</a></li>
<li><a href="#_workarounds">Workarounds</a>
<ul class="sectlevel2">
<li><a href="#_via_system_properties">Via System Properties</a></li>
<li><a href="#_directly_in_vertxoptions">Directly in VertxOptions</a></li>
</ul>
</li>
<li><a href="#_caveats_conclusion">Caveats &amp; Conclusion</a></li>
</ul>
</div>
</div>
</div>
<div class="sect1">
<h2 id="_what_s_the_cause">What&#8217;s the cause?</h2>
<div class="sectionbody">
<div class="paragraph">
<p>The exceptions occur because the interactive debugger repeatedly <em>halts the event loop thread</em> while you use it: browsing around, poking at variables, stepping through your program, etc. The length of time it takes to execute the event being debugged will be drastically longer than normal; hence the watchdog starts barking.</p>
</div>
<div class="paragraph">
<p>Mercifully there&#8217;s a simple solution, which involves setting <code>blockedThreadCheckInterval</code> to a sufficiently long time. <sup class="footnote">[<a id="_footnoteref_2" class="footnote" href="#_footnote_2" title="View footnote.">2</a>]</sup></p>
</div>
<div class="admonitionblock important">
<table>
<tr>
<td class="icon">
<i class="fa icon-important" title="Important"></i>
</td>
<td class="content">
<div class="title">The following should only be used for debugging purposes!</div>
<strong>If your production code is throwing BlockedThreadChecker exceptions, then you have a problem you need to fix.</strong>
</td>
</tr>
</table>
</div>
</div>
</div>
<div class="sect1">
<h2 id="_workarounds">Workarounds</h2>
<div class="sectionbody">
<div class="sect2">
<h3 id="_via_system_properties">Via System Properties</h3>
<div class="paragraph">
<p>Whether you&#8217;re using <a href="http://vertx.io/docs/apidocs/io/vertx/core/Launcher.html">Launcher</a> (which has supplanted Starter) or the Vert.x CLI, pass the following VM argument:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-java" data-lang="java">-Dvertx.options.blockedThreadCheckInterval=200000000 <i class="conum" data-value="1"></i><b>(1)</b></code></pre>
</div>
</div>
<div class="colist arabic">
<table>
<tr>
<td><i class="conum" data-value="1"></i><b>1</b></td>
<td>Some sufficiently large integer (milliseconds).</td>
</tr>
</table>
</div>
<div class="paragraph">
<p>All IDEs also support setting system properties in some fashion. I&#8217;ve briefly outlined Eclipse and IntelliJ below, but the procedure should be similar for others.</p>
</div>
<div class="paragraph">
<p><strong>Eclipse</strong> Debug Configurations &#8594; Arguments &#8594; VM Arguments</p>
</div>
<div class="paragraph">
<p><strong>IntelliJ</strong> Edit Configurations &#8594; Select Application &#8594; Configuration &#8594; VM Options</p>
</div>
<div class="admonitionblock tip">
<table>
<tr>
<td class="icon">
<i class="fa icon-tip" title="Tip"></i>
</td>
<td class="content">
Setting blockedThreadCheckInterval via system properties is likely the best approach; avoiding debug-specific behaviour leaking into your code.
</td>
</tr>
</table>
</div>
</div>
<div class="sect2">
<h3 id="_directly_in_vertxoptions">Directly in VertxOptions</h3>
<div class="paragraph">
<p>If you are not using the CLI or Launcher, or for some reason wish to avoid using system properties, then you can simply set the interval in <a href="http://vertx.io/docs/apidocs/io/vertx/core/VertxOptions.html">VertxOptions</a> directly.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-java" data-lang="java">VertxOptions vxOptions = new VertxOptions()
	.setblockedThreadCheckInterval(200000000); <i class="conum" data-value="1"></i><b>(1)</b>
Vertx myVertx = Vertx.vertx(vxOptions); <i class="conum" data-value="2"></i><b>(2)</b></code></pre>
</div>
</div>
<div class="colist arabic">
<table>
<tr>
<td><i class="conum" data-value="1"></i><b>1</b></td>
<td>Set interval in <code>VertxOptions</code>.</td>
</tr>
<tr>
<td><i class="conum" data-value="2"></i><b>2</b></td>
<td>Pass options to <code>Vertx.vertx()</code> factory.</td>
</tr>
</table>
</div>
</div>
</div>
</div>
<div class="sect1">
<h2 id="_caveats_conclusion">Caveats &amp; Conclusion</h2>
<div class="sectionbody">
<div class="paragraph">
<p>It&#8217;s worth remembering that by halting executing thread(s) in the debugger you may not encounter timing-related issues you otherwise would. So, it is wise to ensure you aren&#8217;t altering <code>blockedThreadCheckInterval</code> unless you really need to.</p>
</div>
<div class="paragraph">
<p>Needless to say, seeing BlockedThreadChecker warnings in production is a symptom of pathological code behaviour, indicating that the event loop is being blocked for excessive periods; you should fix it rather than altering timeouts.</p>
</div>
<div class="paragraph">
<p>Finally, you should normally prefer the <a href="#_via_system_properties">system properties</a> approach so that you can isolate this change to your debugging profiles only.</p>
</div>
<meta name="og:image" content="https://www.rhymewithgravy.com/images/Vert-x-Logo-X.png" />
</div>
</div>
<div id="footnotes">
<hr>
<div class="footnote" id="_footnote_1">
<a href="#_footnoteref_1">1</a>. Eclipse, IntelliJ, NetBeans, etc.
</div>
<div class="footnote" id="_footnote_2">
<a href="#_footnoteref_2">2</a>. Had this as maxEventLoopExecuteTime in a previous revision of the blog, but this doesn&#8217;t work consistently.
</div>
</div>]]></description><link>http://www.rhymewithgravy.com/2016/10/24/Stopping-Vertx-Blocked-Thread-Checker-exceptions-during-interactive-debugging.html</link><guid isPermaLink="true">http://www.rhymewithgravy.com/2016/10/24/Stopping-Vertx-Blocked-Thread-Checker-exceptions-during-interactive-debugging.html</guid><category><![CDATA[vertx]]></category><category><![CDATA[ devtip]]></category><dc:creator><![CDATA[Marc Savy]]></dc:creator><pubDate>Mon, 24 Oct 2016 00:00:00 GMT</pubDate></item><item><title><![CDATA[Vert.x  and Blocking Code]]></title><description><![CDATA[<div id="preamble">
<div class="sectionbody">
<div class="paragraph">
<p>One of Vert.x&#8217;s core tenets is that you should <a href="http://vertx.io/docs/vertx-core/java/#golden_rule">never block the event loop</a>. If you&#8217;re writing an application from scratch and limit yourself to Vert.x&#8217;s provided facilities you&#8217;ll not go far wrong.</p>
</div>
<div class="paragraph">
<p>However, if you&#8217;re writing a more complex application (such as apiman) there&#8217;s a good chance that you&#8217;ll be forced to stray outside of these boundaries, for example: integration constraints; inherently blocking protocols; static or shared data-structures. <sup class="footnote">[<a id="_footnoteref_1" class="footnote" href="#_footnote_1" title="View footnote.">1</a>]</sup></p>
</div>
<div class="paragraph">
<p>Luckily, the Vert.x team understand this, and have provided ways to work with these real-world requirements.</p>
</div>
<div class="paragraph">
<p>Back in the Vert.x 1.x and early 2.x days you only had one option: <a href="http://vertx.io/docs/vertx-core/java/#worker_verticles"><em>worker verticles</em></a>. Now the team have expanded things and there are several excellent options; so, let&#8217;s have a quick review of them. <sup class="footnote">[<a id="_footnoteref_2" class="footnote" href="#_footnote_2" title="View footnote.">2</a>]</sup></p>
</div>
<div id="toc" class="toc">
<div id="toctitle" class="title">Sections</div>
<ul class="sectlevel1">
<li><a href="#_why_is_blocking_bad_anyway">Why is blocking bad, anyway?</a></li>
<li><a href="#_solutions">Solutions</a>
<ul class="sectlevel2">
<li><a href="#_worker_verticles">Worker Verticles</a></li>
<li><a href="#_execute_blocking_statements">Execute Blocking Statements</a></li>
<li><a href="#_vert_x_sync">Vert.x Sync</a></li>
</ul>
</li>
</ul>
</div>
</div>
</div>
<div class="sect1">
<h2 id="_why_is_blocking_bad_anyway">Why is blocking bad, anyway?</h2>
<div class="sectionbody">
<div class="paragraph">
<p>Vert.x uses a pragmatic implementation of the reactor model (more specifically multi-reactor).</p>
</div>
<div class="paragraph">
<p>A simple way to visualise this is to imagine there is only one thread per core, looping indefinitely, and executing work (handlers) from a queue. Many verticle instances share a given reactor; their execution is also <em>enqueued</em> as a task and runs asynchronously - that is, it only runs when the reactor has churned through any preceding tasks and reaches the verticle&#8217;s task(s). Each task runs <em>on the reactor thread directly</em>.</p>
</div>
<div class="paragraph">
<p>Hence, if any of those enqueued tasks executed a blocking operation, such as listening on a socket, <em>the entire reactor</em> would be unable to make progress until the thread resumed.<sup class="footnote">[<a id="_footnoteref_3" class="footnote" href="#_footnote_3" title="View footnote.">3</a>]</sup></p>
</div>
<div class="paragraph">
<p>Instead, Vert.x deals with blocking operations <em>outside of the event loop</em>; enqueuing a handler to be invoked when <em>the result</em> of the blocking operation is completed <sup class="footnote">[<a id="_footnoteref_4" class="footnote" href="#_footnote_4" title="View footnote.">4</a>]</sup>. For instance, instead of blocking on a socket until something arrives, we ask the operating system to call us back when something relevant arrives and invoke our handler with the result.</p>
</div>
<div class="admonitionblock tip">
<table>
<tr>
<td class="icon">
<i class="fa icon-tip" title="Tip"></i>
</td>
<td class="content">
The key benefit of this approach is that the reactor thread <em>does not need to block</em>, so it can achieve excellent CPU utilisation - spending as much of its time as possible usefully executing, rather than waiting or being blocked.
</td>
</tr>
</table>
</div>
<div class="paragraph">
<p>In contrast, the typical webserver&#8217;s threads will spend much of their time in a non-running state (e.g. blocked or waiting), leaving large amounts of CPU time unused <sup class="footnote">[<a id="_footnoteref_5" class="footnote" href="#_footnote_5" title="View footnote.">5</a>]</sup>. To combat resource under-utilisation developers harness large numbers of threads so that new requests can continue to be satisfied. However, this incurs substantial CPU, memory and latency costs due to frequent <a href="https://en.wikipedia.org/wiki/Context_switch#Cost">context switching</a> <sup class="footnote">[<a id="_footnoteref_6" class="footnote" href="#_footnote_6" title="View footnote.">6</a>]</sup>.</p>
</div>
<div class="paragraph">
<p>But, what if you <em>need</em> to do a blocking operation and it&#8217;s  not one of Vert.x&#8217;s supported things?</p>
</div>
</div>
</div>
<div class="sect1">
<h2 id="_solutions">Solutions</h2>
<div class="sectionbody">
<div class="sect2">
<h3 id="_worker_verticles">Worker Verticles</h3>
<div class="paragraph">
<p>The first approach Vert.x offered was <a href="http://vertx.io/docs/vertx-core/java/#worker_verticles">worker verticles</a>. Each worker verticle instance executes entirely on its own thread taken from a threadpool, hence when an operation blocks it does not affect the event loop or block progress.</p>
</div>
<div class="paragraph">
<p>If your verticle&#8217;s work is <em>predominantly</em> blocking, then a worker verticle is a good option. You can use the pattern outlined in the example below to send and receive work over the event bus - this maintains asynchronicity and non-blocking behaviour in your standard verticles whilst allowing you to offload long-running, blocking functionality onto worker verticles. You should aim to minimise the amount of code run in worker verticles to maximise overall resource utilisation. <sup class="footnote">[<a id="_footnoteref_7" class="footnote" href="#_footnote_7" title="View footnote.">7</a>]</sup></p>
</div>
<div class="sect3">
<h4 id="_offering_a_blocking_service">Offering a blocking service</h4>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-java" data-lang="java">package com.example.foo;

public class BlockingVerticle extends AbstractVerticle {
    @Override
    public void start() throws Exception {
        vertx.eventBus().&lt;String&gt;consumer("com.rhymewithgravy.doesit",
            message -&gt; { <i class="conum" data-value="1"></i><b>(1)</b>
                boolean answer = SlowBlockingRhyme
                    .doesItRhymeWithGravy(message.body()); <i class="conum" data-value="2"></i><b>(2)</b>
                message.reply(answer);
            } );
    }

    public static void main(String... args) {
        DeploymentOptions opts = new DeploymentOptions()
            .setWorker(true); <i class="conum" data-value="3"></i><b>(3)</b>
        Vertx.vertx()
            .deployVerticle("com.example.foo.BlockingVerticle", opts); <i class="conum" data-value="4"></i><b>(4)</b>
    }
}</code></pre>
</div>
</div>
<div class="colist arabic">
<table>
<tr>
<td><i class="conum" data-value="1"></i><b>1</b></td>
<td>Listening (non-blocking) on the event bus.</td>
</tr>
<tr>
<td><i class="conum" data-value="2"></i><b>2</b></td>
<td>A service that blocks while it figures out if a word rhymes with gravy. Mostly the answer is no.</td>
</tr>
<tr>
<td><i class="conum" data-value="3"></i><b>3</b></td>
<td>Setting the verticle to be deployed as a worker with <code>setWorker(true)</code>.</td>
</tr>
<tr>
<td><i class="conum" data-value="4"></i><b>4</b></td>
<td>Deploying the verticle, as normal.</td>
</tr>
</table>
</div>
</div>
<div class="sect3">
<h4 id="_consuming_a_blocking_service">Consuming a blocking service</h4>
<div class="paragraph">
<p>Here&#8217;s an example of the some non-blocking sender code which may interact with our fictional service over the event bus:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-java" data-lang="java">vertx.eventBus().send("com.rhymewithgravy.com.doesit", <i class="conum" data-value="1"></i><b>(1)</b>
    "apples", <i class="conum" data-value="2"></i><b>(2)</b>
    reply -&gt; {
        System.out.println("Does apples rhyme with gravy? "
            + reply.result().body()); <i class="conum" data-value="3"></i><b>(3)</b>
    }
);</code></pre>
</div>
</div>
<div class="colist arabic">
<table>
<tr>
<td><i class="conum" data-value="1"></i><b>1</b></td>
<td>Send a message to the service over the event bus.</td>
</tr>
<tr>
<td><i class="conum" data-value="2"></i><b>2</b></td>
<td>Contents of message to send (i.e. word we want to send to rhyme service).</td>
</tr>
<tr>
<td><i class="conum" data-value="3"></i><b>3</b></td>
<td>Print out the blocking service&#8217;s response:  "no", I would presume!</td>
</tr>
</table>
</div>
</div>
</div>
<div class="sect2">
<h3 id="_execute_blocking_statements">Execute Blocking Statements</h3>
<div class="paragraph">
<p>If the majority of your verticle&#8217;s work <em>does not</em> involve blocking (which is probably the most common scenario), then executing the entire verticle on a worker thread is rather wasteful. Even with clever optimisations it isn&#8217;t fully exploiting the platform&#8217;s strengths.</p>
</div>
<div class="paragraph">
<p>It is possible to work around this limitation by separating blocking and non-blocking code into distinct verticles, with the event bus acting as the asynchronous bridge to avoid the blocking verticle stopping progress in the non-blocking verticle  <sup class="footnote">[<a id="_footnoteref_8" class="footnote" href="#_footnote_8" title="View footnote.">8</a>]</sup>. However, this can be rather unwieldy and forces additional boilerplate and complexity where it isn&#8217;t desirable.</p>
</div>
<div class="paragraph">
<p>So, a newer and much more elegant solution was introduced for exactly these scenarios: <em>executeBlocking</em>.</p>
</div>
<div class="paragraph">
<p>Code in an <code>executeBlocking</code> handler will be run from a worker threadpool where it is safe to block, with the results passed back asynchronously.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-java" data-lang="java">vertx.executeBlocking(future -&gt; {
    boolean result = FastBlockingRhyme.doesItRhymeWithGravy("apples"); <i class="conum" data-value="1"></i><b>(1)</b>
    future.complete(result); <i class="conum" data-value="2"></i><b>(2)</b>
}, res -&gt; {
    if (res.succeeded()) {
        System.out.println("Does apples rhyme with gravy?  "
          + res.result()); <i class="conum" data-value="3"></i><b>(3)</b>
    }
});</code></pre>
</div>
</div>
<div class="colist arabic">
<table>
<tr>
<td><i class="conum" data-value="1"></i><b>1</b></td>
<td>New improved rhyme engine, it blocks but is fast.</td>
</tr>
<tr>
<td><i class="conum" data-value="2"></i><b>2</b></td>
<td>Indicate that the work in the block has been completed: successfully or otherwise.</td>
</tr>
<tr>
<td><i class="conum" data-value="3"></i><b>3</b></td>
<td>The result pops out in the second lambda, and we print out a helpful message.</td>
</tr>
</table>
</div>
<div class="paragraph">
<p>In this sample <em>executeBlocking</em> accomplishes the same work as the event bus pattern shown in the <a href="#_worker_verticles">Worker Verticles</a> example, but in a much more concise, efficient and less error-prone manner.</p>
</div>
<div class="admonitionblock tip">
<table>
<tr>
<td class="icon">
<i class="fa icon-tip" title="Tip"></i>
</td>
<td class="content">
<code>executeBlocking</code> should be the preferred way of running blocking code for most simple use cases.
</td>
</tr>
</table>
</div>
</div>
<div class="sect2">
<h3 id="_vert_x_sync">Vert.x Sync</h3>
<div class="paragraph">
<p><a href="http://vertx.io/docs/vertx-sync/java/">Sync</a> the newest area of development for handling blocking code in Vert.x, taking an extremely different approach to the aforementioned techniques. <a href="http://www.paralleluniverse.co/quasar/">Quasar</a> is used to offload blocking work onto <em>fibres</em>, which are extremely lightweight non-kernel threads that don&#8217;t incur the same context switching penalty as traditional threads.</p>
</div>
<div class="paragraph">
<p>It&#8217;s not an option which I&#8217;ve had the opportunity to explore in much depth yet, but I&#8217;m going to spend some time analysing it and follow up; for example, to <a href="https://twitter.com/jetdrone/status/787532093186306049">understand performance implications</a>, maintainability changes and deployment considerations. It sounds a promising area of research and development; asynchronous development tends to be trickier and can suffer from "handler inception" (excessive forwarding and handler hell) which Sync helps flatten out.</p>
</div>
<div class="paragraph">
<p>One of the most obvious differences is that you must instrument the JVM with the Quasar agent, and that the code modifications are coupled to a specific technology. It also only works with Java at the moment.</p>
</div>
<div class="paragraph">
<p>Watch this space!</p>
</div>
<meta name="og:image" content="https://www.rhymewithgravy.com/images/Vert-x-Logo-X.png" />
</div>
</div>
</div>
<div id="footnotes">
<hr>
<div class="footnote" id="_footnote_1">
<a href="#_footnoteref_1">1</a>. Usually you want to avoid these, but for various reasons you may be compelled to do so
</div>
<div class="footnote" id="_footnote_2">
<a href="#_footnoteref_2">2</a>. I&#8217;m assuming you have at least a passing understanding of how to write code in Vert.x)
</div>
<div class="footnote" id="_footnote_3">
<a href="#_footnoteref_3">3</a>. In the meanwhile the latency of waiting tasks is shooting up and work may have to be rejected via timeout.
</div>
<div class="footnote" id="_footnote_4">
<a href="#_footnoteref_4">4</a>. Or making progress in some meaningful way, such as streaming data.
</div>
<div class="footnote" id="_footnote_5">
<a href="#_footnoteref_5">5</a>. And reducing responsiveness if/when the threadpool is exhausted.
</div>
<div class="footnote" id="_footnote_6">
<a href="#_footnoteref_6">6</a>. Switching stacks and registry values; lots of thread state changes; etc
</div>
<div class="footnote" id="_footnote_7">
<a href="#_footnoteref_7">7</a>. There are more advanced options available, such as multithreaded workers which can help improve performance on specific workloads, but are out of the scope of this blogpost. Multithreaded workers require thread-safe code.
</div>
<div class="footnote" id="_footnote_8">
<a href="#_footnoteref_8">8</a>. I call this the <em>event bus pattern for blocking code</em>.
</div>
</div>]]></description><link>http://www.rhymewithgravy.com/2016/10/18/Vertx-and-Blocking-Code.html</link><guid isPermaLink="true">http://www.rhymewithgravy.com/2016/10/18/Vertx-and-Blocking-Code.html</guid><category><![CDATA[vertx]]></category><category><![CDATA[ apiman]]></category><dc:creator><![CDATA[Marc Savy]]></dc:creator><pubDate>Tue, 18 Oct 2016 00:00:00 GMT</pubDate></item><item><title><![CDATA[Byteman now available in homebrew]]></title><description><![CDATA[<div id="preamble">
<div class="sectionbody">
<div class="paragraph">
<p>A friend and colleague of mine, Andrew Dinn, is the brains behind the brilliant <a href="http://byteman.jboss.org/">Byteman project</a>. I recently contributed a <a href="http://brew.sh/">brew</a> formula to install Byteman and all of its scripts on OS X systems - allowing a package manager to sort out installing everything in sensible locations, with upgrading and other hassles handled for you.</p>
</div>
<div class="paragraph">
<p>Install brew if you haven&#8217;t, and then run <sup class="footnote">[<a id="_footnoteref_1" class="footnote" href="#_footnote_1" title="View footnote.">1</a>]</sup>:</p>
</div>
<div class="literalblock">
<div class="content">
<pre>$ brew install byteman</pre>
</div>
</div>
<div class="paragraph">
<p>If you need to, you can install the latest development version of Byteman with (e.g. ALPHA releases):</p>
</div>
<div class="literalblock">
<div class="content">
<pre>$ brew install byteman --devel</pre>
</div>
</div>
<div class="paragraph">
<p>You can upgrade Byteman with <sup class="footnote">[<a id="_footnoteref_2" class="footnote" href="#_footnote_2" title="View footnote.">2</a>]</sup>:</p>
</div>
<div class="literalblock">
<div class="content">
<pre>$ brew upgrade byteman</pre>
</div>
</div>
<div class="paragraph">
<p>You should now have all of the Byteman wrappers and binaries available on your path!</p>
</div>
<div class="literalblock">
<div class="content">
<pre>$ bmjava -version</pre>
</div>
</div>
</div>
</div>
<div class="sect1">
<h2 id="_what_s_byteman">What&#8217;s Byteman?</h2>
<div class="sectionbody">
<div class="paragraph">
<p>If you&#8217;re not familiar with Byteman, it&#8217;s an incredibly powerful byecode manipulation utility for testing, monitoring and tracing. It can be invoked via <a href="https://developer.jboss.org/wiki/ABytemanTutorial#top">scripts or API</a>.</p>
</div>
<div class="paragraph">
<p>It&#8217;s particularly useful for tracking down difficult-to-reproduce concurrency bugs, as you can use it to precisely orchestrate thread orderings (interleavings, etc), wait periods, inject faults etc. There are also some cool up-and-coming projects using it to dynamically inject <a href="https://github.com/hawkular/hawkular-apm">tracing and monitoring</a> into existing code.</p>
</div>
</div>
</div>
<div id="footnotes">
<hr>
<div class="footnote" id="_footnote_1">
<a href="#_footnoteref_1">1</a>. You may need to <code>brew update</code> to download the formula if you haven&#8217;t done so in a long time.
</div>
<div class="footnote" id="_footnote_2">
<a href="#_footnoteref_2">2</a>. Or just <code>brew upgrade</code> to do everything.
</div>
</div>]]></description><link>http://www.rhymewithgravy.com/2016/09/16/Byteman-now-available-in-homebrew.html</link><guid isPermaLink="true">http://www.rhymewithgravy.com/2016/09/16/Byteman-now-available-in-homebrew.html</guid><category><![CDATA[brew]]></category><category><![CDATA[ byteman]]></category><category><![CDATA[ java]]></category><dc:creator><![CDATA[Marc Savy]]></dc:creator><pubDate>Fri, 16 Sep 2016 00:00:00 GMT</pubDate></item><item><title><![CDATA[Changing the root-context for apiman's gateway]]></title><description><![CDATA[<div id="preamble">
<div class="sectionbody">
<div class="paragraph">
<p>An <a href="http://www.apiman.io/">apiman</a> user recently asked me how they could change the root context of apiman-gateway from <code>/apiman-gateway/</code> to something else, for instance <code>/i-love-apiman/</code>.</p>
</div>
<div class="admonitionblock tip">
<table>
<tr>
<td class="icon">
<i class="fa icon-tip" title="Tip"></i>
</td>
<td class="content">
If you&#8217;re using a load balancer or some other mapper, just skip to the <a href="#_alternatives">Alternatives</a> section or <a href="http://www.apiman.io/latest/production-guide.html#_setting_the_api_gateway_public_endpoint">read the apiman production guide</a>.
</td>
</tr>
</table>
</div>
<div class="paragraph">
<p>If you are using the WildFly or EAP apiman distributions (such as <a href="http://www.apiman.io/latest/download.html">our quickstart</a>), here&#8217;s an easy answer <sup class="footnote">[<a id="_footnoteref_1" class="footnote" href="#_footnote_1" title="View footnote.">1</a>]</sup>:</p>
</div>
<div class="olist arabic">
<ol class="arabic">
<li>
<p>Unpack <code>apiman-gateway.war</code>.</p>
<div class="literalblock">
<div class="content">
<pre>$ unzip apiman-gateway.war -d /tmp/apiman-gateway</pre>
</div>
</div>
</li>
<li>
<p>Edit <code>/tmp/apiman-gateway/WEB-INF/jboss-web.xml</code> to be to your new preferred context, e.g. <code>i-love-apiman</code>.</p>
</li>
<li>
<p>Repack the war.</p>
<div class="literalblock">
<div class="content">
<pre>$ zip -r apiman-gateway.war /tmp/apiman-gateway/META-INF /tmp/apiman-gateway/WEB-INF</pre>
</div>
</div>
</li>
<li>
<p>Replace the existing deployment.</p>
</li>
<li>
<p>Alter your <code>apiman.properties</code> file and set <code>apiman-gateway.public-endpoint=&lt;new public endpoint&gt;</code>. <sup class="footnote">[<a id="_footnoteref_2" class="footnote" href="#_footnote_2" title="View footnote.">2</a>]</sup></p>
<div class="literalblock">
<div class="content">
<pre>apiman-gateway.public-endpoint=https://localhost:8443/i-love-apiman/</pre>
</div>
</div>
</li>
</ol>
</div>
</div>
</div>
<div class="sect1">
<h2 id="_result">Result</h2>
<div class="sectionbody">
<div class="paragraph">
<p>When you publish an API to the gateway setup you modified, you should see something like this in the UI:</p>
</div>
<div class="imageblock">
<div class="content">
<img src="http://i.imgur.com/tqjusT6.png" alt="https://localhost:8443/i-love-apiman/test/test/1.0">
</div>
</div>
</div>
</div>
<div class="sect1">
<h2 id="_alternatives">Alternatives</h2>
<div class="sectionbody">
<div class="paragraph">
<p>You can, of course, just set mappings on your load balancer (or some other technique external to apiman) if you want to avoid fiddling with the deployments. Even then, you&#8217;ll still probably want to set <code>apiman-gateway.public-endpoint</code> to report a sensible value for your setup.</p>
</div>
<div class="paragraph">
<p>One final note: you can set these options via Java&#8217;s system properties, too</p>
</div>
<div class="literalblock">
<div class="content">
<pre>$ ./bin/standalone.sh -Dapiman-gateway.public-endpoint=https://localhost:8443/i-love-apiman/</pre>
</div>
</div>
<meta name="og:image" content="https://www.rhymewithgravy.com/images/apiman_logo_final_mono_dark-01.png" />
</div>
</div>
<div id="footnotes">
<hr>
<div class="footnote" id="_footnote_1">
<a href="#_footnoteref_1">1</a>. This procedure would be slightly different for other platforms such as Vert.x, Tomcat, etc
</div>
<div class="footnote" id="_footnote_2">
<a href="#_footnoteref_2">2</a>. See: <a href="http://www.apiman.io/latest/production-guide.html#_setting_the_api_gateway_public_endpoint" class="bare">http://www.apiman.io/latest/production-guide.html#_setting_the_api_gateway_public_endpoint</a>
</div>
</div>]]></description><link>http://www.rhymewithgravy.com/2016/08/24/Changing-the-root-context-for-apimans-gateway.html</link><guid isPermaLink="true">http://www.rhymewithgravy.com/2016/08/24/Changing-the-root-context-for-apimans-gateway.html</guid><category><![CDATA[apiman]]></category><category><![CDATA[ apiman-gateway]]></category><category><![CDATA[ guide]]></category><category><![CDATA[ api management]]></category><dc:creator><![CDATA[Marc Savy]]></dc:creator><pubDate>Wed, 24 Aug 2016 00:00:00 GMT</pubDate></item><item><title><![CDATA[Beware the Connection Header in HTTP/2]]></title><description><![CDATA[<div id="preamble">
<div class="sectionbody">
<div class="paragraph">
<p><a href="http://www.rhymewithgravy.com/2016/08/21/Setting-up-Vertx-HTT-P-with-JKS.html">Whilst tinkering apiman&#8217;s Vert.x gateway implementation</a> I ran into a strange issue when invoking an API via <code>curl --http2</code>. It seemed to work fine in Chrome and using Go&#8217;s <a href="https://github.com/fstab/h2c">h2c</a>:</p>
</div>
<div class="literalblock">
<div class="content">
<pre>$ * http2 error: Invalid HTTP header field was received: frame type: 1, stream: 1, name: [connection], value: [keep-alive]</pre>
</div>
</div>
<div class="paragraph">
<p>This is what the setup looks like (distilled):</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code>HTTP/2 Client &lt;--&gt; Apiman Gateway (HTTP/2) &lt;--&gt; Test API (HTTP/1)</code></pre>
</div>
</div>
</div>
</div>
<div class="sect1">
<h2 id="_what_s_going_on">What&#8217;s going on?</h2>
<div class="sectionbody">
<div class="paragraph">
<p>I took to Twitter to figure out what was going on.</p>
</div>
<blockquote class="twitter-tweet" data-lang="en"><p lang="en" dir="ltr"><a href="https://twitter.com/apiman_io">@apiman_io</a> <a href="https://twitter.com/clementplop">@clementplop</a> although the cURL --http2 doesn&#39;t like the headers Vert.x sends - interesting <a href="https://t.co/0dK81huCmb">https://t.co/0dK81huCmb</a></p>&mdash; Marc Savy (@marcsavy) <a href="https://twitter.com/marcsavy/status/767038443151036416">August 20, 2016</a></blockquote>
<script async src="//platform.twitter.com/widgets.js" charset="utf-8"></script>
<div class="paragraph">
<p>Out of the blue, Mr cURL himself (Daniel Stenberg) popped up with the answer quoted from <a href="https://tools.ietf.org/html/rfc7540#section-3.2.1">RFC 7540</a>:</p>
</div>
<blockquote class="twitter-tweet" data-lang="en"><p lang="en" dir="ltr"><a href="https://twitter.com/marcsavy">@marcsavy</a> <a href="https://twitter.com/apiman_io">@apiman_io</a> <a href="https://twitter.com/clementplop">@clementplop</a> &quot;An endpoint MUST NOT generate an HTTP/2 message containing connection-specific header fields&quot;</p>&mdash; Daniel Stenberg (@bagder) <a href="https://twitter.com/bagder/status/767052367686688768">August 20, 2016</a></blockquote>
<script async src="//platform.twitter.com/widgets.js" charset="utf-8"></script>
</div>
</div>
<div class="sect1">
<h2 id="_mystery_solved">Mystery solved</h2>
<div class="sectionbody">
<div class="paragraph">
<p>Aha! The backend API apiman was <strong>proxying the response from</strong> returned a <code>Connection: keep-alive</code> header. Apiman simply forwarded this on, but it turns out this violates the HTTP/2 spec as <strong>there should be no connection-specific header fields</strong> - in response cURL spits out the error we see above. <sup class="footnote">[<a id="_footnoteref_1" class="footnote" href="#_footnote_1" title="View footnote.">1</a>]</sup></p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code>HTTP/2 Client (http2 error...) &lt;- Apiman Gateway &lt;- Test API (sets "Connection: keep-alive")</code></pre>
</div>
</div>
<div class="paragraph">
<p><a href="https://github.com/apiman/apiman/pull/498">The solution</a> was just to filter out <code>Connection</code> headers in apiman, but I wonder whether Vert.x should do it by default (or show an error message, exception, etc).</p>
</div>
<div class="paragraph">
<p>That said, I think <em>"it&#8217;s the app&#8217;s responsibility not to do stupid things"</em> or <em>"we should handle it and filter out Connection headers"</em> are both valid responses depending upon philosophy.</p>
</div>
<div class="paragraph">
<p>So, <a href="https://twitter.com/julienviet/status/767385923633967105">I let the Vert.x guys know</a>, and let&#8217;s see.</p>
</div>
<meta name="og:image" content="https://www.rhymewithgravy.com/images/Vert-x-Logo-X.png" />
</div>
</div>
<div id="footnotes">
<hr>
<div class="footnote" id="_footnote_1">
<a href="#_footnoteref_1">1</a>. Other implementations seem to just ignore these irrelevant fields.
</div>
</div>]]></description><link>http://www.rhymewithgravy.com/2016/08/23/Beware-the-Connection-Header-in-HTT-P.html</link><guid isPermaLink="true">http://www.rhymewithgravy.com/2016/08/23/Beware-the-Connection-Header-in-HTT-P.html</guid><category><![CDATA[vertx]]></category><category><![CDATA[ apiman]]></category><category><![CDATA[ http2]]></category><dc:creator><![CDATA[Marc Savy]]></dc:creator><pubDate>Tue, 23 Aug 2016 00:00:00 GMT</pubDate></item><item><title><![CDATA[Setting up Vert.x HTTP/2 with JKS]]></title><description><![CDATA[<div id="preamble">
<div class="sectionbody">
<div class="paragraph">
<p>I was playing with <a href="http://vertx.io/">Vert.x&#8217;s</a> excellent HTTP/2 functionality with the aim of determining how difficult it&#8217;d be to add support into <a href="http://apiman.io">apiman</a>'s Vert.x <a href="https://github.com/apiman/apiman/tree/master/gateway/platforms/vertx3/vertx3">gateway implementation</a> (which is still somewhat of a tech preview, but it&#8217;s finally getting some love). Many HTTP/2 clients don&#8217;t support non-TLS connections, so transport security is a de facto requirement in the real-world usage (particularly with browsers).</p>
</div>
<div class="paragraph">
<p>There&#8217;s already <a href="https://github.com/vert-x3/vertx-examples/blob/master/core-examples/src/main/java/io/vertx/example/core/http2/simple/Server.java">an example</a> in the Vert.x <code>core-examples</code> repository demonstrating how to set up and use HTTP/2. However, when using a keystore in JKS format, Vert.x (in v3.3.2, at least) tries to use Jetty&#8217;s <code>alpn-boot</code> ALPN implementation rather than OpenSSL.</p>
</div>
</div>
</div>
<div class="sect1">
<h2 id="_a_few_simple_steps">A few simple steps&#8230;&#8203;</h2>
<div class="sectionbody">
<div class="paragraph">
<p>So, here&#8217;s how to go about making it work:</p>
</div>
<div class="olist arabic">
<ol class="arabic">
<li>
<p>Download the version of <code>apln-boot</code> <a href="http://www.eclipse.org/jetty/documentation/9.4.x/alpn-chapter.html#alpn-versions">corresponding to your version of Java</a>. The binaries are available on <a href="https://repo1.maven.org/maven2/org/mortbay/jetty/alpn/alpn-boot/">Maven Central</a>, or you can build your own if you prefer.</p>
</li>
<li>
<p>When launching your verticle, put <code>alpn-boot</code> on the JVM&#8217;s <em>boot classpath</em>; it&#8217;s altering core library functionality and needs to be available early. There are a few ways to do this, here&#8217;s the easiest one:</p>
<div class="literalblock">
<div class="content">
<pre>$ JAVA_OPTS=-Xbootclasspath/p:&lt;path-to-apln-boot.jar&gt; vertx run Example.java</pre>
</div>
</div>
<div class="paragraph">
<p>If you&#8217;re using an IDE you should add <code>-Xbootclasspath/p:&lt;path-to-apln-boot.jar&gt;</code> to the VM Arguments of your run configuration.</p>
</div>
</li>
<li>
<p>Set <code>setUseAlpn(true)</code> on your <code>HttpServerOptions</code>.</p>
</li>
</ol>
</div>
</div>
</div>
<div class="sect1">
<h2 id="_testing_it_out">Testing it out</h2>
<div class="sectionbody">
<div class="paragraph">
<p>Here&#8217;s some code to test it with.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-java" data-lang="java">import io.vertx.core.AbstractVerticle;
import io.vertx.core.http.HttpServer;
import io.vertx.core.http.HttpServerOptions;
import io.vertx.core.net.JksOptions;

public class Example extends AbstractVerticle {

    @Override
    public void start() throws Exception {
        HttpServer server =
        vertx.createHttpServer(new HttpServerOptions()
            .setUseAlpn(true)
            .setSsl(true)
            .setKeyStoreOptions(
                new JksOptions()
                .setPath(&lt;Path to your JKS&gt;)
                .setPassword(&lt;The JKS password&gt;)
            )
        );

        server.requestHandler(req -&gt; {
            req.response().putHeader("Content-Type", "text/plain")
                .end("Greetings, Earthicans!\n");
        }).listen(8443);
    }
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>You&#8217;ll likely want to check that it&#8217;s really working. I&#8217;ve been using <code>cURL</code> compiled with <code>nghttp2</code> to enable HTTP/2 support; depending on your OS or distro, the shipping version may have been built with it. If you&#8217;re using OS X, you can use <code>brew install curl --with-nghttp2</code>. <sup class="footnote">[<a id="_footnoteref_1" class="footnote" href="#_footnote_1" title="View footnote.">1</a>]</sup></p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-shellsession" data-lang="shellsession"> $  curl -k -v --http2 https://localhost:8443/
 *   Trying ::1...
 * Connected to localhost (::1) port 8443 (#0)
 * ALPN, offering h2
 * ALPN, offering http/1.1
 * Cipher selection: ALL:!EXPORT:!EXPORT40:!EXPORT56:!aNULL:!LOW:!RC4:@STRENGTH
 * successfully set certificate verify locations:
 *   CAfile: /usr/local/etc/openssl/cert.pem
   CApath: none
 * TLSv1.2 (OUT), TLS header, Certificate Status (22):
 * TLSv1.2 (OUT), TLS handshake, Client hello (1):
 * TLSv1.2 (IN), TLS handshake, Server hello (2):
 * TLSv1.2 (IN), TLS handshake, Certificate (11):
 * TLSv1.2 (IN), TLS handshake, Server key exchange (12):
 * TLSv1.2 (IN), TLS handshake, Server finished (14):
 * TLSv1.2 (OUT), TLS handshake, Client key exchange (16):
 * TLSv1.2 (OUT), TLS change cipher, Client hello (1):
 * TLSv1.2 (OUT), TLS handshake, Finished (20):
 * TLSv1.2 (IN), TLS change cipher, Client hello (1):
 * TLSv1.2 (IN), TLS handshake, Finished (20):
 * SSL connection using TLSv1.2 / ECDHE-RSA-AES128-GCM-SHA256
 * ALPN, server accepted to use h2
 * Server certificate:
 *  subject: C=lo; ST=localhost; L=localhost; O=localhost; OU=localhost; CN=localhost
 *  start date: Aug 20 15:23:02 2016 GMT
 *  expire date: Nov 18 15:23:02 2016 GMT
 *  issuer: C=lo; ST=localhost; L=localhost; O=localhost; OU=localhost; CN=localhost
 *  SSL certificate verify result: self signed certificate (18), continuing anyway.
 * Using HTTP2, server supports multi-use
 * Connection state changed (HTTP/2 confirmed)
 * TCP_NODELAY set
 * Copying HTTP/2 data in stream buffer to connection buffer after upgrade: len=0
 * Using Stream ID: 1 (easy handle 0x7fb8aa008800)
 &gt; GET / HTTP/1.1
 &gt; Host: localhost:8443
 &gt; User-Agent: curl/7.50.1
 &gt; Accept: */*
 &gt;
 * Connection state changed (MAX_CONCURRENT_STREAMS updated)!
 &lt; HTTP/2 200
 &lt; content-type: text/plain
 &lt; content-length: 22
 &lt;
 * Connection #0 to host localhost left intact
 Greetings, Earthicans!</code></pre>
</div>
</div>
<div class="paragraph">
<p>Hooray!</p>
</div>
<div class="paragraph">
<p>Vert.x really is a gratifyingly well-thought-out and easy-to-use.</p>
</div>
<meta name="og:image" content="https://www.rhymewithgravy.com/images/Vert-x-Logo-X.png" />
</div>
</div>
<div id="footnotes">
<hr>
<div class="footnote" id="_footnote_1">
<a href="#_footnoteref_1">1</a>. But remember cURL is not linked by default so you&#8217;ll have to dig into its Cellar (e.g. /usr/local/Cellar/curl/7.50.1/bin/curl). Of course, you could alias it, or force link :-).
</div>
</div>]]></description><link>http://www.rhymewithgravy.com/2016/08/21/Setting-up-Vertx-HTT-P-with-JKS.html</link><guid isPermaLink="true">http://www.rhymewithgravy.com/2016/08/21/Setting-up-Vertx-HTT-P-with-JKS.html</guid><category><![CDATA[vertx]]></category><category><![CDATA[ apiman]]></category><category><![CDATA[ guide]]></category><category><![CDATA[ http2]]></category><dc:creator><![CDATA[Marc Savy]]></dc:creator><pubDate>Sun, 21 Aug 2016 00:00:00 GMT</pubDate></item></channel></rss>