Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / Hosted-services / Azure

Build a Microservice with Service Fabric on Windows Server

4.30/5 (5 votes)
21 Apr 2016CPOL5 min read 47.7K   986  
Build a microservice with Service Fabric on Windows Server 2012 using ASP.NET 5 and Service Fabric SDK

Introduction

Microservices architecture style is on the rise of becoming popular. There are a lot of documents/examples on how to create a microservice in Java and docker container but not in .NET using Service Fabric. This article will explain the importance of microservices and clear some confusion of how to create an ASP.NET Web API RESTful microservice using Azure Service Fabric just released in November, 2015. The sample code will also be attached as a reference.

Background

According to the paper written by Martin Fowler and James Lewis here, “the microservice architectural style is an approach to developing a single application as a suite of small services, each running in its own process and communicating with lightweight mechanisms, often an HTTP resource API. These services are built around business capabilities and independently deployable by fully automated deployment machinery. There is a bare minimum of centralized management of these services, which may be written in different programming languages and use different data storage technologies. “ The microservice architecture style has the following pros and cons.

Pros:

  • Enable you to select the most appropriate technology stack. No need to rely on a framework to do everything:
  • Have much smaller codebases so deployment and build times are much quicker
  • Allow you to release smaller change sets
  • Are easier and more cost-effective to scale, as they allow you to focus on scaling just those services that need scaling and not your whole application

Cons:

  • Increase the development time of new features at the beginning
  • Can make application refactoring difficult though techniques like API versioning can mitigate this
  • Introduce additional operational complexity as you have many moving parts that need to be monitored closely

In order to make the microservice work correctly, we will need to ensure the following four things are necessary. They also reflect the above definition and the nine characteristics listed in the paper.

  1. Small Services◦Organization around business capabilities
    • Running in its own process
  2. Service Discovery
    • Service running in its own process communicating with HTTP
    • Deployed as a fully self-contained component
    • Smart endpoints and dumb pipes
  3. Automated Monitoring and Management◦Infrastructure automation
    • Design for failure
    • Decentralized governance
  4. Low Friction Deployment
    • Can be individually scaled and updated

Azure Service Fabric is a platform for reliable, hyperscale, microservice-based applications. It is available both on-premises with Windows Server 2012 as well as in the cloud with Azure.

Image 1

Microsoft provided a good tutorial here, but it did not provide an example on how to build a microservice using ASP.NET Web API with which most .NET developers are familiar. The ASP.NET Web API is also the most used to create RESTful services in .NET nowadays.

Prepare the Development Environment

1. Prerequisite

The following operating system versions are supported for development:

  • Window 7 with PowerShell 3.0 or higher
  • Windows 8/Windows 8.1
  • Windows Server 2012 R2 (Used for testing code in this article)
  • Windows 10

2. Install the Service Fabric runtime, SDK, and Tools

The following Web Platform Installer configurations for Service Fabric development can be used:

3. Enable PowerShell Script Execution

You will need to enable the PowerShell script execution by running the following command from a PowerShell command window as an administrator.

PowerShell
Set-ExecutionPolicy -ExecutionPolicy Unrestricted -Force -Scope CurrentUser

4. Create a local cluster if not there by running the following PowerShell script from the Service Fabric SDK folder.

PowerShell
& "$ENV:ProgramFiles\Microsoft SDKs\Service Fabric\ClusterSetup\DevClusterSetup.ps1"

Build a RESTful ASP.NET Web API Stateless Microservice

I could not really find a tutorial for this purpose. The following two tutorials are close but not exactly or not easy to follow. So I combined the following two tutorials and made the code working as I expected because I wanted to have the stateless service features and did not want to do self-hosting.

The high-level steps are as follows:

Step 1: Launch Visual Studio 2015 as an administrator, and create a new Service Fabric application project named HelloWorld.

Step 2:  Create a stateless service project named HelloWorldStateless:

Step 3: Create folder structure in the same way as that for an ASP.NET Web API project.

Image 2

Step 4: Add code for DefaultController.cs:

C#
namespace HelloWorldStateless.Controllers
{
    using System.Collections.Generic;
    using System.Web.Http;
    using System;

    [RoutePrefix("helloworld")]
    public class DefaultController : ApiController
    {
        // GET api/values
        [Route("values")]
        public IEnumerable<string> Get()
        {
            return new string[] { "value1", "value2" };
        }

        // GET api/values/5
        [Route("values/{id}")]
        public string Get(int id)
        {
            string ret = Convert.ToString(id);
            return ret;
        }

        // POST api/values
        [Route("values")]
        public void Post([FromBody]string value)
        {
        }

        // PUT api/values/5
        [Route("values/{id}")]
        public void Put(int id, [FromBody]string value)
        {
        }

        // DELETE api/values/5
        [Route("values/{id}")]
        public void Delete(int id)
        {
        }
    }
}

