diff --git a/src/BuildingRegistry.Api.BackOffice.Abstractions/Building/Requests/CreateBuildingOsloSnapshotsRequest.cs b/src/BuildingRegistry.Api.BackOffice.Abstractions/Building/Requests/CreateBuildingOsloSnapshotsRequest.cs new file mode 100644 index 000000000..d36dce25f --- /dev/null +++ b/src/BuildingRegistry.Api.BackOffice.Abstractions/Building/Requests/CreateBuildingOsloSnapshotsRequest.cs @@ -0,0 +1,11 @@ +namespace BuildingRegistry.Api.BackOffice.Abstractions.Building.Requests +{ + using System.Collections.Generic; + + public class CreateBuildingOsloSnapshotsRequest + { + public List BuildingPersistentLocalIds { get; set; } + + public string Reden { get; set; } + } +} diff --git a/src/BuildingRegistry.Api.BackOffice.Abstractions/Building/SqsRequests/CreateBuildingOsloSnapshotsSqsRequest.cs b/src/BuildingRegistry.Api.BackOffice.Abstractions/Building/SqsRequests/CreateBuildingOsloSnapshotsSqsRequest.cs new file mode 100644 index 000000000..121e0c50f --- /dev/null +++ b/src/BuildingRegistry.Api.BackOffice.Abstractions/Building/SqsRequests/CreateBuildingOsloSnapshotsSqsRequest.cs @@ -0,0 +1,10 @@ +namespace BuildingRegistry.Api.BackOffice.Abstractions.Building.SqsRequests +{ + using Be.Vlaanderen.Basisregisters.Sqs.Requests; + using Requests; + + public class CreateBuildingOsloSnapshotsSqsRequest : SqsRequest + { + public CreateBuildingOsloSnapshotsRequest Request { get; set; } + } +} diff --git a/src/BuildingRegistry.Api.BackOffice.Abstractions/BuildingUnit/Requests/CreateOsloSnapshotsRequest.cs b/src/BuildingRegistry.Api.BackOffice.Abstractions/BuildingUnit/Requests/CreateBuildingUnitOsloSnapshotsRequest.cs similarity index 81% rename from src/BuildingRegistry.Api.BackOffice.Abstractions/BuildingUnit/Requests/CreateOsloSnapshotsRequest.cs rename to src/BuildingRegistry.Api.BackOffice.Abstractions/BuildingUnit/Requests/CreateBuildingUnitOsloSnapshotsRequest.cs index 0cf3110d2..a4574823c 100644 --- a/src/BuildingRegistry.Api.BackOffice.Abstractions/BuildingUnit/Requests/CreateOsloSnapshotsRequest.cs +++ b/src/BuildingRegistry.Api.BackOffice.Abstractions/BuildingUnit/Requests/CreateBuildingUnitOsloSnapshotsRequest.cs @@ -2,7 +2,7 @@ namespace BuildingRegistry.Api.BackOffice.Abstractions.BuildingUnit.Requests { using System.Collections.Generic; - public class CreateOsloSnapshotsRequest + public class CreateBuildingUnitOsloSnapshotsRequest { public List BuildingUnitPersistentLocalIds { get; set; } diff --git a/src/BuildingRegistry.Api.BackOffice.Abstractions/BuildingUnit/SqsRequests/CreateOsloSnapshotsSqsRequest.cs b/src/BuildingRegistry.Api.BackOffice.Abstractions/BuildingUnit/SqsRequests/CreateBuildingUnitOsloSnapshotsSqsRequest.cs similarity index 53% rename from src/BuildingRegistry.Api.BackOffice.Abstractions/BuildingUnit/SqsRequests/CreateOsloSnapshotsSqsRequest.cs rename to src/BuildingRegistry.Api.BackOffice.Abstractions/BuildingUnit/SqsRequests/CreateBuildingUnitOsloSnapshotsSqsRequest.cs index b220d3db8..b59c69535 100644 --- a/src/BuildingRegistry.Api.BackOffice.Abstractions/BuildingUnit/SqsRequests/CreateOsloSnapshotsSqsRequest.cs +++ b/src/BuildingRegistry.Api.BackOffice.Abstractions/BuildingUnit/SqsRequests/CreateBuildingUnitOsloSnapshotsSqsRequest.cs @@ -3,8 +3,8 @@ namespace BuildingRegistry.Api.BackOffice.Abstractions.BuildingUnit.SqsRequests using Be.Vlaanderen.Basisregisters.Sqs.Requests; using Requests; - public class CreateOsloSnapshotsSqsRequest : SqsRequest + public class CreateBuildingUnitOsloSnapshotsSqsRequest : SqsRequest { - public CreateOsloSnapshotsRequest Request { get; set; } + public CreateBuildingUnitOsloSnapshotsRequest Request { get; set; } } } diff --git a/src/BuildingRegistry.Api.BackOffice.Handlers.Lambda/Handlers/Building/CreateBuildingOsloSnapshotsLambdaHandler.cs b/src/BuildingRegistry.Api.BackOffice.Handlers.Lambda/Handlers/Building/CreateBuildingOsloSnapshotsLambdaHandler.cs new file mode 100644 index 000000000..131ed753c --- /dev/null +++ b/src/BuildingRegistry.Api.BackOffice.Handlers.Lambda/Handlers/Building/CreateBuildingOsloSnapshotsLambdaHandler.cs @@ -0,0 +1,52 @@ +namespace BuildingRegistry.Api.BackOffice.Handlers.Lambda.Handlers.Building +{ + using Be.Vlaanderen.Basisregisters.AggregateSource; + using Be.Vlaanderen.Basisregisters.CommandHandling.Idempotency; + using Be.Vlaanderen.Basisregisters.Sqs.Lambda.Handlers; + using Be.Vlaanderen.Basisregisters.Sqs.Lambda.Infrastructure; + using Requests.Building; + using TicketingService.Abstractions; + + public sealed class CreateBuildingOsloSnapshotsLambdaHandler : SqsLambdaHandlerBase + { + public CreateBuildingOsloSnapshotsLambdaHandler( + ICustomRetryPolicy retryPolicy, + ITicketing ticketing, + IIdempotentCommandHandler idempotentCommandHandler) + : base(retryPolicy, ticketing, idempotentCommandHandler) + { + } + + protected override async Task InnerHandle(CreateBuildingOsloSnapshotsLambdaRequest request, CancellationToken cancellationToken) + { + var cmd = request.ToCommand(); + + try + { + await IdempotentCommandHandler.Dispatch( + cmd.CreateCommandId(), + cmd, + request.Metadata!, + cancellationToken); + } + catch (IdempotencyException) + { + // Idempotent: Do Nothing return last etag + } + + return "done"; + } + + protected override TicketError? MapDomainException(DomainException exception, CreateBuildingOsloSnapshotsLambdaRequest request) => null; + + protected override Task HandleAggregateIdIsNotFoundException(CreateBuildingOsloSnapshotsLambdaRequest request, CancellationToken cancellationToken) + { + throw new NotImplementedException(); + } + + protected override Task ValidateIfMatchHeaderValue(CreateBuildingOsloSnapshotsLambdaRequest request, CancellationToken cancellationToken) + { + return Task.CompletedTask; + } + } +} diff --git a/src/BuildingRegistry.Api.BackOffice.Handlers.Lambda/Handlers/BuildingUnit/CreateOsloSnapshotsLambdaHandler.cs b/src/BuildingRegistry.Api.BackOffice.Handlers.Lambda/Handlers/BuildingUnit/CreateBuildingUnitOsloSnapshotsLambdaHandler.cs similarity index 73% rename from src/BuildingRegistry.Api.BackOffice.Handlers.Lambda/Handlers/BuildingUnit/CreateOsloSnapshotsLambdaHandler.cs rename to src/BuildingRegistry.Api.BackOffice.Handlers.Lambda/Handlers/BuildingUnit/CreateBuildingUnitOsloSnapshotsLambdaHandler.cs index ac50cc6a3..0681755e1 100644 --- a/src/BuildingRegistry.Api.BackOffice.Handlers.Lambda/Handlers/BuildingUnit/CreateOsloSnapshotsLambdaHandler.cs +++ b/src/BuildingRegistry.Api.BackOffice.Handlers.Lambda/Handlers/BuildingUnit/CreateBuildingUnitOsloSnapshotsLambdaHandler.cs @@ -7,9 +7,9 @@ namespace BuildingRegistry.Api.BackOffice.Handlers.Lambda.Handlers.BuildingUnit using Requests.BuildingUnit; using TicketingService.Abstractions; - public sealed class CreateOsloSnapshotsLambdaHandler : SqsLambdaHandlerBase + public sealed class CreateBuildingUnitOsloSnapshotsLambdaHandler : SqsLambdaHandlerBase { - public CreateOsloSnapshotsLambdaHandler( + public CreateBuildingUnitOsloSnapshotsLambdaHandler( ICustomRetryPolicy retryPolicy, ITicketing ticketing, IIdempotentCommandHandler idempotentCommandHandler) @@ -17,7 +17,7 @@ public CreateOsloSnapshotsLambdaHandler( { } - protected override async Task InnerHandle(CreateOsloSnapshotsLambdaRequest request, CancellationToken cancellationToken) + protected override async Task InnerHandle(CreateBuildingUnitOsloSnapshotsLambdaRequest request, CancellationToken cancellationToken) { var cmd = request.ToCommand(); @@ -37,14 +37,14 @@ await IdempotentCommandHandler.Dispatch( return "done"; } - protected override TicketError? MapDomainException(DomainException exception, CreateOsloSnapshotsLambdaRequest request) => null; + protected override TicketError? MapDomainException(DomainException exception, CreateBuildingUnitOsloSnapshotsLambdaRequest request) => null; - protected override Task HandleAggregateIdIsNotFoundException(CreateOsloSnapshotsLambdaRequest request, CancellationToken cancellationToken) + protected override Task HandleAggregateIdIsNotFoundException(CreateBuildingUnitOsloSnapshotsLambdaRequest request, CancellationToken cancellationToken) { throw new NotImplementedException(); } - protected override Task ValidateIfMatchHeaderValue(CreateOsloSnapshotsLambdaRequest request, CancellationToken cancellationToken) + protected override Task ValidateIfMatchHeaderValue(CreateBuildingUnitOsloSnapshotsLambdaRequest request, CancellationToken cancellationToken) { return Task.CompletedTask; } diff --git a/src/BuildingRegistry.Api.BackOffice.Handlers.Lambda/MessageHandler.cs b/src/BuildingRegistry.Api.BackOffice.Handlers.Lambda/MessageHandler.cs index 185e4a41c..22f2b7517 100644 --- a/src/BuildingRegistry.Api.BackOffice.Handlers.Lambda/MessageHandler.cs +++ b/src/BuildingRegistry.Api.BackOffice.Handlers.Lambda/MessageHandler.cs @@ -173,9 +173,15 @@ await mediator.Send(new NotifyOutlinedRealizedBuildingLambdaRequest( new ExtendedWkbGeometry(request.ExtendedWkbGeometry)), cancellationToken); break; - case CreateOsloSnapshotsSqsRequest request: + case CreateBuildingOsloSnapshotsSqsRequest request: await mediator.Send( - new CreateOsloSnapshotsLambdaRequest(messageMetadata.MessageGroupId!, request), + new CreateBuildingOsloSnapshotsLambdaRequest(messageMetadata.MessageGroupId!, request), + cancellationToken); + break; + + case CreateBuildingUnitOsloSnapshotsSqsRequest request: + await mediator.Send( + new CreateBuildingUnitOsloSnapshotsLambdaRequest(messageMetadata.MessageGroupId!, request), cancellationToken); break; diff --git a/src/BuildingRegistry.Api.BackOffice.Handlers.Lambda/Requests/Building/CreateBuildingOsloSnapshotsLambdaRequest.cs b/src/BuildingRegistry.Api.BackOffice.Handlers.Lambda/Requests/Building/CreateBuildingOsloSnapshotsLambdaRequest.cs new file mode 100644 index 000000000..e4f009a78 --- /dev/null +++ b/src/BuildingRegistry.Api.BackOffice.Handlers.Lambda/Requests/Building/CreateBuildingOsloSnapshotsLambdaRequest.cs @@ -0,0 +1,38 @@ +namespace BuildingRegistry.Api.BackOffice.Handlers.Lambda.Requests.Building +{ + using Be.Vlaanderen.Basisregisters.Sqs.Lambda.Requests; + using BuildingRegistry.AllStream.Commands; + using BuildingRegistry.Api.BackOffice.Abstractions.Building.Requests; + using BuildingRegistry.Api.BackOffice.Abstractions.Building.SqsRequests; + using BuildingRegistry.Building; + + public sealed record CreateBuildingOsloSnapshotsLambdaRequest : SqsLambdaRequest + { + public CreateBuildingOsloSnapshotsRequest Request { get; } + + public CreateBuildingOsloSnapshotsLambdaRequest( + string messageGroupId, + CreateBuildingOsloSnapshotsSqsRequest sqsRequest) + : base( + messageGroupId, + sqsRequest.TicketId, + null, + sqsRequest.ProvenanceData.ToProvenance(), + sqsRequest.Metadata) + { + Request = sqsRequest.Request; + } + + /// + /// Map to CreateOsloSnapshots command + /// + /// CreateOsloSnapshots + public CreateOsloSnapshots ToCommand() + { + return new CreateOsloSnapshots( + Request.BuildingPersistentLocalIds.Select(x => new BuildingPersistentLocalId(x)), + [], + Provenance); + } + } +} diff --git a/src/BuildingRegistry.Api.BackOffice.Handlers.Lambda/Requests/BuildingUnit/CreateOsloSnapshotsLambdaRequest.cs b/src/BuildingRegistry.Api.BackOffice.Handlers.Lambda/Requests/BuildingUnit/CreateBuildingUnitOsloSnapshotsLambdaRequest.cs similarity index 78% rename from src/BuildingRegistry.Api.BackOffice.Handlers.Lambda/Requests/BuildingUnit/CreateOsloSnapshotsLambdaRequest.cs rename to src/BuildingRegistry.Api.BackOffice.Handlers.Lambda/Requests/BuildingUnit/CreateBuildingUnitOsloSnapshotsLambdaRequest.cs index 73b4acecd..965a294bf 100644 --- a/src/BuildingRegistry.Api.BackOffice.Handlers.Lambda/Requests/BuildingUnit/CreateOsloSnapshotsLambdaRequest.cs +++ b/src/BuildingRegistry.Api.BackOffice.Handlers.Lambda/Requests/BuildingUnit/CreateBuildingUnitOsloSnapshotsLambdaRequest.cs @@ -6,13 +6,13 @@ namespace BuildingRegistry.Api.BackOffice.Handlers.Lambda.Requests.BuildingUnit using BuildingRegistry.Api.BackOffice.Abstractions.BuildingUnit.SqsRequests; using BuildingRegistry.Building; - public sealed record CreateOsloSnapshotsLambdaRequest : SqsLambdaRequest + public sealed record CreateBuildingUnitOsloSnapshotsLambdaRequest : SqsLambdaRequest { - public CreateOsloSnapshotsRequest Request { get; } + public CreateBuildingUnitOsloSnapshotsRequest Request { get; } - public CreateOsloSnapshotsLambdaRequest( + public CreateBuildingUnitOsloSnapshotsLambdaRequest( string messageGroupId, - CreateOsloSnapshotsSqsRequest sqsRequest) + CreateBuildingUnitOsloSnapshotsSqsRequest sqsRequest) : base( messageGroupId, sqsRequest.TicketId, @@ -30,6 +30,7 @@ public CreateOsloSnapshotsLambdaRequest( public CreateOsloSnapshots ToCommand() { return new CreateOsloSnapshots( + [], Request.BuildingUnitPersistentLocalIds.Select(x => new BuildingUnitPersistentLocalId(x)), Provenance); } diff --git a/src/BuildingRegistry.Api.BackOffice/Building/BuildingController-CreateOsloSnapshots.cs b/src/BuildingRegistry.Api.BackOffice/Building/BuildingController-CreateOsloSnapshots.cs new file mode 100644 index 000000000..4846a6745 --- /dev/null +++ b/src/BuildingRegistry.Api.BackOffice/Building/BuildingController-CreateOsloSnapshots.cs @@ -0,0 +1,41 @@ +namespace BuildingRegistry.Api.BackOffice.Building +{ + using System.Threading; + using System.Threading.Tasks; + using Be.Vlaanderen.Basisregisters.Auth.AcmIdm; + using Be.Vlaanderen.Basisregisters.GrAr.Provenance; + using BuildingRegistry.Api.BackOffice.Abstractions.Building.Requests; + using BuildingRegistry.Api.BackOffice.Abstractions.Building.SqsRequests; + using Microsoft.AspNetCore.Authentication.JwtBearer; + using Microsoft.AspNetCore.Authorization; + using Microsoft.AspNetCore.Mvc; + + public partial class BuildingController + { + /// + /// Creëer nieuwe OSLO snapshots. + /// + /// + /// + /// + [HttpPost("acties/oslosnapshots")] + [Authorize(AuthenticationSchemes = JwtBearerDefaults.AuthenticationScheme, Policy = PolicyNames.GeschetstGebouw.InterneBijwerker)] + public async Task CreateOsloSnapshots( + [FromBody] CreateBuildingOsloSnapshotsRequest request, + CancellationToken cancellationToken = default) + { + var provenance = ProvenanceFactory.Create(new Reason(request.Reden), Modification.Unknown); + + var sqsRequest = new CreateBuildingOsloSnapshotsSqsRequest + { + Request = request, + Metadata = GetMetadata(), + ProvenanceData = new ProvenanceData(provenance) + }; + + var sqsResult = await Mediator.Send(sqsRequest, cancellationToken); + + return Accepted(sqsResult); + } + } +} diff --git a/src/BuildingRegistry.Api.BackOffice/BuildingUnit/BuildingUnitController-CreateOsloSnapshots.cs b/src/BuildingRegistry.Api.BackOffice/BuildingUnit/BuildingUnitController-CreateOsloSnapshots.cs index bfa6ad45f..2f508bf50 100644 --- a/src/BuildingRegistry.Api.BackOffice/BuildingUnit/BuildingUnitController-CreateOsloSnapshots.cs +++ b/src/BuildingRegistry.Api.BackOffice/BuildingUnit/BuildingUnitController-CreateOsloSnapshots.cs @@ -21,12 +21,12 @@ public partial class BuildingUnitController [HttpPost("acties/oslosnapshots")] [Authorize(AuthenticationSchemes = JwtBearerDefaults.AuthenticationScheme, Policy = PolicyNames.GeschetstGebouw.InterneBijwerker)] public async Task CreateOsloSnapshots( - [FromBody] CreateOsloSnapshotsRequest request, + [FromBody] CreateBuildingUnitOsloSnapshotsRequest request, CancellationToken cancellationToken = default) { var provenance = ProvenanceFactory.Create(new Reason(request.Reden), Modification.Unknown); - var sqsRequest = new CreateOsloSnapshotsSqsRequest + var sqsRequest = new CreateBuildingUnitOsloSnapshotsSqsRequest { Request = request, Metadata = GetMetadata(), diff --git a/src/BuildingRegistry.Api.BackOffice/Handlers/Building/CreateBuildingUnitOsloSnapshotsSqsHandler.cs b/src/BuildingRegistry.Api.BackOffice/Handlers/Building/CreateBuildingUnitOsloSnapshotsSqsHandler.cs new file mode 100644 index 000000000..51f89e234 --- /dev/null +++ b/src/BuildingRegistry.Api.BackOffice/Handlers/Building/CreateBuildingUnitOsloSnapshotsSqsHandler.cs @@ -0,0 +1,35 @@ +namespace BuildingRegistry.Api.BackOffice.Handlers.Building +{ + using System.Collections.Generic; + using Abstractions.Building.SqsRequests; + using AllStream; + using Be.Vlaanderen.Basisregisters.Sqs; + using Be.Vlaanderen.Basisregisters.Sqs.Handlers; + using TicketingService.Abstractions; + + public sealed class CreateBuildingOsloSnapshotsSqsHandler : SqsHandler + { + public const string Action = "CreateBuildingOsloSnapshots"; + + public CreateBuildingOsloSnapshotsSqsHandler( + ISqsQueue sqsQueue, + ITicketing ticketing, + ITicketingUrl ticketingUrl) : base(sqsQueue, ticketing, ticketingUrl) + { } + + protected override string? WithAggregateId(CreateBuildingOsloSnapshotsSqsRequest request) + { + return AllStreamId.Instance; + } + + protected override IDictionary WithTicketMetadata(string aggregateId, CreateBuildingOsloSnapshotsSqsRequest sqsRequest) + { + return new Dictionary + { + { RegistryKey, nameof(BuildingRegistry) }, + { ActionKey, Action }, + { AggregateIdKey, aggregateId } + }; + } + } +} diff --git a/src/BuildingRegistry.Api.BackOffice/Handlers/BuildingUnit/CreateOsloSnapshotsSqsHandler.cs b/src/BuildingRegistry.Api.BackOffice/Handlers/BuildingUnit/CreateBuildingUnitOsloSnapshotsSqsHandler.cs similarity index 67% rename from src/BuildingRegistry.Api.BackOffice/Handlers/BuildingUnit/CreateOsloSnapshotsSqsHandler.cs rename to src/BuildingRegistry.Api.BackOffice/Handlers/BuildingUnit/CreateBuildingUnitOsloSnapshotsSqsHandler.cs index 5b6b5efa2..96d49db98 100644 --- a/src/BuildingRegistry.Api.BackOffice/Handlers/BuildingUnit/CreateOsloSnapshotsSqsHandler.cs +++ b/src/BuildingRegistry.Api.BackOffice/Handlers/BuildingUnit/CreateBuildingUnitOsloSnapshotsSqsHandler.cs @@ -7,22 +7,22 @@ namespace BuildingRegistry.Api.BackOffice.Handlers.BuildingUnit using BuildingRegistry.Api.BackOffice.Abstractions.BuildingUnit.SqsRequests; using TicketingService.Abstractions; - public sealed class CreateOsloSnapshotsSqsHandler : SqsHandler + public sealed class CreateBuildingUnitOsloSnapshotsSqsHandler : SqsHandler { - public const string Action = "CreateOsloSnapshots"; + public const string Action = "CreateBuildingUnitOsloSnapshots"; - public CreateOsloSnapshotsSqsHandler( + public CreateBuildingUnitOsloSnapshotsSqsHandler( ISqsQueue sqsQueue, ITicketing ticketing, ITicketingUrl ticketingUrl) : base(sqsQueue, ticketing, ticketingUrl) { } - protected override string? WithAggregateId(CreateOsloSnapshotsSqsRequest request) + protected override string? WithAggregateId(CreateBuildingUnitOsloSnapshotsSqsRequest request) { return AllStreamId.Instance; } - protected override IDictionary WithTicketMetadata(string aggregateId, CreateOsloSnapshotsSqsRequest sqsRequest) + protected override IDictionary WithTicketMetadata(string aggregateId, CreateBuildingUnitOsloSnapshotsSqsRequest sqsRequest) { return new Dictionary { diff --git a/src/BuildingRegistry.Producer.Snapshot.Oslo/Infrastructure/Modules/ApiModule.cs b/src/BuildingRegistry.Producer.Snapshot.Oslo/Infrastructure/Modules/ApiModule.cs index 76d91ee70..1f505a3ca 100644 --- a/src/BuildingRegistry.Producer.Snapshot.Oslo/Infrastructure/Modules/ApiModule.cs +++ b/src/BuildingRegistry.Producer.Snapshot.Oslo/Infrastructure/Modules/ApiModule.cs @@ -95,18 +95,21 @@ private void RegisterProjections(ContainerBuilder builder) var osloNamespace = _configuration["BuildingOsloNamespace"]!.TrimEnd('/'); var producerOptions = CreateBuildingProducerOptions(); + var osloProxy = new OsloProxy(new HttpClient + { + BaseAddress = new Uri(_configuration["BuildingOsloApiUrl"]!.TrimEnd('/')), + }); + return new ProducerBuildingProjections( new Producer(producerOptions), new SnapshotManager( c.Resolve(), - new OsloProxy(new HttpClient - { - BaseAddress = new Uri(_configuration["BuildingOsloApiUrl"]!.TrimEnd('/')), - }), + osloProxy, SnapshotManagerOptions.Create( maxRetryWaitIntervalSeconds, retryBackoffFactor)), - osloNamespace); + osloNamespace, + osloProxy); }, connectedProjectionSettings) .RegisterProjections(c => diff --git a/src/BuildingRegistry.Producer.Snapshot.Oslo/ProducerBuildingProjections.cs b/src/BuildingRegistry.Producer.Snapshot.Oslo/ProducerBuildingProjections.cs index c931b6749..54379a54a 100644 --- a/src/BuildingRegistry.Producer.Snapshot.Oslo/ProducerBuildingProjections.cs +++ b/src/BuildingRegistry.Producer.Snapshot.Oslo/ProducerBuildingProjections.cs @@ -2,8 +2,11 @@ namespace BuildingRegistry.Producer.Snapshot.Oslo { using System; using System.Collections.Generic; + using System.Net; + using System.Net.Http; using System.Threading; using System.Threading.Tasks; + using AllStream.Events; using Be.Vlaanderen.Basisregisters.GrAr.Oslo.SnapshotProducer; using Be.Vlaanderen.Basisregisters.MessageHandling.Kafka; using Be.Vlaanderen.Basisregisters.MessageHandling.Kafka.Producer; @@ -19,10 +22,35 @@ public sealed class ProducerBuildingProjections : ConnectedProjection>(async (_, message, ct) => + { + foreach (var buildingPersistentLocalId in message.Message.BuildingPersistentLocalIds) + { + if (ct.IsCancellationRequested) + { + break; + } + + try + { + await FindAndProduce(async () => + await osloProxy.GetSnapshot(buildingPersistentLocalId.ToString(), ct), + message.Position, + ct); + } + catch (HttpRequestException e) when (e.StatusCode == HttpStatusCode.Gone) + { } + } + }); + When>(async (_, message, ct) => { if (!message.Message.IsRemoved) diff --git a/src/BuildingRegistry.Producer.Snapshot.Oslo/ProducerBuildingUnitProjections.cs b/src/BuildingRegistry.Producer.Snapshot.Oslo/ProducerBuildingUnitProjections.cs index 8986e987f..c716bce3a 100644 --- a/src/BuildingRegistry.Producer.Snapshot.Oslo/ProducerBuildingUnitProjections.cs +++ b/src/BuildingRegistry.Producer.Snapshot.Oslo/ProducerBuildingUnitProjections.cs @@ -3,6 +3,8 @@ namespace BuildingRegistry.Producer.Snapshot.Oslo using System; using System.Collections.Generic; using System.Linq; + using System.Net; + using System.Net.Http; using System.Threading; using System.Threading.Tasks; using AllStream.Events; @@ -37,10 +39,15 @@ public ProducerBuildingUnitProjections( break; } - await FindAndProduce(async () => - await osloProxy.GetSnapshot(buildingUnitPersistentLocalId.ToString(), ct), - message.Position, - ct); + try + { + await FindAndProduce(async () => + await osloProxy.GetSnapshot(buildingUnitPersistentLocalId.ToString(), ct), + message.Position, + ct); + } + catch (HttpRequestException e) when (e.StatusCode == HttpStatusCode.Gone) + { } } }); diff --git a/src/BuildingRegistry/AllStream/AllStream.cs b/src/BuildingRegistry/AllStream/AllStream.cs index bf97d456f..d8bb3f4c0 100644 --- a/src/BuildingRegistry/AllStream/AllStream.cs +++ b/src/BuildingRegistry/AllStream/AllStream.cs @@ -1,15 +1,22 @@ namespace BuildingRegistry.AllStream { using System.Collections.Generic; + using System.Linq; using Be.Vlaanderen.Basisregisters.AggregateSource; using Building; using Events; public sealed class AllStream : AggregateRootEntity { - public void CreateOsloSnapshots(IReadOnlyList buildingUnitPersistentLocalIds) + public void CreateOsloSnapshots( + IReadOnlyList buildingPersistentLocalIds, + IReadOnlyList buildingUnitPersistentLocalIds) { - ApplyChange(new BuildingUnitOsloSnapshotsWereRequested(buildingUnitPersistentLocalIds)); + if(buildingPersistentLocalIds.Any()) + ApplyChange(new BuildingOsloSnapshotsWereRequested(buildingPersistentLocalIds)); + + if(buildingUnitPersistentLocalIds.Any()) + ApplyChange(new BuildingUnitOsloSnapshotsWereRequested(buildingUnitPersistentLocalIds)); } } } diff --git a/src/BuildingRegistry/AllStream/AllStreamCommandHandlerModule.cs b/src/BuildingRegistry/AllStream/AllStreamCommandHandlerModule.cs index e12b9ed5f..a8f15cfd0 100644 --- a/src/BuildingRegistry/AllStream/AllStreamCommandHandlerModule.cs +++ b/src/BuildingRegistry/AllStream/AllStreamCommandHandlerModule.cs @@ -29,7 +29,7 @@ public AllStreamCommandHandlerModule( var allStream = optionalAllStream.HasValue ? optionalAllStream.Value : new AllStream(); - allStream.CreateOsloSnapshots(message.Command.BuildingUnitPersistentLocalIds); + allStream.CreateOsloSnapshots(message.Command.BuildingPersistentLocalIds, message.Command.BuildingUnitPersistentLocalIds); if (!optionalAllStream.HasValue) { diff --git a/src/BuildingRegistry/AllStream/Commands/CreateOsloSnapshots.cs b/src/BuildingRegistry/AllStream/Commands/CreateOsloSnapshots.cs index bebff23e9..f31c7a83e 100644 --- a/src/BuildingRegistry/AllStream/Commands/CreateOsloSnapshots.cs +++ b/src/BuildingRegistry/AllStream/Commands/CreateOsloSnapshots.cs @@ -12,14 +12,17 @@ public sealed class CreateOsloSnapshots : IHasCommandProvenance { private static readonly Guid Namespace = new Guid("2626bb06-4602-4864-a7c5-71f3a884af69"); + public IReadOnlyList BuildingPersistentLocalIds { get; } public IReadOnlyList BuildingUnitPersistentLocalIds { get; } public Provenance Provenance { get; } public CreateOsloSnapshots( + IEnumerable buildingPersistentLocalIds, IEnumerable buildingUnitPersistentLocalIds, Provenance provenance) { + BuildingPersistentLocalIds = buildingPersistentLocalIds.ToList(); BuildingUnitPersistentLocalIds = buildingUnitPersistentLocalIds.ToList(); Provenance = provenance; } @@ -32,6 +35,7 @@ public Guid CreateCommandId() private IEnumerable IdentityFields() { + yield return BuildingPersistentLocalIds; yield return BuildingUnitPersistentLocalIds; foreach (var field in Provenance.GetIdentityFields()) diff --git a/src/BuildingRegistry/AllStream/Events/BuildingOsloSnapshotsWereRequested.cs b/src/BuildingRegistry/AllStream/Events/BuildingOsloSnapshotsWereRequested.cs new file mode 100644 index 000000000..f6c0588cc --- /dev/null +++ b/src/BuildingRegistry/AllStream/Events/BuildingOsloSnapshotsWereRequested.cs @@ -0,0 +1,48 @@ +namespace BuildingRegistry.AllStream.Events +{ + using System.Collections.Generic; + using System.Linq; + using Be.Vlaanderen.Basisregisters.EventHandling; + using Be.Vlaanderen.Basisregisters.GrAr.Provenance; + using BuildingRegistry.Building; + using Newtonsoft.Json; + + [EventName(EventName)] + [EventDescription("Nieuwe OSLO snapshots werd aangevraagd voor de gebouwen.")] + public sealed class BuildingOsloSnapshotsWereRequested : IHasProvenance, ISetProvenance, IMessage + { + public const string EventName = "BuildingOsloSnapshotsWereRequested"; // BE CAREFUL CHANGING THIS!! + + [EventPropertyDescription("Objectidentificatoren van de gebouwen.")] + public IEnumerable BuildingPersistentLocalIds { get; } + + [EventPropertyDescription("Metadata bij het event.")] + public ProvenanceData Provenance { get; private set; } + + public BuildingOsloSnapshotsWereRequested( + IEnumerable buildingPersistentLocalIds) + { + BuildingPersistentLocalIds = buildingPersistentLocalIds + .Select(x => (int)x) + .ToList(); + } + + [JsonConstructor] + private BuildingOsloSnapshotsWereRequested( + IEnumerable buildingPersistentLocalIds, + ProvenanceData provenance) + : this( + buildingPersistentLocalIds.Select(x => new BuildingPersistentLocalId(x))) + => ((ISetProvenance)this).SetProvenance(provenance.ToProvenance()); + + void ISetProvenance.SetProvenance(Provenance provenance) => Provenance = new ProvenanceData(provenance); + + public IEnumerable GetHashFields() + { + var fields = Provenance.GetHashFields().ToList(); + fields.AddRange(BuildingPersistentLocalIds.Select(x => x.ToString())); + + return fields; + } + } +} diff --git a/test/BuildingRegistry.Tests/AggregateTests/WhenRequestingCreateOsloSnapshots/GivenAllStreamDoesNotExist.cs b/test/BuildingRegistry.Tests/AggregateTests/WhenRequestingCreateOsloSnapshots/GivenAllStreamDoesNotExist.cs index 23e0867c7..cdf637346 100644 --- a/test/BuildingRegistry.Tests/AggregateTests/WhenRequestingCreateOsloSnapshots/GivenAllStreamDoesNotExist.cs +++ b/test/BuildingRegistry.Tests/AggregateTests/WhenRequestingCreateOsloSnapshots/GivenAllStreamDoesNotExist.cs @@ -20,6 +20,7 @@ public GivenAllStreamDoesNotExist(ITestOutputHelper testOutputHelper) : base(tes public void ThenBuildingUnitOsloSnapshotsWereRequested() { var command = new CreateOsloSnapshots( + [], [new BuildingUnitPersistentLocalId(1)], Fixture.Create()); diff --git a/test/BuildingRegistry.Tests/AggregateTests/WhenRequestingCreateOsloSnapshots/GivenAllStreamExists.cs b/test/BuildingRegistry.Tests/AggregateTests/WhenRequestingCreateOsloSnapshots/GivenAllStreamExists.cs index 3d1734cbb..1e51d6c67 100644 --- a/test/BuildingRegistry.Tests/AggregateTests/WhenRequestingCreateOsloSnapshots/GivenAllStreamExists.cs +++ b/test/BuildingRegistry.Tests/AggregateTests/WhenRequestingCreateOsloSnapshots/GivenAllStreamExists.cs @@ -10,16 +10,32 @@ namespace BuildingRegistry.Tests.AggregateTests.WhenRequestingCreateOsloSnapshot using Xunit; using Xunit.Abstractions; - public class GivenParcelsExist : BuildingRegistryTest + public class GivenAllStreamExists : BuildingRegistryTest { - public GivenParcelsExist(ITestOutputHelper testOutputHelper) : base(testOutputHelper) + public GivenAllStreamExists(ITestOutputHelper testOutputHelper) : base(testOutputHelper) + { } + + [Fact] + public void ThenBuildingOsloSnapshotsAndBuildingUnitSnapshotsWereRequested() { + var command = new CreateOsloSnapshots( + [new BuildingPersistentLocalId(1)], + [new BuildingUnitPersistentLocalId(2)], + Fixture.Create()); + + Assert(new Scenario() + .Given(AllStreamId.Instance) + .When(command) + .Then(AllStreamId.Instance, + new BuildingOsloSnapshotsWereRequested(command.BuildingPersistentLocalIds), + new BuildingUnitOsloSnapshotsWereRequested(command.BuildingUnitPersistentLocalIds))); } [Fact] - public void ThenParcelOsloSnapshotsWereRequested() + public void WithOnlyBuildingUnits_ThenBuildingUnitOsloSnapshotsWereRequested() { var command = new CreateOsloSnapshots( + [], [new BuildingUnitPersistentLocalId(1)], Fixture.Create()); @@ -30,5 +46,21 @@ [new BuildingUnitPersistentLocalId(1)], new BuildingUnitOsloSnapshotsWereRequested( command.BuildingUnitPersistentLocalIds))); } + + [Fact] + public void WithOnlyBuildings_ThenBuildingOsloSnapshotsWereRequested() + { + var command = new CreateOsloSnapshots( + [new BuildingPersistentLocalId(1)], + [], + Fixture.Create()); + + Assert(new Scenario() + .Given(AllStreamId.Instance) + .When(command) + .Then(AllStreamId.Instance, + new BuildingOsloSnapshotsWereRequested( + command.BuildingPersistentLocalIds))); + } } } diff --git a/test/BuildingRegistry.Tests/BackOffice/Api/Building/WhenRequestingCreateBuildingOsloSnapshots/GivenRequest.cs b/test/BuildingRegistry.Tests/BackOffice/Api/Building/WhenRequestingCreateBuildingOsloSnapshots/GivenRequest.cs new file mode 100644 index 000000000..6536e7305 --- /dev/null +++ b/test/BuildingRegistry.Tests/BackOffice/Api/Building/WhenRequestingCreateBuildingOsloSnapshots/GivenRequest.cs @@ -0,0 +1,71 @@ +namespace BuildingRegistry.Tests.BackOffice.Api.Building.WhenRequestingCreateOsloSnapshots +{ + using System; + using System.Linq; + using System.Threading; + using System.Threading.Tasks; + using AutoFixture; + using Be.Vlaanderen.Basisregisters.GrAr.Provenance; + using Be.Vlaanderen.Basisregisters.Sqs.Requests; + using BuildingRegistry.Api.BackOffice.Abstractions.Building.Requests; + using BuildingRegistry.Api.BackOffice.Abstractions.Building.SqsRequests; + using BuildingRegistry.Api.BackOffice.Building; + using BuildingRegistry.Building; + using Api; + using Fixtures; + using FluentAssertions; + using Microsoft.AspNetCore.Mvc; + using Moq; + using NodaTime; + using Xunit; + using Xunit.Abstractions; + + public class GivenRequest : BackOfficeApiTest + { + private readonly BuildingController _controller; + + public GivenRequest(ITestOutputHelper testOutputHelper) : base(testOutputHelper) + { + Fixture.Customize(new WithFixedBuildingPersistentLocalId()); + + _controller = CreateBuildingControllerWithUser(); + } + + [Fact] + public async Task ThenTicketLocationIsReturned() + { + var buildingPersistentLocalIds = Fixture.CreateMany(); + + var ticketId = Fixture.Create(); + var expectedLocationResult = new LocationResult(CreateTicketUri(ticketId)); + + MockMediator + .Setup(x => x.Send( + It.IsAny(), + CancellationToken.None)) + .Returns(Task.FromResult(expectedLocationResult)); + + var request = new CreateBuildingOsloSnapshotsRequest + { + BuildingPersistentLocalIds = buildingPersistentLocalIds.Select(x => (int)x).ToList(), + Reden = "Test" + }; + + var result = (AcceptedResult)await _controller.CreateOsloSnapshots(request); + + result.Should().NotBeNull(); + AssertLocation(result.Location, ticketId); + + MockMediator.Verify(x => + x.Send( + It.Is(sqsRequest => + sqsRequest.Request == request + && sqsRequest.ProvenanceData.Timestamp != Instant.MinValue + && sqsRequest.ProvenanceData.Application == Application.BuildingRegistry + && sqsRequest.ProvenanceData.Modification == Modification.Unknown + && sqsRequest.ProvenanceData.Reason == request.Reden + ), + CancellationToken.None)); + } + } +} diff --git a/test/BuildingRegistry.Tests/BackOffice/Api/BuildingUnit/WhenRequestingCreateOsloSnapshots/GivenRequest.cs b/test/BuildingRegistry.Tests/BackOffice/Api/BuildingUnit/WhenRequestingCreateBuildingUnitOsloSnapshots/GivenRequest.cs similarity index 92% rename from test/BuildingRegistry.Tests/BackOffice/Api/BuildingUnit/WhenRequestingCreateOsloSnapshots/GivenRequest.cs rename to test/BuildingRegistry.Tests/BackOffice/Api/BuildingUnit/WhenRequestingCreateBuildingUnitOsloSnapshots/GivenRequest.cs index 2754f2214..d8a94e4d4 100644 --- a/test/BuildingRegistry.Tests/BackOffice/Api/BuildingUnit/WhenRequestingCreateOsloSnapshots/GivenRequest.cs +++ b/test/BuildingRegistry.Tests/BackOffice/Api/BuildingUnit/WhenRequestingCreateBuildingUnitOsloSnapshots/GivenRequest.cs @@ -41,11 +41,11 @@ public async Task ThenTicketLocationIsReturned() MockMediator .Setup(x => x.Send( - It.IsAny(), + It.IsAny(), CancellationToken.None)) .Returns(Task.FromResult(expectedLocationResult)); - var request = new CreateOsloSnapshotsRequest + var request = new CreateBuildingUnitOsloSnapshotsRequest { BuildingUnitPersistentLocalIds = buildingUnitPersistentLocalIds.Select(x => (int)x).ToList(), Reden = "UnitTest" @@ -58,7 +58,7 @@ public async Task ThenTicketLocationIsReturned() MockMediator.Verify(x => x.Send( - It.Is(sqsRequest => + It.Is(sqsRequest => sqsRequest.Request == request && sqsRequest.ProvenanceData.Timestamp != Instant.MinValue && sqsRequest.ProvenanceData.Application == Application.BuildingRegistry diff --git a/test/BuildingRegistry.Tests/BackOffice/Lambda/Building/WhenCreatingBuildingOsloSnapshotsRequest.cs b/test/BuildingRegistry.Tests/BackOffice/Lambda/Building/WhenCreatingBuildingOsloSnapshotsRequest.cs new file mode 100644 index 000000000..dc62ccd93 --- /dev/null +++ b/test/BuildingRegistry.Tests/BackOffice/Lambda/Building/WhenCreatingBuildingOsloSnapshotsRequest.cs @@ -0,0 +1,109 @@ +namespace BuildingRegistry.Tests.BackOffice.Lambda.Building +{ + using System; + using System.Linq; + using System.Threading; + using System.Threading.Tasks; + using AllStream; + using Autofac; + using AutoFixture; + using Be.Vlaanderen.Basisregisters.CommandHandling; + using Be.Vlaanderen.Basisregisters.CommandHandling.Idempotency; + using Be.Vlaanderen.Basisregisters.GrAr.Provenance; + using BuildingRegistry.Api.BackOffice.Abstractions.Building.Requests; + using BuildingRegistry.Api.BackOffice.Abstractions.Building.SqsRequests; + using BuildingRegistry.Api.BackOffice.Handlers.Lambda.Handlers.Building; + using BuildingRegistry.Api.BackOffice.Handlers.Lambda.Requests.Building; + using FluentAssertions; + using Moq; + using SqlStreamStore; + using SqlStreamStore.Streams; + using TicketingService.Abstractions; + using Xunit; + using Xunit.Abstractions; + + public class WhenCreatingBuildingOsloSnapshotsRequest : BackOfficeLambdaTest + { + private readonly IdempotencyContext _idempotencyContext; + + public WhenCreatingBuildingOsloSnapshotsRequest(ITestOutputHelper testOutputHelper) : base(testOutputHelper) + { + _idempotencyContext = new FakeIdempotencyContextFactory().CreateDbContext([]); + } + + [Fact] + public async Task ThenTicketingCompleteIsExpected() + { + // Arrange + var ticketing = new Mock(); + + var handler = new CreateBuildingOsloSnapshotsLambdaHandler( + new FakeRetryPolicy(), + ticketing.Object, + new IdempotentCommandHandler(Container.Resolve(), _idempotencyContext)); + + // Act + var ticketId = Guid.NewGuid(); + await handler.Handle( + new CreateBuildingOsloSnapshotsLambdaRequest( + AllStreamId.Instance, + new CreateBuildingOsloSnapshotsSqsRequest + { + TicketId = ticketId, + Request = new CreateBuildingOsloSnapshotsRequest + { + BuildingPersistentLocalIds = [1] + }, + ProvenanceData = Fixture.Create() + }), + CancellationToken.None); + + //Assert + ticketing.Verify(x => + x.Complete( + ticketId, + new TicketResult("done"), + CancellationToken.None)); + + //Assert + var stream = await Container.Resolve().ReadStreamBackwards(new StreamId(AllStreamId.Instance), 0, 1); + var message = stream.Messages.First(); + message.JsonMetadata.Should().Contain(Provenance.ProvenanceMetadataKey.ToLower()); + } + + [Fact] + public async Task WhenIdempotencyException_ThenTicketingCompleteIsExpected() + { + // Arrange + var ticketing = new Mock(); + + var handler = new CreateBuildingOsloSnapshotsLambdaHandler( + new FakeRetryPolicy(), + ticketing.Object, + MockExceptionIdempotentCommandHandler(() => new IdempotencyException(string.Empty)).Object); + + // Act + var ticketId = Guid.NewGuid(); + await handler.Handle( + new CreateBuildingOsloSnapshotsLambdaRequest( + AllStreamId.Instance, + new CreateBuildingOsloSnapshotsSqsRequest + { + TicketId = ticketId, + Request = new CreateBuildingOsloSnapshotsRequest + { + BuildingPersistentLocalIds = [1] + }, + ProvenanceData = Fixture.Create() + }), + CancellationToken.None); + + //Assert + ticketing.Verify(x => + x.Complete( + ticketId, + new TicketResult("done"), + CancellationToken.None)); + } + } +} diff --git a/test/BuildingRegistry.Tests/BackOffice/Lambda/BuildingUnit/WhenCreatingOsloSnapshotsRequest.cs b/test/BuildingRegistry.Tests/BackOffice/Lambda/BuildingUnit/WhenCreatingBuildingUnitOsloSnapshotsRequest.cs similarity index 82% rename from test/BuildingRegistry.Tests/BackOffice/Lambda/BuildingUnit/WhenCreatingOsloSnapshotsRequest.cs rename to test/BuildingRegistry.Tests/BackOffice/Lambda/BuildingUnit/WhenCreatingBuildingUnitOsloSnapshotsRequest.cs index 40498d8a6..26c48a1cd 100644 --- a/test/BuildingRegistry.Tests/BackOffice/Lambda/BuildingUnit/WhenCreatingOsloSnapshotsRequest.cs +++ b/test/BuildingRegistry.Tests/BackOffice/Lambda/BuildingUnit/WhenCreatingBuildingUnitOsloSnapshotsRequest.cs @@ -24,11 +24,11 @@ namespace BuildingRegistry.Tests.BackOffice.Lambda.BuildingUnit using Xunit; using Xunit.Abstractions; - public class WhenCreatingOsloSnapshotsRequest : BackOfficeLambdaTest + public class WhenCreatingBuildingUnitOsloSnapshotsRequest : BackOfficeLambdaTest { private readonly IdempotencyContext _idempotencyContext; - public WhenCreatingOsloSnapshotsRequest(ITestOutputHelper testOutputHelper) : base(testOutputHelper) + public WhenCreatingBuildingUnitOsloSnapshotsRequest(ITestOutputHelper testOutputHelper) : base(testOutputHelper) { _idempotencyContext = new FakeIdempotencyContextFactory().CreateDbContext([]); } @@ -39,7 +39,7 @@ public async Task ThenTicketingCompleteIsExpected() // Arrange var ticketing = new Mock(); - var handler = new CreateOsloSnapshotsLambdaHandler( + var handler = new CreateBuildingUnitOsloSnapshotsLambdaHandler( new FakeRetryPolicy(), ticketing.Object, new IdempotentCommandHandler(Container.Resolve(), _idempotencyContext)); @@ -47,12 +47,12 @@ public async Task ThenTicketingCompleteIsExpected() // Act var ticketId = Guid.NewGuid(); await handler.Handle( - new CreateOsloSnapshotsLambdaRequest( + new CreateBuildingUnitOsloSnapshotsLambdaRequest( AllStreamId.Instance, - new CreateOsloSnapshotsSqsRequest + new CreateBuildingUnitOsloSnapshotsSqsRequest { TicketId = ticketId, - Request = new CreateOsloSnapshotsRequest + Request = new CreateBuildingUnitOsloSnapshotsRequest { BuildingUnitPersistentLocalIds = [1] }, @@ -79,7 +79,7 @@ public async Task WhenIdempotencyException_ThenTicketingCompleteIsExpected() // Arrange var ticketing = new Mock(); - var handler = new CreateOsloSnapshotsLambdaHandler( + var handler = new CreateBuildingUnitOsloSnapshotsLambdaHandler( new FakeRetryPolicy(), ticketing.Object, MockExceptionIdempotentCommandHandler(() => new IdempotencyException(string.Empty)).Object); @@ -87,12 +87,12 @@ public async Task WhenIdempotencyException_ThenTicketingCompleteIsExpected() // Act var ticketId = Guid.NewGuid(); await handler.Handle( - new CreateOsloSnapshotsLambdaRequest( + new CreateBuildingUnitOsloSnapshotsLambdaRequest( AllStreamId.Instance, - new CreateOsloSnapshotsSqsRequest + new CreateBuildingUnitOsloSnapshotsSqsRequest { TicketId = ticketId, - Request = new CreateOsloSnapshotsRequest + Request = new CreateBuildingUnitOsloSnapshotsRequest { BuildingUnitPersistentLocalIds = [1] }, diff --git a/test/BuildingRegistry.Tests/BackOffice/Lambda/MessageHandlerTests.cs b/test/BuildingRegistry.Tests/BackOffice/Lambda/MessageHandlerTests.cs index 7e1e28ff2..537e92173 100644 --- a/test/BuildingRegistry.Tests/BackOffice/Lambda/MessageHandlerTests.cs +++ b/test/BuildingRegistry.Tests/BackOffice/Lambda/MessageHandlerTests.cs @@ -989,7 +989,7 @@ await sut.HandleMessage( } [Fact] - public async Task WhenProcessingCreateOsloSnapshotsSqsRequest_ThenCreateOsloSnapshotsLambdaRequestIsSent() + public async Task WhenProcessingCreateBuildingOsloSnapshotsSqsRequest_ThenCreateBuildingOsloSnapshotsLambdaRequestIsSent() { // Arrange var mediator = new Mock(); @@ -997,7 +997,7 @@ public async Task WhenProcessingCreateOsloSnapshotsSqsRequest_ThenCreateOsloSnap containerBuilder.Register(_ => mediator.Object); var container = containerBuilder.Build(); - var messageData = Fixture.Create(); + var messageData = Fixture.Create(); var messageMetadata = new MessageMetadata { MessageGroupId = Fixture.Create() }; var sut = new MessageHandler(container); @@ -1010,7 +1010,39 @@ await sut.HandleMessage( // Assert mediator - .Verify(x => x.Send(It.Is(request => + .Verify(x => x.Send(It.Is(request => + request.TicketId == messageData.TicketId && + request.MessageGroupId == messageMetadata.MessageGroupId && + request.Request == messageData.Request && + string.IsNullOrEmpty(request.IfMatchHeaderValue) && + request.Provenance == messageData.ProvenanceData.ToProvenance() && + request.Metadata == messageData.Metadata + ), It.IsAny()), Times.Once); + } + + [Fact] + public async Task WhenProcessingCreateBuildingUnitOsloSnapshotsSqsRequest_ThenCreateBuildingUnitOsloSnapshotsLambdaRequestIsSent() + { + // Arrange + var mediator = new Mock(); + var containerBuilder = new ContainerBuilder(); + containerBuilder.Register(_ => mediator.Object); + var container = containerBuilder.Build(); + + var messageData = Fixture.Create(); + var messageMetadata = new MessageMetadata { MessageGroupId = Fixture.Create() }; + + var sut = new MessageHandler(container); + + // Act + await sut.HandleMessage( + messageData, + messageMetadata, + CancellationToken.None); + + // Assert + mediator + .Verify(x => x.Send(It.Is(request => request.TicketId == messageData.TicketId && request.MessageGroupId == messageMetadata.MessageGroupId && request.Request == messageData.Request && diff --git a/test/BuildingRegistry.Tests/BackOffice/Sqs/Building/GivenCreateBuildingOsloSnapshotsBackOfficeRequest.cs b/test/BuildingRegistry.Tests/BackOffice/Sqs/Building/GivenCreateBuildingOsloSnapshotsBackOfficeRequest.cs new file mode 100644 index 000000000..8ba9820fa --- /dev/null +++ b/test/BuildingRegistry.Tests/BackOffice/Sqs/Building/GivenCreateBuildingOsloSnapshotsBackOfficeRequest.cs @@ -0,0 +1,70 @@ +namespace BuildingRegistry.Tests.BackOffice.Sqs.Building +{ + using System; + using System.Collections.Generic; + using System.Linq; + using System.Threading; + using System.Threading.Tasks; + using AllStream; + using AutoFixture; + using Be.Vlaanderen.Basisregisters.MessageHandling.AwsSqs.Simple; + using Be.Vlaanderen.Basisregisters.Sqs; + using BuildingRegistry.Api.BackOffice.Abstractions.Building.Requests; + using BuildingRegistry.Api.BackOffice.Abstractions.Building.SqsRequests; + using BuildingRegistry.Api.BackOffice.Handlers.Building; + using BuildingRegistry.Building; + using Fixtures; + using FluentAssertions; + using Moq; + using TicketingService.Abstractions; + using Xunit; + using Xunit.Abstractions; + + public class GivenCreateBuildingOsloSnapshotsBackOfficeRequest : BuildingRegistryTest + { + public GivenCreateBuildingOsloSnapshotsBackOfficeRequest(ITestOutputHelper testOutputHelper) : base(testOutputHelper) + { + Fixture.Customize(new WithFixedBuildingPersistentLocalId()); + Fixture.Customize(new WithFixedBuildingPersistentLocalId()); + } + + [Fact] + public async Task ThenTicketWithLocationIsCreated() + { + // Arrange + var ticketId = Fixture.Create(); + var ticketingMock = new Mock(); + ticketingMock + .Setup(x => x.CreateTicket(It.IsAny>(), CancellationToken.None)) + .ReturnsAsync(ticketId); + + var ticketingUrl = new TicketingUrl(Fixture.Create().ToString()); + + var sqsQueue = new Mock(); + + var sut = new CreateBuildingOsloSnapshotsSqsHandler( + sqsQueue.Object, + ticketingMock.Object, + ticketingUrl); + + var sqsRequest = new CreateBuildingOsloSnapshotsSqsRequest + { + Request = new CreateBuildingOsloSnapshotsRequest + { + BuildingPersistentLocalIds = Fixture.CreateMany().Select(x => (int)x).ToList() + } + }; + + // Act + var result = await sut.Handle(sqsRequest, CancellationToken.None); + + // Assert + sqsRequest.TicketId.Should().Be(ticketId); + sqsQueue.Verify(x => x.Copy( + sqsRequest, + It.Is(y => y.MessageGroupId == AllStreamId.Instance.ToString()), + CancellationToken.None)); + result.Location.Should().Be(ticketingUrl.For(ticketId)); + } + } +} diff --git a/test/BuildingRegistry.Tests/BackOffice/Sqs/BuildingUnit/GivenCreateOsloSnapshotsBackOfficeRequest.cs b/test/BuildingRegistry.Tests/BackOffice/Sqs/BuildingUnit/GivenCreateBuildingUnitOsloSnapshotsBackOfficeRequest.cs similarity index 83% rename from test/BuildingRegistry.Tests/BackOffice/Sqs/BuildingUnit/GivenCreateOsloSnapshotsBackOfficeRequest.cs rename to test/BuildingRegistry.Tests/BackOffice/Sqs/BuildingUnit/GivenCreateBuildingUnitOsloSnapshotsBackOfficeRequest.cs index b58e3e7d1..25849e1cb 100644 --- a/test/BuildingRegistry.Tests/BackOffice/Sqs/BuildingUnit/GivenCreateOsloSnapshotsBackOfficeRequest.cs +++ b/test/BuildingRegistry.Tests/BackOffice/Sqs/BuildingUnit/GivenCreateBuildingUnitOsloSnapshotsBackOfficeRequest.cs @@ -20,9 +20,9 @@ namespace BuildingRegistry.Tests.BackOffice.Sqs.BuildingUnit using Xunit; using Xunit.Abstractions; - public class GivenCreateOsloSnapshotsBackOfficeRequest : BuildingRegistryTest + public class GivenCreateBuildingUnitOsloSnapshotsBackOfficeRequest : BuildingRegistryTest { - public GivenCreateOsloSnapshotsBackOfficeRequest(ITestOutputHelper testOutputHelper) : base(testOutputHelper) + public GivenCreateBuildingUnitOsloSnapshotsBackOfficeRequest(ITestOutputHelper testOutputHelper) : base(testOutputHelper) { Fixture.Customize(new WithFixedBuildingPersistentLocalId()); Fixture.Customize(new WithFixedBuildingUnitPersistentLocalId()); @@ -42,14 +42,14 @@ public async Task ThenTicketWithLocationIsCreated() var sqsQueue = new Mock(); - var sut = new CreateOsloSnapshotsSqsHandler( + var sut = new CreateBuildingUnitOsloSnapshotsSqsHandler( sqsQueue.Object, ticketingMock.Object, ticketingUrl); - var sqsRequest = new CreateOsloSnapshotsSqsRequest + var sqsRequest = new CreateBuildingUnitOsloSnapshotsSqsRequest { - Request = new CreateOsloSnapshotsRequest + Request = new CreateBuildingUnitOsloSnapshotsRequest { BuildingUnitPersistentLocalIds = Fixture.CreateMany().Select(x => (int)x).ToList() }