Monthly Archives: March 2016

Getting RESTful with Suave

I wanted to implement some microservices and thought, what’s more micro than REST style functions, executing single functions using a functional language (functional everywhere!). So let’s take a dip into the world of Suave using F#.

Suave is a lightweight, non-blocking, webserver which can run on Linux, OSX and Windows. It’s amazingly simple to get up and running and includes routing capabilities and more. Let’s try it out.

Getting Started

Create an F# application and the run Install-Package Suave via Package Manager Console.

Now, this code (below) is taken from the Suave website.

open Suave
open Suave.Filters
open Suave.Operators
open Suave.Successful

[<EntryPoint>]
let main argv = 

    let app =
        choose
            [ GET >=> choose
                [ path "/hello" >=> OK "Hello GET"
                  path "/goodbye" >=> OK "Good bye GET" ]
              POST >=> choose
                [ path "/hello" >=> OK "Hello POST"
                  path "/goodbye" >=> OK "Good bye POST" ] ]

    startWebServer defaultConfig app

    0 // return an integer exit code

Run your application and then from you favourite web browser, type in either http://localhost:8083/hello and/or http://localhost:8083/goodbye and you should see “Hello GET” and/or “Good bye GET”. From the code you can see the application also supports POST.

Let’s test this using Powershell’s Invoke-RestMethod. Typing Invoke-RestMethod -Uri http://localhost:8083/hello -Method Post and you will see “Hello POST”.

Passing arguments

Obviously invoking a REST style method is great, but what about passing arguments to the service. We’re going to need to add the import open Suave.RequestErrors to support errors. We can read parameters from the commands using HttpRequest queryParam

 let browse =
        request (fun r ->
            match r.queryParam "a" with
            | Choice1Of2 a -> 
                match r.queryParam "b" with
                | Choice1Of2 b -> OK (sprintf "a: %s b: %s" a b)
                | Choice2Of2 msg -> BAD_REQUEST msg
            | Choice2Of2 msg -> BAD_REQUEST msg)

    let app =
        choose
            [ GET >=> choose
                [ path "/math/add" >=> browse ]
            ]

    startWebServer defaultConfig browse

Disclaimer: This is literally my first attempt at such code, there may be a better way to achieve this, but I felt the code was worth recording anyway. So from our preferred web browser we can type http://localhost:8083/math/add?a=10&b=100 and you should see a: 10 b:100.

Passing JSON to our service

We can also pass data in the form of JSON. For example, we’re now going to pass JSON contain two integers to our new service. So first off add the following

open Suave.Json
open System.Runtime.Serialization

Now we’ll create the data contracts for sending and receiving our data using, these will be serialized automatically for us through the function mapLson which will see in use soon. Notice we’re also able to deal with specific types, such as integers in this case (instead of just strings everywhere).

[<DataContract>]
type Calc =
   { 
      [<field: DataMember(Name = "a")>]
      a : int;
      [<field: DataMember(Name = "b")>]
      b : int;
   }

[<DataContract>]
type Result =
   { 
      [<field: DataMember(Name = "result")>]
      result : int;
   }

Finally let’s see how we startup our server. Here we use the mapJson to map our JSON request into the type Calc from here we carry out some function (in this case addition) and the result is returned (type inference turns the result into a Result type).

startWebServer defaultConfig (mapJson (fun (calc:Calc) -> { result = calc.a + calc.b }))

Let’s test this using our Invoke-RestMethod Powershell code. We can create the JSON body for this method in the following way.

Invoke-RestMethod -Uri http://localhost:8083/ -Method Post -Body '{"a":10, "b":20}'

References

Suave Music Store
Invoke-RestMethod
Building RESTful Web Services
Building REST Api in Fsharp Using Suave

Setup Powershell to use the Visual Studio paths etc.

This one’s straight off of How I can use PowerShell with the Visual Studio Command Prompt? and it works a treat.

So I amend the $profile file with the following (updated to include VS 2015)

