diff --git a/src/ApiGateways/Mobile.Bff.Shopping/aggregator/Config/UrlsConfig.cs b/src/ApiGateways/Mobile.Bff.Shopping/aggregator/Config/UrlsConfig.cs index 90fa010cd..ccd733bc3 100644 --- a/src/ApiGateways/Mobile.Bff.Shopping/aggregator/Config/UrlsConfig.cs +++ b/src/ApiGateways/Mobile.Bff.Shopping/aggregator/Config/UrlsConfig.cs @@ -1,38 +1,35 @@ -using System.Collections.Generic; +namespace Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator.Config; -namespace Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator.Config +public class UrlsConfig { - public class UrlsConfig + public class CatalogOperations { - public class CatalogOperations - { - public static string GetItemById(int id) => $"/api/v1/catalog/items/{id}"; + public static string GetItemById(int id) => $"/api/v1/catalog/items/{id}"; - public static string GetItemsById(IEnumerable ids) => $"/api/v1/catalog/items?ids={string.Join(',', ids)}"; - } + public static string GetItemsById(IEnumerable ids) => $"/api/v1/catalog/items?ids={string.Join(',', ids)}"; + } - public class BasketOperations - { - public static string GetItemById(string id) => $"/api/v1/basket/{id}"; + public class BasketOperations + { + public static string GetItemById(string id) => $"/api/v1/basket/{id}"; - public static string UpdateBasket() => "/api/v1/basket"; - } + public static string UpdateBasket() => "/api/v1/basket"; + } - public class OrdersOperations - { - public static string GetOrderDraft() => "/api/v1/orders/draft"; - } + public class OrdersOperations + { + public static string GetOrderDraft() => "/api/v1/orders/draft"; + } - public string Basket { get; set; } + public string Basket { get; set; } - public string Catalog { get; set; } + public string Catalog { get; set; } - public string Orders { get; set; } + public string Orders { get; set; } - public string GrpcBasket { get; set; } + public string GrpcBasket { get; set; } - public string GrpcCatalog { get; set; } + public string GrpcCatalog { get; set; } - public string GrpcOrdering { get; set; } - } + public string GrpcOrdering { get; set; } } diff --git a/src/ApiGateways/Mobile.Bff.Shopping/aggregator/Controllers/BasketController.cs b/src/ApiGateways/Mobile.Bff.Shopping/aggregator/Controllers/BasketController.cs index 64399465a..9f39cdd6d 100644 --- a/src/ApiGateways/Mobile.Bff.Shopping/aggregator/Controllers/BasketController.cs +++ b/src/ApiGateways/Mobile.Bff.Shopping/aggregator/Controllers/BasketController.cs @@ -1,156 +1,146 @@ -using Microsoft.AspNetCore.Authorization; -using Microsoft.AspNetCore.Mvc; -using Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator.Models; -using Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator.Services; -using System; -using System.Linq; -using System.Net; -using System.Threading.Tasks; - -namespace Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator.Controllers +namespace Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator.Controllers; + +[Route("api/v1/[controller]")] +[Authorize] +[ApiController] +public class BasketController : ControllerBase { - [Route("api/v1/[controller]")] - [Authorize] - [ApiController] - public class BasketController : ControllerBase + private readonly ICatalogService _catalog; + private readonly IBasketService _basket; + + public BasketController(ICatalogService catalogService, IBasketService basketService) { - private readonly ICatalogService _catalog; - private readonly IBasketService _basket; + _catalog = catalogService; + _basket = basketService; + } - public BasketController(ICatalogService catalogService, IBasketService basketService) + [HttpPost] + [HttpPut] + [ProducesResponseType((int)HttpStatusCode.BadRequest)] + [ProducesResponseType(typeof(BasketData), (int)HttpStatusCode.OK)] + public async Task> UpdateAllBasketAsync([FromBody] UpdateBasketRequest data) + { + if (data.Items == null || !data.Items.Any()) { - _catalog = catalogService; - _basket = basketService; + return BadRequest("Need to pass at least one basket line"); } - [HttpPost] - [HttpPut] - [ProducesResponseType((int)HttpStatusCode.BadRequest)] - [ProducesResponseType(typeof(BasketData), (int)HttpStatusCode.OK)] - public async Task> UpdateAllBasketAsync([FromBody] UpdateBasketRequest data) - { - if (data.Items == null || !data.Items.Any()) - { - return BadRequest("Need to pass at least one basket line"); - } + // Retrieve the current basket + var basket = await _basket.GetById(data.BuyerId) ?? new BasketData(data.BuyerId); - // Retrieve the current basket - var basket = await _basket.GetById(data.BuyerId) ?? new BasketData(data.BuyerId); - - var catalogItems = await _catalog.GetCatalogItemsAsync(data.Items.Select(x => x.ProductId)); - // group by product id to avoid duplicates - var itemsCalculated = data - .Items - .GroupBy(x => x.ProductId, x => x, (k, i) => new { productId = k, items = i }) - .Select(groupedItem => - { - var item = groupedItem.items.First(); - item.Quantity = groupedItem.items.Sum(i => i.Quantity); - return item; - }); - - foreach (var bitem in itemsCalculated) - { - var catalogItem = catalogItems.SingleOrDefault(ci => ci.Id == bitem.ProductId); - if (catalogItem == null) + var catalogItems = await _catalog.GetCatalogItemsAsync(data.Items.Select(x => x.ProductId)); + // group by product id to avoid duplicates + var itemsCalculated = data + .Items + .GroupBy(x => x.ProductId, x => x, (k, i) => new { productId = k, items = i }) + .Select(groupedItem => { - return BadRequest($"Basket refers to a non-existing catalog item ({bitem.ProductId})"); - } + var item = groupedItem.items.First(); + item.Quantity = groupedItem.items.Sum(i => i.Quantity); + return item; + }); - var itemInBasket = basket.Items.FirstOrDefault(x => x.ProductId == bitem.ProductId); - if (itemInBasket == null) - { - basket.Items.Add(new BasketDataItem() - { - Id = bitem.Id, - ProductId = catalogItem.Id, - ProductName = catalogItem.Name, - PictureUrl = catalogItem.PictureUri, - UnitPrice = catalogItem.Price, - Quantity = bitem.Quantity - }); - } - else - { - itemInBasket.Quantity = bitem.Quantity; - } - } - - await _basket.UpdateAsync(basket); - - return basket; - } - - [HttpPut] - [Route("items")] - [ProducesResponseType((int)HttpStatusCode.BadRequest)] - [ProducesResponseType(typeof(BasketData), (int)HttpStatusCode.OK)] - public async Task> UpdateQuantitiesAsync([FromBody] UpdateBasketItemsRequest data) + foreach (var bitem in itemsCalculated) { - if (!data.Updates.Any()) + var catalogItem = catalogItems.SingleOrDefault(ci => ci.Id == bitem.ProductId); + if (catalogItem == null) { - return BadRequest("No updates sent"); + return BadRequest($"Basket refers to a non-existing catalog item ({bitem.ProductId})"); } - // Retrieve the current basket - var currentBasket = await _basket.GetById(data.BasketId); - if (currentBasket == null) + var itemInBasket = basket.Items.FirstOrDefault(x => x.ProductId == bitem.ProductId); + if (itemInBasket == null) { - return BadRequest($"Basket with id {data.BasketId} not found."); + basket.Items.Add(new BasketDataItem() + { + Id = bitem.Id, + ProductId = catalogItem.Id, + ProductName = catalogItem.Name, + PictureUrl = catalogItem.PictureUri, + UnitPrice = catalogItem.Price, + Quantity = bitem.Quantity + }); } - - // Update with new quantities - foreach (var update in data.Updates) + else { - var basketItem = currentBasket.Items.SingleOrDefault(bitem => bitem.Id == update.BasketItemId); + itemInBasket.Quantity = bitem.Quantity; + } + } - if (basketItem == null) - { - return BadRequest($"Basket item with id {update.BasketItemId} not found"); - } + await _basket.UpdateAsync(basket); - basketItem.Quantity = update.NewQty; - } + return basket; + } - // Save the updated basket - await _basket.UpdateAsync(currentBasket); + [HttpPut] + [Route("items")] + [ProducesResponseType((int)HttpStatusCode.BadRequest)] + [ProducesResponseType(typeof(BasketData), (int)HttpStatusCode.OK)] + public async Task> UpdateQuantitiesAsync([FromBody] UpdateBasketItemsRequest data) + { + if (!data.Updates.Any()) + { + return BadRequest("No updates sent"); + } - return currentBasket; + // Retrieve the current basket + var currentBasket = await _basket.GetById(data.BasketId); + if (currentBasket == null) + { + return BadRequest($"Basket with id {data.BasketId} not found."); } - [HttpPost] - [Route("items")] - [ProducesResponseType((int)HttpStatusCode.BadRequest)] - [ProducesResponseType((int)HttpStatusCode.OK)] - public async Task AddBasketItemAsync([FromBody] AddBasketItemRequest data) + // Update with new quantities + foreach (var update in data.Updates) { - if (data == null || data.Quantity == 0) + var basketItem = currentBasket.Items.SingleOrDefault(bitem => bitem.Id == update.BasketItemId); + + if (basketItem == null) { - return BadRequest("Invalid payload"); + return BadRequest($"Basket item with id {update.BasketItemId} not found"); } - // Step 1: Get the item from catalog - var item = await _catalog.GetCatalogItemAsync(data.CatalogItemId); + basketItem.Quantity = update.NewQty; + } + + // Save the updated basket + await _basket.UpdateAsync(currentBasket); - //item.PictureUri = + return currentBasket; + } - // Step 2: Get current basket status - var currentBasket = (await _basket.GetById(data.BasketId)) ?? new BasketData(data.BasketId); - // Step 3: Merge current status with new product - currentBasket.Items.Add(new BasketDataItem() - { - UnitPrice = item.Price, - PictureUrl = item.PictureUri, - ProductId = item.Id, - ProductName = item.Name, - Quantity = data.Quantity, - Id = Guid.NewGuid().ToString() - }); - - // Step 4: Update basket - await _basket.UpdateAsync(currentBasket); - - return Ok(); + [HttpPost] + [Route("items")] + [ProducesResponseType((int)HttpStatusCode.BadRequest)] + [ProducesResponseType((int)HttpStatusCode.OK)] + public async Task AddBasketItemAsync([FromBody] AddBasketItemRequest data) + { + if (data == null || data.Quantity == 0) + { + return BadRequest("Invalid payload"); } + + // Step 1: Get the item from catalog + var item = await _catalog.GetCatalogItemAsync(data.CatalogItemId); + + //item.PictureUri = + + // Step 2: Get current basket status + var currentBasket = (await _basket.GetById(data.BasketId)) ?? new BasketData(data.BasketId); + // Step 3: Merge current status with new product + currentBasket.Items.Add(new BasketDataItem() + { + UnitPrice = item.Price, + PictureUrl = item.PictureUri, + ProductId = item.Id, + ProductName = item.Name, + Quantity = data.Quantity, + Id = Guid.NewGuid().ToString() + }); + + // Step 4: Update basket + await _basket.UpdateAsync(currentBasket); + + return Ok(); } } diff --git a/src/ApiGateways/Mobile.Bff.Shopping/aggregator/Controllers/HomeController.cs b/src/ApiGateways/Mobile.Bff.Shopping/aggregator/Controllers/HomeController.cs index e72e23ca7..5c931462a 100644 --- a/src/ApiGateways/Mobile.Bff.Shopping/aggregator/Controllers/HomeController.cs +++ b/src/ApiGateways/Mobile.Bff.Shopping/aggregator/Controllers/HomeController.cs @@ -1,14 +1,11 @@ -using Microsoft.AspNetCore.Mvc; +namespace Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator.Controllers; -namespace Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator.Controllers +[Route("")] +public class HomeController : Controller { - [Route("")] - public class HomeController : Controller + [HttpGet()] + public IActionResult Index() { - [HttpGet()] - public IActionResult Index() - { - return new RedirectResult("~/swagger"); - } + return new RedirectResult("~/swagger"); } } diff --git a/src/ApiGateways/Mobile.Bff.Shopping/aggregator/Controllers/OrderController.cs b/src/ApiGateways/Mobile.Bff.Shopping/aggregator/Controllers/OrderController.cs index 8bacc80d4..2203db664 100644 --- a/src/ApiGateways/Mobile.Bff.Shopping/aggregator/Controllers/OrderController.cs +++ b/src/ApiGateways/Mobile.Bff.Shopping/aggregator/Controllers/OrderController.cs @@ -1,45 +1,37 @@ -using Microsoft.AspNetCore.Authorization; -using Microsoft.AspNetCore.Mvc; -using Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator.Models; -using Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator.Services; -using System.Net; -using System.Threading.Tasks; +namespace Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator.Controllers; -namespace Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator.Controllers +[Route("api/v1/[controller]")] +[Authorize] +[ApiController] +public class OrderController : ControllerBase { - [Route("api/v1/[controller]")] - [Authorize] - [ApiController] - public class OrderController : ControllerBase + private readonly IBasketService _basketService; + private readonly IOrderingService _orderingService; + + public OrderController(IBasketService basketService, IOrderingService orderingService) { - private readonly IBasketService _basketService; - private readonly IOrderingService _orderingService; + _basketService = basketService; + _orderingService = orderingService; + } - public OrderController(IBasketService basketService, IOrderingService orderingService) + [Route("draft/{basketId}")] + [HttpGet] + [ProducesResponseType((int)HttpStatusCode.BadRequest)] + [ProducesResponseType(typeof(OrderData), (int)HttpStatusCode.OK)] + public async Task> GetOrderDraftAsync(string basketId) + { + if (string.IsNullOrEmpty(basketId)) { - _basketService = basketService; - _orderingService = orderingService; + return BadRequest("Need a valid basketid"); } + // Get the basket data and build a order draft based on it + var basket = await _basketService.GetById(basketId); - [Route("draft/{basketId}")] - [HttpGet] - [ProducesResponseType((int)HttpStatusCode.BadRequest)] - [ProducesResponseType(typeof(OrderData), (int)HttpStatusCode.OK)] - public async Task> GetOrderDraftAsync(string basketId) + if (basket == null) { - if (string.IsNullOrEmpty(basketId)) - { - return BadRequest("Need a valid basketid"); - } - // Get the basket data and build a order draft based on it - var basket = await _basketService.GetById(basketId); - - if (basket == null) - { - return BadRequest($"No basket found for id {basketId}"); - } - - return await _orderingService.GetOrderDraftAsync(basket); + return BadRequest($"No basket found for id {basketId}"); } + + return await _orderingService.GetOrderDraftAsync(basket); } } diff --git a/src/ApiGateways/Mobile.Bff.Shopping/aggregator/Filters/AuthorizeCheckOperationFilter.cs b/src/ApiGateways/Mobile.Bff.Shopping/aggregator/Filters/AuthorizeCheckOperationFilter.cs index e975edb23..e6a0bf56b 100644 --- a/src/ApiGateways/Mobile.Bff.Shopping/aggregator/Filters/AuthorizeCheckOperationFilter.cs +++ b/src/ApiGateways/Mobile.Bff.Shopping/aggregator/Filters/AuthorizeCheckOperationFilter.cs @@ -1,12 +1,5 @@ -using Microsoft.AspNetCore.Authorization; -using Microsoft.OpenApi.Models; -using Swashbuckle.AspNetCore.SwaggerGen; -using System.Collections.Generic; -using System.Linq; - -namespace Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator.Filters +namespace Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator.Filters { - namespace Basket.API.Infrastructure.Filters { public class AuthorizeCheckOperationFilter : IOperationFilter diff --git a/src/ApiGateways/Mobile.Bff.Shopping/aggregator/Infrastructure/GrpcExceptionInterceptor.cs b/src/ApiGateways/Mobile.Bff.Shopping/aggregator/Infrastructure/GrpcExceptionInterceptor.cs index e74a4b2f5..c434074d3 100644 --- a/src/ApiGateways/Mobile.Bff.Shopping/aggregator/Infrastructure/GrpcExceptionInterceptor.cs +++ b/src/ApiGateways/Mobile.Bff.Shopping/aggregator/Infrastructure/GrpcExceptionInterceptor.cs @@ -1,41 +1,35 @@ -using Grpc.Core; -using Grpc.Core.Interceptors; -using Microsoft.Extensions.Logging; -using System.Threading.Tasks; +namespace Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator.Infrastructure; -namespace Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator.Infrastructure +public class GrpcExceptionInterceptor : Interceptor { - public class GrpcExceptionInterceptor : Interceptor + private readonly ILogger _logger; + + public GrpcExceptionInterceptor(ILogger logger) { - private readonly ILogger _logger; + _logger = logger; + } - public GrpcExceptionInterceptor(ILogger logger) - { - _logger = logger; - } + public override AsyncUnaryCall AsyncUnaryCall( + TRequest request, + ClientInterceptorContext context, + AsyncUnaryCallContinuation continuation) + { + var call = continuation(request, context); - public override AsyncUnaryCall AsyncUnaryCall( - TRequest request, - ClientInterceptorContext context, - AsyncUnaryCallContinuation continuation) - { - var call = continuation(request, context); + return new AsyncUnaryCall(HandleResponse(call.ResponseAsync), call.ResponseHeadersAsync, call.GetStatus, call.GetTrailers, call.Dispose); + } - return new AsyncUnaryCall(HandleResponse(call.ResponseAsync), call.ResponseHeadersAsync, call.GetStatus, call.GetTrailers, call.Dispose); + private async Task HandleResponse(Task t) + { + try + { + var response = await t; + return response; } - - private async Task HandleResponse(Task t) + catch (RpcException e) { - try - { - var response = await t; - return response; - } - catch (RpcException e) - { - _logger.LogError("Error calling via grpc: {Status} - {Message}", e.Status, e.Message); - return default; - } + _logger.LogError("Error calling via grpc: {Status} - {Message}", e.Status, e.Message); + return default; } } } diff --git a/src/ApiGateways/Mobile.Bff.Shopping/aggregator/Infrastructure/HttpClientAuthorizationDelegatingHandler.cs b/src/ApiGateways/Mobile.Bff.Shopping/aggregator/Infrastructure/HttpClientAuthorizationDelegatingHandler.cs index 937a745ee..24914ca33 100644 --- a/src/ApiGateways/Mobile.Bff.Shopping/aggregator/Infrastructure/HttpClientAuthorizationDelegatingHandler.cs +++ b/src/ApiGateways/Mobile.Bff.Shopping/aggregator/Infrastructure/HttpClientAuthorizationDelegatingHandler.cs @@ -1,54 +1,44 @@ -using Microsoft.AspNetCore.Authentication; -using Microsoft.AspNetCore.Http; -using Microsoft.Extensions.Logging; -using System.Collections.Generic; -using System.Net.Http; -using System.Net.Http.Headers; -using System.Threading; -using System.Threading.Tasks; - -namespace Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator.Infrastructure -{ - public class HttpClientAuthorizationDelegatingHandler : DelegatingHandler - { - private readonly IHttpContextAccessor _httpContextAccessor; - private readonly ILogger _logger; +namespace Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator.Infrastructure; - public HttpClientAuthorizationDelegatingHandler(IHttpContextAccessor httpContextAccessor, ILogger logger) - { - _httpContextAccessor = httpContextAccessor; - _logger = logger; - } +public class HttpClientAuthorizationDelegatingHandler : DelegatingHandler +{ + private readonly IHttpContextAccessor _httpContextAccessor; + private readonly ILogger _logger; - protected override async Task SendAsync(HttpRequestMessage request, CancellationToken cancellationToken) - { - request.Version = new System.Version(2, 0); - request.Method = HttpMethod.Get; + public HttpClientAuthorizationDelegatingHandler(IHttpContextAccessor httpContextAccessor, ILogger logger) + { + _httpContextAccessor = httpContextAccessor; + _logger = logger; + } - var authorizationHeader = _httpContextAccessor.HttpContext - .Request.Headers["Authorization"]; + protected override async Task SendAsync(HttpRequestMessage request, CancellationToken cancellationToken) + { + request.Version = new System.Version(2, 0); + request.Method = HttpMethod.Get; - if (!string.IsNullOrEmpty(authorizationHeader)) - { - request.Headers.Add("Authorization", new List() { authorizationHeader }); - } + var authorizationHeader = _httpContextAccessor.HttpContext + .Request.Headers["Authorization"]; - var token = await GetToken(); + if (!string.IsNullOrEmpty(authorizationHeader)) + { + request.Headers.Add("Authorization", new List() { authorizationHeader }); + } - if (token != null) - { - request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", token); - } + var token = await GetToken(); - return await base.SendAsync(request, cancellationToken); + if (token != null) + { + request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", token); } - async Task GetToken() - { - const string ACCESS_TOKEN = "access_token"; + return await base.SendAsync(request, cancellationToken); + } - return await _httpContextAccessor.HttpContext - .GetTokenAsync(ACCESS_TOKEN); - } + async Task GetToken() + { + const string ACCESS_TOKEN = "access_token"; + + return await _httpContextAccessor.HttpContext + .GetTokenAsync(ACCESS_TOKEN); } } diff --git a/src/ApiGateways/Mobile.Bff.Shopping/aggregator/Models/AddBasketItemRequest.cs b/src/ApiGateways/Mobile.Bff.Shopping/aggregator/Models/AddBasketItemRequest.cs index d0271d84b..f7037d196 100644 --- a/src/ApiGateways/Mobile.Bff.Shopping/aggregator/Models/AddBasketItemRequest.cs +++ b/src/ApiGateways/Mobile.Bff.Shopping/aggregator/Models/AddBasketItemRequest.cs @@ -1,16 +1,15 @@ -namespace Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator.Models +namespace Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator.Models; + +public class AddBasketItemRequest { - public class AddBasketItemRequest - { - public int CatalogItemId { get; set; } + public int CatalogItemId { get; set; } - public string BasketId { get; set; } + public string BasketId { get; set; } - public int Quantity { get; set; } + public int Quantity { get; set; } - public AddBasketItemRequest() - { - Quantity = 1; - } + public AddBasketItemRequest() + { + Quantity = 1; } } diff --git a/src/ApiGateways/Mobile.Bff.Shopping/aggregator/Models/BasketData.cs b/src/ApiGateways/Mobile.Bff.Shopping/aggregator/Models/BasketData.cs index 7a43d58e5..6a57b4d70 100644 --- a/src/ApiGateways/Mobile.Bff.Shopping/aggregator/Models/BasketData.cs +++ b/src/ApiGateways/Mobile.Bff.Shopping/aggregator/Models/BasketData.cs @@ -1,22 +1,17 @@ -using System.Collections.Generic; +namespace Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator.Models; -namespace Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator.Models +public class BasketData { + public string BuyerId { get; set; } - public class BasketData - { - public string BuyerId { get; set; } - - public List Items { get; set; } = new List(); - - public BasketData() - { - } + public List Items { get; set; } = new List(); - public BasketData(string buyerId) - { - BuyerId = buyerId; - } + public BasketData() + { } + public BasketData(string buyerId) + { + BuyerId = buyerId; + } } diff --git a/src/ApiGateways/Mobile.Bff.Shopping/aggregator/Models/BasketDataItem.cs b/src/ApiGateways/Mobile.Bff.Shopping/aggregator/Models/BasketDataItem.cs index 3ff91df4f..95bda8d37 100644 --- a/src/ApiGateways/Mobile.Bff.Shopping/aggregator/Models/BasketDataItem.cs +++ b/src/ApiGateways/Mobile.Bff.Shopping/aggregator/Models/BasketDataItem.cs @@ -1,21 +1,18 @@ -namespace Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator.Models -{ - - public class BasketDataItem - { - public string Id { get; set; } +namespace Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator.Models; - public int ProductId { get; set; } +public class BasketDataItem +{ + public string Id { get; set; } - public string ProductName { get; set; } + public int ProductId { get; set; } - public decimal UnitPrice { get; set; } + public string ProductName { get; set; } - public decimal OldUnitPrice { get; set; } + public decimal UnitPrice { get; set; } - public int Quantity { get; set; } + public decimal OldUnitPrice { get; set; } - public string PictureUrl { get; set; } - } + public int Quantity { get; set; } + public string PictureUrl { get; set; } } diff --git a/src/ApiGateways/Mobile.Bff.Shopping/aggregator/Models/CatalogItem.cs b/src/ApiGateways/Mobile.Bff.Shopping/aggregator/Models/CatalogItem.cs index 603c70bd7..7b673de3b 100644 --- a/src/ApiGateways/Mobile.Bff.Shopping/aggregator/Models/CatalogItem.cs +++ b/src/ApiGateways/Mobile.Bff.Shopping/aggregator/Models/CatalogItem.cs @@ -1,13 +1,12 @@ -namespace Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator.Models +namespace Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator.Models; + +public class CatalogItem { - public class CatalogItem - { - public int Id { get; set; } + public int Id { get; set; } - public string Name { get; set; } + public string Name { get; set; } - public decimal Price { get; set; } + public decimal Price { get; set; } - public string PictureUri { get; set; } - } + public string PictureUri { get; set; } } diff --git a/src/ApiGateways/Mobile.Bff.Shopping/aggregator/Models/OrderData.cs b/src/ApiGateways/Mobile.Bff.Shopping/aggregator/Models/OrderData.cs index 3ecddcf36..c707eb408 100644 --- a/src/ApiGateways/Mobile.Bff.Shopping/aggregator/Models/OrderData.cs +++ b/src/ApiGateways/Mobile.Bff.Shopping/aggregator/Models/OrderData.cs @@ -1,48 +1,42 @@ -using System; -using System.Collections.Generic; +namespace Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator.Models; -namespace Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator.Models +public class OrderData { + public string OrderNumber { get; set; } - public class OrderData - { - public string OrderNumber { get; set; } + public DateTime Date { get; set; } - public DateTime Date { get; set; } + public string Status { get; set; } - public string Status { get; set; } + public decimal Total { get; set; } - public decimal Total { get; set; } + public string Description { get; set; } - public string Description { get; set; } + public string City { get; set; } - public string City { get; set; } + public string Street { get; set; } - public string Street { get; set; } + public string State { get; set; } - public string State { get; set; } + public string Country { get; set; } - public string Country { get; set; } + public string ZipCode { get; set; } - public string ZipCode { get; set; } + public string CardNumber { get; set; } - public string CardNumber { get; set; } + public string CardHolderName { get; set; } - public string CardHolderName { get; set; } + public bool IsDraft { get; set; } - public bool IsDraft { get; set; } + public DateTime CardExpiration { get; set; } - public DateTime CardExpiration { get; set; } + public string CardExpirationShort { get; set; } - public string CardExpirationShort { get; set; } + public string CardSecurityNumber { get; set; } - public string CardSecurityNumber { get; set; } + public int CardTypeId { get; set; } - public int CardTypeId { get; set; } - - public string Buyer { get; set; } - - public List OrderItems { get; } = new List(); - } + public string Buyer { get; set; } + public List OrderItems { get; } = new List(); } diff --git a/src/ApiGateways/Mobile.Bff.Shopping/aggregator/Models/OrderItemData.cs b/src/ApiGateways/Mobile.Bff.Shopping/aggregator/Models/OrderItemData.cs index b3832fa21..f763a6923 100644 --- a/src/ApiGateways/Mobile.Bff.Shopping/aggregator/Models/OrderItemData.cs +++ b/src/ApiGateways/Mobile.Bff.Shopping/aggregator/Models/OrderItemData.cs @@ -1,19 +1,16 @@ -namespace Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator.Models -{ - - public class OrderItemData - { - public int ProductId { get; set; } +namespace Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator.Models; - public string ProductName { get; set; } +public class OrderItemData +{ + public int ProductId { get; set; } - public decimal UnitPrice { get; set; } + public string ProductName { get; set; } - public decimal Discount { get; set; } + public decimal UnitPrice { get; set; } - public int Units { get; set; } + public decimal Discount { get; set; } - public string PictureUrl { get; set; } - } + public int Units { get; set; } + public string PictureUrl { get; set; } } diff --git a/src/ApiGateways/Mobile.Bff.Shopping/aggregator/Models/UpdateBasketItemData.cs b/src/ApiGateways/Mobile.Bff.Shopping/aggregator/Models/UpdateBasketItemData.cs index f8ec70d5f..d1476c55a 100644 --- a/src/ApiGateways/Mobile.Bff.Shopping/aggregator/Models/UpdateBasketItemData.cs +++ b/src/ApiGateways/Mobile.Bff.Shopping/aggregator/Models/UpdateBasketItemData.cs @@ -1,16 +1,13 @@ -namespace Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator.Models -{ +namespace Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator.Models; - public class UpdateBasketItemData - { - public string BasketItemId { get; set; } +public class UpdateBasketItemData +{ + public string BasketItemId { get; set; } - public int NewQty { get; set; } + public int NewQty { get; set; } - public UpdateBasketItemData() - { - NewQty = 0; - } + public UpdateBasketItemData() + { + NewQty = 0; } - } diff --git a/src/ApiGateways/Mobile.Bff.Shopping/aggregator/Models/UpdateBasketItemsRequest.cs b/src/ApiGateways/Mobile.Bff.Shopping/aggregator/Models/UpdateBasketItemsRequest.cs index 066f01a9c..d0686ef51 100644 --- a/src/ApiGateways/Mobile.Bff.Shopping/aggregator/Models/UpdateBasketItemsRequest.cs +++ b/src/ApiGateways/Mobile.Bff.Shopping/aggregator/Models/UpdateBasketItemsRequest.cs @@ -1,19 +1,14 @@ -using System.Collections.Generic; +namespace Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator.Models; -namespace Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator.Models +public class UpdateBasketItemsRequest { - public class UpdateBasketItemsRequest - { - - public string BasketId { get; set; } + public string BasketId { get; set; } - public ICollection Updates { get; set; } + public ICollection Updates { get; set; } - public UpdateBasketItemsRequest() - { - Updates = new List(); - } + public UpdateBasketItemsRequest() + { + Updates = new List(); } - } diff --git a/src/ApiGateways/Mobile.Bff.Shopping/aggregator/Models/UpdateBasketRequest.cs b/src/ApiGateways/Mobile.Bff.Shopping/aggregator/Models/UpdateBasketRequest.cs index f8fb7eb03..200f3c375 100644 --- a/src/ApiGateways/Mobile.Bff.Shopping/aggregator/Models/UpdateBasketRequest.cs +++ b/src/ApiGateways/Mobile.Bff.Shopping/aggregator/Models/UpdateBasketRequest.cs @@ -1,13 +1,8 @@ -using System.Collections.Generic; +namespace Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator.Models; -namespace Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator.Models +public class UpdateBasketRequest { + public string BuyerId { get; set; } - public class UpdateBasketRequest - { - public string BuyerId { get; set; } - - public IEnumerable Items { get; set; } - } - -} + public IEnumerable Items { get; set; } +} \ No newline at end of file diff --git a/src/ApiGateways/Mobile.Bff.Shopping/aggregator/Models/UpdateBasketRequestItemData.cs b/src/ApiGateways/Mobile.Bff.Shopping/aggregator/Models/UpdateBasketRequestItemData.cs index af28e0157..48ed593a1 100644 --- a/src/ApiGateways/Mobile.Bff.Shopping/aggregator/Models/UpdateBasketRequestItemData.cs +++ b/src/ApiGateways/Mobile.Bff.Shopping/aggregator/Models/UpdateBasketRequestItemData.cs @@ -1,13 +1,10 @@ -namespace Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator.Models -{ - - public class UpdateBasketRequestItemData - { - public string Id { get; set; } // Basket id +namespace Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator.Models; - public int ProductId { get; set; } // Catalog item id +public class UpdateBasketRequestItemData +{ + public string Id { get; set; } // Basket id - public int Quantity { get; set; } // Quantity - } + public int ProductId { get; set; } // Catalog item id + public int Quantity { get; set; } // Quantity } diff --git a/src/ApiGateways/Mobile.Bff.Shopping/aggregator/Program.cs b/src/ApiGateways/Mobile.Bff.Shopping/aggregator/Program.cs index 3e80a543f..290fc9545 100644 --- a/src/ApiGateways/Mobile.Bff.Shopping/aggregator/Program.cs +++ b/src/ApiGateways/Mobile.Bff.Shopping/aggregator/Program.cs @@ -1,10 +1,4 @@ -using Microsoft.AspNetCore; -using Microsoft.AspNetCore.Hosting; -using Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator; -using Serilog; - - -BuildWebHost(args).Run(); +BuildWebHost(args).Run(); IWebHost BuildWebHost(string[] args) => WebHost .CreateDefaultBuilder(args) diff --git a/src/ApiGateways/Mobile.Bff.Shopping/aggregator/Services/BasketService.cs b/src/ApiGateways/Mobile.Bff.Shopping/aggregator/Services/BasketService.cs index d6217175b..1b081bf85 100644 --- a/src/ApiGateways/Mobile.Bff.Shopping/aggregator/Services/BasketService.cs +++ b/src/ApiGateways/Mobile.Bff.Shopping/aggregator/Services/BasketService.cs @@ -1,90 +1,83 @@ -using GrpcBasket; -using Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator.Models; -using Microsoft.Extensions.Logging; -using System.Linq; -using System.Threading.Tasks; +namespace Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator.Services; -namespace Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator.Services +public class BasketService : IBasketService { - public class BasketService : IBasketService + private readonly Basket.BasketClient _basketClient; + private readonly ILogger _logger; + + public BasketService(Basket.BasketClient basketClient, ILogger logger) { - private readonly Basket.BasketClient _basketClient; - private readonly ILogger _logger; + _basketClient = basketClient; + _logger = logger; + } - public BasketService(Basket.BasketClient basketClient, ILogger logger) - { - _basketClient = basketClient; - _logger = logger; - } + public async Task GetById(string id) + { + _logger.LogDebug("grpc client created, request = {@id}", id); + var response = await _basketClient.GetBasketByIdAsync(new BasketRequest { Id = id }); + _logger.LogDebug("grpc response {@response}", response); - public async Task GetById(string id) - { - _logger.LogDebug("grpc client created, request = {@id}", id); - var response = await _basketClient.GetBasketByIdAsync(new BasketRequest { Id = id }); - _logger.LogDebug("grpc response {@response}", response); + return MapToBasketData(response); + } - return MapToBasketData(response); - } + public async Task UpdateAsync(BasketData currentBasket) + { + _logger.LogDebug("Grpc update basket currentBasket {@currentBasket}", currentBasket); + var request = MapToCustomerBasketRequest(currentBasket); + _logger.LogDebug("Grpc update basket request {@request}", request); - public async Task UpdateAsync(BasketData currentBasket) - { - _logger.LogDebug("Grpc update basket currentBasket {@currentBasket}", currentBasket); - var request = MapToCustomerBasketRequest(currentBasket); - _logger.LogDebug("Grpc update basket request {@request}", request); + await _basketClient.UpdateBasketAsync(request); + } - await _basketClient.UpdateBasketAsync(request); + private BasketData MapToBasketData(CustomerBasketResponse customerBasketRequest) + { + if (customerBasketRequest == null) + { + return null; } - private BasketData MapToBasketData(CustomerBasketResponse customerBasketRequest) + var map = new BasketData { - if (customerBasketRequest == null) - { - return null; - } + BuyerId = customerBasketRequest.Buyerid + }; - var map = new BasketData - { - BuyerId = customerBasketRequest.Buyerid - }; + customerBasketRequest.Items.ToList().ForEach(item => map.Items.Add(new BasketDataItem + { + Id = item.Id, + OldUnitPrice = (decimal)item.Oldunitprice, + PictureUrl = item.Pictureurl, + ProductId = item.Productid, + ProductName = item.Productname, + Quantity = item.Quantity, + UnitPrice = (decimal)item.Unitprice + })); - customerBasketRequest.Items.ToList().ForEach(item => map.Items.Add(new BasketDataItem - { - Id = item.Id, - OldUnitPrice = (decimal)item.Oldunitprice, - PictureUrl = item.Pictureurl, - ProductId = item.Productid, - ProductName = item.Productname, - Quantity = item.Quantity, - UnitPrice = (decimal)item.Unitprice - })); + return map; + } - return map; + private CustomerBasketRequest MapToCustomerBasketRequest(BasketData basketData) + { + if (basketData == null) + { + return null; } - private CustomerBasketRequest MapToCustomerBasketRequest(BasketData basketData) + var map = new CustomerBasketRequest { - if (basketData == null) - { - return null; - } - - var map = new CustomerBasketRequest - { - Buyerid = basketData.BuyerId - }; + Buyerid = basketData.BuyerId + }; - basketData.Items.ToList().ForEach(item => map.Items.Add(new BasketItemResponse - { - Id = item.Id, - Oldunitprice = (double)item.OldUnitPrice, - Pictureurl = item.PictureUrl, - Productid = item.ProductId, - Productname = item.ProductName, - Quantity = item.Quantity, - Unitprice = (double)item.UnitPrice - })); + basketData.Items.ToList().ForEach(item => map.Items.Add(new BasketItemResponse + { + Id = item.Id, + Oldunitprice = (double)item.OldUnitPrice, + Pictureurl = item.PictureUrl, + Productid = item.ProductId, + Productname = item.ProductName, + Quantity = item.Quantity, + Unitprice = (double)item.UnitPrice + })); - return map; - } + return map; } } diff --git a/src/ApiGateways/Mobile.Bff.Shopping/aggregator/Services/CatalogService.cs b/src/ApiGateways/Mobile.Bff.Shopping/aggregator/Services/CatalogService.cs index 0101a7058..9fe1bdd5b 100644 --- a/src/ApiGateways/Mobile.Bff.Shopping/aggregator/Services/CatalogService.cs +++ b/src/ApiGateways/Mobile.Bff.Shopping/aggregator/Services/CatalogService.cs @@ -1,43 +1,36 @@ -using CatalogApi; -using Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator.Models; -using System.Collections.Generic; -using System.Linq; -using System.Threading.Tasks; +namespace Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator.Services; -namespace Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator.Services +public class CatalogService : ICatalogService { - public class CatalogService : ICatalogService - { - private readonly Catalog.CatalogClient _client; + private readonly Catalog.CatalogClient _client; - public CatalogService(Catalog.CatalogClient client) - { - _client = client; - } + public CatalogService(Catalog.CatalogClient client) + { + _client = client; + } - public async Task GetCatalogItemAsync(int id) - { - var request = new CatalogItemRequest { Id = id }; - var response = await _client.GetItemByIdAsync(request); - return MapToCatalogItemResponse(response); - } + public async Task GetCatalogItemAsync(int id) + { + var request = new CatalogItemRequest { Id = id }; + var response = await _client.GetItemByIdAsync(request); + return MapToCatalogItemResponse(response); + } - public async Task> GetCatalogItemsAsync(IEnumerable ids) - { - var request = new CatalogItemsRequest { Ids = string.Join(",", ids), PageIndex = 1, PageSize = 10 }; - var response = await _client.GetItemsByIdsAsync(request); - return response.Data.Select(MapToCatalogItemResponse); - } + public async Task> GetCatalogItemsAsync(IEnumerable ids) + { + var request = new CatalogItemsRequest { Ids = string.Join(",", ids), PageIndex = 1, PageSize = 10 }; + var response = await _client.GetItemsByIdsAsync(request); + return response.Data.Select(MapToCatalogItemResponse); + } - private CatalogItem MapToCatalogItemResponse(CatalogItemResponse catalogItemResponse) + private CatalogItem MapToCatalogItemResponse(CatalogItemResponse catalogItemResponse) + { + return new CatalogItem { - return new CatalogItem - { - Id = catalogItemResponse.Id, - Name = catalogItemResponse.Name, - PictureUri = catalogItemResponse.PictureUri, - Price = (decimal)catalogItemResponse.Price - }; - } + Id = catalogItemResponse.Id, + Name = catalogItemResponse.Name, + PictureUri = catalogItemResponse.PictureUri, + Price = (decimal)catalogItemResponse.Price + }; } } diff --git a/src/ApiGateways/Mobile.Bff.Shopping/aggregator/Services/IBasketService.cs b/src/ApiGateways/Mobile.Bff.Shopping/aggregator/Services/IBasketService.cs index d7a390c75..518daffcf 100644 --- a/src/ApiGateways/Mobile.Bff.Shopping/aggregator/Services/IBasketService.cs +++ b/src/ApiGateways/Mobile.Bff.Shopping/aggregator/Services/IBasketService.cs @@ -1,13 +1,9 @@ -using Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator.Models; -using System.Threading.Tasks; +namespace Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator.Services; -namespace Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator.Services +public interface IBasketService { - public interface IBasketService - { - Task GetById(string id); + Task GetById(string id); - Task UpdateAsync(BasketData currentBasket); + Task UpdateAsync(BasketData currentBasket); - } } diff --git a/src/ApiGateways/Mobile.Bff.Shopping/aggregator/Services/ICatalogService.cs b/src/ApiGateways/Mobile.Bff.Shopping/aggregator/Services/ICatalogService.cs index 832dfc740..83c95706e 100644 --- a/src/ApiGateways/Mobile.Bff.Shopping/aggregator/Services/ICatalogService.cs +++ b/src/ApiGateways/Mobile.Bff.Shopping/aggregator/Services/ICatalogService.cs @@ -1,13 +1,8 @@ -using Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator.Models; -using System.Collections.Generic; -using System.Threading.Tasks; +namespace Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator.Services; -namespace Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator.Services +public interface ICatalogService { - public interface ICatalogService - { - Task GetCatalogItemAsync(int id); + Task GetCatalogItemAsync(int id); - Task> GetCatalogItemsAsync(IEnumerable ids); - } + Task> GetCatalogItemsAsync(IEnumerable ids); } diff --git a/src/ApiGateways/Mobile.Bff.Shopping/aggregator/Services/IOrderApiClient.cs b/src/ApiGateways/Mobile.Bff.Shopping/aggregator/Services/IOrderApiClient.cs index 1abe545bd..5cda86223 100644 --- a/src/ApiGateways/Mobile.Bff.Shopping/aggregator/Services/IOrderApiClient.cs +++ b/src/ApiGateways/Mobile.Bff.Shopping/aggregator/Services/IOrderApiClient.cs @@ -1,10 +1,6 @@ -using Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator.Models; -using System.Threading.Tasks; +namespace Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator.Services; -namespace Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator.Services +public interface IOrderApiClient { - public interface IOrderApiClient - { - Task GetOrderDraftFromBasketAsync(BasketData basket); - } + Task GetOrderDraftFromBasketAsync(BasketData basket); } diff --git a/src/ApiGateways/Mobile.Bff.Shopping/aggregator/Services/IOrderingService.cs b/src/ApiGateways/Mobile.Bff.Shopping/aggregator/Services/IOrderingService.cs index 5518a4bbf..fd492f698 100644 --- a/src/ApiGateways/Mobile.Bff.Shopping/aggregator/Services/IOrderingService.cs +++ b/src/ApiGateways/Mobile.Bff.Shopping/aggregator/Services/IOrderingService.cs @@ -1,10 +1,6 @@ -using Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator.Models; -using System.Threading.Tasks; +namespace Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator.Services; -namespace Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator.Services +public interface IOrderingService { - public interface IOrderingService - { - Task GetOrderDraftAsync(BasketData basketData); - } -} \ No newline at end of file + Task GetOrderDraftAsync(BasketData basketData); +} diff --git a/src/ApiGateways/Mobile.Bff.Shopping/aggregator/Services/OrderApiClient.cs b/src/ApiGateways/Mobile.Bff.Shopping/aggregator/Services/OrderApiClient.cs index 8c0b7c90e..6a8465df6 100644 --- a/src/ApiGateways/Mobile.Bff.Shopping/aggregator/Services/OrderApiClient.cs +++ b/src/ApiGateways/Mobile.Bff.Shopping/aggregator/Services/OrderApiClient.cs @@ -1,40 +1,31 @@ -using Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator.Config; -using Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator.Models; -using Microsoft.Extensions.Logging; -using Microsoft.Extensions.Options; -using System.Net.Http; -using System.Threading.Tasks; -using System.Text.Json; +namespace Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator.Services; -namespace Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator.Services +public class OrderApiClient : IOrderApiClient { - public class OrderApiClient : IOrderApiClient - { - private readonly HttpClient _apiClient; - private readonly ILogger _logger; - private readonly UrlsConfig _urls; + private readonly HttpClient _apiClient; + private readonly ILogger _logger; + private readonly UrlsConfig _urls; - public OrderApiClient(HttpClient httpClient, ILogger logger, IOptions config) - { - _apiClient = httpClient; - _logger = logger; - _urls = config.Value; - } + public OrderApiClient(HttpClient httpClient, ILogger logger, IOptions config) + { + _apiClient = httpClient; + _logger = logger; + _urls = config.Value; + } - public async Task GetOrderDraftFromBasketAsync(BasketData basket) - { - var uri = _urls.Orders + UrlsConfig.OrdersOperations.GetOrderDraft(); - var content = new StringContent(JsonSerializer.Serialize(basket), System.Text.Encoding.UTF8, "application/json"); - var response = await _apiClient.PostAsync(uri, content); + public async Task GetOrderDraftFromBasketAsync(BasketData basket) + { + var uri = _urls.Orders + UrlsConfig.OrdersOperations.GetOrderDraft(); + var content = new StringContent(JsonSerializer.Serialize(basket), System.Text.Encoding.UTF8, "application/json"); + var response = await _apiClient.PostAsync(uri, content); - response.EnsureSuccessStatusCode(); + response.EnsureSuccessStatusCode(); - var ordersDraftResponse = await response.Content.ReadAsStringAsync(); + var ordersDraftResponse = await response.Content.ReadAsStringAsync(); - return JsonSerializer.Deserialize(ordersDraftResponse, new JsonSerializerOptions - { - PropertyNameCaseInsensitive = true - }); - } + return JsonSerializer.Deserialize(ordersDraftResponse, new JsonSerializerOptions + { + PropertyNameCaseInsensitive = true + }); } } diff --git a/src/ApiGateways/Mobile.Bff.Shopping/aggregator/Services/OrderingService.cs b/src/ApiGateways/Mobile.Bff.Shopping/aggregator/Services/OrderingService.cs index 7f9d5deb7..2a7de50a7 100644 --- a/src/ApiGateways/Mobile.Bff.Shopping/aggregator/Services/OrderingService.cs +++ b/src/ApiGateways/Mobile.Bff.Shopping/aggregator/Services/OrderingService.cs @@ -1,79 +1,72 @@ -using GrpcOrdering; -using Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator.Models; -using Microsoft.Extensions.Logging; -using System.Linq; -using System.Threading.Tasks; +namespace Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator.Services; -namespace Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator.Services +public class OrderingService : IOrderingService { - public class OrderingService : IOrderingService + private readonly OrderingGrpc.OrderingGrpcClient _orderingGrpcClient; + private readonly ILogger _logger; + + public OrderingService(OrderingGrpc.OrderingGrpcClient orderingGrpcClient, ILogger logger) { - private readonly OrderingGrpc.OrderingGrpcClient _orderingGrpcClient; - private readonly ILogger _logger; + _orderingGrpcClient = orderingGrpcClient; + _logger = logger; + } - public OrderingService(OrderingGrpc.OrderingGrpcClient orderingGrpcClient, ILogger logger) - { - _orderingGrpcClient = orderingGrpcClient; - _logger = logger; - } + public async Task GetOrderDraftAsync(BasketData basketData) + { + _logger.LogDebug(" grpc client created, basketData={@basketData}", basketData); - public async Task GetOrderDraftAsync(BasketData basketData) - { - _logger.LogDebug(" grpc client created, basketData={@basketData}", basketData); + var command = MapToOrderDraftCommand(basketData); + var response = await _orderingGrpcClient.CreateOrderDraftFromBasketDataAsync(command); + _logger.LogDebug(" grpc response: {@response}", response); - var command = MapToOrderDraftCommand(basketData); - var response = await _orderingGrpcClient.CreateOrderDraftFromBasketDataAsync(command); - _logger.LogDebug(" grpc response: {@response}", response); + return MapToResponse(response, basketData); + } - return MapToResponse(response, basketData); + private OrderData MapToResponse(GrpcOrdering.OrderDraftDTO orderDraft, BasketData basketData) + { + if (orderDraft == null) + { + return null; } - private OrderData MapToResponse(GrpcOrdering.OrderDraftDTO orderDraft, BasketData basketData) + var data = new OrderData { - if (orderDraft == null) - { - return null; - } + Buyer = basketData.BuyerId, + Total = (decimal)orderDraft.Total, + }; - var data = new OrderData - { - Buyer = basketData.BuyerId, - Total = (decimal)orderDraft.Total, - }; - - orderDraft.OrderItems.ToList().ForEach(o => data.OrderItems.Add(new OrderItemData - { - Discount = (decimal)o.Discount, - PictureUrl = o.PictureUrl, - ProductId = o.ProductId, - ProductName = o.ProductName, - UnitPrice = (decimal)o.UnitPrice, - Units = o.Units, - })); + orderDraft.OrderItems.ToList().ForEach(o => data.OrderItems.Add(new OrderItemData + { + Discount = (decimal)o.Discount, + PictureUrl = o.PictureUrl, + ProductId = o.ProductId, + ProductName = o.ProductName, + UnitPrice = (decimal)o.UnitPrice, + Units = o.Units, + })); - return data; - } + return data; + } - private CreateOrderDraftCommand MapToOrderDraftCommand(BasketData basketData) + private CreateOrderDraftCommand MapToOrderDraftCommand(BasketData basketData) + { + var command = new CreateOrderDraftCommand { - var command = new CreateOrderDraftCommand - { - BuyerId = basketData.BuyerId, - }; + BuyerId = basketData.BuyerId, + }; - basketData.Items.ForEach(i => command.Items.Add(new BasketItem - { - Id = i.Id, - OldUnitPrice = (double)i.OldUnitPrice, - PictureUrl = i.PictureUrl, - ProductId = i.ProductId, - ProductName = i.ProductName, - Quantity = i.Quantity, - UnitPrice = (double)i.UnitPrice, - })); - - return command; - } + basketData.Items.ForEach(i => command.Items.Add(new BasketItem + { + Id = i.Id, + OldUnitPrice = (double)i.OldUnitPrice, + PictureUrl = i.PictureUrl, + ProductId = i.ProductId, + ProductName = i.ProductName, + Quantity = i.Quantity, + UnitPrice = (double)i.UnitPrice, + })); + return command; } + } diff --git a/src/ApiGateways/Mobile.Bff.Shopping/aggregator/Startup.cs b/src/ApiGateways/Mobile.Bff.Shopping/aggregator/Startup.cs index b8853aee7..3f988395a 100644 --- a/src/ApiGateways/Mobile.Bff.Shopping/aggregator/Startup.cs +++ b/src/ApiGateways/Mobile.Bff.Shopping/aggregator/Startup.cs @@ -1,222 +1,196 @@ -using CatalogApi; -using Devspaces.Support; -using GrpcBasket; -using GrpcOrdering; -using HealthChecks.UI.Client; -using Microsoft.AspNetCore.Authentication.JwtBearer; -using Microsoft.AspNetCore.Builder; -using Microsoft.AspNetCore.Diagnostics.HealthChecks; -using Microsoft.AspNetCore.Hosting; -using Microsoft.AspNetCore.Http; -using Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator.Config; -using Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator.Filters.Basket.API.Infrastructure.Filters; -using Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator.Infrastructure; -using Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator.Services; -using Microsoft.Extensions.Configuration; -using Microsoft.Extensions.DependencyInjection; -using Microsoft.Extensions.Diagnostics.HealthChecks; -using Microsoft.Extensions.Hosting; -using Microsoft.Extensions.Logging; -using Microsoft.Extensions.Options; -using Microsoft.OpenApi.Models; -using System; -using System.Collections.Generic; -using System.IdentityModel.Tokens.Jwt; - -namespace Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator +namespace Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator; + +public class Startup { - public class Startup + public Startup(IConfiguration configuration) { - public Startup(IConfiguration configuration) - { - Configuration = configuration; - } + Configuration = configuration; + } - public IConfiguration Configuration { get; } + public IConfiguration Configuration { get; } - // This method gets called by the runtime. Use this method to add services to the container. - public void ConfigureServices(IServiceCollection services) + // This method gets called by the runtime. Use this method to add services to the container. + public void ConfigureServices(IServiceCollection services) + { + services.AddHealthChecks() + .AddCheck("self", () => HealthCheckResult.Healthy()) + .AddUrlGroup(new Uri(Configuration["CatalogUrlHC"]), name: "catalogapi-check", tags: new string[] { "catalogapi" }) + .AddUrlGroup(new Uri(Configuration["OrderingUrlHC"]), name: "orderingapi-check", tags: new string[] { "orderingapi" }) + .AddUrlGroup(new Uri(Configuration["BasketUrlHC"]), name: "basketapi-check", tags: new string[] { "basketapi" }) + .AddUrlGroup(new Uri(Configuration["IdentityUrlHC"]), name: "identityapi-check", tags: new string[] { "identityapi" }) + .AddUrlGroup(new Uri(Configuration["PaymentUrlHC"]), name: "paymentapi-check", tags: new string[] { "paymentapi" }); + + services.AddCustomMvc(Configuration) + .AddCustomAuthentication(Configuration) + .AddDevspaces() + .AddHttpServices() + .AddGrpcServices(); + } + + // This method gets called by the runtime. Use this method to configure the HTTP request pipeline. + public void Configure(IApplicationBuilder app, IWebHostEnvironment env, ILoggerFactory loggerFactory) + { + var pathBase = Configuration["PATH_BASE"]; + + if (!string.IsNullOrEmpty(pathBase)) { - services.AddHealthChecks() - .AddCheck("self", () => HealthCheckResult.Healthy()) - .AddUrlGroup(new Uri(Configuration["CatalogUrlHC"]), name: "catalogapi-check", tags: new string[] { "catalogapi" }) - .AddUrlGroup(new Uri(Configuration["OrderingUrlHC"]), name: "orderingapi-check", tags: new string[] { "orderingapi" }) - .AddUrlGroup(new Uri(Configuration["BasketUrlHC"]), name: "basketapi-check", tags: new string[] { "basketapi" }) - .AddUrlGroup(new Uri(Configuration["IdentityUrlHC"]), name: "identityapi-check", tags: new string[] { "identityapi" }) - .AddUrlGroup(new Uri(Configuration["PaymentUrlHC"]), name: "paymentapi-check", tags: new string[] { "paymentapi" }); - - services.AddCustomMvc(Configuration) - .AddCustomAuthentication(Configuration) - .AddDevspaces() - .AddHttpServices() - .AddGrpcServices(); + loggerFactory.CreateLogger().LogDebug("Using PATH BASE '{pathBase}'", pathBase); + app.UsePathBase(pathBase); } - // This method gets called by the runtime. Use this method to configure the HTTP request pipeline. - public void Configure(IApplicationBuilder app, IWebHostEnvironment env, ILoggerFactory loggerFactory) + if (env.IsDevelopment()) { - var pathBase = Configuration["PATH_BASE"]; - - if (!string.IsNullOrEmpty(pathBase)) - { - loggerFactory.CreateLogger().LogDebug("Using PATH BASE '{pathBase}'", pathBase); - app.UsePathBase(pathBase); - } - - if (env.IsDevelopment()) - { - app.UseDeveloperExceptionPage(); - } + app.UseDeveloperExceptionPage(); + } - app.UseSwagger().UseSwaggerUI(c => + app.UseSwagger().UseSwaggerUI(c => + { + c.SwaggerEndpoint($"{ (!string.IsNullOrEmpty(pathBase) ? pathBase : string.Empty) }/swagger/v1/swagger.json", "Purchase BFF V1"); + + c.OAuthClientId("mobileshoppingaggswaggerui"); + c.OAuthClientSecret(string.Empty); + c.OAuthRealm(string.Empty); + c.OAuthAppName("Purchase BFF Swagger UI"); + }); + + app.UseRouting(); + app.UseCors("CorsPolicy"); + app.UseAuthentication(); + app.UseAuthorization(); + app.UseEndpoints(endpoints => + { + endpoints.MapDefaultControllerRoute(); + endpoints.MapControllers(); + endpoints.MapHealthChecks("/hc", new HealthCheckOptions() { - c.SwaggerEndpoint($"{ (!string.IsNullOrEmpty(pathBase) ? pathBase : string.Empty) }/swagger/v1/swagger.json", "Purchase BFF V1"); - - c.OAuthClientId("mobileshoppingaggswaggerui"); - c.OAuthClientSecret(string.Empty); - c.OAuthRealm(string.Empty); - c.OAuthAppName("Purchase BFF Swagger UI"); + Predicate = _ => true, + ResponseWriter = UIResponseWriter.WriteHealthCheckUIResponse }); - - app.UseRouting(); - app.UseCors("CorsPolicy"); - app.UseAuthentication(); - app.UseAuthorization(); - app.UseEndpoints(endpoints => + endpoints.MapHealthChecks("/liveness", new HealthCheckOptions { - endpoints.MapDefaultControllerRoute(); - endpoints.MapControllers(); - endpoints.MapHealthChecks("/hc", new HealthCheckOptions() - { - Predicate = _ => true, - ResponseWriter = UIResponseWriter.WriteHealthCheckUIResponse - }); - endpoints.MapHealthChecks("/liveness", new HealthCheckOptions - { - Predicate = r => r.Name.Contains("self") - }); + Predicate = r => r.Name.Contains("self") }); - } + }); } +} - public static class ServiceCollectionExtensions +public static class ServiceCollectionExtensions +{ + public static IServiceCollection AddCustomMvc(this IServiceCollection services, IConfiguration configuration) { - public static IServiceCollection AddCustomMvc(this IServiceCollection services, IConfiguration configuration) - { - services.AddOptions(); - services.Configure(configuration.GetSection("urls")); + services.AddOptions(); + services.Configure(configuration.GetSection("urls")); - services.AddControllers() - .AddJsonOptions(options => options.JsonSerializerOptions.WriteIndented = true); + services.AddControllers() + .AddJsonOptions(options => options.JsonSerializerOptions.WriteIndented = true); - services.AddSwaggerGen(options => + services.AddSwaggerGen(options => + { + options.DescribeAllEnumsAsStrings(); + options.SwaggerDoc("v1", new OpenApiInfo { - options.DescribeAllEnumsAsStrings(); - options.SwaggerDoc("v1", new OpenApiInfo - { - Title = "Shopping Aggregator for Mobile Clients", - Version = "v1", - Description = "Shopping Aggregator for Mobile Clients" - }); - options.AddSecurityDefinition("oauth2", new OpenApiSecurityScheme + Title = "Shopping Aggregator for Mobile Clients", + Version = "v1", + Description = "Shopping Aggregator for Mobile Clients" + }); + options.AddSecurityDefinition("oauth2", new OpenApiSecurityScheme + { + Type = SecuritySchemeType.OAuth2, + Flows = new OpenApiOAuthFlows() { - Type = SecuritySchemeType.OAuth2, - Flows = new OpenApiOAuthFlows() + Implicit = new OpenApiOAuthFlow() { - Implicit = new OpenApiOAuthFlow() - { - AuthorizationUrl = new Uri($"{configuration.GetValue("IdentityUrlExternal")}/connect/authorize"), - TokenUrl = new Uri($"{configuration.GetValue("IdentityUrlExternal")}/connect/token"), + AuthorizationUrl = new Uri($"{configuration.GetValue("IdentityUrlExternal")}/connect/authorize"), + TokenUrl = new Uri($"{configuration.GetValue("IdentityUrlExternal")}/connect/token"), - Scopes = new Dictionary() - { - { "mobileshoppingagg", "Shopping Aggregator for Mobile Clients" } - } + Scopes = new Dictionary() + { + { "mobileshoppingagg", "Shopping Aggregator for Mobile Clients" } } } - }); - - options.OperationFilter(); + } }); - services.AddCors(options => - { - options.AddPolicy("CorsPolicy", - builder => builder - .AllowAnyMethod() - .AllowAnyHeader() - .SetIsOriginAllowed((host) => true) - .AllowCredentials()); - }); + options.OperationFilter(); + }); - return services; - } - public static IServiceCollection AddCustomAuthentication(this IServiceCollection services, IConfiguration configuration) + services.AddCors(options => { - JwtSecurityTokenHandler.DefaultInboundClaimTypeMap.Remove("sub"); - - var identityUrl = configuration.GetValue("urls:identity"); - - services.AddAuthentication(options => - { - options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme; - options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme; + options.AddPolicy("CorsPolicy", + builder => builder + .AllowAnyMethod() + .AllowAnyHeader() + .SetIsOriginAllowed((host) => true) + .AllowCredentials()); + }); + + return services; + } + public static IServiceCollection AddCustomAuthentication(this IServiceCollection services, IConfiguration configuration) + { + JwtSecurityTokenHandler.DefaultInboundClaimTypeMap.Remove("sub"); - }) - .AddJwtBearer(options => - { - options.Authority = identityUrl; - options.RequireHttpsMetadata = false; - options.Audience = "mobileshoppingagg"; - }); + var identityUrl = configuration.GetValue("urls:identity"); - return services; - } + services.AddAuthentication(options => + { + options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme; + options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme; - public static IServiceCollection AddHttpServices(this IServiceCollection services) + }) + .AddJwtBearer(options => { - //register delegating handlers - services.AddTransient(); - services.AddSingleton(); + options.Authority = identityUrl; + options.RequireHttpsMetadata = false; + options.Audience = "mobileshoppingagg"; + }); - //register http services + return services; + } - services.AddHttpClient() - .AddDevspacesSupport(); + public static IServiceCollection AddHttpServices(this IServiceCollection services) + { + //register delegating handlers + services.AddTransient(); + services.AddSingleton(); - return services; - } + //register http services - public static IServiceCollection AddGrpcServices(this IServiceCollection services) - { - services.AddTransient(); + services.AddHttpClient() + .AddDevspacesSupport(); - services.AddScoped(); + return services; + } - services.AddGrpcClient((services, options) => - { - var basketApi = services.GetRequiredService>().Value.GrpcBasket; - options.Address = new Uri(basketApi); - }).AddInterceptor(); + public static IServiceCollection AddGrpcServices(this IServiceCollection services) + { + services.AddTransient(); - services.AddScoped(); + services.AddScoped(); - services.AddGrpcClient((services, options) => - { - var catalogApi = services.GetRequiredService>().Value.GrpcCatalog; - options.Address = new Uri(catalogApi); - }).AddInterceptor(); + services.AddGrpcClient((services, options) => + { + var basketApi = services.GetRequiredService>().Value.GrpcBasket; + options.Address = new Uri(basketApi); + }).AddInterceptor(); - services.AddScoped(); + services.AddScoped(); - services.AddGrpcClient((services, options) => - { - var orderingApi = services.GetRequiredService>().Value.GrpcOrdering; - options.Address = new Uri(orderingApi); - }).AddInterceptor(); + services.AddGrpcClient((services, options) => + { + var catalogApi = services.GetRequiredService>().Value.GrpcCatalog; + options.Address = new Uri(catalogApi); + }).AddInterceptor(); - return services; - } + services.AddScoped(); + services.AddGrpcClient((services, options) => + { + var orderingApi = services.GetRequiredService>().Value.GrpcOrdering; + options.Address = new Uri(orderingApi); + }).AddInterceptor(); + + return services; } + }