Working with Service Fabric Reverse Proxy

 

The Reverse Proxy

Working with Service Fabric, you might hear about the Reverse Proxy, a built-in feature of Azure Service Fabric helps microservices running in a Service Fabric cluster discover and communicate with other services that have HTTP endpoints.

The benefit of Reverse Proxy is providing the standard uniform resource identifier format to identify the services running on Service Fabric Clusters. So you can access your services via Reverse Proxy regardless of the actual port of the services.

Refer here to understand more about the Reverse Proxy.

By default, After installed service fabric the Reverse Proxy will run on port 19081 and access the applications or services by following the format below.

Supported Platforms

Reverse proxy in Service Fabric currently supports the following platforms

  • Windows Cluster: Windows 8 and later or Windows Server 2012 and later.
  • Linux Cluster: Reverse Proxy is not currently available for Linux clusters.

So you should using Window 8 or 10 for develop in order to test the Reverse proxy.

The Service Fabric Application

Create a Service Fabric Application on Visual Studio you will see it allows to host various services inside.

There are 2 kindles of services:

  • The Internal services that are working as backend services and can be access by the other services within an application (using Microsoft.ServiceFabric.Services.Remoting.IService ).
  • The https services that allow users to operate with your data or an API services that exposing your data to other consumers outside of the application.

Check out here for more information about Service Fabric Application

In this demo, I created a Service Fabric application named MvcReservedProxy and added a ReactJs Mvc app. When running the application, I shall have a ReactJs app running on port 8383.

Port 8383 is a random value was assigned by Visual Studio when creating the service.

And here is the endpoint configuration in the service manifest.

The application is working perfectly fine with this port. However, let’s see if you have many apps running on PRD, and each application has some HTTP services inside, resolving the port conflict is a challenge as we need to ensure that the occupation ports are not conflicted with existing one in PRD environment.

Fortunately, Service Fabric doesn’t require the ports to be specified. Instead, it will pick-up the free ports when startup your services. After removed, the port from the endpoint and reran the application. I have a new port http://localhost:30001

Amazing, form now onward I don’t need to care about the ports of the HTTP services anymore.

But, whenever, my application got restarted, re-deployed it will have a new port. So, how can I access my application? Luckily, as mentioned above the Reverse proxy is using a specific uniform resource identifier format to identify the service. So, I can access my application via below URL:

However, the website is not working correctly as some resource files were not able to reach when accessing via Reverse proxy.

To fix this issues, we need to add some additional code to the ReactJs project as below.

I. Update ServiceInstanceListener

Open the ReacJs.cs and changes the ServiceFabricIntegrationOptions from None to UseReverseProxyIntegration

II. Update Mvc Startup configuration

Open Startup.cs and add below code into Configure method.

The ServiceNameUrl format is [YourApplicationName]/[YourServiceName].

III. Update Base Url for Javascript application

After the second step, the MVc application will work fine. However, if you are hosting javascript applications (ex: ReacJs or AngularjS), then you need to update the base tad into your _Layout.cshtml because the routing of ReactJs router will use it.

Use in here

Now, Rerun the application and see the result.

Cheers and the source code here.

HBD.Mef.Mvc Enhancement For WebApi

 

Like the previous post, I have introduced a Workspace for Web Mvc and along with the post, AzureNotes Module was provided as an example.

Now in this post, I would like to update you the new version 1.0.5 of HBD.Mef.Mvc. From this version, it will support the WebApi technology that allows developing a similar Workspace for Web API.

The HBD.Api.Shell

Similarly to HBD.Mvc.Shell, the HBD.Api.Shell is the Workspace allowing to develop a WebApi module in the different project and deploy to the Workspace lately.

Develop a WebApi module is simpler than develop a module for Wb Mvc because WebApi doesn’t have any resources (views, CSS files, and JavaScript files) other than controllers. Hence, deployment a module into the Shell is just copying the binaries and config files only.

To simplify the life, I have provided a general routing for all Modules including the Workspace as below.

This route is applying for all modules and all controllers. Hence, the pathway to access to a controller is api/{area}/{controller}{id} which {area} is Module’s name, {controller} is the controller name and {id} is optional.

