-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(QueueRentalAgreementRequest): Implement rental agreement request…
… queuing with AWS SQS integration - Add AwsSQSMessageBroker project for message queuing via AWS SQS. - Update init-localstack.sh to include rental agreement request queues for LocalStack setup. - Introduce new API endpoints in DeliveryDriverHttpApiAdapter for queuing rental agreement requests. - Expand application core with use cases and validators for rental agreement request processing. - Adjust DeliveryDriverRepository to support new rental management functionalities. - Add unit tests for rental agreement request validation and execution. This commit introduces the capability for delivery drivers to queue rental agreement requests, leveraging AWS SQS for asynchronous message processing. The changes include updates to the application core, adapters, and unit tests to ensure functionality and maintainability. #10
- Loading branch information
Showing
28 changed files
with
845 additions
and
54 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
17 changes: 17 additions & 0 deletions
17
.../Controllers/Rentals/QueueRentalAgreementRequest/V1/QueueRentalAgreementRequestRequest.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
namespace MotoDeliveryManager.Adapters.Inbound.DeliveryDriverHttpApiAdapter.Controllers.Rentals.QueueRentalAgreementRequest.V1; | ||
|
||
/// <summary> | ||
/// Represents the request to queue a rental agreement. | ||
/// </summary> | ||
/// <param name="DeliveryDriverId">The identifier of the delivery driver.</param> | ||
/// <param name="RentalPlanId">The identifier of the motorcycle rental plan.</param> | ||
/// <param name="ExpectedReturnDate">The expected return date of the motorcycle.</param> | ||
/// <remarks>It is used to request a rental agreement for a motorcycle.</remarks> | ||
public record QueueRentalAgreementRequestRequest( | ||
[Required] | ||
Guid DeliveryDriverId, | ||
[Required] | ||
Guid RentalPlanId, | ||
[Required] | ||
[DataType(DataType.Date)] | ||
DateOnly ExpectedReturnDate); |
8 changes: 8 additions & 0 deletions
8
...Controllers/Rentals/QueueRentalAgreementRequest/V1/QueueRentalAgreementRequestResponse.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
namespace MotoDeliveryManager.Adapters.Inbound.DeliveryDriverHttpApiAdapter.Controllers.Rentals.QueueRentalAgreementRequest.V1; | ||
|
||
/// <summary> | ||
/// Represents the response for a queued rental agreement request. | ||
/// </summary> | ||
/// <param name="RentalAgreementId"></param> | ||
/// <remarks>It is used to describe the outcome of a rental agreement request.</remarks> | ||
public record QueueRentalAgreementRequestResponse(Guid RentalAgreementId); |
86 changes: 86 additions & 0 deletions
86
...iverHttpApiAdapter/Controllers/Rentals/QueueRentalAgreementRequest/V1/RentalController.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,86 @@ | ||
namespace MotoDeliveryManager.Adapters.Inbound.DeliveryDriverHttpApiAdapter.Controllers.Rentals.QueueRentalAgreementRequest.V1; | ||
|
||
/// <summary> | ||
/// Represents the controller for the rental management endpoints. | ||
/// </summary> | ||
/// <remarks>It is used to queue a rental agreement request for a motorcycle.</remarks> | ||
/// <seealso cref="IQueueRentalAgreementRequestOutcomeHandler"/> | ||
/// <seealso cref="IQueueRentalAgreementRequestUseCase"/> | ||
[ApiController] | ||
[Route("api/v1/rentals")] | ||
[Produces("application/json")] | ||
[Consumes("application/json")] | ||
public sealed class RentalController(ILogger<RentalController> logger) | ||
: ControllerBase, IQueueRentalAgreementRequestOutcomeHandler | ||
{ | ||
private readonly ILogger<RentalController> _logger = logger; | ||
|
||
private IResult? _viewModel; | ||
|
||
void IQueueRentalAgreementRequestOutcomeHandler.RentalAgreementRequestNotQueued(IDictionary<string, string[]> errors) | ||
{ | ||
var message = "The rental agreement request was not queued."; | ||
var response = ApiResponse<ProblemDetails>.CreateValidationError(errors, HttpContext, message); | ||
_viewModel = Results.UnprocessableEntity(response); | ||
} | ||
|
||
void IQueueRentalAgreementRequestOutcomeHandler.RentalAgreementRequestNotValid(IDictionary<string, string[]> errors) | ||
{ | ||
var message = "The rental agreement request was not valid."; | ||
var response = ApiResponse<ProblemDetails>.CreateValidationError(errors, HttpContext, message); | ||
_viewModel = Results.BadRequest(response); | ||
} | ||
|
||
void IQueueRentalAgreementRequestOutcomeHandler.RentalAgreementRequestQueued(Guid rentalAgreementId) | ||
{ | ||
var message = "The rental agreement request was successfully queued."; | ||
var rentalAgreementResponse = new QueueRentalAgreementRequestResponse(rentalAgreementId); | ||
var response = ApiResponse<QueueRentalAgreementRequestResponse>.CreateSuccess(rentalAgreementResponse, message); | ||
_viewModel = Results.Accepted(string.Empty, response); | ||
} | ||
|
||
/// <summary> | ||
/// Queues a rental agreement request. | ||
/// </summary> | ||
/// <param name="request">The request to queue a rental agreement.</param> | ||
/// <param name="useCase">The use case to queue a rental agreement request.</param> | ||
/// <param name="cancellationToken">The token to monitor for cancellation requests.</param> | ||
/// <returns>The result of the rental agreement request queuing.</returns> | ||
/// <response code="202">The rental agreement request was successfully queued.</response> | ||
/// <response code="400">The rental agreement request was not valid.</response> | ||
/// <response code="422">The rental agreement request was not queued.</response> | ||
/// <remarks>It is used to queue a rental agreement request for a motorcycle.</remarks> | ||
/// <seealso cref="QueueRentalAgreementRequestRequest"/> | ||
/// <seealso cref="QueueRentalAgreementRequestResponse"/> | ||
/// <seealso cref="IQueueRentalAgreementRequestUseCase"/> | ||
/// <seealso cref="IQueueRentalAgreementRequestOutcomeHandler"/> | ||
/// <example> | ||
/// POST /api/v1/rentals/agreements/queue | ||
/// { | ||
/// "deliveryDriverId": "b3f3b3b3-3b3b-3b3b-3b3b-3b3b3b3b3b3b", | ||
/// "rentalPlanId": "b3f3b3b3-3b3b-3b3b-3b3b-3b3b3b3b3b3b", | ||
/// "expectedReturnDate: "2022-12-31" | ||
/// } | ||
/// </example> | ||
[HttpPost("agreements/queue", Name = "QueueRentalAgreementRequest")] | ||
[ProducesResponseType(typeof(ApiResponse<QueueRentalAgreementRequestResponse>), StatusCodes.Status202Accepted)] | ||
[ProducesResponseType(typeof(ApiResponse<ProblemDetails>), StatusCodes.Status400BadRequest)] | ||
[ProducesResponseType(typeof(ApiResponse<ProblemDetails>), StatusCodes.Status422UnprocessableEntity)] | ||
public async Task<IResult> QueueRentalAgreementRequestAsync( | ||
[FromBody] QueueRentalAgreementRequestRequest request, | ||
[FromKeyedServices(UseCaseType.Validation)] IQueueRentalAgreementRequestUseCase useCase, | ||
CancellationToken cancellationToken) | ||
{ | ||
useCase.SetOutcomeHandler(this); | ||
|
||
var inbound = new QueueRentalAgreementRequestInbound( | ||
Guid.NewGuid(), | ||
request.DeliveryDriverId, | ||
request.RentalPlanId, | ||
request.ExpectedReturnDate); | ||
|
||
await useCase.ExecuteAsync(inbound, cancellationToken); | ||
|
||
return _viewModel!; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
34 changes: 34 additions & 0 deletions
34
src/Adapters/Outbounds/AwsSQSMessageBroker/AwsSQSMessageBroker.csproj
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
<Project Sdk="Microsoft.NET.Sdk"> | ||
|
||
<PropertyGroup> | ||
<AssemblyName>MotoDeliveryManager.Adapters.Outbounds.AwsSQSMessageBroker</AssemblyName> | ||
<Description>The AwsS3StorageAdapter project is responsible for the implementation of the outbound ports of the application using the AWS SQS message broker.</Description> | ||
<ImplicitUsings>enable</ImplicitUsings> | ||
<LangVersion>12</LangVersion> | ||
<Nullable>enable</Nullable> | ||
<RootNamespace>MotoDeliveryManager.Adapters.Outbounds.AwsSQSMessageBroker</RootNamespace> | ||
<TargetFramework>net8.0</TargetFramework> | ||
<TreatWarningsAsErrors>true</TreatWarningsAsErrors> | ||
</PropertyGroup> | ||
|
||
<ItemGroup> | ||
<PackageReference Include="AWSSDK.Extensions.NETCore.Setup" Version="3.7.300" /> | ||
<PackageReference Include="AWSSDK.SQS" Version="3.7.300.60" /> | ||
</ItemGroup> | ||
|
||
<ItemGroup> | ||
<ProjectReference Include="..\..\..\Core\Application\Application.csproj" /> | ||
</ItemGroup> | ||
|
||
<ItemGroup> | ||
<Using Include="Amazon.SQS" /> | ||
<Using Include="Amazon.SQS.Model" /> | ||
<Using Include="Microsoft.Extensions.Configuration" /> | ||
<Using Include="Microsoft.Extensions.DependencyInjection" /> | ||
<Using Include="Microsoft.Extensions.Logging" /> | ||
<Using Include="MotoDeliveryManager.Core.Application.UseCases.Rentals.QueueRentalAgreementRequest.Inbounds" /> | ||
<Using Include="MotoDeliveryManager.Core.Application.UseCases.Rentals.QueueRentalAgreementRequest.Outbounds" /> | ||
<Using Include="System.Text.Json" /> | ||
</ItemGroup> | ||
|
||
</Project> |
48 changes: 48 additions & 0 deletions
48
src/Adapters/Outbounds/AwsSQSMessageBroker/SqsMessageProducer.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,48 @@ | ||
namespace MotoDeliveryManager.Adapters.Outbounds.AwsSQSMessageBroker; | ||
|
||
public class SqsMessageProducer(IAmazonSQS sqsClient, string queueUrl, ILogger<SqsMessageProducer> logger) | ||
: IQueueRentalAgreementRequestMessageBroker | ||
{ | ||
private const string SuccessMessage = "Rental Agreement Request with Id: {RentalAgreementRequestId} has been queued successfully. Message Id: {MessageId}, Queue Url: {QueueUrl}"; | ||
|
||
private const string ErrorMessage = "An error occurred while sending a message to SQS queue: {QueueUrl}. AWS Error Code: {ErrorCode}, Error Message: {ErrorMessage}"; | ||
|
||
private const string UnexpectedErrorMessage = "An unexpected error occurred while sending a message to SQS queue: {QueueUrl}"; | ||
|
||
private readonly IAmazonSQS _sqsClient = sqsClient; | ||
|
||
private readonly string _queueUrl = queueUrl; | ||
|
||
public readonly ILogger<SqsMessageProducer> _logger = logger; | ||
|
||
public async Task QueueRentalAgreementRequestAsync( | ||
QueueRentalAgreementRequestInbound rentalAgreementRequest, | ||
CancellationToken cancellationToken) | ||
{ | ||
try | ||
{ | ||
var messageBody = JsonSerializer.Serialize(rentalAgreementRequest); | ||
|
||
var sendMessageRequest = new SendMessageRequest | ||
{ | ||
QueueUrl = _queueUrl, | ||
MessageBody = messageBody | ||
}; | ||
|
||
var response = await _sqsClient.SendMessageAsync(sendMessageRequest); | ||
|
||
_logger.LogInformation(SuccessMessage, rentalAgreementRequest.RentalAgreementId, response.MessageId, _queueUrl); | ||
} | ||
catch (AmazonSQSException ex) | ||
{ | ||
_logger.LogError(ex, ErrorMessage, _queueUrl, ex.ErrorCode, ex.Message); | ||
throw; | ||
} | ||
catch (Exception ex) | ||
{ | ||
_logger.LogError(ex, UnexpectedErrorMessage, _queueUrl); | ||
throw; | ||
} | ||
} | ||
} | ||
|
Oops, something went wrong.