function Set-VsCmd
{
    param(
        [parameter(Mandatory=$true, HelpMessage="Enter VS version as 2010, 2012, 2013, 2015")]
        [ValidateSet(2010,2012,2013,2015)]
        [int]$version
    )
    $VS_VERSION = @{ 2010 = "10.0"; 2012 = "11.0"; 2013 = "12.0"; 2015 = "14.0" }
    if($version -eq 2015)
    {
        $targetDir = "c:\Program Files (x86)\Microsoft Visual Studio $($VS_VERSION[$version])\Common7\Tools"
        $vcvars = "VsMSBuildCmd.bat"
    }
    else
    {
        $targetDir = "c:\Program Files (x86)\Microsoft Visual Studio $($VS_VERSION[$version])\VC"
        $vcvars = "vcvarsall.bat"
    }
 
    if (!(Test-Path (Join-Path $targetDir $vcvars))) {
        "Error: Visual Studio $version not installed"
        return
    }
    pushd $targetDir
    cmd /c $vcvars + "&set" |
    foreach {
      if ($_ -match "(.*?)=(.*)") {
        Set-Item -force -path "ENV:\$($matches[1])" -value "$($matches[2])"
      }
    }
    popd
    write-host "`nVisual Studio $version Command Prompt variables set." -ForegroundColor Yellow
}

The previous version (non-VS 2015) is listed below in case it’s still needed

function Set-VsCmd
{
    param(
        [parameter(Mandatory=$true, HelpMessage="Enter VS version as 2010, 2012, or 2013")]
        [ValidateSet(2010,2012,2013)]
        [int]$version
    )
    $VS_VERSION = @{ 2010 = "10.0"; 2012 = "11.0"; 2013 = "12.0" }
    $targetDir = "c:\Program Files (x86)\Microsoft Visual Studio $($VS_VERSION[$version])\VC"
    if (!(Test-Path (Join-Path $targetDir "vcvarsall.bat"))) {
        "Error: Visual Studio $version not installed"
        return
    }
    pushd $targetDir
    cmd /c "vcvarsall.bat&set" |
    foreach {
      if ($_ -match "(.*?)=(.*)") {
        Set-Item -force -path "ENV:\$($matches[1])" -value "$($matches[2])"
      }
    }
    popd
    write-host "`nVisual Studio $version Command Prompt variables set." -ForegroundColor Yellow
}

Another user on the same question of stackoverlow also put forward the idea of simply changing the shortcut that Visual Studio supply to add the & powershell, like this

%comspec% /k ""C:\Program Files (x86)\Microsoft Visual Studio 12.0\Common7\Tools\VsDevCmd.bat" & powershell"

Creating a Powershell function

We can create commands/cmdlets using C# or combine commands in ps1 files (for example) but we can also implement Powershell functions, which give is the ability to combine existing Powershell commands but wrap them in their own function with their own help etc.

Let’s look at a simple implementation of a tail-like command

Get-Content -Path c:\logs\logfile.log -Wait 

Ofcourse the first thing we might like to do is wrap this in a simple function, like this

function Get-Tail 
{ 
   Get-Content -Path $args[0] -Wait 
}

This works fine, but now maybe we’d like to make it more obvious what argument(s) Get-Tail expects. So we’ll add a parameter which better illustrates the intent via it’s name etc. So now we might have

function Get-Tail 
{ 
   param (
      [Parameter(Mandatory=$true, 
       Position=0, 
       HelpMessage="Path of file to tail")]
      [ValidateNotNullOrEmpty()]
      [string]$Path
   )

   Get-Content -Path $Path -Wait 
}

Here we’ve named the parameter that we expect as Path and we’ve stipulated it’s type. We’ve also added a Parameter attribute to ensure it’s obvious that this is a mandatory field and if the user forgets to supply it, Powershell will ask for it, to that purpose we’ve also supplied a help message so if the user types !? into the prompt for Path, the user will get the help message telling them what’s expected.

This is looking good, but running Get-Help tells us very little about the function so now we can extend this further and make it look like this

