Tuesday, 3 May 2016

Swagger based Web API with C# (2/2) : NSwag

This is the second of two blog posts on using Swagger with C#, and gives a step-by-step guide to quickly creating a C# web-client from a web-API using the Swashbuckle open-source package.

The previous blog entry covered setting up a trivial web-API in C#.



What's NSwag?

NSwag is an open-source toolset for turning Swagger markup into a C# client for a web-API, curated and developed by Rico Suter, who is very responsive on any issues.

NSwag Studio is a component of the toolset which provides a straightforward user-interface to the the client creation process.  The application has an installer for Windows (or a zip if you prefer) and can notify you on start-up if there is a newer version. The latter is very useful because the NSwag project is active and enhancements and fixes are released as soon as they are coded and tested.



Let's Make a Client.

We're going to make a quick client application to call an existing web-API. If you haven't a simple web-API to practice against, you can make yourself one following the previous blog entry.


Step 1 - Install NSwag.

  • Visit the NSwag Studio page.
  • Download and run the MSI to install the application.
  • Then run it.


Step 2 - Get the Specification.

  • On the input pane (left), choose the Swagger Specification tab.
    • I like this best, as it's application-neutral.
  • Find the URL for your specification and paste it into the input box.
    • For the example it is <your-site>/swagger/docs/v1
  • If you only have the Swagger text, paste it into the JSON area.
  • Click Load.




Step 3 - Generate the Client Code.

  • On the output pane (right), choose the CSharp Client tab.
  • Choose a namespace.
  • Tick Generate Client Classes.
  • Tick Generate Client Interfaces.
  • Click Generate Outputs.



Step 4 - Integrate.

  • Copy the code from the bottom box on the right-hand pane.
  • Create a simple application (I made a Windows form with one button).
  • Paste the copied code into a file like SampleWebApi.Generated.cs.
    • Ending in .Generate.cs suppresses Resharper whinges.
  • Call the client from your code (example below).




Swagger based Web API with C# (1/2) : Swashbuckle

This is the first of two blog posts on using Swagger with C#, and gives a step-by-step quick-start for creating a trivial web-API using Swashbuckle open-source package, to get something up and running.

A follow-up blog entry covers client code-generation for a C# client platform.


What's Swagger?

Web-APIs are trending at the moment and everyone wants one.

Swagger is the defacto leading industry standard - at least, for the time being - and is a well-supported markup language for specifying web-APIs.

There are plentiful toolsets out there for generating Swagger markup from web-API code, and generating client code from Swagger markup.


What's Swashbuckle?

Swashbuckle is an open-source toolset for generating Swagger markup from your C# web-API.  You get a documentation portal and test-harness for free, both of which can be accessed by your API users (and their integration tools).


Quick Start Guide


Step 1 - Create a Web API project.

  • Create a new VS2015 project.
  • It should be an ASP.NET Web Application.
  • Choose Empty Project but tick Add folders and core references for Web API.

  • Add a class, SampleController and derive it from ApiController.
  • Add a Get method like the one below.


  • View the Web properties for your project.
  • Paste the Project URL into the Start URL field.
  • Then add api/ followed by your controller name.

  • Run the application and see that the controller Get method works.


Step 2 - Add Swashbuckle

  • Add the Swashbuckle package from Nuget in Visual Studio.

  • Edit the Swagger.Config file created by Nuget in App_Start.
  • Modify the configuration to read as below.
  • Note that we filled in a path for the XML comments file.
 

  • Set the project build properties to create the XML comments file.

  • View the Web properties for your project.
  • Set the Start URL now to be the documentation URL.
 

  • Add a route attribute to your method.
  • Also add some XML method documentation.

  • Run up your project and view the API documentation portal.
  • Click on the text Sample to see the Get method.
  • Note that our XML comment propagated to the portal.

  • Click on the Get method to see its definition.
  • If the method took arguments, they would be displayed here.
  • Click on the Try it out! button to make a call to the API.


Next?

Now you have a basic web-API setup: now you can make the return type more complex, add parameters, add more methods, add more controllers...

Remember to comment the parameters, methods and controllers for a rich, self-documenting API.

There are plenty of code-generators for generating clients in various languages from a Swagger specification.  If you want to create one in C# you could skim my next post, on NSwag.

Friday, 25 September 2015

How to set up Mono in Amazon Web Services

We want to run Mono in an AWS EC2 Linux instance but the default yum package for Mono is really out of date: soooo out of date that it won't even compile the latest source code (remember that to compile Mono source you need an already functioning, recent version of Mono)!

So we're going to have to build from scratch. Before we start, you will need to:
This article was pulled together from multiple sources - but Brad's post was particularly useful.


