Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Melhorias no desempenho. Teste de carga utilizando o k6 #20

Merged
merged 14 commits into from
Sep 17, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
49 changes: 29 additions & 20 deletions Blazing.Api/Controllers/Product/ProductController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,8 @@ namespace Blazing.Api.Controllers.Product
/// <remarks>
/// This class requires an instance of ILogger and IProductAppService to be passed in the constructor.
/// </remarks>
/// <typeparam name="_logger">The type of the logger.</typeparam>
/// <typeparam name="produtoRepository">The type of the product infrastructure service.</typeparam>
/// <parameter name="logger">The type of the logger.</parameter>
/// <parameter name="produtoRepository">The type of the product infrastructure service.</parameter>
[Route("api/[controller]")]
[ApiController]
public class ProductController(ILogger<ProductController> logger, IProductInfrastructureRepository produtoRepository) : ControllerBase
Expand All @@ -28,17 +28,20 @@ public class ProductController(ILogger<ProductController> logger, IProductInfras
/// Adds a list of new productsDto.
/// </summary>
/// <param name="newProductsDto">List of DTOs of productsDto to be added.</param>
/// <param name="cancellationToken"></param>
/// <returns>List of added productsDto.</returns>
[Authorize]
[HttpPost]
public async Task<ActionResult<IEnumerable<ProductDto>>> AddProducts([FromBody] IEnumerable<ProductDto> newProductsDto, CancellationToken cancellationToken)
public async Task<ActionResult<IEnumerable<ProductDto>>> AddProducts([FromBody] IEnumerable<ProductDto> newProductsDto,
CancellationToken cancellationToken)
{

var productAdded = await _productInfraRepository.AddProducts(newProductsDto, cancellationToken);
var productName = productAdded.Select(x => x.Name).ToList();

var productDto = productAdded.ToList();
var productName = productDto.Select(x => x.Name).ToList();

_logger.LogInformation("Produtos adicionados com sucesso. nomes dos produtos: {names}. Total de produtos: {TotalProducts}.",
productName, productAdded.Count());
productName, productDto.Count());

return Ok(productAdded); // Status 200
}
Expand All @@ -47,13 +50,14 @@ public async Task<ActionResult<IEnumerable<ProductDto>>> AddProducts([FromBody]
/// Edit an existing productDto.
/// </summary>
/// <param name="id">The identifier of the productDto to be edited.</param>
/// <param name="productDto">DTO with updated productDto data.</param>
/// <param name="updateProductDto">DTO with updated productDto data.</param>
/// <param name="cancellationToken"></param>
/// <returns>DTO of the edited product.</returns>
[Authorize]
[HttpPut("update")]
public async Task<ActionResult<IEnumerable<ProductDto>>> UpdateProduto([FromBody] IEnumerable<ProductDto> updateProductDto, CancellationToken cancellationToken)
public async Task<ActionResult<IEnumerable<ProductDto>>> UpdateProduto([FromQuery]IEnumerable<Guid> id,
[FromBody] IEnumerable<ProductDto> updateProductDto, CancellationToken cancellationToken)
{
var id = updateProductDto.Select(x => x.Id).ToList();
var productUpdated = await _productInfraRepository.UpdateProduct(id, updateProductDto, cancellationToken);

_logger.LogInformation("Produtos foram atualizados com sucesso utilizando os identificadores: {id}. Total de produtos editados: {TotalProducts}.",
Expand All @@ -65,29 +69,35 @@ public async Task<ActionResult<IEnumerable<ProductDto>>> UpdateProduto([FromBody
/// <summary>
/// Get productsDto from a specific categoryDto.
/// </summary>
/// <param name="page"></param>
/// <param name="pageSize"></param>
/// <param name="id">the identifier of categoryDto.</param>
/// <param name="cancellationToken"></param>
/// <returns>List of products in categoryDto.</returns>
[Authorize]
[HttpGet("categoryId")]
public async Task<ActionResult<IEnumerable<ProductDto?>>> GetProductsByCategoryId([FromQuery] IEnumerable<Guid> id, CancellationToken cancellationToken)
public async Task<ActionResult<IEnumerable<ProductDto?>>> GetProductsByCategoryId(int page, int pageSize, [FromQuery] IEnumerable<Guid> id, CancellationToken cancellationToken)
{
var produtcsCategories = await _productInfraRepository.GetProductsByCategoryId(id, cancellationToken);
if(pageSize > 50)
pageSize = 50;

var productsCategories = await _productInfraRepository.GetProductsByCategoryId(page, pageSize, id, cancellationToken);

_logger.LogInformation("Produtos recuperados com sucesso utilizando os identificadores de categoria: {id}. Total de produtos: {TotalProducts}.",
id, produtcsCategories.Count());
id, productsCategories.Count());

return Ok(produtcsCategories); // Status 200
return Ok(productsCategories); // Status 200
}


/// <summary>
/// Deletes a productDto list.
/// </summary>
/// <param name="id">List of productDto and the identifier to delete.</param>
/// <param name="cancellationToken"></param>
/// <returns>List of deleted productDto.</returns>
[Authorize]
[HttpDelete("delete")]
public async Task<ActionResult<IEnumerable<ProductDto>>> DeleteProducts([FromBody] IEnumerable<Guid> id, CancellationToken cancellationToken)
public async Task<ActionResult<IEnumerable<ProductDto>>> DeleteProducts([FromQuery] IEnumerable<Guid> id, CancellationToken cancellationToken)
{
var productsDeleted = await _productInfraRepository.DeleteProducts(id, cancellationToken);

Expand All @@ -101,10 +111,11 @@ public async Task<ActionResult<IEnumerable<ProductDto>>> DeleteProducts([FromBod
/// Gets a specific productDto by its identifier.
/// </summary>
/// <param name="id">the identifier of the productDto.</param>
/// <param name="cancellationToken"></param>
/// <returns>productDto.</returns>
[Authorize]
[HttpGet("id")]
public async Task<ActionResult<IEnumerable<ProductDto?>>> GetProductById([FromQuery]IEnumerable<Guid> id, CancellationToken cancellationToken)
public async Task<ActionResult<IEnumerable<ProductDto?>>> GetProductById([FromQuery] IEnumerable<Guid> id, CancellationToken cancellationToken)
{
var productsById = await _productInfraRepository.GetProductById(id, cancellationToken);

Expand All @@ -120,11 +131,10 @@ public async Task<ActionResult<IEnumerable<ProductDto>>> DeleteProducts([FromBod
/// <returns>List of product DTOs.</returns>
[Authorize]
[HttpGet]
public async Task<ActionResult<IEnumerable<ProductDto>>> GetAll([FromQuery]int page, int pageSize, CancellationToken cancellationToken)
public async Task<ActionResult<IEnumerable<ProductDto>>> GetAll([FromQuery] int page, int pageSize, CancellationToken cancellationToken)
{
if (pageSize > 50)
pageSize = 50;


var products = await _productInfraRepository.GetAll(page, pageSize, cancellationToken);

Expand All @@ -135,5 +145,4 @@ public async Task<ActionResult<IEnumerable<ProductDto>>> GetAll([FromQuery]int p
}
}
#endregion
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,14 @@ public static IServiceCollection AddConfigApi(
{
services.AddAutoMapper(typeof(BlazingProfile));

//Mapping product
services.AddScoped<ProductDtoMapping>();
services.AddScoped<ProductMapping>();

//Mapping category
services.AddScoped<CategoryDtoMapping>();
services.AddScoped<CategoryMapping>();

services.AddSwaggerGen();

return services;
Expand Down
89 changes: 46 additions & 43 deletions Blazing.Api/Middleware/ExceptionMiddleware.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
namespace Blazing.Api.Middleware
{
#region ExceptionsControllers

public class ExceptionMiddleware(RequestDelegate next, ILogger<ExceptionMiddleware> logger, IWebHostEnvironment env)
{
/// <summary>
Expand Down Expand Up @@ -92,9 +93,11 @@ private async Task HandleExceptionAsync(HttpContext context, DomainException ex,
/// <param name="ex">The domain exception.</param>
private async Task DetermineException(HttpContext context, DomainException ex)
{

switch (ex)
{
case DomainException.NotFoundException or DomainException.IdentityInvalidException:
case DomainException.NotFoundException:
case DomainException.IdentityInvalidException:
await HandleDomainException(context, ex);
break;
case ProductExceptions.ProductAlreadyExistsException:
Expand All @@ -103,22 +106,51 @@ private async Task DetermineException(HttpContext context, DomainException ex)
case ProductExceptions.ProductNotFoundException:
await HandleProductException(context, ex);
break;
case CategoryExceptions.CategoryAlreadyExistsException:
case CategoryExceptions.CategoryNotFoundException:
case CategoryExceptions.CategoryInvalidExceptions:
await HandleCategoryException(context, ex);
break;
case UserException.UserAlreadyExistsException:
case UserException.UserLockedOutException:
case UserException.IdentityAddUserException:
case UserException.UserInvalidException:
case UserException.UserNotFoundException:
await HandleUserException(context, ex);
break;
default:
{
if (ex is CategoryExceptions.CategoryAlreadyExistsException ||
ex is CategoryExceptions.CategoryNotFoundException ||
ex is CategoryExceptions.CategoryInvalidExceptions ||
ex is CategoryExceptions.CategoryInvalidExceptions)
await HandleCategoryException(context, ex);
else if (ex is UserException.UserAlreadyExistsException ||
ex is UserException.UserLockedOutException ||
ex is UserException.IdentityAddUserException ||
ex is UserException.UserInvalidException ||
ex is UserException.UserNotFoundException)
await HandleUserException(context, ex);
await HandleUserException(context, ex);
break;
}
}


}

/// <summary>
/// Handles a domain exception by setting the appropriate HTTP status code and logging the exception.
/// </summary>
/// <param name="context">The HTTP context of the request.</param>
/// <param name="ex">The domain exception to handle.</param>
/// <returns>A task representing the asynchronous operation.</returns>
private async Task HandleDomainException(HttpContext context, DomainException ex)
{
var message = string.Empty;
switch (ex)
{
case DomainException.NotFoundException:
context.Response.StatusCode = StatusCodes.Status404NotFound;
message = ex.Message;
logger.LogWarning("Ocorreu um aviso: {ErrorMessage}", ex.Message);
break;

case DomainException.IdentityInvalidException:
context.Response.StatusCode = StatusCodes.Status409Conflict;
message = ex.Message;
logger.LogWarning("Ocorreu um aviso: {ErrorMessage}", ex.Message);
break;
}

await HandleExceptionAsync(context, ex, message);
}

/// <summary>
Expand Down Expand Up @@ -237,35 +269,6 @@ private async Task HandleUserException(HttpContext context, DomainException ex)

await HandleExceptionAsync(context, ex, message);
}


/// <summary>
/// Handles a domain exception by setting the appropriate HTTP status code and logging the exception.
/// </summary>
/// <param name="context">The HTTP context of the request.</param>
/// <param name="ex">The domain exception to handle.</param>
/// <returns>A task representing the asynchronous operation.</returns>
private async Task HandleDomainException(HttpContext context, DomainException ex)
{
var message = string.Empty;
switch (ex)
{
case DomainException.NotFoundException:
context.Response.StatusCode = StatusCodes.Status404NotFound;
message = ex.Message;
logger.LogWarning("Ocorreu um aviso: {ErrorMessage}", ex.Message);
break;

case DomainException.IdentityInvalidException:
context.Response.StatusCode = StatusCodes.Status409Conflict;
message = ex.Message;
logger.LogWarning("Ocorreu um aviso: {ErrorMessage}", ex.Message);
break;
}

await HandleExceptionAsync(context, ex, message);
}

}
#endregion
}
2 changes: 1 addition & 1 deletion Blazing.Api/Properties/launchSettings.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
"launchBrowser": true,
"launchUrl": "swagger",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
"ASPNETCORE_ENVIRONMENT": "Production"
},
"dotnetRunMessages": true,
"applicationUrl": "https://192.168.0.2:7239;http://192.168.0.2:5244"
Expand Down
6 changes: 4 additions & 2 deletions Blazing.Application/Interface/Product/IProductAppService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,10 @@ public interface IProductAppService<T> where T : BaseEntityDto
/// </summary>
/// <param name="id">The ID of the categoryDto to retrieve productsDto from.</param>
/// <param name="productDto">The productsDto to be retrieved.</param>
/// <param name="cancellationToken"></param>
/// <returns>A task representing the asynchronous operation, with a collection of productsDto in the specified categoryDto.</returns>
Task<IEnumerable<ProductDto?>> GetProductsByCategoryId(IEnumerable<Guid> id, IEnumerable<ProductDto> productDto, CancellationToken cancellationToken);
Task<IEnumerable<ProductDto?>> GetProductsByCategoryId(IEnumerable<Guid> id,
IEnumerable<ProductDto?> productDto, CancellationToken cancellationToken);

/// <summary>
/// Deletes a collection of productsDto by their IDs.
Expand All @@ -49,7 +51,7 @@ public interface IProductAppService<T> where T : BaseEntityDto
/// Retrieves all productsDto.
/// </summary>
/// <returns>A task representing the asynchronous operation, with a collection of all productsDto.</returns>
Task<IEnumerable<ProductDto?>> GetAllProduct(IEnumerable<ProductDto> productDto, CancellationToken cancellationToken);
Task<IEnumerable<ProductDto?>> GetAllProduct(IEnumerable<ProductDto?> productDto, CancellationToken cancellationToken);

/// <summary>
/// checks the name to see if it already exists or not
Expand Down
34 changes: 34 additions & 0 deletions Blazing.Application/Mappings/CategoryDtoMapping.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Blazing.Application.Dto;
using Blazing.Domain.Entities;

namespace Blazing.Application.Mappings
{
public class CategoryDtoMapping
{
public virtual IEnumerable<CategoryDto> ReturnCategoryDto(IEnumerable<Category>? categories, CancellationToken cancellationToken)
{
var categoriesList = new List<CategoryDto>();
foreach (var category in categories)
{
cancellationToken.ThrowIfCancellationRequested();
var categoryDto = new CategoryDto
{
Id = category.Id,
Name = category.Name,
DataCreated = category.DataCreated,
DataDeleted = category.DataDeleted,
DataUpdated = category.DataUpdated
};

categoriesList.Add(categoryDto);
}

return categoriesList;
}
}
}
33 changes: 33 additions & 0 deletions Blazing.Application/Mappings/CategoryMapping.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
using Blazing.Application.Dto;
using Blazing.Domain.Entities;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Blazing.Application.Mappings
{
public class CategoryMapping
{
public virtual IEnumerable<Category> ReturnCategory(IEnumerable<CategoryDto> categories)
{
var categoriesList = new List<Category>();
foreach (var category in categories)
{
var categoryDto = new Category
{
Id = category.Id,
Name = category.Name,
DataCreated = category.DataCreated,
DataDeleted = category.DataDeleted,
DataUpdated = category.DataUpdated
};

categoriesList.Add(categoryDto);
}

return categoriesList;
}
}
}
Loading