This repository has been archived by the owner on Nov 17, 2023. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 10.4k
/
ResilientHttpClient.cs
64 lines (54 loc) · 2.21 KB
/
ResilientHttpClient.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
using Microsoft.Extensions.Logging;
using Newtonsoft.Json;
using Polly;
using Polly.Wrap;
using System;
using System.Collections.Generic;
using System.Net;
using System.Net.Http;
using System.Threading.Tasks;
namespace Microsoft.eShopOnContainers.BuildingBlocks.Resilience.Http
{
/// <summary>
/// HttpClient wrapper that integrates Retry and Circuit
/// breaker policies when invoking HTTP services.
/// Based on Polly library: https://github.com/App-vNext/Polly
/// </summary>
public class ResilientHttpClient : IHttpClient
{
private HttpClient _client;
private PolicyWrap _policyWrapper;
private ILogger<ResilientHttpClient> _logger;
public HttpClient Inst => _client;
public ResilientHttpClient(Policy[] policies, ILogger<ResilientHttpClient> logger)
{
_client = new HttpClient();
_logger = logger;
// Add Policies to be applied
_policyWrapper = Policy.WrapAsync(policies);
}
public Task<string> GetStringAsync(string uri) =>
HttpInvoker(() =>
_client.GetStringAsync(uri));
public Task<HttpResponseMessage> PostAsync<T>(string uri, T item) =>
// a new StringContent must be created for each retry
// as it is disposed after each call
HttpInvoker(() =>
{
var response = _client.PostAsync(uri, new StringContent(JsonConvert.SerializeObject(item), System.Text.Encoding.UTF8, "application/json"));
// raise exception if HttpResponseCode 500
// needed for circuit breaker to track fails
if (response.Result.StatusCode == HttpStatusCode.InternalServerError)
{
throw new HttpRequestException();
}
return response;
});
public Task<HttpResponseMessage> DeleteAsync(string uri) =>
HttpInvoker(() => _client.DeleteAsync(uri));
private Task<T> HttpInvoker<T>(Func<Task<T>> action) =>
// Executes the action applying all
// the policies defined in the wrapper
_policyWrapper.ExecuteAsync(() => action());
}
}