Introduction
A good start to learn about Service Fabric is here.
NB: The application is removed from Azure. Please download the code and run it in your local cluster.
Background
This article builds on this article where you find the original CarClient
and CarAPI
projects which in this article are moved to a Service Fabric Cluster.
Using the Code
Before deploying and running this application in local cluster, make sure that http://localhost:80 and http://localhost:83 are not already used on your computer. If http://localhost:80 is already in use, change to some other free port in CarClient
ServiceManifest.xml. E.g., to use port 8080, write:
<Endpoint Protocol="http" Name="ServiceEndpoint" Type="Input" Port="8080" />
Then start the program in the browser with http://localhost:8080.
Please note that this code is only tested on Google Chrome. The JavaScript in the client runs perfectly on Google Chrome, but I have noticed problems with Internet Explorer and FireFox.
To run this sample, you need an Azure Account and your own Azure SQL Server app. You must update the connection string to point to your own Azure SQL Server. You also need Service Fabric Explorer and Service Fabric Cluster Manager which you get when you install the service fabric SDK.
SQLite has been replaced with Azure SQL Server and the CarClient
and CarAPI
projects are now stateless service fabric services.
To create this solution by Visual Studio, a Service Fabric Application has been chosen as solution template.
In the solution, two stateless ASP.NET Core projects have been added: one WebAPI
and one Web Application as shown below:
The code from the older CarAPI
and CarClient
have been added to the default projects with as few modifications as possible. The solution can be run in both an Azure cluster and a local cluster. The Azure cluster is created by Visual Studio. When creating a SF cluster from Visual Studio, you get a cluster using certificate security. This forces the application to use https for the reverse proxy in Azure as opposed to running it locally where http must be used.
In Azure, the URL used for CarAPI
was http://carfabric.northeurope.cloudapp.azure.com:83/ and in the local cluster, the URL http://localhost:83/ is used. This URL is used by JavaScript in CarClient
for retrieving and updating data in the database. CarAPI
can be checked in local cluster with http://localhost:83/swagger.
For CarClient
, the same URLs are used except the port number is changed to 80. The URL is passed via the environment variable ApiAddressConnectionString
which is defined in the ServiceManifest.xml for CarClient
. How the value is defined when running the app locally respectively in Azure can be seen in Cloud.xml and Local1.xml in folder ApplicationParameters. The code for getting the reverse proxy address is as follows:
public static Uri GetProxyAddress(Uri serviceName)
{
string ApiAddress = Environment.GetEnvironmentVariable("ApiAddressConnectionString");
if (ApiAddress.IndexOf("localhost") > 0)
{
return new Uri($"http://localhost:19081{serviceName.AbsolutePath}/");
}
else
{
return new Uri($"https://localhost:19081{serviceName.AbsolutePath}/");
}
}
This code is found in project CarClient
, file Utils.cs.
Comparing the HTTP Client code between the old traditional solution and the service fabric solution shows the differences clearly.
New Service Fabric code:
namespace CarClient
{
public static class Utils
{
public static async Task<T> Get<T>(string url)
{
Uri serviceName = CarClientApp.GetCarAPIServiceName();
Uri proxyAddress = GetProxyAddress(serviceName);
HttpClientHandler handler = new HttpClientHandler()
{
ServerCertificateCustomValidationCallback =
HttpClientHandler.DangerousAcceptAnyServerCertificateValidator
};
using (var client = new HttpClient(handler) { BaseAddress = proxyAddress })
{
client.DefaultRequestHeaders.Accept.Clear();
client.DefaultRequestHeaders.Accept.Add
(new MediaTypeWithQualityHeaderValue("application/json"));
var response = await client.GetAsync(url);
var content = await response.Content.ReadAsStringAsync();
return await Task.Run(() => JsonConvert.DeserializeObject<T>(content));
}
}
The old code is as follows:
namespace CarClient
{
public static class Utils
{
private static readonly Uri Endpoint = new Uri("http://localhost:54411//");
public static async Task<T> Get<T>(string url)
{
using (var client = new HttpClient() { BaseAddress = EndPoint })
{
client.DefaultRequestHeaders.Accept.Clear();
client.DefaultRequestHeaders.Accept.Add
(new MediaTypeWithQualityHeaderValue("application/json"));
var response = await client.GetAsync(url);
var content = await response.Content.ReadAsStringAsync();
return await Task.Run(() => JsonConvert.DeserializeObject<T>(content));
}
}
For implementation details, please download CarFabric.zip and read the code.
Points of Interest
When creating a SF cluster from Visual Studio, you get a cluster using certificate security. This forces the application to use https for the reverse proxy in Azure as opposed to running it locally where http must be used.
History
- 8th May, 2018: Initial version