Skip to main content

Self-Hosting a Bot in Service Fabric with Katana

I recently participated in a small hackathon with some Microsoft ninjas where we were presented with the problem, How do you host a bot in Service Fabric? It seemed like an easy problem that had probably already been solved, but it wasn't as straightforward as we thought it might be.

At its core from a technology perspective, a bot is really just a Web API. We didn't want to actually host IIS on Service Fabric, so we knew we would want to self-host. If you use the built-in Stateless Service ASP.NET Core template, you'll get a great Web API implementation that's wired up with a KestrelCommunictionListener for Service Fabric. But what if you want to use Katana -- Microsoft's .NET Framework OWIN implementation?

Katana is a flexible set of components for building and hosting OWIN-based web applications on .NET Framework.
Microsoft's Katana Project on GitHub

Although ASP.NET Core has incorporated most of the Katana project's functionality, the project will still be kept up-to-date and ensure any bugs are fixed per their roadmap. Most will look to ASP.NET Core for new functionality, but if you are maintaining a project built with a Katana dependency that you would like to port to be hosted in Service Fabric, you will only need to build a Katana-based ICommunicationListener implementation.

Note: this project was built and all screenshots were taken using Visual Studio 2017, version 15.5.2.

Setting up the Service Fabric Application

We know we'd like to build a Stateless Service to host the Web API, so we'll first create the Service Fabric Application by using the File menu > New > Project... option. Find Service Fabric Application under the C# / Cloud templates.

After you've picked a name for your application, select Stateless Service as your first service in the application. If you select Stateless Service ASP.NET Core, it will automatically include the KestrelCommunicationListener and stub out an ASP.NET Core Controller; however, selecting the Stateless Service will create a service with only Service Fabric scaffolding and no default communication listeners.

At this point, we just need to create a Service Fabric ICommunicationListener for Katana, and we should be able to self-host any full framework ASP.NET website within Service Fabric.

Creating the OWIN ICommunicationListener

It turns out we definitely were not the first to have to implement an OWIN ICommunicationListener, but it is not something available in the Service Fabric libraries. This page of the documentation describes how to implement your own communication listener as required for Service Fabric reliable services communication stack. The Service Fabric team also has provided a sample available as part of the Azure Service Fabric Party Cluster sample. The PartyCluster.WebService uses an OwinCommunciationListener. There is also a somewhat-outdated example documented here that helps describe the implementation step-by-step. Because this example has not been kept up-to-date, there are a few method signatures that are no longer correct, but it might be worth a read to understand what is happening before using the OwinCommunicationListener from the Party Cluster sample.

Pulling this all together, our Stateless Service code now has four additional updates:

  • OwinCommunicationListener class: Sets up the Katana-based self-hosted web server and manages it within the Service Fabric Reliable Services communication stack
  • IOwinAppBuilder class: Interface supporting OWIN configuration as part of the application builder stack during startup
  • Startup class: Startup class to support configuration; passed into the OwinCommunicationListener
  • Updates to StatelessService implementation: Registers the OwinCommunicationListener in the CreateServiceInstanceListeners() override
You'll also need to configure the service to define the ports that will be used. For this example, we used port 80. This must be added to the configuration in the Service Manifest (found under the PackageRoot directory). Update the ResourceEndpoints section so that it includes the following for this ServiceEndpoint:
<Endpoint Name="ServiceEndpoint" Protocol="http" Port="80" Type="Input" />

Adding the Bot

We decided to make one additional change in our implementation. We wanted to keep our Stateless Service as thin as possible, so we created a separate Web API project to contain our controllers, models, and some startup information versus adding these files directly within the Stateless Service project.

For this example, we just used the basic Echo Bot provided as part of the Bot Builder SDK. Their quickstart provides a great walkthrough as well as links to download the Visual Studio templates. Once the templates are installed on your machine, you just have to right-click the solution and add a new project. Search for and select Bot Application.

You now have an Echo Bot ready for use in your application. The final piece that ties these two projects together is the addition of configuration in the Startup class we added to the Stateless Service project. It needs a reference to the Bot Application project so that you can make a call to WebApiConfig.Register(config);. You'll also need to ensure appBuilder.UseWebApi(config); is called since it will setup the Web API bits in the OWIN stack to ensure that is routed and handled correctly by your controllers.

Summary

Although the Katana implementation has been supplanted by a fully-featured ASP.NET Core stack, it may be helpful to support some legacy applications with Katana dependencies in Service Fabric. With these small changes, you can have a complete OWIN stack based on the full-framework Katana project implementation for use within Service Fabric. A complete working example is available on the CodingWithSasquatch GitHub site in the Zohan.ServiceFabricBot repository.

Happy Hacking!

Comments

Popular posts from this blog

Microsoft Flow: Expose Public APIs via Custom Connector

I love fitness trackers. I was excited to get the new Fitbit Alta HR, but some of my eagerness waned when I remembered why I hadn't used a Fitbit since my old Fitbit One -- I hated how it didn't integrate with any of my other applications I used to track my information. Fitbit does support some integration with partner apps, but just not with any apps that I happen to prefer and use. I'm an Android user. I've started to look at Google Fit as a hub for all of my fitness data, but I'm not completely sold on that yet. I've been using Nike+ Run Club since I jumped on the Nike bandwagon years ago and purchased the Nike+ iPod Sport Kit (back when I carried an iPod). I was so excited to have a sensor nestled in my shoe and a coach speaking to me as I was running! Fast-forward to now, and although my phone is the main sensor for everything, I still prefer to use the Nike+ applications to track my runs and training. Nike+ synchronizes data to Google Fit, but not to Fi…