Setting up the Prerequisites


We want the latest version of all build components, plus the Extra Packages For Enterprise Linux for which yum is already configured but which is disabled by default.  So, edit the repository definition to enable the first EPEL entry (which is the run-time) by entering the following commands:
cd /etc/yum.repos.d
sed '0,/^enabled=0/s/enabled=1/' <epel.repo >/tmp/epel.repo
sudo cp /tmp/epel.repo .
Now we can update all repositories to their latest versions:
sudo yum update
And get some build tools that aren't installed by default:
sudo yum install autoconf libtool gettext make automake gcc gcc-c++


Getting the Sources


Install git so that we can download the sources (the git install at time of writing is about 10MB):
sudo yum install git
Make somewhere to download the Mono sources and download them (be cognisant of the size):
mkdir src
cd src
git clone https://github.com/mono/mono


Compiling the Sources


Build the Mono bootstrapper:
cd mono
./autogen.sh --prefix=/usr/local
make get-monolite-latest
Use the bootstrapper to build Mono, then install it:
make EXTERNAL_MCS="${PWD}/mcs/class/lib/monolite/basic.exe"
sudo make install
But that's not enough.  If you were to return to the source tree and make check you would find that one or two of the tests fail - in particular, one around unhandled exceptions in mscorlib.  We can't accept that but at least the newly installed Mono is better than the monolite version.  So let's clean up and compile again: this time with our newly built version as the compiler.
make clean
./autogen.sh --prefix=/usr/local
make
sudo make install
You should make check now if you have time, just to prove that the new version is clean.
If you wish to try out your new toy, copy the text below into a file called HelloWorld.cs:
public class HelloWorld {
    public static void Main() {
        System.Console.WriteLine("Hello World");
    }
}
Then compile and execute, by:
mcs HelloWorld.c
mono HelloWorld.exe

Monday, 21 September 2015

Connecting to an AWS Linux Instance

Connecting to a Linux EC2 Instance over SSH


So you've created a Linux EC2 instance in Amazon Web Services, with a key-pair, and now you need to connect to it over SSH.  For this we'll need:
  • A copy of the PuTTY and PuTTYgen programs, downloaded from the internet.
  • Your key file that was generated when you created the instance.
  • Your instance's IP address, which you can get from the Amazon EC2 page.

Downloading PuTTY and PuTTYgen

PuTTY is a free Telnet and SSH client which we will use to connect to our Linux instance.
PuTTYgen is a tool which will convert our key-file into a form suitable for PuTTY.
The tools are in beta, but they have been for years, like Google products.  They're stable.

Download PuTTY and PuTTYgen from the PuTTY download page by clicking each EXE.
Save them to your local hard-drive wherever is easily accessible: no installation required!



Converting your .PEM key-file to .PPK

To connect to your instance using PuTTY you need a private key file (ending in .ppk).
We'll use PuTTYgen to convert our Amazon key-file (ending in .pem) to that format.
Click the PuTTYgen binary to start the conversion program:


Ensure that SSH-2-RSA is selected as the type, then click Load.
Pick the .pem key-file from Amazon (choose All Files in the file-type drop-down).
Then click Open to load the key:


Once the key is loaded, it can be saved in .ppk format.
You can add a passphrase if you are happy to type that every time you connect.
Then create the private key file in a memorable location by clicking Save private key.


Now close the PuTTYgen application.


Connecting using PuTTY

Open the PuTTY application by clicking it.
In the Host Name box enter ec2-user@ followed by the IP address for your AWS instance.

Then expand the SSH node (under Connection in the left hand side-bar) and expand Auth.
Click Browse and select the private key (.ppk) file that you saved earlier.
Then click Open to connect to your Amazon instance.


And we're done.

Creating an AWS Linux Instance

Creating an Amazon EC2 Linux Micro Instance

We're going to create a Elastic Compute (EC2) micro instance in AWS running Amazon's own cut of Linux.  It's free-tier eligible but if you aim to try to stay free, remember to set up alarms and alerts to keep you informed of your usage and optionally shut down the instance if you hit the free-tier limit.

Log on to AWS and click the EC2 link (main pane, top left, under Compute):


Choose your closest region (menu-bar, top right) and click Launch Instance:


Tick the Free Tier Only checkbox (left side-bar) and choose your image.
Choose Amazon Linux AMI, in my case it's top of the list.  Click Select to the right of it:


Select a free tier Amazon Linux instance (in my case the t2.micro at the top of the list).
Then click Review and Launch:


This generates a mostly complete configuration.  Check it over to be sure.
If your desktop machine has a fixed IP address (or range), edit your security group.
Edit the tags to give your instance a name (add a tag called Name and set its value).
Then click Launch.


