Skip to content
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
70 changes: 0 additions & 70 deletions OrderProcessing.Api/BackgroundJobs/EmailBackgroundService.cs

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
using OrderProcessing.Api.Entities;
using OrderProcessing.Api.Exceptions;
using OrderProcessing.Api.Services.Auditing;
using OrderProcessing.Api.Services.Emailing;
using OrderProcessing.Api.Services.Outbox;
using OrderProcessing.Contracts.Orders;

Expand All @@ -16,20 +15,17 @@ public sealed class CompleteOrderCommandHandler
{
private readonly OrderProcessingDbContext _dbContext;
private readonly IAuditService _auditService;
private readonly IEmailQueue _emailQueue;
private readonly ILogger<CompleteOrderCommandHandler> _logger;
private readonly IOutboxWriter _outboxWriter;

public CompleteOrderCommandHandler(
OrderProcessingDbContext dbContext,
IAuditService auditService,
IEmailQueue emailQueue,
ILogger<CompleteOrderCommandHandler> logger,
IOutboxWriter outboxWriter)
{
_dbContext = dbContext;
_auditService = auditService;
_emailQueue = emailQueue;
_logger = logger;
_outboxWriter = outboxWriter;
}
Expand Down Expand Up @@ -88,85 +84,9 @@ public async Task<OrderResponse> Handle(

_logger.LogInformation( "Order {OrderId} completed", order.Id);

var emailMessage = CreateOrderCompletedEmail(order);

await TryEnqueueEmailAsync(
emailMessage,
order.Id,
cancellationToken);

return MapToResponse(order);
}

private static EmailMessage CreateOrderCompletedEmail(
Order order)
{
var customerName =
$"{order.Customer.FirstName} {order.Customer.LastName}";

var itemLines = order.Items.Select(item =>
$"- {item.ProductName}: {item.Quantity} × " +
$"{item.UnitPrice:F2} = {item.LineTotal:F2}");

var body = $"""
Hello {customerName},

Your order #{order.Id} has been completed successfully.

Items:
{string.Join(Environment.NewLine, itemLines)}

Total amount: {order.TotalAmount:F2}
Status: {order.Status}
Completed at: {order.CompletedAtUtc:yyyy-MM-dd HH:mm} UTC

Thank you.
""";

return new EmailMessage
{
To = order.Customer.Email,
Subject = $"Order #{order.Id} completed",
Body = body,
IsHtml = false
};
}

private async Task TryEnqueueEmailAsync(
EmailMessage message,
int orderId,
CancellationToken cancellationToken)
{
try
{
await _emailQueue.EnqueueAsync(
message,
cancellationToken);

_logger.LogInformation(
"Order-completed email queued. " +
"OrderId: {OrderId}, Recipient: {Recipient}",
orderId,
message.To);
}
catch (OperationCanceledException)
when (cancellationToken.IsCancellationRequested)
{
_logger.LogWarning(
"Order {OrderId} was completed, but email " +
"enqueueing was cancelled",
orderId);
}
catch (Exception exception)
{
_logger.LogError(
exception,
"Order {OrderId} was completed, but its email " +
"could not be queued",
orderId);
}
}

private static OrderResponse MapToResponse(Order order)
{
return new OrderResponse
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
using OrderProcessing.Api.Entities;
using OrderProcessing.Api.Exceptions;
using OrderProcessing.Api.Services.Auditing;
using OrderProcessing.Api.Services.Emailing;
using OrderProcessing.Api.Services.Outbox;
using OrderProcessing.Contracts.Orders;

Expand All @@ -15,20 +14,17 @@ public sealed class CreateOrderCommandHandler : IRequestHandler<CreateOrderComma
{
private readonly OrderProcessingDbContext _dbContext;
private readonly IAuditService _auditService;
private readonly IEmailQueue _emailQueue;
private readonly ILogger<CreateOrderCommandHandler> _logger;
private readonly IOutboxWriter _outboxWriter;

public CreateOrderCommandHandler(
OrderProcessingDbContext dbContext,
IAuditService auditService,
IEmailQueue emailQueue,
ILogger<CreateOrderCommandHandler> logger,
IOutboxWriter outboxWriter)
{
_dbContext = dbContext;
_auditService = auditService;
_emailQueue = emailQueue;
_logger = logger;
_outboxWriter = outboxWriter;
}
Expand Down Expand Up @@ -132,14 +128,6 @@ public async Task<OrderResponse> Handle(CreateOrderCommand command, Cancellation
order.CustomerId,
order.TotalAmount);

var emailMessage = CreateOrderCreatedEmail(order, customer);

await TryEnqueueEmailAsync(
emailMessage,
order.Id,
"Order Created",
cancellationToken);

return MapToResponse(order, $"{customer.FirstName} {customer.LastName}");
}
catch
Expand Down Expand Up @@ -273,71 +261,6 @@ private async Task<CustomerSummary> GetCustomerSummaryAsync(
?? throw new NotFoundException($"Customer with id {customerId} was not found.");
}

private static EmailMessage CreateOrderCreatedEmail(
Order order,
CustomerSummary customer)
{
var customerName = $"{customer.FirstName} {customer.LastName}";

var itemLines = order.Items.Select(item =>
$"- {item.ProductName}: {item.Quantity} × {item.UnitPrice:F2} = {item.LineTotal:F2}");

var body = $"""
Hello {customerName},

Your order #{order.Id} has been created successfully.

Items:
{string.Join(Environment.NewLine, itemLines)}

Total amount: {order.TotalAmount:F2}
Status: {order.Status}

Thank you.
""";

return new EmailMessage
{
To = customer.Email,
Subject = $"Order #{order.Id} created",
Body = body,
IsHtml = false
};
}

private async Task TryEnqueueEmailAsync(
EmailMessage message,
int orderId,
string emailType,
CancellationToken cancellationToken)
{
try
{
await _emailQueue.EnqueueAsync(message, cancellationToken);

_logger.LogInformation(
"{EmailType} email queued. OrderId: {OrderId}, Recipient: {Recipient}",
emailType,
orderId,
message.To);
}
catch (OperationCanceledException)
when (cancellationToken.IsCancellationRequested)
{
_logger.LogWarning(
"Order {OrderId} was saved, but enqueueing the {EmailType} email was cancelled",
orderId,
emailType);
}
catch (Exception exception)
{
_logger.LogError(
exception,
"Order {OrderId} was saved, but its {EmailType} email could not be queued",
orderId,
emailType);
}
}

private static OrderCreatedIntegrationEvent CreateOrderCreatedIntegrationEvent(Order order, CustomerSummary customer)
{
Expand Down
6 changes: 0 additions & 6 deletions OrderProcessing.Api/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
using OrderProcessing.Api.Extensions;
using OrderProcessing.Api.Services.Auditing;
using OrderProcessing.Api.Services.Customers;
using OrderProcessing.Api.Services.Emailing;
using OrderProcessing.Api.Services.Messaging;
using OrderProcessing.Api.Services.Outbox;
using OrderProcessing.Api.Services.Products;
Expand Down Expand Up @@ -42,11 +41,6 @@ public static async Task Main(string[] args)
//builder.Services.AddScoped<IOrderService, OrderService>();
builder.Services.AddScoped<IAuditService, AuditService>();
builder.Services.AddScoped<IOutboxWriter, OutboxWriter>();
builder.Services.AddScoped<IEmailSender, LoggingEmailSender>();
builder.Services.AddSingleton<IEmailQueue>(
_ => new EmailQueue(capacity: 100));

builder.Services.AddHostedService<EmailBackgroundService>();

if (!builder.Environment.IsEnvironment("Testing"))
{
Expand Down
12 changes: 0 additions & 12 deletions OrderProcessing.Api/Services/Emailing/EmailMessage.cs

This file was deleted.

38 changes: 0 additions & 38 deletions OrderProcessing.Api/Services/Emailing/EmailQueue.cs

This file was deleted.

11 changes: 0 additions & 11 deletions OrderProcessing.Api/Services/Emailing/IEmailQueue.cs

This file was deleted.

8 changes: 0 additions & 8 deletions OrderProcessing.Api/Services/Emailing/IEmailSender.cs

This file was deleted.

Loading