-
Notifications
You must be signed in to change notification settings - Fork 4
/
Copy pathCQRSValidationMiddleware.cs
56 lines (45 loc) · 1.97 KB
/
CQRSValidationMiddleware.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
using LeanCode.Contracts;
using LeanCode.CQRS.Execution;
using LeanCode.CQRS.Validation;
using LeanCode.Logging;
using LeanCode.OpenTelemetry;
using Microsoft.AspNetCore.Http;
namespace LeanCode.CQRS.AspNetCore.Middleware;
public class CQRSValidationMiddleware
{
private readonly ILogger<CQRSValidationMiddleware> logger;
private readonly CQRSMetrics metrics;
private readonly RequestDelegate next;
public CQRSValidationMiddleware(ILogger<CQRSValidationMiddleware> logger, CQRSMetrics metrics, RequestDelegate next)
{
this.logger = logger;
this.metrics = metrics;
this.next = next;
}
public async Task InvokeAsync(HttpContext httpContext, ICommandValidatorResolver resolver)
{
var cqrsMetadata = httpContext.GetCQRSObjectMetadata();
var payload = httpContext.GetCQRSRequestPayload();
if (cqrsMetadata.ObjectKind != CQRSObjectKind.Command)
{
throw new InvalidOperationException("CQRSValidationMiddleware may be used only for commands");
}
var validator = resolver.FindCommandValidator(cqrsMetadata.ObjectType);
if (validator is not null)
{
using var activity = LeanCodeActivitySource.StartMiddleware("Validation");
activity?.SetTag("validation.validator", validator.GetType().FullName);
var result = await validator.ValidateAsync(httpContext, (ICommand)payload.Payload);
activity?.SetTag("validation.valid", result.IsValid);
if (!result.IsValid)
{
logger.Warning("Command {@Command} is not valid with result {@Result}", payload.Payload, result);
var commandResult = CommandResult.NotValid(result);
payload.SetResult(ExecutionResult.WithPayload(commandResult, StatusCodes.Status422UnprocessableEntity));
metrics.CQRSFailure(CQRSMetrics.ValidationFailure);
return;
}
}
await next(httpContext);
}
}