<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0" xmlns:media="http://search.yahoo.com/mrss/"><channel><title><![CDATA[Paul Roy]]></title><description><![CDATA[CTO (.NET / C# / Angular / DevOps / Azure), Powerlifting, Music, Magic.]]></description><link>https://www.pa-roy.com/</link><image><url>https://www.pa-roy.com/favicon.png</url><title>Paul Roy</title><link>https://www.pa-roy.com/</link></image><generator>Ghost 5.10</generator><lastBuildDate>Tue, 07 Apr 2026 18:38:37 GMT</lastBuildDate><atom:link href="https://www.pa-roy.com/rss/" rel="self" type="application/rss+xml"/><ttl>60</ttl><item><title><![CDATA[.NET Microservices : Service Discovery (Part 3: Configuring Commands HTTP Service to Consul and consuming it)]]></title><description><![CDATA[<p>Hello again on this third part of our Service Discovery tutorial for .NET core Microservices.</p><p>If you haven&apos;t seen the beginning of the series I recommand you check the <a href="https://www.pa-roy.com/net-microservices-service-discovery-part-1/">first post about Consul &amp; RabbitMQ</a> and the <a href="https://www.pa-roy.com/net-microservices-service-discovery-part-2/">second post about .NET code to access services with Consul</a>, along</p>]]></description><link>https://www.pa-roy.com/net-microservices-service-discovery-part-3/</link><guid isPermaLink="false">6305e568da3f5c6d9295a52b</guid><dc:creator><![CDATA[Paul Roy]]></dc:creator><pubDate>Mon, 05 Sep 2022 15:47:58 GMT</pubDate><content:encoded><![CDATA[<p>Hello again on this third part of our Service Discovery tutorial for .NET core Microservices.</p><p>If you haven&apos;t seen the beginning of the series I recommand you check the <a href="https://www.pa-roy.com/net-microservices-service-discovery-part-1/">first post about Consul &amp; RabbitMQ</a> and the <a href="https://www.pa-roy.com/net-microservices-service-discovery-part-2/">second post about .NET code to access services with Consul</a>, along with the <a href="https://www.youtube.com/watch?v=DgVjEo3OGBI&amp;ab_channel=LesJackson">base course from Les Jackson</a>.</p><!--kg-card-begin: markdown--><p><strong>This post is part of a whole:</strong></p>
<ul>
<li><a href="https://www.pa-roy.com/net-microservices-service-discovery-part-1/">.NET Microservices: Service Discovery (Part 1: Consul &amp; RabbitMQ Deployment)</a></li>
<li><a href="https://www.pa-roy.com/net-microservices-service-discovery-part-2/">.NET Microservices: Service Discovery (Part 2: Reaching RabbitMQ through Consul)</a></li>
<li>.NET Microservices: Service Discovery (Part 3: Configuring Commands HTTP Service to Consul and consuming it)</li>
<li>.NET Microservices: Service Discovery (Part 4: Configuring Platform gRPC Service to Consul and consuming it)</li>
</ul>
<!--kg-card-end: markdown--><p></p><p>We successfully deployed Consul to register our Microservices, we set up RabbitMQ to register automatically to Consul, and we updated our Microservices to call Consul in order to get the RabbitMQ configuration dynamically.</p><p>Several services such as RabbitMQ offer some elements or plugins to configure automatically to Consul, I strongly recommand to check out before doing anything complicated because as you&apos;ve seen, RabbitMQ was quite easy to set up.</p><p>So what do we want to do now? Well the whole point was to remove the dependency between our microservices, so we are going to<strong> register one of the services to Consul </strong>and ask Consul to <strong>deliver the configuration to whomever needs it</strong> at runtime.</p><p>I used some parts of another of TechyMaki&apos;s video about Consul, find out more here:</p><figure class="kg-card kg-embed-card"><iframe width="200" height="113" src="https://www.youtube.com/embed/wpUjiB7PEIA?feature=oembed" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen title="Service Discovery for .NET Core services with HashiCorp Consul &#x1F9ED;"></iframe></figure><p>We are going to register the <strong>CommandService HTTP Service</strong> first, simply because it&apos;s the most trivial to configure and to call.</p><h1 id="registering-our-commands-service-to-consul">Registering our Commands Service to Consul</h1><h2 id="configuring-our-appsettings">Configuring our appsettings</h2><p>Let&apos;s focus on CommandService project.<br>First things first, we are going to need to configure a few things for our appsettings files. The logic here will be reversed, instead of configuring the addresses and ports of the other services, <strong>we&apos;re going to configure our own address, port and consul info (id &amp; name)</strong>.</p><p>When we wanted to call <code>CommandService</code> from <code>PlatformService</code>, we configured the following address locally like that: <code>&quot;CommandsService&quot;: &quot;http://localhost:6000&quot;</code> in the PlatformService project.</p><p>Now, we want to configure <strong>the two appsettings of CommandService</strong> this way:</p><figure class="kg-card kg-code-card"><pre><code class="language-yaml">{
  (&#x2026;)
  &quot;CommandsHttp&quot;: {
    &quot;Id&quot;: &quot;commandshttp&quot;,
    &quot;Name&quot;: &quot;commandshttp&quot;,
    &quot;Address&quot;: &quot;localhost&quot;,
    &quot;Port&quot;: &quot;6000&quot;
  }
}
</code></pre><figcaption>appsettings.Development.json</figcaption></figure><figure class="kg-card kg-code-card"><pre><code class="language-yaml">{
  (&#x2026;)
  &quot;CommandsHttp&quot;: {
    &quot;Id&quot;: &quot;commandshttp&quot;,
    &quot;Name&quot;: &quot;commandshttp&quot;,
    &quot;Address&quot;: &quot;commands-clusterip-srv&quot;,
    &quot;Port&quot;: &quot;80&quot;
  }
}</code></pre><figcaption>appsettings.Production.json</figcaption></figure><p>Locally, our server is running in <code>localhost</code> on port 6000, which is what we configured. <br>In our kubernetes cluster, we configured our service to run on the <code>commands-clusterip-srv</code> address, with a classic port of 80.</p><p>I chose <code>commandshttp</code> as Id &amp; Name for Consul and we&apos;re going to use it now.</p><h2 id="hosted-service">Hosted Service</h2><p>We are going to use a <code>HostedService</code>. The principle is pretty simple, you implement an interface (<code>IHostedService</code>) that has two methods, <code>StartAsync()</code> and <code>StopAsync()</code>, and we will register this class to our AspNet startup system.</p><p>The Hosted Service will trigger the <code>StartAsync()</code> method just before starting the application, and will trigger <code>StopAsync()</code> right before the application stops. Remember this is sequentially triggered at startup so if you need a hosted service, you should keep these two implementation minimal not to overload your overall system.</p><p>This is actually perfect because it&apos;s the exact lifecycle we want for our Consul Registration: register the service at startup, deregister it at shutdown. Life is good.</p><h2 id="consulregisterhostedservice">ConsulRegisterHostedService</h2><p>We are going to create a new class, <code>ConsulRegisterHostedService</code> that we will place in the same folder as the rest of our Consul Services (DiscoveryServices). It will implement the <code>IHostedService</code> interface. We will need the <code>IConsulClient</code> we injected before and the <code>IConfiguration</code> to get our configuration. It should look like that at first:</p><figure class="kg-card kg-code-card"><pre><code class="language-csharp">using Consul;

namespace CommandsService.DiscoveryServices;

public class ConsulRegisterHostedService : IHostedService
{
    public ConsulRegisterHostedService(IConsulClient consulClient, 
                                       IConfiguration configuration)
    {
        _consulClient = consulClient;
        _configuration = configuration;
    }

    public Task StartAsync(CancellationToken cancellationToken)
    {
        Console.WriteLine(&quot;Registering service to Consul&quot;);
		return Task.CompletedTask;
    }

    public Task StopAsync(CancellationToken cancellationToken)
    {
        Console.WriteLine(&quot;Deregistering service to Consul&quot;);
        return Task.CompletedTask;
    }
}</code></pre><figcaption><code>ConsulRegisterHostedService</code> before implementing registration</figcaption></figure><h2 id="registering-our-hosted-service">Registering our Hosted Service</h2><p>Now we&apos;re going to register our Hosted Service. It&apos;s pretty standard, just go to your <code>Program.cs</code> (or <code>Startup.cs</code>) and use the <code>services.AddHostedService&lt;T&gt;()</code> method:</p><figure class="kg-card kg-code-card"><pre><code class="language-csharp">var services = builder.Services;

(&#x2026;)

services.AddHostedService&lt;ConsulRegisterHostedService&gt;();

(&#x2026;)</code></pre><figcaption><code>Program.cs</code></figcaption></figure><p>Just start your application with <code>dotnet run</code> to check you have the register log in the console, then kill it with CTRL+C and check you have the deregister log like that:</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://www.pa-roy.com/content/images/2022/08/image-7.png" class="kg-image" alt loading="lazy" width="616" height="262" srcset="https://www.pa-roy.com/content/images/size/w600/2022/08/image-7.png 600w, https://www.pa-roy.com/content/images/2022/08/image-7.png 616w"><figcaption>Registering &amp; Deregistering logs</figcaption></figure><h2 id="startasync-and-stopasync-implementations">StartAsync() and StopAsync() implementations</h2><p>The implementation is quite simple, Consul has everything ready for us for registration and deregistration with the <code>AgentServiceRegistration</code> class. We&apos;re going to register in <code>StartAsync()</code> and deregister on <code>StopAsync()</code>. Side-note, just as a security we&apos;re going to deregister the existing id before registering it.</p><p>We&apos;re going to use everything we put in our appsettings, just like that in <code>StartAsync()</code>:</p><figure class="kg-card kg-code-card"><pre><code class="language-csharp">public async Task StartAsync(CancellationToken cancellationToken)
{
    Console.WriteLine(&quot;Registering service to Consul&quot;);

    var serviceRegistration = new AgentServiceRegistration()
    {
        Address = _configuration[&quot;CommandsHttp:Address&quot;],
        Port = int.Parse(_configuration[&quot;CommandsHttp:Port&quot;]),
        Name = _configuration[&quot;CommandsHttp:Name&quot;],
        ID = _configuration[&quot;CommandsHttp:Id&quot;]
    };

    try {
        await _consulClient.Agent.ServiceDeregister(serviceRegistration.ID, cancellationToken);
        await _consulClient.Agent.ServiceRegister(serviceRegistration, cancellationToken);
    }
    catch (Exception ex) {
        Console.WriteLine($&quot;Unable to register to Consul: {ex.Message}&quot;);
    }
}</code></pre><figcaption><code>ConsulRegisterHostedService</code> <code>StartAsync()</code> implementation</figcaption></figure><p>And for the <code>StopAsync()</code> implementation:</p><figure class="kg-card kg-code-card"><pre><code class="language-csharp">public async Task StopAsync(CancellationToken cancellationToken)
{
    Console.WriteLine(&quot;Deregistering service to Consul&quot;);
    try {
        await _consulClient.Agent.ServiceDeregister(_configuration[&quot;CommandsHttp:Id&quot;], cancellationToken);
    }
    catch (Exception ex) {
        Console.WriteLine($&quot;Unable to deregister to Consul: {ex.Message}&quot;);
    }
}</code></pre><figcaption><code>ConsulRegisterHostedService</code> <code>StartAsync()</code> implementation</figcaption></figure><p>Pretty straightforward, just put a try-catch block (especially on startup) because something could go wrong and we don&apos;t want a HostedService to fail ungracefully. For instance, if Consul server was not available.</p><p>One improvement could be a retry-mechanism in case Consul is not available; we&apos;re not going to bother here but this might be a good idea in production to avoid orphaned services.</p><p>Now check that you correctly register your service in your Consul management page (http://localhost:8500):</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://www.pa-roy.com/content/images/2022/08/image-8.png" class="kg-image" alt loading="lazy" width="1888" height="494" srcset="https://www.pa-roy.com/content/images/size/w600/2022/08/image-8.png 600w, https://www.pa-roy.com/content/images/size/w1000/2022/08/image-8.png 1000w, https://www.pa-roy.com/content/images/size/w1600/2022/08/image-8.png 1600w, https://www.pa-roy.com/content/images/2022/08/image-8.png 1888w" sizes="(min-width: 720px) 720px"><figcaption>Consul Services</figcaption></figure><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://www.pa-roy.com/content/images/2022/08/image-9.png" class="kg-image" alt loading="lazy" width="1014" height="496" srcset="https://www.pa-roy.com/content/images/size/w600/2022/08/image-9.png 600w, https://www.pa-roy.com/content/images/size/w1000/2022/08/image-9.png 1000w, https://www.pa-roy.com/content/images/2022/08/image-9.png 1014w" sizes="(min-width: 720px) 720px"><figcaption>CommandsHttp is configured to localhost:6000</figcaption></figure><p>Now kill you app and check you no longer have the service; it should be good!<br>If you stay on the page you should have an error message:</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://www.pa-roy.com/content/images/2022/08/image-10.png" class="kg-image" alt loading="lazy" width="1364" height="466" srcset="https://www.pa-roy.com/content/images/size/w600/2022/08/image-10.png 600w, https://www.pa-roy.com/content/images/size/w1000/2022/08/image-10.png 1000w, https://www.pa-roy.com/content/images/2022/08/image-10.png 1364w" sizes="(min-width: 720px) 720px"><figcaption>Service deregistered at runtime</figcaption></figure><p>Congratulations!</p><h2 id="kubernetes-build">Kubernetes build</h2><p>Last step for our CommandService configuration, rebuild, push and restart your deployment:<br><code>docker build -t xxx/commandservice .</code> <br><code>docker push xxx/commandservice</code> <br><code>kubectl rollout restart deployment commands-depl</code></p><p>Now check that your service is correctly registered with the production address:</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://www.pa-roy.com/content/images/2022/08/image-11.png" class="kg-image" alt loading="lazy" width="1085" height="388" srcset="https://www.pa-roy.com/content/images/size/w600/2022/08/image-11.png 600w, https://www.pa-roy.com/content/images/size/w1000/2022/08/image-11.png 1000w, https://www.pa-roy.com/content/images/2022/08/image-11.png 1085w" sizes="(min-width: 720px) 720px"><figcaption>CommandsHttp with production address</figcaption></figure><p>All set regarding CommandService HTTP configuration to Consul! Not that difficult right?</p><h1 id="getting-commandshttp-configuration-from-consul">Getting CommandsHttp configuration from Consul</h1><p>Okay now let&apos;s get back to our <code>PlatformService</code>, trust me this will go very smoothly from now on due to our configuration on the previous post.</p><p>First, you can remove the <code>&quot;CommandsService&quot;</code> parameter from all the appsettings (dev &amp; prod): we won&apos;t need it anymore!</p><p>Get back to <code>ConsulService.cs</code>, we&apos;re going to configure our new id (commandshttp):</p><figure class="kg-card kg-code-card"><pre><code class="language-csharp">namespace PlatformService.DiscoveryServices;

public static class ConsulServices 
{
    public const string RabbitMQ = &quot;rabbitmq&quot;;
    public const string CommandsHttp = &quot;commandshttp&quot;;
}</code></pre><figcaption>ConsulService.cs</figcaption></figure><p>Now get back to our <code>HttpCommandDataClient</code>, we&apos;re going to replace what is no longer needed with our Consul service call. What we currently have:</p><figure class="kg-card kg-code-card"><pre><code class="language-csharp">using System.Text;
using System.Text.Json;
using PlatformService.Dto;

namespace PlatformService.SyncDataServices.Http;

public class HttpCommandDataClient : ICommandDataClient
{
    private readonly HttpClient _httpClient;
    private readonly IConfiguration _configuration;

    public HttpCommandDataClient(HttpClient httpClient, IConfiguration configuration)
    {
        _httpClient = httpClient;
        _configuration = configuration;
        Console.WriteLine($&quot;Configuration is on {_configuration[&quot;CommandsService&quot;]}&quot;);
    }

    public async Task SendPlatformToCommandAsync(PlatformReadDto platform)
    {
        var httpContent = new StringContent(
            JsonSerializer.Serialize(platform),
            Encoding.UTF8,
            &quot;application/json&quot;
        );
        var response = await _httpClient.PostAsync($&quot;{ _configuration[&quot;CommandsService&quot;] }/api/c/platforms&quot;, httpContent);

        if (response.IsSuccessStatusCode)
        {
            Console.WriteLine(&quot;Success !&quot;);
        }
        else
        {
            Console.WriteLine(&quot;Error during Sending Platform to command service&quot;);
        }
    }
}</code></pre><figcaption><code>HttpCommandDataClient.cs</code> before</figcaption></figure><!--kg-card-begin: markdown--><p>So the two steps are</p>
<ul>
<li>Remove <code>IConfiguration</code> and add <code>IConsulRegistryService</code>, just like we did for RabbitMQ previously</li>
<li>Replace our configuration hard-coded values with a consul service call</li>
</ul>
<!--kg-card-end: markdown--><p>I&apos;ll skip the constructor and private fields to focus on the <code>SendPlatformToCommandAsync</code> which should look something like this:</p><figure class="kg-card kg-code-card"><pre><code class="language-csharp">public async Task SendPlatformToCommandAsync(PlatformReadDto platform)
{
    try
    {
        var service = _consulRegistryService.GetService(ConsulServices.CommandsHttp);
        if (service == null)
            throw new ArgumentNullException(nameof(service));

        var httpContent = new StringContent(
            JsonSerializer.Serialize(platform),
            Encoding.UTF8,
            &quot;application/json&quot;
        );
        var response = await _httpClient.PostAsync($&quot;http://{service.Address}:{service.Port}/api/c/platforms&quot;, httpContent);

        if (response.IsSuccessStatusCode)
        {
            Console.WriteLine(&quot;Success !&quot;);
        }
        else
        {
            Console.WriteLine(&quot;Error during Sending Platform to command service&quot;);
        }
    }
    catch (Exception ex)
    {
        Console.WriteLine($&quot;Error during Sending Platform to command service: {ex.Message}&quot;);

    }
}</code></pre><figcaption><code>HttpCommandDataClient.cs</code></figcaption></figure><p>Now start your CommandService locally with <code>dotnet run</code>, check it is correctly registered, start your PlatformService with <code>dotnet run</code> and check that the CommandHttp is correctly found and called; you&apos;re all set!</p><p>All that is left is to just build/push/rollout your image for platformservice and check that everything runs correctly.</p><p>And that&apos;s it!</p><h2 id="additional-side-notes">Additional side-notes</h2><p>First of all, we implemented our <code>IConsulRegistryService.GetService()</code> to be synchronous with a &#xAB; dirty&#xA0;&#xBB; <code>var serviceQueryResult = _consulClient.Health.Service(serviceName).Result;</code>. It was necessary considering we were using it in a constructor, but that is quite a waste when we&apos;re using it in an asynchronous method such as <code>SendPlatformToCommandAsync()</code>. If you want to go to production, I would refactor this a bit.</p><p>Secondly, we could wonder why we&apos;re calling our <code>_consulRegistryService</code> each time. It seems quite a waste of time: we could just load it in the constructor and keep it safe in a field.<br>&#x2026;<strong>BUT&#x2026;</strong><br>That would defeat the whole purpose of the operation! In that ecosystem, the services come and go, live and die, and we want to have the most accurate configuration possible, so we <strong>NEED</strong> to call the service each time actually to be sure to have a service that is alive and healthy at this precise moment, not during initialization.</p><p>An additional implementation could be to listen to the updates from Consul in the <code>ConsulRegistryService</code> to keep a track of the services, it could save a few calls to Consul. I think it might be overkill but I&apos;d like your opinion on this&#xA0;!</p><p></p><p>Thank you for reaching the end of the part 3&#xA0;of that tutorial and I hope that you enjoyed it! <br>Right now you should have nearly all the keys to switch to a fully functional Service Discovery system in your Microservices!<br><br>Next up we&apos;re going to do something similar with gRPC, with just a little configuration twist that deserves its own post in my opinion. <br><br>See you!</p><!--kg-card-begin: markdown--><p><strong>This post is part of a whole:</strong></p>
<ul>
<li><a href="https://www.pa-roy.com/net-microservices-service-discovery-part-1/">.NET Microservices: Service Discovery (Part 1: Consul &amp; RabbitMQ Deployment)</a></li>
<li><a href="https://www.pa-roy.com/net-microservices-service-discovery-part-2/">.NET Microservices: Service Discovery (Part 2: Reaching RabbitMQ through Consul)</a></li>
<li>.NET Microservices: Service Discovery (Part 3: Configuring Commands HTTP Service to Consul and consuming it)</li>
<li>.NET Microservices: Service Discovery (Part 4: Configuring Platform gRPC Service to Consul and consuming it)</li>
</ul>
<!--kg-card-end: markdown-->]]></content:encoded></item><item><title><![CDATA[.NET Microservices : Service Discovery (Part 2: Reaching RabbitMQ through Consul)]]></title><description><![CDATA[<p>Welcome back on this blog for the part 2 of my series regarding Service Discovery for .NET Services.</p><p>If you haven&apos;t seen the beginning of the series I recommand you check <a href="https://www.pa-roy.com/net-microservices-service-discovery-part-1/">the first post</a>, along with the <a href="https://www.youtube.com/watch?v=DgVjEo3OGBI">base course from Les Jackson</a>.</p><!--kg-card-begin: markdown--><p><strong>This post is part of a</strong></p>]]></description><link>https://www.pa-roy.com/net-microservices-service-discovery-part-2/</link><guid isPermaLink="false">6305190b9bc1aa5974c221e1</guid><dc:creator><![CDATA[Paul Roy]]></dc:creator><pubDate>Mon, 29 Aug 2022 12:16:21 GMT</pubDate><content:encoded><![CDATA[<p>Welcome back on this blog for the part 2 of my series regarding Service Discovery for .NET Services.</p><p>If you haven&apos;t seen the beginning of the series I recommand you check <a href="https://www.pa-roy.com/net-microservices-service-discovery-part-1/">the first post</a>, along with the <a href="https://www.youtube.com/watch?v=DgVjEo3OGBI">base course from Les Jackson</a>.</p><!--kg-card-begin: markdown--><p><strong>This post is part of a whole:</strong></p>
<ul>
<li><a href="https://www.pa-roy.com/net-microservices-service-discovery-part-1/">.NET Microservices: Service Discovery (Part 1: Consul &amp; RabbitMQ Deployment)</a></li>
<li>.NET Microservices: Service Discovery (Part 2: Reaching RabbitMQ through Consul)</li>
<li><a href="https://www.pa-roy.com/net-microservices-service-discovery-part-3/">.NET Microservices: Service Discovery (Part 3: Configuring Commands HTTP Service to Consul and consuming it)</a></li>
<li>.NET Microservices: Service Discovery (Part 4: Configuring Platform gRPC Service to Consul and consuming it)</li>
</ul>
<!--kg-card-end: markdown--><p>So &#x2014; where were we? We deployed our Consul Server and we configured RabbitMQ to register to Consul.</p><p>What&apos;s left to to? Simply call the Consul Server from our .NET projects to get the required data to call.</p><p>I used some parts of <strong>TechyMaki</strong>&apos;s video about Consul, find out more here:</p><figure class="kg-card kg-embed-card"><iframe width="200" height="113" src="https://www.youtube.com/embed/RBtk6c8YxNQ?feature=oembed" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen title="Consuming Healthy .NET Core Service Instances from Hashicorp Consul &#x1F9ED;"></iframe></figure><p>I will start with <code>PlatformService</code> because it was the first project we started working on. In the end I&apos;ll recap quickly how to do it for <code>CommandService</code> but it&apos;s very similar and probably a good excercise to try to do it without any help for the second one.</p><h1 id="installing-consul-inject-the-client">Installing Consul &amp; Inject the Client</h1><h2 id="nuget-package-appsettingsjson">Nuget Package &amp; appsettings.json</h2><p>The very beginning is to download and install the <code>Consul</code> framework from the NuGet feed. I like to use the <code>NuGet Gallery</code> extension but you can also add it simply with the command line <code>dotnet add package Consul</code> from your PlatformService folder.</p><p>We will require two parameters for Consul: <code>ConsulAddress</code> and <code>ConsulPort</code>. Open your <code>appsettings.Development.json</code> and add the following parameters to your existing configuration:</p><figure class="kg-card kg-code-card"><pre><code class="language-json">{
  (&#x2026;),  
  &quot;ConsulAddress&quot;: &quot;localhost&quot;,
  &quot;ConsulPort&quot;: &quot;8500&quot;
}</code></pre><figcaption>appsettings.Development.json</figcaption></figure><p>Locally, we are using the LoadBalancer with localhost and the default port of Consul, <code>8500</code></p><p>You can already configure the <code>appsettings.Production.json</code> as we already have the necessary data to do so:</p><figure class="kg-card kg-code-card"><pre><code class="language-json">{
  (&#x2026;),
  &quot;ConsulAddress&quot;: &quot;consul-clusterip-srv&quot;,
  &quot;ConsulPort&quot;: &quot;8500&quot;
}</code></pre><figcaption>appsettings.Production.json</figcaption></figure><p>We are simply using the <code>consul-clusterip-srv</code> wich is the routing we have configured inside our Kubernetes cluster.</p><p><strong>While you&apos;re at it: you can remove the <code>RabbitMQHost</code> and the <code>RabbitMQPort</code> from both configuration files</strong>. We won&apos;t need it anymore, as Consul will give us the information.</p><h2 id="injecting-our-iconsulclient">Injecting our IConsulClient</h2><p>We are going to use dependency injection to inject the <code>IConsulClient</code>, which is the client provided by our Consul NuGet package to interact with the server.</p><p>There is a few possibilities here, I chose to use a Singleton and to configure the Consul parameters from the Configuration on the go. For that, get to your <code>Program.cs</code> (or <code>Startup.cs</code> on .NET5.0) and add the service injection:</p><figure class="kg-card kg-code-card"><pre><code class="language-csharp">(&#x2026;)

services.AddSingleton&lt;IConsulClient, ConsulClient&gt;(serviceProvider =&gt;
{
    var conf = serviceProvider.GetService&lt;IConfiguration&gt;();
    var address = conf?[&quot;ConsulAddress&quot;];
    var port = conf?[&quot;ConsulPort&quot;];
    
    Console.WriteLine($&quot;Configuring Consul at http://{address}:{port}&quot;);
    
    return new ConsulClient(config =&gt;
    {
        config.Address = new Uri($&quot;http://{address}:{port}&quot;);
    });
});

(&#x2026;)</code></pre><figcaption><code>Program.cs</code></figcaption></figure><p>We&apos;re using the singleton constructor that provides us the <code>ServiceProvider</code> in order to get the parameters we defined in our appsettings (<code>ConsulAddress</code> and <code>ConsulPort</code>). The <code>?</code> are null-check operators as .NET6.0 is sensitive on this topic.</p><p>At this point, don&apos;t hesitate to <code>dotnet run</code> your project to check you are correctly injecting your parameters and that your <code>ConsulClient</code> is correctly initialized.</p><h1 id="creating-the-iconsulregistryservice-and-its-lifecycle">Creating the IConsulRegistryService and its lifecycle</h1><p>We&apos;re now ready to create the (.net) service that will help us find the other (consul) services through our Consul Server. We could use the client directly, but it will be clearly cleaner to create this <code>RegistryService</code>.</p><p>Create a new folder at the root of the PlatformService project, that we will name <code>DiscoveryServices</code></p><p>Inside, we&apos;ll first create an interface we will name <code>IConsulRegistryService.cs</code> with the following code :</p><figure class="kg-card kg-code-card"><pre><code class="language-csharp">using Consul;

namespace PlatformService.DiscoveryServices;

public interface IConsulRegistryService
{
    AgentService? GetService(string serviceName);
}</code></pre><figcaption><code>IConsulRegistryService.cs</code></figcaption></figure><p>This will be a simple service that will return the configuration for a serviceName provided.</p><p>In the same folder, we will also create a class to store the keys we can use, with a file named <code>ConsulServices.cs</code>:</p><figure class="kg-card kg-code-card"><pre><code class="language-csharp">namespace PlatformService.DiscoveryServices;

public static class ConsulServices 
{
    public const string RabbitMQ = &quot;rabbitmq&quot;;
}</code></pre><figcaption><code>ConsulServices.cs</code></figcaption></figure><p>And finally, our <code>ConsulRegistryService.cs</code>. This class will implement <code>IConsulRegistryService</code> and we&apos;ll inject two parameters in the constructor: our <code>IConsulClient</code> and the <code>IWebHostEnvironment</code>. I&apos;ll explain later why we need it.</p><p>Your file should look like this: </p><pre><code class="language-csharp">using Consul;

namespace PlatformService.DiscoveryServices;

public class ConsulRegistryService : IConsulRegistryService
{
    private readonly IConsulClient _consulClient;
    private readonly IWebHostEnvironment _webHostEnvironment;

    public ConsulRegistryService(IConsulClient consulClient, 
                                 IWebHostEnvironment webHostEnvironment)
    {
        _consulClient = consulClient;
        _webHostEnvironment = webHostEnvironment;
    }

    public AgentService? GetService(string serviceName) {
		throw new NotImplementedException();
    }
}</code></pre><p>We&apos;re going to implement this method a little bit later; right now let&apos;s focus on injecting and using this.</p><p>As always, let&apos;s get back to <code>Program.cs</code> (or <code>Startup.cs</code>) to create our Singleton. It&apos;s a basic init like we always did. As a measure of security, I always put it after its dependencies (so here after <code>IConsulClient</code> singleton definition):</p><figure class="kg-card kg-code-card"><pre><code class="language-csharp">(&#x2026;)

services.AddSingleton&lt;IConsulRegistryService, ConsulRegistryService&gt;();

(&#x2026;)</code></pre><figcaption><code>Program.cs</code></figcaption></figure><p>And as simple as that, we have injected our service. Now let&apos;s use it!</p><h1 id="getting-the-rabbitmq-configuration">Getting the RabbitMQ configuration</h1><p>Now that we created our service, let&apos;s get back to the <code>MessageBusClient</code> where we did our RabbitMQConfiguration. Let&apos;s focus on the constructor, that&apos;s the only thing we&apos;ll need to change.</p><p>Right now your client should look something like this:</p><figure class="kg-card kg-code-card"><pre><code class="language-csharp">public class MessageBusClient : IMessageBusClient
{
    private readonly IConfiguration _configuration;
    private readonly IConnection _connection;
    private readonly IModel _channel;

    public MessageBusClient(IConfiguration configuration)
    {
        _configuration = configuration;
        var factory = new ConnectionFactory()
        {
            HostName = _configuration[&quot;RabbitMQHost&quot;],
            Port = int.Parse(_configuration[&quot;RabbitMQPort&quot;])
        };
        try
        {
            _connection = factory.CreateConnection();
            _channel = _connection.CreateModel();

            _channel.ExchangeDeclare(exchange: &quot;trigger&quot;, type: ExchangeType.Fanout);

            _connection.ConnectionShutdown += RabbitMQ_ConnectionShutdown;

            Console.WriteLine(&quot;--&gt; Connected to MessageBus&quot;);
        }
        catch (Exception ex)
        {
            Console.WriteLine($&quot;--&gt; Could not connect to the Message Bus: {ex.Message}&quot;);
        }
    }
(&#x2026;)

}</code></pre><figcaption><code>MessageBusClient.cs</code> (the old one)</figcaption></figure><p>First of all we will need to inject our <code>IConsulRegistryService</code> to the constructor. You can also drop the <code>IConfiguration</code>: we won&apos;t need it anymore.</p><p>We are going to get the service informations from our RegistryService (Address &amp; Port) and inject it instead of <code>IConfiguration[&quot;RabbitMQHost&quot;]</code> (and port). Considering our service CAN be null (if there is none available), you should move your code inside the try-catch block and null-check your data, just like this:</p><figure class="kg-card kg-code-card"><pre><code class="language-csharp">public class MessageBusClient : IMessageBusClient
{
    private readonly IConsulRegistryService _consulRegistryService;
    private readonly IConnection _connection;
    private readonly IModel _channel;

    public MessageBusClient(IConsulRegistryService consulRegistryService)
    {
        try
        {
            var service = _consulRegistryService.GetService(ConsulServices.RabbitMQ);
            if (service == null)
                throw new ArgumentNullException(nameof(service));
                
            var factory = new ConnectionFactory()
            {
                HostName = service.Address,
                Port = service.Port
            };
            
            (&#x2026;)
        }
        catch (Exception ex)
        {
            Console.WriteLine($&quot;--&gt; Could not connect to the Message Bus: {ex.Message}&quot;);
        }
    }
(&#x2026;)

}</code></pre><figcaption><code>MessageBusClient.cs</code> (the new one)</figcaption></figure><p>We are simply calling the newly created service to find the RabbitMQ configuration.</p><p>At this point you can <code>dotnet run</code> your project, but you should get a <code>NotImplementException</code> from our new service.</p><h1 id="implementing-the-getservice-method">Implementing the GetService method</h1><p>Let&apos;s talk implementation. What we will need is to ask our Consul client for a healthy service. I won&apos;t get into details about service lifecycle, here we are only focusing on getting things done; this could be improved with more finesse.</p><p>To keep it simple, I also did not take into consideration any async method. Indeed, we are using our <code>GetService(&#x2026;)</code> in a constructor so I used the <code>.Result</code> method to keep it synchronous. Not that clean, if we wanted to do something clean we would have to go further, but our mind is set on getting things done here so there will be room for improvement if you want to go to production.</p><p>Now the implementation looks like that:</p><figure class="kg-card kg-code-card"><pre><code class="language-csharp">public AgentService? GetService(string serviceName) {
    Console.WriteLine($&quot;Looking for service {serviceName}&quot;);

    var serviceQueryResult = _consulClient.Health.Service(serviceName).Result;
    var nbServices = serviceQueryResult?.Response?.Length;
    if (nbServices &gt; 0)
    {
        Console.WriteLine($&quot;{nbServices} service(s) found&quot;);
        var service = serviceQueryResult?.Response[0]!;
        return service.Service;
    }
    else
    {
        Console.WriteLine($&quot;Service not found&quot;);
        return null;
    }
}</code></pre><figcaption><code>ConsulRegistryService.cs</code></figcaption></figure><p>Simply put: we call Consul for a Healthy Service matching the name, we return the first result. Again, a lot could be done to improve it but it&apos;s a decent implementation to start.</p><p>Now <strong>in theory</strong> we could test it all the way locally, but if we do we&apos;re going to hit a rock.</p><p>Remember when we defined our <code>RabbitMQ</code> configuration for Kubernetes? We did something that will actually be a problem for a local test:<br></p><figure class="kg-card kg-code-card"><pre><code class="language-yaml">apiVersion: v1
kind: ConfigMap
metadata:
  name: rabbitmq-config
data:
  enabled_plugins: |
      [rabbitmq_management,rabbitmq_management_agent,rabbitmq_mqtt,rabbitmq_stomp,rabbitmq_peer_discovery_consul].
  rabbitmq.conf: |
      log.console = true 
      loopback_users.guest = false
      cluster_formation.peer_discovery_backend = consul
      cluster_formation.consul.host = consul-clusterip-srv
      cluster_formation.consul.svc = rabbitmq
      cluster_formation.consul.svc_addr = rabbitmq-clusterip-srv</code></pre><figcaption><code>rabbitmq-depl.yaml</code></figcaption></figure><p>Can you see it?</p><p>&#x2026;</p><p>&#x2026;</p><p>That&apos;s right, we registered RabbitMQ with the <code>rabbitmq-clusterip-srv</code> service address. Now this won&apos;t be a problem in production, but it won&apos;t work locally because it&apos;s an internal address.</p><p>My solution here was to add a small snippet of code to rewrite addresses during development. It&apos;s not the best and we usually try to avoid this kind of workaround, but all the &#xAB; proper&#xA0;&#xBB; methods were furiously more complicated in my opinion than two lines of codes.<br>That&apos;s where our <code>IWebHostEnvironment</code> comes to light, with a final implementation looking like that:</p><pre><code class="language-csharp">public AgentService? GetService(string serviceName) {
    Console.WriteLine($&quot;Looking for service {serviceName}&quot;);

    var serviceQueryResult = _consulClient.Health.Service(serviceName).Result;
    var nbServices = serviceQueryResult?.Response?.Length;
    if (nbServices &gt; 0)
    {
        Console.WriteLine($&quot;{nbServices} service(s) found&quot;);
        var service = serviceQueryResult?.Response[0]!;
        if (_webHostEnvironment.IsDevelopment())
            service.Service.Address = &quot;localhost&quot;;
            
        return service.Service;
    }
    else
    {
        Console.WriteLine($&quot;Service not found&quot;);
        return null;
    }
}</code></pre><p>PHEW! Finally!</p><p>Now let&apos;s start our project with <code>dotnet run</code>, you should see something like this in your logs when you call for any method in the <code>PlatformController</code> (the reason is the singleton is initialized when injected, so you won&apos;t see it at startup):</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://www.pa-roy.com/content/images/2022/08/image-3.png" class="kg-image" alt loading="lazy" width="568" height="144"><figcaption>Logs looking for rabbitmq</figcaption></figure><p>Now all you have to do is rebuild your image: <code>docker build -t xxx/platformservice .</code></p><p>Push it: <code>docker push xxx/platformservice</code></p><p>And restart your deployment: <code>kubectl rollout restart deployment platforms-depl</code></p><p>And you should see the same results with your Kubernetes API:</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://www.pa-roy.com/content/images/2022/08/image-4.png" class="kg-image" alt loading="lazy" width="429" height="285"><figcaption>Docker Desktop Logs from PlatformService K8S container</figcaption></figure><h1 id="now-do-it-again-with-commandservice">Now do it again with CommandService</h1><p>Ready for a challenge? Let&apos;s do it again with <code>CommandService</code>: it&apos;s exactly the same.</p><!--kg-card-begin: markdown--><ul>
<li>Add Consul to .net project</li>
<li>Update your appsettings (dev+prod, remove RabbitMQ parameters and add Consul parameters)</li>
<li>Create the <code>IConsulClient</code> dependency injection and use the appsettings values</li>
<li>Create and implement the <code>IConsulRegistryService</code> + <code>ConsulRegistryService</code> (and <code>ConsulServices</code>)</li>
<li>Update the <code>MessageBusSuscriber</code> to replace the <code>IConfiguration</code> hardcoded values of RabbitMQ by the call to <code>IConsulRegistryService</code></li>
<li>Test locally</li>
<li>Test with Kubernetes</li>
</ul>
<!--kg-card-end: markdown--><p></p><p>Now that we have consumed our first service with Consul, it&apos;s time to get hard: we will now register our own services and consume them.</p><p>See you in the next post!</p><!--kg-card-begin: markdown--><p><strong>This post is part of a whole:</strong></p>
<ul>
<li><a href="https://www.pa-roy.com/net-microservices-service-discovery-part-1/">.NET Microservices: Service Discovery (Part 1: Consul &amp; RabbitMQ Deployment)</a></li>
<li>.NET Microservices: Service Discovery (Part 2: Reaching RabbitMQ through Consul)</li>
<li><a href="https://www.pa-roy.com/net-microservices-service-discovery-part-3/">.NET Microservices: Service Discovery (Part 3: Configuring Commands HTTP Service to Consul and consuming it)</a></li>
<li>.NET Microservices: Service Discovery (Part 4: Configuring Platform gRPC Service to Consul and consuming it)</li>
</ul>
<!--kg-card-end: markdown-->]]></content:encoded></item><item><title><![CDATA[.NET Microservices : Service Discovery (Part 1: Consul & RabbitMQ Deployment)]]></title><description><![CDATA[<p>Hey there, it&apos;s been a long time!</p><p>I have discovered a few monthes ago the AMAZING course by <strong>Les Jackson</strong> about microservices with .Net Core.<br>I cannot recommand it enough, it&apos;s a freaking gold mine and a pleasure to watch and to develop alongside this incredible</p>]]></description><link>https://www.pa-roy.com/net-microservices-service-discovery-part-1/</link><guid isPermaLink="false">6304e2cc5445ab163f4ff237</guid><category><![CDATA[microservices]]></category><category><![CDATA[.net]]></category><category><![CDATA[rabbitmq]]></category><category><![CDATA[consul]]></category><dc:creator><![CDATA[Paul Roy]]></dc:creator><pubDate>Tue, 23 Aug 2022 15:46:08 GMT</pubDate><content:encoded><![CDATA[<p>Hey there, it&apos;s been a long time!</p><p>I have discovered a few monthes ago the AMAZING course by <strong>Les Jackson</strong> about microservices with .Net Core.<br>I cannot recommand it enough, it&apos;s a freaking gold mine and a pleasure to watch and to develop alongside this incredible teacher. And it&apos;s entirely free. For such a good material to be free is just an opportunity no-one should miss.</p><p>You can find it here and I strongly recommand to follow it:</p><figure class="kg-card kg-embed-card"><iframe width="200" height="113" src="https://www.youtube.com/embed/DgVjEo3OGBI?feature=oembed" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen title=".NET Microservices &#x2013; Full Course"></iframe></figure><p>Les Jackson finishes his course on final thoughts with what could be improved. Today I want to get into details with <strong>&#xAB; Service Discovery&#xA0;&#xBB;</strong> which is in my opinion the most relevant feature to add after the course. We&apos;re going to improve this course by including an Open-Source Service Discovery. </p><p>Amongst the choices, I found both Eureka (by Netflix) and Consul to be the best options. I chose the latter - Consul - for various reasons and we&apos;re going to implement it together.</p><!--kg-card-begin: markdown--><p><strong>This post is part of a whole:</strong></p>
<ul>
<li>.NET Microservices: Service Discovery (Part 1: Consul &amp; RabbitMQ Deployment)</li>
<li><a href="https://www.pa-roy.com/net-microservices-service-discovery-part-2/">.NET Microservices: Service Discovery (Part 2: Reaching RabbitMQ through Consul)</a></li>
<li><a href="https://www.pa-roy.com/net-microservices-service-discovery-part-3/">.NET Microservices: Service Discovery (Part 3: Configuring Commands HTTP Service to Consul and consuming it)</a></li>
<li>.NET Microservices: Service Discovery (Part 4: Configuring Platform gRPC Service to Consul and consuming it)</li>
</ul>
<!--kg-card-end: markdown--><p></p><p>These posts are starting right at the end of his course. I strongly advise you to do all the course before getting into my posts, <a href="https://github.com/binarythistle/S04E03---.NET-Microservices-Course-">but you can also find the whole content on GitHub</a>. You can start from the repo but I will assume you have all the basics to continue this.</p><p>I should warn you that I did the whole course in .NET 6.0. There is not a lot of differences, but you might find a few new syntax code lines such as <code>namespace xx;</code> or <code>= default!</code> for non-nullable parameters. None of my code relies on .NET 6.0 so you should be fine if you&apos;re still on .NET 5.0 but you might have to update a few lines. Feel free to contact me if you have any issue.</p><h1 id="setting-up-consul">Setting up Consul</h1><p>I won&apos;t get into details of what Consul exactly is, I think you can find a lot on the internet explaining it better than me. <br>What you&apos;ll have to know is that it&apos;s basically <em>a server that can register services with keys and routes</em> which can be called by other services.<br>The main goal is to avoid configuring services with remote addresses of other services but rather configure services with their own informations for others to ask Consul for it.<br><br>First things first, we&apos;ll create a new deployment file in <code>K8S</code> : <code>consul-depl.yaml</code>. You should now be familiar with the yaml syntax but I&apos;ll explain a few things at the best of my ability.</p><p>There is 3&#xA0;blocks, <code>Deployment</code>, <code>Service (ClusterIp)</code> and <code>Service (Load Balancer)</code>. It&apos;s actually quite straightforward and very similar to what we did with RabbitMQ.</p><p>Deployment:</p><figure class="kg-card kg-code-card"><pre><code class="language-yaml">apiVersion: apps/v1
kind: Deployment
metadata:
  name: consul-depl
spec:
  replicas: 1
  selector:
    matchLabels:
      app: consul
  template:
    metadata:
      labels:
        app: consul
    spec:
      containers:
        - name: consul
          image: consul:latest
          ports:
            - containerPort: 8500
              name: consul-tcp-port
            - containerPort: 8600
              name: consul-udp-port</code></pre><figcaption><code>consul-depl.yaml</code></figcaption></figure><p>Again, It&apos;s pretty similar to RabbitMQ, the only difference is the port configuration. Consul uses <code>8500</code> for TCP and <code>8600</code> for UDP. I found other ports for other purposes, but we&apos;ll be fine with these two.<br>Here are the services (ClusterIp and LoadBalancer), I won&apos;t get into details because it&apos;s pretty straightforward: we&apos;re configuring a ClusterIp to route within Kubernetes and a LoadBalancer to access it.</p><figure class="kg-card kg-code-card"><pre><code class="language-yaml">---
apiVersion: v1
kind: Service
metadata:
  name: consul-clusterip-srv
spec:
  selector:
    app: consul
  type: ClusterIP
  ports:
    - name: consul-tcp-port
      protocol: TCP
      port: 8500
      targetPort: 8500
    - name: consul-udp-port
      protocol: UDP
      port: 8600
      targetPort: 8600
---
apiVersion: v1
kind: Service
metadata:
  name: consul-loadbalancer
spec:
  selector:
    app: consul
  type: LoadBalancer
  ports:
    - name: consul-tcp-port
      protocol: TCP
      port: 8500
      targetPort: 8500
    - name: consul-udp-port
      protocol: UDP
      port: 8600
      targetPort: 8600</code></pre><figcaption><code>consul-depl.yaml</code></figcaption></figure><p>All we have to do is apply it with the classic kubectl command: <code>kubectl apply -f consul-depl.yaml</code>.</p><p>You should now be able to browse <a href="http://localhost:8500/"><code>http://localhost:8500/</code></a> and get something like that: </p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://www.pa-roy.com/content/images/2022/08/image.png" class="kg-image" alt loading="lazy" width="1440" height="681" srcset="https://www.pa-roy.com/content/images/size/w600/2022/08/image.png 600w, https://www.pa-roy.com/content/images/size/w1000/2022/08/image.png 1000w, https://www.pa-roy.com/content/images/2022/08/image.png 1440w" sizes="(min-width: 720px) 720px"><figcaption>Main Management Page of Consul</figcaption></figure><p>If that&apos;s the case, Congratulations! You have configured the Service Discovery Server we&apos;ll be using for the rest of the posts.</p><p>Next up, we&apos;ll be setting up RabbitMQ to register to Consul.</p><h1 id="configure-rabbitmq-to-prepare-for-consul">Configure RabbitMQ to prepare for Consul</h1><p>Now this part is a bit tricky, because we&apos;re going to update our RabbitMQ deployment to set it up to connect automatically to Consul. </p><p>The good news is, <a href="https://www.rabbitmq.com/cluster-formation.html#peer-discovery-consul">RabbitMQ supports Peer Discovery Using Consul with a plugin</a>! All we have to do is set up the configuration files to automatically register. The bad news is, we&apos;re going to have to configure a bit more as we&apos;re not going to use the default settings anymore. Nothing too tricky but it was a bit daunting to do.</p><p>This will be done with a new configuration element of Kubernetes: <code>ConfigMap</code>. Let&apos;s open <code>rabbitmq-depl.yaml</code> to add the following config map:</p><figure class="kg-card kg-code-card"><pre><code class="language-yaml">---
apiVersion: v1
kind: ConfigMap
metadata:
  name: rabbitmq-config
data:
  enabled_plugins: |
      [rabbitmq_management,rabbitmq_management_agent,rabbitmq_mqtt,rabbitmq_stomp].
  rabbitmq.conf: |
      log.console = true 
      loopback_users.guest = false</code></pre><figcaption><code>rabbitmq-depl.yaml</code></figcaption></figure><p>What you&apos;re seing here is the default configuration I found for RabbitMQ. It already embeds a few plugins, and it is configured to log to console and to allow the guest user to go through loopback. <br>If you fail to configure the guest user, you won&apos;t be able to connect to the management page and you&apos;ll get the following message: <code>users can only log in via localhost</code>.</p><p><strong>WARNING: The dot (&#xAB;&#xA0;.&#xA0;&#xBB;) at the end of enabled_plugins is mandatory. Failing to add it will prevent you from starting RabbitMQ.</strong></p><p>Next up we&apos;re going to configure the Deployment to access to these elements of configuration, like that: </p><figure class="kg-card kg-code-card"><pre><code class="language-yaml">apiVersion: apps/v1
kind: Deployment
metadata:
  name: rabbitmq-depl
spec:
  replicas: 1
  selector:
    matchLabels:
      app: rabbitmq
  template:
    metadata:
      labels:
        app: rabbitmq
    spec:
      containers:
        - name: rabbitmq
          image: rabbitmq:3-management
          ports:
            - containerPort: 15672
              name: rbmq-mgmt-port
            - containerPort: 5672
              name: rbmq-msg-port
          volumeMounts:
            - name: config-volume
              mountPath: /etc/rabbitmq
      volumes:
        - name: config-volume
          configMap:
            name: rabbitmq-config
            items:
              - key: rabbitmq.conf
                path: rabbitmq.conf
              - key: enabled_plugins
                path: enabled_plugins</code></pre><figcaption><code>rabbitmq-depl.yaml</code></figcaption></figure><p>We added the <code>volumes</code> property, which maps the <code>rabbitmq-config</code> to two files, <code>rabbitmq.conf</code> and <code>enabled_plugins</code>. These are the informations we put earlier in the file with the ConfigMap.<br>Then we added the <code>volumeMounts</code> property to the container, which maps the config volume to <code>/etc/rabbitmq</code>, which is the folder where RabbitMQ will find its config.</p><p>Just reapply and restart with <code>kubectl apply -f rabbitmq-depl.yaml</code> and <code>kubectl rollout restart deployment rabbitmq-depl</code></p><p>Everything should be the same as before. If you have an error at this point, fix it first by checking the logs of the RabbitMQ container through Docker Desktop (or with the console): </p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://www.pa-roy.com/content/images/2022/08/image-1.png" class="kg-image" alt loading="lazy" width="1688" height="817" srcset="https://www.pa-roy.com/content/images/size/w600/2022/08/image-1.png 600w, https://www.pa-roy.com/content/images/size/w1000/2022/08/image-1.png 1000w, https://www.pa-roy.com/content/images/size/w1600/2022/08/image-1.png 1600w, https://www.pa-roy.com/content/images/2022/08/image-1.png 1688w" sizes="(min-width: 720px) 720px"><figcaption>Logs from RabbitMQ Instance in Docker Desktop</figcaption></figure><h1 id="configure-rabbitmq-with-consul">Configure RabbitMQ with Consul</h1><p>Now that you have the few elements required to configure RabbitMQ, we&apos;re going to add the <code>rabbitmq_peer_discovery_consul</code> plugin and its configuration to the <code>ConfigMap</code> of <code>rabbitmq-depl.yaml</code> (update it, do not create a new one):</p><figure class="kg-card kg-code-card"><pre><code class="language-yaml">apiVersion: v1
kind: ConfigMap
metadata:
  name: rabbitmq-config
data:
  enabled_plugins: |
      [rabbitmq_management,rabbitmq_management_agent,rabbitmq_mqtt,rabbitmq_stomp,rabbitmq_peer_discovery_consul].
  rabbitmq.conf: |
      log.console = true 
      loopback_users.guest = false
      cluster_formation.peer_discovery_backend = consul
      cluster_formation.consul.host = consul-clusterip-srv
      cluster_formation.consul.svc = rabbitmq
      cluster_formation.consul.svc_addr = rabbitmq-clusterip-srv</code></pre><figcaption><code>rabbitmq-depl.yaml</code></figcaption></figure><p>The configuration should be:</p><!--kg-card-begin: markdown--><ul>
<li><code>cluster_formation.peer_discovery_backend</code> set to <code>consul</code></li>
<li><code>cluster_formation.consul.host</code> should be the ClusterIp you set for Consul, here <code>consul-clusterip-srv</code></li>
<li><code>cluster_formation.consul.svc</code> is the name we&apos;ll use to find our service, here <code>rabbitmq</code></li>
<li><code>cluster_formation.consul.svc_addr</code> is the address we want to share for RabbitMQ so <code>rabbitmq-clusterip-srv</code> if you followed the course</li>
</ul>
<!--kg-card-end: markdown--><p>Again, just reapply and restart with <code>kubectl apply -f rabbitmq-depl.yaml</code> and <code>kubectl rollout restart deployment rabbitmq-depl</code></p><p>Now if you browse your Consul Management page, you should now be able to see RabbitMQ in the services (alongside with consul, you should have two):</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://www.pa-roy.com/content/images/2022/08/image-2.png" class="kg-image" alt loading="lazy" width="1888" height="569" srcset="https://www.pa-roy.com/content/images/size/w600/2022/08/image-2.png 600w, https://www.pa-roy.com/content/images/size/w1000/2022/08/image-2.png 1000w, https://www.pa-roy.com/content/images/size/w1600/2022/08/image-2.png 1600w, https://www.pa-roy.com/content/images/2022/08/image-2.png 1888w" sizes="(min-width: 720px) 720px"><figcaption>Consul Services Page with RabbitMQ service</figcaption></figure><p></p><p>Alright! Be reassured, this was <strong>by far</strong> the most complicated part of the tutorial in my opinion. You have now configured RabbitMQ to register to Consul, all we have to do now is to update our PlatformService and our CommandService to ask Consul for an address (as opposed to setting it up ourselves).</p><p>I was planning on doing it on the same blog post, but let&apos;s be honest I think this one is already compact enough.</p><p>See you in the next post!</p><!--kg-card-begin: markdown--><p><strong>This post is part of a whole:</strong></p>
<ul>
<li>.NET Microservices: Service Discovery (Part 1: Consul &amp; RabbitMQ Deployment)</li>
<li><a href="https://www.pa-roy.com/net-microservices-service-discovery-part-2/">.NET Microservices: Service Discovery (Part 2: Reaching RabbitMQ through Consul)</a></li>
<li><a href="https://www.pa-roy.com/net-microservices-service-discovery-part-3/">.NET Microservices: Service Discovery (Part 3: Configuring Commands HTTP Service to Consul and consuming it)</a></li>
<li>.NET Microservices: Service Discovery (Part 4: Configuring Platform gRPC Service to Consul and consuming it)</li>
</ul>
<!--kg-card-end: markdown-->]]></content:encoded></item><item><title><![CDATA[EFCore: Raw Sql Query with custom types]]></title><description><![CDATA[<!--kg-card-begin: markdown--><p>Hi everyone!<br>
It has been too long since I posted on this blog.</p>
<p>Here is a small article about a workaround I had to do using <strong>ASP.Net Core</strong> and its <strong>Entity Framework Core (EFCore)</strong>.</p>
<p>A very useful method on Entity Framework is the <strong>raw sql query with a custom</strong></p>]]></description><link>https://www.pa-roy.com/raw-sql-query-efcore/</link><guid isPermaLink="false">6300f01d5409ac12ae7550cf</guid><dc:creator><![CDATA[Paul Roy]]></dc:creator><pubDate>Wed, 06 Sep 2017 19:10:31 GMT</pubDate><content:encoded><![CDATA[<!--kg-card-begin: markdown--><p>Hi everyone!<br>
It has been too long since I posted on this blog.</p>
<p>Here is a small article about a workaround I had to do using <strong>ASP.Net Core</strong> and its <strong>Entity Framework Core (EFCore)</strong>.</p>
<p>A very useful method on Entity Framework is the <strong>raw sql query with a custom type</strong>, which goes pretty much like this:</p>
<pre><code class="language-csharp">var myCustomList = await context.Database.SqlQuery&lt;CustomType&gt;(&quot;SELECT col1, col2, &#x2026; FROM MyTable&quot;).ToListAsync();
</code></pre>
<p>This allow you to use <strong>custom types</strong> to define quick out-of-the-box entities / query mapping, and unfortunately <strong>EFCore does not support this</strong> (at least right now).</p>
<p>I could not go without this super-useful method, so I made an extension to support it.</p>
<hr>
<h3 id="basics">Basics</h3>
<p>I chose to use <a href="https://www.nuget.org/packages/AutoMapper/">AutoMapper</a> for the mapping and <a href="https://www.nuget.org/packages/AutoMapper.Data/">AutoMapper.Data</a> which supports implicit <code>IDataReader</code> mapping. (Edit: Note that Jeremy Sinclair wrote a custom method to map the entities that I did no see before, the link is down below).</p>
<p>We need a generic class for the logic (<code>CustomTypeSqlQuery&lt;T&gt;</code>) and an extension to mimic the behavior we like (<code>DatabaseExtensions</code>).</p>
<p>Please beware that <em>only classes are supported, not basic types like string or int</em>.</p>
<hr>
<h3 id="databaseextensions">DatabaseExtensions</h3>
<p>First the extension, in a file named <code>DatabaseExtensions.cs</code>&#xA0;:</p>
<pre><code class="language-csharp">public static class DatabaseExtensions
{
    public static CustomTypeSqlQuery&lt;T&gt; SqlQuery&lt;T&gt;(
    		this DatabaseFacade database, 
    		string sqlQuery) where T : class
    {
        return new CustomTypeSqlQuery&lt;T&gt;() 
        { 
        	DatabaseFacade = database, 
        	SQLQuery = sqlQuery 
        };
    }
}
</code></pre>
<p>This is an extension to <code>DatabaseFacade</code> which will allow us to to something like:</p>
<pre><code class="language-csharp">context.Database.SqlQuery&lt;CustomType&gt;(&quot;SELECT &#x2026; FROM &#x2026;&quot;)
</code></pre>
<p>and returns a <code>CustomTypeSqlQuery&lt;T&gt;</code>, which holds the logic.</p>
<hr>
<h3 id="customtypesqlquery">CustomTypeSqlQuery</h3>
<p>The full class goes like this:</p>
<pre><code class="language-csharp">public class CustomTypeSqlQuery&lt;T&gt; where T : class
{
  private IMapper _mapper;
  
  public DatabaseFacade DatabaseFacade { get; set; }
  public string SQLQuery { get; set; }

  public CustomTypeSqlQuery()
  {
    _mapper = new MapperConfiguration(cfg =&gt; {
        cfg.AddDataReaderMapping();
        cfg.CreateMap&lt;IDataRecord, T&gt;();
    }).CreateMapper();
  }

  public async Task&lt;IList&lt;T&gt;&gt; ToListAsync()
  {
    IList&lt;T&gt; results = new List&lt;T&gt;();
    var conn = DatabaseFacade.GetDbConnection();
    try
    {
      await conn.OpenAsync();
      using (var command = conn.CreateCommand())
      {
        command.CommandText = SQLQuery;
        DbDataReader reader = await command.ExecuteReaderAsync();

        if (reader.HasRows)
          results = _mapper.Map&lt;IDataReader, IEnumerable&lt;T&gt;&gt;(reader)
                           .ToList();
        reader.Dispose();
      }
    }
    finally
    {
        conn.Close();
    }
    return results;
  }

  public async Task&lt;T&gt; FirstOrDefaultAsync()
  {
    T result = null;
    var conn = DatabaseFacade.GetDbConnection();
    try
    {
      await conn.OpenAsync();
      using (var command = conn.CreateCommand())
      {
        command.CommandText = SQLQuery;
        DbDataReader reader = await command.ExecuteReaderAsync();

        if (reader.HasRows)
        {
          var results = _mapper.Map&lt;IDataReader, IEnumerable&lt;T&gt;&gt;(reader)
          					 .ToList();
          result = results.FirstOrDefault();
        }
        reader.Dispose();
      }
    }
    finally
    {
        conn.Close();
    }
    return result;
  }
}

</code></pre>
<p>As you can see, I create the mapping configuration on the go, which allows me not to declare the mapping. <code>cfg.AddDataReaderMapping()</code> is the method that allows me to map <code>IDataReader</code> directly.</p>
<p>Then I added two methods&#xA0;: <code>ToListAsync()</code> and <code>FirstOrDefaultAsync()</code>. It basically uses a connection and a DbDataReader, which is <a href="https://docs.microsoft.com/en-us/aspnet/core/data/ef-mvc/advanced#call-a-query-that-returns-other-types">what Microsoft recommends for raw SQL Queries</a>.</p>
<p>Please note that <code>FirstOrDefaultAsync()</code> is absolutely <s>barbaric</s> inefficient. A better solution would be to parse the results one by one (<code>await reader.ReadAsync()</code>) and return as soon as we have one result. I did this is just for the example.</p>
<hr>
<p>This allows us to use the extension and the class like this:</p>
<pre><code class="language-csharp">var myList = await context.Database.SqlQuery&lt;CustomType&gt;(&quot;SELECT &#x2026; FROM &#x2026;&quot;)
								   .ToListAsync();
</code></pre>
<p>&#xAB;&#xA0;Et voil&#xE0;&#xA0;!&#xA0;&#xBB;</p>
<p>Almost as easy to use as in Entity Framework 6. I am missing support for basic types, it should not be really difficult to do but I do not need it right now. Feel free to contact me if you want your own appendix.</p>
<p>If you want it on github I can do that too.</p>
<p>See you soon!</p>
<p>PS: Jeremy Sinclair did a pretty nice job writing a method to parse from DbDataReader to a class without AutoMapper <a href="https://www.sinclairinat0r.com/2017/05/06/entity-framework-core--mapping-stored-procedures,-fluently">here</a></p>
<!--kg-card-end: markdown-->]]></content:encoded></item><item><title><![CDATA[Xamarin Forms Dictionary To Value Converter]]></title><description><![CDATA[You want to map a set of keys to a set of values in your Xamarin Forms Views? Enjoy the DictionaryToValueConverter, a generic converter for all use-cases.]]></description><link>https://www.pa-roy.com/xamarin-forms-dictionary-to-value-converter/</link><guid isPermaLink="false">6300f01d5409ac12ae7550ce</guid><dc:creator><![CDATA[Paul Roy]]></dc:creator><pubDate>Mon, 02 May 2016 00:51:05 GMT</pubDate><content:encoded><![CDATA[<!--kg-card-begin: markdown--><p>Hi there!</p>
<p><strong>Wanna map a set of keys to a set of values?</strong></p>
<p><strong>You do not want to create a specific converter for each use-case?</strong></p>
<p>I find that normal. Do not let anyone tell you otherwise.</p>
<hr>
<p>Introducing <strong>the brand new</strong> <code>DictionaryToValueConverter</code>:</p>
<pre><code class="language-csharp">public class DictionaryToValueConverter&lt;T, U&gt; : IValueConverter
{
    public IDictionary&lt;T, U&gt; ValuesMapping { get; set; }

    public object Convert(object value, Type targetType, 
    					  object parameter, CultureInfo culture)
    {
        if (ValuesMapping != null)
        {
            var keyT = (T)key;
            if (ValuesMapping.ContainsKey(keyT))
                return ValuesMapping[keyT];
            else
                return default(U);
        }
        else
            return default(U);
    }

    public object ConvertBack(object value, Type targetType, 
    						  object parameter, CultureInfo culture)
    {
        throw new NotImplementedException(); // not relevant
    }
}
</code></pre>
<p>That converter will map a key to a value. For instance it could be <strong>a color for each enum value</strong> (we will get to that).</p>
<hr>
<p>I did not implement the convert back as <strong>you could map several keys to the same value</strong>. It would not be relevant as you could find several keys for the same value. If you still want to you can use something like that:</p>
<pre><code class="language-csharp">public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
	if (ValuesMapping != null)
	{
	    var valueU = (U)value;
	    var kvps = ValuesMapping.Where(kvp =&gt; kvp.Value.Equals(valueU));

	    if (kvps.Any())
	        return kvps.First().Key;
	    else
	        return default(T);
	}
	else
	    return default(T);
}
</code></pre>
<p><strong>But I would not approve that.</strong></p>
<hr>
<p>To declare this awesome converter you can follow the example right here:</p>
<pre><code class="language-csharp">var myEnumToColorConverter = new DictionaryToValueConverter&lt;MyEnum, Color&gt;()
{
	ValuesMapping = new Dictionary&lt;MyEnum, Color&gt;
		{
			{ MyEnum.Enum1, Color.Red },
			{ MyEnum.Enum2, Color.Green },
			{ MyEnum.Enum3, Color.Blue },
			{ MyEnum.Enum4, Color.Yellow }
		}
};
</code></pre>
<p>And to use it:</p>
<pre><code class="language-csharp">myObject.SetBinding&lt;ObservableObject&gt;(MyObject.ColorProperty, 
								      o =&gt; o.EnumValue, 
                                      converter: myEnumToColorConverter);
</code></pre>
<p>All done.</p>
<p>Of course you can also use:</p>
<pre><code class="language-csharp">SetBinding(MyObject.ColorProperty, new Binding(&quot;EnumValue&quot;, converter: myEnumToColorConverter))
</code></pre>
<p>I am not a monster. Do whatever you want. Use XAML if you prefer.</p>
<hr>
<p>Last-minute tips:</p>
<p>Do not declare a converter per view. Create a converter and use it for all your views.</p>
<p>Do not create too complex things. The simpler the better, if you are re-creating the earth each time you might want to create a specific converter.</p>
<p>In short words: be smart.</p>
<hr>
<p>Paul, out!</p>
<!--kg-card-end: markdown-->]]></content:encoded></item><item><title><![CDATA[Xamarin Forms  Lambda To Boolean Converter]]></title><description><![CDATA[Ever had the issue to convert a lambda expression into a boolean in your views? Seek no more, here is a lambda expression converter for Xamarin Forms.]]></description><link>https://www.pa-roy.com/lambdatobooleanconverter/</link><guid isPermaLink="false">6300f01d5409ac12ae7550cd</guid><dc:creator><![CDATA[Paul Roy]]></dc:creator><pubDate>Mon, 14 Mar 2016 17:23:09 GMT</pubDate><content:encoded><![CDATA[<!--kg-card-begin: markdown--><p>Hi there!</p>
<p>Ever had the issue to <strong>convert</strong> a more or less complex <strong>lambda expression</strong> into a boolean in a <strong>Xamarin Forms view</strong>?</p>
<p>Like &#xAB;&#xA0;I want to show something only for <strong>a property that matches my condition</strong>&#xA0;&#xBB;?</p>
<p>Ever had the error: <code>System.ArgumentException: Invalid expression type</code>?</p>
<hr>
<p><u><strong>/!\</strong></u> Warning: this article could cause severe bleeding for the eyes of the purist. This is kind of a hack. I know that. Defining a lambda in the view, etc. <u><strong>/!\</strong></u></p>
<hr>
<p>Well <strong>seek no more</strong> my friend, here is the <code>LambdaToBooleanConverter</code>:</p>
<pre><code class="language-csharp">public class LambdaToBooleanConverter&lt;T&gt; : IValueConverter
{
    public Func&lt;T, bool&gt; Lambda { get; set; }

    public object Convert(object value, Type targetType, 
    					  object parameter, CultureInfo culture)
    {
        var valueT = (T)value;
        return Lambda(valueT);
    }

    public object ConvertBack(object value, Type targetType, 
    						  object parameter, CultureInfo culture)
    {
        throw new NotSupportedException(); // not relevant.
    }
}
</code></pre>
<p>You can use this in your view like that:</p>
<pre><code class="language-csharp">var isVisibleConverter = new LambdaToBooleanConverter&lt;User&gt;() 
	{ 
    	Lambda = u =&gt; u.Status == Status.Admin 
    };

myControl.SetBinding&lt;MyObservableObject&gt;(MyControl.IsVisibleProperty, 
										 o =&gt; o.User, 
                                         converter: isVisibleConverter);
</code></pre>
<p>Remember to bind on the element that implements the <code>INotifyPropertyChanged</code>.</p>
<p>XAML-side: you might need to declare it in code-behind (not a big fan of the solution).</p>
<hr>
<p>This is <strong>probably not efficient</strong> in terms of performance but it does the job.</p>
<p>Do not use and abuse complex lambdas: <strong>if it is too complex you are probably doing something wrong</strong>.</p>
<p>Do not uselessly declare more than once your converters.</p>
<p>This only solves a minor use-case I had that I did not want to refactor. I my case it was an <em>ObservableObject that added commands to a DTO</em>.<br>
I did not wanted to re-create every property of the DTO but still wanted to bind an expression of the DTO.</p>
<hr>
<p>Paul, out!</p>
<!--kg-card-end: markdown-->]]></content:encoded></item><item><title><![CDATA[Azure App Services Custom Auth (Part 3: client authentication)]]></title><description><![CDATA[Learn how to implement a custom authentication on Azure App Services in a couple of tutorials. Part 3: User Authentication on client-side.]]></description><link>https://www.pa-roy.com/azure-app-services-custom-auth-part-3/</link><guid isPermaLink="false">6300f01d5409ac12ae7550cb</guid><dc:creator><![CDATA[Paul Roy]]></dc:creator><pubDate>Sat, 09 Jan 2016 15:19:04 GMT</pubDate><content:encoded><![CDATA[<!--kg-card-begin: markdown--><p>Hi there!</p>
<p>How have you been? Happy new year to all of you!</p>
<p>It is time to get to the third (already!) part of these blog posts about Azure App Services Custom Authentication.<br>
We will now be talking about the <strong>client-side authentication</strong>.</p>
<p>Again, this post is part of a whole:</p>
<ul>
<li><a href="https://www.pa-roy.com/azure-app-services-custom-auth-part-1/">Azure App Services Custom Auth (Part 1: user management)</a></li>
<li><a href="https://www.pa-roy.com/azure-app-services-custom-auth-part-2/">Azure App Services Custom Auth (Part 2: server authentication)</a></li>
<li>Azure App Services Custom Auth (Part 3: client authentication)</li>
<li>Azure App Services Custom Auth (Part 4: cross-provider users) &#x2014; soon</li>
</ul>
<p>We have thanks to the first two parts a system that is able to:</p>
<ul>
<li>Create and manage users</li>
<li>Generate tokens from user informations</li>
<li>Request and validate queries by authentication</li>
</ul>
<p>Which is already pretty great in my opinion! However you probably want to use the azure app services framework on the client-side with our custom auth and I am here to deliver.</p>
<hr>
<h3 id="azureappservicesclient">Azure App Services Client</h3>
<p>The very first thing we will need is to introduce the client framework of Azure App Services. I did not do this properly before.</p>
<p>I will use the .NET managed version of it in a PCL project (Xamarin Forms).<br>
There might be some slight differences for other platforms but nothing that you should not be able to handle.</p>
<p>We will need to define the <code>MobileServiceClient</code> which is the object we can use later for all our requests. Microsoft made it quite simple for us:</p>
<pre><code class="language-csharp">var client = new MobileServiceClient(@&quot;https://mywebsite.azurewebsites.net/&quot;);
</code></pre>
<p>Remember to use the HTTPS protocol.</p>
<p>I also strongly advice you to use <a href="https://www.nuget.org/packages/modernhttpclient/">ModernHttpClient</a> which handles a bit better the http requests. To use it with Azure App Services we only need to pass on their handler in the constructor:</p>
<pre><code class="language-csharp">var client = new MobileServiceClient(@&quot;https://mywebsite.azurewebsites.net/&quot;, 
					new NativeMessageHandler());
</code></pre>
<p>Both these nuget packages (Azure App Services Client and ModernHttpClient) have to be embedded on your projects using it and on your specific project (iOS, Android, &#x2026;) if I am correct.</p>
<p><strong>I advise you to declare your mobile client only once</strong> and access it with a container by dependency injection.<br>
For instance, I have defined a <code>ServerManager</code> class and a <code>IServerManager</code> interface in charge of creating, controlling and accessing the instances of <code>MobileServiceClient</code> (I have several client services).<br>
This container is in charge of login and logout my users too.</p>
<p>You can also pass on directly the client with the <code>IMobileServiceClient</code> interface if you do not need a container.</p>
<p>I will consider you have access to a declared mobile services client named <code>_client</code> for the rest of the article.</p>
<hr>
<h3 id="authenticatetheuser">Authenticate the user</h3>
<p>If you followed the previous blog post on custom auth, this step should be pretty straightforward.<br>
You will need a registered user <a href="https://www.pa-roy.com/azure-app-services-custom-auth-part-1">as seen on the first part of this topic (call controller from client)</a>.<br>
Just to remind you quickly how it works here are the required steps for the auth:</p>
<ul>
<li>Get the token from user informations</li>
<li>Use the token for requests</li>
<li>Store the token for future use</li>
</ul>
<p>All of this will be pretty simple.</p>
<h4 id="getthetoken">Get the token</h4>
<p>For this step, you will need to <strong>ask the user for his / her informations</strong>. You can simply create a screen with email / password fields and a login button.</p>
<p>It is not really relevant here to blog about UI, so I will just give you a method to get the token with this signature:</p>
<pre><code class="language-csharp">Task&lt;AuthenticationToken&gt; GetAuthenticationToken(string email, 
												 string hash);
</code></pre>
<p>The response we will receive is a classic JSON so we will need the following class to parse it. This is the response we got from the <code>/oauth/token</code> endpoint in the previous post:</p>
<pre><code class="language-csharp">public class AuthenticationToken
{
    public string Guid { get; set; }
    public string Access_Token { get; set; }
    public string Token_Type { get; set; }

    [JsonProperty(&quot;.expires&quot;)]
    public DateTime Expires { get; set; }
}
</code></pre>
<p>The implementation is then pretty straightforward, we only need to send the data like we did testing our server:</p>
<pre><code class="language-csharp">public async Task&lt;AuthenticationToken&gt; 
		GetAuthenticationToken(string email, string password)
{
	// define request content
    HttpContent content = new StringContent(
    string.Format(&quot;username={0}&amp;password={1}&amp;grant_type=password&quot;, 
                  email.ToLower(), 
                  password));
                                    
    // set header
	content.Headers.ContentType 
    = new MediaTypeHeaderValue(&quot;application/x-www-form-urlencoded&quot;);

	// invoke Api
	HttpResponseMessage response 
    	= await _client.InvokeApiAsync(&quot;/oauth/token&quot;, 
            						   content, 
            						   HttpMethod.Post, 
            						   null, 
            						   null);

	// read and parse token
    string flatToken = await response.Content.ReadAsStringAync();
    return JsonConvert
    		.DeserializeObject&lt;AuthenticationToken&gt;(flatToken);
}
</code></pre>
<p>As you can see we use the magic of the framework to do it all!<br>
We are simply using a POST request with the informations (url encoded) to <code>/oauth/token</code> (the endpoint we defined earlier).<br>
Then we get the flat token and deserialize it as an <code>AuthenticationTicket</code>.</p>
<p>Note that emails are not case-sensitive, which is why I registered and authenticated the users with an <code>email.ToLower()</code>.</p>
<p>I strongly advise you to use <em>custom exceptions</em> for invalid grant like this:</p>
<pre><code class="language-csharp">public async Task&lt;AuthenticationToken&gt; 
		GetAuthenticationToken(string email, string password)
{
	try
    {
    	// all we did before
    }
    catch (MobileServiceInvalidOperationException exception)
    {
    	if (string.Equals(exception.Message, &quot;invalid_grant&quot;))
            throw new InvalidGrantException(&quot;Wrong credentails&quot;, 
            								exception);
        else
        	throw;
	}
}
</code></pre>
<h4 id="usethetoken">Use the token</h4>
<p>The underlying idea on the previous article was to fit as best as we could to the existing mechanism to simplify this very step.</p>
<p>The <code>AuthenticationToken</code> we got from the server has all the informations needed for the <code>MobileServiceClient</code> to handle authentication.</p>
<p>We now simply need to pass them as a <code>MobileServiceUser</code> to the client like this:</p>
<pre><code class="language-csharp">public async Task Authenticate(string email, string password)
{
	// get the token
	var token = await GetAuthenticationToken(email, password);

	// authenticate: create and use a mobile service user
	MobileServiceUser user = new MobileServiceUser(token.Guid);
	user.MobileServiceAuthenticationToken = token.Access_Token;
    _client.CurrentUser = user;
}
</code></pre>
<p>And&#x2026; that&apos;s it.</p>
<p>Yes.</p>
<p>That&apos;s it.</p>
<p>Now every query that the client will make will pass on a <code>X-ZUMO-AUTH</code> header, granting access to all methods flagged as <code>[Authorize]</code>.<br>
That also include the whole synchronization mechanism and the <code>SQLiteStorage</code> mechanism.</p>
<p>As long as the token is valid everything will work fine.</p>
<h4 id="storethetoken">Store the token</h4>
<p>We do not want the user to log in each time (s)he opens the application, which is why we will need to <strong>store and re-use the token</strong>.</p>
<p>If you followed the explanations on the previous post you will not be surprised when I tell you that the token only has some basic informations, and that its signature is strongly signed. This means <em>we can store the token unsecurely without compromising our security</em>.</p>
<p>However, a fraud could steal the token on the phone and make requests pretending to be the user. While it is very unlikely <strong>I advise you to <em>securely</em> store the token as well as the user id</strong> (better safe than sorry).</p>
<p>I will post in a next article an implementation for a cross-platform vault, meanwhile we will consider the next interface:</p>
<pre><code class="language-csharp">public interface ISecureStorage
{
	void Store(string key, string value);
	string Retrieve(string key);
	void Delete(string key);
    bool Contains(string key);
} 
</code></pre>
<p>If you absolutely need it right now I believe an implementation can be found in the XLabs project. Meanwhile you can also store the token and user id in the settings even if it is not the best option.</p>
<p>You can then store the informations easily:</p>
<pre><code class="language-csharp">public async Task Authenticate(string email, string password)
{
	// get token
    var token = await GetAuthenticationToken(email, password);

    // authenticate
    // &#x2026;

    // store settings
    _secureStorage.Store(&quot;UserId&quot;, token.Guid);
    _secureStorage.Store(&quot;Token&quot;, token.Access_Token);
}
</code></pre>
<p>And you can handle the invalid grant to clean user informations:</p>
<pre><code class="language-csharp">public async Task Authenticate(string email, string password)
{
	try
    {
    	// previous code
    }
    catch (InvalidGrantException)
    {
    	_secureStorage.Delete(&quot;UserId&quot;);
    	_secureStorage.Delete(&quot;Token&quot;);
        
        // alert user!
    }
}
</code></pre>
<p>The last step is to <strong>use these informations on the opening of the application</strong> to log-in right away.<br>
For instance, it can be done when you create you <code>MobileServiceClient</code>.</p>
<p>It is exactly like before but with the stored informations:</p>
<pre><code class="language-csharp">public async Task AutoAuthenticate()
{
    if (_secureStorage.Contains(&quot;UserId&quot;) 
    	&amp;&amp; _secureStorage.Contains(&quot;Token&quot;))
    {
        var id = _secureStorage.Retrieve(&quot;UserId&quot;);
        var token = _secureStorage.Retrieve(&quot;Token&quot;);

        var user = new MobileServiceUser(id);
        user.MobileServiceAuthenticationToken = token;
        _client.CurrentUser = user;
    }
}
</code></pre>
<p>You can use this method on the start of the application or anywhere you want to log the user automatically.</p>
<p>Now as long as the authentication token is valid this will be enough. But the real issue is when it expires&#x2026;</p>
<hr>
<h3 id="reauthenticatetheuseraftertokenexpiration">Reauthenticate the user after token expiration</h3>
<p>There would be two ways to implement it: use a refresh token mechanism or store their credentials.</p>
<p>I used the latter which means that for this part <strong>you will absolutely need a secure storage for this mechanism</strong>.</p>
<p>Email and password should <strong>NEVER</strong> be stored without encryption <strong>even on the client</strong>.</p>
<p>The code is pretty simple: if a user logs successfully we register his / her credentials and the token expiration like this</p>
<pre><code class="language-csharp">
public async Task Authenticate(string email, string password)
{
    // previous authentication code

    // store settings
    _secureStorage.Store(&quot;UserId&quot;, token.Guid);
    _secureStorage.Store(&quot;Token&quot;, token.Access_Token);
    _secureStorage.Store(&quot;TokenExpirationDate&quot;, 
    					 token.Expires.Ticks.ToString());
    _secureStorage.Store(&quot;UserEmail&quot;, email);
    _secureStorage.Store(&quot;UserPassword&quot;, password);
}
</code></pre>
<p>I chose to store the expiration date as a string with the date&apos;s ticks. <em>If you have a better option you can comment below to offer me better solutions</em> :)</p>
<p>Remember to clean every information we added here when the user enters invalid credentials.</p>
<p>The last step is to check on start if the token is expired and re-authenticate the user if it is.</p>
<pre><code class="language-csharp">public async Task AutoAuthenticate()
{
	if (_secureStorage.Contains(&quot;UserId&quot;) 
	      &amp;&amp; _secureStorage.Contains(&quot;Token&quot;) 
    	  &amp;&amp; _secureStorage.Contains(&quot;TokenExpirationDate&quot;))
	{
		var expirationDateTicks 
        	= _secureStorage.Retrieve(&quot;TokenExpirationDate&quot;);
	    DateTime expirationDate 
        	= new DateTime(long.Parse(expirationDateTicks));
    
		if (expirationDate &lt; DateTime.Now)
	    {
        	// you can also check first if email and password exists
	    	var email = _secureStorage.Retrieve(&quot;UserEmail&quot;);
    		var password = _secureStorage.Retrieve(&quot;UserPassword&quot;);
            
            await Authenticate(email, password);
    	}
	    else
	    {
	      var id = _secureStorage.Retrieve(&quot;UserId&quot;);
    	  var token = _secureStorage.Retrieve(&quot;Token&quot;);

	      var user = new MobileServiceUser(id);
    	  user.MobileServiceAuthenticationToken = token;
	      _client.CurrentUser = user;
    	}
	}
}
</code></pre>
<p>And we are done!</p>
<p>We have a system for the client that can authenticate, auto-authenticate on start and re-authenticate when the token is expired.</p>
<hr>
<h3 id="finally">Finally</h3>
<p>Apart from the <code>ISecureStorage</code> implementation, you should have everything you need to use our brand new custom authentication!</p>
<p>As you can see, a single article for both client and server authentication would have been HUGE which is why I splitted it.</p>
<p>If you have any remark, question, suggestion, <strong>please use the comment section below!</strong> I am <em>always</em> glad to hear from you, even with a comment saying hi.</p>
<p>But wait&#x2026; you said there would be a forth article? Why? Have we not everything we need like you said?<br>
Well I feel there is still some work to be done. On the next article, we will see how we can integrate our custom auth with the existing auth (Facebook, Twitter, G+, Microsoft, AAD, &#x2026;) in order to make our server fully transparent regarding the origin of the auth. We will create <strong>cross-platform users</strong>.</p>
<p>See you soon!</p>
<p>Paul, out!</p>
<hr>
<p>This post is part of a whole:</p>
<ul>
<li><a href="https://www.pa-roy.com/azure-app-services-custom-auth-part-1/">Azure App Services Custom Auth (Part 1: user management)</a></li>
<li><a href="https://www.pa-roy.com/azure-app-services-custom-auth-part-2/">Azure App Services Custom Auth (Part 2: server authentication)</a></li>
<li>Azure App Services Custom Auth (Part 3: client authentication)</li>
<li>Azure App Services Custom Auth (Part 4: cross-provider users) &#x2014; soon</li>
</ul>
<!--kg-card-end: markdown-->]]></content:encoded></item><item><title><![CDATA[Azure App Services Custom Auth (Part 2: server authentication)]]></title><description><![CDATA[Learn how to implement a custom authentication on Azure App Services in a couple of tutorials. Part 2: User Authentication on server-side.]]></description><link>https://www.pa-roy.com/azure-app-services-custom-auth-part-2/</link><guid isPermaLink="false">6300f01d5409ac12ae7550ca</guid><dc:creator><![CDATA[Paul Roy]]></dc:creator><pubDate>Thu, 10 Dec 2015 13:38:54 GMT</pubDate><content:encoded><![CDATA[<!--kg-card-begin: markdown--><p>Hello again everyone!</p>
<p>I hope the first part was interesting enough, on this second part we are going to introduce the <strong>authentication by token</strong> part.</p>
<p>Once again, this post is part of a whole:</p>
<ul>
<li><a href="https://www.pa-roy.com/azure-app-services-custom-auth-part-1/">Azure App Services Custom Auth (Part 1: user management)</a></li>
<li>Azure App Services Custom Auth (Part 2: server authentication)</li>
<li><a href="https://www.pa-roy.com/azure-app-services-custom-auth-part-3/">Azure App Services Custom Auth (Part 3: client authentication)</a></li>
<li>Azure App Services Custom Auth (Part 4: cross-provider users) &#x2014; soon</li>
</ul>
<p>On the first part we only saw the user management and now we currently have a system that can add users from the client and access them quite simply from the server.</p>
<hr>
<h3 id="howtokenauthenticationworks">How token-authentication works</h3>
<p>We are doing authentication, so it is best if we understand how it works.<br>
I will quickly sum up how token based authentication works.<br>
You can skip this whole part if you are familiar with the concepts and go straight to &#xAB;&#xA0;Azure App Services Implementation&#xA0;&#xBB;.</p>
<h4 id="threepartymechanism">Three-party mechanism</h4>
<p>The very first step is to understand that we have three parties involved here.</p>
<ul>
<li><strong>A user:</strong> well, that makes sense</li>
<li><strong>A grant provider:</strong> this server is in charge of verifying and guaranteeing the user is who he says he is</li>
<li><strong>An application server:</strong> this server trusts the provider that the user is verified by him and uses the informations the provider passes on as trusted</li>
</ul>
<p>To ensure that trust the grant provider and the application server share a <strong>common signing key</strong>. In the case of social network providers (Facebook, Twitter, Google, &#x2026;) these are represented by your app id / app secret.</p>
<p>The two servers will share a <strong>token</strong> that the user will pass on each request allowing the application server to verify the authentication.</p>
<p>In our case the provider and the application server will be the same server. On an ideal situation we could separate these and avoid stocking the user informations on the application server (such as authentication by social providers).</p>
<h4 id="signingkeytoken">Signing Key &amp; Token</h4>
<p>In case of JWT (JSON Web Tokens) we have a header, a body and a signature. While the header and the body can easily be decrypted (and thus cannot be considered safe) the signature is a hash of the informations with the signing key.<br>
For testing purposes you can decrypt and check signatures of JWT tokens on <a href="http://jwt.io/">http://jwt.io/</a>.</p>
<p>That means that only somebody that has the signing key can generate tokens that will be validated by our server. This is a strong symetric signing and a great way to share secured informations.</p>
<p>That also mean that <strong>the signing key is the most precious security information</strong>. It must <strong>never be stored on the client</strong> and it must remain hidden and securely stored at anytime by both parties.</p>
<p><u><strong>/!\</strong></u> <u>Do not transfer a key by mail, by chat, by SMS, by USB Key, anything, never, ever, ever</u> <u><strong>/!\</strong></u></p>
<p>also,</p>
<p><u><strong>/!\</strong></u> <u>No signing keys in the code, no secrets under version control or stored in a possibly insecure location</u> <u><strong>/!\</strong></u></p>
<p>A leak of the signing key will compromise your whole security allowing intruders to pretend they are anyone they want to be.</p>
<p>Almost all security hacks are not done by cracking overly complicated security systems.<br>
On <a href="http://www.eetimes.com/document.asp?doc_id=1279619">this article</a> you will see it would take billions of years to crack even a simple encryption.</p>
<p>Most hacks are done using weak security leaks (password security questions, shared passwords between apps, weak passwords, weak security elsewhere, &#x2026;) and you must remember that your whole security system is as weak as your weakest point.</p>
<p>Store your secrets and password securely with tools such as <a href="http://keepass.info/">KeePass</a> and keep them unique whenever you can.</p>
<h4 id="firstauthenticationbyemailpassword">First authentication by email / password</h4>
<p>Back to the good part!<br>
Users authenticate for the first time using their email and their password. This step is necessary to ensure the user is whoever he claims he is.</p>
<p>To do this we are passing the email and password securely (HTTPS, HTTP over SSL) and the provider is checking everything is correct.</p>
<p>In case of success a token is generated. This token encrypts claims such as the nameidentifier, the audience, the issuer, etc.</p>
<h4 id="tokentransmission">Token transmission</h4>
<p>Each request a user make will include a token in the form of a HTTP Header (<code>X-ZUMO-AUTH</code> for Azure App Services &#x2014; a<strong>ZU</strong>re <strong>MO</strong>bile).</p>
<p>The server will check the validity of the token (expiration date, issuer, audience, signature) and use the informations stored in the token locally (user id, user name, &#x2026;).</p>
<h4 id="refreshtoken">Refresh token</h4>
<p>A token has an expiration date and to keep a token alive there is a mechanism of token refreshment. I will not cover this here.</p>
<hr>
<h3 id="azureappservicesimplementation">Azure App Services Implementation</h3>
<p>We are going to use JWT Tokens, OAuth mechanisms from Identity and the existing mechanisms of Azure App Services to keep it as simple as possible.</p>
<h4 id="strategy">Strategy</h4>
<p>What we need to do to achieve our goal is pretty simple:</p>
<ul>
<li>Expose a <code>/oauth/token</code> endpoint on which users can send their email / password</li>
<li>Generate claims and an authentication ticket from their informations (or reject him if the infos are wrong)</li>
<li>Generate and send a token to the user</li>
</ul>
<p>The existing mechanisms will take care of the rest (validating, interpreting and storing the token). The solution I offer uses consumption mechanisms of Azure App Services.</p>
<h4 id="applicationusergenerateuseridentityasyncgeneratingclaims">ApplicationUser.GenerateUserIdentityAsync, generating claims</h4>
<p>The first thing we want to do is to generate Claims from a user. For this we will use the existing mechanisms of Identity and go to our <code>ApplicationUser</code> class to add a method named <code>GenerateUserIdentityAsync</code>.</p>
<p>The implementation is right here:</p>
<pre><code class="language-csharp">public async Task&lt;ClaimsIdentity&gt; GenerateUserIdentityAsync(
		UserManager&lt;ApplicationUser&gt; manager, 
		string authenticationType)
{
	var userIdentity = await manager.CreateIdentityAsync(this, 
									authenticationType);
    userIdentity.AddClaim(new Claim(JwtRegisteredClaimNames.Sub, 
    								this.UserName));
    return userIdentity;
}
</code></pre>
<p>This allows us to generate the ClaimsIdentity from a user which we will use on our authentication mechanism.<br>
We need to add a claim for Azure App Services (which is the Sub claim) on which we will put the username of the user.</p>
<h4 id="customauthprovidervalidatingtheuser">CustomAuthProvider, validating the user</h4>
<p>We will need a provider that can grant users their credentials. In a folder &#xAB;&#xA0;Providers&#xA0;&#xBB; we will create the <code>CustomAuthProvider</code>, deriving from <code>OAuthAuthorizationServerProvider</code>. Once again, the existing mechanisms will avoid us to reimplement everything. This class comes from the <code>Microsoft.Owin.Security.OAuth</code> nuget package.</p>
<p>Here is the implementation of this class:</p>
<pre><code class="language-csharp">public class CustomAuthProvider : OAuthAuthorizationServerProvider
{
    public override Task ValidateClientAuthentication(
    				OAuthValidateClientAuthenticationContext context)
    {
        context.Validated();
        return Task.FromResult&lt;object&gt;(null);
    }

    public override Task TokenEndpoint(OAuthTokenEndpointContext context)
    {
        foreach (KeyValuePair&lt;string, string&gt; property in 
        			context.Properties.Dictionary)
        {
            context.AdditionalResponseParameters.Add(property.Key,
            										 property.Value);
        }

        return Task.FromResult&lt;object&gt;(null);
    }

    public override async Task GrantResourceOwnerCredentials(
    					OAuthGrantResourceOwnerCredentialsContext context)
    {
        var allowedOrigin = &quot;*&quot;;

        context.OwinContext.Response.Headers.Add(
        			&quot;Access-Control-Allow-Origin&quot;, 
                    new[] { allowedOrigin });

        var userManager = context.OwinContext
        						 .GetUserManager&lt;ApplicationUserManager&gt;();

        ApplicationUser user = await userManager.FindAsync(context.UserName,
        												  context.Password);

        if (user == null)
        {
            context.SetError(&quot;invalid_grant&quot;, 
            				 &quot;The user name or password is incorrect.&quot;);
            return;
        }
        
        ClaimsIdentity oAuthIdentity = 
        	await user.GenerateUserIdentityAsync(userManager, &quot;JWT&quot;);
            
        var props = new AuthenticationProperties(
        	new Dictionary&lt;string, string&gt; { { &quot;guid&quot;, user.Id } });
        var ticket = new AuthenticationTicket(oAuthIdentity, props);
            
        context.Validated(ticket);
    }
}
</code></pre>
<p>On this class we are granting the users credentials from a <code>OAuthGrantResourceOwnerCredentialsContext</code> generated from the request.</p>
<p>We are fetching the user from the username sent by the context with the user manager and we are creating an <code>AuthenticationTicket</code> from the JWT claims we generated. Note that I also add the <code>user.Id</code> in the response, which will be useful later on the client-side.</p>
<p>This <code>AuthenticationTicket</code> will be encrypted into a token by our next class:</p>
<h4 id="customzumotokenformatencryptingclaims">CustomZumoTokenFormat, encrypting claims</h4>
<p>In the same folder we will create this class responsible for creating a token from the claims we generated.<br>
The tricky thing here is to fit to the implementation of Azure App Services so we will not have to implement the consumption mechanism again.</p>
<pre><code class="language-csharp">public class CustomZumoTokenFormat : ISecureDataFormat&lt;AuthenticationTicket&gt;
{
    private string _host = string.Format(&quot;https://{0}.azurewebsites.net/&quot;, 
    		Environment.ExpandEnvironmentVariables(&quot;%WEBSITE_SITE_NAME%&quot;)
            .ToLower());

    public string Protect(AuthenticationTicket data)
    {
        if (data == null)
            throw new ArgumentNullException(&quot;data&quot;);

        // Get Signing Key and send x-zumo-auth token from claims
        string signingKey = GetSigningKey();
        var tokenInfo = AppServiceLoginHandler.CreateToken(
        		data.Identity.Claims, 
                signingKey, 
                _host, 
                _host, 
                TimeSpan.FromHours(24));
            
        return tokenInfo.RawData;
    }

    public AuthenticationTicket Unprotect(string protectedText)
    {
        throw new NotImplementedException();
    }

    private static string GetSigningKey()
    {
        string key = 
        	Environment.GetEnvironmentVariable(&quot;WEBSITE_AUTH_SIGNING_KEY&quot;);

        if (string.IsNullOrWhiteSpace(key))
            key = ConfigurationManager.AppSettings[&quot;SigningKey&quot;];

        return key;
    }
}
</code></pre>
<p>While on the first versions I had to decompile their code to get the signing key (which had a different name), Azure App Services open sourced their code and included this GetSigningKey() method that I find pretty elegant.</p>
<p>The <code>AppServiceLoginHandler.CreateToken(&#x2026;)</code> is also a very helpful class and beautifully exposed. I used to hack my way to get access to this class, decompiling the code to see how they exposed and used it (that was a different name).</p>
<p>What we are doing here is simply taking the <code>AuthenticationTicket</code> and creating the associated signed token with their handler.</p>
<p>I generated the host with the environment variable because I had trouble getting a correct issuer / audience for this token. <strong>If anyone has a better way to get or create the correct issuer I am opened to suggestions in the comments!</strong></p>
<h4 id="oauthauthorizationserveroptionsexposingtheendpoint">OAuthAuthorizationServerOptions, exposing the endpoint</h4>
<p>Almost done! What we have left to do is to expose our endpoint and assemble the bricks we created.</p>
<p>For this, just go to your OWIN <code>Startup</code> class. We will create a new method <code>ConfigureCustomAuth</code> with this implementation:</p>
<pre><code class="language-csharp">public static void ConfigureCustomAuth(IAppBuilder appBuilder)
{
	OAuthAuthorizationServerOptions oAuthServerOptions = 
    	new OAuthAuthorizationServerOptions()
    	{
    		TokenEndpointPath = new PathString(&quot;/oauth/token&quot;),
        	Provider = new CustomAuthProvider(),
        	AccessTokenExpireTimeSpan = TimeSpan.FromDays(1),
        	AccessTokenFormat = new CustomZumoTokenFormat(),
    	};

	// OAuth Configuration
    appBuilder.UseOAuthAuthorizationServer(oAuthServerOptions);
}
</code></pre>
<p>Our endpoint will be exposed on <code>/oauth/token</code>, with the provider and the token format we created before.</p>
<p>Calling the <code>/oauth/token</code> endpoint with the user email and password will validate them and create a signed token.</p>
<p>And this is were the magic happens: this token is correctly formatted for Azure App Services which means we do not have to re-implement the consumption!</p>
<p>Finally, we only have to use our method on the <code>Configure</code> method to expose everything correctly:</p>
<pre><code class="language-csharp">public void Configuration(IAppBuilder appBuilder)  
{
    // &#x2026; (part 1 code)

    ConfigureCustomAuth(appBuilder);
}
</code></pre>
<hr>
<h3 id="protectingourmethods">Protecting our methods</h3>
<p>Now that we have implemented this authentication we can simply use the <code>[Authorize]</code> keyword on a controller or a method to restrict the acces only to authenticated users.</p>
<p>Here is my implementation of <code>GetUser</code> to show you:</p>
<pre><code class="language-csharp">public class AccountsController : BaseAuthApiController
{
	[Route(&quot;user/{id:guid}&quot;, Name = &quot;GetUserById&quot;)]
    [Authorize]
    public async Task&lt;IHttpActionResult&gt; GetUser(string Id)
    {
    	var userId = User.Identity.GetUserId();
        var user = await this.AppUserManager.FindByIdAsync(Id);

		if (user != null)
        {
        	if (user.Id != userId)
            	throw new HttpException(401, 
                	&quot;You cannot get other users informations&quot;);
            else
            	return Ok(this.TheModelFactory.Create(user));
        }

        return NotFound();
    }
    
    &#x2026;
}
</code></pre>
<p>This <code>User.Identity.GetUserId()</code> comes from an extension (<code>IdentityExtensions</code> from <code>Microsoft.AspNet.Identity.Core</code>).</p>
<hr>
<h3 id="testingtheauthentication">Testing the authentication</h3>
<p>First <em>do not forget to set locally a signing key</em> (<code>SigningKey</code> in app settings), this can be any 128 bits key with hexadecimal values, you can find implementations on the internet.</p>
<p>Then we need to add to the code if we want to test locally is to disable the HTTPS, so add this line on the authentication declaration:</p>
<pre><code class="language-csharp"> OAuthAuthorizationServerOptions oAuthServerOptions = 
 	new OAuthAuthorizationServerOptions()
    	{
#if DEBUG
        	AllowInsecureHttp = true, // NEVER&#xA0;IN&#xA0;PRODUCTION!
#endif
    		TokenEndpointPath = new PathString(&quot;/oauth/token&quot;),
        	Provider = new CustomAuthProvider(),
        	AccessTokenExpireTimeSpan = TimeSpan.FromDays(1),
        	AccessTokenFormat = new CustomZumoTokenFormat(),
    	};
</code></pre>
<p>Remember we are dealing with passwords which means we absolutely need the HTTPS protocol. If we forget this anyone listening could get the informations of the user.</p>
<p>Now I will assume you have a user created here. You just have to take a REST&#xA0;client such as the awesome chrome extension <a href="https://chrome.google.com/webstore/detail/advanced-rest-client/hgmloofddffdnphfgcellkdfbfbjeloo">Advanced REST Client</a>.</p>
<p>Use <code>http://localhost:port/oauth/token</code> with a <strong>POST</strong> method.<br>
We will send a form (<code>application/x-www-form-urlencoded</code> type) with the values</p>
<ul>
<li><strong>username :</strong> myusername</li>
<li><strong>password :</strong> mypassword</li>
<li><strong>grant_type : password</strong></li>
</ul>
<p>The server will answer with a <code>guid</code> and a <code>access_token</code> (among other things). The first one is the additional property we passed on, and the second is the encrypted token with your claims.</p>
<p>You can partially decrypt the token at <a href="http://jwt.io">http://jwt.io</a>. You will see the different claims (ver(sion), iss(uer), aud(ience), etc.) and you can check that the signature is right using your signing key.</p>
<p>Now you can test your secure endpoints using this token, simply pass on two <strong>headers</strong> when you reach them:</p>
<ul>
<li><strong>X-ZUMO-AUTH :</strong> your_access_token</li>
<li><strong>ZUMO-API-VERSION : 2.0.0</strong></li>
</ul>
<p>The first was is responsible of the authentication, the second was introduced in the latest version of Azure App Services to version their back-end.</p>
<p>You can try this for instance on the GetUser method we authorized later.</p>
<hr>
<h3 id="finally">Finally</h3>
<p>To be honest I did not think this post would be this long and that is why I splitted it into a server-side part and a client-side part.</p>
<p>We have set the biggest part of the authentication on this post and I hope it was easy enough to understand. I also hope you are not disappointed by the fact we could not get into the client-side here.</p>
<p>I would like once again to thank <strong>Taiseer Joudeh</strong> for his amazing posts on Identity, this was really the foundation of all this authentication.</p>
<p>If you have any question or any remark to make please feel free use the comments below, I will be glad to know what you think of all this if some points are unclear or if you have suggestions.</p>
<p>Paul, out!</p>
<hr>
<p>This post is part of a whole:</p>
<ul>
<li><a href="https://www.pa-roy.com/azure-app-services-custom-auth-part-1/">Azure App Services Custom Auth (Part 1: user management)</a></li>
<li>Azure App Services Custom Auth (Part 2: server authentication)</li>
<li><a href="https://www.pa-roy.com/azure-app-services-custom-auth-part-3/">Azure App Services Custom Auth (Part 3: client authentication)</a></li>
<li>Azure App Services Custom Auth (Part 4: cross-provider users) &#x2014; soon</li>
</ul>
<!--kg-card-end: markdown-->]]></content:encoded></item><item><title><![CDATA[Azure App Services Custom Auth (Part 1: user management)]]></title><description><![CDATA[Learn how to implement a custom authentication on Azure App Services in a couple of tutorials. Part 1: User Management.]]></description><link>https://www.pa-roy.com/azure-app-services-custom-auth-part-1/</link><guid isPermaLink="false">6300f01d5409ac12ae7550c9</guid><dc:creator><![CDATA[Paul Roy]]></dc:creator><pubDate>Wed, 25 Nov 2015 15:41:26 GMT</pubDate><content:encoded><![CDATA[<!--kg-card-begin: markdown--><p>Greatings everyone!</p>
<p>I have spent a lot of time making a custom auth work on Azure App Services with a .NET backend. And it is about time I share this, as many users need it.</p>
<p>I first published a working custom auth around <em>April 2015</em>, on a version of App Services that was clearly not designed to do this simply.</p>
<p>I had to hack my way through a lot of complicated stuff at that time and now that App Services have been improved and simplified (and is getting ready for production), I feel <strong>it is time to make a huge post about custom auth</strong>.</p>
<p>I have spent so much time trying to figure this out that I truly believe this blog post might help a lot of users.</p>
<p>This post is part of a whole:</p>
<ul>
<li>Azure App Services Custom Auth (Part 1: user management)</li>
<li><a href="https://www.pa-roy.com/azure-app-services-custom-auth-part-2/">Azure App Services Custom Auth (Part 2: server authentication)</a></li>
<li><a href="https://www.pa-roy.com/azure-app-services-custom-auth-part-3/">Azure App Services Custom Auth (Part 3: client authentication)</a></li>
<li>Azure App Services Custom Auth (Part 4: cross-provider users) &#x2014; soon</li>
</ul>
<hr>
<h3 id="whatyouneedtoknow">What you need to know</h3>
<p>You need basic knowledge on these stuff, not expertise. But I will not be covering them, first because many people did this way better than me and second because I want to focus on other things.</p>
<ul>
<li><strong>ASP.Net</strong>:<br>
Needless to precise, but still</li>
<li><strong>Code first migrations</strong>: You will need to know how to do it, and to have done it for your business context</li>
<li><strong>OWIN</strong>: We are going to mess up with it.</li>
<li><strong>Azure App Services</strong>: I will not cover up how to set-up AAS</li>
</ul>
<p>You also need to know that I use another tutorial as a base, made by a far more advanced developper than I am: <strong>Taiseer Joudeh</strong>.<br>
His tutorials on AspNet.Identity were the real reason I could achieve this custom auth. Let&apos;s take a minute of silence to honor his talent.</p>
<p>&#x2026;</p>
<p>Now, you can find the part 1 of his tutorials here: <a href="http://bitoftech.net/2015/01/21/asp-net-identity-2-with-asp-net-web-api-2-accounts-management/">http://bitoftech.net/2015/01/21/asp-net-identity-2-with-asp-net-web-api-2-accounts-management/</a></p>
<p>If you look at them, you will see a lot of code is shared for this particular post, and I truly hope he does not think I am just copying the content as this is for me the base for what is coming next. Adapting his work on Azure App Services is the true value of my blog posts. Think of it as <code>public class PaulBlogPost : TaiseerBlogPost</code>.</p>
<hr>
<p>Basically, we are going to use AspNet.Identity. Note that you do not necessarly need to use it, but I feel this is the most simple way to achieve our goal.</p>
<hr>
<h3 id="applicationuser">ApplicationUser</h3>
<p>This class will represent a user for us, and will inherit <code>IdentityUser</code>. You will need the nuget package <code>Microsoft.AspNet.Identity.EntityFramework</code> in order to do this.</p>
<p>Here is a basic implementation of ApplicationUser:</p>
<pre><code class="language-csharp">public class ApplicationUser : IdentityUser
{
    [Required]
    public string FirstName { get; set; }

    [Required]
    public string LastName { get; set; }

    [Required]
    public DateTime JoinDate { get; set; }
}
</code></pre>
<p>Note that these three properties are custom-made, you could very well not use them, or defining other properties.<br>
For instance I have a property <code>ProfilePictureUri</code> for the picture of the user. I also have a <code>Provider</code> property, to know if my user comes from Facebook, my auth, or anything else.<br>
What you put on a user to define him is really up to you!</p>
<hr>
<h3 id="applicationdbcontext">ApplicationDbContext</h3>
<p>You probably already have a Context for you business logic. We are going to create a whole new context for the users.<br>
Even if you do not necessarly need to do this, I think it is the best way to go because <strong>you need to decouple as much as possible your user private informations from their application data</strong>.<br>
That way if one day you want to create your own authentication server you have no link between the user data and the user informations.</p>
<p>Now this is what this context look like:</p>
<pre><code class="language-csharp">public class ApplicationDbContext : IdentityDbContext&lt;ApplicationUser&gt;
{
    private const string connectionStringName = &quot;Name=MS_TableConnectionString&quot;;
        
    public ApplicationDbContext() : base(connectionStringName, throwIfV1Schema: false)
    {
        Configuration.ProxyCreationEnabled = false;
        Configuration.LazyLoadingEnabled = false;
    }

	protected override void OnModelCreating(DbModelBuilder modelBuilder)
	{
	    base.OnModelCreating(modelBuilder);
	    modelBuilder.HasDefaultSchema(&quot;Application&quot;);
	}
        
    public static ApplicationDbContext Create()
    {
        return new ApplicationDbContext();
    }
}
</code></pre>
<p>I use the <code>MS_TableConnectionString</code> that is defined on App Services to use the same database.<br>
Not that I put the default schema <code>Application</code> to decouple at a schema level the User informations from their data.</p>
<hr>
<h3 id="applicationconfigurationinitialmigration">ApplicationConfiguration &amp; Initial Migration</h3>
<p>As we have two schema / context, it makes sense to create two configurations. You should already have a configuration for your business logic, we will now create another one for the other Context:</p>
<pre><code class="language-csharp">internal sealed class ApplicationConfiguration : DbMigrationsConfiguration&lt;ApplicationDbContext&gt;
{
    public ApplicationConfiguration()
    {
        AutomaticMigrationsEnabled = false;
    }
}
</code></pre>
<p>Really nothing special here. Regarding your architecture, I recommend to have a <strong>folder &#xAB;&#xA0;Migrations&#xA0;&#xBB;</strong>, on which you will have <strong>two folders: &#xAB;&#xA0;Application&#xA0;&#xBB; and &#xAB;&#xA0;Business&#xA0;&#xBB;</strong> (or the name of your app instead of Business).</p>
<p>Now create your initial migration with the following line:</p>
<pre><code>Add-Migration InitialApplicationMigration -ConfigurationTypeName ApplicationConfiguration
</code></pre>
<hr>
<h3 id="applicationusermanager">ApplicationUserManager</h3>
<p>This manager will allow us to get the users, and will be used by OWIN. The UserManager class is in the nuget package <code>Microsoft.AspNet.Identity.Core</code>.<br>
It needs basic stuff, such as a factory, and here is the implementation:</p>
<pre><code class="language-csharp">public class ApplicationUserManager : UserManager&lt;ApplicationUser&gt;
{
    public ApplicationUserManager(IUserStore&lt;ApplicationUser&gt; store) : base(store)
    {
        UserValidator = new UserValidator&lt;ApplicationUser&gt;(this) { AllowOnlyAlphanumericUserNames = false };
    }

    public static ApplicationUserManager Create(IdentityFactoryOptions&lt;ApplicationUserManager&gt; options, 
    											IOwinContext context)
    {
        var appDbContext = context.Get&lt;ApplicationDbContext&gt;();
        var appUserManager = new ApplicationUserManager(new UserStore&lt;ApplicationUser&gt;(appDbContext));
        return appUserManager;
    }
}
</code></pre>
<p>Just to clarify, I used <code>AllowOnlyAlphanumericUserNames</code> to use the email address as the username. You can do as you want on your side.</p>
<hr>
<h3 id="owinstartupowincontextdbmigrator">OwinStartup, OwinContext &amp; DbMigrator</h3>
<p>Let&apos;s get down to business with OWIN. We have two things to do, define the ApplicationUserManager per OWIN Context and update database on start.</p>
<p>I advise you to update your database on start, because that way you will not need to bother to update your databases on your servers each time. The simple fact that you push in production will set the database up to date regarding your current schema and migrations.</p>
<p>Now we have to create the OWIN Startup class: right click on your project -&gt; Add -&gt; New Item -&gt; OWIN Startup class.</p>
<p>You will end up with an empty class with a <code>Configuration</code> method. We will first add the factory for the context and the user manager:</p>
<pre><code class="language-csharp">public void Configuration(IAppBuilder appBuilder)
{
	appBuilder.CreatePerOwinContext(ApplicationDbContext.Create);
	appBuilder.CreatePerOwinContext&lt;ApplicationUserManager&gt;(ApplicationUserManager.Create);
    
    // &#x2026;
}
</code></pre>
<p>This will allow us to access the manager and the context from the middleware. This is part of the <code>Microsoft.AspNet.Identity.Owin</code> nuget package.<br>
Then we add our basic mobile code:</p>
<pre><code class="language-csharp">public void Configuration(IAppBuilder appBuilder)
{
	// &#x2026;

    HttpConfiguration config = new HttpConfiguration();
    config.MapHttpAttributeRoutes();

    new MobileAppConfiguration()
        .AddMobileAppHomeController()
        .AddTablesWithEntityFramework()
        .MapApiControllers()
        .ApplyTo(config);

    appBuilder.UseWebApi(config);
    
    // &#x2026;
}
</code></pre>
<p>Note that you may have a different mobile configuration, use what you need.<br>
And finally we add our database migration code:</p>
<pre><code class="language-csharp">public void Configuration(IAppBuilder appBuilder)
{
	// &#x2026;
	
    ConfigureDbMigration();
}
</code></pre>
<p>The method ConfigureDbMigration is where we configure our migrations and here is the implementation:</p>
<pre><code class="language-csharp">private void ConfigureDbMigration()
{
    // DbMigrator businessMigrator = new DbMigrator(new BusinessConfiguration());
    // businessMigrator.Update();

    DbMigrator applicationMigrator = new DbMigrator(new ApplicationConfiguration());
    applicationMigrator.Update();
}
</code></pre>
<p>I have commented the business part, as what I want to show you here is the application migration. But as you can see, I have a migration for both my Configurations.</p>
<hr>
<h3 id="accountsapicontroller">Accounts Api Controller</h3>
<p>Now that we have defined all we need to manipulate users, create them and stuff. But we still need to expose this through a controller.</p>
<p>Here is the definition of my controller:</p>
<pre><code class="language-csharp">[RoutePrefix(&quot;api/accounts&quot;)]
public class AccountsController : BaseAuthApiController
{
	[Route(&quot;user/{id:guid}&quot;, Name = &quot;GetUserById&quot;)]
	[Authorize]
	public async Task&lt;IHttpActionResult&gt; GetUser(string Id);
    
	[Route(&quot;user/{username}&quot;, Name = &quot;GetUserByName&quot;)]
	[Authorize]
	public async Task&lt;IHttpActionResult&gt; GetUserByName(string username);

	[Route(&quot;create&quot;)]
	[AllowAnonymous]
	[ResponseType(typeof(UserReturnModel))]
	public async Task&lt;IHttpActionResult&gt; CreateUser(AccountBindingModel createUserModel);
}
</code></pre>
<p>Once again, Taiseer did this work, so I will let you find the implementation of this controller on his amazing blog post from step 7 to 10: <a href="http://bitoftech.net/2015/01/21/asp-net-identity-2-with-asp-net-web-api-2-accounts-management/">http://bitoftech.net/2015/01/21/asp-net-identity-2-with-asp-net-web-api-2-accounts-management/</a></p>
<p>Just note the use of [Authorize] and [AllowAnonymous], which will ensure the methods are used correctly.</p>
<hr>
<h3 id="callcontrollerfromclient">Call controller from client</h3>
<p>You cannot use the [Authorize] controlled methods yet because we did not grant users right, at least for the moment.</p>
<p>But I think we can already introduce the use of the Api from the front-end. I will be doing this with the .NET SDK (I am on Xamarin), but any other SDK would work basically the same way.</p>
<p>As you have seen, the CreateUser method uses two models: <code>AccountBindingModel</code> and <code>UserReturnModel</code>. We will need them both on the client-side. <code>UserReturnModel</code> is really close to ApplicationUser and that is the name I used on the client (it was more explicit):</p>
<pre><code class="language-csharp">public class AccountModelBinding
{
    public string Email { get; set; }
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public string Password { get; set; }
    public string ConfirmPassword { get; set; }
}
</code></pre>
<pre><code class="language-csharp">public class ApplicationUser
{
    public string Id { get; set; }
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public string Email { get; set; }
}
</code></pre>
<p>Now with these elements, the beauty of the SDK does it all for us, by using <code>.InvokeApiAsync</code>:</p>
<pre><code class="language-csharp">IMobileServiceClient mobileServiceClient = new MobileServiceClient(&quot;http://mywebsite.azurewebsites.net/&quot;);
AccountModelBinding accountModelBinding = &#x2026;; // fill with your informations

ApplicationUser createdUser = await mobileServiceClient.InvokeApiAsync&lt;AccountModelBinding, ApplicationUser&gt;(&quot;accounts/create&quot;, accountModelBinding);
</code></pre>
<hr>
<h3 id="errorhandlingfromtheclient">Error handling from the client</h3>
<p>If you want to handle the errors, you can simply catch the <code>MobileServiceInvalidOperationException</code> and look at the content like this:</p>
<pre><code class="language-csharp">try  
    {
        // &#x2026;
    }
    catch (MobileServiceInvalidOperationException exception)
    {
        if (exception.Response.StatusCode == HttpStatusCode.BadRequest)
        {
            /* If you don&apos;t have the latest framework */
            Task&lt;string&gt; readContentTask = exception.Response.Content.ReadAsStringAsync();
            readContentTask.Wait();

            if (readContentTask.Result.Contains(&quot;is already taken.&quot;))
                throw new AccountAlreadyTakenException(&quot;Account already taken&quot;, exception);
            else
                throw;
        }
        else
            throw;
    }
</code></pre>
<p>Or even better with the latest version of .NET where you can await on catch:</p>
<pre><code class="language-csharp">try  
    {
        // &#x2026;
    }
    catch (MobileServiceInvalidOperationException exception)
    {
        if (exception.Response.StatusCode == HttpStatusCode.BadRequest)
        {
            /* If you have the latest framework */
            string content = await exception.Response.Content.ReadAsStringAsync();

            if (content.Contains(&quot;is already taken.&quot;))
                throw new AccountAlreadyTakenException(&quot;Account already taken&quot;, exception);
            else
                throw;
        }
        else
            throw;
    }
</code></pre>
<p>AccountAlreadyTakenException being an exception that I created for this occasion. Check out the HttpStatusCode you need to handle and the message writen with it to filter the exceptions.</p>
<p>I recommend using custom exceptions to handle this like I did.</p>
<hr>
<h3 id="finally">Finally</h3>
<p>You have now made the first step for a custom authentication on Azure App Services, by handling user management.</p>
<p>On the next episode, we will see how to grant users the access to the precious [Authorize] methods (baised on claims).</p>
<p>If you have any question or any remark to make please feel free use the comments below, I will be glad to know what you think of all this if some points are unclear or if you have suggestions.</p>
<p>Paul, out!</p>
<hr>
<p>This post is part of a whole:</p>
<ul>
<li>Azure App Services Custom Auth (Part 1: user management)</li>
<li><a href="https://www.pa-roy.com/azure-app-services-custom-auth-part-2/">Azure App Services Custom Auth (Part 2: server authentication)</a></li>
<li><a href="https://www.pa-roy.com/azure-app-services-custom-auth-part-3/">Azure App Services Custom Auth (Part 3: client authentication)</a></li>
<li>Azure App Services Custom Auth (Part 4: cross-provider users) &#x2014; soon</li>
</ul>
<!--kg-card-end: markdown-->]]></content:encoded></item><item><title><![CDATA[Device.OnPlatform<T>(Default)]]></title><description><![CDATA[Xamarin.Forms is an amazing platform.
But it has flaws, such as the lack of Default mechanism for OnPlatform<T>. Let's find out how to implement this.]]></description><link>https://www.pa-roy.com/device-onplatformtdefault/</link><guid isPermaLink="false">6300f01d5409ac12ae7550c8</guid><dc:creator><![CDATA[Paul Roy]]></dc:creator><pubDate>Mon, 09 Nov 2015 12:55:51 GMT</pubDate><content:encoded><![CDATA[<!--kg-card-begin: markdown--><p>Xamarin Forms is an amazing framework despite a lot of bugs.</p>
<p>It gets better each time it is updated and I am pretty confident it will be mature enough to build any app in a close future, providing you have the time and experience to do so.</p>
<p>But as all framework under development it has its flaws.<br>
Sometimes it is big flaws. Usually, people notice big flaws and developpers fix them for the best. Ironically it is not those flaws that bugs me.</p>
<p>Because sometimes it is these minor things that annoy the end-<strike>user</strike> developper but that go unnoticed just because it is not a problem enough to need a quick fix.</p>
<hr>
<h3 id="deviceonplatform">Device.OnPlatform</h3>
<p>And a good example in my opinion is these methods to define platform-specific code:</p>
<pre><code class="language-csharp">OnPlatform&lt;T&gt;(T iOS, T Android, T WinPhone)
OnPlatform(Action iOS = null, Action Android = null, Action WinPhone = null, Action Default = null)
</code></pre>
<p>It seems cool right&#xA0;? It is. It allows us to define values and snippets of code for each platform like this&#xA0;:</p>
<pre><code class="language-csharp">FontSize = Device.OnPlatform&lt;double&gt;(10, 10, 30);
</code></pre>
<p>It is an incredible tool. But one thing bothers me.</p>
<p>Here I have defined a size of 10 for both Android and iOS. It is okay because I do not mind writing twice &#xAB;&#xA0;10&#xA0;&#xBB;. But when it comes to more complex objects with parameters and all I hate to define it twice / outside. I find it awful for maintainability.</p>
<p>So I end up using something like that (once again I took a very simple example but I only do this for complex situations)&#xA0;:</p>
<pre><code class="language-csharp">Device.OnPlatform(
	WinPhone: () =&gt; FontSize = 30, 
    Default: () =&gt; FontSize = 10);
</code></pre>
<p>Which is terribly unsatisfying as I have to use the Action-based method, the only one that support this Default mechanism.</p>
<hr>
<h2 id="implementationofgenericdefaultmechanism">Implementation of generic Default mechanism</h2>
<p>Why not define a Default mechanism for the typed-version ? Probably because it is a bit trickier as a generic method cannot use null as default value (because not every object can take the null value, ex: bool).<br>
But I need it so let&apos;s figure this out.</p>
<p>There are two workarounds&#xA0;: use <code>default(T)</code> or restrict T to classes (<code>where T : class</code>).<br>
I chose to use <code>default(T)</code> because I want to extend this to any type.</p>
<p>So here is my final implementation of <code>Device.OnPlatform&lt;T&gt;(Default)</code> :)</p>
<pre><code class="language-csharp">public static T OnPlatform&lt;T&gt;(T iOS = default(T), 
								T Android = default(T), 
                                T WinPhone = default(T), 
                                T Default = default(T))
{
    return Device.OnPlatform&lt;T&gt;(
    	object.Equals(iOS, default(T)) ? Default : iOS, 
        object.Equals(Android, default(T)) ? Default : Android, 
        object.Equals(WinPhone, default(T)) ? Default : WinPhone);
}
</code></pre>
<p>And the usage&#xA0;:</p>
<pre><code class="language-csharp">FontSize = DeviceExtensions.OnPlatform&lt;double&gt;(WinPhone: 30, Default: 10);
</code></pre>
<p>Which solves my initial problem. And I hope yours too.<br>
Enjoy :)</p>
<p>Paul, out.</p>
<!--kg-card-end: markdown-->]]></content:encoded></item><item><title><![CDATA[HelloWorld]]></title><description><![CDATA[<!--kg-card-begin: markdown--><p>I&apos;ve always wondered what it would like to blog. To be honest, <strong>I&apos;ve always wanted to share thoughts and ideas</strong> on the internet.</p>
<p>But I&apos;ve never had the courage to do it. I always wondered, <strong>on which subject could I write?</strong> Could I say</p>]]></description><link>https://www.pa-roy.com/helloworld/</link><guid isPermaLink="false">6300f01d5409ac12ae7550c7</guid><dc:creator><![CDATA[Paul Roy]]></dc:creator><pubDate>Sun, 23 Aug 2015 19:52:46 GMT</pubDate><content:encoded><![CDATA[<!--kg-card-begin: markdown--><p>I&apos;ve always wondered what it would like to blog. To be honest, <strong>I&apos;ve always wanted to share thoughts and ideas</strong> on the internet.</p>
<p>But I&apos;ve never had the courage to do it. I always wondered, <strong>on which subject could I write?</strong> Could I say something interesting enough? Should I write in french or in english?</p>
<p>Then I met Lionel Cl&#xE9;ment. He is the creator of &#xAB;&#xA0;l&apos;ivre de lire&#xA0;&#xBB; (<a href="http://www.livredelire.com">http://www.livredelire.com</a>), and more recently &#xAB;&#xA0;InWonderland&#xA0;&#xBB; (<a href="http://inwonderland.fr/">http://inwonderland.fr/</a>), a more personal blog.</p>
<p>The guideline on both blogs: he is talking about his passions. And I realized that was <strong>the real deal: share thoughts about passions.</strong></p>
<hr>
<h3 id="aboutme">About me</h3>
<p>I was <strong>born in 1988</strong> in Normandy (you&apos;ll guess I&apos;m french then). I&apos;ve started coding at the age of 14. I have studied <strong>mathematics</strong> and <strong>informatics</strong> in an engineering school (Ensimag) after studying maths / physics / chemistry.</p>
<p><strong>I am a developper</strong>, I have been working on critical industrial systems for a few years. I&apos;ve lead a <strong>mobile</strong> tech group in my previous company and I&apos;ve also teached <strong>algorithmic</strong> at Ensimag.</p>
<p>With Nicolas Saubin (<a href="http://www.nicolas-saubin.com">http://www.nicolas-saubin.com</a>), I am the <strong>co-founder and CTO of Collibris</strong>: <a href="http://www.collibris-app.com">http://www.collibris-app.com</a>, a french mobile and web app about sharing and discovering books. This is the <em>biggest</em> project of my life and it&apos;s highly probable most posts of this blog will be somehow related to Collibris.</p>
<p><strong>I have a LOT of passions</strong>. Some only last for a time, but I&apos;m always willing to try something new. Among those:</p>
<ul>
<li>Music (bass / guitar / singing &#x2014; I&apos;m the bassist of a group)</li>
<li>&#x152;nology (wine tasting &#x2014; I&apos;ve met Nicolas thanks to this)</li>
<li>Beerology (beer tasting)</li>
<li>Magic (cardistry)</li>
<li>Lockpicking</li>
<li>Martial arts</li>
<li>etc.</li>
</ul>
<p><strong>But my main passion is informatics</strong>. I just love being a developper, building apps and software, and everything related to it (agile, testing, user experience, etc.).</p>
<hr>
<h3 id="aboutthisblog">About this blog</h3>
<p>As I&apos;ve said, I&apos;m a techie. On this blog, I&apos;ll be posting my share of code. I will also talk about <strong>anything revolving around code and technical skills</strong>.</p>
<p>This is just the beginning, so <strong>I&apos;m not quite sure exactly how it will look like</strong>. I really hope I&apos;ll be able to connect with people, <strong>providing quality content</strong>, as I&apos;ve seen on many blogs.</p>
<p>With this blog, I&apos;ll try to <strong>express my opinions about coding</strong>. This world has evolved a lot (quicker than any other in my opinion) and is still evolving at an incredible speed. It&apos;s easy to get lost in only a few years.</p>
<p>I also hope that I&apos;ll be able to help other people out with my posts. <strong>Coding always has been about sharing</strong>, and many have helped me with their blogs, I feel this is the opportunity fore me to put another brick in the wall.</p>
<p>See you soon&#xA0;!<br>
<em>Paul, out.</em></p>
<!--kg-card-end: markdown-->]]></content:encoded></item></channel></rss>