Skip to content
Open
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
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System.Linq;
using System;
using System.Linq;
using System.Net.Mime;
using Azure.Messaging.ServiceBus;
using Paramore.Brighter.Extensions;
Expand Down Expand Up @@ -59,11 +60,17 @@ private static void AddBrighterHeaders(Message message, ServiceBusMessage azureS
azureServiceBusMessage.CorrelationId = message.Header.CorrelationId;
if (!string.IsNullOrEmpty(message.Header.ReplyTo!))
azureServiceBusMessage.ReplyTo = message.Header.ReplyTo?.Value;
if (message.Header.Bag.TryGetValue(ASBConstants.SessionIdKey, out object? value))
azureServiceBusMessage.SessionId = value.ToString();
//Brighter's JSON serialization camelCases bag keys (JsonNamingPolicy.CamelCase), so a key
//written as "SessionId" returns as "sessionId" after a round-trip (e.g. via an Outbox).
//Resolve the SessionId regardless of casing.
var sessionId = message.Header.Bag
.FirstOrDefault(h => string.Equals(h.Key, ASBConstants.SessionIdKey, StringComparison.OrdinalIgnoreCase))
.Value;
if (sessionId is not null)
azureServiceBusMessage.SessionId = sessionId.ToString();

foreach (var header in message.Header.Bag.Where(h =>
!ASBConstants.ReservedHeaders.Contains(h.Key)
!ASBConstants.ReservedHeaders.Contains(h.Key, StringComparer.OrdinalIgnoreCase)
&& !MessageHeader.IsLocalHeader(h.Key)))
{
azureServiceBusMessage.ApplicationProperties[header.Key] = header.Value;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
using System;
using Paramore.Brighter.MessagingGateway.AzureServiceBus;
using Xunit;

namespace Paramore.Brighter.AzureServiceBus.Tests.MessagingGateway;

[Trait("Category", "ASB")]
public class AzureServiceBusMessagePublisherSessionIdTests
{
[Theory]
[InlineData("SessionId")] // as written by application code
[InlineData("sessionId")] // as it returns from a camelCasing serialization round-trip (e.g. via the Outbox)
public void When_Converting_A_Message_With_A_SessionId_Bag_Key_Of_Any_Casing_The_SessionId_Is_Set(string sessionIdKey)
{
// Brighter's JSON serialization uses JsonNamingPolicy.CamelCase, so a bag key written as
// "SessionId" comes back as "sessionId" once the message round-trips through serialization
// (for example when stored in and read back from an Outbox). The publisher must resolve the
// SessionId regardless of the key's casing — and the reserved key must not leak onto the wire.
const string expectedSessionId = "order-42";
var header = new MessageHeader(
messageId: Guid.NewGuid().ToString(),
topic: new RoutingKey("test.topic"),
messageType: MessageType.MT_COMMAND);
header.Bag[sessionIdKey] = expectedSessionId;

var message = new Message(header, new MessageBody("body"));

var asbMessage = AzureServiceBusMessagePublisher.ConvertToServiceBusMessage(message);

// the session id is set on the outgoing message...
Assert.Equal(expectedSessionId, asbMessage.SessionId);
// ...and the reserved header does not leak into ApplicationProperties
Assert.False(asbMessage.ApplicationProperties.ContainsKey(sessionIdKey));
}
}
Loading