Select to Create A New Key Pair from the drop-down and enter a memorable name.
Then click Download Key Pair and save it to a safe location which you'll remember.
If you lose the downloaded file you won't be able to login to your instance so keep it safe!
Now click Launch Instances to finally start-up your new virtual machine!


It will take about 5 minutes to launch your instance: go make a cup of your beverage of choice.
And we're done!  Now we need to connect to it!

Next up: Connecting to an AWS Linux Instance

Sunday, 8 March 2015

Free Speech

I've always wanted to do some basic speech analysis using comforting, old C#.
The pretext is simple, but any implementation would certainly be non-trivial:
  • Take some spoken sentences.
  • Break down each sentence into its words.
  • Analyse the words for their component phonemes.
  • Build a library of these by analysing multiple sound samples.
  • Tease out the commonality and factor out accent and expression.
  • Construct a mechanism for recombining the sounds and applying expression.
  • Voila! Speech synthesis (like no-one's done that, already - ah! the arrogance!).
If I can get as far as extracting and analysing the phonemes, I'll have learned something!

Firstly, I'll need some voice samples:
  • EUSTACE is an academic site with some royalty free downloads - they'll do.
  • The voices are mostly expressionless and the quality is pretty good.
  • They're available as either ESPS files (meh!) or RIFF (.wav) files.
  • ESPS is awkward so let's go with the WAVE files.
On to the parsing of the files:
  • This article on the Microsoft site on the WAVE format has typos on field sizes.
  • This one is much better: concise, clear and seems free of fundamental errors.
  • The parsing is trivial: either write a simple class or wrap the Win32 utilities.
I'll also need a free Fast Fourier Transform implementation for the frequency-analysis:
  • I've used ExoCortex before: that was for .NET 2 and could do with refactoring.
  • Better seems to be Lomont FFT which is more up-to-date (2010) and compact.
  • It's kind of Chris to have coded and shared it, and the quality seems good.
  • Briefly searching t'internet yields no bug-whines.
  • Just a few control-comments to help ReSharper swallow it without hiccoughs.
All set up! Now for some exploratory coding.

Tuesday, 2 December 2014

Use of "await" with WCF-lifetime dependency injection (SimpleInjector)

Found an issue where SimpleInjector WCF-lifetime dependency-injection is broken by asynchronous methods.  The code in question is as follows.  (The deferred construction is performed because the legacy repository is not required by any of the other methods on the class)

        public async Task<UnitQueryResult[]> GetUnitsByVinAsync(string vin)
        {
            return await ExecuteFaultHandledOperation(async () => {
                var result = (await _factory
                    .Build<ISalesForceRepository>()
                    .GetUnitWithReferencesByVin(vin)) ?? new UnitQueryResult[0];

                if (_settings.IsLegacyUnitLookupEnabledForSalesForce)
                {
                    result = result.Concat(
                        (await _factory.Build<ISvrLegacyRepository>()
                            .GetUnitWithReferencesByVin(vin)) ??
                                new UnitQueryResult[0]).ToArray();
                }
                return result;
            });
        }

The exception raised by the yellow code when called from a WCF method is:

The registered delegate for type ISvrLegacyRepository threw an exception.
The ISvrLegacyRepository is registered as 'WCF Operation' lifestyle, but
the instance is requested outside the context of a WCF Operation.

The reason is clear but worrying … by the time the method on the legacy repository is called, the original thread (with its context) has been lost due to the prior await a method on the other repository … so a workaround would be to instantiate the legacy repository before the first await – for example:

        public async Task<UnitQueryResult[]> GetUnitsByVinAsync(string vin)
        {
            return await ExecuteFaultHandledOperation(async () => {
                var legacyRepository = _settings.IsLegacyUnitLookupEnabledForSalesForce?
                    _factory.Build<ISvrLegacyRepository>():
                    null;

                var result = (await _factory
                    .Build<ISalesForceRepository>()
                    .GetUnitWithReferencesByVin(vin)) ?? new UnitQueryResult[0];

                if (legacyRepository != null)
                {
                    result = result.Concat(
                        (await legacyRepository.GetUnitWithReferencesByVin(vin)) ??
                        new UnitQueryResult[0]).ToArray();
                }
                return result;
            });
        }

However, that makes for fragile code, because it depends on the whole call-chain before the use of the factory: if any method in the call-stack prior to a use of the factory to instantiate a WCF-lifetime object has already performed an await, the WCF context is unavailable (we’re now running on a different thread, even though the WCF context is still alive) and instantiation via the factory will fail.  And that obviously won’t be picked up at unit-test L

So, another clear reason to strongly prefer all dependencies to be resolved by the constructor wherever possible.