The module registration also simplified instead of providing the Module Name and custom routing. Promptly with API module requires the name only. Below is sample code to register an API module.

The HBD.Mef.Mvc will base on the registered named and select the appropriate controller for the request. If there is no controller found for an appropriate request the HttpResponseException with 404 status code will be thrown.

Mef Controller Resolver Service

Please note that this registration is for Api modules only. There is nothing changed on the Mvc module registration that had been introduced on the previous post.

The AzureNoteApi

I would like to show you a similar module for HBD.Api.Shell called AzureNoteApi; this module is just exposing all actions of AzureNote in the previous post as WebApi. Below is the details information the Apis. You can use Postman to try out with my live demo.

Live Demo

The HBD.Api.Shell is also published on to Azure you might have a try by using Postman with the following API.

  • HBD.Api.Shell API

  • AzureNote API

Source Code

The latest source codes had been uploaded to Github you can download here.

The Mef for MVC and Azure DocumentDb Demonstration 

 

As I’d already shared the Mef libraries for WPF, WinForms and Console Application. So In this post, I would like to share one more Mef library for .Net MVC.

As you may know, The MVC is supporting Areas that allow developing a set of Views, Controllers, and Resources (Images, CSS and Javascript) inside Areas folder. However, the areas are still a part of MVC application, and the resources need to be imported into the _Layout view manually and deploy along with the application. Beside of that, if any changes in the areas may impact to the whole application and need to be tested carefully before going live.

I. HBD.Mef.Mvc Introduction

PM> Install-Package HBD.Mef.Mvc

The Definition.

  • Workspace: this is an MVC website (a Shell) considering as Module container that allows deploying and run multi modules separately.
  • Module: this is a loosely couple MVC area that is implementing independently with Workspace and able to deploy into the Workspace lately.

So, get used of Area in MVC, I would like to introduce my HBD.Mef.Mvc library, it had been implemented based on the Mef technology allows you to build and manage the MVC areas as a module not only in a separate folder but also in different projects.

Before going to details of the library implementation, I would like to discuss a few questions below.

Why do we need the Modularization application?

  1. Let’s imagine, if you have many development teams and try to make the teams are working independently and separately as much as possible. However, if three or four teams are working a the significant changes of a complex application and that application does not support modularization. So when any team needs to deploy the changed to the Stagings or Production environments, they need to inform all the other teams to ensure there is no conflict between the teams. After deployed,  the other teams need to merge the changes into their source code branches. Managing this situation is a nightmare for the project manager.
  2. The other scenario, if the application doesn’t support modularization, so any change even the small one you need to conduct the System Integration Test (SIT) and User Acceptant Test (UAT) for the whole system because of the impact and the efforts will charge back to the business. You know, The business users may surprise why the simple change is costly?
  3. Micro-Services adoption: as you know, Micro-service is new technology that structures an application as a collection of loosely coupled services, which implement business capabilities. The microservice architecture enables the continuous delivery/deployment of large, complex applications. It also enables an organization to evolve its technology stack.
Micro Service Architecture

So the advantage of the Modularization application:

  • Allow the teams are working on the modules independently, parallelly.
  • Speed up and enable continuous development, delivery process: In term of the Agile development process. Normally, the sprint time is two weeks, and the recommendation to the development team is releasing a small workable feature of the application and demo to the Business users on the Sprint demonstration meeting.
  • Help to scale down the impact of the changes and increase the scalability, flexibility, and stability of the application.
  • Developing and maintain the automation tests or UI tests for a module is much easier for the whole complex application.

What is Mvc Module?

As you know, develop a Module is not just a Views and Controllers but also the settings, configuration, resources, Business and Data logics also. On the next sections, I will show you how to build a Workspace and create a module for that Workspace separately by using HBD.Mef.Mvc.

II HBD.Mef.Mvc Features

1. Navigations

