<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">

  <title><![CDATA[ZeroSharp]]></title>
  <link href="http://ZeroSharp.github.com/atom.xml" rel="self"/>
  <link href="http://ZeroSharp.github.com/"/>
  <updated>2018-11-04T19:50:26+00:00</updated>
  <id>http://ZeroSharp.github.com/</id>
  <author>
    <name><![CDATA[Robert Anderson]]></name>
    
  </author>
  <generator uri="http://octopress.org/">Octopress</generator>

  
  <entry>
    <title type="html"><![CDATA[Has the Riemann Hypothesis been proved?]]></title>
    <link href="http://ZeroSharp.github.com/has-the-riemann-hypothesis-been-proved/"/>
    <updated>2018-09-23T08:35:00+01:00</updated>
    <id>http://ZeroSharp.github.com/has-the-riemann-hypothesis-been-proved</id>
    <content type="html"><![CDATA[<p><img class="right" src="http://ZeroSharp.github.com/images/blog/has-the-riemann-hypothesis-been-proved-michael-atiyah.jpg" title="By Tugsataydin CC BY-SA 4.0 from Wikimedia Commons" >
Tomorrow could be an exciting moment in the history of maths. <a href="https://en.wikipedia.org/wiki/Michael_Atiyah">Sir Michael Atiyah</a> is presenting a proof of the Riemann Hypothesis at the Heidelberg Laureate Forum which will be available on <a href="https://www.youtube.com/user/LaureateForum">their youtube channel</a>. There is a good angle by Ken Regan on the <a href="https://rjlipton.wordpress.com/2018/09/21/the-specter-of-simpler-proofs/">Gödel&#8217;s Lost Letter blog</a>.</p>

<p>The Riemann Hypothesis is one of the most important unsolved problems in mathematics and the subject of one of my favourite books about maths: <a href="https://www.amazon.com/Prime-Obsession-Bernhard-Greatest-Mathematics/dp/0452285259">Prime Obsession</a>.</p>

<p>A few years ago in Paris, I had the pleasure of seeing <a href="http://ZeroSharp.github.com/an-afternoon-with-two-fields-medallists">Sir Michael speak</a>. He spoke so cheerfully about life and mathematics. There is a great interview with him on the <a href="https://www.youtube.com/playlist?list=PLVV0r6CmEsFzjttuP9WTFDzu0oAOJBM_3">Web of Stories</a> YouTube channel.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[My essential web applications and iPhone apps]]></title>
    <link href="http://ZeroSharp.github.com/my-essential-web-applications/"/>
    <updated>2018-09-18T09:27:00+01:00</updated>
    <id>http://ZeroSharp.github.com/my-essential-web-applications</id>
    <content type="html"><![CDATA[<p>This is part three of a series of posts about the software and tools I find invaluable. See <a href="http://ZeroSharp.github.com/essential-applications">Part 1: essential applications</a> and <a href="http://ZeroSharp.github.com/my-essential-visual-studio-tools-and-extensions">Part 2: Visual Studio tools</a>. In this post I&#8217;m covering the online applications and iPhone apps I find indispensible.</p>

<h2><a href="https://www.google.com/gmail/">Gmail</a></h2>

<p>Does the job.</p>

<h2><a href="https://www.lastpass.com/">Lastpass</a></h2>

<p>Everyone needs a password manager.</p>

<h2><a href="https://www.pinboard.in">Pinboard</a> (and the <a href="https://pinswiftapp.com/">PinSwift</a> iPhone app)</h2>

<p>The best bookmark tracking tool. Simple, fast, powerful. The best mobile app for it is <a href="https://pinswiftapp.com/">PinSwift</a>.</p>

<h2><a href="https://bear.app/">Bear</a></h2>

<p>A very pretty MarkDown editor for Mac and iPhone. I use <a href="https://bear.app/">Bear</a> for all my notes.</p>

<h2><a href="https://www.google.com/drive/download/">Google Drive File Stream</a></h2>

<p>Since I use <a href="https://gsuite.google.com/">GSuite</a>, it makes sense to try to put everything there. Google Drive has improved enormously since they moved to a file streaming approach.</p>

<h2><a href="https://mail.google.com/tasks/canvas">Google Tasks</a> (and the <a href="gotasksapp.com/">GoTasks</a> app)</h2>

<p>I need simple task manager with support for multiple lists, hierarchies and available everywhere. Google Tasks is often overlooked in this regard. Check out the <a href="https://mail.google.com/tasks/canvas">Google Tasks canvas</a>. There is also a fantastic free iPhone app for it <a href="http://gotasksapp.com/">GoTasks</a>.</p>

<h2><a href="https://feedly.com/">Feedly</a></h2>

<p><a href="https://feedly.com/">Feedly</a> is the best RSS news feed reader, in my opinion. I keep up with a few development blogs, a few science blogs and the blogs of my friends. The mobile app is great too.</p>

<h2><a href="https://www.xero.com/">Xero</a></h2>

<p>I&#8217;ve been using <a href="https://www.xero.com/">Xero</a> for eight years now. Business accounting software done right.</p>

<h2><a href="https://www.amazon.com/kindle-dbs/fd/kcp">Kindle</a></h2>

<p>I like real books but don&#8217;t always lug them about with me, so often I buy both the hard copy and the kindle version (there shoudl be some sort of clever discount for this&#8230;). The Kindle app is where I spend my time when I have no connectivity (the London tube, airplanes, etc.)</p>

<h2><a href="https://chess.com">Chess.com</a> and <a href="https://lichess.com">Lichess.com</a></h2>

<p>I waste hours playing online blitz chess. I&#8217;ve even written a couple of Chrome extensions: <a href="https://chrome.google.com/webstore/detail/lichess-print-friendly-pd/goijhimgdjppmhmjkaglhggoapkgobfg">Pretty print your games</a> and <a href="https://chrome.google.com/webstore/detail/chesscom-v3-analysis/bhjlkimpkkgkmfjlcfngmakenalgleap">Analyse any chess.com game with lichess</a>.</p>

<p>Chess is a mascohistic, character-building pastime. Progress is elusive. You play a couple of good games and you think you&#8217;re improving and then you get thrashed repeatedly by a 10 year old.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[My essential Visual Studio tools and extensions]]></title>
    <link href="http://ZeroSharp.github.com/my-essential-visual-studio-tools-and-extensions/"/>
    <updated>2018-09-10T15:45:00+01:00</updated>
    <id>http://ZeroSharp.github.com/my-essential-visual-studio-tools-and-extensions</id>
    <content type="html"><![CDATA[<p>This is part two of a series of posts about the software and tools I find invaluable. See <a href="http://ZeroSharp.github.com/essential-applications">part 1</a> and <a href="http://ZeroSharp.github.com/my-essential-web-applications">part 3</a>.</p>

<h2>CodeRush</h2>

<p>I&#8217;ve been using DevExpress <a href="https://www.devexpress.com/products/coderush/">CodeRush</a> since 2005. Check out <a href="https://youtu.be/v5-MVSoqCnU">this video tutorial</a> for a lightening tour of a lot of the features, and look at the DevExpress youtube channel for <a href="https://www.youtube.com/playlist?list=PL8h4jt35t1wgawacCN9wmxq1EN36CNUGk">a load of other tutorials</a>.</p>

<h2>NCrunch</h2>

<p><a href="https://www.ncrunch.net/">NCrunch</a> provides continuous testing for Visual Studio. When I make any change to my code which breaks a unit test, the NCrunch risk status goes red a few seconds later, even without recompiling. I get immediate feedback for any breaking change, so long as I have a test for it. Not only does it encourages me and my team to write good tests, but it allows us to make new changes and
refactor with confidence.</p>

<p><img src="http://ZeroSharp.github.com/images/blog/ncrunch-progress-bar.png"></p>

<h2>Redgate .NET Reflector Developer Bundle</h2>

<p>When the going gets tough, the <a href="https://www.red-gate.com/products/dotnet-development/ants-performance-profiler/index">ANTS Performance Profiler</a> and <a href="https://www.red-gate.com/products/dotnet-development/ants-memory-profiler/index">ANTS Memory Profiler</a> have helped me find some of the hardest bugs I&#8217;ve come across.</p>

<p>Also, while there are several good .NET decompilers, many of them free, I got used to <a href="https://www.red-gate.com/products/dotnet-development/reflector/index">.NET Reflector</a> which comes part of this bundle.</p>

<h2>T4</h2>

<p>I use code generation to automatically generate templates for unit tests for validation rules and <a href="https://docs.microsoft.com/en-us/visualstudio/modeling/code-generation-and-t4-text-templates?view=vs-2017">T4</a> and the <a href="https://marketplace.visualstudio.com/items?itemName=OlegVSych.T4ToolboxforVisualStudio2017">T4 Toolbox</a> fit the bill nicely.</p>

<p>For a more advanced use case, see my post about automatically <a href="http://ZeroSharp.github.com/making-xaf-reports-even-better-part-1/">converting DevExpress v1 report scripts</a> to check for compilation errors and allow for unit testing of report scripts.</p>

<h2>AWS Toolkit</h2>

<p>I always install the <a href="https://aws.amazon.com/visualstudio/">Amazon Web Services Toolkit</a> to make it easy to spin up test servers in the Amazon cloud.</p>

<h2>Next up</h2>

<p>My <a href="http://ZeroSharp.github.com/my-essential-web-applications">essential web applications and iPhone apps</a>.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[My essential applications]]></title>
    <link href="http://ZeroSharp.github.com/essential-applications/"/>
    <updated>2018-09-07T15:23:00+01:00</updated>
    <id>http://ZeroSharp.github.com/essential-applications</id>
    <content type="html"><![CDATA[<p>This is the first in a series of posts where I list the applications that I use and enjoy the most. See <a href="(/my-essential-visual-studio-tools-and-extensions">part 2</a>) and <a href="http://ZeroSharp.github.com/my-essential-web-applications">part 3</a>.</p>

<p>A bit of preamble, my most powerful machine is a Windows-only desktop with lots of RAM and an SSD drive. I use it almost exclusively for development.</p>

<p>I also have a Macbook Pro which is configured to dual-boot Windows and MacOS. The Windows machine is more or less a mirror of my main development machine. The Mac is where I do all my document editing, Word, blogging, etc. I also use it for my occasional forays in to iPhone development or other non-Windows experiments.</p>

<p>When I upgrade my development machine, I reconfigure the previous system for Linux, currently Ubuntu.</p>

<h2>Chocolatey</h2>

<p>In Windows, <a href="Chocolatey%20-%20The%20package%20manager%20for%20Windows">Chocolatey</a> is a very convenient way to install programs. Just go:</p>

<pre><code>C:&gt; choco install nodejs
</code></pre>

<h2>Boxstarter</h2>

<p>Even better, create a powershell script with all the applications you want to install and run it with <a href="https://boxstarter.org/">boxstarter</a>. Repeatable and reboot-resilient environment installations using chocolatey under the hood. For several years now, I have maintained a script for installing my entire development environment (and the build server) from scratch. Works whether it&#8217;s a physical or a virtual machine.</p>

<h2>BeyondCompare</h2>

<p><a href="https://www.scootersoftware.com/">BeyondCompare</a> is the best file-comparison tool I&#8217;ve found. Cross-platform too, I have it installed on my Mac as well.</p>

<h2>Synergy</h2>

<p><a href="https://symless.com/synergy">Synergy</a> allows me to share one mouse and keyboard across all my machines. It works just like dual monitors, except when the mouse moves onto the next screen, you&#8217;ve actually changed computer. I don&#8217;t have multiple monitors any more, I just switch the input on my giant <a href="https://www.dell.com/en-us/shop/dell-ultrasharp-34-curved-monitor-u3417w/apd/210-aiyz/monitors-monitor-accessories">curved 34&#8221; Dell monitor</a> via a keyboard shortcut.</p>

<h2>7Zip</h2>

<p>Nothing to say.</p>

<h2>VS Code</h2>

<p>First class support for .NET and C#, Typescript in particular, but <a href="https://code.visualstudio.com/">VS Code</a> is also extremely good with Javascript, Powershell, Python, Markdown, etc. Multiple cursor support. Cross-platform. Extensions. I&#8217;m writing this blog post in VS Code.</p>

<h2>Visual Studio</h2>

<p>My daily workhorse. I&#8217;ve spent more screen time here than anywhere.</p>

<h2>Zotero</h2>

<p>Keep track of academic papers. Download them for offline reading. Handle citations and bibliographies effortlessly from within Word. <a href="https://www.zotero.org/">Zotero</a>.</p>

<h2>Next up</h2>

<p>More on Visual Studio in the <a href="http://ZeroSharp.github.com/my-essential-visual-studio-tools-and-extensions">next post</a> where I go through my essential extensions and tools.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Macbook and the mysterious sleep]]></title>
    <link href="http://ZeroSharp.github.com/macbook-and-the-mysterious-sleep/"/>
    <updated>2017-08-23T16:46:00+01:00</updated>
    <id>http://ZeroSharp.github.com/macbook-and-the-mysterious-sleep</id>
    <content type="html"><![CDATA[<p>I finally worked out why my Macbook was randomly sleeping.</p>

<p><strong>TL;DR</strong> - <a href="#anchor-tldr">Skip to the end</a>.</p>

<h2>Clues</h2>

<p>It only seemed to happen when I was working while sitting up on the bed with the computer on my lap. It seemed to be related to the position of the computer or possibly the lid. The computer would sleep. I&#8217;d wake it and login again. Continue. Sometimes it would happen once. Sometimes three times in ten minutes. Annoying. I assumed some hardware defect.</p>

<h2>Pajamas</h2>

<p>Then over several days I cracked it. I realised it never happened when I was wearing pajamas. Very strange.</p>

<h2>Reflections</h2>

<p>I started thinking about what normally triggers sleep mode. Closing the lid. How does a Macbook know the lid is closed. There&#8217;s not really a clasp or anything so it must be a magnet. Perhaps it&#8217;s getting confused by my belt buckle or something. My phone?</p>

<p>No, my phone <em>case</em>! The flip-case of my phone has a magnet to keep the flap closed. In my jeans pocket it&#8217;s near enough to make the laptop think the lid has been closed. Duh.</p>

<h2><a name="anchor-tldr"></a>TL;DR</h2>

<p>Take your mobile phone out of your pocket!</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Improvements to Serverless PHP support]]></title>
    <link href="http://ZeroSharp.github.com/improvements-to-serverless-php-support/"/>
    <updated>2017-03-02T11:37:00+00:00</updated>
    <id>http://ZeroSharp.github.com/improvements-to-serverless-php-support</id>
    <content type="html"><![CDATA[<p>I was inspired by two events to jump back into serverless framework.</p>

<p><img class="left" src="http://ZeroSharp.github.com/images/blog/serverless-php-improvements-001.jpeg" width="200" title="Serverless London Meetup" ></p>

<p>Firstly, I attended the second <a href="https://www.meetup.com/Serverless-London/">London serverless meetup</a> yesterday evening which was excellent and showed just how much enthusiasm there is for serverless architectures. Check out their new logo on the left. It was significant that each of the three speakers announced that they are actively hiring serverless developers.</p>

<p>Secondly, <a href="https://github.com/Stolz">Stolz</a> has contributed improvements to my sample project for integrating PHP into the serverless framework. It&#8217;s the purpose of this blog post to cover the changes.</p>

<p>The trick to getting AWS lambda to support PHP is to bundle in a PHP binary so that nodejs can call it with <code>child_process.spawn()</code>. In <a href="http://ZeroSharp.github.com/the-serverless-framework-and-php/">my first implementation</a>, I used an Ubuntu docker base image to compile and produce the php binary. Unfortunately, this is not identical to the container that AWS Lambda uses and so sometimes the logs would contain errors such as:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
</pre></td><td class='code'><pre><code class='sh'><span class='line'>START RequestId: 728dcddf-feaa-11e6-8346-2125e1c055d7 Version: <span class="nv">$LATEST</span>
</span><span class='line'>2017-03-01 18:11:10.455 <span class="o">(</span>+00:00<span class="o">)</span>    728dcddf-feaa-11e6-8346-2125e1c055d7    stderr: ./php: /usr/lib64/libcurl.so.4: no version information available <span class="o">(</span>required by ./php<span class="o">)</span>
</span><span class='line'>
</span><span class='line'>END RequestId: 728dcddf-feaa-11e6-8346-2125e1c055d7
</span><span class='line'>REPORT RequestId: 728dcddf-feaa-11e6-8346-2125e1c055d7    Duration: 6000.08 ms    Billed Duration: 6000 ms    Memory Size: 1024 MB    Max Memory Used: 23 MB  
</span></code></pre></td></tr></table></div></figure>


<p>In my experience, these errors were often not fatal, but the correct approach is to build the php binary from a base image which is closer to the one lambda uses. So instead of my docker file starting with <code>FROM ubuntu</code>, it now starts with <code>FROM amazonlinux</code>. Also, with this image, I can use <code>yum</code> to install other dependencies like <code>libpng-devel</code>. So the new docker build script for producing the php binary looks like this:</p>

<figure class='code'><figcaption><span>dockerfile.buildphp</span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
<span class='line-number'>17</span>
<span class='line-number'>18</span>
<span class='line-number'>19</span>
<span class='line-number'>20</span>
<span class='line-number'>21</span>
<span class='line-number'>22</span>
<span class='line-number'>23</span>
<span class='line-number'>24</span>
<span class='line-number'>25</span>
<span class='line-number'>26</span>
<span class='line-number'>27</span>
<span class='line-number'>28</span>
<span class='line-number'>29</span>
<span class='line-number'>30</span>
<span class='line-number'>31</span>
<span class='line-number'>32</span>
<span class='line-number'>33</span>
<span class='line-number'>34</span>
<span class='line-number'>35</span>
<span class='line-number'>36</span>
<span class='line-number'>37</span>
<span class='line-number'>38</span>
<span class='line-number'>39</span>
<span class='line-number'>40</span>
<span class='line-number'>41</span>
<span class='line-number'>42</span>
</pre></td><td class='code'><pre><code class='sh'><span class='line'><span class="c"># Compile PHP with static linked dependencies</span>
</span><span class='line'><span class="c"># to create a single running binary</span>
</span><span class='line'>
</span><span class='line'>FROM amazonlinux
</span><span class='line'>
</span><span class='line'>ARG PHP_VERSION
</span><span class='line'>
</span><span class='line'>RUN yum install <span class="se">\</span>
</span><span class='line'>    autoconf <span class="se">\</span>
</span><span class='line'>    automake <span class="se">\</span>
</span><span class='line'>    libtool <span class="se">\</span>
</span><span class='line'>    bison <span class="se">\</span>
</span><span class='line'>    re2c <span class="se">\</span>
</span><span class='line'>    libxml2-devel <span class="se">\</span>
</span><span class='line'>    openssl-devel <span class="se">\</span>
</span><span class='line'>    libpng-devel <span class="se">\</span>
</span><span class='line'>    libjpeg-devel <span class="se">\</span>
</span><span class='line'>    curl-devel -y
</span><span class='line'>
</span><span class='line'>RUN curl -sL https://github.com/php/php-src/archive/<span class="nv">$PHP_VERSION</span>.tar.gz | tar -zxv
</span><span class='line'>
</span><span class='line'>WORKDIR /php-src-<span class="nv">$PHP_VERSION</span>
</span><span class='line'>
</span><span class='line'>RUN ./buildconf --force
</span><span class='line'>
</span><span class='line'>RUN ./configure <span class="se">\</span>
</span><span class='line'>    --enable-static<span class="o">=</span>yes <span class="se">\</span>
</span><span class='line'>    --enable-shared<span class="o">=</span>no <span class="se">\</span>
</span><span class='line'>    --disable-all <span class="se">\</span>
</span><span class='line'>    --enable-json <span class="se">\</span>
</span><span class='line'>    --enable-libxml <span class="se">\</span>
</span><span class='line'>    --enable-mbstring <span class="se">\</span>
</span><span class='line'>    --enable-phar <span class="se">\</span>
</span><span class='line'>    --enable-soap <span class="se">\</span>
</span><span class='line'>    --enable-xml <span class="se">\</span>
</span><span class='line'>    --with-curl <span class="se">\</span>
</span><span class='line'>    --with-gd <span class="se">\</span>
</span><span class='line'>    --with-zlib <span class="se">\</span>
</span><span class='line'>    --with-openssl <span class="se">\</span>
</span><span class='line'>    --without-pear
</span><span class='line'>
</span><span class='line'>RUN make -j 5
</span></code></pre></td></tr></table></div></figure>


<p>If you run this with</p>

<pre><code>$ sh dockerfile.buildphp
</code></pre>

<p>It will use docker to overwrite the php binary which will get shipped when you deploy with <code>sls deploy</code>. And this time, there are no more libcurl errors. All the code is <a href="https://github.com/ZeroSharp/serverless-php">on Github</a>.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[A concrete PHP Serverless example - export chess games in PDF]]></title>
    <link href="http://ZeroSharp.github.com/a-concrete-php-serverless-example/"/>
    <updated>2016-11-29T17:37:00+00:00</updated>
    <id>http://ZeroSharp.github.com/a-concrete-php-serverless-example</id>
    <content type="html"><![CDATA[<p>In <a href="http://ZeroSharp.github.com/the-serverless-framework-and-php/">the last post</a> I built a PHP capable sample project for <a href="https://serverless.com/">the Serverless Framework</a>. In this post, I&#8217;ll show a concrete use of it.</p>

<p>The service I&#8217;m building connects runs a PHP function for pretty-printing chess games from the <a href="http://lichess.org/">lichess online chess server</a>. <a href="https://github.com/clarkerubber/lichessPDFExporter">James Clarke</a> has written a PHP function to do this using <a href="http://www.fpdf.org/">fpdf17</a>.</p>

<p>The lichess exporter takes the game id of any game that has been played on the lichess server and produced a PDF output. Take for example, Game 8 of the current World Championship which is <a href="https://en.lichess.org/COQChpzH">here</a>. When I open the resulting file, I see this:</p>

<p><img src="http://ZeroSharp.github.com/images/blog/serverless-lichess-pdf-exporter-001.png"></p>

<p>In this blog post I&#8217;ll describe how I turned this into a serverless service. The goal is to create:</p>

<ul>
<li>Add an endpoint which takes the game id as a parameter</li>
<li>Run the PHP function via an AWS lambda function</li>
<li>Return the result as a stream</li>
</ul>


<h2>Prerequisites</h2>

<p>First check everything we need is installed.</p>

<pre><code>$ serverless --version
1.2.1
$ node --version
v7.1.0
</code></pre>

<h2>Initial setup</h2>

<pre><code>$ mkdir serverless-lichess-to-pdf
$ cd serverless-lichess-to-pdf
$ sls install --url https://github.com/ZeroSharp/serverless-php
</code></pre>

<p>Next copy in the source from https://github.com/clarkerubber/lichessPDFExporter.</p>

<p>You can check it works by running the following.</p>

<pre><code>$ php main.php COQChpzH &gt; COQChpzH.pdf
</code></pre>

<p>What&#8217;s going on here? The php binary (from the serverless-php project) is running main.php (from the lichess-pdf-exporter project) with argument <code>COQChpzH</code> (which corresponds to a <a href="https://en.lichess.org/hsXtkVk8">chess game</a> on the lichess server. The main.php function downloads the game from the lichess API and passes it through the fpdf17 library to create a pdf stream which is written out to the <code>COQChpzH.pdf</code> file.</p>

<h2>Lessons learned</h2>

<p>I learned a few things while trying to get this project working. The basic plan is to modify handler.js so that it return the output of the call described above. Turns out there are quite a few gotchas along the way.</p>

<h2>Lesson 1 - Defining a path parameter</h2>

<p>I want my API to look like this:</p>

<pre><code>http://.../serverless-lichess-to-pdf/export/{gameid}
</code></pre>

<p>I could not find an example in the serverless docs for getting a parameter that is passed in the URL.</p>

<p>Turns out your <code>serverless.yml</code> file should look like this:</p>

<figure class='code'><figcaption><span>serverless.yml</span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
</pre></td><td class='code'><pre><code class='yaml'><span class='line'><span class="l-Scalar-Plain">functions</span><span class="p-Indicator">:</span>
</span><span class='line'>  <span class="l-Scalar-Plain">exportToPdf</span><span class="p-Indicator">:</span>
</span><span class='line'>    <span class="l-Scalar-Plain">handler</span><span class="p-Indicator">:</span> <span class="l-Scalar-Plain">handler.exportToPdf</span>
</span><span class='line'>    <span class="l-Scalar-Plain">events</span><span class="p-Indicator">:</span>
</span><span class='line'>      <span class="p-Indicator">-</span> <span class="l-Scalar-Plain">http</span><span class="p-Indicator">:</span>
</span><span class='line'>          <span class="l-Scalar-Plain">path</span><span class="p-Indicator">:</span> <span class="l-Scalar-Plain">export/{gameid}</span>
</span><span class='line'>          <span class="l-Scalar-Plain">method</span><span class="p-Indicator">:</span> <span class="l-Scalar-Plain">get</span>
</span></code></pre></td></tr></table></div></figure>


<p>Then, in your handler.js you can retrieve the parameter with:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
</pre></td><td class='code'><pre><code class='js'><span class='line'><span class="nx">module</span><span class="p">.</span><span class="nx">exports</span><span class="p">.</span><span class="nx">exportToPdf</span> <span class="o">=</span> <span class="p">(</span><span class="nx">event</span><span class="p">,</span> <span class="nx">context</span><span class="p">,</span> <span class="nx">callback</span><span class="p">)</span> <span class="o">=&gt;</span> <span class="p">{</span>
</span><span class='line'>  <span class="kd">var</span> <span class="nx">gameid</span> <span class="o">=</span> <span class="nx">event</span><span class="p">.</span><span class="nx">pathParameters</span><span class="p">.</span><span class="nx">gameid</span><span class="p">;</span>
</span><span class='line'>  <span class="c1">// etc...</span>
</span><span class='line'><span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>


<p></p>

<h2>Lesson 2 - API Gateway does not support binary data</h2>

<p>I was hoping I could just do something like this:</p>

<figure class='code'><figcaption><span>handler.js</span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
</pre></td><td class='code'><pre><code class='js'><span class='line'><span class="c1">// this does NOT work</span>
</span><span class='line'><span class="kr">const</span> <span class="nx">response</span> <span class="o">=</span> <span class="p">{</span>
</span><span class='line'>    <span class="nx">statusCode</span><span class="o">:</span> <span class="mi">200</span><span class="p">,</span>
</span><span class='line'>    <span class="nx">body</span><span class="o">:</span> <span class="nx">outputFromPhpCall</span><span class="p">,</span>
</span><span class='line'>    <span class="nx">content</span><span class="o">-</span><span class="nx">type</span><span class="o">:</span> <span class="s2">&quot;application/pdf&quot;</span>
</span><span class='line'><span class="p">};</span>
</span><span class='line'>
</span><span class='line'><span class="k">return</span> <span class="nx">callback</span><span class="p">(</span><span class="kc">null</span><span class="p">,</span> <span class="nx">response</span><span class="p">);</span>
</span></code></pre></td></tr></table></div></figure>


<p>At present, you cannot return a binary file. Amazon have just (November 2016) <a href="https://aws.amazon.com/blogs/compute/binary-support-for-api-integrations-with-amazon-api-gateway/">released support for binary types in API Gateway</a> but it&#8217;s currently <a href="https://github.com/serverless/serverless/issues/2797">an open issue</a> in the Serverless Framework.</p>

<h2>Lesson 3 - You can redirect the response to an S3 bucket</h2>

<p>So instead of returning the binary output, I can write the output to an S3 bucket and return a 302 redirection to the S3 resource. Like this:</p>

<figure class='code'><figcaption><span>handler.js</span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
<span class='line-number'>17</span>
<span class='line-number'>18</span>
<span class='line-number'>19</span>
<span class='line-number'>20</span>
<span class='line-number'>21</span>
<span class='line-number'>22</span>
<span class='line-number'>23</span>
<span class='line-number'>24</span>
<span class='line-number'>25</span>
</pre></td><td class='code'><pre><code class='js'><span class='line'><span class="c1">// body contains the output from the PHP call</span>
</span><span class='line'><span class="kr">const</span> <span class="nx">params</span> <span class="o">=</span> <span class="p">{</span>
</span><span class='line'>    <span class="nx">Bucket</span><span class="o">:</span> <span class="nx">bucket</span><span class="p">,</span>
</span><span class='line'>    <span class="nx">Key</span><span class="o">:</span> <span class="nx">key</span><span class="p">,</span>
</span><span class='line'>    <span class="nx">ACL</span><span class="o">:</span> <span class="s1">&#39;public-read-write&#39;</span><span class="p">,</span>
</span><span class='line'>    <span class="nx">Body</span><span class="o">:</span> <span class="nx">body</span><span class="p">,</span>
</span><span class='line'>    <span class="nx">ContentType</span><span class="o">:</span> <span class="s1">&#39;application/pdf&#39;</span>
</span><span class='line'><span class="p">};</span>
</span><span class='line'>
</span><span class='line'><span class="c1">// Save the pdf file to S3    </span>
</span><span class='line'><span class="nx">s3</span><span class="p">.</span><span class="nx">putObject</span><span class="p">(</span><span class="nx">params</span><span class="p">,</span> <span class="kd">function</span><span class="p">(</span><span class="nx">err</span><span class="p">,</span> <span class="nx">data</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'><span class="k">if</span> <span class="p">(</span><span class="nx">err</span><span class="p">)</span>
</span><span class='line'><span class="p">{</span>
</span><span class='line'>    <span class="k">return</span> <span class="nx">callback</span><span class="p">(</span><span class="k">new</span> <span class="nb">Error</span><span class="p">(</span><span class="err">`</span><span class="nx">Failed</span> <span class="nx">to</span> <span class="nx">put</span> <span class="nx">s3</span> <span class="nx">object</span><span class="o">:</span> <span class="nx">$</span><span class="p">{</span><span class="nx">err</span><span class="p">}</span><span class="err">`</span><span class="p">));</span>
</span><span class='line'><span class="p">}</span>
</span><span class='line'>
</span><span class='line'><span class="c1">// respond with a 302 redirect to the PDF file</span>
</span><span class='line'><span class="kr">const</span> <span class="nx">response</span> <span class="o">=</span> <span class="p">{</span>
</span><span class='line'>    <span class="nx">statusCode</span><span class="o">:</span> <span class="mi">302</span><span class="p">,</span>
</span><span class='line'>    <span class="nx">headers</span><span class="o">:</span> <span class="p">{</span>
</span><span class='line'>        <span class="nx">location</span> <span class="o">:</span> <span class="err">`</span><span class="nx">https</span><span class="o">:</span><span class="c1">//s3-eu-west-1.amazonaws.com/${bucket}/${key}`</span>
</span><span class='line'>    <span class="p">}</span>
</span><span class='line'><span class="p">};</span>
</span><span class='line'>
</span><span class='line'><span class="k">return</span> <span class="nx">callback</span><span class="p">(</span><span class="kc">null</span><span class="p">,</span> <span class="nx">response</span><span class="p">);</span>
</span></code></pre></td></tr></table></div></figure>


<h2>Lesson 4 - You can automatically delete S3 objects after a number of days</h2>

<p>Each S3 bucket has optional <a href="https://docs.aws.amazon.com/AmazonS3/latest/dev/object-lifecycle-mgmt.html">lifecycle rules</a> where you can specify that files are automatically removed after a time period. I wanted to set this up within the <code>serverless.yml</code> resources section, but the syntax for the lifecycle rules were not very obvious and I could not find any examples online. The following seems to work:</p>

<figure class='code'><figcaption><span>serverless.yml</span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
</pre></td><td class='code'><pre><code class='yaml'><span class='line'><span class="l-Scalar-Plain">resources</span><span class="p-Indicator">:</span>
</span><span class='line'>  <span class="l-Scalar-Plain">Resources</span><span class="p-Indicator">:</span>
</span><span class='line'>    <span class="l-Scalar-Plain">PackageStorage</span><span class="p-Indicator">:</span>
</span><span class='line'>      <span class="l-Scalar-Plain">Type</span><span class="p-Indicator">:</span> <span class="l-Scalar-Plain">AWS::S3::Bucket</span>
</span><span class='line'>      <span class="l-Scalar-Plain">Properties</span><span class="p-Indicator">:</span>
</span><span class='line'>        <span class="l-Scalar-Plain">AccessControl</span><span class="p-Indicator">:</span> <span class="l-Scalar-Plain">PublicRead</span>
</span><span class='line'>        <span class="l-Scalar-Plain">BucketName</span><span class="p-Indicator">:</span> <span class="l-Scalar-Plain">${self:custom.exportToPdfBucket}</span>
</span><span class='line'>        <span class="l-Scalar-Plain">LifecycleConfiguration</span><span class="p-Indicator">:</span>
</span><span class='line'>          <span class="l-Scalar-Plain">Rules</span><span class="p-Indicator">:</span>
</span><span class='line'>            <span class="p-Indicator">-</span> <span class="l-Scalar-Plain">ExpirationInDays</span><span class="p-Indicator">:</span> <span class="l-Scalar-Plain">1</span>
</span><span class='line'>              <span class="l-Scalar-Plain">Status</span><span class="p-Indicator">:</span> <span class="l-Scalar-Plain">Enabled</span>
</span></code></pre></td></tr></table></div></figure>


<h2>It&#8217;s all working now</h2>

<p>You can check it out by visiting <a href="https://e7tyur4sib.execute-api.eu-west-1.amazonaws.com/dev/export/COQChpzH">this link</a>.</p>

<p>The <a href="https://github.com/ZeroSharp/serverless-lichess-to-pdf">source code is on Github</a>.</p>

<p>I also wrote <a href="https://chrome.google.com/webstore/detail/lichess-print-friendly-pd/goijhimgdjppmhmjkaglhggoapkgobfg">a Chrome extension</a> which injects the link into the lichess page.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[The Serverless Framework and PHP]]></title>
    <link href="http://ZeroSharp.github.com/the-serverless-framework-and-php/"/>
    <updated>2016-11-21T09:21:00+00:00</updated>
    <id>http://ZeroSharp.github.com/the-serverless-framework-and-php</id>
    <content type="html"><![CDATA[<p>The goal of this post is to explain how to call a PHP function from within an AWS lambda using the <a href="https://serverless.com/">Serverless Framework</a>.</p>

<h2>Prerequisites</h2>

<p>First check everything we need is installed.</p>

<pre><code>$ serverless --version
1.1.0
$ node --version
v7.1.0
</code></pre>

<h2>Install the sample PHP function</h2>

<p>Install my sample <em>Hello</em> function from my github repository.</p>

<pre><code>$ sls install --url https://github.com/ZeroSharp/serverless-php
</code></pre>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
</pre></td><td class='code'><pre><code class='sh'><span class='line'>Serverless: Downloading and installing <span class="s2">&quot;serverless-php&quot;</span>…
</span><span class='line'>Serverless: Successfully installed <span class="s2">&quot;serverless-php&quot;</span>.
</span></code></pre></td></tr></table></div></figure>


<h2>The code</h2>

<pre><code>$ cd serverless-php
</code></pre>

<p>Let&#8217;s have a look at the <code>serverless.yml</code> file.</p>

<figure class='code'><figcaption><span>serverless.yml</span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
</pre></td><td class='code'><pre><code class='yaml'><span class='line'><span class="l-Scalar-Plain">service</span><span class="p-Indicator">:</span> <span class="l-Scalar-Plain">serverless-php</span>
</span><span class='line'>
</span><span class='line'><span class="l-Scalar-Plain">provider</span><span class="p-Indicator">:</span>
</span><span class='line'>  <span class="l-Scalar-Plain">name</span><span class="p-Indicator">:</span> <span class="l-Scalar-Plain">aws</span>
</span><span class='line'>  <span class="l-Scalar-Plain">runtime</span><span class="p-Indicator">:</span> <span class="l-Scalar-Plain">nodejs4.3</span>
</span><span class='line'>  <span class="c1"># region: eu-west-1</span>
</span><span class='line'>
</span><span class='line'><span class="l-Scalar-Plain">functions</span><span class="p-Indicator">:</span>
</span><span class='line'>  <span class="l-Scalar-Plain">hello</span><span class="p-Indicator">:</span>
</span><span class='line'>    <span class="l-Scalar-Plain">handler</span><span class="p-Indicator">:</span> <span class="l-Scalar-Plain">handler.hello</span>
</span><span class='line'>    <span class="l-Scalar-Plain">events</span><span class="p-Indicator">:</span>
</span><span class='line'>      <span class="p-Indicator">-</span> <span class="l-Scalar-Plain">http</span><span class="p-Indicator">:</span>
</span><span class='line'>          <span class="l-Scalar-Plain">path</span><span class="p-Indicator">:</span> <span class="l-Scalar-Plain">hello</span>
</span><span class='line'>          <span class="l-Scalar-Plain">method</span><span class="p-Indicator">:</span> <span class="l-Scalar-Plain">get</span>
</span></code></pre></td></tr></table></div></figure>


<p>Now look at the php function <code>index.php</code> that we&#8217;d like our lambda to call.</p>

<figure class='code'><figcaption><span>index.php</span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
</pre></td><td class='code'><pre><code class='php'><span class='line'><span class="cp">&lt;?php</span>
</span><span class='line'>
</span><span class='line'><span class="c1"># $argv will contain the event object. You can output its contents like this if you like</span>
</span><span class='line'><span class="c1">#var_export($argv, true);</span>
</span><span class='line'>
</span><span class='line'><span class="nb">printf</span><span class="p">(</span><span class="s1">&#39;Go Serverless v1.0! Your PHP function executed successfully!&#39;</span><span class="p">);</span>
</span></code></pre></td></tr></table></div></figure>


<p>And the <code>handler.js</code> for the hello function looks as follows. It defines a simple lambda which calls the PHP binary, logs any errors and returns the result.</p>

<figure class='code'><figcaption><span>handler.js</span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
<span class='line-number'>17</span>
<span class='line-number'>18</span>
<span class='line-number'>19</span>
<span class='line-number'>20</span>
<span class='line-number'>21</span>
<span class='line-number'>22</span>
<span class='line-number'>23</span>
<span class='line-number'>24</span>
<span class='line-number'>25</span>
<span class='line-number'>26</span>
<span class='line-number'>27</span>
<span class='line-number'>28</span>
<span class='line-number'>29</span>
<span class='line-number'>30</span>
<span class='line-number'>31</span>
<span class='line-number'>32</span>
<span class='line-number'>33</span>
<span class='line-number'>34</span>
<span class='line-number'>35</span>
<span class='line-number'>36</span>
<span class='line-number'>37</span>
<span class='line-number'>38</span>
<span class='line-number'>39</span>
<span class='line-number'>40</span>
<span class='line-number'>41</span>
<span class='line-number'>42</span>
<span class='line-number'>43</span>
<span class='line-number'>44</span>
</pre></td><td class='code'><pre><code class='js'><span class='line'><span class="s1">&#39;use strict&#39;</span><span class="p">;</span>
</span><span class='line'>
</span><span class='line'><span class="kd">var</span> <span class="nx">child_process</span> <span class="o">=</span> <span class="nx">require</span><span class="p">(</span><span class="s1">&#39;child_process&#39;</span><span class="p">);</span>
</span><span class='line'>
</span><span class='line'><span class="nx">module</span><span class="p">.</span><span class="nx">exports</span><span class="p">.</span><span class="nx">hello</span> <span class="o">=</span> <span class="p">(</span><span class="nx">event</span><span class="p">,</span> <span class="nx">context</span><span class="p">,</span> <span class="nx">callback</span><span class="p">)</span> <span class="o">=&gt;</span> <span class="p">{</span>
</span><span class='line'>
</span><span class='line'>  <span class="kd">var</span> <span class="nx">strToReturn</span> <span class="o">=</span> <span class="s1">&#39;&#39;</span><span class="p">;</span>
</span><span class='line'>
</span><span class='line'>  <span class="kd">var</span> <span class="nx">php</span> <span class="o">=</span> <span class="s1">&#39;./php&#39;</span><span class="p">;</span>
</span><span class='line'>
</span><span class='line'>  <span class="c1">// workaround to get &#39;sls invoke local&#39; to work</span>
</span><span class='line'>  <span class="k">if</span> <span class="p">(</span><span class="k">typeof</span> <span class="nx">process</span><span class="p">.</span><span class="nx">env</span><span class="p">.</span><span class="nx">PWD</span> <span class="o">!==</span> <span class="s2">&quot;undefined&quot;</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'>    <span class="nx">php</span> <span class="o">=</span> <span class="s1">&#39;php&#39;</span><span class="p">;</span>
</span><span class='line'>  <span class="p">}</span>
</span><span class='line'>
</span><span class='line'>  <span class="kd">var</span> <span class="nx">proc</span> <span class="o">=</span> <span class="nx">child_process</span><span class="p">.</span><span class="nx">spawn</span><span class="p">(</span><span class="nx">php</span><span class="p">,</span> <span class="p">[</span> <span class="s2">&quot;index.php&quot;</span><span class="p">,</span> <span class="nx">JSON</span><span class="p">.</span><span class="nx">stringify</span><span class="p">(</span><span class="nx">event</span><span class="p">),</span> <span class="p">{</span> <span class="nx">stdio</span><span class="o">:</span> <span class="s1">&#39;inherit&#39;</span> <span class="p">}</span> <span class="p">]);</span>
</span><span class='line'>
</span><span class='line'>  <span class="nx">proc</span><span class="p">.</span><span class="nx">stdout</span><span class="p">.</span><span class="nx">on</span><span class="p">(</span><span class="s1">&#39;data&#39;</span><span class="p">,</span> <span class="kd">function</span> <span class="p">(</span><span class="nx">data</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'>    <span class="kd">var</span> <span class="nx">dataStr</span> <span class="o">=</span> <span class="nx">data</span><span class="p">.</span><span class="nx">toString</span><span class="p">()</span>
</span><span class='line'>    <span class="c1">// console.log(&#39;stdout: &#39; + dataStr);</span>
</span><span class='line'>    <span class="nx">strToReturn</span> <span class="o">+=</span> <span class="nx">dataStr</span>
</span><span class='line'>  <span class="p">});</span>
</span><span class='line'>
</span><span class='line'>  <span class="c1">// this ensures any error messages raised by the PHP function end up in the logs</span>
</span><span class='line'>  <span class="nx">proc</span><span class="p">.</span><span class="nx">stderr</span><span class="p">.</span><span class="nx">on</span><span class="p">(</span><span class="s1">&#39;data&#39;</span><span class="p">,</span> <span class="kd">function</span> <span class="p">(</span><span class="nx">data</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'>    <span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="err">`</span><span class="nx">stderr</span><span class="o">:</span> <span class="nx">$</span><span class="p">{</span><span class="nx">data</span><span class="p">}</span><span class="err">`</span><span class="p">);</span>
</span><span class='line'>  <span class="p">});</span>
</span><span class='line'>
</span><span class='line'>  <span class="nx">proc</span><span class="p">.</span><span class="nx">on</span><span class="p">(</span><span class="s1">&#39;close&#39;</span><span class="p">,</span> <span class="kd">function</span><span class="p">(</span><span class="nx">code</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'>    <span class="k">if</span><span class="p">(</span><span class="nx">code</span> <span class="o">!==</span> <span class="mi">0</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'>      <span class="k">return</span> <span class="nx">callback</span><span class="p">(</span><span class="k">new</span> <span class="nb">Error</span><span class="p">(</span><span class="err">`</span><span class="nx">Process</span> <span class="nx">exited</span> <span class="kd">with</span> <span class="nx">non</span><span class="o">-</span><span class="nx">zero</span> <span class="nx">status</span> <span class="nx">code</span> <span class="nx">$</span><span class="p">{</span><span class="nx">code</span><span class="p">}</span><span class="err">`</span><span class="p">));</span>
</span><span class='line'>    <span class="p">}</span>
</span><span class='line'>
</span><span class='line'>    <span class="kr">const</span> <span class="nx">response</span> <span class="o">=</span> <span class="p">{</span>
</span><span class='line'>      <span class="nx">statusCode</span><span class="o">:</span> <span class="mi">200</span><span class="p">,</span>
</span><span class='line'>      <span class="nx">body</span><span class="o">:</span> <span class="nx">JSON</span><span class="p">.</span><span class="nx">stringify</span><span class="p">({</span>
</span><span class='line'>        <span class="nx">message</span><span class="o">:</span> <span class="nx">strToReturn</span><span class="p">,</span>
</span><span class='line'>        <span class="c1">//input: event,</span>
</span><span class='line'>      <span class="p">}),</span>
</span><span class='line'>    <span class="p">};</span>
</span><span class='line'>
</span><span class='line'>    <span class="nx">callback</span><span class="p">(</span><span class="kc">null</span><span class="p">,</span> <span class="nx">response</span><span class="p">);</span>
</span><span class='line'>  <span class="p">});</span>
</span><span class='line'><span class="p">};</span>
</span></code></pre></td></tr></table></div></figure>


<p>Included is the PHP binary to bundle with our serverless function.</p>

<p>(You may need to compile it yourself with different options. See below for help on how to do this.)</p>

<p>Check it works from your shell.</p>

<pre><code>$ php index.php
</code></pre>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class='sh'><span class='line'>Go Serverless v1.0! Your PHP <span class="k">function </span>executed successfully!
</span></code></pre></td></tr></table></div></figure>


<p>Run it locally through the Serverless Framework.</p>

<pre><code>$ sls invoke local --function hello
</code></pre>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
</pre></td><td class='code'><pre><code class='sh'><span class='line'>Serverless: Your <span class="k">function </span>ran successfully.
</span><span class='line'>
</span><span class='line'><span class="o">{</span>
</span><span class='line'>    <span class="s2">&quot;statusCode&quot;</span>: 200,
</span><span class='line'>    <span class="s2">&quot;body&quot;</span>: <span class="s2">&quot;{\&quot;message\&quot;:\&quot;Go Serverless v1.0! Your PHP function executed successfully!\&quot;}&quot;</span>
</span><span class='line'><span class="o">}</span>
</span></code></pre></td></tr></table></div></figure>


<p>Looks good. Let&#8217;s deploy.</p>

<pre><code>$ sls deploy
</code></pre>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
<span class='line-number'>17</span>
<span class='line-number'>18</span>
</pre></td><td class='code'><pre><code class='sh'><span class='line'>Serverless: Packaging service…
</span><span class='line'>Serverless: Uploading CloudFormation file to S3…
</span><span class='line'>Serverless: Uploading service .zip file to S3…
</span><span class='line'>Serverless: Updating Stack…
</span><span class='line'>Serverless: Checking Stack update progress…
</span><span class='line'>..........
</span><span class='line'>Serverless: Stack update finished…
</span><span class='line'>
</span><span class='line'>Service Information
</span><span class='line'>service: serverless-php
</span><span class='line'>stage: dev
</span><span class='line'>region: eu-west-1
</span><span class='line'>api keys:
</span><span class='line'>  None
</span><span class='line'>endpoints:
</span><span class='line'>  GET - https://c1w0hct166.execute-api.eu-west-1.amazonaws.com/dev/hello
</span><span class='line'>functions:
</span><span class='line'>  serverless-php-dev-hello: arn:aws:lambda:eu-west-1:962613113552:function:serverless-php-dev-hello
</span></code></pre></td></tr></table></div></figure>


<p>Run the remote function via Serverless.</p>

<pre><code>$ sls invoke --function hello
</code></pre>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
</pre></td><td class='code'><pre><code class='sh'><span class='line'><span class="o">{</span>
</span><span class='line'>    <span class="s2">&quot;statusCode&quot;</span>: 200,
</span><span class='line'>    <span class="s2">&quot;body&quot;</span>: <span class="s2">&quot;{\&quot;message\&quot;:\&quot;Go Serverless v1.0! Your PHP function executed successfully!\&quot;,\&quot;input\&quot;:{}}&quot;</span>
</span><span class='line'><span class="o">}</span>
</span></code></pre></td></tr></table></div></figure>


<p>Visit the endpoint in your browser.</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
</pre></td><td class='code'><pre><code class='json'><span class='line'><span class="p">{</span>
</span><span class='line'>    <span class="nt">&quot;message&quot;</span><span class="p">:</span> <span class="s2">&quot;Go Serverless v1.0! Your PHP function executed successfully!&quot;</span>
</span><span class='line'><span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>


<p>Nice. It&#8217;s all working.</p>

<h2>Rebuilding the PHP binary</h2>

<p>Depending on the PHP function you need to run, it may be necessary to rebuild the php binary with different flags and dependencies. You can do this best with docker.</p>

<pre><code>$ docker --version
Docker version 1.12.3, build 6b644ec
</code></pre>

<p>Modify <code>dockerfile.buildphp</code> as necessary.</p>

<p>Then run:</p>

<pre><code>$ sh buildphp.sh
</code></pre>

<p>This will build a new PHP binary and copy it to the project root. You can immediately deploy for testing with:</p>

<pre><code>$ sls deploy
</code></pre>

<h2>Thanks</h2>

<p>Shout out to <a href="https://github.com/dannylinden/aws-lambda-php">Danny Linden</a> whose code got me started on this.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Smart hiding of the selection boxes in XAF web applications]]></title>
    <link href="http://ZeroSharp.github.com/smart-hiding-of-the-selection-boxes-in-xaf-web-applications/"/>
    <updated>2016-11-06T18:39:00+00:00</updated>
    <id>http://ZeroSharp.github.com/smart-hiding-of-the-selection-boxes-in-xaf-web-applications</id>
    <content type="html"><![CDATA[<p>When an <a href="https://www.devexpress.com/products/net/application_framework/">XAF</a> list view has no selection-based actions available, the selection box still appears in the grid. Users get confused. In this post, we&#8217;ll look at a workaround.</p>

<h2>The problem</h2>

<p>In the XAF MainDemo, lets make Departments read-only for the User role.</p>

<figure class='code'><figcaption><span>Updater.cs</span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
</pre></td><td class='code'><pre><code class='c#'><span class='line'><span class="n">userRole</span><span class="p">.</span><span class="n">AddTypePermissionsRecursively</span><span class="p">&lt;</span><span class="n">Department</span><span class="p">&gt;(</span><span class="n">SecurityOperations</span><span class="p">.</span><span class="n">Create</span><span class="p">,</span> <span class="n">SecurityPermissionState</span><span class="p">.</span><span class="n">Deny</span><span class="p">);</span>
</span><span class='line'><span class="n">userRole</span><span class="p">.</span><span class="n">AddTypePermissionsRecursively</span><span class="p">&lt;</span><span class="n">Department</span><span class="p">&gt;(</span><span class="n">SecurityOperations</span><span class="p">.</span><span class="n">Write</span><span class="p">,</span> <span class="n">SecurityPermissionState</span><span class="p">.</span><span class="n">Deny</span><span class="p">);</span>
</span><span class='line'><span class="n">userRole</span><span class="p">.</span><span class="n">AddTypePermissionsRecursively</span><span class="p">&lt;</span><span class="n">Department</span><span class="p">&gt;(</span><span class="n">SecurityOperations</span><span class="p">.</span><span class="n">Delete</span><span class="p">,</span> <span class="n">SecurityPermissionState</span><span class="p">.</span><span class="n">Deny</span><span class="p">);</span>
</span></code></pre></td></tr></table></div></figure>


<p>Then start the web application, login as John and navigate to the Departments list view. There is a column selection box, but it serves no purpose. There are no actions that depend on a grid selection.</p>

<p><span class='caption-wrapper'><img class='caption' src='http://ZeroSharp.github.com/images/blog/selection-visibility-controller-001.png' width='' height='' title='Without the SelectionColumnVisibilityController'><span class='caption-text'>Without the SelectionColumnVisibilityController</span></span></p>

<h2>The fix</h2>

<p>Here is a controller which calculates whether there are any available actions which require one or more rows to be selected. If there are none, the selection box will not appear.</p>

<p>Add the following controller to the MainDemo.Module.Web project. It hides the selection box if there are no actions which depend on a grid selection.</p>

<figure class='code'><figcaption><span>SelectionColumnVisibilityController.cs</span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
<span class='line-number'>17</span>
<span class='line-number'>18</span>
<span class='line-number'>19</span>
<span class='line-number'>20</span>
<span class='line-number'>21</span>
<span class='line-number'>22</span>
<span class='line-number'>23</span>
<span class='line-number'>24</span>
<span class='line-number'>25</span>
<span class='line-number'>26</span>
<span class='line-number'>27</span>
<span class='line-number'>28</span>
<span class='line-number'>29</span>
<span class='line-number'>30</span>
<span class='line-number'>31</span>
<span class='line-number'>32</span>
<span class='line-number'>33</span>
<span class='line-number'>34</span>
<span class='line-number'>35</span>
<span class='line-number'>36</span>
<span class='line-number'>37</span>
<span class='line-number'>38</span>
<span class='line-number'>39</span>
<span class='line-number'>40</span>
<span class='line-number'>41</span>
<span class='line-number'>42</span>
<span class='line-number'>43</span>
<span class='line-number'>44</span>
<span class='line-number'>45</span>
<span class='line-number'>46</span>
<span class='line-number'>47</span>
<span class='line-number'>48</span>
<span class='line-number'>49</span>
<span class='line-number'>50</span>
<span class='line-number'>51</span>
<span class='line-number'>52</span>
<span class='line-number'>53</span>
<span class='line-number'>54</span>
<span class='line-number'>55</span>
<span class='line-number'>56</span>
<span class='line-number'>57</span>
<span class='line-number'>58</span>
<span class='line-number'>59</span>
<span class='line-number'>60</span>
<span class='line-number'>61</span>
<span class='line-number'>62</span>
<span class='line-number'>63</span>
<span class='line-number'>64</span>
<span class='line-number'>65</span>
<span class='line-number'>66</span>
<span class='line-number'>67</span>
<span class='line-number'>68</span>
<span class='line-number'>69</span>
<span class='line-number'>70</span>
<span class='line-number'>71</span>
<span class='line-number'>72</span>
<span class='line-number'>73</span>
<span class='line-number'>74</span>
<span class='line-number'>75</span>
<span class='line-number'>76</span>
<span class='line-number'>77</span>
<span class='line-number'>78</span>
<span class='line-number'>79</span>
<span class='line-number'>80</span>
<span class='line-number'>81</span>
<span class='line-number'>82</span>
<span class='line-number'>83</span>
<span class='line-number'>84</span>
<span class='line-number'>85</span>
<span class='line-number'>86</span>
<span class='line-number'>87</span>
<span class='line-number'>88</span>
<span class='line-number'>89</span>
<span class='line-number'>90</span>
<span class='line-number'>91</span>
<span class='line-number'>92</span>
<span class='line-number'>93</span>
<span class='line-number'>94</span>
<span class='line-number'>95</span>
<span class='line-number'>96</span>
<span class='line-number'>97</span>
<span class='line-number'>98</span>
<span class='line-number'>99</span>
<span class='line-number'>100</span>
<span class='line-number'>101</span>
<span class='line-number'>102</span>
<span class='line-number'>103</span>
<span class='line-number'>104</span>
<span class='line-number'>105</span>
<span class='line-number'>106</span>
<span class='line-number'>107</span>
<span class='line-number'>108</span>
<span class='line-number'>109</span>
<span class='line-number'>110</span>
<span class='line-number'>111</span>
<span class='line-number'>112</span>
<span class='line-number'>113</span>
<span class='line-number'>114</span>
<span class='line-number'>115</span>
<span class='line-number'>116</span>
<span class='line-number'>117</span>
<span class='line-number'>118</span>
<span class='line-number'>119</span>
<span class='line-number'>120</span>
<span class='line-number'>121</span>
<span class='line-number'>122</span>
<span class='line-number'>123</span>
<span class='line-number'>124</span>
<span class='line-number'>125</span>
<span class='line-number'>126</span>
<span class='line-number'>127</span>
<span class='line-number'>128</span>
<span class='line-number'>129</span>
<span class='line-number'>130</span>
<span class='line-number'>131</span>
<span class='line-number'>132</span>
<span class='line-number'>133</span>
<span class='line-number'>134</span>
<span class='line-number'>135</span>
<span class='line-number'>136</span>
<span class='line-number'>137</span>
<span class='line-number'>138</span>
<span class='line-number'>139</span>
<span class='line-number'>140</span>
<span class='line-number'>141</span>
</pre></td><td class='code'><pre><code class='c#'><span class='line'><span class="k">using</span> <span class="nn">System</span><span class="p">;</span>
</span><span class='line'><span class="k">using</span> <span class="nn">DevExpress.ExpressApp</span><span class="p">;</span>
</span><span class='line'><span class="k">using</span> <span class="nn">DevExpress.ExpressApp.Actions</span><span class="p">;</span>
</span><span class='line'><span class="k">using</span> <span class="nn">DevExpress.ExpressApp.Editors</span><span class="p">;</span>
</span><span class='line'><span class="k">using</span> <span class="nn">DevExpress.ExpressApp.SystemModule</span><span class="p">;</span>
</span><span class='line'><span class="k">using</span> <span class="nn">DevExpress.Web</span><span class="p">;</span>
</span><span class='line'><span class="k">using</span> <span class="nn">System.Linq</span><span class="p">;</span>
</span><span class='line'>
</span><span class='line'><span class="k">namespace</span> <span class="nn">MainDemo.Module.Web.Controllers</span>
</span><span class='line'><span class="p">{</span>
</span><span class='line'>    <span class="k">public</span> <span class="k">class</span> <span class="nc">SelectionColumnVisibilityController</span> <span class="p">:</span> <span class="n">ViewController</span>
</span><span class='line'>    <span class="p">{</span>
</span><span class='line'>        <span class="k">public</span> <span class="nf">SelectionColumnVisibilityController</span><span class="p">()</span>
</span><span class='line'>        <span class="p">{</span>
</span><span class='line'>            <span class="n">TargetViewType</span> <span class="p">=</span> <span class="n">ViewType</span><span class="p">.</span><span class="n">ListView</span><span class="p">;</span>
</span><span class='line'>        <span class="p">}</span>
</span><span class='line'>
</span><span class='line'>        <span class="k">private</span> <span class="kt">bool</span> <span class="nf">IsSelectionColumnVisible</span><span class="p">()</span>
</span><span class='line'>        <span class="p">{</span>
</span><span class='line'>            <span class="kt">bool</span> <span class="n">isSelectionColumnRequired</span> <span class="p">=</span> <span class="k">false</span><span class="p">;</span>
</span><span class='line'>            <span class="c1">// remove checkbox if there are no available actions</span>
</span><span class='line'>            <span class="k">foreach</span> <span class="p">(</span><span class="n">Controller</span> <span class="n">controller</span> <span class="k">in</span> <span class="n">Frame</span><span class="p">.</span><span class="n">Controllers</span><span class="p">)</span>
</span><span class='line'>            <span class="p">{</span>
</span><span class='line'>                <span class="k">if</span> <span class="p">(!</span><span class="n">controller</span><span class="p">.</span><span class="n">Active</span><span class="p">)</span>
</span><span class='line'>                    <span class="k">continue</span><span class="p">;</span>
</span><span class='line'>
</span><span class='line'>                <span class="k">if</span> <span class="p">(</span><span class="n">controller</span><span class="p">.</span><span class="n">Actions</span><span class="p">.</span><span class="n">Count</span> <span class="p">==</span> <span class="m">0</span><span class="p">)</span>
</span><span class='line'>                    <span class="k">continue</span><span class="p">;</span>
</span><span class='line'>
</span><span class='line'>                <span class="kt">bool</span> <span class="n">allowEdit</span> <span class="p">=</span> <span class="k">true</span><span class="p">;</span>
</span><span class='line'>                <span class="k">if</span> <span class="p">((</span><span class="n">Frame</span> <span class="k">is</span> <span class="n">NestedFrame</span><span class="p">)</span> <span class="p">&amp;&amp;</span> <span class="p">(((</span><span class="n">NestedFrame</span><span class="p">)</span><span class="n">Frame</span><span class="p">).</span><span class="n">ViewItem</span> <span class="k">is</span> <span class="n">PropertyEditor</span><span class="p">))</span>
</span><span class='line'>                    <span class="n">allowEdit</span> <span class="p">=</span> <span class="p">(</span><span class="kt">bool</span><span class="p">)((</span><span class="n">PropertyEditor</span><span class="p">)((</span><span class="n">NestedFrame</span><span class="p">)</span><span class="n">Frame</span><span class="p">).</span><span class="n">ViewItem</span><span class="p">).</span><span class="n">AllowEdit</span><span class="p">;</span>
</span><span class='line'>
</span><span class='line'>                <span class="k">foreach</span> <span class="p">(</span><span class="n">ActionBase</span> <span class="n">action</span> <span class="k">in</span> <span class="n">controller</span><span class="p">.</span><span class="n">Actions</span><span class="p">)</span>
</span><span class='line'>                <span class="p">{</span>
</span><span class='line'>                    <span class="k">if</span> <span class="p">(</span><span class="n">action</span><span class="p">.</span><span class="n">SelectionDependencyType</span> <span class="p">==</span> <span class="n">SelectionDependencyType</span><span class="p">.</span><span class="n">RequireMultipleObjects</span><span class="p">)</span>
</span><span class='line'>                    <span class="p">{</span>
</span><span class='line'>                        <span class="k">if</span> <span class="p">(</span><span class="n">action</span><span class="p">.</span><span class="n">Active</span> <span class="p">||</span> <span class="n">IsActionInactiveBySelectionContext</span><span class="p">(</span><span class="n">action</span><span class="p">))</span>
</span><span class='line'>                        <span class="p">{</span>
</span><span class='line'>                            <span class="k">if</span> <span class="p">(</span><span class="n">action</span><span class="p">.</span><span class="n">Enabled</span> <span class="p">||</span> <span class="n">IsActionDisabledBySelectionContext</span><span class="p">(</span><span class="n">action</span><span class="p">))</span>
</span><span class='line'>                            <span class="p">{</span>
</span><span class='line'>                                <span class="n">isSelectionColumnRequired</span> <span class="p">=</span> <span class="k">true</span><span class="p">;</span>
</span><span class='line'>                                <span class="k">break</span><span class="p">;</span>
</span><span class='line'>                            <span class="p">}</span>
</span><span class='line'>                        <span class="p">}</span>
</span><span class='line'>                    <span class="p">}</span>
</span><span class='line'>                <span class="p">}</span>
</span><span class='line'>                <span class="k">if</span> <span class="p">(</span><span class="n">isSelectionColumnRequired</span><span class="p">)</span>
</span><span class='line'>                    <span class="k">break</span><span class="p">;</span>
</span><span class='line'>            <span class="p">}</span>
</span><span class='line'>            <span class="k">return</span> <span class="n">isSelectionColumnRequired</span><span class="p">;</span>
</span><span class='line'>        <span class="p">}</span>
</span><span class='line'>
</span><span class='line'>        <span class="k">private</span> <span class="kt">bool</span> <span class="nf">IsActionInactiveBySelectionContext</span><span class="p">(</span><span class="n">ActionBase</span> <span class="n">action</span><span class="p">)</span>
</span><span class='line'>        <span class="p">{</span>
</span><span class='line'>            <span class="k">if</span> <span class="p">(</span><span class="n">action</span><span class="p">.</span><span class="n">Active</span><span class="p">)</span>
</span><span class='line'>                <span class="k">return</span> <span class="k">true</span><span class="p">;</span>
</span><span class='line'>            <span class="k">else</span>
</span><span class='line'>            <span class="p">{</span>
</span><span class='line'>                <span class="k">foreach</span> <span class="p">(</span><span class="kt">string</span> <span class="n">item</span> <span class="k">in</span> <span class="n">action</span><span class="p">.</span><span class="n">Active</span><span class="p">.</span><span class="n">GetKeys</span><span class="p">())</span>
</span><span class='line'>                <span class="p">{</span>
</span><span class='line'>                    <span class="k">if</span> <span class="p">(</span><span class="n">item</span> <span class="p">==</span> <span class="n">ActionBase</span><span class="p">.</span><span class="n">RequireMultipleObjectsContext</span> <span class="p">||</span> <span class="n">item</span> <span class="p">==</span> <span class="n">ActionBase</span><span class="p">.</span><span class="n">RequireSingleObjectContext</span><span class="p">)</span>
</span><span class='line'>                        <span class="k">continue</span><span class="p">;</span>
</span><span class='line'>                    <span class="k">if</span> <span class="p">(!</span><span class="n">action</span><span class="p">.</span><span class="n">Active</span><span class="p">[</span><span class="n">item</span><span class="p">])</span>
</span><span class='line'>                        <span class="k">return</span> <span class="k">false</span><span class="p">;</span>
</span><span class='line'>                <span class="p">}</span>
</span><span class='line'>                <span class="k">return</span> <span class="k">true</span><span class="p">;</span>
</span><span class='line'>            <span class="p">}</span>
</span><span class='line'>        <span class="p">}</span>
</span><span class='line'>
</span><span class='line'>        <span class="k">private</span> <span class="kt">bool</span> <span class="nf">IsActionDisabledBySelectionContext</span><span class="p">(</span><span class="n">ActionBase</span> <span class="n">action</span><span class="p">)</span>
</span><span class='line'>        <span class="p">{</span>
</span><span class='line'>            <span class="k">if</span> <span class="p">(</span><span class="n">action</span><span class="p">.</span><span class="n">Enabled</span><span class="p">)</span>
</span><span class='line'>                <span class="k">return</span> <span class="k">true</span><span class="p">;</span>
</span><span class='line'>            <span class="k">else</span>
</span><span class='line'>            <span class="p">{</span>
</span><span class='line'>                <span class="k">foreach</span> <span class="p">(</span><span class="kt">string</span> <span class="n">item</span> <span class="k">in</span> <span class="n">action</span><span class="p">.</span><span class="n">Enabled</span><span class="p">.</span><span class="n">GetKeys</span><span class="p">())</span>
</span><span class='line'>                <span class="p">{</span>
</span><span class='line'>                    <span class="k">if</span> <span class="p">(</span><span class="n">item</span> <span class="p">==</span> <span class="n">ActionBase</span><span class="p">.</span><span class="n">RequireMultipleObjectsContext</span> <span class="p">||</span>
</span><span class='line'>                        <span class="n">item</span> <span class="p">==</span> <span class="n">ActionBase</span><span class="p">.</span><span class="n">RequireSingleObjectContext</span> <span class="p">||</span>
</span><span class='line'>                        <span class="n">item</span> <span class="p">==</span> <span class="n">ActionsCriteriaViewController</span><span class="p">.</span><span class="n">EnabledByCriteriaKey</span><span class="p">)</span>
</span><span class='line'>                        <span class="k">continue</span><span class="p">;</span>
</span><span class='line'>                    <span class="k">if</span> <span class="p">(!</span><span class="n">action</span><span class="p">.</span><span class="n">Enabled</span><span class="p">[</span><span class="n">item</span><span class="p">])</span>
</span><span class='line'>                        <span class="k">return</span> <span class="k">false</span><span class="p">;</span>
</span><span class='line'>                <span class="p">}</span>
</span><span class='line'>                <span class="k">return</span> <span class="k">true</span><span class="p">;</span>
</span><span class='line'>            <span class="p">}</span>
</span><span class='line'>        <span class="p">}</span>
</span><span class='line'>
</span><span class='line'>        <span class="k">protected</span> <span class="k">override</span> <span class="k">void</span> <span class="nf">OnViewControlsCreated</span><span class="p">()</span>
</span><span class='line'>        <span class="p">{</span>
</span><span class='line'>            <span class="k">base</span><span class="p">.</span><span class="n">OnViewControlsCreated</span><span class="p">();</span>
</span><span class='line'>            <span class="n">ASPxGridView</span> <span class="n">grid</span> <span class="p">=</span> <span class="p">((</span><span class="n">ListView</span><span class="p">)</span><span class="k">this</span><span class="p">.</span><span class="n">View</span><span class="p">).</span><span class="n">Editor</span><span class="p">.</span><span class="n">Control</span> <span class="k">as</span> <span class="n">ASPxGridView</span><span class="p">;</span>
</span><span class='line'>            <span class="k">if</span> <span class="p">(</span><span class="n">grid</span> <span class="p">!=</span> <span class="k">null</span><span class="p">)</span>
</span><span class='line'>            <span class="p">{</span>
</span><span class='line'>                <span class="n">grid</span><span class="p">.</span><span class="n">Load</span> <span class="p">+=</span> <span class="n">grid_Load</span><span class="p">;</span>
</span><span class='line'>                <span class="n">grid</span><span class="p">.</span><span class="n">DataBound</span> <span class="p">+=</span> <span class="n">grid_DataBound</span><span class="p">;</span>
</span><span class='line'>            <span class="p">}</span>
</span><span class='line'>        <span class="p">}</span>
</span><span class='line'>
</span><span class='line'>        <span class="k">protected</span> <span class="k">override</span> <span class="k">void</span> <span class="nf">OnDeactivated</span><span class="p">()</span>
</span><span class='line'>        <span class="p">{</span>
</span><span class='line'>            <span class="k">base</span><span class="p">.</span><span class="n">OnDeactivated</span><span class="p">();</span>
</span><span class='line'>            <span class="n">ASPxGridView</span> <span class="n">grid</span> <span class="p">=</span> <span class="p">((</span><span class="n">ListView</span><span class="p">)</span><span class="k">this</span><span class="p">.</span><span class="n">View</span><span class="p">).</span><span class="n">Editor</span><span class="p">.</span><span class="n">Control</span> <span class="k">as</span> <span class="n">ASPxGridView</span><span class="p">;</span>
</span><span class='line'>            <span class="k">if</span> <span class="p">(</span><span class="n">grid</span> <span class="p">!=</span> <span class="k">null</span><span class="p">)</span>
</span><span class='line'>            <span class="p">{</span>
</span><span class='line'>                <span class="n">grid</span><span class="p">.</span><span class="n">DataBound</span> <span class="p">-=</span> <span class="n">grid_DataBound</span><span class="p">;</span>
</span><span class='line'>                <span class="n">grid</span><span class="p">.</span><span class="n">Load</span> <span class="p">-=</span> <span class="n">grid_Load</span><span class="p">;</span>
</span><span class='line'>            <span class="p">}</span>
</span><span class='line'>        <span class="p">}</span>
</span><span class='line'>
</span><span class='line'>        <span class="k">void</span> <span class="nf">grid_Load</span><span class="p">(</span><span class="kt">object</span> <span class="n">sender</span><span class="p">,</span> <span class="n">EventArgs</span> <span class="n">e</span><span class="p">)</span>
</span><span class='line'>        <span class="p">{</span>
</span><span class='line'>            <span class="n">SetSelectionColumnVisibility</span><span class="p">(</span><span class="n">sender</span><span class="p">,</span> <span class="n">e</span><span class="p">);</span>
</span><span class='line'>        <span class="p">}</span>
</span><span class='line'>
</span><span class='line'>        <span class="k">void</span> <span class="nf">grid_DataBound</span><span class="p">(</span><span class="kt">object</span> <span class="n">sender</span><span class="p">,</span> <span class="n">EventArgs</span> <span class="n">e</span><span class="p">)</span>
</span><span class='line'>        <span class="p">{</span>
</span><span class='line'>            <span class="n">SetSelectionColumnVisibility</span><span class="p">(</span><span class="n">sender</span><span class="p">,</span> <span class="n">e</span><span class="p">);</span>
</span><span class='line'>        <span class="p">}</span>
</span><span class='line'>
</span><span class='line'>        <span class="k">private</span> <span class="k">void</span> <span class="nf">SetSelectionColumnVisibility</span><span class="p">(</span><span class="kt">object</span> <span class="n">sender</span><span class="p">,</span> <span class="n">EventArgs</span> <span class="n">e</span><span class="p">)</span>
</span><span class='line'>        <span class="p">{</span>
</span><span class='line'>            <span class="kt">bool</span> <span class="n">isSelectionColumnVisible</span> <span class="p">=</span> <span class="n">IsSelectionColumnVisible</span><span class="p">();</span>
</span><span class='line'>            <span class="k">if</span> <span class="p">(!</span><span class="n">isSelectionColumnVisible</span><span class="p">)</span>
</span><span class='line'>            <span class="p">{</span>
</span><span class='line'>                <span class="kt">var</span> <span class="n">grid</span> <span class="p">=</span> <span class="p">(</span><span class="n">ASPxGridView</span><span class="p">)</span><span class="n">sender</span><span class="p">;</span>
</span><span class='line'>                <span class="kt">var</span> <span class="n">selectionBoxColumn</span> <span class="p">=</span>
</span><span class='line'>                    <span class="n">grid</span><span class="p">.</span><span class="n">Columns</span>
</span><span class='line'>                        <span class="p">.</span><span class="n">OfType</span><span class="p">&lt;</span><span class="n">GridViewCommandColumn</span><span class="p">&gt;()</span>
</span><span class='line'>                        <span class="p">.</span><span class="n">Where</span><span class="p">(</span><span class="n">x</span> <span class="p">=&gt;</span> <span class="n">x</span><span class="p">.</span><span class="n">ShowSelectCheckbox</span><span class="p">)</span>
</span><span class='line'>                        <span class="p">.</span><span class="n">FirstOrDefault</span><span class="p">();</span>
</span><span class='line'>
</span><span class='line'>                <span class="k">if</span> <span class="p">(</span><span class="n">selectionBoxColumn</span> <span class="p">!=</span> <span class="k">null</span><span class="p">)</span>
</span><span class='line'>                <span class="p">{</span>
</span><span class='line'>                    <span class="n">selectionBoxColumn</span><span class="p">.</span><span class="n">Visible</span> <span class="p">=</span> <span class="k">false</span><span class="p">;</span>
</span><span class='line'>                <span class="p">}</span>
</span><span class='line'>            <span class="p">}</span>
</span><span class='line'>        <span class="p">}</span>
</span><span class='line'>    <span class="p">}</span>
</span><span class='line'><span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>


<p>Run the application again and see the difference. Now the grid looks like this. Notice, there is no longer a selection box on the row.</p>

<p><img src="http://ZeroSharp.github.com/images/blog/selection-visibility-controller-002.png" title="With the SelectionColumnVisibilityController" ></p>

<p>By the way, this is how it looks with old-style XAF web apps.</p>

<p><span class='caption-wrapper'><img class='caption' src='http://ZeroSharp.github.com/images/blog/selection-visibility-controller-003.png' width='' height='' title='Without the SelectionColumnVisibilityController'><span class='caption-text'>Without the SelectionColumnVisibilityController</span></span></p>

<p><span class='caption-wrapper'><img class='caption' src='http://ZeroSharp.github.com/images/blog/selection-visibility-controller-004.png' width='' height='' title='With the SelectionColumnVisibilityController'><span class='caption-text'>With the SelectionColumnVisibilityController</span></span></p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Sometimes you've just got to deploy]]></title>
    <link href="http://ZeroSharp.github.com/sometimes-youve-just-got-to-deploy/"/>
    <updated>2016-10-16T18:44:00+01:00</updated>
    <id>http://ZeroSharp.github.com/sometimes-youve-just-got-to-deploy</id>
    <content type="html"><![CDATA[<p>Sometimes the deadline has arrived and you still have some failing tests. After a discussion with the dev team, you decide to deploy anyway and fix the bugs for the next release. You need to get the build server to ignore the tests.</p>

<p>One way is just to mark the test with the <code>[Ignore]</code> attribute.</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
</pre></td><td class='code'><pre><code class='c#'><span class='line'><span class="na">[Test]</span>
</span><span class='line'><span class="na">[Ignore]</span> <span class="c1">// TODO: Fix this test before the next release!</span>
</span><span class='line'><span class="k">public</span> <span class="k">void</span> <span class="nf">Test</span><span class="p">()</span>
</span><span class='line'><span class="p">{</span>
</span><span class='line'>    <span class="c1">// Some failing test code...</span>
</span><span class='line'><span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>


<p>After the weekend, everyone forgets about the ignored tests and they never get fixed.</p>

<p>Instead, I like to do this.</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
</pre></td><td class='code'><pre><code class='c#'><span class='line'><span class="na">[Test]</span>
</span><span class='line'><span class="k">public</span> <span class="k">void</span> <span class="nf">Test</span><span class="p">()</span>
</span><span class='line'><span class="p">{</span>
</span><span class='line'>    <span class="k">if</span> <span class="p">(</span><span class="n">DateTime</span><span class="p">.</span><span class="n">Now</span> <span class="p">&lt;</span> <span class="k">new</span> <span class="n">DateTime</span><span class="p">(</span><span class="m">2016</span><span class="p">,</span> <span class="m">10</span><span class="p">,</span> <span class="m">17</span><span class="p">))</span>
</span><span class='line'>        <span class="n">Assert</span><span class="p">.</span><span class="n">Ignore</span><span class="p">(</span><span class="s">&quot;Temporarily ignored until October 17.&quot;</span><span class="p">);</span>
</span><span class='line'>    <span class="c1">// Some failing test code...</span>
</span><span class='line'><span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>


<p>This is a fairly rare occurrence for my team, so the above approach is sufficient and works with all test frameworks. But if you want to go further <a href="https://www.amido.com/code/conditional-ignore-nunit-and-the-ability-to-conditionally-ignore-a-test/">Richard Slater shows how to create an NUnit attribute</a>.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Boxstarter and checksums]]></title>
    <link href="http://ZeroSharp.github.com/boxstarter-and-checksums/"/>
    <updated>2016-09-22T21:04:00+01:00</updated>
    <id>http://ZeroSharp.github.com/boxstarter-and-checksums</id>
    <content type="html"><![CDATA[<p><a href="http://ZeroSharp.github.com/provisioning-a-new-development-machine-with-boxstarter/">I&#8217;ve blogged before</a> about using BoxStarter to efficiently provision a new development machine.</p>

<p>This is working very well for our developers. Maintaining the installation script takes a bit of effort but the benefits are worth it.</p>

<p>Recently, the chocolatey developers have been making things more secure and recent versions now require a checksum with any downloaded package. For now, there seems to be some difficulty using <code>Install-ChocolateyVsixPackage</code> within BoxStarter scripts.</p>

<p>If I try to run a script with</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
</pre></td><td class='code'><pre><code class='powershell'><span class='line'><span class="n">Install-ChocolateyVsixPackage</span>
</span><span class='line'>  <span class="n">StopOnFirstBuildError</span>
</span><span class='line'>  <span class="n">https</span><span class="err">:</span><span class="p">//</span><span class="n">visualstudiogallery</span><span class="p">.</span><span class="n">msdn</span><span class="p">.</span><span class="n">microsoft</span><span class="p">.</span><span class="n">com</span><span class="p">/</span><span class="n">91aaa139</span><span class="p">-</span><span class="n">5d3c</span><span class="p">-</span><span class="n">43a7-b39f</span><span class="p">-</span><span class="n">369196a84fa5</span><span class="p">/</span><span class="n">file</span><span class="p">/</span><span class="n">44205</span><span class="p">/</span><span class="n">7</span><span class="p">/</span><span class="n">StopOnFirstBuildError</span><span class="p">.</span><span class="n">vsix</span>
</span></code></pre></td></tr></table></div></figure>


<p>I get the following error message:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
</pre></td><td class='code'><pre><code class='powershell'><span class='line'> <span class="n">WARNING</span><span class="err">:</span> <span class="n">Missing</span> <span class="n">package</span> <span class="n">checksums</span> <span class="n">are</span> <span class="n">not</span> <span class="n">allowed</span> <span class="p">(</span><span class="n">by</span> <span class="k">default</span> <span class="k">for</span> <span class="n">HTTP</span><span class="p">/</span><span class="n">FTP</span><span class="p">,</span>
</span><span class='line'>  <span class="n">HTTPS</span> <span class="n">when</span> <span class="n">feature</span> <span class="s1">&#39;allowEmptyChecksumsSecure&#39;</span> <span class="n">is</span> <span class="n">disabled</span><span class="p">)</span> <span class="k">for</span>
</span><span class='line'>  <span class="n">safety</span> <span class="n">and</span> <span class="n">security</span> <span class="n">reasons</span><span class="p">.</span> <span class="n">Although</span> <span class="n">we</span> <span class="n">strongly</span> <span class="n">advise</span> <span class="n">against</span> <span class="n">it</span><span class="p">,</span>
</span><span class='line'>  <span class="k">if</span> <span class="n">you</span> <span class="n">need</span> <span class="n">this</span> <span class="n">functionality</span><span class="p">,</span> <span class="n">please</span> <span class="n">set</span> <span class="n">the</span> <span class="n">feature</span>
</span><span class='line'>  <span class="s1">&#39;allowEmptyChecksums&#39;</span> <span class="p">(</span><span class="s1">&#39;choco feature enable -n</span>
</span><span class='line'><span class="s1">  allowEmptyChecksums&#39;</span><span class="p">)</span>
</span><span class='line'> <span class="n">There</span> <span class="n">were</span> <span class="n">errors</span> <span class="n">attempting</span> <span class="n">to</span> <span class="n">retrieve</span> <span class="n">the</span> <span class="n">vsix</span> <span class="n">from</span> <span class="n">https</span><span class="err">:</span><span class="p">//</span><span class="n">visualstudiogallery</span><span class="p">.</span><span class="n">msdn</span><span class="p">.</span><span class="n">microsoft</span><span class="p">.</span><span class="n">com</span><span class="p">/</span><span class="n">91aaa139</span><span class="p">-</span><span class="n">5d3c</span><span class="p">-</span><span class="n">43a</span>
</span><span class='line'>  <span class="n">or</span> <span class="n">pass</span> <span class="k">in</span> <span class="n">the</span> <span class="n">option</span> <span class="s1">&#39;--allow-empty-checksums&#39;</span><span class="p">.</span>
</span><span class='line'> <span class="n">7-b39f</span><span class="p">-</span><span class="n">369196a84fa5</span><span class="p">/</span><span class="n">file</span><span class="p">/</span><span class="n">44205</span><span class="p">/</span><span class="n">7</span><span class="p">/</span><span class="n">StopOnFirstBuildError</span><span class="p">.</span><span class="n">vsix</span><span class="p">.</span> <span class="n">The</span> <span class="n">error</span> <span class="n">message</span> <span class="n">was</span> <span class="s1">&#39;Empty checksums are no longer</span>
</span><span class='line'><span class="s1"> allowed by default for non-secure sources. Please ask the maintainer to add checksums to this package. In the meantime </span>
</span><span class='line'><span class="s1"> if you need this package to work correctly, please enable the feature allowEmptyChecksums or provide the runtime</span>
</span><span class='line'><span class="s1"> switch &#39;</span><span class="p">-</span><span class="n">-allowEmptyChecksums</span><span class="s1">&#39;. We strongly advise against allowing empty checksums for HTTP/FTP sources.&#39;</span><span class="p">.</span>
</span><span class='line'> <span class="n">At</span> <span class="n">C</span><span class="err">:</span><span class="p">\</span><span class="n">ProgramData</span><span class="p">\</span><span class="n">chocolatey</span><span class="p">\</span><span class="n">helpers</span><span class="p">\</span><span class="n">functions</span><span class="p">\</span><span class="n">Install-ChocolateyVsixPackage</span><span class="p">.</span><span class="n">ps1</span><span class="err">:</span><span class="n">173</span> <span class="n">char</span><span class="err">:</span><span class="n">13</span>
</span><span class='line'>
</span><span class='line'><span class="n">etc</span><span class="p">...</span>
</span></code></pre></td></tr></table></div></figure>


<p>I tried the suggested <code>allowEmptyChecksums</code> but it was still raising an error. After some experimentation it seems that the combination of (temporarily) disabling the <code>checksumFiles</code> feature and enabling <code>allowEmptyChecksums</code> works. Here is the relevant section of my boxstarter script.</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
<span class='line-number'>17</span>
<span class='line-number'>18</span>
<span class='line-number'>19</span>
<span class='line-number'>20</span>
</pre></td><td class='code'><pre><code class='powershell'><span class='line'><span class="c"># temporarily enable/disable features to bypass checksums</span>
</span><span class='line'><span class="n">choco</span> <span class="n">feature</span> <span class="n">disable</span> <span class="n">-n</span><span class="p">=</span><span class="n">checksumFiles</span>
</span><span class='line'><span class="n">choco</span> <span class="n">feature</span> <span class="n">enable</span> <span class="n">-n</span><span class="p">=</span><span class="n">allowEmptyChecksums</span>
</span><span class='line'><span class="k">try</span> <span class="p">{</span>
</span><span class='line'>    <span class="c"># VS extensions for all versions of Visual Studio</span>
</span><span class='line'>    <span class="n">Install-ChocolateyVsixPackage</span> <span class="n">StopOnFirstBuildError</span> <span class="n">https</span><span class="err">:</span><span class="p">//</span><span class="n">visualstudiogallery</span><span class="p">.</span><span class="n">msdn</span><span class="p">.</span><span class="n">microsoft</span><span class="p">.</span><span class="n">com</span><span class="p">/</span><span class="n">91aaa139</span><span class="p">-</span><span class="n">5d3c</span><span class="p">-</span><span class="n">43a7-b39f</span><span class="p">-</span><span class="n">369196a84fa5</span><span class="p">/</span><span class="n">file</span><span class="p">/</span><span class="n">44205</span><span class="p">/</span><span class="n">7</span><span class="p">/</span><span class="n">StopOnFirstBuildError</span><span class="p">.</span><span class="n">vsix</span>
</span><span class='line'>    <span class="n">Install-ChocolateyVsixPackage</span> <span class="n">VisualHG</span> <span class="n">https</span><span class="err">:</span><span class="p">//</span><span class="n">visualhg</span><span class="p">.</span><span class="n">codeplex</span><span class="p">.</span><span class="n">com</span><span class="p">/</span><span class="n">downloads</span><span class="p">/</span><span class="n">get</span><span class="p">/</span><span class="n">1475782</span>
</span><span class='line'>
</span><span class='line'>    <span class="c"># VS extensions for VS2015</span>
</span><span class='line'>    <span class="n">Install-ChocolateyVsixPackage</span> <span class="n">WebEssentials2015</span> <span class="n">https</span><span class="err">:</span><span class="p">//</span><span class="n">visualstudiogallery</span><span class="p">.</span><span class="n">msdn</span><span class="p">.</span><span class="n">microsoft</span><span class="p">.</span><span class="n">com</span><span class="p">/</span><span class="n">ee6e6d8c-c837</span><span class="p">-</span><span class="n">41fb</span><span class="p">-</span><span class="n">886a</span><span class="p">-</span><span class="n">6b50ae2d06a2</span><span class="p">/</span><span class="n">file</span><span class="p">/</span><span class="n">146119</span><span class="p">/</span><span class="n">19</span><span class="p">/</span><span class="n">WebEssentials2015</span><span class="p">.</span><span class="n">vsix</span>
</span><span class='line'>    <span class="n">Install-ChocolateyVsixPackage</span> <span class="n">WebExtensionPack</span> <span class="n">https</span><span class="err">:</span><span class="p">//</span><span class="n">visualstudiogallery</span><span class="p">.</span><span class="n">msdn</span><span class="p">.</span><span class="n">microsoft</span><span class="p">.</span><span class="n">com</span><span class="p">/</span><span class="n">f3b504c6</span><span class="p">-</span><span class="n">0095</span><span class="p">-</span><span class="n">42f1-a989</span><span class="p">-</span><span class="n">51d5fc2a8459</span><span class="p">/</span><span class="n">file</span><span class="p">/</span><span class="n">186606</span><span class="p">/</span><span class="n">23</span><span class="p">/</span><span class="n">Web</span><span class="k">%</span><span class="n">20Extension</span><span class="k">%</span><span class="n">20Pack</span><span class="k">%</span><span class="n">20v1</span><span class="p">.</span><span class="n">5</span><span class="p">.</span><span class="n">50</span><span class="p">.</span><span class="n">vsix</span>
</span><span class='line'>    <span class="n">Install-ChocolateyVsixPackage</span> <span class="n">T4Toolbox2015</span> <span class="n">https</span><span class="err">:</span><span class="p">//</span><span class="n">visualstudiogallery</span><span class="p">.</span><span class="n">msdn</span><span class="p">.</span><span class="n">microsoft</span><span class="p">.</span><span class="n">com</span><span class="p">/</span><span class="n">34b6d489-afbc</span><span class="p">-</span><span class="n">4d7b</span><span class="p">-</span><span class="n">82c3-dded2b726dbc</span><span class="p">/</span><span class="n">file</span><span class="p">/</span><span class="n">165481</span><span class="p">/</span><span class="n">2</span><span class="p">/</span><span class="n">T4Toolbox</span><span class="p">.</span><span class="n">14</span><span class="p">.</span><span class="n">0</span><span class="p">.</span><span class="n">0</span><span class="p">.</span><span class="n">71</span><span class="p">.</span><span class="n">vsix</span>
</span><span class='line'>
</span><span class='line'>    <span class="c"># CodeRush for Roslyn Preview</span>
</span><span class='line'>    <span class="n">Install-ChocolateyVsixPackage</span> <span class="n">CodeRushForRoslyn</span> <span class="n">https</span><span class="err">:</span><span class="p">//</span><span class="n">visualstudiogallery</span><span class="p">.</span><span class="n">msdn</span><span class="p">.</span><span class="n">microsoft</span><span class="p">.</span><span class="n">com</span><span class="p">/</span><span class="n">8a8390ae</span><span class="p">-</span><span class="n">1f71</span><span class="p">-</span><span class="n">4659</span><span class="p">-</span><span class="n">9d8d</span><span class="p">-</span><span class="n">5dd56fd8a72e</span><span class="p">/</span><span class="n">file</span><span class="p">/</span><span class="n">163212</span><span class="p">/</span><span class="n">15</span><span class="p">/</span><span class="n">DevExpress</span><span class="p">.</span><span class="n">CodeRush</span><span class="p">.</span><span class="n">Roslyn</span><span class="p">-</span><span class="n">16</span><span class="p">.</span><span class="n">1</span><span class="p">.</span><span class="n">6</span><span class="p">.</span><span class="n">vsix</span>
</span><span class='line'><span class="p">}</span>
</span><span class='line'><span class="k">finally</span> <span class="p">{</span>
</span><span class='line'>    <span class="n">choco</span> <span class="n">feature</span> <span class="n">enable</span> <span class="n">-n</span><span class="p">=</span><span class="n">checksumFiles</span>
</span><span class='line'>    <span class="n">choco</span> <span class="n">feature</span> <span class="n">disable</span> <span class="n">-n</span><span class="p">=</span><span class="n">allowEmptyChecksums</span>
</span><span class='line'><span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>


<p>And then everything works as expected.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[An XAF workaround for 'Prevent this page from creating additional dialogs.']]></title>
    <link href="http://ZeroSharp.github.com/an-xaf-workaround-for-prevent-this-page-from-creating-additional-dialogs-dot/"/>
    <updated>2016-05-16T13:51:00+01:00</updated>
    <id>http://ZeroSharp.github.com/an-xaf-workaround-for-prevent-this-page-from-creating-additional-dialogs-dot</id>
    <content type="html"><![CDATA[<p>Both Chrome and Firefox have a &#8216;feature&#8217; which allows a user to ignore future calls to <code>confirm()</code>. Once this has been checked, any subsequent calls to <code>confirm()</code> return false immediately without showing the window.</p>

<p>In XAF, this behaviour prevents the application from working correctly. For instance, it becomes impossible to confirm a deletion.</p>

<p><img src="http://ZeroSharp.github.com/images/blog/prevent-this-page-001.png"></p>

<p>The following controller provides a work around. It injects some javascript into the page wrapping the call to <code>confirm()</code>. The new code detects when the <strong>Prevent this page from creating additional dialogs</strong> checkbox has been checked and returns true instead. The confirmation window still does not appear, but the XAF application works as if the user had pressed confirm instead of cancel.</p>

<figure class='code'><figcaption><span># HandleDisabledConfirmationsController.cs </span></figcaption>
 <div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
<span class='line-number'>17</span>
<span class='line-number'>18</span>
<span class='line-number'>19</span>
<span class='line-number'>20</span>
<span class='line-number'>21</span>
<span class='line-number'>22</span>
<span class='line-number'>23</span>
<span class='line-number'>24</span>
<span class='line-number'>25</span>
<span class='line-number'>26</span>
<span class='line-number'>27</span>
<span class='line-number'>28</span>
<span class='line-number'>29</span>
<span class='line-number'>30</span>
<span class='line-number'>31</span>
<span class='line-number'>32</span>
<span class='line-number'>33</span>
<span class='line-number'>34</span>
<span class='line-number'>35</span>
<span class='line-number'>36</span>
<span class='line-number'>37</span>
<span class='line-number'>38</span>
<span class='line-number'>39</span>
<span class='line-number'>40</span>
<span class='line-number'>41</span>
<span class='line-number'>42</span>
<span class='line-number'>43</span>
<span class='line-number'>44</span>
<span class='line-number'>45</span>
<span class='line-number'>46</span>
<span class='line-number'>47</span>
<span class='line-number'>48</span>
<span class='line-number'>49</span>
<span class='line-number'>50</span>
<span class='line-number'>51</span>
<span class='line-number'>52</span>
<span class='line-number'>53</span>
<span class='line-number'>54</span>
<span class='line-number'>55</span>
<span class='line-number'>56</span>
<span class='line-number'>57</span>
<span class='line-number'>58</span>
<span class='line-number'>59</span>
<span class='line-number'>60</span>
<span class='line-number'>61</span>
<span class='line-number'>62</span>
<span class='line-number'>63</span>
<span class='line-number'>64</span>
<span class='line-number'>65</span>
<span class='line-number'>66</span>
<span class='line-number'>67</span>
<span class='line-number'>68</span>
<span class='line-number'>69</span>
<span class='line-number'>70</span>
<span class='line-number'>71</span>
<span class='line-number'>72</span>
<span class='line-number'>73</span>
<span class='line-number'>74</span>
<span class='line-number'>75</span>
<span class='line-number'>76</span>
<span class='line-number'>77</span>
</pre></td><td class='code'><pre><code class='c'><span class='line'><span class="n">using</span> <span class="n">DevExpress</span><span class="p">.</span><span class="n">ExpressApp</span><span class="p">;</span>
</span><span class='line'><span class="n">using</span> <span class="n">DevExpress</span><span class="p">.</span><span class="n">ExpressApp</span><span class="p">.</span><span class="n">Web</span><span class="p">;</span>
</span><span class='line'><span class="n">using</span> <span class="n">DevExpress</span><span class="p">.</span><span class="n">Web</span><span class="p">.</span><span class="n">Internal</span><span class="p">;</span>
</span><span class='line'>
</span><span class='line'><span class="n">namespace</span> <span class="n">NetModule</span><span class="p">.</span><span class="n">Web</span><span class="p">.</span><span class="n">Controllers</span>
</span><span class='line'><span class="p">{</span>
</span><span class='line'>    <span class="n">public</span> <span class="n">class</span> <span class="n">HandleDisabledConfirmationsController</span> <span class="o">:</span> <span class="n">Controller</span>
</span><span class='line'>    <span class="p">{</span>
</span><span class='line'>        <span class="n">public</span> <span class="k">static</span> <span class="n">bool</span> <span class="n">IsChrome</span>
</span><span class='line'>        <span class="p">{</span>
</span><span class='line'>            <span class="n">get</span>
</span><span class='line'>            <span class="p">{</span>
</span><span class='line'>                <span class="k">return</span> <span class="n">RenderUtils</span><span class="p">.</span><span class="n">Browser</span><span class="p">.</span><span class="n">IsChrome</span><span class="p">;</span>
</span><span class='line'>            <span class="p">}</span>
</span><span class='line'>        <span class="p">}</span>
</span><span class='line'>
</span><span class='line'>        <span class="n">public</span> <span class="k">static</span> <span class="n">bool</span> <span class="n">IsFirefox</span>
</span><span class='line'>        <span class="p">{</span>
</span><span class='line'>            <span class="n">get</span>
</span><span class='line'>            <span class="p">{</span>
</span><span class='line'>                <span class="k">return</span> <span class="n">RenderUtils</span><span class="p">.</span><span class="n">Browser</span><span class="p">.</span><span class="n">IsFirefox</span><span class="p">;</span>
</span><span class='line'>            <span class="p">}</span>
</span><span class='line'>        <span class="p">}</span>
</span><span class='line'>
</span><span class='line'>        <span class="n">protected</span> <span class="n">override</span> <span class="kt">void</span> <span class="n">OnFrameAssigned</span><span class="p">()</span>
</span><span class='line'>        <span class="p">{</span>
</span><span class='line'>            <span class="n">base</span><span class="p">.</span><span class="n">OnFrameAssigned</span><span class="p">();</span>
</span><span class='line'>            <span class="k">if</span> <span class="p">(</span><span class="n">IsChrome</span> <span class="o">||</span> <span class="n">IsFirefox</span><span class="p">)</span>
</span><span class='line'>            <span class="p">{</span>
</span><span class='line'>                <span class="n">WebWindow</span> <span class="n">window</span> <span class="o">=</span> <span class="n">Frame</span> <span class="n">as</span> <span class="n">WebWindow</span><span class="p">;</span>
</span><span class='line'>                <span class="k">if</span> <span class="p">(</span><span class="n">window</span> <span class="o">!=</span> <span class="n">null</span><span class="p">)</span>
</span><span class='line'>                <span class="p">{</span>
</span><span class='line'>                    <span class="n">window</span><span class="p">.</span><span class="n">CustomRegisterTemplateDependentScripts</span> <span class="o">+=</span> <span class="n">window_CustomRegisterTemplateDependentScripts</span><span class="p">;</span>
</span><span class='line'>                <span class="p">}</span>
</span><span class='line'>            <span class="p">}</span>
</span><span class='line'>        <span class="p">}</span>
</span><span class='line'>
</span><span class='line'>        <span class="n">private</span> <span class="kt">void</span> <span class="n">window_CustomRegisterTemplateDependentScripts</span><span class="p">(</span><span class="n">object</span> <span class="n">sender</span><span class="p">,</span> <span class="n">CustomRegisterTemplateDependentScriptsEventArgs</span> <span class="n">e</span><span class="p">)</span>
</span><span class='line'>        <span class="p">{</span>
</span><span class='line'>            <span class="c1">// wrapper for &#39;confirm&#39;</span>
</span><span class='line'>            <span class="n">WebWindow</span> <span class="n">window</span> <span class="o">=</span> <span class="p">(</span><span class="n">WebWindow</span><span class="p">)</span><span class="n">sender</span><span class="p">;</span>
</span><span class='line'>
</span><span class='line'>            <span class="c1">// Detect the user has checked the &#39;prevent this page from creating additional dialogs&#39;.</span>
</span><span class='line'>            <span class="c1">// In which case assume all confirmations are accepted, rather than the default rejected</span>
</span><span class='line'>            <span class="n">var</span> <span class="n">confirmWrapper</span> <span class="o">=</span> <span class="err">@</span><span class="s">&quot;</span>
</span><span class='line'><span class="o">&lt;</span><span class="n">script</span><span class="o">&gt;</span>
</span><span class='line'><span class="n">window</span><span class="p">.</span><span class="n">nativeConfirm</span> <span class="o">=</span> <span class="n">window</span><span class="p">.</span><span class="n">confirm</span><span class="p">;</span>
</span><span class='line'><span class="n">window</span><span class="p">.</span><span class="n">confirm</span> <span class="o">=</span> <span class="n">function</span><span class="p">(</span><span class="n">message</span><span class="p">)</span>
</span><span class='line'><span class="p">{</span>
</span><span class='line'>    <span class="n">var</span> <span class="n">timeBefore</span> <span class="o">=</span> <span class="n">new</span> <span class="n">Date</span><span class="p">();</span>
</span><span class='line'>    <span class="n">var</span> <span class="n">confirmBool</span> <span class="o">=</span> <span class="n">nativeConfirm</span><span class="p">(</span><span class="n">message</span><span class="p">);</span>
</span><span class='line'>    <span class="n">var</span> <span class="n">timeAfter</span> <span class="o">=</span> <span class="n">new</span> <span class="n">Date</span><span class="p">();</span>
</span><span class='line'>    <span class="k">if</span> <span class="p">((</span><span class="n">timeAfter</span> <span class="o">-</span> <span class="n">timeBefore</span><span class="p">)</span> <span class="o">&lt;</span> <span class="mi">350</span><span class="p">)</span>
</span><span class='line'>    <span class="p">{</span>
</span><span class='line'>        <span class="n">confirmBool</span> <span class="o">=</span> <span class="nb">true</span><span class="p">;</span>
</span><span class='line'>    <span class="p">}</span>
</span><span class='line'>    <span class="k">return</span> <span class="n">confirmBool</span><span class="p">;</span>
</span><span class='line'><span class="p">}</span>
</span><span class='line'><span class="o">&lt;/</span><span class="n">script</span><span class="o">&gt;</span><span class="s">&quot;;</span>
</span><span class='line'>
</span><span class='line'>            <span class="n">e</span><span class="p">.</span><span class="n">Page</span><span class="p">.</span><span class="n">ClientScript</span><span class="p">.</span><span class="n">RegisterClientScriptBlock</span><span class="p">(</span><span class="n">GetType</span><span class="p">(),</span> <span class="s">&quot;WrapConfirmations&quot;</span><span class="p">,</span> <span class="n">confirmWrapper</span><span class="p">);</span>
</span><span class='line'>        <span class="p">}</span>
</span><span class='line'>
</span><span class='line'>        <span class="n">protected</span> <span class="n">override</span> <span class="kt">void</span> <span class="n">OnDeactivated</span><span class="p">()</span>
</span><span class='line'>        <span class="p">{</span>
</span><span class='line'>            <span class="k">if</span> <span class="p">(</span><span class="n">IsChrome</span> <span class="o">||</span> <span class="n">IsFirefox</span><span class="p">)</span>
</span><span class='line'>            <span class="p">{</span>
</span><span class='line'>                <span class="n">WebWindow</span> <span class="n">window</span> <span class="o">=</span> <span class="n">Frame</span> <span class="n">as</span> <span class="n">WebWindow</span><span class="p">;</span>
</span><span class='line'>                <span class="k">if</span> <span class="p">(</span><span class="n">window</span> <span class="o">!=</span> <span class="n">null</span><span class="p">)</span>
</span><span class='line'>                <span class="p">{</span>
</span><span class='line'>                    <span class="n">window</span><span class="p">.</span><span class="n">CustomRegisterTemplateDependentScripts</span> <span class="o">-=</span> <span class="n">window_CustomRegisterTemplateDependentScripts</span><span class="p">;</span>
</span><span class='line'>                <span class="p">}</span>
</span><span class='line'>                <span class="n">base</span><span class="p">.</span><span class="n">OnDeactivated</span><span class="p">();</span>
</span><span class='line'>            <span class="p">}</span>
</span><span class='line'>        <span class="p">}</span>
</span><span class='line'>    <span class="p">}</span>
</span><span class='line'><span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>


<p>The controller works by timing the milliseconds to close the confirmation window. If it is less than 350 milliseconds we can assume the confirmation window never opened owing to the checkbox. In this scenario, it returns true (confirm) rather than false (cancel) in order for XAF to function correctly.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[A basic Chrome extension - analyze your chess.com games on lichess.org]]></title>
    <link href="http://ZeroSharp.github.com/a-basic-chrome-extension-analyze-your-chess-dot-com-games-on-lichess-dot-org/"/>
    <updated>2016-03-04T17:41:00+00:00</updated>
    <id>http://ZeroSharp.github.com/a-basic-chrome-extension-analyze-your-chess-dot-com-games-on-lichess-dot-org</id>
    <content type="html"><![CDATA[<p>I&#8217;ve been trying to get better at chess by playing on <a href="http://www.chess.com">chess.com</a>. I often analyse my games with the help of a computer to see where I made mistakes. My favourite way of doing this is to make use of <a href="http://lichess.org">Lichess.org</a>&#8217;s import functionality. The latest version of chess.com has greatly improved its own post game analysis, but I still much prefer Lichess&#8217;s. So I would often download the finished game in pgn and upload it to Lichess.</p>

<p>Somewhere along the way I came across a Chrome extension written by Allan Rempel which would do this in one step. Unfortunately it stopped working when chess.com upgraded its site and Allan does not seem to be maintaining it any longer. I decided to jump in and try to fix it and maybe add a couple of features myself.</p>

<h2>The extension</h2>

<p>When a chess.com game is finished, you can click on a little knight icon and jump straight to the analysis of the game in Lichess.</p>

<p><img src="http://ZeroSharp.github.com/images/blog/chrome-extension-chessCom.png"></p>

<p>It takes a few seconds to process but then you can see all your mistakes and blunders.</p>

<p><img src="http://ZeroSharp.github.com/images/blog/chrome-extension-lichessOrg.png"></p>

<p>You can play through the game and experiment with different variations. Chess.com&#8217;s new v3 has greatly improved its own post-game analysis but it still lacks many of the features of the Lichess one.</p>

<p>Try it out! The extension is available <a href="https://chrome.google.com/webstore/detail/chesscom-v3-analysis/bhjlkimpkkgkmfjlcfngmakenalgleap">here</a>.</p>

<h2>How to modify an existing extension</h2>

<p>First thing was to find the code of the existing broken extension. A bit of googling lead me to:</p>

<pre><code>$ cd ~/Library/Application\ Support/Google/Chrome/Default/Extensions/
$ ls

total 0
drwx------+ 30 ra  staff  1020 29 Feb 20:39 .
drwx------+ 66 ra  staff  2244 29 Feb 20:56 ..
drwx------+  2 ra  staff    68 29 Feb 20:39 Temp
drwx------+  3 ra  staff   102 14 Sep  2012 allibancfngcpjmjnnboebggipbaalhn
drwx------+  3 ra  staff   102 28 Mar  2013 anfemphbgknehemmbbajjcmakfijiohp
drwx------+  3 ra  staff   102 25 Oct 08:15 apdfllckaahabafndbhieahigkjlhalf
drwx------+  3 ra  staff   102  5 Mar  2015 bepbmhgboaologfdajaanbcjmnhjmhfn
drwx------+  3 ra  staff   102  5 Jun  2014 bfbameneiokkgbdmiekhjnmfkcnldhhm
drwx------+  3 ra  staff   102 22 Feb 20:09 bhjlkimpkkgkmfjlcfngmakenalgleap
drwx------+  3 ra  staff   102 24 Sep 20:33 blpcfgokakmgnkcojhhkbfbldkacnbeo
drwx------+  3 ra  staff   102 29 Jul  2013 bmihblnpomgpjkfddepdpdafhhepdbek
drwx------+  3 ra  staff   102 13 Sep  2012 boeajhmfdjldchidhphikilcgdacljfm
... etc.
</code></pre>

<p>Each extension is in a not very helpfully named folder. If you open <code>chrome://extensions/</code>, you can find the id of any installed extension and work out which directory corresponds to which extension.</p>

<p>So then I dug around in the folder and found <code>ext/background.js</code> where the bulk of the code lies. There is also a <code>manifest.json</code> file which is specifies various parameters such as what permissions are required and which websites will be affected by the extension. I copied all the important files into a development folder.</p>

<h2>Loading the extension from the development folder.</h2>

<ul>
<li>Navigate to chrome://extensions</li>
<li>Expand the developer dropdown menu and click &#8220;Load Unpacked Extension&#8221;</li>
<li>Navigate to development folder</li>
</ul>


<p>Assuming there are no errors, the extension should load into your browser. Don&#8217;t forget to disable any conflicting versions you&#8217;ve installed from the Chrome Web Store.</p>

<p><img src="http://ZeroSharp.github.com/images/blog/chrome-extension-load.png"></p>

<p>I used the Chrome&#8217;s built-in Developer Tools and peppered the code with <code>console.log()</code> to explore how it worked. There are plenty of good <a href="https://developer.chrome.com/extensions/tut_debugging">resources</a> on the Chrome developer site. I managed to fix the broken parts and added support for analysis from chess.com&#8217;s game archive. Then I posted the link on <a href="https://redd.it/47cdew">reddit/r/chess</a>.</p>

<p>The source code for the extension is on <a href="https://github.com/ZeroSharp/Chess.com_Analysis_Chrome_extension">GitHub</a>.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Serverless Framework Part 5: Pulling in a node package]]></title>
    <link href="http://ZeroSharp.github.com/serverless-framework-part-5-pulling-in-a-node-package/"/>
    <updated>2016-02-09T11:31:00+00:00</updated>
    <id>http://ZeroSharp.github.com/serverless-framework-part-5-pulling-in-a-node-package</id>
    <content type="html"><![CDATA[<p>This is the final part of an ongoing series about the <a href="https://github.com/serverless/serverless">Serverless framework</a>.</p>

<p>In the previous posts, the <code>PasswordGenerator</code> always returned &#8216;Password&#8217;. Instead each date should corresponds to a new unique password. We&#8217;ll make use of the <a href="https://www.npmjs.com/package/crypto-js">Crypto-js</a> node package and we&#8217;ll see that the AWS lambda copes just fine.</p>

<h3>Installing a node package</h3>

<p>Pull in the crypto-js package into the serverless component.</p>

<pre><code>$ cd nodejscomponent/
$ npm install crypto-js --save
crypto-js@3.1.6 node_modules/crypto-js
</code></pre>

<p>Now we need the typescript definitions. Watch out there are two different TypeScript typings called <em>cryptojs</em> and <em>crypto-js</em>. The first one is more complete.</p>

<pre><code>$ typings install cryptojs --ambient --save
? Found cryptojs typings for DefinitelyTyped. Continue? Yes
Installing cryptojs@~3.1.2 (DefinitelyTyped)...

cryptojs
└── (No dependencies)
</code></pre>

<p>I&#8217;m not sure why, but there&#8217;s no <code>export</code> in the typings file for <em>cryptojs</em>. Add the following to the bottom of the <em>cryptojs.d.ts</em> file.</p>

<figure class='code'><figcaption><span>nodejscomponent/typings/main/ambient/cryptojs.d.ts </span></figcaption>
 <div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
</pre></td><td class='code'><pre><code class='javascript'><span class='line'>  <span class="p">...</span>
</span><span class='line'><span class="nx">declare</span> <span class="nx">module</span> <span class="s2">&quot;crypto-js&quot;</span> <span class="p">{</span>
</span><span class='line'>    <span class="kr">export</span> <span class="o">=</span> <span class="nx">CryptoJS</span><span class="p">;</span>
</span><span class='line'><span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>


<h3>Improved PasswordGenerator</h3>

<figure class='code'><figcaption><span>nodejscomponent/src/passwordOfTheDay.ts </span></figcaption>
 <div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
<span class='line-number'>17</span>
<span class='line-number'>18</span>
<span class='line-number'>19</span>
<span class='line-number'>20</span>
<span class='line-number'>21</span>
<span class='line-number'>22</span>
<span class='line-number'>23</span>
<span class='line-number'>24</span>
<span class='line-number'>25</span>
<span class='line-number'>26</span>
<span class='line-number'>27</span>
<span class='line-number'>28</span>
<span class='line-number'>29</span>
<span class='line-number'>30</span>
<span class='line-number'>31</span>
<span class='line-number'>32</span>
<span class='line-number'>33</span>
<span class='line-number'>34</span>
<span class='line-number'>35</span>
<span class='line-number'>36</span>
<span class='line-number'>37</span>
</pre></td><td class='code'><pre><code class='javascript'><span class='line'><span class="c1">/// &lt;reference path=&quot;../typings/main.d.ts&quot; /&gt;</span>
</span><span class='line'><span class="kr">import</span> <span class="nx">CryptoJS</span> <span class="o">=</span> <span class="nx">require</span><span class="p">(</span><span class="s2">&quot;crypto-js&quot;</span><span class="p">);</span>
</span><span class='line'>
</span><span class='line'><span class="kr">export</span> <span class="kd">function</span> <span class="nx">checkPotd</span><span class="p">(</span><span class="nx">password</span> <span class="o">:</span> <span class="nx">string</span><span class="p">)</span> <span class="o">:</span> <span class="kr">boolean</span>
</span><span class='line'><span class="p">{</span>
</span><span class='line'>    <span class="k">return</span> <span class="k">new</span> <span class="nx">PasswordGenerator</span><span class="p">().</span><span class="nx">check</span><span class="p">(</span><span class="nx">password</span><span class="p">);</span>
</span><span class='line'><span class="p">}</span>
</span><span class='line'>
</span><span class='line'><span class="kr">export</span> <span class="kr">class</span> <span class="nx">PasswordGenerator</span>
</span><span class='line'><span class="p">{</span>
</span><span class='line'>  <span class="nx">generate</span><span class="p">(</span><span class="nx">date</span><span class="o">:</span> <span class="nb">Date</span><span class="p">)</span> <span class="o">:</span> <span class="nx">string</span>
</span><span class='line'>  <span class="p">{</span>
</span><span class='line'>        <span class="c1">// Get the current date as a YYYYMMDD string</span>
</span><span class='line'>        <span class="kd">var</span> <span class="nx">yyyy</span> <span class="o">=</span> <span class="nx">date</span><span class="p">.</span><span class="nx">getFullYear</span><span class="p">().</span><span class="nx">toString</span><span class="p">();</span>
</span><span class='line'>        <span class="kd">var</span> <span class="nx">mm</span> <span class="o">=</span> <span class="p">(</span><span class="nx">date</span><span class="p">.</span><span class="nx">getMonth</span><span class="p">()</span><span class="o">+</span><span class="mi">1</span><span class="p">).</span><span class="nx">toString</span><span class="p">();</span> <span class="c1">// getMonth() is zero-based</span>
</span><span class='line'>        <span class="kd">var</span> <span class="nx">dd</span>  <span class="o">=</span> <span class="nx">date</span><span class="p">.</span><span class="nx">getDate</span><span class="p">().</span><span class="nx">toString</span><span class="p">();</span>
</span><span class='line'>        <span class="kd">var</span> <span class="nx">plain</span> <span class="o">=</span> <span class="err">`</span><span class="nx">$</span><span class="p">{</span><span class="nx">yyyy</span><span class="p">}</span><span class="nx">$</span><span class="p">{</span><span class="nx">mm</span><span class="p">}</span><span class="nx">$</span><span class="p">{</span><span class="nx">dd</span><span class="p">}</span><span class="err">`</span><span class="p">;</span>
</span><span class='line'>
</span><span class='line'>        <span class="c1">// Using AES CTR with 32 byte key and iv ensures the encrypted string is not too long</span>
</span><span class='line'>        <span class="c1">// See http://stackoverflow.com/a/13298019/1077279</span>
</span><span class='line'>
</span><span class='line'>        <span class="kd">var</span> <span class="nx">key</span> <span class="o">=</span> <span class="nx">CryptoJS</span><span class="p">.</span><span class="nx">enc</span><span class="p">.</span><span class="nx">Hex</span><span class="p">.</span><span class="nx">parse</span><span class="p">(</span><span class="s1">&#39;108c786594543687891374723e809ec5e475a8361f7ad82df04e91ba2c139321&#39;</span><span class="p">);</span>
</span><span class='line'>        <span class="c1">// Use a different initialization vector each time by using the date as part of the vector</span>
</span><span class='line'>        <span class="kd">var</span> <span class="nx">iv</span>  <span class="o">=</span> <span class="nx">CryptoJS</span><span class="p">.</span><span class="nx">enc</span><span class="p">.</span><span class="nx">Hex</span><span class="p">.</span><span class="nx">parse</span><span class="p">(</span><span class="nx">plain</span> <span class="o">+</span> <span class="s1">&#39;3a8fe4440be1e113a271574f379d70a76c3477aaff036d1e83fcd4b9&#39;</span><span class="p">);</span>
</span><span class='line'>        <span class="kd">var</span> <span class="nx">options</span> <span class="o">=</span> <span class="p">{</span> <span class="nx">mode</span><span class="o">:</span> <span class="nx">CryptoJS</span><span class="p">.</span><span class="nx">mode</span><span class="p">.</span><span class="nx">CTR</span><span class="p">,</span> <span class="nx">padding</span><span class="o">:</span> <span class="nx">CryptoJS</span><span class="p">.</span><span class="nx">pad</span><span class="p">.</span><span class="nx">NoPadding</span><span class="p">,</span> <span class="nx">iv</span><span class="o">:</span> <span class="nx">iv</span> <span class="p">};</span>
</span><span class='line'>
</span><span class='line'>        <span class="kd">var</span> <span class="nx">encrypted</span> <span class="o">=</span> <span class="nx">CryptoJS</span><span class="p">.</span><span class="nx">AES</span><span class="p">.</span><span class="nx">encrypt</span><span class="p">(</span><span class="nx">plain</span><span class="p">,</span> <span class="nx">key</span><span class="p">,</span> <span class="nx">options</span><span class="p">);</span>
</span><span class='line'>
</span><span class='line'>      <span class="k">return</span> <span class="nx">encrypted</span><span class="p">.</span><span class="nx">ciphertext</span><span class="p">.</span><span class="nx">toString</span><span class="p">();</span>
</span><span class='line'>  <span class="p">}</span>    
</span><span class='line'>  
</span><span class='line'>  <span class="nx">check</span><span class="p">(</span><span class="nx">password</span> <span class="o">:</span> <span class="nx">string</span><span class="p">)</span> <span class="o">:</span> <span class="kr">boolean</span>
</span><span class='line'>  <span class="p">{</span>
</span><span class='line'>        <span class="c1">// check the value matches today&#39;s password of the day</span>
</span><span class='line'>      <span class="k">return</span> <span class="nx">password</span> <span class="o">==</span> <span class="k">this</span><span class="p">.</span><span class="nx">generate</span><span class="p">(</span><span class="k">new</span> <span class="nb">Date</span><span class="p">());</span>
</span><span class='line'>  <span class="p">}</span>
</span><span class='line'><span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>


<h3>Run the tests</h3>

<p>We expect the tests to fail now since we are no longer returning the same password.</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
<span class='line-number'>17</span>
<span class='line-number'>18</span>
<span class='line-number'>19</span>
<span class='line-number'>20</span>
<span class='line-number'>21</span>
<span class='line-number'>22</span>
<span class='line-number'>23</span>
<span class='line-number'>24</span>
<span class='line-number'>25</span>
<span class='line-number'>26</span>
<span class='line-number'>27</span>
</pre></td><td class='code'><pre><code class='sh'><span class='line'><span class="nv">$ </span>npm <span class="nb">test</span>
</span><span class='line'>&gt; @0.0.1 pretest /Users/ra/Projects/Coprocess/serverlessPotd/nodejscomponent
</span><span class='line'>&gt; tsc
</span><span class='line'>
</span><span class='line'>&gt; @0.0.1 <span class="nb">test</span> /Users/ra/Projects/Coprocess/serverlessPotd/nodejscomponent
</span><span class='line'>&gt; mocha ./lib/test
</span><span class='line'>
</span><span class='line'>  Generator
</span><span class='line'>    <span class="c">#generate</span>
</span><span class='line'>      1<span class="o">)</span> should generate the password
</span><span class='line'>    <span class="c">#check</span>
</span><span class='line'>      ✓ should <span class="k">return </span><span class="nb">false </span>when the password is incorrect
</span><span class='line'>    <span class="c">#check</span>
</span><span class='line'>      2<span class="o">)</span> should <span class="k">return </span><span class="nb">true </span>when the password is correct
</span><span class='line'>
</span><span class='line'>  1 passing <span class="o">(</span>16ms<span class="o">)</span>
</span><span class='line'>  2 failing
</span><span class='line'>
</span><span class='line'>  1<span class="o">)</span> Generator <span class="c">#generate should generate the password:</span>
</span><span class='line'>     Error: Expected <span class="s1">&#39;Password&#39;</span> but was bb4bde4d76b055
</span><span class='line'>      at Context.&lt;anonymous&gt; <span class="o">(</span>lib/test/passwordOfTheDayTest.js:12:23<span class="o">)</span>
</span><span class='line'>
</span><span class='line'>  2<span class="o">)</span> Generator <span class="c">#check should return true when the password is correct:</span>
</span><span class='line'>     Error: Expected <span class="s1">&#39;true&#39;</span> but was <span class="nb">false</span>
</span><span class='line'><span class="nb">      </span>at Context.&lt;anonymous&gt; <span class="o">(</span>lib/test/passwordOfTheDayTest.js:28:23<span class="o">)</span>
</span><span class='line'>
</span><span class='line'>npm ERR! Test failed.  See above <span class="k">for </span>more details.
</span></code></pre></td></tr></table></div></figure>


<h3>Update and improve the tests</h3>

<p>It&#8217;s getting a little more complicated so let&#8217;s pull in <a href="http://chaijs.com/">chai</a> which is a pretty assertions library.</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
</pre></td><td class='code'><pre><code class='sh'><span class='line'><span class="nv">$ </span>npm install chai --save-dev
</span><span class='line'>chai@3.5.0 node_modules/chai
</span><span class='line'>├── assertion-error@1.0.1
</span><span class='line'>├── <span class="nb">type</span>-detect@1.0.0
</span><span class='line'>└── deep-eql@0.1.3 <span class="o">(</span><span class="nb">type</span>-detect@0.1.1<span class="o">)</span>
</span></code></pre></td></tr></table></div></figure>


<p>And the Typescript definitions for chai.</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
</pre></td><td class='code'><pre><code class='sh'><span class='line'><span class="nv">$ </span>typings install chai --save --ambient
</span><span class='line'>? Found chai typings <span class="k">for </span>DefinitelyTyped. Continue? Yes
</span><span class='line'>Installing chai@~3.4.0 <span class="o">(</span>DefinitelyTyped<span class="o">)</span>...
</span><span class='line'>
</span><span class='line'>chai
</span><span class='line'>└── <span class="o">(</span>No dependencies<span class="o">)</span>
</span></code></pre></td></tr></table></div></figure>


<p>Now let&#8217;s flesh out the tests for the <code>PasswordGenerator</code> class.</p>

<figure class='code'><figcaption><span>nodejscomponent/src/test/passwordOfTheDayTest.ts </span></figcaption>
 <div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
<span class='line-number'>17</span>
<span class='line-number'>18</span>
<span class='line-number'>19</span>
<span class='line-number'>20</span>
<span class='line-number'>21</span>
<span class='line-number'>22</span>
<span class='line-number'>23</span>
<span class='line-number'>24</span>
<span class='line-number'>25</span>
<span class='line-number'>26</span>
<span class='line-number'>27</span>
<span class='line-number'>28</span>
<span class='line-number'>29</span>
<span class='line-number'>30</span>
<span class='line-number'>31</span>
<span class='line-number'>32</span>
<span class='line-number'>33</span>
<span class='line-number'>34</span>
<span class='line-number'>35</span>
<span class='line-number'>36</span>
<span class='line-number'>37</span>
<span class='line-number'>38</span>
<span class='line-number'>39</span>
<span class='line-number'>40</span>
<span class='line-number'>41</span>
<span class='line-number'>42</span>
<span class='line-number'>43</span>
<span class='line-number'>44</span>
<span class='line-number'>45</span>
<span class='line-number'>46</span>
<span class='line-number'>47</span>
<span class='line-number'>48</span>
<span class='line-number'>49</span>
<span class='line-number'>50</span>
<span class='line-number'>51</span>
<span class='line-number'>52</span>
<span class='line-number'>53</span>
<span class='line-number'>54</span>
<span class='line-number'>55</span>
<span class='line-number'>56</span>
<span class='line-number'>57</span>
<span class='line-number'>58</span>
</pre></td><td class='code'><pre><code class='javascript'><span class='line'><span class="c1">/// &lt;reference path=&quot;../../typings/main.d.ts&quot; /&gt;</span>
</span><span class='line'><span class="kr">import</span> <span class="nx">PasswordOfTheDay</span> <span class="o">=</span> <span class="nx">require</span><span class="p">(</span><span class="s2">&quot;../passwordOfTheDay&quot;</span><span class="p">);</span>
</span><span class='line'><span class="kr">import</span> <span class="nx">Chai</span> <span class="o">=</span> <span class="nx">require</span><span class="p">(</span><span class="s2">&quot;chai&quot;</span><span class="p">);</span>
</span><span class='line'>
</span><span class='line'><span class="c1">// Tell chai that we&#39;ll be using the &quot;should&quot; style assertions.</span>
</span><span class='line'><span class="nx">Chai</span><span class="p">.</span><span class="nx">should</span><span class="p">();</span>
</span><span class='line'>
</span><span class='line'><span class="nx">describe</span><span class="p">(</span><span class="s2">&quot;Generator&quot;</span><span class="p">,</span> <span class="p">()</span> <span class="o">=&gt;</span> <span class="p">{</span>
</span><span class='line'>    <span class="kd">var</span> <span class="nx">subject</span> <span class="o">:</span> <span class="nx">PasswordOfTheDay</span><span class="p">.</span><span class="nx">PasswordGenerator</span><span class="p">;</span>
</span><span class='line'>
</span><span class='line'>    <span class="nx">beforeEach</span><span class="p">(</span><span class="kd">function</span> <span class="p">()</span> <span class="p">{</span>
</span><span class='line'>        <span class="nx">subject</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">PasswordOfTheDay</span><span class="p">.</span><span class="nx">PasswordGenerator</span><span class="p">();</span>
</span><span class='line'>    <span class="p">});</span>
</span><span class='line'>
</span><span class='line'>    <span class="nx">describe</span><span class="p">(</span><span class="s2">&quot;#generate&quot;</span><span class="p">,</span> <span class="p">()</span> <span class="o">=&gt;</span> <span class="p">{</span>
</span><span class='line'>        <span class="nx">it</span><span class="p">(</span><span class="s2">&quot;should generate the password when the date is 24th July 2010&quot;</span><span class="p">,</span> <span class="p">()</span> <span class="o">=&gt;</span> <span class="p">{</span>
</span><span class='line'>            <span class="kd">var</span> <span class="nx">date</span> <span class="o">:</span> <span class="nb">Date</span> <span class="o">=</span> <span class="k">new</span> <span class="nb">Date</span><span class="p">(</span><span class="mi">2010</span><span class="p">,</span> <span class="mi">6</span><span class="p">,</span> <span class="mi">24</span><span class="p">);</span>
</span><span class='line'>            <span class="kd">var</span> <span class="nx">password</span> <span class="o">:</span> <span class="nx">string</span> <span class="o">=</span> <span class="nx">subject</span><span class="p">.</span><span class="nx">generate</span><span class="p">(</span><span class="nx">date</span><span class="p">);</span>
</span><span class='line'>
</span><span class='line'>            <span class="nx">password</span><span class="p">.</span><span class="nx">should</span><span class="p">.</span><span class="nx">equal</span><span class="p">(</span><span class="s2">&quot;92ab1ff89bf9af&quot;</span><span class="p">);</span>
</span><span class='line'>        <span class="p">});</span>
</span><span class='line'>    <span class="p">});</span>
</span><span class='line'>
</span><span class='line'>    <span class="nx">describe</span><span class="p">(</span><span class="s2">&quot;#generate&quot;</span><span class="p">,</span> <span class="p">()</span> <span class="o">=&gt;</span> <span class="p">{</span>
</span><span class='line'>        <span class="nx">it</span><span class="p">(</span><span class="s2">&quot;should generate a different password when the date is 25th July 2010&quot;</span><span class="p">,</span> <span class="p">()</span> <span class="o">=&gt;</span> <span class="p">{</span>
</span><span class='line'>            <span class="kd">var</span> <span class="nx">date</span> <span class="o">:</span> <span class="nb">Date</span> <span class="o">=</span> <span class="k">new</span> <span class="nb">Date</span><span class="p">(</span><span class="mi">2010</span><span class="p">,</span> <span class="mi">6</span><span class="p">,</span> <span class="mi">25</span><span class="p">);</span>
</span><span class='line'>            <span class="kd">var</span> <span class="nx">password</span> <span class="o">:</span> <span class="nx">string</span> <span class="o">=</span> <span class="nx">subject</span><span class="p">.</span><span class="nx">generate</span><span class="p">(</span><span class="nx">date</span><span class="p">);</span>
</span><span class='line'>
</span><span class='line'>            <span class="nx">password</span><span class="p">.</span><span class="nx">should</span><span class="p">.</span><span class="nx">equal</span><span class="p">(</span><span class="s2">&quot;26a394b21800f1&quot;</span><span class="p">);</span>
</span><span class='line'>        <span class="p">});</span>
</span><span class='line'>    <span class="p">});</span>
</span><span class='line'>    <span class="nx">describe</span><span class="p">(</span><span class="s2">&quot;#check&quot;</span><span class="p">,</span> <span class="p">()</span> <span class="o">=&gt;</span> <span class="p">{</span>
</span><span class='line'>        <span class="nx">it</span><span class="p">(</span><span class="s2">&quot;should return false when the password is incorrect&quot;</span><span class="p">,</span> <span class="p">()</span> <span class="o">=&gt;</span> <span class="p">{</span>
</span><span class='line'>            <span class="kd">var</span> <span class="nx">password</span> <span class="o">:</span> <span class="nx">string</span> <span class="o">=</span> <span class="s2">&quot;garbage&quot;</span><span class="p">;</span>
</span><span class='line'>            <span class="kd">var</span> <span class="nx">result</span> <span class="o">:</span> <span class="kr">boolean</span> <span class="o">=</span> <span class="nx">subject</span><span class="p">.</span><span class="nx">check</span><span class="p">(</span><span class="nx">password</span><span class="p">);</span>
</span><span class='line'>
</span><span class='line'>            <span class="nx">result</span><span class="p">.</span><span class="nx">should</span><span class="p">.</span><span class="nx">be</span><span class="p">.</span><span class="kc">false</span><span class="p">;</span>
</span><span class='line'>        <span class="p">});</span>
</span><span class='line'>    <span class="p">});</span>
</span><span class='line'>
</span><span class='line'>    <span class="nx">describe</span><span class="p">(</span><span class="s2">&quot;#check&quot;</span><span class="p">,</span> <span class="p">()</span> <span class="o">=&gt;</span> <span class="p">{</span>
</span><span class='line'>        <span class="nx">it</span><span class="p">(</span><span class="s2">&quot;should return false when the password is null&quot;</span><span class="p">,</span> <span class="p">()</span> <span class="o">=&gt;</span> <span class="p">{</span>
</span><span class='line'>            <span class="kd">var</span> <span class="nx">password</span> <span class="o">:</span> <span class="nx">string</span> <span class="o">=</span> <span class="kc">null</span><span class="p">;</span>
</span><span class='line'>            <span class="kd">var</span> <span class="nx">result</span> <span class="o">:</span> <span class="kr">boolean</span> <span class="o">=</span> <span class="nx">subject</span><span class="p">.</span><span class="nx">check</span><span class="p">(</span><span class="nx">password</span><span class="p">);</span>
</span><span class='line'>
</span><span class='line'>            <span class="nx">result</span><span class="p">.</span><span class="nx">should</span><span class="p">.</span><span class="nx">be</span><span class="p">.</span><span class="kc">false</span><span class="p">;</span>
</span><span class='line'>        <span class="p">});</span>
</span><span class='line'>    <span class="p">});</span>
</span><span class='line'>
</span><span class='line'>    <span class="nx">describe</span><span class="p">(</span><span class="s2">&quot;#check&quot;</span><span class="p">,</span> <span class="p">()</span> <span class="o">=&gt;</span> <span class="p">{</span>
</span><span class='line'>        <span class="nx">it</span><span class="p">(</span><span class="s2">&quot;should return true when the password is correct&quot;</span><span class="p">,</span> <span class="p">()</span> <span class="o">=&gt;</span> <span class="p">{</span>
</span><span class='line'>            <span class="kd">var</span> <span class="nx">password</span> <span class="o">:</span> <span class="nx">string</span> <span class="o">=</span> <span class="nx">subject</span><span class="p">.</span><span class="nx">generate</span><span class="p">(</span><span class="k">new</span> <span class="nb">Date</span><span class="p">());</span>
</span><span class='line'>            <span class="kd">var</span> <span class="nx">result</span> <span class="o">:</span> <span class="kr">boolean</span> <span class="o">=</span> <span class="nx">subject</span><span class="p">.</span><span class="nx">check</span><span class="p">(</span><span class="nx">password</span><span class="p">);</span>
</span><span class='line'>
</span><span class='line'>            <span class="nx">result</span><span class="p">.</span><span class="nx">should</span><span class="p">.</span><span class="nx">be</span><span class="p">.</span><span class="kc">true</span><span class="p">;</span>
</span><span class='line'>        <span class="p">});</span>
</span><span class='line'>    <span class="p">});</span>
</span><span class='line'><span class="p">});</span>
</span></code></pre></td></tr></table></div></figure>


<p>Run our tests:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
<span class='line-number'>17</span>
<span class='line-number'>18</span>
<span class='line-number'>19</span>
<span class='line-number'>20</span>
<span class='line-number'>21</span>
</pre></td><td class='code'><pre><code class='sh'><span class='line'><span class="nv">$ </span>npm <span class="nb">test</span>
</span><span class='line'>&gt; @0.0.1 pretest /Users/ra/Projects/Coprocess/serverlessPotd/nodejscomponent
</span><span class='line'>&gt; tsc
</span><span class='line'>
</span><span class='line'>&gt; @0.0.1 <span class="nb">test</span> /Users/ra/Projects/Coprocess/serverlessPotd/nodejscomponent
</span><span class='line'>&gt; mocha ./lib/test
</span><span class='line'>
</span><span class='line'>  Generator
</span><span class='line'>    <span class="c">#generate</span>
</span><span class='line'>      ✓ should generate the password when the date is 24th July 2010
</span><span class='line'>    <span class="c">#generate</span>
</span><span class='line'>      ✓ should generate a different password when the date is 25th July 2010
</span><span class='line'>    <span class="c">#check</span>
</span><span class='line'>      ✓ should <span class="k">return </span><span class="nb">false </span>when the password is incorrect
</span><span class='line'>    <span class="c">#check</span>
</span><span class='line'>      ✓ should <span class="k">return </span><span class="nb">false </span>when the password is null
</span><span class='line'>    <span class="c">#check</span>
</span><span class='line'>      ✓ should <span class="k">return </span><span class="nb">true </span>when the password is correct
</span><span class='line'>
</span><span class='line'>
</span><span class='line'>  5 passing <span class="o">(</span>20ms<span class="o">)</span>
</span></code></pre></td></tr></table></div></figure>


<h3>Deploy</h3>

<pre><code>$ serverless dash deploy
</code></pre>

<p>Now when we visit the endpoint with the correct password for today&#8217;s date which happens to be <em>89366e6199f3</em>.</p>

<pre><code>https://...amazonaws.com/dev/potd/check?password=89366e6199f3
</code></pre>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
</pre></td><td class='code'><pre><code class='json'><span class='line'><span class="p">{</span>
</span><span class='line'>    <span class="err">message:</span> <span class="err">true</span>
</span><span class='line'><span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>


<p>Mission accomplished! Notice that using a node package did not require any special steps on the AWS side. In fact we have not had to login to AWS since the very beginning when we created an IAM user for the project. And yet we&#8217;ve managed to build and deploy a cheap and scalable cloud-based service.</p>

<p>The <a href="https://github.com/ZeroSharp/ServerlessPotd">source code</a> is on GitHub. Note the default <em>.gitignore</em> file skips the <em>admin.env</em> file which contains the (sensitive) AWS keys in it so don&#8217;t forget to add your own.</p>

<p>That wraps up my series on building a small, but real-world Serverless application. In a future post, I&#8217;d like to look at providing a secured &#8216;generate&#8217; service to allow authorized users to get today&#8217;s password. Stay tuned.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Serverless Framework - Part 4: Connecting the parts]]></title>
    <link href="http://ZeroSharp.github.com/serverless-framework-part-4-connecting-the-parts/"/>
    <updated>2016-02-01T09:44:00+00:00</updated>
    <id>http://ZeroSharp.github.com/serverless-framework-part-4-connecting-the-parts</id>
    <content type="html"><![CDATA[<p>This is part of an ongoing series about the <a href="https://github.com/serverless/serverless">Serverless framework</a>: <a href="http://ZeroSharp.github.com/serverless-framework-part-1-up-and-running/">Part 1</a>, <a href="http://ZeroSharp.github.com/serverless-framework-part-2-typescript-and-mocha/">part 2</a>, <a href="http://ZeroSharp.github.com/serverless-framework-part-3-the-guts/">part 3</a>.</p>

<h2>New version 0.3.1</h2>

<p><span class="fluo">Edit: since the original version of this post, a new version 0.3.1 of Serverless was released. I have updated the tutorial below to reflect the newer version. Also, <a href="https://github.com/DefinitelyTyped/tsd/issues/269">TSD has been deprecated</a> in favour of <a href="https://www.npmjs.com/package/typings">Typings</a> so I&#8217;ve updated to use Typings instead. </span>
All parts have been updated for the latest version of the framework 0.3.1.</p>

<h2>The Password of the Day Generator class</h2>

<p>First up we need a class to generate and check the password of the day. For the moment, let&#8217;s pretend the password of the day is always the string <em>&#8220;Password&#8221;</em>. Put the following typescript class in <em>nodejscomponent/src</em>.</p>

<figure class='code'><figcaption><span>nodejscomponent/src/passwordOfTheDay.ts </span></figcaption>
 <div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
<span class='line-number'>17</span>
<span class='line-number'>18</span>
<span class='line-number'>19</span>
</pre></td><td class='code'><pre><code class='javascript'><span class='line'><span class="kr">export</span> <span class="kd">function</span> <span class="nx">checkPotd</span><span class="p">(</span><span class="nx">password</span> <span class="o">:</span> <span class="nx">string</span><span class="p">)</span> <span class="o">:</span> <span class="kr">boolean</span>
</span><span class='line'><span class="p">{</span>
</span><span class='line'>    <span class="k">return</span> <span class="k">new</span> <span class="nx">PasswordGenerator</span><span class="p">().</span><span class="nx">check</span><span class="p">(</span><span class="nx">password</span><span class="p">);</span>
</span><span class='line'><span class="p">}</span>
</span><span class='line'>
</span><span class='line'><span class="kr">export</span> <span class="kr">class</span> <span class="nx">PasswordGenerator</span>
</span><span class='line'><span class="p">{</span>
</span><span class='line'>  <span class="nx">generate</span><span class="p">(</span><span class="nx">date</span><span class="o">:</span> <span class="nb">Date</span><span class="p">)</span> <span class="o">:</span> <span class="nx">string</span>
</span><span class='line'>  <span class="p">{</span>
</span><span class='line'>        <span class="c1">// generate today&#39;s password</span>
</span><span class='line'>      <span class="k">return</span> <span class="s2">&quot;Password&quot;</span><span class="p">;</span>
</span><span class='line'>  <span class="p">}</span>    
</span><span class='line'>  
</span><span class='line'>  <span class="nx">check</span><span class="p">(</span><span class="nx">password</span> <span class="o">:</span> <span class="nx">string</span><span class="p">)</span> <span class="o">:</span> <span class="kr">boolean</span>
</span><span class='line'>  <span class="p">{</span>
</span><span class='line'>        <span class="c1">// check the value matches today&#39;s password of the day</span>
</span><span class='line'>      <span class="k">return</span> <span class="nx">password</span> <span class="o">==</span> <span class="k">this</span><span class="p">.</span><span class="nx">generate</span><span class="p">(</span><span class="k">new</span> <span class="nb">Date</span><span class="p">());</span>
</span><span class='line'>  <span class="p">}</span>
</span><span class='line'><span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>


<p>Now add a mocha test for it.</p>

<figure class='code'><figcaption><span>nodejscomponent/src/test/passwordOfTheDayTest.ts </span></figcaption>
 <div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
<span class='line-number'>17</span>
<span class='line-number'>18</span>
<span class='line-number'>19</span>
<span class='line-number'>20</span>
<span class='line-number'>21</span>
<span class='line-number'>22</span>
<span class='line-number'>23</span>
<span class='line-number'>24</span>
<span class='line-number'>25</span>
<span class='line-number'>26</span>
<span class='line-number'>27</span>
<span class='line-number'>28</span>
<span class='line-number'>29</span>
<span class='line-number'>30</span>
<span class='line-number'>31</span>
<span class='line-number'>32</span>
<span class='line-number'>33</span>
<span class='line-number'>34</span>
<span class='line-number'>35</span>
<span class='line-number'>36</span>
<span class='line-number'>37</span>
<span class='line-number'>38</span>
</pre></td><td class='code'><pre><code class='javascript'><span class='line'><span class="c1">/// &lt;reference path=&quot;../../typings/main.d.ts&quot; /&gt;</span>
</span><span class='line'><span class="kr">import</span> <span class="nx">PasswordOfTheDay</span> <span class="o">=</span> <span class="nx">require</span><span class="p">(</span><span class="s2">&quot;../passwordOfTheDay&quot;</span><span class="p">);</span>
</span><span class='line'>
</span><span class='line'><span class="nx">describe</span><span class="p">(</span><span class="s2">&quot;Generator&quot;</span><span class="p">,</span> <span class="p">()</span> <span class="o">=&gt;</span> <span class="p">{</span>
</span><span class='line'>    <span class="kd">var</span> <span class="nx">subject</span> <span class="o">:</span> <span class="nx">PasswordOfTheDay</span><span class="p">.</span><span class="nx">PasswordGenerator</span><span class="p">;</span>
</span><span class='line'>
</span><span class='line'>    <span class="nx">beforeEach</span><span class="p">(</span><span class="kd">function</span> <span class="p">()</span> <span class="p">{</span>
</span><span class='line'>        <span class="nx">subject</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">PasswordOfTheDay</span><span class="p">.</span><span class="nx">PasswordGenerator</span><span class="p">();</span>
</span><span class='line'>    <span class="p">});</span>
</span><span class='line'>
</span><span class='line'>    <span class="nx">describe</span><span class="p">(</span><span class="s2">&quot;#generate&quot;</span><span class="p">,</span> <span class="p">()</span> <span class="o">=&gt;</span> <span class="p">{</span>
</span><span class='line'>        <span class="nx">it</span><span class="p">(</span><span class="s2">&quot;should generate the password&quot;</span><span class="p">,</span> <span class="p">()</span> <span class="o">=&gt;</span> <span class="p">{</span>
</span><span class='line'>            <span class="kd">var</span> <span class="nx">result</span> <span class="o">:</span> <span class="nx">string</span> <span class="o">=</span> <span class="nx">subject</span><span class="p">.</span><span class="nx">generate</span><span class="p">(</span><span class="k">new</span> <span class="nb">Date</span><span class="p">(</span><span class="mi">2010</span><span class="p">,</span> <span class="mi">6</span><span class="p">,</span> <span class="mi">24</span><span class="p">));</span>
</span><span class='line'>            <span class="k">if</span> <span class="p">(</span><span class="nx">result</span> <span class="o">!==</span> <span class="s2">&quot;Password&quot;</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'>                <span class="k">throw</span> <span class="k">new</span> <span class="nb">Error</span><span class="p">(</span><span class="s2">&quot;Expected &#39;Password&#39; but was &quot;</span> <span class="o">+</span> <span class="nx">result</span><span class="p">);</span>
</span><span class='line'>            <span class="p">}</span>
</span><span class='line'>        <span class="p">});</span>
</span><span class='line'>    <span class="p">});</span>
</span><span class='line'>
</span><span class='line'>    <span class="nx">describe</span><span class="p">(</span><span class="s2">&quot;#check&quot;</span><span class="p">,</span> <span class="p">()</span> <span class="o">=&gt;</span> <span class="p">{</span>
</span><span class='line'>        <span class="nx">it</span><span class="p">(</span><span class="s2">&quot;should return false when the password is incorrect&quot;</span><span class="p">,</span> <span class="p">()</span> <span class="o">=&gt;</span> <span class="p">{</span>
</span><span class='line'>            <span class="kd">var</span> <span class="nx">result</span> <span class="o">:</span> <span class="kr">boolean</span> <span class="o">=</span> <span class="nx">subject</span><span class="p">.</span><span class="nx">check</span><span class="p">(</span><span class="s2">&quot;garbage&quot;</span><span class="p">);</span>
</span><span class='line'>            <span class="k">if</span> <span class="p">(</span><span class="nx">result</span> <span class="o">!==</span> <span class="kc">false</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'>                <span class="k">throw</span> <span class="k">new</span> <span class="nb">Error</span><span class="p">(</span><span class="s2">&quot;Expected &#39;false&#39; but was &quot;</span> <span class="o">+</span> <span class="nx">result</span><span class="p">);</span>
</span><span class='line'>            <span class="p">}</span>
</span><span class='line'>        <span class="p">});</span>
</span><span class='line'>    <span class="p">});</span>
</span><span class='line'>
</span><span class='line'>    <span class="nx">describe</span><span class="p">(</span><span class="s2">&quot;#check&quot;</span><span class="p">,</span> <span class="p">()</span> <span class="o">=&gt;</span> <span class="p">{</span>
</span><span class='line'>        <span class="nx">it</span><span class="p">(</span><span class="s2">&quot;should return true when the password is correct&quot;</span><span class="p">,</span> <span class="p">()</span> <span class="o">=&gt;</span> <span class="p">{</span>
</span><span class='line'>            <span class="kd">var</span> <span class="nx">result</span> <span class="o">:</span> <span class="kr">boolean</span> <span class="o">=</span> <span class="nx">subject</span><span class="p">.</span><span class="nx">check</span><span class="p">(</span><span class="s2">&quot;Password&quot;</span><span class="p">);</span>
</span><span class='line'>            <span class="k">if</span> <span class="p">(</span><span class="nx">result</span> <span class="o">!==</span> <span class="kc">true</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'>                <span class="k">throw</span> <span class="k">new</span> <span class="nb">Error</span><span class="p">(</span><span class="s2">&quot;Expected &#39;true&#39; but was &quot;</span> <span class="o">+</span> <span class="nx">result</span><span class="p">);</span>
</span><span class='line'>            <span class="p">}</span>
</span><span class='line'>        <span class="p">});</span>
</span><span class='line'>    <span class="p">});</span>
</span><span class='line'>
</span><span class='line'><span class="p">});</span>
</span></code></pre></td></tr></table></div></figure>


<p>Now compile everything.</p>

<pre><code>$ cd nodejscomponent
$ tsc
</code></pre>

<p>You will now find that there is a corresponding javascript file in the <em>lib</em> folder</p>

<figure class='code'><figcaption><span>nodejscomponent/src/passwordOfTheDay.js </span></figcaption>
 <div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
<span class='line-number'>17</span>
<span class='line-number'>18</span>
</pre></td><td class='code'><pre><code class='javascript'><span class='line'><span class="kd">function</span> <span class="nx">checkPotd</span><span class="p">(</span><span class="nx">password</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'>    <span class="k">return</span> <span class="k">new</span> <span class="nx">PasswordGenerator</span><span class="p">().</span><span class="nx">check</span><span class="p">(</span><span class="nx">password</span><span class="p">);</span>
</span><span class='line'><span class="p">}</span>
</span><span class='line'><span class="nx">exports</span><span class="p">.</span><span class="nx">checkPotd</span> <span class="o">=</span> <span class="nx">checkPotd</span><span class="p">;</span>
</span><span class='line'><span class="kd">var</span> <span class="nx">PasswordGenerator</span> <span class="o">=</span> <span class="p">(</span><span class="kd">function</span> <span class="p">()</span> <span class="p">{</span>
</span><span class='line'>    <span class="kd">function</span> <span class="nx">PasswordGenerator</span><span class="p">()</span> <span class="p">{</span>
</span><span class='line'>    <span class="p">}</span>
</span><span class='line'>    <span class="nx">PasswordGenerator</span><span class="p">.</span><span class="nx">prototype</span><span class="p">.</span><span class="nx">generate</span> <span class="o">=</span> <span class="kd">function</span> <span class="p">(</span><span class="nx">date</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'>        <span class="c1">// generate today&#39;s password</span>
</span><span class='line'>        <span class="k">return</span> <span class="s2">&quot;Password&quot;</span><span class="p">;</span>
</span><span class='line'>    <span class="p">};</span>
</span><span class='line'>    <span class="nx">PasswordGenerator</span><span class="p">.</span><span class="nx">prototype</span><span class="p">.</span><span class="nx">check</span> <span class="o">=</span> <span class="kd">function</span> <span class="p">(</span><span class="nx">password</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'>        <span class="c1">// check the value matches today&#39;s password of the day</span>
</span><span class='line'>        <span class="k">return</span> <span class="nx">password</span> <span class="o">==</span> <span class="k">this</span><span class="p">.</span><span class="nx">generate</span><span class="p">(</span><span class="k">new</span> <span class="nb">Date</span><span class="p">());</span>
</span><span class='line'>    <span class="p">};</span>
</span><span class='line'>    <span class="k">return</span> <span class="nx">PasswordGenerator</span><span class="p">;</span>
</span><span class='line'><span class="p">})();</span>
</span><span class='line'><span class="nx">exports</span><span class="p">.</span><span class="nx">PasswordGenerator</span> <span class="o">=</span> <span class="nx">PasswordGenerator</span><span class="p">;</span>
</span></code></pre></td></tr></table></div></figure>


<p>And likewise for the mocha test in <em>lib/test</em>. Now to run those tests:</p>

<pre><code>$ npm test

&gt; @0.0.1 pretest /Users/ra/Projects/Coprocess/serverlessPotd/nodejscomponent
&gt; tsc

&gt; @0.0.1 test /Users/ra/Projects/Coprocess/serverlessPotd/nodejscomponent
&gt; mocha ./lib/test

Generator
    #generate
    ✓ should generate the password
    #check
    ✓ should return false when the password is incorrect
    #check
    ✓ should return true when the password is correct

3 passing (10ms)
</code></pre>

<p>Nice. Next, modify the main entry point of the component <em>index.js</em>.</p>

<figure class='code'><figcaption><span>nodejscomponent/lib/index.js </span></figcaption>
 <div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
</pre></td><td class='code'><pre><code class='javascript'><span class='line'><span class="c1">// Dependencies</span>
</span><span class='line'><span class="kd">var</span> <span class="nx">PasswordOfTheDay</span> <span class="o">=</span> <span class="nx">require</span><span class="p">(</span><span class="s1">&#39;./passwordOfTheDay&#39;</span><span class="p">);</span>
</span><span class='line'>
</span><span class='line'><span class="nx">module</span><span class="p">.</span><span class="nx">exports</span><span class="p">.</span><span class="nx">respond</span> <span class="o">=</span> <span class="kd">function</span><span class="p">(</span><span class="nx">event</span><span class="p">,</span> <span class="nx">cb</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'>
</span><span class='line'>  <span class="kd">var</span> <span class="nx">result</span> <span class="o">=</span> <span class="nx">PasswordOfTheDay</span><span class="p">.</span><span class="nx">checkPotd</span><span class="p">(</span><span class="nx">event</span><span class="p">.</span><span class="nx">password</span><span class="p">);</span>
</span><span class='line'>  <span class="kd">var</span> <span class="nx">response</span> <span class="o">=</span> <span class="p">{</span>
</span><span class='line'>    <span class="nx">message</span><span class="o">:</span> <span class="nx">result</span>
</span><span class='line'>  <span class="p">};</span>
</span><span class='line'>
</span><span class='line'>  <span class="k">return</span> <span class="nx">cb</span><span class="p">(</span><span class="kc">null</span><span class="p">,</span> <span class="nx">response</span><span class="p">);</span>
</span><span class='line'><span class="p">};</span>
</span></code></pre></td></tr></table></div></figure>


<p>Notice how we make use of <code>event.password</code> which is the parameter we configured in <a href="http://ZeroSharp.github.com/serverless-framework-part-3-the-guts/">part 3</a> in the <code>s_function.json</code> file.</p>

<p>Let&#8217;s deploy!</p>

<pre><code>$ serverless dash deploy
_______                             __
|   _   .-----.----.--.--.-----.----|  .-----.-----.-----.
|   |___|  -__|   _|  |  |  -__|   _|  |  -__|__ --|__ --|
|____   |_____|__|  \___/|_____|__| |__|_____|_____|_____|
|   |   |             The Serverless Application Framework
|       |                           serverless.com, v0.3.1
`-------'

Use the &lt;up&gt;, &lt;down&gt;, &lt;pageup&gt;, &lt;pagedown&gt;, &lt;home&gt;, and &lt;end&gt; keys to navigate.
Press &lt;enter&gt; to select/deselect, or &lt;space&gt; to select/deselect and move down.
Press &lt;ctrl&gt; + &lt;enter&gt; to immediately deploy selected.


Serverless: Select the assets you wish to deploy:
    nodejscomponent - potd - check
    function - nodejscomponent/potd/check
    endpoint - nodejscomponent/potd/check@potd/check~GET
    - - - - -
&gt; Deploy

Serverless: Deploying functions in "dev" to the following regions: eu-west-1  
Serverless: ------------------------  
Serverless: Successfully deployed functions in "dev" to the following regions:   
Serverless: eu-west-1 ------------------------  
Serverless:   nodejscomponent/potd/check: arn:aws:lambda:eu-west-1:962613113552:function:serverlessPotd-nodejscomponent-potd-check:dev  
</code></pre>

<p>And lets visit that URI</p>

<pre><code>https://rhnjv4ms2b.execute-api.eu-west-1.amazonaws.com/development/potd/check?password=nonsense
</code></pre>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
</pre></td><td class='code'><pre><code class='json'><span class='line'><span class="p">{</span>
</span><span class='line'>    <span class="err">message:</span> <span class="err">false</span>
</span><span class='line'><span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>


<pre><code>https://rhnjv4ms2b.execute-api.eu-west-1.amazonaws.com/development/potd/check?password=Password
</code></pre>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
</pre></td><td class='code'><pre><code class='json'><span class='line'><span class="p">{</span>
</span><span class='line'>    <span class="err">message:</span> <span class="err">true</span>
</span><span class='line'><span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>


<p>Rock and roll. A working password checker running on Lambda in the Amazon cloud.</p>

<p>Next up - we&#8217;ll extend the <code>PasswordGenerator</code> class to pull in a node package and generate a better password.</p>

<p>The <a href="https://github.com/ZeroSharp/ServerlessPotd">source code so far</a> is on GitHub. Note the default <em>.gitignore</em> file skips the <em>admin.env</em> file which contains the (sensitive) AWS keys in it so don&#8217;t forget to add your own.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Serverless Framework - Part 3: The guts of a serverless service]]></title>
    <link href="http://ZeroSharp.github.com/serverless-framework-part-3-the-guts/"/>
    <updated>2016-01-29T17:44:00+00:00</updated>
    <id>http://ZeroSharp.github.com/serverless-framework-part-3-the-guts</id>
    <content type="html"><![CDATA[<p>This is part of an ongoing series about the <a href="https://github.com/serverless/serverless">Serverless framework</a>. For those following along, <a href="http://ZeroSharp.github.com/serverless-framework-part-1-up-and-running/">part 1</a> and <a href="http://ZeroSharp.github.com/serverless-framework-part-2-typescript-and-mocha/">part 2</a> have been updated for the current latest version of Serverless 0.3.1.</p>

<p>In this post, we&#8217;ll discuss how a Serverless function actually works.</p>

<h2>The guts of a serverless function</h2>

<p>When we visited the deployed endpoint at the end of <a href="http://ZeroSharp.github.com/serverless-framework-part-1-up-and-running/">part 1</a>, it correctly returned some JSON content.</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
</pre></td><td class='code'><pre><code class='json'><span class='line'><span class="p">{</span>
</span><span class='line'>    <span class="err">message:</span> <span class="nt">&quot;Your Serverless function ran successfully!&quot;</span>
</span><span class='line'><span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>


<p></p>

<p>Where does this message come from? Look at <em>index.js</em> in the component&#8217;s <em>lib</em> folder.</p>

<figure class='code'><figcaption><span>nodejscomponent/lib/index.js </span></figcaption>
 <div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
</pre></td><td class='code'><pre><code class='javascript'><span class='line'><span class="cm">/**</span>
</span><span class='line'><span class="cm"> * Lib</span>
</span><span class='line'><span class="cm"> */</span>
</span><span class='line'>
</span><span class='line'><span class="nx">module</span><span class="p">.</span><span class="nx">exports</span><span class="p">.</span><span class="nx">respond</span> <span class="o">=</span> <span class="kd">function</span><span class="p">(</span><span class="nx">event</span><span class="p">,</span> <span class="nx">cb</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'>
</span><span class='line'>  <span class="kd">var</span> <span class="nx">response</span> <span class="o">=</span> <span class="p">{</span>
</span><span class='line'>    <span class="nx">message</span><span class="o">:</span> <span class="s2">&quot;Your Serverless function ran successfully!&quot;</span>
</span><span class='line'>  <span class="p">};</span>
</span><span class='line'>
</span><span class='line'>  <span class="k">return</span> <span class="nx">cb</span><span class="p">(</span><span class="kc">null</span><span class="p">,</span> <span class="nx">response</span><span class="p">);</span>
</span><span class='line'><span class="p">};</span>
</span></code></pre></td></tr></table></div></figure>


<p>And it&#8217;s the <em>handler.js</em> file in the function&#8217;s subfolder which calls it.</p>

<figure class='code'><figcaption><span>nodejscomponent/potd/check/handler.js </span></figcaption>
 <div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
<span class='line-number'>17</span>
<span class='line-number'>18</span>
<span class='line-number'>19</span>
<span class='line-number'>20</span>
<span class='line-number'>21</span>
<span class='line-number'>22</span>
</pre></td><td class='code'><pre><code class='javascript'><span class='line'><span class="s1">&#39;use strict&#39;</span><span class="p">;</span>
</span><span class='line'>
</span><span class='line'><span class="cm">/**</span>
</span><span class='line'><span class="cm"> * Serverless Module: Lambda Handler</span>
</span><span class='line'><span class="cm"> * - Your lambda functions should be a thin wrapper around your own separate</span>
</span><span class='line'><span class="cm"> * modules, to keep your code testable, reusable and AWS independent</span>
</span><span class='line'><span class="cm"> * - &#39;serverless-helpers-js&#39; module is required for Serverless ENV var support.  Hopefully, AWS will add ENV support to Lambda soon :)</span>
</span><span class='line'><span class="cm"> */</span>
</span><span class='line'>
</span><span class='line'><span class="c1">// Require Serverless ENV vars</span>
</span><span class='line'><span class="kd">var</span> <span class="nx">ServerlessHelpers</span> <span class="o">=</span> <span class="nx">require</span><span class="p">(</span><span class="s1">&#39;serverless-helpers-js&#39;</span><span class="p">).</span><span class="nx">loadEnv</span><span class="p">();</span>
</span><span class='line'>
</span><span class='line'><span class="c1">// Require Logic</span>
</span><span class='line'><span class="kd">var</span> <span class="nx">lib</span> <span class="o">=</span> <span class="nx">require</span><span class="p">(</span><span class="s1">&#39;../../lib&#39;</span><span class="p">);</span>
</span><span class='line'>
</span><span class='line'><span class="c1">// Lambda Handler</span>
</span><span class='line'><span class="nx">module</span><span class="p">.</span><span class="nx">exports</span><span class="p">.</span><span class="nx">handler</span> <span class="o">=</span> <span class="kd">function</span><span class="p">(</span><span class="nx">event</span><span class="p">,</span> <span class="nx">context</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'>
</span><span class='line'>  <span class="nx">lib</span><span class="p">.</span><span class="nx">respond</span><span class="p">(</span><span class="nx">event</span><span class="p">,</span> <span class="kd">function</span><span class="p">(</span><span class="nx">error</span><span class="p">,</span> <span class="nx">response</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'>    <span class="k">return</span> <span class="nx">context</span><span class="p">.</span><span class="nx">done</span><span class="p">(</span><span class="nx">error</span><span class="p">,</span> <span class="nx">response</span><span class="p">);</span>
</span><span class='line'>  <span class="p">});</span>
</span><span class='line'><span class="p">};</span>
</span></code></pre></td></tr></table></div></figure>


<p>In our case we&#8217;re coding a password checking function. The URI will look something like this:</p>

<pre><code>http://something.amazonaws.com/development/potd/check?password=P455w0rd
</code></pre>

<p>We&#8217;ll modify <em>lib/index.js</em> to retrieve the value from the query parameter <code>password</code> and return <code>true</code> if the password is correct and <code>false</code> otherwise. But first we need to set up the parameter.</p>

<h2>Configuring the function parameter</h2>

<p>In each function&#8217;s directory, there is a file named <em>s-function.json</em> which allows you to specify the details of the function call. Add a section to the <code>requestTemplates</code> as follows:</p>

<figure class='code'><figcaption><span>nodejscomponent/potd/check/s-function.js </span></figcaption>
 <div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
<span class='line-number'>17</span>
<span class='line-number'>18</span>
<span class='line-number'>19</span>
<span class='line-number'>20</span>
<span class='line-number'>21</span>
<span class='line-number'>22</span>
<span class='line-number'>23</span>
<span class='line-number'>24</span>
<span class='line-number'>25</span>
<span class='line-number'>26</span>
<span class='line-number'>27</span>
<span class='line-number'>28</span>
<span class='line-number'>29</span>
<span class='line-number'>30</span>
<span class='line-number'>31</span>
<span class='line-number'>32</span>
<span class='line-number'>33</span>
<span class='line-number'>34</span>
<span class='line-number'>35</span>
<span class='line-number'>36</span>
<span class='line-number'>37</span>
</pre></td><td class='code'><pre><code class='json'><span class='line'><span class="p">{</span>
</span><span class='line'>  <span class="nt">&quot;name&quot;</span><span class="p">:</span> <span class="s2">&quot;check&quot;</span><span class="p">,</span>
</span><span class='line'>  <span class="nt">&quot;handler&quot;</span><span class="p">:</span> <span class="s2">&quot;potd/check/handler.handler&quot;</span><span class="p">,</span>
</span><span class='line'>  <span class="nt">&quot;timeout&quot;</span><span class="p">:</span> <span class="mi">6</span><span class="p">,</span>
</span><span class='line'>  <span class="nt">&quot;memorySize&quot;</span><span class="p">:</span> <span class="mi">1024</span><span class="p">,</span>
</span><span class='line'>  <span class="nt">&quot;custom&quot;</span><span class="p">:</span> <span class="p">{</span>
</span><span class='line'>    <span class="nt">&quot;excludePatterns&quot;</span><span class="p">:</span> <span class="p">[],</span>
</span><span class='line'>    <span class="nt">&quot;envVars&quot;</span><span class="p">:</span> <span class="p">[]</span>
</span><span class='line'>  <span class="p">},</span>
</span><span class='line'>  <span class="nt">&quot;endpoints&quot;</span><span class="p">:</span> <span class="p">[</span>
</span><span class='line'>    <span class="p">{</span>
</span><span class='line'>      <span class="nt">&quot;path&quot;</span><span class="p">:</span> <span class="s2">&quot;potd/check&quot;</span><span class="p">,</span>
</span><span class='line'>      <span class="nt">&quot;method&quot;</span><span class="p">:</span> <span class="s2">&quot;GET&quot;</span><span class="p">,</span>
</span><span class='line'>      <span class="nt">&quot;authorizationType&quot;</span><span class="p">:</span> <span class="s2">&quot;none&quot;</span><span class="p">,</span>
</span><span class='line'>      <span class="nt">&quot;apiKeyRequired&quot;</span><span class="p">:</span> <span class="kc">false</span><span class="p">,</span>
</span><span class='line'>      <span class="nt">&quot;requestParameters&quot;</span><span class="p">:</span> <span class="p">{},</span>
</span><span class='line'>      <span class="nt">&quot;requestTemplates&quot;</span><span class="p">:</span> <span class="p">{</span>
</span><span class='line'><span class="err">+</span>       <span class="nt">&quot;application/json&quot;</span><span class="p">:</span> <span class="p">{</span>
</span><span class='line'><span class="err">+</span>           <span class="nt">&quot;password&quot;</span><span class="p">:</span> <span class="s2">&quot;$input.params(&#39;password&#39;)&quot;</span>
</span><span class='line'><span class="err">+</span>       <span class="p">}</span>
</span><span class='line'>      <span class="p">},</span>
</span><span class='line'>      <span class="nt">&quot;responses&quot;</span><span class="p">:</span> <span class="p">{</span>
</span><span class='line'>        <span class="nt">&quot;400&quot;</span><span class="p">:</span> <span class="p">{</span>
</span><span class='line'>          <span class="nt">&quot;statusCode&quot;</span><span class="p">:</span> <span class="s2">&quot;400&quot;</span>
</span><span class='line'>        <span class="p">},</span>
</span><span class='line'>        <span class="nt">&quot;default&quot;</span><span class="p">:</span> <span class="p">{</span>
</span><span class='line'>          <span class="nt">&quot;statusCode&quot;</span><span class="p">:</span> <span class="s2">&quot;200&quot;</span><span class="p">,</span>
</span><span class='line'>          <span class="nt">&quot;responseParameters&quot;</span><span class="p">:</span> <span class="p">{},</span>
</span><span class='line'>          <span class="nt">&quot;responseModels&quot;</span><span class="p">:</span> <span class="p">{},</span>
</span><span class='line'>          <span class="nt">&quot;responseTemplates&quot;</span><span class="p">:</span> <span class="p">{</span>
</span><span class='line'>            <span class="nt">&quot;application/json&quot;</span><span class="p">:</span> <span class="s2">&quot;&quot;</span>
</span><span class='line'>          <span class="p">}</span>
</span><span class='line'>        <span class="p">}</span>
</span><span class='line'>      <span class="p">}</span>
</span><span class='line'>    <span class="p">}</span>
</span><span class='line'>  <span class="p">]</span>
</span><span class='line'><span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>


<p>Note that the <em>s-function.json</em> file is also where you can configure if the service accepts <code>POST</code> or <code>PUT</code> or <code>DELETE</code> requests. Here we are only interested in <code>GET</code>.</p>

<p>You can easily tailor the <code>requestTemplates</code> in this file to extract whatever parameters you need in your lambda function.</p>

<h2>Retrieving the parameter value</h2>

<p>Now back in <em>index.js</em> you will find that the function&#8217;s <code>event</code> parameter has a property <code>password</code> which is set to the value of the querystring parameter.</p>

<figure class='code'><figcaption><span>nodejscomponent/lib/index.js </span></figcaption>
 <div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
</pre></td><td class='code'><pre><code class='javascript'><span class='line'><span class="nx">module</span><span class="p">.</span><span class="nx">exports</span><span class="p">.</span><span class="nx">respond</span> <span class="o">=</span> <span class="kd">function</span><span class="p">(</span><span class="nx">event</span><span class="p">,</span> <span class="nx">cb</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'>
</span><span class='line'>  <span class="kd">var</span> <span class="nx">parameterValue</span> <span class="o">=</span> <span class="nx">event</span><span class="p">.</span><span class="nx">password</span><span class="p">;</span> <span class="c1">// the querystring parameter</span>
</span><span class='line'>  <span class="kd">var</span> <span class="nx">response</span> <span class="o">=</span> <span class="p">{</span>
</span><span class='line'>    <span class="nx">message</span><span class="o">:</span> <span class="nx">parameterValue</span>
</span><span class='line'>  <span class="p">};</span>
</span><span class='line'>
</span><span class='line'>  <span class="k">return</span> <span class="nx">cb</span><span class="p">(</span><span class="kc">null</span><span class="p">,</span> <span class="nx">response</span><span class="p">);</span>
</span><span class='line'><span class="p">};</span>
</span></code></pre></td></tr></table></div></figure>


<p>Redeploy.</p>

<pre><code> $ serverless dash deploy
</code></pre>

<p>Visit the URI.</p>

<pre><code>http://something.amazonaws.com/development/potd/check?password=P455w0rd
</code></pre>

<p>The response is:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
</pre></td><td class='code'><pre><code class='json'><span class='line'><span class="p">{</span>
</span><span class='line'>    <span class="err">message:</span> <span class="nt">&quot;P455w0rd&quot;</span>
</span><span class='line'><span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>


<h2>Ready for implementation</h2>

<p>We now have all the pieces we need. Serverless, Typescript, Mocha and AWS. In the next post I&#8217;ll show how to wire up everything get it working.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Serverless Framework - Part 2: TypeScript and Mocha]]></title>
    <link href="http://ZeroSharp.github.com/serverless-framework-part-2-typescript-and-mocha/"/>
    <updated>2016-01-12T08:08:00+00:00</updated>
    <id>http://ZeroSharp.github.com/serverless-framework-part-2-typescript-and-mocha</id>
    <content type="html"><![CDATA[<p>Happy New Year everyone!</p>

<p>This is the second part of a series about the <a href="https://github.com/serverless/serverless">Serverless</a> framework. Read <a href="http://ZeroSharp.github.com/serverless-framework-part-1-up-and-running/">the first part</a> to get up and running.</p>

<p>First I&#8217;ll describe the webservice I&#8217;m building. Then we&#8217;ll configure our environment for Typescript and Mocha testing.</p>

<h2>Poor man&#8217;s dual factor authentication via a password of the day</h2>

<p><span class='pullquote-right' data-pullquote='it&#8217;s about not having the hassle of administering a server.'>
I&#8217;m the technical lead for an enterprise application which is in use by about 100 large multinational corporates. As part of the installation process, we ask for a registration code which is based on the date. The customer has to call us to get the password of the day. This gives us an opportunity to engage with the customer and also gives us little more control. It&#8217;s a simple form of dual factor authorization where one of the factors requires a phone call.</p>

<p>In the old days, the routine for checking the validity of the password was part of the source code, but we&#8217;ve since moved the checking function to a web service.</p>

<p>It&#8217;s my goal to replace this &#8216;password of the day&#8217; check function with a Serverless module. The service will take a password as input and check that it matches the password of the day.</p>

<p>It&#8217;s a tiny, simple, rarely-used web service but AWS lambda is still a great fit for it. Although lambda can scale if necessary, in this case it&#8217;s about not having the hassle of administering a server.
</span></p>

<h2>Mocha and TypeScript</h2>

<h2>New version 0.3.1</h2>

<p><span class="fluo">Edit: since the original version of this post, a new version 0.3.1 of Serverless was released. I have updated the tutorial below to reflect the newer version. Also, <a href="https://github.com/DefinitelyTyped/tsd/issues/269">TSD has been deprecated</a> in favour of <a href="https://www.npmjs.com/package/typings">Typings</a> so I&#8217;ve updated to use Typings instead. </span></p>

<p>Let&#8217;s do things properly and set up a testing framework.</p>

<p>Make sure you&#8217;re in the component folder.</p>

<pre><code>$ cd nodejscomponent
</code></pre>

<p>Then we&#8217;ll install Mocha.</p>

<pre><code>$ npm install mocha --save-dev
mocha@2.4.5 node_modules/mocha
├── escape-string-regexp@1.0.2
├── commander@2.3.0
├── diff@1.4.0
├── supports-color@1.2.0
├── growl@1.8.1
├── debug@2.2.0 (ms@0.7.1)
├── mkdirp@0.5.1 (minimist@0.0.8)
├── jade@0.26.3 (commander@0.6.1, mkdirp@0.3.0)
└── glob@3.2.3 (inherits@2.0.1, graceful-fs@2.0.3, minimatch@0.2.14)
</code></pre>

<p>Next we&#8217;ll install TypeScript. Of course you can use plain javascript if you prefer. My background is C#: I make fewer dumb mistakes with TypeScript. It looks like there <a href="https://github.com/serverless/serverless/issues/371">is a typescript plugin in the pipeline</a> which will make typescript integration even easier in the future, but for now:</p>

<pre><code>$ npm install typescript --save
typescript@1.7.5 node_modules/typescript

$ npm install typings -g
/usr/local/bin/typings -&gt; /usr/local/lib/node_modules/typings/dist/bin/typings.js
typings@0.6.6 /usr/local/lib/node_modules/typings
├── array-uniq@1.0.2
├── elegant-spinner@1.0.1
├── thenify@3.2.0
├── popsicle-status@1.0.1
... etc ...
</code></pre>

<p>Initialise typings.</p>

<pre><code>$ typings init
-&gt; written typings.json
</code></pre>

<p>Now we add the type definitions for Mocha.</p>

<pre><code>$ typings install mocha --ambient --save
? Found mocha typings for DefinitelyTyped. Continue? Yes
Installing mocha@~2.2.5 (DefinitelyTyped)...

mocha
└── (No dependencies)
</code></pre>

<p>We need a config file for the TypeScript compiler. This goes in the same module directory (<em>back/modules/potd</em> in my case).</p>

<figure class='code'><figcaption><span>tsconfig.json </span></figcaption>
 <div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
</pre></td><td class='code'><pre><code class='json'><span class='line'><span class="p">{</span>
</span><span class='line'>    <span class="nt">&quot;compilerOptions&quot;</span><span class="p">:</span> <span class="p">{</span>
</span><span class='line'>        <span class="nt">&quot;module&quot;</span><span class="p">:</span> <span class="s2">&quot;commonjs&quot;</span><span class="p">,</span>
</span><span class='line'>        <span class="nt">&quot;target&quot;</span><span class="p">:</span> <span class="s2">&quot;es5&quot;</span><span class="p">,</span>
</span><span class='line'>        <span class="nt">&quot;noImplicitAny&quot;</span><span class="p">:</span> <span class="kc">true</span><span class="p">,</span>
</span><span class='line'>        <span class="nt">&quot;sourceMap&quot;</span><span class="p">:</span> <span class="kc">false</span><span class="p">,</span>
</span><span class='line'>        <span class="nt">&quot;declaration&quot;</span><span class="p">:</span> <span class="kc">false</span><span class="p">,</span>
</span><span class='line'>        <span class="nt">&quot;outDir&quot;</span><span class="p">:</span> <span class="s2">&quot;lib&quot;</span>
</span><span class='line'>    <span class="p">},</span>
</span><span class='line'>    <span class="nt">&quot;exclude&quot;</span><span class="p">:</span> <span class="p">[</span>
</span><span class='line'>        <span class="s2">&quot;node_modules&quot;</span><span class="p">,</span>
</span><span class='line'>        <span class="s2">&quot;typings/browser&quot;</span><span class="p">,</span>
</span><span class='line'>        <span class="s2">&quot;typings/browser.d.ts&quot;</span>
</span><span class='line'>    <span class="p">]</span>
</span><span class='line'><span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>


<p>Now make a subdirectory for our TypeScript source files.</p>

<pre><code>$ mkdir src
$ mkdir src/test
</code></pre>

<p>Next up we need to modify the package.json file to add a scripts section. Only the <code>"scripts"</code> section needs changing.</p>

<figure class='code'><figcaption><span>package.json </span></figcaption>
 <div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
<span class='line-number'>17</span>
<span class='line-number'>18</span>
<span class='line-number'>19</span>
<span class='line-number'>20</span>
<span class='line-number'>21</span>
<span class='line-number'>22</span>
<span class='line-number'>23</span>
<span class='line-number'>24</span>
<span class='line-number'>25</span>
</pre></td><td class='code'><pre><code class='json'><span class='line'><span class="p">{</span>
</span><span class='line'>  <span class="nt">&quot;name&quot;</span><span class="p">:</span> <span class="s2">&quot;potd&quot;</span><span class="p">,</span>
</span><span class='line'>  <span class="nt">&quot;version&quot;</span><span class="p">:</span> <span class="s2">&quot;0.0.1&quot;</span><span class="p">,</span>
</span><span class='line'>  <span class="nt">&quot;description&quot;</span><span class="p">:</span> <span class="s2">&quot;Dependencies for a Password of the day Serverless Module&quot;</span><span class="p">,</span>
</span><span class='line'>  <span class="nt">&quot;author&quot;</span><span class="p">:</span> <span class="s2">&quot;Robert Anderson&quot;</span><span class="p">,</span>
</span><span class='line'>  <span class="nt">&quot;license&quot;</span><span class="p">:</span> <span class="s2">&quot;MIT&quot;</span><span class="p">,</span>
</span><span class='line'>  <span class="nt">&quot;private&quot;</span><span class="p">:</span> <span class="kc">true</span><span class="p">,</span>
</span><span class='line'>  <span class="nt">&quot;repository&quot;</span><span class="p">:</span> <span class="p">{</span>
</span><span class='line'>    <span class="nt">&quot;type&quot;</span><span class="p">:</span> <span class="s2">&quot;git&quot;</span><span class="p">,</span>
</span><span class='line'>    <span class="nt">&quot;url&quot;</span><span class="p">:</span> <span class="s2">&quot;git://github.com/&quot;</span>
</span><span class='line'>  <span class="p">},</span>
</span><span class='line'>  <span class="nt">&quot;keywords&quot;</span><span class="p">:</span> <span class="p">[],</span>
</span><span class='line'>  <span class="nt">&quot;devDependencies&quot;</span><span class="p">:</span> <span class="p">{</span>
</span><span class='line'>    <span class="nt">&quot;mocha&quot;</span><span class="p">:</span> <span class="s2">&quot;^2.3.4&quot;</span>
</span><span class='line'>  <span class="p">},</span>
</span><span class='line'>  <span class="nt">&quot;dependencies&quot;</span><span class="p">:</span> <span class="p">{</span>
</span><span class='line'>    <span class="nt">&quot;serverless-helpers-js&quot;</span><span class="p">:</span> <span class="s2">&quot;~0.0.3&quot;</span><span class="p">,</span>
</span><span class='line'>    <span class="nt">&quot;typescript&quot;</span><span class="p">:</span> <span class="s2">&quot;^1.7.5&quot;</span>
</span><span class='line'>  <span class="p">},</span>
</span><span class='line'>  <span class="nt">&quot;scripts&quot;</span><span class="p">:</span> <span class="p">{</span>
</span><span class='line'>    <span class="nt">&quot;prepublish&quot;</span><span class="p">:</span> <span class="s2">&quot;tsc&quot;</span><span class="p">,</span>
</span><span class='line'>    <span class="nt">&quot;pretest&quot;</span><span class="p">:</span> <span class="s2">&quot;tsc&quot;</span><span class="p">,</span>
</span><span class='line'>    <span class="nt">&quot;test&quot;</span><span class="p">:</span> <span class="s2">&quot;mocha ./lib/test&quot;</span>
</span><span class='line'>  <span class="p">}</span>
</span><span class='line'><span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>


<p>We&#8217;ve finished setting up everything for TypeScript and Mocha. Whenever you run <code>tsc</code>, any TypeScript files in <em>/src</em> will get compiled to javascript in <em>/lib</em>. And running <code>npm test</code> will compile and then run any Mocha tests in <em>/lib/test</em>.</p>

<p>The <a href="https://github.com/ZeroSharp/ServerlessPotd">source code so far</a> is on GitHub. Note the default <em>.gitignore</em> file skips the <em>admin.env</em> file which contains the (sensitive) AWS keys in it so don&#8217;t forget to add your own.</p>

<p>In the next post we&#8217;ll create a TypeScript class for the guts of the lambda function which checks the password of the day, along with some corresponding Mocha tests, also written in TypeScript.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Serverless Framework - Part 1: Up and running]]></title>
    <link href="http://ZeroSharp.github.com/serverless-framework-part-1-up-and-running/"/>
    <updated>2015-12-22T20:26:00+00:00</updated>
    <id>http://ZeroSharp.github.com/serverless-framework-part-1-up-and-running</id>
    <content type="html"><![CDATA[<h2>New version 0.3.1</h2>

<p><span class="fluo">Edit: since the original version of this post, a new version 0.3.1 of Serverless was released. I have updated the tutorial below to reflect the newer version. </span></p>

<p>I was in the middle of a blog post about the JAWS framework and before I had finished it changed its name to <a href="https://github.com/serverless/serverless">the Serverless framework</a>. It is a very clever way to build apps without worrying about provisioning server or whether it will scale. This is because it uses Amazon Web Services and in particular the Amazon lambda compute service. It&#8217;s currently in beta.</p>

<p>Follow <a href="http://docs.serverless.com/docs/configuring-aws">the instructions</a> for setting up an administrative IAM user for use with the framework.</p>

<p>Make sure you have node and npm installed. You need node 4.0 or greater.</p>

<pre><code>$ node -v
v4.2.3
$ npm -v
2.14.7
</code></pre>

<p>Install the Serverless framework.</p>

<pre><code>$ npm install serverless -g 
</code></pre>

<p>Create a new project</p>

<pre><code>$ serverless project create
</code></pre>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
<span class='line-number'>17</span>
<span class='line-number'>18</span>
<span class='line-number'>19</span>
<span class='line-number'>20</span>
<span class='line-number'>21</span>
<span class='line-number'>22</span>
<span class='line-number'>23</span>
<span class='line-number'>24</span>
<span class='line-number'>25</span>
<span class='line-number'>26</span>
<span class='line-number'>27</span>
</pre></td><td class='code'><pre><code class=''><span class='line'> _______                             __
</span><span class='line'>|   _   .-----.----.--.--.-----.----|  .-----.-----.-----.
</span><span class='line'>|   |___|  -__|   _|  |  |  -__|   _|  |  -__|__ --|__ --|
</span><span class='line'>|____   |_____|__|  \___/|_____|__| |__|_____|_____|_____|
</span><span class='line'>|   |   |             The Serverless Application Framework
</span><span class='line'>|       |                           serverless.com, v0.3.1
</span><span class='line'>`-------'
</span><span class='line'>
</span><span class='line'>Serverless: Initializing Serverless Project...  
</span><span class='line'>Serverless: Enter a name for this project:  (serverless-vyedql) serverlessPotd
</span><span class='line'>Serverless: Enter a universally unique project bucket name:  (serverless-vyedql-4jboce.com) potd-zerosharp.com
</span><span class='line'>Serverless: Enter an email to use for AWS alarms:  (me@serverless-vyedql.com) potd@nosredna.com
</span><span class='line'>Serverless: Select a region for your project: 
</span><span class='line'>    us-east-1
</span><span class='line'>    us-west-2
</span><span class='line'>  &gt; eu-west-1
</span><span class='line'>    ap-northeast-1
</span><span class='line'>Serverless: Select an AWS profile for your project: 
</span><span class='line'>  &gt; default
</span><span class='line'>Serverless: Creating stage "dev"...  
</span><span class='line'>Serverless: Creating region "eu-west-1" in stage "dev"...  
</span><span class='line'>Serverless: Creating your project bucket on S3: serverless.eu-west-1.potd-zerosharp.com...  
</span><span class='line'>Serverless: Deploying resources to stage "dev" in region "eu-west-1" via Cloudformation (~3 minutes)...  
</span><span class='line'>Serverless: Successfully deployed "dev" resources to "eu-west-1"  
</span><span class='line'>Serverless: Successfully created region "eu-west-1" within stage "dev"  
</span><span class='line'>Serverless: Successfully created stage "dev"  
</span><span class='line'>Serverless: Successfully initialized project "serverlessPotd"  </span></code></pre></td></tr></table></div></figure>


<p>It takes about 3 minutes to setup the necessary CloudFormation stack for your project. Change directory to the newly created project.</p>

<pre><code>$ cd serverlessPotd
</code></pre>

<p>Create a new component.</p>

<pre><code>$ serverless component create
</code></pre>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>Serverless: Enter a name for your new component:  (nodejscomponent) 
</span><span class='line'>Serverless: Enter a name for your component's first module:  (resource) potd
</span><span class='line'>Serverless: Enter a name for your module's first function:  (show) check
</span><span class='line'>Serverless: Successfully created function: "check"  
</span><span class='line'>Serverless: Successfully created new serverless module "potd" inside the component "nodejscomponent"  
</span><span class='line'>Serverless: Installing "serverless-helpers" for this component via NPM...  
</span><span class='line'>Serverless: -----------------  
</span><span class='line'>serverless-helpers-js@0.0.3 node_modules/serverless-helpers-js
</span><span class='line'>└── dotenv@1.2.0
</span><span class='line'>Serverless: -----------------  
</span><span class='line'>Serverless: Successfully created new serverless component: nodejscomponent  </span></code></pre></td></tr></table></div></figure>


<p></p>

<p>This has created the javascript code for a basic lambda function which we can immediately deploy.</p>

<pre><code>$ serverless dash deploy
</code></pre>

<p>At the prompt select both the function and the endpoint and then select <em>Deploy</em>.</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
<span class='line-number'>17</span>
<span class='line-number'>18</span>
<span class='line-number'>19</span>
<span class='line-number'>20</span>
<span class='line-number'>21</span>
<span class='line-number'>22</span>
<span class='line-number'>23</span>
<span class='line-number'>24</span>
<span class='line-number'>25</span>
<span class='line-number'>26</span>
<span class='line-number'>27</span>
<span class='line-number'>28</span>
<span class='line-number'>29</span>
<span class='line-number'>30</span>
</pre></td><td class='code'><pre><code class=''><span class='line'> _______                             __
</span><span class='line'>|   _   .-----.----.--.--.-----.----|  .-----.-----.-----.
</span><span class='line'>|   |___|  -__|   _|  |  |  -__|   _|  |  -__|__ --|__ --|
</span><span class='line'>|____   |_____|__|  \___/|_____|__| |__|_____|_____|_____|
</span><span class='line'>|   |   |             The Serverless Application Framework
</span><span class='line'>|       |                           serverless.com, v0.3.1
</span><span class='line'>`-------'
</span><span class='line'>
</span><span class='line'>Use the &lt;up&gt;, &lt;down&gt;, &lt;pageup&gt;, &lt;pagedown&gt;, &lt;home&gt;, and &lt;end&gt; keys to navigate.
</span><span class='line'>Press &lt;enter&gt; to select/deselect, or &lt;space&gt; to select/deselect and move down.
</span><span class='line'>Press &lt;ctrl&gt; + &lt;enter&gt; to immediately deploy selected.
</span><span class='line'>
</span><span class='line'>
</span><span class='line'>Serverless: Select the assets you wish to deploy:
</span><span class='line'>    nodejscomponent - potd - check
</span><span class='line'>      function - nodejscomponent/potd/check
</span><span class='line'>      endpoint - nodejscomponent/potd/check@potd/check~GET
</span><span class='line'>    - - - - -
</span><span class='line'>  &gt; Deploy
</span><span class='line'>
</span><span class='line'>Serverless: Deploying functions in "dev" to the following regions: eu-west-1  
</span><span class='line'>Serverless: ------------------------  
</span><span class='line'>Serverless: Successfully deployed functions in "dev" to the following regions:   
</span><span class='line'>Serverless: eu-west-1 ------------------------  
</span><span class='line'>Serverless:   nodejscomponent/potd/check: arn:aws:lambda:eu-west-1:962613113552:function:serverlessPotd-nodejscomponent-potd-check:dev  
</span><span class='line'>
</span><span class='line'>Serverless: Deploying endpoints in "dev" to the following regions: eu-west-1  
</span><span class='line'>Serverless: Successfully deployed endpoints in "dev" to the following regions:  
</span><span class='line'>Serverless: eu-west-1 ------------------------  
</span><span class='line'>Serverless:   GET - potd/check - https://rhnjv4ms2b.execute-api.eu-west-1.amazonaws.com/dev/potd/check  </span></code></pre></td></tr></table></div></figure>


<p>Now open a browser and navigate to the URL in the last line. You should see the following JSON response.</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
</pre></td><td class='code'><pre><code class='json'><span class='line'><span class="p">{</span>
</span><span class='line'>    <span class="err">message:</span> <span class="nt">&quot;Your Serverless function ran successfully!&quot;</span>
</span><span class='line'><span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>


<p></p>

<p>Now that&#8217;s already fantastic. With a handful of commands we have deployed an arbitrary javascript function to a URL endpoint very cheaply and with automatic scaling. We never had to consider instance size or memory or operating system.</p>

<p>And it&#8217;s extremely extensible too - thanks to the other AWS services, we can easily make it secure (with Amazon Cognito) kick off emails (SES), store files (S3), add persistence (DynamoDB), etc.</p>

<p>In the next post, I&#8217;ll be applying it to a real life scenario to replace an existing web service.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[DevExpress 2015.2 review part 2]]></title>
    <link href="http://ZeroSharp.github.com/devexpress-15-dot-2-review-part-2/"/>
    <updated>2015-12-10T09:43:00+00:00</updated>
    <id>http://ZeroSharp.github.com/devexpress-15-dot-2-review-part-2</id>
    <content type="html"><![CDATA[<p>This is the second and final dive into some of the new DevExpress XAF 2015.2 features. The <a href="http://ZeroSharp.github.com/devexpress-15-dot-2-review-part-1/">first part</a> covers the Report Designer and the new XML serialisation.</p>

<h2>Batch editing</h2>

<p>Another feature I&#8217;m excited about is the support for batch editing within the web application grids.</p>

<p>Let&#8217;s see what happens when combined with the validation rules. What happens if I edit two rows but only one has a validation problem - does the whole batch get rejected? Or just the row with the problem?</p>

<p>First I modified the edit mode of the Tasks grid to <code>Batch</code> via the model.</p>

<p><img src="http://ZeroSharp.github.com/images/blog/devexpress-15-2-review-001.png"></p>

<p>Then I added a new <code>RuleRequiredField</code> validation rule via the model.</p>

<p><img src="http://ZeroSharp.github.com/images/blog/devexpress-15-2-review-002.png"></p>

<p>I started up the MainDemo application and navigated to the Tasks view and tried to delete the subject of multiple rows at the same time.</p>

<p><img src="http://ZeroSharp.github.com/images/blog/devexpress-15-2-review-003.png"></p>

<p>I never even got to press Save because of another new 15.2 feature: <a href="https://community.devexpress.com/blogs/eaf/archive/2015/11/24/xaf-validation-module-enhancements-for-windows-and-the-web-coming-soon-in-v15-2.aspx">inplace validation</a>! The rules are being validated <em>without</em> a round trip to the server!</p>

<p>So let&#8217;s try another way. <em>Inplace Validation</em> does not work with all rule types, so I deleted my <code>RuleRequiredField</code> from the model and instead added a new <code>RuleFromBoolProperty</code> to the <code>DemoTask</code> object as follows:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
</pre></td><td class='code'><pre><code class='c#'><span class='line'><span class="na">[MemberDesignTimeVisibility(false)]</span>
</span><span class='line'><span class="na">[RuleFromBoolProperty(&quot;SubjectIsRequired&quot;, </span>
</span><span class='line'><span class="na">    DefaultContexts.Save, </span>
</span><span class='line'><span class="na">    &quot;Subject is required.&quot;, </span>
</span><span class='line'><span class="na">    UsedProperties = &quot;Subject&quot;, </span>
</span><span class='line'><span class="na">    SkipNullOrEmptyValues = false)]</span>
</span><span class='line'><span class="k">public</span> <span class="kt">bool</span> <span class="n">IsSubjectRequired</span>
</span><span class='line'><span class="p">{</span>
</span><span class='line'>    <span class="k">get</span>
</span><span class='line'>    <span class="p">{</span>
</span><span class='line'>        <span class="k">return</span> <span class="p">!</span><span class="n">String</span><span class="p">.</span><span class="n">IsNullOrWhiteSpace</span><span class="p">(</span><span class="n">Subject</span><span class="p">);</span>
</span><span class='line'>    <span class="p">}</span>
</span><span class='line'><span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>


<p>Now we go back to the list view for Task and try to set multiple subjects to empty.</p>

<p><img src="http://ZeroSharp.github.com/images/blog/devexpress-15-2-review-004.png"></p>

<p>Fantastic! This time the broken rules appear for each row and it is quite clear which message belongs to which object.</p>

<p>So the batch editing makes use of inplace validation when it can, but handles more complex validation rules well too. This is an excellent combination because the inpalce validation will help to make the client seem very quick and responsive.</p>

<h2>Conclusion</h2>

<p>This concludes my review of DevExpress 2015.2. We&#8217;ve looked in some detail at two of the most impressive new features - the way reports are serialised and the improvements to client-side validation. These changes help with performance and ease of maintenance and I&#8217;m very happy to see that the DevExpress team has focused on these areas. Looking forward to the 2016 releases!</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[DevExpress 2015.2 review part 1]]></title>
    <link href="http://ZeroSharp.github.com/devexpress-15-dot-2-review-part-1/"/>
    <updated>2015-12-09T14:43:00+00:00</updated>
    <id>http://ZeroSharp.github.com/devexpress-15-dot-2-review-part-1</id>
    <content type="html"><![CDATA[<p>Last week, DevExpress released 2015.2.3, their second major version of the year.</p>

<p>There are already some good blog posts about the changes:</p>

<ul>
<li><a href="http://www.codeproject.com/Tips/1060260/Whats-New-for-XAF">Michael Bogaerts</a></li>
<li><a href="http://vimarx.com/blog/92/">Gustavo Marzioni</a></li>
<li><a href="https://www.devexpress.com/Subscriptions/New-2015.xml?product=xaf">DevExpress What&#8217;s New</a></li>
</ul>


<p>Rather than repeat general overviews provided in these, this two-part blog post is more of a &#8216;deep dive&#8217;. In particular I&#8217;ll be looking at two of the new features in the expressApp Framework (XAF).
Today I&#8217;ll cover the new XML serialisation in the report designer. Tomorrow&#8217;s post will examine the new batch editing features.</p>

<h2>Reports</h2>

<p><span class='pullquote-right' data-pullquote='I&#8217;m happy to report that v1 reports are still very much present.'>
Reporting is definitely one of the areas where XAF has progressed the most in recent versions. There is now an in-browser report designer (since 14.2) and an alternative implementation of the reports (reports v2, since 13.2).</p>

<p>In this release, I was a little worried that the support for Reports v1 would be deprecated, since our production system has over 100 custom reports and we have not yet looked for an easy way to migrate these to v2. I&#8217;m happy to report that v1 reports are still very much present.
</span></p>

<p>However there are also a number of new features in v2 Reports, not least of which is the ability to store the report&#8217;s layout in XML. There&#8217;s currently not a lot of documentation about the XML serialization, so let&#8217;s dig in and see what we can discover.</p>

<h3>XML serialization deep dive</h3>

<p>First I ran the demo and ran the <em>Copy Predefined Report</em> on the Contacts Report.</p>

<p>Then I ran the report designer and added a dummy <code>OnBeforePrint()</code> script to one of the table&#8217;s cells.</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
</pre></td><td class='code'><pre><code class='c#'><span class='line'><span class="k">private</span> <span class="k">void</span> <span class="nf">xrTableCell8_BeforePrint</span><span class="p">(</span><span class="kt">object</span> <span class="n">sender</span><span class="p">,</span> <span class="n">System</span><span class="p">.</span><span class="n">Drawing</span><span class="p">.</span><span class="n">Printing</span><span class="p">.</span><span class="n">PrintEventArgs</span> <span class="n">e</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'>  <span class="kt">var</span> <span class="n">x</span> <span class="p">=</span> <span class="m">23</span><span class="p">;</span>
</span><span class='line'><span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>


<p>Then, in the MainDemo&#8217;s Updater.cs file, I placed the following code.</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
</pre></td><td class='code'><pre><code class='c#'><span class='line'><span class="kt">var</span> <span class="n">reportData</span> <span class="p">=</span> <span class="n">ObjectSpace</span><span class="p">.</span><span class="n">FindObject</span><span class="p">&lt;</span><span class="n">ReportDataV2</span><span class="p">&gt;(</span><span class="k">new</span> <span class="n">BinaryOperator</span><span class="p">(</span><span class="s">&quot;DisplayName&quot;</span><span class="p">,</span> <span class="s">&quot;Contacts Report&quot;</span><span class="p">)</span> <span class="p">&amp;</span> <span class="k">new</span> <span class="n">BinaryOperator</span><span class="p">(</span><span class="s">&quot;IsPredefined&quot;</span><span class="p">,</span> <span class="k">new</span> <span class="n">OperandValue</span><span class="p">(</span><span class="k">false</span><span class="p">)));</span>
</span><span class='line'><span class="k">if</span> <span class="p">(</span><span class="n">reportData</span> <span class="p">!=</span> <span class="k">null</span><span class="p">)</span>
</span><span class='line'><span class="p">{</span>
</span><span class='line'>    <span class="kt">var</span> <span class="n">report</span> <span class="p">=</span> <span class="n">ReportDataProvider</span><span class="p">.</span><span class="n">ReportsStorage</span><span class="p">.</span><span class="n">LoadReport</span><span class="p">(</span><span class="n">reportData</span><span class="p">);</span>
</span><span class='line'>    <span class="n">report</span><span class="p">.</span><span class="n">SaveLayoutToXml</span><span class="p">(</span><span class="s">@&quot;C:\Temp\ContactsReport.xml&quot;</span><span class="p">);</span>
</span><span class='line'>    <span class="n">report</span><span class="p">.</span><span class="n">SaveLayout</span><span class="p">(</span><span class="s">@&quot;C:\Temp\ContactsReport.repx&quot;</span><span class="p">);</span>
</span><span class='line'><span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>


<p>This creates two output files. One of them contains the familiar <em>.repx</em> format. The other contains the newer <em>.xml</em> serialization.</p>

<p>The contents of the XML file is displayed below and is 77 lines long.</p>

<div><script src='https://gist.github.com/f085bf10dd65ace5d229.js?file=ContactReport.xml'></script>
<noscript><pre><code></code></pre></noscript></div>


<p>By comparison, the <a href="https://gist.github.com/shamp00/f085bf10dd65ace5d229#file-contactsreport-repx">ContactReport.repx</a> is 408 lines long and much harder to read.</p>

<p>As you can see the XML file is <em>much</em> smaller and simpler than the <em>.repx</em> file. At first I didn&#8217;t believe it contained all the necessary information, so I started up the MainDemo WinForms application, created a blank new report and imported the layout and the layout looks correct and the preview loads with data as expected.</p>

<h3>Scripts</h3>

<p>What about scripts? Are they serialized in the xml version? You bet. In the XML export you can see this has been serialised near the top of the file.</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
</pre></td><td class='code'><pre><code class='xml'><span class='line'>ScriptsSource=
</span><span class='line'>   &quot;<span class="ni">&amp;#xD;&amp;#xA;</span>private void xrTableCell8_BeforePrint(object sender, System.Drawing.Printing.PrintEventArgs e)
</span><span class='line'>   {<span class="ni">&amp;#xD;&amp;#xA;</span>  var x = 23;<span class="ni">&amp;#xD;&amp;#xA;</span>}<span class="ni">&amp;#xD;&amp;#xA;</span>&quot;
</span></code></pre></td></tr></table></div></figure>


<h3>Setup</h3>

<p>In order to use this new XML serialization of report layouts, you must set the ReportsV2 module to use it.</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class='c#'><span class='line'><span class="n">reportsModuleV2</span><span class="p">.</span><span class="n">ReportStoreMode</span> <span class="p">=</span> <span class="n">ReportStoreModes</span><span class="p">.</span><span class="n">XML</span>
</span></code></pre></td></tr></table></div></figure>


<p>This will most likely invalidate any reports which have already been serialized to the database. There are some notes on how to fix this <a href="https://www.devexpress.com/Support/Center/Question/Details/T275363">here</a>.</p>

<h3>Default for new projects</h3>

<p>What about new projects? I created a new solution and chose <em>DevExpress 15.2 XAF Solution Wizard</em> as the type of solution and added the reports module. Now when I navigate to the <code>WinApplication.Designer.cs</code> file, I find:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
</pre></td><td class='code'><pre><code class='c#'><span class='line'><span class="c1">//</span>
</span><span class='line'><span class="c1">// reportsModuleV2</span>
</span><span class='line'><span class="c1">//</span>
</span><span class='line'><span class="k">this</span><span class="p">.</span><span class="n">reportsModuleV2</span><span class="p">.</span><span class="n">ReportDataType</span> <span class="p">=</span> <span class="k">typeof</span><span class="p">(</span><span class="n">DevExpress</span><span class="p">.</span><span class="n">Persistent</span><span class="p">.</span><span class="n">BaseImpl</span><span class="p">.</span><span class="n">ReportDataV2</span><span class="p">);</span>
</span><span class='line'><span class="k">this</span><span class="p">.</span><span class="n">reportsModuleV2</span><span class="p">.</span><span class="n">ReportStoreMode</span> <span class="p">=</span> <span class="n">DevExpress</span><span class="p">.</span><span class="n">ExpressApp</span><span class="p">.</span><span class="n">ReportsV2</span><span class="p">.</span><span class="n">ReportStoreModes</span><span class="p">.</span><span class="n">XML</span><span class="p">;</span>
</span></code></pre></td></tr></table></div></figure>


<p>So the default storage method for new projects is now XML.</p>

<h3>Conclusion</h3>

<p>The XML serialisation looks like a considerable upgrade to the mechanism for storing, loading and saving reports. Now I just need to find a good way of converting my existing v1 reports&#8230; Perhaps a future blog post.</p>

<h2>Coming up</h2>

<p>Tomorrow I&#8217;ll be looking at the new <a href="https://community.devexpress.com/blogs/eaf/archive/2015/11/24/xaf-validation-module-enhancements-for-windows-and-the-web-coming-soon-in-v15-2.aspx">batch editing in grids</a> in more detail.</p>
]]></content>
  </entry>
  
</feed>
