Skip to content

Commit 03d1d62

Browse files
v-fearamskabou
andauthored
Update/failure mode analysis (#239)
* FailureModeAnalysis * Remove unnecessary nuget packages --------- Co-authored-by: Federico Arambarri <v-fearam> Co-authored-by: Jason Bouska <[email protected]>
1 parent 2977c2b commit 03d1d62

File tree

4 files changed

+115
-118
lines changed

4 files changed

+115
-118
lines changed

Reliability/FailureModeAnalysisSample/Controllers/SampleController.cs

+26-27
Original file line numberDiff line numberDiff line change
@@ -2,39 +2,38 @@
22
using Microsoft.Extensions.Logging;
33
using System.Net.Http;
44
using System.Threading.Tasks;
5-
using System.Web.Http;
65

76
namespace FailureModeAnalysisSample.Controllers
87
{
9-
[ApiController]
10-
[Route("[controller]")]
11-
public class SampleController : ControllerBase
12-
{
13-
private readonly ILogger<SampleController> _logger;
14-
private readonly IHttpClientFactory _httpClientFactory;
8+
[ApiController]
9+
[Route("[controller]")]
10+
public class SampleController : ControllerBase
11+
{
12+
private readonly ILogger<SampleController> _logger;
13+
private readonly IHttpClientFactory _httpClientFactory;
1514

16-
public SampleController(ILogger<SampleController> logger, IHttpClientFactory httpClientFactory)
17-
{
18-
_logger = logger;
19-
_httpClientFactory = httpClientFactory;
20-
}
15+
public SampleController(ILogger<SampleController> logger, IHttpClientFactory httpClientFactory)
16+
{
17+
_logger = logger;
18+
_httpClientFactory = httpClientFactory;
19+
}
2120

2221

23-
[HttpGet]
24-
public async Task<ActionResult> Get()
25-
{
26-
var httpClient = _httpClientFactory.CreateClient("SampleService");
22+
[HttpGet]
23+
public async Task<ActionResult> Get()
24+
{
25+
var httpClient = _httpClientFactory.CreateClient("SampleService");
2726

28-
HttpResponseMessage httpResponseMessage = await httpClient.GetAsync("<your GET operation>");
29-
var content = await httpResponseMessage.Content.ReadAsStringAsync();
27+
HttpResponseMessage httpResponseMessage = await httpClient.GetAsync("<your GET operation>");
28+
var content = await httpResponseMessage.Content.ReadAsStringAsync();
3029

31-
if (httpResponseMessage.IsSuccessStatusCode)
32-
{
33-
return Ok(content);
34-
}
35-
36-
_logger.LogError(content);
37-
return StatusCode((int)httpResponseMessage.StatusCode, content);
38-
}
39-
}
30+
if (httpResponseMessage.IsSuccessStatusCode)
31+
{
32+
return Ok(content);
33+
}
34+
35+
_logger.LogError(content);
36+
return StatusCode((int)httpResponseMessage.StatusCode, content);
37+
}
38+
}
4039
}

Reliability/FailureModeAnalysisSample/FailureModeAnalysisSample.csproj

+3-5
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,12 @@
11
<Project Sdk="Microsoft.NET.Sdk.Web">
22

33
<PropertyGroup>
4-
<TargetFramework>netcoreapp3.1</TargetFramework>
4+
<TargetFramework>net8.0</TargetFramework>
55
</PropertyGroup>
66

77
<ItemGroup>
8-
<PackageReference Include="Microsoft.AspNetCore.Mvc.WebApiCompatShim" Version="2.2.0" />
9-
<PackageReference Include="Microsoft.Extensions.Http.Polly" Version="3.1.3" />
10-
<PackageReference Include="Microsoft.VisualStudio.Web.CodeGeneration.Design" Version="3.1.1" />
11-
<PackageReference Include="Polly" Version="7.2.0" />
8+
<PackageReference Include="Microsoft.Extensions.Http.Polly" Version="8.0.6" />
9+
<PackageReference Include="Polly" Version="8.4.0" />
1210
</ItemGroup>
1311

1412

Reliability/FailureModeAnalysisSample/Program.cs

+13-13
Original file line numberDiff line numberDiff line change
@@ -3,18 +3,18 @@
33

44
namespace RetryPatternSample
55
{
6-
public class Program
7-
{
8-
public static void Main(string[] args)
9-
{
10-
CreateHostBuilder(args).Build().Run();
11-
}
6+
public class Program
7+
{
8+
public static void Main(string[] args)
9+
{
10+
CreateHostBuilder(args).Build().Run();
11+
}
1212

13-
public static IHostBuilder CreateHostBuilder(string[] args) =>
14-
Host.CreateDefaultBuilder(args)
15-
.ConfigureWebHostDefaults(webBuilder =>
16-
{
17-
webBuilder.UseStartup<Startup>();
18-
});
19-
}
13+
public static IHostBuilder CreateHostBuilder(string[] args) =>
14+
Host.CreateDefaultBuilder(args)
15+
.ConfigureWebHostDefaults(webBuilder =>
16+
{
17+
webBuilder.UseStartup<Startup>();
18+
});
19+
}
2020
}

Reliability/FailureModeAnalysisSample/Startup.cs

+73-73
Original file line numberDiff line numberDiff line change
@@ -11,77 +11,77 @@
1111

1212
namespace RetryPatternSample
1313
{
14-
public class Startup
15-
{
16-
public Startup(IConfiguration configuration)
17-
{
18-
Configuration = configuration;
19-
}
20-
21-
private ILogger<Startup> _logger;
22-
23-
public IConfiguration Configuration { get; }
24-
25-
// This method gets called by the runtime. Use this method to add services to the container.
26-
public void ConfigureServices(IServiceCollection services)
27-
{
28-
//429 - Throttling - retry twice, incrementing wait time in every retry.
29-
var retryWhenThrottling = Policy
30-
.HandleResult<HttpResponseMessage>(r => r.StatusCode == HttpStatusCode.TooManyRequests)
31-
.WaitAndRetryAsync(2, retryAttempt => TimeSpan.FromSeconds(Math.Pow(5, retryAttempt)));
32-
33-
//408 - Timeout, retry twice, with a 5 secs wait time
34-
var retryWhenTimeout = Policy
35-
.HandleResult<HttpResponseMessage>(r => r.StatusCode == HttpStatusCode.RequestTimeout)
36-
.WaitAndRetryAsync(2, retryAttempt => TimeSpan.FromSeconds(5));
37-
38-
//503 or 5xx service unavailable - wait 10 secs and retry only once.
39-
var retryWhenServiceUnavailable = Policy
40-
.HandleResult<HttpResponseMessage>(r => r.StatusCode == HttpStatusCode.ServiceUnavailable)
41-
.WaitAndRetryAsync(1, retryAttempt => TimeSpan.FromSeconds(10));
42-
43-
//401 unauthorized - retry once and do some retry logic + logging
44-
var retryWhenUnauthorized = Policy
45-
.HandleResult<HttpResponseMessage>(r => r.StatusCode == HttpStatusCode.Unauthorized)
46-
.RetryAsync(1, (exception, retryCount) =>
47-
{
48-
49-
this._logger.LogError($"Error occurred retry attempt: {retryCount}, Error details: {exception.Result.ToString()}");
50-
//Do some logic here like:
51-
//RenewAccessToken();
52-
});
53-
54-
IAsyncPolicy<HttpResponseMessage> policyWrap = Policy.WrapAsync(retryWhenThrottling, retryWhenTimeout, retryWhenServiceUnavailable, retryWhenUnauthorized);
55-
56-
services.AddHttpClient("SampleService", client =>
57-
{
58-
client.BaseAddress = new Uri(@"<You endpoint's base address here>");
59-
client.DefaultRequestHeaders.Add("Accept", "application/json");
60-
}).AddPolicyHandler(policyWrap);
61-
62-
services.AddControllers();
63-
}
64-
65-
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
66-
public void Configure(IApplicationBuilder app, IWebHostEnvironment env, ILogger<Startup> logger)
67-
{
68-
this._logger = logger;
69-
70-
if (env.IsDevelopment())
71-
{
72-
app.UseDeveloperExceptionPage();
73-
}
74-
75-
app.UseHttpsRedirection();
76-
77-
app.UseRouting();
78-
79-
app.UseAuthorization();
80-
81-
app.UseEndpoints(endpoints =>
82-
{
83-
endpoints.MapControllers();
84-
});
85-
}
86-
}
14+
public class Startup
15+
{
16+
public Startup(IConfiguration configuration)
17+
{
18+
Configuration = configuration;
19+
}
20+
21+
private ILogger<Startup> _logger;
22+
23+
public IConfiguration Configuration { get; }
24+
25+
// This method gets called by the runtime. Use this method to add services to the container.
26+
public void ConfigureServices(IServiceCollection services)
27+
{
28+
//429 - Throttling - retry twice, incrementing wait time in every retry.
29+
var retryWhenThrottling = Policy
30+
.HandleResult<HttpResponseMessage>(r => r.StatusCode == HttpStatusCode.TooManyRequests)
31+
.WaitAndRetryAsync(2, retryAttempt => TimeSpan.FromSeconds(Math.Pow(5, retryAttempt)));
32+
33+
//408 - Timeout, retry twice, with a 5 secs wait time
34+
var retryWhenTimeout = Policy
35+
.HandleResult<HttpResponseMessage>(r => r.StatusCode == HttpStatusCode.RequestTimeout)
36+
.WaitAndRetryAsync(2, retryAttempt => TimeSpan.FromSeconds(5));
37+
38+
//503 or 5xx service unavailable - wait 10 secs and retry only once.
39+
var retryWhenServiceUnavailable = Policy
40+
.HandleResult<HttpResponseMessage>(r => r.StatusCode == HttpStatusCode.ServiceUnavailable)
41+
.WaitAndRetryAsync(1, retryAttempt => TimeSpan.FromSeconds(10));
42+
43+
//401 unauthorized - retry once and do some retry logic + logging
44+
var retryWhenUnauthorized = Policy
45+
.HandleResult<HttpResponseMessage>(r => r.StatusCode == HttpStatusCode.Unauthorized)
46+
.RetryAsync(1, (exception, retryCount) =>
47+
{
48+
49+
this._logger.LogError($"Error occurred retry attempt: {retryCount}, Error details: {exception.Result.ToString()}");
50+
//Do some logic here like:
51+
//RenewAccessToken();
52+
});
53+
54+
IAsyncPolicy<HttpResponseMessage> policyWrap = Policy.WrapAsync(retryWhenThrottling, retryWhenTimeout, retryWhenServiceUnavailable, retryWhenUnauthorized);
55+
56+
services.AddHttpClient("SampleService", client =>
57+
{
58+
client.BaseAddress = new Uri(@"<You endpoint's base address here>");
59+
client.DefaultRequestHeaders.Add("Accept", "application/json");
60+
}).AddPolicyHandler(policyWrap);
61+
62+
services.AddControllers();
63+
}
64+
65+
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
66+
public void Configure(IApplicationBuilder app, IWebHostEnvironment env, ILogger<Startup> logger)
67+
{
68+
this._logger = logger;
69+
70+
if (env.IsDevelopment())
71+
{
72+
app.UseDeveloperExceptionPage();
73+
}
74+
75+
app.UseHttpsRedirection();
76+
77+
app.UseRouting();
78+
79+
app.UseAuthorization();
80+
81+
app.UseEndpoints(endpoints =>
82+
{
83+
endpoints.MapControllers();
84+
});
85+
}
86+
}
8787
}

0 commit comments

Comments
 (0)