Along with a Module is a set of navigation that We need to add into the top menu of the Workspace to allow users to navigate and using your modules functions. Let’s see, if developing a module and the navigation are adding directly to the _Layout view of the Workspace, and overwriting the  _Layout file of the Workspace in every deployment. In this case, the dependence happens again if there are more than one development teams are working the same Workspace and on each team, they also maintain a different version of _Layout view on their modules.

  • INavigationService

So in this library is provided an INavigationService allows registering the navigations into the Main Menu of Workspace dynamically.

Currently, the Main menu is supported two level only. You can add a navigation link directly in the main menu, or add a menu and navigation links are children of that menu.

  • IFooterNavigationService

Similarly, the IFooterNavigationService allows registering the links into Footer portion of the Workspace dynamically.

  • Navigation and Authorization

In the MVC some controller actions are required a particular Roles for the execution. So if the current user doesn’t have the necessary Roles, she is not able to execute that actions. In this case, the Workspace will hide all the navigation related to that actions automatically. If there are no visible children of a menu, the Workspace will hide the parent menu as well. It will help to save the main menu space for the other modules.

2. Resource Bundle Handling.

Working with MVC, you will know that the framework provides a feature called Bundle to allows to import the CSS and javascript files into the views.

Similar to navigation. Including all resources into the _Layout view of the Workspace is not recommended and it may conflict with the resources of the other Areas.

To resolve this issue. I have implemented a helper class in the library allows to register the module resources into the bundles and manage to render that bundles when accessing the module viewsIt means the Workspace will present the resources of the accessing module into the _Layout page at runtime. This feature will ensure that no CSS or java scripts conflicts between the Modules.

3. Controllers scanning.

You may be aware that, if we want to export a class into Mef container, we need to mark the class with Export attribute. What happens if you forgot to mark this attribute to the controllers? No worry this case had been covered in this library. It will scan all controllers in your binaries and export into Mef container automatically.

4. Configuration management.

As you know, running a .Net website the AppSettings and ConnectionStrings will be loaded into ConfigurationManager class of System.Configuration.

Definitely, on each Module, it will have a separate set of App Settings and Connection strings. Instead of adding the configuration into Workspace config file. You can keep it in a Wed.config and place it in the top level of your Module. The library will load and merge into the ConfigurationManager automatically.

Currently. Only AppSettings and ConnectionString sections are supporting. As the configuration will merge into Workspace configuration, so I would recommend using the Module Name as the prefix of the configuration keys.

The sample code to show you how to use all features above will be provided on the Module development below.

III. Develop a new Workspace.

The idea to implement an MVC Workspace as a core foundation application, that allows to add-in the modules and services independently.

I have developed a Workspace named HBD.Mvc.Shell using HBD.Mef.Mvc and published to Github, if you want to develop a new Workspace by yourself you can reference my source code in here.

Workspace

However, I would like to highlight a few things as below.

1. Bootstrapper class in the App_Start folder.

After installed HBD.Mef.Mvc from Nuget, a new Bootstrapper class, will be added to App_Start folder automatically.

Only one thing you need to do is overwrite the RegisterMainNavigation method and add the navigation of Workspace in. Because the Menu bar, Footer bar will be rendering from INavigationService and IFooterNavigationService instead of maintaining the menus manually.

The rest of configuration, modules loading, resources management will be done automatically by Bootstrapper itself. However, all methods of Bootstrapper are in virtually so in case you want to customize the logic you can overwrite them easily.

Please note that the DisplayAt and AlignAtRight only supported int the root menu level for both The main menu and Footer navigation.

The FontAwesome and Glyphicon icons also supported on both levels of menu. If you want to display an image on the menus instead, you can replace the Glyphicon with a virtual path of the image location. When rendering the Workspace will scan the image from both Area and global Workspace folders and display the image properly.

2. Main menu and Footer partial views.

In HBD.Mvc.Shell Workspace, I had moved the main menu and footer of _Layout view to the partial views. So, in future if any changes on the menu rendering we just need to re-deploy the small part view files instead of a whole _Layout file. This will help to minimize the impact of the changes to the Workspace.

 

Navigation Partial Views

3. Navigation Authorization.

