diff --git a/src/PublicApi/CatalogBrandEndpoints/CatalogBrandListEndpoint.cs b/src/PublicApi/CatalogBrandEndpoints/CatalogBrandListEndpoint.cs index dce823e..32b3d0b 100644 --- a/src/PublicApi/CatalogBrandEndpoints/CatalogBrandListEndpoint.cs +++ b/src/PublicApi/CatalogBrandEndpoints/CatalogBrandListEndpoint.cs @@ -13,9 +13,8 @@ namespace Microsoft.eShopWeb.PublicApi.CatalogBrandEndpoints; /// /// List Catalog Brands /// -public class CatalogBrandListEndpoint : IEndpoint +public class CatalogBrandListEndpoint : IEndpoint> { - private IRepository _catalogBrandRepository; private readonly IMapper _mapper; public CatalogBrandListEndpoint(IMapper mapper) @@ -28,18 +27,17 @@ public class CatalogBrandListEndpoint : IEndpoint app.MapGet("api/catalog-brands", async (IRepository catalogBrandRepository) => { - _catalogBrandRepository = catalogBrandRepository; - return await HandleAsync(); + return await HandleAsync(catalogBrandRepository); }) .Produces() .WithTags("CatalogBrandEndpoints"); } - public async Task HandleAsync() + public async Task HandleAsync(IRepository catalogBrandRepository) { var response = new ListCatalogBrandsResponse(); - var items = await _catalogBrandRepository.ListAsync(); + var items = await catalogBrandRepository.ListAsync(); response.CatalogBrands.AddRange(items.Select(_mapper.Map)); diff --git a/src/PublicApi/CatalogItemEndpoints/CatalogItemGetByIdEndpoint.cs b/src/PublicApi/CatalogItemEndpoints/CatalogItemGetByIdEndpoint.cs index a1f6011..9f15c72 100644 --- a/src/PublicApi/CatalogItemEndpoints/CatalogItemGetByIdEndpoint.cs +++ b/src/PublicApi/CatalogItemEndpoints/CatalogItemGetByIdEndpoint.cs @@ -11,9 +11,8 @@ namespace Microsoft.eShopWeb.PublicApi.CatalogItemEndpoints; /// /// Get a Catalog Item by Id /// -public class CatalogItemGetByIdEndpoint : IEndpoint +public class CatalogItemGetByIdEndpoint : IEndpoint> { - private IRepository _itemRepository; private readonly IUriComposer _uriComposer; public CatalogItemGetByIdEndpoint(IUriComposer uriComposer) @@ -26,18 +25,17 @@ public class CatalogItemGetByIdEndpoint : IEndpoint itemRepository) => { - _itemRepository = itemRepository; - return await HandleAsync(new GetByIdCatalogItemRequest(catalogItemId)); + return await HandleAsync(new GetByIdCatalogItemRequest(catalogItemId), itemRepository); }) .Produces() .WithTags("CatalogItemEndpoints"); } - public async Task HandleAsync(GetByIdCatalogItemRequest request) + public async Task HandleAsync(GetByIdCatalogItemRequest request, IRepository itemRepository) { var response = new GetByIdCatalogItemResponse(request.CorrelationId()); - var item = await _itemRepository.GetByIdAsync(request.CatalogItemId); + var item = await itemRepository.GetByIdAsync(request.CatalogItemId); if (item is null) return Results.NotFound(); diff --git a/src/PublicApi/CatalogItemEndpoints/CatalogItemListPagedEndpoint.cs b/src/PublicApi/CatalogItemEndpoints/CatalogItemListPagedEndpoint.cs index 308d310..920fe4f 100644 --- a/src/PublicApi/CatalogItemEndpoints/CatalogItemListPagedEndpoint.cs +++ b/src/PublicApi/CatalogItemEndpoints/CatalogItemListPagedEndpoint.cs @@ -15,9 +15,8 @@ namespace Microsoft.eShopWeb.PublicApi.CatalogItemEndpoints; /// /// List Catalog Items (paged) /// -public class CatalogItemListPagedEndpoint : IEndpoint +public class CatalogItemListPagedEndpoint : IEndpoint> { - private IRepository _itemRepository; private readonly IUriComposer _uriComposer; private readonly IMapper _mapper; @@ -32,19 +31,19 @@ public class CatalogItemListPagedEndpoint : IEndpoint itemRepository) => { - _itemRepository = itemRepository; - return await HandleAsync(new ListPagedCatalogItemRequest(pageSize, pageIndex, catalogBrandId, catalogTypeId)); - }) + return await HandleAsync(new ListPagedCatalogItemRequest(pageSize, pageIndex, catalogBrandId, catalogTypeId), itemRepository); + }) .Produces() .WithTags("CatalogItemEndpoints"); } - public async Task HandleAsync(ListPagedCatalogItemRequest request) + public async Task HandleAsync(ListPagedCatalogItemRequest request, IRepository itemRepository) { + await Task.Delay(1000); var response = new ListPagedCatalogItemResponse(request.CorrelationId()); var filterSpec = new CatalogFilterSpecification(request.CatalogBrandId, request.CatalogTypeId); - int totalItems = await _itemRepository.CountAsync(filterSpec); + int totalItems = await itemRepository.CountAsync(filterSpec); var pagedSpec = new CatalogFilterPaginatedSpecification( skip: request.PageIndex.Value * request.PageSize.Value, @@ -52,7 +51,7 @@ public class CatalogItemListPagedEndpoint : IEndpoint)); foreach (CatalogItemDto item in response.CatalogItems) diff --git a/src/PublicApi/CatalogItemEndpoints/CreateCatalogItemEndpoint.cs b/src/PublicApi/CatalogItemEndpoints/CreateCatalogItemEndpoint.cs index 25527f9..c15346f 100644 --- a/src/PublicApi/CatalogItemEndpoints/CreateCatalogItemEndpoint.cs +++ b/src/PublicApi/CatalogItemEndpoints/CreateCatalogItemEndpoint.cs @@ -15,9 +15,8 @@ namespace Microsoft.eShopWeb.PublicApi.CatalogItemEndpoints; /// /// Creates a new Catalog Item /// -public class CreateCatalogItemEndpoint : IEndpoint +public class CreateCatalogItemEndpoint : IEndpoint> { - private IRepository _itemRepository; private readonly IUriComposer _uriComposer; public CreateCatalogItemEndpoint(IUriComposer uriComposer) @@ -31,26 +30,25 @@ public class CreateCatalogItemEndpoint : IEndpoint itemRepository) => { - _itemRepository = itemRepository; - return await HandleAsync(request); + return await HandleAsync(request, itemRepository); }) .Produces() .WithTags("CatalogItemEndpoints"); } - public async Task HandleAsync(CreateCatalogItemRequest request) + public async Task HandleAsync(CreateCatalogItemRequest request, IRepository itemRepository) { var response = new CreateCatalogItemResponse(request.CorrelationId()); var catalogItemNameSpecification = new CatalogItemNameSpecification(request.Name); - var existingCataloogItem = await _itemRepository.CountAsync(catalogItemNameSpecification); + var existingCataloogItem = await itemRepository.CountAsync(catalogItemNameSpecification); if (existingCataloogItem > 0) { throw new DuplicateException($"A catalogItem with name {request.Name} already exists"); } var newItem = new CatalogItem(request.CatalogTypeId, request.CatalogBrandId, request.Description, request.Name, request.Price, request.PictureUri); - newItem = await _itemRepository.AddAsync(newItem); + newItem = await itemRepository.AddAsync(newItem); if (newItem.Id != 0) { @@ -59,7 +57,7 @@ public class CreateCatalogItemEndpoint : IEndpoint /// Deletes a Catalog Item /// -public class DeleteCatalogItemEndpoint : IEndpoint +public class DeleteCatalogItemEndpoint : IEndpoint> { - private IRepository _itemRepository; - public void AddRoute(IEndpointRouteBuilder app) { app.MapDelete("api/catalog-items/{catalogItemId}", [Authorize(Roles = BlazorShared.Authorization.Constants.Roles.ADMINISTRATORS, AuthenticationSchemes = JwtBearerDefaults.AuthenticationScheme)] async (int catalogItemId, IRepository itemRepository) => { - _itemRepository = itemRepository; - return await HandleAsync(new DeleteCatalogItemRequest(catalogItemId)); + return await HandleAsync(new DeleteCatalogItemRequest(catalogItemId), itemRepository); }) .Produces() .WithTags("CatalogItemEndpoints"); } - public async Task HandleAsync(DeleteCatalogItemRequest request) + public async Task HandleAsync(DeleteCatalogItemRequest request, IRepository itemRepository) { var response = new DeleteCatalogItemResponse(request.CorrelationId()); - var itemToDelete = await _itemRepository.GetByIdAsync(request.CatalogItemId); + var itemToDelete = await itemRepository.GetByIdAsync(request.CatalogItemId); if (itemToDelete is null) return Results.NotFound(); - await _itemRepository.DeleteAsync(itemToDelete); + await itemRepository.DeleteAsync(itemToDelete); return Results.Ok(response); } diff --git a/src/PublicApi/CatalogItemEndpoints/UpdateCatalogItemEndpoint.cs b/src/PublicApi/CatalogItemEndpoints/UpdateCatalogItemEndpoint.cs index 2ce0e6c..b923322 100644 --- a/src/PublicApi/CatalogItemEndpoints/UpdateCatalogItemEndpoint.cs +++ b/src/PublicApi/CatalogItemEndpoints/UpdateCatalogItemEndpoint.cs @@ -13,9 +13,8 @@ namespace Microsoft.eShopWeb.PublicApi.CatalogItemEndpoints; /// /// Updates a Catalog Item /// -public class UpdateCatalogItemEndpoint : IEndpoint -{ - private IRepository _itemRepository; +public class UpdateCatalogItemEndpoint : IEndpoint> +{ private readonly IUriComposer _uriComposer; public UpdateCatalogItemEndpoint(IUriComposer uriComposer) @@ -29,25 +28,24 @@ public class UpdateCatalogItemEndpoint : IEndpoint itemRepository) => { - _itemRepository = itemRepository; - return await HandleAsync(request); + return await HandleAsync(request, itemRepository); }) .Produces() .WithTags("CatalogItemEndpoints"); } - public async Task HandleAsync(UpdateCatalogItemRequest request) + public async Task HandleAsync(UpdateCatalogItemRequest request, IRepository itemRepository) { var response = new UpdateCatalogItemResponse(request.CorrelationId()); - var existingItem = await _itemRepository.GetByIdAsync(request.Id); - + var existingItem = await itemRepository.GetByIdAsync(request.Id); + CatalogItem.CatalogItemDetails details = new(request.Name, request.Description, request.Price); existingItem.UpdateDetails(details); existingItem.UpdateBrand(request.CatalogBrandId); existingItem.UpdateType(request.CatalogTypeId); - await _itemRepository.UpdateAsync(existingItem); + await itemRepository.UpdateAsync(existingItem); var dto = new CatalogItemDto { diff --git a/src/PublicApi/CatalogTypeEndpoints/CatalogTypeListEndpoint.cs b/src/PublicApi/CatalogTypeEndpoints/CatalogTypeListEndpoint.cs index 87aa035..3e36735 100644 --- a/src/PublicApi/CatalogTypeEndpoints/CatalogTypeListEndpoint.cs +++ b/src/PublicApi/CatalogTypeEndpoints/CatalogTypeListEndpoint.cs @@ -13,33 +13,31 @@ namespace Microsoft.eShopWeb.PublicApi.CatalogTypeEndpoints; /// /// List Catalog Types /// -public class CatalogTypeListEndpoint : IEndpoint +public class CatalogTypeListEndpoint : IEndpoint> { - private IRepository _catalogTypeRepository; private readonly IMapper _mapper; public CatalogTypeListEndpoint(IMapper mapper) - { + { _mapper = mapper; } public void AddRoute(IEndpointRouteBuilder app) { - app.MapGet("api/catalog-types", + app.MapGet("api/catalog-types", async (IRepository catalogTypeRepository) => { - _catalogTypeRepository = catalogTypeRepository; - return await HandleAsync(); + return await HandleAsync(catalogTypeRepository); }) .Produces() .WithTags("CatalogTypeEndpoints"); } - public async Task HandleAsync() + public async Task HandleAsync(IRepository catalogTypeRepository) { var response = new ListCatalogTypesResponse(); - var items = await _catalogTypeRepository.ListAsync(); + var items = await catalogTypeRepository.ListAsync(); response.CatalogTypes.AddRange(items.Select(_mapper.Map)); diff --git a/tests/PublicApiIntegrationTests/CatalogItemEndpoints/CatalogItemListPagedEndpoint.cs b/tests/PublicApiIntegrationTests/CatalogItemEndpoints/CatalogItemListPagedEndpoint.cs index 1040463..5eb3036 100644 --- a/tests/PublicApiIntegrationTests/CatalogItemEndpoints/CatalogItemListPagedEndpoint.cs +++ b/tests/PublicApiIntegrationTests/CatalogItemEndpoints/CatalogItemListPagedEndpoint.cs @@ -2,7 +2,10 @@ using Microsoft.eShopWeb.PublicApi.CatalogItemEndpoints; using Microsoft.eShopWeb.Web.ViewModels; using Microsoft.VisualStudio.TestTools.UnitTesting; +using System.Collections.Generic; using System.Linq; +using System.Net.Http; +using System.Net; using System.Threading.Tasks; namespace PublicApiIntegrationTests.CatalogItemEndpoints @@ -45,5 +48,26 @@ namespace PublicApiIntegrationTests.CatalogItemEndpoints Assert.AreEqual(totalExpected, model2.CatalogItems.Count()); } + + [DataTestMethod] + [DataRow("catalog-items")] + [DataRow("catalog-brands")] + [DataRow("catalog-types")] + [DataRow("catalog-items/1")] + public async Task SuccessFullMutipleParallelCall(string endpointName) + { + var client = ProgramTest.NewClient; + var tasks = new List>(); + + for (int i = 0; i < 100; i++) + { + var task = client.GetAsync($"/api/{endpointName}"); + tasks.Add(task); + } + await Task.WhenAll(tasks.ToList()); + var totalKO = tasks.Count(t => t.Result.StatusCode != HttpStatusCode.OK); + + Assert.AreEqual(0, totalKO); + } } }