Azure Service Fabric is a distributed systems platform that makes it easy to package, deploy, and manage scalable and reliable microservices. It enables you to build and manage scalable and reliable applications, composed of microservices that run at a very high density on a shared pool of machines, which is referred to as a cluster.

In addition, it provides a sophisticated runtime to build distributed, scalable, stateless and stateful microservices, and provides comprehensive application management capabilities to provision, deploy, monitor, upgrade/patch and delete deployed applications.

ASP.NET Core and Service Fabric

By default, Azure Service Fabric services do not provide a public interface to the web. To expose your application’s functionality to HTTP clients, you will need to create a web project to act as an entry point and then communicate from there with your individual services.

To create a new Service Fabric application with an ASP.NET Core web app you need to take the following steps:

  • create a New Project,
  • select Service Fabric Application and name your app and solution, then
  • from Service Templates, select ASP.NET Core, name your service, and
  • from ASP.NET Core templates, choose Web Application, and click OK

In a few seconds, the application will be created, and you can easily run it in your local Service Fabric cluster. For more info on how you can get started with Service Fabric you can read this article.

ASP.NET Core Environments

ASP.NET Core introduces improved support for controlling application behavior across multiple environments, such as development, staging and production. Environment variables are used to indicate which environment the application is running in, allowing the app to be configured appropriately. To do so, ASP.NET Core references a particular environment variable, ASPNETCORE_ENVIRONMENT to describe the environment the application is currently running in.

Running your Service Fabric app in multiple environments

When debugging your app with Service Fabric, you may come to a point where, although you have properly set the development environment for your ASP.NET core app, as shown in the previous picture, your app is running as in Production environment.

To overcome this issue, you need to follow the next steps to customize the environment for your app to work in, when running in Service Fabric cluster.

Step 1. Add a section to your App Settings

First of all, add a custom config section to PackageRoot\Config\Settings.xml to allow different configuration based on where your app will run (This file is located in the actual ASP.NET Core application).

<?xml version="1.0" encoding="utf-8" ?>
<Settings xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="...">
  <!-- Add your custom configuration sections and parameters here -->
  <Section Name="Environment">
    <Parameter Name="ASPNETCORE_ENVIRONMENT" Value="Development" />
  </Section>
</Settings>

Step 2. Modify Service Fabric App Settings

To override the value used in the previous step for a specific environment pair, you need to add a `ASPNETCORE_ENVIRONMENT` parameter inside the `<Parameters>` tag at the top of the `ApplicationPackageRoot\ApplicationManifest.xml` file:

<?xml version="1.0" encoding="utf-8"?>
<ApplicationManifest xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="...">
  <Parameters>
    <Parameter Name="WebApp_InstanceCount" DefaultValue="-1" />
    <Parameter Name="ASPNETCORE_ENVIRONMENT" DefaultValue="" />
  </Parameters>
 <!-- Rest of the configuration -->
<ApplicationManifest>

and modify the `ServiceManifestImport` tag to include a `ConfigOverride` section:

<?xml version="1.0" encoding="utf-8"?>
<ApplicationManifest xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" ApplicationTypeName="SFEnvironmentsType" ApplicationTypeVersion="1.0.0" xmlns="http://schemas.microsoft.com/2011/01/fabric">
... 
  <ServiceManifestImport>
    <ServiceManifestRef ServiceManifestName="WebAppPkg" ServiceManifestVersion="1.0.0" />
    <ConfigOverrides>
      <ConfigOverride Name="Config">
        <Settings>
          <Section Name="Environment">
            <Parameter Name="ASPNETCORE_ENVIRONMENT" Value="[ASPNETCORE_ENVIRONMENT]" />
          </Section>
        </Settings>
      </ConfigOverride>
    </ConfigOverrides>
  </ServiceManifestImport>
...
</ApplicationManifest>

Step 3. Modify Parameters for your Publish Profiles

Based on where you want to run your app, you can modify Local.1Node.xml, Local.5Node.xml and Cloud.xml files to set the environment parameter to Development or Production according to your needs:

So, Local.1Node.xml and Local.5Node.xml can be:

<?xml version="1.0" encoding="utf-8"?>
<Application xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" Name="fabric:/SFEnvironments" xmlns="http://schemas.microsoft.com/2011/01/fabric">
  <Parameters>
    <Parameter Name="WebApp_InstanceCount" Value="1" />
    <Parameter Name="ASPNETCORE_ENVIRONMENT" Value="Development" />
  </Parameters>
</Application>

and Cloud.xml:

<?xml version="1.0" encoding="utf-8"?>
<Application xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" Name="fabric:/SFEnvironments" xmlns="http://schemas.microsoft.com/2011/01/fabric">
  <Parameters>
    <Parameter Name="WebApp_InstanceCount" Value="1" />
    <Parameter Name="ASPNETCORE_ENVIRONMENT" Value="Production" />
  </Parameters>
</Application>

Step 4. Inject environment in WebListenerCommunicationListener

`WebListenerCommunicationListener` is an implementation of `ICommunicationListener` that allows you to create an ASP.NET Core WebHost inside a Reliable Service, using WebListener as the web server. In the ASP.NET Core application there is a file `WebApp.cs` where you may configure Kestrel or WebListener to register a unique service URL with the Service Fabric Naming Service, and then validate client requests to ensure clients are re-connecting to the right service.

In order to inject the appropriate environment for your app, you need to modify the file as follows:

protected override IEnumerable<ServiceInstanceListener> CreateServiceInstanceListeners()
{
    return new ServiceInstanceListener[]
    {
        new ServiceInstanceListener(serviceContext =>
            new WebListenerCommunicationListener(serviceContext, "ServiceEndpoint", (url, listener) =>
            {
                ServiceEventSource.Current.ServiceMessage(serviceContext, $"Starting WebListener on {url}");

                // Read environment from config files
                var environment = FabricRuntime.GetActivationContext()?
                    .GetConfigurationPackageObject("Config")?
                    .Settings.Sections["Environment"]?
                    .Parameters["ASPNETCORE_ENVIRONMENT"]?.Value;

                return new WebHostBuilder().UseWebListener()
                            .ConfigureServices(
                                services => services
                                    .AddSingleton<StatelessServiceContext>(serviceContext))
                            .UseContentRoot(Directory.GetCurrentDirectory())
                            .UseStartup<Startup>()
                            .UseEnvironment(environment) // use the appropriate environment=
                            .UseApplicationInsights()
                            .UseServiceFabricIntegration(listener, ServiceFabricIntegrationOptions.None)
                            .UseUrls(url)
                            .Build();
            }))
    };
}

 

Categorized in:

Tagged in:

,