diff --git a/Directory.Packages.props b/Directory.Packages.props
index afe03537..3f2d833d 100644
--- a/Directory.Packages.props
+++ b/Directory.Packages.props
@@ -16,7 +16,7 @@
-
+
diff --git a/TransactionProcessor.BusinessLogic/EventHandling/ReadModelDomainEventHandler.cs b/TransactionProcessor.BusinessLogic/EventHandling/ReadModelDomainEventHandler.cs
index 6cd7906f..6f9c2ffa 100644
--- a/TransactionProcessor.BusinessLogic/EventHandling/ReadModelDomainEventHandler.cs
+++ b/TransactionProcessor.BusinessLogic/EventHandling/ReadModelDomainEventHandler.cs
@@ -159,6 +159,7 @@ private Task HandleFileDomainEvent(IDomainEvent domainEvent,
FileProcessor.File.DomainEvents.FileLineProcessingSuccessfulEvent de => this.EstateReportingRepository.UpdateFileLine(de, cancellationToken),
FileProcessor.File.DomainEvents.FileLineProcessingFailedEvent de => this.EstateReportingRepository.UpdateFileLine(de, cancellationToken),
FileProcessor.File.DomainEvents.FileLineProcessingIgnoredEvent de => this.EstateReportingRepository.UpdateFileLine(de, cancellationToken),
+ FileProcessor.File.DomainEvents.FileLineTransactionDispatchFailedEvent de => this.EstateReportingRepository.UpdateFileLine(de, cancellationToken),
FileProcessor.File.DomainEvents.FileProcessingCompletedEvent de => this.EstateReportingRepository.UpdateFileAsComplete(de, cancellationToken),
_ => null
};
diff --git a/TransactionProcessor.Repository/ITransactionProcessorReadModelRepository.cs b/TransactionProcessor.Repository/ITransactionProcessorReadModelRepository.cs
index 0cd193bb..a9798ae2 100644
--- a/TransactionProcessor.Repository/ITransactionProcessorReadModelRepository.cs
+++ b/TransactionProcessor.Repository/ITransactionProcessorReadModelRepository.cs
@@ -182,6 +182,9 @@ Task UpdateFileAsComplete(FileProcessingCompletedEvent domainEvent,
Task UpdateFileLine(FileLineProcessingSuccessfulEvent domainEvent,
CancellationToken cancellationToken);
+
+ Task UpdateFileLine(FileLineTransactionDispatchFailedEvent domainEvent,
+ CancellationToken cancellationToken);
Task UpdateFileLine(FileLineProcessingFailedEvent domainEvent,
CancellationToken cancellationToken);
@@ -2052,6 +2055,19 @@ public async Task UpdateFileLine(FileLineProcessingSuccessfulEvent domai
cancellationToken);
}
+ public async Task UpdateFileLine(FileLineTransactionDispatchFailedEvent domainEvent,
+ CancellationToken cancellationToken) {
+ using ResolvedDbContext? resolvedContext = this.Resolver.Resolve(EstateManagementDatabaseName, domainEvent.EstateId.ToString());
+ await using EstateManagementContext context = resolvedContext.Context;
+
+ return await this.UpdateFileLineStatus(context,
+ domainEvent.FileId,
+ domainEvent.LineNumber,
+ Guid.Empty,
+ "D",
+ cancellationToken);
+ }
+
private async Task UpdateFileLineStatus(EstateManagementContext context,
Guid fileId,
Int32 lineNumber,
diff --git a/TransactionProcessor.Tests/ControllerTests/DomainEventControllerTests.cs b/TransactionProcessor.Tests/ControllerTests/DomainEventControllerTests.cs
index 00532a39..c8ec9a66 100644
--- a/TransactionProcessor.Tests/ControllerTests/DomainEventControllerTests.cs
+++ b/TransactionProcessor.Tests/ControllerTests/DomainEventControllerTests.cs
@@ -1,5 +1,6 @@
using Imposter.Abstractions;
using Microsoft.AspNetCore.Http;
+using Microsoft.AspNetCore.Http.HttpResults;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.DependencyInjection;
using Shouldly;
@@ -32,9 +33,9 @@ public async Task PostEventAsync_WhenAllHandlersSucceed_ReturnsOk()
domainEvent,
new ResultDomainEventHandler(Result.Success()));
- IActionResult result = await controller.PostEventAsync(domainEvent, CancellationToken.None);
-
- result.ShouldBeOfType();
+ IResult result = await controller.PostEventAsync(domainEvent, CancellationToken.None);
+
+ result.ShouldBeOfType();
}
[Fact]
@@ -44,9 +45,9 @@ public async Task PostEventAsync_WhenNoHandlersAreConfigured_ReturnsOk()
DomainEvent domainEvent = CreateDomainEvent();
DomainEventController controller = CreateController(domainEvent);
- IActionResult result = await controller.PostEventAsync(domainEvent, CancellationToken.None);
+ IResult result = await controller.PostEventAsync(domainEvent, CancellationToken.None);
- result.ShouldBeOfType();
+ result.ShouldBeOfType();
}
[Fact]
@@ -58,10 +59,10 @@ public async Task PostEventAsync_WhenHandlerReturnsFailure_ReturnsDetailedProble
DomainEventController controller = CreateController(domainEvent, handler);
- ObjectResult result = (ObjectResult)await controller.PostEventAsync(domainEvent, CancellationToken.None);
+ ProblemHttpResult result = (ProblemHttpResult)await controller.PostEventAsync(domainEvent, CancellationToken.None);
result.StatusCode.ShouldBe(500);
- ProblemDetails problemDetails = (ProblemDetails)result.Value;
+ var problemDetails = result.ProblemDetails;
problemDetails.Title.ShouldBe("One or more event handlers failed");
problemDetails.Status.ShouldBe(500);
problemDetails.Extensions["eventId"].ShouldBeOfType();
@@ -82,9 +83,9 @@ public async Task PostEventAsync_WhenMultipleHandlersFail_ReturnsEveryFailure()
new ResultDomainEventHandler(Result.Failure("First failure")),
new ThrowingDomainEventHandler("Second failure"));
- ObjectResult result = (ObjectResult)await controller.PostEventAsync(domainEvent, CancellationToken.None);
+ ProblemHttpResult result = (ProblemHttpResult)await controller.PostEventAsync(domainEvent, CancellationToken.None);
- String failuresJson = System.Text.Json.JsonSerializer.Serialize(((ProblemDetails)result.Value).Extensions["failures"]);
+ String failuresJson = System.Text.Json.JsonSerializer.Serialize(result.ProblemDetails.Extensions["failures"]);
result.StatusCode.ShouldBe(500);
failuresJson.ShouldContain("First failure");
failuresJson.ShouldContain("Second failure");
diff --git a/TransactionProcessor/Controllers/DomainEventController.cs b/TransactionProcessor/Controllers/DomainEventController.cs
index 62954d6e..715716bd 100644
--- a/TransactionProcessor/Controllers/DomainEventController.cs
+++ b/TransactionProcessor/Controllers/DomainEventController.cs
@@ -3,7 +3,11 @@
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
+using Microsoft.AspNetCore.Http;
+using Microsoft.AspNetCore.Http.HttpResults;
using Shared.Exceptions;
+using Shared.Results;
+using Shared.Results.Web;
namespace TransactionProcessor.Controllers
{
@@ -55,10 +59,15 @@ public DomainEventController(IDomainEventHandlerResolver domainEventHandlerResol
/// The cancellation token.
///
[HttpPost]
- public async Task PostEventAsync([FromBody] Object request,
+ public async Task PostEventAsync([FromBody] Object request,
CancellationToken cancellationToken)
{
- IDomainEvent domainEvent = await this.GetDomainEvent(request);
+ Result domainEventResult = await this.GetDomainEvent(request);
+
+ if (domainEventResult.IsFailed)
+ return ResponseFactory.FromResult(domainEventResult, SuccessFactory);
+
+ IDomainEvent domainEvent = domainEventResult.Data;
List eventHandlers = this.GetDomainEventHandlers(domainEvent);
@@ -72,7 +81,7 @@ public async Task PostEventAsync([FromBody] Object request,
{
// Log a warning out
Logger.LogInformation($"No event handlers configured for Event Type [{domainEvent.GetType().Name}]");
- return this.Ok();
+ return Results.Ok();
}
List executions = eventHandlers
@@ -91,7 +100,7 @@ public async Task PostEventAsync([FromBody] Object request,
List failures = executions.SelectMany(this.GetFailures).ToList();
if (failures.Any())
{
- return this.Problem(title: "One or more event handlers failed",
+ return Results.Problem(title: "One or more event handlers failed",
statusCode: 500,
extensions: new Dictionary
{
@@ -102,8 +111,8 @@ public async Task PostEventAsync([FromBody] Object request,
}
Logger.LogWarning($"Finished processing event - ID [{domainEvent.EventId}]");
-
- return this.Ok();
+
+ return Results.Ok();
}
catch (Exception ex)
{
@@ -114,6 +123,10 @@ public async Task PostEventAsync([FromBody] Object request,
}
}
+ private IDomainEvent SuccessFactory(IDomainEvent arg) {
+ return arg;
+ }
+
private void Callback(CancellationToken cancellationToken,
Guid eventId)
{
@@ -177,21 +190,29 @@ private List GetDomainEventHandlers(IDomainEvent domainEven
return eventHandlersResult.Data;
}
- private async Task GetDomainEvent(Object domainEvent)
+ private async Task> GetDomainEvent(Object domainEvent)
{
String eventType = this.Request.Headers["eventType"].ToString();
- Type type = TypeMap.GetType(eventType);
+ Type type;
+
+ try {
+ type = TypeMap.GetType(eventType);
+ }
+ catch (Exception ex) {
+ // Just swallowing exception here...
+ type = null;
+ }
if (type == null)
- throw new NotFoundException($"Failed to find a domain event with type {eventType}");
+ return Result.NotFound($"Failed to find a domain event with type {eventType}");
if (type.IsSubclassOf(typeof(DomainEvent)))
{
String json = StringSerialiser.Serialise(domainEvent);
DomainEventFactory domainEventFactory = new();
- return domainEventFactory.CreateDomainEvent(json, type);
+ return Result.Success(domainEventFactory.CreateDomainEvent(json, type) as IDomainEvent);
}
return null;
diff --git a/TransactionProcessor/appsettings.json b/TransactionProcessor/appsettings.json
index dfee7b24..a3b48483 100644
--- a/TransactionProcessor/appsettings.json
+++ b/TransactionProcessor/appsettings.json
@@ -94,7 +94,8 @@
"FileProcessingCompletedEvent",
"MerchantOpeningHoursUpdatedEvent",
"MerchantScheduleCreatedEvent",
- "MerchantScheduleMonthUpdatedEvent"
+ "MerchantScheduleMonthUpdatedEvent",
+ "FileLineTransactionDispatchFailedEvent"
]
},
"EventHandlerConfigurationDomain": {