Moved "AddItemToBasket" from MVC Client to a single call in PurchaseBFF
This commit is contained in:
parent
e59829e96b
commit
1c6431d503
@ -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
|
||||
|
@ -3,7 +3,7 @@
|
||||
"windowsAuthentication": false,
|
||||
"anonymousAuthentication": true,
|
||||
"iisExpress": {
|
||||
"applicationUrl": "http://localhost:64020/",
|
||||
"applicationUrl": "http://localhost:56755/",
|
||||
"sslPort": 0
|
||||
}
|
||||
},
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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": []
|
||||
|
@ -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; }
|
||||
|
@ -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();
|
||||
}
|
||||
|
@ -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<BasketService> _logger;
|
||||
private readonly UrlsConfig _urls;
|
||||
public BasketService(IHttpClient httpClient, ILogger<BasketService> logger, IOptionsSnapshot<UrlsConfig> config)
|
||||
private readonly IHttpContextAccessor _httpContextAccessor;
|
||||
|
||||
public BasketService(IHttpClient httpClient, IHttpContextAccessor httpContextAccessor, ILogger<BasketService> logger, IOptionsSnapshot<UrlsConfig> config)
|
||||
{
|
||||
_apiClient = httpClient;
|
||||
_logger = logger;
|
||||
_urls = config.Value;
|
||||
_httpContextAccessor = httpContextAccessor;
|
||||
}
|
||||
|
||||
public async Task<BasketData> 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<BasketData>(data);
|
||||
return basket;
|
||||
}
|
||||
|
||||
public async Task Update(BasketData currentBasket)
|
||||
{
|
||||
var token = await GetUserTokenAsync();
|
||||
var data = await _apiClient.PostAsync<BasketData>(_urls.Basket + UrlsConfig.BasketOperations.UpdateBasket(), currentBasket, token);
|
||||
int i = 0;
|
||||
}
|
||||
|
||||
async Task<string> GetUserTokenAsync()
|
||||
{
|
||||
var context = _httpContextAccessor.HttpContext;
|
||||
return await context.GetTokenAsync("access_token");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -9,5 +9,6 @@ namespace PurchaseBff.Services
|
||||
public interface IBasketService
|
||||
{
|
||||
Task<BasketData> GetById(string id);
|
||||
Task Update(BasketData currentBasket);
|
||||
}
|
||||
}
|
||||
|
@ -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 =>
|
||||
|
@ -3,7 +3,7 @@
|
||||
"windowsAuthentication": false,
|
||||
"anonymousAuthentication": true,
|
||||
"iisExpress": {
|
||||
"applicationUrl": "http://localhost:51078/",
|
||||
"applicationUrl": "http://localhost:56695/",
|
||||
"sslPort": 0
|
||||
}
|
||||
},
|
||||
|
@ -3,7 +3,7 @@
|
||||
"windowsAuthentication": false,
|
||||
"anonymousAuthentication": true,
|
||||
"iisExpress": {
|
||||
"applicationUrl": "http://localhost:55101",
|
||||
"applicationUrl": "http://localhost:56698/",
|
||||
"sslPort": 0
|
||||
}
|
||||
},
|
||||
|
@ -1,9 +1,9 @@
|
||||
{
|
||||
{
|
||||
"iisSettings": {
|
||||
"windowsAuthentication": false,
|
||||
"anonymousAuthentication": true,
|
||||
"iisExpress": {
|
||||
"applicationUrl": "http://localhost:3278/",
|
||||
"applicationUrl": "http://localhost:53933/",
|
||||
"sslPort": 0
|
||||
}
|
||||
},
|
||||
|
@ -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; }
|
||||
|
@ -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");
|
||||
}
|
||||
|
@ -4,27 +4,18 @@ namespace WebMVC.Infrastructure
|
||||
{
|
||||
public static class API
|
||||
{
|
||||
|
||||
public static class Purchase
|
||||
{
|
||||
public static string AddItemToBasket(string baseUri) => $"{baseUri}/basket/items";
|
||||
}
|
||||
|
||||
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 string CleanBasket(string baseUri, string basketId)
|
||||
{
|
||||
return $"{baseUri}/{basketId}";
|
||||
}
|
||||
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
|
||||
|
@ -14,14 +14,19 @@ namespace Microsoft.eShopOnContainers.WebMVC.Services
|
||||
public class BasketService : IBasketService
|
||||
{
|
||||
private readonly IOptionsSnapshot<AppSettings> _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<AppSettings> settings, IHttpContextAccessor httpContextAccesor, IHttpClient httpClient)
|
||||
private readonly string _bffUrl;
|
||||
|
||||
public BasketService(IOptionsSnapshot<AppSettings> 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,22 +109,19 @@ 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<BasketItem>()
|
||||
};
|
||||
}
|
||||
CatalogItemId = productId,
|
||||
BasketId = userId,
|
||||
Quantity = 1
|
||||
}, token);
|
||||
|
||||
basket.Items.Add(product);
|
||||
|
||||
await UpdateBasket(basket);
|
||||
}
|
||||
|
||||
async Task<string> GetUserTokenAsync()
|
||||
|
@ -10,7 +10,7 @@ namespace Microsoft.eShopOnContainers.WebMVC.Services
|
||||
public interface IBasketService
|
||||
{
|
||||
Task<Basket> GetBasket(ApplicationUser user);
|
||||
Task AddItemToBasket(ApplicationUser user, BasketItem product);
|
||||
Task AddItemToBasket(ApplicationUser user, int productId);
|
||||
Task<Basket> UpdateBasket(Basket basket);
|
||||
Task Checkout(BasketDTO basket);
|
||||
Task<Basket> SetQuantities(ApplicationUser user, Dictionary<string, int> quantities);
|
||||
|
@ -130,6 +130,7 @@ namespace Microsoft.eShopOnContainers.WebMVC
|
||||
options.Scope.Add("basket");
|
||||
options.Scope.Add("marketing");
|
||||
options.Scope.Add("locations");
|
||||
options.Scope.Add("purchasebff");
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -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; }
|
||||
|
@ -12,13 +12,5 @@
|
||||
<div class="esh-catalog-price">
|
||||
<span>@Model.Price.ToString("N2")</span>
|
||||
</div>
|
||||
<input type="hidden" asp-for="@Model.CatalogBrand" name="brand" />
|
||||
<input type="hidden" asp-for="@Model.CatalogBrandId" name="brandId" />
|
||||
<input type="hidden" asp-for="@Model.CatalogType" name="type" />
|
||||
<input type="hidden" asp-for="@Model.CatalogTypeId" name="typeId" />
|
||||
<input type="hidden" asp-for="@Model.Description" name="description" />
|
||||
<input type="hidden" asp-for="@Model.Id" name="id" />
|
||||
<input type="hidden" asp-for="@Model.Name" name="name" />
|
||||
<input type="hidden" asp-for="@Model.PictureUri" name="pictureUri" />
|
||||
<input type="hidden" asp-for="@Model.Price" name="price" />
|
||||
</form>
|
||||
|
@ -3,7 +3,7 @@
|
||||
"windowsAuthentication": false,
|
||||
"anonymousAuthentication": true,
|
||||
"iisExpress": {
|
||||
"applicationUrl": "http://localhost:5104/",
|
||||
"applicationUrl": "http://localhost:56727/",
|
||||
"sslPort": 0
|
||||
}
|
||||
},
|
||||
|
@ -92,7 +92,7 @@ namespace UnitTest.Basket.Application
|
||||
//Arrange
|
||||
var fakeCatalogItem = GetFakeCatalogItem();
|
||||
|
||||
_basketServiceMock.Setup(x => x.AddItemToBasket(It.IsAny<ApplicationUser>(), It.IsAny<BasketItem>()))
|
||||
_basketServiceMock.Setup(x => x.AddItemToBasket(It.IsAny<ApplicationUser>(), It.IsAny<Int32>()))
|
||||
.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",
|
||||
|
@ -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
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user