function Get-Tail 
{ 
<#
.SYNOPSIS
   Lists the file to standard out and waits 
   for any change which are then also output
.DESCRIPTION
   Get-Tail works a little like the tail 
   command, it allows the user to write a 
   file to standard out and then waits for
   any further changes, these to are written to
   standard out until the user exist the command.
.PARAMETER Path
   The Path to the file to be tailed
.EXAMPLE
   Get-Tail c:\logs\logfile.log
#>
param
(
[Parameter(Mandatory=$true, 
 Position=0, 
 HelpMessage="Path of file to tail")]
[ValidateNotNullOrEmpty()]
[string]$Path
)
 
Get-Content -Path $Path -Wait 
}

Now we have a command written in Powershell which looks and acts like any of the common commands might work, with help.

Let’s quickly review the lines we’ve added – the <# #> is the comment block for Powershell, within it we’ve headings along the lines of .HEADING and below that we’ve just some text to describe the command. The .PARAMETER is more interesting in that we write the parameter name after it (we can have multiple .PARAMETER blocks for multiple params).

To find out what options are available for the help block, type

Get-Help about_Comment_Based_Help

References

Documenting Your PowerShell Binary Cmdlets

Creating a C# CmdLet

So Powershell comes with a lot of commands/CmdLets but as a developer I’m always interested in how I might write my own. Whilst it’s likely that combining existing commands might produce the results you’re after, if it doesn’t we can resort to writing our own command using C#.

Getting Started

  • Create a new Class Library project
  • Go to the project properties and target the version of .NET supported by your installed version of Powershell (to find this out simply type $PSVersionTable into Powershell and check the CLRVersion)
  • Add a reference to System.Management.Automation to locate this browse to C:\Program Files (x86)\Reference Assemblies\Microsoft\WindowsPowerShell\3.0
  • The namespace we need to add is System.Management.Automation

Hello World CmdLet

Now we’ve got everything set-up we need to make our CmdLet do something. Here’s the source for a good old HelloWorld Cmdlet

[Cmdlet(VerbsCommon.Get, "HelloWorld")]
public class GetHelloWorld : Cmdlet
{
   protected override void ProcessRecord()
   {
      WriteObject("Hello World");
   }
}

The CmdLetAttribute takes a string for the verb, in this case I’m reusing the VerbsCommon.Get string. The next requirements is the noun, the name of the Cmdlet. So in this case the two go together to give us the Cmdlet Get-HelloWorld.

We derive our class from Cmdlet as we’re not dependent upon the Powershell runtime, if we were we’d derive from the PSCmdlet.

Importing and using the new CmdLet

Once we’ve built our CmdLet and assuming it’s been built with the same version of .NET as supported by the installed Powershell, we can import the “module” into Powershell using

Import-Module c:\Dev\MyCmdLets.dll

Obviously replacing the path and DLL with the location and DLL you’re installing

Once imported we can simply run

Get-HelloWorld

Autocomplete also works if you type Get-He then press tab and you’ll find Get-HelloWorld presented.

If you need to rebuild your Cmdlet you’ll need to close the Powershell instance to remove the instance from it, I tried Remove-Module MyCmdLets but this only removes its availability to Powershell, i.e. you can no longer run it, but I guess, like in C# applications, once the module is in the AppDomain you cannot fully unload it.

Parameters

Let’s add a parameter to the Cmdlet.

[Cmdlet(VerbsCommon.Get, "HelloWorld")]
public class GetHelloWorld : Cmdlet
{
   [Parameter(Mandatory = true)]
   public string Name { get; set; }

   protected override void ProcessRecord()
   {
      WriteObject("Hello World " + Name);
   }
}

So now, we’ve added a mandatory parameter Name. When we run the Get-HelloWorld Cmdlet we can now supply the name, thus

Get-HelloWorld -Name Scooby

Returning objects

So far we’ve returned a string, but what about if we want to return and object or better still multiple objects, like Get-Process might.

[Cmdlet(VerbsCommon.Get, "HelloWorld")]
public class GetHelloWorld : Cmdlet
{
   protected override void ProcessRecord()
   {
      WriteObject(new HelloObject { Name = "Scooby", Description = "Dog"} );
      WriteObject(new HelloObject { Name = "Shaggy", Description = "Man" });
      WriteObject(new HelloObject { Name = "Daphne", Description = "Woman" });
   }
}

public class HelloObject
{
   public string Name { get; set; }
   public string Description { get; set; }
}

