Merge branch 'httpclientreview' into dev
This commit is contained in:
commit
2086399a1c
@ -1,16 +1,16 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Net.Http;
|
||||
using System.Net.Http;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Microsoft.eShopOnContainers.BuildingBlocks.Resilience.Http
|
||||
{
|
||||
public interface IHttpClient
|
||||
{
|
||||
HttpClient Inst { get; }
|
||||
Task<string> GetStringAsync(string uri);
|
||||
Task<HttpResponseMessage> PostAsync<T>(string uri, T item);
|
||||
Task<HttpResponseMessage> DeleteAsync(string uri);
|
||||
Task<string> GetStringAsync(string uri, string authorizationToken = null, string authorizationMethod = "Bearer");
|
||||
|
||||
Task<HttpResponseMessage> PostAsync<T>(string uri, T item, string authorizationToken = null, string requestId = null, string authorizationMethod = "Bearer");
|
||||
|
||||
Task<HttpResponseMessage> DeleteAsync(string uri, string authorizationToken = null, string requestId = null, string authorizationMethod = "Bearer");
|
||||
|
||||
Task<HttpResponseMessage> PutAsync<T>(string uri, T item, string authorizationToken = null, string requestId = null, string authorizationMethod = "Bearer");
|
||||
}
|
||||
}
|
||||
|
@ -4,8 +4,10 @@ using Polly;
|
||||
using Polly.Wrap;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Net;
|
||||
using System.Net.Http;
|
||||
using System.Net.Http.Headers;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Microsoft.eShopOnContainers.BuildingBlocks.Resilience.Http
|
||||
@ -18,47 +20,134 @@ namespace Microsoft.eShopOnContainers.BuildingBlocks.Resilience.Http
|
||||
public class ResilientHttpClient : IHttpClient
|
||||
{
|
||||
private HttpClient _client;
|
||||
private PolicyWrap _policyWrapper;
|
||||
private readonly Dictionary<string, PolicyWrap> _policiesPerOrigin;
|
||||
private ILogger<ResilientHttpClient> _logger;
|
||||
public HttpClient Inst => _client;
|
||||
private readonly Func<string, IEnumerable<Policy>> _policyCreator;
|
||||
//public HttpClient Inst => _client;
|
||||
|
||||
public ResilientHttpClient(Policy[] policies, ILogger<ResilientHttpClient> logger)
|
||||
public ResilientHttpClient(Func<string, IEnumerable<Policy>> policyCreator, ILogger<ResilientHttpClient> logger)
|
||||
{
|
||||
_client = new HttpClient();
|
||||
_logger = logger;
|
||||
_policiesPerOrigin = new Dictionary<string, PolicyWrap>();
|
||||
_policyCreator = policyCreator;
|
||||
}
|
||||
|
||||
// Add Policies to be applied
|
||||
_policyWrapper = Policy.WrapAsync(policies);
|
||||
}
|
||||
private Task<T> HttpInvoker<T>(string origin, Func<Task<T>> action)
|
||||
{
|
||||
var normalizedOrigin = NormalizeOrigin(origin);
|
||||
|
||||
public Task<string> GetStringAsync(string uri) =>
|
||||
HttpInvoker(() =>
|
||||
_client.GetStringAsync(uri));
|
||||
if (!_policiesPerOrigin.ContainsKey(normalizedOrigin))
|
||||
{
|
||||
var newWrapper = Policy.WrapAsync(_policyCreator(normalizedOrigin).ToArray());
|
||||
_policiesPerOrigin.Add(normalizedOrigin, newWrapper);
|
||||
}
|
||||
|
||||
var policyWrapper = _policiesPerOrigin[normalizedOrigin];
|
||||
|
||||
// Executes the action applying all
|
||||
// the policies defined in the wrapper
|
||||
return policyWrapper.ExecuteAsync(() => action());
|
||||
}
|
||||
|
||||
private static string NormalizeOrigin(string origin)
|
||||
{
|
||||
return origin?.Trim()?.ToLower();
|
||||
}
|
||||
|
||||
public Task<string> GetStringAsync(string uri, string authorizationToken = null, string authorizationMethod = "Bearer")
|
||||
{
|
||||
var origin = GetOriginFromUri(uri);
|
||||
return HttpInvoker(origin, async () =>
|
||||
{
|
||||
var requestMessage = new HttpRequestMessage(HttpMethod.Get, uri);
|
||||
|
||||
if (authorizationToken != null)
|
||||
{
|
||||
requestMessage.Headers.Authorization = new AuthenticationHeaderValue(authorizationMethod, authorizationToken);
|
||||
}
|
||||
|
||||
var response = await _client.SendAsync(requestMessage);
|
||||
|
||||
return await response.Content.ReadAsStringAsync();
|
||||
});
|
||||
}
|
||||
|
||||
private static string GetOriginFromUri(string uri)
|
||||
{
|
||||
var url = new Uri(uri);
|
||||
var origin = $"{url.Scheme}://{url.DnsSafeHost}:{url.Port}";
|
||||
return origin;
|
||||
}
|
||||
|
||||
private Task<HttpResponseMessage> DoPostPutAsync<T>(HttpMethod method, string uri, T item, string authorizationToken = null, string requestId = null, string authorizationMethod = "Bearer")
|
||||
{
|
||||
if (method != HttpMethod.Post && method != HttpMethod.Put)
|
||||
{
|
||||
throw new ArgumentException("Value must be either post or put.", nameof(method));
|
||||
}
|
||||
|
||||
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 origin = GetOriginFromUri(uri);
|
||||
return HttpInvoker(origin, async () =>
|
||||
{
|
||||
var response = _client.PostAsync(uri, new StringContent(JsonConvert.SerializeObject(item), System.Text.Encoding.UTF8, "application/json"));
|
||||
var requestMessage = new HttpRequestMessage(method, uri);
|
||||
|
||||
requestMessage.Content = new StringContent(JsonConvert.SerializeObject(item), System.Text.Encoding.UTF8, "application/json");
|
||||
|
||||
if (authorizationToken != null)
|
||||
{
|
||||
requestMessage.Headers.Authorization = new AuthenticationHeaderValue(authorizationMethod, authorizationToken);
|
||||
}
|
||||
|
||||
if (requestId != null)
|
||||
{
|
||||
requestMessage.Headers.Add("x-requestid", requestId);
|
||||
}
|
||||
|
||||
var response = await _client.SendAsync(requestMessage);
|
||||
|
||||
// raise exception if HttpResponseCode 500
|
||||
// needed for circuit breaker to track fails
|
||||
if (response.Result.StatusCode == HttpStatusCode.InternalServerError)
|
||||
|
||||
if (response.StatusCode == HttpStatusCode.InternalServerError)
|
||||
{
|
||||
throw new HttpRequestException();
|
||||
}
|
||||
|
||||
return response;
|
||||
});
|
||||
}
|
||||
|
||||
public Task<HttpResponseMessage> DeleteAsync(string uri) =>
|
||||
HttpInvoker(() => _client.DeleteAsync(uri));
|
||||
public Task<HttpResponseMessage> PostAsync<T>(string uri, T item, string authorizationToken = null, string requestId = null, string authorizationMethod = "Bearer")
|
||||
{
|
||||
return DoPostPutAsync(HttpMethod.Post, uri, item, authorizationToken, requestId, authorizationMethod);
|
||||
}
|
||||
public Task<HttpResponseMessage> PutAsync<T>(string uri, T item, string authorizationToken = null, string requestId = null, string authorizationMethod = "Bearer")
|
||||
{
|
||||
return DoPostPutAsync(HttpMethod.Put, uri, item, authorizationToken, requestId, authorizationMethod);
|
||||
}
|
||||
public Task<HttpResponseMessage> DeleteAsync(string uri, string authorizationToken = null, string requestId = null, string authorizationMethod = "Bearer")
|
||||
{
|
||||
var origin = GetOriginFromUri(uri);
|
||||
return HttpInvoker(origin, async () =>
|
||||
{
|
||||
var requestMessage = new HttpRequestMessage(HttpMethod.Delete, uri);
|
||||
|
||||
if (authorizationToken != null)
|
||||
{
|
||||
requestMessage.Headers.Authorization = new AuthenticationHeaderValue(authorizationMethod, authorizationToken);
|
||||
}
|
||||
|
||||
if (requestId != null)
|
||||
{
|
||||
requestMessage.Headers.Add("x-requestid", requestId);
|
||||
}
|
||||
|
||||
return await _client.SendAsync(requestMessage);
|
||||
});
|
||||
}
|
||||
|
||||
private Task<T> HttpInvoker<T>(Func<Task<T>> action) =>
|
||||
// Executes the action applying all
|
||||
// the policies defined in the wrapper
|
||||
_policyWrapper.ExecuteAsync(() => action());
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -1,7 +1,9 @@
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Newtonsoft.Json;
|
||||
using System;
|
||||
using System.Net;
|
||||
using System.Net.Http;
|
||||
using System.Net.Http.Headers;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Microsoft.eShopOnContainers.BuildingBlocks.Resilience.Http
|
||||
@ -10,24 +12,90 @@ namespace Microsoft.eShopOnContainers.BuildingBlocks.Resilience.Http
|
||||
{
|
||||
private HttpClient _client;
|
||||
private ILogger<StandardHttpClient> _logger;
|
||||
public HttpClient Inst => _client;
|
||||
|
||||
public StandardHttpClient(ILogger<StandardHttpClient> logger)
|
||||
{
|
||||
_client = new HttpClient();
|
||||
_logger = logger;
|
||||
}
|
||||
|
||||
public Task<string> GetStringAsync(string uri) =>
|
||||
_client.GetStringAsync(uri);
|
||||
|
||||
public Task<HttpResponseMessage> PostAsync<T>(string uri, T item)
|
||||
public async Task<string> GetStringAsync(string uri, string authorizationToken = null, string authorizationMethod = "Bearer")
|
||||
{
|
||||
var contentString = new StringContent(JsonConvert.SerializeObject(item), System.Text.Encoding.UTF8, "application/json");
|
||||
return _client.PostAsync(uri, contentString);
|
||||
var requestMessage = new HttpRequestMessage(HttpMethod.Get, uri);
|
||||
|
||||
if (authorizationToken != null)
|
||||
{
|
||||
requestMessage.Headers.Authorization = new AuthenticationHeaderValue(authorizationMethod, authorizationToken);
|
||||
}
|
||||
|
||||
var response = await _client.SendAsync(requestMessage);
|
||||
|
||||
return await response.Content.ReadAsStringAsync();
|
||||
}
|
||||
|
||||
public Task<HttpResponseMessage> DeleteAsync(string uri) =>
|
||||
_client.DeleteAsync(uri);
|
||||
private async Task<HttpResponseMessage> DoPostPutAsync<T>(HttpMethod method, string uri, T item, string authorizationToken = null, string requestId = null, string authorizationMethod = "Bearer")
|
||||
{
|
||||
if (method != HttpMethod.Post && method != HttpMethod.Put)
|
||||
{
|
||||
throw new ArgumentException("Value must be either post or put.", nameof(method));
|
||||
}
|
||||
|
||||
// a new StringContent must be created for each retry
|
||||
// as it is disposed after each call
|
||||
|
||||
var requestMessage = new HttpRequestMessage(HttpMethod.Post, uri);
|
||||
|
||||
requestMessage.Content = new StringContent(JsonConvert.SerializeObject(item), System.Text.Encoding.UTF8, "application/json");
|
||||
|
||||
if (authorizationToken != null)
|
||||
{
|
||||
requestMessage.Headers.Authorization = new AuthenticationHeaderValue(authorizationMethod, authorizationToken);
|
||||
}
|
||||
|
||||
if (requestId != null)
|
||||
{
|
||||
requestMessage.Headers.Add("x-requestid", requestId);
|
||||
}
|
||||
|
||||
var response = await _client.SendAsync(requestMessage);
|
||||
|
||||
// raise exception if HttpResponseCode 500
|
||||
// needed for circuit breaker to track fails
|
||||
|
||||
if (response.StatusCode == HttpStatusCode.InternalServerError)
|
||||
{
|
||||
throw new HttpRequestException();
|
||||
}
|
||||
|
||||
return response;
|
||||
}
|
||||
|
||||
|
||||
public async Task<HttpResponseMessage> PostAsync<T>(string uri, T item, string authorizationToken = null, string requestId = null, string authorizationMethod = "Bearer")
|
||||
{
|
||||
return await DoPostPutAsync(HttpMethod.Post, uri, item, authorizationToken, requestId, authorizationToken);
|
||||
}
|
||||
|
||||
public async Task<HttpResponseMessage> PutAsync<T>(string uri, T item, string authorizationToken = null, string requestId = null, string authorizationMethod = "Bearer")
|
||||
{
|
||||
return await DoPostPutAsync(HttpMethod.Put, uri, item, authorizationToken, requestId, authorizationToken);
|
||||
}
|
||||
public async Task<HttpResponseMessage> DeleteAsync(string uri, string authorizationToken = null, string requestId = null, string authorizationMethod = "Bearer")
|
||||
{
|
||||
var requestMessage = new HttpRequestMessage(HttpMethod.Delete, uri);
|
||||
|
||||
if (authorizationToken != null)
|
||||
{
|
||||
requestMessage.Headers.Authorization = new AuthenticationHeaderValue(authorizationMethod, authorizationToken);
|
||||
}
|
||||
|
||||
if (requestId != null)
|
||||
{
|
||||
requestMessage.Headers.Add("x-requestid", requestId);
|
||||
}
|
||||
|
||||
return await _client.SendAsync(requestMessage);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
68
src/Web/WebMVC/Infrastructure/API.cs
Normal file
68
src/Web/WebMVC/Infrastructure/API.cs
Normal file
@ -0,0 +1,68 @@
|
||||
namespace WebMVC.Infrastructure
|
||||
{
|
||||
public static class API
|
||||
{
|
||||
public static class Basket
|
||||
{
|
||||
public static string GetBasket(string baseUri, string basketId)
|
||||
{
|
||||
return $"{baseUri}/{basketId}";
|
||||
}
|
||||
|
||||
public static string UpdateBasket(string baseUri)
|
||||
{
|
||||
return baseUri;
|
||||
}
|
||||
|
||||
public static string CleanBasket(string baseUri, string basketId)
|
||||
{
|
||||
return $"{baseUri}/{basketId}";
|
||||
}
|
||||
}
|
||||
|
||||
public static class Order
|
||||
{
|
||||
public static string GetOrder(string baseUri, string orderId)
|
||||
{
|
||||
return $"{baseUri}/{orderId}";
|
||||
}
|
||||
|
||||
public static string GetAllMyOrders(string baseUri)
|
||||
{
|
||||
return baseUri;
|
||||
}
|
||||
|
||||
public static string AddNewOrder(string baseUri)
|
||||
{
|
||||
return $"{baseUri}/new";
|
||||
}
|
||||
}
|
||||
|
||||
public static class Catalog
|
||||
{
|
||||
public static string GetAllCatalogItems(string baseUri, int page, int take, int? brand, int? type)
|
||||
{
|
||||
var filterQs = "";
|
||||
|
||||
if (brand.HasValue || type.HasValue)
|
||||
{
|
||||
var brandQs = (brand.HasValue) ? brand.Value.ToString() : "null";
|
||||
var typeQs = (type.HasValue) ? type.Value.ToString() : "null";
|
||||
filterQs = $"/type/{typeQs}/brand/{brandQs}";
|
||||
}
|
||||
|
||||
return $"{baseUri}items{filterQs}?pageIndex={page}&pageSize={take}";
|
||||
}
|
||||
|
||||
public static string GetAllBrands(string baseUri)
|
||||
{
|
||||
return $"{baseUri}catalogBrands";
|
||||
}
|
||||
|
||||
public static string GetAllTypes(string baseUri)
|
||||
{
|
||||
return $"{baseUri}catalogTypes";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -17,7 +17,7 @@ namespace Microsoft.eShopOnContainers.WebMVC.Infrastructure
|
||||
=>_logger = logger;
|
||||
|
||||
public ResilientHttpClient CreateResilientHttpClient()
|
||||
=> new ResilientHttpClient(CreatePolicies(), _logger);
|
||||
=> new ResilientHttpClient((origin) => CreatePolicies(), _logger);
|
||||
|
||||
|
||||
private Policy[] CreatePolicies()
|
||||
|
@ -5,9 +5,8 @@ using Microsoft.eShopOnContainers.WebMVC.ViewModels;
|
||||
using Microsoft.Extensions.Options;
|
||||
using Newtonsoft.Json;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Net.Http;
|
||||
using System.Threading.Tasks;
|
||||
using WebMVC.Infrastructure;
|
||||
|
||||
namespace Microsoft.eShopOnContainers.WebMVC.Services
|
||||
{
|
||||
@ -28,15 +27,13 @@ namespace Microsoft.eShopOnContainers.WebMVC.Services
|
||||
|
||||
public async Task<Basket> GetBasket(ApplicationUser user)
|
||||
{
|
||||
var context = _httpContextAccesor.HttpContext;
|
||||
var token = await context.Authentication.GetTokenAsync("access_token");
|
||||
var token = await GetUserTokenAsync();
|
||||
var getBasketUri = API.Basket.GetBasket(_remoteServiceBaseUrl, user.Id);
|
||||
|
||||
_apiClient.Inst.DefaultRequestHeaders.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", token);
|
||||
var dataString = await _apiClient.GetStringAsync(getBasketUri, token);
|
||||
|
||||
var basketUrl = $"{_remoteServiceBaseUrl}/{user.Id}";
|
||||
var dataString = await _apiClient.GetStringAsync(basketUrl);
|
||||
// Use the ?? Null conditional operator to simplify the initialization of response
|
||||
var response = JsonConvert.DeserializeObject<Basket>(dataString) ??
|
||||
var response = JsonConvert.DeserializeObject<Basket>(dataString) ??
|
||||
new Basket()
|
||||
{
|
||||
BuyerId = user.Id
|
||||
@ -47,14 +44,10 @@ namespace Microsoft.eShopOnContainers.WebMVC.Services
|
||||
|
||||
public async Task<Basket> UpdateBasket(Basket basket)
|
||||
{
|
||||
var context = _httpContextAccesor.HttpContext;
|
||||
var token = await context.Authentication.GetTokenAsync("access_token");
|
||||
|
||||
_apiClient.Inst.DefaultRequestHeaders.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", token);
|
||||
var token = await GetUserTokenAsync();
|
||||
var updateBasketUri = API.Basket.UpdateBasket(_remoteServiceBaseUrl);
|
||||
|
||||
var basketUrl = _remoteServiceBaseUrl;
|
||||
|
||||
var response = await _apiClient.PostAsync(basketUrl, basket);
|
||||
var response = await _apiClient.PostAsync(updateBasketUri, basket, token);
|
||||
|
||||
response.EnsureSuccessStatusCode();
|
||||
|
||||
@ -88,7 +81,7 @@ namespace Microsoft.eShopOnContainers.WebMVC.Services
|
||||
order.OrderItems.Add(new OrderItem()
|
||||
{
|
||||
ProductId = int.Parse(x.ProductId),
|
||||
|
||||
|
||||
PictureUrl = x.PictureUrl,
|
||||
ProductName = x.ProductName,
|
||||
Units = x.Quantity,
|
||||
@ -102,7 +95,8 @@ namespace Microsoft.eShopOnContainers.WebMVC.Services
|
||||
|
||||
public async Task AddItemToBasket(ApplicationUser user, BasketItem product)
|
||||
{
|
||||
Basket basket = await GetBasket(user);
|
||||
var basket = await GetBasket(user);
|
||||
|
||||
if (basket == null)
|
||||
{
|
||||
basket = new Basket()
|
||||
@ -113,20 +107,25 @@ namespace Microsoft.eShopOnContainers.WebMVC.Services
|
||||
}
|
||||
|
||||
basket.Items.Add(product);
|
||||
|
||||
await UpdateBasket(basket);
|
||||
}
|
||||
|
||||
public async Task CleanBasket(ApplicationUser user)
|
||||
{
|
||||
var context = _httpContextAccesor.HttpContext;
|
||||
var token = await context.Authentication.GetTokenAsync("access_token");
|
||||
var token = await GetUserTokenAsync();
|
||||
var cleanBasketUri = API.Basket.CleanBasket(_remoteServiceBaseUrl, user.Id);
|
||||
|
||||
var response = await _apiClient.DeleteAsync(cleanBasketUri, token);
|
||||
|
||||
_apiClient.Inst.DefaultRequestHeaders.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", token);
|
||||
var basketUrl = $"{_remoteServiceBaseUrl}/{user.Id}";
|
||||
var response = await _apiClient.DeleteAsync(basketUrl);
|
||||
|
||||
//CCE: response status code...
|
||||
|
||||
}
|
||||
|
||||
async Task<string> GetUserTokenAsync()
|
||||
{
|
||||
var context = _httpContextAccesor.HttpContext;
|
||||
return await context.Authentication.GetTokenAsync("access_token");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -7,43 +7,32 @@ using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading.Tasks;
|
||||
using WebMVC.Infrastructure;
|
||||
|
||||
namespace Microsoft.eShopOnContainers.WebMVC.Services
|
||||
{
|
||||
public class CatalogService : ICatalogService
|
||||
{
|
||||
private readonly IOptionsSnapshot<AppSettings> _settings;
|
||||
private IHttpClient _apiClient;
|
||||
private readonly IHttpClient _apiClient;
|
||||
private readonly ILogger<CatalogService> _logger;
|
||||
|
||||
private readonly string _remoteServiceBaseUrl;
|
||||
|
||||
public CatalogService(IOptionsSnapshot<AppSettings> 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<Catalog> GetCatalogItems(int page,int take, int? brand, int? type)
|
||||
|
||||
public CatalogService(IOptionsSnapshot<AppSettings> settings, IHttpClient httpClient, ILogger<CatalogService> logger)
|
||||
{
|
||||
var itemsQs = $"items?pageIndex={page}&pageSize={take}";
|
||||
var filterQs = "";
|
||||
_settings = settings;
|
||||
_apiClient = httpClient;
|
||||
_logger = logger;
|
||||
|
||||
if (brand.HasValue || type.HasValue)
|
||||
{
|
||||
var brandQs = (brand.HasValue) ? brand.Value.ToString() : "null";
|
||||
var typeQs = (type.HasValue) ? type.Value.ToString() : "null";
|
||||
filterQs = $"/type/{typeQs}/brand/{brandQs}";
|
||||
}
|
||||
_remoteServiceBaseUrl = $"{_settings.Value.CatalogUrl}/api/v1/catalog/";
|
||||
}
|
||||
|
||||
var catalogUrl = $"{_remoteServiceBaseUrl}items{filterQs}?pageIndex={page}&pageSize={take}";
|
||||
public async Task<Catalog> GetCatalogItems(int page, int take, int? brand, int? type)
|
||||
{
|
||||
var allcatalogItemsUri = API.Catalog.GetAllCatalogItems(_remoteServiceBaseUrl, page, take, brand, type);
|
||||
|
||||
var dataString = "";
|
||||
|
||||
//
|
||||
// Using a HttpClient wrapper with Retry and Exponential Backoff
|
||||
//
|
||||
dataString = await _apiClient.GetStringAsync(catalogUrl);
|
||||
var dataString = await _apiClient.GetStringAsync(allcatalogItemsUri);
|
||||
|
||||
var response = JsonConvert.DeserializeObject<Catalog>(dataString);
|
||||
|
||||
@ -52,14 +41,16 @@ namespace Microsoft.eShopOnContainers.WebMVC.Services
|
||||
|
||||
public async Task<IEnumerable<SelectListItem>> GetBrands()
|
||||
{
|
||||
var url = $"{_remoteServiceBaseUrl}catalogBrands";
|
||||
var dataString = await _apiClient.GetStringAsync(url);
|
||||
var getBrandsUri = API.Catalog.GetAllBrands(_remoteServiceBaseUrl);
|
||||
|
||||
var dataString = await _apiClient.GetStringAsync(getBrandsUri);
|
||||
|
||||
var items = new List<SelectListItem>();
|
||||
items.Add(new SelectListItem() { Value = null, Text = "All", Selected = true });
|
||||
|
||||
JArray brands = JArray.Parse(dataString);
|
||||
foreach (JObject brand in brands.Children<JObject>())
|
||||
var brands = JArray.Parse(dataString);
|
||||
|
||||
foreach (var brand in brands.Children<JObject>())
|
||||
{
|
||||
items.Add(new SelectListItem()
|
||||
{
|
||||
@ -73,14 +64,15 @@ namespace Microsoft.eShopOnContainers.WebMVC.Services
|
||||
|
||||
public async Task<IEnumerable<SelectListItem>> GetTypes()
|
||||
{
|
||||
var url = $"{_remoteServiceBaseUrl}catalogTypes";
|
||||
var dataString = await _apiClient.GetStringAsync(url);
|
||||
var getTypesUri = API.Catalog.GetAllTypes(_remoteServiceBaseUrl);
|
||||
|
||||
var dataString = await _apiClient.GetStringAsync(getTypesUri);
|
||||
|
||||
var items = new List<SelectListItem>();
|
||||
items.Add(new SelectListItem() { Value = null, Text = "All", Selected = true });
|
||||
|
||||
JArray brands = JArray.Parse(dataString);
|
||||
foreach (JObject brand in brands.Children<JObject>())
|
||||
var brands = JArray.Parse(dataString);
|
||||
foreach (var brand in brands.Children<JObject>())
|
||||
{
|
||||
items.Add(new SelectListItem()
|
||||
{
|
||||
|
@ -1,14 +1,13 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.eShopOnContainers.WebMVC.ViewModels;
|
||||
using Microsoft.AspNetCore.Authentication;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.Extensions.Options;
|
||||
using System.Net.Http;
|
||||
using Newtonsoft.Json;
|
||||
using Microsoft.AspNetCore.Authentication;
|
||||
using Microsoft.eShopOnContainers.BuildingBlocks.Resilience.Http;
|
||||
using Microsoft.eShopOnContainers.WebMVC.ViewModels;
|
||||
using Microsoft.Extensions.Options;
|
||||
using Newtonsoft.Json;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading.Tasks;
|
||||
using WebMVC.Infrastructure;
|
||||
|
||||
namespace Microsoft.eShopOnContainers.WebMVC.Services
|
||||
{
|
||||
@ -27,15 +26,13 @@ namespace Microsoft.eShopOnContainers.WebMVC.Services
|
||||
_apiClient = httpClient;
|
||||
}
|
||||
|
||||
async public Task<Order> GetOrder(ApplicationUser user, string Id)
|
||||
async public Task<Order> GetOrder(ApplicationUser user, string id)
|
||||
{
|
||||
var context = _httpContextAccesor.HttpContext;
|
||||
var token = await context.Authentication.GetTokenAsync("access_token");
|
||||
_apiClient.Inst.DefaultRequestHeaders.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", token);
|
||||
var token = await GetUserTokenAsync();
|
||||
var getOrderUri = API.Order.GetOrder(_remoteServiceBaseUrl, id);
|
||||
|
||||
var dataString = await _apiClient.GetStringAsync(getOrderUri, token);
|
||||
|
||||
var ordersUrl = $"{_remoteServiceBaseUrl}/{Id}";
|
||||
var dataString = await _apiClient.GetStringAsync(ordersUrl);
|
||||
|
||||
var response = JsonConvert.DeserializeObject<Order>(dataString);
|
||||
|
||||
return response;
|
||||
@ -43,16 +40,13 @@ namespace Microsoft.eShopOnContainers.WebMVC.Services
|
||||
|
||||
async public Task<List<Order>> GetMyOrders(ApplicationUser user)
|
||||
{
|
||||
var context = _httpContextAccesor.HttpContext;
|
||||
var token = await context.Authentication.GetTokenAsync("access_token");
|
||||
var token = await GetUserTokenAsync();
|
||||
var allMyOrdersUri = API.Order.GetAllMyOrders(_remoteServiceBaseUrl);
|
||||
|
||||
_apiClient.Inst.DefaultRequestHeaders.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", token);
|
||||
|
||||
var ordersUrl = _remoteServiceBaseUrl;
|
||||
var dataString = await _apiClient.GetStringAsync(ordersUrl);
|
||||
var dataString = await _apiClient.GetStringAsync(allMyOrdersUri, token);
|
||||
var response = JsonConvert.DeserializeObject<List<Order>>(dataString);
|
||||
|
||||
return response;
|
||||
return response;
|
||||
}
|
||||
|
||||
public Order MapUserInfoIntoOrder(ApplicationUser user, Order order)
|
||||
@ -62,10 +56,10 @@ namespace Microsoft.eShopOnContainers.WebMVC.Services
|
||||
order.State = user.State;
|
||||
order.Country = user.Country;
|
||||
order.ZipCode = user.ZipCode;
|
||||
|
||||
|
||||
order.CardNumber = user.CardNumber;
|
||||
order.CardHolderName = user.CardHolderName;
|
||||
order.CardExpiration = new DateTime(int.Parse("20" + user.Expiration.Split('/')[1]),int.Parse(user.Expiration.Split('/')[0]), 1);
|
||||
order.CardExpiration = new DateTime(int.Parse("20" + user.Expiration.Split('/')[1]), int.Parse(user.Expiration.Split('/')[0]), 1);
|
||||
order.CardSecurityNumber = user.SecurityNumber;
|
||||
|
||||
return order;
|
||||
@ -73,21 +67,21 @@ namespace Microsoft.eShopOnContainers.WebMVC.Services
|
||||
|
||||
async public Task CreateOrder(Order order)
|
||||
{
|
||||
var context = _httpContextAccesor.HttpContext;
|
||||
var token = await context.Authentication.GetTokenAsync("access_token");
|
||||
var token = await GetUserTokenAsync();
|
||||
var requestId = order.RequestId.ToString();
|
||||
var addNewOrderUri = API.Order.AddNewOrder(_remoteServiceBaseUrl);
|
||||
|
||||
_apiClient.Inst.DefaultRequestHeaders.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", token);
|
||||
_apiClient.Inst.DefaultRequestHeaders.Add("x-requestid", order.RequestId.ToString());
|
||||
|
||||
var ordersUrl = $"{_remoteServiceBaseUrl}/new";
|
||||
order.CardTypeId = 1;
|
||||
order.CardExpirationApiFormat();
|
||||
|
||||
SetFakeIdToProducts(order);
|
||||
|
||||
var response = await _apiClient.PostAsync(ordersUrl, order);
|
||||
var response = await _apiClient.PostAsync(addNewOrderUri, order, token, requestId);
|
||||
|
||||
if (response.StatusCode == System.Net.HttpStatusCode.InternalServerError)
|
||||
throw new Exception("Error creating order, try later");
|
||||
{
|
||||
throw new Exception("Error creating order, try later.");
|
||||
}
|
||||
|
||||
response.EnsureSuccessStatusCode();
|
||||
}
|
||||
@ -106,10 +100,17 @@ namespace Microsoft.eShopOnContainers.WebMVC.Services
|
||||
destination.CardSecurityNumber = original.CardSecurityNumber;
|
||||
}
|
||||
|
||||
private void SetFakeIdToProducts(Order order)
|
||||
void SetFakeIdToProducts(Order order)
|
||||
{
|
||||
var id = 1;
|
||||
order.OrderItems.ForEach(x => { x.ProductId = id; id++; });
|
||||
}
|
||||
|
||||
async Task<string> GetUserTokenAsync()
|
||||
{
|
||||
var context = _httpContextAccesor.HttpContext;
|
||||
|
||||
return await context.Authentication.GetTokenAsync("access_token");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -70,11 +70,11 @@ namespace Microsoft.eShopOnContainers.WebMVC
|
||||
if (Configuration.GetValue<string>("UseResilientHttp") == bool.TrueString)
|
||||
{
|
||||
services.AddTransient<IResilientHttpClientFactory, ResilientHttpClientFactory>();
|
||||
services.AddTransient<IHttpClient, ResilientHttpClient>(sp => sp.GetService<IResilientHttpClientFactory>().CreateResilientHttpClient());
|
||||
services.AddSingleton<IHttpClient, ResilientHttpClient>(sp => sp.GetService<IResilientHttpClientFactory>().CreateResilientHttpClient());
|
||||
}
|
||||
else
|
||||
{
|
||||
services.AddTransient<IHttpClient, StandardHttpClient>();
|
||||
services.AddSingleton<IHttpClient, StandardHttpClient>();
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user