Skip to content
This repository has been archived by the owner on Jul 17, 2018. It is now read-only.

HTTP Communication

Christian Weiss edited this page Apr 16, 2016 · 1 revision

The package C3.ServiceFabric.HttpCommunication can also be used outside of the gateway to communicate with HTTP based Service Fabric services. It contains HttpCommunicationClientFactory, a HTTP implementation of ICommunicationClientFactory from the Service Fabric SDK. It is built in a similar way as the built-in Wcf-integration.

Features

  • The library automatically resolves Service Fabric addresses to actual endpoints through the built-in ServicePartitionClient mechanism
  • The library contains retry-logic in HttpCommunicationClient
  • The behavior can be configured through HttpCommunicationOptions

Configuration options

You can configure the library through the class HttpCommunicationOptions. See below for examples.

  • RetryHttpStatusCodeErrors: Defines whether certain status codes from the response should be retried. (eg. 500)
  • MaxRetryCount: The number of times a service request is retried in case of an error.
  • MaxRetryBackoffInterval: The maximum time to wait between two retries.
  • OperationTimeout: The maximum amount of time to wait for one single service request.

The default behavior is defined in HttpCommunicationDefaults:

  • OperationTimeout: 12 seconds
  • MaxRetryCount: 9
  • MaxRetryBackoffInterval: 3 seconds

This means, the gateway will stop after about 2 minutes!

How to use

There is a sample project called HttpDirect that shows how to use this library.

Install the package

The package is available on NuGet: C3.ServiceFabric.HttpCommunication. You can install the package through various ways:

  • project.json: Add the package C3.ServiceFabric.HttpCommunication to the dependencies section
  • PowerShell: Install-Package C3.ServiceFabric.HttpCommunication
  • Visual Studio integration: add the package through the 'Manage NuGet Packages...' dialog (search for C3.ServiceFabric.HttpCommunication)

Add dependency injection services

Open Startup.cs in your ASP.NET Core application. Depending on how you want to configure the package, add one of the following snippets to your ConfigureServices(IServiceCollection services)-method:

// use default options ...

services.AddServiceFabricHttpCommunication();

// ... or overwrite certain defaults from Configuration system ...

services.Configure<HttpCommunicationOptions>(Configuration.GetSection("HttpCommunication"));
services.AddServiceFabricHttpCommunication();

// ... or overwrite certain defaults with code ...

services.AddServiceFabricHttpCommunication(options =>
{
    options.MaxRetryCount = 2;
});

// ... or combine Configuration system with custom settings

services.Configure<HttpCommunicationOptions>(Configuration.GetSection("HttpCommunication"));
services.AddServiceFabricHttpCommunication(options =>
{
	options.RetryHttpStatusCodeErrors = true;
});

Use IHttpCommunicationClientFactory in your controller/middleware/...

This example shows usage in a simple middleware. If you want to use it e.g. in your ASP.NET controller just inject IHttpCommunicationClientFactory into your controller and use it in your action.

/// <summary>
/// This could be a middleware, an ASP.NET Controller, some service, ...
/// Just inject the IHttpCommunicationClientFactory
/// </summary>
public class DirectCommunicationMiddleware
{
	private readonly IHttpCommunicationClientFactory _clientFactory;

	public DirectCommunicationMiddleware(RequestDelegate next,
		IHttpCommunicationClientFactory clientFactory)
	{
		_clientFactory = clientFactory;
	}

	public async Task Invoke(HttpContext context)
	{
		// create the Service Fabric client (it will resolve the address)
		var client = new ServicePartitionClient<HttpCommunicationClient>(
			_clientFactory,
			new Uri("fabric:/GatewaySample/HttpServiceService"));

		// call your service.
		await client.InvokeWithRetry(async x =>
		{
			HttpRequestMessage req = new HttpRequestMessage(HttpMethod.Get, "api/values");

			HttpResponseMessage response = await x.HttpClient.SendAsync(req, context.RequestAborted);

			await context.Response.WriteAsync(DateTime.Now + " - Result from API: ");
			await context.Response.WriteAsync("Status: " + response.StatusCode + "; Body: ");
			await response.Content.CopyToAsync(context.Response.Body);
		});
	}
}