Now running this from Powershell will list two columns, Name and Description and three rows with the name and description as per our objects.

Better still we can now write commands such as

Get-HelloWorld | where {$_.Description -eq "Dog"}

References

Cmdlet Methods

Writing Powershell command (.ps1) files

In a previous post I started to look into using Powershell, but ofcourse the power of commands/Cmdlets comes when they’re either combined or whereby our most common commands exist in files to be run again and again.

So let’s turn an often used command into a ps1 file.

Windows PowerShell ISE (Integrated Scripting Engine)

From the Windows search box (ctrl+R) we can run up the Windows PowerShell ISE. This gives us, both an editor and also a command prompt for writing and testing our command scripts.

You can also run this application from the command line using powershell_is or better still via the alias ise.

In the editor let’s type

Get-Process | where {$_.CPU -gt 1000}

Now save this file as Top-Cpu.ps1

Running our new command

We can simply drag and drop a ps1 file from Windows Explorer onto the Powershell window to fill in the fully qualified path on the command line, pressing enter we can then run the file. Obviously if you know the full path you can do this yourself by typing the same into the command prompt.

Specifying parameters

It may be that our ps1 file is perfect as it is, but it’s also quite likely we’ll want to allow the user to change some values in it at runtime, i.e. using command line arguments/parameters.

To specify parameters in our script we write

param(cpu=1000)

This defines a parameter named cpu and gives a default value, in this case 1000. If we change our script to look like this

param($cpu=1000)
Get-Process | where {$_.CPU -gt $cpu}

where you’ll notice $cpu is the placeholder/variable where the parameter is used. We can now run this script as Top-cpu.ps1 and the default parameter is used. Or we might write Top-cpu.ps1 7000 to supply a new parameter.

Multiple parameters

We can command separate our parameters to include multiple params, like this

param($value=1000, $field="CPU")
Get-Process | where {$_.$field -gt $value}

Maybe not so useful in this specific script, but you get the idea.

References

Windows PowerShell: Defining Parameters

Powershell $profile

What’s the purpose of the $profile

The $profile (like a bash script configuration) allows us to configure the way our Powershell command shell looks, or sets the default location, we can add commands and aliases etc.

Where’s the $profile and does it exist?

Typing the following will result in Powershell telling us where the Microsoft.PowerShell_profile.ps1 file is expected to be

$profile

Just because $profile outputs a path, does not mean there’s a file’s there. It’s simply telling us where it goes to get the profile, we may still need to created one, instead we can use the following

We can find out whether a $profile already exists using

Test-Path $profile

Test-Path determines whether all elements of a path exists, i.e. in this case, does the file exist

Creating the profile file

Typing

New-Item -path $profile -itemType file -force

will create a new item (in this case a file) at the location (and name) supplied by the $profile variable. The force switch ensure the file is overwritten if it already exists.

The ps1 file is just a text file, so from the command line you can run Notepad or powershell_ise (or ofcourse from the Windows GUI you can do the same) and edit the file, allow us to enter the commands that might want available from session to session.

What resource names exist in my WPF application

Occasionally I need to get at the names of the resources in an assembly, usually this coincides with me trying to use a resource which either doesn’t exist of I otherwise make a typo on its name.

This little snippet simply allows us to iterate of the resources in an assembly and returns an array of the key names

public static string[] GetResourceNames(Assembly assembly)
{
   string resName = assembly.GetName().Name + ".g.resources";
   using (var stream = assembly.GetManifestResourceStream(resName))
   {
      using (var reader = new System.Resources.ResourceReader(stream))
      {
         return reader.Cast<DictionaryEntry>().
                    Select(entry =>
		       (string)entry.Key).ToArray();
      }
   }
}

Throwing/rethrowing exception from a continuation onto the Dispatcher

Even with async/await we still have a need for using Task continuations and ofcourse we need to handle exceptions within, or from, these tasks and their continuations.

A problem can occur in a WPF application for example, where the exception seems to get lost, for example from a ICommand handler I has such a situation where I couldn’t seem to catch the exception and neither did it propagate through to any unhandled exception handlers.