Step 5: Add a Startup.cs class at the project root to register the routing, formatters, and any other configuration setup. Add the Json Formatter so that the output will be in Json format.

C#
namespace HelloWorldStateless
{
    using Owin;
    using System.Web.Http;
    using System.Net.Http.Headers;

    public class Startup : IOwinAppBuilder
    {
        public void Configuration(IAppBuilder appBuilder)
        {
            HttpConfiguration config = new HttpConfiguration();
            config.Formatters.JsonFormatter.SupportedMediaTypes.Add(new MediaTypeHeaderValue("text/html"));
            config.MapHttpAttributeRoutes();

            FormatterConfig.ConfigureFormatters(config.Formatters);

            appBuilder.UseWebApi(config);
        }
    }
}

Step 6: Create OwinCommunicationListener.cs class that implements ICommunicationListener:

C#
namespace HelloWorldStateless
{
    using System;
    using System.Fabric;
    using System.Fabric.Description;
    using System.Globalization;
    using System.Threading;
    using System.Threading.Tasks;
    using Microsoft.Owin.Hosting;
    using Microsoft.ServiceFabric.Services.Communication.Runtime;

    public class OwinCommunicationListener : ICommunicationListener
    {
        private readonly IOwinAppBuilder startup;
        private readonly string appRoot;
        private IDisposable serverHandle;
        private string listeningAddress;
        private readonly ServiceInitializationParameters serviceInitializationParameters;

        public OwinCommunicationListener(string appRoot, 
        IOwinAppBuilder startup, ServiceInitializationParameters serviceInitializationParameters)
        {
            this.startup = startup;
            this.appRoot = appRoot;
            this.serviceInitializationParameters = serviceInitializationParameters;
        }

        public void Abort()
        {
            ServiceEventSource.Current.Message("Abort");

            this.StopWebServer();
        }

        public Task CloseAsync(CancellationToken cancellationToken)
        {
            ServiceEventSource.Current.Message("Close");
            this.StopWebServer();

            return Task.FromResult(true);
        }

        public Task<string> OpenAsync(CancellationToken cancellationToken)
        {
            EndpointResourceDescription serviceEndpoint = 
            serviceInitializationParameters.CodePackageActivationContext.GetEndpoint("ServiceEndpoint");
            int port = serviceEndpoint.Port;

            this.listeningAddress = String.Format(
                CultureInfo.InvariantCulture,
                "http://+:{0}/{1}",
                port,
                String.IsNullOrWhiteSpace(this.appRoot)
                    ? String.Empty
                    : this.appRoot.TrimEnd('/') + '/');

            this.serverHandle = WebApp.Start
            (this.listeningAddress, appBuilder => this.startup.Configuration(appBuilder));
            string publishAddress = this.listeningAddress.Replace
            ("+", FabricRuntime.GetNodeContext().IPAddressOrFQDN);

            ServiceEventSource.Current.Message("Listening on {0}", publishAddress);

            return Task.FromResult(publishAddress);
        }

        private void StopWebServer()
        {
            if (this.serverHandle != null)
            {
                try
                {
                    this.serverHandle.Dispose();
                }
                catch (ObjectDisposedException)
                {
                    // no-op
                }
            }
        }
    }
}

Step 7: Configure an HTTP endpoint in PackageRoot\ServiceManifest.xml:

XML
<Resources>
  <Endpoints>
    <Endpoint Name="ServiceEndpoint"
    Type="Input" Protocol="http" Port="8080" />
  </Endpoints>
</Resources>

Step 8: Create and return an instance of OwinCommunicationListener.

C#
namespace HelloWorldStateless
{
    /// <summary>
    /// The FabricRuntime creates an instance of this class for each service type instance. 
    /// </summary>
    internal sealed class HelloWorldStateless : StatelessService
    {
        /// <summary>
        /// Optional override to create listeners (like tcp, http) for this service instance.
        /// </summary>
        /// <returns>The collection of listeners.</returns>
        protected override IEnumerable<ServiceInstanceListener> CreateServiceInstanceListeners()
        {
            return new[]
            {
                new ServiceInstanceListener(initParams => 
                new OwinCommunicationListener("webapp", new Startup(), initParams))
            };
        }
    }
}

Step 9: Run and connect through a web browser.

You can now build and deploy your service. Press F5 in Visual Studio to build and deploy the application. Type the following, the url will echo the value 9 back

http://localhost:8080/webapp/helloworld/values/9

Image 3

Step 10: Monitor the service from the Service Fabric Explorer:

Image 4

That's all you need to do to build an ASP.NET Web API RESTful microservice with Service Fabric.

Here are the .NET solution files created in Visual Studio 2015 running on Windows 2012 R2 with Service Fabric SDK - HelloWorld solution.

Points of Interest

It's very interesting to learn Azure Service Fabric. It's so easy to build a microservice just the same way as that for an ASP.NET Web API application.

History

  • 21st April, 2016: Initial post

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)