Migrating Service Fabric Sample Voting App to ASP.NET Core

Service Fabric is emerging as popular hosting model for microservices, due to its scalability, resilience, and powerful service orchestration capabilities. The fact that it can run anywhere (Azure, other cloud providers, and on-prem) makes for a compelling story, particularly when considering that single cluster can be stretched across multiple locations (see this great blog post by my Mexia colleagues talking about a proof-of-concept hybrid cluster). In my recent interview for SSW TV, I talk about Service Fabric being “PaaS for DevOps”.

Recently Microsoft introduced support for ASP.NET Core stateless services. This is especially relevant when building Service Fabric application in Visual Studio 2017 which has built-in support for .NET Core. However, it can be a bit tricky trying to migrate existing .NET Web API services to ASP.NET Core – which is the subject of this post.

Background

Programming for Service Fabric is not necessarily that difficult, but it can be a learning curve to understand how to implement services that take full advantage of the platform – especially when it comes to leveraging the built-in resilience across stateful replicas, designing a partition scheme, and managing inter-service communication. Fortunately, Microsoft has provided several sample applications to help get started.

Several months ago I ran an Instructor Led Lab at Microsoft Ignite Australia on Service Fabric, using a variation of a simple Voting app demo provided in a lab by Microsoft. My modified version (which included a couple of extra features like a total ballot count and application version display) was built in Visual Studio 2015 with Update 3 using version 2.4.164.9494 of the Service Fabric SDK. The extra feature of adding as ballot count was useful in a demo for the Global Azure Bootcamp where I made some “breaking” code changes that unfairly gave Trump multiple votes in each ballot cast – thus triggering an automated rollback via a custom health check testing that the total ballots equals the total number of votes registered. Here’s a screenshot of the modified version (showing a proportional vote count that I wish had represented reality last November):

image

The architecture of the application is quite simple: it consists of a simple stateless Web API service which hosts a Single Page Application (SPA) using Angular JS that serves as the UI. The votes are stored in a stateful service:

image

The demo worked really well, and the code is available on GitHub.

If you export the package and deploy it to a Service Fabric cluster running the current runtime version (5.6.220.9494 at the time of writing this), the application will work as expected. You can also open the solution in Visual Studio 2017 (I used the Community edition, v15.2 with updates and the latest Service Fabric SDK installed) and it will also compile and deploy in debug mode.

However, when you create new Service Fabric projects in the VS 2017, your project templates look different than in VS 2015. Here’s the VS 2015 version:

image

And here’s the VS 2017 version:

image

Notice the difference? “Stateless Web API” has now turned into “Stateless ASP.NET Core” – indicating Microsoft’s commitment to ASP.NET Core.

Migrating to ASP.NET Core

If you want to migrate your Web API to ASP.NET Core, you will need to make a few changes to the code. Here are the changes I needed to do to migrate the Voting application (assumes that you are starting with my version of the original solution available on GitHub).  I found it easiest to just create the solution from scratch in Visual Studio 2017 (start with a Service Fabric application named “Voting”) and import/copy the code from the original where indicated below.

VotesDataService

  • Create this project as a “Stateful Service” service template
  • Add the following Nuget packages:
    – Microsoft.ServiceFabric.Services.Remoting  (v2.6.220)

    • Copy the IVotingDataService.cs and VotingDataService.cs files from the original solution into the project (just as they are, no changes necessary)
    • Build the project

VotingService

  • Create this project as a “Stateless ASP.NET Core” service template, with a type of “Web API” and version “ASP.NET Core 1.1” (no authentication):
    image
  • Add a project reference to the VotingDataService project.
  • Add the following Nuget package:
    – Microsoft.ServiceFabric.Services.Remoting (v2.6.220)
  • Copy the code from the ServiceEventSource.cs file from the original solution and use it to completely overwrite the code in the existing file (just as it is, no changes necessary)
  • Copy the code from the VotingService.cs file from the original solution and use it to completely overwrite the code in the existing file (ignore syntax errors as these will be fixed up in subsequent steps)
  • Add the following using statements to the VotingService.cs file:
    using Microsoft.ServiceFabric.Services.Communication.AspNetCore;
    using Microsoft.AspNetCore.Hosting;
    using Microsoft.Extensions.DependencyInjection;
    using System.IO;
  • Replace the code in the CreateServiceInstanceListeners() method with the following code:image
  • Create a new HTML file called index.html and copy all code (as is) from same file in original project
  • Modify the code in lines 41-43 as highlighted here:image
  • Find and replace all instances of “../api/” with “./”  (there should be five instances)
  • Change the path in $http.get(‘./votes’) (~line 73) to just “./”  (i.e. remove “votes’)   
  • Change the Copy to Output build property on this file to “Copy always”
    image
  • Add a new folder to the project named Models
  • Right-click the Models folder and select “Add –> New Item…” from the context menu
  • Under Visual C# –> ASP.NET Core, choose “Class” and name the file Vote.cs
  • Add two new properties to the class so that it looks like this:image
  • Delete the ValuesController.cs file the Controllers folder
  • Right-click the Controllers folder and select “Add –> New Item…” from the context menu
  • Under Visual C# –> ASP.NET Core –> Web –> ASP.NET, choose “Web API Controller Class” and name the file VotesController.cs
  • Copy the code from the VotesController.cs class in the original project to this new file
  • Make the following modifications to the file:
    – Remove using statement for System.Web.Http
    – Remove using statement for System.Net.Http.Headers
    – Add the following using statements to the file:
       using System.Collections.Generic;
    using System.Linq;
    using Microsoft.AspNetCore.Mvc;
    using VotingDataService;
    using VotingService.Models

    – Change class inheritance from ApiController to Controller
    – Change the return type of the Get() method to Task<List<Vote>>
    – Change the highlighted lines in the Get() method to appear as follows:      image
    – Change the return type of the GetTotalBallots() method to Task<string>
    – Change the highlighted lines in the GetTotalBallots() method to appear as follows:image– Change the return type of the GetAppVersion() method to Task<string>
    – Change the highlighted lines in the GetAppVersion() method to appear as follows:

    image
    – Change the return line in the Post() method to:
    return new HttpResponseMessage(HttpStatusCode.NoContent);
    – Change the return line in the Delete() method to:
    return new HttpResponseMessage(HttpStatusCode.NoContent);
    –  Add the following attribute to the GetFile() method:
    [Produces(“text/html”)]
    – Change the return type of the GetFile() method to string
    – Modify the method body as highlighted below:

    image

  • Build and deploy!  The app should work the same way as the original version.

