diff --git a/src/Directory.Packages.props b/src/Directory.Packages.props index 1a712572da..099ff4c023 100644 --- a/src/Directory.Packages.props +++ b/src/Directory.Packages.props @@ -54,7 +54,7 @@ - + diff --git a/src/ServiceControl.Audit.AcceptanceTests/Auditing/When_a_message_processed_with_receive_properties.cs b/src/ServiceControl.Audit.AcceptanceTests/Auditing/When_a_message_processed_with_receive_properties.cs new file mode 100644 index 0000000000..b6e807fd51 --- /dev/null +++ b/src/ServiceControl.Audit.AcceptanceTests/Auditing/When_a_message_processed_with_receive_properties.cs @@ -0,0 +1,100 @@ +namespace ServiceControl.Audit.AcceptanceTests.Auditing +{ + using System.Collections.Generic; + using System.Linq; + using System.Threading.Tasks; + using AcceptanceTesting; + using AcceptanceTesting.EndpointTemplates; + using Audit.Auditing.MessagesView; + using NServiceBus; + using NServiceBus.AcceptanceTesting; + using NServiceBus.AcceptanceTesting.Customization; + using NServiceBus.Transport; + using NUnit.Framework; + + class When_a_message_processed_with_receive_properties : AcceptanceTest + { + [Test] + public async Task Should_save_audit_message_with_receive_properties() + { + const string Payload = "PAYLOAD"; + MessagesView auditedMessage = null; + byte[] body = null; + + var context = await Define() + .WithEndpoint(b => b.When((bus, c) => bus.Send(new MyMessage { Payload = Payload }))) + .WithEndpoint() + .Done(async c => + { + if (c.MessageId == null) + { + return false; + } + + var result = await this.TryGetSingle("/api/messages?include_system_messages=false&sort=id", m => m.MessageId == c.MessageId); + auditedMessage = result; + if (!result) + { + return false; + } + + body = await this.DownloadData($"/api{auditedMessage.BodyUrl}"); + + return true; + }) + .Run(); + + var hasReceivedProperties = auditedMessage.Headers.Any(x => x.Key.Equals("ServiceControl.ReceiveProperties.LearningTransport.FileCreatedAt")); + + var receivedProperties = new KeyValuePair(); + if (hasReceivedProperties) + { + receivedProperties = auditedMessage.Headers.First(x => x.Key.Equals("ServiceControl.ReceiveProperties.LearningTransport.FileCreatedAt")); + } + + using (Assert.EnterMultipleScope()) + { + Assert.That(hasReceivedProperties, Is.True, "The audit message should have receive properties"); + Assert.That(receivedProperties.Value, Is.EqualTo(context.ReceivedMessageFileCreatedAt), "The audit message should have receive properties"); + } + } + + public class Sender : EndpointConfigurationBuilder + { + public Sender() => + EndpointSetup(c => + { + var routing = c.ConfigureRouting(); + routing.RouteToEndpoint(typeof(MyMessage), typeof(Receiver)); + }); + } + + public class Receiver : EndpointConfigurationBuilder + { + public Receiver() => EndpointSetup(); + + [Handler] + public class MyMessageHandler(MyContext testContext) : IHandleMessages + { + public Task Handle(MyMessage message, IMessageHandlerContext context) + { + testContext.ReceivedMessageFileCreatedAt = context.Extensions.Get().ReceiveProperties["LearningTransport.FileCreatedAt"]; + testContext.MessageId = context.MessageId; + return Task.Delay(500, context.CancellationToken); + } + } + } + + public class MyMessage : ICommand + { + public string Payload { get; set; } + } + + public class MyContext : ScenarioContext + { + public string MessageId { get; set; } + + public string ReceivedMessageFileCreatedAt { get; set; } + } + } +} \ No newline at end of file diff --git a/src/ServiceControl.Audit/Auditing/AuditPersister.cs b/src/ServiceControl.Audit/Auditing/AuditPersister.cs index f6089e2f28..6392c1444e 100644 --- a/src/ServiceControl.Audit/Auditing/AuditPersister.cs +++ b/src/ServiceControl.Audit/Auditing/AuditPersister.cs @@ -144,6 +144,11 @@ async Task ProcessAuditMessage(MessageContext context, IMessageDispatcher dispat ["MessageIntent"] = context.Headers.MessageIntent() }; + foreach (var property in context.ReceiveProperties) + { + context.Headers.TryAdd($"ServiceControl.ReceiveProperties.{property.Key}", property.Value); + } + var commandsToEmit = new List(); var messagesToEmit = new List(); var enricherContext = new AuditEnricherContext(context.Headers, commandsToEmit, messagesToEmit, metadata);