8000 Merge branch 'polly-integration' into dev · ITCSsDeveloper/eShopOnContainers@15d0e98 · GitHub
Skip to content

Commit 15d0e98

Browse files
committed
Merge branch 'polly-integration' into dev
2 parents 5a374e9 + ddb03a0 commit 15d0e98

12 files changed

Lines changed: 233 additions & 156 deletions

src/Web/WebMVC/Controllers/OrderController.cs

Lines changed: 15 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
using Microsoft.eShopOnContainers.WebMVC.ViewModels;
88
using Microsoft.AspNetCore< 93D4 span class=pl-kos>.Authorization;
99
using System.Net.Http;
10+
using Polly.CircuitBreaker;
1011

1112
namespace Microsoft.eShopOnContainers.WebMVC.Controllers
1213
{
@@ -37,18 +38,24 @@ public async Task<IActionResult> Create()
3738
[HttpPost]
3839
public async Task<IActionResult> Create(Order model, string action)
3940
{
40-
if (ModelState.IsValid)
41+
try
4142
{
42-
var user = _appUserParser.Parse(HttpContext.User);
43-
await _orderSvc.CreateOrder(model);
43+
if (ModelState.IsValid)
44+
{
45+
var user = _appUserParser.Parse(HttpContext.User);
46+
await _orderSvc.CreateOrder(model);
4447

45-
//Empty basket for current user.
46-
await _basketSvc.CleanBasket(user);
48+
//Empty basket for current user.
49+
await _basketSvc.CleanBasket(user);
4750

48-
//Redirect to historic list.
49-
return RedirectToAction("Index");
51+
//Redirect to historic list.
52+
return RedirectToAction("Index");
53+
}
54+
}
55+
catch(BrokenCircuitException ex)
56+
{
57+
ModelState.AddModelError("Error", "Not possible to create a new order, please try later on");
5058
}
51-
5259
return View(model);
5360
}
5461

src/Web/WebMVC/Services/BasketService.cs

Lines changed: 16 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,38 +1,37 @@
1-
using System;
2-
using System.Collections.Generic;
3-
using System.Linq;
4-
using System.Threading.Tasks;
5-
using Microsoft.eShopOnContainers.WebMVC.ViewModels;
1+
using Microsoft.AspNetCore.Authentication;
62
using Microsoft.AspNetCore.Http;
7-
using System.Net.Http;
3+
using Microsoft.eShopOnContainers.WebMVC.ViewModels;
84
using Microsoft.Extensions.Options;
95
using Newtonsoft.Json;
10-
using Microsoft.AspNetCore.Authentication;
11-
using Microsoft.eShopOnContainers.WebMVC.Extensions;
6+
using System.Collections.Generic;
7+
using System.Linq;
8+
using System.Net.Http;
9+
using System.Threading.Tasks;
10+
using WebMVC.Services.Utilities;
1211

1312
namespace Microsoft.eShopOnContainers.WebMVC.Services
1413
{
1514
public class BasketService : IBask 133E etService
1615
{
1716
private readonly IOptionsSnapshot<AppSettings> _settings;
18-
private HttpClient _apiClient;
17+
private IHttpClient _apiClient;
1918
private readonly string _remoteServiceBaseUrl;
2019
private IHttpContextAccessor _httpContextAccesor;
2120

22-
public BasketService(IOptionsSnapshot<AppSettings> settings, IHttpContextAccessor httpContextAccesor)
21+
public BasketService(IOptionsSnapshot<AppSettings> settings, IHttpContextAccessor httpContextAccesor, IHttpClient httpClient)
2322
{
2423
_settings = settings;
2524
_remoteServiceBaseUrl = _settings.Value.BasketUrl;
2625
_httpContextAccesor = httpContextAccesor;
26+
_apiClient = httpClient;
2727
}
2828

2929
public async Task<Basket> GetBasket(ApplicationUser user)
3030
{
3131
var context = _httpContextAccesor.HttpContext;
3232
var token = await context.Authentication.GetTokenAsync("access_token");
3333

34-
_apiClient = new HttpClient();
35-
_apiClient.DefaultRequestHeaders.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", token);
34+
_apiClient.Inst.DefaultRequestHeaders.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", token);
3635

3736
var basketUrl = $"{_remoteServiceBaseUrl}/{user.Id.ToString()}";
3837
var dataString = await _apiClient.GetStringAsync(basketUrl);
@@ -52,13 +51,12 @@ public async Task<Basket> UpdateBasket(Basket basket)
5251
{
5352
var context = _httpContextAccesor.HttpContext;
5453
var token = await context.Authentication.GetTokenAsync("access_token");
55-
56-
_apiClient = new HttpClient();
57-
_apiClient.DefaultRequestHeaders.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", token);
54+
55+
_apiClient.Inst.DefaultRequestHeaders.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", token);
5856

5957
var basketUrl = _remoteServiceBaseUrl;
60-
StringContent content = new StringContent(JsonConvert.SerializeObject(basket), System.Text.Encoding.UTF8, "application/json");
61-
var response = await _apiClient.PostAsync(basketUrl, content);
58+
59+
var response = await _apiClient.PostAsync(basketUrl, basket);
6260

6361
return basket;
6462
}
@@ -120,8 +118,7 @@ public async Task CleanBasket(ApplicationUser user)
120118
var context = _httpContextAccesor.HttpContext;
121119
var token = await context.Authentication.GetTokenAsync("access_token");
122120

123-
_apiClient = new HttpClient();
124-
_apiClient.DefaultRequestHeaders.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", token);
121+
_apiClient.Inst.DefaultRequestHeaders.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", token);
125122
var basketUrl = $"{_remoteServiceBaseUrl}/{user.Id.ToString()}";
126123
var response = await _apiClient.DeleteAsync(basketUrl);
127124

src/Web/WebMVC/Services/CatalogService.cs

Lines changed: 10 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,35 +1,31 @@
1-
using System;
2-
using System.Collections.Generic;
3-
using System.Linq;
4-
using System.Threading.Tasks;
1+
using Microsoft.AspNetCore.Mvc.Rendering;
52
using Microsoft.eShopOnContainers.WebMVC.ViewModels;
6-
using Microsoft.CodeAnalysis.Options;
3+
using Microsoft.Extensions.Logging;
74
using Microsoft.Extensions.Options;
8-
using System.Net.Http;
9-
using Microsoft.AspNetCore.Mvc.Rendering;
105
using Newtonsoft.Json;
116
using Newtonsoft.Json.Linq;
12-
using Microsoft.Extensions.Logging;
7+
using System.Collections.Generic;
8+
using System.Threading.Tasks;
9+
using WebMVC.Services.Utilities;
1310

1411
namespace Microsoft.eShopOnContainers.WebMVC.Services
1512
{
1613
public class CatalogService : ICatalogService
1714
{
1815
private readonly IOptionsSnapshot<AppSettings> _settings;
19-
private HttpClient _apiClient;
16+
private IHttpClient _apiClient;
2017
private readonly string _remoteServiceBaseUrl;
2118

22-
public CatalogService(IOptionsSnapshot<AppSettings> settings, ILoggerFactory loggerFactory) {
19+
public CatalogService(IOptionsSnapshot<AppSettings> settings, ILoggerFactory loggerFactory, IHttpClient httpClient) {
2320
_settings = settings;
2421
_remoteServiceBaseUrl = $"{_settings.Value.CatalogUrl}/api/v1/catalog/";
25-
22+
_apiClient = httpClient;
2623
var log = loggerFactory.CreateLogger("catalog service");
2724
log.LogDebug(settings.Value.CatalogUrl);
2825
}
2926

3027
public async Task<Catalog> GetCatalogItems(int page,int take, int? brand, int? type)
3128
{
32-
_apiClient = new HttpClient();
3329
var itemsQs = $"items?pageIndex={page}&pageSize={take}";
3430
var filterQs = "";
3531

@@ -45,24 +41,17 @@ public async Task<Catalog> GetCatalogItems(int page,int take, int? brand, int? t
4541
var dataString = "";
4642

4743
//
48-
// Using HttpClient with Retry and Exponential Backoff
44+
// Using a HttpClient wrapper with Retry and Exponential Backoff
4945
//
50-
var retry = new RetryWithExponentialBackoff();
51-
await retry.RunAsync(async () =>
52-
{
53-
// work with HttpClient call
54-
dataString = await _apiClient.GetStringAsync(catalogUrl);
55-
});
46+
dataString = await _apiClient.GetStringAsync(catalogUrl);
5647

57-
//var dataString = await _apiClient.GetStringAsync(catalogUrl);
5848
var response = JsonConvert.DeserializeObject<Catalog>(dataString);
5949

6050
return response;
6151
}
6252

6353
public async Task<IEnumerable<SelectListItem>> GetBrands()
6454
{
65-
_apiClient = new HttpClient();
6655
var url = $"{_remoteServiceBaseUrl}catalogBrands";
6756
var dataString = await _apiClient.GetStringAsync(url);
6857

@@ -81,7 +70,6 @@ public async Task<IEnumerable<SelectListItem>> GetBrands()
8170

8271
public async Task<IEnumerable<SelectListItem>> GetTypes()
8372
{
84-
_apiClient = new HttpClient();
8573
var url = $"{_remoteServiceBaseUrl}catalogTypes";
8674
var dataString = await _apiClient.GetStringAsync(url);
8775

src/Web/WebMVC/Services/OrderingService.cs

Lines changed: 11 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -8,30 +8,30 @@
88
using System.Net.Http;
99
using Newtonsoft.Json;
1010
using Microsoft.AspNetCore.Authentication;
11+
using WebMVC.Services.Utilities;
1112

1213
namespace Microsoft.eShopOnContainers.WebMVC.Services
1314
{
1415
public class OrderingService : IOrderingService
1516
{
16-
private HttpClient _apiClient;
17+
private IHttpClient _apiClient;
1718
private readonly string _remoteServiceBaseUrl;
1819
private readonly IOptionsSnapshot<AppSettings> _settings;
1920
private readonly IHttpContextAccessor _httpContextAccesor;
2021

21-
public OrderingService(IOptionsSnapshot<AppSettings> settings, IHttpContextAccessor httpContextAccesor)
22+
public OrderingService(IOptionsSnapshot<AppSettings> settings, IHttpContextAccessor httpContextAccesor, IHttpClient httpClient)
2223
{
2324
_remoteServiceBaseUrl = $"{settings.Value.OrderingUrl}/api/v1/orders";
2425
_settings = settings;
2526
_httpContextAccesor = httpContextAccesor;
27+
_apiClient = httpClient;
2628
}
2729

2830
async public Task<Order> GetOrder(ApplicationUser user, string Id)
2931
{
3032
var context = _httpContextAccesor.HttpContext;
3133
var token = await context.Authentication.GetTokenAsync("access_token");
32-
33-
_apiClient = new HttpClient();
34-
_apiClient.DefaultRequestHeaders.Authorizatio 1DDA n = new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", token);
34+
_apiClient.Inst.DefaultRequestHeaders.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", token);
3535

3636
var ordersUrl = $"{_remoteServiceBaseUrl}/{Id}";
3737
var dataString = await _apiClient.GetStringAsync(ordersUrl);
@@ -46,8 +46,7 @@ async public Task<List<Order>> GetMyOrders(ApplicationUser user)
4646
var context = _httpContextAccesor.HttpContext;
4747
var token = await context.Authentication.GetTokenAsync("access_token");
4848

49-
_apiClient = new HttpClient();
50-
_apiClient.DefaultRequestHeaders.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", token);
49+
_apiClient.Inst.DefaultRequestHeaders.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", token);
5150

5251
var ordersUrl = _remoteServiceBaseUrl;
5352
var dataString = await _apiClient.GetStringAsync(ordersUrl);
@@ -77,17 +76,15 @@ async public Task CreateOrder(Order order)
7776
var context = _httpContextAccesor.HttpContext;
7877
var token = await context.Authentication.GetTokenAsync("access_token");
7978

80-
_apiClient = new HttpClient();
81-
_apiClient.DefaultRequestHeaders.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", token);
82-
_apiClient.DefaultRequestHeaders.Add("x-requestid", order.RequestId.ToString());
79+
_apiClient.Inst.DefaultRequestHeaders.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", token);
80+
_apiClient.Inst.DefaultRequestHeaders.Add("x-requestid", order.RequestId.ToString());
81+
8382
var ordersUrl = $"{_remoteServiceBaseUrl}/new";
8483
order.CardTypeId = 1;
8584
order.CardExpirationApiFormat();
8685
SetFakeIdToProducts(order);
87-
88-
StringContent content = new StringContent(JsonConvert.SerializeObject(order), System.Text.Encoding.UTF8, "application/json");
89-
90-
var response = await _apiClient.PostAsync(ordersUrl, content);
86+
87+
var response = await _apiClient.PostAsync(ordersUrl, order);
9188

9289
if (response.StatusCode == System.Net.HttpStatusCode.InternalServerError)
9390
throw new Exception("Error creating order, try later");
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
using Microsoft.Extensions.Logging;
2+
using Newtonsoft.Json;
3+
using System;
4+
using System.Net.Http;
5+
using System.Threading.Tasks;
6+
7+
namespace WebMVC.Services.Utilities
8+
{
9+
public class HttpApiClient : IHttpClient
10+
{
11+
private HttpClient _client;
12+
private ILogger _logger;
13+
public HttpClient Inst => _client;
14+
public HttpApiClient()
15+
{
16+
_client = new HttpClient();
17+
_logger = new LoggerFactory().CreateLogger(nameof(HttpApiClientWrapper));
18+
}
19+
20+
public async Task<string> GetStringAsync(string uri)
21+
{
22+
return await HttpInvoker(async () =>
23+
await _client.GetStringAsync(uri));
24+
}
25+
26+
public async Task<HttpResponseMessage> PostAsync<T>(string uri, T item)
27+
{
28+
var contentString = new StringContent(JsonConvert.SerializeObject(item), System.Text.Encoding.UTF8, "application/json");
29+
return await HttpInvoker(async () =>
30+
await _client.PostAsync(uri, contentString));
31+
}
32+
33+
public async Task<HttpResponseMessage> DeleteAsync(string uri)
34+
{
35+
return await HttpInvoker(async () =>
36+
await _client.DeleteAsync(uri));
37+
}
38+
39+
private async Task<T> HttpInvoker<T>(Func<Task<T>> action)
40+
{
41+
return await action();
42+
}
43+
}
44+
}
45+

0 commit comments

Comments
 (0)