NOTE: Do not run the app in Internet Explorer 11 as I’ve found it won’t work. Try Google Chrome or another browser instead.

Note that the code in the Controller class is much simpler! And there is no need to use an HtmlMediaFormatter class as in the Web API version.

The final version of this can be found on GitHub as well. Of course, just days before I finally got around to publishing this, Microsoft released its own version of an upgrade for this app! However, they’ve re-implemented it as a proper MVC app instead of an SPA.  Still, they have not included updated lab instructions to build it yourself. Hopefully I will get to do this sometime soon and will attach it to the GitHub repo.

About Dan Toomey
Enterprise integration geek, Microsoft Azure MVP, Pluralsight author, public speaker, MCSE, MCT, MCTS & former professional musician.

8 Responses to Migrating Service Fabric Sample Voting App to ASP.NET Core

  1. Pingback: Microsoft Integration Weekly Update: July 31 | Hooking Stuffs Together

  2. Pingback: Serverless Logging & Alerting with Service Fabric & Azure Event Grid | Mind Over Messaging

  3. Pingback: Serverless Logging & Alerting with Service Fabric & Azure Event Grid - BizTalkGurus

  4. Caoimhe says:

    This is great, thanks – however I had an issue with WebListenerCommunicationListener as I am using ASP.NET Core 2.0.

    This was resolved by using HttpSysCommunicationListener instead and installing the Microsoft.ServiceFabric.AspNetCore.HttpSys package to use instead of the Microsoft.ServiceFabric.AspNetCore.WebListener package.

    https://stackoverflow.com/questions/45701503/how-to-use-weblistenercommunicationlistener-in-service-fabric-asp-net-core-2

  5. Thanks for sharing Dan!
    How would you implement partitions on both services (Web + Data)?
    I wander how it would look like in the CreateServiceReplicaListeners method.
    Microsoft wrote about this in this page: https://docs.microsoft.com/en-us/azure/service-fabric/service-fabric-concepts-partitioning
    but their example is based on HttpCommunicationListener and not on KestrelCommunicationListener like in the example

    • Dan Toomey says:

      That’s a really good question, Guy. I might have a look at upgrading this example to use partitioning when I get some time (which unfortunately won’t be within the next few weeks, given the upcoming MVP Summit, Global Integration and Global Azure bootcamps!)

      One thing to be aware of is that partitioning would not be required on the stateless service, as you can simply deploy that on all nodes and requests would load balance automatically. It’s really only applicable to the stateful service. The first challenge would be to come up with a good partitioning scheme, something that you would expect to evenly distribute the service calls.

      By the way, if you want to see a presentation that shows this example being upgraded in a self-healing deployment & rollback, feel free to check out this recording: https://www.youtube.com/watch?v=HWHZKHvk_9Q&list=PLW-BLrn2azoRfompiZIXzkO5-Q8s3cDmV&index=4

Leave a comment

John Glisson - Geek of the Cloth

Thoughts on integration, technology and what-not...

Prashant BizTalk And Azure Integration Blogs

My Integration Experiences - BizTalk And Azure Integration

The CRUCIBLE

THINK: It's not illegal....yet.....

Architecture for cloud and integration

Abdul Rafay's experiences with software architecture, integration, cloud and things around it.

BizTalk musings

Issues, patterns and useful tips for BizTalk development

EAI Guy.net

Enterprise Applicaiton Integration and SOA 2.0

Connected Pawns

Mainly BizTalk & Little Chess

Adventures inside the Message Box

BizTalk, Azure, and other tools in the Microsoft stack - Johann Cooper

Biz(Talk)2

Talk, talk and more talk about BizTalk

Richard Seroter's Architecture Musings

Blog Featuring Code, Thoughts, and Experiences with Software and Services

Sandro Pereira BizTalk Blog

My notes about BizTalk Server 2004, 2006, 2006 R2, 2009, 2010, 2013 and now also Windows Azure BizTalk Services.

Mind Over Messaging

Musings on BizTalk, Azure, and Enterprise Integration

WordPress.com News

The latest news on WordPress.com and the WordPress community.