From b8969e674662a2e5c9f233fb6e8438f7aeab5dab Mon Sep 17 00:00:00 2001 From: Erik Pique Date: Thu, 15 Nov 2018 12:50:37 +0100 Subject: [PATCH] standar names and fixed response for swagger apis --- src/ApiGateways/ApiGw-Base/Startup.cs | 2 +- .../Controllers/BasketController.cs | 34 +++++---- .../aggregator/Controllers/OrderController.cs | 13 ++-- .../aggregator/Services/BasketService.cs | 4 +- .../aggregator/Services/CatalogService.cs | 4 +- .../aggregator/Services/IBasketService.cs | 8 +-- .../aggregator/Services/ICatalogService.cs | 7 +- .../aggregator/Services/IOrderApiClient.cs | 5 +- .../aggregator/Services/OrderApiClient.cs | 2 +- .../Mobile.Bff.Shopping/aggregator/Startup.cs | 8 +-- .../Controllers/BasketController.cs | 32 +++++---- .../aggregator/Controllers/OrderController.cs | 10 ++- .../aggregator/Services/BasketService.cs | 8 +-- .../aggregator/Services/CatalogService.cs | 11 ++- .../aggregator/Services/IBasketService.cs | 7 +- .../aggregator/Services/ICatalogService.cs | 7 +- .../aggregator/Services/IOrderApiClient.cs | 5 +- .../aggregator/Services/OrderApiClient.cs | 3 +- .../Web.Bff.Shopping/aggregator/Startup.cs | 15 ++-- .../Controllers/BasketController.cs | 33 ++++----- .../Basket.API/Model/RedisBasketRepository.cs | 4 +- .../Application/BasketWebApiTest.cs | 8 +-- .../Controllers/CatalogController.cs | 71 +++++++++++-------- .../Catalog.API/Controllers/PicController.cs | 2 +- .../Controllers/LocationsController.cs | 27 +++---- .../Services/ILocationsService.cs | 8 +-- .../Services/LocationsService.cs | 8 +-- .../Controllers/CampaignsController.cs | 23 +++--- .../Controllers/LocationsController.cs | 6 +- .../Controllers/OrdersController.cs | 42 ++++++----- .../Application/OrdersWebApiTest.cs | 14 ++-- 31 files changed, 224 insertions(+), 207 deletions(-) diff --git a/src/ApiGateways/ApiGw-Base/Startup.cs b/src/ApiGateways/ApiGw-Base/Startup.cs index f6a36b59e..049482dde 100644 --- a/src/ApiGateways/ApiGw-Base/Startup.cs +++ b/src/ApiGateways/ApiGw-Base/Startup.cs @@ -16,7 +16,6 @@ namespace OcelotApiGw { public class Startup { - private readonly IConfiguration _cfg; public Startup(IConfiguration configuration) @@ -71,6 +70,7 @@ namespace OcelotApiGw public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory) { var pathBase = _cfg["PATH_BASE"]; + if (!string.IsNullOrEmpty(pathBase)) { app.UsePathBase(pathBase); diff --git a/src/ApiGateways/Mobile.Bff.Shopping/aggregator/Controllers/BasketController.cs b/src/ApiGateways/Mobile.Bff.Shopping/aggregator/Controllers/BasketController.cs index 95412b066..978b1858c 100644 --- a/src/ApiGateways/Mobile.Bff.Shopping/aggregator/Controllers/BasketController.cs +++ b/src/ApiGateways/Mobile.Bff.Shopping/aggregator/Controllers/BasketController.cs @@ -5,6 +5,7 @@ using Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator.Services; using System; using System.Collections.Generic; using System.Linq; +using System.Net; using System.Threading.Tasks; namespace Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator.Controllers @@ -16,6 +17,7 @@ namespace Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator.Controllers { private readonly ICatalogService _catalog; private readonly IBasketService _basket; + public BasketController(ICatalogService catalogService, IBasketService basketService) { _catalog = catalogService; @@ -24,22 +26,24 @@ namespace Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator.Controllers [HttpPost] [HttpPut] - public async Task> UpdateAllBasket([FromBody] UpdateBasketRequest data) + [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 currentBasket = await _basket.GetById(data.BuyerId); + var currentBasket = await _basket.GetByIdAsync(data.BuyerId); + if (currentBasket == null) { currentBasket = new BasketData(data.BuyerId); } - var catalogItems = await _catalog.GetCatalogItems(data.Items.Select(x => x.ProductId)); + var catalogItems = await _catalog.GetCatalogItemsAsync(data.Items.Select(x => x.ProductId)); var newBasket = new BasketData(data.BuyerId); foreach (var bitem in data.Items) @@ -61,14 +65,16 @@ namespace Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator.Controllers }); } - await _basket.Update(newBasket); + await _basket.UpdateAsync(newBasket); return newBasket; } [HttpPut] [Route("items")] - public async Task> UpdateQuantities([FromBody] UpdateBasketItemsRequest data) + [ProducesResponseType((int)HttpStatusCode.BadRequest)] + [ProducesResponseType(typeof(BasketData), (int)HttpStatusCode.OK)] + public async Task> UpdateQuantitiesAsync([FromBody] UpdateBasketItemsRequest data) { if (!data.Updates.Any()) { @@ -76,7 +82,7 @@ namespace Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator.Controllers } // Retrieve the current basket - var currentBasket = await _basket.GetById(data.BasketId); + var currentBasket = await _basket.GetByIdAsync(data.BasketId); if (currentBasket == null) { return BadRequest($"Basket with id {data.BasketId} not found."); @@ -86,22 +92,26 @@ namespace Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator.Controllers foreach (var update in data.Updates) { var basketItem = currentBasket.Items.SingleOrDefault(bitem => bitem.Id == update.BasketItemId); + if (basketItem == null) { return BadRequest($"Basket item with id {update.BasketItemId} not found"); } + basketItem.Quantity = update.NewQty; } // Save the updated basket - await _basket.Update(currentBasket); + await _basket.UpdateAsync(currentBasket); return currentBasket; } [HttpPost] [Route("items")] - public async Task AddBasketItem([FromBody] AddBasketItemRequest data) + [ProducesResponseType((int)HttpStatusCode.BadRequest)] + [ProducesResponseType((int)HttpStatusCode.OK)] + public async Task AddBasketItemAsync([FromBody] AddBasketItemRequest data) { if (data == null || data.Quantity == 0) { @@ -109,12 +119,12 @@ namespace Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator.Controllers } // Step 1: Get the item from catalog - var item = await _catalog.GetCatalogItem(data.CatalogItemId); + 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); + var currentBasket = (await _basket.GetByIdAsync(data.BasketId)) ?? new BasketData(data.BasketId); // Step 3: Merge current status with new product currentBasket.Items.Add(new BasketDataItem() { @@ -127,7 +137,7 @@ namespace Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator.Controllers }); // Step 4: Update basket - await _basket.Update(currentBasket); + await _basket.UpdateAsync(currentBasket); return Ok(); } diff --git a/src/ApiGateways/Mobile.Bff.Shopping/aggregator/Controllers/OrderController.cs b/src/ApiGateways/Mobile.Bff.Shopping/aggregator/Controllers/OrderController.cs index f138b1ab6..a4b33c6cb 100644 --- a/src/ApiGateways/Mobile.Bff.Shopping/aggregator/Controllers/OrderController.cs +++ b/src/ApiGateways/Mobile.Bff.Shopping/aggregator/Controllers/OrderController.cs @@ -1,6 +1,8 @@ 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 @@ -12,6 +14,7 @@ namespace Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator.Controllers { private readonly IBasketService _basketService; private readonly IOrderApiClient _orderClient; + public OrderController(IBasketService basketService, IOrderApiClient orderClient) { _basketService = basketService; @@ -20,21 +23,23 @@ namespace Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator.Controllers [Route("draft/{basketId}")] [HttpGet] - public async Task GetOrderDraft(string basketId) + [ProducesResponseType((int)HttpStatusCode.BadRequest)] + [ProducesResponseType(typeof(OrderData), (int)HttpStatusCode.OK)] + public async Task> GetOrderDraftAsync(string basketId) { 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); + var basket = await _basketService.GetByIdAsync(basketId); + if (basket == null) { return BadRequest($"No basket found for id {basketId}"); } - var orderDraft = await _orderClient.GetOrderDraftFromBasket(basket); - return Ok(orderDraft); + return await _orderClient.GetOrderDraftFromBasketAsync(basket); } } } diff --git a/src/ApiGateways/Mobile.Bff.Shopping/aggregator/Services/BasketService.cs b/src/ApiGateways/Mobile.Bff.Shopping/aggregator/Services/BasketService.cs index 8339ee44b..5186fe361 100644 --- a/src/ApiGateways/Mobile.Bff.Shopping/aggregator/Services/BasketService.cs +++ b/src/ApiGateways/Mobile.Bff.Shopping/aggregator/Services/BasketService.cs @@ -22,7 +22,7 @@ namespace Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator.Services _urls = config.Value; } - public async Task GetById(string id) + public async Task GetByIdAsync(string id) { var data = await _httpClient.GetStringAsync(_urls.Basket + UrlsConfig.BasketOperations.GetItemById(id)); @@ -31,7 +31,7 @@ namespace Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator.Services return basket; } - public async Task Update(BasketData currentBasket) + public async Task UpdateAsync(BasketData currentBasket) { var basketContent = new StringContent(JsonConvert.SerializeObject(currentBasket), System.Text.Encoding.UTF8, "application/json"); diff --git a/src/ApiGateways/Mobile.Bff.Shopping/aggregator/Services/CatalogService.cs b/src/ApiGateways/Mobile.Bff.Shopping/aggregator/Services/CatalogService.cs index 6c59f0c49..69bca2b39 100644 --- a/src/ApiGateways/Mobile.Bff.Shopping/aggregator/Services/CatalogService.cs +++ b/src/ApiGateways/Mobile.Bff.Shopping/aggregator/Services/CatalogService.cs @@ -22,7 +22,7 @@ namespace Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator.Services _urls = config.Value; } - public async Task GetCatalogItem(int id) + public async Task GetCatalogItemAsync(int id) { var stringContent = await _httpClient.GetStringAsync(_urls.Catalog + UrlsConfig.CatalogOperations.GetItemById(id)); var catalogItem = JsonConvert.DeserializeObject(stringContent); @@ -30,7 +30,7 @@ namespace Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator.Services return catalogItem; } - public async Task> GetCatalogItems(IEnumerable ids) + public async Task> GetCatalogItemsAsync(IEnumerable ids) { var stringContent = await _httpClient.GetStringAsync(_urls.Catalog + UrlsConfig.CatalogOperations.GetItemsById(ids)); var catalogItems = JsonConvert.DeserializeObject(stringContent); diff --git a/src/ApiGateways/Mobile.Bff.Shopping/aggregator/Services/IBasketService.cs b/src/ApiGateways/Mobile.Bff.Shopping/aggregator/Services/IBasketService.cs index 6fd6871c1..ad49e1adb 100644 --- a/src/ApiGateways/Mobile.Bff.Shopping/aggregator/Services/IBasketService.cs +++ b/src/ApiGateways/Mobile.Bff.Shopping/aggregator/Services/IBasketService.cs @@ -1,15 +1,13 @@ using Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator.Models; -using System; -using System.Collections.Generic; -using System.Linq; using System.Threading.Tasks; namespace Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator.Services { public interface IBasketService { - Task GetById(string id); - Task Update(BasketData currentBasket); + Task GetByIdAsync(string id); + + 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 d7e605bfa..832dfc740 100644 --- a/src/ApiGateways/Mobile.Bff.Shopping/aggregator/Services/ICatalogService.cs +++ b/src/ApiGateways/Mobile.Bff.Shopping/aggregator/Services/ICatalogService.cs @@ -1,14 +1,13 @@ using Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator.Models; -using System; using System.Collections.Generic; -using System.Linq; using System.Threading.Tasks; namespace Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator.Services { public interface ICatalogService { - Task GetCatalogItem(int id); - Task> GetCatalogItems(IEnumerable ids); + Task GetCatalogItemAsync(int id); + + 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 30ac013b9..1abe545bd 100644 --- a/src/ApiGateways/Mobile.Bff.Shopping/aggregator/Services/IOrderApiClient.cs +++ b/src/ApiGateways/Mobile.Bff.Shopping/aggregator/Services/IOrderApiClient.cs @@ -1,13 +1,10 @@ using Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator.Models; -using System; -using System.Collections.Generic; -using System.Linq; using System.Threading.Tasks; namespace Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator.Services { public interface IOrderApiClient { - Task GetOrderDraftFromBasket(BasketData basket); + Task GetOrderDraftFromBasketAsync(BasketData basket); } } diff --git a/src/ApiGateways/Mobile.Bff.Shopping/aggregator/Services/OrderApiClient.cs b/src/ApiGateways/Mobile.Bff.Shopping/aggregator/Services/OrderApiClient.cs index 03644c110..da39abbff 100644 --- a/src/ApiGateways/Mobile.Bff.Shopping/aggregator/Services/OrderApiClient.cs +++ b/src/ApiGateways/Mobile.Bff.Shopping/aggregator/Services/OrderApiClient.cs @@ -21,7 +21,7 @@ namespace Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator.Services _urls = config.Value; } - public async Task GetOrderDraftFromBasket(BasketData basket) + public async Task GetOrderDraftFromBasketAsync(BasketData basket) { var uri = _urls.Orders + UrlsConfig.OrdersOperations.GetOrderDraft(); var content = new StringContent(JsonConvert.SerializeObject(basket), System.Text.Encoding.UTF8, "application/json"); diff --git a/src/ApiGateways/Mobile.Bff.Shopping/aggregator/Startup.cs b/src/ApiGateways/Mobile.Bff.Shopping/aggregator/Startup.cs index ca11e28f9..4fe3b4e3b 100644 --- a/src/ApiGateways/Mobile.Bff.Shopping/aggregator/Startup.cs +++ b/src/ApiGateways/Mobile.Bff.Shopping/aggregator/Startup.cs @@ -127,12 +127,14 @@ namespace Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator { JwtSecurityTokenHandler.DefaultInboundClaimTypeMap.Clear(); var identityUrl = configuration.GetValue("urls:identity"); + services.AddAuthentication(options => { options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme; options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme; - }).AddJwtBearer(options => + }) + .AddJwtBearer(options => { options.Authority = identityUrl; options.RequireHttpsMetadata = false; @@ -150,6 +152,7 @@ namespace Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator return services; } + public static IServiceCollection AddHttpServices(this IServiceCollection services) { //register delegating handlers @@ -170,8 +173,6 @@ namespace Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator .AddPolicyHandler(GetRetryPolicy()) .AddPolicyHandler(GetCircuitBreakerPolicy()); - - return services; } @@ -181,7 +182,6 @@ namespace Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator .HandleTransientHttpError() .OrResult(msg => msg.StatusCode == System.Net.HttpStatusCode.NotFound) .WaitAndRetryAsync(6, retryAttempt => TimeSpan.FromSeconds(Math.Pow(2, retryAttempt))); - } private static IAsyncPolicy GetCircuitBreakerPolicy() diff --git a/src/ApiGateways/Web.Bff.Shopping/aggregator/Controllers/BasketController.cs b/src/ApiGateways/Web.Bff.Shopping/aggregator/Controllers/BasketController.cs index 5fc583ad4..6745ffa02 100644 --- a/src/ApiGateways/Web.Bff.Shopping/aggregator/Controllers/BasketController.cs +++ b/src/ApiGateways/Web.Bff.Shopping/aggregator/Controllers/BasketController.cs @@ -5,6 +5,7 @@ using Microsoft.eShopOnContainers.Web.Shopping.HttpAggregator.Services; using System; using System.Collections.Generic; using System.Linq; +using System.Net; using System.Threading.Tasks; namespace Microsoft.eShopOnContainers.Web.Shopping.HttpAggregator.Controllers @@ -16,6 +17,7 @@ namespace Microsoft.eShopOnContainers.Web.Shopping.HttpAggregator.Controllers { private readonly ICatalogService _catalog; private readonly IBasketService _basket; + public BasketController(ICatalogService catalogService, IBasketService basketService) { _catalog = catalogService; @@ -24,22 +26,23 @@ namespace Microsoft.eShopOnContainers.Web.Shopping.HttpAggregator.Controllers [HttpPost] [HttpPut] - public async Task> UpdateAllBasket([FromBody] UpdateBasketRequest data) + [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 currentBasket = await _basket.GetById(data.BuyerId); + var currentBasket = await _basket.GetByIdAsync(data.BuyerId); if (currentBasket == null) { currentBasket = new BasketData(data.BuyerId); } - var catalogItems = await _catalog.GetCatalogItems(data.Items.Select(x => x.ProductId)); + var catalogItems = await _catalog.GetCatalogItemsAsync(data.Items.Select(x => x.ProductId)); var newBasket = new BasketData(data.BuyerId); foreach (var bitem in data.Items) @@ -61,14 +64,16 @@ namespace Microsoft.eShopOnContainers.Web.Shopping.HttpAggregator.Controllers }); } - await _basket.Update(newBasket); + await _basket.UpdateAsync(newBasket); return newBasket; } [HttpPut] [Route("items")] - public async Task> UpdateQuantities([FromBody] UpdateBasketItemsRequest data) + [ProducesResponseType((int)HttpStatusCode.BadRequest)] + [ProducesResponseType(typeof(BasketData), (int)HttpStatusCode.OK)] + public async Task> UpdateQuantitiesAsync([FromBody] UpdateBasketItemsRequest data) { if (!data.Updates.Any()) { @@ -76,7 +81,7 @@ namespace Microsoft.eShopOnContainers.Web.Shopping.HttpAggregator.Controllers } // Retrieve the current basket - var currentBasket = await _basket.GetById(data.BasketId); + var currentBasket = await _basket.GetByIdAsync(data.BasketId); if (currentBasket == null) { return BadRequest($"Basket with id {data.BasketId} not found."); @@ -94,14 +99,16 @@ namespace Microsoft.eShopOnContainers.Web.Shopping.HttpAggregator.Controllers } // Save the updated basket - await _basket.Update(currentBasket); + await _basket.UpdateAsync(currentBasket); return currentBasket; } [HttpPost] [Route("items")] - public async Task AddBasketItem([FromBody] AddBasketItemRequest data) + [ProducesResponseType((int)HttpStatusCode.BadRequest)] + [ProducesResponseType((int)HttpStatusCode.OK)] + public async Task AddBasketItemAsync([FromBody] AddBasketItemRequest data) { if (data == null || data.Quantity == 0) { @@ -109,12 +116,12 @@ namespace Microsoft.eShopOnContainers.Web.Shopping.HttpAggregator.Controllers } // Step 1: Get the item from catalog - var item = await _catalog.GetCatalogItem(data.CatalogItemId); + 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); + var currentBasket = (await _basket.GetByIdAsync(data.BasketId)) ?? new BasketData(data.BasketId); // Step 3: Merge current status with new product currentBasket.Items.Add(new BasketDataItem() { @@ -127,8 +134,7 @@ namespace Microsoft.eShopOnContainers.Web.Shopping.HttpAggregator.Controllers }); // Step 4: Update basket - await _basket.Update(currentBasket); - + await _basket.UpdateAsync(currentBasket); return Ok(); } diff --git a/src/ApiGateways/Web.Bff.Shopping/aggregator/Controllers/OrderController.cs b/src/ApiGateways/Web.Bff.Shopping/aggregator/Controllers/OrderController.cs index d3a51e000..de3e4cc55 100644 --- a/src/ApiGateways/Web.Bff.Shopping/aggregator/Controllers/OrderController.cs +++ b/src/ApiGateways/Web.Bff.Shopping/aggregator/Controllers/OrderController.cs @@ -5,6 +5,7 @@ using Microsoft.eShopOnContainers.Web.Shopping.HttpAggregator.Services; using System; using System.Collections.Generic; using System.Linq; +using System.Net; using System.Threading.Tasks; namespace Microsoft.eShopOnContainers.Web.Shopping.HttpAggregator.Controllers @@ -24,20 +25,23 @@ namespace Microsoft.eShopOnContainers.Web.Shopping.HttpAggregator.Controllers [Route("draft/{basketId}")] [HttpGet] - public async Task> GetOrderDraft(string basketId) + [ProducesResponseType((int)HttpStatusCode.BadRequest)] + [ProducesResponseType(typeof(OrderData), (int)HttpStatusCode.OK)] + public async Task> GetOrderDraftAsync(string basketId) { 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); + var basket = await _basketService.GetByIdAsync(basketId); + if (basket == null) { return BadRequest($"No basket found for id {basketId}"); } - return await _orderClient.GetOrderDraftFromBasket(basket); + return await _orderClient.GetOrderDraftFromBasketAsync(basket); } } } diff --git a/src/ApiGateways/Web.Bff.Shopping/aggregator/Services/BasketService.cs b/src/ApiGateways/Web.Bff.Shopping/aggregator/Services/BasketService.cs index 291e98fd3..d0fb5c008 100644 --- a/src/ApiGateways/Web.Bff.Shopping/aggregator/Services/BasketService.cs +++ b/src/ApiGateways/Web.Bff.Shopping/aggregator/Services/BasketService.cs @@ -10,7 +10,6 @@ namespace Microsoft.eShopOnContainers.Web.Shopping.HttpAggregator.Services { public class BasketService : IBasketService { - private readonly HttpClient _apiClient; private readonly ILogger _logger; private readonly UrlsConfig _urls; @@ -22,18 +21,19 @@ namespace Microsoft.eShopOnContainers.Web.Shopping.HttpAggregator.Services _urls = config.Value; } - public async Task GetById(string id) + public async Task GetByIdAsync(string id) { var data = await _apiClient.GetStringAsync(_urls.Basket + UrlsConfig.BasketOperations.GetItemById(id)); var basket = !string.IsNullOrEmpty(data) ? JsonConvert.DeserializeObject(data) : null; + return basket; } - public async Task Update(BasketData currentBasket) + public async Task UpdateAsync(BasketData currentBasket) { var basketContent = new StringContent(JsonConvert.SerializeObject(currentBasket), System.Text.Encoding.UTF8, "application/json"); - var data = await _apiClient.PostAsync(_urls.Basket + UrlsConfig.BasketOperations.UpdateBasket(), basketContent); + await _apiClient.PostAsync(_urls.Basket + UrlsConfig.BasketOperations.UpdateBasket(), basketContent); } } } diff --git a/src/ApiGateways/Web.Bff.Shopping/aggregator/Services/CatalogService.cs b/src/ApiGateways/Web.Bff.Shopping/aggregator/Services/CatalogService.cs index ba67b7c1e..159e56d85 100644 --- a/src/ApiGateways/Web.Bff.Shopping/aggregator/Services/CatalogService.cs +++ b/src/ApiGateways/Web.Bff.Shopping/aggregator/Services/CatalogService.cs @@ -11,7 +11,6 @@ namespace Microsoft.eShopOnContainers.Web.Shopping.HttpAggregator.Services { public class CatalogService : ICatalogService { - private readonly HttpClient _httpClient; private readonly ILogger _logger; private readonly UrlsConfig _urls; @@ -23,20 +22,18 @@ namespace Microsoft.eShopOnContainers.Web.Shopping.HttpAggregator.Services _urls = config.Value; } - public async Task GetCatalogItem(int id) + public async Task GetCatalogItemAsync(int id) { var stringContent = await _httpClient.GetStringAsync(_urls.Catalog + UrlsConfig.CatalogOperations.GetItemById(id)); - var catalogItem = JsonConvert.DeserializeObject(stringContent); - return catalogItem; + return JsonConvert.DeserializeObject(stringContent); } - public async Task> GetCatalogItems(IEnumerable ids) + public async Task> GetCatalogItemsAsync(IEnumerable ids) { var stringContent = await _httpClient.GetStringAsync(_urls.Catalog + UrlsConfig.CatalogOperations.GetItemsById(ids)); - var catalogItems = JsonConvert.DeserializeObject(stringContent); - return catalogItems; + return JsonConvert.DeserializeObject(stringContent); } } } diff --git a/src/ApiGateways/Web.Bff.Shopping/aggregator/Services/IBasketService.cs b/src/ApiGateways/Web.Bff.Shopping/aggregator/Services/IBasketService.cs index f59c31965..046ef753d 100644 --- a/src/ApiGateways/Web.Bff.Shopping/aggregator/Services/IBasketService.cs +++ b/src/ApiGateways/Web.Bff.Shopping/aggregator/Services/IBasketService.cs @@ -1,15 +1,12 @@ using Microsoft.eShopOnContainers.Web.Shopping.HttpAggregator.Models; -using System; -using System.Collections.Generic; -using System.Linq; using System.Threading.Tasks; namespace Microsoft.eShopOnContainers.Web.Shopping.HttpAggregator.Services { public interface IBasketService { - Task GetById(string id); - Task Update(BasketData currentBasket); + Task GetByIdAsync(string id); + Task UpdateAsync(BasketData currentBasket); } } diff --git a/src/ApiGateways/Web.Bff.Shopping/aggregator/Services/ICatalogService.cs b/src/ApiGateways/Web.Bff.Shopping/aggregator/Services/ICatalogService.cs index 7d192f3cc..9f86b84f9 100644 --- a/src/ApiGateways/Web.Bff.Shopping/aggregator/Services/ICatalogService.cs +++ b/src/ApiGateways/Web.Bff.Shopping/aggregator/Services/ICatalogService.cs @@ -1,14 +1,13 @@ using Microsoft.eShopOnContainers.Web.Shopping.HttpAggregator.Models; -using System; using System.Collections.Generic; -using System.Linq; using System.Threading.Tasks; namespace Microsoft.eShopOnContainers.Web.Shopping.HttpAggregator.Services { public interface ICatalogService { - Task GetCatalogItem(int id); - Task> GetCatalogItems(IEnumerable ids); + Task GetCatalogItemAsync(int id); + + Task> GetCatalogItemsAsync(IEnumerable ids); } } diff --git a/src/ApiGateways/Web.Bff.Shopping/aggregator/Services/IOrderApiClient.cs b/src/ApiGateways/Web.Bff.Shopping/aggregator/Services/IOrderApiClient.cs index c97eccbbd..0e972833c 100644 --- a/src/ApiGateways/Web.Bff.Shopping/aggregator/Services/IOrderApiClient.cs +++ b/src/ApiGateways/Web.Bff.Shopping/aggregator/Services/IOrderApiClient.cs @@ -1,13 +1,10 @@ using Microsoft.eShopOnContainers.Web.Shopping.HttpAggregator.Models; -using System; -using System.Collections.Generic; -using System.Linq; using System.Threading.Tasks; namespace Microsoft.eShopOnContainers.Web.Shopping.HttpAggregator.Services { public interface IOrderApiClient { - Task GetOrderDraftFromBasket(BasketData basket); + Task GetOrderDraftFromBasketAsync(BasketData basket); } } diff --git a/src/ApiGateways/Web.Bff.Shopping/aggregator/Services/OrderApiClient.cs b/src/ApiGateways/Web.Bff.Shopping/aggregator/Services/OrderApiClient.cs index d43e392d3..a26028d69 100644 --- a/src/ApiGateways/Web.Bff.Shopping/aggregator/Services/OrderApiClient.cs +++ b/src/ApiGateways/Web.Bff.Shopping/aggregator/Services/OrderApiClient.cs @@ -10,7 +10,6 @@ namespace Microsoft.eShopOnContainers.Web.Shopping.HttpAggregator.Services { public class OrderApiClient : IOrderApiClient { - private readonly HttpClient _apiClient; private readonly ILogger _logger; private readonly UrlsConfig _urls; @@ -22,7 +21,7 @@ namespace Microsoft.eShopOnContainers.Web.Shopping.HttpAggregator.Services _urls = config.Value; } - public async Task GetOrderDraftFromBasket(BasketData basket) + public async Task GetOrderDraftFromBasketAsync(BasketData basket) { var url = _urls.Orders + UrlsConfig.OrdersOperations.GetOrderDraft(); var content = new StringContent(JsonConvert.SerializeObject(basket), System.Text.Encoding.UTF8, "application/json"); diff --git a/src/ApiGateways/Web.Bff.Shopping/aggregator/Startup.cs b/src/ApiGateways/Web.Bff.Shopping/aggregator/Startup.cs index 1b545f7e7..23db1f912 100644 --- a/src/ApiGateways/Web.Bff.Shopping/aggregator/Startup.cs +++ b/src/ApiGateways/Web.Bff.Shopping/aggregator/Startup.cs @@ -64,13 +64,12 @@ namespace Microsoft.eShopOnContainers.Web.Shopping.HttpAggregator app.UseHttpsRedirection(); app.UseMvc(); - app.UseSwagger().UseSwaggerUI(c => - { - c.SwaggerEndpoint($"{ (!string.IsNullOrEmpty(pathBase) ? pathBase : string.Empty) }/swagger/v1/swagger.json", "Purchase BFF V1"); - //c.ConfigureOAuth2("Microsoft.eShopOnContainers.Web.Shopping.HttpAggregatorwaggerui", "", "", "Purchase BFF Swagger UI"); - }); - - + app.UseSwagger() + .UseSwaggerUI(c => + { + c.SwaggerEndpoint($"{ (!string.IsNullOrEmpty(pathBase) ? pathBase : string.Empty) }/swagger/v1/swagger.json", "Purchase BFF V1"); + //c.ConfigureOAuth2("Microsoft.eShopOnContainers.Web.Shopping.HttpAggregatorwaggerui", "", "", "Purchase BFF Swagger UI"); + }); } } @@ -105,6 +104,7 @@ namespace Microsoft.eShopOnContainers.Web.Shopping.HttpAggregator return services; } + public static IServiceCollection AddCustomMvc(this IServiceCollection services, IConfiguration configuration) { services.AddOptions(); @@ -184,6 +184,7 @@ namespace Microsoft.eShopOnContainers.Web.Shopping.HttpAggregator .WaitAndRetryAsync(6, retryAttempt => TimeSpan.FromSeconds(Math.Pow(2, retryAttempt))); } + static IAsyncPolicy GetCircuitBreakerPolicy() { return HttpPolicyExtensions diff --git a/src/Services/Basket/Basket.API/Controllers/BasketController.cs b/src/Services/Basket/Basket.API/Controllers/BasketController.cs index f230efd84..0e15e65dd 100644 --- a/src/Services/Basket/Basket.API/Controllers/BasketController.cs +++ b/src/Services/Basket/Basket.API/Controllers/BasketController.cs @@ -17,37 +17,28 @@ namespace Microsoft.eShopOnContainers.Services.Basket.API.Controllers public class BasketController : ControllerBase { private readonly IBasketRepository _repository; - private readonly IIdentityService _identitySvc; + private readonly IIdentityService _identityService; private readonly IEventBus _eventBus; - public BasketController(IBasketRepository repository, - IIdentityService identityService, - IEventBus eventBus) + public BasketController(IBasketRepository repository, IIdentityService identityService, IEventBus eventBus) { _repository = repository; - _identitySvc = identityService; + _identityService = identityService; _eventBus = eventBus; } - // GET /id [HttpGet("{id}")] [ProducesResponseType(typeof(CustomerBasket), (int)HttpStatusCode.OK)] - public async Task> Get(string id) + public async Task> GetBasketByIdAsync(string id) { var basket = await _repository.GetBasketAsync(id); - if (basket == null) - { - return new CustomerBasket(id); - } - - return basket; + return basket ?? new CustomerBasket(id); } - // POST /value [HttpPost] [ProducesResponseType(typeof(CustomerBasket), (int)HttpStatusCode.OK)] - public async Task> Post([FromBody]CustomerBasket value) + public async Task> UpdateBasketAsync([FromBody]CustomerBasket value) { return await _repository.UpdateBasketAsync(value); } @@ -56,11 +47,10 @@ namespace Microsoft.eShopOnContainers.Services.Basket.API.Controllers [HttpPost] [ProducesResponseType((int)HttpStatusCode.Accepted)] [ProducesResponseType((int)HttpStatusCode.BadRequest)] - public async Task Checkout([FromBody]BasketCheckout basketCheckout, [FromHeader(Name = "x-requestid")] string requestId) + public async Task CheckoutAsync([FromBody]BasketCheckout basketCheckout, [FromHeader(Name = "x-requestid")] string requestId) { - var userId = _identitySvc.GetUserIdentity(); + var userId = _identityService.GetUserIdentity(); - basketCheckout.RequestId = (Guid.TryParse(requestId, out Guid guid) && guid != Guid.Empty) ? guid : basketCheckout.RequestId; @@ -80,16 +70,17 @@ namespace Microsoft.eShopOnContainers.Services.Basket.API.Controllers // Once basket is checkout, sends an integration event to // ordering.api to convert basket to order and proceeds with // order creation process - _eventBus.Publish(eventMessage); + _eventBus.Publish(eventMessage); return Accepted(); } // DELETE api/values/5 [HttpDelete("{id}")] - public void Delete(string id) + [ProducesResponseType(typeof(void), (int)HttpStatusCode.OK)] + public async Task DeleteBasketByIdAsync(string id) { - _repository.DeleteBasketAsync(id); + await _repository.DeleteBasketAsync(id); } } } diff --git a/src/Services/Basket/Basket.API/Model/RedisBasketRepository.cs b/src/Services/Basket/Basket.API/Model/RedisBasketRepository.cs index f748d2c25..5000e6c29 100644 --- a/src/Services/Basket/Basket.API/Model/RedisBasketRepository.cs +++ b/src/Services/Basket/Basket.API/Model/RedisBasketRepository.cs @@ -10,7 +10,6 @@ namespace Microsoft.eShopOnContainers.Services.Basket.API.Model public class RedisBasketRepository : IBasketRepository { private readonly ILogger _logger; - private readonly ConnectionMultiplexer _redis; private readonly IDatabase _database; @@ -30,12 +29,14 @@ namespace Microsoft.eShopOnContainers.Services.Basket.API.Model { var server = GetServer(); var data = server.Keys(); + return data?.Select(k => k.ToString()); } public async Task GetBasketAsync(string customerId) { var data = await _database.StringGetAsync(customerId); + if (data.IsNullOrEmpty) { return null; @@ -47,6 +48,7 @@ namespace Microsoft.eShopOnContainers.Services.Basket.API.Model public async Task UpdateBasketAsync(CustomerBasket basket) { var created = await _database.StringSetAsync(basket.BuyerId, JsonConvert.SerializeObject(basket)); + if (!created) { _logger.LogInformation("Problem occur persisting the item."); diff --git a/src/Services/Basket/Basket.UnitTests/Application/BasketWebApiTest.cs b/src/Services/Basket/Basket.UnitTests/Application/BasketWebApiTest.cs index 522eb6e44..a2e382b92 100644 --- a/src/Services/Basket/Basket.UnitTests/Application/BasketWebApiTest.cs +++ b/src/Services/Basket/Basket.UnitTests/Application/BasketWebApiTest.cs @@ -44,7 +44,7 @@ namespace UnitTest.Basket.Application //Act var basketController = new BasketController( _basketRepositoryMock.Object, _identityServiceMock.Object, _serviceBusMock.Object); - var actionResult = await basketController.Get(fakeCustomerId); + var actionResult = await basketController.GetBasketByIdAsync(fakeCustomerId); //Assert Assert.Equal((actionResult.Result as OkObjectResult).StatusCode, (int)System.Net.HttpStatusCode.OK); @@ -67,7 +67,7 @@ namespace UnitTest.Basket.Application var basketController = new BasketController( _basketRepositoryMock.Object, _identityServiceMock.Object, _serviceBusMock.Object); - var actionResult = await basketController.Post(fakeCustomerBasket); + var actionResult = await basketController.UpdateBasketAsync(fakeCustomerBasket); //Assert Assert.Equal((actionResult.Result as OkObjectResult).StatusCode, (int)System.Net.HttpStatusCode.OK); @@ -86,7 +86,7 @@ namespace UnitTest.Basket.Application var basketController = new BasketController( _basketRepositoryMock.Object, _identityServiceMock.Object, _serviceBusMock.Object); - var result = await basketController.Checkout(new BasketCheckout(), Guid.NewGuid().ToString()) as BadRequestResult; + var result = await basketController.CheckoutAsync(new BasketCheckout(), Guid.NewGuid().ToString()) as BadRequestResult; Assert.NotNull(result); } @@ -114,7 +114,7 @@ namespace UnitTest.Basket.Application }; //Act - var result = await basketController.Checkout(new BasketCheckout(), Guid.NewGuid().ToString()) as AcceptedResult; + var result = await basketController.CheckoutAsync(new BasketCheckout(), Guid.NewGuid().ToString()) as AcceptedResult; _serviceBusMock.Verify(mock => mock.Publish(It.IsAny()), Times.Once); diff --git a/src/Services/Catalog/Catalog.API/Controllers/CatalogController.cs b/src/Services/Catalog/Catalog.API/Controllers/CatalogController.cs index 6bbe9a092..d9fa4002e 100644 --- a/src/Services/Catalog/Catalog.API/Controllers/CatalogController.cs +++ b/src/Services/Catalog/Catalog.API/Controllers/CatalogController.cs @@ -28,7 +28,7 @@ namespace Microsoft.eShopOnContainers.Services.Catalog.API.Controllers _catalogIntegrationEventService = catalogIntegrationEventService ?? throw new ArgumentNullException(nameof(catalogIntegrationEventService)); _settings = settings.Value; - ((DbContext)context).ChangeTracker.QueryTrackingBehavior = QueryTrackingBehavior.NoTracking; + context.ChangeTracker.QueryTrackingBehavior = QueryTrackingBehavior.NoTracking; } // GET api/v1/[controller]/items[?pageSize=3&pageIndex=10] @@ -36,11 +36,19 @@ namespace Microsoft.eShopOnContainers.Services.Catalog.API.Controllers [Route("items")] [ProducesResponseType(typeof(PaginatedItemsViewModel), (int)HttpStatusCode.OK)] [ProducesResponseType(typeof(IEnumerable), (int)HttpStatusCode.OK)] - public async Task Items([FromQuery]int pageSize = 10, [FromQuery]int pageIndex = 0, [FromQuery] string ids = null) + [ProducesResponseType((int)HttpStatusCode.BadRequest)] + public async Task ItemsAsync([FromQuery]int pageSize = 10, [FromQuery]int pageIndex = 0, string ids = null) { if (!string.IsNullOrEmpty(ids)) { - return GetItemsByIds(ids); + var items = await GetItemsByIdsAsync(ids); + + if (!items.Any()) + { + return BadRequest("ids value invalid. Must be comma-separated list of numbers"); + } + + return Ok(items); } var totalItems = await _catalogContext.CatalogItems @@ -54,37 +62,36 @@ namespace Microsoft.eShopOnContainers.Services.Catalog.API.Controllers itemsOnPage = ChangeUriPlaceholder(itemsOnPage); - var model = new PaginatedItemsViewModel( - pageIndex, pageSize, totalItems, itemsOnPage); + var model = new PaginatedItemsViewModel(pageIndex, pageSize, totalItems, itemsOnPage); return Ok(model); } - private IActionResult GetItemsByIds(string ids) + private async Task> GetItemsByIdsAsync(string ids) { - var numIds = ids.Split(',') - .Select(id => (Ok: int.TryParse(id, out int x), Value: x)); + var numIds = ids.Split(',').Select(id => (Ok: int.TryParse(id, out int x), Value: x)); if (!numIds.All(nid => nid.Ok)) { - return BadRequest("ids value invalid. Must be comma-separated list of numbers"); + return new List(); } var idsToSelect = numIds .Select(id => id.Value); - var items = _catalogContext.CatalogItems.Where(ci => idsToSelect.Contains(ci.Id)).ToList(); + var items = await _catalogContext.CatalogItems.Where(ci => idsToSelect.Contains(ci.Id)).ToListAsync(); items = ChangeUriPlaceholder(items); - return Ok(items); + return items; } [HttpGet] [Route("items/{id:int}")] [ProducesResponseType((int)HttpStatusCode.NotFound)] + [ProducesResponseType((int)HttpStatusCode.BadRequest)] [ProducesResponseType(typeof(CatalogItem), (int)HttpStatusCode.OK)] - public async Task> GetItemById(int id) + public async Task> ItemByIdAsync(int id) { if (id <= 0) { @@ -95,6 +102,7 @@ namespace Microsoft.eShopOnContainers.Services.Catalog.API.Controllers var baseUri = _settings.PicBaseUrl; var azureStorageEnabled = _settings.AzureStorageEnabled; + item.FillProductUrl(baseUri, azureStorageEnabled: azureStorageEnabled); if (item != null) @@ -107,9 +115,9 @@ namespace Microsoft.eShopOnContainers.Services.Catalog.API.Controllers // GET api/v1/[controller]/items/withname/samplename[?pageSize=3&pageIndex=10] [HttpGet] - [Route("[action]/withname/{name:minlength(1)}")] + [Route("items/withname/{name:minlength(1)}")] [ProducesResponseType(typeof(PaginatedItemsViewModel), (int)HttpStatusCode.OK)] - public async Task>> Items(string name, [FromQuery]int pageSize = 10, [FromQuery]int pageIndex = 0) + public async Task>> ItemsWithNameAsync(string name, [FromQuery]int pageSize = 10, [FromQuery]int pageIndex = 0) { var totalItems = await _catalogContext.CatalogItems .Where(c => c.Name.StartsWith(name)) @@ -123,14 +131,14 @@ namespace Microsoft.eShopOnContainers.Services.Catalog.API.Controllers itemsOnPage = ChangeUriPlaceholder(itemsOnPage); - return new PaginatedItemsViewModel(pageIndex, pageSize, totalItems, itemsOnPage); + return new PaginatedItemsViewModel(pageIndex, pageSize, totalItems, itemsOnPage); } // GET api/v1/[controller]/items/type/1/brand[?pageSize=3&pageIndex=10] [HttpGet] - [Route("[action]/type/{catalogTypeId}/brand/{catalogBrandId:int?}")] + [Route("items/type/{catalogTypeId}/brand/{catalogBrandId:int?}")] [ProducesResponseType(typeof(PaginatedItemsViewModel), (int)HttpStatusCode.OK)] - public async Task>> Items(int catalogTypeId, int? catalogBrandId, [FromQuery]int pageSize = 10, [FromQuery]int pageIndex = 0) + public async Task>> ItemsByTypeIdAndBrandIdAsync(int catalogTypeId, int? catalogBrandId, [FromQuery]int pageSize = 10, [FromQuery]int pageIndex = 0) { var root = (IQueryable)_catalogContext.CatalogItems; @@ -153,11 +161,12 @@ namespace Microsoft.eShopOnContainers.Services.Catalog.API.Controllers return new PaginatedItemsViewModel(pageIndex, pageSize, totalItems, itemsOnPage); } + // GET api/v1/[controller]/items/type/all/brand[?pageSize=3&pageIndex=10] [HttpGet] - [Route("[action]/type/all/brand/{catalogBrandId:int?}")] + [Route("items/type/all/brand/{catalogBrandId:int?}")] [ProducesResponseType(typeof(PaginatedItemsViewModel), (int)HttpStatusCode.OK)] - public async Task>> Items(int? catalogBrandId, [FromQuery]int pageSize = 10, [FromQuery]int pageIndex = 0) + public async Task>> ItemsByBrandIdAsync(int? catalogBrandId, [FromQuery]int pageSize = 10, [FromQuery]int pageIndex = 0) { var root = (IQueryable)_catalogContext.CatalogItems; @@ -181,18 +190,18 @@ namespace Microsoft.eShopOnContainers.Services.Catalog.API.Controllers // GET api/v1/[controller]/CatalogTypes [HttpGet] - [Route("[action]")] + [Route("catalogtypes")] [ProducesResponseType(typeof(List), (int)HttpStatusCode.OK)] - public async Task>> CatalogTypes() + public async Task>> CatalogTypesAsync() { return await _catalogContext.CatalogTypes.ToListAsync(); } // GET api/v1/[controller]/CatalogBrands [HttpGet] - [Route("[action]")] + [Route("catalogbrands")] [ProducesResponseType(typeof(List), (int)HttpStatusCode.OK)] - public async Task>> CatalogBrands() + public async Task>> CatalogBrandsAsync() { return await _catalogContext.CatalogBrands.ToListAsync(); } @@ -202,10 +211,9 @@ namespace Microsoft.eShopOnContainers.Services.Catalog.API.Controllers [HttpPut] [ProducesResponseType((int)HttpStatusCode.NotFound)] [ProducesResponseType((int)HttpStatusCode.Created)] - public async Task UpdateProduct([FromBody]CatalogItem productToUpdate) + public async Task UpdateProductAsync([FromBody]CatalogItem productToUpdate) { - var catalogItem = await _catalogContext.CatalogItems - .SingleOrDefaultAsync(i => i.Id == productToUpdate.Id); + var catalogItem = await _catalogContext.CatalogItems.SingleOrDefaultAsync(i => i.Id == productToUpdate.Id); if (catalogItem == null) { @@ -215,7 +223,6 @@ namespace Microsoft.eShopOnContainers.Services.Catalog.API.Controllers var oldPrice = catalogItem.Price; var raiseProductPriceChangedEvent = oldPrice != productToUpdate.Price; - // Update current product catalogItem = productToUpdate; _catalogContext.CatalogItems.Update(catalogItem); @@ -236,14 +243,14 @@ namespace Microsoft.eShopOnContainers.Services.Catalog.API.Controllers await _catalogContext.SaveChangesAsync(); } - return CreatedAtAction(nameof(GetItemById), new { id = productToUpdate.Id }, null); + return CreatedAtAction(nameof(ItemByIdAsync), new { id = productToUpdate.Id }, null); } //POST api/v1/[controller]/items [Route("items")] [HttpPost] [ProducesResponseType((int)HttpStatusCode.Created)] - public async Task CreateProduct([FromBody]CatalogItem product) + public async Task CreateProductAsync([FromBody]CatalogItem product) { var item = new CatalogItem { @@ -254,18 +261,20 @@ namespace Microsoft.eShopOnContainers.Services.Catalog.API.Controllers PictureFileName = product.PictureFileName, Price = product.Price }; + _catalogContext.CatalogItems.Add(item); await _catalogContext.SaveChangesAsync(); - return CreatedAtAction(nameof(GetItemById), new { id = item.Id }, null); + return CreatedAtAction(nameof(ItemByIdAsync), new { id = item.Id }, null); } //DELETE api/v1/[controller]/id [Route("{id}")] [HttpDelete] [ProducesResponseType((int)HttpStatusCode.NoContent)] - public async Task DeleteProduct(int id) + [ProducesResponseType((int)HttpStatusCode.NotFound)] + public async Task DeleteProductAsync(int id) { var product = _catalogContext.CatalogItems.SingleOrDefault(x => x.Id == id); diff --git a/src/Services/Catalog/Catalog.API/Controllers/PicController.cs b/src/Services/Catalog/Catalog.API/Controllers/PicController.cs index 6ea7c802c..7d798597e 100644 --- a/src/Services/Catalog/Catalog.API/Controllers/PicController.cs +++ b/src/Services/Catalog/Catalog.API/Controllers/PicController.cs @@ -28,7 +28,7 @@ namespace Microsoft.eShopOnContainers.Services.Catalog.API.Controllers [ProducesResponseType((int)HttpStatusCode.NotFound)] [ProducesResponseType((int)HttpStatusCode.BadRequest)] // GET: // - public async Task GetImage(int catalogItemId) + public async Task GetImageAsync(int catalogItemId) { if (catalogItemId <= 0) { diff --git a/src/Services/Location/Locations.API/Controllers/LocationsController.cs b/src/Services/Location/Locations.API/Controllers/LocationsController.cs index 09f529449..a9cbae1c2 100644 --- a/src/Services/Location/Locations.API/Controllers/LocationsController.cs +++ b/src/Services/Location/Locations.API/Controllers/LocationsController.cs @@ -28,27 +28,27 @@ namespace Locations.API.Controllers [Route("user/{userId:guid}")] [HttpGet] [ProducesResponseType(typeof(UserLocation), (int)HttpStatusCode.OK)] - public async Task> GetUserLocation(Guid userId) + public async Task> GetUserLocationAsync(Guid userId) { - return await _locationsService.GetUserLocation(userId.ToString()); + return await _locationsService.GetUserLocationAsync(userId.ToString()); } //GET api/v1/[controller]/ [Route("")] [HttpGet] [ProducesResponseType(typeof(List), (int)HttpStatusCode.OK)] - public async Task>> GetAllLocations() + public async Task>> GetAllLocationsAsync() { - return await _locationsService.GetAllLocation(); + return await _locationsService.GetAllLocationAsync(); } //GET api/v1/[controller]/1 [Route("{locationId}")] [HttpGet] [ProducesResponseType(typeof(Microsoft.eShopOnContainers.Services.Locations.API.Model.Locations), (int)HttpStatusCode.OK)] - public async Task> GetLocation(int locationId) + public async Task> GetLocationAsync(int locationId) { - return await _locationsService.GetLocation(locationId); + return await _locationsService.GetLocationAsync(locationId); } //POST api/v1/[controller]/ @@ -56,14 +56,17 @@ namespace Locations.API.Controllers [HttpPost] [ProducesResponseType((int)HttpStatusCode.OK)] [ProducesResponseType((int)HttpStatusCode.BadRequest)] - public async Task CreateOrUpdateUserLocation([FromBody]LocationRequest newLocReq) + public async Task CreateOrUpdateUserLocationAsync([FromBody]LocationRequest newLocReq) { var userId = _identityService.GetUserIdentity(); - var result = await _locationsService.AddOrUpdateUserLocation(userId, newLocReq); - - return result ? - (IActionResult)Ok() : - (IActionResult)BadRequest(); + var result = await _locationsService.AddOrUpdateUserLocationAsync(userId, newLocReq); + + if (!result) + { + return BadRequest(); + } + + return Ok(); } } } diff --git a/src/Services/Location/Locations.API/Infrastructure/Services/ILocationsService.cs b/src/Services/Location/Locations.API/Infrastructure/Services/ILocationsService.cs index 5d55bb25e..11459492a 100644 --- a/src/Services/Location/Locations.API/Infrastructure/Services/ILocationsService.cs +++ b/src/Services/Location/Locations.API/Infrastructure/Services/ILocationsService.cs @@ -7,12 +7,12 @@ public interface ILocationsService { - Task GetLocation(int locationId); + Task GetLocationAsync(int locationId); - Task GetUserLocation(string id); + Task GetUserLocationAsync(string id); - Task> GetAllLocation(); + Task> GetAllLocationAsync(); - Task AddOrUpdateUserLocation(string userId, LocationRequest locRequest); + Task AddOrUpdateUserLocationAsync(string userId, LocationRequest locRequest); } } diff --git a/src/Services/Location/Locations.API/Infrastructure/Services/LocationsService.cs b/src/Services/Location/Locations.API/Infrastructure/Services/LocationsService.cs index 771a075d2..e9c299d23 100644 --- a/src/Services/Location/Locations.API/Infrastructure/Services/LocationsService.cs +++ b/src/Services/Location/Locations.API/Infrastructure/Services/LocationsService.cs @@ -21,22 +21,22 @@ _eventBus = eventBus ?? throw new ArgumentNullException(nameof(eventBus)); } - public async Task GetLocation(int locationId) + public async Task GetLocationAsync(int locationId) { return await _locationsRepository.GetAsync(locationId); } - public async Task GetUserLocation(string userId) + public async Task GetUserLocationAsync(string userId) { return await _locationsRepository.GetUserLocationAsync(userId); } - public async Task> GetAllLocation() + public async Task> GetAllLocationAsync() { return await _locationsRepository.GetLocationListAsync(); } - public async Task AddOrUpdateUserLocation(string userId, LocationRequest currentPosition) + public async Task AddOrUpdateUserLocationAsync(string userId, LocationRequest currentPosition) { // Get the list of ordered regions the user currently is within var currentUserAreaLocationList = await _locationsRepository.GetCurrentUserRegionsListAsync(currentPosition); diff --git a/src/Services/Marketing/Marketing.API/Controllers/CampaignsController.cs b/src/Services/Marketing/Marketing.API/Controllers/CampaignsController.cs index 95d14c475..67ac1bca5 100644 --- a/src/Services/Marketing/Marketing.API/Controllers/CampaignsController.cs +++ b/src/Services/Marketing/Marketing.API/Controllers/CampaignsController.cs @@ -41,7 +41,7 @@ namespace Microsoft.eShopOnContainers.Services.Marketing.API.Controllers [HttpGet] [ProducesResponseType(typeof(List), (int)HttpStatusCode.OK)] - public async Task>> GetAllCampaigns() + public async Task>> GetAllCampaignsAsync() { var campaignList = await _context.Campaigns.ToListAsync(); @@ -56,10 +56,9 @@ namespace Microsoft.eShopOnContainers.Services.Marketing.API.Controllers [HttpGet("{id:int}")] [ProducesResponseType(typeof(CampaignDTO), (int)HttpStatusCode.OK)] [ProducesResponseType((int)HttpStatusCode.NotFound)] - public async Task> GetCampaignById(int id) + public async Task> GetCampaignByIdAsync(int id) { - var campaign = await _context.Campaigns - .SingleOrDefaultAsync(c => c.Id == id); + var campaign = await _context.Campaigns.SingleOrDefaultAsync(c => c.Id == id); if (campaign is null) { @@ -72,7 +71,7 @@ namespace Microsoft.eShopOnContainers.Services.Marketing.API.Controllers [HttpPost] [ProducesResponseType((int)HttpStatusCode.BadRequest)] [ProducesResponseType((int)HttpStatusCode.Created)] - public async Task CreateCampaign([FromBody] CampaignDTO campaignDto) + public async Task CreateCampaignAsync([FromBody] CampaignDTO campaignDto) { if (campaignDto is null) { @@ -84,14 +83,14 @@ namespace Microsoft.eShopOnContainers.Services.Marketing.API.Controllers await _context.Campaigns.AddAsync(campaign); await _context.SaveChangesAsync(); - return CreatedAtAction(nameof(GetCampaignById), new { id = campaign.Id }, null); + return CreatedAtAction(nameof(GetCampaignByIdAsync), new { id = campaign.Id }, null); } [HttpPut("{id:int}")] [ProducesResponseType((int)HttpStatusCode.BadRequest)] [ProducesResponseType((int)HttpStatusCode.NotFound)] [ProducesResponseType((int)HttpStatusCode.Created)] - public async Task UpdateCampaign(int id, [FromBody] CampaignDTO campaignDto) + public async Task UpdateCampaignAsync(int id, [FromBody] CampaignDTO campaignDto) { if (id < 1 || campaignDto is null) { @@ -112,14 +111,14 @@ namespace Microsoft.eShopOnContainers.Services.Marketing.API.Controllers await _context.SaveChangesAsync(); - return CreatedAtAction(nameof(GetCampaignById), new { id = campaignToUpdate.Id }, null); + return CreatedAtAction(nameof(GetCampaignByIdAsync), new { id = campaignToUpdate.Id }, null); } [HttpDelete("{id:int}")] [ProducesResponseType((int)HttpStatusCode.BadRequest)] [ProducesResponseType((int)HttpStatusCode.NotFound)] [ProducesResponseType((int)HttpStatusCode.NoContent)] - public async Task Delete(int id) + public async Task DeleteCampaignByIdAsync(int id) { if (id < 1) { @@ -127,6 +126,7 @@ namespace Microsoft.eShopOnContainers.Services.Marketing.API.Controllers } var campaignToDelete = await _context.Campaigns.FindAsync(id); + if (campaignToDelete is null) { return NotFound(); @@ -140,7 +140,7 @@ namespace Microsoft.eShopOnContainers.Services.Marketing.API.Controllers [HttpGet("user")] [ProducesResponseType(typeof(PaginatedItemsViewModel), (int)HttpStatusCode.OK)] - public async Task>> GetCampaignsByUserId( int pageSize = 10, int pageIndex = 0) + public async Task>> GetCampaignsByUserIdAsync( int pageSize = 10, int pageIndex = 0) { var userId = _identityService.GetUserIdentity(); @@ -165,10 +165,10 @@ namespace Microsoft.eShopOnContainers.Services.Marketing.API.Controllers var userCampaignDtoList = MapCampaignModelListToDtoList(userCampaignList); campaignDtoList.AddRange(userCampaignDtoList); } - } var totalItems = campaignDtoList.Count(); + campaignDtoList = campaignDtoList .Skip(pageSize * pageIndex) .Take(pageSize).ToList(); @@ -176,7 +176,6 @@ namespace Microsoft.eShopOnContainers.Services.Marketing.API.Controllers return new PaginatedItemsViewModel(pageIndex, pageSize, totalItems, campaignDtoList); } - private List MapCampaignModelListToDtoList(List campaignList) { var campaignDtoList = new List(); diff --git a/src/Services/Marketing/Marketing.API/Controllers/LocationsController.cs b/src/Services/Marketing/Marketing.API/Controllers/LocationsController.cs index 98bef1e70..7d5959cb5 100644 --- a/src/Services/Marketing/Marketing.API/Controllers/LocationsController.cs +++ b/src/Services/Marketing/Marketing.API/Controllers/LocationsController.cs @@ -75,7 +75,7 @@ namespace Microsoft.eShopOnContainers.Services.Marketing.API.Controllers [Route("api/v1/campaigns/{campaignId:int}/locations")] [ProducesResponseType((int)HttpStatusCode.BadRequest)] [ProducesResponseType((int)HttpStatusCode.Created)] - public async Task CreateLocation(int campaignId, [FromBody] UserLocationRuleDTO locationRuleDto) + public async Task CreateLocationAsync(int campaignId, [FromBody] UserLocationRuleDTO locationRuleDto) { if (campaignId < 1 || locationRuleDto is null) { @@ -96,7 +96,7 @@ namespace Microsoft.eShopOnContainers.Services.Marketing.API.Controllers [Route("api/v1/campaigns/{campaignId:int}/locations/{userLocationRuleId:int}")] [ProducesResponseType((int)HttpStatusCode.BadRequest)] [ProducesResponseType((int)HttpStatusCode.NotFound)] - public async Task DeleteLocationById(int campaignId, int userLocationRuleId) + public async Task DeleteLocationByIdAsync(int campaignId, int userLocationRuleId) { if (campaignId < 1 || userLocationRuleId < 1) { @@ -118,8 +118,6 @@ namespace Microsoft.eShopOnContainers.Services.Marketing.API.Controllers return NoContent(); } - - private List MapUserLocationRuleModelListToDtoList(List userLocationRuleList) { var userLocationRuleDtoList = new List(); diff --git a/src/Services/Ordering/Ordering.API/Controllers/OrdersController.cs b/src/Services/Ordering/Ordering.API/Controllers/OrdersController.cs index 0f6cbc69c..e2c711b69 100644 --- a/src/Services/Ordering/Ordering.API/Controllers/OrdersController.cs +++ b/src/Services/Ordering/Ordering.API/Controllers/OrdersController.cs @@ -23,7 +23,6 @@ namespace Microsoft.eShopOnContainers.Services.Ordering.API.Controllers public OrdersController(IMediator mediator, IOrderQueries orderQueries, IIdentityService identityService) { - _mediator = mediator ?? throw new ArgumentNullException(nameof(mediator)); _orderQueries = orderQueries ?? throw new ArgumentNullException(nameof(orderQueries)); _identityService = identityService ?? throw new ArgumentNullException(nameof(identityService)); @@ -33,41 +32,51 @@ namespace Microsoft.eShopOnContainers.Services.Ordering.API.Controllers [HttpPut] [ProducesResponseType((int)HttpStatusCode.OK)] [ProducesResponseType((int)HttpStatusCode.BadRequest)] - public async Task CancelOrder([FromBody]CancelOrderCommand command, [FromHeader(Name = "x-requestid")] string requestId) + public async Task CancelOrderAsync([FromBody]CancelOrderCommand command, [FromHeader(Name = "x-requestid")] string requestId) { bool commandResult = false; + if (Guid.TryParse(requestId, out Guid guid) && guid != Guid.Empty) { var requestCancelOrder = new IdentifiedCommand(command, guid); commandResult = await _mediator.Send(requestCancelOrder); } - - return commandResult ? (IActionResult)Ok() : (IActionResult)BadRequest(); + if (!commandResult) + { + return BadRequest(); + } + + return Ok(); } [Route("ship")] [HttpPut] [ProducesResponseType((int)HttpStatusCode.OK)] [ProducesResponseType((int)HttpStatusCode.BadRequest)] - public async Task ShipOrder([FromBody]ShipOrderCommand command, [FromHeader(Name = "x-requestid")] string requestId) + public async Task ShipOrderAsync([FromBody]ShipOrderCommand command, [FromHeader(Name = "x-requestid")] string requestId) { bool commandResult = false; + if (Guid.TryParse(requestId, out Guid guid) && guid != Guid.Empty) { var requestShipOrder = new IdentifiedCommand(command, guid); commandResult = await _mediator.Send(requestShipOrder); } - return commandResult ? (IActionResult)Ok() : (IActionResult)BadRequest(); + if (!commandResult) + { + return BadRequest(); + } + return Ok(); } [Route("{orderId:int}")] [HttpGet] [ProducesResponseType(typeof(Order),(int)HttpStatusCode.OK)] [ProducesResponseType((int)HttpStatusCode.NotFound)] - public async Task GetOrder(int orderId) + public async Task GetOrderAsync(int orderId) { try { @@ -75,40 +84,37 @@ namespace Microsoft.eShopOnContainers.Services.Ordering.API.Controllers return Ok(order); } - catch (KeyNotFoundException) + catch { return NotFound(); } } - [Route("")] [HttpGet] [ProducesResponseType(typeof(IEnumerable), (int)HttpStatusCode.OK)] - public async Task>> GetOrders() + public async Task>> GetOrdersAsync() { var userid = _identityService.GetUserIdentity(); var orders = await _orderQueries.GetOrdersFromUserAsync(Guid.Parse(userid)); + return Ok(orders); } [Route("cardtypes")] [HttpGet] [ProducesResponseType(typeof(IEnumerable), (int)HttpStatusCode.OK)] - public async Task>> GetCardTypes() + public async Task>> GetCardTypesAsync() { - var cardTypes = await _orderQueries - .GetCardTypesAsync(); + var cardTypes = await _orderQueries.GetCardTypesAsync(); return Ok(cardTypes); - } + } [Route("draft")] [HttpPost] - public async Task> GetOrderDraftFromBasketData([FromBody] CreateOrderDraftCommand createOrderDraftCommand) + public async Task> CreateOrderDraftFromBasketDataAsync([FromBody] CreateOrderDraftCommand createOrderDraftCommand) { return await _mediator.Send(createOrderDraftCommand); } } -} - - +} \ No newline at end of file diff --git a/src/Services/Ordering/Ordering.UnitTests/Application/OrdersWebApiTest.cs b/src/Services/Ordering/Ordering.UnitTests/Application/OrdersWebApiTest.cs index 066a7078c..c5b8a1764 100644 --- a/src/Services/Ordering/Ordering.UnitTests/Application/OrdersWebApiTest.cs +++ b/src/Services/Ordering/Ordering.UnitTests/Application/OrdersWebApiTest.cs @@ -36,7 +36,7 @@ namespace UnitTest.Ordering.Application //Act var orderController = new OrdersController(_mediatorMock.Object, _orderQueriesMock.Object, _identityServiceMock.Object); - var actionResult = await orderController.CancelOrder(new CancelOrderCommand(1), Guid.NewGuid().ToString()) as OkResult; + var actionResult = await orderController.CancelOrderAsync(new CancelOrderCommand(1), Guid.NewGuid().ToString()) as OkResult; //Assert Assert.Equal(actionResult.StatusCode, (int)System.Net.HttpStatusCode.OK); @@ -52,7 +52,7 @@ namespace UnitTest.Ordering.Application //Act var orderController = new OrdersController(_mediatorMock.Object, _orderQueriesMock.Object, _identityServiceMock.Object); - var actionResult = await orderController.CancelOrder(new CancelOrderCommand(1), String.Empty) as BadRequestResult; + var actionResult = await orderController.CancelOrderAsync(new CancelOrderCommand(1), String.Empty) as BadRequestResult; //Assert Assert.Equal(actionResult.StatusCode, (int)System.Net.HttpStatusCode.BadRequest); @@ -67,7 +67,7 @@ namespace UnitTest.Ordering.Application //Act var orderController = new OrdersController(_mediatorMock.Object, _orderQueriesMock.Object, _identityServiceMock.Object); - var actionResult = await orderController.ShipOrder(new ShipOrderCommand(1), Guid.NewGuid().ToString()) as OkResult; + var actionResult = await orderController.ShipOrderAsync(new ShipOrderCommand(1), Guid.NewGuid().ToString()) as OkResult; //Assert Assert.Equal(actionResult.StatusCode, (int)System.Net.HttpStatusCode.OK); @@ -83,7 +83,7 @@ namespace UnitTest.Ordering.Application //Act var orderController = new OrdersController(_mediatorMock.Object, _orderQueriesMock.Object, _identityServiceMock.Object); - var actionResult = await orderController.ShipOrder(new ShipOrderCommand(1), String.Empty) as BadRequestResult; + var actionResult = await orderController.ShipOrderAsync(new ShipOrderCommand(1), String.Empty) as BadRequestResult; //Assert Assert.Equal(actionResult.StatusCode, (int)System.Net.HttpStatusCode.BadRequest); @@ -103,7 +103,7 @@ namespace UnitTest.Ordering.Application //Act var orderController = new OrdersController(_mediatorMock.Object, _orderQueriesMock.Object, _identityServiceMock.Object); - var actionResult = await orderController.GetOrders(); + var actionResult = await orderController.GetOrdersAsync(); //Assert Assert.Equal((actionResult.Result as OkObjectResult).StatusCode, (int)System.Net.HttpStatusCode.OK); @@ -120,7 +120,7 @@ namespace UnitTest.Ordering.Application //Act var orderController = new OrdersController(_mediatorMock.Object, _orderQueriesMock.Object, _identityServiceMock.Object); - var actionResult = await orderController.GetOrder(fakeOrderId) as OkObjectResult; + var actionResult = await orderController.GetOrderAsync(fakeOrderId) as OkObjectResult; //Assert Assert.Equal(actionResult.StatusCode, (int)System.Net.HttpStatusCode.OK); @@ -136,7 +136,7 @@ namespace UnitTest.Ordering.Application //Act var orderController = new OrdersController(_mediatorMock.Object, _orderQueriesMock.Object, _identityServiceMock.Object); - var actionResult = await orderController.GetCardTypes(); + var actionResult = await orderController.GetCardTypesAsync(); //Assert Assert.Equal((actionResult.Result as OkObjectResult).StatusCode, (int)System.Net.HttpStatusCode.OK);