From ddb03a0aa8f41108dbd93b4ceed6530fb4b4137a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ram=C3=B3n=20Tom=C3=A1s?= Date: Fri, 17 Mar 2017 13:12:34 +0100 Subject: [PATCH] Refactoing HttpClientApi --- src/Web/WebMVC/Services/BasketService.cs | 10 ++--- src/Web/WebMVC/Services/CatalogService.cs | 9 ++-- src/Web/WebMVC/Services/OrderingService.cs | 9 ++-- .../Services/Utilities/HttpApiClient.cs | 45 +++++++++++++++++++ ...ientWrapper.cs => HttpApiClientWrapper.cs} | 6 +-- .../WebMVC/Services/Utilities/IHttpClient.cs | 16 +++++++ src/Web/WebMVC/Startup.cs | 15 +++++-- src/Web/WebMVC/appsettings.json | 1 + 8 files changed, 87 insertions(+), 24 deletions(-) create mode 100644 src/Web/WebMVC/Services/Utilities/HttpApiClient.cs rename src/Web/WebMVC/Services/Utilities/{HttpClientWrapper.cs => HttpApiClientWrapper.cs} (96%) create mode 100644 src/Web/WebMVC/Services/Utilities/IHttpClient.cs diff --git a/src/Web/WebMVC/Services/BasketService.cs b/src/Web/WebMVC/Services/BasketService.cs index 087e02626..bcb138b87 100644 --- a/src/Web/WebMVC/Services/BasketService.cs +++ b/src/Web/WebMVC/Services/BasketService.cs @@ -14,15 +14,16 @@ namespace Microsoft.eShopOnContainers.WebMVC.Services public class BasketService : IBasketService { private readonly IOptionsSnapshot _settings; - private HttpClientWrapper _apiClient; + private IHttpClient _apiClient; private readonly string _remoteServiceBaseUrl; private IHttpContextAccessor _httpContextAccesor; - public BasketService(IOptionsSnapshot settings, IHttpContextAccessor httpContextAccesor) + public BasketService(IOptionsSnapshot settings, IHttpContextAccessor httpContextAccesor, IHttpClient httpClient) { _settings = settings; _remoteServiceBaseUrl = _settings.Value.BasketUrl; _httpContextAccesor = httpContextAccesor; + _apiClient = httpClient; } public async Task GetBasket(ApplicationUser user) @@ -30,7 +31,6 @@ namespace Microsoft.eShopOnContainers.WebMVC.Services var context = _httpContextAccesor.HttpContext; var token = await context.Authentication.GetTokenAsync("access_token"); - var _apiClient = new HttpClientWrapper(); _apiClient.Inst.DefaultRequestHeaders.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", token); var basketUrl = $"{_remoteServiceBaseUrl}/{user.Id.ToString()}"; @@ -51,8 +51,7 @@ namespace Microsoft.eShopOnContainers.WebMVC.Services { var context = _httpContextAccesor.HttpContext; var token = await context.Authentication.GetTokenAsync("access_token"); - - _apiClient = new HttpClientWrapper(); + _apiClient.Inst.DefaultRequestHeaders.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", token); var basketUrl = _remoteServiceBaseUrl; @@ -119,7 +118,6 @@ namespace Microsoft.eShopOnContainers.WebMVC.Services var context = _httpContextAccesor.HttpContext; var token = await context.Authentication.GetTokenAsync("access_token"); - _apiClient = new HttpClientWrapper(); _apiClient.Inst.DefaultRequestHeaders.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", token); var basketUrl = $"{_remoteServiceBaseUrl}/{user.Id.ToString()}"; var response = await _apiClient.DeleteAsync(basketUrl); diff --git a/src/Web/WebMVC/Services/CatalogService.cs b/src/Web/WebMVC/Services/CatalogService.cs index 7cafb29e0..83b139c1f 100644 --- a/src/Web/WebMVC/Services/CatalogService.cs +++ b/src/Web/WebMVC/Services/CatalogService.cs @@ -13,20 +13,19 @@ namespace Microsoft.eShopOnContainers.WebMVC.Services public class CatalogService : ICatalogService { private readonly IOptionsSnapshot _settings; - private HttpClientWrapper _apiClient; + private IHttpClient _apiClient; private readonly string _remoteServiceBaseUrl; - public CatalogService(IOptionsSnapshot settings, ILoggerFactory loggerFactory) { + public CatalogService(IOptionsSnapshot settings, ILoggerFactory loggerFactory, IHttpClient httpClient) { _settings = settings; _remoteServiceBaseUrl = $"{_settings.Value.CatalogUrl}/api/v1/catalog/"; - + _apiClient = httpClient; var log = loggerFactory.CreateLogger("catalog service"); log.LogDebug(settings.Value.CatalogUrl); } public async Task GetCatalogItems(int page,int take, int? brand, int? type) { - _apiClient = new HttpClientWrapper(); var itemsQs = $"items?pageIndex={page}&pageSize={take}"; var filterQs = ""; @@ -53,7 +52,6 @@ namespace Microsoft.eShopOnContainers.WebMVC.Services public async Task> GetBrands() { - _apiClient = new HttpClientWrapper(); var url = $"{_remoteServiceBaseUrl}catalogBrands"; var dataString = await _apiClient.GetStringAsync(url); @@ -72,7 +70,6 @@ namespace Microsoft.eShopOnContainers.WebMVC.Services public async Task> GetTypes() { - _apiClient = new HttpClientWrapper(); var url = $"{_remoteServiceBaseUrl}catalogTypes"; var dataString = await _apiClient.GetStringAsync(url); diff --git a/src/Web/WebMVC/Services/OrderingService.cs b/src/Web/WebMVC/Services/OrderingService.cs index ff98ac4f9..d53db3090 100644 --- a/src/Web/WebMVC/Services/OrderingService.cs +++ b/src/Web/WebMVC/Services/OrderingService.cs @@ -14,24 +14,23 @@ namespace Microsoft.eShopOnContainers.WebMVC.Services { public class OrderingService : IOrderingService { - private HttpClientWrapper _apiClient; + private IHttpClient _apiClient; private readonly string _remoteServiceBaseUrl; private readonly IOptionsSnapshot _settings; private readonly IHttpContextAccessor _httpContextAccesor; - public OrderingService(IOptionsSnapshot settings, IHttpContextAccessor httpContextAccesor) + public OrderingService(IOptionsSnapshot settings, IHttpContextAccessor httpContextAccesor, IHttpClient httpClient) { _remoteServiceBaseUrl = $"{settings.Value.OrderingUrl}/api/v1/orders"; _settings = settings; _httpContextAccesor = httpContextAccesor; + _apiClient = httpClient; } async public Task GetOrder(ApplicationUser user, string Id) { var context = _httpContextAccesor.HttpContext; var token = await context.Authentication.GetTokenAsync("access_token"); - - _apiClient = new HttpClientWrapper(); _apiClient.Inst.DefaultRequestHeaders.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", token); var ordersUrl = $"{_remoteServiceBaseUrl}/{Id}"; @@ -47,7 +46,6 @@ namespace Microsoft.eShopOnContainers.WebMVC.Services var context = _httpContextAccesor.HttpContext; var token = await context.Authentication.GetTokenAsync("access_token"); - _apiClient = new HttpClientWrapper(); _apiClient.Inst.DefaultRequestHeaders.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", token); var ordersUrl = _remoteServiceBaseUrl; @@ -78,7 +76,6 @@ namespace Microsoft.eShopOnContainers.WebMVC.Services var context = _httpContextAccesor.HttpContext; var token = await context.Authentication.GetTokenAsync("access_token"); - _apiClient = new HttpClientWrapper(); _apiClient.Inst.DefaultRequestHeaders.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", token); _apiClient.Inst.DefaultRequestHeaders.Add("x-requestid", order.RequestId.ToString()); diff --git a/src/Web/WebMVC/Services/Utilities/HttpApiClient.cs b/src/Web/WebMVC/Services/Utilities/HttpApiClient.cs new file mode 100644 index 000000000..8b142f393 --- /dev/null +++ b/src/Web/WebMVC/Services/Utilities/HttpApiClient.cs @@ -0,0 +1,45 @@ +using Microsoft.Extensions.Logging; +using Newtonsoft.Json; +using System; +using System.Net.Http; +using System.Threading.Tasks; + +namespace WebMVC.Services.Utilities +{ + public class HttpApiClient : IHttpClient + { + private HttpClient _client; + private ILogger _logger; + public HttpClient Inst => _client; + public HttpApiClient() + { + _client = new HttpClient(); + _logger = new LoggerFactory().CreateLogger(nameof(HttpApiClientWrapper)); + } + + public async Task GetStringAsync(string uri) + { + return await HttpInvoker(async () => + await _client.GetStringAsync(uri)); + } + + public async Task PostAsync(string uri, T item) + { + var contentString = new StringContent(JsonConvert.SerializeObject(item), System.Text.Encoding.UTF8, "application/json"); + return await HttpInvoker(async () => + await _client.PostAsync(uri, contentString)); + } + + public async Task DeleteAsync(string uri) + { + return await HttpInvoker(async () => + await _client.DeleteAsync(uri)); + } + + private async Task HttpInvoker(Func> action) + { + return await action(); + } + } +} + diff --git a/src/Web/WebMVC/Services/Utilities/HttpClientWrapper.cs b/src/Web/WebMVC/Services/Utilities/HttpApiClientWrapper.cs similarity index 96% rename from src/Web/WebMVC/Services/Utilities/HttpClientWrapper.cs rename to src/Web/WebMVC/Services/Utilities/HttpApiClientWrapper.cs index 24d64ab01..dba0db9df 100644 --- a/src/Web/WebMVC/Services/Utilities/HttpClientWrapper.cs +++ b/src/Web/WebMVC/Services/Utilities/HttpApiClientWrapper.cs @@ -8,16 +8,16 @@ using System.Threading.Tasks; namespace WebMVC.Services.Utilities { - public class HttpClientWrapper + public class HttpApiClientWrapper : IHttpClient { private HttpClient _client; private PolicyWrap _policyWrapper; private ILogger _logger; public HttpClient Inst => _client; - public HttpClientWrapper() + public HttpApiClientWrapper() { _client = new HttpClient(); - _logger = new LoggerFactory().CreateLogger(nameof(HttpClientWrapper)); + _logger = new LoggerFactory().CreateLogger(nameof(HttpApiClientWrapper)); // Add Policies to be applied _policyWrapper = Policy.WrapAsync( diff --git a/src/Web/WebMVC/Services/Utilities/IHttpClient.cs b/src/Web/WebMVC/Services/Utilities/IHttpClient.cs new file mode 100644 index 000000000..2a36466bc --- /dev/null +++ b/src/Web/WebMVC/Services/Utilities/IHttpClient.cs @@ -0,0 +1,16 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Net.Http; +using System.Threading.Tasks; + +namespace WebMVC.Services.Utilities +{ + public interface IHttpClient + { + HttpClient Inst { get; } + Task GetStringAsync(string uri); + Task PostAsync(string uri, T item); + Task DeleteAsync(string uri); + } +} diff --git a/src/Web/WebMVC/Startup.cs b/src/Web/WebMVC/Startup.cs index 8bd7708d3..7888ae253 100644 --- a/src/Web/WebMVC/Startup.cs +++ b/src/Web/WebMVC/Startup.cs @@ -14,6 +14,7 @@ using Microsoft.IdentityModel.Tokens; using Microsoft.AspNetCore.Http; using System.Threading; using Microsoft.Extensions.Options; +using WebMVC.Services.Utilities; namespace Microsoft.eShopOnContainers.WebMVC { @@ -43,14 +44,22 @@ namespace Microsoft.eShopOnContainers.WebMVC { services.AddMvc(); services.Configure(Configuration); - + // Add application services. - services.AddSingleton(); - + services.AddSingleton(); services.AddTransient(); services.AddTransient(); services.AddTransient(); services.AddTransient, IdentityParser>(); + + if(Configuration.GetValue("ActivateCircuitBreaker") == bool.TrueString) + { + services.AddSingleton(); + } + else + { + services.AddSingleton(); + } } // This method gets called by the runtime. Use this method to configure the HTTP request pipeline. diff --git a/src/Web/WebMVC/appsettings.json b/src/Web/WebMVC/appsettings.json index 9fe15aa25..b848c11b1 100644 --- a/src/Web/WebMVC/appsettings.json +++ b/src/Web/WebMVC/appsettings.json @@ -4,6 +4,7 @@ "BasketUrl": "http://localhost:5103", "IdentityUrl": "http://localhost:5105", "CallBackUrl": "http://localhost:5100/", + "ActivateCircuitBreaker": "True", "Logging": { "IncludeScopes": false, "LogLevel": {