In the example below, we’ll assume that RunAsync returns a Task and we want to do something after the task completes on the calling thread (for example if the calling thread was the UI thread), we might have something like this

RunAsync().
   ContinueWith(tsk =>
   {
       // do something UI specific
   }, TaskScheduler.FromCurrentSynchronizationContext());

If we have exceptions occur in the RunAsync method, then we would maybe write something like this

RunAsync().
   ContinueWith(tsk =>
   {
      if(tsk.IsFaulted)
          throw tsk.Exception;

       // do something UI specific      
   }, TaskScheduler.FromCurrentSynchronizationContext());

If you don’t like the exception code mixed with the non-exception you could ofcourse create a continuation that is only called when a fault is detected, using TaskContinuationOptions.OnlyOnFaulted

This will correctly handle the exception and throw it, but you’ll probably find it just seems to disappear after the throw and doesn’t even appear in the various unhandled exception handlers – meaning the worse case occurs for an exception, in that it simply disappears.

What we really want is to throw the exception onto the Dispatcher thread so that an unhandled exception handler can at least alert the user that a problem exists. We can do this using the following line of code

Dispatcher.CurrentDispatcher.BeginInvoke(new Action(() => { throw ex; }));

Now, unfortunately this means the stack trace is lost as we’re not simply re-throwing the original exception, but on the plus side we now actually see the exception.

Finally decided to learn a little Powershell

For years I’ve been thinking of learning Powershell, but I’ve never really had a real need for it, so subsequently it got neglected for such a long time.

I’ve finally decided to spend some time with it and see what it can do for me. Let’s start by looking at some of the basics to getting started with Powershell.

Commands (or Cmdlets)

Built-in commands are also known as Cmdlets, although I’ve also seen that some users prefer to think of Cmdlets as multiple commands – more like batch files. Either way, I’ll use the word interchangeably.

Note: Commands are case-insensitive

Let’s jump right in

Let’s have a look at an example command in Powershell

Get-Process | where {$_.CPU -gt 1000}

In the above, the command is Get-Process. This returns a list of the current processes running on your computer. Running Get-Process will result in eight headings (on my machine). Get-Process actually returns data as objects which we then pipe using | to the where clause.

The where clause syntax uses the braces {} to group together to form a block (much like blocks in C++ etc.). Within this block we use the $_ syntax which is a placeholder which in essence means “the current value” from the Get-Process command. In other words each item return from Get-Process is piped to the where clause and the $_ indicates the current value. From this we use standard object oriented style dot notation to get at a property on the item $_, in this case the property is CPU.

Note: The $ is used for to denote a variable, whether it’s supplied by default by Powershell or created by the user

Next up with have the -gt which as I’m sure you can determine, means “greater than” and ofcourse on the right hand side of this expression is the value we want to test for.

How do we determine what properties exist on an object?

In the previous command we used the CPU property of the results from Get-Process but how did we know that property existed and are there more properties we could have used? Ofcourse, there’s documentation which can tell us such things, but we can also use another Powershell command to tell us.

By typing the following

Get-Process | Get-Member

We can pipe the Get-Process object into Get-Member which will output a list of properties (and other members) of the type returned by Get-Process. If you run this you’ll find the CPU property (and many others).

Actually using the Powershell command prompt we can also view the properties by pressing ctrl+space after the dot, this allows us to list all available member names for an object. In the case of Get-Process this will list 122 possible member names.

Getting help

Powershell’s help system is very powerful. Simply type

Get-Help

to view the help on the Get-Help command. From here you’ll see you can type

Get-Help Get-Process

which will display help on the Get-Process command. We can also view examples for this command using

Get-Help Get-Process -examples

Aliases

Some commands are also aliased, meaning our original Get-Process | where {$_.CPU -gt 1000} can be rewritten as

ps | where {$_.CPU -gt 1000}

ps is simply an alias to the longer winded Get-Process and we can find an alias (if one exists) using the following

Get-Alias -definition Get-Process

Ctrl+Space

I noted previously that you can get a list of member names by pressing the combination ctrl+space after the dot, this is also useful after the – operator, for example when looking for alternatives to gt we can type – then ctrl+space and a list of options appears which includes, bnot, eq, f and more.