From 1c6431d5032e798701dc90190b8ae1d259bed397 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Eduard=20Tom=C3=A0s?= Date: Wed, 31 Jan 2018 15:35:40 +0000 Subject: [PATCH] Moved "AddItemToBasket" from MVC Client to a single call in PurchaseBFF --- docker-compose.override.yml | 1 + .../Properties/launchSettings.json | 4 +-- src/Apigw/OcelotApiGw/Startup.cs | 9 +++++ .../configuration/configuration.json | 14 +++++++- src/BFFs/PurchaseBff/Config/UrlsConfig.cs | 1 + .../Controllers/BasketController.cs | 7 ++-- .../PurchaseBff/Services/BasketService.cs | 23 +++++++++++-- .../PurchaseBff/Services/IBasketService.cs | 1 + src/BFFs/PurchaseBff/Startup.cs | 6 ++++ .../Basket.API/Properties/launchSettings.json | 2 +- .../Properties/launchSettings.json | 2 +- .../Properties/launchSettings.json | 6 ++-- src/Web/WebMVC/AppSettings.cs | 2 ++ src/Web/WebMVC/Controllers/CartController.cs | 14 ++------ src/Web/WebMVC/Infrastructure/API.cs | 31 ++++++----------- src/Web/WebMVC/Services/BasketService.cs | 34 ++++++++++--------- src/Web/WebMVC/Services/IBasketService.cs | 2 +- src/Web/WebMVC/Startup.cs | 1 + src/Web/WebMVC/ViewModels/CatalogItem.cs | 2 +- src/Web/WebMVC/Views/Catalog/_product.cshtml | 8 ----- src/Web/WebSPA/Properties/launchSettings.json | 2 +- .../Basket/Application/CartControllerTest.cs | 4 +-- .../Application/CatalogControllerTest.cs | 6 ++-- 23 files changed, 106 insertions(+), 76 deletions(-) diff --git a/docker-compose.override.yml b/docker-compose.override.yml index 7a27451e2..4b4e3469b 100644 --- a/docker-compose.override.yml +++ b/docker-compose.override.yml @@ -137,6 +137,7 @@ services: - CatalogUrl=http://catalog.api - OrderingUrl=http://ordering.api - BasketUrl=http://basket.api + - PurchaseUrl=http://apigw/purchase-bff - LocationsUrl=http://locations.api - IdentityUrl=http://10.0.75.1:5105 # Local Mac: Use http://docker.for.mac.localhost:5105 || Local Windows: Use 10.0.75.1 in a "Docker for Windows" environment, if using "localhost" from browser. || #Remote access: Use ${ESHOP_EXTERNAL_DNS_NAME_OR_IP} if using external IP or DNS name from browser. - MarketingUrl=http://marketing.api diff --git a/src/Apigw/OcelotApiGw/Properties/launchSettings.json b/src/Apigw/OcelotApiGw/Properties/launchSettings.json index 796011a33..2308ca466 100644 --- a/src/Apigw/OcelotApiGw/Properties/launchSettings.json +++ b/src/Apigw/OcelotApiGw/Properties/launchSettings.json @@ -3,7 +3,7 @@ "windowsAuthentication": false, "anonymousAuthentication": true, "iisExpress": { - "applicationUrl": "http://localhost:64020/", + "applicationUrl": "http://localhost:56755/", "sslPort": 0 } }, @@ -24,4 +24,4 @@ "applicationUrl": "http://localhost:64021/" } } -} +} \ No newline at end of file diff --git a/src/Apigw/OcelotApiGw/Startup.cs b/src/Apigw/OcelotApiGw/Startup.cs index fa20572b2..9c7eb18ef 100644 --- a/src/Apigw/OcelotApiGw/Startup.cs +++ b/src/Apigw/OcelotApiGw/Startup.cs @@ -41,6 +41,15 @@ namespace OcelotApiGw x.Events = new Microsoft.AspNetCore.Authentication.JwtBearer.JwtBearerEvents() { OnAuthenticationFailed = async ctx => + { + int i = 0; + }, + OnTokenValidated = async ctx => + { + int i = 0; + }, + + OnMessageReceived = async ctx => { int i = 0; } diff --git a/src/Apigw/OcelotApiGw/configuration/configuration.json b/src/Apigw/OcelotApiGw/configuration/configuration.json index 4aa756512..2e95c8843 100644 --- a/src/Apigw/OcelotApiGw/configuration/configuration.json +++ b/src/Apigw/OcelotApiGw/configuration/configuration.json @@ -8,13 +8,25 @@ "UpstreamPathTemplate": "/purchase-bff/catalog/{everything}", "UpstreamHttpMethod": [ "GET" ] }, + { + "DownstreamPathTemplate": "/{everything}", + "DownstreamScheme": "http", + "DownstreamHost": "basket.api", + "DownstreamPort": 80, + "UpstreamPathTemplate": "/purchase-bff/basket/{everything}", + "UpstreamHttpMethod": [ "GET" ], + "AuthenticationOptions": { + "AuthenticationProviderKey": "IdentityApiKey", + "AllowedScopes": [] + } + }, { "DownstreamPathTemplate": "/{everything}", "DownstreamScheme": "http", "DownstreamHost": "purchasebff", "DownstreamPort": 80, "UpstreamPathTemplate": "/purchase-bff/{everything}", - "UpstreamHttpMethod": [], + "UpstreamHttpMethod": ["POST"], "AuthenticationOptions": { "AuthenticationProviderKey": "IdentityApiKey", "AllowedScopes": [] diff --git a/src/BFFs/PurchaseBff/Config/UrlsConfig.cs b/src/BFFs/PurchaseBff/Config/UrlsConfig.cs index 5c43bdfa7..2079a4615 100644 --- a/src/BFFs/PurchaseBff/Config/UrlsConfig.cs +++ b/src/BFFs/PurchaseBff/Config/UrlsConfig.cs @@ -15,6 +15,7 @@ namespace PurchaseBff.Config public class BasketOperations { public static string GetItemById(string id) => $"/api/v1/basket/{id}"; + public static string UpdateBasket() => $"/api/v1/basket"; } public string Basket { get; set; } diff --git a/src/BFFs/PurchaseBff/Controllers/BasketController.cs b/src/BFFs/PurchaseBff/Controllers/BasketController.cs index 6886ec806..6030dfadb 100644 --- a/src/BFFs/PurchaseBff/Controllers/BasketController.cs +++ b/src/BFFs/PurchaseBff/Controllers/BasketController.cs @@ -32,20 +32,21 @@ namespace PurchaseBff.Controllers // Step 1: Get the item from catalog var item = await _catalog.GetCatalogItem(data.CatalogItemId); // Step 2: Get current basket status - var currentBasket = await _basket.GetById(data.BasketId); + var currentBasket = (await _basket.GetById(data.BasketId)) ?? new BasketData(data.BasketId); // Step 3: Merge current status with new product currentBasket.Items.Add(new BasketDataItem() { - OldUnitPrice = item.Price, UnitPrice = item.Price, PictureUrl = item.PictureUri, ProductId = item.Id.ToString(), ProductName = item.Name, Quantity = data.Quantity, - Id = item.Id.ToString() + Id = Guid.NewGuid().ToString() }); // Step 4: Update basket + await _basket.Update(currentBasket); + return Ok(); } diff --git a/src/BFFs/PurchaseBff/Services/BasketService.cs b/src/BFFs/PurchaseBff/Services/BasketService.cs index 023f587aa..881718baf 100644 --- a/src/BFFs/PurchaseBff/Services/BasketService.cs +++ b/src/BFFs/PurchaseBff/Services/BasketService.cs @@ -2,6 +2,8 @@ using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; +using Microsoft.AspNetCore.Authentication; +using Microsoft.AspNetCore.Http; using Microsoft.eShopOnContainers.BuildingBlocks.Resilience.Http; using Microsoft.Extensions.Logging; using Microsoft.Extensions.Options; @@ -17,18 +19,35 @@ namespace PurchaseBff.Services private readonly IHttpClient _apiClient; private readonly ILogger _logger; private readonly UrlsConfig _urls; - public BasketService(IHttpClient httpClient, ILogger logger, IOptionsSnapshot config) + private readonly IHttpContextAccessor _httpContextAccessor; + + public BasketService(IHttpClient httpClient, IHttpContextAccessor httpContextAccessor, ILogger logger, IOptionsSnapshot config) { _apiClient = httpClient; _logger = logger; _urls = config.Value; + _httpContextAccessor = httpContextAccessor; } public async Task GetById(string id) { - var data = await _apiClient.GetStringAsync(_urls.Basket + UrlsConfig.BasketOperations.GetItemById(id)); + var token = await GetUserTokenAsync(); + var data = await _apiClient.GetStringAsync(_urls.Basket + UrlsConfig.BasketOperations.GetItemById(id), token); var basket = JsonConvert.DeserializeObject(data); return basket; } + + public async Task Update(BasketData currentBasket) + { + var token = await GetUserTokenAsync(); + var data = await _apiClient.PostAsync(_urls.Basket + UrlsConfig.BasketOperations.UpdateBasket(), currentBasket, token); + int i = 0; + } + + async Task GetUserTokenAsync() + { + var context = _httpContextAccessor.HttpContext; + return await context.GetTokenAsync("access_token"); + } } } diff --git a/src/BFFs/PurchaseBff/Services/IBasketService.cs b/src/BFFs/PurchaseBff/Services/IBasketService.cs index b4bafc461..0c33c5c41 100644 --- a/src/BFFs/PurchaseBff/Services/IBasketService.cs +++ b/src/BFFs/PurchaseBff/Services/IBasketService.cs @@ -9,5 +9,6 @@ namespace PurchaseBff.Services public interface IBasketService { Task GetById(string id); + Task Update(BasketData currentBasket); } } diff --git a/src/BFFs/PurchaseBff/Startup.cs b/src/BFFs/PurchaseBff/Startup.cs index 07a3f4f71..13fdcc269 100644 --- a/src/BFFs/PurchaseBff/Startup.cs +++ b/src/BFFs/PurchaseBff/Startup.cs @@ -92,6 +92,10 @@ namespace PurchaseBff options.Events = new JwtBearerEvents() { OnAuthenticationFailed = async ctx => + { + int i = 0; + }, + OnTokenValidated = async ctx => { int i = 0; } @@ -117,6 +121,8 @@ namespace PurchaseBff app.UseDeveloperExceptionPage(); } + app.UseAuthentication(); + app.UseMvc(); app.UseSwagger().UseSwaggerUI(c => diff --git a/src/Services/Basket/Basket.API/Properties/launchSettings.json b/src/Services/Basket/Basket.API/Properties/launchSettings.json index e42e4f7d1..0045edd47 100644 --- a/src/Services/Basket/Basket.API/Properties/launchSettings.json +++ b/src/Services/Basket/Basket.API/Properties/launchSettings.json @@ -3,7 +3,7 @@ "windowsAuthentication": false, "anonymousAuthentication": true, "iisExpress": { - "applicationUrl": "http://localhost:51078/", + "applicationUrl": "http://localhost:56695/", "sslPort": 0 } }, diff --git a/src/Services/Catalog/Catalog.API/Properties/launchSettings.json b/src/Services/Catalog/Catalog.API/Properties/launchSettings.json index 0357943bb..28f08bad2 100644 --- a/src/Services/Catalog/Catalog.API/Properties/launchSettings.json +++ b/src/Services/Catalog/Catalog.API/Properties/launchSettings.json @@ -3,7 +3,7 @@ "windowsAuthentication": false, "anonymousAuthentication": true, "iisExpress": { - "applicationUrl": "http://localhost:55101", + "applicationUrl": "http://localhost:56698/", "sslPort": 0 } }, diff --git a/src/Services/Location/Locations.API/Properties/launchSettings.json b/src/Services/Location/Locations.API/Properties/launchSettings.json index 45b637914..6401e4bbe 100644 --- a/src/Services/Location/Locations.API/Properties/launchSettings.json +++ b/src/Services/Location/Locations.API/Properties/launchSettings.json @@ -1,9 +1,9 @@ -{ +{ "iisSettings": { "windowsAuthentication": false, "anonymousAuthentication": true, "iisExpress": { - "applicationUrl": "http://localhost:3278/", + "applicationUrl": "http://localhost:53933/", "sslPort": 0 } }, @@ -26,4 +26,4 @@ "applicationUrl": "http://localhost:3279" } } -} +} \ No newline at end of file diff --git a/src/Web/WebMVC/AppSettings.cs b/src/Web/WebMVC/AppSettings.cs index 42100ab62..18db7d4bf 100644 --- a/src/Web/WebMVC/AppSettings.cs +++ b/src/Web/WebMVC/AppSettings.cs @@ -13,6 +13,8 @@ namespace Microsoft.eShopOnContainers.WebMVC public string BasketUrl { get; set; } public string MarketingUrl { get; set; } public string LocationsUrl { get; set; } + + public string PurchaseUrl { get; set; } public bool ActivateCampaignDetailFunction { get; set; } public Logging Logging { get; set; } public bool UseCustomizationData { get; set; } diff --git a/src/Web/WebMVC/Controllers/CartController.cs b/src/Web/WebMVC/Controllers/CartController.cs index 8b41c5320..94f50a2de 100644 --- a/src/Web/WebMVC/Controllers/CartController.cs +++ b/src/Web/WebMVC/Controllers/CartController.cs @@ -70,19 +70,11 @@ namespace Microsoft.eShopOnContainers.WebMVC.Controllers { try { - if (productDetails.Id != null) + if (productDetails?.Id != null) { var user = _appUserParser.Parse(HttpContext.User); - var product = new BasketItem() - { - Id = Guid.NewGuid().ToString(), - Quantity = 1, - ProductName = productDetails.Name, - PictureUrl = productDetails.PictureUri, - UnitPrice = productDetails.Price, - ProductId = productDetails.Id - }; - await _basketSvc.AddItemToBasket(user, product); + await _basketSvc.AddItemToBasket(user, productDetails.Id); + //await _basketSvc.AddItemToBasket(user, product); } return RedirectToAction("Index", "Catalog"); } diff --git a/src/Web/WebMVC/Infrastructure/API.cs b/src/Web/WebMVC/Infrastructure/API.cs index edb2c5ed5..b59183512 100644 --- a/src/Web/WebMVC/Infrastructure/API.cs +++ b/src/Web/WebMVC/Infrastructure/API.cs @@ -4,27 +4,18 @@ namespace WebMVC.Infrastructure { public static class API { - public static class Basket - { - public static string GetBasket(string baseUri, string basketId) - { - return $"{baseUri}/{basketId}"; - } - public static string UpdateBasket(string baseUri) - { - return baseUri; - } - - public static string CheckoutBasket(string baseUri) - { - return $"{baseUri}/checkout"; - } + public static class Purchase + { + public static string AddItemToBasket(string baseUri) => $"{baseUri}/basket/items"; + } - public static string CleanBasket(string baseUri, string basketId) - { - return $"{baseUri}/{basketId}"; - } + public static class Basket + { + public static string GetBasket(string baseUri, string basketId) => $"{baseUri}/{basketId}"; + public static string UpdateBasket(string baseUri) => baseUri; + public static string CheckoutBasket(string baseUri) => $"{baseUri}/checkout"; + public static string CleanBasket(string baseUri, string basketId) => $"{baseUri}/{basketId}"; } public static class Order @@ -100,7 +91,7 @@ namespace WebMVC.Infrastructure public static string CreateOrUpdateUserLocation(string baseUri) { return baseUri; - } + } } } } \ No newline at end of file diff --git a/src/Web/WebMVC/Services/BasketService.cs b/src/Web/WebMVC/Services/BasketService.cs index 6c8524800..e167f73cc 100644 --- a/src/Web/WebMVC/Services/BasketService.cs +++ b/src/Web/WebMVC/Services/BasketService.cs @@ -14,14 +14,19 @@ namespace Microsoft.eShopOnContainers.WebMVC.Services public class BasketService : IBasketService { private readonly IOptionsSnapshot _settings; - private IHttpClient _apiClient; + private readonly IHttpClient _apiClient; private readonly string _remoteServiceBaseUrl; - private IHttpContextAccessor _httpContextAccesor; + private readonly string _purchaseUrl; + private readonly IHttpContextAccessor _httpContextAccesor; - public BasketService(IOptionsSnapshot settings, IHttpContextAccessor httpContextAccesor, IHttpClient httpClient) + private readonly string _bffUrl; + + public BasketService(IOptionsSnapshot settings, + IHttpContextAccessor httpContextAccesor, IHttpClient httpClient) { _settings = settings; _remoteServiceBaseUrl = $"{_settings.Value.BasketUrl}/api/v1/basket"; + _purchaseUrl = $"{_settings.Value.PurchaseUrl}/api/v1"; _httpContextAccesor = httpContextAccesor; _apiClient = httpClient; } @@ -104,23 +109,20 @@ namespace Microsoft.eShopOnContainers.WebMVC.Services return order; } - public async Task AddItemToBasket(ApplicationUser user, BasketItem product) + public async Task AddItemToBasket(ApplicationUser user, int productId) { - var basket = await GetBasket(user); + var token = await GetUserTokenAsync(); + var updateBasketUri = API.Purchase.AddItemToBasket(_purchaseUrl); + var userId = user.Id; - if (basket == null) + var response = await _apiClient.PostAsync(updateBasketUri, new { - basket = new Basket() - { - BuyerId = user.Id, - Items = new List() - }; - } - - basket.Items.Add(product); + CatalogItemId = productId, + BasketId = userId, + Quantity = 1 + }, token); - await UpdateBasket(basket); - } + } async Task GetUserTokenAsync() { diff --git a/src/Web/WebMVC/Services/IBasketService.cs b/src/Web/WebMVC/Services/IBasketService.cs index 13921909a..78898de7d 100644 --- a/src/Web/WebMVC/Services/IBasketService.cs +++ b/src/Web/WebMVC/Services/IBasketService.cs @@ -10,7 +10,7 @@ namespace Microsoft.eShopOnContainers.WebMVC.Services public interface IBasketService { Task GetBasket(ApplicationUser user); - Task AddItemToBasket(ApplicationUser user, BasketItem product); + Task AddItemToBasket(ApplicationUser user, int productId); Task UpdateBasket(Basket basket); Task Checkout(BasketDTO basket); Task SetQuantities(ApplicationUser user, Dictionary quantities); diff --git a/src/Web/WebMVC/Startup.cs b/src/Web/WebMVC/Startup.cs index ced47ea67..e9e86d1cd 100644 --- a/src/Web/WebMVC/Startup.cs +++ b/src/Web/WebMVC/Startup.cs @@ -130,6 +130,7 @@ namespace Microsoft.eShopOnContainers.WebMVC options.Scope.Add("basket"); options.Scope.Add("marketing"); options.Scope.Add("locations"); + options.Scope.Add("purchasebff"); }); } diff --git a/src/Web/WebMVC/ViewModels/CatalogItem.cs b/src/Web/WebMVC/ViewModels/CatalogItem.cs index 6dd216d1d..c869b7382 100644 --- a/src/Web/WebMVC/ViewModels/CatalogItem.cs +++ b/src/Web/WebMVC/ViewModels/CatalogItem.cs @@ -4,7 +4,7 @@ namespace Microsoft.eShopOnContainers.WebMVC.ViewModels { public class CatalogItem { - public string Id { get; set; } + public int Id { get; set; } public string Name { get; set; } public string Description { get; set; } public decimal Price { get; set; } diff --git a/src/Web/WebMVC/Views/Catalog/_product.cshtml b/src/Web/WebMVC/Views/Catalog/_product.cshtml index 11138b55d..0fb1c39c4 100644 --- a/src/Web/WebMVC/Views/Catalog/_product.cshtml +++ b/src/Web/WebMVC/Views/Catalog/_product.cshtml @@ -12,13 +12,5 @@
@Model.Price.ToString("N2")
- - - - - - - - diff --git a/src/Web/WebSPA/Properties/launchSettings.json b/src/Web/WebSPA/Properties/launchSettings.json index fd33f59ec..9be3bf34a 100644 --- a/src/Web/WebSPA/Properties/launchSettings.json +++ b/src/Web/WebSPA/Properties/launchSettings.json @@ -3,7 +3,7 @@ "windowsAuthentication": false, "anonymousAuthentication": true, "iisExpress": { - "applicationUrl": "http://localhost:5104/", + "applicationUrl": "http://localhost:56727/", "sslPort": 0 } }, diff --git a/test/Services/UnitTest/Basket/Application/CartControllerTest.cs b/test/Services/UnitTest/Basket/Application/CartControllerTest.cs index 6bdd2c43c..63f74cf35 100644 --- a/test/Services/UnitTest/Basket/Application/CartControllerTest.cs +++ b/test/Services/UnitTest/Basket/Application/CartControllerTest.cs @@ -92,7 +92,7 @@ namespace UnitTest.Basket.Application //Arrange var fakeCatalogItem = GetFakeCatalogItem(); - _basketServiceMock.Setup(x => x.AddItemToBasket(It.IsAny(), It.IsAny())) + _basketServiceMock.Setup(x => x.AddItemToBasket(It.IsAny(), It.IsAny())) .Returns(Task.FromResult(1)); //Act @@ -118,7 +118,7 @@ namespace UnitTest.Basket.Application { return new CatalogItem() { - Id = "1", + Id = 1, Name = "fakeName", CatalogBrand = "fakeBrand", CatalogType = "fakeType", diff --git a/test/Services/UnitTest/Catalog/Application/CatalogControllerTest.cs b/test/Services/UnitTest/Catalog/Application/CatalogControllerTest.cs index 58d32c212..7410551e4 100644 --- a/test/Services/UnitTest/Catalog/Application/CatalogControllerTest.cs +++ b/test/Services/UnitTest/Catalog/Application/CatalogControllerTest.cs @@ -67,19 +67,19 @@ namespace UnitTest.Catalog.Application { new CatalogItem() { - Id = "1", + Id = 1, Name = "fakeItemA", CatalogTypeId = 1 }, new CatalogItem() { - Id = "2", + Id = 2, Name = "fakeItemB", CatalogTypeId = 1 }, new CatalogItem() { - Id = "3", + Id = 3, Name = "fakeItemC", CatalogTypeId = 1 }