As mentioned above. The navigations are supporting the Authorization, and I would like to move to a separate section to show you how the navigation can pick up the Roles from a controller, or you can specify the Roles manually.

  • Auto Pickup the Roles from Authorize attribute.

The sample code to add a navigation for a controller action

With above code, we will add a navigation titled Import Account From File for the ImportFromFile action of ImportController and below is controller code.

The For extension method will check the Authorize attribute of ImportFromFile action to whether any Authorize with Roles had been specified and pick up the Roles for the navigation automatically. If there is no Authorize attribute had been found it will check at the Controller level for the same.

Note that this automation only happens when there is no Roles had been provided. It means if you already provided the Roles for navigation the auto role pick up won’t be executed.

  • Specify the Roles manually.

Below code is a sample for the manual Role specification:

The WithAuthorize is an extension method that allows you to determine the Roles for navigation. If calling WithAuthorize without any parameter provided, it means the navigation just require the current user is authorized.

IV. Quick start Module development.

To prove my library is working. I have implemented a simple module named Azure Notes. This module is a personal notebook and using Azure DocumentDb to store the note items.

Before starting with the Module implementation, we need to create the Azure DocumentDb first. There is two option for the developers.

1. Setup DocumentDb on Azure Portal

If you already had the Azure Subscription, you can log in to the portal and create a DocumentDb account and then create a collection with the following information.

  • Database name: AzureNotes
  • Collection Id: AzureNotes
  • Partition Key: AzureNotes
  • Storage Capacity: 10GB.
  • Throughput Capacity: 400 RU/s

If you don’t have Azure Subscription, you can install Azure DocumentDb Emulator here, and the create a similar collection as above.

2. Module Implementation

  • Create new Module

Create new Mvc Web application and install the latest version of HBD.Mef.Mvc from nuget. After installed you can delete all the redundant files and just keep the below folders and files.

  • Content folder
  • Controllers folder
  • Views folder
  • Scripts folder
  • all configuration files.

And then add a new class named <YourModuleName>AreaRegistration and then inherited from MefAreaRegistration in HBD.Mef.Mvc this class will help to register your module as an Area in the Workspace application.

Your module should look similar as below.

  • Register Module Routing

  • Register Main Menu Navigation

  • Register Footer Navigation

  • Register Module Bundles

  • Update the App Settings of Web.config file
    • Using Azure DocumentDb Emulator

    • Using Azure DocumentDb

The DocumentDB Account URL and Key can be found in the DocumentDb Account Keys

  • Controller and Views Implementation

You shall continue to implement your controllers and views logics as usually. However, remember to add the Export attribute to your Controllers.

3. Module Deployment

To deploy your module into Workspace. All the folder below need to be copied into Areas\<YourModuleName>\ folder. All binaries of your module will be copied to the bin folder of Workspace.

  • Debug Mode

Running your module on the localhost, you can use set below command line into the post-build event of your module. It helps to copy the necessary files and folders into the Workspace on every build.

  • Deploy to Production

Package your module as the structure below for the production deployment. So that, IT guys can help to copy the folder and files quickly or use the auto deployment tool to deploy the zip file into Workspace application.

  • AzureNotes.zip
    • Areas
      • AzureNote
        • Content: all CSS files of your module.
        • Scripts: all javascript files of your module.
        • Views: all *.cshtml files and folders of your modules.
        • Web.config
    • bin
      • AzureInterfaces.dll
      • AzureNote.dll
      • AzureNoteEntities.dll
      • AzureStorage.dll
      • DocumentDB.Spatial.Sql.dll
      • Microsoft.Azure.Documents.Client.dll
      • Microsoft.Azure.Documents.ServiceInterop.dll

After deployed, just recycle the application pool to re-initialize the Workspace to load new module and displayed on the screen.

4. Live Demo

I have hosted the HBD.Mvc.Shell and Azure Notes module onto my Azure, you may want to take a look at the link below. I just have 25$ on my subscription. So hopefully It is not going to down soon.

V. Source Code

  1. HBD.Mef.Mvc
  2. HBD.Mvc.Shell
  3. AzureNotes